65.9K
CodeProject is changing. Read more.
Home

Retrieve the number of bytes sent/received (and other useful infos) for any network adapter

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.56/5 (21 votes)

Oct 30, 2003

CPOL

1 min read

viewsIcon

103468

downloadIcon

1998

Using Iphlpapi.dll to retrieve network adapters info

Sample Image - BytesSentReceived.jpg

Introduction

This sample snippet shows how to retrieve the list of all network adapters on your machine, plus a lot of infos about each of them. The information you can retrieve are all the members of the structure MIB_IFROW as shown in this MSDN snippet

typedef struct _MIB_IFROW {
  WCHAR   wszName[MAX_INTERFACE_NAME_LEN];
  DWORD   dwIndex;    // index of the interface
  DWORD   dwType;     // type of interface
  DWORD   dwMtu;      // max transmission unit 
  DWORD   dwSpeed;    // speed of the interface 
  DWORD   dwPhysAddrLen;    // length of physical address
  BYTE    bPhysAddr[MAXLEN_PHYSADDR]; // physical address of adapter
  DWORD   dwAdminStatus;    // administrative status
  DWORD   dwOperStatus;     // operational status
  DWORD   dwLastChange;     // last time operational status changed 
  DWORD   dwInOctets;       // octets received
  DWORD   dwInUcastPkts;    // unicast packets received 
  DWORD   dwInNUcastPkts;   // non-unicast packets received 
  DWORD   dwInDiscards;     // received packets discarded 
  DWORD   dwInErrors;       // erroneous packets received 
  DWORD   dwInUnknownProtos;  // unknown protocol packets received 
  DWORD   dwOutOctets;      // octets sent 
  DWORD   dwOutUcastPkts;   // unicast packets sent 
  DWORD   dwOutNUcastPkts;  // non-unicast packets sent 
  DWORD   dwOutDiscards;    // outgoing packets discarded 
  DWORD   dwOutErrors;      // erroneous packets sent 
  DWORD   dwOutQLen;        // output queue length 
  DWORD   dwDescrLen;       // length of bDescr member 
  BYTE    bDescr[MAXLEN_IFDESCR];  // interface description 
} MIB_IFROW,*PMIB_IFROW;
After wasted lot of time trying to reach the performance counter stuff I found this DLL. And now you can use it without having to look around anymore :)

Using the code

In my working environment I don't have the right headers and libs to include in the project, so I used the functions inside the DLL using the LoadLibrary and GetProcAddress, like this:

typedef DWORD (_stdcall *TGetIfTable) (
  MIB_IFTABLE *pIfTable,  // buffer for interface table 
  ULONG *pdwSize,         // size of buffer
  BOOL bOrder             // sort the table by index?
);
...
TGetIfTable pGetIfTable;
...
// not so safe here...
pGetIfTable=(TGetIfTable)GetProcAddress(LoadLibrary("Iphlpapi.dll"),
    "GetIfTable");
/* always remember to test the result of LoadLibrary 
and GetProcAddress against null return values... */

The key function of the DLL  is GetIfTable. You have to call this function twice, first time to know how much memory space allocate, and then to fill the structure with the return values. In the OnInitDialog I get the right size of the adapters-table and I can fill the combo box with all the adapters descriptions

...
m_pTable=NULL;
m_dwAdapters=0;
ULONG uRetCode=pGetIfTable(m_pTable,&m_dwAdapters,TRUE);
if (uRetCode == 122 /* The data area passed to a 
    system call is too small.*/)
{
    // now we know how much memory allocate
    m_pTable=new MIB_IFTABLE[m_dwAdapters];
    pGetIfTable(m_pTable,&m_dwAdapters,TRUE);
    for (UINT i=0;i<m_pTable->dwNumEntries;i++)
    {
        MIB_IFROW Row=m_pTable->table[i];
        char szDescr[MAXLEN_IFDESCR];
        memcpy(szDescr,Row.bDescr,Row.dwDescrLen);
        szDescr[Row.dwDescrLen]=0;
        m_ctlCBAdapters.AddString(szDescr);
    }
}
...

if everything has gone right a timer starts, and the UpdateCounters get called every 100ms

void CP01Dlg::UpdateCounters()
{
    int nIndex=m_ctlCBAdapters.GetCurSel();
    if (nIndex!=CB_ERR)
    {
        pGetIfTable(m_pTable,&m_dwAdapters,TRUE);
        MIB_IFROW Row=m_pTable->table[nIndex];
        m_strInfo.Format("Received %d, Sent %d",Row.dwInOctets,
            Row.dwOutOctets);
        UpdateData(FALSE);
    }
}

That's all

I hope this snippet can save you some time. See you in my next article.