Microsoft KB Archive/129315

{|
 * width="100%"|

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.

AF_IPX
You can use this sample to give an IPX address:

Sample Code
  #include    #include    #include 

#include 

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    #include    #include 

#include   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    #include    #include 

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