1
/* vim:ts=8:sts=8:sw=4:noai:noexpandtab
3
* portable interface index to socket address function.
5
* Copyright (c) 2006-2011 Miru Limited.
7
* This library is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 2.1 of the License, or (at your option) any later version.
12
* This library is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with this library; if not, write to the Free Software
19
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
#include <impl/i18n.h>
23
#include <impl/framework.h>
26
//#define INDEXTOADDR_DEBUG
29
/* interfaces indexes refer to the link layer, we want to find the internet layer address.
30
* the big problem is that multiple IPv6 addresses can be bound to one link - called scopes.
31
* we can just pick the first scope and let IP routing handle the rest.
37
const unsigned ifindex,
38
const sa_family_t iffamily,
39
const uint32_t ifscope,
40
struct sockaddr* restrict ifsa,
41
pgm_error_t** restrict error
44
pgm_return_val_if_fail (NULL != ifsa, FALSE);
46
if (0 == ifindex) /* any interface or address */
48
ifsa->sa_family = iffamily;
51
((struct sockaddr_in*)ifsa)->sin_addr.s_addr = INADDR_ANY;
55
((struct sockaddr_in6*)ifsa)->sin6_addr = in6addr_any;
59
pgm_return_val_if_reached (FALSE);
65
struct pgm_ifaddrs_t *ifap, *ifa;
66
if (!pgm_getifaddrs (&ifap, error)) {
67
pgm_prefix_error (error,
68
_("Enumerating network interfaces: "));
72
for (ifa = ifap; ifa; ifa = ifa->ifa_next)
74
if (NULL == ifa->ifa_addr ||
75
ifa->ifa_addr->sa_family != iffamily)
78
const unsigned i = pgm_if_nametoindex (iffamily, ifa->ifa_name);
82
if (ifscope && ifscope != pgm_sockaddr_scope_id (ifa->ifa_addr))
84
memcpy (ifsa, ifa->ifa_addr, pgm_sockaddr_len(ifa->ifa_addr));
85
pgm_freeifaddrs (ifap);
93
_("No matching network interface index: %i"),
95
pgm_freeifaddrs (ifap);