avahi is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of the
License, or (at your option) any later version.
avahi is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of the
License, or (at your option) any later version.
avahi is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
Public License for more details.
avahi is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with avahi; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
You should have received a copy of the GNU Lesser General Public
License along with avahi; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+#ifndef IFLA_RTA
+#include <linux/if_addr.h>
+#define IFLA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg))))
+#endif
+
+#ifndef IFA_RTA
+#include <linux/if_addr.h>
+#define IFA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifaddrmsg))))
+#endif
+
memset(&req, 0, sizeof(req));
n = (struct nlmsghdr*) req;
n->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg));
n->nlmsg_type = type;
memset(&req, 0, sizeof(req));
n = (struct nlmsghdr*) req;
n->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg));
n->nlmsg_type = type;
static void netlink_callback(AvahiNetlink *nl, struct nlmsghdr *n, void* userdata) {
AvahiInterfaceMonitor *m = userdata;
static void netlink_callback(AvahiNetlink *nl, struct nlmsghdr *n, void* userdata) {
AvahiInterfaceMonitor *m = userdata;
+ /* Check whether there already is an AvahiHwInterface object
+ * for this link, so that we can update its data. Note that
+ * Netlink sends us an RTM_NEWLINK not only when a new
+ * interface appears, but when it changes, too */
+
+
+ /* No object found, so let's create a new
+ * one. avahi_hw_interface_new() will call
+ * avahi_interface_new() internally twice for IPv4 and
+ * IPv6, so there is no need for us to do that
+ * ourselves */
(!m->server->config.use_iff_running || (ifinfomsg->ifi_flags & IFF_RUNNING)) &&
!(ifinfomsg->ifi_flags & IFF_LOOPBACK) &&
(ifinfomsg->ifi_flags & IFF_MULTICAST) &&
(!m->server->config.use_iff_running || (ifinfomsg->ifi_flags & IFF_RUNNING)) &&
!(ifinfomsg->ifi_flags & IFF_LOOPBACK) &&
(ifinfomsg->ifi_flags & IFF_MULTICAST) &&
if (!(i = avahi_interface_monitor_get_interface(m, (AvahiIfIndex) ifaddrmsg->ifa_index, avahi_af_to_proto(ifaddrmsg->ifa_family))))
return;
if (!(i = avahi_interface_monitor_get_interface(m, (AvahiIfIndex) ifaddrmsg->ifa_index, avahi_af_to_proto(ifaddrmsg->ifa_family))))
return;
raddr.proto = avahi_af_to_proto(ifaddrmsg->ifa_family);
l = NLMSG_PAYLOAD(n, sizeof(struct ifaddrmsg));
raddr.proto = avahi_af_to_proto(ifaddrmsg->ifa_family);
l = NLMSG_PAYLOAD(n, sizeof(struct ifaddrmsg));
if ((raddr.proto == AVAHI_PROTO_INET6 && RTA_PAYLOAD(a) != 16) ||
(raddr.proto == AVAHI_PROTO_INET && RTA_PAYLOAD(a) != 4))
return;
if ((raddr.proto == AVAHI_PROTO_INET6 && RTA_PAYLOAD(a) != 16) ||
(raddr.proto == AVAHI_PROTO_INET && RTA_PAYLOAD(a) != 4))
return;
if (!(addr = avahi_interface_address_new(m, i, &raddr, ifaddrmsg->ifa_prefixlen)))
return; /* OOM */
if (!(addr = avahi_interface_address_new(m, i, &raddr, ifaddrmsg->ifa_prefixlen)))
return; /* OOM */
if (netlink_list_items(m->osdep.netlink, RTM_GETADDR, &m->osdep.query_addr_seq) < 0) {
avahi_log_warn("NETLINK: Failed to list addrs: %s", strerror(errno));
m->osdep.list = LIST_DONE;
} else
if (netlink_list_items(m->osdep.netlink, RTM_GETADDR, &m->osdep.query_addr_seq) < 0) {
avahi_log_warn("NETLINK: Failed to list addrs: %s", strerror(errno));
m->osdep.list = LIST_DONE;
} else
+
+ /* Only after this boolean variable has been set, Avahi
+ * will start to announce or browse on all interfaces. It
+ * is originaly set to 0, which means that relevancy
+ * checks and RR updates are disabled during the wild
+ * dumps. */
} else if (n->nlmsg_type == NLMSG_ERROR &&
(n->nlmsg_seq == m->osdep.query_link_seq || n->nlmsg_seq == m->osdep.query_addr_seq)) {
struct nlmsgerr *e = NLMSG_DATA (n);
} else if (n->nlmsg_type == NLMSG_ERROR &&
(n->nlmsg_seq == m->osdep.query_link_seq || n->nlmsg_seq == m->osdep.query_addr_seq)) {
struct nlmsgerr *e = NLMSG_DATA (n);
if (!(m->osdep.netlink = avahi_netlink_new(m->server->poll_api, RTMGRP_LINK|RTMGRP_IPV4_IFADDR|RTMGRP_IPV6_IFADDR, netlink_callback, m)))
goto fail;
if (!(m->osdep.netlink = avahi_netlink_new(m->server->poll_api, RTMGRP_LINK|RTMGRP_IPV4_IFADDR|RTMGRP_IPV6_IFADDR, netlink_callback, m)))
goto fail;
-
- while (m->osdep.list != LIST_DONE) {
- if (!avahi_netlink_work(m->osdep.netlink, 1))
+
+ /* Let's handle netlink events until we are done with wild
+ * dumping */
+
+ while (!m->list_complete)
+ if (!avahi_netlink_work(m->osdep.netlink, 1) == 0)