xref: /csrg-svn/sbin/XNSrouted/output.c (revision 24317)
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