#include <windows.h>
#include <stdio.h>
#include <sys/stat.h>



/* modified with suggestions from Kevin Dunlap so we only pick out netcards bound to tcpip */
  int get_winnt_interfaces()

  {
        HKEY hk, hksub;                      /* registry key handle */
        BOOL bSuccess;
        char newkey[200];

        char servicename[50];
        DWORD sizeofservicename = 50;
        int Done = 0;
        
        /* these need to be big as they are multi_sz in type and hold all ip addresses and subnet mask for a
           given interface */
        char IpAddresses[10000];
        char *ipptr = IpAddresses;
        DWORD sizeofipaddresses = 10000;
        char SubNetMasks[10000];
        char *subptr = SubNetMasks;
        DWORD sizeofsubnetmasks = 10000;
        char bindservicenames[1000];
        DWORD sizeofbindnames = 1000;

       char oneIpAddress[16];
       char oneSubNetMask[16];
       int count = 0;
       char *cp;
       char *onenetcard;

    /* now get all the netcard values which are bound to tcpip */ 

    strcpy(newkey,"SYSTEM\\Currentcontrolset\\Services\\");
    strcat(newkey,"tcpip\\linkage");
       
    printf("opening %s \n",newkey);
    bSuccess = RegOpenKey(HKEY_LOCAL_MACHINE,newkey,&hk);
    if(bSuccess != ERROR_SUCCESS)
    {
        printf("Can not get TCP/IP Linkage from registery.\n");
        return -1;
    }

    /* now get the bind value */
        sizeofbindnames = 1000;
        bSuccess = RegQueryValueEx(hk,     /* subkey handle         */
        "Bind",                            /* value name            */
        NULL,                              /* must be zero          */
        NULL,                              /* value type          not required  */
        (LPBYTE) &bindservicenames,        /* address of value data */
        &sizeofbindnames);                 /* length of value data  */
        if(bSuccess != ERROR_SUCCESS)
        {
            printf("Error in RegQueryValueEx fetching Bind Service names parameter \n");
            RegCloseKey(hk);
            return -1;
        }


          printf("Got values for netcards:\n");
          printf("-----------------------------------------------------------\n");
          cp = bindservicenames;
          { int i;
          for (i=0; i<(int)sizeofbindnames; i++)
            { 
             printf("%c",*cp);
             ++cp;
            }
          printf("\n-----------------------------------------------------------\n");
          }
    /* now loop through and get all the values which are bound to tcpip */ 
    /* we can also close the key here as we have the values now */
    RegCloseKey(hk);
    onenetcard = bindservicenames;
    while(1)
    {
       onenetcard = onenetcard + 8;
       if  ((onenetcard < (bindservicenames + sizeofbindnames)) &&
           (sscanf(onenetcard,"%s",servicename) != EOF))
         {
            onenetcard+= strlen(servicename) + 1;
            printf("got service name = %s \n",servicename);
         }
        else { /* no more */
               break;
             }

        /* skip services that are NDISWAN... since these are temporary interfaces like ras and if we bind to these
           we would have to check if the socket is still ok everytime before using it as when the link goes down
           and comes back up the socket is no longer any good... and the server eventually crashes if we don't check
           this.. and to check it entails a lot of overhead... shouldn't be a problem with machines with only a RAS
           interface anyway as we can bind to the loopback or 0.0.0.0 */

        if ((strlen(servicename) >= 7) && (strncmp(strupr(servicename),"NDISWAN",7) == 0))
          {
            /* skip it */
	        printf("Skippping temporary interface [%s]\n",servicename);
          }
        else {
  
           /* if opening this key fails we can assume it is not a network card ie digiboard and go on.. */
           /* ok now that we have the service name parameter close the key and go get the ipaddress and subnet mask */

           strcpy(newkey,"SYSTEM\\Currentcontrolset\\Services\\");
           strcat(newkey,servicename);
           strcat(newkey,"\\parameters\\tcpip");

           printf("service name = %s \n",servicename);
           printf("opening Service name key: %s \n",newkey);
           bSuccess = RegOpenKey(HKEY_LOCAL_MACHINE,newkey,&hksub);
           if(bSuccess != ERROR_SUCCESS)
            {
              printf("Skipping interface [%s] ... It is not a network card.\n",servicename);
            }

           else { /* ok it is a network card */            
           printf("getting ip address block ...\n");
           /* ok now get the ipaddress and subnetmask */
           sizeofipaddresses = 10000;
           bSuccess = RegQueryValueEx(hksub,  /* subkey handle         */
           "IpAddress",                       /* value name            */
            NULL,                             /* must be zero          */
            NULL,                             /* value type          not required  */
            (LPBYTE) &IpAddresses,               /* address of value data */
            &sizeofipaddresses);                /* length of value data  */
            if(bSuccess != ERROR_SUCCESS)
              {
               printf("Error in RegQueryValueEx fetching IpAddress parameter! \n");
               RegCloseKey(hksub);
               return -1;
              }
          printf("ipaddress block: size = %d\n",sizeofipaddresses);
          printf("-----------------------------------------------------------\n");
          cp = IpAddresses;
          { int i;
          for (i=0; i<(int)sizeofipaddresses; i++)
            { 
             printf("%c",*cp);
             ++cp;
            }
          printf("\n-----------------------------------------------------------\n");
          }
           /* ok now get the ipaddress and subnetmask */

           sizeofsubnetmasks = 10000;
           printf("Getting subnetmask block\n");
           bSuccess = RegQueryValueEx(hksub,  /* subkey handle         */
           "SubNetMask",                      /* value name            */
            NULL,                             /* must be zero          */
            NULL,                             /* value type          not required  */
            (LPBYTE) &SubNetMasks,              /* address of value data */
            &sizeofsubnetmasks);               /* length of value data  */
            if(bSuccess != ERROR_SUCCESS)
              {
               printf("Error in RegQueryValueEx fetching SubNetMask parameter!\n");
               RegCloseKey(hksub);
               return -1;
              }

          printf("subnet block: size = %d\n",sizeofsubnetmasks);
          printf("-----------------------------------------------------------\n");
          cp = SubNetMasks;
          { int i;
          for (i=0; i<(int)sizeofsubnetmasks; i++)
            { 
             printf("%c",*cp);
             ++cp;
            }
          printf("\n-----------------------------------------------------------\n");
          }
          RegCloseKey(hksub);
          /* ok now that we have some addresses and subnet masks go through each one and add to our structure... */
          /* multi_sz strings are terminated by two \0 in a row */


        ipptr = IpAddresses;
        subptr = SubNetMasks;
        Done = 0;
        while (!Done)
        {
         if (sscanf(ipptr,"%s",oneIpAddress) != EOF)
           ipptr+= strlen(oneIpAddress) + 1; /* add one for terminator \0 */
         else Done = 1;
         
         if (sscanf(subptr,"%s",oneSubNetMask) != EOF)
           subptr += strlen(oneSubNetMask) + 1;
         else Done = 1;

         /* now add to interface structure */
         if (!Done)                  
          {
           printf("IP address = %s \n",oneIpAddress);
           printf("Subnet mask = %s \n",oneSubNetMask);
           if (((char *)ipptr == '\0') || ((char *)subptr == '\0')) 
             Done = 1;
        }
          
        }
       } /* it is a network card */
      
     } /* it is/not a temparary interface */
    } /* end of loop  */
    /* now reset the length */
    return 0;
}


void main()

 {
      get_winnt_interfaces();
     
 }

