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