diff options
Diffstat (limited to 'sbin/routed/rdisc.c')
-rw-r--r-- | sbin/routed/rdisc.c | 44 |
1 files changed, 28 insertions, 16 deletions
diff --git a/sbin/routed/rdisc.c b/sbin/routed/rdisc.c index d76041d60c10..113527096883 100644 --- a/sbin/routed/rdisc.c +++ b/sbin/routed/rdisc.c @@ -36,12 +36,14 @@ #include <netinet/ip.h> #include <netinet/ip_icmp.h> -#if !defined(sgi) && !defined(__NetBSD__) -static char sccsid[] __attribute__((unused)) = "@(#)rdisc.c 8.1 (Berkeley) x/y/95"; -#elif defined(__NetBSD__) +#ifdef __NetBSD__ __RCSID("$NetBSD$"); +#elif defined(__FreeBSD__) +__RCSID("$FreeBSD$"); +#else +__RCSID("$Revision: 2.27 $"); +#ident "$Revision: 2.27 $" #endif -#ident "$Revision: 2.22 $" /* router advertisement ICMP packet */ struct icmp_ad { @@ -95,8 +97,9 @@ struct dr { /* accumulated advertisements */ #define UNSIGN_PREF(p) SIGN_PREF(p) /* adjust unsigned preference by interface metric, * without driving it to infinity */ -#define PREF(p, ifp) ((int)(p) <= (ifp)->int_metric ? ((p) != 0 ? 1 : 0) \ - : (p) - ((ifp)->int_metric)) +#define PREF(p, ifp) ((int)(p) <= ((ifp)->int_metric+(ifp)->int_adj_outmetric)\ + ? ((p) != 0 ? 1 : 0) \ + : (p) - ((ifp)->int_metric+(ifp)->int_adj_outmetric)) static void rdisc_sort(void); @@ -189,9 +192,13 @@ set_rdisc_mg(struct interface *ifp, return; #endif memset(&m, 0, sizeof(m)); +#ifdef MCAST_IFINDEX + m.imr_interface.s_addr = htonl(ifp->int_index); +#else m.imr_interface.s_addr = ((ifp->int_if_flags & IFF_POINTOPOINT) ? ifp->int_dstaddr : ifp->int_addr); +#endif if (supplier || (ifp->int_state & IS_NO_ADV_IN) || !on) { @@ -691,17 +698,17 @@ send_rdisc(union ad_u *p, naddr dst, /* 0 or unicast destination */ int type) /* 0=unicast, 1=bcast, 2=mcast */ { - struct sockaddr_in sin; + struct sockaddr_in rsin; int flags; const char *msg; naddr tgt_mcast; - memset(&sin, 0, sizeof(sin)); - sin.sin_addr.s_addr = dst; - sin.sin_family = AF_INET; + memset(&rsin, 0, sizeof(rsin)); + rsin.sin_addr.s_addr = dst; + rsin.sin_family = AF_INET; #ifdef _HAVE_SIN_LEN - sin.sin_len = sizeof(sin); + rsin.sin_len = sizeof(rsin); #endif flags = MSG_DONTROUTE; @@ -714,10 +721,10 @@ send_rdisc(union ad_u *p, case 1: /* broadcast */ if (ifp->int_if_flags & IFF_POINTOPOINT) { msg = "Send pt-to-pt"; - sin.sin_addr.s_addr = ifp->int_dstaddr; + rsin.sin_addr.s_addr = ifp->int_dstaddr; } else { msg = "Send broadcast"; - sin.sin_addr.s_addr = ifp->int_brdaddr; + rsin.sin_addr.s_addr = ifp->int_brdaddr; } break; @@ -731,6 +738,10 @@ send_rdisc(union ad_u *p, } if (rdisc_sock_mcast != ifp) { /* select the right interface. */ +#ifdef MCAST_IFINDEX + /* specify ifindex */ + tgt_mcast = htonl(ifp->int_index); +#else #ifdef MCAST_PPP_BUG /* Do not specify the primary interface explicitly * if we have the multicast point-to-point kernel @@ -744,6 +755,7 @@ send_rdisc(union ad_u *p, } else #endif tgt_mcast = ifp->int_addr; +#endif if (0 > setsockopt(rdisc_sock, IPPROTO_IP, IP_MULTICAST_IF, &tgt_mcast, sizeof(tgt_mcast))) { @@ -761,16 +773,16 @@ send_rdisc(union ad_u *p, if (rdisc_sock < 0) get_rdisc_sock(); - trace_rdisc(msg, ifp->int_addr, sin.sin_addr.s_addr, ifp, + trace_rdisc(msg, ifp->int_addr, rsin.sin_addr.s_addr, ifp, p, p_size); if (0 > sendto(rdisc_sock, p, p_size, flags, - (struct sockaddr *)&sin, sizeof(sin))) { + (struct sockaddr *)&rsin, sizeof(rsin))) { if (ifp == 0 || !(ifp->int_state & IS_BROKE)) msglog("sendto(%s%s%s): %s", ifp != 0 ? ifp->int_name : "", ifp != 0 ? ", " : "", - inet_ntoa(sin.sin_addr), + inet_ntoa(rsin.sin_addr), strerror(errno)); if (ifp != 0) if_sick(ifp); |