summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ot_accesslist.c126
-rw-r--r--ot_accesslist.h42
2 files changed, 168 insertions, 0 deletions
diff --git a/ot_accesslist.c b/ot_accesslist.c
index cdf7731..4df7edb 100644
--- a/ot_accesslist.c
+++ b/ot_accesslist.c
@@ -143,6 +143,132 @@ void accesslist_deinit( void ) {
143} 143}
144#endif 144#endif
145 145
146int address_in_net( const ot_ip6 address, const ot_net *net ) {
147 int bits = net->bits;
148 int result = memcmp( address, &net->address, bits >> 3 );
149 if( !result && ( bits & 7 ) )
150 result = ( ( 0x7f00 >> ( bits & 7 ) ) & address[bits>>3] ) - net->address[bits>>3];
151 return result == 0;
152}
153
154void *set_value_for_net( const ot_net *net, ot_vector *vector, const void *value, const size_t member_size ) {
155 size_t i;
156 int exactmatch;
157
158 /* Caller must have a concept of ot_net in it's member */
159 if( member_size < sizeof(ot_net) )
160 return 0;
161
162 /* Check each net in vector for overlap */
163 uint8_t *member = ((uint8_t*)vector->data);
164 for( i=0; i<vector->size; ++i ) {
165 if( address_in_net( *(ot_ip6*)member, net ) ||
166 address_in_net( net->address, (ot_net*)member ) )
167 return 0;
168 member += member_size;
169 }
170
171 member = vector_find_or_insert( vector, (void*)net, member_size, sizeof(ot_net), &exactmatch );
172 if( member ) {
173 memcpy( member, net, sizeof(ot_net));
174 memcpy( member + sizeof(ot_net), value, member_size - sizeof(ot_net));
175 }
176
177 return member;
178}
179
180/* Takes a vector filled with { ot_net net, uint8_t[x] value };
181 Returns value associated with the net, or NULL if not found */
182void *get_value_for_net( const ot_ip6 address, const ot_vector *vector, const size_t member_size ) {
183 int exactmatch;
184 /* This binary search will return a pointer to the first non-containing network... */
185 ot_net *net = binary_search( address, vector->data, vector->size, member_size, sizeof(ot_ip6), &exactmatch );
186 if( !net )
187 return NULL;
188 /* ... so we'll need to move back one step unless we've exactly hit the first address in network */
189 if( !exactmatch && ( (void*)net > vector->data ) )
190 --net;
191 if( !address_in_net( address, net ) )
192 return NULL;
193 return (void*)net;
194}
195
196#ifdef WANT_FULLLOG_NETWORKS
197static ot_vector g_lognets_list;
198ot_log *g_logchain_first, *g_logchain_last;
199
200static pthread_mutex_t g_lognets_list_mutex = PTHREAD_MUTEX_INITIALIZER;
201void loglist_add_network( const ot_net *net ) {
202 pthread_mutex_lock(&g_lognets_list_mutex);
203 set_value_for_net( net, &g_lognets_list, NULL, sizeof(ot_net));
204 pthread_mutex_unlock(&g_lognets_list_mutex);
205}
206
207void loglist_reset( ) {
208 pthread_mutex_lock(&g_lognets_list_mutex);
209 free( g_lognets_list.data );
210 g_lognets_list.data = 0;
211 g_lognets_list.size = g_lognets_list.space = 0;
212 pthread_mutex_unlock(&g_lognets_list_mutex);
213}
214
215int loglist_check_address( const ot_ip6 address ) {
216 int result;
217 pthread_mutex_lock(&g_lognets_list_mutex);
218 result = ( NULL != get_value_for_net( address, &g_lognets_list, sizeof(ot_net)) );
219 pthread_mutex_unlock(&g_lognets_list_mutex);
220 return result;
221}
222#endif
223
224#ifdef WANT_IP_FROM_PROXY
225typedef struct {
226 ot_net *proxy;
227 ot_vector networks;
228} ot_proxymap;
229
230static ot_vector g_proxies_list;
231static pthread_mutex_t g_proxies_list_mutex = PTHREAD_MUTEX_INITIALIZER;
232
233int proxylist_add_network( const ot_net *proxy, const ot_net *net ) {
234 ot_proxymap *map;
235 int exactmatch, result = 1;
236 pthread_mutex_lock(&g_proxies_list_mutex);
237
238 /* If we have a direct hit, use and extend the vector there */
239 map = binary_search( proxy, g_proxies_list.data, g_proxies_list.size, sizeof(ot_proxymap), sizeof(ot_net), &exactmatch );
240
241 if( !map || !exactmatch ) {
242 /* else see, if we've got overlapping networks
243 and get a new empty vector if not */
244 ot_vector empty;
245 memset( &empty, 0, sizeof( ot_vector ) );
246 map = set_value_for_net( proxy, &g_proxies_list, &empty, sizeof(ot_proxymap));
247 }
248
249 if( map && set_value_for_net( net, &map->networks, NULL, sizeof(ot_net) ) )
250 result = 1;
251
252 pthread_mutex_unlock(&g_proxies_list_mutex);
253 return result;
254}
255
256int proxylist_check_proxy( const ot_ip6 proxy, const ot_ip6 address ) {
257 int result = 0;
258 ot_proxymap *map;
259
260 pthread_mutex_lock(&g_proxies_list_mutex);
261
262 if( ( map = get_value_for_net( proxy, &g_proxies_list, sizeof(ot_proxymap) ) ) )
263 if( !address || get_value_for_net( address, &map->networks, sizeof(ot_net) ) )
264 result = 1;
265
266 pthread_mutex_unlock(&g_proxies_list_mutex);
267 return result;
268}
269
270#endif
271
146static ot_ip6 g_adminip_addresses[OT_ADMINIP_MAX]; 272static ot_ip6 g_adminip_addresses[OT_ADMINIP_MAX];
147static ot_permissions g_adminip_permissions[OT_ADMINIP_MAX]; 273static ot_permissions g_adminip_permissions[OT_ADMINIP_MAX];
148static unsigned int g_adminip_count = 0; 274static unsigned int g_adminip_count = 0;
diff --git a/ot_accesslist.h b/ot_accesslist.h
index 5954a4a..a1e4ad2 100644
--- a/ot_accesslist.h
+++ b/ot_accesslist.h
@@ -24,6 +24,48 @@ extern char *g_accesslist_filename;
24#define accesslist_hashisvalid( hash ) 1 24#define accesslist_hashisvalid( hash ) 1
25#endif 25#endif
26 26
27/* Test if an address is subset of an ot_net, return value is considered a bool */
28int address_in_net( const ot_ip6 address, const ot_net *net );
29
30/* Store a value into a vector of struct { ot_net net, uint8_t[x] value } member;
31 returns NULL
32 if member_size is too small, or
33 if one of the nets inside the vector are a subnet of _net_, or
34 if _net_ is a subnet of one of the nets inside the vector, or
35 if the vector could not be resized
36 returns pointer to new member in vector for success
37 member_size can be sizeof(ot_net) to reduce the lookup to a boolean mapping
38*/
39void *set_value_for_net( const ot_net *net, ot_vector *vector, const void *value, const size_t member_size );
40
41/* Takes a vector filled with struct { ot_net net, uint8_t[x] value } member;
42 Returns pointer to _member_ associated with the net, or NULL if not found
43 member_size can be sizeof(ot_net) to reduce the lookup to a boolean mapping
44*/
45void *get_value_for_net( const ot_ip6 address, const ot_vector *vector, const size_t member_size );
46
47
48#ifdef WANT_IP_FROM_PROXY
49int proxylist_add_network( const ot_net *proxy, const ot_net *net );
50int proxylist_check_network( const ot_ip6 *proxy, const ot_ip6 address /* can be NULL to only check proxy */ );
51#endif
52
53#ifdef WANT_FULLLOG_NETWORKS
54typedef struct ot_log ot_log;
55struct ot_log {
56 ot_ip6 ip;
57 uint8_t *data;
58 size_t size;
59 ot_time time;
60 ot_log *next;
61};
62extern ot_log *g_logchain_first, *g_logchain_last;
63
64void loglist_add_network( const ot_net *net );
65void loglist_reset( );
66int loglist_check_address( const ot_ip6 address );
67#endif
68
27typedef enum { 69typedef enum {
28 OT_PERMISSION_MAY_FULLSCRAPE = 0x1, 70 OT_PERMISSION_MAY_FULLSCRAPE = 0x1,
29 OT_PERMISSION_MAY_STAT = 0x2, 71 OT_PERMISSION_MAY_STAT = 0x2,