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

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

iphlpapi: Fix the byte order in the reported interface mask and report the actual broadcast address instead of 0-s.

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