从端口 6343 捕获 sflow 数据时,UDP header 长度字段始终为零
UDP header length field is zero always while capturing sflow data from port 6343
我正在尝试从端口 6343 捕获 UDP sflow 数据。我正在尝试捕获提供源端口、目标端口、UDP header 长度和校验和的 UDP header 信息。我能够看到端口捕获,但 UDP 和校验和字段分别为 0 和 1,这意味着 UDP 长度未计算,校验和也未计算。我在这里缺少 UDP header 长度和校验和计算的东西吗?
以下是我使用的代码:
#include<stdio.h> //For standard things
#include<stdlib.h> //malloc
#include<string.h> //memset
#include<netinet/ip_icmp.h> //Provides declarations for icmp header
#include<netinet/udp.h> //Provides declarations for udp header
#include<netinet/tcp.h> //Provides declarations for tcp header
#include<netinet/ip.h> //Provides declarations for ip header
#include<sys/socket.h>
#include<arpa/inet.h>
#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 <0)
{
printf("Packets not recieved \n");
return 1;
}
//Now process the packet
handlepacket(buffer , data_size);
printf("Packets arrived from %d \n",ntohs(daddr.sin_port));
printf("Source Port : %d , Destination Port : %d \n", ntohs(udph->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 headers 并在将它们传递给您之前将其剥离。您在 buffer
中看到的是紧跟在 UDP header 之后的内容。
您通过第五个参数将源 IP 和端口传回给 recvfrom
函数,有效负载长度作为 return 值传回。如果 UDP 校验和有问题,OS 会丢弃数据包,您的应用程序代码将永远看不到它,因此您通常不需要在应用程序级别担心。
我正在尝试从端口 6343 捕获 UDP sflow 数据。我正在尝试捕获提供源端口、目标端口、UDP header 长度和校验和的 UDP header 信息。我能够看到端口捕获,但 UDP 和校验和字段分别为 0 和 1,这意味着 UDP 长度未计算,校验和也未计算。我在这里缺少 UDP header 长度和校验和计算的东西吗? 以下是我使用的代码:
#include<stdio.h> //For standard things
#include<stdlib.h> //malloc
#include<string.h> //memset
#include<netinet/ip_icmp.h> //Provides declarations for icmp header
#include<netinet/udp.h> //Provides declarations for udp header
#include<netinet/tcp.h> //Provides declarations for tcp header
#include<netinet/ip.h> //Provides declarations for ip header
#include<sys/socket.h>
#include<arpa/inet.h>
#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 <0)
{
printf("Packets not recieved \n");
return 1;
}
//Now process the packet
handlepacket(buffer , data_size);
printf("Packets arrived from %d \n",ntohs(daddr.sin_port));
printf("Source Port : %d , Destination Port : %d \n", ntohs(udph->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 headers 并在将它们传递给您之前将其剥离。您在 buffer
中看到的是紧跟在 UDP header 之后的内容。
您通过第五个参数将源 IP 和端口传回给 recvfrom
函数,有效负载长度作为 return 值传回。如果 UDP 校验和有问题,OS 会丢弃数据包,您的应用程序代码将永远看不到它,因此您通常不需要在应用程序级别担心。