Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

IP Helper API - Retrieve TCP/IP/UDP Statistics, Interface details, ARP Table and Route Table

0.00/5 (No votes)
28 Feb 2002 2  
Retrieve TCP/IP/UDP statistics, interface details, ARP table, and Route table.

Introduction

There are few articles which describe how to retrieve the statistics about network. We used to load the inetmib1.dll manually and map the function pointers in order to get all the required information.

Finally microsoft published some nice APIs to perform these operations. This article explains how to make use of those published APIs. The APIs are categorized as follows

Interface Class

This class allows applications to retrieve network adapter characteristic information. The IP Helper APIs available for Windows NT 4.0 Service Pack 4 are listed below:

  • GetIfTable: Retrieves all network adapters physical characteristics.
  • GetIfEntry: Retrieves specific adapter characteristics.
  • SetIfEntry: Updates a specific adapter's operating status, such as describing whether an interface is up, down, or in a testing mode.
  • SetIpTTL: Allows applications to modify the Time to Live (TTL) field for all IP packets sent from your system.

IP Address Class

This class allows applications to modify and retrieve IP configuration information. However, most of these APIs are not supported on Windows NT 4.0 Service Pack 4. The IP Helper APIs available for Windows NT 4.0 SP 4 are listed below:

  • GetIpAddrTable: Allows an application to retrieve IP address information.

ARP Table Class

This class provides access to the address resolution protocol (ARP) entries by mapping from an IP address to a physical address. The IP Helper APIs available for Windows NT 4.0 Service Pack 4 are listed below:

  • GetIpNetTable: Retrieves address resolution table information.
  • SetIpNetEntry: Adds entry to the ARP table.
  • DeleteIpNetEntry: Deletes entry from the ARP table.

Route Table Class

This class allows applications to retrieve IP routing information and permits applications to make modifications to route entries in the table. Routing is the selection of the next hop address from a routing table over which a packet is sent. The IP Helper APIs available for Windows NT 4.0 Service Pack 4 are listed below:

  • GetIpForwardTable: Retrieves routing table information.
  • SetIpForwardEntry: Adds a route table entry.
  • DeleteIpForwardEntry: Deletes a route table entry.
  • GetRTTAndHopCount: Provides approximated round trip time information to a specific IP destination and also provides the hop count to that destination.

Statistics Class

This class provides information on various kinds of packet/connection statistics information on a local computer. The IP Helper APIs available for Windows NT 4.0 Service Pack 4 are listed below:

  • GetIpStatistics: Retrieves Internet Protocol (IP) packet statistics.
  • GetIcmpStatistics: Retrieves Internet Control Message Protocol (ICMP) statistics.
  • GetTcpStatistics: Retrieves Transmission Control Protocol (TCP) statistics.
  • GetUdpStatistics: Retrieves User Datagram Protocol (UDP) statistics.

Source code and Demo application

I have put together this demo using Visual Studio .NET

// View.cpp : implementation of the CWinNetStatView class

//

#include "stdafx.h"

#include "WinNetStat.h"

#include "WinNetStatDoc.h"

#include "WinNetStatView.h"

#include "netstatmanager.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

 // CWinNetStatView


IMPLEMENT_DYNCREATE(CWinNetStatView, CFormView)
BEGIN_MESSAGE_MAP(CWinNetStatView, CFormView)
    ON_BN_CLICKED(IDC_TCPSTATS, OnClickedTcpstats)
    ON_BN_CLICKED(IDC_UDPTATS, OnBnClickedUdptats)
    ON_BN_CLICKED(IDC_IPSTATS, OnBnClickedIpstats)
    ON_BN_CLICKED(IDC_NW_PARAMS, OnBnClickedNwParams)
    ON_BN_CLICKED(IDC_ADAPTER_INFO, OnBnClickedAdapterInfo)
END_MESSAGE_MAP()


 // CWinNetStatView construction/destruction 

 CWinNetStatView::CWinNetStatView() : CFormView(CWinNetStatView::IDD)
{
    // TODO: add construction code here

}
CWinNetStatView::~CWinNetStatView()
{
}
void CWinNetStatView::DoDataExchange(CDataExchange* pDX)
{
    CFormView::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_TEXT_OUTPUT, m_TextOutput);
}

BOOL CWinNetStatView::PreCreateWindow(CREATESTRUCT& cs)
{
    // TODO: Modify the Window class or styles here by modifying

    // the CREATESTRUCT cs

    return CFormView::PreCreateWindow(cs);
}

void CWinNetStatView::OnInitialUpdate(){
    CFormView::OnInitialUpdate();
    GetParentFrame()->RecalcLayout();
    ResizeParentToFit();
}

// CWinNetStatView diagnostics

#ifdef _DEBUG
void CWinNetStatView::AssertValid() const
{
    CFormView::AssertValid();
}

void CWinNetStatView::Dump(CDumpContext& dc) const{
    CFormView::Dump(dc);
}

CWinNetStatDoc* CWinNetStatView::GetDocument() const 
{
    ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CWinNetStatDoc)));
    return (CWinNetStatDoc*)m_pDocument;
}
#endif //_DEBUG// CWinNetStatView message handlers


void CWinNetStatView::OnClickedTcpstats()
{
    MIB_TCPSTATS TcpStatsMIB;
    ::GetTcpStatistics(&TcpStatsMIB);
    CString strMsg;
    CString strOutPut;
    strOutPut.Format("\r\n************************************\r\n");
    strMsg.Format("\tTCP/IP Statistics\t\r\n");
    strOutPut+=strMsg;
    strMsg.Format("\r\n************************************\r\n");
    strOutPut+=strMsg;
    strMsg.Format("time-out algorithm:\t%d\r\n",
        TcpStatsMIB.dwRtoAlgorithm);
    strOutPut+=strMsg;
    strMsg.Format("minimum time-out:\t%d\r\n",
        TcpStatsMIB.dwRtoMin);
    strOutPut+=strMsg;
    strMsg.Format("maximum time-out:\t%d\r\n",
        TcpStatsMIB.dwRtoMax);
    strOutPut+=strMsg;
    strMsg.Format("maximum connections:\t%d\r\n",
        TcpStatsMIB.dwMaxConn);
    strOutPut+=strMsg;
    strMsg.Format("active opens:\t%d\r\n",
        TcpStatsMIB.dwActiveOpens);
    strOutPut+=strMsg;
    strMsg.Format("passive opens:\t%d\r\n",
        TcpStatsMIB.dwPassiveOpens);
    strOutPut+=strMsg;
    strMsg.Format("failed attempts:\t%d\r\n",
        TcpStatsMIB.dwAttemptFails);
    strOutPut+=strMsg;
    strMsg.Format("established connections reset:\t%d\r\n",
        TcpStatsMIB.dwEstabResets);
    strOutPut+=strMsg;
    strMsg.Format("established connections:\t%d\r\n",
        TcpStatsMIB.dwCurrEstab);
    strOutPut+=strMsg;
    strMsg.Format("segments received:\t%d\r\n",TcpStatsMIB.dwInSegs);
    strOutPut+=strMsg;
    strMsg.Format("segment sent:\t%d\r\n",TcpStatsMIB.dwOutSegs);
    strOutPut+=strMsg;
    strMsg.Format("segments retransmitted:\t%d\r\n",
        TcpStatsMIB.dwRetransSegs);
    strOutPut+=strMsg;
    strMsg.Format("incoming errors:\t%d\r\n",TcpStatsMIB.dwInErrs);
    strOutPut+=strMsg;
    strMsg.Format("outgoing resets:\t%d\r\n",TcpStatsMIB.dwOutRsts);
    strOutPut+=strMsg;
    strMsg.Format("cumulative connections:\t%d\r\n",
        TcpStatsMIB.dwNumConns);
    strOutPut+=strMsg;
    m_TextOutput.SetWindowText(strOutPut);
}

void CWinNetStatView::OnBnClickedUdptats(){

    MIB_UDPSTATS UDPStatsMIB;
    ::GetUdpStatistics(&UDPStatsMIB);
    CString strMsg;
    CString strOutPut;
    strOutPut.Format("\r\n************************************\r\n");
    strMsg.Format("\tUDP Statistics\t\r\n");
    strOutPut+=strMsg;
    strMsg.Format("\r\n************************************\r\n");
    strOutPut+=strMsg;
    strMsg.Format("received datagrams:\t%d\r\n",UDPStatsMIB.dwInDatagrams);
    strOutPut+=strMsg;
    strMsg.Format("datagrams for which no port exists:\t%d\r\n"
        ,UDPStatsMIB.dwNoPorts);
    strOutPut+=strMsg;
    strMsg.Format("errors on received datagrams:\t%d\r\n",
        UDPStatsMIB.dwInErrors);
    strOutPut+=strMsg;
    strMsg.Format("sent datagrams:\t%d\r\n",UDPStatsMIB.dwOutDatagrams);
    strOutPut+=strMsg;
    strMsg.Format("number of entries in UDP listener table:\t%d\r\n",
        UDPStatsMIB.dwNumAddrs);
    strOutPut+=strMsg;
    m_TextOutput.SetWindowText(strOutPut);
}

void CWinNetStatView::OnBnClickedIpstats(){

    MIB_IPSTATS IPStatsMIB;
    ::GetIpStatistics(&IPStatsMIB);
    CString strMsg;
    CString strOutPut;
    strOutPut.Format("\r\n************************************\r\n");
    strMsg.Format("\tIP Statistics\t\r\n");
    strOutPut+=strMsg;
    strMsg.Format("\r\n************************************\r\n");
    strOutPut+=strMsg;
    strMsg.Format("IP forwarding enabled or disabled:\t%d\r\n",
        IPStatsMIB.dwForwarding);
    strOutPut+=strMsg;
    strMsg.Format("default time-to-live:\t%d\r\n",
        IPStatsMIB.dwDefaultTTL);
    strOutPut+=strMsg;
    strMsg.Format("datagrams received:\t%d\r\n",
        IPStatsMIB.dwInReceives);
    strOutPut+=strMsg;
    strMsg.Format("received header errors:\t%d\r\n",
        IPStatsMIB.dwInHdrErrors);
    strOutPut+=strMsg;
    strMsg.Format("received address errors:\t%d\r\n",
        IPStatsMIB.dwInAddrErrors);
    strOutPut+=strMsg;
    strMsg.Format("datagrams forwarded:\t%d\r\n",
        IPStatsMIB.dwForwDatagrams);
    strOutPut+=strMsg;
    strMsg.Format("datagrams with unknown protocol:\t%d\r\n",
        IPStatsMIB.dwInUnknownProtos);
    strOutPut+=strMsg;
    strMsg.Format("received datagrams discarded:\t%d\r\n",
        IPStatsMIB.dwInDiscards);
    strOutPut+=strMsg;
    strMsg.Format("received datagrams delivered:\t%d\r\n",
        IPStatsMIB.dwInDelivers);
    strOutPut+=strMsg;
    strMsg.Format("sent datagrams discarded:\t%d\r\n",
        IPStatsMIB.dwOutDiscards);
    strOutPut+=strMsg;
    strMsg.Format("datagrams for which no route exists:\t%d\r\n",
        IPStatsMIB.dwOutNoRoutes);
    strOutPut+=strMsg;
    strMsg.Format("datagrams for which all frags did not arrive:\t%d\r\n",
        IPStatsMIB.dwReasmTimeout);
    strOutPut+=strMsg;
    strMsg.Format("datagrams requiring reassembly:\t%d\r\n",
        IPStatsMIB.dwReasmReqds);
    strOutPut+=strMsg;
    strMsg.Format("successful reassemblies:\t%d\r\n",IPStatsMIB.dwReasmOks);
    strOutPut+=strMsg;
    strMsg.Format("failed reassemblies:\t%d\r\n",IPStatsMIB.dwReasmFails);
    strOutPut+=strMsg;
    strMsg.Format("successful fragmentations:\t%d\r\n",IPStatsMIB.dwFragOks);
    strOutPut+=strMsg;
    strMsg.Format("failed fragmentations:\t%d\r\n",IPStatsMIB.dwFragFails);
    strOutPut+=strMsg;
    strMsg.Format("datagrams fragmented:\t%d\r\n",IPStatsMIB.dwFragCreates);
    strOutPut+=strMsg;
    strMsg.Format("number of interfaces on computer:\t%d\r\n",
        IPStatsMIB.dwNumIf);
    strOutPut+=strMsg;
    strMsg.Format("number of IP address on computer:\t%d\r\n",
        IPStatsMIB.dwNumAddr);
    strOutPut+=strMsg;
    strMsg.Format("number of routes in routing table:\t%d\r\n",
        IPStatsMIB.dwNumRoutes);
    strOutPut+=strMsg;
    m_TextOutput.SetWindowText(strOutPut);
}

void CWinNetStatView::OnBnClickedNwParams(){
    FIXED_INFO * FixedInfo;
    ULONG ulOutBufLen;
    DWORD dwRetVal;
    IP_ADDR_STRING * pIPAddr;
    CString strMsg;
    CString strOutPut;
    strOutPut.Format("\r\n************************************\r\n");
    strMsg.Format("\tNetwork Parameters\t\r\n");
    strOutPut+=strMsg;
    strMsg.Format("\r\n************************************\r\n");
    strOutPut+=strMsg;
    FixedInfo = (FIXED_INFO *) GlobalAlloc( GPTR, sizeof( FIXED_INFO ) );
    ulOutBufLen = sizeof( FIXED_INFO );
    if( ERROR_BUFFER_OVERFLOW == GetNetworkParams( FixedInfo, &ulOutBufLen ))
    {
        GlobalFree( FixedInfo );
        FixedInfo =(FIXED_INFO *) GlobalAlloc( GPTR, ulOutBufLen );
    }
    if ( dwRetVal = GetNetworkParams( FixedInfo, &ulOutBufLen ) )
    {
        strMsg.Format( 
            "Call to GetNetworkParams failed. Return Value: %08x\r\n", 
            dwRetVal );
        strOutPut+=strMsg;
    }
    else
    {
        strMsg.Format( "Host Name: %s\r\n", FixedInfo -> HostName );
        strOutPut+=strMsg;
        strMsg.Format( "Domain Name: %s\r\n", FixedInfo -> DomainName );
        strOutPut+=strMsg;
        strMsg.Format( "DNS Servers:\r\n" );
        strOutPut+=strMsg;
        strMsg.Format( "\t%s\r\n", 
            FixedInfo -> DnsServerList.IpAddress.String );
        strOutPut+=strMsg;
        pIPAddr = FixedInfo -> DnsServerList.Next;
        while ( pIPAddr )
        {
            strMsg.Format( "\t%s\r\n", pIPAddr ->IpAddress.String );
            strOutPut+=strMsg;
            pIPAddr = pIPAddr ->Next;
        }
    }
    m_TextOutput.SetWindowText(strOutPut);
}

void CWinNetStatView::OnBnClickedAdapterInfo(){
    IP_ADAPTER_INFO * FixedInfo;
    ULONG ulOutBufLen;
    DWORD dwRetVal;
    IP_ADDR_STRING * pIPAddr;
    CString strMsg;
    CString strOutPut;
    strOutPut.Format("\r\n************************************\r\n");
    strMsg.Format("\t Adaptor Information\t\r\n");
    strOutPut+=strMsg;
    strMsg.Format("\r\n************************************\r\n");
    strOutPut+=strMsg;
    FixedInfo = (IP_ADAPTER_INFO *) GlobalAlloc( GPTR, 
        sizeof( IP_ADAPTER_INFO ) );
    ulOutBufLen = sizeof( IP_ADAPTER_INFO );
    if( ERROR_BUFFER_OVERFLOW == GetAdaptersInfo(FixedInfo,&ulOutBufLen))
    {
        GlobalFree( FixedInfo );
        FixedInfo =(IP_ADAPTER_INFO *) GlobalAlloc( GPTR, ulOutBufLen );
    }
    if ( dwRetVal = GetAdaptersInfo( FixedInfo, &ulOutBufLen ) )
    {
        strMsg.Format( 
            "Call to GetAdaptersInfo failed. Return Value: %08x\r\n", 
            dwRetVal );
        strOutPut+=strMsg;
    }
    else
    {
        strMsg.Format( "AdapterName: %s\r\n",FixedInfo->AdapterName );
        strOutPut+=strMsg;
        strMsg.Format( "Description: %s\r\n",FixedInfo->Description );
        strOutPut+=strMsg;
    }
    m_TextOutput.SetWindowText(strOutPut);
}

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.

A list of licenses authors might use can be found here