Bug Summary

File:libs/sofia-sip/libsofia-sip-ua/su/su_localinfo.c
Location:line 231, column 5
Description:Value stored to 'ip4' is never read

Annotated Source Code

1/*
2 * This file is part of the Sofia-SIP package
3 *
4 * Copyright (C) 2005 Nokia Corporation.
5 *
6 * Contact: Pekka Pessi <pekka.pessi@nokia.com>
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 *
23 */
24
25/**@ingroup su_socket
26 * @CFILE su_localinfo.c
27 *
28 * Obtain list of local addresses.
29 *
30 * @author Pekka Pessi <Pekka.Pessi@nokia.com>
31 * @author Martti Mela <Martti.Mela@nokia.com>
32 *
33 * @date Created: Wed Oct 4 14:09:29 EET 2000 ppessi
34 */
35
36#include "config.h"
37
38#if HAVE_SYS_SOCKIO_H
39#include <sys/sockio.h>
40#endif
41
42#include <sofia-sip/su.h>
43#include <sofia-sip/su_localinfo.h>
44#include <sofia-sip/su_string.h>
45#include "su_module_debug.h"
46
47#include <stdio.h>
48#include <stdlib.h>
49#include <string.h>
50#include <assert.h>
51#include <stddef.h>
52#include <sys/types.h>
53
54#if HAVE_SYS_SOCKET_H1
55#include <sys/socket.h>
56#endif
57#if HAVE_NETINET_IN_H1
58#include <netinet/in.h>
59#endif
60#if HAVE_SYS_IOCTL_H1
61#include <sys/ioctl.h>
62#endif
63#if HAVE_NET_IF_H1
64#include <net/if.h>
65#endif
66#if HAVE_NET_IF_TYPES_H
67#include <net/if_types.h>
68#endif
69
70#if SU_LOCALINFO_TEST
71
72#undef USE_LOCALINFO01
73
74#elif HAVE_GETIFADDRS1
75
76#define USE_LOCALINFO01 1
77#define localinfo0bsd_localinfo bsd_localinfo
78static int bsd_localinfo(su_localinfo_t const *, su_localinfo_t **);
79
80#elif HAVE_IPHLPAPI_H
81
82#include <iphlpapi.h>
83#define USE_LOCALINFO01 1
84#define localinfo0bsd_localinfo win_localinfo
85static int win_localinfo(su_localinfo_t const *, su_localinfo_t **);
86
87#else
88/* No localinfo0(), use localinfo4() and localinfo6() */
89
90#undef USE_LOCALINFO01
91static int localinfo4(su_localinfo_t const *, su_localinfo_t **);
92# if SU_HAVE_IN61
93static int localinfo6(su_localinfo_t const *, su_localinfo_t **);
94# endif
95
96#endif
97
98static int li_scope4(uint32_t ip4);
99#if SU_HAVE_IN61
100static int li_scope6(struct in6_addr const *ip6);
101#endif
102
103#if !SU_LOCALINFO_TEST
104
105static int li_name(su_localinfo_t const*, int, su_sockaddr_t const*, char **);
106static void li_sort(su_localinfo_t *i, su_localinfo_t **rresult);
107
108/** @brief Request local address information.
109 *
110 * Gather the network interfaces and the addresses corresponding to them,
111 * check if they match to the search criteria specifed by @a hints and
112 * return a list of matching local address information in the @a
113 * return_localinfo. The local address information may include IPv4/IPv6
114 * addresses, interface name, interface index, address scope, and domain
115 * names corresponding to the local addresses.
116 *
117 * @param[in] hints specifies selection criteria
118 * @param[out] return_localinfo return list of local addresses
119 *
120 * @par Selection criteria - hints
121 *
122 * The selection criteria @a hints is used to select which addresses are
123 * returned and what kind of information is included in the @a res list.
124 *
125 * @par Selection by flags - hints->li_flags
126 *
127 * The @a hints->li_flags contain flags, which can be combined with bit-wise
128 * or. The currently defined flags are as follows:
129 *
130 * - #LI_V4MAPPED: when returning IPv4 addresses, map them as IPv6
131 * addresses. If this flag is specified, IPv4 addresses are returned even
132 * if @a hints->li_family is set to @c AF_INET6.
133 * - #LI_CANONNAME: return the domain name (DNS PTR) corresponding to the
134 * local address in @a li_canonname.
135 * - #LI_NAMEREQD: Do not return addresses not in DNS.
136 * - #LI_NUMERIC: instead of domain name, return the text presentation of
137 * the addresss in @a li_canonname.
138 * - #LI_DOWN: include interfaces and their addresses even if the interfaces
139 * are down. New in @VERSION_1_12_2.
140 * - #LI_IFNAME: return the interface name in @a li_ifname.
141 *
142 * @par Selection by address family - hints->li_family
143 *
144 * The address family can have three values: 0, AF_INET and AF_INET6. If
145 * address family @a hints->li_family, both IPv4 and IPv6 addresses are
146 * returned.
147 *
148 * @par Selection by interface index - hints->li_index
149 *
150 * If the field @a hints->li_index is non-zero, only the addresses assigned
151 * to the interface with given index are returned. The list of interface
152 * indices and names can be obtained by the function @c su_if_names().
153 *
154 * @par Selection by interface name - hints->li_ifname
155 *
156 * If the field @a hints->li_ifname is not NULL, only the addresses assigned
157 * to the named interface are returned. The list of interface names can be
158 * obtained by the function @c su_if_names().
159 *
160 * @par Selection by address scope - hints->li_scope
161 *
162 * If the field @a hints->li_scope is nonzero, only the addresses with
163 * matching scope are returned. The different address scopes can be combined
164 * with bitwise or. They are defined as follows
165 * - #LI_SCOPE_HOST: host-local address, valid within host (::1, 127.0.0.1/8)
166 * - #LI_SCOPE_LINK: link-local address, valid within link
167 * (IP6 addresses with prefix fe80::/10,
168 * IP4 addresses in net 169.254.0.0/16).
169 * - #LI_SCOPE_SITE: site-local address, addresses valid within organization
170 * (IPv6 addresses with prefix fec::/10,
171 * private IPv4 addresses in nets 10.0.0.0/8, 172.16.0.0/12,
172 * and 192.168.0.0/16 as defined in @RFC1918)
173 * - #LI_SCOPE_GLOBAL: global address.
174 *
175 * For instance, setting @a hints->li_scope to @c LI_SCOPE_GLOBAL | @c
176 * LI_SCOPE_SITE, both the @e global and @e site-local addresses are
177 * returned.
178 *
179 * @sa @RFC1918, @RFC4291, su_sockaddr_scope()
180 *
181 * @par Selection by domain name - hints->li_canonname
182 *
183 * If this field is non-null, the domain name (DNS PTR) corresponding to
184 * local IP addresses should match to the name given in this field.
185 *
186 * @return Zero (#ELI_NOERROR) when successful, or negative error code when
187 * failed.
188 *
189 * @par Diagnostics
190 * Use su_gli_strerror() in order to obtain a string describing the error
191 * code returned by su_getlocalinfo().
192 *
193 */
194int su_getlocalinfo(su_localinfo_t const *hints,
195 su_localinfo_t **return_localinfo)
196{
197 int error = 0, ip4 = 0;
198 int ip6 = 0;
199 su_localinfo_t *result = NULL((void*)0), **rr = &result;
200 su_localinfo_t hh[1] = {{ 0 }};
201
202 assert(return_localinfo)((return_localinfo) ? (void) (0) : __assert_fail ("return_localinfo"
, "su_localinfo.c", 202, __PRETTY_FUNCTION__))
;
203
204 *return_localinfo = NULL((void*)0);
205
206 if (hints) {
207 /* Copy hints so that it can be modified */
208 *hh = *hints;
209 if (hh->li_canonname)
210 hh->li_flags |= LI_CANONNAME;
211#if 0
212 /* hints->li_ifname is used to select by interface,
213 li_ifname is returned with LI_IFNAME flag
214 */
215 if ((hh->li_flags & LI_IFNAME) && hh->li_ifname == NULL((void*)0))
216 return ELI_BADHINTS;
217#endif
218 }
219
220 switch (hh->li_family) {
221#if SU_HAVE_IN61
222 case AF_INET610:
223 if (hh->li_flags & LI_V4MAPPED)
224 ip6 = ip4 = 1, hh->li_family = 0;
225 else
226 ip6 = 1;
227 break;
228#endif
229
230 case AF_INET2:
231 ip4 = 1;
Value stored to 'ip4' is never read
232 break;
233
234 case 0:
235 ip4 = 1;
236#if SU_HAVE_IN61
237 ip6 = 1;
238#endif
239
240 break;
241
242 default:
243 return -1;
244 }
245
246#if USE_LOCALINFO01
247 error = localinfo0bsd_localinfo(hh, rr);
248#else
249
250# if SU_HAVE_IN61
251 if (ip6) {
252 error = localinfo6(hh, rr);
253 if (error == ELI_NOADDRESS && ip4)
254 error = 0;
255
256 if (!error)
257 /* Search end of list */
258 for (; *rr; rr = &(*rr)->li_next)
259 ;
260 }
261# endif
262 if (ip4 && !error) {
263 /* Append IPv4 addresses */
264 error = localinfo4(hh, rr);
265 }
266#endif
267
268 if (ip6) {
269 /* Required to make compiler happy */
270 }
271 if (!result)
272 error = ELI_NOADDRESS;
273
274 if (!error)
275 li_sort(result, return_localinfo);
276 else
277 su_freelocalinfo(result);
278
279 return error;
280}
281
282#endif
283
284/** Free local address information.
285 *
286 * Free a list of su_localinfo_t structures obtained with su_getlocalinfo()
287 * or su_copylocalinfo() along with socket addresses and strings associated
288 * with them.
289 *
290 * @sa su_getlocalinfo(), su_copylocalinfo(), #su_localinfo_t
291 */
292void su_freelocalinfo(su_localinfo_t *tbf)
293{
294 su_localinfo_t *li;
295
296 for (li = tbf; li; li = tbf) {
297 tbf = li->li_next;
298 if (li->li_canonname)
299 free(li->li_canonname);
300 free(li);
301 }
302}
303
304/** Describe su_localinfo errors.
305 *
306 * The function su_gli_strerror() returns a string describing the error
307 * condition indicated by the code that was returned by the function
308 * su_getlocalinfo().
309 *
310 * @param error error code returned by su_getlocalinfo()
311 *
312 * @return
313 * A pointer to string describing the error condition.
314 */
315char const *su_gli_strerror(int error)
316{
317 switch (error) {
318 case ELI_NOERROR: return "No error";
319 case ELI_NOADDRESS: return "No matching address";
320 case ELI_MEMORY: return "Memory allocation error";
321 case ELI_FAMILY: return "Unknown address family";
322 case ELI_RESOLVER: return "Error when resolving address";
323 case ELI_SYSTEM: return "System error";
324 case ELI_BADHINTS: return "Invalid value for hints";
325 default: return "Unknown error";
326 }
327}
328
329/** Duplicate su_localinfo structure.
330 */
331su_localinfo_t *su_copylocalinfo(su_localinfo_t const *li0)
332{
333 size_t n;
334 su_localinfo_t *li, *retval = NULL((void*)0), **lli = &retval;
335
336# define SLEN(s)((s) ? strlen(s) + 1 : 0) ((s) ? strlen(s) + 1 : 0)
337
338 for (; li0 ; li0 = li0->li_next) {
339 n = sizeof(*li0) + li0->li_addrlen + SLEN(li0->li_ifname)((li0->li_ifname) ? strlen(li0->li_ifname) + 1 : 0);
340 if (!(li = calloc(1, n))) {
341 su_freelocalinfo(retval);
342 return NULL((void*)0);
343 }
344 *lli = li;
345 lli = &li->li_next;
346 li->li_flags = li0->li_flags;
347 li->li_family = li0->li_family;
348 li->li_index = li0->li_index;
349 li->li_scope = li0->li_scope;
350 li->li_addrlen = li0->li_addrlen;
351 li->li_addr = memcpy(li + 1, li0->li_addr, li0->li_addrlen);
352
353 if (li0->li_canonname) {
354 if (!(li->li_canonname = malloc(SLEN(li0->li_canonname)((li0->li_canonname) ? strlen(li0->li_canonname) + 1 : 0
)
))) {
355 su_freelocalinfo(retval);
356 return NULL((void*)0);
357 }
358 strcpy(li->li_canonname, li0->li_canonname);
359 }
360
361 if (li0->li_ifname)
362 li->li_ifname = strcpy(li->li_addrlen + (char *)li->li_addr,
363 li0->li_ifname);
364 }
365
366 return retval;
367}
368
369
370/** Return IPv4 address scope */
371static int
372li_scope4(uint32_t ip4)
373{
374 ip4 = ntohl(ip4)(__extension__ ({ unsigned int __v, __x = (ip4); if (__builtin_constant_p
(__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x
) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) <<
8) | (((__x) & 0x000000ff) << 24)); else __asm__ (
"bswap %0" : "=r" (__v) : "0" (__x)); __v; }))
;
375
376 if (0x7f000000 == (ip4 & 0xff000000))
377 return LI_SCOPE_HOST;
378 /* draft-ietf-zeroconf-ipv4-linklocal-02.txt - 169.254/16. */
379 else if (0xa9fe0000 == (ip4 & 0xffff0000))
380 return LI_SCOPE_LINK;
381 /* RFC1918 - 10/8, 172.16/12, 192.168/16. */
382 else if (0x0a000000 == (ip4 & 0xff000000) ||
383 0xac100000 == (ip4 & 0xfff00000) ||
384 0xc0a80000 == (ip4 & 0xffff0000))
385 return LI_SCOPE_SITE;
386 else
387 return LI_SCOPE_GLOBAL;
388}
389
390#if SU_HAVE_IN61
391
392#if HAVE_WINSOCK2_H
393#define IN6_IS_ADDR_LOOPBACK SU_IN6_IS_ADDR_LOOPBACK
394su_inlinestatic inline int
395IN6_IS_ADDR_LOOPBACK(void const *ip6)(__extension__ ({ const struct in6_addr *__a = (const struct in6_addr
*) (void const *ip6); __a->__in6_u.__u6_addr32[0] == 0 &&
__a->__in6_u.__u6_addr32[1] == 0 && __a->__in6_u
.__u6_addr32[2] == 0 && __a->__in6_u.__u6_addr32[3
] == (__extension__ ({ unsigned int __v, __x = (1); if (__builtin_constant_p
(__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x
) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) <<
8) | (((__x) & 0x000000ff) << 24)); else __asm__ (
"bswap %0" : "=r" (__v) : "0" (__x)); __v; })); }))
396{
397 uint8_t const *u = ip6;
398
399 return
400 u[0] == 0 && u[1] == 0 && u[2] == 0 && u[3] == 0 &&
401 u[4] == 0 && u[5] == 0 && u[6] == 0 && u[7] == 0 &&
402 u[8] == 0 && u[9] == 0 && u[10] == 0 && u[11] == 0 &&
403 u[12] == 0 && u[13] == 0 && u[14] == 0 && u[15] == 1;
404}
405#endif
406
407/** Return IPv6 address scope */
408static int
409li_scope6(struct in6_addr const *ip6)
410{
411 if (IN6_IS_ADDR_V4MAPPED(ip6)(__extension__ ({ const struct in6_addr *__a = (const struct in6_addr
*) (ip6); __a->__in6_u.__u6_addr32[0] == 0 && __a
->__in6_u.__u6_addr32[1] == 0 && __a->__in6_u.__u6_addr32
[2] == (__extension__ ({ unsigned int __v, __x = (0xffff); if
(__builtin_constant_p (__x)) __v = ((((__x) & 0xff000000
) >> 24) | (((__x) & 0x00ff0000) >> 8) | (((__x
) & 0x0000ff00) << 8) | (((__x) & 0x000000ff) <<
24)); else __asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); __v
; })); }))
|| IN6_IS_ADDR_V4COMPAT(ip6)(__extension__ ({ const struct in6_addr *__a = (const struct in6_addr
*) (ip6); __a->__in6_u.__u6_addr32[0] == 0 && __a
->__in6_u.__u6_addr32[1] == 0 && __a->__in6_u.__u6_addr32
[2] == 0 && (__extension__ ({ unsigned int __v, __x =
(__a->__in6_u.__u6_addr32[3]); if (__builtin_constant_p (
__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x)
& 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) <<
8) | (((__x) & 0x000000ff) << 24)); else __asm__ (
"bswap %0" : "=r" (__v) : "0" (__x)); __v; })) > 1; }))
) {
412 uint32_t *u = (uint32_t *)(ip6->s6_addr__in6_u.__u6_addr8 + 12);
413
414 uint32_t ip4 = *u;
415 return li_scope4(ip4);
416 }
417 else if (IN6_IS_ADDR_LOOPBACK(ip6)(__extension__ ({ const struct in6_addr *__a = (const struct in6_addr
*) (ip6); __a->__in6_u.__u6_addr32[0] == 0 && __a
->__in6_u.__u6_addr32[1] == 0 && __a->__in6_u.__u6_addr32
[2] == 0 && __a->__in6_u.__u6_addr32[3] == (__extension__
({ unsigned int __v, __x = (1); if (__builtin_constant_p (__x
)) __v = ((((__x) & 0xff000000) >> 24) | (((__x) &
0x00ff0000) >> 8) | (((__x) & 0x0000ff00) <<
8) | (((__x) & 0x000000ff) << 24)); else __asm__ (
"bswap %0" : "=r" (__v) : "0" (__x)); __v; })); }))
)
418 return LI_SCOPE_HOST;
419 else if (IN6_IS_ADDR_LINKLOCAL(ip6)(__extension__ ({ const struct in6_addr *__a = (const struct in6_addr
*) (ip6); (__a->__in6_u.__u6_addr32[0] & (__extension__
({ unsigned int __v, __x = (0xffc00000); if (__builtin_constant_p
(__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x
) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) <<
8) | (((__x) & 0x000000ff) << 24)); else __asm__ (
"bswap %0" : "=r" (__v) : "0" (__x)); __v; }))) == (__extension__
({ unsigned int __v, __x = (0xfe800000); if (__builtin_constant_p
(__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x
) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) <<
8) | (((__x) & 0x000000ff) << 24)); else __asm__ (
"bswap %0" : "=r" (__v) : "0" (__x)); __v; })); }))
)
420 return LI_SCOPE_LINK;
421 else if (IN6_IS_ADDR_SITELOCAL(ip6)(__extension__ ({ const struct in6_addr *__a = (const struct in6_addr
*) (ip6); (__a->__in6_u.__u6_addr32[0] & (__extension__
({ unsigned int __v, __x = (0xffc00000); if (__builtin_constant_p
(__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x
) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) <<
8) | (((__x) & 0x000000ff) << 24)); else __asm__ (
"bswap %0" : "=r" (__v) : "0" (__x)); __v; }))) == (__extension__
({ unsigned int __v, __x = (0xfec00000); if (__builtin_constant_p
(__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x
) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) <<
8) | (((__x) & 0x000000ff) << 24)); else __asm__ (
"bswap %0" : "=r" (__v) : "0" (__x)); __v; })); }))
)
422 return LI_SCOPE_SITE;
423 else
424 return LI_SCOPE_GLOBAL;
425}
426#endif
427
428/** Return the scope of address in the sockaddr structure */
429int su_sockaddr_scope(su_sockaddr_t const *su, socklen_t sulen)
430{
431 if (sulen >= (sizeof su->su_sin) && su->su_familysu_sa.sa_family == AF_INET2)
432 return li_scope4(su->su_sin.sin_addr.s_addr);
433
434#if SU_HAVE_IN61
435 if (sulen >= (sizeof su->su_sin6) && su->su_familysu_sa.sa_family == AF_INET610)
436 return li_scope6(&su->su_sin6.sin6_addr);
437#endif
438
439 return 0;
440}
441
442#if HAVE_OPEN_C
443extern int su_get_local_ip_addr(su_sockaddr_t *su);
444#endif
445
446#if SU_LOCALINFO_TEST
447
448#elif USE_LOCALINFO01
449/* no localinfo4 */
450#elif HAVE_IFCONF1
451#if __APPLE_CC__
452/** Build a list of local IPv4 addresses and append it to *rresult. */
453static
454int localinfo4(su_localinfo_t const *hints, su_localinfo_t **rresult)
455{
456 su_localinfo_t *li = NULL((void*)0);
457 su_sockaddr_t *su;
458 int error = ELI_NOADDRESS;
459 char *canonname = NULL((void*)0);
460 su_socket_t s;
461
462#if SU_HAVE_IN61
463 int su_xtra = (hints->li_flags & LI_V4MAPPED) ? sizeof(*su) : 0;
464#else
465 int const su_xtra = 0;
466#endif
467
468 struct ifconf ifc;
469 int numifs;
470 char *buffer;
471 struct ifreq *ifr, *ifr_next;
472
473 su_sockaddr_t *sa;
474 socklen_t salen = sizeof(*sa);
475 int scope = 0, gni_flags = 0;
476
477 s = su_socket(AF_INET2, SOCK_DGRAMSOCK_DGRAM, 0);
478 if (s == -1) {
479 SU_DEBUG_1(("su_localinfo: su_socket failed: %s\n",((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 1 ? (_su_llog((su_log_global
), 1, "su_localinfo.c", (const char *)__func__, 480, "su_localinfo: su_socket failed: %s\n"
, su_strerror(su_errno()))) : (void)0)
480 su_strerror(su_errno())))((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 1 ? (_su_llog((su_log_global
), 1, "su_localinfo.c", (const char *)__func__, 480, "su_localinfo: su_socket failed: %s\n"
, su_strerror(su_errno()))) : (void)0)
;
481 return ELI_SYSTEM;
482 }
483
484
485 li = calloc(1, (sizeof *li) + (sizeof *sa));
486 sa = (void *)(li + 1);
487
488 error = getsockname(s, (struct sockaddr *) sa, &salen);
489 if (error < 0 && errno(*__errno_location ()) == SOCKET_ERRORSOCKET_ERROR) {
490 SU_DEBUG_1(("%s: getsockname() failed: %s\n", __func__,((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 1 ? (_su_llog((su_log_global
), 1, "su_localinfo.c", (const char *)__func__, 491, "%s: getsockname() failed: %s\n"
, __func__, su_strerror(su_errno()))) : (void)0)
491 su_strerror(su_errno())))((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 1 ? (_su_llog((su_log_global
), 1, "su_localinfo.c", (const char *)__func__, 491, "%s: getsockname() failed: %s\n"
, __func__, su_strerror(su_errno()))) : (void)0)
;
492 }
493
494 error = bind(s, (struct sockaddr *) sa, salen);
495
496 if (error < 0) {
497 SU_DEBUG_1(("%s: bind() failed: %s\n", __func__,((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 1 ? (_su_llog((su_log_global
), 1, "su_localinfo.c", (const char *)__func__, 498, "%s: bind() failed: %s\n"
, __func__, su_strerror(su_errno()))) : (void)0)
498 su_strerror(su_errno())))((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 1 ? (_su_llog((su_log_global
), 1, "su_localinfo.c", (const char *)__func__, 498, "%s: bind() failed: %s\n"
, __func__, su_strerror(su_errno()))) : (void)0)
;
499 goto err;
500 }
501
502 su_close(s);
503
504 scope = li_scope4(sa->su_sin.sin_addr.s_addr);
505
506 if (scope == LI_SCOPE_HOST || scope == LI_SCOPE_LINK)
507 gni_flags = NI_NUMERICHOST1;
508
509 if (su_xtra) {
510 /* Map IPv4 address to IPv6 address */
511 memset(sa, 0, sizeof(*sa));
512 sa->su_familysu_sa.sa_family = AF_INET610;
513 ((int32_t*)&sa->su_sin6.sin6_addr)[3] = sa->su_sin.sin_addr.s_addr;
514 ((int32_t*)&sa->su_sin6.sin6_addr)[2] = htonl(0xffff)(__extension__ ({ unsigned int __v, __x = (0xffff); if (__builtin_constant_p
(__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x
) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) <<
8) | (((__x) & 0x000000ff) << 24)); else __asm__ (
"bswap %0" : "=r" (__v) : "0" (__x)); __v; }))
;
515 }
516
517 li->li_family = sa->su_familysu_sa.sa_family;
518 li->li_scope = scope;
519 li->li_index = 0;
520 li->li_addrlen = su_sockaddr_size(sa)((socklen_t)((sa)->su_sa.sa_family == 2 ? sizeof((sa)->
su_sin) : ((sa)->su_sa.sa_family == 10 ? sizeof((sa)->su_sin6
) : sizeof(*sa))))
;
521 li->li_addr = sa;
522
523 if ((error = li_name(hints, gni_flags, sa, &canonname)) < 0)
524 goto err;
525
526 if (canonname) {
527 if (strchr(canonname, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(canonname) && (':') == '\0' ? (char *) __rawmemchr (
canonname, ':') : __builtin_strchr (canonname, ':')))
||
528 strspn(canonname, "0123456789.")__extension__ ({ char __a0, __a1, __a2; (__builtin_constant_p
("0123456789.") && ((size_t)(const void *)(("0123456789."
) + 1) - (size_t)(const void *)("0123456789.") == 1) ? ((__builtin_constant_p
(canonname) && ((size_t)(const void *)((canonname) +
1) - (size_t)(const void *)(canonname) == 1)) ? __builtin_strspn
(canonname, "0123456789.") : ((__a0 = ((const char *) ("0123456789."
))[0], __a0 == '\0') ? ((void) (canonname), (size_t) 0) : ((__a1
= ((const char *) ("0123456789."))[1], __a1 == '\0') ? __strspn_c1
(canonname, __a0) : ((__a2 = ((const char *) ("0123456789.")
)[2], __a2 == '\0') ? __strspn_c2 (canonname, __a0, __a1) : (
((const char *) ("0123456789."))[3] == '\0' ? __strspn_c3 (canonname
, __a0, __a1, __a2) : __builtin_strspn (canonname, "0123456789."
)))))) : __builtin_strspn (canonname, "0123456789.")); })
== strlen(canonname))
529 li->li_flags |= LI_NUMERIC;
530 }
531 else
532 li->li_flags = 0;
533
534 li->li_canonname = canonname;
535
536 canonname = NULL((void*)0);
537
538 *rresult = li;
539 return 0;
540
541err:
542 if (canonname) free(canonname);
543 if (li) free(li);
544 su_close(s);
545
546 return error;
547}
548#else /* !__APPLE_CC__ */
549/** Build a list of local IPv4 addresses and append it to *rresult. */
550static
551int localinfo4(su_localinfo_t const *hints, su_localinfo_t **rresult)
552{
553 su_localinfo_t *tbf = NULL((void*)0), **lli = &tbf;
554 su_localinfo_t *li = NULL((void*)0), *li_first = NULL((void*)0);
555 su_sockaddr_t *su;
556 int error = ELI_NOADDRESS;
557 char *canonname = NULL((void*)0);
558 su_socket_t s;
559
560#if SU_HAVE_IN61
561 int su_xtra = (hints->li_flags & LI_V4MAPPED) ? sizeof(*su) : 0;
562#else
563 int const su_xtra = 0;
564#endif
565
566 struct ifconf ifc;
567 int numifs;
568 char *buffer;
569 struct ifreq *ifr, *ifr_next;
570
571#if HAVE_OPEN_C
572 su_sockaddr_t *sa;
573 socklen_t salen = sizeof(*sa);
574#endif
575
576 s = su_socket(AF_INET2, SOCK_DGRAMSOCK_DGRAM, 0);
577 if (s == -1) {
578 SU_DEBUG_1(("su_localinfo: su_socket failed: %s\n",((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 1 ? (_su_llog((su_log_global
), 1, "su_localinfo.c", (const char *)__func__, 579, "su_localinfo: su_socket failed: %s\n"
, su_strerror(su_errno()))) : (void)0)
579 su_strerror(su_errno())))((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 1 ? (_su_llog((su_log_global
), 1, "su_localinfo.c", (const char *)__func__, 579, "su_localinfo: su_socket failed: %s\n"
, su_strerror(su_errno()))) : (void)0)
;
580 return ELI_SYSTEM;
581 }
582
583# if HAVE_IFNUM
584 /* Get the list of known IP address from the kernel */
585 if (ioctl(s, SIOCGIFNUM, (char *) &numifs) < 0) {
586 /* can't get number of interfaces -- fall back */
587 SU_DEBUG_1(("su_localinfo: SIOCGIFNUM failed: %s\n",((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 1 ? (_su_llog((su_log_global
), 1, "su_localinfo.c", (const char *)__func__, 588, "su_localinfo: SIOCGIFNUM failed: %s\n"
, su_strerror(su_errno()))) : (void)0)
588 su_strerror(su_errno())))((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 1 ? (_su_llog((su_log_global
), 1, "su_localinfo.c", (const char *)__func__, 588, "su_localinfo: SIOCGIFNUM failed: %s\n"
, su_strerror(su_errno()))) : (void)0)
;
589 error = ELI_SYSTEM;
590 goto err;
591 }
592
593 SU_DEBUG_9(("su_localinfo: %d active interfaces according to SIOCGIFNUM\n",((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 9 ? (_su_llog((su_log_global
), 9, "su_localinfo.c", (const char *)__func__, 594, "su_localinfo: %d active interfaces according to SIOCGIFNUM\n"
, numifs)) : (void)0)
594 numifs))((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 9 ? (_su_llog((su_log_global
), 9, "su_localinfo.c", (const char *)__func__, 594, "su_localinfo: %d active interfaces according to SIOCGIFNUM\n"
, numifs)) : (void)0)
;
595
596 if (numifs < 0)
597# endif
598 /* Default to 64 interfaces. Enough? */
599 numifs = 64;
600
601 if (numifs == 0)
602 return 0;
603
604 /*
605 * Allocate memory for SIOCGIFCONF ioctl buffer. This memory block is also
606 * used as li_first, first localinfo struct that is returned, so it can be
607 * freed by freelocalinfo() without any complications.
608 */
609 ifc.ifc_len = numifs * sizeof (struct ifreq);
610 buffer = malloc(sizeof(su_localinfo_t) + ifc.ifc_len + su_xtra);
611 if (!buffer) {
612 SU_DEBUG_1(("su_localinfo: memory exhausted\n" VA_NONE))((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 1 ? (_su_llog((su_log_global
), 1, "su_localinfo.c", (const char *)__func__, 612, "su_localinfo: memory exhausted\n"
"%s", "")) : (void)0)
;
613 error = ELI_MEMORY;
614 goto err;
615 }
616
617 li_first = (su_localinfo_t *)buffer;
618 memset(li_first, 0, sizeof(su_localinfo_t) + su_xtra);
619 ifc.ifc_bufifc_ifcu.ifcu_buf = buffer + sizeof(su_localinfo_t) + su_xtra;
620#if HAVE_OPEN_C
621 if (ioctl(s, SIOCGIFACTIVECONF, (char *)&ifc) < 0) {
622 SU_DEBUG_1(("su_localinfo: SIOCGIFCONF failed: %s\n",((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 1 ? (_su_llog((su_log_global
), 1, "su_localinfo.c", (const char *)__func__, 623, "su_localinfo: SIOCGIFCONF failed: %s\n"
, su_strerror(su_errno()))) : (void)0)
623 su_strerror(su_errno())))((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 1 ? (_su_llog((su_log_global
), 1, "su_localinfo.c", (const char *)__func__, 623, "su_localinfo: SIOCGIFCONF failed: %s\n"
, su_strerror(su_errno()))) : (void)0)
;
624 error = ELI_SYSTEM;
625 goto err;
626 }
627#else
628 if (ioctl(s, SIOCGIFCONF0x8912, (char *)&ifc) < 0) {
629 SU_DEBUG_1(("su_localinfo: SIOCGIFCONF failed: %s\n",((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 1 ? (_su_llog((su_log_global
), 1, "su_localinfo.c", (const char *)__func__, 630, "su_localinfo: SIOCGIFCONF failed: %s\n"
, su_strerror(su_errno()))) : (void)0)
630 su_strerror(su_errno())))((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 1 ? (_su_llog((su_log_global
), 1, "su_localinfo.c", (const char *)__func__, 630, "su_localinfo: SIOCGIFCONF failed: %s\n"
, su_strerror(su_errno()))) : (void)0)
;
631 error = ELI_SYSTEM;
632 goto err;
633 }
634#endif
635
636 buffer = ifc.ifc_bufifc_ifcu.ifcu_buf + ifc.ifc_len;
637
638 for (ifr = ifc.ifc_reqifc_ifcu.ifcu_req;
639 (void *)ifr < (void *)buffer;
640 ifr = ifr_next) {
641 struct ifreq ifreq[1];
642 int scope, if_index, flags = 0, gni_flags = 0;
643 char *if_name;
644#if SU_HAVE_IN61
645 su_sockaddr_t su2[1];
646#endif
647
648#if SA_LEN
649 if (ifr->ifr_addrifr_ifru.ifru_addr.sa_len > sizeof(ifr->ifr_addrifr_ifru.ifru_addr))
650 ifr_next = (struct ifreq *)
651 (ifr->ifr_addrifr_ifru.ifru_addr.sa_len + (char *)(&ifr->ifr_addrifr_ifru.ifru_addr));
652 else
653#else
654 ifr_next = ifr + 1;
655#endif
656
657 if_name = ifr->ifr_nameifr_ifrn.ifrn_name;
658
659#if defined(SIOCGIFINDEX0x8933)
660 ifreq[0] = *ifr;
661 if (ioctl(s, SIOCGIFINDEX0x8933, ifreq) < 0) {
662 SU_DEBUG_1(("su_localinfo: SIOCGIFINDEX failed: %s\n",((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 1 ? (_su_llog((su_log_global
), 1, "su_localinfo.c", (const char *)__func__, 663, "su_localinfo: SIOCGIFINDEX failed: %s\n"
, su_strerror(su_errno()))) : (void)0)
663 su_strerror(su_errno())))((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 1 ? (_su_llog((su_log_global
), 1, "su_localinfo.c", (const char *)__func__, 663, "su_localinfo: SIOCGIFINDEX failed: %s\n"
, su_strerror(su_errno()))) : (void)0)
;
664 error = ELI_SYSTEM;
665 goto err;
666 }
667#if HAVE_IFR_INDEX
668 if_index = ifreq->ifr_index;
669#elif HAVE_IFR_IFINDEX1
670 if_index = ifreq->ifr_ifindexifr_ifru.ifru_ivalue;
671#else
672#error Unknown index field in struct ifreq
673#endif
674
675#else
676#warning su_localinfo() cannot map interface name to number
677 if_index = 0;
678#endif
679
680 SU_DEBUG_9(("su_localinfo: if %s with index %d\n", if_name, if_index))((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 9 ? (_su_llog((su_log_global
), 9, "su_localinfo.c", (const char *)__func__, 680, "su_localinfo: if %s with index %d\n"
, if_name, if_index)) : (void)0)
;
681
682
683#if HAVE_OPEN_C
684 su_close(s);
685
686 li = calloc(1, sizeof(su_localinfo_t));
687 sa = calloc(1, sizeof(su_sockaddr_t));
688
689 if (su_get_local_ip_addr(sa) < 0)
690 goto err;
691
692 li->li_family = sa->su_familysu_sa.sa_family;
693 li->li_scope = LI_SCOPE_GLOBAL /* scope */;
694 li->li_index = if_index;
695 li->li_addrlen = su_sockaddr_size(sa)((socklen_t)((sa)->su_sa.sa_family == 2 ? sizeof((sa)->
su_sin) : ((sa)->su_sa.sa_family == 10 ? sizeof((sa)->su_sin6
) : sizeof(*sa))))
;
696 li->li_addr = sa;
697
698 if ((error = li_name(hints, gni_flags, sa, &canonname)) < 0)
699 goto err;
700
701 if (canonname) {
702 if (strchr(canonname, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(canonname) && (':') == '\0' ? (char *) __rawmemchr (
canonname, ':') : __builtin_strchr (canonname, ':')))
||
703 strspn(canonname, "0123456789.")__extension__ ({ char __a0, __a1, __a2; (__builtin_constant_p
("0123456789.") && ((size_t)(const void *)(("0123456789."
) + 1) - (size_t)(const void *)("0123456789.") == 1) ? ((__builtin_constant_p
(canonname) && ((size_t)(const void *)((canonname) +
1) - (size_t)(const void *)(canonname) == 1)) ? __builtin_strspn
(canonname, "0123456789.") : ((__a0 = ((const char *) ("0123456789."
))[0], __a0 == '\0') ? ((void) (canonname), (size_t) 0) : ((__a1
= ((const char *) ("0123456789."))[1], __a1 == '\0') ? __strspn_c1
(canonname, __a0) : ((__a2 = ((const char *) ("0123456789.")
)[2], __a2 == '\0') ? __strspn_c2 (canonname, __a0, __a1) : (
((const char *) ("0123456789."))[3] == '\0' ? __strspn_c3 (canonname
, __a0, __a1, __a2) : __builtin_strspn (canonname, "0123456789."
)))))) : __builtin_strspn (canonname, "0123456789.")); })
== strlen(canonname))
704 li->li_flags |= LI_NUMERIC;
705 }
706 else
707 li->li_flags = 0;
708
709 li->li_canonname = canonname;
710
711 canonname = NULL((void*)0);
712
713 *rresult = li;
714
715 return 0;
716#endif
717
718#if defined(SIOCGIFFLAGS0x8913)
719 ifreq[0] = *ifr;
720 if (ioctl(s, SIOCGIFFLAGS0x8913, ifreq) < 0) {
721 SU_DEBUG_1(("su_localinfo: SIOCGIFFLAGS failed: %s\n",((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 1 ? (_su_llog((su_log_global
), 1, "su_localinfo.c", (const char *)__func__, 722, "su_localinfo: SIOCGIFFLAGS failed: %s\n"
, su_strerror(su_errno()))) : (void)0)
722 su_strerror(su_errno())))((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 1 ? (_su_llog((su_log_global
), 1, "su_localinfo.c", (const char *)__func__, 722, "su_localinfo: SIOCGIFFLAGS failed: %s\n"
, su_strerror(su_errno()))) : (void)0)
;
723 error = ELI_SYSTEM;
724 goto err;
725 }
726 /* Do not include interfaces that are down unless explicitly asked */
727 if ((ifreq->ifr_flagsifr_ifru.ifru_flags & IFF_UPIFF_UP) == 0 && (hints->li_flags & LI_DOWN) == 0) {
728 SU_DEBUG_9(("su_localinfo: if %s with index %d is down\n",((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 9 ? (_su_llog((su_log_global
), 9, "su_localinfo.c", (const char *)__func__, 729, "su_localinfo: if %s with index %d is down\n"
, if_name, if_index)) : (void)0)
729 if_name, if_index))((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 9 ? (_su_llog((su_log_global
), 9, "su_localinfo.c", (const char *)__func__, 729, "su_localinfo: if %s with index %d is down\n"
, if_name, if_index)) : (void)0)
;
730 continue;
731 }
732#elif defined(SIOCGIFACTIVECONF)
733/* Handled above in SIOCGIFACTIVECONF vs. SIOCGIFCONF*/
734#else
735#error su_localinfo() cannot determine interface status
736#endif
737
738#if 0
739 *ifreq = *ifr;
740 ifreq->ifr_addrifr_ifru.ifru_addr.sa_family = AF_INET2;
741 if (ioctl(s, SIOCGIFADDR0x8915, ifreq) < 0) {
742 SU_DEBUG_1(("su_localinfo: SIOCGIFADDR failed: %s\n",((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 1 ? (_su_llog((su_log_global
), 1, "su_localinfo.c", (const char *)__func__, 743, "su_localinfo: SIOCGIFADDR failed: %s\n"
, su_strerror(su_errno()))) : (void)0)
743 su_strerror(su_errno())))((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 1 ? (_su_llog((su_log_global
), 1, "su_localinfo.c", (const char *)__func__, 743, "su_localinfo: SIOCGIFADDR failed: %s\n"
, su_strerror(su_errno()))) : (void)0)
;
744 error = ELI_SYSTEM;
745 goto err;
746 }
747 ifr->ifr_addrifr_ifru.ifru_addr = ifreq->ifr_addrifr_ifru.ifru_addr;
748#endif
749
750 su = (su_sockaddr_t *)&ifr->ifr_addrifr_ifru.ifru_addr;
751
752 if (SU_HAS_INADDR_ANY(su)((su)->su_sa.sa_family == 2 ? ((su)->su_sin.sin_addr.s_addr
== ((in_addr_t) 0x00000000)) : ((su)->su_sa.sa_family == 10
? (memcmp(&(su)->su_sin6.sin6_addr, (&in6addr_any
), sizeof(*(&in6addr_any))) == 0) : 0))
)
753 continue;
754
755 scope = li_scope4(su->su_sin.sin_addr.s_addr);
756
757 if ((hints->li_scope && (hints->li_scope & scope) == 0) ||
758 (hints->li_ifname && strcmp(hints->li_ifname, if_name)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(hints->li_ifname) && __builtin_constant_p (if_name
) && (__s1_len = __builtin_strlen (hints->li_ifname
), __s2_len = __builtin_strlen (if_name), (!((size_t)(const void
*)((hints->li_ifname) + 1) - (size_t)(const void *)(hints
->li_ifname) == 1) || __s1_len >= 4) && (!((size_t
)(const void *)((if_name) + 1) - (size_t)(const void *)(if_name
) == 1) || __s2_len >= 4)) ? __builtin_strcmp (hints->li_ifname
, if_name) : (__builtin_constant_p (hints->li_ifname) &&
((size_t)(const void *)((hints->li_ifname) + 1) - (size_t
)(const void *)(hints->li_ifname) == 1) && (__s1_len
= __builtin_strlen (hints->li_ifname), __s1_len < 4) ?
(__builtin_constant_p (if_name) && ((size_t)(const void
*)((if_name) + 1) - (size_t)(const void *)(if_name) == 1) ? __builtin_strcmp
(hints->li_ifname, if_name) : (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (if_name
); int __result = (((const unsigned char *) (const char *) (hints
->li_ifname))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (hints->li_ifname))[1] - __s2[1]); if (__s1_len >
1 && __result == 0) { __result = (((const unsigned char
*) (const char *) (hints->li_ifname))[2] - __s2[2]); if (
__s1_len > 2 && __result == 0) __result = (((const
unsigned char *) (const char *) (hints->li_ifname))[3] - __s2
[3]); } } __result; }))) : (__builtin_constant_p (if_name) &&
((size_t)(const void *)((if_name) + 1) - (size_t)(const void
*)(if_name) == 1) && (__s2_len = __builtin_strlen (if_name
), __s2_len < 4) ? (__builtin_constant_p (hints->li_ifname
) && ((size_t)(const void *)((hints->li_ifname) + 1
) - (size_t)(const void *)(hints->li_ifname) == 1) ? __builtin_strcmp
(hints->li_ifname, if_name) : (- (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (hints->
li_ifname); int __result = (((const unsigned char *) (const char
*) (if_name))[0] - __s2[0]); if (__s2_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
if_name))[1] - __s2[1]); if (__s2_len > 1 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
if_name))[2] - __s2[2]); if (__s2_len > 2 && __result
== 0) __result = (((const unsigned char *) (const char *) (if_name
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (hints
->li_ifname, if_name)))); })
!= 0) ||
759 (hints->li_index && hints->li_index != if_index))
760 continue;
761
762#if SU_HAVE_IN61
763 if (su_xtra) {
764 /* Map IPv4 address to IPv6 address */
765 memset(su2, 0, sizeof(*su2));
766 su2->su_familysu_sa.sa_family = AF_INET610;
767 ((int32_t*)&su2->su_sin6.sin6_addr)[2] = htonl(0xffff)(__extension__ ({ unsigned int __v, __x = (0xffff); if (__builtin_constant_p
(__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x
) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) <<
8) | (((__x) & 0x000000ff) << 24)); else __asm__ (
"bswap %0" : "=r" (__v) : "0" (__x)); __v; }))
;
768 ((int32_t*)&su2->su_sin6.sin6_addr)[3] = su->su_sin.sin_addr.s_addr;
769 su = su2;
770 }
771#endif
772
773 if (scope == LI_SCOPE_HOST || scope == LI_SCOPE_LINK)
774 gni_flags = NI_NUMERICHOST1;
775
776 if ((error = li_name(hints, gni_flags, su, &canonname)) < 0)
777 goto err;
778 else if (error > 0)
779 continue;
780
781 if (canonname)
782 if (strchr(canonname, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(canonname) && (':') == '\0' ? (char *) __rawmemchr (
canonname, ':') : __builtin_strchr (canonname, ':')))
||
783 strspn(canonname, "0123456789.")__extension__ ({ char __a0, __a1, __a2; (__builtin_constant_p
("0123456789.") && ((size_t)(const void *)(("0123456789."
) + 1) - (size_t)(const void *)("0123456789.") == 1) ? ((__builtin_constant_p
(canonname) && ((size_t)(const void *)((canonname) +
1) - (size_t)(const void *)(canonname) == 1)) ? __builtin_strspn
(canonname, "0123456789.") : ((__a0 = ((const char *) ("0123456789."
))[0], __a0 == '\0') ? ((void) (canonname), (size_t) 0) : ((__a1
= ((const char *) ("0123456789."))[1], __a1 == '\0') ? __strspn_c1
(canonname, __a0) : ((__a2 = ((const char *) ("0123456789.")
)[2], __a2 == '\0') ? __strspn_c2 (canonname, __a0, __a1) : (
((const char *) ("0123456789."))[3] == '\0' ? __strspn_c3 (canonname
, __a0, __a1, __a2) : __builtin_strspn (canonname, "0123456789."
)))))) : __builtin_strspn (canonname, "0123456789.")); })
== strlen(canonname))
784 flags |= LI_NUMERIC;
785
786 if (li_first)
787 li = li_first; /* Use li_first with all ifr structs to be freed */
788 else if (!(li = calloc(1, (sizeof *li) + su_xtra))) {
789 error = ELI_MEMORY;
790 goto err;
791 }
792 if (!tbf) tbf = li;
793 *lli = li; lli = &li->li_next;
794
795 if (su_xtra)
796 su = (su_sockaddr_t *)memcpy(li + 1, su, su_xtra);
797
798 li->li_flags = flags;
799 li->li_family = su->su_familysu_sa.sa_family;
800 li->li_scope = scope;
801 li->li_index = if_index;
802 li->li_addrlen = su_sockaddr_size(su)((socklen_t)((su)->su_sa.sa_family == 2 ? sizeof((su)->
su_sin) : ((su)->su_sa.sa_family == 10 ? sizeof((su)->su_sin6
) : sizeof(*su))))
;
803 li->li_addr = su;
804 li->li_canonname = canonname;
805 li->li_ifname = if_name;
806
807 canonname = NULL((void*)0);
808 li_first = NULL((void*)0);
809 }
810
811 if (canonname) free(canonname);
812 if (li_first) free(li_first);
813 su_close(s);
814
815 if (tbf) *rresult = tbf;
816 return 0;
817
818err:
819 if (canonname) free(canonname);
820 if (li_first) free(li_first);
821 su_freelocalinfo(tbf);
822 su_close(s);
823
824 return error;
825}
826#endif /* __APPLE_CC__ */
827#else
828static
829int localinfo4(su_localinfo_t const *hints, su_localinfo_t **rresult)
830{
831 /* Kikka #3: resolve hostname */
832 char hostname[SU_MAXHOST(1025)] = "";
833 char *name, *ifname;
834 struct hostent *h;
835 int i, flags, error, gni_flags = 0;
836 su_localinfo_t *tbf = NULL((void*)0);
837 su_localinfo_t *li = NULL((void*)0), **lli = &tbf;
838 su_sockaddr_t *su;
839#if SU_HAVE_IN61
840 socklen_t su_sockaddr_sizeSU_SOCKADDR_SIZE =
841 (hints->li_flags & LI_V4MAPPED) ? sizeof(*su) : sizeof(struct sockaddr_in);
842 flags = hints->li_flags & (LI_V4MAPPED|LI_CANONNAME|LI_NUMERIC|LI_IFNAME);
843#else
844 socklen_t su_sockaddr_sizeSU_SOCKADDR_SIZE = sizeof(struct sockaddr_in);
845 flags = hints->li_flags & (LI_CANONNAME|LI_NUMERIC|LI_IFNAME);
846#endif
847
848 error = ELI_NOERROR;
849
850 if (hints->li_scope == 0 || (hints->li_scope & LI_SCOPE_GLOBAL)) {
851 if (hints->li_canonname)
852 name = hints->li_canonname;
853 else if (gethostname(name = hostname, sizeof(hostname)) != 0)
854 return ELI_SYSTEM;
855
856 h = gethostbyname(name);
857
858 if (name)
859 if (strchr(name, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(name) && (':') == '\0' ? (char *) __rawmemchr (name
, ':') : __builtin_strchr (name, ':')))
||
860 strspn(name, "0123456789.")__extension__ ({ char __a0, __a1, __a2; (__builtin_constant_p
("0123456789.") && ((size_t)(const void *)(("0123456789."
) + 1) - (size_t)(const void *)("0123456789.") == 1) ? ((__builtin_constant_p
(name) && ((size_t)(const void *)((name) + 1) - (size_t
)(const void *)(name) == 1)) ? __builtin_strspn (name, "0123456789."
) : ((__a0 = ((const char *) ("0123456789."))[0], __a0 == '\0'
) ? ((void) (name), (size_t) 0) : ((__a1 = ((const char *) ("0123456789."
))[1], __a1 == '\0') ? __strspn_c1 (name, __a0) : ((__a2 = ((
const char *) ("0123456789."))[2], __a2 == '\0') ? __strspn_c2
(name, __a0, __a1) : (((const char *) ("0123456789."))[3] ==
'\0' ? __strspn_c3 (name, __a0, __a1, __a2) : __builtin_strspn
(name, "0123456789.")))))) : __builtin_strspn (name, "0123456789."
)); })
== strlen(name))
861 flags |= LI_NUMERIC;
862
863 for (i = 0; h && h->h_addr_list[i]; i++) {
864 if ((li = calloc(1, sizeof(*li) + su_sockaddr_sizeSU_SOCKADDR_SIZE)) == NULL((void*)0)) {
865 error = ELI_MEMORY;
866 goto err;
867 }
868 li->li_flags = flags;
869
870 li->li_scope = li_scope4(*(uint32_t *)h->h_addr_list[i]);
871 if (li->li_scope == LI_SCOPE_HOST)
872 li->li_index = 1, ifname = "lo";
873 else
874 li->li_index = 2, ifname = "eth";
875
876 li->li_addrlen = su_sockaddr_sizeSU_SOCKADDR_SIZE;
877 li->li_addr = su = (su_sockaddr_t *)(li + 1);
878 su->su_familysu_sa.sa_family = li->li_family =
879 li->li_flags & LI_V4MAPPED ? AF_INET610 : AF_INET2;
880
881#if SU_HAVE_IN61
882 if (li->li_flags & LI_V4MAPPED) {
883 ((int32_t*)&su->su_sin6.sin6_addr)[2] = htonl(0xffff)(__extension__ ({ unsigned int __v, __x = (0xffff); if (__builtin_constant_p
(__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x
) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) <<
8) | (((__x) & 0x000000ff) << 24)); else __asm__ (
"bswap %0" : "=r" (__v) : "0" (__x)); __v; }))
;
884 memcpy(&((int32_t*)&su->su_sin6.sin6_addr)[3],
885 h->h_addr_list[i], h->h_length);
886 }
887 else
888#endif
889 memcpy(&su->su_sin.sin_addr.s_addr, h->h_addr_list[i], h->h_length);
890 if (li->li_flags & LI_IFNAME)
891 li->li_ifname = ifname;
892 if (li->li_scope == LI_SCOPE_HOST || li->li_scope == LI_SCOPE_LINK)
893 gni_flags = NI_NUMERICHOST1;
894 if ((error = li_name(hints, gni_flags, su, &li->li_canonname)) < 0)
895 goto err;
896 else if (error > 0) {
897 free(li); li = NULL((void*)0); continue;
898 } else
899 error = ELI_NOADDRESS;
900 *lli = li; lli = &li->li_next; li = NULL((void*)0);
901 }
902 }
903
904 if (hints->li_scope == 0 || (hints->li_scope & LI_SCOPE_HOST)) {
905 if ((li = calloc(1, sizeof(*li) + su_sockaddr_sizeSU_SOCKADDR_SIZE)) == NULL((void*)0)) {
906 error = ELI_MEMORY;
907 goto err;
908 }
909 li->li_flags = hints->li_flags &
910 (LI_V4MAPPED|LI_CANONNAME|LI_NUMERIC|LI_IFNAME);
911 li->li_scope = LI_SCOPE_HOST, li->li_index = 1;
912 if (li->li_flags & LI_IFNAME)
913 li->li_ifname = "lo";
914 li->li_addrlen = su_sockaddr_sizeSU_SOCKADDR_SIZE;
915 li->li_addr = su = (su_sockaddr_t *)(li + 1);
916#if SU_HAVE_IN61
917 if (li->li_flags & LI_V4MAPPED) {
918 su->su_familysu_sa.sa_family = li->li_family = AF_INET610;
919 ((int32_t*)&su->su_sin6.sin6_addr)[2] = htonl(0xffff)(__extension__ ({ unsigned int __v, __x = (0xffff); if (__builtin_constant_p
(__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x
) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) <<
8) | (((__x) & 0x000000ff) << 24)); else __asm__ (
"bswap %0" : "=r" (__v) : "0" (__x)); __v; }))
;
920 ((int32_t*)&su->su_sin6.sin6_addr)[3] = htonl(0x7f000001)(__extension__ ({ unsigned int __v, __x = (0x7f000001); if (__builtin_constant_p
(__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x
) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) <<
8) | (((__x) & 0x000000ff) << 24)); else __asm__ (
"bswap %0" : "=r" (__v) : "0" (__x)); __v; }))
;
921 }
922 else
923#endif
924 su->su_familysu_sa.sa_family = li->li_family = AF_INET2,
925 su->su_sin.sin_addr.s_addr = htonl(0x7f000001)(__extension__ ({ unsigned int __v, __x = (0x7f000001); if (__builtin_constant_p
(__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x
) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) <<
8) | (((__x) & 0x000000ff) << 24)); else __asm__ (
"bswap %0" : "=r" (__v) : "0" (__x)); __v; }))
;
926
927 if ((error = li_name(hints, NI_NUMERICHOST1, su, &li->li_canonname)) < 0) {
928 goto err;
929 } else if (error > 0) {
930 free(li); li = NULL((void*)0);
931 } else {
932 *lli = li; lli = &li->li_next; li = NULL((void*)0);
933 }
934 }
935
936 *rresult = tbf;
937
938 return 0;
939
940err:
941 if (li) su_freelocalinfo(li);
942 su_freelocalinfo(tbf);
943
944 return error;
945}
946
947#endif
948
949#if USE_LOCALINFO01 || !SU_HAVE_IN61 || SU_LOCALINFO_TEST
950/* No localinfo6() */
951#elif HAVE_PROC_NET_IF_INET61
952/** Build a list of local IPv6 addresses and append it to *return_result. */
953static
954int localinfo6(su_localinfo_t const *hints, su_localinfo_t **return_result)
955{
956 su_localinfo_t *li = NULL((void*)0);
957 su_sockaddr_t su[1] = {{ 0 }}, *addr;
958 int error = ELI_NOADDRESS;
959 char *canonname = NULL((void*)0);
960 char line[80];
961 FILE *f;
962
963 if ((f = fopen("/proc/net/if_inet6", "r"))) {
964 for (;error;) {
965 struct in6_addr in6;
966 unsigned if_index, prefix_len, scope, flags;
967 int addrlen, if_namelen;
968 char ifname[16];
969
970 if (!fgets(line, sizeof(line), f)) {
971 if (feof(f))
972 error = ELI_NOERROR;
973 break;
974 }
975
976 if (sscanf(line, "%08x%08x%08x%08x %2x %2x %2x %02x %016s\n",
977 &in6.s6_addr32__in6_u.__u6_addr32[0],
978 &in6.s6_addr32__in6_u.__u6_addr32[1],
979 &in6.s6_addr32__in6_u.__u6_addr32[2],
980 &in6.s6_addr32__in6_u.__u6_addr32[3],
981 &if_index, &prefix_len, &scope, &flags, ifname) != 9)
982 break;
983
984 flags = 0;
985
986 /* Fix global scope (it is 0) */
987 if (!scope) scope = LI_SCOPE_GLOBAL;
988
989 in6.s6_addr32__in6_u.__u6_addr32[0] = htonl(in6.s6_addr32[0])(__extension__ ({ unsigned int __v, __x = (in6.__in6_u.__u6_addr32
[0]); if (__builtin_constant_p (__x)) __v = ((((__x) & 0xff000000
) >> 24) | (((__x) & 0x00ff0000) >> 8) | (((__x
) & 0x0000ff00) << 8) | (((__x) & 0x000000ff) <<
24)); else __asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); __v
; }))
;
990 in6.s6_addr32__in6_u.__u6_addr32[1] = htonl(in6.s6_addr32[1])(__extension__ ({ unsigned int __v, __x = (in6.__in6_u.__u6_addr32
[1]); if (__builtin_constant_p (__x)) __v = ((((__x) & 0xff000000
) >> 24) | (((__x) & 0x00ff0000) >> 8) | (((__x
) & 0x0000ff00) << 8) | (((__x) & 0x000000ff) <<
24)); else __asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); __v
; }))
;
991 in6.s6_addr32__in6_u.__u6_addr32[2] = htonl(in6.s6_addr32[2])(__extension__ ({ unsigned int __v, __x = (in6.__in6_u.__u6_addr32
[2]); if (__builtin_constant_p (__x)) __v = ((((__x) & 0xff000000
) >> 24) | (((__x) & 0x00ff0000) >> 8) | (((__x
) & 0x0000ff00) << 8) | (((__x) & 0x000000ff) <<
24)); else __asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); __v
; }))
;
992 in6.s6_addr32__in6_u.__u6_addr32[3] = htonl(in6.s6_addr32[3])(__extension__ ({ unsigned int __v, __x = (in6.__in6_u.__u6_addr32
[3]); if (__builtin_constant_p (__x)) __v = ((((__x) & 0xff000000
) >> 24) | (((__x) & 0x00ff0000) >> 8) | (((__x
) & 0x0000ff00) << 8) | (((__x) & 0x000000ff) <<
24)); else __asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); __v
; }))
;
993
994 if (IN6_IS_ADDR_V4MAPPED(&in6)(__extension__ ({ const struct in6_addr *__a = (const struct in6_addr
*) (&in6); __a->__in6_u.__u6_addr32[0] == 0 &&
__a->__in6_u.__u6_addr32[1] == 0 && __a->__in6_u
.__u6_addr32[2] == (__extension__ ({ unsigned int __v, __x = (
0xffff); if (__builtin_constant_p (__x)) __v = ((((__x) &
0xff000000) >> 24) | (((__x) & 0x00ff0000) >>
8) | (((__x) & 0x0000ff00) << 8) | (((__x) & 0x000000ff
) << 24)); else __asm__ ("bswap %0" : "=r" (__v) : "0" (
__x)); __v; })); }))
|| IN6_IS_ADDR_V4COMPAT(&in6)(__extension__ ({ const struct in6_addr *__a = (const struct in6_addr
*) (&in6); __a->__in6_u.__u6_addr32[0] == 0 &&
__a->__in6_u.__u6_addr32[1] == 0 && __a->__in6_u
.__u6_addr32[2] == 0 && (__extension__ ({ unsigned int
__v, __x = (__a->__in6_u.__u6_addr32[3]); if (__builtin_constant_p
(__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x
) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) <<
8) | (((__x) & 0x000000ff) << 24)); else __asm__ (
"bswap %0" : "=r" (__v) : "0" (__x)); __v; })) > 1; }))
) {
995 uint32_t ip4 = *(uint32_t *)(in6.s6_addr__in6_u.__u6_addr8 + 12);
996 scope = li_scope4(ip4);
997 }
998
999 if ((hints->li_scope && (hints->li_scope & scope) == 0) ||
1000 (hints->li_index && hints->li_index != if_index) ||
1001 (hints->li_ifname && strcmp(hints->li_ifname, ifname)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(hints->li_ifname) && __builtin_constant_p (ifname
) && (__s1_len = __builtin_strlen (hints->li_ifname
), __s2_len = __builtin_strlen (ifname), (!((size_t)(const void
*)((hints->li_ifname) + 1) - (size_t)(const void *)(hints
->li_ifname) == 1) || __s1_len >= 4) && (!((size_t
)(const void *)((ifname) + 1) - (size_t)(const void *)(ifname
) == 1) || __s2_len >= 4)) ? __builtin_strcmp (hints->li_ifname
, ifname) : (__builtin_constant_p (hints->li_ifname) &&
((size_t)(const void *)((hints->li_ifname) + 1) - (size_t
)(const void *)(hints->li_ifname) == 1) && (__s1_len
= __builtin_strlen (hints->li_ifname), __s1_len < 4) ?
(__builtin_constant_p (ifname) && ((size_t)(const void
*)((ifname) + 1) - (size_t)(const void *)(ifname) == 1) ? __builtin_strcmp
(hints->li_ifname, ifname) : (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (ifname)
; int __result = (((const unsigned char *) (const char *) (hints
->li_ifname))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (hints->li_ifname))[1] - __s2[1]); if (__s1_len >
1 && __result == 0) { __result = (((const unsigned char
*) (const char *) (hints->li_ifname))[2] - __s2[2]); if (
__s1_len > 2 && __result == 0) __result = (((const
unsigned char *) (const char *) (hints->li_ifname))[3] - __s2
[3]); } } __result; }))) : (__builtin_constant_p (ifname) &&
((size_t)(const void *)((ifname) + 1) - (size_t)(const void *
)(ifname) == 1) && (__s2_len = __builtin_strlen (ifname
), __s2_len < 4) ? (__builtin_constant_p (hints->li_ifname
) && ((size_t)(const void *)((hints->li_ifname) + 1
) - (size_t)(const void *)(hints->li_ifname) == 1) ? __builtin_strcmp
(hints->li_ifname, ifname) : (- (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (hints->
li_ifname); int __result = (((const unsigned char *) (const char
*) (ifname))[0] - __s2[0]); if (__s2_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
ifname))[1] - __s2[1]); if (__s2_len > 1 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
ifname))[2] - __s2[2]); if (__s2_len > 2 && __result
== 0) __result = (((const unsigned char *) (const char *) (ifname
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (hints
->li_ifname, ifname)))); })
!= 0))
1002 continue;
1003
1004 su->su_familysu_sa.sa_family = AF_INET610;
1005 su->su_sin6.sin6_addr = in6;
1006
1007 addrlen = su_sockaddr_size(su)((socklen_t)((su)->su_sa.sa_family == 2 ? sizeof((su)->
su_sin) : ((su)->su_sa.sa_family == 10 ? sizeof((su)->su_sin6
) : sizeof(*su))))
;
1008
1009 if ((error = li_name(hints, 0, su, &canonname)) < 0)
1010 break;
1011 else if (error > 0)
1012 continue;
1013 else
1014 error = ELI_NOADDRESS;
1015
1016 if (canonname &&
1017 (strchr(canonname, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(canonname) && (':') == '\0' ? (char *) __rawmemchr (
canonname, ':') : __builtin_strchr (canonname, ':')))
||
1018 strspn(canonname, "0123456789.")__extension__ ({ char __a0, __a1, __a2; (__builtin_constant_p
("0123456789.") && ((size_t)(const void *)(("0123456789."
) + 1) - (size_t)(const void *)("0123456789.") == 1) ? ((__builtin_constant_p
(canonname) && ((size_t)(const void *)((canonname) +
1) - (size_t)(const void *)(canonname) == 1)) ? __builtin_strspn
(canonname, "0123456789.") : ((__a0 = ((const char *) ("0123456789."
))[0], __a0 == '\0') ? ((void) (canonname), (size_t) 0) : ((__a1
= ((const char *) ("0123456789."))[1], __a1 == '\0') ? __strspn_c1
(canonname, __a0) : ((__a2 = ((const char *) ("0123456789.")
)[2], __a2 == '\0') ? __strspn_c2 (canonname, __a0, __a1) : (
((const char *) ("0123456789."))[3] == '\0' ? __strspn_c3 (canonname
, __a0, __a1, __a2) : __builtin_strspn (canonname, "0123456789."
)))))) : __builtin_strspn (canonname, "0123456789.")); })
== strlen(canonname)))
1019 flags |= LI_NUMERIC;
1020
1021 if (hints->li_flags & LI_IFNAME)
1022 if_namelen = strlen(ifname) + 1;
1023 else
1024 if_namelen = 0;
1025
1026 if ((li = calloc(1, sizeof *li + addrlen + if_namelen)) == NULL((void*)0)) {
1027 error = ELI_MEMORY;
1028 break;
1029 }
1030 addr = (su_sockaddr_t*)memcpy((li + 1), su, addrlen);
1031 *return_result = li; return_result = &li->li_next;
1032
1033 li->li_flags = flags;
1034 li->li_family = AF_INET610;
1035 li->li_scope = scope;
1036 li->li_index = if_index;
1037 li->li_addr = addr;
1038 li->li_addrlen = addrlen;
1039 li->li_canonname = canonname;
1040 if (if_namelen)
1041 li->li_ifname = memcpy(addrlen + (char *)addr, ifname, if_namelen);
1042
1043 canonname = NULL((void*)0);
1044 }
1045
1046 fclose(f);
1047 }
1048
1049 if (canonname)
1050 free(canonname);
1051
1052 return error;
1053}
1054#else
1055/* Use HOSTADDR6 */
1056static
1057int localinfo6(su_localinfo_t const *hints, su_localinfo_t **rresult)
1058{
1059 char *addr, *ifname;
1060 int flags, error;
1061 su_localinfo_t *li = NULL((void*)0);
1062 su_sockaddr_t *su;
1063 int const su_sockaddr_sizeSU_SOCKADDR_SIZE = sizeof(*su);
1064
1065 error = ELI_NOADDRESS;
1066
1067#if defined(__APPLE_CC__)
1068 {
1069 su_sockaddr_t *sa;
1070 int salen = sizeof(*sa);
1071 int s;
1072
1073 if (hints->li_scope == 0 || (hints->li_scope & LI_SCOPE_GLOBAL)) {
1074 if ((addr = getenv("HOSTADDR6"))) {
1075
1076 li = calloc(1, sizeof(su_localinfo_t));
1077 sa = calloc(1, sizeof(su_sockaddr_t));
1078
1079 sa->su_familysu_sa.sa_family = AF_INET610;
1080 if (su_inet_ptoninet_pton(AF_INET610, addr, &sa->su_sin6.sin6_addr) <= 0)
1081 goto err;
1082
1083 s = su_socket(AF_INET610, SOCK_DGRAMSOCK_DGRAM, 0);
1084 if (s == -1) {
1085 SU_DEBUG_1(("su_localinfo: su_socket failed: %s\n",((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 1 ? (_su_llog((su_log_global
), 1, "su_localinfo.c", (const char *)__func__, 1086, "su_localinfo: su_socket failed: %s\n"
, su_strerror(su_errno()))) : (void)0)
1086 su_strerror(su_errno())))((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 1 ? (_su_llog((su_log_global
), 1, "su_localinfo.c", (const char *)__func__, 1086, "su_localinfo: su_socket failed: %s\n"
, su_strerror(su_errno()))) : (void)0)
;
1087 return ELI_SYSTEM;
1088 }
1089
1090 error = getsockname(s, (struct sockaddr *) sa, &salen);
1091 if (error < 0 && errno(*__errno_location ()) == SOCKET_ERRORSOCKET_ERROR) {
1092 SU_DEBUG_1(("%s: getsockname() failed: %s\n", __func__,((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 1 ? (_su_llog((su_log_global
), 1, "su_localinfo.c", (const char *)__func__, 1093, "%s: getsockname() failed: %s\n"
, __func__, su_strerror(su_errno()))) : (void)0)
1093 su_strerror(su_errno())))((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 1 ? (_su_llog((su_log_global
), 1, "su_localinfo.c", (const char *)__func__, 1093, "%s: getsockname() failed: %s\n"
, __func__, su_strerror(su_errno()))) : (void)0)
;
1094 }
1095
1096 error = bind(s, (struct sockaddr *) sa, salen);
1097
1098 if (error < 0) {
1099 SU_DEBUG_1(("%s: bind() failed: %s\n", __func__,((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 1 ? (_su_llog((su_log_global
), 1, "su_localinfo.c", (const char *)__func__, 1100, "%s: bind() failed: %s\n"
, __func__, su_strerror(su_errno()))) : (void)0)
1100 su_strerror(su_errno())))((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 1 ? (_su_llog((su_log_global
), 1, "su_localinfo.c", (const char *)__func__, 1100, "%s: bind() failed: %s\n"
, __func__, su_strerror(su_errno()))) : (void)0)
;
1101 goto err;
1102 }
1103
1104 su_close(s);
1105
1106 li->li_family = sa->su_familysu_sa.sa_family;
1107 li->li_scope = LI_SCOPE_GLOBAL;
1108 li->li_index = 0;
1109 li->li_addrlen = su_sockaddr_size(sa)((socklen_t)((sa)->su_sa.sa_family == 2 ? sizeof((sa)->
su_sin) : ((sa)->su_sa.sa_family == 10 ? sizeof((sa)->su_sin6
) : sizeof(*sa))))
;
1110 li->li_addr = sa;
1111
1112 if ((error = li_name(hints, NI_NUMERICHOST1, sa, &li->li_canonname)) < 0)
1113 goto err;
1114
1115 li->li_flags = NI_NUMERICHOST1;
1116 }
1117 }
1118
1119 *rresult = li;
1120 return 0;
1121 }
1122#endif
1123
1124
1125 if (hints->li_scope == 0 || (hints->li_scope & LI_SCOPE_GLOBAL)) {
1126 if ((addr = getenv("HOSTADDR6"))) {
1127 flags = hints->li_flags & (LI_CANONNAME|LI_NUMERIC|LI_IFNAME);
1128
1129 if ((li = calloc(1, sizeof(*li) + su_sockaddr_sizeSU_SOCKADDR_SIZE)) == NULL((void*)0)) {
1130 error = ELI_MEMORY;
1131 goto err;
1132 }
1133 li->li_flags = flags;
1134 li->li_scope = LI_SCOPE_GLOBAL, li->li_index = 2, ifname = "eth";
1135 li->li_addrlen = sizeof(*su);
1136 li->li_addr = su = (su_sockaddr_t *)(li + 1);
1137 su->su_familysu_sa.sa_family = li->li_family = AF_INET610;
1138 if (su_inet_ptoninet_pton(AF_INET610, addr, &su->su_sin6.sin6_addr) <= 0)
1139 goto err;
1140 if (li->li_flags & LI_IFNAME)
1141 li->li_ifname = ifname;
1142 if ((error = li_name(hints, NI_NUMERICHOST1, su, &li->li_canonname)) < 0)
1143 goto err;
1144 else if (error > 0) {
1145 free(li); li = NULL((void*)0);
1146 }
1147 }
1148 }
1149
1150 *rresult = li;
1151
1152 return 0;
1153
1154err:
1155 if (li) su_freelocalinfo(li);
1156 return error;
1157}
1158#endif
1159
1160#if !USE_LOCALINFO01
1161/* no localinfo0() or bsd_localinfo() */
1162#elif HAVE_GETIFADDRS1
1163
1164#include <ifaddrs.h>
1165
1166static
1167int bsd_localinfo(su_localinfo_t const hints[1],
1168 su_localinfo_t **return_result)
1169{
1170 struct ifaddrs *ifa, *results;
1171 int error = 0;
1172#if SU_HAVE_IN61
1173 int v4_mapped = (hints->li_flags & LI_V4MAPPED) != 0;
1174#endif
1175 char *canonname = NULL((void*)0);
1176
1177 if (getifaddrs(&results) < 0) {
1178 if (errno(*__errno_location ()) == ENOMEM12)
1179 return ELI_MEMORY;
1180 else
1181 return ELI_SYSTEM;
1182 }
1183
1184 for (ifa = results; ifa; ifa = ifa->ifa_next) {
1185 su_localinfo_t *li;
1186 su_sockaddr_t *su;
1187#if SU_HAVE_IN61
1188 su_sockaddr_t su2[1];
1189#endif
1190 socklen_t sulen;
1191 int scope, flags = 0, gni_flags = 0, if_index = 0;
1192 char const *ifname = 0;
1193 size_t ifnamelen = 0;
1194
1195 /* no ip address from if that is down */
1196 if ((ifa->ifa_flags & IFF_UPIFF_UP) == 0 && (hints->li_flags & LI_DOWN) == 0)
1197 continue;
1198
1199 su = (su_sockaddr_t *)ifa->ifa_addr;
1200
1201 if (!su)
1202 continue;
1203
1204 if (su->su_familysu_sa.sa_family == AF_INET2) {
1205 sulen = sizeof(su->su_sin);
1206 scope = li_scope4(su->su_sin.sin_addr.s_addr);
1207#if SU_HAVE_IN61
1208 if (v4_mapped)
1209 sulen = sizeof(su->su_sin6);
1210#endif
1211 }
1212#if SU_HAVE_IN61
1213 else if (su->su_familysu_sa.sa_family == AF_INET610) {
1214 if (IN6_IS_ADDR_MULTICAST(&su->su_sin6.sin6_addr)(((const uint8_t *) (&su->su_sin6.sin6_addr))[0] == 0xff
)
)
1215 continue;
1216 sulen = sizeof(su->su_sin6);
1217 scope = li_scope6(&su->su_sin6.sin6_addr);
1218 }
1219#endif
1220 else
1221 continue;
1222
1223 if (hints->li_flags & LI_IFNAME) {
1224 ifname = ifa->ifa_name;
1225 if (ifname)
1226 ifnamelen = strlen(ifname) + 1;
1227 }
1228
1229 if ((hints->li_scope && (hints->li_scope & scope) == 0) ||
1230 (hints->li_family && hints->li_family != su->su_familysu_sa.sa_family) ||
1231 (hints->li_ifname && (!ifname || strcmp(hints->li_ifname, ifname)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(hints->li_ifname) && __builtin_constant_p (ifname
) && (__s1_len = __builtin_strlen (hints->li_ifname
), __s2_len = __builtin_strlen (ifname), (!((size_t)(const void
*)((hints->li_ifname) + 1) - (size_t)(const void *)(hints
->li_ifname) == 1) || __s1_len >= 4) && (!((size_t
)(const void *)((ifname) + 1) - (size_t)(const void *)(ifname
) == 1) || __s2_len >= 4)) ? __builtin_strcmp (hints->li_ifname
, ifname) : (__builtin_constant_p (hints->li_ifname) &&
((size_t)(const void *)((hints->li_ifname) + 1) - (size_t
)(const void *)(hints->li_ifname) == 1) && (__s1_len
= __builtin_strlen (hints->li_ifname), __s1_len < 4) ?
(__builtin_constant_p (ifname) && ((size_t)(const void
*)((ifname) + 1) - (size_t)(const void *)(ifname) == 1) ? __builtin_strcmp
(hints->li_ifname, ifname) : (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (ifname)
; int __result = (((const unsigned char *) (const char *) (hints
->li_ifname))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (hints->li_ifname))[1] - __s2[1]); if (__s1_len >
1 && __result == 0) { __result = (((const unsigned char
*) (const char *) (hints->li_ifname))[2] - __s2[2]); if (
__s1_len > 2 && __result == 0) __result = (((const
unsigned char *) (const char *) (hints->li_ifname))[3] - __s2
[3]); } } __result; }))) : (__builtin_constant_p (ifname) &&
((size_t)(const void *)((ifname) + 1) - (size_t)(const void *
)(ifname) == 1) && (__s2_len = __builtin_strlen (ifname
), __s2_len < 4) ? (__builtin_constant_p (hints->li_ifname
) && ((size_t)(const void *)((hints->li_ifname) + 1
) - (size_t)(const void *)(hints->li_ifname) == 1) ? __builtin_strcmp
(hints->li_ifname, ifname) : (- (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (hints->
li_ifname); int __result = (((const unsigned char *) (const char
*) (ifname))[0] - __s2[0]); if (__s2_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
ifname))[1] - __s2[1]); if (__s2_len > 1 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
ifname))[2] - __s2[2]); if (__s2_len > 2 && __result
== 0) __result = (((const unsigned char *) (const char *) (ifname
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (hints
->li_ifname, ifname)))); })
)) ||
1232 (hints->li_index && hints->li_index != if_index))
1233 continue;
1234
1235 if (scope == LI_SCOPE_HOST || scope == LI_SCOPE_LINK)
1236 gni_flags = NI_NUMERICHOST1;
1237
1238#if SU_HAVE_IN61
1239 if (v4_mapped && su->su_familysu_sa.sa_family == AF_INET2) {
1240 /* Map IPv4 address to IPv6 address */
1241 memset(su2, 0, sizeof(*su2));
1242 su2->su_familysu_sa.sa_family = AF_INET610;
1243 ((int32_t*)&su2->su_sin6.sin6_addr)[2] = htonl(0xffff)(__extension__ ({ unsigned int __v, __x = (0xffff); if (__builtin_constant_p
(__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x
) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) <<
8) | (((__x) & 0x000000ff) << 24)); else __asm__ (
"bswap %0" : "=r" (__v) : "0" (__x)); __v; }))
;
1244 ((int32_t*)&su2->su_sin6.sin6_addr)[3] = su->su_sin.sin_addr.s_addr;
1245 su = su2;
1246 }
1247#endif
1248
1249 if ((error = li_name(hints, gni_flags, su, &canonname)) < 0)
1250 break;
1251
1252 if (error > 0) {
1253 error = 0;
1254 continue;
1255 }
1256
1257 if (canonname)
1258 if (strchr(canonname, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(canonname) && (':') == '\0' ? (char *) __rawmemchr (
canonname, ':') : __builtin_strchr (canonname, ':')))
||
1259 canonname[strspn(canonname, "0123456789.")__extension__ ({ char __a0, __a1, __a2; (__builtin_constant_p
("0123456789.") && ((size_t)(const void *)(("0123456789."
) + 1) - (size_t)(const void *)("0123456789.") == 1) ? ((__builtin_constant_p
(canonname) && ((size_t)(const void *)((canonname) +
1) - (size_t)(const void *)(canonname) == 1)) ? __builtin_strspn
(canonname, "0123456789.") : ((__a0 = ((const char *) ("0123456789."
))[0], __a0 == '\0') ? ((void) (canonname), (size_t) 0) : ((__a1
= ((const char *) ("0123456789."))[1], __a1 == '\0') ? __strspn_c1
(canonname, __a0) : ((__a2 = ((const char *) ("0123456789.")
)[2], __a2 == '\0') ? __strspn_c2 (canonname, __a0, __a1) : (
((const char *) ("0123456789."))[3] == '\0' ? __strspn_c3 (canonname
, __a0, __a1, __a2) : __builtin_strspn (canonname, "0123456789."
)))))) : __builtin_strspn (canonname, "0123456789.")); })
] == '\0')
1260 flags |= LI_NUMERIC;
1261
1262 if (!(li = calloc(1, sizeof(*li) + sulen + ifnamelen))) {
1263 SU_DEBUG_1(("su_getlocalinfo: memory exhausted\n" VA_NONE))((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 1 ? (_su_llog((su_log_global
), 1, "su_localinfo.c", (const char *)__func__, 1263, "su_getlocalinfo: memory exhausted\n"
"%s", "")) : (void)0)
;
1264 error = ELI_MEMORY;
1265 break;
1266 }
1267 *return_result = li, return_result = &li->li_next;
1268
1269 li->li_flags = flags;
1270 li->li_family = su->su_familysu_sa.sa_family;
1271 li->li_scope = scope;
1272 li->li_index = if_index;
1273 li->li_addrlen = sulen;
1274 li->li_addr = memcpy(li + 1, su, sulen);
1275 li->li_canonname = canonname;
1276 if (ifnamelen) {
1277 li->li_ifname = strcpy((char *)(li + 1) + sulen, ifname);
1278 }
1279
1280 canonname = NULL((void*)0);
1281 }
1282
1283 if (canonname)
1284 free(canonname);
1285
1286 freeifaddrs(results);
1287
1288 return error;
1289}
1290
1291#elif USE_LOCALINFO01 && HAVE_IPHLPAPI_H && SU_HAVE_IN61
1292
1293static
1294char const *ws2ifname(DWORD iftype)
1295{
1296 switch (iftype) {
1297 case IF_TYPE_ETHERNET_CSMACD: return "eth";
1298 case IF_TYPE_IEEE80212: return "eth";
1299 case IF_TYPE_FASTETHER: return "eth";
1300 case IF_TYPE_GIGABITETHERNET: return "eth";
1301 case IF_TYPE_ISO88025_TOKENRING: return "token";
1302 case IF_TYPE_FDDI: return "fddi";
1303 case IF_TYPE_PPP: return "ppp";
1304 case IF_TYPE_SOFTWARE_LOOPBACK: return "lo";
1305 case IF_TYPE_SLIP: return "sl";
1306 case IF_TYPE_FRAMERELAY: return "fr";
1307 case IF_TYPE_ATM: return "atm";
1308 case IF_TYPE_HIPPI: return "hippi";
1309 case IF_TYPE_ISDN: return "isdn";
1310 case IF_TYPE_IEEE80211: return "wlan";
1311 case IF_TYPE_ADSL: return "adsl";
1312 case IF_TYPE_RADSL: return "radsl";
1313 case IF_TYPE_SDSL: return "sdsl";
1314 case IF_TYPE_VDSL: return "vdsl";
1315 case IF_TYPE_TUNNEL: return "tunnel";
1316 case IF_TYPE_IEEE1394: return "fw";
1317 case IF_TYPE_OTHER:
1318 default: return "other";
1319 }
1320}
1321
1322static
1323int win_localinfo(su_localinfo_t const hints[1], su_localinfo_t **rresult)
1324{
1325 /* This is Windows XP code, for both IPv6 and IPv4. */
1326 ULONG iaa_size = 2048;
1327 IP_ADAPTER_ADDRESSES *iaa0, *iaa;
1328 int error, loopback_seen = 0;
1329 int v4_mapped = (hints->li_flags & LI_V4MAPPED) != 0;
1330 char *canonname = NULL((void*)0);
1331 su_localinfo_t *li, **next;
1332 int flags = GAA_FLAG_SKIP_MULTICAST;
1333 *rresult = NULL((void*)0); next = rresult;
1334
1335 iaa0 = malloc((size_t)iaa_size);
1336 if (!iaa0) {
1337 SU_DEBUG_1(("su_localinfo: memory exhausted\n"))((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 1 ? (_su_llog((su_log_global
), 1, "su_localinfo.c", (const char *)__func__, 1337, "su_localinfo: memory exhausted\n"
, )) : (void)0)
;
1338 error = ELI_MEMORY;
1339 goto err;
1340 }
1341 error = GetAdaptersAddresses(hints->li_family, flags, NULL((void*)0), iaa0, &iaa_size);
1342 if (error == ERROR_BUFFER_OVERFLOW) {
1343 if ((iaa0 = realloc(iaa0, iaa_size)))
1344 error = GetAdaptersAddresses(hints->li_family, flags, NULL((void*)0), iaa0, &iaa_size);
1345 }
1346 if (error) {
1347 char const *empty = "";
1348 LPTSTR msg = empty;
1349
1350 if (error == ERROR_NO_DATA) {
1351 error = ELI_NOADDRESS;
1352 goto err;
1353 }
1354
1355 if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
1356 FORMAT_MESSAGE_FROM_SYSTEM |
1357 FORMAT_MESSAGE_IGNORE_INSERTS,
1358 NULL((void*)0),
1359 error,
1360 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
1361 msg, 0, NULL((void*)0)))
1362 msg = empty;
1363
1364 SU_DEBUG_1(("su_localinfo: GetAdaptersAddresses: %s (%d)\n", msg, error))((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 1 ? (_su_llog((su_log_global
), 1, "su_localinfo.c", (const char *)__func__, 1364, "su_localinfo: GetAdaptersAddresses: %s (%d)\n"
, msg, error)) : (void)0)
;
1365 if (msg != empty) LocalFree((LPVOID)msg);
1366 error = ELI_SYSTEM;
1367 goto err;
1368 }
1369
1370 for (iaa = iaa0; iaa; iaa = iaa->Next) {
1371 IP_ADAPTER_UNICAST_ADDRESS *ua;
1372 IP_ADAPTER_UNICAST_ADDRESS lua[1];
1373 int if_index = iaa->IfIndex;
1374 size_t ifnamelen = 0;
1375 char ifname[16];
1376
1377 for (ua = iaa->FirstUnicastAddress; ;ua = ua->Next) {
1378 su_sockaddr_t *su;
1379 socklen_t sulen;
1380 su_sockaddr_t su2[1];
1381 int scope, flags = 0, gni_flags = 0;
1382
1383 if (ua == NULL((void*)0)) {
1384 /* There is no loopback interface in windows */
1385 if (!loopback_seen && iaa->Next == NULL((void*)0)) {
1386 struct sockaddr_in loopback_sin = { AF_INET2, 0, {{ 127, 0, 0, 1 }}};
1387
1388 lua->Address.lpSockaddr = (struct sockaddr *)&loopback_sin;
1389 lua->Address.iSockaddrLength = sizeof(loopback_sin);
1390 lua->Next = NULL((void*)0);
1391
1392 iaa->IfType = IF_TYPE_SOFTWARE_LOOPBACK;
1393 if_index = 1;
1394
1395 ua = lua;
1396 }
1397 else
1398 break;
1399 }
1400
1401 su = (su_sockaddr_t *)ua->Address.lpSockaddr;
1402 sulen = ua->Address.iSockaddrLength;
1403
1404 if (su->su_familysu_sa.sa_family == AF_INET2) {
1405 scope = li_scope4(su->su_sin.sin_addr.s_addr);
1406 if (v4_mapped)
1407 sulen = sizeof(su->su_sin6);
1408 if (scope == LI_SCOPE_HOST)
1409 loopback_seen = 1;
1410 }
1411 else if (su->su_familysu_sa.sa_family == AF_INET610) {
1412 if (IN6_IS_ADDR_MULTICAST(&su->su_sin6.sin6_addr)(((const uint8_t *) (&su->su_sin6.sin6_addr))[0] == 0xff
)
)
1413 continue;
1414 scope = li_scope6(&su->su_sin6.sin6_addr);
1415 }
1416 else
1417 continue;
1418
1419 if (hints->li_flags & LI_IFNAME) {
1420 snprintf(ifname, sizeof(ifname), "%s%u",
1421 ws2ifname(iaa->IfType), if_index);
1422 ifnamelen = strlen(ifname) + 1;
1423 }
1424
1425 if ((hints->li_scope && (hints->li_scope & scope) == 0) ||
1426 (hints->li_family && hints->li_family != su->su_familysu_sa.sa_family) ||
1427 /* (hints->li_ifname && strcmp(hints->li_ifname, ifname) != 0) || */
1428 (hints->li_index && hints->li_index != if_index))
1429 continue;
1430
1431 if (scope == LI_SCOPE_HOST || scope == LI_SCOPE_LINK)
1432 gni_flags = NI_NUMERICHOST1;
1433
1434 if (v4_mapped && su->su_familysu_sa.sa_family == AF_INET2) {
1435 /* Map IPv4 address to IPv6 address */
1436 memset(su2, 0, sizeof(*su2));
1437 su2->su_familysu_sa.sa_family = AF_INET610;
1438 ((int32_t*)&su2->su_sin6.sin6_addr)[2] = htonl(0xffff)(__extension__ ({ unsigned int __v, __x = (0xffff); if (__builtin_constant_p
(__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x
) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) <<
8) | (((__x) & 0x000000ff) << 24)); else __asm__ (
"bswap %0" : "=r" (__v) : "0" (__x)); __v; }))
;
1439 ((int32_t*)&su2->su_sin6.sin6_addr)[3] = su->su_sin.sin_addr.s_addr;
1440 su = su2;
1441 }
1442
1443 if ((error = li_name(hints, gni_flags, su, &canonname)) < 0)
1444 goto err;
1445 else if (error > 0)
1446 continue;
1447
1448 if (canonname)
1449 if (strchr(canonname, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(canonname) && (':') == '\0' ? (char *) __rawmemchr (
canonname, ':') : __builtin_strchr (canonname, ':')))
||
1450 strspn(canonname, "0123456789.")__extension__ ({ char __a0, __a1, __a2; (__builtin_constant_p
("0123456789.") && ((size_t)(const void *)(("0123456789."
) + 1) - (size_t)(const void *)("0123456789.") == 1) ? ((__builtin_constant_p
(canonname) && ((size_t)(const void *)((canonname) +
1) - (size_t)(const void *)(canonname) == 1)) ? __builtin_strspn
(canonname, "0123456789.") : ((__a0 = ((const char *) ("0123456789."
))[0], __a0 == '\0') ? ((void) (canonname), (size_t) 0) : ((__a1
= ((const char *) ("0123456789."))[1], __a1 == '\0') ? __strspn_c1
(canonname, __a0) : ((__a2 = ((const char *) ("0123456789.")
)[2], __a2 == '\0') ? __strspn_c2 (canonname, __a0, __a1) : (
((const char *) ("0123456789."))[3] == '\0' ? __strspn_c3 (canonname
, __a0, __a1, __a2) : __builtin_strspn (canonname, "0123456789."
)))))) : __builtin_strspn (canonname, "0123456789.")); })
== strlen(canonname))
1451 flags |= LI_NUMERIC;
1452
1453 if (!(li = calloc(1, sizeof(*li) + sulen + ifnamelen))) {
1454 SU_DEBUG_1(("su_getlocalinfo: memory exhausted\n"))((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 1 ? (_su_llog((su_log_global
), 1, "su_localinfo.c", (const char *)__func__, 1454, "su_getlocalinfo: memory exhausted\n"
, )) : (void)0)
;
1455 error = ELI_MEMORY; goto err;
1456 }
1457 *next = li, next = &li->li_next;
1458
1459 li->li_flags = flags;
1460 li->li_family = su->su_familysu_sa.sa_family;
1461 li->li_scope = scope;
1462 li->li_index = if_index;
1463 li->li_addrlen = sulen;
1464 li->li_addr = memcpy(li + 1, su, sulen);
1465 li->li_canonname = canonname;
1466 if (ifnamelen) {
1467 li->li_ifname = strcpy((char *)(li + 1) + sulen, ifname);
1468 /* WideCharToMultiByte(CP_ACP, 0,
1469 ifname, -1, (char *)(li + 1) + sulen, ifnamelen,
1470 NULL, NULL); */
1471 }
1472
1473 canonname = NULL((void*)0);
1474 }
1475 }
1476
1477 if (iaa0) free(iaa0);
1478 return 0;
1479
1480err:
1481 if (iaa0) free(iaa0);
1482 if (canonname) free(canonname);
1483 su_freelocalinfo(*rresult), *rresult = NULL((void*)0);
1484 return error;
1485}
1486
1487#elif HAVE_SIO_ADDRESS_LIST_QUERY
1488
1489static
1490int localinfo0bsd_localinfo(su_localinfo_t const *hints, su_localinfo_t **rresult)
1491{
1492 /* This is Windows IPv4 code */
1493 short family = AF_INET2;
1494 su_socket_t s;
1495 union {
1496 SOCKET_ADDRESS_LIST sal[1];
1497#if HAVE_INTERFACE_INFO_EX
1498 INTERFACE_INFO_EX ii[1];
1499#else
1500 INTERFACE_INFO ii[1];
1501#endif
1502 char buffer[2048];
1503 } b = {{ 1 }};
1504 DWORD salen = sizeof(b);
1505 int i, error = -1;
1506#if SU_HAVE_IN61
1507 int v4_mapped = (hints->li_flags & LI_V4MAPPED) != 0;
1508#endif
1509 su_localinfo_t *li, *head = NULL((void*)0), **next = &head;
1510 char *canonname = NULL((void*)0), *if_name = NULL((void*)0);
1511
1512 *rresult = NULL((void*)0);
1513
1514 s = su_socket(family, SOCK_DGRAMSOCK_DGRAM, 0);
1515 if (s == INVALID_SOCKET((su_socket_t)INVALID_SOCKET)) {
1516 SU_DEBUG_1(("su_getlocalinfo: %s: %s\n", "su_socket",((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 1 ? (_su_llog((su_log_global
), 1, "su_localinfo.c", (const char *)__func__, 1517, "su_getlocalinfo: %s: %s\n"
, "su_socket", su_strerror(su_errno()))) : (void)0)
1517 su_strerror(su_errno())))((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 1 ? (_su_llog((su_log_global
), 1, "su_localinfo.c", (const char *)__func__, 1517, "su_getlocalinfo: %s: %s\n"
, "su_socket", su_strerror(su_errno()))) : (void)0)
;
1518 return -1;
1519 }
1520
1521 /* get the list of known IP address (NT5 and up) */
1522 if (WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL((void*)0), 0,
1523 &b, sizeof(b), &salen, NULL((void*)0), NULL((void*)0)) == SOCKET_ERRORSOCKET_ERROR) {
1524 SU_DEBUG_1(("su_getlocalinfo: %s: %s\n", "SIO_ADDRESS_LIST_QUERY",((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 1 ? (_su_llog((su_log_global
), 1, "su_localinfo.c", (const char *)__func__, 1525, "su_getlocalinfo: %s: %s\n"
, "SIO_ADDRESS_LIST_QUERY", su_strerror(su_errno()))) : (void
)0)
1525 su_strerror(su_errno())))((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 1 ? (_su_llog((su_log_global
), 1, "su_localinfo.c", (const char *)__func__, 1525, "su_getlocalinfo: %s: %s\n"
, "SIO_ADDRESS_LIST_QUERY", su_strerror(su_errno()))) : (void
)0)
;
1526 error = -1; goto err;
1527 }
1528 if (b.sal->iAddressCount < 1) {
1529 SU_DEBUG_1(("su_getlocalinfo: no local addresses\n"))((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 1 ? (_su_llog((su_log_global
), 1, "su_localinfo.c", (const char *)__func__, 1529, "su_getlocalinfo: no local addresses\n"
, )) : (void)0)
;
1530 error = -1; goto err;
1531 }
1532
1533 for (i = 0; i < b.sal->iAddressCount; i++) {
1534 su_sockaddr_t *su = (su_sockaddr_t *)b.sal->Address[i].lpSockaddr;
1535#if SU_HAVE_IN61
1536 socklen_t sulen = v4_mapped ? sizeof(*su) : b.sal->Address[i].iSockaddrLength;
1537 su_sockaddr_t su2[1];
1538#else
1539 socklen_t sulen = b.sal->Address[i].iSockaddrLength;
1540#endif
1541 int scope, flags = 0, gni_flags = 0;
1542
1543 scope = li_scope4(su->su_sin.sin_addr.s_addr);
1544
1545 if (hints->li_scope && (hints->li_scope & scope) == 0)
1546 continue;
1547
1548 if (scope == LI_SCOPE_HOST || scope == LI_SCOPE_LINK)
1549 gni_flags = NI_NUMERICHOST1;
1550
1551 if (!(li = calloc(1, sizeof(*li) + sulen))) {
1552 SU_DEBUG_1(("su_getlocalinfo: memory exhausted\n"))((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 1 ? (_su_llog((su_log_global
), 1, "su_localinfo.c", (const char *)__func__, 1552, "su_getlocalinfo: memory exhausted\n"
, )) : (void)0)
;
1553 error = -1; goto err;
1554 }
1555 *next = li, next = &li->li_next;
1556
1557#if SU_HAVE_IN61
1558 if (v4_mapped) {
1559 /* Map IPv4 address to IPv6 address */
1560 memset(su2, 0, sizeof(*su2));
1561 su2->su_familysu_sa.sa_family = AF_INET610;
1562 ((int32_t*)&su2->su_sin6.sin6_addr)[2] = htonl(0xffff)(__extension__ ({ unsigned int __v, __x = (0xffff); if (__builtin_constant_p
(__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x
) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) <<
8) | (((__x) & 0x000000ff) << 24)); else __asm__ (
"bswap %0" : "=r" (__v) : "0" (__x)); __v; }))
;
1563 ((int32_t*)&su2->su_sin6.sin6_addr)[3] = su->su_sin.sin_addr.s_addr;
1564 su = su2;
1565 }
1566#endif
1567
1568 if ((error = li_name(hints, gni_flags, su, &canonname)) < 0)
1569 goto err;
1570 else if (error > 0)
1571 continue;
1572
1573 if (canonname)
1574 if (strchr(canonname, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(canonname) && (':') == '\0' ? (char *) __rawmemchr (
canonname, ':') : __builtin_strchr (canonname, ':')))
||
1575 strspn(canonname, "0123456789.")__extension__ ({ char __a0, __a1, __a2; (__builtin_constant_p
("0123456789.") && ((size_t)(const void *)(("0123456789."
) + 1) - (size_t)(const void *)("0123456789.") == 1) ? ((__builtin_constant_p
(canonname) && ((size_t)(const void *)((canonname) +
1) - (size_t)(const void *)(canonname) == 1)) ? __builtin_strspn
(canonname, "0123456789.") : ((__a0 = ((const char *) ("0123456789."
))[0], __a0 == '\0') ? ((void) (canonname), (size_t) 0) : ((__a1
= ((const char *) ("0123456789."))[1], __a1 == '\0') ? __strspn_c1
(canonname, __a0) : ((__a2 = ((const char *) ("0123456789.")
)[2], __a2 == '\0') ? __strspn_c2 (canonname, __a0, __a1) : (
((const char *) ("0123456789."))[3] == '\0' ? __strspn_c3 (canonname
, __a0, __a1, __a2) : __builtin_strspn (canonname, "0123456789."
)))))) : __builtin_strspn (canonname, "0123456789.")); })
== strlen(canonname))
1576 flags |= LI_NUMERIC;
1577
1578 li->li_flags = flags;
1579 li->li_family = su->su_familysu_sa.sa_family;
1580 li->li_scope = scope;
1581 li->li_index = i;
1582 li->li_addrlen = su_sockaddr_size(su)((socklen_t)((su)->su_sa.sa_family == 2 ? sizeof((su)->
su_sin) : ((su)->su_sa.sa_family == 10 ? sizeof((su)->su_sin6
) : sizeof(*su))))
;
1583 li->li_addr = su;
1584 li->li_canonname = canonname, canonname = NULL((void*)0);
1585 if (hints->li_flags & LI_IFNAME)
1586 li->li_ifname = if_name;
1587 li->li_addr = (su_sockaddr_t *)(li + 1);
1588 li->li_addrlen = sulen;
1589 memcpy(li->li_addr, su, sulen);
1590 }
1591
1592 *rresult = head;
1593 su_close(s);
1594
1595 return 0;
1596
1597err:
1598 if (canonname) free(canonname);
1599 su_freelocalinfo(head);
1600 su_close(s);
1601
1602 return error;
1603}
1604#endif
1605
1606#if !SU_LOCALINFO_TEST
1607
1608static
1609int li_name(su_localinfo_t const *hints,
1610 int gni_flags,
1611 su_sockaddr_t const *su,
1612 char **ccanonname)
1613{
1614 char name[SU_MAXHOST(1025)];
1615 int error;
1616 int flags = hints->li_flags;
1617
1618 *ccanonname = NULL((void*)0);
1619
1620 if ((flags & LI_CANONNAME) || hints->li_canonname) {
1621 if ((flags & LI_NAMEREQD) == LI_NAMEREQD)
1622 gni_flags |= NI_NAMEREQD8;
1623 if (flags & LI_NUMERIC)
1624 gni_flags |= NI_NUMERICHOST1;
1625
1626 error = su_getnameinfo(su, su_sockaddr_size(su)((socklen_t)((su)->su_sa.sa_family == 2 ? sizeof((su)->
su_sin) : ((su)->su_sa.sa_family == 10 ? sizeof((su)->su_sin6
) : sizeof(*su))))
,
1627 name, sizeof(name), NULL((void*)0), 0,
1628 gni_flags);
1629 if (error) {
1630 if ((flags & LI_NAMEREQD) == LI_NAMEREQD)
1631 return 1;
1632 SU_DEBUG_7(("li_name: getnameinfo() failed\n" VA_NONE))((((su_log_global) != ((void*)0) && (su_log_global)->
log_init) == 0 ? 9 : (((su_log_global) != ((void*)0) &&
(su_log_global)->log_init > 1) ? (su_log_global)->log_level
: su_log_default->log_level)) >= 7 ? (_su_llog((su_log_global
), 7, "su_localinfo.c", (const char *)__func__, 1632, "li_name: getnameinfo() failed\n"
"%s", "")) : (void)0)
;
1633 if (!su_inet_ntopinet_ntop(su->su_familysu_sa.sa_family, SU_ADDR(su)((su)->su_sa.sa_family == 2 ? (void *)&(su)->su_sin
.sin_addr : ((su)->su_sa.sa_family == 10 ? (void *)&(su
)->su_sin6.sin6_addr : (void *)&(su)->su_sa.sa_data
))
, name, sizeof name))
1634 return ELI_RESOLVER;
1635 }
1636
1637 if (hints->li_canonname && !su_casematch(name, hints->li_canonname))
1638 return 1;
1639
1640 if (!(flags & LI_CANONNAME))
1641 return 0;
1642
1643 if (!(*ccanonname = strdup(name)(__extension__ (__builtin_constant_p (name) && ((size_t
)(const void *)((name) + 1) - (size_t)(const void *)(name) ==
1) ? (((const char *) (name))[0] == '\0' ? (char *) calloc (
(size_t) 1, (size_t) 1) : ({ size_t __len = strlen (name) + 1
; char *__retval = (char *) malloc (__len); if (__retval != (
(void*)0)) __retval = (char *) memcpy (__retval, name, __len)
; __retval; })) : __strdup (name)))
))
1644 return ELI_MEMORY;
1645 }
1646 return 0;
1647}
1648
1649static
1650void li_sort(su_localinfo_t *i, su_localinfo_t **rresult)
1651{
1652 su_localinfo_t *li, **lli;
1653
1654#define LI_MAPPED(li)((li)->li_family == 10 && ((__extension__ ({ const
struct in6_addr *__a = (const struct in6_addr *) (&(li)->
li_addr->su_sin6.sin6_addr); __a->__in6_u.__u6_addr32[0
] == 0 && __a->__in6_u.__u6_addr32[1] == 0 &&
__a->__in6_u.__u6_addr32[2] == (__extension__ ({ unsigned
int __v, __x = (0xffff); if (__builtin_constant_p (__x)) __v
= ((((__x) & 0xff000000) >> 24) | (((__x) & 0x00ff0000
) >> 8) | (((__x) & 0x0000ff00) << 8) | (((__x
) & 0x000000ff) << 24)); else __asm__ ("bswap %0" :
"=r" (__v) : "0" (__x)); __v; })); })) || (__extension__ ({ const
struct in6_addr *__a = (const struct in6_addr *) (&(li)->
li_addr->su_sin6.sin6_addr); __a->__in6_u.__u6_addr32[0
] == 0 && __a->__in6_u.__u6_addr32[1] == 0 &&
__a->__in6_u.__u6_addr32[2] == 0 && (__extension__
({ unsigned int __v, __x = (__a->__in6_u.__u6_addr32[3]);
if (__builtin_constant_p (__x)) __v = ((((__x) & 0xff000000
) >> 24) | (((__x) & 0x00ff0000) >> 8) | (((__x
) & 0x0000ff00) << 8) | (((__x) & 0x000000ff) <<
24)); else __asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); __v
; })) > 1; }))))
\
1655 ((li)->li_family == AF_INET610 && \
1656 (IN6_IS_ADDR_V4MAPPED(&(li)->li_addr->su_sin6.sin6_addr)(__extension__ ({ const struct in6_addr *__a = (const struct in6_addr
*) (&(li)->li_addr->su_sin6.sin6_addr); __a->__in6_u
.__u6_addr32[0] == 0 && __a->__in6_u.__u6_addr32[1
] == 0 && __a->__in6_u.__u6_addr32[2] == (__extension__
({ unsigned int __v, __x = (0xffff); if (__builtin_constant_p
(__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x
) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) <<
8) | (((__x) & 0x000000ff) << 24)); else __asm__ (
"bswap %0" : "=r" (__v) : "0" (__x)); __v; })); }))
|| \
1657 IN6_IS_ADDR_V4COMPAT(&(li)->li_addr->su_sin6.sin6_addr)(__extension__ ({ const struct in6_addr *__a = (const struct in6_addr
*) (&(li)->li_addr->su_sin6.sin6_addr); __a->__in6_u
.__u6_addr32[0] == 0 && __a->__in6_u.__u6_addr32[1
] == 0 && __a->__in6_u.__u6_addr32[2] == 0 &&
(__extension__ ({ unsigned int __v, __x = (__a->__in6_u.__u6_addr32
[3]); if (__builtin_constant_p (__x)) __v = ((((__x) & 0xff000000
) >> 24) | (((__x) & 0x00ff0000) >> 8) | (((__x
) & 0x0000ff00) << 8) | (((__x) & 0x000000ff) <<
24)); else __asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); __v
; })) > 1; }))
))
1658
1659 /* Sort addresses according to scope (and mappedness) */
1660 for (li = i; li; li = i) {
1661 i = li->li_next;
1662 for (lli = rresult; *lli; lli = &(*lli)->li_next) {
1663 if ((*lli)->li_scope < li->li_scope)
1664 break;
1665#if SU_HAVE_IN61
1666 if (LI_MAPPED(*lli)((*lli)->li_family == 10 && ((__extension__ ({ const
struct in6_addr *__a = (const struct in6_addr *) (&(*lli
)->li_addr->su_sin6.sin6_addr); __a->__in6_u.__u6_addr32
[0] == 0 && __a->__in6_u.__u6_addr32[1] == 0 &&
__a->__in6_u.__u6_addr32[2] == (__extension__ ({ unsigned
int __v, __x = (0xffff); if (__builtin_constant_p (__x)) __v
= ((((__x) & 0xff000000) >> 24) | (((__x) & 0x00ff0000
) >> 8) | (((__x) & 0x0000ff00) << 8) | (((__x
) & 0x000000ff) << 24)); else __asm__ ("bswap %0" :
"=r" (__v) : "0" (__x)); __v; })); })) || (__extension__ ({ const
struct in6_addr *__a = (const struct in6_addr *) (&(*lli
)->li_addr->su_sin6.sin6_addr); __a->__in6_u.__u6_addr32
[0] == 0 && __a->__in6_u.__u6_addr32[1] == 0 &&
__a->__in6_u.__u6_addr32[2] == 0 && (__extension__
({ unsigned int __v, __x = (__a->__in6_u.__u6_addr32[3]);
if (__builtin_constant_p (__x)) __v = ((((__x) & 0xff000000
) >> 24) | (((__x) & 0x00ff0000) >> 8) | (((__x
) & 0x0000ff00) << 8) | (((__x) & 0x000000ff) <<
24)); else __asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); __v
; })) > 1; }))))
> LI_MAPPED(li)((li)->li_family == 10 && ((__extension__ ({ const
struct in6_addr *__a = (const struct in6_addr *) (&(li)->
li_addr->su_sin6.sin6_addr); __a->__in6_u.__u6_addr32[0
] == 0 && __a->__in6_u.__u6_addr32[1] == 0 &&
__a->__in6_u.__u6_addr32[2] == (__extension__ ({ unsigned
int __v, __x = (0xffff); if (__builtin_constant_p (__x)) __v
= ((((__x) & 0xff000000) >> 24) | (((__x) & 0x00ff0000
) >> 8) | (((__x) & 0x0000ff00) << 8) | (((__x
) & 0x000000ff) << 24)); else __asm__ ("bswap %0" :
"=r" (__v) : "0" (__x)); __v; })); })) || (__extension__ ({ const
struct in6_addr *__a = (const struct in6_addr *) (&(li)->
li_addr->su_sin6.sin6_addr); __a->__in6_u.__u6_addr32[0
] == 0 && __a->__in6_u.__u6_addr32[1] == 0 &&
__a->__in6_u.__u6_addr32[2] == 0 && (__extension__
({ unsigned int __v, __x = (__a->__in6_u.__u6_addr32[3]);
if (__builtin_constant_p (__x)) __v = ((((__x) & 0xff000000
) >> 24) | (((__x) & 0x00ff0000) >> 8) | (((__x
) & 0x0000ff00) << 8) | (((__x) & 0x000000ff) <<
24)); else __asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); __v
; })) > 1; }))))
)
1667 break;
1668#endif
1669 }
1670 li->li_next = *lli;
1671 *lli = li;
1672 }
1673}
1674
1675#endif
1676
1677/**Get local IP address.
1678 *
1679 * @deprecated
1680 * Use su_getlocalinfo() instead.
1681 */
1682int su_getlocalip(su_sockaddr_t *sa)
1683{
1684 su_localinfo_t *li = NULL((void*)0), hints[1] = {{ 0 }};
1685
1686 hints->li_family = sa->su_sa.sa_family ? sa->su_sa.sa_family : AF_INET2;
1687
1688 if (su_getlocalinfo(hints, &li) == 0) {
1689 memcpy(sa, li->li_addr, li->li_addrlen);
1690 su_freelocalinfo(li);
1691 return 0;
1692 }
1693 else
1694 return -1;
1695}