Q:
WINSOCK库的GetAddressByName 和gethostbyname 返回的信息无法满足我的要求,我想获取更详细的信息,我要知道一切信息,至少要像ipconfig /all 命令输出那样详细, 怎么办?
A:
使用windows SDK提供的IP Helper 库吧,它可以解决你上述的所有要求,使用它,你可以获取或配置本机的TCP/IP( Transmission Control Protocol/Internet Protocol )网络.
它甚至可以帮你发ARP包,你只需要调用SendARP ()这个函数...
Header | Declared in Iphlpapi.h. |
---|---|
Library | Use Iphlpapi.lib. |
下面给出类似ipconfig /all的功能的示例
- #include "stdafx.h"
- #include <winsock2.h>
- #include <ws2tcpip.h>
- #include <windows.h>
- #include <iphlpapi.h>
- #include <comutil.h>
- int IpConfigAll()
- {
- MIB_IPSTATS ipstats;
- GetIpStatistics(&ipstats);
- printf("number of interface: %d/nnumber of address: %d/n",
- ipstats.dwNumIf,ipstats.dwNumAddr);
- PIP_ADAPTER_ADDRESSES AdapterAddresses = NULL;
- ULONG OutBufferLength = 0;
- ULONG RetVal = 0, i;
- int j;
- // The size of the buffer can be different
- // between consecutive API calls.
- // In most cases, i < 2 is sufficient;
- // One call to get the size and one call to get the actual parameters.
- // But if one more interface is added or addresses are added,
- // the call again fails with BUFFER_OVERFLOW.
- // So the number is picked slightly greater than 2.
- // We use i <5 in the example
- for (i = 0; i < 5; i++) {
- RetVal =
- GetAdaptersAddresses(
- AF_INET,
- 0,
- NULL,
- AdapterAddresses,
- &OutBufferLength);
- if (RetVal != ERROR_BUFFER_OVERFLOW) {
- break;
- }
- if (AdapterAddresses != NULL) {
- FREE(AdapterAddresses);
- }
- AdapterAddresses = (PIP_ADAPTER_ADDRESSES)
- MALLOC(OutBufferLength);
- if (AdapterAddresses == NULL) {
- RetVal = GetLastError();
- break;
- }
- }
- if (RetVal == NO_ERROR) {
- // If successful, output some information from the data we received
- PIP_ADAPTER_ADDRESSES AdapterList = AdapterAddresses;
- while (AdapterList) {
- printf("interface(%d:%s) %d %s:/n",
- AdapterList->IfType,
- AdapterList->AdapterName,
- AdapterAddresses->IfIndex,
- (const char*)_bstr_t(AdapterList->FriendlyName));
- printf("/tDescription: %ws/n", AdapterList->Description);
- printf("/tDhcp Enabled: %s/n", AdapterList->Dhcpv4Enabled?"Yes":"No");
- printf("/tOperStatus : %s/n", (AdapterList->OperStatus==IfOperStatusUp)?"Up":"Down");
- printf("/tDnsSuffix: %ws/n", AdapterList->DnsSuffix?AdapterList->DnsSuffix:L"No");
- printf("/tUnicastAddress Address:/n");
- for(PIP_ADAPTER_UNICAST_ADDRESS_LH paddr = AdapterList->FirstUnicastAddress;
- paddr!=NULL;paddr=paddr->Next)
- {
- printf("/t : %s/n",
- inet_ntoa( ((SOCKADDR_IN *)paddr->Address.lpSockaddr)->sin_addr));
- }
- printf("/tAnycastAddress Address:/n");
- for(PIP_ADAPTER_ANYCAST_ADDRESS_XP paddr = AdapterList->FirstAnycastAddress;
- paddr!=NULL;paddr=paddr->Next)
- {
- printf("/t : %s/n",
- inet_ntoa( ((SOCKADDR_IN *)paddr->Address.lpSockaddr)->sin_addr));
- }
- printf("/tMulticast Address:/n");
- for(PIP_ADAPTER_MULTICAST_ADDRESS_XP paddr = AdapterList->FirstMulticastAddress;
- paddr!=NULL;paddr=paddr->Next)
- {
- printf("/t : %s/n",
- inet_ntoa( ((SOCKADDR_IN *)paddr->Address.lpSockaddr)->sin_addr));
- }
- printf("/tDMS server Address:/n");
- for(PIP_ADAPTER_DNS_SERVER_ADDRESS_XP paddr = AdapterList->FirstDnsServerAddress;
- paddr!=NULL;paddr=paddr->Next)
- {
- printf("/t : %s/n",
- inet_ntoa( ((SOCKADDR_IN *)paddr->Address.lpSockaddr)->sin_addr));
- }
- //AdapterList->FirstGatewayAddress only support at vista.
- //
- //Get default gate way from regkey.
- //
- //HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/Tcpip/Parameters/Interfaces
- HKEY hk=NULL;
- WCHAR szSubKey[260] = L"SYSTEM//CurrentControlSet//Services//Tcpip//Parameters//Interfaces//";
- wcscat(szSubKey,_bstr_t(AdapterList->AdapterName));
- RegOpenKey(HKEY_LOCAL_MACHINE,szSubKey,&hk);
- WCHAR szGateWay[255]=L"";
- DWORD dwlen=255;
- DWORD lpType =REG_SZ;
- RegQueryValueEx(hk,L"DefaultGateway",NULL,&lpType,(LPBYTE)szGateWay,&dwlen);
- RegCloseKey(hk);
- printf("/tDMS default gateway:/n");
- printf("/t : %s/n", (const char*)_bstr_t(szGateWay));
- AdapterList = AdapterList->Next;
- }
- }
- else
- {
- LPVOID MsgBuf;
- printf("Call to GetAdaptersAddresses failed./n");
- if (FormatMessage(
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- RetVal,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
- (LPTSTR) &MsgBuf,
- 0,
- NULL )) {
- printf("/tError: %s", MsgBuf);
- }
- LocalFree(MsgBuf);
- }
- if (AdapterAddresses != NULL) {
- FREE(AdapterAddresses);
- }
- //GetNetworkParams(x,x);
- //
- //TODO:
- // Declare and initialize variables.
- //
- DWORD dwSize = 0;
- DWORD dwRetVal = 0;
- //GetIpForwardTable
- //
- //
- dwSize = sizeof(MIB_IPFORWARDTABLE)*(ipstats.dwNumRoutes+ipstats.dwNumIf);
- PMIB_IPFORWARDTABLE pIpForwardTable = (PMIB_IPFORWARDTABLE )MALLOC(dwSize);
- if(GetIpForwardTable(pIpForwardTable,&dwSize,FALSE))
- {
- printf("GetIpForwardTable failed /n");
- FREE(pIpForwardTable);
- return 1;
- }
- for(i=0;i<pIpForwardTable->dwNumEntries;i++)
- {
- IN_ADDR inaddr;
- inaddr.S_un.S_addr= pIpForwardTable->table[i].dwForwardDest;
- printf("%X %s/n", pIpForwardTable->table[i].dwForwardIfIndex,
- inet_ntoa(inaddr));
- }
- FREE(pIpForwardTable);
- /* variables used for GetIfTable and GetIfEntry */
- MIB_IFTABLE *pIfTable;
- MIB_IFROW *pIfRow;
- // Allocate memory for our pointers.
- pIfTable = (MIB_IFTABLE *) MALLOC(sizeof (MIB_IFTABLE));
- if (pIfTable == NULL) {
- printf("Error allocating memory needed to call GetIfTable/n");
- return 1;
- }
- // Make an initial call to GetIfTable to get the
- // necessary size into dwSize
- dwSize = sizeof (MIB_IFTABLE);
- if (GetIfTable(pIfTable, &dwSize, FALSE) == ERROR_INSUFFICIENT_BUFFER) {
- FREE(pIfTable);
- pIfTable = (MIB_IFTABLE *) MALLOC(dwSize);
- if (pIfTable == NULL) {
- printf("Error allocating memory needed to call GetIfTable/n");
- return 1;
- }
- }
- // Make a second call to GetIfTable to get the actual
- // data we want.
- if ((dwRetVal = GetIfTable(pIfTable, &dwSize, FALSE)) == NO_ERROR) {
- printf("/tNum Entries: %ld/n/n", pIfTable->dwNumEntries);
- for (i = 0; i < (int) pIfTable->dwNumEntries; i++) {
- pIfRow = (MIB_IFROW *) & pIfTable->table[i];
- printf("/tIndex[%d]:/t %ld/n", i, pIfRow->dwIndex);
- printf("/tInterfaceName[%d]:/t %ws", i, pIfRow->wszName);
- printf("/n");
- printf("/tDescription[%d]:/t ", i);
- for (j = 0; j < (int) pIfRow->dwDescrLen; j++)
- printf("%c", pIfRow->bDescr[j]);
- printf("/n");
- printf("/tType[%d]:/t ", i);
- switch (pIfRow->dwType) {
- case IF_TYPE_OTHER:
- printf("Other/n");
- break;
- case IF_TYPE_ETHERNET_CSMACD:
- printf("Ethernet/n");
- break;
- case IF_TYPE_ISO88025_TOKENRING:
- printf("Token Ring/n");
- break;
- case IF_TYPE_PPP:
- printf("PPP/n");
- break;
- case IF_TYPE_SOFTWARE_LOOPBACK:
- printf("Software Lookback/n");
- break;
- case IF_TYPE_ATM:
- printf("ATM/n");
- break;
- case IF_TYPE_IEEE80211:
- printf("IEEE 802.11 Wireless/n");
- break;
- case IF_TYPE_TUNNEL:
- printf("Tunnel type encapsulation/n");
- break;
- case IF_TYPE_IEEE1394:
- printf("IEEE 1394 Firewire/n");
- break;
- default:
- printf("Unknown type %ld/n", pIfRow->dwType);
- break;
- }
- printf("/tMtu[%d]:/t/t %ld/n", i, pIfRow->dwMtu);
- printf("/tSpeed[%d]:/t %ld/n", i, pIfRow->dwSpeed);
- printf("/tPhysical Addr:/t ");
- if (pIfRow->dwPhysAddrLen == 0)
- printf("/n");
- for (j = 0; j < (int) pIfRow->dwPhysAddrLen; j++) {
- if (j == (pIfRow->dwPhysAddrLen - 1))
- printf("%.2X/n", (int) pIfRow->bPhysAddr[j]);
- else
- printf("%.2X-", (int) pIfRow->bPhysAddr[j]);
- }
- printf("/tAdmin Status[%d]:/t %ld/n", i, pIfRow->dwAdminStatus);
- printf("/tOper Status[%d]:/t ", i);
- switch (pIfRow->dwOperStatus) {
- case IF_OPER_STATUS_NON_OPERATIONAL:
- printf("Non Operational/n");
- break;
- case IF_OPER_STATUS_UNREACHABLE:
- printf("Unreasonable/n");
- break;
- case IF_OPER_STATUS_DISCONNECTED:
- printf("Disconnected/n");
- break;
- case IF_OPER_STATUS_CONNECTING:
- printf("Connecting/n");
- break;
- case IF_OPER_STATUS_CONNECTED:
- printf("Connected/n");
- break;
- case IF_OPER_STATUS_OPERATIONAL:
- printf("Operational/n");
- break;
- default:
- printf("Unknown status %ld/n", pIfRow->dwAdminStatus);
- break;
- }
- printf("/n");
- }
- } else {
- printf("GetIfTable failed with error: /n", dwRetVal);
- if (pIfTable != NULL) {
- FREE(pIfTable);
- pIfTable = NULL;
- }
- return 1;
- // Here you can use FormatMessage to find out why
- // it failed.
- }
- if (pIfTable != NULL) {
- FREE(pIfTable);
- pIfTable = NULL;
- }
- //GetInterfaceInfo
- //
- //TODO:
- return 0;
- }
- int _tmain(int argc, _TCHAR* argv[])
- {
- IpConfigAll();
- return 0;
- }