Solved

Enumerating IP Addresses

Posted on 1998-07-28
21
186 Views
Last Modified: 2013-12-03
I'm asking this question again...I really need a way to find out which IP Addresses a windows NT box is connected to.  I know this can be done because netstat outputs a list of them in the first column when invoked with the -rn switch.  Please if you know anything helpful then respond
0
Comment
Question by:openGL
  • 7
  • 5
  • 4
  • +4
21 Comments
 
LVL 1

Expert Comment

by:blwatkins
ID: 1411259
What do you want to check it with, Programming language?
0
 

Author Comment

by:openGL
ID: 1411260
C or C++, obviously

0
 

Author Comment

by:openGL
ID: 1411261
Sorry about the harsh tone btw...
0
 
LVL 6

Expert Comment

by:snoegler
ID: 1411262
I have been searching the API's and the DLL exports of wsock32.dll, and there are some un-
documented functions. But i did not find out how to use them ...
A "dumpbin /imports netstat.exe" told me that it is has some "bound imports" to
wsock32.dll,crtdll.dll,kernel32.dll,ntdll.dll, and the type of these imports is not listed.
To make it short - microsoft seems to use some undocumented functions.
Neither the sockets interface nor the windows networking api gave any information about this.
The only way i see - and to which i do not have the manuals to - could be the NETBIOS interface.

The other way - and it seems to be almost as 'portable' as using undocumented functions -
could be to parse the output of netstat. If you think this is a good answer(grin) i have nothing
against to take the points ;)
0
 
LVL 8

Expert Comment

by:trestan
ID: 1411263
Pls try this function:
The GetAddressByName function lets a client obtain a Windows Sockets address for a network service. The client specifies the service of interest by its service type and service name.
Or do you want sth like that? Pls explain your question in a little more detail.

0
 

Author Comment

by:openGL
ID: 1411264
Parsing the output of netstat is trivial, but is not a workable solution for production software. Many NT boxes do not have a working netstat or have it out of permission range, and doing this is way too slow anyway.  GetAddressByName is basically a souped-up gethostbyname...thanks for the effort but quoting random winsock functions is not going to help.  To make it more clear what I'm looking for, I'm running this program on a NT machine which has about 150 different IP addresses.  All I need is a way to get a list of those addresses via c/C++ code.
0
 
LVL 6

Expert Comment

by:snoegler
ID: 1411265
If the case is to find out which addresses your machine OWNS,
i can answer your question. But if you want to know the open
connections OUTGOING from your machine i do not have a better
answer.
0
 

Author Comment

by:openGL
ID: 1411266
then I guess snoegler can't answer my question
0
 
LVL 7

Expert Comment

by:faster
ID: 1411267
What's wrong with gethostname() and then gethostbyname()?  This is the normal to go.
0
 
LVL 7

Expert Comment

by:faster
ID: 1411268
For example:

LPHOSTENT pHostent;
char szLocalHost[256];

//      get local name
if (gethostname(szLocalHost,256) != SOCKET_ERROR)      
{
//      get local host address
      pHostent = gethostbyname(szLocalHost);

                 // now the pHostent.h_addr_list is the list you need. you can check h_addr_list[0], h_addr_list[1] ... until it becomes null.
}

An alternative way (when the host does not have a name, quite rare), is to creare a socket (UDP will do) to an arbitrary address, then call getsockname(), which also gives you a pointer to the pHostent structure.
0
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 6

Expert Comment

by:snoegler
ID: 1411269
You got that from the knowledge base, don't you?
Perhaps i've done something wrong, but i could only get the list of connected computers in
the LAN, not the connections to the net.
0
 
LVL 4

Expert Comment

by:agreen
ID: 1411270
Please unlock this question. I'll post the right answer.
0
 
LVL 4

Expert Comment

by:agreen
ID: 1411271
The NETSTAT application uses SNMP interfaces to obtain TCP/IP information. The INETMIB1.DLL library exports the TCP/IP SNMP interface on NT, calling into the TCPIP.SYS with IOCTL's that return endpoint information.
0
 
LVL 11

Expert Comment

by:alexo
ID: 1411272
Suggestion #1:
For each of the 64K ports on your local address, create a socket with the address/port, check getpeername() and remove the socket.
0
 
LVL 6

Expert Comment

by:snoegler
ID: 1411273
alexo,
i have tried that with getpeername(), and it does not work - i think i didn't make a mistake.
0
 

Author Comment

by:openGL
ID: 1411274
ok, I'm unlocking this for agreen...I'll try the gethostbyname also however
0
 
LVL 4

Expert Comment

by:agreen
ID: 1411275
:) Just select the "Reopen . . ." radiobutton and press submit :)
I can't post the answer when the question is locked .
0
 

Author Comment

by:openGL
ID: 1411276
OK, it's unlocked! Please, you're my lifeline here...
0
 
LVL 4

Accepted Solution

by:
agreen earned 560 total points
ID: 1411277
There is some documentation on SNMP, which is a general information retrieval interface that is customized by individual information providers (like TCP/IP), in the MSDN Library.

The program below relies on the same SNMP interfaces that netstat uses to obtain TCP/IP information.

#include "windows.h"
#include "stdio.h"
#include "snmp.h"
#include "winsock.h"

#define HOSTNAMELEN 256
#define PORTNAMELEN 256
#define ADDRESSLEN HOSTNAMELEN+PORTNAMELEN

typedef struct _tcpinfo {
        struct _tcpinfo         *prev;
        struct _tcpinfo         *next;
        UINT                            state;
        UINT                            localip;
        UINT                            localport;
        UINT                            remoteip;
        UINT                            remoteport;
} TCPINFO, *PTCPINFO;


BOOL (__stdcall *SnmpExtensionInit)(
    IN  DWORD               dwTimeZeroReference,
    OUT HANDLE              *hPollForTrapEvent,
    OUT AsnObjectIdentifier *supportedView);

BOOL (__stdcall *SnmpExtensionQuery)(
    IN BYTE                   requestType,
    IN OUT RFC1157VarBindList *variableBindings,
    OUT AsnInteger            *errorStatus,
    OUT AsnInteger            *errorIndex);

//
// Possible TCP endpoint states
//
static char TcpState[][32] = {
        "???",
        "CLOSED",
        "LISTENING",
        "SYN_SENT",
        "SEN_RECEIVED",
        "ESTABLISHED",
        "FIN_WAIT",
        "FIN_WAIT2",
        "CLOSE_WAIT",
        "CLOSING",
        "LAST_ACK",
        "TIME_WAIT"
};
       
//
// Lists of endpoints
//
TCPINFO         TcpInfoTable;
TCPINFO         UdpInfoTable;



char *GetPortName( UINT port, char *proto, char *name, int namelen )

{
        struct servent *psrvent;

        if( psrvent = getservbyport( htons( (USHORT) port ), proto )) {

                strcpy( name, psrvent->s_name );

        } else {

                sprintf(name, "%d", port);

        }              
        return name;

}



char *GetIpHostName( BOOL local, UINT ipaddr, char *name, int namelen )

{
        struct hostent                  *phostent;
        UINT                                    nipaddr;

        nipaddr = htonl( ipaddr );
        if( !ipaddr  ) {

                if( !local ) {

                        sprintf( name, "%d.%d.%d.%d",
                                (nipaddr >> 24) & 0xFF,
                                (nipaddr >> 16) & 0xFF,
                                (nipaddr >> 8) & 0xFF,
                                (nipaddr) & 0xFF);

                } else {

                        gethostname(name, namelen);
                }

        } else if( ipaddr == 0x0100007f ) {

                if( local ) {

                        gethostname(name, namelen);
                } else {

                        strcpy( name, "localhost" );
                }

        } else if( phostent = gethostbyaddr( (char *) &ipaddr,
                sizeof( nipaddr ), PF_INET )) {

                strcpy( name, phostent->h_name );

        } else {

                sprintf( name, "%d.%d.%d.%d",
                        (nipaddr >> 24) & 0xFF,
                        (nipaddr >> 16) & 0xFF,
                        (nipaddr >> 8) & 0xFF,
                        (nipaddr) & 0xFF);
        }
        return name;

}



BOOLEAN LoadInetMibEntryPoints()

{
        HINSTANCE       hInetLib;

        if( !(hInetLib = LoadLibrary( "inetmib1.dll" ))) {

                return FALSE;
        }

        if( !(SnmpExtensionInit = (void *) GetProcAddress( hInetLib,
                        "SnmpExtensionInit" )) ) {

                return FALSE;
        }

        if( !(SnmpExtensionQuery = (void *) GetProcAddress( hInetLib,
                        "SnmpExtensionQuery" )) ) {

                return FALSE;
        }
       
        return TRUE;

}



int main( int argc, char *argv[] )

{
        HANDLE                                  hTrapEvent;
        AsnObjectIdentifier             hIdentifier;
        RFC1157VarBindList              bindList;
        RFC1157VarBind                  bindEntry;
        UINT                                    tcpidentifiers[] = { 1,3,6,1,2,1,6,13,1,1};
        UINT                                    udpidentifiers[] = { 1,3,6,1,2,1,7,5,1,1};
        AsnInteger                              errorStatus, errorIndex;
        TCPINFO                                 *currentEntry, *newEntry;
        UINT                                    currentIndex;
        WORD                                    wVersionRequested;
        WSADATA                                 wsaData;
        char                                    localname[HOSTNAMELEN], remotename[HOSTNAMELEN];
        char                                    remoteport[PORTNAMELEN], localport[PORTNAMELEN];
        char                                    localaddr[ADDRESSLEN], remoteaddr[ADDRESSLEN];

        //
        // Initialize winsock
        //
        wVersionRequested = MAKEWORD( 1, 1 );
        if( WSAStartup(  wVersionRequested, &wsaData ) ) {

                printf("Could not initialize Winsock.\n");
                return 1;
        }

        //
        // Locate and initialize INETMIB1
        //
        if( !LoadInetMibEntryPoints()) {

                printf("Could not load extension DLL.\n");
                return 1;
        }

        if( !SnmpExtensionInit( GetCurrentTime(), &hTrapEvent, &hIdentifier )) {

                printf("Could not initialize extension DLL.\n");
                return 1;
        }

        //
        // Initialize the query structure once
        //
        bindEntry.name.idLength = 0xA;
        bindEntry.name.ids = tcpidentifiers;
        bindList.list = &bindEntry;
        bindList.len  = 1;

        TcpInfoTable.prev = &TcpInfoTable;
        TcpInfoTable.next = &TcpInfoTable;

        //
        // Roll through TCP connections
        //
        currentIndex = 1;
        currentEntry = &TcpInfoTable;
        while(1) {

                if( !SnmpExtensionQuery( ASN_RFC1157_GETNEXTREQUEST,
                        &bindList, &errorStatus, &errorIndex )) {

                        return 1;
                }

                //
                // Terminate when we're no longer seeing TCP information
                //
                if( bindEntry.name.idLength < 0xA ) break;

                //
                // Go back to start of table if we're reading info
                // about the next byte
                //
                if( currentIndex != bindEntry.name.ids[9] ) {

                        currentEntry = TcpInfoTable.next;
                        currentIndex = bindEntry.name.ids[9];
                }

                //
                // Build our TCP information table
                //
                switch( bindEntry.name.ids[9] ) {

                case 1:
                       
                        //
                        // Always allocate a new structure
                        //
                        newEntry = (TCPINFO *) malloc( sizeof(TCPINFO ));
                        newEntry->prev = currentEntry;
                        newEntry->next = &TcpInfoTable;
                        currentEntry->next = newEntry;
                        currentEntry = newEntry;

                        currentEntry->state = bindEntry.value.asnValue.number;
                        break;

                case 2:

                        currentEntry->localip =
                                *(UINT *) bindEntry.value.asnValue.address.stream;
                        currentEntry = currentEntry->next;
                        break;

                case 3:
                       
                        currentEntry->localport =
                                bindEntry.value.asnValue.number;
                        currentEntry = currentEntry->next;
                        break;

                case 4:

                        currentEntry->remoteip =
                                *(UINT *) bindEntry.value.asnValue.address.stream;
                        currentEntry = currentEntry->next;
                        break;

                case 5:

                        currentEntry->remoteport =
                                bindEntry.value.asnValue.number;
                        currentEntry = currentEntry->next;
                        break;
                }

        }
       
        //
        // Now print the connection information
        //
        printf("%7s %-30s %-30s %s\n", "Proto", "Local", "Remote", "State" );
        currentEntry = TcpInfoTable.next;
        while( currentEntry != &TcpInfoTable ) {

                sprintf( localaddr, "%s:%s",
                        GetIpHostName( TRUE, currentEntry->localip, localname, HOSTNAMELEN),
                        GetPortName( currentEntry->localport, "tcp", localport, PORTNAMELEN ));

                sprintf( remoteaddr, "%s:%s",
                        GetIpHostName( FALSE, currentEntry->remoteip, remotename, HOSTNAMELEN),
                        currentEntry->remoteip ?
                                GetPortName( currentEntry->remoteport, "tcp", remoteport, PORTNAMELEN ):
                                "0" );

                printf("%7s %-30s %-30s %s\n", "TCP",
                        localaddr, remoteaddr,
                        TcpState[currentEntry->state]);
               
                currentEntry = currentEntry->next;
        }
        printf("\n");

        //
        // Initialize the query structure once
        //
        bindEntry.name.idLength = 0xA;
        bindEntry.name.ids = udpidentifiers;
        bindList.list = &bindEntry;
        bindList.len  = 1;

        UdpInfoTable.prev = &UdpInfoTable;
        UdpInfoTable.next = &UdpInfoTable;

        //
        // Roll through UDP endpoints
        //
        currentIndex = 1;
        currentEntry = &UdpInfoTable;
        while(1) {

                if( !SnmpExtensionQuery( ASN_RFC1157_GETNEXTREQUEST,
                        &bindList, &errorStatus, &errorIndex )) {

                        return 1;
                }

                //
                // Terminate when we're no longer seeing TCP information
                //
                if( bindEntry.name.idLength < 0xA ) break;

                //
                // Go back to start of table if we're reading info
                // about the next byte
                //
                if( currentIndex != bindEntry.name.ids[9] ) {

                        currentEntry = UdpInfoTable.next;
                        currentIndex = bindEntry.name.ids[9];
                }

                //
                // Build our TCP information table
                //
                switch( bindEntry.name.ids[9] ) {

                case 1:
                       
                        //
                        // Always allocate a new structure
                        //
                        newEntry = (TCPINFO *) malloc( sizeof(TCPINFO ));
                        newEntry->prev = currentEntry;
                        newEntry->next = &UdpInfoTable;
                        currentEntry->next = newEntry;
                        currentEntry = newEntry;

                        currentEntry->localip =
                                *(UINT *) bindEntry.value.asnValue.address.stream;
                        break;

                case 2:
                       
                        currentEntry->localport =
                                bindEntry.value.asnValue.number;
                        currentEntry = currentEntry->next;
                        break;
                }
        }
       
        //
        // Now print the connection information
        //
        currentEntry = UdpInfoTable.next;
        while( currentEntry != &UdpInfoTable ) {

                printf("%7s %s:%s\n", "UDP",
                                GetIpHostName( TRUE, currentEntry->localip, localname, HOSTNAMELEN),
                                GetPortName( currentEntry->localport, "udp", localport, PORTNAMELEN ) );
               
                currentEntry = currentEntry->next;
        }
        printf("\n");

}


0
 
LVL 4

Expert Comment

by:agreen
ID: 1411278
This program shows you detailed listings of all TCP and UDP endpoints on your system, including the remote address and state of TCP connections.
0
 

Author Comment

by:openGL
ID: 1411279
This is fine because it lets me filter out only the ip's that are listening on port 80, which is what I wanted to do anyway.  Thanks everyone for your help
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

This article describes how to add a user-defined command button to the Windows 7 Explorer toolbar.  In the previous article (http://www.experts-exchange.com/A_2172.html), we saw how to put the Delete button back there where it belongs.  "Delete" is …
For a while now I'v been searching for a circular progress control, much like the one you get when first starting your Silverlight application. I found a couple that were written in WPF and there were a few written in Silverlight, but all appeared o…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now