如何在Linux上正确地将网络接口设置为混杂模式 [英] How to properly put network interface into promiscuous mode on Linux

查看:589
本文介绍了如何在Linux上正确地将网络接口设置为混杂模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

那您如何正确地做到这一点?

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.

  1. 您通过ioctl读取标志
  2. 您更新标志
  3. 其他人修改了标志
  4. 您通过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上正确地将网络接口设置为混杂模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆