|
|
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.