You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DPDK中无法正确打印IP地址的问题求助

DPDK Skeleton示例IP地址打印错误修复

使用DPDK Skeleton示例接收数据包时,打印的IP地址与实际发送的不符(实际发送ICMP包源IP为192.168.250.250,目的IP为192.168.250.1),尝试两种打印方式均得到错误结果:

struct rte_ipv4_hdr *ipv4_hdr = rte_pktmbuf_mtod_offset(bufs[0],
                                struct rte_ipv4_hdr *, sizeof(struct rte_ether_hdr));

/* 第一种方式输出错误IP */
struct in_addr ip_addr = {0};
ip_addr.s_addr = ipv4_hdr->src_addr;
printf("SrcIP: %s\n", inet_ntoa(ip_addr));
ip_addr.s_addr = ipv4_hdr->dst_addr;
printf("DstIP: %s\n", inet_ntoa(ip_addr));

/* 第二种方式输出错误IP */
printf("Source IP: %u.%u.%u.%u\n", (ipv4_hdr->src_addr >> 24) & 0xff,
          (ipv4_hdr->src_addr >> 16) & 0xff,
          (ipv4_hdr->src_addr >> 8) & 0xff,
          ipv4_hdr->src_addr & 0xff);
printf("Dest IP: %u.%u.%u.%u\n", (ipv4_hdr->dst_addr >> 24) & 0xff,
        (ipv4_hdr->dst_addr >> 16) & 0xff,
        (ipv4_hdr->dst_addr >> 8) & 0xff,
        (ipv4_hdr->dst_addr & 0xff));

问题原因

DPDK中rte_ipv4_hdr结构体的src_addr和dst_addr字段存储的是网络字节序(大端),而多数主机采用小端字节序,直接解析会导致字节顺序反转,从而得到错误的IP地址。

修复方案

方案1:修正inet_ntoa调用

inet_ntoa函数要求输入的是主机字节序的32位整数,需要用ntohl()将网络字节序转换为主机字节序:

struct in_addr ip_addr = {0};
ip_addr.s_addr = ntohl(ipv4_hdr->src_addr);
printf("SrcIP: %s\n", inet_ntoa(ip_addr));
ip_addr.s_addr = ntohl(ipv4_hdr->dst_addr);
printf("DstIP: %s\n", inet_ntoa(ip_addr));

方案2:修正手动拆分逻辑

网络字节序是大端格式,IP地址的第一个字节对应32位整数的最低8位,因此调整拆分顺序:

printf("Source IP: %u.%u.%u.%u\n",
       (ipv4_hdr->src_addr & 0xff),
       (ipv4_hdr->src_addr >> 8) & 0xff,
       (ipv4_hdr->src_addr >> 16) & 0xff,
       (ipv4_hdr->src_addr >> 24) & 0xff);
printf("Dest IP: %u.%u.%u.%u\n",
       (ipv4_hdr->dst_addr & 0xff),
       (ipv4_hdr->dst_addr >> 8) & 0xff,
       (ipv4_hdr->dst_addr >> 16) & 0xff,
       (ipv4_hdr->dst_addr >> 24) & 0xff);

或者先转为主机字节序,再按原逻辑拆分:

uint32_t src_ip = ntohl(ipv4_hdr->src_addr);
uint32_t dst_ip = ntohl(ipv4_hdr->dst_addr);
printf("Source IP: %u.%u.%u.%u\n",
       (src_ip >> 24) & 0xff,
       (src_ip >> 16) & 0xff,
       (src_ip >> 8) & 0xff,
       src_ip & 0xff);
printf("Dest IP: %u.%u.%u.%u\n",
       (dst_ip >> 24) & 0xff,
       (dst_ip >> 16) & 0xff,
       (dst_ip >> 8) & 0xff,
       dst_ip & 0xff);

额外说明

你获取IP头指针的方式是正确的,rte_pktmbuf_mtod_offset通过跳过以太网头的大小,准确指向了IP头,偏移问题不存在,核心问题完全是字节序转换缺失导致的。

内容的提问来源于stack exchange,提问作者budoattack

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 23:07:45