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

Last change on this file since 10069 was 10069, checked in by sandervl, 22 years ago

change interface name to use standard os2 naming convention

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