From 114e42787c16f0bb03d41dd70f1147d7362bca98 Mon Sep 17 00:00:00 2001 From: wollman Date: Tue, 19 Nov 1996 20:23:47 +0000 Subject: Latest version of SGI routed courtesy of Vern Schryver. This version adds the capability to use MD5 authentication as defined in the latest documents. Submitted by: Vernon J. Schryver --- sbin/routed/rdisc.c | 148 ++++++++++++++++++++++++++++------------------------ 1 file changed, 81 insertions(+), 67 deletions(-) (limited to 'sbin/routed/rdisc.c') diff --git a/sbin/routed/rdisc.c b/sbin/routed/rdisc.c index da1784c..7433b792 100644 --- a/sbin/routed/rdisc.c +++ b/sbin/routed/rdisc.c @@ -36,7 +36,7 @@ static char sccsid[] = "@(#)rdisc.c 8.1 (Berkeley) x/y/95"; #elif defined(__NetBSD__) static char rcsid[] = "$NetBSD$"; #endif -#ident "$Revision: 1.16 $" +#ident "$Revision: 1.17 $" #include "defs.h" #include @@ -134,8 +134,7 @@ trace_rdisc(char *act, (void)fputc('\n',ftrace); } else { - trace_act("%s Router Solic. from %s to %s via %s" - " value=%#x\n", + trace_act("%s Router Solic. from %s to %s via %s value=%#x", act, naddr_ntoa(from), naddr_ntoa(to), ifp ? ifp->int_name : "?", ntohl(p->so.icmp_so_rsvd)); @@ -161,7 +160,8 @@ get_rdisc_sock(void) */ void set_rdisc_mg(struct interface *ifp, - int on) { /* 0=turn it off */ + int on) /* 0=turn it off */ +{ struct ip_mreq m; if (rdisc_sock < 0) { @@ -174,8 +174,7 @@ set_rdisc_mg(struct interface *ifp, get_rdisc_sock(); } - if (!(ifp->int_if_flags & IFF_MULTICAST) - || (ifp->int_state & IS_ALIAS)) { + if (!(ifp->int_if_flags & IFF_MULTICAST)) { ifp->int_state &= ~(IS_ALL_HOSTS | IS_ALL_ROUTERS); return; } @@ -253,7 +252,7 @@ set_supplier(void) if (supplier_set) return; - trace_act("start suppying routes\n"); + trace_act("start suppying routes"); /* Forget discovered routes. */ @@ -327,8 +326,7 @@ rdisc_age(naddr bad_gate) sec = (now.tv_sec - drp->dr_life + SUPPLY_INTERVAL); if (drp->dr_ts > sec) { - trace_act("age 0.0.0.0 --> %s" - " via %s\n", + trace_act("age 0.0.0.0 --> %s via %s", naddr_ntoa(drp->dr_gate), drp->dr_ifp->int_name); drp->dr_ts = sec; @@ -414,8 +412,8 @@ del_rdisc(struct dr *drp) */ if (i == 0 && ifp->int_rdisc_cnt >= MAX_SOLICITATIONS) { - trace_act("discovered route is bad" - "--re-solicit routers via %s\n", ifp->int_name); + trace_act("discovered route is bad--re-solicit routers via %s", + ifp->int_name); ifp->int_rdisc_cnt = 0; ifp->int_rdisc_timer.tv_sec = 0; rdisc_sol(); @@ -486,7 +484,7 @@ rdisc_sort(void) /* Stop using discovered routes if they are all bad */ if (new_drp == 0) { - trace_act("turn off Router Discovery client\n"); + trace_act("turn off Router Discovery client"); rdisc_ok = 0; if (rt != 0 @@ -504,7 +502,7 @@ rdisc_sort(void) } else { if (cur_drp == 0) { trace_act("turn on Router Discovery client" - " using %s via %s\n", + " using %s via %s", naddr_ntoa(new_drp->dr_gate), new_drp->dr_ifp->int_name); @@ -512,7 +510,7 @@ rdisc_sort(void) } else { trace_act("switch Router Discovery from" - " %s via %s to %s via %s\n", + " %s via %s to %s via %s", naddr_ntoa(cur_drp->dr_gate), cur_drp->dr_ifp->int_name, naddr_ntoa(new_drp->dr_gate), @@ -527,7 +525,8 @@ rdisc_sort(void) } else { rtadd(RIP_DEFAULT, 0, new_drp->dr_gate, new_drp->dr_gate, - 0, 0, RS_RDISC, new_drp->dr_ifp); + HOPCNT_INFINITY-1, 0, + RS_RDISC, new_drp->dr_ifp); } /* Now turn off RIP and delete RIP routes, @@ -551,30 +550,27 @@ parse_ad(naddr from, u_short life, struct interface *ifp) { - static naddr bad_gate; + static struct msg_limit bad_gate; struct dr *drp, *new_drp; if (gate == RIP_DEFAULT || !check_dst(gate)) { - if (bad_gate != from) { - msglog("router %s advertising bad gateway %s", - naddr_ntoa(from), - naddr_ntoa(gate)); - bad_gate = from; - } + msglim(&bad_gate, from,"router %s advertising bad gateway %s", + naddr_ntoa(from), + naddr_ntoa(gate)); return; } /* ignore pointers to ourself and routes via unreachable networks */ if (ifwithaddr(gate, 1, 0) != 0) { - trace_pkt("\tdiscard Router Discovery Ad pointing at us\n"); + trace_pkt(" discard Router Discovery Ad pointing at us"); return; } if (!on_net(gate, ifp->int_net, ifp->int_mask)) { - trace_pkt("\tdiscard Router Discovery Ad" - " toward unreachable net\n"); + trace_pkt(" discard Router Discovery Ad" + " toward unreachable net"); return; } @@ -710,7 +706,7 @@ send_rdisc(union ad_u *p, msg = "Send multicast"; if (ifp->int_state & IS_DUP) { trace_act("abort multicast output via %s" - " with duplicate address\n", + " with duplicate address", ifp->int_name); return; } @@ -800,14 +796,13 @@ rdisc_adv(void) { struct interface *ifp; + if (!supplier) + return; rdisc_timer.tv_sec = now.tv_sec + NEVER; for (ifp = ifnet; ifp; ifp = ifp->int_next) { - if (0 != (ifp->int_state & (IS_NO_ADV_OUT - | IS_PASSIVE - | IS_ALIAS - | IS_BROKE))) + if (0 != (ifp->int_state & (IS_NO_ADV_OUT | IS_BROKE))) continue; if (!timercmp(&ifp->int_rdisc_timer, &now, >) @@ -843,13 +838,13 @@ rdisc_sol(void) union ad_u u; + if (supplier) + return; + rdisc_timer.tv_sec = now.tv_sec + NEVER; for (ifp = ifnet; ifp; ifp = ifp->int_next) { - if (0 != (ifp->int_state & (IS_NO_SOL_OUT - | IS_PASSIVE - | IS_ALIAS - | IS_BROKE)) + if (0 != (ifp->int_state & (IS_NO_SOL_OUT | IS_BROKE)) || ifp->int_rdisc_cnt >= MAX_SOLICITATIONS) continue; @@ -880,20 +875,14 @@ rdisc_sol(void) static struct interface * /* 0 if bad */ ck_icmp(char *act, naddr from, + struct interface *ifp, naddr to, union ad_u *p, u_int len) { - struct interface *ifp; char *type; - /* If we could tell the interface on which a packet from address 0 - * arrived, we could deal with such solicitations. - */ - - ifp = ((from == 0) ? 0 : iflookup(from)); - if (p->icmp.icmp_type == ICMP_ROUTERADVERT) { type = "advertisement"; } else if (p->icmp.icmp_type == ICMP_ROUTERSOLICIT) { @@ -903,8 +892,7 @@ ck_icmp(char *act, } if (p->icmp.icmp_code != 0) { - trace_pkt("unrecognized ICMP Router" - " %s code=%d from %s to %s\n", + trace_pkt("unrecognized ICMP Router %s code=%d from %s to %s", type, p->icmp.icmp_code, naddr_ntoa(from), naddr_ntoa(to)); return 0; @@ -926,14 +914,20 @@ ck_icmp(char *act, void read_d(void) { - static naddr bad_asize, bad_len; + static struct msg_limit bad_asize, bad_len; struct sockaddr_in from; int n, fromlen, cc, hlen; - union { - struct ip ip; - u_short s[512/2]; - u_char b[512]; - } pkt; + struct { +#undef USE_PASSIFNAME /* it is too bad it does not work on raw sockets */ +#ifdef USE_PASSIFNAME + char ifname[IFNAMSIZ]; +#endif + union { + struct ip ip; + u_short s[512/2]; + u_char b[512]; + } pkt; + } buf; union ad_u *p; n_long *wp; struct interface *ifp; @@ -941,7 +935,7 @@ read_d(void) for (;;) { fromlen = sizeof(from); - cc = recvfrom(rdisc_sock, &pkt, sizeof(pkt), 0, + cc = recvfrom(rdisc_sock, &buf, sizeof(buf), 0, (struct sockaddr*)&from, &fromlen); if (cc <= 0) { @@ -952,20 +946,46 @@ read_d(void) if (fromlen != sizeof(struct sockaddr_in)) logbad(1,"impossible recvfrom(rdisc_sock) fromlen=%d", fromlen); +#ifdef USE_PASSIFNAME + if ((cc -= sizeof(buf.ifname)) < 0) + logbad(0,"missing USE_PASSIFNAME; only %d bytes", + cc+sizeof(buf.ifname)); +#endif - hlen = pkt.ip.ip_hl << 2; + hlen = buf.pkt.ip.ip_hl << 2; if (cc < hlen + ICMP_MINLEN) continue; - p = (union ad_u *)&pkt.b[hlen]; + p = (union ad_u *)&buf.pkt.b[hlen]; cc -= hlen; +#ifdef USE_PASSIFNAME + ifp = ifwithname(buf.ifname, 0); + if (ifp == 0) { + /* maybe it is a new interface */ + ifinit(); + ifp = ifwithname(buf.ifname, 0); + if (ifp == 0) { + msglim(&bad_name, from.sin_addr.s_addr, + "impossible rdisc if_ name %.*s", + IFNAMSIZ, buf.ifname); + } + } +#else + /* If we could tell the interface on which a packet from + * address 0 arrived, we could deal with such solicitations. + */ + ifp = ((from.sin_addr.s_addr == 0) + ? 0 : iflookup(from.sin_addr.s_addr)); +#endif ifp = ck_icmp("Recv", - from.sin_addr.s_addr, pkt.ip.ip_dst.s_addr, + from.sin_addr.s_addr, ifp, + buf.pkt.ip.ip_dst.s_addr, p, cc); if (ifp == 0) continue; if (ifwithaddr(from.sin_addr.s_addr, 0, 0)) { - trace_pkt("\tdiscard our own Router Discovery msg\n"); + trace_pkt(" discard our own Router Discovery" + " message"); continue; } @@ -973,27 +993,21 @@ read_d(void) case ICMP_ROUTERADVERT: if (p->ad.icmp_ad_asize*4 < sizeof(p->ad.icmp_ad_info[0])) { - if (bad_asize != from.sin_addr.s_addr) { - msglog("intolerable rdisc address" - " size=%d", - p->ad.icmp_ad_asize); - bad_asize = from.sin_addr.s_addr; - } + msglim(&bad_asize, from.sin_addr.s_addr, + "intolerable rdisc address size=%d", + p->ad.icmp_ad_asize); continue; } if (p->ad.icmp_ad_num == 0) { - trace_pkt("\tempty?\n"); + trace_pkt(" empty?"); continue; } if (cc != (sizeof(p->ad) - sizeof(p->ad.icmp_ad_info) + (p->ad.icmp_ad_num * sizeof(p->ad.icmp_ad_info[0])))) { - if (bad_len != from.sin_addr.s_addr) { - msglog("rdisc length %d does not" - " match ad_num %d", - cc, p->ad.icmp_ad_num); - bad_len = from.sin_addr.s_addr; - } + msglim(&bad_len, from.sin_addr.s_addr, + "rdisc length %d does not match ad_num" + " %d", cc, p->ad.icmp_ad_num); continue; } if (supplier) -- cgit v1.1