90
111
for(nlhdr = (struct nlmsghdr *)buffer;
91
112
NLMSG_OK(nlhdr, len);
92
113
nlhdr = NLMSG_NEXT(nlhdr, len)) {
93
syslog(LOG_DEBUG, "nlmsg_type=%d", nlhdr->nlmsg_type);
116
char ifname[IFNAMSIZ];
94
119
if(nlhdr->nlmsg_type == NLMSG_DONE)
96
if(nlhdr->nlmsg_type == RTM_NEWADDR) {
97
ifa = (struct ifaddrmsg *)NLMSG_DATA(nlhdr);
98
syslog(LOG_DEBUG, "ProcessInterfaceWatchNotify RTM_NEWADDR index=%d", ifa->ifa_index);
99
for(i = 0; i < n_if_addr; i++) {
100
if(ifa->ifa_index == if_nametoindex(if_addr[i])) {
101
AddDropMulticastMembership(s_ssdp, if_addr[i], 0, 0);
105
} else if(nlhdr->nlmsg_type == RTM_DELADDR) {
106
ifa = (struct ifaddrmsg *)NLMSG_DATA(nlhdr);
107
syslog(LOG_DEBUG, "ProcessInterfaceWatchNotify RTM_DELADDR index=%d", ifa->ifa_index);
108
for(i = 0; i < n_if_addr; i++) {
109
if(ifa->ifa_index == if_nametoindex(if_addr[i])) {
110
AddDropMulticastMembership(s_ssdp, if_addr[i], 0, 1);
121
switch(nlhdr->nlmsg_type) {
122
/* case RTM_NEWLINK: */
123
/* case RTM_DELLINK: */
127
/* http://linux-hacks.blogspot.fr/2009/01/sample-code-to-learn-netlink.html */
128
ifa = (struct ifaddrmsg *)NLMSG_DATA(nlhdr);
129
rta = (struct rtattr *)IFA_RTA(ifa);
130
ifa_len = IFA_PAYLOAD(nlhdr);
131
syslog(LOG_DEBUG, "%s %s index=%d fam=%d prefixlen=%d flags=%d scope=%d",
132
"ProcessInterfaceWatchNotify", is_del ? "RTM_DELADDR" : "RTM_NEWADDR",
133
ifa->ifa_index, ifa->ifa_family, ifa->ifa_prefixlen,
134
ifa->ifa_flags, ifa->ifa_scope);
135
for(;RTA_OK(rta, ifa_len); rta = RTA_NEXT(rta, ifa_len)) {
137
/*rta_type : IFA_ADDRESS, IFA_LOCAL, etc. */
139
memset(tmp, 0, sizeof(tmp));
140
switch(rta->rta_type) {
145
inet_ntop(ifa->ifa_family, RTA_DATA(rta), tmp, sizeof(tmp));
146
if(rta->rta_type == IFA_ADDRESS)
147
strncpy(address, tmp, sizeof(address));
150
strncpy(tmp, RTA_DATA(rta), sizeof(tmp));
151
strncpy(ifname, tmp, sizeof(ifname));
155
struct ifa_cacheinfo *cache_info;
156
cache_info = RTA_DATA(rta);
157
snprintf(tmp, sizeof(tmp), "valid=%u prefered=%u",
158
cache_info->ifa_valid, cache_info->ifa_prefered);
162
strncpy(tmp, "*unknown*", sizeof(tmp));
164
syslog(LOG_DEBUG, " rta_len=%d rta_type=%d '%s'", rta->rta_len, rta->rta_type, tmp);
166
syslog(LOG_INFO, "%s: %s/%d %s",
167
is_del ? "RTM_DELADDR" : "RTM_NEWADDR",
168
address, ifa->ifa_prefixlen, ifname);
169
for(i = 0; i < n_if_addr; i++) {
170
if((0 == strcmp(address, if_addr[i])) ||
171
(0 == strcmp(ifname, if_addr[i])) ||
172
(ifa->ifa_index == if_nametoindex(if_addr[i]))) {
173
if(ifa->ifa_family == AF_INET && address[0] != '\0')
174
AddDropMulticastMembership(s_ssdp, address, 0, is_del);
175
else if(ifa->ifa_family == AF_INET6)
176
AddDropMulticastMembership(s_ssdp6, if_addr[i], 1, is_del);
182
syslog(LOG_DEBUG, "unknown nlmsg_type=%d", nlhdr->nlmsg_type);
116
185
#else /* __linux__ */
117
186
struct rt_msghdr * rtm;
118
187
struct ifa_msghdr * ifam;
191
struct sockaddr * sa;
194
char ifname[IFNAMSIZ];
195
int family = AF_UNSPEC;
120
201
len = recv(s, buffer, sizeof(buffer), 0);
122
syslog(LOG_ERR, "ProcessInterfaceWatchNotify recv: %m");
203
syslog(LOG_ERR, "%s recv: %m", "ProcessInterfaceWatchNotify");
125
206
rtm = (struct rt_msghdr *)buffer;
126
207
switch(rtm->rtm_type) {
127
210
case RTM_NEWADDR:
128
211
ifam = (struct ifa_msghdr *)buffer;
129
syslog(LOG_DEBUG, "ProcessInterfaceWatchNotify RTM_NEWADDR index=%d", ifam->ifam_index);
130
for(i = 0; i < n_if_addr; i++) {
131
if(ifam->ifam_index == if_nametoindex(if_addr[i])) {
132
AddDropMulticastMembership(s_ssdp, if_addr[i], 0, 0);
212
syslog(LOG_DEBUG, "%s %s len=%d/%hu index=%hu addrs=%x flags=%x",
213
"ProcessInterfaceWatchNotify", is_del?"RTM_DELADDR":"RTM_NEWADDR",
214
(int)len, ifam->ifam_msglen,
215
ifam->ifam_index, ifam->ifam_addrs, ifam->ifam_flags);
216
p = buffer + sizeof(struct ifa_msghdr);
218
while(p < buffer + len) {
219
sa = (struct sockaddr *)p;
220
while(!(addr & ifam->ifam_addrs) && (addr <= ifam->ifam_addrs))
222
sockaddr_to_string(sa, tmp, sizeof(tmp));
223
syslog(LOG_DEBUG, " %s", tmp);
229
if(sa->sa_family == AF_INET
230
#if defined(__OpenBSD__)
231
|| (sa->sa_family == 0 &&
232
sa->sa_len <= sizeof(struct sockaddr_in))
235
uint32_t sin_addr = ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr);
236
while((prefixlen < 32) &&
237
((sin_addr & (1 << (31 - prefixlen))) != 0))
239
} else if(sa->sa_family == AF_INET6
240
#if defined(__OpenBSD__)
241
|| (sa->sa_family == 0 &&
242
sa->sa_len == sizeof(struct sockaddr_in6))
246
uint8_t * q = ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr;
247
while((*q == 0xff) && (i < 16)) {
254
((*q & (1 << (7 - i))) != 0))
264
if(sa->sa_family == AF_LINK) {
265
struct sockaddr_dl * sdl = (struct sockaddr_dl *)sa;
266
memset(ifname, 0, sizeof(ifname));
267
memcpy(ifname, sdl->sdl_data, sdl->sdl_nlen);
272
family = sa->sa_family;
273
if(sa->sa_family == AF_INET) {
274
inet_ntop(sa->sa_family,
275
&((struct sockaddr_in *)sa)->sin_addr,
276
address, sizeof(address));
277
} else if(sa->sa_family == AF_INET6) {
278
inet_ntop(sa->sa_family,
279
&((struct sockaddr_in6 *)sa)->sin6_addr,
280
address, sizeof(address));
289
syslog(LOG_DEBUG, " %d.%d.%d.%d %02x%02x%02x%02x",
290
(uint8_t)p[0], (uint8_t)p[1], (uint8_t)p[2], (uint8_t)p[3],
291
(uint8_t)p[0], (uint8_t)p[1], (uint8_t)p[2], (uint8_t)p[3]);
292
syslog(LOG_DEBUG, " %d.%d.%d.%d %02x%02x%02x%02x",
293
(uint8_t)p[4], (uint8_t)p[5], (uint8_t)p[6], (uint8_t)p[7],
294
(uint8_t)p[4], (uint8_t)p[5], (uint8_t)p[6], (uint8_t)p[7]);
138
ifam = (struct ifa_msghdr *)buffer;
139
syslog(LOG_DEBUG, "ProcessInterfaceWatchNotify RTM_DELADDR index=%d", ifam->ifam_index);
299
syslog(LOG_INFO, "%s: %s/%d %s",
300
is_del ? "RTM_DELADDR" : "RTM_NEWADDR",
301
address, prefixlen, ifname);
140
302
for(i = 0; i < n_if_addr; i++) {
141
if(ifam->ifam_index == if_nametoindex(if_addr[i])) {
142
/* I dont think it is useful */
143
/*AddDropMulticastMembership(s_ssdp, if_addr[i], 0, 1);*/
303
if(0 == strcmp(address, if_addr[i]) ||
304
0 == strcmp(ifname, if_addr[i]) ||
305
ifam->ifam_index == if_nametoindex(if_addr[i])) {
306
if(family == AF_INET && address[0] != '\0')
307
AddDropMulticastMembership(s_ssdp, address, 0, is_del);
308
else if(family == AF_INET6)
309
AddDropMulticastMembership(s_ssdp6, if_addr[i], 1, is_del);
149
syslog(LOG_DEBUG, "rtm->rtm_type=%d", rtm->rtm_type);
315
syslog(LOG_DEBUG, "Unknown RTM message : rtm->rtm_type=%d len=%d",
316
rtm->rtm_type, (int)len);