xref: /csrg-svn/sbin/XNSrouted/tools/query.c (revision 61473)
148127Sbostic /*-
2*61473Sbostic  * Copyright (c) 1983, 1986, 1993
3*61473Sbostic  *	The Regents of the University of California.  All rights reserved.
426177Ssklower  *
548127Sbostic  * This code includes software contributed to Berkeley by
648127Sbostic  * Bill Nesheim at Cornell University.
735547Sbostic  *
848127Sbostic  * %sccs.include.redist.c%
924265Ssklower  */
1024265Ssklower 
1124265Ssklower #ifndef lint
12*61473Sbostic static char copyright[] =
13*61473Sbostic "@(#) Copyright (c) 1983, 1986, 1993\n\
14*61473Sbostic 	The Regents of the University of California.  All rights reserved.\n";
1535547Sbostic #endif /* not lint */
1624265Ssklower 
1724326Ssklower #ifndef lint
18*61473Sbostic static char sccsid[] = "@(#)query.c	8.1 (Berkeley) 06/05/93";
1935547Sbostic #endif /* not lint */
2024326Ssklower 
2124265Ssklower #include <sys/param.h>
2224265Ssklower #include <sys/protosw.h>
2324265Ssklower #include <sys/socket.h>
2424265Ssklower #include <sys/time.h>
2524265Ssklower #include <netinet/in.h>
2624265Ssklower #include <netns/ns.h>
2724265Ssklower #include <netns/idp.h>
2824265Ssklower #include <errno.h>
2924265Ssklower #include <stdio.h>
3024265Ssklower #include <netdb.h>
3124265Ssklower #include "../protocol.h"
3224265Ssklower #define IDPPORT_RIF 1
3324265Ssklower 
3424265Ssklower #define	WTIME	5		/* Time to wait for responses */
3524265Ssklower 
3624265Ssklower int	s;
3724265Ssklower int	timedout, timeout();
3824265Ssklower char	packet[MAXPACKETSIZE];
3924265Ssklower extern int errno;
4045667Ssklower struct sockaddr_ns	myaddr = {sizeof(myaddr), AF_NS};
4130814Sbostic char *ns_ntoa();
4226176Ssklower struct ns_addr ns_addr();
main(argc,argv)4324265Ssklower main(argc, argv)
4424265Ssklower int argc;
4524265Ssklower char *argv[];
4624265Ssklower {
4724265Ssklower 	int cc, count, bits;
4824265Ssklower 	struct sockaddr from;
4924265Ssklower 	int fromlen = sizeof(from);
5024265Ssklower 	struct timeval notime;
5124265Ssklower 
5224265Ssklower 	if (argc < 2) {
5324265Ssklower 		printf("usage: query hosts...\n");
5424265Ssklower 		exit(1);
5524265Ssklower 	}
5624265Ssklower 	s = getsocket(SOCK_DGRAM, 0);
5724265Ssklower 	if (s < 0) {
5824265Ssklower 		perror("socket");
5924265Ssklower 		exit(2);
6024265Ssklower 	}
6124265Ssklower 
6224265Ssklower 	argv++, argc--;
6324326Ssklower 	query(argv,argc);
6424265Ssklower 
6524265Ssklower 	/*
6624265Ssklower 	 * Listen for returning packets;
6724265Ssklower 	 * may be more than one packet per host.
6824265Ssklower 	 */
6924265Ssklower 	bits = 1 << s;
7024265Ssklower 	bzero(&notime, sizeof(notime));
7124265Ssklower 	signal(SIGALRM, timeout);
7224265Ssklower 	alarm(WTIME);
7324326Ssklower 	while (!timedout ||
7424265Ssklower 	    select(20, &bits, 0, 0, &notime) > 0) {
7524265Ssklower 		struct nspacket {
7624265Ssklower 			struct idp hdr;
7724265Ssklower 			char	data[512];
7824265Ssklower 		} response;
7924265Ssklower 		cc = recvfrom(s, &response, sizeof (response), 0,
8024265Ssklower 		  &from, &fromlen);
8124265Ssklower 		if (cc <= 0) {
8224265Ssklower 			if (cc < 0) {
8324265Ssklower 				if (errno == EINTR)
8424265Ssklower 					continue;
8524265Ssklower 				perror("recvfrom");
8624265Ssklower 				(void) close(s);
8724265Ssklower 				exit(1);
8824265Ssklower 			}
8924265Ssklower 			continue;
9024265Ssklower 		}
9124265Ssklower 		rip_input(&from, response.data, cc);
9224265Ssklower 		count--;
9324265Ssklower 	}
9424265Ssklower }
9545667Ssklower static struct sockaddr_ns router = {sizeof(myaddr), AF_NS};
9626176Ssklower static struct ns_addr zero_addr;
9726176Ssklower static short allones[] = {-1, -1, -1};
9824265Ssklower 
query(argv,argc)9924326Ssklower query(argv,argc)
10024326Ssklower char **argv;
10124265Ssklower {
10224265Ssklower 	register struct rip *msg = (struct rip *)packet;
10324326Ssklower 	char *host = *argv;
10445667Ssklower 	int flags = 0;
10526176Ssklower 	struct ns_addr specific;
10624265Ssklower 
10745667Ssklower 	if (bcmp(*argv, "-r", 3) == 0) {
10845667Ssklower 		flags = MSG_DONTROUTE; argv++; argc--;
10945667Ssklower 	}
11045667Ssklower 	host = *argv;
11126176Ssklower 	router.sns_addr = ns_addr(host);
11224265Ssklower 	router.sns_addr.x_port = htons(IDPPORT_RIF);
11326176Ssklower 	if (ns_hosteq(zero_addr, router.sns_addr)) {
11426176Ssklower 		router.sns_addr.x_host = *(union ns_host *) allones;
11526176Ssklower 	}
11624265Ssklower 	msg->rip_cmd = htons(RIPCMD_REQUEST);
11726176Ssklower 	msg->rip_nets[0].rip_dst = *(union ns_net *) allones;
11824265Ssklower 	msg->rip_nets[0].rip_metric = htons(HOPCNT_INFINITY);
11924326Ssklower 	if (argc > 0) {
12026176Ssklower 		specific = ns_addr(*argv);
12126176Ssklower 		msg->rip_nets[0].rip_dst = specific.x_net;
12226176Ssklower 		specific.x_host = zero_addr.x_host;
12326176Ssklower 		specific.x_port = zero_addr.x_port;
12426176Ssklower 		printf("Net asked for was %s\n", ns_ntoa(specific));
12524326Ssklower 	}
12645667Ssklower 	if (sendto(s, packet, sizeof (struct rip), flags,
12724265Ssklower 	  &router, sizeof(router)) < 0)
12824265Ssklower 		perror(host);
12924265Ssklower }
13024265Ssklower 
13124265Ssklower /*
13224265Ssklower  * Handle an incoming routing packet.
13324265Ssklower  */
13424265Ssklower rip_input(from, msg,  size)
13524265Ssklower 	struct sockaddr_ns *from;
13624265Ssklower 	register struct rip *msg;
13724265Ssklower 	int size;
13824265Ssklower {
13924265Ssklower 	struct netinfo *n;
14024265Ssklower 	char *name;
14124265Ssklower 	int lna, net, subnet;
14224265Ssklower 	struct hostent *hp;
14324265Ssklower 	struct netent *np;
14426176Ssklower 	static struct ns_addr work;
14524265Ssklower 
14624265Ssklower 	if (htons(msg->rip_cmd) != RIPCMD_RESPONSE)
14724265Ssklower 		return;
14826176Ssklower 	printf("from %s\n", ns_ntoa(from->sns_addr));
14924265Ssklower 	size -= sizeof (struct idp);
15024265Ssklower 	size -= sizeof (short);
15124265Ssklower 	n = msg->rip_nets;
15224265Ssklower 	while (size > 0) {
15326176Ssklower 		union ns_net_u net;
15424265Ssklower 		if (size < sizeof (struct netinfo))
15524265Ssklower 			break;
15626176Ssklower 		net.net_e = n->rip_dst;
15726176Ssklower 		printf("\t%d, metric %d\n", ntohl(net.long_e),
15824265Ssklower 			ntohs(n->rip_metric));
15924265Ssklower 		size -= sizeof (struct netinfo), n++;
16024265Ssklower 	}
16124265Ssklower }
16224265Ssklower 
timeout()16324265Ssklower timeout()
16424265Ssklower {
16524265Ssklower 	timedout = 1;
16624265Ssklower }
getsocket(type,proto)16724265Ssklower getsocket(type, proto)
16824265Ssklower 	int type, proto;
16924265Ssklower {
17024265Ssklower 	struct sockaddr_ns *sns = &myaddr;
17124265Ssklower 	int domain = sns->sns_family;
17224265Ssklower 	int retry, s, on = 1;
17324265Ssklower 
17424265Ssklower 	retry = 1;
17524265Ssklower 	while ((s = socket(domain, type, proto)) < 0 && retry) {
17624265Ssklower 		perror("socket");
17724265Ssklower 		sleep(5 * retry);
17824265Ssklower 		retry <<= 1;
17924265Ssklower 	}
18024265Ssklower 	if (retry == 0)
18124265Ssklower 		return (-1);
18224265Ssklower 	while (bind(s, sns, sizeof (*sns), 0) < 0 && retry) {
18324265Ssklower 		perror("bind");
18424265Ssklower 		sleep(5 * retry);
18524265Ssklower 		retry <<= 1;
18624265Ssklower 	}
18724265Ssklower 	if (retry == 0)
18824265Ssklower 		return (-1);
18924265Ssklower 	if (domain==AF_NS) {
19024265Ssklower 		struct idp idp;
19124265Ssklower 		if (setsockopt(s, 0, SO_HEADERS_ON_INPUT, &on, sizeof(on))) {
19224265Ssklower 			perror("setsockopt SEE HEADERS");
19324265Ssklower 			exit(1);
19424265Ssklower 		}
19524265Ssklower 		idp.idp_pt = NSPROTO_RI;
19624265Ssklower 		if (setsockopt(s, 0, SO_DEFAULT_HEADERS, &idp, sizeof(idp))) {
19724265Ssklower 			perror("setsockopt SET HEADERS");
19824265Ssklower 			exit(1);
19924265Ssklower 		}
20024265Ssklower 	}
20124265Ssklower 	if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) {
20224265Ssklower 		perror("setsockopt SO_BROADCAST");
20324265Ssklower 		exit(1);
20424265Ssklower 	}
20524265Ssklower 	return (s);
20624265Ssklower }
207