BSD 4_3_Net_2 release
[unix-history] / usr / src / sbin / XNSrouted / tools / query.c
CommitLineData
0fc6e47b 1/*-
5932a057
KB
2 * Copyright (c) 1983, 1986 The Regents of the University of California.
3 * All rights reserved.
ad09eb30 4 *
0fc6e47b
KB
5 * This code includes software contributed to Berkeley by
6 * Bill Nesheim at Cornell University.
5932a057 7 *
af359dea
C
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
5932a057 23 *
af359dea
C
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
efe4f2b0
KS
35 */
36
37#ifndef lint
791c4f9a 38char copyright[] =
5932a057 39"@(#) Copyright (c) 1983, 1986 The Regents of the University of California.\n\
791c4f9a 40 All rights reserved.\n";
5932a057 41#endif /* not lint */
791c4f9a
KS
42
43#ifndef lint
af359dea 44static char sccsid[] = "@(#)query.c 5.8 (Berkeley) 4/16/91";
5932a057 45#endif /* not lint */
efe4f2b0
KS
46
47#include <sys/param.h>
48#include <sys/protosw.h>
49#include <sys/socket.h>
50#include <sys/time.h>
51#include <netinet/in.h>
52#include <netns/ns.h>
53#include <netns/idp.h>
54#include <errno.h>
55#include <stdio.h>
56#include <netdb.h>
57#include "../protocol.h"
58#define IDPPORT_RIF 1
efe4f2b0
KS
59
60#define WTIME 5 /* Time to wait for responses */
61
62int s;
63int timedout, timeout();
64char packet[MAXPACKETSIZE];
65extern int errno;
d0808c1f 66struct sockaddr_ns myaddr = {sizeof(myaddr), AF_NS};
d0fa19d4 67char *ns_ntoa();
be68ff62 68struct ns_addr ns_addr();
efe4f2b0
KS
69main(argc, argv)
70int argc;
71char *argv[];
72{
73 int cc, count, bits;
74 struct sockaddr from;
75 int fromlen = sizeof(from);
76 struct timeval notime;
77
78 if (argc < 2) {
79 printf("usage: query hosts...\n");
80 exit(1);
81 }
82 s = getsocket(SOCK_DGRAM, 0);
83 if (s < 0) {
84 perror("socket");
85 exit(2);
86 }
87
88 argv++, argc--;
791c4f9a 89 query(argv,argc);
efe4f2b0
KS
90
91 /*
92 * Listen for returning packets;
93 * may be more than one packet per host.
94 */
95 bits = 1 << s;
96 bzero(&notime, sizeof(notime));
97 signal(SIGALRM, timeout);
98 alarm(WTIME);
791c4f9a 99 while (!timedout ||
efe4f2b0
KS
100 select(20, &bits, 0, 0, &notime) > 0) {
101 struct nspacket {
102 struct idp hdr;
103 char data[512];
104 } response;
105 cc = recvfrom(s, &response, sizeof (response), 0,
106 &from, &fromlen);
107 if (cc <= 0) {
108 if (cc < 0) {
109 if (errno == EINTR)
110 continue;
111 perror("recvfrom");
112 (void) close(s);
113 exit(1);
114 }
115 continue;
116 }
117 rip_input(&from, response.data, cc);
118 count--;
119 }
120}
d0808c1f 121static struct sockaddr_ns router = {sizeof(myaddr), AF_NS};
be68ff62
KS
122static struct ns_addr zero_addr;
123static short allones[] = {-1, -1, -1};
efe4f2b0 124
791c4f9a
KS
125query(argv,argc)
126char **argv;
efe4f2b0 127{
efe4f2b0 128 register struct rip *msg = (struct rip *)packet;
791c4f9a 129 char *host = *argv;
d0808c1f 130 int flags = 0;
be68ff62 131 struct ns_addr specific;
efe4f2b0 132
d0808c1f
KS
133 if (bcmp(*argv, "-r", 3) == 0) {
134 flags = MSG_DONTROUTE; argv++; argc--;
135 }
136 host = *argv;
be68ff62 137 router.sns_addr = ns_addr(host);
efe4f2b0 138 router.sns_addr.x_port = htons(IDPPORT_RIF);
be68ff62
KS
139 if (ns_hosteq(zero_addr, router.sns_addr)) {
140 router.sns_addr.x_host = *(union ns_host *) allones;
141 }
efe4f2b0 142 msg->rip_cmd = htons(RIPCMD_REQUEST);
be68ff62 143 msg->rip_nets[0].rip_dst = *(union ns_net *) allones;
efe4f2b0 144 msg->rip_nets[0].rip_metric = htons(HOPCNT_INFINITY);
791c4f9a 145 if (argc > 0) {
be68ff62
KS
146 specific = ns_addr(*argv);
147 msg->rip_nets[0].rip_dst = specific.x_net;
148 specific.x_host = zero_addr.x_host;
149 specific.x_port = zero_addr.x_port;
150 printf("Net asked for was %s\n", ns_ntoa(specific));
791c4f9a 151 }
d0808c1f 152 if (sendto(s, packet, sizeof (struct rip), flags,
efe4f2b0
KS
153 &router, sizeof(router)) < 0)
154 perror(host);
155}
156
157/*
158 * Handle an incoming routing packet.
159 */
160rip_input(from, msg, size)
161 struct sockaddr_ns *from;
162 register struct rip *msg;
163 int size;
164{
165 struct netinfo *n;
166 char *name;
167 int lna, net, subnet;
168 struct hostent *hp;
169 struct netent *np;
be68ff62 170 static struct ns_addr work;
efe4f2b0
KS
171
172 if (htons(msg->rip_cmd) != RIPCMD_RESPONSE)
173 return;
be68ff62 174 printf("from %s\n", ns_ntoa(from->sns_addr));
efe4f2b0
KS
175 size -= sizeof (struct idp);
176 size -= sizeof (short);
177 n = msg->rip_nets;
178 while (size > 0) {
be68ff62 179 union ns_net_u net;
efe4f2b0
KS
180 if (size < sizeof (struct netinfo))
181 break;
be68ff62
KS
182 net.net_e = n->rip_dst;
183 printf("\t%d, metric %d\n", ntohl(net.long_e),
efe4f2b0
KS
184 ntohs(n->rip_metric));
185 size -= sizeof (struct netinfo), n++;
186 }
187}
188
189timeout()
190{
191 timedout = 1;
192}
193getsocket(type, proto)
194 int type, proto;
195{
196 struct sockaddr_ns *sns = &myaddr;
197 int domain = sns->sns_family;
198 int retry, s, on = 1;
199
200 retry = 1;
201 while ((s = socket(domain, type, proto)) < 0 && retry) {
202 perror("socket");
203 sleep(5 * retry);
204 retry <<= 1;
205 }
206 if (retry == 0)
207 return (-1);
208 while (bind(s, sns, sizeof (*sns), 0) < 0 && retry) {
209 perror("bind");
210 sleep(5 * retry);
211 retry <<= 1;
212 }
213 if (retry == 0)
214 return (-1);
215 if (domain==AF_NS) {
216 struct idp idp;
217 if (setsockopt(s, 0, SO_HEADERS_ON_INPUT, &on, sizeof(on))) {
218 perror("setsockopt SEE HEADERS");
219 exit(1);
220 }
221 idp.idp_pt = NSPROTO_RI;
222 if (setsockopt(s, 0, SO_DEFAULT_HEADERS, &idp, sizeof(idp))) {
223 perror("setsockopt SET HEADERS");
224 exit(1);
225 }
226 }
227 if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) {
228 perror("setsockopt SO_BROADCAST");
229 exit(1);
230 }
231 return (s);
232}