X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=avahi-core%2Fiface-pfroute.c;h=9a2e953398e6d03dacaae7bd515937dbd44f9063;hb=e80dfc163e06f9bd9300d096f384bf418ac3062f;hp=f96bfc2924f827322d1ac090586fc6e4fb441c03;hpb=bd68f1a8609d726a46e4487d016427efbc815da1;p=catta diff --git a/avahi-core/iface-pfroute.c b/avahi-core/iface-pfroute.c index f96bfc2..9a2e953 100644 --- a/avahi-core/iface-pfroute.c +++ b/avahi-core/iface-pfroute.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 @@ -48,8 +46,8 @@ #include "iface-pfroute.h" #include "util.h" -static int bitcount (unsigned int n) -{ +static int bitcount (unsigned int n) +{ int count=0 ; while (n) { @@ -64,39 +62,39 @@ static void rtm_info(struct rt_msghdr *rtm, AvahiInterfaceMonitor *m) AvahiHwInterface *hw; struct if_msghdr *ifm = (struct if_msghdr *)rtm; struct sockaddr_dl *sdl = (struct sockaddr_dl *)(ifm + 1); - + if (sdl->sdl_family != AF_LINK) return; - + if (ifm->ifm_addrs == 0 && ifm->ifm_index > 0) { if (!(hw = avahi_interface_monitor_get_hw_interface(m, (AvahiIfIndex) ifm->ifm_index))) return; avahi_hw_interface_free(hw, 0); return; } - + if (!(hw = avahi_interface_monitor_get_hw_interface(m, ifm->ifm_index))) if (!(hw = avahi_hw_interface_new(m, (AvahiIfIndex) ifm->ifm_index))) return; /* OOM */ - + hw->flags_ok = (ifm->ifm_flags & IFF_UP) && (!m->server->config.use_iff_running || (ifm->ifm_flags & IFF_RUNNING)) && !(ifm->ifm_flags & IFF_LOOPBACK) && (ifm->ifm_flags & IFF_MULTICAST) && (m->server->config.allow_point_to_point || !(ifm->ifm_flags & IFF_POINTOPOINT)); - + avahi_free(hw->name); hw->name = avahi_strndup(sdl->sdl_data, sdl->sdl_nlen); - + hw->mtu = ifm->ifm_data.ifi_mtu; - + hw->mac_address_size = sdl->sdl_alen; if (hw->mac_address_size > AVAHI_MAC_ADDRESS_MAX) hw->mac_address_size = AVAHI_MAC_ADDRESS_MAX; - + memcpy(hw->mac_address, sdl->sdl_data + sdl->sdl_nlen, hw->mac_address_size); - + /* { */ /* char mac[256]; */ /* avahi_log_debug("======\n name: %s\n index:%d\n mtu:%d\n mac:%s\n flags_ok:%d\n======", */ @@ -105,7 +103,7 @@ static void rtm_info(struct rt_msghdr *rtm, AvahiInterfaceMonitor *m) /* avahi_format_mac_address(mac, sizeof(mac), hw->mac_address, hw->mac_address_size), */ /* hw->flags_ok); */ /* } */ - + avahi_hw_interface_check_relevant(hw); avahi_hw_interface_update_rrs(hw, 0); } @@ -125,7 +123,7 @@ static void rtm_addr(struct rt_msghdr *rtm, AvahiInterfaceMonitor *m) int raddr_valid = 0; struct ifa_msghdr *ifam = (struct ifa_msghdr *) rtm; char *cp = (char *)(ifam + 1); - int addrs = ifam->ifam_addrs; + char *cp0; int i; int prefixlen = 0; struct sockaddr *sa =NULL; @@ -135,21 +133,34 @@ static void rtm_addr(struct rt_msghdr *rtm, AvahiInterfaceMonitor *m) ((struct sockaddr *)cp)->sa_family = AF_INET; #endif - if(((struct sockaddr *)cp)->sa_family != AF_INET && ((struct sockaddr *)cp)->sa_family != AF_INET6) + for (cp0 = cp, i = 0; i < RTAX_MAX; i++) { + if (!(ifam->ifam_addrs & (1<sa_family != AF_INET && sa->sa_family != AF_INET6) return; - if (!(iface = avahi_interface_monitor_get_interface(m, (AvahiIfIndex) ifam->ifam_index, avahi_af_to_proto(((struct sockaddr *)cp)->sa_family)))) + if (!(iface = avahi_interface_monitor_get_interface(m, (AvahiIfIndex) ifam->ifam_index, avahi_af_to_proto(sa->sa_family)))) return; - raddr.proto = avahi_af_to_proto(((struct sockaddr *)cp)->sa_family); - - for(i = 0; addrs != 0 && i < RTAX_MAX; addrs &= ~(1<sa_family); + + for(cp = cp0, i = 0; i < RTAX_MAX; i++) { - if (!(addrs & 1<ifam_addrs & (1<sa_len == 0) + if (sa->sa_len == 0) continue; #endif switch(sa->sa_family) { @@ -172,6 +183,13 @@ static void rtm_addr(struct rt_msghdr *rtm, AvahiInterfaceMonitor *m) break; case RTA_IFA: memcpy(raddr.data.data, &((struct sockaddr_in6 *)sa)->sin6_addr, sizeof(struct in6_addr)); +#ifdef __KAME__ + if (IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)raddr.data.data)) + { + ((struct in6_addr *)raddr.data.data)->s6_addr[2] = 0; + ((struct in6_addr *)raddr.data.data)->s6_addr[3] = 0; + } +#endif raddr_valid = 1; default: break; @@ -196,9 +214,12 @@ static void rtm_addr(struct rt_msghdr *rtm, AvahiInterfaceMonitor *m) if (!(addriface = avahi_interface_monitor_get_address(m, iface, &raddr))) if (!(addriface = avahi_interface_address_new(m, iface, &raddr, prefixlen))) return; /* OOM */ - /* FIXME */ - /* addriface->global_scope = ifaddrmsg->ifa_scope == RT_SCOPE_UNIVERSE || ifaddrmsg->ifa_scope == RT_SCOPE_SITE; */ - addriface->global_scope = 1; + if (raddr.proto == AVAHI_PROTO_INET6) + { + addriface->global_scope = !(IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)raddr.data.data) || IN6_IS_ADDR_MULTICAST((struct in6_addr *)raddr.data.data)); + } + else + addriface->global_scope = 1; } else { @@ -208,7 +229,7 @@ static void rtm_addr(struct rt_msghdr *rtm, AvahiInterfaceMonitor *m) return; avahi_interface_address_free(addriface); } - + avahi_interface_check_relevant(iface); avahi_interface_update_rrs(iface, 0); } @@ -217,7 +238,7 @@ static void parse_rtmsg(struct rt_msghdr *rtm, AvahiInterfaceMonitor *m) { assert(m); assert(rtm); - + if (rtm->rtm_version != RTM_VERSION) { avahi_log_warn("routing message version %d not understood", rtm->rtm_version); @@ -278,15 +299,15 @@ int avahi_interface_monitor_init_osdep(AvahiInterfaceMonitor *m) { } m->osdep.pfroute->fd = fd; - if (!(m->osdep.pfroute->watch = m->server->poll_api->watch_new(m->server->poll_api, - m->osdep.pfroute->fd, - AVAHI_WATCH_IN, - socket_event, + if (!(m->osdep.pfroute->watch = m->server->poll_api->watch_new(m->server->poll_api, + m->osdep.pfroute->fd, + AVAHI_WATCH_IN, + socket_event, m))) { avahi_log_error(__FILE__": Failed to create watch."); goto fail; } - + return 0; fail: @@ -294,10 +315,10 @@ fail: if (m->osdep.pfroute) { if (m->osdep.pfroute->watch) m->server->poll_api->watch_free(m->osdep.pfroute->watch); - + if (fd >= 0) close(fd); - + m->osdep.pfroute = NULL; } @@ -310,7 +331,7 @@ void avahi_interface_monitor_free_osdep(AvahiInterfaceMonitor *m) { if (m->osdep.pfroute) { if (m->osdep.pfroute->watch) m->server->poll_api->watch_free(m->osdep.pfroute->watch); - + if (m->osdep.pfroute->fd >= 0) close(m->osdep.pfroute->fd); @@ -400,7 +421,7 @@ static void if_add_interface(struct lifreq *lifreq, AvahiInterfaceMonitor *m, in index = if_nametoindex(lifreq->lifr_name); if (!(hw = avahi_interface_monitor_get_hw_interface(m, (AvahiIfIndex) index))) { - if (!(hw = avahi_hw_interface_new(m, (AvahiIfIndex) index))) + if (!(hw = avahi_hw_interface_new(m, (AvahiIfIndex) index))) return; /* OOM */ hw->flags_ok = @@ -422,7 +443,7 @@ static void if_add_interface(struct lifreq *lifreq, AvahiInterfaceMonitor *m, in return; /* OOM */ addriface->global_scope = 1; - + avahi_hw_interface_check_relevant(hw); avahi_hw_interface_update_rrs(hw, 0); } @@ -436,7 +457,7 @@ void avahi_interface_monitor_sync(AvahiInterfaceMonitor *m) { struct rt_msghdr *rtm; assert(m); - + retry2: mib[0] = CTL_NET; mib[1] = PF_ROUTE; @@ -469,7 +490,7 @@ void avahi_interface_monitor_sync(AvahiInterfaceMonitor *m) { rtm = (struct rt_msghdr *)next; parse_rtmsg(rtm, m); } - + m->list_complete = 1; avahi_interface_monitor_check_relevant(m); avahi_interface_monitor_update_rrs(m, 0);