xref: /csrg-svn/sbin/routed/query/query.c (revision 26146)
122643Sdist /*
222643Sdist  * Copyright (c) 1980 Regents of the University of California.
322643Sdist  * All rights reserved.  The Berkeley software License Agreement
422643Sdist  * specifies the terms and conditions for redistribution.
522643Sdist  */
622643Sdist 
76918Ssam #ifndef lint
8*26146Skarels static char sccsid[] = "@(#)query.c	5.3 (Berkeley) 02/12/86";
922643Sdist #endif not lint
106918Ssam 
116918Ssam #include <sys/param.h>
126918Ssam #include <sys/protosw.h>
136918Ssam #include <sys/socket.h>
1415760Skarels #include <sys/time.h>
1515760Skarels #include <netinet/in.h>
166918Ssam #include <errno.h>
176918Ssam #include <stdio.h>
188339Ssam #include <netdb.h>
1925382Skarels #include <protocols/routed.h>
206918Ssam 
2115760Skarels #define	WTIME	5		/* Time to wait for responses */
2215760Skarels 
236918Ssam int	s;
2422547Skarels int	timedout, timeout();
256918Ssam char	packet[MAXPACKETSIZE];
2622547Skarels extern int errno;
27*26146Skarels int	nflag;
286918Ssam 
296918Ssam main(argc, argv)
306918Ssam 	int argc;
316918Ssam 	char *argv[];
326918Ssam {
3315760Skarels 	int cc, count, bits;
346918Ssam 	struct sockaddr from;
3515760Skarels 	int fromlen = sizeof(from);
3615760Skarels 	struct timeval notime;
376918Ssam 
386918Ssam 	if (argc < 2) {
39*26146Skarels usage:
40*26146Skarels 		printf("usage: query [ -n ] hosts...\n");
416918Ssam 		exit(1);
426918Ssam 	}
4315760Skarels 	s = socket(AF_INET, SOCK_DGRAM, 0);
446918Ssam 	if (s < 0) {
456918Ssam 		perror("socket");
466918Ssam 		exit(2);
476918Ssam 	}
4815760Skarels 
496918Ssam 	argv++, argc--;
50*26146Skarels 	if (*argv[0] == '-') {
51*26146Skarels 		switch (*argv[1]) {
52*26146Skarels 		case 'n':
53*26146Skarels 			nflag++;
54*26146Skarels 			break;
55*26146Skarels 		default:
56*26146Skarels 			goto usage;
57*26146Skarels 		}
58*26146Skarels 		argc--, argv++;
59*26146Skarels 	}
606918Ssam 	count = argc;
616918Ssam 	while (argc > 0) {
626918Ssam 		query(*argv);
636918Ssam 		argv++, argc--;
646918Ssam 	}
656918Ssam 
666918Ssam 	/*
6715760Skarels 	 * Listen for returning packets;
6815760Skarels 	 * may be more than one packet per host.
696918Ssam 	 */
7015760Skarels 	bits = 1 << s;
7115760Skarels 	bzero(&notime, sizeof(notime));
7222547Skarels 	signal(SIGALRM, timeout);
7322547Skarels 	alarm(WTIME);
7422547Skarels 	while ((count > 0 && !timedout) ||
7522547Skarels 	    select(20, &bits, 0, 0, &notime) > 0) {
7615760Skarels 		cc = recvfrom(s, packet, sizeof (packet), 0,
7715760Skarels 		  &from, &fromlen);
786918Ssam 		if (cc <= 0) {
796918Ssam 			if (cc < 0) {
8022547Skarels 				if (errno == EINTR)
8122547Skarels 					continue;
8215760Skarels 				perror("recvfrom");
836918Ssam 				(void) close(s);
846918Ssam 				exit(1);
856918Ssam 			}
866918Ssam 			continue;
876918Ssam 		}
886918Ssam 		rip_input(&from, cc);
896918Ssam 		count--;
906918Ssam 	}
916918Ssam }
926918Ssam 
936918Ssam query(host)
946918Ssam 	char *host;
956918Ssam {
966918Ssam 	struct sockaddr_in router;
976918Ssam 	register struct rip *msg = (struct rip *)packet;
988339Ssam 	struct hostent *hp;
998339Ssam 	struct servent *sp;
1006918Ssam 
1016918Ssam 	bzero((char *)&router, sizeof (router));
102*26146Skarels 	router.sin_family = AF_INET;
103*26146Skarels 	router.sin_addr.s_addr = inet_addr(host);
104*26146Skarels 	if (router.sin_addr.s_addr == -1) {
105*26146Skarels 		hp = gethostbyname(host);
106*26146Skarels 		if (hp == 0) {
107*26146Skarels 			printf("%s: unknown\n", host);
108*26146Skarels 			exit(1);
109*26146Skarels 		}
110*26146Skarels 		bcopy(hp->h_addr, &router.sin_addr, hp->h_length);
1116918Ssam 	}
1128339Ssam 	sp = getservbyname("router", "udp");
1138339Ssam 	if (sp == 0) {
1148339Ssam 		printf("udp/router: service unknown\n");
1158339Ssam 		exit(1);
1168339Ssam 	}
11715760Skarels 	router.sin_port = sp->s_port;
1186918Ssam 	msg->rip_cmd = RIPCMD_REQUEST;
11915760Skarels 	msg->rip_vers = RIPVERSION;
12015760Skarels 	msg->rip_nets[0].rip_dst.sa_family = htons(AF_UNSPEC);
12115760Skarels 	msg->rip_nets[0].rip_metric = htonl(HOPCNT_INFINITY);
12215760Skarels 	if (sendto(s, packet, sizeof (struct rip), 0,
12315760Skarels 	  &router, sizeof(router)) < 0)
1246918Ssam 		perror(host);
1256918Ssam }
1266918Ssam 
1276918Ssam /*
1286918Ssam  * Handle an incoming routing packet.
1296918Ssam  */
1306918Ssam rip_input(from, size)
1316918Ssam 	struct sockaddr_in *from;
1326918Ssam 	int size;
1336918Ssam {
1346918Ssam 	register struct rip *msg = (struct rip *)packet;
1356918Ssam 	struct netinfo *n;
1366918Ssam 	char *name;
13722547Skarels 	int lna, net, subnet;
1388339Ssam 	struct hostent *hp;
1398339Ssam 	struct netent *np;
1406918Ssam 
1416918Ssam 	if (msg->rip_cmd != RIPCMD_RESPONSE)
1426918Ssam 		return;
143*26146Skarels 	printf("%d bytes from ");
144*26146Skarels 	if (nflag)
145*26146Skarels 		printf("%s:\n", inet_ntoa(from->sin_addr));
146*26146Skarels 	else {
147*26146Skarels 		hp = gethostbyaddr(&from->sin_addr, sizeof (struct in_addr),
148*26146Skarels 			AF_INET);
149*26146Skarels 		name = hp == 0 ? "???" : hp->h_name;
150*26146Skarels 		printf("%s(%s):\n", name, inet_ntoa(from->sin_addr));
151*26146Skarels 	}
1526918Ssam 	size -= sizeof (int);
1536918Ssam 	n = msg->rip_nets;
1546918Ssam 	while (size > 0) {
1556918Ssam 		register struct sockaddr_in *sin;
1566918Ssam 
1576918Ssam 		if (size < sizeof (struct netinfo))
1586918Ssam 			break;
15915760Skarels 		if (msg->rip_vers > 0) {
16015760Skarels 			n->rip_dst.sa_family =
16115760Skarels 				ntohs(n->rip_dst.sa_family);
16215760Skarels 			n->rip_metric = ntohl(n->rip_metric);
16315760Skarels 		}
1646918Ssam 		sin = (struct sockaddr_in *)&n->rip_dst;
16522547Skarels 		net = inet_netof(sin->sin_addr);
16622547Skarels 		subnet = inet_subnetof(sin->sin_addr);
16722547Skarels 		lna = inet_lnaof(sin->sin_addr);
16822547Skarels 		name = "???";
169*26146Skarels 		if (!nflag) {
170*26146Skarels 			if (lna == INADDR_ANY) {
171*26146Skarels 				np = getnetbyaddr(net, AF_INET);
172*26146Skarels 				if (np)
173*26146Skarels 					name = np->n_name;
174*26146Skarels 				else if (net == 0)
175*26146Skarels 					name = "default";
176*26146Skarels 			} else if ((subnet != net) && ((lna & 0xff) == 0) &&
177*26146Skarels 			    (np = getnetbyaddr(subnet, AF_INET))) {
178*26146Skarels 				struct in_addr subnaddr, inet_makeaddr();
17922547Skarels 
180*26146Skarels 				subnaddr = inet_makeaddr(subnet, INADDR_ANY);
181*26146Skarels 				if (bcmp(&sin->sin_addr, &subnaddr,
182*26146Skarels 				    sizeof(subnaddr)) == 0)
183*26146Skarels 					name = np->n_name;
184*26146Skarels 				else
185*26146Skarels 					goto host;
186*26146Skarels 			} else {
187*26146Skarels 	host:
188*26146Skarels 				hp = gethostbyaddr(&sin->sin_addr,
189*26146Skarels 				    sizeof (struct in_addr), AF_INET);
190*26146Skarels 				if (hp)
191*26146Skarels 					name = hp->h_name;
192*26146Skarels 			}
193*26146Skarels 			printf("\t%s(%s), metric %d\n", name,
194*26146Skarels 				inet_ntoa(sin->sin_addr), n->rip_metric);
195*26146Skarels 		} else
196*26146Skarels 			printf("\t%s, metric %d\n",
197*26146Skarels 				inet_ntoa(sin->sin_addr), n->rip_metric);
1986918Ssam 		size -= sizeof (struct netinfo), n++;
1996918Ssam 	}
2006918Ssam }
20115760Skarels 
20215760Skarels timeout()
20315760Skarels {
20415760Skarels 	timedout = 1;
20515760Skarels }
20622547Skarels 
20722547Skarels /*
20822547Skarels  * Return the possible subnetwork number from an internet address.
20922547Skarels  * SHOULD FIND OUT WHETHER THIS IS A LOCAL NETWORK BEFORE LOOKING
21022547Skarels  * INSIDE OF THE HOST PART.  We can only believe this if we have other
21122547Skarels  * information (e.g., we can find a name for this number).
21222547Skarels  */
21322547Skarels inet_subnetof(in)
21422547Skarels 	struct in_addr in;
21522547Skarels {
21622547Skarels 	register u_long i = ntohl(in.s_addr);
21722547Skarels 
21825382Skarels 	if (IN_CLASSA(i))
21925382Skarels 		return ((i & IN_CLASSB_NET) >> IN_CLASSB_NSHIFT);
22025382Skarels 	else if (IN_CLASSB(i))
22122547Skarels 		return ((i & IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
22225382Skarels 	else
22325382Skarels 		return ((i & 0xffffffc0) >> 28);
22422547Skarels }
225