summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcvs2svn <cvs2svn@FreeBSD.org>1999-01-20 05:11:49 +0000
committercvs2svn <cvs2svn@FreeBSD.org>1999-01-20 05:11:49 +0000
commit2f85fff773f8dc2ad537319fcbe4352f2d241d7a (patch)
treeb813176c0af72f8e0a63a099aad4dba6b72630c9
parentce595def0708b60ce4dde9002ac206fae20be240 (diff)
downloadsrc-test2-vendor/mrouted/mtrace-5.2.tar.gz
src-test2-vendor/mrouted/mtrace-5.2.zip
-rw-r--r--usr.sbin/mrouted/LICENSE48
-rw-r--r--usr.sbin/mrouted/RELEASE326
-rw-r--r--usr.sbin/mrouted/callout.c226
-rw-r--r--usr.sbin/mrouted/cfparse.y637
-rw-r--r--usr.sbin/mrouted/config.c147
-rw-r--r--usr.sbin/mrouted/defs.h317
-rw-r--r--usr.sbin/mrouted/dvmrp.h174
-rw-r--r--usr.sbin/mrouted/igmp.c357
-rw-r--r--usr.sbin/mrouted/inet.c230
-rw-r--r--usr.sbin/mrouted/kern.c241
-rw-r--r--usr.sbin/mrouted/main.c757
-rw-r--r--usr.sbin/mrouted/map-mbone.889
-rw-r--r--usr.sbin/mrouted/mapper.c1034
-rw-r--r--usr.sbin/mrouted/mrinfo.883
-rw-r--r--usr.sbin/mrouted/mrinfo.c633
-rw-r--r--usr.sbin/mrouted/mrouted.8404
-rw-r--r--usr.sbin/mrouted/mrouted.conf43
-rw-r--r--usr.sbin/mrouted/pathnames.h25
-rw-r--r--usr.sbin/mrouted/prune.c2303
-rw-r--r--usr.sbin/mrouted/prune.h143
-rw-r--r--usr.sbin/mrouted/route.c1162
-rw-r--r--usr.sbin/mrouted/route.h51
-rw-r--r--usr.sbin/mrouted/rsrr.c499
-rw-r--r--usr.sbin/mrouted/rsrr.h138
-rw-r--r--usr.sbin/mrouted/rsrr_var.h41
-rw-r--r--usr.sbin/mrouted/vif.c1482
-rw-r--r--usr.sbin/mrouted/vif.h78
27 files changed, 0 insertions, 11668 deletions
diff --git a/usr.sbin/mrouted/LICENSE b/usr.sbin/mrouted/LICENSE
deleted file mode 100644
index ef7da470b117..000000000000
--- a/usr.sbin/mrouted/LICENSE
+++ /dev/null
@@ -1,48 +0,0 @@
-
-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/mrouted/RELEASE b/usr.sbin/mrouted/RELEASE
deleted file mode 100644
index 50127513aa00..000000000000
--- a/usr.sbin/mrouted/RELEASE
+++ /dev/null
@@ -1,326 +0,0 @@
-$Id: README-3.8.mrouted,v 3.8 1995/11/29 22:23:02 fenner Rel $
-
- IP Multicast Extensions for BSD-Derived Unix Systems
-
- Release 3.8
- November 29, 1995
-
- available from parcftp.xerox.com,
- file pub/net-research/ipmulti/mrouted3.8.tar.Z
- binaries pub/net-research/ipmulti/mrouted3.8-sparc-sunos41x.tar.Z
- pub/net-research/ipmulti/mrouted3.8-sparc-solaris2.tar.Z
- pub/net-research/ipmulti/mrouted3.8-i386-bsd.tar.Z
- pub/net-research/ipmulti/mrouted3.8-alpha-osf1.tar.Z
- pub/net-research/ipmulti/mrouted3.8-sgi-irix.tar.Z
- pub/net-research/ipmulti/mrouted3.8-hp-hpux.tar.Z
-
-Note: The 3.8 release is mrouted-only, and will run on top of a 3.5 kernel.
-It is a drop-in replacement for mrouted 3.5, 3.6 or 3.7 .
-
-The 3.8 release fixes the following bugs:
-
- o mrouted would fail to forget prunes when a neighbor went away,
- thus potentially sending traffic down a tunnel after the tunnel
- endpoint has gone down. This was due to some research code making
- it into the "emergency" 3.7 release, sigh.
-
- o mrouted could send prunes with negative lifetimes. This causes
- slightly higher prune traffic but shouldn't be any major problem.
-
-===========
-Release 3.7
-November 28, 1995
-
-The 3.7 release fixes the following bugs:
-
- o mrouted now ignores route reports that include bogus netmasks.
- There was a bug in 3.5 that would mangle default routes into
- tens of bogus routes; this should prevent that bug from killing
- the MBONE.
-
- This solution can cause route flaps and black holes until the
- 3.5's are gone or all of the 3.5's neighbors are 3.7 .
-
- o mrouted now ignores duplicate routes. Ciscos and the above 3.5
- bug could cause two copies of the same route to appear in a single
- routing update; mrouted would insert two copies of the same route
- into its routing table and wreak all sorts of havoc.
-
- o mrouted now sends a group-specific query for both retransmissions
- of a g-s query; previous versions sent a general query the second
- time.
-
- o mrouted now loops back multicasted mtrace responses and
- group-specific membership queries
-
- o mrouted now performs deterministic tiebreaking between two
- neighbors on the same vif.
-
- o mrouted now only does duplicate suppression on traceroute requests,
- not all traceroute packets, so that a loop can be nicely detected
- via a duplicate router instead of just a timeout.
-
- o the buffer size that mrouted uses has been increased to allow
- more than 16 hops in mtrace messages.
-
- o mtrace's hop-by-hop termination is now more likely to be correct.
-
- o mrinfo now waits for the responses to its retransmitted queries.
-
-The 3.7 release has the following new features:
-
- o The configuration file can accept a hostname as the other end
- of a tunnel. There must be a single name->ip mapping for the
- given name, however, or mrouted will fail to start up.
-
- o mrinfo now sends requests to all interfaces of a multihomed host.
-
- o mtrace's passive mode has been implemented.
-
- o The first screen of mtrace statistics is shorter and more likely
- to fit on one screen.
-
-===========
-Release 3.6
-June 26, 1995
-
-The 3.6 release fixes the following bugs:
-
- o mrouted would dump core when attempting to report no routes (i.e. upon
- startup, if you have no enabled phyint's)
-
- o mrouted would dump core if requested to traceroute a source for which it
- had no route
-
- o neighbor flags were not always properly updated on probe or report
-
- o mrouted would sometimes reply to a multicast traceroute on a disabled
- phyint; now it uses the first configured phyint to reply to traceroutes.
-
- o host routes (i.e. netmask 0xffffffff) works now; it was discarding
- IGMP from the host because it was coming from the "broadcast address"
- of the subnet.
-
- o send_igmp() now treats the failure to send an mtrace or a neighbor
- reply as informational, as opposed to warning.
-
- o mrouted would go into an infinite loop trying to respond to a traceroute
- for a source with a netmask of 0xffffffff.
-
- o vifs_with_neighbors was not being reset if the mrouted was restarted
- with SIGHUP
-
- o the default route was not being properly advertised to neighbors (although
- it was accepted if it was advertised to it)
-
- o ANSI-fication for those who it helps, still-K&R-ish for those it doesn't.
-
- o mtrace now attempts to trace three hops past a non-responding router,
- in the hopes that it does support traceroute but just couldn't respond
- (i.e. unicast didn't work and it can't source multicast because all its
- phyints are disabled).
-
- o mrinfo now times out even on a multicast router.
-
-
-===========
-Release 3.5
-May 8, 1995
-
-The 3.5 release has the following new features:
-
- o The kernel and mrouted make sure that each is the correct version, to
- prevent problems with mismatched kernel/mrouted versions. A too-old
- mrouted will die with the error:
-
- can't enable DVMRP routing in kernel: Option not supported by protocol
-
- o mrouted can accept and propogate a default route (essential for
- heirarchical multicast routing)
-
- o Kernel route cache keeps source-specific routes instead of subnet routes,
- eliminating hashing and longest-match problems.
- (allows classless routing, longest-match and default routing)
-
- o Cached kernel routes only get deleted if no traffic is flowing, to
- facilitate multicast traceroute
-
- o mrouted has a new configuration file parser, which provides better error
- messages than before, and allows named boundaries (see man page)
-
- o added "netmask" to phyint configuration, at the suggestion of
- Anders Klemets
-
- o System V and FreeBSD compatibility from John Brezak <brezak@ch.hp.com>
-
- o phyint's can have additional subnets configured, for people with
- multiple subnets on one physical network. mrouted.conf syntax is
- altnet 1.2.3.0, or altnet 1.2.3.0/24 if you need to specify
- a different netmask. There can be as many altnet statements
- as you need.
-
- o both mrouted and the kernel now support classless addresses.
-
- o the kernel supports PIM assert processing by notifying the router
- when a packet arrives on the wrong interface
-
- o the kernel keeps additional counters, and mrouted can be compiled to
- support SNMP and the Multicast MIB
-
- o the packet classifier in the kernel now uses the following udp port
- ranges:
- [0, 16384) - lowest priority, unclassified
- [16384, 32768) - highest priority, i.e. audio
- [32768, 49152) - medium priority, i.e. whiteboard
- [49152, 65536) - low priority, i.e. video
- A future release of a session directory will allocate ports in these
- ranges.
-
- o the configuration code has been modified to default tunnels' rate_limit
- parameters to 500kbps. This is easily modified with a rate_limit keyword
- in mrouted.conf, but should be a good default for the MBONE in general.
-
- o The tunnel sending code now caches a route for ip_output(), this should
- help performance on machines with lots of tunnels.
-
- o Dispatching for de-capsulating packets is now via protosw[], making
- reception of other raw protocols more efficient
-
- o Neighbor capabilities are discovered via a bitmask as opposed to
- version number.
-
- o Multicast traceroute code improved
-
- o mrouted can be compiled with Routing Support for Resource Reservation
- (RSRR), required for RSVP.
-
-
-The 3.5 release fixes the following bugs:
-
- o The IGMPv2 query timeout field was interpreted as being in units of
- 200ms as opposed to 100ms, thus the maximum timeout was set to twice
- the expected value. This is not fatal, as mrouted always queries
- twice in the expectation that a packet could get loss, but it does
- make it less robust in the face of packet loss.
-
- o IGMP could report membership in local-only groups (i.e. 224.0.0.X)
-
- o IGMP could get confused by hearing its own new membership reports, thus
- a router would never perform fast leave.
-
- o IGMP could reset timers for the wrong interface.
-
- o mrouted put a bogus value in the maximum timeout field of IGMPv2 query
- packets.
-
- o Non-querier mrouters would respond to IGMP leave messages
-
- o mrouted was not performing fast leave properly
-
- o If the last member goes away on a transit network, the upstream router
- would stop forwarding even if there are downstream members.
-
- o Kernel hash function improved
-
- o Eliminated possibility of panic(): timeout in cache maintenance
-
- o Reordered resource allocation when sending upcall to handle failure properly
-
- o some endian-ness bugs squashed in mrouted, probably more to go.
-
- o Multicast traceroute could send a reply on a disabled interface.
-
-
-This release consists of the following files:
-
-
- README-3.8.mrouted - this file
-
- mrouted/* - version 3.8 of mrouted,
- mrinfo, map-mbone and
- mtrace.
-
- ifconfig/* - Changes to ifconfig to
- show multicast interfaces
-
- netstat/* - Diffs to netstat
-
- ping/* - sources for ping
- which support
- multicasting
-
- mtest/* - utility for testing
- multicast group
- membership
-
-
-MROUTED 3.8
-
-Mrouted 3.8 has two optional features: SNMP and RSRR. RSRR support
-is required for running RSVP; the SNMP code, with the help of the
-ISODE snmpd, implements both the Multicast MIB and the DVMRP MIB.
-
-RSRR
-----
-Routing Support for Resource Reservations (RSRR) was contributed by
-Daniel Zappala <daniel@isi.edu>.
-
-To enable RSRR support, uncomment the three lines starting with
-RSRR near the top of the Makefile and "make clean; make". Or use
-the prebuilt binary, mrouted.rsrr .
-
-RSRR allows RSVP to query mrouted for its routing entry for a particular
-source-group pair. Using the routing entry and the IP_MULTICAST_VIF
-socket call, RSVP can forward distinct control messages out each
-outgoing interface. This version of mrouted supports RSRR messages
-using a Unix datagram socket.
-
-RSRR currently includes two pairs of query-reply messages. RSVP sends
-an Initial Query when it starts. Mrouted responds with an Initial Reply
-that includes the set of vifs it is using, flagging those that are
-administratively disabled. When RSVP needs the routing entry for a
-source-group pair, it sends a Route Query. Mrouted responds with a
-Route Reply that includes the incoming vif and outgoing vifs for the
-source-group pair.
-
-RSVP may request route change notification by setting the notification
-bit in the Route Query. If mrouted can provide route change
-notification for the source-group pair, it sets the notification bit in
-its Route Reply. When the routing entry for the source-group pair
-changes, mrouted sends an unsolicited Route Reply containing the new
-routing information. The initial release of mrouted 3.5 did not support
-route change notification and always returned a Route Reply with the
-notification bit cleared. This release of mrouted provides route change
-notification when possible.
-
-SNMP
-----
-SNMP support was contributed by David Thaler <thalerd@eecs.umich.edu>.
-
-To enable SNMP support, uncomment the six lines near the top of
-the Makefile below the description of SNMP support, or use the
-prebuilt binary, mrouted.snmp or mrouted.rsrr.snmp .
-
-To link the SNMP-capable mrouted, you need the CMU libraries.
-See http://nic.merit.edu/~mbone/ for a full mrouted-snmp distribution.
-
-Make sure to add the "sysName", "sysContact", "sysVersion" and
-"sysLocation" variables to your /etc/mrouted.conf if you want them
-to provide anything other than default values.
-
-Example:
-
-sysName "tibia"
-sysContact "Bill Fenner <fenner@parc.xerox.com> +1 415 812-4816"
-sysVersion "SunOS 4.1.3 and mrouted 3.8"
-sysLocation "MAXC room, PARC building 35"
-
-The SNMP version of mrouted has an additional command line flag:
-
- -P snmp_port
-
- Specifies a port for SNMP communication (default 161). This option
- should be used when another SNMP daemon already exists. The
- preferred alternate port in this case is port 9161.
-
-The mstat(8) program allows querying of statistics using SNMP.
diff --git a/usr.sbin/mrouted/callout.c b/usr.sbin/mrouted/callout.c
deleted file mode 100644
index 358c7ae86a21..000000000000
--- a/usr.sbin/mrouted/callout.c
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * The mrouted program is covered by the license in the accompanying file
- * named "LICENSE". 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.
- *
- *
- * $Id: callout.c,v 3.8 1995/11/29 22:36:57 fenner Rel $
- */
-
-#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 */
-
-static int in_callout = 0;
-
-struct timeout_q {
- struct timeout_q *next; /* next event */
- int id;
- cfunc_t func; /* function to call */
- char *data; /* func's data */
- int time; /* time offset to next event*/
-};
-
-#ifdef IGMP_DEBUG
-static void print_Q __P((void));
-#else
-#define print_Q()
-#endif
-
-void
-callout_init()
-{
- Q = (struct timeout_q *) 0;
-}
-
-
-/*
- * signal handler for SIGALARM that is called once every second
- */
-void
-age_callout_queue()
-{
- struct timeout_q *ptr;
-
- if (in_callout)
- return;
-
- in_callout = 1;
- ptr = Q;
-
- while (ptr) {
- if (!ptr->time) {
- /* timeout has happened */
- Q = Q->next;
-
- in_callout = 0;
- if (ptr->func)
- ptr->func(ptr->data);
- in_callout = 1;
-
- free(ptr);
- ptr = Q;
- }
- else {
- ptr->time --;
-#ifdef IGMP_DEBUG
- log(LOG_DEBUG,0,"[callout, age_callout_queue] -- time (%d)", ptr->time);
-#endif /* IGMP_DEBUG */
- in_callout = 0; return;
- }
- }
- in_callout = 0;
- return;
-}
-
-
-/*
- * 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 */
- char *data; /* what to call the timeout function with */
-{
- struct timeout_q *ptr, *node, *prev;
-
- if (in_callout)
- return -1;
-
- in_callout = 1;
-
- /* 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");
- in_callout = 0;
- return -1;
- }
- node->func = action;
- node->data = data;
- node->time = delay;
- node->next = 0;
- node->id = ++id;
-
- prev = ptr = Q;
-
- /* insert node in the queue */
-
- /* if the queue is empty, insert the node and return */
- if (!Q)
- Q = node;
- else {
- /* chase the pointer looking for the right place */
- while (ptr) {
-
- if (delay < ptr->time) {
- /* right place */
-
- node->next = ptr;
- if (ptr == Q)
- Q = node;
- else
- prev->next = node;
- ptr->time -= node->time;
- print_Q();
- in_callout = 0;
- return node->id;
- } else {
- /* keep moving */
-
- delay -= ptr->time; node->time = delay;
- prev = ptr;
- ptr = ptr->next;
- }
- }
- prev->next = node;
- }
- print_Q();
- in_callout = 0;
- return node->id;
-}
-
-
-/* clears the associated timer */
-void
-timer_clearTimer(timer_id)
- int timer_id;
-{
- struct timeout_q *ptr, *prev;
-
- if (in_callout)
- return;
- if (!timer_id)
- return;
-
- in_callout = 1;
-
- prev = ptr = Q;
-
- /*
- * find the right node, delete it. the subsequent node's time
- * gets bumped up
- */
-
- print_Q();
- while (ptr) {
- if (ptr->id == timer_id) {
- /* got the right node */
-
- /* unlink it from the queue */
- if (ptr == Q)
- Q = Q->next;
- else
- prev->next = ptr->next;
-
- /* increment next node if any */
- if (ptr->next != 0)
- (ptr->next)->time += ptr->time;
-
- free(ptr->data);
- free(ptr);
- print_Q();
- in_callout = 0;
- return;
- }
- prev = ptr;
- ptr = ptr->next;
- }
- print_Q();
- in_callout = 0;
-}
-
-#ifdef IGMP_DEBUG
-/*
- * debugging utility
- */
-static void
-print_Q()
-{
- struct timeout_q *ptr;
-
- for(ptr = Q; ptr; ptr = ptr->next)
- log(LOG_DEBUG,0,"(%d,%d) ", ptr->id, ptr->time);
-}
-#endif /* IGMP_DEBUG */
-int
-secs_remaining( timer_id)
- int timer_id;
-{
- struct timeout_q *ptr;
- int left=0;
-
- for (ptr = Q; ptr && ptr->id != timer_id; ptr = ptr->next)
- left += ptr->time;
-
- if (!ptr) /* not found */
- return 0;
-
- return left + ptr->time;
-}
diff --git a/usr.sbin/mrouted/cfparse.y b/usr.sbin/mrouted/cfparse.y
deleted file mode 100644
index ab5b89f30ea8..000000000000
--- a/usr.sbin/mrouted/cfparse.y
+++ /dev/null
@@ -1,637 +0,0 @@
-%{
-/*
- * Configuration file parser for mrouted.
- *
- * Written by Bill Fenner, NRL, 1994
- *
- * $Id: cfparse.y,v 3.8 1995/11/29 22:36:57 fenner Rel $
- */
-#include <stdio.h>
-#ifdef __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-#include "defs.h"
-#include <netdb.h>
-
-/*
- * Local function declarations
- */
-static void fatal __P((char *fmt, ...));
-static void warn __P((char *fmt, ...));
-static void yyerror __P((char *s));
-static char * next_word __P((void));
-static int yylex __P((void));
-static u_int32 valid_if __P((char *s));
-static struct ifreq * ifconfaddr __P((struct ifconf *ifcp, u_int32 a));
-int yyparse __P((void));
-
-static FILE *f;
-
-extern int udp_socket;
-char *configfilename = _PATH_MROUTED_CONF;
-
-extern int cache_lifetime;
-extern int max_prune_lifetime;
-
-static int lineno;
-static struct ifreq ifbuf[32];
-static struct ifconf ifc;
-
-static struct uvif *v;
-
-static int order;
-
-struct addrmask {
- u_int32 addr;
- int mask;
-};
-
-struct boundnam {
- char *name;
- struct addrmask bound;
-};
-
-#define MAXBOUNDS 20
-
-struct boundnam boundlist[MAXBOUNDS]; /* Max. of 20 named boundaries */
-int numbounds = 0; /* Number of named boundaries */
-
-%}
-
-%union
-{
- int num;
- char *ptr;
- struct addrmask addrmask;
- u_int32 addr;
-};
-
-%token CACHE_LIFETIME PRUNING
-%token PHYINT TUNNEL NAME
-%token DISABLE IGMPV1 SRCRT
-%token METRIC THRESHOLD RATE_LIMIT BOUNDARY NETMASK ALTNET
-%token SYSNAM SYSCONTACT SYSVERSION SYSLOCATION
-%token <num> BOOLEAN
-%token <num> NUMBER
-%token <ptr> STRING
-%token <addrmask> ADDRMASK
-%token <addr> ADDR
-
-%type <addr> interface addrname
-%type <addrmask> bound boundary addrmask
-
-%start conf
-
-%%
-
-conf : stmts
- ;
-
-stmts : /* Empty */
- | stmts stmt
- ;
-
-stmt : error
- | PHYINT interface {
-
- vifi_t vifi;
-
- if (order)
- fatal("phyints must appear before tunnels");
-
- for (vifi = 0, v = uvifs;
- vifi < numvifs;
- ++vifi, ++v)
- if (!(v->uv_flags & VIFF_TUNNEL) &&
- $2 == v->uv_lcl_addr)
- break;
-
- if (vifi == numvifs)
- fatal("%s is not a configured interface",
- inet_fmt($2,s1));
-
- }
- ifmods
- | TUNNEL interface addrname {
-
- struct ifreq *ifr;
- struct ifreq ffr;
- vifi_t vifi;
-
- order++;
-
- ifr = ifconfaddr(&ifc, $2);
- if (ifr == 0)
- fatal("Tunnel local address %s is not mine",
- inet_fmt($2, s1));
-
- strncpy(ffr.ifr_name, ifr->ifr_name, IFNAMSIZ);
- if (ioctl(udp_socket, SIOCGIFFLAGS, (char *)&ffr)<0)
- fatal("ioctl SIOCGIFFLAGS on %s",ffr.ifr_name);
- if (ffr.ifr_flags & IFF_LOOPBACK)
- fatal("Tunnel local address %s is a loopback interface",
- inet_fmt($2, s1));
-
- if (ifconfaddr(&ifc, $3) != 0)
- fatal("Tunnel remote address %s is one of mine",
- inet_fmt($3, s1));
-
- for (vifi = 0, v = uvifs;
- vifi < numvifs;
- ++vifi, ++v)
- if (v->uv_flags & VIFF_TUNNEL) {
- if ($3 == v->uv_rmt_addr)
- fatal("Duplicate tunnel to %s",
- inet_fmt($3, s1));
- } else if (!(v->uv_flags & VIFF_DISABLED)) {
- if (($3 & v->uv_subnetmask) == v->uv_subnet)
- fatal("Unnecessary tunnel to %s",
- inet_fmt($3,s1));
- }
-
- if (numvifs == MAXVIFS)
- fatal("too many vifs");
-
- v = &uvifs[numvifs];
- v->uv_flags = VIFF_TUNNEL;
- v->uv_metric = DEFAULT_METRIC;
- v->uv_rate_limit= DEFAULT_TUN_RATE_LIMIT;
- v->uv_threshold = DEFAULT_THRESHOLD;
- v->uv_lcl_addr = $2;
- v->uv_rmt_addr = $3;
- v->uv_subnet = 0;
- v->uv_subnetmask= 0;
- v->uv_subnetbcast= 0;
- strncpy(v->uv_name, ffr.ifr_name, IFNAMSIZ);
- v->uv_groups = NULL;
- v->uv_neighbors = NULL;
- v->uv_acl = NULL;
- v->uv_addrs = NULL;
-
- if (!(ffr.ifr_flags & IFF_UP)) {
- v->uv_flags |= VIFF_DOWN;
- vifs_down = TRUE;
- }
- }
- tunnelmods
- {
- log(LOG_INFO, 0,
- "installing tunnel from %s to %s as vif #%u - rate=%d",
- inet_fmt($2, s1), inet_fmt($3, s2),
- numvifs, v->uv_rate_limit);
-
- ++numvifs;
- }
- | PRUNING BOOLEAN { pruning = $2; }
- | CACHE_LIFETIME NUMBER { cache_lifetime = $2;
- max_prune_lifetime = cache_lifetime * 2;
- }
- | NAME STRING boundary { if (numbounds >= MAXBOUNDS) {
- fatal("Too many named boundaries (max %d)", MAXBOUNDS);
- }
-
- boundlist[numbounds].name = malloc(strlen($2) + 1);
- strcpy(boundlist[numbounds].name, $2);
- boundlist[numbounds++].bound = $3;
- }
- | SYSNAM STRING {
-#ifdef SNMP
- set_sysName($2);
-#endif /* SNMP */
- }
- | SYSCONTACT STRING {
-#ifdef SNMP
- set_sysContact($2);
-#endif /* SNMP */
- }
- | SYSVERSION STRING {
-#ifdef SNMP
- set_sysVersion($2);
-#endif /* SNMP */
- }
- | SYSLOCATION STRING {
-#ifdef SNMP
- set_sysLocation($2);
-#endif /* SNMP */
- }
- ;
-
-tunnelmods : /* empty */
- | tunnelmods tunnelmod
- ;
-
-tunnelmod : mod
- | SRCRT { fatal("Source-route tunnels not supported"); }
- ;
-
-ifmods : /* empty */
- | ifmods ifmod
- ;
-
-ifmod : mod
- | DISABLE { v->uv_flags |= VIFF_DISABLED; }
- | IGMPV1 { v->uv_flags |= VIFF_IGMPV1; }
- | NETMASK addrname {
- u_int32 subnet, mask;
-
- mask = $2;
- subnet = v->uv_lcl_addr & mask;
- if (!inet_valid_subnet(subnet, mask))
- fatal("Invalid netmask");
- v->uv_subnet = subnet;
- v->uv_subnetmask = mask;
- v->uv_subnetbcast = subnet | ~mask;
- }
- | NETMASK {
-
- warn("Expected address after netmask keyword, ignored");
-
- }
- | ALTNET addrmask {
-
- struct phaddr *ph;
-
- ph = (struct phaddr *)malloc(sizeof(struct phaddr));
- if (ph == NULL)
- fatal("out of memory");
- if ($2.mask) {
- VAL_TO_MASK(ph->pa_subnetmask, $2.mask);
- } else
- ph->pa_subnetmask = v->uv_subnetmask;
- ph->pa_subnet = $2.addr & ph->pa_subnetmask;
- ph->pa_subnetbcast = ph->pa_subnet | ~ph->pa_subnetmask;
- if ($2.addr & ~ph->pa_subnetmask)
- warn("Extra subnet %s/%d has host bits set",
- inet_fmt($2.addr,s1), $2.mask);
- ph->pa_next = v->uv_addrs;
- v->uv_addrs = ph;
-
- }
- | ALTNET {
-
- warn("Expected address after altnet keyword, ignored");
-
- }
- ;
-
-mod : THRESHOLD NUMBER { if ($2 < 1 || $2 > 255)
- fatal("Invalid threshold %d",$2);
- v->uv_threshold = $2;
- }
- | THRESHOLD {
-
- warn("Expected number after threshold keyword, ignored");
-
- }
- | METRIC NUMBER { if ($2 < 1 || $2 > UNREACHABLE)
- fatal("Invalid metric %d",$2);
- v->uv_metric = $2;
- }
- | METRIC {
-
- warn("Expected number after metric keyword, ignored");
-
- }
- | RATE_LIMIT NUMBER { if ($2 > MAX_RATE_LIMIT)
- fatal("Invalid rate_limit %d",$2);
- v->uv_rate_limit = $2;
- }
- | RATE_LIMIT {
-
- warn("Expected number after rate_limit keyword, ignored");
-
- }
- | BOUNDARY bound {
-
- struct vif_acl *v_acl;
-
- v_acl = (struct vif_acl *)malloc(sizeof(struct vif_acl));
- if (v_acl == NULL)
- fatal("out of memory");
- VAL_TO_MASK(v_acl->acl_mask, $2.mask);
- v_acl->acl_addr = $2.addr & v_acl->acl_mask;
- if ($2.addr & ~v_acl->acl_mask)
- warn("Boundary spec %s/%d has host bits set",
- inet_fmt($2.addr,s1),$2.mask);
- v_acl->acl_next = v->uv_acl;
- v->uv_acl = v_acl;
-
- }
- | BOUNDARY {
-
- warn("Expected boundary spec after boundary keyword, ignored");
-
- }
- ;
-
-interface : ADDR { $$ = $1; }
- | STRING {
- $$ = valid_if($1);
- if ($$ == 0)
- fatal("Invalid interface name %s",$1);
- }
- ;
-
-addrname : ADDR { $$ = $1; }
- | STRING { struct hostent *hp;
-
- if ((hp = gethostbyname($1)) == NULL)
- fatal("No such host %s", $1);
-
- if (hp->h_addr_list[1])
- fatal("Hostname %s does not %s",
- $1, "map to a unique address");
-
- bcopy(hp->h_addr_list[0], &$$,
- hp->h_length);
- }
-
-bound : boundary { $$ = $1; }
- | STRING { int i;
-
- for (i=0; i < numbounds; i++) {
- if (!strcmp(boundlist[i].name, $1)) {
- $$ = boundlist[i].bound;
- break;
- }
- }
- if (i == numbounds) {
- fatal("Invalid boundary name %s",$1);
- }
- }
- ;
-
-boundary : ADDRMASK {
-
- if ((ntohl($1.addr) & 0xff000000) != 0xef000000) {
- fatal("Boundaries must be 239.x.x.x, not %s/%d",
- inet_fmt($1.addr, s1), $1.mask);
- }
- $$ = $1;
-
- }
- ;
-
-addrmask : ADDRMASK { $$ = $1; }
- | ADDR { $$.addr = $1; $$.mask = 0; }
- ;
-%%
-#ifdef __STDC__
-static void
-fatal(char *fmt, ...)
-{
- va_list ap;
- char buf[200];
-
- va_start(ap, fmt);
-#else
-/*VARARGS1*/
-static void
-fatal(fmt, va_alist)
-char *fmt;
-va_dcl
-{
- va_list ap;
- char buf[200];
-
- va_start(ap);
-#endif
- vsprintf(buf, fmt, ap);
- va_end(ap);
-
- log(LOG_ERR,0,"%s: %s near line %d", configfilename, buf, lineno);
-}
-
-#ifdef __STDC__
-static void
-warn(char *fmt, ...)
-{
- va_list ap;
- char buf[200];
-
- va_start(ap, fmt);
-#else
-/*VARARGS1*/
-static void
-warn(fmt, va_alist)
-char *fmt;
-va_dcl
-{
- va_list ap;
- char buf[200];
-
- va_start(ap);
-#endif
- vsprintf(buf, fmt, ap);
- va_end(ap);
-
- log(LOG_WARNING,0,"%s: %s near line %d", configfilename, buf, lineno);
-}
-
-static void
-yyerror(s)
-char *s;
-{
- log(LOG_ERR, 0, "%s: %s near line %d", configfilename, s, lineno);
-}
-
-static char *
-next_word()
-{
- static char buf[1024];
- static char *p=NULL;
- extern FILE *f;
- char *q;
-
- while (1) {
- if (!p || !*p) {
- lineno++;
- if (fgets(buf, sizeof(buf), f) == NULL)
- return NULL;
- p = buf;
- }
- while (*p && (*p == ' ' || *p == '\t')) /* skip whitespace */
- p++;
- if (*p == '#') {
- p = NULL; /* skip comments */
- continue;
- }
- q = p;
-#ifdef SNMP
- if (*p == '"') {
- p++;
- while (*p && *p != '"' && *p != '\n')
- p++; /* find next whitespace */
- if (*p == '"')
- p++;
- } else
-#endif
- while (*p && *p != ' ' && *p != '\t' && *p != '\n')
- p++; /* find next whitespace */
- *p++ = '\0'; /* null-terminate string */
-
- if (!*q) {
- p = NULL;
- continue; /* if 0-length string, read another line */
- }
-
- return q;
- }
-}
-
-static int
-yylex()
-{
- int n;
- u_int32 addr;
- char *q;
-
- if ((q = next_word()) == NULL) {
- return 0;
- }
-
- if (!strcmp(q,"cache_lifetime"))
- return CACHE_LIFETIME;
- if (!strcmp(q,"pruning"))
- return PRUNING;
- if (!strcmp(q,"phyint"))
- return PHYINT;
- if (!strcmp(q,"tunnel"))
- return TUNNEL;
- if (!strcmp(q,"disable"))
- return DISABLE;
- if (!strcmp(q,"metric"))
- return METRIC;
- if (!strcmp(q,"threshold"))
- return THRESHOLD;
- if (!strcmp(q,"rate_limit"))
- return RATE_LIMIT;
- if (!strcmp(q,"srcrt") || !strcmp(q,"sourceroute"))
- return SRCRT;
- if (!strcmp(q,"boundary"))
- return BOUNDARY;
- if (!strcmp(q,"netmask"))
- return NETMASK;
- if (!strcmp(q,"igmpv1"))
- return IGMPV1;
- if (!strcmp(q,"altnet"))
- return ALTNET;
- if (!strcmp(q,"name"))
- return NAME;
- if (!strcmp(q,"on") || !strcmp(q,"yes")) {
- yylval.num = 1;
- return BOOLEAN;
- }
- if (!strcmp(q,"off") || !strcmp(q,"no")) {
- yylval.num = 0;
- return BOOLEAN;
- }
- if (sscanf(q,"%[.0-9]/%d%c",s1,&n,s2) == 2) {
- if ((addr = inet_parse(s1)) != 0xffffffff) {
- yylval.addrmask.mask = n;
- yylval.addrmask.addr = addr;
- return ADDRMASK;
- }
- /* fall through to returning STRING */
- }
- if (sscanf(q,"%[.0-9]%c",s1,s2) == 1) {
- if ((addr = inet_parse(s1)) != 0xffffffff &&
- inet_valid_host(addr)) {
- yylval.addr = addr;
- return ADDR;
- }
- }
- if (sscanf(q,"0x%8x%c",&n,s1) == 1) {
- yylval.addr = n;
- return ADDR;
- }
- if (sscanf(q,"%d%c",&n,s1) == 1) {
- yylval.num = n;
- return NUMBER;
- }
-#ifdef SNMP
- if (!strcmp(q,"sysName"))
- return SYSNAM;
- if (!strcmp(q,"sysContact"))
- return SYSCONTACT;
- if (!strcmp(q,"sysVersion"))
- return SYSVERSION;
- if (!strcmp(q,"sysLocation"))
- return SYSLOCATION;
- if (*q=='"') {
- if (q[ strlen(q)-1 ]=='"')
- q[ strlen(q)-1 ]='\0'; /* trash trailing quote */
- yylval.ptr = q+1;
- return STRING;
- }
-#endif
- yylval.ptr = q;
- return STRING;
-}
-
-void
-config_vifs_from_file()
-{
- extern FILE *f;
-
- order = 0;
- numbounds = 0;
- lineno = 0;
-
- if ((f = fopen(configfilename, "r")) == NULL) {
- if (errno != ENOENT)
- log(LOG_ERR, errno, "can't open %s", configfilename);
- return;
- }
-
- ifc.ifc_buf = (char *)ifbuf;
- ifc.ifc_len = sizeof(ifbuf);
- if (ioctl(udp_socket, SIOCGIFCONF, (char *)&ifc) < 0)
- log(LOG_ERR, errno, "ioctl SIOCGIFCONF");
-
- yyparse();
-
- fclose(f);
-}
-
-static u_int32
-valid_if(s)
-char *s;
-{
- register vifi_t vifi;
- register struct uvif *v;
-
- for (vifi=0, v=uvifs; vifi<numvifs; vifi++, v++)
- if (!strcmp(v->uv_name, s))
- return v->uv_lcl_addr;
-
- return 0;
-}
-
-static struct ifreq *
-ifconfaddr(ifcp, a)
- struct ifconf *ifcp;
- u_int32 a;
-{
- int n;
- struct ifreq *ifrp = (struct ifreq *)ifcp->ifc_buf;
- struct ifreq *ifend = (struct ifreq *)((char *)ifrp + ifcp->ifc_len);
-
- while (ifrp < ifend) {
- if (ifrp->ifr_addr.sa_family == AF_INET &&
- ((struct sockaddr_in *)&ifrp->ifr_addr)->sin_addr.s_addr == a)
- return (ifrp);
-#if (defined(BSD) && (BSD >= 199006))
- n = ifrp->ifr_addr.sa_len + sizeof(ifrp->ifr_name);
- if (n < sizeof(*ifrp))
- ++ifrp;
- else
- ifrp = (struct ifreq *)((char *)ifrp + n);
-#else
- ++ifrp;
-#endif
- }
- return (0);
-}
diff --git a/usr.sbin/mrouted/config.c b/usr.sbin/mrouted/config.c
deleted file mode 100644
index 1147412b904e..000000000000
--- a/usr.sbin/mrouted/config.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * The mrouted program is covered by the license in the accompanying file
- * named "LICENSE". 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.
- *
- *
- * $Id: config.c,v 3.8 1995/11/29 22:36:57 fenner Rel $
- */
-
-
-#include "defs.h"
-
-
-/*
- * Query the kernel to find network interfaces that are multicast-capable
- * and install them in the uvifs array.
- */
-void
-config_vifs_from_kernel()
-{
- struct ifreq ifbuf[32];
- struct ifreq *ifrp, *ifend;
- struct ifconf ifc;
- register struct uvif *v;
- register vifi_t vifi;
- int n;
- u_int32 addr, mask, subnet;
- short flags;
-
- ifc.ifc_buf = (char *)ifbuf;
- ifc.ifc_len = sizeof(ifbuf);
- if (ioctl(udp_socket, SIOCGIFCONF, (char *)&ifc) < 0)
- log(LOG_ERR, errno, "ioctl SIOCGIFCONF");
-
- ifrp = (struct ifreq *)ifbuf;
- ifend = (struct ifreq *)((char *)ifbuf + ifc.ifc_len);
- /*
- * Loop through all of the interfaces.
- */
- for (; ifrp < ifend; ifrp = (struct ifreq *)((char *)ifrp + n)) {
- struct ifreq ifr;
-#if BSD >= 199006
- n = ifrp->ifr_addr.sa_len + sizeof(ifrp->ifr_name);
- if (n < sizeof(*ifrp))
- n = sizeof(*ifrp);
-#else
- n = sizeof(*ifrp);
-#endif
- /*
- * Ignore any interface for an address family other than IP.
- */
- if (ifrp->ifr_addr.sa_family != AF_INET)
- continue;
-
- addr = ((struct sockaddr_in *)&ifrp->ifr_addr)->sin_addr.s_addr;
-
- /*
- * 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.)
- */
- bcopy(ifrp->ifr_name, ifr.ifr_name, sizeof(ifr.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;
-
- /*
- * Ignore any interface whose address and mask do not define a
- * valid subnet number, or whose address is of the form {subnet,0}
- * or {subnet,-1}.
- */
- if (ioctl(udp_socket, SIOCGIFNETMASK, (char *)&ifr) < 0)
- log(LOG_ERR, errno, "ioctl SIOCGIFNETMASK for %s", ifr.ifr_name);
- mask = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
- subnet = addr & mask;
- if (!inet_valid_subnet(subnet, mask) ||
- addr == subnet ||
- addr == (subnet | ~mask)) {
- log(LOG_WARNING, 0,
- "ignoring %s, has invalid address (%s) and/or mask (%s)",
- ifr.ifr_name, inet_fmt(addr, s1), inet_fmt(mask, s2));
- continue;
- }
-
- /*
- * Ignore any interface that is connected to the same subnet as
- * one already installed in the uvifs array.
- */
- for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
- if ((addr & v->uv_subnetmask) == v->uv_subnet ||
- (v->uv_subnet & mask) == subnet) {
- log(LOG_WARNING, 0, "ignoring %s, same subnet as %s",
- ifr.ifr_name, v->uv_name);
- break;
- }
- }
- if (vifi != numvifs) continue;
-
- /*
- * If there is room in the uvifs array, install this interface.
- */
- if (numvifs == MAXVIFS) {
- log(LOG_WARNING, 0, "too many vifs, ignoring %s", ifr.ifr_name);
- continue;
- }
- v = &uvifs[numvifs];
- v->uv_flags = 0;
- v->uv_metric = DEFAULT_METRIC;
- v->uv_rate_limit = DEFAULT_PHY_RATE_LIMIT;
- v->uv_threshold = DEFAULT_THRESHOLD;
- v->uv_lcl_addr = addr;
- v->uv_rmt_addr = 0;
- v->uv_subnet = subnet;
- v->uv_subnetmask = mask;
- v->uv_subnetbcast = subnet | ~mask;
- strncpy(v->uv_name, ifr.ifr_name, IFNAMSIZ);
- v->uv_groups = NULL;
- v->uv_neighbors = NULL;
- v->uv_acl = NULL;
- v->uv_addrs = NULL;
-
- log(LOG_INFO,0,"installing %s (%s on subnet %s) as vif #%u - rate=%d",
- v->uv_name, inet_fmt(addr, s1), inet_fmts(subnet, mask, s2),
- 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;
- }
- }
-}
diff --git a/usr.sbin/mrouted/defs.h b/usr.sbin/mrouted/defs.h
deleted file mode 100644
index 63aef773e77c..000000000000
--- a/usr.sbin/mrouted/defs.h
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * The mrouted program is covered by the license in the accompanying file
- * named "LICENSE". 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.
- *
- *
- * $Id: defs.h,v 3.8 1995/11/29 22:36:34 fenner Rel $
- */
-
-
-#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>
-#ifdef SYSV
-#include <sys/sockio.h>
-#endif
-#include <sys/time.h>
-#include <net/if.h>
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/igmp.h>
-#include <netinet/ip_mroute.h>
-#ifdef RSRR
-#include <sys/un.h>
-#endif /* RSRR */
-
-/*XXX*/
-typedef u_int u_int32;
-
-#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 "dvmrp.h"
-#include "vif.h"
-#include "route.h"
-#include "prune.h"
-#include "pathnames.h"
-#ifdef RSRR
-#include "rsrr.h"
-#include "rsrr_var.h"
-#endif /* RSRR */
-
-/*
- * Miscellaneous constants and macros.
- */
-#define FALSE 0
-#define TRUE 1
-
-#define EQUAL(s1, s2) (strcmp((s1), (s2)) == 0)
-
-#define TIMER_INTERVAL ROUTE_MAX_REPORT_DELAY
-
-#define VENDOR_CODE 1 /* Get a new vendor code if you make significant
- * changes to mrouted. */
-
-#define PROTOCOL_VERSION 3 /* increment when packet format/content changes */
-
-#define MROUTED_VERSION 8 /* increment on local changes or bug fixes, */
- /* reset to 0 whever PROTOCOL_VERSION increments */
-
-#define MROUTED_LEVEL ((MROUTED_VERSION << 8) | PROTOCOL_VERSION | \
- ((NF_PRUNE | NF_GENID | NF_MTRACE) << 16) | \
- (VENDOR_CODE << 24))
- /* for IGMP 'group' field of DVMRP messages */
-
-#define LEAF_FLAGS (( vifs_with_neighbors == 1 ) ? 0x010000 : 0)
- /* more for IGMP 'group' field of DVMRP messages */
-#define DEL_RTE_GROUP 0
-#define DEL_ALL_ROUTES 1
- /* for Deleting kernel table entries */
-
-/* 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
-
-#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 signal(s,f) sigset(s,f)
-#endif
-
-/*
- * External declarations for global variables and functions.
- */
-#define RECV_BUF_SIZE 8192
-extern char *recv_buf;
-extern char *send_buf;
-extern int igmp_socket;
-#ifdef RSRR
-extern int rsrr_socket;
-#endif /* RSRR */
-extern u_int32 allhosts_group;
-extern u_int32 allrtrs_group;
-extern u_int32 dvmrp_group;
-extern u_int32 dvmrp_genid;
-
-#define DEFAULT_DEBUG 2 /* default if "-d" given without value */
-
-extern int debug;
-extern u_char pruning;
-
-extern int routes_changed;
-extern int delay_change_reports;
-extern unsigned nroutes;
-
-extern struct uvif uvifs[MAXVIFS];
-extern vifi_t numvifs;
-extern int vifs_down;
-extern int udp_socket;
-extern int vifs_with_neighbors;
-
-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
-
-#ifdef OLD_KERNEL
-#define MRT_INIT DVMRP_INIT
-#define MRT_DONE DVMRP_DONE
-#define MRT_ADD_VIF DVMRP_ADD_VIF
-#define MRT_DEL_VIF DVMRP_DEL_VIF
-#define MRT_ADD_MFC DVMRP_ADD_MFC
-#define MRT_DEL_MFC DVMRP_DEL_MFC
-
-#define IGMP_PIM 0x14
-#endif
-
-/* main.c */
-extern void log __P((int, int, char *, ...));
-extern int register_input_handler __P((int fd, ihfunc_t func));
-
-/* igmp.c */
-extern void init_igmp __P((void));
-extern void accept_igmp __P((int recvlen));
-extern void send_igmp __P((u_int32 src, u_int32 dst, int type,
- int code, u_int32 group,
- int datalen));
-
-/* callout.c */
-extern void callout_init __P((void));
-extern void age_callout_queue __P((void));
-extern int timer_setTimer __P((int delay, cfunc_t action,
- char *data));
-extern void timer_clearTimer __P((int timer_id));
-
-/* route.c */
-extern void init_routes __P((void));
-extern void start_route_updates __P((void));
-extern void update_route __P((u_int32 origin, u_int32 mask,
- u_int metric, u_int32 src,
- vifi_t vifi));
-extern void age_routes __P((void));
-extern void expire_all_routes __P((void));
-extern void free_all_routes __P((void));
-extern void accept_probe __P((u_int32 src, u_int32 dst,
- char *p, int datalen,
- u_int32 level));
-extern void accept_report __P((u_int32 src, u_int32 dst,
- char *p, int datalen,
- u_int32 level));
-extern struct rtentry * determine_route __P((u_int32 src));
-extern void report __P((int which_routes, vifi_t vifi,
- u_int32 dst));
-extern void report_to_all_neighbors __P((int which_routes));
-extern int report_next_chunk __P((void));
-extern void add_vif_to_routes __P((vifi_t vifi));
-extern void delete_vif_from_routes __P((vifi_t vifi));
-extern void delete_neighbor_from_routes __P((u_int32 addr,
- vifi_t vifi));
-extern void dump_routes __P((FILE *fp));
-extern void start_route_updates __P((void));
-
-/* vif.c */
-extern void init_vifs __P((void));
-extern void check_vif_state __P((void));
-extern vifi_t find_vif __P((u_int32 src, u_int32 dst));
-extern void age_vifs __P((void));
-extern void dump_vifs __P((FILE *fp));
-extern void stop_all_vifs __P((void));
-extern struct listaddr *neighbor_info __P((vifi_t vifi, u_int32 addr));
-extern void accept_group_report __P((u_int32 src, u_int32 dst,
- u_int32 group, int r_type));
-extern void query_groups __P((void));
-extern void probe_for_neighbors __P((void));
-extern int update_neighbor __P((vifi_t vifi, u_int32 addr,
- int msgtype, char *p, int datalen,
- u_int32 level));
-extern void accept_neighbor_request __P((u_int32 src, u_int32 dst));
-extern void accept_neighbor_request2 __P((u_int32 src,
- u_int32 dst));
-extern void accept_neighbors __P((u_int32 src, u_int32 dst,
- u_char *p, int datalen, u_int32 level));
-extern void accept_neighbors2 __P((u_int32 src, u_int32 dst,
- u_char *p, int datalen, u_int32 level));
-extern void accept_leave_message __P((u_int32 src, u_int32 dst,
- u_int32 group));
-extern void accept_membership_query __P((u_int32 src, u_int32 dst,
- u_int32 group, int tmo));
-
-/* config.c */
-extern void config_vifs_from_kernel __P((void));
-
-/* cfparse.y */
-extern void config_vifs_from_file __P((void));
-
-/* inet.c */
-extern int inet_valid_host __P((u_int32 naddr));
-extern int inet_valid_subnet __P((u_int32 nsubnet, u_int32 nmask));
-extern char * inet_fmt __P((u_int32 addr, char *s));
-extern char * inet_fmts __P((u_int32 addr, u_int32 mask, char *s));
-extern u_int32 inet_parse __P((char *s));
-extern int inet_cksum __P((u_short *addr, u_int len));
-
-/* prune.c */
-extern unsigned kroutes;
-extern void add_table_entry __P((u_int32 origin, u_int32 mcastgrp));
-extern void del_table_entry __P((struct rtentry *r,
- u_int32 mcastgrp, u_int del_flag));
-extern void update_table_entry __P((struct rtentry *r));
-extern void init_ktable __P((void));
-extern void accept_prune __P((u_int32 src, u_int32 dst, char *p,
- int datalen));
-extern void steal_sources __P((struct rtentry *rt));
-extern void reset_neighbor_state __P((vifi_t vifi, u_int32 addr));
-extern int grplst_mem __P((vifi_t vifi, u_int32 mcastgrp));
-extern int scoped_addr __P((vifi_t vifi, u_int32 addr));
-extern void free_all_prunes __P((void));
-extern void age_table_entry __P((void));
-extern void dump_cache __P((FILE *fp2));
-extern void update_lclgrp __P((vifi_t vifi, u_int32 mcastgrp));
-extern void delete_lclgrp __P((vifi_t vifi, u_int32 mcastgrp));
-extern void chkgrp_graft __P((vifi_t vifi, u_int32 mcastgrp));
-extern void accept_graft __P((u_int32 src, u_int32 dst, char *p,
- int datalen));
-extern void accept_g_ack __P((u_int32 src, u_int32 dst, char *p,
- int datalen));
-/* u_int is promoted u_char */
-extern void accept_mtrace __P((u_int32 src, u_int32 dst,
- u_int32 group, char *data, u_int no,
- int datalen));
-
-/* kern.c */
-extern void k_set_rcvbuf __P((int bufsize));
-extern void k_hdr_include __P((int bool));
-extern void k_set_ttl __P((int t));
-extern void k_set_loop __P((int l));
-extern void k_set_if __P((u_int32 ifa));
-extern void k_join __P((u_int32 grp, u_int32 ifa));
-extern void k_leave __P((u_int32 grp, u_int32 ifa));
-extern void k_init_dvmrp __P((void));
-extern void k_stop_dvmrp __P((void));
-extern void k_add_vif __P((vifi_t vifi, struct uvif *v));
-extern void k_del_vif __P((vifi_t vifi));
-extern void k_add_rg __P((u_int32 origin, struct gtable *g));
-extern int k_del_rg __P((u_int32 origin, struct gtable *g));
-extern int k_get_version __P((void));
-
-#ifdef SNMP
-/* prune.c */
-extern struct rtentry * snmp_find_route __P(());
-extern struct gtable * find_grp __P(());
-extern struct stable * find_grp_src __P(());
-#endif
-
-#ifdef RSRR
-/* prune.c */
-extern struct gtable *kernel_table;
-extern struct gtable *gtp;
-extern int find_src_grp __P((u_int32 src, u_int32 mask,
- u_int32 grp));
-
-/* rsrr.c */
-extern void rsrr_init __P((void));
-extern void rsrr_read __P((int f, fd_set *rfd));
-extern void rsrr_clean __P((void));
-extern void rsrr_cache_send __P((struct gtable *gt, int notify));
-extern void rsrr_cache_clean __P((struct gtable *gt));
-#endif /* RSRR */
diff --git a/usr.sbin/mrouted/dvmrp.h b/usr.sbin/mrouted/dvmrp.h
deleted file mode 100644
index e471800588dc..000000000000
--- a/usr.sbin/mrouted/dvmrp.h
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * The mrouted program is covered by the license in the accompanying file
- * named "LICENSE". 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.
- *
- *
- * $Id: dvmrp.h,v 3.8 1995/11/29 22:36:57 fenner Rel $
- */
-
-/*
- * A DVMRP message consists of an IP header + an IGMP header + (for some types)
- * zero or more bytes of data.
- *
- * For REPORT messages, the data is route information; the route information
- * consists of one or more lists of the following form:
- *
- * (mask, (origin, metric), (origin, metric), ...)
- *
- * where:
- *
- * "mask" is the subnet mask for all the origins in the list.
- * It is always THREE bytes long, containing the low-order
- * three bytes of the mask (the high-order byte is always
- * 0xff and therefore need not be transmitted).
- *
- * "origin" is the number of a subnet from which multicast datagrams
- * may originate. It is from one to four bytes long,
- * depending on the value of "mask":
- * if all bytes of the mask are zero
- * the subnet number is one byte long
- * else if the low-order two bytes of the mask are zero
- * the subnet number is two bytes long
- * else if the lowest-order byte of the mask is zero
- * the subnet number is three bytes long,
- * else
- * the subnet number is four bytes long.
- *
- * "metric" is a one-byte value consisting of two subfields:
- * - the high-order bit is a flag which, when set, indicates
- * the last (origin, metric) pair of a list.
- * - the low-order seven bits contain the routing metric for
- * the corresponding origin, relative to the sender of the
- * DVMRP report. The metric may have the value of UNREACHABLE
- * added to it as a "split horizon" indication (so called
- * "poisoned reverse").
- *
- * Within a list, the origin subnet numbers must be in ascending order, and
- * the lists themselves are in order of increasing mask value. A message may
- * not exceed 576 bytes, the default maximum IP reassembly size, including
- * the IP and IGMP headers; the route information may be split across more
- * than one message if necessary, by terminating a list in one message and
- * starting a new list in the next message (repeating the same mask value,
- * if necessary).
- *
- * For NEIGHBORS messages, the data is neighboring-router information
- * consisting of one or more lists of the following form:
- *
- * (local-addr, metric, threshold, ncount, neighbor, neighbor, ...)
- *
- * where:
- *
- * "local-addr" is the sending router's address as seen by the neighbors
- * in this list; it is always four bytes long.
- * "metric" is a one-byte unsigned value, the TTL `cost' of forwarding
- * packets to any of the neighbors on this list.
- * "threshold" is a one-byte unsigned value, a lower bound on the TTL a
- * packet must have to be forwarded to any of the neighbors on
- * this list.
- * "ncount" is the number of neighbors in this list.
- * "neighbor" is the address of a neighboring router, four bytes long.
- *
- * As with REPORT messages, NEIGHBORS messages should not exceed 576 bytes,
- * including the IP and IGMP headers; split longer messages by terminating the
- * list in one and continuing in another, repeating the local-addr, etc., if
- * necessary.
- *
- * For NEIGHBORS2 messages, the data is identical to NEIGHBORS except
- * there is a flags byte before the neighbor count:
- *
- * (local-addr, metric, threshold, flags, ncount, neighbor, neighbor, ...)
- */
-
-/*
- * DVMRP message types (carried in the "code" field of an IGMP header)
- */
-#define DVMRP_PROBE 1 /* for finding neighbors */
-#define DVMRP_REPORT 2 /* for reporting some or all routes */
-#define DVMRP_ASK_NEIGHBORS 3 /* sent by mapper, asking for a list */
- /* of this router's neighbors. */
-#define DVMRP_NEIGHBORS 4 /* response to such a request */
-#define DVMRP_ASK_NEIGHBORS2 5 /* as above, want new format reply */
-#define DVMRP_NEIGHBORS2 6
-#define DVMRP_PRUNE 7 /* prune message */
-#define DVMRP_GRAFT 8 /* graft message */
-#define DVMRP_GRAFT_ACK 9 /* graft acknowledgement */
-#define DVMRP_INFO_REQUEST 10 /* information request */
-#define DVMRP_INFO_REPLY 11 /* information reply */
-
-/*
- * 'flags' byte values in DVMRP_NEIGHBORS2 reply.
- */
-#define DVMRP_NF_TUNNEL 0x01 /* neighbors reached via tunnel */
-#define DVMRP_NF_SRCRT 0x02 /* tunnel uses IP source routing */
-#define DVMRP_NF_PIM 0x04 /* neighbor is a PIM neighbor */
-#define DVMRP_NF_DOWN 0x10 /* kernel state of interface */
-#define DVMRP_NF_DISABLED 0x20 /* administratively disabled */
-#define DVMRP_NF_QUERIER 0x40 /* I am the subnet's querier */
-#define DVMRP_NF_LEAF 0x80 /* Neighbor reports that it is a leaf */
-
-/*
- * Request/reply types for info queries/replies
- */
-#define DVMRP_INFO_VERSION 1 /* version string */
-#define DVMRP_INFO_NEIGHBORS 2 /* neighbors2 data */
-
-/*
- * Limit on length of route data
- */
-#define MAX_IP_PACKET_LEN 576
-#define MIN_IP_HEADER_LEN 20
-#define MAX_IP_HEADER_LEN 60
-#define MAX_DVMRP_DATA_LEN \
- ( MAX_IP_PACKET_LEN - MAX_IP_HEADER_LEN - IGMP_MINLEN )
-
-/*
- * Various protocol constants (all times in seconds)
- */
- /* address for multicast DVMRP msgs */
-#define INADDR_DVMRP_GROUP (u_int32)0xe0000004 /* 224.0.0.4 */
-/*
- * 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
-
-#define ROUTE_MAX_REPORT_DELAY 5 /* max delay for reporting changes */
- /* (This is the timer interrupt */
- /* interval; all times must be */
- /* multiples of this value.) */
-
-#define ROUTE_REPORT_INTERVAL 60 /* periodic route report interval */
-#define ROUTE_SWITCH_TIME 140 /* time to switch to equivalent gw */
-#define ROUTE_EXPIRE_TIME 200 /* time to mark route invalid */
-#define ROUTE_DISCARD_TIME 340 /* time to garbage collect route */
-
-#define LEAF_CONFIRMATION_TIME 200 /* time to consider subnet a leaf */
-
-#define NEIGHBOR_PROBE_INTERVAL 10 /* periodic neighbor probe interval */
-#define NEIGHBOR_EXPIRE_TIME 140 /* time to consider neighbor gone */
-
-#define GROUP_QUERY_INTERVAL 125 /* periodic group query interval */
-#define GROUP_EXPIRE_TIME 270 /* time to consider group gone */
-#define LEAVE_EXPIRE_TIME 3 /* " " after receiving a leave */
-/* Note: LEAVE_EXPIRE_TIME should ideally be shorter, but the resolution of
- * the timer in mrouted doesn't allow us to make it any shorter. */
-
-#define UNREACHABLE 32 /* "infinity" metric, must be <= 64 */
-#define DEFAULT_METRIC 1 /* default subnet/tunnel metric */
-#define DEFAULT_THRESHOLD 1 /* default subnet/tunnel threshold */
-
-#define MAX_RATE_LIMIT 100000 /* max rate limit */
-#define DEFAULT_PHY_RATE_LIMIT 0 /* default phyint rate limit */
-#define DEFAULT_TUN_RATE_LIMIT 500 /* default tunnel rate limit */
-
-#define DEFAULT_CACHE_LIFETIME 300 /* kernel route entry discard time */
-#define GRAFT_TIMEOUT_VAL 5 /* retransmission time for grafts */
-
-#define OLD_AGE_THRESHOLD 2
diff --git a/usr.sbin/mrouted/igmp.c b/usr.sbin/mrouted/igmp.c
deleted file mode 100644
index 3c27e6d38d26..000000000000
--- a/usr.sbin/mrouted/igmp.c
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * The mrouted program is covered by the license in the accompanying file
- * named "LICENSE". 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.
- *
- *
- * $Id: igmp.c,v 3.8 1995/11/29 22:36:57 fenner Rel $
- */
-
-
-#include "defs.h"
-
-
-/*
- * Exported variables.
- */
-char *recv_buf; /* input packet buffer */
-char *send_buf; /* output packet buffer */
-int igmp_socket; /* socket for all network I/O */
-u_int32 allhosts_group; /* All hosts addr in net order */
-u_int32 allrtrs_group; /* All-Routers " in net order */
-u_int32 dvmrp_group; /* DVMRP grp addr in net order */
-u_int32 dvmrp_genid; /* IGMP generation id */
-
-/*
- * Local function definitions.
- */
-/* u_char promoted to u_int */
-static char * packet_kind __P((u_int type, u_int code));
-static int igmp_log_level __P((u_int type, u_int code));
-
-/*
- * Open and initialize the igmp socket, and fill in the non-changing
- * IP header fields in the output packet buffer.
- */
-void
-init_igmp()
-{
- struct ip *ip;
-
- recv_buf = malloc(RECV_BUF_SIZE);
- send_buf = malloc(RECV_BUF_SIZE);
-
- if ((igmp_socket = socket(AF_INET, SOCK_RAW, IPPROTO_IGMP)) < 0)
- log(LOG_ERR, errno, "IGMP socket");
-
- k_hdr_include(TRUE); /* include IP header when sending */
- k_set_rcvbuf(48*1024); /* lots of input buffering */
- k_set_ttl(1); /* restrict multicasts to one hop */
- k_set_loop(FALSE); /* disable multicast loopback */
-
- ip = (struct ip *)send_buf;
- ip->ip_hl = sizeof(struct ip) >> 2;
- ip->ip_v = IPVERSION;
- ip->ip_tos = 0;
- ip->ip_off = 0;
- ip->ip_p = IPPROTO_IGMP;
- ip->ip_ttl = MAXTTL; /* applies to unicasts only */
-
- allhosts_group = htonl(INADDR_ALLHOSTS_GROUP);
- dvmrp_group = htonl(INADDR_DVMRP_GROUP);
- allrtrs_group = htonl(INADDR_ALLRTRS_GROUP);
-}
-
-#define PIM_QUERY 0
-#define PIM_REGISTER 1
-#define PIM_REGISTER_STOP 2
-#define PIM_JOIN_PRUNE 3
-#define PIM_RP_REACHABLE 4
-#define PIM_ASSERT 5
-#define PIM_GRAFT 6
-#define PIM_GRAFT_ACK 7
-
-static char *
-packet_kind(type, code)
- u_int type, code;
-{
- switch (type) {
- case IGMP_HOST_MEMBERSHIP_QUERY: return "membership query ";
- case IGMP_HOST_MEMBERSHIP_REPORT: return "membership report ";
- case IGMP_HOST_NEW_MEMBERSHIP_REPORT: return "new member report ";
- case IGMP_HOST_LEAVE_MESSAGE: return "leave message ";
- case IGMP_DVMRP:
- switch (code) {
- case DVMRP_PROBE: return "neighbor probe ";
- case DVMRP_REPORT: return "route report ";
- case DVMRP_ASK_NEIGHBORS: return "neighbor request ";
- case DVMRP_NEIGHBORS: return "neighbor list ";
- case DVMRP_ASK_NEIGHBORS2: return "neighbor request 2";
- case DVMRP_NEIGHBORS2: return "neighbor list 2 ";
- case DVMRP_PRUNE: return "prune message ";
- case DVMRP_GRAFT: return "graft message ";
- case DVMRP_GRAFT_ACK: return "graft message ack ";
- case DVMRP_INFO_REQUEST: return "info request ";
- case DVMRP_INFO_REPLY: return "info reply ";
- default: return "unknown DVMRP msg ";
- }
- case IGMP_PIM:
- switch (code) {
- case PIM_QUERY: return "PIM Router-Query ";
- case PIM_REGISTER: return "PIM Register ";
- case PIM_REGISTER_STOP: return "PIM Register-Stop ";
- case PIM_JOIN_PRUNE: return "PIM Join/Prune ";
- case PIM_RP_REACHABLE: return "PIM RP-Reachable ";
- case PIM_ASSERT: return "PIM Assert ";
- case PIM_GRAFT: return "PIM Graft ";
- case PIM_GRAFT_ACK: return "PIM Graft-Ack ";
- default: return "unknown PIM msg ";
- }
- case IGMP_MTRACE: return "IGMP trace query ";
- case IGMP_MTRACE_RESP: return "IGMP trace reply ";
- default: return "unknown IGMP msg ";
- }
-}
-
-/*
- * Process a newly received IGMP packet that is sitting in the input
- * packet buffer.
- */
-void
-accept_igmp(recvlen)
- int recvlen;
-{
- register u_int32 src, dst, group;
- struct ip *ip;
- struct igmp *igmp;
- int ipdatalen, iphdrlen, igmpdatalen;
-
- if (recvlen < sizeof(struct ip)) {
- log(LOG_WARNING, 0,
- "received packet too short (%u bytes) for IP header", recvlen);
- return;
- }
-
- ip = (struct ip *)recv_buf;
- src = ip->ip_src.s_addr;
- dst = ip->ip_dst.s_addr;
-
- /*
- * this is most likely a message from the kernel indicating that
- * a new src grp pair message has arrived and so, it would be
- * necessary to install a route into the kernel for this.
- */
- if (ip->ip_p == 0) {
- if (src == 0 || dst == 0)
- log(LOG_WARNING, 0, "kernel request not accurate");
- else
- add_table_entry(src, dst);
- return;
- }
-
- iphdrlen = ip->ip_hl << 2;
- ipdatalen = ip->ip_len;
- if (iphdrlen + ipdatalen != recvlen) {
- log(LOG_WARNING, 0,
- "received packet from %s shorter (%u bytes) than hdr+data length (%u+%u)",
- inet_fmt(src, s1), recvlen, iphdrlen, ipdatalen);
- return;
- }
-
- igmp = (struct igmp *)(recv_buf + iphdrlen);
- group = igmp->igmp_group.s_addr;
- igmpdatalen = ipdatalen - IGMP_MINLEN;
- if (igmpdatalen < 0) {
- log(LOG_WARNING, 0,
- "received IP data field too short (%u bytes) for IGMP, from %s",
- ipdatalen, inet_fmt(src, s1));
- return;
- }
-
- log(LOG_DEBUG, 0, "RECV %s from %-15s to %s",
- packet_kind(igmp->igmp_type, igmp->igmp_code),
- inet_fmt(src, s1), inet_fmt(dst, s2));
-
- switch (igmp->igmp_type) {
-
- case IGMP_HOST_MEMBERSHIP_QUERY:
- accept_membership_query(src, dst, group, igmp->igmp_code);
- return;
-
- case IGMP_HOST_MEMBERSHIP_REPORT:
- case IGMP_HOST_NEW_MEMBERSHIP_REPORT:
- accept_group_report(src, dst, group, igmp->igmp_type);
- return;
-
- case IGMP_HOST_LEAVE_MESSAGE:
- accept_leave_message(src, dst, group);
- return;
-
- case IGMP_DVMRP:
- group = ntohl(group);
-
- switch (igmp->igmp_code) {
- case DVMRP_PROBE:
- accept_probe(src, dst,
- (char *)(igmp+1), igmpdatalen, group);
- return;
-
- case DVMRP_REPORT:
- accept_report(src, dst,
- (char *)(igmp+1), igmpdatalen, group);
- return;
-
- case DVMRP_ASK_NEIGHBORS:
- accept_neighbor_request(src, dst);
- return;
-
- case DVMRP_ASK_NEIGHBORS2:
- accept_neighbor_request2(src, dst);
- return;
-
- case DVMRP_NEIGHBORS:
- accept_neighbors(src, dst, (u_char *)(igmp+1), igmpdatalen,
- group);
- return;
-
- case DVMRP_NEIGHBORS2:
- accept_neighbors2(src, dst, (u_char *)(igmp+1), igmpdatalen,
- group);
- return;
-
- case DVMRP_PRUNE:
- accept_prune(src, dst, (char *)(igmp+1), igmpdatalen);
- return;
-
- case DVMRP_GRAFT:
- accept_graft(src, dst, (char *)(igmp+1), igmpdatalen);
- return;
-
- case DVMRP_GRAFT_ACK:
- accept_g_ack(src, dst, (char *)(igmp+1), igmpdatalen);
- return;
-
- case DVMRP_INFO_REQUEST:
- accept_info_request(src, dst, (char *)(igmp+1),
- igmpdatalen);
- return;
-
- case DVMRP_INFO_REPLY:
- accept_info_reply(src, dst, (char *)(igmp+1), igmpdatalen);
- return;
-
- default:
- log(LOG_INFO, 0,
- "ignoring unknown DVMRP message code %u from %s to %s",
- igmp->igmp_code, inet_fmt(src, s1),
- inet_fmt(dst, s2));
- return;
- }
-
- case IGMP_PIM:
- return;
-
- case IGMP_MTRACE_RESP:
- return;
-
- case IGMP_MTRACE:
- accept_mtrace(src, dst, group, (char *)(igmp+1),
- igmp->igmp_code, igmpdatalen);
- return;
-
- default:
- log(LOG_INFO, 0,
- "ignoring unknown IGMP message type %x from %s to %s",
- igmp->igmp_type, inet_fmt(src, s1),
- inet_fmt(dst, s2));
- return;
- }
-}
-
-/*
- * Some IGMP 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.
- */
-static int
-igmp_log_level(type, code)
- u_int type, code;
-{
- switch (type) {
- case IGMP_MTRACE_RESP:
- return LOG_INFO;
-
- case IGMP_DVMRP:
- switch (code) {
- case DVMRP_NEIGHBORS:
- case DVMRP_NEIGHBORS2:
- return LOG_INFO;
- }
- }
- return LOG_WARNING;
-}
-
-/*
- * Construct an IGMP message in the output packet buffer. The caller may
- * have already placed data in that buffer, of length 'datalen'. Then send
- * the message from the interface with IP address 'src' to destination 'dst'.
- */
-void
-send_igmp(src, dst, type, code, group, datalen)
- u_int32 src, dst;
- int type, code;
- u_int32 group;
- int datalen;
-{
- struct sockaddr_in sdst;
- struct ip *ip;
- struct igmp *igmp;
- int setloop;
-
- ip = (struct ip *)send_buf;
- ip->ip_src.s_addr = src;
- ip->ip_dst.s_addr = dst;
- ip->ip_len = MIN_IP_HEADER_LEN + IGMP_MINLEN + datalen;
-
- igmp = (struct igmp *)(send_buf + MIN_IP_HEADER_LEN);
- igmp->igmp_type = type;
- igmp->igmp_code = code;
- igmp->igmp_group.s_addr = group;
- igmp->igmp_cksum = 0;
- igmp->igmp_cksum = inet_cksum((u_short *)igmp,
- IGMP_MINLEN + datalen);
-
- if (IN_MULTICAST(ntohl(dst))) {
- k_set_if(src);
- if (type != IGMP_DVMRP) {
- setloop = 1;
- k_set_loop(TRUE);
- }
- }
-
- bzero(&sdst, sizeof(sdst));
- sdst.sin_family = AF_INET;
-#if (defined(BSD) && (BSD >= 199103))
- sdst.sin_len = sizeof(sdst);
-#endif
- sdst.sin_addr.s_addr = dst;
- if (sendto(igmp_socket, send_buf, ip->ip_len, 0,
- (struct sockaddr *)&sdst, sizeof(sdst)) < 0) {
- if (errno == ENETDOWN)
- check_vif_state();
- else
- log(igmp_log_level(type, code), errno,
- "sendto to %s on %s",
- inet_fmt(dst, s1), inet_fmt(src, s2));
- }
-
- if (setloop)
- k_set_loop(FALSE);
-
- log(LOG_DEBUG, 0, "SENT %s from %-15s to %s",
- packet_kind(type, code), inet_fmt(src, s1), inet_fmt(dst, s2));
-}
diff --git a/usr.sbin/mrouted/inet.c b/usr.sbin/mrouted/inet.c
deleted file mode 100644
index b60e3854da35..000000000000
--- a/usr.sbin/mrouted/inet.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * The mrouted program is covered by the license in the accompanying file
- * named "LICENSE". 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.
- *
- *
- * $Id: inet.c,v 3.8 1995/11/29 22:36:57 fenner Rel $
- */
-
-
-#include "defs.h"
-
-
-/*
- * Exported variables.
- */
-char s1[19]; /* buffers to hold the string representations */
-char s2[19]; /* of IP addresses, to be passed to inet_fmt() */
-char s3[19]; /* or inet_fmts(). */
-char s4[19];
-
-
-/*
- * Verify that a given IP address is credible as a host address.
- * (Without a mask, cannot detect addresses of the form {subnet,0} or
- * {subnet,-1}.)
- */
-int
-inet_valid_host(naddr)
- u_int32 naddr;
-{
- register u_int32 addr;
-
- addr = ntohl(naddr);
-
- return (!(IN_MULTICAST(addr) ||
- IN_BADCLASS (addr) ||
- (addr & 0xff000000) == 0));
-}
-
-/*
- * Verify that a given netmask is plausible;
- * make sure that it is a series of 1's followed by
- * a series of 0's with no discontiguous 1's.
- */
-int
-inet_valid_mask(mask)
- u_int32 mask;
-{
- if (~(((mask & -mask) - 1) | mask) != 0) {
- /* Mask is not contiguous */
- return (FALSE);
- }
-
- return (TRUE);
-}
-
-/*
- * Verify that a given subnet number and mask pair are credible.
- *
- * With CIDR, almost any subnet and mask are credible. mrouted still
- * can't handle aggregated class A's, so we still check that, but
- * otherwise the only requirements are that the subnet address is
- * within the [ABC] range and that the host bits of the subnet
- * are all 0.
- */
-int
-inet_valid_subnet(nsubnet, nmask)
- u_int32 nsubnet, nmask;
-{
- register u_int32 subnet, mask;
-
- subnet = ntohl(nsubnet);
- mask = ntohl(nmask);
-
- if ((subnet & mask) != subnet) return (FALSE);
-
- if (subnet == 0)
- return (mask == 0);
-
- if (IN_CLASSA(subnet)) {
- if (mask < 0xff000000 ||
- (subnet & 0xff000000) == 0x7f000000 ||
- (subnet & 0xff000000) == 0x00000000) return (FALSE);
- }
- else if (IN_CLASSD(subnet) || IN_BADCLASS(subnet)) {
- /* Above Class C address space */
- return (FALSE);
- }
- if (subnet & ~mask) {
- /* Host bits are set in the subnet */
- return (FALSE);
- }
- if (!inet_valid_mask(mask)) {
- /* Netmask is not contiguous */
- return (FALSE);
- }
-
- return (TRUE);
-}
-
-
-/*
- * Convert an IP address in u_long (network) format into a printable string.
- */
-char *
-inet_fmt(addr, s)
- u_int32 addr;
- char *s;
-{
- register u_char *a;
-
- a = (u_char *)&addr;
- sprintf(s, "%u.%u.%u.%u", a[0], a[1], a[2], a[3]);
- return (s);
-}
-
-
-/*
- * Convert an IP subnet number in u_long (network) format into a printable
- * string including the netmask as a number of bits.
- */
-char *
-inet_fmts(addr, mask, s)
- u_int32 addr, mask;
- char *s;
-{
- register u_char *a, *m;
- int bits;
-
- if ((addr == 0) && (mask == 0)) {
- sprintf(s, "default");
- return (s);
- }
- a = (u_char *)&addr;
- m = (u_char *)&mask;
- bits = 33 - ffs(ntohl(mask));
-
- if (m[3] != 0) sprintf(s, "%u.%u.%u.%u/%d", a[0], a[1], a[2], a[3],
- bits);
- else if (m[2] != 0) sprintf(s, "%u.%u.%u/%d", a[0], a[1], a[2], bits);
- else if (m[1] != 0) sprintf(s, "%u.%u/%d", a[0], a[1], bits);
- else sprintf(s, "%u/%d", a[0], bits);
-
- return (s);
-}
-
-/*
- * Convert the printable string representation of an IP address into the
- * u_long (network) format. Return 0xffffffff on error. (To detect the
- * legal address with that value, you must explicitly compare the string
- * with "255.255.255.255".)
- */
-u_int32
-inet_parse(s)
- char *s;
-{
- u_int32 a = 0;
- u_int a0, a1, a2, a3;
- char c;
-
- if (sscanf(s, "%u.%u.%u.%u%c", &a0, &a1, &a2, &a3, &c) != 4 ||
- a0 > 255 || a1 > 255 || a2 > 255 || a3 > 255)
- return (0xffffffff);
-
- ((u_char *)&a)[0] = a0;
- ((u_char *)&a)[1] = a1;
- ((u_char *)&a)[2] = a2;
- ((u_char *)&a)[3] = a3;
-
- return (a);
-}
-
-
-/*
- * inet_cksum extracted from:
- * P I N G . C
- *
- * Author -
- * Mike Muuss
- * U. S. Army Ballistic Research Laboratory
- * December, 1983
- * Modified at Uc Berkeley
- *
- * (ping.c) Status -
- * Public Domain. Distribution Unlimited.
- *
- * I N _ C K S U M
- *
- * Checksum routine for Internet Protocol family headers (C Version)
- *
- */
-int
-inet_cksum(addr, len)
- u_short *addr;
- u_int len;
-{
- register int nleft = (int)len;
- register u_short *w = addr;
- u_short answer = 0;
- register int sum = 0;
-
- /*
- * 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.
- */
- 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/mrouted/kern.c b/usr.sbin/mrouted/kern.c
deleted file mode 100644
index 2a64e5c13916..000000000000
--- a/usr.sbin/mrouted/kern.c
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * The mrouted program is covered by the license in the accompanying file
- * named "LICENSE". 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.
- *
- *
- * $Id: kern.c,v 3.8 1995/11/29 22:36:57 fenner Rel $
- */
-
-
-#include "defs.h"
-
-
-void k_set_rcvbuf(bufsize)
- int bufsize;
-{
- if (setsockopt(igmp_socket, SOL_SOCKET, SO_RCVBUF,
- (char *)&bufsize, sizeof(bufsize)) < 0)
- log(LOG_ERR, errno, "setsockopt SO_RCVBUF %u", bufsize);
-}
-
-
-void k_hdr_include(bool)
- int bool;
-{
-#ifdef IP_HDRINCL
- if (setsockopt(igmp_socket, IPPROTO_IP, IP_HDRINCL,
- (char *)&bool, sizeof(bool)) < 0)
- log(LOG_ERR, errno, "setsockopt IP_HDRINCL %u", bool);
-#endif
-}
-
-
-void k_set_ttl(t)
- int t;
-{
- u_char ttl;
-
- ttl = t;
- if (setsockopt(igmp_socket, IPPROTO_IP, IP_MULTICAST_TTL,
- (char *)&ttl, sizeof(ttl)) < 0)
- log(LOG_ERR, errno, "setsockopt IP_MULTICAST_TTL %u", ttl);
-}
-
-
-void k_set_loop(l)
- int l;
-{
- u_char loop;
-
- loop = l;
- if (setsockopt(igmp_socket, IPPROTO_IP, IP_MULTICAST_LOOP,
- (char *)&loop, sizeof(loop)) < 0)
- log(LOG_ERR, errno, "setsockopt IP_MULTICAST_LOOP %u", loop);
-}
-
-
-void k_set_if(ifa)
- u_int32 ifa;
-{
- struct in_addr adr;
-
- adr.s_addr = ifa;
- if (setsockopt(igmp_socket, IPPROTO_IP, IP_MULTICAST_IF,
- (char *)&adr, sizeof(adr)) < 0)
- log(LOG_ERR, errno, "setsockopt IP_MULTICAST_IF %s",
- inet_fmt(ifa, s1));
-}
-
-
-void k_join(grp, ifa)
- u_int32 grp;
- u_int32 ifa;
-{
- struct ip_mreq mreq;
-
- mreq.imr_multiaddr.s_addr = grp;
- mreq.imr_interface.s_addr = ifa;
-
- if (setsockopt(igmp_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP,
- (char *)&mreq, sizeof(mreq)) < 0)
- log(LOG_WARNING, errno, "can't join group %s on interface %s",
- inet_fmt(grp, s1), inet_fmt(ifa, s2));
-}
-
-
-void k_leave(grp, ifa)
- u_int32 grp;
- u_int32 ifa;
-{
- struct ip_mreq mreq;
-
- mreq.imr_multiaddr.s_addr = grp;
- mreq.imr_interface.s_addr = ifa;
-
- if (setsockopt(igmp_socket, IPPROTO_IP, IP_DROP_MEMBERSHIP,
- (char *)&mreq, sizeof(mreq)) < 0)
- log(LOG_WARNING, errno, "can't leave group %s on interface %s",
- inet_fmt(grp, s1), inet_fmt(ifa, s2));
-}
-
-
-void k_init_dvmrp()
-{
-#ifdef OLD_KERNEL
- if (setsockopt(igmp_socket, IPPROTO_IP, MRT_INIT,
- (char *)NULL, 0) < 0)
-#else
- int v=1;
-
- if (setsockopt(igmp_socket, IPPROTO_IP, MRT_INIT,
- (char *)&v, sizeof(int)) < 0)
-#endif
- log(LOG_ERR, errno, "can't enable Multicast routing in kernel");
-}
-
-
-void k_stop_dvmrp()
-{
- if (setsockopt(igmp_socket, IPPROTO_IP, MRT_DONE,
- (char *)NULL, 0) < 0)
- log(LOG_WARNING, errno, "can't disable Multicast routing in kernel");
-}
-
-
-void k_add_vif(vifi, v)
- vifi_t vifi;
- struct uvif *v;
-{
- struct vifctl vc;
-
- vc.vifc_vifi = vifi;
- vc.vifc_flags = v->uv_flags & VIFF_KERNEL_FLAGS;
- vc.vifc_threshold = v->uv_threshold;
- vc.vifc_rate_limit = v->uv_rate_limit;
- vc.vifc_lcl_addr.s_addr = v->uv_lcl_addr;
- vc.vifc_rmt_addr.s_addr = v->uv_rmt_addr;
-
- if (setsockopt(igmp_socket, IPPROTO_IP, MRT_ADD_VIF,
- (char *)&vc, sizeof(vc)) < 0)
- log(LOG_ERR, errno, "setsockopt MRT_ADD_VIF");
-}
-
-
-void k_del_vif(vifi)
- vifi_t vifi;
-{
- if (setsockopt(igmp_socket, IPPROTO_IP, MRT_DEL_VIF,
- (char *)&vifi, sizeof(vifi)) < 0)
- log(LOG_ERR, errno, "setsockopt MRT_DEL_VIF");
-}
-
-
-/*
- * Adds a (source, mcastgrp) entry to the kernel
- */
-void k_add_rg(origin, g)
- u_int32 origin;
- struct gtable *g;
-{
- struct mfcctl mc;
- vifi_t i;
-
-#ifdef DEBUG_MFC
- md_log(MD_ADD, origin, g->gt_mcastgrp);
-#endif
- /* copy table values so that setsockopt can process it */
- mc.mfcc_origin.s_addr = origin;
-#ifdef OLD_KERNEL
- mc.mfcc_originmask.s_addr = 0xffffffff;
-#endif
- mc.mfcc_mcastgrp.s_addr = g->gt_mcastgrp;
- mc.mfcc_parent = g->gt_route ? g->gt_route->rt_parent : NO_VIF;
- for (i = 0; i < numvifs; i++)
- mc.mfcc_ttls[i] = g->gt_ttls[i];
-
- /* write to kernel space */
- if (setsockopt(igmp_socket, IPPROTO_IP, MRT_ADD_MFC,
- (char *)&mc, sizeof(mc)) < 0) {
-#ifdef DEBUG_MFC
- md_log(MD_ADD_FAIL, origin, g->gt_mcastgrp);
-#endif
- log(LOG_WARNING, errno, "setsockopt MRT_ADD_MFC");
- }
-}
-
-
-/*
- * Deletes a (source, mcastgrp) entry from the kernel
- */
-int k_del_rg(origin, g)
- u_int32 origin;
- struct gtable *g;
-{
- struct mfcctl mc;
- int retval;
-
-#ifdef DEBUG_MFC
- md_log(MD_DEL, origin, g->gt_mcastgrp);
-#endif
- /* copy table values so that setsockopt can process it */
- mc.mfcc_origin.s_addr = origin;
-#ifdef OLD_KERNEL
- mc.mfcc_originmask.s_addr = 0xffffffff;
-#endif
- mc.mfcc_mcastgrp.s_addr = g->gt_mcastgrp;
-
- /* write to kernel space */
- if ((retval = setsockopt(igmp_socket, IPPROTO_IP, MRT_DEL_MFC,
- (char *)&mc, sizeof(mc))) < 0) {
-#ifdef DEBUG_MFC
- md_log(MD_DEL_FAIL, origin, g->gt_mcastgrp);
-#endif
- log(LOG_WARNING, errno, "setsockopt MRT_DEL_MFC");
- }
-
- return retval;
-}
-
-/*
- * Get the kernel's idea of what version of mrouted needs to run with it.
- */
-int k_get_version()
-{
-#ifdef OLD_KERNEL
- return -1;
-#else
- int vers;
- int len = sizeof(vers);
-
- if (getsockopt(igmp_socket, IPPROTO_IP, MRT_VERSION,
- (char *)&vers, &len) < 0)
- log(LOG_ERR, errno,
- "getsockopt MRT_VERSION: perhaps your kernel is too old");
-
- return vers;
-#endif
-}
diff --git a/usr.sbin/mrouted/main.c b/usr.sbin/mrouted/main.c
deleted file mode 100644
index b5ef723bcb73..000000000000
--- a/usr.sbin/mrouted/main.c
+++ /dev/null
@@ -1,757 +0,0 @@
-/*
- * The mrouted program is covered by the license in the accompanying file
- * named "LICENSE". 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.
- *
- *
- * $Id: main.c,v 3.8 1995/11/29 22:36:34 fenner Rel $
- */
-
-/*
- * Written by Steve Deering, Stanford University, February 1989.
- *
- * (An earlier version of DVMRP was implemented by David Waitzman of
- * BBN STC by extending Berkeley's routed program. Some of Waitzman's
- * extensions have been incorporated into mrouted, but none of the
- * original routed code has been adopted.)
- */
-
-
-#include "defs.h"
-#ifdef __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-#include <fcntl.h>
-
-#ifdef SNMP
-#include "snmp.h"
-#endif
-
-#ifndef lint
-static char rcsid[] =
- "@(#) $Id: main.c,v 3.8 1995/11/29 22:36:34 fenner Rel $";
-#endif
-
-extern char *configfilename;
-char versionstring[100];
-
-static char pidfilename[] = _PATH_MROUTED_PID;
-static char dumpfilename[] = _PATH_MROUTED_DUMP;
-static char cachefilename[] = _PATH_MROUTED_CACHE;
-static char genidfilename[] = _PATH_MROUTED_GENID;
-
-int cache_lifetime = DEFAULT_CACHE_LIFETIME;
-int max_prune_lifetime = DEFAULT_CACHE_LIFETIME * 2;
-
-int debug = 0;
-u_char pruning = 1; /* Enable pruning by default */
-
-#ifdef SNMP
-#define NHANDLERS 34
-#else
-#define NHANDLERS 2
-#endif
-
-static struct ihandler {
- int fd; /* File descriptor */
- ihfunc_t func; /* Function to call with &fd_set */
-} ihandlers[NHANDLERS];
-static int nhandlers = 0;
-
-/*
- * Forward declarations.
- */
-static void fasttimer __P((int));
-static void done __P((int));
-static void dump __P((int));
-static void fdump __P((int));
-static void cdump __P((int));
-static void restart __P((int));
-static void timer __P((void));
-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[];
-{
- register int recvlen;
- register int omask;
- int dummy;
- FILE *fp;
- struct timeval tv;
- u_int32 prev_genid;
- int vers;
- fd_set rfds, readers;
- int nfds, n, i;
-#ifdef SNMP
- struct timeval timeout, *tvp = &timeout;
- struct timeval sched, *svp = &sched, now, *nvp = &now;
- int index, block;
-#endif
-
- setlinebuf(stderr);
-
- if (geteuid() != 0) {
- fprintf(stderr, "must be root\n");
- exit(1);
- }
-
- argv++, argc--;
- while (argc > 0 && *argv[0] == '-') {
- if (strcmp(*argv, "-d") == 0) {
- if (argc > 1 && isdigit(*(argv + 1)[0])) {
- argv++, argc--;
- debug = atoi(*argv);
- } else
- debug = DEFAULT_DEBUG;
- } else if (strcmp(*argv, "-c") == 0) {
- if (argc > 1) {
- argv++, argc--;
- configfilename = *argv;
- } else
- goto usage;
- } else if (strcmp(*argv, "-p") == 0) {
- pruning = 0;
-#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: fprintf(stderr,
- "usage: mrouted [-p] [-c configfile] [-d [debug_level]]\n");
- exit(1);
- }
-
- if (debug == 0) {
- /*
- * Detach from the terminal
- */
- int t;
-
- if (fork()) exit(0);
- (void)close(0);
- (void)close(1);
- (void)close(2);
- (void)open("/", 0);
- (void)dup2(0, 1);
- (void)dup2(0, 2);
-#ifdef SYSV
- (void)setpgrp();
-#else
-#ifdef TIOCNOTTY
- t = open("/dev/tty", 2);
- if (t >= 0) {
- (void)ioctl(t, TIOCNOTTY, (char *)0);
- (void)close(t);
- }
-#else
- if (setsid() < 0)
- perror("setsid");
-#endif
-#endif
- }
- else
- fprintf(stderr, "debug level %u\n", debug);
-
-#ifdef LOG_DAEMON
- (void)openlog("mrouted", LOG_PID, LOG_DAEMON);
- (void)setlogmask(LOG_UPTO(LOG_NOTICE));
-#else
- (void)openlog("mrouted", LOG_PID);
-#endif
- sprintf(versionstring, "mrouted version %d.%d",
- PROTOCOL_VERSION, MROUTED_VERSION);
-
- log(LOG_NOTICE, 0, "%s", versionstring);
-
-#ifdef SYSV
- srand48(time(NULL));
-#else
- srandom(gethostid());
-#endif
-
- /*
- * Get generation id
- */
- gettimeofday(&tv, 0);
- dvmrp_genid = tv.tv_sec;
-
- fp = fopen(genidfilename, "r");
- if (fp != NULL) {
- fscanf(fp, "%d", &prev_genid);
- if (prev_genid == dvmrp_genid)
- dvmrp_genid++;
- (void) fclose(fp);
- }
-
- fp = fopen(genidfilename, "w");
- if (fp != NULL) {
- fprintf(fp, "%d", dvmrp_genid);
- (void) fclose(fp);
- }
-
- callout_init();
- init_igmp();
- init_routes();
- init_ktable();
- k_init_dvmrp(); /* enable DVMRP routing in kernel */
-
-#ifndef OLD_KERNEL
- vers = k_get_version();
- /*XXX
- * This function must change whenever the kernel version changes
- */
- if ((((vers >> 8) & 0xff) != 3) ||
- ((vers & 0xff) != 5))
- log(LOG_ERR, 0, "kernel (v%d.%d)/mrouted (v%d.%d) version mismatch",
- (vers >> 8) & 0xff, vers & 0xff,
- PROTOCOL_VERSION, MROUTED_VERSION);
-#endif
-
-#ifdef SNMP
- if (i = snmp_init())
- return i;
-
- gettimeofday(nvp, 0);
- if (nvp->tv_usec < 500000L){
- svp->tv_usec = nvp->tv_usec + 500000L;
- svp->tv_sec = nvp->tv_sec;
- } else {
- svp->tv_usec = nvp->tv_usec - 500000L;
- svp->tv_sec = nvp->tv_sec + 1;
- }
-#endif /* SNMP */
-
- init_vifs();
-
-#ifdef RSRR
- rsrr_init();
-#endif /* RSRR */
-
-#if defined(__STDC__) || defined(__GNUC__)
- /*
- * Allow cleanup if unexpected exit. Apparently some architectures
- * have a kernel bug where closing the socket doesn't do an
- * ip_mrouter_done(), so we attempt to do it on exit.
- */
- atexit(cleanup);
-#endif
-
- if (debug)
- fprintf(stderr, "pruning %s\n", pruning ? "on" : "off");
-
- fp = fopen(pidfilename, "w");
- if (fp != NULL) {
- fprintf(fp, "%d\n", (int)getpid());
- (void) fclose(fp);
- }
-
- (void)signal(SIGALRM, fasttimer);
-
- (void)signal(SIGHUP, restart);
- (void)signal(SIGTERM, done);
- (void)signal(SIGINT, done);
- (void)signal(SIGUSR1, fdump);
- (void)signal(SIGUSR2, cdump);
- if (debug != 0)
- (void)signal(SIGQUIT, dump);
-
- FD_ZERO(&readers);
- FD_SET(igmp_socket, &readers);
- nfds = igmp_socket + 1;
- for (i = 0; i < nhandlers; i++) {
- FD_SET(ihandlers[i].fd, &readers);
- if (ihandlers[i].fd >= nfds)
- nfds = ihandlers[i].fd + 1;
- }
-
- /*
- * Install the vifs in the kernel as late as possible in the
- * initialization sequence.
- */
- init_installvifs();
-
- if (debug >= 2) dump(0);
-
- /* Start up the log rate-limiter */
- resetlogging(NULL);
-
- (void)alarm(1); /* schedule first timer interrupt */
-
- /*
- * Main receive loop.
- */
- dummy = 0;
- for(;;) {
-#ifdef SYSV
- sigset_t block, oblock;
-#endif
- bcopy((char *)&readers, (char *)&rfds, sizeof(rfds));
-#ifdef SNMP
- gettimeofday(nvp, 0);
- if (nvp->tv_sec > svp->tv_sec
- || (nvp->tv_sec == svp->tv_sec && nvp->tv_usec > svp->tv_usec)){
- alarmTimer(nvp);
- eventTimer(nvp);
- if (nvp->tv_usec < 500000L){
- svp->tv_usec = nvp->tv_usec + 500000L;
- svp->tv_sec = nvp->tv_sec;
- } else {
- svp->tv_usec = nvp->tv_usec - 500000L;
- svp->tv_sec = nvp->tv_sec + 1;
- }
- }
-
- tvp = &timeout;
- tvp->tv_sec = 0;
- tvp->tv_usec = 500000L;
-
- block = 0;
- snmp_select_info(&nfds, &rfds, tvp, &block);
- if (block == 1)
- tvp = NULL; /* block without timeout */
- if ((n = select(nfds, &rfds, NULL, NULL, tvp)) < 0)
-#else
- if ((n = select(nfds, &rfds, NULL, NULL, NULL)) < 0)
-#endif
- {
- if (errno != EINTR) /* SIGALRM is expected */
- log(LOG_WARNING, errno, "select failed");
- continue;
- }
-
- if (FD_ISSET(igmp_socket, &rfds)) {
- recvlen = recvfrom(igmp_socket, recv_buf, RECV_BUF_SIZE,
- 0, NULL, &dummy);
- if (recvlen < 0) {
- if (errno != EINTR) log(LOG_ERR, errno, "recvfrom");
- continue;
- }
-#ifdef SYSV
- (void)sigemptyset(&block);
- (void)sigaddset(&block, SIGALRM);
- if (sigprocmask(SIG_BLOCK, &block, &oblock) < 0)
- log(LOG_ERR, errno, "sigprocmask");
-#else
- omask = sigblock(sigmask(SIGALRM));
-#endif
- accept_igmp(recvlen);
-#ifdef SYSV
- (void)sigprocmask(SIG_SETMASK, &oblock, (sigset_t *)NULL);
-#else
- (void)sigsetmask(omask);
-#endif
- }
-
- for (i = 0; i < nhandlers; i++) {
- if (FD_ISSET(ihandlers[i].fd, &rfds)) {
- (*ihandlers[i].func)(ihandlers[i].fd, &rfds);
- }
- }
-
-#ifdef SNMP
- snmp_read(&rfds);
- snmp_timeout(); /* poll */
-#endif
- }
-}
-
-
-/*
- * routine invoked every second. Its main goal is to cycle through
- * the routing table and send partial updates to all neighbors at a
- * rate that will cause the entire table to be sent in ROUTE_REPORT_INTERVAL
- * seconds. Also, every TIMER_INTERVAL seconds it calls timer() to
- * do all the other time-based processing.
- */
-static void
-fasttimer(i)
- int i;
-{
- static unsigned int tlast;
- static unsigned int nsent;
- register unsigned int t = tlast + 1;
- register int n;
-
- /*
- * if we're in the last second, send everything that's left.
- * otherwise send at least the fraction we should have sent by now.
- */
- if (t >= ROUTE_REPORT_INTERVAL) {
- register int nleft = nroutes - nsent;
- while (nleft > 0) {
- if ((n = report_next_chunk()) <= 0)
- break;
- nleft -= n;
- }
- tlast = 0;
- nsent = 0;
- } else {
- register unsigned int ncum = nroutes * t / ROUTE_REPORT_INTERVAL;
- while (nsent < ncum) {
- if ((n = report_next_chunk()) <= 0)
- break;
- nsent += n;
- }
- tlast = t;
- }
- if ((t % TIMER_INTERVAL) == 0)
- timer();
-
- age_callout_queue();/* Advance the timer for the callout queue
- for groups */
- alarm(1);
-}
-
-/*
- * 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.
- */
-
-static u_long virtual_time = 0;
-
-
-/*
- * Timer routine. Performs periodic neighbor probing, route reporting, and
- * group querying duties, and drives various timers in routing entries and
- * virtual interface data structures.
- */
-static void
-timer()
-{
- age_routes(); /* Advance the timers in the route entries */
- age_vifs(); /* Advance the timers for neighbors */
- age_table_entry(); /* Advance the timers for the cache entries */
-
- if (virtual_time % GROUP_QUERY_INTERVAL == 0) {
- /*
- * Time to query the local group memberships on all subnets
- * for which this router is the elected querier.
- */
- query_groups();
- }
-
- if (virtual_time % NEIGHBOR_PROBE_INTERVAL == 0) {
- /*
- * Time to send a probe on all vifs from which no neighbors have
- * been heard. Also, check if any inoperative interfaces have now
- * come up. (If they have, they will also be probed as part of
- * their initialization.)
- */
- probe_for_neighbors();
-
- if (vifs_down)
- check_vif_state();
- }
-
- delay_change_reports = FALSE;
- if (routes_changed) {
- /*
- * Some routes have changed since the last timer interrupt, but
- * have not been reported yet. Report the changed routes to all
- * neighbors.
- */
- report_to_all_neighbors(CHANGED_ROUTES);
- }
-
-#ifdef SNMP
- sync_timer();
-#endif
-
- /*
- * Advance virtual time
- */
- virtual_time += TIMER_INTERVAL;
-}
-
-
-/*
- * On termination, let everyone know we're going away.
- */
-static void
-done(i)
- int i;
-{
- log(LOG_NOTICE, 0, "%s exiting", versionstring);
- cleanup();
- _exit(1);
-}
-
-static void
-cleanup()
-{
- static in_cleanup = 0;
-
- if (!in_cleanup) {
- in_cleanup++;
-#ifdef RSRR
- rsrr_clean();
-#endif /* RSRR */
- expire_all_routes();
- report_to_all_neighbors(ALL_ROUTES);
- k_stop_dvmrp();
- }
-}
-
-
-/*
- * Dump internal data structures to stderr.
- */
-static void
-dump(i)
- int i;
-{
- dump_vifs(stderr);
- dump_routes(stderr);
-}
-
-
-/*
- * Dump internal data structures to a file.
- */
-static void
-fdump(i)
- int i;
-{
- FILE *fp;
-
- fp = fopen(dumpfilename, "w");
- if (fp != NULL) {
- dump_vifs(fp);
- dump_routes(fp);
- (void) fclose(fp);
- }
-}
-
-
-/*
- * Dump local cache contents to a file.
- */
-static void
-cdump(i)
- int i;
-{
- FILE *fp;
-
- fp = fopen(cachefilename, "w");
- if (fp != NULL) {
- dump_cache(fp);
- (void) fclose(fp);
- }
-}
-
-
-/*
- * Restart mrouted
- */
-static void
-restart(i)
- int i;
-{
- register int omask;
-#ifdef SYSV
- sigset_t block, oblock;
-#endif
-
- log(LOG_NOTICE, 0, "%s restart", versionstring);
-
- /*
- * reset all the entries
- */
-#ifdef SYSV
- (void)sigemptyset(&block);
- (void)sigaddset(&block, SIGALRM);
- if (sigprocmask(SIG_BLOCK, &block, &oblock) < 0)
- log(LOG_ERR, errno, "sigprocmask");
-#else
- omask = sigblock(sigmask(SIGALRM));
-#endif
- free_all_prunes();
- free_all_routes();
- stop_all_vifs();
- k_stop_dvmrp();
- close(igmp_socket);
- close(udp_socket);
-
- /*
- * start processing again
- */
- dvmrp_genid++;
- pruning = 1;
-
- init_igmp();
- init_routes();
- init_ktable();
- init_vifs();
- k_init_dvmrp(); /* enable DVMRP routing in kernel */
- init_installvifs();
-
-#ifdef SYSV
- (void)sigprocmask(SIG_SETMASK, &oblock, (sigset_t *)NULL);
-#else
- (void)sigsetmask(omask);
-#endif
-}
-
-#define LOG_MAX_MSGS 20 /* if > 20/minute then shut up for a while */
-#define LOG_SHUT_UP 600 /* shut up for 10 minutes */
-static int log_nmsgs = 0;
-
-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);
-}
-
-/*
- * 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;
- char tbuf[20];
- 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[211] = "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];
-
- switch (debug) {
- case 0: break;
- case 1: if (severity > LOG_NOTICE) break;
- case 2: if (severity > LOG_INFO ) break;
- default:
- gettimeofday(&now,NULL);
- thyme = localtime(&now.tv_sec);
- strftime(tbuf, sizeof(tbuf), "%X.%%03d ", thyme);
- fprintf(stderr, tbuf, now.tv_usec / 1000);
- fprintf(stderr, "%s", 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);
- }
-
- if (severity <= LOG_NOTICE) {
- if (log_nmsgs++ < LOG_MAX_MSGS) {
- if (syserr != 0) {
- errno = syserr;
- syslog(severity, "%s: %m", msg);
- } else
- syslog(severity, "%s", msg);
- }
-
- if (severity <= LOG_ERR) exit(-1);
- }
-}
-
-#ifdef DEBUG_MFC
-void
-md_log(what, origin, mcastgrp)
- int what;
- u_int32 origin, mcastgrp;
-{
- static FILE *f = NULL;
- struct timeval tv;
- u_int32 buf[4];
-
- if (!f) {
- if ((f = fopen("/tmp/mrouted.clog", "w")) == NULL) {
- log(LOG_ERR, errno, "open /tmp/mrouted.clog");
- }
- }
-
- gettimeofday(&tv, NULL);
- buf[0] = tv.tv_sec;
- buf[1] = what;
- buf[2] = origin;
- buf[3] = mcastgrp;
-
- fwrite(buf, sizeof(u_int32), 4, f);
-}
-#endif
diff --git a/usr.sbin/mrouted/map-mbone.8 b/usr.sbin/mrouted/map-mbone.8
deleted file mode 100644
index ba850d234395..000000000000
--- a/usr.sbin/mrouted/map-mbone.8
+++ /dev/null
@@ -1,89 +0,0 @@
-.TH MAP-MBONE 8
-.UC 5
-.SH NAME
-map-mbone \- Multicast connection mapper
-.SH SYNOPSIS
-.B /usr/sbin/map-mbone
-[
-.B \-d
-.I debug_level
-] [
-.B \-f
-] [
-.B \-g
-] [
-.B \-n
-] [
-.B \-r
-.I retry_count
-] [
-.B \-t
-.I timeout_count
-] [
-.B starting_router
-]
-.SH DESCRIPTION
-.I map-mbone
-attempts to display all multicast routers that are reachable from the multicast
-.I starting_router.
-If not specified on the command line, the default multicast
-.I starting_router
-is the localhost.
-.PP
-.I map-mbone
-traverses neighboring multicast routers by sending the ASK_NEIGHBORS IGMP
-message to the multicast starting_router. If this multicast router responds,
-the version number and a list of their neighboring multicast router addresses is
-part of that response. If the responding router has recent multicast version
-number, then
-.I map-mbone
-requests additional information such as metrics, thresholds, and flags from the
-multicast router. For each new occurrence of neighboring multicast router in
-the reply and provided the flooding option has been selected, then
-.I map-mbone
-asks each of this multicast router for a list of neighbors. This search
-for unique routers will continue until no new neighboring multicast routers
-are reported.
-.br
-.ne 5
-.SH INVOCATION
-.PP
-"\-d" option sets the debug level. When the debug level is greater than the
-default value of 0, addition debugging messages are printed. Regardless of
-the debug level, an error condition, will always write an error message and will
-cause
-.I map-mbone
-to terminate.
-Non-zero debug levels have the following effects:
-.IP "level 1"
-packet warnings are printed to stderr.
-.IP "level 2"
-all level 1 messages plus notifications down networks are printed to stderr.
-.IP "level 3"
-all level 2 messages plus notifications of all packet
-timeouts are printed to stderr.
-.PP
-"\-f" option sets flooding option. Flooding allows the recursive search
-of neighboring multicast routers and is enable by default when starting_router
-is not used.
-.PP
-"\-g" option sets graphing in GraphEd format.
-.PP
-"\-n" option disables the DNS lookup for the multicast routers names.
-.PP
-"\-r retry_count" sets the neighbor query retry limit. Default is 1 retry.
-.PP
-"\-t timeout_count" sets the number of seconds to wait for a neighbor query
-reply before retrying. Default timeout is 2 seconds.
-.PP
-.SH IMPORTANT NOTE
-.I map-mbone
-must be run as root.
-.PP
-.SH SEE ALSO
-.BR mrouted (8) ,
-.BR mrinfo (8) ,
-.BR mtrace (8)
-.PP
-.SH AUTHOR
-Pavel Curtis
diff --git a/usr.sbin/mrouted/mapper.c b/usr.sbin/mrouted/mapper.c
deleted file mode 100644
index 1eacd04bb61d..000000000000
--- a/usr.sbin/mrouted/mapper.c
+++ /dev/null
@@ -1,1034 +0,0 @@
-/* Mapper for connections between MRouteD multicast routers.
- * Written by Pavel Curtis <Pavel@PARC.Xerox.Com>
- *
- * $Id: mapper.c,v 3.8 1995/11/29 22:36:57 fenner Rel $
- */
-
-/*
- * Copyright (c) Xerox Corporation 1992. All rights reserved.
- *
- * License is granted to copy, to use, and to make and to use derivative
- * works for research and evaluation purposes, provided that Xerox is
- * acknowledged in all documentation pertaining to any such copy or derivative
- * work. Xerox grants no other licenses expressed or implied. The Xerox trade
- * name should not be used in any advertising without its written permission.
- *
- * XEROX CORPORATION MAKES NO REPRESENTATIONS CONCERNING EITHER THE
- * MERCHANTABILITY OF THIS SOFTWARE OR THE SUITABILITY OF THIS SOFTWARE
- * FOR ANY PARTICULAR PURPOSE. The software is provided "as is" without
- * express or implied warranty of any kind.
- *
- * These notices must be retained in any copies of any part of this software.
- */
-
-#include <string.h>
-#include <netdb.h>
-#include <sys/time.h>
-#include "defs.h"
-#include <arpa/inet.h>
-#ifdef __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-
-#define DEFAULT_TIMEOUT 2 /* How long to wait before retrying requests */
-#define DEFAULT_RETRIES 1 /* How many times to ask each router */
-
-
-/* All IP addresses are stored in the data structure in NET order. */
-
-typedef struct neighbor {
- struct neighbor *next;
- u_int32 addr; /* IP address in NET order */
- u_char metric; /* TTL cost of forwarding */
- u_char threshold; /* TTL threshold to forward */
- u_short flags; /* flags on connection */
-#define NF_PRESENT 0x8000 /* True if flags are meaningful */
-} Neighbor;
-
-typedef struct interface {
- struct interface *next;
- u_int32 addr; /* IP address of the interface in NET order */
- Neighbor *neighbors; /* List of neighbors' IP addresses */
-} Interface;
-
-typedef struct node {
- u_int32 addr; /* IP address of this entry in NET order */
- u_int32 version; /* which mrouted version is running */
- int tries; /* How many requests sent? -1 for aliases */
- union {
- struct node *alias; /* If alias, to what? */
- struct interface *interfaces; /* Else, neighbor data */
- } u;
- struct node *left, *right;
-} Node;
-
-
-Node *routers = 0;
-u_int32 our_addr, target_addr = 0; /* in NET order */
-int debug = 0;
-int retries = DEFAULT_RETRIES;
-int timeout = DEFAULT_TIMEOUT;
-int show_names = TRUE;
-vifi_t numvifs; /* to keep loader happy */
- /* (see COPY_TABLES macro called in kern.c) */
-
-Node * find_node __P((u_int32 addr, Node **ptr));
-Interface * find_interface __P((u_int32 addr, Node *node));
-Neighbor * find_neighbor __P((u_int32 addr, Node *node));
-int main __P((int argc, char *argv[]));
-void ask __P((u_int32 dst));
-void ask2 __P((u_int32 dst));
-int retry_requests __P((Node *node));
-char * inet_name __P((u_int32 addr));
-void print_map __P((Node *node));
-char * graph_name __P((u_int32 addr, char *buf));
-void graph_edges __P((Node *node));
-void elide_aliases __P((Node *node));
-void graph_map __P((void));
-int get_number __P((int *var, int deflt, char ***pargv,
- int *pargc));
-u_int32 host_addr __P((char *name));
-
-
-Node *find_node(addr, ptr)
- u_int32 addr;
- Node **ptr;
-{
- Node *n = *ptr;
-
- if (!n) {
- *ptr = n = (Node *) malloc(sizeof(Node));
- n->addr = addr;
- n->version = 0;
- n->tries = 0;
- n->u.interfaces = 0;
- n->left = n->right = 0;
- return n;
- } else if (addr == n->addr)
- return n;
- else if (addr < n->addr)
- return find_node(addr, &(n->left));
- else
- return find_node(addr, &(n->right));
-}
-
-
-Interface *find_interface(addr, node)
- u_int32 addr;
- Node *node;
-{
- Interface *ifc;
-
- for (ifc = node->u.interfaces; ifc; ifc = ifc->next)
- if (ifc->addr == addr)
- return ifc;
-
- ifc = (Interface *) malloc(sizeof(Interface));
- ifc->addr = addr;
- ifc->next = node->u.interfaces;
- node->u.interfaces = ifc;
- ifc->neighbors = 0;
-
- return ifc;
-}
-
-
-Neighbor *find_neighbor(addr, node)
- u_int32 addr;
- Node *node;
-{
- Interface *ifc;
-
- for (ifc = node->u.interfaces; ifc; ifc = ifc->next) {
- Neighbor *nb;
-
- for (nb = ifc->neighbors; nb; nb = nb->next)
- if (nb->addr == addr)
- return nb;
- }
-
- return 0;
-}
-
-
-/*
- * Log errors and other messages 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;
- char fmt[100];
-
- va_start(ap, format);
-#else
-/*VARARGS3*/
-void
-log(severity, syserr, format, va_alist)
- int severity, syserr;
- char *format;
- va_dcl
-{
- va_list ap;
- char fmt[100];
-
- va_start(ap);
-#endif
-
- switch (debug) {
- case 0: if (severity > LOG_WARNING) return;
- case 1: if (severity > LOG_NOTICE ) return;
- case 2: if (severity > LOG_INFO ) return;
- default:
- fmt[0] = '\0';
- if (severity == LOG_WARNING)
- strcat(fmt, "warning - ");
- strncat(fmt, format, 80);
- vfprintf(stderr, fmt, ap);
- 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);
- }
-
- if (severity <= LOG_ERR)
- exit(-1);
-}
-
-
-/*
- * Send a neighbors-list request.
- */
-void ask(dst)
- u_int32 dst;
-{
- send_igmp(our_addr, dst, IGMP_DVMRP, DVMRP_ASK_NEIGHBORS,
- htonl(MROUTED_LEVEL), 0);
-}
-
-void ask2(dst)
- u_int32 dst;
-{
- send_igmp(our_addr, dst, IGMP_DVMRP, DVMRP_ASK_NEIGHBORS2,
- htonl(MROUTED_LEVEL), 0);
-}
-
-
-/*
- * Process an incoming group membership report.
- */
-void accept_group_report(src, dst, group, r_type)
- u_int32 src, dst, group;
- int r_type;
-{
- log(LOG_INFO, 0, "ignoring IGMP group membership report from %s to %s",
- inet_fmt(src, s1), inet_fmt(dst, s2));
-}
-
-
-/*
- * Process an incoming neighbor probe message.
- */
-void accept_probe(src, dst, p, datalen, level)
- u_int32 src, dst, level;
- char *p;
- int datalen;
-{
- log(LOG_INFO, 0, "ignoring DVMRP probe from %s to %s",
- inet_fmt(src, s1), inet_fmt(dst, s2));
-}
-
-
-/*
- * Process an incoming route report message.
- */
-void accept_report(src, dst, p, datalen, level)
- u_int32 src, dst, level;
- char *p;
- int datalen;
-{
- log(LOG_INFO, 0, "ignoring DVMRP routing report from %s to %s",
- inet_fmt(src, s1), inet_fmt(dst, s2));
-}
-
-
-/*
- * Process an incoming neighbor-list request message.
- */
-void accept_neighbor_request(src, dst)
- u_int32 src, dst;
-{
- if (src != our_addr)
- log(LOG_INFO, 0,
- "ignoring spurious DVMRP neighbor request from %s to %s",
- inet_fmt(src, s1), inet_fmt(dst, s2));
-}
-
-void accept_neighbor_request2(src, dst)
- u_int32 src, dst;
-{
- if (src != our_addr)
- log(LOG_INFO, 0,
- "ignoring spurious DVMRP neighbor request2 from %s to %s",
- inet_fmt(src, s1), inet_fmt(dst, s2));
-}
-
-
-/*
- * Process an incoming neighbor-list message.
- */
-void accept_neighbors(src, dst, p, datalen, level)
- u_int32 src, dst, level;
- u_char *p;
- int datalen;
-{
- Node *node = find_node(src, &routers);
-
- if (node->tries == 0) /* Never heard of 'em; must have hit them at */
- node->tries = 1; /* least once, though...*/
- else if (node->tries == -1) /* follow alias link */
- node = node->u.alias;
-
-#define GET_ADDR(a) (a = ((u_int32)*p++ << 24), a += ((u_int32)*p++ << 16),\
- a += ((u_int32)*p++ << 8), a += *p++)
-
- /* if node is running a recent mrouted, ask for additional info */
- if (level != 0) {
- node->version = level;
- node->tries = 1;
- ask2(src);
- return;
- }
-
- if (debug > 3) {
- int i;
-
- fprintf(stderr, " datalen = %d\n", datalen);
- for (i = 0; i < datalen; i++) {
- if ((i & 0xF) == 0)
- fprintf(stderr, " ");
- fprintf(stderr, " %02x", p[i]);
- if ((i & 0xF) == 0xF)
- fprintf(stderr, "\n");
- }
- if ((datalen & 0xF) != 0xF)
- fprintf(stderr, "\n");
- }
-
- while (datalen > 0) { /* loop through interfaces */
- u_int32 ifc_addr;
- u_char metric, threshold, ncount;
- Node *ifc_node;
- Interface *ifc;
- Neighbor *old_neighbors;
-
- if (datalen < 4 + 3) {
- log(LOG_WARNING, 0, "received truncated interface record from %s",
- inet_fmt(src, s1));
- return;
- }
-
- GET_ADDR(ifc_addr);
- ifc_addr = htonl(ifc_addr);
- metric = *p++;
- threshold = *p++;
- ncount = *p++;
- datalen -= 4 + 3;
-
- /* Fix up any alias information */
- ifc_node = find_node(ifc_addr, &routers);
- if (ifc_node->tries == 0) { /* new node */
- ifc_node->tries = -1;
- ifc_node->u.alias = node;
- } else if (ifc_node != node
- && (ifc_node->tries > 0 || ifc_node->u.alias != node)) {
- /* must merge two hosts' nodes */
- Interface *ifc_i, *next_ifc_i;
-
- if (ifc_node->tries == -1) {
- Node *tmp = ifc_node->u.alias;
-
- ifc_node->u.alias = node;
- ifc_node = tmp;
- }
-
- /* Merge ifc_node (foo_i) into node (foo_n) */
-
- if (ifc_node->tries > node->tries)
- node->tries = ifc_node->tries;
-
- for (ifc_i = ifc_node->u.interfaces; ifc_i; ifc_i = next_ifc_i) {
- Neighbor *nb_i, *next_nb_i, *nb_n;
- Interface *ifc_n = find_interface(ifc_i->addr, node);
-
- old_neighbors = ifc_n->neighbors;
- for (nb_i = ifc_i->neighbors; nb_i; nb_i = next_nb_i) {
- next_nb_i = nb_i->next;
- for (nb_n = old_neighbors; nb_n; nb_n = nb_n->next)
- if (nb_i->addr == nb_n->addr) {
- if (nb_i->metric != nb_n->metric
- || nb_i->threshold != nb_n->threshold)
- log(LOG_WARNING, 0,
- "inconsistent %s for neighbor %s of %s",
- "metric/threshold",
- inet_fmt(nb_i->addr, s1),
- inet_fmt(node->addr, s2));
- free(nb_i);
- break;
- }
- if (!nb_n) { /* no match for this neighbor yet */
- nb_i->next = ifc_n->neighbors;
- ifc_n->neighbors = nb_i;
- }
- }
-
- next_ifc_i = ifc_i->next;
- free(ifc_i);
- }
-
- ifc_node->tries = -1;
- ifc_node->u.alias = node;
- }
-
- ifc = find_interface(ifc_addr, node);
- old_neighbors = ifc->neighbors;
-
- /* Add the neighbors for this interface */
- while (ncount--) {
- u_int32 neighbor;
- Neighbor *nb;
- Node *n_node;
-
- if (datalen < 4) {
- log(LOG_WARNING, 0, "received truncated neighbor list from %s",
- inet_fmt(src, s1));
- return;
- }
-
- GET_ADDR(neighbor);
- neighbor = htonl(neighbor);
- datalen -= 4;
-
- for (nb = old_neighbors; nb; nb = nb->next)
- if (nb->addr == neighbor) {
- if (metric != nb->metric || threshold != nb->threshold)
- log(LOG_WARNING, 0,
- "inconsistent %s for neighbor %s of %s",
- "metric/threshold",
- inet_fmt(nb->addr, s1), inet_fmt(node->addr, s2));
- goto next_neighbor;
- }
-
- nb = (Neighbor *) malloc(sizeof(Neighbor));
- nb->next = ifc->neighbors;
- ifc->neighbors = nb;
- nb->addr = neighbor;
- nb->metric = metric;
- nb->threshold = threshold;
- nb->flags = 0;
-
- n_node = find_node(neighbor, &routers);
- if (n_node->tries == 0 && !target_addr) { /* it's a new router */
- ask(neighbor);
- n_node->tries = 1;
- }
-
- next_neighbor: ;
- }
- }
-}
-
-void accept_neighbors2(src, dst, p, datalen, level)
- u_int32 src, dst, level;
- u_char *p;
- int datalen;
-{
- Node *node = find_node(src, &routers);
- u_int broken_cisco = ((level & 0xffff) == 0x020a); /* 10.2 */
- /* well, only possibly_broken_cisco, but that's too long to type. */
-
- if (node->tries == 0) /* Never heard of 'em; must have hit them at */
- node->tries = 1; /* least once, though...*/
- else if (node->tries == -1) /* follow alias link */
- node = node->u.alias;
-
- while (datalen > 0) { /* loop through interfaces */
- u_int32 ifc_addr;
- u_char metric, threshold, ncount, flags;
- Node *ifc_node;
- Interface *ifc;
- Neighbor *old_neighbors;
-
- if (datalen < 4 + 4) {
- log(LOG_WARNING, 0, "received truncated interface record from %s",
- inet_fmt(src, s1));
- return;
- }
-
- ifc_addr = *(u_int32*)p;
- p += 4;
- metric = *p++;
- threshold = *p++;
- flags = *p++;
- ncount = *p++;
- datalen -= 4 + 4;
-
- if (broken_cisco && ncount == 0) /* dumb Ciscos */
- ncount = 1;
- if (broken_cisco && ncount > 15) /* dumb Ciscos */
- ncount = ncount & 0xf;
-
- /* Fix up any alias information */
- ifc_node = find_node(ifc_addr, &routers);
- if (ifc_node->tries == 0) { /* new node */
- ifc_node->tries = -1;
- ifc_node->u.alias = node;
- } else if (ifc_node != node
- && (ifc_node->tries > 0 || ifc_node->u.alias != node)) {
- /* must merge two hosts' nodes */
- Interface *ifc_i, *next_ifc_i;
-
- if (ifc_node->tries == -1) {
- Node *tmp = ifc_node->u.alias;
-
- ifc_node->u.alias = node;
- ifc_node = tmp;
- }
-
- /* Merge ifc_node (foo_i) into node (foo_n) */
-
- if (ifc_node->tries > node->tries)
- node->tries = ifc_node->tries;
-
- for (ifc_i = ifc_node->u.interfaces; ifc_i; ifc_i = next_ifc_i) {
- Neighbor *nb_i, *next_nb_i, *nb_n;
- Interface *ifc_n = find_interface(ifc_i->addr, node);
-
- old_neighbors = ifc_n->neighbors;
- for (nb_i = ifc_i->neighbors; nb_i; nb_i = next_nb_i) {
- next_nb_i = nb_i->next;
- for (nb_n = old_neighbors; nb_n; nb_n = nb_n->next)
- if (nb_i->addr == nb_n->addr) {
- if (nb_i->metric != nb_n->metric
- || nb_i->threshold != nb_i->threshold)
- log(LOG_WARNING, 0,
- "inconsistent %s for neighbor %s of %s",
- "metric/threshold",
- inet_fmt(nb_i->addr, s1),
- inet_fmt(node->addr, s2));
- free(nb_i);
- break;
- }
- if (!nb_n) { /* no match for this neighbor yet */
- nb_i->next = ifc_n->neighbors;
- ifc_n->neighbors = nb_i;
- }
- }
-
- next_ifc_i = ifc_i->next;
- free(ifc_i);
- }
-
- ifc_node->tries = -1;
- ifc_node->u.alias = node;
- }
-
- ifc = find_interface(ifc_addr, node);
- old_neighbors = ifc->neighbors;
-
- /* Add the neighbors for this interface */
- while (ncount-- && datalen > 0) {
- u_int32 neighbor;
- Neighbor *nb;
- Node *n_node;
-
- if (datalen < 4) {
- log(LOG_WARNING, 0, "received truncated neighbor list from %s",
- inet_fmt(src, s1));
- return;
- }
-
- neighbor = *(u_int32*)p;
- p += 4;
- datalen -= 4;
- if (neighbor == 0)
- /* make leaf nets point to themselves */
- neighbor = ifc_addr;
-
- for (nb = old_neighbors; nb; nb = nb->next)
- if (nb->addr == neighbor) {
- if (metric != nb->metric || threshold != nb->threshold)
- log(LOG_WARNING, 0,
- "inconsistent %s for neighbor %s of %s",
- "metric/threshold",
- inet_fmt(nb->addr, s1), inet_fmt(node->addr, s2));
- goto next_neighbor;
- }
-
- nb = (Neighbor *) malloc(sizeof(Neighbor));
- nb->next = ifc->neighbors;
- ifc->neighbors = nb;
- nb->addr = neighbor;
- nb->metric = metric;
- nb->threshold = threshold;
- nb->flags = flags | NF_PRESENT;
-
- n_node = find_node(neighbor, &routers);
- if (n_node->tries == 0 && !target_addr) { /* it's a new router */
- ask(neighbor);
- n_node->tries = 1;
- }
-
- next_neighbor: ;
- }
- }
-}
-
-
-void check_vif_state()
-{
- log(LOG_NOTICE, 0, "network marked down...");
-}
-
-
-int retry_requests(node)
- Node *node;
-{
- int result;
-
- if (node) {
- result = retry_requests(node->left);
- if (node->tries > 0 && node->tries < retries) {
- if (node->version)
- ask2(node->addr);
- else
- ask(node->addr);
- node->tries++;
- result = 1;
- }
- return retry_requests(node->right) || result;
- } else
- return 0;
-}
-
-
-char *inet_name(addr)
- u_int32 addr;
-{
- struct hostent *e;
-
- e = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET);
-
- return e ? e->h_name : 0;
-}
-
-
-void print_map(node)
- Node *node;
-{
- if (node) {
- char *name, *addr;
-
- print_map(node->left);
-
- addr = inet_fmt(node->addr, s1);
- if (!target_addr
- || (node->tries >= 0 && node->u.interfaces)
- || (node->tries == -1
- && node->u.alias->tries >= 0
- && node->u.alias->u.interfaces)) {
- if (show_names && (name = inet_name(node->addr)))
- printf("%s (%s):", addr, name);
- else
- printf("%s:", addr);
- if (node->tries < 0)
- printf(" alias for %s\n\n", inet_fmt(node->u.alias->addr, s1));
- else if (!node->u.interfaces)
- printf(" no response to query\n\n");
- else {
- Interface *ifc;
-
- if (node->version)
- printf(" <v%d.%d>", node->version & 0xff,
- (node->version >> 8) & 0xff);
- printf("\n");
- for (ifc = node->u.interfaces; ifc; ifc = ifc->next) {
- Neighbor *nb;
- char *ifc_name = inet_fmt(ifc->addr, s1);
- int ifc_len = strlen(ifc_name);
- int count = 0;
-
- printf(" %s:", ifc_name);
- for (nb = ifc->neighbors; nb; nb = nb->next) {
- if (count > 0)
- printf("%*s", ifc_len + 5, "");
- printf(" %s", inet_fmt(nb->addr, s1));
- if (show_names && (name = inet_name(nb->addr)))
- printf(" (%s)", name);
- printf(" [%d/%d", nb->metric, nb->threshold);
- if (nb->flags) {
- u_short flags = nb->flags;
- if (flags & DVMRP_NF_TUNNEL)
- printf("/tunnel");
- if (flags & DVMRP_NF_SRCRT)
- printf("/srcrt");
- if (flags & DVMRP_NF_QUERIER)
- printf("/querier");
- if (flags & DVMRP_NF_DISABLED)
- printf("/disabled");
- if (flags & DVMRP_NF_DOWN)
- printf("/down");
- }
- printf("]\n");
- count++;
- }
- }
- printf("\n");
- }
- }
- print_map(node->right);
- }
-}
-
-
-char *graph_name(addr, buf)
- u_int32 addr;
- char *buf;
-{
- char *name;
-
- if (show_names && (name = inet_name(addr)))
- strcpy(buf, name);
- else
- inet_fmt(addr, buf);
-
- return buf;
-}
-
-
-void graph_edges(node)
- Node *node;
-{
- Interface *ifc;
- Neighbor *nb;
- char name[100];
-
- if (node) {
- graph_edges(node->left);
- if (node->tries >= 0) {
- printf(" %d {$ NP %d0 %d0 $} \"%s%s\" \n",
- (int) node->addr,
- node->addr & 0xFF, (node->addr >> 8) & 0xFF,
- graph_name(node->addr, name),
- node->u.interfaces ? "" : "*");
- for (ifc = node->u.interfaces; ifc; ifc = ifc->next)
- for (nb = ifc->neighbors; nb; nb = nb->next) {
- Node *nb_node = find_node(nb->addr, &routers);
- Neighbor *nb2;
-
- if (nb_node->tries < 0)
- nb_node = nb_node->u.alias;
-
- if (node != nb_node &&
- (!(nb2 = find_neighbor(node->addr, nb_node))
- || node->addr < nb_node->addr)) {
- printf(" %d \"%d/%d",
- nb_node->addr, nb->metric, nb->threshold);
- if (nb2 && (nb2->metric != nb->metric
- || nb2->threshold != nb->threshold))
- printf(",%d/%d", nb2->metric, nb2->threshold);
- if (nb->flags & NF_PRESENT)
- printf("%s%s",
- nb->flags & DVMRP_NF_SRCRT ? "" :
- nb->flags & DVMRP_NF_TUNNEL ? "E" : "P",
- nb->flags & DVMRP_NF_DOWN ? "D" : "");
- printf("\"\n");
- }
- }
- printf(" ;\n");
- }
- graph_edges(node->right);
- }
-}
-
-void elide_aliases(node)
- Node *node;
-{
- if (node) {
- elide_aliases(node->left);
- if (node->tries >= 0) {
- Interface *ifc;
-
- for (ifc = node->u.interfaces; ifc; ifc = ifc->next) {
- Neighbor *nb;
-
- for (nb = ifc->neighbors; nb; nb = nb->next) {
- Node *nb_node = find_node(nb->addr, &routers);
-
- if (nb_node->tries < 0)
- nb->addr = nb_node->u.alias->addr;
- }
- }
- }
- elide_aliases(node->right);
- }
-}
-
-void graph_map()
-{
- time_t now = time(0);
- char *nowstr = ctime(&now);
-
- nowstr[24] = '\0'; /* Kill the newline at the end */
- elide_aliases(routers);
- printf("GRAPH \"Multicast Router Connectivity: %s\" = UNDIRECTED\n",
- nowstr);
- graph_edges(routers);
- printf("END\n");
-}
-
-
-int get_number(var, deflt, pargv, pargc)
- int *var, *pargc, deflt;
- char ***pargv;
-{
- if ((*pargv)[0][2] == '\0') { /* Get the value from the next argument */
- if (*pargc > 1 && isdigit((*pargv)[1][0])) {
- (*pargv)++, (*pargc)--;
- *var = atoi((*pargv)[0]);
- return 1;
- } else if (deflt >= 0) {
- *var = deflt;
- return 1;
- } else
- return 0;
- } else { /* Get value from the rest of this argument */
- if (isdigit((*pargv)[0][2])) {
- *var = atoi((*pargv)[0] + 2);
- return 1;
- } else {
- return 0;
- }
- }
-}
-
-
-u_int32 host_addr(name)
- char *name;
-{
- struct hostent *e = gethostbyname(name);
- int addr;
-
- if (e)
- memcpy(&addr, e->h_addr_list[0], e->h_length);
- else {
- addr = inet_addr(name);
- if (addr == -1)
- addr = 0;
- }
-
- return addr;
-}
-
-
-int main(argc, argv)
- int argc;
- char *argv[];
-{
- int flood = FALSE, graph = FALSE;
-
- setlinebuf(stderr);
-
- if (geteuid() != 0) {
- fprintf(stderr, "must be root\n");
- exit(1);
- }
-
- argv++, argc--;
- while (argc > 0 && argv[0][0] == '-') {
- switch (argv[0][1]) {
- case 'd':
- if (!get_number(&debug, DEFAULT_DEBUG, &argv, &argc))
- goto usage;
- break;
- case 'f':
- flood = TRUE;
- break;
- case 'g':
- graph = TRUE;
- break;
- case 'n':
- show_names = FALSE;
- break;
- case 'r':
- if (!get_number(&retries, -1, &argv, &argc))
- goto usage;
- break;
- case 't':
- if (!get_number(&timeout, -1, &argv, &argc))
- goto usage;
- break;
- default:
- goto usage;
- }
- argv++, argc--;
- }
-
- if (argc > 1) {
- usage:
- fprintf(stderr,
- "Usage: map-mbone [-f] [-g] [-n] [-t timeout] %s\n\n",
- "[-r retries] [-d [debug-level]] [router]");
- fprintf(stderr, "\t-f Flood the routing graph with queries\n");
- fprintf(stderr, "\t (True by default unless `router' is given)\n");
- fprintf(stderr, "\t-g Generate output in GraphEd format\n");
- fprintf(stderr, "\t-n Don't look up DNS names for routers\n");
- exit(1);
- } else if (argc == 1 && !(target_addr = host_addr(argv[0]))) {
- fprintf(stderr, "Unknown host: %s\n", argv[0]);
- exit(2);
- }
-
- if (debug)
- fprintf(stderr, "Debug level %u\n", debug);
-
- init_igmp();
-
- { /* Find a good local address for us. */
- int udp;
- struct sockaddr_in addr;
- int addrlen = sizeof(addr);
-
- addr.sin_family = AF_INET;
-#if (defined(BSD) && (BSD >= 199103))
- addr.sin_len = sizeof addr;
-#endif
- addr.sin_addr.s_addr = dvmrp_group;
- addr.sin_port = htons(2000); /* any port over 1024 will do... */
- if ((udp = socket(AF_INET, SOCK_DGRAM, 0)) < 0
- || connect(udp, (struct sockaddr *) &addr, sizeof(addr)) < 0
- || getsockname(udp, (struct sockaddr *) &addr, &addrlen) < 0) {
- perror("Determining local address");
- exit(-1);
- }
- close(udp);
- our_addr = addr.sin_addr.s_addr;
- }
-
- /* Send initial seed message to all local routers */
- ask(target_addr ? target_addr : allhosts_group);
-
- if (target_addr) {
- Node *n = find_node(target_addr, &routers);
-
- n->tries = 1;
-
- if (flood)
- target_addr = 0;
- }
-
- /* Main receive loop */
- for(;;) {
- fd_set fds;
- struct timeval tv;
- int count, recvlen, dummy = 0;
-
- FD_ZERO(&fds);
- FD_SET(igmp_socket, &fds);
-
- tv.tv_sec = timeout;
- tv.tv_usec = 0;
-
- count = select(igmp_socket + 1, &fds, 0, 0, &tv);
-
- if (count < 0) {
- if (errno != EINTR)
- perror("select");
- continue;
- } else if (count == 0) {
- log(LOG_DEBUG, 0, "Timed out receiving neighbor lists");
- if (retry_requests(routers))
- continue;
- else
- break;
- }
-
- recvlen = recvfrom(igmp_socket, recv_buf, RECV_BUF_SIZE,
- 0, NULL, &dummy);
- if (recvlen >= 0)
- accept_igmp(recvlen);
- else if (errno != EINTR)
- perror("recvfrom");
- }
-
- printf("\n");
-
- if (graph)
- graph_map();
- else {
- if (!target_addr)
- printf("Multicast Router Connectivity:\n\n");
- print_map(routers);
- }
-
- exit(0);
-}
-
-/* dummies */
-void accept_prune(src, dst, p, datalen)
- u_int32 src, dst;
- char *p;
- int datalen;
-{
-}
-void accept_graft(src, dst, p, datalen)
- u_int32 src, dst;
- char *p;
- int datalen;
-{
-}
-void accept_g_ack(src, dst, p, datalen)
- u_int32 src, dst;
- char *p;
- int datalen;
-{
-}
-void add_table_entry(origin, mcastgrp)
- u_int32 origin, mcastgrp;
-{
-}
-void accept_leave_message(src, dst, group)
- u_int32 src, dst, group;
-{
-}
-void accept_mtrace(src, dst, group, data, no, datalen)
- u_int32 src, dst, group;
- char *data;
- u_int no;
- int datalen;
-{
-}
-void accept_membership_query(src, dst, group, tmo)
- u_int32 src, dst, group;
- int tmo;
-{
-}
-void accept_info_request(src, dst, p, datalen)
- u_int32 src, dst;
- u_char *p;
- int datalen;
-{
-}
-void accept_info_reply(src, dst, p, datalen)
- u_int32 src, dst;
- u_char *p;
- int datalen;
-{
-}
diff --git a/usr.sbin/mrouted/mrinfo.8 b/usr.sbin/mrouted/mrinfo.8
deleted file mode 100644
index 1e7f9a91159a..000000000000
--- a/usr.sbin/mrouted/mrinfo.8
+++ /dev/null
@@ -1,83 +0,0 @@
-.TH MRINFO 8
-.UC 5
-.SH NAME
-mrinfo \- Displays configuration info from a multicast router
-.SH SYNOPSIS
-.B /usr/sbin/mrinfo
-[
-.B \-d
-.I debug_level
-] [
-.B \-r
-.I retry_count
-] [
-.B \-t
-.I timeout_count
-]
-.B multicast_router
-
-.SH DESCRIPTION
-.I mrinfo
-attempts to display the configuration information from the multicast router
-.I multicast_router.
-.PP
-.I mrinfo
-uses the ASK_NEIGHBORS IGMP message to the specified multicast router. If this
-multicast router responds, the version number and a list of their neighboring
-multicast router addresses is part of that response. If the responding router
-has a recent multicast version number, then
-.I mrinfo
-requests additional information such as metrics, thresholds, and flags from the
-multicast router. Once the specified multicast router responds, the
-configuration is displayed to the standard output.
-.br
-.ne 5
-.SH INVOCATION
-.PP
-"\-d" option sets the debug level. When the debug level is greater than the
-default value of 0, addition debugging messages are printed. Regardless of
-the debug level, an error condition, will always write an error message and will
-cause
-.I mrinfo
-to terminate.
-Non-zero debug levels have the following effects:
-.IP "level 1"
-packet warnings are printed to stderr.
-.IP "level 2"
-all level 1 messages plus notifications down networks are printed to stderr.
-.IP "level 3"
-all level 2 messages plus notifications of all packet
-timeouts are printed to stderr.
-.PP
-"\-r retry_count" sets the neighbor query retry limit. Default is 3 retry.
-.PP
-"\-t timeout_count" sets the number of seconds to wait for a neighbor query
-reply. Default timeout is 4 seconds.
-.PP
-.SH SAMPLE OUTPUT
-.nf
-.I mrinfo mbone.phony.dom.net
-127.148.176.10 (mbone.phony.dom.net) [version 3.3]:
- 127.148.176.10 -> 0.0.0.0 (?) [1/1/querier]
- 127.148.176.10 -> 127.0.8.4 (mbone2.phony.dom.net) [1/45/tunnel]
- 127.148.176.10 -> 105.1.41.9 (momoney.com) [1/32/tunnel/down]
- 127.148.176.10 -> 143.192.152.119 (mbone.dipu.edu) [1/32/tunnel]
-.fi
-.PP
-For each neighbor of the queried multicast router, the IP of the queried router
-is displayed, followed by the IP and name of the neighbor. In square brackets
-the metric (cost of connection), the treashold (multicast ttl) is displayed. If
-the queried multicast router has a newer version number, the type (tunnel,
-srcrt) and status (disabled, down) of the connection is displayed.
-.PP
-.SH IMPORTANT NOTE
-.I mrinfo
-must be run as root.
-.PP
-.SH SEE ALSO
-.BR mrouted (8) ,
-.BR map-mbone (8) ,
-.BR mtrace (8)
-.PP
-.SH AUTHOR
-Van Jacobson
diff --git a/usr.sbin/mrouted/mrinfo.c b/usr.sbin/mrouted/mrinfo.c
deleted file mode 100644
index 7335aba95cf9..000000000000
--- a/usr.sbin/mrouted/mrinfo.c
+++ /dev/null
@@ -1,633 +0,0 @@
-/*
- * This tool requests configuration info from a multicast router
- * and prints the reply (if any). Invoke it as:
- *
- * mrinfo router-name-or-address
- *
- * Written Wed Mar 24 1993 by Van Jacobson (adapted from the
- * multicast mapper written by Pavel Curtis).
- *
- * The lawyers insist we include the following UC copyright notice.
- * The mapper from which this is derived contained a Xerox copyright
- * notice which follows the UC one. Try not to get depressed noting
- * that the legal gibberish is larger than the program.
- *
- * Copyright (c) 1993 Regents of the University of California.
- * 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. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the Computer Systems
- * Engineering Group at Lawrence Berkeley Laboratory.
- * 4. Neither the name of the University nor of the Laboratory may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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) Xerox Corporation 1992. All rights reserved.
- *
- * License is granted to copy, to use, and to make and to use derivative works
- * for research and evaluation purposes, provided that Xerox is acknowledged
- * in all documentation pertaining to any such copy or derivative work. Xerox
- * grants no other licenses expressed or implied. The Xerox trade name should
- * not be used in any advertising without its written permission.
- *
- * XEROX CORPORATION MAKES NO REPRESENTATIONS CONCERNING EITHER THE
- * MERCHANTABILITY OF THIS SOFTWARE OR THE SUITABILITY OF THIS SOFTWARE FOR
- * ANY PARTICULAR PURPOSE. The software is provided "as is" without express
- * or implied warranty of any kind.
- *
- * These notices must be retained in any copies of any part of this software.
- */
-
-#ifndef lint
-static char rcsid[] =
- "@(#) $Id: mrinfo.c,v 3.8 1995/11/29 22:36:34 fenner Rel $";
-/* original rcsid:
- "@(#) Header: mrinfo.c,v 1.6 93/04/08 15:14:16 van Exp (LBL)";
-*/
-#endif
-
-#include <netdb.h>
-#include <sys/time.h>
-#include "defs.h"
-#include <arpa/inet.h>
-#ifdef __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-
-#define DEFAULT_TIMEOUT 4 /* How long to wait before retrying requests */
-#define DEFAULT_RETRIES 3 /* How many times to ask each router */
-
-u_int32 our_addr, target_addr = 0; /* in NET order */
-int debug = 0;
-int nflag = 0;
-int retries = DEFAULT_RETRIES;
-int timeout = DEFAULT_TIMEOUT;
-int target_level = 0;
-vifi_t numvifs; /* to keep loader happy */
- /* (see COPY_TABLES macro called in kern.c) */
-
-char * inet_name __P((u_int32 addr));
-void ask __P((u_int32 dst));
-void ask2 __P((u_int32 dst));
-int get_number __P((int *var, int deflt, char ***pargv,
- int *pargc));
-u_int32 host_addr __P((char *name));
-void usage __P((void));
-
-/* to shut up -Wstrict-prototypes */
-int main __P((int argc, char *argv[]));
-
-
-char *
-inet_name(addr)
- u_int32 addr;
-{
- struct hostent *e;
- struct in_addr in;
-
- if (addr == 0)
- return "local";
-
- if (nflag ||
- (e = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET)) == NULL) {
- in.s_addr = addr;
- return (inet_ntoa(in));
- }
- return (e->h_name);
-}
-
-/*
- * Log errors and other messages 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;
- char fmt[100];
-
- va_start(ap, format);
-#else
-void
-log(severity, syserr, format, va_alist)
- int severity, syserr;
- char *format;
- va_dcl
-{
- va_list ap;
- char fmt[100];
-
- va_start(ap);
-#endif
- switch (debug) {
- case 0:
- if (severity > LOG_WARNING)
- return;
- case 1:
- if (severity > LOG_NOTICE)
- return;
- case 2:
- if (severity > LOG_INFO)
- return;
- default:
- fmt[0] = '\0';
- if (severity == LOG_WARNING)
- strcat(fmt, "warning - ");
- strncat(fmt, format, 80);
- vfprintf(stderr, fmt, ap);
- 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);
- }
-
- if (severity <= LOG_ERR)
- exit(-1);
-}
-
-/*
- * Send a neighbors-list request.
- */
-void
-ask(dst)
- u_int32 dst;
-{
- send_igmp(our_addr, dst, IGMP_DVMRP, DVMRP_ASK_NEIGHBORS,
- htonl(MROUTED_LEVEL), 0);
-}
-
-void
-ask2(dst)
- u_int32 dst;
-{
- send_igmp(our_addr, dst, IGMP_DVMRP, DVMRP_ASK_NEIGHBORS2,
- htonl(MROUTED_LEVEL), 0);
-}
-
-/*
- * Process an incoming neighbor-list message.
- */
-void
-accept_neighbors(src, dst, p, datalen, level)
- u_int32 src, dst, level;
- u_char *p;
- int datalen;
-{
- u_char *ep = p + datalen;
-#define GET_ADDR(a) (a = ((u_int32)*p++ << 24), a += ((u_int32)*p++ << 16),\
- a += ((u_int32)*p++ << 8), a += *p++)
-
- printf("%s (%s):\n", inet_fmt(src, s1), inet_name(src));
- while (p < ep) {
- register u_int32 laddr;
- register u_char metric;
- register u_char thresh;
- register int ncount;
-
- GET_ADDR(laddr);
- laddr = htonl(laddr);
- metric = *p++;
- thresh = *p++;
- ncount = *p++;
- while (--ncount >= 0) {
- register u_int32 neighbor;
- GET_ADDR(neighbor);
- neighbor = htonl(neighbor);
- printf(" %s -> ", inet_fmt(laddr, s1));
- printf("%s (%s) [%d/%d]\n", inet_fmt(neighbor, s1),
- inet_name(neighbor), metric, thresh);
- }
- }
-}
-
-void
-accept_neighbors2(src, dst, p, datalen, level)
- u_int32 src, dst, level;
- u_char *p;
- int datalen;
-{
- u_char *ep = p + datalen;
- u_int broken_cisco = ((level & 0xffff) == 0x020a); /* 10.2 */
- /* well, only possibly_broken_cisco, but that's too long to type. */
-
- printf("%s (%s) [version %d.%d", inet_fmt(src, s1), inet_name(src),
- level & 0xff, (level >> 8) & 0xff);
- if ((level >> 16) & NF_LEAF) { printf (",leaf"); }
- if ((level >> 16) & NF_PRUNE) { printf (",prune"); }
- if ((level >> 16) & NF_GENID) { printf (",genid"); }
- if ((level >> 16) & NF_MTRACE) { printf (",mtrace"); }
- printf ("]:\n");
-
- while (p < ep) {
- register u_char metric;
- register u_char thresh;
- register u_char flags;
- register int ncount;
- register u_int32 laddr = *(u_int32*)p;
-
- p += 4;
- metric = *p++;
- thresh = *p++;
- flags = *p++;
- ncount = *p++;
- if (broken_cisco && ncount == 0) /* dumb Ciscos */
- ncount = 1;
- if (broken_cisco && ncount > 15) /* dumb Ciscos */
- ncount = ncount & 0xf;
- while (--ncount >= 0 && p < ep) {
- register u_int32 neighbor = *(u_int32*)p;
- p += 4;
- printf(" %s -> ", inet_fmt(laddr, s1));
- printf("%s (%s) [%d/%d", inet_fmt(neighbor, s1),
- inet_name(neighbor), metric, thresh);
- if (flags & DVMRP_NF_TUNNEL)
- printf("/tunnel");
- if (flags & DVMRP_NF_SRCRT)
- printf("/srcrt");
- if (flags & DVMRP_NF_PIM)
- printf("/pim");
- if (flags & DVMRP_NF_QUERIER)
- printf("/querier");
- if (flags & DVMRP_NF_DISABLED)
- printf("/disabled");
- if (flags & DVMRP_NF_DOWN)
- printf("/down");
- if (flags & DVMRP_NF_LEAF)
- printf("/leaf");
- printf("]\n");
- }
- }
-}
-
-int
-get_number(var, deflt, pargv, pargc)
- int *var, *pargc, deflt;
- char ***pargv;
-{
- if ((*pargv)[0][2] == '\0') { /* Get the value from the next
- * argument */
- if (*pargc > 1 && isdigit((*pargv)[1][0])) {
- (*pargv)++, (*pargc)--;
- *var = atoi((*pargv)[0]);
- return 1;
- } else if (deflt >= 0) {
- *var = deflt;
- return 1;
- } else
- return 0;
- } else { /* Get value from the rest of this argument */
- if (isdigit((*pargv)[0][2])) {
- *var = atoi((*pargv)[0] + 2);
- return 1;
- } else {
- return 0;
- }
- }
-}
-
-void
-usage()
-{
- fprintf(stderr,
- "Usage: mrinfo [-n] [-t timeout] [-r retries] [router]\n");
- exit(1);
-}
-
-int
-main(argc, argv)
- int argc;
- char *argv[];
-{
- int tries;
- int trynew;
- struct timeval et;
- struct hostent *hp;
- struct hostent bogus;
- char *host;
- int curaddr;
-
- setlinebuf(stderr);
-
- if (geteuid() != 0) {
- fprintf(stderr, "mrinfo: must be root\n");
- exit(1);
- }
- argv++, argc--;
- while (argc > 0 && argv[0][0] == '-') {
- switch (argv[0][1]) {
- case 'd':
- if (!get_number(&debug, DEFAULT_DEBUG, &argv, &argc))
- usage();
- break;
- case 'n':
- ++nflag;
- break;
- case 'r':
- if (!get_number(&retries, -1, &argv, &argc))
- usage();
- break;
- case 't':
- if (!get_number(&timeout, -1, &argv, &argc))
- usage();
- break;
- default:
- usage();
- }
- argv++, argc--;
- }
- if (argc > 1)
- usage();
- if (argc == 1)
- host = argv[0];
- else
- host = "127.0.0.1";
-
- if ((target_addr = inet_addr(host)) != -1) {
- hp = &bogus;
- hp->h_length = sizeof(target_addr);
- hp->h_addr_list = (char **)malloc(2 * sizeof(char *));
- hp->h_addr_list[0] = malloc(hp->h_length);
- memcpy(hp->h_addr_list[0], &target_addr, hp->h_length);
- hp->h_addr_list[1] = 0;
- } else
- hp = gethostbyname(host);
-
- if (hp == NULL) {
- fprintf(stderr, "mrinfo: %s: no such host\n", argv[0]);
- exit(1);
- }
- if (debug)
- fprintf(stderr, "Debug level %u\n", debug);
-
- init_igmp();
-
- /* Check all addresses; mrouters often have unreachable interfaces */
- for (curaddr = 0; hp->h_addr_list[curaddr] != NULL; curaddr++) {
- memcpy(&target_addr, hp->h_addr_list[curaddr], hp->h_length);
- { /* Find a good local address for us. */
- int udp;
- struct sockaddr_in addr;
- int addrlen = sizeof(addr);
-
- addr.sin_family = AF_INET;
-#if (defined(BSD) && (BSD >= 199103))
- addr.sin_len = sizeof addr;
-#endif
- addr.sin_addr.s_addr = target_addr;
- addr.sin_port = htons(2000); /* any port over 1024 will
- * do... */
- if ((udp = socket(AF_INET, SOCK_DGRAM, 0)) < 0
- || connect(udp, (struct sockaddr *) & addr, sizeof(addr)) < 0
- || getsockname(udp, (struct sockaddr *) & addr, &addrlen) < 0) {
- perror("Determining local address");
- exit(-1);
- }
- close(udp);
- our_addr = addr.sin_addr.s_addr;
- }
-
- tries = 0;
- trynew = 1;
- /*
- * New strategy: send 'ask2' for two timeouts, then fall back
- * to 'ask', since it's not very likely that we are going to
- * find someone who only responds to 'ask' these days
- */
- ask2(target_addr);
-
- gettimeofday(&et, 0);
- et.tv_sec += timeout;
-
- /* Main receive loop */
- for (;;) {
- fd_set fds;
- struct timeval tv, now;
- int count, recvlen, dummy = 0;
- register u_int32 src, dst, group;
- struct ip *ip;
- struct igmp *igmp;
- int ipdatalen, iphdrlen, igmpdatalen;
-
- FD_ZERO(&fds);
- FD_SET(igmp_socket, &fds);
-
- gettimeofday(&now, 0);
- tv.tv_sec = et.tv_sec - now.tv_sec;
- tv.tv_usec = et.tv_usec - now.tv_usec;
-
- if (tv.tv_usec < 0) {
- tv.tv_usec += 1000000L;
- --tv.tv_sec;
- }
- if (tv.tv_sec < 0)
- tv.tv_sec = tv.tv_usec = 0;
-
- count = select(igmp_socket + 1, &fds, 0, 0, &tv);
-
- if (count < 0) {
- if (errno != EINTR)
- perror("select");
- continue;
- } else if (count == 0) {
- log(LOG_DEBUG, 0, "Timed out receiving neighbor lists");
- if (++tries > retries)
- break;
- /* If we've tried ASK_NEIGHBORS2 twice with
- * no response, fall back to ASK_NEIGHBORS
- */
- if (tries == 2 && target_level == 0)
- trynew = 0;
- if (target_level == 0 && trynew == 0)
- ask(target_addr);
- else
- ask2(target_addr);
- gettimeofday(&et, 0);
- et.tv_sec += timeout;
- continue;
- }
- recvlen = recvfrom(igmp_socket, recv_buf, RECV_BUF_SIZE,
- 0, NULL, &dummy);
- if (recvlen <= 0) {
- if (recvlen && errno != EINTR)
- perror("recvfrom");
- continue;
- }
-
- if (recvlen < sizeof(struct ip)) {
- log(LOG_WARNING, 0,
- "packet too short (%u bytes) for IP header",
- recvlen);
- continue;
- }
- ip = (struct ip *) recv_buf;
- if (ip->ip_p == 0)
- continue; /* Request to install cache entry */
- src = ip->ip_src.s_addr;
- dst = ip->ip_dst.s_addr;
- iphdrlen = ip->ip_hl << 2;
- ipdatalen = ip->ip_len;
- if (iphdrlen + ipdatalen != recvlen) {
- log(LOG_WARNING, 0,
- "packet shorter (%u bytes) than hdr+data length (%u+%u)",
- recvlen, iphdrlen, ipdatalen);
- continue;
- }
- igmp = (struct igmp *) (recv_buf + iphdrlen);
- group = igmp->igmp_group.s_addr;
- igmpdatalen = ipdatalen - IGMP_MINLEN;
- if (igmpdatalen < 0) {
- log(LOG_WARNING, 0,
- "IP data field too short (%u bytes) for IGMP, from %s",
- ipdatalen, inet_fmt(src, s1));
- continue;
- }
- if (igmp->igmp_type != IGMP_DVMRP)
- continue;
-
- switch (igmp->igmp_code) {
- case DVMRP_NEIGHBORS:
- case DVMRP_NEIGHBORS2:
- if (src != target_addr) {
- fprintf(stderr, "mrinfo: got reply from %s",
- inet_fmt(src, s1));
- fprintf(stderr, " instead of %s\n",
- inet_fmt(target_addr, s1));
- /*continue;*/
- }
- break;
- default:
- continue; /* ignore all other DVMRP messages */
- }
-
- switch (igmp->igmp_code) {
-
- case DVMRP_NEIGHBORS:
- if (group) {
- /* knows about DVMRP_NEIGHBORS2 msg */
- if (target_level == 0) {
- target_level = ntohl(group);
- ask2(target_addr);
- }
- } else {
- accept_neighbors(src, dst, (u_char *)(igmp + 1),
- igmpdatalen, ntohl(group));
- exit(0);
- }
- break;
-
- case DVMRP_NEIGHBORS2:
- accept_neighbors2(src, dst, (u_char *)(igmp + 1),
- igmpdatalen, ntohl(group));
- exit(0);
- }
- }
- }
- exit(1);
-}
-
-/* dummies */
-void accept_probe(src, dst, p, datalen, level)
- u_int32 src, dst, level;
- char *p;
- int datalen;
-{
-}
-void accept_group_report(src, dst, group, r_type)
- u_int32 src, dst, group;
- int r_type;
-{
-}
-void accept_neighbor_request2(src, dst)
- u_int32 src, dst;
-{
-}
-void accept_report(src, dst, p, datalen, level)
- u_int32 src, dst, level;
- char *p;
- int datalen;
-{
-}
-void accept_neighbor_request(src, dst)
- u_int32 src, dst;
-{
-}
-void accept_prune(src, dst, p, datalen)
- u_int32 src, dst;
- char *p;
- int datalen;
-{
-}
-void accept_graft(src, dst, p, datalen)
- u_int32 src, dst;
- char *p;
- int datalen;
-{
-}
-void accept_g_ack(src, dst, p, datalen)
- u_int32 src, dst;
- char *p;
- int datalen;
-{
-}
-void add_table_entry(origin, mcastgrp)
- u_int32 origin, mcastgrp;
-{
-}
-void check_vif_state()
-{
-}
-void accept_leave_message(src, dst, group)
- u_int32 src, dst, group;
-{
-}
-void accept_mtrace(src, dst, group, data, no, datalen)
- u_int32 src, dst, group;
- char *data;
- u_int no;
- int datalen;
-{
-}
-void accept_membership_query(src, dst, group, tmo)
- u_int32 src, dst, group;
- int tmo;
-{
-}
-void accept_info_request(src, dst, p, datalen)
- u_int32 src, dst;
- u_char *p;
- int datalen;
-{
-}
-void accept_info_reply(src, dst, p, datalen)
- u_int32 src, dst;
- u_char *p;
- int datalen;
-{
-}
diff --git a/usr.sbin/mrouted/mrouted.8 b/usr.sbin/mrouted/mrouted.8
deleted file mode 100644
index 6c4c7bd98616..000000000000
--- a/usr.sbin/mrouted/mrouted.8
+++ /dev/null
@@ -1,404 +0,0 @@
-'\"COPYRIGHT 1989 by The Board of Trustees of Leland Stanford Junior University.
-'\"$Id: mrouted.8,v 3.8 1995/11/29 22:37:21 fenner Rel $
-.TH MROUTED 8
-.UC 5
-.SH NAME
-mrouted \- IP multicast routing daemon
-.SH SYNOPSIS
-.B /etc/mrouted
-[
-.B \-p
-] [
-.B \-c
-.I config_file
-] [
-.B \-d
-[
-.I debug_level
-]]
-.SH DESCRIPTION
-.I Mrouted
-is an implementation of the Distance-Vector Multicast Routing
-Protocol (DVMRP), an earlier version of which is specified in RFC-1075.
-It maintains topological knowledge via a distance-vector routing protocol
-(like RIP, described in RFC-1058), upon which it implements a multicast
-datagram forwarding algorithm called Reverse Path Multicasting.
-.PP
-.I Mrouted
-forwards a multicast datagram along a shortest (reverse) path tree
-rooted at the subnet on which the datagram originates. The multicast
-delivery tree may be thought of as a broadcast delivery tree that has
-been pruned back so that it does not extend beyond those subnetworks
-that have members of the destination group. Hence, datagrams
-are not forwarded along those branches which have no listeners of the
-multicast group. The IP time-to-live of a multicast datagram can be
-used to limit the range of multicast datagrams.
-.PP
-In order to support multicasting among subnets that are separated by (unicast)
-routers that do not support IP multicasting,
-.I mrouted
-includes support for
-"tunnels", which are virtual point-to-point links between pairs of
-.IR mrouted s
-located anywhere in an internet. IP multicast packets are encapsulated for
-transmission through tunnels, so that they look like normal unicast datagrams
-to intervening routers and subnets. The encapsulation
-is added on entry to a tunnel, and stripped off
-on exit from a tunnel.
-By default, the packets are encapsulated using the IP-in-IP protocol
-(IP protocol number 4).
-Older versions of
-.I mrouted
-tunnel using IP source routing, which puts a heavy load on some
-types of routers.
-This version does not support IP source route tunnelling.
-.PP
-The tunnelling mechanism allows
-.I mrouted
-to establish a virtual internet, for
-the purpose of multicasting only, which is independent of the physical
-internet, and which may span multiple Autonomous Systems. This capability
-is intended for experimental support of internet multicasting only, pending
-widespread support for multicast routing by the regular (unicast) routers.
-.I Mrouted
-suffers from the well-known scaling problems of any distance-vector
-routing protocol, and does not (yet) support hierarchical multicast routing.
-.PP
-.I Mrouted
-handles multicast routing only; there may or may not be unicast routing
-software running on the same machine as
-.IR mrouted .
-With the use of tunnels, it
-is not necessary for
-.I mrouted
-to have access to more than one physical subnet
-in order to perform multicast forwarding.
-.br
-.ne 5
-.SH INVOCATION
-.PP
-If no "\-d" option is given, or if the debug level is specified as 0,
-.I mrouted
-detaches from the invoking terminal. Otherwise, it remains attached to the
-invoking terminal and responsive to signals from that terminal. If "\-d" is
-given with no argument, the debug level defaults to 2. Regardless of the
-debug level,
-.I mrouted
-always writes warning and error messages to the system
-log demon. Non-zero debug levels have the following effects:
-.IP "level 1"
-all syslog'ed messages are also printed to stderr.
-.IP "level 2"
-all level 1 messages plus notifications of "significant"
-events are printed to stderr.
-.IP "level 3"
-all level 2 messages plus notifications of all packet
-arrivals and departures are printed to stderr.
-.PP
-Upon startup, mrouted writes its pid to the file /etc/mrouted.pid .
-.SH CONFIGURATION
-.PP
-.I Mrouted
-automatically configures itself to forward on all multicast-capable
-interfaces, i.e., interfaces that have the IFF_MULTICAST flag set (excluding
-the loopback "interface"), and it finds other
-.IR mrouted s
-directly reachable
-via those interfaces. To override the default configuration, or to add
-tunnel links to other
-.IR mrouted s,
-configuration commands may be placed in
-/etc/mrouted.conf (or an alternative file, specified by the "\-c" option).
-There are four types of configuration commands:
-.nf
-
- phyint <local-addr> [disable] [metric <m>]
- [threshold <t>] [rate_limit <b>]
- [boundary (<boundary-name>|<scoped-addr>/<mask-len>)]
- [altnet <network>/<mask-len>]
-
- tunnel <local-addr> <remote-addr> [metric <m>]
- [threshold <t>] [rate_limit <b>]
- [boundary (<boundary-name>|<scoped-addr>/<mask-len>)]
-
- cache_lifetime <ct>
-
- pruning <off/on>
-
- name <boundary-name> <scoped-addr>/<mask-len>
-
-.fi
-.PP
-The file format is free-form; whitespace (including newlines) is not
-significant.
-The
-.I boundary
-and
-.I altnet
-options may be specified as many times as necessary.
-.PP
-The phyint command can be used to disable multicast routing on the physical
-interface identified by local IP address <local-addr>, or to associate a
-non-default metric or threshold with the specified physical interface.
-The local IP address <local-addr> may be replaced by the
-interface name (e.g le0).
-If a phyint is attached to multiple IP subnets, describe each additional subnet
-with the altnet keyword.
-Phyint commands must precede tunnel commands.
-.PP
-The tunnel command can be used to establish a tunnel link between local
-IP address <local-addr> and remote IP address <remote-addr>, and to associate
-a non-default metric or threshold with that tunnel.
-The local IP address <local-addr> may be replaced by the
-interface name (e.g. le0). The remote IP address <remote-addr> may
-be replaced by a host name, if and only if the host name has a single
-IP address associated with it.
-The tunnel must be set
-up in the mrouted.conf files of both routers before it can be used.
-'\"For backwards compatibility with older
-'\".IR mrouted s,
-'\"the srcrt keyword specifies
-'\"encapsulation using IP source routing.
-.PP
-The cache_lifetime is a value that determines the amount of time that a
-cached multicast route stays in kernel before timing out. The value of this
-entry should lie between 300 (5 min) and 86400 (1 day). It defaults to 300.
-.PP
-The pruning <off/on> option is provided for
-.IR mrouted
-to act as a non-pruning router. It is also possible to start
-.IR mrouted
-in a non-pruning mode using the "-p" option on the command line. It is
-expected that a router would be configured in this manner for test
-purposes only. The default mode is pruning enabled.
-.PP
-You may assign names to boundaries to make configuration easier with
-the name keyword. The boundary option on phyint or tunnel commands
-can accept either a name or a boundary.
-.PP
-The metric is the "cost" associated with sending a datagram on the given
-interface or tunnel; it may be used to influence the choice of routes.
-The metric defaults to 1. Metrics should be kept as small as possible,
-because
-.I mrouted
-cannot route along paths with a sum of metrics greater
-than 31.
-.LP
-The threshold is the minimum IP time-to-live required for a multicast datagram
-to be forwarded to the given interface or tunnel. It is used to control the
-scope of multicast datagrams. (The TTL of forwarded packets is only compared
-to the threshold, it is not decremented by the threshold. Every multicast
-router decrements the TTL by 1.) The default threshold is 1.
-.LP
-In general, all
-.IR mrouted s
-connected to a particular subnet or tunnel should
-use the same metric and threshold for that subnet or tunnel.
-.PP
-The rate_limit option allows the network administrator to specify a
-certain bandwidth in Kbits/second which would be allocated to multicast
-traffic. It defaults to 500Kbps on tunnels, and 0 (unlimited) on physical
-interfaces.
-.PP
-The boundary option allows an interface
-to be configured as an administrative boundary for the specified
-scoped address. Packets belonging to this address will not
-be forwarded on a scoped interface. The boundary option accepts either
-a name or a boundary spec.
-.PP
-.I Mrouted
-will not initiate execution if it has fewer than two enabled vifs,
-where a vif (virtual interface) is either a physical multicast-capable
-interface or a tunnel. It will log a warning if all of its vifs are
-tunnels; such an
-.I mrouted
-configuration would be better replaced by more
-direct tunnels (i.e., eliminate the middle man).
-.SH "EXAMPLE CONFIGURATION"
-.PP
-This is an example configuration for a mythical multicast router at a big
-school.
-.sp
-.nf
-#
-# mrouted.conf example
-#
-# Name our boundaries to make it easier
-name LOCAL 239.255.0.0/16
-name EE 239.254.0.0/16
-#
-# le1 is our gateway to compsci, don't forward our
-# local groups to them
-phyint le1 boundary EE
-#
-# le2 is our interface on the classroom net, it has four
-# different length subnets on it.
-# note that you can use either an ip address or an
-# interface name
-phyint 172.16.12.38 boundary EE altnet 172.16.15.0/26
- altnet 172.16.15.128/26 altnet 172.16.48.0/24
-#
-# atm0 is our ATM interface, which doesn't properly
-# support multicasting.
-phyint atm0 disable
-#
-# This is an internal tunnel to another EE subnet
-# Remove the default tunnel rate limit, since this
-# tunnel is over ethernets
-tunnel 192.168.5.4 192.168.55.101 metric 1 threshold 1
- rate_limit 0
-#
-# This is our tunnel to the outside world.
-# Careful with those boundaries, Eugene.
-tunnel 192.168.5.4 10.11.12.13 metric 1 threshold 32
- boundary LOCAL boundary EE
-.fi
-.SH SIGNALS
-.PP
-.I Mrouted
-responds to the following signals:
-.IP HUP
-restarts
-.I mrouted .
-The configuration file is reread every time this signal is evoked.
-.IP INT
-terminates execution gracefully (i.e., by sending
-good-bye messages to all neighboring routers).
-.IP TERM
-same as INT
-.IP USR1
-dumps the internal routing tables to /usr/tmp/mrouted.dump.
-.IP USR2
-dumps the internal cache tables to /usr/tmp/mrouted.cache.
-.IP QUIT
-dumps the internal routing tables to stderr (only if
-.I mrouted
-was invoked with a non-zero debug level).
-.PP
-For convenience in sending signals,
-.I mrouted
-writes its pid to /etc/mrouted.pid upon startup.
-.bp
-.SH EXAMPLE
-.PP
-The routing tables look like this:
-.nf
-
-Virtual Interface Table
- Vif Local-Address Metric Thresh Flags
- 0 36.2.0.8 subnet: 36.2 1 1 querier
- groups: 224.0.2.1
- 224.0.0.4
- pkts in: 3456
- pkts out: 2322323
-
- 1 36.11.0.1 subnet: 36.11 1 1 querier
- groups: 224.0.2.1
- 224.0.1.0
- 224.0.0.4
- pkts in: 345
- pkts out: 3456
-
- 2 36.2.0.8 tunnel: 36.8.0.77 3 1
- peers: 36.8.0.77 (2.2)
- boundaries: 239.0.1
- : 239.1.2
- pkts in: 34545433
- pkts out: 234342
-
- 3 36.2.0.8 tunnel: 36.6.8.23 3 16
-
-Multicast Routing Table (1136 entries)
- Origin-Subnet From-Gateway Metric Tmr In-Vif Out-Vifs
- 36.2 1 45 0 1* 2 3*
- 36.8 36.8.0.77 4 15 2 0* 1* 3*
- 36.11 1 20 1 0* 2 3*
- .
- .
- .
-
-.fi
-In this example, there are four vifs connecting to two subnets and two
-tunnels. The vif 3 tunnel is not in use (no peer address). The vif 0 and
-vif 1 subnets have some groups present; tunnels never have any groups. This
-instance of
-.I mrouted
-is the one responsible for sending periodic group
-membership queries on the vif 0 and vif 1 subnets, as indicated by the
-"querier" flags. The list of boundaries indicate the scoped addresses on that
-interface. A count of the no. of incoming and outgoing packets is also
-shown at each interface.
-.PP
-Associated with each subnet from which a multicast datagram can originate
-is the address of the previous hop router (unless the subnet is directly-
-connected), the metric of the path back to the origin, the amount of time
-since we last received an update for this subnet, the incoming vif for
-multicasts from that origin, and a list of outgoing vifs. "*" means that
-the outgoing vif is connected to a leaf of the broadcast tree rooted at the
-origin, and a multicast datagram from that origin will be forwarded on that
-outgoing vif only if there are members of the destination group on that leaf.
-.bp
-.PP
-.I Mrouted
-also maintains a copy of the kernel forwarding cache table. Entries
-are created and deleted by
-.I mrouted.
-.PP
-The cache tables look like this:
-.nf
-
-Multicast Routing Cache Table (147 entries)
- Origin Mcast-group CTmr Age Ptmr IVif Forwvifs
- 13.2.116/22 224.2.127.255 3m 2m - 0 1
->13.2.116.19
->13.2.116.196
- 138.96.48/21 224.2.127.255 5m 2m - 0 1
->138.96.48.108
- 128.9.160/20 224.2.127.255 3m 2m - 0 1
->128.9.160.45
- 198.106.194/24 224.2.135.190 9m 28s 9m 0P
->198.106.194.22
-
-.fi
-Each entry is characterized by the origin subnet number and mask and the
-destination multicast group. The 'CTmr' field indicates the lifetime
-of the entry. The entry is deleted from the cache table
-when the timer decrements to zero. The 'Age' field is the time since
-this cache entry was originally created. Since cache entries get refreshed
-if traffic is flowing, routing entries can grow very old.
-The 'Ptmr' field is simply a dash if no prune was sent upstream, or the
-amount of time until the upstream prune will time out.
-The 'Ivif' field indicates the
-incoming vif for multicast packets from that origin. Each router also
-maintains a record of the number of prunes received from neighboring
-routers for a particular source and group. If there are no members of
-a multicast group on any downward link of the multicast tree for a
-subnet, a prune message is sent to the upstream router. They are
-indicated by a "P" after the vif number. The Forwvifs field shows the
-interfaces along which datagrams belonging to the source-group are
-forwarded. A "p" indicates that no datagrams are being forwarded along
-that interface. An unlisted interface is a leaf subnet with are no
-members of the particular group on that subnet. A "b" on an interface
-indicates that it is a boundary interface, i.e. traffic will not be
-forwarded on the scoped address on that interface.
-An additional line with a ">" as the first character is printed for
-each source on the subnet. Note that there can be many sources in
-one subnet.
-.SH FILES
-/etc/mrouted.conf
-.br
-/etc/mrouted.pid
-.br
-/usr/tmp/mrouted.dump
-.br
-/usr/tmp/mrouted.cache
-.SH SEE ALSO
-.BR mrinfo (8) ,
-.BR mtrace (8) ,
-.BR map-mbone (8)
-.sp
-DVMRP is described, along with other multicast routing algorithms, in the
-paper "Multicast Routing in Internetworks and Extended LANs" by S. Deering,
-in the Proceedings of the ACM SIGCOMM '88 Conference.
-.SH AUTHORS
-Steve Deering, Ajit Thyagarajan, Bill Fenner
diff --git a/usr.sbin/mrouted/mrouted.conf b/usr.sbin/mrouted/mrouted.conf
deleted file mode 100644
index eb3bad3f4995..000000000000
--- a/usr.sbin/mrouted/mrouted.conf
+++ /dev/null
@@ -1,43 +0,0 @@
-# $Id: mrouted.conf,v 3.8 1995/11/29 22:40:47 fenner Rel $
-#
-# This is the configuration file for "mrouted", an IP multicast router.
-# mrouted looks for it in "/etc/mrouted.conf".
-#
-# Command formats:
-#
-# name <boundname> <scoped-addr>/<mask-len>
-# cache_lifetime 3600 # seconds
-# pruning on
-#
-# phyint <local-addr> [disable] [metric <m>] [threshold <t>] [rate_limit <b>]
-# [boundary (<boundname>|<scoped-addr>/<mask-len>)]
-# [altnet (<subnet>/<mask-len>|<subnet>)]
-# tunnel <local-addr> <remote-addr> [srcrt] [metric <m>]
-# [threshold <t>] [rate_limit <b>]
-# [boundary (<boundname>|<scoped-addr>/<mask-len>)]
-#
-# NOTE: any phyint commands MUST precede any tunnel commands
-# NOTE: the mask-len is the no. of leading 1's in the mask
-# NOTE: rate_limit is in kilobits, and defaults to 500 for tunnels
-#
-# Example of named bounary:
-#name LOCAL 239.255.0.0/16
-#name EE 239.254.0.0/16 # i.e. the EE dept wants local groups
-#
-# Example of use of named boundary
-#phyint le1 boundary EE # le1 is our interface to comp sci,
-# # keep them away from our local groups
-#
-#
-# Template tunnel for mcast_install
-tunnel 128.4.0.77 128.4.0.8 metric 1 threshold 64 rate_limit 500 # <-- REPLACE
-# boundary LOCAL
-#
-# You might want to specify a boundary on your tunnel to the outside world,
-# as above.
-#
-# NOTE: ONLY uncomment the following if you are running mrouted.snmp!
-#sysName "mymrouter"
-#sysContact "Me <me@me.com> +x.yyy.zzz-zzzz"
-#sysVersion "MyOS 4.1.3 and mrouted"
-#sysLocation "The MBONE"
diff --git a/usr.sbin/mrouted/pathnames.h b/usr.sbin/mrouted/pathnames.h
deleted file mode 100644
index b3e3c88f8988..000000000000
--- a/usr.sbin/mrouted/pathnames.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * The mrouted program is covered by the license in the accompanying file
- * named "LICENSE". 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.
- *
- *
- * $Id: pathnames.h,v 3.8 1995/11/29 22:36:57 fenner Rel $
- */
-
-#define _PATH_MROUTED_CONF "/etc/mrouted.conf"
-
-#if (defined(BSD) && (BSD >= 199103))
-#define _PATH_MROUTED_PID "/var/run/mrouted.pid"
-#define _PATH_MROUTED_GENID "/var/run/mrouted.genid"
-#define _PATH_MROUTED_DUMP "/var/tmp/mrouted.dump"
-#define _PATH_MROUTED_CACHE "/var/tmp/mrouted.cache"
-#else
-#define _PATH_MROUTED_PID "/etc/mrouted.pid"
-#define _PATH_MROUTED_GENID "/etc/mrouted.genid"
-#define _PATH_MROUTED_DUMP "/usr/tmp/mrouted.dump"
-#define _PATH_MROUTED_CACHE "/usr/tmp/mrouted.cache"
-#endif
diff --git a/usr.sbin/mrouted/prune.c b/usr.sbin/mrouted/prune.c
deleted file mode 100644
index fe3cdd5b4e14..000000000000
--- a/usr.sbin/mrouted/prune.c
+++ /dev/null
@@ -1,2303 +0,0 @@
-/*
- * The mrouted program is covered by the license in the accompanying file
- * named "LICENSE". 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.
- *
- *
- * $Id: prune.c,v 3.8 1995/11/29 22:36:34 fenner Rel $
- */
-
-
-#include "defs.h"
-
-extern int cache_lifetime;
-extern int max_prune_lifetime;
-extern struct rtentry *routing_table;
-
-extern int phys_vif;
-
-/*
- * dither cache lifetime to obtain a value between x and 2*x
- */
-#ifdef SYSV
-#define CACHE_LIFETIME(x) ((x) + (lrand48() % (x)))
-#else
-#define CACHE_LIFETIME(x) ((x) + (random() % (x)))
-#endif
-
-#define CHK_GS(x, y) { \
- switch(x) { \
- case 2: \
- case 4: \
- case 8: \
- case 16: \
- case 32: \
- case 64: \
- case 128: \
- case 256: y = 1; \
- break; \
- default: y = 0; \
- } \
- }
-
-struct gtable *kernel_table; /* ptr to list of kernel grp entries*/
-static struct gtable *kernel_no_route; /* list of grp entries w/o routes */
-struct gtable *gtp; /* pointer for kernel rt entries */
-unsigned int kroutes; /* current number of cache entries */
-
-/****************************************************************************
- Functions that are local to prune.c
-****************************************************************************/
-static void prun_add_ttls __P((struct gtable *gt));
-static int pruning_neighbor __P((vifi_t vifi, u_int32 addr));
-static int can_mtrace __P((vifi_t vifi, u_int32 addr));
-static struct ptable * find_prune_entry __P((u_int32 vr, struct ptable *pt));
-static void expire_prune __P((vifi_t vifi, struct gtable *gt));
-static void send_prune __P((struct gtable *gt));
-static void send_graft __P((struct gtable *gt));
-static void send_graft_ack __P((u_int32 src, u_int32 dst,
- u_int32 origin, u_int32 grp));
-static void update_kernel __P((struct gtable *g));
-static char * scaletime __P((u_long t));
-
-/*
- * Updates the ttl values for each vif.
- */
-static void
-prun_add_ttls(gt)
- struct gtable *gt;
-{
- struct uvif *v;
- vifi_t vifi;
-
- for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
- if (VIFM_ISSET(vifi, gt->gt_grpmems))
- gt->gt_ttls[vifi] = v->uv_threshold;
- else
- gt->gt_ttls[vifi] = 0;
- }
-}
-
-/*
- * checks for scoped multicast addresses
- */
-#define GET_SCOPE(gt) { \
- register vifi_t _i; \
- if ((ntohl((gt)->gt_mcastgrp) & 0xff000000) == 0xef000000) \
- for (_i = 0; _i < numvifs; _i++) \
- if (scoped_addr(_i, (gt)->gt_mcastgrp)) \
- VIFM_SET(_i, (gt)->gt_scope); \
- }
-
-int
-scoped_addr(vifi, addr)
- vifi_t vifi;
- u_int32 addr;
-{
- struct vif_acl *acl;
-
- for (acl = uvifs[vifi].uv_acl; acl; acl = acl->acl_next)
- if ((addr & acl->acl_mask) == acl->acl_addr)
- return 1;
-
- return 0;
-}
-
-/*
- * Determine if mcastgrp has a listener on vifi
- */
-int
-grplst_mem(vifi, mcastgrp)
- vifi_t vifi;
- u_int32 mcastgrp;
-{
- register struct listaddr *g;
- register struct uvif *v;
-
- v = &uvifs[vifi];
-
- for (g = v->uv_groups; g != NULL; g = g->al_next)
- if (mcastgrp == g->al_addr)
- return 1;
-
- return 0;
-}
-
-/*
- * Finds the group entry with the specified source and netmask.
- * If netmask is 0, it uses the route's netmask.
- *
- * Returns TRUE if found a match, and the global variable gtp is left
- * pointing to entry before the found entry.
- * Returns FALSE if no exact match found, gtp is left pointing to before
- * the entry in question belongs, or is NULL if the it belongs at the
- * head of the list.
- */
-int
-find_src_grp(src, mask, grp)
- u_int32 src;
- u_int32 mask;
- u_int32 grp;
-{
- struct gtable *gt;
-
- gtp = NULL;
- gt = kernel_table;
- while (gt != NULL) {
- if (grp == gt->gt_mcastgrp &&
- (mask ? (gt->gt_route->rt_origin == src &&
- gt->gt_route->rt_originmask == mask) :
- ((src & gt->gt_route->rt_originmask) ==
- gt->gt_route->rt_origin)))
- return TRUE;
- if (ntohl(grp) > ntohl(gt->gt_mcastgrp) ||
- (grp == gt->gt_mcastgrp &&
- (ntohl(mask) < ntohl(gt->gt_route->rt_originmask) ||
- (mask == gt->gt_route->rt_originmask &&
- (ntohl(src) > ntohl(gt->gt_route->rt_origin)))))) {
- gtp = gt;
- gt = gt->gt_gnext;
- }
- else break;
- }
- return FALSE;
-}
-
-/*
- * Check if the neighbor supports pruning
- */
-static int
-pruning_neighbor(vifi, addr)
- vifi_t vifi;
- u_int32 addr;
-{
- struct listaddr *n = neighbor_info(vifi, addr);
- int vers;
-
- if (n == NULL)
- return 0;
-
- if (n->al_flags & NF_PRUNE)
- return 1;
-
- /*
- * Versions from 3.0 to 3.4 relied on the version number to identify
- * that they could handle pruning.
- */
- vers = NBR_VERS(n);
- return (vers >= 0x0300 && vers <= 0x0304);
-}
-
-/*
- * Can the neighbor in question handle multicast traceroute?
- */
-static int
-can_mtrace(vifi, addr)
- vifi_t vifi;
- u_int32 addr;
-{
- struct listaddr *n = neighbor_info(vifi, addr);
- int vers;
-
- if (n == NULL)
- return 0;
-
- if (n->al_flags & NF_MTRACE)
- return 1;
-
- /*
- * Versions 3.3 and 3.4 relied on the version number to identify
- * that they could handle traceroute.
- */
- vers = NBR_VERS(n);
- return (vers >= 0x0303 && vers <= 0x0304);
-}
-
-/*
- * Returns the prune entry of the router, or NULL if none exists
- */
-static struct ptable *
-find_prune_entry(vr, pt)
- u_int32 vr;
- struct ptable *pt;
-{
- while (pt) {
- if (pt->pt_router == vr)
- return pt;
- pt = pt->pt_next;
- }
-
- return NULL;
-}
-
-/*
- * Send a prune message to the dominant router for
- * this source.
- *
- * Record an entry that a prune was sent for this group
- */
-static void
-send_prune(gt)
- struct gtable *gt;
-{
- struct ptable *pt;
- char *p;
- int i;
- int datalen;
- u_int32 src;
- u_int32 dst;
- u_int32 tmp;
-
- /* Don't process any prunes if router is not pruning */
- if (pruning == 0)
- return;
-
- /* Can't process a prune if we don't have an associated route */
- if (gt->gt_route == NULL)
- return;
-
- /* Don't send a prune to a non-pruning router */
- if (!pruning_neighbor(gt->gt_route->rt_parent, gt->gt_route->rt_gateway))
- return;
-
- /*
- * sends a prune message to the router upstream.
- */
- src = uvifs[gt->gt_route->rt_parent].uv_lcl_addr;
- dst = gt->gt_route->rt_gateway;
-
- p = send_buf + MIN_IP_HEADER_LEN + IGMP_MINLEN;
- datalen = 0;
-
- /*
- * determine prune lifetime
- */
- gt->gt_prsent_timer = gt->gt_timer;
- for (pt = gt->gt_pruntbl; pt; pt = pt->pt_next)
- if (pt->pt_timer < gt->gt_prsent_timer)
- gt->gt_prsent_timer = pt->pt_timer;
-
- /*
- * If we have a graft pending, cancel graft retransmission
- */
- gt->gt_grftsnt = 0;
-
- for (i = 0; i < 4; i++)
- *p++ = ((char *)&(gt->gt_route->rt_origin))[i];
- for (i = 0; i < 4; i++)
- *p++ = ((char *)&(gt->gt_mcastgrp))[i];
- tmp = htonl(gt->gt_prsent_timer);
- for (i = 0; i < 4; i++)
- *p++ = ((char *)&(tmp))[i];
- datalen += 12;
-
- send_igmp(src, dst, IGMP_DVMRP, DVMRP_PRUNE,
- htonl(MROUTED_LEVEL), datalen);
-
- log(LOG_DEBUG, 0, "sent prune for (%s %s)/%d on vif %d to %s",
- inet_fmts(gt->gt_route->rt_origin, gt->gt_route->rt_originmask, s1),
- inet_fmt(gt->gt_mcastgrp, s2),
- gt->gt_prsent_timer, gt->gt_route->rt_parent,
- inet_fmt(gt->gt_route->rt_gateway, s3));
-}
-
-/*
- * a prune was sent upstream
- * so, a graft has to be sent to annul the prune
- * set up a graft timer so that if an ack is not
- * heard within that time, another graft request
- * is sent out.
- */
-static void
-send_graft(gt)
- struct gtable *gt;
-{
- register char *p;
- register int i;
- int datalen;
- u_int32 src;
- u_int32 dst;
-
- /* Can't send a graft without an associated route */
- if (gt->gt_route == NULL)
- return;
-
- src = uvifs[gt->gt_route->rt_parent].uv_lcl_addr;
- dst = gt->gt_route->rt_gateway;
-
- p = send_buf + MIN_IP_HEADER_LEN + IGMP_MINLEN;
- datalen = 0;
-
- for (i = 0; i < 4; i++)
- *p++ = ((char *)&(gt->gt_route->rt_origin))[i];
- for (i = 0; i < 4; i++)
- *p++ = ((char *)&(gt->gt_mcastgrp))[i];
- datalen += 8;
-
- if (datalen != 0) {
- send_igmp(src, dst, IGMP_DVMRP, DVMRP_GRAFT,
- htonl(MROUTED_LEVEL), datalen);
- }
- log(LOG_DEBUG, 0, "sent graft for (%s %s) to %s on vif %d",
- inet_fmts(gt->gt_route->rt_origin, gt->gt_route->rt_originmask, s1),
- inet_fmt(gt->gt_mcastgrp, s2),
- inet_fmt(gt->gt_route->rt_gateway, s3), gt->gt_route->rt_parent);
-}
-
-/*
- * Send an ack that a graft was received
- */
-static void
-send_graft_ack(src, dst, origin, grp)
- u_int32 src;
- u_int32 dst;
- u_int32 origin;
- u_int32 grp;
-{
- register char *p;
- register int i;
- int datalen;
-
- p = send_buf + MIN_IP_HEADER_LEN + IGMP_MINLEN;
- datalen = 0;
-
- for (i = 0; i < 4; i++)
- *p++ = ((char *)&(origin))[i];
- for (i = 0; i < 4; i++)
- *p++ = ((char *)&(grp))[i];
- datalen += 8;
-
- send_igmp(src, dst, IGMP_DVMRP, DVMRP_GRAFT_ACK,
- htonl(MROUTED_LEVEL), datalen);
-
- log(LOG_DEBUG, 0, "sent graft ack for (%s, %s) to %s",
- inet_fmt(origin, s1), inet_fmt(grp, s2), inet_fmt(dst, s3));
-}
-
-/*
- * Update the kernel cache with all the routes hanging off the group entry
- */
-static void
-update_kernel(g)
- struct gtable *g;
-{
- struct stable *st;
-
- for (st = g->gt_srctbl; st; st = st->st_next)
- k_add_rg(st->st_origin, g);
-}
-
-/****************************************************************************
- Functions that are used externally
-****************************************************************************/
-
-#ifdef SNMP
-#include <sys/types.h>
-#include "snmp.h"
-
-/*
- * Find a specific group entry in the group table
- */
-struct gtable *
-find_grp(grp)
- u_long grp;
-{
- struct gtable *gt;
-
- for (gt = kernel_table; gt; gt = gt->gt_gnext) {
- if (ntohl(grp) < ntohl(gt->gt_mcastgrp))
- break;
- if (gt->gt_mcastgrp == grp)
- return gt;
- }
- return NULL;
-}
-
-/*
- * Given a group entry and source, find the corresponding source table
- * entry
- */
-struct stable *
-find_grp_src(gt, src)
- struct gtable *gt;
- u_long src;
-{
- struct stable *st;
- u_long grp = gt->gt_mcastgrp;
- struct gtable *gtcurr;
-
- for (gtcurr = gt; gtcurr->gt_mcastgrp == grp; gtcurr = gtcurr->gt_gnext) {
- for (st = gtcurr->gt_srctbl; st; st = st->st_next)
- if (st->st_origin == src)
- return st;
- }
- return NULL;
-}
-
-/*
- * Find next entry > specification
- */
-int
-next_grp_src_mask(gtpp, stpp, grp, src, mask)
- struct gtable **gtpp; /* ordered by group */
- struct stable **stpp; /* ordered by source */
- u_long grp;
- u_long src;
- u_long mask;
-{
- struct gtable *gt, *gbest = NULL;
- struct stable *st, *sbest = NULL;
-
- /* Find first group entry >= grp spec */
- (*gtpp) = kernel_table;
- while ((*gtpp) && ntohl((*gtpp)->gt_mcastgrp) < ntohl(grp))
- (*gtpp)=(*gtpp)->gt_gnext;
- if (!(*gtpp))
- return 0; /* no more groups */
-
- for (gt = kernel_table; gt; gt=gt->gt_gnext) {
- /* Since grps are ordered, we can stop when group changes from gbest */
- if (gbest && gbest->gt_mcastgrp != gt->gt_mcastgrp)
- break;
- for (st = gt->gt_srctbl; st; st=st->st_next) {
-
- /* Among those entries > spec, find "lowest" one */
- if (((ntohl(gt->gt_mcastgrp)> ntohl(grp))
- || (ntohl(gt->gt_mcastgrp)==ntohl(grp)
- && ntohl(st->st_origin)> ntohl(src))
- || (ntohl(gt->gt_mcastgrp)==ntohl(grp)
- && ntohl(st->st_origin)==src && 0xFFFFFFFF>ntohl(mask)))
- && (!gbest
- || (ntohl(gt->gt_mcastgrp)< ntohl(gbest->gt_mcastgrp))
- || (ntohl(gt->gt_mcastgrp)==ntohl(gbest->gt_mcastgrp)
- && ntohl(st->st_origin)< ntohl(sbest->st_origin)))) {
- gbest = gt;
- sbest = st;
- }
- }
- }
- (*gtpp) = gbest;
- (*stpp) = sbest;
- return (*gtpp)!=0;
-}
-
-/*
- * Ensure that sg contains current information for the given group,source.
- * This is fetched from the kernel as a unit so that counts for the entry
- * are consistent, i.e. packet and byte counts for the same entry are
- * read at the same time.
- */
-void
-refresh_sg(sg, gt, st)
- struct sioc_sg_req *sg;
- struct gtable *gt;
- struct stable *st;
-{
- static int lastq = -1;
-
- if (quantum != lastq || sg->src.s_addr!=st->st_origin
- || sg->grp.s_addr!=gt->gt_mcastgrp) {
- lastq = quantum;
- sg->src.s_addr = st->st_origin;
- sg->grp.s_addr = gt->gt_mcastgrp;
- ioctl(udp_socket, SIOCGETSGCNT, (char *)sg);
- }
-}
-
-/*
- * Return pointer to a specific route entry. This must be a separate
- * function from find_route() which modifies rtp.
- */
-struct rtentry *
-snmp_find_route(src, mask)
- register u_long src, mask;
-{
- register struct rtentry *rt;
-
- for (rt = routing_table; rt; rt = rt->rt_next) {
- if (src == rt->rt_origin && mask == rt->rt_originmask)
- return rt;
- }
- return NULL;
-}
-
-/*
- * Find next route entry > specification
- */
-int
-next_route(rtpp, src, mask)
- struct rtentry **rtpp;
- u_long src;
- u_long mask;
-{
- struct rtentry *rt, *rbest = NULL;
-
- /* Among all entries > spec, find "lowest" one in order */
- for (rt = routing_table; rt; rt=rt->rt_next) {
- if ((ntohl(rt->rt_origin) > ntohl(src)
- || (ntohl(rt->rt_origin) == ntohl(src)
- && ntohl(rt->rt_originmask) > ntohl(mask)))
- && (!rbest || (ntohl(rt->rt_origin) < ntohl(rbest->rt_origin))
- || (ntohl(rt->rt_origin) == ntohl(rbest->rt_origin)
- && ntohl(rt->rt_originmask) < ntohl(rbest->rt_originmask))))
- rbest = rt;
- }
- (*rtpp) = rbest;
- return (*rtpp)!=0;
-}
-
-/*
- * Given a routing table entry, and a vifi, find the next vifi/entry
- */
-int
-next_route_child(rtpp, src, mask, vifi)
- struct rtentry **rtpp;
- u_long src;
- u_long mask;
- vifi_t *vifi; /* vif at which to start looking */
-{
- struct rtentry *rt;
-
- /* Get (S,M) entry */
- if (!((*rtpp) = snmp_find_route(src,mask)))
- if (!next_route(rtpp, src, mask))
- return 0;
-
- /* Continue until we get one with a valid next vif */
- do {
- for (; (*rtpp)->rt_children && *vifi<numvifs; (*vifi)++)
- if (VIFM_ISSET(*vifi, (*rtpp)->rt_children))
- return 1;
- *vifi = 0;
- } while( next_route(rtpp, (*rtpp)->rt_origin, (*rtpp)->rt_originmask) );
-
- return 0;
-}
-
-/*
- * Given a routing table entry, and a vifi, find the next entry
- * equal to or greater than those
- */
-int
-next_child(gtpp, stpp, grp, src, mask, vifi)
- struct gtable **gtpp;
- struct stable **stpp;
- u_long grp;
- u_long src;
- u_long mask;
- vifi_t *vifi; /* vif at which to start looking */
-{
- struct stable *st;
-
- /* Get (G,S,M) entry */
- if (mask!=0xFFFFFFFF
- || !((*gtpp) = find_grp(grp))
- || !((*stpp) = find_grp_src((*gtpp),src)))
- if (!next_grp_src_mask(gtpp, stpp, grp, src, mask))
- return 0;
-
- /* Continue until we get one with a valid next vif */
- do {
- for (; (*gtpp)->gt_route->rt_children && *vifi<numvifs; (*vifi)++)
- if (VIFM_ISSET(*vifi, (*gtpp)->gt_route->rt_children))
- return 1;
- *vifi = 0;
- } while (next_grp_src_mask(gtpp, stpp, (*gtpp)->gt_mcastgrp,
- (*stpp)->st_origin, 0xFFFFFFFF) );
-
- return 0;
-}
-#endif /* SNMP */
-
-/*
- * Initialize the kernel table structure
- */
-void
-init_ktable()
-{
- kernel_table = NULL;
- kernel_no_route = NULL;
- kroutes = 0;
-}
-
-/*
- * Add a new table entry for (origin, mcastgrp)
- */
-void
-add_table_entry(origin, mcastgrp)
- u_int32 origin;
- u_int32 mcastgrp;
-{
- struct rtentry *r;
- struct gtable *gt,**gtnp,*prev_gt;
- struct stable *st,**stnp;
- vifi_t i;
-
-#ifdef DEBUG_MFC
- md_log(MD_MISS, origin, mcastgrp);
-#endif
-
- r = determine_route(origin);
- prev_gt = NULL;
- if (r == NULL) {
- /*
- * Look for it on the no_route table; if it is found then
- * it will be detected as a duplicate below.
- */
- for (gt = kernel_no_route; gt; gt = gt->gt_next)
- if (mcastgrp == gt->gt_mcastgrp &&
- gt->gt_srctbl && gt->gt_srctbl->st_origin == origin)
- break;
- gtnp = &kernel_no_route;
- } else {
- gtnp = &r->rt_groups;
- while ((gt = *gtnp) != NULL) {
- if (gt->gt_mcastgrp >= mcastgrp)
- break;
- gtnp = &gt->gt_next;
- prev_gt = gt;
- }
- }
-
- if (gt == NULL || gt->gt_mcastgrp != mcastgrp) {
- gt = (struct gtable *)malloc(sizeof(struct gtable));
- if (gt == NULL)
- log(LOG_ERR, 0, "ran out of memory");
-
- gt->gt_mcastgrp = mcastgrp;
- gt->gt_timer = CACHE_LIFETIME(cache_lifetime);
- time(&gt->gt_ctime);
- gt->gt_grpmems = 0;
- gt->gt_scope = 0;
- gt->gt_prsent_timer = 0;
- gt->gt_grftsnt = 0;
- gt->gt_srctbl = NULL;
- gt->gt_pruntbl = NULL;
- gt->gt_route = r;
-#ifdef RSRR
- gt->gt_rsrr_cache = NULL;
-#endif
-
- if (r != NULL) {
- /* obtain the multicast group membership list */
- for (i = 0; i < numvifs; i++) {
- if (VIFM_ISSET(i, r->rt_children) &&
- !(VIFM_ISSET(i, r->rt_leaves)))
- VIFM_SET(i, gt->gt_grpmems);
-
- if (VIFM_ISSET(i, r->rt_leaves) && grplst_mem(i, mcastgrp))
- VIFM_SET(i, gt->gt_grpmems);
- }
- GET_SCOPE(gt);
- if (VIFM_ISSET(r->rt_parent, gt->gt_scope))
- gt->gt_scope = -1;
- gt->gt_grpmems &= ~gt->gt_scope;
- } else {
- gt->gt_scope = -1;
- gt->gt_grpmems = 0;
- }
-
- /* update ttls */
- prun_add_ttls(gt);
-
- gt->gt_next = *gtnp;
- *gtnp = gt;
- if (gt->gt_next)
- gt->gt_next->gt_prev = gt;
- gt->gt_prev = prev_gt;
-
- if (r) {
- if (find_src_grp(r->rt_origin, r->rt_originmask, gt->gt_mcastgrp)) {
- struct gtable *g;
-
- g = gtp ? gtp->gt_gnext : kernel_table;
- log(LOG_WARNING, 0, "Entry for (%s %s) (rt:%x) exists (rt:%x)",
- inet_fmts(r->rt_origin, r->rt_originmask, s1),
- inet_fmt(g->gt_mcastgrp, s2),
- r, g->gt_route);
- } else {
- if (gtp) {
- gt->gt_gnext = gtp->gt_gnext;
- gt->gt_gprev = gtp;
- gtp->gt_gnext = gt;
- } else {
- gt->gt_gnext = kernel_table;
- gt->gt_gprev = NULL;
- kernel_table = gt;
- }
- if (gt->gt_gnext)
- gt->gt_gnext->gt_gprev = gt;
- }
- } else {
- gt->gt_gnext = gt->gt_gprev = NULL;
- }
- }
-
- stnp = &gt->gt_srctbl;
- while ((st = *stnp) != NULL) {
- if (ntohl(st->st_origin) >= ntohl(origin))
- break;
- stnp = &st->st_next;
- }
-
- if (st == NULL || st->st_origin != origin) {
- st = (struct stable *)malloc(sizeof(struct stable));
- if (st == NULL)
- log(LOG_ERR, 0, "ran out of memory");
-
- st->st_origin = origin;
- st->st_pktcnt = 0;
- st->st_next = *stnp;
- *stnp = st;
- } else {
-#ifdef DEBUG_MFC
- md_log(MD_DUPE, origin, mcastgrp);
-#endif
- log(LOG_WARNING, 0, "kernel entry already exists for (%s %s)",
- inet_fmt(origin, s1), inet_fmt(mcastgrp, s2));
- /* XXX Doing this should cause no harm, and may ensure
- * kernel<>mrouted synchronization */
- k_add_rg(origin, gt);
- return;
- }
-
- kroutes++;
- k_add_rg(origin, gt);
-
- log(LOG_DEBUG, 0, "add cache entry (%s %s) gm:%x, parent-vif:%d",
- inet_fmt(origin, s1),
- inet_fmt(mcastgrp, s2),
- gt->gt_grpmems, r ? r->rt_parent : -1);
-
- /* If there are no leaf vifs
- * which have this group, then
- * mark this src-grp as a prune candidate.
- */
- if (!gt->gt_prsent_timer && !gt->gt_grpmems && r && r->rt_gateway)
- send_prune(gt);
-}
-
-/*
- * An mrouter has gone down and come up on an interface
- * Forward on that interface immediately
- */
-void
-reset_neighbor_state(vifi, addr)
- vifi_t vifi;
- u_int32 addr;
-{
- struct rtentry *r;
- struct gtable *g;
- struct ptable *pt, **ptnp;
- struct stable *st;
-
- for (g = kernel_table; g; g = g->gt_gnext) {
- r = g->gt_route;
-
- /*
- * If neighbor was the parent, remove the prune sent state
- * and all of the source cache info so that prunes get
- * regenerated.
- */
- if (vifi == r->rt_parent) {
- if (addr == r->rt_gateway) {
- log(LOG_DEBUG, 0, "reset_neighbor_state parent reset (%s %s)",
- inet_fmts(r->rt_origin, r->rt_originmask, s1),
- inet_fmt(g->gt_mcastgrp, s2));
-
- g->gt_prsent_timer = 0;
- g->gt_grftsnt = 0;
- while (st = g->gt_srctbl) {
- g->gt_srctbl = st->st_next;
- k_del_rg(st->st_origin, g);
- kroutes--;
- free(st);
- }
- }
- } else {
- /*
- * Neighbor was not the parent, send grafts to join the groups
- */
- if (g->gt_prsent_timer) {
- g->gt_grftsnt = 1;
- send_graft(g);
- g->gt_prsent_timer = 0;
- }
-
- /*
- * Remove any prunes that this router has sent us.
- */
- ptnp = &g->gt_pruntbl;
- while ((pt = *ptnp) != NULL) {
- if (pt->pt_vifi == vifi && pt->pt_router == addr) {
- *ptnp = pt->pt_next;
- free(pt);
- } else
- ptnp = &pt->pt_next;
- }
-
- /*
- * And see if we want to forward again.
- */
- if (!VIFM_ISSET(vifi, g->gt_grpmems)) {
- if (VIFM_ISSET(vifi, r->rt_children) &&
- !(VIFM_ISSET(vifi, r->rt_leaves)))
- VIFM_SET(vifi, g->gt_grpmems);
-
- if (VIFM_ISSET(vifi, r->rt_leaves) &&
- grplst_mem(vifi, g->gt_mcastgrp))
- VIFM_SET(vifi, g->gt_grpmems);
-
- g->gt_grpmems &= ~g->gt_scope;
- prun_add_ttls(g);
-
- /* Update kernel state */
- update_kernel(g);
-#ifdef RSRR
- /* Send route change notification to reservation protocol. */
- rsrr_cache_send(g,1);
-#endif /* RSRR */
-
- log(LOG_DEBUG, 0, "reset member state (%s %s) gm:%x",
- inet_fmts(r->rt_origin, r->rt_originmask, s1),
- inet_fmt(g->gt_mcastgrp, s2), g->gt_grpmems);
- }
- }
- }
-}
-
-/*
- * Delete table entry from the kernel
- * del_flag determines how many entries to delete
- */
-void
-del_table_entry(r, mcastgrp, del_flag)
- struct rtentry *r;
- u_int32 mcastgrp;
- u_int del_flag;
-{
- struct gtable *g, *prev_g;
- struct stable *st, *prev_st;
- struct ptable *pt, *prev_pt;
-
- if (del_flag == DEL_ALL_ROUTES) {
- g = r->rt_groups;
- while (g) {
- log(LOG_DEBUG, 0, "del_table_entry deleting (%s %s)",
- inet_fmts(r->rt_origin, r->rt_originmask, s1),
- inet_fmt(g->gt_mcastgrp, s2));
- st = g->gt_srctbl;
- while (st) {
- if (k_del_rg(st->st_origin, g) < 0) {
- log(LOG_WARNING, errno,
- "del_table_entry trying to delete (%s, %s)",
- inet_fmt(st->st_origin, s1),
- inet_fmt(g->gt_mcastgrp, s2));
- }
- kroutes--;
- prev_st = st;
- st = st->st_next;
- free(prev_st);
- }
- g->gt_srctbl = NULL;
-
- pt = g->gt_pruntbl;
- while (pt) {
- prev_pt = pt;
- pt = pt->pt_next;
- free(prev_pt);
- }
- g->gt_pruntbl = NULL;
-
- if (g->gt_gnext)
- g->gt_gnext->gt_gprev = g->gt_gprev;
- if (g->gt_gprev)
- g->gt_gprev->gt_gnext = g->gt_gnext;
- else
- kernel_table = g->gt_gnext;
-
-#ifdef RSRR
- /* Send route change notification to reservation protocol. */
- rsrr_cache_send(g,0);
- rsrr_cache_clean(g);
-#endif /* RSRR */
- prev_g = g;
- g = g->gt_next;
- free(prev_g);
- }
- r->rt_groups = NULL;
- }
-
- /*
- * Dummy routine - someday this may be needed, so it is just there
- */
- if (del_flag == DEL_RTE_GROUP) {
- prev_g = (struct gtable *)&r->rt_groups;
- for (g = r->rt_groups; g; g = g->gt_next) {
- if (g->gt_mcastgrp == mcastgrp) {
- log(LOG_DEBUG, 0, "del_table_entry deleting (%s %s)",
- inet_fmts(r->rt_origin, r->rt_originmask, s1),
- inet_fmt(g->gt_mcastgrp, s2));
- st = g->gt_srctbl;
- while (st) {
- if (k_del_rg(st->st_origin, g) < 0) {
- log(LOG_WARNING, errno,
- "del_table_entry trying to delete (%s, %s)",
- inet_fmt(st->st_origin, s1),
- inet_fmt(g->gt_mcastgrp, s2));
- }
- kroutes--;
- prev_st = st;
- st = st->st_next;
- free(prev_st);
- }
- g->gt_srctbl = NULL;
-
- pt = g->gt_pruntbl;
- while (pt) {
- prev_pt = pt;
- pt = pt->pt_next;
- free(prev_pt);
- }
- g->gt_pruntbl = NULL;
-
- if (g->gt_gnext)
- g->gt_gnext->gt_gprev = g->gt_gprev;
- if (g->gt_gprev)
- g->gt_gprev->gt_gnext = g->gt_gnext;
- else
- kernel_table = g->gt_gnext;
-
- if (prev_g != (struct gtable *)&r->rt_groups)
- g->gt_next->gt_prev = prev_g;
- else
- g->gt_next->gt_prev = NULL;
- prev_g->gt_next = g->gt_next;
-
-#ifdef RSRR
- /* Send route change notification to reservation protocol. */
- rsrr_cache_send(g,0);
- rsrr_cache_clean(g);
-#endif /* RSRR */
- free(g);
- g = prev_g;
- } else {
- prev_g = g;
- }
- }
- }
-}
-
-/*
- * update kernel table entry when a route entry changes
- */
-void
-update_table_entry(r)
- struct rtentry *r;
-{
- struct gtable *g;
- struct ptable *pt, *prev_pt;
- vifi_t i;
-
- for (g = r->rt_groups; g; g = g->gt_next) {
- pt = g->gt_pruntbl;
- while (pt) {
- prev_pt = pt->pt_next;
- free(pt);
- pt = prev_pt;
- }
- g->gt_pruntbl = NULL;
-
- g->gt_grpmems = 0;
-
- /* obtain the multicast group membership list */
- for (i = 0; i < numvifs; i++) {
- if (VIFM_ISSET(i, r->rt_children) &&
- !(VIFM_ISSET(i, r->rt_leaves)))
- VIFM_SET(i, g->gt_grpmems);
-
- if (VIFM_ISSET(i, r->rt_leaves) && grplst_mem(i, g->gt_mcastgrp))
- VIFM_SET(i, g->gt_grpmems);
- }
- if (VIFM_ISSET(r->rt_parent, g->gt_scope))
- g->gt_scope = -1;
- g->gt_grpmems &= ~g->gt_scope;
-
- log(LOG_DEBUG, 0, "updating cache entries (%s %s) gm:%x",
- inet_fmts(r->rt_origin, r->rt_originmask, s1),
- inet_fmt(g->gt_mcastgrp, s2),
- g->gt_grpmems);
-
- if (g->gt_grpmems && g->gt_prsent_timer) {
- g->gt_grftsnt = 1;
- send_graft(g);
- g->gt_prsent_timer = 0;
- }
-
- /* update ttls and add entry into kernel */
- prun_add_ttls(g);
- update_kernel(g);
-#ifdef RSRR
- /* Send route change notification to reservation protocol. */
- rsrr_cache_send(g,1);
-#endif /* RSRR */
-
- /* Check if we want to prune this group */
- if (!g->gt_prsent_timer && g->gt_grpmems == 0 && r->rt_gateway) {
- g->gt_timer = CACHE_LIFETIME(cache_lifetime);
- send_prune(g);
- }
- }
-}
-
-/*
- * set the forwarding flag for all mcastgrps on this vifi
- */
-void
-update_lclgrp(vifi, mcastgrp)
- vifi_t vifi;
- u_int32 mcastgrp;
-{
- struct rtentry *r;
- struct gtable *g;
-
- log(LOG_DEBUG, 0, "group %s joined on vif %d",
- inet_fmt(mcastgrp, s1), vifi);
-
- for (g = kernel_table; g; g = g->gt_gnext) {
- if (ntohl(mcastgrp) < ntohl(g->gt_mcastgrp))
- break;
-
- r = g->gt_route;
- if (g->gt_mcastgrp == mcastgrp &&
- VIFM_ISSET(vifi, r->rt_children)) {
-
- VIFM_SET(vifi, g->gt_grpmems);
- g->gt_grpmems &= ~g->gt_scope;
- if (g->gt_grpmems == 0)
- continue;
-
- prun_add_ttls(g);
- log(LOG_DEBUG, 0, "update lclgrp (%s %s) gm:%x",
- inet_fmts(r->rt_origin, r->rt_originmask, s1),
- inet_fmt(g->gt_mcastgrp, s2), g->gt_grpmems);
-
- update_kernel(g);
-#ifdef RSRR
- /* Send route change notification to reservation protocol. */
- rsrr_cache_send(g,1);
-#endif /* RSRR */
- }
- }
-}
-
-/*
- * reset forwarding flag for all mcastgrps on this vifi
- */
-void
-delete_lclgrp(vifi, mcastgrp)
- vifi_t vifi;
- u_int32 mcastgrp;
-{
- struct rtentry *r;
- struct gtable *g;
-
- log(LOG_DEBUG, 0, "group %s left on vif %d",
- inet_fmt(mcastgrp, s1), vifi);
-
- for (g = kernel_table; g; g = g->gt_gnext) {
- if (ntohl(mcastgrp) < ntohl(g->gt_mcastgrp))
- break;
-
- if (g->gt_mcastgrp == mcastgrp) {
- int stop_sending = 1;
-
- r = g->gt_route;
- /*
- * If this is not a leaf, then we have router neighbors on this
- * vif. Only turn off forwarding if they have all pruned.
- */
- if (!VIFM_ISSET(vifi, r->rt_leaves)) {
- struct listaddr *vr;
-
- for (vr = uvifs[vifi].uv_neighbors; vr; vr = vr->al_next)
- if (find_prune_entry(vr->al_addr, g->gt_pruntbl) == NULL) {
- stop_sending = 0;
- break;
- }
- }
-
- if (stop_sending) {
- VIFM_CLR(vifi, g->gt_grpmems);
- log(LOG_DEBUG, 0, "delete lclgrp (%s %s) gm:%x",
- inet_fmts(r->rt_origin, r->rt_originmask, s1),
- inet_fmt(g->gt_mcastgrp, s2), g->gt_grpmems);
-
- prun_add_ttls(g);
- update_kernel(g);
-#ifdef RSRR
- /* Send route change notification to reservation protocol. */
- rsrr_cache_send(g,1);
-#endif /* RSRR */
-
- /*
- * If there are no more members of this particular group,
- * send prune upstream
- */
- if (!g->gt_prsent_timer && g->gt_grpmems == 0 && r->rt_gateway)
- send_prune(g);
- }
- }
- }
-}
-
-/*
- * Takes the prune message received and then strips it to
- * determine the (src, grp) pair to be pruned.
- *
- * Adds the router to the (src, grp) entry then.
- *
- * Determines if further packets have to be sent down that vif
- *
- * Determines if a corresponding prune message has to be generated
- */
-void
-accept_prune(src, dst, p, datalen)
- u_int32 src;
- u_int32 dst;
- char *p;
- int datalen;
-{
- u_int32 prun_src;
- u_int32 prun_grp;
- u_int32 prun_tmr;
- vifi_t vifi;
- int i;
- int stop_sending;
- struct rtentry *r;
- struct gtable *g;
- struct ptable *pt;
- struct listaddr *vr;
-
- /* Don't process any prunes if router is not pruning */
- if (pruning == 0)
- return;
-
- if ((vifi = find_vif(src, dst)) == NO_VIF) {
- log(LOG_INFO, 0,
- "ignoring prune report from non-neighbor %s",
- inet_fmt(src, s1));
- return;
- }
-
- /* Check if enough data is present */
- if (datalen < 12)
- {
- log(LOG_WARNING, 0,
- "non-decipherable prune from %s",
- inet_fmt(src, s1));
- return;
- }
-
- for (i = 0; i< 4; i++)
- ((char *)&prun_src)[i] = *p++;
- for (i = 0; i< 4; i++)
- ((char *)&prun_grp)[i] = *p++;
- for (i = 0; i< 4; i++)
- ((char *)&prun_tmr)[i] = *p++;
- prun_tmr = ntohl(prun_tmr);
-
- log(LOG_DEBUG, 0, "%s on vif %d prunes (%s %s)/%d",
- inet_fmt(src, s1), vifi,
- inet_fmt(prun_src, s2), inet_fmt(prun_grp, s3), prun_tmr);
-
- /*
- * Find the subnet for the prune
- */
- if (find_src_grp(prun_src, 0, prun_grp)) {
- g = gtp ? gtp->gt_gnext : kernel_table;
- r = g->gt_route;
-
- if (!VIFM_ISSET(vifi, r->rt_children)) {
- log(LOG_WARNING, 0, "prune received from non-child %s for (%s %s)",
- inet_fmt(src, s1), inet_fmt(prun_src, s2),
- inet_fmt(prun_grp, s3));
- return;
- }
- if (VIFM_ISSET(vifi, g->gt_scope)) {
- log(LOG_WARNING, 0, "prune received from %s on scoped grp (%s %s)",
- inet_fmt(src, s1), inet_fmt(prun_src, s2),
- inet_fmt(prun_grp, s3));
- return;
- }
- if ((pt = find_prune_entry(src, g->gt_pruntbl)) != NULL) {
- /*
- * If it's about to expire, then it's only still around because
- * of timer granularity, so don't warn about it.
- */
- if (pt->pt_timer > 10) {
- log(LOG_WARNING, 0, "%s %d from %s for (%s %s)/%d %s %d %s %x",
- "duplicate prune received on vif",
- vifi, inet_fmt(src, s1), inet_fmt(prun_src, s2),
- inet_fmt(prun_grp, s3), prun_tmr,
- "old timer:", pt->pt_timer, "cur gm:", g->gt_grpmems);
- }
- pt->pt_timer = prun_tmr;
- } else {
- /* allocate space for the prune structure */
- pt = (struct ptable *)(malloc(sizeof(struct ptable)));
- if (pt == NULL)
- log(LOG_ERR, 0, "pt: ran out of memory");
-
- pt->pt_vifi = vifi;
- pt->pt_router = src;
- pt->pt_timer = prun_tmr;
-
- pt->pt_next = g->gt_pruntbl;
- g->gt_pruntbl = pt;
- }
-
- /* Refresh the group's lifetime */
- g->gt_timer = CACHE_LIFETIME(cache_lifetime);
- if (g->gt_timer < prun_tmr)
- g->gt_timer = prun_tmr;
-
- /*
- * check if any more packets need to be sent on the
- * vif which sent this message
- */
- stop_sending = 1;
- for (vr = uvifs[vifi].uv_neighbors; vr; vr = vr->al_next)
- if (find_prune_entry(vr->al_addr, g->gt_pruntbl) == NULL) {
- stop_sending = 0;
- break;
- }
-
- if (stop_sending && !grplst_mem(vifi, prun_grp)) {
- VIFM_CLR(vifi, g->gt_grpmems);
- log(LOG_DEBUG, 0, "prune (%s %s), stop sending on vif %d, gm:%x",
- inet_fmts(r->rt_origin, r->rt_originmask, s1),
- inet_fmt(g->gt_mcastgrp, s2), vifi, g->gt_grpmems);
-
- prun_add_ttls(g);
- update_kernel(g);
-#ifdef RSRR
- /* Send route change notification to reservation protocol. */
- rsrr_cache_send(g,1);
-#endif /* RSRR */
- }
-
- /*
- * check if all the child routers have expressed no interest
- * in this group and if this group does not exist in the
- * interface
- * Send a prune message then upstream
- */
- if (!g->gt_prsent_timer && g->gt_grpmems == 0 && r->rt_gateway) {
- send_prune(g);
- }
- } else {
- /*
- * There is no kernel entry for this group. Therefore, we can
- * simply ignore the prune, as we are not forwarding this traffic
- * downstream.
- */
- log(LOG_DEBUG, 0, "%s (%s %s)/%d from %s",
- "prune message received with no kernel entry for",
- inet_fmt(prun_src, s1), inet_fmt(prun_grp, s2),
- prun_tmr, inet_fmt(src, s3));
- return;
- }
-}
-
-/*
- * Checks if this mcastgrp is present in the kernel table
- * If so and if a prune was sent, it sends a graft upwards
- */
-void
-chkgrp_graft(vifi, mcastgrp)
- vifi_t vifi;
- u_int32 mcastgrp;
-{
- struct rtentry *r;
- struct gtable *g;
-
- for (g = kernel_table; g; g = g->gt_gnext) {
- if (ntohl(mcastgrp) < ntohl(g->gt_mcastgrp))
- break;
-
- r = g->gt_route;
- if (g->gt_mcastgrp == mcastgrp && VIFM_ISSET(vifi, r->rt_children))
- if (g->gt_prsent_timer) {
- VIFM_SET(vifi, g->gt_grpmems);
-
- /*
- * If the vif that was joined was a scoped vif,
- * ignore it ; don't graft back
- */
- g->gt_grpmems &= ~g->gt_scope;
- if (g->gt_grpmems == 0)
- continue;
-
- /* set the flag for graft retransmission */
- g->gt_grftsnt = 1;
-
- /* send graft upwards */
- send_graft(g);
-
- /* reset the prune timer and update cache timer*/
- g->gt_prsent_timer = 0;
- g->gt_timer = max_prune_lifetime;
-
- log(LOG_DEBUG, 0, "chkgrp graft (%s %s) gm:%x",
- inet_fmts(r->rt_origin, r->rt_originmask, s1),
- inet_fmt(g->gt_mcastgrp, s2), g->gt_grpmems);
-
- prun_add_ttls(g);
- update_kernel(g);
-#ifdef RSRR
- /* Send route change notification to reservation protocol. */
- rsrr_cache_send(g,1);
-#endif /* RSRR */
- }
- }
-}
-
-/* determine the multicast group and src
- *
- * if it does, then determine if a prune was sent
- * upstream.
- * if prune sent upstream, send graft upstream and send
- * ack downstream.
- *
- * if no prune sent upstream, change the forwarding bit
- * for this interface and send ack downstream.
- *
- * if no entry exists for this group send ack downstream.
- */
-void
-accept_graft(src, dst, p, datalen)
- u_int32 src;
- u_int32 dst;
- char *p;
- int datalen;
-{
- vifi_t vifi;
- u_int32 graft_src;
- u_int32 graft_grp;
- int i;
- struct rtentry *r;
- struct gtable *g;
- struct ptable *pt, **ptnp;
-
- if ((vifi = find_vif(src, dst)) == NO_VIF) {
- log(LOG_INFO, 0,
- "ignoring graft from non-neighbor %s",
- inet_fmt(src, s1));
- return;
- }
-
- if (datalen < 8) {
- log(LOG_WARNING, 0,
- "received non-decipherable graft from %s",
- inet_fmt(src, s1));
- return;
- }
-
- for (i = 0; i< 4; i++)
- ((char *)&graft_src)[i] = *p++;
- for (i = 0; i< 4; i++)
- ((char *)&graft_grp)[i] = *p++;
-
- log(LOG_DEBUG, 0, "%s on vif %d grafts (%s %s)",
- inet_fmt(src, s1), vifi,
- inet_fmt(graft_src, s2), inet_fmt(graft_grp, s3));
-
- /*
- * Find the subnet for the graft
- */
- if (find_src_grp(graft_src, 0, graft_grp)) {
- g = gtp ? gtp->gt_gnext : kernel_table;
- r = g->gt_route;
-
- if (VIFM_ISSET(vifi, g->gt_scope)) {
- log(LOG_WARNING, 0, "graft received from %s on scoped grp (%s %s)",
- inet_fmt(src, s1), inet_fmt(graft_src, s2),
- inet_fmt(graft_grp, s3));
- return;
- }
-
- ptnp = &g->gt_pruntbl;
- while ((pt = *ptnp) != NULL) {
- if ((pt->pt_vifi == vifi) && (pt->pt_router == src)) {
- *ptnp = pt->pt_next;
- free(pt);
-
- VIFM_SET(vifi, g->gt_grpmems);
- log(LOG_DEBUG, 0, "accept graft (%s %s) gm:%x",
- inet_fmts(r->rt_origin, r->rt_originmask, s1),
- inet_fmt(g->gt_mcastgrp, s2), g->gt_grpmems);
-
- prun_add_ttls(g);
- update_kernel(g);
-#ifdef RSRR
- /* Send route change notification to reservation protocol. */
- rsrr_cache_send(g,1);
-#endif /* RSRR */
- break;
- } else {
- ptnp = &pt->pt_next;
- }
- }
-
- /* send ack downstream */
- send_graft_ack(dst, src, graft_src, graft_grp);
- g->gt_timer = max_prune_lifetime;
-
- if (g->gt_prsent_timer) {
- /* set the flag for graft retransmission */
- g->gt_grftsnt = 1;
-
- /* send graft upwards */
- send_graft(g);
-
- /* reset the prune sent timer */
- g->gt_prsent_timer = 0;
- }
- } else {
- /*
- * We have no state for the source and group in question.
- * We can simply acknowledge the graft, since we know
- * that we have no prune state, and grafts are requests
- * to remove prune state.
- */
- send_graft_ack(dst, src, graft_src, graft_grp);
- log(LOG_DEBUG, 0, "%s (%s %s) from %s",
- "graft received with no kernel entry for",
- inet_fmt(graft_src, s1), inet_fmt(graft_grp, s2),
- inet_fmt(src, s3));
- return;
- }
-}
-
-/*
- * find out which group is involved first of all
- * then determine if a graft was sent.
- * if no graft sent, ignore the message
- * if graft was sent and the ack is from the right
- * source, remove the graft timer so that we don't
- * have send a graft again
- */
-void
-accept_g_ack(src, dst, p, datalen)
- u_int32 src;
- u_int32 dst;
- char *p;
- int datalen;
-{
- struct gtable *g;
- vifi_t vifi;
- u_int32 grft_src;
- u_int32 grft_grp;
- int i;
-
- if ((vifi = find_vif(src, dst)) == NO_VIF) {
- log(LOG_INFO, 0,
- "ignoring graft ack from non-neighbor %s",
- inet_fmt(src, s1));
- return;
- }
-
- if (datalen < 0 || datalen > 8) {
- log(LOG_WARNING, 0,
- "received non-decipherable graft ack from %s",
- inet_fmt(src, s1));
- return;
- }
-
- for (i = 0; i< 4; i++)
- ((char *)&grft_src)[i] = *p++;
- for (i = 0; i< 4; i++)
- ((char *)&grft_grp)[i] = *p++;
-
- log(LOG_DEBUG, 0, "%s on vif %d acks graft (%s, %s)",
- inet_fmt(src, s1), vifi,
- inet_fmt(grft_src, s2), inet_fmt(grft_grp, s3));
-
- /*
- * Find the subnet for the graft ack
- */
- if (find_src_grp(grft_src, 0, grft_grp)) {
- g = gtp ? gtp->gt_gnext : kernel_table;
- g->gt_grftsnt = 0;
- } else {
- log(LOG_WARNING, 0, "%s (%s, %s) from %s",
- "rcvd graft ack with no kernel entry for",
- inet_fmt(grft_src, s1), inet_fmt(grft_grp, s2),
- inet_fmt(src, s3));
- return;
- }
-}
-
-
-/*
- * free all prune entries and kernel routes
- * normally, this should inform the kernel that all of its routes
- * are going away, but this is only called by restart(), which is
- * about to call MRT_DONE which does that anyway.
- */
-void
-free_all_prunes()
-{
- register struct rtentry *r;
- register struct gtable *g, *prev_g;
- register struct stable *s, *prev_s;
- register struct ptable *p, *prev_p;
-
- for (r = routing_table; r; r = r->rt_next) {
- g = r->rt_groups;
- while (g) {
- s = g->gt_srctbl;
- while (s) {
- prev_s = s;
- s = s->st_next;
- free(prev_s);
- }
-
- p = g->gt_pruntbl;
- while (p) {
- prev_p = p;
- p = p->pt_next;
- free(prev_p);
- }
-
- prev_g = g;
- g = g->gt_next;
- free(prev_g);
- }
- r->rt_groups = NULL;
- }
- kernel_table = NULL;
-
- g = kernel_no_route;
- while (g) {
- if (g->gt_srctbl)
- free(g->gt_srctbl);
-
- prev_g = g;
- g = g->gt_next;
- free(prev_g);
- }
- kernel_no_route = NULL;
-}
-
-/*
- * When a new route is created, search
- * a) The less-specific part of the routing table
- * b) The route-less kernel table
- * for sources that the new route might want to handle.
- *
- * "Inheriting" these sources might be cleanest, but simply deleting
- * them is easier, and letting the kernel re-request them.
- */
-void
-steal_sources(rt)
- struct rtentry *rt;
-{
- register struct rtentry *rp;
- register struct gtable *gt, **gtnp;
- register struct stable *st, **stnp;
-
- for (rp = rt->rt_next; rp; rp = rp->rt_next) {
- if ((rt->rt_origin & rp->rt_originmask) == rp->rt_origin) {
- log(LOG_DEBUG, 0, "Route for %s stealing sources from %s",
- inet_fmts(rt->rt_origin, rt->rt_originmask, s1),
- inet_fmts(rp->rt_origin, rp->rt_originmask, s2));
- for (gt = rp->rt_groups; gt; gt = gt->gt_next) {
- stnp = &gt->gt_srctbl;
- while ((st = *stnp) != NULL) {
- if ((st->st_origin & rt->rt_originmask) == rt->rt_origin) {
- log(LOG_DEBUG, 0, "%s stealing (%s %s) from %s",
- inet_fmts(rt->rt_origin, rt->rt_originmask, s1),
- inet_fmt(st->st_origin, s3),
- inet_fmt(gt->gt_mcastgrp, s4),
- inet_fmts(rp->rt_origin, rp->rt_originmask, s2));
- if (k_del_rg(st->st_origin, gt) < 0) {
- log(LOG_WARNING, errno, "%s (%s, %s)",
- "steal_sources trying to delete",
- inet_fmt(st->st_origin, s1),
- inet_fmt(gt->gt_mcastgrp, s2));
- }
- *stnp = st->st_next;
- kroutes--;
- free(st);
- } else {
- stnp = &st->st_next;
- }
- }
- }
- }
- }
-
- gtnp = &kernel_no_route;
- while ((gt = *gtnp) != NULL) {
- if (gt->gt_srctbl && ((gt->gt_srctbl->st_origin & rt->rt_originmask)
- == rt->rt_origin)) {
- log(LOG_DEBUG, 0, "%s stealing (%s %s) from %s",
- inet_fmts(rt->rt_origin, rt->rt_originmask, s1),
- inet_fmt(gt->gt_srctbl->st_origin, s3),
- inet_fmt(gt->gt_mcastgrp, s4),
- "no_route table");
- if (k_del_rg(gt->gt_srctbl->st_origin, gt) < 0) {
- log(LOG_WARNING, errno, "%s (%s %s)",
- "steal_sources trying to delete",
- inet_fmt(gt->gt_srctbl->st_origin, s1),
- inet_fmt(gt->gt_mcastgrp, s2));
- }
- kroutes--;
- free(gt->gt_srctbl);
- *gtnp = gt->gt_next;
- if (gt->gt_next)
- gt->gt_next->gt_prev = gt->gt_prev;
- free(gt);
- } else {
- gtnp = &gt->gt_next;
- }
- }
-}
-
-/*
- * Advance the timers on all the cache entries.
- * If there are any entries whose timers have expired,
- * remove these entries from the kernel cache.
- */
-void
-age_table_entry()
-{
- struct rtentry *r;
- struct gtable *gt, **gtnptr;
- struct stable *st, **stnp;
- struct ptable *pt, **ptnp;
- struct sioc_sg_req sg_req;
-
- log(LOG_DEBUG, 0, "ageing entries");
-
- gtnptr = &kernel_table;
- while ((gt = *gtnptr) != NULL) {
- r = gt->gt_route;
-
- /* advance the timer for the kernel entry */
- gt->gt_timer -= ROUTE_MAX_REPORT_DELAY;
-
- /* decrement prune timer if need be */
- if (gt->gt_prsent_timer > 0) {
- gt->gt_prsent_timer -= ROUTE_MAX_REPORT_DELAY;
- if (gt->gt_prsent_timer <= 0) {
- log(LOG_DEBUG, 0, "upstream prune tmo (%s %s)",
- inet_fmts(r->rt_origin, r->rt_originmask, s1),
- inet_fmt(gt->gt_mcastgrp, s2));
- gt->gt_prsent_timer = -1;
- }
- }
-
- /* retransmit graft if graft sent flag is still set */
- if (gt->gt_grftsnt) {
- register int y;
- CHK_GS(gt->gt_grftsnt++, y);
- if (y)
- send_graft(gt);
- }
-
- /*
- * Age prunes
- *
- * If a prune expires, forward again on that vif.
- */
- ptnp = &gt->gt_pruntbl;
- while ((pt = *ptnp) != NULL) {
- if ((pt->pt_timer -= ROUTE_MAX_REPORT_DELAY) <= 0) {
- log(LOG_DEBUG, 0, "expire prune (%s %s) from %s on vif %d",
- inet_fmts(r->rt_origin, r->rt_originmask, s1),
- inet_fmt(gt->gt_mcastgrp, s2),
- inet_fmt(pt->pt_router, s3),
- pt->pt_vifi);
-
- expire_prune(pt->pt_vifi, gt);
-
- /* remove the router's prune entry and await new one */
- *ptnp = pt->pt_next;
- free(pt);
- } else {
- ptnp = &pt->pt_next;
- }
- }
-
- /*
- * If the cache entry has expired, delete source table entries for
- * silent sources. If there are no source entries left, and there
- * are no downstream prunes, then the entry is deleted.
- * Otherwise, the cache entry's timer is refreshed.
- */
- if (gt->gt_timer <= 0) {
- /* Check for traffic before deleting source entries */
- sg_req.grp.s_addr = gt->gt_mcastgrp;
- stnp = &gt->gt_srctbl;
- while ((st = *stnp) != NULL) {
- sg_req.src.s_addr = st->st_origin;
- if (ioctl(udp_socket, SIOCGETSGCNT, (char *)&sg_req) < 0) {
- log(LOG_WARNING, errno, "%s (%s %s)",
- "age_table_entry: SIOCGETSGCNT failing for",
- inet_fmt(st->st_origin, s1),
- inet_fmt(gt->gt_mcastgrp, s2));
- /* Make sure it gets deleted below */
- sg_req.pktcnt = st->st_pktcnt;
- }
- if (sg_req.pktcnt == st->st_pktcnt) {
- *stnp = st->st_next;
- log(LOG_DEBUG, 0, "age_table_entry deleting (%s %s)",
- inet_fmt(st->st_origin, s1),
- inet_fmt(gt->gt_mcastgrp, s2));
- if (k_del_rg(st->st_origin, gt) < 0) {
- log(LOG_WARNING, errno,
- "age_table_entry trying to delete (%s %s)",
- inet_fmt(st->st_origin, s1),
- inet_fmt(gt->gt_mcastgrp, s2));
- }
- kroutes--;
- free(st);
- } else {
- st->st_pktcnt = sg_req.pktcnt;
- stnp = &st->st_next;
- }
- }
-
- /*
- * Retain the group entry if we have downstream prunes or if
- * there is at least one source in the list that still has
- * traffic, or if our upstream prune timer is running.
- */
- if (gt->gt_pruntbl != NULL || gt->gt_srctbl != NULL ||
- gt->gt_prsent_timer > 0) {
- gt->gt_timer = CACHE_LIFETIME(cache_lifetime);
- if (gt->gt_prsent_timer == -1)
- if (gt->gt_grpmems == 0)
- send_prune(gt);
- else
- gt->gt_prsent_timer = 0;
- gtnptr = &gt->gt_gnext;
- continue;
- }
-
- log(LOG_DEBUG, 0, "timeout cache entry (%s, %s)",
- inet_fmts(r->rt_origin, r->rt_originmask, s1),
- inet_fmt(gt->gt_mcastgrp, s2));
-
- if (gt->gt_prev)
- gt->gt_prev->gt_next = gt->gt_next;
- else
- gt->gt_route->rt_groups = gt->gt_next;
- if (gt->gt_next)
- gt->gt_next->gt_prev = gt->gt_prev;
-
- if (gt->gt_gprev) {
- gt->gt_gprev->gt_gnext = gt->gt_gnext;
- gtnptr = &gt->gt_gprev->gt_gnext;
- } else {
- kernel_table = gt->gt_gnext;
- gtnptr = &kernel_table;
- }
- if (gt->gt_gnext)
- gt->gt_gnext->gt_gprev = gt->gt_gprev;
-
-#ifdef RSRR
- /* Send route change notification to reservation protocol. */
- rsrr_cache_send(gt,0);
- rsrr_cache_clean(gt);
-#endif /* RSRR */
- free((char *)gt);
- } else {
- if (gt->gt_prsent_timer == -1)
- if (gt->gt_grpmems == 0)
- send_prune(gt);
- else
- gt->gt_prsent_timer = 0;
- gtnptr = &gt->gt_gnext;
- }
- }
-
- /*
- * When traversing the no_route table, the decision is much easier.
- * Just delete it if it has timed out.
- */
- gtnptr = &kernel_no_route;
- while ((gt = *gtnptr) != NULL) {
- /* advance the timer for the kernel entry */
- gt->gt_timer -= ROUTE_MAX_REPORT_DELAY;
-
- if (gt->gt_timer < 0) {
- if (gt->gt_srctbl) {
- if (k_del_rg(gt->gt_srctbl->st_origin, gt) < 0) {
- log(LOG_WARNING, errno, "%s (%s %s)",
- "age_table_entry trying to delete no-route",
- inet_fmt(gt->gt_srctbl->st_origin, s1),
- inet_fmt(gt->gt_mcastgrp, s2));
- }
- free(gt->gt_srctbl);
- }
- *gtnptr = gt->gt_next;
- if (gt->gt_next)
- gt->gt_next->gt_prev = gt->gt_prev;
-
- free((char *)gt);
- } else {
- gtnptr = &gt->gt_next;
- }
- }
-}
-
-/*
- * Modify the kernel to forward packets when one or multiple prunes that
- * were received on the vif given by vifi, for the group given by gt,
- * have expired.
- */
-static void
-expire_prune(vifi, gt)
- vifi_t vifi;
- struct gtable *gt;
-{
- /*
- * No need to send a graft, any prunes that we sent
- * will expire before any prunes that we have received.
- */
- if (gt->gt_prsent_timer > 0) {
- log(LOG_DEBUG, 0, "prune expired with %d left on %s",
- gt->gt_prsent_timer, "prsent_timer");
- gt->gt_prsent_timer = 0;
- }
-
- /* modify the kernel entry to forward packets */
- if (!VIFM_ISSET(vifi, gt->gt_grpmems)) {
- struct rtentry *rt = gt->gt_route;
- VIFM_SET(vifi, gt->gt_grpmems);
- log(LOG_DEBUG, 0, "forw again (%s %s) gm:%x vif:%d",
- inet_fmts(rt->rt_origin, rt->rt_originmask, s1),
- inet_fmt(gt->gt_mcastgrp, s2), gt->gt_grpmems, vifi);
-
- prun_add_ttls(gt);
- update_kernel(gt);
-#ifdef RSRR
- /* Send route change notification to reservation protocol. */
- rsrr_cache_send(gt,1);
-#endif /* RSRR */
- }
-}
-
-
-static char *
-scaletime(t)
- u_long t;
-{
- static char buf1[5];
- static char buf2[5];
- static char *buf=buf1;
- char s;
- char *p;
-
- p = buf;
- if (buf == buf1)
- buf = buf2;
- else
- buf = buf1;
-
- if (t < 120) {
- s = 's';
- } else if (t < 3600) {
- t /= 60;
- s = 'm';
- } else if (t < 86400) {
- t /= 3600;
- s = 'h';
- } else if (t < 864000) {
- t /= 86400;
- s = 'd';
- } else {
- t /= 604800;
- s = 'w';
- }
- if (t > 999)
- return "*** ";
-
- sprintf(p,"%3d%c", (int)t, s);
-
- return p;
-}
-
-/*
- * Print the contents of the cache table on file 'fp2'.
- */
-void
-dump_cache(fp2)
- FILE *fp2;
-{
- register struct rtentry *r;
- register struct gtable *gt;
- register struct stable *st;
- register struct ptable *pt;
- register vifi_t i;
- register time_t thyme = time(0);
-
- fprintf(fp2,
- "Multicast Routing Cache Table (%d entries)\n%s", kroutes,
- " Origin Mcast-group CTmr Age Ptmr IVif Forwvifs\n");
-
- for (gt = kernel_no_route; gt; gt = gt->gt_next) {
- if (gt->gt_srctbl) {
- fprintf(fp2, " %-18s %-15s %-4s %-4s - -1\n",
- inet_fmts(gt->gt_srctbl->st_origin, 0xffffffff, s1),
- inet_fmt(gt->gt_mcastgrp, s2), scaletime(gt->gt_timer),
- scaletime(thyme - gt->gt_ctime));
- fprintf(fp2, ">%s\n", inet_fmt(gt->gt_srctbl->st_origin, s1));
- }
- }
-
- for (gt = kernel_table; gt; gt = gt->gt_gnext) {
- r = gt->gt_route;
- fprintf(fp2, " %-18s %-15s",
- inet_fmts(r->rt_origin, r->rt_originmask, s1),
- inet_fmt(gt->gt_mcastgrp, s2));
-
- fprintf(fp2, " %-4s", scaletime(gt->gt_timer));
-
- fprintf(fp2, " %-4s %-4s ", scaletime(thyme - gt->gt_ctime),
- gt->gt_prsent_timer ? scaletime(gt->gt_prsent_timer) :
- " -");
-
- fprintf(fp2, "%2u%c%c ", r->rt_parent,
- gt->gt_prsent_timer ? 'P' : ' ',
- VIFM_ISSET(r->rt_parent, gt->gt_scope) ? 'B' : ' ');
-
- for (i = 0; i < numvifs; ++i) {
- if (VIFM_ISSET(i, gt->gt_grpmems))
- fprintf(fp2, " %u ", i);
- else if (VIFM_ISSET(i, r->rt_children) &&
- !VIFM_ISSET(i, r->rt_leaves))
- fprintf(fp2, " %u%c", i,
- VIFM_ISSET(i, gt->gt_scope) ? 'b' : 'p');
- }
- fprintf(fp2, "\n");
- for (st = gt->gt_srctbl; st; st = st->st_next) {
- fprintf(fp2, ">%s\n", inet_fmt(st->st_origin, s1));
- }
-#ifdef DEBUG_PRUNES
- for (pt = gt->gt_pruntbl; pt; pt = pt->pt_next) {
- fprintf(fp2, "<r:%s v:%d t:%d\n", inet_fmt(pt->pt_router, s1),
- pt->pt_vifi, pt->pt_timer);
- }
-#endif
- }
-}
-
-/*
- * Traceroute function which returns traceroute replies to the requesting
- * router. Also forwards the request to downstream routers.
- */
-void
-accept_mtrace(src, dst, group, data, no, datalen)
- u_int32 src;
- u_int32 dst;
- u_int32 group;
- char *data;
- u_int no; /* promoted u_char */
- int datalen;
-{
- u_char type;
- struct rtentry *rt;
- struct gtable *gt;
- struct tr_query *qry;
- struct tr_resp *resp;
- int vifi;
- char *p;
- int rcount;
- int errcode = TR_NO_ERR;
- int resptype;
- struct timeval tp;
- struct sioc_vif_req v_req;
- struct sioc_sg_req sg_req;
-
- /* 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;
- log(LOG_DEBUG, 0, "Initial traceroute query rcvd from %s to %s",
- inet_fmt(src, s1), inet_fmt(dst, s2));
- }
- else if ((datalen - QLEN) % RLEN == 0) {
- type = RESP;
- log(LOG_DEBUG, 0, "In-transit traceroute query rcvd from %s to %s",
- inet_fmt(src, s1), inet_fmt(dst, s2));
- if (IN_MULTICAST(ntohl(dst))) {
- log(LOG_DEBUG, 0, "Dropping multicast response");
- return;
- }
- }
- else {
- log(LOG_WARNING, 0, "%s from %s to %s",
- "Non decipherable traceroute request recieved",
- inet_fmt(src, s1), inet_fmt(dst, s2));
- return;
- }
-
- qry = (struct tr_query *)data;
-
- /*
- * if it is a packet with all reports filled, drop it
- */
- if ((rcount = (datalen - QLEN)/RLEN) == no) {
- log(LOG_DEBUG, 0, "packet with all reports filled in");
- return;
- }
-
- log(LOG_DEBUG, 0, "s: %s g: %s d: %s ", inet_fmt(qry->tr_src, s1),
- inet_fmt(group, s2), inet_fmt(qry->tr_dst, s3));
- log(LOG_DEBUG, 0, "rttl: %d rd: %s", qry->tr_rttl,
- inet_fmt(qry->tr_raddr, s1));
- log(LOG_DEBUG, 0, "rcount:%d, qid:%06x", rcount, qry->tr_qid);
-
- /* determine the routing table entry for this traceroute */
- rt = determine_route(qry->tr_src);
- if (rt) {
- log(LOG_DEBUG, 0, "rt parent vif: %d rtr: %s metric: %d",
- rt->rt_parent, inet_fmt(rt->rt_gateway, s1), rt->rt_metric);
- log(LOG_DEBUG, 0, "rt origin %s",
- inet_fmts(rt->rt_origin, rt->rt_originmask, 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.
- */
- log(LOG_DEBUG, 0, "ignoring duplicate traceroute packet");
- return;
- }
-
- if (rt == NULL) {
- log(LOG_DEBUG, 0, "Mcast traceroute: no route entry %s",
- inet_fmt(qry->tr_src, s1));
- if (IN_MULTICAST(ntohl(dst)))
- return;
- }
- vifi = find_vif(qry->tr_dst, 0);
-
- if (vifi == NO_VIF) {
- /* The traceroute destination is not on one of my subnet vifs. */
- log(LOG_DEBUG, 0, "Destination %s not an interface",
- inet_fmt(qry->tr_dst, s1));
- if (IN_MULTICAST(ntohl(dst)))
- return;
- errcode = TR_WRONG_IF;
- } else if (rt != NULL && !VIFM_ISSET(vifi, rt->rt_children)) {
- log(LOG_DEBUG, 0, "Destination %s not on forwarding tree for src %s",
- inet_fmt(qry->tr_dst, s1), inet_fmt(qry->tr_src, s2));
- if (IN_MULTICAST(ntohl(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(src, dst)) == NO_VIF) {
- 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;
-
- log(LOG_DEBUG, 0, "Sending traceroute response");
-
- /* copy the packet to the sending buffer */
- p = send_buf + MIN_IP_HEADER_LEN + IGMP_MINLEN;
-
- 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 tr_resp) > send_buf + RECV_BUF_SIZE) {
- resp = (struct tr_resp *)p - 1;
- resp->tr_rflags = TR_NO_SPACE;
- rt = NULL;
- goto sendit;
- }
-
- /*
- * fill in initial response fields
- */
- resp = (struct tr_resp *)p;
- bzero(resp, sizeof(struct tr_resp));
- datalen += RLEN;
-
- resp->tr_qarr = htonl((tp.tv_sec + JAN_1970) << 16) +
- ((tp.tv_usec >> 4) & 0xffff);
-
- resp->tr_rproto = PROTO_DVMRP;
- if (errcode != TR_NO_ERR) {
- resp->tr_rflags = errcode;
- rt = NULL; /* hack to enforce send straight to requestor */
- goto sendit;
- }
- resp->tr_outaddr = uvifs[vifi].uv_lcl_addr;
- resp->tr_fttl = uvifs[vifi].uv_threshold;
- resp->tr_rflags = TR_NO_ERR;
-
- /*
- * obtain # of packets out on interface
- */
- v_req.vifi = vifi;
- if (ioctl(udp_socket, SIOCGETVIFCNT, (char *)&v_req) >= 0)
- resp->tr_vifout = htonl(v_req.ocount);
-
- /*
- * fill in scoping & pruning information
- */
- if (rt)
- 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) {
- sg_req.src.s_addr = qry->tr_src;
- sg_req.grp.s_addr = group;
- if (ioctl(udp_socket, SIOCGETSGCNT, (char *)&sg_req) >= 0)
- resp->tr_pktcnt = htonl(sg_req.pktcnt);
-
- 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) &&
- !VIFM_ISSET(vifi, rt->rt_leaves))
- 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;
- }
-
- /*
- * if no rte exists, set NO_RTE error
- */
- if (rt == NULL) {
- src = dst; /* the dst address of resp. pkt */
- resp->tr_inaddr = 0;
- resp->tr_rflags = TR_NO_RTE;
- resp->tr_rmtaddr = 0;
- } else {
- /* get # of packets in on interface */
- v_req.vifi = rt->rt_parent;
- if (ioctl(udp_socket, SIOCGETVIFCNT, (char *)&v_req) >= 0)
- resp->tr_vifin = htonl(v_req.icount);
-
- MASK_TO_VAL(rt->rt_originmask, resp->tr_smask);
- src = uvifs[rt->rt_parent].uv_lcl_addr;
- resp->tr_inaddr = src;
- resp->tr_rmtaddr = rt->rt_gateway;
- if (!VIFM_ISSET(vifi, rt->rt_children)) {
- log(LOG_DEBUG, 0, "Destination %s not on forwarding tree for src %s",
- inet_fmt(qry->tr_dst, s1), inet_fmt(qry->tr_src, s2));
- resp->tr_rflags = TR_WRONG_IF;
- }
- if (rt->rt_metric >= UNREACHABLE) {
- resp->tr_rflags = TR_NO_RTE;
- /* Hack to send reply directly */
- rt = NULL;
- }
- }
-
-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.
- */
- log(LOG_DEBUG, 0, "rcount:%d, no:%d", rcount, no);
-
- if ((rcount + 1 == no) || (rt == NULL) || (rt->rt_metric == 1)) {
- resptype = IGMP_MTRACE_RESP;
- dst = qry->tr_raddr;
- } else
- if (!can_mtrace(rt->rt_parent, rt->rt_gateway)) {
- dst = qry->tr_raddr;
- resp->tr_rflags = TR_OLD_ROUTER;
- resptype = IGMP_MTRACE_RESP;
- } else {
- dst = rt->rt_gateway;
- resptype = IGMP_MTRACE;
- }
-
- if (IN_MULTICAST(ntohl(dst))) {
- /*
- * Send the reply on a known multicast capable vif.
- * If we don't have one, we can't source any multicasts anyway.
- */
- if (phys_vif != -1) {
- log(LOG_DEBUG, 0, "Sending reply to %s from %s",
- inet_fmt(dst, s1), inet_fmt(uvifs[phys_vif].uv_lcl_addr, s2));
- k_set_ttl(qry->tr_rttl);
- send_igmp(uvifs[phys_vif].uv_lcl_addr, dst,
- resptype, no, group,
- datalen);
- k_set_ttl(1);
- } else
- log(LOG_INFO, 0, "No enabled phyints -- %s",
- "dropping traceroute reply");
- } else {
- log(LOG_DEBUG, 0, "Sending %s to %s from %s",
- resptype == IGMP_MTRACE_RESP ? "reply" : "request on",
- inet_fmt(dst, s1), inet_fmt(src, s2));
-
- send_igmp(src, dst,
- resptype, no, group,
- datalen);
- }
- return;
-}
diff --git a/usr.sbin/mrouted/prune.h b/usr.sbin/mrouted/prune.h
deleted file mode 100644
index 57ae067ce74f..000000000000
--- a/usr.sbin/mrouted/prune.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * The mrouted program is covered by the license in the accompanying file
- * named "LICENSE". 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.
- *
- *
- * $Id: prune.h,v 3.8 1995/11/29 22:36:57 fenner Rel $
- */
-
-/*
- * Group table
- *
- * Each group entry is a member of two doubly-linked lists:
- *
- * a) A list hanging off of the routing table entry for this source (rt_groups)
- * sorted by group address under the routing entry (gt_next, gt_prev)
- * b) An independent list pointed to by kernel_table, which is a list of
- * active source,group's (gt_gnext, gt_gprev).
- *
- */
-struct gtable {
- struct gtable *gt_next; /* pointer to the next entry */
- struct gtable *gt_prev; /* back pointer for linked list */
- struct gtable *gt_gnext; /* fwd pointer for group list */
- struct gtable *gt_gprev; /* rev pointer for group list */
- u_int32 gt_mcastgrp; /* multicast group associated */
- vifbitmap_t gt_scope; /* scoped interfaces */
- u_char gt_ttls[MAXVIFS]; /* ttl vector for forwarding */
- vifbitmap_t gt_grpmems; /* forw. vifs for src, grp */
- int gt_prsent_timer; /* prune timer for this group */
- int gt_timer; /* timer for this group entry */
- time_t gt_ctime; /* time of entry creation */
- u_char gt_grftsnt; /* graft sent/retransmit timer */
- struct stable *gt_srctbl; /* source table */
- struct ptable *gt_pruntbl; /* prune table */
- struct rtentry *gt_route; /* parent route */
-#ifdef RSRR
- struct rsrr_cache *gt_rsrr_cache; /* RSRR cache */
-#endif /* RSRR */
-};
-
-/*
- * Source table
- *
- * When source-based prunes exist, there will be a struct ptable here as well.
- */
-struct stable
-{
- struct stable *st_next; /* pointer to the next entry */
- u_int32 st_origin; /* host origin of multicasts */
- u_long st_pktcnt; /* packet count for src-grp entry */
-};
-
-/*
- * structure to store incoming prunes. Can hang off of either group or source.
- */
-struct ptable
-{
- struct ptable *pt_next; /* pointer to the next entry */
- u_int32 pt_router; /* router that sent this prune */
- vifi_t pt_vifi; /* vif prune received on */
- int pt_timer; /* timer for prune */
-};
-
-/*
- * The packet format for a traceroute request.
- */
-struct tr_query {
- u_int32 tr_src; /* traceroute source */
- u_int32 tr_dst; /* traceroute destination */
- u_int32 tr_raddr; /* traceroute response address */
-#if defined(BYTE_ORDER) && (BYTE_ORDER == LITTLE_ENDIAN)
- struct {
- u_int qid : 24; /* traceroute query id */
- u_int ttl : 8; /* traceroute response ttl */
- } q;
-#else
- struct {
- u_int ttl : 8; /* traceroute response ttl */
- u_int qid : 24; /* traceroute query id */
- } q;
-#endif /* BYTE_ORDER */
-};
-
-#define tr_rttl q.ttl
-#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 tr_resp {
- u_int32 tr_qarr; /* query arrival time */
- u_int32 tr_inaddr; /* incoming interface address */
- u_int32 tr_outaddr; /* outgoing interface address */
- u_int32 tr_rmtaddr; /* parent address in source tree */
- u_int32 tr_vifin; /* input packet count on interface */
- u_int32 tr_vifout; /* output packet count on interface */
- u_int32 tr_pktcnt; /* total incoming packets for src-grp */
- u_char tr_rproto; /* routing protocol deployed on router */
- u_char tr_fttl; /* ttl required to forward on outvif */
- u_char tr_smask; /* subnet mask for src addr */
- u_char tr_rflags; /* forwarding error codes */
-};
-
-/* defs within mtrace */
-#define QUERY 1
-#define RESP 2
-#define QLEN sizeof(struct tr_query)
-#define RLEN sizeof(struct tr_resp)
-
-/* fields for tr_rflags (forwarding error codes) */
-#define TR_NO_ERR 0
-#define TR_WRONG_IF 1
-#define TR_PRUNED 2
-#define TR_OPRUNED 3
-#define TR_SCOPED 4
-#define TR_NO_RTE 5
-#define TR_NO_FWD 7
-#define TR_NO_SPACE 0x81
-#define TR_OLD_ROUTER 0x82
-
-/* fields for tr_rproto (routing protocol) */
-#define PROTO_DVMRP 1
-#define PROTO_MOSPF 2
-#define PROTO_PIM 3
-#define PROTO_CBT 4
-
-#define MASK_TO_VAL(x, i) { \
- u_int32 _x = ntohl(x); \
- (i) = 1; \
- while ((_x) <<= 1) \
- (i)++; \
- };
-
-#define VAL_TO_MASK(x, i) { \
- x = htonl(~((1 << (32 - (i))) - 1)); \
- };
-
-#define NBR_VERS(n) (((n)->al_pv << 8) + (n)->al_mv)
diff --git a/usr.sbin/mrouted/route.c b/usr.sbin/mrouted/route.c
deleted file mode 100644
index c2b6b9e8b932..000000000000
--- a/usr.sbin/mrouted/route.c
+++ /dev/null
@@ -1,1162 +0,0 @@
-/*
- * The mrouted program is covered by the license in the accompanying file
- * named "LICENSE". 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.
- *
- *
- * $Id: route.c,v 3.8 1995/11/29 22:36:57 fenner Rel $
- */
-
-
-#include "defs.h"
-
-
-/*
- * This define statement saves a lot of space later
- */
-#define RT_ADDR (struct rtentry *)&routing_table
-
-/*
- * Exported variables.
- */
-int routes_changed; /* 1=>some routes have changed */
-int delay_change_reports; /* 1=>postpone change reports */
-
-
-/*
- * The routing table is shared with prune.c , so must not be static.
- */
-struct rtentry *routing_table; /* pointer to list of route entries */
-
-/*
- * Private variables.
- */
-static struct rtentry *rtp; /* pointer to a route entry */
-static struct rtentry *rt_end; /* pointer to last route entry */
-unsigned int nroutes; /* current number of route entries */
-
-/*
- * Private functions.
- */
-static int init_children_and_leaves __P((struct rtentry *r,
- vifi_t parent));
-static int find_route __P((u_int32 origin, u_int32 mask));
-static void create_route __P((u_int32 origin, u_int32 mask));
-static void discard_route __P((struct rtentry *prev_r));
-static int compare_rts __P((const void *rt1, const void *rt2));
-static int report_chunk __P((struct rtentry *start_rt, vifi_t vifi,
- u_int32 dst));
-
-/*
- * Initialize the routing table and associated variables.
- */
-void
-init_routes()
-{
- routing_table = NULL;
- rt_end = RT_ADDR;
- nroutes = 0;
- routes_changed = FALSE;
- delay_change_reports = FALSE;
-}
-
-
-/*
- * Initialize the children and leaf bits for route 'r', along with the
- * associated dominant, subordinate, and leaf timing data structures.
- * Return TRUE if this changes the value of either the children or
- * leaf bitmaps for 'r'.
- */
-static int
-init_children_and_leaves(r, parent)
- register struct rtentry *r;
- register vifi_t parent;
-{
- register vifi_t vifi;
- register struct uvif *v;
- vifbitmap_t old_children, old_leaves;
-
- VIFM_COPY(r->rt_children, old_children);
- VIFM_COPY(r->rt_leaves, old_leaves );
-
- VIFM_CLRALL(r->rt_children);
- VIFM_CLRALL(r->rt_leaves);
- r->rt_flags &= ~RTF_LEAF_TIMING;
-
- for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
- r->rt_dominants [vifi] = 0;
- r->rt_subordinates[vifi] = 0;
-
- if (vifi != parent && !(v->uv_flags & (VIFF_DOWN|VIFF_DISABLED))) {
- VIFM_SET(vifi, r->rt_children);
- if (v->uv_neighbors == NULL) {
- VIFM_SET(vifi, r->rt_leaves);
- r->rt_leaf_timers[vifi] = 0;
- }
- else {
- r->rt_leaf_timers[vifi] = LEAF_CONFIRMATION_TIME;
- r->rt_flags |= RTF_LEAF_TIMING;
- }
- }
- else {
- r->rt_leaf_timers[vifi] = 0;
- }
- }
-
- return (!VIFM_SAME(r->rt_children, old_children) ||
- !VIFM_SAME(r->rt_leaves, old_leaves));
-}
-
-
-/*
- * A new vif has come up -- update the children and leaf bitmaps in all route
- * entries to take that into account.
- */
-void
-add_vif_to_routes(vifi)
- register vifi_t vifi;
-{
- register struct rtentry *r;
- register struct uvif *v;
-
- v = &uvifs[vifi];
- for (r = routing_table; r != NULL; r = r->rt_next) {
- if (r->rt_metric != UNREACHABLE &&
- !VIFM_ISSET(vifi, r->rt_children)) {
- VIFM_SET(vifi, r->rt_children);
- r->rt_dominants [vifi] = 0;
- r->rt_subordinates[vifi] = 0;
- if (v->uv_neighbors == NULL) {
- VIFM_SET(vifi, r->rt_leaves);
- r->rt_leaf_timers[vifi] = 0;
- }
- else {
- VIFM_CLR(vifi, r->rt_leaves);
- r->rt_leaf_timers[vifi] = LEAF_CONFIRMATION_TIME;
- r->rt_flags |= RTF_LEAF_TIMING;
- }
- update_table_entry(r);
- }
- }
-}
-
-
-/*
- * A vif has gone down -- expire all routes that have that vif as parent,
- * and update the children bitmaps in all other route entries to take into
- * account the failed vif.
- */
-void
-delete_vif_from_routes(vifi)
- register vifi_t vifi;
-{
- register struct rtentry *r;
-
- for (r = routing_table; r != NULL; r = r->rt_next) {
- if (r->rt_metric != UNREACHABLE) {
- if (vifi == r->rt_parent) {
- del_table_entry(r, 0, DEL_ALL_ROUTES);
- r->rt_timer = ROUTE_EXPIRE_TIME;
- r->rt_metric = UNREACHABLE;
- r->rt_flags |= RTF_CHANGED;
- routes_changed = TRUE;
- }
- else if (VIFM_ISSET(vifi, r->rt_children)) {
- VIFM_CLR(vifi, r->rt_children);
- VIFM_CLR(vifi, r->rt_leaves);
- r->rt_subordinates[vifi] = 0;
- r->rt_leaf_timers [vifi] = 0;
- update_table_entry(r);
- }
- else {
- r->rt_dominants[vifi] = 0;
- }
- }
- }
-}
-
-
-/*
- * A neighbor has failed or become unreachable. If that neighbor was
- * considered a dominant or subordinate router in any route entries,
- * take appropriate action.
- */
-void
-delete_neighbor_from_routes(addr, vifi)
- register u_int32 addr;
- register vifi_t vifi;
-{
- register struct rtentry *r;
- register struct uvif *v;
-
- v = &uvifs[vifi];
- for (r = routing_table; r != NULL; r = r->rt_next) {
- if (r->rt_metric != UNREACHABLE) {
- if (r->rt_dominants[vifi] == addr) {
- VIFM_SET(vifi, r->rt_children);
- r->rt_dominants [vifi] = 0;
- r->rt_subordinates[vifi] = 0;
- if (v->uv_neighbors == NULL) {
- VIFM_SET(vifi, r->rt_leaves);
- r->rt_leaf_timers[vifi] = 0;
- }
- else {
- VIFM_CLR(vifi, r->rt_leaves);
- r->rt_leaf_timers[vifi] = LEAF_CONFIRMATION_TIME;
- r->rt_flags |= RTF_LEAF_TIMING;
- }
- update_table_entry(r);
- }
- else if (r->rt_subordinates[vifi] == addr) {
- r->rt_subordinates[vifi] = 0;
- if (v->uv_neighbors == NULL) {
- VIFM_SET(vifi, r->rt_leaves);
- update_table_entry(r);
- }
- else {
- r->rt_leaf_timers[vifi] = LEAF_CONFIRMATION_TIME;
- r->rt_flags |= RTF_LEAF_TIMING;
- }
- }
- else if (v->uv_neighbors == NULL &&
- r->rt_leaf_timers[vifi] != 0) {
- VIFM_SET(vifi, r->rt_leaves);
- r->rt_leaf_timers[vifi] = 0;
- update_table_entry(r);
- }
- }
- }
-}
-
-
-/*
- * Prepare for a sequence of ordered route updates by initializing a pointer
- * to the start of the routing table. The pointer is used to remember our
- * position in the routing table in order to avoid searching from the
- * beginning for each update; this relies on having the route reports in
- * a single message be in the same order as the route entries in the routing
- * table.
- */
-void
-start_route_updates()
-{
- rtp = RT_ADDR;
-}
-
-
-/*
- * Starting at the route entry following the one to which 'rtp' points,
- * look for a route entry matching the specified origin and mask. If a
- * match is found, return TRUE and leave 'rtp' pointing at the found entry.
- * If no match is found, return FALSE and leave 'rtp' pointing to the route
- * entry preceding the point at which the new origin should be inserted.
- * This code is optimized for the normal case in which the first entry to
- * be examined is the matching entry.
- */
-static int
-find_route(origin, mask)
- register u_int32 origin, mask;
-{
- register struct rtentry *r;
-
- r = rtp->rt_next;
- while (r != NULL) {
- if (origin == r->rt_origin && mask == r->rt_originmask) {
- rtp = r;
- return (TRUE);
- }
- if (ntohl(mask) < ntohl(r->rt_originmask) ||
- (mask == r->rt_originmask &&
- ntohl(origin) < ntohl(r->rt_origin))) {
- rtp = r;
- r = r->rt_next;
- }
- else break;
- }
- return (FALSE);
-}
-
-/*
- * Create a new routing table entry for the specified origin and link it into
- * the routing table. The shared variable 'rtp' is assumed to point to the
- * routing entry after which the new one should be inserted. It is left
- * pointing to the new entry.
- *
- * Only the origin, originmask, originwidth and flags fields are initialized
- * in the new route entry; the caller is responsible for filling in the the
- * rest.
- */
-static void
-create_route(origin, mask)
- u_int32 origin, mask;
-{
- register struct rtentry *r;
-
- if ((r = (struct rtentry *) malloc(sizeof(struct rtentry) +
- (2 * numvifs * sizeof(u_int32)) +
- (numvifs * sizeof(u_int)))) == NULL) {
- log(LOG_ERR, 0, "ran out of memory"); /* fatal */
- }
- r->rt_origin = origin;
- r->rt_originmask = mask;
- if (((char *)&mask)[3] != 0) r->rt_originwidth = 4;
- else if (((char *)&mask)[2] != 0) r->rt_originwidth = 3;
- else if (((char *)&mask)[1] != 0) r->rt_originwidth = 2;
- else r->rt_originwidth = 1;
- r->rt_flags = 0;
- r->rt_dominants = (u_int32 *)(r + 1);
- r->rt_subordinates = (u_int32 *)(r->rt_dominants + numvifs);
- r->rt_leaf_timers = (u_int *)(r->rt_subordinates + numvifs);
- r->rt_groups = NULL;
-
- r->rt_next = rtp->rt_next;
- rtp->rt_next = r;
- r->rt_prev = rtp;
- if (r->rt_next != NULL)
- (r->rt_next)->rt_prev = r;
- else
- rt_end = r;
- rtp = r;
- ++nroutes;
-}
-
-
-/*
- * Discard the routing table entry following the one to which 'prev_r' points.
- */
-static void
-discard_route(prev_r)
- register struct rtentry *prev_r;
-{
- register struct rtentry *r;
-
- r = prev_r->rt_next;
- prev_r->rt_next = r->rt_next;
- if (prev_r->rt_next != NULL)
- (prev_r->rt_next)->rt_prev = prev_r;
- else
- rt_end = prev_r;
- free((char *)r);
- --nroutes;
-}
-
-
-/*
- * Process a route report for a single origin, creating or updating the
- * corresponding routing table entry if necessary. 'src' is either the
- * address of a neighboring router from which the report arrived, or zero
- * to indicate a change of status of one of our own interfaces.
- */
-void
-update_route(origin, mask, metric, src, vifi)
- u_int32 origin, mask;
- u_int metric;
- u_int32 src;
- vifi_t vifi;
-{
- register struct rtentry *r;
- u_int adj_metric;
-
- /*
- * Compute an adjusted metric, taking into account the cost of the
- * subnet or tunnel over which the report arrived, and normalizing
- * all unreachable/poisoned metrics into a single value.
- */
- if (src != 0 && (metric < 1 || metric >= 2*UNREACHABLE)) {
- log(LOG_WARNING, 0,
- "%s reports out-of-range metric %u for origin %s",
- inet_fmt(src, s1), metric, inet_fmts(origin, mask, s2));
- return;
- }
- adj_metric = metric + uvifs[vifi].uv_metric;
- if (adj_metric > UNREACHABLE) adj_metric = UNREACHABLE;
-
- /*
- * Look up the reported origin in the routing table.
- */
- if (!find_route(origin, mask)) {
- /*
- * Not found.
- * Don't create a new entry if the report says it's unreachable,
- * or if the reported origin and mask are invalid.
- */
- if (adj_metric == UNREACHABLE) {
- return;
- }
- if (src != 0 && !inet_valid_subnet(origin, mask)) {
- log(LOG_WARNING, 0,
- "%s reports an invalid origin (%s) and/or mask (%08x)",
- inet_fmt(src, s1), inet_fmt(origin, s2), ntohl(mask));
- return;
- }
-
- /*
- * OK, create the new routing entry. 'rtp' will be left pointing
- * to the new entry.
- */
- create_route(origin, mask);
-
- /*
- * Now "steal away" any sources that belong under this route
- * by deleting any cache entries they might have created
- * and allowing the kernel to re-request them.
- */
- steal_sources(rtp);
-
- rtp->rt_metric = UNREACHABLE; /* temporary; updated below */
- }
-
- /*
- * We now have a routing entry for the reported origin. Update it?
- */
- r = rtp;
- if (r->rt_metric == UNREACHABLE) {
- /*
- * The routing entry is for a formerly-unreachable or new origin.
- * If the report claims reachability, update the entry to use
- * the reported route.
- */
- if (adj_metric == UNREACHABLE)
- return;
-
- r->rt_parent = vifi;
- init_children_and_leaves(r, vifi);
-
- r->rt_gateway = src;
- r->rt_timer = 0;
- r->rt_metric = adj_metric;
- r->rt_flags |= RTF_CHANGED;
- routes_changed = TRUE;
- update_table_entry(r);
- }
- else if (src == r->rt_gateway) {
- /*
- * The report has come either from the interface directly-connected
- * to the origin subnet (src and r->rt_gateway both equal zero) or
- * from the gateway we have chosen as the best first-hop gateway back
- * towards the origin (src and r->rt_gateway not equal zero). Reset
- * the route timer and, if the reported metric has changed, update
- * our entry accordingly.
- */
- r->rt_timer = 0;
- if (adj_metric == r->rt_metric)
- return;
-
- if (adj_metric == UNREACHABLE) {
- del_table_entry(r, 0, DEL_ALL_ROUTES);
- r->rt_timer = ROUTE_EXPIRE_TIME;
- }
- else if (adj_metric < r->rt_metric) {
- if (init_children_and_leaves(r, vifi)) {
- update_table_entry(r);
- }
- }
- r->rt_metric = adj_metric;
- r->rt_flags |= RTF_CHANGED;
- routes_changed = TRUE;
- }
- else if (src == 0 ||
- (r->rt_gateway != 0 &&
- (adj_metric < r->rt_metric ||
- (adj_metric == r->rt_metric &&
- (ntohl(src) < ntohl(r->rt_gateway) ||
- r->rt_timer >= ROUTE_SWITCH_TIME))))) {
- /*
- * The report is for an origin we consider reachable; the report
- * comes either from one of our own interfaces or from a gateway
- * other than the one we have chosen as the best first-hop gateway
- * back towards the origin. If the source of the update is one of
- * our own interfaces, or if the origin is not a directly-connected
- * subnet and the reported metric for that origin is better than
- * what our routing entry says, update the entry to use the new
- * gateway and metric. We also switch gateways if the reported
- * metric is the same as the one in the route entry and the gateway
- * associated with the route entry has not been heard from recently,
- * or if the metric is the same but the reporting gateway has a lower
- * IP address than the gateway associated with the route entry.
- * Did you get all that?
- */
- if (r->rt_parent != vifi || adj_metric < r->rt_metric) {
- /*
- * XXX Why do we do this if we are just changing the metric?
- */
- r->rt_parent = vifi;
- if (init_children_and_leaves(r, vifi)) {
- update_table_entry(r);
- }
- }
- r->rt_gateway = src;
- r->rt_timer = 0;
- r->rt_metric = adj_metric;
- r->rt_flags |= RTF_CHANGED;
- routes_changed = TRUE;
- }
- else if (vifi != r->rt_parent) {
- /*
- * The report came from a vif other than the route's parent vif.
- * Update the children and leaf info, if necessary.
- */
- if (VIFM_ISSET(vifi, r->rt_children)) {
- /*
- * Vif is a child vif for this route.
- */
- if (metric < r->rt_metric ||
- (metric == r->rt_metric &&
- ntohl(src) < ntohl(uvifs[vifi].uv_lcl_addr))) {
- /*
- * Neighbor has lower metric to origin (or has same metric
- * and lower IP address) -- it becomes the dominant router,
- * and vif is no longer a child for me.
- */
- VIFM_CLR(vifi, r->rt_children);
- VIFM_CLR(vifi, r->rt_leaves);
- r->rt_dominants [vifi] = src;
- r->rt_subordinates[vifi] = 0;
- r->rt_leaf_timers [vifi] = 0;
- update_table_entry(r);
- }
- else if (metric > UNREACHABLE) { /* "poisoned reverse" */
- /*
- * Neighbor considers this vif to be on path to route's
- * origin; if no subordinate recorded, record this neighbor
- * as subordinate and clear the leaf flag.
- */
- if (r->rt_subordinates[vifi] == 0) {
- VIFM_CLR(vifi, r->rt_leaves);
- r->rt_subordinates[vifi] = src;
- r->rt_leaf_timers [vifi] = 0;
- update_table_entry(r);
- }
- }
- else if (src == r->rt_subordinates[vifi]) {
- /*
- * Current subordinate no longer considers this vif to be on
- * path to route's origin; it is no longer a subordinate
- * router, and we set the leaf confirmation timer to give
- * us time to hear from other subordinates.
- */
- r->rt_subordinates[vifi] = 0;
- if (uvifs[vifi].uv_neighbors == NULL ||
- uvifs[vifi].uv_neighbors->al_next == NULL) {
- VIFM_SET(vifi, r->rt_leaves);
- update_table_entry(r);
- }
- else {
- r->rt_leaf_timers [vifi] = LEAF_CONFIRMATION_TIME;
- r->rt_flags |= RTF_LEAF_TIMING;
- }
- }
-
- }
- else if (src == r->rt_dominants[vifi] &&
- (metric > r->rt_metric ||
- (metric == r->rt_metric &&
- ntohl(src) > ntohl(uvifs[vifi].uv_lcl_addr)))) {
- /*
- * Current dominant no longer has a lower metric to origin
- * (or same metric and lower IP address); we adopt the vif
- * as our own child.
- */
- VIFM_SET(vifi, r->rt_children);
- r->rt_dominants [vifi] = 0;
- if (metric > UNREACHABLE) {
- r->rt_subordinates[vifi] = src;
- }
- else if (uvifs[vifi].uv_neighbors == NULL ||
- uvifs[vifi].uv_neighbors->al_next == NULL) {
- VIFM_SET(vifi, r->rt_leaves);
- }
- else {
- r->rt_leaf_timers[vifi] = LEAF_CONFIRMATION_TIME;
- r->rt_flags |= RTF_LEAF_TIMING;
- }
- update_table_entry(r);
- }
- }
-}
-
-
-/*
- * On every timer interrupt, advance the timer in each routing entry.
- */
-void
-age_routes()
-{
- register struct rtentry *r;
- register struct rtentry *prev_r;
- register vifi_t vifi;
-
- for (prev_r = RT_ADDR, r = routing_table;
- r != NULL;
- prev_r = r, r = r->rt_next) {
-
- if ((r->rt_timer += TIMER_INTERVAL) < ROUTE_EXPIRE_TIME) {
- /*
- * Route is still good; see if any leaf timers need to be
- * advanced.
- */
- if (r->rt_flags & RTF_LEAF_TIMING) {
- r->rt_flags &= ~RTF_LEAF_TIMING;
- for (vifi = 0; vifi < numvifs; ++vifi) {
- if (r->rt_leaf_timers[vifi] != 0) {
- /*
- * Unlike other timers, leaf timers decrement.
- */
- if ((r->rt_leaf_timers[vifi] -= TIMER_INTERVAL) == 0){
-#ifdef NOTYET
- /* If the vif is a physical leaf but has neighbors,
- * it is not a tree leaf. If I am a leaf, then no
- * interface with neighbors is a tree leaf. */
- if (!(((uvifs[vifi].uv_flags & VIFF_LEAF) ||
- (vifs_with_neighbors == 1)) &&
- (uvifs[vifi].uv_neighbors != NULL))) {
-#endif
- VIFM_SET(vifi, r->rt_leaves);
- update_table_entry(r);
-#ifdef NOTYET
- }
-#endif
- }
- else {
- r->rt_flags |= RTF_LEAF_TIMING;
- }
- }
- }
- }
- }
- else if (r->rt_timer >= ROUTE_DISCARD_TIME) {
- /*
- * Time to garbage-collect the route entry.
- */
- del_table_entry(r, 0, DEL_ALL_ROUTES);
- discard_route(prev_r);
- r = prev_r;
- }
- else if (r->rt_metric != UNREACHABLE) {
- /*
- * Time to expire the route entry. If the gateway is zero,
- * i.e., it is a route to a directly-connected subnet, just
- * set the timer back to zero; such routes expire only when
- * the interface to the subnet goes down.
- */
- if (r->rt_gateway == 0) {
- r->rt_timer = 0;
- }
- else {
- del_table_entry(r, 0, DEL_ALL_ROUTES);
- r->rt_metric = UNREACHABLE;
- r->rt_flags |= RTF_CHANGED;
- routes_changed = TRUE;
- }
- }
- }
-}
-
-
-/*
- * Mark all routes as unreachable. This function is called only from
- * hup() in preparation for informing all neighbors that we are going
- * off the air. For consistency, we ought also to delete all reachable
- * route entries from the kernel, but since we are about to exit we rely
- * on the kernel to do its own cleanup -- no point in making all those
- * expensive kernel calls now.
- */
-void
-expire_all_routes()
-{
- register struct rtentry *r;
-
- for (r = routing_table; r != NULL; r = r->rt_next) {
- r->rt_metric = UNREACHABLE;
- r->rt_flags |= RTF_CHANGED;
- routes_changed = TRUE;
- }
-}
-
-
-/*
- * Delete all the routes in the routing table.
- */
-void
-free_all_routes()
-{
- register struct rtentry *r;
-
- r = RT_ADDR;
-
- while (r->rt_next)
- discard_route(r);
-}
-
-
-/*
- * Process an incoming neighbor probe message.
- */
-void
-accept_probe(src, dst, p, datalen, level)
- u_int32 src;
- u_int32 dst;
- char *p;
- int datalen;
- u_int32 level;
-{
- vifi_t vifi;
-
- if ((vifi = find_vif(src, dst)) == NO_VIF) {
- log(LOG_INFO, 0,
- "ignoring probe from non-neighbor %s", inet_fmt(src, s1));
- return;
- }
-
- update_neighbor(vifi, src, DVMRP_PROBE, p, datalen, level);
-}
-
-struct newrt {
- u_int32 mask;
- u_int32 origin;
- int metric;
- int pad;
-};
-
-static int
-compare_rts(rt1, rt2)
- const void *rt1;
- const void *rt2;
-{
- register struct newrt *r1 = (struct newrt *)rt1;
- register struct newrt *r2 = (struct newrt *)rt2;
- register u_int32 m1 = ntohl(r1->mask);
- register u_int32 m2 = ntohl(r2->mask);
- register u_int32 o1, o2;
-
- if (m1 > m2)
- return (-1);
- if (m1 < m2)
- return (1);
-
- /* masks are equal */
- o1 = ntohl(r1->origin);
- o2 = ntohl(r2->origin);
- if (o1 > o2)
- return (-1);
- if (o1 < o2)
- return (1);
- return (0);
-}
-
-/*
- * Process an incoming route report message.
- */
-void
-accept_report(src, dst, p, datalen, level)
- u_int32 src, dst, level;
- register char *p;
- register int datalen;
-{
- vifi_t vifi;
- register int width, i, nrt = 0;
- int metric;
- u_int32 mask;
- u_int32 origin;
- struct newrt rt[4096];
-
- if ((vifi = find_vif(src, dst)) == NO_VIF) {
- log(LOG_INFO, 0,
- "ignoring route report from non-neighbor %s", inet_fmt(src, s1));
- return;
- }
-
- if (!update_neighbor(vifi, src, DVMRP_REPORT, NULL, 0, level))
- return;
-
- if (datalen > 2*4096) {
- log(LOG_INFO, 0,
- "ignoring oversize (%d bytes) route report from %s",
- datalen, inet_fmt(src, s1));
- return;
- }
-
- while (datalen > 0) { /* Loop through per-mask lists. */
-
- if (datalen < 3) {
- log(LOG_WARNING, 0,
- "received truncated route report from %s",
- inet_fmt(src, s1));
- return;
- }
- ((u_char *)&mask)[0] = 0xff; width = 1;
- if ((((u_char *)&mask)[1] = *p++) != 0) width = 2;
- if ((((u_char *)&mask)[2] = *p++) != 0) width = 3;
- if ((((u_char *)&mask)[3] = *p++) != 0) width = 4;
- if (!inet_valid_mask(ntohl(mask))) {
- log(LOG_WARNING, 0,
- "%s reports bogus netmask 0x%08x (%s)",
- inet_fmt(src, s1), ntohl(mask), inet_fmt(mask, s2));
- return;
- }
- datalen -= 3;
-
- do { /* Loop through (origin, metric) pairs */
- if (datalen < width + 1) {
- log(LOG_WARNING, 0,
- "received truncated route report from %s",
- inet_fmt(src, s1));
- return;
- }
- origin = 0;
- for (i = 0; i < width; ++i)
- ((char *)&origin)[i] = *p++;
- metric = *p++;
- datalen -= width + 1;
- rt[nrt].mask = mask;
- rt[nrt].origin = origin;
- rt[nrt].metric = (metric & 0x7f);
- ++nrt;
- } while (!(metric & 0x80));
- }
-
- qsort((char*)rt, nrt, sizeof(rt[0]), compare_rts);
- start_route_updates();
- /*
- * If the last entry is default, change mask from 0xff000000 to 0
- */
- if (rt[nrt-1].origin == 0)
- rt[nrt-1].mask = 0;
-
- log(LOG_DEBUG, 0, "Updating %d routes from %s to %s", nrt,
- inet_fmt(src, s1), inet_fmt(dst, s2));
- for (i = 0; i < nrt; ++i) {
- if (i != 0 && rt[i].origin == rt[i-1].origin &&
- rt[i].mask == rt[i-1].mask) {
- log(LOG_WARNING, 0, "%s reports duplicate route for %s",
- inet_fmt(src, s1), inet_fmts(rt[i].origin, rt[i].mask, s2));
- continue;
- }
- update_route(rt[i].origin, rt[i].mask, rt[i].metric,
- src, vifi);
- }
-
- if (routes_changed && !delay_change_reports)
- report_to_all_neighbors(CHANGED_ROUTES);
-}
-
-
-/*
- * Send a route report message to destination 'dst', via virtual interface
- * 'vifi'. 'which_routes' specifies ALL_ROUTES or CHANGED_ROUTES.
- */
-void
-report(which_routes, vifi, dst)
- int which_routes;
- vifi_t vifi;
- u_int32 dst;
-{
- register struct rtentry *r;
- register char *p;
- register int i;
- int datalen = 0;
- int width = 0;
- u_int32 mask = 0;
- u_int32 src;
- u_int32 nflags;
-
- src = uvifs[vifi].uv_lcl_addr;
-
- p = send_buf + MIN_IP_HEADER_LEN + IGMP_MINLEN;
-
-#ifdef NOTYET
- /* If I'm not a leaf, but the neighbor is a leaf, only advertise default */
- if ((vifs_with_neighbors != 1) && (uvifs[vifi].uv_flags & VIFF_LEAF)) {
- *p++ = 0; /* 0xff000000 mask */
- *p++ = 0;
- *p++ = 0;
- *p++ = 0; /* class A net 0.0.0.0 == default */
- *p++ = 0x81; /*XXX metric 1, is this safe? */
- datalen += 5;
- send_igmp(src, dst, IGMP_DVMRP, DVMRP_REPORT,
- htonl(MROUTED_LEVEL), datalen);
- return;
- }
-#endif
-
- nflags = (uvifs[vifi].uv_flags & VIFF_LEAF) ? 0 : LEAF_FLAGS;
-
- for (r = rt_end; r != RT_ADDR; r = r->rt_prev) {
-
- if (which_routes == CHANGED_ROUTES && !(r->rt_flags & RTF_CHANGED))
- continue;
-
- /*
- * If there is no room for this route in the current message,
- * send the message and start a new one.
- */
- if (datalen + ((r->rt_originmask == mask) ?
- (width + 1) :
- (r->rt_originwidth + 4)) > MAX_DVMRP_DATA_LEN) {
- *(p-1) |= 0x80;
- send_igmp(src, dst, IGMP_DVMRP, DVMRP_REPORT,
- htonl(MROUTED_LEVEL | nflags), datalen);
-
- p = send_buf + MIN_IP_HEADER_LEN + IGMP_MINLEN;
- datalen = 0;
- mask = 0;
- }
-
- if (r->rt_originmask != mask || datalen == 0) {
- mask = r->rt_originmask;
- width = r->rt_originwidth;
- if (datalen != 0) *(p-1) |= 0x80;
- *p++ = ((char *)&mask)[1];
- *p++ = ((char *)&mask)[2];
- *p++ = ((char *)&mask)[3];
- datalen += 3;
- }
-
- for (i = 0; i < width; ++i)
- *p++ = ((char *)&(r->rt_origin))[i];
-
- *p++ = (r->rt_parent == vifi && r->rt_metric != UNREACHABLE) ?
- (char)(r->rt_metric + UNREACHABLE) : /* "poisoned reverse" */
- (char)(r->rt_metric);
-
- datalen += width + 1;
- }
-
- if (datalen != 0) {
- *(p-1) |= 0x80;
- send_igmp(src, dst, IGMP_DVMRP, DVMRP_REPORT,
- htonl(MROUTED_LEVEL | nflags), datalen);
- }
-}
-
-
-/*
- * Send a route report message to all neighboring routers.
- * 'which_routes' specifies ALL_ROUTES or CHANGED_ROUTES.
- */
-void
-report_to_all_neighbors(which_routes)
- int which_routes;
-{
- register vifi_t vifi;
- register struct uvif *v;
- register struct rtentry *r;
- int routes_changed_before;
-
- /*
- * Remember the state of the global routes_changed flag before
- * generating the reports, and clear the flag.
- */
- routes_changed_before = routes_changed;
- routes_changed = FALSE;
-
-
- for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
- if (v->uv_neighbors != NULL) {
- report(which_routes, vifi,
- (v->uv_flags & VIFF_TUNNEL) ? v->uv_rmt_addr
- : dvmrp_group);
- }
- }
-
- /*
- * If there were changed routes before we sent the reports AND
- * if no new changes occurred while sending the reports, clear
- * the change flags in the individual route entries. If changes
- * did occur while sending the reports, new reports will be
- * generated at the next timer interrupt.
- */
- if (routes_changed_before && !routes_changed) {
- for (r = routing_table; r != NULL; r = r->rt_next) {
- r->rt_flags &= ~RTF_CHANGED;
- }
- }
-
- /*
- * Set a flag to inhibit further reports of changed routes until the
- * next timer interrupt. This is to alleviate update storms.
- */
- delay_change_reports = TRUE;
-}
-
-/*
- * Send a route report message to destination 'dst', via virtual interface
- * 'vifi'. 'which_routes' specifies ALL_ROUTES or CHANGED_ROUTES.
- */
-static int
-report_chunk(start_rt, vifi, dst)
- register struct rtentry *start_rt;
- vifi_t vifi;
- u_int32 dst;
-{
- register struct rtentry *r;
- register char *p;
- register int i;
- register int nrt = 0;
- int datalen = 0;
- int width = 0;
- u_int32 mask = 0;
- u_int32 src;
- u_int32 nflags;
-
- src = uvifs[vifi].uv_lcl_addr;
- p = send_buf + MIN_IP_HEADER_LEN + IGMP_MINLEN;
-
- nflags = (uvifs[vifi].uv_flags & VIFF_LEAF) ? 0 : LEAF_FLAGS;
-
- for (r = start_rt; r != RT_ADDR; r = r->rt_prev) {
-
-#ifdef NOTYET
- /* Don't send poisoned routes back to parents if I am a leaf */
- if ((vifs_with_neighbors == 1) && (r->rt_parent == vifi)
- && (r->rt_metric > 1)) {
- ++nrt;
- continue;
- }
-#endif
-
- /*
- * If there is no room for this route in the current message,
- * send it & return how many routes we sent.
- */
- if (datalen + ((r->rt_originmask == mask) ?
- (width + 1) :
- (r->rt_originwidth + 4)) > MAX_DVMRP_DATA_LEN) {
- *(p-1) |= 0x80;
- send_igmp(src, dst, IGMP_DVMRP, DVMRP_REPORT,
- htonl(MROUTED_LEVEL | nflags), datalen);
- return (nrt);
- }
- if (r->rt_originmask != mask || datalen == 0) {
- mask = r->rt_originmask;
- width = r->rt_originwidth;
- if (datalen != 0) *(p-1) |= 0x80;
- *p++ = ((char *)&mask)[1];
- *p++ = ((char *)&mask)[2];
- *p++ = ((char *)&mask)[3];
- datalen += 3;
- }
- for (i = 0; i < width; ++i)
- *p++ = ((char *)&(r->rt_origin))[i];
-
- *p++ = (r->rt_parent == vifi && r->rt_metric != UNREACHABLE) ?
- (char)(r->rt_metric + UNREACHABLE) : /* "poisoned reverse" */
- (char)(r->rt_metric);
- ++nrt;
- datalen += width + 1;
- }
- if (datalen != 0) {
- *(p-1) |= 0x80;
- send_igmp(src, dst, IGMP_DVMRP, DVMRP_REPORT,
- htonl(MROUTED_LEVEL | nflags), datalen);
- }
- return (nrt);
-}
-
-/*
- * send the next chunk of our routing table to all neighbors.
- * return the length of the smallest chunk we sent out.
- */
-int
-report_next_chunk()
-{
- register vifi_t vifi;
- register struct uvif *v;
- register struct rtentry *sr;
- register int i, n = 0, min = 20000;
- static int start_rt;
-
- if (nroutes <= 0)
- return (0);
-
- /*
- * find this round's starting route.
- */
- for (sr = rt_end, i = start_rt; --i >= 0; ) {
- sr = sr->rt_prev;
- if (sr == RT_ADDR)
- sr = rt_end;
- }
-
- /*
- * send one chunk of routes starting at this round's start to
- * all our neighbors.
- */
- for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
- if ((v->uv_neighbors != NULL)
-#ifdef NOTYET
- && !(v->uv_flags & VIFF_LEAF)
-#endif
- ) {
- n = report_chunk(sr, vifi,
- (v->uv_flags & VIFF_TUNNEL) ? v->uv_rmt_addr
- : dvmrp_group);
- if (n < min)
- min = n;
- }
- }
- if (min == 20000)
- min = 0; /* Neighborless router didn't send any routes */
-
- n = min;
- log(LOG_INFO, 0, "update %d starting at %d of %d",
- n, (nroutes - start_rt), nroutes);
-
- start_rt = (start_rt + n) % nroutes;
- return (n);
-}
-
-
-/*
- * Print the contents of the routing table on file 'fp'.
- */
-void
-dump_routes(fp)
- FILE *fp;
-{
- register struct rtentry *r;
- register vifi_t i;
-
-
- fprintf(fp,
- "Multicast Routing Table (%u %s)\n%s\n",
- nroutes, (nroutes == 1) ? "entry" : "entries",
- " Origin-Subnet From-Gateway Metric Tmr In-Vif Out-Vifs");
-
- for (r = routing_table; r != NULL; r = r->rt_next) {
-
- fprintf(fp, " %-18s %-15s ",
- inet_fmts(r->rt_origin, r->rt_originmask, s1),
- (r->rt_gateway == 0) ? "" : inet_fmt(r->rt_gateway, s2));
-
- fprintf(fp, (r->rt_metric == UNREACHABLE) ? " NR " : "%4u ",
- r->rt_metric);
-
- fprintf(fp, " %3u %3u ", r->rt_timer, r->rt_parent);
-
- for (i = 0; i < numvifs; ++i) {
- if (VIFM_ISSET(i, r->rt_children)) {
- fprintf(fp, " %u%c",
- i, VIFM_ISSET(i, r->rt_leaves) ? '*' : ' ');
- }
- }
- fprintf(fp, "\n");
- }
- fprintf(fp, "\n");
-}
-
-struct rtentry *
-determine_route(src)
- u_int32 src;
-{
- struct rtentry *rt;
-
- for (rt = routing_table; rt != NULL; rt = rt->rt_next) {
- if (rt->rt_origin == (src & rt->rt_originmask))
- break;
- }
- return rt;
-}
diff --git a/usr.sbin/mrouted/route.h b/usr.sbin/mrouted/route.h
deleted file mode 100644
index 73159d50261e..000000000000
--- a/usr.sbin/mrouted/route.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * The mrouted program is covered by the license in the accompanying file
- * named "LICENSE". 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.
- *
- *
- * $Id: route.h,v 3.8 1995/11/29 22:36:57 fenner Rel $
- */
-
-/*
- * Routing Table Entry, one per subnet from which a multicast could originate.
- * (Note: all addresses, subnet numbers and masks are kept in NETWORK order.)
- *
- * The Routing Table is stored as a doubly-linked list of these structures,
- * ordered by decreasing value of rt_originmask and, secondarily, by
- * decreasing value of rt_origin within each rt_originmask value.
- * This data structure is efficient for generating route reports, whether
- * full or partial, for processing received full reports, for clearing the
- * CHANGED flags, and for periodically advancing the timers in all routes.
- * It is not so efficient for updating a small number of routes in response
- * to a partial report. In a stable topology, the latter are rare; if they
- * turn out to be costing a lot, we can add an auxiliary hash table for
- * faster access to arbitrary route entries.
- */
-struct rtentry {
- struct rtentry *rt_next; /* link to next entry MUST BE FIRST */
- u_int32 rt_origin; /* subnet origin of multicasts */
- u_int32 rt_originmask; /* subnet mask for origin */
- short rt_originwidth; /* # bytes of origin subnet number */
- u_char rt_metric; /* cost of route back to origin */
- u_char rt_flags; /* RTF_ flags defined below */
- u_int32 rt_gateway; /* first-hop gateway back to origin */
- vifi_t rt_parent; /* incoming vif (ie towards origin) */
- vifbitmap_t rt_children; /* outgoing children vifs */
- vifbitmap_t rt_leaves; /* subset of outgoing children vifs */
- u_int32 *rt_dominants; /* per vif dominant gateways */
- u_int32 *rt_subordinates; /* per vif subordinate gateways */
- u_int *rt_leaf_timers; /* per vif leaf confirmation timers */
- u_int rt_timer; /* for timing out the route entry */
- struct rtentry *rt_prev; /* link to previous entry */
- struct gtable *rt_groups; /* link to active groups */
-};
-
-#define RTF_CHANGED 0x01 /* route changed but not reported */
-#define RTF_LEAF_TIMING 0x02 /* some leaf timers are running */
-
-#define ALL_ROUTES 0 /* possible arguments to report() */
-#define CHANGED_ROUTES 1 /* and report_to_all_neighbors() */
diff --git a/usr.sbin/mrouted/rsrr.c b/usr.sbin/mrouted/rsrr.c
deleted file mode 100644
index ea9628f55aea..000000000000
--- a/usr.sbin/mrouted/rsrr.c
+++ /dev/null
@@ -1,499 +0,0 @@
-/*
- * Copyright (c) 1993 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 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, Information
- * Sciences Institute. The name of the University may not be used to
- * endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THE UNIVERSITY OF SOUTHERN CALIFORNIA makes no 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.
- *
- * Other copyrights might apply to parts of this software and are so
- * noted when applicable.
- */
-
-/* RSRR code written by Daniel Zappala, USC Information Sciences Institute,
- * April 1995.
- */
-
-/* May 1995 -- Added support for Route Change Notification */
-
-#ifdef RSRR
-
-#include "defs.h"
-#include <sys/param.h>
-#if (defined(BSD) && (BSD >= 199103))
-#include <stddef.h>
-#endif
-
-/* Taken from prune.c */
-/*
- * checks for scoped multicast addresses
- */
-#define GET_SCOPE(gt) { \
- register int _i; \
- if (((gt)->gt_mcastgrp & 0xff000000) == 0xef000000) \
- for (_i = 0; _i < numvifs; _i++) \
- if (scoped_addr(_i, (gt)->gt_mcastgrp)) \
- VIFM_SET(_i, (gt)->gt_scope); \
- }
-
-/*
- * Exported variables.
- */
-int rsrr_socket; /* interface to reservation protocol */
-
-/*
- * Global RSRR variables.
- */
-char rsrr_recv_buf[RSRR_MAX_LEN]; /* RSRR receive buffer */
-char rsrr_send_buf[RSRR_MAX_LEN]; /* RSRR send buffer */
-
-struct sockaddr_un client_addr;
-int client_length = sizeof(client_addr);
-
-
-/*
- * Procedure definitions needed internally.
- */
-static void rsrr_accept __P((int recvlen));
-static void rsrr_accept_iq __P((void));
-static int rsrr_accept_rq __P((struct rsrr_rq *route_query, int flags,
- struct gtable *gt_notify));
-static int rsrr_send __P((int sendlen));
-static void rsrr_cache __P((struct gtable *gt,
- struct rsrr_rq *route_query));
-
-/* Initialize RSRR socket */
-void
-rsrr_init()
-{
- int servlen;
- struct sockaddr_un serv_addr;
-
- if ((rsrr_socket = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0)
- log(LOG_ERR, errno, "Can't create RSRR socket");
-
- unlink(RSRR_SERV_PATH);
- bzero((char *) &serv_addr, sizeof(serv_addr));
- serv_addr.sun_family = AF_UNIX;
- strcpy(serv_addr.sun_path, RSRR_SERV_PATH);
-#if (defined(BSD) && (BSD >= 199103))
- servlen = offsetof(struct sockaddr_un, sun_path) +
- strlen(serv_addr.sun_path);
- serv_addr.sun_len = servlen;
-#else
- servlen = sizeof(serv_addr.sun_family) + strlen(serv_addr.sun_path);
-#endif
-
- if (bind(rsrr_socket, (struct sockaddr *) &serv_addr, servlen) < 0)
- log(LOG_ERR, errno, "Can't bind RSRR socket");
-
- if (register_input_handler(rsrr_socket,rsrr_read) < 0)
- log(LOG_WARNING, 0, "Couldn't register RSRR as an input handler");
-}
-
-/* Read a message from the RSRR socket */
-void
-rsrr_read(f, rfd)
- int f;
- fd_set *rfd;
-{
- register int rsrr_recvlen;
- register int omask;
-
- bzero((char *) &client_addr, sizeof(client_addr));
- rsrr_recvlen = recvfrom(rsrr_socket, rsrr_recv_buf, sizeof(rsrr_recv_buf),
- 0, (struct sockaddr *)&client_addr, &client_length);
- if (rsrr_recvlen < 0) {
- if (errno != EINTR)
- log(LOG_ERR, errno, "RSRR recvfrom");
- return;
- }
- /* Use of omask taken from main() */
- omask = sigblock(sigmask(SIGALRM));
- rsrr_accept(rsrr_recvlen);
- (void)sigsetmask(omask);
-}
-
-/* Accept a message from the reservation protocol and take
- * appropriate action.
- */
-static void
-rsrr_accept(recvlen)
- int recvlen;
-{
- struct rsrr_header *rsrr;
- struct rsrr_rq *route_query;
-
- if (recvlen < RSRR_HEADER_LEN) {
- log(LOG_WARNING, 0,
- "Received RSRR packet of %d bytes, which is less than min size",
- recvlen);
- return;
- }
-
- rsrr = (struct rsrr_header *) rsrr_recv_buf;
-
- if (rsrr->version > RSRR_MAX_VERSION) {
- log(LOG_WARNING, 0,
- "Received RSRR packet version %d, which I don't understand",
- rsrr->version);
- return;
- }
-
- switch (rsrr->version) {
- case 1:
- switch (rsrr->type) {
- case RSRR_INITIAL_QUERY:
- /* Send Initial Reply to client */
- log(LOG_INFO, 0, "Received Initial Query\n");
- rsrr_accept_iq();
- break;
- case RSRR_ROUTE_QUERY:
- /* Check size */
- if (recvlen < RSRR_RQ_LEN) {
- log(LOG_WARNING, 0,
- "Received Route Query of %d bytes, which is too small",
- recvlen);
- break;
- }
- /* Get the query */
- route_query = (struct rsrr_rq *) (rsrr_recv_buf + RSRR_HEADER_LEN);
- log(LOG_INFO, 0,
- "Received Route Query for src %s grp %s notification %d",
- inet_fmt(route_query->source_addr.s_addr, s1),
- inet_fmt(route_query->dest_addr.s_addr,s2),
- BIT_TST(rsrr->flags,RSRR_NOTIFICATION_BIT));
- /* Send Route Reply to client */
- rsrr_accept_rq(route_query,rsrr->flags,NULL);
- break;
- default:
- log(LOG_WARNING, 0,
- "Received RSRR packet type %d, which I don't handle",
- rsrr->type);
- break;
- }
- break;
-
- default:
- log(LOG_WARNING, 0,
- "Received RSRR packet version %d, which I don't understand",
- rsrr->version);
- break;
- }
-}
-
-/* Send an Initial Reply to the reservation protocol. */
-static void
-rsrr_accept_iq()
-{
- struct rsrr_header *rsrr;
- struct rsrr_vif *vif_list;
- struct uvif *v;
- int vifi, sendlen;
-
- /* Check for space. There should be room for plenty of vifs,
- * but we should check anyway.
- */
- if (numvifs > RSRR_MAX_VIFS) {
- log(LOG_WARNING, 0,
- "Can't send RSRR Route Reply because %d is too many vifs %d",
- numvifs);
- return;
- }
-
- /* Set up message */
- rsrr = (struct rsrr_header *) rsrr_send_buf;
- rsrr->version = 1;
- rsrr->type = RSRR_INITIAL_REPLY;
- rsrr->flags = 0;
- rsrr->num = numvifs;
-
- vif_list = (struct rsrr_vif *) (rsrr_send_buf + RSRR_HEADER_LEN);
-
- /* Include the vif list. */
- for (vifi=0, v = uvifs; vifi < numvifs; vifi++, v++) {
- vif_list[vifi].id = vifi;
- vif_list[vifi].status = 0;
- if (v->uv_flags & VIFF_DISABLED)
- BIT_SET(vif_list[vifi].status,RSRR_DISABLED_BIT);
- vif_list[vifi].threshold = v->uv_threshold;
- vif_list[vifi].local_addr.s_addr = v->uv_lcl_addr;
- }
-
- /* Get the size. */
- sendlen = RSRR_HEADER_LEN + numvifs*RSRR_VIF_LEN;
-
- /* Send it. */
- log(LOG_INFO, 0, "Send RSRR Initial Reply");
- rsrr_send(sendlen);
-}
-
-/* Send a Route Reply to the reservation protocol. The Route Query
- * contains the query to which we are responding. The flags contain
- * the incoming flags from the query or, for route change
- * notification, the flags that should be set for the reply. The
- * kernel table entry contains the routing info to use for a route
- * change notification.
- */
-static int
-rsrr_accept_rq(route_query,flags,gt_notify)
- struct rsrr_rq *route_query;
- int flags;
- struct gtable *gt_notify;
-{
- struct rsrr_header *rsrr;
- struct rsrr_rr *route_reply;
- struct gtable *gt,local_g;
- struct rtentry *r;
- int sendlen,i;
- u_long mcastgrp;
-
- /* Set up message */
- rsrr = (struct rsrr_header *) rsrr_send_buf;
- rsrr->version = 1;
- rsrr->type = RSRR_ROUTE_REPLY;
- rsrr->flags = 0;
- rsrr->num = 0;
-
- route_reply = (struct rsrr_rr *) (rsrr_send_buf + RSRR_HEADER_LEN);
- route_reply->dest_addr.s_addr = route_query->dest_addr.s_addr;
- route_reply->source_addr.s_addr = route_query->source_addr.s_addr;
- route_reply->query_id = route_query->query_id;
-
- /* Blank routing entry for error. */
- route_reply->in_vif = 0;
- route_reply->reserved = 0;
- route_reply->out_vif_bm = 0;
-
- /* Get the size. */
- sendlen = RSRR_RR_LEN;
-
- /* If kernel table entry is defined, then we are sending a Route Reply
- * due to a Route Change Notification event. Use the kernel table entry
- * to supply the routing info.
- */
- if (gt_notify) {
- /* Set flags */
- rsrr->flags = flags;
- /* Include the routing entry. */
- route_reply->in_vif = gt_notify->gt_route->rt_parent;
- route_reply->out_vif_bm = gt_notify->gt_grpmems;
-
- } else if (find_src_grp(route_query->source_addr.s_addr, 0,
- route_query->dest_addr.s_addr)) {
-
- /* Found kernel entry. Code taken from add_table_entry() */
- gt = gtp ? gtp->gt_gnext : kernel_table;
-
- /* Include the routing entry. */
- route_reply->in_vif = gt->gt_route->rt_parent;
- route_reply->out_vif_bm = gt->gt_grpmems;
-
- /* Cache reply if using route change notification. */
- if BIT_TST(flags,RSRR_NOTIFICATION_BIT) {
- rsrr_cache(gt,route_query);
- BIT_SET(rsrr->flags,RSRR_NOTIFICATION_BIT);
- }
-
- } else {
- /* No kernel entry; use routing table. */
- r = determine_route(route_query->source_addr.s_addr);
-
- if (r != NULL) {
- /* We need to mimic what will happen if a data packet
- * is forwarded by multicast routing -- the kernel will
- * make an upcall and mrouted will install a route in the kernel.
- * Our outgoing vif bitmap should reflect what that table
- * will look like. Grab code from add_table_entry().
- * This is gross, but it's probably better to be accurate.
- */
-
- gt = &local_g;
- mcastgrp = route_query->dest_addr.s_addr;
-
- gt->gt_mcastgrp = mcastgrp;
- gt->gt_grpmems = 0;
- gt->gt_scope = 0;
- gt->gt_route = r;
-
- /* obtain the multicast group membership list */
- for (i = 0; i < numvifs; i++) {
- if (VIFM_ISSET(i, r->rt_children) &&
- !(VIFM_ISSET(i, r->rt_leaves)))
- VIFM_SET(i, gt->gt_grpmems);
-
- if (VIFM_ISSET(i, r->rt_leaves) && grplst_mem(i, mcastgrp))
- VIFM_SET(i, gt->gt_grpmems);
- }
-
- GET_SCOPE(gt);
- gt->gt_grpmems &= ~gt->gt_scope;
-
- /* Include the routing entry. */
- route_reply->in_vif = gt->gt_route->rt_parent;
- route_reply->out_vif_bm = gt->gt_grpmems;
-
- } else {
- /* Set error bit. */
- BIT_SET(rsrr->flags,RSRR_ERROR_BIT);
- }
- }
-
- if (gt_notify)
- log(LOG_INFO, 0, "Route Change: Send RSRR Route Reply");
-
- else
- log(LOG_INFO, 0, "Send RSRR Route Reply");
-
- log(LOG_INFO, 0, "for src %s dst %s in vif %d out vif %d\n",
- inet_fmt(route_reply->source_addr.s_addr,s1),
- inet_fmt(route_reply->dest_addr.s_addr,s2),
- route_reply->in_vif,route_reply->out_vif_bm);
-
- /* Send it. */
- return rsrr_send(sendlen);
-}
-
-/* Send an RSRR message. */
-static int
-rsrr_send(sendlen)
- int sendlen;
-{
- int error;
-
- /* Send it. */
- error = sendto(rsrr_socket, rsrr_send_buf, sendlen, 0,
- (struct sockaddr *)&client_addr, client_length);
-
- /* Check for errors. */
- if (error < 0) {
- log(LOG_WARNING, errno, "Failed send on RSRR socket");
- } else if (error != sendlen) {
- log(LOG_WARNING, 0,
- "Sent only %d out of %d bytes on RSRR socket\n", error, sendlen);
- }
- return error;
-}
-
-/* Cache a message being sent to a client. Currently only used for
- * caching Route Reply messages for route change notification.
- */
-static void
-rsrr_cache(gt,route_query)
- struct gtable *gt;
- struct rsrr_rq *route_query;
-{
- struct rsrr_cache *rc, **rcnp;
- struct rsrr_header *rsrr;
-
- rsrr = (struct rsrr_header *) rsrr_send_buf;
-
- rcnp = &gt->gt_rsrr_cache;
- while ((rc = *rcnp) != NULL) {
- if ((rc->route_query.source_addr.s_addr ==
- route_query->source_addr.s_addr) &&
- (rc->route_query.dest_addr.s_addr ==
- route_query->dest_addr.s_addr) &&
- (!strcmp(rc->client_addr.sun_path,client_addr.sun_path))) {
- /* Cache entry already exists.
- * Check if route notification bit has been cleared.
- */
- if (!BIT_TST(rsrr->flags,RSRR_NOTIFICATION_BIT)) {
- /* Delete cache entry. */
- *rcnp = rc->next;
- free(rc);
- } else {
- /* Update */
- rc->route_query.query_id = route_query->query_id;
- log(LOG_DEBUG, 0,
- "Update cached query id %ld from client %s\n",
- rc->route_query.query_id, rc->client_addr.sun_path);
- }
- return;
- }
- rcnp = &rc->next;
- }
-
- /* Cache entry doesn't already exist. Create one and insert at
- * front of list.
- */
- rc = (struct rsrr_cache *) malloc(sizeof(struct rsrr_cache));
- if (rc == NULL)
- log(LOG_ERR, 0, "ran out of memory");
- rc->route_query.source_addr.s_addr = route_query->source_addr.s_addr;
- rc->route_query.dest_addr.s_addr = route_query->dest_addr.s_addr;
- rc->route_query.query_id = route_query->query_id;
- strcpy(rc->client_addr.sun_path, client_addr.sun_path);
- rc->client_length = client_length;
- rc->next = gt->gt_rsrr_cache;
- gt->gt_rsrr_cache = rc;
- log(LOG_DEBUG, 0, "Cached query id %ld from client %s\n",
- rc->route_query.query_id,rc->client_addr.sun_path);
-}
-
-/* Send all the messages in the cache. Currently this is used to send
- * all the cached Route Reply messages for route change notification.
- */
-void
-rsrr_cache_send(gt,notify)
- struct gtable *gt;
- int notify;
-{
- struct rsrr_cache *rc, **rcnp;
- int flags = 0;
-
- if (notify)
- BIT_SET(flags,RSRR_NOTIFICATION_BIT);
-
- rcnp = &gt->gt_rsrr_cache;
- while ((rc = *rcnp) != NULL) {
- if (rsrr_accept_rq(&rc->route_query,flags,gt) < 0) {
- log(LOG_DEBUG, 0, "Deleting cached query id %ld from client %s\n",
- rc->route_query.query_id,rc->client_addr.sun_path);
- /* Delete cache entry. */
- *rcnp = rc->next;
- free(rc);
- } else {
- rcnp = &rc->next;
- }
- }
-}
-
-/* Clean the cache by deleting all entries. */
-void
-rsrr_cache_clean(gt)
- struct gtable *gt;
-{
- struct rsrr_cache *rc,*rc_next;
-
- printf("cleaning cache for group %s\n",inet_fmt(gt->gt_mcastgrp, s1));
- rc = gt->gt_rsrr_cache;
- while (rc) {
- rc_next = rc->next;
- free(rc);
- rc = rc_next;
- }
- gt->gt_rsrr_cache = NULL;
-}
-
-void
-rsrr_clean()
-{
- unlink(RSRR_SERV_PATH);
-}
-
-#endif /* RSRR */
diff --git a/usr.sbin/mrouted/rsrr.h b/usr.sbin/mrouted/rsrr.h
deleted file mode 100644
index 8bc8c9176535..000000000000
--- a/usr.sbin/mrouted/rsrr.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (c) 1993 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 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, Information
- * Sciences Institute. The name of the University may not be used to
- * endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THE UNIVERSITY OF SOUTHERN CALIFORNIA makes no 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.
- *
- * Other copyrights might apply to parts of this software and are so
- * noted when applicable.
- */
-
-#define RSRR_SERV_PATH "/tmp/.rsrr_svr"
-/* Note this needs to be 14 chars for 4.3 BSD compatibility */
-#define RSRR_CLI_PATH "/tmp/.rsrr_cli"
-
-#define RSRR_MAX_LEN 2048
-#define RSRR_HEADER_LEN (sizeof(struct rsrr_header))
-#define RSRR_RQ_LEN (RSRR_HEADER_LEN + sizeof(struct rsrr_rq))
-#define RSRR_RR_LEN (RSRR_HEADER_LEN + sizeof(struct rsrr_rr))
-#define RSRR_VIF_LEN (sizeof(struct rsrr_vif))
-
-/* Current maximum number of vifs. */
-#define RSRR_MAX_VIFS 32
-
-/* Maximum acceptable version */
-#define RSRR_MAX_VERSION 1
-
-/* RSRR message types */
-#define RSRR_ALL_TYPES 0
-#define RSRR_INITIAL_QUERY 1
-#define RSRR_INITIAL_REPLY 2
-#define RSRR_ROUTE_QUERY 3
-#define RSRR_ROUTE_REPLY 4
-
-/* RSRR Initial Reply (Vif) Status bits
- * Each definition represents the position of the bit from right to left.
- *
- * Right-most bit is the disabled bit, set if the vif is administratively
- * disabled.
- */
-#define RSRR_DISABLED_BIT 0
-/* All other bits are zeroes */
-
-/* RSRR Route Query/Reply flag bits
- * Each definition represents the position of the bit from right to left.
- *
- * Right-most bit is the Route Change Notification bit, set if the
- * reservation protocol wishes to receive notification of
- * a route change for the source-destination pair listed in the query.
- * Notification is in the form of an unsolicitied Route Reply.
- */
-#define RSRR_NOTIFICATION_BIT 0
-/* Next bit indicates an error returning the Route Reply. */
-#define RSRR_ERROR_BIT 1
-/* All other bits are zeroes */
-
-/* Definition of an RSRR message header.
- * An Initial Query uses only the header, and an Initial Reply uses
- * the header and a list of vifs.
- */
-struct rsrr_header {
- u_char version; /* RSRR Version, currently 1 */
- u_char type; /* type of message, as defined above */
- u_char flags; /* flags; defined by type */
- u_char num; /* number; defined by type */
-};
-
-/* Definition of a vif as seen by the reservation protocol.
- *
- * Routing gives the reservation protocol a list of vifs in the
- * Initial Reply.
- *
- * We explicitly list the ID because we can't assume that all routing
- * protocols will use the same numbering scheme.
- *
- * The status is a bitmask of status flags, as defined above. It is the
- * responsibility of the reservation protocol to perform any status checks
- * if it uses the MULTICAST_VIF socket option.
- *
- * The threshold indicates the ttl an outgoing packet needs in order to
- * be forwarded. The reservation protocol must perform this check itself if
- * it uses the MULTICAST_VIF socket option.
- *
- * The local address is the address of the physical interface over which
- * packets are sent.
- */
-struct rsrr_vif {
- u_char id; /* vif id */
- u_char threshold; /* vif threshold ttl */
- u_short status; /* vif status bitmask */
- struct in_addr local_addr; /* vif local address */
-};
-
-/* Definition of an RSRR Route Query.
- *
- * The query asks routing for the forwarding entry for a particular
- * source and destination. The query ID uniquely identifies the query
- * for the reservation protocol. Thus, the combination of the client's
- * address and the query ID forms a unique identifier for routing.
- * Flags are defined above.
- */
-struct rsrr_rq {
- struct in_addr dest_addr; /* destination */
- struct in_addr source_addr; /* source */
- u_long query_id; /* query ID */
-};
-
-/* Definition of an RSRR Route Reply.
- *
- * Routing uses the reply to give the reservation protocol the
- * forwarding entry for a source-destination pair. Routing copies the
- * query ID from the query and fills in the incoming vif and a bitmask
- * of the outgoing vifs.
- * Flags are defined above.
- */
-struct rsrr_rr {
- struct in_addr dest_addr; /* destination */
- struct in_addr source_addr; /* source */
- u_long query_id; /* query ID */
- u_short in_vif; /* incoming vif */
- u_short reserved; /* reserved */
- u_long out_vif_bm; /* outgoing vif bitmask */
-};
diff --git a/usr.sbin/mrouted/rsrr_var.h b/usr.sbin/mrouted/rsrr_var.h
deleted file mode 100644
index 9b1c09c1396e..000000000000
--- a/usr.sbin/mrouted/rsrr_var.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 1993 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 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, Information
- * Sciences Institute. The name of the University may not be used to
- * endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THE UNIVERSITY OF SOUTHERN CALIFORNIA makes no 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.
- *
- * Other copyrights might apply to parts of this software and are so
- * noted when applicable.
- */
-
-/* RSRR things that are only needed by mrouted. */
-
-/* Cache of Route Query messages, distinguished by source,
- * destination, and client addresses. Cache is flushed by RSRR client
- * -- it sends notification when an unwanted Route Reply is received.
- * Since this only happens during route changes, it is more likely
- * that the cache will be flushed when the kernel table entry is
- * deleted. */
-struct rsrr_cache {
- struct rsrr_rq route_query; /* Cached Route Query */
- struct sockaddr_un client_addr; /* Client address */
- int client_length; /* Length of client */
- struct rsrr_cache *next; /* next cache item */
-};
-
diff --git a/usr.sbin/mrouted/vif.c b/usr.sbin/mrouted/vif.c
deleted file mode 100644
index 3716292d1cab..000000000000
--- a/usr.sbin/mrouted/vif.c
+++ /dev/null
@@ -1,1482 +0,0 @@
-/*
- * The mrouted program is covered by the license in the accompanying file
- * named "LICENSE". 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.
- *
- *
- * $Id: vif.c,v 3.8 1995/11/29 22:36:57 fenner Rel $
- */
-
-
-#include "defs.h"
-#include <fcntl.h>
-
-/*
- * Exported variables.
- */
-struct uvif uvifs[MAXVIFS]; /* array of 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 vifs_with_neighbors; /* == 1 if I am a leaf */
-
-typedef struct {
- vifi_t vifi;
- struct listaddr *g;
- int q_time;
-} cbk_t;
-
-/*
- * Forward declarations.
- */
-static void start_vif __P((vifi_t vifi));
-static void start_vif2 __P((vifi_t vifi));
-static void stop_vif __P((vifi_t vifi));
-static void age_old_hosts __P((void));
-static void send_probe_on_vif __P((struct uvif *v));
-static int info_version __P((char *p));
-static void DelVif __P((void *arg));
-static int SetTimer __P((int vifi, struct listaddr *g));
-static int DeleteTimer __P((int id));
-static void SendQuery __P((void *arg));
-static int SetQueryTimer __P((struct listaddr *g, vifi_t vifi, int to_expire,
- int q_time));
-
-
-/*
- * Initialize the virtual interfaces, but do not install
- * them in the kernel. Start routing on all vifs that are
- * not down or disabled.
- */
-void
-init_vifs()
-{
- vifi_t vifi;
- struct uvif *v;
- int enabled_vifs, enabled_phyints;
- extern char *configfilename;
-
- numvifs = 0;
- vifs_with_neighbors = 0;
- vifs_down = FALSE;
-
- /*
- * Configure the vifs based on the interface configuration of the
- * the kernel and the contents of the configuration file.
- * (Open a UDP socket for ioctl use in the config procedures.)
- */
- if ((udp_socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
- log(LOG_ERR, errno, "UDP socket");
- log(LOG_INFO,0,"Getting vifs from kernel interfaces");
- config_vifs_from_kernel();
- log(LOG_INFO,0,"Getting vifs from %s",configfilename);
- config_vifs_from_file();
-
- /*
- * Quit if there are fewer than two enabled vifs.
- */
- enabled_vifs = 0;
- enabled_phyints = 0;
- phys_vif = -1;
- for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
- if (!(v->uv_flags & VIFF_DISABLED)) {
- ++enabled_vifs;
- if (!(v->uv_flags & VIFF_TUNNEL)) {
- if (phys_vif == -1)
- phys_vif = vifi;
- ++enabled_phyints;
- }
- }
- }
- if (enabled_vifs < 2)
- log(LOG_ERR, 0, "can't forward: %s",
- enabled_vifs == 0 ? "no enabled vifs" : "only one enabled vif");
-
- if (enabled_phyints == 0)
- log(LOG_WARNING, 0,
- "no enabled interfaces, forwarding via tunnels only");
-
- log(LOG_INFO, 0, "Installing vifs in mrouted...");
- for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
- if (!(v->uv_flags & VIFF_DISABLED)) {
- if (!(v->uv_flags & VIFF_DOWN)) {
- if (v->uv_flags & VIFF_TUNNEL)
- log(LOG_INFO, 0, "vif #%d, tunnel %s -> %s", vifi,
- inet_fmt(v->uv_lcl_addr, s1),
- inet_fmt(v->uv_rmt_addr, s2));
- else
- log(LOG_INFO, 0, "vif #%d, phyint %s", vifi,
- inet_fmt(v->uv_lcl_addr, s1));
- start_vif2(vifi);
- } else log(LOG_INFO, 0,
- "%s is not yet up; vif #%u not in service",
- v->uv_name, vifi);
- }
- }
-}
-
-/*
- * Start routing on all virtual interfaces that are not down or
- * administratively disabled.
- */
-void
-init_installvifs()
-{
- vifi_t vifi;
- struct uvif *v;
-
- log(LOG_INFO, 0, "Installing vifs in kernel...");
- for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
- if (!(v->uv_flags & VIFF_DISABLED)) {
- if (!(v->uv_flags & VIFF_DOWN)) {
- if (v->uv_flags & VIFF_TUNNEL)
- log(LOG_INFO, 0, "vif #%d, tunnel %s -> %s", vifi,
- inet_fmt(v->uv_lcl_addr, s1),
- inet_fmt(v->uv_rmt_addr, s2));
- else
- log(LOG_INFO, 0, "vif #%d, phyint %s", vifi,
- inet_fmt(v->uv_lcl_addr, s1));
- k_add_vif(vifi, &uvifs[vifi]);
- } else log(LOG_INFO, 0,
- "%s is not yet up; vif #%u not in service",
- v->uv_name, vifi);
- }
- }
-}
-
-/*
- * 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;
-
- vifs_down = FALSE;
- for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
-
- if (v->uv_flags & VIFF_DISABLED) continue;
-
- strncpy(ifr.ifr_name, v->uv_name, IFNAMSIZ);
- if (ioctl(udp_socket, SIOCGIFFLAGS, (char *)&ifr) < 0)
- log(LOG_ERR, errno,
- "ioctl SIOCGIFFLAGS for %s", ifr.ifr_name);
-
- if (v->uv_flags & VIFF_DOWN) {
- if (ifr.ifr_flags & IFF_UP) {
- v->uv_flags &= ~VIFF_DOWN;
- start_vif(vifi);
- log(LOG_INFO, 0,
- "%s has come up; vif #%u now in service",
- v->uv_name, vifi);
- }
- else vifs_down = TRUE;
- }
- else {
- if (!(ifr.ifr_flags & IFF_UP)) {
- stop_vif(vifi);
- v->uv_flags |= VIFF_DOWN;
- log(LOG_INFO, 0,
- "%s has gone down; vif #%u taken out of service",
- v->uv_name, vifi);
- vifs_down = TRUE;
- }
- }
- }
-}
-
-/*
- * Send a probe message on vif v
- */
-static void
-send_probe_on_vif(v)
- register struct uvif *v;
-{
- register char *p;
- register int datalen = 0;
- struct listaddr *nbr;
- int i;
-
- p = send_buf + MIN_IP_HEADER_LEN + IGMP_MINLEN;
-
- for (i = 0; i < 4; i++)
- *p++ = ((char *)&(dvmrp_genid))[i];
- datalen += 4;
-
- /*
- * add the neighbor list on the interface to the message
- */
- nbr = v->uv_neighbors;
-
- while (nbr) {
- for (i = 0; i < 4; i++)
- *p++ = ((char *)&nbr->al_addr)[i];
- datalen +=4;
- nbr = nbr->al_next;
- }
-
- send_igmp(v->uv_lcl_addr,
- (v->uv_flags & VIFF_TUNNEL) ? v->uv_rmt_addr
- : dvmrp_group,
- IGMP_DVMRP, DVMRP_PROBE,
- htonl(MROUTED_LEVEL |
- ((v->uv_flags & VIFF_LEAF) ? 0 : LEAF_FLAGS)),
- datalen);
-}
-
-/*
- * Add a vifi to the kernel and start routing on it.
- */
-static void
-start_vif(vifi)
- vifi_t vifi;
-{
- /*
- * Install the interface in the kernel's vif structure.
- */
- k_add_vif(vifi, &uvifs[vifi]);
-
- start_vif2(vifi);
-}
-
-/*
- * Add a vifi to all the user-level data structures but don't add
- * it to the kernel yet.
- */
-static void
-start_vif2(vifi)
- vifi_t vifi;
-{
- struct uvif *v;
- u_int32 src;
- struct phaddr *p;
-
- v = &uvifs[vifi];
- src = v->uv_lcl_addr;
-
- /*
- * Update the existing route entries to take into account the new vif.
- */
- add_vif_to_routes(vifi);
-
- if (!(v->uv_flags & VIFF_TUNNEL)) {
- /*
- * Join the DVMRP multicast group on the interface.
- * (This is not strictly necessary, since the kernel promiscuously
- * receives IGMP packets addressed to ANY IP multicast group while
- * multicast routing is enabled. However, joining the group allows
- * this host to receive non-IGMP packets as well, such as 'pings'.)
- */
- k_join(dvmrp_group, src);
-
- /*
- * 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(allrtrs_group, src);
-
- /*
- * Install an entry in the routing table for the subnet to which
- * the interface is connected.
- */
- start_route_updates();
- update_route(v->uv_subnet, v->uv_subnetmask, 0, 0, vifi);
- for (p = v->uv_addrs; p; p = p->pa_next) {
- start_route_updates();
- update_route(p->pa_subnet, p->pa_subnetmask, 0, 0, vifi);
- }
-
- /*
- * Until neighbors are discovered, assume responsibility for sending
- * periodic group membership queries to the subnet. Send the first
- * query.
- */
- v->uv_flags |= VIFF_QUERIER;
- send_igmp(src, allhosts_group, IGMP_HOST_MEMBERSHIP_QUERY,
- (v->uv_flags & VIFF_IGMPV1) ? 0 :
- IGMP_MAX_HOST_REPORT_DELAY * IGMP_TIMER_SCALE, 0, 0);
- age_old_hosts();
- }
-
- v->uv_leaf_timer = LEAF_CONFIRMATION_TIME;
-
- /*
- * Send a probe via the new vif to look for neighbors.
- */
- send_probe_on_vif(v);
-}
-
-/*
- * Stop routing on the specified virtual interface.
- */
-static void
-stop_vif(vifi)
- vifi_t vifi;
-{
- struct uvif *v;
- struct listaddr *a;
- struct phaddr *p;
-
- v = &uvifs[vifi];
-
- if (!(v->uv_flags & VIFF_TUNNEL)) {
- /*
- * Depart from the DVMRP multicast group on the interface.
- */
- k_leave(dvmrp_group, v->uv_lcl_addr);
-
- /*
- * Depart from the ALL-ROUTERS multicast group on the interface.
- */
- k_leave(allrtrs_group, v->uv_lcl_addr);
-
- /*
- * Update the entry in the routing table for the subnet to which
- * the interface is connected, to take into account the interface
- * failure.
- */
- start_route_updates();
- update_route(v->uv_subnet, v->uv_subnetmask, UNREACHABLE, 0, vifi);
- for (p = v->uv_addrs; p; p = p->pa_next) {
- start_route_updates();
- update_route(p->pa_subnet, p->pa_subnetmask, UNREACHABLE, 0, vifi);
- }
-
- /*
- * Discard all group addresses. (No need to tell kernel;
- * the k_del_vif() call, below, will clean up kernel state.)
- */
- while (v->uv_groups != NULL) {
- a = v->uv_groups;
- v->uv_groups = a->al_next;
- free((char *)a);
- }
-
- v->uv_flags &= ~VIFF_QUERIER;
- }
-
- /*
- * Update the existing route entries to take into account the vif failure.
- */
- delete_vif_from_routes(vifi);
-
- /*
- * Delete the interface from the kernel's vif structure.
- */
- k_del_vif(vifi);
-
- /*
- * Discard all neighbor addresses.
- */
- if (v->uv_neighbors)
- vifs_with_neighbors--;
-
- while (v->uv_neighbors != NULL) {
- a = v->uv_neighbors;
- v->uv_neighbors = a->al_next;
- free((char *)a);
- }
-}
-
-
-/*
- * stop routing on all vifs
- */
-void
-stop_all_vifs()
-{
- vifi_t vifi;
- struct uvif *v;
- struct listaddr *a;
- struct vif_acl *acl;
-
- for (vifi = 0; vifi < numvifs; vifi++) {
- v = &uvifs[vifi];
- while (v->uv_groups != NULL) {
- a = v->uv_groups;
- v->uv_groups = a->al_next;
- free((char *)a);
- }
- while (v->uv_neighbors != NULL) {
- a = v->uv_neighbors;
- v->uv_neighbors = a->al_next;
- free((char *)a);
- }
- while (v->uv_acl != NULL) {
- acl = v->uv_acl;
- v->uv_acl = acl->acl_next;
- free((char *)acl);
- }
- }
-}
-
-
-/*
- * Find the virtual interface from which an incoming packet arrived,
- * based on the packet's source and destination IP addresses.
- */
-vifi_t
-find_vif(src, dst)
- register u_int32 src;
- register u_int32 dst;
-{
- register 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_DOWN|VIFF_DISABLED))) {
- if (v->uv_flags & VIFF_TUNNEL) {
- if (src == v->uv_rmt_addr && dst == v->uv_lcl_addr)
- return(vifi);
- }
- else {
- if ((src & v->uv_subnetmask) == v->uv_subnet &&
- ((v->uv_subnetmask == 0xffffffff) ||
- (src != v->uv_subnetbcast)))
- return(vifi);
- for (p=v->uv_addrs; p; p=p->pa_next) {
- if ((src & p->pa_subnetmask) == p->pa_subnet &&
- ((p->pa_subnetmask == 0xffffffff) ||
- (src != p->pa_subnetbcast)))
- return(vifi);
- }
- }
- }
- }
- return (NO_VIF);
-}
-
-static void
-age_old_hosts()
-{
- register vifi_t vifi;
- register struct uvif *v;
- register struct listaddr *g;
-
- /*
- * Decrement the old-hosts-present timer for each
- * active group on each vif.
- */
- for (vifi = 0, v = uvifs; vifi < numvifs; vifi++, v++)
- for (g = v->uv_groups; g != NULL; g = g->al_next)
- if (g->al_old)
- g->al_old--;
-}
-
-
-/*
- * Send group membership queries to all subnets for which I am querier.
- */
-void
-query_groups()
-{
- register vifi_t vifi;
- register struct uvif *v;
-
- for (vifi = 0, v = uvifs; vifi < numvifs; vifi++, v++) {
- if (v->uv_flags & VIFF_QUERIER) {
- send_igmp(v->uv_lcl_addr, allhosts_group,
- IGMP_HOST_MEMBERSHIP_QUERY,
- (v->uv_flags & VIFF_IGMPV1) ? 0 :
- IGMP_MAX_HOST_REPORT_DELAY * IGMP_TIMER_SCALE, 0, 0);
- }
- }
- age_old_hosts();
-}
-
-/*
- * Process an incoming host membership query
- */
-void
-accept_membership_query(src, dst, group, tmo)
- u_int32 src, dst, group;
- int tmo;
-{
- register vifi_t vifi;
- register struct uvif *v;
-
- if ((vifi = find_vif(src, dst)) == NO_VIF ||
- (uvifs[vifi].uv_flags & VIFF_TUNNEL)) {
- log(LOG_INFO, 0,
- "ignoring group membership query from non-adjacent host %s",
- inet_fmt(src, s1));
- return;
- }
-
- v = &uvifs[vifi];
-
- /*
- * If we consider ourselves the querier for this vif, but hear a
- * query from a router with a lower IP address, yield to them.
- *
- * This is done here as well as in the neighbor discovery in case
- * there is a querier that doesn't speak DVMRP.
- *
- * XXX If this neighbor doesn't speak DVMRP, then we need to create
- * some neighbor state for him so that we can time him out!
- */
- if ((v->uv_flags & VIFF_QUERIER) &&
- (ntohl(src) < ntohl(v->uv_lcl_addr))) {
- v->uv_flags &= ~VIFF_QUERIER;
-
- }
-}
-
-/*
- * Process an incoming group membership report.
- */
-void
-accept_group_report(src, dst, group, r_type)
- u_int32 src, dst, group;
- int r_type;
-{
- register vifi_t vifi;
- register struct uvif *v;
- register struct listaddr *g;
-
- if ((vifi = find_vif(src, dst)) == NO_VIF ||
- (uvifs[vifi].uv_flags & VIFF_TUNNEL)) {
- log(LOG_INFO, 0,
- "ignoring group membership report from non-adjacent host %s",
- inet_fmt(src, s1));
- return;
- }
-
- v = &uvifs[vifi];
-
- /*
- * Look for the group in our group list; if found, reset its timer.
- */
- for (g = v->uv_groups; g != NULL; g = g->al_next) {
- if (group == g->al_addr) {
- if (r_type == IGMP_HOST_MEMBERSHIP_REPORT)
- g->al_old = OLD_AGE_THRESHOLD;
-#ifdef SNMP
- g->al_genid = src;
-#endif /* SNMP */
-
- /** delete old timers, set a timer for expiration **/
- g->al_timer = GROUP_EXPIRE_TIME;
- 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(vifi, g);
- 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;
- if (r_type == IGMP_HOST_NEW_MEMBERSHIP_REPORT)
- g->al_old = 0;
- else
- g->al_old = OLD_AGE_THRESHOLD;
-#ifdef SNMP
- g->al_genid = src;
-#endif
-
- /** set a timer for expiration **/
- g->al_query = 0;
- g->al_timer = GROUP_EXPIRE_TIME;
- time(&g->al_ctime);
- g->al_timerid = SetTimer(vifi, g);
- g->al_next = v->uv_groups;
- v->uv_groups = g;
-
- update_lclgrp(vifi, group);
- }
-
- /*
- * Check if a graft is necessary for this group
- */
- chkgrp_graft(vifi, group);
-}
-
-
-void
-accept_leave_message(src, dst, group)
- u_int32 src, dst, group;
-{
- register vifi_t vifi;
- register struct uvif *v;
- register struct listaddr *g;
-
- if ((vifi = find_vif(src, dst)) == NO_VIF ||
- (uvifs[vifi].uv_flags & VIFF_TUNNEL)) {
- log(LOG_INFO, 0,
- "ignoring group leave report from non-adjacent host %s",
- inet_fmt(src, s1));
- return;
- }
-
- v = &uvifs[vifi];
-
- if (!(v->uv_flags & VIFF_QUERIER) || (v->uv_flags & VIFF_IGMPV1))
- return;
-
- /*
- * Look for the group in our group list in order to set up a short-timeout
- * query.
- */
- for (g = v->uv_groups; g != NULL; g = g->al_next) {
- if (group == g->al_addr) {
- log(LOG_DEBUG, 0,
- "[vif.c, _accept_leave_message] %d %d \n",
- g->al_old, g->al_query);
-
- /* Ignore the leave message if there are old hosts present */
- if (g->al_old)
- return;
-
- /* still waiting for a reply to a query, ignore the leave */
- 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 = LEAVE_EXPIRE_TIME;
- send_igmp(v->uv_lcl_addr, g->al_addr,
- IGMP_HOST_MEMBERSHIP_QUERY,
- LEAVE_EXPIRE_TIME / 3 * IGMP_TIMER_SCALE,
- g->al_addr, 0);
- g->al_query = SetQueryTimer(g, vifi, g->al_timer / 3,
- LEAVE_EXPIRE_TIME / 3 * IGMP_TIMER_SCALE);
- g->al_timerid = SetTimer(vifi, g);
- break;
- }
- }
-}
-
-
-/*
- * Send a periodic probe on all vifs.
- * Useful to determine one-way interfaces.
- * Detect neighbor loss faster.
- */
-void
-probe_for_neighbors()
-{
- register vifi_t vifi;
- register struct uvif *v;
-
- for (vifi = 0, v = uvifs; vifi < numvifs; vifi++, v++) {
- if (!(v->uv_flags & (VIFF_DOWN|VIFF_DISABLED))) {
- send_probe_on_vif(v);
- }
- }
-}
-
-
-/*
- * Send a list of all of our neighbors to the requestor, `src'.
- */
-void
-accept_neighbor_request(src, dst)
- u_int32 src, dst;
-{
- vifi_t vifi;
- struct uvif *v;
- u_char *p, *ncount;
- struct listaddr *la;
- int datalen;
- u_int32 temp_addr, us, them = src;
-
- /* Determine which of our addresses to use as the source of our response
- * to this query.
- */
- if (IN_MULTICAST(ntohl(dst))) { /* query sent to a multicast group */
- int udp; /* find best interface to reply on */
- struct sockaddr_in addr;
- int addrlen = sizeof(addr);
-
- addr.sin_family = AF_INET;
-#if (defined(BSD) && (BSD >= 199103))
- addr.sin_len = sizeof addr;
-#endif
- addr.sin_addr.s_addr = dst;
- addr.sin_port = htons(2000); /* any port over 1024 will do... */
- if ((udp = socket(AF_INET, SOCK_DGRAM, 0)) < 0
- || connect(udp, (struct sockaddr *) &addr, sizeof(addr)) < 0
- || getsockname(udp, (struct sockaddr *) &addr, &addrlen) < 0) {
- log(LOG_WARNING, errno, "Determining local address");
- close(udp);
- return;
- }
- close(udp);
- us = addr.sin_addr.s_addr;
- } else /* query sent to us alone */
- us = dst;
-
-#define PUT_ADDR(a) temp_addr = ntohl(a); \
- *p++ = temp_addr >> 24; \
- *p++ = (temp_addr >> 16) & 0xFF; \
- *p++ = (temp_addr >> 8) & 0xFF; \
- *p++ = temp_addr & 0xFF;
-
- p = (u_char *) (send_buf + MIN_IP_HEADER_LEN + IGMP_MINLEN);
- datalen = 0;
-
- for (vifi = 0, v = uvifs; vifi < numvifs; vifi++, v++) {
- if (v->uv_flags & VIFF_DISABLED)
- continue;
-
- ncount = 0;
-
- for (la = v->uv_neighbors; la; la = la->al_next) {
-
- /* Make sure that there's room for this neighbor... */
- if (datalen + (ncount == 0 ? 4 + 3 + 4 : 4) > MAX_DVMRP_DATA_LEN) {
- send_igmp(us, them, IGMP_DVMRP, DVMRP_NEIGHBORS,
- htonl(MROUTED_LEVEL), datalen);
- p = (u_char *) (send_buf + MIN_IP_HEADER_LEN + IGMP_MINLEN);
- datalen = 0;
- ncount = 0;
- }
-
- /* Put out the header for this neighbor list... */
- if (ncount == 0) {
- PUT_ADDR(v->uv_lcl_addr);
- *p++ = v->uv_metric;
- *p++ = v->uv_threshold;
- ncount = p;
- *p++ = 0;
- datalen += 4 + 3;
- }
-
- PUT_ADDR(la->al_addr);
- datalen += 4;
- (*ncount)++;
- }
- }
-
- if (datalen != 0)
- send_igmp(us, them, IGMP_DVMRP, DVMRP_NEIGHBORS, htonl(MROUTED_LEVEL),
- datalen);
-}
-
-/*
- * Send a list of all of our neighbors to the requestor, `src'.
- */
-void
-accept_neighbor_request2(src, dst)
- u_int32 src, dst;
-{
- vifi_t vifi;
- struct uvif *v;
- u_char *p, *ncount;
- struct listaddr *la;
- int datalen;
- u_int32 us, them = src;
-
- /* Determine which of our addresses to use as the source of our response
- * to this query.
- */
- if (IN_MULTICAST(ntohl(dst))) { /* query sent to a multicast group */
- int udp; /* find best interface to reply on */
- struct sockaddr_in addr;
- int addrlen = sizeof(addr);
-
- addr.sin_family = AF_INET;
-#if (defined(BSD) && (BSD >= 199103))
- addr.sin_len = sizeof addr;
-#endif
- addr.sin_addr.s_addr = dst;
- addr.sin_port = htons(2000); /* any port over 1024 will do... */
- if ((udp = socket(AF_INET, SOCK_DGRAM, 0)) < 0
- || connect(udp, (struct sockaddr *) &addr, sizeof(addr)) < 0
- || getsockname(udp, (struct sockaddr *) &addr, &addrlen) < 0) {
- log(LOG_WARNING, errno, "Determining local address");
- close(udp);
- return;
- }
- close(udp);
- us = addr.sin_addr.s_addr;
- } else /* query sent to us alone */
- us = dst;
-
- p = (u_char *) (send_buf + MIN_IP_HEADER_LEN + IGMP_MINLEN);
- datalen = 0;
-
- for (vifi = 0, v = uvifs; vifi < numvifs; vifi++, v++) {
- register u_short vflags = v->uv_flags;
- register u_char rflags = 0;
- if (vflags & VIFF_TUNNEL)
- rflags |= DVMRP_NF_TUNNEL;
- if (vflags & VIFF_SRCRT)
- rflags |= DVMRP_NF_SRCRT;
- if (vflags & VIFF_DOWN)
- rflags |= DVMRP_NF_DOWN;
- if (vflags & VIFF_DISABLED)
- rflags |= DVMRP_NF_DISABLED;
- if (vflags & VIFF_QUERIER)
- rflags |= DVMRP_NF_QUERIER;
- if (vflags & VIFF_LEAF)
- rflags |= DVMRP_NF_LEAF;
- ncount = 0;
- la = v->uv_neighbors;
- if (la == NULL) {
- /*
- * include down & disabled interfaces and interfaces on
- * leaf nets.
- */
- if (rflags & DVMRP_NF_TUNNEL)
- rflags |= DVMRP_NF_DOWN;
- if (datalen > MAX_DVMRP_DATA_LEN - 12) {
- send_igmp(us, them, IGMP_DVMRP, DVMRP_NEIGHBORS2,
- htonl(MROUTED_LEVEL), datalen);
- p = (u_char *) (send_buf + MIN_IP_HEADER_LEN + IGMP_MINLEN);
- datalen = 0;
- }
- *(u_int*)p = v->uv_lcl_addr;
- p += 4;
- *p++ = v->uv_metric;
- *p++ = v->uv_threshold;
- *p++ = rflags;
- *p++ = 1;
- *(u_int*)p = v->uv_rmt_addr;
- p += 4;
- datalen += 12;
- } else {
- for ( ; la; la = la->al_next) {
- /* Make sure that there's room for this neighbor... */
- if (datalen + (ncount == 0 ? 4+4+4 : 4) > MAX_DVMRP_DATA_LEN) {
- send_igmp(us, them, IGMP_DVMRP, DVMRP_NEIGHBORS2,
- htonl(MROUTED_LEVEL), datalen);
- p = (u_char *) (send_buf + MIN_IP_HEADER_LEN + IGMP_MINLEN);
- datalen = 0;
- ncount = 0;
- }
- /* Put out the header for this neighbor list... */
- if (ncount == 0) {
- *(u_int*)p = v->uv_lcl_addr;
- p += 4;
- *p++ = v->uv_metric;
- *p++ = v->uv_threshold;
- *p++ = rflags;
- ncount = p;
- *p++ = 0;
- datalen += 4 + 4;
- }
- *(u_int*)p = la->al_addr;
- p += 4;
- datalen += 4;
- (*ncount)++;
- }
- }
- }
- if (datalen != 0)
- send_igmp(us, them, IGMP_DVMRP, DVMRP_NEIGHBORS2, htonl(MROUTED_LEVEL),
- datalen);
-}
-
-void
-accept_info_request(src, dst, p, datalen)
- u_int32 src, dst;
- u_char *p;
- int datalen;
-{
- u_char *q;
- int len;
- int outlen = 0;
-
- q = (u_char *) (send_buf + MIN_IP_HEADER_LEN + IGMP_MINLEN);
-
- /* To be general, this must deal properly with breaking up over-sized
- * packets. That implies passing a length to each function, and
- * allowing each function to request to be called again. Right now,
- * we're only implementing the one thing we are positive will fit into
- * a single packet, so we wimp out.
- */
- while (datalen > 0) {
- len = 0;
- switch (*p) {
- case DVMRP_INFO_VERSION:
- len = info_version(q);
- break;
-
- case DVMRP_INFO_NEIGHBORS:
- default:
- log(LOG_INFO, 0, "ignoring unknown info type %d", *p);
- break;
- }
- *(q+1) = len++;
- outlen += len * 4;
- q += len * 4;
- len = (*(p+1) + 1) * 4;
- p += len;
- datalen -= len;
- }
-
- if (outlen != 0)
- send_igmp(INADDR_ANY, src, IGMP_DVMRP, DVMRP_INFO_REPLY,
- htonl(MROUTED_LEVEL), outlen);
-}
-
-/*
- * Information response -- return version string
- */
-static int
-info_version(p)
- char *p;
-{
- int len;
- extern char versionstring[];
-
- *p++ = DVMRP_INFO_VERSION;
- p++; /* skip over length */
- *p++ = 0; /* zero out */
- *p++ = 0; /* reserved fields */
- strcpy(p, versionstring); /* XXX strncpy!!! */
-
- len = strlen(versionstring);
- return ((len + 3) / 4);
-}
-
-/*
- * Process an incoming neighbor-list message.
- */
-void
-accept_neighbors(src, dst, p, datalen, level)
- u_int32 src, dst, level;
- u_char *p;
- int datalen;
-{
- log(LOG_INFO, 0, "ignoring spurious DVMRP neighbor list from %s to %s",
- inet_fmt(src, s1), inet_fmt(dst, s2));
-}
-
-
-/*
- * Process an incoming neighbor-list message.
- */
-void
-accept_neighbors2(src, dst, p, datalen, level)
- u_int32 src, dst, level;
- u_char *p;
- int datalen;
-{
- log(LOG_INFO, 0, "ignoring spurious DVMRP neighbor list2 from %s to %s",
- inet_fmt(src, s1), inet_fmt(dst, s2));
-}
-
-/*
- * Process an incoming info reply message.
- */
-void
-accept_info_reply(src, dst, p, datalen)
- u_int32 src, dst;
- u_char *p;
- int datalen;
-{
- log(LOG_INFO, 0, "ignoring spurious DVMRP info reply from %s to %s",
- inet_fmt(src, s1), inet_fmt(dst, s2));
-}
-
-
-/*
- * Update the neighbor entry for neighbor 'addr' on vif 'vifi'.
- * 'msgtype' is the type of DVMRP message received from the neighbor.
- * Return TRUE if 'addr' is a valid neighbor, FALSE otherwise.
- */
-int
-update_neighbor(vifi, addr, msgtype, p, datalen, level)
- vifi_t vifi;
- u_int32 addr;
- int msgtype;
- char *p;
- int datalen;
- u_int32 level;
-{
- register struct uvif *v;
- register struct listaddr *n;
- u_int32 genid = 0;
- u_int32 router;
- u_int32 send_tables = 0;
- int do_reset = FALSE;
- int nflags;
-
- v = &uvifs[vifi];
- nflags = (level >> 16) & 0xff;
-
- /*
- * Confirm that 'addr' is a valid neighbor address on vif 'vifi'.
- * IT IS ASSUMED that this was preceded by a call to find_vif(), which
- * checks that 'addr' is either a valid remote tunnel endpoint or a
- * non-broadcast address belonging to a directly-connected subnet.
- * Therefore, here we check only that 'addr' is not our own address
- * (due to an impostor or erroneous loopback) or an address of the form
- * {subnet,0} ("the unknown host"). These checks are not performed in
- * find_vif() because those types of address are acceptable for some
- * types of IGMP message (such as group membership reports).
- */
- if (!(v->uv_flags & VIFF_TUNNEL) &&
- (addr == v->uv_lcl_addr ||
- addr == v->uv_subnet )) {
- log(LOG_WARNING, 0,
- "received DVMRP message from 'the unknown host' or self: %s",
- inet_fmt(addr, s1));
- return (FALSE);
- }
-
- /*
- * Look for addr in list of neighbors.
- */
- for (n = v->uv_neighbors; n != NULL; n = n->al_next) {
- if (addr == n->al_addr) {
- break;
- }
- }
-
- /*
- * Found it. Reset its timer, and check for a version change
- */
- if (n) {
- n->al_timer = 0;
-
- /*
- * update the neighbors version and protocol number
- * if changed => router went down and came up,
- * so take action immediately.
- */
- if ((n->al_pv != (level & 0xff)) ||
- (n->al_mv != ((level >> 8) & 0xff))) {
-
- do_reset = TRUE;
- log(LOG_DEBUG, 0,
- "version change neighbor %s [old:%d.%d, new:%d.%d]",
- inet_fmt(addr, s1),
- n->al_pv, n->al_mv, level&0xff, (level >> 8) & 0xff);
-
- n->al_pv = level & 0xff;
- n->al_mv = (level >> 8) & 0xff;
- }
- } else {
- /*
- * If not found, add it to the list. If the neighbor has a lower
- * IP address than me, yield querier duties to it.
- */
- log(LOG_DEBUG, 0, "New neighbor %s on vif %d v%d.%d nf 0x%02x",
- inet_fmt(addr, s1), vifi, level & 0xff, (level >> 8) & 0xff,
- (level >> 16) & 0xff);
-
- n = (struct listaddr *)malloc(sizeof(struct listaddr));
- if (n == NULL)
- log(LOG_ERR, 0, "ran out of memory"); /* fatal */
-
- n->al_addr = addr;
- n->al_pv = level & 0xff;
- n->al_mv = (level >> 8) & 0xff;
- n->al_genid = 0;
-
- time(&n->al_ctime);
- n->al_timer = 0;
- n->al_next = v->uv_neighbors;
-
- /*
- * If we thought that we had no neighbors on this vif, send a route
- * report to the vif. If this is just a new neighbor on the same
- * vif, send the route report just to the new neighbor.
- */
- if (v->uv_neighbors == NULL) {
- send_tables = (v->uv_flags & VIFF_TUNNEL) ? addr : dvmrp_group;
- vifs_with_neighbors++;
- } else {
- send_tables = addr;
- }
-
- v->uv_neighbors = n;
-
- if (!(v->uv_flags & VIFF_TUNNEL) &&
- ntohl(addr) < ntohl(v->uv_lcl_addr))
- v->uv_flags &= ~VIFF_QUERIER;
- }
-
- /*
- * Check if the router gen-ids are the same.
- * Need to reset the prune state of the router if not.
- * Also check for one-way interfaces by seeing if we are in our
- * neighbor's list of known routers.
- */
- if (msgtype == DVMRP_PROBE) {
-
- /* Check genid neighbor flag. Also check version number; 3.3 and
- * 3.4 didn't set this flag. */
- if ((((level >> 16) & 0xff) & NF_GENID) ||
- (((level & 0xff) == 3) && (((level >> 8) & 0xff) > 2))) {
-
- int i;
-
- if (datalen < 4) {
- log(LOG_WARNING, 0,
- "received truncated probe message from %s (len %d)",
- inet_fmt(addr, s1), datalen);
- return (FALSE);
- }
-
- for (i = 0; i < 4; i++)
- ((char *)&genid)[i] = *p++;
- datalen -= 4;
-
- if (n->al_genid == 0)
- n->al_genid = genid;
- else if (n->al_genid != genid) {
- log(LOG_DEBUG, 0,
- "new genid neigbor %s on vif %d [old:%x, new:%x]",
- inet_fmt(addr, s1), vifi, n->al_genid, genid);
-
- n->al_genid = genid;
- do_reset = TRUE;
- }
-
- /*
- * loop through router list and check for one-way ifs.
- */
-
- v->uv_flags |= VIFF_ONEWAY;
-
- while (datalen > 0) {
- if (datalen < 4) {
- log(LOG_WARNING, 0,
- "received truncated probe message from %s (len %d)",
- inet_fmt(addr, s1), datalen);
- return (FALSE);
- }
- for (i = 0; i < 4; i++)
- ((char *)&router)[i] = *p++;
- datalen -= 4;
- if (router == v->uv_lcl_addr) {
- v->uv_flags &= ~VIFF_ONEWAY;
- break;
- }
- }
- }
- }
- if (n->al_flags != nflags) {
- n->al_flags = nflags;
-
- if (n->al_flags & NF_LEAF) {
- /*XXX If we have non-leaf neighbors then we know we shouldn't
- * mark this vif as a leaf. For now we just count on other
- * probes and/or reports resetting the timer. */
- if (!v->uv_leaf_timer)
- v->uv_leaf_timer = LEAF_CONFIRMATION_TIME;
- } else {
- /* If we get a leaf to non-leaf transition, we *must* update
- * the routing table. */
- if (v->uv_flags & VIFF_LEAF && send_tables == 0)
- send_tables = addr;
- v->uv_flags &= ~VIFF_LEAF;
- v->uv_leaf_timer = 0;
- }
- }
- if (do_reset) {
- reset_neighbor_state(vifi, addr);
- if (!send_tables)
- send_tables = addr;
- }
- if (send_tables)
- report(ALL_ROUTES, vifi, send_tables);
-
- return (TRUE);
-}
-
-
-/*
- * On every timer interrupt, advance the timer in each neighbor and
- * group entry on every vif.
- */
-void
-age_vifs()
-{
- register vifi_t vifi;
- register struct uvif *v;
- register struct listaddr *a, *prev_a, *n;
- register u_int32 addr;
-
- for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v ) {
- if (v->uv_leaf_timer && (v->uv_leaf_timer -= TIMER_INTERVAL == 0)) {
- v->uv_flags |= VIFF_LEAF;
- }
-
- for (prev_a = (struct listaddr *)&(v->uv_neighbors),
- a = v->uv_neighbors;
- a != NULL;
- prev_a = a, a = a->al_next) {
-
- if ((a->al_timer += TIMER_INTERVAL) < NEIGHBOR_EXPIRE_TIME)
- continue;
-
- /*
- * Neighbor has expired; delete it from the neighbor list,
- * delete it from the 'dominants' and 'subordinates arrays of
- * any route entries and assume querier duties unless there is
- * another neighbor with a lower IP address than mine.
- */
- addr = a->al_addr;
- prev_a->al_next = a->al_next;
- free((char *)a);
- a = prev_a;
-
- delete_neighbor_from_routes(addr, vifi);
-
- if (v->uv_neighbors == NULL)
- vifs_with_neighbors--;
-
- v->uv_leaf_timer = LEAF_CONFIRMATION_TIME;
-
- if (!(v->uv_flags & VIFF_TUNNEL)) {
- v->uv_flags |= VIFF_QUERIER;
- for (n = v->uv_neighbors; n != NULL; n = n->al_next) {
- if (ntohl(n->al_addr) < ntohl(v->uv_lcl_addr)) {
- v->uv_flags &= ~VIFF_QUERIER;
- }
- if (!(n->al_flags & NF_LEAF)) {
- v->uv_leaf_timer = 0;
- }
- }
- }
- }
- }
-}
-
-/*
- * Returns the neighbor info struct for a given neighbor
- */
-struct listaddr *
-neighbor_info(vifi, addr)
- vifi_t vifi;
- u_int32 addr;
-{
- struct listaddr *u;
-
- for (u = uvifs[vifi].uv_neighbors; u; u = u->al_next)
- if (u->al_addr == addr)
- return u;
-
- return NULL;
-}
-
-/*
- * Print the contents of the uvifs array on file 'fp'.
- */
-void
-dump_vifs(fp)
- FILE *fp;
-{
- register vifi_t vifi;
- register struct uvif *v;
- register struct listaddr *a;
- register struct phaddr *p;
- struct sioc_vif_req v_req;
-
- fprintf(fp, "vifs_with_neighbors = %d\n", vifs_with_neighbors);
-
- if (vifs_with_neighbors == 1)
- fprintf(fp,"[This host is a leaf]\n\n");
-
- fprintf(fp,
- "\nVirtual Interface Table\n%s",
- "Vif Name Local-Address ");
- fprintf(fp,
- "M Thr Rate Flags\n");
-
- for (vifi = 0, v = uvifs; vifi < numvifs; vifi++, v++) {
-
- fprintf(fp, "%2u %6s %-15s %6s: %-18s %2u %3u %5u ",
- vifi,
- v->uv_name,
- inet_fmt(v->uv_lcl_addr, s1),
- (v->uv_flags & VIFF_TUNNEL) ?
- "tunnel":
- "subnet",
- (v->uv_flags & VIFF_TUNNEL) ?
- inet_fmt(v->uv_rmt_addr, s2) :
- inet_fmts(v->uv_subnet, v->uv_subnetmask, s3),
- v->uv_metric,
- v->uv_threshold,
- v->uv_rate_limit);
-
- if (v->uv_flags & VIFF_ONEWAY) fprintf(fp, " one-way");
- if (v->uv_flags & VIFF_DOWN) fprintf(fp, " down");
- if (v->uv_flags & VIFF_DISABLED) fprintf(fp, " disabled");
- if (v->uv_flags & VIFF_QUERIER) fprintf(fp, " querier");
- if (v->uv_flags & VIFF_SRCRT) fprintf(fp, " src-rt");
- if (v->uv_flags & VIFF_LEAF) fprintf(fp, " leaf");
- if (v->uv_flags & VIFF_IGMPV1) fprintf(fp, " IGMPv1");
- fprintf(fp, "\n");
-
- if (v->uv_addrs != NULL) {
- fprintf(fp, " alternate subnets: %s\n",
- inet_fmts(v->uv_addrs->pa_subnet, v->uv_addrs->pa_subnetmask, s1));
- for (p = v->uv_addrs->pa_next; p; p = p->pa_next) {
- fprintf(fp, " %s\n",
- inet_fmts(p->pa_subnet, p->pa_subnetmask, s1));
- }
- }
-
- if (v->uv_neighbors != NULL) {
- fprintf(fp, " peers: %s (%d.%d) (0x%x)\n",
- inet_fmt(v->uv_neighbors->al_addr, s1),
- v->uv_neighbors->al_pv, v->uv_neighbors->al_mv,
- v->uv_neighbors->al_flags);
- for (a = v->uv_neighbors->al_next; a != NULL; a = a->al_next) {
- fprintf(fp, " %s (%d.%d) (0x%x)\n",
- inet_fmt(a->al_addr, s1), a->al_pv, a->al_mv,
- a->al_flags);
- }
- }
-
- if (v->uv_groups != NULL) {
- fprintf(fp, " groups: %-15s\n",
- inet_fmt(v->uv_groups->al_addr, s1));
- for (a = v->uv_groups->al_next; a != NULL; a = a->al_next) {
- fprintf(fp, " %-15s\n",
- inet_fmt(a->al_addr, s1));
- }
- }
- if (v->uv_acl != NULL) {
- struct vif_acl *acl;
-
- fprintf(fp, " boundaries: %-18s\n",
- inet_fmts(v->uv_acl->acl_addr, v->uv_acl->acl_mask, s1));
- for (acl = v->uv_acl->acl_next; acl != NULL; acl = acl->acl_next) {
- fprintf(fp, " : %-18s\n",
- inet_fmts(acl->acl_addr, acl->acl_mask, s1));
- }
- }
- v_req.vifi = vifi;
- if (ioctl(udp_socket, SIOCGETVIFCNT, (char *)&v_req) < 0) {
- log(LOG_WARNING, 0,
- "SIOCGETVIFCNT fails");
- }
- else {
- fprintf(fp, " pkts in : %ld\n",
- v_req.icount);
- fprintf(fp, " pkts out: %ld\n",
- v_req.ocount);
- }
- fprintf(fp, "\n");
- }
- fprintf(fp, "\n");
-}
-
-/*
- * Time out record of a group membership on a vif
- */
-static void
-DelVif(arg)
- void *arg;
-{
- cbk_t *cbk = (cbk_t *)arg;
- vifi_t vifi = cbk->vifi;
- struct uvif *v = &uvifs[vifi];
- 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_lclgrp(vifi, 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(vifi, g)
- vifi_t vifi;
- struct listaddr *g;
-{
- cbk_t *cbk;
-
- cbk = (cbk_t *) malloc(sizeof(cbk_t));
- cbk->g = g;
- cbk->vifi = vifi;
- return timer_setTimer(g->al_timer, (cfunc_t)DelVif, (void *)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->vifi];
-
- send_igmp(v->uv_lcl_addr, cbk->g->al_addr,
- IGMP_HOST_MEMBERSHIP_QUERY,
- cbk->q_time, cbk->g->al_addr, 0);
- cbk->g->al_query = 0;
- free(cbk);
-}
-
-/*
- * Set a timer to send a group-specific query.
- */
-static int
-SetQueryTimer(g, vifi, to_expire, q_time)
- struct listaddr *g;
- vifi_t vifi;
- int to_expire, q_time;
-{
- cbk_t *cbk;
-
- cbk = (cbk_t *) malloc(sizeof(cbk_t));
- cbk->g = g;
- cbk->q_time = q_time;
- cbk->vifi = vifi;
- return timer_setTimer(to_expire, (cfunc_t)SendQuery, (void *)cbk);
-}
diff --git a/usr.sbin/mrouted/vif.h b/usr.sbin/mrouted/vif.h
deleted file mode 100644
index 94f5f7a9ee7b..000000000000
--- a/usr.sbin/mrouted/vif.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * The mrouted program is covered by the license in the accompanying file
- * named "LICENSE". 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.
- *
- *
- * $Id: vif.h,v 3.8 1995/11/29 22:36:57 fenner Rel $
- */
-
-/*
- * User level Virtual Interface structure
- *
- * A "virtual interface" is either a physical, multicast-capable interface
- * (called a "phyint") or a virtual point-to-point link (called a "tunnel").
- * (Note: all addresses, subnet numbers and masks are kept in NETWORK order.)
- */
-struct uvif {
- u_short uv_flags; /* VIFF_ flags defined below */
- u_char uv_metric; /* cost of this vif */
- u_int uv_rate_limit; /* rate limit on this vif */
- u_char uv_threshold; /* min ttl required to forward on vif */
- u_int32 uv_lcl_addr; /* local address of this vif */
- u_int32 uv_rmt_addr; /* remote end-point addr (tunnels only) */
- u_int32 uv_subnet; /* subnet number (phyints only) */
- u_int32 uv_subnetmask; /* subnet mask (phyints only) */
- u_int32 uv_subnetbcast;/* subnet broadcast addr (phyints only) */
- char uv_name[IFNAMSIZ]; /* interface name */
- struct listaddr *uv_groups; /* list of local groups (phyints only) */
- struct listaddr *uv_neighbors; /* list of neighboring routers */
- 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 subnets on this vif */
-};
-
-#define VIFF_KERNEL_FLAGS (VIFF_TUNNEL|VIFF_SRCRT)
-#define VIFF_DOWN 0x0100 /* kernel state of interface */
-#define VIFF_DISABLED 0x0200 /* administratively disabled */
-#define VIFF_QUERIER 0x0400 /* I am the subnet's querier */
-#define VIFF_ONEWAY 0x0800 /* Maybe one way interface */
-#define VIFF_LEAF 0x1000 /* all neighbors are leaves */
-#define VIFF_IGMPV1 0x2000 /* Act as an IGMPv1 Router */
-
-struct phaddr {
- struct phaddr *pa_next;
- u_int32 pa_subnet; /* extra subnet */
- u_int32 pa_subnetmask; /* netmask of extra subnet */
- u_int32 pa_subnetbcast; /* broadcast of extra subnet */
-};
-
-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 listaddr {
- struct listaddr *al_next; /* link to next addr, MUST BE FIRST */
- u_int32 al_addr; /* local group or neighbor address */
- u_long al_timer; /* for timing out group or neighbor */
- time_t al_ctime; /* neighbor creation time */
- u_int32 al_genid; /* generation id for neighbor */
- u_char al_pv; /* router protocol version */
- u_char al_mv; /* router mrouted version */
- u_long al_timerid; /* returned by set timer */
- u_long al_query; /* second query in case of leave */
- u_short al_old; /* time since heard old report */
- u_char al_flags; /* flags related to this neighbor */
-};
-
-#define NF_LEAF 0x01 /* This neighbor is a leaf */
-#define NF_PRUNE 0x02 /* This neighbor understands prunes */
-#define NF_GENID 0x04 /* I supply genid & rtrlist in probe*/
-#define NF_MTRACE 0x08 /* I can understand mtrace requests */
-
-#define NO_VIF ((vifi_t)MAXVIFS) /* An invalid vif index */