"Fossies" - the Fresh Open Source Software Archive

Member "scanssh-2.1/exclude.c" (31 Mar 2004, 4949 Bytes) of package /linux/privat/old/scanssh-2.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /*
    2  * Copyright 2000 Niels Provos <provos@citi.umich.edu>
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  * 3. The name of the author may not be used to endorse or promote products
   14  *    derived from this software without specific prior written permission.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   26  */
   27 
   28 #include <sys/types.h>
   29 
   30 #ifdef HAVE_CONFIG_H
   31 #include "config.h"
   32 #endif
   33 
   34 #include <sys/queue.h>
   35 #include <sys/socket.h>
   36 #include <netinet/in.h>
   37 #include <arpa/inet.h>
   38 
   39 #include <stdio.h>
   40 #include <stdlib.h>
   41 #include <ctype.h>
   42 #include <netdb.h>
   43 #include <string.h>
   44 #include <err.h>
   45 
   46 #include <dnet.h>
   47 
   48 #include "exclude.h"
   49 
   50 char *excludefile = "exclude.list";
   51 struct exclude_list excludequeue;
   52 struct exclude_list rndexclqueue;
   53 
   54 #define RNDSBOXSIZE 128
   55 #define RNDSBOXSHIFT    7
   56 #define RNDROUNDS   32
   57 
   58 uint32_t rndsbox[RNDSBOXSIZE];
   59 
   60 char *unusednets[] = {
   61     "127.0.0.0/8",      /* local */
   62     "10.0.0.0/8",       /* rfc-1918 */
   63     "172.16.0.0/12",    /* rfc-1918 */
   64     "192.168.0.0/16",   /* rfc-1918 */
   65     "224.0.0.0/4",      /* rfc-1112 */
   66     "240.0.0.0/4",
   67     "0.0.0.0/8",
   68     "255.0.0.0/8",
   69     NULL
   70 };
   71 
   72 void
   73 rndsboxinit(uint32_t seed)
   74 {
   75     int i;
   76 
   77     /* We need repeatable random numbers here */
   78     srandom(seed);
   79     for (i = 0; i < RNDSBOXSIZE; i++) {
   80         rndsbox[i] = random();
   81     }
   82 }
   83 
   84 /*
   85  * We receive the prefix in host-order.
   86  * Use a modifed TEA to create a permutation of 2^(32-bits)
   87  * elements.
   88  */
   89 
   90 uint32_t
   91 rndgetaddr(int bits, uint32_t count)
   92 {
   93     uint32_t sum = 0, mask, sboxmask;
   94     int i, left, right, kshift;
   95 
   96     if (bits == 32)
   97         return (0);
   98 
   99     left = (32 - bits) / 2;
  100     right = (32 - bits) - left;
  101 
  102     mask  = 0xffffffff >> bits;
  103     if (RNDSBOXSIZE < (1 << left)) {
  104         sboxmask = RNDSBOXSIZE - 1;
  105         kshift = RNDSBOXSHIFT;
  106     } else {
  107         sboxmask = (1 << left) - 1;
  108         kshift = left;
  109     }
  110 
  111     for (i = 0; i < RNDROUNDS; i++) {
  112         sum += 0x9e3779b9;
  113         count ^= rndsbox[(count^sum) & sboxmask]  << kshift;
  114         count += sum;
  115         count &= mask;
  116         count = ((count << left) | (count >> right)) & mask;
  117     }
  118 
  119     return (count);
  120 }
  121 
  122 void
  123 excludeinsert(struct addr *addr, struct exclude_list *queue)
  124 {
  125     struct exclude *entry;
  126 
  127     if ((entry = malloc(sizeof(*entry))) == NULL)
  128         err(1, "malloc");
  129 
  130     /* Set up the addresses; still IPv4 dependent */
  131     entry->e_net = *addr;
  132     TAILQ_INSERT_HEAD(queue, entry, e_next);
  133 }
  134 
  135 int
  136 setupexcludes(void)
  137 {
  138     FILE *stream;
  139     char line[BUFSIZ];
  140     size_t len;
  141     struct addr addr;
  142     int i;
  143 
  144     TAILQ_INIT(&excludequeue);
  145     TAILQ_INIT(&rndexclqueue);
  146 
  147     for (i = 0; unusednets[i]; i++) {
  148         if (addr_pton(unusednets[i], &addr) == -1)
  149             errx(1, "addr_pton for unused %s", unusednets[i]);
  150         excludeinsert(&addr, &rndexclqueue);
  151     }
  152 
  153     if ((stream = fopen(excludefile, "r")) == NULL)
  154         return (-1);
  155 
  156     while (fgets(line, sizeof(line), stream) != NULL) {
  157         len = strlen(line);
  158         if (line[len - 1] != '\n') {
  159             fprintf(stderr, "Ignoring line without newline\n");
  160             continue;
  161         }
  162         line[len - 1] = '\0';
  163         if (addr_pton(line, &addr) == -1) {
  164             fprintf(stderr, "Can't parse <%s> in exclude file.\n",
  165                 line);
  166             exit (1);
  167         }
  168         excludeinsert(&addr, &excludequeue);
  169     }
  170 
  171     fclose(stream);
  172 
  173     return (0);
  174 }
  175 
  176 struct addr
  177 exclude(struct addr address, struct exclude_list *queue)
  178 {
  179     struct addr addr_a, addr_aend;
  180     struct exclude *entry;
  181 
  182     /* Check for overflow */
  183     if (address.addr_ip == INADDR_ANY)
  184         return (address);
  185 
  186     TAILQ_FOREACH(entry, queue, e_next) {
  187         /* Set up the addresses; still IPv4 dependent */
  188         addr_a = entry->e_net;
  189         addr_a.addr_bits = IP_ADDR_BITS;
  190 
  191         addr_bcast(&entry->e_net, &addr_aend);
  192         addr_aend.addr_bits = IP_ADDR_BITS;
  193 
  194         if (addr_cmp(&address, &addr_a) >= 0 &&
  195             addr_cmp(&address, &addr_aend) <= 0) {
  196             /* Increment and check overflow */
  197             ip_addr_t ip = ntohl(addr_aend.addr_ip) + 1;
  198             address.addr_ip = htonl(ip);
  199             return (exclude(address, queue));
  200         }
  201     }
  202 
  203     return (address);
  204 }