[Winpcap-users] How to retrieve IP address associated with an Interface

Vasily Borovyak vbor at isd.dp.ua
Tue Jul 11 15:24:49 GMT 2006


Here is several ways to determine IP address..

------------------------------------------------------------------------
*#1 Using WSAIoctl Winsock2 with SIO_ADDRESS_LIST_QUERY*

#include    <iostream>
#include    <winsock2.h>

#pragma        comment (lib, "ws2_32.lib")

int main(void)
{
    using            std::cout;
    using            std::cerr;
    using            std::endl;

    WSADATA        wd;
    SOCKET        sock;
    char            buf[65535];
    DWORD            dwSize = 65535;
    int                nRet;
    SOCKET_ADDRESS_LIST *pAddr;
    SOCKADDR*    saddr;
   
    nRet = WSAStartup(MAKEWORD(2,0), &wd);
    if(nRet != 0){
        cerr << "WSAStartup fail with code " << nRet << endl;
        return -1;
    }
    sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(sock == INVALID_SOCKET){
        cerr << "socket fail with code " << WSAGetLastError() << endl;
        return -2;
    }
    ZeroMemory(buf, 65535);
    nRet = WSAIoctl(sock, SIO_ADDRESS_LIST_QUERY, NULL, 0, buf, 65535, 
&dwSize, NULL, NULL);
    if(nRet != SOCKET_ERROR){
        pAddr = reinterpret_cast<SOCKET_ADDRESS_LIST*>(buf);
        nRet = pAddr->iAddressCount;
        saddr = pAddr->Address->lpSockaddr;
        while (0 < nRet--){
            cout << 
inet_ntoa(reinterpret_cast<SOCKADDR_IN*>(saddr)->sin_addr) << endl;
            saddr++;
        }
        nRet = 0;
    }else {
        cerr << "WSAIoctl fail with code " << WSAGetLastError() << endl;
        nRet = -3;
    }
    closesocket(sock);
    WSACleanup();
    return nRet;
}

------------------------------------------------------------------------
*#2 Using IP Helper API*

#include    <iostream>
#include    <windows.h>
#include    <iphlpapi.h>

#pragma        comment (lib, "iphlpapi")

void main (void)
{
    using                            std::cout;
    using                            std::cerr;
    using                            std::endl;
   
    char*                            buf;
    PIP_ADAPTER_INFO    pAdaptersInfo;
    PIP_ADDR_STRING        pAddr;
    DWORD                            dwSize = 0;

    if(GetAdaptersInfo(NULL, &dwSize) != ERROR_BUFFER_OVERFLOW){
        cerr << "GetAdaptersInfo fail" << endl;
        return;
    }
    buf = new char[dwSize];
    if (!buf) return;
    pAdaptersInfo = reinterpret_cast<PIP_ADAPTER_INFO>(buf);
    if (GetAdaptersInfo (pAdaptersInfo, &dwSize) == ERROR_SUCCESS){
        while (pAdaptersInfo){
            pAddr = &pAdaptersInfo->IpAddressList;
            while (pAddr){
                cout <<"Address: " << pAddr->IpAddress.String << "/" <<
                    pAddr->IpMask.String << endl;
                pAddr = pAddr->Next;
            }
            pAdaptersInfo = pAdaptersInfo->Next;
        }
    }
    delete[] buf;
}

------------------------------------------------------------------------
*#3 The easiest one.*

#include    <iostream>
#include    <winsock2.h>

#pragma        comment (lib, "ws2_32.lib")

int main(void)
{
    using            std::cout;
    using            std::cerr;
    using            std::endl;

    WSADATA            wd;
    char            buf[65535];
    int                nRet;
    struct hostent    *phe;
    struct in_addr    *paddr;
   
    nRet = WSAStartup(MAKEWORD(1, 1), &wd);
    if(nRet != 0){
        cerr << "WSAStartup fail with code " << nRet << endl;
        return -1;
    }
    if(gethostname(buf, 65535) != SOCKET_ERROR){
        phe = gethostbyname(buf);
        if(phe != 0){
            while(phe->h_addr_list[nRet]){
                paddr = reinterpret_cast<struct 
in_addr*>(phe->h_addr_list[nRet++]);
                cout << inet_ntoa(*paddr) << endl;
            }
        }
    }
    WSACleanup();
    return nRet;
}

------------------------------------------------------------------------
*#4 Broadcasting and determining network configuration*

#include <ioctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <netinet/in.h>
int
main (int argc, char *argv[])
{
      int sock;
      struct ifconf d;
      struct ifreq *ifr, *end, *cur, *temp;
      char buffer[128];
      if ((sock= socket (AF_INET, SOCK_DGRAM, 0)) == -1) {
            perror ("socket");
            exit (EXIT_FAILURE);
      }
      /* temporary storage for getting broadcast address */
      temp= (struct ifreq *)buffer;
      d.ifc_len= 4096;
      d.ifc_buf= malloc (d.ifc_len);
      if (ioctl (sock, SIOCGIFCONF, &d) == -1) {
            perror ("ioctl (SIOCGIFCONF)");
            exit (EXIT_FAILURE);
      }
      /*
       * Note that the ifreq structure is variable length so we have to 
step
       * along the structure by the size of the prev structure
       */
      ifr= (struct ifreq *) d.ifc_req;
      end= (struct ifreq *) ((char *) ifr + d.ifc_len);
      while (ifr < end) {
            cur= ifr;
            /* step along the array by the size of the current structure */
            ifr=(struct ifreq *)((char *)ifr + ifr->ifr_addr.sa_len + 
IFNAMSIZ);
            /* if this isn't in the INET address family ignore */
            if (cur->ifr_addr.sa_family != AF_INET)
                  continue;  
            /* save aside the ifr structure to get the broadcast addr */
            memcpy(temp, cur, cur->ifr_addr.sa_len + IFNAMSIZ);
 
            printf ("%s (%s) ", cur->ifr_name, inet_ntoa(((struct 
sockaddr_in *)
                                                 
&cur->ifr_addr)->sin_addr));
            /* get the flags for this interface */
            if (ioctl (sock, SIOCGIFFLAGS, (char *) cur) < 0) {
                  perror ("ioctl (SIOCGIFFLAGS)");
                  exit (EXIT_FAILURE);
            }
            /* if the interface is up, print out some information about 
it */
            if (cur->ifr_flags & IFF_UP) {
                  if (cur->ifr_flags & IFF_BROADCAST) {
                        printf ("broadcast ");
                        if (ioctl(sock, SIOCGIFBRDADDR, (char *)temp) != -1)
                              printf("%s ", inet_ntoa(((struct 
sockaddr_in *)
                                                 
&temp->ifr_addr)->sin_addr));
                        else {
                              perror("ioctl (SIOCGIFBRDADDR)");
                              exit(EXIT_FAILURE);
                        }
                  }
                  if (cur->ifr_flags & IFF_POINTOPOINT) {
                        printf ("point-to-point dst ");
                        if (ioctl(sock, SIOCGIFDSTADDR, (char *)temp) != -1)
                              printf("%s ", inet_ntoa(((struct 
sockaddr_in *)
                                                 
&cur->ifr_addr)->sin_addr));
                        else {
                              perror("ioctl (SIOCGIFDSTADDR)");
                              exit(EXIT_FAILURE);
                        }
                  }
            }
            putc ('\n', stdout);
      }
      return EXIT_SUCCESS;
}

------------------------------------------------------------------------
*#5 Using  SNMP Extension Agent API*

#include    <iostream>
#include    <winsock2.h>
#include    <snmp.h>

#pragma        comment(lib, "snmpapi.lib")
#pragma        comment(lib, "ws2_32.lib")

namespace bsnmp {
    PFNSNMPEXTENSIONINIT    SnmpExtensionInit;
    PFNSNMPEXTENSIONQUERY    SnmpExtensionQuery;
};

int main(void)
{
    HANDLE                    hPollForTrapEvent;
    AsnObjectIdentifier        SupportedView;
    HMODULE                    hLib;
    UINT                    OID[] = { 1, 3, 6, 1, 2, 1, 4 , 20, 1 ,1 };
    SnmpVarBindList            SVBList;
    SnmpVarBind                SVBVars[1];
    AsnObjectIdentifier        AsnOID = { sizeof(OID)/sizeof(UINT), OID };
    AsnInteger32            ErrorStatus, ErrorIndex;

    hLib = LoadLibrary("inetmib1.dll");
    if (!hLib){
        std::cerr << "Loadlibrary fail" << std::endl;
        return -1;
    }
    bsnmp::SnmpExtensionInit = 
reinterpret_cast<PFNSNMPEXTENSIONINIT>(GetProcAddress(hLib, 
"SnmpExtensionInit"));
    bsnmp::SnmpExtensionQuery = 
reinterpret_cast<PFNSNMPEXTENSIONQUERY>(GetProcAddress(hLib, 
"SnmpExtensionQuery"));
    if(!bsnmp::SnmpExtensionInit || !bsnmp::SnmpExtensionQuery){
        std::cerr << "GetProcAddress fail" << std::endl;
        return -2;
    }
    if(bsnmp::SnmpExtensionInit(0, &hPollForTrapEvent, &SupportedView)){
        SVBList.len = 1;
        SVBList.list = SVBVars;
        SnmpUtilOidCpy(&SVBVars[0].name, &AsnOID);
        while(true){
            if(bsnmp::SnmpExtensionQuery(ASN_RFC1157_GETNEXTREQUEST, 
&SVBList, &ErrorStatus, &ErrorIndex) != 0){
                if(SnmpUtilOidNCmp(&SVBVars[0].name, &AsnOID, 
AsnOID.idLength)) break;
                std::cout << inet_ntoa(*reinterpret_cast<struct 
in_addr*>(SVBVars[0].value.asnValue.address.stream))
                    << std::endl;
            }else break;
        }
        SnmpUtilOidFree(&SVBVars[0].name);
    }else {
        std::cerr << "SnmpExtensionInit fail" << std::endl;
    }
    FreeLibrary(hLib);
    return 0;
}

------------------------------------------------------------------------
*#6 Using WinPCAP*

#include "pcap.h"
#include "pcap-int.h"

#include <ntddndis.h>
#pragma     comment(lib, "packet.lib")

#ifndef WIN32
#include <sys/socket.h>
#include <netinet/in.h>
#else
#include <winsock.h>
#endif

void ifprint(pcap_if_t *d);
char *iptos(u_long in);
int getmac(pcap_t* ha, char* pStr);

int main()
{
  pcap_if_t *alldevs;
  pcap_if_t *d;
  char errbuf[PCAP_ERRBUF_SIZE+1];

  if (pcap_findalldevs(&alldevs, errbuf) == -1)
  {
    fprintf(stderr,"Error in pcap_findalldevs: %s\n",errbuf);
    exit(1);
  }

  for(d=alldevs;d;d=d->next)
  {
    ifprint(d);
  }

  return 1;
}

void ifprint(pcap_if_t *d)
{
  pcap_addr_t *a;
  pcap_t      *hadapter;
  char          pMAC[20];
  printf("%s\n",d->name);
  if (d->description)
    printf("\tDescription: %s\n",d->description);
  printf("\tLoopback: %s\n",(d->flags & PCAP_IF_LOOPBACK)?"yes":"no");
  hadapter = pcap_open_live(d->name, 0, 0, 0, 0);
  if(getmac(hadapter, pMAC)){
    printf("\tMAC Address: %s\n", pMAC);
  }
  pcap_close(hadapter);
  for(a=d->addresses;a;a=a->next) {
    printf("\tAddress Family: #%d\n",a->addr->sa_family);
 
    switch(a->addr->sa_family)
    {
      case AF_INET:
        printf("\tAddress Family Name: AF_INET\n");
        if (a->addr)
          printf("\tAddress: %s\n",iptos(((struct sockaddr_in 
*)a->addr)->sin_addr.s_addr));
        if (a->netmask)
          printf("\tNetmask: %s\n",iptos(((struct sockaddr_in 
*)a->netmask)->sin_addr.s_addr));
        if (a->broadaddr)
          printf("\tBroadcast Address: %s\n",iptos(((struct sockaddr_in 
*)a->broadaddr)->sin_addr.s_addr));
        if (a->dstaddr)
          printf("\tDestination Address: %s\n",iptos(((struct 
sockaddr_in *)a->dstaddr)->sin_addr.s_addr));
        break;
      default:
        printf("\tAddress Family Name: Unknown\n");
        break;
    }
  }
  printf("\n");
}

#define IPTOSBUFFERS    12
char *iptos(u_long in)
{
    static char output[IPTOSBUFFERS][3*4+3+1];
    static short which;
    u_char *p;

    p = (u_char *)&in;
    which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1);
    sprintf(output[which], "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
    return output[which];
}
int getmac(pcap_t* ha, char* pStr)
{
  PPACKET_OID_DATA    pOidData;
  CHAR pAddr[sizeof(PACKET_OID_DATA)+5];
  ZeroMemory(pAddr, sizeof(PACKET_OID_DATA)+5);
  pOidData = (PPACKET_OID_DATA) pAddr;
  pOidData->Oid = OID_802_3_CURRENT_ADDRESS;
  pOidData->Length = 6;
  if(PacketRequest(ha->adapter, FALSE, pOidData))
  {   
      sprintf(pStr, "%.02X:%.02X:%.02X:%.02X:%.02X:%.02X",
          pOidData->Data[0],pOidData->Data[1],pOidData->Data[2],
          pOidData->Data[3],pOidData->Data[4],pOidData->Data[5]);
  }else{
      return 0;
  }
  return 1;
}

------------------------------------------------------------------------
*#7 Using VB*

strComputer = "."
'strComputer = "сетевое имя удаленного компа"
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set IPConfigSet = objWMIService.ExecQuery _
("Select * from Win32_NetworkAdapterConfiguration where IPEnabled=TRUE")
For Each IPConfig in IPConfigSet
If Not IsNull(IPConfig.IPAddress) Then
For i=LBound(IPConfig.IPAddress) to UBound(IPConfig.IPAddress)
WScript.Echo IPConfig.IPAddress(i), IPConfig.Description(i)
Next
End If
Next

------------------------------------------------------------------------

-- 
Best regards. Vasily Borovyak <vbor at isd.dp.ua>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.winpcap.org/pipermail/winpcap-users/attachments/20060711/50d4ebdb/attachment-0001.htm


More information about the Winpcap-users mailing list