0

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?

dbush
  • 205,898
  • 23
  • 218
  • 273
Kishore
  • 21
  • 2
  • 7

1 Answers1

2

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.

Community
  • 1
  • 1
dbush
  • 205,898
  • 23
  • 218
  • 273
  • Thank you for your comments. I used the mentioned suggestion and the output is as follows : Source Port : 61842 , Destination Port : 6343, UDP Length: 61444. Is this correct ? A doubt which arises here is that the destination port is 6343 ( port from where I am trying to capture the data) should be the source port since that's the port from where I am collecting data ?? not sure if my understanding is right ? – Kishore Jul 29 '15 at 09:32
  • The source and destination ports are correct. Your socket is bound to port 6343, so all packets received on that socket should have 6343 as the destination port. – dbush Jul 29 '15 at 10:41
  • Thank you for your comments. How about the protocol ? I am calling iph->protocol before printing. is that the right way to do ? – Kishore Jul 29 '15 at 10:57
  • The IP header is not included in your data buffer, so you shouldn't be trying to read it. Because the socket you're receiving on is of type AF_INET / SOCK_DGRAM, the protocol in the IP header will always be 17 (UDP). – dbush Jul 29 '15 at 12:07
  • Ok..makes sense for me now. But I am asking this question out of curiosity Is there any possible way to display the protocol field by changing socket type ?? – Kishore Jul 29 '15 at 12:28
  • I think I ignored my primary question here.. as you mentioned for data payload that I should be knowing the data format of what I am receiving. I am receiving UDP packets, what would the payload essentially contain?? I mean will it give the same information what header is sending ?? – Kishore Jul 29 '15 at 12:31
  • The raw packet on the network contains: Ethernet header (assuming you're using Ethernet), IP header, UDP header, application data. When using `recvfrom` on a socket created with `AF_INET` and `SOC_DGRAM`, the only part that gets stored in your buffer is the application data part. – dbush Jul 29 '15 at 12:38
  • Because of the type of socket you are using, the protocol field in the IP header is effectively a constant, i.e. 17 for UDP, so you can just print that if you want. If you really need to see the entire IP datagram, you need to use a low level capture library such as libpcap. – dbush Jul 29 '15 at 12:40
  • Thank you for your comments. The data payload which I have mentioned in my question as my output, I am confused in finding out how to convert the hex format into a readable form. I am not really sure what contents does it contain which I could print out as my output. – Kishore Jul 29 '15 at 14:39