文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>通过发送arp请求检测局域网内是否有机器处于混杂..

通过发送arp请求检测局域网内是否有机器处于混杂..

时间:2010-05-08  来源:HJLin

目的:     今天饱受局域网内的arp欺骗困挠,所以复习了一下相关的arp方面的知识。mark一下。 功能:     检测局域网内的某台机器是否处于混杂模式状态。 原理:     构造一个arp请求数据帧发送给带检测的机器。通过是收到arp响应判断带检测的机器是否处于混杂模式。首先构造出下面的数据帧。

ARP分组:

  • 目的以太网地址 00 00 00 00 00 00(说明1)
  • 发送方以太网地址 00 11 22 33 44 55(说明2)
  • 高层协议类型 08 00(IP)
  • 硬件类型 00 01(以太网)
  • 硬件地址长度 06(以太网地址长度)
  • IP地址长度 04
  • 发送方的IP地址 本机IP地址
  • 目标的IP地址 被检测主机的IP地址
  • ARP操作码 00 01(ARP请求01、ARP应答02)

  以太网帧:

  • 协议类型 08 06(ARP)
  • 发送方的硬件地址 本机以太网卡地址
  • 目标硬件地址 FF FF FF FF FF FE

 说明1:这时ARP要查询的以太网地址,全部填0或者1都可以。

  说明2:用自己的以太网地址代替。

复制过来,省得打字太麻烦,最关键的一句话就是这里了:目标硬件地址 FF FF FF FF FF FE。这个地址是个特殊的mac地址叫做为广播地址。他有这样的特点,不管在windows或者linux环境下,当网卡处于混杂模式的情况下,网卡的硬件过滤器不会过滤该分组,当然是废话了,混杂模式的网卡才不管你这个地址是什么了,他什么都不过滤,但是如果是普通模式的情况下,硬件过滤器会丢弃该数据帧。那么我们就不会收到arp响应了。接着假如带检测的机器网卡在混杂模式下,该数据帧就会进行下一步处理,也就是通过软件过滤器了。目前的软件过滤器实现一般只判断这个mac地址的第一个字节是不是FF,如果是FF,软件过滤器就把这个数据帧当作是广播处理,就是不过滤的意思了,这样就会交给内核正常的处理流程了,这样的话处于混杂模式的机器就会发送一个arp相应给我们了,那就ok了。反之如果不是FF,软件过滤器就会丢弃掉这个数据帧,这就是为什么我们要把这个目标硬件地址设置成FF FF FF FF FF FE的原因了。

 

代码:

[code]

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <unistd.h>
#include <sys/socket.h>
#include <linux/if_arp.h>
#include <errno.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>

//arp frame header (14 bytes)
struct frame_hdr {
        unsigned char dst_mac[6];
        unsigned char src_mac[6];
        unsigned short frm_type;
};
//arp frame header+body (14+8+20 bytes)
struct frame_ether {
        struct frame_hdr fh;
        struct arphdr ah;
        unsigned char src_mac[6];
        unsigned char src_ip[4];
        unsigned char dst_mac[6];
        unsigned char dst_ip[4];
};

int main(int argc, char **argv) {
        int sockfd;
        struct sockaddr_ll peer_addr;

        //创建AF_PACKET类型socket
        sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ARP));
        if(sockfd == -1)perror("socket()");

        //初始化struct sockaddr_ll 类型的socket地址结构
        memset(&peer_addr, 0, sizeof(peer_addr));
        peer_addr.sll_family = AF_PACKET;
        struct ifreq req;
        strcpy(req.ifr_name, "eth0");
        if(ioctl(sockfd, SIOCGIFINDEX, &req) != 0)perror("ioctl()");
        peer_addr.sll_ifindex = req.ifr_ifindex;
        peer_addr.sll_protocol = htons(ETH_P_ARP);

        //发送arp请求到要检测的机器ip
        unsigned char bad_mac[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}; //伪广播地址,混杂模式下,软件过滤层不会过滤该数据帧。就是说会有arp相应了
        unsigned char my_ip[4] = {192, 168, 1, 99};  //本机的ip地址
        unsigned char my_mac[6] = {0x00, 0x0c, 0x29, 0x5e, 0x01, 0xff}; //本机的mac地址
        unsigned char dst_ip[4] = {192, 168, 1, 102}; //要检测是否处于混杂模式的机器ip
        unsigned char dst_mac[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};


        //build arp frame
        struct frame_ether frame;
        memcpy(frame.fh.dst_mac, bad_mac, 6);
        memcpy(frame.fh.src_mac, my_mac, 6);
        frame.fh.frm_type = htons(ETH_P_ARP);

        frame.ah.ar_hrd = htons(ARPHRD_ETHER);
        frame.ah.ar_pro = htons(ETH_P_IP);
        frame.ah.ar_hln = 6;
        frame.ah.ar_pln = 4;
        frame.ah.ar_op = htons(ARPOP_REQUEST);
        memcpy(frame.src_mac, my_mac, 6);
        memcpy(frame.src_ip, my_ip, 4);
        memcpy(frame.dst_mac, dst_mac, 6);
        memcpy(frame.dst_ip, dst_ip, 4);
        int nbytes = sendto(sockfd, &frame, sizeof(frame), 0, (struct sockaddr*)&peer_addr, sizeof(peer_addr));
        printf("nbytes = %d\n", nbytes);

        return 0;
}

[/code]   说明: linux的2.6内核。 直接gcc编译。 然后执行。   同时打开一个窗口用tcpdump arp 观察是否收到了arp响应。     最后: that's all!
相关阅读 更多 +
排行榜 更多 +
我是班长去广告版下载

我是班长去广告版下载

模拟经营 下载
什么鸭小游戏安卓版下载

什么鸭小游戏安卓版下载

策略塔防 下载
极光影院官方最新版本2025下载

极光影院官方最新版本2025下载

趣味娱乐 下载