Click here to Skip to main content
15,881,204 members
Articles / Desktop Programming / MFC
Article

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

Rate me:
Please Sign up or sign in to vote.
3.13/5 (5 votes)
28 Feb 20022 min read 134K   4.9K   46   15
Retrieve TCP/IP/UDP statistics, interface details, ARP table, and Route table.

Image 1

Image 2

Image 3

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


Written By
Web Developer
United States United States
BS in Electrical engineering
MS in Computer science
Working since 12 Years.
Server side architecture/design/development is my favorite work.
-------------------------------------------
All ideas are worthless unless they are implemented.

Comments and Discussions

 
Generalnetwork availability notification Pin
m_shezy12-Nov-06 18:24
m_shezy12-Nov-06 18:24 
Generaldemo zip file Pin
Johnjfh9-Nov-05 17:32
Johnjfh9-Nov-05 17:32 
GeneralVC 6 Pin
vicenç13-May-05 5:11
vicenç13-May-05 5:11 
GeneralIP Stack Statistics Pin
Obi Wan 211-Dec-04 14:02
Obi Wan 211-Dec-04 14:02 
GeneralThe Demo file does not contain .exe Pin
softwaredeveloper11-Oct-03 6:11
softwaredeveloper11-Oct-03 6:11 
GeneralRe: The Demo file does not contain .exe Pin
Yurich23-Nov-03 12:25
Yurich23-Nov-03 12:25 
GeneralRe: The Demo file does not contain .exe Pin
Member 50866531-Mar-04 23:13
Member 50866531-Mar-04 23:13 
GeneralAdapter specific info Pin
jonzeke18-Jul-03 10:31
jonzeke18-Jul-03 10:31 
Questionhow can i find the bandwidth usage? Pin
hirr18-Jun-03 3:38
hirr18-Jun-03 3:38 
GeneralMemory leak Pin
Anatoly Ivasyuk15-Aug-02 9:13
Anatoly Ivasyuk15-Aug-02 9:13 
GeneralCan't find h file Pin
Matt Newman7-Mar-02 16:35
Matt Newman7-Mar-02 16:35 
I am using VC++ 7 Standard and it keeps looking for includes. Say if the example folder is on C: drive it looks for the includes at \Program Files\etc etc not C:\Program Files. Am I the only one this problem?

-Suspicious | :suss: Matt NewmanSuspicious | :suss:
-Sonork ID: 100.11179:BestSnowman
Frankly AOL should stick to what it does best: Fooling millions of americans into believing that it, AOL, is the web. -Paul Watson
GeneralRe: Can't find h file Pin
Q_K_Hou9-Jun-03 3:38
Q_K_Hou9-Jun-03 3:38 
QuestionLink? Pin
Matt Newman1-Mar-02 15:37
Matt Newman1-Mar-02 15:37 
AnswerRe: Link? Pin
Matt Newman1-Mar-02 15:46
Matt Newman1-Mar-02 15:46 
GeneralScreen shot images Pin
shanthu1-Mar-02 8:55
shanthu1-Mar-02 8:55 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.