C语言 DPDK:DNS查询数据包中的数据包格式错误、IP长度错误和UDP长度错误

4sup72z8  于 2023-03-01  发布在  其他
关注(0)|答案(1)|浏览(199)

我正在使用dpdk-stable-19.11.10版本为我的项目。基本上我正在建立一个DNS标准查询消息,并通过路由器(DUT)发送到DNS服务器/响应器。我面临的问题,当我在DNS服务器接收数据包,一些数据包是畸形的,由于以下原因:虚假IP长度、错误UDP长度和DNS格式错误的数据包。
第一种情况:我正在构建一个DNS查询数据包,如下所示:

m = rte_pktmbuf_alloc(info->q[qid].tx_mp);

dns_qhdr = rte_pktmbuf_mtod(m, struct dns_question_t *);
(.....dns question header)
pkt_size += sizeof(struct dns_question_t);

query_name = (unsigned char *)rte_pktmbuf_prepend(m, (strlen(dns_application_data) + 1));
prev_str_len = (strlen(dns_application_data) + 1);
memset(query_name, 0, prev_str_len);
strncpy((query_name), dns_application_data, (strlen(dns_application_data)));
pkt_size += (strlen(dns_application_data) + 1);

dns_hdr = (struct dns_new_hdr_t *)rte_pktmbuf_prepend(m, (uint16_t)sizeof(struct dns_new_hdr_t));
(.....dns header)
pkt_size +=  sizeof(struct dns_new_hdr_t);

udp_hdr = (struct udphdr *)rte_pktmbuf_prepend(m, (uint16_t)sizeof(struct udphdr));
l4_len = L4_UDP_HDR_SIZE + pkt_size;
udp_hdr->len = htons(l4_len);

ip_hdr = (struct iphdr *)rte_pktmbuf_prepend(m, (uint16_t)sizeof(struct iphdr));
ip_hdr->tot_len = htons(pkt_size + L3_IPV4_HDR_SIZE);

eth_hdr = (struct ethernet_hdr *)rte_pktmbuf_prepend(m, (uint16_t)sizeof(struct ethernet_hdr));

m->data_len = m->pkt_len = pkt_size;
rte_memcpy((struct rte_mbuf *)(store_packets[streams]), m, mbuf_len);
send_mbuf(m, port, qid);(calling ```rte_eth_tx_burst``` to send packets).

我使用ol_flags将校验和卸载到硬件,没有问题。
我没有任何问题,如果我发送数据包像以上。但如果我试图发送以下格式的数据包,我看到问题的rx端口(在DNS服务器)。
第二例:因此,我使用rte_memcpy复制数据包并将其存储到数组rte_memcpy((struct rte_mbuf *)(store_packets[streams]), m, mbuf_len);中,而不是构建每个数据包报头值
稍后使用rte_pktmbuf_clone克隆数据包m = rte_pktmbuf_clone((struct rte_mbuf *)(store_packets[streams]), info->q[qid].tx_mp);rte_pktmbuf_mtod_offset以更改DNS、UDP、IPV4和ETHERNET报头值。

pkt_size = 0;
dns_hdr = (struct dns_new_hdr_t *) rte_pktmbuf_mtod_offset(m, struct dns_new_hdr_t *,sizeof(struct ethernet_hdr) + L3_IPV4_HDR_SIZE  + sizeof(struct udphdr));

unsigned char *query_name = (unsigned char*) rte_pktmbuf_mtod_offset(m, struct dns_qhdr *,sizeof(struct ethernet_hdr) + L3_IPV4_HDR_SIZE + sizeof(struct udphdr) + sizeof(struct dns_new_hdr_t));
prev_str_len = (strlen(dns_application_data) + 1);
memset(query_name, 0, prev_str_len);
strncpy((query_name), dns_application_data, (strlen(dns_application_data)));

dns_qhdr = (struct dns_question_t *) rte_pktmbuf_mtod_offset(m, struct dns_question_t*,(sizeof(struct ethernet_hdr) +  L3_IPV4_HDR_SIZE + sizeof(struct udphdr) + sizeof(struct dns_new_hdr_t) + prev_str_len));

pkt_size += sizeof(struct ethernet_hdr) +  L3_IPV4_HDR_SIZE + L4_UDP_HDR_SIZE +  sizeof(struct dns_new_hdr_t) + sizeof(struct dns_question_t) + prev_str_len;

ip_hdr = rte_pktmbuf_mtod_offset(m, struct iphdr *, (sizeof(struct ethernet_hdr)));
ip_hdr->tot_len = htons(pkt_size - sizeof(struct ethernet_hdr));

udp_hdr = (struct udphdr *)  rte_pktmbuf_mtod_offset(m, struct udphdr *,sizeof(struct ethernet_hdr) + sizeof(struct iphdr));
l4_len = sizeof(struct dns_question_t) + sizeof(struct dns_new_hdr_t) + prev_str_len + L4_UDP_HDR_SIZE;
udp_hdr->len = htons(l4_len);

m->data_len = m->pkt_len = pkt_size;
rte_eth_tx_burst();

由于IPV4和UDP长度取决于DNS查询消息,所以我最后更新了IP4总长度和UDP长度。
克隆数据包(根据DNS查询消息pkt_size可能不同)并发送后,我将重新计算数据包大小。
m->data_len = m->pkt_len = pkt_size;
克隆数据包后,我使用rte_pktmbuf_mtod_offset更改了所有(L7到L2)报头值,但我仍然看到***假IPV4长度、错误UDP长度和格式错误的DNS数据包***。
请找到tx和rx pcaps.https://drive.google.com/drive/folders/1UsJFAOG2AjtT1-5n2kgVKpm6xKkWV96W?usp=sharing的驱动器链接克隆前和克隆后发送的数据包应该是相同的。谁能指出我这里是什么搞砸了吗?!谢谢

kx7yvsdv

kx7yvsdv1#

如果dns_question_t和dns_new_hdr_t结构中存在任何指针(用于DNS名称),请检查pkt_size值。您需要正确计算IPV4和UPD标头长度,包括指针值大小。请共享您发送的出错数据包示例,这有助于调试

相关问题