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

net_units.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: net_units.c,v 1.208 2009-08-01 09:23:54 anton Exp $*/

#include "netams.h"
#include "flow.h"
#include "attrlist.h"

const char *netunit_type_name[NETUNIT_TYPES_NUM]={ "unknown", "user", "host", "cluster", "net", "group" };

in_addr_t AutoAssignIP(struct cli_def *cli);

NetUnitsList *Units;
/////////////////////////////////////////////////////////////////////////
// NetUnit class
NetUnit::NetUnit(netunit_type t):Object() {
      name=NULL;
      type=t;

      description=NULL;

      ap=fp=NULL;

      ELIST_INIT(attrlist);
      ELIST_INIT(parents);
      ELIST_INIT(dslist);
      ELIST_INIT(monitors);

      sys_policy=SP_NONE;
      sys_policy_perm=0;

      logindata=NULL;
      quotadata=NULL;

      // for default unit set up we have no bandwidth
      bwi=NULL;

#ifdef HAVE_BILLING
      account=NULL;
#endif
      flags=0;

      email=password=NULL;
}

NetUnit::~NetUnit() {
     u_char *dsl;
     ELIST_FOR_EACH(dslist, dsl) {
      aFree(dsl);
     }
     ELIST_FREE(dslist);

      //remove reference to this unit, if it's target for policy
      if(flags&NETUNIT_POLICY_TARGET) PolicyL->DeleteUnitFromTarget(this);
#ifdef HAVE_BILLING
      if(account) account->AddUnit(this, REMOVE);
      else
#endif
      if(ap) delete ap;

      if(fp) delete fp;
      if(logindata) aFree(logindata);
      while(quotadata) {
            sQuotaData *tmp = quotadata;
            quotadata = quotadata->next;
            aFree(tmp);
      }

      ELIST_FREE(parents);
      ELIST_FREE(monitors);
      //clear attributes
      Attribute *a;
      ELIST_FOR_EACH(attrlist, a) {
            delete a;
      }
      ELIST_FREE(attrlist);

      if(name) aFree(name);
      if(description) aFree(description);
      if(bwi) aFree(bwi);
      if(email) aFree(email);
      if(password) aFree(password);
}

void NetUnit::setName(char *n){
      if(name) aFree(name);
      name=set_string(n);
      flags|=NETUNIT_CHANGED;
      sPConstructStoreOidMessage(this);
}

match NetUnit::Check(Flow *list){
      struct ipv4_info_value  *ipv4_info = (struct ipv4_info_value*)list->get(ATTR_IPV4_INFO);

      if(ipv4_info == NULL) {
            aLog(D_WARN, "No IPv4 attribute in NetUnit::Check\n");
            return MATCH_NONE;
      }

      return Check(ipv4_info->ip_src, ipv4_info->ip_dst);
}

void NetUnit::unit2trees(u_char flag) {
      Service *s=NULL;

    while((s=Services->getServiceNextByType(SERVICE_DATASOURCE,s))) {
            //we do not work with stopped data-sources
            if(this->checkDSList(s->instance)) {
                  unit2ds(s, flag);
            }
      }
      FW_CHECK_CHANGED(time(NULL));
}

void NetUnit::setDSList(u_char ds_id){
      u_char *dsl=(u_char*)aMalloc(sizeof(u_char));

      *dsl=ds_id;

      ELIST_ADD(dslist, dsl);
}

void NetUnit::clearDSList(u_char ds_id){
      u_char *dsl;

      ELIST_FOR_EACH(dslist, dsl) {
            if(*dsl == ds_id) {
                  ELIST_REMOVE(dslist, dsl);
                  aFree(dsl);
            }
      }
}

int NetUnit::checkDSList(u_char ds_id){
      if(!dslist) return 1;

      u_char *dsl;
      ELIST_FOR_EACH(dslist, dsl) {
            if(*dsl == ds_id)
                  return 1;
      }
      return 0;
}

void NetUnit::SetSysPolicy(SysPolicy sp, u_char flag, time_t now) {
      if(flag) sys_policy|=sp;
      else sys_policy&= ~ sp;
      if (now) FW_CHECK_CHANGED(now);

      Service *acl = Services->getServiceNextByType(SERVICE_ACL_SERVER, NULL);
      if (acl) acl->ProcessMessage(this);
      // printf(" -- %d -- %d -- \n", sys_policy, sp);
}

void NetUnit::ShowConfig(struct cli_def *cli, u_char show_flags) {
      policy_data *cpd;
      char tmp[32];

      cli_bufprint(cli, "unit %s oid %06X", netunit_type_name[type], id);
      if (name)
            SHOW_STR(cli, "name", name);
      //print attributes
      Attribute *a;
      char buf[128];
      ELIST_FOR_EACH(attrlist, a) {
            if(a->getAttr(buf)!=NULL)
                  cli_bufprint(cli," %s %s", a->name(), buf);
      }

      switch (type) {
            case NETUNIT_HOST: {
                  NetUnit_host *h = (NetUnit_host*)this;
                  cli_bufprint(cli, " ip %s", inet_ntop(AF_INET, &(h->ip), tmp, 32));
                  if (h->mac) cli_bufprint(cli, " mac %s", ether_ntoa(h->mac));
                  break;
            }
            case NETUNIT_CLUSTER: {
                  NetUnit_net *t;
                  NetUnit_cluster *h = (NetUnit_cluster*)this;
                  for (t=h->root; t!=NULL; t=t->next)
                        cli_bufprint(cli, " ip %s/%u",
                              inet_ntop(AF_INET, &(t->ip), tmp, 32), MASK2MLEN(t->mask));
                  break;
            }
            case NETUNIT_NET: {
                  NetUnit_net *t = (NetUnit_net*)this;
                  cli_bufprint(cli, " ip %s/%u",
                        inet_ntop(AF_INET, &(t->ip), tmp, 32), MASK2MLEN(t->mask));
                  if (t->auto_units_id) cli_bufprint(cli, " auto-units %u", t->auto_units_id);
                  break;
            }
            case NETUNIT_USER: {
                  NetUnit_user *u = (NetUnit_user*)this;
                  if(u->ip.s_addr!=0) cli_bufprint(cli, " ip %s", inet_ntop(AF_INET, &(u->ip), tmp, 32));
                  if (u->mac) cli_bufprint(cli, " mac %s", ether_ntoa(u->mac));
                  break;
            }
            default:
                  ;
      } //switch

      if(description)
            SHOW_STR(cli, "description", description);

      if (email)
            cli_bufprint(cli, " email %s", email);

      if (password)
            cli_bufprint(cli, " password %s", (show_flags&CFG_NO_PASSWORDS)?"***":password);

      //bw info
      if (bwi) {
            cli_bufprint(cli, " bw");
            getBW(bwi, cli);
      }

      if(!ELIST_IS_EMPTY(dslist)) {
            u_char *dsl;
            cli_bufprint(cli, " ds-list ");
            ELIST_FOR_EACH(dslist, dsl) {
                  if (dsl!=*dslist) cli_bufprint(cli, ",");
                  cli_bufprint(cli, "%u", *dsl);
            }
      }

      if(parents) {
            NetUnit_group *gr;
            cli_bufprint(cli, " parent");
            ELIST_FOR_EACH(parents, gr) {
                  cli_bufprint(cli, " ");
                  SHOW_OIDS(cli, show_flags, gr->name, gr->id);
            }
      }

      if (sys_policy!=SP_NONE) {
            //in config print only few sys_policies
            GetSysPolicy(cli, sys_policy&SP_DENY,sys_policy_perm);
      }
      if (flags&NETUNIT_NLP) cli_bufprint(cli, " no-local-pass");
      if (flags&NETUNIT_BACKUP_FW) cli_bufprint(cli, " backup-fw");

      if ((flags&NETUNIT_AP_NODEFAULT) && (flags&NETUNIT_FP_NODEFAULT))
            cli_bufprint(cli, " nodefault");
      else if ((flags&NETUNIT_AP_NODEFAULT) && !(flags&NETUNIT_FP_NODEFAULT))
            cli_bufprint(cli, " ap-nodefault");
      else if (!(flags&NETUNIT_AP_NODEFAULT) && (flags&NETUNIT_FP_NODEFAULT))
            cli_bufprint(cli, " fp-nodefault");

      if (ap
#ifdef HAVE_BILLING
      && !account
#endif
      ) {
            u_char header_printed=0, already_default;
            policy_data *cpx;

            for (cpd=ap->root; cpd!=NULL; cpd=cpd->next) {
                  already_default=0;
                  if (Processor->def && Processor->def->ap && !(flags&NETUNIT_AP_NODEFAULT)) {
                        for (cpx=Processor->def->ap->root; cpx!=NULL; cpx=cpx->next)
                              if (cpx->policy->id == cpd->policy->id
                              && cpx->policy_flags == cpd->policy_flags) {
                                    already_default=1;
                                    break;
                              }
                  }
                  if (!already_default) {
                        if (!header_printed) {
                              cli_bufprint(cli, " acct-policy");
                              header_printed=1;
                        }
                        cli_bufprint(cli, " %s%s",
                              (cpd->policy_flags&POLICY_FLAG_INV)?"!":"",
                              (cpd->policy_flags&POLICY_FLAG_BRK)?"%":"");
                        SHOW_OIDS(cli, show_flags, cpd->policy->name, cpd->policy->id);
                  }
            }
      }

      if (fp) {
            u_char header_printed=0, already_default;
            policy_data *cpx;

            for (cpd=fp->root; cpd!=NULL; cpd=cpd->next) {
                  already_default=0;
                  if (Processor->def && Processor->def->fp && !(flags&NETUNIT_FP_NODEFAULT)) {
                        for (cpx=Processor->def->fp->root; cpx!=NULL; cpx=cpx->next)
                              if (cpx->policy->id == cpd->policy->id
                              && cpx->policy_flags == cpd->policy_flags) {
                                    already_default=1;
                                    break;
                              }
                  }
                  if (!already_default) {
                        if (!header_printed) {
                              cli_bufprint(cli, " fw-policy");
                              header_printed=1;
                        }
                        cli_bufprint(cli, " %s%s",
                              (cpd->policy_flags&POLICY_FLAG_INV)?"!":"",
                              (cpd->policy_flags&POLICY_FLAG_BRK)?"%":"");
                        SHOW_OIDS(cli, show_flags , cpd->policy->name, cpd->policy->id);
                  }
            }
      }
      cli_bufprint(cli, "\n");
}
/////////////////////////////////////////////////////////////////////////
// NetUnitsList class
NetUnitsList::NetUnitsList():List(){
      groups=NULL;
}

NetUnitsList::~NetUnitsList(){
        ELIST_FREE(groups);
}

int NetUnitsList::Insert(NetUnit *u) {
      int res = ((List*)this)->Insert(u);

      if(res && u->type == NETUNIT_GROUP){
            netams_rwlock_wrlock(&rwlock);
            ELIST_ADD(groups, u);
            Units->SortGroups();
            netams_rwlock_unlock(&rwlock);
      }
      return res;
}

int NetUnitsList::Delete(NetUnit *u) {
      int res = ((List*)this)->Delete(u);

      if(res && u->type == NETUNIT_GROUP){
            netams_rwlock_wrlock(&rwlock);
            ELIST_REMOVE(groups, u);
            Units->SortGroups();
            netams_rwlock_unlock(&rwlock);
      }

      return res;
}

NetUnit* NetUnitsList::getUnit(char *name){
      NetUnit *d=NULL;

      if(!name) return NULL;

      netams_rwlock_rdlock(&rwlock);
      for(d=(NetUnit*)root; d!=NULL; d=(NetUnit*)d->next)
            if (STREQ(d->name, name)) break;
      netams_rwlock_unlock(&rwlock);

      if(!d && !strchr(name, '.')) {
            oid id=strtol(name, NULL, 16);
            d=(NetUnit*)getById(id);
      }
      return d;
}

NetUnit* NetUnitsList::getUnitByIP(in_addr_t s) {
      NetUnit *d=NULL;

      netams_rwlock_rdlock(&rwlock);
      for(d=(NetUnit*)root; d!=NULL; d=(NetUnit*)d->next) {
            if (d->type==NETUNIT_USER) {
                  NetUnit_user *du = (NetUnit_user*)d;
                  if (du->ip.s_addr==s) break;
            }
            if (d->type==NETUNIT_HOST) {
                  NetUnit_host *du = (NetUnit_host*)d;
                  if (du->ip.s_addr==s) break;
            }
      }
      netams_rwlock_unlock(&rwlock);
      return d;
}


void NetUnitsList::DeletePolicyElsewhere(Policy *p){
      NetUnit *d;
      policy_data *cpd;
      u_char del=0;

      netams_rwlock_wrlock(&rwlock);
      for (d=(NetUnit*)root; d!=NULL; d=(NetUnit*)d->next) {
            if(d->ap) {
                  for (cpd=d->ap->root; cpd!=NULL; cpd=cpd->next)
                        if (cpd->policy==p)
                              if(!d->ap->Delete(p)) {delete d->ap; d->ap=NULL;}
            }
            if(d->fp) {
                  for (cpd=d->fp->root; cpd!=NULL; cpd=cpd->next)
                        if (cpd->policy==p)
                              if(!d->fp->Delete(p)) {delete d->fp; d->fp=NULL; del++;}

            }
      }
      netams_rwlock_unlock(&rwlock);
      if(del) FW_CHECK_CHANGED(time(NULL));
}

void NetUnitsList::listPasswordsHtml(FILE *f){
      NetUnit *u;

      netams_rwlock_rdlock(&rwlock);
      for(u=(NetUnit*)root; u!=NULL; u=(NetUnit*)u->next)
            if (u->password)
                  fprintf(f, "%s:%s\n", u->name, crypt(u->password, "$1$"));
      netams_rwlock_unlock(&rwlock);
      return;
}

void NetUnit_group::SetGroupWeights(NetUnit_group *u, u_char weight) {
      NetUnit_group *gr;

      //set weights
      weight++;
      if (u->level<weight)
            u->level=weight;
      ELIST_FOR_EACH(u->parents, gr) {
            if(this == gr)
                  aLog(D_WARN, "NetUnit groups loop: start=%s loop=%s len=%u\n",
                         this->name, u->name, weight);
            else
                  SetGroupWeights(gr, weight);
      }
}

void NetUnitsList::SortGroups() {
      NetUnit_group *u, *up, *tmp;

      //clear weights
      ELIST_FOR_EACH(groups, u) {
            u->level=0;
      }

      //set weights
      ELIST_FOR_EACH(groups, u) {
            u->SetGroupWeights(u, 0);
      }

      //classical sort
      ELIST_FOR_EACH(groups, u) {
            ELIST_FOR_EACH(groups, up) {
                  if(u->level < up->level) {
                        //swap units
                        tmp=u;
                        u=up;
                        up=tmp;
                  }
            }
      }
}

void NetUnitsList::Unit2Group(NetUnit *u, NetUnit_group *g, u_char action) {

      netams_rwlock_wrlock(&rwlock);
      if(action==ADD) {
            ELIST_ADD(g->childrens, u);
            ELIST_ADD(u->parents, g);
            g->references++;
      } else { //remove
            ELIST_REMOVE(g->childrens, u);
            ELIST_REMOVE(u->parents, g);
            g->references--;
      }
      if(u->type == NETUNIT_GROUP) SortGroups();
      netams_rwlock_unlock(&rwlock);
}

void NetUnitsList::ShowConfig(struct cli_def *cli, u_char show_flags) {
      NetUnit *u;

      netams_rwlock_rdlock(&rwlock);
      //print groups first
      ELIST_FOR_EACH(groups, u) {
            u->ShowConfig(cli, show_flags);
      }

      for (u=(NetUnit*)root; u!=NULL; u=(NetUnit*)u->next) {
            if(u->type==NETUNIT_GROUP) continue;
            u->ShowConfig(cli, show_flags);
      }
      netams_rwlock_unlock(&rwlock);
}
/////////////////////////////////////////////////////////////////////////
// NetUnit_cluster class
NetUnit_cluster::NetUnit_cluster() : NetUnit(NETUNIT_CLUSTER) {
      root=NULL;
      references=0;
      netams_rwlock_init(&rwlock, NULL);
}

NetUnit_cluster::~NetUnit_cluster(){
      NetUnit *net;

      while(root) {
            net=root;
            root=root->next;
            delete net;
      }

      netams_rwlock_destroy(&rwlock);
}

void NetUnit_cluster::Add(struct in_addr ip, struct in_addr mask){
      netams_rwlock_wrlock(&rwlock);
      NetUnit_net *d;
      for(d=root; d!=NULL; d=d->next)
            if (d->ip.s_addr==ip.s_addr && d->mask.s_addr==mask.s_addr) {
                  netams_rwlock_unlock(&rwlock);
                  return;
            }

      d=new NetUnit_net();
      d->ip.s_addr=ip.s_addr;
      d->mask.s_addr=mask.s_addr;

      d->next=root;
      root=d;
      references++;
      netams_rwlock_unlock(&rwlock);
}

void NetUnit_cluster::Remove(struct in_addr ip, struct in_addr mask){
      NetUnit_net *d, *p=NULL;

      netams_rwlock_wrlock(&rwlock);
      for(d=root; d!=NULL; d=d->next)     {
            if (d->ip.s_addr==ip.s_addr && d->mask.s_addr==mask.s_addr) {
                  if (d==root) root=NULL;
                  else p->next=d->next;

                  references--;
                  delete d;
                  break;
            }
            p=d;
      }
      netams_rwlock_unlock(&rwlock);
}

match NetUnit_cluster::Check(in_addr src, in_addr dst) {
      match mf=MATCH_NONE;
      NetUnit_net *d;

      netams_rwlock_rdlock(&rwlock);
      for (d=root; d!=NULL; d=d->next) {
            mf|=d->Check(src, dst);
      }
      netams_rwlock_unlock(&rwlock);
      return mf;
}

int NetUnit_cluster::unit2ds(Service *ds, u_char flag) {
      Service_Datasource_Interface *handle = (Service_Datasource_Interface*)ds;

      for(NetUnit_net *h=root;h!=NULL;h=h->next)
            handle->unit2ds(h->ip.s_addr, MASK2MLEN(h->mask), (NetUnit*)this, flag);
      return 1;
}
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
// NetUnit_group class
NetUnit_group::NetUnit_group() : NetUnit(NETUNIT_GROUP){
      childrens = NULL;
      level = 0;
      references = 0;
}

NetUnit_group::~NetUnit_group() {
      ELIST_FREE(childrens);
}

match NetUnit_group::Check(in_addr src, in_addr dst) {
      match mf=MATCH_NONE;
      NetUnit *u;

      //we do not need locks here, because we depends on NetUnitsList lock
      ELIST_FOR_EACH(childrens, u){
            mf|=u->Check(src, dst);
      }

      return mf;
}

/////////////////////////////////////////////////////////////////////////
// NetUnit_host class
NetUnit_host::NetUnit_host() : NetUnit(NETUNIT_HOST) {
      ip.s_addr=0;
      mac=NULL;
}

NetUnit_host::~NetUnit_host() {
      if(mac) aFree(mac);
}

match NetUnit_host::Check(in_addr src, in_addr dst) {
      match mf=MATCH_NONE;

      if (ip.s_addr==src.s_addr) mf|=MATCH_SRC;
      if (ip.s_addr==dst.s_addr) mf|=MATCH_DST;

      return mf;
}

int NetUnit_host::unit2ds(Service *ds,u_char flag) {
      Service_Datasource_Interface *handle = (Service_Datasource_Interface*)ds;
      return handle->unit2ds(ip.s_addr, 32, (NetUnit*)this, flag);
}
/////////////////////////////////////////////////////////////////////////
NetUnit_net::NetUnit_net() : NetUnit(NETUNIT_NET) {
      ip.s_addr=0;
      mask.s_addr=INADDR_BROADCAST;
      auto_units_id=0;
}

match NetUnit_net::Check(in_addr src, in_addr dst){
      match mf=MATCH_NONE;

      if (ip.s_addr==(src.s_addr&mask.s_addr)) mf|=MATCH_SRC;
      if (ip.s_addr==(dst.s_addr&mask.s_addr)) mf|=MATCH_DST;

      return mf;
}

int NetUnit_net::unit2ds(Service *ds, u_char flag) {
      Service_Datasource_Interface *handle = (Service_Datasource_Interface*)ds;
      return handle->unit2ds(ip.s_addr, MASK2MLEN(mask), (NetUnit*)this, flag);
}
/////////////////////////////////////////////////////////////////////////
// NetUnit_user class
NetUnit_user::NetUnit_user() : NetUnit(NETUNIT_USER) {
        ip.s_addr=0;
      mac=NULL;
}

NetUnit_user::~NetUnit_user() {
      if(mac) aFree(mac);
}

match NetUnit_user::Check(in_addr src, in_addr dst) {
      match mf=MATCH_NONE;

      if (ip.s_addr==src.s_addr) mf|=MATCH_SRC;
      if (ip.s_addr==dst.s_addr) mf|=MATCH_DST;

      return mf;
}

int NetUnit_user::unit2ds(Service *ds, u_char flag) {
      if (ip.s_addr) {
            Service_Datasource_Interface *handle = (Service_Datasource_Interface*)ds;
            return handle->unit2ds(ip.s_addr, 32, (NetUnit*)this, flag);
      }
      return 0;
}
/////////////////////////////////////////////////////////////////////////
NetUnit* aParseUnit(char *param[], u_char *i, oid *uid) {
      NetUnit *u;

      if (!param[*i]) return NULL; // sanity check

      if (STRARG(param[*i], "name")) {
            u=Units->getUnit(param[(*i)+1]);
            if(u!=NULL)
                  (*i)+=2;
            return u;
      } else if (STRARG(param[*i], "oid")) {
            oid id = strtol(param[++(*i)], NULL, 16);
            u=(NetUnit*)Units->getById(id);
            if(uid!=NULL) *uid=id;
      } else {
            oid id = strtol(param[*i], NULL, 16);
            u=(NetUnit*)Units->getById(id);
            if(u==NULL)
                  u=Units->getUnit(param[*i]);
            else
                  if(uid!=NULL) *uid=id;
      }
      (*i)++;
      return u;
}

int cUnit(struct cli_def *cli, char **param, int argc, u_char no_flag){
      NetUnit *u;
      u_char i=2;
      u_char type=0;
      const char *type_name=NULL;
      oid id=0;
      char buffer[32];

      u=aParseUnit(param, &i, &id);

      for(u_char j=0;j<NETUNIT_TYPES_NUM;j++) {
            if (STREQ(param[1], netunit_type_name[j])) {
                  type=j;
                  type_name=netunit_type_name[type];
                  break;
            }
      }
      if(!type) return CLI_ERROR;

      NetUnit_host *host=(NetUnit_host*)u;
        NetUnit_user *user=(NetUnit_user*)u;
        NetUnit_net *net=(NetUnit_net*)u;
        NetUnit_cluster *cluster=(NetUnit_cluster*)u;
        NetUnit_group *group=(NetUnit_group*)u;

      if (!u && !no_flag) {
            switch(type) {
                  case NETUNIT_HOST:
                        host= new NetUnit_host();
                        u=(NetUnit*)host;
                        break;
                  case NETUNIT_USER:
                        user= new NetUnit_user();
                u=(NetUnit*)user;
                        break;
                  case NETUNIT_NET:
                        net= new NetUnit_net();
                        u=(NetUnit*)net;
                break;
                  case NETUNIT_GROUP:
                        group= new NetUnit_group();
                        u=(NetUnit*)group;
                break;
                  case NETUNIT_CLUSTER:
                        cluster= new NetUnit_cluster();
                        u=(NetUnit*)cluster;
                break;
                  default:
                        return PARSE_OK; // we already sure we have correct type
            }
            u->id=newOid(id);
            Units->Insert(u);
            cli_error(cli, "unit %s %06X created", type_name, u->id);

      } else if (!u && no_flag) {
            cli_error(cli, "unit %s does not exist", type_name);
            return CLI_OK;
      } else if (u && no_flag) {
            cli_error(cli, "unit %s %06X deleted", type_name, u->id);
            Units->Delete(u);
            if(u->type) u->unit2trees(REMOVE);
            delete u;
            return CLI_OK;
      }

      for(i=2; i<argc; i+=2) {
            no_flag=0;
            if (STREQ(param[i], "no")) {
                  no_flag=1;
                  i++;
            }

            if (strstr(param[i], "sys-")==param[i]) { // possibly sys-* here
                  SetSysPolicy(cli, u, param[i]);
                  i-=1;

            } else if (STREQ(param[i], "nodefault")) {
                  if (no_flag) {
                        u->flags&=~NETUNIT_AP_NODEFAULT;
                        u->flags&=~NETUNIT_FP_NODEFAULT;
                  }
                  else {
                        u->flags|=NETUNIT_AP_NODEFAULT;
                        u->flags|=NETUNIT_FP_NODEFAULT;
                  }
                  cli_error(cli, "%s %06X default policies will %sbe used", type_name, u->id, no_flag?"not ":"");
                  i-=1;

            } else if (STREQ(param[i], "ap-nodefault")) {
                  if (no_flag) u->flags&=~NETUNIT_AP_NODEFAULT;
                  else u->flags|=NETUNIT_AP_NODEFAULT;
                  cli_error(cli, "%s %06X default acct policies will %sbe used", type_name, u->id, no_flag?"not ":"");
                  i-=1;

            } else if (STREQ(param[i], "fp-nodefault")) {
                  if (no_flag) u->flags&=~NETUNIT_FP_NODEFAULT;
                  else u->flags|=NETUNIT_FP_NODEFAULT;
                  i-=1;

            } else if (STREQ(param[i], "acct-policy")) {
                  PolicyAdd(u, &i, POLICY_ACCT, cli, param, no_flag);

            } else if (STREQ(param[i], "fw-policy")) {
                  PolicyAdd(u, &i, POLICY_FW, cli, param, no_flag);

            } else if (STRARG(param[i], "ip")) {
                  u->unit2trees(REMOVE);
                  switch(type) {
                        case NETUNIT_CLUSTER:
                              struct in_addr addr, mask;
                              getAddr(param[i+1], &addr, &mask);

                    if(no_flag) cluster->Remove(addr, mask);
                              else cluster->Add(addr, mask);
                              break;
                        case NETUNIT_HOST:
                    if(no_flag)
                                    host->ip.s_addr=0;
                              else {
                                    if (STREQ(param[i+1], "auto")) {
                                          aFree(param[i+1]);
                                          host->ip.s_addr=AutoAssignIP(cli);
                                          inet_ntop(AF_INET, &(host->ip), buffer, 32);
                                          param[i+1]=set_string(buffer);
                                    }
                                    else inet_aton(param[i+1], &host->ip);
                              }
                              break;
                        case NETUNIT_USER:
                              if(no_flag)
                                    user->ip.s_addr=0;
                              else {
                                    if (STREQ(param[i+1], "auto")) {
                                          aFree(param[i+1]);
                                          user->ip.s_addr=AutoAssignIP(cli);
                                          inet_ntop(AF_INET, &(user->ip), buffer, 32);
                                          param[i+1]=set_string(buffer);
                                    }
                                          else inet_aton(param[i+1], &user->ip);
                              }
                              break;
                        case NETUNIT_NET:
                              if(no_flag) net->ip.s_addr=0;
                              else {
                                    getAddr(param[i+1], &net->ip, &net->mask);
                              }
                              break;
                        default:
                              cli_error(cli, "IP for %s not supported", type_name);
                              break;
                  }
                        u->unit2trees(ADD);
                        cli_error(cli, "%s %06X ip set: %s", type_name, u->id, param[i+1]);

            } else if (type == NETUNIT_NET && STRARG(param[i], "mask")) {
                u->unit2trees(REMOVE);
                inet_aton(param[i+1], &net->mask);
                        net->ip.s_addr&=net->mask.s_addr; //correct net ip
                u->unit2trees(ADD);
                cli_error(cli, "net %06X mask set: %s",
                              u->id, inet_ntop(AF_INET, &(net->mask), buffer, 32));
            } else if (STRARG(param[i], "mac")) {
                  struct ether_addr **mac=NULL;
                  switch(type) {
                        case NETUNIT_HOST:
                              mac = &((NetUnit_host*)u)->mac;
                              break;
                        case NETUNIT_USER:
                              mac = &((NetUnit_user*)u)->mac;
                              break;
                        default:
                              cli_error(cli, "MAC for %s not supported", type_name);
                              break;
                  }
                  if (mac) {
                        if (no_flag) {
                              aFree(*mac);
                              *mac=NULL;
                              cli_error(cli, "%s %06X mac cleared", type_name, u->id);
                        }
                        else {
                              void *p = ether_aton(param[i+1]);
                              if (p) {
                                    if (*mac==NULL)
                                          *mac = (struct ether_addr*)aMalloc(sizeof (struct ether_addr));
                                    memcpy(*mac, p, sizeof (struct ether_addr));
                                    cli_error(cli, "%s %06X mac set: %s",
                                          type_name, u->id, param[i+1]);
                              } else
                                    cli_error(cli, "%s %06X mac invalid",
                                          type_name, u->id);
                        }
                  } // mac
            } else if (STRARG(param[i], "name")) {
                  u->setName(param[i+1]);
                  cli_error(cli, "%s %06X name set: %s", type_name, u->id, u->name);
            } else if (STREQ(param[i], "bw")) {
                  u->bwi=setBW(u->bwi, param, &i);
#ifndef HAVE_BW
                  cli_error(cli, "%s %06X: trying to set BW while this runtime has no BW support; please recompile!", type_name, u->id);
                  aLog(D_WARN, "%s %06X: \n\ttrying to set BW while this runtime has no BW support; please recompile!\n\n", type_name, u->id);
#else
                  cli_bufprint(cli, "%s %06X allowed bandwidth set:",
                        type_name, u->id);
                  getBW(u->bwi, cli);
                  cli_bufprint(cli, "\n");
#endif
            } else if (STRARG(param[i], "email")) {
                        if(u->email) aFree(u->email);
                  if(no_flag) {
                        u->email=NULL;
                        cli_error(cli, "%s %06X email cleared", type_name, u->id);
                  } else {
                              u->email=set_string(param[i+1]);
                              cli_error(cli, "%s %06X email set: %s", type_name, u->id, u->email);
                  }

            } else if (STREQ(param[i], "ds-list")) {
                  u->unit2trees(REMOVE);
                  DSListAdd(u, &i, cli, param, no_flag);
                  u->unit2trees(ADD);

            } else if (STRARG(param[i], "auto-units") && u->type==NETUNIT_NET) {
                  net->auto_units_id=strtol(param[i+1], NULL, 10);
                  cli_error(cli, "%s %06X set auto-units ID %u",
                        type_name, u->id, net->auto_units_id);

            } else if (STRARG(param[i], "parent")) {
                  NetUnit_group *gr;

                  gr=(NetUnit_group*)Units->getUnit(param[i+1]);
                  if(!gr) {
                        if(no_flag) {
                              ELIST_FREE(u->parents);
                        } else
                              cli_error(cli, "group %s for %s %06X not exist",
                                    param[i+1], type_name, u->id);
                        continue;
                  }

                  while((gr=(NetUnit_group*)Units->getUnit(param[i+1]))) {
                        if (no_flag) {
                              Units->Unit2Group(u, gr, REMOVE);
                              cli_error(cli, "%s %06X parent cleared", type_name, u->id);
                        } else {
                              if(u == gr)
                                    cli_error(cli, "group %s (%06X): can't add parent to itself",
                                          gr->name, gr->id);
                              else {
                                    Units->Unit2Group(u, gr, ADD);
                                    cli_error(cli, "%s %06X added to group %s",
                                          type_name, u->id, gr->name);
                              }
                        }
                        i++;
                  }
                  i-=1;
                  FW_CHECK_CHANGED(time(NULL));

            } else if (STREQ(param[i], "no-local-pass")) {
                  if (no_flag)
                        u->flags&=~NETUNIT_NLP;
                  else
                        u->flags|=NETUNIT_NLP;
                  cli_error(cli, "%s %06X no-local-pass flag set: %u", type_name, u->id, u->flags&NETUNIT_NLP);
                  i-=1;

            } else if (STREQ(param[i], "backup-fw")) {
                  if (no_flag)
                        u->flags&=~NETUNIT_BACKUP_FW;
                  else
                        u->flags|=NETUNIT_BACKUP_FW;
                  cli_error(cli, "%s %06X backup-fw flag set: %u", type_name, u->id, u->flags&NETUNIT_BACKUP_FW);
                  i-=1;

            } else if (STRARG(param[i], "password")) {
                  if(u->password) aFree(u->password);
                  if(no_flag) {
                        u->password=NULL;
                        cli_error(cli, "Unit %s %06X password cleared",
                              type_name, u->id);
                  } else {
                              u->password=set_string(param[i+1]);
                              cli_error(cli, "Unit %s %06X password set: %s",
                              type_name, u->id, u->password);
                  }

                } else if (STRARG(param[i], "description")) {
                        if(u->description) aFree(u->description);
                  if(no_flag) {
                        u->description=NULL;
                        cli_error(cli, "Unit %s %06X description cleared",
                              type_name, u->id);
                  } else {
                              u->description=set_string(param[i+1]);
                              cli_error(cli, "Unit %s %06X description set: %s",
                                    type_name, u->id, u->description);
                  }

            } else if (STREQ(param[i], "oid")) {
                  ;//do nothing
            } else {
                  cli_error(cli, "%s %06X command '%s' unknown",
                        type_name, u->id, param[i]);
                  i--;
            }
      }

      //add default policies
      if (Processor->def) {
            NetUnit *def=Processor->def;
            if(!(u->flags&NETUNIT_AP_NODEFAULT) && def->ap)
                  def->ap->SetForUnit(POLICY_ACCT, u, cli);
            if(!(u->flags&NETUNIT_FP_NODEFAULT) && def->fp) {
                  def->fp->SetForUnit(POLICY_FW, u, cli);
                  FW_CHECK_CHANGED(time(NULL));
            }
      }

      return CLI_OK;
}
/////////////////////////////////////////////////////////////////////////
int cShowUnits(struct cli_def *cli, const char *cmd, char **argv, int argc){     // "show units"
      NetUnit *d;
      char buffer[32];
//    argv[argc]=argv[argc+1]="empty";

      netams_rwlock_rdlock(&Units->rwlock);

      if (STREQ(argv[2], "syspolicy")) {
            u_char print_where_set=0;
            if (STREQ(argv[3], "whereset")) print_where_set=1;
            cli_print(cli, "%6s | %10s | %10s", "OID", "NAME", "SYSPOLICY");
            for (d=(NetUnit*)Units->root; d!=NULL; d=(NetUnit*)d->next) {
                  if ((print_where_set==1 && d->sys_policy!=SP_NONE) || print_where_set==0){
                        cli_bufprint(cli, "%06X | %10s | ",
                              d->id, d->name?d->name:"<\?\?>");
                        GetSysPolicy(cli, d->sys_policy, d->sys_policy_perm);
                        cli_bufprint(cli, "\n");
                  }
            }
      }
      else if (STREQ(argv[2], "email")) {
            cli_print(cli, "%6s | %10s | %10s", "OID", "NAME", "E-MAIL");
            for (d=(NetUnit*)Units->root; d!=NULL; d=(NetUnit*)d->next) {
                  if (d->email) {
                        cli_print(cli, "%06X | %10s | %s", d->id, d->name?d->name:"<\?\?>", d->email);
                  }
        }
      }
      else if (STREQ(argv[2], "mac")) {
            cli_print(cli, "%6s | %8s | %10s | %15s | %18s", "OID", "TYPE", "NAME", "IP", "MAC");
            u_char print_where_set=0;
            if (STREQ(argv[3], "whereset")) print_where_set=1;
            char *ptr;
            struct ether_addr *mac;
            for (d=(NetUnit*)Units->root; d!=NULL; d=(NetUnit*)d->next) {
                  ptr = NULL;
                  buffer[0]='\0';
                  switch (d->type){
                        case NETUNIT_HOST:
                              mac = ((NetUnit_host*)d)->mac;
                              if (mac) ptr = ether_ntoa(mac);
                              inet_ntop(AF_INET, &((NetUnit_host*)d)->ip, buffer, 32);
                              break;
                        case NETUNIT_USER:
                              mac = ((NetUnit_user*)d)->mac;
                              if (mac) ptr = ether_ntoa(mac);
                              inet_ntop(AF_INET, &((NetUnit_user*)d)->ip, buffer, 32);
                              break;
                        default:
                              break;
                  }
                  if (!print_where_set || (print_where_set && ptr) ) {
                        cli_print(cli, "%06X | %8s | %10s | %15s | %18s",
                              d->id, netunit_type_name[d->type],
                              d->name?d->name:"<\?\?>",
                              buffer, ptr?ptr:"<\?\?>");
                  }
            }
      }

      else if (STRARG(argv[2], "name")) {
            NetUnit *d = Units->getUnit(argv[3]);
            if (d!=NULL) {
                  if (d->type==NETUNIT_HOST) {
                        NetUnit_host *dh=(NetUnit_host*)d;
                        cli_print(cli, "%06X | %10s | %s",
                              d->id, d->name?d->name:"<\?\?>",
                              inet_ntop(AF_INET, &(dh->ip), buffer, 32));
                  }
                  else if (d->type==NETUNIT_USER) {
                        NetUnit_user *dh=(NetUnit_user*)d;
                        cli_print(cli, "%06X | %10s | %s",
                              d->id, d->name?d->name:"<\?\?>",
                              inet_ntop(AF_INET, &(dh->ip), buffer, 32));
                  }
            }
      } else {
            u_char show_type=0; //show units <type>
            u_char show_active=0; //show units users active
            for(u_char i=0;i<NETUNIT_TYPES_NUM;i++) {
                  if (STREQ(argv[2], netunit_type_name[i])){
                        show_type = i;
                        break;
                  }
            }
            if (STREQ(argv[3], "syspolicy")) {
                  cli_print(cli, "%6s | %10s | %10s", "OID", "NAME", "SYSPOLICY");
                  for (d=(NetUnit*)Units->root; d!=NULL; d=(NetUnit*)d->next) {
                        if(d->type!=show_type) continue;
                              cli_bufprint(cli, "%06X | %10s | ",
                              d->id,d->name?d->name:"<\?\?>");
                        GetSysPolicy(cli, d->sys_policy, d->sys_policy_perm);
                        cli_bufprint(cli, "\n");
                  }
                  netams_rwlock_unlock(&Units->rwlock);
            return CLI_OK;
        }

            if (STREQ(argv[3], "active")) show_active=1;

            cli_print(cli, "%8s | %6s | %10s | %3s | %10s | %15s |%-20s",
                  "TYPE", "OID", "NAME", "NLP", "PARENT", "EMAIL", "PARAMS");
            for(d=(NetUnit*)Units->root; d!=NULL; d=(NetUnit*)d->next)  {
                  if(show_type && d->type!=show_type) continue;
                  if(show_active) {
                        if(d->type!=NETUNIT_USER) continue;
                        NetUnit_user *h=(NetUnit_user*)d;
                        if(h->ip.s_addr==0) continue;
                  }

                  cli_bufprint(cli, "%8s | %06X | %10s | %3s |",
                        netunit_type_name[d->type], d->id,
                        d->name?d->name:"<\?\?>",
                        d->flags&NETUNIT_NLP?" + ":"");

                  NetUnit_group *gr;
                  ELIST_FOR_EACH(d->parents, gr) {
                        if (gr->name)
                              cli_bufprint(cli," %6s", gr->name);
                  }
                  cli_bufprint(cli, "| %15s | ", d->email?d->email:"");

                  switch (d->type) {
                  case NETUNIT_HOST: {
                        NetUnit_host *h;
                        h = (NetUnit_host*)d;
                        cli_bufprint(cli, "IP: %-12s",inet_ntop(AF_INET, &(h->ip), buffer, 32));
                        break;
                  }
                  case NETUNIT_USER: {
                        NetUnit_user *h;
                        h = (NetUnit_user*)d;
                        cli_bufprint(cli, "IP: %-12s", inet_ntop(AF_INET, &(h->ip), buffer, 32));
                        break;
                  }
                  case NETUNIT_CLUSTER: {
                        NetUnit_cluster *h;
                        NetUnit_net *t;
                        h = (NetUnit_cluster*)d;
                        cli_bufprint(cli, "IPs:");
                        for (t=h->root; t!=NULL; t=t->next)
                              cli_bufprint(cli, " %s/%u",
                                    inet_ntop(AF_INET, &(t->ip), buffer, 32), MASK2MLEN(t->mask));
                        break;
                  }
                  case NETUNIT_GROUP: {
                        NetUnit_group *gr;
                        NetUnit *t;
                        gr = (NetUnit_group*)d;
                        if(gr->email) cli_bufprint(cli, "Sub:");
                        ELIST_FOR_EACH(gr->childrens, t) {
                              if (t->name)
                                    cli_bufprint(cli, " %s", t->name);
                        }
                        break;
                  }
                  case NETUNIT_NET: {
                        NetUnit_net *h;
                        h = (NetUnit_net*)d;
                        cli_bufprint(cli, "%s/%u",
                              inet_ntop(AF_INET, &(h->ip), buffer, 32), MASK2MLEN(h->mask));
                        break;
                  }
                  default:
                        cli_bufprint(cli, "%8s | %06X", "<\?\?>", d->id);
                        break;
                  }
                  cli_bufprint(cli, "\n");
            }
      }

      netams_rwlock_unlock(&Units->rwlock);
      return CLI_OK;
}

/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
int cShowUnitsList(struct cli_def *cli, const char *cmd, char **argv, int argc) {
      NetUnit *d2=NULL;
      policy_data *cpd;
      u_char isfull=0;
      u_char i=2;
      char t_str[32];

      for(; i<argc; i++) {
            if(STREQ(argv[i], "full"))
                  isfull=1;
            else
                  d2=aParseUnit(argv, &i);
      }

      netams_rwlock_rdlock(&Units->rwlock);
      for (NetUnit *d=(NetUnit*)Units->root; d!=NULL; d=(NetUnit*)d->next) {

            if (d2 && d!=d2) continue;

            cli_bufprint(cli, "OID: %06X Name: %-10s Type: %-8s", d->id, d->name, netunit_type_name[d->type]);
            if (d->flags&NETUNIT_NLP) cli_bufprint(cli, " NLP");
            if (d->parents) {
                  NetUnit_group *gr;
                  cli_bufprint(cli, " Parents:");
                  ELIST_FOR_EACH(d->parents, gr) {
                        cli_bufprint(cli, " %s", gr->name);
                  }
            }

            if (!ELIST_IS_EMPTY(d->dslist)) {
                  u_char *dsl;
                  cli_bufprint(cli, " DS-list:");
                  ELIST_FOR_EACH(d->dslist, dsl)
                        cli_bufprint(cli, " %u", *dsl);
            }

            cli_bufprint(cli, "\n");

            cli_print(cli, " %-11s %s",
                  "SYST policy ",
                  (d->sys_policy==SP_NONE)?"is not set":""); //GetSysPolicy(tmp, d->sys_policy, d->sys_policy_perm));

            cli_bufprint(cli, "%-11s", "  FW policy");
            if (d->fp) {
                  cli_print(cli, ": %-6s %-10s %-12s %-12s",  "OID", "NAME", "CHECK", "MATCH");
                  for (cpd=d->fp->root; cpd!=NULL; cpd=cpd->next) {
                        cli_print(cli, "%-10s %s%s %06X %-10s %-12llu %-12llu",
                              "", (cpd->policy_flags&POLICY_FLAG_BRK)?"%":" ",
                              (cpd->policy_flags&POLICY_FLAG_INV)?"!":" ",
                              cpd->policy->id, cpd->policy->name?cpd->policy->name:"<\?\?>",
                              cpd->check, cpd->match);
                  }
            }
            else
                  cli_print(cli, " list is empty");

            cli_bufprint(cli, "%-11s", "ACCT policy");

            if (d->ap) {
                  netams_rwlock_rdlock(&d->ap->rwlock);
                  cli_print(cli, ": %-6s %-6s %-10s %-12s %-12s",  "FLAGS", "OID", "NAME", "CHECK", "MATCH");
                  for (cpd=d->ap->root; cpd!=NULL; cpd=cpd->next) {
                        cli_print(cli, " %-12s %s%s    %06X  %-10s %-12llu %-12llu",
                              "", (cpd->policy_flags&POLICY_FLAG_BRK)?"%":" ",
                              (cpd->policy_flags&POLICY_FLAG_INV)?"!":" ",
                              cpd->policy->id, cpd->policy->name?cpd->policy->name:"<\?\?>",
                              cpd->check, cpd->match);
                        if (isfull) {
                              timeU2T(cpd->flow.from, t_str);
                              cli_print(cli, "%-19s %-10s in: %-12llu out: %-12llu",
                                    cpd->flow.from?t_str:"--.--.---- --:--:--",  "flow",
                                    cpd->flow.in, cpd->flow.out);
                              timeU2T(cpd->m.from, t_str);
                              cli_print(cli, "%-19s %-10s in: %-12llu out: %-12llu",
                                    t_str,  "month", cpd->m.in, cpd->m.out);
                              timeU2T(cpd->w.from, t_str);
                              cli_print(cli, "%-19s %-10s in: %-12llu out: %-12llu",
                                    t_str,  "week", cpd->w.in, cpd->w.out);
                              timeU2T(cpd->d.from, t_str);
                              cli_print(cli, "%-19s %-10s in: %-12llu out: %-12llu",
                                    t_str,  "day", cpd->d.in, cpd->d.out);
                              timeU2T(cpd->h.from, t_str);
                              cli_print(cli, "%-19s %-10s in: %-12llu out: %-12llu",
                                    t_str,  "hour", cpd->h.in, cpd->h.out);
                        }
                  }
                  netams_rwlock_unlock(&d->ap->rwlock);
                  cli_bufprint(cli, "\n");
            }
            else
                  cli_print(cli, " list is empty");
      }
      netams_rwlock_unlock(&Units->rwlock);
      return PARSE_OK;
}

/////////////////////////////////////////////////////////////////////////
void DSListAdd(NetUnit *u, u_char *i, struct cli_def *cli, char *param[], u_char no_flag){
      char *res, *ptr;

      aDebug(DEBUG_DS_IP, "NetUnit: DSL: adding DS list \"%s\"\n", param[(*i)+1]);

      int k=strlen(param[(*i)+1]);
      unsigned f;

      for (ptr=param[(*i)+1]; (ptr-param[(*i)+1])<k ;ptr=res+1) {
            if(no_flag && ( STREQ(ptr,"all") || STREQ(ptr,"*")) ) {
                  cli_error(cli, "ds-list cleared for unit %06X", u->id);
                  u_char *dsl;
                  ELIST_FOR_EACH(u->dslist, dsl) {
                        aFree(dsl);
                  }
                  ELIST_FREE(u->dslist);
                  return;
            }
            f=strtol(ptr, &res, 10);
            if (no_flag) {
                  cli_error(cli, "removing DS %u from list for unit %06X", f, u->id);
                  u->clearDSList(f);
            }
            else {
                  cli_error(cli, "adding DS %u to list for unit %06X", f, u->id);
                  u->setDSList(f);
            }
      }
}

/////////////////////////////////////////////////////////////////////////
in_addr_t AutoAssignIP(struct cli_def *cli) {
      unsigned addr;

      for(AutoAssignEntry *e=Processor->auto_assign; e!=NULL; e=e->next) {
            for(addr=ntohl(e->start.s_addr); addr<=ntohl(e->stop.s_addr); addr++) {
                  if (!Units->getUnitByIP(htonl(addr))) {
#ifdef DEBUG
                        char buffer[32];
                        struct in_addr ip;
                        ip.s_addr=htonl(addr);
                        aDebug(DEBUG_COMMAND, "selected auto-assign address %s \n", inet_ntop(AF_INET, &(ip), buffer, 32));
#endif
                        return htonl(addr);
                        }
            }
      }
      cli_error(cli, "auto-assign address pool is empty, discarding new request");
      return 0;
}
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////

Generated by  Doxygen 1.6.0   Back to index