|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1983 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: */ ! 6: ! 7: #ifndef lint ! 8: static char sccsid[] = "@(#)output.c 5.3 (Berkeley) 5/30/86"; ! 9: #endif not lint ! 10: ! 11: /* ! 12: * Routing Table Management Daemon ! 13: */ ! 14: #include "defs.h" ! 15: ! 16: /* ! 17: * Apply the function "f" to all non-passive ! 18: * interfaces. If the interface supports the ! 19: * use of broadcasting use it, otherwise address ! 20: * the output to the known router. ! 21: */ ! 22: toall(f) ! 23: int (*f)(); ! 24: { ! 25: register struct interface *ifp; ! 26: register struct sockaddr *dst; ! 27: register int flags; ! 28: extern struct interface *ifnet; ! 29: ! 30: for (ifp = ifnet; ifp; ifp = ifp->int_next) { ! 31: if (ifp->int_flags & IFF_PASSIVE) ! 32: continue; ! 33: dst = ifp->int_flags & IFF_BROADCAST ? &ifp->int_broadaddr : ! 34: ifp->int_flags & IFF_POINTOPOINT ? &ifp->int_dstaddr : ! 35: &ifp->int_addr; ! 36: flags = ifp->int_flags & IFF_INTERFACE ? MSG_DONTROUTE : 0; ! 37: (*f)(dst, flags, ifp); ! 38: } ! 39: } ! 40: ! 41: /* ! 42: * Output a preformed packet. ! 43: */ ! 44: /*ARGSUSED*/ ! 45: sendmsg(dst, flags, ifp) ! 46: struct sockaddr *dst; ! 47: int flags; ! 48: struct interface *ifp; ! 49: { ! 50: ! 51: (*afswitch[dst->sa_family].af_output)(s, flags, ! 52: dst, sizeof (struct rip)); ! 53: TRACE_OUTPUT(ifp, dst, sizeof (struct rip)); ! 54: } ! 55: ! 56: /* ! 57: * Supply dst with the contents of the routing tables. ! 58: * If this won't fit in one packet, chop it up into several. ! 59: */ ! 60: supply(dst, flags, ifp) ! 61: struct sockaddr *dst; ! 62: int flags; ! 63: struct interface *ifp; ! 64: { ! 65: register struct rt_entry *rt; ! 66: struct netinfo *n = msg->rip_nets; ! 67: register struct rthash *rh; ! 68: struct rthash *base = hosthash; ! 69: int doinghost = 1, size; ! 70: int (*output)() = afswitch[dst->sa_family].af_output; ! 71: int (*sendsubnet)() = afswitch[dst->sa_family].af_sendsubnet; ! 72: ! 73: msg->rip_cmd = RIPCMD_RESPONSE; ! 74: msg->rip_vers = RIPVERSION; ! 75: again: ! 76: for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) ! 77: for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; rt = rt->rt_forw) { ! 78: /* ! 79: * Don't resend the information ! 80: * on the network from which it was received. ! 81: */ ! 82: if (ifp && rt->rt_ifp == ifp) ! 83: continue; ! 84: if (rt->rt_state & RTS_EXTERNAL) ! 85: continue; ! 86: /* ! 87: * Limit the spread of subnet information ! 88: * to those who are interested. ! 89: */ ! 90: if (doinghost == 0 && rt->rt_state & RTS_SUBNET) { ! 91: if (ifp && (ifp->int_flags & IFF_SUBNET) == 0) ! 92: continue; ! 93: if (rt->rt_dst.sa_family != dst->sa_family) ! 94: continue; ! 95: if ((*sendsubnet)(rt, dst) == 0) ! 96: continue; ! 97: } ! 98: size = (char *)n - packet; ! 99: if (size > MAXPACKETSIZE - sizeof (struct netinfo)) { ! 100: (*output)(s, flags, dst, size); ! 101: TRACE_OUTPUT(ifp, dst, size); ! 102: n = msg->rip_nets; ! 103: } ! 104: n->rip_dst = rt->rt_dst; ! 105: n->rip_dst.sa_family = htons(n->rip_dst.sa_family); ! 106: n->rip_metric = htonl(min(rt->rt_metric + 1, HOPCNT_INFINITY)); ! 107: n++; ! 108: } ! 109: if (doinghost) { ! 110: doinghost = 0; ! 111: base = nethash; ! 112: goto again; ! 113: } ! 114: if (n != msg->rip_nets) { ! 115: size = (char *)n - packet; ! 116: (*output)(s, flags, dst, size); ! 117: TRACE_OUTPUT(ifp, dst, size); ! 118: } ! 119: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.