moving on top of ourself is simple
[heimdal.git] / lib / roken / getifaddrs_w32.c
blobff0250baa38539207fed885df116c135e9095403
1 /***********************************************************************
2 * Copyright (c) 2009, Secure Endpoints Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
22 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28 * OF THE POSSIBILITY OF SUCH DAMAGE.
30 **********************************************************************/
32 #ifdef HAVE_CONFIG_H
33 #include<config.h>
34 #endif
36 #include <roken.h>
38 #include <ifaddrs.h>
40 #ifndef _WIN32
41 #error This is a Windows specific implementation.
42 #endif
44 static struct sockaddr *
45 dupaddr(const sockaddr_gen * src)
47 sockaddr_gen * d = malloc(sizeof(*d));
49 if (d) {
50 memcpy(d, src, sizeof(*d));
53 return (struct sockaddr *) d;
56 int ROKEN_LIB_FUNCTION
57 rk_getifaddrs(struct ifaddrs **ifpp)
59 SOCKET s = INVALID_SOCKET;
60 size_t il_len = 8192;
61 int ret = -1;
62 INTERFACE_INFO *il = NULL;
64 *ifpp = NULL;
66 s = socket(AF_INET, SOCK_DGRAM, 0);
67 if (s == INVALID_SOCKET)
68 return -1;
70 for (;;) {
71 DWORD cbret = 0;
73 il = malloc(il_len);
74 if (!il)
75 break;
77 ZeroMemory(il, il_len);
79 if (WSAIoctl(s, SIO_GET_INTERFACE_LIST, NULL, 0,
80 (LPVOID) il, (DWORD) il_len, &cbret,
81 NULL, NULL) == 0) {
82 il_len = cbret;
83 break;
86 free (il);
87 il = NULL;
89 if (WSAGetLastError() == WSAEFAULT && cbret > il_len) {
90 il_len = cbret;
91 } else {
92 break;
96 if (!il)
97 goto _exit;
99 /* il is an array of INTERFACE_INFO structures. il_len has the
100 actual size of the buffer. The number of elements is
101 il_len/sizeof(INTERFACE_INFO) */
104 size_t n = il_len / sizeof(INTERFACE_INFO);
105 size_t i;
107 for (i = 0; i < n; i++ ) {
108 struct ifaddrs *ifp;
110 ifp = malloc(sizeof(*ifp));
111 if (ifp == NULL)
112 break;
114 ZeroMemory(ifp, sizeof(*ifp));
116 ifp->ifa_next = NULL;
117 ifp->ifa_name = NULL;
118 ifp->ifa_flags = il[i].iiFlags;
119 ifp->ifa_addr = dupaddr(&il[i].iiAddress);
120 ifp->ifa_netmask = dupaddr(&il[i].iiNetmask);
121 ifp->ifa_broadaddr = dupaddr(&il[i].iiBroadcastAddress);
122 ifp->ifa_data = NULL;
124 *ifpp = ifp;
125 ifpp = &ifp->ifa_next;
128 if (i == n)
129 ret = 0;
132 _exit:
134 if (s != INVALID_SOCKET)
135 closesocket(s);
137 if (il)
138 free (il);
140 return ret;
143 void ROKEN_LIB_FUNCTION
144 rk_freeifaddrs(struct ifaddrs *ifp)
146 struct ifaddrs *p, *q;
148 for(p = ifp; p; ) {
149 if (p->ifa_name)
150 free(p->ifa_name);
151 if(p->ifa_addr)
152 free(p->ifa_addr);
153 if(p->ifa_dstaddr)
154 free(p->ifa_dstaddr);
155 if(p->ifa_netmask)
156 free(p->ifa_netmask);
157 if(p->ifa_data)
158 free(p->ifa_data);
159 q = p;
160 p = p->ifa_next;
161 free(q);