]> git.meshlink.io Git - catta/blobdiff - avahi-core/iface-linux.c
forgot to pull the publish_no_reverse change to the example.
[catta] / avahi-core / iface-linux.c
index c8ed9e05c6e913a58b7a9e9c30f4690b4c513a05..da497bc4dcbadb4816d5dc301acb25d3fd55e135 100644 (file)
@@ -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
@@ -50,12 +48,12 @@ static int netlink_list_items(AvahiNetlink *nl, uint16_t type, unsigned *ret_seq
     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);
@@ -69,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);
@@ -77,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;
@@ -93,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
@@ -136,10 +134,10 @@ static void netlink_callback(AvahiNetlink *nl, struct nlmsghdr *n, void* userdat
                     hw->mac_address_size = RTA_PAYLOAD(a);
                     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:
                     ;
             }
@@ -156,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 */
@@ -174,17 +172,17 @@ 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;
         size_t l;
-        AvahiAddress raddr;
-        int raddr_valid = 0;
+        AvahiAddress raddr, rlocal, *r;
+        int raddr_valid = 0, rlocal_valid = 0;
 
         /* We are only interested in IPv4 and IPv6 */
         if (ifaddrmsg->ifa_family != AF_INET && ifaddrmsg->ifa_family != AF_INET6)
@@ -197,7 +195,7 @@ static void netlink_callback(AvahiNetlink *nl, struct nlmsghdr *n, void* userdat
             return;
 
         /* Fill in address family for our new address */
-        raddr.proto = avahi_af_to_proto(ifaddrmsg->ifa_family);
+        rlocal.proto = raddr.proto = avahi_af_to_proto(ifaddrmsg->ifa_family);
 
         l = NLMSG_PAYLOAD(n, sizeof(struct ifaddrmsg));
         a = IFA_RTA(ifaddrmsg);
@@ -205,9 +203,26 @@ static void netlink_callback(AvahiNetlink *nl, struct nlmsghdr *n, void* userdat
         while (RTA_OK(a, l)) {
 
             switch(a->rta_type) {
+
                 case IFA_ADDRESS:
-                    /* Fill in address data */
-                    
+
+                    if ((rlocal.proto == AVAHI_PROTO_INET6 && RTA_PAYLOAD(a) != 16) ||
+                        (rlocal.proto == AVAHI_PROTO_INET && RTA_PAYLOAD(a) != 4))
+                        return;
+
+                    memcpy(rlocal.data.data, RTA_DATA(a), RTA_PAYLOAD(a));
+                    rlocal_valid = 1;
+
+                    break;
+
+                case IFA_LOCAL:
+
+                    /* Fill in local address data. Usually this is
+                     * preferable over IFA_ADDRESS if both are set,
+                     * since this refers to the local address of a PPP
+                     * link while IFA_ADDRESS refers to the other
+                     * end. */
+
                     if ((raddr.proto == AVAHI_PROTO_INET6 && RTA_PAYLOAD(a) != 16) ||
                         (raddr.proto == AVAHI_PROTO_INET && RTA_PAYLOAD(a) != 4))
                         return;
@@ -220,32 +235,37 @@ static void netlink_callback(AvahiNetlink *nl, struct nlmsghdr *n, void* userdat
                 default:
                     ;
             }
-            
+
             a = RTA_NEXT(a, l);
         }
 
         /* If there was no adress attached to this message, let's quit. */
-        if (!raddr_valid)
+        if (rlocal_valid)
+            r = &rlocal;
+        else if (raddr_valid)
+            r = &raddr;
+        else
             return;
 
         if (n->nlmsg_type == RTM_NEWADDR) {
             AvahiInterfaceAddress *addr;
 
             /* This address is new or has been modified, so let's get an object for it */
-            if (!(addr = avahi_interface_monitor_get_address(m, i, &raddr)))
+            if (!(addr = avahi_interface_monitor_get_address(m, i, r)))
 
                 /* Mmm, no object existing yet, so let's create a new one */
-                if (!(addr = avahi_interface_address_new(m, i, &raddr, ifaddrmsg->ifa_prefixlen)))
+                if (!(addr = avahi_interface_address_new(m, i, r, ifaddrmsg->ifa_prefixlen)))
                     return; /* OOM */
 
             /* 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);
 
             /* Try to get a reference to our AvahiInterfaceAddress object for this address */
-            if (!(addr = avahi_interface_monitor_get_address(m, i, &raddr)))
+            if (!(addr = avahi_interface_monitor_get_address(m, i, r)))
                 return;
 
             /* And free it */
@@ -260,16 +280,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;
@@ -300,14 +320,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));
     }
@@ -317,7 +337,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;
 
@@ -361,7 +381,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;