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
+
static int netlink_list_items(AvahiNetlink *nl, uint16_t type, unsigned *ret_seq) {
struct nlmsghdr *n;
struct rtgenmsg *gen;
uint8_t req[1024];
/* Issue a wild dump NETLINK request */
static int netlink_list_items(AvahiNetlink *nl, uint16_t type, unsigned *ret_seq) {
struct nlmsghdr *n;
struct rtgenmsg *gen;
uint8_t req[1024];
/* Issue a wild dump NETLINK request */
memset(&req, 0, sizeof(req));
n = (struct nlmsghdr*) req;
n->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg));
memset(&req, 0, sizeof(req));
n = (struct nlmsghdr*) req;
n->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg));
AvahiInterfaceMonitor *m = userdata;
/* This routine is called for every RTNETLINK response packet */
AvahiInterfaceMonitor *m = userdata;
/* This routine is called for every RTNETLINK response packet */
if (n->nlmsg_type == RTM_NEWLINK) {
/* A new interface appeared or an existing one has been modified */
if (n->nlmsg_type == RTM_NEWLINK) {
/* A new interface appeared or an existing one has been modified */
* interface appears, but when it changes, too */
if (!(hw = avahi_interface_monitor_get_hw_interface(m, ifinfomsg->ifi_index)))
* interface appears, but when it changes, too */
if (!(hw = avahi_interface_monitor_get_hw_interface(m, ifinfomsg->ifi_index)))
/* No object found, so let's create a new
* one. avahi_hw_interface_new() will call
* avahi_interface_new() internally twice for IPv4 and
/* No object found, so let's create a new
* one. avahi_hw_interface_new() will call
* avahi_interface_new() internally twice for IPv4 and
(!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) &&
/* Handle interface attributes */
l = NLMSG_PAYLOAD(n, sizeof(struct ifinfomsg));
/* Handle interface attributes */
l = NLMSG_PAYLOAD(n, sizeof(struct ifinfomsg));
/* Update any associated RRs of this interface. (i.e. the
* _workstation._tcp record containing the MAC address) */
avahi_hw_interface_update_rrs(hw, 0);
/* Update any associated RRs of this interface. (i.e. the
* _workstation._tcp record containing the MAC address) */
avahi_hw_interface_update_rrs(hw, 0);
} else if (n->nlmsg_type == RTM_NEWADDR || n->nlmsg_type == RTM_DELADDR) {
/* An address has been added, modified or removed */
} else if (n->nlmsg_type == RTM_NEWADDR || n->nlmsg_type == RTM_DELADDR) {
/* An address has been added, modified or removed */
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;
/* Update any associated RRs, like A or AAAA for our new/removed address */
avahi_interface_update_rrs(i, 0);
/* Update any associated RRs, like A or AAAA for our new/removed address */
avahi_interface_update_rrs(i, 0);
} else if (n->nlmsg_type == NLMSG_DONE) {
/* This wild dump request ended, so let's see what we do next */
} else if (n->nlmsg_type == NLMSG_DONE) {
/* This wild dump request ended, so let's see what we do next */
if (m->osdep.list == LIST_IFACE) {
/* Mmmm, interfaces have been wild dumped already, so
* let's go on with wild dumping the addresses */
if (m->osdep.list == LIST_IFACE) {
/* Mmmm, interfaces have been wild dumped already, so
* let's go on with wild dumping the addresses */
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;
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;
/* Tell the user that the wild dump is complete */
avahi_log_info("Network interface enumeration completed.");
}
/* Tell the user that the wild dump is complete */
avahi_log_info("Network interface enumeration completed.");
}
} 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);
/* Some kind of error happened. Let's just tell the user and
* ignore it otherwise */
} 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);
/* Some kind of error happened. Let's just tell the user and
* ignore it otherwise */