在从端口6343捕获sflow数据时,UDP报头长度字段始终为零

我试图从端口6343捕获UDP sflow数据。我试图捕获UDP头信息,它提供源端口,目标端口,UDP头长度和校验和。 我能够看到端口捕获,但UDP和校验和字段分别为0和1,这意味着不计算UDP长度,也不计算校验和。 我在这里遗漏了UDP标头长度和校验和计算的内容吗? 以下是我使用的代码:

#include //For standard things #include //malloc #include //memset #include //Provides declarations for icmp header #include //Provides declarations for udp header #include //Provides declarations for tcp header #include //Provides declarations for ip header #include #include #define PORT 6343 #define PCKT_LEN 65536 void handlepacket(unsigned char *, int); int sockt; int i,j; struct sockaddr_in source,dest; int main() { int saddr_size,data_size; struct sockaddr_in daddr; struct sockaddr_in saddr; //struct in_addr in; unsigned char *buffer = (unsigned char *)malloc(65536); // Its Big ! Malloc allocates a block of size bytes of memory,returning a pointer to the begining of the block struct udphdr *udph = (struct udphdr*)(buffer + sizeof(struct iphdr)); printf("Starting...\n"); //Create a raw socket that shall sniff sockt = socket(AF_INET ,SOCK_DGRAM ,0); if(sockt < 0) { printf("Socket Error\n"); return 1; } memset((char *)&daddr,0,sizeof(daddr)); //prepare the sockaddr_in structure daddr.sin_family = AF_INET; daddr.sin_addr.s_addr = INADDR_ANY; daddr.sin_port = htons(PORT); //Bind if(bind(sockt,(struct sockaddr *)&daddr, sizeof(daddr))<0) { printf("bind failed"); return 1; } printf("bind done"); while(1) { saddr_size = sizeof saddr; printf("waiting for data..."); //Receive a packet data_size = recvfrom(sockt , buffer ,65536 , 0 , (struct sockaddr*) &saddr , (socklen_t*)&saddr_size); if(data_size source), ntohs(udph->dest)); } close(sockt); printf("Finished"); return 0; } void handlepacket(unsigned char *buffer, int data_size) { //IP header length struct iphdr *iph = (struct iphdr *)buffer; unsigned short iphdrlen = iph->ihl*4; // UDP header length struct udphdr *udph = (struct udphdr*)(buffer + iphdrlen); memset(&source,0,sizeof(source)); source.sin_addr.s_addr = iph ->saddr; memset(&dest,0,sizeof(dest)); dest.sin_addr.s_addr = iph->daddr; printf("UDP Length : %d , UDP checksum : %d \n",ntohs(udph->len), ntohs(udph->check)); } 

当使用创建类型为AF_INET / SOCK_DGRAM的套接字时,操作系统会处理IP和UDP标头,并在将它们传递给您之前将其剥离。 您在buffer看到的是紧跟在UDP标头之后的内容。

您通过第五个参数将源IP和端口传递回recvfrom函数,并将有效负载长度作为返回值传回。 如果UDP校验和存在问题,操作系统将丢弃该数据包,您的应用程序代码将永远不会看到它,因此您通常不需要担心应用程序级别。