|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1985 The Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * This file includes significant work done at Cornell University by ! 6: * Bill Nesheim. That work included by permission. ! 7: * ! 8: * Redistribution and use in source and binary forms are permitted ! 9: * provided that: (1) source distributions retain this entire copyright ! 10: * notice and comment, and (2) distributions including binaries display ! 11: * the following acknowledgement: ``This product includes software ! 12: * developed by the University of California, Berkeley and its contributors'' ! 13: * in the documentation or other materials provided with the distribution ! 14: * and in all advertising materials mentioning features or use of this ! 15: * software. Neither the name of the University nor the names of its ! 16: * contributors may be used to endorse or promote products derived ! 17: * from this software without specific prior written permission. ! 18: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 19: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 20: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 21: */ ! 22: ! 23: #ifndef lint ! 24: static char sccsid[] = "@(#)output.c 5.7 (Berkeley) 6/1/90"; ! 25: #endif /* not lint */ ! 26: ! 27: /* ! 28: * Routing Table Management Daemon ! 29: */ ! 30: #include "defs.h" ! 31: ! 32: /* ! 33: * Apply the function "f" to all non-passive ! 34: * interfaces. If the interface supports the ! 35: * use of broadcasting use it, otherwise address ! 36: * the output to the known router. ! 37: */ ! 38: toall(f) ! 39: int (*f)(); ! 40: { ! 41: register struct interface *ifp; ! 42: register struct sockaddr *dst; ! 43: register int flags; ! 44: extern struct interface *ifnet; ! 45: ! 46: for (ifp = ifnet; ifp; ifp = ifp->int_next) { ! 47: if (ifp->int_flags & IFF_PASSIVE) ! 48: continue; ! 49: dst = ifp->int_flags & IFF_BROADCAST ? &ifp->int_broadaddr : ! 50: ifp->int_flags & IFF_POINTOPOINT ? &ifp->int_dstaddr : ! 51: &ifp->int_addr; ! 52: flags = ifp->int_flags & IFF_INTERFACE ? MSG_DONTROUTE : 0; ! 53: (*f)(dst, flags, ifp); ! 54: } ! 55: } ! 56: ! 57: /* ! 58: * Output a preformed packet. ! 59: */ ! 60: /*ARGSUSED*/ ! 61: sendmsg(dst, flags, ifp) ! 62: struct sockaddr *dst; ! 63: int flags; ! 64: struct interface *ifp; ! 65: { ! 66: ! 67: (*afswitch[dst->sa_family].af_output) ! 68: (flags, 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) ! 77: struct sockaddr *dst; ! 78: int flags; ! 79: struct interface *ifp; ! 80: { ! 81: register struct rt_entry *rt; ! 82: register struct rthash *rh; ! 83: register struct netinfo *nn; ! 84: register struct netinfo *n = msg->rip_nets; ! 85: struct rthash *base = hosthash; ! 86: struct sockaddr_ns *sns = (struct sockaddr_ns *) dst; ! 87: int (*output)() = afswitch[dst->sa_family].af_output; ! 88: int doinghost = 1, size, metric; ! 89: union ns_net net; ! 90: ! 91: msg->rip_cmd = ntohs(RIPCMD_RESPONSE); ! 92: again: ! 93: for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) ! 94: for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; rt = rt->rt_forw) { ! 95: size = (char *)n - (char *)msg; ! 96: if (size > MAXPACKETSIZE - sizeof (struct netinfo)) { ! 97: (*output)(flags, dst, size); ! 98: TRACE_OUTPUT(ifp, dst, size); ! 99: n = msg->rip_nets; ! 100: } ! 101: sns = (struct sockaddr_ns *)&rt->rt_dst; ! 102: if ((rt->rt_flags & (RTF_HOST|RTF_GATEWAY)) == RTF_HOST) ! 103: sns = (struct sockaddr_ns *)&rt->rt_router; ! 104: metric = min(rt->rt_metric + 1, HOPCNT_INFINITY); ! 105: net = sns->sns_addr.x_net; ! 106: /* ! 107: * Make sure that we don't put out a two net entries ! 108: * for a pt to pt link (one for the G route, one for the if) ! 109: * This is a kludge, and won't work if there are lots of nets. ! 110: */ ! 111: for (nn = msg->rip_nets; nn < n; nn++) { ! 112: if (ns_neteqnn(net, nn->rip_dst)) { ! 113: if (metric < ntohs(nn->rip_metric)) ! 114: nn->rip_metric = htons(metric); ! 115: goto next; ! 116: } ! 117: } ! 118: n->rip_dst = net; ! 119: n->rip_metric = htons(metric); ! 120: n++; ! 121: next:; ! 122: } ! 123: if (doinghost) { ! 124: doinghost = 0; ! 125: base = nethash; ! 126: goto again; ! 127: } ! 128: if (n != msg->rip_nets) { ! 129: size = (char *)n - (char *)msg; ! 130: (*output)(flags, dst, size); ! 131: TRACE_OUTPUT(ifp, dst, size); ! 132: } ! 133: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.