交换型网络环境嗅探原理及LINUX下的实现( 二 )


以上讨论的是欺骗两台主机 , 假如我能让局域网中每一台主机的ARP高速缓存中关于其它任意一个主机所对应的MAC地址都为我的MAC地址(04:04:04:04) , 则本局域网中所有数据包我都能捕捉到!
6. 程序设计思路
使用到的函数包
libpcap : 捕捉ARP数据包 。
libnet : 获得本机的MAC地址和IP地址;构造和发送ARP欺骗包 。
这两个的函数包的使用在网上资料很多 , 本文中不介绍 。
主要数据结构
程序中有两个全局变量 , MYIP代表本机的IP地址 , MYMAC代表本机的MAC地址 。
程序中维护一个存放主机信息的链表:
typedef strUCt host HOST;
struct host
{
unsigned long ip; // IP地址
unsigned char mac[6]; // MAC地址
int mac_flag;// 0:MAC为空 , 1:MAC不为空
HOST * next;
};

把握本局域网中每一台主机的IP地址和MAC地址信息 。
利用libpcap捕捉网络中的ARP请求/应答包 , 最大限度的提取相关信息 。如在第五节中的B对A的ARP请求包 , 我们可以提取出关于B的完整信息(2.2.2.2 , 02:02:02) , 也获得了关于A的部分信息(1.1.1.1 , null) 。在知道网络中有主机A的情况下 , 我们可以构造并发送对A的ARP请求包 , 捕捉A的ARP应答包 , 从而完整把握A的信息 。同理 , 我们也可以捕捉TCP/UDP等数据包 , 从中提取信息 。
创建一个向链表增加主机信息的函数:add_host(ip , mac) , 每收到一个ARP请求/应答包 , 都执行add_host( )两次:add_host(发送端IP , 发送端MAC) , add_host(目的端IP , 目的端MAC) 。
在收到ARP应答包时 , 首先检查发送端的IP和MAC , 假如IP不是自己的 , 但MAC是自己的 , 则说明此应答包是本机构造的ARP欺骗包 , 程序忽略 。
对于正常的ARP请求包和应答包 , add_host(ip , mac )中IP或MAC只要有一个是自己的(ip == MYIPmac ==MYMAC) , 则程序忽略 。显然 , 没有必要自己欺骗自己 。
add_host(ip , mac)遍历主机链表 , 假如IP存在 , 且MAC不空 , 则把MAC地址写入;假如不存在 , 则增加一个HOST节点 , 写入IP地址 , 假如MAC不空 , 则也把MAC地址写入 。注重到这样一个情况:在ARP请求包中 , 目的MAC地址是没有意义的 , 所以我们只写入IP地址 , 而MAC地址用NULL来表示 。这是我们收集网络拓朴结构的一种被动方法 。
函数add_host( )逻辑设计MYIP = IP(d) , MYMAC = MAC(d)
代码如下:
void add_host(u_long ip, u_char * mac)
{
HOST * new = NULL;
HOST * cur = NULL;
if( (ip == MYIP)(mac && mac_equal(mac, MYMAC)) )
return;
//遍历链表查询IP地址
for(cur = head; cur; cur = cur->next)
{
if( ip == cur->ip )
{
if( mac ) // MAC地址不空 , 则写入
{
memcpy(cur->mac, mac, ETHER_ADDR_LEN);
cur->mac_flag = 1;
}
return;
}
}
if(cur == NULL) // 链表中没有此IP地址
{
new = (HOST *)malloc(sizeof(HOST));
new->ip = ip;
if( mac )
{
memcpy(new->mac, mac, ETHER_ADDR_LEN);
new->mac_flag = 1;
}
else
new->mac_flag = 0;
new->next = NULL;
if(! head) // 把新节点加入链表
{
head = new;
tail = new;
}
else
{
tail->next = new;
tail = new;
} 
}
return;
}

周期性的向局域网中每一台主机发送ARP欺骗包 。
创建一个发送ARP欺骗包的函数send_fake_arp_packet() , 遍历主机链表的每一个IP地址 , 假如此IP地址的MAC地址已知 , 则遍历主机链表中其它IP地址 , 以其它IP地址和本机的MAC地址为发送端 , 以选中的IP地址和MAC地址为目的端 , 构造并发送ARP应答欺骗包;假如此IP地址的MAC地址未知 , 则以本机IP地址和MAC地址为发送端 , 以选中的IP地址为目的端 , 构造并发送正常的ARP请求包 。注重 , 这是我们收集网络拓朴结构的一种主动方法 。

推荐阅读