From 2dd555017d992610a09beeff1425734afa740df7 Mon Sep 17 00:00:00 2001 From: ume Date: Sun, 3 Jun 2001 18:16:39 +0000 Subject: Remove pim6[ds]d from the tree. The software had a restrictive license than we can handle. pim6[ds]d are available as ports instead. --- usr.sbin/Makefile | 2 - usr.sbin/pim6dd/LICENSE.mrouted | 49 - usr.sbin/pim6dd/LICENSE.pimd | 48 - usr.sbin/pim6dd/Makefile | 89 - usr.sbin/pim6dd/VERSION | 2 - usr.sbin/pim6dd/callout.c | 256 --- usr.sbin/pim6dd/config.c | 792 ------- usr.sbin/pim6dd/debug.c | 565 ----- usr.sbin/pim6dd/debug.h | 121 -- usr.sbin/pim6dd/defs.h | 606 ------ usr.sbin/pim6dd/inet6.c | 288 --- usr.sbin/pim6dd/kern.c | 415 ---- usr.sbin/pim6dd/main.c | 720 ------- usr.sbin/pim6dd/mld6.c | 548 ----- usr.sbin/pim6dd/mld6.h | 48 - usr.sbin/pim6dd/mld6_proto.c | 523 ----- usr.sbin/pim6dd/mrt.c | 803 ------- usr.sbin/pim6dd/mrt.h | 228 -- usr.sbin/pim6dd/pathnames.h | 63 - usr.sbin/pim6dd/pim6.c | 441 ---- usr.sbin/pim6dd/pim6_proto.c | 1596 -------------- usr.sbin/pim6dd/pim6dd.8 | 132 -- usr.sbin/pim6dd/pim6dd.conf.5 | 165 -- usr.sbin/pim6dd/pimdd.h | 553 ----- usr.sbin/pim6dd/route.c | 659 ------ usr.sbin/pim6dd/routesock.c | 373 ---- usr.sbin/pim6dd/timer.c | 336 --- usr.sbin/pim6dd/trace.c | 540 ----- usr.sbin/pim6dd/trace.h | 204 -- usr.sbin/pim6dd/vers.c | 2 - usr.sbin/pim6dd/vif.c | 535 ----- usr.sbin/pim6dd/vif.h | 292 --- usr.sbin/pim6sd/BUGS.TODO | 126 -- usr.sbin/pim6sd/BUGS.V6 | 10 - usr.sbin/pim6sd/LICENSE.mrouted | 49 - usr.sbin/pim6sd/LICENSE.pim6dd | 31 - usr.sbin/pim6sd/LICENSE.pim6sd | 47 - usr.sbin/pim6sd/LICENSE.pimd | 48 - usr.sbin/pim6sd/Makefile | 96 - usr.sbin/pim6sd/README | 85 - usr.sbin/pim6sd/README.first | 15 - usr.sbin/pim6sd/callout.c | 317 --- usr.sbin/pim6sd/callout.h | 62 - usr.sbin/pim6sd/cfparse.h | 55 - usr.sbin/pim6sd/cfparse.y | 1023 --------- usr.sbin/pim6sd/cftoken.l | 664 ------ usr.sbin/pim6sd/config.c | 495 ----- usr.sbin/pim6sd/config.h | 73 - usr.sbin/pim6sd/crc.c | 103 - usr.sbin/pim6sd/crc.h | 47 - usr.sbin/pim6sd/debug.c | 998 --------- usr.sbin/pim6sd/debug.h | 153 -- usr.sbin/pim6sd/defs.h | 81 - usr.sbin/pim6sd/inet6.c | 292 --- usr.sbin/pim6sd/inet6.h | 76 - usr.sbin/pim6sd/kern.c | 413 ---- usr.sbin/pim6sd/kern.h | 77 - usr.sbin/pim6sd/main.c | 767 ------- usr.sbin/pim6sd/mld6.c | 564 ----- usr.sbin/pim6sd/mld6.h | 92 - usr.sbin/pim6sd/mld6_proto.c | 619 ------ usr.sbin/pim6sd/mld6_proto.h | 71 - usr.sbin/pim6sd/mrt.c | 1500 ------------- usr.sbin/pim6sd/mrt.h | 340 --- usr.sbin/pim6sd/mtrace6/Makefile | 85 - usr.sbin/pim6sd/mtrace6/mtrace6.8 | 119 -- usr.sbin/pim6sd/mtrace6/mtrace6.c | 713 ------- usr.sbin/pim6sd/pathnames.h | 80 - usr.sbin/pim6sd/pim6.c | 518 ----- usr.sbin/pim6sd/pim6.h | 69 - usr.sbin/pim6sd/pim6_proto.c | 4129 ------------------------------------ usr.sbin/pim6sd/pim6_proto.h | 102 - usr.sbin/pim6sd/pim6sd.8 | 170 -- usr.sbin/pim6sd/pim6sd.conf.5 | 317 --- usr.sbin/pim6sd/pim6sd.conf.sample | 107 - usr.sbin/pim6sd/pim6stat | 89 - usr.sbin/pim6sd/pim6stat.1 | 95 - usr.sbin/pim6sd/pimd.h | 526 ----- usr.sbin/pim6sd/route.c | 1179 ---------- usr.sbin/pim6sd/route.h | 84 - usr.sbin/pim6sd/routesock.c | 428 ---- usr.sbin/pim6sd/routesock.h | 56 - usr.sbin/pim6sd/rp.c | 1207 ----------- usr.sbin/pim6sd/rp.h | 122 -- usr.sbin/pim6sd/timer.c | 1301 ------------ usr.sbin/pim6sd/timer.h | 101 - usr.sbin/pim6sd/trace.c | 558 ----- usr.sbin/pim6sd/trace.h | 210 -- usr.sbin/pim6sd/var.h | 62 - usr.sbin/pim6sd/vers.c | 2 - usr.sbin/pim6sd/vif.c | 824 ------- usr.sbin/pim6sd/vif.h | 277 --- usr.sbin/pim6sd/vmbuf.h | 49 - 93 files changed, 34962 deletions(-) delete mode 100644 usr.sbin/pim6dd/LICENSE.mrouted delete mode 100644 usr.sbin/pim6dd/LICENSE.pimd delete mode 100644 usr.sbin/pim6dd/Makefile delete mode 100644 usr.sbin/pim6dd/VERSION delete mode 100644 usr.sbin/pim6dd/callout.c delete mode 100644 usr.sbin/pim6dd/config.c delete mode 100644 usr.sbin/pim6dd/debug.c delete mode 100644 usr.sbin/pim6dd/debug.h delete mode 100644 usr.sbin/pim6dd/defs.h delete mode 100644 usr.sbin/pim6dd/inet6.c delete mode 100644 usr.sbin/pim6dd/kern.c delete mode 100644 usr.sbin/pim6dd/main.c delete mode 100644 usr.sbin/pim6dd/mld6.c delete mode 100644 usr.sbin/pim6dd/mld6.h delete mode 100644 usr.sbin/pim6dd/mld6_proto.c delete mode 100644 usr.sbin/pim6dd/mrt.c delete mode 100644 usr.sbin/pim6dd/mrt.h delete mode 100644 usr.sbin/pim6dd/pathnames.h delete mode 100644 usr.sbin/pim6dd/pim6.c delete mode 100644 usr.sbin/pim6dd/pim6_proto.c delete mode 100644 usr.sbin/pim6dd/pim6dd.8 delete mode 100644 usr.sbin/pim6dd/pim6dd.conf.5 delete mode 100644 usr.sbin/pim6dd/pimdd.h delete mode 100644 usr.sbin/pim6dd/route.c delete mode 100644 usr.sbin/pim6dd/routesock.c delete mode 100644 usr.sbin/pim6dd/timer.c delete mode 100644 usr.sbin/pim6dd/trace.c delete mode 100644 usr.sbin/pim6dd/trace.h delete mode 100644 usr.sbin/pim6dd/vers.c delete mode 100644 usr.sbin/pim6dd/vif.c delete mode 100644 usr.sbin/pim6dd/vif.h delete mode 100644 usr.sbin/pim6sd/BUGS.TODO delete mode 100644 usr.sbin/pim6sd/BUGS.V6 delete mode 100644 usr.sbin/pim6sd/LICENSE.mrouted delete mode 100644 usr.sbin/pim6sd/LICENSE.pim6dd delete mode 100644 usr.sbin/pim6sd/LICENSE.pim6sd delete mode 100644 usr.sbin/pim6sd/LICENSE.pimd delete mode 100644 usr.sbin/pim6sd/Makefile delete mode 100644 usr.sbin/pim6sd/README delete mode 100644 usr.sbin/pim6sd/README.first delete mode 100644 usr.sbin/pim6sd/callout.c delete mode 100644 usr.sbin/pim6sd/callout.h delete mode 100644 usr.sbin/pim6sd/cfparse.h delete mode 100644 usr.sbin/pim6sd/cfparse.y delete mode 100644 usr.sbin/pim6sd/cftoken.l delete mode 100644 usr.sbin/pim6sd/config.c delete mode 100644 usr.sbin/pim6sd/config.h delete mode 100644 usr.sbin/pim6sd/crc.c delete mode 100644 usr.sbin/pim6sd/crc.h delete mode 100644 usr.sbin/pim6sd/debug.c delete mode 100644 usr.sbin/pim6sd/debug.h delete mode 100644 usr.sbin/pim6sd/defs.h delete mode 100644 usr.sbin/pim6sd/inet6.c delete mode 100644 usr.sbin/pim6sd/inet6.h delete mode 100644 usr.sbin/pim6sd/kern.c delete mode 100644 usr.sbin/pim6sd/kern.h delete mode 100644 usr.sbin/pim6sd/main.c delete mode 100644 usr.sbin/pim6sd/mld6.c delete mode 100644 usr.sbin/pim6sd/mld6.h delete mode 100644 usr.sbin/pim6sd/mld6_proto.c delete mode 100644 usr.sbin/pim6sd/mld6_proto.h delete mode 100644 usr.sbin/pim6sd/mrt.c delete mode 100644 usr.sbin/pim6sd/mrt.h delete mode 100644 usr.sbin/pim6sd/mtrace6/Makefile delete mode 100644 usr.sbin/pim6sd/mtrace6/mtrace6.8 delete mode 100644 usr.sbin/pim6sd/mtrace6/mtrace6.c delete mode 100644 usr.sbin/pim6sd/pathnames.h delete mode 100644 usr.sbin/pim6sd/pim6.c delete mode 100644 usr.sbin/pim6sd/pim6.h delete mode 100644 usr.sbin/pim6sd/pim6_proto.c delete mode 100644 usr.sbin/pim6sd/pim6_proto.h delete mode 100644 usr.sbin/pim6sd/pim6sd.8 delete mode 100644 usr.sbin/pim6sd/pim6sd.conf.5 delete mode 100644 usr.sbin/pim6sd/pim6sd.conf.sample delete mode 100755 usr.sbin/pim6sd/pim6stat delete mode 100644 usr.sbin/pim6sd/pim6stat.1 delete mode 100644 usr.sbin/pim6sd/pimd.h delete mode 100644 usr.sbin/pim6sd/route.c delete mode 100644 usr.sbin/pim6sd/route.h delete mode 100644 usr.sbin/pim6sd/routesock.c delete mode 100644 usr.sbin/pim6sd/routesock.h delete mode 100644 usr.sbin/pim6sd/rp.c delete mode 100644 usr.sbin/pim6sd/rp.h delete mode 100644 usr.sbin/pim6sd/timer.c delete mode 100644 usr.sbin/pim6sd/timer.h delete mode 100644 usr.sbin/pim6sd/trace.c delete mode 100644 usr.sbin/pim6sd/trace.h delete mode 100644 usr.sbin/pim6sd/var.h delete mode 100644 usr.sbin/pim6sd/vers.c delete mode 100644 usr.sbin/pim6sd/vif.c delete mode 100644 usr.sbin/pim6sd/vif.h delete mode 100644 usr.sbin/pim6sd/vmbuf.h 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 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 -#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 [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 '. - * 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 '. - * 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 -#else -#include -#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(§ime); - 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if ((defined(SYSV)) || (defined(__bsdi__)) || ((defined SunOS) && (SunOS < 50))) -#include -#endif /* SYSV || __bsdi__ || SunOS 4.x */ -#include -#include -#if defined(__FreeBSD__) && __FreeBSD__ >= 3 -#include -#endif /* __FreeBSD__ >= 3 */ -#include -#include -#include -#include - -#include -#include - -#include -#ifdef __FreeBSD__ /* sigh */ -#include -#endif /* __FreeBSD__ */ -#if (defined(__bsdi__)) || (defined(__FreeBSD__) && (__FreeBSD_version >= 220000)) -#define rtentry kernel_rtentry -#include -#undef rtentry -#endif /* __bsdi__ or __FreeBSD_version >= 220000 */ -#include -#include -#include -#ifdef RSRR -#include -#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 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 -#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 - -/* - * 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; \ - iprune_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; \ - iprune_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 - -/* - * 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 - -#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 -#include -#include "defs.h" -#include -#include -#ifdef HAVE_ROUTING_SOCKETS -#include -#endif -#include -#include -#include - -#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 , 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 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 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 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 - - * 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" and - Fred Griffoul - - * 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 -#include -#include -#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 - -#include - -#include - -#include -#include - -#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 LOGLEV NOLOGLEV -%type NUMBER -%type STRING IFNAME -%type if_attributes rp_substatement rp_attributes -%type 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 / */ -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 interval ] - * 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 interval ] - * 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 -#include -#include -#include -#ifdef HAVE_STDARG_H -#include -#else -#include -#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 */ -log { DP("begin logging"); BEGIN S_LOG; return(LOGGING); } -(no)?mld_proto { - YYD_ECHO; - yylval.num = DEBUG_MLD_PROTO; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?mld_timer { - YYD_ECHO; - yylval.num = DEBUG_MLD_TIMER; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?mld_member { - YYD_ECHO; - yylval.num = DEBUG_MLD_MEMBER; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?mld { - YYD_ECHO; - yylval.num = DEBUG_MLD; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?switch { - YYD_ECHO; - yylval.num = DEBUG_SWITCH; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?m?trace { - YYD_ECHO; - yylval.num = DEBUG_TRACE; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?traceroute { - YYD_ECHO; - yylval.num = DEBUG_TRACE; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?timeout { - YYD_ECHO; - yylval.num = DEBUG_TIMEOUT; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?callout { - YYD_ECHO; - yylval.num = DEBUG_TIMEOUT; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?pkt { - YYD_ECHO; - yylval.num = DEBUG_PKT; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?packets { - YYD_ECHO; - yylval.num = DEBUG_PKT; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?interfaces { - YYD_ECHO; - yylval.num = DEBUG_IF; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?vif { - YYD_ECHO; - yylval.num = DEBUG_IF; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?kernel { - YYD_ECHO; - yylval.num = DEBUG_KERN; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?cache { - YYD_ECHO; - yylval.num = DEBUG_MFC; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?mfc { - YYD_ECHO; - yylval.num = DEBUG_MFC; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?k_cache { - YYD_ECHO; - yylval.num = DEBUG_MFC; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?k_mfc { - YYD_ECHO; - yylval.num = DEBUG_MFC; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?rsrr { - YYD_ECHO; - yylval.num = DEBUG_RSRR; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?pim_detail { - YYD_ECHO; - yylval.num = DEBUG_PIM_DETAIL; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?pim_hello { - YYD_ECHO; - yylval.num = DEBUG_PIM_HELLO; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?pim_neighbors { - YYD_ECHO; - yylval.num = DEBUG_PIM_HELLO; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?pim_register { - YYD_ECHO; - yylval.num = DEBUG_PIM_REGISTER; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?registers { - YYD_ECHO; - yylval.num = DEBUG_PIM_REGISTER; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?pim_join_prune { - YYD_ECHO; - yylval.num = DEBUG_PIM_JOIN_PRUNE; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?pim_j_p { - YYD_ECHO; - yylval.num = DEBUG_PIM_JOIN_PRUNE; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?pim_jp { - YYD_ECHO; - yylval.num = DEBUG_PIM_JOIN_PRUNE; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?pim_bootstrap { - YYD_ECHO; - yylval.num = DEBUG_PIM_BOOTSTRAP; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?pim_bsr { - YYD_ECHO; - yylval.num = DEBUG_PIM_BOOTSTRAP; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?bsr { - YYD_ECHO; - yylval.num = DEBUG_PIM_BOOTSTRAP; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?bootstrap { - YYD_ECHO; - yylval.num = DEBUG_PIM_BOOTSTRAP; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?pim_asserts { - YYD_ECHO; - yylval.num = DEBUG_PIM_ASSERT; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?pim_cand_rp { - YYD_ECHO; - yylval.num = DEBUG_PIM_CAND_RP; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?pim_c_rp { - YYD_ECHO; - yylval.num = DEBUG_PIM_CAND_RP; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?pim_rp { - YYD_ECHO; - yylval.num = DEBUG_PIM_CAND_RP; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?rp { - YYD_ECHO; - yylval.num = DEBUG_PIM_CAND_RP; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?pim_routes { - YYD_ECHO; - yylval.num = DEBUG_PIM_MRT; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?pim_routing { - YYD_ECHO; - yylval.num = DEBUG_PIM_MRT; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?pim_mrt { - YYD_ECHO; - yylval.num = DEBUG_PIM_MRT; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?pim_timers { - YYD_ECHO; - yylval.num = DEBUG_PIM_TIMER; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?pim_rpf { - YYD_ECHO; - yylval.num = DEBUG_PIM_RPF; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?rpf { - YYD_ECHO; - yylval.num = DEBUG_RPF; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?pim { - YYD_ECHO; - yylval.num = DEBUG_PIM; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?routes { - YYD_ECHO; - yylval.num = DEBUG_MRT; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?routing { - YYD_ECHO; - yylval.num = DEBUG_MRT; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?mrt { - YYD_ECHO; - yylval.num = DEBUG_MRT; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?routers { - YYD_ECHO; - yylval.num = DEBUG_NEIGHBORS; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?mrouters { - YYD_ECHO; - yylval.num = DEBUG_NEIGHBORS; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?neighbors { - YYD_ECHO; - yylval.num = DEBUG_NEIGHBORS; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?timers { - YYD_ECHO; - yylval.num = DEBUG_TIMER; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -(no)?asserts { - YYD_ECHO; - yylval.num = DEBUG_ASSERT; - if (strncmp("no", yytext, 2)) - return(LOGLEV); - else - return(NOLOGLEV); -} -all { YYD_ECHO; yylval.num = DEBUG_ALL; return(LOGLEV); } -3 { YYD_ECHO; yylval.num = DEBUG_ALL; return(LOGLEV); } -{semi} { DP("end logging"); BEGIN S_CNF; return(EOS); } -{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 */ -reverselookup { YYD_ECHO; return(REVERSELOOKUP); } - - /* phyint */ -phyint { DP("begin phyint"); BEGIN S_PHYINT; return(PHYINT); } -{string} { - YYD_ECHO; - BEGIN S_IFCONF; - yylval.val.l = strlen(yytext); - yylval.val.v = strdup(yytext); - return(IFNAME); -} -{semi} { yyerror("phyint was specified without interface."); return(EOS); } -disable { YYD_ECHO; return(DISABLE); } -preference { YYD_ECHO; return(PREFERENCE); } -metric { YYD_ECHO; return(METRIC); } -nolistener { YYD_ECHO; return(NOLISTENER); } -{semi} { DP("end phyint"); BEGIN S_CNF; return(EOS); } - - /* cand_rp */ -cand_rp { DP("begin cand_rp"); BEGIN S_CANDRP; return(CANDRP); } -priority { YYD_ECHO; return(PRIORITY); } -time { YYD_ECHO; return(TIME); } -{ifname} { - YYD_ECHO; - yylval.val.l = strlen(yytext); - yylval.val.v = strdup(yytext); - return(IFNAME); -} -{semi} { DP("end cand_rp"); BEGIN S_CNF; return(EOS); } - - /* cand_bootstrap_router */ -cand_bootstrap_router { DP("begin cand_bsr"); BEGIN S_CANDBSR; return(CANDBSR); } -priority { YYD_ECHO; return(PRIORITY); } -masklen { YYD_ECHO; return(MASKLEN); } -time { YYD_ECHO; return(TIME); } -{ifname} { - YYD_ECHO; - yylval.val.l = strlen(yytext); - yylval.val.v = strdup(yytext); - return(IFNAME); -} -{semi} { DP("end cand_bsr"); BEGIN S_CNF; return(EOS); } - - /* group_prefix */ -group_prefix { YYD_ECHO; return(GRPPFX); } - - /* switch_register_threshold */ -switch_register_threshold { - YYD_ECHO; BEGIN S_THRES; return(REGTHRES); -} - /* switch_data_threshold */ -switch_data_threshold { - YYD_ECHO; BEGIN S_THRES; return(DATATHRES); -} -rate { YYD_ECHO; return(RATE); } -interval { YYD_ECHO; return(INTERVAL); } -{semi} { DP("end thres"); BEGIN S_CNF; return(EOS); } - - /* various parameters */ -default_source_metric { YYD_ECHO; return(SRCMETRIC); } -default_source_preference { YYD_ECHO; return(SRCPREF); } -hello_period { YYD_ECHO; return(HELLOPERIOD); } -granularity { YYD_ECHO; return(GRANULARITY); } -join_prune_period { YYD_ECHO; return(JPPERIOD); } -data_timeout { YYD_ECHO; return(DATATIME); } -register_suppression_timeout { YYD_ECHO; return(REGSUPTIME); } -probe_time { YYD_ECHO; return(PROBETIME); } -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 -#include -#include -#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 -#endif -#include -#ifdef HAVE_GETIFADDRS -#include -#endif -#include -#include -#include -#include "config.h" -#include -#include -#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 -#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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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 -#else -#include -#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 -#include - -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 - -#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 -#include -#include -#include -#include -#include "defs.h" -#include "vif.h" -#include "inet6.h" -#include - -/* 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if defined(__FreeBSD__) && __FreeBSD__ >= 3 -#include -#endif -#include -#include -#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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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 -#include -#include -#include - -#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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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 -#include -#include -#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 -#include -#include -#include -#include -#include -#include -#include -#include -#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 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 -#include -#include -#include -#include - -#include -#if defined(__FreeBSD__) && __FreeBSD__ >= 3 -#include -#endif - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#ifdef HAVE_GETIFADDRS -#include -#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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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 -#include -#include -#include -#include -#include -#include - -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 -#include -#include -#include -#include -#include -#include -#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(®_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(®_src->sin6_addr), - inet6_fmt(®_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 [metric] [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 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 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 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 '. -# 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 '. -#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 '. -#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 :