1: /* $Id: ifacewatcher.c,v 1.1.1.2 2013/07/22 00:32:35 misho Exp $ */
2: /* Project MiniUPnP
3: * web : http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
4: * (c) 2011 Thomas BERNARD
5: * This software is subject to the conditions detailed
6: * in the LICENCE file provided within the distribution */
7:
8: #include "../config.h"
9:
10: #include <sys/types.h>
11: #include <sys/time.h>
12: #include <sys/socket.h>
13: #include <net/if.h>
14: #include <net/route.h>
15: #include <syslog.h>
16: #include <signal.h>
17:
18: #if !defined(SA_LEN)
19: #define SA_LEN(sa) (sa)->sa_len
20: #endif
21:
22: #define SALIGN (sizeof(long) - 1)
23: #define SA_RLEN(sa) ((sa)->sa_len ? (((sa)->sa_len + SALIGN) & ~SALIGN) : (SALIGN + 1))
24:
25: #include "../upnputils.h"
26: #include "../upnpglobalvars.h"
27:
28: extern volatile sig_atomic_t should_send_public_address_change_notif;
29:
30: int
31: OpenAndConfInterfaceWatchSocket(void)
32: {
33: int s;
34:
35: /*s = socket(PF_ROUTE, SOCK_RAW, AF_INET);*/
36: s = socket(PF_ROUTE, SOCK_RAW, AF_UNSPEC);
37: /* The family parameter may be AF_UNSPEC which will provide routing informa-
38: * tion for all address families, or can be restricted to a specific address
39: * family by specifying which one is desired. There can be more than one
40: * routing socket open per system. */
41: if(s < 0) {
42: syslog(LOG_ERR, "OpenAndConfInterfaceWatchSocket socket: %m");
43: }
44: return s;
45: }
46:
47: void
48: ProcessInterfaceWatchNotify(int s)
49: {
50: char buf[4096];
51: ssize_t len;
52: char tmp[64];
53: struct rt_msghdr * rtm;
54: struct if_msghdr * ifm;
55: struct ifa_msghdr * ifam;
56: #ifdef RTM_IFANNOUNCE
57: struct if_announcemsghdr * ifanm;
58: #endif
59: char * p;
60: struct sockaddr * sa;
61: unsigned int ext_if_name_index = 0;
62:
63: len = recv(s, buf, sizeof(buf), 0);
64: if(len < 0) {
65: syslog(LOG_ERR, "ProcessInterfaceWatchNotify recv: %m");
66: return;
67: }
68: if(ext_if_name) {
69: ext_if_name_index = if_nametoindex(ext_if_name);
70: }
71: rtm = (struct rt_msghdr *)buf;
72: syslog(LOG_DEBUG, "%u rt_msg : msglen=%d version=%d type=%d", (unsigned)len,
73: rtm->rtm_msglen, rtm->rtm_version, rtm->rtm_type);
74: switch(rtm->rtm_type) {
75: case RTM_IFINFO: /* iface going up/down etc. */
76: ifm = (struct if_msghdr *)buf;
77: syslog(LOG_DEBUG, " RTM_IFINFO: addrs=%x flags=%x index=%hu",
78: ifm->ifm_addrs, ifm->ifm_flags, ifm->ifm_index);
79: break;
80: #ifdef RTM_IFANNOUNCE
81: case RTM_IFANNOUNCE: /* iface arrival/departure */
82: ifanm = (struct if_announcemsghdr *)buf;
83: syslog(LOG_DEBUG, " RTM_IFANNOUNCE: index=%hu what=%hu ifname=%s",
84: ifanm->ifan_index, ifanm->ifan_what, ifanm->ifan_name);
85: break;
86: #endif
87: #ifdef RTM_IEEE80211
88: case RTM_IEEE80211: /* IEEE80211 wireless event */
89: syslog(LOG_DEBUG, " RTM_IEEE80211");
90: break;
91: #endif
92: case RTM_NEWADDR: /* address being added to iface */
93: ifam = (struct ifa_msghdr *)buf;
94: syslog(LOG_DEBUG, " RTM_NEWADDR: addrs=%x flags=%x index=%hu",
95: ifam->ifam_addrs, ifam->ifam_flags, ifam->ifam_index);
96: p = buf + sizeof(struct ifa_msghdr);
97: while(p < buf + len) {
98: sa = (struct sockaddr *)p;
99: sockaddr_to_string(sa, tmp, sizeof(tmp));
100: syslog(LOG_DEBUG, " %s", tmp);
101: p += SA_RLEN(sa);
102: }
103: if(ifam->ifam_index == ext_if_name_index) {
104: should_send_public_address_change_notif = 1;
105: }
106: break;
107: case RTM_DELADDR: /* address being removed from iface */
108: ifam = (struct ifa_msghdr *)buf;
109: if(ifam->ifam_index == ext_if_name_index) {
110: should_send_public_address_change_notif = 1;
111: }
112: break;
113: default:
114: syslog(LOG_DEBUG, "unprocessed RTM message type=%d", rtm->rtm_type);
115: }
116: }
117:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>