VS2012编写获取ARP命令
上周读了大牛的一篇博文:VC++实现IP与ARP信息获取,可以同理实现APR攻击,自己动手试验了下,由于我采用了VS2012,所以期间出现了不少编译问题,于是做了部分代码修订,最终能够正常执行。
分享如下:
PMIB_IPNETTABLE MyGetIpNetTable(BOOL bOrder);void MyFreeIpNetTable(PMIB_IPNETTABLE pIpNetTable);PMIB_IPADDRTABLE MyGetIpAddrTable(BOOL bOrder);void MyFreeIpAddrTable(PMIB_IPADDRTABLE pIpAddrTable);BOOL InterfaceIdxToInterfaceIp(PMIB_IPADDRTABLE pIpAddrTable,DWORD dwIndex,DWORD& dwIpAddr);BOOL PrintARPTable();/*InterfaceIdxToInterfaceIp 根据IP地址表,将接口索引转化为IP地址pIpAddrTable是IP地址表dwIndex是接口索引函数执行成功之后,str将包含接口的IP地址*/BOOL InterfaceIdxToInterfaceIp(PMIB_IPADDRTABLE pIpAddrTable,DWORD dwIndex,DWORD& dwIpAddr){//遍历IP地址表,查找索引dwIndex对应的IP地址for (DWORD dwIdx = 0;dwIdx < pIpAddrTable->dwNumEntries;dwIdx++){if (dwIndex == pIpAddrTable->table[dwIdx].dwIndex){// 返回查询结果dwIpAddr = pIpAddrTable->table[dwIdx].dwAddr;//inet_ntoa(*((in_addr*)&pIpAddrTable->table[dwIdx].dwAddr));if (dwIpAddr != 0){return TRUE;}else return FALSE;}}return FALSE;}//获取IP地址到适配器的映射关系,即ARP表 PMIB_IPNETTABLE MyGetIpNetTable(BOOL bOrder) { PMIB_IPNETTABLE pIpNetTable = NULL; DWORD dwActualSize = 0; //查询所需缓冲区的大小 if (::GetIpNetTable(pIpNetTable,&dwActualSize,bOrder) == ERROR_INSUFFICIENT_BUFFER) { //为MIB_IPNETTABLE结构申请内存 pIpNetTable = (PMIB_IPNETTABLE)::GlobalAlloc(GPTR,dwActualSize); //获取ARP表 if (::GetIpNetTable(pIpNetTable,&dwActualSize,bOrder) == NO_ERROR) { return pIpNetTable; } ::GlobalFree(pIpNetTable); } return NULL; } void MyFreeIpNetTable(PMIB_IPNETTABLE pIpNetTable) { if (pIpNetTable != NULL) { ::GlobalFree(pIpNetTable); } } //获取IP地址表 PMIB_IPADDRTABLE MyGetIpAddrTable(BOOL bOrder) { PMIB_IPADDRTABLE pIpAddrTable = NULL; DWORD dwActualSize = 0; if (::GetIpAddrTable(pIpAddrTable,&dwActualSize,bOrder) == ERROR_INSUFFICIENT_BUFFER) { pIpAddrTable = (PMIB_IPADDRTABLE)::GlobalAlloc(GPTR,dwActualSize); if (::GetIpAddrTable(pIpAddrTable,&dwActualSize,bOrder) == NO_ERROR) { return pIpAddrTable; } ::GlobalFree(pIpAddrTable); } return NULL; } void MyFreeIpAddrTable(PMIB_IPADDRTABLE pIpAddrTable) { if (pIpAddrTable != NULL) { ::GlobalFree(pIpAddrTable); } } BOOL PrintARPTable() { /* ARP表格打印 */ DWORD i=0,dwCurrIndex=1; char szType[128] = {""}; DWORD dwIpAddr = 0; //首先获取ARP表 PMIB_IPNETTABLE pIpNetTable = MyGetIpNetTable(TRUE); if (pIpNetTable == NULL) { printf("pIpNetTable == NULL in line %d\n",__LINE__); return FALSE; } //获取IP地址表,以便根据它将ARP表项中的接口索引转化为IP地址 PMIB_IPADDRTABLE pIpAddrTable = MyGetIpAddrTable(TRUE); //当前的适配器索引。注意,ARP表应该按照接口索引排序 if (InterfaceIdxToInterfaceIp(pIpAddrTable,dwCurrIndex,dwIpAddr)) { printf("\nInterface: %s on Interface 0x%X\n",inet_ntoa(*((in_addr*)&dwIpAddr)),dwCurrIndex); printf(" Internet Address\tPhysical Address\tType\n"); } else { printf("Error: Could not convert Interface number 0x%X to IP address.\n", pIpNetTable->table[0].dwIndex); return FALSE; } //打印出索引为dwCurrIndex的适配器上的ARP表项 for (i=0; i < pIpNetTable->dwNumEntries; ++i) { //不相等则说明要打印下一个适配器上的ARP表项 if (pIpNetTable->table[i].dwIndex != dwCurrIndex) { dwCurrIndex = pIpNetTable->table[i].dwIndex; if (InterfaceIdxToInterfaceIp(pIpAddrTable,dwCurrIndex,dwIpAddr)) { printf("\nInterface: %s on Interface 0x%X\n",inet_ntoa(*((in_addr*)&dwIpAddr)),dwCurrIndex); printf(" Internet Address\tPhysical Address\tType\n"); } else { printf("Error: Could not convert Interface number 0x%X to IP address.\n", pIpNetTable->table[0].dwIndex); return FALSE; } } //打印此ARP表项中的数据 //IP地址 struct in_addr inadTmp; inadTmp.s_addr = pIpNetTable->table[i].dwAddr; //类型 switch(pIpNetTable->table[i].dwType) { case 1: strcpy_s(szType,"other"); break; case 2: strcpy_s(szType,"invalidated"); break; case 3: strcpy_s(szType,"dynamic"); break; case 4: strcpy_s(szType,"invalidType"); break; default: break; } printf(" %-16s\t%02X-%02X-%02X-%02X-%02X-%02X\t%-11s\n",inet_ntoa(inadTmp), pIpNetTable->table[i].bPhysAddr[0],pIpNetTable->table[i].bPhysAddr[1], pIpNetTable->table[i].bPhysAddr[2],pIpNetTable->table[i].bPhysAddr[3], pIpNetTable->table[i].bPhysAddr[4],pIpNetTable->table[i].bPhysAddr[5], szType); } return TRUE; }