/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1999 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/*
* Portions of this source code were derived from Berkeley 4.3 BSD
* under license from the Regents of the University of California.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Routing Table Management Daemon
*/
#include "defs.h"
/*
* Return a pointer to the specified option buffer.
* If not found return NULL.
*/
static void *
{
}
}
return (NULL);
}
/*
* Read a packet and passes it to rip_input() for processing.
*/
void
{
int len;
/*
* Only syslog if a true error occurred.
*/
return;
}
if (len == 0)
return;
sizeof (buf1));
}
/* Ignore packets > 64k or control buffers that don't fit */
"Truncated message: msg_flags 0x%x from %s\n",
}
return;
}
buf1);
}
return;
}
}
/*
* Process a newly received packet.
*/
static void
{
struct netinfo6 *n;
int newsize;
}
/*
* If the packet is recevied on an interface with IFF_NORTEXCH flag set,
* we ignore the packet.
*/
"Ignore received RIPng packet on %s "
"(no route exchange on interface)\n",
}
return;
}
"Bad version number %d in packet from %s\n",
}
return;
}
"Non-zero reserved octets found in packet from "
"%s\n",
buf1);
}
}
case RIPCMD6_REQUEST: /* multicasted request */
ifp->int_ipackets++;
newsize = 0;
/*
* Adjust size by the length of the command, version and
* reserved fields (which are in total 32-bit aligned).
*/
/*
* From section 2.4.1 of RFC 2080:
*
* If there is exactly one entry in the request with a
* destination prefix of zero, a prefix length of zero and
* an infinite metric, then supply the entire routing
* table.
*/
n->rip6_prefix_length == 0 &&
n->rip6_metric == HOPCNT_INFINITY) {
n->rip6_prefix_length);
if (IN6_IS_ADDR_UNSPECIFIED(&prefix)) {
return;
}
}
if (n->rip6_prefix_length > IPV6_ABITS) {
"Bad prefix length %d in request "
"from %s\n",
n->rip6_prefix_length, buf1);
}
continue;
}
if (IN6_IS_ADDR_LINKLOCAL(&n->rip6_prefix) ||
IN6_IS_ADDR_MULTICAST(&n->rip6_prefix)) {
"Bad prefix %s in request from "
"%s\n",
(void *)&n->rip6_prefix, buf2,
sizeof (buf2)),
buf1);
}
continue;
}
n->rip6_prefix_length);
}
if (size > 0) {
"Ignoring %d octets of trailing data in "
"request from %s\n",
}
}
/*
* Adjust newsize by the length of the command, version
* and reserved fields (which are in total 32-bit
* aligned).
*/
}
return;
case RIPCMD6_RESPONSE:
if (hopcount != IPV6_MAX_HOPS) {
"Bad hop count %d in response from %s\n",
}
return;
}
"Bad source port %d in response from %s\n",
}
return;
}
"Bad source address (not link-local) in "
"response from %s\n", buf1);
}
return;
}
ifp->int_ipackets++;
/*
* Adjust size by the length of the command, version and
* reserved fields (which are in total 32-bit aligned).
*/
/*
* From section 2.1.1 of RFC 2080:
*
* This is a next hop RTE if n->rip6_metric is set to
* HOPCNT_NEXTHOP. If the next hop address (which is
* placed in the prefix field of this special RTE) is
* unspecified or is not a link-local address, then use
* the originator's address instead (effectively turning
* off next hop RTE processing.)
*/
if (n->rip6_metric == HOPCNT_NEXTHOP) {
/*
* First check to see if the unspecified address
* was given as the next hop address. This is
* the correct way of specifying the end of use
* of a next hop address.
*/
if (IN6_IS_ADDR_UNSPECIFIED(&n->rip6_prefix)) {
continue;
}
/*
* A next hop address that is not a link-local
* address is treated as the unspecified one.
* Trace this event if input tracing is enabled.
*/
if (!IN6_IS_ADDR_LINKLOCAL(&n->rip6_prefix)) {
"Bad next hop %s in "
"response from %s\n",
(void *)&n->rip6_prefix,
buf1);
}
continue;
}
/*
* Verify that the next hop address is not one
* of our own.
*/
(char *)&sa) < 0) {
"rip_input: "
"ioctl (verify my address): %m");
return;
}
"Bad next hop %s is self "
"in response from %s\n",
(void *)&n->rip6_prefix,
buf1);
}
continue;
}
nexthop = n->rip6_prefix;
continue;
}
if (foundnexthop)
else
if (n->rip6_metric > HOPCNT_INFINITY ||
n->rip6_metric < 1) {
"Bad metric %d in response from "
"%s\n",
n->rip6_metric, buf1);
}
continue;
}
if (n->rip6_prefix_length > IPV6_ABITS) {
"Bad prefix length %d in response "
"from %s\n",
n->rip6_prefix_length, buf1);
}
continue;
}
if (IN6_IS_ADDR_LINKLOCAL(&n->rip6_prefix) ||
IN6_IS_ADDR_MULTICAST(&n->rip6_prefix)) {
"Bad prefix %s in response from "
"%s\n",
(void *)&n->rip6_prefix, buf2,
sizeof (buf2)),
buf1);
}
continue;
}
/* Include metric for incoming interface */
n->rip6_prefix_length);
if (n->rip6_metric < HOPCNT_INFINITY) {
gate, n->rip6_prefix_length,
n->rip6_metric, n->rip6_route_tag,
}
continue;
}
/*
* If the supplied metric is at least HOPCNT_INFINITY
* and the current metric of the route is
* HOPCNT_INFINITY, then this particular RTE is ignored.
*/
if (n->rip6_metric >= HOPCNT_INFINITY &&
continue;
/*
* From section 2.4.2 of RFC 2080:
*
* Update if any one of the following is true
*
* 1) From current gateway and a different metric.
* 2) From current gateway and a different index.
* 3) A shorter (smaller) metric.
* 4) Equivalent metric and an age at least
* one-half of EXPIRE_TIME.
*
* Otherwise, update timer for the interface on which
* the packet arrived.
*/
} else if (n->rip6_metric < HOPCNT_INFINITY) {
}
}
}
return;
default:
"Bad command %d in packet from %s\n",
}
return;
}
}
/*
* If changes have occurred, and if we have not sent a multicast
* recently, send a dynamic update. This update is sent only
* on interfaces other than the one on which we received notice
* of the change. If we are within MIN_WAIT_TIME of a full update,
* don't bother sending; if we just sent a dynamic update
* and set a timer (nextmcast), delay until that time.
* If we just sent a full update, delay the dynamic update.
* Set a timer for a randomized value to suppress additional
* dynamic updates until it expires; if we delayed sending
* the current changes, set needupdate.
*/
void
{
int delay;
return;
/* BEGIN CSTYLED */
/* END CSTYLED */
TRACE_ACTION("send dynamic update",
} else {
TRACE_ACTION("delay dynamic update",
}
MAX_WAIT_TIME * 1000000);
if (tracing & ACTION_BIT) {
"inhibit dynamic update for %d msec\n",
delay / 1000);
}
/*
* If the next possibly dynamic update
* is within MIN_WAIT_TIME of the next full
* update, force the delay past the full
* update, or we might send a dynamic update
* just before the full update.
*/
}
}
}