Question

How to get the length of received UDP packet? Using wireshark I could see the correct length of datagram. How can I print this value in my simple udp server program? I am receiving binary data (Non printable ascii characters as a data) So I can not use strlen(buf) which throws incorrect length.

      if (ret=recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *)&si_other, &slen)==-1){
            error = ioctl(s, FIONREAD, &value);
            printf(" from ioctl UDP packet length is : %d error is : %d\n", value, error);
      }

udp packet length is always '0' from the above code. Any comments?

I also tried like below

         if (ret=recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *)&si_other, &slen)!=-1){
            unsigned short iphdrlen;
            struct iphdr* iph = (struct iphdr*)buf;
            iphdrlen =iph->ihl*4;

            printf("IP version :%d\n", ((unsigned int)((iph->version))));
            printf("protocol .. %d\n", ((unsigned int)(iph->protocol)));
            printf("total len .. %d\n", (ntohs(iph->tot_len)));
         }

The above code always returns me wrong values from ip header? Any comments?

The original C file is included here.

#include "udp_common.h"

int main(void)
{
        struct sockaddr_in si_me, si_other;
        int s, i, slen=sizeof(si_other);
        unsigned char buf[BUFLEN];
        int noofbytes=0;
        int ret=0,error,value;

        memset(buf, 0, 512);
        if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
                diep("socket");

        memset((char *) &si_me, 0, sizeof(si_me));
        si_me.sin_family = AF_INET;
        si_me.sin_port = htons(PORT);
        si_me.sin_addr.s_addr = htonl(INADDR_ANY);
        if (bind(s, (struct sockaddr *)&si_me, sizeof(si_me))==-1)
                diep("bind");

        for (i=0; ; i++)
        //for (i=0; i<NPACK ; i++) 
        {
                if (ret=recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *)&si_other, &slen)==-1)
                diep("recvfrom()");
                printf(" source port is : %d %d\n", ntohs(si_other.sin_port), slen);

                unsigned short iphdrlen;
                struct iphdr* iph = (struct iphdr*)buf;
                iphdrlen =iph->ihl*4;

                printf("IP version :%d\n", ((unsigned int)((iph->version))));
                printf("protocol .. %d\n", ((unsigned int)(iph->protocol)));
                printf("total len .. %d\n", (ntohs(iph->tot_len)));
                error = ioctl(s, FIONREAD, &value);
                printf(" from ioctl UDP packet length is : %d error is : %d\n", value, error);
                printf(" Return code from recvfrom is : %d\n", ret);
                printf("Received packet from %s:%d\nData: %s\n\n",
                inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port), buf);

                int j=0;
                for ( j = 0; j <20; j++)
                {
                        char x = buf[j];
                        short int i;
                        for (i=1;i<9;i++)
                        {
                                ((x | (1<<8-i)) == x)?printf("1"):printf("0");
                        }
                        printf(" ");
                }
                printf("\n");
        }


        close(s);
        return 0;
}

And the output I am receivingis as follows:

 source port is : 4232 16
IP version :1
protocol .. 65
total len .. 4096
 from ioctl UDP packet length is : 0 error is : 0
 Return code from recvfrom is : 0
Received packet from 127.0.0.1:4232
Data: 

00010000 00000001 00010000 00000000 11110001 00010001 00010001 00100100 01000100 01000001 00010001 00100100 01000100 01000000 00000000 00010000 00000000 00010000 10100000 10100000 

The above decrypted data matched with my sent data.

Was it helpful?

Solution

How did you create your socket ? Is it a raw socket (SOCK_RAW) or a dgram socket (SOCK_DGRAM) ? In the second case, you won't get ip/udp headers, only payload.

By the way, the packet length is the returned value of the function recvfrom - in your case, the "ret" variable. Check recvfrom man page.

OTHER TIPS

Short answer (although it is already in the comments above): recvfrom returns the number of bytes received.

problem is here:

if (ret=recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *)&si_other, &slen)==-1)

rewrite it as:

ret=recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *)&si_other, &slen)
if (ret==-1)
{
}

ret will contain the number of bytes

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top