Commit | Line | Data |
---|---|---|
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 | 38 | char 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 | 44 | static 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 | ||
62 | int s; | |
63 | int timedout, timeout(); | |
64 | char packet[MAXPACKETSIZE]; | |
65 | extern int errno; | |
d0808c1f | 66 | struct sockaddr_ns myaddr = {sizeof(myaddr), AF_NS}; |
d0fa19d4 | 67 | char *ns_ntoa(); |
be68ff62 | 68 | struct ns_addr ns_addr(); |
efe4f2b0 KS |
69 | main(argc, argv) |
70 | int argc; | |
71 | char *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(¬ime, sizeof(notime)); | |
97 | signal(SIGALRM, timeout); | |
98 | alarm(WTIME); | |
791c4f9a | 99 | while (!timedout || |
efe4f2b0 KS |
100 | select(20, &bits, 0, 0, ¬ime) > 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 | 121 | static struct sockaddr_ns router = {sizeof(myaddr), AF_NS}; |
be68ff62 KS |
122 | static struct ns_addr zero_addr; |
123 | static short allones[] = {-1, -1, -1}; | |
efe4f2b0 | 124 | |
791c4f9a KS |
125 | query(argv,argc) |
126 | char **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 | */ | |
160 | rip_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 | ||
189 | timeout() | |
190 | { | |
191 | timedout = 1; | |
192 | } | |
193 | getsocket(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 | } |