aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin/XNSrouted/tools/query.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/XNSrouted/tools/query.c')
-rw-r--r--usr.sbin/XNSrouted/tools/query.c232
1 files changed, 232 insertions, 0 deletions
diff --git a/usr.sbin/XNSrouted/tools/query.c b/usr.sbin/XNSrouted/tools/query.c
new file mode 100644
index 000000000000..2e6374d1f63f
--- /dev/null
+++ b/usr.sbin/XNSrouted/tools/query.c
@@ -0,0 +1,232 @@
+/*-
+ * Copyright (c) 1983, 1986 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code includes software contributed to Berkeley by
+ * Bill Nesheim at Cornell University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1983, 1986 The Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)query.c 5.8 (Berkeley) 4/16/91";
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <netns/ns.h>
+#include <netns/idp.h>
+#include <errno.h>
+#include <stdio.h>
+#include <netdb.h>
+#include "../protocol.h"
+#define IDPPORT_RIF 1
+
+#define WTIME 5 /* Time to wait for responses */
+
+int s;
+int timedout, timeout();
+char packet[MAXPACKETSIZE];
+extern int errno;
+struct sockaddr_ns myaddr = {sizeof(myaddr), AF_NS};
+char *ns_ntoa();
+struct ns_addr ns_addr();
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ int cc, count, bits;
+ struct sockaddr from;
+ int fromlen = sizeof(from);
+ struct timeval notime;
+
+ if (argc < 2) {
+ printf("usage: query hosts...\n");
+ exit(1);
+ }
+ s = getsocket(SOCK_DGRAM, 0);
+ if (s < 0) {
+ perror("socket");
+ exit(2);
+ }
+
+ argv++, argc--;
+ query(argv,argc);
+
+ /*
+ * Listen for returning packets;
+ * may be more than one packet per host.
+ */
+ bits = 1 << s;
+ bzero(&notime, sizeof(notime));
+ signal(SIGALRM, timeout);
+ alarm(WTIME);
+ while (!timedout ||
+ select(20, &bits, 0, 0, &notime) > 0) {
+ struct nspacket {
+ struct idp hdr;
+ char data[512];
+ } response;
+ cc = recvfrom(s, &response, sizeof (response), 0,
+ &from, &fromlen);
+ if (cc <= 0) {
+ if (cc < 0) {
+ if (errno == EINTR)
+ continue;
+ perror("recvfrom");
+ (void) close(s);
+ exit(1);
+ }
+ continue;
+ }
+ rip_input(&from, response.data, cc);
+ count--;
+ }
+}
+static struct sockaddr_ns router = {sizeof(myaddr), AF_NS};
+static struct ns_addr zero_addr;
+static short allones[] = {-1, -1, -1};
+
+query(argv,argc)
+char **argv;
+{
+ register struct rip *msg = (struct rip *)packet;
+ char *host = *argv;
+ int flags = 0;
+ struct ns_addr specific;
+
+ if (bcmp(*argv, "-r", 3) == 0) {
+ flags = MSG_DONTROUTE; argv++; argc--;
+ }
+ host = *argv;
+ router.sns_addr = ns_addr(host);
+ router.sns_addr.x_port = htons(IDPPORT_RIF);
+ if (ns_hosteq(zero_addr, router.sns_addr)) {
+ router.sns_addr.x_host = *(union ns_host *) allones;
+ }
+ msg->rip_cmd = htons(RIPCMD_REQUEST);
+ msg->rip_nets[0].rip_dst = *(union ns_net *) allones;
+ msg->rip_nets[0].rip_metric = htons(HOPCNT_INFINITY);
+ if (argc > 0) {
+ specific = ns_addr(*argv);
+ msg->rip_nets[0].rip_dst = specific.x_net;
+ specific.x_host = zero_addr.x_host;
+ specific.x_port = zero_addr.x_port;
+ printf("Net asked for was %s\n", ns_ntoa(specific));
+ }
+ if (sendto(s, packet, sizeof (struct rip), flags,
+ &router, sizeof(router)) < 0)
+ perror(host);
+}
+
+/*
+ * Handle an incoming routing packet.
+ */
+rip_input(from, msg, size)
+ struct sockaddr_ns *from;
+ register struct rip *msg;
+ int size;
+{
+ struct netinfo *n;
+ char *name;
+ int lna, net, subnet;
+ struct hostent *hp;
+ struct netent *np;
+ static struct ns_addr work;
+
+ if (htons(msg->rip_cmd) != RIPCMD_RESPONSE)
+ return;
+ printf("from %s\n", ns_ntoa(from->sns_addr));
+ size -= sizeof (struct idp);
+ size -= sizeof (short);
+ n = msg->rip_nets;
+ while (size > 0) {
+ union ns_net_u net;
+ if (size < sizeof (struct netinfo))
+ break;
+ net.net_e = n->rip_dst;
+ printf("\t%d, metric %d\n", ntohl(net.long_e),
+ ntohs(n->rip_metric));
+ size -= sizeof (struct netinfo), n++;
+ }
+}
+
+timeout()
+{
+ timedout = 1;
+}
+getsocket(type, proto)
+ int type, proto;
+{
+ struct sockaddr_ns *sns = &myaddr;
+ int domain = sns->sns_family;
+ int retry, s, on = 1;
+
+ retry = 1;
+ while ((s = socket(domain, type, proto)) < 0 && retry) {
+ perror("socket");
+ sleep(5 * retry);
+ retry <<= 1;
+ }
+ if (retry == 0)
+ return (-1);
+ while (bind(s, sns, sizeof (*sns), 0) < 0 && retry) {
+ perror("bind");
+ sleep(5 * retry);
+ retry <<= 1;
+ }
+ if (retry == 0)
+ return (-1);
+ if (domain==AF_NS) {
+ struct idp idp;
+ if (setsockopt(s, 0, SO_HEADERS_ON_INPUT, &on, sizeof(on))) {
+ perror("setsockopt SEE HEADERS");
+ exit(1);
+ }
+ idp.idp_pt = NSPROTO_RI;
+ if (setsockopt(s, 0, SO_DEFAULT_HEADERS, &idp, sizeof(idp))) {
+ perror("setsockopt SET HEADERS");
+ exit(1);
+ }
+ }
+ if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) {
+ perror("setsockopt SO_BROADCAST");
+ exit(1);
+ }
+ return (s);
+}