Blog of Lei Shen

Blog of Lei Shen header image 2

GetExtendedTCPTable

April 16th, 2008 · No Comments

It is tricky to use GetExtendedTCPTable since somehow the iphlpapi.h is somehow not insync with what doc was saying.  So most likely you will get an error like unable to find GetExtendedTCPTable.

Here is what you need to do:

1) Define couple essential structures and function definitions yourself

2) Get the GetExtendedTCPTable by using GetProcAddress to avoid the link problem (the lib does not contain the new function yet)

Here is an example:

In the iphlpapi_2.h

#include <Iprtrmib.h>

char* g_mibTCPState[] =  {
 ”???”,
 ”MIB_TCP_STATE_CLOSED”,
 ”MIB_TCP_STATE_LISTEN”,
 ”MIB_TCP_STATE_SYN_SENT”,
 ”MIB_TCP_STATE_SYN_RCVD”,
 ”MIB_TCP_STATE_ESTAB”,
 ”MIB_TCP_STATE_FIN_WAIT1″,
 ”MIB_TCP_STATE_FIN_WAIT2″,
 ”MIB_TCP_STATE_CLOSE_WAIT”,
 ”MIB_TCP_STATE_CLOSING”,
 ”MIB_TCP_STATE_LAST_ACK”,
 ”MIB_TCP_STATE_TIME_WAIT”,
 ”MIB_TCP_STATE_DELETE_TCB” };

typedef enum {
  TCP_TABLE_BASIC_LISTENER,
  TCP_TABLE_BASIC_CONNECTIONS,
  TCP_TABLE_BASIC_ALL,
  TCP_TABLE_OWNER_PID_LISTENER,
  TCP_TABLE_OWNER_PID_CONNECTIONS,
  TCP_TABLE_OWNER_PID_ALL,
  TCP_TABLE_OWNER_MODULE_LISTENER,
  TCP_TABLE_OWNER_MODULE_CONNECTIONS,
  TCP_TABLE_OWNER_MODULE_ALL
} TCP_TABLE_CLASS, *PTCP_TABLE_CLASS;
typedef struct _MIB_TCPROW_OWNER_PID { 
 DWORD dwState; 
 DWORD dwLocalAddr; 
 DWORD dwLocalPort; 
 DWORD dwRemoteAddr; 
 DWORD dwRemotePort; 
 DWORD dwOwningPid;
} MIB_TCPROW_OWNER_PID,  *PMIB_TCPROW_OWNER_PID;

typedef struct { 
 DWORD dwNumEntries; 
 MIB_TCPROW_OWNER_PID table[ANY_SIZE];
} MIB_TCPTABLE_OWNER_PID,  *PMIB_TCPTABLE_OWNER_PID;
//This is really by try and error to figure out it should be 16
#define TCPIP_OWNING_MODULE_SIZE 16
typedef struct _MIB_TCPROW_OWNER_MODULE { 
 DWORD dwState; 
 DWORD dwLocalAddr; 
 DWORD dwLocalPort; 
 DWORD dwRemoteAddr; 
 DWORD dwRemotePort; 
 DWORD dwOwningPid; 
 LARGE_INTEGER liCreateTimestamp; 
 ULONGLONG OwningModuleInfo[TCPIP_OWNING_MODULE_SIZE];
} MIB_TCPROW_OWNER_MODULE,  *PMIB_TCPROW_OWNER_MODULE;

typedef struct { 
 DWORD dwNumEntries; 
 MIB_TCPROW_OWNER_MODULE table[ANY_SIZE];
} MIB_TCPTABLE_OWNER_MODULE,  *PMIB_TCPTABLE_OWNER_MODULE;
DWORD (WINAPI *pGetExtendedTcpTable)(
  PVOID pTcpTable,
  PDWORD pdwSize,
  BOOL bOrder,
  ULONG ulAf,
  TCP_TABLE_CLASS TableClass,
  ULONG Reserved
);

The in the main function:
#define WIN32_LEAN_AND_MEAN

#include <stdio.h>
#include <windows.h>
#include <winsock2.h>
#include <malloc.h>
#include <iphlpapi.h>
#include “iphlpapi_2.h”
BOOL initFunctions(){
 pGetExtendedTcpTable =
  (DWORD (WINAPI *)(PVOID,PDWORD,BOOL,ULONG,TCP_TABLE_CLASS,ULONG))
    GetProcAddress(LoadLibrary( “iphlpapi.dll”), “GetExtendedTcpTable”);
 if(pGetExtendedTcpTable == NULL) return FALSE;
 return TRUE;

}

int main(int argc, char* argv[])
{
 if(!initFunctions()){
  printf(”Needed to have XP SP2, Vista SP1 or Server 2003 SP1 and above\n”);
  return 1;
 }

 PVOID pTCPTable = NULL;
 DWORD size = 0;
 DWORD result = 0;
 result = pGetExtendedTcpTable(NULL, &size, true, AF_INET, TCP_TABLE_OWNER_MODULE_ALL, 0);
 while(result == ERROR_INSUFFICIENT_BUFFER){
  if(pTCPTable != NULL){
   free(pTCPTable);
  }
  pTCPTable = malloc(size);
  result = pGetExtendedTcpTable(pTCPTable, &size, true, AF_INET, TCP_TABLE_OWNER_MODULE_ALL, 0);
  if(result != NO_ERROR){
   printf(”Failed to get TCP Table %s\n”, GetLastError());
   free(pTCPTable);
   return 1;
  }
 }
 if(result != NO_ERROR){
  printf(”Failed to get size estimation %s\n”, GetLastError());
  return 1;
 }

 printf(”Total of %d Entries\n”, ((PMIB_TCPTABLE_OWNER_MODULE)pTCPTable)->dwNumEntries);
 for(DWORD i = 0; i < ((PMIB_TCPTABLE_OWNER_MODULE)pTCPTable)->dwNumEntries; i++){
  MIB_TCPROW_OWNER_MODULE module = ((PMIB_TCPTABLE_OWNER_MODULE)pTCPTable)->table[i];
  printf(”PID = %d, “, module.dwOwningPid);
  printf(”State = %s\n “, g_mibTCPState[module.dwState]);
  printf(”    LocalAddress = %d.%d.%d.%d, “,
      (htonl(module.dwLocalAddr) >> 24) & 0xFF,
      (htonl(module.dwLocalAddr) >> 16) & 0xFF,
      (htonl(module.dwLocalAddr) >> 8) & 0xFF,
      (htonl(module.dwLocalAddr)) & 0xFF);
  printf(”LocalPort = %u,\n “, htons((short)module.dwLocalPort));
  if(module.dwState != MIB_TCP_STATE_LISTEN){
   printf(”    RemoteAddress = %d.%d.%d.%d, “,
       (htonl(module.dwRemoteAddr) >> 24) & 0xFF,
       (htonl(module.dwRemoteAddr) >> 16) & 0xFF,
       (htonl(module.dwRemoteAddr) >> 8) & 0xFF,
       (htonl(module.dwRemoteAddr)) & 0xFF);
   printf(”RemotePort = %u\n “, htons((short)module.dwRemotePort));
  }
  printf(”    TimeStamp = %I64d, “, module.liCreateTimestamp);
  printf(”    ULONGLONG = UnDocumentedMeaning\n”);
  printf(”\n”);
 }
 

 if(pTCPTable != NULL) {
  free(pTCPTable);
 }
 return 0;
}

Tags: Technical

0 responses so far ↓

  • There are no comments yet...Kick things off by filling out the form below.

You must log in to post a comment.