xref: /csrg-svn/sbin/routed/query/query.c (revision 8339)
1 #ifndef lint
2 static char sccsid[] = "@(#)query.c	4.3 10/06/82";
3 #endif
4 
5 #include <sys/param.h>
6 #include <sys/protosw.h>
7 #include <sys/socket.h>
8 #include <net/in.h>
9 #include <errno.h>
10 #include <stdio.h>
11 #include <netdb.h>
12 #include "rip.h"
13 
14 int	s;
15 char	packet[MAXPACKETSIZE];
16 
17 main(argc, argv)
18 	int argc;
19 	char *argv[];
20 {
21 	int cc, count;
22 	struct sockaddr from;
23 
24 	if (argc < 2) {
25 		printf("usage: query hosts...\n");
26 		exit(1);
27 	}
28 	s = socket(SOCK_DGRAM, 0, 0, 0);
29 	if (s < 0) {
30 		perror("socket");
31 		exit(2);
32 	}
33 	argv++, argc--;
34 	count = argc;
35 	while (argc > 0) {
36 		query(*argv);
37 		argv++, argc--;
38 	}
39 
40 	/*
41 	 * Listen for returning packets
42 	 */
43 	while (count > 0) {
44 		cc = receive(s, &from, packet, sizeof (packet));
45 		if (cc <= 0) {
46 			if (cc < 0) {
47 				perror("receive");
48 				(void) close(s);
49 				exit(1);
50 			}
51 			continue;
52 		}
53 		rip_input(&from, cc);
54 		count--;
55 	}
56 }
57 
58 query(host)
59 	char *host;
60 {
61 	struct sockaddr_in router;
62 	register struct rip *msg = (struct rip *)packet;
63 	struct hostent *hp;
64 	struct servent *sp;
65 
66 	bzero((char *)&router, sizeof (router));
67 	hp = gethostbyname(host);
68 	if (hp == 0) {
69 		printf("%s: unknown\n", host);
70 		exit(1);
71 	}
72 	bcopy(hp->h_addr, &router.sin_addr, hp->h_length);
73 	router.sin_family = AF_INET;
74 	sp = getservbyname("router", "udp");
75 	if (sp == 0) {
76 		printf("udp/router: service unknown\n");
77 		exit(1);
78 	}
79 	router.sin_port = htons(sp->s_port);
80 	msg->rip_cmd = RIPCMD_REQUEST;
81 	msg->rip_nets[0].rip_dst.sa_family = AF_UNSPEC;
82 	msg->rip_nets[0].rip_metric = HOPCNT_INFINITY;
83 	if (send(s, &router, packet, sizeof (struct rip)) < 0)
84 		perror(host);
85 }
86 
87 /*
88  * Handle an incoming routing packet.
89  */
90 rip_input(from, size)
91 	struct sockaddr_in *from;
92 	int size;
93 {
94 	register struct rip *msg = (struct rip *)packet;
95 	struct netinfo *n;
96 	char *name;
97 	struct hostent *hp;
98 	struct netent *np;
99 
100 	if (msg->rip_cmd != RIPCMD_RESPONSE)
101 		return;
102 	hp = gethostbyaddr(&from->sin_addr, sizeof (struct in_addr));
103 	name = hp == 0 ? "???" : hp->h_name;
104 	printf("from %s(%x):\n", name, from->sin_addr);
105 	size -= sizeof (int);
106 	n = msg->rip_nets;
107 	while (size > 0) {
108 		register struct sockaddr_in *sin;
109 
110 		if (size < sizeof (struct netinfo))
111 			break;
112 		sin = (struct sockaddr_in *)&n->rip_dst;
113 		if (in_lnaof(sin->sin_addr) == INADDR_ANY) {
114 			np = getnetbyaddr(in_netof(sin->sin_addr));
115 			name = np ? np->n_name : "???";
116 		} else {
117 			hp = gethostbyaddr(&sin->sin_addr,
118 				sizeof (struct in_addr));
119 			name = hp ? hp->h_name : "???";
120 		}
121 		printf("\t%s(%x), metric %d\n", name,
122 			sin->sin_addr, n->rip_metric);
123 		size -= sizeof (struct netinfo), n++;
124 	}
125 }
126 
127 /*
128  * Return the network number from an internet
129  * address; handles class a/b/c network #'s.
130  */
131 in_netof(in)
132 	struct in_addr in;
133 {
134 #if vax || pdp11
135 	register u_long net;
136 
137 	if ((in.s_addr&IN_CLASSA) == 0)
138 		return (in.s_addr & IN_CLASSA_NET);
139 	if ((in.s_addr&IN_CLASSB) == 0)
140 		return ((int)htons((u_short)(in.s_addr & IN_CLASSB_NET)));
141 	net = htonl((u_long)(in.s_addr & IN_CLASSC_NET));
142 	net >>= 8;
143 	return ((int)net);
144 #else
145 	return (IN_NETOF(in));
146 #endif
147 }
148 
149 /*
150  * Return the local network address portion of an
151  * internet address; handles class a/b/c network
152  * number formats.
153  */
154 in_lnaof(in)
155 	struct in_addr in;
156 {
157 #if vax || pdp11
158 #define	IN_LNAOF(in) \
159 	(((in).s_addr&IN_CLASSA) == 0 ? (in).s_addr&IN_CLASSA_LNA : \
160 		((in).s_addr&IN_CLASSB) == 0 ? (in).s_addr&IN_CLASSB_LNA : \
161 			(in).s_addr&IN_CLASSC_LNA)
162 	return ((int)htonl((u_long)IN_LNAOF(in)));
163 #else
164 	return (IN_LNAOF(in));
165 #endif
166 }
167