148127Sbostic /*-
2*61473Sbostic * Copyright (c) 1983, 1986, 1993
3*61473Sbostic * The Regents of the University of California. All rights reserved.
426177Ssklower *
548127Sbostic * This code includes software contributed to Berkeley by
648127Sbostic * Bill Nesheim at Cornell University.
735547Sbostic *
848127Sbostic * %sccs.include.redist.c%
924265Ssklower */
1024265Ssklower
1124265Ssklower #ifndef lint
12*61473Sbostic static char copyright[] =
13*61473Sbostic "@(#) Copyright (c) 1983, 1986, 1993\n\
14*61473Sbostic The Regents of the University of California. All rights reserved.\n";
1535547Sbostic #endif /* not lint */
1624265Ssklower
1724326Ssklower #ifndef lint
18*61473Sbostic static char sccsid[] = "@(#)query.c 8.1 (Berkeley) 06/05/93";
1935547Sbostic #endif /* not lint */
2024326Ssklower
2124265Ssklower #include <sys/param.h>
2224265Ssklower #include <sys/protosw.h>
2324265Ssklower #include <sys/socket.h>
2424265Ssklower #include <sys/time.h>
2524265Ssklower #include <netinet/in.h>
2624265Ssklower #include <netns/ns.h>
2724265Ssklower #include <netns/idp.h>
2824265Ssklower #include <errno.h>
2924265Ssklower #include <stdio.h>
3024265Ssklower #include <netdb.h>
3124265Ssklower #include "../protocol.h"
3224265Ssklower #define IDPPORT_RIF 1
3324265Ssklower
3424265Ssklower #define WTIME 5 /* Time to wait for responses */
3524265Ssklower
3624265Ssklower int s;
3724265Ssklower int timedout, timeout();
3824265Ssklower char packet[MAXPACKETSIZE];
3924265Ssklower extern int errno;
4045667Ssklower struct sockaddr_ns myaddr = {sizeof(myaddr), AF_NS};
4130814Sbostic char *ns_ntoa();
4226176Ssklower struct ns_addr ns_addr();
main(argc,argv)4324265Ssklower main(argc, argv)
4424265Ssklower int argc;
4524265Ssklower char *argv[];
4624265Ssklower {
4724265Ssklower int cc, count, bits;
4824265Ssklower struct sockaddr from;
4924265Ssklower int fromlen = sizeof(from);
5024265Ssklower struct timeval notime;
5124265Ssklower
5224265Ssklower if (argc < 2) {
5324265Ssklower printf("usage: query hosts...\n");
5424265Ssklower exit(1);
5524265Ssklower }
5624265Ssklower s = getsocket(SOCK_DGRAM, 0);
5724265Ssklower if (s < 0) {
5824265Ssklower perror("socket");
5924265Ssklower exit(2);
6024265Ssklower }
6124265Ssklower
6224265Ssklower argv++, argc--;
6324326Ssklower query(argv,argc);
6424265Ssklower
6524265Ssklower /*
6624265Ssklower * Listen for returning packets;
6724265Ssklower * may be more than one packet per host.
6824265Ssklower */
6924265Ssklower bits = 1 << s;
7024265Ssklower bzero(¬ime, sizeof(notime));
7124265Ssklower signal(SIGALRM, timeout);
7224265Ssklower alarm(WTIME);
7324326Ssklower while (!timedout ||
7424265Ssklower select(20, &bits, 0, 0, ¬ime) > 0) {
7524265Ssklower struct nspacket {
7624265Ssklower struct idp hdr;
7724265Ssklower char data[512];
7824265Ssklower } response;
7924265Ssklower cc = recvfrom(s, &response, sizeof (response), 0,
8024265Ssklower &from, &fromlen);
8124265Ssklower if (cc <= 0) {
8224265Ssklower if (cc < 0) {
8324265Ssklower if (errno == EINTR)
8424265Ssklower continue;
8524265Ssklower perror("recvfrom");
8624265Ssklower (void) close(s);
8724265Ssklower exit(1);
8824265Ssklower }
8924265Ssklower continue;
9024265Ssklower }
9124265Ssklower rip_input(&from, response.data, cc);
9224265Ssklower count--;
9324265Ssklower }
9424265Ssklower }
9545667Ssklower static struct sockaddr_ns router = {sizeof(myaddr), AF_NS};
9626176Ssklower static struct ns_addr zero_addr;
9726176Ssklower static short allones[] = {-1, -1, -1};
9824265Ssklower
query(argv,argc)9924326Ssklower query(argv,argc)
10024326Ssklower char **argv;
10124265Ssklower {
10224265Ssklower register struct rip *msg = (struct rip *)packet;
10324326Ssklower char *host = *argv;
10445667Ssklower int flags = 0;
10526176Ssklower struct ns_addr specific;
10624265Ssklower
10745667Ssklower if (bcmp(*argv, "-r", 3) == 0) {
10845667Ssklower flags = MSG_DONTROUTE; argv++; argc--;
10945667Ssklower }
11045667Ssklower host = *argv;
11126176Ssklower router.sns_addr = ns_addr(host);
11224265Ssklower router.sns_addr.x_port = htons(IDPPORT_RIF);
11326176Ssklower if (ns_hosteq(zero_addr, router.sns_addr)) {
11426176Ssklower router.sns_addr.x_host = *(union ns_host *) allones;
11526176Ssklower }
11624265Ssklower msg->rip_cmd = htons(RIPCMD_REQUEST);
11726176Ssklower msg->rip_nets[0].rip_dst = *(union ns_net *) allones;
11824265Ssklower msg->rip_nets[0].rip_metric = htons(HOPCNT_INFINITY);
11924326Ssklower if (argc > 0) {
12026176Ssklower specific = ns_addr(*argv);
12126176Ssklower msg->rip_nets[0].rip_dst = specific.x_net;
12226176Ssklower specific.x_host = zero_addr.x_host;
12326176Ssklower specific.x_port = zero_addr.x_port;
12426176Ssklower printf("Net asked for was %s\n", ns_ntoa(specific));
12524326Ssklower }
12645667Ssklower if (sendto(s, packet, sizeof (struct rip), flags,
12724265Ssklower &router, sizeof(router)) < 0)
12824265Ssklower perror(host);
12924265Ssklower }
13024265Ssklower
13124265Ssklower /*
13224265Ssklower * Handle an incoming routing packet.
13324265Ssklower */
13424265Ssklower rip_input(from, msg, size)
13524265Ssklower struct sockaddr_ns *from;
13624265Ssklower register struct rip *msg;
13724265Ssklower int size;
13824265Ssklower {
13924265Ssklower struct netinfo *n;
14024265Ssklower char *name;
14124265Ssklower int lna, net, subnet;
14224265Ssklower struct hostent *hp;
14324265Ssklower struct netent *np;
14426176Ssklower static struct ns_addr work;
14524265Ssklower
14624265Ssklower if (htons(msg->rip_cmd) != RIPCMD_RESPONSE)
14724265Ssklower return;
14826176Ssklower printf("from %s\n", ns_ntoa(from->sns_addr));
14924265Ssklower size -= sizeof (struct idp);
15024265Ssklower size -= sizeof (short);
15124265Ssklower n = msg->rip_nets;
15224265Ssklower while (size > 0) {
15326176Ssklower union ns_net_u net;
15424265Ssklower if (size < sizeof (struct netinfo))
15524265Ssklower break;
15626176Ssklower net.net_e = n->rip_dst;
15726176Ssklower printf("\t%d, metric %d\n", ntohl(net.long_e),
15824265Ssklower ntohs(n->rip_metric));
15924265Ssklower size -= sizeof (struct netinfo), n++;
16024265Ssklower }
16124265Ssklower }
16224265Ssklower
timeout()16324265Ssklower timeout()
16424265Ssklower {
16524265Ssklower timedout = 1;
16624265Ssklower }
getsocket(type,proto)16724265Ssklower getsocket(type, proto)
16824265Ssklower int type, proto;
16924265Ssklower {
17024265Ssklower struct sockaddr_ns *sns = &myaddr;
17124265Ssklower int domain = sns->sns_family;
17224265Ssklower int retry, s, on = 1;
17324265Ssklower
17424265Ssklower retry = 1;
17524265Ssklower while ((s = socket(domain, type, proto)) < 0 && retry) {
17624265Ssklower perror("socket");
17724265Ssklower sleep(5 * retry);
17824265Ssklower retry <<= 1;
17924265Ssklower }
18024265Ssklower if (retry == 0)
18124265Ssklower return (-1);
18224265Ssklower while (bind(s, sns, sizeof (*sns), 0) < 0 && retry) {
18324265Ssklower perror("bind");
18424265Ssklower sleep(5 * retry);
18524265Ssklower retry <<= 1;
18624265Ssklower }
18724265Ssklower if (retry == 0)
18824265Ssklower return (-1);
18924265Ssklower if (domain==AF_NS) {
19024265Ssklower struct idp idp;
19124265Ssklower if (setsockopt(s, 0, SO_HEADERS_ON_INPUT, &on, sizeof(on))) {
19224265Ssklower perror("setsockopt SEE HEADERS");
19324265Ssklower exit(1);
19424265Ssklower }
19524265Ssklower idp.idp_pt = NSPROTO_RI;
19624265Ssklower if (setsockopt(s, 0, SO_DEFAULT_HEADERS, &idp, sizeof(idp))) {
19724265Ssklower perror("setsockopt SET HEADERS");
19824265Ssklower exit(1);
19924265Ssklower }
20024265Ssklower }
20124265Ssklower if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) {
20224265Ssklower perror("setsockopt SO_BROADCAST");
20324265Ssklower exit(1);
20424265Ssklower }
20524265Ssklower return (s);
20624265Ssklower }
207