This commit was manufactured by cvs2svn to create branch 'XEROX'.
This commit is contained in:
parent
15fe6b8712
commit
ed30da51aa
511
usr.sbin/mrouted/cfparse.y
Normal file
511
usr.sbin/mrouted/cfparse.y
Normal file
@ -0,0 +1,511 @@
|
||||
%{
|
||||
/*
|
||||
* Configuration file parser for mrouted.
|
||||
*
|
||||
* Written by Bill Fenner, NRL, 1994
|
||||
*
|
||||
* $Id: cfparse.y,v 3.5 1995/05/09 01:00:39 fenner Exp $
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <varargs.h>
|
||||
#include "defs.h"
|
||||
|
||||
static FILE *f;
|
||||
|
||||
extern int udp_socket;
|
||||
char *configfilename = _PATH_MROUTED_CONF;
|
||||
|
||||
extern int cache_lifetime;
|
||||
extern int max_prune_lifetime;
|
||||
|
||||
static int lineno;
|
||||
static struct ifreq ifbuf[32];
|
||||
static struct ifconf ifc;
|
||||
|
||||
static struct uvif *v;
|
||||
|
||||
static int order;
|
||||
|
||||
struct addrmask {
|
||||
u_int32 addr;
|
||||
int mask;
|
||||
};
|
||||
|
||||
struct boundnam {
|
||||
char *name;
|
||||
struct addrmask bound;
|
||||
};
|
||||
|
||||
#define MAXBOUNDS 20
|
||||
|
||||
struct boundnam boundlist[MAXBOUNDS]; /* Max. of 20 named boundaries */
|
||||
int numbounds = 0; /* Number of named boundaries */
|
||||
|
||||
%}
|
||||
|
||||
%union
|
||||
{
|
||||
int num;
|
||||
char *ptr;
|
||||
struct addrmask addrmask;
|
||||
u_int32 addr;
|
||||
};
|
||||
|
||||
%token CACHE_LIFETIME PRUNING
|
||||
%token PHYINT TUNNEL NAME
|
||||
%token DISABLE METRIC THRESHOLD RATE_LIMIT SRCRT BOUNDARY NETMASK ALTNET
|
||||
%token <num> BOOLEAN
|
||||
%token <num> NUMBER
|
||||
%token <ptr> STRING
|
||||
%token <addrmask> ADDRMASK
|
||||
%token <addr> ADDR
|
||||
|
||||
%type <addr> interface
|
||||
%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));
|
||||
|
||||
/*log(LOG_INFO, 0, "phyint: %x\n", v);*/
|
||||
}
|
||||
ifmods
|
||||
| TUNNEL interface ADDR {
|
||||
|
||||
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;
|
||||
}
|
||||
/*log(LOG_INFO, 0, "tunnel: %x\n", v);*/
|
||||
}
|
||||
tunnelmods
|
||||
{
|
||||
log(LOG_INFO, 0,
|
||||
"installing tunnel from %s to %s as vif #%u - rate=%d",
|
||||
inet_fmt($2, s1), inet_fmt($3, s2),
|
||||
numvifs, v->uv_rate_limit);
|
||||
|
||||
++numvifs;
|
||||
}
|
||||
| PRUNING BOOLEAN { pruning = $2; }
|
||||
| CACHE_LIFETIME NUMBER { cache_lifetime = $2;
|
||||
max_prune_lifetime = cache_lifetime * 2;
|
||||
}
|
||||
| NAME STRING boundary { if (numbounds >= MAXBOUNDS) {
|
||||
fatal("Too many named boundaries (max %d)", MAXBOUNDS);
|
||||
}
|
||||
|
||||
boundlist[numbounds].name = malloc(strlen($2) + 1);
|
||||
strcpy(boundlist[numbounds].name, $2);
|
||||
boundlist[numbounds++].bound = $3;
|
||||
}
|
||||
;
|
||||
|
||||
tunnelmods : /* empty */
|
||||
| tunnelmods /*{ log(LOG_INFO, 0, "tunnelmod: %x", v); }*/ tunnelmod
|
||||
;
|
||||
|
||||
tunnelmod : mod
|
||||
| SRCRT { fatal("Source-route tunnels not supported"); }
|
||||
;
|
||||
|
||||
ifmods : /* empty */
|
||||
| ifmods /*{ log(LOG_INFO, 0, "ifmod: %x", v); }*/ ifmod
|
||||
;
|
||||
|
||||
ifmod : mod
|
||||
| DISABLE { v->uv_flags |= VIFF_DISABLED; }
|
||||
| NETMASK ADDR { v->uv_subnetmask = $2; }
|
||||
| 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_mask, $2.mask);
|
||||
} else
|
||||
ph->pa_mask = v->uv_subnetmask;
|
||||
ph->pa_addr = $2.addr & ph->pa_mask;
|
||||
if ($2.addr & ~ph->pa_mask)
|
||||
warn("Extra addr %s/%d has host bits set",
|
||||
inet_fmt($2.addr,s1), $2.mask);
|
||||
ph->pa_next = v->uv_addrs;
|
||||
v->uv_addrs = ph;
|
||||
|
||||
}
|
||||
;
|
||||
|
||||
mod : THRESHOLD NUMBER { if ($2 < 1 || $2 > 255)
|
||||
fatal("Invalid threshold %d",$2);
|
||||
v->uv_threshold = $2;
|
||||
}
|
||||
| THRESHOLD {
|
||||
|
||||
warn("Expected number after threshold keyword");
|
||||
|
||||
}
|
||||
| METRIC NUMBER { if ($2 < 1 || $2 > UNREACHABLE)
|
||||
fatal("Invalid metric %d",$2);
|
||||
v->uv_metric = $2;
|
||||
}
|
||||
| METRIC {
|
||||
|
||||
warn("Expected number after metric keyword");
|
||||
|
||||
}
|
||||
| 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");
|
||||
|
||||
}
|
||||
| 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");
|
||||
|
||||
}
|
||||
;
|
||||
|
||||
interface : ADDR { $$ = $1; }
|
||||
| STRING {
|
||||
$$ = valid_if($1);
|
||||
if ($$ == 0)
|
||||
fatal("Invalid interface name %s",$1);
|
||||
}
|
||||
;
|
||||
|
||||
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; }
|
||||
;
|
||||
%%
|
||||
/*VARARGS1*/
|
||||
static void fatal(fmt, va_alist)
|
||||
char *fmt;
|
||||
va_dcl
|
||||
{
|
||||
va_list ap;
|
||||
char buf[200];
|
||||
|
||||
va_start(ap);
|
||||
vsprintf(buf, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
log(LOG_ERR,0,"%s: %s near line %d", configfilename, buf, lineno);
|
||||
}
|
||||
|
||||
/*VARARGS1*/
|
||||
static void warn(fmt, va_alist)
|
||||
char *fmt;
|
||||
va_dcl
|
||||
{
|
||||
va_list ap;
|
||||
char buf[200];
|
||||
|
||||
va_start(ap);
|
||||
vsprintf(buf, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
log(LOG_WARNING,0,"%s: %s near line %d", configfilename, buf, lineno);
|
||||
}
|
||||
|
||||
void yyerror(s)
|
||||
char *s;
|
||||
{
|
||||
log(LOG_ERR, 0, "%s: %s near line %d", configfilename, s, lineno);
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
int yylex()
|
||||
{
|
||||
int n;
|
||||
u_int32 addr;
|
||||
char *q;
|
||||
|
||||
if ((q = next_word()) == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcmp(q,"cache_lifetime"))
|
||||
return CACHE_LIFETIME;
|
||||
if (!strcmp(q,"pruning"))
|
||||
return PRUNING;
|
||||
if (!strcmp(q,"phyint"))
|
||||
return PHYINT;
|
||||
if (!strcmp(q,"tunnel"))
|
||||
return TUNNEL;
|
||||
if (!strcmp(q,"disable"))
|
||||
return DISABLE;
|
||||
if (!strcmp(q,"metric"))
|
||||
return METRIC;
|
||||
if (!strcmp(q,"threshold"))
|
||||
return THRESHOLD;
|
||||
if (!strcmp(q,"rate_limit"))
|
||||
return RATE_LIMIT;
|
||||
if (!strcmp(q,"srcrt") || !strcmp(q,"sourceroute"))
|
||||
return SRCRT;
|
||||
if (!strcmp(q,"boundary"))
|
||||
return BOUNDARY;
|
||||
if (!strcmp(q,"netmask"))
|
||||
return NETMASK;
|
||||
if (!strcmp(q,"name"))
|
||||
return NAME;
|
||||
if (!strcmp(q,"altnet"))
|
||||
return ALTNET;
|
||||
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;
|
||||
}
|
||||
yylval.ptr = q;
|
||||
return STRING;
|
||||
}
|
||||
|
||||
void config_vifs_from_file()
|
||||
{
|
||||
extern FILE *f;
|
||||
|
||||
order = 0;
|
||||
numbounds = 0;
|
||||
lineno = 0;
|
||||
|
||||
if ((f = fopen(configfilename, "r")) == NULL) {
|
||||
if (errno != ENOENT)
|
||||
log(LOG_ERR, errno, "can't open %s", configfilename);
|
||||
return;
|
||||
}
|
||||
|
||||
ifc.ifc_buf = (char *)ifbuf;
|
||||
ifc.ifc_len = sizeof(ifbuf);
|
||||
if (ioctl(udp_socket, SIOCGIFCONF, (char *)&ifc) < 0)
|
||||
log(LOG_ERR, errno, "ioctl SIOCGIFCONF");
|
||||
|
||||
yyparse();
|
||||
|
||||
close(f);
|
||||
}
|
||||
|
||||
static u_int32
|
||||
valid_if(s)
|
||||
char *s;
|
||||
{
|
||||
register vifi_t vifi;
|
||||
register struct uvif *v;
|
||||
|
||||
for (vifi=0, v=uvifs; vifi<numvifs; vifi++, v++)
|
||||
if (!strcmp(v->uv_name, s))
|
||||
return v->uv_lcl_addr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ifreq *
|
||||
ifconfaddr(ifcp, a)
|
||||
struct ifconf *ifcp;
|
||||
u_int32 a;
|
||||
{
|
||||
int n;
|
||||
struct ifreq *ifrp = (struct ifreq *)ifcp->ifc_buf;
|
||||
struct ifreq *ifend = (struct ifreq *)((char *)ifrp + ifcp->ifc_len);
|
||||
|
||||
while (ifrp < ifend) {
|
||||
if (ifrp->ifr_addr.sa_family == AF_INET &&
|
||||
((struct sockaddr_in *)&ifrp->ifr_addr)->sin_addr.s_addr == a)
|
||||
return (ifrp);
|
||||
#if (defined(BSD) && (BSD >= 199006))
|
||||
n = ifrp->ifr_addr.sa_len + sizeof(ifrp->ifr_name);
|
||||
if (n < sizeof(*ifrp))
|
||||
++ifrp;
|
||||
else
|
||||
ifrp = (struct ifreq *)((char *)ifrp + n);
|
||||
#else
|
||||
++ifrp;
|
||||
#endif
|
||||
}
|
||||
return (0);
|
||||
}
|
97
usr.sbin/mrouted/map-mbone.8
Normal file
97
usr.sbin/mrouted/map-mbone.8
Normal file
@ -0,0 +1,97 @@
|
||||
.Dd March 31, 1995
|
||||
.Dt MAP-MBONE 8
|
||||
.Os FreeBSD 2.0
|
||||
.Sh NAME
|
||||
.Nm map-mbone
|
||||
.Nd multicast connection mapper
|
||||
.Sh SYNOPSIS
|
||||
.Nm map-mbone
|
||||
.Op Fl d Ar debuglevel
|
||||
.Op Fl f
|
||||
.Op Fl g
|
||||
.Op Fl n
|
||||
.Op Fl r Ar retries
|
||||
.Op Fl t Ar timeout
|
||||
.Op Ar router
|
||||
.Sh DESCRIPTION
|
||||
.Nm map-mbone
|
||||
attempts to display all multicast routers that are reachable from the multicast
|
||||
router
|
||||
.Ar router .
|
||||
If not specified on the command line, the default
|
||||
.Ar router
|
||||
is the local host.
|
||||
.Nm
|
||||
traverses neighboring multicast routers by sending the
|
||||
.Dv ASK_NEIGHBORS
|
||||
.Tn IGMP
|
||||
message to each 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
|
||||
.Nm
|
||||
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
|
||||
.Nm
|
||||
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.
|
||||
.Pp
|
||||
The options supported by
|
||||
.Nm
|
||||
are as follows:
|
||||
.Bl -tag -width XXXdebuglevel
|
||||
.It Fl d Ar debuglevel
|
||||
This sets the debug level to
|
||||
.Ar debuglevel .
|
||||
When the debug level is greater than the default value of 0,
|
||||
additional 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:
|
||||
.Bl -tag -width "level 3"
|
||||
.It level 1
|
||||
packet warnings are printed to stderr.
|
||||
.It level 2
|
||||
all level 1 messages plus notifications down networks are printed to stderr.
|
||||
.It level 3
|
||||
all level 2 messages plus notifications of all packet
|
||||
timeouts are printed to stderr.
|
||||
.El
|
||||
.It Fl f
|
||||
This option enables flooding. Flooding allows
|
||||
.Nm
|
||||
to perform recursive search
|
||||
of neighboring multicast routers and is enabled by default when an
|
||||
initial
|
||||
.Ar router
|
||||
is not specified.
|
||||
.It Fl g
|
||||
This option enables graphing in GraphEd format.
|
||||
.It Fl n
|
||||
This option disables the DNS lookup for the multicast routers' names.
|
||||
.It Fl r Ar retries
|
||||
This options sets the neighbor query retry limit to
|
||||
.Ar retries .
|
||||
The default is one retry.
|
||||
.It Fl t Ar timeout
|
||||
This option sets the number of seconds to wait for a neighbor query
|
||||
reply before retrying. The default timeout is two seconds.
|
||||
.Sh RESTRICTIONS
|
||||
.Nm
|
||||
must be run as `root'.
|
||||
.Sh SEE ALSO
|
||||
.Xr mrinfo 8 ,
|
||||
.Xr mrouted 8 ,
|
||||
.Xr mtrace 8
|
||||
.Sh AUTHOR
|
||||
Pavel Curtis
|
||||
.Sh HISTORY
|
||||
A
|
||||
.Nm
|
||||
command first appeared in
|
||||
.Tn FreeBSD
|
||||
2.0.
|
92
usr.sbin/mrouted/mrinfo.8
Normal file
92
usr.sbin/mrouted/mrinfo.8
Normal file
@ -0,0 +1,92 @@
|
||||
.Dd March 31, 1995
|
||||
.Dt MRINFO 8
|
||||
.Sh NAME
|
||||
.Nm mrinfo
|
||||
.Nd displays configuration info from a multicast router
|
||||
.Sh SYNOPSIS
|
||||
.Nm mrinfo
|
||||
.Op Fl d Ar debuglevel
|
||||
.Op Fl r Ar retries
|
||||
.Op Fl t Ar timeout
|
||||
.Ar router
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm mrinfo
|
||||
program attempts to display the configuration information from the
|
||||
multicast router
|
||||
.Ar router .
|
||||
.Pp
|
||||
.Nm
|
||||
uses the
|
||||
.Dv ASK_NEIGHBORS
|
||||
.Tn 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
|
||||
.Nm 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.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
program accepts the following options:
|
||||
.Bl -tag -width XXXdebuglevel
|
||||
.It Fl d Ar debuglevel
|
||||
This option sets the debug level to
|
||||
.Ar debuglevel .
|
||||
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
|
||||
.Nm
|
||||
to terminate.
|
||||
Non-zero debug levels have the following effects:
|
||||
.Bl -tag -width "level 3"
|
||||
.It level 1
|
||||
packet warnings are printed to stderr.
|
||||
.It level 2
|
||||
all level 1 messages plus notifications down networks are printed to stderr.
|
||||
.It level 3
|
||||
all level 2 messages plus notifications of all packet
|
||||
timeouts are printed to stderr.
|
||||
.El
|
||||
.It Fl r Ar retries
|
||||
This option sets the neighbor query retry limit to
|
||||
.Ar retries .
|
||||
The default is three retries.
|
||||
.It Fl t Ar timeout
|
||||
This sets the number of seconds to wait for a neighbor query
|
||||
reply. The default timeout is four seconds.
|
||||
.El
|
||||
.Sh SAMPLE OUTPUT
|
||||
.Bd -literal
|
||||
# mrinfo mbone.phony.dom.net
|
||||
127.148.176.10 (mbone.phony.dom.net) [version 3.3]:
|
||||
127.148.176.10 -> 0.0.0.0 (?) [1/1/querier]
|
||||
127.148.176.10 -> 127.0.8.4 (mbone2.phony.dom.net) [1/45/tunnel]
|
||||
127.148.176.10 -> 105.1.41.9 (momoney.com) [1/32/tunnel/down]
|
||||
127.148.176.10 -> 143.192.152.119 (mbone.dipu.edu) [1/32/tunnel]
|
||||
.Ed
|
||||
.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) and the
|
||||
threshold (minimum TTL to forward) are displayed. If the queried multicast
|
||||
router has a newer version number, the type (tunnel, srcrt) and status
|
||||
(disabled, down) of the connection are also displayed.
|
||||
.Sh RESTRICTIONS
|
||||
.Nm
|
||||
must be run as `root'.
|
||||
.Sh SEE ALSO
|
||||
.Xr map-mbone 8 ,
|
||||
.Xr mrouted 8 ,
|
||||
.Xr mtrace 8
|
||||
.Sh AUTHOR
|
||||
Pavel Curtis
|
||||
.Sh HISTORY
|
||||
An
|
||||
.Nm
|
||||
command first appeared in
|
||||
.Tn FreeBSD
|
||||
2.0.
|
499
usr.sbin/mrouted/mtrace.8
Normal file
499
usr.sbin/mrouted/mtrace.8
Normal file
@ -0,0 +1,499 @@
|
||||
.\" 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.
|
||||
.\"
|
||||
.\" $Id: mtrace.8,v 3.5 1995/05/09 01:23:58 fenner Exp $
|
||||
.\"
|
||||
.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
|
||||
.I src_addr
|
||||
] [
|
||||
.B \-t
|
||||
.I ttl
|
||||
] [
|
||||
.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
|
||||
utilizes 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.
|
||||
.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!!
|
||||
Version 3.3 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 newer than 3.3.
|
||||
.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.
|
||||
.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 (not implemented yet).
|
||||
.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 \-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
|
||||
.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 explicity 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)
|
25
usr.sbin/mrouted/pathnames.h
Normal file
25
usr.sbin/mrouted/pathnames.h
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* The mrouted program is covered by the license in the accompanying file
|
||||
* named "LICENSE". Use of the mrouted program represents acceptance of
|
||||
* the terms and conditions listed in that file.
|
||||
*
|
||||
* The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
|
||||
* Leland Stanford Junior University.
|
||||
*
|
||||
*
|
||||
* $Id: pathnames.h,v 3.5 1995/05/09 01:00:39 fenner Exp $
|
||||
*/
|
||||
|
||||
#define _PATH_MROUTED_CONF "/etc/mrouted.conf"
|
||||
|
||||
#if (defined(BSD) && (BSD >= 199103))
|
||||
#define _PATH_MROUTED_PID "/var/run/mrouted.pid"
|
||||
#define _PATH_MROUTED_GENID "/var/run/mrouted.genid"
|
||||
#define _PATH_MROUTED_DUMP "/var/tmp/mrouted.dump"
|
||||
#define _PATH_MROUTED_CACHE "/var/tmp/mrouted.cache"
|
||||
#else
|
||||
#define _PATH_MROUTED_PID "/etc/mrouted.pid"
|
||||
#define _PATH_MROUTED_GENID "/etc/mrouted.genid"
|
||||
#define _PATH_MROUTED_DUMP "/usr/tmp/mrouted.dump"
|
||||
#define _PATH_MROUTED_CACHE "/usr/tmp/mrouted.cache"
|
||||
#endif
|
498
usr.sbin/mrouted/rsrr.c
Normal file
498
usr.sbin/mrouted/rsrr.c
Normal file
@ -0,0 +1,498 @@
|
||||
/*
|
||||
* Copyright (c) 1993 by the University of Southern California
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation in source and binary forms for non-commercial purposes
|
||||
* and without fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies and that both the copyright notice and
|
||||
* this permission notice appear in supporting documentation. and that
|
||||
* any documentation, advertising materials, and other materials related
|
||||
* to such distribution and use acknowledge that the software was
|
||||
* developed by the University of Southern California, Information
|
||||
* Sciences Institute. The name of the University may not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THE UNIVERSITY OF SOUTHERN CALIFORNIA makes no representations about
|
||||
* the suitability of this software for any purpose. THIS SOFTWARE IS
|
||||
* PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* Other copyrights might apply to parts of this software and are so
|
||||
* noted when applicable.
|
||||
*/
|
||||
|
||||
/* RSRR code written by Daniel Zappala, USC Information Sciences Institute,
|
||||
* April 1995.
|
||||
*/
|
||||
|
||||
/* May 1995 -- Added support for Route Change Notification */
|
||||
|
||||
#ifdef RSRR
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
/* Taken from prune.c */
|
||||
/*
|
||||
* checks for scoped multicast addresses
|
||||
*/
|
||||
#define GET_SCOPE(gt) { \
|
||||
register int _i; \
|
||||
if (((gt)->gt_mcastgrp & 0xff000000) == 0xef000000) \
|
||||
for (_i = 0; _i < numvifs; _i++) \
|
||||
if (scoped_addr(_i, (gt)->gt_mcastgrp)) \
|
||||
VIFM_SET(_i, (gt)->gt_scope); \
|
||||
}
|
||||
|
||||
/*
|
||||
* Exported variables.
|
||||
*/
|
||||
int rsrr_socket; /* interface to reservation protocol */
|
||||
|
||||
/*
|
||||
* Global RSRR variables.
|
||||
*/
|
||||
char rsrr_recv_buf[RSRR_MAX_LEN]; /* RSRR receive buffer */
|
||||
char rsrr_send_buf[RSRR_MAX_LEN]; /* RSRR send buffer */
|
||||
|
||||
struct sockaddr_un client_addr;
|
||||
int client_length = sizeof(client_addr);
|
||||
|
||||
|
||||
/*
|
||||
* Procedure definitions needed internally.
|
||||
*/
|
||||
void rsrr_accept();
|
||||
void rsrr_accept_iq();
|
||||
int rsrr_accept_rq();
|
||||
int rsrr_send();
|
||||
void rsrr_cache();
|
||||
|
||||
/* Initialize RSRR socket */
|
||||
void
|
||||
rsrr_init()
|
||||
{
|
||||
int servlen;
|
||||
struct sockaddr_un serv_addr;
|
||||
|
||||
if ((rsrr_socket = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0)
|
||||
log(LOG_ERR, errno, "Can't create RSRR socket");
|
||||
|
||||
unlink(RSRR_SERV_PATH);
|
||||
bzero((char *) &serv_addr, sizeof(serv_addr));
|
||||
serv_addr.sun_family = AF_UNIX;
|
||||
strcpy(serv_addr.sun_path, RSRR_SERV_PATH);
|
||||
servlen = sizeof(serv_addr.sun_family) + strlen(serv_addr.sun_path);
|
||||
|
||||
if (bind(rsrr_socket, (struct sockaddr *) &serv_addr, servlen) < 0)
|
||||
log(LOG_ERR, errno, "Can't bind RSRR socket");
|
||||
|
||||
if (register_input_handler(rsrr_socket,rsrr_read) < 0)
|
||||
log(LOG_WARNING, 0, "Couldn't register RSRR as an input handler");
|
||||
}
|
||||
|
||||
/* Read a message from the RSRR socket */
|
||||
void
|
||||
rsrr_read()
|
||||
{
|
||||
register int rsrr_recvlen;
|
||||
register int omask;
|
||||
|
||||
bzero((char *) &client_addr, sizeof(client_addr));
|
||||
rsrr_recvlen = recvfrom(rsrr_socket, rsrr_recv_buf, sizeof(rsrr_recv_buf),
|
||||
0, (struct sockaddr *)&client_addr,&client_length);
|
||||
if (rsrr_recvlen < 0) {
|
||||
if (errno != EINTR)
|
||||
log(LOG_ERR, errno, "RSRR recvfrom");
|
||||
return;
|
||||
}
|
||||
/* Use of omask taken from main() */
|
||||
omask = sigblock(sigmask(SIGALRM));
|
||||
rsrr_accept(rsrr_recvlen);
|
||||
(void)sigsetmask(omask);
|
||||
}
|
||||
|
||||
/* Accept a message from the reservation protocol and take
|
||||
* appropriate action.
|
||||
*/
|
||||
void
|
||||
rsrr_accept(recvlen)
|
||||
int recvlen;
|
||||
{
|
||||
struct rsrr_header *rsrr;
|
||||
struct rsrr_rq *route_query;
|
||||
|
||||
if (recvlen < RSRR_HEADER_LEN) {
|
||||
log(LOG_WARNING, 0,
|
||||
"Received RSRR packet of %d bytes, which is less than min size",
|
||||
recvlen);
|
||||
return;
|
||||
}
|
||||
|
||||
rsrr = (struct rsrr_header *) rsrr_recv_buf;
|
||||
|
||||
if (rsrr->version > RSRR_MAX_VERSION) {
|
||||
log(LOG_WARNING, 0,
|
||||
"Received RSRR packet version %d, which I don't understand",
|
||||
rsrr->version);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (rsrr->version) {
|
||||
case 1:
|
||||
switch (rsrr->type) {
|
||||
case RSRR_INITIAL_QUERY:
|
||||
/* Send Initial Reply to client */
|
||||
log(LOG_INFO, 0, "Received Initial Query\n");
|
||||
rsrr_accept_iq();
|
||||
break;
|
||||
case RSRR_ROUTE_QUERY:
|
||||
/* Check size */
|
||||
if (recvlen < RSRR_RQ_LEN) {
|
||||
log(LOG_WARNING, 0,
|
||||
"Received Route Query of %d bytes, which is too small",
|
||||
recvlen);
|
||||
break;
|
||||
}
|
||||
/* Get the query */
|
||||
route_query = (struct rsrr_rq *) (rsrr_recv_buf + RSRR_HEADER_LEN);
|
||||
log(LOG_INFO, 0,
|
||||
"Received Route Query for src %s grp %s notification %d",
|
||||
inet_fmt(route_query->source_addr.s_addr, s1),
|
||||
inet_fmt(route_query->dest_addr.s_addr,s2),
|
||||
BIT_TST(rsrr->flags,RSRR_NOTIFICATION_BIT));
|
||||
/* Send Route Reply to client */
|
||||
rsrr_accept_rq(route_query,rsrr->flags,NULL);
|
||||
break;
|
||||
default:
|
||||
log(LOG_WARNING, 0,
|
||||
"Received RSRR packet type %d, which I don't handle",
|
||||
rsrr->type);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
log(LOG_WARNING, 0,
|
||||
"Received RSRR packet version %d, which I don't understand",
|
||||
rsrr->version);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Send an Initial Reply to the reservation protocol. */
|
||||
void
|
||||
rsrr_accept_iq()
|
||||
{
|
||||
struct rsrr_header *rsrr;
|
||||
struct rsrr_vif *vif_list;
|
||||
struct uvif *v;
|
||||
int vifi, sendlen;
|
||||
|
||||
/* Check for space. There should be room for plenty of vifs,
|
||||
* but we should check anyway.
|
||||
*/
|
||||
if (numvifs > RSRR_MAX_VIFS) {
|
||||
log(LOG_WARNING, 0,
|
||||
"Can't send RSRR Route Reply because %d is too many vifs %d",
|
||||
numvifs);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set up message */
|
||||
rsrr = (struct rsrr_header *) rsrr_send_buf;
|
||||
rsrr->version = 1;
|
||||
rsrr->type = RSRR_INITIAL_REPLY;
|
||||
rsrr->flags = 0;
|
||||
rsrr->num = numvifs;
|
||||
|
||||
vif_list = (struct rsrr_vif *) (rsrr_send_buf + RSRR_HEADER_LEN);
|
||||
|
||||
/* Include the vif list. */
|
||||
for (vifi=0, v = uvifs; vifi < numvifs; vifi++, v++) {
|
||||
vif_list[vifi].id = vifi;
|
||||
vif_list[vifi].status = 0;
|
||||
if (v->uv_flags & VIFF_DISABLED)
|
||||
BIT_SET(vif_list[vifi].status,RSRR_DISABLED_BIT);
|
||||
vif_list[vifi].threshold = v->uv_threshold;
|
||||
vif_list[vifi].local_addr.s_addr = v->uv_lcl_addr;
|
||||
}
|
||||
|
||||
/* Get the size. */
|
||||
sendlen = RSRR_HEADER_LEN + numvifs*RSRR_VIF_LEN;
|
||||
|
||||
/* Send it. */
|
||||
log(LOG_INFO, 0, "Send RSRR Initial Reply");
|
||||
rsrr_send(sendlen);
|
||||
}
|
||||
|
||||
/* Send a Route Reply to the reservation protocol. The Route Query
|
||||
* contains the query to which we are responding. The flags contain
|
||||
* the incoming flags from the query or, for route change
|
||||
* notification, the flags that should be set for the reply. The
|
||||
* kernel table entry contains the routing info to use for a route
|
||||
* change notification.
|
||||
*/
|
||||
int
|
||||
rsrr_accept_rq(route_query,flags,gt_notify)
|
||||
struct rsrr_rq *route_query;
|
||||
int flags;
|
||||
struct gtable *gt_notify;
|
||||
{
|
||||
struct rsrr_header *rsrr;
|
||||
struct rsrr_rr *route_reply;
|
||||
struct gtable *gt,local_g;
|
||||
struct rtentry *r;
|
||||
int sendlen,i;
|
||||
u_long mcastgrp;
|
||||
|
||||
/* Set up message */
|
||||
rsrr = (struct rsrr_header *) rsrr_send_buf;
|
||||
rsrr->version = 1;
|
||||
rsrr->type = RSRR_ROUTE_REPLY;
|
||||
rsrr->flags = 0;
|
||||
rsrr->num = 0;
|
||||
|
||||
route_reply = (struct rsrr_rr *) (rsrr_send_buf + RSRR_HEADER_LEN);
|
||||
route_reply->dest_addr.s_addr = route_query->dest_addr.s_addr;
|
||||
route_reply->source_addr.s_addr = route_query->source_addr.s_addr;
|
||||
route_reply->query_id = route_query->query_id;
|
||||
|
||||
/* Blank routing entry for error. */
|
||||
route_reply->in_vif = 0;
|
||||
route_reply->reserved = 0;
|
||||
route_reply->out_vif_bm = 0;
|
||||
|
||||
/* Get the size. */
|
||||
sendlen = RSRR_RR_LEN;
|
||||
|
||||
/* If kernel table entry is defined, then we are sending a Route Reply
|
||||
* due to a Route Change Notification event. Use the kernel table entry
|
||||
* to supply the routing info.
|
||||
*/
|
||||
if (gt_notify) {
|
||||
/* Set flags */
|
||||
rsrr->flags = flags;
|
||||
/* Include the routing entry. */
|
||||
route_reply->in_vif = gt_notify->gt_route->rt_parent;
|
||||
route_reply->out_vif_bm = gt_notify->gt_grpmems;
|
||||
|
||||
} else if (find_src_grp(route_query->source_addr.s_addr, 0,
|
||||
route_query->dest_addr.s_addr)) {
|
||||
|
||||
/* Found kernel entry. Code taken from add_table_entry() */
|
||||
gt = gtp ? gtp->gt_gnext : kernel_table;
|
||||
|
||||
/* Include the routing entry. */
|
||||
route_reply->in_vif = gt->gt_route->rt_parent;
|
||||
route_reply->out_vif_bm = gt->gt_grpmems;
|
||||
|
||||
/* Cache reply if using route change notification. */
|
||||
if BIT_TST(flags,RSRR_NOTIFICATION_BIT) {
|
||||
rsrr_cache(gt,route_query);
|
||||
BIT_SET(rsrr->flags,RSRR_NOTIFICATION_BIT);
|
||||
}
|
||||
|
||||
} else {
|
||||
/* No kernel entry; use routing table. */
|
||||
r = determine_route(route_query->source_addr.s_addr);
|
||||
|
||||
if (r != NULL) {
|
||||
/* We need to mimic what will happen if a data packet
|
||||
* is forwarded by multicast routing -- the kernel will
|
||||
* make an upcall and mrouted will install a route in the kernel.
|
||||
* Our outgoing vif bitmap should reflect what that table
|
||||
* will look like. Grab code from add_table_entry().
|
||||
* This is gross, but it's probably better to be accurate.
|
||||
*/
|
||||
|
||||
gt = &local_g;
|
||||
mcastgrp = route_query->dest_addr.s_addr;
|
||||
|
||||
gt->gt_mcastgrp = mcastgrp;
|
||||
gt->gt_grpmems = 0;
|
||||
gt->gt_scope = 0;
|
||||
gt->gt_route = r;
|
||||
|
||||
/* obtain the multicast group membership list */
|
||||
for (i = 0; i < numvifs; i++) {
|
||||
if (VIFM_ISSET(i, r->rt_children) &&
|
||||
!(VIFM_ISSET(i, r->rt_leaves)))
|
||||
VIFM_SET(i, gt->gt_grpmems);
|
||||
|
||||
if (VIFM_ISSET(i, r->rt_leaves) && grplst_mem(i, mcastgrp))
|
||||
VIFM_SET(i, gt->gt_grpmems);
|
||||
}
|
||||
|
||||
GET_SCOPE(gt);
|
||||
gt->gt_grpmems &= ~gt->gt_scope;
|
||||
|
||||
/* Include the routing entry. */
|
||||
route_reply->in_vif = gt->gt_route->rt_parent;
|
||||
route_reply->out_vif_bm = gt->gt_grpmems;
|
||||
|
||||
} else {
|
||||
/* Set error bit. */
|
||||
BIT_SET(rsrr->flags,RSRR_ERROR_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
if (gt_notify)
|
||||
log(LOG_INFO, 0, "Route Change: Send RSRR Route Reply");
|
||||
|
||||
else
|
||||
log(LOG_INFO, 0, "Send RSRR Route Reply");
|
||||
|
||||
log(LOG_INFO, 0, "for src %s dst %s in vif %d out vif %d\n",
|
||||
inet_fmt(route_reply->source_addr.s_addr,s1),
|
||||
inet_fmt(route_reply->dest_addr.s_addr,s2),
|
||||
route_reply->in_vif,route_reply->out_vif_bm);
|
||||
|
||||
/* Send it. */
|
||||
return rsrr_send(sendlen);
|
||||
}
|
||||
|
||||
/* Send an RSRR message. */
|
||||
int
|
||||
rsrr_send(sendlen)
|
||||
int sendlen;
|
||||
{
|
||||
int error;
|
||||
|
||||
/* Send it. */
|
||||
error = sendto(rsrr_socket, rsrr_send_buf, sendlen, 0,
|
||||
(struct sockaddr *)&client_addr, client_length);
|
||||
|
||||
/* Check for errors. */
|
||||
if (error < 0) {
|
||||
log(LOG_WARNING, errno, "Failed send on RSRR socket");
|
||||
return error;
|
||||
}
|
||||
if (error != sendlen) {
|
||||
log(LOG_WARNING, 0,
|
||||
"Sent only %d out of %d bytes on RSRR socket\n", error, sendlen);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
/* Cache a message being sent to a client. Currently only used for
|
||||
* caching Route Reply messages for route change notification.
|
||||
*/
|
||||
void
|
||||
rsrr_cache(gt,route_query)
|
||||
struct gtable *gt;
|
||||
struct rsrr_rq *route_query;
|
||||
{
|
||||
struct rsrr_cache *rc,*rc_prev;
|
||||
struct rsrr_header *rsrr;
|
||||
|
||||
rsrr = (struct rsrr_header *) rsrr_send_buf;
|
||||
|
||||
rc = gt->gt_rsrr_cache;
|
||||
while (rc) {
|
||||
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. */
|
||||
if (rc == gt->gt_rsrr_cache)
|
||||
/* Deleting first entry. */
|
||||
gt->gt_rsrr_cache = rc->next;
|
||||
else
|
||||
rc_prev->next = rc->next;
|
||||
free(rc);
|
||||
} else {
|
||||
/* Update */
|
||||
rc->route_query.query_id = route_query->query_id;
|
||||
printf("Update cached query id %d from client %s\n",
|
||||
rc->route_query.query_id,rc->client_addr.sun_path);
|
||||
}
|
||||
return;
|
||||
}
|
||||
rc_prev = rc;
|
||||
rc = rc->next;
|
||||
}
|
||||
|
||||
/* Cache entry doesn't already exist. Create one and insert at
|
||||
* front of list.
|
||||
*/
|
||||
rc = (struct rsrr_cache *) malloc(sizeof(struct rsrr_cache));
|
||||
if (rc == NULL)
|
||||
log(LOG_ERR, 0, "ran out of memory");
|
||||
rc->route_query.source_addr.s_addr = route_query->source_addr.s_addr;
|
||||
rc->route_query.dest_addr.s_addr = route_query->dest_addr.s_addr;
|
||||
rc->route_query.query_id = route_query->query_id;
|
||||
strcpy(rc->client_addr.sun_path, client_addr.sun_path);
|
||||
rc->client_length = client_length;
|
||||
rc->next = gt->gt_rsrr_cache;
|
||||
gt->gt_rsrr_cache = rc;
|
||||
printf("Cached query id %d 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,*rc_next,*rc_prev;
|
||||
int flags = 0;
|
||||
|
||||
rc = gt->gt_rsrr_cache;
|
||||
while (rc) {
|
||||
rc_next = rc->next;
|
||||
|
||||
if (notify)
|
||||
BIT_SET(flags,RSRR_NOTIFICATION_BIT);
|
||||
|
||||
if (rsrr_accept_rq(&rc->route_query,flags,gt) < 0) {
|
||||
printf("Deleting cached query id %d from client %s\n",
|
||||
rc->route_query.query_id,rc->client_addr.sun_path);
|
||||
/* Delete cache entry. */
|
||||
if (rc == gt->gt_rsrr_cache)
|
||||
/* Deleting first entry. */
|
||||
gt->gt_rsrr_cache = rc_next;
|
||||
else
|
||||
rc_prev->next = rc_next;
|
||||
free(rc);
|
||||
} else {
|
||||
rc_prev = rc;
|
||||
}
|
||||
rc = 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 */
|
138
usr.sbin/mrouted/rsrr.h
Normal file
138
usr.sbin/mrouted/rsrr.h
Normal file
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright (c) 1993 by the University of Southern California
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation in source and binary forms for non-commercial purposes
|
||||
* and without fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies and that both the copyright notice and
|
||||
* this permission notice appear in supporting documentation. and that
|
||||
* any documentation, advertising materials, and other materials related
|
||||
* to such distribution and use acknowledge that the software was
|
||||
* developed by the University of Southern California, Information
|
||||
* Sciences Institute. The name of the University may not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THE UNIVERSITY OF SOUTHERN CALIFORNIA makes no representations about
|
||||
* the suitability of this software for any purpose. THIS SOFTWARE IS
|
||||
* PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* Other copyrights might apply to parts of this software and are so
|
||||
* noted when applicable.
|
||||
*/
|
||||
|
||||
#define RSRR_SERV_PATH "/tmp/.rsrr_svr"
|
||||
/* Note this needs to be 14 chars for 4.3 BSD compatibility */
|
||||
#define RSRR_CLI_PATH "/tmp/.rsrr_cli"
|
||||
|
||||
#define RSRR_MAX_LEN 2048
|
||||
#define RSRR_HEADER_LEN (sizeof(struct rsrr_header))
|
||||
#define RSRR_RQ_LEN (RSRR_HEADER_LEN + sizeof(struct rsrr_rq))
|
||||
#define RSRR_RR_LEN (RSRR_HEADER_LEN + sizeof(struct rsrr_rr))
|
||||
#define RSRR_VIF_LEN (sizeof(struct rsrr_vif))
|
||||
|
||||
/* Current maximum number of vifs. */
|
||||
#define RSRR_MAX_VIFS 32
|
||||
|
||||
/* Maximum acceptable version */
|
||||
#define RSRR_MAX_VERSION 1
|
||||
|
||||
/* RSRR message types */
|
||||
#define RSRR_ALL_TYPES 0
|
||||
#define RSRR_INITIAL_QUERY 1
|
||||
#define RSRR_INITIAL_REPLY 2
|
||||
#define RSRR_ROUTE_QUERY 3
|
||||
#define RSRR_ROUTE_REPLY 4
|
||||
|
||||
/* RSRR Initial Reply (Vif) Status bits.
|
||||
* Each definition represents the position of the bit from right to left.
|
||||
*
|
||||
* Right-most bit is the disabled bit, set if the vif is administratively
|
||||
* disabled.
|
||||
*/
|
||||
#define RSRR_DISABLED_BIT 0
|
||||
/* All other bits are zeroes */
|
||||
|
||||
/* RSRR Route Query/Reply flag bits.
|
||||
* Each definition represents the position of the bit from right to left.
|
||||
*
|
||||
* Right-most bit is the Route Change Notification bit, set if the
|
||||
* reservation protocol wishes to receive notification of
|
||||
* a route change for the source-destination pair listed in the query.
|
||||
* Notification is in the form of an unsolicitied Route Reply.
|
||||
*/
|
||||
#define RSRR_NOTIFICATION_BIT 0
|
||||
/* Next bit indicates an error returning the Route Reply. */
|
||||
#define RSRR_ERROR_BIT 1
|
||||
/* All other bits are zeroes */
|
||||
|
||||
/* Definition of an RSRR message header.
|
||||
* An Initial Query uses only the header, and an Initial Reply uses
|
||||
* the header and a list of vifs.
|
||||
*/
|
||||
struct rsrr_header {
|
||||
u_char version; /* RSRR Version, currently 1 */
|
||||
u_char type; /* type of message, as defined above */
|
||||
u_char flags; /* flags; defined by type */
|
||||
u_char num; /* number; defined by type */
|
||||
};
|
||||
|
||||
/* Definition of a vif as seen by the reservation protocol.
|
||||
*
|
||||
* Routing gives the reservation protocol a list of vifs in the
|
||||
* Initial Reply.
|
||||
*
|
||||
* We explicitly list the ID because we can't assume that all routing
|
||||
* protocols will use the same numbering scheme.
|
||||
*
|
||||
* The status is a bitmask of status flags, as defined above. It is the
|
||||
* responsibility of the reservation protocol to perform any status checks
|
||||
* if it uses the MULTICAST_VIF socket option.
|
||||
*
|
||||
* The threshold indicates the ttl an outgoing packet needs in order to
|
||||
* be forwarded. The reservation protocol must perform this check itself if
|
||||
* it uses the MULTICAST_VIF socket option.
|
||||
*
|
||||
* The local address is the address of the physical interface over which
|
||||
* packets are sent.
|
||||
*/
|
||||
struct rsrr_vif {
|
||||
u_char id; /* vif id */
|
||||
u_char threshold; /* vif threshold ttl */
|
||||
u_short status; /* vif status bitmask */
|
||||
struct in_addr local_addr; /* vif local address */
|
||||
};
|
||||
|
||||
/* Definition of an RSRR Route Query.
|
||||
*
|
||||
* The query asks routing for the forwarding entry for a particular
|
||||
* source and destination. The query ID uniquely identifies the query
|
||||
* for the reservation protocol. Thus, the combination of the client's
|
||||
* address and the query ID forms a unique identifier for routing.
|
||||
* Flags are defined above.
|
||||
*/
|
||||
struct rsrr_rq {
|
||||
struct in_addr dest_addr; /* destination */
|
||||
struct in_addr source_addr; /* source */
|
||||
u_long query_id; /* query ID */
|
||||
};
|
||||
|
||||
/* Definition of an RSRR Route Reply.
|
||||
*
|
||||
* Routing uses the reply to give the reservation protocol the
|
||||
* forwarding entry for a source-destination pair. Routing copies the
|
||||
* query ID from the query and fills in the incoming vif and a bitmask
|
||||
* of the outgoing vifs.
|
||||
* Flags are defined above.
|
||||
*/
|
||||
struct rsrr_rr {
|
||||
struct in_addr dest_addr; /* destination */
|
||||
struct in_addr source_addr; /* source */
|
||||
u_long query_id; /* query ID */
|
||||
u_short in_vif; /* incoming vif */
|
||||
u_short reserved; /* reserved */
|
||||
u_long out_vif_bm; /* outgoing vif bitmask */
|
||||
};
|
41
usr.sbin/mrouted/rsrr_var.h
Normal file
41
usr.sbin/mrouted/rsrr_var.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 1993 by the University of Southern California
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation in source and binary forms for non-commercial purposes
|
||||
* and without fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies and that both the copyright notice and
|
||||
* this permission notice appear in supporting documentation. and that
|
||||
* any documentation, advertising materials, and other materials related
|
||||
* to such distribution and use acknowledge that the software was
|
||||
* developed by the University of Southern California, Information
|
||||
* Sciences Institute. The name of the University may not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THE UNIVERSITY OF SOUTHERN CALIFORNIA makes no representations about
|
||||
* the suitability of this software for any purpose. THIS SOFTWARE IS
|
||||
* PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* Other copyrights might apply to parts of this software and are so
|
||||
* noted when applicable.
|
||||
*/
|
||||
|
||||
/* RSRR things that are only needed by mrouted. */
|
||||
|
||||
/* Cache of Route Query messages, distinguished by source,
|
||||
* destination, and client addresses. Cache is flushed by RSRR client
|
||||
* -- it sends notification when an unwanted Route Reply is received.
|
||||
* Since this only happens during route changes, it is more likely
|
||||
* that the cache will be flushed when the kernel table entry is
|
||||
* deleted. */
|
||||
struct rsrr_cache {
|
||||
struct rsrr_rq route_query; /* Cached Route Query */
|
||||
struct sockaddr_un client_addr; /* Client address */
|
||||
int client_length; /* Length of client */
|
||||
struct rsrr_cache *next; /* next cache item */
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user