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

Defined functions

inet_subnetof defined in line 236; used 1 times
main defined in line 31; never used
query defined in line 97; used 1 times
  • in line 64
rip_input defined in line 134; used 1 times
  • in line 92
timeout defined in line 225; used 2 times

Defined variables

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

Defined macros

STIME defined in line 23; used 1 times
  • in line 75
WTIME defined in line 22; used 1 times
  • in line 77
Last modified: 1987-07-22
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 806
Valid CSS Valid XHTML 1.0 Strict