aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin/mrouted/mrinfo.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/mrouted/mrinfo.c')
-rw-r--r--usr.sbin/mrouted/mrinfo.c151
1 files changed, 116 insertions, 35 deletions
diff --git a/usr.sbin/mrouted/mrinfo.c b/usr.sbin/mrouted/mrinfo.c
index 8f137d0f3e6a..f4ccc86eb6d8 100644
--- a/usr.sbin/mrouted/mrinfo.c
+++ b/usr.sbin/mrouted/mrinfo.c
@@ -61,7 +61,7 @@
#ifndef lint
static char rcsid[] =
- "@(#) $Id: mrinfo.c,v 3.5.1.1 1995/05/09 22:58:05 fenner Exp $";
+ "@(#) $Id: mrinfo.c,v 3.6 1995/06/25 19:05:34 fenner Exp $";
/* original rcsid:
"@(#) Header: mrinfo.c,v 1.6 93/04/08 15:14:16 van Exp (LBL)";
*/
@@ -71,6 +71,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 */
@@ -80,10 +85,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 addr));
+void ask __P((u_int32 dst));
+void ask2 __P((u_int32 dst));
+int get_number __P((int *var, int deflt, char ***pargv,
+ int *pargc));
+u_int32 host_addr __P((char *name));
+void usage __P((void));
+
+/* to shut up -Wstrict-prototypes */
+int main __P((int argc, char *argv[]));
+
+
char *
inet_name(addr)
u_int32 addr;
@@ -107,14 +124,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)
@@ -130,7 +159,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)
@@ -166,9 +195,9 @@ ask2(dst)
* Process an incoming neighbor-list message.
*/
void
-accept_neighbors(src, dst, p, datalen)
- u_int32 src, dst;
- u_char *p;
+accept_neighbors(src, dst, p, datalen, level)
+ u_int32 src, dst, level;
+ u_char *p;
int datalen;
{
u_char *ep = p + datalen;
@@ -199,17 +228,17 @@ accept_neighbors(src, dst, p, datalen)
}
void
-accept_neighbors2(src, dst, p, datalen)
- u_int32 src, dst;
- u_char *p;
+accept_neighbors2(src, dst, p, datalen, level)
+ u_int32 src, dst, level;
+ u_char *p;
int datalen;
{
u_char *ep = p + datalen;
- u_int broken_cisco = ((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);
+ level & 0xff, (level >> 8) & 0xff);
while (p < ep) {
register u_char metric;
@@ -308,6 +337,10 @@ main(argc, argv)
int argc;
char *argv[];
{
+ int tries = 0;
+ int trynew = 1;
+ struct timeval et;
+
setlinebuf(stderr);
if (geteuid() != 0) {
@@ -375,12 +408,20 @@ main(argc, argv)
our_addr = addr.sin_addr.s_addr;
}
- ask(target_addr);
+ /*
+ * 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 src, dst, group;
struct ip *ip;
@@ -390,8 +431,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);
@@ -401,9 +450,14 @@ main(argc, argv)
continue;
} else if (count == 0) {
log(LOG_DEBUG, 0, "Timed out receiving neighbor lists");
- if (--retries < 0)
+ if (++tries > retries)
exit(1);
- if (target_level == 0)
+ /* 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);
@@ -473,57 +527,84 @@ 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);
}
}
}
/* dummies */
-void accept_probe()
+void accept_probe(src, dst, p, datalen, level)
+ u_int32 src, dst, level;
+ char *p;
+ int datalen;
{
}
-void accept_group_report()
+void accept_group_report(src, dst, group, r_type)
+ u_int32 src, dst, group;
+ int r_type;
{
}
-void accept_neighbor_request2()
+void accept_neighbor_request2(src, dst)
+ u_int32 src, dst;
{
}
-void accept_report()
+void accept_report(src, dst, p, datalen, level)
+ u_int32 src, dst, level;
+ char *p;
+ int datalen;
{
}
-void accept_neighbor_request()
+void accept_neighbor_request(src, dst)
+ u_int32 src, dst;
{
}
-void accept_prune()
+void accept_prune(src, dst, p, datalen)
+ u_int32 src, dst;
+ char *p;
+ int datalen;
{
}
-void accept_graft()
+void accept_graft(src, dst, p, datalen)
+ u_int32 src, dst;
+ char *p;
+ int datalen;
{
}
-void accept_g_ack()
+void accept_g_ack(src, dst, p, datalen)
+ u_int32 src, dst;
+ char *p;
+ int datalen;
{
}
-void add_table_entry()
+void add_table_entry(origin, mcastgrp)
+ u_int32 origin, mcastgrp;
{
}
void check_vif_state()
{
}
-void accept_leave_message()
+void accept_leave_message(src, dst, group)
+ u_int32 src, dst, group;
{
}
-void accept_mtrace()
+void accept_mtrace(src, dst, group, data, no, datalen)
+ u_int32 src, dst, group;
+ char *data;
+ u_int no;
+ int datalen;
{
}
-void accept_membership_query()
+void accept_membership_query(src, dst, group, tmo)
+ u_int32 src, dst, group;
+ int tmo;
{
}