Logo Search packages:      
Sourcecode: netams version File versions  Download package

p_prefix.c

/*************************************************************************
***   Authentication, authorization, accounting + firewalling package
***   Copyright 1998-2002 Anton Vinokurov <anton@netams.com>
***   Copyright 2002-2008 NeTAMS Development Team
***   This code is GPL v3
***   For latest version and more info, visit this project web page
***   located at http://www.netams.com
***
*************************************************************************/
/* $Id: p_prefix.c,v 1.44 2008-02-23 08:35:02 anton Exp $ */

#include "netams.h"
#include "iptree.h"

/////////////////////////////////////////////////////////////////////////////////////////////
PrefixFile::PrefixFile(){
      list=NULL;
      filename=NULL;
      num_prefixes=0;
      descriptor=NULL;
      ptree=new PrefixTree;
      netams_rwlock_init(&rwlock, NULL);
      //    printf("PrefixFile constructor: this=%p\n", this);
}
/////////////////////////////////////////////////////////////////////////////////////////////
PrefixFile::~PrefixFile(){
      if(list) this->Unload();
        delete ptree;
      netams_rwlock_destroy(&rwlock);
      aFree(filename);
}
/////////////////////////////////////////////////////////////////////////////////////////////
int PrefixFile::Load(char *f){
      char *tmp=set_string(f);
      if (filename) aFree(filename);
      filename=tmp;
      descriptor=fopen(filename, "r");
      if (!descriptor) { aLog(D_ERR, "unable to open prefix file: %s\n", strerror(errno)); return -1; }

      char buf[64], *addr;
      u_char mask;
      struct in_addr ia;
      unsigned i=0;
#ifdef DEBUG
      char buffer[32];
#endif
      
      netams_rwlock_wrlock(&rwlock);
      
      while (!feof(descriptor)){
            addr=fgets(buf, 63, descriptor);
            if(!addr) continue;     
            if(addr[0]=='#') addr++;
            if(addr[0]=='!') addr++;
            if(buf[0]!='#' && !isdigit(addr[0])) continue;
            num_prefixes++;
      }
      rewind(descriptor);
      
      list=(net_prefix*)aMalloc(sizeof(net_prefix)*(num_prefixes));

      while (!feof(descriptor) && i<num_prefixes){
            addr=fgets(buf, 63, descriptor);
            if(!addr) continue;
            
            list[i].flags=0;

            if(addr[0]=='#') {
                  list[i].flags|=PREFIX_COMMENTED;
                  addr++;
            }
            if(addr[0]=='!') {
                  list[i].flags|=PREFIX_INVERTED;
                  addr++;
            }
            if(!isdigit(addr[0])) continue;

            mask=getAddr(addr, &ia);

            list[i].network.s_addr=ia.s_addr;
            list[i].mask=mask;
            list[i].match=0;
            if(!(list[i].flags&PREFIX_COMMENTED)) ptree->prefix2tree(&list[i]);

#ifdef DEBUG
            aDebug(DEBUG_IPTREE, "i=%4u buf=%s%s%s/%u\n", i, 
                        (list[i].flags&PREFIX_COMMENTED)?"#":"",
                        (list[i].flags&PREFIX_INVERTED)?"!":"",
                        inet_ntop(AF_INET, &ia, buffer, 32), mask);
#endif
            i++;  
      }
      netams_rwlock_unlock(&rwlock);
      
      aLog(D_INFO, "%u prefixes from %s read ok, starting %p\n", i, filename, list); 
      aLog(D_INFO, "PrefixTree: %lu nodes [%u] + %lu dynamic links [%u] allocated, %lu bytes used\n",ptree->nodes,sizeof(IPTree_node),ptree->dlink,256*sizeof(IPTree_node*),ptree->nodes*sizeof(IPTree_node)+ptree->dlink*256*sizeof(IPTree_node*));
      fclose(descriptor);
      descriptor=NULL;
      return 0;
}
/////////////////////////////////////////////////////////////////////////////////////////////
void PrefixFile::Unload(){

      aLog(D_INFO, "%u prefixes from %s closed\n", num_prefixes, filename); 
      netams_rwlock_wrlock(&rwlock);
      ptree->freetree(ptree->root);
      aFree(list);
      list=NULL;
      netams_rwlock_unlock(&rwlock);
      num_prefixes=0;
}
/////////////////////////////////////////////////////////////////////////////////////////////
u_char PrefixFile::Check(unsigned addr){
      u_char mf=0;

      if(!ptree->root) return 0;
      netams_rwlock_rdlock(&rwlock);
      if(ptree->checktree(addr)) mf=1;
      netams_rwlock_unlock(&rwlock);
      return mf;
}
/////////////////////////////////////////////////////////////////////////////////////////////
void PrefixFile::Dump(struct cli_def *cli){
      net_prefix *p;

      cli_print(cli, "prefix file %s, total %u entries", filename, num_prefixes);

      char buffer[32];
      netams_rwlock_rdlock(&rwlock);

      for (unsigned i=0; i<num_prefixes; i++) {
            p=&list[i];
            cli_print(cli, "prefix %05u %s%s%s/%u %llu", i, 
                  (p->flags&PREFIX_COMMENTED)?"#":"",
                  (p->flags&PREFIX_INVERTED)?"!":"",
                  inet_ntop(AF_INET, &p->network, buffer, 32), p->mask, p->match);
      }
      netams_rwlock_unlock(&rwlock);
}
/////////////////////////////////////////////////////////////////////////////////////////////
void PrefixFile::Do(struct cli_def *cli, char *action){
      if (STREQ(action, "reload")) { 
            Unload(); 
            Load(filename); 
      }
      else if (STREQ(action, "save")) Save(cli);
      else if (STREQ(action, "dump")) Dump(cli); 
      else if (STREQ(action, "unload")) Unload(); 
      else if (STREQ(action, "zeromatch")) {
            netams_rwlock_wrlock(&rwlock);
            for (unsigned i=0; i<num_prefixes; i++)
                  list[i].match=0;
            netams_rwlock_unlock(&rwlock);
            cli_error(cli, "all prefixes match set to zero");
      }
      else
            cli_error(cli, "unknown 'do' action requested: '%s'", action);
}
/////////////////////////////////////////////////////////////////////////////////////////////
void PrefixFile::Save(struct cli_def *cli){
      if(!ptree->root) {
            cli_error(cli, "nothing to save: ip tree is empty");
            return;
      }
      descriptor=fopen(filename, "w");
      if (!descriptor) {
            aLog(D_ERR, "unable to open prefix file %s: %s!\n",filename,strerror(errno)); 
            return;
      }
      rewind(descriptor);
      net_prefix *p;

      char buffer[32];
      netams_rwlock_rdlock(&rwlock);

      for (unsigned i=0; i<num_prefixes; i++){
            p=&list[i];
            fprintf(descriptor, "%s%s%s/%u\n", 
                  (p->flags&PREFIX_COMMENTED)?"#":"",
                  (p->flags&PREFIX_INVERTED)?"!":"",
                  inet_ntop(AF_INET, &p->network, buffer, 32), p->mask);
      }
      netams_rwlock_unlock(&rwlock);
      
      fflush(descriptor);
      fclose(descriptor);
      cli_error(cli, "%u prefixes saved to %s(%p)", num_prefixes, filename, descriptor);
}
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////

Generated by  Doxygen 1.6.0   Back to index