summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/Makefile2
-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
-rw-r--r--usr.sbin/pim6sd/BUGS.TODO126
-rw-r--r--usr.sbin/pim6sd/BUGS.V610
-rw-r--r--usr.sbin/pim6sd/LICENSE.mrouted49
-rw-r--r--usr.sbin/pim6sd/LICENSE.pim6dd31
-rw-r--r--usr.sbin/pim6sd/LICENSE.pim6sd47
-rw-r--r--usr.sbin/pim6sd/LICENSE.pimd48
-rw-r--r--usr.sbin/pim6sd/Makefile96
-rw-r--r--usr.sbin/pim6sd/README85
-rw-r--r--usr.sbin/pim6sd/README.first15
-rw-r--r--usr.sbin/pim6sd/callout.c317
-rw-r--r--usr.sbin/pim6sd/callout.h62
-rw-r--r--usr.sbin/pim6sd/cfparse.h55
-rw-r--r--usr.sbin/pim6sd/cfparse.y1023
-rw-r--r--usr.sbin/pim6sd/cftoken.l664
-rw-r--r--usr.sbin/pim6sd/config.c495
-rw-r--r--usr.sbin/pim6sd/config.h73
-rw-r--r--usr.sbin/pim6sd/crc.c103
-rw-r--r--usr.sbin/pim6sd/crc.h47
-rw-r--r--usr.sbin/pim6sd/debug.c998
-rw-r--r--usr.sbin/pim6sd/debug.h153
-rw-r--r--usr.sbin/pim6sd/defs.h81
-rw-r--r--usr.sbin/pim6sd/inet6.c292
-rw-r--r--usr.sbin/pim6sd/inet6.h76
-rw-r--r--usr.sbin/pim6sd/kern.c413
-rw-r--r--usr.sbin/pim6sd/kern.h77
-rw-r--r--usr.sbin/pim6sd/main.c767
-rw-r--r--usr.sbin/pim6sd/mld6.c564
-rw-r--r--usr.sbin/pim6sd/mld6.h92
-rw-r--r--usr.sbin/pim6sd/mld6_proto.c619
-rw-r--r--usr.sbin/pim6sd/mld6_proto.h71
-rw-r--r--usr.sbin/pim6sd/mrt.c1500
-rw-r--r--usr.sbin/pim6sd/mrt.h340
-rw-r--r--usr.sbin/pim6sd/mtrace6/Makefile85
-rw-r--r--usr.sbin/pim6sd/mtrace6/mtrace6.8119
-rw-r--r--usr.sbin/pim6sd/mtrace6/mtrace6.c713
-rw-r--r--usr.sbin/pim6sd/pathnames.h80
-rw-r--r--usr.sbin/pim6sd/pim6.c518
-rw-r--r--usr.sbin/pim6sd/pim6.h69
-rw-r--r--usr.sbin/pim6sd/pim6_proto.c4129
-rw-r--r--usr.sbin/pim6sd/pim6_proto.h102
-rw-r--r--usr.sbin/pim6sd/pim6sd.8170
-rw-r--r--usr.sbin/pim6sd/pim6sd.conf.5317
-rw-r--r--usr.sbin/pim6sd/pim6sd.conf.sample107
-rwxr-xr-xusr.sbin/pim6sd/pim6stat89
-rw-r--r--usr.sbin/pim6sd/pim6stat.195
-rw-r--r--usr.sbin/pim6sd/pimd.h526
-rw-r--r--usr.sbin/pim6sd/route.c1179
-rw-r--r--usr.sbin/pim6sd/route.h84
-rw-r--r--usr.sbin/pim6sd/routesock.c428
-rw-r--r--usr.sbin/pim6sd/routesock.h56
-rw-r--r--usr.sbin/pim6sd/rp.c1207
-rw-r--r--usr.sbin/pim6sd/rp.h122
-rw-r--r--usr.sbin/pim6sd/timer.c1301
-rw-r--r--usr.sbin/pim6sd/timer.h101
-rw-r--r--usr.sbin/pim6sd/trace.c558
-rw-r--r--usr.sbin/pim6sd/trace.h210
-rw-r--r--usr.sbin/pim6sd/var.h62
-rw-r--r--usr.sbin/pim6sd/vers.c2
-rw-r--r--usr.sbin/pim6sd/vif.c824
-rw-r--r--usr.sbin/pim6sd/vif.h277
-rw-r--r--usr.sbin/pim6sd/vmbuf.h49
93 files changed, 0 insertions, 34962 deletions
diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile
index cdfd59e..6d9b018 100644
--- a/usr.sbin/Makefile
+++ b/usr.sbin/Makefile
@@ -65,8 +65,6 @@ SUBDIR= IPXrouted \
pccard \
pciconf \
periodic \
- pim6dd \
- pim6sd \
pkg_install \
pnpinfo \
ppp \
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 */
-};
diff --git a/usr.sbin/pim6sd/BUGS.TODO b/usr.sbin/pim6sd/BUGS.TODO
deleted file mode 100644
index 93c330e..0000000
--- a/usr.sbin/pim6sd/BUGS.TODO
+++ /dev/null
@@ -1,126 +0,0 @@
- $Id: BUGS.TODO,v 1.1.1.1 1999/08/08 23:30:57 itojun Exp $
- $FreeBSD$
-
-THIS LIST IS FAR AWAY FROM BEING COMPLETE, so these are the few things
-that came up at the right moment to be written down.
-
- * Experimental kernel MFC (*,G) related:
- If the (S,G) iif or oifs are different from the (*,G) or (*,*,RP)
- iifs/oifs, the resp. (*,G) or (*,*,RP) will delete and disallow
- creating (*,G) MFC. Only after all MRT (S,G) are deleted, the
- corresponding (*,G) or (*,*,RP) will create (*,G) MFC.
-
- * Experimental kernel MFC (*,G) related:
- Right now when the MFC (*,G) total datarate is above the SPT switch
- threshold, the (*,G) MFC will be deleted, and any further cache miss
- will result in (S,G) MFC (the problem is that we must do (S,G)
- monitoring for eventually high datagate sources). Only after all
- (S,G) MFCs expire, the daemon's MRT will stop creating (S,G) MFCs
- (i.e. the next cache miss will result in (*,G) kernel MFC).
- A better selection should be applied to sort out the higher
- datarate sources, and at the same time to have (*,G)MFC as well.
- For example, create few (S,G), and after that create the (*,G). If some
- of the created (S,G) MFC entries have very low datarate, delete them.
-
- * Use NetBSD's definition for IPADDR (netinet/in.h):
-#ifdef _KERNEL
-#define __IPADDR(x) ((u_int32_t) htonl((u_int32_t)(x)))
-#else
-#define __IPADDR(x) ((u_int32_t)(x))
-#endif
-
-
- * The (S,G)RPbit in the DR for the sender and the (S,G)SPT in the
- downstream router won't timeout and will refresh each other even
- if the sender is not active:
-
- S--DR-----------------R1------------RP
- (S,G)RPbit (S,G)
- iif toward S
-
- * Check whether the kernel code sends CACHE_MISS and WRONG_IIF for
- the LAN-scoped addresses
-
- * If the RP for a group changes, the DR should cancel any PIM-register-stop
- timers (XXX: not in the spec, but should be there)
-
- * If a new interface is configured, include it automatically
-
- * Don't create routing entries for local link scoped groups
-
- * Implement adm. scoped filters
-
- * Do precise check of the timer events to speed up the propagation of the
- Cand-RP messages + Cand-BSR messages and the election of the BSR.
-
- * Fix the bug for messing up the things when the receiver is on the
- same host as the RP for the multicast group (probably was fixed with alpha6,
- because I cannot reproduce it anymore)
-
- * Do more precise error check for the received PIM messages. In most cases,
- the whole message must be parsed completely before starting processing it.
-
- * Clean up the debugging messages.
-
- * Use Patricia tree to search the routing table
- (There is a nice paper in Sigcomm '97 about fast routing tables
- implementation, so need to check it as well)
-
- * Do switch back to the Shared Tree by timing out the SPT if the rate
- is too low (not in the spec, but Ahmed pointed out some complications if
- this happens)
-
- * Change all countdown timers to events timeout (callout.c)
- (The current implementation is very unefficient if the routing table becomes
- very large)
-
- * Send immediately Join/Prune, instead of relying of Join/Prune timer = 0
-
- * Fix the code allowing interface UP/DOWN without restarting pimd.
-
- * Do more testings for SPT switch, Join/Prune, asserts, etc...
-
- * Test the (*,*,RP) code (need PIM/DVMRP border router to do so)
-
- * Test the RSRR (RSVP support) code
-
- * Send Initial_Reply RSRR message if the interfaces detected by pimd change
-
- * SNMP support
-
-===TODO by function name===
-igmp_proto.c:
- * accept_group_report():
- - add a leaf if DR or forwarder (currently only if DR)???
- * accept_leave_message():
- - send immediately PIM prune message if the last member has left
-
-main.c
- * main():
- - use a combination of time and hostid to initialize the random generator.
- * restart():
- - check the implementation
-
-pim_proto.c
- * pim_register():
- - IF THE BORDER BIT IS SET, THEN FORWARD THE WHOLE PACKET FROM USER SPACE
- AND AT THE SAME TIME IGNORE ANY CACHE_MISS SIGNALS FROM THE KERNEL.
- * register_stop():
- - REGISTER_STOP rate limiting
-
-route.c
- * process_cache_miss()
- - use negative cache.
-
-rp.c
- * add_rp_grp_entry():
- - FIX THE BUG when adding an RP for different prefix requires remapping
- for some groups!!!
- (Intentionally left, waiting to come up with an idea how to implement
- it simple and efficient. If you configure all RPs to advertise the
- same prefix, the bug won't "show up")
-
-================DONE=====================
-
- * When receive PIM_REGISTER, check whether I am the chosen RP
-
diff --git a/usr.sbin/pim6sd/BUGS.V6 b/usr.sbin/pim6sd/BUGS.V6
deleted file mode 100644
index 330ffda..0000000
--- a/usr.sbin/pim6sd/BUGS.V6
+++ /dev/null
@@ -1,10 +0,0 @@
-$FreeBSD$
-
-Write your bugs reports here
-
-BSR and Cand_rp discovery (base mecanism ): fixed
-Encap/decap and unicast register send : fixed.
-Join/Prune messages: They are sent but the RP don't create the (*,G) entry: fixed.
-Check with the sockaddr6_any and sockaddr_d (not sure it works because of the scope..)
-Pb with filling the upstream neighbor:fixed
-to query groups at boot time not efficient because there is no RP
diff --git a/usr.sbin/pim6sd/LICENSE.mrouted b/usr.sbin/pim6sd/LICENSE.mrouted
deleted file mode 100644
index e03eb82..0000000
--- a/usr.sbin/pim6sd/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/pim6sd/LICENSE.pim6dd b/usr.sbin/pim6sd/LICENSE.pim6dd
deleted file mode 100644
index 764c6fd..0000000
--- a/usr.sbin/pim6sd/LICENSE.pim6dd
+++ /dev/null
@@ -1,31 +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$
- */
-
diff --git a/usr.sbin/pim6sd/LICENSE.pim6sd b/usr.sbin/pim6sd/LICENSE.pim6sd
deleted file mode 100644
index 3f96a55..0000000
--- a/usr.sbin/pim6sd/LICENSE.pim6sd
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 1999 LSIIT Laboratory.
- * 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.
- */
-/*
- * Questions concerning this software should be directed to
- * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
- *
- * $FreeBSD$
- */
-/*
- * This program has been derived from pim6dd.
- * The pim6dd program is covered by the license in the accompanying file
- * named "LICENSE.pim6dd".
- */
-/*
- * This program has been derived from pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- */
-
-
diff --git a/usr.sbin/pim6sd/LICENSE.pimd b/usr.sbin/pim6sd/LICENSE.pimd
deleted file mode 100644
index 46955e1..0000000
--- a/usr.sbin/pim6sd/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:57 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/pim6sd/Makefile b/usr.sbin/pim6sd/Makefile
deleted file mode 100644
index 882973a..0000000
--- a/usr.sbin/pim6sd/Makefile
+++ /dev/null
@@ -1,96 +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 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.8 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= pim6sd
-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 rp.c crc.c trace.c\
- cfparse.y cftoken.l
-SRCS+= y.tab.h
-y.tab.h: cfparse.y
-CLEANFILES+= lex.yy.c y.tab.h y.tab.c
-CFLAGS+=-Wall
-CFLAGS+=-I. -I${.CURDIR}
-CFLAGS+=-DINET6 -DPIM -DIOCTL_OK_ON_RAW_SOCKET -DHAVE_GETIFADDRS
-CFLAGS+=-DHAVE_STDARG_H
-DPADD= ${LIBY} ${LIBL}
-LDADD= -ly -ll
-SCRIPTS=pim6stat
-
-MAN= pim6stat.1 pim6sd.conf.5 pim6sd.8
-
-.include <bsd.prog.mk>
diff --git a/usr.sbin/pim6sd/README b/usr.sbin/pim6sd/README
deleted file mode 100644
index 49dfc17..0000000
--- a/usr.sbin/pim6sd/README
+++ /dev/null
@@ -1,85 +0,0 @@
- $Id: README,v 1.1.1.1 1999/08/08 23:30:57 itojun Exp $
- $FreeBSD$
-
-WARNING! WARNING! WARNING!
-THIS RELEASE IS VERY ALPHA, SO PLEASE DO NOT REDISTRIBUTE AND
-DO NOT TRY IT OUTSIDE OF YOUR TESTBED.
-
-This is README for pimd, the PIM multicast daemon.
-PIM-SM version: 2
-Check ftp://catarina.usc.edu/pub/pim/pimd/ for lastest version.
-
-SUPPORTED PLATFORMS: FreeBSD-2.2.*, SunOS-4.1.3, Solaris-2.5.1 and 2.6,
-SGI, BSDI 3.0/3.1, NetBSD-1.3
-
-AVAILABLE PIM kernel patches: FreeBSD-2.2.1, FreeBSD-2.2.2, FreeBSD-2.2,5,
- SunOS-4.1.3, SGI, BSDI-3.0, BSDI-3.1, NetBSD-1.3
-
-Linux: pimd compiles under Linux, and linux-2.1.103 seems to have PIM-SMv2
-kernel support, but I haven't tested whether the kernel patches really work.
-
-FAST START (read "fast explanation" :))
-
-1. Apply the PIM kernel patches, recompile, reboot
-
-2. Copy pimd.conf to /etc and edit as appropriate. Disable the interfaces
-you don't need. Note that you need at least 2 physical interfaces enabled.
-
-3. Edit Makefile by uncommenting the line(s) corresponding to your platform.
-
-4. Recompile pimd
-
-5. Run pimd as a root. It is highly recommended to run it in debug mode.
-Because there are many debug messages, you can specify only a subset of
-the messages to be printed out:
-
-usage: pimd [-c configfile] [-d [debug_level][,debug_level]]
-
-Valid debug levels: dvmrp_prunes,dvmrp_mrt,dvmrp_neighbors,dvmrp_timers,igmp_proto,igmp_timers,igmp_members,trace,timeout,pkt,interfaces,kernel,cache,rsrr,pim_hello,pim_register,pim_join_prune,pim_bootstrap,pim_asserts,pim_cand_rp,pim_routes,pim_timers,pim_rpf
-
-If you want to see all messages, use "pimd -d" only.
-
-6. Note that it takes of the order of 30 seconds to 1 minute until the
-Bootstrap router is elected and the RP-set distributed to the PIM routers,
-and without the RP-set in the routers the multicast packets cannot be
-forwarded.
-
-7. There are plenty of bugs, some of them known (check BUGS.TODO),
-some of them unknown, so your bug reports are more than welcome.
-
-
-Pavlin Ivanov Radoslavov
-pavlin@catarina.usc.edu
-
-ACKNOWLEDGEMENTS:
-
- * The PIM kernel modifications and pimd itself were originally
- written by Ahmed Helmy (ahelmy@catarina.usc.edu) as a summer intern in SGI.
-
- * The "up to the March '97 I-D spec" + RSVP support pimd version was done
- during my summer'97 intern in Sun Microsystems under Michael Speer's
- supervision.
-
- * BSDI 3.0/3.1 support + various improvements and bug reports
- by Hitoshi Asaeda (asaeda@yamato.ibm.co.jp).
-
- * Bug reports and SGI tests by Nidhi Bhaskar (nidhi@cho-oyu.engr.sgi.com).
-
- * Bug reports and SunOS tests by Isabelle Girard (girardi@rc.bel.alcatel.be)
- and Dirk Ooms (oomsd@rc.bel.alcatel.be)
-
- * NetBSD-1.3 compilation support (both for pimd and the kernel mods) and
- bug reports by Heiko W.Rupp <hwr@pilhuhn.de>
-
- * Bug reports by Chirayu Shah (shahzad@torrentnet.com)
-
- * A number of changes copied back from pimdd (PIM-DM) stand-alone
- implementation by Kurt Windisch (kurtw@antc.uoregon.edu)
-
- * Linux patches by "Jonathan Day" <jd9812@my-dejanews.com> and
- Fred Griffoul <griffoul@ccrle.nec.de>
-
- * Thanks to the FreeBSD team and particularly to the
- freebsd-hackers mailing list participants for the help
- with the real-time debugging of the FreeBSD kernel.
-
diff --git a/usr.sbin/pim6sd/README.first b/usr.sbin/pim6sd/README.first
deleted file mode 100644
index 87a1c3c..0000000
--- a/usr.sbin/pim6sd/README.first
+++ /dev/null
@@ -1,15 +0,0 @@
-$FreeBSD$
-
-WARNING WARNING WARNING:
-
-This is Pim Sparse Mode for IPv6. BUT IT HAS STILL SOME PROBLEMS !
-So , before trying to run it , take a look to the code.
-
-
-THIS VERSION NEEDS :
-
-lots of debugging work...
-AND : more debugging work :)
-
-
-Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
diff --git a/usr.sbin/pim6sd/callout.c b/usr.sbin/pim6sd/callout.c
deleted file mode 100644
index d2f9d04..0000000
--- a/usr.sbin/pim6sd/callout.c
+++ /dev/null
@@ -1,317 +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
- */
-/*
- * Questions concerning this software should be directed to
- * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
- *
- */
-/*
- * This program has been derived from pim6dd.
- * The pim6dd program is covered by the license in the accompanying file
- * named "LICENSE.pim6dd".
- */
-/*
- * This program has been derived from pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- * $FreeBSD$
- */
-
-
-#include <stdio.h>
-#include <syslog.h>
-#include <stdlib.h>
-#include "debug.h"
-#include "defs.h"
-#include "callout.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 */
-};
-
-#if 0
-#define CALLOUT_DEBUG 1
-#define CALLOUT_DEBUG2 1
-#endif /* 0 */
-
-#ifdef CALLOUT_DEBUG2
-static void print_Q __P((void));
-#else
-#define print_Q()
-#endif
-
-void
-callout_init()
-{
- 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;
- print_Q();
- return node->id;
- }
- else
- {
- /* keep moving */
-
- delay -= ptr->time;
- node->time = delay;
- prev = ptr;
- ptr = ptr->next;
- }
- }
- prev->next = node;
- }
- print_Q();
- 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
- */
-
- print_Q();
- 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);
- print_Q();
- return;
- }
- prev = ptr;
- ptr = ptr->next;
- }
- print_Q();
-}
-
-#ifdef CALLOUT_DEBUG2
-/*
- * 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_DEBUG2 */
diff --git a/usr.sbin/pim6sd/callout.h b/usr.sbin/pim6sd/callout.h
deleted file mode 100644
index 6d08d31..0000000
--- a/usr.sbin/pim6sd/callout.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 1999 LSIIT Laboratory.
- * 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.
- */
-/*
- * Questions concerning this software should be directed to
- * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
- *
- */
-/*
- * This program has been derived from pim6dd.
- * The pim6dd program is covered by the license in the accompanying file
- * named "LICENSE.pim6dd".
- *
- */
-/*
- * This program has been derived from pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- * $FreeBSD$
- */
-
-
-#ifndef CALLOUT_H
-#define CALLOUT_H
-
-#include "defs.h"
-
-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));
-
-#endif
diff --git a/usr.sbin/pim6sd/cfparse.h b/usr.sbin/pim6sd/cfparse.h
deleted file mode 100644
index b4f6758..0000000
--- a/usr.sbin/pim6sd/cfparse.h
+++ /dev/null
@@ -1,55 +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.
- *
- * $FreeBSD$
- */
-#if defined(YIPS_DEBUG)
-# define DP(str) YIPSDEBUG(DEBUG_CONF, cfdebug_print(str, yytext, yyleng))
-# define YYD_ECHO \
- { YIPSDEBUG(DEBUG_CONF, printf("<%d>", yy_start); ECHO ; printf("\n");); }
-# define YIPSDP(cmd) YIPSDEBUG(DEBUG_CONF, cmd)
-# define PLOG printf
-#else
-# define DP(str)
-# define YYD_ECHO
-# define YIPSDP(cmd)
-# define PLOG(cmd)
-#endif /* defined(YIPS_DEBUG) */
-
-/* cfparse.y */
-extern void cf_init __P((int, int));
-#ifdef notyet
-extern int re_cfparse __P((void));
-#endif
-extern int cf_post_config __P((void));
-extern int yyparse __P((void));
-
-/* cftoken.l */
-extern void yyerror __P((char *, ...));
-extern void yywarn __P((char *, ...));
-extern int cfparse __P((int, int));
diff --git a/usr.sbin/pim6sd/cfparse.y b/usr.sbin/pim6sd/cfparse.y
deleted file mode 100644
index e0e358f..0000000
--- a/usr.sbin/pim6sd/cfparse.y
+++ /dev/null
@@ -1,1023 +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.
- *
- * $FreeBSD$
- */
-%{
-#include <sys/types.h>
-
-#include <netinet/in.h>
-
-#include <arpa/inet.h>
-
-#include <string.h>
-#include <syslog.h>
-
-#include "defs.h"
-#include "rp.h"
-#include "vif.h"
-
-#include "var.h"
-#include "vmbuf.h"
-#include "cfparse.h"
-#include "debug.h"
-#include "pimd.h"
-#include "timer.h"
-#include "inet6.h"
-
-#define set_param(var,val,p) \
- do {\
- if ((var) != -1) {\
- yywarn("%s doubly defined(ignore %d)", (p), (val));\
- }\
- else {\
- (var) = val;\
- }\
- } while(0)
-
-struct in6_prefix {
- struct in6_addr paddr;
- int plen;
-};
-
-struct attr_list {
- struct attr_list *next;
- int type;
- union {
- unsigned int flags;
- double number;
- struct in6_prefix prefix;
- }attru;
-};
-
-enum {IFA_FLAG, IFA_PREFERENCE, IFA_METRIC, RPA_PRIORITY, RPA_TIME,
- BSRA_PRIORITY, BSRA_TIME, BSRA_MASKLEN, IN6_PREFIX, THRESA_RATE,
- THRESA_INTERVAL};
-
-static int strict; /* flag if the grammer check is strict */
-static struct attr_list *rp_attr, *bsr_attr, *grp_prefix, *regthres_attr,
- *datathres_attr;
-static char *cand_rp_ifname, *cand_bsr_ifname;
-static int srcmetric, srcpref, helloperiod, jpperiod, granularity,
- datatimo, regsuptimo, probetime, asserttimo;
-static double helloperiod_coef, jpperiod_coef;
-
-static int debugonly;
-
-extern int yylex __P((void));
-%}
-
-%union {
- unsigned long num;
- double fl;
- vchar_t val;
- struct attr_list *attr;
-}
-
-%token EOS
-%token LOGGING LOGLEV NOLOGLEV
-%token YES NO
-%token REVERSELOOKUP
-%token PHYINT IFNAME DISABLE PREFERENCE METRIC NOLISTENER
-%token GRPPFX
-%token CANDRP CANDBSR TIME PRIORITY MASKLEN
-%token NUMBER STRING SLASH
-%token REGTHRES DATATHRES RATE INTERVAL
-%token SRCMETRIC SRCPREF HELLOPERIOD GRANULARITY JPPERIOD
-%token DATATIME REGSUPTIME PROBETIME ASSERTTIME
-
-%type <num> LOGLEV NOLOGLEV
-%type <fl> NUMBER
-%type <val> STRING IFNAME
-%type <attr> if_attributes rp_substatement rp_attributes
-%type <attr> bsr_substatement bsr_attributes thres_attributes
-
-%%
-statements:
- /* empty */
- | statements statement
- ;
-
-statement:
- logging_statement
- | reverselookup_statement
- | phyint_statement
- | candrp_statement
- | candbsr_statement
- | grppfx_statement
- | regthres_statement
- | datathres_statement
- | param_statement
- ;
-
-/* logging */
-logging_statement:
- LOGGING log_specs EOS
- ;
-
-log_specs:
- /* empty */
- | log_specs LOGLEV {debug |= $2;}
- | log_specs NOLOGLEV {debug &= ~($2);}
- ;
-
-/* reverselookup */
-reverselookup_statement:
- REVERSELOOKUP YES EOS { numerichost = FALSE; }
- | REVERSELOOKUP NO EOS { numerichost = TRUE; }
- ;
-
-/* phyint */
-phyint_statement:
- PHYINT IFNAME if_attributes EOS {
- struct uvif *v;
-
- v = find_vif($2.v);
- free($2.v); /* XXX */
- if (v == NULL) {
- yywarn("unknown interface: %s", $2.v);
- free_attr_list($3);
- if (strict)
- return(-1);
- }
- else {
- struct attr_list *p;
-
- for (p = (struct attr_list *)v->config_attr;
- p && p->next; p = p->next)
- ;
- if (p)
- p->next = (void *)$3;
- else
- v->config_attr = (void *)$3;
- }
- }
- ;
-
-if_attributes:
- { $$ = NULL; }
- | if_attributes DISABLE
- {
- if (($$ = add_attribute_flag($1, IFA_FLAG,
- VIFF_DISABLED)) == NULL)
- return(-1);
- }
- | if_attributes NOLISTENER
- {
- if (($$ = add_attribute_flag($1, IFA_FLAG,
- VIFF_NOLISTENER)) == NULL)
- return(-1);
- }
- | if_attributes PREFERENCE NUMBER
- {
- if (($$ = add_attribute_num($1, IFA_PREFERENCE, $3))
- == NULL)
- return(-1);
- }
- | if_attributes METRIC NUMBER
- {
- if (($$ = add_attribute_num($1, IFA_METRIC, $3))
- == NULL)
- return(-1);
- }
- ;
-
-/* cand_rp */
-candrp_statement:
- CANDRP rp_substatement EOS {
- if (cand_rp_flag == TRUE) {
- yywarn("cand_rp doubly defined");
- free_attr_list($2);
- if (strict)
- return(-1);
- }
- else {
- cand_rp_flag = TRUE;
- rp_attr = $2;
- }
- }
- ;
-/* XXX: intermediate rule to avoid shift-reduce conflict */
-rp_substatement:
- IFNAME rp_attributes
- {
- if (cand_rp_ifname) {
- yywarn("ifname for cand_rp doubly defined");
- if (strict)
- return(-1);
- }
- else
- cand_rp_ifname = $1.v;
- $$ = $2;
- }
- | rp_attributes
- ;
-rp_attributes:
- { $$ = NULL; }
- | rp_attributes PRIORITY NUMBER
- {
- if (($$ = add_attribute_num($1, RPA_PRIORITY, $3))
- == NULL)
- return(-1);
- }
- | rp_attributes TIME NUMBER
- {
- if (($$ = add_attribute_num($1, RPA_TIME, $3))
- == NULL)
- return(-1);
- }
- ;
-
-/* cand_bootstrap_router */
-candbsr_statement:
- CANDBSR bsr_substatement EOS {
- if (cand_bsr_flag == TRUE) {
- yywarn("cand_bsr doubly defined");
- free_attr_list($2);
- if (strict)
- return(-1);
- }
- else {
- cand_bsr_flag = TRUE;
- bsr_attr = $2;
- }
- }
- ;
-/* XXX: intermediate rule to avoid shift-reduce conflict */
-bsr_substatement:
- IFNAME bsr_attributes
- {
- if (cand_bsr_ifname) {
- yywarn("ifname for cand_bsr doubly defined");
- if (strict)
- return(-1);
- }
- else
- cand_bsr_ifname = $1.v;
- $$ = $2;
- }
- | bsr_attributes
- ;
-
-bsr_attributes:
- { $$ = NULL; }
- | bsr_attributes PRIORITY NUMBER
- {
- if (($$ = add_attribute_num($1, BSRA_PRIORITY, $3))
- == NULL)
- return(-1);
- }
- | bsr_attributes TIME NUMBER
- {
- if (($$ = add_attribute_num($1, BSRA_TIME, $3))
- == NULL)
- return(-1);
- }
- | bsr_attributes MASKLEN NUMBER
- {
- int masklen = $3;
-
- if (masklen < 0 || masklen > 128)
- yywarn("invalid mask length: %d (ignored)",
- masklen);
- else if (($$ = add_attribute_num($1, BSRA_MASKLEN,
- masklen))
- == NULL)
- return(-1);
- }
- ;
-
-/* group_prefix <group-addr>/<prefix_len> */
-grppfx_statement:
- GRPPFX STRING SLASH NUMBER EOS {
- struct in6_prefix prefix;
- int prefixok = 1;
-
- if (inet_pton(AF_INET6, $2.v, &prefix.paddr) != 1) {
- yywarn("invalid IPv6 address: %s (ignored)", $2);
- prefixok = 0;
- }
- free($2.v); /* XXX: which was allocated dynamically */
-
- prefix.plen = $4;
- if (prefix.plen < 0 || prefix.plen > 128) {
- yywarn("invalid prefix length: %d (ignored)",
- prefix.plen);
- prefixok = 0;
- }
- if (IN6_IS_ADDR_MC_NODELOCAL(&prefix.paddr) ||
- IN6_IS_ADDR_MC_LINKLOCAL(&prefix.paddr)) {
- yywarn("group prefix (%s/%d) has a narrow scope "
- "(ignored)",
- inet6_fmt(&prefix.paddr), prefix.plen);
- prefixok = 0;
- }
-
- if (prefixok) {
- struct attr_list *new;
-
- if ((new = malloc(sizeof(*new))) == NULL) {
- yyerror("malloc failed");
- return(NULL);
- }
- memset(new, 0, sizeof(*new));
-
- new->type = IN6_PREFIX;
- new->attru.prefix = prefix;
- new->next = grp_prefix;
-
- grp_prefix = new;
- }
- }
- ;
-
-/*
- * switch_register_threshold [rate <number> interval <number>]
- * Operation: reads and assigns the switch to the spt threshold
- * due to registers for the router, if used as RP.
- * Maybe extended to support different thresholds for different
- * groups(prefixes).
- */
-regthres_statement:
- REGTHRES thres_attributes EOS {
- if (regthres_attr) {
- yywarn("switch_register_threshold doubly defined");
- free_attr_list($2);
- if (strict)
- return(-1);
- }
- else
- regthres_attr = $2;
- }
- ;
-
-thres_attributes:
- { $$ = NULL; }
- | thres_attributes RATE NUMBER
- {
- if (($$ = add_attribute_num($1, THRESA_RATE, $3))
- == NULL)
- return(-1);
- }
- | thres_attributes INTERVAL NUMBER
- {
- if (($$ = add_attribute_num($1, THRESA_INTERVAL, $3))
- == NULL)
- return(-1);
- }
-
-/*
- * switch_data_threshold [rate <number> interval <number>]
- * Operation: reads and assigns the switch to the spt threshold due to
- * data packets, if used as DR.
- */
-datathres_statement:
- DATATHRES thres_attributes EOS {
- if (datathres_attr) {
- yywarn("switch_data_threshold doubly defined");
- free_attr_list($2);
- if (strict)
- return(-1);
- }
- else
- datathres_attr = $2;
- }
- ;
-
-param_statement:
- SRCMETRIC NUMBER EOS
- {
- set_param(srcmetric, $2, "default_source_metric");
- }
- | SRCPREF NUMBER EOS
- {
- set_param(srcpref, $2, "default_source_preference");
- }
- | HELLOPERIOD NUMBER EOS
- {
- set_param(helloperiod, $2, "hello_period");
- }
- | HELLOPERIOD NUMBER NUMBER EOS
- {
- set_param(helloperiod, $2, "hello_period");
- set_param(helloperiod_coef, $3, "hello_period(coef)");
- }
- | JPPERIOD NUMBER EOS
- {
- set_param(jpperiod, $2, "join_prune_period");
- }
- | JPPERIOD NUMBER NUMBER EOS
- {
- set_param(jpperiod, $2, "join_prune_period");
- set_param(jpperiod_coef, $3, "join_prune_period(coef)");
- }
- | GRANULARITY NUMBER EOS
- {
- set_param(granularity, $2, "granularity");
- }
- | DATATIME NUMBER EOS
- {
- set_param(datatimo, $2, "data_timeout");
- }
- | REGSUPTIME NUMBER EOS
- {
- set_param(regsuptimo, $2, "register_suppression_timeout");
- }
- | PROBETIME NUMBER EOS
- {
- set_param(probetime, $2, "probe_time");
- }
- | ASSERTTIME NUMBER EOS
- {
- set_param(asserttimo, $2, "assert_timeout");
- }
- ;
-%%
-
-static struct attr_list *add_attribute_flag __P((struct attr_list *, int,
- unsigned int));
-static struct attr_list *add_attribute_num __P((struct attr_list *, int,
- double));
-static void free_attr_list __P((struct attr_list *));
-static int param_config __P((void));
-static int phyint_config __P((void));
-static int rp_config __P((void));
-static int bsr_config __P((void));
-static int grp_prefix_config __P((void));
-static int regthres_config __P((void));
-static int datathres_config __P((void));
-
-static struct attr_list *
-add_attribute_flag(list, type, flag)
- struct attr_list *list;
- int type;
- unsigned int flag;
-{
- struct attr_list *p;
-
- if ((p = malloc(sizeof(*p))) == NULL) {
- yyerror("malloc failed");
- return(NULL);
- }
- memset((void *)p, 0, sizeof(*p));
- p->type = type;
- p->attru.flags = flag;
- p->next = list;
-
- return(p);
-}
-
-/* XXX: too many dup code... */
-static struct attr_list *
-add_attribute_num(list, type, num)
- struct attr_list *list;
- int type;
- double num;
-{
- struct attr_list *p;
-
- if ((p = malloc(sizeof(*p))) == NULL) {
- yyerror("malloc failed");
- return(NULL);
- }
- memset((void *)p, 0, sizeof(*p));
- p->type = type;
- p->attru.number = num;
- p->next = list;
-
- return(p);
-}
-
-static void
-free_attr_list(list)
- struct attr_list *list;
-{
- struct attr_list *p, *next;
-
- for(p = list; p; p = next) {
- next = p->next;
- free(p);
- }
-}
-
-static int
-param_config()
-{
- struct uvif *v;
- vifi_t vifi;
-
- /* at first, set the default values to all the undefined variables */
- if (srcmetric == -1) srcmetric = DEFAULT_LOCAL_METRIC;
- if (srcpref == -1) srcpref = DEFAULT_LOCAL_PREF;
- if (helloperiod == -1) helloperiod = PIM_TIMER_HELLO_PERIOD;
- if (helloperiod_coef == -1) helloperiod_coef = 3.5;
- if (jpperiod == -1) jpperiod = PIM_JOIN_PRUNE_PERIOD;
- if (jpperiod_coef == -1) jpperiod_coef = 3.5;
- if (granularity == -1) granularity = DEFAULT_TIMER_INTERVAL;
- if (datatimo == -1) datatimo = PIM_DATA_TIMEOUT;
- if (regsuptimo == -1) regsuptimo = PIM_REGISTER_SUPPRESSION_TIMEOUT;
- if (probetime == -1) probetime = PIM_REGISTER_PROBE_TIME;
- if (asserttimo == -1) asserttimo = PIM_ASSERT_TIMEOUT;
-
- /* set protocol parameters using the configuration variables */
- for (vifi = 0, v = uvifs; vifi < MAXVIFS; ++vifi, ++v) {
- v->uv_local_metric = srcmetric;
- v->uv_local_pref = srcpref;
- }
- pim_hello_period = helloperiod;
- pim_hello_holdtime = helloperiod * helloperiod_coef;
- pim_join_prune_period = jpperiod;
- pim_join_prune_holdtime = jpperiod * jpperiod_coef;
- timer_interval = granularity;
- pim_data_timeout = datatimo;
- pim_register_suppression_timeout = regsuptimo;
- pim_register_probe_time = probetime;
- pim_assert_timeout = asserttimo;
-
- IF_DEBUG(DEBUG_PIM_HELLO) {
- log(LOG_DEBUG, 0, "pim_hello_period set to: %u",
- pim_hello_period);
- log(LOG_DEBUG, 0, "pim_hello_holdtime set to: %u",
- pim_hello_holdtime);
- }
-
- IF_DEBUG(DEBUG_PIM_JOIN_PRUNE) {
- log(LOG_DEBUG,0 , "pim_join_prune_period set to: %u",
- pim_join_prune_period);
- log(LOG_DEBUG, 0, "pim_join_prune_holdtime set to: %u",
- pim_join_prune_holdtime);
- }
- IF_DEBUG(DEBUG_TIMER) {
- log(LOG_DEBUG,0 , "timer interval set to: %u", timer_interval);
- }
- IF_DEBUG(DEBUG_PIM_TIMER) {
- log(LOG_DEBUG,0 , "PIM data timeout set to: %u",
- pim_data_timeout);
- }
- IF_DEBUG(DEBUG_PIM_REGISTER) {
- log(LOG_DEBUG, 0,
- "PIM register suppression timeout set to: %u",
- pim_register_suppression_timeout);
- log(LOG_DEBUG, 0, "PIM register probe time set to: %u",
- pim_register_probe_time);
- }
- IF_DEBUG(DEBUG_PIM_ASSERT) {
- log(LOG_DEBUG, 0,
- "PIM assert timeout set to: %u",
- pim_assert_timeout);
- }
- return(0);
-}
-
-static int
-phyint_config()
-{
- struct uvif *v;
- vifi_t vifi;
- struct attr_list *al;
-
- for (vifi = 0, v = uvifs; vifi < numvifs ; ++vifi , ++v) {
- for (al = (struct attr_list *)v->config_attr; al; al = al->next) {
- switch(al->type) {
- case IFA_FLAG:
- v->uv_flags |= al->attru.flags;
- break;
- case IFA_PREFERENCE:
- if (al->attru.number < 1 ||
- al->attru.number > 255)
- yywarn("invalid phyint preference(%d)",
- (int)al->attru.number);
- else {
- v->uv_local_pref = al->attru.number;
- IF_DEBUG(DEBUG_ASSERT)
- log(LOG_DEBUG, 0,
- "default localpref for %s "
- "is %d",
- v->uv_name,
- v->uv_local_pref);
- }
- break;
- case IFA_METRIC:
- if (al->attru.number < 1 ||
- al->attru.number > 1024)
- yywarn("invalid metric(%d)",
- al->attru.number);
- else {
- v->uv_metric = al->attru.number;
- IF_DEBUG(DEBUG_ASSERT)
- log(LOG_DEBUG, 0,
- "default local metric for %s "
- "is %d",
- v->uv_name,
- v->uv_metric);
- }
- break;
- }
- }
- }
-
- return(0);
-}
-
-static int
-rp_config()
-{
- struct sockaddr_in6 *sa6_rp = NULL;
- struct attr_list *al;
- u_int8 *data_ptr;
-
- /* initialization by default values */
- my_cand_rp_adv_period = PIM_DEFAULT_CAND_RP_ADV_PERIOD;
- my_cand_rp_priority = PIM_DEFAULT_CAND_RP_PRIORITY;
-
- if (cand_rp_ifname) {
- sa6_rp = local_iface(cand_rp_ifname);
- if (!sa6_rp)
- log(LOG_WARNING, 0,
- "cand_rp '%s' is not configured. "
- "take the max local address the router..",
- cand_rp_ifname);
- }
-
- for (al = rp_attr; al; al = al->next) {
- switch(al->type) {
- case RPA_PRIORITY:
- if (al->attru.number < 0)
- my_cand_rp_priority =
- PIM_DEFAULT_CAND_RP_PRIORITY;
- else
- my_cand_rp_priority = al->attru.number;
- break;
- case RPA_TIME:
- if (al->attru.number < 10)
- my_cand_rp_adv_period = 10;
- else if (al->attru.number > PIM_DEFAULT_CAND_RP_ADV_PERIOD)
- my_cand_rp_adv_period =
- PIM_DEFAULT_CAND_RP_ADV_PERIOD;
- else
- my_cand_rp_adv_period = al->attru.number;
- break;
- default:
- yywarn("unknown attribute(%d) for RP", al->type);
- break;
- }
- }
-
- if (!sa6_rp)
- sa6_rp = max_global_address(); /* this MUST suceed */
- my_cand_rp_address = *sa6_rp;
-
- /*
- * initialize related parameters
- */
-
- /*
- * Note that sizeof(pim6_enocd_uni_addr_t) might be larger than
- * the length of the Encoded-Unicast-address field(18 byte) due to
- * some padding put in the compiler. However, it doesn't matter
- * since we use the space just as a buffer(i.e not as the message).
- */
- cand_rp_adv_message.buffer = (u_int8 *)malloc(4 +
- sizeof(pim6_encod_uni_addr_t) +
- 255*sizeof(pim6_encod_grp_addr_t));
- if(cand_rp_adv_message.buffer == NULL)
- log(LOG_ERR, 0, "Candrpadv Buffer allocation");
-
- cand_rp_adv_message.prefix_cnt_ptr = cand_rp_adv_message.buffer;
-
- /*
- * By default, if no group_prefix configured, then prefix_cnt == 0
- * implies group_prefix = ff00::/8 and masklen = 8.
- */
- *cand_rp_adv_message.prefix_cnt_ptr = 0;
- cand_rp_adv_message.insert_data_ptr = cand_rp_adv_message.buffer;
-
- /* TODO: XXX: HARDCODING!!! */
- cand_rp_adv_message.insert_data_ptr += (4 + 18);
- cand_rp_adv_message.message_size =
- cand_rp_adv_message.insert_data_ptr - cand_rp_adv_message.buffer;
-
- my_cand_rp_holdtime = 2.5 * my_cand_rp_adv_period;
-
- /* TODO: HARDCODING! */
- data_ptr = cand_rp_adv_message.buffer + 1; /* WARNING */
- PUT_BYTE(my_cand_rp_priority,data_ptr);
- PUT_HOSTSHORT(my_cand_rp_holdtime, data_ptr);
- PUT_EUADDR6(my_cand_rp_address.sin6_addr,data_ptr);
- IF_DEBUG(DEBUG_PIM_CAND_RP) {
- log(LOG_DEBUG, 0,
- "Local Cand-RP address is : %s",
- inet6_fmt(&my_cand_rp_address.sin6_addr));
- log(LOG_DEBUG, 0,
- "Local Cand-RP priority is : %u",my_cand_rp_priority);
- log(LOG_DEBUG, 0,
- "Local Cand-RP advertisement period is : %u sec.",
- my_cand_rp_adv_period);
- }
-
- return(0);
-}
-
-static int
-bsr_config()
-{
- struct sockaddr_in6 *sa6_bsr = NULL;
- struct attr_list *al;
- int my_bsr_hash_masklen;
-
- /* initialization by default values */
- my_bsr_period = PIM_DEFAULT_BOOTSTRAP_PERIOD;
- my_bsr_priority = PIM_DEFAULT_BSR_PRIORITY;
- my_bsr_hash_masklen = RP_DEFAULT_IPV6_HASHMASKLEN;
-
- if (cand_bsr_ifname) {
- sa6_bsr = local_iface(cand_bsr_ifname);
- if (!sa6_bsr)
- log(LOG_WARNING, 0,
- "bsr '%s' is not configured. "
- "take the max local address the router..",
- cand_bsr_ifname);
- }
-
- for (al = bsr_attr; al; al = al->next) {
- switch(al->type) {
- case BSRA_PRIORITY:
- if (al->attru.number >= 0)
- my_bsr_priority = al->attru.number;
- break;
- case BSRA_MASKLEN:
- /* validation has been done. */
- my_bsr_hash_masklen = al->attru.number;
- break;
- case BSRA_TIME:
- if (al->attru.number < 10)
- my_bsr_period = 10;
- else if (al->attru.number > PIM_DEFAULT_BOOTSTRAP_PERIOD)
- my_bsr_period =
- PIM_DEFAULT_BOOTSTRAP_PERIOD;
- else
- my_bsr_period = al->attru.number;
- break;
- default:
- yywarn("unknown attribute(%d) for BSR", al->type);
- break;
- }
- }
-
- if (!sa6_bsr)
- sa6_bsr = max_global_address(); /* this MUST suceed */
- my_bsr_address = *sa6_bsr;
- MASKLEN_TO_MASK6(my_bsr_hash_masklen, my_bsr_hash_mask);
-
- IF_DEBUG(DEBUG_PIM_BOOTSTRAP) {
- log(LOG_DEBUG, 0, "Local BSR address: %s",
- inet6_fmt(&my_bsr_address.sin6_addr));
- log(LOG_DEBUG, 0, "Local BSR priority : %u", my_bsr_priority);
- log(LOG_DEBUG, 0, "Local BSR period is : %u sec.",
- my_bsr_period);
- log(LOG_DEBUG, 0, "Local BSR hash mask length: %d",
- my_bsr_hash_masklen);
- }
-
- return(0);
-}
-
-static int
-grp_prefix_config()
-{
- struct attr_list *pl;
-
- if (cand_rp_flag != TRUE) {
- log(LOG_WARNING, 0,
- "group_prefix was specified without cand_rp(ignored)");
- return(0);
- }
-
- for (pl = grp_prefix; pl; pl = pl->next) {
- if (!IN6_IS_ADDR_MULTICAST(&pl->attru.prefix.paddr)) {
- log(LOG_WARNING, 0,
- "Config error: %s is not a mulicast address(ignored)",
- inet6_fmt(&pl->attru.prefix.paddr));
- continue;
- }
-
- if (!(~(*cand_rp_adv_message.prefix_cnt_ptr))) {
- log(LOG_WARNING, 0,
- "Too many group_prefix configured. Truncating...");
- break;
- }
-
- /* validation for plen has almost done */
- if (pl->attru.prefix.plen < PIM_GROUP_PREFIX_DEFAULT_MASKLEN)
- pl->attru.prefix.plen = PIM_GROUP_PREFIX_DEFAULT_MASKLEN;
-
- PUT_EGADDR6(pl->attru.prefix.paddr,
- (u_int8)pl->attru.prefix.plen, 0,
- cand_rp_adv_message.insert_data_ptr);
- (*cand_rp_adv_message.prefix_cnt_ptr)++;
- }
-
- /* finally, adjust the data size */
- cand_rp_adv_message.message_size =
- cand_rp_adv_message.insert_data_ptr - cand_rp_adv_message.buffer;
-
- return(0);
-}
-
-static int
-regthres_config()
-{
- struct attr_list *al;
- int rate = -1;
- int interval = -1;
-
- if (cand_rp_flag != TRUE) {
- log(LOG_WARNING, 0,
- "register_threshold was specified without cand_rp");
- }
-
- for (al = regthres_attr; al; al = al->next) {
- switch(al->type) {
- case THRESA_RATE:
- if (al->attru.number < 0)
- yywarn("invalid regthres rate: %d(ignored)",
- al->attru.number);
- else if (rate != -1)
- yywarn("regthres rate is doubly defined(ignored)");
- else
- rate = al->attru.number;
- break;
- case THRESA_INTERVAL:
- if (al->attru.number < 0)
- yywarn("invalid regthres interval: %d(ignored)",
- al->attru.number);
- else if (interval != -1)
- yywarn("regthres interval is doubly defined(ignored)");
- else
- interval = al->attru.number;
- break;
- default:
- yywarn("unknown attribute(%d) for regthres", al->type);
- break;
- }
- }
-
- /* set default values if not specified */
- if (rate == -1)
- rate = PIM_DEFAULT_REG_RATE;
- if (interval == -1)
- interval = PIM_DEFAULT_REG_RATE_INTERVAL;
-
- pim_reg_rate_bytes = (rate * interval ) /10;
- pim_reg_rate_check_interval = interval;
-
- return(0);
-}
-
-static int
-datathres_config()
-{
- struct attr_list *al;
- int rate = -1;
- int interval = -1;
-
- for (al = datathres_attr; al; al = al->next) {
- switch(al->type) {
- case THRESA_RATE:
- if (al->attru.number < 0)
- yywarn("invalid datathres rate: %d(ignored)",
- al->attru.number);
- else if (rate != -1)
- yywarn("datathres rate is doubly defined(ignored)");
- else
- rate = al->attru.number;
- break;
- case THRESA_INTERVAL:
- if (al->attru.number < 0)
- yywarn("invalid datathres interval: %d(ignored)",
- al->attru.number);
- else if (interval != -1)
- yywarn("datathres interval is doubly defined(ignored)");
- else
- interval = al->attru.number;
- break;
- default:
- yywarn("unknown attribute(%d) for datathres", al->type);
- break;
- }
- }
-
- /* set default values if not specified */
- if (rate == -1)
- rate = PIM_DEFAULT_DATA_RATE;
- if (interval == -1)
- interval = PIM_DEFAULT_DATA_RATE_INTERVAL;
-
- pim_data_rate_bytes = (rate * interval ) /10;
- pim_data_rate_check_interval = interval;
-
- return(0);
-}
-
-int
-cf_post_config()
-{
- struct uvif *v;
- vifi_t vifi;
-
- if (debugonly)
- goto cleanup;
-
- param_config(); /* must be called before phyint_conifg() */
-
- phyint_config();
-
- if (cand_bsr_flag == TRUE)
- bsr_config();
-
- if (cand_rp_flag == TRUE)
- rp_config();
-
- if (grp_prefix) /* this must be called after rp_config() */
- grp_prefix_config();
-
- if (cand_rp_flag == TRUE)
- regthres_config();
-
- datathres_config();
-
- IF_DEBUG(DEBUG_SWITCH) {
- log(LOG_DEBUG, 0, "reg_rate_limit set to %u (bits/s)",
- pim_reg_rate_bytes);
- log(LOG_DEBUG, 0, "reg_rate_interval set to %u s.",
- pim_reg_rate_check_interval);
- log(LOG_DEBUG, 0, "data_rate_limit set to %u (bits/s)",
- pim_data_rate_bytes);
- log(LOG_DEBUG, 0, "data_rate_interval set to %u s.",
- pim_data_rate_check_interval);
- }
-
- cleanup:
- /* cleanup temporary variables */
- if (cand_rp_ifname) free(cand_rp_ifname);
- if (cand_bsr_ifname) free(cand_bsr_ifname);
- if (rp_attr) free_attr_list(rp_attr);
- if (bsr_attr) free_attr_list(bsr_attr);
- if (grp_prefix) free_attr_list(grp_prefix);
- if (regthres_attr) free_attr_list(regthres_attr);
- if (datathres_attr) free_attr_list(datathres_attr);
- for (vifi = 0, v = uvifs; vifi < numvifs ; ++vifi , ++v)
- free_attr_list((struct attr_list *)v->config_attr);
-
- return(0);
-}
-
-/* initialize all the temporary variables */
-void
-cf_init(s, d)
-{
- struct uvif *v;
- vifi_t vifi;
-
- strict = s;
- debugonly = d;
-
- debug = 0;
-
- rp_attr = bsr_attr = grp_prefix = regthres_attr = datathres_attr = NULL;
-
- cand_rp_ifname = cand_bsr_ifname = NULL;
-
- srcmetric = srcpref = helloperiod = jpperiod = jpperiod_coef
- = granularity = datatimo = regsuptimo = probetime
- = asserttimo = -1;
- helloperiod_coef = jpperiod_coef = -1;
-
- for (vifi = 0, v = uvifs; vifi < numvifs ; ++vifi , ++v)
- v->config_attr = NULL;
-}
diff --git a/usr.sbin/pim6sd/cftoken.l b/usr.sbin/pim6sd/cftoken.l
deleted file mode 100644
index 1a9abde..0000000
--- a/usr.sbin/pim6sd/cftoken.l
+++ /dev/null
@@ -1,664 +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.
- *
- * $FreeBSD$
- */
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#ifdef HAVE_STDARG_H
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-
-#include "var.h"
-#include "vmbuf.h"
-#include "debug.h"
-#include "cfparse.h"
-#include "y.tab.h"
-
-static int yyerrorcount = 0;
-int lineno = 1;
-int yy_first_time = 1;
-
-extern char configfilename[];
-
-#if 0
-static void cfdebug_print __P((char *, char *, int));
-#endif
-
-extern int yylex __P((void));
-%}
-
-/* common seciton */
-nl \n
-ws [ \t]+
-comment \#.*
-semi \;
-string [a-zA-Z0-9:\._][a-zA-Z0-9:\._]*
-digit [0-9]
-integer {digit}+
-number {integer}|({digit}*\.{integer})
-hexdigit [0-9A-Fa-f]
-hexpair {hexdigit}{hexdigit}
-hexstring 0[xX]{hexpair}+
-ifname [a-zA-Z]+[0-9]+
-slash \/
-
-%s S_CNF
-%s S_LOG
-%s S_PHYINT S_IFCONF S_CANDRP S_CANDBSR S_PREFIX
-%s S_THRES
-
-%%
-%{
- if (yy_first_time) {
- BEGIN S_CNF;
- yy_first_time = 0;
- }
-%}
-
- /* logging */
-<S_CNF>log { DP("begin logging"); BEGIN S_LOG; return(LOGGING); }
-<S_LOG>(no)?mld_proto {
- YYD_ECHO;
- yylval.num = DEBUG_MLD_PROTO;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?mld_timer {
- YYD_ECHO;
- yylval.num = DEBUG_MLD_TIMER;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?mld_member {
- YYD_ECHO;
- yylval.num = DEBUG_MLD_MEMBER;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?mld {
- YYD_ECHO;
- yylval.num = DEBUG_MLD;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?switch {
- YYD_ECHO;
- yylval.num = DEBUG_SWITCH;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?m?trace {
- YYD_ECHO;
- yylval.num = DEBUG_TRACE;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?traceroute {
- YYD_ECHO;
- yylval.num = DEBUG_TRACE;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?timeout {
- YYD_ECHO;
- yylval.num = DEBUG_TIMEOUT;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?callout {
- YYD_ECHO;
- yylval.num = DEBUG_TIMEOUT;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?pkt {
- YYD_ECHO;
- yylval.num = DEBUG_PKT;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?packets {
- YYD_ECHO;
- yylval.num = DEBUG_PKT;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?interfaces {
- YYD_ECHO;
- yylval.num = DEBUG_IF;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?vif {
- YYD_ECHO;
- yylval.num = DEBUG_IF;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?kernel {
- YYD_ECHO;
- yylval.num = DEBUG_KERN;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?cache {
- YYD_ECHO;
- yylval.num = DEBUG_MFC;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?mfc {
- YYD_ECHO;
- yylval.num = DEBUG_MFC;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?k_cache {
- YYD_ECHO;
- yylval.num = DEBUG_MFC;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?k_mfc {
- YYD_ECHO;
- yylval.num = DEBUG_MFC;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?rsrr {
- YYD_ECHO;
- yylval.num = DEBUG_RSRR;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?pim_detail {
- YYD_ECHO;
- yylval.num = DEBUG_PIM_DETAIL;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?pim_hello {
- YYD_ECHO;
- yylval.num = DEBUG_PIM_HELLO;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?pim_neighbors {
- YYD_ECHO;
- yylval.num = DEBUG_PIM_HELLO;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?pim_register {
- YYD_ECHO;
- yylval.num = DEBUG_PIM_REGISTER;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?registers {
- YYD_ECHO;
- yylval.num = DEBUG_PIM_REGISTER;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?pim_join_prune {
- YYD_ECHO;
- yylval.num = DEBUG_PIM_JOIN_PRUNE;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?pim_j_p {
- YYD_ECHO;
- yylval.num = DEBUG_PIM_JOIN_PRUNE;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?pim_jp {
- YYD_ECHO;
- yylval.num = DEBUG_PIM_JOIN_PRUNE;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?pim_bootstrap {
- YYD_ECHO;
- yylval.num = DEBUG_PIM_BOOTSTRAP;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?pim_bsr {
- YYD_ECHO;
- yylval.num = DEBUG_PIM_BOOTSTRAP;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?bsr {
- YYD_ECHO;
- yylval.num = DEBUG_PIM_BOOTSTRAP;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?bootstrap {
- YYD_ECHO;
- yylval.num = DEBUG_PIM_BOOTSTRAP;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?pim_asserts {
- YYD_ECHO;
- yylval.num = DEBUG_PIM_ASSERT;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?pim_cand_rp {
- YYD_ECHO;
- yylval.num = DEBUG_PIM_CAND_RP;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?pim_c_rp {
- YYD_ECHO;
- yylval.num = DEBUG_PIM_CAND_RP;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?pim_rp {
- YYD_ECHO;
- yylval.num = DEBUG_PIM_CAND_RP;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?rp {
- YYD_ECHO;
- yylval.num = DEBUG_PIM_CAND_RP;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?pim_routes {
- YYD_ECHO;
- yylval.num = DEBUG_PIM_MRT;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?pim_routing {
- YYD_ECHO;
- yylval.num = DEBUG_PIM_MRT;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?pim_mrt {
- YYD_ECHO;
- yylval.num = DEBUG_PIM_MRT;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?pim_timers {
- YYD_ECHO;
- yylval.num = DEBUG_PIM_TIMER;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?pim_rpf {
- YYD_ECHO;
- yylval.num = DEBUG_PIM_RPF;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?rpf {
- YYD_ECHO;
- yylval.num = DEBUG_RPF;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?pim {
- YYD_ECHO;
- yylval.num = DEBUG_PIM;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?routes {
- YYD_ECHO;
- yylval.num = DEBUG_MRT;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?routing {
- YYD_ECHO;
- yylval.num = DEBUG_MRT;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?mrt {
- YYD_ECHO;
- yylval.num = DEBUG_MRT;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?routers {
- YYD_ECHO;
- yylval.num = DEBUG_NEIGHBORS;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?mrouters {
- YYD_ECHO;
- yylval.num = DEBUG_NEIGHBORS;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?neighbors {
- YYD_ECHO;
- yylval.num = DEBUG_NEIGHBORS;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?timers {
- YYD_ECHO;
- yylval.num = DEBUG_TIMER;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>(no)?asserts {
- YYD_ECHO;
- yylval.num = DEBUG_ASSERT;
- if (strncmp("no", yytext, 2))
- return(LOGLEV);
- else
- return(NOLOGLEV);
-}
-<S_LOG>all { YYD_ECHO; yylval.num = DEBUG_ALL; return(LOGLEV); }
-<S_LOG>3 { YYD_ECHO; yylval.num = DEBUG_ALL; return(LOGLEV); }
-<S_LOG>{semi} { DP("end logging"); BEGIN S_CNF; return(EOS); }
-<S_LOG>{string} { yywarn("unknown log type: %s (ignored)", yytext); }
-
- /* yes-or-no */
-[yY][eE][sS] { YYD_ECHO; return(YES); }
-[nN][oO] { YYD_ECHO; return(NO); }
-
- /* reverselookup */
-<S_CNF>reverselookup { YYD_ECHO; return(REVERSELOOKUP); }
-
- /* phyint */
-<S_CNF>phyint { DP("begin phyint"); BEGIN S_PHYINT; return(PHYINT); }
-<S_PHYINT>{string} {
- YYD_ECHO;
- BEGIN S_IFCONF;
- yylval.val.l = strlen(yytext);
- yylval.val.v = strdup(yytext);
- return(IFNAME);
-}
-<S_PHYINT>{semi} { yyerror("phyint was specified without interface."); return(EOS); }
-<S_IFCONF>disable { YYD_ECHO; return(DISABLE); }
-<S_IFCONF>preference { YYD_ECHO; return(PREFERENCE); }
-<S_IFCONF>metric { YYD_ECHO; return(METRIC); }
-<S_IFCONF>nolistener { YYD_ECHO; return(NOLISTENER); }
-<S_IFCONF>{semi} { DP("end phyint"); BEGIN S_CNF; return(EOS); }
-
- /* cand_rp */
-<S_CNF>cand_rp { DP("begin cand_rp"); BEGIN S_CANDRP; return(CANDRP); }
-<S_CANDRP>priority { YYD_ECHO; return(PRIORITY); }
-<S_CANDRP>time { YYD_ECHO; return(TIME); }
-<S_CANDRP>{ifname} {
- YYD_ECHO;
- yylval.val.l = strlen(yytext);
- yylval.val.v = strdup(yytext);
- return(IFNAME);
-}
-<S_CANDRP>{semi} { DP("end cand_rp"); BEGIN S_CNF; return(EOS); }
-
- /* cand_bootstrap_router */
-<S_CNF>cand_bootstrap_router { DP("begin cand_bsr"); BEGIN S_CANDBSR; return(CANDBSR); }
-<S_CANDBSR>priority { YYD_ECHO; return(PRIORITY); }
-<S_CANDBSR>masklen { YYD_ECHO; return(MASKLEN); }
-<S_CANDBSR>time { YYD_ECHO; return(TIME); }
-<S_CANDBSR>{ifname} {
- YYD_ECHO;
- yylval.val.l = strlen(yytext);
- yylval.val.v = strdup(yytext);
- return(IFNAME);
-}
-<S_CANDBSR>{semi} { DP("end cand_bsr"); BEGIN S_CNF; return(EOS); }
-
- /* group_prefix */
-<S_CNF>group_prefix { YYD_ECHO; return(GRPPFX); }
-
- /* switch_register_threshold */
-<S_CNF>switch_register_threshold {
- YYD_ECHO; BEGIN S_THRES; return(REGTHRES);
-}
- /* switch_data_threshold */
-<S_CNF>switch_data_threshold {
- YYD_ECHO; BEGIN S_THRES; return(DATATHRES);
-}
-<S_THRES>rate { YYD_ECHO; return(RATE); }
-<S_THRES>interval { YYD_ECHO; return(INTERVAL); }
-<S_THRES>{semi} { DP("end thres"); BEGIN S_CNF; return(EOS); }
-
- /* various parameters */
-<S_CNF>default_source_metric { YYD_ECHO; return(SRCMETRIC); }
-<S_CNF>default_source_preference { YYD_ECHO; return(SRCPREF); }
-<S_CNF>hello_period { YYD_ECHO; return(HELLOPERIOD); }
-<S_CNF>granularity { YYD_ECHO; return(GRANULARITY); }
-<S_CNF>join_prune_period { YYD_ECHO; return(JPPERIOD); }
-<S_CNF>data_timeout { YYD_ECHO; return(DATATIME); }
-<S_CNF>register_suppression_timeout { YYD_ECHO; return(REGSUPTIME); }
-<S_CNF>probe_time { YYD_ECHO; return(PROBETIME); }
-<S_CNF>assert_timeout { YYD_ECHO; return(ASSERTTIME); }
-
- /* misc */
-{ws} { ; }
-{nl} { lineno++; }
-{comment} { DP("comment"); }
-{number} { YYD_ECHO; yylval.fl = atof(yytext); return(NUMBER); }
-{slash} { YYD_ECHO; return(SLASH); }
-{semi} { DP("end cnf"); return(EOS); }
-
- /* last resort */
-{string} {
- YYD_ECHO;
- yylval.val.l = strlen(yytext);
- yylval.val.v = strdup(yytext);
- return(STRING);
- }
-%%
-
-#if 0
-static void
-cfdebug_print(w, t, l)
- char *w, *t;
- int l;
-{
- printf("<%d>%s [%s] (%d)\n", yy_start, w, t, l);
-}
-#endif
-
-static void
-yyerror0(char *s, va_list ap)
-{
- fprintf(stderr, "%s %d: ", configfilename, lineno);
- vfprintf(stderr, s, ap);
- fprintf(stderr, "\n");
-}
-
-void
-yyerror(char *s, ...)
-{
- va_list ap;
-#ifdef HAVE_STDARG_H
- va_start(ap, s);
-#else
- va_start(ap);
-#endif
- yyerror0(s, ap);
- va_end(ap);
- yyerrorcount++;
-}
-
-void
-yywarn(char *s, ...)
-{
- va_list ap;
-#ifdef HAVE_STDARG_H
- va_start(ap, s);
-#else
- va_start(ap);
-#endif
- yyerror0(s, ap);
- va_end(ap);
-}
-
-int
-cfparse(strict, debugonly)
- int strict, debugonly;
-{
- if ((yyin = fopen(configfilename, "r")) == NULL) {
- fprintf(stderr, "cfparse: fopen(%s)\n", configfilename);
- return(-1);
- }
-
- cf_init(strict, debugonly);
-
- if ((yyparse() || yyerrorcount) && strict) {
- if (yyerrorcount) {
- yyerror("fatal parse failure: exiting (%d errors)",
- yyerrorcount);
- } else
- yyerror("fatal parse failure: exiting");
- return(-1);
- }
-
- YIPSDP(PLOG("parse successed.\n"));
-
- return cf_post_config();
-}
diff --git a/usr.sbin/pim6sd/config.c b/usr.sbin/pim6sd/config.c
deleted file mode 100644
index 7cbd7d8..0000000
--- a/usr.sbin/pim6sd/config.c
+++ /dev/null
@@ -1,495 +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
- * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
- *
- */
-/*
- * This program has been derived from pim6dd.
- * The pim6dd program is covered by the license in the accompanying file
- * named "LICENSE.pim6dd".
- */
-/*
- * This program has been derived from pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- */
-/*
- * 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/ioctl.h>
-#include <syslog.h>
-#include <stdlib.h>
-#include "vif.h"
-#include "pim6.h"
-#include "inet6.h"
-#include "rp.h"
-#include "pimd.h"
-#include "timer.h"
-#include "route.h"
-#if defined(__FreeBSD__) && __FreeBSD__ >= 3
-#include <net/if_var.h>
-#endif
-#include <netinet6/in6_var.h>
-#ifdef HAVE_GETIFADDRS
-#include <ifaddrs.h>
-#endif
-#include <string.h>
-#include <errno.h>
-#include <ctype.h>
-#include "config.h"
-#include <arpa/inet.h>
-#include <stdio.h>
-#include "debug.h"
-
-void add_phaddr(struct uvif *v, struct sockaddr_in6 *addr,
- struct in6_addr *mask);
-
-void
-config_vifs_from_kernel()
-{
- register struct uvif *v;
- register vifi_t vifi;
- int i;
- struct sockaddr_in6 addr;
- struct in6_addr mask;
- 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, "getifaddrs");
-
- /*
- * Loop through all of the interfaces.
- */
- for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
- struct in6_ifreq ifr6;
-
- /*
- * Ignore any interface for an address family other than IPv6.
- */
- if (ifa->ifa_addr->sa_family != AF_INET6) {
- /* Eventually may have IPv6 address later */
- total_interfaces++;
- continue;
- }
-
- memcpy(&addr, ifa->ifa_addr, sizeof(struct sockaddr_in6));
-
- flags = ifa->ifa_flags;
-
-
- /*
- * Get netmask of the address.
- */
- memcpy(&mask,
- &((struct sockaddr_in6 *)ifa->ifa_netmask)->sin6_addr,
- sizeof(mask));
-
- /*
- * Get IPv6 specific flags, and ignore an anycast address.
- * XXX: how about a deprecated, tentative, duplicated or
- * detached address?
- */
- memcpy(ifr6.ifr_name, ifa->ifa_name, sizeof(ifr6.ifr_name));
- ifr6.ifr_addr = *(struct sockaddr_in6 *)ifa->ifa_addr;
- if (ioctl(udp_socket, SIOCGIFAFLAG_IN6, &ifr6) < 0) {
- log(LOG_ERR, errno, "ioctl SIOCGIFAFLAG_IN6 for %s",
- inet6_fmt(&ifr6.ifr_addr.sin6_addr));
- }
- else {
- if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_ANYCAST) {
- log(LOG_DEBUG, 0, "config_vifs_from_kernel: "
- "%s on %s is an anycast address, ignored",
- inet6_fmt(&ifr6.ifr_addr.sin6_addr),
- ifa->ifa_name);
- continue;
- }
- }
-
- 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 vifs, 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_dst_addr = allpim6routers_group;
- v->uv_subnetmask = mask;
- strncpy(v->uv_name, ifa->ifa_name, IFNAMSIZ);
- v->uv_ifindex = if_nametoindex(v->uv_name);
- add_phaddr(v, &addr,&mask);
-
- /* prefix local calc. (and what about add_phaddr?...) */
- for (i = 0; i < sizeof(struct in6_addr); i++)
- v->uv_prefix.sin6_addr.s6_addr[i] =
- addr.sin6_addr.s6_addr[i] & mask.s6_addr[i];
-
- if(flags & IFF_POINTOPOINT)
- v->uv_flags |=(VIFF_REXMIT_PRUNES | VIFF_POINT_TO_POINT);
-
- /*
- * Disable multicast routing on loopback interfaces and
- * interfaces that do not support multicast. But they are
- * still necessary, since global addresses maybe assigned only
- * on such interfaces.
- */
- if ((flags & IFF_LOOPBACK) != 0 ||
- (flags & IFF_MULTICAST) == 0)
- v->uv_flags |= VIFF_DISABLED;
-
- IF_DEBUG(DEBUG_IF)
- log(LOG_DEBUG,0,
- "Installing %s (%s on subnet %s) ,"
- "as vif #%u - rate = %d",
- v->uv_name,inet6_fmt(&addr.sin6_addr),
- net6name(&v->uv_prefix.sin6_addr,&mask),
- numvifs,v->uv_rate_limit);
-
- ++numvifs;
-
-
- 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
-
- /*
- * Ignore any interface for an address family other than IPv6.
- */
- if ( ifrp->ifr_addr.sa_family != AF_INET6)
- {
- /* Eventually may have IP address later */
- total_interfaces++;
- 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));
-
- if(ioctl(udp_socket,SIOCGIFFLAGS,(char *)&ifr) <0)
- log(LOG_ERR, errno, "ioctl SIOCGIFFLAGS for %s", ifr.ifr_name);
- flags = ifr.ifr_flags;
-
-#if 0
- /*
- * Ignore loopback interfaces and interfaces that do not
- * support multicast.
- */
- if((flags & (IFF_LOOPBACK | IFF_MULTICAST ))!= IFF_MULTICAST)
- continue;
-#endif
-
- /*
- * 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",
- inet6_fmt(&ifr6.ifr_addr.sin6_addr));
- memcpy(&mask,&ifr6.ifr_addr.sin6_addr,sizeof(mask));
-
- /*
- * Get IPv6 specific flags, and ignore an anycast address.
- * XXX: how about a deprecated, tentative, duplicated or
- * detached address?
- */
- ifr6.ifr_addr = *(struct sockaddr_in6 *)&ifrp->ifr_addr;
- if (ioctl(udp_socket, SIOCGIFAFLAG_IN6, &ifr6) < 0) {
- log(LOG_ERR, errno, "ioctl SIOCGIFAFLAG_IN6 for %s",
- inet6_fmt(&ifr6.ifr_addr.sin6_addr));
- }
- else {
- if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_ANYCAST) {
- log(LOG_DEBUG, 0, "config_vifs_from_kernel: "
- "%s on %s is an anycast address, ignored",
- inet6_fmt(&ifr6.ifr_addr.sin6_addr),
- ifr.ifr_name);
- continue;
- }
- }
-
- 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 vifs, 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_dst_addr = allpim6routers_group;
- v->uv_subnetmask = mask;
- strncpy ( v->uv_name , ifr.ifr_name,IFNAMSIZ);
- v->uv_ifindex = if_nametoindex(v->uv_name);
- add_phaddr(v,&addr,&mask);
-
- /* prefix local calc. (and what about add_phaddr?...) */
- for (i = 0; i < sizeof(struct in6_addr); i++)
- v->uv_prefix.sin6_addr.s6_addr[i] =
- addr.sin6_addr.s6_addr[i] & mask.s6_addr[i];
-
- if(flags & IFF_POINTOPOINT)
- v->uv_flags |=(VIFF_REXMIT_PRUNES | VIFF_POINT_TO_POINT);
-
- /*
- * Disable multicast routing on loopback interfaces and
- * interfaces that do not support multicast. But they are
- * still necessary, since global addresses maybe assigned only
- * on such interfaces.
- */
- if ((flags & IFF_LOOPBACK) != 0 || (flags & IFF_MULTICAST) == 0)
- v->uv_flags |= VIFF_DISABLED;
-
- IF_DEBUG(DEBUG_IF)
- log(LOG_DEBUG,0,
- "Installing %s (%s on subnet %s) ,"
- "as vif #%u - rate = %d",
- v->uv_name,inet6_fmt(&addr.sin6_addr),
- net6name(&v->uv_prefix.sin6_addr,&mask),
- numvifs,v->uv_rate_limit);
-
- ++numvifs;
-
-
- if( !(flags & IFF_UP))
- {
- v->uv_flags |= VIFF_DOWN;
- vifs_down = TRUE;
- }
-
- }
-#endif /* HAVE_GETIFADDRS */
-}
-
-void
-add_phaddr(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;
-
- 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;
- }
-
- pa->pa_next = v->uv_addrs;
- v->uv_addrs = pa;
-}
diff --git a/usr.sbin/pim6sd/config.h b/usr.sbin/pim6sd/config.h
deleted file mode 100644
index 5ce6593..0000000
--- a/usr.sbin/pim6sd/config.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 1999 LSIIT Laboratory.
- * 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.
- */
-/*
- * Questions concerning this software should be directed to
- * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
- *
- */
-/*
- * This program has been derived from pim6dd.
- * The pim6dd program is covered by the license in the accompanying file
- * named "LICENSE.pim6dd".
- */
-/*
- * This program has been derived from pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- * $FreeBSD$
- */
-
-#ifndef CONFIG_H
-#define CONFIG_H
-
-#define UNKNOWN -1
-#define EMPTY 1
-#define PHYINT 2
-#define CANDIDATE_RP 3
-#define GROUP_PREFIX 4
-#define BOOTSTRAP_RP 5
-#define REG_THRESHOLD 6
-#define DATA_THRESHOLD 7
-#define DEFAULT_SOURCE_METRIC 8
-#define DEFAULT_SOURCE_PREFERENCE 9
-#define HELLO_PERIOD 10
-#define GRANULARITY 11
-#define JOIN_PRUNE_PERIOD 12
-#define DATA_TIMEOUT 13
-#define REGISTER_SUPPRESSION_TIMEOUT 14
-#define PROBE_TIME 15
-#define ASSERT_TIMEOUT 16
-
-#define EQUAL(s1, s2) (strcmp((s1), (s2)) == 0)
-
-void config_vifs_from_kernel __P((void));
-void config_vifs_from_file __P((void));
-
-#endif
diff --git a/usr.sbin/pim6sd/crc.c b/usr.sbin/pim6sd/crc.c
deleted file mode 100644
index ca16b63..0000000
--- a/usr.sbin/pim6sd/crc.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 1999 LSIIT Laboratory.
- * 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.
- */
-/*
- * Questions concerning this software should be directed to
- * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
- *
- */
-/*
- * This program has been derived from pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- * $FreeBSD$
- */
-/* CRC implantation : stolen from RFC 2083 section 15.*/
-
-#include <sys/cdefs.h>
-#include "crc.h"
-
-/* Table of CRCs of all 8-bit messages. */
- unsigned long crc_table[256];
-
-/* Flag: has the table been computed? Initially false. */
- int crc_table_computed = 0;
-
-
-/* Make the table for a fast CRC. */
-
-static void make_crc_table __P((void));
-static unsigned long update_crc __P((unsigned long, unsigned char *, int));
-
-static void make_crc_table(void)
-{
- unsigned long c;
- int n, k;
- for (n = 0; n < 256; n++)
- {
- c = (unsigned long) n;
- for (k = 0; k < 8; k++)
- {
- if (c & 1)
- c = 0xedb88320L ^ (c >> 1);
- else
- c = c >> 1;
- }
- crc_table[n] = c;
- }
- crc_table_computed = 1;
-}
-
-/* Update a running CRC with the bytes buf[0..len-1]--the CRC
- should be initialized to all 1's, and the transmitted value
- is the 1's complement of the final running CRC (see the
- crc() routine below)). */
-
-static unsigned long update_crc(unsigned long crc, unsigned char *buf,
- int len)
-{
- unsigned long c = crc;
- int n;
-
- if (!crc_table_computed)
- make_crc_table();
- for (n = 0; n < len; n++)
- {
- c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);
- }
- return c;
-}
-
-
-/* Return the CRC of the bytes buf[0..len-1]. */
-
-unsigned long crc(unsigned char *buf, int len)
-{
- return update_crc(0xffffffffL, buf, len) ^ 0xffffffffL;
-}
diff --git a/usr.sbin/pim6sd/crc.h b/usr.sbin/pim6sd/crc.h
deleted file mode 100644
index d1c49f8..0000000
--- a/usr.sbin/pim6sd/crc.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 1999 LSIIT Laboratory.
- * 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.
- */
-/*
- * Questions concerning this software should be directed to
- * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
- *
- */
-/*
- * This program has been derived from pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- * $FreeBSD$
- */
-
-#ifndef CRC_H
-#define CRC_H
-
-extern unsigned long crc __P((unsigned char *buf, int len));
-
-#endif
diff --git a/usr.sbin/pim6sd/debug.c b/usr.sbin/pim6sd/debug.c
deleted file mode 100644
index 03f9d8a..0000000
--- a/usr.sbin/pim6sd/debug.c
+++ /dev/null
@@ -1,998 +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
- * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
- *
- */
-/*
- * This program has been derived from pim6dd.
- * The pim6dd program is covered by the license in the accompanying file
- * named "LICENSE.pim6dd".
- */
-/*
- * This program has been derived from pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- */
-/*
- * 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 <syslog.h>
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <errno.h>
-#include <net/route.h>
-#include <netinet/in.h>
-#include <netinet/ip_mroute.h>
-#include <netinet/icmp6.h>
-#include <netinet6/pim6.h>
-#include "pathnames.h"
-#include "defs.h"
-#include "pimd.h"
-#include "debug.h"
-#include "mrt.h"
-#include "vif.h"
-#include "rp.h"
-#include "inet6.h"
-
-#ifdef __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-
-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 statfilename[] = _PATH_PIM6D_STAT;
-
-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_nbrs(fp);
- dump_mldqueriers(fp);
- dump_pim_mrt(fp);
- dump_rp_set(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_stat()
-{
- FILE *fp;
- vifi_t vifi;
- register struct uvif *v;
-
- fp = fopen(statfilename, "w");
- if (fp == NULL) {
- log(LOG_WARNING, errno, "dump_stat: can't open file(%s)",
- statfilename);
- return;
- }
-
- fprintf(fp, "pim6sd per-interface statistics\n");
- for (vifi = 0, v = uvifs; vifi < numvifs; vifi++, v++) {
-#if 0 /* is it better to skip them? */
- if ((v->uv_flags & (VIFF_DISABLED|VIFF_DOWN)) != 0)
- continue;
-#endif
- fprintf(fp, " Mif=%d, PhyIF=%s\n", vifi, v->uv_name);
- fprintf(fp, "\t%qu pim6 hello received\n",
- (unsigned long long)v->uv_in_pim6_hello);
- fprintf(fp, "\t%qu pim6 join-prune received\n",
- (unsigned long long)v->uv_in_pim6_join_prune);
- fprintf(fp, "\t%qu pim6 bootstrap received\n",
- (unsigned long long)v->uv_in_pim6_bootsrap);
- fprintf(fp, "\t%qu pim6 assert received\n",
- (unsigned long long)v->uv_in_pim6_assert);
-
- fprintf(fp, "\t%qu pim6 hello sent\n",
- (unsigned long long)v->uv_out_pim6_hello);
- fprintf(fp, "\t%qu pim6 join-prune sent\n",
- (unsigned long long)v->uv_out_pim6_join_prune);
- fprintf(fp, "\t%qu pim6 bootstrap sent\n",
- (unsigned long long)v->uv_out_pim6_bootsrap);
- fprintf(fp, "\t%qu pim6 assert sent\n",
- (unsigned long long)v->uv_out_pim6_assert);
-
- fprintf(fp, "\t%qu MLD query received\n",
- (unsigned long long)v->uv_in_mld_query);
- fprintf(fp, "\t%qu MLD report received\n",
- (unsigned long long)v->uv_in_mld_report);
- fprintf(fp, "\t%qu MLD done received\n",
- (unsigned long long)v->uv_in_mld_done);
-
- fprintf(fp, "\t%qu MLD query sent\n",
- (unsigned long long)v->uv_out_mld_query);
- fprintf(fp, "\t%qu MLD report sent\n",
- (unsigned long long)v->uv_out_mld_report);
- fprintf(fp, "\t%qu MLD done sent\n",
- (unsigned long long)v->uv_out_mld_done);
-
- fprintf(fp, "\t%qu forwarding cache miss\n",
- (unsigned long long)v->uv_cache_miss);
- fprintf(fp, "\t%qu forwarding cache miss and not created\n",
- (unsigned long long)v->uv_cache_notcreated);
-
- fprintf(fp, "\t%qu PIM neighbor timeouts\n",
- (unsigned long long)v->uv_pim6_nbr_timo);
- fprintf(fp, "\t%qu MLD listener timeouts\n",
- (unsigned long long)v->uv_listener_timo);
- fprintf(fp, "\t%qu MLD querier timeouts\n",
- (unsigned long long)v->uv_querier_timo);
- fprintf(fp, "\t%qu out-I/F timeouts\n",
- (unsigned long long)v->uv_outif_timo);
- }
-
- fprintf(fp, "\npim6sd interface independent statistics\n");
-
- fprintf(fp, "\t%qu pim6 register received\n",
- (unsigned long long)pim6dstat.in_pim6_register);
- fprintf(fp, "\t%qu pim6 register-stop received\n",
- (unsigned long long)pim6dstat.in_pim6_register_stop);
- fprintf(fp, "\t%qu pim6 cand-RP received\n",
- (unsigned long long)pim6dstat.in_pim6_cand_rp);
- fprintf(fp, "\t%qu pim6 graft received\n",
- (unsigned long long)pim6dstat.in_pim6_graft);
- fprintf(fp, "\t%qu pim6 graft ack received\n",
- (unsigned long long)pim6dstat.in_pim6_graft_ack);
-
- fprintf(fp, "\t%qu pim6 register sent\n",
- (unsigned long long)pim6dstat.out_pim6_register);
- fprintf(fp, "\t%qu pim6 register-stop sent\n",
- (unsigned long long)pim6dstat.out_pim6_register_stop);
- fprintf(fp, "\t%qu pim6 cand-RP sent\n",
- (unsigned long long)pim6dstat.out_pim6_cand_rp);
-
- fprintf(fp, "\t%qu transitions of forwarder initiated SPT\n",
- (unsigned long long)pim6dstat.pim6_trans_spt_forward);
- fprintf(fp, "\t%qu transitions of RP initiated SPT\n",
- (unsigned long long)pim6dstat.pim6_trans_spt_rp);
-
- fprintf(fp, "\t%qu pim6 bootstrap timeouts\n",
- (unsigned long long)pim6dstat.pim6_bootstrap_timo);
- fprintf(fp, "\t%qu pim6 RP group entry timeouts\n",
- (unsigned long long)pim6dstat.pim6_rpgrp_timo);
- fprintf(fp, "\t%qu pim6 routing entry timeouts\n",
- (unsigned long long)pim6dstat.pim6_rtentry_timo);
-
- fprintf(fp, "\t%qu kernel cache additions\n",
- (unsigned long long)pim6dstat.kern_add_cache);
- fprintf(fp, "\t%qu kernel cache addition failures\n",
- (unsigned long long)pim6dstat.kern_add_cache_fail);
- fprintf(fp, "\t%qu kernel cache deletions\n",
- (unsigned long long)pim6dstat.kern_del_cache);
- fprintf(fp, "\t%qu kernel cache deletion failures\n",
- (unsigned long long)pim6dstat.kern_del_cache_fail);
- fprintf(fp, "\t%qu failures of getting kernel cache\n",
- (unsigned long long)pim6dstat.kern_sgcnt_fail);
-
- fclose(fp);
-}
-
-void
-dump_vifs(fp)
- FILE *fp;
-{
- vifi_t vifi;
- register struct uvif *v;
- struct phaddr *pa;
-
- fprintf(fp, "\nMulticast Interface Table\n %-4s %-6s %-43s %5s %-14s\n",
- "Mif", " PhyIF", "Local-Address/Prefixlen","Scope", "Flags");
-
- 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 %-43s", "", "",
- net6name(&pa->pa_addr.sin6_addr,
- &pa->pa_subnetmask));
- fprintf(fp," %-5d\n", pa->pa_addr.sin6_scope_id);
- continue;
- }
-
- firstaddr = 0;
- fprintf(fp, " %-3u %6s %-43s", vifi,
- (v->uv_flags & MIFF_REGISTER)?"regist":v->uv_name,
- net6name(&pa->pa_addr.sin6_addr,
- &pa->pa_subnetmask));
- fprintf(fp," %-5d", pa->pa_addr.sin6_scope_id);
-
- if (v->uv_flags & MIFF_REGISTER)
- fprintf(fp, " REGISTER");
- 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");
- if (v->uv_flags & VIFF_PIM_NBR)
- fprintf(fp, " PIM");
- if (v->uv_flags & VIFF_QUERIER)
- fprintf(fp, " QRY");
-#if 0 /* impossible */
- if (v->uv_flags & VIFF_DVMRP_NBR)
- {
- fprintf(fp, " DVMRP");
- }
-#endif
- if (v->uv_flags & VIFF_NONBRS)
- fprintf(fp, " NO-NBR");
-
- fprintf(fp, "\n");
- }
-
- fprintf(fp, " %3s %6s ", "", "");
- fprintf(fp, "Timers: PIM hello = %d:%02d, MLD query = %d:%02d\n",
- v->uv_pim_hello_timer / 60, v->uv_pim_hello_timer % 60,
- v->uv_gq_timer / 60, v->uv_gq_timer % 60);
- }
- fprintf(fp, "\n");
-}
-
-void
-dump_nbrs(fp)
- FILE *fp;
-{
- struct uvif *v;
- vifi_t vifi;
- pim_nbr_entry_t *n;
-
- fprintf(fp, "PIM Neighbor List\n");
- fprintf(fp, " %-3s %6s %-40s %-5s\n",
- "Mif", "PhyIF", "Address", "Timer");
-
- for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
- if ((n = v->uv_pim_neighbors) != NULL) {
- int first = 1;
-
- fprintf(fp, " %-3u %6s", vifi,
- (v->uv_flags & MIFF_REGISTER) ? "regist":
- v->uv_name);
- for (; n != NULL; n = n->next) {
- if (first)
- first = 0;
- else
- fprintf(fp, " %3s %6s", "", "");
- fprintf(fp, " %-40s %-5u\n",
- inet6_fmt(&n->address.sin6_addr),
- n->timer);
- }
- }
- }
-
- fprintf(fp, "\n");
-}
-
-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",
- sa6_fmt(&v->uv_querier->al_addr),
- (u_long)v->uv_querier->al_timer,
- sec2str(now - v->uv_querier->al_ctime));
- }
- }
-
- 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 (debug || severity <= LOG_WARNING)
- {
- time_t t;
- FILE *fp = log_fp ? log_fp : stderr;
-
- gettimeofday(&now, NULL);
- t = (time_t)now.tv_sec;
- thyme = localtime(&t);
- if (!debug)
- fprintf(fp, "%s: ", progname);
- fprintf(fp, "%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(fp, "\n");
- else
- if (syserr < sys_nerr)
- fprintf(fp, ": %s\n", sys_errlist[syserr]);
- else
- fprintf(fp, ": 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);
-}
-
-/* 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;
- int i;
- u_int number_of_cache_mirrors = 0;
- u_int number_of_groups = 0;
- char joined_oifs[(sizeof(if_set) << 3) + 1];
- char asserted_oifs[(sizeof(if_set) << 3) + 1];
- cand_rp_t *rp;
- kernel_cache_t *kernel_cache;
- char oifs[(sizeof(if_set) << 3) + 1];
- char pruned_oifs[(sizeof(if_set) << 3) + 1];
- char leaves_oifs[(sizeof(if_set) << 3) + 1];
- char incoming_iif[(sizeof(if_set) << 3) + 1];
-
- fprintf(fp, "Multicast Routing Table\n%s",
- " Source Group RP-addr 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++;
- if ((r = g->grp_route) != (mrtentry_t *) NULL)
- {
- if (r->flags & MRTF_KERNEL_CACHE)
- {
- for (kernel_cache = r->kernel_cache;
- kernel_cache != (kernel_cache_t *) NULL;
- kernel_cache = kernel_cache->next)
- number_of_cache_mirrors++;
- }
-
- /* Print the (*,G) routing info */
- fprintf(fp, "---------------------------(*,G)----------------------------\n");
- fprintf(fp, " %-15s", "IN6ADDR_ANY");
- fprintf(fp, " %-15s", inet6_fmt(&g->group.sin6_addr));
- fprintf(fp, " %-15s",
- g->active_rp_grp ? inet6_fmt(&g->rpaddr.sin6_addr) : "NULL");
-
- for (vifi = 0; vifi < numvifs; vifi++)
- {
- oifs[vifi] =
- IF_ISSET(vifi, &r->oifs) ? 'o' : '.';
- joined_oifs[vifi] =
- IF_ISSET(vifi, &r->joined_oifs) ? 'j' : '.';
- pruned_oifs[vifi] =
- IF_ISSET(vifi, &r->pruned_oifs) ? 'p' : '.';
- leaves_oifs[vifi] =
- IF_ISSET(vifi, &r->leaves) ? 'l' : '.';
- asserted_oifs[vifi] =
- IF_ISSET(vifi, &r->asserted_oifs) ? 'a' : '.';
- incoming_iif[vifi] = '.';
- }
- oifs[vifi] = 0x0; /* End of string */
- joined_oifs[vifi] = 0x0;
- pruned_oifs[vifi] = 0x0;
- leaves_oifs[vifi] = 0x0;
- asserted_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, "Joined oifs: %-20s\n", joined_oifs);
- fprintf(fp, "Pruned oifs: %-20s\n", pruned_oifs);
- fprintf(fp, "Leaves oifs: %-20s\n", leaves_oifs);
- fprintf(fp, "Asserted oifs: %-20s\n", asserted_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=%d JP=%d RS=%d Assert=%d\n",
- r->timer, r->jp_timer, r->rs_timer, r->assert_timer);
-
- fprintf(fp, " MIF 0 1 2 3 4 5 6 7 8 9\n");
- for (vifi = 0, i = 0; vifi < numvifs && i <= numvifs / 10; i++) {
- int j;
-
- fprintf(fp, " %4d", i);
- for (j = 0; j < 10 && vifi < numvifs; j++, vifi++)
- fprintf(fp, " %3d", r->vif_timers[vifi]);
- fprintf(fp, "\n");
- }
- }
-
- /* Print all (S,G) routing info */
-
- for (r = g->mrtlink; r != (mrtentry_t *) NULL; r = r->grpnext)
- {
- fprintf(fp, "---------------------------(S,G)----------------------------\n");
- if (r->flags & MRTF_KERNEL_CACHE)
- number_of_cache_mirrors++;
-
- /* Print the routing info */
- fprintf(fp, " %-15s", inet6_fmt(&r->source->address.sin6_addr));
- fprintf(fp, " %-15s", inet6_fmt(&g->group.sin6_addr));
- fprintf(fp, " %-15s",
- g->active_rp_grp ? inet6_fmt(&g->rpaddr.sin6_addr) : "NULL");
-
- for (vifi = 0; vifi < numvifs; vifi++)
- {
- oifs[vifi] =
- IF_ISSET(vifi, &r->oifs) ? 'o' : '.';
- joined_oifs[vifi] =
- IF_ISSET(vifi, &r->joined_oifs) ? 'j' : '.';
- pruned_oifs[vifi] =
- IF_ISSET(vifi, &r->pruned_oifs) ? 'p' : '.';
- leaves_oifs[vifi] =
- IF_ISSET(vifi, &r->leaves) ? 'l' : '.';
- asserted_oifs[vifi] =
- IF_ISSET(vifi, &r->asserted_oifs) ? 'a' : '.';
- incoming_iif[vifi] = '.';
- }
- oifs[vifi] = 0x0; /* End of string */
- joined_oifs[vifi] = 0x0;
- pruned_oifs[vifi] = 0x0;
- leaves_oifs[vifi] = 0x0;
- asserted_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, "Joined oifs: %-20s\n", joined_oifs);
- fprintf(fp, "Pruned oifs: %-20s\n", pruned_oifs);
- fprintf(fp, "Leaves oifs: %-20s\n", leaves_oifs);
- fprintf(fp, "Asserted oifs: %-20s\n", asserted_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=%d JP=%d RS=%d Assert=%d\n",
- r->timer, r->jp_timer, r->rs_timer, r->assert_timer);
-
- fprintf(fp, " MIF 0 1 2 3 4 5 6 7 8 9\n");
- for (vifi = 0, i = 0; vifi < numvifs && i <= numvifs / 10; i++) {
- int j;
-
- fprintf(fp, " %4d", i);
- for (j = 0; j < 10 && vifi < numvifs; j++, vifi++)
- fprintf(fp, " %3d", r->vif_timers[vifi]);
- fprintf(fp, "\n");
- }
- }
- } /* for all groups */
-
- /* Print the (*,*,R) routing entries */
- fprintf(fp, "--------------------------(*,*,RP)--------------------------\n");
- for (rp = cand_rp_list; rp != (cand_rp_t *) NULL; rp = rp->next)
- {
- if ((r = rp->rpentry->mrtlink) != (mrtentry_t *) NULL)
- {
- if (r->flags & MRTF_KERNEL_CACHE)
- {
- for (kernel_cache = r->kernel_cache;
- kernel_cache != (kernel_cache_t *) NULL;
- kernel_cache = kernel_cache->next)
- number_of_cache_mirrors++;
- }
-
- /* Print the (*,*,RP) routing info */
- fprintf(fp, " RP = %-15s", inet6_fmt(&r->source->address.sin6_addr));
- fprintf(fp, " %-15s", "IN6ADDR_ANY");
-
- for (vifi = 0; vifi < numvifs; vifi++)
- {
- oifs[vifi] =
- IF_ISSET(vifi, &r->oifs) ? 'o' : '.';
- joined_oifs[vifi] =
- IF_ISSET(vifi, &r->joined_oifs) ? 'j' : '.';
- pruned_oifs[vifi] =
- IF_ISSET(vifi, &r->pruned_oifs) ? 'p' : '.';
- leaves_oifs[vifi] =
- IF_ISSET(vifi, &r->leaves) ? 'l' : '.';
- asserted_oifs[vifi] =
- IF_ISSET(vifi, &r->asserted_oifs) ? 'a' : '.';
- incoming_iif[vifi] = '.';
- }
- oifs[vifi] = 0x0; /* End of string */
- joined_oifs[vifi] = 0x0;
- pruned_oifs[vifi] = 0x0;
- leaves_oifs[vifi] = 0x0;
- asserted_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, "Joined oifs: %-20s\n", joined_oifs);
- fprintf(fp, "Pruned oifs: %-20s\n", pruned_oifs);
- fprintf(fp, "Leaves oifs: %-20s\n", leaves_oifs);
- fprintf(fp, "Asserted oifs: %-20s\n", asserted_oifs);
- fprintf(fp, "Outgoing oifs: %-20s\n", oifs);
- fprintf(fp, "Incoming : %-20s\n", incoming_iif);
-
- fprintf(fp, "\nTIMERS: Entry=%d JP=%d RS=%d Assert=%d\n",
- r->timer, r->jp_timer, r->rs_timer, r->assert_timer);
-
- fprintf(fp, " MIF 0 1 2 3 4 5 6 7 8 9\n");
- for (vifi = 0, i = 0; vifi < numvifs && i <= numvifs / 10; i++) {
- int j;
-
- fprintf(fp, " %4d", i);
- for (j = 0; j < 10 && vifi < numvifs; j++, vifi++)
- fprintf(fp, " %3d", r->vif_timers[vifi]);
- fprintf(fp, "\n");
- }
- }
- } /* For all (*,*,RP) */
-
- fprintf(fp, "Number of Groups: %u\n", number_of_groups);
- fprintf(fp, "Number of Cache MIRRORs: %u\n\n", number_of_cache_mirrors);
-}
-
-
-/* TODO: modify the output for better redability */
-/*
- * Dumps the local Cand-RP-set
- */
-int
-dump_rp_set(fp)
- FILE *fp;
-{
- cand_rp_t *rp;
- rp_grp_entry_t *rp_grp_entry;
- grp_mask_t *grp_mask;
-
- fprintf(fp, "---------------------------RP-Set----------------------------\n");
- fprintf(fp, "Current BSR address: %s Prio: %d Timeout: %d\n",
- inet6_fmt(&curr_bsr_address.sin6_addr), curr_bsr_priority,
- pim_bootstrap_timer);
- fprintf(fp, "%-40s %-3s Group prefix Prio Hold Age\n",
- "RP-address", "IN");
-
- for (rp = cand_rp_list; rp != (cand_rp_t *) NULL; rp = rp->next)
- {
-
- fprintf(fp, "%-40s %-3d ",
- inet6_fmt(&rp->rpentry->address.sin6_addr),
- rp->rpentry->incoming);
- if ((rp_grp_entry = rp->rp_grp_next) != (rp_grp_entry_t *) NULL)
- {
- grp_mask = rp_grp_entry->group;
- fprintf(fp, "%-16.16s %-4u %-4u %-3u\n",
- net6name(&grp_mask->group_addr.sin6_addr,
- &grp_mask->group_mask),
- rp_grp_entry->priority, rp_grp_entry->advholdtime,
- rp_grp_entry->holdtime);
-
- for (rp_grp_entry = rp_grp_entry->rp_grp_next;
- rp_grp_entry != (rp_grp_entry_t *) NULL;
- rp_grp_entry = rp_grp_entry->rp_grp_next)
- {
- grp_mask = rp_grp_entry->group;
- fprintf(fp, "%59.16s %-4u %-4u %-3u\n", /* XXX: hardcoding */
- net6name(&grp_mask->group_addr.sin6_addr,
- &grp_mask->group_mask),
- rp_grp_entry->priority,
- rp_grp_entry->advholdtime, rp_grp_entry->holdtime);
- }
- }
- }
- return (TRUE);
-}
diff --git a/usr.sbin/pim6sd/debug.h b/usr.sbin/pim6sd/debug.h
deleted file mode 100644
index 683aada..0000000
--- a/usr.sbin/pim6sd/debug.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 1999 LSIIT Laboratory.
- * 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.
- */
-/*
- * Questions concerning this software should be directed to
- * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
- *
- */
-/*
- * This program has been derived from pim6dd.
- * The pim6dd program is covered by the license in the accompanying file
- * named "LICENSE.pim6dd".
- */
-/*
- * This program has been derived from pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- * $FreeBSD$
- */
-
-
-
-#ifndef DEBUG_H
-#define DEBUG_H
-#include <sys/types.h>
-#include <stdio.h>
-
-extern unsigned long debug;
-extern int log_nmsgs;
-extern FILE *log_fp;
-#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_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 )
-
-#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 )
-
-/* CONFIG related */
-#define DEBUG_CONF 0x01000000
-
-#define DEBUG_ALL 0xffffffff
-#define DEBUG_SWITCH 0x80000000
-
-#define DEBUG_DEFAULT 0xffffffff/* default if "-d" given without value */
-
-#if defined(YIPS_DEBUG)
-#define YIPSDEBUG(lev,arg) if ((debug & (lev)) == (lev)) { arg; }
-#else
-#define YIPSDEBUG(lev,arg)
-#endif /* defined(YIPS_DEBUG) */
-
-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 *, ...));
-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_nbrs __P((FILE *fp));
-extern void dump_mldqueriers __P((FILE *fp));
-extern void dump_pim_mrt __P((FILE *fp));
-extern int dump_rp_set __P((FILE *fp));
-extern void dump_stat __P((void));
-
-#endif
diff --git a/usr.sbin/pim6sd/defs.h b/usr.sbin/pim6sd/defs.h
deleted file mode 100644
index 58ffe6b..0000000
--- a/usr.sbin/pim6sd/defs.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 1999 LSIIT Laboratory.
- * 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.
- */
-/*
- * Questions concerning this software should be directed to
- * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
- *
- */
-/*
- * This program has been derived from pim6dd.
- * The pim6dd program is covered by the license in the accompanying file
- * named "LICENSE.pim6dd".
- */
-/*
- * This program has been derived from pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- * $FreeBSD$
- */
-
-
-#ifndef DEFS_H
-#define DEFS_H
-
-#include <sys/types.h>
-
-#define TRUE 1
-#define FALSE 0
-#define ELSE else /* To make emacs cc-mode happy */
-
-#define max( a , b ) ( ( a )<( b )?( b ):( a ) )
-
-typedef void ( *ihfunc_t ) __P( ( int , fd_set * ) );
-typedef void ( *cfunc_t ) __P( ( void * ) );
-
-int register_input_handler __P((int fd,ihfunc_t func));
-
-/* CONFIGCONFIGCONFIGCONFIG */
-
-#define HAVE_ROUTING_SOCKETS
-#define HAVE_SA_LEN
-#define RANDOM() random()
-
-#define PRINTF printf
-#define ALL_MCAST_GROUPS_LENGTH 8
-
-
-typedef u_int u_int32;
-typedef u_short u_int16;
-typedef u_char u_int8;
-
-
-extern char configfilename[];
-
-#endif
diff --git a/usr.sbin/pim6sd/inet6.c b/usr.sbin/pim6sd/inet6.c
deleted file mode 100644
index 220a443..0000000
--- a/usr.sbin/pim6sd/inet6.c
+++ /dev/null
@@ -1,292 +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.
- */
-/*
- * Questions concerning this software should be directed to
- * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
- *
- */
-/*
- * This program has been derived from pim6dd.
- * The pim6dd program is covered by the license in the accompanying file
- * named "LICENSE.pim6dd".
- */
-/*
- * This program has been derived from pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- * $FreeBSD$
- */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <stdio.h>
-#include <netdb.h>
-#include <string.h>
-#include "defs.h"
-#include "vif.h"
-#include "inet6.h"
-#include <arpa/inet.h>
-
-/* flag if address to hostname resolution should be perfomed */
-int numerichost = TRUE;
-
-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_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_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 *
-sa6_fmt(struct sockaddr_in6 *sa6)
-{
- static char ip6buf[8][MAXHOSTNAMELEN];
- static int ip6round = 0;
- int flags = NI_WITHSCOPEID;
- char *cp;
-
- ip6round = (ip6round + 1) & 7;
- cp = ip6buf[ip6round];
-
- if (numerichost)
- flags |= NI_NUMERICHOST;
- getnameinfo((struct sockaddr *)sa6, sa6->sin6_len, cp, MAXHOSTNAMELEN,
- NULL, 0, flags);
-
- return(cp);
-}
-
-char *
-inet6_fmt(struct in6_addr * addr)
-{
- struct sockaddr_in6 sa6;
-
-
- memset(&sa6, 0, sizeof(sa6));
- sa6.sin6_len = sizeof(sa6);
- sa6.sin6_family = AF_INET6;
- sa6.sin6_addr = *addr;
- sa6.sin6_scope_id = 0; /* XXX */
-
- return(sa6_fmt(&sa6));
-}
-
-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/pim6sd/inet6.h b/usr.sbin/pim6sd/inet6.h
deleted file mode 100644
index c7225f6..0000000
--- a/usr.sbin/pim6sd/inet6.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 1999 LSIIT Laboratory.
- * 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.
- */
-/*
- * Questions concerning this software should be directed to
- * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
- *
- */
-/*
- * This program has been derived from pim6dd.
- * The pim6dd program is covered by the license in the accompanying file
- * named "LICENSE.pim6dd".
- */
-/*
- * This program has been derived from pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- * $FreeBSD$
- */
-
-
-#ifndef INET6_H
-#define INET6_H
-#include "vif.h"
-
-extern int numerichost;
-
-extern int inet6_equal __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_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 *sa6_fmt __P((struct sockaddr_in6 *sa6));
-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));
-
-
-
-#endif
diff --git a/usr.sbin/pim6sd/kern.c b/usr.sbin/pim6sd/kern.c
deleted file mode 100644
index 44c415a..0000000
--- a/usr.sbin/pim6sd/kern.c
+++ /dev/null
@@ -1,413 +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
- * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
- *
- */
-/*
- * This program has been derived from pim6dd.
- * The pim6dd program is covered by the license in the accompanying file
- * named "LICENSE.pim6dd".
- */
-/*
- * This program has been derived from pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- * $FreeBSD$
- */
-
-#include <sys/time.h>
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <errno.h>
-#include <net/if.h>
-#include <net/route.h>
-#include <netinet/in.h>
-#include <netinet6/ip6_mroute.h>
-#if defined(__FreeBSD__) && __FreeBSD__ >= 3
-#include <net/if_var.h>
-#endif
-#include <netinet6/in6_var.h>
-#include <syslog.h>
-#include "pimd.h"
-#include "inet6.h"
-#include "vif.h"
-#include "mrt.h"
-#include "debug.h"
-#include "kern.h"
-
-
-/*
- * Open/init the multicast routing in the kernel and sets the MRT_ASSERT
- * flag in the kernel.
- *
- */
-
-
-void
-k_init_pim(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, "Pim kernel initialization");
-}
-
-/*
- * 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 PIM 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(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,"Buffer reception size for socket %d : %d in %d iterations",socket, bufsize, iter);
-}
-
-/*
- * Set the default Hop Limit for the multicast packets outgoing from this
- * socket.
- */
-
-void
-k_set_hlim(int socket, int h)
-{
- int hlim = h;
-
- if (setsockopt(socket, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *) &hlim, sizeof(hlim)) < 0)
- log(LOG_ERR,errno,"k_set_hlim");
-
-}
-
-/*
- * Set/reset the IPV6_MULTICAST_LOOP. Set/reset is specified by "flag".
- */
-
-
-void
-k_set_loop(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,"k_set_loop");
-}
-
-/*
- * Set the IPV6_MULTICAST_IF option on local interface which has the
- * specified index.
- */
-
-
-void
-k_set_if(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(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)
- syslog(LOG_WARNING, "Cannot join group %s on interface %s",
- inet6_fmt(grp), ifindex2str(ifindex));
-}
-
-/*
- * Leave a multicats grp group on local interface ifa.
- */
-
-void
-k_leave(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)
- syslog(LOG_WARNING, "Cannot leave group %s on interface %s",
- inet6_fmt(grp), ifindex2str(ifindex));
-}
-
-/*
- * Add a virtual interface in the kernel.
- */
-
-void
-k_add_vif(int socket, vifi_t vifi, struct uvif * v)
-{
- struct mif6ctl mc;
-
- mc.mif6c_mifi = vifi;
- mc.mif6c_flags = v->uv_flags;
-
- mc.mif6c_pifi = v->uv_ifindex;
-
- if ((v->uv_flags & MIFF_REGISTER))
- IF_DEBUG(DEBUG_PIM_REGISTER)
- log(LOG_DEBUG,0,"register vifi : %d , register pifi : %d ", vifi, 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(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(int socket, struct sockaddr_in6 * source, struct sockaddr_in6 * group)
-{
- struct mf6cctl mc;
-
- mc.mf6cc_origin = *source;
- mc.mf6cc_mcastgrp = *group;
-
- pim6dstat.kern_del_cache++;
- if (setsockopt(socket, IPPROTO_IPV6, MRT6_DEL_MFC, (char *) &mc, sizeof(mc)) < 0)
- {
- pim6dstat.kern_del_cache_fail++;
- log(LOG_WARNING, errno, "setsockopt MRT6_DEL_MFC");
- return FALSE;
- }
-
- syslog(LOG_DEBUG, "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, rp_addr)
- int socket;
- struct sockaddr_in6 *source;
- struct sockaddr_in6 *group;
- vifi_t iif;
- if_set *oifs;
- struct sockaddr_in6 *rp_addr;
-{
- struct mf6cctl mc;
- vifi_t vifi;
- struct uvif *v;
-
- mc.mf6cc_origin = *source;
- mc.mf6cc_mcastgrp = *group;
- mc.mf6cc_parent = iif;
-
-
- IF_ZERO(&mc.mf6cc_ifset);
-
- for (vifi = 0, v = uvifs; vifi < numvifs; vifi++, v++)
- {
- if (IF_ISSET(vifi, oifs))
- IF_SET(vifi, &mc.mf6cc_ifset);
- else
- IF_CLR(vifi, &mc.mf6cc_ifset);
- }
-
-#ifdef PIM_REG_KERNEL_ENCAP
- mc.mf6cc_rp_addr.s_addr = rp_addr;
-#endif
-
- pim6dstat.kern_add_cache++;
- if (setsockopt(socket, IPPROTO_IPV6, MRT6_ADD_MFC, (char *) &mc,
- sizeof(mc)) < 0)
- {
- pim6dstat.kern_add_cache_fail++;
- log(LOG_WARNING, errno,
- "setsockopt MRT_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)
- {
- pim6dstat.kern_sgcnt_fail++;
- 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/pim6sd/kern.h b/usr.sbin/pim6sd/kern.h
deleted file mode 100644
index 13ba8e8..0000000
--- a/usr.sbin/pim6sd/kern.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 1999 LSIIT Laboratory.
- * 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.
- */
-/*
- * Questions concerning this software should be directed to
- * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
- *
- */
-/*
- * This program has been derived from pim6dd.
- * The pim6dd program is covered by the license in the accompanying file
- * named "LICENSE.pim6dd".
- */
-/*
- * This program has been derived from pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- * $FreeBSD$
- */
-
-
-#ifndef KERN_H
-#define KERN_H
-#include "vif.h"
-#include "mrt.h"
-
-extern void k_set_rcvbuf __P((int socket, int bufsize, int minsize));
-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, struct sockaddr_in6 *rp_addr));
-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));
-
-
-
-#endif
diff --git a/usr.sbin/pim6sd/main.c b/usr.sbin/pim6sd/main.c
deleted file mode 100644
index 67dda40..0000000
--- a/usr.sbin/pim6sd/main.c
+++ /dev/null
@@ -1,767 +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
- * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
- *
- */
-/*
- * This program has been derived from pim6dd.
- * The pim6dd program is covered by the license in the accompanying file
- * named "LICENSE.pim6dd".
- */
-/*
- * This program has been derived from pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- */
-/*
- * 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/time.h>
-#include <errno.h>
-#include <paths.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <signal.h>
-#include <string.h>
-#include <syslog.h>
-#include <fcntl.h>
-#include "pathnames.h"
-#include "defs.h"
-#include "debug.h"
-#include "mld6.h"
-#include "pim6.h"
-#include "vif.h"
-#include "routesock.h"
-#include "callout.h"
-#include "mrt.h"
-#include "timer.h"
-#include "rp.h"
-#include "kern.h"
-#include "cfparse.h"
-
-char configfilename[256] = _PATH_PIM6D_CONF;
-char versionstring[100];
-char logfilename[256] = _PATH_PIM6D_LOGFILE;
-
-/* TODO: not used
-static char genidfilename[] = _PATH_PIM6D_GENID;
-*/
-static char pidfilename[] = _PATH_PIM6D_PID;
-
-FILE *log_fp = stderr;
-char *progname;
-
-static int foreground = 0;
-static int sighandled = 0;
-
-#define GOT_SIGINT 0x01
-#define GOT_SIGHUP 0x02
-#define GOT_SIGUSR1 0x04
-#define GOT_SIGUSR2 0x08
-#define GOT_SIGALRM 0x10
-#define GOT_SIGINFO 0x20
-
-
-#define NHANDLERS 3
-
-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[] = {
- { "mld_proto", DEBUG_MLD_PROTO, 5 },
- { "mld_timer", DEBUG_MLD_TIMER, 5 },
- { "mld_member", DEBUG_MLD_MEMBER, 5 },
- { "mld", DEBUG_MLD, 3 },
- { "switch", DEBUG_SWITCH, 2 },
- { "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_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));
-
-
-/* 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=0,
- n,
- i,
- secs;
- extern char todaysversion[];
- struct sigaction sa;
- struct debugname *d;
- char c;
- int tmpd;
-
- setlinebuf(stderr);
-
- if (geteuid() != 0)
- {
- fprintf(stderr, "pim6sd: 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;
- int no=0;
-
- argv++;
- argc--;
- debug = 0;
- p = *argv;
- q = NULL;
- while (p)
- {
- q = strchr(p, ',');
- if (q)
- *q++ = '\0';
- if(p[0]=='-')
- {
- no=1;
- p++;
- }
- 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;
- }
- if(no)
- {
- debug &=~d->level;
- no=0;
- }
- else
- 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;
- }
- else if (strcmp(*argv, "-f") == 0)
- foreground = 1;
- else
- goto usage;
-
- argv++;
- argc--;
- }
-
- if (argc > 0)
- {
-usage:
- tmpd = 0xffffffff;
- fprintf(stderr, "usage: pim6sd [-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("pim6sd", LOG_PID, LOG_DAEMON);
-// (void) setlogmask(LOG_UPTO(LOG_NOTICE));
-#else
- (void) openlog("pim6sd", LOG_PID);
-#endif /* LOG_DAEMON */
- /* open a log file */
- if ((log_fp = fopen(logfilename, "w")) == NULL)
- log(LOG_ERR, errno, "fopen(%s)", logfilename);
- setlinebuf(log_fp);
-
- sprintf(versionstring, "pim6sd version %s", todaysversion);
-
- log(LOG_INFO, 0, "%s starting", versionstring);
-
- /*
- * TODO: XXX: use a combination of time and hostid to initialize the
- * random generator.
- */
-
-#ifdef SYSV
- srand48(time(NULL));
-#else
- srandom(time(NULL));
-#endif
-
- callout_init();
- init_mld6();
- init_pim6();
-
-#ifdef HAVE_ROUTING_SOCKETS
- init_routesock();
-#endif /* HAVE_ROUTING_SOCKETS */
-
- init_pim6_mrt();
- init_timers();
-
- /* TODO: check the kernel DVMRP/MROUTED/PIM support version */
-
- init_vifs();
- init_rp6_and_bsr6(); /* Must be after init_vifs() */
-
- 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);
- sigaction(SIGINFO, &sa, NULL);
-
- FD_ZERO(&readers);
- FD_SET(mld6_socket, &readers);
- 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(log_fp);
- IF_DEBUG(DEBUG_PIM_MRT)
- dump_pim_mrt(log_fp);
-
- /* schedule first timer interrupt */
- timer_setTimer(timer_interval, timer, NULL);
-
- if (foreground == 0)
- {
- /* Detach from the terminal */
-#ifdef TIOCNOTTY
- int t;
-#endif /* TIOCNOTTY */
-
- if (fork())
- exit(0);
-
-#ifdef HAVE_ROUTING_SOCKETS
- pid = getpid();
-#endif
- (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 */
-
- 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_SIGINFO)
- {
- sighandled &= ~GOT_SIGINFO;
- dump_stat();
- }
- if (sighandled & GOT_SIGUSR1)
- {
- sighandled &= ~GOT_SIGUSR1;
- fdump(SIGUSR1);
- }
- if (sighandled & GOT_SIGUSR2)
- {
- sighandled &= ~GOT_SIGUSR2;
-#ifdef notyet
- cdump(SIGUSR2);
-#else
- cfparse(0, 1); /* reset debug level */
-#endif
- }
- if (sighandled & GOT_SIGALRM)
- {
- sighandled &= ~GOT_SIGALRM;
- timer(&dummysigalrm);
- }
- }
- if ((n = select(nfds, &rfds, NULL, NULL, timeout)) < 0)
- {
- if (errno != EINTR)
- 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)
- 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)
- {
- 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.
- * this granularity is configurable ( see file pim6sd.conf.sample)
- */
-
-static void
-timer(i)
- void *i;
-{
- age_vifs(); /* Timeout neighbors and groups */
- age_routes(); /* Timeout routing entries */
- age_misc(); /* Timeout the rest (Cand-RP list, etc) */
-
- 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()
-{
-
- /*
- * TODO: XXX (not in the spec): if I am the BSR, somehow inform the other
- * routers I am going down and need to elect another BSR? (probably by
- * sending a the Cand-RP-set with my_priority=LOWEST?)
- *
- */
-
- k_stop_pim(mld6_socket);
-}
-
-
-/*
- * 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;
-
- case SIGINFO:
- sighandled |= GOT_SIGINFO;
- break;
- }
-}
-
-
-/* TODO: not verified */
-/*
- * Restart the daemon
- */
-
-static void
-restart(i)
- int i;
-{
-
- 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();
- init_vifs();
-
- /* schedule timer interrupts */
- timer_setTimer(timer_interval, timer, NULL);
-}
diff --git a/usr.sbin/pim6sd/mld6.c b/usr.sbin/pim6sd/mld6.c
deleted file mode 100644
index 55ae6e2..0000000
--- a/usr.sbin/pim6sd/mld6.c
+++ /dev/null
@@ -1,564 +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
- * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
- *
- */
-/*
- * This program has been derived from pim6dd.
- * The pim6dd program is covered by the license in the accompanying file
- * named "LICENSE.pim6dd".
- */
-/*
- * This program has been derived from pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- * $FreeBSD$
- */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-#include <errno.h>
-#include <netinet/in.h>
-#include <netinet/icmp6.h>
-#include <netinet/ip6.h>
-#include <arpa/inet.h>
-#include <stdlib.h>
-#include <syslog.h>
-#include <string.h>
-#include "mld6.h"
-#include "kern.h"
-#include "defs.h"
-#include "inet6.h"
-#include "debug.h"
-#include "mld6_proto.h"
-#include "route.h"
-#include "trace.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",
- 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/pim6sd/mld6.h b/usr.sbin/pim6sd/mld6.h
deleted file mode 100644
index 0f97061..0000000
--- a/usr.sbin/pim6sd/mld6.h
+++ /dev/null
@@ -1,92 +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.
- */
-/*
- * Questions concerning this software should be directed to
- * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
- *
- */
-/*
- * This program has been derived from pim6dd.
- * The pim6dd program is covered by the license in the accompanying file
- * named "LICENSE.pim6dd".
- */
-/*
- * This program has been derived from pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- * $FreeBSD$
- */
-
-
-#ifndef MLD6_H
-#define MLD6_H
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <unistd.h>
-
-#define RECV_BUF_SIZE 64*1024
-#define SO_RECV_BUF_SIZE_MAX 256*1024
-#define SO_RECV_BUF_SIZE_MIN 48*1024
-#define MINHLIM 1
-
-
-/*
- * 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))
-
-extern int mld6_socket;
-extern char *mld6_recv_buf;
-extern struct sockaddr_in6 allrouters_group;
-extern struct sockaddr_in6 allnodes_group;
-extern char *mld6_send_buf;
-
-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));
-
-#endif
diff --git a/usr.sbin/pim6sd/mld6_proto.c b/usr.sbin/pim6sd/mld6_proto.c
deleted file mode 100644
index b76f0b1..0000000
--- a/usr.sbin/pim6sd/mld6_proto.c
+++ /dev/null
@@ -1,619 +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
- * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
- *
- */
-/*
- * This program has been derived from pim6dd.
- * The pim6dd program is covered by the license in the accompanying file
- * named "LICENSE.pim6dd".
- */
-/*
- * This program has been derived from pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- */
-/*
- * 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.
- *
- */
-/*
- * 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/types.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <net/route.h>
-#include <netinet/in.h>
-#include <netinet6/ip6_mroute.h>
-#include <netinet/icmp6.h>
-#include <syslog.h>
-#include <stdlib.h>
-#include "mld6.h"
-#include "vif.h"
-#include "debug.h"
-#include "inet6.h"
-#include "route.h"
-#include "callout.h"
-#include "timer.h"
-
-#include "mld6_proto.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);
- v->uv_out_mld_query++;
- }
-
- /*
- * 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 listener 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];
- v->uv_in_mld_query++;
- IF_DEBUG(DEBUG_MLD)
- log(LOG_DEBUG, 0,
- "accepting multicast listener query on %s: "
- "src %s, dst %s, grp %s",
- v->uv_name,
- inet6_fmt(&src->sin6_addr), inet6_fmt(dst),
- inet6_fmt(group));
-
- 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.
- */
- 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) { /* this should be impossible... */
- 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 %d",
- 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_DEBUG, 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];
- v->uv_in_mld_report++;
-
- /*
- * 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))
- {
- IF_DEBUG(DEBUG_MLD)
- log(LOG_DEBUG,0,
- "The group already exist");
-
- 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)
- {
- IF_DEBUG(DEBUG_MLD)
- log(LOG_DEBUG,0,
- "The group don't exist , trying to add it");
-
- 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};
-
- /* Don't create routing entries for the LAN scoped addresses */
-
- if (IN6_IS_ADDR_MC_NODELOCAL(group)) /* sanity? */
- {
- IF_DEBUG(DEBUG_MLD)
- log(LOG_DEBUG, 0,
- "accept_listener_done: address multicast node local(%s),"
- " ignore it...", inet6_fmt(group));
- return;
- }
-
- if (IN6_IS_ADDR_MC_LINKLOCAL(group))
- {
- IF_DEBUG(DEBUG_MLD)
- log(LOG_DEBUG, 0,
- "accept_listener_done: address multicast link local(%s), "
- "ignore it ...", inet6_fmt(group));
- return;
- }
-
- 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];
- v->uv_in_mld_done++;
-
- 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 %d \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);
- v->uv_out_mld_query++;
- }
- 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);
-
- /* increment statistics */
- v->uv_listener_timo++;
-
- 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);
- v->uv_out_mld_query++;
- }
- 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/pim6sd/mld6_proto.h b/usr.sbin/pim6sd/mld6_proto.h
deleted file mode 100644
index e9cb7eb..0000000
--- a/usr.sbin/pim6sd/mld6_proto.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 1999 LSIIT Laboratory.
- * 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.
- */
-/*
- * Questions concerning this software should be directed to
- * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
- *
- */
-/*
- * This program has been derived from pim6dd.
- * The pim6dd program is covered by the license in the accompanying file
- * named "LICENSE.pim6dd".
- */
-/*
- * This program has been derived from pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- * $FreeBSD$
- */
-
-
-#ifndef MLD6_PROTO_H
-#define MLD6_PROTO_H
-
-#include "vif.h"
-
-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));
-
-
-
-#endif
diff --git a/usr.sbin/pim6sd/mrt.c b/usr.sbin/pim6sd/mrt.c
deleted file mode 100644
index 02f15dc..0000000
--- a/usr.sbin/pim6sd/mrt.c
+++ /dev/null
@@ -1,1500 +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
- * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
- *
- */
-/*
- * This program has been derived from pim6dd.
- * The pim6dd program is covered by the license in the accompanying file
- * named "LICENSE.pim6dd".
- */
-/*
- * This program has been derived from pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- * $FreeBSD$
- */
-
-#include <syslog.h>
-#include <stdlib.h>
-#include <string.h>
-#include "mrt.h"
-#include "vif.h"
-#include "rp.h"
-#include "pimd.h"
-#include "debug.h"
-#include "mld6.h"
-#include "inet6.h"
-#include "timer.h"
-#include "route.h"
-#include "kern.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));
-
-static void move_kernel_cache __P((mrtentry_t * mrtentry_ptr,
- u_int16 flags));
-
-void
-init_pim6_mrt()
-{
-
- /* TODO: delete any existing routing table */
-
- /* Initialize the source list */
- /* The first entry has address 'IN6ADDR_ANY' 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;
- RESET_TIMER(srclist->timer);
- srclist->cand_rp = (cand_rp_t *) NULL;
-
- /* Initialize the group list */
- /* The first entry has address 'IN6ADDR_ANY' 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;
- grplist->rpnext = (grpentry_t *) NULL;
- grplist->rpprev = (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;
- memset(&grplist->rpaddr, 0, sizeof(struct sockaddr_in6));
- grplist->rpaddr.sin6_len = sizeof(struct sockaddr_in6);
- grplist->rpaddr.sin6_family = AF_INET6;
- grplist->mrtlink = (mrtentry_t *) NULL;
- grplist->active_rp_grp = (rp_grp_entry_t *) NULL;
- grplist->grp_route = (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;
- mrtentry_t *mrtentry_ptr_wc;
- mrtentry_t *mrtentry_ptr_pmbr;
- mrtentry_t *mrtentry_ptr_2;
- rpentry_t *rpentry_ptr=NULL;
- rp_grp_entry_t *rp_grp_entry_ptr;
-
- if (flags & (MRTF_SG | MRTF_WC))
- {
- if (!IN6_IS_ADDR_MULTICAST(&group->sin6_addr))
- return (mrtentry_t *) NULL;
- }
-
- if (flags & MRTF_SG)
- if (!inet6_valid_host(source))
- return (mrtentry_t *) NULL;
-
- if (create == DONT_CREATE)
- {
- if (flags & (MRTF_SG | MRTF_WC))
- {
- if (search_grplist(group, &grpentry_ptr) == FALSE)
- {
- /* Group not found. Return the (*,*,RP) entry */
- if (flags & MRTF_PMBR)
- {
- rpentry_ptr = rp_match(group);
- if (rpentry_ptr != (rpentry_t *) NULL)
- return (rpentry_ptr->mrtlink);
- }
- return (mrtentry_t *) NULL;
- }
- /* Search for the source */
- if (flags & MRTF_SG)
- {
- if (search_grpmrtlink(grpentry_ptr, source,
- &mrtentry_ptr) == TRUE)
- {
- /* Exact (S,G) entry found */
- return (mrtentry_ptr);
- }
- }
- /* No (S,G) entry. Return the (*,G) entry (if exist) */
- if ((flags & MRTF_WC) &&
- (grpentry_ptr->grp_route != (mrtentry_t *) NULL))
- return (grpentry_ptr->grp_route);
- }
-
- /* Return the (*,*,RP) entry */
-
- if (flags & MRTF_PMBR)
- {
- rpentry_ptr = (rpentry_t *) NULL;
- if (group != NULL)
- rpentry_ptr = rp_match(group);
- else
- if (source != NULL)
- rpentry_ptr = rp_find(source);
- if (rpentry_ptr != (rpentry_t *) NULL)
- return (rpentry_ptr->mrtlink);
- }
- return (mrtentry_t *) NULL;
- }
-
-
- /* Creation allowed */
-
- if (flags & (MRTF_SG | MRTF_WC))
- {
-
- grpentry_ptr = create_grpentry(group);
- if (grpentry_ptr == (grpentry_t *) NULL)
- {
- return (mrtentry_t *) NULL;
- }
-
- if (grpentry_ptr->active_rp_grp == (rp_grp_entry_t *) NULL)
- {
- rp_grp_entry_ptr = rp_grp_match(group);
-
- if (rp_grp_entry_ptr == (rp_grp_entry_t *) NULL)
- {
- if ((grpentry_ptr->mrtlink == (mrtentry_t *) NULL)
- && (grpentry_ptr->grp_route == (mrtentry_t *) NULL))
- {
- /* New created grpentry. Delete it. */
-
- delete_grpentry(grpentry_ptr);
- }
-
- return (mrtentry_t *) NULL;
- }
-
- rpentry_ptr = rp_grp_entry_ptr->rp->rpentry;
- grpentry_ptr->active_rp_grp = rp_grp_entry_ptr;
- grpentry_ptr->rpaddr = rpentry_ptr->address;
-
- /* Link to the top of the rp_grp_chain */
-
- grpentry_ptr->rpnext = rp_grp_entry_ptr->grplink;
- rp_grp_entry_ptr->grplink = grpentry_ptr;
- if (grpentry_ptr->rpnext != (grpentry_t *) NULL)
- grpentry_ptr->rpnext->rpprev = grpentry_ptr;
- }
- else
- rpentry_ptr = grpentry_ptr->active_rp_grp->rp->rpentry;
- }
-
- mrtentry_ptr_wc = mrtentry_ptr_pmbr = (mrtentry_t *) NULL;
-
- if (flags & MRTF_WC)
- {
- /* Setup the (*,G) routing entry */
-
- mrtentry_ptr_wc = create_mrtentry((srcentry_t *) NULL, grpentry_ptr,
- MRTF_WC);
-
- if (mrtentry_ptr_wc == (mrtentry_t *) NULL)
- {
- if (grpentry_ptr->mrtlink == (mrtentry_t *) NULL)
- {
- /* New created grpentry. Delete it. */
-
- delete_grpentry(grpentry_ptr);
- }
- return (mrtentry_t *) NULL;
- }
-
- if (mrtentry_ptr_wc->flags & MRTF_NEW)
- {
- mrtentry_ptr_pmbr = rpentry_ptr->mrtlink;
-
- /* Copy the oif list from the (*,*,RP) entry */
-
- if (mrtentry_ptr_pmbr != (mrtentry_t *) NULL)
- {
- VOIF_COPY(mrtentry_ptr_pmbr, mrtentry_ptr_wc);
- }
-
- mrtentry_ptr_wc->incoming = rpentry_ptr->incoming;
- mrtentry_ptr_wc->upstream = rpentry_ptr->upstream;
- mrtentry_ptr_wc->metric = rpentry_ptr->metric;
- mrtentry_ptr_wc->preference = rpentry_ptr->preference;
- move_kernel_cache(mrtentry_ptr_wc, 0);
-
-#ifdef RSRR
- rsrr_cache_bring_up(mrtentry_ptr_wc);
-#endif /* RSRR */
-
- }
-
- if (!(flags & MRTF_SG))
- {
- return (mrtentry_ptr_wc);
- }
- }
-
- if (flags & MRTF_SG)
- {
- /* Setup the (S,G) routing entry */
- srcentry_ptr = create_srcentry(source);
- if (srcentry_ptr == (srcentry_t *) NULL)
- {
- /* TODO: XXX: The MRTF_NEW flag check may be misleading?? check */
-
- if (((grpentry_ptr->grp_route == (mrtentry_t *) NULL)
- || ((grpentry_ptr->grp_route != (mrtentry_t *) NULL)
- && (grpentry_ptr->grp_route->flags & MRTF_NEW)))
- && (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->grp_route == (mrtentry_t *) NULL)
- || ((grpentry_ptr->grp_route != (mrtentry_t *) NULL)
- && (grpentry_ptr->grp_route->flags & MRTF_NEW)))
- && (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)
- {
- if ((mrtentry_ptr_2 = grpentry_ptr->grp_route)
- == (mrtentry_t *) NULL)
- {
- mrtentry_ptr_2 = rpentry_ptr->mrtlink;
- }
- /* Copy the oif list from the existing (*,G) or (*,*,RP) entry */
- if (mrtentry_ptr_2 != (mrtentry_t *) NULL)
- {
- VOIF_COPY(mrtentry_ptr_2, mrtentry_ptr);
- if (flags & MRTF_RP)
- {
- /* ~(S,G) prune entry */
- mrtentry_ptr->incoming = mrtentry_ptr_2->incoming;
- mrtentry_ptr->upstream = mrtentry_ptr_2->upstream;
- mrtentry_ptr->metric = mrtentry_ptr_2->metric;
- mrtentry_ptr->preference = mrtentry_ptr_2->preference;
- mrtentry_ptr->flags |= MRTF_RP;
- }
- }
- if (!(mrtentry_ptr->flags & MRTF_RP))
- {
- mrtentry_ptr->incoming = srcentry_ptr->incoming;
- mrtentry_ptr->upstream = srcentry_ptr->upstream;
- mrtentry_ptr->metric = srcentry_ptr->metric;
- mrtentry_ptr->preference = srcentry_ptr->preference;
- }
- move_kernel_cache(mrtentry_ptr, 0);
-#ifdef RSRR
- rsrr_cache_bring_up(mrtentry_ptr);
-#endif /* RSRR */
- }
- return (mrtentry_ptr);
- }
-
- if (flags & MRTF_PMBR)
- {
- /* Get/return the (*,*,RP) routing entry */
-
- if (group != NULL)
- rpentry_ptr = rp_match(group);
- else
- if (source != NULL)
- {
- rpentry_ptr = rp_find(source);
- if (rpentry_ptr == (rpentry_t *) NULL)
- {
- return (mrtentry_t *) NULL;
- }
- }
- else
- return (mrtentry_t *) NULL; /* source == group ==
- * IN6ADDR_ANY */
-
- if (rpentry_ptr->mrtlink != (mrtentry_t *) NULL)
- return (rpentry_ptr->mrtlink);
- mrtentry_ptr = create_mrtentry(rpentry_ptr, (grpentry_t *) NULL,
- MRTF_PMBR);
- if (mrtentry_ptr == (mrtentry_t *) NULL)
- return (mrtentry_t *) NULL;
- mrtentry_ptr->incoming = rpentry_ptr->incoming;
- mrtentry_ptr->upstream = rpentry_ptr->upstream;
- mrtentry_ptr->metric = rpentry_ptr->metric;
- mrtentry_ptr->preference = rpentry_ptr->preference;
- return (mrtentry_ptr);
- }
-
- return (mrtentry_t *) NULL;
-}
-
-
-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->flags & MRTF_KERNEL_CACHE)
- /* Delete the kernel cache first */
- delete_mrtentry_all_kernel_cache(mrtentry_ptr);
- 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)
- && (mrtentry_ptr->group->grp_route == (mrtentry_t *) NULL))
- {
- /* Delete the group entry if it has no (*,G) routing 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;
-
- if (grpentry_ptr->grp_route != (mrtentry_t *) NULL)
- {
- if (grpentry_ptr->grp_route->flags & MRTF_KERNEL_CACHE)
- delete_mrtentry_all_kernel_cache(grpentry_ptr->grp_route);
- FREE_MRTENTRY(grpentry_ptr->grp_route);
- }
-
- /* Delete from the rp_grp_entry chain */
- if (grpentry_ptr->active_rp_grp != (rp_grp_entry_t *) NULL)
- {
- if (grpentry_ptr->rpnext != (grpentry_t *) NULL)
- grpentry_ptr->rpnext->rpprev = grpentry_ptr->rpprev;
- if (grpentry_ptr->rpprev != (grpentry_t *) NULL)
- grpentry_ptr->rpprev->rpnext = grpentry_ptr->rpnext;
- else
- grpentry_ptr->active_rp_grp->grplink = grpentry_ptr->rpnext;
- }
-
- for (mrtentry_ptr = grpentry_ptr->mrtlink;
- mrtentry_ptr != (mrtentry_t *) NULL;
- mrtentry_ptr = mrtentry_next)
- {
- mrtentry_next = mrtentry_ptr->grpnext;
- if (mrtentry_ptr->flags & MRTF_KERNEL_CACHE)
- /* Delete the kernel cache first */
- delete_mrtentry_all_kernel_cache(mrtentry_ptr);
- 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;
-{
- grpentry_t *grpentry_ptr;
- mrtentry_t *mrtentry_wc;
- mrtentry_t *mrtentry_rp;
-
- if (mrtentry_ptr == (mrtentry_t *) NULL)
- return;
-
- /* Delete the kernel cache first */
- if (mrtentry_ptr->flags & MRTF_KERNEL_CACHE)
- delete_mrtentry_all_kernel_cache(mrtentry_ptr);
-
-#ifdef RSRR
- /* Tell the reservation daemon */
- rsrr_cache_clean(mrtentry_ptr);
-#endif /* RSRR */
-
- if (mrtentry_ptr->flags & MRTF_PMBR)
- {
- /* (*,*,RP) mrtentry */
- mrtentry_ptr->source->mrtlink = (mrtentry_t *) NULL;
- }
- else
- if (mrtentry_ptr->flags & MRTF_SG)
- {
- /* (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)
- {
- /*
- * All (S,G) MRT entries are gone. Allow creating (*,G)
- * MFC entries.
- */
- mrtentry_rp
- = mrtentry_ptr->group->active_rp_grp->rp->rpentry->mrtlink;
- mrtentry_wc = mrtentry_ptr->group->grp_route;
- if (mrtentry_rp != (mrtentry_t *) NULL)
- mrtentry_rp->flags &= ~MRTF_MFC_CLONE_SG;
- if (mrtentry_wc != (mrtentry_t *) NULL)
- mrtentry_wc->flags &= ~MRTF_MFC_CLONE_SG;
- else
- {
- /*
- * Delete the group entry if it has no (*,G) routing
- * 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;
- }
- else
- {
- /* This mrtentry should be (*,G) */
- grpentry_ptr = mrtentry_ptr->group;
- grpentry_ptr->grp_route = (mrtentry_t *) NULL;
-
- if (grpentry_ptr->mrtlink == (mrtentry_t *) NULL)
- /* Delete the group entry if it has no (S,G) entries */
- delete_grpentry(grpentry_ptr);
- }
-
- 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;
- RESET_TIMER(srcentry_ptr->timer);
- srcentry_ptr->cand_rp = (cand_rp_t *) NULL;
- 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;
- }
-
- /*
- * TODO: XXX: Note that this is NOT a (*,G) routing entry, but simply a
- * group entry, probably used to search the routing table (to find (S,G)
- * entries for example.) To become (*,G) routing entry, we must setup
- * grpentry_ptr->grp_route
- */
-
- grpentry_ptr->group = *group;
- memset(&grpentry_ptr->rpaddr, 0, sizeof(struct sockaddr_in6));
- grpentry_ptr->rpaddr.sin6_len = sizeof(struct sockaddr_in6);
- grpentry_ptr->rpaddr.sin6_family = AF_INET6;
- grpentry_ptr->mrtlink = (mrtentry_t *) NULL;
- grpentry_ptr->active_rp_grp = (rp_grp_entry_t *) NULL;
- grpentry_ptr->grp_route = (mrtentry_t *) NULL;
- grpentry_ptr->rpnext = (grpentry_t *) NULL;
- grpentry_ptr->rpprev = (grpentry_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_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->joined_oifs);
- IF_ZERO(&mrtentry_ptr->leaves);
- IF_ZERO(&mrtentry_ptr->pruned_oifs);
- IF_ZERO(&mrtentry_ptr->asserted_oifs);
- IF_ZERO(&mrtentry_ptr->oifs);
- mrtentry_ptr->upstream = (pim_nbr_entry_t *) NULL;
- mrtentry_ptr->metric = 0;
- mrtentry_ptr->preference = 0;
- mrtentry_ptr->pmbr_addr.sin6_addr = in6addr_any;
- mrtentry_ptr->pmbr_addr.sin6_len = sizeof(struct sockaddr_in6);
- mrtentry_ptr->pmbr_addr.sin6_family = AF_INET6;
-
-#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->vif_timers = (u_int16 *) malloc(sizeof(u_int16) * numvifs);
- mrtentry_ptr->vif_deletion_delay =
- (u_int16 *) malloc(sizeof(u_int16) * numvifs);
- vif_numbers = numvifs;
-#else
- mrtentry_ptr->vif_timers =
- (u_int16 *) malloc(sizeof(u_int16) * total_interfaces);
- mrtentry_ptr->vif_deletion_delay =
- (u_int16 *) malloc(sizeof(u_int16) * total_interfaces);
- vif_numbers = total_interfaces;
-#endif /* SAVE_MEMORY */
- if ((mrtentry_ptr->vif_timers == (u_int16 *) NULL) ||
- (mrtentry_ptr->vif_deletion_delay == (u_int16 *) 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->vif_timers; i < vif_numbers;
- i++, i_ptr++)
- RESET_TIMER(*i_ptr);
- for (i = 0, i_ptr = mrtentry_ptr->vif_deletion_delay; i < vif_numbers;
- i++, i_ptr++)
- RESET_TIMER(*i_ptr);
-
- mrtentry_ptr->flags = MRTF_NEW;
- RESET_TIMER(mrtentry_ptr->timer);
- RESET_TIMER(mrtentry_ptr->jp_timer);
- RESET_TIMER(mrtentry_ptr->rs_timer);
- RESET_TIMER(mrtentry_ptr->assert_timer);
- RESET_TIMER(mrtentry_ptr->assert_rate_timer);
- mrtentry_ptr->kernel_cache = (kernel_cache_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;
-
-
- if (flags & MRTF_SG)
- {
- /* (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;
-
- IF_DEBUG(DEBUG_MFC)
- log(LOG_DEBUG, 0, "create SG entry, source %s, group %s",
- inet6_fmt(&source->sin6_addr),
- inet6_fmt(&group->sin6_addr));
-
- return (r_new);
- }
-
- if (flags & MRTF_WC)
- {
- /* (*,G) entry */
-
- if (grpentry_ptr->grp_route != (mrtentry_t *) NULL)
- return (grpentry_ptr->grp_route);
- r_new = alloc_mrtentry(srcentry_ptr, grpentry_ptr);
- if (r_new == (mrtentry_t *) NULL)
- return (mrtentry_t *) NULL;
- grpentry_ptr->grp_route = r_new;
- r_new->flags |= (MRTF_WC | MRTF_RP);
- return (r_new);
- }
-
- if (flags & MRTF_PMBR)
- {
- /* (*,*,RP) entry */
-
- if (srcentry_ptr->mrtlink != (mrtentry_t *) NULL)
- return (srcentry_ptr->mrtlink);
- r_new = alloc_mrtentry(srcentry_ptr, grpentry_ptr);
- if (r_new == (mrtentry_t *) NULL)
- return (mrtentry_t *) NULL;
- srcentry_ptr->mrtlink = r_new;
- r_new->flags |= (MRTF_PMBR | MRTF_RP);
- return (r_new);
- }
-
- return (mrtentry_t *) NULL;
-}
-
-
-/*
- * Delete all kernel cache for this mrtentry
- */
-void
-delete_mrtentry_all_kernel_cache(mrtentry_ptr)
- mrtentry_t *mrtentry_ptr;
-{
- kernel_cache_t *kernel_cache_prev;
- kernel_cache_t *kernel_cache_ptr;
-
- if (!(mrtentry_ptr->flags & MRTF_KERNEL_CACHE))
- {
- return;
- }
-
- /* Free all kernel_cache entries */
- for (kernel_cache_ptr = mrtentry_ptr->kernel_cache;
- kernel_cache_ptr != (kernel_cache_t *) NULL;)
- {
- kernel_cache_prev = kernel_cache_ptr;
- kernel_cache_ptr = kernel_cache_ptr->next;
- k_del_mfc(mld6_socket, &kernel_cache_prev->source,
- &kernel_cache_prev->group);
- free((char *) kernel_cache_prev);
- }
- mrtentry_ptr->kernel_cache = (kernel_cache_t *) NULL;
-
- /* turn off the cache flag(s) */
- mrtentry_ptr->flags &= ~(MRTF_KERNEL_CACHE | MRTF_MFC_CLONE_SG);
-}
-
-
-void
-delete_single_kernel_cache(mrtentry_ptr, kernel_cache_ptr)
- mrtentry_t *mrtentry_ptr;
- kernel_cache_t *kernel_cache_ptr;
-{
- if (kernel_cache_ptr->prev == (kernel_cache_t *) NULL)
- {
- mrtentry_ptr->kernel_cache = kernel_cache_ptr->next;
- if (mrtentry_ptr->kernel_cache == (kernel_cache_t *) NULL)
- mrtentry_ptr->flags &= ~(MRTF_KERNEL_CACHE | MRTF_MFC_CLONE_SG);
- }
- else
- kernel_cache_ptr->prev->next = kernel_cache_ptr->next;
- if (kernel_cache_ptr->next != (kernel_cache_t *) NULL)
- kernel_cache_ptr->next->prev = kernel_cache_ptr->prev;
- IF_DEBUG(DEBUG_MFC)
- log(LOG_DEBUG, 0, "Deleting MFC entry for source %s and group %s",
- inet6_fmt(&kernel_cache_ptr->source.sin6_addr),
- inet6_fmt(&kernel_cache_ptr->source.sin6_addr));
- k_del_mfc(mld6_socket, &kernel_cache_ptr->source,
- &kernel_cache_ptr->group);
- free((char *) kernel_cache_ptr);
-}
-
-
-void
-delete_single_kernel_cache_addr(mrtentry_ptr, source, group)
- mrtentry_t *mrtentry_ptr;
- struct sockaddr_in6 *source;
- struct sockaddr_in6 *group;
-{
- kernel_cache_t *kernel_cache_ptr;
-
- if (mrtentry_ptr == (mrtentry_t *) NULL)
- return;
-
-
- /* Find the exact (S,G) kernel_cache entry */
- for (kernel_cache_ptr = mrtentry_ptr->kernel_cache;
- kernel_cache_ptr != (kernel_cache_t *) NULL;
- kernel_cache_ptr = kernel_cache_ptr->next)
- {
- if (inet6_lessthan(&kernel_cache_ptr->group, group))
- continue;
- if (inet6_greaterthan(&kernel_cache_ptr->group, group))
- return; /* Not found */
- if (inet6_lessthan(&kernel_cache_ptr->source, source))
- continue;
- if (inet6_greaterthan(&kernel_cache_ptr->source, source))
- return; /* Not found */
- /* Found exact match */
- break;
- }
-
- if (kernel_cache_ptr == (kernel_cache_t *) NULL)
- return;
-
- /* Found. Delete it */
- if (kernel_cache_ptr->prev == (kernel_cache_t *) NULL)
- {
- mrtentry_ptr->kernel_cache = kernel_cache_ptr->next;
- if (mrtentry_ptr->kernel_cache == (kernel_cache_t *) NULL)
- mrtentry_ptr->flags &= ~(MRTF_KERNEL_CACHE | MRTF_MFC_CLONE_SG);
- }
- else
- kernel_cache_ptr->prev->next = kernel_cache_ptr->next;
- if (kernel_cache_ptr->next != (kernel_cache_t *) NULL)
- kernel_cache_ptr->next->prev = kernel_cache_ptr->prev;
- IF_DEBUG(DEBUG_MFC)
- log(LOG_DEBUG, 0, "Deleting MFC entry for source %s and group %s",
- inet6_fmt(&kernel_cache_ptr->source.sin6_addr),
- inet6_fmt(&kernel_cache_ptr->group.sin6_addr));
- k_del_mfc(mld6_socket, &kernel_cache_ptr->source,
- &kernel_cache_ptr->group);
- free((char *) kernel_cache_ptr);
-}
-
-
-/*
- * Installs kernel cache for (source, group). Assumes mrtentry_ptr is the
- * correct entry.
- */
-void
-add_kernel_cache(mrtentry_ptr, source, group, flags)
- mrtentry_t *mrtentry_ptr;
- struct sockaddr_in6 *source;
- struct sockaddr_in6 *group;
- u_int16 flags;
-{
- kernel_cache_t *kernel_cache_next;
- kernel_cache_t *kernel_cache_prev;
- kernel_cache_t *kernel_cache_new;
-
- if (mrtentry_ptr == (mrtentry_t *) NULL)
- return;
-
- move_kernel_cache(mrtentry_ptr, flags);
-
- if (mrtentry_ptr->flags & MRTF_SG)
- {
- /* (S,G) */
- if (mrtentry_ptr->flags & MRTF_KERNEL_CACHE)
- return;
- kernel_cache_new = (kernel_cache_t *) malloc(sizeof(kernel_cache_t));
- kernel_cache_new->next = (kernel_cache_t *) NULL;
- kernel_cache_new->prev = (kernel_cache_t *) NULL;
- kernel_cache_new->source = *source;
- kernel_cache_new->group = *group;
- kernel_cache_new->sg_count.pktcnt = 0;
- kernel_cache_new->sg_count.bytecnt = 0;
- kernel_cache_new->sg_count.wrong_if = 0;
- mrtentry_ptr->kernel_cache = kernel_cache_new;
- mrtentry_ptr->flags |= MRTF_KERNEL_CACHE;
- return;
- }
-
- kernel_cache_prev = (kernel_cache_t *) NULL;
-
- for (kernel_cache_next = mrtentry_ptr->kernel_cache;
- kernel_cache_next != (kernel_cache_t *) NULL;
- kernel_cache_prev = kernel_cache_next,
- kernel_cache_next = kernel_cache_next->next)
- {
- if (inet6_lessthan(&kernel_cache_next->group , group))
- continue;
- if (inet6_greaterthan(&kernel_cache_next->group , group))
- break;
- if (inet6_lessthan(&kernel_cache_next->source , source))
- continue;
- if (inet6_greaterthan(&kernel_cache_next->source , source))
- break;
- /* Found exact match. Nothing to change. */
- return;
- }
-
- /*
- * The new entry must be placed between kernel_cache_prev and
- * kernel_cache_next
- */
- kernel_cache_new = (kernel_cache_t *) malloc(sizeof(kernel_cache_t));
- if (kernel_cache_prev != (kernel_cache_t *) NULL)
- kernel_cache_prev->next = kernel_cache_new;
- else
- mrtentry_ptr->kernel_cache = kernel_cache_new;
- if (kernel_cache_next != (kernel_cache_t *) NULL)
- kernel_cache_next->prev = kernel_cache_new;
- kernel_cache_new->prev = kernel_cache_prev;
- kernel_cache_new->next = kernel_cache_next;
- kernel_cache_new->source = *source;
- kernel_cache_new->group = *group;
- kernel_cache_new->sg_count.pktcnt = 0;
- kernel_cache_new->sg_count.bytecnt = 0;
- kernel_cache_new->sg_count.wrong_if = 0;
- mrtentry_ptr->flags |= MRTF_KERNEL_CACHE;
-}
-
-/*
- * Bring the kernel cache "UP": from the (*,*,RP) to (*,G) or (S,G)
- */
-static void
-move_kernel_cache(mrtentry_ptr, flags)
- mrtentry_t *mrtentry_ptr;
- u_int16 flags;
-{
- kernel_cache_t *kernel_cache_ptr;
- kernel_cache_t *insert_kernel_cache_ptr;
- kernel_cache_t *first_kernel_cache_ptr;
- kernel_cache_t *last_kernel_cache_ptr;
- kernel_cache_t *prev_kernel_cache_ptr;
- mrtentry_t *mrtentry_pmbr;
- mrtentry_t *mrtentry_rp;
- int found;
-
- if (mrtentry_ptr == (mrtentry_t *) NULL)
- return;
-
- if (mrtentry_ptr->flags & MRTF_PMBR)
- return;
-
- if (mrtentry_ptr->flags & MRTF_WC)
- {
- /* Move the cache info from (*,*,RP) to (*,G) */
- mrtentry_pmbr =
- mrtentry_ptr->group->active_rp_grp->rp->rpentry->mrtlink;
- if (mrtentry_pmbr == (mrtentry_t *) NULL)
- return; /* Nothing to move */
-
- first_kernel_cache_ptr = last_kernel_cache_ptr =
- (kernel_cache_t *) NULL;
- for (kernel_cache_ptr = mrtentry_pmbr->kernel_cache;
- kernel_cache_ptr != (kernel_cache_t *) NULL;
- kernel_cache_ptr = kernel_cache_ptr->next)
- {
- /*
- * The order is: (1) smaller group; (2) smaller source within
- * group
- */
- if (inet6_lessthan(&kernel_cache_ptr->group, &mrtentry_ptr->group->group))
- continue;
- if (!inet6_equal(&kernel_cache_ptr->group, &mrtentry_ptr->group->group))
- break;
- /* Select the kernel_cache entries to move */
- if (first_kernel_cache_ptr == (kernel_cache_t *) NULL)
- {
- first_kernel_cache_ptr = last_kernel_cache_ptr =
- kernel_cache_ptr;
- }
- else
- last_kernel_cache_ptr = kernel_cache_ptr;
- }
-
- if (first_kernel_cache_ptr != (kernel_cache_t *) NULL)
- {
- /* Fix the old chain */
- if (first_kernel_cache_ptr->prev != (kernel_cache_t *) NULL)
- {
- first_kernel_cache_ptr->prev->next =
- last_kernel_cache_ptr->next;
- }
- else
- mrtentry_pmbr->kernel_cache = last_kernel_cache_ptr->next;
- if (last_kernel_cache_ptr->next != (kernel_cache_t *) NULL)
- last_kernel_cache_ptr->next->prev =
- first_kernel_cache_ptr->prev;
- if (mrtentry_pmbr->kernel_cache == (kernel_cache_t *) NULL)
- mrtentry_pmbr->flags
- &= ~(MRTF_KERNEL_CACHE | MRTF_MFC_CLONE_SG);
-
- /* Insert in the new place */
- prev_kernel_cache_ptr = (kernel_cache_t *) NULL;
- last_kernel_cache_ptr->next = (kernel_cache_t *) NULL;
- mrtentry_ptr->flags |= MRTF_KERNEL_CACHE;
-
- for (kernel_cache_ptr = mrtentry_ptr->kernel_cache;
- kernel_cache_ptr != (kernel_cache_t *) NULL;)
- {
- if (first_kernel_cache_ptr == (kernel_cache_t *) NULL)
- break; /* All entries have been inserted */
- if (inet6_greaterthan(&kernel_cache_ptr->source,&first_kernel_cache_ptr->source))
- {
- /* Insert the entry before kernel_cache_ptr */
- insert_kernel_cache_ptr = first_kernel_cache_ptr;
- first_kernel_cache_ptr = first_kernel_cache_ptr->next;
- if (kernel_cache_ptr->prev != (kernel_cache_t *) NULL)
- kernel_cache_ptr->prev->next =
- insert_kernel_cache_ptr;
- else
- mrtentry_ptr->kernel_cache =
- insert_kernel_cache_ptr;
- insert_kernel_cache_ptr->prev =
- kernel_cache_ptr->prev;
- insert_kernel_cache_ptr->next = kernel_cache_ptr;
- kernel_cache_ptr->prev = insert_kernel_cache_ptr;
- }
- prev_kernel_cache_ptr = kernel_cache_ptr;
- kernel_cache_ptr = kernel_cache_ptr->next;
- }
- if (first_kernel_cache_ptr != (kernel_cache_t *) NULL)
- {
- /* Place all at the end after prev_kernel_cache_ptr */
- if (prev_kernel_cache_ptr != (kernel_cache_t *) NULL)
- prev_kernel_cache_ptr->next = first_kernel_cache_ptr;
- else
- mrtentry_ptr->kernel_cache = first_kernel_cache_ptr;
- first_kernel_cache_ptr->prev = prev_kernel_cache_ptr;
- }
- }
- return;
- }
-
- if (mrtentry_ptr->flags & MRTF_SG)
- {
- /*
- * (S,G) entry. Move the whole group cache from (*,*,RP) to (*,G) and
- * then get the necessary entry from (*,G). TODO: Not optimized! The
- * particular entry is moved first to (*,G), then we have to search
- * again (*,G) to find it and move to (S,G).
- */
- /* TODO: XXX: No need for this? Thinking.... */
- /* move_kernel_cache(mrtentry_ptr->group->grp_route, flags); */
-
- if ((mrtentry_rp = mrtentry_ptr->group->grp_route) ==
- (mrtentry_t *) NULL)
- mrtentry_rp =
- mrtentry_ptr->group->active_rp_grp->rp->rpentry->mrtlink;
- if (mrtentry_rp == (mrtentry_t *) NULL)
- return;
-
- if (mrtentry_rp->incoming != mrtentry_ptr->incoming)
- {
- /*
- * XXX: the (*,*,RP) (or (*,G)) iif is different from the (S,G)
- * iif. No need to move the cache, because (S,G) don't need it.
- * After the first packet arrives on the shortest path, the
- * correct cache entry will be created. If (flags &
- * MFC_MOVE_FORCE) then we must move the cache. This usually
- * happens when switching to the shortest path. The calling
- * function will immediately call k_chg_mfc() to modify the
- * kernel cache.
- */
- if (!(flags & MFC_MOVE_FORCE))
- return;
- }
-
- /* Find the exact entry */
-
- found = FALSE;
- for (kernel_cache_ptr = mrtentry_rp->kernel_cache;
- kernel_cache_ptr != (kernel_cache_t *) NULL;
- kernel_cache_ptr = kernel_cache_ptr->next)
- {
- if (inet6_lessthan(&kernel_cache_ptr->group, &mrtentry_ptr->group->group))
- continue;
- if (inet6_greaterthan(&kernel_cache_ptr->group, &mrtentry_ptr->group->group))
- break;
- if (inet6_lessthan(&kernel_cache_ptr->source, &mrtentry_ptr->source->address))
- continue;
- if (inet6_greaterthan(&kernel_cache_ptr->source, &mrtentry_ptr->source->address))
- break;
- /* We found it! */
- if (kernel_cache_ptr->prev != (kernel_cache_t *) NULL)
- kernel_cache_ptr->prev->next = kernel_cache_ptr->next;
- else
- {
- mrtentry_rp->kernel_cache = kernel_cache_ptr->next;
- }
- if (kernel_cache_ptr->next != (kernel_cache_t *) NULL)
- kernel_cache_ptr->next->prev = kernel_cache_ptr->prev;
- found = TRUE;
- break;
- }
-
- if (found == TRUE)
- {
- if (mrtentry_rp->kernel_cache == (kernel_cache_t *) NULL)
- mrtentry_rp->flags &= ~(MRTF_KERNEL_CACHE | MRTF_MFC_CLONE_SG);
- if (mrtentry_ptr->kernel_cache != (kernel_cache_t *) NULL)
- free((char *) mrtentry_ptr->kernel_cache);
- mrtentry_ptr->flags |= MRTF_KERNEL_CACHE;
- mrtentry_ptr->kernel_cache = kernel_cache_ptr;
- kernel_cache_ptr->prev = (kernel_cache_t *) NULL;
- kernel_cache_ptr->next = (kernel_cache_t *) NULL;
- }
- }
-}
diff --git a/usr.sbin/pim6sd/mrt.h b/usr.sbin/pim6sd/mrt.h
deleted file mode 100644
index 4aa428e..0000000
--- a/usr.sbin/pim6sd/mrt.h
+++ /dev/null
@@ -1,340 +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
- * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
- *
- */
-/*
- * This program has been derived from pim6dd.
- * The pim6dd program is covered by the license in the accompanying file
- * named "LICENSE.pim6dd".
- */
-/*
- * This program has been derived from pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- * $FreeBSD$
- */
-
-
-#ifndef MRT_H
-#define MRT_H
-
-#include <sys/param.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <net/route.h>
-#include <netinet/in.h>
-#include <netinet/ip_mroute.h>
-#include <netinet6/ip6_mroute.h>
-#include <string.h>
-#include "defs.h"
-
-
-/* flags for the mrt entries */
-
-#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) */
-#define MRTF_MFC_CLONE_SG 0x8000 /* clone (S,G) MFC from (*,G) or (*,*,RP) */
-
-#define CREATE TRUE
-#define DONT_CREATE FALSE
-
-
-#define MFC_MOVE_FORCE 0x1
-#define MFC_UPDATE_FORCE 0x2
-
-
-/* Macro to duplicate oif info (oif bits, timers) */
-
-#define VOIF_COPY(from , to ) \
- do { \
- IF_COPY(&from->joined_oifs , &to->joined_oifs); \
- IF_COPY(&from->oifs ,&to->oifs ); \
- IF_COPY(&from->leaves , &to->leaves); \
- IF_COPY(&from->pruned_oifs , &to->leaves ); \
- IF_COPY(&from->asserted_oifs ,&to->asserted_oifs); \
- bcopy(from->vif_timers , to->vif_timers , \
- numvifs*sizeof(from->vif_timers[0])); \
- bcopy(from->vif_deletion_delay , to->vif_deletion_delay , \
- numvifs*sizeof(from->vif_deletion_delay[0])); \
- } while (0)
-
-
-#define FREE_MRTENTRY(mrtentry_ptr) \
- do { \
- kernel_cache_t *prev; \
- kernel_cache_t *next; \
- \
- free( (char *)( (mrtentry_ptr)->vif_timers ) ); \
- free( (char *)( (mrtentry_ptr)->vif_deletion_delay ) ); \
- for( next=(mrtentry_ptr)->kernel_cache ; next!=(kernel_cache_t *)NULL ; ) \
- { \
- prev=next; \
- next=next->next; \
- free(prev); \
- } \
- free( (char *)( (mrtentry_ptr)->kernel_cache ) ); \
- free( (char *)(mrtentry_ptr) ); \
- } while (0)
-
-
-/*
- * The complicated structure used by the more complicated Join/Prune
- * message building
- */
-
-
-typedef struct build_jp_message {
- struct build_jp_message *next; /* Used to chain the free entries */
- u_int8 *jp_message; /* The Join/Prune message */
- u_int32 jp_message_size; /* Size of the Join/Prune message (in bytes) */
- u_int16 holdtime; /* Join/Prune message holdtime field */
- struct sockaddr_in6 curr_group; /* Current group address */
- u_int8 curr_group_msklen; /* Current group masklen */
- u_int8 *join_list; /* The working area for the join addresses */
- u_int32 join_list_size; /* The size of the join_list (in bytes) */
- u_int16 join_addr_number; /* Number of the join addresses in join_list */
- u_int8 *prune_list; /* The working area for the prune addresses */
- u_int32 prune_list_size; /* The size of the prune_list (in bytes) */
- u_int16 prune_addr_number; /* Number of the prune addresses in prune_list*/
- u_int8 *rp_list_join; /* The working area for RP join addresses */
- u_int32 rp_list_join_size; /* The size of the rp_list_join (in bytes) */
- u_int16 rp_list_join_number; /* Number of RP addresses in rp_list_join */
- u_int8 *rp_list_prune; /* The working area for RP prune addresses */
- u_int32 rp_list_prune_size; /* The size of the rp_list_prune (in bytes) */
- u_int16 rp_list_prune_number; /* Number of RP addresses in rp_list_prune */
- u_int8 *num_groups_ptr; /* Pointer to number_of_groups in jp_message */
-} build_jp_message_t;
-
-
-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 */
- build_jp_message_t *build_jp_message; /* A structure for fairly
- * complicated Join/Prune
- * message construction.
- */
-
-} pim_nbr_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? */
- struct cand_rp *cand_rp; /* Used if this is rpentry_t */
-} srcentry_t;
-typedef srcentry_t rpentry_t;
-
-/* (RP<->group) matching table related structures */
-
-typedef struct cand_rp {
- struct cand_rp *next; /* Next candidate RP */
- struct cand_rp *prev; /* Previous candidate RP */
- struct rp_grp_entry *rp_grp_next; /* The rp_grp_entry chain for that RP*/
- rpentry_t *rpentry; /* Pointer to the RP entry */
-} cand_rp_t;
-
-typedef struct grp_mask {
- struct grp_mask *next;
- struct grp_mask *prev;
- struct rp_grp_entry *grp_rp_next;
- struct sockaddr_in6 group_addr;
- struct in6_addr group_mask;
- struct in6_addr hash_mask;
- u_int16 fragment_tag; /* Used for garbage collection */
- u_int8 group_rp_number; /* Used when assembling segments */
-} grp_mask_t;
-
-typedef struct rp_grp_entry {
- struct rp_grp_entry *rp_grp_next; /* Next entry for same RP */
- struct rp_grp_entry *rp_grp_prev; /* Prev entry for same RP */
- struct rp_grp_entry *grp_rp_next; /* Next entry for same grp prefix */
- struct rp_grp_entry *grp_rp_prev; /* Prev entry for same grp prefix */
- struct grpentry *grplink; /* Link to all grps via this entry*/
- u_int16 advholdtime; /* The advertised holdtime */
- u_int16 holdtime; /* The RP holdtime (will be aged) */
- u_int16 fragment_tag; /* The fragment tag from the
- * received BSR message
- */
-
- u_int8 priority; /* The RP priority */
- grp_mask_t *group; /* Pointer to (group,mask) entry */
- cand_rp_t *rp; /* Pointer to the RP */
-} rp_grp_entry_t;
-
-typedef struct grpentry {
- struct grpentry *next; /* link to next entry */
- struct grpentry *prev; /* link to prev entry */
- struct grpentry *rpnext; /* next grp for the same RP */
- struct grpentry *rpprev; /* prev grp for the same RP */
- struct sockaddr_in6 group; /* subnet group of multicasts */
- struct sockaddr_in6 rpaddr; /* The IPv6 address of the RP */
- struct mrtentry *mrtlink; /* link to (S,G) routing entries */
- rp_grp_entry_t *active_rp_grp; /* Pointer to the active rp_grp entry*/
- struct mrtentry *grp_route; /* Pointer to the (*,G) routing entry*/
-} grpentry_t;
-
-typedef 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 joined_oifs; /* The joined oifs (Join received) */
- if_set pruned_oifs; /* The pruned oifs (Prune received) */
- if_set asserted_oifs; /* The asserted oifs (lost Assert) */
- 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; /* Routing Metric for this entry */
- u_int32 preference; /* The metric preference value */
- struct sockaddr_in6 pmbr_addr; /* The PMBR address (for interop) */
- u_int16 *vif_timers; /* vifs timer list */
- u_int16 *vif_deletion_delay; /* vifs deletion delay list */
-
- u_int16 flags; /* The MRTF_* flags */
- u_int16 timer; /* entry timer */
- u_int16 jp_timer; /* The Join/Prune timer */
- u_int16 rs_timer; /* Register-Suppression Timer */
- u_int assert_timer;
- u_int assert_rate_timer;
- struct kernel_cache *kernel_cache; /* List of the kernel cache entries */
-#ifdef RSRR
- struct rsrr_cache *rsrr_cache; /* Used to save RSRR requests for
- * routes change notification.
- */
-#endif /* RSRR */
-
-} mrtentry_t;
-
-
-/*
- * Used to get forwarded data related counts (number of packet, number of
- * bits, etc)
- */
-
-struct sg_count {
- u_quad_t pktcnt; /* Number of packets for (s,g) */
- u_quad_t bytecnt; /* Number of bytes for (s,g) */
- u_quad_t wrong_if; /* Number of packets received on wrong iif for (s,g) */
-};
-
-/*
- * Structure to keep track of existing (S,G) MFC entries in the kernel
- * for particular (*,G) or (*,*,RP) entry. We must keep track for
- * each active source which doesn't have (S,G) entry in the daemon's
- * routing table. We need to keep track of such sources for two reasons:
- *
- * (1) If the kernel does not support (*,G) MFC entries (currently, the
- * "official" mcast code doesn't), we must know all installed (s,G) entries
- * in the kernel and modify them if the iif or oif for the (*,G) changes.
- *
- * (2) By checking periodically the traffic coming from the shared tree,
- * we can either delete the idle sources or switch to the shortest path.
- *
- * Note that even if we have (*,G) implemented in the kernel, we still
- * need to have this structure because of (2)
- */
-
-
-typedef struct kernel_cache {
- struct kernel_cache *next;
- struct kernel_cache *prev;
- struct sockaddr_in6 source;
- struct sockaddr_in6 group;
- struct sg_count sg_count; /* The (s,g) data retated counters (see above) */
-} kernel_cache_t;
-
-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 */
-};
-
-/* globals and functions exportations */
-
-extern srcentry_t *srclist;
-extern grpentry_t *grplist;
-
-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 void delete_mrtentry_all_kernel_cache __P((mrtentry_t *mrtentry_ptr));
-extern void delete_single_kernel_cache __P((mrtentry_t *mrtentry_ptr,
- kernel_cache_t *kernel_cache_ptr));
-extern void delete_single_kernel_cache_addr __P((mrtentry_t *mrtentry_ptr,
- struct sockaddr_in6 *source,
- struct sockaddr_in6 *group));
-extern void add_kernel_cache __P((mrtentry_t *mrtentry_ptr,
- struct sockaddr_in6 *source, struct sockaddr_in6 *group,
- u_int16 flags));
-
-
-#endif
diff --git a/usr.sbin/pim6sd/mtrace6/Makefile b/usr.sbin/pim6sd/mtrace6/Makefile
deleted file mode 100644
index b9c1637..0000000
--- a/usr.sbin/pim6sd/mtrace6/Makefile
+++ /dev/null
@@ -1,85 +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 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.3 2000/02/25 06:35:42 itojun Exp $
-# $FreeBSD$
-#
-#
-#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.
-
-PROG= mtrace6
-
-CFLAGS+=-Wall
-CFLAGS+= -I$(.CURDIR)/.. -DHAVE_GETIFADDRS
-
-MAN= mtrace6.8
-
-.include <bsd.prog.mk>
diff --git a/usr.sbin/pim6sd/mtrace6/mtrace6.8 b/usr.sbin/pim6sd/mtrace6/mtrace6.8
deleted file mode 100644
index 23480b3..0000000
--- a/usr.sbin/pim6sd/mtrace6/mtrace6.8
+++ /dev/null
@@ -1,119 +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.
-.\"
-.\" $Id: mtrace6.8,v 1.3 1999/09/12 17:03:18 jinmei Exp $
-.\" $FreeBSD$
-.\"
-.Dd September 12, 1999
-.Dt MTRACE6 8
-.Os
-.Sh NAME
-.Nm mtrace6
-.Nd print IPv6 multicast path from a source to
-a receiver
-.Sh SYNOPSIS
-.Nm
-.Op Fl d Ar destination
-.Op Fl g Ar gateway
-.Op Fl h Ar hops
-.Op Fl i Ar interface
-.Op Fl m Ar maxhops
-.Op Fl n
-.Op Fl r Ar response_addr
-.Op Fl w Ar waittime
-.Ar source
-.Ar group
-.Sh DESCRIPTION
-.Nm
-utilizes a tracing feature implemented in multicast routers that is
-accessed via an extension to the MLD protocol. A trace query is
-passed hop-by-hop along the reverse path from the
-.Ar destination
-to the
-.Ar source ,
-collecting hop addresses, packet counts, and routing error conditions
-along the path, and then the response is returned to the requestor.
-.Sh OPTIONS
-.Bl -tag -width Ds
-.It Fl d Ar destination
-Specifies the multicast receiver that the query wants to trace.
-It is the host running
-.Nm
-by default.
-.It Fl g Ar gateway
-Send the trace query via unicast directly to the multicast router
-.Ar gateway .
-The unicast router must be the last-hop router on the path from the
-intended source to the receiver.
-.Ar gateway
-can also be a multicast address that the last hop router joins.
-.It Fl h Ar hops
-Set
-.Ar hops
-to the IPv6 hop limit field of query packets. The default is 64.
-.It Fl i Ar interface
-Specifies the local interface (on a multi-homed host) for sending
-the trace query and as the default for the receiver and the response
-destination.
-.It Fl m Ar maxhops
-Set to
-.Ar maxhops
-to the maximum number of hops that will be traced from the receiver
-back toward the source. The default is 127 hops.
-.It Fl n
-Print hop addresses numerically rather than symbolically and numerically
-(saves a nameserver address-to-name lookup for each router found on
-the path).
-.It Fl r Ar response_addr
-Specify the host that the trace response sends to.
-By default, the response will send to the host running
-.Nm .
-.It Fl w Ar waittime
-Set the time to wait for a trace response to
-.Ar waittime
-seconds. The default is 3 seconds.
-.El
-.Sh SEE ALSO
-.Xr pim6dd 8 ,
-.Xr pim6sd 8 ,
-.Xr mtrace 8
-.Sh BUGS
-Multicast trace for IPv6 is experimental. MLD types for query and
-response, and packet format are not officially defined.
-.Pp
-.Ar waittime
-specified by the
-.Fl w
-option is currently meaningless.
-.Sh HISTORY
-The
-.Nm
-command first appeared in WIDE/KAME IPv6 protocol stack kit.
-.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/pim6sd/mtrace6/mtrace6.c b/usr.sbin/pim6sd/mtrace6/mtrace6.c
deleted file mode 100644
index b6c838d..0000000
--- a/usr.sbin/pim6sd/mtrace6/mtrace6.c
+++ /dev/null
@@ -1,713 +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.
- *
- * $FreeBSD$
- */
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <sys/select.h>
-
-#include <net/if.h>
-#if defined(__FreeBSD__) && __FreeBSD__ >= 3
-#include <net/if_var.h>
-#endif
-
-#include <netinet/in.h>
-
-#include <netinet6/in6_var.h>
-#include <netinet/icmp6.h>
-
-#include <string.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <netdb.h>
-#include <err.h>
-#ifdef HAVE_GETIFADDRS
-#include <ifaddrs.h>
-#endif
-
-#include "trace.h"
-
-static char *gateway, *intface, *source, *group, *receiver, *destination;
-static int mldsoc, hops = 64, maxhops = 127, waittime = 3, querylen, opt_n;
-static struct sockaddr *gw_sock, *src_sock, *grp_sock, *dst_sock, *rcv_sock;
-static char *querypacket;
-static char frombuf[1024]; /* XXX: enough size? */
-
-int main __P((int, char *[]));
-static char *proto_type __P((u_int));
-static char *pr_addr __P((struct sockaddr *, int));
-static void setqid __P((int, char *));
-static void mtrace_loop __P((void));
-static char *str_rflags __P((int));
-static void show_ip6_result __P((struct sockaddr_in6 *, int));
-static void show_result __P((struct sockaddr *, int));
-static void set_sockaddr __P((char *, struct addrinfo *, struct sockaddr *));
-static int is_multicast __P((struct sockaddr *));
-static char *all_routers_str __P((int));
-static int ip6_validaddr __P((char *, struct sockaddr_in6 *));
-static int get_my_sockaddr __P((int, struct sockaddr *));
-static void set_hlim __P((int, struct sockaddr *, int));
-static void set_join __P((int, char *, struct sockaddr *));
-static void set_filter __P((int, int));
-static void open_socket __P((void));
-static void make_ip6_packet __P((void));
-static void make_packet __P((void));
-static void usage __P((void));
-
-int
-main(argc, argv)
- int argc;
- char *argv[];
-{
- int op;
-
- /* get parameters */
- while((op = getopt(argc, argv, "d:g:h:i:m:nr:w:")) != -1) {
- switch(op) {
- case 'd':
- destination = optarg;
- break;
- case 'g':
- gateway = optarg;
- break;
- case 'h':
- hops = atoi(optarg);
- if (hops < 0 || hops > 255) {
- warnx("query/response hops must be between 0 and 255");
- usage();
- }
- break;
- case 'i':
- intface = optarg;
- break;
- case 'm':
- maxhops = atoi(optarg);
- if (maxhops < 0 || maxhops > 255) {
- warnx("maxhops must be between 0 and 255");
- usage();
- }
- break;
- case 'n':
- opt_n = 1;
- break;
- case 'r':
- receiver = optarg;
- break;
- case 'w':
- waittime = atoi(optarg);
- break;
- case '?':
- default:
- usage();
- break;
- }
- }
- argc -= optind;
- argv += optind;
-
- if (argc < 2)
- usage();
- source = argv[0];
- group = argv[1];
-
- /* examine addresses and open a socket */
- open_socket();
-
- /* construct a query packet according to the specified parameters */
- make_packet();
-
- mtrace_loop();
- exit(0);
- /*NOTREACHED*/
-}
-
-static char *
-proto_type(type)
- u_int type;
-{
- static char buf[80];
-
- switch (type) {
- case PROTO_DVMRP:
- return ("DVMRP");
- case PROTO_MOSPF:
- return ("MOSPF");
- case PROTO_PIM:
- return ("PIM");
- case PROTO_CBT:
- return ("CBT");
- case PROTO_PIM_SPECIAL:
- return ("PIM/Special");
- case PROTO_PIM_STATIC:
- return ("PIM/Static");
- case PROTO_DVMRP_STATIC:
- return ("DVMRP/Static");
- case 0:
- return ("None");
- default:
- (void) sprintf(buf, "Unknown protocol code %d", type);
- return (buf);
- }
-}
-
-static char *
-pr_addr(addr, numeric)
- struct sockaddr *addr;
- int numeric;
-{
- static char buf[MAXHOSTNAMELEN];
- int flag = 0;
-
- if (numeric)
- flag |= NI_NUMERICHOST;
- flag |= NI_WITHSCOPEID;
-
- getnameinfo(addr, addr->sa_len, buf, sizeof(buf), NULL, 0, flag);
-
- return (buf);
-}
-
-static void
-setqid(family, query)
- int family;
- char *query;
-{
- struct tr6_query *q6;
-
- switch(family) {
- case AF_INET6:
- q6 = (struct tr6_query *)((struct mld6_hdr *)query + 1);
- q6->tr_qid = (u_int32_t)random();
- }
-}
-
-static void
-mtrace_loop()
-{
- int nsoc, fromlen, rcvcc;
- struct timeval tv, tv_wait;
- struct fd_set fds;
- struct sockaddr_storage from_ss;
- struct sockaddr *from_sock = (struct sockaddr *)&from_ss;
-
- /* initializa random number of query ID */
- gettimeofday(&tv, 0);
- srandom(tv.tv_usec);
-
- while(1) { /* XXX */
- setqid(gw_sock->sa_family, querypacket);
-
- if (sendto(mldsoc, (void *)querypacket, querylen, 0, gw_sock,
- gw_sock->sa_len) < 0)
- err(1, "sendto");
-
- tv_wait.tv_sec = waittime;
- tv_wait.tv_usec = 0;
-
- FD_ZERO(&fds);
- FD_SET(mldsoc, &fds);
-
- if ((nsoc = select(mldsoc + 1, &fds, NULL, NULL, &tv_wait)) < 0)
- err(1, "select");
-
- if (nsoc == 0) {
- printf("Timeout\n");
- exit(0); /* XXX try again? */
- }
-
- fromlen = sizeof(from_ss);
- if ((rcvcc = recvfrom(mldsoc, frombuf, sizeof(frombuf), 0,
- from_sock, &fromlen))
- < 0)
- err(1, "recvfrom");
-
- show_result(from_sock, rcvcc);
- exit(0); /* XXX */
- }
-}
-
-char *fwd_code[] = {"NOERR", "WRONGIF", "SPRUNE", "RPRUNE", "SCOPED", "NORT",
- "WRONGLH", "NOFWD", "RP", "RPFIF", "NOMC", "HIDDEN"};
-char *fwd_errcode[] = {"", "NOSPC", "OLD", "ADMIN"};
-
-static char *
-str_rflags(flag)
- int flag;
-{
- if (0x80 & flag) { /* fatal error */
- flag &= ~0x80;
- if (flag >= sizeof(fwd_errcode) / sizeof(char *) ||
- flag == 0) {
- warnx("unknown error code(%d)", flag);
- return("UNKNOWN");
- }
- return(fwd_errcode[flag]);
- }
-
- /* normal code */
- if (flag >= sizeof(fwd_code) / sizeof(char *)) {
- warnx("unknown forward code(%d)", flag);
- return("UNKNOWN");
- }
- return(fwd_code[flag]);
-}
-
-static void
-show_ip6_result(from6, datalen)
- struct sockaddr_in6 *from6;
- int datalen;
-{
- struct mld6_hdr *mld6_tr_resp = (struct mld6_hdr *)frombuf;
- struct mld6_hdr *mld6_tr_query = (struct mld6_hdr *)querypacket;
- struct tr6_query *tr6_rquery = (struct tr6_query *)(mld6_tr_resp + 1);
- struct tr6_query *tr6_query = (struct tr6_query *)(mld6_tr_query + 1);
- struct tr6_resp *tr6_resp = (struct tr6_resp *)(tr6_rquery + 1),
- *rp, *rp_end;
- int i;
-
- if (datalen < sizeof(*mld6_tr_resp) + sizeof(*tr6_rquery) +
- sizeof(*tr6_resp)) {
- warnx("show_ip6_result: receive data length(%d) is short",
- datalen);
- return;
- }
-
- switch(mld6_tr_resp->mld6_type) {
- case MLD6_MTRACE_RESP:
- if ((datalen - sizeof(*mld6_tr_resp) - sizeof(*tr6_rquery)) %
- sizeof(*tr6_resp)) {
- warnx("show_ip6_result: incomplete response (%d bytes)",
- datalen);
- return;
- }
- rp_end = (struct tr6_resp *)((char *)mld6_tr_resp + datalen);
-
- /* sanity check for the response */
- if (tr6_query->tr_qid != tr6_rquery->tr_qid ||
- !IN6_ARE_ADDR_EQUAL(&tr6_query->tr_src, &tr6_rquery->tr_src) ||
- !IN6_ARE_ADDR_EQUAL(&tr6_query->tr_dst, &tr6_rquery->tr_dst))
- return; /* XXX: bark here? */
-
- for (i = 0, rp = tr6_resp; rp < rp_end; i++, rp++) {
- struct sockaddr_in6 sa_resp, sa_upstream;
-
- /* reinitialize the sockaddr. paranoid? */
- memset((void *)&sa_resp, 0, sizeof(sa_resp));
- sa_resp.sin6_family = AF_INET6;
- sa_resp.sin6_len = sizeof(sa_resp);
- memset((void *)&sa_upstream, 0, sizeof(sa_upstream));
- sa_upstream.sin6_family = AF_INET6;
- sa_upstream.sin6_len = sizeof(sa_upstream);
-
- sa_resp.sin6_addr = rp->tr_lcladdr;
- sa_upstream.sin6_addr = rp->tr_rmtaddr;
-
- /* print information for the router */
- printf("%3d ", -i);/* index */
- /* router address and incoming/outgoing interface */
- printf("%s", pr_addr((struct sockaddr *)&sa_resp, opt_n));
- printf("(%s/%d->%d) ",
- pr_addr((struct sockaddr *)&sa_upstream, 1),
- ntohl(rp->tr_inifid), ntohl(rp->tr_outifid));
- /* multicast routing protocol type */
- printf("%s ", proto_type(rp->tr_rproto));
- /* forwarding error code */
- printf("%s", str_rflags(rp->tr_rflags & 0xff));
-
- putchar('\n');
- }
-
- break;
- default: /* impossible... */
- warnx("show_ip6_result: invalid ICMPv6 type(%d)",
- mld6_tr_resp->mld6_type); /* assert? */
- break;
- }
-}
-
-static void
-show_result(from, datalen)
- struct sockaddr *from;
- int datalen;
-{
- switch(from->sa_family) {
- case AF_INET6:
- show_ip6_result((struct sockaddr_in6 *)from, datalen);
- break;
- default:
- errx(1, "show_result: illegal AF(%d) on recv", from->sa_family);
- }
-}
-
-static void
-set_sockaddr(addrname, hints, sap)
- char *addrname;
- struct addrinfo *hints;
- struct sockaddr *sap;
-{
- struct addrinfo *res;
- int ret_ga;
-
- ret_ga = getaddrinfo(addrname, NULL, hints, &res);
- if (ret_ga)
- errx(1, "getaddrinfo faild: %s", gai_strerror(ret_ga));
- if (!res->ai_addr)
- errx(1, "getaddrinfo failed");
- memcpy((void *)sap, (void *)res->ai_addr, res->ai_addr->sa_len);
-
- freeaddrinfo(res);
-}
-
-static int
-is_multicast(sa)
- struct sockaddr *sa;
-{
- switch(sa->sa_family) {
- case AF_INET6:
- if (IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)sa)->sin6_addr))
- return 1;
- else
- return 0;
- break;
- default:
- return 0; /* XXX: support IPv4? */
- }
-}
-
-static char *
-all_routers_str(family)
- int family;
-{
- switch(family) {
- case AF_INET6:
- return("ff02::1");
- default:
- errx(1, "all_routers_str: unknown AF(%d)", family);
- }
-}
-
-static int
-ip6_validaddr(ifname, addr)
- char *ifname;
- struct sockaddr_in6 *addr;
-{
- int s;
- struct in6_ifreq ifr6;
- u_int32_t flags6;
-
- /* we need a global address only...XXX: should be flexible? */
- if (IN6_IS_ADDR_LOOPBACK(&addr->sin6_addr) ||
- IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr) ||
- IN6_IS_ADDR_SITELOCAL(&addr->sin6_addr))
- return(0);
-
- /* get IPv6 dependent flags and examine them */
- if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
- err(1, "ip6_validaddr: socket");
-
- strncpy(ifr6.ifr_name, ifname, sizeof(ifr6.ifr_name));
- ifr6.ifr_addr = *addr;
- if (ioctl(s, SIOCGIFAFLAG_IN6, &ifr6) < 0)
- err(1, "ioctl(SIOCGIFAFLAG_IN6)");
- close(s);
- flags6 = ifr6.ifr_ifru.ifru_flags6;
- if (flags6 & (IN6_IFF_ANYCAST | IN6_IFF_TENTATIVE |
- IN6_IFF_DUPLICATED | IN6_IFF_DETACHED))
- return(0);
-
- return(1);
-}
-
-static int
-get_my_sockaddr(family, addrp)
- int family;
- struct sockaddr *addrp;
-{
-#ifdef HAVE_GETIFADDRS
- struct ifaddrs *ifap, *ifa;
-
- if (getifaddrs(&ifap) != 0) {
- err(1, "getifaddrs");
- /*NOTREACHED */
- }
-
- for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
- if (ifa->ifa_addr->sa_family == family) {
- switch(family) {
- case AF_INET6:
- if (ip6_validaddr(ifa->ifa_name,
- (struct sockaddr_in6 *)ifa->ifa_addr))
- goto found;
- }
- }
- }
-
- freeifaddrs(ifap);
- return (-1); /* not found */
-
- found:
- memcpy((void *)addrp, (void *)ifa->ifa_addr, ifa->ifa_addr->sa_len);
- freeifaddrs(ifap);
- return (0);
-#else
-#define IF_BUFSIZE 8192 /* XXX: adhoc...should be customizable? */
- int i, s;
- struct ifconf ifconf;
- struct ifreq *ifrp;
- static char ifbuf[IF_BUFSIZE];
-
- if ((s = socket(family, SOCK_DGRAM, 0)) < 0)
- err(1, "socket");
-
- ifconf.ifc_buf = ifbuf;
- ifconf.ifc_len = sizeof(ifbuf);
-
- if (ioctl(s, SIOCGIFCONF, (char *)&ifconf) < 0)
- err(1, "ioctl(SIOCGIFCONF)");
- close(s);
-
- for (i = 0; i < ifconf.ifc_len; ) {
- ifrp = (struct ifreq *)(ifbuf + i);
- if (ifrp->ifr_addr.sa_family == family) {
- switch(family) {
- case AF_INET6:
- if (ip6_validaddr(ifrp->ifr_name,
- (struct sockaddr_in6 *)&ifrp->ifr_addr))
- goto found;
- }
- }
-
- i += IFNAMSIZ;
- /* i += max(sizeof(sockaddr), ifr_addr.sa_len) */
- if (ifrp->ifr_addr.sa_len > sizeof(struct sockaddr))
- i += ifrp->ifr_addr.sa_len;
- else
- i += sizeof(struct sockaddr);
- }
-
- return(-1); /* not found */
-
- found:
- memcpy((void *)addrp, (void *)&ifrp->ifr_addr, ifrp->ifr_addr.sa_len);
- return(0);
-#undef IF_BUFSIZE
-#endif
-}
-
-static void
-set_hlim(s, addr, hops)
- int s, hops;
- struct sockaddr *addr;
-{
- struct sockaddr_in6 *sin6;
- int opt;
-
- switch(addr->sa_family) {
- case AF_INET6:
- sin6 = (struct sockaddr_in6 *)addr;
- opt = IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr) ?
- IPV6_MULTICAST_HOPS : IPV6_UNICAST_HOPS;
- if (setsockopt(s, IPPROTO_IPV6, opt, (char *)&hops,
- sizeof(hops)) == -1)
- err(1, "setsockopt(%s)",
- (opt == IPV6_MULTICAST_HOPS) ?
- "IPV6_MULTICAST_HOPS" : "IPV6_UNICAST_HOPS");
- break;
- }
-}
-
-static void
-set_join(s, ifname, group)
- int s;
- char *ifname;
- struct sockaddr *group;
-{
- struct ipv6_mreq mreq6;
- u_int ifindex;
-
- switch(group->sa_family) {
- case AF_INET6:
- if ((ifindex = if_nametoindex(ifname)) == 0)
- err(1, "set_join: if_nametoindex failed for %s", ifname);
- mreq6.ipv6mr_multiaddr =
- ((struct sockaddr_in6 *)group)->sin6_addr;
- mreq6.ipv6mr_interface = ifindex;
-
- if (setsockopt(s, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq6,
- sizeof(mreq6)) < 0)
- err(1, "setsockopt(IPV6_JOIN_GROUP)");
- break;
- }
-}
-
-static void
-set_filter(s, family)
- int s, family;
-{
- struct icmp6_filter filter6;
-
- switch(family) {
- case AF_INET6:
- ICMP6_FILTER_SETBLOCKALL(&filter6);
- ICMP6_FILTER_SETPASS(MLD6_MTRACE_RESP, &filter6);
- if (setsockopt(s, IPPROTO_ICMPV6, ICMP6_FILTER, &filter6,
- sizeof(filter6)) < 0)
- err(1, "setsockopt(ICMP6_FILTER)");
- break;
- }
-}
-
-static void
-open_socket()
-{
- struct addrinfo hints;
- static struct sockaddr_storage gw_ss, src_ss, grp_ss, dst_ss, rcv_ss;
-
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = AF_INET6; /* to be independent of AF? */
- hints.ai_socktype = SOCK_RAW;
- hints.ai_protocol = IPPROTO_ICMPV6;
-
- /* multicast group(must be specified) */
- grp_sock = (struct sockaddr *)&grp_ss;
- set_sockaddr(group, &hints, grp_sock);
- if (!is_multicast(grp_sock))
- errx(1, "group(%s) is not a multicast address", group);
-
- /* multicast source(must be specified) */
- src_sock = (struct sockaddr *)&src_ss;
- set_sockaddr(source, &hints, src_sock);
- if (is_multicast(src_sock))
- errx(1, "source(%s) is not a unicast address", source);
-
- /* last hop gateway for the destination(if specified) */
- gw_sock = (struct sockaddr *)&gw_ss;
- if (gateway) /* can be either multicast or unicast */
- set_sockaddr(gateway, &hints, gw_sock);
- else {
- char *r = all_routers_str(grp_sock->sa_family);
-
- set_sockaddr(r, &hints, gw_sock);
- }
-
- /* destination address for the trace */
- dst_sock = (struct sockaddr *)&dst_ss;
- if (destination) {
- set_sockaddr(destination, &hints, dst_sock);
- if (is_multicast(dst_sock))
- errx(1, "destination(%s) is not a unicast address",
- destination);
- }
- else {
- /* XXX: consider interface? */
- get_my_sockaddr(grp_sock->sa_family, dst_sock);
- }
-
- /* response receiver(if specified) */
- rcv_sock = (struct sockaddr *)&rcv_ss;
- if (receiver) { /* can be either multicast or unicast */
- set_sockaddr(receiver, &hints, rcv_sock);
- if (is_multicast(rcv_sock) &&
- intface == NULL) {
-#ifdef notyet
- warnx("receive I/F is not specified for multicast"
- "response(%s)", receiver);
- intface = default_intface;
-#else
- errx(1, "receive I/F is not specified for multicast"
- "response(%s)", receiver);
-#endif
- }
- }
- else {
- /* XXX: consider interface? */
- get_my_sockaddr(grp_sock->sa_family, rcv_sock);
- }
-
- if ((mldsoc = socket(hints.ai_family, hints.ai_socktype,
- hints.ai_protocol)) < 0)
- err(1, "socket");
-
- /* set necessary socket options */
- if (hops)
- set_hlim(mldsoc, gw_sock, hops);
- if (receiver && is_multicast(rcv_sock))
- set_join(mldsoc, intface, rcv_sock);
- set_filter(mldsoc, grp_sock->sa_family);
-}
-
-static void
-make_ip6_packet()
-{
- struct mld6_hdr *mld6_tr_query;
- struct tr6_query *tr6_query;
-
- querylen = sizeof(*mld6_tr_query) + sizeof(*tr6_query);
- if ((querypacket = malloc(querylen)) == NULL)
- errx(1, "make_ip6_packet: malloc failed");
- memset(querypacket, 0, querylen);
-
- /* fill in MLD header */
- mld6_tr_query = (struct mld6_hdr *)querypacket;
- mld6_tr_query->mld6_type = MLD6_MTRACE;
- mld6_tr_query->mld6_code = maxhops & 0xff;
- mld6_tr_query->mld6_addr = ((struct sockaddr_in6 *)grp_sock)->sin6_addr;
-
- /* fill in mtrace query fields */
- tr6_query = (struct tr6_query *)(mld6_tr_query + 1);
- tr6_query->tr_src = ((struct sockaddr_in6 *)src_sock)->sin6_addr;
- tr6_query->tr_dst = ((struct sockaddr_in6 *)dst_sock)->sin6_addr;
- tr6_query->tr_raddr = ((struct sockaddr_in6 *)rcv_sock)->sin6_addr;
- tr6_query->tr_rhlim = 0xff & hops;
-}
-
-static void
-make_packet()
-{
- switch(grp_sock->sa_family) {
- case AF_INET6:
- make_ip6_packet();
- break;
- default:
- errx(1, "make_packet: unsupported AF(%d)", grp_sock->sa_family);
- }
-}
-
-static void
-usage()
-{
- fprintf(stderr, "usage: mtrace6 %s\n",
- "[-d destination] [-g gateway] [-h hops] [-i interface] "
- "[-m maxhops] [-n] [-r response_addr] [-w waittime] source group");
- exit(1);
-}
diff --git a/usr.sbin/pim6sd/pathnames.h b/usr.sbin/pim6sd/pathnames.h
deleted file mode 100644
index 27e871a..0000000
--- a/usr.sbin/pim6sd/pathnames.h
+++ /dev/null
@@ -1,80 +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
- * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
- *
- */
-/*
- * This program has been derived from pim6dd.
- * The pim6dd program is covered by the license in the accompanying file
- * named "LICENSE.pim6dd".
- */
-/*
- * This program has been derived from pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- */
-/*
- * 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$
- */
-
-#ifndef PATHNAMES_H
-#define PATHNAMES_H
-
-#define _PATH_PIM6D_CONF "/etc/pim6sd.conf"
-#define _PATH_PIM6D_LOGFILE "/var/log/pim6sd.log"
-
-#if (defined(BSD) && (BSD >= 199103))
- #define _PATH_PIM6D_PID "/var/run/pim6sd.pid"
- #define _PATH_PIM6D_GENID "/var/run/pim6sd.genid"
- #define _PATH_PIM6D_DUMP "/var/run/pim6sd.dump"
- #define _PATH_PIM6D_CACHE "/var/run/pim6sd.cache"
- #define _PATH_PIM6D_STAT "/var/run/pim6sd.stat"
-#else
- #define _PATH_PIM6D_PID "/etc/pim6sd.pid"
- #define _PATH_PIM6D_GENID "/etc/pim6sd.genid"
- #define _PATH_PIM6D_DUMP "/etc/pim6sd.dump"
- #define _PATH_PIM6D_CACHE "/etc/pim6sd.cache"
- #define _PATH_PIM6D_STAT "/etc/pim6sd.stat"
-#endif
-
-#endif
diff --git a/usr.sbin/pim6sd/pim6.c b/usr.sbin/pim6sd/pim6.c
deleted file mode 100644
index 2741693..0000000
--- a/usr.sbin/pim6sd/pim6.c
+++ /dev/null
@@ -1,518 +0,0 @@
-/*
- * Copyright (C) 1999 LSIIT Laboratory.
- * 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 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.
- */
-/*
- * Questions concerning this software should be directed to
- * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
- *
- */
-/*
- * This program has been derived from pim6dd.
- * The pim6dd program is covered by the license in the accompanying file
- * named "LICENSE.pim6dd".
- */
-/*
- * This program has been derived from pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- * $FreeBSD$
- */
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-#include <errno.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <netinet6/ip6_mroute.h>
-#include <netinet6/pim6.h>
-#include <netinet/ip6.h>
-#include <arpa/inet.h>
-#include <stdlib.h>
-#include <syslog.h>
-#include <signal.h>
-#include "mld6.h"
-#include "defs.h"
-#include "kern.h"
-#include "pim6.h"
-#include "pimd.h"
-#include "pim6_proto.h"
-#include "inet6.h"
-#include "debug.h"
-
-struct sockaddr_in6 allpim6routers_group;
-int pim6_socket;
-char *pim6_recv_buf;
-char *pim6_send_buf;
-
-static struct sockaddr_in6 from;
-static struct iovec sndiovpim[2];
-static struct iovec rcviovpim[2];
-static struct msghdr sndmhpim,
- rcvmhpim;
-static u_char *sndcmsgbufpim = NULL;
-static int sndcmsglen;
-static u_char *rcvcmsgbufpim = NULL;
-static int rcvcmsglen;
-
-
-/*
- * 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()
-{
- struct cmsghdr *cmsgp;
- int on;
-
- if ( (pim6_recv_buf = malloc( RECV_BUF_SIZE)) == NULL ||
- (pim6_send_buf = malloc (RECV_BUF_SIZE)) == NULL)
- log(LOG_ERR,errno,"pim6 buffer allocation");
-
- IF_DEBUG(DEBUG_KERN)
- log(LOG_DEBUG,0,"%d octets allocated for the emit/recept buffer pim6",RECV_BUF_SIZE);
-
- 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);
- k_set_hlim(pim6_socket,MINHLIM);
- k_set_loop(pim6_socket,FALSE);
-
- memset(&allpim6routers_group, 0, sizeof(allpim6routers_group));
- 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");
- memset(&sockaddr6_d, 0, sizeof(sockaddr6_d));
- sockaddr6_d.sin6_len = sizeof(sockaddr6_d);
- sockaddr6_d.sin6_family = AF_INET6;
- if (inet_pton(AF_INET6, "ff00::",
- (void *)&sockaddr6_d.sin6_addr) != 1)
- log(LOG_ERR, 0, "inet_pton failed for ff00::");
-
- /* specify to tell receiving interface */
- on = 1;
-#ifdef IPV6_RECVPKTINFO
- if (setsockopt(pim6_socket, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on,
- sizeof(on)) < 0)
- log(LOG_ERR, errno, "setsockopt(IPV6_RECVPKTINFO)");
-#else
- if (setsockopt(pim6_socket, IPPROTO_IPV6, IPV6_PKTINFO, &on,
- sizeof(on)) < 0)
- log(LOG_ERR, errno, "setsockopt(IPV6_PKTINFO)");
-#endif
-
- /* initialize msghdr for receiving packets */
- rcviovpim[0].iov_base = (caddr_t) pim6_recv_buf;
- rcviovpim[0].iov_len = RECV_BUF_SIZE;
- rcvmhpim.msg_name = (caddr_t ) &from;
- rcvmhpim.msg_namelen = sizeof (from);
- rcvmhpim.msg_iov = rcviovpim;
- rcvmhpim.msg_iovlen = 1;
- rcvcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo));
- if (rcvcmsgbufpim == NULL &&
- (rcvcmsgbufpim = malloc(rcvcmsglen)) == NULL)
- log(LOG_ERR, 0, "malloc failed");
- rcvmhpim.msg_control = (caddr_t ) rcvcmsgbufpim;
- rcvmhpim.msg_controllen = rcvcmsglen;
-
- sndmhpim.msg_namelen=sizeof(struct sockaddr_in6);
- sndmhpim.msg_iov=sndiovpim;
- sndmhpim.msg_iovlen=1;
- sndcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo));
- if (sndcmsgbufpim == NULL &&
- (sndcmsgbufpim = malloc(sndcmsglen)) == NULL)
- log(LOG_ERR, 0, "malloc failed");
- sndmhpim.msg_control = (caddr_t)sndcmsgbufpim;
- sndmhpim.msg_controllen = sndcmsglen;
- cmsgp=(struct cmsghdr *)sndcmsgbufpim;
- cmsgp->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
- cmsgp->cmsg_level = IPPROTO_IPV6;
- cmsgp->cmsg_type = IPV6_PKTINFO;
-
- if ( register_input_handler(pim6_socket, pim6_read) <0)
- log(LOG_ERR,0,"Registering pim6 socket");
-
- /* Initialize the building Join/Prune messages working area */
- build_jp_message_pool = (build_jp_message_t *)NULL;
- build_jp_message_pool_counter = 0;
-}
-
-/* Read a PIM message */
-
-static void
-pim6_read(f, rfd)
- int f;
- fd_set *rfd;
-{
- register int pim6_recvlen;
-
-#ifdef SYSV
- sigset_t block, oblock;
-#else
- register int omask;
-#endif
-
- pim6_recvlen = recvmsg(pim6_socket,&rcvmhpim,0);
-
- 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 dst;
- struct in6_pktinfo *pi=NULL;
- struct sockaddr_in6 *src = (struct sockaddr_in6 *)rcvmhpim.msg_name;
- struct cmsghdr *cm;
- int ifindex=0;
-
- /* 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 *)rcvmhpim.msg_iov[0].iov_base;
-
- /* extract vital information via Advanced API */
- for(cm = (struct cmsghdr *)CMSG_FIRSTHDR(&rcvmhpim);
- cm;
- cm =(struct cmsghdr *)CMSG_NXTHDR(&rcvmhpim , 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));
- dst.sin6_addr=pi->ipi6_addr;
- ifindex = pi->ipi6_ifindex;
- if (IN6_IS_ADDR_LINKLOCAL(&dst.sin6_addr))
- dst.sin6_scope_id = ifindex;
- else
- dst.sin6_scope_id = 0;
- }
- }
-
- if(pi==NULL)
- log(LOG_ERR,0,"pim6_socket : unable to get destination packet");
-
- if(ifindex==0)
- log(LOG_ERR,0,"pim6_socket : unable to get ifindex");
-
-#define NOSUCHDEF
-#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));
- }
- }
-#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:
- receive_pim6_register(src, &dst, (char *)(pim), pimlen);
- break;
- case PIM_REGISTER_STOP:
- receive_pim6_register_stop(src, &dst, (char *)(pim), pimlen);
- break;
- case PIM_JOIN_PRUNE:
- receive_pim6_join_prune(src, &dst, (char *)(pim), pimlen);
- break;
- case PIM_BOOTSTRAP:
- receive_pim6_bootstrap(src, &dst, (char *)(pim), pimlen);
- break;
- case PIM_ASSERT:
- receive_pim6_assert(src, &dst, (char *)(pim), pimlen);
- break;
- case PIM_GRAFT:
- pim6dstat.in_pim6_graft++;
- log(LOG_INFO, 0, "ignore %s from %s",
- packet_kind(IPPROTO_PIM, pim->pim_type, 0),
- inet6_fmt(&src->sin6_addr));
- break;
- case PIM_GRAFT_ACK:
- pim6dstat.in_pim6_graft_ack++;
- log(LOG_INFO, 0, "ignore %s from %s",
- packet_kind(IPPROTO_PIM, pim->pim_type, 0),
- inet6_fmt(&src->sin6_addr));
- break;
- case PIM_CAND_RP_ADV:
- receive_pim6_cand_rp_adv(src, &dst, (char *)(pim), pimlen);
- break;
- default:
- log(LOG_INFO, 0,
- "ignore unknown PIM message code %u from %s",
- pim->pim_type,
- inet6_fmt(&src->sin6_addr));
- break;
- }
-}
-
-void
-send_pim6(char *buf, struct sockaddr_in6 *src,
- struct sockaddr_in6 *dst, int type, int datalen)
-{
- struct pim *pim;
- int setloop=0;
- int ifindex=0;
- int sendlen=sizeof(struct pim)+datalen;
- struct cmsghdr *cmsgp;
- struct in6_pktinfo *sndpktinfo;
-
- sndiovpim[0].iov_base=(caddr_t)buf;
- sndiovpim[0].iov_len=datalen+sizeof(struct pim);
- cmsgp=(struct cmsghdr *)sndcmsgbufpim;
- sndpktinfo=(struct in6_pktinfo *)CMSG_DATA(cmsgp);
- sndmhpim.msg_name=(caddr_t)dst;
-
- pim = (struct pim *)buf;
- pim->pim_type = type;
- pim->pim_ver = PIM_PROTOCOL_VERSION;
- pim->pim_rsv = 0;
- pim->pim_cksum = 0;
-
- if(pim->pim_type == PIM_REGISTER)
- {
- sendlen = sizeof(struct pim)+sizeof(pim_register_t);
-
- }
-
- pim->pim_cksum = pim6_cksum((u_int16 *)pim,
- &src->sin6_addr, &dst->sin6_addr,
- sendlen);
-
- if (IN6_IS_ADDR_MULTICAST(&dst->sin6_addr))
- {
- if (!IN6_IS_ADDR_LINKLOCAL(&src->sin6_addr))
- {
- log(LOG_WARNING, 0,
- "trying to send pim multicast packet "
- "with non linklocal src(%s), ignoring",
- inet6_fmt(&src->sin6_addr));
- return;
- }
- sndmhpim.msg_control=NULL;
- sndmhpim.msg_controllen=0;
- ifindex=src->sin6_scope_id;
-
- 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);
- }
- }
- else
- {
- sndmhpim.msg_control = (caddr_t)sndcmsgbufpim;
- sndmhpim.msg_controllen = sndcmsglen;
- sndpktinfo->ipi6_ifindex=src->sin6_scope_id;
- memcpy(&sndpktinfo->ipi6_addr, &src->sin6_addr,
- sizeof(sndpktinfo->ipi6_addr));
- }
- if (sendmsg(pim6_socket, &sndmhpim, 0) < 0) {
- if (errno == ENETDOWN)
- check_vif_state();
- else {
- log(LOG_WARNING, errno, "sendmsg from %s to %s",
- inet6_fmt(&src->sin6_addr),
- inet6_fmt(&dst->sin6_addr));
- }
- }
-
- if(setloop)
- k_set_loop(pim6_socket, FALSE);
-
- return;
-}
-
-/* ============================== */
-
-/*
- * 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.
- */
-int pim6_cksum(u_short *addr, struct in6_addr *src ,struct in6_addr *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/pim6sd/pim6.h b/usr.sbin/pim6sd/pim6.h
deleted file mode 100644
index 4b4356a..0000000
--- a/usr.sbin/pim6sd/pim6.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 1999 LSIIT Laboratory.
- * 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.
- */
-/*
- * Questions concerning this software should be directed to
- * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
- *
- */
-/*
- * This program has been derived from pim6dd.
- * The pim6dd program is covered by the license in the accompanying file
- * named "LICENSE.pim6dd".
- */
-/*
- * This program has been derived from pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- * $FreeBSD$
- */
-
-
-#ifndef PIM6_H
-#define PIM6_H
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <netinet/in.h>
-#include <unistd.h>
-#include <netinet6/ip6_mroute.h>
-
-extern struct sockaddr_in6 allpim6routers_group;
-extern char *pim6_send_buf;
-extern int pim6_socket;
-
-void init_pim6 __P((void));
-extern void send_pim6 __P((char *buf, struct sockaddr_in6 *src,
- struct sockaddr_in6 *dst, int type,
- int datalen));
-
-
-#endif
diff --git a/usr.sbin/pim6sd/pim6_proto.c b/usr.sbin/pim6sd/pim6_proto.c
deleted file mode 100644
index dd65ed1..0000000
--- a/usr.sbin/pim6sd/pim6_proto.c
+++ /dev/null
@@ -1,4129 +0,0 @@
-/*
- * Copyright (C) 1999 LSIIT Laboratory.
- * 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 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
- * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
- *
- */
-/*
- * This program has been derived from pim6dd.
- * The pim6dd program is covered by the license in the accompanying file
- * named "LICENSE.pim6dd".
- */
-/*
- * This program has been derived from pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- * $FreeBSD$
- */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet6/pim6.h>
-#include <netinet/ip6.h>
-#include <syslog.h>
-#include <stdlib.h>
-#include "mrt.h"
-#include "defs.h"
-#include "vif.h"
-#include "debug.h"
-#include "pim6.h"
-#include "pim6_proto.h"
-#include "pimd.h"
-#include "rp.h"
-#include "mld6.h"
-#include "timer.h"
-#include "route.h"
-#include "inet6.h"
-#include "kern.h"
-#include "routesock.h"
-
-/*
- * Local functions definitions.
- */
-
-static int parse_pim6_hello __P((char *pktPtr , int datalen , struct sockaddr_in6 *src,
- u_int16 *holdtime));
-
-static int send_pim6_register_stop __P((struct sockaddr_in6 *reg_src , struct sockaddr_in6 *reg_dst ,
- struct sockaddr_in6 *inner_source,
- struct sockaddr_in6 *inner_grp));
-
-static build_jp_message_t *get_jp6_working_buff __P((void));
-static void return_jp6_working_buff __P((pim_nbr_entry_t * pim_nbr));
-static void pack_jp6_message __P((pim_nbr_entry_t * pim_nbr));
-static void send_jp6_message __P((pim_nbr_entry_t * pim_nbr));
-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));
-
-build_jp_message_t *build_jp_message_pool;
-int build_jp_message_pool_counter;
-struct sockaddr_in6 sockaddr6_any = {sizeof(struct sockaddr_in6) , AF_INET6 ,0,0, IN6ADDR_ANY_INIT};
-struct sockaddr_in6 sockaddr6_d;
-
-struct pim6dstat pim6dstat;
-
-/************************************************************************
- * 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;
- int bsr_length;
- u_int8 *data_ptr;
- srcentry_t *srcentry_ptr;
- mrtentry_t *mrtentry_ptr;
-
-
- 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];
- v->uv_in_pim6_hello++; /* increment statistacs */
- if (v->uv_flags & (VIFF_DOWN | VIFF_DISABLED | MIFF_REGISTER))
- 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_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;
- SET_TIMER(new_nbr->timer, holdtime);
- new_nbr->build_jp_message = (build_jp_message_t *) NULL;
- 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;
-
- /* Since a new neighbour has come up, let it know your existence */
- /*
- * XXX: TODO: not in the spec, but probably should send the message after
- * a short random period?
- */
-
- send_pim6_hello(v, pim_hello_holdtime);
-
- if (v->uv_flags & VIFF_DR)
- {
- /*
- * If I am the current DR on that interface, so send an RP-Set
- * message to the new neighbor.
- */
-
- if ((bsr_length = create_pim6_bootstrap_message(pim6_send_buf)))
- send_pim6(pim6_send_buf, &v->uv_linklocal->pa_addr , src , PIM_BOOTSTRAP,
- bsr_length);
-
-
- /* The router with highest network address is the elected DR */
- if (inet6_lessthan(&v->uv_linklocal->pa_addr,&v->uv_pim_neighbors->address))
- {
- /*
- * I was the DR, but not anymore. Remove all register_vif from
- * oif list for all directly connected sources (for vifi).
- */
- /* TODO: XXX: first entry is not used! */
- for (srcentry_ptr = srclist->next;
- srcentry_ptr != (srcentry_t *) NULL;
- srcentry_ptr = srcentry_ptr->next)
- {
- /* If not directly connected source for vifi */
-
- if ((srcentry_ptr->incoming != mifi)
- || (srcentry_ptr->upstream != (pim_nbr_entry_t *) NULL))
- continue;
- for (mrtentry_ptr = srcentry_ptr->mrtlink;
- mrtentry_ptr != (mrtentry_t *) NULL;
- mrtentry_ptr = mrtentry_ptr->srcnext)
- {
- if (!(mrtentry_ptr->flags & MRTF_SG))
- continue; /* This is not (S,G) entry */
- /* Remove the register oif */
- IF_CLR(reg_vif_num, &mrtentry_ptr->joined_oifs);
- change_interfaces(mrtentry_ptr,
- mrtentry_ptr->incoming,
- &mrtentry_ptr->joined_oifs,
- &mrtentry_ptr->pruned_oifs,
- &mrtentry_ptr->leaves,
- &mrtentry_ptr->asserted_oifs, 0);
- }
- }
- v->uv_flags &= ~VIFF_DR;
- }
- }
-
- /*
- * TODO: XXX: does a new neighbor change any routing entries info? Need
- * to trigger joins?
- */
-
- IF_DEBUG(DEBUG_PIM_HELLO)
- log(LOG_DEBUG,0,"I'have got a new neighbor %s on vif %s",inet6_fmt(&src->sin6_addr),v->uv_name);
- 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;
- mrtentry_t *mrtentry_srcs;
- grpentry_t *grpentry_ptr;
- pim_nbr_entry_t *new_nbr;
- cand_rp_t *cand_rp_ptr;
- rp_grp_entry_t *rp_grp_entry_ptr;
- rpentry_t *rpentry_ptr;
- struct uvif *v;
-
- 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;
-
- return_jp6_working_buff(nbr_delete);
-
- 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);
- }
- 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 */
- for (srcentry_ptr = srclist; srcentry_ptr != (srcentry_t *) NULL;
- srcentry_ptr = srcentry_ptr_next)
- {
- srcentry_ptr_next = srcentry_ptr->next;
-
- if (srcentry_ptr->upstream != nbr_delete)
- continue;
-
- /* Reset the next hop (PIM) router */
-
- if (set_incoming(srcentry_ptr, PIM_IIF_SOURCE) == FALSE)
- {
- /*
- * Coudn't reset it. Sorry, the hext 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);
- }
- else
- if (srcentry_ptr->upstream != (pim_nbr_entry_t *) NULL)
- {
- /* Ignore the local or directly connected sources */
- /*
- * Browse all MRT entries for this source and reset the
- * upstream router. Note that the upstream router is not
- * always toward the source: it could be toward the RP for
- * example.
- */
- new_nbr = srcentry_ptr->upstream;
- for (mrtentry_ptr = srcentry_ptr->mrtlink;
- mrtentry_ptr != (mrtentry_t *) NULL;
- mrtentry_ptr = mrtentry_ptr->srcnext)
- {
- if (!(mrtentry_ptr->flags & MRTF_RP))
- {
- mrtentry_ptr->upstream = srcentry_ptr->upstream;
- mrtentry_ptr->metric = srcentry_ptr->metric;
- mrtentry_ptr->preference = srcentry_ptr->preference;
- change_interfaces(mrtentry_ptr, srcentry_ptr->incoming,
- &mrtentry_ptr->joined_oifs,
- &mrtentry_ptr->pruned_oifs,
- &mrtentry_ptr->leaves,
- &mrtentry_ptr->asserted_oifs, 0);
- }
- }
- }
- }
-
- /* Update the RP entries */
- for (cand_rp_ptr = cand_rp_list; cand_rp_ptr != (cand_rp_t *) NULL;
- cand_rp_ptr = cand_rp_ptr->next)
- {
- if (cand_rp_ptr->rpentry->upstream != nbr_delete)
- continue;
- rpentry_ptr = cand_rp_ptr->rpentry;
- /* Reset the RP entry iif */
- /* TODO: check if error setting the iif! */
- if (local_address(&rpentry_ptr->address) == NO_VIF)
- {
- set_incoming(rpentry_ptr, PIM_IIF_RP);
- }
- else
- {
- rpentry_ptr->incoming = reg_vif_num;
- rpentry_ptr->upstream = (pim_nbr_entry_t *) NULL;
- }
- mrtentry_ptr = rpentry_ptr->mrtlink;
- if (mrtentry_ptr != (mrtentry_t *) NULL)
- {
- mrtentry_ptr->upstream = rpentry_ptr->upstream;
- mrtentry_ptr->metric = rpentry_ptr->metric;
- mrtentry_ptr->preference = rpentry_ptr->preference;
- change_interfaces(mrtentry_ptr,
- rpentry_ptr->incoming,
- &mrtentry_ptr->joined_oifs,
- &mrtentry_ptr->pruned_oifs,
- &mrtentry_ptr->leaves,
- &mrtentry_ptr->asserted_oifs, 0);
- }
- /* Update the group entries for this RP */
- for (rp_grp_entry_ptr = cand_rp_ptr->rp_grp_next;
- rp_grp_entry_ptr != (rp_grp_entry_t *) NULL;
- rp_grp_entry_ptr = rp_grp_entry_ptr->rp_grp_next)
- {
- for (grpentry_ptr = rp_grp_entry_ptr->grplink;
- grpentry_ptr != (grpentry_t *) NULL;
- grpentry_ptr = grpentry_ptr->rpnext)
- {
- mrtentry_ptr = grpentry_ptr->grp_route;
- if (mrtentry_ptr != (mrtentry_t *) NULL)
- {
- mrtentry_ptr->upstream = rpentry_ptr->upstream;
- mrtentry_ptr->metric = rpentry_ptr->metric;
- mrtentry_ptr->preference = rpentry_ptr->preference;
- change_interfaces(mrtentry_ptr,
- rpentry_ptr->incoming,
- &mrtentry_ptr->joined_oifs,
- &mrtentry_ptr->pruned_oifs,
- &mrtentry_ptr->leaves,
- &mrtentry_ptr->asserted_oifs, 0);
- }
- /* Update only the (S,G)RPbit entries for this group */
- for (mrtentry_srcs = grpentry_ptr->mrtlink;
- mrtentry_srcs != (mrtentry_t *) NULL;
- mrtentry_srcs = mrtentry_srcs->grpnext)
- {
- if (mrtentry_srcs->flags & MRTF_RP)
- {
- mrtentry_ptr->upstream = rpentry_ptr->upstream;
- mrtentry_ptr->metric = rpentry_ptr->metric;
- mrtentry_ptr->preference = rpentry_ptr->preference;
- change_interfaces(mrtentry_srcs,
- rpentry_ptr->incoming,
- &mrtentry_srcs->joined_oifs,
- &mrtentry_srcs->pruned_oifs,
- &mrtentry_srcs->leaves,
- &mrtentry_srcs->asserted_oifs, 0);
- }
- }
- }
- }
- }
-
- 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);
- SET_TIMER(v->uv_pim_hello_timer, pim_hello_period);
-
- v->uv_out_pim6_hello++;
- return (TRUE);
-}
-
-/************************************************************************
- * PIM_REGISTER
- ************************************************************************/
-/*
- * TODO: XXX: IF THE BORDER BIT IS SET, THEN FORWARD THE WHOLE PACKET FROM
- * USER SPACE AND AT THE SAME TIME IGNORE ANY CACHE_MISS SIGNALS FROM THE
- * KERNEL.
- */
-
-int
-receive_pim6_register(reg_src, reg_dst, pim_message, datalen)
- struct sockaddr_in6 *reg_src,
- *reg_dst;
- char *pim_message;
- int datalen;
-{
- struct sockaddr_in6 inner_src,
- inner_grp;
- pim_register_t *register_p;
- struct ip6_hdr *ip;
- u_int32 borderBit,
- nullRegisterBit;
- mrtentry_t *mrtentry_ptr;
- mrtentry_t *mrtentry_ptr2;
- if_set oifs;
-
- pim6dstat.in_pim6_register++;
-
- register_p = (pim_register_t *) (pim_message + sizeof(struct pim));
-
- borderBit = ntohl(register_p->reg_flags) & PIM_MESSAGE_REGISTER_BORDER_BIT;
- nullRegisterBit =
- ntohl(register_p->reg_flags) & PIM_MESSAGE_REGISTER_NULL_REGISTER_BIT;
-
- /* initialize the pointer to the encapsulated packet */
- ip = (struct ip6_hdr *) (register_p + 1);
-
- /*
- * We are keeping all addresses in network order,
- * so no need for byte order translation.
- */
- inner_src.sin6_addr = ip->ip6_src;
- inner_grp.sin6_addr = ip->ip6_dst;
-
- /* scope validation of the inner source and destination addresses */
- if (IN6_IS_ADDR_LINKLOCAL(&ip->ip6_src)) {
- log(LOG_WARNING, 0,
- "receive_pim6_register: inner source(%s) has invalid scope",
- inet6_fmt(&ip->ip6_src));
- }
-#ifdef notyet
- if (IN6_IS_ADDR_SITELOCAL)
- inner_src.sin6_scope_id = addr2scopeid(&ip->ip6_src, &ip->ip6_dst,
- reg_src, reg_dst);
- else
-#endif
- inner_src.sin6_scope_id = 0;
-
- if (IN6_IS_ADDR_MC_NODELOCAL(&ip->ip6_dst) ||
- IN6_IS_ADDR_MC_LINKLOCAL(&ip->ip6_dst)) {
- log(LOG_WARNING, 0,
- "receive_pim6_register: inner group(%s) has invalid scope",
- inet6_fmt(&ip->ip6_dst));
- return(FALSE); /* XXX: can we discard it? */
- }
-#ifdef notyet
- if (IN6_IS_ADDR_MC_SITELOCAL(&ip->ip6_dst))
- inner_grp.sin6_scope_id = addr2scopeid(&ip->ip6_src, &ip->ip6_dst,
- reg_src, reg_dst);
- else
- inner_grp.sin6_scope_id = 0;
-#endif
- inner_grp.sin6_scope_id = 0;
-
- mrtentry_ptr = find_route(&inner_src, &inner_grp,
- MRTF_SG | MRTF_WC | MRTF_PMBR, DONT_CREATE);
-
- if (mrtentry_ptr == (mrtentry_t *) NULL)
- {
-
- /* No routing entry. Send REGISTER_STOP and return. */
-
- IF_DEBUG(DEBUG_PIM_REGISTER)
- log(LOG_DEBUG, 0,
- "No routing entry for source %s and/or group %s",
- inet6_fmt(&inner_src.sin6_addr), inet6_fmt(&inner_grp.sin6_addr));
-
- /* TODO: XXX: shouldn't be inner_src=IN6ADDR_ANY? Not in the spec. */
-
- send_pim6_register_stop(reg_dst, reg_src, &inner_grp, &inner_src);
- return (TRUE);
- }
-
- /* XXX: not in the spec: check if I am the RP for that group */
- if (!inet6_equal(&my_cand_rp_address, reg_dst)
- || (check_mrtentry_rp(mrtentry_ptr, &my_cand_rp_address) == FALSE))
- {
- send_pim6_register_stop(reg_dst, reg_src, &inner_grp, &inner_src);
- return (TRUE);
- }
-
- if (mrtentry_ptr->flags & MRTF_SG)
- {
-
- /* (S,G) found */
- /* TODO: check the timer again */
-
- SET_TIMER(mrtentry_ptr->timer, pim_data_timeout); /* restart timer */
- if (!(mrtentry_ptr->flags & MRTF_SPT))
- {
- /* The SPT bit is not set */
-
- if (!nullRegisterBit)
- {
- calc_oifs(mrtentry_ptr, &oifs);
- if (IF_ISEMPTY(&oifs)
- && (mrtentry_ptr->incoming == reg_vif_num))
- {
- send_pim6_register_stop(reg_dst, reg_src, &inner_grp,
- &inner_src);
- return (TRUE);
- }
-
- /*
- * TODO: XXX: BUG!!! The data will be forwarded by the kernel
- * MFC!!! Need to set a special flag for this routing entry
- * so after a cache miss occur, the multicast packet will be
- * forwarded from user space and won't install entry in the
- * kernel MFC. The problem is that the kernel MFC doesn't
- * know the PMBR address and simply sets the multicast
- * forwarding cache to accept/forward all data coming from
- * the register_vif.
- */
-
- if (borderBit)
- {
- if (!inet6_equal(&mrtentry_ptr->pmbr_addr,reg_src))
- {
- send_pim6_register_stop(reg_dst, reg_src,
- &inner_grp, &inner_src);
- return (TRUE);
-
- }
- }
- return (TRUE);
- }
- /* TODO: XXX: if NULL_REGISTER and has (S,G) with SPT=0, then..? */
- return (TRUE);
- }
- else
- {
- /* The SPT bit is set */
- send_pim6_register_stop(reg_dst, reg_src, &inner_grp, &inner_src);
- return (TRUE);
- }
- }
- if (mrtentry_ptr->flags & (MRTF_WC | MRTF_PMBR))
- {
- if (borderBit)
- {
- /*
- * Create (S,G) state. The oifs will be the copied from the
- * existing (*,G) or (*,*,RP) entry.
- */
-
- mrtentry_ptr2 = find_route(&inner_src, &inner_grp, MRTF_SG,
- CREATE);
- if (mrtentry_ptr2 != (mrtentry_t *) NULL)
- {
- mrtentry_ptr2->pmbr_addr = *reg_src;
-
- /* Clear the SPT flag */
-
- mrtentry_ptr2->flags &= ~(MRTF_SPT | MRTF_NEW);
- SET_TIMER(mrtentry_ptr2->timer, pim_data_timeout);
-
- /* TODO: explicitly call the Join/Prune send function? */
-
- FIRE_TIMER(mrtentry_ptr2->jp_timer); /* Send the Join
- * immediately */
- /*
- * TODO: explicitly call this function?
- * send_pim6_join_prune(mrtentry_ptr2->upstream->vifi,
- * mrtentry_ptr2->upstream, pim_join_prune_holdtime);
- */
- }
- }
- }
-
- if (mrtentry_ptr->flags & MRTF_WC)
- {
- /* (*,G) entry */
-
- calc_oifs(mrtentry_ptr, &oifs);
- if (IF_ISEMPTY(&oifs))
- {
- send_pim6_register_stop(reg_dst, reg_src, &inner_grp, &sockaddr6_any);
- return (FALSE);
- }
-
- /* XXX: TODO: check with the spec again */
-
- else
- {
- if (!nullRegisterBit)
- {
- /* Install cache entry in the kernel */
- /*
- * TODO: XXX: probably redundant here, because the
- * decapsulated mcast packet in the kernel will result in
- * CACHE_MISS
- */
-
- struct sockaddr_in6 *mfc_source = &inner_src;
-
-
-#ifdef KERNEL_MFC_WC_G
- if (!(mrtentry_ptr->flags & MRTF_MFC_CLONE_SG))
- mfc_source = NULL;
-#endif /* KERNEL_MFC_WC_G */
-
- add_kernel_cache(mrtentry_ptr, mfc_source, &inner_grp, 0);
- k_chg_mfc(mld6_socket, mfc_source, &inner_grp,
- mrtentry_ptr->incoming, &mrtentry_ptr->oifs,
- &mrtentry_ptr->group->rpaddr);
- return (TRUE);
- }
- }
- return (TRUE);
- }
-
- if (mrtentry_ptr->flags & MRTF_PMBR)
- {
- /* (*,*,RP) entry */
- if (!nullRegisterBit)
- {
- struct sockaddr_in6 *mfc_source = &inner_src;
-
- /*
- * XXX: have to create either (S,G) or (*,G). The choice below is
- * (*,G)
- */
-
- mrtentry_ptr2 = find_route(NULL, &inner_grp, MRTF_WC,
- CREATE);
- if (mrtentry_ptr2 == (mrtentry_t *) NULL)
- return (FALSE);
- if (mrtentry_ptr2->flags & MRTF_NEW)
- {
- /* TODO: something else? Have the feeling sth is missing */
-
- mrtentry_ptr2->flags &= ~MRTF_NEW;
-
- /* TODO: XXX: copy the timer from the (*,*,RP) entry? */
-
- COPY_TIMER(mrtentry_ptr->timer, mrtentry_ptr2->timer);
- }
- /* Install cache entry in the kernel */
-
-#ifdef KERNEL_MFC_WC_G
-
- if (!(mrtentry_ptr->flags & MRTF_MFC_CLONE_SG))
- mfc_source = NULL;
-#endif /* KERNEL_MFC_WC_G */
- add_kernel_cache(mrtentry_ptr, mfc_source, &inner_grp, 0);
- k_chg_mfc(mld6_socket, mfc_source, &inner_grp,
- mrtentry_ptr->incoming, &mrtentry_ptr->oifs,
- &mrtentry_ptr2->group->rpaddr);
-
- return (TRUE);
- }
- }
-
- /* Shoudn't happen: invalid routing entry? */
- /* XXX: TODO: shoudn't be inner_src=IN6ADDR_ANY? Not in the spec. */
-
- send_pim6_register_stop(reg_dst, reg_src, &inner_grp, &inner_src);
- return (TRUE);
-}
-
-
-int
-send_pim6_register(pkt)
- char *pkt;
-{
- register struct ip6_hdr *ip6;
- static struct sockaddr_in6 source= {sizeof(source) , AF_INET6 };
- static struct sockaddr_in6 group= {sizeof(group) , AF_INET6 };
- mifi_t mifi;
- rpentry_t *rpentry_ptr;
- mrtentry_t *mrtentry_ptr;
- mrtentry_t *mrtentry_ptr2;
-
- struct sockaddr_in6 *reg_src,
- *reg_dst;
- int pktlen = 0;
- char *buf;
-
- ip6=(struct ip6_hdr *)pkt;
-
- group.sin6_addr = ip6->ip6_dst;
- source.sin6_addr = ip6->ip6_src;
-
- if ((mifi = find_vif_direct_local(&source)) == NO_VIF)
- return (FALSE);
-
- if (!(uvifs[mifi].uv_flags & VIFF_DR))
- return (FALSE); /* I am not the DR for that subnet */
-
-
-
- rpentry_ptr = rp_match(&group);
- if (rpentry_ptr == (rpentry_t *) NULL)
- return (FALSE); /* No RP for this group */
- if (local_address(&rpentry_ptr->address) != NO_VIF)
- /* TODO: XXX: not sure it is working! */
- return (FALSE); /* I am the RP for this group */
-
- mrtentry_ptr = find_route(&source, &group, MRTF_SG, CREATE);
- if (mrtentry_ptr == (mrtentry_t *) NULL)
- return (FALSE); /* Cannot create (S,G) state */
-
- if (mrtentry_ptr->flags & MRTF_NEW)
- {
- /* A new entry */
- mrtentry_ptr->flags &= ~MRTF_NEW;
- RESET_TIMER(mrtentry_ptr->rs_timer); /* Reset the
- * Register-Suppression timer */
- if ((mrtentry_ptr2 = mrtentry_ptr->group->grp_route) ==
- (mrtentry_t *) NULL)
- mrtentry_ptr2 =
- mrtentry_ptr->group->active_rp_grp->rp->rpentry->mrtlink;
- if (mrtentry_ptr2 != (mrtentry_t *) NULL)
- {
- FIRE_TIMER(mrtentry_ptr2->jp_timer); /* Timeout the
- * Join/Prune timer */
- /*
- * TODO: explicitly call this function?
- * send_pim6_join_prune(mrtentry_ptr2->upstream->vifi,
- * mrtentry_ptr2->upstream, pim_join_prune_holdtime);
- */
- }
- }
- /* Restart the (S,G) Entry-timer */
-
- SET_TIMER(mrtentry_ptr->timer, pim_data_timeout);
-
- IF_TIMER_NOT_SET(mrtentry_ptr->rs_timer)
- {
- /*
- * The Register-Suppression Timer is not running. Encapsulate the
- * data and send to the RP.
- */
- buf = pim6_send_buf + sizeof(struct pim);
-
- bzero(buf, sizeof(pim_register_t)); /* No flags set */
- buf += sizeof(pim_register_t);
-
- /* Copy the data packet at the back of the register packet */
- /* TODO: check pktlen. ntohs? */
-
- pktlen = ntohs(ip6->ip6_plen);
- pktlen +=sizeof(struct ip6_hdr); /* XXX */
-
- bcopy((char *) ip6, buf, pktlen);
- pktlen += sizeof(pim_register_t);
- reg_src = max_global_address();
- reg_dst = &mrtentry_ptr->group->rpaddr;
-
- send_pim6(pim6_send_buf, reg_src , reg_dst , PIM_REGISTER,
- pktlen);
-
- pim6dstat.out_pim6_register++;
-
- return (TRUE);
- }
- return (TRUE);
-}
-
-int
-send_pim6_null_register(mrtentry_ptr)
- mrtentry_t *mrtentry_ptr;
-{
- struct ip6_hdr *ip;
- pim_register_t *pim_register;
- int pktlen = 0;
- mifi_t mifi;
- struct sockaddr_in6 *reg_source,
- *dest;
-
- /* No directly connected source; no local address */
-
- if ((mifi = find_vif_direct_local(&mrtentry_ptr->source->address)) == NO_VIF)
- return (FALSE);
-
- pim_register = (pim_register_t *) (pim6_send_buf + sizeof(struct pim));
- bzero((char *) pim_register, sizeof(pim_register_t));
- pim_register->reg_flags = htonl(pim_register->reg_flags
- | PIM_MESSAGE_REGISTER_NULL_REGISTER_BIT);
-
- /* include the dummy ip header */
- ip = (struct ip6_hdr *) (pim_register +1);
- ip->ip6_plen= 0;
- ip->ip6_flow=0;
- ip->ip6_vfc = 0x60;
- ip->ip6_hlim = MINHLIM;
- ip->ip6_nxt = IPPROTO_NONE;
- ip->ip6_src = mrtentry_ptr->source->address.sin6_addr;
- ip->ip6_dst = mrtentry_ptr->group->group.sin6_addr;
-
- pktlen = sizeof(pim_register_t) + sizeof(struct ip6_hdr);
-
- dest = &mrtentry_ptr->group->rpaddr;
- reg_source = max_global_address();
-
- send_pim6(pim6_send_buf, reg_source , dest, PIM_REGISTER,
- pktlen);
- pim6dstat.out_pim6_register++; /* should be counted separately? */
-
- return (TRUE);
-}
-
-
-/************************************************************************
- * PIM_REGISTER_STOP
- ************************************************************************/
-int
-receive_pim6_register_stop(reg_src, reg_dst, pim_message, datalen)
- struct sockaddr_in6 *reg_src,
- *reg_dst;
- char *pim_message;
- register int datalen;
-{
- pim_register_stop_t *pim_regstop_p;
- pim6_encod_grp_addr_t encod_grp;
- pim6_encod_uni_addr_t encod_unisrc;
- struct sockaddr_in6 source,
- group;
- u_int8 *data_ptr;
- mrtentry_t *mrtentry_ptr;
- if_set pruned_oifs;
- mifi_t mifi;
- struct uvif *v;
-
- pim6dstat.in_pim6_register_stop++;
-
- pim_regstop_p = (pim_register_stop_t *) (pim_message +
- sizeof(struct pim));
- data_ptr = (u_int8 *) & pim_regstop_p->encod_grp;
- GET_EGADDR6(&encod_grp, data_ptr);
- GET_EUADDR6(&encod_unisrc, data_ptr);
-
- group.sin6_addr = encod_grp.mcast_addr;
-
- /* scope validation of the inner source and destination addresses */
-
-#ifdef notyet
- if (IN6_IS_ADDR_MC_SITELOCAL(&ip->ip6_dst))
- group.sin6_scope_id = addr2scopeid(&ip->ip6_src, &ip->ip6_dst,
- reg_src, reg_dst);
- else
-#endif
-
- group.sin6_scope_id = 0;
- source.sin6_addr = encod_unisrc.unicast_addr;
-
- /* the source address must be global...but is it always true? */
-
-#ifdef notyet
- if (IN6_IS_ADDR_SITELOCAL)
- source.sin6_scope_id = addr2scopeid(&ip->ip6_src, &ip->ip6_dst,
- reg_src, reg_dst);
- else
-#endif
-
- source.sin6_scope_id = 0;
-
- if((mifi= find_vif_direct_local(&source))==NO_VIF)
- {
- IF_DEBUG(DEBUG_PIM_REGISTER)
- {
- log(LOG_WARNING,0,
- "Received PIM_REGISTER_STOP from RP %s for a non "
- "direct-connect source %s",
- inet6_fmt(&reg_src->sin6_addr),
- inet6_fmt(&encod_unisrc.unicast_addr));
- }
- return FALSE;
- }
-
- v=&uvifs[mifi];
-
-
- group.sin6_scope_id = inet6_uvif2scopeid(&group, v);
- source.sin6_scope_id = inet6_uvif2scopeid(&source,
- v);
-
-
- IF_DEBUG(DEBUG_PIM_REGISTER)
- {
- log(LOG_DEBUG, 0,
- "Received PIM_REGISTER_STOP from RP %s to %s "
- "source : %s group : %s",
- inet6_fmt(&reg_src->sin6_addr),
- inet6_fmt(&reg_dst->sin6_addr),
- inet6_fmt(&encod_unisrc.unicast_addr),
- inet6_fmt(&encod_grp.mcast_addr));
- }
-
- /* TODO: apply the group mask and do register_stop for all grp addresses */
- /* TODO: check for SourceAddress == 0 */
-
-
- mrtentry_ptr = find_route(&source, &group,
- MRTF_SG, DONT_CREATE);
- if (mrtentry_ptr == (mrtentry_t *) NULL)
- {
- return (FALSE);
- }
-
- /*
- * XXX: not in the spec: check if the PIM_REGISTER_STOP originator is
- * really the RP
- */
-
-
- if (check_mrtentry_rp(mrtentry_ptr, reg_src) == FALSE)
- {
- return (FALSE);
- }
-
- /* restart the Register-Suppression timer */
-
- SET_TIMER(mrtentry_ptr->rs_timer, (0.5 * pim_register_suppression_timeout)
- + (RANDOM() % (pim_register_suppression_timeout + 1)));
- /* Prune the register_vif from the outgoing list */
-
- IF_COPY(&mrtentry_ptr->pruned_oifs, &pruned_oifs);
- IF_SET(reg_vif_num, &pruned_oifs);
- change_interfaces(mrtentry_ptr, mrtentry_ptr->incoming,
- &mrtentry_ptr->joined_oifs, &pruned_oifs,
- &mrtentry_ptr->leaves,
- &mrtentry_ptr->asserted_oifs, 0);
- return (TRUE);
-}
-
-
-/* TODO: optional rate limiting is not implemented yet */
-/* Unicasts a REGISTER_STOP message to the DR */
-
-static int
-send_pim6_register_stop(reg_src, reg_dst, inner_grp, inner_src)
- struct sockaddr_in6 *reg_src,
- *reg_dst,
- *inner_grp,
- *inner_src;
-{
- char *buf;
- u_int8 *data_ptr;
-
- buf = pim6_send_buf + sizeof(struct pim);
- data_ptr = (u_int8 *) buf;
- PUT_EGADDR6(inner_grp->sin6_addr, SINGLE_GRP_MSK6LEN, 0, data_ptr);
- PUT_EUADDR6(inner_src->sin6_addr, data_ptr);
-
- send_pim6(pim6_send_buf, reg_src , reg_dst , PIM_REGISTER_STOP,
- data_ptr-(u_int8 *) buf);
- pim6dstat.out_pim6_register_stop++;
-
- return (TRUE);
-}
-
-/************************************************************************
- * PIM_JOIN_PRUNE
- ************************************************************************/
-int
-join_or_prune(mrtentry_ptr, upstream_router)
- mrtentry_t *mrtentry_ptr;
- pim_nbr_entry_t *upstream_router;
-{
- if_set entry_oifs;
- mrtentry_t *mrtentry_grp;
-
- if ((mrtentry_ptr == (mrtentry_t *) NULL))
- {
- IF_DEBUG(DEBUG_PIM_JOIN_PRUNE)
- log(LOG_DEBUG,0,"Join_or_prune : mrtentry_ptr is null");
- return (PIM_ACTION_NOTHING);
- }
- if( upstream_router == (pim_nbr_entry_t *) NULL)
- {
- IF_DEBUG(DEBUG_PIM_JOIN_PRUNE)
- log(LOG_DEBUG,0,"Join_or_prune : upstream_router is null");
- return (PIM_ACTION_NOTHING);
- }
-
- calc_oifs(mrtentry_ptr, &entry_oifs);
- if (mrtentry_ptr->flags & (MRTF_PMBR | MRTF_WC))
- {
- /* (*,*,RP) or (*,G) entry */
- /* The (*,*,RP) or (*,G) J/P messages are sent only toward the RP */
-
- if (upstream_router != mrtentry_ptr->upstream)
- return (PIM_ACTION_NOTHING);
-
- /* TODO: XXX: Can we have (*,*,RP) prune? */
-
- if (IF_ISEMPTY(&entry_oifs))
- {
- /* NULL oifs */
- if (!(uvifs[mrtentry_ptr->incoming].uv_flags & VIFF_DR))
- {
- /* I am not the DR for that subnet. */
- return (PIM_ACTION_PRUNE);
- }
- if (IF_ISSET(mrtentry_ptr->incoming, &mrtentry_ptr->leaves))
- /* I am the DR and have local leaves */
- return (PIM_ACTION_JOIN);
- /* Probably the last local member hast timeout */
- return (PIM_ACTION_PRUNE);
- }
- return (PIM_ACTION_JOIN);
- }
-
- if (mrtentry_ptr->flags & MRTF_SG)
- {
- /* (S,G) entry */
- /* TODO: check again */
- if (mrtentry_ptr->upstream == upstream_router)
- {
- if (!(mrtentry_ptr->flags & MRTF_RP))
- {
- /* Upstream router toward S */
- if (IF_ISEMPTY(&entry_oifs))
- {
- if (mrtentry_ptr->group->active_rp_grp != (rp_grp_entry_t *)NULL &&
- inet6_equal(&mrtentry_ptr->group->rpaddr,
- &my_cand_rp_address))
- {
- /*
- * (S,G) at the RP. Don't send Join/Prune (see the
- * end of Section 3.3.2)
- */
-
- return (PIM_ACTION_NOTHING);
- }
- return (PIM_ACTION_PRUNE);
- }
- else
- return (PIM_ACTION_JOIN);
- }
- else
- {
- /* Upstream router toward RP */
- if (IF_ISEMPTY(&entry_oifs))
- return (PIM_ACTION_PRUNE);
- }
- }
-
- /*
- * Looks like the case when the upstream router toward S is different
- * from the upstream router toward RP
- */
-
- if (mrtentry_ptr->group->active_rp_grp == (rp_grp_entry_t *) NULL)
- return (PIM_ACTION_NOTHING);
- mrtentry_grp = mrtentry_ptr->group->grp_route;
- if (mrtentry_grp == (mrtentry_t *) NULL)
- mrtentry_grp =
- mrtentry_ptr->group->active_rp_grp->rp->rpentry->mrtlink;
- if (mrtentry_grp == (mrtentry_t *) NULL)
- return (PIM_ACTION_NOTHING);
- if (mrtentry_grp->upstream != upstream_router)
- return (PIM_ACTION_NOTHING); /* XXX: shoudn't happen */
-
- if ((!(mrtentry_ptr->flags & MRTF_RP))
- && (mrtentry_ptr->flags & MRTF_SPT))
- {
- return (PIM_ACTION_PRUNE);
- }
- }
- return (PIM_ACTION_NOTHING);
-}
-
-/* TODO: too long, simplify it! */
-#define PIM6_JOIN_PRUNE_MINLEN (4 + PIM6_ENCODE_UNI_ADDR_LEN + 4)
-
-int
-receive_pim6_join_prune(src, dst, pim_message, datalen)
- struct sockaddr_in6 *src,
- *dst;
- 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 *data_ptr_start;
- u_int8 num_groups;
- u_int8 num_groups_tmp;
- int star_star_rp_found;
- u_int16 holdtime;
- u_int16 num_j_srcs;
- u_int16 num_j_srcs_tmp;
- u_int16 num_p_srcs;
- struct sockaddr_in6 source;
- struct sockaddr_in6 group;
- struct sockaddr_in6 target;
- struct in6_addr s_mask;
- struct in6_addr g_mask;
- u_int8 s_flags;
- u_int8 reserved;
- rpentry_t *rpentry_ptr;
- mrtentry_t *mrtentry_ptr;
- mrtentry_t *mrtentry_srcs;
- mrtentry_t *mrtentry_rp;
- grpentry_t *grpentry_ptr;
- u_int16 jp_value;
- pim_nbr_entry_t *upstream_router;
- int my_action;
- int ignore_group;
- rp_grp_entry_t *rp_grp_entry_ptr;
- u_int8 *data_ptr_group_j_start;
- u_int8 *data_ptr_group_p_start;
-
- 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];
- v->uv_in_pim6_join_prune++;
- if (uvifs[mifi].uv_flags &
- (VIFF_DOWN | VIFF_DISABLED | VIFF_NONBRS | MIFF_REGISTER))
- {
- return (FALSE); /* Shoudn't come on this interface */
- }
-
- /* sanity check for the minimum length */
- if (datalen < PIM6_JOIN_PRUNE_MINLEN) {
- log(LOG_NOTICE, 0,
- "receive_pim6_join_prune: Join/Prune message size(%u) is"
- " too short from %s on %s",
- datalen, inet6_fmt(&src->sin6_addr), v->uv_name);
- return(FALSE);
- }
- datalen -= PIM6_JOIN_PRUNE_MINLEN;
- 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);
-
- /* Sanity check for the message length through all the groups */
- num_groups_tmp = num_groups;
- data_ptr_start = data_ptr;
- while (num_groups_tmp--) {
- int srclen;
-
- /* group addr + #join + #src */
- if (datalen < PIM6_ENCODE_GRP_ADDR_LEN + sizeof(u_int32_t)) {
- log(LOG_NOTICE, 0,
- "receive_pim6_join_prune: Join/Prune message from %s on %s is"
- " too short to contain enough data",
- inet6_fmt(&src->sin6_addr), v->uv_name);
- return(FALSE);
- }
- datalen -= (PIM6_ENCODE_GRP_ADDR_LEN + sizeof(u_int32_t));
- data_ptr += PIM6_ENCODE_GRP_ADDR_LEN;
-
- /* joined source addresses and pruned source addresses */
- GET_HOSTSHORT(num_j_srcs, data_ptr);
- GET_HOSTSHORT(num_p_srcs, data_ptr);
- srclen = (num_j_srcs + num_p_srcs) * PIM6_ENCODE_SRC_ADDR_LEN;
- if (datalen < srclen) {
- log(LOG_NOTICE, 0,
- "receive_pim6_join_prune: Join/Prune message from %s on %s is"
- " too short to contain enough data",
- inet6_fmt(&src->sin6_addr), v->uv_name);
- return(FALSE);
- }
- datalen -= srclen;
- data_ptr += srclen;
- }
- data_ptr = data_ptr_start;
- num_groups_tmp = num_groups;
-
- if (!inet6_localif_address(&target, v) &&
- !IN6_IS_ADDR_UNSPECIFIED(&uni_target_addr.unicast_addr))
- {
-
- /* if I am not the targer of the join message */
- /*
- * Join/Prune suppression code. This either modifies the J/P timers
- * or triggers an overriding Join.
- */
- /*
- * Note that if we have (S,G) prune and (*,G) Join, we must send them
- * in the same message. We don't bother to modify both timers here.
- * The Join/Prune sending function will take care of that.
- */
-
- 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 */
- }
-
- if (inet6_equal(&group,&sockaddr6_d) &&
- (encod_src.masklen == STAR_STAR_RP_MSK6LEN))
- {
- /* (*,*,RP) Join suppression */
-
- 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);
- if ((s_flags & USADDR_RP_BIT) &&
- (s_flags & USADDR_WC_BIT))
- {
- /* This is the RP address. */
- rpentry_ptr = rp_find(&source);
- if (rpentry_ptr == (rpentry_t *) NULL)
- continue; /* Don't have such RP. Ignore */
- mrtentry_rp = rpentry_ptr->mrtlink;
- my_action = join_or_prune(mrtentry_rp,
- upstream_router);
- if (my_action != PIM_ACTION_JOIN)
- continue;
-
- /* Check the holdtime */
- /* TODO: XXX: TIMER implem. dependency! */
-
- if (mrtentry_rp->jp_timer > holdtime)
- continue;
- if ((mrtentry_rp->jp_timer == holdtime)
- && (inet6_greaterthan(src, &v->uv_linklocal->pa_addr)))
- continue;
-
- /*
- * Set the Join/Prune suppression timer for this
- * routing entry by increasing the current Join/Prune
- * timer.
- */
- jp_value = pim_join_prune_period +
- 0.5 * (RANDOM() % pim_join_prune_period);
- /* TODO: XXX: TIMER implem. dependency! */
-
- if (mrtentry_rp->jp_timer < jp_value)
- SET_TIMER(mrtentry_rp->jp_timer, jp_value);
- }
- } /* num_j_srcs */
-
- while (num_p_srcs--)
- {
- /*
- * TODO: XXX: Can we have (*,*,RP) prune message? Not in
- * the spec, but anyway, the code below can handle them:
- * either suppress the local (*,*,RP) prunes or override
- * the prunes by sending (*,*,RP) and/or (*,G) and/or
- * (S,G) Join.
- */
-
- 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);
- if ((s_flags & USADDR_RP_BIT) &&
- (s_flags & USADDR_WC_BIT))
- {
- /* This is the RP address. */
- rpentry_ptr = rp_find(&source);
- if (rpentry_ptr == (rpentry_t *) NULL)
- continue; /* Don't have such RP. Ignore */
- mrtentry_rp = rpentry_ptr->mrtlink;
- my_action = join_or_prune(mrtentry_rp,
- upstream_router);
- if (my_action == PIM_ACTION_PRUNE)
- {
- /* TODO: XXX: TIMER implem. dependency! */
- if ((mrtentry_rp->jp_timer < holdtime)
- || ((mrtentry_rp->jp_timer == holdtime)
- && (inet6_greaterthan(src, &v->uv_linklocal->pa_addr))))
- {
- /* Suppress the Prune */
- jp_value = pim_join_prune_period+
- 0.5 * (RANDOM() % pim_join_prune_period);
- if (mrtentry_rp->jp_timer < jp_value)
- SET_TIMER(mrtentry_rp->jp_timer, jp_value);
- }
- }
- else
- if (my_action == PIM_ACTION_JOIN)
- {
- /* Override the Prune by scheduling a Join */
- jp_value = (RANDOM() % 11) / (10 * PIM_RANDOM_DELAY_JOIN_TIMEOUT);
- /* TODO: XXX: TIMER implem. dependency! */
- if (mrtentry_rp->jp_timer > jp_value)
- SET_TIMER(mrtentry_rp->jp_timer, jp_value);
- }
- /*
- * Check all (*,G) and (S,G) matching to this RP. If
- * my_action == JOIN, then send a Join and override
- * the (*,*,RP) Prune.
- */
- for (grpentry_ptr =
- rpentry_ptr->cand_rp->rp_grp_next->grplink;
- grpentry_ptr != (grpentry_t *) NULL;
- grpentry_ptr = grpentry_ptr->rpnext)
- {
- my_action = join_or_prune(grpentry_ptr->grp_route,
- upstream_router);
- if (my_action == PIM_ACTION_JOIN)
- {
-
- jp_value = (RANDOM() % 11) / (10 * PIM_RANDOM_DELAY_JOIN_TIMEOUT);
- /* TODO: XXX: TIMER implem. dependency! */
- if (grpentry_ptr->grp_route->jp_timer >
- jp_value)
- SET_TIMER(grpentry_ptr->grp_route->jp_timer, jp_value);
- }
- for (mrtentry_srcs = grpentry_ptr->mrtlink;
- mrtentry_srcs != (mrtentry_t *) NULL;
- mrtentry_srcs = mrtentry_srcs->grpnext)
- {
- my_action = join_or_prune(mrtentry_srcs,
- upstream_router);
- if (my_action == PIM_ACTION_JOIN)
- {
-
- jp_value = (RANDOM() % 11) / (10 * PIM_RANDOM_DELAY_JOIN_TIMEOUT);
- /* TODO: XXX: TIMER implem. dependency! */
- if (mrtentry_srcs->jp_timer > jp_value)
- SET_TIMER(mrtentry_srcs->jp_timer, jp_value);
- }
- } /* For all (S,G) */
- } /* For all (*,G) */
- }
- } /* num_p_srcs */
- continue; /* This was (*,*,RP) suppression */
- }
-
- /* (*,G) or (S,G) suppression */
- /*
- * TODO: XXX: currently, accumulated groups (i.e. group_masklen <
- * group_address_lengt) are not implemented. Just need to create
- * a loop and apply the procedure below for all groups matching
- * the prefix.
- */
-
- 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);
-
- if ((s_flags & USADDR_RP_BIT) && (s_flags & USADDR_WC_BIT))
- {
- /* (*,G) JOIN_REQUEST (toward the RP) */
- mrtentry_ptr = find_route(&sockaddr6_any , &group, MRTF_WC,
- DONT_CREATE);
- my_action = join_or_prune(mrtentry_ptr, upstream_router);
- if (my_action != PIM_ACTION_JOIN)
- continue;
- /* (*,G) Join suppresion */
- if (!inet6_equal(&source,&mrtentry_ptr->group->active_rp_grp->rp->rpentry->address))
- continue; /* The RP address doesn't match.
- * Ignore. */
-
- /* Check the holdtime */
- /* TODO: XXX: TIMER implem. dependency! */
- if (mrtentry_ptr->jp_timer > holdtime)
- continue;
- if ((mrtentry_ptr->jp_timer == holdtime)
- && (inet6_greaterthan(src, &v->uv_linklocal->pa_addr)))
- continue;
- jp_value = pim_join_prune_period +
- 0.5 * (RANDOM() % pim_join_prune_period);
- if (mrtentry_ptr->jp_timer < jp_value)
- SET_TIMER(mrtentry_ptr->jp_timer, jp_value);
- continue;
- } /* End of (*,G) Join suppression */
-
- /* (S,G) Join suppresion */
- mrtentry_ptr = find_route(&source, &group, MRTF_SG,
- DONT_CREATE);
- my_action = join_or_prune(mrtentry_ptr, upstream_router);
- if (my_action != PIM_ACTION_JOIN)
- continue;
-
- /* Check the holdtime */
- /* TODO: XXX: TIMER implem. dependency! */
- if (mrtentry_ptr->jp_timer > holdtime)
- continue;
- if ((mrtentry_ptr->jp_timer == holdtime)
- && (inet6_greaterthan(src, &v->uv_linklocal->pa_addr)))
- continue;
- jp_value = pim_join_prune_period +
- 0.5 * (RANDOM() % pim_join_prune_period);
- if (mrtentry_ptr->jp_timer < jp_value)
- SET_TIMER(mrtentry_ptr->jp_timer, jp_value);
- continue;
- }
-
- /* Prunes suppression */
- 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 (encod_src.masklen >
- (sizeof(struct in6_addr) << 3))
- continue;
-
-
- if (!inet6_valid_host(&source))
- continue;
- s_flags = encod_src.flags;
- MASKLEN_TO_MASK6(encod_src.masklen, s_mask);
- if ((s_flags & USADDR_RP_BIT) && (s_flags & USADDR_WC_BIT))
- {
- /* (*,G) prune suppression */
- rpentry_ptr = rp_match(&source);
- if ((rpentry_ptr == (rpentry_t *) NULL)
- || (!inet6_equal(&rpentry_ptr->address , &source)))
- continue; /* No such RP or it is different.
- * Ignore */
- mrtentry_ptr = find_route(&sockaddr6_any, &group, MRTF_WC,
- DONT_CREATE);
- my_action = join_or_prune(mrtentry_ptr, upstream_router);
- if (my_action == PIM_ACTION_PRUNE)
- {
- /* TODO: XXX: TIMER implem. dependency! */
- if ((mrtentry_ptr->jp_timer < holdtime)
- || ((mrtentry_ptr->jp_timer == holdtime)
- && (inet6_greaterthan(src, &v->uv_linklocal->pa_addr))))
- {
- /* Suppress the Prune */
- jp_value = pim_join_prune_period +
- 0.5 * (RANDOM() % pim_join_prune_period);
- if (mrtentry_ptr->jp_timer < jp_value)
- SET_TIMER(mrtentry_ptr->jp_timer, jp_value);
- }
- }
- else
- if (my_action == PIM_ACTION_JOIN)
- {
- /* Override the Prune by scheduling a Join */
- jp_value = (RANDOM() % 11) / (10 * PIM_RANDOM_DELAY_JOIN_TIMEOUT);
- /* TODO: XXX: TIMER implem. dependency! */
- if (mrtentry_ptr->jp_timer > jp_value)
- SET_TIMER(mrtentry_ptr->jp_timer, jp_value);
- }
-
- /*
- * Check all (S,G) entries for this group. If my_action
- * == JOIN, then send the Join and override the (*,G)
- * Prune.
- */
- for (mrtentry_srcs = mrtentry_ptr->group->mrtlink;
- mrtentry_srcs != (mrtentry_t *) NULL;
- mrtentry_srcs = mrtentry_srcs->grpnext)
- {
- my_action = join_or_prune(mrtentry_srcs,
- upstream_router);
- if (my_action == PIM_ACTION_JOIN)
- {
- jp_value = (RANDOM() % 11) / (10 * PIM_RANDOM_DELAY_JOIN_TIMEOUT);
- /* TODO: XXX: TIMER implem. dependency! */
- if (mrtentry_ptr->jp_timer > jp_value)
- SET_TIMER(mrtentry_ptr->jp_timer, jp_value);
- }
- } /* For all (S,G) */
- continue; /* End of (*,G) prune suppression */
- }
-
- /* (S,G) prune suppression */
- mrtentry_ptr = find_route(&source, &group, MRTF_SG,
- DONT_CREATE);
- my_action = join_or_prune(mrtentry_ptr, upstream_router);
- if (my_action == PIM_ACTION_PRUNE)
- {
- /* Suppress the (S,G) Prune */
- /* TODO: XXX: TIMER implem. dependency! */
- if ((mrtentry_ptr->jp_timer < holdtime)
- || ((mrtentry_ptr->jp_timer == holdtime)
- && (inet6_greaterthan(src, &v->uv_linklocal->pa_addr))))
- {
- jp_value = pim_join_prune_period +
- 0.5 * (RANDOM() % pim_join_prune_period);
- if (mrtentry_ptr->jp_timer < jp_value)
- SET_TIMER(mrtentry_ptr->jp_timer, jp_value);
- }
- }
- else
- if (my_action == PIM_ACTION_JOIN)
- {
- /* Override the Prune by scheduling a Join */
- jp_value = (RANDOM() % 11) / (10 * PIM_RANDOM_DELAY_JOIN_TIMEOUT);
- /* TODO: XXX: TIMER implem. dependency! */
- if (mrtentry_ptr->jp_timer > jp_value)
- SET_TIMER(mrtentry_ptr->jp_timer, jp_value);
- }
- } /* while (num_p_srcs--) */
- } /* while (num_groups--) */
- return (TRUE);
- } /* End of Join/Prune suppression code */
-
- /* I am the target of this join, so process the message */
-
- /*
- * The spec says that if there is (*,G) Join, it has priority over old
- * existing ~(S,G) prunes in the routing table. However, if the (*,G)
- * Join and the ~(S,G) prune are in the same message, ~(S,G) has the
- * priority. The spec doesn't say it, but I think the same is true for
- * (*,*,RP) and ~(S,G) prunes.
- *
- * The code below do: (1) Check the whole message for (*,*,RP) Joins. (1.1)
- * If found, clean all pruned_oifs for all (*,G) and all (S,G) for each
- * RP in the list, but do not update the kernel cache. Then go back to
- * the beginning of the message and start processing for each group: (2)
- * Check for Prunes. If no prunes, process the Joins. (3) If there are
- * Prunes: (3.1) Scan the Join part for existing (*,G) Join. (3.1.1) If
- * there is (*,G) Join, clear join interface from the pruned_oifs for all
- * (S,G), but DO NOT flush the change to the kernel (by using
- * change_interfaces() for example) (3.2) After the pruned_oifs are
- * eventually cleared in (3.1.1), process the Prune part of the message
- * normally (setting the prune_oifs and flashing the changes to the
- * (kernel). (3.3) After the Prune part is processed, process the Join
- * part normally (by applying any changes to the kernel) (4) If there
- * were (*,*,RP) Join/Prune, process them.
- *
- * If the Join/Prune list is too long, it may result in long processing
- * overhead. The idea above is not to place any wrong info in the kernel,
- * because it may result in short-time existing traffic forwarding on
- * wrong interface. Hopefully, in the future will find a better way to
- * implement it.
- */
-
- IF_DEBUG(DEBUG_PIM_JOIN_PRUNE)
- log(LOG_DEBUG,0,"I'm the target of the JOIN/PRUNE message");
-
- num_groups_tmp = num_groups;
- data_ptr_start = data_ptr;
- star_star_rp_found = FALSE; /* Indicating whether we have (*,*,RP) join */
-
- IF_DEBUG(DEBUG_PIM_JOIN_PRUNE)
- log(LOG_DEBUG,0,"Number of groups to process : %d",num_groups_tmp);
-
- while (num_groups_tmp--)
- {
- /* Search for (*,*,RP) Join */
- GET_EGADDR6(&encod_group, data_ptr);
- GET_HOSTSHORT(num_j_srcs, data_ptr);
- GET_HOSTSHORT(num_p_srcs, data_ptr);
- group.sin6_addr = encod_group.mcast_addr;
- group.sin6_scope_id = inet6_uvif2scopeid(&group, v);
-
- IF_DEBUG(DEBUG_PIM_JOIN_PRUNE)
- {
- log(LOG_DEBUG, 0,
- "Group to process : %s",inet6_fmt(&encod_group.mcast_addr));
- log(LOG_DEBUG, 0,
- "Number of join : %d",num_j_srcs );
- log(LOG_DEBUG, 0,
- "Number of prune : %d",num_p_srcs );
- }
-
- if (!(inet6_equal(&group,&sockaddr6_d))
- || (encod_src.masklen != STAR_STAR_RP_MSK6LEN))
- {
- /* This is not (*,*,RP). Jump to the next group. */
- data_ptr += (num_j_srcs + num_p_srcs) * sizeof(pim6_encod_src_addr_t);
- IF_DEBUG(DEBUG_PIM_JOIN_PRUNE)
- {
- log(LOG_DEBUG, 0,
- "I'm looking for the (*,*,RP) entry , skip to next entry");
- }
- continue;
- }
-
- /*
- * (*,*,RP) found. For each RP and each (*,G) and each (S,G) clear
- * the pruned oif, but do not update the kernel.
- */
-
- star_star_rp_found = TRUE;
- while (num_j_srcs--)
- {
- GET_ESADDR6(&encod_src, data_ptr);
- source.sin6_addr = encod_src.src_addr;
- rpentry_ptr = rp_find(&source);
-
- if (rpentry_ptr == (rpentry_t *) NULL)
- continue;
- for (rp_grp_entry_ptr = rpentry_ptr->cand_rp->rp_grp_next;
- rp_grp_entry_ptr != (rp_grp_entry_t *) NULL;
- rp_grp_entry_ptr = rp_grp_entry_ptr->rp_grp_next)
- {
- for (grpentry_ptr = rp_grp_entry_ptr->grplink;
- grpentry_ptr != (grpentry_t *) NULL;
- grpentry_ptr = grpentry_ptr->rpnext)
- {
- if (grpentry_ptr->grp_route != (mrtentry_t *) NULL)
- IF_CLR(mifi, &grpentry_ptr->grp_route->pruned_oifs);
- for (mrtentry_ptr = grpentry_ptr->mrtlink;
- mrtentry_ptr != (mrtentry_t *) NULL;
- mrtentry_ptr = mrtentry_ptr->grpnext)
- IF_CLR(mifi, &mrtentry_ptr->pruned_oifs);
- }
- }
- }
- data_ptr += (num_p_srcs) * sizeof(pim6_encod_src_addr_t);
- }
-
- /*
- * Start processing the groups. If this is (*,*,RP), skip it, but process
- * it at the end.don't forget to reinit data_ptr!
- */
-
- data_ptr = data_ptr_start;
- num_groups_tmp = num_groups;
-
- while (num_groups_tmp--)
- {
- GET_EGADDR6(&encod_group, data_ptr);
- GET_HOSTSHORT(num_j_srcs, data_ptr);
- GET_HOSTSHORT(num_p_srcs, data_ptr);
- group.sin6_addr = encod_group.mcast_addr;
- group.sin6_scope_id = inet6_uvif2scopeid(&group, v);
-
- IF_DEBUG(DEBUG_PIM_JOIN_PRUNE)
- {
- log(LOG_DEBUG,0,"Group to process : %s",inet6_fmt(&encod_group.mcast_addr));
- log(LOG_DEBUG,0,"Number of join : %d",num_j_srcs );
- log(LOG_DEBUG,0,"Number of prune : %d",num_p_srcs );
- }
-
- 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 one */
- }
-
-
- if (inet6_equal(&group, &sockaddr6_d)
- && (encod_group.masklen == STAR_STAR_RP_MSK6LEN))
- {
- /* This is (*,*,RP). Jump to the next group. */
- IF_DEBUG(DEBUG_PIM_JOIN_PRUNE) {
- log(LOG_DEBUG, 0, "This is (*,*,RP). Jump to next.");
- }
- data_ptr += (num_j_srcs + num_p_srcs) * sizeof(pim6_encod_src_addr_t);
- continue;
- }
-
- rpentry_ptr = rp_match(&group);
- if (rpentry_ptr == (rpentry_t *) NULL)
- continue;
-
- IF_DEBUG(DEBUG_PIM_JOIN_PRUNE)
- log(LOG_DEBUG,0,"The rp for this JOIN/PRUNE is %s",inet6_fmt(&rpentry_ptr->address.sin6_addr));
-
- data_ptr_group_j_start = data_ptr;
- data_ptr_group_p_start = data_ptr + num_j_srcs * sizeof(pim6_encod_src_addr_t);
-
- /*
- * Scan the Join part for (*,G) Join and then clear the particular
- * interface from pruned_oifs for all (S,G). If the RP address in the
- * Join message is different from the local match, ignore the whole
- * group.
- */
-
- num_j_srcs_tmp = num_j_srcs;
- ignore_group = FALSE;
-
- while (num_j_srcs_tmp--)
- {
- GET_ESADDR6(&encod_src, data_ptr);
- source.sin6_addr=encod_src.src_addr;
- source.sin6_scope_id = inet6_uvif2scopeid(&source,v);
-
- if ((encod_src.flags & USADDR_RP_BIT)
- && (encod_src.flags & USADDR_WC_BIT))
- {
- /*
- * This is the RP address, i.e. (*,G) Join. Check if the
- * RP-mapping is consistent and if "yes", then Reset the
- * pruned_oifs for all (S,G) entries.
- */
-
- if(!inet6_equal(&rpentry_ptr->address, &source))
- {
- ignore_group = TRUE;
- IF_DEBUG(DEBUG_PIM_JOIN_PRUNE)
- log(LOG_DEBUG,0,"And I'm not the RP for this address");
- break;
- }
-
- mrtentry_ptr = find_route(&sockaddr6_any, &group,
- MRTF_WC, DONT_CREATE);
-
- if (mrtentry_ptr != (mrtentry_t *) NULL)
- {
- for (mrtentry_srcs = mrtentry_ptr->group->mrtlink;
- mrtentry_srcs != (mrtentry_t *) NULL;
- mrtentry_srcs = mrtentry_srcs->grpnext)
- IF_CLR(mifi, &mrtentry_srcs->pruned_oifs);
- }
- break;
- }
- }
-
- if (ignore_group == TRUE)
- continue;
-
- data_ptr = data_ptr_group_p_start;
-
- /* Process the Prune part first */
-
- 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;
- if (!(s_flags & (USADDR_WC_BIT | USADDR_RP_BIT)))
- {
- /* (S,G) prune sent toward S */
- mrtentry_ptr = find_route(&source, &group, MRTF_SG,
- DONT_CREATE);
- if (mrtentry_ptr == (mrtentry_t *) NULL)
- continue; /* I don't have (S,G) to prune. Ignore. */
- /*
- * If the link is point-to-point, timeout the oif
- * immediately, otherwise decrease the timer to allow other
- * downstream routers to override the prune.
- */
- /* TODO: XXX: increase the entry timer? */
-
- if (v->uv_flags & VIFF_POINT_TO_POINT)
- {
- FIRE_TIMER(mrtentry_ptr->vif_timers[mifi]);
- }
- else
- {
- /* TODO: XXX: TIMER implem. dependency! */
- if (mrtentry_ptr->vif_timers[mifi] >
- mrtentry_ptr->vif_deletion_delay[mifi])
- SET_TIMER(mrtentry_ptr->vif_timers[mifi],
- mrtentry_ptr->vif_deletion_delay[mifi]);
- }
- IF_TIMER_NOT_SET(mrtentry_ptr->vif_timers[mifi])
- {
- IF_CLR(mifi, &mrtentry_ptr->joined_oifs);
- IF_SET(mifi, &mrtentry_ptr->pruned_oifs);
- change_interfaces(mrtentry_ptr,
- mrtentry_ptr->incoming,
- &mrtentry_ptr->joined_oifs,
- &mrtentry_ptr->pruned_oifs,
- &mrtentry_ptr->leaves,
- &mrtentry_ptr->asserted_oifs, 0);
- }
- continue;
- }
-
- if ((s_flags & USADDR_RP_BIT)
- && (!(s_flags & USADDR_WC_BIT)))
- {
- /* ~(S,G)RPbit prune sent toward the RP */
- mrtentry_ptr = find_route(&source, &group, MRTF_SG,
- DONT_CREATE);
- if (mrtentry_ptr != (mrtentry_t *) NULL)
- {
- SET_TIMER(mrtentry_ptr->timer, holdtime);
- if (v->uv_flags & VIFF_POINT_TO_POINT)
- {
- FIRE_TIMER(mrtentry_ptr->vif_timers[mifi]);
- }
- else
- {
- /* TODO: XXX: TIMER implem. dependency! */
- if (mrtentry_ptr->vif_timers[mifi] >
- mrtentry_ptr->vif_deletion_delay[mifi])
- SET_TIMER(mrtentry_ptr->vif_timers[mifi],
- mrtentry_ptr->vif_deletion_delay[mifi]);
- }
- IF_TIMER_NOT_SET(mrtentry_ptr->vif_timers[mifi])
- {
- IF_CLR(mifi, &mrtentry_ptr->joined_oifs);
- IF_SET(mifi, &mrtentry_ptr->pruned_oifs);
- change_interfaces(mrtentry_ptr,
- mrtentry_ptr->incoming,
- &mrtentry_ptr->joined_oifs,
- &mrtentry_ptr->pruned_oifs,
- &mrtentry_ptr->leaves,
- &mrtentry_ptr->asserted_oifs, 0);
- }
- continue;
- }
- /* There is no (S,G) entry. Check for (*,G) or (*,*,RP) */
- mrtentry_ptr = find_route(NULL, &group,
- MRTF_WC | MRTF_PMBR,
- DONT_CREATE);
- if (mrtentry_ptr != (mrtentry_t *) NULL)
- {
- mrtentry_ptr = find_route(&source, &group,
- MRTF_SG | MRTF_RP,
- CREATE);
- if (mrtentry_ptr == (mrtentry_t *) NULL)
- continue;
- mrtentry_ptr->flags &= ~MRTF_NEW;
- RESET_TIMER(mrtentry_ptr->vif_timers[mifi]);
-
- /*
- * TODO: XXX: The spec doens't say what value to use for
- * the entry time. Use the J/P holdtime.
- */
-
- SET_TIMER(mrtentry_ptr->timer, holdtime);
-
- /*
- * TODO: XXX: The spec says to delete the oif. However,
- * its timer only should be lowered, so the prune can be
- * overwritten on multiaccess LAN. Spec BUG.
- */
-
- IF_CLR(mifi, &mrtentry_ptr->joined_oifs);
- IF_SET(mifi, &mrtentry_ptr->pruned_oifs);
- change_interfaces(mrtentry_ptr,
- mrtentry_ptr->incoming,
- &mrtentry_ptr->joined_oifs,
- &mrtentry_ptr->pruned_oifs,
- &mrtentry_ptr->leaves,
- &mrtentry_ptr->asserted_oifs, 0);
- }
- continue;
- }
-
- if ((s_flags & USADDR_RP_BIT) && (s_flags & USADDR_WC_BIT))
- {
- /* (*,G) Prune */
- mrtentry_ptr = find_route(NULL, &group,
- MRTF_WC | MRTF_PMBR,
- DONT_CREATE);
- if (mrtentry_ptr != (mrtentry_t *) NULL)
- {
- if (mrtentry_ptr->flags & MRTF_WC)
- {
- /*
- * TODO: XXX: Should check the whole Prune list in
- * advance for (*,G) prune and if the RP address does
- * not match the local RP-map, then ignore the whole
- * group, not only this particular (*,G) prune.
- */
- if (!inet6_equal(&mrtentry_ptr->group->active_rp_grp->rp->rpentry->address, &source ))
- continue; /* The RP address doesn't match. */
- if (v->uv_flags & VIFF_POINT_TO_POINT)
- {
- FIRE_TIMER(mrtentry_ptr->vif_timers[mifi]);
- }
- else
- {
- /* TODO: XXX: TIMER implem. dependency! */
- if (mrtentry_ptr->vif_timers[mifi] >
- mrtentry_ptr->vif_deletion_delay[mifi])
- SET_TIMER(mrtentry_ptr->vif_timers[mifi],
- mrtentry_ptr->vif_deletion_delay[mifi]);
- }
- IF_TIMER_NOT_SET(mrtentry_ptr->vif_timers[mifi])
- {
- IF_CLR(mifi, &mrtentry_ptr->joined_oifs);
- IF_SET(mifi, &mrtentry_ptr->pruned_oifs);
- change_interfaces(mrtentry_ptr,
- mrtentry_ptr->incoming,
- &mrtentry_ptr->joined_oifs,
- &mrtentry_ptr->pruned_oifs,
- &mrtentry_ptr->leaves,
- &mrtentry_ptr->asserted_oifs, 0);
- }
- continue;
- }
- /* No (*,G) entry, but found (*,*,RP). Create (*,G) */
- if (!inet6_equal(&mrtentry_ptr->source->address, &source))
- continue; /* The RP address doesn't match. */
- mrtentry_ptr = find_route(NULL, &group,
- MRTF_WC, CREATE);
- if (mrtentry_ptr == (mrtentry_t *) NULL)
- continue;
- mrtentry_ptr->flags &= ~MRTF_NEW;
- RESET_TIMER(mrtentry_ptr->vif_timers[mifi]);
-
- /*
- * TODO: XXX: should only lower the oif timer, so it can
- * be overwritten on multiaccess LAN. Spec bug.
- */
-
- IF_CLR(mifi, &mrtentry_ptr->joined_oifs);
- IF_SET(mifi, &mrtentry_ptr->pruned_oifs);
- change_interfaces(mrtentry_ptr,
- mrtentry_ptr->incoming,
- &mrtentry_ptr->joined_oifs,
- &mrtentry_ptr->pruned_oifs,
- &mrtentry_ptr->leaves,
- &mrtentry_ptr->asserted_oifs, 0);
- } /* (*,G) or (*,*,RP) found */
- } /* (*,G) prune */
- } /* while(num_p_srcs--) */
-
- /* End of (S,G) and (*,G) Prune handling */
-
- /* Jump back to the Join part and process it */
- data_ptr = data_ptr_group_j_start;
- 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;
- s_flags = encod_src.flags;
- MASKLEN_TO_MASK6(encod_src.masklen, s_mask);
- if ((s_flags & USADDR_WC_BIT)
- && (s_flags & USADDR_RP_BIT))
- {
- /* (*,G) Join toward RP */
- /*
- * It has been checked already that this RP address is the
- * same as the local RP-maping.
- */
- mrtentry_ptr = find_route(NULL, &group, MRTF_WC,
- CREATE);
- if (mrtentry_ptr == (mrtentry_t *) NULL)
- continue;
- IF_SET(mifi, &mrtentry_ptr->joined_oifs);
- IF_CLR(mifi, &mrtentry_ptr->pruned_oifs);
- IF_CLR(mifi, &mrtentry_ptr->asserted_oifs);
- /* TODO: XXX: TIMER implem. dependency! */
- if (mrtentry_ptr->vif_timers[mifi] < holdtime)
- {
- SET_TIMER(mrtentry_ptr->vif_timers[mifi], holdtime);
- mrtentry_ptr->vif_deletion_delay[mifi] = holdtime / 3;
- }
- if (mrtentry_ptr->timer < holdtime)
- SET_TIMER(mrtentry_ptr->timer, holdtime);
- mrtentry_ptr->flags &= ~MRTF_NEW;
- change_interfaces(mrtentry_ptr,
- mrtentry_ptr->incoming,
- &mrtentry_ptr->joined_oifs,
- &mrtentry_ptr->pruned_oifs,
- &mrtentry_ptr->leaves,
- &mrtentry_ptr->asserted_oifs, 0);
- /*
- * Need to update the (S,G) entries, because of the previous
- * cleaning of the pruned_oifs. The reason is that if the
- * oifs for (*,G) weren't changed, the (S,G) entries won't be
- * updated by change_interfaces()
- */
-
- for (mrtentry_srcs = mrtentry_ptr->group->mrtlink;
- mrtentry_srcs != (mrtentry_t *) NULL;
- mrtentry_srcs = mrtentry_srcs->grpnext)
- change_interfaces(mrtentry_srcs,
- mrtentry_srcs->incoming,
- &mrtentry_srcs->joined_oifs,
- &mrtentry_srcs->pruned_oifs,
- &mrtentry_srcs->leaves,
- &mrtentry_srcs->asserted_oifs, 0);
- continue;
- }
-
- if (!(s_flags & (USADDR_WC_BIT | USADDR_RP_BIT)))
- {
- /* (S,G) Join toward S */
- if (mifi == get_iif(&source))
- continue; /* Ignore this (S,G) Join */
- mrtentry_ptr = find_route(&source, &group, MRTF_SG, CREATE);
- if (mrtentry_ptr == (mrtentry_t *) NULL)
- continue;
- IF_SET(mifi, &mrtentry_ptr->joined_oifs);
- IF_CLR(mifi, &mrtentry_ptr->pruned_oifs);
- IF_CLR(mifi, &mrtentry_ptr->asserted_oifs);
- /* TODO: XXX: TIMER implem. dependency! */
- if (mrtentry_ptr->vif_timers[mifi] < holdtime)
- {
- SET_TIMER(mrtentry_ptr->vif_timers[mifi], holdtime);
- mrtentry_ptr->vif_deletion_delay[mifi] = holdtime / 3;
- }
- if (mrtentry_ptr->timer < holdtime)
- SET_TIMER(mrtentry_ptr->timer, holdtime);
- /*
- * TODO: if this is a new entry, send immediately the Join
- * message toward S. The Join/Prune timer for new entries is
- * 0, but it does not means the message will be sent
- * immediately.
- */
- mrtentry_ptr->flags &= ~MRTF_NEW;
- /*
- * Note that we must create (S,G) without the RPbit set. If
- * we already had such entry, change_interfaces() will reset
- * the RPbit propertly.
- */
- change_interfaces(mrtentry_ptr,
- mrtentry_ptr->source->incoming,
- &mrtentry_ptr->joined_oifs,
- &mrtentry_ptr->pruned_oifs,
- &mrtentry_ptr->leaves,
- &mrtentry_ptr->asserted_oifs, 0);
- continue;
- }
- } /* while(num_j_srcs--) */
- } /* for all groups */
-
- /* Now process the (*,*,RP) Join/Prune */
-
- if (star_star_rp_found == TRUE)
- return (TRUE);
- data_ptr = data_ptr_start;
- while (num_groups--)
- {
- /*
- * The conservative approach is to scan again the whole message, just
- * in case if we have more than one (*,*,RP) requests.
- */
- GET_EGADDR6(&encod_group, data_ptr);
- GET_HOSTSHORT(num_j_srcs, data_ptr);
- GET_HOSTSHORT(num_p_srcs, data_ptr);
-
- group.sin6_addr = encod_group.mcast_addr;
- group.sin6_scope_id = inet6_uvif2scopeid(&group, v);
-
- if (!inet6_equal(&group,&sockaddr6_d)
- || (encod_group.masklen != STAR_STAR_RP_MSK6LEN))
- {
- /* This is not (*,*,RP). Jump to the next group. */
- data_ptr +=
- (num_j_srcs + num_p_srcs) * sizeof(pim6_encod_src_addr_t);
- continue;
- }
- /* (*,*,RP) found */
- while (num_j_srcs--)
- {
- /* TODO: XXX: check that the iif is different from the Join oifs */
- 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;
- MASKLEN_TO_MASK6(encod_src.masklen, s_mask);
- mrtentry_ptr = find_route(&source, NULL, MRTF_PMBR,
- CREATE);
- if (mrtentry_ptr == (mrtentry_t *) NULL)
- continue;
- IF_SET(mifi, &mrtentry_ptr->joined_oifs);
- IF_CLR(mifi, &mrtentry_ptr->pruned_oifs);
- IF_CLR(mifi, &mrtentry_ptr->asserted_oifs);
- /* TODO: XXX: TIMER implem. dependency! */
- if (mrtentry_ptr->vif_timers[mifi] < holdtime)
- {
- SET_TIMER(mrtentry_ptr->vif_timers[mifi], holdtime);
- mrtentry_ptr->vif_deletion_delay[mifi] = holdtime / 3;
- }
- if (mrtentry_ptr->timer < holdtime)
- SET_TIMER(mrtentry_ptr->timer, holdtime);
- mrtentry_ptr->flags &= ~MRTF_NEW;
- change_interfaces(mrtentry_ptr,
- mrtentry_ptr->incoming,
- &mrtentry_ptr->joined_oifs,
- &mrtentry_ptr->pruned_oifs,
- &mrtentry_ptr->leaves,
- &mrtentry_ptr->asserted_oifs, 0);
-
- /*
- * Need to update the (S,G) and (*,G) entries, because of the
- * previous cleaning of the pruned_oifs. The reason is that if
- * the oifs for (*,*,RP) weren't changed, the (*,G) and (S,G)
- * entries won't be updated by change_interfaces()
- */
-
- for (rp_grp_entry_ptr = mrtentry_ptr->source->cand_rp->rp_grp_next;
- rp_grp_entry_ptr != (rp_grp_entry_t *) NULL;
- rp_grp_entry_ptr = rp_grp_entry_ptr->rp_grp_next)
- for (grpentry_ptr = rp_grp_entry_ptr->grplink;
- grpentry_ptr != (grpentry_t *) NULL;
- grpentry_ptr = grpentry_ptr->rpnext)
- {
- /* Update the (*,G) entry */
- change_interfaces(grpentry_ptr->grp_route,
- grpentry_ptr->grp_route->incoming,
- &grpentry_ptr->grp_route->joined_oifs,
- &grpentry_ptr->grp_route->pruned_oifs,
- &grpentry_ptr->grp_route->leaves,
- &grpentry_ptr->grp_route->asserted_oifs, 0);
- /* Update the (S,G) entries */
- for (mrtentry_srcs = grpentry_ptr->mrtlink;
- mrtentry_srcs != (mrtentry_t *) NULL;
- mrtentry_srcs = mrtentry_srcs->grpnext)
- change_interfaces(mrtentry_srcs,
- mrtentry_srcs->incoming,
- &mrtentry_srcs->joined_oifs,
- &mrtentry_srcs->pruned_oifs,
- &mrtentry_srcs->leaves,
- &mrtentry_srcs->asserted_oifs, 0);
- }
- continue;
- }
-
- while (num_p_srcs--)
- {
- /* TODO: XXX: can we have (*,*,RP) Prune? */
- 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;
- MASKLEN_TO_MASK6(encod_src.masklen, s_mask);
- mrtentry_ptr = find_route(&source, NULL , MRTF_PMBR,
- DONT_CREATE);
- if (mrtentry_ptr == (mrtentry_t *) NULL)
- continue;
- /*
- * If the link is point-to-point, timeout the oif immediately,
- * otherwise decrease the timer to allow other downstream routers
- * to override the prune.
- */
- /* TODO: XXX: increase the entry timer? */
- if (v->uv_flags & VIFF_POINT_TO_POINT)
- {
- FIRE_TIMER(mrtentry_ptr->vif_timers[mifi]);
- }
- else
- {
- /* TODO: XXX: TIMER implem. dependency! */
- if (mrtentry_ptr->vif_timers[mifi] >
- mrtentry_ptr->vif_deletion_delay[mifi])
- SET_TIMER(mrtentry_ptr->vif_timers[mifi],
- mrtentry_ptr->vif_deletion_delay[mifi]);
- }
- IF_TIMER_NOT_SET(mrtentry_ptr->vif_timers[mifi])
- {
- IF_CLR(mifi, &mrtentry_ptr->joined_oifs);
- IF_SET(mifi, &mrtentry_ptr->pruned_oifs);
- IF_SET(mifi, &mrtentry_ptr->asserted_oifs);
- change_interfaces(mrtentry_ptr,
- mrtentry_ptr->incoming,
- &mrtentry_ptr->joined_oifs,
- &mrtentry_ptr->pruned_oifs,
- &mrtentry_ptr->leaves,
- &mrtentry_ptr->asserted_oifs, 0);
- }
-
- }
- } /* For all groups processing (*,*,R) */
-
- return (TRUE);
-}
-
-
-/*
- * TODO: NOT USED, probably buggy, but may need it in the future.
- */
-/*
- * TODO: create two functions: periodic which timeout the timers and
- * non-periodic which only check but don't timeout the timers.
- */
-/*
- * Create and send Join/Prune messages per interface. Only the entries which
- * have the Join/Prune timer expired are included. In the special case when
- * we have ~(S,G)RPbit Prune entry, we must include any (*,G) or (*,*,RP)
- * Currently the whole table is scanned. In the future will have all routing
- * entries linked in a chain with the corresponding upstream pim_nbr_entry.
- *
- * If pim_nbr is not NULL, then send to only this particular PIM neighbor,
- */
-int
-send_periodic_pim6_join_prune(mifi, pim_nbr, holdtime)
- mifi_t mifi;
- pim_nbr_entry_t *pim_nbr;
- u_int16 holdtime;
-{
- grpentry_t *grpentry_ptr;
- mrtentry_t *mrtentry_ptr;
- rpentry_t *rpentry_ptr;
- struct sockaddr_in6 src_addr;
- struct uvif *v;
- pim_nbr_entry_t *pim_nbr_ptr;
- cand_rp_t *cand_rp_ptr;
-
- /*
- * Walk through all routing entries. The iif must match to include the
- * entry. Check first the (*,G) entry and then all associated (S,G). At
- * the end of the message will add any (*,*,RP) entries. TODO: check
- * other PIM-SM implementations and decide the more appropriate place to
- * put the (*,*,RP) entries: in the beginning of the message or at the
- * end.
- */
-
- v = &uvifs[mifi];
-
- /* Check the (*,G) and (S,G) entries */
- for (grpentry_ptr = grplist; grpentry_ptr != (grpentry_t *) NULL;
- grpentry_ptr = grpentry_ptr->next)
- {
- mrtentry_ptr = grpentry_ptr->grp_route;
- /* TODO: XXX: TIMER implem. dependency! */
- if ((mrtentry_ptr != (mrtentry_t *) NULL)
- && (mrtentry_ptr->incoming == mifi)
- && (mrtentry_ptr->jp_timer <= timer_interval))
- {
-
- /* If join/prune to a particular neighbor only was specified */
- if ((pim_nbr != (pim_nbr_entry_t *) NULL)
- && (mrtentry_ptr->upstream != pim_nbr))
- continue;
-
- /* TODO: XXX: The J/P suppression timer is not in the spec! */
- if (!IF_ISEMPTY(&mrtentry_ptr->joined_oifs) ||
- (v->uv_flags & VIFF_DR))
- {
- add_jp_entry(mrtentry_ptr->upstream, holdtime,
- &grpentry_ptr->group,
- SINGLE_GRP_MSK6LEN,
- &grpentry_ptr->rpaddr,
- SINGLE_SRC_MSK6LEN, 0, PIM_ACTION_JOIN);
- }
- /* TODO: XXX: TIMER implem. dependency! */
- if (IF_ISEMPTY(&mrtentry_ptr->joined_oifs)
- && (!(v->uv_flags & VIFF_DR))
- && (mrtentry_ptr->jp_timer <= timer_interval))
- {
- add_jp_entry(mrtentry_ptr->upstream, holdtime,
- &grpentry_ptr->group, SINGLE_GRP_MSK6LEN,
- &grpentry_ptr->rpaddr,
- SINGLE_SRC_MSK6LEN, 0, PIM_ACTION_PRUNE);
- }
- }
-
- /* Check the (S,G) entries */
- for (mrtentry_ptr = grpentry_ptr->mrtlink;
- mrtentry_ptr != (mrtentry_t *) NULL;
- mrtentry_ptr = mrtentry_ptr->grpnext)
- {
-
- /* If join/prune to a particular neighbor only was specified */
- if ((pim_nbr != (pim_nbr_entry_t *) NULL)
- && (mrtentry_ptr->upstream != pim_nbr))
- continue;
-
- if (mrtentry_ptr->flags & MRTF_RP)
- {
- /* RPbit set */
-
- src_addr = mrtentry_ptr->source->address;
- if (IF_ISEMPTY(&mrtentry_ptr->joined_oifs)
- || ((find_vif_direct_local(&src_addr) != NO_VIF)
- && grpentry_ptr->grp_route != (mrtentry_t *) NULL))
- /* TODO: XXX: TIMER implem. dependency! */
- if ((grpentry_ptr->grp_route->incoming == mifi)
- && (grpentry_ptr->grp_route->jp_timer
- <= timer_interval))
- /* S is directly connected. Send toward RP */
- add_jp_entry(grpentry_ptr->grp_route->upstream,
- holdtime,
- &grpentry_ptr->group, SINGLE_GRP_MSK6LEN,
- &src_addr, SINGLE_SRC_MSK6LEN,
- MRTF_RP, PIM_ACTION_PRUNE);
- }
- else
- {
- /* RPbit cleared */
- if (IF_ISEMPTY(&mrtentry_ptr->joined_oifs))
- {
- /* TODO: XXX: TIMER implem. dependency! */
- if ((mrtentry_ptr->incoming == mifi)
- && (mrtentry_ptr->jp_timer <= timer_interval))
- add_jp_entry(mrtentry_ptr->upstream, holdtime,
- &grpentry_ptr->group, SINGLE_GRP_MSK6LEN,
- &mrtentry_ptr->source->address,
- SINGLE_SRC_MSK6LEN, 0, PIM_ACTION_PRUNE);
- }
- else
- {
- /* TODO: XXX: TIMER implem. dependency! */
- if ((mrtentry_ptr->incoming == mifi)
- && (mrtentry_ptr->jp_timer <= timer_interval))
- add_jp_entry(mrtentry_ptr->upstream, holdtime,
- &grpentry_ptr->group, SINGLE_GRP_MSK6LEN,
- &mrtentry_ptr->source->address,
- SINGLE_SRC_MSK6LEN, 0, PIM_ACTION_JOIN);
- }
- /* TODO: XXX: TIMER implem. dependency! */
- if ((mrtentry_ptr->flags & MRTF_SPT)
- && (grpentry_ptr->grp_route != (mrtentry_t *) NULL)
- && (mrtentry_ptr->incoming !=
- grpentry_ptr->grp_route->incoming)
- && (grpentry_ptr->grp_route->incoming == mifi)
- && (grpentry_ptr->grp_route->jp_timer
- <= timer_interval))
- add_jp_entry(grpentry_ptr->grp_route->upstream, holdtime,
- &grpentry_ptr->group, SINGLE_GRP_MSK6LEN,
- &mrtentry_ptr->source->address,
- SINGLE_SRC_MSK6LEN, MRTF_RP,
- PIM_ACTION_PRUNE);
- }
- }
- }
-
- /* Check the (*,*,RP) entries */
- for (cand_rp_ptr = cand_rp_list; cand_rp_ptr != (cand_rp_t *) NULL;
- cand_rp_ptr = cand_rp_ptr->next)
- {
- rpentry_ptr = cand_rp_ptr->rpentry;
-
- /* If join/prune to a particular neighbor only was specified */
- if ((pim_nbr != (pim_nbr_entry_t *) NULL)
- && (rpentry_ptr->upstream != pim_nbr))
- continue;
-
-
- /* TODO: XXX: TIMER implem. dependency! */
- if ((rpentry_ptr->mrtlink != (mrtentry_t *) NULL)
- && (rpentry_ptr->incoming == mifi)
- && (rpentry_ptr->mrtlink->jp_timer <= timer_interval))
- {
- add_jp_entry(rpentry_ptr->upstream, holdtime,
- &sockaddr6_d, STAR_STAR_RP_MSK6LEN,
- &rpentry_ptr->address,
- SINGLE_SRC_MSK6LEN, MRTF_RP | MRTF_WC,
- PIM_ACTION_JOIN);
- }
- }
-
- /* Send all pending Join/Prune messages */
- for (pim_nbr_ptr = v->uv_pim_neighbors;
- pim_nbr_ptr != (pim_nbr_entry_t *) NULL;
- pim_nbr_ptr = pim_nbr->next)
- {
-
- /* If join/prune to a particular neighbor only was specified */
- if ((pim_nbr != (pim_nbr_entry_t *) NULL)
- && (pim_nbr_ptr != pim_nbr))
- continue;
-
- pack_and_send_jp6_message(pim_nbr_ptr);
- }
-
- return (TRUE);
-}
-
-
-int
-add_jp_entry(pim_nbr, holdtime, group, grp_msklen, source, src_msklen,
- addr_flags, join_prune)
- pim_nbr_entry_t *pim_nbr;
- u_int16 holdtime;
- struct sockaddr_in6 *group;
- u_int8 grp_msklen;
- struct sockaddr_in6 *source;
- u_int8 src_msklen;
- u_int16 addr_flags;
- u_int8 join_prune;
-{
- build_jp_message_t *bjpm;
- u_int8 *data_ptr;
- u_int8 flags = 0;
- int rp_flag;
-
-
- bjpm = pim_nbr->build_jp_message;
-
- if (bjpm != (build_jp_message_t *) NULL)
- {
- if ((bjpm->jp_message_size + bjpm->join_list_size +
- bjpm->prune_list_size + bjpm->rp_list_join_size +
- bjpm->rp_list_prune_size >= MAX_JP_MESSAGE_SIZE)
- || (bjpm->join_list_size >= MAX_JOIN_LIST_SIZE)
- || (bjpm->prune_list_size >= MAX_PRUNE_LIST_SIZE)
- || (bjpm->rp_list_join_size >= MAX_JOIN_LIST_SIZE)
- || (bjpm->rp_list_prune_size >= MAX_PRUNE_LIST_SIZE))
- {
- /*
- * TODO: XXX: BUG: If the list is getting too large, must be
- * careful with the fragmentation.
- */
- pack_and_send_jp6_message(pim_nbr);
- bjpm = pim_nbr->build_jp_message; /* The buffer will be freed */
- }
- }
-
- if (bjpm != (build_jp_message_t *) NULL)
- {
- if ((!inet6_equal(&bjpm->curr_group, group)
- || (bjpm->curr_group_msklen != grp_msklen)
- || (bjpm->holdtime != holdtime)))
- {
- pack_jp6_message(pim_nbr);
- }
- }
-
- if (bjpm == (build_jp_message_t *) NULL)
- {
- bjpm = get_jp6_working_buff();
- pim_nbr->build_jp_message = bjpm;
- data_ptr = bjpm->jp_message;
- PUT_EUADDR6(pim_nbr->address.sin6_addr, data_ptr);
- PUT_BYTE(0, data_ptr); /* Reserved */
- bjpm->num_groups_ptr = data_ptr++; /* The pointer for numgroups */
- *(bjpm->num_groups_ptr) = 0; /* Zero groups */
- PUT_HOSTSHORT(holdtime, data_ptr);
- bjpm->holdtime = holdtime;
- bjpm->jp_message_size = data_ptr - bjpm->jp_message;
- }
-
- /* TODO: move somewhere else, only when it is a new group */
- bjpm->curr_group = *group;
- bjpm->curr_group_msklen = grp_msklen;
-
- if (inet6_equal(group, &sockaddr6_d) &&
- (grp_msklen == STAR_STAR_RP_MSK6LEN))
- rp_flag = TRUE;
- else
- rp_flag = FALSE;
-
- switch (join_prune)
- {
- case PIM_ACTION_JOIN:
- if (rp_flag == TRUE)
- data_ptr = bjpm->rp_list_join + bjpm->rp_list_join_size;
- else
- data_ptr = bjpm->join_list + bjpm->join_list_size;
- break;
- case PIM_ACTION_PRUNE:
- if (rp_flag == TRUE)
- data_ptr = bjpm->rp_list_join + bjpm->rp_list_join_size;
- else
- data_ptr = bjpm->prune_list + bjpm->prune_list_size;
- break;
- default:
- return (FALSE);
- }
-
- flags |= USADDR_S_BIT; /* Mandatory for PIMv2 */
- if (addr_flags & MRTF_RP)
- flags |= USADDR_RP_BIT;
- if (addr_flags & MRTF_WC)
- flags |= USADDR_WC_BIT;
- PUT_ESADDR6(source->sin6_addr, src_msklen, flags, data_ptr);
-
- switch (join_prune)
- {
- case PIM_ACTION_JOIN:
- if (rp_flag == TRUE)
- {
- bjpm->rp_list_join_size = data_ptr - bjpm->rp_list_join;
- bjpm->rp_list_join_number++;
- }
- else
- {
- bjpm->join_list_size = data_ptr - bjpm->join_list;
- bjpm->join_addr_number++;
- }
- break;
- case PIM_ACTION_PRUNE:
- if (rp_flag == TRUE)
- {
- bjpm->rp_list_prune_size = data_ptr - bjpm->rp_list_prune;
- bjpm->rp_list_prune_number++;
- }
- else
- {
- bjpm->prune_list_size = data_ptr - bjpm->prune_list;
- bjpm->prune_addr_number++;
- }
- break;
- default:
- return (FALSE);
- }
-
- return (TRUE);
-}
-
-
-/* TODO: check again the size of the buffers */
-
-static build_jp_message_t *
-get_jp6_working_buff()
-{
- build_jp_message_t *bjpm_ptr;
-
- if (build_jp_message_pool_counter == 0)
- {
- bjpm_ptr = (build_jp_message_t *) malloc(sizeof(build_jp_message_t));
- bjpm_ptr->next = (build_jp_message_t *) NULL;
- bjpm_ptr->jp_message =
- (u_int8 *) malloc(MAX_JP_MESSAGE_SIZE +
- sizeof(pim_jp_encod_grp_t) +
- 2 * sizeof(pim6_encod_src_addr_t));
- bjpm_ptr->jp_message_size = 0;
- bjpm_ptr->join_list_size = 0;
- bjpm_ptr->join_addr_number = 0;
- bjpm_ptr->join_list = (u_int8 *) malloc(MAX_JOIN_LIST_SIZE +
- sizeof(pim6_encod_src_addr_t));
- bjpm_ptr->prune_list_size = 0;
- bjpm_ptr->prune_addr_number = 0;
- bjpm_ptr->prune_list = (u_int8 *) malloc(MAX_PRUNE_LIST_SIZE +
- sizeof(pim6_encod_src_addr_t));
- bjpm_ptr->rp_list_join_size = 0;
- bjpm_ptr->rp_list_join_number = 0;
- bjpm_ptr->rp_list_join = (u_int8 *) malloc(MAX_JOIN_LIST_SIZE +
- sizeof(pim6_encod_src_addr_t));
- bjpm_ptr->rp_list_prune_size = 0;
- bjpm_ptr->rp_list_prune_number = 0;
- bjpm_ptr->rp_list_prune = (u_int8 *) malloc(MAX_PRUNE_LIST_SIZE +
- sizeof(pim6_encod_src_addr_t));
- bjpm_ptr->curr_group = sockaddr6_any;
- bjpm_ptr->curr_group_msklen = 0;
- bjpm_ptr->holdtime = 0;
- return bjpm_ptr;
- }
- else
- {
- bjpm_ptr = build_jp_message_pool;
- build_jp_message_pool = build_jp_message_pool->next;
- build_jp_message_pool_counter--;
- bjpm_ptr->jp_message_size = 0;
- bjpm_ptr->join_list_size = 0;
- bjpm_ptr->join_addr_number = 0;
- bjpm_ptr->prune_list_size = 0;
- bjpm_ptr->prune_addr_number = 0;
- bjpm_ptr->curr_group = sockaddr6_any;
- bjpm_ptr->curr_group_msklen = 0;
- return (bjpm_ptr);
- }
-}
-
-
-static void
-return_jp6_working_buff(pim_nbr)
- pim_nbr_entry_t *pim_nbr;
-{
- build_jp_message_t *bjpm_ptr = pim_nbr->build_jp_message;
-
- if (bjpm_ptr == (build_jp_message_t *) NULL)
- return;
- /* Don't waste memory by keeping too many free buffers */
- /* TODO: check/modify the definitions for POOL_NUMBER and size */
- if (build_jp_message_pool_counter >= MAX_JP_MESSAGE_POOL_NUMBER)
- {
- free((void *) bjpm_ptr->jp_message);
- free((void *) bjpm_ptr->join_list);
- free((void *) bjpm_ptr->prune_list);
- free((void *) bjpm_ptr->rp_list_join);
- free((void *) bjpm_ptr->rp_list_prune);
- free((void *) bjpm_ptr);
- }
- else
- {
- bjpm_ptr->next = build_jp_message_pool;
- build_jp_message_pool = bjpm_ptr;
- build_jp_message_pool_counter++;
- }
- pim_nbr->build_jp_message = (build_jp_message_t *) NULL;
-}
-
-
-/*
- * TODO: XXX: Currently, the (*,*,RP) stuff goes at the end of the Join/Prune
- * message. However, this particular implementation of PIM processes the
- * Join/Prune messages faster if (*,*,RP) is at the beginning. Modify some of
- * the functions below such that the outgoing messages place (*,*,RP) at the
- * beginning, not at the end.
- */
-
-static void
-pack_jp6_message(pim_nbr)
- pim_nbr_entry_t *pim_nbr;
-{
- build_jp_message_t *bjpm;
- u_int8 *data_ptr;
-
- bjpm = pim_nbr->build_jp_message;
- if ((bjpm == (build_jp_message_t *) NULL)
- || (inet6_equal(&bjpm->curr_group,&sockaddr6_any)))
- return;
- data_ptr = bjpm->jp_message + bjpm->jp_message_size;
- PUT_EGADDR6(bjpm->curr_group.sin6_addr, bjpm->curr_group_msklen, 0, data_ptr);
- PUT_HOSTSHORT(bjpm->join_addr_number, data_ptr);
- PUT_HOSTSHORT(bjpm->prune_addr_number, data_ptr);
- bcopy(bjpm->join_list, data_ptr, bjpm->join_list_size);
- data_ptr += bjpm->join_list_size;
- bcopy(bjpm->prune_list, data_ptr, bjpm->prune_list_size);
- data_ptr += bjpm->prune_list_size;
- bjpm->jp_message_size = (data_ptr - bjpm->jp_message);
- bjpm->join_list_size = 0;
- bjpm->join_addr_number = 0;
-#if 0 /* isn't this necessary? */
- bjpm->rp_list_join_size = 0;
- bjpm->rp_list_join_number = 0;
-#endif
- bjpm->prune_list_size = 0;
- bjpm->prune_addr_number = 0;
-#if 0 /* isn't this necessary? */
- bjpm->rp_list_prune_size = 0;
- bjpm->rp_list_prune_number = 0;
-#endif
- (*bjpm->num_groups_ptr)++;
- bjpm->curr_group = sockaddr6_any;
- bjpm->curr_group_msklen = 0;
- if (*bjpm->num_groups_ptr == ((u_int8) ~ 0 - 1))
- {
- if (bjpm->rp_list_join_number + bjpm->rp_list_prune_number)
- {
- /* Add the (*,*,RP) at the end */
- data_ptr = bjpm->jp_message + bjpm->jp_message_size;
- PUT_EGADDR6(sockaddr6_d.sin6_addr, STAR_STAR_RP_MSK6LEN, 0, data_ptr);
- PUT_HOSTSHORT(bjpm->rp_list_join_number, data_ptr);
- PUT_HOSTSHORT(bjpm->rp_list_prune_number, data_ptr);
- bcopy(bjpm->rp_list_join, data_ptr, bjpm->rp_list_join_size);
- data_ptr += bjpm->rp_list_join_size;
- bcopy(bjpm->rp_list_prune, data_ptr, bjpm->rp_list_prune_size);
- data_ptr += bjpm->rp_list_prune_size;
- bjpm->jp_message_size = (data_ptr - bjpm->jp_message);
- bjpm->rp_list_join_size = 0;
- bjpm->rp_list_join_number = 0;
- bjpm->rp_list_prune_size = 0;
- bjpm->rp_list_prune_number = 0;
- (*bjpm->num_groups_ptr)++;
- }
- send_jp6_message(pim_nbr);
- }
-}
-
-void
-pack_and_send_jp6_message(pim_nbr)
- pim_nbr_entry_t *pim_nbr;
-{
- u_int8 *data_ptr;
- build_jp_message_t *bjpm;
-
-
- if ((pim_nbr == (pim_nbr_entry_t *) NULL)
- || ((bjpm = pim_nbr->build_jp_message) == (build_jp_message_t *) NULL))
- {
- return;
- }
- pack_jp6_message(pim_nbr);
-
-
- if (bjpm->rp_list_join_number + bjpm->rp_list_prune_number)
- {
- /* Add the (*,*,RP) at the end */
- data_ptr = bjpm->jp_message + bjpm->jp_message_size;
-
- PUT_EGADDR6(sockaddr6_d.sin6_addr, STAR_STAR_RP_MSK6LEN, 0, data_ptr);
- PUT_HOSTSHORT(bjpm->rp_list_join_number, data_ptr);
- PUT_HOSTSHORT(bjpm->rp_list_prune_number, data_ptr);
- bcopy(bjpm->rp_list_join, data_ptr, bjpm->rp_list_join_size);
- data_ptr += bjpm->rp_list_join_size;
- bcopy(bjpm->rp_list_prune, data_ptr, bjpm->rp_list_prune_size);
- data_ptr += bjpm->rp_list_prune_size;
- bjpm->jp_message_size = (data_ptr - bjpm->jp_message);
- bjpm->rp_list_join_size = 0;
- bjpm->rp_list_join_number = 0;
- bjpm->rp_list_prune_size = 0;
- bjpm->rp_list_prune_number = 0;
- (*bjpm->num_groups_ptr)++;
- }
- send_jp6_message(pim_nbr);
-}
-
-static void
-send_jp6_message(pim_nbr)
- pim_nbr_entry_t *pim_nbr;
-{
- u_int16 datalen;
- mifi_t mifi;
-
- datalen = pim_nbr->build_jp_message->jp_message_size;
- mifi = pim_nbr->vifi;
- bcopy(pim_nbr->build_jp_message->jp_message,
- pim6_send_buf+sizeof(struct pim), datalen);
-
- send_pim6(pim6_send_buf, &uvifs[mifi].uv_linklocal->pa_addr,
- &allpim6routers_group , PIM_JOIN_PRUNE, datalen);
- uvifs[mifi].uv_out_pim6_join_prune++;
- return_jp6_working_buff(pim_nbr);
-}
-
-/************************************************************************
- * PIM_ASSERT
- ************************************************************************/
-int
-receive_pim6_assert(src, dst, pim_message, datalen)
- struct sockaddr_in6 *src,
- *dst;
- 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,
- *mrtentry_ptr2;
- u_int8 *data_ptr;
- struct uvif *v;
- u_int32 assert_preference;
- u_int32 assert_metric;
- u_int32 assert_rptbit;
- u_int32 local_metric;
- u_int32 local_preference;
- u_int8 local_rptbit;
- u_int8 local_wins;
- pim_nbr_entry_t *original_upstream_router;
-
-
- 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];
- v->uv_in_pim6_assert++;
- if (uvifs[mifi].uv_flags &
- (VIFF_DOWN | VIFF_DISABLED | VIFF_NONBRS | MIFF_REGISTER))
- 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);
- assert_rptbit = assert_preference & PIM_ASSERT_RPT_BIT;
-
- 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);
-
- /* Find the longest "active" entry, i.e. the one with a kernel mirror */
- if (assert_rptbit)
- {
- mrtentry_ptr = find_route(NULL, &group,
- MRTF_WC | MRTF_PMBR, DONT_CREATE);
- if (mrtentry_ptr != (mrtentry_t *) NULL)
- if (!(mrtentry_ptr->flags & MRTF_KERNEL_CACHE))
- if (mrtentry_ptr->flags & MRTF_WC)
- {
- mrtentry_ptr =
- mrtentry_ptr->group->active_rp_grp->rp->rpentry->mrtlink;
- }
- }
- else
- {
- mrtentry_ptr = find_route(&source, &group,
- MRTF_SG | MRTF_WC | MRTF_PMBR, DONT_CREATE);
- if ((mrtentry_ptr != (mrtentry_t *) NULL))
- if (!(mrtentry_ptr->flags & MRTF_KERNEL_CACHE))
- {
- if (mrtentry_ptr->flags & MRTF_SG)
- {
- mrtentry_ptr2 = mrtentry_ptr->group->grp_route;
- if ((mrtentry_ptr2 != (mrtentry_t *) NULL)
- && (mrtentry_ptr2->flags & MRTF_KERNEL_CACHE))
- mrtentry_ptr = mrtentry_ptr2;
- else
- mrtentry_ptr = mrtentry_ptr->group->active_rp_grp->rp->rpentry->mrtlink;
- }
- else
- if (mrtentry_ptr->flags & MRTF_WC)
- mrtentry_ptr = mrtentry_ptr->group->active_rp_grp->rp->rpentry->mrtlink;
- }
- }
- if ((mrtentry_ptr == (mrtentry_t *) NULL)
- || (!(mrtentry_ptr->flags & MRTF_KERNEL_CACHE)))
- /* No routing entry or not "active" entry. Ignore the assert */
- return (FALSE);
-
- /* Prepare the local preference and metric */
- if ((mrtentry_ptr->flags & MRTF_PMBR)
- || ((mrtentry_ptr->flags & MRTF_SG)
- && (!(mrtentry_ptr->flags & MRTF_RP))))
- {
- /* Either (S,G) (toward S) or (*,*,RP). */
- /* TODO: XXX: get the info from mrtentry, or source or from kernel ? */
- /*
- * local_metric = mrtentry_ptr->source->metric; local_preference =
- * mrtentry_ptr->source->preference;
- */
- local_metric = mrtentry_ptr->metric;
- local_preference = mrtentry_ptr->preference;
- }
- else
- {
- /*
- * Should be (*,G) or (S,G)RPbit entry. Get what we need from the RP
- * info.
- */
- /* TODO: get the info from mrtentry, RP-entry or kernel? */
- /*
- * local_metric =
- * mrtentry_ptr->group->active_rp_grp->rp->rpentry->metric;
- * local_preference =
- * mrtentry_ptr->group->active_rp_grp->rp->rpentry->preference;
- */
-
- local_metric = mrtentry_ptr->metric;
- local_preference = mrtentry_ptr->preference;
- }
-
- local_rptbit = (mrtentry_ptr->flags & MRTF_RP);
- if (local_rptbit)
- /* Make the RPT bit the most significant one */
- local_preference |= PIM_ASSERT_RPT_BIT;
-
-
- if (IF_ISSET(mifi, &mrtentry_ptr->oifs))
- {
- /* The ASSERT has arrived on oif */
-
- /*
- * TODO: XXX: here the processing order is different from the spec.
- * The spec requires first eventually to create a routing entry (see
- * 3.5.2.1(1) and then compare the metrics. Here we compare first the
- * metrics with the existing longest match entry and if we lose then
- * create a new entry and compare again. This saves us the
- * unnecessary creating of a routing entry if we anyway are going to
- * lose: for example the local (*,*,RP) vs the remote (*,*,RP) or
- * (*,G)
- */
-
- local_wins = compare_metrics(local_preference, local_metric,
- &v->uv_linklocal->pa_addr, assert_preference,
- assert_metric, src);
-
- if (local_wins == TRUE)
- {
- /* TODO: verify the parameters */
- send_pim6_assert(&source, &group, mifi, mrtentry_ptr);
- return (TRUE);
- }
-
- /* Create a "better" routing entry and try again */
-
- if ((assert_rptbit) && (mrtentry_ptr->flags & MRTF_PMBR))
- {
- /* The matching entry was (*,*,RP). Create (*,G) */
- mrtentry_ptr2 = find_route(NULL, &group, MRTF_WC, CREATE);
- }
- else
- if ((!assert_rptbit) &&
- (mrtentry_ptr->flags & (MRTF_WC | MRTF_PMBR)))
- {
- /* create (S,G) */
- mrtentry_ptr2 = find_route(&source, &group, MRTF_SG, CREATE);
- }
- else
- {
- /* We have no chance to win. Give up and prune the oif */
- mrtentry_ptr2 = (mrtentry_t *) NULL;
- }
-
- if (mrtentry_ptr2 != (mrtentry_t *) NULL)
- {
- mrtentry_ptr2->flags &= ~MRTF_NEW;
-
- /*
- * TODO: XXX: The spec doesn't say what entry timer value to use
- * when the routing entry is created because of asserts.
- */
-
- SET_TIMER(mrtentry_ptr2->timer, pim_data_timeout);
- if (mrtentry_ptr2->flags & MRTF_RP)
- {
- /*
- * Either (*,G) or (S,G)RPbit entry. Get what we need from
- * the RP info.
- */
- /* TODO: where to get the metric+preference from? */
- /*
- * local_metric =
- * mrtentry_ptr->group->active_rp_grp->rp->rpentry->metric;
- * local_preference =
- * mrtentry_ptr->group->active_rp_grp->rp->rpentry->preference
- * ;
- */
- local_metric = mrtentry_ptr->metric;
- local_preference = mrtentry_ptr->preference;
- local_preference |= PIM_ASSERT_RPT_BIT;
- }
- else
- {
- /* (S,G) toward the source */
- /* TODO: where to get the metric from ? */
- /*
- * local_metric = mrtentry_ptr->source->metric;
- * local_preference = mrtentry_ptr->source->preference;
- */
- local_metric = mrtentry_ptr->metric;
- local_preference = mrtentry_ptr->preference;
- }
-
- local_wins = compare_metrics(local_preference, local_metric,
- &v->uv_linklocal->pa_addr, assert_preference,
- assert_metric, src);
-
- if (local_wins == TRUE)
- {
- /* TODO: verify the parameters */
- send_pim6_assert(&source, &group, mifi, mrtentry_ptr);
- return (TRUE);
- }
- /* We lost, but have created the entry which has to be pruned */
- mrtentry_ptr = mrtentry_ptr2;
- }
-
- /* Have to remove that outgoing vifi from mrtentry_ptr */
- IF_SET(mifi, &mrtentry_ptr->asserted_oifs);
- /* TODO: XXX: TIMER implem. dependency! */
- if (mrtentry_ptr->timer < pim_assert_timeout)
- SET_TIMER(mrtentry_ptr->timer, pim_assert_timeout);
- /*
- * TODO: XXX: check that the timer of all affected routing entries
- * has been restarted.
- */
- change_interfaces(mrtentry_ptr,
- mrtentry_ptr->incoming,
- &mrtentry_ptr->joined_oifs,
- &mrtentry_ptr->pruned_oifs,
- &mrtentry_ptr->leaves,
- &mrtentry_ptr->asserted_oifs, 0);
- return (FALSE); /* Doesn't matter the return value */
- } /* End of assert received on oif */
-
-
- if (mrtentry_ptr->incoming == mifi)
- {
- /* Assert received on iif */
- if (assert_rptbit)
- {
- if (!(mrtentry_ptr->flags & MRTF_RP))
- return (TRUE); /* The locally used upstream router will win
- * the assert, so don't change it. */
- }
-
- /*
- * TODO: where to get the local metric and preference from? system
- * call or mrtentry is fine?
- */
- local_metric = mrtentry_ptr->metric;
- local_preference = mrtentry_ptr->preference;
- if (mrtentry_ptr->flags & MRTF_RP)
- local_preference |= PIM_ASSERT_RPT_BIT;
-
- local_wins = compare_metrics(local_preference, local_metric,
- &mrtentry_ptr->upstream->address,
- assert_preference, assert_metric, src);
-
- if (local_wins == TRUE)
- return (TRUE); /* return whatever */
-
- /* The upstream must be changed to the winner */
- mrtentry_ptr->preference = assert_preference;
- mrtentry_ptr->metric = assert_metric;
- mrtentry_ptr->upstream = find_pim6_nbr(src);
-
- /* Check if the upstream router is different from the original one */
- if (mrtentry_ptr->flags & MRTF_PMBR)
- original_upstream_router = mrtentry_ptr->source->upstream;
- else
- if (mrtentry_ptr->flags & MRTF_RP)
- original_upstream_router =
- mrtentry_ptr->group->active_rp_grp->rp->rpentry->upstream;
- else
- original_upstream_router = mrtentry_ptr->source->upstream;
- if (mrtentry_ptr->upstream != original_upstream_router)
- {
- mrtentry_ptr->flags |= MRTF_ASSERTED;
- SET_TIMER(mrtentry_ptr->assert_timer, pim_assert_timeout);
- }
- else
- mrtentry_ptr->flags &= ~MRTF_ASSERTED;
- }
-
- 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;
- srcentry_t *srcentry_ptr;
-
- /* Don't send assert if the outgoing interface a tunnel or register vif */
- if (uvifs[mifi].uv_flags & (MIFF_REGISTER | VIFF_TUNNEL))
- return (FALSE);
-
- 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);
-
- /*
- * TODO: XXX: where to get the metric from: srcentry_ptr or mrtentry_ptr
- * or from the kernel?
- */
-
- if (mrtentry_ptr->flags & MRTF_PMBR)
- {
- /* (*,*,RP) */
- srcentry_ptr = mrtentry_ptr->source;
- /*
- * TODO: set_incoming(srcentry_ptr, PIM_IIF_RP);
- */
- }
- else
- if (mrtentry_ptr->flags & MRTF_RP)
- {
- /* (*,G) or (S,G)RPbit (iif toward RP) */
- srcentry_ptr = mrtentry_ptr->group->active_rp_grp->rp->rpentry;
- /*
- * TODO: set_incoming(srcentry_ptr, PIM_IIF_RP);
- */
- }
- else
- {
- /* (S,G) toward S */
- srcentry_ptr = mrtentry_ptr->source;
- /*
- * TODO: set_incoming(srcentry_ptr, PIM_IIF_SOURCE);
- */
- }
-
- /*
- * TODO: check again! local_metric = srcentry_ptr->metric;
- * local_preference = srcentry_ptr->preference;
- */
- local_metric = mrtentry_ptr->metric;
- local_preference = mrtentry_ptr->preference;
-
- if (mrtentry_ptr->flags & MRTF_RP)
- local_preference |= PIM_ASSERT_RPT_BIT;
- PUT_HOSTLONG(local_preference, data_ptr);
- PUT_HOSTLONG(local_metric, data_ptr);
-
- send_pim6(pim6_send_buf, &uvifs[mifi].uv_linklocal->pa_addr,
- &allpim6routers_group, PIM_ASSERT,
- data_ptr - data_start_ptr);
- uvifs[mifi].uv_out_pim6_assert++;
-
- 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 threatment 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_BOOTSTRAP
- ************************************************************************/
-#define PIM6_BOOTSTRAP_MINLEN (PIM_MINLEN + PIM6_ENCODE_UNI_ADDR_LEN)
-
-int
-receive_pim6_bootstrap(src, dst, pim_message, datalen)
- struct sockaddr_in6 *src,
- *dst;
- char *pim_message;
- int datalen;
-{
- u_int8 *data_ptr;
- u_int8 *max_data_ptr;
- u_int16 new_bsr_fragment_tag;
- u_int8 new_bsr_hash_masklen;
- u_int8 new_bsr_priority;
- pim6_encod_uni_addr_t new_bsr_uni_addr;
- struct sockaddr_in6 new_bsr_address;
- struct rpfctl rpfc;
- pim_nbr_entry_t *n,
- *rpf_neighbor;
- struct sockaddr_in6 neighbor_addr;
- mifi_t mifi,
- incoming = NO_VIF;
- int min_datalen;
- pim6_encod_grp_addr_t curr_group_addr;
- pim6_encod_uni_addr_t curr_rp_addr;
- u_int8 curr_rp_count;
- u_int8 curr_frag_rp_count;
- u_int16 reserved_short;
- u_int16 curr_rp_holdtime;
- u_int8 curr_rp_priority;
- u_int8 reserved_byte;
- struct in6_addr curr_group_mask;
- grp_mask_t *grp_mask_ptr;
- grp_mask_t *grp_mask_next;
- rp_grp_entry_t *grp_rp_entry_ptr;
- rp_grp_entry_t *grp_rp_entry_next;
- struct sockaddr_in6 prefix_h,
- prefix_h2,
- group_,
- rpp_;
- int i;
- struct uvif *v;
-
-
- if ((mifi=find_vif_direct(src)) == NO_VIF)
- {
- /*
- * Either a local vif or somehow received PIM_BOOTSTRAP from
- * non-directly connected router. Ignore it.
- */
- if (local_address(src) == NO_VIF)
- log(LOG_INFO, 0,
- "Ignoring PIM_BOOTSTRAP from non-neighbor router %s",
- inet6_fmt(&src->sin6_addr));
- return (FALSE);
- }
-
- /* sanity check for the minimum length */
- if (datalen < PIM6_BOOTSTRAP_MINLEN) {
- log(LOG_NOTICE, 0,
- "receive_pim6_bootstrap: Bootstrap message size(%u) is"
- " too short from %s",
- datalen, inet6_fmt(&src->sin6_addr));
- return(FALSE);
- }
-
- v = &uvifs[mifi];
- v->uv_in_pim6_bootsrap++;
- data_ptr = (u_int8 *) (pim_message + sizeof(struct pim));
-
- /* Parse the PIM_BOOTSTRAP message */
- GET_HOSTSHORT(new_bsr_fragment_tag, data_ptr);
- GET_BYTE(new_bsr_hash_masklen, data_ptr);
- GET_BYTE(new_bsr_priority, data_ptr);
- GET_EUADDR6(&new_bsr_uni_addr, data_ptr);
-
- /*
- * BSR address must be a global unicast address.
- * [draft-ietf-pim-ipv6-01.txt sec 4.5]
- */
- if (IN6_IS_ADDR_MULTICAST(&new_bsr_uni_addr.unicast_addr) ||
- IN6_IS_ADDR_LINKLOCAL(&new_bsr_uni_addr.unicast_addr) ||
- IN6_IS_ADDR_SITELOCAL(&new_bsr_uni_addr.unicast_addr)) {
- log(LOG_WARNING, 0,
- "receive_pim6_bootstrap: invalid BSR address: %s",
- inet6_fmt(&new_bsr_uni_addr.unicast_addr));
- return(FALSE);
- }
-
- new_bsr_address.sin6_addr = new_bsr_uni_addr.unicast_addr;
- new_bsr_address.sin6_len = sizeof(new_bsr_address);
- new_bsr_address.sin6_family = AF_INET6;
- new_bsr_address.sin6_scope_id = inet6_uvif2scopeid(&new_bsr_address, v);
-
- if (local_address(&new_bsr_address) != NO_VIF)
- {
- IF_DEBUG(DEBUG_RPF | DEBUG_PIM_BOOTSTRAP)
- log(LOG_DEBUG, 0,
- "receive_pim6_bootstrap: Bootstrap from myself(%s), ignored.",
- inet6_fmt(&new_bsr_address.sin6_addr));
- return (FALSE); /* The new BSR is one of my local addresses */
- }
-
- /*
- * Compare the current BSR priority with the priority of the BSR included
- * in the message.
- */
- /*
- * TODO: if I am just starting and will become the BSR, I should accept
- * the message coming from the current BSR and get the current
- * Cand-RP-Set.
- */
-
- if ((curr_bsr_priority > new_bsr_priority) ||
- ((curr_bsr_priority == new_bsr_priority)
- && (inet6_greaterthan(&curr_bsr_address, &new_bsr_address))))
- {
- /* The message's BSR is less preferred than the current BSR */
- log(LOG_DEBUG, 0,
- "receive_pim6_bootstrap: BSR(%s, prio=%d) is less preferred"
- " than the current BSR(%s, prio=%d)",
- inet6_fmt(&new_bsr_address.sin6_addr), new_bsr_priority,
- inet6_fmt(&curr_bsr_address.sin6_addr), curr_bsr_priority);
- return (FALSE); /* Ignore the received BSR message */
- }
-
- /* Check the iif, if this was PIM-ROUTERS multicast */
- if (IN6_ARE_ADDR_EQUAL(&dst->sin6_addr, &allpim6routers_group.sin6_addr))
- {
- k_req_incoming(&new_bsr_address, &rpfc);
- if ((rpfc.iif == NO_VIF) ||
- IN6_IS_ADDR_UNSPECIFIED(&rpfc.rpfneighbor.sin6_addr))
- {
- /* coudn't find a route to the BSR */
- log(LOG_NOTICE, 0,
- "receive_pim6_bootstrap: can't find a route to the BSR(%s)",
- inet6_fmt(&new_bsr_address.sin6_addr));
- return (FALSE);
- }
-
- neighbor_addr = *src;
- incoming = rpfc.iif;
-
- if (uvifs[incoming].uv_flags &
- (VIFF_DISABLED | VIFF_DOWN | MIFF_REGISTER))
- {
- log(LOG_NOTICE, 0,
- "receive_pim6_bootstrap: Bootstrap from an invalid interface(%s)",
- uvifs[incoming].uv_name);
- return (FALSE); /* Shoudn't arrive on that interface */
- }
-
- /* Find the upstream router */
-
- for (n = uvifs[incoming].uv_pim_neighbors; n != NULL; n = n->next)
- {
- if (inet6_lessthan(&neighbor_addr, &n->address))
- continue;
- if (inet6_equal(&neighbor_addr, &n->address))
- {
- rpf_neighbor = n;
- break;
- }
- log(LOG_NOTICE, 0,
- "receive_pim6_bootstrap: Bootstrap from an unrecognized "
- "neighbor(%s) on %s",
- inet6_fmt(&neighbor_addr.sin6_addr), uvifs[incoming].uv_name);
- return (FALSE); /* No neighbor toward BSR found */
- }
-
- /* redundant checks? */
- if ((n == (pim_nbr_entry_t *) NULL ))
- {
- return (FALSE); /* Sender of this message is not the RPF*/
- }
- /* neighbor */
- if(!(inet6_equal(&n->address, src)))
- {
- return (FALSE);
- }
- }
- else
- {
- if (local_address(dst) == NO_VIF)
- /*
- * TODO: XXX: this situation should be handled earlier: The
- * destination is neither ALL_PIM_ROUTERS nor me
- */
- log(LOG_NOTICE, 0,
- "receive_pim6_bootstrap: Bootstrap with an invalid dst(%s)",
- inet6_fmt(&dst->sin6_addr));
- return (FALSE);
-
- /* Probably unicasted from the current DR */
- if (cand_rp_list != (cand_rp_t *) NULL)
- {
- /*
- * Hmmm, I do have a Cand-RP-list, but some neighbor has a
- * different opinion and is unicasting it to me. Ignore this guy.
- */
- log(LOG_INFO, 0,
- "receive_pim6_bootstrap: Bootstrap received but we already "
- "have RPs. ignored.");
- return (FALSE);
- }
- for (mifi = 0; mifi < numvifs; mifi++)
- {
- if (uvifs[mifi].uv_flags & (VIFF_DISABLED | VIFF_DOWN |
- MIFF_REGISTER))
- continue;
- if (inet6_equal(&uvifs[mifi].uv_linklocal->pa_addr,dst))
- {
- incoming = mifi;
- break;
- }
- }
- if (incoming == NO_VIF)
- {
- /* Cannot find the receiving iif toward that DR */
- IF_DEBUG(DEBUG_RPF | DEBUG_PIM_BOOTSTRAP)
- log(LOG_DEBUG, 0,
- "Unicast boostrap message from %s to %s ignored: "
- "cannot find iif",
- inet6_fmt(&src->sin6_addr), inet6_fmt(&dst->sin6_addr));
- return (FALSE);
- }
- /*
- * TODO: check the sender is directly connected and I am really the
- * DR.
- */
- }
-
- if (cand_rp_flag == TRUE)
- {
- /* If change in the BSR address, send immediately Cand-RP-Adv */
- /* TODO: use some random delay? */
-
- if (!inet6_equal(&new_bsr_address , &curr_bsr_address))
- {
- send_pim6_cand_rp_adv();
- SET_TIMER(pim_cand_rp_adv_timer, my_cand_rp_adv_period);
- }
- }
-
- /* Forward the BSR Message first and then update the RP-set list */
- /* XXX: should we do sanity checks before forwarding?? */
- /* TODO: if the message was unicasted to me, resend? */
-
- for (mifi = 0; mifi < numvifs; mifi++)
- {
- if (mifi == incoming)
- continue;
- if (uvifs[mifi].uv_flags & (VIFF_DISABLED | VIFF_DOWN |
- MIFF_REGISTER | VIFF_TUNNEL | VIFF_NONBRS))
- continue;
-
- bcopy(pim_message, (char *)(pim6_send_buf), datalen);
-
- send_pim6(pim6_send_buf, &uvifs[mifi].uv_linklocal->pa_addr,
- &allpim6routers_group, PIM_BOOTSTRAP,
- datalen - sizeof(struct pim));
- }
-
- max_data_ptr = (u_int8 *) pim_message + datalen;
-
- /*
- * TODO: XXX: this 24 is HARDCODING!!! Do a bunch of definitions and make
- * it stylish!
- * 24 = Encoded-Group Address(20) + RP-cound(1) + Frag-RP(1) + Reserved(2)
- */
- min_datalen = 24;
-
- if ((new_bsr_fragment_tag != curr_bsr_fragment_tag) ||
- (inet6_equal(&new_bsr_address, &curr_bsr_address)))
- {
- /* Throw away the old segment */
- delete_rp_list(&segmented_cand_rp_list, &segmented_grp_mask_list);
- }
-
- curr_bsr_address = new_bsr_address;
- curr_bsr_priority = new_bsr_priority;
- curr_bsr_fragment_tag = new_bsr_fragment_tag;
- MASKLEN_TO_MASK6(new_bsr_hash_masklen, curr_bsr_hash_mask);
- SET_TIMER(pim_bootstrap_timer, PIM_BOOTSTRAP_TIMEOUT);
-
- while (data_ptr + min_datalen <= max_data_ptr)
- {
- GET_EGADDR6(&curr_group_addr, data_ptr);
- GET_BYTE(curr_rp_count, data_ptr);
- GET_BYTE(curr_frag_rp_count, data_ptr);
- GET_HOSTSHORT(reserved_short, data_ptr);
- MASKLEN_TO_MASK6(curr_group_addr.masklen, curr_group_mask);
-
- if (IN6_IS_ADDR_MC_NODELOCAL(&curr_group_addr.mcast_addr) ||
- IN6_IS_ADDR_MC_LINKLOCAL(&curr_group_addr.mcast_addr)) {
- log(LOG_WARNING, 0,
- "receive_pim6_bootstrap: "
- "group prefix has a narraw scope: %s (ignored)",
- inet6_fmt(&curr_group_addr.mcast_addr));
- continue;
- }
- if (curr_rp_count == 0)
- {
- group_.sin6_addr = curr_group_addr.mcast_addr;
- delete_grp_mask(&cand_rp_list, &grp_mask_list,
- &group_, curr_group_mask);
- continue;
- }
- if (curr_rp_count == curr_frag_rp_count)
- {
- /* Add all RPs */
- while (curr_frag_rp_count--)
- {
- /*
- * Sanity for the data length; the data packet must contain
- * Encoded-Unicast-RP-Address(18) + RP-Holdtime(2) +
- * RP-Priority(1) + Reserved(1).
- */
- if (data_ptr + PIM6_ENCODE_UNI_ADDR_LEN + sizeof(u_int32_t)
- > max_data_ptr) {
- log(LOG_NOTICE, 0,
- "receive_pim6_bootstrap: Bootstrap from %s on %s "
- "does not have enough length to contatin RP information",
- inet6_fmt(&src->sin6_addr), v->uv_name);
-
- /*
- * Ignore the rest of the message.
- * XXX: should we discard the entire message?
- */
- goto garbage_collect;
- }
-
- GET_EUADDR6(&curr_rp_addr, data_ptr);
- GET_HOSTSHORT(curr_rp_holdtime, data_ptr);
- GET_BYTE(curr_rp_priority, data_ptr);
- GET_BYTE(reserved_byte, data_ptr);
- MASKLEN_TO_MASK6(curr_group_addr.masklen, curr_group_mask);
- rpp_.sin6_addr = curr_rp_addr.unicast_addr;
- rpp_.sin6_len = sizeof(rpp_);
- rpp_.sin6_family = AF_INET6;
- /*
- * The cand_rp address scope should be global.
- * XXX: however, is a site-local RP sometimes useful?
- * we currently discard such RP...
- */
- if (IN6_IS_ADDR_LINKLOCAL(&rpp_.sin6_addr) ||
- IN6_IS_ADDR_SITELOCAL(&rpp_.sin6_addr)) {
- log(LOG_WARNING, 0,
- "receive_pim6_bootstrap: invalid RP address: %s",
- inet6_fmt(&rpp_.sin6_addr));
- continue;
- }
- rpp_.sin6_scope_id = 0;
- group_.sin6_addr = curr_group_addr.mcast_addr;
- group_.sin6_len = sizeof(group_);
- group_.sin6_family = AF_INET6;
- group_.sin6_scope_id = inet6_uvif2scopeid(&group_,v);
-
- add_rp_grp_entry(&cand_rp_list, &grp_mask_list,
- &rpp_, curr_rp_priority,
- curr_rp_holdtime, &group_,
- curr_group_mask,
- curr_bsr_hash_mask,
- curr_bsr_fragment_tag);
- }
- continue;
- }
- /*
- * This is a partial list of the RPs for this group prefix. Save
- * until all segments arrive.
- */
-
- for (i = 0; i < sizeof(struct in6_addr); i++) {
- prefix_h.sin6_addr.s6_addr[i] =
- curr_group_addr.mcast_addr.s6_addr[i]
- & curr_group_mask.s6_addr[i];
- }
-
- for (grp_mask_ptr = segmented_grp_mask_list;
- grp_mask_ptr != (grp_mask_t *) NULL;
- grp_mask_ptr = grp_mask_ptr->next)
- {
- for (i = 0; i < sizeof(struct in6_addr); i++) {
- prefix_h2.sin6_addr.s6_addr[i] =
- grp_mask_ptr->group_addr.sin6_addr.s6_addr[i]
- & grp_mask_ptr->group_mask.s6_addr[i];
- }
-
- if (inet6_greaterthan(&prefix_h2, &prefix_h))
- continue;
- else
- break;
- }
- if ((grp_mask_ptr != (grp_mask_t *) NULL)
- && (IN6_ARE_ADDR_EQUAL(&grp_mask_ptr->group_addr.sin6_addr,
- &curr_group_addr.mcast_addr))
- && (IN6_ARE_ADDR_EQUAL(&grp_mask_ptr->group_mask, &curr_group_mask))
- && (grp_mask_ptr->group_rp_number + curr_frag_rp_count
- == curr_rp_count))
- {
- /* All missing PRs have arrived. Add all RP entries */
- while (curr_frag_rp_count--)
- {
- GET_EUADDR6(&curr_rp_addr, data_ptr);
- GET_HOSTSHORT(curr_rp_holdtime, data_ptr);
- GET_BYTE(curr_rp_priority, data_ptr);
- GET_BYTE(reserved_byte, data_ptr);
- MASKLEN_TO_MASK6(curr_group_addr.masklen, curr_group_mask);
- rpp_.sin6_addr = curr_rp_addr.unicast_addr;
- rpp_.sin6_scope_id=0;
- group_.sin6_addr = curr_group_addr.mcast_addr;
- group_.sin6_scope_id = inet6_uvif2scopeid(&group_,v);
- add_rp_grp_entry(&cand_rp_list,
- &grp_mask_list,
- &rpp_,
- curr_rp_priority,
- curr_rp_holdtime,
- &group_,
- curr_group_mask,
- curr_bsr_hash_mask,
- curr_bsr_fragment_tag);
- }
- /* Add the rest from the previously saved segments */
- for (grp_rp_entry_ptr = grp_mask_ptr->grp_rp_next;
- grp_rp_entry_ptr != (rp_grp_entry_t *) NULL;
- grp_rp_entry_ptr = grp_rp_entry_ptr->grp_rp_next)
- {
- group_.sin6_addr = curr_group_addr.mcast_addr;
- group_.sin6_scope_id = inet6_uvif2scopeid(&group_,v);
- add_rp_grp_entry(&cand_rp_list,
- &grp_mask_list,
- &grp_rp_entry_ptr->rp->rpentry->address,
- grp_rp_entry_ptr->priority,
- grp_rp_entry_ptr->holdtime,
- &group_,
- curr_group_mask,
- curr_bsr_hash_mask,
- curr_bsr_fragment_tag);
- }
- group_.sin6_addr = curr_group_addr.mcast_addr;
- group_.sin6_scope_id = inet6_uvif2scopeid(&group_,v);
- delete_grp_mask(&segmented_cand_rp_list,
- &segmented_grp_mask_list,
- &group_,
- curr_group_mask);
- }
- else
- {
- /* Add the partially received RP-list to the group of pending RPs */
- while (curr_frag_rp_count--)
- {
- GET_EUADDR6(&curr_rp_addr, data_ptr);
- GET_HOSTSHORT(curr_rp_holdtime, data_ptr);
- GET_BYTE(curr_rp_priority, data_ptr);
- GET_BYTE(reserved_byte, data_ptr);
- MASKLEN_TO_MASK6(curr_group_addr.masklen, curr_group_mask);
- rpp_.sin6_addr = curr_rp_addr.unicast_addr;
- group_.sin6_addr = curr_group_addr.mcast_addr;
- group_.sin6_scope_id = inet6_uvif2scopeid(&group_,v);
- add_rp_grp_entry(&segmented_cand_rp_list,
- &segmented_grp_mask_list,
- &rpp_,
- curr_rp_priority,
- curr_rp_holdtime,
- &group_,
- curr_group_mask,
- curr_bsr_hash_mask,
- curr_bsr_fragment_tag);
- }
- }
- }
-
-
- garbage_collect:
- /*
- * Garbage collection. Check all group prefixes and if the fragment_tag
- * for a group_prefix is the same as curr_bsr_fragment_tag, then remove
- * all RPs for this group_prefix which have different fragment tag.
- */
-
- for (grp_mask_ptr = grp_mask_list;
- grp_mask_ptr != (grp_mask_t *) NULL;
- grp_mask_ptr = grp_mask_next)
- {
- grp_mask_next = grp_mask_ptr->next;
- if (grp_mask_ptr->fragment_tag == curr_bsr_fragment_tag)
- {
- for (grp_rp_entry_ptr = grp_mask_ptr->grp_rp_next;
- grp_rp_entry_ptr != (rp_grp_entry_t *) NULL;
- grp_rp_entry_ptr = grp_rp_entry_next)
- {
- grp_rp_entry_next = grp_rp_entry_ptr->grp_rp_next;
- if (grp_rp_entry_ptr->fragment_tag != curr_bsr_fragment_tag)
- delete_rp_grp_entry(&cand_rp_list, &grp_mask_list,
- grp_rp_entry_ptr);
- }
- }
- }
-
- /* Cleanup also the list used by incompleted segments */
-
- for (grp_mask_ptr = segmented_grp_mask_list;
- grp_mask_ptr != (grp_mask_t *) NULL;
- grp_mask_ptr = grp_mask_next)
- {
- grp_mask_next = grp_mask_ptr->next;
- if (grp_mask_ptr->fragment_tag == curr_bsr_fragment_tag)
- {
- for (grp_rp_entry_ptr = grp_mask_ptr->grp_rp_next;
- grp_rp_entry_ptr != (rp_grp_entry_t *) NULL;
- grp_rp_entry_ptr = grp_rp_entry_next)
- {
- grp_rp_entry_next = grp_rp_entry_ptr->grp_rp_next;
- if (grp_rp_entry_ptr->fragment_tag != curr_bsr_fragment_tag)
- delete_rp_grp_entry(&segmented_cand_rp_list,
- &segmented_grp_mask_list,
- grp_rp_entry_ptr);
- }
- }
- }
-
- return (TRUE);
-}
-
-void
-send_pim6_bootstrap()
-{
- int datalen;
- mifi_t mifi;
-
- if ((datalen = create_pim6_bootstrap_message(pim6_send_buf)))
- {
- for (mifi = 0; mifi < numvifs; mifi++)
- {
- if (uvifs[mifi].uv_flags & (VIFF_DISABLED | VIFF_DOWN |
- MIFF_REGISTER | VIFF_TUNNEL))
- continue;
-
- send_pim6(pim6_send_buf, &uvifs[mifi].uv_linklocal->pa_addr,
- &allpim6routers_group, PIM_BOOTSTRAP, datalen);
- uvifs[mifi].uv_out_pim6_bootsrap++;
- }
- }
-}
-
-/************************************************************************
- * PIM_CAND_RP_ADV
- ************************************************************************/
-/*
- * minimum length of a cand. RP adv. message;
- * length of PIM header + prefix-cnt(1) + priority(1) + holdtime(2) +
- * encoded unicast RP addr(18)
- */
-#define PIM6_CAND_RP_ADV_MINLEN (PIM_MINLEN + PIM6_ENCODE_UNI_ADDR_LEN)
-
-/*
- * If I am the Bootstrap router, process the advertisement, otherwise ignore
- * it.
- */
-int
-receive_pim6_cand_rp_adv(src, dst, pim_message, datalen)
- struct sockaddr_in6 *src,
- *dst;
- char *pim_message;
- register int datalen;
-{
- u_int8 prefix_cnt;
- u_int8 priority;
- u_int16 holdtime;
- pim6_encod_uni_addr_t cand_rp_addr;
- pim6_encod_grp_addr_t encod_grp_addr;
- u_int8 *data_ptr;
- struct in6_addr grp_mask;
- struct sockaddr_in6 group_, rpp_;
-
- pim6dstat.in_pim6_cand_rp++;
-
- /* if I am not the bootstrap RP, then do not accept the message */
- if ((cand_bsr_flag != FALSE) &&
- !inet6_equal(&curr_bsr_address, &my_bsr_address))
- {
- log(LOG_NOTICE, 0,
- "receive_pim6_cand_rp_adv: receive cand_RP from %s "
- "but I'm not the BSR",
- inet6_fmt(&src->sin6_addr));
- return (FALSE);
- }
-
- /* sanity check for the minimum length */
- if (datalen < PIM6_CAND_RP_ADV_MINLEN) {
- log(LOG_NOTICE, 0,
- "receive_pim6_cand_rp_adv: cand_RP message size(%u) is"
- " too short from %s",
- datalen, inet6_fmt(&src->sin6_addr));
- return(FALSE);
- }
- datalen -= PIM6_CAND_RP_ADV_MINLEN;
-
- data_ptr = (u_int8 *) (pim_message + sizeof(struct pim));
- /* Parse the CAND_RP_ADV message */
- GET_BYTE(prefix_cnt, data_ptr);
- GET_BYTE(priority, data_ptr);
- GET_HOSTSHORT(holdtime, data_ptr);
- GET_EUADDR6(&cand_rp_addr, data_ptr);
-
- /*
- * The RP Address field is set to the globally reachable IPv6 address
- * [draft-ietf-pim-ipv6].
- */
- if (IN6_IS_ADDR_LINKLOCAL(&cand_rp_addr.unicast_addr)) {
- /* XXX: prohibit a site-local address as well? */
- log(LOG_WARNING, 0,
- "receive_pim6_cand_rp_adv: non global address(%s) as RP",
- inet6_fmt(&cand_rp_addr.unicast_addr));
- return(FALSE);
- }
-
- memset(&rpp_, 0, sizeof(rpp_));
- if (prefix_cnt == 0)
- {
- /* The default ff:: and masklen of 8 */
- MASKLEN_TO_MASK6(ALL_MCAST_GROUPS_LENGTH, grp_mask);
- rpp_.sin6_addr = cand_rp_addr.unicast_addr;
- /*
- * note that we don't have to take care of scope id, since
- * the address should be global(see above).
- */
- add_rp_grp_entry(&cand_rp_list, &grp_mask_list,
- &rpp_, priority, holdtime,
- &sockaddr6_d, grp_mask,
- my_bsr_hash_mask,
- curr_bsr_fragment_tag);
- return (TRUE);
- }
- while (prefix_cnt--)
- {
- /*
- * Sanity check for the message length.
- * XXX: do we have to do the check at an earlier stage and
- * discard the whole message (instead of adopting a part of it)
- * if it's bogus?
- */
- if (datalen < PIM6_ENCODE_GRP_ADDR_LEN) {
- log(LOG_NOTICE, 0,
- "receive_pim6_cand_rp_adv: cand_RP message from %s is"
- " too short to contain enough groups",
- inet6_fmt(&src->sin6_addr));
- return(FALSE);
- }
- datalen -= PIM6_ENCODE_GRP_ADDR_LEN;
-
- GET_EGADDR6(&encod_grp_addr, data_ptr);
- MASKLEN_TO_MASK6(encod_grp_addr.masklen, grp_mask);
- group_.sin6_addr = encod_grp_addr.mcast_addr;
- group_.sin6_scope_id = 0; /* XXX: what if for scoped multicast addr? */
- rpp_.sin6_addr = cand_rp_addr.unicast_addr;
- /* see above note on scope id */
-
- add_rp_grp_entry(&cand_rp_list, &grp_mask_list,
- &rpp_, priority, holdtime,
- &group_, grp_mask,
- my_bsr_hash_mask,
- curr_bsr_fragment_tag);
- }
-
- return (TRUE);
-}
-
-int
-send_pim6_cand_rp_adv()
-{
- u_int8 prefix_cnt;
- struct in6_addr grp_mask;
- pim6_encod_grp_addr_t encod_grp_addr;
- u_int8 *data_ptr;
- struct sockaddr_in6 group_;
-
- if (!inet6_valid_host(&curr_bsr_address))
- return (FALSE); /* No BSR yet */
-
- if( inet6_equal(&curr_bsr_address, &my_bsr_address))
- {
- /* I am the BSR and have to include my own group_prefix stuff */
- prefix_cnt = *cand_rp_adv_message.prefix_cnt_ptr;
- if (prefix_cnt == 0)
- {
- /* The default ff00:: and masklen of 8 */
- MASKLEN_TO_MASK6(ALL_MCAST_GROUPS_LENGTH, grp_mask);
- add_rp_grp_entry(&cand_rp_list, &grp_mask_list,
- &my_cand_rp_address, my_cand_rp_priority,
- my_cand_rp_holdtime,
- &sockaddr6_d,
- grp_mask,
- my_bsr_hash_mask,
- curr_bsr_fragment_tag);
- return (TRUE);
- }
- /* TODO: hardcoding!! */
- /* 18 = sizeof(pim6_encod_uni_addr_t) without padding */
- data_ptr = cand_rp_adv_message.buffer + (4 + 18);
-
- while (prefix_cnt--)
- {
- GET_EGADDR6(&encod_grp_addr, data_ptr);
- MASKLEN_TO_MASK6(encod_grp_addr.masklen, grp_mask);
- group_.sin6_addr = encod_grp_addr.mcast_addr;
- group_.sin6_scope_id = 0; /*XXX */
- add_rp_grp_entry(&cand_rp_list,
- &grp_mask_list,
- &my_cand_rp_address, my_cand_rp_priority,
- my_cand_rp_holdtime,
- &group_, grp_mask,
- my_bsr_hash_mask,
- curr_bsr_fragment_tag);
- }
- return (TRUE);
- }
-
- data_ptr = (u_int8 *) (pim6_send_buf + sizeof(struct pim));
-
- bcopy((char *)cand_rp_adv_message.buffer, (char *) data_ptr,
- cand_rp_adv_message.message_size);
-
- send_pim6(pim6_send_buf, &my_cand_rp_address, &curr_bsr_address ,
- PIM_CAND_RP_ADV, cand_rp_adv_message.message_size);
- pim6dstat.out_pim6_cand_rp++;
-
- return TRUE;
-}
diff --git a/usr.sbin/pim6sd/pim6_proto.h b/usr.sbin/pim6sd/pim6_proto.h
deleted file mode 100644
index 46fad58..0000000
--- a/usr.sbin/pim6sd/pim6_proto.h
+++ /dev/null
@@ -1,102 +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
- * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
- *
- */
-/*
- * This program has been derived from pim6dd.
- * The pim6dd program is covered by the license in the accompanying file
- * named "LICENSE.pim6dd".
- */
-/*
- * This program has been derived from pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- * $FreeBSD$
- */
-
-
-#ifndef PIM6_PROTO_H
-#define PIM6_PROTO_H
-#include "defs.h"
-#include "vif.h"
-#include "mrt.h"
-
-extern build_jp_message_t *build_jp_message_pool;
-extern int build_jp_message_pool_counter;
-extern struct sockaddr_in6 sockaddr6_any;
-extern struct sockaddr_in6 sockaddr6_d;
-
-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_register __P((struct sockaddr_in6 *src, struct sockaddr_in6 *dst,
- char *pim_message, int datalen));
-extern int send_pim6_null_register __P((mrtentry_t *r));
-extern int receive_pim6_register_stop __P((struct sockaddr_in6 *src, struct sockaddr_in6 *dst,
- char *pim_message,
- int datalen));
-extern int send_pim6_register __P((char *pkt));
-extern int receive_pim6_join_prune __P((struct sockaddr_in6 *src, struct sockaddr_in6 *dst,
- char *pim_message, int datalen));
-extern int join_or_prune __P((mrtentry_t *mrtentry_ptr,
- pim_nbr_entry_t *upstream_router));
-extern int receive_pim6_assert __P((struct sockaddr_in6 *src, struct sockaddr_in6 *dst,
- char *pim_message, int datalen));
-extern int send_pim6_assert __P((struct sockaddr_in6 *source, struct sockaddr_in6 *group,
- vifi_t vifi,
- mrtentry_t *mrtentry_ptr));
-extern int send_periodic_pim6_join_prune __P((vifi_t vifi,
- pim_nbr_entry_t *pim_nbr,
- u_int16 holdtime));
-extern int add_jp_entry __P((pim_nbr_entry_t *pim_nbr,
- u_int16 holdtime, struct sockaddr_in6 *group,
- u_int8 grp_msklen, struct sockaddr_in6 *source,
- u_int8 src_msklen,
- u_int16 addr_flags,
- u_int8 join_prune));
-extern void pack_and_send_jp6_message __P((pim_nbr_entry_t *pim_nbr));
-extern int receive_pim6_cand_rp_adv __P((struct sockaddr_in6 *src, struct sockaddr_in6 *dst,
- char *pim_message, int datalen));
-extern int receive_pim6_bootstrap __P((struct sockaddr_in6 *src, struct sockaddr_in6 *dst,
- char *pim_message, int datalen));
-extern int send_pim6_cand_rp_adv __P((void));
-extern void send_pim6_bootstrap __P((void));
-
-
-#endif
diff --git a/usr.sbin/pim6sd/pim6sd.8 b/usr.sbin/pim6sd/pim6sd.8
deleted file mode 100644
index b72f333..0000000
--- a/usr.sbin/pim6sd/pim6sd.8
+++ /dev/null
@@ -1,170 +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.
-.\"
-.\" $Id: pim6sd.8,v 1.6 2000/05/18 16:11:46 itojun Exp $
-.\" $FreeBSD$
-.\"
-.Dd June 10, 1999
-.Dt PIM6SD 8
-.Os
-.Sh NAME
-.Nm pim6sd
-.Nd PIM for IPv6 sparse mode daemon
-.Sh SYNOPSIS
-.Nm
-.Op Fl c Ar configfile
-.Oo
-.Fl d
-.Sm off
-.Op Ar debug_level Op , Ar ...
-.Sm on
-.Oc
-.Op Fl f
-.Sh DESCRIPTION
-.Nm Pim6sd
-is an IPv6 multicast routing daemon, which supports
-PIMv2(Protocol Independent Multicast Version 2) sparse 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/pim6sd.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 mld_proto , mld_timer , mld_member , mld ,
-.Ic switch , trace , mtrace , traceroute ,
-.Ic timeout , callout , pkt , packets ,
-.Ic interfaces , vif , kernel , cache ,
-.Ic mfc , k_cache , k_mfc , rsrr ,
-.Ic pim_detail , pim_hello , pim_neighbors , pim_register ,
-.Ic registers , pim_join_prune , pim_j_p , pim_jp ,
-.Ic pim_bootstrap , pim_bsr , bsr , bootstrap ,
-.Ic pim_asserts , pim_cand_rp , pim_c_rp , pim_rp ,
-.Ic rp , pim_routes , pim_routing , pim_mrt ,
-.Ic pim_timers , pim_rpf , rpf , pim ,
-.Ic routes , routing , mrt , routers ,
-.Ic mrouters , neighbors , timers ,
-and
-.Ic asserts .
-.It Fl f
-Do not become daemon, run in foreground. This option is for debugging
-use.
-.El
-.Pp
-.Nm Pim6sd
-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/pim6sd.conf
-.Po
-or an alternative file, specified by the
-.Sq Fl c
-option
-.Pc .
-.Pp
-The
-.Nm
-program dumps its current routing information to a dump file when
-it receives a
-.Dv SIGUSR1
-signal.
-The information includes a list of PIM neighbors,
-.Nm
-internal multicast routing table, and
-BSR and RP related information. Also, the program dumps its internal
-statistics to a file when it receives a SIGINFO signal.
-.Pp
-When
-.Nm
-receives a SIGUSR2 signal, it rereads the configuration file and
-reset its debug level.
-.Pp
-The
-.Nm
-program puts its logs to a separate file
-.Pq Pa /var/log/pim6sd.log .
-The log level can be configured by the
-.Fl d
-command line option or the configuration file.
-.\"
-.Sh FILES
-.Bl -tag -width /etc/pim6sd.conf -compact
-.It Pa /etc/pim6sd.conf
-The default configuration file.
-.It Pa /var/run/pim6sd.dump
-The file to which
-.Nm
-dumps its internal status.
-.It Pa /var/run/pim6sd.stat
-The file to which
-.Nm
-dumps its internal statistics.
-.It Pa /var/log/pim6sd.log
-The pim6sd specific log file.
-.El
-.Sh SEE ALSO
-.Xr daemon 3 ,
-.Xr pim6sd.conf 5
-.Sh HISTORY
-The
-.Nm
-command is developed by Mickael Hoerdt at LSIIT Laboratory.
-It is based on IPv4 PIM sparse-mode
-.Nm pimd
-developed at University of Southern California,
-which 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 Pim6sd
-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
-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/pim6sd/pim6sd.conf.5 b/usr.sbin/pim6sd/pim6sd.conf.5
deleted file mode 100644
index 427cb9e..0000000
--- a/usr.sbin/pim6sd/pim6sd.conf.5
+++ /dev/null
@@ -1,317 +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.
-.\"
-.\" KAME Id: pim6sd.conf.5,v 1.10 2000/07/09 17:28:42 itojun Exp
-.\" $FreeBSD$
-.\"
-.Dd October 6, 1999
-.Dt PIM6SD.CONF 5
-.Os
-.Sh NAME
-.Nm pim6sd.conf
-.Nd config file for pim6sd, PIM-SM daemon for IPv6
-.\"
-.Sh DESCRIPTION
-The
-.Nm
-configuration file consists of a sequence of statements terminated
-by a semi-colon
-.Pq Ql \&; ,
-each of which specifies how the daemon treats
-each interface on the system, specifies some parameters of the PIM
-protocol, and requires some special behavior defined by the protocol.
-.Pp
-Each statement can be constructed by multiple lines.
-.Pp
-Lines beginning with
-.Ql #
-are comments.
-.\".Pp
-.\"Note that
-.\".Xr pim6sd 8
-.\"works even without the configuration file, although the daemon
-.\"will warn that there is no configuration file.
-.\"In such a case, the daemon will automatically set the default value
-.\"to each configurable parameter.
-.\"
-.Pp
-The following statements can be specified in the configuration file.
-.Pp
-.Bl -tag -width Ds
-.It Ic log Ar option... ;
-Specify debug messages to be printed out. Each
-.Ar option
-usually specifies a subset of the messages to be printed.
-If an
-.Ar option
-begins with
-.Ic no ,
-it means that the set of the messages that are specified by the option
-will not be printed. For example,
-.Ic `all nomld'
-means that all the messages except MLD related ones will be printed.
-Valid options are
-.Ic mld_proto , mld_timer , mld_member , mld ,
-.Ic switch , trace , mtrace , traceroute ,
-.Ic timeout , callout , pkt , packets ,
-.Ic interfaces , vif , kernel , cache ,
-.Ic mfc , k_cache , k_mfc , rsrr ,
-.Ic pim_detail , pim_hello , pim_neighbors , pim_register ,
-.Ic registers , pim_join_prune , pim_j_p , pim_jp ,
-.Ic pim_bootstrap , pim_bsr , bsr , bootstrap ,
-.Ic pim_asserts , pim_cand_rp , pim_c_rp , pim_rp ,
-.Ic rp , pim_routes , pim_routing , pim_mrt ,
-.Ic pim_timers , pim_rpf , rpf , pim ,
-.Ic routes , routing , mrt , routers ,
-.Ic mrouters , neighbors , timers , asserts ,
-and
-.Ic all .
-.\"
-.It Ic reverselookup Pq Cm yes | no ;
-Specifies if a hostname for an IPv6 address should be resolved
-on logging.
-.Ic yes
-means a hostname should be resolved, and
-.Ic no
-means should not.
-By default, a hostname is not resolved.
-.\"
-.It Ic phyint Ar interface Op Cm disable ;
-Specifies
-.Xr pim6sd 8
-to ignore the interface even if the interface is multicast-capable.
-Note that PIM will be activated on all interfaces by default(including
-the case where there is no configuration file).
-Interfaces are specified in the form of "name unit", such as
-.Ar gif0
-and
-.Ar ep1 .
-.\"
-.It Xo
-.Ic phyint Ar interface
-.Op Cm preference Ar preference
-.Op Cm metric Ar metric
-.Op Cm nolistener ;
-.Xc
-Specifies the preference and/or metric values when sending a PIM
-assert message on the interface.
-If another optional parameter
-.Ic nolistener
-is specified,
-.Xr pim6sd 8
-will not send any MLD packets on the interface.
-This option is usually meaningless but will be useful when
-MLD messages are noisy (e.g. when debugging) and there is surely no
-listner on the interface.
-.\"
-.It Ic default_source_preference Ar preference ;
-Specifies a default preference value when sending a PIM assert message.
-Preferences are used by assert elections to determine upstream routers.
-Currently
-.Xr pim6sd 8
-cannot reliably obtain preferences and metrics from the
-unicast routing protocols, so a default value may be configured.
-The default preference is 1024.
-.\"
-.It Ic default_source_metric Ar metric ;
-Specifies a default metric value when sending a PIM assert message.
-It is recommended that preferences be set such that metrics are never
-consulted. However, default metrics may also be set and will default to
-1024.
-.\"
-.It Ic granularity Ar second ;
-Specifies timer granularity in seconds.
-The default value is 5.
-.\"
-.It Ic hello_period Ar period coef ;
-.Ar Period
-specifies the period in second between 2 hello messages.
-.Ar Coef
-is the coefficient to determine the hello holdtime;
-the holdtime will be
-.Ar period
-*
-.Ar coef .
-The default values of the period and the coefficient are 30 and 3.5,
-respectively. The default holdtime is 105 seconds as a result.
-.\"
-.It Ic join_prune_period Ar period coef ;
-.Ar Period
-specifies the period in second between 2 join/prune messages.
-.Ar Coef
-is the coefficient to determine the join/prune holdtime;
-the holdtime will be
-.Ar period
-*
-.Ar coef .
-The default values of the period and the coefficient are 60 and 3.5,
-respectively. Consequently, the default holdtime is 210 seconds.
-.\"
-.It Ic data_timeout Ar timer ;
-Specifies the time after which (S,G) state for a silent source will be
-deleted.
-The default value is 210.
-.\"
-.It Ic register_suppression_timeout Ar interval ;
-.Ar Interval
-specifies the interval between receiving a Register-Stop and allowing
-PIM Register to be send again.
-The default value is 60.
-.\"
-.It Ic probe_time Ar timer ;
-.Ar Timer
-specifies the time between sending a null Register and the
-Register-Suppression-Timer expiring unless it is restarted by
-receiving a Register-Stop.
-The default value is 5.
-.\"
-.It Ic assert_timeout Ar interval ;
-.Ar Interval
-specifies the interval between the last time an Assert is received and
-the time at which the assert is timeout.
-The default value is 180.
-.\"
-.It Xo
-.Ic cand_rp
-.Op Ar interface
-.Op Cm time Ar time
-.Op Cm priority Ar priority ;
-.Xc
-Specifies to act as a candidate Rendezvous Point(RP).
-It is recommended to specify
-.Ic cand_rp
-only in typical usage.
-All other parameters are optional and will be set automatically.
-If an
-.Ar interface
-is specified,
-.Xr pim6sd 8
-will search for a global address on the specified interface
-and set the address in Candidate RP Advertisements.
-An optional parameter
-.Ic time
-specifies the interval of two succeeding advertisements in seconds.
-Its default value is 60.
-2.5 *
-.Ar time
-will be set to Candidate-RP-Advertisement messages.
-Another optional parameter
-.Ic priority
-specifies the priority of the RP.
-The default value is 0, which means the highest priority.
-.\"
-.It Ic group_prefix Ar prefix ;
-When acting as a Rendezvous Point(RP),
-.Ar prefix
-specifies a group prefix that the RP will handle.
-.\"
-.It Xo
-.Ic cand_bootstrap_router
-.Op Ar interface
-.Op Cm time Ar time
-.Op Cm priority Ar priority
-.Op Cm masklen Ar masklen ;
-.Xc
-Specifies to act as a candidate bootstrap router(BSR).
-It is recommended to specify
-.Ic cand_bootstrap_router
-only in typical usage.
-All other parameters are optional and will be set automatically.
-If an
-.Ar interface
-is specified,
-.Xr pim6sd 8
-will search for a global address on the specified interface
-and set the address in Bootstrap messages.
-An optional parameter
-.Ic time
-specifies the interval of two succeeding bootstraps in seconds.
-Its default value is 60.
-Another optional parameter
-.Ic priority
-specifies the priority of the RP.
-The default value is 0, which means the lowest priority.
-Hash mask length can also be specified by the
-.Ic masklen
-parametr. Its value,
-.Ar masklen ,
-must be no less than 0 and no greater than 128.
-.\"
-.It Xo
-.Ic switch_register_threshold
-.Cm rate Ar rate Cm interval Ar interval ;
-.Xc
-Specifies the threshold that a Rendezvous Point(RP) switches to a shortest
-path tree, which is valid only when acting as an RP.
-.Ic rate
-specifies the threshold in bits per second, and
-.Ic interval
-specifies the interval of checking the rate in seconds.
-The default values are 50000 and 20, respectively.
-.\"
-.It Xo
-.Ic switch_data_threshold
-.Cm rate Ar rate Cm interval Ar interval ;
-.Xc
-Specifies the threshold that a last hop router switches to a shortest
-path tree.
-.Ic rate
-specifies the threshold in bits per second, and
-.Ic interval
-specifies the interval of checking the rate in seconds.
-The default values are 50000 and 20, respectively.
-.El
-.\"
-.Sh EXAMPLES
-.Bd -literal -offset
-# phyint gif0 disable;
-# phyint ep0 preference 101;
-phyint de0 disable;
-#
-# followings are for a candidate Rendezvous Point, which should usually
-# be disabled.
-cand_bootstrap_router;
-cand_rp;
-.Ed
-.Sh SEE ALSO
-.Xr pim6sd 8
-.Sh HISTORY
-The
-.Xr pim6sd 8
-command is developed by Mickael Hoerdt at LSIIT Laboratory.
-It is based on IPv4 PIM sparse-mode
-.Nm pimd
-developed at University of Southern California,
-which 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/pim6sd/pim6sd.conf.sample b/usr.sbin/pim6sd/pim6sd.conf.sample
deleted file mode 100644
index 2aabc6b..0000000
--- a/usr.sbin/pim6sd/pim6sd.conf.sample
+++ /dev/null
@@ -1,107 +0,0 @@
-# $FreeBSD$
-#
-#The timer granularity.
-#More this value is small,more pim6sd will be accurate
-#default if not specified : 5
-#BE SURE to have to same granularity on ALL routers,
-#otherwise....
-
-#granularity 5;
-
-#syntax : phyint <interface> <disable> <metric> [metric] <preference> [preference]
-#metric and pref are for the asserts messages
-#samples :
-
-#phyint ed1 disable;
-#phyint de0 disable;
-#phyint ed0 disable;
-#phyint gif0 disable;
-
-#---------------Protocol timer specifications---------------------------#
-#Notes : theses value are the default spec value!
-#do not touch it if you don't know what you do!!
-#you MUST change theses values according to the granularity value!
-#syntax : 'hello_period <number> <coef>'.
-# number is the period in second between 2 hello messages
-# and coef is the coef to deterimine the hello holdtime=hello_period*coef
-# default if not specified: 30 3.5
-
-#hello_period 30 3.5;
-
-#syntax : 'join_prune_period <number> <coef>'.
-# number is the period in second between 2 join/prune messages
-# and coef is the coef to deterimine the join/prune holdtime=join_prune_period*coef
-# default if not specified : 60 3.5
-
-#join_prune_period 60 3.5;
-
-#syntax : 'data_timeout <number>'.
-# number is the time after which (S,G) state for a silent source will be deleted
-# default if not specified : 210
-
-#data_timeout 210;
-
-#syntax : 'register_suppression_timeout <number>'.
-# This is the mean interval between receiving a Register-Stop and allowing
-#Register to be send again.
-# default if not specified : 60
-
-#register_suppression_timeout 60;
-
-#syntax : 'probe_time <number>'.
-#This is the time between sending a null Register and the Register-Suppression-Timer
-#expiring unless it is restarted by receiving a Register-Stop.
-#default if not specified : 5
-
-#probe_time 5;
-
-#syntax : 'assert_timeout <number>'.
-#this is the interval between the last time an Assert is received and the time at wich the
-#assert is timeout
-#default if not specified : 180
-
-#assert_timeout 180;
-
-#syntax : <cand_rp> <interface> <time> [time] <priority> [priority]
-#and time can't be < 10
-#you can just type cand_rp,
-#samples :
-#cand_rp;
-#cand_rp de0;
-#cand_rp ed0 priority 0 time 6;
-
-#syntax : <group_prefix> <multicast address>/<prefix length>
-#group_prefix ff06::15
-#default if not specified : ff00::/8
-#samples:
-#group_prefix ff1e::15/128;
-#group_prefix ff2e::/16;
-
-#syntax : <cand_bootstrap_router> <interface> <priority> [priority] <time> [time]
-#Typically, you can simply set cand_bootstrap_router for a candidate bootstrap
-#router. All other parameters are optional.
-#the bootstrap period is configurable, BUT the holdtime of a bootstrap
-#router is not in the fields of a bootstrap message : it is hardcoded
-#in the pim6sd include file!
-#So be sure to have a time < PIM_BOOSTRAP_TIMEOUT (file pimd.h )
-#cand_bootstrap_router de0 priority 15 time 5;
-
-#syntax : <switch_register_threshold> <rate> [number] <interval> [number]
-#default rate = 50000 interval = 20s
-#samples :
-#TODO : not tested
-#switch_register_threshold rate 54389 interval 45;
-#switch_register_threshold;
-
-#syntax : <switch_data_threshold> <rate> [number] <interval> [number]
-#default rate = 50000 interval = 20s
-#TODO : not tested
-#samples:
-#switch_data_threshold interval 100 rate 1000;
-
-#syntax : <default_source_metric> [number]
-
-#default_source_metric 1243;
-#syntax : <default_source_preference> [number]
-
-#default_source_preference 123 ;
diff --git a/usr.sbin/pim6sd/pim6stat b/usr.sbin/pim6sd/pim6stat
deleted file mode 100755
index 667ee4a..0000000
--- a/usr.sbin/pim6sd/pim6stat
+++ /dev/null
@@ -1,89 +0,0 @@
-#!/bin/sh
-
-# 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.
-#
-# $FreeBSD$
-
-# get options
-while getopts "df:p:sw:" option
-do
- case $option in
- d)
- densemode="YES";;
- f)
- dumpfile="${OPTARG}";;
- p)
- pidfile="${OPTARG}";;
- s)
- statmode="YES";;
- w)
- waittime="${OPTARG}";;
- *) # (error msg printed by getopts)
- echo usage: pim6stat [-d][-f dumpfile][-p pidfile][-w waitsec]
- exit 2;;
- esac
-done
-
-# set parameters
-if [ X"${pidfile}" = X ]; then
- if [ X"${densemode}" = X"YES" ]; then
- pidfile=/var/run/pim6dd.pid
- else
- pidfile=/var/run/pim6sd.pid
- fi
-fi
-
-if [ X"${waittime}" = X ]; then
- waittime=1
-fi
-
-if [ X"${statmode}" = X"YES" ]; then
- signame=-INFO
-else
- signame=-USR1
-fi
-
-if [ X"${dumpfile}" = X ]; then
- if [ X"${statmode}" = X"YES" ]; then
- if [ X"${densemode}" = X"YES" ]; then
- dumpfile=/var/run/pim6dd.stat
- else
- dumpfile=/var/run/pim6sd.stat
- fi
- else
- if [ X"${densemode}" = X"YES" ]; then
- dumpfile=/var/run/pim6dd.dump
- else
- dumpfile=/var/run/pim6sd.dump
- fi
- fi
-fi
-
-# execution
-kill ${signame} `cat ${pidfile}`
-sleep ${waittime}
-cat ${dumpfile}
diff --git a/usr.sbin/pim6sd/pim6stat.1 b/usr.sbin/pim6sd/pim6stat.1
deleted file mode 100644
index 0ee8049..0000000
--- a/usr.sbin/pim6sd/pim6stat.1
+++ /dev/null
@@ -1,95 +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.
-.\"
-.\" $Id: pim6stat.1,v 1.5 2000/05/05 14:57:14 sumikawa Exp $
-.\" $FreeBSD$
-.\"
-.Dd July 28, 1999
-.Dt PIM6STAT 1
-.Os
-.Sh NAME
-.Nm pim6stat
-.Nd show PIM for IPv6 status
-.Sh SYNOPSIS
-.Nm
-.Op Fl ds
-.Op Fl f Ar dumpfile
-.Op Fl p Ar pidfile
-.Op Fl w Ar waitsec
-.Sh DESCRIPTION
-.Nm Pim6stat
-shows status or statistics of the PIM for IPv6 daemon currently running.
-When invoked, it sends a signal to let the daemon dump its internal
-status to a file, waits for dumping, and outputs the content of the file
-to standard output.
-.Pp
-Options supported by
-.Nm :
-.Bl -tag -width Ds
-.It Fl d
-specifies to show the status of a dense mode daemon (if running).
-By default,
-.Nm
-assumes sparse mode.
-.It Fl f
-specifies the dumpfile to which the PIM daemon dumps its status.
-.It Fl p
-specifies the PID file of the currently running daemon.
-.It Fl s
-specifies to dump statistics instead of status (for sparse mode only).
-.It Fl w
-specifies the wait period in seconds between sending a signal to the
-daemon and outputs the dumpfile.
-.El
-.Sh FILES
-.Bl -tag -width /var/run/pim6sd.pidX -compact
-.It Pa /var/run/pim6sd.pid
-The default PID file for a sparse mode daemon.
-.It Pa /var/run/pim6dd.pid
-The default PID file for a dense mode daemon.
-.It Pa /var/run/pim6sd.dump
-The default dump file for a sparse mode daemon.
-.It Pa /var/run/pim6dd.dump
-The default dump file for a dense mode daemon.
-.It Pa /var/run/pim6sd.stat
-The default statistics dump file for a sparse mode daemon.
-.El
-.Sh SEE ALSO
-.Xr pim6dd 8 ,
-.Xr pim6sd 8
-.Sh HISTORY
-The
-.Nm
-command first appeared in KAME IPv6 protocol stack kit.
-.Pp
-IPv6 and IPsec support based on the KAME Project (http://www.kame.net/) stack
-was initially integrated into
-.Fx 4.0
-.Sh BUGS
-.Nm Pim6stat
-needs superuser privilege.
-.\"
diff --git a/usr.sbin/pim6sd/pimd.h b/usr.sbin/pim6sd/pimd.h
deleted file mode 100644
index 4ad81a6..0000000
--- a/usr.sbin/pim6sd/pimd.h
+++ /dev/null
@@ -1,526 +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
- * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
- *
- */
-/*
- * This program has been derived from pim6dd.
- * The pim6dd program is covered by the license in the accompanying file
- * named "LICENSE.pim6dd".
- */
-/*
- * This program has been derived from pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- * $FreeBSD$
- */
-
-
-#ifndef PIMD_H
-#define PIMD_H
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include "defs.h"
-
-#define PIM_PROTOCOL_VERSION 2
-
-/* PIM protocol timers (in seconds) */
-#define PIM_REGISTER_SUPPRESSION_TIMEOUT 60
-#define PIM_REGISTER_PROBE_TIME 5 /* Used to send NULL_REGISTER */
-#define PIM_DATA_TIMEOUT 210
-
-#define PIM_TIMER_HELLO_PERIOD 30
-#define PIM_JOIN_PRUNE_PERIOD 60
-
-#define PIM_JOIN_PRUNE_HOLDTIME (3.5 * PIM_JOIN_PRUNE_PERIOD)
-#define PIM_RANDOM_DELAY_JOIN_TIMEOUT 4.5
-
-#define PIM_DEFAULT_CAND_RP_ADV_PERIOD 60
-#define PIM_DEFAULT_BOOTSTRAP_PERIOD 60
-
-#define PIM_BOOTSTRAP_TIMEOUT (2.5 * PIM_DEFAULT_BOOTSTRAP_PERIOD + 10)
-#define PIM_TIMER_HELLO_HOLDTIME (3.5 * PIM_TIMER_HELLO_PERIOD)
-#define PIM_ASSERT_TIMEOUT 180
-
-
-/* Misc definitions */
-#define PIM_DEFAULT_CAND_RP_PRIORITY 0 /* 0 is the highest. Don't know
- * why this is the default.
- * See the PS version (Mar' 97),
- * pp.22 bottom of the spec.
- */
-
-#define PIM_DEFAULT_BSR_PRIORITY 0 /* 0 is the lowest */
-#define RP_DEFAULT_IPV6_HASHMASKLEN 126 /* the default group msklen used
- * by the hash function to
- * calculate the group-to-RP
- * mapping
- */
-
-#define SINGLE_SRC_MSK6LEN 128 /* the single source mask length */
-#define SINGLE_GRP_MSK6LEN 128 /* the single group mask length */
-
-/* TODO: change? */
-#define PIM_GROUP_PREFIX_DEFAULT_MASKLEN 8 /* The default group masklen if
- * omitted in the config file.
- */
-
-/* Datarate related definitions */
-/* REG_RATE is used by the RP to switch to the shortest path instead of
- * decapsulating Registers.
- * DATA_RATE is the threshold for the last hop router to initiate
- * switching to the shortest path.
- */
-/* TODO: XXX: probably no need for two different intervals.
- */
-
-#define PIM_DEFAULT_REG_RATE 50000 /* max # of register bits/s */
-#define PIM_DEFAULT_REG_RATE_INTERVAL 20 /* regrate probe interval */
-#define PIM_DEFAULT_DATA_RATE 50000 /* max # of data bits/s */
-#define PIM_DEFAULT_DATA_RATE_INTERVAL 20 /* datarate check interval */
-
-#define DATA_RATE_CHECK_INTERVAL 20 /* Data rate check interval */
-#define REG_RATE_CHECK_INTERVAL 20 /* PIM Reg. rate check interval*/
-
-#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_REG_RATE_LIMIT 0 /* default register_vif rate limit */
-
-/**************************************************************************
- * 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_IPv6 0
-
-
-/* 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;
-/* XXX: sizeof(pim6_encod_uni_addr_t) does not work due to misalignment */
-#define PIM6_ENCODE_UNI_ADDR_LEN 18
-
-/* 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;
-/* XXX: sizeof(pim6_encod_grp_addr_t) MAY NOT work due to an alignment problem */
-#define PIM6_ENCODE_GRP_ADDR_LEN 20
-
-/* 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;
-/* XXX: sizeof(pim6_encod_src_addr_t) MAY NOT work due to an alignment problem */
-#define PIM6_ENCODE_SRC_ADDR_LEN 20
-
-#define USADDR_RP_BIT 0x1
-#define USADDR_WC_BIT 0x2
-#define USADDR_S_BIT 0x4
-
-/**************************************************************************
- * PIM Messages formats *
- *************************************************************************/
-
-/* 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;
-
-/* PIM Register */
-typedef struct pim_register_ {
- u_int32 reg_flags;
-} pim_register_t;
-
-/* PIM Register-Stop */
-typedef struct pim_register_stop_ {
- pim6_encod_grp_addr_t encod_grp;
- pim6_encod_uni_addr_t encod_src; /* XXX: 18 bytes long, misaligned */
-} pim_register_stop_t;
-
-/* PIM Join/Prune: XXX: all 128-bit addresses misaligned! */
-typedef struct pim_jp_header_ {
- pim6_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_ {
- pim6_encod_grp_addr_t encod_grp;
- u_int16 number_join_src;
- u_int16 number_prune_src;
-} pim_jp_encod_grp_t;
-
-
-#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
-#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
-
-
-/* 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
-
-/* PIM_REGISTER definitions */
-#define PIM_MESSAGE_REGISTER_BORDER_BIT 0x80000000
-#define PIM_MESSAGE_REGISTER_NULL_REGISTER_BIT 0x40000000
-
-#define MASK_TO_MASKLEN6(mask , masklen) \
-do { \
- register u_int32 tmp_mask; \
- register u_int8 tmp_masklen = sizeof((mask)) <<3; \
- int i; \
- int kl; \
- for(i=0;i<4;i++) \
- { \
- tmp_mask=ntohl(*(u_int32_t *)&mask.s6_addr[i * 4]); \
- for(kl=32; tmp_masklen >0 && kl>0 ; tmp_masklen--, kl-- , tmp_mask >>=1) \
- if( tmp_mask & 0x1) \
- break; \
- } \
- (masklen) =tmp_masklen; \
- } 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_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_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_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_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_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_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)
-
-/* Used if no relaible unicast routing information available */
-#define UCAST_DEFAULT_SOURCE_METRIC 1024
-#define UCAST_DEFAULT_SOURCE_PREFERENCE 1024
-
-
-#define DEFAULT_LOCAL_PREF 101 /* assert pref par defaut */
-#define DEFAULT_LOCAL_METRIC 1024 /* assert metrique par default */
-
-
-/*
- * TODO: recalculate the messages sizes, probably with regard to the MTU
- * TODO: cleanup
- */
-
-#define MAX_JP_MESSAGE_SIZE 8192
-#define MAX_JP_MESSAGE_POOL_NUMBER 8
-#define MAX_JOIN_LIST_SIZE 1500
-#define MAX_PRUNE_LIST_SIZE 1500
-
-#define STAR_STAR_RP_MSK6LEN 8 /* Masklen for
- * ff00 ::
- * to encode (*,*,RP)
- */
-
-/* interface independent statistics */
-struct pim6dstat {
- /* incoming PIM6 packets on this interface */
- u_quad_t in_pim6_register;
- u_quad_t in_pim6_register_stop;
- u_quad_t in_pim6_cand_rp;
- u_quad_t in_pim6_graft; /* for dense mode only */
- u_quad_t in_pim6_graft_ack; /* for dense mode only */
- /* outgoing PIM6 packets on this interface */
- u_quad_t out_pim6_register;
- u_quad_t out_pim6_register_stop;
- u_quad_t out_pim6_cand_rp;
- /* SPT transition */
- u_quad_t pim6_trans_spt_forward;
- u_quad_t pim6_trans_spt_rp;
- /* occurrences of timeouts */
- u_quad_t pim6_bootstrap_timo;/* pim_bootstrap_timer */
- u_quad_t pim6_rpgrp_timo; /* rp_grp_entry_ptr->holdtime */
- u_quad_t pim6_rtentry_timo; /* routing entry */
- /* kernel internals */
- u_quad_t kern_add_cache;
- u_quad_t kern_add_cache_fail;
- u_quad_t kern_del_cache;
- u_quad_t kern_del_cache_fail;
- u_quad_t kern_sgcnt_fail;
-};
-
-extern struct pim6dstat pim6dstat;
-#endif
diff --git a/usr.sbin/pim6sd/route.c b/usr.sbin/pim6sd/route.c
deleted file mode 100644
index 26869f8..0000000
--- a/usr.sbin/pim6sd/route.c
+++ /dev/null
@@ -1,1179 +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
- * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
- *
- */
-/*
- * This program has been derived from pim6dd.
- * The pim6dd program is covered by the license in the accompanying file
- * named "LICENSE.pim6dd".
- */
-/*
- * This program has been derived from pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- * $FreeBSD$
- */
-
-#include <sys/types.h>
-#include <syslog.h>
-#include "pimd.h"
-#include "vif.h"
-#include "mrt.h"
-#include "debug.h"
-#include "pim6_proto.h"
-#include "route.h"
-#include "mld6.h"
-#include "rp.h"
-#include "kern.h"
-#include "timer.h"
-#include "inet6.h"
-#include <netinet6/ip6_mroute.h>
-#include <netinet/ip6.h>
-#include "routesock.h"
-
-static void process_cache_miss __P((struct mrt6msg * im));
-static void process_wrong_iif __P((struct mrt6msg * im));
-static void process_whole_pkt __P((char *buf));
-
-u_int32 default_source_metric = UCAST_DEFAULT_SOURCE_METRIC;
-u_int32 default_source_preference = UCAST_DEFAULT_SOURCE_PREFERENCE;
-
-
-/* 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!!! Yes Really for Ipv6!!
- */
-/*
- * TODO: XXX: change the metric and preference for all (S,G) entries per
- * source or RP?
- */
-/*
- * 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. If srcentry==PIM_IIF_RP, then "upstream" in
- * case of directly connected "source" will be that "source" (if it is also
- * PIM router).,
- */
-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->metric = 0;
- srcentry_ptr->preference = 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)
- {
- /*
- * The source is directly connected. Check whether we are looking for
- * real source or RP
- */
-
- if (srctype == PIM_IIF_SOURCE)
- {
- srcentry_ptr->upstream = (pim_nbr_entry_t *) NULL;
- return (TRUE);
- }
- else
- {
- /* PIM_IIF_RP */
- neighbor_addr = source;
- }
- }
- else
- {
- /* 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;
- /* 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 ;-).
- * Yes but the neighbors are link-local and the rp is global ipv6..
- */
-/* WARNING WARNING WARNING WARNING */
-/* If the router is directly connected to the RP and the RP is the BSR , the next hop is
- * the globally reachable addresse of the RP : NOT link local neighbor but
- * a ipv6 global neighbor...
- * the upstream router is the globally reachable router...
- *
- */
-/* WARNING WARNING WARNING WARNING */
-
- v = &uvifs[srcentry_ptr->incoming];
- if (inet6_equal(&source,&neighbor_addr))
- {
- srcentry_ptr->upstream=v->uv_pim_neighbors;
- return (TRUE);
- }
-
- 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);
-}
-
-
-/*
- * 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;
-{
- mrtentry_t *mrtentry_ptr;
- if_set old_oifs;
- if_set new_oifs;
- if_set new_leaves;
-
-
- mrtentry_ptr = find_route(&sockaddr6_any, group, MRTF_WC, CREATE);
-
- if (mrtentry_ptr == (mrtentry_t *) NULL)
- return;
-
- if ((mrtentry_ptr->incoming == vifi)
- && (!(uvifs[vifi].uv_flags & VIFF_DR)))
- {
- /*
- * The report is received on the iif for this routing entry and I am
- * not the DR for that subnet. Ignore it.
- */
-
- if (mrtentry_ptr->flags & MRTF_NEW)
- delete_mrtentry(mrtentry_ptr);
- return;
- }
-
- IF_DEBUG(DEBUG_MRT)
- log(LOG_DEBUG, 0, "Adding vif %d for group %s", vifi,
- inet6_fmt(&group->sin6_addr));
-
- if (IF_ISSET(vifi, &mrtentry_ptr->leaves))
- return; /* Already a leaf */
- calc_oifs(mrtentry_ptr, &old_oifs);
- IF_COPY(&mrtentry_ptr->leaves, &new_leaves);
- IF_SET(vifi, &new_leaves); /* Add the leaf */
- change_interfaces(mrtentry_ptr,
- mrtentry_ptr->incoming,
- &mrtentry_ptr->joined_oifs,
- &mrtentry_ptr->pruned_oifs,
- &new_leaves,
- &mrtentry_ptr->asserted_oifs, 0);
- calc_oifs(mrtentry_ptr, &new_oifs);
-
- if ((mrtentry_ptr->flags & MRTF_NEW)
- || (IF_ISEMPTY(&old_oifs) && (!IF_ISEMPTY(&new_oifs))))
- {
-
- /*
- * A new created entry or the oifs have changed from NULL to
- * non-NULL.
- */
-
- mrtentry_ptr->flags &= ~MRTF_NEW;
- FIRE_TIMER(mrtentry_ptr->jp_timer); /* Timeout the Join/Prune
- * timer */
- /*
- * TODO: explicitly call the function below?
- * send_pim6_join_prune(mrtentry_ptr->upstream->vifi,
- * mrtentry_ptr->upstream, pim_join_prune_holdtime);
- */
- }
-}
-
-
-/*
- * 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;
-{
- mrtentry_t *mrtentry_ptr;
- mrtentry_t *mrtentry_srcs;
- if_set new_oifs;
- if_set old_oifs;
- if_set new_leaves;
-
- mrtentry_ptr = find_route(&sockaddr6_any, group, MRTF_WC, DONT_CREATE);
- if (mrtentry_ptr == (mrtentry_t *) NULL)
- return;
-
- if (!IF_ISSET(vifi, &mrtentry_ptr->leaves))
- return; /* This interface wasn't leaf */
-
- calc_oifs(mrtentry_ptr, &old_oifs);
- IF_COPY(&mrtentry_ptr->leaves, &new_leaves);
- IF_CLR(vifi, &new_leaves);
- change_interfaces(mrtentry_ptr,
- mrtentry_ptr->incoming,
- &mrtentry_ptr->joined_oifs,
- &mrtentry_ptr->pruned_oifs,
- &new_leaves,
- &mrtentry_ptr->asserted_oifs, 0);
- calc_oifs(mrtentry_ptr, &new_oifs);
- if ((!IF_ISEMPTY(&old_oifs)) && IF_ISEMPTY(&new_oifs))
- {
- /* The result oifs have changed from non-NULL to NULL */
- FIRE_TIMER(mrtentry_ptr->jp_timer); /* Timeout the Join/Prune
- * timer */
- /*
- * TODO: explicitly call the function?
- * send_pim6_join_prune(mrtentry_ptr->upstream->vifi,
- * mrtentry_ptr->upstream, pim_join_prune_holdtime);
- */
- }
- /*
- * Check all (S,G) entries and clear the inherited "leaf" flag. TODO:
- * XXX: This won't work for IGMPv3, because there we don't know whether
- * the (S,G) leaf oif was inherited from the (*,G) entry or was created
- * by source specific IGMP join.
- */
- for (mrtentry_srcs = mrtentry_ptr->group->mrtlink;
- mrtentry_srcs != (mrtentry_t *) NULL;
- mrtentry_srcs = mrtentry_srcs->grpnext)
- {
- IF_COPY(&mrtentry_srcs->leaves, &new_leaves);
- IF_CLR(vifi, &new_leaves);
- change_interfaces(mrtentry_srcs,
- mrtentry_srcs->incoming,
- &mrtentry_srcs->joined_oifs,
- &mrtentry_srcs->pruned_oifs,
- &new_leaves,
- &mrtentry_srcs->asserted_oifs, 0);
- }
-
-}
-
-
-void
-calc_oifs(mrtentry_ptr, oifs_ptr)
- mrtentry_t *mrtentry_ptr;
- if_set *oifs_ptr;
-{
- if_set oifs;
- mrtentry_t *grp_route;
- mrtentry_t *rp_route;
-
- /*
- * oifs = (((copied_outgoing + my_join) - my_prune) + my_leaves) -
- * my_asserted_oifs - incoming_interface, i.e. `leaves` have higher
- * priority than `prunes`, but lower priority than `asserted`. The
- * incoming interface is always deleted from the oifs
- */
-
- if (mrtentry_ptr == (mrtentry_t *) NULL)
- {
- IF_ZERO(oifs_ptr);
- return;
- }
- IF_ZERO(&oifs);
- if (!(mrtentry_ptr->flags & MRTF_PMBR))
- {
- /* Either (*,G) or (S,G). Merge with the oifs from the (*,*,RP) */
- if ((rp_route =
- mrtentry_ptr->group->active_rp_grp->rp->rpentry->mrtlink)
- != (mrtentry_t *) NULL)
- {
- IF_MERGE(&oifs, &rp_route->joined_oifs, &oifs);
- IF_CLR_MASK(&oifs, &rp_route->pruned_oifs);
- IF_MERGE(&oifs, &rp_route->leaves, &oifs);
- IF_CLR_MASK(&oifs, &rp_route->asserted_oifs);
- }
- }
- if (mrtentry_ptr->flags & MRTF_SG)
- {
- /* (S,G) entry. Merge with the oifs from (*,G) */
- if ((grp_route = mrtentry_ptr->group->grp_route)
- != (mrtentry_t *) NULL)
- {
- IF_MERGE(&oifs, &grp_route->joined_oifs, &oifs);
- IF_CLR_MASK(&oifs, &grp_route->pruned_oifs);
- IF_MERGE(&oifs, &grp_route->leaves, &oifs);
- IF_CLR_MASK(&oifs, &grp_route->asserted_oifs);
- }
- }
-
- /* Calculate my own stuff */
- IF_MERGE(&oifs, &mrtentry_ptr->joined_oifs, &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(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_joined_oifs_, new_pruned_oifs,
- new_leaves_, new_asserted_oifs, flags)
- mrtentry_t *mrtentry_ptr;
- vifi_t new_iif;
- if_set *new_joined_oifs_;
- if_set *new_pruned_oifs;
- if_set *new_leaves_;
- if_set *new_asserted_oifs;
- u_int16 flags;
-{
- if_set new_joined_oifs; /* The oifs for that particular
- * mrtentry */
- if_set old_joined_oifs;
- if_set old_pruned_oifs;
- if_set old_leaves;
- if_set new_leaves;
- if_set old_asserted_oifs;
- if_set new_real_oifs; /* The result oifs */
- if_set old_real_oifs;
- vifi_t old_iif;
- rpentry_t *rpentry_ptr;
- cand_rp_t *cand_rp_ptr;
- kernel_cache_t *kernel_cache_ptr;
- rp_grp_entry_t *rp_grp_entry_ptr;
- grpentry_t *grpentry_ptr;
- mrtentry_t *mrtentry_srcs;
- mrtentry_t *mrtentry_wc;
- mrtentry_t *mrtentry_rp;
- int delete_mrtentry_flag;
- int return_value;
- int fire_timer_flag;
-
- if (mrtentry_ptr == (mrtentry_t *) NULL)
- return (0);
-
- IF_COPY(new_joined_oifs_, &new_joined_oifs);
- IF_COPY(new_leaves_, &new_leaves);
-
- old_iif = mrtentry_ptr->incoming;
- IF_COPY(&mrtentry_ptr->joined_oifs, &old_joined_oifs);
- 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_joined_oifs, &mrtentry_ptr->joined_oifs);
- 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)
- && !(flags & MFC_UPDATE_FORCE))
- return 0; /* Nothing to change */
-
- if ((return_value != 0) || (new_iif != old_iif)
- || (flags & MFC_UPDATE_FORCE))
- FIRE_TIMER(mrtentry_ptr->jp_timer);
-
- IF_COPY(&new_real_oifs, &mrtentry_ptr->oifs);
-
- if (mrtentry_ptr->flags & MRTF_PMBR)
- {
- /* (*,*,RP) entry */
- rpentry_ptr = mrtentry_ptr->source;
- if (rpentry_ptr == (rpentry_t *) NULL)
- return (0); /* Shoudn't happen */
- rpentry_ptr->incoming = new_iif;
- cand_rp_ptr = rpentry_ptr->cand_rp;
-
- if (IF_ISEMPTY(&new_real_oifs))
- {
- delete_mrtentry_flag = TRUE;
- }
- else
- {
- delete_mrtentry_flag = FALSE;
-#ifdef RSRR
- rsrr_cache_send(mrtentry_ptr, RSRR_NOTIFICATION_OK);
-#endif /* RSRR */
- }
-
- if (mrtentry_ptr->flags & MRTF_KERNEL_CACHE)
- {
- /* Update the kernel MFC entries */
- if (delete_mrtentry_flag == TRUE)
- /*
- * XXX: no need to send RSRR message. Will do it when delete
- * the mrtentry.
- */
- for (kernel_cache_ptr = mrtentry_ptr->kernel_cache;
- kernel_cache_ptr != (kernel_cache_t *) NULL;
- kernel_cache_ptr = kernel_cache_ptr->next)
- delete_mrtentry_all_kernel_cache(mrtentry_ptr);
- else
- {
- for (kernel_cache_ptr = mrtentry_ptr->kernel_cache;
- kernel_cache_ptr != (kernel_cache_t *) NULL;
- kernel_cache_ptr = kernel_cache_ptr->next)
- /* here mrtentry_ptr->source->address is the RP address */
- k_chg_mfc(mld6_socket, &kernel_cache_ptr->source,
- &kernel_cache_ptr->group, new_iif,
- &new_real_oifs, &mrtentry_ptr->source->address);
- }
- }
-
- /*
- * Update all (*,G) entries associated with this RP. The particular
- * (*,G) outgoing are not changed, but the change in the (*,*,RP)
- * oifs may have affect the real oifs.
- */
- fire_timer_flag = FALSE;
- for (rp_grp_entry_ptr = cand_rp_ptr->rp_grp_next;
- rp_grp_entry_ptr != (rp_grp_entry_t *) NULL;
- rp_grp_entry_ptr = rp_grp_entry_ptr->rp_grp_next)
- {
- for (grpentry_ptr = rp_grp_entry_ptr->grplink;
- grpentry_ptr != (grpentry_t *) NULL;
- grpentry_ptr = grpentry_ptr->rpnext)
- {
- if (grpentry_ptr->grp_route != (mrtentry_t *) NULL)
- {
- if (change_interfaces(grpentry_ptr->grp_route, new_iif,
- &grpentry_ptr->grp_route->joined_oifs,
- &grpentry_ptr->grp_route->pruned_oifs,
- &grpentry_ptr->grp_route->leaves,
- &grpentry_ptr->grp_route->asserted_oifs,
- flags))
- fire_timer_flag = TRUE;
- }
- else
- {
- /* Change all (S,G) entries if no (*,G) */
- for (mrtentry_srcs = grpentry_ptr->mrtlink;
- mrtentry_srcs != (mrtentry_t *) NULL;
- mrtentry_srcs = mrtentry_srcs->grpnext)
- {
- if (mrtentry_srcs->flags & MRTF_RP)
- {
- if (change_interfaces(mrtentry_srcs, new_iif,
- &mrtentry_srcs->joined_oifs,
- &mrtentry_srcs->pruned_oifs,
- &mrtentry_srcs->leaves,
- &mrtentry_srcs->asserted_oifs,
- flags))
- fire_timer_flag = TRUE;
- }
- else
- {
- if (change_interfaces(mrtentry_srcs,
- mrtentry_srcs->incoming,
- &mrtentry_srcs->joined_oifs,
- &mrtentry_srcs->pruned_oifs,
- &mrtentry_srcs->leaves,
- &mrtentry_srcs->asserted_oifs,
- flags))
- fire_timer_flag = TRUE;
- }
- }
- }
- }
- }
- if (fire_timer_flag == TRUE)
- FIRE_TIMER(mrtentry_ptr->jp_timer);
- if (delete_mrtentry_flag == TRUE)
- {
- /*
- * TODO: XXX: trigger a Prune message? Don't delete now, it will
- * be automatically timed out. If want to delete now, don't
- * reference to it anymore! delete_mrtentry(mrtentry_ptr);
- */
- }
- return (return_value); /* (*,*,RP) */
- }
-
- if (mrtentry_ptr->flags & MRTF_WC)
- {
- /* (*,G) entry */
- if (IF_ISEMPTY(&new_real_oifs))
- delete_mrtentry_flag = TRUE;
- else
- {
- delete_mrtentry_flag = FALSE;
-#ifdef RSRR
- rsrr_cache_send(mrtentry_ptr, RSRR_NOTIFICATION_OK);
-#endif /* RSRR */
- }
- if (mrtentry_ptr->flags & MRTF_KERNEL_CACHE)
- {
- if (delete_mrtentry_flag == TRUE)
- delete_mrtentry_all_kernel_cache(mrtentry_ptr);
- else
- {
- for (kernel_cache_ptr = mrtentry_ptr->kernel_cache;
- kernel_cache_ptr != (kernel_cache_t *) NULL;
- kernel_cache_ptr = kernel_cache_ptr->next)
- k_chg_mfc(mld6_socket, &kernel_cache_ptr->source,
- &kernel_cache_ptr->group, new_iif,
- &new_real_oifs, &mrtentry_ptr->group->rpaddr);
- }
- }
- /*
- * Update all (S,G) entries for this group. For the (S,G)RPbit
- * entries the iif is the iif toward the RP; The particular (S,G)
- * oifs are not changed, but the change in the (*,G) oifs may affect
- * the real oifs.
- */
- fire_timer_flag = FALSE;
- for (mrtentry_srcs = mrtentry_ptr->group->mrtlink;
- mrtentry_srcs != (mrtentry_t *) NULL;
- mrtentry_srcs = mrtentry_srcs->grpnext)
- {
- if (mrtentry_srcs->flags & MRTF_RP)
- {
- if (change_interfaces(mrtentry_srcs, new_iif,
- &mrtentry_srcs->joined_oifs,
- &mrtentry_srcs->pruned_oifs,
- &mrtentry_srcs->leaves,
- &mrtentry_srcs->asserted_oifs, flags))
- fire_timer_flag = TRUE;
- }
- else
- {
- if (change_interfaces(mrtentry_srcs, mrtentry_srcs->incoming,
- &mrtentry_srcs->joined_oifs,
- &mrtentry_srcs->pruned_oifs,
- &mrtentry_srcs->leaves,
- &mrtentry_srcs->asserted_oifs, flags))
- fire_timer_flag = TRUE;
- }
- }
-
- if (fire_timer_flag == TRUE)
- FIRE_TIMER(mrtentry_ptr->jp_timer);
- if (delete_mrtentry_flag == TRUE)
- {
- /* TODO: XXX: the oifs are NULL. Send a Prune message? */
- }
- return (return_value); /* (*,G) */
- }
-
- if (mrtentry_ptr->flags & MRTF_SG)
- {
- /* (S,G) entry */
-#ifdef KERNEL_MFC_WC_G
- if_set tmp_oifs;
- mrtentry_t *mrtentry_tmp;
-#endif /* KERNEL_MFC_WC_G */
-
- mrtentry_rp = mrtentry_ptr->group->active_rp_grp->rp->rpentry->mrtlink;
- mrtentry_wc = mrtentry_ptr->group->grp_route;
-#ifdef KERNEL_MFC_WC_G
- /*
- * Check whether (*,*,RP) or (*,G) have different (iif,oifs) from the
- * (S,G). If "yes", then forbid creating (*,G) MFC.
- */
- for (mrtentry_tmp = mrtentry_rp; 1; mrtentry_tmp = mrtentry_wc)
- {
- for (; 1;)
- {
- if (mrtentry_tmp == (mrtentry_t *) NULL)
- break;
- if (mrtentry_tmp->flags & MRTF_MFC_CLONE_SG)
- break;
- if (mrtentry_tmp->incoming != mrtentry_ptr->incoming)
- {
- delete_single_kernel_cache_addr(mrtentry_tmp, IN6ADDR_ANY_N,
- mrtentry_ptr->group->group);
- mrtentry_tmp->flags |= MRTF_MFC_CLONE_SG;
- break;
- }
- calc_oifs(mrtentry_tmp, &tmp_oifs);
- if (!(IF_SAME(&new_real_oifs, &tmp_oifs)))
- mrtentry_tmp->flags |= MRTF_MFC_CLONE_SG;
- break;
- }
- if (mrtentry_tmp == mrtentry_wc)
- break;
- }
-#endif /* KERNEL_MFC_WC_G */
-
- if (IF_ISEMPTY(&new_real_oifs))
- delete_mrtentry_flag = TRUE;
- else
- {
- delete_mrtentry_flag = FALSE;
-#ifdef RSRR
- rsrr_cache_send(mrtentry_ptr, RSRR_NOTIFICATION_OK);
-#endif /* RSRR */
- }
- if (mrtentry_ptr->flags & MRTF_KERNEL_CACHE)
- {
- if (delete_mrtentry_flag == TRUE)
- delete_mrtentry_all_kernel_cache(mrtentry_ptr);
- else
- {
- k_chg_mfc(mld6_socket, &mrtentry_ptr->source->address,
- &mrtentry_ptr->group->group, new_iif, &new_real_oifs,
- &mrtentry_ptr->group->rpaddr);
- }
- }
- if (old_iif != new_iif)
- {
- if (new_iif == mrtentry_ptr->source->incoming)
- {
- /*
- * For example, if this was (S,G)RPbit with iif toward the
- * RP, and now switch to the Shortest Path. The setup of
- * MRTF_SPT flag must be done by the external calling
- * function (triggered only by receiving of a data from the
- * source.)
- */
- mrtentry_ptr->flags &= ~MRTF_RP;
- /*
- * TODO: XXX: delete? Check again where will be the best
- * place to set it. mrtentry_ptr->flags |= MRTF_SPT;
- */
- }
- if (((mrtentry_wc != (mrtentry_t *) NULL)
- && (mrtentry_wc->incoming == new_iif))
- || ((mrtentry_rp != (mrtentry_t *) NULL)
- && (mrtentry_rp->incoming == new_iif)))
- {
- /*
- * If the new iif points toward the RP, reset the SPT flag.
- * (PIM-SM-spec-10.ps pp. 11, 2.10, last sentence of first
- * paragraph.
- */
- /* TODO: XXX: check again! */
-
- mrtentry_ptr->flags &= ~MRTF_SPT;
- mrtentry_ptr->flags |= MRTF_RP;
- }
- }
- /*
- * TODO: XXX: if this is (S,G)RPbit entry and the oifs==(*,G)oifs,
- * then delete the (S,G) entry?? The same if we have (*,*,RP) ?
- */
- if (delete_mrtentry_flag == TRUE)
- {
- /* TODO: XXX: the oifs are NULL. Send a Prune message ? */
- }
- /* TODO: XXX: have the feeling something is missing.... */
- return (return_value); /* (S,G) */
- }
- 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;
-}
-
-
-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;
- case MRT6MSG_WHOLEPKT:
- process_whole_pkt(mld6_recv_buf);
- break;
- default:
- IF_DEBUG(DEBUG_KERN)
- log(LOG_DEBUG, 0, "Unknown kernel_call code");
- break;
- }
-}
-
-
-/*
- * TODO: when cache miss, check the iif, because probably ASSERTS shoult take
- * place
- */
-
-static void
-process_cache_miss(im)
- struct mrt6msg *im;
-{
- static struct sockaddr_in6 source = {sizeof(source) , AF_INET6 };
- static struct sockaddr_in6 mfc_source = {sizeof(source) , AF_INET6 };
- static struct sockaddr_in6 group = {sizeof(group) , AF_INET6 };
-
- static struct sockaddr_in6 rp_addr = {sizeof(source) , AF_INET6 };
- vifi_t iif;
- mrtentry_t *mrtentry_ptr;
- mrtentry_t *mrtentry_rp;
-
- /*
- * 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;
- group.sin6_scope_id = inet6_uvif2scopeid(&group, &uvifs[im->im6_mif]);
- source.sin6_addr = mfc_source.sin6_addr = im->im6_src;
- source.sin6_scope_id = inet6_uvif2scopeid(&source, &uvifs[im->im6_mif]);
- iif = im->im6_mif;
-
- uvifs[iif].uv_cache_miss++;
- IF_DEBUG(DEBUG_MFC)
- log(LOG_DEBUG, 0, "Cache miss, src %s, dst %s, iif %d",
- inet6_fmt(&source.sin6_addr), inet6_fmt(&group.sin6_addr), iif);
-
- /*
- * TODO: XXX: check whether the kernel generates cache miss for the LAN
- * scoped addresses
- */
-
- /* 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))
- goto fail;
-
- /* TODO: check if correct in case the source is one of my addresses */
- /*
- * If I am the DR for this source, create (S,G) and add the register_vif
- * to the oifs.
- */
- if ((uvifs[iif].uv_flags & VIFF_DR)
- && (find_vif_direct_local(&source) == iif))
- {
- mrtentry_ptr = find_route(&source, &group, MRTF_SG, CREATE);
- if (mrtentry_ptr == (mrtentry_t *) NULL)
- {
- goto fail;
- }
-
- mrtentry_ptr->flags &= ~MRTF_NEW;
-
- /* set reg_vif_num as outgoing interface ONLY if I am not the RP */
-
- if (!inet6_equal(&mrtentry_ptr->group->rpaddr, &my_cand_rp_address))
- IF_SET(reg_vif_num, &mrtentry_ptr->joined_oifs);
- change_interfaces(mrtentry_ptr,
- mrtentry_ptr->incoming,
- &mrtentry_ptr->joined_oifs,
- &mrtentry_ptr->pruned_oifs,
- &mrtentry_ptr->leaves,
- &mrtentry_ptr->asserted_oifs, 0);
- }
- else
- {
- mrtentry_ptr = find_route(&source, &group,
- MRTF_SG | MRTF_WC | MRTF_PMBR,
- DONT_CREATE);
- if (mrtentry_ptr == (mrtentry_t *) NULL)
- goto fail;
- }
-
- /*
- * TODO: if there are too many cache miss for the same (S,G), install
- * negative cache entry in the kernel (oif==NULL) to prevent too many
- * upcalls.
- */
- if (mrtentry_ptr->incoming == iif)
- {
- if (!IF_ISEMPTY(&mrtentry_ptr->oifs))
- {
- if (mrtentry_ptr->flags & MRTF_SG)
- {
- /* TODO: check that the RPbit is not set? */
- /* TODO: XXX: TIMER implem. dependency! */
-
- if (mrtentry_ptr->timer < pim_data_timeout)
- SET_TIMER(mrtentry_ptr->timer, pim_data_timeout);
- if (!(mrtentry_ptr->flags & MRTF_SPT))
- {
- if ((mrtentry_rp = mrtentry_ptr->group->grp_route) ==
- (mrtentry_t *) NULL)
- mrtentry_rp = mrtentry_ptr->group->active_rp_grp->rp->rpentry->mrtlink;
- if (mrtentry_rp != (mrtentry_t *) NULL)
- {
- /*
- * Check if the (S,G) iif is different from the (*,G)
- * or (*,*,RP) iif
- */
- if ((mrtentry_ptr->incoming != mrtentry_rp->incoming)
- || (mrtentry_ptr->upstream != mrtentry_rp->upstream))
- {
- mrtentry_ptr->flags |= MRTF_SPT;
- mrtentry_ptr->flags &= ~MRTF_RP;
- }
- }
- }
- }
- if (mrtentry_ptr->flags & MRTF_PMBR)
- rp_addr = mrtentry_ptr->source->address;
- else
- rp_addr = mrtentry_ptr->group->rpaddr;
- mfc_source = source;
-// TODO
-#ifdef KERNEL_MFC_WC_G
- if (mrtentry_ptr->flags & (MRTF_WC | MRTF_PMBR))
- if (!(mrtentry_ptr->flags & MRTF_MFC_CLONE_SG))
- mfc_source = IN6ADDR_ANY_N;
-#endif /* KERNEL_MFC_WC_G */
-
- add_kernel_cache(mrtentry_ptr, &mfc_source, &group, MFC_MOVE_FORCE);
- k_chg_mfc(mld6_socket, &mfc_source, &group, iif, &mrtentry_ptr->oifs,
- &rp_addr);
- /*
- * TODO: XXX: No need for RSRR message, because nothing has
- * changed.
- */
- }
- return; /* iif match */
- }
-
- /* The iif doesn't match */
- if (mrtentry_ptr->flags & MRTF_SG)
- {
- if (mrtentry_ptr->flags & MRTF_SPT)
- /* Arrived on wrong interface */
- goto fail;
- if ((mrtentry_rp = mrtentry_ptr->group->grp_route) ==
- (mrtentry_t *) NULL)
- mrtentry_rp =
- mrtentry_ptr->group->active_rp_grp->rp->rpentry->mrtlink;
- if (mrtentry_rp != (mrtentry_t *) NULL)
- {
- if (mrtentry_rp->incoming == iif)
- {
- /* Forward on (*,G) or (*,*,RP) */
-
-#ifdef KERNEL_MFC_WC_G
- if (!(mrtentry_rp->flags & MRTF_MFC_CLONE_SG))
- mfc_source = IN6ADDR_ANY_N;
-#endif /* KERNEL_MFC_WC_G */
-
- add_kernel_cache(mrtentry_rp, &mfc_source, &group, 0);
- k_chg_mfc(mld6_socket, &mfc_source, &group, iif,
- &mrtentry_rp->oifs, &mrtentry_ptr->group->rpaddr);
-#ifdef RSRR
- rsrr_cache_send(mrtentry_rp, RSRR_NOTIFICATION_OK);
-#endif /* RSRR */
-
- return;
- }
- }
- goto fail;
- }
-
- fail:
- uvifs[iif].uv_cache_notcreated++;
-}
-
-
-/*
- * A multicast packet has been received on wrong iif by the kernel. Check for
- * a matching entry. If there is (S,G) with reset SPTbit and the packet was
- * received on the iif toward the source, this completes the switch to the
- * shortest path and triggers (S,G) prune toward the RP (unless I am the RP).
- * Otherwise, if the packet's iif is in the oiflist of the routing entry,
- * trigger an Assert.
- */
-
-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};
- vifi_t iif;
- mrtentry_t *mrtentry_ptr;
-
- group.sin6_addr = im->im6_dst;
- source.sin6_addr = im->im6_src;
- iif = im->im6_mif;
-
-
- /* 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;
-
-
- /*
- * Ignore if it comes on register vif. register vif is neither SPT iif,
- * neither is used to send asserts out.
- */
- if (uvifs[iif].uv_flags & MIFF_REGISTER)
- return;
-
- mrtentry_ptr = find_route(&source, &group, MRTF_SG | MRTF_WC | MRTF_PMBR,
- DONT_CREATE);
- if (mrtentry_ptr == (mrtentry_t *)NULL)
- return;
-
- /*
- * TODO: check again!
- */
- if (mrtentry_ptr->flags & MRTF_SG)
- {
- if (!(mrtentry_ptr->flags & MRTF_SPT))
- {
- if (mrtentry_ptr->source->incoming == iif)
- {
- /* Switch to the Shortest Path */
- mrtentry_ptr->flags |= MRTF_SPT;
- mrtentry_ptr->flags &= ~MRTF_RP;
- add_kernel_cache(mrtentry_ptr, &source, &group, MFC_MOVE_FORCE);
- k_chg_mfc(mld6_socket, &source, &group, iif,
- &mrtentry_ptr->oifs, &mrtentry_ptr->group->rpaddr);
- FIRE_TIMER(mrtentry_ptr->jp_timer);
-#ifdef RSRR
- rsrr_cache_send(mrtentry_ptr, RSRR_NOTIFICATION_OK);
-#endif /* RSRR */
- return;
- }
- }
- }
-
- /* Trigger an Assert */
- if (IF_ISSET(iif, &mrtentry_ptr->oifs))
- send_pim6_assert(&source, &group, iif, mrtentry_ptr);
-}
-
-/*
- * Receives whole packets from the register vif entries in the kernel, and
- * calls the send_pim_register procedure to encapsulate the packets and
- * unicasts them to the RP.
- */
-static void
-process_whole_pkt(buf)
- char *buf;
-{
-
- send_pim6_register((char *) (buf + sizeof(struct mrt6msg)));
-
-}
-
-
-mrtentry_t *
-switch_shortest_path(source, group)
- struct sockaddr_in6 *source;
- struct sockaddr_in6 *group;
-{
- mrtentry_t *mrtentry_ptr;
-
- /* TODO: XXX: prepare and send immediately the (S,G) join? */
- if ((mrtentry_ptr = find_route(source, group, MRTF_SG, CREATE)) !=
- (mrtentry_t *) NULL)
- {
- if (mrtentry_ptr->flags & MRTF_NEW)
- {
- mrtentry_ptr->flags &= ~MRTF_NEW;
- }
- else
- {
- if (mrtentry_ptr->flags & MRTF_RP)
- {
- /*
- * (S,G)RPbit with iif toward RP. Reset to (S,G) with iif
- * toward S. Delete the kernel cache (if any), because
- * change_interfaces() will reset it with iif toward S and no
- * data will arrive from RP before the switch really occurs.
- */
- mrtentry_ptr->flags &= ~MRTF_RP;
- mrtentry_ptr->incoming = mrtentry_ptr->source->incoming;
- mrtentry_ptr->upstream = mrtentry_ptr->source->upstream;
- delete_mrtentry_all_kernel_cache(mrtentry_ptr);
- change_interfaces(mrtentry_ptr,
- mrtentry_ptr->incoming,
- &mrtentry_ptr->joined_oifs,
- &mrtentry_ptr->pruned_oifs,
- &mrtentry_ptr->leaves,
- &mrtentry_ptr->asserted_oifs, 0);
- }
- }
-
- SET_TIMER(mrtentry_ptr->timer, pim_data_timeout);
- FIRE_TIMER(mrtentry_ptr->jp_timer);
- }
- return (mrtentry_ptr);
-}
diff --git a/usr.sbin/pim6sd/route.h b/usr.sbin/pim6sd/route.h
deleted file mode 100644
index 9dacf1b..0000000
--- a/usr.sbin/pim6sd/route.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 1999 LSIIT Laboratory.
- * 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.
- */
-/*
- * Questions concerning this software should be directed to
- * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
- *
- */
-/*
- * This program has been derived from pim6dd.
- * The pim6dd program is covered by the license in the accompanying file
- * named "LICENSE.pim6dd".
- */
-/*
- * This program has been derived from pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- * $FreeBSD$
- */
-
-
-#ifndef ROUTE_H
-#define ROUTE_H
-
-#include "mrt.h"
-
-extern u_int32 default_source_preference;
-extern u_int32 default_source_metric;
-
-int change_interfaces( mrtentry_t *mrtentry_ptr,vifi_t new_iif,
- if_set *new_joined_oifs,if_set *new_pruned_oifs,if_set *new_leaves_ , if_set *asserted ,
- u_int16 flags);
-
-extern void process_kernel_call __P((void));
-extern int set_incoming __P((srcentry_t *srcentry_ptr,
- int srctype));
-extern vifi_t get_iif __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 pim_nbr_entry_t *find_pim6_nbr __P((struct sockaddr_in6 *source));
-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 mrtentry_t *switch_shortest_path __P((struct sockaddr_in6 *source, struct sockaddr_in6 *group));
-
-
-#endif
diff --git a/usr.sbin/pim6sd/routesock.c b/usr.sbin/pim6sd/routesock.c
deleted file mode 100644
index 04fe948..0000000
--- a/usr.sbin/pim6sd/routesock.c
+++ /dev/null
@@ -1,428 +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
- * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
- *
- */
-/*
- * This program has been derived from pim6dd.
- * The pim6dd program is covered by the license in the accompanying file
- * named "LICENSE.pim6dd".
- */
-/*
- * This program has been derived from pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- */
-/*
- * 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 <sys/types.h>
-#include <errno.h>
-#include <sys/socket.h>
-#include <netinet/in.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 <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <syslog.h>
-#include "vif.h"
-#include "debug.h"
-#include "routesock.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;
- }
-// TODO : UTILITY ?
-#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;
-#if 0
- default:
- /*
- * There are some defined flags other than above 4,
- * but we are not interested in them.
- */
- log(LOG_WARNING, 0,
- "Routesock.c (getmsg) unknown flag : %d",i);
-#endif
- }
- 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/pim6sd/routesock.h b/usr.sbin/pim6sd/routesock.h
deleted file mode 100644
index 48f3efc..0000000
--- a/usr.sbin/pim6sd/routesock.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 1999 LSIIT Laboratory.
- * 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.
- */
-/*
- * Questions concerning this software should be directed to
- * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
- *
- */
-/*
- * This program has been derived from pim6dd.
- * The pim6dd program is covered by the license in the accompanying file
- * named "LICENSE.pim6dd".
- */
-/*
- * This program has been derived from pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- * $FreeBSD$
- */
-
-
-#ifndef ROUTESOCK_H
-#define ROUTESOCK_H
-
-int init_routesock __P((void));
-extern int pid;
-extern int k_req_incoming __P((struct sockaddr_in6 *source,
- struct rpfctl *rpfp));
-
-#endif
diff --git a/usr.sbin/pim6sd/rp.c b/usr.sbin/pim6sd/rp.c
deleted file mode 100644
index e24b71b..0000000
--- a/usr.sbin/pim6sd/rp.c
+++ /dev/null
@@ -1,1207 +0,0 @@
-/*
- * Copyright (C) 1999 LSIIT Laboratory.
- * 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
- * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
- *
- */
-/*
- * This program has been derived from pim6dd.
- * The pim6dd program is covered by the license in the accompanying file
- * named "LICENSE.pim6dd".
- */
-/*
- * This program has been derived from pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- * $FreeBSD$
- */
-
-#include <stdlib.h>
-#include <syslog.h>
-#include "rp.h"
-#include "pim6_proto.h"
-#include "pimd.h"
-#include <netinet6/pim6.h>
-#include "timer.h"
-#include "inet6.h"
-#include "route.h"
-#include "pimd.h"
-#include "debug.h"
-#include "crc.h"
-
-/*
- * The hash function. Stollen from Eddy's (eddy@isi.edu) implementation (for
- * compatibility ;)
- */
-
-#define SEED1 1103515245
-#define SEED2 12345
-#define RP_HASH_VALUE(G, M, C) (((SEED1) * (((SEED1) * ((G) & (M)) + (SEED2)) ^ (C)) + (SEED2)) % 0x80000000)
-#define RP_HASH_VALUE2(P, C) (((SEED1) * (((SEED1) * (P) + (SEED2)) ^ (C)) + (SEED2)) % 0x80000000)
-
-cand_rp_t *cand_rp_list;
-grp_mask_t *grp_mask_list;
-cand_rp_t *segmented_cand_rp_list;
-grp_mask_t *segmented_grp_mask_list;
-u_int16 curr_bsr_fragment_tag;
-u_int8 curr_bsr_priority;
-struct sockaddr_in6 curr_bsr_address;
-struct in6_addr curr_bsr_hash_mask;
-u_int16 pim_bootstrap_timer; /* For electing the BSR and sending
- * Cand-RP-set msgs */
-u_int8 my_bsr_priority;
-struct sockaddr_in6 my_bsr_address;
-struct in6_addr my_bsr_hash_mask;
-u_int8 cand_bsr_flag = FALSE; /* Set to TRUE if I am a candidate
- * BSR */
-struct sockaddr_in6 my_cand_rp_address;
-u_int8 my_cand_rp_priority;
-u_int16 my_cand_rp_holdtime;
-u_int16 my_cand_rp_adv_period; /* The locally configured Cand-RP
- * adv. period. */
-u_int16 my_bsr_period; /* The locally configured BSR
- period */
-u_int16 pim_cand_rp_adv_timer;
-u_int8 cand_rp_flag = FALSE; /* Candidate RP flag */
-struct cand_rp_adv_message_ cand_rp_adv_message;
-struct in6_addr rp_my_ipv6_hashmask;
-
-
-/*
- * Local functions definition.
- */
-static cand_rp_t *add_cand_rp __P((cand_rp_t **used_cand_rp_list ,
- struct sockaddr_in6 *address));
-
-static grp_mask_t *add_grp_mask __P((grp_mask_t ** used_grp_mask_list,
- struct sockaddr_in6 *group_addr,
- struct in6_addr group_mask,
- struct in6_addr hash_mask));
-
-static void delete_grp_mask_entry __P((cand_rp_t ** used_cand_rp_list,
- grp_mask_t ** used_grp_mask_list,
- grp_mask_t * grp_mask_delete));
-
-static void delete_rp_entry __P((cand_rp_t ** used_cand_rp_list,
- grp_mask_t ** used_grp_mask_list,
- cand_rp_t * cand_rp_ptr));
-
-
-void
-init_rp6_and_bsr6()
-{
- /* TODO: if the grplist is not NULL, remap all groups ASAP! */
-
- delete_rp_list(&cand_rp_list, &grp_mask_list);
- delete_rp_list(&segmented_cand_rp_list, &segmented_grp_mask_list);
-
- if (cand_bsr_flag == FALSE)
- {
- /*
- * If I am not candidat BSR, initialize the "current BSR" as having
- * the lowest priority.
- */
-
- curr_bsr_fragment_tag = 0;
- curr_bsr_priority = 0; /* Lowest priority */
- curr_bsr_address = sockaddr6_any; /* Lowest priority */
- MASKLEN_TO_MASK6(RP_DEFAULT_IPV6_HASHMASKLEN, curr_bsr_hash_mask);
- SET_TIMER(pim_bootstrap_timer, PIM_BOOTSTRAP_TIMEOUT);
- }
- else
- {
- curr_bsr_fragment_tag = RANDOM();
- curr_bsr_priority = my_bsr_priority;
- curr_bsr_address = my_bsr_address;
- curr_bsr_hash_mask = my_bsr_hash_mask;
- SET_TIMER(pim_bootstrap_timer, bootstrap_initial_delay());
- }
-
- if (cand_rp_flag != FALSE)
- {
- MASKLEN_TO_MASK6(RP_DEFAULT_IPV6_HASHMASKLEN, rp_my_ipv6_hashmask);
- /* Setup the Cand-RP-Adv-Timer */
- SET_TIMER(pim_cand_rp_adv_timer, RANDOM() % my_cand_rp_adv_period);
- }
-}
-
-
-/*
- * XXX: This implementation is based on section 6.2 of RFC 2362, which
- * is highly dependent on IPv4.
- * We'll have to rewrite the function...
- */
-u_int16
-bootstrap_initial_delay()
-{
-// long AddrDelay;
-// long Delay;
-// long log_mask;
-// int log_of_2;
-// u_int8 bestPriority;
-
- /*
- * The bootstrap timer initial value (if Cand-BSR). It depends of the
- * bootstrap router priority: higher priority has shorter value:
- *
- * Delay = 5 + 2*log_2(1 + bestPriority - myPriority) + AddrDelay;
- *
- * bestPriority = Max(storedPriority, myPriority); if (bestPriority ==
- * myPriority) AddrDelay = log_2(bestAddr - myAddr)/16; else AddrDelay =
- * 2 - (myAddr/2^31);
- */
-
-// bestPriority = max(curr_bsr_priority, my_bsr_priority);
-// if (bestPriority == my_bsr_priority)
- // {
-// AddrDelay = ntohl(curr_bsr_address) - ntohl(my_bsr_address);
- /* Calculate the integer part of log_2 of (bestAddr - myAddr) */
- /*
- * To do so, have to find the position number of the first bit from
- * left which is `1`
- */
-// log_mask = sizeof(AddrDelay) << 3;
-// log_mask = (1 << (log_mask - 1)); /* Set the leftmost bit to
-// * `1` */
-/* for (log_of_2 = (sizeof(AddrDelay) << 3) - 1; log_of_2; log_of_2--)
- {
- if (AddrDelay & log_mask)
- break;
- else
-*/
-// log_mask >>= 1; /* Start shifting `1` on right */
-/* }
- AddrDelay = log_of_2 / 16;
- }
- else
- AddrDelay = 2 - (ntohl(my_bsr_address) / (1 << 31));
-
- Delay = 1 + bestPriority - my_bsr_priority;
- */
- /* Calculate log_2(Delay) */
-// log_mask = sizeof(Delay) << 3;
-// log_mask = (1 << (log_mask - 1));
-/* Set the leftmost bit to `1`
-*/
-
- /* for (log_of_2 = (sizeof(Delay) << 3) - 1; log_of_2; log_of_2--)
- {
- if (Delay & log_mask)
- break;
- else
-*/
-// log_mask >>= 1; /* Start shifting `1` on right */
-
-/* }
-
- Delay = 5 + 2 * Delay + AddrDelay;
- return (u_int16) Delay;
-*/
-
- /* Temporary implementation */
- return (RANDOM()%my_bsr_period);
-}
-
-
-static cand_rp_t *
-add_cand_rp(used_cand_rp_list, address)
- cand_rp_t **used_cand_rp_list;
- struct sockaddr_in6 *address;
-{
- cand_rp_t *cand_rp_prev = (cand_rp_t *) NULL;
- cand_rp_t *cand_rp;
- cand_rp_t *cand_rp_new;
- rpentry_t *rpentry_ptr;
-
- /* The ordering is the bigger first */
- for (cand_rp = *used_cand_rp_list; cand_rp != (cand_rp_t *) NULL;
- cand_rp_prev = cand_rp, cand_rp = cand_rp->next)
- {
-
- if (inet6_greaterthan(&cand_rp->rpentry->address, address))
- continue;
- if (inet6_equal(&cand_rp->rpentry->address , address))
- return (cand_rp);
- else
- break;
- }
-
- /* Create and insert the new entry between cand_rp_prev and cand_rp */
- cand_rp_new = (cand_rp_t *) malloc(sizeof(cand_rp_t));
- cand_rp_new->rp_grp_next = (rp_grp_entry_t *) NULL;
- cand_rp_new->next = cand_rp;
- cand_rp_new->prev = cand_rp_prev;
- if (cand_rp != (cand_rp_t *) NULL)
- cand_rp->prev = cand_rp_new;
- if (cand_rp_prev == (cand_rp_t *) NULL)
- {
- *used_cand_rp_list = cand_rp_new;
- }
- else
- {
- cand_rp_prev->next = cand_rp_new;
- }
-
- rpentry_ptr = (rpentry_t *) malloc(sizeof(rpentry_t));
- cand_rp_new->rpentry = rpentry_ptr;
- rpentry_ptr->next = (srcentry_t *) NULL;
- rpentry_ptr->prev = (srcentry_t *) NULL;
- rpentry_ptr->address = *address;
- rpentry_ptr->mrtlink = (mrtentry_t *) NULL;
- rpentry_ptr->incoming = NO_VIF;
- rpentry_ptr->upstream = (pim_nbr_entry_t *) NULL;
-
- /* TODO: setup the metric and the preference as ~0 (the lowest)? */
-
- rpentry_ptr->metric = ~0;
- rpentry_ptr->preference = ~0;
- RESET_TIMER(rpentry_ptr->timer);
- rpentry_ptr->cand_rp = cand_rp_new;
-
- /*
- * TODO: XXX: check whether there is a route to that RP: if return value
- * is FALSE, then no route.
- */
-
- if (local_address(&rpentry_ptr->address) == NO_VIF)
- {
- /* TODO: check for error and delete */
- set_incoming(rpentry_ptr, PIM_IIF_RP);
- }
- else
- {
- /* TODO: XXX: CHECK!!! */
- rpentry_ptr->incoming = reg_vif_num;
- }
-
- return (cand_rp_new);
-}
-
-
-static grp_mask_t *
-add_grp_mask(used_grp_mask_list, group_addr, group_mask, hash_mask)
- grp_mask_t **used_grp_mask_list;
- struct sockaddr_in6 *group_addr;
- struct in6_addr group_mask;
- struct in6_addr hash_mask;
-{
- grp_mask_t *grp_mask_prev = (grp_mask_t *) NULL;
- grp_mask_t *grp_mask;
- grp_mask_t *grp_mask_tmp;
- struct sockaddr_in6 prefix_h;
- struct sockaddr_in6 prefix_h2;
- int i;
-
- /* I compare on the adresses, inet6_equal use the scope, too */
- prefix_h.sin6_scope_id = prefix_h2.sin6_scope_id = 0;
-
- for (i = 0; i < sizeof(struct in6_addr); i++)
- prefix_h.sin6_addr.s6_addr[i] =
- group_addr->sin6_addr.s6_addr[i] & group_mask.s6_addr[i];
-
- /* The ordering is: bigger first */
- for (grp_mask = *used_grp_mask_list; grp_mask != (grp_mask_t *) NULL;
- grp_mask_prev = grp_mask, grp_mask = grp_mask->next)
- {
- for (i = 0; i < sizeof(struct in6_addr); i++)
- prefix_h2.sin6_addr.s6_addr[i] =
- (grp_mask->group_addr.sin6_addr.s6_addr[i] &
- grp_mask->group_mask.s6_addr[i]);
- if (inet6_greaterthan(&prefix_h2, &prefix_h) )
- continue;
- if (inet6_equal(&prefix_h2, &prefix_h))
- return (grp_mask);
- else
- break;
- }
-
- grp_mask_tmp = (grp_mask_t *) malloc(sizeof(grp_mask_t));
- grp_mask_tmp->grp_rp_next = (rp_grp_entry_t *) NULL;
- grp_mask_tmp->next = grp_mask;
- grp_mask_tmp->prev = grp_mask_prev;
- if (grp_mask != (grp_mask_t *) NULL)
- grp_mask->prev = grp_mask_tmp;
- if (grp_mask_prev == (grp_mask_t *) NULL)
- {
- *used_grp_mask_list = grp_mask_tmp;
- }
- else
- {
- grp_mask_prev->next = grp_mask_tmp;
- }
-
- grp_mask_tmp->group_addr = *group_addr;
- grp_mask_tmp->group_mask = group_mask;
- grp_mask_tmp->hash_mask = hash_mask;
- grp_mask_tmp->group_rp_number = 0;
- grp_mask_tmp->fragment_tag = 0;
- return (grp_mask_tmp);
-}
-
-
-/*
- * TODO: XXX: BUG: a remapping for some groups currently using some other
- * grp_mask may be required by the addition of the new entry!!! Remapping all
- * groups might be a costly process...
- */
-rp_grp_entry_t *
-add_rp_grp_entry(used_cand_rp_list, used_grp_mask_list,
- rp_addr, rp_priority, rp_holdtime, group_addr, group_mask,
- bsr_hash_mask,
- fragment_tag)
- cand_rp_t **used_cand_rp_list;
- grp_mask_t **used_grp_mask_list;
- struct sockaddr_in6 *rp_addr;
- u_int8 rp_priority;
- u_int16 rp_holdtime;
- struct sockaddr_in6 *group_addr;
- struct in6_addr group_mask;
- struct in6_addr bsr_hash_mask;
- u_int16 fragment_tag;
-{
- cand_rp_t *cand_rp_ptr;
- grp_mask_t *grp_mask_ptr;
- rpentry_t *rpentry_ptr;
- rp_grp_entry_t *grp_rp_entry_next;
- rp_grp_entry_t *grp_rp_entry_new;
- rp_grp_entry_t *grp_rp_entry_prev = (rp_grp_entry_t *) NULL;
- grpentry_t *grpentry_ptr_prev;
- grpentry_t *grpentry_ptr_next;
- u_int8 old_highest_priority = ~0; /* Smaller value means
- * "higher" */
-
- /* Input data verification */
- if (!inet6_valid_host(rp_addr))
- return (rp_grp_entry_t *) NULL;
-
- if (!IN6_IS_ADDR_MULTICAST(&group_addr->sin6_addr))
- {
- return (rp_grp_entry_t *) NULL;
- }
- grp_mask_ptr = add_grp_mask(used_grp_mask_list, group_addr, group_mask,
- bsr_hash_mask);
- if (grp_mask_ptr == (grp_mask_t *) NULL)
- return (rp_grp_entry_t *) NULL;
-
- /* TODO: delete */
-#if 0
- if (grp_mask_ptr->grp_rp_next != (rp_grp_entry_t *) NULL)
- {
- /* Check for obsolete grp_rp chain */
- if ((my_bsr_address != curr_bsr_address)
- && (grp_mask_ptr->grp_rp_next->fragment_tag != fragment_tag))
- {
- /* This grp_rp chain is obsolete. Delete it. */
- delete_grp_mask(used_cand_rp_list, used_grp_mask_list,
- group_addr, group_mask);
- grp_mask_ptr = add_grp_mask(used_grp_mask_list, group_addr,
- group_mask, bsr_hash_mask);
- if (grp_mask_ptr == (grp_mask_t *) NULL)
- return (rp_grp_entry_t *) NULL;
- }
- }
-#endif /* 0 */
-
- cand_rp_ptr = add_cand_rp(used_cand_rp_list, rp_addr);
- if (cand_rp_ptr == (cand_rp_t *) NULL)
- {
- if (grp_mask_ptr->grp_rp_next == (rp_grp_entry_t *) NULL)
- delete_grp_mask(used_cand_rp_list, used_grp_mask_list,
- group_addr, group_mask);
- return (rp_grp_entry_t *) NULL;
- }
-
- rpentry_ptr = cand_rp_ptr->rpentry;
- SET_TIMER(rpentry_ptr->timer, rp_holdtime);
- grp_mask_ptr->fragment_tag = fragment_tag; /* For garbage collection */
-
- grp_rp_entry_prev = (rp_grp_entry_t *) NULL;
- grp_rp_entry_next = grp_mask_ptr->grp_rp_next;
-
- /* TODO: improve it */
-
- if (grp_rp_entry_next != (rp_grp_entry_t *) NULL)
- old_highest_priority = grp_rp_entry_next->priority;
- for (; grp_rp_entry_next != (rp_grp_entry_t *) NULL;
- grp_rp_entry_prev = grp_rp_entry_next,
- grp_rp_entry_next = grp_rp_entry_next->grp_rp_next)
- {
- /*
- * Smaller value means higher priority. The entries are sorted with
- * the highest priority first.
- */
- if (grp_rp_entry_next->priority < rp_priority)
- continue;
- if (grp_rp_entry_next->priority > rp_priority)
- break;
-
- /*
- * Here we don't care about higher/lower addresses, because higher
- * address does not guarantee higher hash_value, but anyway we do
- * order with the higher address first, so it will be easier to find
- * an existing entry and update the holdtime.
- */
-
- if (inet6_greaterthan(&grp_rp_entry_next->rp->rpentry->address , rp_addr))
- continue;
- if (inet6_lessthan(&grp_rp_entry_next->rp->rpentry->address , rp_addr))
- break;
-
- /* We already have this entry. Update the holdtime */
- /*
- * TODO: We shoudn't have old existing entry, because with the
- * current implementation all of them will be deleted (different
- * fragment_tag). Debug and check and eventually delete.
- */
-
- grp_rp_entry_next->holdtime = rp_holdtime;
- grp_rp_entry_next->advholdtime = rp_holdtime;
- grp_rp_entry_next->fragment_tag = fragment_tag;
- return (grp_rp_entry_next);
- }
-
- /* Create and link the new entry */
-
- grp_rp_entry_new = (rp_grp_entry_t *) malloc(sizeof(rp_grp_entry_t));
- grp_rp_entry_new->grp_rp_next = grp_rp_entry_next;
- grp_rp_entry_new->grp_rp_prev = grp_rp_entry_prev;
- if (grp_rp_entry_next != (rp_grp_entry_t *) NULL)
- grp_rp_entry_next->grp_rp_prev = grp_rp_entry_new;
- if (grp_rp_entry_prev == (rp_grp_entry_t *) NULL)
- grp_mask_ptr->grp_rp_next = grp_rp_entry_new;
- else
- grp_rp_entry_prev->grp_rp_next = grp_rp_entry_new;
-
- /*
- * The rp_grp_entry chain is not ordered, so just plug the new entry at
- * the head.
- */
-
- grp_rp_entry_new->rp_grp_next = cand_rp_ptr->rp_grp_next;
- if (cand_rp_ptr->rp_grp_next != (rp_grp_entry_t *) NULL)
- cand_rp_ptr->rp_grp_next->rp_grp_prev = grp_rp_entry_new;
- grp_rp_entry_new->rp_grp_prev = (rp_grp_entry_t *) NULL;
- cand_rp_ptr->rp_grp_next = grp_rp_entry_new;
-
- grp_rp_entry_new->holdtime = rp_holdtime;
- grp_rp_entry_new->advholdtime = rp_holdtime;
- grp_rp_entry_new->fragment_tag = fragment_tag;
- grp_rp_entry_new->priority = rp_priority;
- grp_rp_entry_new->group = grp_mask_ptr;
- grp_rp_entry_new->rp = cand_rp_ptr;
- grp_rp_entry_new->grplink = (grpentry_t *) NULL;
-
- grp_mask_ptr->group_rp_number++;
-
- if (grp_mask_ptr->grp_rp_next->priority == rp_priority)
- {
- /* The first entries are with the best priority. */
- /* Adding this rp_grp_entry may result in group_to_rp remapping */
- for (grp_rp_entry_next = grp_mask_ptr->grp_rp_next;
- grp_rp_entry_next != (rp_grp_entry_t *) NULL;
- grp_rp_entry_next = grp_rp_entry_next->grp_rp_next)
- {
- if (grp_rp_entry_next->priority > old_highest_priority)
- break;
- for (grpentry_ptr_prev = grp_rp_entry_next->grplink;
- grpentry_ptr_prev != (grpentry_t *) NULL;)
- {
- grpentry_ptr_next = grpentry_ptr_prev->rpnext;
- remap_grpentry(grpentry_ptr_prev);
- grpentry_ptr_prev = grpentry_ptr_next;
- }
- }
- }
-
- return (grp_rp_entry_new);
-}
-
-
-void
-delete_rp_grp_entry(used_cand_rp_list, used_grp_mask_list,
- rp_grp_entry_delete)
- cand_rp_t **used_cand_rp_list;
- grp_mask_t **used_grp_mask_list;
- rp_grp_entry_t *rp_grp_entry_delete;
-{
- grpentry_t *grpentry_ptr;
- grpentry_t *grpentry_ptr_next;
-
- if (rp_grp_entry_delete == (rp_grp_entry_t *) NULL)
- return;
- rp_grp_entry_delete->group->group_rp_number--;
- /* Free the rp_grp* and grp_rp* links */
- if (rp_grp_entry_delete->rp_grp_prev != (rp_grp_entry_t *) NULL)
- rp_grp_entry_delete->rp_grp_prev->rp_grp_next =
- rp_grp_entry_delete->rp_grp_next;
- else
- rp_grp_entry_delete->rp->rp_grp_next =
- rp_grp_entry_delete->rp_grp_next;
- if (rp_grp_entry_delete->rp_grp_next != (rp_grp_entry_t *) NULL)
- rp_grp_entry_delete->rp_grp_next->rp_grp_prev =
- rp_grp_entry_delete->rp_grp_prev;
-
- if (rp_grp_entry_delete->grp_rp_prev != (rp_grp_entry_t *) NULL)
- rp_grp_entry_delete->grp_rp_prev->grp_rp_next =
- rp_grp_entry_delete->grp_rp_next;
- else
- rp_grp_entry_delete->group->grp_rp_next =
- rp_grp_entry_delete->grp_rp_next;
- if (rp_grp_entry_delete->grp_rp_next != (rp_grp_entry_t *) NULL)
- rp_grp_entry_delete->grp_rp_next->grp_rp_prev =
- rp_grp_entry_delete->grp_rp_prev;
-
- /* Delete Cand-RP or Group-prefix if useless */
- if (rp_grp_entry_delete->group->grp_rp_next ==
- (rp_grp_entry_t *) NULL)
- delete_grp_mask_entry(used_cand_rp_list, used_grp_mask_list,
- rp_grp_entry_delete->group);
- if (rp_grp_entry_delete->rp->rp_grp_next ==
- (rp_grp_entry_t *) NULL)
- delete_rp_entry(used_cand_rp_list, used_grp_mask_list,
- rp_grp_entry_delete->rp);
-
- /* Remap all affected groups */
- for (grpentry_ptr = rp_grp_entry_delete->grplink;
- grpentry_ptr != (grpentry_t *) NULL;
- grpentry_ptr = grpentry_ptr_next)
- {
- grpentry_ptr_next = grpentry_ptr->rpnext;
- remap_grpentry(grpentry_ptr);
- }
-
- free((char *) rp_grp_entry_delete);
-}
-
-/*
- * TODO: XXX: the affected group entries will be partially setup, because may
- * have group routing entry, but NULL pointers to RP. After the call to this
- * function, must remap all group entries ASAP.
- */
-
-void
-delete_rp_list(used_cand_rp_list, used_grp_mask_list)
- cand_rp_t **used_cand_rp_list;
- grp_mask_t **used_grp_mask_list;
-{
- cand_rp_t *cand_rp_ptr,
- *cand_rp_next;
- grp_mask_t *grp_mask_ptr,
- *grp_mask_next;
- rp_grp_entry_t *rp_grp_entry_ptr,
- *rp_grp_entry_next;
- grpentry_t *grpentry_ptr,
- *grpentry_ptr_next;
-
- for (cand_rp_ptr = *used_cand_rp_list;
- cand_rp_ptr != (cand_rp_t *) NULL;)
- {
- cand_rp_next = cand_rp_ptr->next;
- /* Free the mrtentry (if any) for this RP */
- if (cand_rp_ptr->rpentry->mrtlink != (mrtentry_t *) NULL)
- {
- if (cand_rp_ptr->rpentry->mrtlink->flags & MRTF_KERNEL_CACHE)
- delete_mrtentry_all_kernel_cache(cand_rp_ptr->rpentry->mrtlink);
- FREE_MRTENTRY(cand_rp_ptr->rpentry->mrtlink);
- }
- free(cand_rp_ptr->rpentry);
-
- /* Free the whole chain of rp_grp_entry for this RP */
- for (rp_grp_entry_ptr = cand_rp_ptr->rp_grp_next;
- rp_grp_entry_ptr != (rp_grp_entry_t *) NULL;
- rp_grp_entry_ptr = rp_grp_entry_next)
- {
- rp_grp_entry_next = rp_grp_entry_ptr->rp_grp_next;
- /* Clear the RP related invalid pointers for all group entries */
- for (grpentry_ptr = rp_grp_entry_ptr->grplink;
- grpentry_ptr != (grpentry_t *) NULL;
- grpentry_ptr = grpentry_ptr_next)
- {
- grpentry_ptr_next = grpentry_ptr->rpnext;
- grpentry_ptr->rpnext = (grpentry_t *) NULL;
- grpentry_ptr->rpprev = (grpentry_t *) NULL;
- grpentry_ptr->active_rp_grp = (rp_grp_entry_t *) NULL;
- grpentry_ptr->rpaddr = sockaddr6_any;
- }
- free(rp_grp_entry_ptr);
- }
- cand_rp_ptr = cand_rp_next;
- }
- *used_cand_rp_list = (cand_rp_t *) NULL;
-
- for (grp_mask_ptr = *used_grp_mask_list;
- grp_mask_ptr != (grp_mask_t *) NULL;
- grp_mask_ptr = grp_mask_next)
- {
- grp_mask_next = grp_mask_ptr->next;
- free(grp_mask_ptr);
- }
- *used_grp_mask_list = (grp_mask_t *) NULL;
-}
-
-
-void
-delete_grp_mask(used_cand_rp_list, used_grp_mask_list, group_addr, group_mask)
- cand_rp_t **used_cand_rp_list;
- grp_mask_t **used_grp_mask_list;
- struct sockaddr_in6 *group_addr;
- struct in6_addr group_mask;
-{
- grp_mask_t *grp_mask_ptr;
- struct sockaddr_in6 prefix_h;
- struct sockaddr_in6 prefix_h2;
- int i;
-
- for (i = 0; i < sizeof(struct in6_addr); i++)
- prefix_h.sin6_addr.s6_addr[i] = group_addr->sin6_addr.s6_addr[i]&group_mask.s6_addr[i];
-
- for (grp_mask_ptr = *used_grp_mask_list;
- grp_mask_ptr != (grp_mask_t *) NULL;
- grp_mask_ptr = grp_mask_ptr->next)
- {
- for (i = 0; i < sizeof(struct in6_addr); i++)
- prefix_h2.sin6_addr.s6_addr[i] =
- grp_mask_ptr->group_addr.sin6_addr.s6_addr[i]&grp_mask_ptr->group_mask.s6_addr[i];
-
- if (inet6_greaterthan(&prefix_h2, &prefix_h))
- continue;
- if (IN6_ARE_ADDR_EQUAL(&grp_mask_ptr->group_addr.sin6_addr,
- &group_addr->sin6_addr) &&
- IN6_ARE_ADDR_EQUAL(&grp_mask_ptr->group_mask, &group_mask))
- break;
- else
- return; /* Not found */
- }
-
- if (grp_mask_ptr == (grp_mask_t *) NULL)
- return; /* Not found */
-
- delete_grp_mask_entry(used_cand_rp_list, used_grp_mask_list,
- grp_mask_ptr);
-}
-
-static void
-delete_grp_mask_entry(used_cand_rp_list, used_grp_mask_list, grp_mask_delete)
- cand_rp_t **used_cand_rp_list;
- grp_mask_t **used_grp_mask_list;
- grp_mask_t *grp_mask_delete;
-{
- grpentry_t *grpentry_ptr,
- *grpentry_ptr_next;
- rp_grp_entry_t *grp_rp_entry_ptr;
- rp_grp_entry_t *grp_rp_entry_next;
-
- if (grp_mask_delete == (grp_mask_t *) NULL)
- return;
-
- /* Remove from the grp_mask_list first */
-
- if (grp_mask_delete->prev != (grp_mask_t *) NULL)
- grp_mask_delete->prev->next = grp_mask_delete->next;
- else
- *used_grp_mask_list = grp_mask_delete->next;
-
- if (grp_mask_delete->next != (grp_mask_t *) NULL)
- grp_mask_delete->next->prev = grp_mask_delete->prev;
-
- /* Remove all grp_rp entries for this grp_mask */
- for (grp_rp_entry_ptr = grp_mask_delete->grp_rp_next;
- grp_rp_entry_ptr != (rp_grp_entry_t *) NULL;
- grp_rp_entry_ptr = grp_rp_entry_next)
- {
- grp_rp_entry_next = grp_rp_entry_ptr->grp_rp_next;
- /* Remap all related grpentry */
- for (grpentry_ptr = grp_rp_entry_ptr->grplink;
- grpentry_ptr != (grpentry_t *) NULL;
- grpentry_ptr = grpentry_ptr_next)
- {
- grpentry_ptr_next = grpentry_ptr->rpnext;
- remap_grpentry(grpentry_ptr);
-
- }
- if (grp_rp_entry_ptr->rp_grp_prev != (rp_grp_entry_t *) NULL)
- {
- grp_rp_entry_ptr->rp_grp_prev->rp_grp_next =
- grp_rp_entry_ptr->rp_grp_next;
- }
- else
- {
- grp_rp_entry_ptr->rp->rp_grp_next = grp_rp_entry_ptr->rp_grp_next;
- }
- if (grp_rp_entry_ptr->rp_grp_next != (rp_grp_entry_t *) NULL)
- grp_rp_entry_ptr->rp_grp_next->rp_grp_prev =
- grp_rp_entry_ptr->rp_grp_prev;
- if (grp_rp_entry_ptr->rp->rp_grp_next == (rp_grp_entry_t *) NULL)
- {
- /* Delete the RP entry */
- delete_rp_entry(used_cand_rp_list, used_grp_mask_list,
- grp_rp_entry_ptr->rp);
- }
- free(grp_rp_entry_ptr);
- }
-}
-
-/*
- * TODO: currently not used.
- */
-
-void
-delete_rp(used_cand_rp_list, used_grp_mask_list, rp_addr)
- cand_rp_t **used_cand_rp_list;
- grp_mask_t **used_grp_mask_list;
- struct sockaddr_in6 *rp_addr;
-{
- cand_rp_t *cand_rp_ptr;
-
- for (cand_rp_ptr = *used_cand_rp_list;
- cand_rp_ptr != (cand_rp_t *) NULL;
- cand_rp_ptr = cand_rp_ptr->next)
- {
- if (inet6_greaterthan(&cand_rp_ptr->rpentry->address, rp_addr))
- continue;
- if (inet6_equal(&cand_rp_ptr->rpentry->address,rp_addr))
- break;
- else
- return; /* Not found */
- }
-
- if (cand_rp_ptr == (cand_rp_t *) NULL)
- return; /* Not found */
- delete_rp_entry(used_cand_rp_list, used_grp_mask_list, cand_rp_ptr);
-}
-
-
-static void
-delete_rp_entry(used_cand_rp_list, used_grp_mask_list, cand_rp_delete)
- cand_rp_t **used_cand_rp_list;
- grp_mask_t **used_grp_mask_list;
- cand_rp_t *cand_rp_delete;
-{
- rp_grp_entry_t *rp_grp_entry_ptr;
- rp_grp_entry_t *rp_grp_entry_next;
- grpentry_t *grpentry_ptr;
- grpentry_t *grpentry_ptr_next;
-
- if (cand_rp_delete == (cand_rp_t *) NULL)
- return;
-
- /* Remove from the cand-RP chain */
- if (cand_rp_delete->prev != (cand_rp_t *) NULL)
- cand_rp_delete->prev->next = cand_rp_delete->next;
- else
- *used_cand_rp_list = cand_rp_delete->next;
-
- if (cand_rp_delete->next != (cand_rp_t *) NULL)
- cand_rp_delete->next->prev = cand_rp_delete->prev;
-
- if (cand_rp_delete->rpentry->mrtlink != (mrtentry_t *) NULL)
- {
- if (cand_rp_delete->rpentry->mrtlink->flags & MRTF_KERNEL_CACHE)
- delete_mrtentry_all_kernel_cache(cand_rp_delete->rpentry->mrtlink);
- FREE_MRTENTRY(cand_rp_delete->rpentry->mrtlink);
- }
- free((char *) cand_rp_delete->rpentry);
-
- /* Remove all rp_grp entries for this RP */
- for (rp_grp_entry_ptr = cand_rp_delete->rp_grp_next;
- rp_grp_entry_ptr != (rp_grp_entry_t *) NULL;
- rp_grp_entry_ptr = rp_grp_entry_next)
- {
- rp_grp_entry_next = rp_grp_entry_ptr->rp_grp_next;
- rp_grp_entry_ptr->group->group_rp_number--;
-
- /* First take care of the grp_rp chain */
- if (rp_grp_entry_ptr->grp_rp_prev != (rp_grp_entry_t *) NULL)
- {
- rp_grp_entry_ptr->grp_rp_prev->grp_rp_next =
- rp_grp_entry_ptr->grp_rp_next;
- }
- else
- {
- rp_grp_entry_ptr->group->grp_rp_next =
- rp_grp_entry_ptr->grp_rp_next;
- }
- if (rp_grp_entry_ptr->grp_rp_next != (rp_grp_entry_t *) NULL)
- {
- rp_grp_entry_ptr->grp_rp_next->grp_rp_prev =
- rp_grp_entry_ptr->grp_rp_prev;
- }
-
- if (rp_grp_entry_ptr->grp_rp_next == (rp_grp_entry_t *) NULL)
- {
- delete_grp_mask_entry(used_cand_rp_list, used_grp_mask_list,
- rp_grp_entry_ptr->group);
- }
-
- /* Remap the related groups */
- for (grpentry_ptr = rp_grp_entry_ptr->grplink;
- grpentry_ptr != (grpentry_t *) NULL;
- grpentry_ptr = grpentry_ptr_next)
- {
- grpentry_ptr_next = grpentry_ptr->rpnext;
- remap_grpentry(grpentry_ptr);
- }
- free(rp_grp_entry_ptr);
- }
- free((char *) cand_rp_delete);
-}
-
-
-/*
- * Rehash the RP for the group. XXX: currently, every time when
- * remap_grpentry() is called, there has being a good reason to change the
- * RP, so for performancy reasons no check is performed whether the RP will
- * be really different one.
- */
-
-int
-remap_grpentry(grpentry_ptr)
- grpentry_t *grpentry_ptr;
-{
- rpentry_t *rpentry_ptr;
- rp_grp_entry_t *rp_grp_entry_ptr;
- mrtentry_t *grp_route;
- mrtentry_t *mrtentry_ptr;
-
- if (grpentry_ptr == (grpentry_t *) NULL)
- return (FALSE);
-
- /* Remove from the list of all groups matching to the same RP */
- if (grpentry_ptr->rpprev != (grpentry_t *) NULL)
- grpentry_ptr->rpprev->rpnext = grpentry_ptr->rpnext;
- else
- {
- if (grpentry_ptr->active_rp_grp != (rp_grp_entry_t *) NULL)
- grpentry_ptr->active_rp_grp->grplink = grpentry_ptr->rpnext;
- }
- if (grpentry_ptr->rpnext != (grpentry_t *) NULL)
- grpentry_ptr->rpnext->rpprev = grpentry_ptr->rpprev;
-
- rp_grp_entry_ptr = rp_grp_match(&grpentry_ptr->group);
- if (rp_grp_entry_ptr == (rp_grp_entry_t *) NULL)
- {
- /* If cannot remap, delete the group */
- delete_grpentry(grpentry_ptr);
- return (FALSE);
- }
- rpentry_ptr = rp_grp_entry_ptr->rp->rpentry;
-
- /* Add to the new chain of all groups mapping to the same RP */
- grpentry_ptr->rpaddr = rpentry_ptr->address;
- grpentry_ptr->active_rp_grp = rp_grp_entry_ptr;
- grpentry_ptr->rpnext = rp_grp_entry_ptr->grplink;
- if (grpentry_ptr->rpnext != (grpentry_t *) NULL)
- grpentry_ptr->rpnext->rpprev = grpentry_ptr;
- grpentry_ptr->rpprev = (grpentry_t *) NULL;
- rp_grp_entry_ptr->grplink = grpentry_ptr;
-
- if ((grp_route = grpentry_ptr->grp_route) != (mrtentry_t *) NULL)
- {
- grp_route->upstream = rpentry_ptr->upstream;
- grp_route->metric = rpentry_ptr->metric;
- grp_route->preference = rpentry_ptr->preference;
- change_interfaces(grp_route, rpentry_ptr->incoming,
- &grp_route->joined_oifs,
- &grp_route->pruned_oifs,
- &grp_route->leaves,
- &grp_route->asserted_oifs, MFC_UPDATE_FORCE);
- }
-
- for (mrtentry_ptr = grpentry_ptr->mrtlink;
- mrtentry_ptr != (mrtentry_t *) NULL;
- mrtentry_ptr = mrtentry_ptr->grpnext)
- {
- if (!(mrtentry_ptr->flags & MRTF_RP))
- continue;
- mrtentry_ptr->upstream = rpentry_ptr->upstream;
- mrtentry_ptr->metric = rpentry_ptr->metric;
- mrtentry_ptr->preference = rpentry_ptr->preference;
- change_interfaces(mrtentry_ptr, rpentry_ptr->incoming,
- &mrtentry_ptr->joined_oifs,
- &mrtentry_ptr->pruned_oifs,
- &mrtentry_ptr->leaves,
- &mrtentry_ptr->asserted_oifs, MFC_UPDATE_FORCE);
- }
-
- return (TRUE);
-}
-
-
-rpentry_t *
-rp_match(group)
- struct sockaddr_in6 *group;
-{
- rp_grp_entry_t *rp_grp_entry_ptr;
-
- rp_grp_entry_ptr = rp_grp_match(group);
- if (rp_grp_entry_ptr != (rp_grp_entry_t *) NULL)
- return (rp_grp_entry_ptr->rp->rpentry);
- else
- return (rpentry_t *) NULL;
-}
-
-
-rp_grp_entry_t *
-rp_grp_match(group)
- struct sockaddr_in6 *group;
-{
- grp_mask_t *grp_mask_ptr;
- rp_grp_entry_t *grp_rp_entry_ptr;
- rp_grp_entry_t *best_entry = (rp_grp_entry_t *) NULL;
- u_int8 best_priority = ~0; /* Smaller is better */
- u_int32 best_hash_value = 0; /* Bigger is better */
- struct sockaddr_in6 best_address_h; /* Bigger is better */
- u_int32 curr_hash_value = 0;
- struct sockaddr_in6 curr_address_h;
-
- struct sockaddr_in6 prefix_h;
- struct sockaddr_in6 prefix_h2;
- int i;
-
- if (grp_mask_list == (grp_mask_t *) NULL)
- return (rp_grp_entry_t *) NULL;
-
- /* XXX: I compare on the adresses, inet6_equal use the scope too */
- prefix_h.sin6_scope_id = prefix_h2.sin6_scope_id = 0;
-
- for (grp_mask_ptr = grp_mask_list; grp_mask_ptr != (grp_mask_t *) NULL;
- grp_mask_ptr = grp_mask_ptr->next)
- {
- for (i = 0; i < sizeof(struct in6_addr); i++)
- prefix_h2.sin6_addr.s6_addr[i] =
- (grp_mask_ptr->group_addr.sin6_addr.s6_addr[i] &
- grp_mask_ptr->group_mask.s6_addr[i]);
- for (i = 0; i < sizeof(struct in6_addr); i++)
- prefix_h.sin6_addr.s6_addr[i] =
- (group->sin6_addr.s6_addr[i] &
- grp_mask_ptr->group_mask.s6_addr[i]);
-
- /* Search the grp_mask (group_prefix) list */
- if (!inet6_equal(&prefix_h, &prefix_h2))
- continue;
-
- for (grp_rp_entry_ptr = grp_mask_ptr->grp_rp_next;
- grp_rp_entry_ptr != (rp_grp_entry_t *) NULL;
- grp_rp_entry_ptr = grp_rp_entry_ptr->grp_rp_next)
- {
-
- if (best_priority < grp_rp_entry_ptr->priority)
- break;
-
- curr_address_h = grp_rp_entry_ptr->rp->rpentry->address;
-#if 0
- curr_hash_value = RP_HASH_VALUE(crc((char *)&group->sin6_addr,
- sizeof(struct in6_addr)),
- crc((char *)&grp_mask_ptr->hash_mask,
- sizeof(struct in6_addr)),
- crc((char *)&curr_address_h.sin6_addr,
- sizeof(struct in6_addr)));
-#else
- {
- struct in6_addr masked_grp;
- int i;
-
- for (i = 0; i < sizeof(struct in6_addr); i++)
- masked_grp.s6_addr[i] =
- group->sin6_addr.s6_addr[i] &
- grp_mask_ptr->hash_mask.s6_addr[i];
- curr_hash_value = RP_HASH_VALUE2(crc((char *)&masked_grp,
- sizeof(struct in6_addr)),
- crc((char *)&curr_address_h.sin6_addr,
- sizeof(struct in6_addr)));
- }
-#endif
-
- if (best_priority == grp_rp_entry_ptr->priority)
- {
- /* Compare the hash_value and then the addresses */
-
- if (curr_hash_value < best_hash_value)
- continue;
- if (curr_hash_value == best_hash_value)
- if (inet6_lessthan(&curr_address_h ,&best_address_h))
- continue;
- }
-
- /* The current entry in the loop is preferred */
-
- best_entry = grp_rp_entry_ptr;
- best_priority = best_entry->priority;
- best_address_h = curr_address_h;
- best_hash_value = curr_hash_value;
- }
- }
-
-
- if (best_entry == (rp_grp_entry_t *) NULL)
- return (rp_grp_entry_t *) NULL;
-
- IF_DEBUG(DEBUG_PIM_CAND_RP)
- log(LOG_DEBUG,0,"Rp_grp_match found %s for group %s",
- inet6_fmt(&best_entry->rp->rpentry->address.sin6_addr),
- inet6_fmt(&group->sin6_addr));
-
- return (best_entry);
-}
-
-
-rpentry_t *
-rp_find(rp_address)
- struct sockaddr_in6 *rp_address;
-{
- cand_rp_t *cand_rp_ptr;
-
- for (cand_rp_ptr = cand_rp_list; cand_rp_ptr != (cand_rp_t *) NULL;
- cand_rp_ptr = cand_rp_ptr->next)
- {
- if( inet6_greaterthan(&cand_rp_ptr->rpentry->address,rp_address))
- continue;
- if( inet6_equal(&cand_rp_ptr->rpentry->address,rp_address))
- return (cand_rp_ptr->rpentry);
- return (rpentry_t *) NULL;
- }
-
- return (rpentry_t *) NULL;
-}
-
-
-/*
- * Create a bootstrap message in "send_buff" and returns the data size
- * (excluding the IP header and the PIM header) Can be used both by the
- * Bootstrap router to multicast the RP-set or by the DR to unicast it to a
- * new neighbor. It DOES NOT change any timers.
- */
-
-int
-create_pim6_bootstrap_message(send_buff)
- char *send_buff;
-{
- u_int8 *data_ptr;
- grp_mask_t *grp_mask_ptr;
- rp_grp_entry_t *grp_rp_entry_ptr;
- int datalen;
- u_int8 masklen=0;
-
- if (IN6_IS_ADDR_UNSPECIFIED(&curr_bsr_address.sin6_addr))
- return (0);
-
- data_ptr = (u_int8 *) (send_buff + sizeof(struct pim));
-
- if( inet6_equal(&curr_bsr_address , &my_bsr_address ))
- curr_bsr_fragment_tag++;
- PUT_HOSTSHORT(curr_bsr_fragment_tag, data_ptr);
- MASK_TO_MASKLEN6(curr_bsr_hash_mask, masklen);
- PUT_BYTE(masklen, data_ptr);
- PUT_BYTE(curr_bsr_priority, data_ptr);
- PUT_EUADDR6(curr_bsr_address.sin6_addr, data_ptr);
-
- /* TODO: XXX: No fragmentation support (yet) */
-
- for (grp_mask_ptr = grp_mask_list; grp_mask_ptr != (grp_mask_t *) NULL;
- grp_mask_ptr = grp_mask_ptr->next)
- {
- MASK_TO_MASKLEN6(grp_mask_ptr->group_mask, masklen);
- PUT_EGADDR6(grp_mask_ptr->group_addr.sin6_addr, masklen, 0, data_ptr);
- PUT_BYTE(grp_mask_ptr->group_rp_number, data_ptr);
- PUT_BYTE(grp_mask_ptr->group_rp_number, data_ptr); /* TODO: if frag. */
- PUT_HOSTSHORT(0, data_ptr);
- for (grp_rp_entry_ptr = grp_mask_ptr->grp_rp_next;
- grp_rp_entry_ptr != (rp_grp_entry_t *) NULL;
- grp_rp_entry_ptr = grp_rp_entry_ptr->grp_rp_next)
- {
- PUT_EUADDR6(grp_rp_entry_ptr->rp->rpentry->address.sin6_addr, data_ptr);
- PUT_HOSTSHORT(grp_rp_entry_ptr->advholdtime, data_ptr);
- PUT_BYTE(grp_rp_entry_ptr->priority, data_ptr);
- PUT_BYTE(0, data_ptr); /* The reserved field */
- }
- }
-
- datalen = (data_ptr - (u_int8 *) send_buff) - sizeof(struct pim);
-
- return (datalen);
-}
-
-
-/*
- * Check if the rp_addr is the RP for the group corresponding to
- * mrtentry_ptr. Return TRUE or FALSE.
- */
-
-int
-check_mrtentry_rp(mrtentry_ptr, rp_addr)
- mrtentry_t *mrtentry_ptr;
- struct sockaddr_in6 *rp_addr;
-{
- rp_grp_entry_t *rp_grp_entry_ptr;
-
- if (mrtentry_ptr == (mrtentry_t *) NULL)
- return (FALSE);
- if (IN6_IS_ADDR_UNSPECIFIED(&rp_addr->sin6_addr))
- return (FALSE);
- rp_grp_entry_ptr = mrtentry_ptr->group->active_rp_grp;
- if (rp_grp_entry_ptr == (rp_grp_entry_t *) NULL)
- return (FALSE);
- if (inet6_equal(&mrtentry_ptr->group->rpaddr,rp_addr))
- return (TRUE);
- return (FALSE);
-}
diff --git a/usr.sbin/pim6sd/rp.h b/usr.sbin/pim6sd/rp.h
deleted file mode 100644
index a45bc1c..0000000
--- a/usr.sbin/pim6sd/rp.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 1999 LSIIT Laboratory.
- * 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.
- */
-/*
- * Questions concerning this software should be directed to
- * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
- *
- */
-/*
- * This program has been derived from pim6dd.
- * The pim6dd program is covered by the license in the accompanying file
- * named "LICENSE.pim6dd".
- */
-/*
- * This program has been derived from pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- * $FreeBSD$
- */
-
-
-#ifndef RP_H
-#define RP_H
-
-#include "defs.h"
-#include "mrt.h"
-
-extern cand_rp_t *cand_rp_list;
-extern grp_mask_t *grp_mask_list;
-extern cand_rp_t *segmented_cand_rp_list;
-extern grp_mask_t *segmented_grp_mask_list;
-
-extern u_int8 cand_rp_flag;
-extern u_int8 cand_bsr_flag;
-extern u_int8 my_cand_rp_priority;
-extern u_int8 my_bsr_priority;
-extern u_int16 my_cand_rp_adv_period;
-extern u_int16 my_bsr_period;
-extern u_int16 my_cand_rp_holdtime;
-extern struct sockaddr_in6 my_cand_rp_address;
-extern struct sockaddr_in6 my_bsr_address;
-extern struct in6_addr my_bsr_hash_mask;
-extern struct in6_addr curr_bsr_hash_mask;
-extern struct sockaddr_in6 curr_bsr_address;
-extern u_int16 curr_bsr_fragment_tag;
-extern u_int8 curr_bsr_priority;
-extern u_int16 pim_bootstrap_timer;
-extern u_int16 pim_cand_rp_adv_timer;
-
-extern struct cand_rp_adv_message_ {
- u_int8 *buffer;
- u_int8 *insert_data_ptr;
- u_int8 *prefix_cnt_ptr;
- u_int16 message_size;
-} cand_rp_adv_message;
-
-
-extern void init_rp6_and_bsr6 __P((void));
-void delete_rp_list( cand_rp_t **used_cand_rp_list , grp_mask_t **used_grp_mask_list );
-u_int16 bootstrap_initial_delay __P((void));
-extern rpentry_t *rp_match __P((struct sockaddr_in6 *group));
-extern rp_grp_entry_t *rp_grp_match __P((struct sockaddr_in6 *group));
-extern int create_pim6_bootstrap_message __P((char *send_buff));
-
-extern rp_grp_entry_t *add_rp_grp_entry __P((cand_rp_t **used_cand_rp_list,
- grp_mask_t **used_grp_mask_list,
- struct sockaddr_in6 *rp_addr,
- u_int8 rp_priority,
- u_int16 rp_holdtime,
- struct sockaddr_in6 *group_addr,
- struct in6_addr group_mask,
- struct in6_addr bsr_hash_mask,
- u_int16 fragment_tag));
-extern void delete_rp_grp_entry __P((cand_rp_t **used_cand_rp_list,
- grp_mask_t **used_grp_mask_list,
- rp_grp_entry_t *rp_grp_entry_delete));
-extern void delete_grp_mask __P((cand_rp_t **used_cand_rp_list,
- grp_mask_t **used_grp_mask_list,
- struct sockaddr_in6 *group_addr,
- struct in6_addr group_mask));
-extern void delete_rp __P((cand_rp_t **used_cand_rp_list,
- grp_mask_t **used_grp_mask_list,
- struct sockaddr_in6 *rp_addr));
-extern void delete_rp_list __P((cand_rp_t **used_cand_rp_list,
- grp_mask_t **used_grp_mask_list));
-extern rpentry_t *rp_match __P((struct sockaddr_in6 *group));
-extern rp_grp_entry_t *rp_grp_match __P((struct sockaddr_in6 *group));
-extern rpentry_t *rp_find __P((struct sockaddr_in6 *rp_address));
-extern int remap_grpentry __P((grpentry_t *grpentry_ptr));
-extern int check_mrtentry_rp __P((mrtentry_t *mrtentry_ptr,
- struct sockaddr_in6 *rp_addr));
-
-
-
-
-#endif
diff --git a/usr.sbin/pim6sd/timer.c b/usr.sbin/pim6sd/timer.c
deleted file mode 100644
index 44859f2..0000000
--- a/usr.sbin/pim6sd/timer.c
+++ /dev/null
@@ -1,1301 +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
- * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
- *
- */
-/*
- * This program has been derived from pim6dd.
- * The pim6dd program is covered by the license in the accompanying file
- * named "LICENSE.pim6dd".
- */
-/*
- * This program has been derived from pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- * $FreeBSD$
- */
-
-#include <stdlib.h>
-#include <syslog.h>
-#include "pimd.h"
-#include "mrt.h"
-#include "vif.h"
-#include <netinet6/ip6_mroute.h>
-#include "timer.h"
-#include "debug.h"
-#include "rp.h"
-#include "pim6_proto.h"
-#include "mld6.h"
-#include "mld6_proto.h"
-#include "route.h"
-#include "kern.h"
-#include "debug.h"
-#include "inet6.h"
-
-/*
- * Global variables
- */
-/*
- * XXX: The RATE is in bits/s. To include the header overhead, the
- * approximation is 1 byte/s = 10 bits/s `whatever_bytes` is the maximum
- * number of bytes within the test interval.
- */
-
-u_int32 timer_interval=DEFAULT_TIMER_INTERVAL;
-u_int32 pim_reg_rate_bytes =
-(PIM_DEFAULT_REG_RATE * PIM_DEFAULT_REG_RATE_INTERVAL) / 10;
-u_int32 pim_reg_rate_check_interval = PIM_DEFAULT_REG_RATE_INTERVAL;
-u_int32 pim_data_rate_bytes =
-(PIM_DEFAULT_DATA_RATE * PIM_DEFAULT_DATA_RATE_INTERVAL) / 10;
-u_int32 pim_data_rate_check_interval = PIM_DEFAULT_DATA_RATE_INTERVAL;
-u_int32 pim_hello_period = PIM_TIMER_HELLO_PERIOD;
-u_int32 pim_hello_holdtime = PIM_TIMER_HELLO_HOLDTIME;
-u_int32 pim_join_prune_period = PIM_JOIN_PRUNE_PERIOD;
-u_int32 pim_join_prune_holdtime = PIM_JOIN_PRUNE_HOLDTIME;
-u_int32 pim_data_timeout=PIM_DATA_TIMEOUT;
-u_int32 pim_register_suppression_timeout=PIM_REGISTER_SUPPRESSION_TIMEOUT;
-u_int32 pim_register_probe_time=PIM_REGISTER_PROBE_TIME;
-u_int32 pim_assert_timeout=PIM_ASSERT_TIMEOUT;
-
-
-/*
- * 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 */
-
-u_int16 pim_data_rate_timer; /* Used to check periodically the
- * datarate of the active sources and
- * eventually switch to the shortest
- * path (if forwarder) */
-u_int8 pim_data_rate_flag; /* Used to indicate there was a
- * timeout */
-
-u_int16 pim_reg_rate_timer; /* The same as above, but used by the
- * RP to switch to the shortest path
- * and avoid the PIM registers. */
-u_int8 pim_reg_rate_flag;
-u_int8 rate_flag;
-
-/*
- * TODO: XXX: the timers below are not used. Instead, the data rate timer is
- * used.
- */
-u_int16 kernel_cache_timer; /* Used to timeout the kernel cache
- * entries for idle sources */
-u_int16 kernel_cache_check_interval;
-
-/* to request and compare any route changes */
-
-srcentry_t srcentry_save;
-rpentry_t rpentry_save;
-
-/*
- * Init some timers
- */
-void
-init_timers()
-{
- unicast_routing_check_interval = UCAST_ROUTING_CHECK_INTERVAL;
- SET_TIMER(unicast_routing_timer, unicast_routing_check_interval);
-
- /*
- * The routing_check and the rate_check timers are interleaved to reduce
- * the amount of work that has to be done at once.
- */
- /* XXX: for simplicity, both the intervals are the same */
-
- if (pim_data_rate_check_interval < pim_reg_rate_check_interval)
- pim_reg_rate_check_interval = pim_data_rate_check_interval;
-
- SET_TIMER(pim_data_rate_timer, 3 * pim_data_rate_check_interval / 2);
- SET_TIMER(pim_reg_rate_timer, 3 * pim_reg_rate_check_interval / 2);
-
- /*
- * Initialize the srcentry and rpentry 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;
- RESET_TIMER(srcentry_save.timer);
- srcentry_save.cand_rp = (cand_rp_t *) NULL;
-
- rpentry_save.prev = (rpentry_t *) NULL;
- rpentry_save.next = (rpentry_t *) NULL;
- memset(&rpentry_save.address, 0, sizeof(struct sockaddr_in6));
- rpentry_save.address.sin6_len = sizeof(struct sockaddr_in6);
- rpentry_save.address.sin6_family= AF_INET6;
- rpentry_save.mrtlink = (mrtentry_t *) NULL;
- rpentry_save.incoming = NO_VIF;
- rpentry_save.upstream = (pim_nbr_entry_t *) NULL;
- rpentry_save.metric = ~0;
- rpentry_save.preference = ~0;
- RESET_TIMER(rpentry_save.timer);
- rpentry_save.cand_rp = (cand_rp_t *) NULL;
-
-}
-
-
-/*
- * 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 | MIFF_REGISTER))
- 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) {
- v->uv_querier_timo++; /* count statistics */
-
- /* 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.
- */
- /* TODO: XXX: TIMER implem. dependency! */
-
- if (PIM_MESSAGE_HELLO_HOLDTIME_FOREVER == curr_nbr->timer)
- continue;
- IF_NOT_TIMEOUT(curr_nbr->timer)
- continue;
-
- v->uv_pim6_nbr_timo++;
- IF_DEBUG(DEBUG_PIM_HELLO)
- log(LOG_DEBUG, 0,
- "%s on %s is dead , delete it",
- inet6_fmt(&curr_nbr->address.sin6_addr),
- uvifs[curr_nbr->vifi].uv_name);
- delete_pim6_nbr(curr_nbr);
- }
-
- /* PIM_HELLO periodic */
- IF_TIMEOUT(v->uv_pim_hello_timer)
- send_pim6_hello(v, pim_hello_holdtime);
-
- /* MLD6 query periodic */
- IF_TIMEOUT(v->uv_gq_timer)
- query_groups(v);
- }
-
- IF_DEBUG(DEBUG_IF) {
- dump_vifs(log_fp);
- ;
- }
-}
-
-/*
- * Scan the whole routing table and timeout a bunch of timers:
- * - oifs timers
- * - Join/Prune timer
- * - routing entry
- * - Assert timer
- * - Register-Suppression timer
- *
- * - If the global timer for checking the unicast routing has expired, perform
- * also iif/upstream router change verification
- * - If the global timer for checking the data rate has expired, check the
- * number of bytes forwarded after the lastest timeout. If bigger than
- * a given threshold, then switch to the shortest path.
- * If `number_of_bytes == 0`, then delete the kernel cache entry.
- *
- * Only the entries which have the Join/Prune timer expired are sent.
- * In the special case when we have ~(S,G)RPbit Prune entry, we must
- * include any (*,G) or (*,*,RP) XXX: ???? what and why?
- *
- * Below is a table which summarizes the segmantic rules.
- *
- * On the left side is "if A must be included in the J/P message".
- * On the top is "shall/must include B?"
- * "Y" means "MUST include"
- * "SY" means "SHOULD include"
- * "N" means "NO NEED to include"
- * (G is a group that matches to RP)
- *
- * -----------||-----------||-----------
- * || (*,*,RP) || (*,G) || (S,G) ||
- * ||-----------||-----------||-----------||
- * || J | P || J | P || J | P ||
- * ==================================================||
- * J || n/a | n/a || N | Y || N | Y ||
- * (*,*,RP) -----------------------------------------||
- * P || n/a | n/a || SY | N || SY | N ||
- * ==================================================||
- * J || N | N || n/a | n/a || N | Y ||
- * (*,G) -----------------------------------------||
- * P || N | N || n/a | n/a || SY | N ||
- * ==================================================||
- * J || N | N || N | N || n/a | n/a ||
- * (S,G) -----------------------------------------||
- * P || N | N || N | N || n/a | n/a ||
- * ==================================================
- *
- */
-
-void
-age_routes()
-{
- cand_rp_t *cand_rp_ptr;
- grpentry_t *grpentry_ptr;
- grpentry_t *grpentry_ptr_next;
- mrtentry_t *mrtentry_grp;
- mrtentry_t *mrtentry_rp;
- mrtentry_t *mrtentry_wide;
- mrtentry_t *mrtentry_srcs;
- mrtentry_t *mrtentry_srcs_next;
- struct uvif *v;
- vifi_t vifi;
- pim_nbr_entry_t *pim_nbr_ptr;
- int change_flag;
- int rp_action,
- grp_action,
- src_action=0,
- src_action_rp=0;
- int dont_calc_action;
- int did_switch_flag;
- rp_grp_entry_t *rp_grp_entry_ptr;
- kernel_cache_t *kernel_cache_ptr;
- kernel_cache_t *kernel_cache_next;
- u_long curr_bytecnt;
- rpentry_t *rpentry_ptr;
- int update_rp_iif;
- int update_src_iif;
- if_set new_pruned_oifs;
-
- /*
- * Timing out of the global `unicast_routing_timer` and `data_rate_timer`
- */
-
- IF_TIMEOUT(unicast_routing_timer)
- {
- ucast_flag = TRUE;
- SET_TIMER(unicast_routing_timer, unicast_routing_check_interval);
- }
- ELSE
- {
- ucast_flag = FALSE;
- }
-
- IF_TIMEOUT(pim_data_rate_timer)
- {
- pim_data_rate_flag = TRUE;
- SET_TIMER(pim_data_rate_timer, pim_data_rate_check_interval);
- }
- ELSE
- {
- pim_data_rate_flag = FALSE;
- }
-
- IF_TIMEOUT(pim_reg_rate_timer)
- {
- pim_reg_rate_flag = TRUE;
- SET_TIMER(pim_reg_rate_timer, pim_reg_rate_check_interval);
- }
- ELSE
- {
- pim_reg_rate_flag = FALSE;
- }
-
- rate_flag = pim_data_rate_flag | pim_reg_rate_flag;
-
- /* Scan the (*,*,RP) entries */
-
- for (cand_rp_ptr = cand_rp_list; cand_rp_ptr != (cand_rp_t *) NULL;
- cand_rp_ptr = cand_rp_ptr->next)
- {
-
- rpentry_ptr = cand_rp_ptr->rpentry;
-
- /*
- * Need to save only `incoming` and `upstream` to discover unicast
- * route changes. `metric` and `preference` are not interesting for
- * us.
- */
-
- rpentry_save.incoming = rpentry_ptr->incoming;
- rpentry_save.upstream = rpentry_ptr->upstream;
-
- update_rp_iif = FALSE;
- if ((ucast_flag == TRUE) &&
- (!inet6_equal(&rpentry_ptr->address ,&my_cand_rp_address)))
- {
- /*
- * I am not the RP. If I was the RP, then the iif is register_vif
- * and no need to reset it.
- */
-
- if (set_incoming(rpentry_ptr, PIM_IIF_RP) != TRUE)
- {
- /*
- * TODO: XXX: no route to that RP. Panic? There is a high
- * probability the network is partitioning so immediately
- * remapping to other RP is not a good idea. Better wait the
- * Bootstrap mechanism to take care of it and provide me with
- * correct Cand-RP-Set.
- */
- ;
- }
- else
- {
- if ((rpentry_save.upstream != rpentry_ptr->upstream)
- || (rpentry_save.incoming != rpentry_ptr->incoming))
- {
- /*
- * Routing change has occur. Update all (*,G) and
- * (S,G)RPbit iifs mapping to that RP
- */
- update_rp_iif = TRUE;
- }
- }
- }
-
- rp_action = PIM_ACTION_NOTHING;
- mrtentry_rp = cand_rp_ptr->rpentry->mrtlink;
-
- if (mrtentry_rp != (mrtentry_t *) NULL)
- {
- /* outgoing interfaces timers */
-
- change_flag = FALSE;
- for (vifi = 0; vifi < numvifs; vifi++)
- {
- if (IF_ISSET(vifi, &mrtentry_rp->joined_oifs))
- IF_TIMEOUT(mrtentry_rp->vif_timers[vifi])
- {
- uvifs[vifi].uv_outif_timo++;
- IF_CLR(vifi, &mrtentry_rp->joined_oifs);
- change_flag = TRUE;
- }
- }
- if ((change_flag == TRUE) || (update_rp_iif == TRUE))
- {
- change_interfaces(mrtentry_rp,
- rpentry_ptr->incoming,
- &mrtentry_rp->joined_oifs,
- &mrtentry_rp->pruned_oifs,
- &mrtentry_rp->leaves,
- &mrtentry_rp->asserted_oifs, 0);
- mrtentry_rp->upstream = rpentry_ptr->upstream;
- }
-
- if (rate_flag == TRUE)
- {
- /* Check the activity for this entry */
-
- /*
- * XXX: the spec says to start monitoring first the total
- * traffic for all senders for particular (*,*,RP) or (*,G)
- * and if the total traffic exceeds some predefined
- * threshold, then start monitoring the data traffic for each
- * particular sender for this group: (*,G) or (*,*,RP).
- * However, because the kernel cache/traffic info is of the
- * form (S,G), it is easier if we are simply collecting (S,G)
- * traffic all the time.
- *
- * For (*,*,RP) if the number of bytes received between the last
- * check and now exceeds some precalculated value (based on
- * interchecking period and datarate threshold AND if there
- * are directly connected members (i.e. we are their last
- * hop(e) router), then create (S,G) and start initiating
- * (S,G) Join toward the source. The same applies for (*,G).
- * The spec does not say that if the datarate goes below a
- * given threshold, then will switch back to the shared tree,
- * hence after a switch to the source-specific tree occurs, a
- * source with low datarate, but periodically sending will
- * keep the (S,G) states.
- *
- * If a source with kernel cache entry has been idle after the
- * last time a check of the datarate for the whole routing
- * table, then delete its kernel cache entry.
- */
- for (kernel_cache_ptr = mrtentry_rp->kernel_cache;
- kernel_cache_ptr != (kernel_cache_t *) NULL;
- kernel_cache_ptr = kernel_cache_next)
- {
- kernel_cache_next = kernel_cache_ptr->next;
- curr_bytecnt = kernel_cache_ptr->sg_count.bytecnt;
- if (k_get_sg_cnt(udp_socket, &kernel_cache_ptr->source,
- &kernel_cache_ptr->group,
- &kernel_cache_ptr->sg_count)
- || (curr_bytecnt ==
- kernel_cache_ptr->sg_count.bytecnt))
- {
- /*
- * Either for some reason there is no such routing
- * entry or that particular (s,g) was idle. Delete
- * the routing entry from the kernel.
- */
-
- delete_single_kernel_cache(mrtentry_rp,
- kernel_cache_ptr);
- continue;
- }
- /*
- * Check if the datarate was high enough to switch to
- * source specific tree.
- */
- /* Forwarder initiated switch */
-
- did_switch_flag = FALSE;
- if (curr_bytecnt + pim_data_rate_bytes
- < kernel_cache_ptr->sg_count.bytecnt)
- {
- if (vif_forwarder(&mrtentry_rp->leaves,
- &mrtentry_rp->oifs) == TRUE)
- {
-#ifdef KERNEL_MFC_WC_G
-// TODO (one day... :))
- if (kernel_cache_ptr->source == IN6ADDR_ANY_N)
- {
- delete_single_kernel_cache(mrtentry_rp,
- kernel_cache_ptr);
- mrtentry_rp->flags |= MRTF_MFC_CLONE_SG;
- continue;
- }
-#endif /* KERNEL_MFC_WC_G */
- pim6dstat.pim6_trans_spt_forward++;
- switch_shortest_path(&kernel_cache_ptr->source,
- &kernel_cache_ptr->group);
- did_switch_flag = TRUE;
- }
- }
-
- /* RP initiated switch */
-
- if ((did_switch_flag == FALSE)
- && (curr_bytecnt + pim_reg_rate_bytes
- < kernel_cache_ptr->sg_count.bytecnt))
- {
- if (mrtentry_rp->incoming == reg_vif_num)
-
-#ifdef KERNEL_MFC_WC_G
-// TODO (one day :))
- if (kernel_cache_ptr->source == IN6ADDR_ANY_N)
- {
- delete_single_kernel_cache(mrtentry_rp,
- kernel_cache_ptr);
- mrtentry_rp->flags |= MRTF_MFC_CLONE_SG;
- continue;
- }
-#endif /* KERNEL_MFC_WC_G */
- pim6dstat.pim6_trans_spt_rp++;
- switch_shortest_path(&kernel_cache_ptr->source,
- &kernel_cache_ptr->group);
- }
- }
- }
-
- /* Join/Prune timer */
- IF_TIMEOUT(mrtentry_rp->jp_timer)
- {
-
- IF_DEBUG(DEBUG_PIM_JOIN_PRUNE)
- log(LOG_DEBUG,0,"Join/Prune timer expired");
-
- rp_action = join_or_prune(mrtentry_rp,
- mrtentry_rp->upstream);
-
- IF_DEBUG(DEBUG_PIM_JOIN_PRUNE)
- log(LOG_DEBUG,0,"rp_action = %d",rp_action);
-
- if (rp_action != PIM_ACTION_NOTHING)
- add_jp_entry(mrtentry_rp->upstream,
- pim_join_prune_holdtime,
- &sockaddr6_d,
- STAR_STAR_RP_MSK6LEN,
- &mrtentry_rp->source->address,
- SINGLE_SRC_MSK6LEN,
- MRTF_RP | MRTF_WC,
- rp_action);
- SET_TIMER(mrtentry_rp->jp_timer, pim_join_prune_period);
- }
-
- /* Assert timer */
- if (mrtentry_rp->flags & MRTF_ASSERTED)
- {
- IF_TIMEOUT(mrtentry_rp->assert_timer)
- {
- /* TODO: XXX: reset the upstream router now */
- mrtentry_rp->flags &= ~MRTF_ASSERTED;
- }
- }
- /* Register-Suppression timer */
- /*
- * TODO: to reduce the kernel calls, if the timer is running,
- * install a negative cache entry in the kernel?
- */
- /*
- * TODO: can we have Register-Suppression timer for (*,*,RP)?
- * Currently no...
- */
-
- IF_TIMEOUT(mrtentry_rp->rs_timer)
- ;
- /* routing entry */
-
- if ((TIMEOUT(mrtentry_rp->timer))
- && (IF_ISEMPTY(&mrtentry_rp->leaves)))
- {
- pim6dstat.pim6_rtentry_timo++;
- delete_mrtentry(mrtentry_rp);
- }
- } /* mrtentry_rp != NULL */
-
- /* Just in case if that (*,*,RP) was deleted */
-
- mrtentry_rp = cand_rp_ptr->rpentry->mrtlink;
-
- /* Check the (*,G) and (S,G) entries */
-
- for (rp_grp_entry_ptr = cand_rp_ptr->rp_grp_next;
- rp_grp_entry_ptr != (rp_grp_entry_t *) NULL;
- rp_grp_entry_ptr = rp_grp_entry_ptr->rp_grp_next)
- {
-
- for (grpentry_ptr = rp_grp_entry_ptr->grplink;
- grpentry_ptr != (grpentry_t *) NULL;
- grpentry_ptr = grpentry_ptr_next)
- {
- grpentry_ptr_next = grpentry_ptr->rpnext;
- mrtentry_grp = grpentry_ptr->grp_route;
- mrtentry_srcs = grpentry_ptr->mrtlink;
-
- grp_action = PIM_ACTION_NOTHING;
- if (mrtentry_grp != (mrtentry_t *) NULL)
- {
- /* The (*,G) entry */
- /* outgoing interfaces timers */
-
- change_flag = FALSE;
- for (vifi = 0; vifi < numvifs; vifi++)
- {
- if (IF_ISSET(vifi, &mrtentry_grp->joined_oifs))
- IF_TIMEOUT(mrtentry_grp->vif_timers[vifi])
- {
- IF_CLR(vifi, &mrtentry_grp->joined_oifs);
- uvifs[vifi].uv_outif_timo++;
- change_flag = TRUE;
- }
- }
-
- if ((change_flag == TRUE) || (update_rp_iif == TRUE))
- {
- change_interfaces(mrtentry_grp,
- rpentry_ptr->incoming,
- &mrtentry_grp->joined_oifs,
- &mrtentry_grp->pruned_oifs,
- &mrtentry_grp->leaves,
- &mrtentry_grp->asserted_oifs, 0);
- mrtentry_grp->upstream = rpentry_ptr->upstream;
- }
-
- /* Check the sources activity */
-
- if (rate_flag == TRUE)
- {
- for (kernel_cache_ptr = mrtentry_grp->kernel_cache;
- kernel_cache_ptr != (kernel_cache_t *) NULL;
- kernel_cache_ptr = kernel_cache_next)
- {
- kernel_cache_next = kernel_cache_ptr->next;
- curr_bytecnt =
- kernel_cache_ptr->sg_count.bytecnt;
- if (k_get_sg_cnt(udp_socket,
- &kernel_cache_ptr->source,
- &kernel_cache_ptr->group,
- &kernel_cache_ptr->sg_count)
- || (curr_bytecnt ==
- kernel_cache_ptr->sg_count.bytecnt))
- {
- /*
- * Either for whatever reason there is no
- * such routing entry or that particular
- * (s,g) was idle. Delete the routing entry
- * from the kernel.
- */
-
- delete_single_kernel_cache(mrtentry_grp,
- kernel_cache_ptr);
- continue;
- }
-
- /*
- * Check if the datarate was high enough to
- * switch to source specific tree.
- */
- /* Forwarder initiated switch */
-
- did_switch_flag = FALSE;
- if (curr_bytecnt + pim_data_rate_bytes
- < kernel_cache_ptr->sg_count.bytecnt)
- {
- if (vif_forwarder(&mrtentry_grp->leaves,
- &mrtentry_grp->oifs) == TRUE)
- {
-#ifdef KERNEL_MFC_WC_G
-// TODO
- if (kernel_cache_ptr->source
- == IN6ADDR_ANY_N)
- {
- delete_single_kernel_cache(mrtentry_grp, kernel_cache_ptr);
- mrtentry_grp->flags
- |= MRTF_MFC_CLONE_SG;
- continue;
- }
-#endif /* KERNEL_MFC_WC_G */
-
- pim6dstat.pim6_trans_spt_forward++;
- switch_shortest_path(&kernel_cache_ptr->source, &kernel_cache_ptr->group);
- did_switch_flag = TRUE;
- }
- }
-
- /* RP initiated switch */
-
- if ((did_switch_flag == FALSE)
- && (curr_bytecnt + pim_reg_rate_bytes
- < kernel_cache_ptr->sg_count.bytecnt))
- {
- if (mrtentry_grp->incoming == reg_vif_num)
-#ifdef KERNEL_MFC_WC_G
-// TODO
- if (kernel_cache_ptr->source
- == IN6ADDR_ANY_N)
- {
- delete_single_kernel_cache(mrtentry_grp, kernel_cache_ptr);
- mrtentry_grp->flags
- |= MRTF_MFC_CLONE_SG;
- continue;
- }
-#endif /* KERNEL_MFC_WC_G */
- pim6dstat.pim6_trans_spt_rp++;
- switch_shortest_path(&kernel_cache_ptr->source,
- &kernel_cache_ptr->group);
- }
- }
- }
-
- dont_calc_action = FALSE;
- if (rp_action != PIM_ACTION_NOTHING)
- {
- grp_action = join_or_prune(mrtentry_grp,
- mrtentry_grp->upstream);
- dont_calc_action = TRUE;
- if (((rp_action == PIM_ACTION_JOIN)
- && (grp_action == PIM_ACTION_PRUNE))
- || ((rp_action == PIM_ACTION_PRUNE)
- && (grp_action == PIM_ACTION_JOIN)))
- FIRE_TIMER(mrtentry_grp->jp_timer);
- }
-
- /* Join/Prune timer */
-
- IF_TIMEOUT(mrtentry_grp->jp_timer)
- {
- IF_DEBUG(DEBUG_PIM_JOIN_PRUNE)
- log(LOG_DEBUG,0,"Join/Prune timer expired");
-
- if (dont_calc_action != TRUE)
- grp_action = join_or_prune(mrtentry_grp,
- mrtentry_grp->upstream);
-
- IF_DEBUG(DEBUG_PIM_JOIN_PRUNE)
- log(LOG_DEBUG,0,"grp_action = %d",grp_action);
-
- if (grp_action != PIM_ACTION_NOTHING)
- {
- add_jp_entry(mrtentry_grp->upstream,
- pim_join_prune_holdtime,
- &mrtentry_grp->group->group,
- SINGLE_GRP_MSK6LEN,
- &cand_rp_ptr->rpentry->address,
- SINGLE_SRC_MSK6LEN,
- MRTF_RP | MRTF_WC,
- grp_action);
- }
-
- SET_TIMER(mrtentry_grp->jp_timer, pim_join_prune_period);
- }
-
- /* Assert timer */
- if (mrtentry_grp->flags & MRTF_ASSERTED)
- {
- IF_TIMEOUT(mrtentry_grp->assert_timer)
- {
- /* TODO: XXX: reset the upstream router now */
- mrtentry_grp->flags &= ~MRTF_ASSERTED;
- }
- }
- /* Register-Suppression timer */
- /*
- * TODO: to reduce the kernel calls, if the timer is
- * running, install a negative cache entry in the kernel?
- */
- /*
- * TODO: currently cannot have Register-Suppression timer
- * for (*,G) entry, but keep this around.
- */
- IF_TIMEOUT(mrtentry_grp->rs_timer)
- ;
-
- /* routing entry */
-
- if ((TIMEOUT(mrtentry_grp->timer))
- && (IF_ISEMPTY(&mrtentry_grp->leaves)))
- {
- pim6dstat.pim6_rtentry_timo++;
- delete_mrtentry(mrtentry_grp);
- }
- } /* if (mrtentry_grp != NULL) */
-
-
- /* For all (S,G) for this group */
- /* XXX: mrtentry_srcs was set before */
- for (; mrtentry_srcs != (mrtentry_t *) NULL;
- mrtentry_srcs = mrtentry_srcs_next)
- {
- /* routing entry */
- mrtentry_srcs_next = mrtentry_srcs->grpnext;
-
- /* outgoing interfaces timers */
-
- change_flag = FALSE;
- for (vifi = 0; vifi < numvifs; vifi++)
- {
- if (IF_ISSET(vifi, &mrtentry_srcs->joined_oifs))
- {
- /* TODO: checking for reg_num_vif is slow! */
-
- if (vifi != reg_vif_num)
- {
- IF_TIMEOUT(mrtentry_srcs->vif_timers[vifi])
- {
- IF_CLR(vifi,
- &mrtentry_srcs->joined_oifs);
- change_flag = TRUE;
- uvifs[vifi].uv_outif_timo++;
- }
- }
- }
- }
-
- update_src_iif = FALSE;
- if (ucast_flag == TRUE)
- {
- if (!(mrtentry_srcs->flags & MRTF_RP))
- {
- /* iif toward the source */
- srcentry_save.incoming =
- mrtentry_srcs->source->incoming;
- srcentry_save.upstream =
- mrtentry_srcs->source->upstream;
- if (set_incoming(mrtentry_srcs->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_srcs);
- continue;
- }
- else
- {
-
- /* iif info found */
-
- if ((srcentry_save.incoming !=
- mrtentry_srcs->incoming)
- || (srcentry_save.upstream !=
- mrtentry_srcs->upstream))
- {
- /* Route change has occur */
- update_src_iif = TRUE;
- mrtentry_srcs->incoming =
- mrtentry_srcs->source->incoming;
- mrtentry_srcs->upstream =
- mrtentry_srcs->source->upstream;
- }
- }
- }
- else
- {
- /* (S,G)RPBit with iif toward RP */
- if ((rpentry_save.upstream !=
- mrtentry_srcs->upstream)
- || (rpentry_save.incoming !=
- mrtentry_srcs->incoming))
- {
- update_src_iif = TRUE; /* XXX: a hack */
- /* XXX: setup the iif now! */
- mrtentry_srcs->incoming =
- rpentry_ptr->incoming;
- mrtentry_srcs->upstream =
- rpentry_ptr->upstream;
- }
- }
- }
-
- if ((change_flag == TRUE) || (update_src_iif == TRUE))
- /* Flush the changes */
- change_interfaces(mrtentry_srcs,
- mrtentry_srcs->incoming,
- &mrtentry_srcs->joined_oifs,
- &mrtentry_srcs->pruned_oifs,
- &mrtentry_srcs->leaves,
- &mrtentry_srcs->asserted_oifs, 0);
-
- if (rate_flag == TRUE)
- {
- for (kernel_cache_ptr = mrtentry_srcs->kernel_cache;
- kernel_cache_ptr != (kernel_cache_t *) NULL;
- kernel_cache_ptr = kernel_cache_next)
- {
- kernel_cache_next = kernel_cache_ptr->next;
- curr_bytecnt = kernel_cache_ptr->sg_count.bytecnt;
- if (k_get_sg_cnt(udp_socket,
- &kernel_cache_ptr->source,
- &kernel_cache_ptr->group,
- &kernel_cache_ptr->sg_count)
- || (curr_bytecnt ==
- kernel_cache_ptr->sg_count.bytecnt))
- {
- /*
- * Either for some reason there is no such
- * routing entry or that particular (s,g) was
- * idle. Delete the routing entry from the
- * kernel.
- */
-
- delete_single_kernel_cache(mrtentry_srcs,
- kernel_cache_ptr);
- continue;
- }
- /*
- * Check if the datarate was high enough to
- * switch to source specific tree. Need to check
- * only when we have (S,G)RPbit in the forwarder
- * or the RP itself.
- */
-
- if (!(mrtentry_srcs->flags & MRTF_RP))
- continue;
-
- /* Forwarder initiated switch */
-
- did_switch_flag = FALSE;
- if (curr_bytecnt + pim_data_rate_bytes
- < kernel_cache_ptr->sg_count.bytecnt)
- {
- if (vif_forwarder(&mrtentry_srcs->leaves,
- &mrtentry_srcs->oifs)
- == TRUE)
- {
- switch_shortest_path(&kernel_cache_ptr->source, &kernel_cache_ptr->group);
- did_switch_flag = TRUE;
- }
- }
- /* RP initiated switch */
- if ((did_switch_flag == FALSE)
- && (curr_bytecnt + pim_reg_rate_bytes
- < kernel_cache_ptr->sg_count.bytecnt))
- {
- if (mrtentry_srcs->incoming == reg_vif_num)
- switch_shortest_path(&kernel_cache_ptr->source, &kernel_cache_ptr->group);
- }
-
- /*
- * XXX: currentry the spec doesn't say to switch
- * back to the shared tree if low datarate, but
- * if needed to implement, the check must be done
- * here. Don't forget to check whether I am a
- * forwarder for that source.
- */
- }
- }
-
- mrtentry_wide = mrtentry_srcs->group->grp_route;
- if (mrtentry_wide == (mrtentry_t *) NULL)
- mrtentry_wide = mrtentry_rp;
-
- dont_calc_action = FALSE;
- if ((rp_action != PIM_ACTION_NOTHING)
- || (grp_action != PIM_ACTION_NOTHING))
- {
- src_action_rp = join_or_prune(mrtentry_srcs,
- rpentry_ptr->upstream);
- src_action = src_action_rp;
- dont_calc_action = TRUE;
- if (src_action_rp == PIM_ACTION_JOIN)
- {
- if ((grp_action == PIM_ACTION_PRUNE)
- || (rp_action == PIM_ACTION_PRUNE))
- FIRE_TIMER(mrtentry_srcs->jp_timer);
- }
- else
- if (src_action_rp == PIM_ACTION_PRUNE)
- {
- if ((grp_action == PIM_ACTION_JOIN)
- || (rp_action == PIM_ACTION_JOIN))
- FIRE_TIMER(mrtentry_srcs->jp_timer);
- }
- }
-
- /* Join/Prune timer */
-
- IF_TIMEOUT(mrtentry_srcs->jp_timer)
- {
- if ((dont_calc_action != TRUE)
- || (rpentry_ptr->upstream
- != mrtentry_srcs->upstream))
- src_action = join_or_prune(mrtentry_srcs,
- mrtentry_srcs->upstream);
- IF_DEBUG(DEBUG_PIM_JOIN_PRUNE)
- log(LOG_DEBUG,0,"src_action = %d",src_action);
-
- if (src_action != PIM_ACTION_NOTHING)
- add_jp_entry(mrtentry_srcs->upstream,
- pim_join_prune_holdtime,
- &mrtentry_srcs->group->group,
- SINGLE_GRP_MSK6LEN,
- &mrtentry_srcs->source->address,
- SINGLE_SRC_MSK6LEN,
- mrtentry_srcs->flags & MRTF_RP,
- src_action);
- if (mrtentry_wide != (mrtentry_t *) NULL)
- {
- /*
- * Have both (S,G) and (*,G) (or (*,*,RP)). Check
- * if need to send (S,G) PRUNE toward RP
- */
-
- if (mrtentry_srcs->upstream
- != mrtentry_wide->upstream)
- {
- if (dont_calc_action != TRUE)
- src_action_rp =
- join_or_prune(mrtentry_srcs,
- mrtentry_wide->upstream);
- /*
- * XXX: TODO: do error check if src_action ==
- * PIM_ACTION_JOIN, which should be an error.
- */
-
- if (src_action_rp == PIM_ACTION_PRUNE)
- {
- IF_DEBUG(DEBUG_PIM_JOIN_PRUNE)
- log(LOG_DEBUG,0,"src_action = %d",src_action);
- add_jp_entry(mrtentry_wide->upstream,
- pim_join_prune_holdtime,
- &mrtentry_srcs->group->group,
- SINGLE_GRP_MSK6LEN,
- &mrtentry_srcs->source->address,
- SINGLE_SRC_MSK6LEN,
- MRTF_RP,
- src_action_rp);
- }
- }
- }
- SET_TIMER(mrtentry_srcs->jp_timer, pim_join_prune_period);
- }
- /* Assert timer */
- if (mrtentry_srcs->flags & MRTF_ASSERTED)
- {
- IF_TIMEOUT(mrtentry_srcs->assert_timer)
- {
- /* TODO: XXX: reset the upstream router now */
- mrtentry_srcs->flags &= ~MRTF_ASSERTED;
- }
- }
- /* Register-Suppression timer */
- /*
- * TODO: to reduce the kernel calls, if the timer is
- * running, install a negative cache entry in the kernel?
- */
-
- IF_TIMER_SET(mrtentry_srcs->rs_timer)
- {
- IF_TIMEOUT(mrtentry_srcs->rs_timer)
- {
- /* Start encapsulating the packets */
- IF_COPY(&mrtentry_srcs->pruned_oifs,
- &new_pruned_oifs);
- IF_CLR(reg_vif_num, &new_pruned_oifs);
- change_interfaces(mrtentry_srcs,
- mrtentry_srcs->incoming,
- &mrtentry_srcs->joined_oifs,
- &new_pruned_oifs,
- &mrtentry_srcs->leaves,
- &mrtentry_srcs->asserted_oifs, 0);
- }
- ELSE
- {
- /*
- * The register suppression timer is running.
- * Check whether it is time to send
- * PIM_NULL_REGISTER.
- */
- /* TODO: XXX: TIMER implem. dependency! */
-
- if (mrtentry_srcs->rs_timer
- <= pim_register_probe_time)
- {
- /* Time to send a PIM_NULL_REGISTER */
- /*
- * XXX: a (bad) hack! This will be sending
- * periodically NULL_REGISTERS between
- * pim_register_probe_time and 0. Well,
- * because PROBE_TIME is 5 secs , it will
- * happen only once ( if granularity is 5 and prob 5!)
- * , so it helps to avoid
- * adding a flag to the routing entry whether
- * a NULL_REGISTER was sent.
- */
- send_pim6_null_register(mrtentry_srcs);
- }
- }
- }
-
- /* routing entry */
- if (TIMEOUT(mrtentry_srcs->timer))
- {
- pim6dstat.pim6_rtentry_timo++;
-
- if (IF_ISEMPTY(&mrtentry_srcs->leaves))
- {
- delete_mrtentry(mrtentry_srcs);
- continue;
- }
- /*
- * XXX: if DR, Register suppressed, and leaf oif
- * inherited from (*,G), the directly connected
- * source is not active anymore, this (S,G) entry
- * won't timeout. Check if the leaf oifs are
- * inherited from (*,G); if true. delete the (S,G)
- * entry.
- */
-
- if (mrtentry_srcs->group->grp_route
- != (mrtentry_t *) NULL)
- {
- if_set r_and, r_xor;
- vif_and(&mrtentry_srcs->group->grp_route->leaves,
- &mrtentry_srcs->leaves,
- &r_and);
- vif_xor(&r_and ,&mrtentry_srcs->leaves,
- &r_xor);
- if (IF_ISEMPTY(&r_xor))
- {
- delete_mrtentry(mrtentry_srcs);
- continue;
- }
- }
- }
- } /* End of (S,G) loop */
- } /* End of (*,G) loop */
- }
- } /* For all cand RPs */
-
- /* TODO: check again! */
- for (vifi = 0, v = &uvifs[0]; vifi < numvifs; vifi++, v++)
- {
- /* Send all pending Join/Prune messages */
- for (pim_nbr_ptr = v->uv_pim_neighbors;
- pim_nbr_ptr != (pim_nbr_entry_t *) NULL;
- pim_nbr_ptr = pim_nbr_ptr->next)
- {
- pack_and_send_jp6_message(pim_nbr_ptr);
- }
- }
-
- IF_DEBUG(DEBUG_PIM_MRT)
- dump_pim_mrt(log_fp);
- return;
-}
-
-
-/*
- * TODO: timeout the RP-group mapping entries during the scan of the whole
- * routing table?
- */
-void
-age_misc()
-{
- rp_grp_entry_t *rp_grp_entry_ptr;
- rp_grp_entry_t *rp_grp_entry_next;
- grp_mask_t *grp_mask_ptr;
- grp_mask_t *grp_mask_next;
-
- /* Timeout the Cand-RP-set entries */
- for (grp_mask_ptr = grp_mask_list;
- grp_mask_ptr != (grp_mask_t *) NULL;
- grp_mask_ptr = grp_mask_next)
- {
- /*
- * If we timeout an entry, the grp_mask_ptr entry might be removed.
- */
- grp_mask_next = grp_mask_ptr->next;
- for (rp_grp_entry_ptr = grp_mask_ptr->grp_rp_next;
- rp_grp_entry_ptr != (rp_grp_entry_t *) NULL;
- rp_grp_entry_ptr = rp_grp_entry_next)
- {
- rp_grp_entry_next = rp_grp_entry_ptr->grp_rp_next;
- IF_TIMEOUT(rp_grp_entry_ptr->holdtime) {
- delete_rp_grp_entry(&cand_rp_list, &grp_mask_list,
- rp_grp_entry_ptr);
- pim6dstat.pim6_rpgrp_timo++;
- }
- }
- }
-
- /* Cand-RP-Adv timer */
- if (cand_rp_flag == TRUE)
- {
- IF_TIMEOUT(pim_cand_rp_adv_timer)
- {
- send_pim6_cand_rp_adv();
- SET_TIMER(pim_cand_rp_adv_timer, my_cand_rp_adv_period);
- }
- }
-
- /* bootstrap-timer */
-
- IF_TIMEOUT(pim_bootstrap_timer)
- {
- pim6dstat.pim6_bootstrap_timo++;
-
- if (cand_bsr_flag == FALSE)
- {
- /*
- * If I am not Cand-BSR, start accepting Bootstrap messages from
- * anyone. XXX: Even if the BSR has timeout, the existing
- * Cand-RP-Set is kept.
- */
- curr_bsr_fragment_tag = 0;
- curr_bsr_priority = 0; /* Lowest priority */
- memset(&curr_bsr_address, 0, sizeof(struct sockaddr_in6));
- curr_bsr_address.sin6_len = sizeof(struct sockaddr_in6);
- curr_bsr_address.sin6_family = AF_INET6;
- MASKLEN_TO_MASK6(RP_DEFAULT_IPV6_HASHMASKLEN, curr_bsr_hash_mask);
- SET_TIMER(pim_bootstrap_timer, PIM_BOOTSTRAP_TIMEOUT);
- }
- else
- {
- /* I am Cand-BSR, so set the current BSR to me */
- if (inet6_equal(&curr_bsr_address, &my_bsr_address))
- {
- SET_TIMER(pim_bootstrap_timer, my_bsr_period);
- send_pim6_bootstrap();
- }
- else
- {
- /*
- * Short delay before becoming the BSR and start sending of
- * the Cand-RP set (to reduce the transient control
- * overhead).
- */
- SET_TIMER(pim_bootstrap_timer, bootstrap_initial_delay());
- curr_bsr_fragment_tag = RANDOM();
- curr_bsr_priority = my_bsr_priority;
- curr_bsr_address = my_bsr_address;
- memcpy(&curr_bsr_hash_mask , &my_bsr_hash_mask , sizeof(struct in6_addr));
- }
- }
- }
-
-
- IF_DEBUG(DEBUG_PIM_BOOTSTRAP | DEBUG_PIM_CAND_RP)
- dump_rp_set(log_fp);
- /* TODO: XXX: anything else to timeout */
-}
diff --git a/usr.sbin/pim6sd/timer.h b/usr.sbin/pim6sd/timer.h
deleted file mode 100644
index 41e6f44..0000000
--- a/usr.sbin/pim6sd/timer.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 1999 LSIIT Laboratory.
- * 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.
- */
-/*
- * Questions concerning this software should be directed to
- * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
- *
- */
-/*
- * This program has been derived from pim6dd.
- * The pim6dd program is covered by the license in the accompanying file
- * named "LICENSE.pim6dd".
- */
-/*
- * This program has been derived from pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- * $FreeBSD$
- */
-
-
-#ifndef TIMER_H
-#define TIMER_H
-
-/* the default granularity if not specified in the config file */
-
-#define DEFAULT_TIMER_INTERVAL 5
-
-/* For timeout. The timers count down */
-
-#define SET_TIMER(timer, value) (timer) = (value)
-#define RESET_TIMER(timer) (timer) = 0
-#define COPY_TIMER(timer_1, timer_2) (timer_2) = (timer_1)
-#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_TIMER_NOT_SET(timer) if ((timer) <= 0)
-
-#define IF_TIMEOUT(timer) \
- if (!((timer) -= (MIN(timer, timer_interval))))
-
-#define IF_NOT_TIMEOUT(timer) \
- if ((timer) -= (MIN(timer, timer_interval)))
-
-#define TIMEOUT(timer) \
- (!((timer) -= (MIN(timer, timer_interval))))
-
-#define NOT_TIMEOUT(timer) \
- ((timer) -= (MIN(timer, timer_interval)))
-
-
-extern u_int32 pim_reg_rate_bytes;
-extern u_int32 pim_reg_rate_check_interval;
-extern u_int32 pim_data_rate_bytes;
-extern u_int32 pim_data_rate_check_interval;
-extern u_int32 pim_hello_period;
-extern u_int32 pim_hello_holdtime;
-extern u_int32 timer_interval;
-extern u_int32 pim_join_prune_period;
-extern u_int32 pim_join_prune_holdtime;
-extern u_int32 pim_data_timeout;
-extern u_int32 pim_register_suppression_timeout;
-extern u_int32 pim_register_probe_time;
-extern u_int32 pim_assert_timeout;
-
-extern void init_timers __P((void));
-extern void init_timers __P((void));
-extern void age_vifs __P((void));
-extern void age_routes __P((void));
-extern void age_misc __P((void));
-
-
-#endif
diff --git a/usr.sbin/pim6sd/trace.c b/usr.sbin/pim6sd/trace.c
deleted file mode 100644
index f13abae..0000000
--- a/usr.sbin/pim6sd/trace.c
+++ /dev/null
@@ -1,558 +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.7 1999/09/16 08:45:45 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 <sys/types.h>
-#include <sys/socket.h>
-#include "vif.h"
-#include "inet6.h"
-#include <sys/ioctl.h>
-#include <sys/uio.h>
-#include <errno.h>
-#include <net/if.h>
-#if defined(__FreeBSD__) && __FreeBSD__ >= 3
-#include <net/if_var.h>
-#endif
-#include <netinet/in.h>
-#include <netinet/icmp6.h>
-#include <netinet/ip6.h>
-#include <netinet6/ip6_mroute.h>
-#include <netinet6/in6_var.h>
-#include <arpa/inet.h>
-#include <stdlib.h>
-#include <syslog.h>
-#include <string.h>
-#include "defs.h"
-#include "mld6.h"
-#include "kern.h"
-#include "debug.h"
-#include "mld6_proto.h"
-#include "route.h"
-#include "rp.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;
- rpentry_t *rpentry_ptr;
-
- /* 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 */
- }
-
- /*
- * 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;
-
- 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 */
- 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 {
- 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/pim6sd/trace.h b/usr.sbin/pim6sd/trace.h
deleted file mode 100644
index 4a5aa6b..0000000
--- a/usr.sbin/pim6sd/trace.h
+++ /dev/null
@@ -1,210 +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/09 15:47:11 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$
- */
-
-#ifndef TRACE_H
-#define TRACE_H
-
-/*
- * 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)
-
-void accept_mtrace __P((struct sockaddr_in6 *, struct in6_addr *,
- struct in6_addr *, int, char *, u_int, int));
-#endif /* TRACE_H */
diff --git a/usr.sbin/pim6sd/var.h b/usr.sbin/pim6sd/var.h
deleted file mode 100644
index 93556e0..0000000
--- a/usr.sbin/pim6sd/var.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 1995, 1996, 1997, and 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$
- */
-/* YIPS @(#)$Id: var.h,v 1.1 1999/10/29 09:04:54 jinmei Exp $ */
-
-#if !defined(_VAR_H_)
-#define _VAR_H_
-
-#include <sys/socket.h>
-
-#define MAX3(a,b,c) (a > b ? (a > c ? a : c) : (b > c ? b : c))
-
-#define CALLOC(size, cast) (cast)calloc(1, (size))
-
-#define ISSET(exp, bit) (((exp) & (bit)) == (bit))
-
-#define ATOX(c) \
- (isdigit(c) ? (c - '0') : (isupper(c) ? (c - 'A' + 10) : (c - 'a' + 10) ))
-
-#define LALIGN(a) \
- ((a) > 0 ? ((a) &~ (sizeof(long) - 1)) : sizeof(long))
-
-#define RNDUP(a) \
- ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
-
-#define BUFADDRSIZE 128
-#define INET_NTOP(addr, buf) \
- inet_ntop(((struct sockaddr *)(addr))->sa_family, _INADDRBYSA(addr), buf, sizeof(buf))
-
-#define GETNAMEINFO(x, y, z) \
- getnameinfo((x), (x)->sa_len, (y), sizeof(y), (z), sizeof(z), \
- NI_NUMERICHOST | NI_NUMERICSERV)
-
-#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
-#endif /*!defined(_VAR_H_)*/
diff --git a/usr.sbin/pim6sd/vers.c b/usr.sbin/pim6sd/vers.c
deleted file mode 100644
index 5264529..0000000
--- a/usr.sbin/pim6sd/vers.c
+++ /dev/null
@@ -1,2 +0,0 @@
-/* $FreeBSD$ */
-char todaysversion[]="2.1.0-alpha23";
diff --git a/usr.sbin/pim6sd/vif.c b/usr.sbin/pim6sd/vif.c
deleted file mode 100644
index 2664e46..0000000
--- a/usr.sbin/pim6sd/vif.c
+++ /dev/null
@@ -1,824 +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
- * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
- *
- */
-/*
- * This program has been derived from pim6dd.
- * The pim6dd program is covered by the license in the accompanying file
- * named "LICENSE.pim6dd".
- */
-/*
- * This program has been derived from pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- */
-/*
- * 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/ioctl.h>
-#include <errno.h>
-#include <syslog.h>
-#include <string.h>
-#include <stdlib.h>
-#include "vif.h"
-#include "mld6.h"
-#include "pim6.h"
-#include "pimd.h"
-#include "route.h"
-#include "config.h"
-#include "inet6.h"
-#include "kern.h"
-#include "mld6_proto.h"
-#include "pim6_proto.h"
-#include "mrt.h"
-#include "debug.h"
-#include "timer.h"
-
-struct uvif uvifs[MAXMIFS]; /*the list of virtualsinterfaces */
-vifi_t numvifs; /*total number of interface */
-int vifs_down;
-vifi_t reg_vif_num; /*register interface*/
-int phys_vif; /* An enabled vif that has a global address */
-int udp_socket;
-int total_interfaces;
-if_set if_nullset;
-if_set if_result;
-
-int init_reg_vif __P((void));
-void start_all_vifs __P((void));
-void start_vif __P((vifi_t vifi));
-void stop_vif __P((vifi_t vivi));
-int update_reg_vif __P((vifi_t register_vifi));
-
-extern int cfparse __P((int, int));
-
-void init_vifs()
-{
- vifi_t vifi;
- struct uvif *v;
- int enabled_vifs;
-
- numvifs = 0;
- reg_vif_num = NO_VIF;
-
- /*
- * 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 all the interfaces ... */
-
- for(vifi = 0,v=uvifs; vifi < MAXVIFS; ++ vifi, ++v)
- {
- memset(v,0,sizeof(*v)); /* everything is zeroed => NULL , pointer NULL , addrANY ...) */
- v->uv_metric = DEFAULT_METRIC;
- v->uv_rate_limit = DEFAULT_PHY_RATE_LIMIT;
- strncpy(v->uv_name,"",IFNAMSIZ);
- v->uv_local_pref = default_source_preference;
- v->uv_local_metric = default_source_metric;
- }
- IF_DEBUG(DEBUG_IF)
- log(LOG_DEBUG,0,"Interfaces world initialized...");
- IF_DEBUG(DEBUG_IF)
- log(LOG_DEBUG,0,"Getting vifs from kernel");
- config_vifs_from_kernel();
- if (max_global_address() == NULL)
- log(LOG_ERR, 0, "There's no global address");
- IF_DEBUG(DEBUG_IF)
- log(LOG_DEBUG,0,"Getting vifs from %s",configfilename);
-
- /* read config from file */
- if (cfparse(1, 0) != 0)
- log(LOG_ERR, 0, "fatal error in parsing the config file");
-
- enabled_vifs = 0;
- phys_vif = -1;
-
- for( vifi = 0, v = uvifs ; vifi < numvifs ; ++ vifi,++v)
- {
- if(v->uv_flags & (VIFF_DISABLED | VIFF_DOWN | MIFF_REGISTER))
- continue;
- if(v->uv_linklocal == NULL)
- log(LOG_ERR,0,"there is no link-local address on vif %s",v->uv_name);
- 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 vifs" : "only one enabled vif" );
-
- memset(&if_nullset,0,sizeof(if_nullset));
- k_init_pim(mld6_socket);
- IF_DEBUG(DEBUG_PIM_DETAIL)
- log(LOG_DEBUG,0,"Pim kernel initialization done");
-
-
- /* Add a dummy virtual interface to support Registers in the kernel. */
- init_reg_vif();
-
- start_all_vifs();
-
-}
-int init_reg_vif()
-{
- struct uvif *v;
- vifi_t i;
-
- v = &uvifs[numvifs];
- if (( numvifs+1 ) == MAXVIFS )
- {
- /* Exit the program! The PIM router must have a Register vif */
- log(LOG_ERR, 0,
- "cannot install the Register vif: too many interfaces");
- /* To make lint happy */
- return (FALSE);
- }
-
- /*
- * So far in PIM we need only one register vif and we save its number in
- * the global reg_vif_num.
- */
-
-
- reg_vif_num = numvifs;
-
- /* Use the address of the first available physical interface to
- * create the register vif.
- */
-
- for(i =0 ; i < numvifs ; i++)
- {
- if(uvifs[i].uv_flags & (VIFF_DOWN | VIFF_DISABLED | MIFF_REGISTER))
- continue;
- else
- break;
- }
- if( i >= numvifs)
- {
- log(LOG_ERR, 0, "No physical interface enabled");
- return -1;
- }
-
-
- memcpy(v,&uvifs[i],sizeof(*v));
- strncpy(v->uv_name,"register_mif0",IFNAMSIZ);
- v->uv_flags = MIFF_REGISTER;
-
-#ifdef PIM_EXPERIMENTAL
- v->uv_flags |= MIFF_REGISTER_KERNEL_ENCAP;
-#endif
-
- IF_DEBUG(DEBUG_IF)
- log(LOG_DEBUG,0,"Interface %s (subnet %s) ,installed on vif #%u - rate = %d",
- v->uv_name,net6name(&v->uv_prefix.sin6_addr,&v->uv_subnetmask),
- reg_vif_num,v->uv_rate_limit);
-
- numvifs++;
- total_interfaces++;
- return 0;
-}
-
-void start_all_vifs()
-{
- vifi_t vifi;
- struct uvif *v;
- u_int action;
-
-
- /* Start first the NON-REGISTER vifs */
-
- for(action=0; ;action = MIFF_REGISTER )
- {
- for(vifi= 0,v = uvifs;vifi < numvifs ; ++vifi, ++v)
- {
- if (( v->uv_flags & MIFF_REGISTER ) ^ action )
- /* If starting non-registers but the vif is a register
- * or if starting registers, but the interface is not
- * a register, then just continue.
- */
- continue;
-
- if ( v->uv_flags & (VIFF_DISABLED | VIFF_DOWN ))
- {
- IF_DEBUG(DEBUG_IF)
- {
- if ( v-> uv_flags & VIFF_DISABLED)
- log(LOG_DEBUG,0,"%s is DISABLED ; vif #%u out of service",v->uv_name,vifi);
- else
- log(LOG_DEBUG,0,"%s is DOWN ; vif #%u out of service",v->uv_name,vifi);
- }
- }
- else
- start_vif(vifi);
- }
- if ( action == MIFF_REGISTER)
- break;
- }
-}
-
-/*
- * Initialize the vif and add to the kernel. The vif can be either
- * physical, register or tunnel (tunnels will be used in the future
- * when this code becomes PIM multicast boarder router.
- */
-
-
-void start_vif (vifi_t vifi)
-{
- struct uvif *v;
-
- v = &uvifs[vifi];
-
- /* Initialy no router on any vif */
-
- if( v-> uv_flags & MIFF_REGISTER)
- v->uv_flags = v->uv_flags & ~VIFF_DOWN;
- else
- {
- v->uv_flags = (v->uv_flags | VIFF_DR | VIFF_NONBRS) & ~ VIFF_DOWN;
- v->uv_pim_hello_timer = 1 + RANDOM() % pim_hello_period;
- v->uv_jp_timer = 1 + RANDOM() % pim_join_prune_period;
- }
-
- /* Tell kernel to add, i.e. start this vif */
-
- k_add_vif(mld6_socket,vifi,&uvifs[vifi]);
- IF_DEBUG(DEBUG_IF)
- log(LOG_DEBUG,0,"%s comes up ,vif #%u now in service",v->uv_name,vifi);
-
- if (!(v->uv_flags & MIFF_REGISTER)) {
- /*
- * 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.this allow receiving mld6 messages too.
- */
- 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(struct listaddr));
- memset(v->uv_querier, 0, sizeof(struct listaddr));
- }
- 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);
-
- /*
- * Send a probe via the new vif to look for neighbors.
- */
- send_pim6_hello(v, pim_hello_holdtime);
- }
-}
-
-/*
- * Stop a vif (either physical interface, tunnel or
- * register.) If we are running only PIM we don't have tunnels.
- */
-
-
-void stop_vif( vifi_t vifi )
-{
- struct uvif *v;
- struct listaddr *a;
- register pim_nbr_entry_t *n;
- register pim_nbr_entry_t *next;
- struct vif_acl *acl;
-
-
- /*
- * TODO: make sure that the kernel viftable is
- * consistent with the daemon table
- */
-
- v=&uvifs[vifi];
- if( !( v->uv_flags&MIFF_REGISTER ) )
- {
- 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;
- if( !(v->uv_flags & MIFF_REGISTER ))
- {
- RESET_TIMER(v->uv_pim_hello_timer);
- RESET_TIMER(v->uv_jp_timer);
- RESET_TIMER(v->uv_gq_timer);
-
- 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;
-
- IF_DEBUG(DEBUG_IF)
- log( LOG_DEBUG ,0,"%s goes down , vif #%u out of service" , v->uv_name , vifi);
-}
-
-/*
- * Update the register vif in the multicast routing daemon and the
- * kernel because the interface used initially to get its local address
- * is DOWN. register_vifi is the index to the Register vif which needs
- * to be updated. As a result the Register vif has a new uv_lcl_addr and
- * is UP (virtually :))
- */
-int
-update_reg_vif( vifi_t register_vifi )
-{
- register struct uvif *v;
- register vifi_t vifi;
-
- /* Find the first useable vif with solid physical background */
- for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
- if (v->uv_flags & (VIFF_DISABLED | VIFF_DOWN | VIFF_TUNNEL
- | MIFF_REGISTER))
- continue;
- /* Found. Stop the bogus Register vif first */
- stop_vif(register_vifi);
- uvifs[register_vifi].uv_linklocal->pa_addr =
- uvifs[vifi].uv_linklocal->pa_addr;
- start_vif(register_vifi);
- IF_DEBUG(DEBUG_PIM_REGISTER | DEBUG_IF)
- log(LOG_NOTICE, 0, "%s has come up; vif #%u now in service",
- uvifs[register_vifi].uv_name, register_vifi);
- return 0;
- }
- vifs_down = TRUE;
- log(LOG_WARNING, 0, "Cannot start Register vif: %s",
- uvifs[vifi].uv_name);
- return(-1);
-}
-
-/*
- * 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);
-}
-
-/*
- * Check if the interface exists in the mif table. If true
- * return the highest address of the interface else return NULL.
- */
-struct sockaddr_in6 *
-local_iface(char *ifname)
-{
- register struct uvif *v;
- vifi_t vifi;
- 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;
- if(EQUAL(v->uv_name, ifname))
- {
- for(p=v->uv_addrs; p!=NULL; p=p->pa_next)
- {
- if (!IN6_IS_ADDR_LINKLOCAL(&p->pa_addr.sin6_addr)&&
- !IN6_IS_ADDR_SITELOCAL(&p->pa_addr.sin6_addr)) {
- /*
- * If this is the first global address
- * or larger than the current MAX global
- * address, remember it.
- */
- if (pmax == NULL ||
- inet6_lessthan(&pmax->pa_addr,
- &p->pa_addr))
- pmax = p;
- }
- }
- if (pmax)
- return(&pmax->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=TRUE;
-
- /* TODO: Check all potential interfaces!!! */
- /* Check the physical and tunnels only */
- for( vifi=0 , v=uvifs ; vifi<numvifs ; ++vifi , ++v )
- {
- if( v->uv_flags & ( VIFF_DISABLED|MIFF_REGISTER ) )
- 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 ; vif #%u taken out of service",
- v->uv_name , vifi );
- stop_vif ( vifi );
- vifs_down = TRUE;
- }
- }
- }
-
- /* Check the register(s) vif(s) */
- for( vifi=0 , v=uvifs ; vifi<numvifs ; ++vifi , ++v )
- {
- register vifi_t vifi2;
- register struct uvif *v2;
- int found;
-
- if( !(v->uv_flags & MIFF_REGISTER ) )
- continue;
- else
- {
- found=0;
-
- /* Find a physical vif with the same IP address as the
- * Register vif.
- */
- for( vifi2=0 , v2=uvifs ; vifi2<numvifs ; ++vifi2 , ++v2 )
- {
- if( v2->uv_flags & ( VIFF_DISABLED|VIFF_DOWN|VIFF_TUNNEL|MIFF_REGISTER ))
- continue;
- if( IN6_ARE_ADDR_EQUAL( &v->uv_linklocal->pa_addr.sin6_addr,
- &v2->uv_linklocal->pa_addr.sin6_addr ))
- {
- found=1;
- break;
- }
- }
- if(!found)
- /* The physical interface with the IP address as the Register
- * vif is probably DOWN. Get a replacement.
- */
- update_reg_vif( vifi );
- }
- }
- 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|MIFF_REGISTER))
- 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 | MIFF_REGISTER))
- 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 |MIFF_REGISTER))
- 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);
-}
-
-int
-vif_forwarder(if_set *p1 , if_set *p2)
-{
- int idx;
-
- for(idx=0 ; idx < sizeof(*p1)/sizeof(fd_mask) ; idx++)
- {
- if (p1->ifs_bits[idx] & p2->ifs_bits[idx])
- return(TRUE);
-
- }
-
- /* (p1 & p2) is empty. We're not the forwarder */
- return(FALSE);
-}
-
-if_set *
-vif_and(if_set *p1 , if_set *p2, if_set *result)
-{
- int idx;
-
- IF_ZERO(result);
-
- for(idx=0 ; idx < sizeof(*p1)/sizeof(fd_mask) ; idx++)
- {
- result->ifs_bits[idx] = p1->ifs_bits[idx] & p2->ifs_bits[idx];
- }
-
- return(result);
-}
-
-if_set *
-vif_xor(if_set *p1 , if_set *p2, if_set *result)
-{
- int idx;
-
- IF_ZERO(result);
-
- for(idx=0 ; idx < sizeof(*p1)/sizeof(fd_mask) ; idx++)
- {
- result->ifs_bits[idx] =
- p1->ifs_bits[idx] ^ p2->ifs_bits[idx];
- }
-
- return(result);
-}
-/*
- * 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);
- }
- }
-}
-
-struct uvif *
-find_vif(ifname)
- char *ifname;
-{
- struct uvif *v;
- vifi_t vifi;
-
- for (vifi = 0, v = uvifs; vifi < numvifs ; ++vifi , ++v) {
- if (strcasecmp(v->uv_name, ifname) == 0)
- return(v);
- }
-
- return(NULL);
-}
diff --git a/usr.sbin/pim6sd/vif.h b/usr.sbin/pim6sd/vif.h
deleted file mode 100644
index d81d657..0000000
--- a/usr.sbin/pim6sd/vif.h
+++ /dev/null
@@ -1,277 +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
- * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
- *
- */
-/*
- * This program has been derived from pim6dd.
- * The pim6dd program is covered by the license in the accompanying file
- * named "LICENSE.pim6dd".
- */
-/*
- * This program has been derived from pimd.
- * The pimd program is covered by the license in the accompanying file
- * named "LICENSE.pimd".
- *
- */
-/*
- * 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$
- */
-
-#ifndef VIF_H
-#define VIF_H
-
-#include <sys/param.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <net/route.h>
-#include <net/if.h>
-#include <netinet6/ip6_mroute.h>
-#include <netinet/ip_mroute.h>
-#include "defs.h"
-
-extern int total_interfaces;
-extern int udp_socket;
-extern struct uvif uvifs[];
-extern vifi_t numvifs;
-extern int vifs_down;
-extern int phys_vif;
-extern vifi_t reg_vif_num;
-
-#define NO_VIF ((vifi_t)MAXVIFS) /* An invalid vif index */
-#define DEFAULT_METRIC 1
-#define VIFF_DOWN 0x000100
-#define VIFF_DISABLED 0x000200
-#define VIFF_QUERIER 0x000400
-#define VIFF_REXMIT_PRUNES 0x004000
-#define VIFF_DR 0x040000
-#define VIFF_NONBRS 0x080000
-#define VIFF_PIM_NBR 0x200000
-#define VIFF_POINT_TO_POINT 0x400000
-#define NBRTYPE u_long
-#define NBRBITS sizeof(NBRTYPE) *8
-
-
-extern if_set if_nullset;
-#define IF_ISEMPTY(p) (memcmp((p), &if_nullset, sizeof(if_nullset)) == 0)
-#define IF_SAME(p1, p2) (memcmp((p1),(p2),sizeof(*(p1))) == 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]; \
- }\
- }
-
-typedef struct {
- NBRTYPE hi;
- NBRTYPE lo;
-} nbrbitmap_t;
-
-struct vf_element {
- struct vf_element *vfe_next;
- struct sockaddr_in6 *vfe_addr;
- struct in6_addr vfe_mask;
- int vfe_flags;
-#define VFRF_EXACT 0x0001
-};
-
-#define VFT_ACCEPT 1
-#define VFT_DENY 2
-#define VFF_BIDIR 1
-
-struct vif_filter {
- int vf_type;
- int vf_flags;
- struct vf_element *vf_filter;
-};
-
-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 */
- 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
-
-/*
- * 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;
- u_char uv_metric; /* VIFF_ flags defined below */
- u_char uv_admetric; /* advertised cost of this vif */
- u_int uv_rate_limit; /* rate limit on this vif */
-
- struct phaddr *uv_linklocal; /* link-local address of this vif */
- struct sockaddr_in6 uv_rmt_addr;/* remote end-point addr (tunnels only) */
- 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 lisaddr *uv_dvmrp_neighbors;
- 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_leaftimer; /* time until this vif is considrd leaf */
- struct phaddr *uv_addrs; /* Additional addresses on this vif */
- struct vif_filter *uvfilter; /* 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 */
- u_int16 uv_jp_timer; /* Join/Prune 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 nbr routers */
-
- void *config_attr; /* temporary buffer while parsing config */
-
- /* the followings are to collect statistics */
- /* incoming PIM6 packets on this interface */
- u_quad_t uv_in_pim6_hello;
- u_quad_t uv_in_pim6_join_prune;
- u_quad_t uv_in_pim6_bootsrap;
- u_quad_t uv_in_pim6_assert;
- /* outgoing PIM6 packets on this interface */
- u_quad_t uv_out_pim6_hello;
- u_quad_t uv_out_pim6_join_prune;
- u_quad_t uv_out_pim6_bootsrap;
- u_quad_t uv_out_pim6_assert;
- /* incoming MLD packets on this interface */
- u_quad_t uv_in_mld_query;
- u_quad_t uv_in_mld_report;
- u_quad_t uv_in_mld_done;
- /* outgoing MLD packets on this interface */
- u_quad_t uv_out_mld_query;
- u_quad_t uv_out_mld_report;
- u_quad_t uv_out_mld_done;
- /* statistics about the forwarding cache in kernel */
- u_quad_t uv_cache_miss;
- u_quad_t uv_cache_notcreated;
- /* occurrences of timeouts */
- u_quad_t uv_pim6_nbr_timo;
- u_quad_t uv_listener_timo;
- u_quad_t uv_querier_timo;
- u_quad_t uv_outif_timo; /* outgoing interfaces timers */
-};
-
-struct phaddr {
- struct phaddr *pa_next;
- struct sockaddr_in6 pa_addr;
- struct sockaddr_in6 pa_prefix;
- struct in6_addr pa_subnetmask;
-};
-
-
-/* The Access Control List (list with scoped addresses) member */
-#define VIFF_NOLISTENER 0x800000 /* no listener on the link */
-
-struct vif_acl {
- struct vif_acl *acl_next;
- struct sockaddr_in6 acl_addr;
- struct in6_addr acl_mask;
-};
-
-/*
- * 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 */
-};
-
-
-
-
-extern void init_vifs __P((void));
-extern void stop_all_vifs __P((void));
-extern void check_vif_state __P((void));
-struct sockaddr_in6 * max_global_address __P((void));
-struct sockaddr_in6 * uv_global __P((vifi_t));
-extern vifi_t local_address __P((struct sockaddr_in6 *src));
-struct sockaddr_in6 * local_iface __P((char *ifname));
-extern vifi_t find_vif_direct __P((struct sockaddr_in6 *src));
-extern vifi_t find_vif_direct_local __P((struct sockaddr_in6 *src));
-extern int vif_forwarder __P((if_set *p1 ,if_set *p2));
-extern if_set *vif_and __P((if_set *p1, if_set *p2, if_set *result));
-extern if_set *vif_xor __P((if_set *p1, if_set *p2, if_set *result));
-extern struct uvif *find_vif __P((char *ifname));
-#endif
diff --git a/usr.sbin/pim6sd/vmbuf.h b/usr.sbin/pim6sd/vmbuf.h
deleted file mode 100644
index b6931dd..0000000
--- a/usr.sbin/pim6sd/vmbuf.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 1995, 1996, 1997, and 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$
- */
-/* YIPS @(#)$Id: vmbuf.h,v 1.1 1999/10/29 09:04:55 jinmei Exp $ */
-
-typedef struct _vchar_ {
- u_int32_t t; /* type of the value */
- size_t l; /* length of the value */
- caddr_t v; /* place holder to the value in buffer */
-#if 0
- caddr_t v0; /* pointer to the buffer - not used any more */
-#endif
-} vchar_t;
-
-extern vchar_t *vmalloc(size_t);
-extern vchar_t *vrealloc(vchar_t *, size_t);
-extern void vfree(vchar_t *);
-extern vchar_t *vdup(vchar_t *);
-extern int pvdump(vchar_t *);
-
-#define VREALLOC(ptr, size) ((ptr) = vrealloc((ptr), (size)))
-
OpenPOWER on IntegriCloud