Thursday, May 27, 2010

The quick and easy way to add web interfaces to C/C++ applications

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.

Background

We 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

Posted via email from jasper22's posterous