6

I have an error from the following scenario with IGMP socket call;

fd = socket(PF_INET,  SOCK_RAW, IPPROTO_IGMP) ;
setsockopt( fd, IPPROTO_IP, IP_HDRINCL, nval, sizeof(nval) );
/** Fill in the IP header and Ethernet header**/
/*** Fill, create the IGMP packet structures***/
if(sendto( fd, &buf, sizeof(buf), 0,(struct sockaddr *) &addr, sizeof(addr)) < 0) {
    printf("Socket Sendto error %d : %s\n", errno, strerror(errno));
    return 0;
}

the sendto call fails saying Message too long. I am using 8192 as the buffer size. So I tried using the following call to fix this error;

if(setsockopt(dlpifd, IPPROTO_IP, SO_SNDBUF, &val, sizeof(int)) < 0) {
   printf("Can't set socket options:%d:%s\n", errno, strerror(errno));
   return 0;`
}

setsockopt( ) call succeeds but the same error for sendto();

So i checked the SO_SNDBUF size with getsockopt( ) call and it shows 1 byte ?!

What is wrong I am doing.

Does the Linux kernel need recompile for IGMP support ? or I am missing something?

Uli Köhler
  • 13,012
  • 16
  • 70
  • 120
Sathya
  • 81
  • 1
  • 1
  • 3

1 Answers1

7

Ethernet (the link layer you are most probably working against) frame is usually 1500 bytes long. Give the send() the exact size of the message, not the buffer size.

SO_SNDBUF is the in-kernel per-socket buffer, which tells how much to buffer for TCP, limits the size of datagram for UDP, and does not make any sense for raw sockets.

Nikolai Fetissov
  • 82,306
  • 11
  • 110
  • 171
  • Thanks Nik ! for the help. Does that mean for this scenario I should use send( ) and not sendto( ) and the exact message size (even if it is more than 1500 default size?!) and not the buff size. – Sathya Jan 25 '11 at 16:17
  • HI, I am attempting to send an IGMP packet 'pigmp->igmp_type = IGMP_MEMBERSHIP_QUERY;' and not a TCP or an UDP, I suspect the sequence of calls/things I am doing in the code may be wrong or the arguments/values which I am using for filling the structures should be wrong. I checked and could not find a fault in those aspects. So using send( ) instead of sendto( ) is not hleping to fix this. Anyone worked on IGMP (Multicasting) can throw me some light. -Thanks in advance -Sathya – Sathya Jan 27 '11 at 10:11
  • Hi Nik, As said, Now it works fine for packet sizes <= 1500. It throws erro:90 for anything more(even for 1501). I tried using setsockopt() to increase the SO_SNDBUF but no effect from that call. Since send( ) call cannot be used for raw socket bcos it is connectionless and the same reason for IGMP packet I am still using sendto( ). I want to know what holds good for setsockopt( ) to SO_SNDBUF change. - Thanks - Sathya – Sathya Jan 28 '11 at 14:29
  • `sendto()` is fine - I used `send()` as a general name anyway. You won't get anything larger then 1500 bytes through ethernet - that's the hardware limit. `SO_SNDBUF` has no effect here - raw sockets don't do buffering. – Nikolai Fetissov Jan 28 '11 at 15:11