#include "arpPkt.h"
#include <iostream.h>
#include <./pcap.h>
pcap_if_t* alldevs;
pcap_if_t* d;
int i=0,num; //第几个网络适配器
pcap_t *adhandle; //指向分配的空间
char errbuf[PCAP_ERRBUF_SIZE];//错误信息
arp_packet arpPacket;//// 定义ARPPACKET结构体变量
unsigned char tmp_dest_ip[4] = {0,0,0,0};//目的ip
unsigned char tmp_sour_ip[4] = {0,0,0,0};//自身ip
unsigned char tmp_sour_addr[6] = {0x00,0x00,0x00,0x00,0x00,0x00};//目的mac
void setpkt();//初始化packet
void sendPkt();//发送并接收arp packet
void GetMACaddress();
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);//接收到arp packet处理
void main () {
if(pcap_findalldevs(&alldevs,errbuf) == -1)//获得网络设备指针
{
cout<<"Error in pcap_findalldevs:"<<endl;
return ;
}
// 显示网卡列表
for(d=alldevs;d;d=d->next)
{
++i;
cout<<i<<":name:"<<d->name<<endl;
if (d->description)
cout<<"description:"<<d->description<<endl;
else
cout<<"No description available)\n";
}
if(i==0)
{
cout<<"\nNo interfaces found! Make sure WinPcap is installed.\n";
return ;//没有发现网卡信息
}
cout<<"Enter the interface number:(1-"<<i<<")";
cin>>num;
if(num < 1 || num > i)
{
cout<<"\nInterface number out of range.\n";
/* 释放内存 */
pcap_freealldevs(alldevs);
return ;
}
/* 转到选择的网卡 */
for(d=alldevs, i=0; i< num-1 ;d=d->next, i++);
/* 打开设备 */
if ( (adhandle= pcap_open_live(d->name, // name of the device
65536, // portion of the packet to capture
// 65536 guarantees that the whole packet will be captured on all the link layers
1, // promiscuous mode
1000, // read timeout
errbuf // error buffer
) ) == NULL)
{
cout<<"\nUnable to open the adapter. "<<d->name<<"is not supported by WinPcap\n";
/* Free the device list */
pcap_freealldevs(alldevs);
return ;
}
if(d->addresses==NULL){
cout<<"Unable to open the adapter:"<<d->name<<endl;
return;
}
for(i=0;i<4;i++){
tmp_sour_ip[i]=d->addresses->addr->sa_data[i+2];
tmp_dest_ip[i]=d->addresses->addr->sa_data[i+2]&d->addresses->netmask->sa_data[i+2];
}
cout<<"this pc's ip and mac:\nip:";
for(i=0;i<4;i++){
cout<<dec<<(int)tmp_sour_ip[i];
if(i!=3)
cout<<".";
}
cout<<endl<<"the results:(ctrl+c to quit)\n";
GetMACaddress();
setpkt();//初始packet
sendPkt();//发送arp请求,并监听arp响应
}
void sendPkt(){
for(i=1;i<256;i++)
{
arpPacket.arp.dest_ip[3]=(unsigned char)i;
if (pcap_sendpacket(adhandle, (unsigned char*)&arpPacket, sizeof(arpPacket) ) != 0)//发送arp 请求报
{
cout<<"\nError sending the packet: \n";
return;
}
pcap_loop(adhandle, 1, packet_handler, NULL);//接受arp相应包并且做出处理
}
cout<<"send ok!"<<endl;
}
void setpkt(){//设置初始arppkt的数据
memset(&arpPacket, 0, sizeof(arp_packet)); // 数据包初始化
//自动填充的字段
arpPacket.arp.add_len = (unsigned char)6;//mac长度
arpPacket.arp.pro_len = (unsigned char)4;//ip长度
arpPacket.eth.eh_type = htons((unsigned short)0x0806); // DLC Header的以太网类型
arpPacket.arp.hardware_type = htons((unsigned short)1);; // 硬件类型
arpPacket.arp.protocol_type = htons((unsigned short)0x0800); // 上层协议类型
arpPacket.arp.option = htons((unsigned short)0x1);//1为arp请求
for(int i=0;i<sizeof(arpPacket.eth.dest_mac);i++)
arpPacket.eth.dest_mac[i]=0xff;//广播地址
//sour ip and mac
memcpy(arpPacket.arp.sour_addr,tmp_sour_addr,sizeof(tmp_sour_addr));
memcpy(arpPacket.arp.sour_ip,tmp_sour_ip,sizeof(tmp_sour_ip));
memcpy(arpPacket.eth.source_mac,tmp_sour_addr,sizeof(tmp_sour_addr));
memcpy(arpPacket.arp.dest_ip,tmp_dest_ip,sizeof(tmp_dest_ip));
}
/* Callback function invoked by libpcap for every incoming packet */
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
ethernet_head *PETHDR;
arp_head *PARPHDR;
//retireve the position of the ethernet header
PETHDR=(ethernet_head *)pkt_data;
if((PETHDR->eh_type)==0x0608) //arp data
{
//retireve the position of the arp header
PARPHDR=(arp_head *)(pkt_data +14);
if(PARPHDR->option==0x0200)//对应答进行操作
{
cout<<"ip:\t";
for(int i=0;i<4;i++){
cout<<dec<<(int)PARPHDR->sour_ip[i];
if(i!=3)
cout<<".";
}
cout<<"\tmac:\t";
for(i=0;i<6;i++){
if((int)PARPHDR->sour_addr[i] < 16)//显示ip
cout<<"0";
cout<<hex<<(int)PARPHDR->sour_addr[i];//显示mac
if(i!=5)
cout<<"-";
}
cout<<endl;
}
}
}
void GetMACaddress(void)
{
unsigned char MACData[8]; // Allocate data structure for MAC (6 bytes needed)
WKSTA_TRANSPORT_INFO_0 *pwkti; // Allocate data structure for Netbios
DWORD dwEntriesRead;
DWORD dwTotalEntries;
BYTE *pbBuffer;
// Get MAC address via NetBios's enumerate function
NET_API_STATUS dwStatus = NetWkstaTransportEnum(
NULL, // [in] server name
0, // [in] data structure to return
&pbBuffer, // [out] pointer to buffer
MAX_PREFERRED_LENGTH, // [in] maximum length
&dwEntriesRead, // [out] counter of elements actually enumerated
&dwTotalEntries, // [out] total number of elements that could be enumerated
NULL); // [in/out] resume handle
assert(dwStatus == NERR_Success);
pwkti = (WKSTA_TRANSPORT_INFO_0 *)pbBuffer; // type cast the buffer
for(DWORD i=1; i< dwEntriesRead; i++) // first address is 00000000, skip it
{ // enumerate MACs and print
swscanf((wchar_t *)pwkti[i].wkti0_transport_address, L"%2hx%2hx%2hx%2hx%2hx%2hx",
&MACData[0], &MACData[1], &MACData[2], &MACData[3], &MACData[4], &MACData[5]);
printf("mac: %02X-%02X-%02X-%02X-%02X-%02X\n",
MACData[0], MACData[1], MACData[2], MACData[3], MACData[4], MACData[5]);
for(int i = 0;i < 6;i++)
tmp_sour_addr[i]=(int)MACData[i];
}
// Release pbBuffer allocated by above function
dwStatus = NetApiBufferFree(pbBuffer);
assert(dwStatus == NERR_Success);
}