如何使用 C 程序读取来自端口的 UDP 数据负载 [英] How to read the UDP data payload coming from a port using C program

查看:30
本文介绍了如何使用 C 程序读取来自端口的 UDP 数据负载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从端口 6343 捕获 UDP 数据包.在捕获它的同时,我还必须捕获有效负载.我正在获取 ASCII 格式的有效负载.我必须阅读有效载荷的内容.以下是我的代码:

#include//对于标准的东西#include//malloc#include//内存集#include//为icmp头提供声明#include//提供udp头的声明#include//提供tcp头的声明#include//提供ip头的声明#include#include#define 端口 6343void print_udp_packet(unsigned char*, int);void ProcessPacket(unsigned char*, int);void PrintData (unsigned char* , int);国际袜子;int i,j;struct sockaddr_in source,dest;int main(){int saddr_size,data_size;结构 sockaddr_in 萨德尔;结构 sockaddr_in 爸爸;//struct in_addr in;unsigned char *buffer = (unsigned char *)malloc(65536);//它很大!Malloc 分配一块大小为字节的内存,返回一个指向块开头的指针struct udphdr *udph = (struct udphdr*)(buffer + sizeof(struct iphdr));struct iphdr *iph = (struct iphdr *)buffer;memset(&source,0,sizeof(source));source.sin_addr.s_addr = iph ->saddr;memset(&dest,0,sizeof(dest));dest.sin_addr.s_addr = iph->daddr;unsigned short iphdrlen = iph->ihl*4;printf("开始...\n");//创建一个套接字袜子=套接字(AF_INET,SOCK_DGRAM,0);如果(袜子<0){printf("套接字错误\n");返回 1;}memset((char *)&daddr,0,sizeof(daddr));//准备sockaddr_in结构daddr.sin_family = AF_INET;daddr.sin_addr.s_addr = htonl(INADDR_ANY);daddr.sin_port = htons(PORT);//绑定if(bind(sockt,(struct sockaddr *)&daddr, sizeof(daddr))<0){printf("绑定失败");返回 1;}printf("绑定完成");同时(1){saddr_size = sizeof saddr;printf("正在等待数据...");//接收数据包data_size = recvfrom(sockt , buffer ,65536 , 0 , (struct sockaddr*) &saddr , (socklen_t*)&saddr_size);如果(数据大小<0){printf("未收到数据包\n");返回 1;}printf("数据包来自 %d \n",ntohs(daddr.sin_port));printf("\t 源端口:%d,目标端口:%d,UDP 长度:%d,协议:%d,总长度:%d \n", ntohs(udph->source), ntohs(udph->dest), ntohs(data_size), (unsigned int)iph->protocol, ntohs(iph->tot_len));printf("源 IP : %s\n",inet_ntoa(saddr.sin_addr));printf("目标 IP : %s\n",inet_ntoa(daddr.sin_addr));ProcessPacket(缓冲区,数据大小);}关闭(袜子);printf("完成");返回0;}void ProcessPacket(无符号字符*缓冲区,整数大小){print_udp_packet(缓冲区,大小);}void print_udp_packet(unsigned char *buffer , int size){无符号短 iphdrlen;struct iphdr *iph = (struct iphdr *)buffer;iphdrlen = iph->ihl*4;struct udphdr *udph = (struct udphdr*)(buffer + iphdrlen);printf("数据有效载荷\n");PrintData(buffer + iphdrlen + sizeof udph,(size - sizeof udph - iph->ihl * 4 ));printf("\n########################################################");}void PrintData (unsigned char* data , int size){for(i=0 ; i <大小 ; i++){if( i!=0 && i%16==0)//如果一行十六进制打印完成...{printf("");for(j=i-16 ; j=32 && data[j]<=128)printf("%c",(unsigned char)data[j]);//如果是数字或字母否则 printf(".");//否则打印一个点}printf("\n");}if(i%16==0) printf(" ");printf(" %02X",(unsigned int)data[i]);if( i==size-1)//打印最后一个空格{for(j=0;j<15-i%16;j++) printf(" ");//多余的空格printf("");for(j=i-i%16 ; j<=i ; j++){if(data[j]>=32 && data[j]<=128) printf("%c",(unsigned char)data[j]);否则 printf(".");}printf("\n");}}}

我收到的输出如下:

源端口:55784,目的端口:59568,UDP长度:5122,协议:188,总长度:5122源IP:147.188.195.6目标 IP : 0.0.0.0数据负载93 BC C0 06 00 00 00 00 00 1F 39 D4 D9 E8 E8 B0 .....9 .....00 00 00 03 00 00 00 01 00 00 00 9C 00 B1 C9 4E ...............N00 00 00 1D 00 00 01 00 78 F9 F5 6B 00 10 67 8F ........x..k..g.00 00 00 1D 00 00 00 28 00 00 00 02 00 00 00 01 .......(......00 00 00 5C 00 00 00 01 00 00 00 4E 00 00 00 04 ...\.......N..00 00 00 4C F0 92 1C 48 C2 00 00 0E 0C 30 C7 C7 ...L...H.....0..08 00 45 00 00 3C 28 4D 40 00 25 06 1C 7E 4C 5C ..E..<(M@.%..~L\70 AE 93 BC C0 2A B4 FE 00 50 59 41 29 30 00 00 p..*...PYA)0..00 00 A0 02 FF FF FD BF 00 00 02 04 05 B4 04 02 .....................08 0A 00 13 01 7D 00 00 00 00 01 03 03 06 00 00 .....} .....00 00 03 E9 00 00 00 10 00 00 00 03 00 00 00 02 .....................00 00 00 02 FF FF FF FF 00 00 00 01 00 00 00 A8 .....................00 B1 C9 4F 00 00 00 1D 00 00 01 00 78 F9 F6 82 ...O........x...00 10 67 8F 00 00 00 1D 00 00 00 00 00 00 00 02 .....00 00 00 01 00 00 00 68 00 00 00 01 00 00 00 59 .......h.......Y00 00 00 04 00 00 00 58 F0 92 1C 48 C2 00 00 0E .......X...H..0C 30 C7 C7 08 00 45 00 00 47 D8 94 00 00 2F 11 .0....E..G..../.2F 0A 46 27 EA 1F 93 BC C0 04 17 72 00 35 00 33/.F'.......r.5.3BF 19 43 B9 00 10 00 01 00 00 00 00 00 01 03 6E ...................n73 32 04 73 75 73 78 02 61 63 02 75 6B 00 00 01 s2.susx.ac.uk...00 01 00 00 29 10 00 00 00 80 00 00 00 00 00 00 ...........00 00 03 E9 00 00 00 10 00 00 00 03 00 00 00 02 .....................00 00 00 02 FF FF FF FF 00 00 00 01 00 00 00 9C .....................00 B1 C9 50 00 00 00 1D 00 00 01 00 78 F9 F6 F0 ...P........x...00 10 67 8F 00 00 00 00 00 00 00 1D 00 00 00 02 .....00 00 00 01 00 00 00 5C 00 00 00 01 00 00 00 50 .......\.......P00 00 00 04 00 00 00 4C 00 0E 0C 30 C7 C7 F0 92 ....L...0....1C 48 C2 00 08 00 45 00 00 3E BC F6 00 00 3F 11 .H....E..>....?.38 9F 93 BC C0 04 C2 53 70 05 00 35 BE FE 00 2A 8......Sp..5......*28 53 82 D8 81 05 00 01 00 00 00 00 00 00 03 77 (S......w77 77 06 67 6F 6F 67 6C 65 02 63 6F 02 75 6B 00 ww.google.co.uk.00 01 00 01 00 00 03 E9 00 00 00 10 FF FF FF FF .....................00 00 00 00 00 00 00 03 FF FF FF FF ......................

我很困惑如何将这些数据变成可读的形式以了解有效负载的内容?

解决方案

首先,您打印的端口号、协议和数据长度不正确.正如我在中提到的那样我对您上一个问题的回答,IP 和 UDP 标头不包含在由 recvfrom 填充的缓冲区中.源端口和目标端口分别位于 saddr.sin_portdaddr.sin_port 中(确保在打印前在这些字段上调用 ​​ntohs),并且UDP payload长度为recvfrom的返回值,即data_size.

至于数据负载的格式,您需要确切知道您收到的数据是什么格式.在此基础上,您可以提取相关字段并以可读格式打印它们.对于初学者,您可以从 main 调用 PrintData 而不是 ProcessPacket,因为您无需担心 IP 和 UDP 标头.

I am trying to capture the UDP data packets from port 6343. while capturing it, I have to capture the payload also. I am getting the payload in ASCII format. I have to read the contents of the payload. The following is my code:

#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


void print_udp_packet(unsigned char*, int);
void ProcessPacket(unsigned char*, int);
void PrintData (unsigned char* , int);

int sockt;
int i,j;

struct sockaddr_in source,dest; 

int main()
{
    int saddr_size,data_size;
    struct sockaddr_in saddr;
    struct sockaddr_in daddr;

    //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));
    struct iphdr *iph = (struct iphdr *)buffer;
    memset(&source,0,sizeof(source));
    source.sin_addr.s_addr = iph ->saddr;
    memset(&dest,0,sizeof(dest));
    dest.sin_addr.s_addr = iph->daddr;
    unsigned short iphdrlen = iph->ihl*4;


    printf("Starting...\n");
    //Create a socket
    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 = htonl(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;
    }

    printf("Packets arrived from %d \n",ntohs(daddr.sin_port));
    printf("\t Source Port : %d , Destination Port : %d, UDP Length : %d,Protocol : %d, total length : %d \n", ntohs(udph->source), ntohs(udph->dest), ntohs(data_size), (unsigned int)iph->protocol, ntohs(iph->tot_len)); 
    printf("Source IP        : %s\n",inet_ntoa(saddr.sin_addr));
    printf("Destination IP   : %s\n",inet_ntoa(daddr.sin_addr));
    ProcessPacket(buffer,data_size);
    }
    close(sockt);
    printf("Finished");
    return 0;
}

void ProcessPacket(unsigned char* buffer, int size)
{

    print_udp_packet(buffer ,size);

}

void print_udp_packet(unsigned char *buffer , int size)
{

    unsigned short iphdrlen;

    struct iphdr *iph = (struct iphdr *)buffer;
    iphdrlen = iph->ihl*4;

    struct udphdr *udph = (struct udphdr*)(buffer + iphdrlen);

    printf("Data Payload\n");  
    PrintData(buffer + iphdrlen + sizeof udph ,( size - sizeof udph - iph->ihl * 4 ));

    printf("\n###########################################################");
}

void PrintData (unsigned char* data , int size)
{

    for(i=0 ; i < size ; i++)
    {
        if( i!=0 && i%16==0)   //if one line of hex printing is complete...
        {
            printf("         ");
            for(j=i-16 ; j<i ; j++)
            {
                if(data[j]>=32 && data[j]<=128)
                    printf("%c",(unsigned char)data[j]); //if its a number or alphabet

                else printf("."); //otherwise print a dot
            }
            printf("\n");
        } 

        if(i%16==0) printf("   ");
            printf(" %02X",(unsigned int)data[i]);

        if( i==size-1)  //print the last spaces
        {
            for(j=0;j<15-i%16;j++) printf("   "); //extra spaces

            printf("   ");

            for(j=i-i%16 ; j<=i ; j++)
            {
                if(data[j]>=32 && data[j]<=128) printf("%c",(unsigned char)data[j]);
                else printf(".");
            }
            printf("\n");
        }
    }
}

The output I am receiving is as follows:

Source Port : 55784 , Destination Port : 59568, UDP Length : 5122,Protocol : 188, total length : 5122 
Source IP        : 147.188.195.6
Destination IP   : 0.0.0.0
Data Payload
    93 BC C0 06 00 00 00 00 00 1F 39 D4 D9 E8 E8 B0         ..........9.....
    00 00 00 03 00 00 00 01 00 00 00 9C 00 B1 C9 4E         ...............N
    00 00 00 1D 00 00 01 00 78 F9 F5 6B 00 10 67 8F         ........x..k..g.
    00 00 00 1D 00 00 00 28 00 00 00 02 00 00 00 01         .......(........
    00 00 00 5C 00 00 00 01 00 00 00 4E 00 00 00 04         ...\.......N....
    00 00 00 4C F0 92 1C 48 C2 00 00 0E 0C 30 C7 C7         ...L...H.....0..
    08 00 45 00 00 3C 28 4D 40 00 25 06 1C 7E 4C 5C         ..E..<(M@.%..~L\
    70 AE 93 BC C0 2A B4 FE 00 50 59 41 29 30 00 00         p....*...PYA)0..
    00 00 A0 02 FF FF FD BF 00 00 02 04 05 B4 04 02         ................
    08 0A 00 13 01 7D 00 00 00 00 01 03 03 06 00 00         .....}..........
    00 00 03 E9 00 00 00 10 00 00 00 03 00 00 00 02         ................
    00 00 00 02 FF FF FF FF 00 00 00 01 00 00 00 A8         ................
    00 B1 C9 4F 00 00 00 1D 00 00 01 00 78 F9 F6 82         ...O........x...
    00 10 67 8F 00 00 00 1D 00 00 00 00 00 00 00 02         ..g.............
    00 00 00 01 00 00 00 68 00 00 00 01 00 00 00 59         .......h.......Y
    00 00 00 04 00 00 00 58 F0 92 1C 48 C2 00 00 0E         .......X...H....
    0C 30 C7 C7 08 00 45 00 00 47 D8 94 00 00 2F 11         .0....E..G..../.
    2F 0A 46 27 EA 1F 93 BC C0 04 17 72 00 35 00 33         /.F'.......r.5.3
    BF 19 43 B9 00 10 00 01 00 00 00 00 00 01 03 6E         ..C............n
    73 32 04 73 75 73 78 02 61 63 02 75 6B 00 00 01         s2.susx.ac.uk...
    00 01 00 00 29 10 00 00 00 80 00 00 00 00 00 00         ....)....�......
    00 00 03 E9 00 00 00 10 00 00 00 03 00 00 00 02         ................
    00 00 00 02 FF FF FF FF 00 00 00 01 00 00 00 9C         ................
    00 B1 C9 50 00 00 00 1D 00 00 01 00 78 F9 F6 F0         ...P........x...
    00 10 67 8F 00 00 00 00 00 00 00 1D 00 00 00 02         ..g.............
    00 00 00 01 00 00 00 5C 00 00 00 01 00 00 00 50         .......\.......P
    00 00 00 04 00 00 00 4C 00 0E 0C 30 C7 C7 F0 92         .......L...0....
    1C 48 C2 00 08 00 45 00 00 3E BC F6 00 00 3F 11         .H....E..>....?.
    38 9F 93 BC C0 04 C2 53 70 05 00 35 BE FE 00 2A         8......Sp..5...*
    28 53 82 D8 81 05 00 01 00 00 00 00 00 00 03 77         (S.............w
    77 77 06 67 6F 6F 67 6C 65 02 63 6F 02 75 6B 00         ww.google.co.uk.
    00 01 00 01 00 00 03 E9 00 00 00 10 FF FF FF FF         ................
    00 00 00 00 00 00 00 03 FF FF FF FF               ............

I am confused how to make this data into a readable form to know the content of the payload?

解决方案

First off, the port numbers, protocol, and data length you're printing out aren't correct. As I mentioned in my answer to your previous question, the IP and UDP headers are not included in the buffer that was populated by recvfrom. The source and destination ports are in saddr.sin_port and daddr.sin_port respectively (make sure to call ntohs on those field before printing), and the UDP payload length is the return value of recvfrom, i.e. data_size.

As for the the format of the data payload, you need to know exactly what the data you've received is formatted. Based on that, you can pull out the relevant fields and print them in a readable format. For starters, you can call PrintData instead of ProcessPacket from main since you don't need to worry about the IP and UDP headers.

这篇关于如何使用 C 程序读取来自端口的 UDP 数据负载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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