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