summaryrefslogtreecommitdiff
path: root/gnu
diff options
context:
space:
mode:
authorwiz <wiz@NetBSD.org>2003-03-05 22:09:46 +0000
committerwiz <wiz@NetBSD.org>2003-03-05 22:09:46 +0000
commitd201ab97524d0dea49ef4e231fb7d075589b4aa9 (patch)
treeb88119ec6d6986a054b3dd358ae5a69b36b58555 /gnu
parent54ad96333df255c3f07add7859d4827eae487197 (diff)
Moved back to usr.sbin.
Diffstat (limited to 'gnu')
-rw-r--r--gnu/dist/map-mbone/map-mbone.891
-rw-r--r--gnu/dist/map-mbone/mapper.c974
-rw-r--r--gnu/dist/mrinfo/mrinfo.885
-rw-r--r--gnu/dist/mrinfo/mrinfo.c600
-rw-r--r--gnu/dist/mrouted/LICENSE48
-rw-r--r--gnu/dist/mrouted/callout.c227
-rw-r--r--gnu/dist/mrouted/cfparse.y624
-rw-r--r--gnu/dist/mrouted/config.c121
-rw-r--r--gnu/dist/mrouted/defs.h304
-rw-r--r--gnu/dist/mrouted/dvmrp.h173
-rw-r--r--gnu/dist/mrouted/igmp.c351
-rw-r--r--gnu/dist/mrouted/inet.c223
-rw-r--r--gnu/dist/mrouted/kern.c224
-rw-r--r--gnu/dist/mrouted/main.c701
-rw-r--r--gnu/dist/mrouted/mrouted.8404
-rw-r--r--gnu/dist/mrouted/pathnames.h22
-rw-r--r--gnu/dist/mrouted/prune.c2234
-rw-r--r--gnu/dist/mrouted/prune.h150
-rw-r--r--gnu/dist/mrouted/route.c1129
-rw-r--r--gnu/dist/mrouted/route.h50
-rw-r--r--gnu/dist/mrouted/rsrr.c504
-rw-r--r--gnu/dist/mrouted/rsrr.h144
-rw-r--r--gnu/dist/mrouted/rsrr_var.h47
-rw-r--r--gnu/dist/mrouted/snmp.c1288
-rw-r--r--gnu/dist/mrouted/snmp.h9
-rw-r--r--gnu/dist/mrouted/vif.c1442
-rw-r--r--gnu/dist/mrouted/vif.h77
-rw-r--r--gnu/dist/mtrace/mtrace.8516
-rw-r--r--gnu/dist/mtrace/mtrace.c1758
-rw-r--r--gnu/usr.sbin/map-mbone/Makefile13
-rw-r--r--gnu/usr.sbin/mrinfo/Makefile15
-rw-r--r--gnu/usr.sbin/mrouted/Makefile17
-rw-r--r--gnu/usr.sbin/mtrace/Makefile16
33 files changed, 0 insertions, 14581 deletions
diff --git a/gnu/dist/map-mbone/map-mbone.8 b/gnu/dist/map-mbone/map-mbone.8
deleted file mode 100644
index 51ced7d0827..00000000000
--- a/gnu/dist/map-mbone/map-mbone.8
+++ /dev/null
@@ -1,91 +0,0 @@
-.\" $NetBSD: map-mbone.8,v 1.1 2002/10/01 03:50:08 itojun Exp $
-.\"
-.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/gnu/dist/map-mbone/mapper.c b/gnu/dist/map-mbone/mapper.c
deleted file mode 100644
index 124449241dc..00000000000
--- a/gnu/dist/map-mbone/mapper.c
+++ /dev/null
@@ -1,974 +0,0 @@
-/* $NetBSD: mapper.c,v 1.2 2002/12/06 16:01:14 thorpej Exp $ */
-
-/* Mapper for connections between MRouteD multicast routers.
- * Written by Pavel Curtis <Pavel@PARC.Xerox.Com>
- */
-
-/*
- * Copyright (c) 1992, 2001 Xerox Corporation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 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.
- *
- * Neither name of the Xerox, PARC, nor the names of its contributors may be used
- * to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 XEROX CORPORATION 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.
- */
-
-#include <string.h>
-#include <netdb.h>
-#include <sys/time.h>
-#include <poll.h>
-#include "defs.h"
-#include <arpa/inet.h>
-#include <stdarg.h>
-
-#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_t 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_t addr; /* IP address of the interface in NET order */
- Neighbor *neighbors; /* List of neighbors' IP addresses */
-} Interface;
-
-typedef struct node {
- u_int32_t addr; /* IP address of this entry in NET order */
- u_int32_t 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_t 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(u_int32_t addr, Node **ptr);
-Interface * find_interface(u_int32_t addr, Node *node);
-Neighbor * find_neighbor(u_int32_t addr, Node *node);
-int main(int argc, char *argv[]);
-void ask(u_int32_t dst);
-void ask2(u_int32_t dst);
-int retry_requests(Node *node);
-char * inet_name(u_int32_t addr);
-void print_map(Node *node);
-char * graph_name(u_int32_t addr, char *buf);
-void graph_edges(Node *node);
-void elide_aliases(Node *node);
-void graph_map(void);
-int get_number(int *var, int deflt, char ***pargv,
- int *pargc);
-u_int32_t host_addr(char *name);
-
-void logit(int severity, int syserr, const char *format, ...)
- __attribute__((__format__(__printf__, 3, 4)));
-
-Node *find_node(u_int32_t 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(u_int32_t 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(u_int32_t 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.
- */
-void
-logit(int severity, int syserr, const char *format, ...)
-{
- va_list ap;
- char fmt[100];
-
- 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);
- format = fmt;
- va_start(ap, format);
- vfprintf(stderr, format, ap);
- va_end(ap);
- if (syserr == 0)
- fprintf(stderr, "\n");
- else
- fprintf(stderr, ": %s\n", strerror(syserr));
- }
-
- if (severity <= LOG_ERR)
- exit(1);
-}
-
-
-/*
- * Send a neighbors-list request.
- */
-void ask(u_int32_t dst)
-{
- send_igmp(our_addr, dst, IGMP_DVMRP, DVMRP_ASK_NEIGHBORS,
- htonl(MROUTED_LEVEL), 0);
-}
-
-void ask2(u_int32_t 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(u_int32_t src, u_int32_t dst, u_int32_t group, int r_type)
-{
- logit(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(u_int32_t src, u_int32_t dst, char *p, int datalen,
- u_int32_t level)
-{
- logit(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(u_int32_t src, u_int32_t dst, char *p, int datalen,
- u_int32_t level)
-{
- logit(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(u_int32_t src, u_int32_t dst)
-{
- if (src != our_addr)
- logit(LOG_INFO, 0,
- "ignoring spurious DVMRP neighbor request from %s to %s",
- inet_fmt(src, s1), inet_fmt(dst, s2));
-}
-
-void accept_neighbor_request2(u_int32_t src, u_int32_t dst)
-{
- if (src != our_addr)
- logit(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(u_int32_t src, u_int32_t dst, u_char *p, int datalen,
- u_int32_t level)
-{
- 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_t)*p++ << 24), a += ((u_int32_t)*p++ << 16),\
- a += ((u_int32_t)*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_t ifc_addr;
- u_char metric, threshold, ncount;
- Node *ifc_node;
- Interface *ifc;
- Neighbor *old_neighbors;
-
- if (datalen < 4 + 3) {
- logit(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)
- logit(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_t neighbor;
- Neighbor *nb;
- Node *n_node;
-
- if (datalen < 4) {
- logit(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)
- logit(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(u_int32_t src, u_int32_t dst, u_char *p, int datalen,
- u_int32_t level)
-{
- 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_t ifc_addr;
- u_char metric, threshold, ncount, flags;
- Node *ifc_node;
- Interface *ifc;
- Neighbor *old_neighbors;
-
- if (datalen < 4 + 4) {
- logit(LOG_WARNING, 0, "received truncated interface record from %s",
- inet_fmt(src, s1));
- return;
- }
-
- ifc_addr = *(u_int32_t*)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)
- logit(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_t neighbor;
- Neighbor *nb;
- Node *n_node;
-
- if (datalen < 4) {
- logit(LOG_WARNING, 0, "received truncated neighbor list from %s",
- inet_fmt(src, s1));
- return;
- }
-
- neighbor = *(u_int32_t*)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)
- logit(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(void)
-{
- logit(LOG_NOTICE, 0, "network marked down...");
-}
-
-
-int retry_requests(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(u_int32_t addr)
-{
- struct hostent *e;
-
- e = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET);
-
- return e ? e->h_name : 0;
-}
-
-
-void print_map(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(u_int32_t 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)
-{
- 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)
-{
- 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(void)
-{
- 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(int *var, int deflt, char ***pargv, int *pargc)
-{
- 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_t host_addr(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(int argc, char **argv)
-{
- int flood = FALSE, graph = FALSE;
- struct pollfd set[1];
-
- 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);
-
- memset(&addr, 0, 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 */
- set[0].fd = igmp_socket;
- set[0].events = POLLIN;
- for(;;) {
- int count, recvlen, dummy = 0;
-
- count = poll(set, 1, timeout * 1000);
-
- if (count < 0) {
- if (errno != EINTR)
- perror("poll");
- continue;
- } else if (count == 0) {
- logit(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(u_int32_t src, u_int32_t dst, char *p, int datalen)
-{
-}
-void accept_graft(u_int32_t src, u_int32_t dst, char *p, int datalen)
-{
-}
-void accept_g_ack(u_int32_t src, u_int32_t dst, char *p, int datalen)
-{
-}
-void add_table_entry(u_int32_t origin, u_int32_t mcastgrp)
-{
-}
-void accept_leave_message(u_int32_t src, u_int32_t dst, u_int32_t group)
-{
-}
-void accept_mtrace(u_int32_t src, u_int32_t dst, u_int32_t group, char *data,
- u_int no, int datalen)
-{
-}
-void accept_membership_query(u_int32_t src, u_int32_t dst, u_int32_t group,
- int tmo)
-{
-}
-void accept_info_request(u_int32_t src, u_int32_t dst, u_char *p, int datalen)
-{
-}
-void accept_info_reply(u_int32_t src, u_int32_t dst, u_char *p, int datalen)
-{
-}
diff --git a/gnu/dist/mrinfo/mrinfo.8 b/gnu/dist/mrinfo/mrinfo.8
deleted file mode 100644
index dd1fb13e986..00000000000
--- a/gnu/dist/mrinfo/mrinfo.8
+++ /dev/null
@@ -1,85 +0,0 @@
-.\" $NetBSD: mrinfo.8,v 1.1 2002/10/01 03:50:09 itojun Exp $
-.\"
-.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 -\*[Gt] 0.0.0.0 (?) [1/1/querier]
- 127.148.176.10 -\*[Gt] 127.0.8.4 (mbone2.phony.dom.net) [1/45/tunnel]
- 127.148.176.10 -\*[Gt] 105.1.41.9 (momoney.com) [1/32/tunnel/down]
- 127.148.176.10 -\*[Gt] 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/gnu/dist/mrinfo/mrinfo.c b/gnu/dist/mrinfo/mrinfo.c
deleted file mode 100644
index ae5c5a30484..00000000000
--- a/gnu/dist/mrinfo/mrinfo.c
+++ /dev/null
@@ -1,600 +0,0 @@
-/* $NetBSD: mrinfo.c,v 1.2 2002/12/06 16:02:20 thorpej Exp $ */
-
-/*
- * 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) 1992, 2001 Xerox Corporation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 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.
-
- * Neither name of the Xerox, PARC, nor the names of its contributors may be used
- * to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 XEROX CORPORATION 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.
- */
-
-#include <sys/cdefs.h>
-#ifndef lint
-#if 0
-static char rcsid[] =
- "@(#) Header: mrinfo.c,v 1.6 93/04/08 15:14:16 van Exp (LBL)";
-#else
-__RCSID("$NetBSD: mrinfo.c,v 1.2 2002/12/06 16:02:20 thorpej Exp $");
-#endif
-#endif
-
-#include <string.h>
-#include <netdb.h>
-#include <sys/time.h>
-#include <poll.h>
-#include "defs.h"
-#include <arpa/inet.h>
-#include <stdarg.h>
-
-#define DEFAULT_TIMEOUT 4 /* How long to wait before retrying requests */
-#define DEFAULT_RETRIES 3 /* How many times to ask each router */
-
-u_int32_t 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(u_int32_t addr);
-void ask(u_int32_t dst);
-void ask2(u_int32_t dst);
-int get_number(int *var, int deflt, char ***pargv,
- int *pargc);
-u_int32_t host_addr(char *name);
-void usage(void);
-
-/* to shut up -Wstrict-prototypes */
-int main(int argc, char *argv[]);
-/* logit() prototyped in defs.h */
-
-
-char *
-inet_name(u_int32_t 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.
- */
-void
-logit(int severity, int syserr, const char *format, ...)
-{
- va_list ap;
-
- switch (debug) {
- case 0:
- if (severity > LOG_WARNING)
- return;
- case 1:
- if (severity > LOG_NOTICE)
- return;
- case 2:
- if (severity > LOG_INFO)
- return;
- default:
- if (severity == LOG_WARNING)
- fprintf(stderr, "warning - ");
- va_start(ap, format);
- vfprintf(stderr, format, ap);
- va_end(ap);
- if (syserr == 0)
- fprintf(stderr, "\n");
- else
- fprintf(stderr, ": %s\n", strerror(syserr));
- }
-
- if (severity <= LOG_ERR)
- exit(1);
-}
-
-/*
- * Send a neighbors-list request.
- */
-void
-ask(u_int32_t dst)
-{
- send_igmp(our_addr, dst, IGMP_DVMRP, DVMRP_ASK_NEIGHBORS,
- htonl(MROUTED_LEVEL), 0);
-}
-
-void
-ask2(u_int32_t dst)
-{
- send_igmp(our_addr, dst, IGMP_DVMRP, DVMRP_ASK_NEIGHBORS2,
- htonl(MROUTED_LEVEL), 0);
-}
-
-/*
- * Process an incoming neighbor-list message.
- */
-void
-accept_neighbors(u_int32_t src, u_int32_t dst, u_char *p, int datalen,
- u_int32_t level)
-{
- u_char *ep = p + datalen;
-#define GET_ADDR(a) (a = ((u_int32_t)*p++ << 24), a += ((u_int32_t)*p++ << 16),\
- a += ((u_int32_t)*p++ << 8), a += *p++)
-
- printf("%s (%s):\n", inet_fmt(src, s1), inet_name(src));
- while (p < ep) {
- u_int32_t laddr;
- u_char metric;
- u_char thresh;
- int ncount;
-
- GET_ADDR(laddr);
- laddr = htonl(laddr);
- metric = *p++;
- thresh = *p++;
- ncount = *p++;
- while (--ncount >= 0) {
- u_int32_t 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(u_int32_t src, u_int32_t dst, u_char *p, int datalen,
- u_int32_t level)
-{
- 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) {
- u_char metric;
- u_char thresh;
- u_char flags;
- int ncount;
- u_int32_t laddr = *(u_int32_t*)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) {
- u_int32_t neighbor = *(u_int32_t*)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(int *var, int deflt, char ***pargv, int *pargc)
-{
- 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(void)
-{
- fprintf(stderr,
- "Usage: mrinfo [-n] [-t timeout] [-r retries] [router]\n");
- exit(1);
-}
-
-int
-main(int argc, char *argv[])
-{
- int tries;
- int trynew;
- struct timeval et;
- struct hostent *hp;
- struct hostent bogus;
- char *host;
- int curaddr;
-
- if (geteuid() != 0) {
- fprintf(stderr, "mrinfo: must be root\n");
- exit(1);
- }
- init_igmp();
- if (setuid(getuid()) == -1)
- logit(LOG_ERR, errno, "setuid");
-
- setlinebuf(stderr);
-
- 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 *));
- if (hp->h_addr_list == NULL)
- logit(LOG_ERR, errno, "malloc");
- hp->h_addr_list[0] = malloc(hp->h_length);
- if (hp->h_addr_list[0] == NULL)
- logit(LOG_ERR, errno, "malloc");
- memcpy(hp->h_addr_list[0], &target_addr, sizeof(hp->h_addr_list[0]));
- hp->h_addr_list[1] = NULL;
- } else
- hp = gethostbyname(host);
-
- if (hp == NULL || hp->h_length != sizeof(target_addr)) {
- fprintf(stderr, "mrinfo: %s: no such host\n", argv[0]);
- exit(1);
- }
- if (debug)
- fprintf(stderr, "Debug level %u\n", debug);
-
- /* 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], sizeof(target_addr));
- { /* Find a good local address for us. */
- int udp;
- struct sockaddr_in addr;
- int addrlen = sizeof(addr);
-
- memset(&addr, 0, 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 (;;) {
- struct pollfd set[1];
- struct timeval tv, now;
- int count, recvlen, dummy = 0;
- u_int32_t src, dst, group;
- struct ip *ip;
- struct igmp *igmp;
- int ipdatalen, iphdrlen, igmpdatalen;
-
- set[0].fd = igmp_socket;
- set[0].events = POLLIN;
-
- 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 = poll(set, 1, tv.tv_sec * 1000 + tv.tv_usec / 1000);
-
- if (count < 0) {
- if (errno != EINTR)
- perror("select");
- continue;
- } else if (count == 0) {
- logit(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)) {
- logit(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) {
- logit(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) {
- logit(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(u_int32_t src, u_int32_t dst, char *p, int datalen,
- u_int32_t level)
-{
-}
-void accept_group_report(u_int32_t src, u_int32_t dst, u_int32_t group,
- int r_type)
-{
-}
-void accept_neighbor_request2(u_int32_t src, u_int32_t dst)
-{
-}
-void accept_report(u_int32_t src, u_int32_t dst, char *p, int datalen,
- u_int32_t level)
-{
-}
-void accept_neighbor_request(u_int32_t src, u_int32_t dst)
-{
-}
-void accept_prune(u_int32_t src, u_int32_t dst, char *p, int datalen)
-{
-}
-void accept_graft(u_int32_t src, u_int32_t dst, char *p, int datalen)
-{
-}
-void accept_g_ack(u_int32_t src, u_int32_t dst, char *p, int datalen)
-{
-}
-void add_table_entry(u_int32_t origin, u_int32_t mcastgrp)
-{
-}
-void check_vif_state(void)
-{
-}
-void accept_leave_message(u_int32_t src, u_int32_t dst, u_int32_t group)
-{
-}
-void accept_mtrace(u_int32_t src, u_int32_t dst, u_int32_t group, char *data,
- u_int no, int datalen)
-{
-}
-void accept_membership_query(u_int32_t src, u_int32_t dst, u_int32_t group,
- int tmo)
-{
-}
-void accept_info_request(u_int32_t src, u_int32_t dst, u_char *p, int datalen)
-{
-}
-void accept_info_reply(u_int32_t src, u_int32_t dst, u_char *p, int datalen)
-{
-}
diff --git a/gnu/dist/mrouted/LICENSE b/gnu/dist/mrouted/LICENSE
deleted file mode 100644
index ef7da470b11..00000000000
--- a/gnu/dist/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/gnu/dist/mrouted/callout.c b/gnu/dist/mrouted/callout.c
deleted file mode 100644
index 4b76d29a8ec..00000000000
--- a/gnu/dist/mrouted/callout.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/* $NetBSD: callout.c,v 1.2 2002/12/06 16:02:55 thorpej Exp $ */
-
-/*
- * 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.
- */
-
-#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(void);
-#else
-#define print_Q()
-#endif
-
-int secs_remaining(int);
-
-void
-callout_init(void)
-{
- Q = (struct timeout_q *) 0;
-}
-
-
-/*
- * signal handler for SIGALARM that is called once every second
- */
-void
-age_callout_queue(void)
-{
- 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
- logit(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
- *
- * delay: number of units for timeout
- * action: function to be called on timeout
- * data: what to call the timeout function with
- */
-int
-timer_setTimer(int delay, cfunc_t action, char *data)
-{
- 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) {
- logit(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(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(void)
-{
- struct timeout_q *ptr;
-
- for(ptr = Q; ptr; ptr = ptr->next)
- logit(LOG_DEBUG,0,"(%d,%d) ", ptr->id, ptr->time);
-}
-#endif /* IGMP_DEBUG */
-
-int
-secs_remaining(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/gnu/dist/mrouted/cfparse.y b/gnu/dist/mrouted/cfparse.y
deleted file mode 100644
index a9d60476ca7..00000000000
--- a/gnu/dist/mrouted/cfparse.y
+++ /dev/null
@@ -1,624 +0,0 @@
-%{
-/* $NetBSD: cfparse.y,v 1.2 2002/12/06 16:02:55 thorpej Exp $ */
-
-/*
- * Configuration file parser for mrouted.
- *
- * Written by Bill Fenner, NRL, 1994
- * Copyright (c) 1994
- * Naval Research Laboratory (NRL/CCS)
- * and the
- * Defense Advanced Research Projects Agency (DARPA)
- *
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright notice and
- * this permission notice appear in all copies of the software, derivative
- * works or modified versions, and any portions thereof, and that both notices
- * appear in supporting documentation.
- *
- * NRL AND DARPA ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
- * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM
- * THE USE OF THIS SOFTWARE.
- */
-#include <stdio.h>
-#include <stdarg.h>
-#include "defs.h"
-#include <netdb.h>
-
-/*
- * Local function declarations
- */
-static void fatal(char *fmt, ...)
- __attribute__((__format__(__printf__, 1, 2)));
-static void warn(char *fmt, ...)
- __attribute__((__format__(__printf__, 1, 2)));
-static void yyerror(char *s);
-static char * next_word(void);
-static int yylex(void);
-static u_int32_t valid_if(char *s);
-static struct ifreq * ifconfaddr(struct ifconf *ifcp, u_int32_t a);
-int yyparse(void);
-
-static FILE *f __attribute__((__unused__)); /* XXX egcs */
-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_t 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_t 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
- {
- logit(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_t 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; }
- ;
-%%
-static void
-fatal(char *fmt, ...)
-{
- va_list ap;
- char buf[200];
-
- va_start(ap, fmt);
- vsprintf(buf, fmt, ap);
- va_end(ap);
-
- logit(LOG_ERR,0,"%s: %s near line %d", configfilename, buf, lineno);
-}
-
-static void
-warn(char *fmt, ...)
-{
- va_list ap;
- char buf[200];
-
- va_start(ap, fmt);
- vsprintf(buf, fmt, ap);
- va_end(ap);
-
- logit(LOG_WARNING,0,"%s: %s near line %d", configfilename, buf, lineno);
-}
-
-static void
-yyerror(s)
-char *s;
-{
- logit(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_t 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)
- logit(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)
- logit(LOG_ERR, errno, "ioctl SIOCGIFCONF");
-
- yyparse();
-
- fclose(f);
-}
-
-static u_int32_t
-valid_if(s)
-char *s;
-{
- vifi_t vifi;
- 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_t 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/gnu/dist/mrouted/config.c b/gnu/dist/mrouted/config.c
deleted file mode 100644
index 6667594ff0f..00000000000
--- a/gnu/dist/mrouted/config.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/* $NetBSD: config.c,v 1.2 2002/12/06 16:02:55 thorpej Exp $ */
-
-/*
- * 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.
- */
-
-#include "defs.h"
-#include <net/if.h>
-#include <ifaddrs.h>
-
-
-/*
- * Query the kernel to find network interfaces that are multicast-capable
- * and install them in the uvifs array.
- */
-void
-config_vifs_from_kernel(void)
-{
- struct ifaddrs *ifa, *ifap;
- struct uvif *v;
- vifi_t vifi;
- u_int32_t addr, mask, subnet;
- short flags;
-
- if (getifaddrs(&ifap) < 0)
- logit(LOG_ERR, errno, "getifaddrs");
-
- for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
- /*
- * Ignore any interface for an address family other than IP.
- */
- if (ifa->ifa_addr->sa_family != AF_INET)
- continue;
-
- addr = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr;
-
- /*
- * Ignore loopback interfaces and interfaces that do not support
- * multicast.
- */
- flags = ifa->ifa_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}.
- */
- mask = ((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr.s_addr;
- subnet = addr & mask;
- if (!inet_valid_subnet(subnet, mask) ||
- addr == subnet ||
- addr == (subnet | ~mask)) {
- logit(LOG_WARNING, 0,
- "ignoring %s, has invalid address (%s) and/or mask (%s)",
- ifa->ifa_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) {
- logit(LOG_WARNING, 0, "ignoring %s, same subnet as %s",
- ifa->ifa_name, v->uv_name);
- break;
- }
- }
- if (vifi != numvifs)
- continue;
-
- /*
- * If there is room in the uvifs array, install this interface.
- */
- if (numvifs == MAXVIFS) {
- logit(LOG_WARNING, 0, "too many vifs, ignoring %s", ifa->ifa_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;
- strlcpy(v->uv_name, ifa->ifa_name, sizeof(v->uv_name));
- v->uv_groups = NULL;
- v->uv_neighbors = NULL;
- v->uv_acl = NULL;
- v->uv_addrs = NULL;
-
- logit(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;
- }
- }
-
- freeifaddrs(ifap);
-}
diff --git a/gnu/dist/mrouted/defs.h b/gnu/dist/mrouted/defs.h
deleted file mode 100644
index ce6afe4351c..00000000000
--- a/gnu/dist/mrouted/defs.h
+++ /dev/null
@@ -1,304 +0,0 @@
-/* $NetBSD: defs.h,v 1.2 2002/12/06 16:02:55 thorpej Exp $ */
-
-/*
- * 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.
- */
-
-
-#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 */
-
-typedef void (*cfunc_t)(void *);
-typedef void (*ihfunc_t)(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... */
-#define JAN_1970 2208988800UL /* 1970 - 1900 in seconds */
-
-#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_t allhosts_group;
-extern u_int32_t allrtrs_group;
-extern u_int32_t dvmrp_group;
-extern u_int32_t 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 logit(int, int, const char *, ...)
- __attribute__((__format__(__printf__, 3, 4)));
-extern int register_input_handler(int fd, ihfunc_t func);
-
-/* igmp.c */
-extern void init_igmp(void);
-extern void accept_igmp(int recvlen);
-extern void send_igmp(u_int32_t src, u_int32_t dst, int type,
- int code, u_int32_t group, int datalen);
-
-/* callout.c */
-extern void callout_init(void);
-extern void age_callout_queue(void);
-extern int timer_setTimer(int delay, cfunc_t action, char *data);
-extern void timer_clearTimer(int timer_id);
-
-/* route.c */
-extern void init_routes(void);
-extern void start_route_updates(void);
-extern void update_route(u_int32_t origin, u_int32_t mask,
- u_int metric, u_int32_t src, vifi_t vifi);
-extern void age_routes(void);
-extern void expire_all_routes(void);
-extern void free_all_routes(void);
-extern void accept_probe(u_int32_t src, u_int32_t dst,
- char *p, int datalen, u_int32_t level);
-extern void accept_report(u_int32_t src, u_int32_t dst,
- char *p, int datalen, u_int32_t level);
-extern struct rtentry * determine_route(u_int32_t src);
-extern void report(int which_routes, vifi_t vifi, u_int32_t dst);
-extern void report_to_all_neighbors(int which_routes);
-extern int report_next_chunk(void);
-extern void add_vif_to_routes(vifi_t vifi);
-extern void delete_vif_from_routes(vifi_t vifi);
-extern void delete_neighbor_from_routes(u_int32_t addr,
- vifi_t vifi);
-extern void dump_routes(FILE *fp);
-extern void start_route_updates(void);
-
-/* vif.c */
-extern void init_vifs(void);
-extern void check_vif_state(void);
-extern vifi_t find_vif(u_int32_t src, u_int32_t dst);
-extern void age_vifs(void);
-extern void dump_vifs(FILE *fp);
-extern void stop_all_vifs(void);
-extern struct listaddr *neighbor_info(vifi_t vifi, u_int32_t addr);
-extern void accept_group_report(u_int32_t src, u_int32_t dst,
- u_int32_t group, int r_type);
-extern void query_groups(void);
-extern void probe_for_neighbors(void);
-extern int update_neighbor(vifi_t vifi, u_int32_t addr,
- int msgtype, char *p, int datalen,
- u_int32_t level);
-extern void accept_neighbor_request(u_int32_t src, u_int32_t dst);
-extern void accept_neighbor_request2(u_int32_t src, u_int32_t dst);
-extern void accept_neighbors(u_int32_t src, u_int32_t dst,
- u_char *p, int datalen,
- u_int32_t level);
-extern void accept_neighbors2(u_int32_t src, u_int32_t dst,
- u_char *p, int datalen,
- u_int32_t level);
-extern void accept_leave_message(u_int32_t src, u_int32_t dst,
- u_int32_t group);
-extern void accept_membership_query(u_int32_t src, u_int32_t dst,
- u_int32_t group, int tmo);
-
-/* config.c */
-extern void config_vifs_from_kernel(void);
-
-/* cfparse.y */
-extern void config_vifs_from_file(void);
-
-/* inet.c */
-extern int inet_valid_host(u_int32_t naddr);
-extern int inet_valid_mask(u_int32_t mask);
-extern int inet_valid_subnet(u_int32_t nsubnet, u_int32_t nmask);
-extern char * inet_fmt(u_int32_t addr, char *s);
-extern char * inet_fmts(u_int32_t addr, u_int32_t mask, char *s);
-extern u_int32_t inet_parse(char *s);
-extern int inet_cksum(u_short *addr, u_int len);
-
-/* prune.c */
-extern unsigned kroutes;
-extern void add_table_entry(u_int32_t origin, u_int32_t mcastgrp);
-extern void del_table_entry(struct rtentry *r,
- u_int32_t mcastgrp, u_int del_flag);
-extern void update_table_entry(struct rtentry *r);
-extern void init_ktable(void);
-extern void accept_prune(u_int32_t src, u_int32_t dst, char *p,
- int datalen);
-extern void steal_sources(struct rtentry *rt);
-extern void reset_neighbor_state(vifi_t vifi, u_int32_t addr);
-extern int grplst_mem(vifi_t vifi, u_int32_t mcastgrp);
-extern int scoped_addr(vifi_t vifi, u_int32_t addr);
-extern void free_all_prunes(void);
-extern void age_table_entry(void);
-extern void dump_cache(FILE *fp2);
-extern void update_lclgrp(vifi_t vifi, u_int32_t mcastgrp);
-extern void delete_lclgrp(vifi_t vifi, u_int32_t mcastgrp);
-extern void chkgrp_graft(vifi_t vifi, u_int32_t mcastgrp);
-extern void accept_graft(u_int32_t src, u_int32_t dst, char *p,
- int datalen);
-extern void accept_g_ack(u_int32_t src, u_int32_t dst, char *p,
- int datalen);
-/* u_int is promoted u_char */
-extern void accept_mtrace(u_int32_t src, u_int32_t dst,
- u_int32_t group, char *data, u_int no,
- int datalen);
-extern int find_src_grp(u_int32_t, u_int32_t, u_int32_t);
-
-/* kern.c */
-extern void k_set_rcvbuf(int bufsize);
-extern void k_hdr_include(int bool);
-extern void k_set_ttl(int t);
-extern void k_set_loop(int l);
-extern void k_set_if(u_int32_t ifa);
-extern void k_join(u_int32_t grp, u_int32_t ifa);
-extern void k_leave(u_int32_t grp, u_int32_t ifa);
-extern void k_init_dvmrp(void);
-extern void k_stop_dvmrp(void);
-extern void k_add_vif(vifi_t vifi, struct uvif *v);
-extern void k_del_vif(vifi_t vifi);
-extern void k_add_rg(u_int32_t origin, struct gtable *g);
-extern int k_del_rg(u_int32_t origin, struct gtable *g);
-extern int k_get_version(void);
-
-#ifdef SNMP
-/* prune.c */
-extern struct rtentry * snmp_find_route();
-extern struct gtable * find_grp();
-extern struct stable * find_grp_src();
-#endif
-
-#ifdef RSRR
-/* prune.c */
-extern struct gtable *kernel_table;
-extern struct gtable *gtp;
-extern int find_src_grp(u_int32_t src, u_int32_t mask,
- u_int32_t grp);
-
-/* rsrr.c */
-extern void rsrr_init(void);
-extern void rsrr_read(int f, fd_set *rfd);
-extern void rsrr_clean(void);
-extern void rsrr_cache_send(struct gtable *gt, int notify);
-extern void rsrr_cache_clean(struct gtable *gt);
-#endif /* RSRR */
-
-/* vif.c */
-extern void accept_info_reply(u_int32_t, u_int32_t, u_char *, int);
-extern void accept_info_request(u_int32_t, u_int32_t,
- u_char *, int);
-extern void init_installvifs(void);
diff --git a/gnu/dist/mrouted/dvmrp.h b/gnu/dist/mrouted/dvmrp.h
deleted file mode 100644
index a7e71a9bdc3..00000000000
--- a/gnu/dist/mrouted/dvmrp.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/* $NetBSD: dvmrp.h,v 1.1 2002/10/01 03:31:07 itojun Exp $ */
-
-/*
- * 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.
- */
-
-/*
- * 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_t)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_t)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/gnu/dist/mrouted/igmp.c b/gnu/dist/mrouted/igmp.c
deleted file mode 100644
index 9c2670fe674..00000000000
--- a/gnu/dist/mrouted/igmp.c
+++ /dev/null
@@ -1,351 +0,0 @@
-/* $NetBSD: igmp.c,v 1.2 2002/12/06 16:02:56 thorpej Exp $ */
-
-/*
- * 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.
- */
-
-
-#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_t allhosts_group; /* All hosts addr in net order */
-u_int32_t allrtrs_group; /* All-Routers " in net order */
-u_int32_t dvmrp_group; /* DVMRP grp addr in net order */
-u_int32_t dvmrp_genid; /* IGMP generation id */
-
-/*
- * Local function definitions.
- */
-/* u_char promoted to u_int */
-static char * packet_kind(u_int type, u_int code);
-static int igmp_log_level(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(void)
-{
- 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)
- logit(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(u_int type, u_int code)
-{
- switch (type) {
- case IGMP_HOST_MEMBERSHIP_QUERY: return "membership query ";
- case IGMP_v1_HOST_MEMBERSHIP_REPORT: return "v1 member report ";
- case IGMP_v2_HOST_MEMBERSHIP_REPORT: return "v2 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_QUERY: return "IGMP trace query ";
- case IGMP_MTRACE_REPLY: 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(int recvlen)
-{
- u_int32_t src, dst, group;
- struct ip *ip;
- struct igmp *igmp;
- int ipdatalen, iphdrlen, igmpdatalen;
-
- if (recvlen < sizeof(struct ip)) {
- logit(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)
- logit(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) {
- logit(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) {
- logit(LOG_WARNING, 0,
- "received IP data field too short (%u bytes) for IGMP, from %s",
- ipdatalen, inet_fmt(src, s1));
- return;
- }
-
- logit(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_v1_HOST_MEMBERSHIP_REPORT:
- case IGMP_v2_HOST_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:
- logit(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_REPLY:
- return;
-
- case IGMP_MTRACE_QUERY:
- accept_mtrace(src, dst, group, (char *)(igmp+1),
- igmp->igmp_code, igmpdatalen);
- return;
-
- default:
- logit(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(u_int type, u_int code)
-{
- switch (type) {
- case IGMP_MTRACE_REPLY:
- 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(u_int32_t src, u_int32_t dst, int type, int code, u_int32_t group,
- int datalen)
-{
- struct sockaddr_in sdst;
- struct ip *ip;
- struct igmp *igmp;
- int setloop;
-
- setloop = 0;
- 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_int16_t *)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
- logit(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);
-
- logit(LOG_DEBUG, 0, "SENT %s from %-15s to %s",
- packet_kind(type, code), inet_fmt(src, s1), inet_fmt(dst, s2));
-}
diff --git a/gnu/dist/mrouted/inet.c b/gnu/dist/mrouted/inet.c
deleted file mode 100644
index 725a30adcd5..00000000000
--- a/gnu/dist/mrouted/inet.c
+++ /dev/null
@@ -1,223 +0,0 @@
-/* $NetBSD: inet.c,v 1.1 2002/10/01 03:31:08 itojun Exp $ */
-
-/*
- * 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.
- */
-
-
-#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(u_int32_t naddr)
-{
- u_int32_t 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(u_int32_t 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(u_int32_t nsubnet, u_int32_t nmask)
-{
- u_int32_t 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(u_int32_t addr, char *s)
-{
- 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(u_int32_t addr, u_int32_t mask, char *s)
-{
- 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_t
-inet_parse(char *s)
-{
- u_int32_t 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(u_int16_t *addr, u_int len)
-{
- int nleft = (int)len;
- u_int16_t *w = addr;
- int32_t sum = 0;
- union {
- u_int16_t w;
- u_int8_t b[2];
- } answer;
-
- /*
- * 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) {
- answer.w = 0;
- answer.b[0] = *(u_char *)w ;
- sum += answer.w;
- }
-
- /*
- * 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.w = ~sum; /* truncate to 16 bits */
- return (answer.w);
-}
diff --git a/gnu/dist/mrouted/kern.c b/gnu/dist/mrouted/kern.c
deleted file mode 100644
index ca2d20babe8..00000000000
--- a/gnu/dist/mrouted/kern.c
+++ /dev/null
@@ -1,224 +0,0 @@
-/* $NetBSD: kern.c,v 1.2 2002/12/06 16:02:56 thorpej Exp $ */
-
-/*
- * 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.
- */
-
-
-#include "defs.h"
-
-
-void k_set_rcvbuf(int bufsize)
-{
- if (setsockopt(igmp_socket, SOL_SOCKET, SO_RCVBUF,
- (char *)&bufsize, sizeof(bufsize)) < 0)
- logit(LOG_ERR, errno, "setsockopt SO_RCVBUF %u", bufsize);
-}
-
-
-void k_hdr_include(int bool)
-{
-#ifdef IP_HDRINCL
- if (setsockopt(igmp_socket, IPPROTO_IP, IP_HDRINCL,
- (char *)&bool, sizeof(bool)) < 0)
- logit(LOG_ERR, errno, "setsockopt IP_HDRINCL %u", bool);
-#endif
-}
-
-
-void k_set_ttl(int t)
-{
- u_char ttl;
-
- ttl = t;
- if (setsockopt(igmp_socket, IPPROTO_IP, IP_MULTICAST_TTL,
- (char *)&ttl, sizeof(ttl)) < 0)
- logit(LOG_ERR, errno, "setsockopt IP_MULTICAST_TTL %u", ttl);
-}
-
-
-void k_set_loop(int l)
-{
- u_char loop;
-
- loop = l;
- if (setsockopt(igmp_socket, IPPROTO_IP, IP_MULTICAST_LOOP,
- (char *)&loop, sizeof(loop)) < 0)
- logit(LOG_ERR, errno, "setsockopt IP_MULTICAST_LOOP %u", loop);
-}
-
-
-void k_set_if(u_int32_t ifa)
-{
- struct in_addr adr;
-
- adr.s_addr = ifa;
- if (setsockopt(igmp_socket, IPPROTO_IP, IP_MULTICAST_IF,
- (char *)&adr, sizeof(adr)) < 0)
- logit(LOG_ERR, errno, "setsockopt IP_MULTICAST_IF %s",
- inet_fmt(ifa, s1));
-}
-
-
-void k_join(u_int32_t grp, u_int32_t 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)
- logit(LOG_WARNING, errno, "can't join group %s on interface %s",
- inet_fmt(grp, s1), inet_fmt(ifa, s2));
-}
-
-
-void k_leave(u_int32_t grp, u_int32_t 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)
- logit(LOG_WARNING, errno, "can't leave group %s on interface %s",
- inet_fmt(grp, s1), inet_fmt(ifa, s2));
-}
-
-
-void k_init_dvmrp(void)
-{
-#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
- logit(LOG_ERR, errno, "can't enable Multicast routing in kernel");
-}
-
-
-void k_stop_dvmrp(void)
-{
- if (setsockopt(igmp_socket, IPPROTO_IP, MRT_DONE,
- (char *)NULL, 0) < 0)
- logit(LOG_WARNING, errno, "can't disable Multicast routing in kernel");
-}
-
-
-void k_add_vif(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)
- logit(LOG_ERR, errno, "setsockopt MRT_ADD_VIF");
-}
-
-
-void k_del_vif(vifi_t vifi)
-{
- if (setsockopt(igmp_socket, IPPROTO_IP, MRT_DEL_VIF,
- (char *)&vifi, sizeof(vifi)) < 0)
- logit(LOG_ERR, errno, "setsockopt MRT_DEL_VIF");
-}
-
-
-/*
- * Adds a (source, mcastgrp) entry to the kernel
- */
-void k_add_rg(u_int32_t 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
- logit(LOG_WARNING, errno, "setsockopt MRT_ADD_MFC");
- }
-}
-
-
-/*
- * Deletes a (source, mcastgrp) entry from the kernel
- */
-int k_del_rg(u_int32_t 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
- logit(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(void)
-{
-#ifdef OLD_KERNEL
- return -1;
-#else
- int vers;
- int len = sizeof(vers);
-
- if (getsockopt(igmp_socket, IPPROTO_IP, MRT_VERSION,
- (char *)&vers, &len) < 0)
- logit(LOG_ERR, errno,
- "getsockopt MRT_VERSION: perhaps your kernel is too old");
-
- return vers;
-#endif
-}
diff --git a/gnu/dist/mrouted/main.c b/gnu/dist/mrouted/main.c
deleted file mode 100644
index 48512a39696..00000000000
--- a/gnu/dist/mrouted/main.c
+++ /dev/null
@@ -1,701 +0,0 @@
-/* $NetBSD: main.c,v 1.2 2002/12/06 16:02:56 thorpej Exp $ */
-
-/*
- * 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.
- */
-
-/*
- * 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"
-#include <stdarg.h>
-#include <fcntl.h>
-
-#ifdef SNMP
-#include "snmp.h"
-#endif
-
-#include <sys/cdefs.h>
-#ifndef lint
-__RCSID("@(#) $NetBSD: main.c,v 1.2 2002/12/06 16:02:56 thorpej Exp $");
-#endif
-
-#include <err.h>
-#include <util.h>
-
-extern char *configfilename;
-char versionstring[100];
-
-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(int);
-static void done(int);
-static void dump(int);
-static void fdump(int);
-static void cdump(int);
-static void restart(int);
-static void timer(void);
-static void cleanup(void);
-static void resetlogging(void *);
-
-/* To shut up gcc -Wstrict-prototypes */
-int main(int argc, char *argv[]);
-void logit(int severity, int syserr, const char *format, ...)
- __attribute__((__format__(__printf__, 3, 4)));
-
-int
-register_input_handler(int fd, ihfunc_t func)
-{
- if (nhandlers >= NHANDLERS)
- return -1;
-
- ihandlers[nhandlers].fd = fd;
- ihandlers[nhandlers++].func = func;
-
- return 0;
-}
-
-int
-main(int argc, char *argv[])
-{
- int recvlen;
- int omask;
- int dummy;
- FILE *fp;
- struct timeval tv;
- u_int32_t 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
- */
- if (daemon(0, 0))
- err(1, "can't fork");
- pidfile(NULL);
- }
- 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);
-
- logit(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))
- logit(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 */
-
- /*
- * 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);
-
- if (debug)
- fprintf(stderr, "pruning %s\n", pruning ? "on" : "off");
-
- (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);
- if (igmp_socket >= FD_SETSIZE)
- logit(LOG_ERR, 0, "descriptor too big");
- FD_SET(igmp_socket, &readers);
- nfds = igmp_socket + 1;
- for (i = 0; i < nhandlers; i++) {
- if (ihandlers[i].fd >= FD_SETSIZE)
- logit(LOG_ERR, 0, "descriptor too big");
- 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 */
- logit(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) logit(LOG_ERR, errno, "recvfrom");
- continue;
- }
-#ifdef SYSV
- (void)sigemptyset(&block);
- (void)sigaddset(&block, SIGALRM);
- if (sigprocmask(SIG_BLOCK, &block, &oblock) < 0)
- logit(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(int i)
-{
- static unsigned int tlast;
- static unsigned int nsent;
- unsigned int t = tlast + 1;
- 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) {
- int nleft = nroutes - nsent;
- while (nleft > 0) {
- if ((n = report_next_chunk()) <= 0)
- break;
- nleft -= n;
- }
- tlast = 0;
- nsent = 0;
- } else {
- 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(void)
-{
- 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(int i)
-{
- logit(LOG_NOTICE, 0, "%s exiting", versionstring);
- cleanup();
- _exit(1);
-}
-
-static void
-cleanup(void)
-{
- static int 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(int i)
-{
- dump_vifs(stderr);
- dump_routes(stderr);
-}
-
-
-/*
- * Dump internal data structures to a file.
- */
-static void
-fdump(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(int i)
-{
- FILE *fp;
-
- fp = fopen(cachefilename, "w");
- if (fp != NULL) {
- dump_cache(fp);
- (void) fclose(fp);
- }
-}
-
-
-/*
- * Restart mrouted
- */
-static void
-restart(int i)
-{
- int omask;
-#ifdef SYSV
- sigset_t block, oblock;
-#endif
-
- logit(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)
- logit(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(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.
- */
-void
-logit(int severity, int syserr, const char *format, ...)
-{
- va_list ap;
- static char fmt[211] = "warning - ";
- char *msg;
- char tbuf[20];
- struct timeval now;
- struct tm *thyme;
- time_t t;
-
- va_start(ap, format);
- 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);
- t = now.tv_sec;
- thyme = localtime(&t);
- strftime(tbuf, sizeof(tbuf), "%X", thyme);
- fprintf(stderr, "%s.%03ld %s", tbuf, (long)now.tv_usec / 1000,
- msg);
- if (syserr == 0)
- fprintf(stderr, "\n");
- else
- fprintf(stderr, ": %s\n", strerror(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(int what, u_int32_t origin, u_int32_t mcastgrp)
-{
- static FILE *f = NULL;
- struct timeval tv;
- u_int32_t buf[4];
-
- if (!f) {
- if ((f = fopen("/tmp/mrouted.clog", "w")) == NULL) {
- logit(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_t), 4, f);
-}
-#endif
diff --git a/gnu/dist/mrouted/mrouted.8 b/gnu/dist/mrouted/mrouted.8
deleted file mode 100644
index 35d13383d38..00000000000
--- a/gnu/dist/mrouted/mrouted.8
+++ /dev/null
@@ -1,404 +0,0 @@
-'\" $NetBSD: mrouted.8,v 1.1 2002/10/01 03:31:08 itojun Exp $
-'\"COPYRIGHT 1989 by The Board of Trustees of Leland Stanford Junior University.
-.TH MROUTED 8
-.UC 5
-.SH NAME
-mrouted \- IP multicast routing daemon
-.SH SYNOPSIS
-.B 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 /var/run/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 \*[Lt]local-addr\*[Gt] [disable] [metric \*[Lt]m\*[Gt]]
- [threshold \*[Lt]t\*[Gt]] [rate_limit \*[Lt]b\*[Gt]]
- [boundary (\*[Lt]boundary-name\*[Gt]|\*[Lt]scoped-addr\*[Gt]/\*[Lt]mask-len\*[Gt])]
- [altnet \*[Lt]network\*[Gt]/\*[Lt]mask-len\*[Gt]]
-
- tunnel \*[Lt]local-addr\*[Gt] \*[Lt]remote-addr\*[Gt] [metric \*[Lt]m\*[Gt]]
- [threshold \*[Lt]t\*[Gt]] [rate_limit \*[Lt]b\*[Gt]]
- [boundary (\*[Lt]boundary-name\*[Gt]|\*[Lt]scoped-addr\*[Gt]/\*[Lt]mask-len\*[Gt])]
-
- cache_lifetime \*[Lt]ct\*[Gt]
-
- pruning \*[Lt]off/on\*[Gt]
-
- name \*[Lt]boundary-name\*[Gt] \*[Lt]scoped-addr\*[Gt]/\*[Lt]mask-len\*[Gt]
-
-.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 \*[Lt]local-addr\*[Gt], or to associate a
-non-default metric or threshold with the specified physical interface.
-The local IP address \*[Lt]local-addr\*[Gt] 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 \*[Lt]local-addr\*[Gt] and remote IP address \*[Lt]remote-addr\*[Gt], and to associate
-a non-default metric or threshold with that tunnel.
-The local IP address \*[Lt]local-addr\*[Gt] may be replaced by the
-interface name (e.g. le0). The remote IP address \*[Lt]remote-addr\*[Gt] 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 \*[Lt]off/on\*[Gt] 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 /var/tmp/mrouted.dump.
-.IP USR2
-dumps the internal cache tables to /var/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 /var/run/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
-\*[Gt]13.2.116.19
-\*[Gt]13.2.116.196
- 138.96.48/21 224.2.127.255 5m 2m - 0 1
-\*[Gt]138.96.48.108
- 128.9.160/20 224.2.127.255 3m 2m - 0 1
-\*[Gt]128.9.160.45
- 198.106.194/24 224.2.135.190 9m 28s 9m 0P
-\*[Gt]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 "\*[Gt]" 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
-/var/run/mrouted.pid
-.br
-/var/tmp/mrouted.dump
-.br
-/var/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/gnu/dist/mrouted/pathnames.h b/gnu/dist/mrouted/pathnames.h
deleted file mode 100644
index 74c49faebee..00000000000
--- a/gnu/dist/mrouted/pathnames.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* $NetBSD: pathnames.h,v 1.1 2002/10/01 03:31:09 itojun Exp $ */
-
-/*
- * 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.
- */
-
-#define _PATH_MROUTED_CONF "/etc/mrouted.conf"
-
-#if (defined(BSD) && (BSD >= 199103))
-#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_GENID "/etc/mrouted.genid"
-#define _PATH_MROUTED_DUMP "/usr/tmp/mrouted.dump"
-#define _PATH_MROUTED_CACHE "/usr/tmp/mrouted.cache"
-#endif
diff --git a/gnu/dist/mrouted/prune.c b/gnu/dist/mrouted/prune.c
deleted file mode 100644
index 4a1511a1ebd..00000000000
--- a/gnu/dist/mrouted/prune.c
+++ /dev/null
@@ -1,2234 +0,0 @@
-/* $NetBSD: prune.c,v 1.2 2002/12/06 16:02:56 thorpej Exp $ */
-
-/*
- * 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.
- */
-
-
-#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(struct gtable *gt);
-static int pruning_neighbor(vifi_t vifi, u_int32_t addr);
-static int can_mtrace(vifi_t vifi, u_int32_t addr);
-static struct ptable * find_prune_entry(u_int32_t vr, struct ptable *pt);
-static void expire_prune(vifi_t vifi, struct gtable *gt);
-static void send_prune(struct gtable *gt);
-static void send_graft(struct gtable *gt);
-static void send_graft_ack(u_int32_t src, u_int32_t dst,
- u_int32_t origin, u_int32_t grp);
-static void update_kernel(struct gtable *g);
-static char * scaletime(u_long t);
-
-/*
- * Updates the ttl values for each vif.
- */
-static void
-prun_add_ttls(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) { \
- 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_t vifi, u_int32_t 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_t vifi, u_int32_t mcastgrp)
-{
- struct listaddr *g;
- 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(u_int32_t src, u_int32_t mask, u_int32_t 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_t vifi, u_int32_t 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_t vifi, u_int32_t 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(u_int32_t 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(struct gtable *gt)
-{
- struct ptable *pt;
- char *p;
- int i;
- int datalen;
- u_int32_t src;
- u_int32_t dst;
- u_int32_t 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);
-
- logit(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(struct gtable *gt)
-{
- char *p;
- int i;
- int datalen;
- u_int32_t src;
- u_int32_t 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);
- }
- logit(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(u_int32_t src, u_int32_t dst, u_int32_t origin, u_int32_t grp)
-{
- char *p;
- 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);
-
- logit(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(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(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
- *
- * gtpp: ordered by group
- * stpp: ordered by source
- */
-int
-next_grp_src_mask(struct gtable **gtpp, struct stable **stpp, 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(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(igmp_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(u_long src, u_long mask)
-{
- 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(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
- *
- * vifi: vifi at which to start looking
- */
-int
-next_route_child(struct rtentry **rtpp, u_long src, u_long mask, vifi_t *vifi)
-{
- 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
- *
- * vifi: vifi at which to start looking
- */
-int
-next_child(struct gtable **gtpp, struct stable **stpp, u_long grp, u_long src,
- u_long mask, vifi_t *vifi)
-{
- 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(void)
-{
- kernel_table = NULL;
- kernel_no_route = NULL;
- kroutes = 0;
-}
-
-/*
- * Add a new table entry for (origin, mcastgrp)
- */
-void
-add_table_entry(u_int32_t origin, u_int32_t 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)
- logit(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;
- logit(LOG_WARNING, 0, "Entry for (%s %s) (rt:%p) exists (rt:%p)",
- 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)
- logit(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
- logit(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);
-
- logit(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_t vifi, u_int32_t 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) {
- logit(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) != NULL) {
- 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 */
-
- logit(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(struct rtentry *r, u_int32_t 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) {
- logit(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) {
- logit(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) {
- logit(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) {
- logit(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(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;
-
- logit(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_t vifi, u_int32_t mcastgrp)
-{
- struct rtentry *r;
- struct gtable *g;
-
- logit(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);
- logit(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_t vifi, u_int32_t mcastgrp)
-{
- struct rtentry *r;
- struct gtable *g;
-
- logit(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);
- logit(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(u_int32_t src, u_int32_t dst, char *p, int datalen)
-{
- u_int32_t prun_src;
- u_int32_t prun_grp;
- u_int32_t 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) {
- logit(LOG_INFO, 0,
- "ignoring prune report from non-neighbor %s",
- inet_fmt(src, s1));
- return;
- }
-
- /* Check if enough data is present */
- if (datalen < 12)
- {
- logit(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);
-
- logit(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)) {
- logit(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)) {
- logit(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) {
- logit(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)
- logit(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);
- logit(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.
- */
- logit(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_t vifi, u_int32_t 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;
-
- logit(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(u_int32_t src, u_int32_t dst, char *p, int datalen)
-{
- vifi_t vifi;
- u_int32_t graft_src;
- u_int32_t graft_grp;
- int i;
- struct rtentry *r;
- struct gtable *g;
- struct ptable *pt, **ptnp;
-
- if ((vifi = find_vif(src, dst)) == NO_VIF) {
- logit(LOG_INFO, 0,
- "ignoring graft from non-neighbor %s",
- inet_fmt(src, s1));
- return;
- }
-
- if (datalen < 8) {
- logit(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++;
-
- logit(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)) {
- logit(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);
- logit(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);
- logit(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(u_int32_t src, u_int32_t dst, char *p, int datalen)
-{
- struct gtable *g;
- vifi_t vifi;
- u_int32_t grft_src;
- u_int32_t grft_grp;
- int i;
-
- if ((vifi = find_vif(src, dst)) == NO_VIF) {
- logit(LOG_INFO, 0,
- "ignoring graft ack from non-neighbor %s",
- inet_fmt(src, s1));
- return;
- }
-
- if (datalen < 0 || datalen > 8) {
- logit(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++;
-
- logit(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 {
- logit(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(void)
-{
- struct rtentry *r;
- struct gtable *g, *prev_g;
- struct stable *s, *prev_s;
- 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(struct rtentry *rt)
-{
- struct rtentry *rp;
- struct gtable *gt, **gtnp;
- struct stable *st, **stnp;
-
- for (rp = rt->rt_next; rp; rp = rp->rt_next) {
- if ((rt->rt_origin & rp->rt_originmask) == rp->rt_origin) {
- logit(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) {
- logit(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) {
- logit(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)) {
- logit(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) {
- logit(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(void)
-{
- struct rtentry *r;
- struct gtable *gt, **gtnptr;
- struct stable *st, **stnp;
- struct ptable *pt, **ptnp;
- struct sioc_sg_req sg_req;
-
- logit(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) {
- logit(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) {
- 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) {
- logit(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(igmp_socket, SIOCGETSGCNT, (char *)&sg_req) < 0) {
- logit(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;
- logit(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) {
- logit(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;
- }
-
- logit(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) {
- logit(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_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) {
- logit(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);
- logit(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(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(FILE *fp2)
-{
- struct rtentry *r;
- struct gtable *gt;
- struct stable *st;
- vifi_t i;
- 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.
- *
- * no: promoted u_char
- */
-void
-accept_mtrace(u_int32_t src, u_int32_t dst, u_int32_t group, char *data,
- u_int no, 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_t oqid = 0;
-
- /* timestamp the request/response */
- gettimeofday(&tp, 0);
-
- /*
- * Check if it is a query or a response
- */
- if (datalen == QLEN) {
- type = QUERY;
- logit(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;
- logit(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))) {
- logit(LOG_DEBUG, 0, "Dropping multicast response");
- return;
- }
- }
- else {
- logit(LOG_WARNING, 0, "%s from %s to %s",
- "Non decipherable traceroute request received",
- 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) {
- logit(LOG_DEBUG, 0, "packet with all reports filled in");
- return;
- }
-
- logit(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));
- logit(LOG_DEBUG, 0, "rttl: %d rd: %s", qry->tr_rttl,
- inet_fmt(qry->tr_raddr, s1));
- logit(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) {
- logit(LOG_DEBUG, 0, "rt parent vif: %d rtr: %s metric: %d",
- rt->rt_parent, inet_fmt(rt->rt_gateway, s1), rt->rt_metric);
- logit(LOG_DEBUG, 0, "rt origin %s",
- inet_fmts(rt->rt_origin, rt->rt_originmask, s1));
- } else
- logit(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
- * receive 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.
- */
- logit(LOG_DEBUG, 0, "ignoring duplicate traceroute packet");
- return;
- }
-
- if (rt == NULL) {
- logit(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. */
- logit(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)) {
- logit(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) {
- logit(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;
-
- logit(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(igmp_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(igmp_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(igmp_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)) {
- logit(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.
- */
- logit(LOG_DEBUG, 0, "rcount:%d, no:%d", rcount, no);
-
- if ((rcount + 1 == no) || (rt == NULL) || (rt->rt_metric == 1)) {
- resptype = IGMP_MTRACE_REPLY;
- 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_REPLY;
- } else {
- dst = rt->rt_gateway;
- resptype = IGMP_MTRACE_QUERY;
- }
-
- 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) {
- logit(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
- logit(LOG_INFO, 0, "No enabled phyints -- %s",
- "dropping traceroute reply");
- } else {
- logit(LOG_DEBUG, 0, "Sending %s to %s from %s",
- resptype == IGMP_MTRACE_REPLY ? "reply" : "request on",
- inet_fmt(dst, s1), inet_fmt(src, s2));
-
- send_igmp(src, dst,
- resptype, no, group,
- datalen);
- }
- return;
-}
diff --git a/gnu/dist/mrouted/prune.h b/gnu/dist/mrouted/prune.h
deleted file mode 100644
index 9f0ad8b8e95..00000000000
--- a/gnu/dist/mrouted/prune.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/* $NetBSD: prune.h,v 1.1 2002/10/01 03:31:09 itojun Exp $ */
-
-/*
- * 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.
- */
-
-/*
- * 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_t 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_t 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_t 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_t tr_src; /* traceroute source */
- u_int32_t tr_dst; /* traceroute destination */
- u_int32_t 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_t tr_qarr; /* query arrival time */
- u_int32_t tr_inaddr; /* incoming interface address */
- u_int32_t tr_outaddr; /* outgoing interface address */
- u_int32_t tr_rmtaddr; /* parent address in source tree */
- u_int32_t tr_vifin; /* input packet count on interface */
- u_int32_t tr_vifout; /* output packet count on interface */
- u_int32_t tr_pktcnt; /* total incoming packets for src-grp */
- u_char tr_rproto; /* routing protocol deployed on router */
- 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_RP_OR_CORE 8
-#define TR_RPF_INT 9
-#define TR_NO_MULTICAST 10
-#define TR_NO_SPACE 0x81
-#define TR_OLD_ROUTER 0x82
-#define TR_ADMIN_DENY 0x83
-
-/* fields for tr_rproto (routing protocol) */
-#define PROTO_DVMRP 1
-#define PROTO_MOSPF 2
-#define PROTO_PIM 3
-#define PROTO_CBT 4
-#define PROTO_PIM_SPEC 5
-#define PROTO_PIM_STAT 6
-#define PROTO_DVMRP_STAT 7
-#define PROTO_PIM_MBGP 8
-
-#define MASK_TO_VAL(x, i) { \
- u_int32_t _x = ntohl(x); \
- (i) = 1; \
- while ((_x) <<= 1) \
- (i)++; \
- };
-
-#define VAL_TO_MASK(x, i) { \
- x = htonl(~((1 << (32 - (i))) - 1)); \
- };
-
-#define NBR_VERS(n) (((n)->al_pv << 8) + (n)->al_mv)
diff --git a/gnu/dist/mrouted/route.c b/gnu/dist/mrouted/route.c
deleted file mode 100644
index c33825c26af..00000000000
--- a/gnu/dist/mrouted/route.c
+++ /dev/null
@@ -1,1129 +0,0 @@
-/* $NetBSD: route.c,v 1.2 2002/12/06 16:02:57 thorpej Exp $ */
-
-/*
- * 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.
- */
-
-
-#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(struct rtentry *r, vifi_t parent);
-static int find_route(u_int32_t origin, u_int32_t mask);
-static void create_route(u_int32_t origin, u_int32_t mask);
-static void discard_route(struct rtentry *prev_r);
-static int compare_rts(const void *rt1, const void *rt2);
-static int report_chunk(struct rtentry *start_rt, vifi_t vifi, u_int32_t dst);
-
-/*
- * Initialize the routing table and associated variables.
- */
-void
-init_routes(void)
-{
- 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(struct rtentry *r, vifi_t parent)
-{
- vifi_t vifi;
- 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_t vifi)
-{
- struct rtentry *r;
- 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_t vifi)
-{
- 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(u_int32_t addr, vifi_t vifi)
-{
- struct rtentry *r;
- 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(void)
-{
- 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(u_int32_t origin, u_int32_t mask)
-{
- 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 rest.
- */
-static void
-create_route(u_int32_t origin, u_int32_t mask)
-{
- struct rtentry *r;
-
- if ((r = (struct rtentry *) malloc(sizeof(struct rtentry) +
- (2 * numvifs * sizeof(u_int32_t)) +
- (numvifs * sizeof(u_int)))) == NULL) {
- logit(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_t *)(r + 1);
- r->rt_subordinates = (u_int32_t *)(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(struct rtentry *prev_r)
-{
- 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(u_int32_t origin, u_int32_t mask, u_int metric, u_int32_t src,
- vifi_t vifi)
-{
- 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)) {
- logit(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)) {
- logit(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(void)
-{
- struct rtentry *r;
- struct rtentry *prev_r;
- 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(void)
-{
- 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(void)
-{
- struct rtentry *r;
-
- r = RT_ADDR;
-
- while (r->rt_next)
- discard_route(r);
-}
-
-
-/*
- * Process an incoming neighbor probe message.
- */
-void
-accept_probe(u_int32_t src, u_int32_t dst, char *p, int datalen,
- u_int32_t level)
-{
- vifi_t vifi;
-
- if ((vifi = find_vif(src, dst)) == NO_VIF) {
- logit(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_t mask;
- u_int32_t origin;
- int metric;
- int pad;
-};
-
-static int
-compare_rts(const void *rt1, const void *rt2)
-{
- struct newrt *r1 = (struct newrt *)rt1;
- struct newrt *r2 = (struct newrt *)rt2;
- u_int32_t m1 = ntohl(r1->mask);
- u_int32_t m2 = ntohl(r2->mask);
- u_int32_t 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(u_int32_t src, u_int32_t dst, char *p, int datalen,
- u_int32_t level)
-{
- vifi_t vifi;
- int width, i, nrt = 0;
- int metric;
- u_int32_t mask;
- u_int32_t origin;
- struct newrt rt[4096];
-
- if ((vifi = find_vif(src, dst)) == NO_VIF) {
- logit(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) {
- logit(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) {
- logit(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))) {
- logit(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) {
- logit(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;
-
- logit(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) {
- logit(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(int which_routes, vifi_t vifi, u_int32_t dst)
-{
- struct rtentry *r;
- char *p;
- int i;
- int datalen = 0;
- int width = 0;
- u_int32_t mask = 0;
- u_int32_t src;
- u_int32_t 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(int which_routes)
-{
- vifi_t vifi;
- struct uvif *v;
- 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(struct rtentry *start_rt, vifi_t vifi, u_int32_t dst)
-{
- struct rtentry *r;
- char *p;
- int i;
- int nrt = 0;
- int datalen = 0;
- int width = 0;
- u_int32_t mask = 0;
- u_int32_t src;
- u_int32_t 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(void)
-{
- vifi_t vifi;
- struct uvif *v;
- struct rtentry *sr;
- 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;
- logit(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(FILE *fp)
-{
- struct rtentry *r;
- 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(u_int32_t 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/gnu/dist/mrouted/route.h b/gnu/dist/mrouted/route.h
deleted file mode 100644
index a81ba2944c1..00000000000
--- a/gnu/dist/mrouted/route.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* $NetBSD: route.h,v 1.1 2002/10/01 03:31:10 itojun Exp $ */
-
-/*
- * 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.
- */
-
-/*
- * 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_t rt_origin; /* subnet origin of multicasts */
- u_int32_t 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_t 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_t *rt_dominants; /* per vif dominant gateways */
- u_int32_t *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/gnu/dist/mrouted/rsrr.c b/gnu/dist/mrouted/rsrr.c
deleted file mode 100644
index 07d084f2eaf..00000000000
--- a/gnu/dist/mrouted/rsrr.c
+++ /dev/null
@@ -1,504 +0,0 @@
-/* $NetBSD: rsrr.c,v 1.3 2002/12/06 16:02:57 thorpej Exp $ */
-
-/*
- * Copyright (c) 1993, 1998-2001.
- * The University of Southern California/Information Sciences Institute.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/* 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) { \
- 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(int recvlen);
-static void rsrr_accept_iq(void);
-static int rsrr_accept_rq(struct rsrr_rq *route_query, int flags,
- struct gtable *gt_notify);
-static int rsrr_send(int sendlen);
-static void rsrr_cache(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_LOCAL, SOCK_DGRAM, 0)) < 0)
- logit(LOG_ERR, errno, "Can't create RSRR socket");
-
- unlink(RSRR_SERV_PATH);
- bzero((char *) &serv_addr, sizeof(serv_addr));
- serv_addr.sun_family = AF_LOCAL;
- 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)
- logit(LOG_ERR, errno, "Can't bind RSRR socket");
-
- if (register_input_handler(rsrr_socket,rsrr_read) < 0)
- logit(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;
-{
- int rsrr_recvlen;
- 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)
- logit(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) {
- logit(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) {
- logit(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 */
- logit(LOG_INFO, 0, "Received Initial Query\n");
- rsrr_accept_iq();
- break;
- case RSRR_ROUTE_QUERY:
- /* Check size */
- if (recvlen < RSRR_RQ_LEN) {
- logit(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);
- logit(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:
- logit(LOG_WARNING, 0,
- "Received RSRR packet type %d, which I don't handle",
- rsrr->type);
- break;
- }
- break;
-
- default:
- logit(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) {
- logit(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. */
- logit(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)
- logit(LOG_INFO, 0, "Route Change: Send RSRR Route Reply");
-
- else
- logit(LOG_INFO, 0, "Send RSRR Route Reply");
-
- logit(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) {
- logit(LOG_WARNING, errno, "Failed send on RSRR socket");
- } else if (error != sendlen) {
- logit(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;
- logit(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)
- logit(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;
- logit(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) {
- logit(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/gnu/dist/mrouted/rsrr.h b/gnu/dist/mrouted/rsrr.h
deleted file mode 100644
index 6de824c1200..00000000000
--- a/gnu/dist/mrouted/rsrr.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/* $NetBSD: rsrr.h,v 1.2 2002/10/01 03:41:13 itojun Exp $ */
-
-/*
- * Copyright (c) 1993, 1998-2001.
- * The University of Southern California/Information Sciences Institute.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#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/gnu/dist/mrouted/rsrr_var.h b/gnu/dist/mrouted/rsrr_var.h
deleted file mode 100644
index 692e894a334..00000000000
--- a/gnu/dist/mrouted/rsrr_var.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* $NetBSD: rsrr_var.h,v 1.2 2002/10/01 03:41:13 itojun Exp $ */
-
-/*
- * Copyright (c) 1998-2001.
- * The University of Southern California/Information Sciences Institute.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/* 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/gnu/dist/mrouted/snmp.c b/gnu/dist/mrouted/snmp.c
deleted file mode 100644
index 2dba206548f..00000000000
--- a/gnu/dist/mrouted/snmp.c
+++ /dev/null
@@ -1,1288 +0,0 @@
-/* $NetBSD: snmp.c,v 1.1 2002/10/01 03:31:11 itojun Exp $ */
-
-#include "defs.h"
-#include <netinet/in_var.h>
-#include "snmp.h"
-#include "snmplib/asn1.h"
-#include "snmplib/party.h"
-#include "snmplib/snmp_impl.h"
-#define MROUTED
-#include "snmpd/snmp_vars.h"
-
- in_port_t dest_port = 0;
- int sdlen = 0;
-
-struct addrCache {
- u_long addr;
- int status;
-#define UNUSED 0
-#define USED 1
-#define OLD 2
-};
-
-static struct addrCache addrCache[10];
-
-/*
- * Initialize the SNMP part of mrouted
- */
-int /* returns: 0 on success, true on error */
-snmp_init(dest_port)
- in_port_t dest_port;
-{
- u_long myaddr;
- int ret;
- struct partyEntry *pp;
- struct sockaddr_in me;
- int index, sd, portlist[32];
-
- init_snmp();
- /* init_mib(); why was this here? */
- if (read_party_database("/etc/party.conf") > 0){
- fprintf(stderr, "Couldn't read party database from /etc/party.conf\n");
- exit(0);
- }
- if (read_context_database("/etc/context.conf") > 0){
- fprintf(stderr, "Couldn't read context database from /etc/context.conf\n");
- exit(0);
- }
- if (read_acl_database("/etc/acl.conf") > 0){
- fprintf(stderr, "Couldn't read acl database from /etc/acl.conf\n");
- exit(0);
- }
- if (read_view_database("/etc/view.conf") > 0){
- fprintf(stderr, "Couldn't read view database from /etc/view.conf\n");
- exit(0);
- }
-
- myaddr = get_myaddr();
- if (ret = agent_party_init(myaddr, ".1.3.6.1")){
- if (ret == 1){
- fprintf(stderr, "Conflict found with initial noAuth/noPriv parties... continuing\n");
- } else if (ret == -1){
- fprintf(stderr, "Error installing initial noAuth/noPriv parties, exiting\n");
- exit(1);
- } else {
- fprintf(stderr, "Unknown error, exiting\n");
- exit(2);
- }
- }
-
- printf("Opening port(s): ");
- fflush(stdout);
- party_scanInit();
- for(pp = party_scanNext(); pp; pp = party_scanNext()){
- if ((pp->partyTDomain != DOMAINSNMPUDP)
- || bcmp((char *)&myaddr, pp->partyTAddress, 4))
- continue; /* don't listen for non-local parties */
-
- dest_port = 0;
- bcopy(pp->partyTAddress + 4, &dest_port, 2);
- for(index = 0; index < sdlen; index++)
- if (dest_port == portlist[index])
- break;
- if (index < sdlen) /* found a hit before the end of the list */
- continue;
- printf("%u ", dest_port);
- fflush(stdout);
- /* Set up connections */
- sd = socket(AF_INET, SOCK_DGRAM, 0);
- if (sd < 0){
- perror("socket");
- return 1;
- }
- memset(&me, 0, sizeof(me));
- me.sin_family = AF_INET;
- me.sin_addr.s_addr = INADDR_ANY;
- /* already in network byte order (I think) */
- me.sin_port = dest_port;
- if (bind(sd, (struct sockaddr *)&me, sizeof(me)) != 0){
- perror("bind");
- return 2;
- }
- register_input_handler(sd, snmp_read_packet);
- portlist[sdlen] = dest_port;
- if (++sdlen == 32){
- printf("No more sockets... ignoring rest of file\n");
- break;
- }
- }
- printf("\n");
- bzero((char *)addrCache, sizeof(addrCache));
-}
-
-/*
- * Place an IP address into an OID starting at element n
- */
-void
-put_address(name, addr, n)
- oid *name;
- u_long addr;
- int n;
-{
- int i;
-
- for (i=n+3; i>=n+0; i--) {
- name[i] = addr & 0xFF;
- addr >>= 8;
- }
-}
-
-/* Get an IP address from an OID starting at element n */
-int
-get_address(name, length, addr, n)
- oid *name;
- int length;
- u_long *addr;
- int n;
-{
- int i;
- int ok = 1;
-
- (*addr) = 0;
-
- if (length < n+4)
- return 0;
-
- for (i=n; i<n+4; i++) {
- (*addr) <<= 8;
- if (i >= length)
- ok = 0;
- else
- (*addr) |= name[i];
- }
- return ok;
-}
-
-/*
- * Implements scalar objects from DVMRP and Multicast MIBs
- */
-u_char *
-o_scalar(vp, name, length, exact, var_len, write_method)
- struct variable *vp; /* IN - pointer to variable entry that points here */
- oid *name; /* IN/OUT - input name requested, output name found */
- int *length; /* IN/OUT - length of input and output oid's */
- int exact; /* IN - TRUE if an exact match was requested. */
- int *var_len; /* OUT - length of variable or 0 if function returned. */
- int (**write_method)(); /* OUT - pointer to function to set variable, otherwise 0 */
-{
- int result;
-
- *write_method = 0;
- result = compare(name, *length, vp->name, (int)vp->namelen);
- if ((exact && (result != 0)) || (!exact && (result >= 0)))
- return NULL;
-
- bcopy((char *)vp->name, (char *)name,
- (int)vp->namelen * sizeof(oid));
- *length = vp->namelen;
- *var_len = sizeof(long);
-
- switch (vp->magic) {
-
- case ipMRouteEnable:
- long_return = 1;
- return (u_char *) &long_return;
-
- case dvmrpVersion: {
- static char buff[15];
-
- sprintf(buff, "mrouted%d.%d", PROTOCOL_VERSION, MROUTED_VERSION);
- *var_len = strlen(buff);
- return (u_char *)buff;
- }
-
- case dvmrpGenerationId:
- long_return = dvmrp_genid;
- return (u_char *) &long_return;
-
- default:
- ERROR("");
- }
- return NULL;
-}
-
-/*
- * Find if a specific scoped boundary exists on a Vif
- */
-struct vif_acl *
-find_boundary(vifi, addr, mask)
- vifi_t vifi;
- u_long addr;
- u_long mask;
-{
- struct vif_acl *n;
-
- for (n = uvifs[vifi].uv_acl; n != NULL; n = n->acl_next) {
- if (addr == n->acl_addr && mask==n->acl_mask)
- return n;
- }
- return NULL;
-}
-
-/*
- * Find the lowest boundary >= (V,A,M) spec
- */
-struct vif_acl *
-next_boundary(vifi, addr, mask)
- vifi_t *vifi;
- u_long addr;
- u_long mask;
-{
- struct vif_acl *bestn, *n;
- int i;
-
- for (i = *vifi; i < numvifs; i++) {
- bestn = NULL;
- for (n = uvifs[i].uv_acl; n; n=n->acl_next) {
- if ((i > *vifi || n->acl_addr > addr
- || (n->acl_addr == addr && n->acl_mask >= mask))
- && (!bestn || n->acl_addr < bestn->acl_addr
- || (n->acl_addr==bestn->acl_addr && n->acl_mask<bestn->acl_mask)))
- bestn = n;
- }
- if (bestn) {
- *vifi = i;
- return bestn;
- }
- }
- return NULL;
-}
-
-/*
- * Implements the Boundary Table portion of the DVMRP MIB
- */
-u_char *
-o_dvmrpBoundaryTable(vp, name, length, exact, var_len, write_method)
- struct variable *vp; /* IN - pointer to variable entry that points here */
- oid *name; /* IN/OUT - input name requested, output name found */
- int *length; /* IN/OUT - length of input and output oid's */
- int exact; /* IN - TRUE if an exact match was requested. */
- int *var_len; /* OUT - length of variable or 0 if function returned. */
- int (**write_method)(); /* OUT - pointer to function to set variable, otherwise 0 */
-{
- vifi_t vifi;
- u_long addr, mask;
- struct vif_acl *bound;
- oid newname[MAX_NAME_LEN];
- int len;
-
- /* Copy name OID to new OID */
- bcopy((char *)vp->name, (char *)newname, (int)vp->namelen * sizeof(oid));
-
- if (exact) {
- if (*length != vp->namelen + 9)
- return NULL;
-
- if ((vifi = name[vp->namelen]) >= numvifs)
- return NULL;
-
- if (!get_address(name, *length, &addr, vp->namelen+1)
- || !get_address(name, *length, &mask, vp->namelen+5))
- return NULL;
-
- if (!(bound = find_boundary(vifi, addr, mask)))
- return NULL;
-
- bcopy((char *)name, (char *)newname, ((int)*length) * sizeof(oid));
- } else {
- len = *length;
- if (compare(name, *length, vp->name, vp->namelen) < 0)
- len = vp->namelen;
-
- if (len < vp->namelen + 9) { /* get first entry */
-
- if (len == vp->namelen) {
- vifi = addr = mask = 0;
- } else {
- vifi = name[vp->namelen];
- get_address(name, len, &addr, vp->namelen+1);
- get_address(name, len, &mask, vp->namelen+5);
- }
-
- bound = next_boundary(&vifi,addr,mask);
- if (!bound)
- return NULL;
-
- newname[vp->namelen] = vifi;
- put_address(newname, bound->acl_addr, vp->namelen+1);
- put_address(newname, bound->acl_mask, vp->namelen+5);
- } else { /* get next entry given previous */
- vifi = name[vp->namelen];
- get_address(name, *length, &addr, vp->namelen+1);
- get_address(name, *length, &mask, vp->namelen+5);
-
- if (!(bound = next_boundary(&vifi,addr,mask+1)))
- return NULL;
-
- newname[vp->namelen] = vifi;
- put_address(newname, bound->acl_addr, vp->namelen+1);
- put_address(newname, bound->acl_mask, vp->namelen+5);
- }
- }
-
- /* Save new OID */
- *length = vp->namelen + 9;
- bcopy((char *)newname, (char *)name, ((int)*length) * sizeof(oid));
- *write_method = 0;
- *var_len = sizeof(long);
-
- switch (vp->magic) {
-
- case dvmrpBoundaryVifIndex:
- long_return = vifi;
- return (u_char *) &long_return;
-
- default:
- ERROR("");
- }
- return NULL;
-}
-
-/*
- * Find the lowest neighbor >= (V,A) spec
- */
-struct listaddr *
-next_neighbor(vifi, addr)
- vifi_t *vifi;
- u_long addr;
-{
- struct listaddr *bestn, *n;
- int i;
-
- for (i = *vifi; i < numvifs; i++) {
- bestn = NULL;
- for (n = uvifs[i].uv_neighbors; n; n=n->al_next) {
- if ((i > *vifi || n->al_addr >= addr)
- && (!bestn || n->al_addr < bestn->al_addr))
- bestn = n;
- }
- if (bestn) {
- *vifi = i;
- return bestn;
- }
- }
- return NULL;
-}
-
-/*
- * Find a neighbor, if it exists off a given Vif
- */
-struct listaddr *
-find_neighbor(vifi, addr)
- vifi_t vifi;
- u_long addr;
-{
- struct listaddr *n;
-
- for (n = uvifs[vifi].uv_neighbors; n != NULL; n = n->al_next) {
- if (addr == n->al_addr)
- return n;
- }
- return NULL;
-}
-
-u_char *
-o_dvmrpNeighborTable(vp, name, length, exact, var_len, write_method)
- struct variable *vp; /* IN - pointer to variable entry that points here */
- oid *name; /* IN/OUT - input name requested, output name found */
- int *length; /* IN/OUT - length of input and output oid's */
- int exact; /* IN - TRUE if an exact match was requested. */
- int *var_len; /* OUT - length of variable or 0 if function returned. */
- int (**write_method)(); /* OUT - pointer to function to set variable, otherwise 0 */
-{
- vifi_t vifi;
- u_long addr, mask;
- struct listaddr *neighbor;
- oid newname[MAX_NAME_LEN];
- int len;
-
- /* Copy name OID to new OID */
- bcopy((char *)vp->name, (char *)newname, (int)vp->namelen * sizeof(oid));
-
- if (exact) {
- if (*length != vp->namelen + 5)
- return NULL;
-
- if ((vifi = name[vp->namelen]) >= numvifs)
- return NULL;
-
- if (!get_address(name, *length, &addr, vp->namelen+1))
- return NULL;
-
- if (!(neighbor = find_neighbor(vifi, addr)))
- return NULL;
-
- bcopy((char *)name, (char *)newname, ((int)*length) * sizeof(oid));
- } else {
- len = *length;
- if (compare(name, *length, vp->name, vp->namelen) < 0)
- len = vp->namelen;
-
- if (len < vp->namelen + 5) { /* get first entry */
-
- if (len == vp->namelen) {
- vifi = addr = 0;
- } else {
- vifi = name[vp->namelen];
- get_address(name, len, &addr, vp->namelen+1);
- }
-
- neighbor = next_neighbor(&vifi,addr);
- if (!neighbor)
- return NULL;
-
- newname[vp->namelen] = vifi;
- put_address(newname, neighbor->al_addr, vp->namelen+1);
- } else { /* get next entry given previous */
- vifi = name[vp->namelen];
- get_address(name, *length, &addr, vp->namelen+1);
-
- if (!(neighbor = next_neighbor(&vifi,addr+1)))
- return NULL;
-
- newname[vp->namelen] = vifi;
- put_address(newname, neighbor->al_addr, vp->namelen+1);
- }
- }
-
- /* Save new OID */
- *length = vp->namelen + 5;
- bcopy((char *)newname, (char *)name, ((int)*length) * sizeof(oid));
- *write_method = 0;
- *var_len = sizeof(long);
-
- switch (vp->magic) {
-
- case dvmrpNeighborUpTime: {
- time_t currtime;
- time(&currtime);
- long_return = (currtime - neighbor->al_ctime)*100;
- return (u_char *) &long_return;
- }
-
- case dvmrpNeighborExpiryTime:
- long_return = (NEIGHBOR_EXPIRE_TIME - neighbor->al_timer
- + secs_remaining_offset()) * 100;
- return (u_char *) &long_return;
-
- case dvmrpNeighborVersion: {
- static char buff[15];
-
- sprintf(buff, "%d.%d", neighbor->al_pv, neighbor->al_mv);
- *var_len = strlen(buff);
- return (u_char *)buff;
- }
-
- case dvmrpNeighborGenerationId:
- long_return = neighbor->al_genid;
- return (u_char *) &long_return;
-
- default:
- ERROR("");
- }
- return NULL;
-}
-
-/* Look up ifIndex given uvifs[ifnum].uv_lcl_addr */
-struct in_ifaddr * /* returns: in_ifaddr structure, or null on error */
-ipaddr_to_ifindex(ipaddr, ifIndex)
- u_long ipaddr;
- int *ifIndex;
-{
- int interface;
-static struct in_ifaddr in_ifaddr;
-
- Interface_Scan_Init();
- for (;;) {
- if (Interface_Scan_Next(&interface, (char *)0, NULL, &in_ifaddr) == 0)
- return NULL;
-
- if (((struct sockaddr_in *) &(in_ifaddr.ia_addr))->sin_addr.s_addr
- == ipaddr) {
- *ifIndex = interface;
- return &in_ifaddr;
- }
- }
-}
-
-/*
- * Find if a specific scoped boundary exists on a Vif
- */
-struct listaddr *
-find_cache(grp, vifi)
- u_long grp;
- vifi_t vifi;
-{
- struct listaddr *n;
-
- for (n = uvifs[vifi].uv_groups; n != NULL; n = n->al_next) {
- if (grp == n->al_addr)
- return n;
- }
- return NULL;
-}
-
-/*
- * Find the next group cache entry >= (A,V) spec
- */
-struct listaddr *
-next_cache(addr, vifi)
- u_long addr;
- vifi_t *vifi;
-{
- struct listaddr *bestn=NULL, *n;
- int i, besti;
-
- /* Step through all entries looking for the next one */
- for (i = 0; i < numvifs; i++) {
- for (n = uvifs[i].uv_groups; n; n=n->al_next) {
- if ((n->al_addr > addr || (n->al_addr == addr && i >= *vifi))
- && (!bestn || n->al_addr < bestn->al_addr
- || (n->al_addr == bestn->al_addr && i < besti))) {
- bestn = n;
- besti = i;
- }
- }
- }
-
- if (bestn) {
- *vifi = besti;
- return bestn;
- }
- return NULL;
-}
-
-/*
- * Implements the IGMP Cache Table portion of the IGMP MIB
- */
-u_char *
-o_igmpCacheTable(vp, name, length, exact, var_len, write_method)
- struct variable *vp; /* IN - pointer to variable entry that points here */
- oid *name; /* IN/OUT - input name requested, output name found */
- int *length; /* IN/OUT - length of input and output oid's */
- int exact; /* IN - TRUE if an exact match was requested. */
- int *var_len; /* OUT - length of variable or 0 if function returned. */
- int (**write_method)(); /* OUT - pointer to function to set variable, otherwise 0 */
-{
- vifi_t vifi;
- u_long grp;
- int ifIndex;
- struct listaddr *cache;
- oid newname[MAX_NAME_LEN];
- int len;
- struct in_ifaddr *in_ifaddr;
- struct in_multi in_multi, *inm;
-
- /* Copy name OID to new OID */
- bcopy((char *)vp->name, (char *)newname, (int)vp->namelen * sizeof(oid));
-
- if (exact) {
- if (*length != vp->namelen + 5)
- return NULL;
-
- if ((vifi = name[vp->namelen+4]) >= numvifs)
- return NULL;
-
- if (!get_address(name, *length, &grp, vp->namelen))
- return NULL;
-
- if (!(cache = find_cache(grp, vifi)))
- return NULL;
-
- bcopy((char *)name, (char *)newname, ((int)*length) * sizeof(oid));
- } else {
- len = *length;
- if (compare(name, *length, vp->name, vp->namelen) < 0)
- len = vp->namelen;
-
- if (len < vp->namelen + 5) { /* get first entry */
-
- if (len == vp->namelen) {
- vifi = grp = 0;
- } else {
- get_address(name, len, &grp, vp->namelen);
- vifi = name[vp->namelen+4];
- }
-
- cache = next_cache(grp,&vifi);
- if (!cache)
- return NULL;
-
- put_address(newname, cache->al_addr, vp->namelen);
- newname[vp->namelen+4] = vifi;
- } else { /* get next entry given previous */
- get_address(name, *length, &grp, vp->namelen);
- vifi = name[vp->namelen+4]+1;
-
- if (!(cache = next_cache(grp,&vifi)))
- return NULL;
-
- put_address(newname, cache->al_addr, vp->namelen);
- newname[vp->namelen+4] = vifi;
- }
- }
-
- /* Save new OID */
- *length = vp->namelen + 5;
- bcopy((char *)newname, (char *)name, ((int)*length) * sizeof(oid));
- *write_method = 0;
- *var_len = sizeof(long);
-
- /* Look up ifIndex given uvifs[vifi].uv_lcl_addr */
- in_ifaddr = ipaddr_to_ifindex(uvifs[vifi].uv_lcl_addr, &ifIndex);
-
- switch (vp->magic) {
-
- case igmpCacheSelf:
- inm = in_ifaddr->ia_multiaddrs;
- while (inm) {
- klookup( (int)inm, (char *)&in_multi, sizeof(in_multi));
-
- if (in_multi.inm_addr.s_addr == cache->al_addr) {
- long_return = 1; /* true */
- return (u_char *) &long_return;
- }
-
- inm = in_multi.inm_next;
- }
- long_return = 2; /* false */
- return (u_char *) &long_return;
-
- case igmpCacheLastReporter:
- return (u_char *) &cache->al_genid;
-
- case igmpCacheUpTime: {
- time_t currtime;
- time(&currtime);
- long_return = (currtime - cache->al_ctime)*100;
- return (u_char *) &long_return;
- }
-
- case igmpCacheExpiryTime:
- long_return = secs_remaining(cache->al_timerid)*100;
- return (u_char *) &long_return;
-
- case igmpCacheStatus:
- long_return = 1;
- return (u_char *) &long_return;
-
- default:
- ERROR("");
- }
- return NULL;
-}
-
-/*
- * Implements the IGMP Interface Table portion of the IGMP MIB
- */
-u_char *
-o_igmpInterfaceTable(vp, name, length, exact, var_len, write_method)
- struct variable *vp; /* IN - pointer to variable entry that points here */
- oid *name; /* IN/OUT - input name requested, output name found */
- int *length; /* IN/OUT - length of input and output oid's */
- int exact; /* IN - TRUE if an exact match was requested. */
- int *var_len; /* OUT - length of variable or 0 if function returned. */
- int (**write_method)(); /* OUT - pointer to function to set variable, otherwise 0 */
-{
- oid newname[MAX_NAME_LEN];
- int ifnum;
- int result;
-static struct sioc_vif_req v_req;
-
- /* Copy name OID to new OID */
- bcopy((char *)vp->name, (char *)newname, (int)vp->namelen * sizeof(oid));
-
- /* find "next" interface */
- for(ifnum = 0; ifnum < numvifs; ifnum++){
- if (!(uvifs[ifnum].uv_flags & VIFF_QUERIER))
- continue;
- newname[vp->namelen] = (oid)ifnum;
- result = compare(name, *length, newname, (int)vp->namelen + 1);
- if ((exact && (result == 0)) || (!exact && (result < 0)))
- break;
- }
- if (ifnum >= numvifs)
- return NULL;
-
- /* Save new OID */
- bcopy((char *)newname, (char *)name, ((int)vp->namelen + 1) * sizeof(oid));
- *length = vp->namelen + 1;
- *write_method = 0;
- *var_len = sizeof(long);
-
- switch (vp->magic){
-
- case igmpInterfaceQueryInterval:
- long_return = GROUP_QUERY_INTERVAL;
- return (u_char *) &long_return;
-
- case igmpInterfaceStatus:
- long_return = 1; /* active */
- return (u_char *) &long_return;
-
- default:
- ERROR("");
- }
- return NULL;
-}
-
-/*
- * Given a virtual interface number, make sure we have the current
- * kernel information for that Vif.
- */
-refresh_vif(v_req, ifnum)
- struct sioc_vif_req *v_req;
- int ifnum;
-{
- static int lastq = -1;
-
- if (quantum!=lastq || v_req->vifi != ifnum) {
- lastq = quantum;
- v_req->vifi = ifnum;
- if (ioctl(igmp_socket, SIOCGETVIFCNT, (char *)v_req) < 0)
- v_req->icount = v_req->ocount = v_req->ibytes = v_req->obytes = 0;
- }
-}
-
-/*
- * Implements the Multicast Routing Interface Table portion of the Multicast MIB
- */
-u_char *
-o_ipMRouteInterfaceTable(vp, name, length, exact, var_len, write_method)
- struct variable *vp; /* IN - pointer to variable entry that points here */
- oid *name; /* IN/OUT - input name requested, output name found */
- int *length; /* IN/OUT - length of input and output oid's */
- int exact; /* IN - TRUE if an exact match was requested. */
- int *var_len; /* OUT - length of variable or 0 if function returned. */
- int (**write_method)(); /* OUT - pointer to function to set variable, otherwise 0 */
-{
- oid newname[MAX_NAME_LEN];
- int ifnum;
- int result;
-static struct sioc_vif_req v_req;
-
- /* Copy name OID to new OID */
- bcopy((char *)vp->name, (char *)newname, (int)vp->namelen * sizeof(oid));
-
- /* find "next" interface */
- for(ifnum = 0; ifnum < numvifs; ifnum++){
- newname[vp->namelen] = (oid)ifnum;
- result = compare(name, *length, newname, (int)vp->namelen + 1);
- if ((exact && (result == 0)) || (!exact && (result < 0)))
- break;
- }
- if (ifnum >= numvifs)
- return NULL;
-
- /* Save new OID */
- bcopy((char *)newname, (char *)name, ((int)vp->namelen + 1) * sizeof(oid));
- *length = vp->namelen + 1;
- *write_method = 0;
- *var_len = sizeof(long);
-
- switch (vp->magic){
-
- case ipMRouteInterfaceTtl:
- long_return = uvifs[ifnum].uv_threshold;
- return (u_char *) &long_return;
-
- case dvmrpVInterfaceType:
- if (uvifs[ifnum].uv_flags & VIFF_SRCRT)
- long_return = 2;
- else if (uvifs[ifnum].uv_flags & VIFF_TUNNEL)
- long_return = 1;
- else if (uvifs[ifnum].uv_flags & VIFF_QUERIER)
- long_return = 3;
- else /* SUBNET */
- long_return = 4;
- return (u_char *) &long_return;
-
- case dvmrpVInterfaceState:
- if (uvifs[ifnum].uv_flags & VIFF_DISABLED)
- long_return = 3;
- else if ((uvifs[ifnum].uv_flags & VIFF_DOWN)
- || ((uvifs[ifnum].uv_flags & VIFF_TUNNEL) && (uvifs[ifnum].uv_neighbors==NULL)))
- long_return = 2;
- else /* UP */
- long_return = 1;
- return (u_char *) &long_return;
-
- case dvmrpVInterfaceLocalAddress:
- return (u_char *) &uvifs[ifnum].uv_lcl_addr;
-
- case dvmrpVInterfaceRemoteAddress:
- return (u_char *) ((uvifs[ifnum].uv_flags & VIFF_TUNNEL) ?
- &uvifs[ifnum].uv_rmt_addr :
- &uvifs[ifnum].uv_subnet);
-
- case dvmrpVInterfaceRemoteSubnetMask:
- return (u_char *) &uvifs[ifnum].uv_subnetmask;
-
- case dvmrpVInterfaceMetric:
- long_return = uvifs[ifnum].uv_metric;
- return (u_char *) &long_return;
-
- case dvmrpVInterfaceRateLimit:
- long_return = uvifs[ifnum].uv_rate_limit;
- return (u_char *) &long_return;
-
- case dvmrpVInterfaceInPkts:
- refresh_vif(&v_req, ifnum);
- long_return = v_req.icount;
- return (u_char *) &long_return;
-
- case dvmrpVInterfaceOutPkts:
- refresh_vif(&v_req, ifnum);
- long_return = v_req.ocount;
- return (u_char *) &long_return;
-
- case dvmrpVInterfaceInOctets:
- refresh_vif(&v_req, ifnum);
- long_return = v_req.ibytes;
- return (u_char *) &long_return;
-
- case dvmrpVInterfaceOutOctets:
- refresh_vif(&v_req, ifnum);
- long_return = v_req.obytes;
- return (u_char *) &long_return;
-
- default:
- ERROR("");
- }
- return NULL;
-}
-
-/*
- * Implements the DVMRP Route Table portion of the DVMRP MIB
- */
-u_char *
-o_dvmrpRouteTable(vp, name, length, exact, var_len, write_method)
- struct variable *vp; /* IN - pointer to variable entry that points here */
- oid *name; /* IN/OUT - input name requested, output name found */
- int *length; /* IN/OUT - length of input and output oid's */
- int exact; /* IN - TRUE if an exact match was requested. */
- int *var_len; /* OUT - length of variable or 0 if function returned. */
- int (**write_method)(); /* OUT - pointer to function to set variable, otherwise 0 */
-{
- u_long src, mask;
- oid newname[MAX_NAME_LEN];
- int len;
- struct rtentry *rt = NULL;
-
- /* Copy name OID to new OID */
- bcopy((char *)vp->name, (char *)newname, (int)vp->namelen * sizeof(oid));
-
- if (exact) {
- if (*length != vp->namelen + 8)
- return NULL;
-
- if (!get_address(name, *length, &src, vp->namelen)
- || !get_address(name, *length, &mask, vp->namelen+4))
- return NULL;
-
- if (!(rt = snmp_find_route(src, mask)))
- return NULL;
-
- bcopy((char *)name, (char *)newname, ((int)*length) * sizeof(oid));
- } else {
- len = *length;
- if (compare(name, *length, vp->name, vp->namelen) < 0)
- len = vp->namelen;
-
- if (len < vp->namelen + 8) { /* get first entry */
-
- if (len == vp->namelen) {
- src = mask = 0;
- } else {
- get_address(name, len, &src, vp->namelen);
- get_address(name, len, &mask, vp->namelen+4);
- }
-
- if (!next_route(&rt,src,mask)) /* Get first entry */
- return NULL;
-
- put_address(newname, rt->rt_origin , vp->namelen);
- put_address(newname, rt->rt_originmask, vp->namelen+4);
- } else { /* get next entry given previous */
- get_address(name, *length, &src, vp->namelen);
- get_address(name, *length, &mask, vp->namelen+4);
-
- if (!next_route(&rt, src,mask))
- return NULL;
-
- put_address(newname, rt->rt_origin, vp->namelen);
- put_address(newname, rt->rt_originmask, vp->namelen+4);
- }
- }
-
- /* Save new OID */
- *length = vp->namelen + 8;
- bcopy((char *)newname, (char *)name, ((int)*length) * sizeof(oid));
- *write_method = 0;
- *var_len = sizeof(long);
-
- switch (vp->magic) {
-
- case dvmrpRouteUpstreamNeighbor:
- return (u_char *) &rt->rt_gateway;
-
- case dvmrpRouteInVifIndex:
- long_return = rt->rt_parent;
- return (u_char *) &long_return;
-
- case dvmrpRouteMetric:
- long_return = rt->rt_metric;
- return (u_char *) &long_return;
-
- case dvmrpRouteExpiryTime:
- long_return = (ROUTE_EXPIRE_TIME - rt->rt_timer
- + secs_remaining_offset()) * 100;
- return (u_char *) &long_return;
-
- default:
- ERROR("");
- }
- return NULL;
-}
-
-/*
- * Implements the DVMRP Routing Next Hop Table portion of the DVMRP MIB
- */
-u_char *
-o_dvmrpRouteNextHopTable(vp, name, length, exact, var_len, write_method)
- struct variable *vp; /* IN - pointer to variable entry that points here */
- oid *name; /* IN/OUT - input name requested, output name found */
- int *length; /* IN/OUT - length of input and output oid's */
- int exact; /* IN - TRUE if an exact match was requested. */
- int *var_len; /* OUT - length of variable or 0 if function returned. */
- int (**write_method)(); /* OUT - pointer to function to set variable, otherwise 0 */
-{
- u_long src, mask;
- vifi_t vifi;
- struct rtentry *rt = NULL;
- oid newname[MAX_NAME_LEN];
- int len;
-
- /* Copy name OID to new OID */
- bcopy((char *)vp->name, (char *)newname, (int)vp->namelen * sizeof(oid));
-
- if (exact) {
- if (*length != vp->namelen + 9)
- return NULL;
-
- if (!get_address(name, *length, &src, vp->namelen)
- || !get_address(name, *length, &mask, vp->namelen+4)
- || (!(rt=snmp_find_route(src,mask))))
- return NULL;
-
- vifi = name[vp->namelen+8];
- if (!(VIFM_ISSET(vifi, rt->rt_children)))
- return NULL;
-
- bcopy((char *)name, (char *)newname, ((int)*length) * sizeof(oid));
- } else {
- len = *length;
- if (compare(name, *length, vp->name, vp->namelen) < 0)
- len = vp->namelen;
-
- if (len < vp->namelen + 9) { /* get first entry */
-
- get_address(name, len, &src, vp->namelen);
- get_address(name, len, &mask, vp->namelen+4);
-
- /* Find first child vif */
- vifi=0;
- if (!next_route_child(&rt, src, mask, &vifi))
- return NULL;
-
- put_address(newname, rt->rt_origin, vp->namelen);
- put_address(newname, rt->rt_originmask, vp->namelen+4);
- newname[vp->namelen+8] = vifi;
- } else { /* get next entry given previous */
- vifi = name[vp->namelen+8] + 1;
- if (!get_address(name, *length, &src, vp->namelen)
- || !get_address(name, *length, &mask, vp->namelen+4)
- || !next_route_child(&rt, src, mask, &vifi))
- return NULL;
-
- put_address(newname, rt->rt_origin, vp->namelen);
- put_address(newname, rt->rt_originmask, vp->namelen+4);
- newname[vp->namelen+8] = vifi;
- }
- }
-
- /* Save new OID */
- *length = vp->namelen + 9;
- bcopy((char *)newname, (char *)name, ((int)*length) * sizeof(oid));
- *write_method = 0;
- *var_len = sizeof(long);
-
- switch (vp->magic) {
-
- case dvmrpRouteNextHopType:
- long_return = (VIFM_ISSET(vifi, rt->rt_leaves))? 1 : 2;
- return (u_char *) &long_return;
-
- default:
- ERROR("");
- }
- return NULL;
-}
-
-/*
- * Implements the IP Multicast Route Table portion of the Multicast MIB
- */
-u_char *
-o_ipMRouteTable(vp, name, length, exact, var_len, write_method)
- struct variable *vp; /* IN - pointer to variable entry that points here */
- oid *name; /* IN/OUT - input name requested, output name found */
- int *length; /* IN/OUT - length of input and output oid's */
- int exact; /* IN - TRUE if an exact match was requested. */
- int *var_len; /* OUT - length of variable or 0 if function returned. */
- int (**write_method)(); /* OUT - pointer to function to set variable, otherwise 0 */
-{
- u_long src, grp, mask;
- struct gtable *gt = NULL;
- struct stable *st = NULL;
-static struct sioc_sg_req sg_req;
- oid newname[MAX_NAME_LEN];
- int len;
-
- /* Copy name OID to new OID */
- bcopy((char *)vp->name, (char *)newname, (int)vp->namelen * sizeof(oid));
-
- if (exact) {
- if (*length != vp->namelen + 12)
- return NULL;
-
- if (!get_address(name, *length, &grp, vp->namelen)
- || !get_address(name, *length, &src, vp->namelen+4)
- || !get_address(name, *length, &mask, vp->namelen+8)
- || (mask != 0xFFFFFFFF) /* we keep sources now, not subnets */
- || !(gt = find_grp(grp))
- || !(st = find_grp_src(gt,src)))
- return NULL;
-
- bcopy((char *)name, (char *)newname, ((int)*length) * sizeof(oid));
- } else {
- len = *length;
- if (compare(name, *length, vp->name, vp->namelen) < 0)
- len = vp->namelen;
-
- if (len < vp->namelen + 12) { /* get first entry */
-
- get_address(name, len, &grp, vp->namelen);
- get_address(name, len, &src, vp->namelen+4);
- get_address(name, len, &mask, vp->namelen+8);
-
- if (!next_grp_src_mask(&gt,&st,grp,src,mask)) /* Get first entry */
- return NULL;
-
- put_address(newname, gt->gt_mcastgrp, vp->namelen);
- put_address(newname, st->st_origin, vp->namelen+4);
- put_address(newname, 0xFFFFFFFF, vp->namelen+8);
- } else { /* get next entry given previous */
- get_address(name, *length, &grp , vp->namelen);
- get_address(name, *length, &src , vp->namelen+4);
- get_address(name, *length, &mask, vp->namelen+8);
-
- if (!next_grp_src_mask(&gt, &st, grp,src,mask))
- return NULL;
-
- put_address(newname, gt->gt_mcastgrp, vp->namelen);
- put_address(newname, st->st_origin, vp->namelen+4);
- put_address(newname, 0xFFFFFFFF, vp->namelen+8);
- }
- }
-
- /* Save new OID */
- *length = vp->namelen + 12;
- bcopy((char *)newname, (char *)name, ((int)*length) * sizeof(oid));
- *write_method = 0;
- *var_len = sizeof(long);
-
- switch (vp->magic) {
-
- case ipMRouteUpstreamNeighbor:
- return (u_char *) &gt->gt_route->rt_gateway;
-
- case ipMRouteInIfIndex:
- long_return = gt->gt_route->rt_parent;
- return (u_char *) &long_return;
-
- case ipMRouteUpTime: {
- time_t currtime;
- time(&currtime);
- long_return = (currtime - gt->gt_ctime)*100;
- return (u_char *) &long_return;
- }
-
- case ipMRouteExpiryTime:
- long_return = 5*((gt->gt_timer+4)/5); /* round up to nearest 5 */
- long_return = (long_return + secs_remaining_offset()) * 100;
- return (u_char *) &long_return;
-
- case ipMRoutePkts:
- refresh_sg(&sg_req, gt, st);
- long_return = sg_req.pktcnt;
- return (u_char *) &long_return;
-
- case ipMRouteOctets:
- refresh_sg(&sg_req, gt, st);
- long_return = sg_req.bytecnt;
- return (u_char *) &long_return;
-
- case ipMRouteDifferentInIfIndexes:
- refresh_sg(&sg_req, gt, st);
- long_return = sg_req.wrong_if;
- return (u_char *) &long_return;
-
- case ipMRouteProtocol:
- long_return = 4;
- return (u_char *) &long_return;
-
- default:
- ERROR("");
- }
- return NULL;
-}
-
-/*
- * Implements the IP Multicast Routing Next Hop Table portion of the Multicast
- * MIB
- */
-u_char *
-o_ipMRouteNextHopTable(vp, name, length, exact, var_len, write_method)
- struct variable *vp; /* IN - pointer to variable entry that points here */
- oid *name; /* IN/OUT - input name requested, output name found */
- int *length; /* IN/OUT - length of input and output oid's */
- int exact; /* IN - TRUE if an exact match was requested. */
- int *var_len; /* OUT - length of variable or 0 if function returned. */
- int (**write_method)(); /* OUT - pointer to function to set variable, otherwise 0 */
-{
- u_long src, grp, mask, addr;
- vifi_t vifi;
- struct gtable *gt;
- struct stable *st;
- oid newname[MAX_NAME_LEN];
- int len;
-
- /* Copy name OID to new OID */
- bcopy((char *)vp->name, (char *)newname, (int)vp->namelen * sizeof(oid));
-
- if (exact) {
- if (*length != vp->namelen + 17)
- return NULL;
-
- if (!get_address(name, *length, &grp, vp->namelen)
- || !get_address(name, *length, &src, vp->namelen+4)
- || !get_address(name, *length, &mask, vp->namelen+8)
- || !get_address(name, *length, &addr, vp->namelen+13)
- || grp!=addr
- || mask!=0xFFFFFFFF
- || (!(gt=find_grp(grp)))
- || (!(st=find_grp_src(gt,src))))
- return NULL;
-
- vifi = name[vp->namelen+12];
- if (!(VIFM_ISSET(vifi, gt->gt_route->rt_children)))
- return NULL;
-
- bcopy((char *)name, (char *)newname, ((int)*length) * sizeof(oid));
- } else {
- len = *length;
- if (compare(name, *length, vp->name, vp->namelen) < 0)
- len = vp->namelen;
-
- if (len < vp->namelen + 17) { /* get first entry */
-
- get_address(name, len, &grp, vp->namelen);
- get_address(name, len, &src, vp->namelen+4);
- get_address(name, len, &mask, vp->namelen+8);
-
- /* Find first child vif */
- vifi=0;
- if (!next_child(&gt, &st, grp, src, mask, &vifi))
- return NULL;
-
- put_address(newname, gt->gt_mcastgrp, vp->namelen);
- put_address(newname, st->st_origin, vp->namelen+4);
- put_address(newname, 0xFFFFFFFF, vp->namelen+8);
- newname[vp->namelen+12] = vifi;
- put_address(newname, gt->gt_mcastgrp, vp->namelen+13);
-
- } else { /* get next entry given previous */
- vifi = name[vp->namelen+12]+1;
- if (!get_address(name, *length, &grp, vp->namelen)
- || !get_address(name, *length, &src, vp->namelen+4)
- || !get_address(name, *length, &mask, vp->namelen+8)
- || !next_child(&gt, &st, grp, src, mask, &vifi))
- return NULL;
-
- put_address(newname, gt->gt_mcastgrp, vp->namelen);
- put_address(newname, st->st_origin, vp->namelen+4);
- put_address(newname, 0xFFFFFFFF, vp->namelen+8);
- newname[vp->namelen+12] = vifi;
- put_address(newname, gt->gt_mcastgrp, vp->namelen+13);
- }
- }
-
- /* Save new OID */
- *length = vp->namelen + 17;
- bcopy((char *)newname, (char *)name, ((int)*length) * sizeof(oid));
- *write_method = 0;
- *var_len = sizeof(long);
-
- switch (vp->magic) {
-
- case ipMRouteNextHopState:
- long_return = (VIFM_ISSET(vifi, gt->gt_grpmems))? 2 : 1;
- return (u_char *) &long_return;
-
- /* Currently equal to ipMRouteUpTime */
- case ipMRouteNextHopUpTime: {
- time_t currtime;
- time(&currtime);
- long_return = (currtime - gt->gt_ctime)*100;
- return (u_char *) &long_return;
- }
-
- case ipMRouteNextHopExpiryTime:
- long_return = 5*((gt->gt_prsent_timer+4)/5); /* round up to nearest 5*/
- long_return = (long_return + secs_remaining_offset()) * 100;
- return (u_char *) &long_return;
-
- case ipMRouteNextHopClosestMemberHops:
- long_return = 0;
- return (u_char *) &long_return;
-
- case ipMRouteNextHopProtocol:
- long_return = 4;
- return (u_char *) &long_return;
-
- default:
- ERROR("");
- }
- return NULL;
-}
-
-/* sync_timer is called by timer() every TIMER_INTERVAL seconds.
- * Its job is to record this time so that we can compute on demand
- * the approx # seconds remaining until the next timer() call
- */
-static time_t lasttimer;
-
-void
-sync_timer()
-{
- time(&lasttimer);
-}
-
-int /* in range [-TIMER_INTERVAL..0] */
-secs_remaining_offset()
-{
- time_t tm;
-
- time(&tm);
- return lasttimer-tm;
-}
diff --git a/gnu/dist/mrouted/snmp.h b/gnu/dist/mrouted/snmp.h
deleted file mode 100644
index 8cf99e84e65..00000000000
--- a/gnu/dist/mrouted/snmp.h
+++ /dev/null
@@ -1,9 +0,0 @@
-/* $NetBSD: snmp.h,v 1.1 2002/10/01 03:31:11 itojun Exp $ */
-
-extern int portlist[32], sdlen;
-extern in_port_t dest_port;
-extern int quantum;
-
-extern int snmp_read_packet();
-
-#define DEFAULT_PORT 161
diff --git a/gnu/dist/mrouted/vif.c b/gnu/dist/mrouted/vif.c
deleted file mode 100644
index f9554ace209..00000000000
--- a/gnu/dist/mrouted/vif.c
+++ /dev/null
@@ -1,1442 +0,0 @@
-/* $NetBSD: vif.c,v 1.2 2002/12/06 16:02:57 thorpej Exp $ */
-
-/*
- * 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.
- */
-
-
-#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(vifi_t vifi);
-static void start_vif2(vifi_t vifi);
-static void stop_vif(vifi_t vifi);
-static void age_old_hosts(void);
-static void send_probe_on_vif(struct uvif *v);
-static int info_version(char *p);
-static void DelVif(void *arg);
-static int SetTimer(vifi_t vifi, struct listaddr *g);
-static int DeleteTimer(int id);
-static void SendQuery(void *arg);
-static int SetQueryTimer(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(void)
-{
- 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)
- logit(LOG_ERR, errno, "UDP socket");
- logit(LOG_INFO,0,"Getting vifs from kernel interfaces");
- config_vifs_from_kernel();
- logit(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)
- logit(LOG_ERR, 0, "can't forward: %s",
- enabled_vifs == 0 ? "no enabled vifs" : "only one enabled vif");
-
- if (enabled_phyints == 0)
- logit(LOG_WARNING, 0,
- "no enabled interfaces, forwarding via tunnels only");
-
- logit(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)
- logit(LOG_INFO, 0, "vif #%d, tunnel %s -> %s", vifi,
- inet_fmt(v->uv_lcl_addr, s1),
- inet_fmt(v->uv_rmt_addr, s2));
- else
- logit(LOG_INFO, 0, "vif #%d, phyint %s", vifi,
- inet_fmt(v->uv_lcl_addr, s1));
- start_vif2(vifi);
- } else logit(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(void)
-{
- vifi_t vifi;
- struct uvif *v;
-
- logit(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)
- logit(LOG_INFO, 0, "vif #%d, tunnel %s -> %s", vifi,
- inet_fmt(v->uv_lcl_addr, s1),
- inet_fmt(v->uv_rmt_addr, s2));
- else
- logit(LOG_INFO, 0, "vif #%d, phyint %s", vifi,
- inet_fmt(v->uv_lcl_addr, s1));
- k_add_vif(vifi, &uvifs[vifi]);
- } else logit(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(void)
-{
- vifi_t vifi;
- 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)
- logit(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);
- logit(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;
- logit(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(struct uvif *v)
-{
- char *p;
- 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_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_t vifi)
-{
- struct uvif *v;
- u_int32_t 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_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(void)
-{
- 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(u_int32_t src, u_int32_t dst)
-{
- vifi_t vifi;
- struct uvif *v;
- 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(void)
-{
- vifi_t vifi;
- struct uvif *v;
- 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(void)
-{
- vifi_t vifi;
- 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(u_int32_t src, u_int32_t dst, u_int32_t group, int tmo)
-{
- vifi_t vifi;
- struct uvif *v;
-
- if ((vifi = find_vif(src, dst)) == NO_VIF ||
- (uvifs[vifi].uv_flags & VIFF_TUNNEL)) {
- logit(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(u_int32_t src, u_int32_t dst, u_int32_t group, int r_type)
-{
- vifi_t vifi;
- struct uvif *v;
- struct listaddr *g;
-
- if ((vifi = find_vif(src, dst)) == NO_VIF ||
- (uvifs[vifi].uv_flags & VIFF_TUNNEL)) {
- logit(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_v1_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)
- logit(LOG_ERR, 0, "ran out of memory"); /* fatal */
-
- g->al_addr = group;
- if (r_type == IGMP_v2_HOST_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(u_int32_t src, u_int32_t dst, u_int32_t group)
-{
- vifi_t vifi;
- struct uvif *v;
- struct listaddr *g;
-
- if ((vifi = find_vif(src, dst)) == NO_VIF ||
- (uvifs[vifi].uv_flags & VIFF_TUNNEL)) {
- logit(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) {
- logit(LOG_DEBUG, 0,
- "[vif.c, _accept_leave_message] %d %ld\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(void)
-{
- vifi_t vifi;
- 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(u_int32_t src, u_int32_t dst)
-{
- vifi_t vifi;
- struct uvif *v;
- u_char *p, *ncount;
- struct listaddr *la;
- int datalen;
- u_int32_t 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);
-
- memset(&addr, 0, 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) {
- logit(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(u_int32_t src, u_int32_t dst)
-{
- vifi_t vifi;
- struct uvif *v;
- u_char *p, *ncount;
- struct listaddr *la;
- int datalen;
- u_int32_t 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);
-
- memset(&addr, 0, 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) {
- logit(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++) {
- u_short vflags = v->uv_flags;
- 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(u_int32_t src, u_int32_t 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:
- logit(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(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(u_int32_t src, u_int32_t dst, u_char *p, int datalen,
- u_int32_t level)
-{
- logit(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(u_int32_t src, u_int32_t dst, u_char *p, int datalen,
- u_int32_t level)
-{
- logit(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(u_int32_t src, u_int32_t dst, u_char *p, int datalen)
-{
- logit(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_t vifi, u_int32_t addr, int msgtype, char *p, int datalen, u_int32_t level)
-{
- struct uvif *v;
- struct listaddr *n;
- u_int32_t genid = 0;
- u_int32_t router;
- u_int32_t 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 )) {
- logit(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;
- logit(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.
- */
- logit(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)
- logit(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) {
- logit(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) {
- logit(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) {
- logit(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(void)
-{
- vifi_t vifi;
- struct uvif *v;
- struct listaddr *a, *prev_a, *n;
- u_int32_t 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_t vifi, u_int32_t 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(FILE *fp)
-{
- vifi_t vifi;
- struct uvif *v;
- struct listaddr *a;
- 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(igmp_socket, SIOCGETVIFCNT, (char *)&v_req) < 0) {
- logit(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(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_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(int id)
-{
- timer_clearTimer(id);
- return 0;
-}
-
-/*
- * Send a group-specific query.
- */
-static void
-SendQuery(void *arg)
-{
- cbk_t *cbk = (cbk_t *)arg;
- 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(struct listaddr *g, vifi_t vifi, int to_expire, int q_time)
-{
- cbk_t *cbk;
-
- cbk = (cbk_t *) malloc(sizeof(cbk_t));
- cbk->g = g;
- cbk->q_time = q_time;
- cbk->vifi = vifi;
- return timer_setTimer(to_expire, (cfunc_t)SendQuery, (void *)cbk);
-}
diff --git a/gnu/dist/mrouted/vif.h b/gnu/dist/mrouted/vif.h
deleted file mode 100644
index 80bbc99ccb5..00000000000
--- a/gnu/dist/mrouted/vif.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/* $NetBSD: vif.h,v 1.1 2002/10/01 03:31:12 itojun Exp $ */
-
-/*
- * 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.
- */
-
-/*
- * 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_t uv_lcl_addr; /* local address of this vif */
- u_int32_t uv_rmt_addr; /* remote end-point addr (tunnels only) */
- u_int32_t uv_subnet; /* subnet number (phyints only) */
- u_int32_t uv_subnetmask; /* subnet mask (phyints only) */
- u_int32_t 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_t pa_subnet; /* extra subnet */
- u_int32_t pa_subnetmask; /* netmask of extra subnet */
- u_int32_t pa_subnetbcast; /* broadcast of extra subnet */
-};
-
-struct vif_acl {
- struct vif_acl *acl_next; /* next acl member */
- u_int32_t acl_addr; /* Group address */
- u_int32_t acl_mask; /* Group addr. mask */
-};
-
-struct listaddr {
- struct listaddr *al_next; /* link to next addr, MUST BE FIRST */
- u_int32_t 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_t 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 */
diff --git a/gnu/dist/mtrace/mtrace.8 b/gnu/dist/mtrace/mtrace.8
deleted file mode 100644
index 08be3632f8e..00000000000
--- a/gnu/dist/mtrace/mtrace.8
+++ /dev/null
@@ -1,516 +0,0 @@
-.\" $NetBSD: mtrace.8,v 1.2 2003/02/04 23:07:31 perry Exp $
-.\"
-.\" Copyright (c) 1995 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.
-.\"
-.\" This manual page (but not the software) was derived from the
-.\" manual page for the traceroute program which bears the following
-.\" copyright notice:
-.\"
-.\" Copyright (c) 1988 The Regents of the University of California.
-.\" All rights reserved.
-.\"
-.TH MTRACE 8 "May 8, 1995"
-.UC 6
-.SH NAME
-mtrace \- print multicast path from a source to a receiver
-.SH SYNOPSIS
-.B mtrace
-[
-.B \-g
-.I gateway
-] [
-.B \-i
-.I if_addr
-] [
-.B \-l
-] [
-.B \-M
-] [
-.B \-m
-.I max_hops
-] [
-.B \-n
-] [
-.B \-p
-] [
-.B \-q
-.I nqueries
-] [
-.B \-r
-.I resp_dest
-] [
-.B \-s
-] [
-.B \-S
-.I stat_int
-] [
-.B \-t
-.I ttl
-] [
-.B \-v
-] [
-.B \-w
-.I waittime
-]
-.I source
-[
-.I receiver
-] [
-.I group
-]
-.SH DESCRIPTION
-Assessing problems in the distribution of IP multicast traffic
-can be difficult.
-.B mtrace
-uses a tracing feature implemented in multicast routers
-.RB ( mrouted
-version 3.3 and later) that is
-accessed via an extension to the IGMP protocol. A trace query is
-passed hop-by-hop along the reverse path from the
-.I receiver
-to the
-.IR source ,
-collecting hop addresses, packet counts, and routing error conditions
-along the path, and then the response is returned to the requestor.
-.PP
-The only required parameter is the
-.I source
-host name or address. The default
-.I receiver
-is the host running mtrace, and the default
-.I group
-is "MBone Audio" (224.2.0.1), which is sufficient if packet loss
-statistics for a particular multicast group are not needed. These two
-optional parameters may be specified to test the path to some other
-receiver in a particular group, subject to some constraints as
-detailed below. The two parameters can be distinguished because the
-.I receiver
-is a unicast address and the
-.I group
-is a multicast address.
-.PP
-NOTE: For Solaris 2.4/2.5, if the multicast interface is not the default
-interface, the -i option must be used to set the local address.
-.SH OPTIONS
-.TP 8 8
-.BI \-g\ gwy
-Send the trace query via unicast directly to the multicast router
-.I gwy
-rather than multicasting the query.
-This must be the last-hop router on the path from the intended
-.I source
-to the
-.IR receiver .
-.RS 8
-.TP 12 12
-.I CAUTION!!
-Versions 3.3 and 3.5 of
-.B mrouted
-will crash if a trace query is received via a
-unicast packet and
-.B mrouted
-has no route for the
-.I source
-address. Therefore, do not use the
-.B \-g
-option unless the target
-.B mrouted
-has been verified to be 3.4 or newer than 3.5.
-.RE
-.TP 8 8
-.BI \-i\ addr
-Use
-.I addr
-as the local interface address (on a multi-homed host) for sending the
-trace query and as the default for the
-.I receiver
-and the response destination.
-.TP 8 8
-.B \-l
-Loop indefinitely printing packet rate and loss statistics for the
-multicast path every 10 seconds (see
-.B \-S
-.IR stat_int ).
-.TP 8 8
-.B \-M
-Always send the response using multicast rather than attempting
-unicast first.
-.TP 8 8
-.BI \-m\ n
-Set to
-.I n
-the maximum number of hops that will be traced from the
-.I receiver
-back toward the
-.IR source .
-The default is 32 hops (infinity for the DVMRP routing protocol).
-.TP 8 8
-.B \-n
-Print hop addresses numerically rather than symbolically and numerically
-(saves a nameserver address-to-name lookup for each router found on the
-path).
-.TP 8 8
-.BI \-q\ n
-Set the maximum number of query attempts for any hop to
-.IR n .
-The default is 3.
-.TP 8 8
-.B \-p
-Listen passively for multicast responses from traces initiated by
-others. This works best when run on a multicast router.
-.TP 8 8
-.BI \-r\ host
-Send the trace response to
-.I host
-rather than to the host on which
-.B mtrace
-is being run, or to a multicast address other than the one registered
-for this purpose (224.0.1.32).
-.TP 8 8
-.B \-s
-Print a short form output including only the multicast path and not
-the packet rate and loss statistics.
-.TP 8 8
-.BI \-S\ n
-Change the interval between statistics gathering traces to
-.I n
-seconds (default 10 seconds).
-.TP 8 8
-.BI \-t\ ttl
-Set the
-.I ttl
-(time-to-live, or number of hops) for multicast trace queries and
-responses. The default is 64, except for local queries to the "all
-routers" multicast group which use ttl 1.
-.TP 8 8
-.B \-v
-Verbose mode; show hop times on the initial trace and statistics display.
-.TP 8 8
-.BI \-w\ n
-Set the time to wait for a trace response to
-.I n
-seconds (default 3 seconds).
-.SH USAGE
-.SS How It Works
-The technique used by the
-.B traceroute
-tool to trace unicast network paths will not work for IP multicast
-because ICMP responses are specifically forbidden for multicast traffic.
-Instead, a tracing feature has been built into the multicast routers.
-This technique has the advantage that additional information about
-packet rates and losses can be accumulated while the number of packets
-sent is minimized.
-.PP
-Since multicast uses
-reverse path forwarding, the trace is run backwards from the
-.I receiver
-to the
-.IR source .
-A trace query packet is sent to the last
-hop multicast router (the leaf router for the desired
-.I receiver
-address). The last hop router builds a trace response packet, fills in
-a report for its hop, and forwards the trace packet using unicast to
-the router it believes is the previous hop for packets originating
-from the specified
-.IR source .
-Each router along the path adds its report and forwards the packet.
-When the trace response packet reaches the first hop router (the router
-that is directly connected to the source's net), that router sends the
-completed response to the response destination address specified in
-the trace query.
-.PP
-If some multicast router along the path does not implement the
-multicast traceroute feature or if there is some outage, then no
-response will be returned. To solve this problem, the trace query
-includes a maximum hop count field to limit the number of hops traced
-before the response is returned. That allows a partial path to be
-traced.
-.PP
-The reports inserted by each router contain not only the address of
-the hop, but also the ttl required to forward and some flags to indicate
-routing errors, plus counts of the total number of packets on the
-incoming and outgoing interfaces and those forwarded for the specified
-.IR group .
-Taking differences in these counts for two traces separated in time
-and comparing the output packet counts from one hop with the input
-packet counts of the next hop allows the calculation of packet rate
-and packet loss statistics for each hop to isolate congestion
-problems.
-.SS Finding the Last-Hop Router
-The trace query must be sent to the multicast router which is the
-last hop on the path from the
-.I source
-to the
-.IR receiver .
-If the receiver is on the local subnet (as determined using the subnet
-mask), then the default method is to multicast the trace query to
-all-routers.mcast.net (224.0.0.2) with a ttl of 1. Otherwise, the
-trace query is multicast to the
-.I group
-address since the last hop router will be a member of that group if
-the receiver is. Therefore it is necessary to specify a group that
-the intended receiver has joined. This multicast is sent with a
-default ttl of 64, which may not be sufficient for all cases (changed
-with the
-.B \-t
-option).
-If the last hop router is known, it may also be addressed directly
-using the
-.B \-g
-option). Alternatively, if it is desired to trace a group that the
-receiver has not joined, but it is known that the last-hop router is a
-member of another group, the
-.B \-g
-option may also be used to specify a different multicast address for the
-trace query.
-.PP
-When tracing from a multihomed host or router, the default receiver
-address may not be the desired interface for the path from the source.
-In that case, the desired interface should be specified explicitly as
-the
-.IR receiver .
-.SS Directing the Response
-By default,
-.B mtrace
-first attempts to trace the full reverse path, unless the number of
-hops to trace is explicitly set with the
-.B \-m
-option. If there is no response within a 3 second timeout interval
-(changed with the
-.B \-w
-option), a "*" is printed and the probing switches to hop-by-hop mode.
-Trace queries are issued starting with a maximum hop count of one and
-increasing by one until the full path is traced or no response is
-received. At each hop, multiple probes are sent (default is three,
-changed with
-.B \-q
-option). The first half of the attempts (default is one) are made with
-the unicast address of the host running
-.B mtrace
-as the destination for the response. Since the unicast route may be
-blocked, the remainder of attempts request that the response be
-multicast to mtrace.mcast.net (224.0.1.32) with the ttl set to 32 more
-than what's needed to pass the thresholds seen so far along the path
-to the receiver. For the last quarter of the attempts (default is
-one), the ttl is increased by another 32 each time up to a maximum of
-192. Alternatively, the ttl may be set explicitly with the
-.B \-t
-option and/or the initial unicast attempts can be forced to use
-multicast instead with the
-.B \-M
-option. For each attempt, if no response is received within the
-timeout, a "*" is printed. After the specified number of attempts
-have failed,
-.B mtrace
-will try to query the next hop router with a DVMRP_ASK_NEIGHBORS2
-request (as used by the
-.B mrinfo
-program) to see what kind of router it is.
-.SH EXAMPLES
-The output of
-.B mtrace
-is in two sections. The first section is a short listing of the hops
-in the order they are queried, that is, in the reverse of the order
-from the
-.I source
-to the
-.IR receiver .
-For each hop, a line is printed showing the hop number (counted
-negatively to indicate that this is the reverse path); the multicast
-routing protocol (DVMRP, MOSPF, PIM, etc.); the threshold required to
-forward data (to the previous hop in the listing as indicated by the
-up-arrow character); and the cumulative delay for the query to reach
-that hop (valid only if the clocks are synchronized). This first
-section ends with a line showing the round-trip time which measures
-the interval from when the query is issued until the response is
-received, both derived from the local system clock. A sample use and
-output might be:
-.PP
-.nf
-.ft C
-oak.isi.edu 80# mtrace -l caraway.lcs.mit.edu 224.2.0.3
-Mtrace from 18.26.0.170 to 128.9.160.100 via group 224.2.0.3
-Querying full reverse path...
- 0 oak.isi.edu (128.9.160.100)
- -1 cub.isi.edu (128.9.160.153) DVMRP thresh^ 1 3 ms
- -2 la.dart.net (140.173.128.1) DVMRP thresh^ 1 14 ms
- -3 dc.dart.net (140.173.64.1) DVMRP thresh^ 1 50 ms
- -4 bbn.dart.net (140.173.32.1) DVMRP thresh^ 1 63 ms
- -5 mit.dart.net (140.173.48.2) DVMRP thresh^ 1 71 ms
- -6 caraway.lcs.mit.edu (18.26.0.170)
-Round trip time 124 ms
-.fi
-.PP
-The second section provides a pictorial view of the path in the
-forward direction with data flow indicated by arrows pointing downward
-and the query path indicated by arrows pointing upward. For each hop,
-both the entry and exit addresses of the router are shown if
-different, along with the initial ttl required on the packet in order
-to be forwarded at this hop and the propagation delay across the hop
-assuming that the routers at both ends have synchronized clocks. The
-right half of this section is composed of several columns of
-statistics in two groups. Within each group, the columns are the
-number of packets lost, the number of packets sent, the percentage
-lost, and the average packet rate at each hop. These statistics are
-calculated from differences between traces and from hop to hop as
-explained above. The first group shows the statistics for all traffic
-flowing out the interface at one hop and in the interface at the next
-hop. The second group shows the statistics only for traffic forwarded
-from the specified
-.I source
-to the specified
-.IR group .
-.PP
-These statistics are shown on one or two lines for each hop. Without
-any options, this second section of the output is printed only once,
-approximately 10 seconds after the initial trace. One line is shown
-for each hop showing the statistics over that 10-second period. If
-the
-.B \-l
-option is given, the second section is repeated every 10 seconds and
-two lines are shown for each hop. The first line shows the statistics
-for the last 10 seconds, and the second line shows the cumulative
-statistics over the period since the initial trace, which is 101
-seconds in the example below. The second section of the output is
-omitted if the
-.B \-s
-option is set.
-.ie t \{\
-.ft C
-. ie \w'i'<>\w'm' \{\" looks like this is not proper Courier font
-(If this example is not properly columned with a fixed-width font, get
-.B groff
-and try again.)
-. \}
-.\}
-.PP
-.ft C
-.nf
-Waiting to accumulate statistics... Results after 101 seconds:
-
- Source Response Dest Packet Statistics For Only For Traffic
-18.26.0.170 128.9.160.100 All Multicast Traffic From 18.26.0.170
- | __/ rtt 125 ms Lost/Sent = Pct Rate To 224.2.0.3
- v / hop 65 ms --------------------- ------------------
-18.26.0.144
-140.173.48.2 mit.dart.net
- | ^ ttl 1 0/6 = --% 0 pps 0/2 = --% 0 pps
- v | hop 8 ms 1/52 = 2% 0 pps 0/18 = 0% 0 pps
-140.173.48.1
-140.173.32.1 bbn.dart.net
- | ^ ttl 2 0/6 = --% 0 pps 0/2 = --% 0 pps
- v | hop 12 ms 1/52 = 2% 0 pps 0/18 = 0% 0 pps
-140.173.32.2
-140.173.64.1 dc.dart.net
- | ^ ttl 3 0/271 = 0% 27 pps 0/2 = --% 0 pps
- v | hop 34 ms -1/2652 = 0% 26 pps 0/18 = 0% 0 pps
-140.173.64.2
-140.173.128.1 la.dart.net
- | ^ ttl 4 -2/831 = 0% 83 pps 0/2 = --% 0 pps
- v | hop 11 ms -3/8072 = 0% 79 pps 0/18 = 0% 0 pps
-140.173.128.2
-128.9.160.153 cub.isi.edu
- | \\__ ttl 5 833 83 pps 2 0 pps
- v \\ hop -8 ms 8075 79 pps 18 0 pps
-128.9.160.100 128.9.160.100
- Receiver Query Source
-.fi
-.PP
-Because the packet counts may be changing as the trace query is
-propagating, there may be small errors (off by 1 or 2) in these
-statistics. However, those errors should not accumulate, so the
-cumulative statistics line should increase in accuracy as a new trace
-is run every 10 seconds. There are two sources of larger errors, both
-of which show up as negative losses:
-.LP
-.RS
-.PD 0
-.TP 3
-\(bu
-If the input to a node is from a multi-access network with more than
-one other node attached, then the input count will be (close to) the
-sum of the output counts from all the attached nodes, but the output
-count from the previous hop on the traced path will be only part of
-that. Hence the output count minus the input count will be negative.
-.TP 3
-\(bu
-In release 3.3 of the DVMRP multicast forwarding software for SunOS
-and other systems, a multicast packet generated on a router will be
-counted as having come in an interface even though it did not. This
-creates the negative loss that can be seen in the example above.
-.PD
-.RE
-.LP
-Note that these negative losses may mask positive losses.
-.PP
-In the example, there is also one negative hop time. This simply
-indicates a lack of synchronization between the system clocks across
-that hop. This example also illustrates how the percentage loss is
-shown as two dashes when the number of packets sent is less than 10
-because the percentage would not be statistically valid.
-.PP
-A second example shows a trace to a receiver that is not local; the
-query is sent to the last-hop router with the
-.B \-g
-option. In this example, the trace of the full reverse path resulted
-in no response because there was a node running an old version of
-.B mrouted
-that did not implement the multicast traceroute function, so
-.B mtrace
-switched to hop-by-hop mode. The \*(lqRoute pruned\*(rq error code
-indicates that traffic for group 224.2.143.24 would not be forwarded.
-.PP
-.nf
-.ft C
-oak.isi.edu 108# mtrace -g 140.173.48.2 204.62.246.73 \\
- butter.lcs.mit.edu 224.2.143.24
-Mtrace from 204.62.246.73 to 18.26.0.151 via group 224.2.143.24
-Querying full reverse path... * switching to hop-by-hop:
- 0 butter.lcs.mit.edu (18.26.0.151)
- -1 jam.lcs.mit.edu (18.26.0.144) DVMRP thresh^ 1 33 ms Route pruned
- -2 bbn.dart.net (140.173.48.1) DVMRP thresh^ 1 36 ms
- -3 dc.dart.net (140.173.32.2) DVMRP thresh^ 1 44 ms
- -4 darpa.dart.net (140.173.240.2) DVMRP thresh^ 16 47 ms
- -5 * * * noc.hpc.org (192.187.8.2) [mrouted 2.2] didn't respond
-Round trip time 95 ms
-.fi
-.SH AUTHOR
-Implemented by Steve Casner based on an initial prototype written by
-Ajit Thyagarajan. The multicast traceroute mechanism was designed by
-Van Jacobson with help from Steve Casner, Steve Deering, Dino
-Farinacci, and Deb Agrawal; it was implemented in
-.B mrouted
-by Ajit Thyagarajan and Bill Fenner. The option syntax and the output
-format of
-.B mtrace
-are modeled after the unicast
-.B traceroute
-program written by Van Jacobson.
-.SH SEE ALSO
-.BR mrouted (8) ,
-.BR mrinfo (8) ,
-.BR map-mbone (8) ,
-.BR traceroute (8)
diff --git a/gnu/dist/mtrace/mtrace.c b/gnu/dist/mtrace/mtrace.c
deleted file mode 100644
index 2c6775f5323..00000000000
--- a/gnu/dist/mtrace/mtrace.c
+++ /dev/null
@@ -1,1758 +0,0 @@
-/* $NetBSD: mtrace.c,v 1.2 2002/12/06 16:03:41 thorpej Exp $ */
-
-/*
- * mtrace.c
- *
- * This tool traces the branch of a multicast tree from a source to a
- * receiver for a particular multicast group and gives statistics
- * about packet rate and loss for each hop along the path. It can
- * usually be invoked just as
- *
- * mtrace source
- *
- * to trace the route from that source to the local host for a default
- * group when only the route is desired and not group-specific packet
- * counts. See the usage line for more complex forms.
- *
- *
- * Released 4 Apr 1995. This program was adapted by Steve Casner
- * (USC/ISI) from a prototype written by Ajit Thyagarajan (UDel and
- * Xerox PARC). It attempts to parallel in command syntax and output
- * format the unicast traceroute program written by Van Jacobson (LBL)
- * for the parts where that makes sense.
- *
- * Copyright (c) 1995 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.
- *
- * In particular, parts of the prototype version of this program may
- * have been derived from mrouted programs sources covered by the
- * license in the accompanying file named "LICENSE".
- */
-
-#include <sys/cdefs.h>
-#ifndef lint
-__RCSID("$NetBSD: mtrace.c,v 1.2 2002/12/06 16:03:41 thorpej Exp $");
-#endif
-
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/time.h>
-#include <poll.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <ctype.h>
-#include <memory.h>
-#include <netdb.h>
-#include <string.h>
-#include "defs.h"
-
-#include <stdarg.h>
-#ifdef SUNOS5
-#include <sys/systeminfo.h>
-#endif
-
-#define DEFAULT_TIMEOUT 3 /* How long to wait before retrying requests */
-#define DEFAULT_RETRIES 3 /* How many times to try */
-#define MAXHOPS UNREACHABLE /* Don't need more hops than max metric */
-#define UNICAST_TTL 255 /* TTL for unicast response */
-#define MULTICAST_TTL1 64 /* Default TTL for multicast query/response */
-#define MULTICAST_TTL_INC 32 /* TTL increment for increase after timeout */
-#define MULTICAST_TTL_MAX 192 /* Maximum TTL allowed (protect low-BW links */
-
-struct resp_buf {
- u_long qtime; /* Time query was issued */
- u_long rtime; /* Time response was received */
- int len; /* Number of reports or length of data */
- struct igmp igmp; /* IGMP header */
- union {
- struct {
- struct tr_query q; /* Query/response header */
- struct tr_resp r[MAXHOPS]; /* Per-hop reports */
- } t;
- char d[MAX_DVMRP_DATA_LEN]; /* Neighbor data */
- } u;
-} base, incr[2];
-
-#define qhdr u.t.q
-#define resps u.t.r
-#define ndata u.d
-
-char names[MAXHOPS][40];
-int reset[MAXHOPS]; /* To get around 3.4 bug, ... */
-int swaps[MAXHOPS]; /* To get around 3.6 bug, ... */
-
-int timeout = DEFAULT_TIMEOUT;
-int nqueries = DEFAULT_RETRIES;
-int numeric = FALSE;
-int debug = 0;
-int passive = FALSE;
-int multicast = FALSE;
-int statint = 10;
-int verbose = 0;
-
-u_int32_t defgrp; /* Default group if not specified */
-u_int32_t query_cast; /* All routers multicast addr */
-u_int32_t resp_cast; /* Mtrace response multicast addr */
-
-u_int32_t lcl_addr = 0; /* This host address, in NET order */
-u_int32_t dst_netmask; /* netmask to go with qdst */
-
-/*
- * Query/response parameters, all initialized to zero and set later
- * to default values or from options.
- */
-u_int32_t qsrc = 0; /* Source address in the query */
-u_int32_t qgrp = 0; /* Group address in the query */
-u_int32_t qdst = 0; /* Destination (receiver) address in query */
-u_char qno = 0; /* Max number of hops to query */
-u_int32_t raddr = 0; /* Address where response should be sent */
-int qttl = 0; /* TTL for the query packet */
-u_char rttl = 0; /* TTL for the response packet */
-u_int32_t gwy = 0; /* User-supplied last-hop router address */
-u_int32_t tdst = 0; /* Address where trace is sent (last-hop) */
-
-vifi_t numvifs; /* to keep loader happy */
- /* (see kern.c) */
-
-u_long byteswap(u_long);
-char * inet_name(u_int32_t addr);
-u_int32_t host_addr(char *name);
-/* u_int is promoted u_char */
-char * proto_type(u_int type);
-char * flag_type(u_int type);
-
-u_int32_t get_netmask(int s, u_int32_t dst);
-int get_ttl(struct resp_buf *buf);
-int t_diff(u_long a, u_long b);
-u_long fixtime(u_long time);
-int send_recv(u_int32_t dst, int type, int code,
- int tries, struct resp_buf *save);
-char * print_host(u_int32_t addr);
-char * print_host2(u_int32_t addr1, u_int32_t addr2);
-void print_trace(int index, struct resp_buf *buf);
-int what_kind(struct resp_buf *buf, char *why);
-char * scale(int *hop);
-void stat_line(struct tr_resp *r, struct tr_resp *s,
- int have_next, int *res);
-void fixup_stats(struct resp_buf *base,
- struct resp_buf *prev,
- struct resp_buf *new);
-int print_stats(struct resp_buf *base,
- struct resp_buf *prev,
- struct resp_buf *new);
-void check_vif_state(void);
-void passive_mode(void);
-
-int main(int argc, char *argv[]);
-/* logit() prototyped in defs.h */
-
-
-char *
-inet_name(u_int32_t addr)
-{
- struct hostent *e;
-
- e = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET);
-
- return e ? e->h_name : "?";
-}
-
-
-u_int32_t
-host_addr(char *name)
-{
- struct hostent *e = (struct hostent *)0;
- u_int32_t addr;
- int i, dots = 3;
- char buf[40];
- char *ip = name;
- char *op = buf;
-
- /*
- * Undo BSD's favor -- take fewer than 4 octets as net/subnet address
- * if the name is all numeric.
- */
- for (i = sizeof(buf) - 7; i > 0; --i) {
- if (*ip == '.') --dots;
- else if (*ip == '\0') break;
- else if (!isdigit(*ip)) dots = 0; /* Not numeric, don't add zeroes */
- *op++ = *ip++;
- }
- for (i = 0; i < dots; ++i) {
- *op++ = '.';
- *op++ = '0';
- }
- *op = '\0';
-
- if (dots <= 0) e = gethostbyname(name);
- if (e) memcpy((char *)&addr, e->h_addr_list[0], sizeof(addr));
- else {
- addr = inet_addr(buf);
- if (addr == -1) {
- addr = 0;
- printf("Could not parse %s as host name or address\n", name);
- }
- }
- return addr;
-}
-
-
-char *
-proto_type(u_int type)
-{
- static char buf[80];
-
- switch (type) {
- case PROTO_DVMRP:
- return ("DVMRP");
- case PROTO_MOSPF:
- return ("MOSPF");
- case PROTO_PIM:
- return ("PIM");
- case PROTO_CBT:
- return ("CBT");
- case PROTO_PIM_SPEC:
- return ("PIM-special");
- case PROTO_PIM_STAT:
- return ("PIM-static");
- case PROTO_DVMRP_STAT:
- return ("DVMRP-static");
- case PROTO_PIM_MBGP:
- return ("PIM/MBGP");
- default:
- (void)snprintf(buf, sizeof buf, "Unknown protocol code %d", type);
- return (buf);
- }
-}
-
-
-char *
-flag_type(u_int type)
-{
- static char buf[80];
-
- switch (type) {
- case TR_NO_ERR:
- return ("");
- case TR_WRONG_IF:
- return ("Wrong interface");
- case TR_PRUNED:
- return ("Prune sent upstream");
- case TR_OPRUNED:
- return ("Output pruned");
- case TR_SCOPED:
- return ("Hit scope boundary");
- case TR_NO_RTE:
- return ("No route");
- case TR_OLD_ROUTER:
- return ("Next router no mtrace");
- case TR_NO_FWD:
- return ("Not forwarding");
- case TR_NO_SPACE:
- return ("No space in packet");
- case TR_RP_OR_CORE:
- return ("RP/Core");
- case TR_RPF_INT:
- return ("Trace packet on RPT interface");
- case TR_NO_MULTICAST:
- return ("Trace packet on non-MC interface");
- case TR_ADMIN_DENY:
- return ("Trace admin-denied");
- default:
- (void)snprintf(buf, sizeof buf, "Unknown error code %d", type);
- return (buf);
- }
-}
-
-/*
- * If destination is on a local net, get the netmask, else set the
- * netmask to all ones. There are two side effects: if the local
- * address was not explicitly set, and if the destination is on a
- * local net, use that one; in either case, verify that the local
- * address is valid.
- */
-
-u_int32_t
-get_netmask(int s, u_int32_t dst)
-{
- unsigned int i;
- char ifbuf[5000];
- struct ifconf ifc;
- struct ifreq *ifr;
- u_int32_t if_addr, if_mask;
- u_int32_t retval = 0xFFFFFFFF;
- int found = FALSE;
-
- ifc.ifc_buf = ifbuf;
- ifc.ifc_len = sizeof(ifbuf);
- if (ioctl(s, SIOCGIFCONF, (char *) &ifc) < 0) {
- perror("ioctl (SIOCGIFCONF)");
- return (retval);
- }
- for (i = 0; i < ifc.ifc_len; ) {
- ifr = (struct ifreq *)((char *)ifc.ifc_req + i);
- i += sizeof(ifr->ifr_name) + ifr->ifr_addr.sa_len;
- if_addr = ((struct sockaddr_in *)&(ifr->ifr_addr))->sin_addr.s_addr;
- if (ioctl(s, SIOCGIFNETMASK, (char *)ifr) >= 0) {
- if_mask = ((struct sockaddr_in *)&(ifr->ifr_addr))->sin_addr.s_addr;
- if ((dst & if_mask) == (if_addr & if_mask)) {
- retval = if_mask;
- if (lcl_addr == 0) lcl_addr = if_addr;
- }
- }
- if (lcl_addr == if_addr) found = TRUE;
- }
- if (!found && lcl_addr != 0) {
- printf("Interface address is not valid\n");
- exit(1);
- }
- return (retval);
-}
-
-
-int
-get_ttl(struct resp_buf *buf)
-{
- int rno;
- struct tr_resp *b;
- u_int ttl;
-
- if (buf && (rno = buf->len) > 0) {
- b = buf->resps + rno - 1;
- ttl = b->tr_fttl;
-
- while (--rno > 0) {
- --b;
- if (ttl < b->tr_fttl) ttl = b->tr_fttl;
- else ++ttl;
- }
- ttl += MULTICAST_TTL_INC;
- if (ttl < MULTICAST_TTL1) ttl = MULTICAST_TTL1;
- if (ttl > MULTICAST_TTL_MAX) ttl = MULTICAST_TTL_MAX;
- return (ttl);
- } else return(MULTICAST_TTL1);
-}
-
-/*
- * Calculate the difference between two 32-bit NTP timestamps and return
- * the result in milliseconds.
- */
-int
-t_diff(u_long a, u_long b)
-{
- int d = a - b;
-
- return ((d * 125) >> 13);
-}
-
-/*
- * Fixup for incorrect time format in 3.3 mrouted.
- * This is possible because (JAN_1970 mod 64K) is quite close to 32K,
- * so correct and incorrect times will be far apart.
- */
-u_long
-fixtime(u_long time)
-{
- if (abs((int)(time-base.qtime)) > 0x3FFFFFFF)
- time = ((time & 0xFFFF0000) + (JAN_1970 << 16)) +
- ((time & 0xFFFF) << 14) / 15625;
- return (time);
-}
-
-/*
- * Swap bytes for poor little-endian machines that don't byte-swap
- */
-u_long
-byteswap(u_long v)
-{
- return ((v << 24) | ((v & 0xff00) << 8) |
- ((v >> 8) & 0xff00) | (v >> 24));
-}
-
-int
-send_recv(u_int32_t dst, int type, int code, int tries, struct resp_buf *save)
-{
- struct pollfd set[1];
- struct timeval tq, tr, tv;
- struct ip *ip;
- struct igmp *igmp;
- struct tr_query *query, *rquery;
- int ipdatalen, iphdrlen, igmpdatalen;
- u_int32_t local, group;
- int datalen;
- int count, recvlen, dummy = 0;
- int len;
- int i;
-
- if (type == IGMP_MTRACE_QUERY) {
- group = qgrp;
- datalen = sizeof(struct tr_query);
- } else {
- group = htonl(MROUTED_LEVEL);
- datalen = 0;
- }
- if (IN_MULTICAST(ntohl(dst))) local = lcl_addr;
- else local = INADDR_ANY;
-
- /*
- * If the reply address was not explictly specified, start off
- * with the unicast address of this host. Then, if there is no
- * response after trying half the tries with unicast, switch to
- * the standard multicast reply address. If the TTL was also not
- * specified, set a multicast TTL and if needed increase it for the
- * last quarter of the tries.
- */
- query = (struct tr_query *)(send_buf + MIN_IP_HEADER_LEN + IGMP_MINLEN);
- query->tr_raddr = raddr ? raddr : multicast ? resp_cast : lcl_addr;
- query->tr_rttl = rttl ? rttl :
- IN_MULTICAST(ntohl(query->tr_raddr)) ? get_ttl(save) : UNICAST_TTL;
- query->tr_src = qsrc;
- query->tr_dst = qdst;
-
- for (i = tries ; i > 0; --i) {
- if (tries == nqueries && raddr == 0) {
- if (i == ((nqueries + 1) >> 1)) {
- query->tr_raddr = resp_cast;
- if (rttl == 0) query->tr_rttl = get_ttl(save);
- }
- if (i <= ((nqueries + 3) >> 2) && rttl == 0) {
- query->tr_rttl += MULTICAST_TTL_INC;
- if (query->tr_rttl > MULTICAST_TTL_MAX)
- query->tr_rttl = MULTICAST_TTL_MAX;
- }
- }
-
- /*
- * Change the qid for each request sent to avoid being confused
- * by duplicate responses
- */
-#ifdef SYSV
- query->tr_qid = ((u_int32_t)lrand48() >> 8);
-#else
- query->tr_qid = ((u_int32_t)random() >> 8);
-#endif
-
- /*
- * Set timer to calculate delays, then send query
- */
- gettimeofday(&tq, 0);
- send_igmp(local, dst, type, code, group, datalen);
-
- /*
- * Wait for response, discarding false alarms
- */
- set[0].fd = igmp_socket;
- set[0].events = POLLIN;
- while (TRUE) {
- gettimeofday(&tv, 0);
- tv.tv_sec = tq.tv_sec + timeout - tv.tv_sec;
- tv.tv_usec = tq.tv_usec - tv.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 = poll(set, 1, tv.tv_sec * 1000 + tv.tv_usec / 1000);
-
- if (count < 0) {
- if (errno != EINTR) perror("select");
- continue;
- } else if (count == 0) {
- printf("* ");
- fflush(stdout);
- break;
- }
-
- gettimeofday(&tr, 0);
- recvlen = recvfrom(igmp_socket, recv_buf, RECV_BUF_SIZE,
- 0, (struct sockaddr *)0, &dummy);
-
- if (recvlen <= 0) {
- if (recvlen && errno != EINTR) perror("recvfrom");
- continue;
- }
-
- if (recvlen < sizeof(struct ip)) {
- fprintf(stderr,
- "packet too short (%u bytes) for IP header", recvlen);
- continue;
- }
- ip = (struct ip *) recv_buf;
- if (ip->ip_p == 0) /* ignore cache creation requests */
- continue;
-
- iphdrlen = ip->ip_hl << 2;
- ipdatalen = ip->ip_len;
- if (iphdrlen + ipdatalen != recvlen) {
- fprintf(stderr,
- "packet shorter (%u bytes) than hdr+data len (%u+%u)\n",
- recvlen, iphdrlen, ipdatalen);
- continue;
- }
-
- igmp = (struct igmp *) (recv_buf + iphdrlen);
- igmpdatalen = ipdatalen - IGMP_MINLEN;
- if (igmpdatalen < 0) {
- fprintf(stderr,
- "IP data field too short (%u bytes) for IGMP from %s\n",
- ipdatalen, inet_fmt(ip->ip_src.s_addr, s1));
- continue;
- }
-
- switch (igmp->igmp_type) {
-
- case IGMP_DVMRP:
- if (igmp->igmp_code != DVMRP_NEIGHBORS2) continue;
- len = igmpdatalen;
- /*
- * Accept DVMRP_NEIGHBORS2 response if it comes from the
- * address queried or if that address is one of the local
- * addresses in the response.
- */
- if (ip->ip_src.s_addr != dst) {
- u_int32_t *p = (u_int32_t *)(igmp + 1);
- u_int32_t *ep = p + (len >> 2);
- while (p < ep) {
- u_int32_t laddr = *p++;
- int n = ntohl(*p++) & 0xFF;
- if (laddr == dst) {
- ep = p + 1; /* ensure p < ep after loop */
- break;
- }
- p += n;
- }
- if (p >= ep) continue;
- }
- break;
-
- case IGMP_MTRACE_QUERY: /* For backward compatibility with 3.3 */
- case IGMP_MTRACE_REPLY:
- if (igmpdatalen <= QLEN) continue;
- if ((igmpdatalen - QLEN)%RLEN) {
- printf("packet with incorrect datalen\n");
- continue;
- }
-
- /*
- * Ignore responses that don't match query.
- */
- rquery = (struct tr_query *)(igmp + 1);
- if (rquery->tr_qid != query->tr_qid) continue;
- if (rquery->tr_src != qsrc) continue;
- if (rquery->tr_dst != qdst) continue;
- len = (igmpdatalen - QLEN)/RLEN;
-
- /*
- * Ignore trace queries passing through this node when
- * mtrace is run on an mrouter that is in the path
- * (needed only because IGMP_MTRACE_QUERY is accepted above
- * for backward compatibility with multicast release 3.3).
- */
- if (igmp->igmp_type == IGMP_MTRACE_QUERY) {
- struct tr_resp *r = (struct tr_resp *)(rquery+1) + len - 1;
- u_int32_t smask;
-
- VAL_TO_MASK(smask, r->tr_smask);
- if (len < code && (r->tr_inaddr & smask) != (qsrc & smask)
- && r->tr_rmtaddr != 0 && !(r->tr_rflags & 0x80))
- continue;
- }
-
- /*
- * A match, we'll keep this one.
- */
- if (len > code) {
- fprintf(stderr,
- "Num hops received (%d) exceeds request (%d)\n",
- len, code);
- }
- rquery->tr_raddr = query->tr_raddr; /* Insure these are */
- rquery->tr_rttl = query->tr_rttl; /* as we sent them */
- break;
-
- default:
- continue;
- }
-
- /*
- * Most of the sanity checking done at this point.
- * Return this packet we have been waiting for.
- */
- if (save) {
- save->qtime = ((tq.tv_sec + JAN_1970) << 16) +
- (tq.tv_usec << 10) / 15625;
- save->rtime = ((tr.tv_sec + JAN_1970) << 16) +
- (tr.tv_usec << 10) / 15625;
- save->len = len;
- bcopy((char *)igmp, (char *)&save->igmp, ipdatalen);
- }
- return (recvlen);
- }
- }
- return (0);
-}
-
-/*
- * Most of this code is duplicated elsewhere. I'm not sure if
- * the duplication is absolutely required or not.
- *
- * Ideally, this would keep track of ongoing statistics
- * collection and print out statistics. (& keep track
- * of h-b-h traces and only print the longest) For now,
- * it just snoops on what traces it can.
- */
-void
-passive_mode(void)
-{
- struct timeval tr;
- struct ip *ip;
- struct igmp *igmp;
- struct tr_resp *r;
- int ipdatalen, iphdrlen, igmpdatalen;
- int len, recvlen, dummy = 0;
- u_int32_t smask;
-
- if (raddr) {
- if (IN_MULTICAST(ntohl(raddr))) k_join(raddr, INADDR_ANY);
- } else k_join(htonl(0xE0000120), INADDR_ANY);
-
- while (1) {
- recvlen = recvfrom(igmp_socket, recv_buf, RECV_BUF_SIZE,
- 0, (struct sockaddr *)0, &dummy);
- gettimeofday(&tr,0);
-
- if (recvlen <= 0) {
- if (recvlen && errno != EINTR) perror("recvfrom");
- continue;
- }
-
- if (recvlen < sizeof(struct ip)) {
- fprintf(stderr,
- "packet too short (%u bytes) for IP header", recvlen);
- continue;
- }
- ip = (struct ip *) recv_buf;
- if (ip->ip_p == 0) /* ignore cache creation requests */
- continue;
-
- iphdrlen = ip->ip_hl << 2;
- ipdatalen = ip->ip_len;
- if (iphdrlen + ipdatalen != recvlen) {
- fprintf(stderr,
- "packet shorter (%u bytes) than hdr+data len (%u+%u)\n",
- recvlen, iphdrlen, ipdatalen);
- continue;
- }
-
- igmp = (struct igmp *) (recv_buf + iphdrlen);
- igmpdatalen = ipdatalen - IGMP_MINLEN;
- if (igmpdatalen < 0) {
- fprintf(stderr,
- "IP data field too short (%u bytes) for IGMP from %s\n",
- ipdatalen, inet_fmt(ip->ip_src.s_addr, s1));
- continue;
- }
-
- switch (igmp->igmp_type) {
-
- case IGMP_MTRACE_QUERY: /* For backward compatibility with 3.3 */
- case IGMP_MTRACE_REPLY:
- if (igmpdatalen < QLEN) continue;
- if ((igmpdatalen - QLEN)%RLEN) {
- printf("packet with incorrect datalen\n");
- continue;
- }
-
- len = (igmpdatalen - QLEN)/RLEN;
-
- break;
-
- default:
- continue;
- }
-
- base.qtime = ((tr.tv_sec + JAN_1970) << 16) +
- (tr.tv_usec << 10) / 15625;
- base.rtime = ((tr.tv_sec + JAN_1970) << 16) +
- (tr.tv_usec << 10) / 15625;
- base.len = len;
- bcopy((char *)igmp, (char *)&base.igmp, ipdatalen);
- /*
- * If the user specified which traces to monitor,
- * only accept traces that correspond to the
- * request
- */
- if ((qsrc != 0 && qsrc != base.qhdr.tr_src) ||
- (qdst != 0 && qdst != base.qhdr.tr_dst) ||
- (qgrp != 0 && qgrp != igmp->igmp_group.s_addr))
- continue;
-
- printf("Mtrace from %s to %s via group %s (mxhop=%d)\n",
- inet_fmt(base.qhdr.tr_dst, s1), inet_fmt(base.qhdr.tr_src, s2),
- inet_fmt(igmp->igmp_group.s_addr, s3), igmp->igmp_code);
- if (len == 0)
- continue;
- printf(" 0 ");
- print_host(base.qhdr.tr_dst);
- printf("\n");
- print_trace(1, &base);
- r = base.resps + base.len - 1;
- VAL_TO_MASK(smask, r->tr_smask);
- if ((r->tr_inaddr & smask) == (base.qhdr.tr_src & smask)) {
- printf("%3d ", -(base.len+1));
- print_host(base.qhdr.tr_src);
- printf("\n");
- } else if (r->tr_rmtaddr != 0) {
- printf("%3d ", -(base.len+1));
- what_kind(&base, r->tr_rflags == TR_OLD_ROUTER ?
- "doesn't support mtrace"
- : "is the next hop");
- }
- printf("\n");
- }
-}
-
-char *
-print_host(u_int32_t addr)
-{
- return print_host2(addr, 0);
-}
-
-/*
- * On some routers, one interface has a name and the other doesn't.
- * We always print the address of the outgoing interface, but can
- * sometimes get the name from the incoming interface. This might be
- * confusing but should be slightly more helpful than just a "?".
- */
-char *
-print_host2(u_int32_t addr1, u_int32_t addr2)
-{
- char *name;
-
- if (numeric) {
- printf("%s", inet_fmt(addr1, s1));
- return ("");
- }
- name = inet_name(addr1);
- if (*name == '?' && *(name + 1) == '\0' && addr2 != 0)
- name = inet_name(addr2);
- printf("%s (%s)", name, inet_fmt(addr1, s1));
- return (name);
-}
-
-/*
- * Print responses as received (reverse path from dst to src)
- */
-void
-print_trace(int index, struct resp_buf *buf)
-{
- struct tr_resp *r;
- char *name;
- int i;
- int hop;
- char *ms, *ft;
-
- i = abs(index);
- r = buf->resps + i - 1;
-
- for (; i <= buf->len; ++i, ++r) {
- if (index > 0) printf("%3d ", -i);
- name = print_host2(r->tr_outaddr, r->tr_inaddr);
- printf(" %s thresh^ %d", proto_type(r->tr_rproto), r->tr_fttl);
- if (verbose) {
- hop = t_diff(fixtime(ntohl(r->tr_qarr)), buf->qtime);
- ms = scale(&hop);
- printf(" %d%s", hop, ms);
- }
- ft = flag_type(r->tr_rflags);
- if (strlen(ft) != 0)
- printf(" %s", ft);
- printf("\n");
- memcpy(names[i-1], name, sizeof(names[0]) - 1);
- names[i-1][sizeof(names[0])-1] = '\0';
- }
-}
-
-/*
- * See what kind of router is the next hop
- */
-int
-what_kind(struct resp_buf *buf, char *why)
-{
- u_int32_t smask;
- int retval;
- int hops = buf->len;
- struct tr_resp *r = buf->resps + hops - 1;
- u_int32_t next = r->tr_rmtaddr;
-
- retval = send_recv(next, IGMP_DVMRP, DVMRP_ASK_NEIGHBORS2, 1, &incr[0]);
- print_host(next);
- if (retval) {
- u_int32_t version = ntohl(incr[0].igmp.igmp_group.s_addr);
- u_int32_t *p = (u_int32_t *)incr[0].ndata;
- u_int32_t *ep = p + (incr[0].len >> 2);
- char *type = "";
- retval = 0;
- switch (version & 0xFF) {
- case 1:
- type = "proteon/mrouted ";
- retval = 1;
- break;
-
- case 2:
- case 3:
- if (((version >> 8) & 0xFF) < 3) retval = 1;
- /* Fall through */
- case 4:
- type = "mrouted ";
- break;
-
- case 10:
- type = "cisco ";
- }
- printf(" [%s%d.%d] %s\n",
- type, version & 0xFF, (version >> 8) & 0xFF,
- why);
- VAL_TO_MASK(smask, r->tr_smask);
- while (p < ep) {
- u_int32_t laddr = *p++;
- int flags = (ntohl(*p) & 0xFF00) >> 8;
- int n = ntohl(*p++) & 0xFF;
- if (!(flags & (DVMRP_NF_DOWN | DVMRP_NF_DISABLED)) &&
- (laddr & smask) == (qsrc & smask)) {
- printf("%3d ", -(hops+2));
- print_host(qsrc);
- printf("\n");
- return 1;
- }
- p += n;
- }
- return retval;
- }
- printf(" %s\n", why);
- return 0;
-}
-
-
-char *
-scale(int *hop)
-{
- if (*hop > -1000 && *hop < 10000) return (" ms");
- *hop /= 1000;
- if (*hop > -1000 && *hop < 10000) return (" s ");
- return ("s ");
-}
-
-/*
- * Calculate and print one line of packet loss and packet rate statistics.
- * Checks for count of all ones from mrouted 2.3 that doesn't have counters.
- */
-#define NEITHER 0
-#define INS 1
-#define OUTS 2
-#define BOTH 3
-void
-stat_line(struct tr_resp *r, struct tr_resp *s, int have_next, int *rst)
-{
- int timediff = (fixtime(ntohl(s->tr_qarr)) -
- fixtime(ntohl(r->tr_qarr))) >> 16;
- int v_lost, v_pct;
- int g_lost, g_pct;
- int v_out = ntohl(s->tr_vifout) - ntohl(r->tr_vifout);
- int g_out = ntohl(s->tr_pktcnt) - ntohl(r->tr_pktcnt);
- int v_pps, g_pps;
- char v_str[8], g_str[8];
- int have = NEITHER;
- int res = *rst;
-
- if (timediff == 0) timediff = 1;
- v_pps = v_out / timediff;
- g_pps = g_out / timediff;
-
- if ((v_out && (s->tr_vifout != 0xFFFFFFFF && s->tr_vifout != 0)) ||
- (r->tr_vifout != 0xFFFFFFFF && r->tr_vifout != 0))
- have |= OUTS;
-
- if (have_next) {
- --r, --s, --rst;
- if ((s->tr_vifin != 0xFFFFFFFF && s->tr_vifin != 0) ||
- (r->tr_vifin != 0xFFFFFFFF && r->tr_vifin != 0))
- have |= INS;
- if (*rst)
- res = 1;
- }
-
- switch (have) {
- case BOTH:
- v_lost = v_out - (ntohl(s->tr_vifin) - ntohl(r->tr_vifin));
- if (v_out) v_pct = (v_lost * 100 + (v_out >> 1)) / v_out;
- else v_pct = 0;
- if (-100 < v_pct && v_pct < 101 && v_out > 10)
- (void)snprintf(v_str, sizeof v_str, "%3d", v_pct);
- else memcpy(v_str, " --", 4);
-
- g_lost = g_out - (ntohl(s->tr_pktcnt) - ntohl(r->tr_pktcnt));
- if (g_out) g_pct = (g_lost * 100 + (g_out >> 1))/ g_out;
- else g_pct = 0;
- if (-100 < g_pct && g_pct < 101 && g_out > 10)
- (void)snprintf(g_str, sizeof g_str, "%3d", g_pct);
- else memcpy(g_str, " --", 4);
-
- printf("%6d/%-5d=%s%%%4d pps",
- v_lost, v_out, v_str, v_pps);
- if (res)
- printf("\n");
- else
- printf("%6d/%-5d=%s%%%4d pps\n",
- g_lost, g_out, g_str, g_pps);
- break;
-
- case INS:
- v_out = ntohl(s->tr_vifin) - ntohl(r->tr_vifin);
- v_pps = v_out / timediff;
- /* Fall through */
-
- case OUTS:
- printf(" %-5d %4d pps",
- v_out, v_pps);
- if (res)
- printf("\n");
- else
- printf(" %-5d %4d pps\n",
- g_out, g_pps);
- break;
-
- case NEITHER:
- printf("\n");
- break;
- }
-
- if (debug > 2) {
- printf("\t\t\t\tv_in: %ld ", (long)ntohl(s->tr_vifin));
- printf("v_out: %ld ", (long)ntohl(s->tr_vifout));
- printf("pkts: %ld\n", (long)ntohl(s->tr_pktcnt));
- printf("\t\t\t\tv_in: %ld ", (long)ntohl(r->tr_vifin));
- printf("v_out: %ld ", (long)ntohl(r->tr_vifout));
- printf("pkts: %ld\n", (long)ntohl(r->tr_pktcnt));
- printf("\t\t\t\tv_in: %ld ",
- (long)ntohl(s->tr_vifin)-ntohl(r->tr_vifin));
- printf("v_out: %ld ",
- (long)(ntohl(s->tr_vifout) - ntohl(r->tr_vifout)));
- printf("pkts: %ld ", (long)(ntohl(s->tr_pktcnt) - ntohl(r->tr_pktcnt)));
- printf("time: %d\n", timediff);
- printf("\t\t\t\tres: %d\n", res);
- }
-}
-
-/*
- * A fixup to check if any pktcnt has been reset, and to fix the
- * byteorder bugs in mrouted 3.6 on little-endian machines.
- */
-void
-fixup_stats(struct resp_buf *base, struct resp_buf *prev, struct resp_buf *new)
-{
- int rno = base->len;
- struct tr_resp *b = base->resps + rno;
- struct tr_resp *p = prev->resps + rno;
- struct tr_resp *n = new->resps + rno;
- int *r = reset + rno;
- int *s = swaps + rno;
- int res;
-
- /* Check for byte-swappers */
- while (--rno >= 0) {
- --n; --p; --b; --s;
- if (*s || abs(ntohl(n->tr_vifout) - ntohl(p->tr_vifout)) > 100000) {
- /* This host sends byteswapped reports; swap 'em */
- if (!*s) {
- *s = 1;
- b->tr_qarr = byteswap(b->tr_qarr);
- b->tr_vifin = byteswap(b->tr_vifin);
- b->tr_vifout = byteswap(b->tr_vifout);
- b->tr_pktcnt = byteswap(b->tr_pktcnt);
- }
-
- n->tr_qarr = byteswap(n->tr_qarr);
- n->tr_vifin = byteswap(n->tr_vifin);
- n->tr_vifout = byteswap(n->tr_vifout);
- n->tr_pktcnt = byteswap(n->tr_pktcnt);
- }
- }
-
- rno = base->len;
- b = base->resps + rno;
- p = prev->resps + rno;
- n = new->resps + rno;
-
- while (--rno >= 0) {
- --n; --p; --b; --r;
- res = ((ntohl(n->tr_pktcnt) < ntohl(b->tr_pktcnt)) ||
- (ntohl(n->tr_pktcnt) < ntohl(p->tr_pktcnt)));
- if (debug > 2)
- printf("\t\tr=%d, res=%d\n", *r, res);
- if (*r) {
- if (res || *r > 1) {
- /*
- * This router appears to be a 3.4 with that nasty ol'
- * neighbor version bug, which causes it to constantly
- * reset. Just nuke the statistics for this node, and
- * don't even bother giving it the benefit of the
- * doubt from now on.
- */
- p->tr_pktcnt = b->tr_pktcnt = n->tr_pktcnt;
- r++;
- } else {
- /*
- * This is simply the situation that the original
- * fixup_stats was meant to deal with -- that a
- * 3.3 or 3.4 router deleted a cache entry while
- * traffic was still active.
- */
- *r = 0;
- break;
- }
- } else
- *r = res;
- }
-
- if (rno < 0) return;
-
- rno = base->len;
- b = base->resps + rno;
- p = prev->resps + rno;
-
- while (--rno >= 0) (--b)->tr_pktcnt = (--p)->tr_pktcnt;
-}
-
-/*
- * Print responses with statistics for forward path (from src to dst)
- */
-int
-print_stats(struct resp_buf *base, struct resp_buf *prev, struct resp_buf *new)
-{
- int rtt, hop;
- char *ms;
- u_int32_t smask;
- int rno = base->len - 1;
- struct tr_resp *b = base->resps + rno;
- struct tr_resp *p = prev->resps + rno;
- struct tr_resp *n = new->resps + rno;
- int *r = reset + rno;
- u_long resptime = new->rtime;
- u_long qarrtime = fixtime(ntohl(n->tr_qarr));
- u_int ttl = n->tr_fttl;
- int first = (base == prev);
-
- VAL_TO_MASK(smask, b->tr_smask);
- printf(" Source Response Dest");
- printf(" Packet Statistics For Only For Traffic\n");
- printf("%-15s %-15s All Multicast Traffic From %s\n",
- ((b->tr_inaddr & smask) == (qsrc & smask)) ? s1 : " * * * ",
- inet_fmt(base->qhdr.tr_raddr, s2), inet_fmt(qsrc, s1));
- rtt = t_diff(resptime, new->qtime);
- ms = scale(&rtt);
- printf(" %c __/ rtt%5d%s Lost/Sent = Pct Rate To %s\n",
- first ? 'v' : '|', rtt, ms, inet_fmt(qgrp, s2));
- if (!first) {
- hop = t_diff(resptime, qarrtime);
- ms = scale(&hop);
- printf(" v / hop%5d%s", hop, ms);
- printf(" --------------------- --------------------\n");
- }
- if (debug > 2) {
- printf("\t\t\t\tv_in: %ld ", (long)ntohl(n->tr_vifin));
- printf("v_out: %ld ", (long)ntohl(n->tr_vifout));
- printf("pkts: %ld\n", (long)ntohl(n->tr_pktcnt));
- printf("\t\t\t\tv_in: %ld ", (long)ntohl(b->tr_vifin));
- printf("v_out: %ld ", (long)ntohl(b->tr_vifout));
- printf("pkts: %ld\n", (long)ntohl(b->tr_pktcnt));
- printf("\t\t\t\tv_in: %ld ",
- (long)(ntohl(n->tr_vifin) - ntohl(b->tr_vifin)));
- printf("v_out: %ld ",
- (long)(ntohl(n->tr_vifout) - ntohl(b->tr_vifout)));
- printf("pkts: %ld\n",
- (long)(ntohl(n->tr_pktcnt) - ntohl(b->tr_pktcnt)));
- printf("\t\t\t\treset: %d\n", *r);
- }
-
- while (TRUE) {
- if ((n->tr_inaddr != b->tr_inaddr) || (n->tr_inaddr != b->tr_inaddr))
- return 1; /* Route changed */
-
- if ((n->tr_inaddr != n->tr_outaddr))
- printf("%-15s\n", inet_fmt(n->tr_inaddr, s1));
- printf("%-15s %-14s %s\n", inet_fmt(n->tr_outaddr, s1), names[rno],
- flag_type(n->tr_rflags));
-
- if (rno-- < 1) break;
-
- printf(" %c ^ ttl%5d ", first ? 'v' : '|', ttl);
- stat_line(p, n, TRUE, r);
- if (!first) {
- resptime = qarrtime;
- qarrtime = fixtime(ntohl((n-1)->tr_qarr));
- hop = t_diff(resptime, qarrtime);
- ms = scale(&hop);
- printf(" v | hop%5d%s", hop, ms);
- stat_line(b, n, TRUE, r);
- }
-
- --b, --p, --n, --r;
- if (ttl < n->tr_fttl) ttl = n->tr_fttl;
- else ++ttl;
- }
-
- printf(" %c \\__ ttl%5d ", first ? 'v' : '|', ttl);
- stat_line(p, n, FALSE, r);
- if (!first) {
- hop = t_diff(qarrtime, new->qtime);
- ms = scale(&hop);
- printf(" v \\ hop%5d%s", hop, ms);
- stat_line(b, n, FALSE, r);
- }
- printf("%-15s %s\n", inet_fmt(qdst, s1), inet_fmt(lcl_addr, s2));
- printf(" Receiver Query Source\n\n");
- return 0;
-}
-
-
-/***************************************************************************
- * main
- ***************************************************************************/
-
-int
-main(int argc, char **argv)
-{
- int udp;
- struct sockaddr_in addr;
- int addrlen = sizeof(addr);
- int recvlen;
- struct timeval tv;
- struct resp_buf *prev, *new;
- struct tr_resp *r;
- u_int32_t smask;
- int rno;
- int hops, nexthop, tries;
- u_int32_t lastout = 0;
- int numstats = 1;
- int waittime;
- int seed;
-
- if (geteuid() != 0) {
- fprintf(stderr, "mtrace: must be root\n");
- exit(1);
- }
- init_igmp();
- if (setuid(getuid()) == -1)
- logit(LOG_ERR, errno, "setuid");
-
- argv++, argc--;
- if (argc == 0) goto usage;
-
- while (argc > 0 && *argv[0] == '-') {
- char *p = *argv++; argc--;
- p++;
- do {
- char c = *p++;
- char *arg = (char *) 0;
- if (isdigit(*p)) {
- arg = p;
- p = "";
- } else if (argc > 0) arg = argv[0];
- switch (c) {
- case 'd': /* Unlisted debug print option */
- if (arg && isdigit(*arg)) {
- debug = atoi(arg);
- if (debug < 0) debug = 0;
- if (debug > 3) debug = 3;
- if (arg == argv[0]) argv++, argc--;
- break;
- } else
- goto usage;
- case 'M': /* Use multicast for reponse */
- multicast = TRUE;
- break;
- case 'l': /* Loop updating stats indefinitely */
- numstats = 3153600;
- break;
- case 'n': /* Don't reverse map host addresses */
- numeric = TRUE;
- break;
- case 'p': /* Passive listen for traces */
- passive = TRUE;
- break;
- case 'v': /* Verbosity */
- verbose = TRUE;
- break;
- case 's': /* Short form, don't wait for stats */
- numstats = 0;
- break;
- case 'w': /* Time to wait for packet arrival */
- if (arg && isdigit(*arg)) {
- timeout = atoi(arg);
- if (timeout < 1) timeout = 1;
- if (arg == argv[0]) argv++, argc--;
- break;
- } else
- goto usage;
- case 'm': /* Max number of hops to trace */
- if (arg && isdigit(*arg)) {
- qno = atoi(arg);
- if (qno > MAXHOPS) qno = MAXHOPS;
- else if (qno < 1) qno = 0;
- if (arg == argv[0]) argv++, argc--;
- break;
- } else
- goto usage;
- case 'q': /* Number of query retries */
- if (arg && isdigit(*arg)) {
- nqueries = atoi(arg);
- if (nqueries < 1) nqueries = 1;
- if (arg == argv[0]) argv++, argc--;
- break;
- } else
- goto usage;
- case 'g': /* Last-hop gateway (dest of query) */
- if (arg && (gwy = host_addr(arg))) {
- if (arg == argv[0]) argv++, argc--;
- break;
- } else
- goto usage;
- case 't': /* TTL for query packet */
- if (arg && isdigit(*arg)) {
- qttl = atoi(arg);
- if (qttl < 1) qttl = 1;
- rttl = qttl;
- if (arg == argv[0]) argv++, argc--;
- break;
- } else
- goto usage;
- case 'r': /* Dest for response packet */
- if (arg && (raddr = host_addr(arg))) {
- if (arg == argv[0]) argv++, argc--;
- break;
- } else
- goto usage;
- case 'i': /* Local interface address */
- if (arg && (lcl_addr = host_addr(arg))) {
- if (arg == argv[0]) argv++, argc--;
- break;
- } else
- goto usage;
- case 'S': /* Stat accumulation interval */
- if (arg && isdigit(*arg)) {
- statint = atoi(arg);
- if (statint < 1) statint = 1;
- if (arg == argv[0]) argv++, argc--;
- break;
- } else
- goto usage;
- default:
- goto usage;
- }
- } while (*p);
- }
-
- if (argc > 0 && (qsrc = host_addr(argv[0]))) { /* Source of path */
- if (IN_MULTICAST(ntohl(qsrc))) goto usage;
- argv++, argc--;
- if (argc > 0 && (qdst = host_addr(argv[0]))) { /* Dest of path */
- argv++, argc--;
- if (argc > 0 && (qgrp = host_addr(argv[0]))) { /* Path via group */
- argv++, argc--;
- }
- if (IN_MULTICAST(ntohl(qdst))) {
- u_int32_t temp = qdst;
- qdst = qgrp;
- qgrp = temp;
- if (IN_MULTICAST(ntohl(qdst))) goto usage;
- } else if (qgrp && !IN_MULTICAST(ntohl(qgrp))) goto usage;
- }
- }
-
- if (passive) {
- passive_mode();
- return(0);
- }
-
- if (argc > 0 || qsrc == 0) {
-usage: printf("\
-Usage: mtrace [-Mlnps] [-w wait] [-m max_hops] [-q nqueries] [-g gateway]\n\
- [-S statint] [-t ttl] [-r resp_dest] [-i if_addr] source [receiver] [group]\n");
- exit(1);
- }
-
- /*
- * Set useful defaults for as many parameters as possible.
- */
-
- defgrp = htonl(0xE0020001); /* MBone Audio (224.2.0.1) */
- query_cast = htonl(0xE0000002); /* All routers multicast addr */
- resp_cast = htonl(0xE0000120); /* Mtrace response multicast addr */
- if (qgrp == 0) qgrp = defgrp;
-
- /*
- * Get default local address for multicasts to use in setting defaults.
- */
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
-#if (defined(BSD) && (BSD >= 199103))
- addr.sin_len = sizeof(addr);
-#endif
- addr.sin_addr.s_addr = qgrp;
- addr.sin_port = htons(2000); /* Any port above 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);
- }
-
-#ifdef SUNOS5
- /*
- * SunOS 5.X prior to SunOS 2.6, getsockname returns 0 for udp socket.
- * This call to sysinfo will return the hostname.
- * If the default multicast interfface (set with the route
- * for 224.0.0.0) is not the same as the hostname,
- * mtrace -i [if_addr] will have to be used.
- */
- if (addr.sin_addr.s_addr == 0) {
- char myhostname[MAXHOSTNAMELEN];
- struct hostent *hp;
- int error;
-
- error = sysinfo(SI_HOSTNAME, myhostname, sizeof(myhostname));
- if (error == -1) {
- perror("Getting my hostname");
- exit(1);
- }
-
- hp = gethostbyname(myhostname);
- if (hp == NULL || hp->h_addrtype != AF_INET ||
- hp->h_length != sizeof(addr.sin_addr)) {
- perror("Finding IP address for my hostname");
- exit(1);
- }
-
- memcpy((char *)&addr.sin_addr.s_addr, hp->h_addr,
- sizeof(addr.sin_addr.s_addr));
- }
-#endif
-
- /*
- * Default destination for path to be queried is the local host.
- */
- if (qdst == 0) qdst = lcl_addr ? lcl_addr : addr.sin_addr.s_addr;
- dst_netmask = get_netmask(udp, qdst);
- close(udp);
- if (lcl_addr == 0) lcl_addr = addr.sin_addr.s_addr;
-
- /*
- * Initialize the seed for random query identifiers.
- */
- gettimeofday(&tv, 0);
- seed = tv.tv_usec ^ lcl_addr;
-#ifdef SYSV
- srand48(seed);
-#else
- srandom(seed);
-#endif
-
- /*
- * Protect against unicast queries to mrouted versions that might crash.
- */
- if (gwy && !IN_MULTICAST(ntohl(gwy)))
- if (send_recv(gwy, IGMP_DVMRP, DVMRP_ASK_NEIGHBORS2, 1, &incr[0])) {
- int version = ntohl(incr[0].igmp.igmp_group.s_addr) & 0xFFFF;
- if (version == 0x0303 || version == 0x0503) {
- printf("Don't use -g to address an mrouted 3.%d, it might crash\n",
- (version >> 8) & 0xFF);
- exit(0);
- }
- }
-
- printf("Mtrace from %s to %s via group %s\n",
- inet_fmt(qsrc, s1), inet_fmt(qdst, s2), inet_fmt(qgrp, s3));
-
- if ((qdst & dst_netmask) == (qsrc & dst_netmask)) {
- printf("Source & receiver are directly connected, no path to trace\n");
- exit(0);
- }
-
- /*
- * If the response is to be a multicast address, make sure we
- * are listening on that multicast address.
- */
- if (raddr) {
- if (IN_MULTICAST(ntohl(raddr))) k_join(raddr, lcl_addr);
- } else k_join(resp_cast, lcl_addr);
-
- /*
- * If the destination is on the local net, the last-hop router can
- * be found by multicast to the all-routers multicast group.
- * Otherwise, use the group address that is the subject of the
- * query since by definition the last-hop router will be a member.
- * Set default TTLs for local remote multicasts.
- */
- restart:
-
- if (gwy == 0)
- if ((qdst & dst_netmask) == (lcl_addr & dst_netmask)) tdst = query_cast;
- else tdst = qgrp;
- else tdst = gwy;
-
- if (IN_MULTICAST(ntohl(tdst))) {
- k_set_loop(1); /* If I am running on a router, I need to hear this */
- if (tdst == query_cast) k_set_ttl(qttl ? qttl : 1);
- else k_set_ttl(qttl ? qttl : MULTICAST_TTL1);
- }
-
- /*
- * Try a query at the requested number of hops or MAXHOPS if unspecified.
- */
- if (qno == 0) {
- hops = MAXHOPS;
- tries = 1;
- printf("Querying full reverse path... ");
- fflush(stdout);
- } else {
- hops = qno;
- tries = nqueries;
- printf("Querying reverse path, maximum %d hops... ", qno);
- fflush(stdout);
- }
- base.rtime = 0;
- base.len = 0;
-
- recvlen = send_recv(tdst, IGMP_MTRACE_QUERY, hops, tries, &base);
-
- /*
- * If the initial query was successful, print it. Otherwise, if
- * the query max hop count is the default of zero, loop starting
- * from one until there is no response for four hops. The extra
- * hops allow getting past an mtrace-capable mrouter that can't
- * send multicast packets because all phyints are disabled.
- */
- if (recvlen) {
- printf("\n 0 ");
- print_host(qdst);
- printf("\n");
- print_trace(1, &base);
- r = base.resps + base.len - 1;
- if (r->tr_rflags == TR_OLD_ROUTER || r->tr_rflags == TR_NO_SPACE ||
- qno != 0) {
- printf("%3d ", -(base.len+1));
- what_kind(&base, r->tr_rflags == TR_OLD_ROUTER ?
- "doesn't support mtrace"
- : "is the next hop");
- } else {
- VAL_TO_MASK(smask, r->tr_smask);
- if ((r->tr_inaddr & smask) == (qsrc & smask)) {
- printf("%3d ", -(base.len+1));
- print_host(qsrc);
- printf("\n");
- }
- }
- } else if (qno == 0) {
- printf("switching to hop-by-hop:\n 0 ");
- print_host(qdst);
- printf("\n");
-
- for (hops = 1, nexthop = 1; hops <= MAXHOPS; ++hops) {
- printf("%3d ", -hops);
- fflush(stdout);
-
- /*
- * After a successful first hop, try switching to the unicast
- * address of the last-hop router instead of multicasting the
- * trace query. This should be safe for mrouted versions 3.3
- * and 3.5 because there is a long route timeout with metric
- * infinity before a route disappears. Switching to unicast
- * reduces the amount of multicast traffic and avoids a bug
- * with duplicate suppression in mrouted 3.5.
- */
- if (hops == 2 && gwy == 0 &&
- (recvlen = send_recv(lastout, IGMP_MTRACE_QUERY, hops, 1, &base)))
- tdst = lastout;
- else recvlen = send_recv(tdst, IGMP_MTRACE_QUERY, hops, nqueries, &base);
-
- if (recvlen == 0) {
- if (hops == 1) break;
- if (hops == nexthop) {
- if (what_kind(&base, "didn't respond")) {
- /* the ask_neighbors determined that the
- * not-responding router is the first-hop. */
- break;
- }
- } else if (hops < nexthop + 3) {
- printf("\n");
- } else {
- printf("...giving up\n");
- break;
- }
- continue;
- }
- r = base.resps + base.len - 1;
- if (base.len == hops &&
- (hops == 1 || (base.resps+nexthop-2)->tr_outaddr == lastout)) {
- if (hops == nexthop) {
- print_trace(-hops, &base);
- } else {
- printf("\nResuming...\n");
- print_trace(nexthop, &base);
- }
- } else {
- if (base.len < hops) {
- /*
- * A shorter trace than requested means a fatal error
- * occurred along the path, or that the route changed
- * to a shorter one.
- *
- * If the trace is longer than the last one we received,
- * then we are resuming from a skipped router (but there
- * is still probably a problem).
- *
- * If the trace is shorter than the last one we
- * received, then the route must have changed (and
- * there is still probably a problem).
- */
- if (nexthop <= base.len) {
- printf("\nResuming...\n");
- print_trace(nexthop, &base);
- } else if (nexthop > base.len + 1) {
- hops = base.len;
- printf("\nRoute must have changed...\n");
- print_trace(1, &base);
- }
- } else {
- /*
- * The last hop address is not the same as it was;
- * the route probably changed underneath us.
- */
- hops = base.len;
- printf("\nRoute must have changed...\n");
- print_trace(1, &base);
- }
- }
- lastout = r->tr_outaddr;
-
- if (base.len < hops ||
- r->tr_rmtaddr == 0 ||
- (r->tr_rflags & 0x80)) {
- VAL_TO_MASK(smask, r->tr_smask);
- if (r->tr_rmtaddr) {
- if (hops != nexthop) {
- printf("\n%3d ", -(base.len+1));
- }
- what_kind(&base, r->tr_rflags == TR_OLD_ROUTER ?
- "doesn't support mtrace" :
- "would be the next hop");
- /* XXX could do segmented trace if TR_NO_SPACE */
- } else if (r->tr_rflags == TR_NO_ERR &&
- (r->tr_inaddr & smask) == (qsrc & smask)) {
- printf("%3d ", -(hops + 1));
- print_host(qsrc);
- printf("\n");
- }
- break;
- }
-
- nexthop = hops + 1;
- }
- }
-
- if (base.rtime == 0) {
- printf("Timed out receiving responses\n");
- if (IN_MULTICAST(ntohl(tdst))) {
- if (tdst == query_cast)
- printf("Perhaps no local router has a route for source %s\n",
- inet_fmt(qsrc, s1));
- else
- printf("Perhaps receiver %s is not a member of group %s,\n"
- "or no router local to it has a route for source %s,\n"
- "or multicast at ttl %d doesn't reach its last-hop router"
- " for that source\n",
- inet_fmt(qdst, s2), inet_fmt(qgrp, s3), inet_fmt(qsrc, s1),
- qttl ? qttl : MULTICAST_TTL1);
- }
- exit(1);
- }
-
- printf("Round trip time %d ms\n\n", t_diff(base.rtime, base.qtime));
-
- /*
- * Use the saved response which was the longest one received,
- * and make additional probes after delay to measure loss.
- */
- raddr = base.qhdr.tr_raddr;
- rttl = base.qhdr.tr_rttl;
- gettimeofday(&tv, 0);
- waittime = statint - (((tv.tv_sec + JAN_1970) & 0xFFFF) - (base.qtime >> 16));
- prev = &base;
- new = &incr[numstats&1];
-
- while (numstats--) {
- if (waittime < 1) printf("\n");
- else {
- printf("Waiting to accumulate statistics... ");
- fflush(stdout);
- sleep((unsigned)waittime);
- }
- rno = base.len;
- recvlen = send_recv(tdst, IGMP_MTRACE_QUERY, rno, nqueries, new);
-
- if (recvlen == 0) {
- printf("Timed out.\n");
- exit(1);
- }
-
- if (rno != new->len) {
- printf("Trace length doesn't match:\n");
- /*
- * XXX Should this trace result be printed, or is that
- * too verbose? Perhaps it should just say restarting.
- * But if the path is changing quickly, this may be the
- * only snapshot of the current path. But, if the path
- * is changing that quickly, does the current path really
- * matter?
- */
- print_trace(1, new);
- printf("Restarting.\n\n");
- numstats++;
- goto restart;
- }
-
- printf("Results after %d seconds:\n\n",
- (int)((new->qtime - base.qtime) >> 16));
- fixup_stats(&base, prev, new);
- if (print_stats(&base, prev, new)) {
- printf("Route changed:\n");
- print_trace(1, new);
- printf("Restarting.\n\n");
- goto restart;
- }
- prev = new;
- new = &incr[numstats&1];
- waittime = statint;
- }
-
- /*
- * If the response was multicast back, leave the group
- */
- if (raddr) {
- if (IN_MULTICAST(ntohl(raddr))) k_leave(raddr, lcl_addr);
- } else k_leave(resp_cast, lcl_addr);
-
- return (0);
-}
-
-void
-check_vif_state(void)
-{
- logit(LOG_WARNING, errno, "sendto");
-}
-
-/*
- * 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.
- */
-void
-logit(int severity, int syserr, const char *format, ...)
-{
- va_list ap;
-
- switch (debug) {
- case 0: if (severity > LOG_WARNING) return;
- case 1: if (severity > LOG_NOTICE) return;
- case 2: if (severity > LOG_INFO ) return;
- default:
- if (severity == LOG_WARNING)
- fprintf(stderr, "warning - ");
- va_start(ap, format);
- vfprintf(stderr, format, ap);
- va_end(ap);
- if (syserr == 0)
- fprintf(stderr, "\n");
- else
- fprintf(stderr, ": %s\n", strerror(syserr));
- }
- if (severity <= LOG_ERR) exit(1);
-}
-
-/* dummies */
-void accept_probe(u_int32_t src, u_int32_t dst, char *p, int datalen,
- u_int32_t level)
-{
-}
-void accept_group_report(u_int32_t src, u_int32_t dst, u_int32_t group,
- int r_type)
-{
-}
-void accept_neighbor_request2(u_int32_t src, u_int32_t dst)
-{
-}
-void accept_report(u_int32_t src, u_int32_t dst, char *p, int datalen,
- u_int32_t level)
-{
-}
-void accept_neighbor_request(u_int32_t src, u_int32_t dst)
-{
-}
-void accept_prune(u_int32_t src, u_int32_t dst, char *p, int datalen)
-{
-}
-void accept_graft(u_int32_t src, u_int32_t dst, char *p, int datalen)
-{
-}
-void accept_g_ack(u_int32_t src, u_int32_t dst, char *p, int datalen)
-{
-}
-void add_table_entry(u_int32_t origin, u_int32_t mcastgrp)
-{
-}
-void accept_leave_message(u_int32_t src, u_int32_t dst, u_int32_t group)
-{
-}
-void accept_mtrace(u_int32_t src, u_int32_t dst, u_int32_t group, char *data,
- u_int no, int datalen)
-{
-}
-void accept_membership_query(u_int32_t src, u_int32_t dst, u_int32_t group,
- int tmo)
-{
-}
-void accept_neighbors(u_int32_t src, u_int32_t dst, u_char *p, int datalen,
- u_int32_t level)
-{
-}
-void accept_neighbors2(u_int32_t src, u_int32_t dst, u_char *p, int datalen,
- u_int32_t level)
-{
-}
-void accept_info_request(u_int32_t src, u_int32_t dst, u_char *p, int datalen)
-{
-}
-void accept_info_reply(u_int32_t src, u_int32_t dst, u_char *p, int datalen)
-{
-}
diff --git a/gnu/usr.sbin/map-mbone/Makefile b/gnu/usr.sbin/map-mbone/Makefile
deleted file mode 100644
index 7843fe0c844..00000000000
--- a/gnu/usr.sbin/map-mbone/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-# $NetBSD: Makefile,v 1.1 2002/10/01 03:50:12 itojun Exp $
-# from: Id: Makefile,v 1.5 1993/06/24 05:11:16 deering Exp
-
-.include <bsd.own.mk>
-
-.PATH: ${NETBSDSRCDIR}/gnu/dist/map-mbone ${NETBSDSRCDIR}/gnu/dist/mrouted
-CPPFLAGS+= -I${NETBSDSRCDIR}/gnu/dist/mrouted
-
-PROG= map-mbone
-SRCS= igmp.c inet.c kern.c mapper.c
-MAN= map-mbone.8
-
-.include <bsd.prog.mk>
diff --git a/gnu/usr.sbin/mrinfo/Makefile b/gnu/usr.sbin/mrinfo/Makefile
deleted file mode 100644
index df81c8acb06..00000000000
--- a/gnu/usr.sbin/mrinfo/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-# $NetBSD: Makefile,v 1.1 2002/10/01 03:50:12 itojun Exp $
-# from: Id: Makefile,v 1.5 1993/06/24 05:11:16 deering Exp
-
-.include <bsd.own.mk>
-
-.PATH: ${NETBSDSRCDIR}/gnu/dist/mrinfo ${NETBSDSRCDIR}/gnu/dist/mrouted
-CPPFLAGS+= -I${NETBSDSRCDIR}/gnu/dist/mrouted
-
-PROG= mrinfo
-SRCS= igmp.c inet.c kern.c mrinfo.c
-MAN= mrinfo.8
-BINOWN= root
-BINMODE=4555
-
-.include <bsd.prog.mk>
diff --git a/gnu/usr.sbin/mrouted/Makefile b/gnu/usr.sbin/mrouted/Makefile
deleted file mode 100644
index 28d5d6bbfda..00000000000
--- a/gnu/usr.sbin/mrouted/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-# $NetBSD: Makefile,v 1.2 2002/10/17 12:50:00 itojun Exp $
-# from: Id: Makefile,v 1.5 1993/06/24 05:11:16 deering Exp
-
-.include <bsd.own.mk>
-
-PROG= mrouted
-SRCS= callout.c cfparse.y config.c igmp.c inet.c kern.c main.c prune.c \
- route.c vif.c
-MAN= mrouted.8
-
-LDADD+= -lutil
-DPADD+= ${LIBUTIL}
-CPPFLAGS+=-I${NETBSDSRCDIR}/gnu/dist/mrouted -I${.CURDIR}
-
-.PATH: ${NETBSDSRCDIR}/gnu/dist/mrouted
-
-.include <bsd.prog.mk>
diff --git a/gnu/usr.sbin/mtrace/Makefile b/gnu/usr.sbin/mtrace/Makefile
deleted file mode 100644
index 047dd680c0f..00000000000
--- a/gnu/usr.sbin/mtrace/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-# $NetBSD: Makefile,v 1.1 2002/10/01 03:50:12 itojun Exp $
-# from: Id: Makefile,v 1.5 1993/06/24 05:11:16 deering Exp
-
-.include <bsd.own.mk>
-
-.PATH: ${NETBSDSRCDIR}/gnu/dist/mrouted ${NETBSDSRCDIR}/gnu/dist/mtrace
-CPPFLAGS+= -I${NETBSDSRCDIR}/gnu/dist/mrouted
-
-PROG= mtrace
-SRCS= igmp.c inet.c kern.c mtrace.c
-MAN= mtrace.8
-
-BINMODE=4555
-BINOWN= root
-
-.include <bsd.prog.mk>