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

Last change on this file since 21916 was 21916, checked in by dmik, 14 years ago

Merge branch gcc-kmk to trunk.

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 OS2gethostname (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 int j;
277 for (j = 0; j < cAddresses; ++j)
278 {
279#ifdef DEBUG
280 if (i == 0) // print only once
281 {
282 dprintf(("IPHLPAPI: ADDR %d:", j));
283 dprintf(("IPHLPAPI: IPAddress 0x%08X", addrInfo[j].IPAddress));
284 dprintf(("IPHLPAPI: interfaceIndex %d", addrInfo[j].interfaceIndex));
285 dprintf(("IPHLPAPI: netmask 0x%08X", addrInfo[j].netmask));
286 dprintf(("IPHLPAPI: broadcastAddress 0x%08X", addrInfo[j].broadcastAddress));
287 }
288#endif
289 if (addrInfo[j].interfaceIndex == ifIndex)
290 {
291 ++cIfAddresses;
292
293 IP_ADDR_STRING *addr;
294 if (cIfAddresses == 1)
295 {
296 addr = &pipAdapter->IpAddressList;
297 }
298 else
299 {
300 addr->Next = (IP_ADDR_STRING*) malloc(sizeof(IP_ADDR_STRING));
301 addr = addr->Next;
302 }
303
304 memset((char *) addr, 0, sizeof(IP_ADDR_STRING));
305 addr->Next = NULL;
306 stringIPAddress(addr->IpAddress.String, addrInfo[j].IPAddress);
307 // mask is in network byte order for some reason
308 stringIPAddress(addr->IpMask.String, ntohl(addrInfo[j].netmask));
309 addr->Context = 0;
310 }
311 }
312
313 // fill pipAdapter->GatewayList
314 int cIfGateways = 0;
315 struct rtentry *rtentry = rtentries->rttable;
316 for (j = 0; j < rtentries->hostcount + rtentries->netcount; ++j)
317 {
318#ifdef DEBUG
319 if (i == 0) // print only once
320 {
321 dprintf(("IPHLPAPI: RTENTRY %d:", j));
322 dprintf(("IPHLPAPI: rt_hash 0x%08X", rtentry->rt_hash));
323 dprintf(("IPHLPAPI: rt_dst 0x%08X", ((struct sockaddr_in *)(&rtentry->rt_dst))->sin_addr.s_addr));
324 dprintf(("IPHLPAPI: rt_gateway 0x%08X", ((struct sockaddr_in *)(&rtentry->rt_gateway))->sin_addr.s_addr));
325 dprintf(("IPHLPAPI: rt_flags 0x%08X", rtentry->rt_flags));
326 dprintf(("IPHLPAPI: rt_refcnt %d", rtentry->rt_refcnt));
327 dprintf(("IPHLPAPI: rt_use %d", rtentry->rt_use));
328 dprintf(("IPHLPAPI: rt_ifp 0x%p", rtentry->rt_ifp));
329 //dprintf(("IPHLPAPI: if_name %s", rtentry->rt_ifp->if_name));
330 dprintf(("IPHLPAPI: metric1 %d", rtentry->metric1));
331 dprintf(("IPHLPAPI: metric2 %d", rtentry->metric2));
332 dprintf(("IPHLPAPI: metric3 %d", rtentry->metric3));
333 dprintf(("IPHLPAPI: metric4 %d", rtentry->metric4));
334 }
335#endif
336 // only take default gateways for this interface
337#if 1
338 // rtentry->rt_ifp is (always?) a high address (0xFxxxxxxx) and for
339 // some reason reading it causes an access violation on some systems
340 // while works great on other systems. I don't know why. Luckily
341 // (luckily???), the definition of struct rtentries in headers is
342 // wrong -- each entry in the rtentries::rttable array is
343 // additionally followed by an ASCIIZ string containing the
344 // interface name. And the interface name is what we need. Owse.
345 char *if_name = (char *)(rtentry + 1);
346 dprintf(("IPHLPAPI: if_name %s", if_name));
347
348 if (strcmp(if_name, iShortName) == 0 &&
349#else
350 if (strcmp(rtentry->rt_ifp->if_name, iShortName) == 0 &&
351#endif
352 ((struct sockaddr_in *)(&rtentry->rt_dst))->sin_addr.s_addr == 0)
353 {
354 ++cIfGateways;
355
356 IP_ADDR_STRING *addr;
357 if (cIfGateways == 1)
358 {
359 addr = &pipAdapter->GatewayList;
360 }
361 else
362 {
363 addr->Next = (IP_ADDR_STRING *) malloc(sizeof(IP_ADDR_STRING));
364 addr = addr->Next;
365 }
366
367 memset((char *) addr, 0, sizeof(IP_ADDR_STRING));
368 addr->Next = NULL;
369 struct sockaddr_in * sin =
370 (struct sockaddr_in *)(&rtentry->rt_gateway);
371 strcpy((char *) &addr->IpAddress.String, inet_ntoa(sin->sin_addr));
372 strcpy((char *) &addr->IpMask.String, "255.255.255.255");
373 addr->Context = 0;
374 }
375
376 // Compensate for the interface name following the rtentry
377 ++rtentry;
378 rtentry = (struct rtentry *)
379 (((char *) rtentry) + strlen(((char *) rtentry)) + 1);
380 }
381
382
383 // loop over
384 if (!topAdapter)
385 topAdapter = pipAdapter;
386 oldAdapter =
387 pipAdapter;
388
389 ++idx;
390 }
391 pipAdapter = topAdapter;
392
393 // loop over addressees to fill pmipaddrTable
394 for (i = 0; i < cAddresses; ++i)
395 {
396 // skip addresses referring to empty interface entries
397 if (addrInfo[i].interfaceIndex >= IFMIB_ENTRIES ||
398 ifmibget.iftable[addrInfo[i].interfaceIndex].ifType == 0)
399 continue;
400
401 pmipaddrTable->table[i].dwAddr = addrInfo[i].IPAddress;
402 pmipaddrTable->table[i].dwIndex = addrInfo[i].interfaceIndex;
403 // mask is in network byte order for some reason
404 pmipaddrTable->table[i].dwMask = ntohl(addrInfo[i].netmask);
405 pmipaddrTable->table[i].dwBCastAddr = addrInfo[i].broadcastAddress;
406 pmipaddrTable->table[i].dwReasmSize = 0; // ?
407 }
408
409 // current address is the first address so far
410 pipAdapter->CurrentIpAddress = &pipAdapter->IpAddressList;
411
412 // Cleanup
413 soclose(clientSocket);
414 free(buffer2);
415 free(buffer);
416}
417
418// copy over the whole list and advance the target pointer and correct new list
419static void i_copyIP_ADDRESS_STRING(PBYTE *ppTarget, PIP_ADDR_STRING pstruct,PIP_ADDR_STRING pias)
420{
421 PIP_ADDR_STRING dummy = NULL;
422 // We already have this copied
423 pias = pias -> Next;
424 while (pias)
425 {
426 memcpy(*ppTarget, pias, sizeof( IP_ADDR_STRING ) );
427 pstruct->Next = (PIP_ADDR_STRING) *ppTarget;
428 *ppTarget += sizeof ( IP_ADDR_STRING );
429 pias = pias->Next;
430 pstruct = pstruct->Next;
431 }
432}
433
434static DWORD i_sizeOfIP_ADAPTER_INFO(PIP_ADAPTER_INFO piai)
435{
436 PIP_ADDR_STRING pias;
437
438 // check for sufficient space
439 DWORD dwRequired = sizeof( IP_ADAPTER_INFO );
440
441 // follow the IP_ADDR_STRING lists
442 pias = &piai->IpAddressList;
443 while( pias )
444 {
445 dwRequired += sizeof( IP_ADDR_STRING );
446 pias = pias->Next;
447 }
448
449 pias = &piai->GatewayList;
450 while( pias )
451 {
452 dwRequired += sizeof( IP_ADDR_STRING );
453 pias = pias->Next;
454 }
455
456 pias = &piai->DhcpServer;
457 while( pias )
458 {
459 dwRequired += sizeof( IP_ADDR_STRING );
460 pias = pias->Next;
461 }
462
463 pias = &piai->PrimaryWinsServer;
464 while( pias )
465 {
466 dwRequired += sizeof( IP_ADDR_STRING );
467 pias = pias->Next;
468 }
469
470 pias = &piai->SecondaryWinsServer;
471 while( pias )
472 {
473 dwRequired += sizeof( IP_ADDR_STRING );
474 pias = pias->Next;
475 }
476
477 return dwRequired;
478}
479
480
481//******************************************************************************
482//******************************************************************************
483
484// Note: returns error 50 under NT4 (NOT_SUPPORTED)
485// so we better check out alternative ways, too.
486
487ODINFUNCTION2(DWORD, GetAdaptersInfo,
488 PIP_ADAPTER_INFO, pAdapterInfo,
489 PULONG, pOutBufLen)
490{
491 dprintf(("GetAdaptersInfo API called"));
492 dprintf(("Address passed is %p",pAdapterInfo));
493 if (NULL == pOutBufLen)
494 return ERROR_INVALID_PARAMETER;
495
496 // verify first block of memory to write to
497 if (IsBadWritePtr(pAdapterInfo, 4))
498 return ERROR_INVALID_PARAMETER;
499
500 if (NULL == pipAdapter)
501 {
502 // gather the information and save it
503 i_initializeAdapterInformation();
504 }
505
506 if (NULL == pipAdapter)
507 return ERROR_NO_DATA;
508
509 // OK, just copy over the information as far as possible
510 LONG lSpaceLeft = *pOutBufLen;
511 PBYTE pTarget = (PBYTE)pAdapterInfo;
512 PIP_ADAPTER_INFO pip;
513
514 // calculate overall required buffer size
515 DWORD dwRequiredBuffer = 0;
516
517 for( pip = pipAdapter ; pip ; pip = pip->Next )
518 {
519 // check for sufficient space
520 dwRequiredBuffer += i_sizeOfIP_ADAPTER_INFO(pip);
521 }
522
523 for( pip = pipAdapter ; pip ; pip = pip->Next )
524 {
525 // check for sufficient space
526 DWORD dwRequired = i_sizeOfIP_ADAPTER_INFO(pip);
527
528 lSpaceLeft -= dwRequired;
529 if (lSpaceLeft >= 0)
530 {
531 // @PF revised - this thing works because we currently do not support
532 // multi-ip, multi-gateway or multi-DHCP servers lists
533 // TODO - add lists support
534 memcpy(pTarget, pip, sizeof( IP_ADAPTER_INFO ));
535 // point to currentIPAddress
536 ((PIP_ADAPTER_INFO)(pTarget))->CurrentIpAddress = &((PIP_ADAPTER_INFO)(pTarget))->IpAddressList;
537 pTarget += sizeof( IP_ADAPTER_INFO );
538
539// i_copyIP_ADDRESS_STRING(&pTarget, &pip->IpAddressList);
540// i_copyIP_ADDRESS_STRING(&pTarget, &pip->GatewayList);
541// i_copyIP_ADDRESS_STRING(&pTarget, &pip->DhcpServer);
542// i_copyIP_ADDRESS_STRING(&pTarget, &pip->PrimaryWinsServer);
543// i_copyIP_ADDRESS_STRING(&pTarget, &pip->SecondaryWinsServer);
544 }
545 else
546 {
547 // return overall size of required buffer
548 *pOutBufLen = dwRequiredBuffer;
549 return ERROR_BUFFER_OVERFLOW;
550 }
551 }
552 return ERROR_SUCCESS;
553}
554
555
556//******************************************************************************
557//******************************************************************************
558ODINFUNCTION2(DWORD, GetNetworkParams,
559 PFIXED_INFO, pFixedInfo,
560 PULONG, pOutBufLen)
561{
562 struct sockaddr_in * sin;
563 PFIXED_INFO fi = pFixedInfo;
564 DWORD memNeeded;
565 PIP_ADDR_STRING dnslist = NULL, pdnslist = NULL;
566
567 dprintf(("GetNetworkParams pFixedInfo:%x pOutBufLen:%d",pFixedInfo,*pOutBufLen));
568 res_init();
569
570 // Check how much mem we will need
571 memNeeded = sizeof(FIXED_INFO)+_res.nscount*sizeof(IP_ADDR_STRING);
572
573 if (((LONG)(*pOutBufLen - memNeeded)) < 0)
574 {
575 // return overall size of required buffer
576 *pOutBufLen = memNeeded;
577 return ERROR_BUFFER_OVERFLOW;
578 }
579
580 // This is dynamically updated info
581 memset(pFixedInfo,0,memNeeded);
582
583 OS2gethostname(fi->HostName,128);
584 strcpy(fi->DomainName,_res.defdname);
585
586 // Fill in DNS Servers
587 fi->CurrentDnsServer = &fi->DnsServerList;
588 dnslist = &fi->DnsServerList;
589
590 for (int i = 0; i<_res.nscount; i++)
591 {
592 if (pdnslist) pdnslist->Next = dnslist;
593 sin = (struct sockaddr_in *)&_res.nsaddr_list[i];
594 strcpy(dnslist->IpAddress.String,inet_ntoa(sin->sin_addr));
595 dprintf(("IPHLPAPI: GetNetworkParams Adding DNS Server %s",inet_ntoa(sin->sin_addr)));
596 pdnslist = dnslist;
597 if ( pdnslist == &fi->DnsServerList) dnslist = (PIP_ADDR_STRING)(fi + 1);
598 else dnslist += 1;
599 }
600 fi->EnableDns = 1;
601 return ERROR_SUCCESS;
602}
603//******************************************************************************
604//******************************************************************************
605
606DWORD AddIPAddress(IPAddr Address, // IP address to add
607 IPMask IpMask, // subnet mask for IP address
608 DWORD IfIndex, // index of adapter
609 PULONG NTEContext, // Net Table Entry context
610 PULONG NTEInstance // Net Table Entry Instance
611 );
612// SIOCAIFADDR
613
614DWORD DeleteIPAddress(
615 ULONG NTEContext // net table entry context
616 );
617// SIOCDIFADDR
618
619//******************************************************************************
620//******************************************************************************
621DWORD WIN32API GetIpAddrTable(PMIB_IPADDRTABLE pIpAddrTable, PULONG pdwSize,
622 BOOL bOrder)
623{
624 DWORD buflen;
625 DWORD rc;
626
627 dprintf(("GetIpAddrTable %x %x %d", pIpAddrTable, pdwSize, bOrder));
628
629 if(pdwSize == NULL) {
630 rc = ERROR_INVALID_PARAMETER;
631 goto end;
632 }
633
634 if(pmipaddrTable == NULL)
635 {
636 // gather the information and save it
637 i_initializeAdapterInformation();
638 }
639 if(pmipaddrTable == NULL)
640 return ERROR_NO_DATA;
641
642
643 buflen = sizeof(MIB_IPADDRTABLE) - sizeof(MIB_IPADDRROW);
644 buflen+= pmipaddrTable->dwNumEntries*sizeof(MIB_IPADDRROW);
645
646 if(buflen > *pdwSize) {
647 *pdwSize = buflen;
648 rc = ERROR_BUFFER_OVERFLOW;
649 goto end;
650 }
651 rc = ERROR_SUCCESS;
652
653 memcpy(pIpAddrTable, pmipaddrTable, buflen);
654
655end:
656 dprintf(("GetIpAddrTable returned %d", rc));
657 return rc;
658}
659//******************************************************************************
660//******************************************************************************
661DWORD WIN32API GetIfTable(PMIB_IFTABLE pIfTable, PULONG pdwSize, BOOL bOrder)
662{
663 DWORD buflen;
664 DWORD rc;
665
666 dprintf(("GetIfTable %x %x %d", pIfTable, pdwSize, bOrder));
667
668 if(pdwSize == NULL) {
669 rc = ERROR_INVALID_PARAMETER;
670 goto end;
671 }
672
673 if(pmibTable == NULL)
674 {
675 // gather the information and save it
676 i_initializeAdapterInformation();
677 }
678 if(pmibTable == NULL)
679 return ERROR_NO_DATA;
680
681
682 buflen = sizeof(MIB_IFTABLE) - sizeof(MIB_IFROW);
683 buflen+= pmibTable->dwNumEntries*sizeof(MIB_IFROW);
684
685 if(buflen > *pdwSize) {
686 *pdwSize = buflen;
687 rc = ERROR_BUFFER_OVERFLOW;
688 goto end;
689 }
690
691 memcpy(pIfTable, pmibTable, buflen);
692
693 rc = ERROR_SUCCESS;
694end:
695 dprintf(("GetIfTable returned %d", rc));
696 return rc;
697}
698//******************************************************************************
699//******************************************************************************
700DWORD WIN32API GetFriendlyIfIndex(DWORD IfIndex)
701{
702 dprintf(("GetFriendlyIfIndex %d; returns the same index", IfIndex));
703 return IfIndex;
704}
705//******************************************************************************
706//******************************************************************************
Note: See TracBrowser for help on using the repository browser.