xref: /original-bsd/sbin/routed/query/query.c (revision 4f485440)
1 #ifndef lint
2 static char sccsid[] = "@(#)query.c	4.5 10/07/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), AF_INET);
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 (inet_lnaof(sin->sin_addr) == INADDR_ANY) {
114 			np = getnetbyaddr(inet_netof(sin->sin_addr), AF_INET);
115 			name = np ? np->n_name : "???";
116 		} else {
117 			hp = gethostbyaddr(&sin->sin_addr,
118 				sizeof (struct in_addr), AF_INET);
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