Создание сокета происходит вот так:
argv[1]=IP;
argv[2]=Interface name;
unsigned char dst_mac[6] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
int sock=socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
struct ifreq ifr;
strncpy((char*)ifr.ifr_name, argv[2], IFNAMSIZ);
if (ioctl(sock, SIOGIFINDEX, &ifr) < 0) {
perror("getting device index number");
return 1;
}
printf("Interface index=%d\n",ifr.ifr_ifindex);
if(ioctl(sock, SIOCGIFHWADDR, &ifr)<0){
perror("getting device addr");
return 1;
}
memcpy(scr_mac,ifr.ifr_hwaddr.sa_data,ETH_ALEN);
printf("MAC=%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",scr_mac[0],scr_mac[1],scr_mac[2],scr_mac[3],scr_mac[4],scr_mac[5]);
struct sockaddr_in sa_in;
if(ioctl(sock, SIOCGIFADDR, &ifr) < 0) {
perror("ioctl SIOCGIFADDR");
return -1;
}
memset((void *)&sa_in, 0, sizeof(struct sockaddr_in));
memcpy((void *)&sa_in, (void *)&ifr.ifr_addr, sizeof(struct sockaddr));
//memcpy((void *)&ifp->ip, (void *)&s.sin_addr.s_addr, sizeof(__u32));
printf("Interface addr=%x\n",ntohl(sa_in.sin_addr.s_addr));
struct sockaddr_ll sall;
memset(&sall,0,sizeof(sall));
sall.sll_family=AF_PACKET;
sall.sll_ifindex=ifr.ifr_ifindex;
sall.sll_protocol=htons(ETH_P_ALL);
sall.sll_halen = ETH_ALEN;
memcpy(sall.sll_addr, scr_mac, ETH_ALEN);
if(bind(sock,(struct sockaddr *)&sall,sizeof(sall))<0) {
perror("bind");
exit(1);
}
На одной машине установлена fedora 10 rus, ядро 2.6.27.41, интерфейсы eth0,lo - всё работает правильно.
На другой машине установлена openSuse 11.1, ядра есть разные 2.6.27.7, 2.6.27.41, 2.6.31.3, интерфейсы eth0, eth1, eth2, lo.
eth1,eth2 вроде работают правильно, а вот при посылке пакета на интерфейс eth0 пакеты не отправляются, хотя sendto возвращает правильное число отправленных байт (1052 bytes).
Wireshark видит эти призрачные пакеты только в Any-интерфейсе, соответственно с приписанными заголовками «Linux cooked capture».
На неверно работающей машине iptables -L:
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
ЗЫ:Простите за «многа букаф»)