|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.