11

I'm making a program which create a RAW socket in order to read all traffic. Between the call of socket() and recvfrom() (last one is in a loop to get out all packets from buffer) I wait 5s.

When I run the program, I send about 200 packets with hping3 command in « faster mode » (to fill in the buffer fastly) to my program. As soon as 5s are elapsed, my program extract about 150 packets from the buffer.

I try to change the size of the receive buffer to get better result:

int a = 65535;
if ( (setsockopt(sockfd, 0, SO_RCVBUF, &a ,sizeof(int)) ) < 0 )
{
    fprintf(stderr, "Error setting sock opts..\n");
}

However, whatever is the value of « a », 1 or 10000000, it seems nothing changes, I still get ~150 packets from the buffer.

What's the problem?

Edit: Value of « a » is verified with a getsockopt call.

Flow
  • 187
  • 1
  • 2
  • 8
  • Can you show us more code, including relevant calls to `socket()` etc.? Letting us know your operating system might help too. – Daniel Roethlisberger Apr 08 '12 at 14:28
  • Sure, I run this program under Linux 3.2 64bits. The call to `socket()` : `sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)` – Flow Apr 08 '12 at 14:37

2 Answers2

18

You may also be limited by the OS, if it still doesn't seem to be working. Check the values in:

/proc/sys/net/core/rmem_default
/proc/sys/net/core/rmem_max

If it's TCP as you say in your example, and not actually a raw socket, you can also check the values in:

/proc/sys/net/ipv4/tcp_mem

If you run cat on these files they'll show you the current settings. To change them permanently, use sysctl. It's a good idea to write these settings down before you start changing things. Here's a great tutorial on making those changes: http://fasterdata.es.net/fasterdata/host-tuning/linux/.

rutgersmike
  • 1,183
  • 9
  • 18
  • Thank you too, I've increased the rmem_max value and it works very well I can get all packets. – Flow Apr 08 '12 at 15:08
  • You have any idea about windows, where we can check this values? – sreepurna Mar 14 '17 at 09:48
  • 1
    As a a privileged process (CAP_NET_ADMIN) you can use `SO_RCVBUFFORCE` instead of `SO_RCVBUF` to ignore the `rmem_max` limit. – scai Oct 04 '19 at 12:13
12

The level argument to setsockopt should be SOL_SOCKET, not 0:

int a = 65535;
if (setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &a, sizeof(int)) == -1) {
    fprintf(stderr, "Error setting socket opts: %s\n", strerror(errno));
}
Daniel Roethlisberger
  • 6,958
  • 2
  • 41
  • 59
  • Thank you, it works well the value changes now. However the limit of receive buffer is 262142 and if a packet is 50 bytes sized then there should be about 5200 packets in memory and not only 150? – Flow Apr 08 '12 at 15:00
  • 1
    Note that the buffer size has an upper limit defined by `/proc/sys/net/core/rmem_max`. For an even larger buffer you either need to change this global limit or as a a privileged process (CAP_NET_ADMIN) you can use `SO_RCVBUFFORCE` instead of `SO_RCVBUF` to ignore the `rmem_max` limit. – scai Oct 04 '19 at 12:18