#include <stdio.h>
#include <pcap.h>
#include <stdlib.h>
#include <Winsock2.h>
#include <iostream>
#include <tchar.h>
#include <conio.h>
#pragma comment (lib,"Ws2_32.lib")
#pragma comment (lib,"wpcap.lib")
using namespace std;#define HARDWARE_TYPE 0x0001
#define PROTOCOL_TYPE 0x0800
#define CAOZUO_REQ 0x0001
#define CAOZUO_REP 0x0002
#define PHY_TYPE 0x8086
#define MACIPLEN 0x0604
#define ARP_PAD {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
#define BROADMAC {0xff,0xff,0xff,0xff,0xff,0xff}
#define ETH_HRD_DEFAULT {BROADMAC,{0,0,0,0,0,0},htons(PHY_TYPE)}
#define ARP_HRD_DEFAULT {htons(HARDWARE_TYPE),htons(PROTOCOL_TYPE),htons(MACIPLEN),htons(CAOZUO_REQ),{0,0,0,0,0,0},0,{0,0,0,0,0,0},0,ARP_PAD}struct ethernet_head
{
u_char dest_mac[6];
u_char sour_mac[6];
u_short eth_type;
};struct arp_head
{
u_short hard_type;
u_short proto_type;
u_short maciplen;
u_short caozuo;
u_char sour_addr[6];
u_long sour_ip;
u_char dest_addr[6];
u_long dest_ip;
u_char padding[18];
};struct arp_packet
{
ethernet_head eth;
arp_head arp;
};
//构建报文
u_char* enArpReqPack(u_char *source_mac,u_char *destine_mac,u_long source_ip,u_long destine_ip,int packetsize)
{
arp_packet arpPackStru ={ETH_HRD_DEFAULT,ARP_HRD_DEFAULT};
u_char *arpStruToStr=(u_char*)malloc(sizeof(u_char*)*packetsize);
memset(arpStruToStr,0,sizeof(arpStruToStr));
memcpy(arpStruToStr,&arpPackStru.eth.dest_mac,6);
memcpy(arpStruToStr+6,source_mac,6);
memcpy(arpStruToStr+12,&arpPackStru.eth.eth_type,2);
memcpy(arpStruToStr+14,&arpPackStru.arp.hard_type,2);
memcpy(arpStruToStr+16,&arpPackStru.arp.proto_type,2);
memcpy(arpStruToStr+18,&arpPackStru.arp.maciplen,2);
memcpy(arpStruToStr+20,&arpPackStru.arp.caozuo,2);
memcpy(arpStruToStr+22,source_mac,6);
memcpy(arpStruToStr+28,&source_ip,4);
memcpy(arpStruToStr+32,&arpPackStru.arp.dest_addr,6);
memcpy(arpStruToStr+38,&destine_ip,4);
return arpStruToStr;
}//获取本地的mac地址
u_char *getSelfMac(char *pDevName,u_long chLocalIP)
{
int GotMac=0;
pcap_t *pAdaptHandle;
char errbuf[PCAP_ERRBUF_SIZE];
if((pAdaptHandle=pcap_open_live(pDevName,60,1,100,errbuf))==NULL)
{
printf("\n打不开所需要的适配器\n");
return NULL;
}
printf("3-1done\n");
struct pcap_pkthdr *header;
const u_char *pkt_data;
int res;
u_short arp_option;
u_long arp_yuanip=0;
u_long arp_muip=0;
u_char arp_yuanmac[6];
u_char source_mac[6]={0,0,0,0,0,0};
u_char *packetforself;
packetforself=enArpReqPack(source_mac,source_mac,chLocalIP,chLocalIP,60);
printf("3-2done\n");
while(!GotMac)
{
pcap_sendpacket(pAdaptHandle,packetforself,60);
Sleep(10);
res=pcap_next_ex(pAdaptHandle,&header,&pkt_data);
// printf("3-3done\n");
if (res==0)continue;
printf("3-4done\n");
memcpy(&arp_option,pkt_data+20,2);
memcpy(arp_yuanmac,pkt_data+22,6);
memcpy(&arp_yuanip,pkt_data+28,4);
memcpy(&arp_muip,pkt_data+38,4);
if(arp_option==htons(CAOZUO_REP)&&arp_muip==chLocalIP&&arp_yuanip==chLocalIP)
{
GotMac=1;
pcap_close(pAdaptHandle);
return arp_yuanmac;
}
Sleep(100);
}
pcap_close(pAdaptHandle);
return arp_yuanmac;
}
//接受数据包的回调函数void packet_handler(u_char *param,const struct pcap_pkthdr *header,const u_char *pkt_data)
{
printf("DONE\n");
struct tm *ltime;
char timestr[16];
time_t local_tv_sec;
strftime(timestr,sizeof(timestr),"%H %M %S",ltime);
printf("%s",timestr);
u_char mudimac[6];
u_long mudiip;
memcpy(mudimac,&pkt_data+22,6);
memcpy(&mudiip,&pkt_data+28,4);
printf("%s.....%d\n",mudimac,mudiip);}int main()
{
pcap_if_t *alldevs;
pcap_if_t *d;
u_char *LOCALMAC;
u_long LOCALIP;
u_long destineIP;
u_char* arp_for_request;
u_char mudimac[6]={0,0,0,0,0,0};
int iresult;
int i=0;
int inum;
u_int netsize;
pcap_t *adhandle;
char errbuf[PCAP_ERRBUF_SIZE];
u_int netmask;
char *filter ="ether proto\\arp";//过滤规则
struct bpf_program fcode;//过虑结果
//获得本地的设备列表
if(pcap_findalldevs(&alldevs,errbuf)==-1)
{
fprintf(stderr,"使用函数错误,无法找到设备列表%s\n",errbuf);
return -1;
}
//显示设备列表
for(d=alldevs;d;d=d->next)
{
printf("%d.%s",++i,d->name);
if(d->description)
{
printf("   %s\n",d->description);
}
else 
printf("   没有介绍\n");
}
if(i==0)
{
printf("没有找到网络接口\n");
}
//选择的网络网卡
printf("请选择工作的网卡(1-%d):",i);
scanf("%d",&iresult);
while(iresult<1||iresult>i)
{
printf("请正确输入\n");
scanf("%d",&iresult);
}
printf("第一步成功\n");
//跳转到选择的网卡
for(d=alldevs,inum=0;inum<i-1;d=d->next,inum++);
//获取本地网卡的mac地址
LOCALIP=((struct sockaddr_in *)(d->addresses))->sin_addr.s_addr;//获得网卡的IP地址
printf("第二部成功:%d\n",LOCALIP);
LOCALMAC=getSelfMac(d->name,LOCALIP);
printf("第三步成功:%s\n",LOCALMAC); //打开网卡
adhandle=pcap_open_live(d->name,60,0,100,errbuf);
if(adhandle==NULL)
{
fprintf(stderr,"\n无法打开网卡,WinPcap不支持%s",d->name);
pcap_freealldevs(alldevs);
return -1;
}
printf("第四步成功\n"); //本程序只支持以太网
if(pcap_datalink(adhandle)!=DLT_EN10MB)
{
fprintf(stderr,"\n本程序只能在以太网下运行");
pcap_freealldevs(alldevs);
return -1;
}
//向局域网内的电脑发送报文
//获得子网上的机器数
netmask=((struct sockaddr_in*)(d->addresses))->sin_addr.S_un.S_addr;
netsize=~ntohl(netmask);
destineIP=ntohl(LOCALIP&netmask);
for(inum=0;inum<netsize;inum++)
{
destineIP++;
if(destineIP==LOCALIP)continue;
arp_for_request=enArpReqPack(LOCALMAC,mudimac,LOCALIP,htons(destineIP),60);
pcap_sendpacket(adhandle,arp_for_request,60);
Sleep(15);
}
free (arp_for_request);
printf("第五步成功\n");
//开始接受报文
    //设置过滤器
if(pcap_compile(adhandle,&fcode,filter,1,netmask)<0)
{
fprintf(stderr,"\n无法编译过滤规则\n");
pcap_freealldevs(alldevs);
return -1;
}
if(pcap_setfilter(adhandle,&fcode)<0)
{
fprintf(stderr,"\n过滤器设置错误\n");
pcap_freealldevs(alldevs);
return -1;
}
printf("第六步成功\n");
//开始捕获数据包
pcap_loop(adhandle,0,packet_handler,NULL);
return 0;
}