dcsimg
December 7, 2016
Hot Topics:

IP Helper API: Retrieving Basic Information

  • September 10, 2004
  • By Alex Gusev
  • Send Email »
  • More Articles »

Getting Interfaces Info

The last section of the IP Helper API we will consider in this article is obtaining different info about network interfaces. As noted above, an interface is an IP-level abstraction for network stuff. Similarily to adapters, you can retrieve all required data by calling the following functions:

  • GetInterfaceInfo: To obtain a list of the network interface adapters
  • GetIfTable: To obtain the MIB-II interface table
  • GetIfEntry: To obtain info for specific interface
  • GetBestInterface or GetBestInterfaceEx: To obtain the best interface index for specified host address

The simplest case is the GetInterfaceInfo function:

void CNWParamsDlg::ShowInterfaces(PIP_INTERFACE_INFO pIfTable)
{
   m_ListBox.ResetContent();
   CString sTmp;
   sTmp.Format(L"Num Adapters: %d",pIfTable->NumAdapters);
   m_ListBox.AddString(sTmp);

   PIP_ADAPTER_INDEX_MAP pAdapter = pIfTable->Adapter;
   for (int i = 0; i < pIfTable->NumAdapters; i++)
   {
      sTmp.Format(L"Idx: %lu Name: %s", pIfTable->Adapter[i].Index,
                                        pIfTable->Adapter[i].Name);
      m_ListBox.AddString(sTmp);
   }

   ((CStatic*)GetDlgItem(IDC_STATIC_INFO))->
      SetWindowText(L"Interfaces:");
}

void CNWParamsDlg::OnInterfaces()
{
   ULONG dwOutBufLen = 0;
   DWORD dwRes       = GetInterfaceInfo(NULL,&dwOutBufLen);

   PIP_INTERFACE_INFO pIfTable =
      (PIP_INTERFACE_INFO)new BYTE[dwOutBufLen];
   dwRes = GetInterfaceInfo(pIfTable,&dwOutBufLen);

   TRACE(L"dwRes = %lu\n",dwRes);
   if ( dwRes == 0 )
      ShowInterfaces(pIfTable);
}

It lists all existing interfaces and adapters. There is nothing to discuss anything regarding this function, so let's move to the next ones.

GetIfTable returns interface table content into its pIfTable parameter:

typedef struct _MIB_IFTABLE {
   DWORD dwNumEntries;
   MIB_IFROW table[ANY_SIZE];
} MIB_IFTABLE, *PMIB_IFTABLE;

Each row in this table is presented by a MIB_IFROW struct. In turn, MIB_IFROW contains a lot of useful information:

typedef struct _MIB_IFROW {
   WCHAR wszName[MAX_INTERFACE_NAME_LEN];
   DWORD dwIndex;
   DWORD dwType;
   DWORD dwMtu;
   DWORD dwSpeed;
   DWORD dwPhysAddrLen;
   BYTE bPhysAddr[MAXLEN_PHYSADDR];
   DWORD dwAdminStatus;
   DWORD dwOperStatus;
   DWORD dwLastChange;
   DWORD dwInOctets;
   DWORD dwInUcastPkts;
   DWORD dwInNUcastPkts;
   DWORD dwInDiscards;
   DWORD dwInErrors;
   DWORD dwInUnknownProtos;
   DWORD dwOutOctets;
   DWORD dwOutUcastPkts;
   DWORD dwOutNUcastPkts;
   DWORD dwOutDiscards;
   DWORD dwOutErrors;
   DWORD dwOutQLen;
   DWORD dwDescrLen;
   BYTE bDescr[MAXLEN_IFDESCR];
} MIB_IFROW, *PMIB_IFROW;

As you see, there is a lot of informative data here. I'd like to highlight the following fields:

  • WCHAR wszName[MAX_INTERFACE_NAME_LEN];
  • DWORD dwIndex;
  • DWORD dwType;
  • DWORD dwMtu;
  • DWORD dwSpeed;
  • DWORD dwDescrLen;
  • BYTE bDescr[MAXLEN_IFDESCR];

For example, knowing dwMtu for a specific interface may significantly reduce network traffic if you will use the same block size in transmission. You can be interested in other parameters too for some reasons, depending on the application type you are developing. As a final shot, the snippet below shows how to select the best network interface for a specific IP.

void CNWParamsDlg::OnBestInterface()
{
   IPAddr dwDestAddr = inet_addr("63.236.73.167");
   DWORD dwBestIfIndex = -1;
   DWORD dwRes = GetBestInterface(dwDestAddr, &dwBestIfIndex);

   CString sTmp;
   sTmp.Format(L"Best Index : %lu - ",dwBestIfIndex);

   MIB_IFROW IfRow;
   IfRow.dwIndex = dwBestIfIndex;
   dwRes = GetIfEntry(&IfRow);

   m_ListBox.ResetContent();
   m_ListBox.AddString(sTmp + IfRow.wszName);
   ((CStatic*)GetDlgItem(IDC_STATIC_INFO))->
      SetWindowText(L"Best Interface Index:");
}

And that's all for today! New articles are coming soon.

Download

Download the accompanying code's zip file here

About the Author

Alex Gusev started to play with mainframes at the end of the 1980s, using Pascal and REXX, but soon switched to C/C++ and Java on different platforms. When mobile PDAs seriously rose their heads in the IT market, Alex did it too. Now, he works at an international retail software company as a team leader of the Mobile R department, making programmers' lives in the mobile jungles a little bit simpler.





Page 3 of 3



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Sitemap | Contact Us

Thanks for your registration, follow us on our social networks to keep up-to-date
Rocket Fuel