Ignore:
Timestamp:
Feb 20, 2002, 12:57:31 PM (24 years ago)
Author:
sandervl
Message:

PF: Implemented GetAdaptersInfo & GetNetworkParams

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/iphlpapi/iphlpapi.cpp

    r7264 r7973  
    1 /* $Id: iphlpapi.cpp,v 1.5 2001-10-29 13:37:29 phaller Exp $ */
     1/* $Id: iphlpapi.cpp,v 1.6 2002-02-20 11:57:31 sandervl Exp $ */
    22/*
    33 *      IPHLPAPI library
     
    1010 ****************************************************************************/
    1111
     12
     13#include <stdio.h>
    1214#include <odin.h>
    1315#include <odinwrap.h>
     
    1820
    1921#include <string.h>
    20 
    2122#include "iphlpapi.h"
     23
     24#define BSD_SELECT 1
     25#define OS2 1
     26
     27#include <types.h>
     28#include <sys\socket.h>
     29#include <sys\ioctl.h>
     30#include <net\route.h>
     31#include <net\if.h>
     32#include <net\if_arp.h>
     33#ifdef TCPV40HDRS
     34#include <netinet\in.h>
     35#include <arpa\NAMESER.H>
     36#endif
     37#include <resolv.h>
     38#include <unistd.h>
     39
     40#include "iphlwrap.h"
     41
     42#pragma pack(1)
     43typedef struct
     44{
     45        unsigned long IPAddress;
     46        unsigned short interfaceNum;
     47        unsigned long netmask;
     48        unsigned long broadcastAddress;
     49} interfaceInformation;
     50
     51/* Incomplete but will do for us */
     52
     53#ifndef TCPV40HDRS
     54struct ifnet {
     55        char    *if_name;               /* name, e.g. ``en'' or ``lo'' */
     56        short   if_unit;                /* sub-unit for lower level driver */
     57        short   if_mtu;                 /* maximum transmission unit */
     58};
     59#endif
     60
     61struct ilist {
     62  struct ilist *next;
     63  unsigned long addr;
     64};
     65
     66struct rlist {
     67  struct rlist *next;
     68  unsigned long gate;
     69  unsigned long net;
     70  unsigned long mask;
     71  char done;
     72};
     73
     74#pragma pack()
    2275
    2376ODINDEBUGCHANNEL(IPHLPAPI-IPHLPAPI)
     
    2881 ****************************************************************************/
    2982
    30 static PIP_ADAPTER_INFO pipAdapters = NULL;
    31 
    32 
    33 //******************************************************************************
    34 //******************************************************************************
     83static PIP_ADAPTER_INFO pipAdapter = NULL;
     84
     85
     86//******************************************************************************
     87//******************************************************************************
     88
     89void stringIPAddress(char* dst,u_long data)
     90{
     91    sprintf(dst, "%u.%u.%u.%u",
     92                        (char)data,
     93                        (char)(*(((char*)&data) + 1)),
     94                        (char)(*(((char*)&data) + 2)),
     95                        (char)(*(((char*)&data) + 3)));
     96}
     97
     98void stringNetmask(char* dst,u_long data)
     99{
     100   sprintf(dst,"%u.%u.%u.%u",
     101                        (char)(*(((char*)&data) + 3)),
     102                        (char)(*(((char*)&data) + 2)),
     103                        (char)(*(((char*)&data) + 1)),
     104                        (char)data);
     105}
     106
    35107static void i_initializeAdapterInformation(void)
    36108{
    37   // @@@PH
    38   // yet a fake to test some app
    39   pipAdapters = (PIP_ADAPTER_INFO)malloc (sizeof (IP_ADAPTER_INFO) );
    40  
    41   memset(pipAdapters, 0, sizeof( IP_ADAPTER_INFO ));
    42   pipAdapters->Next = NULL;
    43   pipAdapters->ComboIndex = 1;
    44   strcpy(pipAdapters->AdapterName, "ODIN IPHLPAPI Test Adapter");
    45   strcpy(pipAdapters->Description, "ODIN IPHLPAPI Test Adapter (faked information)");
    46   pipAdapters->AddressLength = 6; // MAX address
    47   pipAdapters->Address[0] = 'V';
    48   pipAdapters->Address[1] = 'P';
    49   pipAdapters->Address[2] = 'C';
    50   pipAdapters->Address[3] = 'O';
    51   pipAdapters->Address[4] = 'S';
    52   pipAdapters->Address[5] = '2';
    53   pipAdapters->Index = 16777218;
    54   pipAdapters->Type = 6;
    55   pipAdapters->DhcpEnabled = 0;
    56  
    57   static IP_ADDR_STRING iasLocalhost;
    58   iasLocalhost.Next = NULL;
    59   strcpy((char*)&iasLocalhost.IpAddress,"127.0.0.1");
    60   strcpy((char*)&iasLocalhost.IpMask, "255.0.0.0");
    61   iasLocalhost.Context = 0;
    62  
    63   static IP_ADDR_STRING iasGateway;
    64   iasGateway.Next = NULL;
    65   strcpy((char*)&iasGateway.IpAddress,"192.168.1.1");
    66   strcpy((char*)&iasGateway.IpMask, "255.255.255.0");
    67   iasGateway.Context = 0;
    68  
    69  
    70   memcpy((char*)&pipAdapters->IpAddressList, (char*)&iasLocalhost, sizeof(iasLocalhost));
    71   pipAdapters->CurrentIpAddress = &pipAdapters->IpAddressList;
    72   memcpy((char*)&pipAdapters->GatewayList,   (char*)&iasGateway, sizeof(iasGateway));
    73   memset((char*)&pipAdapters->DhcpServer, 0, sizeof( IP_ADDR_STRING ) );
    74   pipAdapters->HaveWins = 0;
    75   memset((char*)&pipAdapters->PrimaryWinsServer, 0, sizeof( IP_ADDR_STRING ) );
    76   memset((char*)&pipAdapters->SecondaryWinsServer, 0, sizeof( IP_ADDR_STRING ) );
    77   pipAdapters->LeaseObtained = 0;
    78   pipAdapters->LeaseExpires = 0;
    79 }
    80 
    81 // copy over the whole list and advance the target pointer
    82 static void i_copyIP_ADDRESS_STRING(PBYTE *ppTarget, PIP_ADDR_STRING pias)
    83 {
     109  unsigned char *p;
     110  char iShortName[6];
     111  struct rlist * rnode = NULL, * rdef = NULL;
     112  PIP_ADAPTER_INFO oldAdapter = NULL,topAdapter = NULL;
     113  struct sockaddr_in * sin;
     114  struct ifmib ifmibget;
     115  int rc,i;
     116  char *buffer,*buffer2;
     117  struct ifnet *pifnet;
     118  short int cInterfaces;
     119#ifndef TCPV40HDRS
     120  struct ortentry *r;
     121#else
     122  struct rtentry *r;
     123#endif
     124
     125  // Init Subsystem and open a socket for ioctl() calls
     126  sock_init();
     127
     128  int clientSocket = socket(PF_INET, SOCK_STREAM, 0);
     129  dprintf(("IPHLPAPI(Init): Opened socket %d\n", clientSocket));
     130
     131  // Whole buf minimum size is 65536 and memsets are really needed in other case
     132  // we will get garbage in adapter names.
     133
     134  buffer = (char*)malloc(64 * 1024);
     135  memset(buffer, 0, 65536);
     136  memset(&ifmibget,0, sizeof(struct ifmib));
     137
     138  rc = ioctl(clientSocket, SIOSTATIF, (char*)&ifmibget, sizeof(struct ifmib));
     139  dprintf(("IPHLPAPI(SIOSTATIF) ioctl returned: %d\n", rc));
     140  if (rc == -1)
     141  {
     142    free(buffer);
     143    soclose(clientSocket);         
     144    return;
     145  }       
     146
     147  rc = ioctl(clientSocket, SIOSTATAT, (char*)buffer, 65536);
     148  dprintf(("IPHLPAPI(SIOSTATAT) ioctl returned: %d\n", rc));
     149  if (rc == -1)
     150  {
     151    free(buffer);
     152    soclose(clientSocket);         
     153    return;
     154  }       
     155  cInterfaces = *(short int*)buffer;
     156  dprintf(("IPHLPAPI Call returned %d interfaces\n", cInterfaces));
     157
     158  for (int currentInterface = 0; currentInterface < cInterfaces; currentInterface++)
     159  {
     160    interfaceInformation *ifInfo = (interfaceInformation*)(buffer + 2 + (currentInterface * sizeof(interfaceInformation)));
     161    // For now let's dump only lanX and pppX adapters, loopback (?)
     162//    if (ifInfo->interfaceNum ==9) continue;
     163
     164    // Allocate and clear mem
     165    pipAdapter = (PIP_ADAPTER_INFO)malloc (sizeof (IP_ADAPTER_INFO));
     166    memset(pipAdapter, 0, sizeof(IP_ADAPTER_INFO));
     167    if (oldAdapter)
     168       oldAdapter->Next = pipAdapter;
     169
     170    pipAdapter->Next = NULL;
     171    pipAdapter->ComboIndex = 1;
     172    i =  ifInfo->interfaceNum;
     173    // Gather some other stats
     174    dprintf(("IPHLPAPI: interface number: %u\n", ifInfo->interfaceNum));
     175
     176    if (ifInfo->interfaceNum>=0 && ifInfo->interfaceNum<9) // lanX
     177       { strcpy(iShortName,"lan"); iShortName[3] = ifInfo->interfaceNum+48;
     178         iShortName[4] = 0;}
     179
     180    // I do not like this very much, but seems there is no other documented
     181    // way
     182
     183    if (strstr(ifmibget.iftable[i].ifDescr,"back")) // lo
     184        strcpy(iShortName,"lo");       
     185
     186    if (strstr(ifmibget.iftable[i].ifDescr,"ace ppp")) // pppX
     187        strcpy(iShortName,strstr(ifmibget.iftable[i].ifDescr,"ppp"));       
     188
     189    if (strstr(ifmibget.iftable[i].ifDescr,"ace sl")) // slX
     190        strcpy(iShortName,strstr(ifmibget.iftable[i].ifDescr,"sl"));       
     191
     192    if (strstr(ifmibget.iftable[i].ifDescr,"ace dod")) // dodX
     193        strcpy(iShortName,strstr(ifmibget.iftable[i].ifDescr,"dod"));       
     194
     195    dprintf(("IPHLPAPI: interface name[%s] : %s\n",iShortName, ifmibget.iftable[i].ifDescr));
     196    strcpy(pipAdapter->AdapterName, ifmibget.iftable[i].ifDescr);
     197    strcpy(pipAdapter->Description, ifmibget.iftable[i].ifDescr);
     198         
     199    pipAdapter->AddressLength = 6; // MAX address
     200    memcpy(pipAdapter->Address,ifmibget.iftable[i].ifPhysAddr,6);
     201    pipAdapter->Index = ifmibget.iftable[i].ifIndex;
     202    pipAdapter->Type = ifmibget.iftable[i].ifType; // Careful with this (?)
     203    pipAdapter->DhcpEnabled = 0; // Also a question
     204 
     205    // TODO: Adapter may support multiple IP addrs
     206    IP_ADDR_STRING iasAdapterIP;
     207    iasAdapterIP.Next = NULL;
     208    stringIPAddress((char*)&iasAdapterIP.IpAddress,ifInfo->IPAddress);
     209    stringNetmask((char*)&iasAdapterIP.IpMask,ifInfo->netmask);
     210    iasAdapterIP.Context = 0;
     211 
     212    // Now we are going to catch gateways for this interface 
     213    buffer2 = (char*) malloc(64*1024);   
     214    memset(buffer2, 0, 65536);
     215   
     216    rc = ioctl(clientSocket, SIOSTATRT, (char*)buffer2, 65536);
     217    dprintf(("IPHLPAPI(SIOSTATRT):ioctl returned: %d\n", rc));
     218
     219    if (rc == -1)
     220    {
     221      free(buffer);
     222      free(buffer2);
     223      soclose(clientSocket);       
     224      // better return nothing than some trash, unwinding and freeing
     225      for (topAdapter; pipAdapter; topAdapter = pipAdapter) {
     226          pipAdapter = topAdapter -> Next;
     227          free(topAdapter);
     228      }
     229      return;
     230     }       
     231         
     232     rtentries *routeEntries = (rtentries*)buffer2;
     233     p = (unsigned char *)&routeEntries->rttable[0];
     234
     235     IP_ADDR_STRING iasGateway;   
     236     memset(&iasGateway,0,sizeof(iasGateway));
     237
     238     for (int currentRoute = 0; currentRoute < (routeEntries->hostcount+routeEntries->netcount); currentRoute++)
     239     {
     240     // First check if this route is for our interface   
     241#ifndef TCPV40HDRS
     242         r = (struct ortentry *) (p);
     243#else
     244         r = (struct rtentry *) (p);
     245#endif
     246         if (strcmp((const char*)(p + sizeof(struct rtentry)),iShortName)==0)
     247         {
     248            sin = (struct sockaddr_in *)(&r->rt_dst);
     249            if (strcmp(inet_ntoa(sin->sin_addr),"0.0.0.0")==0)
     250            { 
     251               iasGateway.Next = NULL;
     252               // TODO : Some systems may have many gateways   
     253               sin = (struct sockaddr_in *)(&r->rt_gateway);
     254               strcpy(iasGateway.IpAddress.String,inet_ntoa(sin->sin_addr));
     255               sin = (struct sockaddr_in *)&p[-4];
     256               strcpy(iasGateway.IpMask.String,inet_ntoa(sin->sin_addr));
     257               iasGateway.Context = 0;
     258            }
     259         }
     260#ifndef TCPV40HDRS
     261       p+=sizeof(struct ortentry);
     262#else
     263       p+=sizeof(struct rtentry);
     264#endif
     265       p+=strlen((char *)p)+1;
     266    }
     267 
     268  memcpy((char*)&pipAdapter->IpAddressList, (char*)&iasAdapterIP, sizeof(iasAdapterIP));
     269  pipAdapter->CurrentIpAddress = &pipAdapter->IpAddressList;
     270  memcpy((char*)&pipAdapter->GatewayList,   (char*)&iasGateway, sizeof(iasGateway));
     271  // what about OS/2 DHCP?
     272  memset((char*)&pipAdapter->DhcpServer, 0, sizeof( IP_ADDR_STRING ) );
     273  pipAdapter->HaveWins = 0;
     274  memset((char*)&pipAdapter->PrimaryWinsServer, 0, sizeof( IP_ADDR_STRING ) );
     275  memset((char*)&pipAdapter->SecondaryWinsServer, 0, sizeof( IP_ADDR_STRING ) );
     276  pipAdapter->LeaseObtained = 0;
     277  pipAdapter->LeaseExpires = 0;
     278  if (!topAdapter) topAdapter = pipAdapter;
     279  oldAdapter = pipAdapter;
     280 }
     281 pipAdapter = topAdapter;
     282
     283 // Cleanup
     284 if (buffer) free(buffer);
     285 if (buffer2) free(buffer2);
     286 soclose(clientSocket);
     287}
     288
     289// copy over the whole list and advance the target pointer and correct new list
     290static void i_copyIP_ADDRESS_STRING(PBYTE *ppTarget, PIP_ADDR_STRING pstruct,PIP_ADDR_STRING pias)
     291{
     292  PIP_ADDR_STRING dummy = NULL;
     293  // We already have this copied
     294  pias = pias -> Next;
    84295  while (pias)
    85296  {
    86297    memcpy(*ppTarget, pias, sizeof( IP_ADDR_STRING ) );
     298    pstruct->Next = (PIP_ADDR_STRING) *ppTarget;
    87299    *ppTarget += sizeof ( IP_ADDR_STRING );
    88300    pias = pias->Next;
    89   }
     301    pstruct = pstruct->Next;
     302  }
     303}
     304
     305static DWORD i_sizeOfFIXED_INFO(PFIXED_INFO pinfo)
     306{
     307 PIP_ADDR_STRING pias;
     308
     309 DWORD dwRequired = sizeof( FIXED_INFO );
     310 
     311 // follow the IP_ADDR_STRING lists
     312 pias = &pinfo->DnsServerList;
     313 while( pias )
     314 {
     315   dwRequired += sizeof( IP_ADDR_STRING );
     316   pias = pias->Next;
     317 }
     318 return dwRequired;
    90319}
    91320
     
    147376              PULONG,           pOutBufLen)
    148377{
    149   dprintf(("GetAdaptersInfo incorrectly implemented"));
    150  
     378  dprintf(("GetAdaptersInfo API called"));
     379  dprintf(("Address passed is %p",pAdapterInfo));
    151380  if (NULL == pOutBufLen)
    152381    return ERROR_INVALID_PARAMETER;
     
    156385    return ERROR_INVALID_PARAMETER;
    157386 
    158   if (NULL == pipAdapters)
     387  if (NULL == pipAdapter)
    159388  {
    160389    // gather the information and save it
    161390    i_initializeAdapterInformation();
    162    
    163     // determine number of IP adapters (interfaces) in the system
    164    
    165     // os2_ioctl() SIOSTATIF42
    166   }
    167  
    168   if (NULL == pipAdapters)
     391  }
     392 
     393  if (NULL == pipAdapter)
    169394    return ERROR_NO_DATA;
    170395 
     
    177402  DWORD dwRequiredBuffer = 0;
    178403 
    179   for( pip = pipAdapters ; pip ; pip = pip->Next )
     404  for( pip = pipAdapter ; pip ; pip = pip->Next )
    180405  {
    181406    // check for sufficient space
     
    183408  }
    184409 
    185   for( pip = pipAdapters ; pip ; pip = pip->Next )
     410  for( pip = pipAdapter ; pip ; pip = pip->Next )
    186411  {
    187412    // check for sufficient space
     
    195420      memcpy(pTarget, pip, sizeof( IP_ADAPTER_INFO ));
    196421      pTarget += sizeof( IP_ADAPTER_INFO );
    197      
    198       // @@@PH shall point to somewhere within the current buffer
    199       pip->CurrentIpAddress = (PIP_ADDR_STRING)pTarget;
    200      
    201       i_copyIP_ADDRESS_STRING(&pTarget, &pip->IpAddressList);
    202       i_copyIP_ADDRESS_STRING(&pTarget, &pip->GatewayList);
    203       i_copyIP_ADDRESS_STRING(&pTarget, &pip->DhcpServer);
    204       i_copyIP_ADDRESS_STRING(&pTarget, &pip->PrimaryWinsServer);
    205       i_copyIP_ADDRESS_STRING(&pTarget, &pip->SecondaryWinsServer);
     422       
     423      // point to currentIPAddress
     424      ((PIP_ADAPTER_INFO)(pTarget))->CurrentIpAddress = &((PIP_ADAPTER_INFO)(pTarget))->IpAddressList;
     425      //@@PF Need to fix lots of stuff here
     426//      i_copyIP_ADDRESS_STRING(&pTarget, &pip->IpAddressList);
     427//      i_copyIP_ADDRESS_STRING(&pTarget, &pip->GatewayList);
     428//      i_copyIP_ADDRESS_STRING(&pTarget, &pip->DhcpServer);
     429//      i_copyIP_ADDRESS_STRING(&pTarget, &pip->PrimaryWinsServer);
     430//      i_copyIP_ADDRESS_STRING(&pTarget, &pip->SecondaryWinsServer);
    206431    }
    207432    else
     
    212437    }
    213438  }
    214  
    215439  return ERROR_SUCCESS;
    216440}
     
    223447              PULONG,      pOutBufLen)
    224448{
    225   dprintf(("GetNetworkParams not implemented"));
    226   return ERROR_NOT_SUPPORTED; //NT returns this
    227 }
    228 //******************************************************************************
    229 //******************************************************************************
    230 
     449  struct sockaddr_in * sin;
     450  FIXED_INFO fi;
     451  DWORD memNeeded;
     452  PIP_ADDR_STRING dnslist = NULL, pdnslist = NULL;
     453
     454  // This is dynamically updated info
     455  res_init();
     456  memset(&fi,0,sizeof(FIXED_INFO));
     457
     458  dprintf(("GetNetworkParams pFixedInfo:%x pOutBufLen:%d",pFixedInfo,*pOutBufLen));
     459
     460  gethostname(fi.HostName,128);
     461  strcpy(fi.DomainName,_res.defdname);
     462
     463  // For VPC DNS Servers are pretty much enough for now
     464  fi.CurrentDnsServer = &fi.DnsServerList;   
     465  dnslist = &fi.DnsServerList;
     466  pdnslist = dnslist;
     467
     468  for (int i = 0; i<_res.nscount; i++)
     469  {
     470      if (!dnslist)   
     471      {
     472          dnslist = (PIP_ADDR_STRING) malloc(sizeof(IP_ADDR_STRING));
     473          memset(dnslist,0,sizeof(IP_ADDR_STRING));
     474          pdnslist->Next = dnslist;
     475      }
     476      sin = (struct sockaddr_in *)&_res.nsaddr_list[i];               
     477      strcpy(dnslist->IpAddress.String,inet_ntoa(sin->sin_addr));
     478      dnslist->Context = 0;
     479      dprintf(("IPHLPAPI: GetNetworkParams Adding DNS Server %s",inet_ntoa(sin->sin_addr)));
     480      pdnslist = dnslist;
     481      dnslist = dnslist->Next;
     482  }     
     483  fi.EnableDns = 1;
     484  // NodeType (?)
     485  memNeeded = i_sizeOfFIXED_INFO(&fi);
     486  LONG buflen = *pOutBufLen;
     487  PBYTE pTarget        = (PBYTE)pFixedInfo;
     488  if (((LONG)(buflen - memNeeded)) > 0)
     489  {
     490    // copy over the whole structure hierarchy
     491    memcpy(pTarget, &fi, sizeof( FIXED_INFO ));
     492    pTarget += sizeof( FIXED_INFO );
     493    i_copyIP_ADDRESS_STRING(&pTarget, &pFixedInfo->DnsServerList,&fi.DnsServerList);
     494  }
     495  else
     496  {
     497   // return overall size of required buffer
     498   *pOutBufLen = memNeeded;
     499   return ERROR_BUFFER_OVERFLOW;
     500  }
     501
     502 //cleanup
     503 pdnslist = fi.DnsServerList.Next;
     504 while( pdnslist )
     505 {
     506   dnslist = pdnslist->Next;
     507   free(pdnslist);
     508   pdnslist = dnslist;
     509 }
     510
     511 return ERROR_SUCCESS;
     512}
     513//******************************************************************************
     514//******************************************************************************
    231515
    232516DWORD AddIPAddress(IPAddr Address, // IP address to add
Note: See TracChangeset for help on using the changeset viewer.