home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / sbin / XNSrouted / tools / query.c next >
Encoding:
C/C++ Source or Header  |  1991-04-16  |  6.1 KB  |  233 lines

  1. /*-
  2.  * Copyright (c) 1983, 1986 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * This code includes software contributed to Berkeley by
  6.  * Bill Nesheim at Cornell University.
  7.  *
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions
  10.  * are met:
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in the
  15.  *    documentation and/or other materials provided with the distribution.
  16.  * 3. All advertising materials mentioning features or use of this software
  17.  *    must display the following acknowledgement:
  18.  *    This product includes software developed by the University of
  19.  *    California, Berkeley and its contributors.
  20.  * 4. Neither the name of the University nor the names of its contributors
  21.  *    may be used to endorse or promote products derived from this software
  22.  *    without specific prior written permission.
  23.  *
  24.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  25.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  28.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  30.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  31.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  34.  * SUCH DAMAGE.
  35.  */
  36.  
  37. #ifndef lint
  38. char copyright[] =
  39. "@(#) Copyright (c) 1983, 1986 The Regents of the University of California.\n\
  40.  All rights reserved.\n";
  41. #endif /* not lint */
  42.  
  43. #ifndef lint
  44. static char sccsid[] = "@(#)query.c    5.8 (Berkeley) 4/16/91";
  45. #endif /* not lint */
  46.  
  47. #include <sys/param.h>
  48. #include <sys/protosw.h>
  49. #include <sys/socket.h>
  50. #include <sys/time.h>
  51. #include <netinet/in.h>
  52. #include <netns/ns.h>
  53. #include <netns/idp.h>
  54. #include <errno.h>
  55. #include <stdio.h>
  56. #include <netdb.h>
  57. #include "../protocol.h"
  58. #define IDPPORT_RIF 1
  59.  
  60. #define    WTIME    5        /* Time to wait for responses */
  61.  
  62. int    s;
  63. int    timedout, timeout();
  64. char    packet[MAXPACKETSIZE];
  65. extern int errno;
  66. struct sockaddr_ns    myaddr = {sizeof(myaddr), AF_NS};
  67. char *ns_ntoa();
  68. struct ns_addr ns_addr();
  69. main(argc, argv)
  70. int argc;
  71. char *argv[];
  72. {
  73.     int cc, count, bits;
  74.     struct sockaddr from;
  75.     int fromlen = sizeof(from);
  76.     struct timeval notime;
  77.     
  78.     if (argc < 2) {
  79.         printf("usage: query hosts...\n");
  80.         exit(1);
  81.     }
  82.     s = getsocket(SOCK_DGRAM, 0);
  83.     if (s < 0) {
  84.         perror("socket");
  85.         exit(2);
  86.     }
  87.  
  88.     argv++, argc--;
  89.     query(argv,argc);
  90.  
  91.     /*
  92.      * Listen for returning packets;
  93.      * may be more than one packet per host.
  94.      */
  95.     bits = 1 << s;
  96.     bzero(¬ime, sizeof(notime));
  97.     signal(SIGALRM, timeout);
  98.     alarm(WTIME);
  99.     while (!timedout || 
  100.         select(20, &bits, 0, 0, ¬ime) > 0) {
  101.         struct nspacket {
  102.             struct idp hdr;
  103.             char    data[512];
  104.         } response;
  105.         cc = recvfrom(s, &response, sizeof (response), 0,
  106.           &from, &fromlen);
  107.         if (cc <= 0) {
  108.             if (cc < 0) {
  109.                 if (errno == EINTR)
  110.                     continue;
  111.                 perror("recvfrom");
  112.                 (void) close(s);
  113.                 exit(1);
  114.             }
  115.             continue;
  116.         }
  117.         rip_input(&from, response.data, cc);
  118.         count--;
  119.     }
  120. }
  121. static struct sockaddr_ns router = {sizeof(myaddr), AF_NS};
  122. static struct ns_addr zero_addr;
  123. static short allones[] = {-1, -1, -1};
  124.  
  125. query(argv,argc)
  126. char **argv;
  127. {
  128.     register struct rip *msg = (struct rip *)packet;
  129.     char *host = *argv;
  130.     int flags = 0;
  131.     struct ns_addr specific;
  132.  
  133.     if (bcmp(*argv, "-r", 3) == 0) {
  134.         flags = MSG_DONTROUTE; argv++; argc--;
  135.     }
  136.     host = *argv;
  137.     router.sns_addr = ns_addr(host);
  138.     router.sns_addr.x_port = htons(IDPPORT_RIF);
  139.     if (ns_hosteq(zero_addr, router.sns_addr)) {
  140.         router.sns_addr.x_host = *(union ns_host *) allones;
  141.     }
  142.     msg->rip_cmd = htons(RIPCMD_REQUEST);
  143.     msg->rip_nets[0].rip_dst = *(union ns_net *) allones;
  144.     msg->rip_nets[0].rip_metric = htons(HOPCNT_INFINITY);
  145.     if (argc > 0) {
  146.         specific = ns_addr(*argv);
  147.         msg->rip_nets[0].rip_dst = specific.x_net;
  148.         specific.x_host = zero_addr.x_host;
  149.         specific.x_port = zero_addr.x_port;
  150.         printf("Net asked for was %s\n", ns_ntoa(specific));
  151.     }
  152.     if (sendto(s, packet, sizeof (struct rip), flags,
  153.       &router, sizeof(router)) < 0)
  154.         perror(host);
  155. }
  156.  
  157. /*
  158.  * Handle an incoming routing packet.
  159.  */
  160. rip_input(from, msg,  size)
  161.     struct sockaddr_ns *from;
  162.     register struct rip *msg;
  163.     int size;
  164. {
  165.     struct netinfo *n;
  166.     char *name;
  167.     int lna, net, subnet;
  168.     struct hostent *hp;
  169.     struct netent *np;
  170.     static struct ns_addr work;
  171.  
  172.     if (htons(msg->rip_cmd) != RIPCMD_RESPONSE)
  173.         return;
  174.     printf("from %s\n", ns_ntoa(from->sns_addr));
  175.     size -= sizeof (struct idp);
  176.     size -= sizeof (short);
  177.     n = msg->rip_nets;
  178.     while (size > 0) {
  179.         union ns_net_u net;
  180.         if (size < sizeof (struct netinfo))
  181.             break;
  182.         net.net_e = n->rip_dst;
  183.         printf("\t%d, metric %d\n", ntohl(net.long_e),
  184.             ntohs(n->rip_metric));
  185.         size -= sizeof (struct netinfo), n++;
  186.     }
  187. }
  188.  
  189. timeout()
  190. {
  191.     timedout = 1;
  192. }
  193. getsocket(type, proto)
  194.     int type, proto; 
  195. {
  196.     struct sockaddr_ns *sns = &myaddr;
  197.     int domain = sns->sns_family;
  198.     int retry, s, on = 1;
  199.  
  200.     retry = 1;
  201.     while ((s = socket(domain, type, proto)) < 0 && retry) {
  202.         perror("socket");
  203.         sleep(5 * retry);
  204.         retry <<= 1;
  205.     }
  206.     if (retry == 0)
  207.         return (-1);
  208.     while (bind(s, sns, sizeof (*sns), 0) < 0 && retry) {
  209.         perror("bind");
  210.         sleep(5 * retry);
  211.         retry <<= 1;
  212.     }
  213.     if (retry == 0)
  214.         return (-1);
  215.     if (domain==AF_NS) {
  216.         struct idp idp;
  217.         if (setsockopt(s, 0, SO_HEADERS_ON_INPUT, &on, sizeof(on))) {
  218.             perror("setsockopt SEE HEADERS");
  219.             exit(1);
  220.         }
  221.         idp.idp_pt = NSPROTO_RI;
  222.         if (setsockopt(s, 0, SO_DEFAULT_HEADERS, &idp, sizeof(idp))) {
  223.             perror("setsockopt SET HEADERS");
  224.             exit(1);
  225.         }
  226.     }
  227.     if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) {
  228.         perror("setsockopt SO_BROADCAST");
  229.         exit(1);
  230.     }
  231.     return (s);
  232. }
  233.