Introduction

The main purpose of this library is to watch the UDP/TCP connections that are active ( like netstat does ) on your PC; it is mainly a wrapper to the IpHelperApi.dll, and it implements 4 generic functions that get statistics about TCP and UDP connections (GetUdpStats()/GetTcpStats()) and also get the tables for UDP and TCP connections (GetUdpConnexions() / GetTcpConnexions()).

It also implements 2 undocumented functions of the IpHelperApi.dll that are similar to GetUdpConnexions/GetTcpConnexions except that they get the processID attached to the connection; in the Win 32 API they are named : AllocateAndGetTcpExTableFromStack and AllocateAndGetUdpExTableFromStack.

Wrapping the IpHlpAPI.dll

The library is named IPHelper and it is just a wrapper to IpHelperAPI.dll using P/Invoke mechanism of the .NET framework In the IPHlpAPI32.cs file are all the declarations of the functions and structs from the IPHlpApi.dll; it uses standard attributes from the System.Runtime.InteropServices namespace.

The SetLastError=true flag allow us to get info about any errors raised in the P/Invoke mechanism, usually the error code is returned by the API function but this code is not very self-explanatory so I included a function to get the message description using the FormatMessage function of the kernell32.dll :

This function just gets a message description from the system and if no description is found it returns "none".

In the MSDN docs all the iphlpapi functions fill their own structure using passed in arguments; for simple structures without array, pointer or nested structure, it is very easy to get the structure correctly filled, but for complex structures it could become much harder.

Let's see how to do that :

Getting the results from the API call

Simple structure Wrapping

First let see how to get the result for a simple function : GetTcpStats(), this function is used to get several info about the TCP connections like, the number of active connections.

The GetTcpTable function takes three params, a pointer to the structure that will hold the results, the size of the buffer pointed to by the pTcpTable parameter (note that if the buffer is too small, on output the function sets this parameter equal to the required buffer size), and a bool flag to tell if we want the results to be sorted or not

The main problem here is that we can't use direct marshalling for those 2 structures because there is a undefined size array, but there are several solutions to solve this issue, I choose to use a simple generic method, replace the first param by a byte array.

Then we have to use this function in the IPHelper class in the GetTcpConnexion member method.

The first thing to do is to get the size of the buffer (pTcpTable) that we need to get all the results, this is done by calling the function with a dumb buffer, the function will then return the size of the necessary buffer in the pdwSize param; note that is possible because the function has been declared with the out keyword before the pdwSize param :

That's it we have a structure called TcpConnexion that holds all the active connections.

Note that we had to convert local and remote port form a DWORD (UInt32) to an Int16 which is done with bitwise operator. The GetUdpConnexion() works exactly in the same way.

IpHelperApi Undocumented functions

The GetTcpConnexion() and GetUdpConnexion() functions are useful, but they can't be used to control the active connections, that means that we can't close any connections or even get more info of which software is using this connection. To be able to get control over the connection means that we have to know which process is attached to it, but those two functions are only available on windows XP.

After several days of seeking a way to get the processId attached to a connection I found that the ipHlpApi has some undocumented functions : AllocateAndGetTcpExTableFromStack and AllocateAndGetUdpExTableFromStack - those two functions are acting exactly the same way that GetTcpTable and GetUdpTable except that they get the processID attached to the connection, don't ask why they are not documented on MSDN, I really don't know.

So here is how to use them, let's see how AllocateAndGetTcpExTableFromStack (AllocateAndGetUdpExTableFromStack works in the same way) is declared in C++

The first param is a pointer on the structure that holds the result, the 2nd param is a bool flag to order the result, the 3rd is a pointer to the heap of the process and the two others are flags that I don't know the meaning of.

This function follows the same pattern of GetTcpTable and the results are stored in a structure that have an undefined size array. I used a solution lightly different to implement this in C# than I used for GetTcpTable : The safe C# version of pointer.

Don't be afraid it is not so scary for those who are not familiar with Pointer let's (briefly) what it is about.

A Pointer is a data structure that store a memory address, for example if you have an integer that holds the number "100", a pointer on this integer will store the address of the value "100" and not the value itself, hope its clear.

To use it I will basically follow the same path that I used for GetTcpTable : call the function first time to get the number of connections (row) and so to get the correct buffer size, and then call the function a second time to get the correct results.

So we have to pass an IntPtr to the function, the 1st thing to do is to define an IntPtr that points to a memory space large enough to store all the result, so, as I said, we have to allocate an arbitrary memory space to call the function a 1st time, then we can get the number of connections with : int NumEntries = (int)Marshal.ReadIntPtr(lpTable); here we are using a function from the Marshal class to read the value pointed by a pointer; finally don't forget to free to memory previously allocated to avoid memory leaks.

Now let's get all the data :

///////////////////
// calculate the real buffer size nb of entrie *
// size of the struct for each entrie(24) + the dwNumEntries
BufferSize = (NumEntries*rowsize)+4;
// make the struct to hold the resullts
TcpExConnexions = new IpHlpApidotnet.MIB_EXTCPTABLE();
// Allocate memory
lpTable = Marshal.AllocHGlobal(BufferSize);
res = IPHlpAPI32Wrapper.AllocateAndGetTcpExTableFromStack(
ref lpTable, true,IPHlpAPI32Wrapper.GetProcessHeap() ,0,2);
if(res!=NO_ERROR)
{
Debug.WriteLine("Erreur : "+
IPHlpAPI32Wrapper.GetAPIErrorMessageDescription(res)+
" "+res);
return; // Error. You should handle it
}
// New pointer of iterating throught the data
IntPtr current = lpTable;
CurrentIndex = 0;
// get the (again) the number of entries
NumEntries = (int)Marshal.ReadIntPtr(current);
TcpExConnexions.dwNumEntries = NumEntries;
// Make the array of entries
TcpExConnexions.table = new MIB_EXTCPROW[NumEntries];
// iterate the pointer of 4 (the size of the DWORD dwNumEntries)
CurrentIndex+=4;
current = (IntPtr)((int)current+CurrentIndex);
// for each entries
for(int i=0; i< NumEntries;i++)
{
// The state of the connexion (in string)
TcpExConnexions.table[i].StrgState =
this.convert_state((int)Marshal.ReadIntPtr(current));
// The state of the connexion (in ID)
TcpExConnexions.table[i].iState = (int)Marshal.ReadIntPtr(current);
// iterate the pointer of 4
current = (IntPtr)((int)current+4);
// get the local address of the connexion
UInt32 localAddr = (UInt32)Marshal.ReadIntPtr(current);
// iterate the pointer of 4
current = (IntPtr)((int)current+4);
// get the local port of the connexion
UInt32 localPort = (UInt32)Marshal.ReadIntPtr(current);
// iterate the pointer of 4
current = (IntPtr)((int)current+4);
// Store the local endpoint in the struct and
// convert the port in decimal (ie convert_Port())
TcpExConnexions.table[i].Local = new IPEndPoint(localAddr,
(int)convert_Port(localPort));
// get the remote address of the connexion
UInt32 RemoteAddr = (UInt32)Marshal.ReadIntPtr(current);
// iterate the pointer of 4
current = (IntPtr)((int)current+4);
UInt32 RemotePort=0;
// if the remote address = 0 (0.0.0.0) the remote port is always 0
// else get the remote port
if(RemoteAddr!=0)
{
RemotePort = (UInt32)Marshal.ReadIntPtr(current);
RemotePort=convert_Port(RemotePort);
}
current = (IntPtr)((int)current+4);
// store the remote endpoint in the struct and
// convert the port in decimal (ie convert_Port())
TcpExConnexions.table[i].Remote = new IPEndPoint(
RemoteAddr,(int)RemotePort);
// store the process ID
TcpExConnexions.table[i].dwProcessId =
(int)Marshal.ReadIntPtr(current);
// Store and get the process name in the struct
TcpExConnexions.table[i].ProcessName =
this.get_process_name(TcpExConnexions.table[i].dwProcessId);
current = (IntPtr)((int)current+4);
}
// free the buffer
Marshal.FreeHGlobal(lpTable);
// re init the pointer
current = IntPtr.Zero;

So we call again the function with the right buffer size, and then we will "navigate" in the memory with the beginning of the allocated memory as the starting address.

The 1st 4 bytes are the number of entries, then we enter in a loop for each row in the connection table that begins at the starting address + 4 , in the 1st loop we will have the same mechanism : get each value ordered like in the MIB_TCPROW_EX, and for each value iterate the pointer by 4, do this as many time as the number of rows.

That's it, we have all the connection AND the process ID attached to it, I added a few helper functions that, for example, get the process name by giving the process ID, but they are pretty simple and self-explanatory.

Remember those 2 functions are only available under WinXP.

How to use the library

I wrote a little app to test the lib, it just shows the results of all the functions in the library, in a listview.

Here are the methods of the lib :

GetTcpStats() fill a MIB_TCPSTATS structure

GetUdpStats() fill a MIB_UDPSTATS structure

GetTcpConnexions() fill a MIB_TCPTABLE structure

GetUdpConnexions() fill a MIB_UDPTABLE structure

GetExTcpConnexions() fill a MIB_EXTCPTABLE structure

GetExUdpConnexions() fill a MIB_EXUDPTABLE structure

That's it, hope it will be useful.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

Dear sir,
I have used this code and am getting some of the TCP sockets in CLOSE_WAIT state.Please sir,tell me the way to close that particular sockets which is in the state of CLOSE_WAIT .So i need to close the sockets which is showing CLOSE_WAIT command without using close() default function. (Need close method definition)

I want limit each connection that use INTERNET. I have code that throttle one connection [whit the help of this Bandwidth throttling[^]], but my question is how to intercept the connections and limit the use of bandwidth in each connection bee found.

LAN To LAN
i have 2 program which using udp technology for both send program and receive program.This two program work very well on LAN connection means both sender and receiver is in same connection.On lan setting i used port 11000 and ip is a fixed ip.

Lan to Outside world
But when i try it on the internet with same port for lan setting,sender is in private network(lan) and i try to send msg to receiver(outside world) where receiver is using dynamic ip address(behind router) it seems the destination pc cannot receive any message from the udp sender.

I'm sure there is no firewall blocking.i already tried winsock still cannot.i was not allowed to do NAT also not allowed to do DYNDNS. Anyone who have better solution please help me i'm working with this problem for 6 month

This is really a wonderful article. Thanks a bunch. I am just wondering how to get this information on a remote box. I mean, given an IP address, it need to get TCP and UDP table of the remote system. Is there any way of doing this? Please suggest.

possible(i can get) on this dll:
-remote port
-remote address
-local port
-local address
-process id
-process name
---how about process path??... my purpose is to get the crc of that process i need the path of it..

Whilst this is a lot simpler and also faster than using iphlpapi.dll there is no way to retrieve the process and the pid associated with that connection - afaik anyway. If thats not the case, please enlighten me as that functionality fully managed and as simple as possible ofc, is what I'm looking for ^^

I compared the connection obtained from your code (i.e. from TCP Tables) and found out that it does not return every connection opened.
I check with Ethereal and apparently there are some ports "conversation" in Ethereal which is not listed by the Tcp Table.

The last parameter in the AllocateAndGetTcpExTableFromStack is the Address Family. If you pass in AF_INET6 (23) instead of AF_INET (2), on Win2k3 and WinXP boxes, you should see the set of IPv6 connections set up on your machine.

In this case the first parameter is a pointer to a pointer to a MIB_TCP6TABLE_OWNER_PID structure
that's defined as: