1 /* $Id: ifacewatcher.c,v 1.5 2012/05/21 08:55:10 nanard Exp $ */
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 */
10 #include <sys/types.h>
12 #include <sys/socket.h>
14 #include <net/route.h>
19 #define SA_LEN(sa) (sa)->sa_len
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
;
31 OpenAndConfInterfaceWatchSocket(void)
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. */
42 syslog(LOG_ERR
, "OpenAndConfInterfaceWatchSocket socket: %m");
48 ProcessInterfaceWatchNotify(int s
)
53 struct rt_msghdr
* rtm
;
54 struct if_msghdr
* ifm
;
55 struct ifa_msghdr
* ifam
;
57 struct if_announcemsghdr
* ifanm
;
61 unsigned int ext_if_name_index
= 0;
63 len
= recv(s
, buf
, sizeof(buf
), 0);
65 syslog(LOG_ERR
, "ProcessInterfaceWatchNotify recv: %m");
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
);
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
);
88 case RTM_IEEE80211
: /* IEEE80211 wireless event */
89 syslog(LOG_DEBUG
, " RTM_IEEE80211");
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
);
103 if(ifam
->ifam_index
== ext_if_name_index
) {
104 should_send_public_address_change_notif
= 1;
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;
114 syslog(LOG_DEBUG
, "unprocessed RTM message type=%d", rtm
->rtm_type
);