从端口 6343 捕获 sflow 数据时,UDP 标头长度字段始终为零 [英] UDP header length field is zero always while capturing sflow data from port 6343

查看:38
本文介绍了从端口 6343 捕获 sflow 数据时,UDP 标头长度字段始终为零的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to capture the UDP sflow data from port 6343. I am trying to capture the UDP header information which provides source port, destination port, UDP header length and checksum. I am able to see the ports capturing, but the UDP and checksum fields are 0 and 1 respectively which means the UDP length is not calculated and checksum is also not calculated. Am I missing something here for UDP header length and checksum calculation ?? The following is my code which I use:

#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类型的socket时,操作系统处理IP和UDP标题并在将它们传递给您之前将它们剥离.您在 buffer 中看到的是紧跟在 UDP 标头之后的内容.

When use create a socket of type AF_INET / SOCK_DGRAM, the operating system processes and IP and UDP headers and strips them off before passing them to you. What you see in buffer is what immediately follows the UDP header.

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

You're passed back the source IP and port via fifth parameter to the recvfrom function, and the payload length is passed back as the return value. If there is a problem with the UDP checksum, the OS would discard the packet and your application code would never see it, so it's not something you typically need to worry about on the application level.

这篇关于从端口 6343 捕获 sflow 数据时,UDP 标头长度字段始终为零的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆