ZBLOG

dpdk使用ndpi_detection_process_packet过滤http协议代码

以下是一个简单的DPDK使用nDPI过滤HTTP协议的示例代码,该代码使用了ndpi_detection_process_packet函数进行协议检测和过滤:

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include <rte_eal.h>
#include <rte_ethdev.h>
#include <rte_mbuf.h>

#include "ndpi_api.h"

#define RX_RING_SIZE 128
#define TX_RING_SIZE 512
#define NUM_MBUFS 8191
#define MBUF_CACHE_SIZE 250
#define BURST_SIZE 32

static const struct rte_eth_conf port_conf_default = {
    .rxmode = { .max_rx_pkt_len = ETHER_MAX_LEN }
};

struct app_lcore_params {
    uint16_t port;
} __rte_cache_aligned;

static struct app_lcore_params lcore_params[RTE_MAX_LCORE];

static void packet_handler(struct rte_mbuf *pkt, uint16_t portid) {
    /* Perform nDPI protocol detection */
    ndpi_detection_module_struct *ndpi_mod = ndpi_init_detection_module();
    ndpi_flow_info_t flow_info;
    memset(&flow_info, 0, sizeof(flow_info));
    ndpi_protocol_t detected_proto = NDPI_PROTOCOL_UNKNOWN;

    if (pkt->packet_type & RTE_PTYPE_L2_ETHER) {
        if (pkt->packet_type & RTE_PTYPE_L3_IPV4) {
            detected_proto =
                ndpi_detection_process_packet(ndpi_mod,
                                              pkt->buf_addr + pkt->data_off,
                                              pkt->data_len,
                                              &flow_info);
        } else if (pkt->packet_type & RTE_PTYPE_L3_IPV6) {
            detected_proto =
                ndpi_detection_process_packet6(ndpi_mod,
                                               pkt->buf_addr + pkt->data_off,
                                               pkt->data_len,
                                               &flow_info);
        }
    }

    /* Check if protocol is HTTP */
    if (detected_proto == NDPI_PROTOCOL_HTTP ||
        detected_proto == NDPI_PROTOCOL_SSL) {
        printf("HTTP packet received on port %u\n", portid);

        /* Print out some HTTP information */
        struct ndpi_http_response_t *http_response =
            ndpi_match_http_request(ndpi_mod, &flow_info);
        if (http_response != NULL) {
            printf("Method: %s\n", http_response->method.ptr);
            printf("URI: %s\n", http_response->uri.ptr);
            printf("Version: %s\n", http_response->version.ptr);
        }
    }

    rte_pktmbuf_free(pkt);

    ndpi_exit_detection_module(ndpi_mod, NULL);

}

static int lcore_main(__attribute__((unused)) void *arg) {
    uint16_t port;

    RTE_LCORE_FOREACH_SLAVE(port) {
        if (lcore_params[rte_lcore_id()].port != port)
            continue;

        printf("Initializing RX/TX queues for port %u...\n", port);

        struct rte_eth_dev_info dev_info;
        rte_eth_dev_info_get(port, &dev_info);

        struct rte_eth_rxconf rx_conf = dev_info.default_rxconf;
        struct rte_eth_txconf tx_conf = dev_info.default_txconf;
        
        /* Configure the Ethernet device. */
	rte_eth_dev_configure(port, 1, 1, &port_conf_default);
	
	/* Allocate and set up RX queue(s). */
	rte_eth_rx_queue_setup(port, 0, RX_RING_SIZE,
			       rte_eth_dev_socket_id(port),
			       &rx_conf,
			       mbuf_pool);

	/* Allocate and set up TX queue(s). */
	rte_eth_tx_queue_setup(port, 0, TX_RING_SIZE,
			       rte_eth_dev_socket_id(port),
			       &tx_conf);
	
        /* Start the Ethernet port. */
        rte_eth_dev_start(port);

        printf("Port %u initialized.\n", port);
    }

    while (1) {
        RTE_LCORE_FOREACH_SLAVE(port) {
            if (lcore_params[rte_lcore_id()].port != port)
                continue;

            struct rte_mbuf *bufs[BURST_SIZE];
            const uint16_t nb_rx = rte_eth_rx_burst(port, 0, bufs, BURST_SIZE);
            for (uint16_t i = 0; i < nb_rx; i++)
                packet_handler(bufs[i], port);

            rte_delay_us(10);
        }
    }

    return 0;
}

static int parse_args(int argc, char **argv) {
    int num_ports = rte_eth_dev_count_avail();

    if (num_ports == 0)
        return -1;

    for (int i = 0; i < RTE_MAX_LCORE; ++i) {
        lcore_params[i].port = UINT16_MAX;
    }

    int opt;
    while ((opt = getopt(argc, argv, "p:")) != EOF) {
        switch (opt) {
            case 'p':
                lcore_params[0].port = strtoul(optarg, NULL, 10);
                break;
            default:
                return -1;
        }
    }

    if (lcore_params[0].port == UINT16_MAX)
        return -1;

    return 0;
}

int main(int argc, char **argv) {

    int ret;

	ret = rte_eal_init(argc, argv);
	if (ret < 0)
		rte_exit(EXIT_FAILURE, "Error with EAL initialization\n");

	argc -= ret;
	argv += ret;

	if (parse_args(argc, argv) < 0) {
        printf("Usage: %s -p <port_id>\n", argv[0]);
		rte_exit(EXIT_FAILURE, "Invalid command-line arguments\n");
    }

    /* Create the mbuf pool. */
    struct rte_mempool *mbuf_pool =
        rte_pktmbuf_pool_create("MBUF_POOL", NUM_MBUFS * RTE_MAX_LCORE,
                                MBUF_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE,
                                rte_socket_id());

    if (mbuf_pool == NULL)
        rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");

	RTE_LCORE_FOREACH_SLAVE(ret) {
		if (lcore_params[ret].port == UINT16_MAX)
			continue;

		rte_eal_remote_launch(lcore_main, NULL, ret);
	}

	lcore_main(NULL);

	return 0;
}

请注意,此示例代码并未完全测试,可能需要进行修改才能正常工作。此外,如果要使用最新版的nDPI库,请确保已正确安装和配置该库。

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://sdn.0voice.com/?id=1241

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?