summaryrefslogtreecommitdiffstats
path: root/usr.sbin/mrinfo
diff options
context:
space:
mode:
authorderaadt <deraadt@openbsd.org>1995-12-14 01:45:19 +0000
committerderaadt <deraadt@openbsd.org>1995-12-14 01:45:19 +0000
commita17240f23138f53f8df246dc6d635a91bbea37fd (patch)
tree0efa6e902d306754512a5281106abc4637c61ed2 /usr.sbin/mrinfo
parentuse string.h (diff)
downloadwireguard-openbsd-a17240f23138f53f8df246dc6d635a91bbea37fd.tar.xz
wireguard-openbsd-a17240f23138f53f8df246dc6d635a91bbea37fd.zip
from netbsd; update to mrouted 3.8
Diffstat (limited to 'usr.sbin/mrinfo')
-rw-r--r--usr.sbin/mrinfo/mrinfo.c250
1 files changed, 177 insertions, 73 deletions
diff --git a/usr.sbin/mrinfo/mrinfo.c b/usr.sbin/mrinfo/mrinfo.c
index 20bd54fcf36..e8cfc4f091d 100644
--- a/usr.sbin/mrinfo/mrinfo.c
+++ b/usr.sbin/mrinfo/mrinfo.c
@@ -1,4 +1,4 @@
-/* $NetBSD: mrinfo.c,v 1.3 1995/10/03 23:20:45 thorpej Exp $ */
+/* $NetBSD: mrinfo.c,v 1.4 1995/12/10 11:00:51 mycroft Exp $ */
/*
* This tool requests configuration info from a multicast router
@@ -63,7 +63,7 @@
#ifndef lint
static char rcsid[] =
- "@(#) $NetBSD: mrinfo.c,v 1.3 1995/10/03 23:20:45 thorpej Exp $";
+ "@(#) $NetBSD: mrinfo.c,v 1.4 1995/12/10 11:00:51 mycroft Exp $";
/* original rcsid:
"@(#) Header: mrinfo.c,v 1.6 93/04/08 15:14:16 van Exp (LBL)";
*/
@@ -74,6 +74,11 @@ static char rcsid[] =
#include <sys/time.h>
#include "defs.h"
#include <arpa/inet.h>
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
#define DEFAULT_TIMEOUT 4 /* How long to wait before retrying requests */
#define DEFAULT_RETRIES 3 /* How many times to ask each router */
@@ -83,10 +88,22 @@ int debug = 0;
int nflag = 0;
int retries = DEFAULT_RETRIES;
int timeout = DEFAULT_TIMEOUT;
-int target_level;
+int target_level = 0;
vifi_t numvifs; /* to keep loader happy */
/* (see COPY_TABLES macro called in kern.c) */
+char * inet_name __P((u_int32_t addr));
+void ask __P((u_int32_t dst));
+void ask2 __P((u_int32_t dst));
+int get_number __P((int *var, int deflt, char ***pargv,
+ int *pargc));
+u_int32_t host_addr __P((char *name));
+void usage __P((void));
+
+/* to shut up -Wstrict-prototypes */
+int main __P((int argc, char *argv[]));
+
+
char *
inet_name(addr)
u_int32_t addr;
@@ -110,14 +127,26 @@ inet_name(addr)
* message and the current debug level. For errors of severity LOG_ERR or
* worse, terminate the program.
*/
+#ifdef __STDC__
+void
+log(int severity, int syserr, char *format, ...)
+{
+ va_list ap;
+ char fmt[100];
+
+ va_start(ap, format);
+#else
void
-log(severity, syserr, format, a, b, c, d, e)
+log(severity, syserr, format, va_alist)
int severity, syserr;
char *format;
- int a, b, c, d, e;
+ va_dcl
{
+ va_list ap;
char fmt[100];
+ va_start(ap);
+#endif
switch (debug) {
case 0:
if (severity > LOG_WARNING)
@@ -133,7 +162,7 @@ log(severity, syserr, format, a, b, c, d, e)
if (severity == LOG_WARNING)
strcat(fmt, "warning - ");
strncat(fmt, format, 80);
- fprintf(stderr, fmt, a, b, c, d, e);
+ vfprintf(stderr, fmt, ap);
if (syserr == 0)
fprintf(stderr, "\n");
else if (syserr < sys_nerr)
@@ -169,9 +198,9 @@ ask2(dst)
* Process an incoming neighbor-list message.
*/
void
-accept_neighbors(src, dst, p, datalen)
- u_int32_t src, dst;
- u_char *p;
+accept_neighbors(src, dst, p, datalen, level)
+ u_int32_t src, dst, level;
+ u_char *p;
int datalen;
{
u_char *ep = p + datalen;
@@ -202,17 +231,22 @@ accept_neighbors(src, dst, p, datalen)
}
void
-accept_neighbors2(src, dst, p, datalen)
- u_int32_t src, dst;
- u_char *p;
+accept_neighbors2(src, dst, p, datalen, level)
+ u_int32_t src, dst, level;
+ u_char *p;
int datalen;
{
u_char *ep = p + datalen;
- u_int broken_cisco = ((target_level & 0xffff) == 0x020a); /* 10.2 */
+ 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]:\n", inet_fmt(src, s1), inet_name(src),
- target_level & 0xff, (target_level >> 8) & 0xff);
+ printf("%s (%s) [version %d.%d", inet_fmt(src, s1), inet_name(src),
+ level & 0xff, (level >> 8) & 0xff);
+ if ((level >> 16) & NF_LEAF) { printf (",leaf"); }
+ if ((level >> 16) & NF_PRUNE) { printf (",prune"); }
+ if ((level >> 16) & NF_GENID) { printf (",genid"); }
+ if ((level >> 16) & NF_MTRACE) { printf (",mtrace"); }
+ printf ("]:\n");
while (p < ep) {
register u_char metric;
@@ -281,23 +315,6 @@ get_number(var, deflt, pargv, pargc)
}
}
-u_int32_t
-host_addr(name)
- char *name;
-{
- struct hostent *e;
- u_int32_t addr;
-
- addr = inet_addr(name);
- if ((int)addr == -1) {
- e = gethostbyname(name);
- if (e == NULL || e->h_length != sizeof(addr))
- return (0);
- memcpy(&addr, e->h_addr_list[0], e->h_length);
- }
- return(addr);
-}
-
void
usage()
{
@@ -311,6 +328,14 @@ main(argc, argv)
int argc;
char *argv[];
{
+ int tries;
+ int trynew;
+ struct timeval et;
+ struct hostent *hp;
+ struct hostent bogus;
+ char *host;
+ int curaddr;
+
setlinebuf(stderr);
if (geteuid() != 0) {
@@ -343,11 +368,21 @@ main(argc, argv)
if (argc > 1)
usage();
if (argc == 1)
- target_addr = host_addr(argv[0]);
+ host = argv[0];
else
- target_addr = host_addr("127.0.0.1");
-
- if (target_addr == 0) {
+ host = "127.0.0.1";
+
+ if ((target_addr = inet_addr(host)) != -1) {
+ hp = &bogus;
+ hp->h_length = sizeof(target_addr);
+ hp->h_addr_list = (char **)malloc(2 * sizeof(char *));
+ hp->h_addr_list[0] = malloc(hp->h_length);
+ memcpy(hp->h_addr_list[0], &target_addr, hp->h_length);
+ hp->h_addr_list[1] = 0;
+ } else
+ hp = gethostbyname(host);
+
+ if (hp == NULL) {
fprintf(stderr, "mrinfo: %s: no such host\n", argv[0]);
exit(1);
}
@@ -356,7 +391,10 @@ main(argc, argv)
init_igmp();
- { /* Find a good local address for us. */
+ /* Check all addresses; mrouters often have unreachable interfaces */
+ for (curaddr = 0; hp->h_addr_list[curaddr] != NULL; curaddr++) {
+ memcpy(&target_addr, hp->h_addr_list[curaddr], hp->h_length);
+ { /* Find a good local address for us. */
int udp;
struct sockaddr_in addr;
int addrlen = sizeof(addr);
@@ -376,14 +414,24 @@ main(argc, argv)
}
close(udp);
our_addr = addr.sin_addr.s_addr;
- }
-
- ask(target_addr);
-
- /* Main receive loop */
- for (;;) {
+ }
+
+ tries = 0;
+ trynew = 1;
+ /*
+ * New strategy: send 'ask2' for two timeouts, then fall back
+ * to 'ask', since it's not very likely that we are going to
+ * find someone who only responds to 'ask' these days
+ */
+ ask2(target_addr);
+
+ gettimeofday(&et, 0);
+ et.tv_sec += timeout;
+
+ /* Main receive loop */
+ for (;;) {
fd_set fds;
- struct timeval tv;
+ struct timeval tv, now;
int count, recvlen, dummy = 0;
register u_int32_t src, dst, group;
struct ip *ip;
@@ -393,8 +441,16 @@ main(argc, argv)
FD_ZERO(&fds);
FD_SET(igmp_socket, &fds);
- tv.tv_sec = timeout;
- tv.tv_usec = 0;
+ gettimeofday(&now, 0);
+ tv.tv_sec = et.tv_sec - now.tv_sec;
+ tv.tv_usec = et.tv_usec - now.tv_usec;
+
+ if (tv.tv_usec < 0) {
+ tv.tv_usec += 1000000L;
+ --tv.tv_sec;
+ }
+ if (tv.tv_sec < 0)
+ tv.tv_sec = tv.tv_usec = 0;
count = select(igmp_socket + 1, &fds, 0, 0, &tv);
@@ -404,12 +460,19 @@ main(argc, argv)
continue;
} else if (count == 0) {
log(LOG_DEBUG, 0, "Timed out receiving neighbor lists");
- if (--retries < 0)
- exit(1);
- if (target_level == 0)
+ 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,
@@ -434,19 +497,19 @@ main(argc, argv)
iphdrlen = ip->ip_hl << 2;
ipdatalen = ip->ip_len;
if (iphdrlen + ipdatalen != recvlen) {
- log(LOG_WARNING, 0,
- "packet shorter (%u bytes) than hdr+data length (%u+%u)",
- recvlen, iphdrlen, ipdatalen);
- continue;
+ log(LOG_WARNING, 0,
+ "packet shorter (%u bytes) than hdr+data length (%u+%u)",
+ recvlen, iphdrlen, ipdatalen);
+ continue;
}
igmp = (struct igmp *) (recv_buf + iphdrlen);
group = igmp->igmp_group.s_addr;
igmpdatalen = ipdatalen - IGMP_MINLEN;
if (igmpdatalen < 0) {
- log(LOG_WARNING, 0,
- "IP data field too short (%u bytes) for IGMP, from %s",
- ipdatalen, inet_fmt(src, s1));
- continue;
+ log(LOG_WARNING, 0,
+ "IP data field too short (%u bytes) for IGMP, from %s",
+ ipdatalen, inet_fmt(src, s1));
+ continue;
}
if (igmp->igmp_type != IGMP_DVMRP)
continue;
@@ -476,57 +539,98 @@ main(argc, argv)
ask2(target_addr);
}
} else {
- accept_neighbors(src, dst, (char *)(igmp + 1),
- igmpdatalen);
+ accept_neighbors(src, dst, (u_char *)(igmp + 1),
+ igmpdatalen, ntohl(group));
exit(0);
}
break;
case DVMRP_NEIGHBORS2:
- accept_neighbors2(src, dst, (char *)(igmp + 1),
- igmpdatalen);
+ accept_neighbors2(src, dst, (u_char *)(igmp + 1),
+ igmpdatalen, ntohl(group));
exit(0);
}
+ }
}
+ exit(1);
}
/* dummies */
-void accept_probe()
+void accept_probe(src, dst, p, datalen, level)
+ u_int32_t src, dst, level;
+ char *p;
+ int datalen;
{
}
-void accept_group_report()
+void accept_group_report(src, dst, group, r_type)
+ u_int32_t src, dst, group;
+ int r_type;
{
}
-void accept_neighbor_request2()
+void accept_neighbor_request2(src, dst)
+ u_int32_t src, dst;
{
}
-void accept_report()
+void accept_report(src, dst, p, datalen, level)
+ u_int32_t src, dst, level;
+ char *p;
+ int datalen;
{
}
-void accept_neighbor_request()
+void accept_neighbor_request(src, dst)
+ u_int32_t src, dst;
{
}
-void accept_prune()
+void accept_prune(src, dst, p, datalen)
+ u_int32_t src, dst;
+ char *p;
+ int datalen;
{
}
-void accept_graft()
+void accept_graft(src, dst, p, datalen)
+ u_int32_t src, dst;
+ char *p;
+ int datalen;
{
}
-void accept_g_ack()
+void accept_g_ack(src, dst, p, datalen)
+ u_int32_t src, dst;
+ char *p;
+ int datalen;
{
}
-void add_table_entry()
+void add_table_entry(origin, mcastgrp)
+ u_int32_t origin, mcastgrp;
{
}
void check_vif_state()
{
}
-void accept_leave_message()
+void accept_leave_message(src, dst, group)
+ u_int32_t src, dst, group;
+{
+}
+void accept_mtrace(src, dst, group, data, no, datalen)
+ u_int32_t src, dst, group;
+ char *data;
+ u_int no;
+ int datalen;
{
}
-void accept_mtrace()
+void accept_membership_query(src, dst, group, tmo)
+ u_int32_t src, dst, group;
+ int tmo;
{
}
-void accept_membership_query()
+void accept_info_request(src, dst, p, datalen)
+ u_int32_t src, dst;
+ u_char *p;
+ int datalen;
+{
+}
+void accept_info_reply(src, dst, p, datalen)
+ u_int32_t src, dst;
+ u_char *p;
+ int datalen;
{
}