3e6fd38e353a9566a7ca40a955994fb7eaaa72ff
[darkstat] / localip.c
1 /* darkstat 3
2 * copyright (c) 2001-2008 Emil Mikulic.
3 *
4 * localip.c: determine local IP of our capture interface
5 *
6 * You may use, modify and redistribute this file under the terms of the
7 * GNU General Public License version 2. (see COPYING.GPL)
8 */
9
10 #include "darkstat.h"
11 #include "conv.h" /* for strlcpy */
12 #include "decode.h" /* for ip_to_str */
13 #include "err.h"
14 #include "localip.h"
15
16 #ifdef HAVE_SYS_SOCKIO_H
17 # include <sys/sockio.h> /* for SIOCGIFADDR, especially on Solaris */
18 #endif
19 #include <sys/socket.h>
20 #include <sys/ioctl.h>
21 #include <net/if.h>
22 #include <errno.h>
23 #include <string.h>
24 #include <unistd.h>
25
26 static const char *iface = NULL;
27 in_addr_t localip = 0;
28 static in_addr_t last_localip = 0;
29
30 void
31 localip_init(const char *interface)
32 {
33 iface = interface;
34 localip_update();
35 }
36
37 void
38 localip_update(void)
39 {
40 int tmp = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
41 struct ifreq ifr;
42 struct sockaddr sa;
43
44 if (iface == NULL) {
45 /* reading from capfile */
46 localip = 0;
47 return;
48 }
49
50 strlcpy(ifr.ifr_name, iface, IFNAMSIZ);
51 ifr.ifr_addr.sa_family = AF_INET;
52 if (ioctl(tmp, SIOCGIFADDR, &ifr) == -1) {
53 if (errno == EADDRNOTAVAIL) {
54 /* lost IP, e.g. ifconfig eth0 delete, don't die */
55 localip = 0;
56 close(tmp);
57 return;
58 } else
59 err(1, "can't get own IP address on interface \"%s\"", iface);
60 }
61 close(tmp);
62 sa = ifr.ifr_addr;
63
64 /* struct sockaddr {
65 * sa_family_t sa_family; * address family, AF_xxx
66 * char sa_data[14]; * 14 bytes of protocol address
67 *
68 * struct sockaddr_in {
69 * sa_family_t sin_family; * Address family
70 * unsigned short int sin_port; * Port number
71 * struct in_addr sin_addr; * Internet address
72 *
73 * struct in_addr {
74 * __u32 s_addr;
75 */
76
77 localip = ((struct sockaddr_in*)&sa)->sin_addr.s_addr;
78 if (last_localip != localip) {
79 verbosef("local_ip update(%s) = %s", iface, ip_to_str(localip));
80 last_localip = localip;
81 }
82 }
83
84 /* vim:set ts=3 sw=3 tw=78 expandtab: */