blob: 2ef5b3150ac5db04d27e92b42e9296dc7eef7732 [file] [log] [blame]
Juan Lang38fa5ad2003-05-13 03:32:20 +00001/*
2 * iphlpapi dll implementation
3 *
4 * Copyright (C) 2003 Juan Lang
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include "config.h"
22
23#include <stdlib.h>
Gerald Pfeifer9512ba52003-05-13 23:37:29 +000024#include <sys/types.h>
Pierre d'Herbemont30f84a32003-05-19 21:41:00 +000025#ifdef HAVE_NETINET_IN_H
Gerald Pfeifer9512ba52003-05-13 23:37:29 +000026#include <netinet/in.h>
Pierre d'Herbemont30f84a32003-05-19 21:41:00 +000027#endif
28#ifdef HAVE_ARPA_NAMESER_H
29#include <arpa/nameser.h>
30#endif
Juan Lang38fa5ad2003-05-13 03:32:20 +000031#include <resolv.h>
32#include "winbase.h"
33#include "iphlpapi.h"
34#include "ifenum.h"
35#include "ipstats.h"
36#include "wine/debug.h"
37
38WINE_DEFAULT_DEBUG_CHANNEL(iphlpapi);
39
40
41/******************************************************************
42 * AddIPAddress (IPHLPAPI.@)
43 *
44 *
45 * PARAMS
46 *
47 * Address [In]
48 * IpMask [In]
49 * IfIndex [In]
50 * NTEContext [In/Out]
51 * NTEInstance [In/Out]
52 *
53 * RETURNS
54 *
55 * DWORD
56 *
57 */
58DWORD WINAPI AddIPAddress(IPAddr Address, IPMask IpMask, DWORD IfIndex, PULONG NTEContext, PULONG NTEInstance)
59{
60 FIXME(":stub\n");
61 /* marking Win2K+ functions not supported */
62 return ERROR_NOT_SUPPORTED;
63}
64
65
66/******************************************************************
67 * CreateIpForwardEntry (IPHLPAPI.@)
68 *
69 *
70 * PARAMS
71 *
72 * pRoute [In/Out]
73 *
74 * RETURNS
75 *
76 * DWORD
77 *
78 */
79DWORD WINAPI CreateIpForwardEntry(PMIB_IPFORWARDROW pRoute)
80{
81 /* could use SIOCADDRT, not sure I want to */
82 FIXME(":stub\n");
83 return (DWORD) 0;
84}
85
86
87/******************************************************************
88 * CreateIpNetEntry (IPHLPAPI.@)
89 *
90 *
91 * PARAMS
92 *
93 * pArpEntry [In/Out]
94 *
95 * RETURNS
96 *
97 * DWORD
98 *
99 */
100DWORD WINAPI CreateIpNetEntry(PMIB_IPNETROW pArpEntry)
101{
102 /* could use SIOCSARP on systems that support it, not sure I want to */
103 FIXME(":stub\n");
104 return (DWORD) 0;
105}
106
107
108/******************************************************************
109 * CreateProxyArpEntry (IPHLPAPI.@)
110 *
111 *
112 * PARAMS
113 *
114 * dwAddress [In]
115 * dwMask [In]
116 * dwIfIndex [In]
117 *
118 * RETURNS
119 *
120 * DWORD
121 *
122 */
123DWORD WINAPI CreateProxyArpEntry(DWORD dwAddress, DWORD dwMask, DWORD dwIfIndex)
124{
125 FIXME(":stub\n");
126 /* marking Win2K+ functions not supported */
127 return ERROR_NOT_SUPPORTED;
128}
129
130
131/******************************************************************
132 * DeleteIPAddress (IPHLPAPI.@)
133 *
134 *
135 * PARAMS
136 *
137 * NTEContext [In]
138 *
139 * RETURNS
140 *
141 * DWORD
142 *
143 */
144DWORD WINAPI DeleteIPAddress(ULONG NTEContext)
145{
146 FIXME(":stub\n");
147 /* marking Win2K+ functions not supported */
148 return ERROR_NOT_SUPPORTED;
149}
150
151
152/******************************************************************
153 * DeleteIpForwardEntry (IPHLPAPI.@)
154 *
155 *
156 * PARAMS
157 *
158 * pRoute [In/Out]
159 *
160 * RETURNS
161 *
162 * DWORD
163 *
164 */
165DWORD WINAPI DeleteIpForwardEntry(PMIB_IPFORWARDROW pRoute)
166{
167 /* could use SIOCDELRT, not sure I want to */
168 FIXME(":stub\n");
169 return (DWORD) 0;
170}
171
172
173/******************************************************************
174 * DeleteIpNetEntry (IPHLPAPI.@)
175 *
176 *
177 * PARAMS
178 *
179 * pArpEntry [In/Out]
180 *
181 * RETURNS
182 *
183 * DWORD
184 *
185 */
186DWORD WINAPI DeleteIpNetEntry(PMIB_IPNETROW pArpEntry)
187{
188 /* could use SIOCDARP on systems that support it, not sure I want to */
189 FIXME(":stub\n");
190 return (DWORD) 0;
191}
192
193
194/******************************************************************
195 * DeleteProxyArpEntry (IPHLPAPI.@)
196 *
197 *
198 * PARAMS
199 *
200 * dwAddress [In]
201 * dwMask [In]
202 * dwIfIndex [In]
203 *
204 * RETURNS
205 *
206 * DWORD
207 *
208 */
209DWORD WINAPI DeleteProxyArpEntry(DWORD dwAddress, DWORD dwMask, DWORD dwIfIndex)
210{
211 FIXME(":stub\n");
212 /* marking Win2K+ functions not supported */
213 return ERROR_NOT_SUPPORTED;
214}
215
216
217/******************************************************************
218 * EnableRouter (IPHLPAPI.@)
219 *
220 *
221 * PARAMS
222 *
223 * pHandle [In/Out]
224 * pOverlapped [In/Out]
225 *
226 * RETURNS
227 *
228 * DWORD
229 *
230 */
231DWORD WINAPI EnableRouter(HANDLE * pHandle, OVERLAPPED * pOverlapped)
232{
233 FIXME(":stub\n");
234 /* could echo "1" > /proc/net/sys/net/ipv4/ip_forward, not sure I want to
235 could map EACCESS to ERROR_ACCESS_DENIED, I suppose
236 marking Win2K+ functions not supported */
237 return ERROR_NOT_SUPPORTED;
238}
239
240
241/******************************************************************
242 * FlushIpNetTable (IPHLPAPI.@)
243 *
244 *
245 * PARAMS
246 *
247 * dwIfIndex [In]
248 *
249 * RETURNS
250 *
251 * DWORD
252 *
253 */
254DWORD WINAPI FlushIpNetTable(DWORD dwIfIndex)
255{
256 FIXME(":stub\n");
257 /* this flushes the arp cache of the given index
258 marking Win2K+ functions not supported */
259 return ERROR_NOT_SUPPORTED;
260}
261
262
263/******************************************************************
264 * GetAdapterIndex (IPHLPAPI.@)
265 *
266 *
267 * PARAMS
268 *
269 * AdapterName [In/Out]
270 * IfIndex [In/Out]
271 *
272 * RETURNS
273 *
274 * DWORD
275 *
276 */
277DWORD WINAPI GetAdapterIndex(LPWSTR AdapterName, PULONG IfIndex)
278{
279 FIXME(":stub\n");
280 /* marking Win2K+ functions not supported */
281 return ERROR_NOT_SUPPORTED;
282}
283
284
285/******************************************************************
286 * GetAdaptersInfo (IPHLPAPI.@)
287 *
288 *
289 * PARAMS
290 *
291 * pAdapterInfo [In/Out]
292 * pOutBufLen [In/Out]
293 *
294 * RETURNS
295 *
296 * DWORD
297 *
298 */
299DWORD WINAPI GetAdaptersInfo(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen)
300{
301 DWORD ret;
302
303 if (!pOutBufLen)
304 ret = ERROR_INVALID_PARAMETER;
305 else {
306 DWORD numNonLoopbackInterfaces = getNumNonLoopbackInterfaces();
307
308 if (numNonLoopbackInterfaces > 0) {
309 /* this calculation assumes only one address in the IP_ADDR_STRING lists.
310 that's okay, because:
311 - we don't get multiple addresses per adapter anyway
312 - we don't know about per-adapter gateways
313 - we don't know about DHCP or WINS (and these must be single anyway) */
314 ULONG size = sizeof(IP_ADAPTER_INFO) * numNonLoopbackInterfaces;
315
316 if (!pAdapterInfo || *pOutBufLen < size) {
317 *pOutBufLen = size;
318 ret = ERROR_BUFFER_OVERFLOW;
319 }
320 else {
321 InterfaceIndexTable *table = getNonLoopbackInterfaceIndexTable();
322
323 if (table) {
324 size = sizeof(IP_ADAPTER_INFO) * table->numIndexes;
325 if (*pOutBufLen < size) {
326 *pOutBufLen = size;
327 ret = ERROR_INSUFFICIENT_BUFFER;
328 }
329 else {
330 DWORD ndx;
331
332 memset(pAdapterInfo, 0, size);
333 for (ndx = 0; ndx < table->numIndexes; ndx++) {
334 PIP_ADAPTER_INFO ptr = &pAdapterInfo[ndx];
335 DWORD addrLen = sizeof(ptr->Address), type;
336
337 /* on Win98 this is left empty, but whatever */
338 strncpy(ptr->AdapterName,
339 getInterfaceNameByIndex(table->indexes[ndx]),
340 sizeof(ptr->AdapterName));
341 ptr->AdapterName[MAX_ADAPTER_NAME_LENGTH] = '\0';
342 getInterfacePhysicalByIndex(table->indexes[ndx], &addrLen,
343 ptr->Address, &type);
344 /* MS defines address length and type as UINT in some places and
345 DWORD in others, **sigh**. Don't want to assume that PUINT and
346 PDWORD are equiv (64-bit?) */
347 ptr->AddressLength = addrLen;
348 ptr->Type = type;
349 ptr->Index = table->indexes[ndx];
350 toIPAddressString(getInterfaceIPAddrByIndex(table->indexes[ndx]),
351 ptr->IpAddressList.IpAddress.String);
352 toIPAddressString(getInterfaceMaskByIndex(table->indexes[ndx]),
353 ptr->IpAddressList.IpMask.String);
354 if (ndx < table->numIndexes + 1)
Eric Pouech9b5cde82003-06-23 03:32:28 +0000355 ptr->Next = (ndx == table->numIndexes - 1) ? NULL : &pAdapterInfo[ndx + 1];
Juan Lang38fa5ad2003-05-13 03:32:20 +0000356 }
357 ret = NO_ERROR;
358 }
359 free(table);
360 }
361 else
362 ret = ERROR_OUTOFMEMORY;
363 }
364 }
365 else
366 ret = ERROR_NO_DATA;
367 }
368 return ret;
369}
370
371
372/******************************************************************
373 * GetBestInterface (IPHLPAPI.@)
374 *
375 *
376 * PARAMS
377 *
378 * dwDestAddr [In]
379 * pdwBestIfIndex [In/Out]
380 *
381 * RETURNS
382 *
383 * DWORD
384 *
385 */
386DWORD WINAPI GetBestInterface(IPAddr dwDestAddr, PDWORD pdwBestIfIndex)
387{
388 FIXME(":stub\n");
389 return (DWORD) 0;
390}
391
392
393/******************************************************************
394 * GetBestRoute (IPHLPAPI.@)
395 *
396 *
397 * PARAMS
398 *
399 * dwDestAddr [In]
400 * dwSourceAddr [In]
401 * OUT [In]
402 *
403 * RETURNS
404 *
405 * DWORD
406 *
407 */
408DWORD WINAPI GetBestRoute(DWORD dwDestAddr, DWORD dwSourceAddr, PMIB_IPFORWARDROW pBestRoute)
409{
410 FIXME(":stub\n");
411 return (DWORD) 0;
412}
413
414
415/******************************************************************
416 * GetFriendlyIfIndex (IPHLPAPI.@)
417 *
418 *
419 * PARAMS
420 *
421 * IfIndex [In]
422 *
423 * RETURNS
424 *
425 * DWORD
426 *
427 */
428DWORD WINAPI GetFriendlyIfIndex(DWORD IfIndex)
429{
430 /* windows doesn't validate these, either, just makes sure the top byte is
431 cleared. I assume my ipshared module never gives an index with the top
432 byte set. */
433 return IfIndex;
434}
435
436
437/******************************************************************
438 * GetIcmpStatistics (IPHLPAPI.@)
439 *
440 *
441 * PARAMS
442 *
443 * pStats [In/Out]
444 *
445 * RETURNS
446 *
447 * DWORD
448 *
449 */
450DWORD WINAPI GetIcmpStatistics(PMIB_ICMP pStats)
451{
452 return getICMPStats(pStats);
453}
454
455
456/******************************************************************
457 * GetIfEntry (IPHLPAPI.@)
458 *
459 *
460 * PARAMS
461 *
462 * pIfRow [In/Out]
463 *
464 * RETURNS
465 *
466 * DWORD
467 *
468 */
469DWORD WINAPI GetIfEntry(PMIB_IFROW pIfRow)
470{
471 DWORD ret;
472 const char *name;
473
474 if (!pIfRow)
475 return ERROR_INVALID_PARAMETER;
476
477 name = getInterfaceNameByIndex(pIfRow->dwIndex);
478 if (name) {
479 ret = getInterfaceEntryByName(name, pIfRow);
480 if (ret == NO_ERROR)
481 ret = getInterfaceStatsByName(name, pIfRow);
482 }
483 else
484 ret = ERROR_INVALID_DATA;
485 return ret;
486}
487
488
489/******************************************************************
490 * GetIfTable (IPHLPAPI.@)
491 *
492 *
493 * PARAMS
494 *
495 * pIfTable [In/Out]
496 * pdwSize [In/Out]
497 * bOrder [In]
498 *
499 * RETURNS
500 *
501 * DWORD
502 *
503 */
504DWORD WINAPI GetIfTable(PMIB_IFTABLE pIfTable, PULONG pdwSize, BOOL bOrder)
505{
506 DWORD ret;
507
508 if (!pdwSize)
509 ret = ERROR_INVALID_PARAMETER;
510 else {
511 DWORD numInterfaces = getNumInterfaces();
512 ULONG size = sizeof(MIB_IFTABLE) + (numInterfaces - 1) * sizeof(MIB_IFROW);
513
514 if (!pIfTable || *pdwSize < size) {
515 *pdwSize = size;
516 ret = ERROR_INSUFFICIENT_BUFFER;
517 }
518 else {
519 InterfaceIndexTable *table = getInterfaceIndexTable();
520
521 if (table) {
522 size = sizeof(MIB_IFTABLE) + (table->numIndexes - 1) *
523 sizeof(MIB_IFROW);
524 if (*pdwSize < size) {
525 *pdwSize = size;
526 ret = ERROR_INSUFFICIENT_BUFFER;
527 }
528 else {
529 DWORD ndx;
530
531 if (bOrder)
532 FIXME(":order not implemented");
533 pIfTable->dwNumEntries = 0;
534 for (ndx = 0; ndx < table->numIndexes; ndx++) {
535 pIfTable->table[ndx].dwIndex = table->indexes[ndx];
536 GetIfEntry(&pIfTable->table[ndx]);
537 pIfTable->dwNumEntries++;
538 }
539 ret = NO_ERROR;
540 }
541 free(table);
542 }
543 else
544 ret = ERROR_OUTOFMEMORY;
545 }
546 }
547 return ret;
548}
549
550
551/******************************************************************
552 * GetInterfaceInfo (IPHLPAPI.@)
553 *
554 *
555 * PARAMS
556 *
557 * pIfTable [In/Out]
558 * dwOutBufLen [In/Out]
559 *
560 * RETURNS
561 *
562 * DWORD
563 *
564 */
565DWORD WINAPI GetInterfaceInfo(PIP_INTERFACE_INFO pIfTable, PULONG dwOutBufLen)
566{
567 DWORD ret;
568
569 if (!dwOutBufLen)
570 ret = ERROR_INVALID_PARAMETER;
571 else {
572 DWORD numInterfaces = getNumInterfaces();
573 ULONG size = sizeof(IP_INTERFACE_INFO) + (numInterfaces - 1) *
574 sizeof(IP_ADAPTER_INDEX_MAP);
575
576 if (!pIfTable || *dwOutBufLen < size) {
577 *dwOutBufLen = size;
578 ret = ERROR_INSUFFICIENT_BUFFER;
579 }
580 else {
581 InterfaceIndexTable *table = getInterfaceIndexTable();
582
583 if (table) {
584 size = sizeof(IP_INTERFACE_INFO) + (table->numIndexes - 1) *
585 sizeof(IP_ADAPTER_INDEX_MAP);
586 if (*dwOutBufLen < size) {
587 *dwOutBufLen = size;
588 ret = ERROR_INSUFFICIENT_BUFFER;
589 }
590 else {
591 DWORD ndx;
592
593 pIfTable->NumAdapters = 0;
594 for (ndx = 0; ndx < table->numIndexes; ndx++) {
595 const char *walker, *name;
596 WCHAR *assigner;
597
598 pIfTable->Adapter[ndx].Index = table->indexes[ndx];
599 name = getInterfaceNameByIndex(table->indexes[ndx]);
600 for (walker = name, assigner = pIfTable->Adapter[ndx].Name;
601 walker && *walker &&
602 assigner - pIfTable->Adapter[ndx].Name < MAX_ADAPTER_NAME - 1;
603 walker++, assigner++)
604 *assigner = *walker;
605 *assigner = 0;
606 pIfTable->NumAdapters++;
607 }
608 ret = NO_ERROR;
609 }
610 free(table);
611 }
612 else
613 ret = ERROR_OUTOFMEMORY;
614 }
615 }
616 return ret;
617}
618
619
620/******************************************************************
621 * GetIpAddrTable (IPHLPAPI.@)
622 *
623 *
624 * PARAMS
625 *
626 * pIpAddrTable [In/Out]
627 * pdwSize [In/Out]
628 * bOrder [In]
629 *
630 * RETURNS
631 *
632 * DWORD
633 *
634 */
635DWORD WINAPI GetIpAddrTable(PMIB_IPADDRTABLE pIpAddrTable, PULONG pdwSize, BOOL bOrder)
636{
637 DWORD ret;
638
639 if (!pdwSize)
640 ret = ERROR_INVALID_PARAMETER;
641 else {
642 DWORD numInterfaces = getNumInterfaces();
643 ULONG size = sizeof(MIB_IPADDRTABLE) + (numInterfaces - 1) *
644 sizeof(MIB_IPADDRROW);
645
646 if (!pIpAddrTable || *pdwSize < size) {
647 *pdwSize = size;
648 ret = ERROR_INSUFFICIENT_BUFFER;
649 }
650 else {
651 InterfaceIndexTable *table = getInterfaceIndexTable();
652
653 if (table) {
654 size = sizeof(MIB_IPADDRTABLE) + (table->numIndexes - 1) *
655 sizeof(MIB_IPADDRROW);
656 if (*pdwSize < size) {
657 *pdwSize = size;
658 ret = ERROR_INSUFFICIENT_BUFFER;
659 }
660 else {
661 DWORD ndx;
662
663 if (bOrder)
664 FIXME(":order not implemented");
665 pIpAddrTable->dwNumEntries = 0;
666 for (ndx = 0; ndx < table->numIndexes; ndx++) {
667 pIpAddrTable->table[ndx].dwIndex = table->indexes[ndx];
668 pIpAddrTable->table[ndx].dwAddr =
669 getInterfaceIPAddrByIndex(table->indexes[ndx]);
670 pIpAddrTable->table[ndx].dwMask =
671 getInterfaceMaskByIndex(table->indexes[ndx]);
672 pIpAddrTable->table[ndx].dwBCastAddr =
673 getInterfaceBCastAddrByIndex(table->indexes[ndx]);
674 /* FIXME: hardcoded reasm size, not sure where to get it */
675 pIpAddrTable->table[ndx].dwReasmSize = 65535;
676 pIpAddrTable->table[ndx].unused1 = 0;
677 pIpAddrTable->table[ndx].wType = 0; /* aka unused2 */
678 pIpAddrTable->dwNumEntries++;
679 }
680 ret = NO_ERROR;
681 }
682 free(table);
683 }
684 else
685 ret = ERROR_OUTOFMEMORY;
686 }
687 }
688 return ret;
689}
690
691
692/******************************************************************
693 * GetIpForwardTable (IPHLPAPI.@)
694 *
695 *
696 * PARAMS
697 *
698 * pIpForwardTable [In/Out]
699 * pdwSize [In/Out]
700 * bOrder [In]
701 *
702 * RETURNS
703 *
704 * DWORD
705 *
706 */
707DWORD WINAPI GetIpForwardTable(PMIB_IPFORWARDTABLE pIpForwardTable, PULONG pdwSize, BOOL bOrder)
708{
709 DWORD ret;
710
711 if (!pdwSize)
712 ret = ERROR_INVALID_PARAMETER;
713 else {
714 DWORD numRoutes = getNumRoutes();
715 ULONG sizeNeeded = sizeof(MIB_IPFORWARDTABLE) + (numRoutes - 1) *
716 sizeof(MIB_IPFORWARDROW);
717
718 if (!pIpForwardTable || *pdwSize < sizeNeeded) {
719 *pdwSize = sizeNeeded;
720 ret = ERROR_INSUFFICIENT_BUFFER;
721 }
722 else {
723 RouteTable *table = getRouteTable();
724 if (table) {
725 sizeNeeded = sizeof(MIB_IPFORWARDTABLE) + (table->numRoutes - 1) *
726 sizeof(MIB_IPFORWARDROW);
727 if (*pdwSize < sizeNeeded) {
728 *pdwSize = sizeNeeded;
729 ret = ERROR_INSUFFICIENT_BUFFER;
730 }
731 else {
732 DWORD ndx;
733
734 if (bOrder)
735 FIXME(":order not implemented");
736 pIpForwardTable->dwNumEntries = table->numRoutes;
737 for (ndx = 0; ndx < numRoutes; ndx++) {
738 pIpForwardTable->table[ndx].dwForwardIfIndex =
739 table->routes[ndx].ifIndex;
740 pIpForwardTable->table[ndx].dwForwardDest =
741 table->routes[ndx].dest;
742 pIpForwardTable->table[ndx].dwForwardMask =
743 table->routes[ndx].mask;
744 pIpForwardTable->table[ndx].dwForwardPolicy = 0;
745 pIpForwardTable->table[ndx].dwForwardNextHop =
746 table->routes[ndx].gateway;
747 /* FIXME: this type is appropriate for local interfaces; may not
748 always be appropriate */
749 pIpForwardTable->table[ndx].dwForwardType = MIB_IPROUTE_TYPE_DIRECT;
750 /* FIXME: other protos might be appropriate, e.g. the default route
751 is typically set with MIB_IPPROTO_NETMGMT instead */
752 pIpForwardTable->table[ndx].dwForwardProto = MIB_IPPROTO_LOCAL;
753 /* punt on age and AS */
754 pIpForwardTable->table[ndx].dwForwardAge = 0;
755 pIpForwardTable->table[ndx].dwForwardNextHopAS = 0;
756 pIpForwardTable->table[ndx].dwForwardMetric1 =
757 table->routes[ndx].metric;
758 /* rest of the metrics are 0.. */
759 pIpForwardTable->table[ndx].dwForwardMetric2 = 0;
760 pIpForwardTable->table[ndx].dwForwardMetric3 = 0;
761 pIpForwardTable->table[ndx].dwForwardMetric4 = 0;
762 pIpForwardTable->table[ndx].dwForwardMetric5 = 0;
763 }
764 ret = NO_ERROR;
765 }
766 free(table);
767 }
768 else
769 ret = ERROR_OUTOFMEMORY;
770 }
771 }
772 return ret;
773}
774
775
776/******************************************************************
777 * GetIpNetTable (IPHLPAPI.@)
778 *
779 *
780 * PARAMS
781 *
782 * pIpNetTable [In/Out]
783 * pdwSize [In/Out]
784 * bOrder [In]
785 *
786 * RETURNS
787 *
788 * DWORD
789 *
790 */
791DWORD WINAPI GetIpNetTable(PMIB_IPNETTABLE pIpNetTable, PULONG pdwSize, BOOL bOrder)
792{
793 DWORD ret;
794
795 if (!pdwSize)
796 ret = ERROR_INVALID_PARAMETER;
797 else {
798 DWORD numEntries = getNumArpEntries();
799 ULONG size = sizeof(MIB_IPNETTABLE) + (numEntries - 1) *
800 sizeof(MIB_IPNETROW);
801
802 if (!pIpNetTable || *pdwSize < size) {
803 *pdwSize = size;
804 ret = ERROR_INSUFFICIENT_BUFFER;
805 }
806 else {
807 PMIB_IPNETTABLE table = getArpTable();
808
809 if (table) {
810 size = sizeof(MIB_IPNETTABLE) + (table->dwNumEntries - 1) *
811 sizeof(MIB_IPNETROW);
812 if (*pdwSize < size) {
813 *pdwSize = size;
814 ret = ERROR_INSUFFICIENT_BUFFER;
815 }
816 else {
817 if (bOrder)
818 FIXME(":order not implemented");
819 memcpy(pIpNetTable, table, size);
820 ret = NO_ERROR;
821 }
822 free(table);
823 }
824 else
825 ret = ERROR_OUTOFMEMORY;
826 }
827 }
828 return ret;
829}
830
831
832/******************************************************************
833 * GetIpStatistics (IPHLPAPI.@)
834 *
835 *
836 * PARAMS
837 *
838 * pStats [In/Out]
839 *
840 * RETURNS
841 *
842 * DWORD
843 *
844 */
845DWORD WINAPI GetIpStatistics(PMIB_IPSTATS pStats)
846{
847 return getIPStats(pStats);
848}
849
850
851/******************************************************************
852 * GetNetworkParams (IPHLPAPI.@)
853 *
854 *
855 * PARAMS
856 *
857 * pFixedInfo [In/Out]
858 * pOutBufLen [In/Out]
859 *
860 * RETURNS
861 *
862 * DWORD
863 *
864 */
865DWORD WINAPI GetNetworkParams(PFIXED_INFO pFixedInfo, PULONG pOutBufLen)
866{
867 DWORD size;
868
869 if (!pOutBufLen)
870 return ERROR_INVALID_PARAMETER;
871
872 size = sizeof(FIXED_INFO) + min(1, (_res.nscount - 1) *
873 sizeof(IP_ADDR_STRING));
874 if (!pFixedInfo || *pOutBufLen < size) {
875 *pOutBufLen = size;
876 return ERROR_BUFFER_OVERFLOW;
877 }
878
879 memset(pFixedInfo, 0, size);
880 size = sizeof(pFixedInfo->HostName);
881 GetComputerNameExA(ComputerNameDnsHostname, pFixedInfo->HostName, &size);
882 size = sizeof(pFixedInfo->DomainName);
883 GetComputerNameExA(ComputerNameDnsDomain, pFixedInfo->DomainName, &size);
884 if (_res.nscount > 0) {
885 PIP_ADDR_STRING ptr;
886 int i;
887
888 for (i = 0, ptr = &pFixedInfo->DnsServerList; i < _res.nscount;
889 i++, ptr = ptr->Next) {
890 toIPAddressString(_res.nsaddr_list[i].sin_addr.s_addr,
891 ptr->IpAddress.String);
892 ptr->Next = (PIP_ADDR_STRING)((PBYTE)ptr + sizeof(IP_ADDRESS_STRING));
893 }
894 }
895 /* FIXME: can check whether routing's enabled in /proc/sys/net/ipv4/ip_forward
896 I suppose could also check for a listener on port 53 to set EnableDns */
897 return NO_ERROR;
898}
899
900
901/******************************************************************
902 * GetNumberOfInterfaces (IPHLPAPI.@)
903 *
904 *
905 * PARAMS
906 *
907 * pdwNumIf [In/Out]
908 *
909 * RETURNS
910 *
911 * DWORD
912 *
913 */
914DWORD WINAPI GetNumberOfInterfaces(PDWORD pdwNumIf)
915{
916 DWORD ret;
917
918 if (!pdwNumIf)
919 ret = ERROR_INVALID_PARAMETER;
920 else {
921 *pdwNumIf = getNumInterfaces();
922 ret = NO_ERROR;
923 }
924 return ret;
925}
926
927
928/******************************************************************
929 * GetPerAdapterInfo (IPHLPAPI.@)
930 *
931 *
932 * PARAMS
933 *
934 * IfIndex [In]
935 * pPerAdapterInfo [In/Out]
936 * pOutBufLen [In/Out]
937 *
938 * RETURNS
939 *
940 * DWORD
941 *
942 */
943DWORD WINAPI GetPerAdapterInfo(ULONG IfIndex, PIP_PER_ADAPTER_INFO pPerAdapterInfo, PULONG pOutBufLen)
944{
945 FIXME(":stub\n");
946 /* marking Win2K+ functions not supported */
947 return ERROR_NOT_SUPPORTED;
948}
949
950
951/******************************************************************
952 * GetRTTAndHopCount (IPHLPAPI.@)
953 *
954 *
955 * PARAMS
956 *
957 * DestIpAddress [In]
958 * HopCount [In/Out]
959 * MaxHops [In]
960 * RTT [In/Out]
961 *
962 * RETURNS
963 *
964 * BOOL
965 *
966 */
967BOOL WINAPI GetRTTAndHopCount(IPAddr DestIpAddress, PULONG HopCount, ULONG MaxHops, PULONG RTT)
968{
969 FIXME(":stub\n");
970 return (BOOL) 0;
971}
972
973
974/******************************************************************
975 * GetTcpStatistics (IPHLPAPI.@)
976 *
977 *
978 * PARAMS
979 *
980 * pStats [In/Out]
981 *
982 * RETURNS
983 *
984 * DWORD
985 *
986 */
987DWORD WINAPI GetTcpStatistics(PMIB_TCPSTATS pStats)
988{
989 return getTCPStats(pStats);
990}
991
992
993/******************************************************************
994 * GetTcpTable (IPHLPAPI.@)
995 *
996 *
997 * PARAMS
998 *
999 * pTcpTable [In/Out]
1000 * pdwSize [In/Out]
1001 * bOrder [In]
1002 *
1003 * RETURNS
1004 *
1005 * DWORD
1006 *
1007 */
1008DWORD WINAPI GetTcpTable(PMIB_TCPTABLE pTcpTable, PDWORD pdwSize, BOOL bOrder)
1009{
1010 DWORD ret;
1011
1012 if (!pdwSize)
1013 ret = ERROR_INVALID_PARAMETER;
1014 else {
1015 DWORD numEntries = getNumTcpEntries();
1016 ULONG size = sizeof(MIB_TCPTABLE) + (numEntries - 1) * sizeof(MIB_TCPROW);
1017
1018 if (!pTcpTable || *pdwSize < size) {
1019 *pdwSize = size;
1020 ret = ERROR_INSUFFICIENT_BUFFER;
1021 }
1022 else {
1023 PMIB_TCPTABLE table = getTcpTable();
1024
1025 if (table) {
1026 size = sizeof(MIB_TCPTABLE) + (table->dwNumEntries - 1) *
1027 sizeof(MIB_TCPROW);
1028 if (*pdwSize < size) {
1029 *pdwSize = size;
1030 ret = ERROR_INSUFFICIENT_BUFFER;
1031 }
1032 else {
1033 if (bOrder)
1034 FIXME(":order not implemented");
1035 memcpy(pTcpTable, table, size);
1036 ret = NO_ERROR;
1037 }
1038 free(table);
1039 }
1040 else
1041 ret = ERROR_OUTOFMEMORY;
1042 }
1043 }
1044 return ret;
1045}
1046
1047
1048/******************************************************************
1049 * GetUdpStatistics (IPHLPAPI.@)
1050 *
1051 *
1052 * PARAMS
1053 *
1054 * pStats [In/Out]
1055 *
1056 * RETURNS
1057 *
1058 * DWORD
1059 *
1060 */
1061DWORD WINAPI GetUdpStatistics(PMIB_UDPSTATS pStats)
1062{
1063 return getUDPStats(pStats);
1064}
1065
1066
1067/******************************************************************
1068 * GetUdpTable (IPHLPAPI.@)
1069 *
1070 *
1071 * PARAMS
1072 *
1073 * pUdpTable [In/Out]
1074 * pdwSize [In/Out]
1075 * bOrder [In]
1076 *
1077 * RETURNS
1078 *
1079 * DWORD
1080 *
1081 */
1082DWORD WINAPI GetUdpTable(PMIB_UDPTABLE pUdpTable, PDWORD pdwSize, BOOL bOrder)
1083{
1084 DWORD ret;
1085
1086 if (!pdwSize)
1087 ret = ERROR_INVALID_PARAMETER;
1088 else {
1089 DWORD numEntries = getNumUdpEntries();
1090 ULONG size = sizeof(MIB_UDPTABLE) + (numEntries - 1) * sizeof(MIB_UDPROW);
1091
1092 if (!pUdpTable || *pdwSize < size) {
1093 *pdwSize = size;
1094 ret = ERROR_INSUFFICIENT_BUFFER;
1095 }
1096 else {
1097 PMIB_UDPTABLE table = getUdpTable();
1098
1099 if (table) {
1100 size = sizeof(MIB_UDPTABLE) + (table->dwNumEntries - 1) *
1101 sizeof(MIB_UDPROW);
1102 if (*pdwSize < size) {
1103 *pdwSize = size;
1104 ret = ERROR_INSUFFICIENT_BUFFER;
1105 }
1106 else {
1107 if (bOrder)
1108 FIXME(":order not implemented");
1109 memcpy(pUdpTable, table, size);
1110 ret = NO_ERROR;
1111 }
1112 free(table);
1113 }
1114 else
1115 ret = ERROR_OUTOFMEMORY;
1116 }
1117 }
1118 return ret;
1119}
1120
1121
1122/******************************************************************
1123 * GetUniDirectionalAdapterInfo (IPHLPAPI.@)
1124 *
1125 *
1126 * PARAMS
1127 *
1128 * pIPIfInfo [In/Out]
1129 * dwOutBufLen [In/Out]
1130 *
1131 * RETURNS
1132 *
1133 * DWORD
1134 *
1135 */
1136DWORD WINAPI GetUniDirectionalAdapterInfo(PIP_UNIDIRECTIONAL_ADAPTER_ADDRESS pIPIfInfo, PULONG dwOutBufLen)
1137{
1138 /* a unidirectional adapter?? not bloody likely! */
1139 return ERROR_NOT_SUPPORTED;
1140}
1141
1142
1143/******************************************************************
1144 * IpReleaseAddress (IPHLPAPI.@)
1145 *
1146 *
1147 * PARAMS
1148 *
1149 * AdapterInfo [In/Out]
1150 *
1151 * RETURNS
1152 *
1153 * DWORD
1154 *
1155 */
1156DWORD WINAPI IpReleaseAddress(PIP_ADAPTER_INDEX_MAP AdapterInfo)
1157{
1158 /* not a stub, never going to support this (and I never mark an adapter as
1159 DHCP enabled, see GetAdaptersInfo, so this should never get called) */
1160 return ERROR_NOT_SUPPORTED;
1161}
1162
1163
1164/******************************************************************
1165 * IpRenewAddress (IPHLPAPI.@)
1166 *
1167 *
1168 * PARAMS
1169 *
1170 * AdapterInfo [In/Out]
1171 *
1172 * RETURNS
1173 *
1174 * DWORD
1175 *
1176 */
1177DWORD WINAPI IpRenewAddress(PIP_ADAPTER_INDEX_MAP AdapterInfo)
1178{
1179 /* not a stub, never going to support this (and I never mark an adapter as
1180 DHCP enabled, see GetAdaptersInfo, so this should never get called) */
1181 return ERROR_NOT_SUPPORTED;
1182}
1183
1184
1185/******************************************************************
1186 * NotifyAddrChange (IPHLPAPI.@)
1187 *
1188 *
1189 * PARAMS
1190 *
1191 * Handle [In/Out]
1192 * overlapped [In/Out]
1193 *
1194 * RETURNS
1195 *
1196 * DWORD
1197 *
1198 */
1199DWORD WINAPI NotifyAddrChange(PHANDLE Handle, LPOVERLAPPED overlapped)
1200{
1201 FIXME(":stub\n");
1202 /* marking Win2K+ functions not supported */
1203 return ERROR_NOT_SUPPORTED;
1204}
1205
1206
1207/******************************************************************
1208 * NotifyRouteChange (IPHLPAPI.@)
1209 *
1210 *
1211 * PARAMS
1212 *
1213 * Handle [In/Out]
1214 * overlapped [In/Out]
1215 *
1216 * RETURNS
1217 *
1218 * DWORD
1219 *
1220 */
1221DWORD WINAPI NotifyRouteChange(PHANDLE Handle, LPOVERLAPPED overlapped)
1222{
1223 FIXME(":stub\n");
1224 /* marking Win2K+ functions not supported */
1225 return ERROR_NOT_SUPPORTED;
1226}
1227
1228
1229/******************************************************************
1230 * SendARP (IPHLPAPI.@)
1231 *
1232 *
1233 * PARAMS
1234 *
1235 * DestIP [In]
1236 * SrcIP [In]
1237 * pMacAddr [In/Out]
1238 * PhyAddrLen [In/Out]
1239 *
1240 * RETURNS
1241 *
1242 * DWORD
1243 *
1244 */
1245DWORD WINAPI SendARP(IPAddr DestIP, IPAddr SrcIP, PULONG pMacAddr, PULONG PhyAddrLen)
1246{
1247 FIXME(":stub\n");
1248 /* marking Win2K+ functions not supported */
1249 return ERROR_NOT_SUPPORTED;
1250}
1251
1252
1253/******************************************************************
1254 * SetIfEntry (IPHLPAPI.@)
1255 *
1256 *
1257 * PARAMS
1258 *
1259 * pIfRow [In/Out]
1260 *
1261 * RETURNS
1262 *
1263 * DWORD
1264 *
1265 */
1266DWORD WINAPI SetIfEntry(PMIB_IFROW pIfRow)
1267{
1268 /* this is supposed to set an administratively interface up or down.
1269 Could do SIOCSIFFLAGS and set/clear IFF_UP, but, not sure I want to, and
1270 this sort of down is indistinguishable from other sorts of down (e.g. no
1271 link). */
1272 FIXME(":stub\n");
1273 return ERROR_NOT_SUPPORTED;
1274}
1275
1276
1277/******************************************************************
1278 * SetIpForwardEntry (IPHLPAPI.@)
1279 *
1280 *
1281 * PARAMS
1282 *
1283 * pRoute [In/Out]
1284 *
1285 * RETURNS
1286 *
1287 * DWORD
1288 *
1289 */
1290DWORD WINAPI SetIpForwardEntry(PMIB_IPFORWARDROW pRoute)
1291{
1292 /* this is to add a route entry, how's it distinguishable from
1293 CreateIpForwardEntry?
1294 could use SIOCADDRT, not sure I want to */
1295 FIXME(":stub\n");
1296 return (DWORD) 0;
1297}
1298
1299
1300/******************************************************************
1301 * SetIpNetEntry (IPHLPAPI.@)
1302 *
1303 *
1304 * PARAMS
1305 *
1306 * pArpEntry [In/Out]
1307 *
1308 * RETURNS
1309 *
1310 * DWORD
1311 *
1312 */
1313DWORD WINAPI SetIpNetEntry(PMIB_IPNETROW pArpEntry)
1314{
1315 /* same as CreateIpNetEntry here, could use SIOCSARP, not sure I want to */
1316 FIXME(":stub\n");
1317 return (DWORD) 0;
1318}
1319
1320
1321/******************************************************************
1322 * SetIpStatistics (IPHLPAPI.@)
1323 *
1324 *
1325 * PARAMS
1326 *
1327 * pIpStats [In/Out]
1328 *
1329 * RETURNS
1330 *
1331 * DWORD
1332 *
1333 */
1334DWORD WINAPI SetIpStatistics(PMIB_IPSTATS pIpStats)
1335{
1336 FIXME(":stub\n");
1337 return (DWORD) 0;
1338}
1339
1340
1341/******************************************************************
1342 * SetIpTTL (IPHLPAPI.@)
1343 *
1344 *
1345 * PARAMS
1346 *
1347 * nTTL [In]
1348 *
1349 * RETURNS
1350 *
1351 * DWORD
1352 *
1353 */
1354DWORD WINAPI SetIpTTL(UINT nTTL)
1355{
1356 /* could echo nTTL > /proc/net/sys/net/ipv4/ip_default_ttl, not sure I
1357 want to. Could map EACCESS to ERROR_ACCESS_DENIED, I suppose */
1358 FIXME(":stub\n");
1359 return (DWORD) 0;
1360}
1361
1362
1363/******************************************************************
1364 * SetTcpEntry (IPHLPAPI.@)
1365 *
1366 *
1367 * PARAMS
1368 *
1369 * pTcpRow [In/Out]
1370 *
1371 * RETURNS
1372 *
1373 * DWORD
1374 *
1375 */
1376DWORD WINAPI SetTcpEntry(PMIB_TCPROW pTcpRow)
1377{
1378 FIXME(":stub\n");
1379 return (DWORD) 0;
1380}
1381
1382
1383/******************************************************************
1384 * UnenableRouter (IPHLPAPI.@)
1385 *
1386 *
1387 * PARAMS
1388 *
1389 * pOverlapped [In/Out]
1390 * lpdwEnableCount [In/Out]
1391 *
1392 * RETURNS
1393 *
1394 * DWORD
1395 *
1396 */
1397DWORD WINAPI UnenableRouter(OVERLAPPED * pOverlapped, LPDWORD lpdwEnableCount)
1398{
1399 FIXME(":stub\n");
1400 /* could echo "0" > /proc/net/sys/net/ipv4/ip_forward, not sure I want to
1401 could map EACCESS to ERROR_ACCESS_DENIED, I suppose
1402 marking Win2K+ functions not supported */
1403 return ERROR_NOT_SUPPORTED;
1404}