HOWTO: Use Winsock to Enumerate Addresses |
Q129315
The information in this article applies to:
- Microsoft Win32 Software Development Kit (SDK) for Windows NT, versions 3.5, 3.51
SUMMARY
Winsock offers several ways to obtain addressing information for TCP/IP-based machines. This article demonstrates how to obtain address information for IPX and NetBIOS under Windows NT.
MORE INFORMATION
Method One
AF_IPX
You can use this sample to give an IPX address:
Sample Code
#include <winsock.h> #include <wsipx.h> #include <wsnwlink.h> #include <stdio.h> void main() { WSADATA wsaData; int cAdapters, res, cbOpt = sizeof( cAdapters ), cbAddr = sizeof( SOCKADDR_IPX ); SOCKET s; SOCKADDR_IPX Addr; if (WSAStartup(0x0101, &wsaData)) { printf("WSAStartup failed %s\n", WSAGetLastError()); return; } // Create IPX socket. s = socket( AF_IPX, SOCK_DGRAM, NSPROTO_IPX ); if(s==INVALID_SOCKET) printf("Error: %u\n", WSAGetLastError()); // Socket must be bound prior to calling IPX_MAX_ADAPTER_NUM. memset( &Addr, 0, sizeof( Addr )); Addr.sa_family = AF_IPX; res = bind( s, (SOCKADDR*) &Addr, cbAddr); if(res != 0) printf("Error: %u\n", WSAGetLastError()); // Get the number of adapters => cAdapters. res = getsockopt( (SOCKET) s, NSPROTO_IPX, IPX_MAX_ADAPTER_NUM, (char *) &cAdapters, &cbOpt ); if(res != 0) printf("Error: %u\n", WSAGetLastError()); // At this point cAdapters is the number of installed adapters. while ( cAdapters > 0 ) { IPX_ADDRESS_DATA IpxData; memset( &IpxData, 0, sizeof(IpxData)); // Specify which adapter to check. IpxData.adapternum = cAdapters - 1; cbOpt = sizeof( IpxData ); // Get information for the current adapter. res = getsockopt( s, NSPROTO_IPX, IPX_ADDRESS, (char*) &IpxData, &cbOpt ); if(res != 0) printf("Error: %u\n", WSAGetLastError()); else { // IpxData contains the address for the current adapter. int i; printf("Net Number: "); for (i=0;i<4;i++) printf("%02X",IpxData.netnum[i]); printf("\n"); printf("Node Address: "); for (i=0;i<5;i++) printf("%02X-",IpxData.nodenum[i]); printf("%02X\n",IpxData.nodenum[i]); } cAdapters--; } WSACleanup(); return; }
AF_NETBIOS
The following sample uses the EnumProtocols() function to give lana numbers for the available NetBIOS transports. Additionally, under Winsock2, the function WSAEnumProtocols() replaces EnumProtocols(); it returns the same information as before, but also includes additional information. With both functions, the key is to take the absolute value of the iProtocol field of either the PROTOCOL_INFO or WSAPROTOCOL_INFO structure, which is the LANA number for that transport.
The PROTOCOL_INFO structure is returned by EnumProtocols(), while WSAEnumProtocols() uses the WSAPROTOCOL_INFO structure. This enumeration does not work under Windows NT 3.5 because of a bug in EnumProtocols(). Winsock 2 is available on Windows NT 4.0 or later.
NOTE: Winsock 2 is also available for Windows 95 and its functionality is built in to Windows 98.
Lastly, the iProtocol value for the transport corresponding to LANA 0 will be 0x80000000. The reason for this is protocol 0 is reserved for internal use.
Sample Code
#include <windows.h> #include <assert.h> #include <nspapi.h> #include <stdio.h> void main() { DWORD cb = 0; PROTOCOL_INFO *pPI; BOOL pfLanas[100]; int iRes, nLanas = sizeof(pfLanas) / sizeof(BOOL); // Specify NULL for lpiProtocols to enumerate all protocols. // First, determine the output buffer size. iRes = EnumProtocols( NULL, NULL, &cb ); // Verify that the expected error was received. assert( iRes == -1 && GetLastError() == ERROR_INSUFFICIENT_BUFFER ); if (!cb) { printf( "No available NetBIOS transports.\n"); return; } // Allocate a buffer of the specified size. pPI = (PROTOCOL_INFO*) malloc( cb ); // Enumerate all protocols. iRes = EnumProtocols( NULL, pPI, &cb ); // EnumProtocols() lists each lana number twice, once for // SOCK_DGRAM and once for SOCK_SEQPACKET. Set a flag in pfLanas // so unique lanas can be identified. memset( pfLanas, 0, sizeof( pfLanas )); while (iRes > 0) { // Scan protocols looking for AF_NETBIOS. if ( pPI[--iRes].iAddressFamily == AF_NETBIOS ) // Found one. pfLanas[ abs(pPI[iRes].iProtocol) ] = TRUE; } printf( "Available NetBIOS lana numbers: " ); while( nLanas-- ) if ( pfLanas[nLanas] ) printf( "%d ", nLanas ); printf( "\n" ); free( pPI ); return; }
AF_APPLETALK
Address enumeration is not meaningful for AF_APPLETALK. On a multi-homed host with routing disabled, only the default adapter is used. If routing is enabled, a single AppleTalk address is used for all installed network adapters.
Method Two
Listed below is an example of how to use the WinSock database APIs to give IP addresses:
Sample Code
#include <windows.h> #include <winsock.h> #include <stdio.h> void main() { WSADATA wsaData; char szHostname[100]; HOSTENT *pHostEnt; int nAdapter = 0; struct sockaddr_in sAddr; if (WSAStartup(0x0101, &wsaData)) { printf("WSAStartup failed %s\n", WSAGetLastError()); return; } gethostname( szHostname, sizeof( szHostname )); pHostEnt = gethostbyname( szHostname ); while ( pHostEnt->h_addr_list[nAdapter] ) { // pHostEnt->h_addr_list[nAdapter] is the current address in host // order. // Copy the address information from the pHostEnt to a sockaddr_in // structure. memcpy ( &sAddr.sin_addr.s_addr, pHostEnt->h_addr_list[nAdapter], pHostEnt->h_length); // Output the machines IP Address. printf("Name: %s\nAddress: %s\n", pHostEnt->h_name, inet_ntoa(sAddr.sin_addr)); nAdapter++; } WSACleanup(); return; }
Additional query words:
Keywords : kbnetwork kbAPI kbNetBIOS kbOSWinNT350 kbOSWinNT351 kbSDKPlatform kbWinsock kbGrpDSNet
Issue type : kbhowto
Technology : kbWin32SDKSearch kbAudDeveloper kbSDKSearch kbWin32sSearch kbWin32SDKNT350 kbWin32SDKNT351
Last Reviewed: October 17, 1999 |