xref: /csrg-svn/sbin/XNSrouted/tools/query.c (revision 24326)
124265Ssklower /*
2*24326Ssklower  * 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
8*24326Ssklower char copyright[] =
9*24326Ssklower "@(#) Copyright (c) 1983 Regents of the University of California.\n\
10*24326Ssklower  All rights reserved.\n";
1124265Ssklower #endif not lint
1224265Ssklower 
13*24326Ssklower #ifndef lint
14*24326Ssklower static char sccsid[] = "@(#)query.c	5.2 (Berkeley) 08/16/85";
15*24326Ssklower #endif not lint
16*24326Ssklower 
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 #define xnnet(p)	(*(long *)&(p))
3024265Ssklower 
3124265Ssklower #define	WTIME	5		/* Time to wait for responses */
3224265Ssklower 
3324265Ssklower int	s;
3424265Ssklower int	timedout, timeout();
3524265Ssklower char	packet[MAXPACKETSIZE];
3624265Ssklower extern int errno;
3724265Ssklower struct sockaddr_ns	myaddr = {AF_NS};
3824265Ssklower main(argc, argv)
3924265Ssklower int argc;
4024265Ssklower char *argv[];
4124265Ssklower {
4224265Ssklower 	int cc, count, bits;
4324265Ssklower 	struct sockaddr from;
4424265Ssklower 	int fromlen = sizeof(from);
4524265Ssklower 	struct timeval notime;
4624265Ssklower 
4724265Ssklower 	if (argc < 2) {
4824265Ssklower 		printf("usage: query hosts...\n");
4924265Ssklower 		exit(1);
5024265Ssklower 	}
5124265Ssklower 	s = getsocket(SOCK_DGRAM, 0);
5224265Ssklower 	if (s < 0) {
5324265Ssklower 		perror("socket");
5424265Ssklower 		exit(2);
5524265Ssklower 	}
5624265Ssklower 
5724265Ssklower 	argv++, argc--;
58*24326Ssklower 	query(argv,argc);
5924265Ssklower 
6024265Ssklower 	/*
6124265Ssklower 	 * Listen for returning packets;
6224265Ssklower 	 * may be more than one packet per host.
6324265Ssklower 	 */
6424265Ssklower 	bits = 1 << s;
6524265Ssklower 	bzero(&notime, sizeof(notime));
6624265Ssklower 	signal(SIGALRM, timeout);
6724265Ssklower 	alarm(WTIME);
68*24326Ssklower 	while (!timedout ||
6924265Ssklower 	    select(20, &bits, 0, 0, &notime) > 0) {
7024265Ssklower 		struct nspacket {
7124265Ssklower 			struct idp hdr;
7224265Ssklower 			char	data[512];
7324265Ssklower 		} response;
7424265Ssklower 		cc = recvfrom(s, &response, sizeof (response), 0,
7524265Ssklower 		  &from, &fromlen);
7624265Ssklower 		if (cc <= 0) {
7724265Ssklower 			if (cc < 0) {
7824265Ssklower 				if (errno == EINTR)
7924265Ssklower 					continue;
8024265Ssklower 				perror("recvfrom");
8124265Ssklower 				(void) close(s);
8224265Ssklower 				exit(1);
8324265Ssklower 			}
8424265Ssklower 			continue;
8524265Ssklower 		}
8624265Ssklower 		rip_input(&from, response.data, cc);
8724265Ssklower 		count--;
8824265Ssklower 	}
8924265Ssklower }
9024265Ssklower 
91*24326Ssklower query(argv,argc)
92*24326Ssklower char **argv;
9324265Ssklower {
9424265Ssklower 	struct sockaddr_ns router;
9524265Ssklower 	register struct rip *msg = (struct rip *)packet;
9624265Ssklower 	long mynet;
9724265Ssklower 	short work[3];
98*24326Ssklower 	char *host = *argv;
9924265Ssklower 
100*24326Ssklower 	argv++; argc--;
10124265Ssklower 	bzero((char *)&router, sizeof (router));
10224265Ssklower 	router.sns_family = AF_NS;
10324265Ssklower 	router.sns_addr.x_port = htons(IDPPORT_RIF);
10424265Ssklower 	sscanf(host, "%ld:%hx,%hx,%hx",
10524265Ssklower 			&mynet,work+0, work+1, work+2);
10624265Ssklower 	router.sns_addr.x_host  = *(union ns_host *)work;
10724265Ssklower 	xnnet(router.sns_addr.x_net) =  htonl(mynet);
10824265Ssklower 	msg->rip_cmd = htons(RIPCMD_REQUEST);
10924265Ssklower 	xnnet(msg->rip_nets[0]) = -1;
11024265Ssklower 	msg->rip_nets[0].rip_metric = htons(HOPCNT_INFINITY);
111*24326Ssklower 	if (argc > 0) {
112*24326Ssklower 		u_long wanted = xnnet(msg->rip_nets[0]) = htonl(atoi(*argv));
113*24326Ssklower 		printf("Net asked for was %d\n", ntohl(wanted));
114*24326Ssklower 	}
11524265Ssklower 	if (sendto(s, packet, sizeof (struct rip), 0,
11624265Ssklower 	  &router, sizeof(router)) < 0)
11724265Ssklower 		perror(host);
11824265Ssklower }
11924265Ssklower 
12024265Ssklower /*
12124265Ssklower  * Handle an incoming routing packet.
12224265Ssklower  */
12324265Ssklower rip_input(from, msg,  size)
12424265Ssklower 	struct sockaddr_ns *from;
12524265Ssklower 	register struct rip *msg;
12624265Ssklower 	int size;
12724265Ssklower {
12824265Ssklower 	struct netinfo *n;
12924265Ssklower 	char *name;
13024265Ssklower 	int lna, net, subnet;
13124265Ssklower 	struct hostent *hp;
13224265Ssklower 	struct netent *np;
13324265Ssklower 
13424265Ssklower 	if (htons(msg->rip_cmd) != RIPCMD_RESPONSE)
13524265Ssklower 		return;
13624265Ssklower 	printf("from %d:%x,%x,%x\n",
13724265Ssklower 		ntohl(xnnet(from->sns_addr.x_net)),
13824265Ssklower 		from->sns_addr.x_host.s_host[0],
13924265Ssklower 		from->sns_addr.x_host.s_host[1],
14024265Ssklower 		from->sns_addr.x_host.s_host[2]);
14124265Ssklower 	size -= sizeof (struct idp);
14224265Ssklower 	size -= sizeof (short);
14324265Ssklower 	n = msg->rip_nets;
14424265Ssklower 	while (size > 0) {
14524265Ssklower 		if (size < sizeof (struct netinfo))
14624265Ssklower 			break;
14724265Ssklower 		printf("\t%d, metric %d\n", ntohl(xnnet(n->rip_dst[0])),
14824265Ssklower 			ntohs(n->rip_metric));
14924265Ssklower 		size -= sizeof (struct netinfo), n++;
15024265Ssklower 	}
15124265Ssklower }
15224265Ssklower 
15324265Ssklower timeout()
15424265Ssklower {
15524265Ssklower 	timedout = 1;
15624265Ssklower }
15724265Ssklower getsocket(type, proto)
15824265Ssklower 	int type, proto;
15924265Ssklower {
16024265Ssklower 	struct sockaddr_ns *sns = &myaddr;
16124265Ssklower 	int domain = sns->sns_family;
16224265Ssklower 	int retry, s, on = 1;
16324265Ssklower 
16424265Ssklower 	retry = 1;
16524265Ssklower 	while ((s = socket(domain, type, proto)) < 0 && retry) {
16624265Ssklower 		perror("socket");
16724265Ssklower 		sleep(5 * retry);
16824265Ssklower 		retry <<= 1;
16924265Ssklower 	}
17024265Ssklower 	if (retry == 0)
17124265Ssklower 		return (-1);
17224265Ssklower 	while (bind(s, sns, sizeof (*sns), 0) < 0 && retry) {
17324265Ssklower 		perror("bind");
17424265Ssklower 		sleep(5 * retry);
17524265Ssklower 		retry <<= 1;
17624265Ssklower 	}
17724265Ssklower 	if (retry == 0)
17824265Ssklower 		return (-1);
17924265Ssklower 	if (domain==AF_NS) {
18024265Ssklower 		struct idp idp;
18124265Ssklower 		if (setsockopt(s, 0, SO_HEADERS_ON_INPUT, &on, sizeof(on))) {
18224265Ssklower 			perror("setsockopt SEE HEADERS");
18324265Ssklower 			exit(1);
18424265Ssklower 		}
18524265Ssklower 		idp.idp_pt = NSPROTO_RI;
18624265Ssklower 		if (setsockopt(s, 0, SO_DEFAULT_HEADERS, &idp, sizeof(idp))) {
18724265Ssklower 			perror("setsockopt SET HEADERS");
18824265Ssklower 			exit(1);
18924265Ssklower 		}
19024265Ssklower 	}
19124265Ssklower 	if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) {
19224265Ssklower 		perror("setsockopt SO_BROADCAST");
19324265Ssklower 		exit(1);
19424265Ssklower 	}
19524265Ssklower 	return (s);
19624265Ssklower }
197