rework interface metrics to invert perspective; other misc. fixes
[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
7892134c 8static char sccsid[] = "@(#)output.c 5.7 (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;
7892134c 63 register struct interface *ifp;
7e7de0c9
SL
64{
65 register struct rt_entry *rt;
7892134c 66 register struct netinfo *n = msg->rip_nets;
7e7de0c9
SL
67 register struct rthash *rh;
68 struct rthash *base = hosthash;
69 int doinghost = 1, size;
70 int (*output)() = afswitch[dst->sa_family].af_output;
7892134c 71 int (*sendroute)() = afswitch[dst->sa_family].af_sendroute;
f2ce7d44 72 int npackets = 0;
7e7de0c9
SL
73
74 msg->rip_cmd = RIPCMD_RESPONSE;
55d340a4 75 msg->rip_vers = RIPVERSION;
7e7de0c9
SL
76again:
77 for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++)
78 for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; rt = rt->rt_forw) {
4fad5a6e 79 /*
7892134c
MK
80 * Don't resend the information on the network
81 * from which it was received (unless sending
82 * in response to a query).
4fad5a6e 83 */
7127cc90
MK
84 if (ifp && rt->rt_ifp == ifp &&
85 (rt->rt_state & RTS_INTERFACE) == 0)
4fad5a6e
MK
86 continue;
87 if (rt->rt_state & RTS_EXTERNAL)
88 continue;
89 /*
90 * Limit the spread of subnet information
91 * to those who are interested.
92 */
93 if (doinghost == 0 && rt->rt_state & RTS_SUBNET) {
4fad5a6e
MK
94 if (rt->rt_dst.sa_family != dst->sa_family)
95 continue;
7892134c 96 if ((*sendroute)(rt, dst) == 0)
4fad5a6e
MK
97 continue;
98 }
7e7de0c9
SL
99 size = (char *)n - packet;
100 if (size > MAXPACKETSIZE - sizeof (struct netinfo)) {
7fe7fe74 101 (*output)(s, flags, dst, size);
7e7de0c9
SL
102 TRACE_OUTPUT(ifp, dst, size);
103 n = msg->rip_nets;
f2ce7d44 104 npackets++;
7e7de0c9
SL
105 }
106 n->rip_dst = rt->rt_dst;
55d340a4 107 n->rip_dst.sa_family = htons(n->rip_dst.sa_family);
7892134c 108 n->rip_metric = htonl(min(rt->rt_metric + 1, HOPCNT_INFINITY));
7e7de0c9
SL
109 n++;
110 }
111 if (doinghost) {
112 doinghost = 0;
113 base = nethash;
114 goto again;
115 }
f2ce7d44 116 if (n != msg->rip_nets || npackets == 0) {
7e7de0c9 117 size = (char *)n - packet;
7fe7fe74 118 (*output)(s, flags, dst, size);
7e7de0c9
SL
119 TRACE_OUTPUT(ifp, dst, size);
120 }
121}