|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1983, 1988 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that this notice is preserved and that due credit is given ! 7: * to the University of California at Berkeley. The name of the University ! 8: * may not be used to endorse or promote products derived from this ! 9: * software without specific prior written permission. This software ! 10: * is provided ``as is'' without express or implied warranty. ! 11: */ ! 12: ! 13: #ifndef lint ! 14: static char sccsid[] = "@(#)output.c 5.10 (Berkeley) 5/31/88"; ! 15: #endif /* not lint */ ! 16: ! 17: /* ! 18: * Routing Table Management Daemon ! 19: */ ! 20: #include "defs.h" ! 21: ! 22: /* ! 23: * Apply the function "f" to all non-passive ! 24: * interfaces. If the interface supports the ! 25: * use of broadcasting use it, otherwise address ! 26: * the output to the known router. ! 27: */ ! 28: toall(f) ! 29: int (*f)(); ! 30: { ! 31: register struct interface *ifp; ! 32: register struct sockaddr *dst; ! 33: register int flags; ! 34: extern struct interface *ifnet; ! 35: ! 36: for (ifp = ifnet; ifp; ifp = ifp->int_next) { ! 37: if (ifp->int_flags & IFF_PASSIVE) ! 38: continue; ! 39: dst = ifp->int_flags & IFF_BROADCAST ? &ifp->int_broadaddr : ! 40: ifp->int_flags & IFF_POINTOPOINT ? &ifp->int_dstaddr : ! 41: &ifp->int_addr; ! 42: flags = ifp->int_flags & IFF_INTERFACE ? MSG_DONTROUTE : 0; ! 43: (*f)(dst, flags, ifp); ! 44: } ! 45: } ! 46: ! 47: /* ! 48: * Output a preformed packet. ! 49: */ ! 50: /*ARGSUSED*/ ! 51: sendmsg(dst, flags, ifp) ! 52: struct sockaddr *dst; ! 53: int flags; ! 54: struct interface *ifp; ! 55: { ! 56: ! 57: (*afswitch[dst->sa_family].af_output)(s, flags, ! 58: dst, sizeof (struct rip)); ! 59: TRACE_OUTPUT(ifp, dst, sizeof (struct rip)); ! 60: } ! 61: ! 62: /* ! 63: * Supply dst with the contents of the routing tables. ! 64: * If this won't fit in one packet, chop it up into several. ! 65: */ ! 66: supply(dst, flags, ifp) ! 67: struct sockaddr *dst; ! 68: int flags; ! 69: register struct interface *ifp; ! 70: { ! 71: register struct rt_entry *rt; ! 72: register struct netinfo *n = msg->rip_nets; ! 73: register struct rthash *rh; ! 74: struct rthash *base = hosthash; ! 75: int doinghost = 1, size; ! 76: int (*output)() = afswitch[dst->sa_family].af_output; ! 77: int (*sendroute)() = afswitch[dst->sa_family].af_sendroute; ! 78: int npackets = 0; ! 79: ! 80: msg->rip_cmd = RIPCMD_RESPONSE; ! 81: msg->rip_vers = RIPVERSION; ! 82: bzero(msg->rip_res1, sizeof(msg->rip_res1)); ! 83: again: ! 84: for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) ! 85: for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; rt = rt->rt_forw) { ! 86: /* ! 87: * Don't resend the information on the network ! 88: * from which it was received (unless sending ! 89: * in response to a query). ! 90: */ ! 91: if (ifp && rt->rt_ifp == ifp && ! 92: (rt->rt_state & RTS_INTERFACE) == 0) ! 93: continue; ! 94: if (rt->rt_state & RTS_EXTERNAL) ! 95: continue; ! 96: /* ! 97: * Limit the spread of subnet information ! 98: * to those who are interested. ! 99: */ ! 100: if (doinghost == 0 && rt->rt_state & RTS_SUBNET) { ! 101: if (rt->rt_dst.sa_family != dst->sa_family) ! 102: continue; ! 103: if ((*sendroute)(rt, dst) == 0) ! 104: continue; ! 105: } ! 106: size = (char *)n - packet; ! 107: if (size > MAXPACKETSIZE - sizeof (struct netinfo)) { ! 108: (*output)(s, flags, dst, size); ! 109: TRACE_OUTPUT(ifp, dst, size); ! 110: /* ! 111: * If only sending to ourselves, ! 112: * one packet is enough to monitor interface. ! 113: */ ! 114: if ((ifp->int_flags & ! 115: (IFF_BROADCAST | IFF_POINTOPOINT | IFF_REMOTE)) == 0) ! 116: return; ! 117: n = msg->rip_nets; ! 118: npackets++; ! 119: } ! 120: n->rip_dst = rt->rt_dst; ! 121: n->rip_dst.sa_family = htons(n->rip_dst.sa_family); ! 122: n->rip_metric = htonl(rt->rt_metric); ! 123: n++; ! 124: } ! 125: if (doinghost) { ! 126: doinghost = 0; ! 127: base = nethash; ! 128: goto again; ! 129: } ! 130: if (n != msg->rip_nets || npackets == 0) { ! 131: size = (char *)n - packet; ! 132: (*output)(s, flags, dst, size); ! 133: TRACE_OUTPUT(ifp, dst, size); ! 134: } ! 135: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.