"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. For more information about "exclude.c" see the Fossies "Dox" file reference documentation.

    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 }