xref: /csrg-svn/sbin/routed/query/query.c (revision 8344)
16918Ssam #ifndef lint
2*8344Ssam static char sccsid[] = "@(#)query.c	4.4 10/06/82";
36918Ssam #endif
46918Ssam 
56918Ssam #include <sys/param.h>
66918Ssam #include <sys/protosw.h>
76918Ssam #include <sys/socket.h>
86918Ssam #include <net/in.h>
96918Ssam #include <errno.h>
106918Ssam #include <stdio.h>
118339Ssam #include <netdb.h>
126918Ssam #include "rip.h"
136918Ssam 
146918Ssam int	s;
156918Ssam char	packet[MAXPACKETSIZE];
166918Ssam 
176918Ssam main(argc, argv)
186918Ssam 	int argc;
196918Ssam 	char *argv[];
206918Ssam {
216918Ssam 	int cc, count;
226918Ssam 	struct sockaddr from;
236918Ssam 
246918Ssam 	if (argc < 2) {
256918Ssam 		printf("usage: query hosts...\n");
266918Ssam 		exit(1);
276918Ssam 	}
288339Ssam 	s = socket(SOCK_DGRAM, 0, 0, 0);
296918Ssam 	if (s < 0) {
306918Ssam 		perror("socket");
316918Ssam 		exit(2);
326918Ssam 	}
336918Ssam 	argv++, argc--;
346918Ssam 	count = argc;
356918Ssam 	while (argc > 0) {
366918Ssam 		query(*argv);
376918Ssam 		argv++, argc--;
386918Ssam 	}
396918Ssam 
406918Ssam 	/*
416918Ssam 	 * Listen for returning packets
426918Ssam 	 */
436918Ssam 	while (count > 0) {
446918Ssam 		cc = receive(s, &from, packet, sizeof (packet));
456918Ssam 		if (cc <= 0) {
466918Ssam 			if (cc < 0) {
476918Ssam 				perror("receive");
486918Ssam 				(void) close(s);
496918Ssam 				exit(1);
506918Ssam 			}
516918Ssam 			continue;
526918Ssam 		}
536918Ssam 		rip_input(&from, cc);
546918Ssam 		count--;
556918Ssam 	}
566918Ssam }
576918Ssam 
586918Ssam query(host)
596918Ssam 	char *host;
606918Ssam {
616918Ssam 	struct sockaddr_in router;
626918Ssam 	register struct rip *msg = (struct rip *)packet;
638339Ssam 	struct hostent *hp;
648339Ssam 	struct servent *sp;
656918Ssam 
666918Ssam 	bzero((char *)&router, sizeof (router));
678339Ssam 	hp = gethostbyname(host);
688339Ssam 	if (hp == 0) {
696918Ssam 		printf("%s: unknown\n", host);
706918Ssam 		exit(1);
716918Ssam 	}
728339Ssam 	bcopy(hp->h_addr, &router.sin_addr, hp->h_length);
736918Ssam 	router.sin_family = AF_INET;
748339Ssam 	sp = getservbyname("router", "udp");
758339Ssam 	if (sp == 0) {
768339Ssam 		printf("udp/router: service unknown\n");
778339Ssam 		exit(1);
788339Ssam 	}
798339Ssam 	router.sin_port = htons(sp->s_port);
806918Ssam 	msg->rip_cmd = RIPCMD_REQUEST;
816918Ssam 	msg->rip_nets[0].rip_dst.sa_family = AF_UNSPEC;
826918Ssam 	msg->rip_nets[0].rip_metric = HOPCNT_INFINITY;
836918Ssam 	if (send(s, &router, packet, sizeof (struct rip)) < 0)
846918Ssam 		perror(host);
856918Ssam }
866918Ssam 
876918Ssam /*
886918Ssam  * Handle an incoming routing packet.
896918Ssam  */
906918Ssam rip_input(from, size)
916918Ssam 	struct sockaddr_in *from;
926918Ssam 	int size;
936918Ssam {
946918Ssam 	register struct rip *msg = (struct rip *)packet;
956918Ssam 	struct netinfo *n;
966918Ssam 	char *name;
978339Ssam 	struct hostent *hp;
988339Ssam 	struct netent *np;
996918Ssam 
1006918Ssam 	if (msg->rip_cmd != RIPCMD_RESPONSE)
1016918Ssam 		return;
102*8344Ssam 	hp = gethostbyaddr(&from->sin_addr, sizeof (struct in_addr), AF_INET);
1038339Ssam 	name = hp == 0 ? "???" : hp->h_name;
1046918Ssam 	printf("from %s(%x):\n", name, from->sin_addr);
1056918Ssam 	size -= sizeof (int);
1066918Ssam 	n = msg->rip_nets;
1076918Ssam 	while (size > 0) {
1086918Ssam 		register struct sockaddr_in *sin;
1096918Ssam 
1106918Ssam 		if (size < sizeof (struct netinfo))
1116918Ssam 			break;
1126918Ssam 		sin = (struct sockaddr_in *)&n->rip_dst;
1138339Ssam 		if (in_lnaof(sin->sin_addr) == INADDR_ANY) {
114*8344Ssam 			np = getnetbyaddr(in_netof(sin->sin_addr), AF_INET);
1158339Ssam 			name = np ? np->n_name : "???";
1168339Ssam 		} else {
1178339Ssam 			hp = gethostbyaddr(&sin->sin_addr,
118*8344Ssam 				sizeof (struct in_addr), AF_INET);
1198339Ssam 			name = hp ? hp->h_name : "???";
1208339Ssam 		}
1216918Ssam 		printf("\t%s(%x), metric %d\n", name,
1226918Ssam 			sin->sin_addr, n->rip_metric);
1236918Ssam 		size -= sizeof (struct netinfo), n++;
1246918Ssam 	}
1256918Ssam }
1268339Ssam 
1278339Ssam /*
1288339Ssam  * Return the network number from an internet
1298339Ssam  * address; handles class a/b/c network #'s.
1308339Ssam  */
1318339Ssam in_netof(in)
1328339Ssam 	struct in_addr in;
1338339Ssam {
1348339Ssam #if vax || pdp11
1358339Ssam 	register u_long net;
1368339Ssam 
1378339Ssam 	if ((in.s_addr&IN_CLASSA) == 0)
1388339Ssam 		return (in.s_addr & IN_CLASSA_NET);
1398339Ssam 	if ((in.s_addr&IN_CLASSB) == 0)
1408339Ssam 		return ((int)htons((u_short)(in.s_addr & IN_CLASSB_NET)));
1418339Ssam 	net = htonl((u_long)(in.s_addr & IN_CLASSC_NET));
1428339Ssam 	net >>= 8;
1438339Ssam 	return ((int)net);
1448339Ssam #else
1458339Ssam 	return (IN_NETOF(in));
1468339Ssam #endif
1478339Ssam }
1488339Ssam 
1498339Ssam /*
1508339Ssam  * Return the local network address portion of an
1518339Ssam  * internet address; handles class a/b/c network
1528339Ssam  * number formats.
1538339Ssam  */
1548339Ssam in_lnaof(in)
1558339Ssam 	struct in_addr in;
1568339Ssam {
1578339Ssam #if vax || pdp11
1588339Ssam #define	IN_LNAOF(in) \
1598339Ssam 	(((in).s_addr&IN_CLASSA) == 0 ? (in).s_addr&IN_CLASSA_LNA : \
1608339Ssam 		((in).s_addr&IN_CLASSB) == 0 ? (in).s_addr&IN_CLASSB_LNA : \
1618339Ssam 			(in).s_addr&IN_CLASSC_LNA)
1628339Ssam 	return ((int)htonl((u_long)IN_LNAOF(in)));
1638339Ssam #else
1648339Ssam 	return (IN_LNAOF(in));
1658339Ssam #endif
1668339Ssam }
167