我正在使用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
的驱动器链接克隆前和克隆后发送的数据包应该是相同的。谁能指出我这里是什么搞砸了吗?!谢谢
1条答案
按热度按时间kx7yvsdv1#
如果dns_question_t和dns_new_hdr_t结构中存在任何指针(用于DNS名称),请检查pkt_size值。您需要正确计算IPV4和UPD标头长度,包括指针值大小。请共享您发送的出错数据包示例,这有助于调试