Size of Buffer in recvfrom in Solaris vs Linux

I have a C program that reads custom icmp packets off a socket. The program has been used for years on Solaris, but I am now having to port it to Linux.

Got it all compliled on Linux and when I ran it and sent in a test icmp packet, the size of the packet appears to be quite larger on Linux than it was on Solaris.

On both Linux and Solaris, when I print out "rc", I get about the same size of bytes read, which is 276.

1
2
3
4
5
6
7
8
9
10
11
char recv_buffer[8184];

if ((rc = recvfrom(sd, recv_buffer, 8184, iFlag, &sFrom, &iFromLen)) == -1)
{
do something
}
else 
{
ip_recv_ptr = (struct ip *) recv_buffer;
printf("Length of data received %d\n", ip_recv_ptr->ip_len);
}


I cast recv_buffer to a pointer of type struct ip and then print out the size of the data received.

On Solaris, ip_recv_ptr->ip_len prints out 248

On Linux, ip_recv_ptr->ip_len prints out 5113

Now this is a really big difference. I am reading the same packet of size 270`ish off the socket on both Solaris and Linux, but the amount of data in recv_buffer is 248 on Solaris and 5113 on Linux.

So, I am really lost as to what is happening. The source code is that same and the test packet is the same. Any ideas? on what's going on here?

Thanks



Perhaps Linux does not append a '\0' to the data, so it just keeps going until it finds a '\0'.

You could try intializing your buffer to all nulls.
Hmm...
248 = 0xF8
5113 = 0x13F9
Possibly an endianness issue coupled with integers of different sizes?
I just added this, but the results were the same.

 
memset(recv_buffer,'\0', 8184);
Can you explain about the "integers of different sizes" a bit more or what I should be looking at?
Check that sizeof(ip_recv_ptr->ip_len) is the same on both implementations (Linux and Solaris).
I could do a quick check if you post the definition of struct ip and the raw data you're sending.
I did a sizeof of both SOlaris and Linux....

 
printf("Sizeof: %d\n", sizeof(ip_recv_ptr->ip_len))


And got the same results on both...

Sizeof: 2
Last edited on
Here is the definition of struct ip on Linux....

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
struct ip
  {
#if __BYTE_ORDER == __LITTLE_ENDIAN
    unsigned int ip_hl:4;               /* header length */
    unsigned int ip_v:4;                /* version */
#endif
#if __BYTE_ORDER == __BIG_ENDIAN
    unsigned int ip_v:4;                /* version */
    unsigned int ip_hl:4;               /* header length */
#endif
    u_int8_t ip_tos;                    /* type of service */
    u_short ip_len;                     /* total length */
    u_short ip_id;                      /* identification */
    u_short ip_off;                     /* fragment offset field */
#define IP_RF 0x8000                    /* reserved fragment flag */
#define IP_DF 0x4000                    /* dont fragment flag */
#define IP_MF 0x2000                    /* more fragments flag */
#define IP_OFFMASK 0x1fff               /* mask for fragmenting bits */
    u_int8_t ip_ttl;                    /* time to live */
    u_int8_t ip_p;                      /* protocol */
    u_short ip_sum;                     /* checksum */
    struct in_addr ip_src, ip_dst;      /* source and dest address */
  }; 




Here is the definition of struct ip on Solaris....

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
struct ip {
#ifdef _BIT_FIELDS_LTOH
        uchar_t ip_hl:4,                /* header length */
                ip_v:4;                 /* version */
#else
        uchar_t ip_v:4,                 /* version */
                ip_hl:4;                /* header length */
#endif
        uchar_t ip_tos;                 /* type of service */
        short   ip_len;                 /* total length */
        ushort_t ip_id;                 /* identification */
        short   ip_off;                 /* fragment offset field */
#define IP_DF 0x4000                    /* dont fragment flag */
#define IP_MF 0x2000                    /* more fragments flag */
        uchar_t ip_ttl;                 /* time to live */
        uchar_t ip_p;                   /* protocol */
        ushort_t ip_sum;                /* checksum */
        struct  in_addr ip_src, ip_dst; /* source and dest address */
}; 
Last edited on
Sorry. I got nothing, then.
No problem. I will keep looking. Maybe focus on the calls to socket(), socketopt(), and recvfrom(). Maybe there is something different on Linux with these calls.
Last edited on
I think the recvfrom() implementation is different in Linux. The following link might be helpful:

http://developers.sun.com/solaris/articles/solaris_linux_app.html
I checked out the link, but I don't see much of any difference in recvfrom() on Linux.
Topic archived. No new replies allowed.