PCAP头,获取UDP信息
我试图从数据包捕获中获取UDP信息,但我不知道这些信息在哪里。我知道以太网报头是14字节,IPv6报头是40字节。此外,UDP源端口是UDP头中的前2个字节。因此,它应该是14+40-1=53。因此UDP源端口应该是字节54和55。不对,我拿到20016了。对于我使用的示例pcap文件,它应该是51216。其他一切都是正确的,确定IPv4或IPv6,并确定是UDP还是TCPPCAP头,获取UDP信息,udp,ipv6,pcap,Udp,Ipv6,Pcap,我试图从数据包捕获中获取UDP信息,但我不知道这些信息在哪里。我知道以太网报头是14字节,IPv6报头是40字节。此外,UDP源端口是UDP头中的前2个字节。因此,它应该是14+40-1=53。因此UDP源端口应该是字节54和55。不对,我拿到20016了。对于我使用的示例pcap文件,它应该是51216。其他一切都是正确的,确定IPv4或IPv6,并确定是UDP还是TCP int main(int argc, char *argv[]) { pcap_t *pcap_handle =
int main(int argc, char *argv[]) {
pcap_t *pcap_handle = NULL; /* Handle for PCAP library */
struct pcap_pkthdr *packet_hdr = NULL; /* Packet header from PCAP */
const u_char *packet_data = NULL; /* Packet data from PCAP */
int ret = 0; /* Return value from library calls */
char use_file = 0; /* Flag to use file or live capture */
/* Setup the capture and get the valid handle. */
pcap_handle = setup_capture(argc, argv, &use_file);
/* Loop through all the packets in the trace file.
* ret will equal -2 when the trace file ends.
* ret will never equal -2 for a live capture. */
ret = pcap_next_ex(pcap_handle, &packet_hdr, &packet_data);
struct ether_header
{
u_int8_t ether_dhost[6]; /* destination eth addr */
u_int8_t ether_shost[6]; /* source ether addr */
u_int16_t ether_type; /* packet type ID field */
};
struct ether_header *eptr;
char src[INET_ADDRSTRLEN];
char dst[INET_ADDRSTRLEN];
char src6[INET6_ADDRSTRLEN];
char dst6[INET6_ADDRSTRLEN];
while( ret != -2 ) {
if( valid_capture(ret, pcap_handle, use_file) ){
eptr = (struct ether_header *) packet_data;
fprintf(stdout,"%s -> ",ether_ntoa((const struct ether_addr *)&eptr->ether_shost));
fprintf(stdout,"%s \n",ether_ntoa((const struct ether_addr *)&eptr->ether_dhost));
if(packet_data[12] == 0x08 && packet_data[13] == 0x00)
{
printf(" [IPv4] ");
fprintf(stdout,"%s -> ", inet_ntop(AF_INET,(const void *)packet_data+26,src,INET_ADDRSTRLEN));
fprintf(stdout,"%s\n", inet_ntop(AF_INET,(const void *)packet_data+30,dst,INET_ADDRSTRLEN));
if(packet_data[23] == 0x06)
{
printf(" [TCP] \n");
}
else if(packet_data[23] == 0x11)
{
}
else{
printf(" [%d] \n",packet_data[23]);
}
}
else if(packet_data[12] == 0x86 && packet_data[13] == 0xdd)
{
printf("[IPv6] ");
printf("%s -> ", inet_ntop(AF_INET6, (const void *)packet_data+22, src6, INET6_ADDRSTRLEN));
printf("%s \n", inet_ntop(AF_INET6, (const void *)packet_data+38, dst6, INET6_ADDRSTRLEN));
if(packet_data[20] == 0x06)
{
printf(" [TCP] \n");
}
else if(packet_data[20] == 0x11)
{
printf("[UDP] Source: %d",packet_data[54]); //problem here
printf("%d \n",packet_data[55]); //problem here
}
else{
printf(" [%d] \n",packet_data[20]);
}
} else {
fprintf(stdout," [%d] \n",ntohs(eptr->ether_type));
}
谢谢你的帮助和指导
printf("[UDP] Source: %d",packet_data[54]); //problem here
printf("%d \n",packet_data[55]); //problem here
UDP端口是网络字节顺序的16位整数。而是将其打印为两个8位整数。假设您打印的是
20016
数据[54]
可能是200
,数据[55]
是16
。因此,端口的正确值是200*256+16=51216
,这正是您所期望的。Aww为什么这个问题会被否决?您的问题缺少任何代码来重现您的问题,因此很难判断您做错了什么。但是,只有当pcap链路类型为DLT_EN10MB并且UDP是IPv6数据包中的第一个扩展头时,您的参数才是正确的。啊,好的。我会附上我的密码。不确定DLT_EN10MB是什么,但我有一个检查,根据IPv6报头中的协议值确定它是否为UDB。我只是得到了错误的端口号。DLT_EN10MB是pcap文件可能使用的众多链接类型之一。不同的链接类型具有不同的大小,因此您需要检查pcap文件使用的类型。看到了吗?好的,所以我得到了正确的数组索引,只是转换不正确。@Mike1982:正确。这就是为什么在问题中包含代码几乎总是更好的原因:)谢谢。那么,有没有一个内置函数可以为我进行这种转换?我做了packet_data[54]*256+packet_data[55]并且它可以工作,但是我不知道硬编码是否是一个理想的解决方案。有没有一个内置的网络功能可以为我做到这一点?有。但当然,您必须首先将这两个字节视为uint16\u t
,这可以用C进行一些转换,即htons(*(uint16\u t*)(packet\u data+54))