xref: /csrg-svn/sbin/XNSrouted/tools/query.c (revision 30814)
124265Ssklower /*
226177Ssklower  * Copyright (c) 1983, 1986 Regents of the University of California.
324265Ssklower  * All rights reserved.  The Berkeley software License Agreement
424265Ssklower  * specifies the terms and conditions for redistribution.
526177Ssklower  *
626177Ssklower  * This file include significant work done at Cornell University
726177Ssklower  * by Bill Nesheim.  That work included by permission.
824265Ssklower  */
924265Ssklower 
1024265Ssklower #ifndef lint
1124326Ssklower char copyright[] =
1226177Ssklower "@(#) Copyright (c) 1983, 1986 Regents of the University of California.\n\
1324326Ssklower  All rights reserved.\n";
1424265Ssklower #endif not lint
1524265Ssklower 
1624326Ssklower #ifndef lint
17*30814Sbostic static char sccsid[] = "@(#)query.c	5.5 (Berkeley) 04/06/87";
1824326Ssklower #endif not lint
1924326Ssklower 
2024265Ssklower #include <sys/param.h>
2124265Ssklower #include <sys/protosw.h>
2224265Ssklower #include <sys/socket.h>
2324265Ssklower #include <sys/time.h>
2424265Ssklower #include <netinet/in.h>
2524265Ssklower #include <netns/ns.h>
2624265Ssklower #include <netns/idp.h>
2724265Ssklower #include <errno.h>
2824265Ssklower #include <stdio.h>
2924265Ssklower #include <netdb.h>
3024265Ssklower #include "../protocol.h"
3124265Ssklower #define IDPPORT_RIF 1
3224265Ssklower 
3324265Ssklower #define	WTIME	5		/* Time to wait for responses */
3424265Ssklower 
3524265Ssklower int	s;
3624265Ssklower int	timedout, timeout();
3724265Ssklower char	packet[MAXPACKETSIZE];
3824265Ssklower extern int errno;
3924265Ssklower struct sockaddr_ns	myaddr = {AF_NS};
40*30814Sbostic char *ns_ntoa();
4126176Ssklower struct ns_addr ns_addr();
4224265Ssklower main(argc, argv)
4324265Ssklower int argc;
4424265Ssklower char *argv[];
4524265Ssklower {
4624265Ssklower 	int cc, count, bits;
4724265Ssklower 	struct sockaddr from;
4824265Ssklower 	int fromlen = sizeof(from);
4924265Ssklower 	struct timeval notime;
5024265Ssklower 
5124265Ssklower 	if (argc < 2) {
5224265Ssklower 		printf("usage: query hosts...\n");
5324265Ssklower 		exit(1);
5424265Ssklower 	}
5524265Ssklower 	s = getsocket(SOCK_DGRAM, 0);
5624265Ssklower 	if (s < 0) {
5724265Ssklower 		perror("socket");
5824265Ssklower 		exit(2);
5924265Ssklower 	}
6024265Ssklower 
6124265Ssklower 	argv++, argc--;
6224326Ssklower 	query(argv,argc);
6324265Ssklower 
6424265Ssklower 	/*
6524265Ssklower 	 * Listen for returning packets;
6624265Ssklower 	 * may be more than one packet per host.
6724265Ssklower 	 */
6824265Ssklower 	bits = 1 << s;
6924265Ssklower 	bzero(&notime, sizeof(notime));
7024265Ssklower 	signal(SIGALRM, timeout);
7124265Ssklower 	alarm(WTIME);
7224326Ssklower 	while (!timedout ||
7324265Ssklower 	    select(20, &bits, 0, 0, &notime) > 0) {
7424265Ssklower 		struct nspacket {
7524265Ssklower 			struct idp hdr;
7624265Ssklower 			char	data[512];
7724265Ssklower 		} response;
7824265Ssklower 		cc = recvfrom(s, &response, sizeof (response), 0,
7924265Ssklower 		  &from, &fromlen);
8024265Ssklower 		if (cc <= 0) {
8124265Ssklower 			if (cc < 0) {
8224265Ssklower 				if (errno == EINTR)
8324265Ssklower 					continue;
8424265Ssklower 				perror("recvfrom");
8524265Ssklower 				(void) close(s);
8624265Ssklower 				exit(1);
8724265Ssklower 			}
8824265Ssklower 			continue;
8924265Ssklower 		}
9024265Ssklower 		rip_input(&from, response.data, cc);
9124265Ssklower 		count--;
9224265Ssklower 	}
9324265Ssklower }
9426176Ssklower static struct sockaddr_ns router = {AF_NS};
9526176Ssklower static struct ns_addr zero_addr;
9626176Ssklower static short allones[] = {-1, -1, -1};
9724265Ssklower 
9824326Ssklower query(argv,argc)
9924326Ssklower char **argv;
10024265Ssklower {
10124265Ssklower 	register struct rip *msg = (struct rip *)packet;
10224326Ssklower 	char *host = *argv;
10326176Ssklower 	struct ns_addr specific;
10424265Ssklower 
10524326Ssklower 	argv++; argc--;
10626176Ssklower 	router.sns_addr = ns_addr(host);
10724265Ssklower 	router.sns_addr.x_port = htons(IDPPORT_RIF);
10826176Ssklower 	if (ns_hosteq(zero_addr, router.sns_addr)) {
10926176Ssklower 		router.sns_addr.x_host = *(union ns_host *) allones;
11026176Ssklower 	}
11124265Ssklower 	msg->rip_cmd = htons(RIPCMD_REQUEST);
11226176Ssklower 	msg->rip_nets[0].rip_dst = *(union ns_net *) allones;
11324265Ssklower 	msg->rip_nets[0].rip_metric = htons(HOPCNT_INFINITY);
11424326Ssklower 	if (argc > 0) {
11526176Ssklower 		specific = ns_addr(*argv);
11626176Ssklower 		msg->rip_nets[0].rip_dst = specific.x_net;
11726176Ssklower 		specific.x_host = zero_addr.x_host;
11826176Ssklower 		specific.x_port = zero_addr.x_port;
11926176Ssklower 		printf("Net asked for was %s\n", ns_ntoa(specific));
12024326Ssklower 	}
12124265Ssklower 	if (sendto(s, packet, sizeof (struct rip), 0,
12224265Ssklower 	  &router, sizeof(router)) < 0)
12324265Ssklower 		perror(host);
12424265Ssklower }
12524265Ssklower 
12624265Ssklower /*
12724265Ssklower  * Handle an incoming routing packet.
12824265Ssklower  */
12924265Ssklower rip_input(from, msg,  size)
13024265Ssklower 	struct sockaddr_ns *from;
13124265Ssklower 	register struct rip *msg;
13224265Ssklower 	int size;
13324265Ssklower {
13424265Ssklower 	struct netinfo *n;
13524265Ssklower 	char *name;
13624265Ssklower 	int lna, net, subnet;
13724265Ssklower 	struct hostent *hp;
13824265Ssklower 	struct netent *np;
13926176Ssklower 	static struct ns_addr work;
14024265Ssklower 
14124265Ssklower 	if (htons(msg->rip_cmd) != RIPCMD_RESPONSE)
14224265Ssklower 		return;
14326176Ssklower 	printf("from %s\n", ns_ntoa(from->sns_addr));
14424265Ssklower 	size -= sizeof (struct idp);
14524265Ssklower 	size -= sizeof (short);
14624265Ssklower 	n = msg->rip_nets;
14724265Ssklower 	while (size > 0) {
14826176Ssklower 		union ns_net_u net;
14924265Ssklower 		if (size < sizeof (struct netinfo))
15024265Ssklower 			break;
15126176Ssklower 		net.net_e = n->rip_dst;
15226176Ssklower 		printf("\t%d, metric %d\n", ntohl(net.long_e),
15324265Ssklower 			ntohs(n->rip_metric));
15424265Ssklower 		size -= sizeof (struct netinfo), n++;
15524265Ssklower 	}
15624265Ssklower }
15724265Ssklower 
15824265Ssklower timeout()
15924265Ssklower {
16024265Ssklower 	timedout = 1;
16124265Ssklower }
16224265Ssklower getsocket(type, proto)
16324265Ssklower 	int type, proto;
16424265Ssklower {
16524265Ssklower 	struct sockaddr_ns *sns = &myaddr;
16624265Ssklower 	int domain = sns->sns_family;
16724265Ssklower 	int retry, s, on = 1;
16824265Ssklower 
16924265Ssklower 	retry = 1;
17024265Ssklower 	while ((s = socket(domain, type, proto)) < 0 && retry) {
17124265Ssklower 		perror("socket");
17224265Ssklower 		sleep(5 * retry);
17324265Ssklower 		retry <<= 1;
17424265Ssklower 	}
17524265Ssklower 	if (retry == 0)
17624265Ssklower 		return (-1);
17724265Ssklower 	while (bind(s, sns, sizeof (*sns), 0) < 0 && retry) {
17824265Ssklower 		perror("bind");
17924265Ssklower 		sleep(5 * retry);
18024265Ssklower 		retry <<= 1;
18124265Ssklower 	}
18224265Ssklower 	if (retry == 0)
18324265Ssklower 		return (-1);
18424265Ssklower 	if (domain==AF_NS) {
18524265Ssklower 		struct idp idp;
18624265Ssklower 		if (setsockopt(s, 0, SO_HEADERS_ON_INPUT, &on, sizeof(on))) {
18724265Ssklower 			perror("setsockopt SEE HEADERS");
18824265Ssklower 			exit(1);
18924265Ssklower 		}
19024265Ssklower 		idp.idp_pt = NSPROTO_RI;
19124265Ssklower 		if (setsockopt(s, 0, SO_DEFAULT_HEADERS, &idp, sizeof(idp))) {
19224265Ssklower 			perror("setsockopt SET HEADERS");
19324265Ssklower 			exit(1);
19424265Ssklower 		}
19524265Ssklower 	}
19624265Ssklower 	if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) {
19724265Ssklower 		perror("setsockopt SO_BROADCAST");
19824265Ssklower 		exit(1);
19924265Ssklower 	}
20024265Ssklower 	return (s);
20124265Ssklower }
202