Recently we needed a way to monitor a remote system’s IPv4-TCP connection table without having to periodically log on to the system and run the “netstat” command. The solution that I came up with, a lightweight netstat like server, provides real-time connection monitoring viewable from any internet browser. The project is a nice example of how to add web-interfaces to applications that only have text UIs. BackgroundWe used the Microsoft function GetTcpTable for gathering connection data. A Microsoft example, which illustrated how to use the function, listed below, provided a nice starting point. Collapse
1 // Need to link with Iphlpapi.lib and Ws2_32.lib
2 #include <winsock2.h> 3 #include <ws2tcpip.h> 4 #include <iphlpapi.h> 5 #include <stdio.h> 6
7 #pragma comment(lib, "iphlpapi.lib")
8 #pragma comment(lib, "ws2_32.lib")
9
10 #define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
11 #define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
12
13 /* Note: could also use malloc() and free() */
14
15 int main()
16 {
17
18 // Declare and initialize variables
19 PMIB_TCPTABLE pTcpTable;
20 DWORD dwSize = 0;
21 DWORD dwRetVal = 0;
22
23 char szLocalAddr[128];
24 char szRemoteAddr[128];
25
26 struct in_addr IpAddr;
27
28 int i;
29
30 pTcpTable = (MIB_TCPTABLE *) MALLOC(sizeof (MIB_TCPTABLE));
31 if (pTcpTable == NULL) {
32 printf("Error allocating memory\n");
33 return 1;
34 }
35
36 dwSize = sizeof (MIB_TCPTABLE);
37 // Make an initial call to GetTcpTable to
38 // get the necessary size into the dwSize variable
39 if ((dwRetVal = GetTcpTable(pTcpTable, &dwSize, TRUE)) ==
40 ERROR_INSUFFICIENT_BUFFER) {
41 FREE(pTcpTable);
42 pTcpTable = (MIB_TCPTABLE *) MALLOC(dwSize);
43 if (pTcpTable == NULL) {
44 printf("Error allocating memory\n");
45 return 1;
46 }
47 }
48 // Make a second call to GetTcpTable to get
49 // the actual data we require
50 if ((dwRetVal = GetTcpTable(pTcpTable, &dwSize, TRUE)) == NO_ERROR) {
51 printf("\tNumber of entries: %d\n", (int) pTcpTable->dwNumEntries);
52 for (i = 0; i < (int) pTcpTable->dwNumEntries; i++) {
53 IpAddr.S_un.S_addr = (u_long) pTcpTable->table[i].dwLocalAddr;
54 strcpy_s(szLocalAddr, sizeof (szLocalAddr), inet_ntoa(IpAddr));
55 IpAddr.S_un.S_addr = (u_long) pTcpTable->table[i].dwRemoteAddr;
56 strcpy_s(szRemoteAddr, sizeof (szRemoteAddr), inet_ntoa(IpAddr));
57
58 printf("\n\tTCP[%d] State: %ld - ", i,
59 pTcpTable->table[i].dwState);
60 switch (pTcpTable->table[i].dwState) {
61 case MIB_TCP_STATE_CLOSED:
62 printf("CLOSED\n");
63 break;
64 case MIB_TCP_STATE_LISTEN:
65 printf("LISTEN\n");
66 break;Read more: Codeproject
1 // Need to link with Iphlpapi.lib and Ws2_32.lib
2 #include <winsock2.h> 3 #include <ws2tcpip.h> 4 #include <iphlpapi.h> 5 #include <stdio.h> 6
7 #pragma comment(lib, "iphlpapi.lib")
8 #pragma comment(lib, "ws2_32.lib")
9
10 #define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
11 #define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
12
13 /* Note: could also use malloc() and free() */
14
15 int main()
16 {
17
18 // Declare and initialize variables
19 PMIB_TCPTABLE pTcpTable;
20 DWORD dwSize = 0;
21 DWORD dwRetVal = 0;
22
23 char szLocalAddr[128];
24 char szRemoteAddr[128];
25
26 struct in_addr IpAddr;
27
28 int i;
29
30 pTcpTable = (MIB_TCPTABLE *) MALLOC(sizeof (MIB_TCPTABLE));
31 if (pTcpTable == NULL) {
32 printf("Error allocating memory\n");
33 return 1;
34 }
35
36 dwSize = sizeof (MIB_TCPTABLE);
37 // Make an initial call to GetTcpTable to
38 // get the necessary size into the dwSize variable
39 if ((dwRetVal = GetTcpTable(pTcpTable, &dwSize, TRUE)) ==
40 ERROR_INSUFFICIENT_BUFFER) {
41 FREE(pTcpTable);
42 pTcpTable = (MIB_TCPTABLE *) MALLOC(dwSize);
43 if (pTcpTable == NULL) {
44 printf("Error allocating memory\n");
45 return 1;
46 }
47 }
48 // Make a second call to GetTcpTable to get
49 // the actual data we require
50 if ((dwRetVal = GetTcpTable(pTcpTable, &dwSize, TRUE)) == NO_ERROR) {
51 printf("\tNumber of entries: %d\n", (int) pTcpTable->dwNumEntries);
52 for (i = 0; i < (int) pTcpTable->dwNumEntries; i++) {
53 IpAddr.S_un.S_addr = (u_long) pTcpTable->table[i].dwLocalAddr;
54 strcpy_s(szLocalAddr, sizeof (szLocalAddr), inet_ntoa(IpAddr));
55 IpAddr.S_un.S_addr = (u_long) pTcpTable->table[i].dwRemoteAddr;
56 strcpy_s(szRemoteAddr, sizeof (szRemoteAddr), inet_ntoa(IpAddr));
57
58 printf("\n\tTCP[%d] State: %ld - ", i,
59 pTcpTable->table[i].dwState);
60 switch (pTcpTable->table[i].dwState) {
61 case MIB_TCP_STATE_CLOSED:
62 printf("CLOSED\n");
63 break;
64 case MIB_TCP_STATE_LISTEN:
65 printf("LISTEN\n");
66 break;Read more: Codeproject