1 #ifndef lint 2 static char sccsid[] = "@(#)output.c 4.5 (Berkeley) 4/9/84"; 3 #endif 4 5 /* 6 * Routing Table Management Daemon 7 */ 8 #include "defs.h" 9 10 /* 11 * Apply the function "f" to all non-passive 12 * interfaces. If the interface supports the 13 * use of broadcasting use it, otherwise address 14 * the output to the known router. 15 */ 16 toall(f) 17 int (*f)(); 18 { 19 register struct interface *ifp; 20 register struct sockaddr *dst; 21 register int flags; 22 extern struct interface *ifnet; 23 24 for (ifp = ifnet; ifp; ifp = ifp->int_next) { 25 if (ifp->int_flags & IFF_PASSIVE) 26 continue; 27 dst = ifp->int_flags & IFF_BROADCAST ? &ifp->int_broadaddr : 28 ifp->int_flags & IFF_POINTOPOINT ? &ifp->int_dstaddr : 29 &ifp->int_addr; 30 flags = ifp->int_flags & IFF_INTERFACE ? MSG_DONTROUTE : 0; 31 (*f)(dst, flags, ifp); 32 } 33 } 34 35 /* 36 * Output a preformed packet. 37 */ 38 /*ARGSUSED*/ 39 sendmsg(dst, flags, ifp) 40 struct sockaddr *dst; 41 int flags; 42 struct interface *ifp; 43 { 44 45 (*afswitch[dst->sa_family].af_output) 46 (flags, dst, sizeof (struct rip)); 47 TRACE_OUTPUT(ifp, dst, sizeof (struct rip)); 48 } 49 50 /* 51 * Supply dst with the contents of the routing tables. 52 * If this won't fit in one packet, chop it up into several. 53 */ 54 supply(dst, flags, ifp) 55 struct sockaddr *dst; 56 int flags; 57 struct interface *ifp; 58 { 59 register struct rt_entry *rt; 60 struct netinfo *n = msg->rip_nets; 61 register struct rthash *rh; 62 struct rthash *base = hosthash; 63 int doinghost = 1, size; 64 struct sockaddr_ns *sns = (struct sockaddr_ns *) dst; 65 int (*output)() = afswitch[dst->sa_family].af_output; 66 67 msg->rip_cmd = ntohs(RIPCMD_RESPONSE); 68 again: 69 for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) 70 for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; rt = rt->rt_forw) { 71 size = (char *)n - (char *)msg; 72 if (size > MAXPACKETSIZE - sizeof (struct netinfo)) { 73 (*output)(flags, dst, size); 74 TRACE_OUTPUT(ifp, dst, size); 75 n = msg->rip_nets; 76 } 77 sns = (struct sockaddr_ns *)&rt->rt_dst; 78 xnnet(n->rip_dst[0]) = ns_netof(sns->sns_addr); 79 n->rip_metric = htons(min(rt->rt_metric + 1, HOPCNT_INFINITY)); 80 n++; 81 } 82 if (doinghost) { 83 doinghost = 0; 84 base = nethash; 85 goto again; 86 } 87 if (n != msg->rip_nets) { 88 size = (char *)n - (char *)msg; 89 (*output)(flags, dst, size); 90 TRACE_OUTPUT(ifp, dst, size); 91 } 92 } 93