Miniupnpd vet 1.8 (20130207)
[tomato.git] / release / src / router / miniupnpd / bsd / ifacewatcher.c
blob67d64f47a5c9ded5cc8ebeeb7166d941c19f96e1
1 /* $Id: ifacewatcher.c,v 1.5 2012/05/21 08:55:10 nanard 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 */
8 #include "../config.h"
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>
18 #if !defined(SA_LEN)
19 #define SA_LEN(sa) (sa)->sa_len
20 #endif
22 #define SALIGN (sizeof(long) - 1)
23 #define SA_RLEN(sa) ((sa)->sa_len ? (((sa)->sa_len + SALIGN) & ~SALIGN) : (SALIGN + 1))
25 #include "../upnputils.h"
26 #include "../upnpglobalvars.h"
28 extern volatile sig_atomic_t should_send_public_address_change_notif;
30 int
31 OpenAndConfInterfaceWatchSocket(void)
33 int s;
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");
44 return s;
47 void
48 ProcessInterfaceWatchNotify(int s)
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;
63 len = recv(s, buf, sizeof(buf), 0);
64 if(len < 0) {
65 syslog(LOG_ERR, "ProcessInterfaceWatchNotify recv: %m");
66 return;
68 if(ext_if_name) {
69 ext_if_name_index = if_nametoindex(ext_if_name);
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);
103 if(ifam->ifam_index == ext_if_name_index) {
104 should_send_public_address_change_notif = 1;
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;
112 break;
113 default:
114 syslog(LOG_DEBUG, "unprocessed RTM message type=%d", rtm->rtm_type);