dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / cmd-inet / usr.lib / in.ripngd / output.c
blob72fa31b138b46943e89e8a64ff9fad8487d38875
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
23 * Copyright 1999 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
31 * Portions of this source code were derived from Berkeley 4.3 BSD
32 * under license from the Regents of the University of California.
35 #ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.1 */
38 * Routing Table Management Daemon
40 #include "defs.h"
43 * Apply the function "supply" to all active
44 * interfaces with a link-local address.
46 void
47 supplyall(struct sockaddr_in6 *sin6, int rtstate, struct interface *skipif,
48 boolean_t splith)
50 struct interface *ifp;
52 for (ifp = ifnet; ifp != NULL; ifp = ifp->int_next) {
53 if ((ifp->int_flags & RIP6_IFF_UP) == 0)
54 continue;
55 if (ifp->int_flags & RIP6_IFF_NORTEXCH) {
56 if (tracing & OUTPUT_BIT) {
57 (void) fprintf(ftrace,
58 "Suppress sending RIPng response packet "
59 "on %s (no route exchange on interface)\n",
60 ifp->int_name);
61 (void) fflush(ftrace);
63 continue;
65 if (ifp->int_sock == -1)
66 continue;
67 if (ifp == skipif)
68 continue;
69 if (!IN6_IS_ADDR_LINKLOCAL(&ifp->int_addr))
70 continue;
71 supply(sin6, ifp, rtstate, splith);
75 static void
76 solicit(struct sockaddr_in6 *sin6, struct interface *ifp)
78 msg->rip6_cmd = RIPCMD6_REQUEST;
79 msg->rip6_vers = RIPVERSION6;
80 msg->rip6_nets[0].rip6_prefix = in6addr_any;
81 msg->rip6_nets[0].rip6_prefix_length = 0;
82 msg->rip6_nets[0].rip6_metric = HOPCNT_INFINITY;
83 sendpacket(sin6, ifp, sizeof (struct rip6), 0);
86 void
87 solicitall(struct sockaddr_in6 *sin6)
89 struct interface *ifp;
91 for (ifp = ifnet; ifp != NULL; ifp = ifp->int_next) {
92 if ((ifp->int_flags & RIP6_IFF_UP) == 0)
93 continue;
94 if (ifp->int_flags & RIP6_IFF_NORTEXCH) {
95 if (tracing & OUTPUT_BIT) {
96 (void) fprintf(ftrace,
97 "Suppress sending RIPng request packet "
98 "on %s (no route exchange on interface)\n",
99 ifp->int_name);
100 (void) fflush(ftrace);
102 continue;
104 if (ifp->int_sock == -1)
105 continue;
106 solicit(sin6, ifp);
112 * Output a preformed packet.
114 /*ARGSUSED*/
115 void
116 sendpacket(struct sockaddr_in6 *sin6, struct interface *ifp, int size,
117 int flags)
119 if (sendto(ifp->int_sock, packet, size, flags,
120 (struct sockaddr *)sin6, sizeof (*sin6)) < 0) {
121 syslog(LOG_ERR, "sendpacket: sendto: %m");
122 return;
124 TRACE_OUTPUT(ifp, sin6, sizeof (struct rip6));
125 ifp->int_opackets++;
129 * Supply dst with the contents of the routing tables.
130 * If this won't fit in one packet, chop it up into several.
132 void
133 supply(struct sockaddr_in6 *sin6, struct interface *ifp, int rtstate,
134 boolean_t splith)
136 struct rt_entry *rt;
137 struct netinfo6 *n = msg->rip6_nets;
138 struct rthash *rh;
139 int size, i, maxsize;
140 uint8_t rtmetric;
142 msg->rip6_cmd = RIPCMD6_RESPONSE;
143 msg->rip6_vers = RIPVERSION6;
146 * Initialize maxsize to the size of the largest RIPng packet supported
147 * on the outgoing interface.
149 maxsize = ifp->int_mtu - sizeof (ip6_t) - sizeof (struct udphdr);
151 for (i = IPV6_ABITS; i >= 0; i--) {
152 if (net_hashes[i] == NULL)
153 continue;
155 for (rh = net_hashes[i]; rh < &net_hashes[i][ROUTEHASHSIZ];
156 rh++) {
157 for (rt = rh->rt_forw; rt != (struct rt_entry *)rh;
158 rt = rt->rt_forw) {
160 if (IN6_IS_ADDR_LINKLOCAL(&rt->rt_dst))
161 continue;
162 if (IN6_IS_ADDR_UNSPECIFIED(&rt->rt_dst))
163 continue;
165 /* do not send if private */
166 if (rt->rt_state & RTS_PRIVATE)
167 continue;
170 * Don't resend the information
171 * on the network from which it was received.
173 if (splith && rt->rt_ifp != NULL &&
174 strcmp(ifp->int_ifbase,
175 rt->rt_ifp->int_ifbase) == 0) {
176 if (dopoison)
177 rtmetric = HOPCNT_INFINITY;
178 else
179 continue;
180 } else {
181 rtmetric = rt->rt_metric;
185 * For dynamic updates, limit update to routes
186 * with the specified state.
188 if (rtstate != 0 &&
189 (rt->rt_state & rtstate) == 0)
190 continue;
193 * Check if there is space for another RTE. If
194 * not, send the packet built up and reset n for
195 * the remaining RTEs.
197 size = (char *)n - packet;
198 if (size > maxsize - sizeof (struct netinfo6)) {
199 sendpacket(sin6, ifp, size, 0);
200 TRACE_OUTPUT(ifp, sin6, size);
201 n = msg->rip6_nets;
203 n->rip6_prefix = rt->rt_dst;
204 n->rip6_route_tag = rt->rt_tag;
205 n->rip6_prefix_length = rt->rt_prefix_length;
206 n->rip6_metric = min(rtmetric, HOPCNT_INFINITY);
207 n++;
208 } /* end of hash chain */
209 } /* end of particular prefix length */
210 } /* end of all prefix lengths */
211 if (n != msg->rip6_nets) {
212 size = (char *)n - packet;
213 sendpacket(sin6, ifp, size, 0);
214 TRACE_OUTPUT(ifp, sin6, size);