I'm struggling to bind raw socket to interface, my goal to implement simple packet sniffer. Already dedicated hours searching the web and went through references, part of them listed at bottom.
I'm able to open socket, no error on bind, but when stripping Ethernet header and observing IP header I see that catched loopback (127.0.0.1) and other, undesired, ethX ifaces traffic.
One of conclusions is setsockopt can NOT be used in my case, here is my code snippets :
struct sockaddr_ll sll;
int raw_sock;
raw_sock = socket( PF_PACKET , SOCK_RAW , htons(ETH_P_ALL)) ;
// also tried with AF_PACKET
bzero(&sll , sizeof(sll));
sll.sll_family = PF_PACKET;
// also tried with AF_PACKET
sll.sll_ifindex =get_iface_index(raw_sock,"eth1");
// returns valid ifr.ifr_ifindex;
sll.sll_protocol = htons(ETH_P_ALL);
if((bind(raw_sock , (struct sockaddr *)&sll , sizeof(sll))) ==-1)
{
perror("bind: ");
exit(-1);
}
saddr_size = (sizeof sll);
data_size = recvfrom(raw_sock , buffer_ptr, 65536, 0 , &sll , (socklen_t*)&saddr_size);
Thanks in advance !
References :
- http://man7.org/linux/man-pages/man7/packet.7.html
- http://man7.org/linux/man-pages/man2/bind.2.html
- Raw socket with device bind using setsockopt() system is not working in Fedora core 6(2.6.18-1.2798.fc6)
- how to bind raw socket to specific interface
Edit-1 : Thanks a lot for dedicating your time for reply, I'm quite lost and frustrated from endless search for solution.
- I'm restricted to my own implementation, thus unable to use libcap nor others.
Interface index returned from ioctl call SIOCGIFINDEX is 3 in my case and is identical to sll.sll_ifindex value. Assuming I can rely on "ip link show" - my eth1 index is indeed 3.
int get_iface_index(int socket,char *iface_name){ struct ifreq ifr; char ifname[IFNAMSIZ]="eth1"; // Ugly hard coded, will be changed memset(&ifr, 0, sizeof(struct ifreq)); strncpy((char *)ifr.ifr_name, ifname, IFNAMSIZ); if (ioctl(socket, SIOCGIFINDEX, &ifr) < 0){ perror("ioctl: "); return -1; } return ifr.ifr_ifindex; // Always success here 2 for eth0, 3 for eth1 }