delay deletion from internal tables when cur router deletes
[unix-history] / usr / src / sbin / routed / query / query.c
index d4585af..fe7adc3 100644 (file)
@@ -5,7 +5,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)query.c    5.1 (Berkeley) %G%";
+static char sccsid[] = "@(#)query.c    5.7 (Berkeley) %G%";
 #endif not lint
 
 #include <sys/param.h>
 #endif not lint
 
 #include <sys/param.h>
@@ -16,14 +16,16 @@ static char sccsid[] = "@(#)query.c 5.1 (Berkeley) %G%";
 #include <errno.h>
 #include <stdio.h>
 #include <netdb.h>
 #include <errno.h>
 #include <stdio.h>
 #include <netdb.h>
-#include "../protocol.h"
+#include <protocols/routed.h>
 
 
-#define        WTIME   5               /* Time to wait for responses */
+#define        WTIME   5               /* Time to wait for all responses */
+#define        STIME   500000          /* usec to wait for another response */
 
 int    s;
 int    timedout, timeout();
 char   packet[MAXPACKETSIZE];
 extern int errno;
 
 int    s;
 int    timedout, timeout();
 char   packet[MAXPACKETSIZE];
 extern int errno;
+int    nflag;
 
 main(argc, argv)
        int argc;
 
 main(argc, argv)
        int argc;
@@ -32,10 +34,11 @@ main(argc, argv)
        int cc, count, bits;
        struct sockaddr from;
        int fromlen = sizeof(from);
        int cc, count, bits;
        struct sockaddr from;
        int fromlen = sizeof(from);
-       struct timeval notime;
+       struct timeval shorttime;
        
        if (argc < 2) {
        
        if (argc < 2) {
-               printf("usage: query hosts...\n");
+usage:
+               printf("usage: query [ -n ] hosts...\n");
                exit(1);
        }
        s = socket(AF_INET, SOCK_DGRAM, 0);
                exit(1);
        }
        s = socket(AF_INET, SOCK_DGRAM, 0);
@@ -45,9 +48,19 @@ main(argc, argv)
        }
 
        argv++, argc--;
        }
 
        argv++, argc--;
-       count = argc;
+       if (*argv[0] == '-') {
+               switch (argv[0][1]) {
+               case 'n':
+                       nflag++;
+                       break;
+               default:
+                       goto usage;
+               }
+               argc--, argv++;
+       }
        while (argc > 0) {
                query(*argv);
        while (argc > 0) {
                query(*argv);
+               count++;
                argv++, argc--;
        }
 
                argv++, argc--;
        }
 
@@ -56,11 +69,12 @@ main(argc, argv)
         * may be more than one packet per host.
         */
        bits = 1 << s;
         * may be more than one packet per host.
         */
        bits = 1 << s;
-       bzero(&notime, sizeof(notime));
+       bzero(&shorttime, sizeof(shorttime));
+       shorttime.tv_usec = STIME;
        signal(SIGALRM, timeout);
        alarm(WTIME);
        while ((count > 0 && !timedout) ||
        signal(SIGALRM, timeout);
        alarm(WTIME);
        while ((count > 0 && !timedout) ||
-           select(20, &bits, 0, 0, &notime) > 0) {
+           select(20, &bits, 0, 0, &shorttime) > 0) {
                cc = recvfrom(s, packet, sizeof (packet), 0,
                  &from, &fromlen);
                if (cc <= 0) {
                cc = recvfrom(s, packet, sizeof (packet), 0,
                  &from, &fromlen);
                if (cc <= 0) {
@@ -87,13 +101,16 @@ query(host)
        struct servent *sp;
 
        bzero((char *)&router, sizeof (router));
        struct servent *sp;
 
        bzero((char *)&router, sizeof (router));
-       hp = gethostbyname(host);
-       if (hp == 0) {
-               printf("%s: unknown\n", host);
-               exit(1);
-       }
-       bcopy(hp->h_addr, &router.sin_addr, hp->h_length);
        router.sin_family = AF_INET;
        router.sin_family = AF_INET;
+       router.sin_addr.s_addr = inet_addr(host);
+       if (router.sin_addr.s_addr == -1) {
+               hp = gethostbyname(host);
+               if (hp == 0) {
+                       printf("%s: unknown\n", host);
+                       exit(1);
+               }
+               bcopy(hp->h_addr, &router.sin_addr, hp->h_length);
+       }
        sp = getservbyname("router", "udp");
        if (sp == 0) {
                printf("udp/router: service unknown\n");
        sp = getservbyname("router", "udp");
        if (sp == 0) {
                printf("udp/router: service unknown\n");
@@ -117,7 +134,7 @@ rip_input(from, size)
        int size;
 {
        register struct rip *msg = (struct rip *)packet;
        int size;
 {
        register struct rip *msg = (struct rip *)packet;
-       struct netinfo *n;
+       register struct netinfo *n;
        char *name;
        int lna, net, subnet;
        struct hostent *hp;
        char *name;
        int lna, net, subnet;
        struct hostent *hp;
@@ -125,51 +142,81 @@ rip_input(from, size)
 
        if (msg->rip_cmd != RIPCMD_RESPONSE)
                return;
 
        if (msg->rip_cmd != RIPCMD_RESPONSE)
                return;
-       hp = gethostbyaddr(&from->sin_addr, sizeof (struct in_addr), AF_INET);
-       name = hp == 0 ? "???" : hp->h_name;
-       printf("from %s(%s):\n", name, inet_ntoa(from->sin_addr));
+       printf("%d bytes from ", size);
+       if (nflag)
+               printf("%s:\n", inet_ntoa(from->sin_addr));
+       else {
+               hp = gethostbyaddr(&from->sin_addr, sizeof (struct in_addr),
+                       AF_INET);
+               name = hp == 0 ? "???" : hp->h_name;
+               printf("%s(%s):\n", name, inet_ntoa(from->sin_addr));
+       }
        size -= sizeof (int);
        n = msg->rip_nets;
        while (size > 0) {
        size -= sizeof (int);
        n = msg->rip_nets;
        while (size > 0) {
-               register struct sockaddr_in *sin;
+           if (size < sizeof (struct netinfo))
+                   break;
+           if (msg->rip_vers > 0) {
+                   n->rip_dst.sa_family =
+                           ntohs(n->rip_dst.sa_family);
+                   n->rip_metric = ntohl(n->rip_metric);
+           }
+           switch (n->rip_dst.sa_family) {
+
+           case AF_INET:
+               { register struct sockaddr_in *sin;
 
 
-               if (size < sizeof (struct netinfo))
-                       break;
-               if (msg->rip_vers > 0) {
-                       n->rip_dst.sa_family =
-                               ntohs(n->rip_dst.sa_family);
-                       n->rip_metric = ntohl(n->rip_metric);
-               }
                sin = (struct sockaddr_in *)&n->rip_dst;
                net = inet_netof(sin->sin_addr);
                subnet = inet_subnetof(sin->sin_addr);
                lna = inet_lnaof(sin->sin_addr);
                name = "???";
                sin = (struct sockaddr_in *)&n->rip_dst;
                net = inet_netof(sin->sin_addr);
                subnet = inet_subnetof(sin->sin_addr);
                lna = inet_lnaof(sin->sin_addr);
                name = "???";
-               if (lna == INADDR_ANY) {
-                       np = getnetbyaddr(net, AF_INET);
-                       if (np)
-                               name = np->n_name;
-                       else if (net == 0)
+               if (!nflag) {
+                       if (sin->sin_addr.s_addr == 0)
                                name = "default";
                                name = "default";
-               } else if ((subnet != net) && ((lna & 0xff) == 0) &&
-                   (np = getnetbyaddr(subnet, AF_INET))) {
-                       struct in_addr subnaddr, inet_makeaddr();
-
-                       subnaddr = inet_makeaddr(subnet, INADDR_ANY);
-                       if (bcmp(&sin->sin_addr, &subnaddr, sizeof(subnaddr)) == 0)
-                               name = np->n_name;
-                       else
-                               goto host;
-               } else {
-host:
-                       hp = gethostbyaddr(&sin->sin_addr,
-                           sizeof (struct in_addr), AF_INET);
-                       if (hp)
-                               name = hp->h_name;
+                       else if (lna == INADDR_ANY) {
+                               np = getnetbyaddr(net, AF_INET);
+                               if (np)
+                                       name = np->n_name;
+                               else if (net == 0)
+                                       name = "default";
+                       } else if ((lna & 0xff) == 0 &&
+                           (np = getnetbyaddr(subnet, AF_INET))) {
+                               struct in_addr subnaddr, inet_makeaddr();
+
+                               subnaddr = inet_makeaddr(subnet, INADDR_ANY);
+                               if (bcmp(&sin->sin_addr, &subnaddr,
+                                   sizeof(subnaddr)) == 0)
+                                       name = np->n_name;
+                               else
+                                       goto host;
+                       } else {
+       host:
+                               hp = gethostbyaddr(&sin->sin_addr,
+                                   sizeof (struct in_addr), AF_INET);
+                               if (hp)
+                                       name = hp->h_name;
+                       }
+                       printf("\t%s(%s), metric %d\n", name,
+                               inet_ntoa(sin->sin_addr), n->rip_metric);
+               } else
+                       printf("\t%s, metric %d\n",
+                               inet_ntoa(sin->sin_addr), n->rip_metric);
+               break;
+               }
+
+           default:
+               { u_short *p = (u_short *)n->rip_dst.sa_data;
+
+               printf("\t(af %d) %x %x %x %x %x %x %x, metric %d\n",
+                   p[0], p[1], p[2], p[3], p[4], p[5], p[6],
+                   n->rip_dst.sa_family,
+                   n->rip_metric);
+               break;
                }
                }
-               printf("\t%s(%s), metric %d\n", name,
-                       inet_ntoa(sin->sin_addr), n->rip_metric);
-               size -= sizeof (struct netinfo), n++;
+                       
+           }
+           size -= sizeof (struct netinfo), n++;
        }
 }
 
        }
 }
 
@@ -180,9 +227,6 @@ timeout()
 
 /*
  * Return the possible subnetwork number from an internet address.
 
 /*
  * Return the possible subnetwork number from an internet address.
- * If the address is of the form of a subnet address (most significant
- * bit of the host part is set), believe the subnet exists.
- * Otherwise, return the network number.
  * SHOULD FIND OUT WHETHER THIS IS A LOCAL NETWORK BEFORE LOOKING
  * INSIDE OF THE HOST PART.  We can only believe this if we have other
  * information (e.g., we can find a name for this number).
  * SHOULD FIND OUT WHETHER THIS IS A LOCAL NETWORK BEFORE LOOKING
  * INSIDE OF THE HOST PART.  We can only believe this if we have other
  * information (e.g., we can find a name for this number).
@@ -192,16 +236,10 @@ inet_subnetof(in)
 {
        register u_long i = ntohl(in.s_addr);
 
 {
        register u_long i = ntohl(in.s_addr);
 
-       if (IN_CLASSA(i)) {
-               if (IN_SUBNETA(i))
-                       return ((i & IN_CLASSA_SUBNET) >> IN_CLASSA_SUBNSHIFT);
-               else
-                       return ((i & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT);
-       } else if (IN_CLASSB(i)) {
-               if (IN_SUBNETB(i))
-                       return ((i & IN_CLASSB_SUBNET) >> IN_CLASSB_SUBNSHIFT);
-               else
-                       return ((i & IN_CLASSB_NET) >> IN_CLASSB_NSHIFT);
-       } else
+       if (IN_CLASSA(i))
+               return ((i & IN_CLASSB_NET) >> IN_CLASSB_NSHIFT);
+       else if (IN_CLASSB(i))
                return ((i & IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
                return ((i & IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
+       else
+               return ((i & 0xffffffc0) >> 28);
 }
 }