"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 }