dcsimg
December 8, 2016
Hot Topics:

IP Helper API: Managing IP Addresses

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

Retrieving Basic ARP Information

Finally, let's consider how to obtain IP-to-MAC mapping. This process is called an Address Resolution Protocol (ARP). The IP Helper API has several functions dealing with it, but right now we will discuss only a couple of them: GetIpNetTable and SetIpNetEntry. GetIpNetTable retrieves the ARP table, which contains the mapping of IP addresses to physical addresses. Physical addresses are sometimes referred to as Media Access Controller (MAC) addresses. If you need to change some parameters of a specific entry, use a SetIpNetEntry call. The following code sample completes our investigations for this article:

void CNWParamsDlg::ShowIp2MAC(PMIB_IPNETTABLE pIpNetTable)
{
   m_ListBox.ResetContent();
   CString sTmp;
   sTmp.Format(L"Num Entries: %d",pIpNetTable->dwNumEntries);
   m_ListBox.AddString(sTmp);

   in_addr addr;
   TCHAR szBuffer[128];

   for (int i = 0; i < pIpNetTable->dwNumEntries; i++)
   {
      MIB_IFROW mibRow;
      memset(&mibRow,0,sizeof(mibRow));
      mibRow.dwIndex = pIpNetTable->table[i].dwIndex;
      GetIfEntry(&mibRow);
      sTmp.Format(L"Idx: %lu Name: %s", pIpNetTable->
                  table[i].dwIndex, mibRow.wszName);
      m_ListBox.AddString(sTmp);

      addr.S_un.S_addr = pIpNetTable->table[i].dwAddr;
      char *szAddr = inet_ntoa(addr);
      memset(szBuffer,0,sizeof(szBuffer));
      MultiByteToWideChar(CP_ACP,0,szAddr,strlen(szAddr),
                          szBuffer,sizeof(szBuffer));
      sTmp.Format(L"   IP: %s", szBuffer);
      switch (pIpNetTable->table[i].dwType)
      {
      case MIB_IPNET_TYPE_OTHER:
         sTmp += L" OTHER";
         break;
      case MIB_IPNET_TYPE_INVALID:
         sTmp += L" INVALID";
         break;
      case MIB_IPNET_TYPE_DYNAMIC:
         sTmp += L" DYNAMIC";
         break;
      case MIB_IPNET_TYPE_STATIC:
         sTmp += L" STATIC";
         break;
      }
      m_ListBox.AddString(sTmp);

      if(pIpNetTable->table[i].dwPhysAddrLen>0)
      {
         CString strToChar;
         CString strCurrentMac;
         BYTE *pAddress = pIpNetTable->table[i].bPhysAddr;
         for(int nCount=0; nCount-pIpNetTable->
             table[i].dwPhysAddrLen;nCount++,pAddress++)
         {
            strToChar.Format(L"%02X",*pAddress);
            strCurrentMac+=strToChar;
            if ( nCount + 1 < pIpNetTable- 
                 table[i].dwPhysAddrLen )
                    strCurrentMac += L":";
         }
         m_ListBox.AddString(L"   MAC: " + strCurrentMac);
      }
   }

   ((CStatic*)GetDlgItem(IDC_STATIC_INFO))->
    SetWindowText(L"Ip to MAC:");
}

void CNWParamsDlg::OnIpNetTable()
{
   PMIB_IPNETTABLE pIpNetTable = NULL;
   ULONG dwSize = 0;
   DWORD dwRes = GetIpNetTable(pIpNetTable, &dwSize, FALSE);

   if ( dwRes == ERROR_INSUFFICIENT_BUFFER )
   {
      pIpNetTable = (PMIB_IPNETTABLE)new BYTE[dwSize];
      dwRes = GetIpNetTable(pIpNetTable, &dwSize, FALSE);

      if ( dwRes == NO_ERROR )
         ShowIp2MAC(pIpNetTable);

      delete pIpNetTable;
   }
}

void CNWParamsDlg::OnSetIpNetTable()
{
   PMIB_IPNETTABLE pIpNetTable = NULL;
   ULONG dwSize = 0;
   DWORD dwRes = GetIpNetTable(pIpNetTable, &dwSize, FALSE);

   if ( dwRes == ERROR_INSUFFICIENT_BUFFER )
   {
      pIpNetTable = (PMIB_IPNETTABLE)new BYTE[dwSize];
      dwRes = GetIpNetTable(pIpNetTable, &dwSize, FALSE);

      if ( dwRes == NO_ERROR )
      {
         MIB_IPNETROW mibIpNetRow = pIpNetTable->table[0];
         mibIpNetRow.dwType = MIB_IPNET_TYPE_STATIC;
         dwRes = SetIpNetEntry(&mibIpNetRow);
      }

      delete pIpNetTable;
   }
}

Once again, you may see that it follows a common IP Hepler API scheme: discovering the needed size of the output buffer, getting information, and then surfing though linked lists or tables. Actually, IP Helper API provides many similar methods that return information about the same stuff on different slices.

Have we have something left undiscussed? For sure, yes, and we will touch the rest partially in the next article.

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