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/types.h> /* OpenBSD needs this */
17 #include <sys/socket.h>
24 static const char *iface
= NULL
;
25 struct addr localip4
, localip6
;
26 static struct addr last_localip4
, last_localip6
;
29 localip_init(const char *interface
)
38 struct ifaddrs
*ifas
, *ifa
;
39 int got_v4
= 0, got_v6
= 0;
41 localip4
.family
= IPv4
;
42 localip6
.family
= IPv6
;
45 /* reading from capfile */
47 memset(&(localip6
.ip
.v6
), 0, sizeof(localip6
.ip
.v6
));
51 if (getifaddrs(&ifas
) < 0)
52 err(1, "can't get own IP address on interface \"%s\"", iface
);
54 for (ifa
= ifas
; ifa
; ifa
= ifa
->ifa_next
) {
56 break; /* Task is already complete. */
58 if (strncmp(ifa
->ifa_name
, iface
, IFNAMSIZ
))
59 continue; /* Wrong interface. */
61 /* The first IPv4 name is always functional. */
62 if ((ifa
->ifa_addr
->sa_family
== AF_INET
) && !got_v4
)
64 /* Good IPv4 address. */
66 ((struct sockaddr_in
*)ifa
->ifa_addr
)->sin_addr
.s_addr
;
71 /* IPv6 needs some obvious exceptions. */
72 if ( ifa
->ifa_addr
->sa_family
== AF_INET6
) {
73 struct sockaddr_in6
*sa6
= (struct sockaddr_in6
*) ifa
->ifa_addr
;
75 if ( IN6_IS_ADDR_LINKLOCAL(&(sa6
->sin6_addr
))
76 || IN6_IS_ADDR_SITELOCAL(&(sa6
->sin6_addr
)) )
79 /* Only standard IPv6 can reach this point. */
80 memcpy(&(localip6
.ip
.v6
), &sa6
->sin6_addr
, sizeof(localip6
.ip
.v6
));
87 /* Report an error if IPv4 address could not be found. */
89 err(1, "can't get own IPv4 address on interface \"%s\"", iface
);
91 if (!addr_equal(&last_localip4
, &localip4
)) {
92 verbosef("localip4 update(%s) = %s", iface
, addr_to_str(&localip4
));
93 last_localip4
= localip4
;
95 if (!addr_equal(&last_localip6
, &localip6
)) {
96 verbosef("localip6 update(%s) = %s", iface
, addr_to_str(&localip6
));
97 last_localip6
= localip6
;
101 /* vim:set ts=3 sw=3 tw=78 expandtab: */