* 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.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 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
* ---------------------------------
* Copyright (c) Xerox Corporation 1992. All rights reserved.
* License is granted to copy, to use, and to make and to use derivative works
* for research and evaluation purposes, provided that Xerox is acknowledged
* in all documentation pertaining to any such copy or derivative work. Xerox
* grants no other licenses expressed or implied. The Xerox trade name should
* not be used in any advertising without its written permission.
* XEROX CORPORATION MAKES NO REPRESENTATIONS CONCERNING EITHER THE
* MERCHANTABILITY OF THIS SOFTWARE OR THE SUITABILITY OF THIS SOFTWARE FOR
* ANY PARTICULAR PURPOSE. The software is provided "as is" without express
* or implied warranty of any kind.
* These notices must be retained in any copies of any part of this software.
"@(#) $Id: mrinfo.c,v 1.3 1993/06/24 05:11:16 deering Exp $";
"@(#) Header: mrinfo.c,v 1.6 93/04/08 15:14:16 van Exp (LBL)";
#define DEFAULT_TIMEOUT 4 /* How long to wait before retrying requests */
#define DEFAULT_RETRIES 3 /* How many times to ask each router */
u_long our_addr
, target_addr
= 0; /* in NET order */
int retries
= DEFAULT_RETRIES
;
int timeout
= DEFAULT_TIMEOUT
;
e
= gethostbyaddr((char *)&addr
, sizeof(addr
), AF_INET
);
return e
? 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.
log(severity
, syserr
, format
, a
, b
, c
, d
, e
)
if (severity
> LOG_WARNING
)
if (severity
> LOG_NOTICE
)
if (severity
== LOG_WARNING
)
strcat(fmt
, "warning - ");
strncat(fmt
, format
, 80);
fprintf(stderr
, fmt
, a
, b
, c
, d
, e
);
else if (syserr
< sys_nerr
)
fprintf(stderr
, ": %s\n", sys_errlist
[syserr
]);
fprintf(stderr
, ": errno %d\n", syserr
);
* Send a neighbors-list request.
send_igmp(our_addr
, dst
, IGMP_DVMRP
, DVMRP_ASK_NEIGHBORS
,
htonl(MROUTED_LEVEL
), 0);
send_igmp(our_addr
, dst
, IGMP_DVMRP
, DVMRP_ASK_NEIGHBORS2
,
htonl(MROUTED_LEVEL
), 0);
* Process an incoming neighbor-list message.
accept_neighbors(src
, dst
, p
, datalen
)
u_char
*ep
= p
+ datalen
;
#define GET_ADDR(a) (a = ((u_long)*p++ << 24), a += ((u_long)*p++ << 16),\
a += ((u_long)*p++ << 8), a += *p++)
printf("%s (%s):\n", inet_fmt(src
, s1
), inet_name(src
));
register u_long 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
);
accept_neighbors2(src
, dst
, p
, datalen
)
u_char
*ep
= p
+ datalen
;
printf("%s (%s) [version %d.%d]:\n", inet_fmt(src
, s1
), inet_name(src
),
target_level
& 0xff, (target_level
>> 8) & 0xff);
register u_long laddr
= *(u_long
*)p
;
register u_long neighbor
= *(u_long
*)p
;
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
)
if (flags
& DVMRP_NF_SRCRT
)
if (flags
& DVMRP_NF_QUERIER
)
if (flags
& DVMRP_NF_DISABLED
)
if (flags
& DVMRP_NF_DOWN
)
get_number(var
, deflt
, pargv
, pargc
)
if ((*pargv
)[0][2] == '\0') { /* Get the value from the next
if (*pargc
> 1 && isdigit((*pargv
)[1][0])) {
*var
= atoi((*pargv
)[0]);
} else { /* Get value from the rest of this argument */
if (isdigit((*pargv
)[0][2])) {
*var
= atoi((*pargv
)[0] + 2);
struct hostent
*e
= gethostbyname(name
);
memcpy(&addr
, e
->h_addr_list
[0], e
->h_length
);
fprintf(stderr
, "Usage: mrinfo [-t timeout] [-r retries] router\n");
fprintf(stderr
, "mrinfo: must be root\n");
while (argc
> 0 && argv
[0][0] == '-') {
if (!get_number(&debug
, DEFAULT_DEBUG
, &argv
, &argc
))
if (!get_number(&retries
, -1, &argv
, &argc
))
if (!get_number(&timeout
, -1, &argv
, &argc
))
target_addr
= host_addr(argv
[0]);
fprintf(stderr
, "mrinfo: %s: no such host\n", argv
[0]);
fprintf(stderr
, "Debug level %u\n", debug
);
{ /* Find a good local address for us. */
int addrlen
= sizeof(addr
);
addr
.sin_family
= AF_INET
;
addr
.sin_addr
.s_addr
= target_addr
;
addr
.sin_port
= htons(2000); /* any port over 1024 will
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");
our_addr
= addr
.sin_addr
.s_addr
;
int count
, recvlen
, dummy
= 0;
register u_long src
, dst
, group
;
int ipdatalen
, iphdrlen
, igmpdatalen
;
FD_SET(igmp_socket
, &fds
);
count
= select(igmp_socket
+ 1, &fds
, 0, 0, &tv
);
log(LOG_DEBUG
, 0, "Timed out receiving neighbor lists");
recvlen
= recvfrom(igmp_socket
, recv_buf
, sizeof(recv_buf
),
if (recvlen
&& errno
!= EINTR
)
if (recvlen
< sizeof(struct ip
)) {
"packet too short (%u bytes) for IP header",
ip
= (struct ip
*) recv_buf
;
if (src
!= target_addr
) {
fprintf(stderr
, "mrinfo: got reply from %s",
fprintf(stderr
, " instead of %s\n",
inet_fmt(target_addr
, s1
));
iphdrlen
= ip
->ip_hl
<< 2;
if (iphdrlen
+ ipdatalen
!= recvlen
) {
"packet shorter (%u bytes) than hdr+data length (%u+%u)",
recvlen
, iphdrlen
, ipdatalen
);
igmp
= (struct igmp
*) (recv_buf
+ iphdrlen
);
group
= igmp
->igmp_group
.s_addr
;
igmpdatalen
= ipdatalen
- IGMP_MINLEN
;
"IP data field too short (%u bytes) for IGMP, from %s",
ipdatalen
, inet_fmt(src
, s1
));
if (igmp
->igmp_type
!= IGMP_DVMRP
)
switch (igmp
->igmp_code
) {
/* knows about DVMRP_NEIGHBORS2 msg */
target_level
= ntohl(group
);
accept_neighbors(src
, dst
, (char *)(igmp
+ 1),
accept_neighbors2(src
, dst
, (char *)(igmp
+ 1),
void accept_group_report()
void accept_neighbor_request2()
void accept_neighbor_request()