don't send net route to subnet gw's unless on subnet 0;
[unix-history] / usr / src / sbin / routed / output.c
CommitLineData
5ff67f98
DF
1/*
2 * Copyright (c) 1983 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 */
6
7e7de0c9 7#ifndef lint
09069ad0 8static char sccsid[] = "@(#)output.c 5.3 (Berkeley) %G%";
5ff67f98 9#endif not lint
7e7de0c9
SL
10
11/*
12 * Routing Table Management Daemon
13 */
7fe7fe74 14#include "defs.h"
7e7de0c9
SL
15
16/*
17 * Apply the function "f" to all non-passive
18 * interfaces. If the interface supports the
19 * use of broadcasting use it, otherwise address
20 * the output to the known router.
21 */
22toall(f)
23 int (*f)();
24{
25 register struct interface *ifp;
26 register struct sockaddr *dst;
7fe7fe74 27 register int flags;
7e7de0c9
SL
28 extern struct interface *ifnet;
29
30 for (ifp = ifnet; ifp; ifp = ifp->int_next) {
31 if (ifp->int_flags & IFF_PASSIVE)
32 continue;
33 dst = ifp->int_flags & IFF_BROADCAST ? &ifp->int_broadaddr :
34 ifp->int_flags & IFF_POINTOPOINT ? &ifp->int_dstaddr :
35 &ifp->int_addr;
55d340a4 36 flags = ifp->int_flags & IFF_INTERFACE ? MSG_DONTROUTE : 0;
7fe7fe74 37 (*f)(dst, flags, ifp);
7e7de0c9
SL
38 }
39}
40
41/*
42 * Output a preformed packet.
43 */
44/*ARGSUSED*/
7fe7fe74 45sendmsg(dst, flags, ifp)
7e7de0c9 46 struct sockaddr *dst;
7fe7fe74 47 int flags;
7e7de0c9
SL
48 struct interface *ifp;
49{
50
7fe7fe74 51 (*afswitch[dst->sa_family].af_output)(s, flags,
7e7de0c9
SL
52 dst, sizeof (struct rip));
53 TRACE_OUTPUT(ifp, dst, sizeof (struct rip));
54}
55
56/*
57 * Supply dst with the contents of the routing tables.
58 * If this won't fit in one packet, chop it up into several.
59 */
7fe7fe74 60supply(dst, flags, ifp)
7e7de0c9 61 struct sockaddr *dst;
7fe7fe74 62 int flags;
7e7de0c9
SL
63 struct interface *ifp;
64{
65 register struct rt_entry *rt;
66 struct netinfo *n = msg->rip_nets;
67 register struct rthash *rh;
68 struct rthash *base = hosthash;
69 int doinghost = 1, size;
70 int (*output)() = afswitch[dst->sa_family].af_output;
4fad5a6e 71 int (*sendsubnet)() = afswitch[dst->sa_family].af_sendsubnet;
7e7de0c9
SL
72
73 msg->rip_cmd = RIPCMD_RESPONSE;
55d340a4 74 msg->rip_vers = RIPVERSION;
7e7de0c9
SL
75again:
76 for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++)
77 for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; rt = rt->rt_forw) {
4fad5a6e
MK
78 /*
79 * Don't resend the information
80 * on the network from which it was received.
81 */
82 if (ifp && rt->rt_ifp == ifp)
83 continue;
84 if (rt->rt_state & RTS_EXTERNAL)
85 continue;
86 /*
87 * Limit the spread of subnet information
88 * to those who are interested.
89 */
90 if (doinghost == 0 && rt->rt_state & RTS_SUBNET) {
91 if (ifp && (ifp->int_flags & IFF_SUBNET) == 0)
92 continue;
93 if (rt->rt_dst.sa_family != dst->sa_family)
94 continue;
09069ad0 95 if ((*sendsubnet)(rt, dst) == 0)
4fad5a6e
MK
96 continue;
97 }
7e7de0c9
SL
98 size = (char *)n - packet;
99 if (size > MAXPACKETSIZE - sizeof (struct netinfo)) {
7fe7fe74 100 (*output)(s, flags, dst, size);
7e7de0c9
SL
101 TRACE_OUTPUT(ifp, dst, size);
102 n = msg->rip_nets;
103 }
104 n->rip_dst = rt->rt_dst;
55d340a4 105 n->rip_dst.sa_family = htons(n->rip_dst.sa_family);
9b1c54bf 106 n->rip_metric = htonl(min(rt->rt_metric + 1, HOPCNT_INFINITY));
7e7de0c9
SL
107 n++;
108 }
109 if (doinghost) {
110 doinghost = 0;
111 base = nethash;
112 goto again;
113 }
114 if (n != msg->rip_nets) {
115 size = (char *)n - packet;
7fe7fe74 116 (*output)(s, flags, dst, size);
7e7de0c9
SL
117 TRACE_OUTPUT(ifp, dst, size);
118 }
119}