网卡正常情况下,即非混杂混杂模式下,只接收目的地址是本机的数据包。在以太网上,有大量的数据包,但真正发送给自己的非常少,所以非混杂模式下可以极大的减轻网卡的处理负担。混杂模式(Promiscuous Mode)则是相反,网卡能够接收所有经过它的数据流,而不论其目的地址是否是它他。

可以通过Shell命令来修改网卡工作在混杂模式或非混杂模式,如果在做软件开发,那么也可以通过C语言方式编程来实现。

#include <stdio.h>

#include <unistd.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <errno.h>

#include <linux/if_ether.h>

#include <net/if.h>

#include <sys/ioctl.h>

#include <string.h>

#define ETH_NAME "eth1"

int do_promisc(void) {

    int f, s;

    struct ifreq ifr;

    if ( (f=socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)))<0){

        return -1;

    }

    strcpy(ifr.ifr_name, ETH_NAME);

    

    if ((s = ioctl(f, SIOCGIFFLAGS, &ifr))<0){

      close(f);

      return-1;

    }

    

    if(ifr.ifr_flags & IFF_RUNNING){

        printf("eth link up\n");

    }else{

        printf("eth link down\n");

    }

    ifr.ifr_flags |= IFF_PROMISC;

    if ((s = ioctl(f, SIOCSIFFLAGS, &ifr)) < 0){

      return -1;

    }

    printf("Setting interface ::: %s ::: to promisc\n\n", ifr.ifr_name);

    return 0;

}

int check_nic(void)

{

    struct ifreq ifr;

    int skfd = socket(AF_INET, SOCK_DGRAM, 0);

    strcpy(ifr.ifr_name, ETH_NAME);

    if (ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0)

    {

        close(skfd);

        return -1;

    }

    if(ifr.ifr_flags & IFF_RUNNING){

        printf("link up\n");

        close(skfd);

        return 0; // 网卡已插上网线

    }else {

        printf("link down\n");

        close(skfd);

        return -1;

    }

}

int main(void) {

    do_promisc();

    return 0;

关于通过C语言来设置Linux中网卡为混杂模式,本文就介绍这么多,希望对您有所帮助,谢谢!

03-14 13:25