|
|
1.1 root 1: /*
2: * Copyright (c) 1983, 1986 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: *
6: * This file include significant work done at Cornell University
7: * by Bill Nesheim. That work included by permission.
8: */
9:
10: #ifndef lint
11: char copyright[] =
12: "@(#) Copyright (c) 1983, 1986 Regents of the University of California.\n\
13: All rights reserved.\n";
14: #endif not lint
15:
16: #ifndef lint
17: static char sccsid[] = "@(#)query.c 1.4 (Berkeley) 2/14/86";
18: #endif not lint
19:
20: #include <sys/param.h>
21: #include <sys/protosw.h>
22: #include <sys/socket.h>
23: #include <sys/time.h>
24: #include <netinet/in.h>
25: #include <netns/ns.h>
26: #include <netns/idp.h>
27: #include <errno.h>
28: #include <stdio.h>
29: #include <netdb.h>
30: #include "../protocol.h"
31: #define IDPPORT_RIF 1
32:
33: #define WTIME 5 /* Time to wait for responses */
34:
35: int s;
36: int timedout, timeout();
37: char packet[MAXPACKETSIZE];
38: extern int errno;
39: struct sockaddr_ns myaddr = {AF_NS};
40: char ns_ntoa();
41: struct ns_addr ns_addr();
42: main(argc, argv)
43: int argc;
44: char *argv[];
45: {
46: int cc, count, bits;
47: struct sockaddr from;
48: int fromlen = sizeof(from);
49: struct timeval notime;
50:
51: if (argc < 2) {
52: printf("usage: query hosts...\n");
53: exit(1);
54: }
55: s = getsocket(SOCK_DGRAM, 0);
56: if (s < 0) {
57: perror("socket");
58: exit(2);
59: }
60:
61: argv++, argc--;
62: query(argv,argc);
63:
64: /*
65: * Listen for returning packets;
66: * may be more than one packet per host.
67: */
68: bits = 1 << s;
69: bzero(¬ime, sizeof(notime));
70: signal(SIGALRM, timeout);
71: alarm(WTIME);
72: while (!timedout ||
73: select(20, &bits, 0, 0, ¬ime) > 0) {
74: struct nspacket {
75: struct idp hdr;
76: char data[512];
77: } response;
78: cc = recvfrom(s, &response, sizeof (response), 0,
79: &from, &fromlen);
80: if (cc <= 0) {
81: if (cc < 0) {
82: if (errno == EINTR)
83: continue;
84: perror("recvfrom");
85: (void) close(s);
86: exit(1);
87: }
88: continue;
89: }
90: rip_input(&from, response.data, cc);
91: count--;
92: }
93: }
94: static struct sockaddr_ns router = {AF_NS};
95: static struct ns_addr zero_addr;
96: static short allones[] = {-1, -1, -1};
97:
98: query(argv,argc)
99: char **argv;
100: {
101: register struct rip *msg = (struct rip *)packet;
102: char *host = *argv;
103: struct ns_addr specific;
104:
105: argv++; argc--;
106: router.sns_addr = ns_addr(host);
107: router.sns_addr.x_port = htons(IDPPORT_RIF);
108: if (ns_hosteq(zero_addr, router.sns_addr)) {
109: router.sns_addr.x_host = *(union ns_host *) allones;
110: }
111: msg->rip_cmd = htons(RIPCMD_REQUEST);
112: msg->rip_nets[0].rip_dst = *(union ns_net *) allones;
113: msg->rip_nets[0].rip_metric = htons(HOPCNT_INFINITY);
114: if (argc > 0) {
115: specific = ns_addr(*argv);
116: msg->rip_nets[0].rip_dst = specific.x_net;
117: specific.x_host = zero_addr.x_host;
118: specific.x_port = zero_addr.x_port;
119: printf("Net asked for was %s\n", ns_ntoa(specific));
120: }
121: if (sendto(s, packet, sizeof (struct rip), 0,
122: &router, sizeof(router)) < 0)
123: perror(host);
124: }
125:
126: /*
127: * Handle an incoming routing packet.
128: */
129: rip_input(from, msg, size)
130: struct sockaddr_ns *from;
131: register struct rip *msg;
132: int size;
133: {
134: struct netinfo *n;
135: char *name;
136: int lna, net, subnet;
137: struct hostent *hp;
138: struct netent *np;
139: static struct ns_addr work;
140:
141: if (htons(msg->rip_cmd) != RIPCMD_RESPONSE)
142: return;
143: printf("from %s\n", ns_ntoa(from->sns_addr));
144: size -= sizeof (struct idp);
145: size -= sizeof (short);
146: n = msg->rip_nets;
147: while (size > 0) {
148: union ns_net_u net;
149: if (size < sizeof (struct netinfo))
150: break;
151: net.net_e = n->rip_dst;
152: printf("\t%d, metric %d\n", ntohl(net.long_e),
153: ntohs(n->rip_metric));
154: size -= sizeof (struct netinfo), n++;
155: }
156: }
157:
158: timeout()
159: {
160: timedout = 1;
161: }
162: getsocket(type, proto)
163: int type, proto;
164: {
165: struct sockaddr_ns *sns = &myaddr;
166: int domain = sns->sns_family;
167: int retry, s, on = 1;
168:
169: retry = 1;
170: while ((s = socket(domain, type, proto)) < 0 && retry) {
171: perror("socket");
172: sleep(5 * retry);
173: retry <<= 1;
174: }
175: if (retry == 0)
176: return (-1);
177: while (bind(s, sns, sizeof (*sns), 0) < 0 && retry) {
178: perror("bind");
179: sleep(5 * retry);
180: retry <<= 1;
181: }
182: if (retry == 0)
183: return (-1);
184: if (domain==AF_NS) {
185: struct idp idp;
186: if (setsockopt(s, 0, SO_HEADERS_ON_INPUT, &on, sizeof(on))) {
187: perror("setsockopt SEE HEADERS");
188: exit(1);
189: }
190: idp.idp_pt = NSPROTO_RI;
191: if (setsockopt(s, 0, SO_DEFAULT_HEADERS, &idp, sizeof(idp))) {
192: perror("setsockopt SET HEADERS");
193: exit(1);
194: }
195: }
196: if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) {
197: perror("setsockopt SO_BROADCAST");
198: exit(1);
199: }
200: return (s);
201: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.