以下代码可以输出收到的数据包的IP地址、MAC地址和TCP端口。
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <inttypes.h>
#include <rte_eal.h>
#include <rte_ethdev.h>
#include <rte_mbuf.h>
#define RX_RING_SIZE 256
#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,
},
};
int main(int argc, char *argv[]) {
int ret;
uint16_t portid;
uint16_t nb_ports;
struct rte_eth_conf port_conf = port_conf_default;
struct rte_mempool *mbuf_pool;
struct rte_eth_rxconf rxq_conf;
struct rte_eth_dev_info dev_info;
uint16_t nb_rxd = RX_RING_SIZE;
uint16_t nb_txd = 0;
uint16_t q;
struct rte_eth_stats stats;
ret = rte_eal_init(argc, argv);
if (ret < 0)
rte_exit(EXIT_FAILURE, "Error with EAL initialization\n");
nb_ports = rte_eth_dev_count_avail();
if (nb_ports < 1)
rte_exit(EXIT_FAILURE, "Error: no Ethernet ports found.\n");
portid = 0;
mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NUM_MBUFS,
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");
printf("Initializing port %"PRIu16"...\n", portid);
ret = rte_eth_dev_configure(portid, 1, 1, &port_conf);
if (ret < 0)
rte_exit(EXIT_FAILURE, "Cannot configure device: err=%d, port=%"PRIu16"\n",
ret, portid);
ret = rte_eth_dev_adjust_nb_rx_tx_desc(portid, &nb_rxd, &nb_txd);
if (ret < 0)
rte_exit(EXIT_FAILURE, "Cannot adjust number of descriptors: err=%d, port=%"PRIu16"\n",
ret, portid);
rte_eth_macaddr_get(portid, &port_conf_default.rx_adv_conf.rss_conf.rss_key);
rxq_conf = dev_info.default_rxconf;
rxq_conf.offloads = port_conf_default.rxmode.offloads;
ret = rte_eth_rx_queue_setup(portid, 0, nb_rxd, rte_eth_dev_socket_id(portid),
&rxq_conf, mbuf_pool);
if (ret < 0)
rte_exit(EXIT_FAILURE, "rte_eth_rx_queue_setup:err=%d, port=%"PRIu16"\n",
ret, portid);
ret = rte_eth_dev_start(portid);
if (ret < 0)
rte_exit(EXIT_FAILURE, "rte_eth_dev_start:err=%d, port=%"PRIu16"\n",
ret, portid);
printf("Port %d started\n", portid);
printf("Accepting packets. Press Ctrl+C to quit.\n");
for (;;) {
struct rte_mbuf *bufs[BURST_SIZE];
const uint16_t nb_rx = rte_eth_rx_burst(portid, 0, bufs, BURST_SIZE);
if (unlikely(nb_rx == 0))
continue;
for (q = 0; q < nb_rx; q++) {
struct rte_mbuf *mbuf = bufs[q];
struct ether_hdr *eth_hdr = rte_pktmbuf_mtod(mbuf, struct ether_hdr*);
if (eth_hdr->ether_type == htons(ETHER_TYPE_IPv4)) {
struct ipv4_hdr *ipv4_hdr = (struct ipv4_hdr *)(eth_hdr + 1);
uint32_t src_ip = rte_be_to_cpu_32(ipv4_hdr->src_addr);
uint32_t dst_ip = rte_be_to_cpu_32(ipv4_hdr->dst_addr);
printf("Received packet with src IP address %"PRIu8".%"PRIu8".%"PRIu8".%"PRIu8
" and dst IP address %"PRIu8".%"PRIu8".%"PRIu8".%"PRIu8"\n",
(uint8_t)(src_ip >> 24), (uint8_t)(src_ip >> 16),
(uint8_t)(src_ip >> 8), (uint8_t)src_ip,
(uint8_t)(dst_ip >> 24), (uint8_t)(dst_ip >> 16),
(uint8_t)(dst_ip >> 8), (uint8_t)dst_ip);
} else if (eth_hdr->ether_type == htons(ETHER_TYPE_ARP)) {
// Handle ARP packets
} else if (eth_hdr->ether_type == htons(ETHER_TYPE_VLAN)) {
// Handle VLAN-tagged packets
} else {
printf("Received packet with unknown Ethernet type: %"PRIx16"\n", eth_hdr->ether_type);
}
rte_pktmbuf_free(mbuf);
}
}
return 0;
}
注意,上述代码只处理IPv4数据包。如果需要处理其他类型的数据包,请在if (eth_hdr->ether_type == htons(ETHER_TYPE_IPv4))
语句后添加相应的处理代码。