xref: /csrg-svn/sbin/routed/query/query.c (revision 15760)
1 #ifndef lint
2 static char sccsid[] = "@(#)query.c	4.6 12/21/83";
3 #endif
4 
5 #include <sys/param.h>
6 #include <sys/protosw.h>
7 #include <sys/socket.h>
8 #include <sys/time.h>
9 #include <netinet/in.h>
10 #include <errno.h>
11 #include <stdio.h>
12 #include <netdb.h>
13 #include "../protocol.h"
14 
15 #define	WTIME	5		/* Time to wait for responses */
16 
17 int	s;
18 char	packet[MAXPACKETSIZE];
19 
20 main(argc, argv)
21 	int argc;
22 	char *argv[];
23 {
24 	int cc, count, bits;
25 	struct sockaddr from;
26 	int fromlen = sizeof(from);
27 	struct timeval notime;
28 
29 	if (argc < 2) {
30 		printf("usage: query hosts...\n");
31 		exit(1);
32 	}
33 	s = socket(AF_INET, SOCK_DGRAM, 0);
34 	if (s < 0) {
35 		perror("socket");
36 		exit(2);
37 	}
38 
39 	argv++, argc--;
40 	count = argc;
41 	while (argc > 0) {
42 		query(*argv);
43 		argv++, argc--;
44 	}
45 
46 	/*
47 	 * Listen for returning packets;
48 	 * may be more than one packet per host.
49 	 */
50 	bits = 1 << s;
51 	bzero(&notime, sizeof(notime));
52 	while (count > 0 || select(20, &bits, 0, 0, &notime) > 0) {
53 		cc = recvfrom(s, packet, sizeof (packet), 0,
54 		  &from, &fromlen);
55 		if (cc <= 0) {
56 			if (cc < 0) {
57 				perror("recvfrom");
58 				(void) close(s);
59 				exit(1);
60 			}
61 			continue;
62 		}
63 		rip_input(&from, cc);
64 		count--;
65 	}
66 }
67 
68 query(host)
69 	char *host;
70 {
71 	struct sockaddr_in router;
72 	register struct rip *msg = (struct rip *)packet;
73 	struct hostent *hp;
74 	struct servent *sp;
75 
76 	bzero((char *)&router, sizeof (router));
77 	hp = gethostbyname(host);
78 	if (hp == 0) {
79 		printf("%s: unknown\n", host);
80 		exit(1);
81 	}
82 	bcopy(hp->h_addr, &router.sin_addr, hp->h_length);
83 	router.sin_family = AF_INET;
84 	sp = getservbyname("router", "udp");
85 	if (sp == 0) {
86 		printf("udp/router: service unknown\n");
87 		exit(1);
88 	}
89 	router.sin_port = sp->s_port;
90 	msg->rip_cmd = RIPCMD_REQUEST;
91 	msg->rip_vers = RIPVERSION;
92 	msg->rip_nets[0].rip_dst.sa_family = htons(AF_UNSPEC);
93 	msg->rip_nets[0].rip_metric = htonl(HOPCNT_INFINITY);
94 	if (sendto(s, packet, sizeof (struct rip), 0,
95 	  &router, sizeof(router)) < 0)
96 		perror(host);
97 }
98 
99 /*
100  * Handle an incoming routing packet.
101  */
102 rip_input(from, size)
103 	struct sockaddr_in *from;
104 	int size;
105 {
106 	register struct rip *msg = (struct rip *)packet;
107 	struct netinfo *n;
108 	char *name;
109 	struct hostent *hp;
110 	struct netent *np;
111 
112 	if (msg->rip_cmd != RIPCMD_RESPONSE)
113 		return;
114 	hp = gethostbyaddr(&from->sin_addr, sizeof (struct in_addr), AF_INET);
115 	name = hp == 0 ? "???" : hp->h_name;
116 	printf("from %s(%s):\n", name, inet_ntoa(from->sin_addr));
117 	size -= sizeof (int);
118 	n = msg->rip_nets;
119 	while (size > 0) {
120 		register struct sockaddr_in *sin;
121 
122 		if (size < sizeof (struct netinfo))
123 			break;
124 		if (msg->rip_vers > 0) {
125 			n->rip_dst.sa_family =
126 				ntohs(n->rip_dst.sa_family);
127 			n->rip_metric = ntohl(n->rip_metric);
128 		}
129 		sin = (struct sockaddr_in *)&n->rip_dst;
130 		if (inet_lnaof(sin->sin_addr) == INADDR_ANY) {
131 			np = getnetbyaddr(inet_netof(sin->sin_addr), AF_INET);
132 			name = np ? np->n_name : "???";
133 		} else {
134 			hp = gethostbyaddr(&sin->sin_addr,
135 				sizeof (struct in_addr), AF_INET);
136 			name = hp ? hp->h_name : "???";
137 		}
138 		printf("\t%s(%s), metric %d\n", name,
139 			inet_ntoa(sin->sin_addr), n->rip_metric);
140 		size -= sizeof (struct netinfo), n++;
141 	}
142 }
143 
144 timeout()
145 {
146 	timedout = 1;
147 }
148