1 /* $Id: ifacewatcher.c,v 1.3 2011/06/04 16:19:51 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>
18 #define SA_LEN(sa) (sa)->sa_len
21 #define SALIGN (sizeof(long) - 1)
22 #define SA_RLEN(sa) ((sa)->sa_len ? (((sa)->sa_len + SALIGN) & ~SALIGN) : (SALIGN + 1))
24 #include "../upnputils.h"
25 #include "../upnpglobalvars.h"
27 extern volatile int should_send_public_address_change_notif
;
30 OpenAndConfInterfaceWatchSocket(void)
34 /*s = socket(PF_ROUTE, SOCK_RAW, AF_INET);*/
35 s
= socket(PF_ROUTE
, SOCK_RAW
, AF_UNSPEC
);
36 /* The family parameter may be AF_UNSPEC which will provide routing informa-
37 * tion for all address families, or can be restricted to a specific address
38 * family by specifying which one is desired. There can be more than one
39 * routing socket open per system. */
41 syslog(LOG_ERR
, "OpenAndConfInterfaceWatchSocket socket: %m");
47 ProcessInterfaceWatchNotify(int s
)
52 struct rt_msghdr
* rtm
;
53 struct if_msghdr
* ifm
;
54 struct ifa_msghdr
* ifam
;
56 struct if_announcemsghdr
* ifanm
;
60 unsigned int ext_if_name_index
= 0;
62 len
= recv(s
, buf
, sizeof(buf
), 0);
64 syslog(LOG_ERR
, "ProcessInterfaceWatchNotify recv: %m");
68 ext_if_name_index
= if_nametoindex(ext_if_name
);
70 rtm
= (struct rt_msghdr
*)buf
;
71 syslog(LOG_DEBUG
, "%u rt_msg : msglen=%d version=%d type=%d", (unsigned)len
,
72 rtm
->rtm_msglen
, rtm
->rtm_version
, rtm
->rtm_type
);
73 switch(rtm
->rtm_type
) {
74 case RTM_IFINFO
: /* iface going up/down etc. */
75 ifm
= (struct if_msghdr
*)buf
;
76 syslog(LOG_DEBUG
, " RTM_IFINFO: addrs=%x flags=%x index=%hu",
77 ifm
->ifm_addrs
, ifm
->ifm_flags
, ifm
->ifm_index
);
80 case RTM_IFANNOUNCE
: /* iface arrival/departure */
81 ifanm
= (struct if_announcemsghdr
*)buf
;
82 syslog(LOG_DEBUG
, " RTM_IFANNOUNCE: index=%hu what=%hu ifname=%s",
83 ifanm
->ifan_index
, ifanm
->ifan_what
, ifanm
->ifan_name
);
87 case RTM_IEEE80211
: /* IEEE80211 wireless event */
88 syslog(LOG_DEBUG
, " RTM_IEEE80211");
91 case RTM_NEWADDR
: /* address being added to iface */
92 ifam
= (struct ifa_msghdr
*)buf
;
93 syslog(LOG_DEBUG
, " RTM_NEWADDR: addrs=%x flags=%x index=%hu",
94 ifam
->ifam_addrs
, ifam
->ifam_flags
, ifam
->ifam_index
);
95 p
= buf
+ sizeof(struct ifa_msghdr
);
96 while(p
< buf
+ len
) {
97 sa
= (struct sockaddr
*)p
;
98 sockaddr_to_string(sa
, tmp
, sizeof(tmp
));
99 syslog(LOG_DEBUG
, " %s", tmp
);
102 if(ifam
->ifam_index
== ext_if_name_index
) {
103 should_send_public_address_change_notif
= 1;
106 case RTM_DELADDR
: /* address being removed from iface */
107 ifam
= (struct ifa_msghdr
*)buf
;
108 if(ifam
->ifam_index
== ext_if_name_index
) {
109 should_send_public_address_change_notif
= 1;
113 syslog(LOG_DEBUG
, "unprocessed RTM message type=%d", rtm
->rtm_type
);