ZBLOG

19.2版本的dpdk使用最新版nDPI过滤http协议代码

以下是使用DPDK 19.2版本和最新版nDPI过滤HTTP协议的代码示例:

#include <rte_common.h>
#include <rte_mbuf.h>
#include <rte_ethdev.h>
#include <rte_ether.h>
#include <rte_ip.h>
#include <rte_udp.h>
#include <ndpi_protocol_ids.h>
#include <ndpi_api.h>

#define HTTP_PORT 80

// Initialize nDPI library and return handle
struct ndpi_detection_module_struct *init_ndpi(void) {
    // Allocate memory for nDPI detection module
    struct ndpi_detection_module_struct *handle = malloc(sizeof(struct ndpi_detection_module_struct));

    // Initialize nDPI detection module
    if (!ndpi_init_detection_module(handle, NDPI_PROTOCOL_UNKNOWN)) {
        printf("ERROR: Could not initialize nDPI detection module\n");
        exit(EXIT_FAILURE);
    }

    // Enable HTTP detection
    ndpi_set_protocol_detection_bitmask2(handle, NDPI_PROTOCOL_HTTP, NDPI_PROTOCOL_CATEGORY_WEBMAIL|NDPI_PROTOCOL_CATEGORY_SOCIAL_NETWORK|NDPI_PROTOCOL_CATEGORY_SEARCH_ENGINE);

    return handle;
}

// Process incoming packets using nDPI library to detect HTTP traffic
void process_packet(struct rte_mbuf *pkt, struct ndpi_detection_module_struct *handle) {
    // Parse Ethernet header
    struct ether_hdr *eth_hdr = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
    
    // Only process IPv4 packets with UDP transport layer protocol
    if (eth_hdr->ether_type == htons(ETHER_TYPE_IPv4)) {
        struct ipv4_hdr *ip_hdr = (struct ipv4_hdr *)((char *)eth_hdr + sizeof(struct ether_hdr));
        
        if (ip_hdr->next_proto_id == IPPROTO_UDP) {
            struct udp_hdr *udp_hdr = (struct udp_hdr *)((char *)ip_hdr + sizeof(struct ipv4_hdr));
            
            // Check if packet is sent to HTTP port
            if (ntohs(udp_hdr->dst_port) == HTTP_PORT) {
                // Parse payload of UDP packet
                uint16_t pkt_len = rte_pktmbuf_data_len(pkt);
                char *payload = (char *)rte_pktmbuf_mtod_offset(pkt, char *, sizeof(struct ether_hdr) + sizeof(struct ipv4_hdr) + sizeof(struct udp_hdr));
                
                // Detect protocol using nDPI library
                struct ndpi_detection_results results;
                ndpi_protocol detected_proto = ndpi_detection_process_packet(handle, (uint8_t*)payload, pkt_len, 0, &results);

                // Print detected protocol and other information
                if (detected_proto == NDPI_PROTOCOL_HTTP) {
                    printf("Detected HTTP traffic with %u bytes\n", pkt_len);
                    printf("HTTP host: %s\n", results.http.host_name);
                    printf("HTTP user agent: %s\n", results.http.user_agent);
                    printf("HTTP URI: %s\n", results.http.uri);
                }
            }
        }
    }
}

int main(int argc, char **argv) {
    // Initialize DPDK environment
    int ret = rte_eal_init(argc, argv);
    if (ret < 0)
        rte_exit(EXIT_FAILURE, "Cannot initialize EAL\n");
    
    // Get number of available network interfaces
    uint16_t nb_ports = rte_eth_dev_count_avail();
    
    // Configure and start first network interface in promiscuous mode
    struct rte_eth_conf port_conf;
    memset(&port_conf, 0, sizeof(port_conf));
    port_conf.rxmode.mq_mode = ETH_MQ_RX_NONE;
    port_conf.rxmode.max_rx_pkt_len = ETHER_MAX_LEN;
    port_conf.rxmode.split_hdr_size = 0;
    port_conf.rxmode.offloads = DEV_RX_OFFLOAD_CHECKSUM;
    port_conf.txmode.mq_mode = ETH_MQ_TX_NONE;

    struct rte_eth_dev_info dev_info;
    rte_eth_dev_info_get(0, &dev_info);
    uint16_t rx_rings = dev_info.max_rx_queues;

    ret = rte_eth_dev_configure(0, rx_rings, 1, &port_conf);
    if (ret < 0)
        rte_exit(EXIT_FAILURE, "Cannot configure network interface\n");

    for (uint16_t q = 0; q < rx_rings; q++) {
        ret = rte_eth_rx_queue_setup(0, q, RX_RING_SIZE, rte_eth_dev_socket_id(0), NULL, NULL);
        if (ret < 0)
            rte_exit(EXIT_FAILURE, "Cannot setup RX queue\n");
    }

    ret = rte_eth_promiscuous_enable(0);
    if (ret != 0)
        rte_exit(EXIT_FAILURE, "Cannot enable promiscuous mode on network interface\n");

    ret = rte_eth_dev_start(0);
    if (ret < 0)
        rte_exit(EXIT_FAILURE, "Cannot start network interface\n");

    // Initialize nDPI library
    struct ndpi_detection_module_struct *handle = init_ndpi();
    
    // Process incoming packets indefinitely
    while (1) {
        struct rte_mbuf *pkt;
        
        RTE_ETH_FOREACH_DEV(0) {
            uint16_t nb_rx_pkts = rte_eth_rx_burst(0, 0, &pkt, 1);

            for (uint16_t i = 0; i < nb_rx_pkts; i++)
                process_packet(pkt[i], handle);
            
            if (nb_rx_pkts > 0)
                rte_pktmbuf_free(pkt);
        }
    }

    return 0;
}

此代码使用DPDK的Ethernet、IPv4和UDP头文件解析收到的数据包,然后使用nDPI库检测HTTP流量。如果检测到HTTP流量,则打印一些信息,例如主机名、用户代理和URI。

请注意,此代码只处理一个网络接口,并且假定该接口在DPDK环境中已配置并启动。您可能需要根据自己的需求进行更改。

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

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

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

联系我们

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

微信号:3007537140

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

关注我们
x

注册

已经有帐号?