X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=avahi-core%2Fiface-linux.c;h=4d12f73504193d00332f56debdcdd8581f00bab7;hb=65cb5c100eb1e5891f145be0b89aaa3c2d2e4317;hp=4fc4addfd49cf6e37f4e48314a7f891ae6765ee3;hpb=71cb9656e633111a127779af5923780620792e0b;p=catta diff --git a/avahi-core/iface-linux.c b/avahi-core/iface-linux.c index 4fc4add..4d12f73 100644 --- a/avahi-core/iface-linux.c +++ b/avahi-core/iface-linux.c @@ -1,18 +1,16 @@ -/* $Id$ */ - /*** This file is part of avahi. - + 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. - + 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 @@ -34,18 +32,28 @@ #include "iface.h" #include "iface-linux.h" +#ifndef IFLA_RTA +#include +#define IFLA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg)))) +#endif + +#ifndef IFA_RTA +#include +#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 */ - + memset(&req, 0, sizeof(req)); n = (struct nlmsghdr*) req; n->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)); n->nlmsg_type = type; - n->nlmsg_flags = NLM_F_ROOT|NLM_F_REQUEST; + n->nlmsg_flags = NLM_F_REQUEST|NLM_F_DUMP; n->nlmsg_pid = 0; gen = NLMSG_DATA(n); @@ -59,7 +67,7 @@ static void netlink_callback(AvahiNetlink *nl, struct nlmsghdr *n, void* userdat AvahiInterfaceMonitor *m = userdata; /* This routine is called for every RTNETLINK response packet */ - + assert(m); assert(n); assert(m->osdep.netlink == nl); @@ -67,7 +75,7 @@ static void netlink_callback(AvahiNetlink *nl, struct nlmsghdr *n, void* userdat if (n->nlmsg_type == RTM_NEWLINK) { /* A new interface appeared or an existing one has been modified */ - + struct ifinfomsg *ifinfomsg = NLMSG_DATA(n); AvahiHwInterface *hw; struct rtattr *a = NULL; @@ -83,7 +91,7 @@ static void netlink_callback(AvahiNetlink *nl, struct nlmsghdr *n, void* userdat * 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 @@ -98,7 +106,7 @@ static void netlink_callback(AvahiNetlink *nl, struct nlmsghdr *n, void* userdat (!m->server->config.use_iff_running || (ifinfomsg->ifi_flags & IFF_RUNNING)) && !(ifinfomsg->ifi_flags & IFF_LOOPBACK) && (ifinfomsg->ifi_flags & IFF_MULTICAST) && - !(ifinfomsg->ifi_flags & IFF_POINTOPOINT); + (m->server->config.allow_point_to_point || !(ifinfomsg->ifi_flags & IFF_POINTOPOINT)); /* Handle interface attributes */ l = NLMSG_PAYLOAD(n, sizeof(struct ifinfomsg)); @@ -124,12 +132,12 @@ static void netlink_callback(AvahiNetlink *nl, struct nlmsghdr *n, void* userdat /* Fill in hardware (MAC) address */ hw->mac_address_size = RTA_PAYLOAD(a); - if (hw->mac_address_size > AVAHI_MAX_MAC_ADDRESS) - hw->mac_address_size = AVAHI_MAX_MAC_ADDRESS; - + if (hw->mac_address_size > AVAHI_MAC_ADDRESS_MAX) + hw->mac_address_size = AVAHI_MAC_ADDRESS_MAX; + memcpy(hw->mac_address, RTA_DATA(a), hw->mac_address_size); break; - + default: ; } @@ -146,7 +154,7 @@ static void netlink_callback(AvahiNetlink *nl, struct nlmsghdr *n, void* userdat /* 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_DELLINK) { /* An interface has been removed */ @@ -164,11 +172,11 @@ static void netlink_callback(AvahiNetlink *nl, struct nlmsghdr *n, void* userdat /* Free our object */ avahi_hw_interface_free(hw, 0); - + } else if (n->nlmsg_type == RTM_NEWADDR || n->nlmsg_type == RTM_DELADDR) { /* An address has been added, modified or removed */ - + struct ifaddrmsg *ifaddrmsg = NLMSG_DATA(n); AvahiInterface *i; struct rtattr *a = NULL; @@ -197,7 +205,7 @@ static void netlink_callback(AvahiNetlink *nl, struct nlmsghdr *n, void* userdat switch(a->rta_type) { case IFA_ADDRESS: /* Fill in address data */ - + if ((raddr.proto == AVAHI_PROTO_INET6 && RTA_PAYLOAD(a) != 16) || (raddr.proto == AVAHI_PROTO_INET && RTA_PAYLOAD(a) != 4)) return; @@ -210,7 +218,7 @@ static void netlink_callback(AvahiNetlink *nl, struct nlmsghdr *n, void* userdat default: ; } - + a = RTA_NEXT(a, l); } @@ -230,6 +238,7 @@ static void netlink_callback(AvahiNetlink *nl, struct nlmsghdr *n, void* userdat /* Update the scope field for the address */ addr->global_scope = ifaddrmsg->ifa_scope == RT_SCOPE_UNIVERSE || ifaddrmsg->ifa_scope == RT_SCOPE_SITE; + addr->deprecated = !!(ifaddrmsg->ifa_flags & IFA_F_DEPRECATED); } else { AvahiInterfaceAddress *addr; assert(n->nlmsg_type == RTM_DELADDR); @@ -250,16 +259,16 @@ static void netlink_callback(AvahiNetlink *nl, struct nlmsghdr *n, void* userdat /* 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 */ - + 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; @@ -290,14 +299,14 @@ static void netlink_callback(AvahiNetlink *nl, struct nlmsghdr *n, void* userdat /* 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 */ - + if (e->error) avahi_log_warn("NETLINK: Failed to browse: %s", strerror(-e->error)); } @@ -307,7 +316,7 @@ int avahi_interface_monitor_init_osdep(AvahiInterfaceMonitor *m) { assert(m); /* Initialize our own data */ - + m->osdep.netlink = NULL; m->osdep.query_addr_seq = m->osdep.query_link_seq = 0; @@ -351,7 +360,7 @@ void avahi_interface_monitor_sync(AvahiInterfaceMonitor *m) { /* 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) break;