然后是发送ARP请求报文的主线程,取得所有适配器的名字。其中,“adapter_name”表示一个用于存放适配器名字的缓冲区,而这些适配器名字将以UNICODE编码方式存入此缓冲区中。UNICODE编码方式就是用一个字的空间(两个字节)来存放一个字符。这样,每个字符间自然会出现一个''\0''。而两个适配器名字之间将会有一个字为''\0''作为间隔。adapter_length:这个缓冲区的大小:
★
if(PacketGetAdapterNames((char*)adapter_name, &adapter_length)==FALSE)
{
printf("PacketGetAdapterNames error:%d\n",GetLastError());
return 0;
}
★
打开适配器,此处我默认打开第一块适配器:
★
lpAdapter=(LPADAPTER)PacketOpenAdapter((LPTSTR)adapter_list[0]);
if (!lpAdapter||(lpAdapter->hFile==INVALID_HANDLE_VALUE))
{
printf("Unable to open the driver, Error Code : %lx\n", GetLastError());
return 0;
}
★
以太网头部和ARP头部结构赋值,StrToMac函数是笔者自定义的字符串转换为Mac地址的函数:
★
StrToMac("00E06E41508F",s_Mac); //"00E06E41508F"是笔者测试程序所用的本地机的网卡地址,测试者应将其改为测试机网卡地址
memcpy(et_header.eh_src,s_Mac,6);
StrToMac("FFFFFFFFFFFE",d_Mac); //目的物理地址设置为FFFFFFFFFFFE。
memcpy(et_header.eh_dst,d_Mac,6);
et_header.eh_type=htons(0x0806); //类型为0x0806表示这是ARP包
arp_header.arp_hdr=htons(0x0001); //硬件地址类型以太网地址
arp_header.arp_pro=htons(0x0800); //协议地址类型为IP协议
arp_header.arp_hln=6; //硬件地址长度为6
arp_header.arp_pln=4; //协议地址长度为4
arp_header.arp_opt=htons(0x0001); //标识为ARP请求
arp_header.arp_spa=inet_addr("172.24.21.10"); //"172.24.21.10"是我测试程序所用的本地机的IP,测试者应将其改为测试机IP
memcpy(arp_header.arp_sha,et_header.eh_src,6);
arp_header.arp_tpa=inet_addr(argv[1]);
memcpy(arp_header.arp_tha,et_header.eh_dst,6);
★
发送数据包:
★
lpPacket=PacketAllocatePacket(); //给PACKET结构指针分配内存
PacketInitPacket(lpPacket,buffer,512); //初始化PACKET结构指针
PacketSetNumWrites(lpAdapter,5); //设置发送次数
PacketSendPacket(lpAdapter,lpPacket,TRUE);//发送ARP请求包
★
最后别忘了扫尾工作:
★
PacketFreePacket(lpPacket); //释放PACKET结构指针
PacketCloseAdapter(lpAdapter); //关闭适配器
★
最后是监听线程:
设置接收数据包的系列参数:
★
PacketSetHwFilter(lpAdapter, NDIS_PACKET_TYPE_DIRECTED); //设置网卡为直接模式
PacketSetBuff(lpAdapter,1024); //设置网卡接收数据包的缓冲区大小
PacketSetReadTimeout(lpAdapter,2); //设置接收到一个包后的“休息”时间
★
接收数据包:
★PacketReceivePacket(lpAdapter, lpPacket, TRUE); //接收数据包★
对数据包进行分析,以得出结论:
★
char *buf;
bpf_hdr *lpBpfhdr;
ET_HEADER *lpEthdr;
in_addr addr={0};
buf=(char *)lpPacket->Buffer;
lpBpfhdr=(bpf_hdr *)buf;
lpEthdr=(ET_HEADER *)(buf+lpBpfhdr->bh_hdrlen);
if(lpEthdr->eh_type==htons(0x0806)) //判断是否为ARP包
{
ARP_HEADER *lpArphdr=(ARP_HEADER*)(buf+lpBpfhdr->bh_hdrlen+sizeof(ET_HEADER));
char source_ip[20]={0},dest_ip[20]={0};
addr.S_un.S_addr=lpArphdr->arp_spa;
memcpy(source_ip,inet_ntoa(addr),strlen(inet_ntoa(addr)));
memset(&addr,0,sizeof(in_addr));
addr.S_un.S_addr=lpArphdr->arp_tpa;
memcpy(dest_ip,inet_ntoa(addr),strlen(inet_ntoa(addr)));
if(!strcmp(source_ip,ip) && !strcmp(dest_ip,"172.24.21.10
")) //判断接收到的包的源IP与目的IP是否正确(字符串变量ip是从主线程传递过来的被探测机的ip)
{
if(lpArphdr->arp_opt==htons(0x0002)) //判断是否为ARP应答
{
printf("There is a Sniffer!\n");
}
}
http://www.cnxhacker.com/Article/hacker/tools/200612/7441_2.html