96d5b8714ca883e16e4118a3dd43c37dbbf678da
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)
11 #include "conv.h" /* for strlcpy */
12 #include "decode.h" /* for ip_to_str, ip6_to_str */
22 static const char *iface
= NULL
;
24 in_addr_t localip
= 0;
25 static in_addr_t last_localip
= 0;
27 struct in6_addr localip6
;
28 static struct in6_addr last_localip6
;
31 localip_init(const char *interface
)
40 struct ifaddrs
*ifas
, *ifa
;
47 /* reading from capfile */
49 memset(&localip6
, '\0', sizeof(localip6
));
53 if (getifaddrs(&ifas
) < 0)
54 err(1, "can't get own IP address on interface \"%s\"", iface
);
56 for (ifa
= ifas
; ifa
; ifa
= ifa
->ifa_next
) {
57 if (flags
== (HAS_IPV4
| HAS_IPV6
))
58 break; /* Task is already complete. */
60 if (strncmp(ifa
->ifa_name
, iface
, IFNAMSIZ
))
61 continue; /* Wrong interface. */
63 /* The first IPv4 name is always functional. */
64 if ( (ifa
->ifa_addr
->sa_family
== AF_INET
)
65 && ! (flags
& HAS_IPV4
) ) {
66 /* Good IPv4 address. */
67 localip
= ((struct sockaddr_in
*) ifa
->ifa_addr
)->sin_addr
.s_addr
;
72 /* IPv6 needs some obvious exceptions. */
73 if( ifa
->ifa_addr
->sa_family
== AF_INET6
) {
74 struct sockaddr_in6
*sa6
= (struct sockaddr_in6
*) ifa
->ifa_addr
;
76 if( IN6_IS_ADDR_LINKLOCAL(&(sa6
->sin6_addr
.s6_addr
))
77 || IN6_IS_ADDR_SITELOCAL(&(sa6
->sin6_addr
.s6_addr
)) )
80 /* Only standard IPv6 can reach this point. */
81 memcpy(&localip6
, &sa6
->sin6_addr
, sizeof(localip6
));
88 /* Repport an error if IPv4 address could not be found. */
89 if ( !(flags
& HAS_IPV4
) )
90 err(1, "can't get own IPv4 address on interface \"%s\"", iface
);
93 * sa_family_t sa_family; * address family, AF_xxx
94 * char sa_data[14]; * 14 bytes of protocol address
96 * struct sockaddr_in {
97 * sa_family_t sin_family; * Address family
98 * unsigned short int sin_port; * Port number
99 * struct in_addr sin_addr; * Internet address
105 if (last_localip
!= localip
) {
106 verbosef("local_ip update(%s) = %s", iface
, ip_to_str(localip
));
107 last_localip
= localip
;
109 if (memcmp(&last_localip6
, &localip6
, sizeof(localip6
))) {
110 verbosef("local_ip6 update(%s) = %s", iface
, ip6_to_str(&localip6
));
111 memcpy(&last_localip6
, &localip6
, sizeof(localip6
));
115 /* vim:set ts=3 sw=3 tw=78 expandtab: */