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

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

Expose the iphlpapi.dll interface at source level through iprtrmib.h/iphlpapi.h.

File size: 19.9 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)
49typedef struct
50{
51 unsigned long IPAddress;
52 unsigned short interfaceNum;
53 unsigned long netmask;
54 unsigned long broadcastAddress;
55} interfaceInformation;
56
57/* Incomplete but will do for us */
58
59#ifndef TCPV40HDRS
60struct ifnet {
61 char *if_name; /* name, e.g. ``en'' or ``lo'' */
62 short if_unit; /* sub-unit for lower level driver */
63 short if_mtu; /* maximum transmission unit */
64};
65#endif
66
67struct ilist {
68 struct ilist *next;
69 unsigned long addr;
70};
71
72struct rlist {
73 struct rlist *next;
74 unsigned long gate;
75 unsigned long net;
76 unsigned long mask;
77 char done;
78};
79
80#pragma pack()
81
82//We don't want to use the OS2 version directly, but the one in wsock32
83int WIN32API ODIN_gethostname (char * name, int namelen);
84
85ODINDEBUGCHANNEL(IPHLPAPI-IPHLPAPI)
86
87
88/****************************************************************************
89 * module global variables
90 ****************************************************************************/
91
92static PIP_ADAPTER_INFO pipAdapter = NULL;
93static PMIB_IFTABLE pmibTable = NULL;
94static PMIB_IPADDRTABLE pmipaddrTable = NULL;
95
96//******************************************************************************
97//******************************************************************************
98
99void stringIPAddress(char* dst,u_long data)
100{
101 sprintf(dst, "%u.%u.%u.%u",
102 (char)data,
103 (char)(*(((char*)&data) + 1)),
104 (char)(*(((char*)&data) + 2)),
105 (char)(*(((char*)&data) + 3)));
106}
107
108void stringNetmask(char* dst,u_long data)
109{
110 sprintf(dst,"%u.%u.%u.%u",
111 (char)(*(((char*)&data) + 3)),
112 (char)(*(((char*)&data) + 2)),
113 (char)(*(((char*)&data) + 1)),
114 (char)data);
115}
116
117static void i_initializeAdapterInformation(void)
118{
119 unsigned char *p;
120 char iShortName[6];
121 struct rlist * rnode = NULL, * rdef = NULL;
122 PIP_ADAPTER_INFO oldAdapter = NULL,topAdapter = NULL;
123 struct sockaddr_in * sin;
124 int rc,i;
125 char *buffer=NULL,*buffer2=NULL;
126 struct ifnet *pifnet;
127 struct ifmib ifmibget;
128 int cInterfaces;
129#ifndef TCPV40HDRS
130 struct ortentry *r;
131#else
132 struct rtentry *r;
133#endif
134
135 // Init Subsystem and open a socket for ioctl() calls
136 sock_init();
137
138 int clientSocket = socket(PF_INET, SOCK_STREAM, 0);
139 dprintf(("IPHLPAPI(Init): Opened socket %d\n", clientSocket));
140
141 // Whole buf minimum size is 65536 and memsets are really needed in other case
142 // we will get garbage in adapter names.
143
144 buffer = (char*)malloc(64 * 1024);
145 memset(buffer, 0, 65536);
146 memset(&ifmibget,0, sizeof(struct ifmib));
147
148 rc = ioctl(clientSocket, SIOSTATIF, (char*)&ifmibget, sizeof(struct ifmib));
149 dprintf(("IPHLPAPI(SIOSTATIF) ioctl returned: %d\n", rc));
150 if (rc == -1)
151 {
152 free(buffer);
153 soclose(clientSocket);
154 return;
155 }
156
157 rc = ioctl(clientSocket, SIOSTATAT, (char*)buffer, 65536);
158 dprintf(("IPHLPAPI(SIOSTATAT) ioctl returned: %d\n", rc));
159 if (rc == -1)
160 {
161 free(buffer);
162 soclose(clientSocket);
163 return;
164 }
165 cInterfaces = *(short int*)buffer;
166 dprintf(("IPHLPAPI Call returned %d interfaces\n", cInterfaces));
167
168 pmibTable = (PMIB_IFTABLE)malloc(cInterfaces*sizeof(MIB_IFTABLE));
169 memset(pmibTable, 0, cInterfaces*sizeof(MIB_IFTABLE));
170 pmibTable->dwNumEntries = cInterfaces;
171
172 pmipaddrTable = (PMIB_IPADDRTABLE)malloc(cInterfaces*sizeof(MIB_IPADDRTABLE));
173 memset(pmipaddrTable, 0, cInterfaces*sizeof(MIB_IPADDRTABLE));
174 pmipaddrTable->dwNumEntries = cInterfaces;
175
176 for (int currentInterface = 0; currentInterface < cInterfaces; currentInterface++)
177 {
178 interfaceInformation *ifInfo = (interfaceInformation*)(buffer + 2 + (currentInterface * sizeof(interfaceInformation)));
179 // For now let's dump only lanX and pppX adapters, loopback (?)
180// if (ifInfo->interfaceNum ==9) continue;
181
182 // Allocate and clear mem
183 pipAdapter = (PIP_ADAPTER_INFO)malloc (sizeof (IP_ADAPTER_INFO));
184 memset(pipAdapter, 0, sizeof(IP_ADAPTER_INFO));
185 if (oldAdapter)
186 oldAdapter->Next = pipAdapter;
187
188 pipAdapter->Next = NULL;
189 pipAdapter->ComboIndex = 1;
190 i = ifInfo->interfaceNum;
191 // Gather some other stats
192 dprintf(("IPHLPAPI: interface number: %u\n", ifInfo->interfaceNum));
193
194 if (ifInfo->interfaceNum>=0 && ifInfo->interfaceNum<9) // lanX
195 { strcpy(iShortName,"lan"); iShortName[3] = ifInfo->interfaceNum+48;
196 iShortName[4] = 0;}
197
198 // I do not like this very much, but seems there is no other documented
199 // way
200
201 if (strstr(ifmibget.iftable[i].ifDescr,"back")) // lo
202 strcpy(iShortName,"lo");
203
204 if (strstr(ifmibget.iftable[i].ifDescr,"ace ppp")) // pppX
205 strcpy(iShortName,strstr(ifmibget.iftable[i].ifDescr,"ppp"));
206
207 if (strstr(ifmibget.iftable[i].ifDescr,"ace sl")) // slX
208 strcpy(iShortName,strstr(ifmibget.iftable[i].ifDescr,"sl"));
209
210 if (strstr(ifmibget.iftable[i].ifDescr,"ace dod")) // dodX
211 strcpy(iShortName,strstr(ifmibget.iftable[i].ifDescr,"dod"));
212
213 dprintf(("IPHLPAPI: interface name[%s] : %s\n",iShortName, ifmibget.iftable[i].ifDescr));
214 strcpy(pipAdapter->AdapterName, ifmibget.iftable[i].ifDescr);
215 strcpy(pipAdapter->Description, ifmibget.iftable[i].ifDescr);
216
217 pipAdapter->AddressLength = 6; // MAX address
218 memcpy(pipAdapter->Address,ifmibget.iftable[i].ifPhysAddr,6);
219 pipAdapter->Index = ifmibget.iftable[i].ifIndex;
220 pipAdapter->Type = ifmibget.iftable[i].ifType; // Careful with this (?)
221 pipAdapter->DhcpEnabled = 0; // Also a question
222
223 MultiByteToWideChar(CP_ACP, 0, iShortName, strlen(iShortName),
224 pmibTable->table[currentInterface].wszName,
225 MAX_INTERFACE_NAME_LEN);
226
227 pmibTable->table[currentInterface].dwIndex = ifmibget.iftable[i].ifIndex;
228 pmibTable->table[currentInterface].dwType = ifmibget.iftable[i].ifType; /* type of the interface */
229 pmibTable->table[currentInterface].dwMtu = ifmibget.iftable[i].ifMtu; /* MTU of the interface */
230 pmibTable->table[currentInterface].dwSpeed = ifmibget.iftable[i].ifSpeed;
231
232 pmibTable->table[currentInterface].dwPhysAddrLen = 0; //??
233 memcpy(pmibTable->table[currentInterface].bPhysAddr, ifmibget.iftable[i].ifPhysAddr, sizeof(ifmibget.iftable[i].ifPhysAddr));
234
235 pmibTable->table[currentInterface].dwAdminStatus = ifmibget.iftable[i].ifOperStatus;
236 pmibTable->table[currentInterface].dwOperStatus = (ifmibget.iftable[i].ifOperStatus == IFF_UP) ? MIB_IF_OPER_STATUS_OPERATIONAL : MIB_IF_OPER_STATUS_NON_OPERATIONAL;
237
238 pmibTable->table[currentInterface].dwLastChange = ifmibget.iftable[i].ifLastChange;
239 pmibTable->table[currentInterface].dwInOctets = ifmibget.iftable[i].ifInOctets;
240 pmibTable->table[currentInterface].dwInUcastPkts = ifmibget.iftable[i].ifInUcastPkts;
241 pmibTable->table[currentInterface].dwInNUcastPkts = ifmibget.iftable[i].ifInNUcastPkts;
242 pmibTable->table[currentInterface].dwInDiscards = ifmibget.iftable[i].ifInDiscards;
243 pmibTable->table[currentInterface].dwInErrors = ifmibget.iftable[i].ifInErrors;
244 pmibTable->table[currentInterface].dwInUnknownProtos = ifmibget.iftable[i].ifInUnknownProtos;
245 pmibTable->table[currentInterface].dwOutOctets = ifmibget.iftable[i].ifOutOctets;
246 pmibTable->table[currentInterface].dwOutUcastPkts = ifmibget.iftable[i].ifOutUcastPkts;
247 pmibTable->table[currentInterface].dwOutNUcastPkts = ifmibget.iftable[i].ifOutNUcastPkts;
248 pmibTable->table[currentInterface].dwOutDiscards = ifmibget.iftable[i].ifOutDiscards;
249 pmibTable->table[currentInterface].dwOutErrors = ifmibget.iftable[i].ifOutErrors;
250// pmibTable->table[currentInterface].dwOutQLen
251
252 pmibTable->table[currentInterface].dwDescrLen = strlen(ifmibget.iftable[i].ifDescr);
253 strncpy((char *)pmibTable->table[currentInterface].bDescr, iShortName, strlen(iShortName));
254// strncpy((char *)pmibTable->table[currentInterface].bDescr, ifmibget.iftable[i].ifDescr, sizeof(pmibTable->table[currentInterface].bDescr));
255
256
257 pmipaddrTable->table[currentInterface].dwAddr = ifInfo->IPAddress;
258 pmipaddrTable->table[currentInterface].dwMask = ifInfo->netmask;
259 pmipaddrTable->table[currentInterface].dwBCastAddr = 0; //??
260 pmipaddrTable->table[currentInterface].dwIndex = ifmibget.iftable[i].ifIndex;
261
262; /* MTU of the interface */
263
264
265
266 // TODO: Adapter may support multiple IP addrs
267 IP_ADDR_STRING iasAdapterIP;
268 iasAdapterIP.Next = NULL;
269 stringIPAddress((char*)&iasAdapterIP.IpAddress,ifInfo->IPAddress);
270 stringNetmask((char*)&iasAdapterIP.IpMask,ifInfo->netmask);
271 iasAdapterIP.Context = 0;
272
273 // Now we are going to catch gateways for this interface
274 buffer2 = (char*) malloc(64*1024);
275 memset(buffer2, 0, 65536);
276
277 rc = ioctl(clientSocket, SIOSTATRT, (char*)buffer2, 65536);
278 dprintf(("IPHLPAPI(SIOSTATRT):ioctl returned: %d\n", rc));
279
280 if (rc == -1)
281 {
282 free(buffer);
283 free(buffer2);
284 soclose(clientSocket);
285 // better return nothing than some trash, unwinding and freeing
286 for (topAdapter; pipAdapter; topAdapter = pipAdapter) {
287 pipAdapter = topAdapter -> Next;
288 free(topAdapter);
289 }
290 return;
291 }
292
293 rtentries *routeEntries = (rtentries*)buffer2;
294 p = (unsigned char *)&routeEntries->rttable[0];
295
296 IP_ADDR_STRING iasGateway;
297 memset(&iasGateway,0,sizeof(iasGateway));
298
299 for (int currentRoute = 0; currentRoute < (routeEntries->hostcount+routeEntries->netcount); currentRoute++)
300 {
301 // First check if this route is for our interface
302#ifndef TCPV40HDRS
303 r = (struct ortentry *) (p);
304#else
305 r = (struct rtentry *) (p);
306#endif
307 if (strcmp((const char*)(p + sizeof(struct rtentry)),iShortName)==0)
308 {
309 sin = (struct sockaddr_in *)(&r->rt_dst);
310 if (strcmp(inet_ntoa(sin->sin_addr),"0.0.0.0")==0)
311 {
312 iasGateway.Next = NULL;
313 // TODO : Some systems may have many gateways
314 sin = (struct sockaddr_in *)(&r->rt_gateway);
315 strcpy(iasGateway.IpAddress.String,inet_ntoa(sin->sin_addr));
316 sin = (struct sockaddr_in *)&p[-4];
317 strcpy(iasGateway.IpMask.String,inet_ntoa(sin->sin_addr));
318 iasGateway.Context = 0;
319 }
320 }
321#ifndef TCPV40HDRS
322 p+=sizeof(struct ortentry);
323#else
324 p+=sizeof(struct rtentry);
325#endif
326 p+=strlen((char *)p)+1;
327 }
328
329 memcpy((char*)&pipAdapter->IpAddressList, (char*)&iasAdapterIP, sizeof(iasAdapterIP));
330 pipAdapter->CurrentIpAddress = &pipAdapter->IpAddressList;
331 memcpy((char*)&pipAdapter->GatewayList, (char*)&iasGateway, sizeof(iasGateway));
332 // what about OS/2 DHCP?
333 memset((char*)&pipAdapter->DhcpServer, 0, sizeof( IP_ADDR_STRING ) );
334 pipAdapter->HaveWins = 0;
335 memset((char*)&pipAdapter->PrimaryWinsServer, 0, sizeof( IP_ADDR_STRING ) );
336 memset((char*)&pipAdapter->SecondaryWinsServer, 0, sizeof( IP_ADDR_STRING ) );
337 pipAdapter->LeaseObtained = 0;
338 pipAdapter->LeaseExpires = 0;
339 if (!topAdapter) topAdapter = pipAdapter;
340 oldAdapter = pipAdapter;
341 }
342 pipAdapter = topAdapter;
343
344 // Cleanup
345 if (buffer) free(buffer);
346 if (buffer2) free(buffer2);
347 soclose(clientSocket);
348}
349
350// copy over the whole list and advance the target pointer and correct new list
351static void i_copyIP_ADDRESS_STRING(PBYTE *ppTarget, PIP_ADDR_STRING pstruct,PIP_ADDR_STRING pias)
352{
353 PIP_ADDR_STRING dummy = NULL;
354 // We already have this copied
355 pias = pias -> Next;
356 while (pias)
357 {
358 memcpy(*ppTarget, pias, sizeof( IP_ADDR_STRING ) );
359 pstruct->Next = (PIP_ADDR_STRING) *ppTarget;
360 *ppTarget += sizeof ( IP_ADDR_STRING );
361 pias = pias->Next;
362 pstruct = pstruct->Next;
363 }
364}
365
366static DWORD i_sizeOfIP_ADAPTER_INFO(PIP_ADAPTER_INFO piai)
367{
368 PIP_ADDR_STRING pias;
369
370 // check for sufficient space
371 DWORD dwRequired = sizeof( IP_ADAPTER_INFO );
372
373 // follow the IP_ADDR_STRING lists
374 pias = &piai->IpAddressList;
375 while( pias )
376 {
377 dwRequired += sizeof( IP_ADDR_STRING );
378 pias = pias->Next;
379 }
380
381 pias = &piai->GatewayList;
382 while( pias )
383 {
384 dwRequired += sizeof( IP_ADDR_STRING );
385 pias = pias->Next;
386 }
387
388 pias = &piai->DhcpServer;
389 while( pias )
390 {
391 dwRequired += sizeof( IP_ADDR_STRING );
392 pias = pias->Next;
393 }
394
395 pias = &piai->PrimaryWinsServer;
396 while( pias )
397 {
398 dwRequired += sizeof( IP_ADDR_STRING );
399 pias = pias->Next;
400 }
401
402 pias = &piai->SecondaryWinsServer;
403 while( pias )
404 {
405 dwRequired += sizeof( IP_ADDR_STRING );
406 pias = pias->Next;
407 }
408
409 return dwRequired;
410}
411
412
413//******************************************************************************
414//******************************************************************************
415
416// Note: returns error 50 under NT4 (NOT_SUPPORTED)
417// so we better check out alternative ways, too.
418
419ODINFUNCTION2(DWORD, GetAdaptersInfo,
420 PIP_ADAPTER_INFO, pAdapterInfo,
421 PULONG, pOutBufLen)
422{
423 dprintf(("GetAdaptersInfo API called"));
424 dprintf(("Address passed is %p",pAdapterInfo));
425 if (NULL == pOutBufLen)
426 return ERROR_INVALID_PARAMETER;
427
428 // verify first block of memory to write to
429 if (IsBadWritePtr(pAdapterInfo, 4))
430 return ERROR_INVALID_PARAMETER;
431
432 if (NULL == pipAdapter)
433 {
434 // gather the information and save it
435 i_initializeAdapterInformation();
436 }
437
438 if (NULL == pipAdapter)
439 return ERROR_NO_DATA;
440
441 // OK, just copy over the information as far as possible
442 LONG lSpaceLeft = *pOutBufLen;
443 PBYTE pTarget = (PBYTE)pAdapterInfo;
444 PIP_ADAPTER_INFO pip;
445
446 // calculate overall required buffer size
447 DWORD dwRequiredBuffer = 0;
448
449 for( pip = pipAdapter ; pip ; pip = pip->Next )
450 {
451 // check for sufficient space
452 dwRequiredBuffer += i_sizeOfIP_ADAPTER_INFO(pip);
453 }
454
455 for( pip = pipAdapter ; pip ; pip = pip->Next )
456 {
457 // check for sufficient space
458 DWORD dwRequired = i_sizeOfIP_ADAPTER_INFO(pip);
459
460 lSpaceLeft -= dwRequired;
461 if (lSpaceLeft >= 0)
462 {
463 // @PF revised - this thing works because we currently do not support
464 // multi-ip, multi-gateway or multi-DHCP servers lists
465 // TODO - add lists support
466 memcpy(pTarget, pip, sizeof( IP_ADAPTER_INFO ));
467 // point to currentIPAddress
468 ((PIP_ADAPTER_INFO)(pTarget))->CurrentIpAddress = &((PIP_ADAPTER_INFO)(pTarget))->IpAddressList;
469 pTarget += sizeof( IP_ADAPTER_INFO );
470
471// i_copyIP_ADDRESS_STRING(&pTarget, &pip->IpAddressList);
472// i_copyIP_ADDRESS_STRING(&pTarget, &pip->GatewayList);
473// i_copyIP_ADDRESS_STRING(&pTarget, &pip->DhcpServer);
474// i_copyIP_ADDRESS_STRING(&pTarget, &pip->PrimaryWinsServer);
475// i_copyIP_ADDRESS_STRING(&pTarget, &pip->SecondaryWinsServer);
476 }
477 else
478 {
479 // return overall size of required buffer
480 *pOutBufLen = dwRequiredBuffer;
481 return ERROR_BUFFER_OVERFLOW;
482 }
483 }
484 return ERROR_SUCCESS;
485}
486
487
488//******************************************************************************
489//******************************************************************************
490ODINFUNCTION2(DWORD, GetNetworkParams,
491 PFIXED_INFO, pFixedInfo,
492 PULONG, pOutBufLen)
493{
494 struct sockaddr_in * sin;
495 PFIXED_INFO fi = pFixedInfo;
496 DWORD memNeeded;
497 PIP_ADDR_STRING dnslist = NULL, pdnslist = NULL;
498
499 dprintf(("GetNetworkParams pFixedInfo:%x pOutBufLen:%d",pFixedInfo,*pOutBufLen));
500 res_init();
501
502 // Check how much mem we will need
503 memNeeded = sizeof(FIXED_INFO)+_res.nscount*sizeof(IP_ADDR_STRING);
504
505 if (((LONG)(*pOutBufLen - memNeeded)) < 0)
506 {
507 // return overall size of required buffer
508 *pOutBufLen = memNeeded;
509 return ERROR_BUFFER_OVERFLOW;
510 }
511
512 // This is dynamically updated info
513 memset(pFixedInfo,0,memNeeded);
514
515 ODIN_gethostname(fi->HostName,128);
516 strcpy(fi->DomainName,_res.defdname);
517
518 // Fill in DNS Servers
519 fi->CurrentDnsServer = &fi->DnsServerList;
520 dnslist = &fi->DnsServerList;
521
522 for (int i = 0; i<_res.nscount; i++)
523 {
524 if (pdnslist) pdnslist->Next = dnslist;
525 sin = (struct sockaddr_in *)&_res.nsaddr_list[i];
526 strcpy(dnslist->IpAddress.String,inet_ntoa(sin->sin_addr));
527 dprintf(("IPHLPAPI: GetNetworkParams Adding DNS Server %s",inet_ntoa(sin->sin_addr)));
528 pdnslist = dnslist;
529 if ( pdnslist == &fi->DnsServerList) dnslist = (PIP_ADDR_STRING)(fi + 1);
530 else dnslist += 1;
531 }
532 fi->EnableDns = 1;
533 return ERROR_SUCCESS;
534}
535//******************************************************************************
536//******************************************************************************
537
538DWORD AddIPAddress(IPAddr Address, // IP address to add
539 IPMask IpMask, // subnet mask for IP address
540 DWORD IfIndex, // index of adapter
541 PULONG NTEContext, // Net Table Entry context
542 PULONG NTEInstance // Net Table Entry Instance
543 );
544// SIOCAIFADDR
545
546DWORD DeleteIPAddress(
547 ULONG NTEContext // net table entry context
548 );
549// SIOCDIFADDR
550
551//******************************************************************************
552//******************************************************************************
553DWORD WIN32API GetIpAddrTable(PMIB_IPADDRTABLE pIpAddrTable, PULONG pdwSize,
554 BOOL bOrder)
555{
556 DWORD buflen;
557 DWORD rc;
558
559 dprintf(("GetIpAddrTable %x %x %d", pIpAddrTable, pdwSize, bOrder));
560
561 if(pdwSize == NULL) {
562 rc = ERROR_INVALID_PARAMETER;
563 goto end;
564 }
565
566 if(pmipaddrTable == NULL)
567 {
568 // gather the information and save it
569 i_initializeAdapterInformation();
570 }
571 if(pmipaddrTable == NULL)
572 return ERROR_NO_DATA;
573
574
575 buflen = sizeof(MIB_IPADDRTABLE) - sizeof(MIB_IPADDRROW);
576 buflen+= pmipaddrTable->dwNumEntries*sizeof(MIB_IPADDRROW);
577
578 if(buflen > *pdwSize) {
579 *pdwSize = buflen;
580 rc = ERROR_BUFFER_OVERFLOW;
581 goto end;
582 }
583 rc = ERROR_SUCCESS;
584
585 memcpy(pIpAddrTable, pmipaddrTable, buflen);
586
587end:
588 dprintf(("GetIpAddrTable returned %d", rc));
589 return rc;
590}
591//******************************************************************************
592//******************************************************************************
593DWORD WIN32API GetIfTable(PMIB_IFTABLE pIfTable, PULONG pdwSize, BOOL bOrder)
594{
595 DWORD buflen;
596 DWORD rc;
597
598 dprintf(("GetIfTable %x %x %d", pIfTable, pdwSize, bOrder));
599
600 if(pdwSize == NULL) {
601 rc = ERROR_INVALID_PARAMETER;
602 goto end;
603 }
604
605 if(pmibTable == NULL)
606 {
607 // gather the information and save it
608 i_initializeAdapterInformation();
609 }
610 if(pmibTable == NULL)
611 return ERROR_NO_DATA;
612
613
614 buflen = sizeof(MIB_IFTABLE) - sizeof(MIB_IFROW);
615 buflen+= pmibTable->dwNumEntries*sizeof(MIB_IFROW);
616
617 if(buflen > *pdwSize) {
618 *pdwSize = buflen;
619 rc = ERROR_BUFFER_OVERFLOW;
620 goto end;
621 }
622
623 memcpy(pIfTable, pmibTable, buflen);
624
625 rc = ERROR_SUCCESS;
626end:
627 dprintf(("GetIfTable returned %d", rc));
628 return rc;
629}
630//******************************************************************************
631//******************************************************************************
632DWORD WIN32API GetFriendlyIfIndex(DWORD IfIndex)
633{
634 dprintf(("GetFriendlyIfIndex %d; returns the same index", IfIndex));
635 return IfIndex;
636}
637//******************************************************************************
638//******************************************************************************
Note: See TracBrowser for help on using the repository browser.