source: trunk/src/iphlpapi/iphlpapi.cpp@ 21563

Last change on this file since 21563 was 21563, checked in by dmik, 15 years ago

iphlpapi: Fixed a crash when building the adapter/interface/address tables due to a bogus ioctl(SIOSTATRT) implementation in OS/2.

File size: 23.2 KB
Line 
1/* $Id: iphlpapi.cpp,v 1.15 2003-05-05 15:26:03 sandervl Exp $ */
2/*
3 * IPHLPAPI library
4 *
5 */
6
7
8/****************************************************************************
9 * includes
10 ****************************************************************************/
11
12
13#include <stdio.h>
14#include <odin.h>
15#include <odinwrap.h>
16#include <os2sel.h>
17
18#include <os2win.h>
19#include <winversion.h>
20
21#include <string.h>
22#include <iprtrmib.h>
23#include <winnls.h>
24
25#define BSD_SELECT 1
26#define OS2 1
27
28#include <types.h>
29#include <sys/socket.h>
30#include <sys/ioctl.h>
31#include <net/route.h>
32#include <net/if.h>
33#include <net/if_arp.h>
34#ifdef TCPV40HDRS
35#include <netinet/in.h>
36#include <arpa/NAMESER.H>
37#endif
38#include <resolv.h>
39#include <unistd.h>
40
41#include "iphlwrap.h"
42
43/* from ipexport.h */
44typedef ULONG IPAddr;
45typedef ULONG IPMask;
46typedef ULONG IP_STATUS;
47
48#pragma pack(1)
49
50typedef struct
51{
52 unsigned long IPAddress;
53 unsigned short interfaceIndex;
54 unsigned long netmask;
55 unsigned long broadcastAddress;
56}
57AddrInfo;
58
59#pragma pack()
60
61//We don't want to use the OS2 version directly, but the one in wsock32
62int WIN32API ODIN_gethostname (char * name, int namelen);
63
64ODINDEBUGCHANNEL(IPHLPAPI-IPHLPAPI)
65
66
67/****************************************************************************
68 * module global variables
69 ****************************************************************************/
70
71static PIP_ADAPTER_INFO pipAdapter = NULL;
72static PMIB_IFTABLE pmibTable = NULL;
73static PMIB_IPADDRTABLE pmipaddrTable = NULL;
74
75//******************************************************************************
76//******************************************************************************
77
78void stringIPAddress(char* dst,u_long data)
79{
80 sprintf(dst, "%u.%u.%u.%u",
81 (char)data,
82 (char)(*(((char*)&data) + 1)),
83 (char)(*(((char*)&data) + 2)),
84 (char)(*(((char*)&data) + 3)));
85}
86
87static void i_initializeAdapterInformation(void)
88{
89 char iShortName[8];
90 PIP_ADAPTER_INFO oldAdapter = NULL, topAdapter = NULL;
91 int rc;
92 char *buffer = NULL, *buffer2 = NULL;
93 struct ifmib ifmibget;
94 int cAddresses;
95 AddrInfo *addrInfo;
96 struct rtentries *rtentries;
97
98 // Init Subsystem and open a socket for ioctl() calls
99 sock_init();
100
101 int clientSocket = socket(PF_INET, SOCK_STREAM, 0);
102 dprintf(("IPHLPAPI: Init: Opened socket %d\n", clientSocket));
103
104 // Whole buf minimum size is 65536 and memsets are really needed in other case
105 // we will get garbage in adapter names.
106
107 memset(&ifmibget,0, sizeof(struct ifmib));
108 buffer = (char*) malloc(65536);
109 memset(buffer, 0, 65536);
110 buffer2 = (char*) malloc(65536);
111 memset(buffer2, 0, 65536);
112
113 rc = ioctl(clientSocket, SIOSTATIF, (char*)&ifmibget, sizeof(struct ifmib));
114 dprintf(("IPHLPAPI: ioctl(SIOSTATIF) returned: %d\n", rc));
115 if (rc == -1)
116 {
117 free(buffer2);
118 free(buffer);
119 soclose(clientSocket);
120 return;
121 }
122 dprintf(("IPHLPAPI: ioctl(SIOSTATIF) returned %d interfaces\n", ifmibget.ifNumber));
123
124 rc = ioctl(clientSocket, SIOSTATAT, buffer, 65536);
125 dprintf(("IPHLPAPI: ioctl(SIOSTATAT) returned: %d\n", rc));
126 if (rc == -1)
127 {
128 free(buffer2);
129 free(buffer);
130 soclose(clientSocket);
131 return;
132 }
133 cAddresses = *(short int *) buffer;
134 addrInfo = (AddrInfo *) (buffer + sizeof(short int));
135 dprintf(("IPHLPAPI: ioctl(SIOSTATAT) returned %d addresses\n", cAddresses));
136
137 rc = ioctl(clientSocket, SIOSTATRT, buffer2, 65536);
138 dprintf(("IPHLPAPI: ioctl(SIOSTATRT) returned: %d\n", rc));
139 if (rc == -1)
140 {
141 free(buffer2);
142 free(buffer);
143 soclose(clientSocket);
144 return;
145 }
146 rtentries = (struct rtentries *) buffer2;
147 dprintf(("IPHLPAPI: ioctl(SIOSTATRT) returned %d host and %d net routes\n",
148 rtentries->hostcount, rtentries->netcount));
149
150 pmibTable = (PMIB_IFTABLE) malloc(ifmibget.ifNumber * sizeof(MIB_IFTABLE));
151 memset(pmibTable, 0, ifmibget.ifNumber * sizeof(MIB_IFTABLE));
152 pmibTable->dwNumEntries = ifmibget.ifNumber;
153
154 pmipaddrTable = (PMIB_IPADDRTABLE) malloc(cAddresses * sizeof(MIB_IPADDRTABLE));
155 memset(pmipaddrTable, 0, cAddresses * sizeof(MIB_IPADDRTABLE));
156 pmipaddrTable->dwNumEntries = cAddresses;
157
158 // loop over interfaces
159 int idx, i;
160 for (i = idx = 0; i < IFMIB_ENTRIES && idx < ifmibget.ifNumber; ++i)
161 {
162 // skip empty interface entries
163 if (ifmibget.iftable[i].ifType == 0)
164 continue;
165
166 short ifIndex = ifmibget.iftable[i].ifIndex;
167 dprintf(("IPHLPAPI: interface index: %u\n", ifIndex));
168
169 // Guess the symbolic interface name. I do not like this very much, but
170 // seems there is no other documented way
171
172 if (ifIndex >= 0 && ifIndex < 9) // lanX
173 {
174 strcpy(iShortName,"lan");
175 iShortName[3] = ifIndex + 48;
176 iShortName[4] = 0;
177 }
178 else
179 if (strstr(ifmibget.iftable[i].ifDescr, "back")) // loopback
180 {
181 strcpy(iShortName,"lo");
182 }
183 else
184 if (strstr(ifmibget.iftable[i].ifDescr, "ace ppp")) // pppX
185 {
186 strcpy(iShortName, strstr(ifmibget.iftable[i].ifDescr, "ppp"));
187 }
188 else
189 if (strstr(ifmibget.iftable[i].ifDescr,"ace sl")) // slX
190 {
191 strcpy(iShortName,strstr(ifmibget.iftable[i].ifDescr, "sl"));
192 }
193 else
194 if (strstr(ifmibget.iftable[i].ifDescr,"ace dod")) // dodX
195 {
196 strcpy(iShortName,strstr(ifmibget.iftable[i].ifDescr, "dod"));
197 }
198 else // something else...
199 {
200 strcpy(iShortName,"unk");
201 iShortName[3] = ifIndex + 48;
202 iShortName[4] = 0;
203 }
204
205 dprintf(("IPHLPAPI: interface name: %s [%s]\n", iShortName,
206 ifmibget.iftable[i].ifDescr));
207
208 // Allocate the adapter info entry
209 pipAdapter = (PIP_ADAPTER_INFO)malloc (sizeof(IP_ADAPTER_INFO));
210 memset(pipAdapter, 0, sizeof(IP_ADAPTER_INFO));
211 if (oldAdapter)
212 oldAdapter->Next = pipAdapter;
213
214 // Fill the adapter info entry
215 pipAdapter->Next = NULL;
216 pipAdapter->ComboIndex = 1; // unused according to MSDN
217 strcpy(pipAdapter->AdapterName, ifmibget.iftable[i].ifDescr);
218 strcpy(pipAdapter->Description, ifmibget.iftable[i].ifDescr);
219
220 pipAdapter->AddressLength = sizeof(ifmibget.iftable[i].ifPhysAddr);
221 memcpy(pipAdapter->Address,ifmibget.iftable[i].ifPhysAddr, sizeof(ifmibget.iftable[i].ifPhysAddr));
222 pipAdapter->Index = ifIndex;
223 pipAdapter->Type = ifmibget.iftable[i].ifType; // Careful with this (?)
224
225 // what about OS/2 DHCP?
226 pipAdapter->DhcpEnabled = 0; // Also a question
227 memset((char*)&pipAdapter->DhcpServer, 0, sizeof(IP_ADDR_STRING));
228
229 pipAdapter->HaveWins = 0;
230 memset((char*)&pipAdapter->PrimaryWinsServer, 0, sizeof(IP_ADDR_STRING));
231 memset((char*)&pipAdapter->SecondaryWinsServer, 0, sizeof(IP_ADDR_STRING));
232 pipAdapter->LeaseObtained = 0;
233 pipAdapter->LeaseExpires = 0;
234
235 // Fill the interface table entry
236 MultiByteToWideChar(CP_ACP, 0, iShortName, strlen(iShortName),
237 pmibTable->table[idx].wszName,
238 MAX_INTERFACE_NAME_LEN);
239
240 pmibTable->table[idx].dwIndex = ifIndex;
241 pmibTable->table[idx].dwType = ifmibget.iftable[i].ifType;
242 pmibTable->table[idx].dwMtu = ifmibget.iftable[i].ifMtu;
243 pmibTable->table[idx].dwSpeed = ifmibget.iftable[i].ifSpeed;
244
245 pmibTable->table[idx].dwPhysAddrLen = sizeof(ifmibget.iftable[i].ifPhysAddr);
246 memcpy(pmibTable->table[idx].bPhysAddr, ifmibget.iftable[i].ifPhysAddr,
247 sizeof(ifmibget.iftable[i].ifPhysAddr));
248
249 pmibTable->table[idx].dwAdminStatus =
250 (ifmibget.iftable[i].ifOperStatus == IFF_UP) ?
251 MIB_IF_ADMIN_STATUS_UP : MIB_IF_ADMIN_STATUS_DOWN;
252 pmibTable->table[idx].dwOperStatus =
253 (ifmibget.iftable[i].ifOperStatus == IFF_UP) ?
254 MIB_IF_OPER_STATUS_OPERATIONAL : MIB_IF_OPER_STATUS_NON_OPERATIONAL;
255
256 pmibTable->table[idx].dwLastChange = ifmibget.iftable[i].ifLastChange;
257 pmibTable->table[idx].dwInOctets = ifmibget.iftable[i].ifInOctets;
258 pmibTable->table[idx].dwInUcastPkts = ifmibget.iftable[i].ifInUcastPkts;
259 pmibTable->table[idx].dwInNUcastPkts = ifmibget.iftable[i].ifInNUcastPkts;
260 pmibTable->table[idx].dwInDiscards = ifmibget.iftable[i].ifInDiscards;
261 pmibTable->table[idx].dwInErrors = ifmibget.iftable[i].ifInErrors;
262 pmibTable->table[idx].dwInUnknownProtos = ifmibget.iftable[i].ifInUnknownProtos;
263 pmibTable->table[idx].dwOutOctets = ifmibget.iftable[i].ifOutOctets;
264 pmibTable->table[idx].dwOutUcastPkts = ifmibget.iftable[i].ifOutUcastPkts;
265 pmibTable->table[idx].dwOutNUcastPkts = ifmibget.iftable[i].ifOutNUcastPkts;
266 pmibTable->table[idx].dwOutDiscards = ifmibget.iftable[i].ifOutDiscards;
267 pmibTable->table[idx].dwOutErrors = ifmibget.iftable[i].ifOutErrors;
268 pmibTable->table[idx].dwOutQLen = 0; // unused according to MSDN
269
270 pmibTable->table[idx].dwDescrLen = strlen(ifmibget.iftable[i].ifDescr);
271 strncpy((char *)pmibTable->table[idx].bDescr, ifmibget.iftable[i].ifDescr,
272 sizeof(pmibTable->table[idx].bDescr));
273
274 // fill pipAdapter->IpAddressList
275 int cIfAddresses = 0;
276 for (int j = 0; j < cAddresses; ++j)
277 {
278#ifdef DEBUG
279 if (i == 0) // print only once
280 {
281 dprintf(("IPHLPAPI: ADDR %d:", j));
282 dprintf(("IPHLPAPI: IPAddress 0x%08X", addrInfo[j].IPAddress));
283 dprintf(("IPHLPAPI: interfaceIndex %d", addrInfo[j].interfaceIndex));
284 dprintf(("IPHLPAPI: netmask 0x%08X", addrInfo[j].netmask));
285 dprintf(("IPHLPAPI: broadcastAddress 0x%08X", addrInfo[j].broadcastAddress));
286 }
287#endif
288 if (addrInfo[j].interfaceIndex == ifIndex)
289 {
290 ++cIfAddresses;
291
292 IP_ADDR_STRING *addr;
293 if (cIfAddresses == 1)
294 {
295 addr = &pipAdapter->IpAddressList;
296 }
297 else
298 {
299 addr->Next = (IP_ADDR_STRING*) malloc(sizeof(IP_ADDR_STRING));
300 addr = addr->Next;
301 }
302
303 memset((char *) addr, 0, sizeof(IP_ADDR_STRING));
304 addr->Next = NULL;
305 stringIPAddress(addr->IpAddress.String, addrInfo[j].IPAddress);
306 // mask is in network byte order for some reason
307 stringIPAddress(addr->IpMask.String, ntohl(addrInfo[j].netmask));
308 addr->Context = 0;
309 }
310 }
311
312 // fill pipAdapter->GatewayList
313 int cIfGateways = 0;
314 struct rtentry *rtentry = rtentries->rttable;
315 for (j = 0; j < rtentries->hostcount + rtentries->netcount; ++j)
316 {
317#ifdef DEBUG
318 if (i == 0) // print only once
319 {
320 dprintf(("IPHLPAPI: RTENTRY %d:", j));
321 dprintf(("IPHLPAPI: rt_hash 0x%08X", rtentry->rt_hash));
322 dprintf(("IPHLPAPI: rt_dst 0x%08X", ((struct sockaddr_in *)(&rtentry->rt_dst))->sin_addr.s_addr));
323 dprintf(("IPHLPAPI: rt_gateway 0x%08X", ((struct sockaddr_in *)(&rtentry->rt_gateway))->sin_addr.s_addr));
324 dprintf(("IPHLPAPI: rt_flags 0x%08X", rtentry->rt_flags));
325 dprintf(("IPHLPAPI: rt_refcnt %d", rtentry->rt_refcnt));
326 dprintf(("IPHLPAPI: rt_use %d", rtentry->rt_use));
327 dprintf(("IPHLPAPI: rt_ifp 0x%p", rtentry->rt_ifp));
328 //dprintf(("IPHLPAPI: if_name %s", rtentry->rt_ifp->if_name));
329 dprintf(("IPHLPAPI: metric1 %d", rtentry->metric1));
330 dprintf(("IPHLPAPI: metric2 %d", rtentry->metric2));
331 dprintf(("IPHLPAPI: metric3 %d", rtentry->metric3));
332 dprintf(("IPHLPAPI: metric4 %d", rtentry->metric4));
333 }
334#endif
335 // only take default gateways for this interface
336#if 1
337 // rtentry->rt_ifp is (always?) a high address (0xFxxxxxxx) and for
338 // some reason reading it causes an access violation on some systems
339 // while works great on other systems. I don't know why. Luckily
340 // (luckily???), the definition of struct rtentries in headers is
341 // wrong -- each entry in the rtentries::rttable array is
342 // additionally followed by an ASCIIZ string containing the
343 // interface name. And the interface name is what we need. Owse.
344 char *if_name = (char *)(rtentry + 1);
345 dprintf(("IPHLPAPI: if_name %s", if_name));
346
347 if (strcmp(if_name, iShortName) == 0 &&
348#else
349 if (strcmp(rtentry->rt_ifp->if_name, iShortName) == 0 &&
350#endif
351 ((struct sockaddr_in *)(&rtentry->rt_dst))->sin_addr.s_addr == 0)
352 {
353 ++cIfGateways;
354
355 IP_ADDR_STRING *addr;
356 if (cIfGateways == 1)
357 {
358 addr = &pipAdapter->GatewayList;
359 }
360 else
361 {
362 addr->Next = (IP_ADDR_STRING *) malloc(sizeof(IP_ADDR_STRING));
363 addr = addr->Next;
364 }
365
366 memset((char *) addr, 0, sizeof(IP_ADDR_STRING));
367 addr->Next = NULL;
368 struct sockaddr_in * sin =
369 (struct sockaddr_in *)(&rtentry->rt_gateway);
370 strcpy((char *) &addr->IpAddress.String, inet_ntoa(sin->sin_addr));
371 strcpy((char *) &addr->IpMask.String, "255.255.255.255");
372 addr->Context = 0;
373 }
374
375 // Compensate for the interface name following the rtentry
376 ++rtentry;
377 rtentry = (struct rtentry *)
378 (((char *) rtentry) + strlen(((char *) rtentry)) + 1);
379 }
380
381
382 // loop over
383 if (!topAdapter)
384 topAdapter = pipAdapter;
385 oldAdapter =
386 pipAdapter;
387
388 ++idx;
389 }
390 pipAdapter = topAdapter;
391
392 // loop over addressees to fill pmipaddrTable
393 for (i = 0; i < cAddresses; ++i)
394 {
395 // skip addresses referring to empty interface entries
396 if (addrInfo[i].interfaceIndex >= IFMIB_ENTRIES ||
397 ifmibget.iftable[addrInfo[i].interfaceIndex].ifType == 0)
398 continue;
399
400 pmipaddrTable->table[i].dwAddr = addrInfo[i].IPAddress;
401 pmipaddrTable->table[i].dwIndex = addrInfo[i].interfaceIndex;
402 // mask is in network byte order for some reason
403 pmipaddrTable->table[i].dwMask = ntohl(addrInfo[i].netmask);
404 pmipaddrTable->table[i].dwBCastAddr = addrInfo[i].broadcastAddress;
405 pmipaddrTable->table[i].dwReasmSize = 0; // ?
406 }
407
408 // current address is the first address so far
409 pipAdapter->CurrentIpAddress = &pipAdapter->IpAddressList;
410
411 // Cleanup
412 soclose(clientSocket);
413 free(buffer2);
414 free(buffer);
415}
416
417// copy over the whole list and advance the target pointer and correct new list
418static void i_copyIP_ADDRESS_STRING(PBYTE *ppTarget, PIP_ADDR_STRING pstruct,PIP_ADDR_STRING pias)
419{
420 PIP_ADDR_STRING dummy = NULL;
421 // We already have this copied
422 pias = pias -> Next;
423 while (pias)
424 {
425 memcpy(*ppTarget, pias, sizeof( IP_ADDR_STRING ) );
426 pstruct->Next = (PIP_ADDR_STRING) *ppTarget;
427 *ppTarget += sizeof ( IP_ADDR_STRING );
428 pias = pias->Next;
429 pstruct = pstruct->Next;
430 }
431}
432
433static DWORD i_sizeOfIP_ADAPTER_INFO(PIP_ADAPTER_INFO piai)
434{
435 PIP_ADDR_STRING pias;
436
437 // check for sufficient space
438 DWORD dwRequired = sizeof( IP_ADAPTER_INFO );
439
440 // follow the IP_ADDR_STRING lists
441 pias = &piai->IpAddressList;
442 while( pias )
443 {
444 dwRequired += sizeof( IP_ADDR_STRING );
445 pias = pias->Next;
446 }
447
448 pias = &piai->GatewayList;
449 while( pias )
450 {
451 dwRequired += sizeof( IP_ADDR_STRING );
452 pias = pias->Next;
453 }
454
455 pias = &piai->DhcpServer;
456 while( pias )
457 {
458 dwRequired += sizeof( IP_ADDR_STRING );
459 pias = pias->Next;
460 }
461
462 pias = &piai->PrimaryWinsServer;
463 while( pias )
464 {
465 dwRequired += sizeof( IP_ADDR_STRING );
466 pias = pias->Next;
467 }
468
469 pias = &piai->SecondaryWinsServer;
470 while( pias )
471 {
472 dwRequired += sizeof( IP_ADDR_STRING );
473 pias = pias->Next;
474 }
475
476 return dwRequired;
477}
478
479
480//******************************************************************************
481//******************************************************************************
482
483// Note: returns error 50 under NT4 (NOT_SUPPORTED)
484// so we better check out alternative ways, too.
485
486ODINFUNCTION2(DWORD, GetAdaptersInfo,
487 PIP_ADAPTER_INFO, pAdapterInfo,
488 PULONG, pOutBufLen)
489{
490 dprintf(("GetAdaptersInfo API called"));
491 dprintf(("Address passed is %p",pAdapterInfo));
492 if (NULL == pOutBufLen)
493 return ERROR_INVALID_PARAMETER;
494
495 // verify first block of memory to write to
496 if (IsBadWritePtr(pAdapterInfo, 4))
497 return ERROR_INVALID_PARAMETER;
498
499 if (NULL == pipAdapter)
500 {
501 // gather the information and save it
502 i_initializeAdapterInformation();
503 }
504
505 if (NULL == pipAdapter)
506 return ERROR_NO_DATA;
507
508 // OK, just copy over the information as far as possible
509 LONG lSpaceLeft = *pOutBufLen;
510 PBYTE pTarget = (PBYTE)pAdapterInfo;
511 PIP_ADAPTER_INFO pip;
512
513 // calculate overall required buffer size
514 DWORD dwRequiredBuffer = 0;
515
516 for( pip = pipAdapter ; pip ; pip = pip->Next )
517 {
518 // check for sufficient space
519 dwRequiredBuffer += i_sizeOfIP_ADAPTER_INFO(pip);
520 }
521
522 for( pip = pipAdapter ; pip ; pip = pip->Next )
523 {
524 // check for sufficient space
525 DWORD dwRequired = i_sizeOfIP_ADAPTER_INFO(pip);
526
527 lSpaceLeft -= dwRequired;
528 if (lSpaceLeft >= 0)
529 {
530 // @PF revised - this thing works because we currently do not support
531 // multi-ip, multi-gateway or multi-DHCP servers lists
532 // TODO - add lists support
533 memcpy(pTarget, pip, sizeof( IP_ADAPTER_INFO ));
534 // point to currentIPAddress
535 ((PIP_ADAPTER_INFO)(pTarget))->CurrentIpAddress = &((PIP_ADAPTER_INFO)(pTarget))->IpAddressList;
536 pTarget += sizeof( IP_ADAPTER_INFO );
537
538// i_copyIP_ADDRESS_STRING(&pTarget, &pip->IpAddressList);
539// i_copyIP_ADDRESS_STRING(&pTarget, &pip->GatewayList);
540// i_copyIP_ADDRESS_STRING(&pTarget, &pip->DhcpServer);
541// i_copyIP_ADDRESS_STRING(&pTarget, &pip->PrimaryWinsServer);
542// i_copyIP_ADDRESS_STRING(&pTarget, &pip->SecondaryWinsServer);
543 }
544 else
545 {
546 // return overall size of required buffer
547 *pOutBufLen = dwRequiredBuffer;
548 return ERROR_BUFFER_OVERFLOW;
549 }
550 }
551 return ERROR_SUCCESS;
552}
553
554
555//******************************************************************************
556//******************************************************************************
557ODINFUNCTION2(DWORD, GetNetworkParams,
558 PFIXED_INFO, pFixedInfo,
559 PULONG, pOutBufLen)
560{
561 struct sockaddr_in * sin;
562 PFIXED_INFO fi = pFixedInfo;
563 DWORD memNeeded;
564 PIP_ADDR_STRING dnslist = NULL, pdnslist = NULL;
565
566 dprintf(("GetNetworkParams pFixedInfo:%x pOutBufLen:%d",pFixedInfo,*pOutBufLen));
567 res_init();
568
569 // Check how much mem we will need
570 memNeeded = sizeof(FIXED_INFO)+_res.nscount*sizeof(IP_ADDR_STRING);
571
572 if (((LONG)(*pOutBufLen - memNeeded)) < 0)
573 {
574 // return overall size of required buffer
575 *pOutBufLen = memNeeded;
576 return ERROR_BUFFER_OVERFLOW;
577 }
578
579 // This is dynamically updated info
580 memset(pFixedInfo,0,memNeeded);
581
582 ODIN_gethostname(fi->HostName,128);
583 strcpy(fi->DomainName,_res.defdname);
584
585 // Fill in DNS Servers
586 fi->CurrentDnsServer = &fi->DnsServerList;
587 dnslist = &fi->DnsServerList;
588
589 for (int i = 0; i<_res.nscount; i++)
590 {
591 if (pdnslist) pdnslist->Next = dnslist;
592 sin = (struct sockaddr_in *)&_res.nsaddr_list[i];
593 strcpy(dnslist->IpAddress.String,inet_ntoa(sin->sin_addr));
594 dprintf(("IPHLPAPI: GetNetworkParams Adding DNS Server %s",inet_ntoa(sin->sin_addr)));
595 pdnslist = dnslist;
596 if ( pdnslist == &fi->DnsServerList) dnslist = (PIP_ADDR_STRING)(fi + 1);
597 else dnslist += 1;
598 }
599 fi->EnableDns = 1;
600 return ERROR_SUCCESS;
601}
602//******************************************************************************
603//******************************************************************************
604
605DWORD AddIPAddress(IPAddr Address, // IP address to add
606 IPMask IpMask, // subnet mask for IP address
607 DWORD IfIndex, // index of adapter
608 PULONG NTEContext, // Net Table Entry context
609 PULONG NTEInstance // Net Table Entry Instance
610 );
611// SIOCAIFADDR
612
613DWORD DeleteIPAddress(
614 ULONG NTEContext // net table entry context
615 );
616// SIOCDIFADDR
617
618//******************************************************************************
619//******************************************************************************
620DWORD WIN32API GetIpAddrTable(PMIB_IPADDRTABLE pIpAddrTable, PULONG pdwSize,
621 BOOL bOrder)
622{
623 DWORD buflen;
624 DWORD rc;
625
626 dprintf(("GetIpAddrTable %x %x %d", pIpAddrTable, pdwSize, bOrder));
627
628 if(pdwSize == NULL) {
629 rc = ERROR_INVALID_PARAMETER;
630 goto end;
631 }
632
633 if(pmipaddrTable == NULL)
634 {
635 // gather the information and save it
636 i_initializeAdapterInformation();
637 }
638 if(pmipaddrTable == NULL)
639 return ERROR_NO_DATA;
640
641
642 buflen = sizeof(MIB_IPADDRTABLE) - sizeof(MIB_IPADDRROW);
643 buflen+= pmipaddrTable->dwNumEntries*sizeof(MIB_IPADDRROW);
644
645 if(buflen > *pdwSize) {
646 *pdwSize = buflen;
647 rc = ERROR_BUFFER_OVERFLOW;
648 goto end;
649 }
650 rc = ERROR_SUCCESS;
651
652 memcpy(pIpAddrTable, pmipaddrTable, buflen);
653
654end:
655 dprintf(("GetIpAddrTable returned %d", rc));
656 return rc;
657}
658//******************************************************************************
659//******************************************************************************
660DWORD WIN32API GetIfTable(PMIB_IFTABLE pIfTable, PULONG pdwSize, BOOL bOrder)
661{
662 DWORD buflen;
663 DWORD rc;
664
665 dprintf(("GetIfTable %x %x %d", pIfTable, pdwSize, bOrder));
666
667 if(pdwSize == NULL) {
668 rc = ERROR_INVALID_PARAMETER;
669 goto end;
670 }
671
672 if(pmibTable == NULL)
673 {
674 // gather the information and save it
675 i_initializeAdapterInformation();
676 }
677 if(pmibTable == NULL)
678 return ERROR_NO_DATA;
679
680
681 buflen = sizeof(MIB_IFTABLE) - sizeof(MIB_IFROW);
682 buflen+= pmibTable->dwNumEntries*sizeof(MIB_IFROW);
683
684 if(buflen > *pdwSize) {
685 *pdwSize = buflen;
686 rc = ERROR_BUFFER_OVERFLOW;
687 goto end;
688 }
689
690 memcpy(pIfTable, pmibTable, buflen);
691
692 rc = ERROR_SUCCESS;
693end:
694 dprintf(("GetIfTable returned %d", rc));
695 return rc;
696}
697//******************************************************************************
698//******************************************************************************
699DWORD WIN32API GetFriendlyIfIndex(DWORD IfIndex)
700{
701 dprintf(("GetFriendlyIfIndex %d; returns the same index", IfIndex));
702 return IfIndex;
703}
704//******************************************************************************
705//******************************************************************************
Note: See TracBrowser for help on using the repository browser.