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
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]
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
43 * Apply the function "supply" to all active
44 * interfaces with a link-local address.
47 supplyall(struct sockaddr_in6
*sin6
, int rtstate
, struct interface
*skipif
,
50 struct interface
*ifp
;
52 for (ifp
= ifnet
; ifp
!= NULL
; ifp
= ifp
->int_next
) {
53 if ((ifp
->int_flags
& RIP6_IFF_UP
) == 0)
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",
61 (void) fflush(ftrace
);
65 if (ifp
->int_sock
== -1)
69 if (!IN6_IS_ADDR_LINKLOCAL(&ifp
->int_addr
))
71 supply(sin6
, ifp
, rtstate
, splith
);
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);
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)
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",
100 (void) fflush(ftrace
);
104 if (ifp
->int_sock
== -1)
112 * Output a preformed packet.
116 sendpacket(struct sockaddr_in6
*sin6
, struct interface
*ifp
, int size
,
119 if (sendto(ifp
->int_sock
, packet
, size
, flags
,
120 (struct sockaddr
*)sin6
, sizeof (*sin6
)) < 0) {
121 syslog(LOG_ERR
, "sendpacket: sendto: %m");
124 TRACE_OUTPUT(ifp
, sin6
, sizeof (struct rip6
));
129 * Supply dst with the contents of the routing tables.
130 * If this won't fit in one packet, chop it up into several.
133 supply(struct sockaddr_in6
*sin6
, struct interface
*ifp
, int rtstate
,
137 struct netinfo6
*n
= msg
->rip6_nets
;
139 int size
, i
, maxsize
;
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
)
155 for (rh
= net_hashes
[i
]; rh
< &net_hashes
[i
][ROUTEHASHSIZ
];
157 for (rt
= rh
->rt_forw
; rt
!= (struct rt_entry
*)rh
;
160 if (IN6_IS_ADDR_LINKLOCAL(&rt
->rt_dst
))
162 if (IN6_IS_ADDR_UNSPECIFIED(&rt
->rt_dst
))
165 /* do not send if private */
166 if (rt
->rt_state
& RTS_PRIVATE
)
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) {
177 rtmetric
= HOPCNT_INFINITY
;
181 rtmetric
= rt
->rt_metric
;
185 * For dynamic updates, limit update to routes
186 * with the specified state.
189 (rt
->rt_state
& rtstate
) == 0)
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
);
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
);
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
);