resync with kernel, add metric and IFF_LOOPBACK
[unix-history] / usr / src / sbin / XNSrouted / tools / query.c
CommitLineData
efe4f2b0 1/*
791c4f9a 2 * Copyright (c) 1983 Regents of the University of California.
efe4f2b0
KS
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 */
6
7#ifndef lint
791c4f9a
KS
8char copyright[] =
9"@(#) Copyright (c) 1983 Regents of the University of California.\n\
10 All rights reserved.\n";
11#endif not lint
12
13#ifndef lint
14static char sccsid[] = "@(#)query.c 5.2 (Berkeley) %G%";
efe4f2b0
KS
15#endif not lint
16
17#include <sys/param.h>
18#include <sys/protosw.h>
19#include <sys/socket.h>
20#include <sys/time.h>
21#include <netinet/in.h>
22#include <netns/ns.h>
23#include <netns/idp.h>
24#include <errno.h>
25#include <stdio.h>
26#include <netdb.h>
27#include "../protocol.h"
28#define IDPPORT_RIF 1
29#define xnnet(p) (*(long *)&(p))
30
31#define WTIME 5 /* Time to wait for responses */
32
33int s;
34int timedout, timeout();
35char packet[MAXPACKETSIZE];
36extern int errno;
37struct sockaddr_ns myaddr = {AF_NS};
38main(argc, argv)
39int argc;
40char *argv[];
41{
42 int cc, count, bits;
43 struct sockaddr from;
44 int fromlen = sizeof(from);
45 struct timeval notime;
46
47 if (argc < 2) {
48 printf("usage: query hosts...\n");
49 exit(1);
50 }
51 s = getsocket(SOCK_DGRAM, 0);
52 if (s < 0) {
53 perror("socket");
54 exit(2);
55 }
56
57 argv++, argc--;
791c4f9a 58 query(argv,argc);
efe4f2b0
KS
59
60 /*
61 * Listen for returning packets;
62 * may be more than one packet per host.
63 */
64 bits = 1 << s;
65 bzero(&notime, sizeof(notime));
66 signal(SIGALRM, timeout);
67 alarm(WTIME);
791c4f9a 68 while (!timedout ||
efe4f2b0
KS
69 select(20, &bits, 0, 0, &notime) > 0) {
70 struct nspacket {
71 struct idp hdr;
72 char data[512];
73 } response;
74 cc = recvfrom(s, &response, sizeof (response), 0,
75 &from, &fromlen);
76 if (cc <= 0) {
77 if (cc < 0) {
78 if (errno == EINTR)
79 continue;
80 perror("recvfrom");
81 (void) close(s);
82 exit(1);
83 }
84 continue;
85 }
86 rip_input(&from, response.data, cc);
87 count--;
88 }
89}
90
791c4f9a
KS
91query(argv,argc)
92char **argv;
efe4f2b0
KS
93{
94 struct sockaddr_ns router;
95 register struct rip *msg = (struct rip *)packet;
96 long mynet;
97 short work[3];
791c4f9a 98 char *host = *argv;
efe4f2b0 99
791c4f9a 100 argv++; argc--;
efe4f2b0
KS
101 bzero((char *)&router, sizeof (router));
102 router.sns_family = AF_NS;
103 router.sns_addr.x_port = htons(IDPPORT_RIF);
104 sscanf(host, "%ld:%hx,%hx,%hx",
105 &mynet,work+0, work+1, work+2);
106 router.sns_addr.x_host = *(union ns_host *)work;
107 xnnet(router.sns_addr.x_net) = htonl(mynet);
108 msg->rip_cmd = htons(RIPCMD_REQUEST);
109 xnnet(msg->rip_nets[0]) = -1;
110 msg->rip_nets[0].rip_metric = htons(HOPCNT_INFINITY);
791c4f9a
KS
111 if (argc > 0) {
112 u_long wanted = xnnet(msg->rip_nets[0]) = htonl(atoi(*argv));
113 printf("Net asked for was %d\n", ntohl(wanted));
114 }
efe4f2b0
KS
115 if (sendto(s, packet, sizeof (struct rip), 0,
116 &router, sizeof(router)) < 0)
117 perror(host);
118}
119
120/*
121 * Handle an incoming routing packet.
122 */
123rip_input(from, msg, size)
124 struct sockaddr_ns *from;
125 register struct rip *msg;
126 int size;
127{
128 struct netinfo *n;
129 char *name;
130 int lna, net, subnet;
131 struct hostent *hp;
132 struct netent *np;
133
134 if (htons(msg->rip_cmd) != RIPCMD_RESPONSE)
135 return;
136 printf("from %d:%x,%x,%x\n",
137 ntohl(xnnet(from->sns_addr.x_net)),
138 from->sns_addr.x_host.s_host[0],
139 from->sns_addr.x_host.s_host[1],
140 from->sns_addr.x_host.s_host[2]);
141 size -= sizeof (struct idp);
142 size -= sizeof (short);
143 n = msg->rip_nets;
144 while (size > 0) {
145 if (size < sizeof (struct netinfo))
146 break;
147 printf("\t%d, metric %d\n", ntohl(xnnet(n->rip_dst[0])),
148 ntohs(n->rip_metric));
149 size -= sizeof (struct netinfo), n++;
150 }
151}
152
153timeout()
154{
155 timedout = 1;
156}
157getsocket(type, proto)
158 int type, proto;
159{
160 struct sockaddr_ns *sns = &myaddr;
161 int domain = sns->sns_family;
162 int retry, s, on = 1;
163
164 retry = 1;
165 while ((s = socket(domain, type, proto)) < 0 && retry) {
166 perror("socket");
167 sleep(5 * retry);
168 retry <<= 1;
169 }
170 if (retry == 0)
171 return (-1);
172 while (bind(s, sns, sizeof (*sns), 0) < 0 && retry) {
173 perror("bind");
174 sleep(5 * retry);
175 retry <<= 1;
176 }
177 if (retry == 0)
178 return (-1);
179 if (domain==AF_NS) {
180 struct idp idp;
181 if (setsockopt(s, 0, SO_HEADERS_ON_INPUT, &on, sizeof(on))) {
182 perror("setsockopt SEE HEADERS");
183 exit(1);
184 }
185 idp.idp_pt = NSPROTO_RI;
186 if (setsockopt(s, 0, SO_DEFAULT_HEADERS, &idp, sizeof(idp))) {
187 perror("setsockopt SET HEADERS");
188 exit(1);
189 }
190 }
191 if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) {
192 perror("setsockopt SO_BROADCAST");
193 exit(1);
194 }
195 return (s);
196}