11.4.2 设置套接口以捕获链路帧的编程方法

来源:互联网 发布:网络直播用的什么协议 编辑:程序博客网 时间:2024/06/10 17:42

11.4.2  设置套接口以捕获链路帧的编程方法

Linux下编写网络监听程序,比较简单的方法是在超级用户模式下,利用类型为SOCK_PACKET的套接口(用socket()函数创建)来捕获链路帧数据。Linux程序中需引用如下头文件:

 

#include <sys/socket.h>

#include <sys/ioctl.h>              /*ioctl 命令*/

#include <Linux/if_ether.h>         /*ethhdr 结构*/

#include <net/if.h>                 /*ifreq 结构*/

#include <netinet/in.h>             /*in_addr结构*/

#include <Linux/ip.h>               /*iphdr 结构*/

#include <Linux/udp.h>              /*udphdr 结构*/

#include <Linux/tcp.h>              /*tcphdr 结构*/

 

建立SOCK_PACKET类型套接字的方法在11.4.1中已经进行了介绍。如果要监视所有类型的包,则需要采用如下代码:

 

int fd;                              /*fd是套接口的描述符*/

fd = socket(AF_INET, SOCK_PACKET, htons(0x0003));

 

侦听其他主机网络的数据在局域网诊断中经常使用。如果要监听其他网卡的数据,需要将本地的网卡设置为“混杂”模式;当然还需要一个都连接于同一HUB的局域网或者具有“镜像”功能的交换机才可以,否则,只能接收到其他主机的广播包。

 

char*ethname = "eth0";                   /*对网卡eth0进行混杂设置*/

struct ifreq  ifr;                      /*网络接口结构*/

strcpy(ifr.ifr_name, ethname);          /*eth0”写入ifr结构的一个字段中*/

i = ioctl (fd, SIOCGIFFLAGS, &ifr);     /*获得eth0的标志位值*/

if (i<0)                                /*判断是否取出出错*/

{

    close(fd);

    perror("can’t get flags /n");

    return -1;

}

ifr.ifr_flags|=IFF_PROMISC; /*保留原来设置的情况下,在标志位中加入“混杂”方式*/

i = ioctl(fd, SIOCSIFFLAGS, &ifr);      /*将标志位设置写入*/

if (i<0)                                /*判断是否写入出错*/

{

    perror("promiscuous set error/n");

    return -2;

}

 

上面的代码使用了ioctl()SIOCGIFFLAGSSIOCSIFFLAGS命令,用来取出和写入网络接口的标志设置。注意,在修改网络接口标志的时候,务必要先将之前的标志取出,与想设置的位进行“位或”计算后再写入;不要直接将设置的位值写入,因为直接写入会覆盖之前的设置,造成网络接口混乱。遵循如下的步骤:

1)取出标志位。

2)目标标志位=取出的标志位|设置的标志位。

3)写入目标标志位。

原创粉丝点击