xref: /csrg-svn/sbin/routed/query/query.c (revision 8339)
16918Ssam #ifndef lint
2*8339Ssam static char sccsid[] = "@(#)query.c	4.3 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>
11*8339Ssam #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 	}
28*8339Ssam 	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;
63*8339Ssam 	struct hostent *hp;
64*8339Ssam 	struct servent *sp;
656918Ssam 
666918Ssam 	bzero((char *)&router, sizeof (router));
67*8339Ssam 	hp = gethostbyname(host);
68*8339Ssam 	if (hp == 0) {
696918Ssam 		printf("%s: unknown\n", host);
706918Ssam 		exit(1);
716918Ssam 	}
72*8339Ssam 	bcopy(hp->h_addr, &router.sin_addr, hp->h_length);
736918Ssam 	router.sin_family = AF_INET;
74*8339Ssam 	sp = getservbyname("router", "udp");
75*8339Ssam 	if (sp == 0) {
76*8339Ssam 		printf("udp/router: service unknown\n");
77*8339Ssam 		exit(1);
78*8339Ssam 	}
79*8339Ssam 	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;
97*8339Ssam 	struct hostent *hp;
98*8339Ssam 	struct netent *np;
996918Ssam 
1006918Ssam 	if (msg->rip_cmd != RIPCMD_RESPONSE)
1016918Ssam 		return;
102*8339Ssam 	hp = gethostbyaddr(&from->sin_addr, sizeof (struct in_addr));
103*8339Ssam 	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;
113*8339Ssam 		if (in_lnaof(sin->sin_addr) == INADDR_ANY) {
114*8339Ssam 			np = getnetbyaddr(in_netof(sin->sin_addr));
115*8339Ssam 			name = np ? np->n_name : "???";
116*8339Ssam 		} else {
117*8339Ssam 			hp = gethostbyaddr(&sin->sin_addr,
118*8339Ssam 				sizeof (struct in_addr));
119*8339Ssam 			name = hp ? hp->h_name : "???";
120*8339Ssam 		}
1216918Ssam 		printf("\t%s(%x), metric %d\n", name,
1226918Ssam 			sin->sin_addr, n->rip_metric);
1236918Ssam 		size -= sizeof (struct netinfo), n++;
1246918Ssam 	}
1256918Ssam }
126*8339Ssam 
127*8339Ssam /*
128*8339Ssam  * Return the network number from an internet
129*8339Ssam  * address; handles class a/b/c network #'s.
130*8339Ssam  */
131*8339Ssam in_netof(in)
132*8339Ssam 	struct in_addr in;
133*8339Ssam {
134*8339Ssam #if vax || pdp11
135*8339Ssam 	register u_long net;
136*8339Ssam 
137*8339Ssam 	if ((in.s_addr&IN_CLASSA) == 0)
138*8339Ssam 		return (in.s_addr & IN_CLASSA_NET);
139*8339Ssam 	if ((in.s_addr&IN_CLASSB) == 0)
140*8339Ssam 		return ((int)htons((u_short)(in.s_addr & IN_CLASSB_NET)));
141*8339Ssam 	net = htonl((u_long)(in.s_addr & IN_CLASSC_NET));
142*8339Ssam 	net >>= 8;
143*8339Ssam 	return ((int)net);
144*8339Ssam #else
145*8339Ssam 	return (IN_NETOF(in));
146*8339Ssam #endif
147*8339Ssam }
148*8339Ssam 
149*8339Ssam /*
150*8339Ssam  * Return the local network address portion of an
151*8339Ssam  * internet address; handles class a/b/c network
152*8339Ssam  * number formats.
153*8339Ssam  */
154*8339Ssam in_lnaof(in)
155*8339Ssam 	struct in_addr in;
156*8339Ssam {
157*8339Ssam #if vax || pdp11
158*8339Ssam #define	IN_LNAOF(in) \
159*8339Ssam 	(((in).s_addr&IN_CLASSA) == 0 ? (in).s_addr&IN_CLASSA_LNA : \
160*8339Ssam 		((in).s_addr&IN_CLASSB) == 0 ? (in).s_addr&IN_CLASSB_LNA : \
161*8339Ssam 			(in).s_addr&IN_CLASSC_LNA)
162*8339Ssam 	return ((int)htonl((u_long)IN_LNAOF(in)));
163*8339Ssam #else
164*8339Ssam 	return (IN_LNAOF(in));
165*8339Ssam #endif
166*8339Ssam }
167