summaryrefslogtreecommitdiffstats
path: root/usr.sbin/pim6dd
diff options
context:
space:
mode:
authorume <ume@FreeBSD.org>2001-06-03 18:16:39 +0000
committerume <ume@FreeBSD.org>2001-06-03 18:16:39 +0000
commit2dd555017d992610a09beeff1425734afa740df7 (patch)
tree28a1d4bb2f4a9efac2f863f324f9457a2b751cab /usr.sbin/pim6dd
parent27ef13f896793993f071c86908a1c7a1def39c8d (diff)
downloadFreeBSD-src-2dd555017d992610a09beeff1425734afa740df7.zip
FreeBSD-src-2dd555017d992610a09beeff1425734afa740df7.tar.gz
Remove pim6[ds]d from the tree. The software had a restrictive license
than we can handle. pim6[ds]d are available as ports instead.
Diffstat (limited to 'usr.sbin/pim6dd')
-rw-r--r--usr.sbin/pim6dd/LICENSE.mrouted49
-rw-r--r--usr.sbin/pim6dd/LICENSE.pimd48
-rw-r--r--usr.sbin/pim6dd/Makefile89
-rw-r--r--usr.sbin/pim6dd/VERSION2
-rw-r--r--usr.sbin/pim6dd/callout.c256
-rw-r--r--usr.sbin/pim6dd/config.c792
-rw-r--r--usr.sbin/pim6dd/debug.c565
-rw-r--r--usr.sbin/pim6dd/debug.h121
-rw-r--r--usr.sbin/pim6dd/defs.h606
-rw-r--r--usr.sbin/pim6dd/inet6.c288
-rw-r--r--usr.sbin/pim6dd/kern.c415
-rw-r--r--usr.sbin/pim6dd/main.c720
-rw-r--r--usr.sbin/pim6dd/mld6.c548
-rw-r--r--usr.sbin/pim6dd/mld6.h48
-rw-r--r--usr.sbin/pim6dd/mld6_proto.c523
-rw-r--r--usr.sbin/pim6dd/mrt.c803
-rw-r--r--usr.sbin/pim6dd/mrt.h228
-rw-r--r--usr.sbin/pim6dd/pathnames.h63
-rw-r--r--usr.sbin/pim6dd/pim6.c441
-rw-r--r--usr.sbin/pim6dd/pim6_proto.c1596
-rw-r--r--usr.sbin/pim6dd/pim6dd.8132
-rw-r--r--usr.sbin/pim6dd/pim6dd.conf.5165
-rw-r--r--usr.sbin/pim6dd/pimdd.h553
-rw-r--r--usr.sbin/pim6dd/route.c659
-rw-r--r--usr.sbin/pim6dd/routesock.c373
-rw-r--r--usr.sbin/pim6dd/timer.c336
-rw-r--r--usr.sbin/pim6dd/trace.c540
-rw-r--r--usr.sbin/pim6dd/trace.h204
-rw-r--r--usr.sbin/pim6dd/vers.c2
-rw-r--r--usr.sbin/pim6dd/vif.c535
-rw-r--r--usr.sbin/pim6dd/vif.h292
31 files changed, 0 insertions, 11992 deletions
diff --git a/usr.sbin/pim6dd/LICENSE.mrouted b/usr.sbin/pim6dd/LICENSE.mrouted
deleted file mode 100644
index e03eb82..0000000
--- a/usr.sbin/pim6dd/LICENSE.mrouted
+++ /dev/null
@@ -1,49 +0,0 @@
-$FreeBSD$
-
-The mrouted program is covered by the following license. Use of the
-mrouted program represents acceptance of these terms and conditions.
-
-1. STANFORD grants to LICENSEE a nonexclusive and nontransferable license
-to use, copy and modify the computer software ``mrouted'' (hereinafter
-called the ``Program''), upon the terms and conditions hereinafter set
-out and until Licensee discontinues use of the Licensed Program.
-
-2. LICENSEE acknowledges that the Program is a research tool still in
-the development state, that it is being supplied ``as is,'' without any
-accompanying services from STANFORD, and that this license is entered
-into in order to encourage scientific collaboration aimed at further
-development and application of the Program.
-
-3. LICENSEE may copy the Program and may sublicense others to use object
-code copies of the Program or any derivative version of the Program.
-All copies must contain all copyright and other proprietary notices found
-in the Program as provided by STANFORD. Title to copyright to the
-Program remains with STANFORD.
-
-4. LICENSEE may create derivative versions of the Program. LICENSEE
-hereby grants STANFORD a royalty-free license to use, copy, modify,
-distribute and sublicense any such derivative works. At the time
-LICENSEE provides a copy of a derivative version of the Program to a
-third party, LICENSEE shall provide STANFORD with one copy of the source
-code of the derivative version at no charge to STANFORD.
-
-5. STANFORD MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
-By way of example, but not limitation, STANFORD MAKES NO REPRESENTATION
-OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR
-THAT THE USE OF THE LICENSED PROGRAM WILL NOT INFRINGE ANY PATENTS,
-COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. STANFORD shall not be held liable
-for any liability nor for any direct, indirect or consequential damages
-with respect to any claim by LICENSEE or any third party on account of or
-arising from this Agreement or use of the Program.
-
-6. This agreement shall be construed, interpreted and applied in
-accordance with the State of California and any legal action arising
-out of this Agreement or use of the Program shall be filed in a court
-in the State of California.
-
-7. Nothing in this Agreement shall be construed as conferring rights to
-use in advertising, publicity or otherwise any trademark or the name
-of ``Stanford''.
-
-The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
-Leland Stanford Junior University.
diff --git a/usr.sbin/pim6dd/LICENSE.pimd b/usr.sbin/pim6dd/LICENSE.pimd
deleted file mode 100644
index d88a457..0000000
--- a/usr.sbin/pim6dd/LICENSE.pimd
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 1998 by the University of Southern California.
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation in source and binary forms for lawful
- * purposes and without fee is hereby granted, provided
- * that the above copyright notice appear in all copies and that both
- * the copyright notice and this permission notice appear in supporting
- * documentation, and that any documentation, advertising materials,
- * and other materials related to such distribution and use acknowledge
- * that the software was developed by the University of Southern
- * California and/or Information Sciences Institute.
- * The name of the University of Southern California may not
- * be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THE UNIVERSITY OF SOUTHERN CALIFORNIA DOES NOT MAKE ANY REPRESENTATIONS
- * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. THIS SOFTWARE IS
- * PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
- * NON-INFRINGEMENT.
- *
- * IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT,
- * TORT, OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH,
- * THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Other copyrights might apply to parts of this software and are so
- * noted when applicable.
- */
-/*
- * Questions concerning this software should be directed to
- * Pavlin Ivanov Radoslavov (pavlin@catarina.usc.edu)
- *
- * $Id: LICENSE.pimd,v 1.1.1.1 1999/08/08 23:30:50 itojun Exp $
- */
-/*
- * Part of this program has been derived from mrouted.
- * The mrouted program is covered by the license in the accompanying file
- * named "LICENSE.mrouted".
- *
- * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
- * Leland Stanford Junior University.
- *
- * $FreeBSD$
- */
diff --git a/usr.sbin/pim6dd/Makefile b/usr.sbin/pim6dd/Makefile
deleted file mode 100644
index 4f1fd56..0000000
--- a/usr.sbin/pim6dd/Makefile
+++ /dev/null
@@ -1,89 +0,0 @@
-# Copyright (c) 1998 WIDE Project. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-# 1. Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-# 3. Neither the name of the project nor the names of its contributors
-# may be used to endorse or promote products derived from this software
-# without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
-# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-# SUCH DAMAGE.
-
-# Copyright (c) 1998 by the University of Oregon.
-# All rights reserved.
-#
-# Permission to use, copy, modify, and distribute this software and
-# its documentation in source and binary forms for lawful
-# purposes and without fee is hereby granted, provided
-# that the above copyright notice appear in all copies and that both
-# the copyright notice and this permission notice appear in supporting
-# documentation, and that any documentation, advertising materials,
-# and other materials related to such distribution and use acknowledge
-# that the software was developed by the University of Oregon.
-# The name of the University of Oregon may not be used to endorse or
-# promote products derived from this software without specific prior
-# written permission.
-#
-# THE UNIVERSITY OF OREGON DOES NOT MAKE ANY REPRESENTATIONS
-# ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. THIS SOFTWARE IS
-# PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
-# INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
-# NON-INFRINGEMENT.
-#
-# IN NO EVENT SHALL UO, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
-# SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT,
-# TORT, OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH,
-# THE USE OR PERFORMANCE OF THIS SOFTWARE.
-#
-# Other copyrights might apply to parts of this software and are so
-# noted when applicable.
-#
-#
-# Questions concerning this software should be directed to
-# Kurt Windisch (kurtw@antc.uoregon.edu)
-#
-# $Id: Makefile,v 1.2 2000/02/25 06:32:22 itojun Exp $
-#
-#
-#Part of this program has been derived from PIM sparse-mode pimd.
-#The pimd program is covered by the license in the accompanying file
-#named "LICENSE.pimd".
-#
-#The pimd program is COPYRIGHT 1998 by University of Southern California.
-#
-#Part of this program has been derived from mrouted.
-#The mrouted program is covered by the license in the accompanying file
-#named "LICENSE.mrouted".
-#
-#The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
-#Leland Stanford Junior University.
-#
-# $FreeBSD$
-
-PROG= pim6dd
-SRCS= mld6.c mld6_proto.c\
- inet6.c kern.c main.c config.c debug.c routesock.c vers.c callout.c\
- route.c vif.c timer.c mrt.c pim6.c pim6_proto.c trace.c
-
-CFLAGS+=-Wall
-CFLAGS+=-DINET6 -DPIM -DIOCTL_OK_ON_RAW_SOCKET -DHAVE_GETIFADDRS
-
-MAN= pim6dd.conf.5 pim6dd.8
-
-.include <bsd.prog.mk>
diff --git a/usr.sbin/pim6dd/VERSION b/usr.sbin/pim6dd/VERSION
deleted file mode 100644
index 69e5262..0000000
--- a/usr.sbin/pim6dd/VERSION
+++ /dev/null
@@ -1,2 +0,0 @@
-# $FreeBSD$
-0.2.1.0-alpha15
diff --git a/usr.sbin/pim6dd/callout.c b/usr.sbin/pim6dd/callout.c
deleted file mode 100644
index 6cf96de..0000000
--- a/usr.sbin/pim6dd/callout.c
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * The mrouted program is covered by the license in the accompanying file
- * named "LICENSE.mrouted". Use of the mrouted program represents acceptance
- * of the terms and conditions listed in that file.
- *
- * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
- * Leland Stanford Junior University.
- *
- *
- * callout.c,v 3.8.4.5 1997/05/16 20:18:25 fenner Exp
- *
- * $FreeBSD$
- */
-
-#include "defs.h"
-
-/* the code below implements a callout queue */
-static int id = 0;
-static struct timeout_q *Q = 0; /* pointer to the beginning of timeout queue */
-
-struct timeout_q {
- struct timeout_q *next; /* next event */
- int id;
- cfunc_t func; /* function to call */
- void *data; /* func's data */
- int time; /* time offset to next event*/
-};
-
-#ifdef CALLOUT_DEBUG
-static void print_Q __P((void));
-#else
-#define print_Q()
-#endif
-
-void
-callout_init()
-{
- if (Q) {
- log(LOG_ERR, 0, "timer used before callout_init()");
- exit(1);
- }
- Q = (struct timeout_q *) 0;
-}
-
-void
-free_all_callouts()
-{
- struct timeout_q *p;
-
- while (Q) {
- p = Q;
- Q = Q->next;
- free(p);
- }
-}
-
-
-/*
- * elapsed_time seconds have passed; perform all the events that should
- * happen.
- */
-void
-age_callout_queue(elapsed_time)
- int elapsed_time;
-{
- struct timeout_q *ptr, *expQ;
-
-#ifdef CALLOUT_DEBUG
- IF_DEBUG(DEBUG_TIMEOUT)
- log(LOG_DEBUG, 0, "aging queue (elapsed time %d):", elapsed_time);
- print_Q();
-#endif
-
- expQ = Q;
- ptr = NULL;
-
- while (Q) {
- if (Q->time > elapsed_time) {
- Q->time -= elapsed_time;
- if (ptr) {
- ptr->next = NULL;
- break;
- }
- return;
- } else {
- elapsed_time -= Q->time;
- ptr = Q;
- Q = Q->next;
- }
- }
-
- /* handle queue of expired timers */
- while (expQ) {
- ptr = expQ;
- if (ptr->func)
- ptr->func(ptr->data);
- expQ = expQ->next;
- free(ptr);
- }
-}
-
-/*
- * Return in how many seconds age_callout_queue() would like to be called.
- * Return -1 if there are no events pending.
- */
-int
-timer_nextTimer()
-{
- if (Q) {
- if (Q->time < 0) {
- log(LOG_WARNING, 0, "timer_nextTimer top of queue says %d",
- Q->time);
- return 0;
- }
- return Q->time;
- }
- return -1;
-}
-
-/*
- * sets the timer
- */
-int
-timer_setTimer(delay, action, data)
- int delay; /* number of units for timeout */
- cfunc_t action; /* function to be called on timeout */
- void *data; /* what to call the timeout function with */
-{
- struct timeout_q *ptr, *node, *prev;
-
-#ifdef CALLOUT_DEBUG
- IF_DEBUG(DEBUG_TIMEOUT)
- log(LOG_DEBUG, 0, "setting timer:");
- print_Q();
-#endif
-
- /* create a node */
- node = (struct timeout_q *)malloc(sizeof(struct timeout_q));
- if (node == 0) {
- log(LOG_WARNING, 0, "Malloc Failed in timer_settimer\n");
- return -1;
- }
- node->func = action;
- node->data = data;
- node->time = delay;
- node->next = 0;
- node->id = ++id;
-
- prev = ptr = Q;
-
- /* insert node in the queue */
-
- /* if the queue is empty, insert the node and return */
- if (!Q)
- Q = node;
- else {
- /* chase the pointer looking for the right place */
- while (ptr) {
-
- if (delay < ptr->time) {
- /* right place */
-
- node->next = ptr;
- if (ptr == Q)
- Q = node;
- else
- prev->next = node;
- ptr->time -= node->time;
- return node->id;
- } else {
- /* keep moving */
-
- delay -= ptr->time; node->time = delay;
- prev = ptr;
- ptr = ptr->next;
- }
- }
- prev->next = node;
- }
- return node->id;
-}
-
-/* returns the time until the timer is scheduled */
-int
-timer_leftTimer(timer_id)
- int timer_id;
-{
- struct timeout_q *ptr;
- int left = 0;
-
- if (!timer_id)
- return -1;
-
- for (ptr = Q; ptr; ptr = ptr->next) {
- left += ptr->time;
- if (ptr->id == timer_id)
- return left;
- }
- return -1;
-}
-
-/* clears the associated timer */
-void
-timer_clearTimer(timer_id)
- int timer_id;
-{
- struct timeout_q *ptr, *prev;
-
- if (!timer_id)
- return;
-
- prev = ptr = Q;
-
- /*
- * find the right node, delete it. the subsequent node's time
- * gets bumped up
- */
-
- while (ptr) {
- if (ptr->id == timer_id) {
- /* got the right node */
-
- /* unlink it from the queue */
- if (ptr == Q)
- Q = Q->next;
- else
- prev->next = ptr->next;
-
- /* increment next node if any */
- if (ptr->next != 0)
- (ptr->next)->time += ptr->time;
-
- if (ptr->data)
- free(ptr->data);
- free(ptr);
- return;
- }
- prev = ptr;
- ptr = ptr->next;
- }
-}
-
-#ifdef CALLOUT_DEBUG
-/*
- * debugging utility
- */
-static void
-print_Q()
-{
- struct timeout_q *ptr;
-
- IF_DEBUG(DEBUG_TIMEOUT)
- for (ptr = Q; ptr; ptr = ptr->next)
- log(LOG_DEBUG, 0, "(%d,%d) ", ptr->id, ptr->time);
-}
-#endif /* CALLOUT_DEBUG */
diff --git a/usr.sbin/pim6dd/config.c b/usr.sbin/pim6dd/config.c
deleted file mode 100644
index f241287..0000000
--- a/usr.sbin/pim6dd/config.c
+++ /dev/null
@@ -1,792 +0,0 @@
-/*
- * Copyright (c) 1998 by the University of Southern California.
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation in source and binary forms for lawful
- * purposes and without fee is hereby granted, provided
- * that the above copyright notice appear in all copies and that both
- * the copyright notice and this permission notice appear in supporting
- * documentation, and that any documentation, advertising materials,
- * and other materials related to such distribution and use acknowledge
- * that the software was developed by the University of Southern
- * California and/or Information Sciences Institute.
- * The name of the University of Southern California may not
- * be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THE UNIVERSITY OF SOUTHERN CALIFORNIA DOES NOT MAKE ANY REPRESENTATIONS
- * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. THIS SOFTWARE IS
- * PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
- * NON-INFRINGEMENT.
- *
- * IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT,
- * TORT, OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH,
- * THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Other copyrights might apply to parts of this software and are so
- * noted when applicable.
- */
-/*
- * Questions concerning this software should be directed to
- * Pavlin Ivanov Radoslavov (pavlin@catarina.usc.edu)
- *
- * $Id: config.c,v 1.6 2000/02/23 16:10:26 itojun Exp $
- */
-/*
- * Part of this program has been derived from mrouted.
- * The mrouted program is covered by the license in the accompanying file
- * named "LICENSE.mrouted".
- *
- * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
- * Leland Stanford Junior University.
- *
- * $FreeBSD$
- */
-
-#include "defs.h"
-#ifdef HAVE_GETIFADDRS
-#include <ifaddrs.h>
-#endif
-
-
-/*
- * Forward declarations.
- */
-static char *next_word __P((char **));
-static int parse_phyint __P((char *s));
-static void add_phaddr __P((struct uvif *v, struct sockaddr_in6 *addr,
- struct in6_addr *mask));
-static mifi_t ifname2mifi __P((char *ifname));
-static int wordToOption __P((char *));
-static int parse_filter __P((char *s));
-#if 0 /* not used */
-static int parse_default_source_metric __P((char *));
-static int parse_default_source_preference __P((char *));
-#endif
-
-/*
- * Query the kernel to find network interfaces that are multicast-capable
- * and install them in the uvifs array.
- */
-void
-config_vifs_from_kernel()
-{
- register struct uvif *v;
- register vifi_t vifi;
- struct sockaddr_in6 addr;
- struct in6_addr mask, prefix;
- short flags;
-#ifdef HAVE_GETIFADDRS
- struct ifaddrs *ifap, *ifa;
-#else
- int n;
- int num_ifreq = 64;
- struct ifconf ifc;
- struct ifreq *ifrp, *ifend;
-#endif
-
- total_interfaces = 0; /* The total number of physical interfaces */
-
-#ifdef HAVE_GETIFADDRS
- if (getifaddrs(&ifap))
- log(LOG_ERR, errno, "getiaddrs");
-
- /*
- * Loop through all of the interfaces.
- */
- for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
- /*
- * Ignore any interface for an address family other than IPv6.
- */
- if (ifa->ifa_addr->sa_family != AF_INET6) {
- total_interfaces++; /* Eventually may have IPv6 address later */
- continue;
- }
-
- memcpy(&addr, ifa->ifa_addr, sizeof(struct sockaddr_in6));
-
- flags = ifa->ifa_flags;
- if ((flags & (IFF_LOOPBACK | IFF_MULTICAST)) != IFF_MULTICAST)
- continue;
-
- /*
- * Get netmask of the address.
- */
- memcpy(&mask, &((struct sockaddr_in6 *)ifa->ifa_netmask)->sin6_addr,
- sizeof(mask));
-
- if (IN6_IS_ADDR_LINKLOCAL(&addr.sin6_addr)) {
- addr.sin6_scope_id = if_nametoindex(ifa->ifa_name);
-#ifdef __KAME__
- /*
- * Hack for KAME kernel. Set sin6_scope_id field of a
- * link local address and clear the index embedded in
- * the address.
- */
- /* clear interface index */
- addr.sin6_addr.s6_addr[2] = 0;
- addr.sin6_addr.s6_addr[3] = 0;
-#endif
- }
-
- /*
- * If the address is connected to the same subnet as one already
- * installed in the uvifs array, just add the address to the list
- * of addresses of the uvif.
- */
- for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
- if (strcmp(v->uv_name, ifa->ifa_name) == 0) {
- add_phaddr(v, &addr, &mask);
- break;
- }
- }
- if (vifi != numvifs)
- continue;
-
- /*
- * If there is room in the uvifs array, install this interface.
- */
- if (numvifs == MAXMIFS) {
- log(LOG_WARNING, 0, "too many ifs, ignoring %s", ifa->ifa_name);
- continue;
- }
-
- /*
- * Everyone below is a potential vif interface.
- * We don't care if it has wrong configuration or not configured
- * at all.
- */
- total_interfaces++;
-
- v = &uvifs[numvifs];
- v->uv_flags = 0;
- v->uv_metric = DEFAULT_METRIC;
- v->uv_admetric = 0;
- v->uv_rate_limit = DEFAULT_PHY_RATE_LIMIT;
- v->uv_dst_addr = allpim6routers_group;
- v->uv_prefix.sin6_addr = prefix;
- v->uv_subnetmask = mask;
- strncpy(v->uv_name, ifa->ifa_name, IFNAMSIZ);
- v->uv_ifindex = if_nametoindex(v->uv_name);
- v->uv_groups = (struct listaddr *)NULL;
- v->uv_dvmrp_neighbors = (struct listaddr *)NULL;
- NBRM_CLRALL(v->uv_nbrmap);
- v->uv_querier = (struct listaddr *)NULL;
- v->uv_prune_lifetime = 0;
- v->uv_acl = (struct vif_acl *)NULL;
- v->uv_leaf_timer = 0;
- v->uv_addrs = (struct phaddr *)NULL;
- v->uv_filter = (struct vif_filter *)NULL;
- v->uv_pim_hello_timer = 0;
- v->uv_gq_timer = 0;
- v->uv_pim_neighbors = (struct pim_nbr_entry *)NULL;
- v->uv_local_pref = default_source_preference;
- v->uv_local_metric = default_source_metric;
- add_phaddr(v, &addr, &mask);
-
- if (flags & IFF_POINTOPOINT)
- v->uv_flags |= (VIFF_REXMIT_PRUNES | VIFF_POINT_TO_POINT);
- log(LOG_INFO, 0,
- "installing %s as if #%u - rate=%d",
- v->uv_name, numvifs, v->uv_rate_limit);
- ++numvifs;
-
- /*
- * If the interface is not yet up, set the vifs_down flag to
- * remind us to check again later.
- */
- if (!(flags & IFF_UP)) {
- v->uv_flags |= VIFF_DOWN;
- vifs_down = TRUE;
- }
- }
-
- freeifaddrs(ifap);
-#else /* !HAVE_GETIFADDRS */
- ifc.ifc_len = num_ifreq * sizeof(struct ifreq);
- ifc.ifc_buf = calloc(ifc.ifc_len, sizeof(char));
- while (ifc.ifc_buf) {
- caddr_t newbuf;
-
- if (ioctl(udp_socket, SIOCGIFCONF, (char *)&ifc) < 0)
- log(LOG_ERR, errno, "ioctl SIOCGIFCONF");
-
- /*
- * If the buffer was large enough to hold all the addresses
- * then break out, otherwise increase the buffer size and
- * try again.
- *
- * The only way to know that we definitely had enough space
- * is to know that there was enough space for at least one
- * more struct ifreq. ???
- */
- if ((num_ifreq * sizeof(struct ifreq)) >=
- ifc.ifc_len + sizeof(struct ifreq))
- break;
-
- num_ifreq *= 2;
- ifc.ifc_len = num_ifreq * sizeof(struct ifreq);
- newbuf = realloc(ifc.ifc_buf, ifc.ifc_len);
- if (newbuf == NULL)
- free(ifc.ifc_buf);
- ifc.ifc_buf = newbuf;
- }
- if (ifc.ifc_buf == NULL)
- log(LOG_ERR, 0, "config_vifs_from_kernel: ran out of memory");
-
- ifrp = (struct ifreq *)ifc.ifc_buf;
- ifend = (struct ifreq *)(ifc.ifc_buf + ifc.ifc_len);
- /*
- * Loop through all of the interfaces.
- */
- for (; ifrp < ifend; ifrp = (struct ifreq *)((char *)ifrp + n)) {
- struct ifreq ifr;
- struct in6_ifreq ifr6;
-#ifdef HAVE_SA_LEN
- n = ifrp->ifr_addr.sa_len + sizeof(ifrp->ifr_name);
- if (n < sizeof(*ifrp))
- n = sizeof(*ifrp);
-#else
- n = sizeof(*ifrp);
-#endif /* HAVE_SA_LEN */
-
- /*
- * Ignore any interface for an address family other than IPv6.
- */
- if (ifrp->ifr_addr.sa_family != AF_INET6) {
- total_interfaces++; /* Eventually may have IPv6 address later */
- continue;
- }
-
- memcpy(&addr, &ifrp->ifr_addr, sizeof(struct sockaddr_in6));
-
- /*
- * Need a template to preserve address info that is
- * used below to locate the next entry. (Otherwise,
- * SIOCGIFFLAGS stomps over it because the requests
- * are returned in a union.)
- */
- memcpy(ifr.ifr_name, ifrp->ifr_name, sizeof(ifr.ifr_name));
- memcpy(ifr6.ifr_name, ifrp->ifr_name, sizeof(ifr6.ifr_name));
-
- /*
- * Ignore loopback interfaces and interfaces that do not
- * support multicast.
- */
- if (ioctl(udp_socket, SIOCGIFFLAGS, (char *)&ifr) < 0)
- log(LOG_ERR, errno, "ioctl SIOCGIFFLAGS for %s", ifr.ifr_name);
- flags = ifr.ifr_flags;
- if ((flags & (IFF_LOOPBACK | IFF_MULTICAST)) != IFF_MULTICAST)
- continue;
-
- /*
- * Get netmask of the address.
- */
- ifr6.ifr_addr = *(struct sockaddr_in6 *)&ifrp->ifr_addr;
- if (ioctl(udp_socket, SIOCGIFNETMASK_IN6, (char *)&ifr6) < 0)
- log(LOG_ERR, errno, "ioctl SIOCGIFNETMASK_IN6 for %s",
- ifr6.ifr_name);
- memcpy(&mask, &ifr6.ifr_addr.sin6_addr, sizeof(mask));
-
- if (IN6_IS_ADDR_LINKLOCAL(&addr.sin6_addr)) {
- addr.sin6_scope_id = if_nametoindex(ifrp->ifr_name);
-#ifdef __KAME__
- /*
- * Hack for KAME kernel. Set sin6_scope_id field of a
- * link local address and clear the index embedded in
- * the address.
- */
- /* clear interface index */
- addr.sin6_addr.s6_addr[2] = 0;
- addr.sin6_addr.s6_addr[3] = 0;
-#endif
- }
-
- /*
- * If the address is connected to the same subnet as one already
- * installed in the uvifs array, just add the address to the list
- * of addresses of the uvif.
- */
- for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
- if (strcmp(v->uv_name, ifr.ifr_name) == 0) {
- add_phaddr(v, &addr, &mask);
- break;
- }
- }
- if (vifi != numvifs)
- continue;
-
- /*
- * If there is room in the uvifs array, install this interface.
- */
- if (numvifs == MAXMIFS) {
- log(LOG_WARNING, 0, "too many ifs, ignoring %s", ifr.ifr_name);
- continue;
- }
-
- /*
- * Everyone below is a potential vif interface.
- * We don't care if it has wrong configuration or not configured
- * at all.
- */
- total_interfaces++;
-
- v = &uvifs[numvifs];
- v->uv_flags = 0;
- v->uv_metric = DEFAULT_METRIC;
- v->uv_admetric = 0;
- v->uv_rate_limit = DEFAULT_PHY_RATE_LIMIT;
- v->uv_dst_addr = allpim6routers_group;
- v->uv_prefix.sin6_addr = prefix;
- v->uv_subnetmask = mask;
- strncpy(v->uv_name, ifr.ifr_name, IFNAMSIZ);
- v->uv_ifindex = if_nametoindex(v->uv_name);
- v->uv_groups = (struct listaddr *)NULL;
- v->uv_dvmrp_neighbors = (struct listaddr *)NULL;
- NBRM_CLRALL(v->uv_nbrmap);
- v->uv_querier = (struct listaddr *)NULL;
- v->uv_prune_lifetime = 0;
- v->uv_acl = (struct vif_acl *)NULL;
- v->uv_leaf_timer = 0;
- v->uv_addrs = (struct phaddr *)NULL;
- v->uv_filter = (struct vif_filter *)NULL;
- v->uv_pim_hello_timer = 0;
- v->uv_gq_timer = 0;
- v->uv_pim_neighbors = (struct pim_nbr_entry *)NULL;
- v->uv_local_pref = default_source_preference;
- v->uv_local_metric = default_source_metric;
- add_phaddr(v, &addr, &mask);
-
- if (flags & IFF_POINTOPOINT)
- v->uv_flags |= (VIFF_REXMIT_PRUNES | VIFF_POINT_TO_POINT);
- log(LOG_INFO, 0,
- "installing %s as if #%u - rate=%d",
- v->uv_name, numvifs, v->uv_rate_limit);
- ++numvifs;
-
- /*
- * If the interface is not yet up, set the vifs_down flag to
- * remind us to check again later.
- */
- if (!(flags & IFF_UP)) {
- v->uv_flags |= VIFF_DOWN;
- vifs_down = TRUE;
- }
- }
-#endif /* HAVE_GETIFADDRS */
-}
-
-static void
-add_phaddr(v, addr, mask)
- struct uvif *v;
- struct sockaddr_in6 *addr;
- struct in6_addr *mask;
-{
- struct phaddr *pa;
- int i;
-
- if ((pa = malloc(sizeof(*pa))) == NULL)
- log(LOG_ERR, 0, "add_phaddr: memory exhausted");
-
- memset(pa, 0, sizeof(*pa));
- pa->pa_addr = *addr;
- pa->pa_subnetmask = *mask;
-
- /*
- * install the prefix of the address derived from the address
- * and the mask.
- */
- for (i = 0; i < sizeof(struct in6_addr); i++)
- pa->pa_prefix.sin6_addr.s6_addr[i] =
- addr->sin6_addr.s6_addr[i] & mask->s6_addr[i];
- pa->pa_prefix.sin6_scope_id = addr->sin6_scope_id;
-
- if (IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr)) {
- if (v->uv_linklocal) {
- log(LOG_WARNING, 0,
- "add_phaddr: found more than one link-local "
- "address on %s",
- v->uv_name);
- }
- v->uv_linklocal = pa; /* relace anyway */
- }
-
- /* link into chain */
- pa->pa_next = v->uv_addrs;
- v->uv_addrs = pa;
-}
-
-static mifi_t
-ifname2mifi(ifname)
- char *ifname;
-{
- mifi_t mifi;
- struct uvif *v;
-
- for (mifi = 0, v = uvifs; mifi < numvifs; ++mifi, ++v) {
- if (strcmp(v->uv_name, ifname) == 0)
- break;
- }
- return(mifi);
-}
-
-#define UNKNOWN -1
-#define EMPTY 1
-#define PHYINT 2
-#define DEFAULT_SOURCE_METRIC 3
-#define DEFAULT_SOURCE_PREFERENCE 4
-#define FILTER 5
-
-/*
- * function name: wordToOption
- * input: char *word, a pointer to the word
- * output: int; a number corresponding to the code of the word
- * operation: converts the result of the string comparisons into numerics.
- * comments: called by config_vifs_from_file()
- */
-static int
-wordToOption(word)
- char *word;
-{
- if (EQUAL(word, ""))
- return EMPTY;
- if (EQUAL(word, "phyint"))
- return PHYINT;
- if (EQUAL(word, "default_source_metric"))
- return DEFAULT_SOURCE_METRIC;
- if (EQUAL(word, "default_source_preference"))
- return DEFAULT_SOURCE_PREFERENCE;
- if (EQUAL(word, "filter"))
- return FILTER;
- return UNKNOWN;
-}
-
-/*
- * function name: parse_phyint
- * input: char *s, pointing to the parsing point of the file
- * output: int (TRUE if the parsing was successful, o.w. FALSE)
- * operation: parses the physical interface file configurations, if any.
- * The general form is:
- * phyint <ifname> [disable]
- */
-static int
-parse_phyint(s)
- char *s;
-{
- char *w, c, *ifname;
- vifi_t vifi;
- struct uvif *v;
- u_int n;
-
- if (EQUAL((w = next_word(&s)), "")) {
- log(LOG_WARNING, 0, "Missing phyint in %s", configfilename);
- return(FALSE);
- } /* if empty */
- ifname = w;
-
- for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
- if (vifi == numvifs) {
- log(LOG_WARNING, 0,
- "phyint %s in %s is not a configured interface",
- ifname, configfilename);
- return(FALSE);
- } /* if vifi == numvifs */
-
- if (strcmp(v->uv_name, ifname))
- continue;
-
- while (!EQUAL((w = next_word(&s)), "")) {
- if (EQUAL(w, "disable"))
- v->uv_flags |= VIFF_DISABLED;
- else if (EQUAL(w, "nolistener"))
- v->uv_flags |= VIFF_NOLISTENER;
- else if(EQUAL(w, "preference")) {
- if(EQUAL((w = next_word(&s)), ""))
- log(LOG_WARNING, 0,
- "Missing preference for phyint %s in %s",
- ifname, configfilename);
- else if (sscanf(w, "%u%c", &n, &c) != 1 ||
- n < 1 || n > 255 )
- log(LOG_WARNING, 0,
- "Invalid preference '%s' for phyint %s in %s",
- w, ifname,
- configfilename);
- else {
- IF_DEBUG(DEBUG_ASSERT)
- log(LOG_DEBUG, 0,
- "Config setting default local preference on %s to %d.",
- ifname, n);
- v->uv_local_pref = n;
- }
-
- } else if(EQUAL(w, "metric")) {
- if(EQUAL((w = next_word(&s)), ""))
- log(LOG_WARNING, 0,
- "Missing metric for phyint %s in %s",
- ifname, configfilename);
- else if (sscanf(w, "%u%c", &n, &c) != 1 ||
- n < 1 || n > 1024 )
- log(LOG_WARNING, 0,
- "Invalid metric '%s' for phyint %s in %s",
- w, ifname,
- configfilename);
- else {
- IF_DEBUG(DEBUG_ASSERT)
- log(LOG_DEBUG, 0,
- "Config setting default local metric on %s to %d.",
- ifname, n);
- v->uv_local_metric = n;
- }
- }
- } /* if not empty */
- break;
- }
- return(TRUE);
-}
-
-static int
-parse_filter(s)
- char *s;
-{
- char *w, *groups, *p;
- mifi_t mifi;
- struct in6_addr grp1, grp2;
- if_set filterset;
- struct mrtfilter *filter;
- int plen = 0, filtertype;
-
- if (EQUAL((groups = next_word(&s)), "")) {
- log(LOG_WARNING, 0, "Missing multicast group in %s",
- configfilename);
- return(FALSE);
- }
-
- /*
- * Group address specification. Valid format are the followings.
- * - Group1-Group2: specifies a numerical range of a scope.
- * - GroupPrefix/Prefixlen: specifies a prefix of a scope. If the
- * Prefixlen is omitted, it means the exact match.
- */
- if ((p = strchr(groups, '-')) != NULL) { /* Group1-Group2 */
- char *maddr1, *maddr2;
-
- maddr1 = groups;
- maddr2 = p + 1;
- *p = '\0';
- if (inet_pton(AF_INET6, maddr1, (void *)&grp1) != 1 ||
- !IN6_IS_ADDR_MULTICAST(&grp1)) {
- log(LOG_WARNING, 0, "invalid group address %s", maddr1);
- return(FALSE);
- }
- if (inet_pton(AF_INET6, maddr2, (void *)&grp2) != 1 ||
- !IN6_IS_ADDR_MULTICAST(&grp2)) {
- log(LOG_WARNING, 0, "invalid group address %s", maddr2);
- return(FALSE);
- }
- filtertype = FILTER_RANGE;
- }
- else if ((p = strchr(groups, '/')) != NULL) { /* GroupPrefix/Plen */
- char *mprefix = groups;
- int plen = atoi(p + 1);
- *p = '\0';
- if (inet_pton(AF_INET6, mprefix, (void *)&grp1) != 1 ||
- !IN6_IS_ADDR_MULTICAST(&grp1)) {
- log(LOG_WARNING, 0, "invalid group prefix %s", mprefix);
- return(FALSE);
- }
- if (plen < 0 || plen > 128) {
- log(LOG_WARNING, 0, "invalid prefix length %s", p + 1);
- return(FALSE);
- }
- filtertype = FILTER_PREFIX;
- }
- else {
- if (inet_pton(AF_INET6, groups, (void *)&grp1) != 1) {
- log(LOG_WARNING, 0, "invalid group address %s", groups);
- return(FALSE);
- }
- plen = 128; /* exact match */
- filtertype = FILTER_PREFIX;
- }
-
- IF_ZERO(&filterset);
- while (!EQUAL((w = next_word(&s)), "")) {
- if ((mifi = ifname2mifi(w)) == MAXMIFS) {
- /* XXX: scope consideration?? */
- log(LOG_WARNING, 0,
- "phyint %s in %s is not a configured interface",
- w, configfilename);
- return(FALSE);
- }
-
- IF_SET(mifi, &filterset);
- }
- if (IF_ISEMPTY(&filterset)) {
- log(LOG_WARNING, 0,
- "filter set is empty. ignore it.");
- return(FALSE);
- }
-
- filter = add_filter(filtertype, &grp1, &grp2, plen);
- IF_COPY(&filterset, &filter->ifset);
-
- return(TRUE);
-}
-
-#if 0 /* not used */
-/*
- * function name: parse_default_source_metric
- * input: char *s
- * output: int
- * operation: reads and assigns the default source metric, if no reliable
- * unicast routing information available.
- * General form:
- * 'default_source_metric <number>'.
- * default pref and metric statements should precede all phyint
- * statements in the config file.
- */
-static int
-parse_default_source_metric(s)
- char *s;
-{
- char *w;
- u_int value;
- vifi_t vifi;
- struct uvif *v;
-
- value = DEFAULT_LOCAL_METRIC;
- if (EQUAL((w = next_word(&s)), "")) {
- log(LOG_WARNING, 0,
- "Missing default source metric; set to default %u",
- DEFAULT_LOCAL_METRIC);
- } else if (sscanf(w, "%u", &value) != 1) {
- log(LOG_WARNING, 0,
- "Invalid default source metric; set to default %u",
- DEFAULT_LOCAL_METRIC);
- value = DEFAULT_LOCAL_METRIC;
- }
- default_source_metric = value;
- log(LOG_INFO, 0, "default_source_metric is %u", value);
-
- for (vifi = 0, v = uvifs; vifi < MAXMIFS; ++vifi, ++v) {
- v->uv_local_metric = default_source_metric;
- }
-
- return(TRUE);
-}
-
-
-/*
- * function name: parse_default_source_preference
- * input: char *s
- * output: int
- * operation: reads and assigns the default source preference, if no reliable
- * unicast routing information available.
- * General form:
- * 'default_source_preference <number>'.
- * default pref and metric statements should precede all phyint
- * statements in the config file.
-*/
-static int
-parse_default_source_preference(s)
- char *s;
-{
- char *w;
- u_int value;
- vifi_t vifi;
- struct uvif *v;
-
- value = DEFAULT_LOCAL_PREF;
- if (EQUAL((w = next_word(&s)), "")) {
- log(LOG_WARNING, 0,
- "Missing default source preference; set to default %u",
- DEFAULT_LOCAL_PREF);
- } else if (sscanf(w, "%u", &value) != 1) {
- log(LOG_WARNING, 0,
- "Invalid default source preference; set to default %u",
- DEFAULT_LOCAL_PREF);
- value = DEFAULT_LOCAL_PREF;
- }
- default_source_preference = value;
- log(LOG_INFO, 0, "default_source_preference is %u", value);
-
- for (vifi = 0, v = uvifs; vifi < MAXMIFS; ++vifi, ++v) {
- v->uv_local_pref = default_source_preference;
- }
-
- return(TRUE);
-}
-#endif
-
-void
-config_vifs_from_file()
-{
- FILE *f;
- char linebuf[100];
- char *w, *s;
- int option;
-
- if ((f = fopen(configfilename, "r")) == NULL) {
- if (errno != ENOENT) log(LOG_WARNING, errno, "can't open %s",
- configfilename);
- return;
- }
-
- while (fgets(linebuf, sizeof(linebuf), f) != NULL) {
- s = linebuf;
- w = next_word(&s);
- option = wordToOption(w);
- switch(option) {
- case EMPTY:
- continue;
- break;
- case PHYINT:
- parse_phyint(s);
- break;
- case FILTER:
- parse_filter(s);
- break;
- default:
- log(LOG_WARNING, 0, "unknown command '%s' in %s",
- w, configfilename);
- }
- }
- fclose(f);
-}
-
-static char *
-next_word(s)
- char **s;
-{
- char *w;
-
- w = *s;
- while (*w == ' ' || *w == '\t')
- w++;
-
- *s = w;
- for(;;) {
- switch (**s) {
- case ' ' :
- case '\t' :
- **s = '\0';
- (*s)++;
- return(w);
- case '\n' :
- case '#' :
- **s = '\0';
- return(w);
- case '\0' :
- return(w);
- default :
- if (isascii(**s) && isupper(**s))
- **s = tolower(**s);
- (*s)++;
- }
- }
-}
-
diff --git a/usr.sbin/pim6dd/debug.c b/usr.sbin/pim6dd/debug.c
deleted file mode 100644
index 740d999..0000000
--- a/usr.sbin/pim6dd/debug.c
+++ /dev/null
@@ -1,565 +0,0 @@
-/*
- * Copyright (c) 1998 by the University of Southern California.
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation in source and binary forms for lawful
- * purposes and without fee is hereby granted, provided
- * that the above copyright notice appear in all copies and that both
- * the copyright notice and this permission notice appear in supporting
- * documentation, and that any documentation, advertising materials,
- * and other materials related to such distribution and use acknowledge
- * that the software was developed by the University of Southern
- * California and/or Information Sciences Institute.
- * The name of the University of Southern California may not
- * be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THE UNIVERSITY OF SOUTHERN CALIFORNIA DOES NOT MAKE ANY REPRESENTATIONS
- * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. THIS SOFTWARE IS
- * PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
- * NON-INFRINGEMENT.
- *
- * IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT,
- * TORT, OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH,
- * THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Other copyrights might apply to parts of this software and are so
- * noted when applicable.
- */
-/*
- * Questions concerning this software should be directed to
- * Pavlin Ivanov Radoslavov (pavlin@catarina.usc.edu)
- *
- * $Id: debug.c,v 1.10 2000/10/05 22:27:07 itojun Exp $
- */
-/*
- * Part of this program has been derived from mrouted.
- * The mrouted program is covered by the license in the accompanying file
- * named "LICENSE.mrouted".
- *
- * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
- * Leland Stanford Junior University.
- *
- * $FreeBSD$
- */
-
-#include "defs.h"
-
-
-#ifdef __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-
-extern int haveterminal;
-extern char *progname;
-
-int log_nmsgs = 0;
-unsigned long debug = 0x00000000; /* If (long) is smaller than
- * 4 bytes, then we are in
- * trouble.
- */
-static char dumpfilename[] = _PATH_PIM6D_DUMP;
-static char cachefilename[] = _PATH_PIM6D_CACHE; /* TODO: notused */
-
-static char *sec2str __P((time_t));
-
-static char *
-sec2str(total)
- time_t total;
-{
- static char result[256];
- int days, hours, mins, secs;
- int first = 1;
- char *p = result;
-
- days = total / 3600 / 24;
- hours = (total / 3600) % 24;
- mins = (total / 60) % 60;
- secs = total % 60;
-
- if (days) {
- first = 0;
- p += sprintf(p, "%dd", days);
- }
- if (!first || hours) {
- first = 0;
- p += sprintf(p, "%dh", hours);
- }
- if (!first || mins) {
- first = 0;
- p += sprintf(p, "%dm", mins);
- }
- sprintf(p, "%ds", secs);
-
- return(result);
-}
-
-char *
-packet_kind(proto, type, code)
- u_int proto, type, code;
-{
- static char unknown[60];
-
- switch (proto) {
- case IPPROTO_ICMPV6:
- switch (type) {
- case MLD6_LISTENER_QUERY: return "Multicast Listener Query ";
- case MLD6_LISTENER_REPORT: return "Multicast Listener Report ";
- case MLD6_LISTENER_DONE: return "Multicast Listener Done ";
- default:
- sprintf(unknown,
- "UNKNOWN ICMPv6 message: type = 0x%02x, code = 0x%02x ",
- type, code);
- return unknown;
- }
-
- case IPPROTO_PIM: /* PIM v2 */
- switch (type) {
- case PIM_V2_HELLO: return "PIM v2 Hello ";
- case PIM_V2_REGISTER: return "PIM v2 Register ";
- case PIM_V2_REGISTER_STOP: return "PIM v2 Register_Stop ";
- case PIM_V2_JOIN_PRUNE: return "PIM v2 Join/Prune ";
- case PIM_V2_BOOTSTRAP: return "PIM v2 Bootstrap ";
- case PIM_V2_ASSERT: return "PIM v2 Assert ";
- case PIM_V2_GRAFT: return "PIM-DM v2 Graft ";
- case PIM_V2_GRAFT_ACK: return "PIM-DM v2 Graft_Ack ";
- case PIM_V2_CAND_RP_ADV: return "PIM v2 Cand. RP Adv. ";
- default:
- sprintf(unknown, "UNKNOWN PIM v2 message type =%3d ", type);
- return unknown;
- }
- default:
- sprintf(unknown, "UNKNOWN proto =%3d ", proto);
- return unknown;
- }
-}
-
-
-/*
- * Used for debugging particular type of messages.
- */
-int
-debug_kind(proto, type, code)
- u_int proto, type, code;
-{
- switch (proto) {
- case IPPROTO_ICMPV6:
- switch (type) {
- case MLD6_LISTENER_QUERY: return DEBUG_MLD;
- case MLD6_LISTENER_REPORT: return DEBUG_MLD;
- case MLD6_LISTENER_DONE: return DEBUG_MLD;
- default: return DEBUG_MLD;
- }
- case IPPROTO_PIM: /* PIM v2 */
- /* TODO: modify? */
- switch (type) {
- case PIM_V2_HELLO: return DEBUG_PIM;
- case PIM_V2_REGISTER: return DEBUG_PIM_REGISTER;
- case PIM_V2_REGISTER_STOP: return DEBUG_PIM_REGISTER;
- case PIM_V2_JOIN_PRUNE: return DEBUG_PIM;
- case PIM_V2_BOOTSTRAP: return DEBUG_PIM_BOOTSTRAP;
- case PIM_V2_ASSERT: return DEBUG_PIM;
- case PIM_V2_GRAFT: return DEBUG_PIM;
- case PIM_V2_GRAFT_ACK: return DEBUG_PIM;
- case PIM_V2_CAND_RP_ADV: return DEBUG_PIM_CAND_RP;
- default: return DEBUG_PIM;
- }
- default: return 0;
- }
- return 0;
-}
-
-
-/*
- * Some messages are more important than others. This routine
- * determines the logging level at which to log a send error (often
- * "No route to host"). This is important when there is asymmetric
- * reachability and someone is trying to, i.e., mrinfo me periodically.
- */
-int
-log_level(proto, type, code)
- u_int proto, type, code;
-{
- switch (proto) {
- case IPPROTO_ICMPV6:
- switch (type) {
- default:
- return LOG_WARNING;
- }
-
- case IPPROTO_PIM:
- /* PIM v2 */
- switch (type) {
- default:
- return LOG_INFO;
- }
- default:
- return LOG_WARNING;
- }
- return LOG_WARNING;
-}
-
-
-/*
- * Dump internal data structures to stderr.
- */
-/* TODO: currently not used
-void
-dump(int i)
-{
- dump_vifs(stderr);
- dump_pim_mrt(stderr);
-}
-*/
-
-/*
- * Dump internal data structures to a file.
- */
-void
-fdump(i)
- int i;
-{
- FILE *fp;
- fp = fopen(dumpfilename, "w");
- if (fp != NULL) {
- dump_vifs(fp);
- dump_mldqueriers(fp);
- dump_pim_mrt(fp);
- dump_lcl_grp(fp);
- (void) fclose(fp);
- }
-}
-
-/* TODO: dummy, to be used in the future. */
-/*
- * Dump local cache contents to a file.
- */
-void
-cdump(i)
- int i;
-{
- FILE *fp;
-
- fp = fopen(cachefilename, "w");
- if (fp != NULL) {
- /* TODO: implement it:
- dump_cache(fp);
- */
- (void) fclose(fp);
- }
-}
-
-void
-dump_vifs(fp)
- FILE *fp;
-{
- vifi_t vifi;
- register struct uvif *v;
- pim_nbr_entry_t *n;
- struct phaddr *pa;
- int width;
- int i;
-
- fprintf(fp, "\nMulticast Interface Table\n %-4s %-6s %-50s %-14s %s",
- "Mif", " PhyIF", "Local-Address/Prefixlen", "Flags",
- "Neighbors\n");
-
- for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
- int firstaddr = 1;
- for (pa = v->uv_addrs; pa; pa = pa->pa_next) {
- if (!firstaddr) {
- fprintf(fp, " %3s %6s %-50s\n", "", "",
- net6name(&pa->pa_addr.sin6_addr,
- &pa->pa_subnetmask));
- continue;
- }
-
- firstaddr = 0;
- fprintf(fp, " %-3u %6s %-50s", vifi, v->uv_name,
- net6name(&pa->pa_addr.sin6_addr,
- &pa->pa_subnetmask));
- firstaddr = 0;
-#if 0
- if (v->uv_flags & MIFF_REGISTER)
- fprintf(fp, "%-16s ", v->uv_name);
- else
- fprintf(fp,"%-16.16s ",
- net6name(&v->uv_prefix.sin6_addr,
- &v->uv_subnetmask));
-#endif
- width = 0;
- if (v->uv_flags & VIFF_DISABLED)
- fprintf(fp, " DISABLED");
- if (v->uv_flags & VIFF_NOLISTENER)
- fprintf(fp, " NOLISTENER");
- if (v->uv_flags & VIFF_DOWN)
- fprintf(fp, " DOWN");
- if (v->uv_flags & VIFF_DR) {
- fprintf(fp, " DR");
- width += 3;
- }
- if (v->uv_flags & VIFF_PIM_NBR) {
- fprintf(fp, " PIM");
- width += 4;
- }
-#if 0 /* impossible */
- if (v->uv_flags & VIFF_DVMRP_NBR) {
- fprintf(fp, " DVMRP");
- width += 6;
- }
-#endif
- if (v->uv_flags & VIFF_NONBRS) {
- fprintf(fp, " %-12s", "NO-NBR");
- width += 6;
- }
- if (v->uv_flags & VIFF_QUERIER)
- fprintf(fp, " QRY");
-
- if ((n = v->uv_pim_neighbors) != NULL) {
- /* Print the first neighbor on the same line */
- for (i = width; i <= 15; i++)
- fprintf(fp, " ");
- fprintf(fp, "%-12s\n",
- inet6_fmt(&n->address.sin6_addr));
- for (n = n->next; n != NULL; n = n->next)
- fprintf(fp, "%64s %-15s\n", "",
- inet6_fmt(&n->address.sin6_addr));
-
- }
- else
- fprintf(fp, "\n");
- }
- }
- fprintf(fp, "\n");
-}
-
-
-/*
- * Log errors and other messages to the system log daemon and to stderr,
- * according to the severity of the message and the current debug level.
- * For errors of severity LOG_ERR or worse, terminate the program.
- */
-#ifdef __STDC__
-void
-log(int severity, int syserr, char *format, ...)
-{
- va_list ap;
- static char fmt[211] = "warning - ";
- char *msg;
- struct timeval now;
- struct tm *thyme;
-
- va_start(ap, format);
-#else
-/*VARARGS3*/
-void
-log(severity, syserr, format, va_alist)
- int severity, syserr;
- char *format;
- va_dcl
-{
- va_list ap;
- static char fmt[311] = "warning - ";
- char *msg;
- char tbuf[20];
- struct timeval now;
- struct tm *thyme;
-
- va_start(ap);
-#endif
- vsprintf(&fmt[10], format, ap);
- va_end(ap);
- msg = (severity == LOG_WARNING) ? fmt : &fmt[10];
-
- /*
- * Log to stderr if we haven't forked yet and it's a warning or worse,
- * or if we're debugging.
- */
- if (haveterminal && (debug || severity <= LOG_WARNING)) {
- time_t sectime;
- gettimeofday(&now,NULL);
- sectime = (time_t) now.tv_sec;
- thyme = localtime(&sectime);
- if (!debug)
- fprintf(stderr, "%s: ", progname);
- fprintf(stderr, "%02d:%02d:%02d.%03ld %s", thyme->tm_hour,
- thyme->tm_min, thyme->tm_sec, (long int)now.tv_usec / 1000,
- msg);
- if (syserr == 0)
- fprintf(stderr, "\n");
- else if (syserr < sys_nerr)
- fprintf(stderr, ": %s\n", sys_errlist[syserr]);
- else
- fprintf(stderr, ": errno %d\n", syserr);
- }
-
- /*
- * Always log things that are worse than warnings, no matter what
- * the log_nmsgs rate limiter says.
- * Only count things worse than debugging in the rate limiter
- * (since if you put daemon.debug in syslog.conf you probably
- * actually want to log the debugging messages so they shouldn't
- * be rate-limited)
- */
- if ((severity < LOG_WARNING) || (log_nmsgs < LOG_MAX_MSGS)) {
- if (severity < LOG_DEBUG)
- log_nmsgs++;
- if (syserr != 0) {
- errno = syserr;
- syslog(severity, "%s: %m", msg);
- } else
- syslog(severity, "%s", msg);
- }
-
- if (severity <= LOG_ERR) exit(-1);
-}
-
-void
-dump_mldqueriers(fp)
- FILE *fp;
-{
- struct uvif *v;
- vifi_t vifi;
- time_t now;
-
- fprintf(fp, "MLD Querier List\n");
- fprintf(fp, " %-3s %6s %-40s %-5s %15s\n",
- "Mif", "PhyIF", "Address", "Timer", "Last");
- (void)time(&now);
-
- for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
- if (v->uv_querier) {
- fprintf(fp, " %-3u %6s", vifi,
- (v->uv_flags & MIFF_REGISTER) ? "regist":
- v->uv_name);
-
- fprintf(fp, " %-40s %5lu %15s\n",
- inet6_fmt(&v->uv_querier->al_addr.sin6_addr),
- (u_long)v->uv_querier->al_timer,
- sec2str(now - v->uv_querier->al_ctime));
- }
- }
-
- fprintf(fp, "\n");
-}
-
-/* TODO: format the output for better readability */
-void
-dump_pim_mrt(fp)
- FILE *fp;
-{
- grpentry_t *g;
- register mrtentry_t *r;
- register vifi_t vifi;
- u_int number_of_groups = 0;
- char oifs[(sizeof(if_set)<<3)+1];
- char pruned_oifs[(sizeof(if_set)<<3)+1];
- char asserted_oifs[(sizeof(if_set)<<3)+1];
- char leaves_oifs[(sizeof(if_set)<<3)+1];
- char filter_oifs[(sizeof(if_set)<<3)+1];
- char incoming_iif[(sizeof(if_set)<<3)+1];
-
- fprintf(fp, "Multicast Routing Table\n%s",
- " Source Group Flags\n");
-
- /* TODO: remove the dummy 0:: group (first in the chain) */
- for (g = grplist->next; g != (grpentry_t *)NULL; g = g->next) {
- number_of_groups++;
- /* Print all (S,G) routing info */
- for (r = g->mrtlink; r != (mrtentry_t *)NULL; r = r->grpnext) {
- fprintf(fp, "---------------------------(S,G)----------------------------\n");
- /* Print the routing info */
- fprintf(fp, " %-15s", inet6_fmt(&r->source->address.sin6_addr));
- fprintf(fp, " %-15s", inet6_fmt(&g->group.sin6_addr));
-
- for (vifi = 0; vifi < numvifs; vifi++) {
- oifs[vifi] =
- IF_ISSET(vifi, &r->oifs) ? 'o' : '.';
- pruned_oifs[vifi] =
- IF_ISSET(vifi, &r->pruned_oifs) ? 'p' : '.';
- asserted_oifs[vifi] =
- IF_ISSET(vifi, &r->pruned_oifs) ? 'a' : '.';
- filter_oifs[vifi] =
- IF_ISSET(vifi, &r->filter_oifs) ? 'f' : '.';
- leaves_oifs[vifi] =
- IF_ISSET(vifi, &r->leaves) ? 'l' : '.';
- incoming_iif[vifi] = '.';
- }
- oifs[vifi] = 0x0; /* End of string */
- pruned_oifs[vifi] = 0x0;
- leaves_oifs[vifi] = 0x0;
- filter_oifs[vifi] = 0x0;
- incoming_iif[vifi] = 0x0;
- incoming_iif[r->incoming] = 'I';
-
- /* TODO: don't need some of the flags */
- if (r->flags & MRTF_SPT) fprintf(fp, " SPT");
- if (r->flags & MRTF_WC) fprintf(fp, " WC");
- if (r->flags & MRTF_RP) fprintf(fp, " RP");
- if (r->flags & MRTF_REGISTER) fprintf(fp, " REG");
- if (r->flags & MRTF_IIF_REGISTER) fprintf(fp, " IIF_REG");
- if (r->flags & MRTF_NULL_OIF) fprintf(fp, " NULL_OIF");
- if (r->flags & MRTF_KERNEL_CACHE) fprintf(fp, " CACHE");
- if (r->flags & MRTF_ASSERTED) fprintf(fp, " ASSERTED");
- if (r->flags & MRTF_REG_SUPP) fprintf(fp, " REG_SUPP");
- if (r->flags & MRTF_SG) fprintf(fp, " SG");
- if (r->flags & MRTF_PMBR) fprintf(fp, " PMBR");
- fprintf(fp, "\n");
-
- fprintf(fp, "Pruned oifs: %-20s\n", pruned_oifs);
- fprintf(fp, "Asserted oifs: %-20s\n", pruned_oifs);
- fprintf(fp, "Filtered oifs: %-20s\n", filter_oifs);
- fprintf(fp, "Leaves oifs: %-20s\n", leaves_oifs);
- fprintf(fp, "Outgoing oifs: %-20s\n", oifs);
- fprintf(fp, "Incoming : %-20s\n", incoming_iif);
-
- fprintf(fp, "Upstream nbr: %s\n",
- r->upstream ? inet6_fmt(&r->upstream->address.sin6_addr) : "NONE");
- fprintf(fp, "\nTIMERS: Entry Prune VIFS:");
- for (vifi = 0; vifi < numvifs; vifi++)
- fprintf(fp, " %2d", vifi);
- fprintf(fp, "\n %3d ",
- r->timer);
- for (vifi = 0; vifi < numvifs; vifi++)
- fprintf(fp, " %3d", r->prune_timers[vifi]);
- fprintf(fp, "\n");
- }
- }/* for all groups */
-
- fprintf(fp, "Number of Groups: %u\n", number_of_groups);
-}
-
-void
-dump_lcl_grp(fp)
- FILE *fp;
-{
- vifi_t vifi;
- struct uvif *v;
- struct listaddr *g;
-
- fprintf(fp, "\nList of local listener information per interface\n");
- for (vifi = 0, v = uvifs; vifi < numvifs; vifi++, v++) {
- int first = 1;
-
- for (g = v->uv_groups; g != NULL; g = g->al_next) {
- if (first) {
- fprintf(fp, " Mif %d(%s)\n", vifi, v->uv_name);
- first = 0;
- }
- fprintf(fp, " %s", inet6_fmt(&g->al_addr.sin6_addr));
- if (g->al_timerid)
- fprintf(fp, " timeout: %d",
- timer_leftTimer(g->al_timerid));
- if (g->al_query)
- fprintf(fp, " querytimer: %d",
- timer_leftTimer(g->al_timerid));
- fputc('\n', fp);
- }
- }
-}
diff --git a/usr.sbin/pim6dd/debug.h b/usr.sbin/pim6dd/debug.h
deleted file mode 100644
index 1d4e294..0000000
--- a/usr.sbin/pim6dd/debug.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (c) 1998 by the University of Southern California.
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation in source and binary forms for lawful
- * purposes and without fee is hereby granted, provided
- * that the above copyright notice appear in all copies and that both
- * the copyright notice and this permission notice appear in supporting
- * documentation, and that any documentation, advertising materials,
- * and other materials related to such distribution and use acknowledge
- * that the software was developed by the University of Southern
- * California and/or Information Sciences Institute.
- * The name of the University of Southern California may not
- * be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THE UNIVERSITY OF SOUTHERN CALIFORNIA DOES NOT MAKE ANY REPRESENTATIONS
- * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. THIS SOFTWARE IS
- * PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
- * NON-INFRINGEMENT.
- *
- * IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT,
- * TORT, OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH,
- * THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Other copyrights might apply to parts of this software and are so
- * noted when applicable.
- */
-/*
- * Questions concerning this software should be directed to
- * Pavlin Ivanov Radoslavov (pavlin@catarina.usc.edu)
- *
- * $Id: debug.h,v 1.1.1.1 1999/08/08 23:30:52 itojun Exp $
- */
-/*
- * Part of this program has been derived from mrouted.
- * The mrouted program is covered by the license in the accompanying file
- * named "LICENSE.mrouted".
- *
- * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
- * Leland Stanford Junior University.
- *
- * $FreeBSD$
- */
-
-extern unsigned long debug;
-extern int log_nmsgs;
-#define IF_DEBUG(l) if (debug && debug & (l))
-
-#define LOG_MAX_MSGS 20 /* if > 20/minute then shut up for a while */
-#define LOG_SHUT_UP 600 /* shut up for 10 minutes */
-
-
-/* Debug values definition */
-/* DVMRP reserved for future use */
-#define DEBUG_DVMRP_PRUNE 0x00000001
-#define DEBUG_DVMRP_ROUTE 0x00000002
-#define DEBUG_DVMRP_PEER 0x00000004
-#define DEBUG_DVMRP_TIMER 0x00000008
-#define DEBUG_DVMRP_DETAIL 0x01000000
-#define DEBUG_DVMRP ( DEBUG_DVMRP_PRUNE | DEBUG_DVMRP_ROUTE | \
- DEBUG_DVMRP_PEER )
-
-/* MLD related */
-#define DEBUG_MLD_PROTO 0x00000010
-#define DEBUG_MLD_TIMER 0x00000020
-#define DEBUG_MLD_MEMBER 0x00000040
-#define DEBUG_MEMBER DEBUG_MLD_MEMBER
-#define DEBUG_MLD ( DEBUG_MLD_PROTO | DEBUG_MLD_TIMER | \
- DEBUG_MLD_MEMBER )
-
-/* Misc */
-#define DEBUG_TRACE 0x00000080
-#define DEBUG_TIMEOUT 0x00000100
-#define DEBUG_PKT 0x00000200
-
-
-/* Kernel related */
-#define DEBUG_IF 0x00000400
-#define DEBUG_KERN 0x00000800
-#define DEBUG_MFC 0x00001000
-#define DEBUG_RSRR 0x00002000
-
-/* PIM related */
-#define DEBUG_PIM_GRAFT 0x02000000
-#define DEBUG_PIM_HELLO 0x00004000
-#define DEBUG_PIM_REGISTER 0x00008000
-#define DEBUG_PIM_JOIN_PRUNE 0x00010000
-#define DEBUG_PIM_BOOTSTRAP 0x00020000
-#define DEBUG_PIM_ASSERT 0x00040000
-#define DEBUG_PIM_CAND_RP 0x00080000
-#define DEBUG_PIM_MRT 0x00100000
-#define DEBUG_PIM_TIMER 0x00200000
-#define DEBUG_PIM_RPF 0x00400000
-#define DEBUG_RPF DEBUG_PIM_RPF
-#define DEBUG_PIM_DETAIL 0x00800000
-#define DEBUG_PIM ( DEBUG_PIM_HELLO | DEBUG_PIM_REGISTER | \
- DEBUG_PIM_JOIN_PRUNE | DEBUG_PIM_BOOTSTRAP | \
- DEBUG_PIM_ASSERT | DEBUG_PIM_CAND_RP | \
- DEBUG_PIM_MRT | DEBUG_PIM_TIMER | \
- DEBUG_PIM_RPF | DEBUG_PIM_GRAFT )
-
-#define DEBUG_MRT ( DEBUG_DVMRP_ROUTE | DEBUG_PIM_MRT )
-#define DEBUG_NEIGHBORS ( DEBUG_DVMRP_PEER | DEBUG_PIM_HELLO )
-#define DEBUG_TIMER ( DEBUG_MLD_TIMER | DEBUG_DVMRP_TIMER | \
- DEBUG_PIM_TIMER )
-#define DEBUG_ASSERT ( DEBUG_PIM_ASSERT )
-#define DEBUG_ALL 0xffffffff
-
-
-#define DEBUG_DEFAULT 0xffffffff/* default if "-d" given without value */
-
-
-
-
-
-
diff --git a/usr.sbin/pim6dd/defs.h b/usr.sbin/pim6dd/defs.h
deleted file mode 100644
index f5c2d31..0000000
--- a/usr.sbin/pim6dd/defs.h
+++ /dev/null
@@ -1,606 +0,0 @@
-/*
- * Copyright (c) 1998 by the University of Oregon.
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation in source and binary forms for lawful
- * purposes and without fee is hereby granted, provided
- * that the above copyright notice appear in all copies and that both
- * the copyright notice and this permission notice appear in supporting
- * documentation, and that any documentation, advertising materials,
- * and other materials related to such distribution and use acknowledge
- * that the software was developed by the University of Oregon.
- * The name of the University of Oregon may not be used to endorse or
- * promote products derived from this software without specific prior
- * written permission.
- *
- * THE UNIVERSITY OF OREGON DOES NOT MAKE ANY REPRESENTATIONS
- * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. THIS SOFTWARE IS
- * PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
- * NON-INFRINGEMENT.
- *
- * IN NO EVENT SHALL UO, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT,
- * TORT, OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH,
- * THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Other copyrights might apply to parts of this software and are so
- * noted when applicable.
- */
-/*
- * Questions concerning this software should be directed to
- * Kurt Windisch (kurtw@antc.uoregon.edu)
- *
- * $Id: defs.h,v 1.9 2000/10/05 22:20:38 itojun Exp $
- */
-/*
- * Part of this program has been derived from PIM sparse-mode pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- * The pimd program is COPYRIGHT 1998 by University of Southern California.
- *
- * Part of this program has been derived from mrouted.
- * The mrouted program is covered by the license in the accompanying file
- * named "LICENSE.mrouted".
- *
- * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
- * Leland Stanford Junior University.
- *
- * $FreeBSD$
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <errno.h>
-#include <syslog.h>
-#include <signal.h>
-#include <string.h>
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <sys/queue.h>
-#include <fcntl.h>
-#if ((defined(SYSV)) || (defined(__bsdi__)) || ((defined SunOS) && (SunOS < 50)))
-#include <sys/sockio.h>
-#endif /* SYSV || __bsdi__ || SunOS 4.x */
-#include <sys/time.h>
-#include <net/if.h>
-#if defined(__FreeBSD__) && __FreeBSD__ >= 3
-#include <net/if_var.h>
-#endif /* __FreeBSD__ >= 3 */
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/icmp6.h>
-
-#include <netinet6/in6_var.h>
-#include <netinet/ip6.h>
-
-#include <arpa/inet.h>
-#ifdef __FreeBSD__ /* sigh */
-#include <osreldate.h>
-#endif /* __FreeBSD__ */
-#if (defined(__bsdi__)) || (defined(__FreeBSD__) && (__FreeBSD_version >= 220000))
-#define rtentry kernel_rtentry
-#include <net/route.h>
-#undef rtentry
-#endif /* __bsdi__ or __FreeBSD_version >= 220000 */
-#include <netinet/ip_mroute.h>
-#include <netinet6/ip6_mroute.h>
-#include <strings.h>
-#ifdef RSRR
-#include <sys/un.h>
-#endif /* RSRR */
-
-typedef u_int u_int32;
-typedef u_short u_int16;
-typedef u_char u_int8;
-
-#ifndef __P
-#ifdef __STDC__
-#define __P(x) x
-#else
-#define __P(x) ()
-#endif
-#endif
-
-typedef void (*cfunc_t) __P((void *));
-typedef void (*ihfunc_t) __P((int, fd_set *));
-
-#include "pimdd.h"
-#include "mrt.h"
-#include "mld6.h"
-#include "vif.h"
-#include "debug.h"
-#include "pathnames.h"
-#ifdef RSRR
-#include "rsrr.h"
-#include "rsrr_var.h"
-#endif /* RSRR */
-
-/*
- * Miscellaneous constants and macros
- */
-/* #if (!(defined(__bsdi__)) && !(defined(KERNEL))) */
-#ifndef KERNEL
-#define max(a, b) ((a) < (b) ? (b) : (a))
-#define min(a, b) ((a) > (b) ? (b) : (a))
-#endif
-
-/*
- * Various definitions to make it working for different platforms
- */
-/* The old style sockaddr definition doesn't have sa_len */
-#if (defined(BSD) && (BSD >= 199006)) /* sa_len was added with 4.3-Reno */
-#define HAVE_SA_LEN
-#endif
-
-/* Versions of Solaris older than 2.6 don't have routing sockets. */
-/* XXX TODO: check FreeBSD version and add all other platforms */
-#if ((defined(SunOS) && SunOS >=56) || (defined __FreeBSD__) || (defined IRIX) || (defined __bsdi__) || defined(__NetBSD__))
-#define HAVE_ROUTING_SOCKETS
-#endif
-
-#define TRUE 1
-#define FALSE 0
-
-#define CREATE TRUE
-#define DONT_CREATE FALSE
-
-#define EQUAL(s1, s2) (strcmp((s1), (s2)) == 0)
-
-/* obnoxious gcc gives an extraneous warning about this constant... */
-#if defined(__STDC__) || defined(__GNUC__)
-#define JAN_1970 2208988800UL /* 1970 - 1900 in seconds */
-#else
-#define JAN_1970 2208988800L /* 1970 - 1900 in seconds */
-#define const /**/
-#endif
-
-
-#define MINHLIM 1 /* min hoplim in the packets send locally */
-
-#define MAX_IP_PACKET_LEN 576
-#define MIN_IP_HEADER_LEN 20
-#define MAX_IP_HEADER_LEN 60
-
-
-/*
- * The IGMPv2 <netinet/in.h> defines INADDR_ALLRTRS_GROUP, but earlier
- * ones don't, so we define it conditionally here.
- */
-#ifndef INADDR_ALLRTRS_GROUP
- /* address for multicast mtrace msg */
-#define INADDR_ALLRTRS_GROUP (u_int32)0xe0000002 /* 224.0.0.2 */
-#endif
-
-#ifndef INADDR_MAX_LOCAL_GROUP
-define INADDR_MAX_LOCAL_GROUP (u_int32)0xe00000ff /* 224.0.0.255 */
-#endif
-
-#define INADDR_ANY_N (u_int32)0x00000000 /* INADDR_ANY in
- * network order */
-#define CLASSD_PREFIX (u_int32)0xe0000000 /* 224.0.0.0 */
-#define ALL_MCAST_GROUPS_ADDR (u_int32)0xe0000000 /* 224.0.0.0 */
-#define ALL_MCAST_GROUPS_LENGTH 4
-
-/* Used by DVMRP */
-#define DEFAULT_METRIC 1 /* default subnet/tunnel metric */
-#define DEFAULT_THRESHOLD 1 /* default subnet/tunnel threshold */
-
-#define TIMER_INTERVAL 5 /* 5 sec virtual timer granularity */
-
-#ifdef RSRR
-#define BIT_ZERO(X) ((X) = 0)
-#define BIT_SET(X,n) ((X) |= 1 << (n))
-#define BIT_CLR(X,n) ((X) &= ~(1 << (n)))
-#define BIT_TST(X,n) ((X) & 1 << (n))
-#endif /* RSRR */
-
-#ifdef SYSV
-#define bcopy(a, b, c) memcpy((b), (a), (c))
-#define bzero(s, n) memset((s), 0, (n))
-#define setlinebuf(s) setvbuf((s), (NULL), (_IOLBF), 0)
-#define RANDOM() lrand48()
-#else
-#define RANDOM() random()
-#endif /* SYSV */
-
-/*
- * External declarations for global variables and functions.
- */
-#define RECV_BUF_SIZE 64*1024 /* Maximum buff size to send
- * or receive packet */
-#define SO_RECV_BUF_SIZE_MAX 256*1024
-#define SO_RECV_BUF_SIZE_MIN 48*1024
-
-/* TODO: describe the variables and clean up */
-extern char *mld6_recv_buf;
-extern char *mld6_send_buf;
-extern char *pim6_recv_buf;
-extern char *pim6_send_buf;
-extern int mld6_socket;
-extern int pim6_socket;
-extern struct sockaddr_in6 allnodes_group;
-extern struct sockaddr_in6 allrouters_group;
-extern struct sockaddr_in6 allpim6routers_group;
-extern if_set nbr_mifs;
-
-#ifdef RSRR
-extern int rsrr_socket;
-#endif /* RSRR */
-
-extern u_long virtual_time;
-extern char configfilename[];
-
-extern u_int32 default_source_metric;
-extern u_int32 default_source_preference;
-
-extern srcentry_t *srclist;
-extern grpentry_t *grplist;
-
-extern struct uvif uvifs[];
-extern vifi_t numvifs;
-extern int total_interfaces;
-extern int phys_vif;
-extern int udp_socket;
-
-extern int vifs_down;
-
-extern char s1[];
-extern char s2[];
-extern char s3[];
-extern char s4[];
-
-#if !(defined(BSD) && (BSD >= 199103))
-extern int errno;
-extern int sys_nerr;
-extern char * sys_errlist[];
-#endif
-
-
-#ifndef IGMP_MEMBERSHIP_QUERY
-#define IGMP_MEMBERSHIP_QUERY IGMP_HOST_MEMBERSHIP_QUERY
-#if !(defined(__NetBSD__))
-#define IGMP_V1_MEMBERSHIP_REPORT IGMP_HOST_MEMBERSHIP_REPORT
-#define IGMP_V2_MEMBERSHIP_REPORT IGMP_HOST_NEW_MEMBERSHIP_REPORT
-#else
-#define IGMP_V1_MEMBERSHIP_REPORT IGMP_v1_HOST_MEMBERSHIP_REPORT
-#define IGMP_V2_MEMBERSHIP_REPORT IGMP_v2_HOST_MEMBERSHIP_REPORT
-#endif
-#define IGMP_V2_LEAVE_GROUP IGMP_HOST_LEAVE_MESSAGE
-#endif
-
-#if defined(__NetBSD__)
-#define IGMP_MTRACE_RESP IGMP_MTRACE_REPLY
-#define IGMP_MTRACE IGMP_MTRACE_QUERY
-#endif
-
-/* For timeout. The timers count down */
-#define SET_TIMER(timer, value) (timer) = (value)
-#define IF_TIMER_SET(timer) if ((timer) > 0)
-#define IF_TIMER_NOT_SET(timer) if ((timer) <= 0)
-#define FIRE_TIMER(timer) (timer) = 0
-
-#define IF_TIMEOUT(value) \
- if (!(((value) >= TIMER_INTERVAL) && ((value) -= TIMER_INTERVAL)))
-
-#define IF_NOT_TIMEOUT(value) \
- if (((value) >= TIMER_INTERVAL) && ((value) -= TIMER_INTERVAL))
-
-#define TIMEOUT(value) \
- (!(((value) >= TIMER_INTERVAL) && ((value) -= TIMER_INTERVAL)))
-
-#define NOT_TIMEOUT(value) \
- (((value) >= TIMER_INTERVAL) && ((value) -= TIMER_INTERVAL))
-
-#define ELSE else /* To make emacs cc-mode happy */
-
-
-/*
- * External function definitions
- */
-
-/* callout.c */
-extern void callout_init __P((void));
-extern void free_all_callouts __P((void));
-extern void age_callout_queue __P((int));
-extern int timer_nextTimer __P((void));
-extern int timer_setTimer __P((int, cfunc_t, void *));
-extern void timer_clearTimer __P((int));
-extern int timer_leftTimer __P((int));
-
-/* config.c */
-extern void config_vifs_from_kernel __P((void));
-extern void config_vifs_from_file __P((void));
-
-/* debug.c */
-extern char *packet_kind __P((u_int proto, u_int type, u_int code));
-extern int debug_kind __P((u_int proto, u_int type, u_int code));
-extern void log __P((int, int, char *, ...))
- __attribute__((__format__(__printf__, 3, 4)));
-extern void dump_mldqueriers __P((FILE *));
-extern int log_level __P((u_int proto, u_int type, u_int code));
-extern void dump __P((int i));
-extern void fdump __P((int i));
-extern void cdump __P((int i));
-extern void dump_vifs __P((FILE *fp));
-extern void dump_pim_mrt __P((FILE *fp));
-extern void dump_lcl_grp __P((FILE *fp));
-
-/* dvmrp_proto.c */
-extern void dvmrp_accept_probe __P((u_int32 src, u_int32 dst,
- char *p, int datalen,
- u_int32 level));
-extern void dvmrp_accept_report __P((u_int32 src, u_int32 dst,
- char *p, int datalen,
- u_int32 level));
-extern void dvmrp_accept_info_request __P((u_int32 src, u_int32 dst,
- u_char *p, int datalen));
-extern void dvmrp_accept_info_reply __P((u_int32 src, u_int32 dst,
- u_char *p, int datalen));
-extern void dvmrp_accept_neighbors __P((u_int32 src, u_int32 dst,
- u_char *p, int datalen,
- u_int32 level));
-extern void dvmrp_accept_neighbors2 __P((u_int32 src, u_int32 dst,
- u_char *p, int datalen,
- u_int32 level));
-extern void dvmrp_accept_prune __P((u_int32 src, u_int32 dst,
- char *p, int datalen));
-extern void dvmrp_accept_graft __P((u_int32 src, u_int32 dst,
- char *p, int datalen));
-extern void dvmrp_accept_g_ack __P((u_int32 src, u_int32 dst,
- char *p, int datalen));
-/* mld6.c */
-void init_mld6 __P((void));
-void send_mld6 __P((int type, int code, struct sockaddr_in6 *src,
- struct sockaddr_in6 *dst, struct in6_addr *group,
- int index, int delay, int datalen, int alert));
-
-/* mld6_proto.c */
-extern void query_groups __P((struct uvif *v));
-extern int check_grp_membership __P((struct uvif *v,
- struct sockaddr_in6 *group));
-extern void accept_listener_query __P((struct sockaddr_in6 *src,
- struct in6_addr *dst,
- struct in6_addr *group,
- int tmo));
-extern void accept_listener_report __P((struct sockaddr_in6 *src,
- struct in6_addr *dst,
- struct in6_addr *group));
-extern void accept_listener_done __P((struct sockaddr_in6 *src,
- struct in6_addr *dst,
- struct in6_addr *group));
-extern int check_multicast_listener __P((struct uvif *v,
- struct sockaddr_in6 *group));
-
-/* igmp.c */
-#if 0
-extern void init_igmp __P((void));
-extern void send_igmp __P((char *buf, u_int32 src, u_int32 dst,
- int type, int code, u_int32 group,
- int datalen));
-
-/* igmp_proto.c */
-extern void query_groups __P((struct uvif *v));
-extern void accept_membership_query __P((u_int32 src, u_int32 dst,
- u_int32 group, int tmo));
-extern void accept_group_report __P((u_int32 src, u_int32 dst,
- u_int32 group, int r_type));
-extern void accept_leave_message __P((u_int32 src, u_int32 dst,
- u_int32 group));
-#endif
-
-#if 0
-/* inet.c */
-extern int inet_cksum __P((u_int16 *addr, u_int len));
-extern int inet_valid_host __P((u_int32 naddr));
-extern int inet_valid_mask __P((u_int32 mask));
-extern int inet_valid_subnet __P((u_int32 nsubnet, u_int32 nmask));
-extern char *inet_fmt __P((u_int32, char *s));
-#ifdef NOSUCHDEF
-extern char *inet_fmts __P((u_int32 addr, u_int32 mask, char *s));
-#endif /* NOSUCHDEF */
-extern char *netname __P((u_int32 addr, u_int32 mask));
-extern u_int32 inet_parse __P((char *s, int n));
-#endif
-
-/* inet6.c */
-extern int inet6_equal __P((struct sockaddr_in6 *sa1,
- struct sockaddr_in6 *sa2));
-extern int inet6_lessoreq __P((struct sockaddr_in6 *sa1,
- struct sockaddr_in6 *sa2));
-extern int inet6_lessthan __P((struct sockaddr_in6 *sa1,
- struct sockaddr_in6 *sa2));
-extern int inet6_localif_address __P((struct sockaddr_in6 *sa,
- struct uvif *v));
-extern int inet6_greaterthan __P((struct sockaddr_in6 *sa1,
- struct sockaddr_in6 *sa2));
-extern int inet6_greateroreq __P((struct sockaddr_in6 *sa1,
- struct sockaddr_in6 *sa2));
-extern int inet6_match_prefix __P((struct sockaddr_in6 *sa1,
- struct sockaddr_in6 *sa2,
- struct in6_addr *mask));
-extern int inet6_mask2plen __P((struct in6_addr *mask));
-extern int inet6_uvif2scopeid __P((struct sockaddr_in6 *sa, struct uvif *v));
-extern int inet6_valid_host __P((struct sockaddr_in6 *addr));
-extern char *inet6_fmt __P((struct in6_addr *addr));
-extern char *ifindex2str __P((int ifindex));
-extern char *net6name __P((struct in6_addr *prefix,
- struct in6_addr *mask));
-
-/* kern.c */
-extern void k_set_rcvbuf __P((int socket, int bufsize, int minsize));
-extern void k_hdr_include __P((int socket, int bool));
-extern void k_set_hlim __P((int socket, int t));
-extern void k_set_loop __P((int socket, int l));
-extern void k_set_if __P((int socket, u_int ifindex));
-extern void k_join __P((int socket, struct in6_addr *grp,
- u_int ifindex));
-extern void k_leave __P((int socket, struct in6_addr *grp,
- u_int ifindex));
-extern void k_init_pim __P((int));
-extern void k_stop_pim __P((int));
-extern int k_del_mfc __P((int socket, struct sockaddr_in6 *source,
- struct sockaddr_in6 *group));
-extern int k_chg_mfc __P((int socket, struct sockaddr_in6 *source,
- struct sockaddr_in6 *group, vifi_t iif,
- if_set *oifs));
-extern void k_add_vif __P((int socket, vifi_t vifi, struct uvif *v));
-extern void k_del_vif __P((int socket, vifi_t vifi));
-extern int k_get_vif_count __P((vifi_t vifi, struct vif_count *retval));
-extern int k_get_sg_cnt __P((int socket, struct sockaddr_in6 *source,
- struct sockaddr_in6 *group,
- struct sg_count *retval));
-
-/* main.c */
-extern int register_input_handler __P((int fd, ihfunc_t func));
-
-/* mrt.c */
-extern void init_pim6_mrt __P((void));
-extern mrtentry_t *find_route __P((struct sockaddr_in6 *source,
- struct sockaddr_in6 *group,
- u_int16 flags, char create));
-extern grpentry_t *find_group __P((struct sockaddr_in6 *group));
-extern srcentry_t *find_source __P((struct sockaddr_in6 *source));
-extern void delete_mrtentry __P((mrtentry_t *mrtentry_ptr));
-extern void delete_srcentry __P((srcentry_t *srcentry_ptr));
-extern void delete_grpentry __P((grpentry_t *grpentry_ptr));
-extern struct mrtfilter *search_filter __P((struct in6_addr *));
-extern struct mrtfilter *add_filter __P((int, struct in6_addr *,
- struct in6_addr *, int));
-
-/* pim6.c */
-extern void init_pim6 __P((void));
-extern void send_pim6 __P((char *buf, struct sockaddr_in6 *src,
- struct sockaddr_in6 *dst,
- int type, int datalen));
-
-/* pim6_poto.c */
-extern int receive_pim6_hello __P((struct sockaddr_in6 *src,
- char *pim_message, int datalen));
-extern int send_pim6_hello __P((struct uvif *v, u_int16 holdtime));
-extern void delete_pim6_nbr __P((pim_nbr_entry_t *nbr_delete));
-extern int receive_pim6_join_prune __P((struct sockaddr_in6 *src,
- char *pim_message, int datalen));
-extern int send_pim6_jp __P((mrtentry_t *mrtentry_ptr, int action,
- mifi_t mifi,
- struct sockaddr_in6 *target_addr,
- u_int16 holdtime, int echo));
-
-extern int receive_pim6_assert __P((struct sockaddr_in6 *src,
- char *pim_message, int datalen));
-extern int send_pim6_assert __P((struct sockaddr_in6 *source,
- struct sockaddr_in6 *group,
- mifi_t mifi,
- mrtentry_t *mrtentry_ptr));
-extern void delete_pim6_graft_entry __P((mrtentry_t *mrtentry_ptr));
-extern int receive_pim6_graft __P((struct sockaddr_in6 *src,
- char *pim_message, int datalen,
- int pimtype));
-extern int send_pim6_graft __P((mrtentry_t *mrtentry_ptr));
-
-#if 0
-/* pim.c */
-extern void init_pim __P((void));
-extern void send_pim __P((char *buf, u_int32 src, u_int32 dst,
- int type, int datalen));
-extern void send_pim_unicast __P((char *buf, u_int32 src, u_int32 dst,
- int type, int datalen));
-/* pim_proto.c */
-extern int receive_pim_hello __P((u_int32 src, u_int32 dst,
- char *pim_message, int datalen));
-extern int send_pim_hello __P((struct uvif *v, u_int16 holdtime));
-extern void delete_pim_nbr __P((pim_nbr_entry_t *nbr_delete));
-extern int receive_pim_join_prune __P((u_int32 src, u_int32 dst,
- char *pim_message, int datalen));
-extern int send_pim_jp __P((mrtentry_t *mrtentry_ptr, int action,
- vifi_t vifi, u_int32 target_addr,
- u_int16 holdtime));
-extern int receive_pim_assert __P((u_int32 src, u_int32 dst,
- char *pim_message, int datalen));
-extern int send_pim_assert __P((u_int32 source, u_int32 group,
- vifi_t vifi,
- mrtentry_t *mrtentry_ptr));
-extern void delete_pim_graft_entry __P((mrtentry_t *mrtentry_ptr));
-extern int receive_pim_graft __P((u_int32 src, u_int32 dst,
- char *pim_message, int datalen,
- int pimtype));
-#endif
-
-/* route.c */
-extern int set_incoming __P((srcentry_t *srcentry_ptr,
- int srctype));
-extern vifi_t get_iif __P((struct sockaddr_in6 *source));
-extern pim_nbr_entry_t *find_pim6_nbr __P((struct sockaddr_in6 *source));
-extern int add_sg_oif __P((mrtentry_t *mrtentry_ptr,
- vifi_t vifi,
- u_int16 holdtime,
- int update_holdtime));
-extern void add_leaf __P((vifi_t vifi,
- struct sockaddr_in6 *source,
- struct sockaddr_in6 *group));
-extern void delete_leaf __P((vifi_t vifi,
- struct sockaddr_in6 *source,
- struct sockaddr_in6 *group));
-extern void set_leaves __P((mrtentry_t *mrtentry_ptr));
-extern int change_interfaces __P((mrtentry_t *mrtentry_ptr,
- vifi_t new_iif,
- if_set *new_pruned_oifs,
- if_set *new_leaves_,
- if_set *new_asserted_oifs));
-extern void calc_oifs __P((mrtentry_t *mrtentry_ptr,
- if_set *oifs_ptr));
-extern void process_kernel_call __P((void));
-extern int delete_vif_from_mrt __P((vifi_t vifi));
-extern void trigger_join_alert __P((mrtentry_t *mrtentry_ptr));
-extern void trigger_prune_alert __P((mrtentry_t *mrtentry_ptr));
-
-
-/* routesock.c */
-extern int k_req_incoming __P((struct sockaddr_in6 *source,
- struct rpfctl *rpfp));
-#ifdef HAVE_ROUTING_SOCKETS
-extern int init_routesock __P((void));
-#endif /* HAVE_ROUTING_SOCKETS */
-
-#ifdef RSRR
-#define gtable mrtentry
-#define RSRR_NOTIFICATION_OK TRUE
-#define RSRR_NOTIFICATION_FALSE FALSE
-
-/* rsrr.c */
-extern void rsrr_init __P((void));
-extern void rsrr_clean __P((void));
-extern void rsrr_cache_send __P((struct gtable *, int));
-extern void rsrr_cache_clean __P((struct gtable *));
-extern void rsrr_cache_bring_up __P((struct gtable *));
-#endif /* RSRR */
-
-/* timer.c */
-extern void init_timers __P((void));
-extern void age_vifs __P((void));
-extern void age_routes __P((void));
-extern int clean_srclist __P((void));
-
-/* trace.c */
-/* u_int is promoted u_char */
-extern void accept_mtrace __P((struct sockaddr_in6 *src,
- struct in6_addr *dst, struct in6_addr *group,
- int ifindex, char *data, u_int no, int datalen));
-
-/* vif.c */
-extern void init_vifs __P((void));
-extern void stop_all_vifs __P((void));
-extern void check_vif_state __P((void));
-extern vifi_t local_address __P((struct sockaddr_in6 *src));
-extern vifi_t find_vif_direct __P((struct sockaddr_in6 *src));
-extern vifi_t find_vif_direct_local __P((struct sockaddr_in6 *src));
-extern struct sockaddr_in6 *max_global_address __P((void));
-extern struct sockaddr_in6 *uv_global __P((vifi_t vifi));
diff --git a/usr.sbin/pim6dd/inet6.c b/usr.sbin/pim6dd/inet6.c
deleted file mode 100644
index 3caddfd..0000000
--- a/usr.sbin/pim6dd/inet6.c
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Copyright (C) 1998 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include "defs.h"
-
-int
-inet6_uvif2scopeid(struct sockaddr_in6 *sa, struct uvif *v)
-{
- if (IN6_IS_ADDR_MULTICAST(&sa->sin6_addr)) {
- if (IN6_IS_ADDR_MC_LINKLOCAL(&sa->sin6_addr))
- return(v->uv_ifindex);
- if (IN6_IS_ADDR_MC_SITELOCAL(&sa->sin6_addr))
- return(v->uv_siteid);
- }
- else {
- if (IN6_IS_ADDR_LINKLOCAL(&sa->sin6_addr))
- return(v->uv_ifindex);
-
- if (IN6_IS_ADDR_SITELOCAL(&sa->sin6_addr))
- return(v->uv_siteid);
- }
-
- return(0);
-}
-
-int
-inet6_localif_address(struct sockaddr_in6 *sa, struct uvif *v)
-{
- struct phaddr *pa;
-
- for (pa = v->uv_addrs; pa; pa = pa->pa_next)
- if (inet6_equal(sa, &pa->pa_addr))
- return(TRUE);
-
- return(FALSE);
-}
-
-int
-inet6_valid_host(struct sockaddr_in6 *addr)
-{
- if (IN6_IS_ADDR_MULTICAST(&addr->sin6_addr))
- return(FALSE);
-
- return(TRUE);
-}
-
-int
-inet6_equal(struct sockaddr_in6 *sa1, struct sockaddr_in6 *sa2)
-{
- if (sa1->sin6_scope_id == sa2->sin6_scope_id &&
- IN6_ARE_ADDR_EQUAL(&sa1->sin6_addr, &sa2->sin6_addr))
- return(1);
-
- return(0);
-}
-
-int
-inet6_lessthan(struct sockaddr_in6 *sa1, struct sockaddr_in6 *sa2)
-{
- u_int32_t s32_1, s32_2;
- int i;
-
- if (sa1->sin6_scope_id < sa2->sin6_scope_id)
- return(1);
- if (sa1->sin6_scope_id == sa2->sin6_scope_id) {
- for (i = 0; i < 4; i++) {
- s32_1 = ntohl(*(u_int32_t *)&sa1->sin6_addr.s6_addr[i * 4]);
- s32_2 = ntohl(*(u_int32_t *)&sa2->sin6_addr.s6_addr[i * 4]);
-
- if (s32_1 > s32_2)
- return(0);
- if (s32_1 < s32_2)
- return(1);
-
- /* otherwide, continue to compare */
- }
- }
-
- return(0);
-}
-
-int
-inet6_lessoreq(struct sockaddr_in6 *sa1, struct sockaddr_in6 *sa2)
-{
- u_int32_t s32_1, s32_2;
- int i;
-
- if (sa1->sin6_scope_id < sa2->sin6_scope_id)
- return(1);
- if (sa1->sin6_scope_id == sa2->sin6_scope_id) {
- for (i = 0; i < 4; i++) {
- s32_1 = ntohl(*(u_int32_t *)&sa1->sin6_addr.s6_addr[i * 4]);
- s32_2 = ntohl(*(u_int32_t *)&sa2->sin6_addr.s6_addr[i * 4]);
-
- if (s32_1 > s32_2)
- return(0);
- if (s32_1 < s32_2)
- return(1);
-
- /* otherwide, continue to compare */
- }
- /* sa1 == sa2 */
- return(1);
- }
-
- return(0);
-}
-
-int
-inet6_greaterthan(struct sockaddr_in6 *sa1, struct sockaddr_in6 *sa2)
-{
- u_int32_t s32_1, s32_2;
- int i;
-
- if (sa1->sin6_scope_id > sa2->sin6_scope_id)
- return(1);
- if (sa1->sin6_scope_id == sa2->sin6_scope_id) {
- for (i = 0; i < 4; i++) {
- s32_1 = ntohl(*(u_int32_t *)&sa1->sin6_addr.s6_addr[i * 4]);
- s32_2 = ntohl(*(u_int32_t *)&sa2->sin6_addr.s6_addr[i * 4]);
-
- if (s32_1 < s32_2)
- return(0);
- if (s32_1 > s32_2)
- return(1);
-
- /* otherwide, continue to compare */
- }
- }
-
- return(0);
-}
-
-int
-inet6_greateroreq(struct sockaddr_in6 *sa1, struct sockaddr_in6 *sa2)
-{
- u_int32_t s32_1, s32_2;
- int i;
-
- if (sa1->sin6_scope_id > sa2->sin6_scope_id)
- return(1);
- if (sa1->sin6_scope_id == sa2->sin6_scope_id) {
- for (i = 0; i < 4; i++) {
- s32_1 = ntohl(*(u_int32_t *)&sa1->sin6_addr.s6_addr[i * 4]);
- s32_2 = ntohl(*(u_int32_t *)&sa2->sin6_addr.s6_addr[i * 4]);
-
- if (s32_1 < s32_2)
- return(0);
- if (s32_1 > s32_2)
- return(1);
-
- /* otherwide, continue to compare */
- }
- /* sa1 == sa2 */
- return(1);
- }
-
- return(0);
-}
-
-int
-inet6_match_prefix(sa1, sa2, mask)
- struct sockaddr_in6 *sa1, *sa2;
- struct in6_addr *mask;
-{
- int i;
-
- if (sa1->sin6_scope_id != sa2->sin6_scope_id)
- return(0);
-
- for (i = 0; i < 16; i++) {
- if ((sa1->sin6_addr.s6_addr[i] ^ sa2->sin6_addr.s6_addr[i]) &
- mask->s6_addr[i])
- return(0);
- }
-
- return(1);
-}
-
-char *
-inet6_fmt(struct in6_addr *addr)
-{
- static char ip6buf[8][INET6_ADDRSTRLEN];
- static int ip6round = 0;
- char *cp;
-
- ip6round = (ip6round + 1) & 7;
- cp = ip6buf[ip6round];
-
- inet_ntop(AF_INET6, addr, cp, INET6_ADDRSTRLEN);
- return(cp);
-}
-
-char *
-ifindex2str(int ifindex)
-{
- static char ifname[IFNAMSIZ];
-
- return(if_indextoname(ifindex, ifname));
-}
-
-int
-inet6_mask2plen(struct in6_addr *mask)
-{
- int masklen;
- u_char *p = (u_char *)mask;
- u_char *lim = p + 16;
-
- for (masklen = 0; p < lim; p++) {
- switch (*p) {
- case 0xff:
- masklen += 8;
- break;
- case 0xfe:
- masklen += 7;
- break;
- case 0xfc:
- masklen += 6;
- break;
- case 0xf8:
- masklen += 5;
- break;
- case 0xf0:
- masklen += 4;
- break;
- case 0xe0:
- masklen += 3;
- break;
- case 0xc0:
- masklen += 2;
- break;
- case 0x80:
- masklen += 1;
- break;
- case 0x00:
- break;
- }
- }
-
- return(masklen);
-}
-
-char *
-net6name(struct in6_addr *prefix, struct in6_addr *mask)
-{
- static char ip6buf[8][INET6_ADDRSTRLEN + 4]; /* length of addr/plen */
- static int ip6round = 0;
- char *cp;
-
- ip6round = (ip6round + 1) & 7;
- cp = ip6buf[ip6round];
-
- inet_ntop(AF_INET6, prefix, cp, INET6_ADDRSTRLEN);
- cp += strlen(cp);
- *cp = '/';
- cp++;
- sprintf(cp, "%d", inet6_mask2plen(mask));
-
- return(ip6buf[ip6round]);
-}
diff --git a/usr.sbin/pim6dd/kern.c b/usr.sbin/pim6dd/kern.c
deleted file mode 100644
index 69118dc..0000000
--- a/usr.sbin/pim6dd/kern.c
+++ /dev/null
@@ -1,415 +0,0 @@
-/*
- * Copyright (c) 1998 by the University of Southern California.
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation in source and binary forms for lawful
- * purposes and without fee is hereby granted, provided
- * that the above copyright notice appear in all copies and that both
- * the copyright notice and this permission notice appear in supporting
- * documentation, and that any documentation, advertising materials,
- * and other materials related to such distribution and use acknowledge
- * that the software was developed by the University of Southern
- * California and/or Information Sciences Institute.
- * The name of the University of Southern California may not
- * be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THE UNIVERSITY OF SOUTHERN CALIFORNIA DOES NOT MAKE ANY REPRESENTATIONS
- * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. THIS SOFTWARE IS
- * PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
- * NON-INFRINGEMENT.
- *
- * IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT,
- * TORT, OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH,
- * THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Other copyrights might apply to parts of this software and are so
- * noted when applicable.
- */
-/*
- * Questions concerning this software should be directed to
- * Pavlin Ivanov Radoslavov (pavlin@catarina.usc.edu)
- *
- * $Id: kern.c,v 1.1.1.1 1999/08/08 23:30:52 itojun Exp $
- */
-/*
- * Part of this program has been derived from mrouted.
- * The mrouted program is covered by the license in the accompanying file
- * named "LICENSE.mrouted".
- *
- * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
- * Leland Stanford Junior University.
- *
- * $FreeBSD$
- */
-
-#include "defs.h"
-
-#ifdef RAW_OUTPUT_IS_RAW
-int curttl = 0;
-#endif
-
-
-/*
- * Open/init the multicast routing in the kernel and sets the MRT_ASSERT
- * flag in the kernel.
- *
- */
-void
-k_init_pim(socket)
- int socket;
-{
- int v = 1;
-
- if (setsockopt(socket, IPPROTO_IPV6,
- MRT6_INIT, (char *)&v, sizeof(int)) < 0)
- log(LOG_ERR, errno, "cannot enable multicast routing in kernel");
-
- if(setsockopt(socket, IPPROTO_IPV6,
- MRT6_PIM, (char *)&v, sizeof(int)) < 0)
- log(LOG_ERR, errno, "cannot set ASSERT flag in kernel");
-}
-
-
-/*
- * Stops the multicast routing in the kernel and resets the MRT_ASSERT
- * flag in the kernel.
- */
-void
-k_stop_pim(socket)
- int socket;
-{
- int v = 0;
-
- if(setsockopt(socket, IPPROTO_IPV6, MRT6_PIM,
- (char *)&v, sizeof(int)) < 0)
- log(LOG_ERR, errno, "cannot reset ASSERT flag in kernel");
-
- if (setsockopt(socket, IPPROTO_IPV6, MRT6_DONE, (char *)NULL, 0) < 0)
- log(LOG_ERR, errno, "cannot disable multicast routing in kernel");
-
-}
-
-
-/*
- * Set the socket receiving buffer. `bufsize` is the preferred size,
- * `minsize` is the smallest acceptable size.
- */
-void k_set_rcvbuf(socket, bufsize, minsize)
- int socket;
- int bufsize;
- int minsize;
-{
- int delta = bufsize / 2;
- int iter = 0;
-
- /*
- * Set the socket buffer. If we can't set it as large as we
- * want, search around to try to find the highest acceptable
- * value. The highest acceptable value being smaller than
- * minsize is a fatal error.
- */
- if (setsockopt(socket, SOL_SOCKET, SO_RCVBUF,
- (char *)&bufsize, sizeof(bufsize)) < 0) {
- bufsize -= delta;
- while (1) {
- iter++;
- if (delta > 1)
- delta /= 2;
-
- if (setsockopt(socket, SOL_SOCKET, SO_RCVBUF,
- (char *)&bufsize, sizeof(bufsize)) < 0) {
- bufsize -= delta;
- } else {
- if (delta < 1024)
- break;
- bufsize += delta;
- }
- }
- if (bufsize < minsize) {
- log(LOG_ERR, 0, "OS-allowed buffer size %u < app min %u",
- bufsize, minsize);
- /*NOTREACHED*/
- }
- }
- IF_DEBUG(DEBUG_KERN)
- log(LOG_DEBUG, 0, "Got %d byte buffer size in %d iterations",
- bufsize, iter);
-}
-
-#if 0 /* there is no HDRINCL option in IPv6 */
-/*
- * Set/reset the IP_HDRINCL option. My guess is we don't need it for raw
- * sockets, but having it here won't hurt. Well, unless you are running
- * an older version of FreeBSD (older than 2.2.2). If the multicast
- * raw packet is bigger than 208 bytes, then IP_HDRINCL triggers a bug
- * in the kernel and "panic". The kernel patch for netinet/ip_raw.c
- * coming with this distribution fixes it.
- */
-void k_hdr_include(socket, bool)
- int socket;
- int bool;
-{
-#ifdef IP_HDRINCL
- if (setsockopt(socket, IPPROTO_IP, IP_HDRINCL,
- (char *)&bool, sizeof(bool)) < 0)
- log(LOG_ERR, errno, "setsockopt IP_HDRINCL %u", bool);
-#endif
-}
-#endif /* 0 */
-
-/*
- * Set the default Hop Limit for the multicast packets outgoing from this
- * socket.
- */
-void k_set_hlim(socket, h)
- int socket;
- int h;
-{
-#ifdef RAW_OUTPUT_IS_RAW
- curttl = h;
-#else
- int hlim = h;
-
- if (setsockopt(socket, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
- (char *)&hlim, sizeof(hlim)) < 0)
- log(LOG_ERR, errno, "setsockopt IPV6_MULTICAST_HOPS %u", hlim);
-#endif
-}
-
-
-/*
- * Set/reset the IPV6_MULTICAST_LOOP. Set/reset is specified by "flag".
- */
-void k_set_loop(socket, flag)
- int socket;
- int flag;
-{
- u_int loop;
-
- loop = flag;
- if (setsockopt(socket, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
- (char *)&loop, sizeof(loop)) < 0)
- log(LOG_ERR, errno, "setsockopt IPV6_MULTICAST_LOOP %u", loop);
-}
-
-
-/*
- * Set the IPV6_MULTICAST_IF option on local interface which has the
- * specified index.
- */
-void k_set_if(socket, ifindex)
- int socket;
- u_int ifindex;
-{
- if (setsockopt(socket, IPPROTO_IPV6, IPV6_MULTICAST_IF,
- (char *)&ifindex, sizeof(ifindex)) < 0)
- log(LOG_ERR, errno, "setsockopt IPV6_MULTICAST_IF for %s",
- ifindex2str(ifindex));
-}
-
-
-/*
- * Join a multicast grp group on local interface ifa.
- */
-void k_join(socket, grp, ifindex)
- int socket;
- struct in6_addr *grp;
- u_int ifindex;
-{
- struct ipv6_mreq mreq;
-
- mreq.ipv6mr_multiaddr = *grp;
- mreq.ipv6mr_interface = ifindex;
-
- if (setsockopt(socket, IPPROTO_IPV6, IPV6_JOIN_GROUP,
- (char *)&mreq, sizeof(mreq)) < 0)
- log(LOG_WARNING, errno, "cannot join group %s on interface %s",
- inet6_fmt(grp), ifindex2str(ifindex));
-}
-
-
-/*
- * Leave a multicats grp group on local interface ifa.
- */
-void k_leave(socket, grp, ifindex)
- int socket;
- struct in6_addr *grp;
- u_int ifindex;
-{
- struct ipv6_mreq mreq;
-
- mreq.ipv6mr_multiaddr = *grp;
- mreq.ipv6mr_interface = ifindex;
-
- if (setsockopt(socket, IPPROTO_IPV6, IPV6_LEAVE_GROUP,
- (char *)&mreq, sizeof(mreq)) < 0)
- log(LOG_WARNING, errno, "cannot leave group %s on interface %s",
- inet6_fmt(grp), ifindex2str(ifindex));
-}
-
-
-/*
- * Add a virtual interface in the kernel.
- */
-void k_add_vif(socket, vifi, v)
- int socket;
- vifi_t vifi;
- struct uvif *v;
-{
- struct mif6ctl mc;
-
- mc.mif6c_mifi = vifi;
- /* TODO: only for DVMRP tunnels?
- mc.mif6c_flags = v->uv_flags & VIFF_KERNEL_FLAGS;
- */
- mc.mif6c_flags = v->uv_flags;
-#ifdef notyet
- mc.mif6c_rate_limit = v->uv_rate_limit;
-#endif
- mc.mif6c_pifi = v->uv_ifindex;
-
- if (setsockopt(socket, IPPROTO_IPV6, MRT6_ADD_MIF,
- (char *)&mc, sizeof(mc)) < 0)
- log(LOG_ERR, errno, "setsockopt MRT6_ADD_MIF on mif %d", vifi);
-}
-
-/*
- * Delete a virtual interface in the kernel.
- */
-void k_del_vif(socket, vifi)
- int socket;
- vifi_t vifi;
-{
- if (setsockopt(socket, IPPROTO_IPV6, MRT6_DEL_MIF,
- (char *)&vifi, sizeof(vifi)) < 0)
- log(LOG_ERR, errno, "setsockopt MRT6_DEL_MIF on mif %d", vifi);
-}
-
-
-/*
- * Delete all MFC entries for particular routing entry from the kernel.
- */
-int
-k_del_mfc(socket, source, group)
- int socket;
- struct sockaddr_in6 *source;
- struct sockaddr_in6 *group;
-{
- struct mf6cctl mc;
-
- mc.mf6cc_origin = *source;
- mc.mf6cc_mcastgrp = *group;
-
- if (setsockopt(socket, IPPROTO_IPV6, MRT6_DEL_MFC, (char *)&mc,
- sizeof(mc)) < 0) {
- log(LOG_WARNING, errno, "setsockopt MRT6_DEL_MFC");
- return FALSE;
- }
-
- IF_DEBUG(DEBUG_MFC)
- log(LOG_DEBUG, 0, "Deleted MFC entry: src %s, grp %s",
- inet6_fmt(&source->sin6_addr),
- inet6_fmt(&group->sin6_addr));
-
- return(TRUE);
-}
-
-
-/*
- * Install/modify a MFC entry in the kernel
- */
-int
-k_chg_mfc(socket, source, group, iif, oifs)
- int socket;
- struct sockaddr_in6 *source;
- struct sockaddr_in6 *group;
- vifi_t iif;
- if_set *oifs;
-{
- struct mf6cctl mc;
- vifi_t vifi;
-
- mc.mf6cc_origin = *source;
- mc.mf6cc_mcastgrp = *group;
- mc.mf6cc_parent = iif;
-
- IF_ZERO(&mc.mf6cc_ifset);
- for (vifi = 0; vifi < numvifs; vifi++) {
- if (IF_ISSET(vifi, oifs))
- IF_SET(vifi, &mc.mf6cc_ifset);
- else
- IF_CLR(vifi, &mc.mf6cc_ifset);
- }
-
- if (setsockopt(socket, IPPROTO_IPV6, MRT6_ADD_MFC, (char *)&mc,
- sizeof(mc)) < 0) {
- log(LOG_WARNING, errno,
- "setsockopt MRT6_ADD_MFC for source %s and group %s",
- inet6_fmt(&source->sin6_addr), inet6_fmt(&group->sin6_addr));
- return(FALSE);
- }
- return(TRUE);
-}
-
-
-/*
- * Get packet counters for particular interface
- */
-/*
- * XXX: TODO: currently not used, but keep just in case we need it later.
- */
-int k_get_vif_count(vifi, retval)
- vifi_t vifi;
- struct vif_count *retval;
-{
- struct sioc_mif_req6 mreq;
-
- mreq.mifi = vifi;
- if (ioctl(udp_socket, SIOCGETMIFCNT_IN6, (char *)&mreq) < 0) {
- log(LOG_WARNING, errno, "SIOCGETMIFCNT_IN6 on vif %d", vifi);
- retval->icount = retval->ocount = retval->ibytes =
- retval->obytes = 0xffffffff;
- return (1);
- }
- retval->icount = mreq.icount;
- retval->ocount = mreq.ocount;
- retval->ibytes = mreq.ibytes;
- retval->obytes = mreq.obytes;
- return (0);
-}
-
-
-/*
- * Gets the number of packets, bytes, and number of packets arrived
- * on wrong if in the kernel for particular (S,G) entry.
- */
-int
-k_get_sg_cnt(socket, source, group, retval)
- int socket; /* udp_socket */
- struct sockaddr_in6 *source;
- struct sockaddr_in6 *group;
- struct sg_count *retval;
-{
- struct sioc_sg_req6 sgreq;
-
- sgreq.src = *source;
- sgreq.grp = *group;
- if (ioctl(socket, SIOCGETSGCNT_IN6, (char *)&sgreq) < 0) {
- log(LOG_WARNING, errno, "SIOCGETSGCNT_IN6 on (%s %s)",
- inet6_fmt(&source->sin6_addr), inet6_fmt(&group->sin6_addr));
- retval->pktcnt = retval->bytecnt = retval->wrong_if = ~0; /* XXX */
- return(1);
- }
- retval->pktcnt = sgreq.pktcnt;
- retval->bytecnt = sgreq.bytecnt;
- retval->wrong_if = sgreq.wrong_if;
- return(0);
-}
-
-
-
diff --git a/usr.sbin/pim6dd/main.c b/usr.sbin/pim6dd/main.c
deleted file mode 100644
index 5e518b4..0000000
--- a/usr.sbin/pim6dd/main.c
+++ /dev/null
@@ -1,720 +0,0 @@
-/*
- * Copyright (c) 1998 by the University of Oregon.
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation in source and binary forms for lawful
- * purposes and without fee is hereby granted, provided
- * that the above copyright notice appear in all copies and that both
- * the copyright notice and this permission notice appear in supporting
- * documentation, and that any documentation, advertising materials,
- * and other materials related to such distribution and use acknowledge
- * that the software was developed by the University of Oregon.
- * The name of the University of Oregon may not be used to endorse or
- * promote products derived from this software without specific prior
- * written permission.
- *
- * THE UNIVERSITY OF OREGON DOES NOT MAKE ANY REPRESENTATIONS
- * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. THIS SOFTWARE IS
- * PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
- * NON-INFRINGEMENT.
- *
- * IN NO EVENT SHALL UO, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT,
- * TORT, OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH,
- * THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Other copyrights might apply to parts of this software and are so
- * noted when applicable.
- */
-/*
- * Questions concerning this software should be directed to
- * Kurt Windisch (kurtw@antc.uoregon.edu)
- *
- * $Id: main.c,v 1.4 2000/10/05 22:20:38 itojun Exp $
- */
-/*
- * Part of this program has been derived from PIM sparse-mode pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- * The pimd program is COPYRIGHT 1998 by University of Southern California.
- *
- * Part of this program has been derived from mrouted.
- * The mrouted program is covered by the license in the accompanying file
- * named "LICENSE.mrouted".
- *
- * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
- * Leland Stanford Junior University.
- *
- * $FreeBSD$
- */
-
-#include <paths.h>
-#include "defs.h"
-
-#ifdef SNMP
-#include "snmp.h"
-#endif
-
-char configfilename[256] = _PATH_PIM6D_CONF;
-char versionstring[100];
-
-static char pidfilename[] = _PATH_PIM6D_PID;
-/* TODO: not used
-static char genidfilename[] = _PATH_PIM6D_GENID;
-*/
-
-int haveterminal = 1;
-char *progname;
-
-static int sighandled = 0;
-#define GOT_SIGINT 0x01
-#define GOT_SIGHUP 0x02
-#define GOT_SIGUSR1 0x04
-#define GOT_SIGUSR2 0x08
-#define GOT_SIGALRM 0x10
-
-
-#ifdef SNMP
-#define NHANDLERS 34
-#else
-#define NHANDLERS 3
-#endif
-
-static struct ihandler {
- int fd; /* File descriptor */
- ihfunc_t func; /* Function to call with &fd_set */
-} ihandlers[NHANDLERS];
-static int nhandlers = 0;
-
-static struct debugname {
- char *name;
- int level;
- int nchars;
-} debugnames[] = {
-#if 0
- { "dvmrp_detail", DEBUG_DVMRP_DETAIL, 5 },
- { "dvmrp_prunes", DEBUG_DVMRP_PRUNE, 8 },
- { "dvmrp_pruning", DEBUG_DVMRP_PRUNE, 8 },
- { "dvmrp_mrt", DEBUG_DVMRP_ROUTE, 7 },
- { "dvmrp_routes", DEBUG_DVMRP_ROUTE, 7 },
- { "dvmrp_routing", DEBUG_DVMRP_ROUTE, 7 },
- { "dvmrp_neighbors", DEBUG_DVMRP_PEER, 7 },
- { "dvmrp_peers", DEBUG_DVMRP_PEER, 8 },
- { "dvmrp_hello", DEBUG_DVMRP_PEER, 7 },
- { "dvmrp_timers", DEBUG_DVMRP_TIMER, 7 },
- { "dvmrp", DEBUG_DVMRP, 1 },
- { "igmp_proto", DEBUG_IGMP_PROTO, 6 },
- { "igmp_timers", DEBUG_IGMP_TIMER, 6 },
- { "igmp_members", DEBUG_IGMP_MEMBER, 6 },
- { "groups", DEBUG_MEMBER, 1 },
- { "membership", DEBUG_MEMBER, 2 },
- { "igmp", DEBUG_IGMP, 1 },
-#endif
- { "trace", DEBUG_TRACE, 2 },
- { "mtrace", DEBUG_TRACE, 2 },
- { "traceroute", DEBUG_TRACE, 2 },
- { "timeout", DEBUG_TIMEOUT, 2 },
- { "callout", DEBUG_TIMEOUT, 3 },
- { "pkt", DEBUG_PKT, 2 },
- { "packets", DEBUG_PKT, 2 },
- { "interfaces", DEBUG_IF, 2 },
- { "vif", DEBUG_IF, 1 },
- { "kernel", DEBUG_KERN, 2 },
- { "cache", DEBUG_MFC, 1 },
- { "mfc", DEBUG_MFC, 2 },
- { "k_cache", DEBUG_MFC, 2 },
- { "k_mfc", DEBUG_MFC, 2 },
- { "rsrr", DEBUG_RSRR, 2 },
- { "pim_detail", DEBUG_PIM_DETAIL, 5 },
- { "pim_hello", DEBUG_PIM_HELLO, 5 },
- { "pim_neighbors", DEBUG_PIM_HELLO, 5 },
- { "pim_register", DEBUG_PIM_REGISTER, 5 },
- { "registers", DEBUG_PIM_REGISTER, 2 },
- { "pim_join_prune", DEBUG_PIM_JOIN_PRUNE, 5 },
- { "pim_j_p", DEBUG_PIM_JOIN_PRUNE, 5 },
- { "pim_jp", DEBUG_PIM_JOIN_PRUNE, 5 },
- { "pim_graft", DEBUG_PIM_GRAFT, 5 },
- { "pim_bootstrap", DEBUG_PIM_BOOTSTRAP, 5 },
- { "pim_bsr", DEBUG_PIM_BOOTSTRAP, 5 },
- { "bsr", DEBUG_PIM_BOOTSTRAP, 1 },
- { "bootstrap", DEBUG_PIM_BOOTSTRAP, 1 },
- { "pim_asserts", DEBUG_PIM_ASSERT, 5 },
- { "pim_cand_rp", DEBUG_PIM_CAND_RP, 5 },
- { "pim_c_rp", DEBUG_PIM_CAND_RP, 5 },
- { "pim_rp", DEBUG_PIM_CAND_RP, 6 },
- { "rp", DEBUG_PIM_CAND_RP, 2 },
- { "pim_routes", DEBUG_PIM_MRT, 6 },
- { "pim_routing", DEBUG_PIM_MRT, 6 },
- { "pim_mrt", DEBUG_PIM_MRT, 5 },
- { "pim_timers", DEBUG_PIM_TIMER, 5 },
- { "pim_rpf", DEBUG_PIM_RPF, 6 },
- { "rpf", DEBUG_RPF, 3 },
- { "pim", DEBUG_PIM, 1 },
- { "routes", DEBUG_MRT, 1 },
- { "routing", DEBUG_MRT, 1 },
- { "mrt", DEBUG_MRT, 1 },
- { "routers", DEBUG_NEIGHBORS, 6 },
- { "mrouters", DEBUG_NEIGHBORS, 7 },
- { "neighbors", DEBUG_NEIGHBORS, 1 },
- { "timers", DEBUG_TIMER, 1 },
- { "asserts", DEBUG_ASSERT, 1 },
- { "all", DEBUG_ALL, 2 },
- { "3", 0xffffffff, 1 } /* compat. */
-};
-
-/*
- * Forward declarations.
- */
-static void handler __P((int));
-static void timer __P((void *));
-static void cleanup __P((void));
-static void restart __P((int));
-static void cleanup __P((void));
-static void resetlogging __P((void *));
-
-
-/* To shut up gcc -Wstrict-prototypes */
-int main __P((int argc, char **argv));
-
-int
-register_input_handler(fd, func)
- int fd;
- ihfunc_t func;
-{
- if (nhandlers >= NHANDLERS)
- return -1;
-
- ihandlers[nhandlers].fd = fd;
- ihandlers[nhandlers++].func = func;
-
- return 0;
-}
-
-int
-main(argc, argv)
- int argc;
- char *argv[];
-{
- int dummy, dummysigalrm;
- FILE *fp;
- struct timeval tv, difftime, curtime, lasttime, *timeout;
- fd_set rfds, readers;
- int nfds, n, i, secs;
- extern char todaysversion[];
- struct sigaction sa;
- struct debugname *d;
- char c;
- int tmpd;
-
-
- setlinebuf(stderr);
-
- if (geteuid() != 0) {
- fprintf(stderr, "pim6dd: must be root\n");
- exit(1);
- }
-
- progname = strrchr(argv[0], '/');
- if (progname)
- progname++;
- else
- progname = argv[0];
-
- argv++;
- argc--;
- while (argc > 0 && *argv[0] == '-') {
- if (strcmp(*argv, "-d") == 0) {
- if (argc > 1 && *(argv + 1)[0] != '-') {
- char *p,*q;
- int i, len;
- struct debugname *d;
-
- argv++;
- argc--;
- debug = 0;
- p = *argv; q = NULL;
- while (p) {
- q = strchr(p, ',');
- if (q)
- *q++ = '\0';
- len = strlen(p);
- for (i = 0, d = debugnames;
- i < sizeof(debugnames) / sizeof(debugnames[0]);
- i++, d++)
- if (len >= d->nchars && strncmp(d->name, p, len) == 0)
- break;
- if (i == sizeof(debugnames) / sizeof(debugnames[0])) {
- int j = 0xffffffff;
- int k = 0;
- fprintf(stderr, "Valid debug levels: ");
- for (i = 0, d = debugnames;
- i < sizeof(debugnames) / sizeof(debugnames[0]);
- i++, d++) {
- if ((j & d->level) == d->level) {
- if (k++)
- putc(',', stderr);
- fputs(d->name, stderr);
- j &= ~d->level;
- }
- }
- putc('\n', stderr);
- goto usage;
- }
- debug |= d->level;
- p = q;
- }
- }
- else
- debug = DEBUG_DEFAULT;
- }
- else if (strcmp(*argv, "-c") == 0) {
- if (argc > 1) {
- argv++; argc--;
- strcpy(configfilename, *argv);
- }
- else
- goto usage;
-/* TODO: not implemented */
-#ifdef SNMP
- }
- else if (strcmp(*argv, "-P") == 0) {
- if (argc > 1 && isdigit(*(argv + 1)[0])) {
- argv++, argc--;
- dest_port = atoi(*argv);
- }
- else
- dest_port = DEFAULT_PORT;
-#endif
- }
- else
- goto usage;
- argv++; argc--;
- }
-
- if (argc > 0) {
- usage:
- tmpd = 0xffffffff;
- fprintf(stderr, "usage: pim6dd [-c configfile] [-d [debug_level][,debug_level]]\n");
-
- fprintf(stderr, "debug levels: ");
- c = '(';
- for (d = debugnames; d < debugnames +
- sizeof(debugnames) / sizeof(debugnames[0]); d++) {
- if ((tmpd & d->level) == d->level) {
- tmpd &= ~d->level;
- fprintf(stderr, "%c%s", c, d->name);
- c = ',';
- }
- }
- fprintf(stderr, ")\n");
- exit(1);
- }
-
- if (debug != 0) {
- tmpd = debug;
- fprintf(stderr, "debug level 0x%lx ", debug);
- c = '(';
- for (d = debugnames; d < debugnames +
- sizeof(debugnames) / sizeof(debugnames[0]); d++) {
- if ((tmpd & d->level) == d->level) {
- tmpd &= ~d->level;
- fprintf(stderr, "%c%s", c, d->name);
- c = ',';
- }
- }
- fprintf(stderr, ")\n");
- }
-
-#ifdef LOG_DAEMON
- (void)openlog("pim6dd", LOG_PID, LOG_DAEMON);
- (void)setlogmask(LOG_UPTO(LOG_NOTICE));
-#else
- (void)openlog("pim6dd", LOG_PID);
-#endif /* LOG_DAEMON */
- sprintf(versionstring, "pim6dd version %s", todaysversion);
-
- log(LOG_DEBUG, 0, "%s starting", versionstring);
-
-/* TODO: XXX: use a combination of time and hostid to initialize the random
- * generator.
- */
-#ifdef SYSV
- srand48(time(NULL));
-#else
- {
- struct timeval tm;
- gettimeofday(&tm, NULL);
- srandom(tm.tv_usec + gethostid());
- }
-#endif
-
- callout_init();
-
- /* Start up the log rate-limiter */
- resetlogging(NULL);
-
- init_mld6();
-#if 0
- k_stop_pim(mld6_socket);
- exit(0); /* XXX */
-#endif
- init_pim6();
-
- init_pim6_mrt();
- init_timers();
-
- /* TODO: check the kernel DVMRP/MROUTED/PIM support version */
-
-#ifdef SNMP
- if (i = snmp_init())
- return i;
-#endif /* SNMP */
- init_vifs();
-
-#ifdef RSRR
- rsrr_init();
-#endif /* RSRR */
-
- sa.sa_handler = handler;
- sa.sa_flags = 0; /* Interrupt system calls */
- sigemptyset(&sa.sa_mask);
- sigaction(SIGALRM, &sa, NULL);
- sigaction(SIGHUP, &sa, NULL);
- sigaction(SIGTERM, &sa, NULL);
- sigaction(SIGINT, &sa, NULL);
- sigaction(SIGUSR1, &sa, NULL);
- sigaction(SIGUSR2, &sa, NULL);
-
- FD_ZERO(&readers);
- FD_SET(mld6_socket, &readers);
- nfds = mld6_socket + 1;
- for (i = 0; i < nhandlers; i++) {
- FD_SET(ihandlers[i].fd, &readers);
- if (ihandlers[i].fd >= nfds)
- nfds = ihandlers[i].fd + 1;
- }
-
- IF_DEBUG(DEBUG_IF)
- dump_vifs(stderr);
- IF_DEBUG(DEBUG_PIM_MRT)
- dump_pim_mrt(stderr);
-
- /* schedule first timer interrupt */
- timer_setTimer(TIMER_INTERVAL, timer, NULL);
-
- if (debug == 0) {
- /* Detach from the terminal */
-#ifdef TIOCNOTTY
- int t;
-#endif /* TIOCNOTTY */
-
- haveterminal = 0;
- if (fork())
- exit(0);
- (void)close(0);
- (void)close(1);
- (void)close(2);
- (void)open("/", 0);
- (void)dup2(0, 1);
- (void)dup2(0, 2);
-#if defined(SYSV) || defined(linux)
- (void)setpgrp();
-#else
-#ifdef TIOCNOTTY
- t = open(_PATH_TTY, 2);
- if (t >= 0) {
- (void)ioctl(t, TIOCNOTTY, (char *)0);
- (void)close(t);
- }
-#else
- if (setsid() < 0)
- perror("setsid");
-#endif /* TIOCNOTTY */
-#endif /* SYSV */
- } /* End of child process code */
-
-#ifdef HAVE_ROUTING_SOCKETS
- init_routesock();
-#endif /* HAVE_ROUTING_SOCKETS */
-
- fp = fopen(pidfilename, "w");
- if (fp != NULL) {
- fprintf(fp, "%d\n", (int)getpid());
- (void) fclose(fp);
- }
-
- /*
- * Main receive loop.
- */
- dummy = 0;
- dummysigalrm = SIGALRM;
- difftime.tv_usec = 0;
- gettimeofday(&curtime, NULL);
- lasttime = curtime;
- for(;;) {
- bcopy((char *)&readers, (char *)&rfds, sizeof(rfds));
- secs = timer_nextTimer();
- if (secs == -1)
- timeout = NULL;
- else {
- timeout = &tv;
- timeout->tv_sec = secs;
- timeout->tv_usec = 0;
- }
-
- if (sighandled) {
- if (sighandled & GOT_SIGINT) {
- sighandled &= ~GOT_SIGINT;
- break;
- }
- if (sighandled & GOT_SIGHUP) {
- sighandled &= ~GOT_SIGHUP;
- restart(SIGHUP);
- }
- if (sighandled & GOT_SIGUSR1) {
- sighandled &= ~GOT_SIGUSR1;
- fdump(SIGUSR1);
- }
- if (sighandled & GOT_SIGUSR2) {
- sighandled &= ~GOT_SIGUSR2;
- cdump(SIGUSR2);
- }
- if (sighandled & GOT_SIGALRM) {
- sighandled &= ~GOT_SIGALRM;
- timer(&dummysigalrm);
- }
- }
- if ((n = select(nfds, &rfds, NULL, NULL, timeout)) < 0) {
- if (errno != EINTR) /* SIGALRM is expected */
- log(LOG_WARNING, errno, "select failed");
- continue;
- }
-
- /*
- * Handle timeout queue.
- *
- * If select + packet processing took more than 1 second,
- * or if there is a timeout pending, age the timeout queue.
- *
- * If not, collect usec in difftime to make sure that the
- * time doesn't drift too badly.
- *
- * If the timeout handlers took more than 1 second,
- * age the timeout queue again. XXX This introduces the
- * potential for infinite loops!
- */
- do {
- /*
- * If the select timed out, then there's no other
- * activity to account for and we don't need to
- * call gettimeofday.
- */
- if (n == 0) {
- curtime.tv_sec = lasttime.tv_sec + secs;
- curtime.tv_usec = lasttime.tv_usec;
- n = -1; /* don't do this next time through the loop */
- } else
- gettimeofday(&curtime, NULL);
- difftime.tv_sec = curtime.tv_sec - lasttime.tv_sec;
- difftime.tv_usec += curtime.tv_usec - lasttime.tv_usec;
-#ifdef TIMERDEBUG
- IF_DEBUG(DEBUG_TIMEOUT)
- log(LOG_DEBUG, 0, "TIMEOUT: secs %d, diff secs %d, diff usecs %d", secs, difftime.tv_sec, difftime.tv_usec );
-#endif
- while (difftime.tv_usec >= 1000000) {
- difftime.tv_sec++;
- difftime.tv_usec -= 1000000;
- }
- if (difftime.tv_usec < 0) {
- difftime.tv_sec--;
- difftime.tv_usec += 1000000;
- }
- lasttime = curtime;
- if (secs == 0 || difftime.tv_sec > 0) {
-#ifdef TIMERDEBUG
- IF_DEBUG(DEBUG_TIMEOUT)
- log(LOG_DEBUG, 0, "\taging callouts: secs %d, diff secs %d, diff usecs %d", secs, difftime.tv_sec, difftime.tv_usec );
-#endif
- age_callout_queue(difftime.tv_sec);
- }
- secs = -1;
- } while (difftime.tv_sec > 0);
-
- /* Handle sockets */
- if (n > 0) {
- /* TODO: shall check first mld6_socket for better performance? */
- for (i = 0; i < nhandlers; i++) {
- if (FD_ISSET(ihandlers[i].fd, &rfds)) {
- (*ihandlers[i].func)(ihandlers[i].fd, &rfds);
- }
- }
- }
-
- } /* Main loop */
-
- log(LOG_NOTICE, 0, "%s exiting", versionstring);
- cleanup();
- exit(0);
-}
-
-/*
- * The 'virtual_time' variable is initialized to a value that will cause the
- * first invocation of timer() to send a probe or route report to all vifs
- * and send group membership queries to all subnets for which this router is
- * querier. This first invocation occurs approximately TIMER_INTERVAL seconds
- * after the router starts up. Note that probes for neighbors and queries
- * for group memberships are also sent at start-up time, as part of initial-
- * ization. This repetition after a short interval is desirable for quickly
- * building up topology and membership information in the presence of possible
- * packet loss.
- *
- * 'virtual_time' advances at a rate that is only a crude approximation of
- * real time, because it does not take into account any time spent processing,
- * and because the timer intervals are sometimes shrunk by a random amount to
- * avoid unwanted synchronization with other routers.
- */
-
-u_long virtual_time = 0;
-
-/*
- * Timer routine. Performs all perodic functions:
- * aging interfaces, quering neighbors and members, etc... The granularity
- * is equal to TIMER_INTERVAL.
- */
-static void
-timer(i)
- void *i;
-{
- age_vifs(); /* Timeout neighbors and groups */
- age_routes(); /* Timeout routing entries */
-
- virtual_time += TIMER_INTERVAL;
- timer_setTimer(TIMER_INTERVAL, timer, NULL);
-}
-
-/*
- * Performs all necessary functions to quit gracefully
- */
-/* TODO: implement all necessary stuff */
-static void
-cleanup()
-{
-
-#ifdef RSRR
- rsrr_clean();
-#endif /* RSRR */
-
- k_stop_pim(mld6_socket);
-
- /* TODO: XXX (not in the spec)
- */
-}
-
-
-/*
- * Signal handler. Take note of the fact that the signal arrived
- * so that the main loop can take care of it.
- */
-static void
-handler(sig)
- int sig;
-{
- switch (sig) {
- case SIGALRM:
- sighandled |= GOT_SIGALRM;
- case SIGINT:
- case SIGTERM:
- sighandled |= GOT_SIGINT;
- break;
-
- case SIGHUP:
- sighandled |= GOT_SIGHUP;
- break;
-
- case SIGUSR1:
- sighandled |= GOT_SIGUSR1;
- break;
-
- case SIGUSR2:
- sighandled |= GOT_SIGUSR2;
- break;
- }
-}
-
-
-/* TODO: not verified */
-/* PIMDM TODO */
-/*
- * Restart the daemon
- */
-static void
-restart(i)
- int i;
-{
-#ifdef SNMP
- int s;
-#endif /* SNMP */
-
- log(LOG_NOTICE, 0, "%s restart", versionstring);
-
- /*
- * reset all the entries
- */
- /*
- * TODO: delete?
- * free_all_routes();
- */
- free_all_callouts();
- stop_all_vifs();
- nhandlers=0;
- k_stop_pim(mld6_socket);
- close(mld6_socket);
- close(pim6_socket);
- close(udp_socket);
-
- /*
- * start processing again
- */
- init_mld6();
- init_pim6();
-#ifdef HAVE_ROUTING_SOCKETS
- init_routesock();
-#endif /* HAVE_ROUTING_SOCKETS */
- init_pim6_mrt();
-#ifdef SNMP
- if ( s = snmp_init())
- exit(s);
-#endif /* SNMP */
- init_vifs();
-
-#ifdef RSRR
- rsrr_init();
-#endif /* RSRR */
-
- /* schedule timer interrupts */
- timer_setTimer(TIMER_INTERVAL, timer, NULL);
-}
-
-
-static void
-resetlogging(arg)
- void *arg;
-{
- int nxttime = 60;
- void *narg = NULL;
-
- if (arg == NULL && log_nmsgs > LOG_MAX_MSGS) {
- nxttime = LOG_SHUT_UP;
- narg = (void *)&log_nmsgs; /* just need some valid void * */
- syslog(LOG_WARNING, "logging too fast, shutting up for %d minutes",
- LOG_SHUT_UP / 60);
- } else {
- log_nmsgs = 0;
- }
-
- timer_setTimer(nxttime, resetlogging, narg);
-}
diff --git a/usr.sbin/pim6dd/mld6.c b/usr.sbin/pim6dd/mld6.c
deleted file mode 100644
index 1b0fe8e..0000000
--- a/usr.sbin/pim6dd/mld6.c
+++ /dev/null
@@ -1,548 +0,0 @@
-/*
- * Copyright (C) 1998 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*
- * Copyright (c) 1998 by the University of Southern California.
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation in source and binary forms for lawful
- * purposes and without fee is hereby granted, provided
- * that the above copyright notice appear in all copies and that both
- * the copyright notice and this permission notice appear in supporting
- * documentation, and that any documentation, advertising materials,
- * and other materials related to such distribution and use acknowledge
- * that the software was developed by the University of Southern
- * California and/or Information Sciences Institute.
- * The name of the University of Southern California may not
- * be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THE UNIVERSITY OF SOUTHERN CALIFORNIA DOES NOT MAKE ANY REPRESENTATIONS
- * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. THIS SOFTWARE IS
- * PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
- * NON-INFRINGEMENT.
- *
- * IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT,
- * TORT, OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH,
- * THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Other copyrights might apply to parts of this software and are so
- * noted when applicable.
- */
-/*
- * Questions concerning this software should be directed to
- * Pavlin Ivanov Radoslavov (pavlin@catarina.usc.edu)
- *
- * $Id: mld6.c,v 1.14 2000/10/05 22:20:38 itojun Exp $
- */
-/*
- * Part of this program has been derived from mrouted.
- * The mrouted program is covered by the license in the accompanying file
- * named "LICENSE.mrouted".
- *
- * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
- * Leland Stanford Junior University.
- *
- * $FreeBSD$
- */
-
-#include "defs.h"
-#include <sys/uio.h>
-
-/*
- * Exported variables.
- */
-
-char *mld6_recv_buf; /* input packet buffer */
-char *mld6_send_buf; /* output packet buffer */
-int mld6_socket; /* socket for all network I/O */
-struct sockaddr_in6 allrouters_group = {sizeof(struct sockaddr_in6), AF_INET6};
-struct sockaddr_in6 allnodes_group = {sizeof(struct sockaddr_in6), AF_INET6};
-
-/* Extenals */
-
-extern struct in6_addr in6addr_linklocal_allnodes;
-
-/* local variables. */
-static struct sockaddr_in6 dst = {sizeof(dst), AF_INET6};
-static struct msghdr sndmh,
- rcvmh;
-static struct iovec sndiov[2];
-static struct iovec rcviov[2];
-static struct sockaddr_in6 from;
-static u_char *rcvcmsgbuf = NULL;
-static int rcvcmsglen;
-
-#ifndef USE_RFC2292BIS
-u_int8_t raopt[IP6OPT_RTALERT_LEN];
-#endif
-static char *sndcmsgbuf;
-static int ctlbuflen = 0;
-static u_short rtalert_code;
-
-/* local functions */
-
-static void mld6_read __P((int i, fd_set * fds));
-static void accept_mld6 __P((int len));
-static void make_mld6_msg __P((int, int, struct sockaddr_in6 *,
- struct sockaddr_in6 *, struct in6_addr *, int, int, int, int));
-
-#ifndef IP6OPT_ROUTER_ALERT /* XXX to be compatible older systems */
-#define IP6OPT_ROUTER_ALERT IP6OPT_RTALERT
-#endif
-
-/*
- * Open and initialize the MLD socket.
- */
-void
-init_mld6()
-{
- struct icmp6_filter filt;
- int on;
-
- rtalert_code = htons(IP6OPT_RTALERT_MLD);
- if (!mld6_recv_buf && (mld6_recv_buf = malloc(RECV_BUF_SIZE)) == NULL)
- log(LOG_ERR, 0, "malloc failed");
- if (!mld6_send_buf && (mld6_send_buf = malloc(RECV_BUF_SIZE)) == NULL)
- log(LOG_ERR, 0, "malloc failed");
-
- rcvcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) +
- CMSG_SPACE(sizeof(int));
- if (rcvcmsgbuf == NULL && (rcvcmsgbuf = malloc(rcvcmsglen)) == NULL)
- log(LOG_ERR, 0,"malloc failed");
-
- IF_DEBUG(DEBUG_KERN)
- log(LOG_DEBUG,0,"%d octets allocated for the emit/recept buffer mld6",RECV_BUF_SIZE);
-
- if ((mld6_socket = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0)
- log(LOG_ERR, errno, "MLD6 socket");
-
- k_set_rcvbuf(mld6_socket, SO_RECV_BUF_SIZE_MAX,
- SO_RECV_BUF_SIZE_MIN); /* lots of input buffering */
- k_set_hlim(mld6_socket, MINHLIM); /* restrict multicasts to one hop */
- k_set_loop(mld6_socket, FALSE); /* disable multicast loopback */
-
- /* address initialization */
- allnodes_group.sin6_addr = in6addr_linklocal_allnodes;
- if (inet_pton(AF_INET6, "ff02::2",
- (void *) &allrouters_group.sin6_addr) != 1)
- log(LOG_ERR, 0, "inet_pton failed for ff02::2");
-
- /* filter all non-MLD ICMP messages */
- ICMP6_FILTER_SETBLOCKALL(&filt);
- ICMP6_FILTER_SETPASS(ICMP6_MEMBERSHIP_QUERY, &filt);
- ICMP6_FILTER_SETPASS(ICMP6_MEMBERSHIP_REPORT, &filt);
- ICMP6_FILTER_SETPASS(ICMP6_MEMBERSHIP_REDUCTION, &filt);
- ICMP6_FILTER_SETPASS(MLD6_MTRACE_RESP, &filt);
- ICMP6_FILTER_SETPASS(MLD6_MTRACE, &filt);
- if (setsockopt(mld6_socket, IPPROTO_ICMPV6, ICMP6_FILTER, &filt,
- sizeof(filt)) < 0)
- log(LOG_ERR, errno, "setsockopt(ICMP6_FILTER)");
-
- /* specify to tell receiving interface */
- on = 1;
-#ifdef IPV6_RECVPKTINFO
- if (setsockopt(mld6_socket, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on,
- sizeof(on)) < 0)
- log(LOG_ERR, errno, "setsockopt(IPV6_RECVPKTINFO)");
-#else /* old adv. API */
- if (setsockopt(mld6_socket, IPPROTO_IPV6, IPV6_PKTINFO, &on,
- sizeof(on)) < 0)
- log(LOG_ERR, errno, "setsockopt(IPV6_PKTINFO)");
-#endif
- on = 1;
- /* specify to tell value of hoplimit field of received IP6 hdr */
-#ifdef IPV6_RECVHOPLIMIT
- if (setsockopt(mld6_socket, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on,
- sizeof(on)) < 0)
- log(LOG_ERR, errno, "setsockopt(IPV6_RECVHOPLIMIT)");
-#else /* old adv. API */
- if (setsockopt(mld6_socket, IPPROTO_IPV6, IPV6_HOPLIMIT, &on,
- sizeof(on)) < 0)
- log(LOG_ERR, errno, "setsockopt(IPV6_HOPLIMIT)");
-#endif
- /* initialize msghdr for receiving packets */
- rcviov[0].iov_base = (caddr_t) mld6_recv_buf;
- rcviov[0].iov_len = RECV_BUF_SIZE;
- rcvmh.msg_name = (caddr_t) & from;
- rcvmh.msg_namelen = sizeof(from);
- rcvmh.msg_iov = rcviov;
- rcvmh.msg_iovlen = 1;
- rcvmh.msg_control = (caddr_t) rcvcmsgbuf;
- rcvmh.msg_controllen = rcvcmsglen;
-
- /* initialize msghdr for sending packets */
- sndiov[0].iov_base = (caddr_t)mld6_send_buf;
- sndmh.msg_namelen = sizeof(struct sockaddr_in6);
- sndmh.msg_iov = sndiov;
- sndmh.msg_iovlen = 1;
- /* specifiy to insert router alert option in a hop-by-hop opt hdr. */
-#ifndef USE_RFC2292BIS
- raopt[0] = IP6OPT_ROUTER_ALERT;
- raopt[1] = IP6OPT_RTALERT_LEN - 2;
- memcpy(&raopt[2], (caddr_t) & rtalert_code, sizeof(u_short));
-#endif
-
- /* register MLD message handler */
- if (register_input_handler(mld6_socket, mld6_read) < 0)
- log(LOG_ERR, 0,
- "Couldn't register mld6_read as an input handler");
-}
-
-/* Read an MLD message */
-static void
-mld6_read(i, rfd)
- int i;
- fd_set *rfd;
-{
- register int mld6_recvlen;
-
- mld6_recvlen = recvmsg(mld6_socket, &rcvmh, 0);
-
- if (mld6_recvlen < 0)
- {
- if (errno != EINTR)
- log(LOG_ERR, errno, "MLD6 recvmsg");
- return;
- }
-
- /* TODO: make it as a thread in the future releases */
- accept_mld6(mld6_recvlen);
-}
-
-/*
- * Process a newly received MLD6 packet that is sitting in the input packet
- * buffer.
- */
-static void
-accept_mld6(recvlen)
-int recvlen;
-{
- struct in6_addr *group, *dst = NULL;
- struct mld6_hdr *mldh;
- struct cmsghdr *cm;
- struct in6_pktinfo *pi = NULL;
- int *hlimp = NULL;
- int ifindex = 0;
- struct sockaddr_in6 *src = (struct sockaddr_in6 *) rcvmh.msg_name;
-
- if (recvlen < sizeof(struct mld6_hdr))
- {
- log(LOG_WARNING, 0,
- "received packet too short (%u bytes) for MLD header",
- recvlen);
- return;
- }
- mldh = (struct mld6_hdr *) rcvmh.msg_iov[0].iov_base;
-
- /*
- * Packets sent up from kernel to daemon have ICMPv6 type = 0.
- * Note that we set filters on the mld6_socket, so we should never
- * see a "normal" ICMPv6 packet with type 0 of ICMPv6 type.
- */
- if (mldh->mld6_type == 0) {
- /* XXX: msg_controllen must be reset in this case. */
- rcvmh.msg_controllen = rcvcmsglen;
-
- process_kernel_call();
- return;
- }
-
- group = &mldh->mld6_addr;
-
- /* extract optional information via Advanced API */
- for (cm = (struct cmsghdr *) CMSG_FIRSTHDR(&rcvmh);
- cm;
- cm = (struct cmsghdr *) CMSG_NXTHDR(&rcvmh, cm))
- {
- if (cm->cmsg_level == IPPROTO_IPV6 &&
- cm->cmsg_type == IPV6_PKTINFO &&
- cm->cmsg_len == CMSG_LEN(sizeof(struct in6_pktinfo)))
- {
- pi = (struct in6_pktinfo *) (CMSG_DATA(cm));
- ifindex = pi->ipi6_ifindex;
- dst = &pi->ipi6_addr;
- }
- if (cm->cmsg_level == IPPROTO_IPV6 &&
- cm->cmsg_type == IPV6_HOPLIMIT &&
- cm->cmsg_len == CMSG_LEN(sizeof(int)))
- hlimp = (int *) CMSG_DATA(cm);
- }
- if (hlimp == NULL)
- {
- log(LOG_WARNING, 0,
- "failed to get receiving hop limit");
- return;
- }
-
- /* TODO: too noisy. Remove it? */
-//#define NOSUCHDEF
-#ifdef NOSUCHDEF
- IF_DEBUG(DEBUG_PKT | debug_kind(IPPROTO_ICMPV6, mldh->mld6_type,
- mldh->mld6_code))
- log(LOG_DEBUG, 0, "RECV %s from %s to %s",
- packet_kind(IPPROTO_ICMPV6,
- mldh->mld6_type, mldh->mld6_code),
- inet6_fmt(&src->sin6_addr), inet6_fmt(dst));
-#endif /* NOSUCHDEF */
-
- /* for an mtrace message, we don't need strict checks */
- if (mldh->mld6_type == MLD6_MTRACE) {
- accept_mtrace(src, dst, group, ifindex, (char *)(mldh + 1),
- mldh->mld6_code, recvlen - sizeof(struct mld6_hdr));
- return;
- }
-
- /* hop limit check */
- if (*hlimp != 1)
- {
- log(LOG_WARNING, 0,
- "received an MLD6 message with illegal hop limit(%d) from %s",
- *hlimp, inet6_fmt(&src->sin6_addr));
- /* but accept the packet */
- }
- if (ifindex == 0)
- {
- log(LOG_WARNING, 0, "failed to get receiving interface");
- return;
- }
-
- /* scope check */
- if (IN6_IS_ADDR_MC_NODELOCAL(&mldh->mld6_addr))
- {
- log(LOG_INFO, 0,
- "RECV %s with an invalid scope: %s from %s",
- packet_kind(IPPROTO_ICMPV6, mldh->mld6_type,
- mldh->mld6_code),
- inet6_fmt(&mldh->mld6_addr),
- inet6_fmt(&src->sin6_addr));
- return; /* discard */
- }
-
- /* source address check */
- if (!IN6_IS_ADDR_LINKLOCAL(&src->sin6_addr))
- {
- log(LOG_INFO, 0,
- "RECV %s from a non link local address: %s",
- packet_kind(IPPROTO_ICMPV6, mldh->mld6_type,
- mldh->mld6_code),
- inet6_fmt(&src->sin6_addr));
- return;
- }
-
- switch (mldh->mld6_type)
- {
- case MLD6_LISTENER_QUERY:
- accept_listener_query(src, dst, group,
- ntohs(mldh->mld6_maxdelay));
- return;
-
- case MLD6_LISTENER_REPORT:
- accept_listener_report(src, dst, group);
- return;
-
- case MLD6_LISTENER_DONE:
- accept_listener_done(src, dst, group);
- return;
-
- default:
- /* This must be impossible since we set a type filter */
- log(LOG_INFO, 0,
- "ignoring unknown ICMPV6 message type %x from %s to %s",
- mldh->mld6_type, inet6_fmt(&src->sin6_addr),
- inet6_fmt(dst));
- return;
- }
-}
-
-static void
-make_mld6_msg(type, code, src, dst, group, ifindex, delay, datalen, alert)
- int type, code, ifindex, delay, datalen, alert;
- struct sockaddr_in6 *src, *dst;
- struct in6_addr *group;
-{
- static struct sockaddr_in6 dst_sa = {sizeof(dst_sa), AF_INET6};
- struct mld6_hdr *mhp = (struct mld6_hdr *)mld6_send_buf;
- int ctllen, hbhlen = 0;
-
- switch(type) {
- case MLD6_MTRACE:
- case MLD6_MTRACE_RESP:
- sndmh.msg_name = (caddr_t)dst;
- break;
- default:
- if (IN6_IS_ADDR_UNSPECIFIED(group))
- dst_sa.sin6_addr = allnodes_group.sin6_addr;
- else
- dst_sa.sin6_addr = *group;
- sndmh.msg_name = (caddr_t)&dst_sa;
- datalen = sizeof(struct mld6_hdr);
- break;
- }
-
- bzero(mhp, sizeof(*mhp));
- mhp->mld6_type = type;
- mhp->mld6_code = code;
- mhp->mld6_maxdelay = htons(delay);
- mhp->mld6_addr = *group;
-
- sndiov[0].iov_len = datalen;
-
- /* estimate total ancillary data length */
- ctllen = 0;
- if (ifindex != -1 || src)
- ctllen += CMSG_SPACE(sizeof(struct in6_pktinfo));
- if (alert) {
-#ifdef USE_RFC2292BIS
- if ((hbhlen = inet6_opt_init(NULL, 0)) == -1)
- log(LOG_ERR, 0, "inet6_opt_init(0) failed");
- if ((hbhlen = inet6_opt_append(NULL, 0, hbhlen, IP6OPT_ROUTER_ALERT, 2,
- 2, NULL)) == -1)
- log(LOG_ERR, 0, "inet6_opt_append(0) failed");
- if ((hbhlen = inet6_opt_finish(NULL, 0, hbhlen)) == -1)
- log(LOG_ERR, 0, "inet6_opt_finish(0) failed");
- ctllen += CMSG_SPACE(hbhlen);
-#else /* old advanced API */
- hbhlen = inet6_option_space(sizeof(raopt));
- ctllen += hbhlen;
-#endif
-
- }
- /* extend ancillary data space (if necessary) */
- if (ctlbuflen < ctllen) {
- if (sndcmsgbuf)
- free(sndcmsgbuf);
- if ((sndcmsgbuf = malloc(ctllen)) == NULL)
- log(LOG_ERR, 0, "make_mld6_msg: malloc failed"); /* assert */
- ctlbuflen = ctllen;
- }
- /* store ancillary data */
- if ((sndmh.msg_controllen = ctllen) > 0) {
- struct cmsghdr *cmsgp;
-
- sndmh.msg_control = sndcmsgbuf;
- cmsgp = CMSG_FIRSTHDR(&sndmh);
-
- if (ifindex != -1 || src) {
- struct in6_pktinfo *pktinfo;
-
- cmsgp->cmsg_len = CMSG_SPACE(sizeof(struct in6_pktinfo));
- cmsgp->cmsg_level = IPPROTO_IPV6;
- cmsgp->cmsg_type = IPV6_PKTINFO;
- pktinfo = (struct in6_pktinfo *)CMSG_DATA(cmsgp);
- memset((caddr_t)pktinfo, 0, sizeof(*pktinfo));
- if (ifindex != -1)
- pktinfo->ipi6_ifindex = ifindex;
- if (src)
- pktinfo->ipi6_addr = src->sin6_addr;
- cmsgp = CMSG_NXTHDR(&sndmh, cmsgp);
- }
- if (alert) {
-#ifdef USE_RFC2292BIS
- int currentlen;
- void *hbhbuf, *optp = NULL;
-
- cmsgp->cmsg_len = CMSG_SPACE(hbhlen);
- cmsgp->cmsg_level = IPPROTO_IPV6;
- cmsgp->cmsg_type = IPV6_HOPOPTS;
- hbhbuf = CMSG_DATA(cmsgp);
-
- if ((currentlen = inet6_opt_init(hbhbuf, hbhlen)) == -1)
- log(LOG_ERR, 0, "inet6_opt_init(len = %d) failed",
- hbhlen);
- if ((currentlen = inet6_opt_append(hbhbuf, hbhlen,
- currentlen,
- IP6OPT_ROUTER_ALERT, 2,
- 2, &optp)) == -1)
- log(LOG_ERR, 0,
- "inet6_opt_append(len = %d) failed",
- currentlen, hbhlen);
- (void)inet6_opt_set_val(optp, 0, &rtalert_code,
- sizeof(rtalert_code));
- if (inet6_opt_finish(hbhbuf, hbhlen, currentlen) == -1)
- log(LOG_ERR, 0, "inet6_opt_finish(buf) failed");
-#else /* old advanced API */
- if (inet6_option_init((void *)cmsgp, &cmsgp, IPV6_HOPOPTS))
- log(LOG_ERR, 0, /* assert */
- "make_mld6_msg: inet6_option_init failed");
- if (inet6_option_append(cmsgp, raopt, 4, 0))
- log(LOG_ERR, 0, /* assert */
- "make_mld6_msg: inet6_option_append failed");
-#endif
- cmsgp = CMSG_NXTHDR(&sndmh, cmsgp);
- }
- }
- else
- sndmh.msg_control = NULL; /* clear for safety */
-}
-
-void
-send_mld6(type, code, src, dst, group, index, delay, datalen, alert)
- int type;
- int code; /* for trace packets only */
- struct sockaddr_in6 *src;
- struct sockaddr_in6 *dst; /* may be NULL */
- struct in6_addr *group;
- int index, delay, alert;
- int datalen; /* for trace packets only */
-{
- int setloop = 0;
- struct sockaddr_in6 *dstp;
-
- make_mld6_msg(type, code, src, dst, group, index, delay, datalen, alert);
- dstp = (struct sockaddr_in6 *)sndmh.msg_name;
- if (IN6_ARE_ADDR_EQUAL(&dstp->sin6_addr, &allnodes_group.sin6_addr)) {
- setloop = 1;
- k_set_loop(mld6_socket, TRUE);
- }
- if (sendmsg(mld6_socket, &sndmh, 0) < 0) {
- if (errno == ENETDOWN)
- check_vif_state();
- else
- log(log_level(IPPROTO_ICMPV6, type, 0), errno,
- "sendmsg to %s with src %s on %s",
- inet6_fmt(&dstp->sin6_addr),
- src ? inet6_fmt(&src->sin6_addr) : "(unspec)",
- ifindex2str(index));
-
- if (setloop)
- k_set_loop(mld6_socket, FALSE);
- return;
- }
-
- IF_DEBUG(DEBUG_PKT|debug_kind(IPPROTO_IGMP, type, 0))
- log(LOG_DEBUG, 0, "SENT %s from %-15s to %s",
- packet_kind(IPPROTO_ICMPV6, type, 0),
- src ? inet6_fmt(&src->sin6_addr) : "unspec",
- inet6_fmt(&dstp->sin6_addr));
-}
diff --git a/usr.sbin/pim6dd/mld6.h b/usr.sbin/pim6dd/mld6.h
deleted file mode 100644
index 310ebcf..0000000
--- a/usr.sbin/pim6dd/mld6.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 1998 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-/*
- * Constans for Multicast Listener Discovery protocol for IPv6.
- */
-#define MLD6_ROBUSTNESS_VARIABLE 2
-#define MLD6_QUERY_INTERVAL 125 /* in seconds */
-#define MLD6_QUERY_RESPONSE_INTERVAL 10000 /* in milliseconds */
-#ifndef MLD6_TIMER_SCALE
-#define MLD6_TIMER_SCALE 1000
-#endif
-#define MLD6_LISTENER_INTERVAL (MLD6_ROBUSTNESS_VARIABLE * \
- MLD6_QUERY_INTERVAL + \
- MLD6_QUERY_RESPONSE_INTERVAL / MLD6_TIMER_SCALE)
-#define MLD6_LAST_LISTENER_QUERY_INTERVAL 1000 /* in milliseconds */
-#define MLD6_LAST_LISTENER_QUERY_COUNT MLD6_ROBUSTNESS_VARIABLE
-#define MLD6_OTHER_QUERIER_PRESENT_INTERVAL (MLD6_ROBUSTNESS_VARIABLE * \
- MLD6_QUERY_INTERVAL + \
- MLD6_QUERY_RESPONSE_INTERVAL / (2 * MLD6_TIMER_SCALE))
diff --git a/usr.sbin/pim6dd/mld6_proto.c b/usr.sbin/pim6dd/mld6_proto.c
deleted file mode 100644
index a87973d..0000000
--- a/usr.sbin/pim6dd/mld6_proto.c
+++ /dev/null
@@ -1,523 +0,0 @@
-/*
- * Copyright (C) 1998 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*
- * Copyright (c) 1998 by the University of Oregon.
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation in source and binary forms for lawful
- * purposes and without fee is hereby granted, provided
- * that the above copyright notice appear in all copies and that both
- * the copyright notice and this permission notice appear in supporting
- * documentation, and that any documentation, advertising materials,
- * and other materials related to such distribution and use acknowledge
- * that the software was developed by the University of Oregon.
- * The name of the University of Oregon may not be used to endorse or
- * promote products derived from this software without specific prior
- * written permission.
- *
- * THE UNIVERSITY OF OREGON DOES NOT MAKE ANY REPRESENTATIONS
- * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. THIS SOFTWARE IS
- * PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
- * NON-INFRINGEMENT.
- *
- * IN NO EVENT SHALL UO, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT,
- * TORT, OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH,
- * THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Other copyrights might apply to parts of this software and are so
- * noted when applicable.
- */
-/*
- * Questions concerning this software should be directed to
- * Kurt Windisch (kurtw@antc.uoregon.edu)
- *
- * $Id: mld6_proto.c,v 1.5 2000/10/05 22:20:38 itojun Exp $
- */
-/*
- * Part of this program has been derived from PIM sparse-mode pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- * The pimd program is COPYRIGHT 1998 by University of Southern California.
- *
- * Part of this program has been derived from mrouted.
- * The mrouted program is covered by the license in the accompanying file
- * named "LICENSE.mrouted".
- *
- * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
- * Leland Stanford Junior University.
- *
- * $FreeBSD$
- */
-
-#include "defs.h"
-
-extern struct in6_addr in6addr_any;
-
-typedef struct {
- mifi_t mifi;
- struct listaddr *g;
- int q_time;
-} cbk_t;
-
-
-/*
- * Forward declarations.
- */
-static void DelVif __P((void *arg));
-static int SetTimer __P((int mifi, struct listaddr *g));
-static int DeleteTimer __P((int id));
-static void SendQuery __P((void *arg));
-static int SetQueryTimer __P((struct listaddr *g, int mifi, int to_expire,
- int q_time));
-
-/*
- * Send group membership queries on that interface if I am querier.
- */
-void
-query_groups(v)
- register struct uvif *v;
-{
- register struct listaddr *g;
-
- v->uv_gq_timer = MLD6_QUERY_INTERVAL;
- if (v->uv_flags & VIFF_QUERIER && (v->uv_flags & VIFF_NOLISTENER) == 0)
- send_mld6(MLD6_LISTENER_QUERY, 0, &v->uv_linklocal->pa_addr,
- NULL, (struct in6_addr *)&in6addr_any,
- v->uv_ifindex, MLD6_QUERY_RESPONSE_INTERVAL, 0, 1);
-
- /*
- * Decrement the old-hosts-present timer for each
- * active group on that vif.
- */
- for (g = v->uv_groups; g != NULL; g = g->al_next)
- if (g->al_old > TIMER_INTERVAL)
- g->al_old -= TIMER_INTERVAL;
- else
- g->al_old = 0;
-}
-
-
-/*
- * Process an incoming host membership query
- */
-void
-accept_listener_query(src, dst, group, tmo)
- struct sockaddr_in6 *src;
- struct in6_addr *dst, *group;
- int tmo;
-{
- register int mifi;
- register struct uvif *v;
- struct sockaddr_in6 group_sa = {sizeof(group_sa), AF_INET6};
-
- /* Ignore my own membership query */
- if (local_address(src) != NO_VIF)
- return;
-
- if ((mifi = find_vif_direct(src)) == NO_VIF) {
- IF_DEBUG(DEBUG_MLD)
- log(LOG_INFO, 0,
- "accept_listener_query: can't find a mif");
- return;
- }
-
- v = &uvifs[mifi];
-
- if (v->uv_querier == NULL || !inet6_equal(&v->uv_querier->al_addr, src))
- {
- /*
- * This might be:
- * - A query from a new querier, with a lower source address
- * than the current querier (who might be me)
- * - A query from a new router that just started up and doesn't
- * know who the querier is.
- * - A query from the current querier
- */
- if (inet6_lessthan(src, (v->uv_querier ? &v->uv_querier->al_addr
- : &v->uv_linklocal->pa_addr))) {
- IF_DEBUG(DEBUG_MLD)
- log(LOG_DEBUG, 0, "new querier %s (was %s) "
- "on mif %d",
- inet6_fmt(&src->sin6_addr),
- v->uv_querier ?
- inet6_fmt(&v->uv_querier->al_addr.sin6_addr) :
- "me", mifi);
- if (!v->uv_querier) {
- v->uv_querier = (struct listaddr *)
- malloc(sizeof(struct listaddr));
- memset(v->uv_querier, 0,
- sizeof(struct listaddr));
- }
- v->uv_flags &= ~VIFF_QUERIER;
- v->uv_querier->al_addr = *src;
- time(&v->uv_querier->al_ctime);
- }
- }
-
- /*
- * Reset the timer since we've received a query.
- */
- if (v->uv_querier && inet6_equal(src, &v->uv_querier->al_addr))
- v->uv_querier->al_timer = MLD6_OTHER_QUERIER_PRESENT_INTERVAL;
-
- /*
- * If this is a Group-Specific query which we did not source,
- * we must set our membership timer to [Last Member Query Count] *
- * the [Max Response Time] in the packet.
- */
- if (!IN6_IS_ADDR_UNSPECIFIED(group) &&
- inet6_equal(src, &v->uv_linklocal->pa_addr)) {
- register struct listaddr *g;
-
- IF_DEBUG(DEBUG_MLD)
- log(LOG_DEBUG, 0,
- "%s for %s from %s on mif %d, timer %d",
- "Group-specific membership query",
- inet6_fmt(group),
- inet6_fmt(&src->sin6_addr), mifi, tmo);
-
- group_sa.sin6_addr = *group;
- group_sa.sin6_scope_id = inet6_uvif2scopeid(&group_sa, v);
- for (g = v->uv_groups; g != NULL; g = g->al_next) {
- if (inet6_equal(&group_sa, &g->al_addr)
- && g->al_query == 0) {
- /* setup a timeout to remove the group membership */
- if (g->al_timerid)
- g->al_timerid = DeleteTimer(g->al_timerid);
- g->al_timer = MLD6_LAST_LISTENER_QUERY_COUNT *
- tmo / MLD6_TIMER_SCALE;
- /*
- * use al_query to record our presence
- * in last-member state
- */
- g->al_query = -1;
- g->al_timerid = SetTimer(mifi, g);
- IF_DEBUG(DEBUG_MLD)
- log(LOG_DEBUG, 0,
- "timer for grp %s on mif %d "
- "set to %ld",
- inet6_fmt(group),
- mifi, g->al_timer);
- break;
- }
- }
- }
-}
-
-
-/*
- * Process an incoming group membership report.
- */
-void
-accept_listener_report(src, dst, group)
- struct sockaddr_in6 *src;
- struct in6_addr *dst, *group;
-{
- register mifi_t mifi;
- register struct uvif *v;
- register struct listaddr *g;
- struct sockaddr_in6 group_sa = {sizeof(group_sa), AF_INET6};
-
- if (IN6_IS_ADDR_MC_LINKLOCAL(group)) {
- IF_DEBUG(DEBUG_MLD)
- log(LOG_DEBUG, 0,
- "accept_listener_report: group(%s) has the "
- "link-local scope. discard", inet6_fmt(group));
- return;
- }
-
- if ((mifi = find_vif_direct_local(src)) == NO_VIF) {
- IF_DEBUG(DEBUG_MLD)
- log(LOG_INFO, 0,
- "accept_listener_report: can't find a mif");
- return;
- }
-
- IF_DEBUG(DEBUG_MLD)
- log(LOG_INFO, 0,
- "accepting multicast listener report: "
- "src %s, dst %s, grp %s",
- inet6_fmt(&src->sin6_addr), inet6_fmt(dst),
- inet6_fmt(group));
-
- v = &uvifs[mifi];
-
- /*
- * Look for the group in our group list; if found, reset its timer.
- */
- group_sa.sin6_addr = *group;
- group_sa.sin6_scope_id = inet6_uvif2scopeid(&group_sa, v);
- for (g = v->uv_groups; g != NULL; g = g->al_next) {
- if (inet6_equal(&group_sa, &g->al_addr)) {
- g->al_reporter = *src;
-
- /* delete old timers, set a timer for expiration */
- g->al_timer = MLD6_LISTENER_INTERVAL;
- if (g->al_query)
- g->al_query = DeleteTimer(g->al_query);
- if (g->al_timerid)
- g->al_timerid = DeleteTimer(g->al_timerid);
- g->al_timerid = SetTimer(mifi, g);
- add_leaf(mifi, NULL, &group_sa);
- break;
- }
- }
-
- /*
- * If not found, add it to the list and update kernel cache.
- */
- if (g == NULL) {
- g = (struct listaddr *)malloc(sizeof(struct listaddr));
- if (g == NULL)
- log(LOG_ERR, 0, "ran out of memory"); /* fatal */
-
- g->al_addr = group_sa;
- g->al_old = 0;
-
- /** set a timer for expiration **/
- g->al_query = 0;
- g->al_timer = MLD6_LISTENER_INTERVAL;
- g->al_reporter = *src;
- g->al_timerid = SetTimer(mifi, g);
- g->al_next = v->uv_groups;
- v->uv_groups = g;
- time(&g->al_ctime);
-
- add_leaf(mifi, NULL, &group_sa);
- }
-}
-
-
-/* TODO: send PIM prune message if the last member? */
-void
-accept_listener_done(src, dst, group)
- struct sockaddr_in6 *src;
- struct in6_addr *dst, *group;
-{
- register mifi_t mifi;
- register struct uvif *v;
- register struct listaddr *g;
- struct sockaddr_in6 group_sa = {sizeof(group_sa), AF_INET6};
-
- if ((mifi = find_vif_direct_local(src)) == NO_VIF) {
- IF_DEBUG(DEBUG_MLD)
- log(LOG_INFO, 0,
- "accept_listener_done: can't find a mif");
- return;
- }
-
- IF_DEBUG(DEBUG_MLD)
- log(LOG_INFO, 0,
- "accepting listener done message: src %s, dst %s, grp %s",
- inet6_fmt(&src->sin6_addr),
- inet6_fmt(dst), inet6_fmt(group));
-
- v = &uvifs[mifi];
-
- if (!(v->uv_flags & (VIFF_QUERIER | VIFF_DR)))
- return;
-
- /*
- * Look for the group in our group list in order to set up a
- * short-timeout query.
- */
- group_sa.sin6_addr = *group;
- group_sa.sin6_scope_id = inet6_uvif2scopeid(&group_sa, v);
- for (g = v->uv_groups; g != NULL; g = g->al_next) {
- if (inet6_equal(&group_sa, &g->al_addr)) {
- IF_DEBUG(DEBUG_MLD)
- log(LOG_DEBUG, 0,
- "[accept_done_message] %d %ld\n",
- g->al_old, g->al_query);
-
- /*
- * Ignore the done message if there are old
- * hosts present
- */
- if (g->al_old)
- return;
-
- /*
- * still waiting for a reply to a query,
- * ignore the done
- */
- if (g->al_query)
- return;
-
- /** delete old timer set a timer for expiration **/
- if (g->al_timerid)
- g->al_timerid = DeleteTimer(g->al_timerid);
-
- /** send a group specific querry **/
- g->al_timer = (MLD6_LAST_LISTENER_QUERY_INTERVAL/MLD6_TIMER_SCALE) *
- (MLD6_LAST_LISTENER_QUERY_COUNT + 1);
- if (v->uv_flags & VIFF_QUERIER &&
- (v->uv_flags & VIFF_NOLISTENER) == 0)
- send_mld6(MLD6_LISTENER_QUERY, 0,
- &v->uv_linklocal->pa_addr, NULL,
- &g->al_addr.sin6_addr,
- v->uv_ifindex,
- MLD6_LAST_LISTENER_QUERY_INTERVAL, 0, 1);
- g->al_query = SetQueryTimer(g, mifi,
- MLD6_LAST_LISTENER_QUERY_INTERVAL/MLD6_TIMER_SCALE,
- MLD6_LAST_LISTENER_QUERY_INTERVAL);
- g->al_timerid = SetTimer(mifi, g);
- break;
- }
- }
-}
-
-
-/*
- * Time out record of a group membership on a vif
- */
-static void
-DelVif(arg)
- void *arg;
-{
- cbk_t *cbk = (cbk_t *)arg;
- mifi_t mifi = cbk->mifi;
- struct uvif *v = &uvifs[mifi];
- struct listaddr *a, **anp, *g = cbk->g;
-
- /*
- * Group has expired
- * delete all kernel cache entries with this group
- */
- if (g->al_query)
- DeleteTimer(g->al_query);
-
- delete_leaf(mifi, NULL, &g->al_addr);
-
- anp = &(v->uv_groups);
- while ((a = *anp) != NULL) {
- if (a == g) {
- *anp = a->al_next;
- free((char *)a);
- } else {
- anp = &a->al_next;
- }
- }
-
- free(cbk);
-}
-
-
-/*
- * Set a timer to delete the record of a group membership on a vif.
- */
-static int
-SetTimer(mifi, g)
- mifi_t mifi;
- struct listaddr *g;
-{
- cbk_t *cbk;
-
- cbk = (cbk_t *) malloc(sizeof(cbk_t));
- cbk->mifi = mifi;
- cbk->g = g;
- return timer_setTimer(g->al_timer, DelVif, cbk);
-}
-
-
-/*
- * Delete a timer that was set above.
- */
-static int
-DeleteTimer(id)
- int id;
-{
- timer_clearTimer(id);
- return 0;
-}
-
-
-/*
- * Send a group-specific query.
- */
-static void
-SendQuery(arg)
- void *arg;
-{
- cbk_t *cbk = (cbk_t *)arg;
- register struct uvif *v = &uvifs[cbk->mifi];
-
- if (v->uv_flags & VIFF_QUERIER && (v->uv_flags & VIFF_NOLISTENER) == 0)
- send_mld6(MLD6_LISTENER_QUERY, 0, &v->uv_linklocal->pa_addr,
- NULL, &cbk->g->al_addr.sin6_addr,
- v->uv_ifindex, cbk->q_time, 0, 1);
- cbk->g->al_query = 0;
- free(cbk);
-}
-
-
-/*
- * Set a timer to send a group-specific query.
- */
-static int
-SetQueryTimer(g, mifi, to_expire, q_time)
- struct listaddr *g;
- mifi_t mifi;
- int to_expire;
- int q_time;
-{
- cbk_t *cbk;
-
- cbk = (cbk_t *) malloc(sizeof(cbk_t));
- cbk->g = g;
- cbk->q_time = q_time;
- cbk->mifi = mifi;
- return timer_setTimer(to_expire, SendQuery, cbk);
-}
-
-/* Checks for MLD listener: returns TRUE if there is a receiver for the
- * group on the given uvif, or returns FALSE otherwise.
- */
-int
-check_multicast_listener(v, group)
- struct uvif *v;
- struct sockaddr_in6 *group;
-{
- register struct listaddr *g;
-
- /*
- * Look for the group in our listener list;
- */
- for (g = v->uv_groups; g != NULL; g = g->al_next) {
- if (inet6_equal(group, &g->al_addr))
- return TRUE;
- }
- return FALSE;
-}
diff --git a/usr.sbin/pim6dd/mrt.c b/usr.sbin/pim6dd/mrt.c
deleted file mode 100644
index df4df3c..0000000
--- a/usr.sbin/pim6dd/mrt.c
+++ /dev/null
@@ -1,803 +0,0 @@
-/*
- * Copyright (c) 1998 by the University of Oregon.
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation in source and binary forms for lawful
- * purposes and without fee is hereby granted, provided
- * that the above copyright notice appear in all copies and that both
- * the copyright notice and this permission notice appear in supporting
- * documentation, and that any documentation, advertising materials,
- * and other materials related to such distribution and use acknowledge
- * that the software was developed by the University of Oregon.
- * The name of the University of Oregon may not be used to endorse or
- * promote products derived from this software without specific prior
- * written permission.
- *
- * THE UNIVERSITY OF OREGON DOES NOT MAKE ANY REPRESENTATIONS
- * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. THIS SOFTWARE IS
- * PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
- * NON-INFRINGEMENT.
- *
- * IN NO EVENT SHALL UO, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT,
- * TORT, OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH,
- * THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Other copyrights might apply to parts of this software and are so
- * noted when applicable.
- */
-/*
- * Questions concerning this software should be directed to
- * Kurt Windisch (kurtw@antc.uoregon.edu)
- *
- * $Id: mrt.c,v 1.3 2000/05/18 16:09:39 itojun Exp $
- */
-/*
- * Part of this program has been derived from PIM sparse-mode pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- * The pimd program is COPYRIGHT 1998 by University of Southern California.
- *
- * Part of this program has been derived from mrouted.
- * The mrouted program is covered by the license in the accompanying file
- * named "LICENSE.mrouted".
- *
- * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
- * Leland Stanford Junior University.
- *
- * $FreeBSD$
- */
-
-#include "defs.h"
-
-srcentry_t *srclist;
-grpentry_t *grplist;
-
-/*
- * Local functions definition
- */
-static srcentry_t *create_srcentry __P((struct sockaddr_in6 *source));
-static int search_srclist __P((struct sockaddr_in6 *source,
- srcentry_t **sourceEntry));
-static int search_srcmrtlink __P((srcentry_t *srcentry_ptr,
- struct sockaddr_in6 *group,
- mrtentry_t **mrtPtr));
-static void insert_srcmrtlink __P((mrtentry_t *elementPtr,
- mrtentry_t *insertPtr,
- srcentry_t *srcListPtr));
-static grpentry_t *create_grpentry __P((struct sockaddr_in6 *group));
-static int search_grplist __P((struct sockaddr_in6 *group,
- grpentry_t **groupEntry));
-static int search_grpmrtlink __P((grpentry_t *grpentry_ptr,
- struct sockaddr_in6 *source,
- mrtentry_t **mrtPtr));
-static void insert_grpmrtlink __P((mrtentry_t *elementPtr,
- mrtentry_t *insertPtr,
- grpentry_t *grpListPtr));
-static mrtentry_t *alloc_mrtentry __P((srcentry_t *srcentry_ptr,
- grpentry_t *grpentry_ptr));
-static mrtentry_t *create_mrtentry __P((srcentry_t *srcentry_ptr,
- grpentry_t *grpentry_ptr,
- u_int16 flags));
-
-
-void
-init_pim6_mrt()
-{
-
- /* TODO: delete any existing routing table */
-
- /* Initialize the source list */
- /* The first entry has the unspecified address and is not used */
- /* The order is the smallest address first. */
- srclist = (srcentry_t *)malloc(sizeof(srcentry_t));
- srclist->next = (srcentry_t *)NULL;
- srclist->prev = (srcentry_t *)NULL;
- memset(&srclist->address, 0, sizeof(struct sockaddr_in6));
- srclist->address.sin6_len = sizeof(struct sockaddr_in6);
- srclist->address.sin6_family = AF_INET6;
- srclist->mrtlink = (mrtentry_t *)NULL;
- srclist->incoming = NO_VIF;
- srclist->upstream = (pim_nbr_entry_t *)NULL;
- srclist->metric = 0;
- srclist->preference = 0;
- srclist->timer = 0;
-
- /* Initialize the group list */
- /* The first entry has the unspecified address and is not used */
- /* The order is the smallest address first. */
- grplist = (grpentry_t *)malloc(sizeof(grpentry_t));
- grplist->next = (grpentry_t *)NULL;
- grplist->prev = (grpentry_t *)NULL;
- memset(&grplist->group, 0, sizeof(struct sockaddr_in6));
- grplist->group.sin6_len = sizeof(struct sockaddr_in6);
- grplist->group.sin6_family = AF_INET6;
- grplist->mrtlink = (mrtentry_t *)NULL;
-}
-
-
-grpentry_t*
-find_group(group)
- struct sockaddr_in6 *group;
-{
- grpentry_t *grpentry_ptr;
-
- if (!IN6_IS_ADDR_MULTICAST(&group->sin6_addr))
- return (grpentry_t *)NULL;
-
- if (search_grplist(group, &grpentry_ptr) == TRUE) {
- /* Group found! */
- return (grpentry_ptr);
- }
- return (grpentry_t *)NULL;
-}
-
-
-srcentry_t *
-find_source(source)
- struct sockaddr_in6 *source;
-{
- srcentry_t *srcentry_ptr;
-
- if (!inet6_valid_host(source))
- return (srcentry_t *)NULL;
-
- if (search_srclist(source, &srcentry_ptr) == TRUE) {
- /* Source found! */
- return (srcentry_ptr);
- }
- return (srcentry_t *)NULL;
-}
-
-
-mrtentry_t *
-find_route(source, group, flags, create)
- struct sockaddr_in6 *source, *group;
- u_int16 flags;
- char create;
-{
- srcentry_t *srcentry_ptr;
- grpentry_t *grpentry_ptr;
- mrtentry_t *mrtentry_ptr;
-
- if (!IN6_IS_ADDR_MULTICAST(&group->sin6_addr))
- return (mrtentry_t *)NULL;
-
- if (!inet6_valid_host(source))
- return (mrtentry_t *)NULL;
-
- if (create == DONT_CREATE) {
- if (search_grplist(group, &grpentry_ptr) == FALSE)
- return (mrtentry_t *)NULL;
- /* Search for the source */
- if (search_grpmrtlink(grpentry_ptr, source,
- &mrtentry_ptr) == TRUE) {
- /* Exact (S,G) entry found */
- return (mrtentry_ptr);
- }
- return (mrtentry_t *)NULL;
- }
-
-
- /* Creation allowed */
-
- grpentry_ptr = create_grpentry(group);
- if (grpentry_ptr == (grpentry_t *)NULL) {
- return (mrtentry_t *)NULL;
- }
-
- /* Setup the (S,G) routing entry */
- srcentry_ptr = create_srcentry(source);
- if (srcentry_ptr == (srcentry_t *)NULL) {
- if (grpentry_ptr->mrtlink == (mrtentry_t *)NULL) {
- /* New created grpentry. Delete it. */
- delete_grpentry(grpentry_ptr);
- }
- return (mrtentry_t *)NULL;
- }
-
- mrtentry_ptr = create_mrtentry(srcentry_ptr, grpentry_ptr, MRTF_SG);
- if (mrtentry_ptr == (mrtentry_t *)NULL) {
- if (grpentry_ptr->mrtlink == (mrtentry_t *)NULL) {
- /* New created grpentry. Delete it. */
- delete_grpentry(grpentry_ptr);
- }
- if (srcentry_ptr->mrtlink == (mrtentry_t *)NULL) {
- /* New created srcentry. Delete it. */
- delete_srcentry(srcentry_ptr);
- }
- return (mrtentry_t *)NULL;
- }
-
- if (mrtentry_ptr->flags & MRTF_NEW) {
- struct mrtfilter *f;
- /* The mrtentry pref/metric should be the pref/metric of the
- * _upstream_ assert winner. Since this isn't known now,
- * set it to the config'ed default
- */
- mrtentry_ptr->incoming = srcentry_ptr->incoming;
- mrtentry_ptr->upstream = srcentry_ptr->upstream;
- mrtentry_ptr->metric = srcentry_ptr->metric;
- mrtentry_ptr->preference = srcentry_ptr->preference;
-
- if ((f = search_filter(&group->sin6_addr)))
- IF_COPY(&f->ifset, &mrtentry_ptr->filter_oifs);
- }
-
- return (mrtentry_ptr);
-}
-
-
-void
-delete_srcentry(srcentry_ptr)
- srcentry_t *srcentry_ptr;
-{
- mrtentry_t *mrtentry_ptr;
- mrtentry_t *mrtentry_next;
-
- if (srcentry_ptr == (srcentry_t *)NULL)
- return;
- /* TODO: XXX: the first entry is unused and always there */
- srcentry_ptr->prev->next = srcentry_ptr->next;
- if (srcentry_ptr->next != (srcentry_t *)NULL)
- srcentry_ptr->next->prev = srcentry_ptr->prev;
-
- for (mrtentry_ptr = srcentry_ptr->mrtlink;
- mrtentry_ptr != (mrtentry_t *)NULL;
- mrtentry_ptr = mrtentry_next) {
- mrtentry_next = mrtentry_ptr->srcnext;
- if (mrtentry_ptr->grpprev != (mrtentry_t *)NULL)
- mrtentry_ptr->grpprev->grpnext = mrtentry_ptr->grpnext;
- else {
- mrtentry_ptr->group->mrtlink = mrtentry_ptr->grpnext;
- if (mrtentry_ptr->grpnext == (mrtentry_t *)NULL) {
- /* Delete the group entry */
- delete_grpentry(mrtentry_ptr->group);
- }
- }
- if (mrtentry_ptr->grpnext != (mrtentry_t *)NULL)
- mrtentry_ptr->grpnext->grpprev = mrtentry_ptr->grpprev;
- FREE_MRTENTRY(mrtentry_ptr);
- }
- free((char *)srcentry_ptr);
-}
-
-
-void
-delete_grpentry(grpentry_ptr)
- grpentry_t *grpentry_ptr;
-{
- mrtentry_t *mrtentry_ptr;
- mrtentry_t *mrtentry_next;
-
- if (grpentry_ptr == (grpentry_t *)NULL)
- return;
- /* TODO: XXX: the first entry is unused and always there */
- grpentry_ptr->prev->next = grpentry_ptr->next;
- if (grpentry_ptr->next != (grpentry_t *)NULL)
- grpentry_ptr->next->prev = grpentry_ptr->prev;
-
- for (mrtentry_ptr = grpentry_ptr->mrtlink;
- mrtentry_ptr != (mrtentry_t *)NULL;
- mrtentry_ptr = mrtentry_next) {
- mrtentry_next = mrtentry_ptr->grpnext;
- if (mrtentry_ptr->srcprev != (mrtentry_t *)NULL)
- mrtentry_ptr->srcprev->srcnext = mrtentry_ptr->srcnext;
- else {
- mrtentry_ptr->source->mrtlink = mrtentry_ptr->srcnext;
- if (mrtentry_ptr->srcnext == (mrtentry_t *)NULL) {
- /* Delete the srcentry if this was the last routing entry */
- delete_srcentry(mrtentry_ptr->source);
- }
- }
- if (mrtentry_ptr->srcnext != (mrtentry_t *)NULL)
- mrtentry_ptr->srcnext->srcprev = mrtentry_ptr->srcprev;
- FREE_MRTENTRY(mrtentry_ptr);
- }
- free((char *)grpentry_ptr);
-}
-
-
-void
-delete_mrtentry(mrtentry_ptr)
- mrtentry_t *mrtentry_ptr;
-{
- if (mrtentry_ptr == (mrtentry_t *)NULL)
- return;
-
- /* Delete the kernel cache first */
- k_del_mfc(mld6_socket, &mrtentry_ptr->source->address,
- &mrtentry_ptr->group->group);
-
-#ifdef RSRR
- /* Tell the reservation daemon */
- rsrr_cache_clean(mrtentry_ptr);
-#endif /* RSRR */
-
- /* (S,G) mrtentry */
- /* Delete from the grpentry MRT chain */
- if (mrtentry_ptr->grpprev != (mrtentry_t *)NULL)
- mrtentry_ptr->grpprev->grpnext = mrtentry_ptr->grpnext;
- else {
- mrtentry_ptr->group->mrtlink = mrtentry_ptr->grpnext;
- if (mrtentry_ptr->grpnext == (mrtentry_t *)NULL) {
- /* Delete the group entry */
- delete_grpentry(mrtentry_ptr->group);
- }
- }
-
- if (mrtentry_ptr->grpnext != (mrtentry_t *)NULL)
- mrtentry_ptr->grpnext->grpprev = mrtentry_ptr->grpprev;
-
- /* Delete from the srcentry MRT chain */
- if (mrtentry_ptr->srcprev != (mrtentry_t *)NULL)
- mrtentry_ptr->srcprev->srcnext = mrtentry_ptr->srcnext;
- else {
- mrtentry_ptr->source->mrtlink = mrtentry_ptr->srcnext;
- if (mrtentry_ptr->srcnext == (mrtentry_t *)NULL) {
- /* Delete the srcentry if this was the last routing entry */
- delete_srcentry(mrtentry_ptr->source);
- }
- }
- if (mrtentry_ptr->srcnext != (mrtentry_t *)NULL)
- mrtentry_ptr->srcnext->srcprev = mrtentry_ptr->srcprev;
-
- FREE_MRTENTRY(mrtentry_ptr);
-}
-
-
-static int
-search_srclist(source, sourceEntry)
- struct sockaddr_in6 *source;
- register srcentry_t **sourceEntry;
-{
- register srcentry_t *s_prev,*s;
-
- for (s_prev = srclist, s = s_prev->next; s != (srcentry_t *)NULL;
- s_prev = s, s = s->next) {
- /* The srclist is ordered with the smallest addresses first.
- * The first entry is not used.
- */
- if (inet6_lessthan(&s->address, source))
- continue;
- if (inet6_equal(&s->address, source)) {
- *sourceEntry = s;
- return(TRUE);
- }
- break;
- }
- *sourceEntry = s_prev; /* The insertion point is between s_prev and s */
- return(FALSE);
-}
-
-
-static int
-search_grplist(group, groupEntry)
- struct sockaddr_in6 *group;
- register grpentry_t **groupEntry;
-{
- register grpentry_t *g_prev, *g;
-
- for (g_prev = grplist, g = g_prev->next; g != (grpentry_t *)NULL;
- g_prev = g, g = g->next) {
- /* The grplist is ordered with the smallest address first.
- * The first entry is not used.
- */
- if (inet6_lessthan(&g->group, group))
- continue;
- if (inet6_equal(&g->group, group)) {
- *groupEntry = g;
- return(TRUE);
- }
- break;
- }
- *groupEntry = g_prev; /* The insertion point is between g_prev and g */
- return(FALSE);
-}
-
-static srcentry_t *
-create_srcentry(source)
- struct sockaddr_in6 *source;
-{
- register srcentry_t *srcentry_ptr;
- srcentry_t *srcentry_prev;
-
- if (search_srclist(source, &srcentry_prev) == TRUE)
- return (srcentry_prev);
-
- srcentry_ptr = (srcentry_t *)malloc(sizeof(srcentry_t));
- if (srcentry_ptr == (srcentry_t *)NULL) {
- log(LOG_WARNING, 0, "Memory allocation error for srcentry %s",
- inet6_fmt(&source->sin6_addr));
- return (srcentry_t *)NULL;
- }
-
- srcentry_ptr->address = *source;
- /*
- * Free the memory if there is error getting the iif and
- * the next hop (upstream) router.
- */
- if (set_incoming(srcentry_ptr, PIM_IIF_SOURCE) == FALSE) {
- free((char *)srcentry_ptr);
- return (srcentry_t *)NULL;
- }
- srcentry_ptr->mrtlink = (mrtentry_t *)NULL;
- srcentry_ptr->timer = 0;
- srcentry_ptr->next = srcentry_prev->next;
- srcentry_prev->next = srcentry_ptr;
- srcentry_ptr->prev = srcentry_prev;
- if (srcentry_ptr->next != (srcentry_t *)NULL)
- srcentry_ptr->next->prev = srcentry_ptr;
-
- IF_DEBUG(DEBUG_MFC)
- log(LOG_DEBUG, 0, "create source entry, source %s",
- inet6_fmt(&source->sin6_addr));
- return (srcentry_ptr);
-}
-
-
-static grpentry_t *
-create_grpentry(group)
- struct sockaddr_in6 *group;
-{
- register grpentry_t *grpentry_ptr;
- grpentry_t *grpentry_prev;
-
- if (search_grplist(group, &grpentry_prev) == TRUE)
- return (grpentry_prev);
-
- grpentry_ptr = (grpentry_t *)malloc(sizeof(grpentry_t));
- if (grpentry_ptr == (grpentry_t *)NULL) {
- log(LOG_WARNING, 0, "Memory allocation error for grpentry %s",
- inet6_fmt(&group->sin6_addr));
- return (grpentry_t *)NULL;
- }
-
- grpentry_ptr->group = *group;
- grpentry_ptr->mrtlink = (mrtentry_t *)NULL;
-
- /* Now it is safe to include the new group entry */
- grpentry_ptr->next = grpentry_prev->next;
- grpentry_prev->next = grpentry_ptr;
- grpentry_ptr->prev = grpentry_prev;
- if (grpentry_ptr->next != (grpentry_t *)NULL)
- grpentry_ptr->next->prev = grpentry_ptr;
-
- IF_DEBUG(DEBUG_MFC)
- log(LOG_DEBUG, 0, "create group entry, group %s",
- inet6_fmt(&group->sin6_addr));
- return(grpentry_ptr);
-}
-
-
-/*
- * Return TRUE if the entry is found and then *mrtPtr is set to point to that
- * entry. Otherwise return FALSE and *mrtPtr points the previous entry
- * (or NULL if first in the chain.
- */
-static int
-search_srcmrtlink(srcentry_ptr, group, mrtPtr)
- srcentry_t *srcentry_ptr;
- struct sockaddr_in6 *group;
- mrtentry_t **mrtPtr;
-{
- register mrtentry_t *mrtentry_ptr;
- register mrtentry_t *m_prev = (mrtentry_t *)NULL;
-
- for(mrtentry_ptr = srcentry_ptr->mrtlink;
- mrtentry_ptr != (mrtentry_t *)NULL;
- m_prev = mrtentry_ptr, mrtentry_ptr = mrtentry_ptr->srcnext) {
- /* The entries are ordered with the smaller group address first.
- * The addresses are in network order.
- */
- if (inet6_lessthan(&mrtentry_ptr->group->group, group))
- continue;
- if (inet6_equal(&mrtentry_ptr->group->group, group)) {
- *mrtPtr = mrtentry_ptr;
- return(TRUE);
- }
- break;
- }
- *mrtPtr = m_prev;
- return(FALSE);
-}
-
-
-/*
- * Return TRUE if the entry is found and then *mrtPtr is set to point to that
- * entry. Otherwise return FALSE and *mrtPtr points the previous entry
- * (or NULL if first in the chain.
- */
-static int
-search_grpmrtlink(grpentry_ptr, source, mrtPtr)
- grpentry_t *grpentry_ptr;
- struct sockaddr_in6 *source;
- mrtentry_t **mrtPtr;
-{
- register mrtentry_t *mrtentry_ptr;
- register mrtentry_t *m_prev = (mrtentry_t *)NULL;
-
- for (mrtentry_ptr = grpentry_ptr->mrtlink;
- mrtentry_ptr != (mrtentry_t *)NULL;
- m_prev = mrtentry_ptr, mrtentry_ptr = mrtentry_ptr->grpnext) {
- /* The entries are ordered with the smaller source address first.
- * The addresses are in network order.
- */
- if (inet6_lessthan(&mrtentry_ptr->source->address, source))
- continue;
- if (inet6_equal(source, &mrtentry_ptr->source->address)) {
- *mrtPtr = mrtentry_ptr;
- return(TRUE);
- }
- break;
- }
- *mrtPtr = m_prev;
- return(FALSE);
-}
-
-
-static void
-insert_srcmrtlink(mrtentry_new, mrtentry_prev, srcentry_ptr)
- mrtentry_t *mrtentry_new;
- mrtentry_t *mrtentry_prev;
- srcentry_t *srcentry_ptr;
-{
- if (mrtentry_prev == (mrtentry_t *)NULL) {
- /* Has to be insert as the head entry for this source */
- mrtentry_new->srcnext = srcentry_ptr->mrtlink;
- mrtentry_new->srcprev = (mrtentry_t *)NULL;
- srcentry_ptr->mrtlink = mrtentry_new;
- }
- else {
- /* Insert right after the mrtentry_prev */
- mrtentry_new->srcnext = mrtentry_prev->srcnext;
- mrtentry_new->srcprev = mrtentry_prev;
- mrtentry_prev->srcnext = mrtentry_new;
- }
- if (mrtentry_new->srcnext != (mrtentry_t *)NULL)
- mrtentry_new->srcnext->srcprev = mrtentry_new;
-}
-
-
-static void
-insert_grpmrtlink(mrtentry_new, mrtentry_prev, grpentry_ptr)
- mrtentry_t *mrtentry_new;
- mrtentry_t *mrtentry_prev;
- grpentry_t *grpentry_ptr;
-{
- if (mrtentry_prev == (mrtentry_t *)NULL) {
- /* Has to be insert as the head entry for this group */
- mrtentry_new->grpnext = grpentry_ptr->mrtlink;
- mrtentry_new->grpprev = (mrtentry_t *)NULL;
- grpentry_ptr->mrtlink = mrtentry_new;
- }
- else {
- /* Insert right after the mrtentry_prev */
- mrtentry_new->grpnext = mrtentry_prev->grpnext;
- mrtentry_new->grpprev = mrtentry_prev;
- mrtentry_prev->grpnext = mrtentry_new;
- }
- if (mrtentry_new->grpnext != (mrtentry_t *)NULL)
- mrtentry_new->grpnext->grpprev = mrtentry_new;
-}
-
-
-static mrtentry_t *
-alloc_mrtentry(srcentry_ptr, grpentry_ptr)
- srcentry_t *srcentry_ptr;
- grpentry_t *grpentry_ptr;
-{
- register mrtentry_t *mrtentry_ptr;
- u_int16 i, *i_ptr;
- u_long *il_ptr;
- u_int8 vif_numbers;
-
- mrtentry_ptr = (mrtentry_t *)malloc(sizeof(mrtentry_t));
- if (mrtentry_ptr == (mrtentry_t *)NULL) {
- log(LOG_WARNING, 0, "alloc_mrtentry(): out of memory");
- return (mrtentry_t *)NULL;
- }
-
- /*
- * grpnext, grpprev, srcnext, srcprev will be setup when we link the
- * mrtentry to the source and group chains
- */
- mrtentry_ptr->source = srcentry_ptr;
- mrtentry_ptr->group = grpentry_ptr;
- mrtentry_ptr->incoming = NO_VIF;
- IF_ZERO(&mrtentry_ptr->leaves);
- IF_ZERO(&mrtentry_ptr->pruned_oifs);
- IF_ZERO(&mrtentry_ptr->oifs);
- IF_ZERO(&mrtentry_ptr->filter_oifs);
- IF_ZERO(&mrtentry_ptr->asserted_oifs);
- mrtentry_ptr->upstream = (pim_nbr_entry_t *)NULL;
- mrtentry_ptr->metric = 0;
- mrtentry_ptr->preference = 0;
-#ifdef RSRR
- mrtentry_ptr->rsrr_cache = (struct rsrr_cache *)NULL;
-#endif /* RSRR */
-
-/*
- * XXX: TODO: if we are short in memory, we can reserve as few as possible
- * space for vif timers (per group and/or routing entry), but then everytime
- * when a new interfaces is configured, the router will be restarted and
- * will delete the whole routing table. The "memory is cheap" solution is
- * to reserve timer space for all potential vifs in advance and then no
- * need to delete the routing table and disturb the forwarding.
- */
-#ifdef SAVE_MEMORY
- mrtentry_ptr->prune_timers = (u_int16 *)malloc(sizeof(u_int16) * numvifs);
- mrtentry_ptr->prune_delay_timerids =
- (u_long *)malloc(sizeof(u_long) * numvifs);
- mrtentry_ptr->last_assert = (u_long *)malloc(sizeof(u_long) * numvifs);
- mrtentry_ptr->last_prune = (u_long *)malloc(sizeof(u_long) * numvifs);
- vif_numbers = numvifs;
-#else
- mrtentry_ptr->prune_timers =
- (u_int16 *)malloc(sizeof(u_int16) * total_interfaces);
- mrtentry_ptr->prune_delay_timerids =
- (u_long *)malloc(sizeof(u_long) * total_interfaces);
- mrtentry_ptr->last_assert =
- (u_long *)malloc(sizeof(u_long) * total_interfaces);
- mrtentry_ptr->last_prune =
- (u_long *)malloc(sizeof(u_long) * total_interfaces);
- vif_numbers = total_interfaces;
-#endif /* SAVE_MEMORY */
- if ((mrtentry_ptr->prune_timers == (u_int16 *)NULL) ||
- (mrtentry_ptr->prune_delay_timerids == (u_long *)NULL) ||
- (mrtentry_ptr->last_assert == (u_long *)NULL) ||
- (mrtentry_ptr->last_prune == (u_long *)NULL)) {
- log(LOG_WARNING, 0, "alloc_mrtentry(): out of memory");
- FREE_MRTENTRY(mrtentry_ptr);
- return (mrtentry_t *)NULL;
- }
- /* Reset the timers */
- for (i = 0, i_ptr = mrtentry_ptr->prune_timers; i < vif_numbers;
- i++, i_ptr++)
- *i_ptr = 0;
- for (i = 0, il_ptr = mrtentry_ptr->prune_delay_timerids; i < vif_numbers;
- i++, il_ptr++)
- *il_ptr = 0;
- for (i = 0, il_ptr = mrtentry_ptr->last_assert; i < vif_numbers;
- i++, il_ptr++)
- *il_ptr = 0;
- for (i = 0, il_ptr = mrtentry_ptr->last_prune; i < vif_numbers;
- i++, il_ptr++)
- *il_ptr = 0;
-
- mrtentry_ptr->flags = MRTF_NEW;
- mrtentry_ptr->timer = 0;
- mrtentry_ptr->join_delay_timerid = 0;
- mrtentry_ptr->assert_timer = 0;
- mrtentry_ptr->graft = (pim_graft_entry_t *)NULL;
-
- return(mrtentry_ptr);
-}
-
-
-static mrtentry_t *
-create_mrtentry(srcentry_ptr, grpentry_ptr, flags)
- srcentry_t *srcentry_ptr;
- grpentry_t *grpentry_ptr;
- u_int16 flags;
-{
- mrtentry_t *r_new;
- mrtentry_t *r_grp_insert, *r_src_insert; /* pointers to insert */
- struct sockaddr_in6 *source;
- struct sockaddr_in6 *group;
-
- /* (S,G) entry */
- source = &srcentry_ptr->address;
- group = &grpentry_ptr->group;
-
- if (search_grpmrtlink(grpentry_ptr, source, &r_grp_insert) == TRUE) {
- return(r_grp_insert);
- }
- if (search_srcmrtlink(srcentry_ptr, group, &r_src_insert) == TRUE) {
- /*
- * Hmmm, search_grpmrtlink() didn't find the entry, but
- * search_srcmrtlink() did find it! Shoudn't happen. Panic!
- */
- log(LOG_ERR, 0, "MRT inconsistency for src %s and grp %s\n",
- inet6_fmt(&source->sin6_addr), inet6_fmt(&group->sin6_addr));
- /* not reached but to make lint happy */
- return (mrtentry_t *)NULL;
- }
- /*
- * Create and insert in group mrtlink and source mrtlink chains.
- */
- r_new = alloc_mrtentry(srcentry_ptr, grpentry_ptr);
- if (r_new == (mrtentry_t *)NULL)
- return (mrtentry_t *)NULL;
- /*
- * r_new has to be insert right after r_grp_insert in the
- * grp mrtlink chain and right after r_src_insert in the
- * src mrtlink chain
- */
- insert_grpmrtlink(r_new, r_grp_insert, grpentry_ptr);
- insert_srcmrtlink(r_new, r_src_insert, srcentry_ptr);
- r_new->flags |= MRTF_SG;
- return (r_new);
-}
-
-/* ======================== */
-/* filter related functions */
-struct mrtfilter *filterlist;
-
-/*
- * Search for a filter entry in the filter list.
- */
-struct mrtfilter *
-search_filter(maddr)
- struct in6_addr *maddr;
-{
- struct mrtfilter *f;
- struct sockaddr_in6 msa6;
-
- for (f = filterlist; f; f = f->next) {
- switch(f->type) {
- case FILTER_RANGE:
- msa6.sin6_scope_id = 0; /* XXX: scope consideration */
- msa6.sin6_addr = *maddr;
- if (inet6_greateroreq(&msa6, &f->mrtf_from) &&
- inet6_lessoreq(&msa6, &f->mrtf_to))
- return(f);
- break;
- case FILTER_PREFIX:
- msa6.sin6_scope_id = 0; /* XXX: scope consideration */
- if (inet6_match_prefix(&msa6, &f->mrtf_prefix,
- &f->mrtf_mask))
- return(f);
- break;
- }
- }
-
- return(NULL);
-}
-
-/*
- * Make a new filter entry.
- * This function assumes
- */
-struct mrtfilter *
-add_filter(type, maddr1, maddr2, plen)
- struct in6_addr *maddr1, *maddr2;
- int type, plen;
-{
- struct mrtfilter *f;
- struct sockaddr_in6 from, to;
-
- if ((f = malloc(sizeof(*f))) == NULL)
- log(LOG_ERR, 0, "add_filter: malloc failed"); /* assert */
- memset((void *)f, 0, sizeof(*f));
-
- f->type = type;
- switch(type) {
- case FILTER_RANGE:
- memset((void *)&from, 0, sizeof(from));
- memset((void *)&to, 0, sizeof(to));
- from.sin6_addr = *maddr1;
- to.sin6_addr = *maddr2;
- if (inet6_lessthan(&from, &to)) {
- f->mrtf_from = from;
- f->mrtf_to = to;
- }
- else {
- f->mrtf_from = to;
- f->mrtf_to = from;
- }
- break;
- case FILTER_PREFIX:
- f->mrtf_prefix.sin6_addr = *maddr1;
- MASKLEN_TO_MASK6(plen, f->mrtf_mask);
- break;
- }
- f->next = filterlist;
- filterlist = f;
-
- return(f);
-}
diff --git a/usr.sbin/pim6dd/mrt.h b/usr.sbin/pim6dd/mrt.h
deleted file mode 100644
index daac170..0000000
--- a/usr.sbin/pim6dd/mrt.h
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (c) 1998 by the University of Oregon.
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation in source and binary forms for lawful
- * purposes and without fee is hereby granted, provided
- * that the above copyright notice appear in all copies and that both
- * the copyright notice and this permission notice appear in supporting
- * documentation, and that any documentation, advertising materials,
- * and other materials related to such distribution and use acknowledge
- * that the software was developed by the University of Oregon.
- * The name of the University of Oregon may not be used to endorse or
- * promote products derived from this software without specific prior
- * written permission.
- *
- * THE UNIVERSITY OF OREGON DOES NOT MAKE ANY REPRESENTATIONS
- * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. THIS SOFTWARE IS
- * PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
- * NON-INFRINGEMENT.
- *
- * IN NO EVENT SHALL UO, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT,
- * TORT, OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH,
- * THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Other copyrights might apply to parts of this software and are so
- * noted when applicable.
- */
-/*
- * Questions concerning this software should be directed to
- * Kurt Windisch (kurtw@antc.uoregon.edu)
- *
- * $Id: mrt.h,v 1.2 1999/08/24 10:04:56 jinmei Exp $
- */
-/*
- * Part of this program has been derived from PIM sparse-mode pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- * The pimd program is COPYRIGHT 1998 by University of Southern California.
- *
- * Part of this program has been derived from mrouted.
- * The mrouted program is covered by the license in the accompanying file
- * named "LICENSE.mrouted".
- *
- * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
- * Leland Stanford Junior University.
- *
- * $FreeBSD$
- */
-
-#define MRTF_SPT 0x0001 /* iif toward source */
-#define MRTF_WC 0x0002 /* (*,G) entry */
-#define MRTF_RP 0x0004 /* iif toward RP */
-#define MRTF_NEW 0x0008 /* new created routing entry */
-#define MRTF_IIF_REGISTER 0x0020 /* ??? */
-#define MRTF_REGISTER 0x0080 /* ??? */
-#define MRTF_KERNEL_CACHE 0x0200 /* a mirror for the kernel cache */
-#define MRTF_NULL_OIF 0x0400 /* null oif cache.. ??? */
-#define MRTF_REG_SUPP 0x0800 /* register suppress ??? */
-#define MRTF_ASSERTED 0x1000 /* upstream is not that of src ??? */
-#define MRTF_SG 0x2000 /* (S,G) pure, not hanging off of (*,G)*/
-#define MRTF_PMBR 0x4000 /* (*,*,RP) entry (for interop) */
-
-/* Macro to duplicate oif info (oif bits, timers): XXX: unused */
-#define VOIF_COPY(from, to) \
- do { \
- VIFM_COPY((from)->joined_oifs, (to)->joined_oifs); \
- VIFM_COPY((from)->oifs, (to)->oifs); \
- VIFM_COPY((from)->leaves, (to)->leaves); \
- VIFM_COPY((from)->pruned_oifs, (to)->pruned_oifs); \
- bcopy((from)->prune_timers, (to)->prune_timers, \
- numvifs*sizeof((from)->prune_timers[0])); \
- bcopy((from)->prune_delay_timerids, \
- (to)->prune_delay_timerids, \
- numvifs*sizeof((from)->prune_delay_timerids[0])); \
- (to)->join_delay_timerid = (from)->join_delay_timerid; \
- } while (0)
-
-#ifdef SAVE_MEMORY
-#define FREE_MRTENTRY(mrtentry_ptr) \
- do { \
- u_int16 i; \
- u_long *il_ptr; \
- free((char *)((mrtentry_ptr)->prune_timers)); \
- for(i=0, il_ptr=(mrtentry_ptr)->prune_delay_timerids; \
- i<numvifs; i++, il_ptr++) \
- timer_clearTimer(*il_ptr); \
- free((char *)((mrtentry_ptr)->prune_delay_timerids)); \
- timer_clearTimer((mrtentry_ptr)->join_delay_timerid); \
- delete_pim6_graft_entry((mrtentry_ptr)); \
- free((char *)(mrtentry_ptr)); \
- } while (0)
-#else
-#define FREE_MRTENTRY(mrtentry_ptr) \
- do { \
- u_int16 i; \
- u_long *il_ptr; \
- free((char *)((mrtentry_ptr)->prune_timers)); \
- for(i=0, il_ptr=(mrtentry_ptr)->prune_delay_timerids; \
- i<total_interfaces; i++, il_ptr++) \
- timer_clearTimer(*il_ptr); \
- free((char *)((mrtentry_ptr)->prune_delay_timerids)); \
- free((char *)((mrtentry_ptr)->last_assert)); \
- free((char *)((mrtentry_ptr)->last_prune)); \
- timer_clearTimer((mrtentry_ptr)->join_delay_timerid); \
- delete_pim6_graft_entry((mrtentry_ptr)); \
- free((char *)(mrtentry_ptr)); \
- } while (0)
-#endif /* SAVE_MEMORY */
-
-typedef struct pim_nbr_entry {
- struct pim_nbr_entry *next; /* link to next neighbor */
- struct pim_nbr_entry *prev; /* link to prev neighbor */
- struct sockaddr_in6 address; /* neighbor address */
- vifi_t vifi; /* which interface */
- u_int16 timer; /* for timing out neighbor */
-} pim_nbr_entry_t;
-
-
-/*
- * Used to get forwarded data related counts (number of packet, number of
- * bits, etc)
- */
-struct sg_count {
- u_long pktcnt; /* Number of packets for (s,g) */
- u_long bytecnt; /* Number of bytes for (s,g) */
- u_long wrong_if; /* Number of packets received on wrong iif for (s,g) */
-};
-
-typedef struct mrtentry mrtentry_t;
-typedef struct pim_graft_entry {
- struct pim_graft_entry *next;
- struct pim_graft_entry *prev;
- mrtentry_t *mrtlink;
-} pim_graft_entry_t;
-
-
-typedef struct srcentry {
- struct srcentry *next; /* link to next entry */
- struct srcentry *prev; /* link to prev entry */
- struct sockaddr_in6 address; /* source or RP address */
- struct mrtentry *mrtlink; /* link to routing entries */
- vifi_t incoming; /* incoming vif */
- struct pim_nbr_entry *upstream; /* upstream router */
- u_int32 metric; /* Unicast Routing Metric to the source */
- u_int32 preference; /* The metric preference (for assers)*/
- u_int16 timer; /* Entry timer??? Delete? */
-} srcentry_t;
-
-
-typedef struct grpentry {
- struct grpentry *next; /* link to next entry */
- struct grpentry *prev; /* link to prev entry */
- struct sockaddr_in6 group; /* subnet group of multicasts */
- struct mrtentry *mrtlink; /* link to (S,G) routing entries */
-} grpentry_t;
-
-struct mrtentry {
- struct mrtentry *grpnext; /* next entry of same group */
- struct mrtentry *grpprev; /* prev entry of same group */
- struct mrtentry *srcnext; /* next entry of same source */
- struct mrtentry *srcprev; /* prev entry of same source */
- struct grpentry *group; /* pointer to group entry */
- struct srcentry *source; /* pointer to source entry (or RP) */
- vifi_t incoming; /* the iif (either toward S or RP) */
-
- if_set oifs; /* The current result oifs */
- if_set pruned_oifs; /* The pruned oifs (Prune received) */
- if_set asserted_oifs; /* The asserted oifs (Lost Assert) */
- if_set filter_oifs; /* The filtered oifs */
- if_set leaves; /* Has directly connected members */
- struct pim_nbr_entry *upstream; /* upstream router, needed because
- * of the asserts it may be different
- * than the source (or RP) upstream
- * router.
- */
- u_int32 metric; /* Metric for the upstream */
- u_int32 preference; /* preference for the upstream */
- u_int16 *prune_timers; /* prune timer list */
- u_long *prune_delay_timerids; /* timers for LAN prunes */
- u_long join_delay_timerid; /* timer for delay joins */
- u_int16 flags; /* The MRTF_* flags */
- u_int16 timer; /* entry timer */
- u_int assert_timer;
- struct sg_count sg_count;
- u_long *last_assert; /* time for last data-driven assert */
- u_long *last_prune; /* time for last data-driven prune */
- pim_graft_entry_t *graft; /* Pointer into graft entry list */
-#ifdef RSRR
- struct rsrr_cache *rsrr_cache; /* Used to save RSRR requests for
- * routes change notification.
- */
-#endif /* RSRR */
-};
-
-
-struct vif_count {
- u_long icount; /* Input packet count on vif */
- u_long ocount; /* Output packet count on vif */
- u_long ibytes; /* Input byte count on vif */
- u_long obytes; /* Output byte count on vif */
-};
-
-#define FILTER_RANGE 0
-#define FILTER_PREFIX 1
-struct mrtfilter {
- struct mrtfilter *next; /* link to the next entry */
- int type; /* filter type: RANGE or PREFIX */
- union { /* type specific data structure */
- struct {
- struct sockaddr_in6 from;
- struct sockaddr_in6 to;
- } mrtfu_range;
- struct {
- struct sockaddr_in6 prefix;
- struct in6_addr mask;
- } mrtfu_prefix;
- } mrtu;
- if_set ifset; /* interface list */
-};
-#define mrtf_from mrtu.mrtfu_range.from
-#define mrtf_to mrtu.mrtfu_range.to
-#define mrtf_prefix mrtu.mrtfu_prefix.prefix
-#define mrtf_mask mrtu.mrtfu_prefix.mask
diff --git a/usr.sbin/pim6dd/pathnames.h b/usr.sbin/pim6dd/pathnames.h
deleted file mode 100644
index b611736..0000000
--- a/usr.sbin/pim6dd/pathnames.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 1998 by the University of Southern California.
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation in source and binary forms for lawful
- * purposes and without fee is hereby granted, provided
- * that the above copyright notice appear in all copies and that both
- * the copyright notice and this permission notice appear in supporting
- * documentation, and that any documentation, advertising materials,
- * and other materials related to such distribution and use acknowledge
- * that the software was developed by the University of Southern
- * California and/or Information Sciences Institute.
- * The name of the University of Southern California may not
- * be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THE UNIVERSITY OF SOUTHERN CALIFORNIA DOES NOT MAKE ANY REPRESENTATIONS
- * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. THIS SOFTWARE IS
- * PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
- * NON-INFRINGEMENT.
- *
- * IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT,
- * TORT, OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH,
- * THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Other copyrights might apply to parts of this software and are so
- * noted when applicable.
- */
-/*
- * Questions concerning this software should be directed to
- * Pavlin Ivanov Radoslavov (pavlin@catarina.usc.edu)
- *
- * $Id: pathnames.h,v 1.2 1999/12/16 05:36:37 jinmei Exp $
- */
-/*
- * Part of this program has been derived from mrouted.
- * The mrouted program is covered by the license in the accompanying file
- * named "LICENSE.mrouted".
- *
- * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
- * Leland Stanford Junior University.
- *
- * $FreeBSD$
- */
-
-
-#define _PATH_PIM6D_CONF "/etc/pim6dd.conf"
-
-#if (defined(BSD) && (BSD >= 199103))
-#define _PATH_PIM6D_PID "/var/run/pim6dd.pid"
-#define _PATH_PIM6D_GENID "/var/run/pim6dd.genid"
-#define _PATH_PIM6D_DUMP "/var/run/pim6dd.dump"
-#define _PATH_PIM6D_CACHE "/var/run/pim6dd.cache"
-#else
-#define _PATH_PIM6D_PID "/etc/pim6dd.pid"
-#define _PATH_PIM6D_GENID "/etc/pim6dd.genid"
-#define _PATH_PIM6D_DUMP "/etc/pim6dd.dump"
-#define _PATH_PIM6D_CACHE "/etc/pim6dd.cache"
-#endif
diff --git a/usr.sbin/pim6dd/pim6.c b/usr.sbin/pim6dd/pim6.c
deleted file mode 100644
index e0a18fe..0000000
--- a/usr.sbin/pim6dd/pim6.c
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
- * Copyright (C) 1998 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-/*
- * Copyright (c) 1998 by the University of Southern California.
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation in source and binary forms for lawful
- * purposes and without fee is hereby granted, provided
- * that the above copyright notice appear in all copies and that both
- * the copyright notice and this permission notice appear in supporting
- * documentation, and that any documentation, advertising materials,
- * and other materials related to such distribution and use acknowledge
- * that the software was developed by the University of Southern
- * California and/or Information Sciences Institute.
- * The name of the University of Southern California may not
- * be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THE UNIVERSITY OF SOUTHERN CALIFORNIA DOES NOT MAKE ANY REPRESENTATIONS
- * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. THIS SOFTWARE IS
- * PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
- * NON-INFRINGEMENT.
- *
- * IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT,
- * TORT, OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH,
- * THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Other copyrights might apply to parts of this software and are so
- * noted when applicable.
- */
-/*
- * Questions concerning this software should be directed to
- * Pavlin Ivanov Radoslavov (pavlin@catarina.usc.edu)
- *
- * $Id: pim6.c,v 1.6 2000/03/07 02:23:50 jinmei Exp $
- * $FreeBSD$
- */
-
-#include "defs.h"
-#include <sys/uio.h>
-
-/*
- * Exported variables.
- */
-char *pim6_recv_buf; /* input packet buffer */
-char *pim6_send_buf; /* output packet buffer */
-
-struct sockaddr_in6 allpim6routers_group; /* ALL_PIM_ROUTERS group */
-int pim6_socket; /* socket for PIM control msgs */
-
-/*
- * Local variables.
- */
-static struct sockaddr_in6 from;
-static struct msghdr sndmh;
-static struct iovec sndiov[2];
-static struct in6_pktinfo *sndpktinfo;
-static u_char *sndcmsgbuf = NULL;
-
-/*
- * Local function definitions.
- */
-static void pim6_read __P((int f, fd_set *rfd));
-static void accept_pim6 __P((int recvlen));
-static int pim6_cksum __P((u_short *, struct in6_addr *,
- struct in6_addr *, int));
-
-void
-init_pim6()
-{
- static int sndcmsglen;
- struct cmsghdr *cmsgp = (struct cmsghdr *)sndcmsgbuf;
-
- sndcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo));
- if ((pim6_socket = socket(AF_INET6, SOCK_RAW, IPPROTO_PIM)) < 0)
- log(LOG_ERR, errno, "PIM6 socket");
-
- k_set_rcvbuf(pim6_socket, SO_RECV_BUF_SIZE_MAX,
- SO_RECV_BUF_SIZE_MIN); /* lots of input buffering */
- k_set_hlim(pim6_socket, MINHLIM); /* restrict multicasts to one hop */
- k_set_loop(pim6_socket, FALSE); /* disable multicast loopback */
-
- allpim6routers_group.sin6_len = sizeof(allpim6routers_group);
- allpim6routers_group.sin6_family = AF_INET6;
- if (inet_pton(AF_INET6, "ff02::d",
- (void *)&allpim6routers_group.sin6_addr) != 1)
- log(LOG_ERR, 0, "inet_pton failed for ff02::d");
-
- if ((pim6_recv_buf = malloc(RECV_BUF_SIZE)) == NULL ||
- (pim6_send_buf = malloc(RECV_BUF_SIZE)) == NULL) {
- log(LOG_ERR, 0, "init_pim6: malloc failed\n");
- }
-
- /* initialize msghdr for sending packets */
- sndmh.msg_namelen = sizeof(struct sockaddr_in6);
- sndmh.msg_iov = sndiov;
- sndmh.msg_iovlen = 1;
- if (sndcmsgbuf == NULL && (sndcmsgbuf = malloc(sndcmsglen)) == NULL)
- log(LOG_ERR, 0, "malloc failed");
- sndmh.msg_control = (caddr_t)sndcmsgbuf;
- sndmh.msg_controllen = sndcmsglen;
- /* initilization cmsg for specifing outgoing interfaces and source */
- cmsgp=(struct cmsghdr *)sndcmsgbuf;
- cmsgp->cmsg_len = CMSG_SPACE(sizeof(struct in6_pktinfo));
- cmsgp->cmsg_level = IPPROTO_IPV6;
- cmsgp->cmsg_type = IPV6_PKTINFO;
- sndpktinfo = (struct in6_pktinfo *)CMSG_DATA(cmsgp);
-
- if (register_input_handler(pim6_socket, pim6_read) < 0)
- log(LOG_ERR, 0,
- "cannot register pim6_read() as an input handler");
-
- IF_ZERO(&nbr_mifs);
-}
-
-/* Read a PIM message */
-static void
-pim6_read(f, rfd)
- int f;
- fd_set *rfd;
-{
- register int pim6_recvlen;
- int fromlen = sizeof(from);
-#ifdef SYSV
- sigset_t block, oblock;
-#else
- register int omask;
-#endif
-
- pim6_recvlen = recvfrom(pim6_socket, pim6_recv_buf, RECV_BUF_SIZE,
- 0, (struct sockaddr *)&from, &fromlen);
-
- if (pim6_recvlen < 0) {
- if (errno != EINTR)
- log(LOG_ERR, errno, "PIM6 recvmsg");
- return;
- }
-
-#ifdef SYSV
- (void)sigemptyset(&block);
- (void)sigaddset(&block, SIGALRM);
- if (sigprocmask(SIG_BLOCK, &block, &oblock) < 0)
- log(LOG_ERR, errno, "sigprocmask");
-#else
- /* Use of omask taken from main() */
- omask = sigblock(sigmask(SIGALRM));
-#endif /* SYSV */
-
- accept_pim6(pim6_recvlen);
-
-#ifdef SYSV
- (void)sigprocmask(SIG_SETMASK, &oblock, (sigset_t *)NULL);
-#else
- (void)sigsetmask(omask);
-#endif /* SYSV */
-}
-
-
-static void
-accept_pim6(pimlen)
- int pimlen;
-{
- register struct pim *pim;
- struct sockaddr_in6 *src = &from;
-
- /* sanity check */
- if (pimlen < sizeof(pim)) {
- log(LOG_WARNING, 0,
- "data field too short (%u bytes) for PIM header, from %s",
- pimlen, inet6_fmt(&src->sin6_addr));
- return;
- }
- pim = (struct pim *)pim6_recv_buf;
-
-#ifdef NOSUCHDEF /* TODO: delete. Too noisy */
- IF_DEBUG(DEBUG_PIM_DETAIL) {
- IF_DEBUG(DEBUG_PIM) {
- log(LOG_DEBUG, 0, "Receiving %s from %s",
- packet_kind(IPPROTO_PIM, pim->pim_type, 0),
- inet6_fmt(&src->sin6_addr));
- log(LOG_DEBUG, 0, "PIM type is %u", pim->pim_type);
- }
- }
-#endif /* NOSUCHDEF */
-
-
- /* Check of PIM version is already done in the kernel */
- /*
- * TODO: check the dest. is ALL_PIM_ROUTERS (if multicast address)
- * is it necessary?
- */
- /* Checksum verification is done in the kernel. */
-
- switch (pim->pim_type) {
- case PIM_HELLO:
- receive_pim6_hello(src, (char *)(pim), pimlen);
- break;
- case PIM_REGISTER:
- log(LOG_INFO, 0, "ignore %s from %s",
- packet_kind(IPPROTO_PIM, pim->pim_type, 0),
- inet6_fmt(&src->sin6_addr));
- break;
- case PIM_REGISTER_STOP:
- log(LOG_INFO, 0, "ignore %s from %s",
- packet_kind(IPPROTO_PIM, pim->pim_type, 0),
- inet6_fmt(&src->sin6_addr));
- break;
- case PIM_JOIN_PRUNE:
- receive_pim6_join_prune(src, (char *)(pim), pimlen);
- break;
- case PIM_BOOTSTRAP:
- log(LOG_INFO, 0, "ignore %s from %s",
- packet_kind(IPPROTO_PIM, pim->pim_type, 0),
- inet6_fmt(&src->sin6_addr));
- break;
- case PIM_ASSERT:
- receive_pim6_assert(src, (char *)(pim), pimlen);
- break;
- case PIM_GRAFT:
- case PIM_GRAFT_ACK:
- receive_pim6_graft(src, (char *)(pim), pimlen, pim->pim_type);
- break;
- case PIM_CAND_RP_ADV:
- log(LOG_INFO, 0, "ignore %s from %s",
- packet_kind(IPPROTO_PIM, pim->pim_type, 0),
- inet6_fmt(&src->sin6_addr));
- break;
- default:
- log(LOG_INFO, 0,
- "ignore unknown PIM message code %u from %s",
- pim->pim_type,
- inet6_fmt(&src->sin6_addr));
- break;
- }
-}
-
-
-/*
- * Send a multicast PIM packet from src to dst, PIM message type = "type"
- * and data length (after the PIM header) = "datalen"
- */
-void
-send_pim6(buf, src, dst, type, datalen)
- char *buf;
- struct sockaddr_in6 *src, *dst;
- int type, datalen;
-{
- struct pim *pim;
- int setloop = 0;
- int ifindex = 0, sendlen = sizeof(struct pim) + datalen;
-
- /* Prepare the PIM packet */
- pim = (struct pim *)buf;
- pim->pim_type = type;
- pim->pim_ver = PIM_PROTOCOL_VERSION;
- pim->pim_rsv = 0;
- pim->pim_cksum = 0;
- /*
- * TODO: XXX: if start using this code for PIM_REGISTERS, exclude the
- * encapsulated packet from the checksum.
- */
- pim->pim_cksum = pim6_cksum((u_int16 *)pim,
- &src->sin6_addr, &dst->sin6_addr,
- sendlen);
-
- /*
- * Specify the source address of the packet. Also, specify the
- * outgoing interface and the source address if possible.
- */
- memcpy(&sndpktinfo->ipi6_addr, &src->sin6_addr,
- sizeof(src->sin6_addr));
- if ((ifindex = src->sin6_scope_id) != 0) {
- sndpktinfo->ipi6_ifindex = ifindex;
- }
- else {
- sndpktinfo->ipi6_ifindex = 0; /* make sure to be cleared */
- log(LOG_WARNING, 0,
- "send_pim6: could not determine the outgoint IF; send anyway");
- }
-
- if (IN6_IS_ADDR_MULTICAST(&dst->sin6_addr)) {
- k_set_if(pim6_socket, ifindex);
- if (IN6_ARE_ADDR_EQUAL(&dst->sin6_addr,
- &allnodes_group.sin6_addr) ||
- IN6_ARE_ADDR_EQUAL(&dst->sin6_addr,
- &allrouters_group.sin6_addr) ||
- IN6_ARE_ADDR_EQUAL(&dst->sin6_addr,
- &allpim6routers_group.sin6_addr)) {
- setloop = 1;
- k_set_loop(pim6_socket, TRUE);
- }
- }
-
- sndmh.msg_name = (caddr_t)dst;
- sndiov[0].iov_base = (caddr_t)buf;
- sndiov[0].iov_len = sendlen;
- if (sendmsg(pim6_socket, &sndmh, 0) < 0) {
- if (errno == ENETDOWN)
- check_vif_state();
- else
- log(LOG_WARNING, errno, "sendto from %s to %s",
- inet6_fmt(&src->sin6_addr),
- inet6_fmt(&dst->sin6_addr));
- if (setloop)
- k_set_loop(pim6_socket, FALSE);
- return;
- }
-
- if (setloop)
- k_set_loop(pim6_socket, FALSE);
-
- IF_DEBUG(DEBUG_PIM_DETAIL) {
- IF_DEBUG(DEBUG_PIM) {
- char ifname[IFNAMSIZ];
-
- log(LOG_DEBUG, 0, "SENT %s from %-15s to %s on %s",
- packet_kind(IPPROTO_PIM, type, 0),
- inet6_fmt(&src->sin6_addr),
- inet6_fmt(&dst->sin6_addr),
- ifindex ? if_indextoname(ifindex, ifname) : "?");
- }
- }
-}
-
-u_int pim_send_cnt = 0;
-#define SEND_DEBUG_NUMBER 50
-
-/* ============================== */
-
-/*
- * Checksum routine for Internet Protocol family headers (Portable Version).
- *
- * This routine is very heavily used in the network
- * code and should be modified for each CPU to be as fast as possible.
- */
-
-#define ADDCARRY(x) (x > 65535 ? x -= 65535 : x)
-#define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);}
-
-static union {
- u_short phs[4];
- struct {
- u_long ph_len;
- u_char ph_zero[3];
- u_char ph_nxt;
- } ph;
-} uph;
-
-/*
- * Our algorithm is simple, using a 32 bit accumulator (sum), we add
- * sequential 16 bit words to it, and at the end, fold back all the
- * carry bits from the top 16 bits into the lower 16 bits.
- */
-static int
-pim6_cksum(addr, src, dst, len)
- u_short *addr;
- struct in6_addr *src, *dst;
- int len;
-{
- register int nleft = len;
- register u_short *w;
- register int sum = 0;
- u_short answer = 0;
-
- /*
- * First create IP6 pseudo header and calculate a summary.
- */
- w = (u_short *)src;
- uph.ph.ph_len = htonl(len);
- uph.ph.ph_nxt = IPPROTO_PIM;
-
- /* IPv6 source address */
- sum += w[0];
- /* XXX: necessary? */
- if (!(IN6_IS_ADDR_LINKLOCAL(src) || IN6_IS_ADDR_MC_LINKLOCAL(src)))
- sum += w[1];
- sum += w[2]; sum += w[3]; sum += w[4]; sum += w[5];
- sum += w[6]; sum += w[7];
- /* IPv6 destination address */
- w = (u_short *)dst;
- sum += w[0];
- /* XXX: necessary? */
- if (!(IN6_IS_ADDR_LINKLOCAL(dst) || IN6_IS_ADDR_MC_LINKLOCAL(dst)))
- sum += w[1];
- sum += w[2]; sum += w[3]; sum += w[4]; sum += w[5];
- sum += w[6]; sum += w[7];
- /* Payload length and upper layer identifier */
- sum += uph.phs[0]; sum += uph.phs[1];
- sum += uph.phs[2]; sum += uph.phs[3];
-
- /*
- * Secondly calculate a summary of the first mbuf excluding offset.
- */
- w = addr;
- while (nleft > 1) {
- sum += *w++;
- nleft -= 2;
- }
-
- /* mop up an odd byte, if necessary */
- if (nleft == 1) {
- *(u_char *)(&answer) = *(u_char *)w ;
- sum += answer;
- }
-
- /* add back carry outs from top 16 bits to low 16 bits */
- sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
- sum += (sum >> 16); /* add carry */
- answer = ~sum; /* truncate to 16 bits */
- return(answer);
-}
diff --git a/usr.sbin/pim6dd/pim6_proto.c b/usr.sbin/pim6dd/pim6_proto.c
deleted file mode 100644
index 8a39a5e..0000000
--- a/usr.sbin/pim6dd/pim6_proto.c
+++ /dev/null
@@ -1,1596 +0,0 @@
-/*
- * Copyright (C) 1998 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-/*
- * Copyright (c) 1998 by the University of Oregon.
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation in source and binary forms for lawful
- * purposes and without fee is hereby granted, provided
- * that the above copyright notice appear in all copies and that both
- * the copyright notice and this permission notice appear in supporting
- * documentation, and that any documentation, advertising materials,
- * and other materials related to such distribution and use acknowledge
- * that the software was developed by the University of Oregon.
- * The name of the University of Oregon may not be used to endorse or
- * promote products derived from this software without specific prior
- * written permission.
- *
- * THE UNIVERSITY OF OREGON DOES NOT MAKE ANY REPRESENTATIONS
- * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. THIS SOFTWARE IS
- * PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
- * NON-INFRINGEMENT.
- *
- * IN NO EVENT SHALL UO, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT,
- * TORT, OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH,
- * THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Other copyrights might apply to parts of this software and are so
- * noted when applicable.
- */
-/*
- * Questions concerning this software should be directed to
- * Kurt Windisch (kurtw@antc.uoregon.edu)
- *
- * $Id: pim6_proto.c,v 1.6 2000/10/05 22:20:38 itojun Exp $
- */
-/*
- * Part of this program has been derived from PIM sparse-mode pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- * The pimd program is COPYRIGHT 1998 by University of Southern California.
- *
- * Part of this program has been derived from mrouted.
- * The mrouted program is covered by the license in the accompanying file
- * named "LICENSE.mrouted".
- *
- * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
- * Leland Stanford Junior University.
- *
- * $FreeBSD$
- */
-
-#include "defs.h"
-
-/*
- * Local functions definitions.
- */
-static int parse_pim6_hello __P((char *pktPtr, int datalen,
- struct sockaddr_in6 *src,
- u_int16 *holdtime));
-static void delayed_join_job __P((void *));
-static void schedule_delayed_join __P((mrtentry_t *, struct sockaddr_in6 *));
-static void delayed_prune_job __P((void *));
-static void schedule_delayed_prune __P((mrtentry_t *, mifi_t, u_int16));
-static int compare_metrics __P((u_int32 local_preference,
- u_int32 local_metric,
- struct sockaddr_in6 *local_address,
- u_int32 remote_preference,
- u_int32 remote_metric,
- struct sockaddr_in6 *remote_address));
-static int retransmit_pim6_graft __P((mrtentry_t *));
-static void retransmit_all_pim6_grafts __P((void *));
-
-if_set nbr_mifs; /* Mifs that have one or more neighbors attached */
-
-/************************************************************************
- * PIM_HELLO
- ************************************************************************/
-int
-receive_pim6_hello(src, pim_message, datalen)
- struct sockaddr_in6 *src;
- register char *pim_message;
- int datalen;
-{
- mifi_t mifi;
- struct uvif *v;
- register pim_nbr_entry_t *nbr, *prev_nbr, *new_nbr;
- u_int16 holdtime;
- u_int8 *data_ptr;
- int state_change;
- srcentry_t *srcentry_ptr;
- srcentry_t *srcentry_ptr_next;
- mrtentry_t *mrtentry_ptr;
- u_long random_delay;
-
- if ((mifi = find_vif_direct(src)) == NO_VIF) {
- /* Either a local vif or somehow received PIM_HELLO from
- * non-directly connected router. Ignore it.
- */
- if (local_address(src) == NO_VIF)
- log(LOG_INFO, 0,
- "Ignoring PIM_HELLO from non-neighbor router %s",
- inet6_fmt(&src->sin6_addr));
- return(FALSE);
- }
-
- v = &uvifs[mifi];
- if (v->uv_flags & (VIFF_DOWN | VIFF_DISABLED))
- return(FALSE); /* Shoudn't come on this interface */
- data_ptr = (u_int8 *)(pim_message + sizeof(struct pim));
-
- /* Get the Holdtime (in seconds) from the message. Return if error. */
- if (parse_pim6_hello(pim_message, datalen, src, &holdtime) == FALSE)
- return(FALSE);
- IF_DEBUG(DEBUG_PIM_HELLO | DEBUG_PIM_TIMER)
- log(LOG_DEBUG, 0, "PIM HELLO holdtime from %s is %u",
- inet6_fmt(&src->sin6_addr), holdtime);
-
- for (prev_nbr = (pim_nbr_entry_t *)NULL, nbr = v->uv_pim_neighbors;
- nbr != (pim_nbr_entry_t *)NULL;
- prev_nbr = nbr, nbr = nbr->next) {
- /* The PIM neighbors are sorted in decreasing order of the
- * network addresses (note that to be able to compare them
- * correctly we must translate the addresses in host order.
- */
- if (inet6_lessthan(src, &nbr->address))
- continue;
- if (inet6_equal(src, &nbr->address)) {
- /* We already have an entry for this host */
- if (0 == holdtime) {
- /*
- * Looks like we have a nice neighbor who is
- * going down and wants to inform us by sending
- * "holdtime=0". Thanks buddy and see you again!
- */
- log(LOG_INFO, 0,
- "PIM HELLO received: neighbor %s going down",
- inet6_fmt(&src->sin6_addr));
- delete_pim6_nbr(nbr);
- return(TRUE);
- }
- /* Set the timer */
- nbr->timer = holdtime;
- return(TRUE);
- }
- else
- /*
- * No entry for this neighbor. Exit the loop and create an
- * entry for it.
- */
- break;
- }
-
- /*
- * This is a new neighbor. Create a new entry for it.
- * It must be added right after `prev_nbr`
- */
- new_nbr = (pim_nbr_entry_t *)malloc(sizeof(pim_nbr_entry_t));
- new_nbr->address = *src;
- new_nbr->vifi = mifi;
- new_nbr->timer = holdtime;
- new_nbr->next = nbr;
- new_nbr->prev = prev_nbr;
-
- if (prev_nbr != (pim_nbr_entry_t *)NULL)
- prev_nbr->next = new_nbr;
- else
- v->uv_pim_neighbors = new_nbr;
- if (new_nbr->next != (pim_nbr_entry_t *)NULL)
- new_nbr->next->prev = new_nbr;
-
- v->uv_flags &= ~VIFF_NONBRS;
- v->uv_flags |= VIFF_PIM_NBR;
- IF_SET(mifi, &nbr_mifs);
-
- /* Elect a new DR */
- if (inet6_lessthan(&v->uv_linklocal->pa_addr,
- &v->uv_pim_neighbors->address)) {
- /* The first address is the new potential remote
- * DR address and it wins (is >) over the local address.
- */
- v->uv_flags &= ~VIFF_DR;
- }
-
- /*
- * Since a new neighbour has come up, let it know your existence ASAP;
- * compute a random value, and reset the value to the hello timer
- * if it's smaller than the rest of the timer.
- * XXX: not in the spec...
- */
- random_delay = 1 + (random() % (long)(PIM_TIMER_HELLO_PERIOD - 1));
- if (random_delay < v->uv_pim_hello_timer)
- v->uv_pim_hello_timer = random_delay;
-
- /* Update the source entries */
- for (srcentry_ptr = srclist; srcentry_ptr != (srcentry_t *)NULL;
- srcentry_ptr = srcentry_ptr_next) {
- srcentry_ptr_next = srcentry_ptr->next;
-
- if (srcentry_ptr->incoming == mifi)
- continue;
-
- for (mrtentry_ptr = srcentry_ptr->mrtlink;
- mrtentry_ptr != (mrtentry_t *)NULL;
- mrtentry_ptr = mrtentry_ptr->srcnext) {
-
- if(!(IF_ISSET(mifi, &mrtentry_ptr->oifs))) {
- state_change =
- change_interfaces(mrtentry_ptr,
- srcentry_ptr->incoming,
- &mrtentry_ptr->pruned_oifs,
- &mrtentry_ptr->leaves,
- &mrtentry_ptr->asserted_oifs);
- if(state_change == 1)
- trigger_join_alert(mrtentry_ptr);
- }
- }
- }
-
- IF_DEBUG(DEBUG_PIM_HELLO)
- dump_vifs(stderr); /* Show we got a new neighbor */
- return(TRUE);
-}
-
-void
-delete_pim6_nbr(nbr_delete)
- pim_nbr_entry_t *nbr_delete;
-{
- srcentry_t *srcentry_ptr;
- srcentry_t *srcentry_ptr_next;
- mrtentry_t *mrtentry_ptr;
- struct uvif *v;
- int state_change;
-
- v = &uvifs[nbr_delete->vifi];
-
- /* Delete the entry from the pim_nbrs chain */
- if (nbr_delete->prev != (pim_nbr_entry_t *)NULL)
- nbr_delete->prev->next = nbr_delete->next;
- else
- v->uv_pim_neighbors = nbr_delete->next;
- if (nbr_delete->next != (pim_nbr_entry_t *)NULL)
- nbr_delete->next->prev = nbr_delete->prev;
-
- if (v->uv_pim_neighbors == (pim_nbr_entry_t *)NULL) {
- /* This was our last neighbor. */
- v->uv_flags &= ~VIFF_PIM_NBR;
- v->uv_flags |= (VIFF_NONBRS | VIFF_DR | VIFF_QUERIER);
- IF_CLR(nbr_delete->vifi, &nbr_mifs);
- }
- else {
- if (inet6_greaterthan(&v->uv_linklocal->pa_addr,
- &v->uv_pim_neighbors->address)) {
- /* The first address is the new potential remote
- * DR address, but the local address is the winner.
- */
- v->uv_flags |= VIFF_DR;
- }
- }
-
- /* Update the source entries:
- * If the deleted nbr was my upstream, then reset incoming and
- * update all (S,G) entries for sources reachable through it.
- * If the deleted nbr was the last on a non-iif vif, then recalcuate
- * outgoing interfaces.
- */
- for (srcentry_ptr = srclist; srcentry_ptr != (srcentry_t *)NULL;
- srcentry_ptr = srcentry_ptr_next) {
- srcentry_ptr_next = srcentry_ptr->next;
-
- /* The only time we don't need to scan all mrtentries is
- * when the nbr was on the iif, but not the upstream nbr!
- */
- if (nbr_delete->vifi == srcentry_ptr->incoming &&
- srcentry_ptr->upstream != nbr_delete)
- continue;
-
- /* Reset the next hop (PIM) router */
- if(srcentry_ptr->upstream == nbr_delete)
- if (set_incoming(srcentry_ptr, PIM_IIF_SOURCE) == FALSE) {
- /*
- * Couldn't reset it. Sorry, the next hop router
- * toward that source is probably not
- * a PIM router, or cannot find route at all,
- * hence I cannot handle this source and have to
- * delete it.
- */
- delete_srcentry(srcentry_ptr);
- free((char *)nbr_delete);
- return;
- }
-
- for (mrtentry_ptr = srcentry_ptr->mrtlink;
- mrtentry_ptr != (mrtentry_t *)NULL;
- mrtentry_ptr = mrtentry_ptr->srcnext) {
- mrtentry_ptr->incoming = srcentry_ptr->incoming;
- mrtentry_ptr->upstream = srcentry_ptr->upstream;
- mrtentry_ptr->metric = srcentry_ptr->metric;
- mrtentry_ptr->preference = srcentry_ptr->preference;
- state_change =
- change_interfaces(mrtentry_ptr,
- srcentry_ptr->incoming,
- &mrtentry_ptr->pruned_oifs,
- &mrtentry_ptr->leaves,
- &mrtentry_ptr->asserted_oifs);
- if(state_change == -1) {
- trigger_prune_alert(mrtentry_ptr);
- } else if(state_change == 1) {
- trigger_join_alert(mrtentry_ptr);
- }
- }
- }
-
- free((char *)nbr_delete);
-}
-
-
-/* TODO: simplify it! */
-static int
-parse_pim6_hello(pim_message, datalen, src, holdtime)
- char *pim_message;
- int datalen;
- struct sockaddr_in6 *src;
- u_int16 *holdtime;
-{
- u_int8 *pim_hello_message;
- u_int8 *data_ptr;
- u_int16 option_type;
- u_int16 option_length;
- int holdtime_received_ok = FALSE;
- int option_total_length;
-
- pim_hello_message = (u_int8 *)(pim_message + sizeof(struct pim));
- datalen -= sizeof(struct pim);
- for ( ; datalen >= sizeof(pim_hello_t); ) {
- /* Ignore any data if shorter than (pim_hello header) */
- data_ptr = pim_hello_message;
- GET_HOSTSHORT(option_type, data_ptr);
- GET_HOSTSHORT(option_length, data_ptr);
- switch (option_type) {
- case PIM_MESSAGE_HELLO_HOLDTIME:
- if (PIM_MESSAGE_HELLO_HOLDTIME_LENGTH != option_length) {
- IF_DEBUG(DEBUG_PIM_HELLO)
- log(LOG_DEBUG, 0,
- "PIM HELLO Holdtime from %s: "
- "invalid OptionLength = %u",
- inet6_fmt(&src->sin6_addr),
- option_length);
- return (FALSE);
- }
- GET_HOSTSHORT(*holdtime, data_ptr);
- holdtime_received_ok = TRUE;
- break;
- default:
- /* Ignore any unknown options */
- break;
- }
-
- /* Move to the next option */
- /* XXX: TODO: If we are padding to the end of the 32 bit boundary,
- * use the first method to move to the next option, otherwise
- * simply (sizeof(pim_hello_t) + option_length).
- */
-#ifdef BOUNDARY_32_BIT
- option_total_length = (sizeof(pim_hello_t) + (option_length & ~0x3) +
- ((option_length & 0x3) ? 4 : 0));
-#else
- option_total_length = (sizeof(pim_hello_t) + option_length);
-#endif /* BOUNDARY_32_BIT */
- datalen -= option_total_length;
- pim_hello_message += option_total_length;
- }
- return (holdtime_received_ok);
-}
-
-
-int
-send_pim6_hello(v, holdtime)
- struct uvif *v;
- u_int16 holdtime;
-{
- char *buf;
- u_int8 *data_ptr;
-
- int datalen;
-
- buf = pim6_send_buf + sizeof(struct pim);
- data_ptr = (u_int8 *)buf;
- PUT_HOSTSHORT(PIM_MESSAGE_HELLO_HOLDTIME, data_ptr);
- PUT_HOSTSHORT(PIM_MESSAGE_HELLO_HOLDTIME_LENGTH, data_ptr);
- PUT_HOSTSHORT(holdtime, data_ptr);
-
- datalen = data_ptr - (u_int8 *)buf;
-
- send_pim6(pim6_send_buf, &v->uv_linklocal->pa_addr,
- &allpim6routers_group, PIM_HELLO, datalen);
- v->uv_pim_hello_timer = PIM_TIMER_HELLO_PERIOD;
- return(TRUE);
-}
-
-
-/************************************************************************
- * PIM_JOIN_PRUNE
- ************************************************************************/
-
-typedef struct {
- struct sockaddr_in6 source;
- struct sockaddr_in6 group;
- struct sockaddr_in6 target;
-} join_delay_cbk_t;
-
-typedef struct {
- mifi_t mifi;
- struct sockaddr_in6 source;
- struct sockaddr_in6 group;
- u_int16 holdtime;
-} prune_delay_cbk_t;
-
-static void
-delayed_join_job(arg)
- void *arg;
-{
- mrtentry_t *mrtentry_ptr;
-
- join_delay_cbk_t *cbk = (join_delay_cbk_t *)arg;
-
- mrtentry_ptr = find_route(&cbk->source, &cbk->group,
- MRTF_SG, DONT_CREATE);
- if(mrtentry_ptr == (mrtentry_t *)NULL)
- return;
-
- if(mrtentry_ptr->join_delay_timerid)
- timer_clearTimer(mrtentry_ptr->join_delay_timerid);
-
- if(mrtentry_ptr->upstream)
- send_pim6_jp(mrtentry_ptr, PIM_ACTION_JOIN,
- mrtentry_ptr->incoming,
- &mrtentry_ptr->upstream->address, 0, 0);
-
- free(cbk);
-}
-
-static void
-schedule_delayed_join(mrtentry_ptr, target)
- mrtentry_t *mrtentry_ptr;
- struct sockaddr_in6 *target;
-{
- u_long random_delay;
- join_delay_cbk_t *cbk;
-
- /* Delete existing timer */
- if(mrtentry_ptr->join_delay_timerid)
- timer_clearTimer(mrtentry_ptr->join_delay_timerid);
-
-#ifdef SYSV
- random_delay = lrand48() % (long)PIM_RANDOM_DELAY_JOIN_TIMEOUT;
-#else
- random_delay = random() % (long)PIM_RANDOM_DELAY_JOIN_TIMEOUT;
-#endif
-
- IF_DEBUG(DEBUG_PIM_JOIN_PRUNE)
- log(LOG_DEBUG, 0, "Scheduling join for src %s, grp %s, delay %ld",
- inet6_fmt(&mrtentry_ptr->source->address.sin6_addr),
- inet6_fmt(&mrtentry_ptr->group->group.sin6_addr),
- random_delay);
-
- if(random_delay == 0 && mrtentry_ptr->upstream) {
- send_pim6_jp(mrtentry_ptr, PIM_ACTION_JOIN,
- mrtentry_ptr->incoming,
- &mrtentry_ptr->upstream->address, 0, 0);
- return;
- }
-
- cbk = (join_delay_cbk_t *)malloc(sizeof(join_delay_cbk_t));
- cbk->source = mrtentry_ptr->source->address;
- cbk->group = mrtentry_ptr->group->group;
- cbk->target = *target;
-
- mrtentry_ptr->join_delay_timerid =
- timer_setTimer(random_delay, delayed_join_job, cbk);
-}
-
-
-static void
-delayed_prune_job(arg)
- void *arg;
-{
- mrtentry_t *mrtentry_ptr;
- if_set new_pruned_oifs;
- int state_change;
-
- prune_delay_cbk_t *cbk = (prune_delay_cbk_t *)arg;
-
- mrtentry_ptr = find_route(&cbk->source, &cbk->group,
- MRTF_SG, DONT_CREATE);
- if(mrtentry_ptr == (mrtentry_t *)NULL)
- return;
-
- if(mrtentry_ptr->prune_delay_timerids[cbk->mifi])
- timer_clearTimer(mrtentry_ptr->prune_delay_timerids[cbk->mifi]);
-
- if(IF_ISSET(cbk->mifi, &mrtentry_ptr->oifs)) {
- IF_DEBUG(DEBUG_PIM_JOIN_PRUNE)
- log(LOG_DEBUG, 0,
- "Deleting pruned mif %d for src %s, grp %s",
- cbk->mifi,
- inet6_fmt(&cbk->source.sin6_addr),
- inet6_fmt(&cbk->group.sin6_addr));
-
- IF_COPY(&mrtentry_ptr->pruned_oifs, &new_pruned_oifs);
- IF_SET(cbk->mifi, &new_pruned_oifs);
- SET_TIMER(mrtentry_ptr->prune_timers[cbk->mifi], cbk->holdtime);
-
- state_change =
- change_interfaces(mrtentry_ptr,
- mrtentry_ptr->incoming,
- &new_pruned_oifs,
- &mrtentry_ptr->leaves,
- &mrtentry_ptr->asserted_oifs);
-
- /* Handle transition to negative cache */
- if(state_change == -1)
- trigger_prune_alert(mrtentry_ptr);
- }
-
- free(cbk);
-}
-
-static void
-schedule_delayed_prune(mrtentry_ptr, mifi, holdtime)
- mrtentry_t *mrtentry_ptr;
- mifi_t mifi;
- u_int16 holdtime;
-{
- prune_delay_cbk_t *cbk;
-
- /* Delete existing timer */
- if(mrtentry_ptr->prune_delay_timerids[mifi])
- timer_clearTimer(mrtentry_ptr->prune_delay_timerids[mifi]);
-
- cbk = (prune_delay_cbk_t *)malloc(sizeof(prune_delay_cbk_t));
- cbk->mifi = mifi;
- cbk->source = mrtentry_ptr->source->address;
- cbk->group = mrtentry_ptr->group->group;
- cbk->holdtime = holdtime;
-
- mrtentry_ptr->prune_delay_timerids[mifi] =
- timer_setTimer((u_int16)PIM_RANDOM_DELAY_JOIN_TIMEOUT,
- delayed_prune_job, cbk);
-}
-
-
-/* TODO: when parsing, check if we go beyong message size */
-int
-receive_pim6_join_prune(src, pim_message, datalen)
- struct sockaddr_in6 *src;
- char *pim_message;
- register int datalen;
-{
- mifi_t mifi;
- struct uvif *v;
- pim6_encod_uni_addr_t uni_target_addr;
- pim6_encod_grp_addr_t encod_group;
- pim6_encod_src_addr_t encod_src;
- u_int8 *data_ptr;
- u_int8 num_groups;
- u_int16 holdtime;
- u_int16 num_j_srcs, num_p_srcs;
- struct sockaddr_in6 source, group, target;
- struct in6_addr s_mask, g_mask;
- u_int8 s_flags;
- u_int8 reserved;
- mrtentry_t *mrtentry_ptr;
- pim_nbr_entry_t *upstream_router;
- if_set new_pruned_oifs;
- int state_change;
-
- if ((mifi = find_vif_direct(src)) == NO_VIF) {
- /*
- * Either a local vif or somehow received PIM_JOIN_PRUNE from
- * non-directly connected router. Ignore it.
- */
- if (local_address(src) == NO_VIF)
- log(LOG_INFO, 0,
- "Ignoring PIM_JOIN_PRUNE from non-neighbor router %s",
- inet6_fmt(&src->sin6_addr));
- return(FALSE);
- }
-
- v = &uvifs[mifi];
- if (uvifs[mifi].uv_flags & (VIFF_DOWN | VIFF_DISABLED | VIFF_NONBRS))
- return(FALSE); /* Shoudn't come on this interface */
- data_ptr = (u_int8 *)(pim_message + sizeof(struct pim));
-
- /* Get the target address */
- GET_EUADDR6(&uni_target_addr, data_ptr);
- GET_BYTE(reserved, data_ptr);
- GET_BYTE(num_groups, data_ptr);
- if (num_groups == 0)
- return (FALSE); /* No indication for groups in the message */
- GET_HOSTSHORT(holdtime, data_ptr);
- target.sin6_len = sizeof(target);
- target.sin6_family = AF_INET6;
- target.sin6_addr = uni_target_addr.unicast_addr;
- target.sin6_scope_id = inet6_uvif2scopeid(&target, v);
-
- IF_DEBUG(DEBUG_PIM_JOIN_PRUNE)
- log(LOG_DEBUG, 0,
- "PIM Join/Prune received from %s : target %s, holdtime %d",
- inet6_fmt(&src->sin6_addr),
- inet6_fmt(&target.sin6_addr),
- holdtime);
-
- if (!inet6_localif_address(&target, v) &&
- !IN6_IS_ADDR_UNSPECIFIED(&uni_target_addr.unicast_addr)) {
- /* if I am not the target of the join or prune message */
- /*
- * Join Suppression: when receiving a join not addressed to me,
- * if I am delaying a join for this (S,G) then cancel the delayed
- * join.
- * Prune Soliticiting Joins: when receiving a prune not
- * addressed to me on a LAN, schedule delayed join if I have
- * downstream receivers.
- */
- upstream_router = find_pim6_nbr(&target);
- if (upstream_router == (pim_nbr_entry_t *)NULL)
- return (FALSE); /* I have no such neighbor */
- group.sin6_len = sizeof(group);
- group.sin6_family = AF_INET6;
- source.sin6_len = sizeof(source);
- source.sin6_family = AF_INET6;
- while (num_groups--) {
- GET_EGADDR6(&encod_group, data_ptr);
- GET_HOSTSHORT(num_j_srcs, data_ptr);
- GET_HOSTSHORT(num_p_srcs, data_ptr);
- if (encod_group.masklen > (sizeof(struct in6_addr) << 3))
- continue;
- MASKLEN_TO_MASK6(encod_group.masklen, g_mask);
- group.sin6_addr = encod_group.mcast_addr;
- group.sin6_scope_id = inet6_uvif2scopeid(&group, v);
- if (!IN6_IS_ADDR_MULTICAST(&group.sin6_addr)) {
- data_ptr +=
- (num_j_srcs + num_p_srcs) * sizeof(pim6_encod_src_addr_t);
- continue; /* Ignore this group and jump to the next */
- }
-
- while (num_j_srcs--) {
- GET_ESADDR6(&encod_src, data_ptr);
- source.sin6_addr = encod_src.src_addr;
- source.sin6_scope_id = inet6_uvif2scopeid(&source,
- v);
-
- /* sanity checks */
- if (!inet6_valid_host(&source))
- continue;
- if (encod_src.masklen >
- (sizeof(struct in6_addr) << 3))
- continue;
-
- s_flags = encod_src.flags;
- MASKLEN_TO_MASK6(encod_src.masklen, s_mask);
-
- /* (S,G) Join suppresion */
- mrtentry_ptr = find_route(&source, &group,
- MRTF_SG, DONT_CREATE);
- if(mrtentry_ptr == (mrtentry_t *)NULL)
- continue;
-
- IF_DEBUG(DEBUG_PIM_JOIN_PRUNE)
- log(LOG_DEBUG, 0,
- "\tJOIN src %s, group %s - canceling "
- "delayed join",
- inet6_fmt(&source.sin6_addr),
- inet6_fmt(&group.sin6_addr));
-
- /* Cancel the delayed join */
- if(mrtentry_ptr->join_delay_timerid) {
- timer_clearTimer(mrtentry_ptr->join_delay_timerid);
- mrtentry_ptr->join_delay_timerid = 0;
- }
- }
-
- while (num_p_srcs--) {
- GET_ESADDR6(&encod_src, data_ptr);
- source.sin6_addr = encod_src.src_addr;
- source.sin6_scope_id = inet6_uvif2scopeid(&source,
- v);
- /* sanity checks */
- if (!inet6_valid_host(&source))
- continue;
- if (encod_src.masklen >
- (sizeof(struct in6_addr) << 3))
- continue;
-
- s_flags = encod_src.flags;
-
- /* if P2P link (not addressed to me) ignore
- */
- if(uvifs[mifi].uv_flags & VIFF_POINT_TO_POINT)
- continue;
-
- /*
- * if non-null oiflist then schedule delayed join.
- */
- mrtentry_ptr = find_route(&source, &group,
- MRTF_SG, DONT_CREATE);
- if(mrtentry_ptr == (mrtentry_t *)NULL)
- continue;
-
- if(!(IF_ISEMPTY(&mrtentry_ptr->oifs))) {
- IF_DEBUG(DEBUG_PIM_JOIN_PRUNE)
- log(LOG_DEBUG, 0,
- "\tPRUNE src %s, group %s "
- "- scheduling delayed join",
- inet6_fmt(&source.sin6_addr),
- inet6_fmt(&group.sin6_addr));
-
- schedule_delayed_join(mrtentry_ptr,
- &target);
- }
- }
-
- } /* while groups */
-
- return(TRUE);
- } /* if not unicast target */
-
- /* I am the target of this join/prune:
- * For joins, cancel delayed prunes that I have scheduled.
- * For prunes, echo the prune and schedule delayed prunes on LAN or
- * prune immediately on point-to-point links.
- */
- else {
- while (num_groups--) {
- GET_EGADDR6(&encod_group, data_ptr);
- GET_HOSTSHORT(num_j_srcs, data_ptr);
- GET_HOSTSHORT(num_p_srcs, data_ptr);
- IF_DEBUG(DEBUG_PIM_JOIN_PRUNE)
- log(LOG_DEBUG, 0,
- "PIM Join/Prune received: grp: %s plen: %d, "
- "%d jsrc, %d psrc",
- inet6_fmt(&encod_group.mcast_addr),
- encod_group.masklen, num_j_srcs, num_p_srcs);
- if (encod_group.masklen > (sizeof(struct in6_addr) << 3))
- continue; /* Ignore this group */
- MASKLEN_TO_MASK6(encod_group.masklen, g_mask);
- group.sin6_addr = encod_group.mcast_addr;
- group.sin6_scope_id = inet6_uvif2scopeid(&group, v);
- if (!IN6_IS_ADDR_MULTICAST(&group.sin6_addr)) {
- data_ptr +=
- (num_j_srcs + num_p_srcs) * sizeof(pim6_encod_src_addr_t);
- continue; /* Ignore this group and jump to the next */
- }
-
- while (num_j_srcs--) {
- GET_ESADDR6(&encod_src, data_ptr);
- source.sin6_addr = encod_src.src_addr;
- source.sin6_scope_id = inet6_uvif2scopeid(&source,
- v);
- if (!inet6_valid_host(&source))
- continue;
- if (encod_src.masklen >
- (sizeof(struct in6_addr) << 3))
- continue;
-
- s_flags = encod_src.flags;
- MASKLEN_TO_MASK6(encod_src.masklen, s_mask);
-
- mrtentry_ptr = find_route(&source, &group,
- MRTF_SG, DONT_CREATE);
- if(mrtentry_ptr == (mrtentry_t *)NULL)
- continue;
-
- IF_DEBUG(DEBUG_PIM_JOIN_PRUNE)
- log(LOG_DEBUG, 0,
- "\tJOIN src %s, group %s - canceling "
- "delayed prune",
- inet6_fmt(&source.sin6_addr),
- inet6_fmt(&group.sin6_addr));
-
- /* Cancel the delayed prune */
- if(mrtentry_ptr->prune_delay_timerids[mifi]) {
- timer_clearTimer(mrtentry_ptr->prune_delay_timerids[mifi]);
- mrtentry_ptr->prune_delay_timerids[mifi] = 0;
- }
- }
-
- while (num_p_srcs--) {
- GET_ESADDR6(&encod_src, data_ptr);
- source.sin6_addr = encod_src.src_addr;
- source.sin6_scope_id = inet6_uvif2scopeid(&source,
- v);
- if (!inet6_valid_host(&source))
- continue;
- s_flags = encod_src.flags;
-
-
- mrtentry_ptr = find_route(&source, &group,
- MRTF_SG, DONT_CREATE);
- if(mrtentry_ptr == (mrtentry_t *)NULL)
- continue;
-
- /* if P2P link (addressed to me) prune immediately
- */
- if(uvifs[mifi].uv_flags & VIFF_POINT_TO_POINT) {
- if(IF_ISSET(mifi, &mrtentry_ptr->oifs)) {
-
- IF_DEBUG(DEBUG_PIM_JOIN_PRUNE)
- log(LOG_DEBUG, 0,
- "\tPRUNE(P2P) src %s,"
- "group %s - pruning "
- "mif",
- inet6_fmt(&source.sin6_addr),
- inet6_fmt(&group.sin6_addr));
-
- IF_DEBUG(DEBUG_MRT)
- log(LOG_DEBUG, 0, "Deleting pruned mif %d for src %s, grp %s",
- mifi,
- inet6_fmt(&source.sin6_addr),
- inet6_fmt(&group.sin6_addr));
-
- IF_COPY(&mrtentry_ptr->pruned_oifs, &new_pruned_oifs);
- IF_SET(mifi, &new_pruned_oifs);
- SET_TIMER(mrtentry_ptr->prune_timers[mifi], holdtime);
-
- state_change =
- change_interfaces(mrtentry_ptr,
- mrtentry_ptr->incoming,
- &new_pruned_oifs,
- &mrtentry_ptr->leaves,
- &mrtentry_ptr->asserted_oifs);
-
- /* Handle transition to negative cache */
- if(state_change == -1)
- trigger_prune_alert(mrtentry_ptr);
- } /* if is pruned */
- } /* if p2p */
-
- /* if LAN link, echo the prune and schedule delayed
- * oif deletion
- */
- else {
- IF_DEBUG(DEBUG_PIM_JOIN_PRUNE)
- log(LOG_DEBUG, 0,
- "\tPRUNE(LAN) src %s, group "
- "%s - scheduling delayed prune",
- inet6_fmt(&source.sin6_addr),
- inet6_fmt(&group.sin6_addr));
-
- send_pim6_jp(mrtentry_ptr,
- PIM_ACTION_PRUNE, mifi,
- &target, holdtime, 1);
- schedule_delayed_prune(mrtentry_ptr,
- mifi, holdtime);
- }
- }
- } /* while groups */
- } /* else I am unicast target */
-
- return(TRUE);
-}
-
-
-int
-send_pim6_jp(mrtentry_ptr, action, mifi, target_addr, holdtime, echo)
- mrtentry_t *mrtentry_ptr;
- int action; /* PIM_ACTION_JOIN or PIM_ACTION_PRUNE */
- mifi_t mifi; /* vif to send join/prune on */
- struct sockaddr_in6 *target_addr; /* encoded unicast target neighbor */
- u_int16 holdtime; /* holdtime */
- int echo;
-{
- u_int8 *data_ptr, *data_start_ptr;
-
- data_ptr = (u_int8 *)(pim6_send_buf + sizeof(struct pim));
- data_start_ptr = data_ptr;
-
- if(echo == 0 && mrtentry_ptr->upstream == (pim_nbr_entry_t *)NULL) {
- /* No upstream neighbor - don't send */
- return(FALSE);
- }
-
- IF_DEBUG(DEBUG_PIM_JOIN_PRUNE)
- log(LOG_DEBUG, 0,
- "Sending %s: vif %s, src %s, group %s, "
- "target %s, holdtime %d",
- action==PIM_ACTION_JOIN ? "JOIN" : "PRUNE",
- inet6_fmt(&uvifs[mifi].uv_linklocal->pa_addr.sin6_addr),
- inet6_fmt(&mrtentry_ptr->source->address.sin6_addr),
- inet6_fmt(&mrtentry_ptr->group->group.sin6_addr),
- inet6_fmt(&target_addr->sin6_addr), holdtime);
-
- PUT_EUADDR6(target_addr->sin6_addr, data_ptr); /* encoded unicast target addr */
- PUT_BYTE(0, data_ptr); /* Reserved */
- *data_ptr++ = (u_int8)1; /* number of groups */
- PUT_HOSTSHORT(holdtime, data_ptr); /* holdtime */
-
- /* data_ptr points at the first, and only encoded mcast group */
- PUT_EGADDR6(mrtentry_ptr->group->group.sin6_addr,
- SINGLE_GRP_MSK6LEN, 0, data_ptr);
-
- /* set the number of join and prune sources */
- if(action == PIM_ACTION_JOIN) {
- PUT_HOSTSHORT(1, data_ptr);
- PUT_HOSTSHORT(0, data_ptr);
- } else if(action == PIM_ACTION_PRUNE) {
- PUT_HOSTSHORT(0, data_ptr);
- PUT_HOSTSHORT(1, data_ptr);
- }
-
- PUT_ESADDR6(mrtentry_ptr->source->address.sin6_addr, SINGLE_SRC_MSK6LEN,
- 0, data_ptr);
-
- /* Cancel active graft */
- if (echo == 0)
- delete_pim6_graft_entry(mrtentry_ptr);
-
- send_pim6(pim6_send_buf, &uvifs[mifi].uv_linklocal->pa_addr,
- &allpim6routers_group, PIM_JOIN_PRUNE,
- data_ptr - data_start_ptr);
-
- return(TRUE);
-}
-
-
-/************************************************************************
- * PIM_ASSERT
- ************************************************************************/
-
-/* Notes on assert prefs/metrics
- * - For downstream routers, compare pref/metric previously received from
- * winner against those in message.
- * ==> store assert winner's pref/metric in mrtentry
- * - For upstream router compare my actualy pref/metric for the source
- * against those received in message.
- * ==> store my actual pref/metric in srcentry
- */
-
-int
-receive_pim6_assert(src, pim_message, datalen)
- struct sockaddr_in6 *src;
- register char *pim_message;
- int datalen;
-{
- mifi_t mifi;
- pim6_encod_uni_addr_t eusaddr;
- pim6_encod_grp_addr_t egaddr;
- struct sockaddr_in6 source, group;
- mrtentry_t *mrtentry_ptr;
- u_int8 *data_ptr;
- struct uvif *v;
- u_int32 assert_preference;
- u_int32 assert_metric;
- u_int32 local_metric;
- u_int32 local_preference;
- u_int8 local_wins;
- if_set new_pruned_oifs, new_leaves;
- int state_change;
-
- if ((mifi = find_vif_direct(src)) == NO_VIF) {
- /* Either a local vif or somehow received PIM_ASSERT from
- * non-directly connected router. Ignore it.
- */
- if (local_address(src) == NO_VIF)
- log(LOG_INFO, 0,
- "Ignoring PIM_ASSERT from non-neighbor router %s",
- inet6_fmt(&src->sin6_addr));
- return(FALSE);
- }
-
- v = &uvifs[mifi];
- if (uvifs[mifi].uv_flags & (VIFF_DOWN | VIFF_DISABLED | VIFF_NONBRS))
- return(FALSE); /* Shoudn't come on this interface */
- data_ptr = (u_int8 *)(pim_message + sizeof(struct pim));
-
- /* Get the group and source addresses */
- GET_EGADDR6(&egaddr, data_ptr);
- GET_EUADDR6(&eusaddr, data_ptr);
-
- /* Get the metric related info */
- GET_HOSTLONG(assert_preference, data_ptr);
- GET_HOSTLONG(assert_metric, data_ptr);
-
- source.sin6_addr = eusaddr.unicast_addr;
- source.sin6_scope_id = inet6_uvif2scopeid(&source, v);
- group.sin6_addr = egaddr.mcast_addr;
- group.sin6_scope_id = inet6_uvif2scopeid(&group, v);
-
- IF_DEBUG(DEBUG_PIM_ASSERT)
- log(LOG_DEBUG, 0,
- "PIM Assert received from %s: src %s, grp %s, "
- "pref %d, metric %d",
- inet6_fmt(&src->sin6_addr),
- inet6_fmt(&source.sin6_addr),
- inet6_fmt(&group.sin6_addr),
- assert_preference, assert_metric);
-
- if ((mrtentry_ptr = find_route(&source, &group, MRTF_SG, CREATE))
- == NULL) {
- IF_DEBUG(DEBUG_PIM_ASSERT)
- log(LOG_INFO, 0,
- "\tFailed to create a mrtentry src:%s grp:%s",
- inet6_fmt(&source.sin6_addr),
- inet6_fmt(&group.sin6_addr));
- return(FALSE);
- }
- if(mrtentry_ptr->flags & MRTF_NEW) {
- /* For some reason, it's possible for asserts to be processed
- * before the data alerts a cache miss. Therefore, when an
- * assert is received, create (S,G) state and continue, since
- * we know by the assert that there are upstream forwarders.
- */
- IF_DEBUG(DEBUG_PIM_ASSERT)
- log(LOG_DEBUG, 0, "\tNo MRT entry - creating...");
-
- mrtentry_ptr->flags &= ~MRTF_NEW;
-
- /* Set oifs */
- set_leaves(mrtentry_ptr);
- calc_oifs(mrtentry_ptr, &(mrtentry_ptr->oifs));
-
- /* Add it to the kernel */
- k_chg_mfc(mld6_socket, &source, &group, mrtentry_ptr->incoming,
- &mrtentry_ptr->oifs);
-
-#ifdef RSRR
- rsrr_cache_send(mrtentry_ptr, RSRR_NOTIFICATION_OK);
-#endif /* RSRR */
-
- /* No need to call change_interfaces, but check for NULL oiflist */
- if(IF_ISEMPTY(&mrtentry_ptr->oifs))
- trigger_prune_alert(mrtentry_ptr);
- }
-
- /* If arrived on iif, I'm downstream of the asserted LAN.
- * If arrived on oif, I'm upstream of the asserted LAN.
- */
- if (mifi == mrtentry_ptr->incoming) {
- /* assert arrived on iif ==> I'm a downstream router */
-
- /* Determine local (really that of upstream nbr!) pref/metric */
- local_metric = mrtentry_ptr->metric;
- local_preference = mrtentry_ptr->preference;
-
- if(mrtentry_ptr->upstream &&
- inet6_equal(&mrtentry_ptr->upstream->address, src) &&
- assert_preference == local_preference &&
- assert_metric == local_metric)
-
- /* if assert from previous winner w/ same pref/metric,
- * then assert sender wins again */
- local_wins = FALSE;
-
- else
- /* assert from someone else or something changed */
- local_wins = compare_metrics(local_preference,
- local_metric,
- &mrtentry_ptr->upstream->address,
- assert_preference,
- assert_metric, src);
-
- /*
- * This is between the assert sender and previous winner or rpf
- * (who is the "local" in this case).
- */
- if(local_wins == TRUE) {
- /* the assert-sender loses, so discard the assert */
- IF_DEBUG(DEBUG_PIM_ASSERT)
- log(LOG_DEBUG, 0,
- "\tAssert sender %s loses",
- inet6_fmt(&src->sin6_addr));
- return(TRUE);
- }
-
- /* The assert sender wins: upstream must be changed to the winner */
- IF_DEBUG(DEBUG_PIM_ASSERT)
- log(LOG_DEBUG, 0, "\tAssert sender %s wins",
- inet6_fmt(&src->sin6_addr));
- if(inet6_equal(&mrtentry_ptr->upstream->address, src)) {
- IF_DEBUG(DEBUG_PIM_ASSERT)
- log(LOG_DEBUG, 0,
- "\tChanging upstream nbr to %s",
- inet6_fmt(&src->sin6_addr));
- mrtentry_ptr->preference = assert_preference;
- mrtentry_ptr->metric = assert_metric;
- mrtentry_ptr->upstream = find_pim6_nbr(src);
- }
- SET_TIMER(mrtentry_ptr->assert_timer, PIM_ASSERT_TIMEOUT);
- mrtentry_ptr->flags |= MRTF_ASSERTED;
-
- /* Send a join for the S,G if oiflist is non-empty */
- if(!(IF_ISEMPTY(&mrtentry_ptr->oifs)))
- send_pim6_jp(mrtentry_ptr, PIM_ACTION_JOIN,
- mrtentry_ptr->incoming, src, 0, 0);
-
- } /* if assert on iif */
-
- /* If the assert arrived on an oif: */
- else {
- if(!(IF_ISSET(mifi, &mrtentry_ptr->oifs)))
- return(FALSE);
- /* assert arrived on oif ==> I'm a upstream router */
-
- /* Determine local pref/metric */
- local_metric = mrtentry_ptr->source->metric;
- local_preference = mrtentry_ptr->source->preference;
-
- local_wins = compare_metrics(local_preference, local_metric,
- &v->uv_linklocal->pa_addr,
- assert_preference,
- assert_metric, src);
-
- if(local_wins == FALSE) {
-
- /* Assert sender wins - prune the interface */
-
- IF_DEBUG(DEBUG_PIM_ASSERT)
- log(LOG_DEBUG, 0,
- "\tAssert sender %s wins - pruning...",
- inet6_fmt(&src->sin6_addr));
-
- IF_COPY(&mrtentry_ptr->pruned_oifs, &new_pruned_oifs);
- IF_SET(mifi, &new_pruned_oifs);
- IF_SET(mifi, &mrtentry_ptr->asserted_oifs);
- SET_TIMER(mrtentry_ptr->prune_timers[mifi],
- PIM_JOIN_PRUNE_HOLDTIME);
-
- if (IF_ISSET(mifi, &mrtentry_ptr->leaves)) {
- IF_COPY(&mrtentry_ptr->leaves, &new_leaves);
- IF_CLR(mifi, &new_leaves);
- state_change =
- change_interfaces(mrtentry_ptr,
- mrtentry_ptr->incoming,
- &new_pruned_oifs,
- &mrtentry_ptr->leaves,
- &new_leaves);
- }
- else {
- state_change =
- change_interfaces(mrtentry_ptr,
- mrtentry_ptr->incoming,
- &new_pruned_oifs,
- &mrtentry_ptr->leaves,
- &mrtentry_ptr->asserted_oifs);
- }
-
- /* Handle transition to negative cache */
- if(state_change == -1)
- trigger_prune_alert(mrtentry_ptr);
-
- } /* assert sender wins */
-
- else {
-
- /* Local wins (assert sender loses):
- * send assert and schedule prune
- */
-
- IF_DEBUG(DEBUG_PIM_ASSERT)
- log(LOG_DEBUG, 0,
- "\tAssert sender %s loses - "
- "sending assert and scheuling prune",
- inet6_fmt(&src->sin6_addr));
-
- if(!(IF_ISSET(mifi, &mrtentry_ptr->leaves))) {
- /*
- * No directly connected receivers - delay prune
- */
- send_pim6_jp(mrtentry_ptr, PIM_ACTION_PRUNE,
- mifi, &v->uv_linklocal->pa_addr,
- PIM_JOIN_PRUNE_HOLDTIME, 0);
- schedule_delayed_prune(mrtentry_ptr, mifi,
- PIM_JOIN_PRUNE_HOLDTIME);
- }
- send_pim6_assert(&source, &group, mifi, mrtentry_ptr);
- }
-
- } /* if assert on oif */
-
- return(TRUE);
-}
-
-
-int
-send_pim6_assert(source, group, mifi, mrtentry_ptr)
- struct sockaddr_in6 *source;
- struct sockaddr_in6 *group;
- mifi_t mifi;
- mrtentry_t *mrtentry_ptr;
-{
- u_int8 *data_ptr;
- u_int8 *data_start_ptr;
- u_int32 local_preference;
- u_int32 local_metric;
-
- data_ptr = (u_int8 *)(pim6_send_buf + sizeof(struct pim));
- data_start_ptr = data_ptr;
- PUT_EGADDR6(group->sin6_addr, SINGLE_GRP_MSK6LEN, 0, data_ptr);
- PUT_EUADDR6(source->sin6_addr, data_ptr);
-
- local_metric = mrtentry_ptr->source->metric;
- local_preference = mrtentry_ptr->source->preference;
-
- PUT_HOSTLONG(local_preference, data_ptr);
- PUT_HOSTLONG(local_metric, data_ptr);
-
- IF_DEBUG(DEBUG_PIM_ASSERT)
- log(LOG_DEBUG, 0,
- "PIM Assert sending: src %s, grp %s, "
- "pref %d, metric %d",
- inet6_fmt(&source->sin6_addr),
- inet6_fmt(&group->sin6_addr),
- local_metric, local_preference);
-
- send_pim6(pim6_send_buf, &uvifs[mifi].uv_linklocal->pa_addr,
- &allpim6routers_group, PIM_ASSERT,
- data_ptr - data_start_ptr);
-
- return(TRUE);
-}
-
-
-/* Return TRUE if the local win, otherwise FALSE */
-static int
-compare_metrics(local_preference, local_metric, local_address,
- remote_preference, remote_metric, remote_address)
- u_int32 local_preference;
- u_int32 local_metric;
- struct sockaddr_in6 *local_address;
- u_int32 remote_preference;
- u_int32 remote_metric;
- struct sockaddr_in6 *remote_address;
-{
- /* Now lets see who has a smaller gun (aka "asserts war") */
- /* FYI, the smaller gun...err metric wins, but if the same
- * caliber, then the bigger network address wins. The order of
- * treatment is: preference, metric, address.
- */
- /* The RPT bits are already included as the most significant bits
- * of the preferences.
- */
- if (remote_preference > local_preference)
- return TRUE;
- if (remote_preference < local_preference)
- return FALSE;
- if (remote_metric > local_metric)
- return TRUE;
- if (remote_metric < local_metric)
- return FALSE;
- if (inet6_greaterthan(local_address, remote_address))
- return TRUE;
- return FALSE;
-}
-
-
-
-
-/************************************************************************
- * PIM_GRAFT
- ************************************************************************/
-
-
-u_long graft_retrans_timer; /* Graft retransmission timer */
-pim_graft_entry_t *graft_list; /* Active grafting entries */
-
-
-void
-delete_pim6_graft_entry(mrtentry_ptr)
- mrtentry_t *mrtentry_ptr;
-{
- pim_graft_entry_t *graft_entry;
-
- if(mrtentry_ptr->graft == (pim_graft_entry_t *)NULL)
- return;
- graft_entry = mrtentry_ptr->graft;
-
- if(graft_entry->prev)
- graft_entry->prev->next = graft_entry->next;
- else
- graft_list = graft_entry->next;
- if(graft_entry->next)
- graft_entry->next->prev = graft_entry->prev;
- mrtentry_ptr->graft = (pim_graft_entry_t *)NULL;
- free(graft_entry);
-
- /* Stop the timer if there are no more entries */
- if(!graft_list) {
- timer_clearTimer(graft_retrans_timer);
- graft_retrans_timer = 0;
- }
-}
-
-
-static int
-retransmit_pim6_graft(mrtentry_ptr)
- mrtentry_t *mrtentry_ptr;
-{
- u_int8 *data_ptr, *data_start_ptr;
-
- data_ptr = (u_int8 *)(pim6_send_buf + sizeof(struct pim));
- data_start_ptr = data_ptr;
-
- if (mrtentry_ptr->upstream == (pim_nbr_entry_t *)NULL) {
- /* No upstream neighbor - don't send */
- return(FALSE);
- }
-
- IF_DEBUG(DEBUG_PIM_GRAFT)
- log(LOG_DEBUG, 0,
- "Sending GRAFT: vif %s, src %s, grp %s, dst %s",
- inet6_fmt(&uvifs[mrtentry_ptr->incoming].uv_linklocal->pa_addr.sin6_addr),
- inet6_fmt(&mrtentry_ptr->source->address.sin6_addr),
- inet6_fmt(&mrtentry_ptr->group->group.sin6_addr),
- inet6_fmt(&mrtentry_ptr->upstream->address.sin6_addr));
-
-
- /* unicast target */
- PUT_EUADDR6(mrtentry_ptr->upstream->address.sin6_addr, data_ptr);
- PUT_BYTE(0, data_ptr); /* Reserved */
- *data_ptr++ = (u_int8)1; /* number of groups */
- PUT_HOSTSHORT(0, data_ptr); /* no holdtime */
-
- /* data_ptr points at the first, and only encoded mcast group */
- PUT_EGADDR6(mrtentry_ptr->group->group.sin6_addr,
- SINGLE_GRP_MSK6LEN, 0, data_ptr);
-
- /* set the number of join(graft) and prune sources */
- PUT_HOSTSHORT(1, data_ptr);
- PUT_HOSTSHORT(0, data_ptr);
-
- PUT_ESADDR6(mrtentry_ptr->source->address.sin6_addr, SINGLE_SRC_MSK6LEN,
- 0, data_ptr);
-
- send_pim6(pim6_send_buf,
- &uvifs[mrtentry_ptr->incoming].uv_linklocal->pa_addr,
- &mrtentry_ptr->upstream->address,
- PIM_GRAFT, data_ptr - data_start_ptr);
-
- return(TRUE);
-}
-
-
-static void
-retransmit_all_pim6_grafts(arg)
- void *arg; /* UNUSED */
-{
- pim_graft_entry_t *graft_ptr;
-
- IF_DEBUG(DEBUG_PIM_GRAFT)
- log(LOG_DEBUG, 0, "Retransmitting all pending PIM-Grafts");
-
-
- for(graft_ptr = graft_list;
- graft_ptr != NULL;
- graft_ptr = graft_ptr->next) {
-
- IF_DEBUG(DEBUG_PIM_GRAFT)
- log(LOG_DEBUG, 0, "\tGRAFT src %s, grp %s",
- inet6_fmt(&graft_ptr->mrtlink->source->address.sin6_addr),
- inet6_fmt(&graft_ptr->mrtlink->group->group.sin6_addr));
-
- retransmit_pim6_graft(graft_ptr->mrtlink);
- }
-
- if (graft_list)
- timer_setTimer(PIM_GRAFT_RETRANS_PERIOD,
- retransmit_all_pim6_grafts, (void *)NULL);
-}
-
-
-int
-receive_pim6_graft(src, pim_message, datalen, pimtype)
- struct sockaddr_in6 *src;
- register char *pim_message;
- int datalen;
- int pimtype;
-{
- mifi_t mifi;
- struct uvif *v;
- pim6_encod_uni_addr_t uni_target_addr;
- pim6_encod_grp_addr_t encod_group;
- pim6_encod_src_addr_t encod_src;
- u_int8 *data_ptr;
- u_int8 num_groups;
- u_int16 holdtime;
- u_int16 num_j_srcs;
- u_int16 num_p_srcs;
- struct sockaddr_in6 source, group;
- struct in6_addr s_mask, g_mask;
- u_int8 s_flags;
- u_int8 reserved;
- mrtentry_t *mrtentry_ptr;
- int state_change;
-
- if ((mifi = find_vif_direct(src)) == NO_VIF) {
- /* Either a local vif or somehow received PIM_GRAFT from
- * non-directly connected router. Ignore it.
- */
- if (local_address(src) == NO_VIF)
- log(LOG_INFO, 0,
- "Ignoring PIM_GRAFT from non-neighbor router %s",
- inet6_fmt(&src->sin6_addr));
- return(FALSE);
- }
-
- v = &uvifs[mifi];
- if (uvifs[mifi].uv_flags & (VIFF_DOWN | VIFF_DISABLED | VIFF_NONBRS))
- return(FALSE); /* Shoudn't come on this interface */
- data_ptr = (u_int8 *)(pim_message + sizeof(struct pim));
-
- /* Get the target address */
- GET_EUADDR6(&uni_target_addr, data_ptr);
- GET_BYTE(reserved, data_ptr);
- GET_BYTE(num_groups, data_ptr);
- if (num_groups == 0)
- return (FALSE); /* No indication for groups in the message */
- GET_HOSTSHORT(holdtime, data_ptr);
-
- IF_DEBUG(DEBUG_PIM_GRAFT)
- log(LOG_DEBUG, 0,
- "PIM %s received from %s on mif %d, grps: %d",
- pimtype == PIM_GRAFT ? "GRAFT" : "GRAFT-ACK",
- inet6_fmt(&src->sin6_addr), mifi, num_groups);
-
- group.sin6_len = sizeof(group);
- group.sin6_family = AF_INET6;
- source.sin6_len = sizeof(source);
- source.sin6_family = AF_INET6;
- while (num_groups--) {
- GET_EGADDR6(&encod_group, data_ptr);
- GET_HOSTSHORT(num_j_srcs, data_ptr);
- GET_HOSTSHORT(num_p_srcs, data_ptr);
- IF_DEBUG(DEBUG_PIM_GRAFT)
- log(LOG_DEBUG, 0,
- " PIM graft: grp: %s, plen: %d, %d jsrcs, %d psrcs",
- inet6_fmt(&encod_group.mcast_addr),
- encod_group.masklen, num_j_srcs, num_p_srcs);
- if (encod_group.masklen > (sizeof(struct in6_addr) << 3))
- continue;
- MASKLEN_TO_MASK6(encod_group.masklen, g_mask);
- group.sin6_addr = encod_group.mcast_addr;
- group.sin6_scope_id = inet6_uvif2scopeid(&group, v);
- if (!IN6_IS_ADDR_MULTICAST(&group.sin6_addr)) {
- data_ptr +=
- (num_j_srcs + num_p_srcs) * sizeof(pim6_encod_src_addr_t);
- continue; /* Ignore this group and jump to the next */
- }
-
- while (num_j_srcs--) {
- GET_ESADDR6(&encod_src, data_ptr);
- if (encod_src.masklen > (sizeof(struct in6_addr) << 3))
- continue;
- source.sin6_addr = encod_src.src_addr;
- source.sin6_scope_id = inet6_uvif2scopeid(&source, v);
- if (!inet6_valid_host(&source))
- continue;
- s_flags = encod_src.flags;
- MASKLEN_TO_MASK6(encod_src.masklen, s_mask);
-
- mrtentry_ptr = find_route(&source, &group, MRTF_SG,
- DONT_CREATE);
- if(mrtentry_ptr == (mrtentry_t *)NULL)
- continue;
-
- if(pimtype == PIM_GRAFT) {
- /* Graft */
- IF_DEBUG(DEBUG_PIM_GRAFT)
- log(LOG_DEBUG, 0,
- "\tGRAFT src %s, group %s - "
- "forward data on mif %d",
- inet6_fmt(&source.sin6_addr),
- inet6_fmt(&group.sin6_addr),
- mifi);
-
- /* Cancel any delayed prune */
- if(mrtentry_ptr->prune_delay_timerids[mifi]) {
- timer_clearTimer(mrtentry_ptr->prune_delay_timerids[mifi]);
- mrtentry_ptr->prune_delay_timerids[mifi] = 0;
- }
-
- /* Add to oiflist (unprune) */
- if (IF_ISSET(mifi, &mrtentry_ptr->pruned_oifs)) {
- IF_CLR(mifi, &mrtentry_ptr->pruned_oifs);
- IF_CLR(mifi, &mrtentry_ptr->asserted_oifs);
- SET_TIMER(mrtentry_ptr->prune_timers[mifi], 0);
- state_change =
- change_interfaces(mrtentry_ptr,
- mrtentry_ptr->incoming,
- &mrtentry_ptr->pruned_oifs,
- &mrtentry_ptr->leaves,
- &mrtentry_ptr->asserted_oifs);
- if(state_change == 1)
- trigger_join_alert(mrtentry_ptr);
- }
- } /* Graft */
- else {
- /* Graft-Ack */
- IF_DEBUG(DEBUG_PIM_GRAFT)
- log(LOG_DEBUG, 0,
- "\tGRAFT-ACK src %s, group %s - "
- "forward data on mif %d",
- inet6_fmt(&source.sin6_addr),
- inet6_fmt(&group.sin6_addr),
- mifi);
- if(mrtentry_ptr->graft)
- delete_pim6_graft_entry(mrtentry_ptr);
- }
- }
- /* Ignore anything in the prune portion of the message! */
- }
-
- /* Respond to graft with a graft-ack */
- if(pimtype == PIM_GRAFT) {
- IF_DEBUG(DEBUG_PIM_GRAFT)
- log(LOG_DEBUG, 0, "Sending GRAFT-ACK: mif %s, dst %s",
- inet6_fmt(&uvifs[mifi].uv_linklocal->pa_addr.sin6_addr),
- inet6_fmt(&src->sin6_addr));
- bcopy(pim_message, pim6_send_buf, datalen);
- send_pim6(pim6_send_buf, &uvifs[mifi].uv_linklocal->pa_addr,
- src, PIM_GRAFT_ACK, datalen - sizeof(struct pim));
- }
-
- return(TRUE);
-}
-
-int
-send_pim6_graft(mrtentry_ptr)
- mrtentry_t *mrtentry_ptr;
-{
- pim_graft_entry_t *new_graft;
- int was_sent = 0;
-
- if(mrtentry_ptr->graft != (pim_graft_entry_t *)NULL)
- /* Already sending grafts */
- return(FALSE);
-
- /* Send the first graft */
- was_sent = retransmit_pim6_graft(mrtentry_ptr);
- if(!was_sent)
- return(FALSE);
-
- /* Set up retransmission */
- new_graft = (pim_graft_entry_t *)malloc(sizeof(pim_graft_entry_t));
- if (new_graft == (pim_graft_entry_t *)NULL) {
- log(LOG_WARNING, 0,
- "Memory allocation error for graft entry src %s, grp %s",
- inet6_fmt(&mrtentry_ptr->source->address.sin6_addr),
- inet6_fmt(&mrtentry_ptr->group->group.sin6_addr));
- return(FALSE);
- }
- new_graft->next = graft_list;
- new_graft->prev = (pim_graft_entry_t *)NULL;
- new_graft->mrtlink = mrtentry_ptr;
- if(graft_list)
- graft_list->prev = new_graft;
- graft_list = new_graft;
- mrtentry_ptr->graft = new_graft;
-
- /* Set up timer if not running */
- if(!graft_retrans_timer)
- graft_retrans_timer = timer_setTimer(PIM_GRAFT_RETRANS_PERIOD,
- retransmit_all_pim6_grafts,
- (void *)NULL);
-
- return(TRUE);
-}
diff --git a/usr.sbin/pim6dd/pim6dd.8 b/usr.sbin/pim6dd/pim6dd.8
deleted file mode 100644
index c48b874..0000000
--- a/usr.sbin/pim6dd/pim6dd.8
+++ /dev/null
@@ -1,132 +0,0 @@
-.\" $KAME: pim6dd.8,v 1.6 2000/07/10 08:52:59 itojun Exp $
-.\"
-.\" Copyright (C) 1998 WIDE Project.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. Neither the name of the project nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD$
-.\"
-.Dd November 17, 1998
-.Dt PIM6DD 8
-.Os
-.Sh NAME
-.Nm pim6dd
-.Nd PIM for IPv6 dense mode daemon
-.Sh SYNOPSIS
-.Nm
-.Op Fl c Ar configfile
-.Oo
-.Fl d
-.Sm off
-.Op Ar debug_level Op , Ar ...
-.Sm on
-.Oc
-.Sh DESCRIPTION
-.Nm Pim6dd
-is an IPv6 multicast routing daemon, which supports
-PIMv2(Protocol Independent Multicast Version 2) dense mode
-for IPv6.
-.Pp
-Options supported by
-.Nm :
-.Bl -tag -width Ds
-.It Fl c Ar configfile
-Specify alternate location,
-.Ar configfile ,
-for configuration file.
-By default,
-.Pa /etc/pim6dd.conf
-is used.
-.It Fl d
-Specify debug levels. If this option is specified without any arguments,
-all debug messages will be printed out.
-A subset of the messages to be printed out can be specified
-as arguments of the option.
-Valid debug levels are
-.Ic timeout , packets , interfaces , kernel ,
-.Ic mfc , pim_detail , pim_hello , kernel ,
-.Ic mfc , pim_detail , pim_hello , pim_jp ,
-.Ic pim_graft , pim_asserts , pim_routes , pim_timers ,
-.Ic rpf , pim , routes , routers ,
-.Ic timers ,
-and
-.Ic asserts .
-.El
-.Pp
-.Nm Pim6dd
-automatically configures itself to forward on all multicast-capable
-interfaces, i.e., interfaces that have the IFF_MULTICAST flag set (excluding
-the "loopback interface").
-To override the default configuration,
-configuration commands may be placed in
-.Pa /etc/pim6dd.conf
-.Po
-or an alternative file, specified by the
-.Sq Fl c
-option
-.Pc .
-.\"
-.Sh FILES
-.Bl -tag -width /etc/pim6dd.conf -compact
-.It Pa /etc/pim6dd.conf
-The default configuration file.
-.El
-.Sh SEE ALSO
-.Xr daemon 3 ,
-.Xr pim6dd.conf 5
-.Sh HISTORY
-The
-.Nm
-command is based on
-.Nm pimdd ,
-which is an IPv4 multicast routing daemon
-developed at the University of Oregon.
-.Nm Pimdd
-has been derived from PIM sparse-mode
-.Nm pimd
-developed at University of Southern California.
-Part of these two programs above has also been derived from
-.Nm mrouted .
-.Nm Mrouted
-is COPYRIGHT 1989 by The Board of Trustees of
-Leland Stanford Junior University.
-.\"
-.Sh BUGS
-.Nm Pim6dd
-does not contain any unicast routing engine, so a unicast routing
-daemon needs to run on the system.
-.Pp
-The kernel unicast routing table is periodically polled by
-.Nm
-in order to follow changes of existing unicast routes.
-.Pp
-.Nm
-must be used on an IPv6 router.
-Be sure to set
-.Li net.inet6.ip6.forwarding
-variable to 1 with
-.Xr sysctl 8 .
-.\"
diff --git a/usr.sbin/pim6dd/pim6dd.conf.5 b/usr.sbin/pim6dd/pim6dd.conf.5
deleted file mode 100644
index c2a8706..0000000
--- a/usr.sbin/pim6dd/pim6dd.conf.5
+++ /dev/null
@@ -1,165 +0,0 @@
-.\" $KAME: pim6dd.conf.5,v 1.6 2000/07/10 08:52:59 itojun Exp $
-.\"
-.\" Copyright (C) 1998 WIDE Project.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. Neither the name of the project nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD$
-.\"
-.Dd November 17, 1998
-.Dt PIM6DD.CONF 5
-.Os
-.Sh NAME
-.Nm pim6dd.conf
-.Nd "config file for pim6dd, PIM for IPv6 dense mode daemon
-.\"
-.Sh DESCRIPTION
-The file describes how the
-.Xr pim6dd 8
-daemon treats each interface on the system.
-By default(including the case where there is no configuration file),
-PIM will be activated on all interfaces, which can be overridden
-by the file.
-Lines beginning with
-.Ql #
-are comments.
-.Pp
-The following configuration directives are availble:
-.Pp
-.Bl -tag -width Ds -compact
-.It Xo
-.Ic default_source_preference Ar preference
-.Xc
-Specifies a default preference value when sending a PIM assert message.
-Preferences are used by assert elections to determine upstream routers.
-Currently
-.Xr pim6dd 8
-does not have an effective method to obtain preferences and metrics from the
-unicast routing protocols, so you may want to set a default value by hand.
-.\"
-.It Ic default_source_metric Ar metric
-Specifies a default metric value when sending a PIM assert message.
-Since
-.Xr pim6dd 8
-cannot get an effective metric of unicast routing,
-it is recommended that preferences is set such that metrics are never
-consulted. However, default metrics may also be set, and
-its default value is 1024.
-.\"
-.It Xo
-.Ic phyint Ar interface
-.Op disable
-.Xc
-Specifies
-.Xr pim6dd 8
-to ignore the interface even if the interface is multicast-capable.
-Interfaces are specified in the form of "name unit", such as
-.Ar gif0
-and
-.Ar ep1 .
-.\"
-.It Xo
-.Ic phyint Ar interface
-.Op preference Ar preference
-.Op metric Ar metric
-.Xc
-Specifies the preference and/or metric values when sending a PIM
-assert message on the interface.
-.\"
-.It Xo
-.Ic filter Ar groupaddrs Ar interfaces...
-.Xc
-Specifies an output filter by defining an administrative scope.
-If an incoming multicast packet's destination
-matches the specified
-.Ar groupaddrs ,
-the packet is not sent on the
-.Ar interfaces .
-Moreover, if there is no other interface than the specified
-interfaces,
-.Xr pim6dd 8
-sends a prune message to the upstream neighbor.
-Valid formats of
-.Ar groupaddrs
-are as follows.
-.Bl -tag -width Ds -compact
-.It Ar multicastaddr1-multicastaddr2
-specifies a numerical range of a scope.
-Multicast addresses
-from
-.Ar multicastaddr1
-to
-.Ar multicastaddr2
-will be filtered out.
-Note that neither a white space nor a tab character must not be
-inserted before nor after
-.Ql - .
-.It Ar multicastaddr/prefixlen
-specifies a group prefix of a scope.
-Multicast addresses which match the specified prefix will be filtered
-out.
-If
-.Ar prefixlen
-is omitted, it means the exact match for
-.Ar multicastaddr .
-.El
-.Ar interfaces
-are specified as a blank separated list of interfaces. Each interface is
-specified in the form of "name unit".
-.El
-.\"
-.Sh EXAMPLES
-.Bd -literal -offset
-# phyint gif0 disable
-# phyint ep0 preference 101
-phyint de0 disable
-filter ff15::4000/120 gif1 gif2
-filter ff18::1000-ff18::1050 gif3
-.Ed
-.Sh SEE ALSO
-.Xr pim6dd 8
-.Sh HISTORY
-The
-.Xr pim6dd 8
-command and the configuration file
-.Nm
-are based on
-.Nm pimdd ,
-which is an IPv4 multicast routing daemon
-developed at the University of Oregon.
-.Nm pimdd
-has been derived from PIM sparse-mode
-.Nm pimd
-developed at University of Southern California.
-Part of these two programs above has also been derived from
-.Nm mrouted .
-.Nm mrouted
-is COPYRIGHT 1989 by The Board of Trustees of
-Leland Stanford Junior University.
-.Pp
-IPv6 and IPsec support based on the KAME Project (http://www.kame.net/) stack
-was initially integrated into
-.Fx 4.0
diff --git a/usr.sbin/pim6dd/pimdd.h b/usr.sbin/pim6dd/pimdd.h
deleted file mode 100644
index 73880f6..0000000
--- a/usr.sbin/pim6dd/pimdd.h
+++ /dev/null
@@ -1,553 +0,0 @@
-/*
- * Copyright (c) 1998 by the University of Oregon.
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation in source and binary forms for lawful
- * purposes and without fee is hereby granted, provided
- * that the above copyright notice appear in all copies and that both
- * the copyright notice and this permission notice appear in supporting
- * documentation, and that any documentation, advertising materials,
- * and other materials related to such distribution and use acknowledge
- * that the software was developed by the University of Oregon.
- * The name of the University of Oregon may not be used to endorse or
- * promote products derived from this software without specific prior
- * written permission.
- *
- * THE UNIVERSITY OF OREGON DOES NOT MAKE ANY REPRESENTATIONS
- * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. THIS SOFTWARE IS
- * PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
- * NON-INFRINGEMENT.
- *
- * IN NO EVENT SHALL UO, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT,
- * TORT, OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH,
- * THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Other copyrights might apply to parts of this software and are so
- * noted when applicable.
- */
-/*
- * Questions concerning this software should be directed to
- * Kurt Windisch (kurtw@antc.uoregon.edu)
- *
- * $Id: pimdd.h,v 1.1.1.1 1999/08/08 23:30:53 itojun Exp $
- */
-/*
- * Part of this program has been derived from PIM sparse-mode pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- * The pimd program is COPYRIGHT 1998 by University of Southern California.
- *
- * Part of this program has been derived from mrouted.
- * The mrouted program is covered by the license in the accompanying file
- * named "LICENSE.mrouted".
- *
- * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
- * Leland Stanford Junior University.
- *
- * $FreeBSD$
- */
-
-#include <netinet6/pim6.h>
-
-#define PIM_PROTOCOL_VERSION 2
-#define PIMD_VERSION PIM_PROTOCOL_VERSION
-#define PIMD_SUBVERSION 1
-#if 0
-#define PIM_CONSTANT 0x000eff00 /* constant portion of 'group' field */
-#endif
-#define PIM_CONSTANT 0
-#define PIMD_LEVEL (PIM_CONSTANT | PIMD_VERSION | (PIMD_SUBVERSION << 8))
-
-#define INADDR_ALL_PIM_ROUTERS (u_int32)0xe000000D /* 224.0.0.13 */
-
-
-/* PIM protocol timers (in seconds) */
-#ifndef TIMER_INTERVAL
-#define TIMER_INTERVAL 5 /* virtual timer granularity */
-#endif /* TIMER_INTERVAL */
-
-#define PIM_DATA_TIMEOUT 210
-#define PIM_TIMER_HELLO_PERIOD 30
-#define PIM_JOIN_PRUNE_HOLDTIME 210
-#define PIM_RANDOM_DELAY_JOIN_TIMEOUT 3
-#define PIM_GRAFT_RETRANS_PERIOD 3
-#define PIM_TIMER_HELLO_HOLDTIME (3.5 * PIM_TIMER_HELLO_PERIOD)
-#define PIM_ASSERT_TIMEOUT 210
-
-
-/* Misc definitions */
-#define SINGLE_SRC_MSKLEN 32 /* the single source mask length */
-#define SINGLE_GRP_MSKLEN 32 /* the single group mask length */
-
-#define SINGLE_SRC_MSK6LEN 128 /* the single source mask length for IPv6*/
-#define SINGLE_GRP_MSK6LEN 128 /* the single group mask length for IPv6*/
-
-/* TODO: change? */
-#define PIM_GROUP_PREFIX_DEFAULT_MASKLEN 16 /* The default group masklen if
- * omitted in the config file.
- */
-
-#define UCAST_ROUTING_CHECK_INTERVAL 20 /* Unfortunately, if the unicast
- * routing changes, the kernel
- * or any of the existing
- * unicast routing daemons
- * don't send us a signal.
- * Have to ask periodically the
- * kernel for any route changes.
- * Default: every 20 seconds.
- * Sigh.
- */
-
-
-#define DEFAULT_PHY_RATE_LIMIT 0 /* default phyint rate limit */
-
-#define DEFAULT_LOCAL_PREF 101 /* Default assert preference */
-#define DEFAULT_LOCAL_METRIC 1024 /* Default assert metric */
-
-/**************************************************************************
- * PIM Encoded-Unicast, Encoded-Group and Encoded-Source Address formats *
- *************************************************************************/
-/* Address families definition */
-#define ADDRF_RESERVED 0
-#define ADDRF_IPv4 1
-#define ADDRF_IPv6 2
-#define ADDRF_NSAP 3
-#define ADDRF_HDLC 4
-#define ADDRF_BBN1822 5
-#define ADDRF_802 6
-#define ADDRF_ETHERNET ADDRF_802
-#define ADDRF_E163 7
-#define ADDRF_E164 8
-#define ADDRF_SMDS ADDRF_E164
-#define ADDRF_ATM ADDRF_E164
-#define ADDRF_F69 9
-#define ADDRF_TELEX ADDRF_F69
-#define ADDRF_X121 10
-#define ADDRF_X25 ADDRF_X121
-#define ADDRF_IPX 11
-#define ADDRF_APPLETALK 12
-#define ADDRF_DECNET_IV 13
-#define ADDRF_BANYAN 14
-#define ADDRF_E164_NSAP 15
-
-/* Addresses Encoding Type (specific for each Address Family */
-#define ADDRT_IPv4 0
-#define ADDRT_IPv6 0
-
-
-#if 0 /* XXX: the definition is for IPv4 only */
-/* Encoded-Unicast: 6 bytes long */
-typedef struct pim_encod_uni_addr_ {
- u_int8 addr_family;
- u_int8 encod_type;
- u_int32 unicast_addr; /* XXX: Note the 32-bit boundary
- * misalignment for the unicast
- * address when placed in the
- * memory. Must read it byte-by-byte!
- */
-} pim_encod_uni_addr_t;
-#endif
-/* Encoded-Unicast: 18 bytes long */
-typedef struct pim6_encod_uni_addr_ {
- u_int8 addr_family;
- u_int8 encod_type;
- struct in6_addr unicast_addr; /* XXX: Note the 32-bit boundary
- * misalignment for the unicast
- * address when placed in the
- * memory. Must read it byte-by-byte!
- */
-} pim6_encod_uni_addr_t;
-
-#if 0 /* XXX: the definition is for IPv4 only */
-/* Encoded-Group */
-typedef struct pim_encod_grp_addr_ {
- u_int8 addr_family;
- u_int8 encod_type;
- u_int8 reserved;
- u_int8 masklen;
- u_int32 mcast_addr;
-} pim_encod_grp_addr_t;
-#endif
-/* Encoded-Group */
-typedef struct pim6_encod_grp_addr_ {
- u_int8 addr_family;
- u_int8 encod_type;
- u_int8 reserved;
- u_int8 masklen;
- struct in6_addr mcast_addr;
-} pim6_encod_grp_addr_t;
-
-#if 0 /* XXX: the definition is for IPv4 only */
-/* Encoded-Source */
-typedef struct pim_encod_src_addr_ {
- u_int8 addr_family;
- u_int8 encod_type;
- u_int8 flags;
- u_int8 masklen;
- u_int32 src_addr;
-} pim_encod_src_addr_t;
-#endif
-/* Encoded-Source */
-typedef struct pim6_encod_src_addr_ {
- u_int8 addr_family;
- u_int8 encod_type;
- u_int8 flags;
- u_int8 masklen;
- struct in6_addr src_addr;
-} pim6_encod_src_addr_t;
-#define USADDR_RP_BIT 0x1
-#define USADDR_WC_BIT 0x2
-#define USADDR_S_BIT 0x4
-
-/**************************************************************************
- * PIM Messages formats *
- *************************************************************************/
-/* TODO: XXX: some structures are probably not used at all */
-
-typedef struct pim pim_header_t;
-
-/* PIM Hello */
-typedef struct pim_hello_ {
- u_int16 option_type; /* Option type */
- u_int16 option_length; /* Length of the Option Value field in bytes */
-} pim_hello_t;
-
-#if 0
-/* PIM Join/Prune: XXX: all 32-bit addresses misaligned! */
-typedef struct pim_jp_header_ {
- pim_encod_uni_addr_t encod_upstream_nbr;
- u_int8 reserved;
- u_int8 num_groups;
- u_int16 holdtime;
-} pim_jp_header_t;
-
-typedef struct pim_jp_encod_grp_ {
- pim_encod_grp_addr_t encod_grp;
- u_int16 number_join_src;
- u_int16 number_prune_src;
-} pim_jp_encod_grp_t;
-#endif
-
-#define PIM_ACTION_NOTHING 0
-#define PIM_ACTION_JOIN 1
-#define PIM_ACTION_PRUNE 2
-
-#define PIM_IIF_SOURCE 1
-#define PIM_IIF_RP 2
-
-#define PIM_ASSERT_RPT_BIT 0x80000000
-
-
-/* PIM messages type */
-#define PIM_HELLO 0
-#ifndef PIM_REGISTER
-#define PIM_REGISTER 1
-#endif
-#define PIM_REGISTER_STOP 2
-#define PIM_JOIN_PRUNE 3
-#define PIM_BOOTSTRAP 4
-#define PIM_ASSERT 5
-#define PIM_GRAFT 6
-#define PIM_GRAFT_ACK 7
-#define PIM_CAND_RP_ADV 8
-
-#define PIM_V2_HELLO PIM_HELLO
-#define PIM_V2_REGISTER PIM_REGISTER
-#define PIM_V2_REGISTER_STOP PIM_REGISTER_STOP
-#define PIM_V2_JOIN_PRUNE PIM_JOIN_PRUNE
-#define PIM_V2_BOOTSTRAP PIM_BOOTSTRAP
-#define PIM_V2_ASSERT PIM_ASSERT
-#define PIM_V2_GRAFT PIM_GRAFT
-#define PIM_V2_GRAFT_ACK PIM_GRAFT_ACK
-#define PIM_V2_CAND_RP_ADV PIM_CAND_RP_ADV
-
-#define PIM_V1_QUERY 0
-#define PIM_V1_REGISTER 1
-#define PIM_V1_REGISTER_STOP 2
-#define PIM_V1_JOIN_PRUNE 3
-#define PIM_V1_RP_REACHABILITY 4
-#define PIM_V1_ASSERT 5
-#define PIM_V1_GRAFT 6
-#define PIM_V1_GRAFT_ACK 7
-
-/* Vartious options from PIM messages definitions */
-/* PIM_HELLO definitions */
-#define PIM_MESSAGE_HELLO_HOLDTIME 1
-#define PIM_MESSAGE_HELLO_HOLDTIME_LENGTH 2
-#define PIM_MESSAGE_HELLO_HOLDTIME_FOREVER 0xffff
-
-
-#define MASK_TO_MASKLEN(mask, masklen) \
- do { \
- register u_int32 tmp_mask = ntohl((mask)); \
- register u_int8 tmp_masklen = sizeof((mask)) << 3; \
- for ( ; tmp_masklen > 0; tmp_masklen--, tmp_mask >>= 1) \
- if (tmp_mask & 0x1) \
- break; \
- (masklen) = tmp_masklen; \
- } while (0)
-
-#define MASKLEN_TO_MASK(masklen, mask) \
-do { \
- (mask) = (masklen)? htonl(~0 << ((sizeof((mask)) << 3) - (masklen))) : 0;\
-} while (0)
-
-#define MASKLEN_TO_MASK6(masklen, mask6) \
- do {\
- u_char maskarray[8] = \
- {0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff}; \
- int bytelen, bitlen, i; \
- memset(&(mask6), 0, sizeof(mask6));\
- bytelen = (masklen) / 8;\
- bitlen = (masklen) % 8;\
- for (i = 0; i < bytelen; i++) \
- (mask6).s6_addr[i] = 0xff;\
- if (bitlen) \
- (mask6).s6_addr[bytelen] = maskarray[bitlen - 1]; \
- }while(0);
-
-/*
- * A bunch of macros because of the lack of 32-bit boundary alignment.
- * All because of one misalligned address format. Hopefully this will be
- * fixed in PIMv3. (cp) must be (u_int8 *) .
- */
-/* Originates from Eddy Rusty's (eddy@isi.edu) PIM-SM implementation for
- * gated.
- */
-
-/* PUT_NETLONG puts "network ordered" data to the datastream.
- * PUT_HOSTLONG puts "host ordered" data to the datastream.
- * GET_NETLONG gets the data and keeps it in "network order" in the memory
- * GET_HOSTLONG gets the data, but in the memory it is in "host order"
- * The same for all {PUT,GET}_{NET,HOST}{SHORT,LONG}
- */
-#define GET_BYTE(val, cp) ((val) = *(cp)++)
-#define PUT_BYTE(val, cp) (*(cp)++ = (u_int8)(val))
-
-#define GET_HOSTSHORT(val, cp) \
- do { \
- register u_int16 Xv; \
- Xv = (*(cp)++) << 8; \
- Xv |= *(cp)++; \
- (val) = Xv; \
- } while (0)
-
-#define PUT_HOSTSHORT(val, cp) \
- do { \
- register u_int16 Xv; \
- Xv = (u_int16)(val); \
- *(cp)++ = (u_int8)(Xv >> 8); \
- *(cp)++ = (u_int8)Xv; \
- } while (0)
-
-#if defined(BYTE_ORDER) && (BYTE_ORDER == LITTLE_ENDIAN)
-#define GET_NETSHORT(val, cp) \
- do { \
- register u_int16 Xv; \
- Xv = *(cp)++; \
- Xv |= (*(cp)++) << 8; \
- (val) = Xv; \
- } while (0)
-#define PUT_NETSHORT(val, cp) \
- do { \
- register u_int16 Xv; \
- Xv = (u_int16)(val); \
- *(cp)++ = (u_int8)Xv; \
- *(cp)++ = (u_int8)(Xv >> 8); \
- } while (0)
-#else
-#define GET_NETSHORT(val, cp) GET_HOSTSHORT(val, cp)
-#define PUT_NETSHORT(val, cp) PUT_HOSTSHORT(val, cp)
-#endif /* {GET,PUT}_NETSHORT */
-
-#define GET_HOSTLONG(val, cp) \
- do { \
- register u_long Xv; \
- Xv = (*(cp)++) << 24; \
- Xv |= (*(cp)++) << 16; \
- Xv |= (*(cp)++) << 8; \
- Xv |= *(cp)++; \
- (val) = Xv; \
- } while (0)
-
-#define PUT_HOSTLONG(val, cp) \
- do { \
- register u_int32 Xv; \
- Xv = (u_int32)(val); \
- *(cp)++ = (u_int8)(Xv >> 24); \
- *(cp)++ = (u_int8)(Xv >> 16); \
- *(cp)++ = (u_int8)(Xv >> 8); \
- *(cp)++ = (u_int8)Xv; \
- } while (0)
-
-#if defined(BYTE_ORDER) && (BYTE_ORDER == LITTLE_ENDIAN)
-#define GET_NETLONG(val, cp) \
- do { \
- register u_long Xv; \
- Xv = *(cp)++; \
- Xv |= (*(cp)++) << 8; \
- Xv |= (*(cp)++) << 16; \
- Xv |= (*(cp)++) << 24; \
- (val) = Xv; \
- } while (0)
-
-#define PUT_NETLONG(val, cp) \
- do { \
- register u_int32 Xv; \
- Xv = (u_int32)(val); \
- *(cp)++ = (u_int8)Xv; \
- *(cp)++ = (u_int8)(Xv >> 8); \
- *(cp)++ = (u_int8)(Xv >> 16); \
- *(cp)++ = (u_int8)(Xv >> 24); \
- } while (0)
-#else
-#define GET_NETLONG(val, cp) GET_HOSTLONG(val, cp)
-#define PUT_NETLONG(val, cp) PUT_HOSTLONG(val, cp)
-#endif /* {GET,PUT}_HOSTLONG */
-
-
-#define GET_ESADDR(esa, cp) \
- do { \
- (esa)->addr_family = *(cp)++; \
- (esa)->encod_type = *(cp)++; \
- (esa)->flags = *(cp)++; \
- (esa)->masklen = *(cp)++; \
- GET_NETLONG((esa)->src_addr, (cp)); \
- } while(0)
-
-#define GET_ESADDR6(esa, cp) /* XXX: hard coding */ \
- do { \
- (esa)->addr_family = *(cp)++; \
- (esa)->encod_type = *(cp)++; \
- (esa)->flags = *(cp)++; \
- (esa)->masklen = *(cp)++; \
- memcpy(&(esa)->src_addr, (cp), sizeof(struct in6_addr)); \
- (cp) += sizeof(struct in6_addr); \
- } while(0)
-
-#define PUT_ESADDR(addr, masklen, flags, cp) \
- do { \
- u_int32 mask; \
- MASKLEN_TO_MASK((masklen), mask); \
- *(cp)++ = ADDRF_IPv4; /* family */ \
- *(cp)++ = ADDRT_IPv4; /* type */ \
- *(cp)++ = (flags); /* flags */ \
- *(cp)++ = (masklen); \
- PUT_NETLONG((addr) & mask, (cp)); \
- } while(0)
-
-#define PUT_ESADDR6(addr, masklen, flags, cp) \
- do { \
- int i; \
- struct in6_addr maskaddr; \
- MASKLEN_TO_MASK6(masklen, maskaddr); \
- *(cp)++ = ADDRF_IPv6; /* family */ \
- *(cp)++ = ADDRT_IPv6; /* type */ \
- *(cp)++ = (flags); /* flags */ \
- *(cp)++ = (masklen); \
- for (i = 0; i < sizeof(struct in6_addr); i++, (cp)++) \
- *(cp) = maskaddr.s6_addr[i] & (addr).s6_addr[i]; \
- } while(0)
-
-#define GET_EGADDR(ega, cp) \
- do { \
- (ega)->addr_family = *(cp)++; \
- (ega)->encod_type = *(cp)++; \
- (ega)->reserved = *(cp)++; \
- (ega)->masklen = *(cp)++; \
- GET_NETLONG((ega)->mcast_addr, (cp)); \
- } while(0)
-
-#define GET_EGADDR6(ega, cp) /* XXX: hard coding */ \
- do { \
- (ega)->addr_family = *(cp)++; \
- (ega)->encod_type = *(cp)++; \
- (ega)->reserved = *(cp)++; \
- (ega)->masklen = *(cp)++; \
- memcpy(&(ega)->mcast_addr, (cp), sizeof(struct in6_addr)); \
- (cp) += sizeof(struct in6_addr); \
- } while(0)
-
-#define PUT_EGADDR(addr, masklen, reserved, cp) \
- do { \
- u_int32 mask; \
- MASKLEN_TO_MASK((masklen), mask); \
- *(cp)++ = ADDRF_IPv4; /* family */ \
- *(cp)++ = ADDRT_IPv4; /* type */ \
- *(cp)++ = (reserved); /* reserved; should be 0 */ \
- *(cp)++ = (masklen); \
- PUT_NETLONG((addr) & mask, (cp)); \
- } while(0)
-
-#define PUT_EGADDR6(addr, masklen, reserved, cp) \
- do { \
- int i; \
- struct in6_addr maskaddr; \
- MASKLEN_TO_MASK6(masklen, maskaddr); \
- *(cp)++ = ADDRF_IPv6; /* family */ \
- *(cp)++ = ADDRT_IPv6; /* type */ \
- *(cp)++ = (reserved); /* reserved; should be 0 */ \
- *(cp)++ = (masklen); \
- for (i = 0; i < sizeof(struct in6_addr); i++, (cp)++) \
- *(cp) = maskaddr.s6_addr[i] & (addr).s6_addr[i]; \
- } while(0)
-
-#define GET_EUADDR(eua, cp) \
- do { \
- (eua)->addr_family = *(cp)++; \
- (eua)->encod_type = *(cp)++; \
- GET_NETLONG((eua)->unicast_addr, (cp)); \
- } while(0)
-
-#define GET_EUADDR6(eua, cp) /* XXX hard conding */ \
- do { \
- (eua)->addr_family = *(cp)++; \
- (eua)->encod_type = *(cp)++; \
- memcpy(&(eua)->unicast_addr, (cp), sizeof(struct in6_addr)); \
- (cp) += sizeof(struct in6_addr); \
- } while(0)
-
-#define PUT_EUADDR(addr, cp) \
- do { \
- *(cp)++ = ADDRF_IPv4; /* family */ \
- *(cp)++ = ADDRT_IPv4; /* type */ \
- PUT_NETLONG((addr), (cp)); \
- } while(0)
-
-#define PUT_EUADDR6(addr, cp) \
- do { \
- *(cp)++ = ADDRF_IPv6; /* family */ \
- *(cp)++ = ADDRT_IPv6; /* type */ \
- memcpy((cp), &(addr), sizeof(struct in6_addr)); \
- (cp) += sizeof(struct in6_addr); \
- } while(0)
-
-/* TODO: Currently not used. Probably not need at all. Delete! */
-#ifdef NOSUCHDEF
-/* This is completely IGMP related stuff? */
-#define PIM_LEAF_TIMEOUT (3.5 * IGMP_QUERY_INTERVAL)
-#endif /* NOSUCHDEF */
-
-#if defined(__bsdi__) || defined(__NetBSD__)
-/*
- * Struct used to communicate from kernel to multicast router
- * note the convenient similarity to an IP packet
- */
-struct igmpmsg {
- u_long unused1;
- u_long unused2;
- u_char im_msgtype; /* what type of message */
-#define IGMPMSG_NOCACHE 1
-#define IGMPMSG_WRONGVIF 2
-#define IGMPMSG_WHOLEPKT 3 /* used for user level encap*/
- u_char im_mbz; /* must be zero */
- u_char im_vif; /* vif rec'd on */
- u_char unused3;
- struct in_addr im_src, im_dst;
-};
-#endif
diff --git a/usr.sbin/pim6dd/route.c b/usr.sbin/pim6dd/route.c
deleted file mode 100644
index 8a39ae0..0000000
--- a/usr.sbin/pim6dd/route.c
+++ /dev/null
@@ -1,659 +0,0 @@
-/*
- * Copyright (c) 1998 by the University of Oregon.
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation in source and binary forms for lawful
- * purposes and without fee is hereby granted, provided
- * that the above copyright notice appear in all copies and that both
- * the copyright notice and this permission notice appear in supporting
- * documentation, and that any documentation, advertising materials,
- * and other materials related to such distribution and use acknowledge
- * that the software was developed by the University of Oregon.
- * The name of the University of Oregon may not be used to endorse or
- * promote products derived from this software without specific prior
- * written permission.
- *
- * THE UNIVERSITY OF OREGON DOES NOT MAKE ANY REPRESENTATIONS
- * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. THIS SOFTWARE IS
- * PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
- * NON-INFRINGEMENT.
- *
- * IN NO EVENT SHALL UO, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT,
- * TORT, OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH,
- * THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Other copyrights might apply to parts of this software and are so
- * noted when applicable.
- */
-/*
- * Questions concerning this software should be directed to
- * Kurt Windisch (kurtw@antc.uoregon.edu)
- *
- * $Id: route.c,v 1.3 1999/10/27 11:40:30 jinmei Exp $
- */
-/*
- * Part of this program has been derived from PIM sparse-mode pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- * The pimd program is COPYRIGHT 1998 by University of Southern California.
- *
- * Part of this program has been derived from mrouted.
- * The mrouted program is covered by the license in the accompanying file
- * named "LICENSE.mrouted".
- *
- * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
- * Leland Stanford Junior University.
- *
- * $FreeBSD$
- */
-
-#include "defs.h"
-
-
-static u_int16 max_prune_timeout __P((mrtentry_t *));
-static void process_cache_miss __P((struct mrt6msg *im));
-static void process_wrong_iif __P((struct mrt6msg *im));
-
-u_int32 default_source_preference = DEFAULT_LOCAL_PREF;
-u_int32 default_source_metric = DEFAULT_LOCAL_METRIC;
-
-
-/* Return the iif for given address */
-vifi_t
-get_iif(address)
- struct sockaddr_in6 *address;
-{
- struct rpfctl rpfc;
-
- k_req_incoming(address, &rpfc);
- if (IN6_IS_ADDR_UNSPECIFIED(&rpfc.rpfneighbor.sin6_addr))
- return (NO_VIF);
- return (rpfc.iif);
-}
-
-/* Return the PIM neighbor toward a source */
-/* If route not found or if a local source or if a directly connected source,
- * but is not PIM router, or if the first hop router is not a PIM router,
- * then return NULL.
- */
-pim_nbr_entry_t *
-find_pim6_nbr(source)
- struct sockaddr_in6 *source;
-{
- struct rpfctl rpfc;
- pim_nbr_entry_t *pim_nbr;
- struct sockaddr_in6 *next_hop_router_addr;
-
- if (local_address(source) != NO_VIF)
- return (pim_nbr_entry_t *)NULL;
- k_req_incoming(source, &rpfc);
- if ((IN6_IS_ADDR_UNSPECIFIED(&rpfc.rpfneighbor.sin6_addr))
- || (rpfc.iif == NO_VIF))
- return (pim_nbr_entry_t *)NULL;
- next_hop_router_addr = &rpfc.rpfneighbor;
- for (pim_nbr = uvifs[rpfc.iif].uv_pim_neighbors;
- pim_nbr != (pim_nbr_entry_t *)NULL;
- pim_nbr = pim_nbr->next)
- if (inet6_equal(&pim_nbr->address, next_hop_router_addr))
- return(pim_nbr);
- return (pim_nbr_entry_t *)NULL;
-}
-
-/* TODO: check again the exact setup if the source is local or directly
- * connected!!!
- */
-/* TODO: XXX: change the metric and preference for all (S,G) entries per
- * source?
- */
-/* PIMDM TODO - If possible, this would be the place to correct set the
- * source's preference and metric to that obtained from the kernel
- * and/or unicast routing protocol. For now, set it to the configured
- * default for local pref/metric.
- */
-/*
- * Set the iif, upstream router, preference and metric for the route
- * toward the source. Return TRUE is the route was found, othewise FALSE.
- * If srctype==PIM_IIF_SOURCE and if the source is directly connected
- * then the "upstream" is set to NULL.
- * Note that srctype is a hold-over from the PIM-SM daemon and is unused.
- */
-int
-set_incoming(srcentry_ptr, srctype)
- srcentry_t *srcentry_ptr;
- int srctype;
-{
- struct rpfctl rpfc;
- struct sockaddr_in6 *source = &srcentry_ptr->address;
- struct sockaddr_in6 *neighbor_addr;
- register struct uvif *v;
- register pim_nbr_entry_t *n;
-
- /* Preference will be 0 if directly connected */
- srcentry_ptr->preference = 0;
- srcentry_ptr->metric = 0;
-
- if ((srcentry_ptr->incoming = local_address(source)) != NO_VIF) {
- /* The source is a local address */
- /* TODO: set the upstream to myself? */
- srcentry_ptr->upstream = (pim_nbr_entry_t *)NULL;
- return (TRUE);
- }
-
- if ((srcentry_ptr->incoming = find_vif_direct(source)) == NO_VIF) {
- /* TODO: probably need to check the case if the iif is disabled */
- /* Use the lastest resource: the kernel unicast routing table */
- k_req_incoming(source, &rpfc);
- if ((rpfc.iif == NO_VIF) ||
- IN6_IS_ADDR_UNSPECIFIED(&rpfc.rpfneighbor.sin6_addr)) {
- /* couldn't find a route */
- IF_DEBUG(DEBUG_PIM_MRT | DEBUG_RPF)
- log(LOG_DEBUG, 0, "NO ROUTE found for %s",
- inet6_fmt(&source->sin6_addr));
- return(FALSE);
- }
- srcentry_ptr->incoming = rpfc.iif;
- neighbor_addr = &rpfc.rpfneighbor;
- }
- else {
- /* The source is directly connected.
- */
- srcentry_ptr->upstream = (pim_nbr_entry_t *)NULL;
- return (TRUE);
- }
-
- /* set the preference for sources that aren't directly connected. */
- v = &uvifs[srcentry_ptr->incoming];
- srcentry_ptr->preference = v->uv_local_pref;
- srcentry_ptr->metric = v->uv_local_metric;
-
- /*
- * The upstream router must be a (PIM router) neighbor, otherwise we
- * are in big trouble ;-)
- */
- for (n = v->uv_pim_neighbors; n != NULL; n = n->next) {
- if (inet6_lessthan(neighbor_addr, &n->address))
- continue;
- if (inet6_equal(neighbor_addr, &n->address)) {
- /*
- *The upstream router is found in the list of neighbors.
- * We are safe!
- */
- srcentry_ptr->upstream = n;
- IF_DEBUG(DEBUG_RPF)
- log(LOG_DEBUG, 0,
- "For src %s, iif is %d, next hop router is %s",
- inet6_fmt(&source->sin6_addr), srcentry_ptr->incoming,
- inet6_fmt(&neighbor_addr->sin6_addr));
- return(TRUE);
- }
- else break;
- }
-
- /* TODO: control the number of messages! */
- log(LOG_INFO, 0,
- "For src %s, iif is %d, next hop router is %s: NOT A PIM ROUTER",
- inet6_fmt(&source->sin6_addr), srcentry_ptr->incoming,
- inet6_fmt(&neighbor_addr->sin6_addr));
- srcentry_ptr->upstream = (pim_nbr_entry_t *)NULL;
-
- return(FALSE);
-}
-
-
-/* Set the leaves in a new mrtentry */
-void set_leaves(mrtentry_ptr)
- mrtentry_t *mrtentry_ptr;
-{
- vifi_t vifi;
- struct uvif *v;
-
- /* Check for a group report on each vif */
- for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v)
- if(check_multicast_listener(v, &mrtentry_ptr->group->group))
- IF_SET(vifi, &mrtentry_ptr->leaves);
-}
-
-
-/* Handle new receiver
- *
- * TODO: XXX: currently `source` is not used. Will be used with IGMPv3 where
- * we have source-specific Join/Prune.
- */
-void
-add_leaf(vifi, source, group)
- vifi_t vifi;
- struct sockaddr_in6 *source;
- struct sockaddr_in6 *group;
-{
- grpentry_t *grpentry_ptr;
- mrtentry_t *mrtentry_srcs;
- if_set new_leaves;
- int state_change;
-
- grpentry_ptr = find_group(group);
- if (grpentry_ptr == (grpentry_t *)NULL)
- return;
-
- /* walk the source list for the group and add vif to oiflist */
- for (mrtentry_srcs = grpentry_ptr->mrtlink;
- mrtentry_srcs != (mrtentry_t *)NULL;
- mrtentry_srcs = mrtentry_srcs->grpnext) {
-
- /* if applicable, add the vif to the leaves */
- if (mrtentry_srcs->incoming == vifi)
- continue;
-
- if(!(IF_ISSET(vifi, &mrtentry_srcs->leaves))) {
-
- IF_DEBUG(DEBUG_MRT)
- log(LOG_DEBUG, 0, "Adding leaf vif %d for src %s group %s",
- vifi,
- inet6_fmt(&mrtentry_srcs->source->address.sin6_addr),
- inet6_fmt(&group->sin6_addr));
-
- IF_COPY(&mrtentry_srcs->leaves, &new_leaves);
- IF_SET(vifi, &new_leaves); /* Add the leaf */
-
- state_change =
- change_interfaces(mrtentry_srcs,
- mrtentry_srcs->incoming,
- &mrtentry_srcs->pruned_oifs,
- &new_leaves,
- &mrtentry_srcs->asserted_oifs);
-
- /* Handle transition from negative cache */
- if(state_change == 1)
- trigger_join_alert(mrtentry_srcs);
- }
- }
-}
-
-
-/*
- * TODO: XXX: currently `source` is not used. To be used with IGMPv3 where
- * we have source-specific joins/prunes.
- */
-void
-delete_leaf(vifi, source, group)
- vifi_t vifi;
- struct sockaddr_in6 *source;
- struct sockaddr_in6 *group;
-{
- grpentry_t *grpentry_ptr;
- mrtentry_t *mrtentry_srcs;
- if_set new_leaves;
- int state_change;
-
- /* mrtentry_t *mrtentry_ptr;
- * mrtentry_t *mrtentry_srcs;
- * vifbitmap_t new_oifs;
- * vifbitmap_t old_oifs;
- * vifbitmap_t new_leaves;
- */
-
- grpentry_ptr = find_group(group);
- if (grpentry_ptr == (grpentry_t *)NULL)
- return;
-
- /* walk the source list for the group and delete vif to leaves */
- for (mrtentry_srcs = grpentry_ptr->mrtlink;
- mrtentry_srcs != (mrtentry_t *)NULL;
- mrtentry_srcs = mrtentry_srcs->grpnext) {
-
- /* if applicable, delete the vif from the leaves */
- if (mrtentry_srcs->incoming == vifi)
- continue;
-
- if(IF_ISSET(vifi, &mrtentry_srcs->leaves)) {
-
- IF_DEBUG(DEBUG_MRT)
- log(LOG_DEBUG, 0, "Deleting leaf vif %d for src %s, group %s",
- vifi,
- inet6_fmt(&mrtentry_srcs->source->address.sin6_addr),
- inet6_fmt(&group->sin6_addr));
-
- IF_COPY(&mrtentry_srcs->leaves, &new_leaves);
- IF_CLR(vifi, &new_leaves); /* Remove the leaf */
-
- state_change =
- change_interfaces(mrtentry_srcs,
- mrtentry_srcs->incoming,
- &mrtentry_srcs->pruned_oifs,
- &new_leaves,
- &mrtentry_srcs->asserted_oifs);
-
- /* Handle transition to negative cache */
- if(state_change == -1)
- trigger_prune_alert(mrtentry_srcs);
- }
- }
-}
-
-void
-calc_oifs(mrtentry_ptr, oifs_ptr)
- mrtentry_t *mrtentry_ptr;
- if_set *oifs_ptr;
-{
- if_set oifs;
-
- /*
- * oifs =
- * ((nbr_ifs - my_prune) + my_leaves) - my_filters - incoming_interface,
- * i.e.`leaves` have higher priority than `prunes`, but lower than `filters'.
- * Asserted oifs (those that lost assert) are handled as pruned oifs.
- * The incoming interface is always deleted from the oifs
- */
-
- if (mrtentry_ptr == (mrtentry_t *)NULL) {
- IF_ZERO(oifs_ptr);
- return;
- }
-
- IF_COPY(&nbr_mifs, &oifs);
- IF_CLR_MASK(&oifs, &mrtentry_ptr->pruned_oifs);
- IF_MERGE(&oifs, &mrtentry_ptr->leaves, &oifs);
- IF_CLR_MASK(&oifs, &mrtentry_ptr->asserted_oifs);
- IF_CLR_MASK(&oifs, &mrtentry_ptr->filter_oifs);
- IF_CLR(mrtentry_ptr->incoming, &oifs);
- IF_COPY(&oifs, oifs_ptr);
-}
-
-
-/*
- * Set the iif, join/prune/leaves/asserted interfaces. Calculate and
- * set the oifs.
- * Return 1 if oifs change from NULL to not-NULL.
- * Return -1 if oifs change from non-NULL to NULL
- * else return 0
- * If the iif change or if the oifs change from NULL to non-NULL
- * or vice-versa, then schedule that mrtentry join/prune timer to
- * timeout immediately.
- */
-int
-change_interfaces(mrtentry_ptr, new_iif, new_pruned_oifs,
- new_leaves_, new_asserted_oifs)
- mrtentry_t *mrtentry_ptr;
- vifi_t new_iif;
- if_set *new_pruned_oifs;
- if_set *new_leaves_;
- if_set *new_asserted_oifs;
-{
- if_set old_pruned_oifs; /* unnecessary? */
- if_set old_leaves; /* unnecessary? */
- if_set new_leaves;
- if_set new_real_oifs; /* The result oifs */
- if_set old_real_oifs;
- if_set old_asserted_oifs; /* unnecessary? */
- vifi_t old_iif;
- int return_value;
-
- if (mrtentry_ptr == (mrtentry_t *)NULL)
- return (0);
-
- IF_COPY(new_leaves_, &new_leaves);
-
- old_iif = mrtentry_ptr->incoming;
- IF_COPY(&mrtentry_ptr->leaves, &old_leaves);
- IF_COPY(&mrtentry_ptr->pruned_oifs, &old_pruned_oifs);
- IF_COPY(&mrtentry_ptr->asserted_oifs, &old_asserted_oifs);
-
- IF_COPY(&mrtentry_ptr->oifs, &old_real_oifs);
-
- mrtentry_ptr->incoming = new_iif;
- IF_COPY(new_pruned_oifs, &mrtentry_ptr->pruned_oifs);
- IF_COPY(&new_leaves, &mrtentry_ptr->leaves);
- IF_COPY(new_asserted_oifs, &mrtentry_ptr->asserted_oifs);
- calc_oifs(mrtentry_ptr, &new_real_oifs);
-
- if (IF_ISEMPTY(&old_real_oifs)) {
- if (IF_ISEMPTY(&new_real_oifs))
- return_value = 0;
- else
- return_value = 1;
- } else {
- if (IF_ISEMPTY(&new_real_oifs))
- return_value = -1;
- else
- return_value = 0;
- }
-
- if ((IF_SAME(&new_real_oifs, &old_real_oifs))
- && (new_iif == old_iif))
- return 0; /* Nothing to change */
-
- IF_COPY(&new_real_oifs, &mrtentry_ptr->oifs);
-
- k_chg_mfc(mld6_socket, &mrtentry_ptr->source->address,
- &mrtentry_ptr->group->group, new_iif, &new_real_oifs);
-
-#ifdef RSRR
- rsrr_cache_send(mrtentry_ptr, RSRR_NOTIFICATION_OK);
-#endif /* RSRR */
-
- return (return_value);
-}
-
-
-/* TODO: implement it. Required to allow changing of the physical interfaces
- * configuration without need to restart pimd.
- */
-int
-delete_vif_from_mrt(vifi)
-vifi_t vifi;
-{
- return TRUE;
-}
-
-
-static u_int16
-max_prune_timeout(mrtentry_ptr)
- mrtentry_t *mrtentry_ptr;
-{
- vifi_t vifi;
-#if 0
- /* XXX: I don't understand how the variable works...(jinmei@kame.net) */
- u_int16 time_left = 0;
-#endif
- u_int16 max_holdtime = 0;
-
- for(vifi=0; vifi < numvifs; ++vifi)
- if(IF_ISSET(vifi, &mrtentry_ptr->pruned_oifs) &&
- mrtentry_ptr->prune_timers[vifi])
- /* XXX - too expensive ? */
- if(mrtentry_ptr->prune_timers[vifi] > max_holdtime)
- max_holdtime = mrtentry_ptr->prune_timers[vifi];
-#if 0
- /* XXX: This is original. But does it have any meaning? */
- max_holdtime = time_left;
-#endif
-
- if(max_holdtime == 0)
- max_holdtime = (u_int16)PIM_JOIN_PRUNE_HOLDTIME;
-
- return(max_holdtime);
-}
-
-
-void
-process_kernel_call()
-{
- register struct mrt6msg *im; /* igmpmsg control struct */
-
- im = (struct mrt6msg *) mld6_recv_buf;
-
- switch (im->im6_msgtype) {
- case MRT6MSG_NOCACHE:
- process_cache_miss(im);
- break;
- case MRT6MSG_WRONGMIF:
- process_wrong_iif(im);
- break;
- default:
- IF_DEBUG(DEBUG_KERN)
- log(LOG_DEBUG, 0, "Unknown kernel_call code, %d", im->im6_msgtype);
- break;
- }
-}
-
-
-/*
- * Protocol actions:
- * 1. Create (S,G) entry (find_route(CREATE))
- * a. set iif and oifs
- */
-static void
-process_cache_miss(im)
- struct mrt6msg *im;
-{
- static struct sockaddr_in6 source = {sizeof(source), AF_INET6};
- static struct sockaddr_in6 group = {sizeof(group), AF_INET6};
- mrtentry_t *mrtentry_ptr;
-
- /*
- * When there is a cache miss, we check only the header of the packet
- * (and only it should be sent up by the kernel.
- */
-
- group.sin6_addr = im->im6_dst;
- source.sin6_addr = im->im6_src;
- group.sin6_scope_id = inet6_uvif2scopeid(&group, &uvifs[im->im6_mif]);
- source.sin6_scope_id = inet6_uvif2scopeid(&source, &uvifs[im->im6_mif]);
-
- IF_DEBUG(DEBUG_MFC)
- log(LOG_DEBUG, 0, "Cache miss, src %s, dst %s",
- inet6_fmt(&source.sin6_addr), inet6_fmt(&group.sin6_addr));
-
- /* Don't create routing entries for the LAN scoped addresses */
- if (IN6_IS_ADDR_MC_NODELOCAL(&group.sin6_addr) ||/* sanity? */
- IN6_IS_ADDR_MC_LINKLOCAL(&group.sin6_addr))
- return;
-
- /* Create the (S,G) entry */
- mrtentry_ptr = find_route(&source, &group, MRTF_SG, CREATE);
- if (mrtentry_ptr == (mrtentry_t *)NULL)
- return;
- mrtentry_ptr->flags &= ~MRTF_NEW;
-
- /* Set oifs */
- set_leaves(mrtentry_ptr);
- calc_oifs(mrtentry_ptr, &(mrtentry_ptr->oifs));
-
- /* Add it to the kernel */
- k_chg_mfc(mld6_socket, &source, &group, mrtentry_ptr->incoming,
- &mrtentry_ptr->oifs);
-
-#ifdef RSRR
- rsrr_cache_send(mrtentry_ptr, RSRR_NOTIFICATION_OK);
-#endif /* RSRR */
-
- /* No need to call change_interfaces, but check for NULL oiflist */
- if(IF_ISEMPTY(&mrtentry_ptr->oifs))
- trigger_prune_alert(mrtentry_ptr);
-}
-
-
-/*
- * A multicast packet has been received on wrong iif by the kernel.
- * If the packet was received on a point-to-point interface, rate-limit
- * prunes. if the packet was received on a LAN interface, rate-limit
- * asserts.
- */
-static void
-process_wrong_iif(im)
- struct mrt6msg *im;
-{
- static struct sockaddr_in6 source = {sizeof(source), AF_INET6};
- static struct sockaddr_in6 group = {sizeof(group), AF_INET6};
- mifi_t mifi;
- mrtentry_t *mrtentry_ptr;
-
- group.sin6_addr = im->im6_dst;
- source.sin6_addr = im->im6_src;
- mifi = (mifi_t)im->im6_mif;
- group.sin6_scope_id = inet6_uvif2scopeid(&group, &uvifs[mifi]);
- source.sin6_scope_id = inet6_uvif2scopeid(&source, &uvifs[mifi]);
-
- /* PIMDM TODO Don't create routing entries for the LAN scoped addresses */
- if (IN6_IS_ADDR_MC_NODELOCAL(&group.sin6_addr) ||/* sanity? */
- IN6_IS_ADDR_MC_LINKLOCAL(&group.sin6_addr))
- return;
-
- mrtentry_ptr = find_route(&source, &group, MRTF_SG, DONT_CREATE);
- if(mrtentry_ptr == (mrtentry_t *)NULL)
- return;
-
- /* Ratelimit prunes or asserts */
-#ifdef notyet
- if(uvifs[mifi].uv_flags & VIFF_POINT_TO_POINT) {
-
- /* Wrong vif on P2P interface - rate-limit prunes */
-
- if(mrtentry_ptr->last_prune[mifi] == virtual_time)
- /* Skip due to rate-limiting */
- return;
- mrtentry_ptr->last_prune[mifi] = virtual_time;
-
- if(uvifs[mifi].uv_rmt_addr)
- send_pim6_jp(mrtentry_ptr, PIM_ACTION_PRUNE, mifi,
- uvifs[mifi].uv_rmt_addr,
- max_prune_timeout(mrtentry_ptr), 0);
- else
- log(LOG_WARNING, 0,
- "Can't send wrongvif prune on p2p %s: no remote address",
- uvifs[mifi].uv_lcl_addr);
- } else
-#endif
- {
-
- /* Wrong vif on LAN interface - rate-limit asserts */
-
- if(mrtentry_ptr->last_assert[mifi] == virtual_time)
- /* Skip due to rate-limiting */
- return;
- mrtentry_ptr->last_assert[mifi] = virtual_time;
-
- /* Send the assert */
- send_pim6_assert(&source, &group, mifi, mrtentry_ptr);
- }
-}
-
-
-void
-trigger_prune_alert(mrtentry_ptr)
- mrtentry_t *mrtentry_ptr;
-{
- IF_DEBUG(DEBUG_MRT)
- log(LOG_DEBUG, 0, "Now negative cache for src %s, grp %s - pruning",
- inet6_fmt(&mrtentry_ptr->source->address.sin6_addr),
- inet6_fmt(&mrtentry_ptr->group->group.sin6_addr));
-
- /* Set the entry timer to the max of the prune timers */
- SET_TIMER(mrtentry_ptr->timer, max_prune_timeout(mrtentry_ptr));
-
- /* Send a prune */
- if(mrtentry_ptr->upstream)
- send_pim6_jp(mrtentry_ptr, PIM_ACTION_PRUNE, mrtentry_ptr->incoming,
- &mrtentry_ptr->upstream->address,
- max_prune_timeout(mrtentry_ptr), 0);
-}
-
-void
-trigger_join_alert(mrtentry_ptr)
- mrtentry_t *mrtentry_ptr;
-{
- IF_DEBUG(DEBUG_MRT)
- log(LOG_DEBUG, 0, "Now forwarding state for src %s, grp %s - grafting",
- inet6_fmt(&mrtentry_ptr->source->address.sin6_addr),
- inet6_fmt(&mrtentry_ptr->group->group.sin6_addr));
-
- /* Refresh the entry timer */
- SET_TIMER(mrtentry_ptr->timer, PIM_DATA_TIMEOUT);
-
- /* Send graft */
- send_pim6_graft(mrtentry_ptr);
-}
diff --git a/usr.sbin/pim6dd/routesock.c b/usr.sbin/pim6dd/routesock.c
deleted file mode 100644
index a2065b9..0000000
--- a/usr.sbin/pim6dd/routesock.c
+++ /dev/null
@@ -1,373 +0,0 @@
-/*
- * Copyright (c) 1998 by the University of Southern California.
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation in source and binary forms for lawful
- * purposes and without fee is hereby granted, provided
- * that the above copyright notice appear in all copies and that both
- * the copyright notice and this permission notice appear in supporting
- * documentation, and that any documentation, advertising materials,
- * and other materials related to such distribution and use acknowledge
- * that the software was developed by the University of Southern
- * California and/or Information Sciences Institute.
- * The name of the University of Southern California may not
- * be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THE UNIVERSITY OF SOUTHERN CALIFORNIA DOES NOT MAKE ANY REPRESENTATIONS
- * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. THIS SOFTWARE IS
- * PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
- * NON-INFRINGEMENT.
- *
- * IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT,
- * TORT, OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH,
- * THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Other copyrights might apply to parts of this software and are so
- * noted when applicable.
- */
-/*
- * Questions concerning this software should be directed to
- * Pavlin Ivanov Radoslavov (pavlin@catarina.usc.edu)
- *
- * $Id: routesock.c,v 1.4 1999/11/19 04:05:48 sumikawa Exp $
- */
-/*
- * Part of this program has been derived from mrouted.
- * The mrouted program is covered by the license in the accompanying file
- * named "LICENSE.mrouted".
- *
- * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
- * Leland Stanford Junior University.
- *
- * $FreeBSD$
- */
-
-#include <sys/param.h>
-#include <sys/file.h>
-#include "defs.h"
-#include <sys/socket.h>
-#include <net/route.h>
-#ifdef HAVE_ROUTING_SOCKETS
-#include <net/if_dl.h>
-#endif
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <stdlib.h>
-
-#ifdef HAVE_ROUTING_SOCKETS
-union sockunion {
- struct sockaddr sa;
- struct sockaddr_in6 sin6;
- struct sockaddr_dl sdl;
-} so_dst, so_ifp;
-typedef union sockunion *sup;
-int routing_socket;
-int rtm_addrs, pid;
-struct rt_metrics rt_metrics;
-u_long rtm_inits;
-
-/*
- * Local functions definitions.
- */
-static int getmsg __P((register struct rt_msghdr *, int,
- struct rpfctl *rpfinfo));
-
-/*
- * TODO: check again!
- */
-#ifdef IRIX
-#define ROUNDUP(a) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(__uint64_t) - 1))) \
- : sizeof(__uint64_t))
-#else
-#define ROUNDUP(a) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) \
- : sizeof(long))
-#endif /* IRIX */
-
-#ifdef HAVE_SA_LEN
-#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
-#else
-#define ADVANCE(x, n) (x += ROUNDUP(4)) /* TODO: a hack!! */
-#endif
-
-/* Open and initialize the routing socket */
-int
-init_routesock()
-{
- pid = getpid();
- routing_socket = socket(PF_ROUTE, SOCK_RAW, AF_INET6);
- if (routing_socket < 0) {
- log(LOG_ERR, 0, "\nRouting socket error");
- return -1;
- }
- if (fcntl(routing_socket, F_SETFL, O_NONBLOCK) == -1){
- log(LOG_ERR, 0, "\n Routing socket error");
- return -1;
- }
-#if 0
- {
- int off;
-
- off = 0;
- if (setsockopt(routing_socket, SOL_SOCKET,
- SO_USELOOPBACK, (char *)&off,
- sizeof(off)) < 0){
- log(LOG_ERR, 0 , "\n setsockopt(SO_USELOOPBACK,0)");
- return -1;
- }
- }
-#endif
- return 0;
-}
-
-
-struct {
- struct rt_msghdr m_rtm;
- char m_space[512];
-} m_rtmsg;
-
-
-/* get the rpf neighbor info */
-int
-k_req_incoming(source, rpfp)
- struct sockaddr_in6 *source;
- struct rpfctl *rpfp;
-{
- int flags = RTF_STATIC;
- register sup su;
- static int seq;
- int rlen;
- register char *cp = m_rtmsg.m_space;
- register int l;
- struct rpfctl rpfinfo;
-
-/* TODO: a hack!!!! */
-#ifdef HAVE_SA_LEN
-#define NEXTADDR(w, u) \
- if (rtm_addrs & (w)) { \
- l = ROUNDUP(u.sa.sa_len); bcopy((char *)&(u), cp, l); cp += l;\
- }
-#else
-#define NEXTADDR(w, u) \
- if (rtm_addrs & (w)) { \
- l = ROUNDUP(4); bcopy((char *)&(u), cp, l); cp += l;\
- }
-#endif /* HAVE_SA_LEN */
-
- /* initialize */
- memset(&rpfp->rpfneighbor, 0, sizeof(rpfp->rpfneighbor));
- rpfp->source = *source;
-
- /* check if local address or directly connected before calling the
- * routing socket
- */
-
- if ((rpfp->iif = find_vif_direct_local(source)) != NO_VIF) {
- rpfp->rpfneighbor = *source;
- return(TRUE);
- }
-
- /* prepare the routing socket params */
- rtm_addrs |= RTA_DST;
- rtm_addrs |= RTA_IFP;
- su = &so_dst;
- su->sin6.sin6_family = AF_INET6;
-#ifdef HAVE_SA_LEN
- su->sin6.sin6_len = sizeof(struct sockaddr_in6);
-#endif
- su->sin6.sin6_addr = source->sin6_addr;
- su->sin6.sin6_scope_id = source->sin6_scope_id;
- so_ifp.sa.sa_family = AF_LINK;
-#ifdef HAVE_SA_LEN
- so_ifp.sa.sa_len = sizeof(struct sockaddr_dl);
-#endif
- flags |= RTF_UP;
- flags |= RTF_HOST;
- flags |= RTF_GATEWAY;
- errno = 0;
- bzero((char *)&m_rtmsg, sizeof(m_rtmsg));
-
-#define rtm m_rtmsg.m_rtm
- rtm.rtm_type = RTM_GET;
- rtm.rtm_flags = flags;
- rtm.rtm_version = RTM_VERSION;
- rtm.rtm_seq = ++seq;
- rtm.rtm_addrs = rtm_addrs;
- rtm.rtm_rmx = rt_metrics;
- rtm.rtm_inits = rtm_inits;
-
- NEXTADDR(RTA_DST, so_dst);
- NEXTADDR(RTA_IFP, so_ifp);
- rtm.rtm_msglen = l = cp - (char *)&m_rtmsg;
-
- if ((rlen = write(routing_socket, (char *)&m_rtmsg, l)) < 0) {
- IF_DEBUG(DEBUG_RPF | DEBUG_KERN) {
- if (errno == ESRCH)
- log(LOG_DEBUG, 0,
- "Writing to routing socket: no such route\n");
- else
- log(LOG_DEBUG, 0, "Error writing to routing socket");
- }
- return(FALSE);
- }
-
- do {
- l = read(routing_socket, (char *)&m_rtmsg, sizeof(m_rtmsg));
- } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid));
-
- if (l < 0) {
- IF_DEBUG(DEBUG_RPF | DEBUG_KERN)
- log(LOG_DEBUG, 0, "Read from routing socket failed: %s", strerror(errno));
- return(FALSE);
- }
-
- if (getmsg(&rtm, l, &rpfinfo)){
- rpfp->rpfneighbor = rpfinfo.rpfneighbor;
- rpfp->iif = rpfinfo.iif;
- }
-#undef rtm
- return (TRUE);
-}
-
-
-/*
- * Returns TRUE on success, FALSE otherwise. rpfinfo contains the result.
- */
-int
-getmsg(rtm, msglen, rpfinfop)
- register struct rt_msghdr *rtm;
- int msglen;
- struct rpfctl *rpfinfop;
-{
- struct sockaddr *dst = NULL, *gate = NULL, *mask = NULL;
- struct sockaddr_dl *ifp = NULL;
- register struct sockaddr *sa;
- register char *cp;
- register int i;
- struct sockaddr_in6 *sin6;
- vifi_t vifi;
- struct uvif *v;
- char in6txt[INET6_ADDRSTRLEN];
-
- if (rpfinfop == (struct rpfctl *)NULL)
- return(FALSE);
-
- sin6 = (struct sockaddr_in6 *)&so_dst;
- IF_DEBUG(DEBUG_RPF)
- log(LOG_DEBUG, 0, "route to: %s",
- inet_ntop(AF_INET6, &sin6->sin6_addr, in6txt, INET6_ADDRSTRLEN));
- cp = ((char *)(rtm + 1));
- if (rtm->rtm_addrs)
- for (i = 1; i; i <<= 1)
- if (i & rtm->rtm_addrs) {
- sa = (struct sockaddr *)cp;
- switch (i) {
- case RTA_DST:
- dst = sa;
- break;
- case RTA_GATEWAY:
- gate = sa;
- break;
- case RTA_NETMASK:
- mask = sa;
- break;
- case RTA_IFP:
- if (sa->sa_family == AF_LINK &&
- ((struct sockaddr_dl *)sa)->sdl_nlen)
- ifp = (struct sockaddr_dl *)sa;
- break;
- }
- ADVANCE(cp, sa);
- }
-
- if (!ifp){ /* No incoming interface */
- IF_DEBUG(DEBUG_RPF)
- log(LOG_DEBUG, 0,
- "No incoming interface for destination %s",
- inet_ntop(AF_INET6, &sin6->sin6_addr, in6txt, INET6_ADDRSTRLEN));
- return(FALSE);
- }
- if (dst && mask)
- mask->sa_family = dst->sa_family;
- if (dst) {
- sin6 = (struct sockaddr_in6 *)dst;
- IF_DEBUG(DEBUG_RPF)
- log(LOG_DEBUG, 0, " destination is: %s",
- inet_ntop(AF_INET6, &sin6->sin6_addr, in6txt, INET6_ADDRSTRLEN));
- }
- if (gate && rtm->rtm_flags & RTF_GATEWAY) {
- sin6 = (struct sockaddr_in6 *)gate;
- IF_DEBUG(DEBUG_RPF)
- log(LOG_DEBUG, 0, " gateway is: %s",
- inet_ntop(AF_INET6, &sin6->sin6_addr, in6txt, INET6_ADDRSTRLEN));
- rpfinfop->rpfneighbor = *sin6;
-
- if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
-#if 0
- rpfinfop->rpfneighbor.sin6_scope_id =
- ntohs(*(u_int16_t *)&sin6->sin6_addr.s6_addr[2]);
-#endif
- rpfinfop->rpfneighbor.sin6_scope_id = ifp->sdl_index;
- /*
- * XXX: KAME kernel embeds the interface index to the address.
- * Clear the index for safety.
- */
- rpfinfop->rpfneighbor.sin6_addr.s6_addr[2] = 0;
- rpfinfop->rpfneighbor.sin6_addr.s6_addr[3] = 0;
- }
- }
-
- for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v)
- /* get the number of the interface by matching the name */
- if ((strlen(v->uv_name) == ifp->sdl_nlen) &&
- !(strncmp(v->uv_name,ifp->sdl_data,ifp->sdl_nlen)))
- break;
-
- IF_DEBUG(DEBUG_RPF)
- log(LOG_DEBUG, 0, " iif is %d", vifi);
-
- rpfinfop->iif = vifi;
-
- if (vifi >= numvifs){
- IF_DEBUG(DEBUG_RPF)
- log(LOG_DEBUG, 0,
- "Invalid incoming interface for destination %s, because of invalid virtual interface",
- inet_ntop(AF_INET6, &sin6->sin6_addr, in6txt, INET6_ADDRSTRLEN));
- return(FALSE);/* invalid iif */
- }
-
- return(TRUE);
-}
-
-
-#else /* HAVE_ROUTING_SOCKETS */
-
-
-/*
- * Return in rpfcinfo the incoming interface and the next hop router
- * toward source.
- */
-/* TODO: check whether next hop router address is in network or host order */
-int
-k_req_incoming(source, rpfcinfo)
- struct sockaddr_in6 *source;
- struct rpfctl *rpfcinfo;
-{
- rpfcinfo->source = *source;
- rpfcinfo->iif = NO_VIF; /* just initialized, will be */
- /* changed in kernel */
- memset(&rpfcinfo->rpfneighbor, 0, sizeof(rpfcinfo->rpfneighbor)); /* initialized */
-
- if (ioctl(udp_socket, SIOCGETRPF, (char *) rpfcinfo) < 0){
- log(LOG_ERR, errno, "ioctl SIOCGETRPF k_req_incoming");
- return(FALSE);
- }
- return (TRUE);
-}
-
-#endif /* HAVE_ROUTING_SOCKETS */
-
diff --git a/usr.sbin/pim6dd/timer.c b/usr.sbin/pim6dd/timer.c
deleted file mode 100644
index a27b9d4..0000000
--- a/usr.sbin/pim6dd/timer.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * Copyright (c) 1998 by the University of Oregon.
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation in source and binary forms for lawful
- * purposes and without fee is hereby granted, provided
- * that the above copyright notice appear in all copies and that both
- * the copyright notice and this permission notice appear in supporting
- * documentation, and that any documentation, advertising materials,
- * and other materials related to such distribution and use acknowledge
- * that the software was developed by the University of Oregon.
- * The name of the University of Oregon may not be used to endorse or
- * promote products derived from this software without specific prior
- * written permission.
- *
- * THE UNIVERSITY OF OREGON DOES NOT MAKE ANY REPRESENTATIONS
- * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. THIS SOFTWARE IS
- * PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
- * NON-INFRINGEMENT.
- *
- * IN NO EVENT SHALL UO, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT,
- * TORT, OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH,
- * THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Other copyrights might apply to parts of this software and are so
- * noted when applicable.
- */
-/*
- * Questions concerning this software should be directed to
- * Kurt Windisch (kurtw@antc.uoregon.edu)
- *
- * $Id: timer.c,v 1.6 2000/10/05 22:20:38 itojun Exp $
- */
-/*
- * Part of this program has been derived from PIM sparse-mode pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- * The pimd program is COPYRIGHT 1998 by University of Southern California.
- *
- * Part of this program has been derived from mrouted.
- * The mrouted program is covered by the license in the accompanying file
- * named "LICENSE.mrouted".
- *
- * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
- * Leland Stanford Junior University.
- *
- * $FreeBSD$
- */
-
-#include "defs.h"
-
-
-/*
- * Global variables
- */
-
-/*
- * Local functions definitions.
- */
-
-
-/*
- * Local variables
- */
-u_int16 unicast_routing_timer; /* Used to check periodically for any
- * change in the unicast routing.
- */
-u_int16 unicast_routing_check_interval;
-u_int8 ucast_flag; /* Used to indicate there was a timeout */
-
-
-/* to request and compare any route changes */
-srcentry_t srcentry_save;
-
-/*
- * Init some timers
- */
-void
-init_timers()
-{
- unicast_routing_check_interval = UCAST_ROUTING_CHECK_INTERVAL;
- unicast_routing_timer = unicast_routing_check_interval;
-
- /* Initialize the srcentry used to save the old routes
- * during unicast routing change discovery process.
- */
- srcentry_save.prev = (srcentry_t *)NULL;
- srcentry_save.next = (srcentry_t *)NULL;
- memset(&srcentry_save.address, 0, sizeof(struct sockaddr_in6));
- srcentry_save.address.sin6_len = sizeof(struct sockaddr_in6);
- srcentry_save.address.sin6_family= AF_INET6;
- srcentry_save.mrtlink = (mrtentry_t *)NULL;
- srcentry_save.incoming = NO_VIF;
- srcentry_save.upstream = (pim_nbr_entry_t *)NULL;
- srcentry_save.metric = ~0;
- srcentry_save.preference = ~0;
- srcentry_save.timer = 0;
-
-}
-
-/*
- * On every timer interrupt, advance (i.e. decrease) the timer for each
- * neighbor and group entry for each vif.
- */
-void
-age_vifs()
-{
- vifi_t vifi;
- register struct uvif *v;
- register pim_nbr_entry_t *next_nbr, *curr_nbr;
-
-/* XXX: TODO: currently, sending to qe* interface which is DOWN
- * doesn't return error (ENETDOWN) on my Solaris machine,
- * so have to check periodically the
- * interfaces status. If this is fixed, just remove the defs around
- * the "if (vifs_down)" line.
- */
-
-#if (!((defined SunOS) && (SunOS >= 50)))
- if (vifs_down)
-#endif /* Solaris */
- check_vif_state();
-
- /* Age many things */
- for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
- if (v->uv_flags & (VIFF_DISABLED | VIFF_DOWN))
- continue;
-
- /* Timeout the MLD querier (unless we re the querier) */
- if ((v->uv_flags & VIFF_QUERIER) == 0 &&
- v->uv_querier) { /* this must be non-NULL, but check for safety. */
- IF_TIMEOUT(v->uv_querier->al_timer) {
- /* act as a querier by myself */
- v->uv_flags |= VIFF_QUERIER;
- v->uv_querier->al_addr = v->uv_linklocal->pa_addr;
- v->uv_querier->al_timer = MLD6_OTHER_QUERIER_PRESENT_INTERVAL;
- time(&v->uv_querier->al_ctime); /* reset timestamp */
- query_groups(v);
- }
- }
-
- /* Timeout neighbors */
- for (curr_nbr = v->uv_pim_neighbors; curr_nbr != NULL;
- curr_nbr = next_nbr) {
- next_nbr = curr_nbr->next;
- /*
- * Never timeout neighbors with holdtime = 0xffff.
- * This may be used with ISDN lines to avoid keeping the
- * link up with periodic Hello messages.
- */
- if (PIM_MESSAGE_HELLO_HOLDTIME_FOREVER == curr_nbr->timer)
- continue;
- IF_NOT_TIMEOUT(curr_nbr->timer)
- continue;
-
- delete_pim6_nbr(curr_nbr);
- }
-
- /* PIM_HELLO periodic */
- IF_TIMEOUT(v->uv_pim_hello_timer)
- send_pim6_hello(v, PIM_TIMER_HELLO_HOLDTIME);
-
- /* MLD query periodic */
- IF_TIMEOUT(v->uv_gq_timer)
- query_groups(v);
- }
-
- IF_DEBUG(DEBUG_IF) {
- dump_vifs(stderr);
- dump_lcl_grp(stderr);
- }
-}
-
-
-/*
- * Scan the whole routing table and timeout a bunch of timers:
- * - prune timers
- * - Join/Prune delay timer
- * - routing entry
- * - Assert timer
- */
-void
-age_routes()
-{
- mrtentry_t *mrtentry_ptr, *mrtentry_next;
- grpentry_t *grpentry_ptr, *grpentry_next;
- vifi_t vifi;
- int change_flag, state_change;
- int update_src_iif;
- u_long curr_bytecnt;
-
- /*
- * Timing out of the global `unicast_routing_timer` and data rate timer
- */
- IF_TIMEOUT(unicast_routing_timer) {
- ucast_flag = TRUE;
- unicast_routing_timer = unicast_routing_check_interval;
- }
- ELSE {
- ucast_flag = FALSE;
- }
-
- /* Walk the (S,G) entries */
- if(grplist == (grpentry_t *)NULL)
- return;
- for(grpentry_ptr = grplist;
- grpentry_ptr != (grpentry_t *)NULL;
- grpentry_ptr = grpentry_next) {
- grpentry_next = grpentry_ptr->next;
-
- for(mrtentry_ptr = grpentry_ptr->mrtlink;
- mrtentry_ptr != (mrtentry_t *)NULL;
- mrtentry_ptr = mrtentry_next) {
- mrtentry_next = mrtentry_ptr->grpnext;
-
- /* Refresh entry timer if data forwarded */
- curr_bytecnt = mrtentry_ptr->sg_count.bytecnt;
- if (k_get_sg_cnt(udp_socket,
- &mrtentry_ptr->source->address,
- &mrtentry_ptr->group->group,
- &mrtentry_ptr->sg_count)) {
- /* No such routing entry in kernel */
- delete_mrtentry(mrtentry_ptr);
- continue;
- }
- if(!(IF_ISEMPTY(&mrtentry_ptr->oifs)) &&
- curr_bytecnt != mrtentry_ptr->sg_count.bytecnt) {
- /* Packets have been forwarded - refresh timer
- * Note that these counters count packets received,
- * not packets forwarded. So only refresh if packets
- * received and non-null oiflist.
- */
- IF_DEBUG(DEBUG_MFC)
- log(LOG_DEBUG, 0,
- "Refreshing src %s, dst %s after %ld bytes forwarded",
- inet6_fmt(&mrtentry_ptr->source->address.sin6_addr),
- inet6_fmt(&mrtentry_ptr->group->group.sin6_addr),
- mrtentry_ptr->sg_count.bytecnt);
- SET_TIMER(mrtentry_ptr->timer, PIM_DATA_TIMEOUT);
- }
-
- /* Time out the entry */
- IF_TIMEOUT(mrtentry_ptr->timer) {
- delete_mrtentry(mrtentry_ptr);
- continue;
- }
-
- /* Time out asserts */
- if(mrtentry_ptr->flags & MRTF_ASSERTED)
- IF_TIMEOUT(mrtentry_ptr->assert_timer) {
- mrtentry_ptr->flags &= ~MRTF_ASSERTED;
- mrtentry_ptr->upstream = mrtentry_ptr->source->upstream;
- mrtentry_ptr->metric = mrtentry_ptr->source->metric;
- mrtentry_ptr->preference = mrtentry_ptr->source->preference;
- }
-
- /* Time out Pruned interfaces */
- change_flag = FALSE;
- for (vifi = 0; vifi < numvifs; vifi++) {
- if (IF_ISSET(vifi, &mrtentry_ptr->pruned_oifs))
- IF_TIMEOUT(mrtentry_ptr->prune_timers[vifi]) {
- IF_CLR(vifi, &mrtentry_ptr->pruned_oifs);
- SET_TIMER(mrtentry_ptr->prune_timers[vifi], 0);
- change_flag = TRUE;
- }
- }
-
- /* Unicast Route changes */
- update_src_iif = FALSE;
- if (ucast_flag == TRUE) {
- /* iif toward the source */
- srcentry_save.incoming = mrtentry_ptr->source->incoming;
- srcentry_save.upstream = mrtentry_ptr->source->upstream;
- srcentry_save.preference = mrtentry_ptr->source->preference;
- srcentry_save.metric = mrtentry_ptr->source->metric;
-
- if (set_incoming(mrtentry_ptr->source,
- PIM_IIF_SOURCE) != TRUE) {
- /*
- * XXX: not in the spec!
- * Cannot find route toward that source.
- * This is bad. Delete the entry.
- */
- delete_mrtentry(mrtentry_ptr);
- continue;
- }
- else {
- /* iif info found */
- if (!(mrtentry_ptr->flags & MRTF_ASSERTED) &&
- ((srcentry_save.incoming !=
- mrtentry_ptr->incoming)
- || (srcentry_save.upstream !=
- mrtentry_ptr->upstream))) {
- /* Route change has occur */
- update_src_iif = TRUE;
- mrtentry_ptr->incoming =
- mrtentry_ptr->source->incoming;
- mrtentry_ptr->upstream =
- mrtentry_ptr->source->upstream;
- /* mrtentry should have pref/metric of upstream
- * assert winner, but we dont have that info,
- * so use the source pref/metric, which will be
- * larger and thus the correct assert winner
- * from upstream will be chosen.
- */
- mrtentry_ptr->preference =
- mrtentry_ptr->source->preference;
- mrtentry_ptr->metric =
- mrtentry_ptr->source->metric;
- }
- }
- }
-
- if ((change_flag == TRUE) || (update_src_iif == TRUE)) {
- /* Flush the changes */
- state_change =
- change_interfaces(mrtentry_ptr,
- mrtentry_ptr->incoming,
- &mrtentry_ptr->pruned_oifs,
- &mrtentry_ptr->leaves,
- &mrtentry_ptr->asserted_oifs);
- if(state_change == -1)
- trigger_prune_alert(mrtentry_ptr);
- }
- }
- }
-
- IF_DEBUG(DEBUG_PIM_MRT)
- dump_pim_mrt(stderr);
- return;
-}
diff --git a/usr.sbin/pim6dd/trace.c b/usr.sbin/pim6dd/trace.c
deleted file mode 100644
index 7d1f641..0000000
--- a/usr.sbin/pim6dd/trace.c
+++ /dev/null
@@ -1,540 +0,0 @@
-/*
- * Copyright (C) 1999 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-/*
- * Copyright (c) 1998 by the University of Southern California.
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation in source and binary forms for lawful
- * non-commercial purposes and without fee is hereby granted, provided
- * that the above copyright notice appear in all copies and that both
- * the copyright notice and this permission notice appear in supporting
- * documentation, and that any documentation, advertising materials,
- * and other materials related to such distribution and use acknowledge
- * that the software was developed by the University of Southern
- * California and/or Information Sciences Institute.
- * The name of the University of Southern California may not
- * be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THE UNIVERSITY OF SOUTHERN CALIFORNIA DOES NOT MAKE ANY REPRESENTATIONS
- * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. THIS SOFTWARE IS
- * PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
- * NON-INFRINGEMENT.
- *
- * IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT,
- * TORT, OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH,
- * THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Other copyrights might apply to parts of this software and are so
- * noted when applicable.
- */
-/*
- * Questions concerning this software should be directed to
- * Pavlin Ivanov Radoslavov (pavlin@catarina.usc.edu)
- *
- * $Id: trace.c,v 1.5 1999/09/16 08:46:00 jinmei Exp $
- */
-/*
- * Part of this program has been derived from mrouted.
- * The mrouted program is covered by the license in the accompanying file
- * named "LICENSE.mrouted".
- *
- * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
- * Leland Stanford Junior University.
- *
- * $FreeBSD$
- */
-
-
-#include "defs.h"
-#include "trace.h"
-
-/* TODO */
-/*
- * Traceroute function which returns traceroute replies to the requesting
- * router. Also forwards the request to downstream routers.
- */
-void
-accept_mtrace(src, dst, group, ifindex, data, no, datalen)
- struct sockaddr_in6 *src;
- struct in6_addr *dst;
- struct in6_addr *group;
- int ifindex;
- char *data;
- u_int no; /* promoted u_char */
- int datalen;
-{
- u_char type;
- mrtentry_t *mrt;
- struct tr6_query *qry;
- struct tr6_resp *resp;
- int vifi, ovifi;
- char *p;
- int rcount;
- int errcode = TR_NO_ERR;
- int resptype;
- struct timeval tp;
- struct sioc_mif_req6 mreq;
- struct in6_addr parent_address;
- struct sockaddr_in6 src_sa6 = {sizeof(src_sa6), AF_INET6};
- struct sockaddr_in6 dst_sa6 = {sizeof(dst_sa6), AF_INET6};
- struct sockaddr_in6 resp_sa6 = {sizeof(resp_sa6), AF_INET6};
- struct sockaddr_in6 grp_sa6 = {sizeof(grp_sa6), AF_INET6};
- struct sockaddr_in6 *sa_global;
-#ifdef SM_ONLY
- rpentry_t *rpentry_ptr;
-#endif
-
- /* Remember qid across invocations */
- static u_int32 oqid = 0;
-
- /* timestamp the request/response */
- gettimeofday(&tp, 0);
-
- /*
- * Check if it is a query or a response
- */
- if (datalen == QLEN) {
- type = QUERY;
- IF_DEBUG(DEBUG_TRACE)
- log(LOG_DEBUG, 0, "Initial traceroute query rcvd "
- "from %s to %s",
- inet6_fmt(&src->sin6_addr),
- inet6_fmt(dst));
- }
- else if ((datalen - QLEN) % RLEN == 0) {
- type = RESP;
- IF_DEBUG(DEBUG_TRACE)
- log(LOG_DEBUG, 0, "In-transit traceroute query rcvd "
- "from %s to %s",
- inet6_fmt(&src->sin6_addr),
- inet6_fmt(dst));
- if (IN6_IS_ADDR_MULTICAST(dst)) {
- IF_DEBUG(DEBUG_TRACE)
- log(LOG_DEBUG, 0, "Dropping multicast response");
- return;
- }
- }
- else {
- log(LOG_WARNING, 0, "%s from %s to %s",
- "Non decipherable traceroute request recieved",
- inet6_fmt(&src->sin6_addr), inet6_fmt(dst));
- return;
- }
-
- qry = (struct tr6_query *)data;
- src_sa6.sin6_addr = qry->tr_src;
- src_sa6.sin6_scope_id =
- (IN6_IS_ADDR_LINKLOCAL(&qry->tr_src)
- || IN6_IS_ADDR_MC_LINKLOCAL(&qry->tr_src)) ? ifindex : 0;
- dst_sa6.sin6_addr = qry->tr_dst;
- dst_sa6.sin6_scope_id =
- (IN6_IS_ADDR_LINKLOCAL(&qry->tr_dst)
- || IN6_IS_ADDR_MC_LINKLOCAL(&qry->tr_dst)) ? ifindex : 0;
- grp_sa6.sin6_addr = *group;
- grp_sa6.sin6_scope_id = 0;
-
- /*
- * if it is a packet with all reports filled, drop it
- */
- if ((rcount = (datalen - QLEN)/RLEN) == no) {
- IF_DEBUG(DEBUG_TRACE)
- log(LOG_DEBUG, 0, "packet with all reports filled in");
- return;
- }
-
- IF_DEBUG(DEBUG_TRACE) {
- log(LOG_DEBUG, 0, "s: %s g: %s d: %s ",
- inet6_fmt(&qry->tr_src),
- inet6_fmt(group), inet6_fmt(&qry->tr_dst));
- log(LOG_DEBUG, 0, "rhlim: %d rd: %s", qry->tr_rhlim,
- inet6_fmt(&qry->tr_raddr));
- log(LOG_DEBUG, 0, "rcount:%d, qid:%06x", rcount, qry->tr_qid);
- }
-
- /* determine the routing table entry for this traceroute */
- mrt = find_route(&src_sa6, &grp_sa6, MRTF_SG | MRTF_WC | MRTF_PMBR,
- DONT_CREATE);
- IF_DEBUG(DEBUG_TRACE) {
- if (mrt != (mrtentry_t *)NULL) {
- if (mrt->upstream != (pim_nbr_entry_t *)NULL)
- parent_address = mrt->upstream->address.sin6_addr;
- else
- parent_address = in6addr_any;
- log(LOG_DEBUG, 0,
- "mrt parent mif: %d rtr: %s metric: %d",
- mrt->incoming,
- inet6_fmt(&parent_address), mrt->metric);
- /* TODO
- log(LOG_DEBUG, 0, "mrt origin %s",
- RT_FMT(rt, s1));
- */
- } else
- log(LOG_DEBUG, 0, "...no route");
- }
-
- /*
- * Query type packet - check if rte exists
- * Check if the query destination is a vif connected to me.
- * and if so, whether I should start response back
- */
- if (type == QUERY) {
- if (oqid == qry->tr_qid) {
- /*
- * If the multicast router is a member of the group
- * being queried, and the query is multicasted,
- * then the router can recieve multiple copies of
- * the same query. If we have already replied to
- * this traceroute, just ignore it this time.
- *
- * This is not a total solution, but since if this
- * fails you only get N copies, N <= the number of
- * interfaces on the router, it is not fatal.
- */
- IF_DEBUG(DEBUG_TRACE)
- log(LOG_DEBUG, 0,
- "ignoring duplicate traceroute packet");
- return;
- }
-
- if (mrt == (mrtentry_t *)NULL) {
- IF_DEBUG(DEBUG_TRACE)
- log(LOG_DEBUG, 0,
- "Mcast traceroute: no route entry %s",
- inet6_fmt(&qry->tr_src));
-#if 0
- if (IN6_IS_ADDR_MULTICAST(dst))
- return;
-#endif
- }
- vifi = find_vif_direct(&dst_sa6);
-
- if (vifi == NO_VIF) {
- /*
- * The traceroute destination is not on one of
- * my subnet vifs.
- */
- IF_DEBUG(DEBUG_TRACE)
- log(LOG_DEBUG, 0,
- "Destination %s not an interface",
- inet6_fmt(&qry->tr_dst));
- if (IN6_IS_ADDR_MULTICAST(dst))
- return;
- errcode = TR_WRONG_IF;
- } else if (mrt != (mrtentry_t *)NULL &&
- !IF_ISSET(vifi, &mrt->oifs)) {
- IF_DEBUG(DEBUG_TRACE)
- log(LOG_DEBUG, 0,
- "Destination %s not on forwarding tree "
- "for src %s",
- inet6_fmt(&qry->tr_dst),
- inet6_fmt(&qry->tr_src));
- if (IN6_IS_ADDR_MULTICAST(dst))
- return;
- errcode = TR_WRONG_IF;
- }
- }
- else {
- /*
- * determine which interface the packet came in on
- * RESP packets travel hop-by-hop so this either traversed
- * a tunnel or came from a directly attached mrouter.
- */
- if ((vifi = find_vif_direct(src)) == NO_VIF) {
- IF_DEBUG(DEBUG_TRACE)
- log(LOG_DEBUG, 0,
- "Wrong interface for packet");
- errcode = TR_WRONG_IF;
- }
- }
-
- /* Now that we've decided to send a response, save the qid */
- oqid = qry->tr_qid;
-
- IF_DEBUG(DEBUG_TRACE)
- log(LOG_DEBUG, 0, "Sending traceroute response");
-
- /* copy the packet to the sending buffer */
- p = mld6_send_buf + sizeof(struct mld6_hdr);
-
- bcopy(data, p, datalen);
-
- p += datalen;
-
- /*
- * If there is no room to insert our reply, coopt the previous hop
- * error indication to relay this fact.
- */
- if (p + sizeof(struct tr6_resp) > mld6_send_buf + RECV_BUF_SIZE) {
- resp = (struct tr6_resp *)p - 1;
- resp->tr_rflags = TR_NO_SPACE;
- mrt = NULL;
- goto sendit;
- }
-
- /*
- * fill in initial response fields
- */
- resp = (struct tr6_resp *)p;
- bzero(resp, sizeof(struct tr6_resp));
- datalen += (RLEN + sizeof(struct mld6_hdr));
-
- resp->tr_qarr = htonl(((tp.tv_sec + JAN_1970) << 16) +
- ((tp.tv_usec << 10) / 15625));
-
- resp->tr_rproto = PROTO_PIM;
- resp->tr_outifid = (vifi == NO_VIF) ? TR_NO_VIF : htonl(vifi);
- resp->tr_rflags = errcode;
- if ((sa_global = max_global_address()) == NULL) /* impossible */
- log(LOG_ERR, 0, "acept_mtrace: max_global_address returns NULL");
- resp->tr_lcladdr = sa_global->sin6_addr;
-
- /*
- * obtain # of packets out on interface
- */
- mreq.mifi = vifi;
- if (vifi != NO_VIF &&
- ioctl(udp_socket, SIOCGETMIFCNT_IN6, (char *)&mreq) >= 0)
- resp->tr_vifout = htonl(mreq.ocount);
- else
- resp->tr_vifout = 0xffffffff;
-
- /*
- * fill in scoping & pruning information
- */
- /* TODO */
-#if 0
- if (mrt != (mrtentry_t *)NULL)
- for (gt = rt->rt_groups; gt; gt = gt->gt_next) {
- if (gt->gt_mcastgrp >= group)
- break;
- }
- else
- gt = NULL;
-
- if (gt && gt->gt_mcastgrp == group) {
- struct stable *st;
-
- for (st = gt->gt_srctbl; st; st = st->st_next)
- if (qry->tr_src == st->st_origin)
- break;
-
- sg_req.src.s_addr = qry->tr_src;
- sg_req.grp.s_addr = group;
- if (st && st->st_ctime != 0 &&
- ioctl(udp_socket, SIOCGETSGCNT, (char *)&sg_req) >= 0)
- resp->tr_pktcnt = htonl(sg_req.pktcnt + st->st_savpkt);
- else
- resp->tr_pktcnt = htonl(st ? st->st_savpkt : 0xffffffff);
-
- if (VIFM_ISSET(vifi, gt->gt_scope))
- resp->tr_rflags = TR_SCOPED;
- else if (gt->gt_prsent_timer)
- resp->tr_rflags = TR_PRUNED;
- else if (!VIFM_ISSET(vifi, gt->gt_grpmems))
- if (VIFM_ISSET(vifi, rt->rt_children) &&
- NBRM_ISSETMASK(uvifs[vifi].uv_nbrmap,
- rt->rt_subordinates)) /*XXX*/
- resp->tr_rflags = TR_OPRUNED;
- else
- resp->tr_rflags = TR_NO_FWD;
- } else {
- if (scoped_addr(vifi, group))
- resp->tr_rflags = TR_SCOPED;
- else if (rt && !VIFM_ISSET(vifi, rt->rt_children))
- resp->tr_rflags = TR_NO_FWD;
- }
-#endif /* 0 */
-
- /*
- * if no rte exists, set NO_RTE error
- */
- if (mrt == (mrtentry_t *)NULL) {
- src->sin6_addr = *dst; /* the dst address of resp. pkt */
- resp->tr_inifid = TR_NO_VIF;
- resp->tr_rflags = TR_NO_RTE;
- memset(&resp->tr_rmtaddr, 0, sizeof(struct in6_addr));
- } else {
- /* get # of packets in on interface */
- mreq.mifi = mrt->incoming;
- if (ioctl(udp_socket, SIOCGETMIFCNT_IN6, (char *)&mreq) >= 0)
- resp->tr_vifin = htonl(mreq.icount);
- else
- resp->tr_vifin = 0xffffffff;
-
- /*
- * TODO
- * MASK_TO_VAL(rt->rt_originmask, resp->tr_smask);
- */
- resp->tr_inifid = htonl(mrt->incoming);
- if (mrt->upstream != (pim_nbr_entry_t *)NULL)
- parent_address = mrt->upstream->address.sin6_addr;
- else
- parent_address = in6addr_any;
-
- resp->tr_rmtaddr = parent_address;
- if (!IF_ISSET(vifi, &mrt->oifs)) {
- IF_DEBUG(DEBUG_TRACE)
- log(LOG_DEBUG, 0,
- "Destination %s not on forwarding tree "
- "for src %s",
- inet6_fmt(&qry->tr_dst),
- inet6_fmt(&qry->tr_src));
- resp->tr_rflags = TR_WRONG_IF;
- }
-#if 0
- if (rt->rt_metric >= UNREACHABLE) {
- resp->tr_rflags = TR_NO_RTE;
- /* Hack to send reply directly */
- rt = NULL;
- }
-#endif /* 0 */
- }
-
-#ifdef SM_ONLY
- /*
- * If we're the RP for the trace group, note it.
- */
- rpentry_ptr = rp_match(&grp_sa6);
- if (rpentry_ptr && local_address(&rpentry_ptr->address) != NO_VIF)
- resp->tr_rflags = TR_RP;
-#endif /* SM_ONLY */
-
- sendit:
- /*
- * if metric is 1 or no. of reports is 1, send response to requestor
- * else send to upstream router. If the upstream router can't handle
- * mtrace, set an error code and send to requestor anyway.
- */
- IF_DEBUG(DEBUG_TRACE)
- log(LOG_DEBUG, 0, "rcount:%d, no:%d", rcount, no);
-
- ovifi = NO_VIF; /* unspecified */
- if ((rcount + 1 == no) || (mrt == NULL) || (mrt->metric == 1)) {
- resptype = MLD6_MTRACE_RESP;
- resp_sa6.sin6_addr = qry->tr_raddr;
- if (IN6_IS_ADDR_LINKLOCAL(&resp_sa6.sin6_addr) ||
- IN6_IS_ADDR_MC_LINKLOCAL(&resp_sa6.sin6_addr)) {
- if ((ovifi = find_vif_direct(&dst_sa6)) == NO_VIF) {
- log(LOG_INFO, 0,
- "can't determine outgoing i/f for mtrace "
- "response.");
- return;
- }
- }
- } else
- /* TODO */
- {
-#if 0
- if (!can_mtrace(rt->rt_parent, rt->rt_gateway)) {
- resp_sa6.sin6_addr = qry->tr_raddr;
- resp->tr_rflags = TR_OLD_ROUTER;
- resptype = MLD6_MTRACE_RESP;
- } else
-#endif /* 0 */
-#ifdef SM_ONLY
- if (mrt->incoming &&
- (uvifs[mrt->incoming].uv_flags & MIFF_REGISTER)) {
- log(LOG_DEBUG, 0,
- "incoming i/f is for register. "
- "Can't be forwarded anymore.");
- resp_sa6.sin6_addr = qry->tr_raddr;
- resptype = MLD6_MTRACE_RESP;
- } else
-#endif /* SM_ONLY */
- {
- if (mrt->upstream != (pim_nbr_entry_t *)NULL)
- parent_address =
- mrt->upstream->address.sin6_addr;
- else
- parent_address = allrouters_group.sin6_addr;
- resp_sa6.sin6_addr = parent_address;
- ovifi = mrt->incoming;
- resptype = MLD6_MTRACE;
- }
- }
-
- if (IN6_IS_ADDR_MULTICAST(&resp_sa6.sin6_addr)) {
- struct sockaddr_in6 *sa6;
-
- /*
- * Send the reply on a known multicast capable vif.
- * If we don't have one, we can't source any
- * multicasts anyway.
- */
- if (IN6_IS_ADDR_MC_LINKLOCAL(&resp_sa6.sin6_addr)) {
- sa6 = &uvifs[ovifi].uv_linklocal->pa_addr;
- ifindex = uvifs[ovifi].uv_ifindex;
- }
- else {
- if (phys_vif != -1 &&
- (sa6 = uv_global(phys_vif)) != NULL) {
- IF_DEBUG(DEBUG_TRACE)
- log(LOG_DEBUG, 0,
- "Sending reply to %s from %s",
- inet6_fmt(dst),
- inet6_fmt(&sa6->sin6_addr));
- ifindex = uvifs[phys_vif].uv_ifindex;
- }
- else {
- log(LOG_INFO, 0, "No enabled phyints -- %s",
- "dropping traceroute reply");
- return;
- }
- }
- k_set_hlim(mld6_socket, qry->tr_rhlim);
- send_mld6(resptype, no, sa6, &resp_sa6, group,
- ifindex, 0, datalen, 0);
- k_set_hlim(mld6_socket, 1);
- } else {
- struct sockaddr_in6 *sa6 = NULL;
- ifindex = -1; /* unspecified by default */
-
- if (IN6_IS_ADDR_LINKLOCAL(&resp_sa6.sin6_addr)) {
- /* ovifi must be valid in this case */
- ifindex = uvifs[ovifi].uv_ifindex;
- sa6 = &uvifs[ovifi].uv_linklocal->pa_addr;
- }
-
- IF_DEBUG(DEBUG_TRACE)
- log(LOG_DEBUG, 0, "Sending %s to %s from %s",
- resptype == MLD6_MTRACE_RESP ?
- "reply" : "request on",
- inet6_fmt(dst),
- sa6 ? inet6_fmt(&sa6->sin6_addr) : "unspecified");
-
- send_mld6(resptype, no, sa6, &resp_sa6, group, ifindex,
- 0, datalen, 0);
- }
- return;
-}
diff --git a/usr.sbin/pim6dd/trace.h b/usr.sbin/pim6dd/trace.h
deleted file mode 100644
index 739c987..0000000
--- a/usr.sbin/pim6dd/trace.h
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (C) 1999 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-/*
- * Copyright (c) 1998 by the University of Southern California.
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation in source and binary forms for lawful
- * purposes and without fee is hereby granted, provided
- * that the above copyright notice appear in all copies and that both
- * the copyright notice and this permission notice appear in supporting
- * documentation, and that any documentation, advertising materials,
- * and other materials related to such distribution and use acknowledge
- * that the software was developed by the University of Southern
- * California and/or Information Sciences Institute.
- * The name of the University of Southern California may not
- * be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THE UNIVERSITY OF SOUTHERN CALIFORNIA DOES NOT MAKE ANY REPRESENTATIONS
- * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. THIS SOFTWARE IS
- * PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
- * NON-INFRINGEMENT.
- *
- * IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT,
- * TORT, OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH,
- * THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Other copyrights might apply to parts of this software and are so
- * noted when applicable.
- */
-/*
- * Questions concerning this software should be directed to
- * Pavlin Ivanov Radoslavov (pavlin@catarina.usc.edu)
- *
- * $Id: trace.h,v 1.2 1999/09/12 17:00:10 jinmei Exp $
- */
-/*
- * Part of this program has been derived from mrouted.
- * The mrouted program is covered by the license in the accompanying file
- * named "LICENSE.mrouted".
- *
- * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
- * Leland Stanford Junior University.
- *
- * $FreeBSD$
- */
-
-
-/*
- * The packet format for a traceroute request.
- */
-struct tr6_query {
- struct in6_addr tr_src; /* traceroute source */
- struct in6_addr tr_dst; /* traceroute destination */
- struct in6_addr tr_raddr; /* traceroute response address */
-#if defined(BYTE_ORDER) && (BYTE_ORDER == LITTLE_ENDIAN)
- struct {
- u_int32_t qid : 24; /* traceroute query id */
- u_int32_t rhlim : 8; /* traceroute response ttl */
- } q;
-#else
- struct {
- u_int32_t rhlim : 8; /* traceroute response ttl */
- u_int32_t qid : 24; /* traceroute query id */
- } q;
-#endif /* BYTE_ORDER */
-};
-
-#define tr_rhlim q.rhlim
-#define tr_qid q.qid
-
-/*
- * Traceroute response format. A traceroute response has a tr_query at the
- * beginning, followed by one tr_resp for each hop taken.
- */
-struct tr6_resp {
- u_int32_t tr_qarr; /* query arrival time */
-#if 0
- struct in6_addr tr_inaddr; /* incoming interface address */
- struct in6_addr tr_outaddr; /* outgoing interface address */
-#endif
- u_int32_t tr_inifid; /* incoming interface identifier */
- u_int32_t tr_outifid; /* outgoing interface identifier */
- struct in6_addr tr_lcladdr; /* router's address(must have largest scope) */
- struct in6_addr tr_rmtaddr; /* parent address in source tree */
- u_int32_t tr_vifin; /* input packet count on interface */
- u_int32_t tr_vifout; /* output packet count on interface */
- u_int32_t tr_pktcnt; /* total incoming packets for src-grp */
- u_char tr_rproto; /* routing protocol deployed on router */
-#if 0
- u_char tr_fhlim; /* hop limit required to forward on outvif */
-#endif
- u_char tr_flags; /* flags */
- u_char tr_plen; /* prefix length for src addr */
- u_char tr_rflags; /* forwarding error codes */
-};
-
-/* defs within mtrace */
-#define QUERY 1
-#define RESP 2
-#define QLEN sizeof(struct tr6_query)
-#define RLEN sizeof(struct tr6_resp)
-
-/* fields for tr_inifid and tr_outifid */
-#define TR_NO_VIF 0xffffffff/* interface can't be determined */
-
-/* fields for tr_rflags (forwarding error codes) */
-#define TR_NO_ERR 0 /* No error */
-#define TR_WRONG_IF 1 /* traceroute arrived on non-oif */
-#define TR_PRUNED 2 /* router has sent a prune upstream */
-#define TR_OPRUNED 3 /* stop forw. after request from next hop rtr*/
-#define TR_SCOPED 4 /* group adm. scoped at this hop */
-#define TR_NO_RTE 5 /* no route for the source */
-#define TR_NO_LHR 6 /* not the last-hop router */
-#define TR_NO_FWD 7 /* not forwarding for this (S,G). Reason = ? */
-#define TR_RP 8 /* I am the RP/Core */
-#define TR_IIF 9 /* request arrived on the iif */
-#define TR_NO_MULTI 0x0a /* multicast disabled on that interface */
-#define TR_NO_SPACE 0x81 /* no space to insert responce data block */
-#define TR_OLD_ROUTER 0x82 /* previous hop does not support traceroute */
-#define TR_ADMIN_PROHIB 0x83 /* traceroute adm. prohibited */
-
-/* fields for tr_flags */
-#define TR_SUBNET_COUNT 0x80 /* pkt count for (S,G) is for source network */
-
-/* fields for r_plen */
-#define TR_GROUP_ONLY 0xff /* forwarding solely on group state */
-
-/* fields for packets count */
-#define TR_CANT_COUNT 0xffffffff /* no count can be reported */
-
-/* fields for tr_rproto (routing protocol) */
-#define PROTO_DVMRP 1
-#define PROTO_MOSPF 2
-#define PROTO_PIM 3
-#define PROTO_CBT 4
-#define PROTO_PIM_SPECIAL 5
-#define PROTO_PIM_STATIC 6
-#define PROTO_DVMRP_STATIC 7
-
-#define MASK_TO_VAL(x, i) { \
- u_int32_t _x = ntohl(x); \
- (i) = 1; \
- while ((_x) <<= 1) \
- (i)++; \
- };
-
-#define VAL_TO_MASK(x, i) { \
- x = htonl(~((1 << (32 - (i))) - 1)); \
- };
-
-#define MASKLEN_TO_MASK6(masklen, mask6) \
- do {\
- u_char maskarray[8] = \
- {0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff}; \
- int bytelen, bitlen, i; \
- memset(&(mask6), 0, sizeof(mask6));\
- bytelen = (masklen) / 8;\
- bitlen = (masklen) % 8;\
- for (i = 0; i < bytelen; i++) \
- (mask6).s6_addr[i] = 0xff;\
- if (bitlen) \
- (mask6).s6_addr[bytelen] = maskarray[bitlen - 1]; \
- }while(0);
-
-/* obnoxious gcc gives an extraneous warning about this constant... */
-#if defined(__STDC__) || defined(__GNUC__)
-#define JAN_1970 2208988800UL /* 1970 - 1900 in seconds */
-#else
-#define JAN_1970 2208988800L /* 1970 - 1900 in seconds */
-#define const /**/
-#endif
-
-#define NBR_VERS(n) (((n)->al_pv << 8) + (n)->al_mv)
diff --git a/usr.sbin/pim6dd/vers.c b/usr.sbin/pim6dd/vers.c
deleted file mode 100644
index 72668af..0000000
--- a/usr.sbin/pim6dd/vers.c
+++ /dev/null
@@ -1,2 +0,0 @@
-/* $FreeBSD$ */
-char todaysversion[]="0.2.1.0-alpha15";
diff --git a/usr.sbin/pim6dd/vif.c b/usr.sbin/pim6dd/vif.c
deleted file mode 100644
index 2fa533c..0000000
--- a/usr.sbin/pim6dd/vif.c
+++ /dev/null
@@ -1,535 +0,0 @@
-/*
- * Copyright (c) 1998 by the University of Southern California.
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation in source and binary forms for lawful
- * purposes and without fee is hereby granted, provided
- * that the above copyright notice appear in all copies and that both
- * the copyright notice and this permission notice appear in supporting
- * documentation, and that any documentation, advertising materials,
- * and other materials related to such distribution and use acknowledge
- * that the software was developed by the University of Southern
- * California and/or Information Sciences Institute.
- * The name of the University of Southern California may not
- * be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THE UNIVERSITY OF SOUTHERN CALIFORNIA DOES NOT MAKE ANY REPRESENTATIONS
- * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. THIS SOFTWARE IS
- * PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
- * NON-INFRINGEMENT.
- *
- * IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT,
- * TORT, OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH,
- * THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Other copyrights might apply to parts of this software and are so
- * noted when applicable.
- */
-/*
- * Questions concerning this software should be directed to
- * Pavlin Ivanov Radoslavov (pavlin@catarina.usc.edu)
- *
- * $Id: vif.c,v 1.5 2000/05/18 15:29:40 itojun Exp $
- */
-/*
- * Part of this program has been derived from mrouted.
- * The mrouted program is covered by the license in the accompanying file
- * named "LICENSE.mrouted".
- *
- * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
- * Leland Stanford Junior University.
- *
- * $FreeBSD$
- */
-
-#include "defs.h"
-
-/*
- * Exported variables.
- */
-struct uvif uvifs[MAXMIFS]; /* array of all virtual interfaces */
-vifi_t numvifs; /* Number of vifs in use */
-int vifs_down; /* 1=>some interfaces are down */
-int phys_vif; /* An enabled vif */
-int udp_socket; /* Since the honkin' kernel doesn't support */
- /* ioctls on raw IP sockets, we need a UDP */
- /* socket as well as our IGMP (raw) socket. */
- /* How dumb. */
-int total_interfaces; /* Number of all interfaces: including the
- * non-configured, but excluding the
- * loopback interface and the non-multicast
- * capable interfaces.
- */
-if_set if_nullset; /* an interface face that has all-0 bit
- * (for comparison)
- */
-
-/*
- * Forward declarations.
- */
-static void start_vif __P((vifi_t vifi));
-static void stop_vif __P((vifi_t vifi));
-static void start_all_vifs __P((void));
-
-
-void
-init_vifs()
-{
- vifi_t vifi;
- struct uvif *v;
- int enabled_vifs;
-
- numvifs = 0;
- vifs_down = FALSE;
-
- /*
- * Configure the vifs based on the interface configuration of
- * the kernel and the contents of the configuration file.
- * (Open a UDP socket for ioctl use in the config procedures if
- * the kernel can't handle IOCTL's on the MLD socket.)
- */
-#ifdef IOCTL_OK_ON_RAW_SOCKET
- udp_socket = mld6_socket;
-#else
- if ((udp_socket = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
- log(LOG_ERR, errno, "UDP6 socket");
-#endif
-
- /*
- * Clean up all vifs
- */
- for (vifi = 0, v = uvifs; vifi < MAXMIFS; ++vifi, ++v) {
- memset(v, 0, sizeof(*v));
- v->uv_flags = 0;
- v->uv_metric = DEFAULT_METRIC;
- v->uv_admetric = 0;
- v->uv_rate_limit = DEFAULT_PHY_RATE_LIMIT;
- strncpy(v->uv_name, "", IFNAMSIZ);
- v->uv_groups = (struct listaddr *)NULL;
- v->uv_dvmrp_neighbors = (struct listaddr *)NULL;
- NBRM_CLRALL(v->uv_nbrmap);
- v->uv_querier = (struct listaddr *)NULL;
- v->uv_prune_lifetime = 0;
- v->uv_acl = (struct vif_acl *)NULL;
- v->uv_leaf_timer = 0;
- v->uv_addrs = (struct phaddr *)NULL;
- v->uv_filter = (struct vif_filter *)NULL;
- v->uv_pim_hello_timer = 0;
- v->uv_gq_timer = 0;
- v->uv_pim_neighbors = (struct pim_nbr_entry *)NULL;
- v->uv_local_pref = default_source_preference;
- v->uv_local_metric = default_source_metric;
- }
-
- log(LOG_INFO, 0, "Getting ifs from kernel");
- config_vifs_from_kernel();
- log(LOG_INFO, 0, "Getting ifs from %s", configfilename);
- config_vifs_from_file();
-
- /*
- * Quit if there are fewer than two enabled vifs or there is a vif
- * which has no link local address.
- */
- enabled_vifs = 0;
- phys_vif = -1;
-
- for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
- if (v->uv_flags & (VIFF_DISABLED | VIFF_DOWN))
- continue;
- if (v->uv_linklocal == NULL)
- log(LOG_ERR, 0,
- "there is no link-local address on vif#%d", vifi);
- if (phys_vif == -1) {
- struct phaddr *p;
-
- /*
- * If this vif has a global address, set its id
- * to phys_vif.
- */
- for(p = v->uv_addrs; p; p = p->pa_next) {
- if (!IN6_IS_ADDR_LINKLOCAL(&p->pa_addr.sin6_addr) &&
- !IN6_IS_ADDR_SITELOCAL(&p->pa_addr.sin6_addr)) {
- phys_vif = vifi;
- break;
- }
- }
- }
- enabled_vifs++;
- }
-
- if (enabled_vifs < 2)
- log(LOG_ERR, 0, "can't forward: %s",
- enabled_vifs == 0 ? "no enabled ifs" : "only one enabled if");
-
- memset(&if_nullset, 0, sizeof(if_nullset));
- k_init_pim(mld6_socket); /* Call to kernel to initiliaze structures */
-
- start_all_vifs();
-}
-
-
-static void
-start_all_vifs()
-{
- vifi_t vifi;
- struct uvif *v;
-
- for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
- /* Start vif if not DISABLED or DOWN */
- if (v->uv_flags & (VIFF_DISABLED | VIFF_DOWN)) {
- if (v->uv_flags & VIFF_DISABLED)
- log(LOG_INFO, 0,
- "%s is DISABLED; if #%u out of service",
- v->uv_name, vifi);
- else
- log(LOG_INFO, 0,
- "%s is DOWN; if #%u out of service",
- v->uv_name, vifi);
- }
- else
- start_vif(vifi);
- }
-}
-
-
-
-/*
- * stop all vifs
- */
-void
-stop_all_vifs()
-{
- vifi_t vifi;
- struct uvif *v;
-
- for (vifi = 0, v=uvifs; vifi < numvifs; ++vifi, ++v) {
- if (!(v->uv_flags & VIFF_DOWN)) {
- stop_vif(vifi);
- }
- }
-}
-
-
-/*
- * Initialize the vif and add to the kernel. The vif can be either
- * physical, tunnel (tunnels will be used in the future
- * when this code becomes PIM multicast boarder router.)
- */
-static void
-start_vif(vifi)
- vifi_t vifi;
-{
- struct uvif *v;
- u_long random_delay;
-
- v = &uvifs[vifi];
- /* Initialy no router on any vif */
- v->uv_flags = (v->uv_flags | VIFF_DR | VIFF_NONBRS) & ~VIFF_DOWN;
- v->uv_pim_hello_timer = 1 + RANDOM() % PIM_TIMER_HELLO_PERIOD;
- /* TODO: CHECK THE TIMERS!!!!! Set or reset? */
- v->uv_gq_timer = 0;
- v->uv_pim_neighbors = (pim_nbr_entry_t *)NULL;
-
- /* Tell kernel to add, i.e. start this vif */
- k_add_vif(mld6_socket, vifi, &uvifs[vifi]);
- log(LOG_INFO, 0, "%s comes up; if #%u now in service", v->uv_name, vifi);
-
- /*
- * Join the PIM multicast group on the interface.
- */
- k_join(mld6_socket, &allpim6routers_group.sin6_addr, v->uv_ifindex);
-
- /*
- * Join the ALL-ROUTERS multicast group on the interface.
- * This allows mtrace requests to loop back if they are run
- * on the multicast router.
- */
- k_join(mld6_socket, &allrouters_group.sin6_addr, v->uv_ifindex);
-
- /*
- * Until neighbors are discovered, assume responsibility for sending
- * periodic group membership queries to the subnet. Send the first
- * query.
- */
- v->uv_flags |= VIFF_QUERIER;
- if (!v->uv_querier) {
- v->uv_querier = (struct listaddr *)malloc(sizeof(*v->uv_querier));
- memset(v->uv_querier, 0, sizeof(*v->uv_querier));
- }
- v->uv_querier->al_addr = v->uv_linklocal->pa_addr;
- v->uv_querier->al_timer = MLD6_OTHER_QUERIER_PRESENT_INTERVAL;
- time(&v->uv_querier->al_ctime); /* reset timestamp */
- query_groups(v);
-
- /*
- * To avoid synchronization among routers booting simultaneously, set
- * the hello timer to a random value between 1 to PIM_TIMER_HELLO_PERIOD.
- */
- random_delay = 1 + (random() % (long)(PIM_TIMER_HELLO_PERIOD - 1));
- v->uv_pim_hello_timer = random_delay;
-}
-
-
-/*
- * Stop a vif (either physical interface or tunnel).
- * If we are running only PIM we don't have tunnels.
- */
-static void
-stop_vif(vifi)
- vifi_t vifi;
-{
- struct uvif *v;
- struct listaddr *a;
- register pim_nbr_entry_t *n, *next;
- struct vif_acl *acl;
-
- /*
- * TODO: make sure that the kernel viftable is
- * consistent with the daemon table
- */
- v = &uvifs[vifi];
- k_leave(mld6_socket, &allpim6routers_group.sin6_addr, v->uv_ifindex);
- k_leave(mld6_socket, &allrouters_group.sin6_addr, v->uv_ifindex);
- /*
- * Discard all group addresses. (No need to tell kernel;
- * the k_del_vif() call will clean up kernel state.)
- */
- while (v->uv_groups != NULL) {
- a = v->uv_groups;
- v->uv_groups = a->al_next;
- free((char *)a);
- }
-
- /*
- * TODO: inform (eventually) the neighbors I am going down by sending
- * PIM_HELLO with holdtime=0 so someone else should become a DR.
- */
-
- /* TODO: dummy! Implement it!! Any problems if don't use it? */
- delete_vif_from_mrt(vifi);
-
- /*
- * Delete the interface from the kernel's vif structure.
- */
- k_del_vif(mld6_socket, vifi);
- v->uv_flags = (v->uv_flags & ~VIFF_DR & ~VIFF_QUERIER & ~VIFF_NONBRS )
- | VIFF_DOWN;
- v->uv_pim_hello_timer = 0;
- v->uv_gq_timer = 0;
- for (n = v->uv_pim_neighbors; n != NULL; n = next) {
- next = n->next; /* Free the space for each neighbour */
- free((char *)n);
- }
- v->uv_pim_neighbors = NULL;
-
- /* TODO: currently not used */
- /* The Access Control List (list with the scoped addresses) */
- while (v->uv_acl != NULL) {
- acl = v->uv_acl;
- v->uv_acl = acl->acl_next;
- free((char *)acl);
- }
-
- vifs_down = TRUE;
- log(LOG_INFO, 0,
- "%s goes down; if #%u out of service", v->uv_name, vifi);
-}
-
-/*
- * return the max global Ipv6 address of an UP and ENABLED interface
- * other than the MIFF_REGISTER interface.
-*/
-struct sockaddr_in6 *
-max_global_address()
-{
- vifi_t vifi;
- struct uvif *v;
- struct phaddr *p;
- struct phaddr *pmax = NULL;
-
- for(vifi=0,v=uvifs;vifi< numvifs;++vifi,++v)
- {
- if(v->uv_flags & (VIFF_DISABLED | VIFF_DOWN | MIFF_REGISTER))
- continue;
- /*
- * take first the max global address of the interface
- * (without link local) => aliasing
- */
- for(p=v->uv_addrs;p!=NULL;p=p->pa_next)
- {
- /*
- * If this is the first global address, take it anyway.
- */
- if (pmax == NULL) {
- if (!IN6_IS_ADDR_LINKLOCAL(&p->pa_addr.sin6_addr) &&
- !IN6_IS_ADDR_SITELOCAL(&p->pa_addr.sin6_addr))
- pmax = p;
- }
- else {
- if (inet6_lessthan(&pmax->pa_addr,
- &p->pa_addr) &&
- !IN6_IS_ADDR_LINKLOCAL(&p->pa_addr.sin6_addr) &&
- !IN6_IS_ADDR_SITELOCAL(&p->pa_addr.sin6_addr))
- pmax=p;
- }
- }
- }
-
- return(pmax ? &pmax->pa_addr : NULL);
-}
-
-struct sockaddr_in6 *
-uv_global(vifi)
- vifi_t vifi;
-{
- struct uvif *v = &uvifs[vifi];
- struct phaddr *p;
-
- for (p = v->uv_addrs; p; p = p->pa_next) {
- if (!IN6_IS_ADDR_LINKLOCAL(&p->pa_addr.sin6_addr) &&
- !IN6_IS_ADDR_SITELOCAL(&p->pa_addr.sin6_addr))
- return(&p->pa_addr);
- }
-
- return(NULL);
-}
-
-/*
- * See if any interfaces have changed from up state to down, or vice versa,
- * including any non-multicast-capable interfaces that are in use as local
- * tunnel end-points. Ignore interfaces that have been administratively
- * disabled.
- */
-void
-check_vif_state()
-{
- register vifi_t vifi;
- register struct uvif *v;
- struct ifreq ifr;
- static int checking_vifs = 0;
-
- /*
- * XXX: TODO: True only for DVMRP?? Check.
- * If we get an error while checking, (e.g. two interfaces go down
- * at once, and we decide to send a prune out one of the failed ones)
- * then don't go into an infinite loop!
- */
- if (checking_vifs)
- return;
-
- vifs_down = FALSE;
- checking_vifs = 1;
- /* TODO: Check all potential interfaces!!! */
- /* Check the physical interfaces only */
- for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
- if (v->uv_flags & VIFF_DISABLED)
- continue;
-
- strncpy(ifr.ifr_name, v->uv_name, IFNAMSIZ);
- /* get the interface flags */
- if (ioctl(udp_socket, SIOCGIFFLAGS, (char *)&ifr) < 0)
- log(LOG_ERR, errno,
- "check_vif_state: ioctl SIOCGIFFLAGS for %s", ifr.ifr_name);
-
- if (v->uv_flags & VIFF_DOWN) {
- if (ifr.ifr_flags & IFF_UP) {
- start_vif(vifi);
- }
- else vifs_down = TRUE;
- }
- else {
- if (!(ifr.ifr_flags & IFF_UP)) {
- log(LOG_NOTICE, 0,
- "%s has gone down; if #%u taken out of service",
- v->uv_name, vifi);
- stop_vif(vifi);
- vifs_down = TRUE;
- }
- }
- }
- checking_vifs = 0;
-}
-
-
-/*
- * If the source is directly connected to us, find the vif number for
- * the corresponding physical interface (tunnels excluded).
- * Local addresses are excluded.
- * Return the vif number or NO_VIF if not found.
- */
-vifi_t
-find_vif_direct(src)
- struct sockaddr_in6 *src;
-{
- vifi_t vifi;
- register struct uvif *v;
- register struct phaddr *p;
-
- for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
- if (v->uv_flags & (VIFF_DISABLED | VIFF_DOWN | VIFF_TUNNEL))
- continue;
- for (p = v->uv_addrs; p; p = p->pa_next) {
- if (inet6_equal(src, &p->pa_addr))
- return(NO_VIF);
- if (inet6_match_prefix(src, &p->pa_prefix, &p->pa_subnetmask))
- return(vifi);
- }
- }
- return (NO_VIF);
-}
-
-
-/*
- * Checks if src is local address. If "yes" return the vif index,
- * otherwise return value is NO_VIF.
- */
-vifi_t
-local_address(src)
- struct sockaddr_in6 *src;
-{
- vifi_t vifi;
- register struct uvif *v;
- register struct phaddr *p;
-
- for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
- if (v->uv_flags & (VIFF_DISABLED | VIFF_DOWN))
- continue;
- for (p = v->uv_addrs; p; p = p->pa_next) {
- if (inet6_equal(src, &p->pa_addr))
- return(vifi);
- }
- }
- /* Returning NO_VIF means not a local address */
- return (NO_VIF);
-}
-
-/*
- * If the source is directly connected, or is local address,
- * find the vif number for the corresponding physical interface
- * (tunnels excluded).
- * Return the vif number or NO_VIF if not found.
- */
-vifi_t
-find_vif_direct_local(src)
- struct sockaddr_in6 *src;
-{
- vifi_t vifi;
- register struct uvif *v;
- register struct phaddr *p;
-
- for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
- if (v->uv_flags & (VIFF_DISABLED | VIFF_DOWN | VIFF_TUNNEL))
- continue;
- for (p = v->uv_addrs; p; p = p->pa_next) {
- if (inet6_equal(src, &p->pa_addr) ||
- inet6_match_prefix(src, &p->pa_prefix, &p->pa_subnetmask))
- return(vifi);
- }
- }
- return (NO_VIF);
-}
diff --git a/usr.sbin/pim6dd/vif.h b/usr.sbin/pim6dd/vif.h
deleted file mode 100644
index 2a068e3..0000000
--- a/usr.sbin/pim6dd/vif.h
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * Copyright (c) 1998 by the University of Southern California.
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation in source and binary forms for lawful
- * purposes and without fee is hereby granted, provided
- * that the above copyright notice appear in all copies and that both
- * the copyright notice and this permission notice appear in supporting
- * documentation, and that any documentation, advertising materials,
- * and other materials related to such distribution and use acknowledge
- * that the software was developed by the University of Southern
- * California and/or Information Sciences Institute.
- * The name of the University of Southern California may not
- * be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THE UNIVERSITY OF SOUTHERN CALIFORNIA DOES NOT MAKE ANY REPRESENTATIONS
- * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. THIS SOFTWARE IS
- * PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
- * NON-INFRINGEMENT.
- *
- * IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT,
- * TORT, OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH,
- * THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Other copyrights might apply to parts of this software and are so
- * noted when applicable.
- */
-/*
- * Questions concerning this software should be directed to
- * Pavlin Ivanov Radoslavov (pavlin@catarina.usc.edu)
- *
- * $Id: vif.h,v 1.2 1999/08/24 16:45:23 jinmei Exp $
- */
-/*
- * Part of this program has been derived from mrouted.
- * The mrouted program is covered by the license in the accompanying file
- * named "LICENSE.mrouted".
- *
- * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
- * Leland Stanford Junior University.
- *
- * $FreeBSD$
- */
-
-
-/*
- * Bitmap handling functions.
- * These should be fast but generic. bytes can be slow to zero and compare,
- * words are hard to make generic. Thus two sets of macros (yuk).
- */
-
-/*
- * The VIFM_ functions should migrate out of <netinet/ip_mroute.h>, since
- * the kernel no longer uses vifbitmaps.
- */
-#ifndef VIFM_SET
-
-typedef u_int32 vifbitmap_t;
-
-#define VIFM_SET(n, m) ((m) |= (1 << (n)))
-#define VIFM_CLR(n, m) ((m) &= ~(1 << (n)))
-#define VIFM_ISSET(n, m) ((m) & (1 << (n)))
-#define VIFM_CLRALL(m) ((m) = 0x00000000)
-#define VIFM_COPY(mfrom, mto) ((mto) = (mfrom))
-#define VIFM_SAME(m1, m2) ((m1) == (m2))
-#endif
-/*
- * And <netinet/ip_mroute.h> was missing some required functions anyway
- */
-#if !defined(__NetBSD__)
-#define VIFM_SETALL(m) ((m) = ~0)
-#endif
-#define VIFM_ISSET_ONLY(n, m) ((m) == (1 << (n)))
-#define VIFM_ISEMPTY(m) ((m) == 0)
-#define VIFM_CLR_MASK(m, mask) ((m) &= ~(mask))
-#define VIFM_SET_MASK(m, mask) ((m) |= (mask))
-#define VIFM_MERGE(m1, m2, result) ((result) = (m1) | (m2))
-
-/*
- * And <netinet6/ip6_mroute.h> was missing some required functions anyway
- */
-extern if_set if_nullset;
-#define IF_ISEMPTY(p) (memcmp((p), &if_nullset, sizeof(if_nullset)) == 0)
-#define IF_CLR_MASK(p, mask) \
- {\
- int idx;\
- for (idx = 0; idx < sizeof(*(p))/sizeof(fd_mask); idx++) {\
- (p)->ifs_bits[idx] &= ~((mask)->ifs_bits[idx]);\
- }\
- }
-#define IF_MERGE(p1, p2, result) \
- {\
- int idx;\
- for (idx = 0; idx < sizeof(*(p1))/sizeof(fd_mask); idx++) {\
- (result)->ifs_bits[idx] = (p1)->ifs_bits[idx]|(p2)->ifs_bits[idx]; \
- }\
- }
-#define IF_SAME(p1, p2) (memcmp((p1),(p2),sizeof(*(p1))) == 0)
-
-/* Check whether I am the forwarder on some LAN */
-#define VIFM_FORWARDER(leaves, oifs) ((leaves) & (oifs))
-
-/*
- * Neighbor bitmaps are, for efficiency, implemented as a struct
- * containing two variables of a native machine type. If you
- * have a native type that's bigger than a long, define it below.
- */
-#define NBRTYPE u_long
-#define NBRBITS sizeof(NBRTYPE) * 8
-
-typedef struct {
- NBRTYPE hi;
- NBRTYPE lo;
-} nbrbitmap_t;
-#define MAXNBRS 2 * NBRBITS
-
-#define NBRM_SET(n, m) (((n) < NBRBITS) ? ((m).lo |= (1 << (n))) : \
- ((m).hi |= (1 << (n - NBRBITS))))
-#define NBRM_CLR(n, m) (((n) < NBRBITS) ? ((m).lo &= ~(1 << (n))) : \
- ((m).hi &= ~(1 << (n - NBRBITS))))
-#define NBRM_ISSET(n, m) (((n) < NBRBITS) ? ((m).lo & (1 << (n))) : \
- ((m).hi & (1 << ((n) - NBRBITS))))
-#define NBRM_CLRALL(m) ((m).lo = (m).hi = 0)
-#define NBRM_COPY(mfrom, mto) ((mto).lo = (mfrom).lo, (mto).hi = (mfrom).hi)
-#define NBRM_SAME(m1, m2) (((m1).lo == (m2).lo) && ((m1).hi == (m2).hi))
-#define NBRM_ISEMPTY(m) (((m).lo == 0) && ((m).hi == 0))
-#define NBRM_SETMASK(m, mask) (((m).lo |= (mask).lo),((m).hi |= (mask).hi))
-#define NBRM_CLRMASK(m, mask) (((m).lo &= ~(mask).lo),((m).hi &= ~(mask).hi))
-#define NBRM_MASK(m, mask) (((m).lo &= (mask).lo),((m).hi &= (mask).hi))
-#define NBRM_ISSETMASK(m, mask) (((m).lo & (mask).lo) || ((m).hi & (mask).hi))
-#define NBRM_ISSETALLMASK(m, mask)\
- ((((m).lo & (mask).lo) == (mask).lo) && \
- (((m).hi & (mask).hi) == (mask).hi))
-/*
- * This macro is TRUE if all the subordinates have been pruned, or if
- * there are no subordinates on this vif.
- * The arguments is the map of subordinates, the map of neighbors on the
- * vif, and the map of received prunes.
- */
-#define SUBS_ARE_PRUNED(sub, vifmask, prunes) \
- (((sub).lo & (vifmask).lo) == ((prunes).lo & (vifmask).lo & (sub).lo) && \
- ((sub).hi & (vifmask).hi) == ((prunes).hi & (vifmask).hi & (sub).hi))
-
-/*
- * User level Virtual Interface structure
- *
- * A "virtual interface" is either a physical, multicast-capable interface
- * (called a "phyint"), a virtual point-to-point link (called a "tunnel")
- * or a "register vif" used by PIM. The register vif is used by the
- * Designated Router (DR) to send encapsulated data packets to the
- * Rendevous Point (RP) for a particular group. The data packets are
- * encapsulated in PIM messages (IPPROTO_PIM = 103) and then unicast to
- * the RP.
- * (Note: all addresses, subnet numbers and masks are kept in NETWORK order.)
- */
-struct uvif {
- u_int uv_flags; /* VIFF_ flags defined below */
- u_char uv_metric; /* cost of this vif */
- u_char uv_admetric; /* advertised cost of this vif */
-#if 0 /* unused for IPv6? */
- u_char uv_threshold; /* min ttl required to forward on vif */
-#endif
- u_int uv_rate_limit; /* rate limit on this vif */
- struct sockaddr_in6 uv_lcl_addr;/* local address of this vif */
- struct phaddr *uv_linklocal;/* link-local address of this vif */
-#if 0
- u_int32 uv_rmt_addr; /* remote end-point addr (tunnels only) */
-#endif
- struct sockaddr_in6 uv_dst_addr; /* destination for PIM messages */
- struct sockaddr_in6 uv_prefix; /* prefix (phyints only) */
- struct in6_addr uv_subnetmask; /* subnet mask (phyints only) */
- char uv_name[IFNAMSIZ]; /* interface name */
- u_int uv_ifindex; /* index of the interface */
- u_int uv_siteid; /* index of the site on the interface */
- struct listaddr *uv_groups; /* list of local groups (phyints only) */
- struct listaddr *uv_dvmrp_neighbors; /* list of neighboring routers */
- nbrbitmap_t uv_nbrmap; /* bitmap of active neighboring routers */
- struct listaddr *uv_querier; /* MLD querier on vif */
- int uv_prune_lifetime; /* Prune lifetime or 0 for default */
- struct vif_acl *uv_acl; /* access control list of groups */
- int uv_leaf_timer; /* time until this vif is considrd leaf */
- struct phaddr *uv_addrs; /* Additional addresses on this vif */
- struct vif_filter *uv_filter; /* Route filters on this vif */
- u_int16 uv_pim_hello_timer;/* timer for sending PIM hello msgs */
- u_int16 uv_gq_timer; /* Group Query timer */
- int uv_local_pref; /* default local preference for assert */
- int uv_local_metric; /* default local metric for assert */
- struct pim_nbr_entry *uv_pim_neighbors; /* list of PIM neighbor routers */
-};
-
-/* TODO: define VIFF_KERNEL_FLAGS */
-#define VIFF_KERNEL_FLAGS (VIFF_TUNNEL | VIFF_SRCRT)
-#define VIFF_DOWN 0x000100 /* kernel state of interface */
-#define VIFF_DISABLED 0x000200 /* administratively disabled */
-#define VIFF_QUERIER 0x000400 /* I am the subnet's querier */
-#define VIFF_ONEWAY 0x000800 /* Maybe one way interface */
-#define VIFF_LEAF 0x001000 /* all neighbors are leaves */
-#define VIFF_IGMPV1 0x002000 /* Act as an IGMPv1 Router */
-#define VIFF_REXMIT_PRUNES 0x004000 /* retransmit prunes */
-#define VIFF_PASSIVE 0x008000 /* passive tunnel */
-#define VIFF_ALLOW_NONPRUNERS 0x010000 /* ok to peer with nonprunrs */
-#define VIFF_NOFLOOD 0x020000 /* don't flood on this vif */
-#define VIFF_DR 0x040000 /* designated router */
-/* TODO: VIFF_NONBRS == VIFF_ONEWAY? */
-#define VIFF_NONBRS 0x080000 /* no neighbor on vif */
-#define VIFF_POINT_TO_POINT 0x100000 /* point-to-point link */
-#define VIFF_PIM_NBR 0x200000 /* PIM neighbor */
-#define VIFF_DVMRP_NBR 0x400000 /* DVMRP neighbor */
-#define VIFF_NOLISTENER 0x800000 /* no listener on the link */
-
-struct phaddr {
- struct phaddr *pa_next;
- struct sockaddr_in6 pa_addr; /* extra address */
- struct sockaddr_in6 pa_prefix; /* prefix of the extra address */
- struct in6_addr pa_subnetmask; /* netmask */
-};
-
-/* The Access Control List (list with scoped addresses) member */
-struct vif_acl {
- struct vif_acl *acl_next; /* next acl member */
- u_int32 acl_addr; /* Group address */
- u_int32 acl_mask; /* Group addr. mask */
-};
-
-struct vif_filter {
- int vf_type;
-#define VFT_ACCEPT 1
-#define VFT_DENY 2
- int vf_flags;
-#define VFF_BIDIR 1
- struct vf_element *vf_filter;
-};
-
-struct vf_element {
- struct vf_element *vfe_next;
- struct sockaddr_in6 *vfe_addr;
- struct in6_addr vfe_mask;
- int vfe_flags;
-#define VFEF_EXACT 0x0001
-};
-
-struct listaddr {
- struct listaddr *al_next; /* link to next addr, MUST BE FIRST */
- struct sockaddr_in6 al_addr; /* local group or neighbor address */
- u_long al_timer; /* for timing out group or neighbor */
- time_t al_ctime; /* entry creation time */
- union {
- u_int32 alu_genid; /* generation id for neighbor */
- struct sockaddr_in6 alu_reporter;/* a host which reported membership */
- } al_alu;
- u_char al_pv; /* router protocol version */
- u_char al_mv; /* router mrouted version */
- u_char al_old; /* time since heard old report: unnecessary for mld */
- u_char al_index; /* neighbor index */
- u_long al_timerid; /* timer for group membership */
- u_long al_query; /* timer for repeated leave query */
- u_int16 al_flags; /* flags related to this neighbor */
-};
-#define al_genid al_alu.alu_genid
-#define al_reporter al_alu.alu_reporter
-
-#define NBRF_LEAF 0x0001 /* This neighbor is a leaf */
-#define NBRF_GENID 0x0100 /* I know this neighbor's genid */
-#define NBRF_WAITING 0x0200 /* Waiting for peering to come up */
-#define NBRF_ONEWAY 0x0400 /* One-way peering */
-#define NBRF_TOOOLD 0x0800 /* Too old (policy decision) */
-#define NBRF_TOOMANYROUTES 0x1000 /* Neighbor is spouting routes */
-#define NBRF_NOTPRUNING 0x2000 /* Neighbor doesn't appear to prune */
-
-/*
- * Don't peer with neighbors with any of these flags set
- */
-#define NBRF_DONTPEER (NBRF_WAITING|NBRF_ONEWAY|NBRF_TOOOLD| \
- NBRF_TOOMANYROUTES|NBRF_NOTPRUNING)
-
-#define NO_VIF ((vifi_t)MAXMIFS) /* An invalid vif index */
-
-
-/*
- * Used to get the RPF neighbor and IIF info
- * for a given source from the unicast routing table.
- */
-struct rpfctl {
- struct sockaddr_in6 source; /* the source for which we want iif and rpfnbr */
- struct sockaddr_in6 rpfneighbor;/* next hop towards the source */
- vifi_t iif; /* the incoming interface to reach the next hop */
-};
OpenPOWER on IntegriCloud