xref: /csrg-svn/sbin/XNSrouted/tools/query.c (revision 26176)
124265Ssklower /*
224326Ssklower  * Copyright (c) 1983 Regents of the University of California.
324265Ssklower  * All rights reserved.  The Berkeley software License Agreement
424265Ssklower  * specifies the terms and conditions for redistribution.
524265Ssklower  */
624265Ssklower 
724265Ssklower #ifndef lint
824326Ssklower char copyright[] =
924326Ssklower "@(#) Copyright (c) 1983 Regents of the University of California.\n\
1024326Ssklower  All rights reserved.\n";
1124265Ssklower #endif not lint
1224265Ssklower 
1324326Ssklower #ifndef lint
14*26176Ssklower static char sccsid[] = "@(#)query.c	5.3 (Berkeley) 02/14/86";
1524326Ssklower #endif not lint
1624326Ssklower 
1724265Ssklower #include <sys/param.h>
1824265Ssklower #include <sys/protosw.h>
1924265Ssklower #include <sys/socket.h>
2024265Ssklower #include <sys/time.h>
2124265Ssklower #include <netinet/in.h>
2224265Ssklower #include <netns/ns.h>
2324265Ssklower #include <netns/idp.h>
2424265Ssklower #include <errno.h>
2524265Ssklower #include <stdio.h>
2624265Ssklower #include <netdb.h>
2724265Ssklower #include "../protocol.h"
2824265Ssklower #define IDPPORT_RIF 1
2924265Ssklower 
3024265Ssklower #define	WTIME	5		/* Time to wait for responses */
3124265Ssklower 
3224265Ssklower int	s;
3324265Ssklower int	timedout, timeout();
3424265Ssklower char	packet[MAXPACKETSIZE];
3524265Ssklower extern int errno;
3624265Ssklower struct sockaddr_ns	myaddr = {AF_NS};
37*26176Ssklower char ns_ntoa();
38*26176Ssklower struct ns_addr ns_addr();
3924265Ssklower main(argc, argv)
4024265Ssklower int argc;
4124265Ssklower char *argv[];
4224265Ssklower {
4324265Ssklower 	int cc, count, bits;
4424265Ssklower 	struct sockaddr from;
4524265Ssklower 	int fromlen = sizeof(from);
4624265Ssklower 	struct timeval notime;
4724265Ssklower 
4824265Ssklower 	if (argc < 2) {
4924265Ssklower 		printf("usage: query hosts...\n");
5024265Ssklower 		exit(1);
5124265Ssklower 	}
5224265Ssklower 	s = getsocket(SOCK_DGRAM, 0);
5324265Ssklower 	if (s < 0) {
5424265Ssklower 		perror("socket");
5524265Ssklower 		exit(2);
5624265Ssklower 	}
5724265Ssklower 
5824265Ssklower 	argv++, argc--;
5924326Ssklower 	query(argv,argc);
6024265Ssklower 
6124265Ssklower 	/*
6224265Ssklower 	 * Listen for returning packets;
6324265Ssklower 	 * may be more than one packet per host.
6424265Ssklower 	 */
6524265Ssklower 	bits = 1 << s;
6624265Ssklower 	bzero(&notime, sizeof(notime));
6724265Ssklower 	signal(SIGALRM, timeout);
6824265Ssklower 	alarm(WTIME);
6924326Ssklower 	while (!timedout ||
7024265Ssklower 	    select(20, &bits, 0, 0, &notime) > 0) {
7124265Ssklower 		struct nspacket {
7224265Ssklower 			struct idp hdr;
7324265Ssklower 			char	data[512];
7424265Ssklower 		} response;
7524265Ssklower 		cc = recvfrom(s, &response, sizeof (response), 0,
7624265Ssklower 		  &from, &fromlen);
7724265Ssklower 		if (cc <= 0) {
7824265Ssklower 			if (cc < 0) {
7924265Ssklower 				if (errno == EINTR)
8024265Ssklower 					continue;
8124265Ssklower 				perror("recvfrom");
8224265Ssklower 				(void) close(s);
8324265Ssklower 				exit(1);
8424265Ssklower 			}
8524265Ssklower 			continue;
8624265Ssklower 		}
8724265Ssklower 		rip_input(&from, response.data, cc);
8824265Ssklower 		count--;
8924265Ssklower 	}
9024265Ssklower }
91*26176Ssklower static struct sockaddr_ns router = {AF_NS};
92*26176Ssklower static struct ns_addr zero_addr;
93*26176Ssklower static short allones[] = {-1, -1, -1};
9424265Ssklower 
9524326Ssklower query(argv,argc)
9624326Ssklower char **argv;
9724265Ssklower {
9824265Ssklower 	register struct rip *msg = (struct rip *)packet;
9924326Ssklower 	char *host = *argv;
100*26176Ssklower 	struct ns_addr specific;
10124265Ssklower 
10224326Ssklower 	argv++; argc--;
103*26176Ssklower 	router.sns_addr = ns_addr(host);
10424265Ssklower 	router.sns_addr.x_port = htons(IDPPORT_RIF);
105*26176Ssklower 	if (ns_hosteq(zero_addr, router.sns_addr)) {
106*26176Ssklower 		router.sns_addr.x_host = *(union ns_host *) allones;
107*26176Ssklower 	}
10824265Ssklower 	msg->rip_cmd = htons(RIPCMD_REQUEST);
109*26176Ssklower 	msg->rip_nets[0].rip_dst = *(union ns_net *) allones;
11024265Ssklower 	msg->rip_nets[0].rip_metric = htons(HOPCNT_INFINITY);
11124326Ssklower 	if (argc > 0) {
112*26176Ssklower 		specific = ns_addr(*argv);
113*26176Ssklower 		msg->rip_nets[0].rip_dst = specific.x_net;
114*26176Ssklower 		specific.x_host = zero_addr.x_host;
115*26176Ssklower 		specific.x_port = zero_addr.x_port;
116*26176Ssklower 		printf("Net asked for was %s\n", ns_ntoa(specific));
11724326Ssklower 	}
11824265Ssklower 	if (sendto(s, packet, sizeof (struct rip), 0,
11924265Ssklower 	  &router, sizeof(router)) < 0)
12024265Ssklower 		perror(host);
12124265Ssklower }
12224265Ssklower 
12324265Ssklower /*
12424265Ssklower  * Handle an incoming routing packet.
12524265Ssklower  */
12624265Ssklower rip_input(from, msg,  size)
12724265Ssklower 	struct sockaddr_ns *from;
12824265Ssklower 	register struct rip *msg;
12924265Ssklower 	int size;
13024265Ssklower {
13124265Ssklower 	struct netinfo *n;
13224265Ssklower 	char *name;
13324265Ssklower 	int lna, net, subnet;
13424265Ssklower 	struct hostent *hp;
13524265Ssklower 	struct netent *np;
136*26176Ssklower 	static struct ns_addr work;
13724265Ssklower 
13824265Ssklower 	if (htons(msg->rip_cmd) != RIPCMD_RESPONSE)
13924265Ssklower 		return;
140*26176Ssklower 	printf("from %s\n", ns_ntoa(from->sns_addr));
14124265Ssklower 	size -= sizeof (struct idp);
14224265Ssklower 	size -= sizeof (short);
14324265Ssklower 	n = msg->rip_nets;
14424265Ssklower 	while (size > 0) {
145*26176Ssklower 		union ns_net_u net;
14624265Ssklower 		if (size < sizeof (struct netinfo))
14724265Ssklower 			break;
148*26176Ssklower 		net.net_e = n->rip_dst;
149*26176Ssklower 		printf("\t%d, metric %d\n", ntohl(net.long_e),
15024265Ssklower 			ntohs(n->rip_metric));
15124265Ssklower 		size -= sizeof (struct netinfo), n++;
15224265Ssklower 	}
15324265Ssklower }
15424265Ssklower 
15524265Ssklower timeout()
15624265Ssklower {
15724265Ssklower 	timedout = 1;
15824265Ssklower }
15924265Ssklower getsocket(type, proto)
16024265Ssklower 	int type, proto;
16124265Ssklower {
16224265Ssklower 	struct sockaddr_ns *sns = &myaddr;
16324265Ssklower 	int domain = sns->sns_family;
16424265Ssklower 	int retry, s, on = 1;
16524265Ssklower 
16624265Ssklower 	retry = 1;
16724265Ssklower 	while ((s = socket(domain, type, proto)) < 0 && retry) {
16824265Ssklower 		perror("socket");
16924265Ssklower 		sleep(5 * retry);
17024265Ssklower 		retry <<= 1;
17124265Ssklower 	}
17224265Ssklower 	if (retry == 0)
17324265Ssklower 		return (-1);
17424265Ssklower 	while (bind(s, sns, sizeof (*sns), 0) < 0 && retry) {
17524265Ssklower 		perror("bind");
17624265Ssklower 		sleep(5 * retry);
17724265Ssklower 		retry <<= 1;
17824265Ssklower 	}
17924265Ssklower 	if (retry == 0)
18024265Ssklower 		return (-1);
18124265Ssklower 	if (domain==AF_NS) {
18224265Ssklower 		struct idp idp;
18324265Ssklower 		if (setsockopt(s, 0, SO_HEADERS_ON_INPUT, &on, sizeof(on))) {
18424265Ssklower 			perror("setsockopt SEE HEADERS");
18524265Ssklower 			exit(1);
18624265Ssklower 		}
18724265Ssklower 		idp.idp_pt = NSPROTO_RI;
18824265Ssklower 		if (setsockopt(s, 0, SO_DEFAULT_HEADERS, &idp, sizeof(idp))) {
18924265Ssklower 			perror("setsockopt SET HEADERS");
19024265Ssklower 			exit(1);
19124265Ssklower 		}
19224265Ssklower 	}
19324265Ssklower 	if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) {
19424265Ssklower 		perror("setsockopt SO_BROADCAST");
19524265Ssklower 		exit(1);
19624265Ssklower 	}
19724265Ssklower 	return (s);
19824265Ssklower }
199