xref: /original-bsd/sbin/routed/output.c (revision f0fd5f8a)
1 #ifndef lint
2 static char sccsid[] = "@(#)output.c	4.1 11/02/82";
3 #endif
4 
5 /*
6  * Routing Table Management Daemon
7  */
8 #include "router.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 	extern struct interface *ifnet;
22 
23 	for (ifp = ifnet; ifp; ifp = ifp->int_next) {
24 		if (ifp->int_flags & IFF_PASSIVE)
25 			continue;
26 		dst = ifp->int_flags & IFF_BROADCAST ? &ifp->int_broadaddr :
27 		      ifp->int_flags & IFF_POINTOPOINT ? &ifp->int_dstaddr :
28 		      &ifp->int_addr;
29 		(*f)(dst, ifp->int_flags & IFF_INTERFACE, ifp);
30 	}
31 }
32 
33 /*
34  * Output a preformed packet.
35  */
36 /*ARGSUSED*/
37 sendmsg(dst, dontroute, ifp)
38 	struct sockaddr *dst;
39 	int dontroute;
40 	struct interface *ifp;
41 {
42 
43 	(*afswitch[dst->sa_family].af_output)(dontroute ? snoroute : s,
44 		dst, sizeof (struct rip));
45 	TRACE_OUTPUT(ifp, dst, sizeof (struct rip));
46 }
47 
48 /*
49  * Supply dst with the contents of the routing tables.
50  * If this won't fit in one packet, chop it up into several.
51  */
52 supply(dst, dontroute, ifp)
53 	struct sockaddr *dst;
54 	struct interface *ifp;
55 {
56 	register struct rt_entry *rt;
57 	struct netinfo *n = msg->rip_nets;
58 	register struct rthash *rh;
59 	struct rthash *base = hosthash;
60 	int doinghost = 1, size;
61 	int (*output)() = afswitch[dst->sa_family].af_output;
62 	int sto = dontroute ? snoroute : s;
63 
64 	msg->rip_cmd = RIPCMD_RESPONSE;
65 again:
66 	for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++)
67 	for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; rt = rt->rt_forw) {
68 		size = (char *)n - packet;
69 		if (size > MAXPACKETSIZE - sizeof (struct netinfo)) {
70 			(*output)(sto, dst, size);
71 			TRACE_OUTPUT(ifp, dst, size);
72 			n = msg->rip_nets;
73 		}
74 		n->rip_dst = rt->rt_dst;
75 		n->rip_metric = min(rt->rt_metric + 1, HOPCNT_INFINITY);
76 		n++;
77 	}
78 	if (doinghost) {
79 		doinghost = 0;
80 		base = nethash;
81 		goto again;
82 	}
83 	if (n != msg->rip_nets) {
84 		size = (char *)n - packet;
85 		(*output)(sto, dst, size);
86 		TRACE_OUTPUT(ifp, dst, size);
87 	}
88 }
89