X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=avahi-core%2Fiface-pfroute.c;h=9a2e953398e6d03dacaae7bd515937dbd44f9063;hb=9c0f9c65093cfa53d45f9b68782321eb8063a032;hp=a67b8267a1bf5bcbe957a469a29b3a7ddf537bab;hpb=2f111835513ceecab837cb769f0d7b6b6c80f68b;p=catta diff --git a/avahi-core/iface-pfroute.c b/avahi-core/iface-pfroute.c index a67b826..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); @@ -262,10 +283,11 @@ static void socket_event(AvahiWatch *w, int fd, AVAHI_GCC_UNUSED AvahiWatchEvent int avahi_interface_monitor_init_osdep(AvahiInterfaceMonitor *m) { int fd = -1; - m->osdep.pfroute = NULL; assert(m); + m->osdep.pfroute = NULL; + if ((fd = socket(PF_ROUTE, SOCK_RAW, AF_UNSPEC)) < 0) { avahi_log_error(__FILE__": socket(PF_ROUTE): %s", strerror(errno)); goto fail; @@ -277,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: @@ -293,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; } @@ -309,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); @@ -318,7 +340,7 @@ void avahi_interface_monitor_free_osdep(AvahiInterfaceMonitor *m) { } } -#ifndef HAVE_SYS_SYSCTL_H +#if defined (SIOCGLIFNUM) && defined(HAVE_STRUCT_LIFCONF) /* Solaris 8 and later; Sol 7? */ /* * I got this function from GNU zsbra */ @@ -399,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 = @@ -421,21 +443,21 @@ 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); } #endif void avahi_interface_monitor_sync(AvahiInterfaceMonitor *m) { -#ifdef HAVE_SYS_SYSCTL_H +#ifndef HAVE_STRUCT_LIFCONF size_t needed; int mib[6]; char *buf, *lim, *next, count = 0; struct rt_msghdr *rtm; assert(m); - + retry2: mib[0] = CTL_NET; mib[1] = PF_ROUTE; @@ -468,12 +490,12 @@ 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); avahi_log_info("Network interface enumeration completed."); -#else +#elif defined (SIOCGLIFNUM) && defined(HAVE_STRUCT_LIFCONF) /* Solaris 8 and later; Sol 7? */ int sockfd; int ret; int n;