1、关于默认网关的监测,通常情况下 使用 route PRINT -4 可以获取到默认网关,如果您有多个网卡且都连接到了路由 您会发现 有多个默认网关。而跳跃点数则是优先级。数字越小 优先级越高。
static void getIpAddressByIndex(DWORD ifIndex, char * ip) { DWORD dwSize = 0, i =0; if(ERROR_INSUFFICIENT_BUFFER == GetIpAddrTable(NULL, &dwSize,TRUE)) { PMIB_IPADDRTABLE pIPAddrTable = (PMIB_IPADDRTABLE)GlobalAlloc(GPTR, dwSize); if(GetIpAddrTable(pIPAddrTable, &dwSize, FALSE) == NO_ERROR) { for(i =0; i < pIPAddrTable->dwNumEntries; i++) { if(ifIndex == pIPAddrTable->table[i].dwIndex) { struct in_addr gateway; gateway.s_addr = pIPAddrTable->table[i].dwAddr; if(NULL != ip) strcpy(ip, inet_ntoa(gateway)); } } } GlobalFree(pIPAddrTable); } } /* 获取默认网关IP地址, 以及最近的网络接口索引. 返回值: 成功返回 真, 失败返回假 */ BOOL GetDefaultGateWay(char * sGateWay, char * ipAddress) { PMIB_IPFORWARDTABLE pIpRouteTable = NULL; DWORD dwActualSize = 0, i = 0, mIfIndex = 0; if(ERROR_INSUFFICIENT_BUFFER == GetIpForwardTable(pIpRouteTable, &dwActualSize,TRUE)) { pIpRouteTable = (PMIB_IPFORWARDTABLE)GlobalAlloc(GPTR, dwActualSize); if(GetIpForwardTable(pIpRouteTable, &dwActualSize, TRUE) == NO_ERROR) { DWORD MinMetric = 0x7FFFFFFF, tableIndex = 0; MIB_IPFORWARDROW * table = NULL; // 遍历 查找跳跃点数最小的默认网关. for (i = 0; i < pIpRouteTable->dwNumEntries; i++) { DWORD dwCurrIndex = pIpRouteTable->table[i].dwForwardIfIndex; if(0x00 == pIpRouteTable->table[i].dwForwardMask && 0x00 == pIpRouteTable->table[i].dwForwardDest && pIpRouteTable->table[i].dwForwardProto == 3) { if(pIpRouteTable->table[i].dwForwardMetric1 < MinMetric) { MinMetric = pIpRouteTable->table[i].dwForwardMetric1; tableIndex = i; } } } if(0x7FFFFFFF != MinMetric) { struct in_addr gateway; table = &pIpRouteTable->table[tableIndex]; gateway.s_addr = table->dwForwardNextHop; if(NULL != sGateWay) strcpy(sGateWay, inet_ntoa(gateway)); if(NULL != ipAddress) getIpAddressByIndex(table->dwForwardIfIndex, ipAddress); GlobalFree(pIpRouteTable); return TRUE; } } GlobalFree(pIpRouteTable); } return FALSE; }
得到网关地址了。接下来可以使用SendARP 函数来获取MAC地址。
static void CheckGateWayMac(client_config_t * _cfg) { unsigned char gateway_mac[6]={0}; ULONG ulen=6; IPAddr destIP=inet_addr(_cfg->gateway); if(NO_ERROR==SendARP(destIP, NULL, (PULONG)gateway_mac, &ulen)) { sprintf(_cfg->gateway_mac, "%02X:%02X:%02X:%02X:%02X:%02X", gateway_mac[0],gateway_mac[1],gateway_mac[2],gateway_mac[3],gateway_mac[4],gateway_mac[5]); update_networkenv(FALSE); } }
有本地IP地址了。可以通过遍历网卡来获取本机MAC。 待续。
BOOL getAdapterInfo() { ULONG cbBuf = 0; PIP_ADAPTER_INFO pAdapter = NULL; PIP_ADAPTER_INFO pMemory = NULL; DWORD dwResult = 0; DWORD ifIndex = 0; char m_gateway[17], m_ipaddress[17]; // 这里是检测网关. if(FALSE == GetDefaultGateWay(m_gateway, m_ipaddress, &ifIndex)) { return FALSE; } if(SOCKET_ERROR != gethostname(_cfg.host_name, MAX_HOSTNAME_LEN)) { //成功 dwResult = GetAdaptersInfo(NULL, &cbBuf); if(ERROR_BUFFER_OVERFLOW == dwResult) { pMemory = pAdapter = (PIP_ADAPTER_INFO) malloc(cbBuf > sizeof(IP_ADAPTER_INFO)? cbBuf: sizeof(IP_ADAPTER_INFO)); if(NO_ERROR == GetAdaptersInfo(pAdapter, &cbBuf)) { while (pAdapter) { if(ifIndex == pAdapter->Index) { //找到了网卡接口MAC sprintf(_cfg.mac_address,"%02X:%02X:%02X:%02X:%02X:%02X", pAdapter->Address[0],pAdapter->Address[1],pAdapter->Address[2],pAdapter->Address[3],pAdapter->Address[4],pAdapter->Address[5]); // 保存网关和IP地址到配置文件. strcpy(_cfg.gateway, m_gateway); strcpy(_cfg.ip_address, m_ipaddress); CheckGateWayMac(&_cfg); // 获取网关MAC free(pMemory); return TRUE; } pAdapter = pAdapter->Next; } free(pMemory); } } return FALSE; }else{ printf("ERROR:%d\n",GetLastError()); } return FALSE; }