1: /*
   2:  * Copyright (c) 1980 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  */
   6: 
   7: #ifndef lint
   8: static char sccsid[] = "@(#)query.c	5.7 (Berkeley) 5/15/86";
   9: #endif not lint
  10: 
  11: #include <sys/param.h>
  12: #include <sys/protosw.h>
  13: #include <sys/socket.h>
  14: #include <sys/time.h>
  15: #include <netinet/in.h>
  16: #include <errno.h>
  17: #include <stdio.h>
  18: #include <netdb.h>
  19: #include <protocols/routed.h>
  20: 
  21: #define WTIME   5       /* Time to wait for all responses */
  22: #define STIME   500000      /* usec to wait for another response */
  23: 
  24: int s;
  25: int timedout, timeout();
  26: char    packet[MAXPACKETSIZE];
  27: extern int errno;
  28: int nflag;
  29: 
  30: main(argc, argv)
  31:     int argc;
  32:     char *argv[];
  33: {
  34:     int cc, count, bits;
  35:     struct sockaddr from;
  36:     int fromlen = sizeof(from);
  37:     struct timeval shorttime;
  38: 
  39:     if (argc < 2) {
  40: usage:
  41:         printf("usage: query [ -n ] hosts...\n");
  42:         exit(1);
  43:     }
  44:     s = socket(AF_INET, SOCK_DGRAM, 0);
  45:     if (s < 0) {
  46:         perror("socket");
  47:         exit(2);
  48:     }
  49: 
  50:     argv++, argc--;
  51:     if (*argv[0] == '-') {
  52:         switch (argv[0][1]) {
  53:         case 'n':
  54:             nflag++;
  55:             break;
  56:         default:
  57:             goto usage;
  58:         }
  59:         argc--, argv++;
  60:     }
  61:     while (argc > 0) {
  62:         query(*argv);
  63:         count++;
  64:         argv++, argc--;
  65:     }
  66: 
  67:     /*
  68: 	 * Listen for returning packets;
  69: 	 * may be more than one packet per host.
  70: 	 */
  71:     bits = 1 << s;
  72:     bzero(&shorttime, sizeof(shorttime));
  73:     shorttime.tv_usec = STIME;
  74:     signal(SIGALRM, timeout);
  75:     alarm(WTIME);
  76:     while ((count > 0 && !timedout) ||
  77:         select(20, &bits, 0, 0, &shorttime) > 0) {
  78:         cc = recvfrom(s, packet, sizeof (packet), 0,
  79:           &from, &fromlen);
  80:         if (cc <= 0) {
  81:             if (cc < 0) {
  82:                 if (errno == EINTR)
  83:                     continue;
  84:                 perror("recvfrom");
  85:                 (void) close(s);
  86:                 exit(1);
  87:             }
  88:             continue;
  89:         }
  90:         rip_input(&from, cc);
  91:         count--;
  92:     }
  93: }
  94: 
  95: query(host)
  96:     char *host;
  97: {
  98:     struct sockaddr_in router;
  99:     register struct rip *msg = (struct rip *)packet;
 100:     struct hostent *hp;
 101:     struct servent *sp;
 102: 
 103:     bzero((char *)&router, sizeof (router));
 104:     router.sin_family = AF_INET;
 105:     router.sin_addr.s_addr = inet_addr(host);
 106:     if (router.sin_addr.s_addr == -1) {
 107:         hp = gethostbyname(host);
 108:         if (hp == 0) {
 109:             printf("%s: unknown\n", host);
 110:             exit(1);
 111:         }
 112:         bcopy(hp->h_addr, &router.sin_addr, hp->h_length);
 113:     }
 114:     sp = getservbyname("router", "udp");
 115:     if (sp == 0) {
 116:         printf("udp/router: service unknown\n");
 117:         exit(1);
 118:     }
 119:     router.sin_port = sp->s_port;
 120:     msg->rip_cmd = RIPCMD_REQUEST;
 121:     msg->rip_vers = RIPVERSION;
 122:     msg->rip_nets[0].rip_dst.sa_family = htons(AF_UNSPEC);
 123:     msg->rip_nets[0].rip_metric = htonl(HOPCNT_INFINITY);
 124:     if (sendto(s, packet, sizeof (struct rip), 0,
 125:       &router, sizeof(router)) < 0)
 126:         perror(host);
 127: }
 128: 
 129: /*
 130:  * Handle an incoming routing packet.
 131:  */
 132: rip_input(from, size)
 133:     struct sockaddr_in *from;
 134:     int size;
 135: {
 136:     register struct rip *msg = (struct rip *)packet;
 137:     register struct netinfo *n;
 138:     char *name;
 139:     int lna, net, subnet;
 140:     struct hostent *hp;
 141:     struct netent *np;
 142: 
 143:     if (msg->rip_cmd != RIPCMD_RESPONSE)
 144:         return;
 145:     printf("%d bytes from ", size);
 146:     if (nflag)
 147:         printf("%s:\n", inet_ntoa(from->sin_addr));
 148:     else {
 149:         hp = gethostbyaddr(&from->sin_addr, sizeof (struct in_addr),
 150:             AF_INET);
 151:         name = hp == 0 ? "???" : hp->h_name;
 152:         printf("%s(%s):\n", name, inet_ntoa(from->sin_addr));
 153:     }
 154:     size -= sizeof (int);
 155:     n = msg->rip_nets;
 156:     while (size > 0) {
 157:         if (size < sizeof (struct netinfo))
 158:             break;
 159:         if (msg->rip_vers > 0) {
 160:             n->rip_dst.sa_family =
 161:                 ntohs(n->rip_dst.sa_family);
 162:             n->rip_metric = ntohl(n->rip_metric);
 163:         }
 164:         switch (n->rip_dst.sa_family) {
 165: 
 166:         case AF_INET:
 167:         { register struct sockaddr_in *sin;
 168: 
 169:         sin = (struct sockaddr_in *)&n->rip_dst;
 170:         net = inet_netof(sin->sin_addr);
 171:         subnet = inet_subnetof(sin->sin_addr);
 172:         lna = inet_lnaof(sin->sin_addr);
 173:         name = "???";
 174:         if (!nflag) {
 175:             if (sin->sin_addr.s_addr == 0)
 176:                 name = "default";
 177:             else if (lna == INADDR_ANY) {
 178:                 np = getnetbyaddr(net, AF_INET);
 179:                 if (np)
 180:                     name = np->n_name;
 181:                 else if (net == 0)
 182:                     name = "default";
 183:             } else if ((lna & 0xff) == 0 &&
 184:                 (np = getnetbyaddr(subnet, AF_INET))) {
 185:                 struct in_addr subnaddr, inet_makeaddr();
 186: 
 187:                 subnaddr = inet_makeaddr(subnet, INADDR_ANY);
 188:                 if (bcmp(&sin->sin_addr, &subnaddr,
 189:                     sizeof(subnaddr)) == 0)
 190:                     name = np->n_name;
 191:                 else
 192:                     goto host;
 193:             } else {
 194:     host:
 195:                 hp = gethostbyaddr(&sin->sin_addr,
 196:                     sizeof (struct in_addr), AF_INET);
 197:                 if (hp)
 198:                     name = hp->h_name;
 199:             }
 200:             printf("\t%s(%s), metric %d\n", name,
 201:                 inet_ntoa(sin->sin_addr), n->rip_metric);
 202:         } else
 203:             printf("\t%s, metric %d\n",
 204:                 inet_ntoa(sin->sin_addr), n->rip_metric);
 205:         break;
 206:         }
 207: 
 208:         default:
 209:         { u_short *p = (u_short *)n->rip_dst.sa_data;
 210: 
 211:         printf("\t(af %d) %x %x %x %x %x %x %x, metric %d\n",
 212:             p[0], p[1], p[2], p[3], p[4], p[5], p[6],
 213:             n->rip_dst.sa_family,
 214:             n->rip_metric);
 215:         break;
 216:         }
 217: 
 218:         }
 219:         size -= sizeof (struct netinfo), n++;
 220:     }
 221: }
 222: 
 223: timeout()
 224: {
 225:     timedout = 1;
 226: }
 227: 
 228: /*
 229:  * Return the possible subnetwork number from an internet address.
 230:  * SHOULD FIND OUT WHETHER THIS IS A LOCAL NETWORK BEFORE LOOKING
 231:  * INSIDE OF THE HOST PART.  We can only believe this if we have other
 232:  * information (e.g., we can find a name for this number).
 233:  */
 234: inet_subnetof(in)
 235:     struct in_addr in;
 236: {
 237:     register u_long i = ntohl(in.s_addr);
 238: 
 239:     if (IN_CLASSA(i))
 240:         return ((i & IN_CLASSB_NET) >> IN_CLASSB_NSHIFT);
 241:     else if (IN_CLASSB(i))
 242:         return ((i & IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
 243:     else
 244:         return ((i & 0xffffffc0) >> 28);
 245: }

Defined functions

inet_subnetof defined in line 234; used 1 times
main defined in line 30; never used
query defined in line 95; used 1 times
  • in line 62
rip_input defined in line 132; used 1 times
  • in line 90
timeout defined in line 223; used 2 times

Defined variables

nflag defined in line 28; used 3 times
packet defined in line 26; used 5 times
s defined in line 24; used 6 times
sccsid defined in line 8; never used
timedout defined in line 25; used 2 times

Defined macros

STIME defined in line 22; used 1 times
  • in line 73
WTIME defined in line 21; used 1 times
  • in line 75
Last modified: 1986-05-15
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1716
Valid CSS Valid XHTML 1.0 Strict