gpt4 book ai didi

c - 如何使用 C 程序读取来自端口的 UDP 数据负载

转载 作者:太空宇宙 更新时间:2023-11-04 07:07:13 25 4
gpt4 key购买 nike

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

#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");
}
}
}

我收到的输出如下:

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 ............

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

最佳答案

首先,您打印的端口号、协议(protocol)和数据长度不正确。正如我在 my answer to your previous question 中提到的,IP 和 UDP header 不包含在由 recvfrom 填充的缓冲区中。源端口和目标端口分别在 saddr.sin_portdaddr.sin_port 中(确保在打印前在这些字段上调用 ​​ntohs),以及UDP payload长度为recvfrom的返回值,即data_size

至于数据有效载荷的格式,您需要确切地知道您收到的数据的格式。基于此,您可以提取相关字段并以可读格式打印它们。对于初学者,您可以从 main 调用 PrintData 而不是 ProcessPacket,因为您不需要担心 IP 和 UDP header 。

关于c - 如何使用 C 程序读取来自端口的 UDP 数据负载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31686628/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com