2 * copyright (c) 2001-2008 Emil Mikulic.
4 * localip.c: determine local IP of our capture interface
6 * You may use, modify and redistribute this file under the terms of the
7 * GNU General Public License version 2. (see COPYING.GPL)
12 #include "conv.h" /* for strlcpy */
16 #include <sys/socket.h>
23 static const char *iface
= NULL
;
24 struct addr localip4
, localip6
;
25 static struct addr last_localip4
, last_localip6
;
28 localip_init(const char *interface
)
37 struct ifaddrs
*ifas
, *ifa
;
38 int got_v4
= 0, got_v6
= 0;
40 localip4
.family
= IPv4
;
41 localip6
.family
= IPv6
;
44 /* reading from capfile */
46 memset(&(localip6
.ip
.v6
), 0, sizeof(localip6
.ip
.v6
));
50 if (getifaddrs(&ifas
) < 0)
51 err(1, "can't get own IP address on interface \"%s\"", iface
);
53 for (ifa
= ifas
; ifa
; ifa
= ifa
->ifa_next
) {
55 break; /* Task is already complete. */
57 if (strncmp(ifa
->ifa_name
, iface
, IFNAMSIZ
))
58 continue; /* Wrong interface. */
60 /* The first IPv4 name is always functional. */
61 if ((ifa
->ifa_addr
->sa_family
== AF_INET
) && !got_v4
)
63 /* Good IPv4 address. */
65 ((struct sockaddr_in
*)ifa
->ifa_addr
)->sin_addr
.s_addr
;
70 /* IPv6 needs some obvious exceptions. */
71 if ( ifa
->ifa_addr
->sa_family
== AF_INET6
) {
72 struct sockaddr_in6
*sa6
= (struct sockaddr_in6
*) ifa
->ifa_addr
;
74 if ( IN6_IS_ADDR_LINKLOCAL(&(sa6
->sin6_addr
))
75 || IN6_IS_ADDR_SITELOCAL(&(sa6
->sin6_addr
)) )
78 /* Only standard IPv6 can reach this point. */
79 memcpy(&(localip6
.ip
.v6
), &sa6
->sin6_addr
, sizeof(localip6
.ip
.v6
));
86 /* Report an error if IPv4 address could not be found. */
88 err(1, "can't get own IPv4 address on interface \"%s\"", iface
);
90 if (!addr_equal(&last_localip4
, &localip4
)) {
91 verbosef("localip4 update(%s) = %s", iface
, addr_to_str(&localip4
));
92 last_localip4
= localip4
;
94 if (!addr_equal(&last_localip6
, &localip6
)) {
95 verbosef("localip6 update(%s) = %s", iface
, addr_to_str(&localip6
));
96 last_localip6
= localip6
;
100 /* vim:set ts=3 sw=3 tw=78 expandtab: */