Search code examples
cwinsock

Get all IP-Addresses in C


I have the following problem. I have to write a Plugin for Pidgin in the Language C. I am completely new to C. I found the following Code.

  WORD wVersionRequested;
  WSADATA wsaData;
  char name[255];
  char* ip;
  PHOSTENT hostinfo;
  wVersionRequested = MAKEWORD( 2, 0 );

  if ( WSAStartup( wVersionRequested, &wsaData ) == 0 )  {
        if( gethostname ( name, sizeof(name)) == 0) {
              if((hostinfo = gethostbyname(name)) != NULL) {
                    ip = inet_ntoa (*(struct in_addr *)*hostinfo->h_addr_list);
              }
        }
        WSACleanup( );
  } 

I have the IP-Address 172.28.52.220 But because of my VMWare I also have the IP 10.0.1.3. In my Plugin now the IP 10.0.1.3 is assigned to my variable. i need the IP to find out in which location of my company I am. I need hte 172...

Now I could find in the winsock2.h that *hostinfo->h_addr_list contains the list of Ip addresses. How can I assign the 172. Address to my IP_Variable?

Thank you in advance for your help!


Edit: Just to clarify: I don´t want to have my external IP address. I need my internals.


Solution

  • Here is an example I tested on on linux. I dont have access to a Windows system until tomorrow, but can test and update the answer if required.

    It is comparable to the Windows version only without the WSAStartup call at the beginning.

    #include <unistd.h>
    #include <stdio.h>
    #include <errno.h>
    #include <netdb.h>
    
    int main()
    {
      char hostnamebuff[100];
    
      if(gethostname(hostnamebuff, 100) == 0)
      {
        struct hostent* hostinfo = gethostbyname(hostnamebuff);
        printf("host name is %s\n", hostnamebuff);
    
        if(hostinfo != NULL)
        {
          char** paddrlist = hostinfo->h_addr_list;
    
          printf("host list is\n");      
          while(*paddrlist != NULL)
          {
             char addrbuff[INET6_ADDRSTRLEN];
             if(inet_ntop(hostinfo->h_addrtype, *paddrlist, addrbuff, hostinfo->h_addrtype == AF_INET ? INET_ADDRSTRLEN : INET6_ADDRSTRLEN))
             {
               printf("%s\n", addrbuff);
    
               if(strncmp(addrbuff, "172.", 4) == 0)
               {
                 printf("its a match\n");
                 break;
               }
             } else
             {
               printf("failed to convert an address\n");
             }
             paddrlist++;
          }
        } else
        {
          printf("failed on gethostbyname\n");
        }
      } else
      {
        printf("failed on gethostname errno=%d\n", errno);
      }
    }
    

    The h_addr_list member of hostent is a NULL terminated array of pointers to char* (so its double pointer). My example shows how to traverse this. Hope it helps.

    As for this distinctly smelly bit of code

    ip = inet_ntoa (*(struct in_addr *)*hostinfo->h_addr_list);
    

    This is a highly unreadable way of getting the first entry in the address list.