当前位置:  开发笔记 > 运维 > 正文

从混杂的网络设备读取

如何解决《从混杂的网络设备读取》经验,为你挑选了2个好方法。

我想为无线流量编写一个实时分析工具.

有谁知道如何从C中的混杂(或嗅探)设备读取?

我知道您需要具有root权限才能执行此操作.我想知道是否有人知道这样做需要什么功能.正常的插座在这里似乎没有意义.



1> DGentry..:

在Linux上,您使用PF_PACKET套接字从原始设备读取数据,例如以混杂模式运行的以太网接口:

s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))

这将发送到您的套接字的每个数据包的副本.但是,您很可能并不真正想要每个数据包.内核可以使用BPF(Berkeley Packet Filter)执行第一级过滤.BPF本质上是一个基于堆栈的虚拟机:它处理一小组指令,例如:

ldh = load halfword (from packet)  
jeq = jump if equal  
ret = return with exit code  

BPF的退出代码告诉内核是否将数据包复制到套接字.可以使用setsockopt(s,SOL_SOCKET,SO_ATTACH_FILTER)直接编写相对较小的BPF程序.(警告:内核采用struct sock_fprog,而不是struct bpf_program,不要混淆那些,否则你的程序在某些平台上不起作用).

对于任何相当复杂的事情,你真的想使用libpcap.BPF的功能有限,特别是每个数据包可以执行的指令数量.libpcap将把一个复杂的过滤器分成两部分,内核执行第一级过滤,而能力更强的用户空间代码则丢弃它实际上不想看到的数据包.

libpcap还从应用程序代码中抽象出内核接口.Linux和BSD使用类似的API,但Solaris需要DLPI,Windows使用其他东西.



2> 小智..:

我曾经不得不听原始的以太网帧,最后为此创建了一个包装器.通过使用设备名称调用该函数,ex eth0我得到了一个处于混杂模式的套接字.您需要做的是创建一个原始套接字,然后将其置于混杂模式.我就是这样做的.

int raw_init (const char *device)
{
    struct ifreq ifr;
    int raw_socket;

    memset (&ifr, 0, sizeof (struct ifreq));

    /* Open A Raw Socket */
    if ((raw_socket = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL))) < 1)
    {
        printf ("ERROR: Could not open socket, Got #?\n");
        exit (1);
    }

    /* Set the device to use */
    strcpy (ifr.ifr_name, device);

    /* Get the current flags that the device might have */
    if (ioctl (raw_socket, SIOCGIFFLAGS, &ifr) == -1)
    {
        perror ("Error: Could not retrive the flags from the device.\n");
        exit (1);
    }

    /* Set the old flags plus the IFF_PROMISC flag */
    ifr.ifr_flags |= IFF_PROMISC;
    if (ioctl (raw_socket, SIOCSIFFLAGS, &ifr) == -1)
    {
        perror ("Error: Could not set flag IFF_PROMISC");
        exit (1);
    }
    printf ("Entering promiscuous mode\n");

    /* Configure the device */

    if (ioctl (raw_socket, SIOCGIFINDEX, &ifr) < 0)
    {
        perror ("Error: Error getting the device index.\n");
        exit (1);
    }

    return raw_socket;
}

然后当你有你的套接字时,你可以使用select来处理数据包到达时.

推荐阅读
我我檬檬我我186
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有