Kishore
Kishore

Reputation: 21

How to read the UDP data payload coming from a port using C program

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?

Upvotes: 0

Views: 7629

Answers (1)

dbush
dbush

Reputation: 225697

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.

Upvotes: 2

Related Questions