xref: /csrg-svn/sbin/routed/query/query.c (revision 15760)
16918Ssam #ifndef lint
2*15760Skarels static char sccsid[] = "@(#)query.c	4.6 12/21/83";
36918Ssam #endif
46918Ssam 
56918Ssam #include <sys/param.h>
66918Ssam #include <sys/protosw.h>
76918Ssam #include <sys/socket.h>
8*15760Skarels #include <sys/time.h>
9*15760Skarels #include <netinet/in.h>
106918Ssam #include <errno.h>
116918Ssam #include <stdio.h>
128339Ssam #include <netdb.h>
13*15760Skarels #include "../protocol.h"
146918Ssam 
15*15760Skarels #define	WTIME	5		/* Time to wait for responses */
16*15760Skarels 
176918Ssam int	s;
186918Ssam char	packet[MAXPACKETSIZE];
196918Ssam 
206918Ssam main(argc, argv)
216918Ssam 	int argc;
226918Ssam 	char *argv[];
236918Ssam {
24*15760Skarels 	int cc, count, bits;
256918Ssam 	struct sockaddr from;
26*15760Skarels 	int fromlen = sizeof(from);
27*15760Skarels 	struct timeval notime;
286918Ssam 
296918Ssam 	if (argc < 2) {
306918Ssam 		printf("usage: query hosts...\n");
316918Ssam 		exit(1);
326918Ssam 	}
33*15760Skarels 	s = socket(AF_INET, SOCK_DGRAM, 0);
346918Ssam 	if (s < 0) {
356918Ssam 		perror("socket");
366918Ssam 		exit(2);
376918Ssam 	}
38*15760Skarels 
396918Ssam 	argv++, argc--;
406918Ssam 	count = argc;
416918Ssam 	while (argc > 0) {
426918Ssam 		query(*argv);
436918Ssam 		argv++, argc--;
446918Ssam 	}
456918Ssam 
466918Ssam 	/*
47*15760Skarels 	 * Listen for returning packets;
48*15760Skarels 	 * may be more than one packet per host.
496918Ssam 	 */
50*15760Skarels 	bits = 1 << s;
51*15760Skarels 	bzero(&notime, sizeof(notime));
52*15760Skarels 	while (count > 0 || select(20, &bits, 0, 0, &notime) > 0) {
53*15760Skarels 		cc = recvfrom(s, packet, sizeof (packet), 0,
54*15760Skarels 		  &from, &fromlen);
556918Ssam 		if (cc <= 0) {
566918Ssam 			if (cc < 0) {
57*15760Skarels 				perror("recvfrom");
586918Ssam 				(void) close(s);
596918Ssam 				exit(1);
606918Ssam 			}
616918Ssam 			continue;
626918Ssam 		}
636918Ssam 		rip_input(&from, cc);
646918Ssam 		count--;
656918Ssam 	}
666918Ssam }
676918Ssam 
686918Ssam query(host)
696918Ssam 	char *host;
706918Ssam {
716918Ssam 	struct sockaddr_in router;
726918Ssam 	register struct rip *msg = (struct rip *)packet;
738339Ssam 	struct hostent *hp;
748339Ssam 	struct servent *sp;
756918Ssam 
766918Ssam 	bzero((char *)&router, sizeof (router));
778339Ssam 	hp = gethostbyname(host);
788339Ssam 	if (hp == 0) {
796918Ssam 		printf("%s: unknown\n", host);
806918Ssam 		exit(1);
816918Ssam 	}
828339Ssam 	bcopy(hp->h_addr, &router.sin_addr, hp->h_length);
836918Ssam 	router.sin_family = AF_INET;
848339Ssam 	sp = getservbyname("router", "udp");
858339Ssam 	if (sp == 0) {
868339Ssam 		printf("udp/router: service unknown\n");
878339Ssam 		exit(1);
888339Ssam 	}
89*15760Skarels 	router.sin_port = sp->s_port;
906918Ssam 	msg->rip_cmd = RIPCMD_REQUEST;
91*15760Skarels 	msg->rip_vers = RIPVERSION;
92*15760Skarels 	msg->rip_nets[0].rip_dst.sa_family = htons(AF_UNSPEC);
93*15760Skarels 	msg->rip_nets[0].rip_metric = htonl(HOPCNT_INFINITY);
94*15760Skarels 	if (sendto(s, packet, sizeof (struct rip), 0,
95*15760Skarels 	  &router, sizeof(router)) < 0)
966918Ssam 		perror(host);
976918Ssam }
986918Ssam 
996918Ssam /*
1006918Ssam  * Handle an incoming routing packet.
1016918Ssam  */
1026918Ssam rip_input(from, size)
1036918Ssam 	struct sockaddr_in *from;
1046918Ssam 	int size;
1056918Ssam {
1066918Ssam 	register struct rip *msg = (struct rip *)packet;
1076918Ssam 	struct netinfo *n;
1086918Ssam 	char *name;
1098339Ssam 	struct hostent *hp;
1108339Ssam 	struct netent *np;
1116918Ssam 
1126918Ssam 	if (msg->rip_cmd != RIPCMD_RESPONSE)
1136918Ssam 		return;
1148344Ssam 	hp = gethostbyaddr(&from->sin_addr, sizeof (struct in_addr), AF_INET);
1158339Ssam 	name = hp == 0 ? "???" : hp->h_name;
116*15760Skarels 	printf("from %s(%s):\n", name, inet_ntoa(from->sin_addr));
1176918Ssam 	size -= sizeof (int);
1186918Ssam 	n = msg->rip_nets;
1196918Ssam 	while (size > 0) {
1206918Ssam 		register struct sockaddr_in *sin;
1216918Ssam 
1226918Ssam 		if (size < sizeof (struct netinfo))
1236918Ssam 			break;
124*15760Skarels 		if (msg->rip_vers > 0) {
125*15760Skarels 			n->rip_dst.sa_family =
126*15760Skarels 				ntohs(n->rip_dst.sa_family);
127*15760Skarels 			n->rip_metric = ntohl(n->rip_metric);
128*15760Skarels 		}
1296918Ssam 		sin = (struct sockaddr_in *)&n->rip_dst;
1308365Ssam 		if (inet_lnaof(sin->sin_addr) == INADDR_ANY) {
1318365Ssam 			np = getnetbyaddr(inet_netof(sin->sin_addr), AF_INET);
1328339Ssam 			name = np ? np->n_name : "???";
1338339Ssam 		} else {
1348339Ssam 			hp = gethostbyaddr(&sin->sin_addr,
1358344Ssam 				sizeof (struct in_addr), AF_INET);
1368339Ssam 			name = hp ? hp->h_name : "???";
1378339Ssam 		}
138*15760Skarels 		printf("\t%s(%s), metric %d\n", name,
139*15760Skarels 			inet_ntoa(sin->sin_addr), n->rip_metric);
1406918Ssam 		size -= sizeof (struct netinfo), n++;
1416918Ssam 	}
1426918Ssam }
143*15760Skarels 
144*15760Skarels timeout()
145*15760Skarels {
146*15760Skarels 	timedout = 1;
147*15760Skarels }
148