install correct aliases file
[unix-history] / usr / src / sbin / routed / output.c
CommitLineData
5ff67f98 1/*
2d222ff5 2 * Copyright (c) 1983, 1988 Regents of the University of California.
0eb85d71
KB
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
b8c620d6
KB
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
5ff67f98
DF
16 */
17
7e7de0c9 18#ifndef lint
b8c620d6 19static char sccsid[] = "@(#)output.c 5.11 (Berkeley) %G%";
0eb85d71 20#endif /* not lint */
7e7de0c9
SL
21
22/*
23 * Routing Table Management Daemon
24 */
7fe7fe74 25#include "defs.h"
7e7de0c9
SL
26
27/*
28 * Apply the function "f" to all non-passive
29 * interfaces. If the interface supports the
30 * use of broadcasting use it, otherwise address
31 * the output to the known router.
32 */
33toall(f)
34 int (*f)();
35{
36 register struct interface *ifp;
37 register struct sockaddr *dst;
7fe7fe74 38 register int flags;
7e7de0c9
SL
39 extern struct interface *ifnet;
40
41 for (ifp = ifnet; ifp; ifp = ifp->int_next) {
42 if (ifp->int_flags & IFF_PASSIVE)
43 continue;
44 dst = ifp->int_flags & IFF_BROADCAST ? &ifp->int_broadaddr :
45 ifp->int_flags & IFF_POINTOPOINT ? &ifp->int_dstaddr :
46 &ifp->int_addr;
55d340a4 47 flags = ifp->int_flags & IFF_INTERFACE ? MSG_DONTROUTE : 0;
7fe7fe74 48 (*f)(dst, flags, ifp);
7e7de0c9
SL
49 }
50}
51
52/*
53 * Output a preformed packet.
54 */
55/*ARGSUSED*/
7fe7fe74 56sendmsg(dst, flags, ifp)
7e7de0c9 57 struct sockaddr *dst;
7fe7fe74 58 int flags;
7e7de0c9
SL
59 struct interface *ifp;
60{
61
7fe7fe74 62 (*afswitch[dst->sa_family].af_output)(s, flags,
7e7de0c9
SL
63 dst, sizeof (struct rip));
64 TRACE_OUTPUT(ifp, dst, sizeof (struct rip));
65}
66
67/*
68 * Supply dst with the contents of the routing tables.
69 * If this won't fit in one packet, chop it up into several.
70 */
7fe7fe74 71supply(dst, flags, ifp)
7e7de0c9 72 struct sockaddr *dst;
7fe7fe74 73 int flags;
7892134c 74 register struct interface *ifp;
7e7de0c9
SL
75{
76 register struct rt_entry *rt;
7892134c 77 register struct netinfo *n = msg->rip_nets;
7e7de0c9
SL
78 register struct rthash *rh;
79 struct rthash *base = hosthash;
80 int doinghost = 1, size;
81 int (*output)() = afswitch[dst->sa_family].af_output;
7892134c 82 int (*sendroute)() = afswitch[dst->sa_family].af_sendroute;
f2ce7d44 83 int npackets = 0;
7e7de0c9
SL
84
85 msg->rip_cmd = RIPCMD_RESPONSE;
55d340a4 86 msg->rip_vers = RIPVERSION;
eabc591a 87 bzero(msg->rip_res1, sizeof(msg->rip_res1));
7e7de0c9
SL
88again:
89 for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++)
90 for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; rt = rt->rt_forw) {
4fad5a6e 91 /*
7892134c
MK
92 * Don't resend the information on the network
93 * from which it was received (unless sending
94 * in response to a query).
4fad5a6e 95 */
7127cc90
MK
96 if (ifp && rt->rt_ifp == ifp &&
97 (rt->rt_state & RTS_INTERFACE) == 0)
4fad5a6e
MK
98 continue;
99 if (rt->rt_state & RTS_EXTERNAL)
100 continue;
101 /*
102 * Limit the spread of subnet information
103 * to those who are interested.
104 */
105 if (doinghost == 0 && rt->rt_state & RTS_SUBNET) {
4fad5a6e
MK
106 if (rt->rt_dst.sa_family != dst->sa_family)
107 continue;
7892134c 108 if ((*sendroute)(rt, dst) == 0)
4fad5a6e
MK
109 continue;
110 }
7e7de0c9
SL
111 size = (char *)n - packet;
112 if (size > MAXPACKETSIZE - sizeof (struct netinfo)) {
7fe7fe74 113 (*output)(s, flags, dst, size);
7e7de0c9 114 TRACE_OUTPUT(ifp, dst, size);
2d222ff5
MK
115 /*
116 * If only sending to ourselves,
117 * one packet is enough to monitor interface.
118 */
119 if ((ifp->int_flags &
120 (IFF_BROADCAST | IFF_POINTOPOINT | IFF_REMOTE)) == 0)
121 return;
7e7de0c9 122 n = msg->rip_nets;
f2ce7d44 123 npackets++;
7e7de0c9
SL
124 }
125 n->rip_dst = rt->rt_dst;
55d340a4 126 n->rip_dst.sa_family = htons(n->rip_dst.sa_family);
2d222ff5 127 n->rip_metric = htonl(rt->rt_metric);
7e7de0c9
SL
128 n++;
129 }
130 if (doinghost) {
131 doinghost = 0;
132 base = nethash;
133 goto again;
134 }
f2ce7d44 135 if (n != msg->rip_nets || npackets == 0) {
7e7de0c9 136 size = (char *)n - packet;
7fe7fe74 137 (*output)(s, flags, dst, size);
7e7de0c9
SL
138 TRACE_OUTPUT(ifp, dst, size);
139 }
140}