pfd_config.c

Go to the documentation of this file.
00001 /*
00002  * $Id: pfd_config.c 346460 2009-11-14 05:06:47Z ssiano $
00003  *
00004  * This code is provided as is by Juniper Networks SDK Developer Support.
00005  * It is provided with no warranties or guarantees, and Juniper Networks
00006  * will not provide support or maintenance of this code in any fashion.
00007  * The code is provided only to help a developer better understand how
00008  * the SDK can be used.
00009  *
00010  * Copyright (c) 2007-2008, Juniper Networks, Inc.
00011  * All rights reserved.
00012  */
00013 
00023 #include <string.h>
00024 #include <pthread.h>
00025 #include <jnx/atomic.h>
00026 #include "pfd_config.h"
00027 #include "pfd_logging.h"
00028 
00029 /*** Constants ***/
00030 
00031 
00032 /*** Data structures: ***/
00033 
00034 /*
00035  * These are maintained as a fast pre-filter sort of like counting filters.
00036  * Indexes are the bytes in the 1st, 2nd, 3rd, and 4th authorized address.
00037  * Values are the counters for number of authorized user addresses that contain
00038  * the index's value.
00039  * 
00040  * so first_byte[i] = j <=> 
00041  *    address pattern i.*.*.* appears in j authorized users' addresses
00042  */
00043 static uint32_t first_byte [256]; 
00044 static uint32_t second_byte[256]; 
00045 static uint32_t third_byte [256]; 
00046 static uint32_t fourth_byte[256]; 
00047 
00048 static in_addr_t pfd_address;  
00049 static in_addr_t cpd_address;  
00050 
00051 static patroot root; 
00052 static pthread_rwlock_t config_lock; 
00053 
00054 /*
00055  * Multiple dataloop threads will access this PATRICIA Tree for reading, and 
00056  * the mgmt thread will do some writing.
00057  * 
00058  * Only the mgmt thread reads and writes to the pfd/cpd addresses.
00059  * These get passed to the threads in a messaging fashion instead.
00060  */
00061 
00066 static atomic_uint_t current_time;
00067 
00068 /*** STATIC/INTERNAL Functions ***/
00069 
00074 PATNODE_TO_STRUCT(data_entry, pfd_auth_user_t, node)
00075 
00076 
00077 
00092 static void
00093 update_time(evContext ctx __unused,
00094             void * uap  __unused,
00095             struct timespec due __unused,
00096             struct timespec inter __unused)
00097 {
00098     atomic_add_uint(1, &current_time);
00099 }
00100 
00101 /*** GLOBAL/EXTERNAL Functions ***/
00102 
00103 
00114 status_t
00115 init_config(evContext ctx)
00116 {
00117     patricia_root_init(&root, FALSE, sizeof(in_addr_t), 0);
00118                    // root, is key ptr, key size, key offset
00119     
00120     pthread_rwlock_init(&config_lock, NULL);
00121 
00122     bzero(&first_byte, sizeof(first_byte));
00123     bzero(&second_byte, sizeof(second_byte));
00124     bzero(&third_byte, sizeof(third_byte));
00125     bzero(&fourth_byte, sizeof(fourth_byte));
00126     
00127     pfd_address = 0;
00128     cpd_address = 0;
00129     
00130     current_time = (atomic_uint_t)(time(NULL) - 1);
00131     
00132     // cached system time
00133     if(evSetTimer(ctx, update_time, NULL,
00134         evNowTime(), evConsTime(1, 0), NULL)) {
00135 
00136         LOG(LOG_EMERG, "%s: Failed to initialize an eventlib timer to generate "
00137             "the cached time", __func__);
00138         return EFAIL;
00139     }
00140     
00141     return SUCCESS;
00142 }
00143 
00147 void
00148 clear_config(void)
00149 {
00150     patnode * node = NULL;
00151     pfd_auth_user_t * auth_user = NULL;
00152     
00153     pthread_rwlock_wrlock(&config_lock);
00154     
00155     while((node = patricia_find_next(&root, NULL)) != NULL) {
00156 
00157         auth_user = data_entry(node);
00158 
00159         if (!patricia_delete(&root, node)) {
00160             LOG(LOG_ERR, "%s: patricia delete failed", __func__);
00161         }
00162 
00163         if(auth_user) {
00164             free(auth_user);
00165         }
00166     }
00167     
00168     bzero(&first_byte, sizeof(first_byte));
00169     bzero(&second_byte, sizeof(second_byte));
00170     bzero(&third_byte, sizeof(third_byte));
00171     bzero(&fourth_byte, sizeof(fourth_byte));
00172     
00173     pthread_rwlock_unlock(&config_lock);
00174 }
00175 
00176 
00183 void
00184 add_auth_user_addr(in_addr_t addr)
00185 {
00186     pfd_auth_user_t * auth_user;
00187     const uint8_t const * byte = (const uint8_t const *)&addr;
00188     
00189     auth_user = calloc(1, sizeof(pfd_auth_user_t));
00190     auth_user->address = addr; 
00191     
00192     /* add to data_root patricia tree */
00193     patricia_node_init_length(&auth_user->node, sizeof(in_addr_t));
00194 
00195     pthread_rwlock_wrlock(&config_lock);
00196     
00197     if (!patricia_add(&root, &auth_user->node)) {
00198         LOG(LOG_ERR, "%s: patricia_add failed", __func__);
00199         free(auth_user);
00200         pthread_rwlock_unlock(&config_lock);
00201         return;
00202     }
00203     
00204     // build pre-filter arrays
00205     ++first_byte[byte[0]];
00206     ++second_byte[byte[1]];
00207     ++third_byte[byte[2]];
00208     ++fourth_byte[byte[3]];
00209     
00210     pthread_rwlock_unlock(&config_lock);
00211 }
00212 
00213 
00220 void
00221 delete_auth_user_addr(in_addr_t addr)
00222 {
00223     patnode * node = NULL;
00224     pfd_auth_user_t * auth_user = NULL;
00225     const uint8_t const * byte = (const uint8_t const *)&addr;
00226     
00227     pthread_rwlock_wrlock(&config_lock);
00228         
00229     node = patricia_get(&root, sizeof(in_addr_t), &addr);
00230     
00231     if (node == NULL) {
00232         LOG(LOG_NOTICE, "%s: called with a user's that is already not "
00233             "authorized", __func__);
00234         pthread_rwlock_unlock(&config_lock);
00235         return;
00236     }
00237     
00238     auth_user = data_entry(node);
00239     
00240     if (!patricia_delete(&root, node)) {
00241         LOG(LOG_ERR, "%s: patricia delete failed", __func__);
00242         pthread_rwlock_unlock(&config_lock);
00243         return;
00244     }
00245     
00246     if(auth_user) {
00247         free(auth_user);
00248     }
00249     
00250     // build pre-filter arrays
00251     --first_byte[byte[0]];
00252     --second_byte[byte[1]];
00253     --third_byte[byte[2]];
00254     --fourth_byte[byte[3]];
00255     
00256     pthread_rwlock_unlock(&config_lock);
00257 }
00258 
00259 
00268 boolean
00269 is_auth_user(in_addr_t addr)
00270 {
00271     const uint8_t const * byte = (const uint8_t const *)&addr;
00272     patnode * p = NULL;
00273     
00274     pthread_rwlock_rdlock(&config_lock);
00275     
00276     // very fast and efficient pre-filter
00277     if(first_byte[byte[0]] && second_byte[byte[1]] &&
00278        third_byte[byte[2]] && fourth_byte[byte[3]]) {
00279         
00280         p = patricia_get(&root, sizeof(in_addr_t), &addr);
00281     }
00282     
00283     pthread_rwlock_unlock(&config_lock);
00284     
00285     return (p != NULL);
00286 }
00287 
00288 
00295 in_addr_t
00296 get_pfd_address(void)
00297 {
00298     return pfd_address;
00299 }
00300 
00301 
00308 void
00309 set_pfd_address(in_addr_t addr)
00310 {
00311     pfd_address = addr;
00312 }
00313 
00314 
00321 in_addr_t
00322 get_cpd_address(void)
00323 {
00324     return cpd_address;
00325 }
00326 
00327 
00334 void
00335 set_cpd_address(in_addr_t addr)
00336 {
00337     cpd_address = addr;
00338 }
00339 
00340 
00347 time_t
00348 get_current_time(void)
00349 {
00350     return (time_t)current_time;
00351 }

2007-2009 Juniper Networks, Inc. All rights reserved. The information contained herein is confidential information of Juniper Networks, Inc., and may not be used, disclosed, distributed, modified, or copied without the prior written consent of Juniper Networks, Inc. in an express license. This information is subject to change by Juniper Networks, Inc. Juniper Networks, the Juniper Networks logo, and JUNOS are registered trademarks of Juniper Networks, Inc. in the United States and other countries. All other trademarks, service marks, registered trademarks, or registered service marks are the property of their respective owners.
Generated on Sun May 30 20:27:07 2010 for SDK Your Net Corporation Policy Manager Example: Packet Filtering Daemon (pfd) 1.0 by Doxygen 1.5.1