/* darkstat 3 * copyright (c) 2001-2007 Emil Mikulic. * * localip.c: determine local IP of our capture interface * * You may use, modify and redistribute this file under the terms of the * GNU General Public License version 2. (see COPYING.GPL) */ #include "darkstat.h" #include "conv.h" /* for strlcpy */ #include "decode.h" /* for ip_to_str */ #include "err.h" #include "localip.h" #ifdef HAVE_SYS_SOCKIO_H # include /* for SIOCGIFADDR, especially on Solaris */ #endif #include #include #include #include #include #include static const char *iface = NULL; in_addr_t localip = 0; static in_addr_t last_localip = 0; void localip_init(const char *interface) { iface = interface; localip_update(); } void localip_update(void) { int tmp = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); struct ifreq ifr; struct sockaddr sa; strlcpy(ifr.ifr_name, iface, IFNAMSIZ); ifr.ifr_addr.sa_family = AF_INET; if (ioctl(tmp, SIOCGIFADDR, &ifr) == -1) { if (errno == EADDRNOTAVAIL) { /* lost IP, e.g. ifconfig eth0 delete, don't die */ localip = 0; close(tmp); return; } else err(1, "can't get own IP address on interface \"%s\"", iface); } close(tmp); sa = ifr.ifr_addr; /* struct sockaddr { * sa_family_t sa_family; * address family, AF_xxx * char sa_data[14]; * 14 bytes of protocol address * * struct sockaddr_in { * sa_family_t sin_family; * Address family * unsigned short int sin_port; * Port number * struct in_addr sin_addr; * Internet address * * struct in_addr { * __u32 s_addr; */ localip = ((struct sockaddr_in*)&sa)->sin_addr.s_addr; if (last_localip != localip) { verbosef("local_ip update(%s) = %s", iface, ip_to_str(localip)); last_localip = localip; } } /* vim:set ts=3 sw=3 tw=78 expandtab: */