|
|
1.1 root 1: /*
2: * Copyright (c) 1983, 1986 The Regents of the University of California.
3: * All rights reserved.
4: *
5: * This file includes significant work done at Cornell University by
6: * Bill Nesheim. That work included by permission.
7: *
8: * Redistribution and use in source and binary forms are permitted
9: * provided that the above copyright notice and this paragraph are
10: * duplicated in all such forms and that any documentation,
11: * advertising materials, and other materials related to such
12: * distribution and use acknowledge that the software was developed
13: * by the University of California, Berkeley. The name of the
14: * University may not be used to endorse or promote products derived
15: * from this software without specific prior written permission.
16: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18: * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19: */
20:
21: #ifndef lint
22: char copyright[] =
23: "@(#) Copyright (c) 1983, 1986 The Regents of the University of California.\n\
24: All rights reserved.\n";
25: #endif /* not lint */
26:
27: #ifndef lint
28: static char sccsid[] = "@(#)query.c 5.6 (Berkeley) 9/19/88";
29: #endif /* not lint */
30:
31: #include <sys/param.h>
32: #include <sys/protosw.h>
33: #include <sys/socket.h>
34: #include <sys/time.h>
35: #include <netinet/in.h>
36: #include <netns/ns.h>
37: #include <netns/idp.h>
38: #include <errno.h>
39: #include <stdio.h>
40: #include <netdb.h>
41: #include "../protocol.h"
42: #define IDPPORT_RIF 1
43:
44: #define WTIME 5 /* Time to wait for responses */
45:
46: int s;
47: int timedout, timeout();
48: char packet[MAXPACKETSIZE];
49: extern int errno;
50: struct sockaddr_ns myaddr = {AF_NS};
51: char *ns_ntoa();
52: struct ns_addr ns_addr();
53: main(argc, argv)
54: int argc;
55: char *argv[];
56: {
57: int cc, count, bits;
58: struct sockaddr from;
59: int fromlen = sizeof(from);
60: struct timeval notime;
61:
62: if (argc < 2) {
63: printf("usage: query hosts...\n");
64: exit(1);
65: }
66: s = getsocket(SOCK_DGRAM, 0);
67: if (s < 0) {
68: perror("socket");
69: exit(2);
70: }
71:
72: argv++, argc--;
73: query(argv,argc);
74:
75: /*
76: * Listen for returning packets;
77: * may be more than one packet per host.
78: */
79: bits = 1 << s;
80: bzero(¬ime, sizeof(notime));
81: signal(SIGALRM, timeout);
82: alarm(WTIME);
83: while (!timedout ||
84: select(20, &bits, 0, 0, ¬ime) > 0) {
85: struct nspacket {
86: struct idp hdr;
87: char data[512];
88: } response;
89: cc = recvfrom(s, &response, sizeof (response), 0,
90: &from, &fromlen);
91: if (cc <= 0) {
92: if (cc < 0) {
93: if (errno == EINTR)
94: continue;
95: perror("recvfrom");
96: (void) close(s);
97: exit(1);
98: }
99: continue;
100: }
101: rip_input(&from, response.data, cc);
102: count--;
103: }
104: }
105: static struct sockaddr_ns router = {AF_NS};
106: static struct ns_addr zero_addr;
107: static short allones[] = {-1, -1, -1};
108:
109: query(argv,argc)
110: char **argv;
111: {
112: register struct rip *msg = (struct rip *)packet;
113: char *host = *argv;
114: struct ns_addr specific;
115:
116: argv++; argc--;
117: router.sns_addr = ns_addr(host);
118: router.sns_addr.x_port = htons(IDPPORT_RIF);
119: if (ns_hosteq(zero_addr, router.sns_addr)) {
120: router.sns_addr.x_host = *(union ns_host *) allones;
121: }
122: msg->rip_cmd = htons(RIPCMD_REQUEST);
123: msg->rip_nets[0].rip_dst = *(union ns_net *) allones;
124: msg->rip_nets[0].rip_metric = htons(HOPCNT_INFINITY);
125: if (argc > 0) {
126: specific = ns_addr(*argv);
127: msg->rip_nets[0].rip_dst = specific.x_net;
128: specific.x_host = zero_addr.x_host;
129: specific.x_port = zero_addr.x_port;
130: printf("Net asked for was %s\n", ns_ntoa(specific));
131: }
132: if (sendto(s, packet, sizeof (struct rip), 0,
133: &router, sizeof(router)) < 0)
134: perror(host);
135: }
136:
137: /*
138: * Handle an incoming routing packet.
139: */
140: rip_input(from, msg, size)
141: struct sockaddr_ns *from;
142: register struct rip *msg;
143: int size;
144: {
145: struct netinfo *n;
146: char *name;
147: int lna, net, subnet;
148: struct hostent *hp;
149: struct netent *np;
150: static struct ns_addr work;
151:
152: if (htons(msg->rip_cmd) != RIPCMD_RESPONSE)
153: return;
154: printf("from %s\n", ns_ntoa(from->sns_addr));
155: size -= sizeof (struct idp);
156: size -= sizeof (short);
157: n = msg->rip_nets;
158: while (size > 0) {
159: union ns_net_u net;
160: if (size < sizeof (struct netinfo))
161: break;
162: net.net_e = n->rip_dst;
163: printf("\t%d, metric %d\n", ntohl(net.long_e),
164: ntohs(n->rip_metric));
165: size -= sizeof (struct netinfo), n++;
166: }
167: }
168:
169: timeout()
170: {
171: timedout = 1;
172: }
173: getsocket(type, proto)
174: int type, proto;
175: {
176: struct sockaddr_ns *sns = &myaddr;
177: int domain = sns->sns_family;
178: int retry, s, on = 1;
179:
180: retry = 1;
181: while ((s = socket(domain, type, proto)) < 0 && retry) {
182: perror("socket");
183: sleep(5 * retry);
184: retry <<= 1;
185: }
186: if (retry == 0)
187: return (-1);
188: while (bind(s, sns, sizeof (*sns), 0) < 0 && retry) {
189: perror("bind");
190: sleep(5 * retry);
191: retry <<= 1;
192: }
193: if (retry == 0)
194: return (-1);
195: if (domain==AF_NS) {
196: struct idp idp;
197: if (setsockopt(s, 0, SO_HEADERS_ON_INPUT, &on, sizeof(on))) {
198: perror("setsockopt SEE HEADERS");
199: exit(1);
200: }
201: idp.idp_pt = NSPROTO_RI;
202: if (setsockopt(s, 0, SO_DEFAULT_HEADERS, &idp, sizeof(idp))) {
203: perror("setsockopt SET HEADERS");
204: exit(1);
205: }
206: }
207: if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) {
208: perror("setsockopt SO_BROADCAST");
209: exit(1);
210: }
211: return (s);
212: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.