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