HOWTO: Use Winsock to Enumerate Addresses
ID: 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 kbNTOS350 kbNTOS351 kbSDKPlatform kbWinsock kbGrpNet
Version : :3.5,3.51
Platform :
Issue type : kbhowto