Comment lire la charge utile de données UDP provenant d’un port utilisant le programme C

J’essaie de capturer les paquets de données UDP du port 6343. Lors de la capture, je dois également capturer la charge utile. Je reçois la charge utile au format ASCII. Je dois lire le contenu de la charge utile. Voici mon code:

#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 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 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=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=ii%16 ; j=32 && data[j]<=128) printf("%c",(unsigned char)data[j]); else printf("."); } printf("\n"); } } } 

Le résultat que je reçois est le suivant:

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

Je suis confus comment faire de ces données une forme lisible pour connaître le contenu de la charge utile?

Tout d’abord, les numéros de port, le protocole et la longueur des données que vous imprimez ne sont pas corrects. Comme je l’ai mentionné dans ma réponse à votre question précédente , les en-têtes IP et UDP ne sont pas inclus dans la mémoire tampon qui a été remplie par recvfrom . Les ports source et destination sont respectivement dans saddr.sin_port et daddr.sin_port (assurez-vous d’appeler ntohs sur ce champ avant l’impression), et la longueur de la charge utile UDP est la valeur de retour de recvfrom , c’est-à-dire data_size .

En ce qui concerne le format de la charge de données, vous devez savoir exactement en quoi les données que vous avez reçues sont formatées. Sur cette base, vous pouvez extraire les champs pertinents et les imprimer dans un format lisible. Pour commencer, vous pouvez appeler PrintData au lieu de ProcessPacket depuis main car vous n’avez pas à vous soucier des en-têtes IP et UDP.