NO SCCS FILE!! "@(#)yyget.c 5.2 (Berkeley) 6/29/90"
[unix-history] / usr / src / sbin / XNSrouted / tools / query.c
CommitLineData
efe4f2b0 1/*
5932a057
KB
2 * Copyright (c) 1983, 1986 The Regents of the University of California.
3 * All rights reserved.
ad09eb30 4 *
5932a057
KB
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.
efe4f2b0
KS
19 */
20
21#ifndef lint
791c4f9a 22char copyright[] =
5932a057 23"@(#) Copyright (c) 1983, 1986 The Regents of the University of California.\n\
791c4f9a 24 All rights reserved.\n";
5932a057 25#endif /* not lint */
791c4f9a
KS
26
27#ifndef lint
d0808c1f 28static char sccsid[] = "@(#)query.c 5.7 (Berkeley) %G%";
5932a057 29#endif /* not lint */
efe4f2b0
KS
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
efe4f2b0
KS
43
44#define WTIME 5 /* Time to wait for responses */
45
46int s;
47int timedout, timeout();
48char packet[MAXPACKETSIZE];
49extern int errno;
d0808c1f 50struct sockaddr_ns myaddr = {sizeof(myaddr), AF_NS};
d0fa19d4 51char *ns_ntoa();
be68ff62 52struct ns_addr ns_addr();
efe4f2b0
KS
53main(argc, argv)
54int argc;
55char *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--;
791c4f9a 73 query(argv,argc);
efe4f2b0
KS
74
75 /*
76 * Listen for returning packets;
77 * may be more than one packet per host.
78 */
79 bits = 1 << s;
80 bzero(&notime, sizeof(notime));
81 signal(SIGALRM, timeout);
82 alarm(WTIME);
791c4f9a 83 while (!timedout ||
efe4f2b0
KS
84 select(20, &bits, 0, 0, &notime) > 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}
d0808c1f 105static struct sockaddr_ns router = {sizeof(myaddr), AF_NS};
be68ff62
KS
106static struct ns_addr zero_addr;
107static short allones[] = {-1, -1, -1};
efe4f2b0 108
791c4f9a
KS
109query(argv,argc)
110char **argv;
efe4f2b0 111{
efe4f2b0 112 register struct rip *msg = (struct rip *)packet;
791c4f9a 113 char *host = *argv;
d0808c1f 114 int flags = 0;
be68ff62 115 struct ns_addr specific;
efe4f2b0 116
d0808c1f
KS
117 if (bcmp(*argv, "-r", 3) == 0) {
118 flags = MSG_DONTROUTE; argv++; argc--;
119 }
120 host = *argv;
be68ff62 121 router.sns_addr = ns_addr(host);
efe4f2b0 122 router.sns_addr.x_port = htons(IDPPORT_RIF);
be68ff62
KS
123 if (ns_hosteq(zero_addr, router.sns_addr)) {
124 router.sns_addr.x_host = *(union ns_host *) allones;
125 }
efe4f2b0 126 msg->rip_cmd = htons(RIPCMD_REQUEST);
be68ff62 127 msg->rip_nets[0].rip_dst = *(union ns_net *) allones;
efe4f2b0 128 msg->rip_nets[0].rip_metric = htons(HOPCNT_INFINITY);
791c4f9a 129 if (argc > 0) {
be68ff62
KS
130 specific = ns_addr(*argv);
131 msg->rip_nets[0].rip_dst = specific.x_net;
132 specific.x_host = zero_addr.x_host;
133 specific.x_port = zero_addr.x_port;
134 printf("Net asked for was %s\n", ns_ntoa(specific));
791c4f9a 135 }
d0808c1f 136 if (sendto(s, packet, sizeof (struct rip), flags,
efe4f2b0
KS
137 &router, sizeof(router)) < 0)
138 perror(host);
139}
140
141/*
142 * Handle an incoming routing packet.
143 */
144rip_input(from, msg, size)
145 struct sockaddr_ns *from;
146 register struct rip *msg;
147 int size;
148{
149 struct netinfo *n;
150 char *name;
151 int lna, net, subnet;
152 struct hostent *hp;
153 struct netent *np;
be68ff62 154 static struct ns_addr work;
efe4f2b0
KS
155
156 if (htons(msg->rip_cmd) != RIPCMD_RESPONSE)
157 return;
be68ff62 158 printf("from %s\n", ns_ntoa(from->sns_addr));
efe4f2b0
KS
159 size -= sizeof (struct idp);
160 size -= sizeof (short);
161 n = msg->rip_nets;
162 while (size > 0) {
be68ff62 163 union ns_net_u net;
efe4f2b0
KS
164 if (size < sizeof (struct netinfo))
165 break;
be68ff62
KS
166 net.net_e = n->rip_dst;
167 printf("\t%d, metric %d\n", ntohl(net.long_e),
efe4f2b0
KS
168 ntohs(n->rip_metric));
169 size -= sizeof (struct netinfo), n++;
170 }
171}
172
173timeout()
174{
175 timedout = 1;
176}
177getsocket(type, proto)
178 int type, proto;
179{
180 struct sockaddr_ns *sns = &myaddr;
181 int domain = sns->sns_family;
182 int retry, s, on = 1;
183
184 retry = 1;
185 while ((s = socket(domain, type, proto)) < 0 && retry) {
186 perror("socket");
187 sleep(5 * retry);
188 retry <<= 1;
189 }
190 if (retry == 0)
191 return (-1);
192 while (bind(s, sns, sizeof (*sns), 0) < 0 && retry) {
193 perror("bind");
194 sleep(5 * retry);
195 retry <<= 1;
196 }
197 if (retry == 0)
198 return (-1);
199 if (domain==AF_NS) {
200 struct idp idp;
201 if (setsockopt(s, 0, SO_HEADERS_ON_INPUT, &on, sizeof(on))) {
202 perror("setsockopt SEE HEADERS");
203 exit(1);
204 }
205 idp.idp_pt = NSPROTO_RI;
206 if (setsockopt(s, 0, SO_DEFAULT_HEADERS, &idp, sizeof(idp))) {
207 perror("setsockopt SET HEADERS");
208 exit(1);
209 }
210 }
211 if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) {
212 perror("setsockopt SO_BROADCAST");
213 exit(1);
214 }
215 return (s);
216}