Reputation: 20571
I have a raw socket set up bound to a device that is already in promiscuous mode:
int sock = socket (PF_INET, SOCK_RAW, IPPROTO_TCP);
if(sock == -1)
{
return -1;
}
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_ifrn.ifrn_name, "eth0", IFNAMSIZ);
if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) < 0)
{
close(sock);
return -2;
}
while(1) {
packet_size = recvfrom(sock , buffer , 65536 , 0 , NULL, NULL);
// packet processing...
}
And my issue is that I am only receiving packets on my socket with IP destination matching the IP of the device (eth0) I am bound to. How can I receive all the TCP packets that the device is receiving? I can see all the TCP packets on the device in Wireshark, but the only packets that I see in my raw socket are those addressed to the device IP.
Upvotes: 2
Views: 1362
Reputation: 5055
The reason of receiving packets directed only to IP of your device is that you are using PF_INET
raw socket. When PF_INET
raw socket is used - skb
faces different sanity checks when goes across the stack (see below).
F.e. :
int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
{
/*...*/
/* When the interface is in promisc. mode, drop all the crap
* that it receives, do not try to analyse it.
*/
if (skb->pkt_type == PACKET_OTHERHOST)
goto drop;
So the call trace is something like: __netif_receive_skb_core()
->ip_rcv()
->...->ip_local_deliver()
->...->raw_local_deliver()
->raw_rcv()
->...->tcp_rcv()
(you can check trace through the trace-cmd
).
But tcpdump/Wireshark obtains packets around __netif_receive_skb_core()
, i.e. before some sanity checks. Hence is discrepancy that confused you.
Therefore if you want skb
's to bypass a large part of Linux kernel network stack - you should use PF_PACKET
raw sockets.
Upvotes: 3