ARP帧数据结构
#define
BROADMAC {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}
//
广播MAC
#define EH_TYPE 0x0806 // ARP类型
#define ARP_HRD 0X0001 // 硬件类型:以太网接口类型为
#define ARP_PRO 0x0800 // 协议类型:IP协议类型为X0800
#define ARP_HLN 0x06 // 硬件地址长度:MAC地址长度为B
#define ARP_PLN 0x04 // 协议地址长度:IP地址长度为B
#define ARP_REQUEST 0x0001 // 操作:ARP请求为
#define ARP_REPLY 0x0002 // 操作:ARP应答为
#define ARP_THA {0,0,0,0,0,0} // 目的MAC地址:ARP请求中该字段没有意义,设为;ARP响应中为接收方的MAC地址
#define ARP_PAD {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} // 18字节的填充数据
#define SPECIAL 0x70707070 // 定义获得自己MAC地址的特殊源IP,.112.112.112
#define ETH_HRD_DEFAULT {BROADMAC, {0,0,0,0,0,0}, htons(EH_TYPE)} // 广播ARP包帧头
#define ARP_HRD_DEFAULT {htons(ARP_HRD), htons(ARP_PRO), ARP_HLN, ARP_PLN, htons(ARP_REQUEST), {0,0,0,0,0,0}, 0, ARP_THA, 0, ARP_PAD}
#define IPTOSBUFFERS 12
#define WM_PACKET WM_USER + 105 // 用户自定义消息
struct ethernet_head
{ // 物理帧帧头结构
unsigned char dest_mac[ 6 ]; // 目标主机MAC地址(6字节)
unsigned char source_mac[ 6 ]; // 源端MAC地址(6字节)
unsigned short eh_type; // 以太网类型(2字节)
};
struct arp_head
{ // ARP数据帧
unsigned short hardware_type; // 硬件类型:以太网接口类型为
unsigned short protocol_type; // 协议类型:IP协议类型为X0800
unsigned char add_len; // 硬件地址长度:MAC地址长度为B
unsigned char pro_len; // 协议地址长度:IP地址长度为B
unsigned short option; // 操作:ARP请求为,ARP应答为
unsigned char sour_addr[ 6 ]; // 源MAC地址:发送方的MAC地址
unsigned long sour_ip; // 源IP地址:发送方的IP地址
unsigned char dest_addr[ 6 ]; // 目的MAC地址:ARP请求中该字段没有意义;ARP响应中为接收方的MAC地址
unsigned long dest_ip; // 目的IP地址:ARP请求中为请求解析的IP地址;ARP响应中为接收方的IP地址
unsigned char padding[ 18 ];
};
struct arp_packet // 最终arp包结构
{ // 物理帧结构
ethernet_head eth; // 以太网头部
arp_head arp; // arp数据包头部
};
#define EH_TYPE 0x0806 // ARP类型
#define ARP_HRD 0X0001 // 硬件类型:以太网接口类型为
#define ARP_PRO 0x0800 // 协议类型:IP协议类型为X0800
#define ARP_HLN 0x06 // 硬件地址长度:MAC地址长度为B
#define ARP_PLN 0x04 // 协议地址长度:IP地址长度为B
#define ARP_REQUEST 0x0001 // 操作:ARP请求为
#define ARP_REPLY 0x0002 // 操作:ARP应答为
#define ARP_THA {0,0,0,0,0,0} // 目的MAC地址:ARP请求中该字段没有意义,设为;ARP响应中为接收方的MAC地址
#define ARP_PAD {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} // 18字节的填充数据
#define SPECIAL 0x70707070 // 定义获得自己MAC地址的特殊源IP,.112.112.112
#define ETH_HRD_DEFAULT {BROADMAC, {0,0,0,0,0,0}, htons(EH_TYPE)} // 广播ARP包帧头
#define ARP_HRD_DEFAULT {htons(ARP_HRD), htons(ARP_PRO), ARP_HLN, ARP_PLN, htons(ARP_REQUEST), {0,0,0,0,0,0}, 0, ARP_THA, 0, ARP_PAD}
#define IPTOSBUFFERS 12
#define WM_PACKET WM_USER + 105 // 用户自定义消息
struct ethernet_head
{ // 物理帧帧头结构
unsigned char dest_mac[ 6 ]; // 目标主机MAC地址(6字节)
unsigned char source_mac[ 6 ]; // 源端MAC地址(6字节)
unsigned short eh_type; // 以太网类型(2字节)
};
struct arp_head
{ // ARP数据帧
unsigned short hardware_type; // 硬件类型:以太网接口类型为
unsigned short protocol_type; // 协议类型:IP协议类型为X0800
unsigned char add_len; // 硬件地址长度:MAC地址长度为B
unsigned char pro_len; // 协议地址长度:IP地址长度为B
unsigned short option; // 操作:ARP请求为,ARP应答为
unsigned char sour_addr[ 6 ]; // 源MAC地址:发送方的MAC地址
unsigned long sour_ip; // 源IP地址:发送方的IP地址
unsigned char dest_addr[ 6 ]; // 目的MAC地址:ARP请求中该字段没有意义;ARP响应中为接收方的MAC地址
unsigned long dest_ip; // 目的IP地址:ARP请求中为请求解析的IP地址;ARP响应中为接收方的IP地址
unsigned char padding[ 18 ];
};
struct arp_packet // 最终arp包结构
{ // 物理帧结构
ethernet_head eth; // 以太网头部
arp_head arp; // arp数据包头部
};
获取本机的网络适配器
int
i
=
1
;
string strDev = "" ;
m_Dev.AddString( " 经分析,本系统网络适配器列表如下: " );
pcap_if_t * alldevs = 0 ;
pcap_if_t * pDev = 0 ;
pcap_addr_t * pAdr = 0 ;
char errbuf[PCAP_ERRBUF_SIZE + 1 ];
if (pcap_findalldevs( & alldevs, errbuf) == - 1 )
{ // 获得设备列表
MessageBox(errbuf, NULL, MB_OK | MB_ICONINFORMATION); // 若没有设备则弹出警告
exit( 1 );
}
for (pDev = alldevs; pDev; pDev = pDev -> next)
{ // 遍历所有成员
if (pDev -> description)
{
strDev = char (i + 48 );
strDev += " . " ;
strDev += DelSpace(pDev -> description); // 去掉网卡描述过多的空格
pAdr = pDev -> addresses; // IP地址
if (pAdr != NULL)
{
if (pAdr -> addr -> sa_family == AF_INET)
{ // pAdr->addr是否IP地址类型
strDev += " -> " ;
strDev += IpToStr((( struct sockaddr_in * )pAdr -> addr) -> sin_addr.s_addr);
if (IpToStr((( struct sockaddr_in * )pAdr -> addr) -> sin_addr.s_addr)[ 0 ] != ' 0 ' )
{
m_Dev_No = i;
UpdateData(FALSE); // 传递变量值去界面
}
strDev += " & [ " ;
strDev += IpToStr((( struct sockaddr_in * )pAdr -> netmask) -> sin_addr.s_addr); // 子网掩码
strDev += " ] " ;
GetDlgItem(IDC_GET_MAC) -> EnableWindow(TRUE); // 若网卡有IP地址,则使抓包按钮可用
}
}
m_Dev.InsertString(i ++ , strDev.c_str());
}
}
pcap_freealldevs(alldevs); // 不再需要网络适配器列表, 释放
string strDev = "" ;
m_Dev.AddString( " 经分析,本系统网络适配器列表如下: " );
pcap_if_t * alldevs = 0 ;
pcap_if_t * pDev = 0 ;
pcap_addr_t * pAdr = 0 ;
char errbuf[PCAP_ERRBUF_SIZE + 1 ];
if (pcap_findalldevs( & alldevs, errbuf) == - 1 )
{ // 获得设备列表
MessageBox(errbuf, NULL, MB_OK | MB_ICONINFORMATION); // 若没有设备则弹出警告
exit( 1 );
}
for (pDev = alldevs; pDev; pDev = pDev -> next)
{ // 遍历所有成员
if (pDev -> description)
{
strDev = char (i + 48 );
strDev += " . " ;
strDev += DelSpace(pDev -> description); // 去掉网卡描述过多的空格
pAdr = pDev -> addresses; // IP地址
if (pAdr != NULL)
{
if (pAdr -> addr -> sa_family == AF_INET)
{ // pAdr->addr是否IP地址类型
strDev += " -> " ;
strDev += IpToStr((( struct sockaddr_in * )pAdr -> addr) -> sin_addr.s_addr);
if (IpToStr((( struct sockaddr_in * )pAdr -> addr) -> sin_addr.s_addr)[ 0 ] != ' 0 ' )
{
m_Dev_No = i;
UpdateData(FALSE); // 传递变量值去界面
}
strDev += " & [ " ;
strDev += IpToStr((( struct sockaddr_in * )pAdr -> netmask) -> sin_addr.s_addr); // 子网掩码
strDev += " ] " ;
GetDlgItem(IDC_GET_MAC) -> EnableWindow(TRUE); // 若网卡有IP地址,则使抓包按钮可用
}
}
m_Dev.InsertString(i ++ , strDev.c_str());
}
}
pcap_freealldevs(alldevs); // 不再需要网络适配器列表, 释放
获取本机MAC地址
unsigned
char
*
BuildArpRequestPacket(unsigned
char
*
source_mac, unsigned
char
*
arp_sha, unsigned
long
chLocalIP, unsigned
long
arp_tpa,
int
PackSize)
{ // 封装ARP请求包
static arp_packet arpPackStru;
static const arp_packet arpDefaultPack = {ETH_HRD_DEFAULT,ARP_HRD_DEFAULT};
memcpy( & arpPackStru, & arpDefaultPack, sizeof (arpDefaultPack));
// 填充源MAC地址
memcpy(arpPackStru.eth.source_mac,source_mac, 6 ); // 源MAC
memcpy(arpPackStru.arp.sour_addr,arp_sha, 6 ); // 源MAC
arpPackStru.arp.sour_ip = chLocalIP; // 源IP地址
arpPackStru.arp.dest_ip = arp_tpa; // 目的IP地址
return (unsigned char * ) & arpPackStru;
}
unsigned char * GetSelfMac( char * pDevName, unsigned long chLocalIP)
{ // 获得本机MAC地址,pDevName为网卡名称,chLocalIP为本机IP地址
pcap_t * pAdaptHandle;
char errbuf[PCAP_ERRBUF_SIZE + 1 ];
// 打开网卡适配器
if ((pAdaptHandle = pcap_open_live(pDevName, 60 , 1 , 100 , errbuf)) == NULL)
{
MessageBox(NULL, " 无法打开适配器,可能与之不兼容! " , " Note " , MB_OK);
return NULL;
}
struct pcap_pkthdr * header; // 包头部
const u_char * pkt_data; // 包数据部
int res;
unsigned short arp_op;
static unsigned char arp_sha[ 6 ];
unsigned long arp_spa = 0 ;
unsigned long arp_tpa = 0 ;
unsigned char source_mac[ 6 ] = { 0 , 0 , 0 , 0 , 0 , 0 };
unsigned char * arp_packet_for_self;
arp_packet_for_self = BuildArpRequestPacket(source_mac, source_mac, SPECIAL, chLocalIP, 60 ); // 把自己作为目的,构建一个广播ARP请求包,伪造请求来自.112.112.112
while ( ! GetMacSignal)
{
pcap_sendpacket(pAdaptHandle, arp_packet_for_self, 60 ); // 发送ARP请求包
Sleep( 10 );
res = pcap_next_ex(pAdaptHandle, & header, & pkt_data);
if (res == 0 )
{
continue ;
}
// 物理帧头部占字节,然后是硬件类型,上层协议类型,硬件地址长度,IP地址长度,这四个占去字节,具体参看ARP帧的数据结构
memcpy( & arp_op, pkt_data + 20 , 2 ); // 操作类型(请求或应答)
memcpy(arp_sha, pkt_data + 22 , 6 ); // 源MAC
memcpy( & arp_spa, pkt_data + 28 , 4 ); // 源IP
memcpy( & arp_tpa, pkt_data + 38 , 4 ); // 目标IP
if (arp_op == htons(ARP_REPLY) && arp_spa == chLocalIP && arp_tpa == SPECIAL)
{ // 是本机
GetMacSignal = 1 ;
pcap_close(pAdaptHandle);
return arp_sha;
}
Sleep( 100 ); // 若不成功再等ms再发,让网卡歇歇
}
pcap_close(pAdaptHandle);
return arp_sha;
}
{ // 封装ARP请求包
static arp_packet arpPackStru;
static const arp_packet arpDefaultPack = {ETH_HRD_DEFAULT,ARP_HRD_DEFAULT};
memcpy( & arpPackStru, & arpDefaultPack, sizeof (arpDefaultPack));
// 填充源MAC地址
memcpy(arpPackStru.eth.source_mac,source_mac, 6 ); // 源MAC
memcpy(arpPackStru.arp.sour_addr,arp_sha, 6 ); // 源MAC
arpPackStru.arp.sour_ip = chLocalIP; // 源IP地址
arpPackStru.arp.dest_ip = arp_tpa; // 目的IP地址
return (unsigned char * ) & arpPackStru;
}
unsigned char * GetSelfMac( char * pDevName, unsigned long chLocalIP)
{ // 获得本机MAC地址,pDevName为网卡名称,chLocalIP为本机IP地址
pcap_t * pAdaptHandle;
char errbuf[PCAP_ERRBUF_SIZE + 1 ];
// 打开网卡适配器
if ((pAdaptHandle = pcap_open_live(pDevName, 60 , 1 , 100 , errbuf)) == NULL)
{
MessageBox(NULL, " 无法打开适配器,可能与之不兼容! " , " Note " , MB_OK);
return NULL;
}
struct pcap_pkthdr * header; // 包头部
const u_char * pkt_data; // 包数据部
int res;
unsigned short arp_op;
static unsigned char arp_sha[ 6 ];
unsigned long arp_spa = 0 ;
unsigned long arp_tpa = 0 ;
unsigned char source_mac[ 6 ] = { 0 , 0 , 0 , 0 , 0 , 0 };
unsigned char * arp_packet_for_self;
arp_packet_for_self = BuildArpRequestPacket(source_mac, source_mac, SPECIAL, chLocalIP, 60 ); // 把自己作为目的,构建一个广播ARP请求包,伪造请求来自.112.112.112
while ( ! GetMacSignal)
{
pcap_sendpacket(pAdaptHandle, arp_packet_for_self, 60 ); // 发送ARP请求包
Sleep( 10 );
res = pcap_next_ex(pAdaptHandle, & header, & pkt_data);
if (res == 0 )
{
continue ;
}
// 物理帧头部占字节,然后是硬件类型,上层协议类型,硬件地址长度,IP地址长度,这四个占去字节,具体参看ARP帧的数据结构
memcpy( & arp_op, pkt_data + 20 , 2 ); // 操作类型(请求或应答)
memcpy(arp_sha, pkt_data + 22 , 6 ); // 源MAC
memcpy( & arp_spa, pkt_data + 28 , 4 ); // 源IP
memcpy( & arp_tpa, pkt_data + 38 , 4 ); // 目标IP
if (arp_op == htons(ARP_REPLY) && arp_spa == chLocalIP && arp_tpa == SPECIAL)
{ // 是本机
GetMacSignal = 1 ;
pcap_close(pAdaptHandle);
return arp_sha;
}
Sleep( 100 ); // 若不成功再等ms再发,让网卡歇歇
}
pcap_close(pAdaptHandle);
return arp_sha;
}
发送ARP请求线程
void
SendArpRequest(pcap_if_t
*
pDev, unsigned
char
*
bLocalMac)
{ // 发送ARP请求
pcap_addr_t * pAdr = 0 ;
unsigned long chLocalIp = 0 ; // 存放本地ip地址
unsigned long arp_tpa = 0 ;
unsigned long snd_tpa = 0 ;
unsigned long nlNetMask = 0 ;
int netsize = 0 ;
const char * pDevName = strSelDeviceName.c_str();
pcap_t * pAdaptHandle;
char errbuf[PCAP_ERRBUF_SIZE + 1 ];
// 打开网卡适配器
if ((pAdaptHandle = pcap_open_live(pDev -> name, 60 , 0 , 100 , errbuf)) == NULL)
{
MessageBox(NULL, " 无法打开适配器,可能与之不兼容! " , " Send " , MB_OK);
return ;
}
unsigned char * arp_packet_for_req;
arp_packet_for_req = BuildArpRequestPacket(bLocalMac, bLocalMac, chLocalIp, chLocalIp, 60 ); // 构造包
unsigned long ulOldMask = 0 ;
for (pAdr = pDev -> addresses; pAdr; pAdr = pAdr -> next)
{
if ( ! nThreadSignal)
{ // 判断线程是否应该中止
break ;
}
chLocalIp = (( struct sockaddr_in * )pAdr -> addr) -> sin_addr.s_addr; // 得到本地ip
if ( ! chLocalIp)
{
continue ;
}
nlNetMask = (( struct sockaddr_in * )(pAdr -> netmask)) -> sin_addr.S_un.S_addr; // 得到子网掩码
if (ulOldMask == nlNetMask)
{
continue ;
}
ulOldMask = nlNetMask;
netsize = ~ ntohl(nlNetMask); // 子网大小
arp_tpa = ntohl(chLocalIp & nlNetMask); // IP地址
for ( int i = 0 ; i < netsize; i ++ )
{
if ( ! nThreadSignal)
{
break ;
}
arp_tpa ++ ;
snd_tpa = htonl(arp_tpa);
memcpy(arp_packet_for_req + 38 , & snd_tpa, 4 ); // 目的IP在子网范围内按序增长
pcap_sendpacket(pAdaptHandle, arp_packet_for_req, 60 ); // 发送ARP请求包
Sleep( 5 ); // 休息一下再发ARP请求包
}
}
}
UINT StartArpScan(LPVOID mainClass)
{ // 发送ARP请求线程
AfxGetApp() -> m_pMainWnd -> SendMessage(WM_PACKET, 0 , 1 ); // 开始发送ARP请求包
SendArpRequest(pDevGlobalHandle, bLocalMac); // 对选中设备的所有绑定的IP网段进行ARP请求
AfxGetApp() -> m_pMainWnd -> SendMessage(WM_PACKET, 0 , 2 ); // 全部ARP请求包发送完毕
return 0 ;
}
{ // 发送ARP请求
pcap_addr_t * pAdr = 0 ;
unsigned long chLocalIp = 0 ; // 存放本地ip地址
unsigned long arp_tpa = 0 ;
unsigned long snd_tpa = 0 ;
unsigned long nlNetMask = 0 ;
int netsize = 0 ;
const char * pDevName = strSelDeviceName.c_str();
pcap_t * pAdaptHandle;
char errbuf[PCAP_ERRBUF_SIZE + 1 ];
// 打开网卡适配器
if ((pAdaptHandle = pcap_open_live(pDev -> name, 60 , 0 , 100 , errbuf)) == NULL)
{
MessageBox(NULL, " 无法打开适配器,可能与之不兼容! " , " Send " , MB_OK);
return ;
}
unsigned char * arp_packet_for_req;
arp_packet_for_req = BuildArpRequestPacket(bLocalMac, bLocalMac, chLocalIp, chLocalIp, 60 ); // 构造包
unsigned long ulOldMask = 0 ;
for (pAdr = pDev -> addresses; pAdr; pAdr = pAdr -> next)
{
if ( ! nThreadSignal)
{ // 判断线程是否应该中止
break ;
}
chLocalIp = (( struct sockaddr_in * )pAdr -> addr) -> sin_addr.s_addr; // 得到本地ip
if ( ! chLocalIp)
{
continue ;
}
nlNetMask = (( struct sockaddr_in * )(pAdr -> netmask)) -> sin_addr.S_un.S_addr; // 得到子网掩码
if (ulOldMask == nlNetMask)
{
continue ;
}
ulOldMask = nlNetMask;
netsize = ~ ntohl(nlNetMask); // 子网大小
arp_tpa = ntohl(chLocalIp & nlNetMask); // IP地址
for ( int i = 0 ; i < netsize; i ++ )
{
if ( ! nThreadSignal)
{
break ;
}
arp_tpa ++ ;
snd_tpa = htonl(arp_tpa);
memcpy(arp_packet_for_req + 38 , & snd_tpa, 4 ); // 目的IP在子网范围内按序增长
pcap_sendpacket(pAdaptHandle, arp_packet_for_req, 60 ); // 发送ARP请求包
Sleep( 5 ); // 休息一下再发ARP请求包
}
}
}
UINT StartArpScan(LPVOID mainClass)
{ // 发送ARP请求线程
AfxGetApp() -> m_pMainWnd -> SendMessage(WM_PACKET, 0 , 1 ); // 开始发送ARP请求包
SendArpRequest(pDevGlobalHandle, bLocalMac); // 对选中设备的所有绑定的IP网段进行ARP请求
AfxGetApp() -> m_pMainWnd -> SendMessage(WM_PACKET, 0 , 2 ); // 全部ARP请求包发送完毕
return 0 ;
}
接收ARP响应线程
UINT WaitForArpRepeatPacket(LPVOID mainClass)
{
pcap_t * pAdaptHandle;
const char * pDevName = strSelDeviceName.c_str();
char errbuf[PCAP_ERRBUF_SIZE + 1 ];
// 打开网卡适配器
if ((pAdaptHandle = pcap_open_live(pDevName, 60 , 0 , 100 , errbuf)) == NULL)
{
MessageBox(NULL, " 无法打开适配器,可能与之不兼容! " , " wait " , MB_OK);
return - 1 ;
}
string ipWithMac;
char * filter = " ether proto//arp " ;
bpf_program fcode;
int res;
unsigned short arp_op = 0 ;
unsigned char arp_sha [ 6 ];
unsigned long arp_spa = 0 ;
struct pcap_pkthdr * header;
const u_char * pkt_data;
if (pcap_compile(pAdaptHandle, & fcode, filter, 1 , (unsigned long )( 0xFFFF0000 )) < 0 )
{
MessageBox(NULL, " 过滤条件语法错误! " , " wait " , MB_OK);
return - 1 ;
}
// set the filter
if (pcap_setfilter(pAdaptHandle, & fcode) < 0 )
{
MessageBox(NULL, " 适配器与过滤条件不兼容! " , " wait " , MB_OK);
return - 1 ;
}
while ( 1 )
{
if ( ! nThreadSignal)
{
break ;
}
int i = 0 ;
ipWithMac = "" ;
res = pcap_next_ex(pAdaptHandle, & header, & pkt_data);
if ( ! res)
{
continue ;
}
memcpy( & arp_op, pkt_data + 20 , 2 ); // 包的操作类型
memcpy(arp_sha, pkt_data + 22 , 6 ); // 源MAC地址
memcpy( & arp_spa, pkt_data + 28 , 4 ); // 源IP地址
ipWithMac += IpToStr(arp_spa);
for ( int j = strlen(IpToStr(arp_spa)); j < 16 ; j ++ )
{
ipWithMac += " " ;
}
ipWithMac += " --*-> " ;
ipWithMac += MacToStr(arp_sha);
for (i = 6 ; i > 0 ; i -- )
{
if (arp_sha[i - 1 ] != bLocalMac[i - 1 ])
{
break ;
}
}
if (arp_op == htons(ARP_REPLY) && i)
{
AfxGetApp() -> m_pMainWnd -> SendMessage(WM_PACKET, WPARAM( & ipWithMac), 0 ); // 通知主线程更新界面
}
}
return 0 ;
}
{
pcap_t * pAdaptHandle;
const char * pDevName = strSelDeviceName.c_str();
char errbuf[PCAP_ERRBUF_SIZE + 1 ];
// 打开网卡适配器
if ((pAdaptHandle = pcap_open_live(pDevName, 60 , 0 , 100 , errbuf)) == NULL)
{
MessageBox(NULL, " 无法打开适配器,可能与之不兼容! " , " wait " , MB_OK);
return - 1 ;
}
string ipWithMac;
char * filter = " ether proto//arp " ;
bpf_program fcode;
int res;
unsigned short arp_op = 0 ;
unsigned char arp_sha [ 6 ];
unsigned long arp_spa = 0 ;
struct pcap_pkthdr * header;
const u_char * pkt_data;
if (pcap_compile(pAdaptHandle, & fcode, filter, 1 , (unsigned long )( 0xFFFF0000 )) < 0 )
{
MessageBox(NULL, " 过滤条件语法错误! " , " wait " , MB_OK);
return - 1 ;
}
// set the filter
if (pcap_setfilter(pAdaptHandle, & fcode) < 0 )
{
MessageBox(NULL, " 适配器与过滤条件不兼容! " , " wait " , MB_OK);
return - 1 ;
}
while ( 1 )
{
if ( ! nThreadSignal)
{
break ;
}
int i = 0 ;
ipWithMac = "" ;
res = pcap_next_ex(pAdaptHandle, & header, & pkt_data);
if ( ! res)
{
continue ;
}
memcpy( & arp_op, pkt_data + 20 , 2 ); // 包的操作类型
memcpy(arp_sha, pkt_data + 22 , 6 ); // 源MAC地址
memcpy( & arp_spa, pkt_data + 28 , 4 ); // 源IP地址
ipWithMac += IpToStr(arp_spa);
for ( int j = strlen(IpToStr(arp_spa)); j < 16 ; j ++ )
{
ipWithMac += " " ;
}
ipWithMac += " --*-> " ;
ipWithMac += MacToStr(arp_sha);
for (i = 6 ; i > 0 ; i -- )
{
if (arp_sha[i - 1 ] != bLocalMac[i - 1 ])
{
break ;
}
}
if (arp_op == htons(ARP_REPLY) && i)
{
AfxGetApp() -> m_pMainWnd -> SendMessage(WM_PACKET, WPARAM( & ipWithMac), 0 ); // 通知主线程更新界面
}
}
return 0 ;
}
主线程消息处理
LRESULT CArpByWinpcapDlg::OnPacket(WPARAM wParam, LPARAM lParam)
{
string * transPack = ( string * )wParam;
// 处理捕获到的数据包
if (lParam == 0 )
{
m_Mac_list.AddString(transPack -> c_str());
m_count = " 发现 " ;
char buffer[ 5 ];
itoa(m_Mac_list.GetCount(), buffer, 10 ); // 将数量转化为进制字符串;
m_count += buffer;
m_count += " 台活动主机 " ;
}
else if (lParam == 1 )
{
m_sending = " 正在发送ARP请求包! " ;
}
else if (lParam == 2 )
{
if (nThreadSignal)
{
m_sending = " 全部ARP请求包发送完毕! " ; // 判断是自行发送完毕还是用户终止的?
};
}
UpdateData(FALSE);
return 0 ;
}
{
string * transPack = ( string * )wParam;
// 处理捕获到的数据包
if (lParam == 0 )
{
m_Mac_list.AddString(transPack -> c_str());
m_count = " 发现 " ;
char buffer[ 5 ];
itoa(m_Mac_list.GetCount(), buffer, 10 ); // 将数量转化为进制字符串;
m_count += buffer;
m_count += " 台活动主机 " ;
}
else if (lParam == 1 )
{
m_sending = " 正在发送ARP请求包! " ;
}
else if (lParam == 2 )
{
if (nThreadSignal)
{
m_sending = " 全部ARP请求包发送完毕! " ; // 判断是自行发送完毕还是用户终止的?
};
}
UpdateData(FALSE);
return 0 ;
}
参考资料:《Winpcap网络开发库入门》