|
|
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: (1) source distributions retain this entire copyright ! 7: * notice and comment, and (2) distributions including binaries display ! 8: * the following acknowledgement: ``This product includes software ! 9: * developed by the University of California, Berkeley and its contributors'' ! 10: * in the documentation or other materials provided with the distribution ! 11: * and in all advertising materials mentioning features or use of this ! 12: * software. Neither the name of the University nor the names of its ! 13: * contributors may be used to endorse or promote products derived ! 14: * from this software without specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #ifndef lint ! 21: static char sccsid[] = "@(#)output.c 5.14 (Berkeley) 6/1/90"; ! 22: #endif /* not lint */ ! 23: ! 24: /* ! 25: * Routing Table Management Daemon ! 26: */ ! 27: #include "defs.h" ! 28: ! 29: /* ! 30: * Apply the function "f" to all non-passive ! 31: * interfaces. If the interface supports the ! 32: * use of broadcasting use it, otherwise address ! 33: * the output to the known router. ! 34: */ ! 35: toall(f, rtstate, skipif) ! 36: int (*f)(); ! 37: int rtstate; ! 38: struct interface *skipif; ! 39: { ! 40: register struct interface *ifp; ! 41: register struct sockaddr *dst; ! 42: register int flags; ! 43: extern struct interface *ifnet; ! 44: ! 45: for (ifp = ifnet; ifp; ifp = ifp->int_next) { ! 46: if (ifp->int_flags & IFF_PASSIVE || ifp == skipif) ! 47: continue; ! 48: dst = ifp->int_flags & IFF_BROADCAST ? &ifp->int_broadaddr : ! 49: ifp->int_flags & IFF_POINTOPOINT ? &ifp->int_dstaddr : ! 50: &ifp->int_addr; ! 51: flags = ifp->int_flags & IFF_INTERFACE ? MSG_DONTROUTE : 0; ! 52: (*f)(dst, flags, ifp, rtstate); ! 53: } ! 54: } ! 55: ! 56: /* ! 57: * Output a preformed packet. ! 58: */ ! 59: /*ARGSUSED*/ ! 60: sendmsg(dst, flags, ifp, rtstate) ! 61: struct sockaddr *dst; ! 62: int flags; ! 63: struct interface *ifp; ! 64: int rtstate; ! 65: { ! 66: ! 67: (*afswitch[dst->sa_family].af_output)(s, flags, ! 68: dst, sizeof (struct rip)); ! 69: TRACE_OUTPUT(ifp, dst, sizeof (struct rip)); ! 70: } ! 71: ! 72: /* ! 73: * Supply dst with the contents of the routing tables. ! 74: * If this won't fit in one packet, chop it up into several. ! 75: */ ! 76: supply(dst, flags, ifp, rtstate) ! 77: struct sockaddr *dst; ! 78: int flags; ! 79: register struct interface *ifp; ! 80: int rtstate; ! 81: { ! 82: register struct rt_entry *rt; ! 83: register struct netinfo *n = msg->rip_nets; ! 84: register struct rthash *rh; ! 85: struct rthash *base = hosthash; ! 86: int doinghost = 1, size; ! 87: int (*output)() = afswitch[dst->sa_family].af_output; ! 88: int (*sendroute)() = afswitch[dst->sa_family].af_sendroute; ! 89: int npackets = 0; ! 90: ! 91: msg->rip_cmd = RIPCMD_RESPONSE; ! 92: msg->rip_vers = RIPVERSION; ! 93: bzero(msg->rip_res1, sizeof(msg->rip_res1)); ! 94: again: ! 95: for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) ! 96: for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; rt = rt->rt_forw) { ! 97: /* ! 98: * Don't resend the information on the network ! 99: * from which it was received (unless sending ! 100: * in response to a query). ! 101: */ ! 102: if (ifp && rt->rt_ifp == ifp && ! 103: (rt->rt_state & RTS_INTERFACE) == 0) ! 104: continue; ! 105: if (rt->rt_state & RTS_EXTERNAL) ! 106: continue; ! 107: /* ! 108: * For dynamic updates, limit update to routes ! 109: * with the specified state. ! 110: */ ! 111: if (rtstate && (rt->rt_state & rtstate) == 0) ! 112: continue; ! 113: /* ! 114: * Limit the spread of subnet information ! 115: * to those who are interested. ! 116: */ ! 117: if (doinghost == 0 && rt->rt_state & RTS_SUBNET) { ! 118: if (rt->rt_dst.sa_family != dst->sa_family) ! 119: continue; ! 120: if ((*sendroute)(rt, dst) == 0) ! 121: continue; ! 122: } ! 123: size = (char *)n - packet; ! 124: if (size > MAXPACKETSIZE - sizeof (struct netinfo)) { ! 125: TRACE_OUTPUT(ifp, dst, size); ! 126: (*output)(s, flags, dst, size); ! 127: /* ! 128: * If only sending to ourselves, ! 129: * one packet is enough to monitor interface. ! 130: */ ! 131: if (ifp && (ifp->int_flags & ! 132: (IFF_BROADCAST | IFF_POINTOPOINT | IFF_REMOTE)) == 0) ! 133: return; ! 134: n = msg->rip_nets; ! 135: npackets++; ! 136: } ! 137: n->rip_dst = rt->rt_dst; ! 138: #if BSD < 198810 ! 139: if (sizeof(n->rip_dst.sa_family) > 1) /* XXX */ ! 140: n->rip_dst.sa_family = htons(n->rip_dst.sa_family); ! 141: #else ! 142: #define osa(x) ((struct osockaddr *)(&(x))) ! 143: osa(n->rip_dst)->sa_family = htons(n->rip_dst.sa_family); ! 144: #endif ! 145: n->rip_metric = htonl(rt->rt_metric); ! 146: n++; ! 147: } ! 148: if (doinghost) { ! 149: doinghost = 0; ! 150: base = nethash; ! 151: goto again; ! 152: } ! 153: if (n != msg->rip_nets || (npackets == 0 && rtstate == 0)) { ! 154: size = (char *)n - packet; ! 155: TRACE_OUTPUT(ifp, dst, size); ! 156: (*output)(s, flags, dst, size); ! 157: } ! 158: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.