⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 arp.cpp

📁 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, &eth, 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 + -