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