Итак, как вы это делаете правильно?Как правильно поместить сетевой интерфейс в беспорядочный режим на Linux
Я знаю, как это сделать, создав сокет, а затем установив флаг IFF_PROMISC с помощью ioctl (как описано в «howto check a network devices status in C?» и в другом месте), но это выглядит ошибочным, по крайней мере, теоретически.
1) вы читаете флаги через IOCTL 2) обновить флаги 3) кто-то еще измененные флаги 4) вы установили обновленные флаги через IOCTL
Есть ли лучший способ или я просто слишком беспокоиться?
Позже я обнаружил, что один должен добавить интерфейс PACKET_MR_PROMISC через setsockopt (который также не имеет расы), как это:
void set_promisc(const char *ifname, bool enable)
{
struct packet_mreq mreq = {0};
int sfd;
int action;
if ((sfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1) {
perror("unable to open socket");
return;
}
mreq.mr_ifindex = if_nametoindex(ifname);
mreq.mr_type = PACKET_MR_PROMISC;
if (mreq.mr_ifindex == 0) {
perror("unable to get interface index");
return;
}
if (enable)
action = PACKET_ADD_MEMBERSHIP;
else
action = PACKET_DROP_MEMBERSHIP;
if (setsockopt(sfd, SOL_PACKET, action, &mreq, sizeof(mreq)) != 0) {
perror("unable to enter promiscouous mode");
return;
}
close(sfd);
}
К сожалению, это не имеет никакого эффекта на интерфейсе, хотя он должен, если я нестандартно the doc правильно. Возможно broken since 2001 (tm)? Комментарии в источнике pcap также жалуются на это.
И ** ** почему вы думаете, 'ioctl' не так? И что было бы «более простым способом»? – Olaf
Операция чтения/изменения/записи должна быть атомарной. – dbrank0