I am trying use a port from two applications and have each of them receive the packet from a different set of IP addresses. In order to achieve this, I use the SO_REUSEPORT and SO_ATTACH_REUSEPORT_CBPF socket options. My code is as follows:
parentfd = socket(AF_INET, SOCK_STREAM, 0);
if (parentfd < 0)
error( "ERROR opening socket");
struct sock_filter code[]={
{ 0x28, 0, 0, 0x0000000c },
{ 0x15, 0, 3, 0x00000800 },
{ 0x20, 0, 0, 0x0000001a },
{ 0x15, 2, 0, 0xc0a8ff01 },
{ 0x6, 0, 0, 0x00000000 },
{ 0x6, 0, 0, 0x00040000 },
{ 0x6, 0, 0, 0x00000001 },
};
struct sock_fprog bpf = {
.len = ARRAY_SIZE(code),
.filter = code,
};
if (setsockopt(parentfd, SOL_SOCKET, SO_REUSEPORT, (const void *)&optval,sizeof(optval)))
error("ERROR setting SO_REUSEPORT");
if (setsockopt(parentfd, SOL_SOCKET, SO_ATTACH_REUSEPORT_CBPF, (const void *)&bpf, sizeof(bpf)))
error("ERROR setting SO_ATTACH_REUSEPORT_CBPF);
I also have a different process that listens to the same port using only the SO_REUSEPORT flag. From a machine with IP 192.168.255.1
I am running echo 1234 | ncat 192.168.255.150 1234
. Based on my filter I would expect all traffic from that IP address to be received by the second process. However, it is all received by the first. When I change the filter to a simple:
struct sock_filter code[]={
{ 0x6, 0, 0, 0x00000001 },
};
It works as expected and all packets are received by the second process. Any idea why this might be happening?
I found out what the problem was. The filter is applied to all packets, even the TCP handshake packets. Also, the base pointer points to the first byte of the packet payload, not headers. Hence, when it executes
ldh[12]
it gets out of the limits of the packet (SYN packet has 0 bytes of payload) and the default behavior is to return 0.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With