📄 arp.cpp
字号:
//////////////////////////////////////////////////////////////////////////
// arp.cpp
#include "stdafx.h"
#include "arp.h"
#include "iptypes.h"
#include "IPhlpapi.h"
#include "ipflux.h"
#include "ipfluxdlg.h"
extern CIPFluxApp theApp;
// success return 0
int CWinPcap::OpenPcap()
{
WCHAR buf[1024];
ULONG bufsize = sizeof(buf);
int res, i = 0;
int n_sz = sizeof(adapterlist);
memset ((void*)adapterlist, 0, n_sz);
res = PacketGetAdapterNames ((char*)buf, &bufsize); // 枚举网卡
#ifdef NDEBUG
::MessageBoxW(NULL, buf, NULL, MB_OK);
#endif
if (res == 0)
{
return -1;
}
WCHAR *p1, *p2;
p1 = p2 = buf;
while ((*p1 != '\0') || (*(p1 - 1) != '\0'))
{
if (*p1 == '\0')
{
memcpy (adapterlist[i], p2, 2 * (p1 - p2));
p2 = p1 + 1;
i++;
}
p1++;
}
m_iAdapterNum = i;
m_iSelAdapter = i - 1;
// m_iSelAdapter = 0;
// 打开最后一个网卡,PC机一般是一个网卡
m_lpAdapter = PacketOpenAdapter( ((char *)adapterlist + m_iSelAdapter * 1024) );
if (m_lpAdapter == NULL || (m_lpAdapter->hFile == INVALID_HANDLE_VALUE))
{
AfxMessageBox("PacketOpenAdapter failed!");
return -1;
}
// 分配sender包空间
m_lpPacketSender = PacketAllocatePacket();
if (m_lpPacketSender == NULL)
return -1;
return 0;
}
void CWinPcap::ClosePcap()
{
PacketFreePacket(m_lpPacketSender);
PacketFreePacket(m_lpPacketReceiver);
PacketCloseAdapter(m_lpAdapter);
}
/************************************************************************
功能 获得本机网卡的IP地址,物理地址,涉及到<ntddndis.h>
参数
sin IP地址
strMAC MAC地址16进制表达
mac[] MAC地址字节表达
************************************************************************/
void CWinPcap::GetNetInfo(sockaddr_in &sin, CString &strMAC, BYTE mac[])
{
PIP_ADAPTER_INFO pAdapterInfo = NULL;
char ch;
long sizeinfo;
ULONG size = 0;
int res = 0;
DWORD retv = 0;
char szErr[32] = "";
CString str;
str.Empty();
char szMac[3] = "";
// char szMAC[18] = "FF-FF-FF-FF-FF-FF";
// char szTmp[2] = "";
// CString strAddr;
// strAddr.Format ("Address of sin : 0x%X\nAddress of strMAC : 0x%X\nAddress of mac[] : 0x%X", &sin, &strMAC, &mac);
// AfxMessageBox(strAddr);
sizeinfo = sizeof(m_netinfo);
if (m_lpAdapter)
{
// 先获得ip地址
#ifdef NDEBUG
AfxMessageBox("Trap2");
#endif
// __try{
res = PacketGetNetInfoEx (adapterlist[m_iSelAdapter], &m_netinfo, &sizeinfo);
// }
/*
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
{
AfxMessageBox("EXCEPTION_ACCESS_VIOLATION");
}
*/
#ifdef NDEBUG
AfxMessageBox("Trap3");
#endif
if (res)
{
sin = *(struct sockaddr_in *)&m_netinfo.IPAddress;
}
else
{
strMAC = "FF-FF-FF-FF-FF-FF";
}
// 试图获得AdapterInfo,size返回需要的缓冲区的大小
res = GetAdaptersInfo ((PIP_ADAPTER_INFO)&ch, &size);
if (res == ERROR_BUFFER_OVERFLOW)
{
pAdapterInfo = (PIP_ADAPTER_INFO)malloc (sizeof(IP_ADAPTER_INFO));
if (pAdapterInfo == NULL)
{
AfxMessageBox("malloc fails!");
}
res = GetAdaptersInfo(pAdapterInfo, &size);
if (res == 0)
{
//CString str;
BYTE *pch = pAdapterInfo->Address; // 导出mac地址16进制表达
memcpy (mac, pch, 6);
for (int i = 0; i < 6; i++)
{
/*
if (i)
strcat(szMAC, "-");
sprintf (szTmp, "%02X", *(pch + i));
strcat(szMAC, szTmp);
*/
if (i)
strMAC += "-";
sprintf (szMac, "%02X", *(pch + i));
strMAC += szMac;
/*
try{
str.Format("%02X", *(pch + i));
}
catch (...) {
AfxMessageBox("EXCEPTION_ACCESS_VIOLATION");
}
strMAC += str;
*/
}
// szMAC[17] = '\0';
}
free (pAdapterInfo);
}
}
// strMAC = szMAC;
}
/***********************************************************************
功能 供发送线程调用,发送一个arp请求包
参数
ipCur 目标IP地址
ipMine 本机IP地址
mac[] 网卡MAC地址
***********************************************************************/
int CWinPcap::Sender(ULONG ipCur, ULONG ipMine, BYTE mac[])
{
char pBufSend[1024];
ETHDR eth;
ARPHDR arp;
// Fill the ARP request packets.
int i;
for (i = 0; i < 6; i++)
{
eth.eh_dst[i] = 0xff;
arp.arp_tha[i] = 0x00;
}
// {填充DLC头和ARP头
eth.eh_type = htons(ETH_ARP);
memcpy(eth.eh_src, mac, 6);
arp.arp_hdr = htons(ARP_HARDWARE);
arp.arp_pro = htons(ETH_IP);
arp.arp_hln = 6;
arp.arp_pln = 4;
arp.arp_opt = htons(ARP_REQUEST);
memcpy(arp.arp_sha, mac, 6);
arp.arp_spa = htonl(ipMine);
arp.arp_tpa = htonl(ipCur);
// }
memset(pBufSend, 0, sizeof(pBufSend));
memcpy(pBufSend, ð, sizeof(eth));
// 装配完整arp包
memcpy(pBufSend + sizeof(eth), &arp, sizeof(arp));
PacketInitPacket(m_lpPacketSender, pBufSend, sizeof(eth) + sizeof(arp));
if(PacketSendPacket(m_lpAdapter, m_lpPacketSender,TRUE)==FALSE)
{
return -1;
}
static int j = 0;
CString str;
str.Format ("发送第%d个ARP包\n", ++j);
OutputDebugString(str); // 送到输出窗口,仅调试时有效
return 0;
}
int CWinPcap::Sniff()
{
static CIPFluxDlg *pdlg = (CIPFluxDlg *)AfxGetMainWnd();
char recvbuf[1024*250];
DWORD res = 0;
static int icount = 0;
CString str;
// {初始化网卡,设置为混合模式NDIS_PACKET_TYPE_PROMISCUOUS
if(PacketSetHwFilter(m_lpAdapter, NDIS_PACKET_TYPE_PROMISCUOUS)==FALSE)
{
//printf("Warning: Unable to set the adapter to promiscuous mode\n");
}
if(PacketSetBuff(m_lpAdapter, 500*1024)==FALSE)
{
//printf("PacketSetBuff Error: %d\n",GetLastError());
return -1;
}
if(PacketSetReadTimeout(m_lpAdapter, 1)==FALSE)
{
//printf("Warning: Unable to set the timeout\n");
}
if((m_lpPacketReceiver=PacketAllocatePacket())==FALSE)
{
//printf("PacketAllocatePacket receive Error: %d\n",GetLastError());
return -1;
}
PacketInitPacket(m_lpPacketReceiver, (char *)recvbuf, sizeof(recvbuf));
// }
// {接受包
do
{
if(PacketReceivePacket(m_lpAdapter, m_lpPacketReceiver, TRUE) == FALSE)
{
if(GetLastError() == 6)
return 0;
return -1;
}
icount++;
str.Format ("收到 %d 个包\n", icount);
OutputDebugString ((LPCTSTR)str);
GetData (m_lpPacketReceiver); // 解析包的内容
if (pdlg->m_bStop == TRUE)
break;
}while (1);
// }
ResetEvent(pdlg->m_hEvent); // 辅助函数
return 0;
}
/***********************************************************************
功能 从接受到的包中提取和解析处ARP包个字段
参数
lp 网卡接受到的包的缓冲区指针
***********************************************************************/
void CWinPcap::GetData(LPPACKET lp)
{
ULONG ulOffset = 0, ulBytesReceived;
char *buf = NULL;
char *pChar, *pBase;
struct bpf_hdr *phdr = NULL;
struct sockaddr_in sin;
ETHDR *pEther;
ARPHDR *pArp;
//IPHDR *pIphdr;
CString strIP, strMAC;
static CIPFluxDlg *pdlg = (CIPFluxDlg *)AfxGetMainWnd();
// TRACE ("CWinPcap::GetData\n");
buf = (char*)lp->Buffer;
ulBytesReceived = lp->ulBytesReceived;
while (ulOffset < ulBytesReceived)
{
phdr = (struct bpf_hdr *)(buf + ulOffset);
ulOffset += phdr->bh_hdrlen;
pChar = (char *)(buf + ulOffset);
pBase = pChar;
ulOffset = Packet_WORDALIGN(ulOffset + phdr->bh_caplen);
pEther = (PETHDR)pChar;
pArp = (PARPHDR)(pChar + sizeof(ETHDR));
// receive ARP reply packets containing IP address and relative MAC address
// 受到arp响应包,包含IP地址和相关的MAC地址
if (pEther->eh_type == htons(ETH_ARP) && pArp->arp_opt == htons(ARP_REPLY))
{
OutputDebugString ("收到一个ARP响应包\n");
sin.sin_addr.s_addr = pArp->arp_spa;
strIP.Format("%-16s", inet_ntoa(sin.sin_addr));
CString str;
str.Format("%02X", pEther->eh_src[0]);
strMAC = str;
for (int i = 1; i < 6; i++)
{
str.Format ("-%02X", pEther->eh_src[i]);
strMAC += str;
}
pdlg->ShowSearch(strIP, strMAC);
SetEvent(pdlg->m_hEvent);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -