xref: /csrg-svn/sbin/XNSrouted/tools/query.c (revision 35547)
124265Ssklower /*
2*35547Sbostic  * Copyright (c) 1983, 1986 The Regents of the University of California.
3*35547Sbostic  * All rights reserved.
426177Ssklower  *
5*35547Sbostic  * This file includes significant work done at Cornell University by
6*35547Sbostic  * Bill Nesheim.  That work included by permission.
7*35547Sbostic  *
8*35547Sbostic  * Redistribution and use in source and binary forms are permitted
9*35547Sbostic  * provided that the above copyright notice and this paragraph are
10*35547Sbostic  * duplicated in all such forms and that any documentation,
11*35547Sbostic  * advertising materials, and other materials related to such
12*35547Sbostic  * distribution and use acknowledge that the software was developed
13*35547Sbostic  * by the University of California, Berkeley.  The name of the
14*35547Sbostic  * University may not be used to endorse or promote products derived
15*35547Sbostic  * from this software without specific prior written permission.
16*35547Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17*35547Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18*35547Sbostic  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1924265Ssklower  */
2024265Ssklower 
2124265Ssklower #ifndef lint
2224326Ssklower char copyright[] =
23*35547Sbostic "@(#) Copyright (c) 1983, 1986 The Regents of the University of California.\n\
2424326Ssklower  All rights reserved.\n";
25*35547Sbostic #endif /* not lint */
2624265Ssklower 
2724326Ssklower #ifndef lint
28*35547Sbostic static char sccsid[] = "@(#)query.c	5.6 (Berkeley) 09/19/88";
29*35547Sbostic #endif /* not lint */
3024326Ssklower 
3124265Ssklower #include <sys/param.h>
3224265Ssklower #include <sys/protosw.h>
3324265Ssklower #include <sys/socket.h>
3424265Ssklower #include <sys/time.h>
3524265Ssklower #include <netinet/in.h>
3624265Ssklower #include <netns/ns.h>
3724265Ssklower #include <netns/idp.h>
3824265Ssklower #include <errno.h>
3924265Ssklower #include <stdio.h>
4024265Ssklower #include <netdb.h>
4124265Ssklower #include "../protocol.h"
4224265Ssklower #define IDPPORT_RIF 1
4324265Ssklower 
4424265Ssklower #define	WTIME	5		/* Time to wait for responses */
4524265Ssklower 
4624265Ssklower int	s;
4724265Ssklower int	timedout, timeout();
4824265Ssklower char	packet[MAXPACKETSIZE];
4924265Ssklower extern int errno;
5024265Ssklower struct sockaddr_ns	myaddr = {AF_NS};
5130814Sbostic char *ns_ntoa();
5226176Ssklower struct ns_addr ns_addr();
5324265Ssklower main(argc, argv)
5424265Ssklower int argc;
5524265Ssklower char *argv[];
5624265Ssklower {
5724265Ssklower 	int cc, count, bits;
5824265Ssklower 	struct sockaddr from;
5924265Ssklower 	int fromlen = sizeof(from);
6024265Ssklower 	struct timeval notime;
6124265Ssklower 
6224265Ssklower 	if (argc < 2) {
6324265Ssklower 		printf("usage: query hosts...\n");
6424265Ssklower 		exit(1);
6524265Ssklower 	}
6624265Ssklower 	s = getsocket(SOCK_DGRAM, 0);
6724265Ssklower 	if (s < 0) {
6824265Ssklower 		perror("socket");
6924265Ssklower 		exit(2);
7024265Ssklower 	}
7124265Ssklower 
7224265Ssklower 	argv++, argc--;
7324326Ssklower 	query(argv,argc);
7424265Ssklower 
7524265Ssklower 	/*
7624265Ssklower 	 * Listen for returning packets;
7724265Ssklower 	 * may be more than one packet per host.
7824265Ssklower 	 */
7924265Ssklower 	bits = 1 << s;
8024265Ssklower 	bzero(&notime, sizeof(notime));
8124265Ssklower 	signal(SIGALRM, timeout);
8224265Ssklower 	alarm(WTIME);
8324326Ssklower 	while (!timedout ||
8424265Ssklower 	    select(20, &bits, 0, 0, &notime) > 0) {
8524265Ssklower 		struct nspacket {
8624265Ssklower 			struct idp hdr;
8724265Ssklower 			char	data[512];
8824265Ssklower 		} response;
8924265Ssklower 		cc = recvfrom(s, &response, sizeof (response), 0,
9024265Ssklower 		  &from, &fromlen);
9124265Ssklower 		if (cc <= 0) {
9224265Ssklower 			if (cc < 0) {
9324265Ssklower 				if (errno == EINTR)
9424265Ssklower 					continue;
9524265Ssklower 				perror("recvfrom");
9624265Ssklower 				(void) close(s);
9724265Ssklower 				exit(1);
9824265Ssklower 			}
9924265Ssklower 			continue;
10024265Ssklower 		}
10124265Ssklower 		rip_input(&from, response.data, cc);
10224265Ssklower 		count--;
10324265Ssklower 	}
10424265Ssklower }
10526176Ssklower static struct sockaddr_ns router = {AF_NS};
10626176Ssklower static struct ns_addr zero_addr;
10726176Ssklower static short allones[] = {-1, -1, -1};
10824265Ssklower 
10924326Ssklower query(argv,argc)
11024326Ssklower char **argv;
11124265Ssklower {
11224265Ssklower 	register struct rip *msg = (struct rip *)packet;
11324326Ssklower 	char *host = *argv;
11426176Ssklower 	struct ns_addr specific;
11524265Ssklower 
11624326Ssklower 	argv++; argc--;
11726176Ssklower 	router.sns_addr = ns_addr(host);
11824265Ssklower 	router.sns_addr.x_port = htons(IDPPORT_RIF);
11926176Ssklower 	if (ns_hosteq(zero_addr, router.sns_addr)) {
12026176Ssklower 		router.sns_addr.x_host = *(union ns_host *) allones;
12126176Ssklower 	}
12224265Ssklower 	msg->rip_cmd = htons(RIPCMD_REQUEST);
12326176Ssklower 	msg->rip_nets[0].rip_dst = *(union ns_net *) allones;
12424265Ssklower 	msg->rip_nets[0].rip_metric = htons(HOPCNT_INFINITY);
12524326Ssklower 	if (argc > 0) {
12626176Ssklower 		specific = ns_addr(*argv);
12726176Ssklower 		msg->rip_nets[0].rip_dst = specific.x_net;
12826176Ssklower 		specific.x_host = zero_addr.x_host;
12926176Ssklower 		specific.x_port = zero_addr.x_port;
13026176Ssklower 		printf("Net asked for was %s\n", ns_ntoa(specific));
13124326Ssklower 	}
13224265Ssklower 	if (sendto(s, packet, sizeof (struct rip), 0,
13324265Ssklower 	  &router, sizeof(router)) < 0)
13424265Ssklower 		perror(host);
13524265Ssklower }
13624265Ssklower 
13724265Ssklower /*
13824265Ssklower  * Handle an incoming routing packet.
13924265Ssklower  */
14024265Ssklower rip_input(from, msg,  size)
14124265Ssklower 	struct sockaddr_ns *from;
14224265Ssklower 	register struct rip *msg;
14324265Ssklower 	int size;
14424265Ssklower {
14524265Ssklower 	struct netinfo *n;
14624265Ssklower 	char *name;
14724265Ssklower 	int lna, net, subnet;
14824265Ssklower 	struct hostent *hp;
14924265Ssklower 	struct netent *np;
15026176Ssklower 	static struct ns_addr work;
15124265Ssklower 
15224265Ssklower 	if (htons(msg->rip_cmd) != RIPCMD_RESPONSE)
15324265Ssklower 		return;
15426176Ssklower 	printf("from %s\n", ns_ntoa(from->sns_addr));
15524265Ssklower 	size -= sizeof (struct idp);
15624265Ssklower 	size -= sizeof (short);
15724265Ssklower 	n = msg->rip_nets;
15824265Ssklower 	while (size > 0) {
15926176Ssklower 		union ns_net_u net;
16024265Ssklower 		if (size < sizeof (struct netinfo))
16124265Ssklower 			break;
16226176Ssklower 		net.net_e = n->rip_dst;
16326176Ssklower 		printf("\t%d, metric %d\n", ntohl(net.long_e),
16424265Ssklower 			ntohs(n->rip_metric));
16524265Ssklower 		size -= sizeof (struct netinfo), n++;
16624265Ssklower 	}
16724265Ssklower }
16824265Ssklower 
16924265Ssklower timeout()
17024265Ssklower {
17124265Ssklower 	timedout = 1;
17224265Ssklower }
17324265Ssklower getsocket(type, proto)
17424265Ssklower 	int type, proto;
17524265Ssklower {
17624265Ssklower 	struct sockaddr_ns *sns = &myaddr;
17724265Ssklower 	int domain = sns->sns_family;
17824265Ssklower 	int retry, s, on = 1;
17924265Ssklower 
18024265Ssklower 	retry = 1;
18124265Ssklower 	while ((s = socket(domain, type, proto)) < 0 && retry) {
18224265Ssklower 		perror("socket");
18324265Ssklower 		sleep(5 * retry);
18424265Ssklower 		retry <<= 1;
18524265Ssklower 	}
18624265Ssklower 	if (retry == 0)
18724265Ssklower 		return (-1);
18824265Ssklower 	while (bind(s, sns, sizeof (*sns), 0) < 0 && retry) {
18924265Ssklower 		perror("bind");
19024265Ssklower 		sleep(5 * retry);
19124265Ssklower 		retry <<= 1;
19224265Ssklower 	}
19324265Ssklower 	if (retry == 0)
19424265Ssklower 		return (-1);
19524265Ssklower 	if (domain==AF_NS) {
19624265Ssklower 		struct idp idp;
19724265Ssklower 		if (setsockopt(s, 0, SO_HEADERS_ON_INPUT, &on, sizeof(on))) {
19824265Ssklower 			perror("setsockopt SEE HEADERS");
19924265Ssklower 			exit(1);
20024265Ssklower 		}
20124265Ssklower 		idp.idp_pt = NSPROTO_RI;
20224265Ssklower 		if (setsockopt(s, 0, SO_DEFAULT_HEADERS, &idp, sizeof(idp))) {
20324265Ssklower 			perror("setsockopt SET HEADERS");
20424265Ssklower 			exit(1);
20524265Ssklower 		}
20624265Ssklower 	}
20724265Ssklower 	if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) {
20824265Ssklower 		perror("setsockopt SO_BROADCAST");
20924265Ssklower 		exit(1);
21024265Ssklower 	}
21124265Ssklower 	return (s);
21224265Ssklower }
213