Я пытаюсь захватить только пакеты из определенного интерфейса, и вместо этого я получаю пакеты со всех интерфейсов. Что я делаю не так?Sniffing интерфейс ethernet на linux
bool Snooper::raw_init (const char *device)
{
uid_t privid = geteuid();
int retval;
bool retVal = false;
do {
if ((retval = setuid(0)) != 0) {
perror("seteuid error");
break;
}
cap_t caps = cap_get_proc();
cap_value_t cap_list[2];
cap_list[0] = CAP_NET_RAW;
cap_list[1] = CAP_SETUID;
if ((retval = cap_set_flag(caps, CAP_EFFECTIVE, 2, cap_list, CAP_SET)) == -1) {
perror("cap_set_flag error");
break;
}
if ((retval = cap_set_proc(caps)) == -1) {
perror("cap_set_proc error");
break;
}
struct ifreq ifr;
memset(&ifr, 0, sizeof (struct ifreq));
/* Open A Raw Socket */
if ((m_sockfd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL))) < 1) {
perror("Snooper::raw_init:socket Error");
break;
}
/* Set the device to use */
strncpy(ifr.ifr_name, device, strlen(device) + 1);
/* Get the current flags that the device might have */
if (ioctl(m_sockfd, SIOCGIFFLAGS, &ifr) == -1) {
perror("Error: Could not retrieve the flags from the device.\n");
break;
}
printf("The interface is ::: %s\n", device);
perror("Retrieved flags from interface successfully");
/* Set the old flags plus the IFF_PROMISC flag */
ifr.ifr_flags |= IFF_PROMISC;
if (ioctl(m_sockfd, SIOCSIFFLAGS, &ifr) == -1) {
perror("Error: Could not set flag IFF_PROMISC");
break;
}
printf("Setting interface ::: %s ::: to promisc\n", device);
/* Configure the device */
if (ioctl(m_sockfd, SIOCGIFINDEX, &ifr) < 0) {
perror("Error: Error getting the device index.\n");
break;
}
retVal = true;
} while(false);
if ((retval = seteuid(privid)) != 0) {
perror("seteuid error");
}
return retVal;
}
Прежде всего, подтвердите, что я могу доверять root, так как это требует IFF_PROMISC. Затем создайте сокет для трафика UDP, заготовьте IOCtl для устройства и, наконец, IOCtl для PROMISC.
Теперь, когда у меня есть готовый сокет, я петлю на recv, однако я также получаю пакеты от других интерфейсов.
Благодаря @Vlad Лазаренко сейчас работает. Я думал, что это будет привязка, однако ни один из других примеров, найденных в других местах, никогда не использовался bind, и поэтому он был опущен. Как кто-либо еще хочет выполнять однотипную задачу. После компиляции. chown root exe, затем chmod a + s exe. Хотя вы должны иметь права root для выполнения любого действия. –