问题描述
那您如何正确地做到这一点?
So how do you do this properly?
我知道如何创建套接字,然后使用ioctl设置IFF_PROMISC标志(如""和其他地方),但这至少在理论上看来是有缺陷的.
I know how to do it by creating socket, then setting IFF_PROMISC flag using ioctl (as explained in "howto check a network devices status in C?" and elsewhere), but this looks flawed at least in theory.
- 您通过ioctl读取标志
- 您更新标志
- 其他人修改了标志
- 您通过ioctl设置了更新的标志
有更好的方法吗?还是我太担心了?
Is there a better way or do I simply worry too much?
后来我发现应该像这样通过setsockopt(也没有种族)将接口添加到PACKET_MR_PROMISC:
Later I found that one should add interface to PACKET_MR_PROMISC via setsockopt (which also does not have a race) like this:
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);
}
不幸的是,如果我不理解文档正确.可能自2001年(tm)以来已损坏?pcap来源中的评论也对此有所抱怨.
Unfortunately this has no effect whatsoever on interface, although it should, if I unserstand the doc correctly. Possibly broken since 2001 (tm)?Comments in pcap source also complain about this.
推荐答案
PACKET_MR_PROMISC
打开设备的混杂模式.这不会反映在ifconfig
所示的状态中,因为它不会修改设备上全局IFF_PROMISC
标志的状态.这并不意味着它还没有完成. pcap库现在是这样工作的,wireshark(和其他十二个实用程序)可以打开设备并查看未发送到本地系统的数据包表明它可以工作.
PACKET_MR_PROMISC
turns on promiscuous mode for the device. That will not be reflected in the status shown by ifconfig
as it does not modify the state of the global IFF_PROMISC
flag on the device. That does not mean it hasn't been done though. This is how the pcap library works now and the fact that wireshark (and a dozen other utilities) can open a device and see packets not addressed to the local system shows that it works.
每个设备上都有一个内部计数器,每次进程使用PACKET_MR_PROMISC
时该计数器都会增加,而当进程消失时该计数器将递减.这样就解决了您最初描述的种族.
There is an internal counter on each device that is incremented each time a process uses PACKET_MR_PROMISC
, and decremented when that process goes away. That solves the race you originally described.
从您提供的最后一个链接开始:
From the last link you provided:
> IFF_PROMISC is not set,
It's not supposed to be set.
The correct way to put into promiscuous mode the device to which a
PF_PACKET socket is to do a SOL_PACKET/PACKET_ADD_MEMBERSHIP
"setsockopt()" call with PACKET_MR_PROMISC as the argument (see the
"packet(7)" man page), and that's what libpcap is doing.
The old way of directly setting IFF_PROMISC had problems - to quote the
comment at the front of "pcap-linux.c":
[snipped]
这篇关于如何在Linux上正确地将网络接口设置为混杂模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!