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

ike.xconf.cpp

/*
 * Copyright (c) 2007
 *      Shrew Soft Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Redistributions in any form must be accompanied by information on
 *    how to obtain complete source code for the software and any
 *    accompanying software that uses the software.  The source code
 *    must either be included in the distribution or be available for no
 *    more than the cost of distribution plus a nominal fee, and must be
 *    freely redistributable under reasonable conditions.  For an
 *    executable file, complete source code means the source code for all
 *    modules it contains.  It does not include source code for modules or
 *    files that typically accompany the major components of the operating
 *    system on which the executable file runs.
 *
 * THIS SOFTWARE IS PROVIDED BY SHREW SOFT INC ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
 * NON-INFRINGEMENT, ARE DISCLAIMED.  IN NO EVENT SHALL SHREW SOFT INC
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 * AUTHOR : Matthew Grooms
 *          mgrooms@shrew.net
 *
 */

#include "iked.h"

//
// XCONF - BASE CLASS
//

_IKED_XCONF::~_IKED_XCONF()
{
      delete [] pool4_array;
}

bool _IKED_XCONF::pool4_set( in_addr & base, long bits, long max )
{
      //
      // calculate network mask and addr
      //

      config.mask.s_addr = 0;

      for( long i = 0; i < bits; i++ )
      {
            config.mask.s_addr >>= 1;
            config.mask.s_addr |= 0x80000000;
      }

      config.mask.s_addr = htonl( config.mask.s_addr );
      config.addr.s_addr = base.s_addr & config.mask.s_addr;

      if( pool4_array != NULL )
            delete [] pool4_array;

      //
      // calculate max total addresses
      // for the given network and the
      // first and last usable address
      //

      long len = ntohl( base.s_addr | ~config.mask.s_addr ) -
                     ntohl( base.s_addr ) + 1; 

      if( max )
      {
            if( max <= len )
                  pool4_total = max;
            else
                  pool4_total = len;
      }
      else
            pool4_total = len;

      in_addr last;
      last.s_addr = htonl( ntohl( base.s_addr ) + pool4_total - 1 );

      static const char * adj = "( adjusted )";
      static const char * org = "";
      const char * adj_base = org;
      const char * adj_last = org;

      if( base.s_addr == config.addr.s_addr )
      {
            if( max )
                  adj_base = adj;

            base.s_addr = htonl( ntohl( base.s_addr ) + 1 );
            pool4_total--;
      }

      if( last.s_addr == ( base.s_addr | ~config.mask.s_addr ) )
      {
            if( max )
                  adj_last = adj;

            last.s_addr = htonl( ntohl( last.s_addr ) - 1 );
            pool4_total--;
      }

      //
      // create our address pool
      //

      pool4_array = new POOL4[ pool4_total ];
      if( pool4_array == NULL )
            return false;

      for( long a = 0; a < pool4_total; a++ )
      {
            pool4_array[ a ].addr.s_addr = htonl( ntohl( base.s_addr ) + a );
            pool4_array[ a ].used = false;
      }

      char txtaddr[ LIBIKE_MAX_TEXTADDR ];
      char txtmask[ LIBIKE_MAX_TEXTADDR ];
      char txtbase[ LIBIKE_MAX_TEXTADDR ];
      char txtlast[ LIBIKE_MAX_TEXTADDR ];

      iked.text_addr( txtaddr, config.addr );
      iked.text_addr( txtmask, config.mask );
      iked.text_addr( txtbase, base );
      iked.text_addr( txtlast, last );

      iked.log.txt( LLOG_DEBUG,
            "ii : created %s address pool\n"
            "ii : - network   %s\n"
            "ii : - netmask   %s\n"
            "ii : - base addr %s %s\n"
            "ii : - last addr %s %s\n"
            "ii : - available %i\n",
            name(),
            txtaddr,
            txtmask,
            txtbase,
            adj_base,
            txtlast,
            adj_last,
            pool4_total );

      return true;
}

bool _IKED_XCONF::pool4_get( in_addr & addr )
{
      if( pool4_inuse == pool4_total )
            return false;

      pool4_lock.lock();

      long index = 0;
      for( ; index < pool4_total; index++ )
      {
            if( !pool4_array[ index ].used )
            {
                  addr = pool4_array[ index ].addr;
                  pool4_array[ index ].used = true;

                  char txtaddr[ LIBIKE_MAX_TEXTADDR ];
                  iked.text_addr( txtaddr, addr );

                  iked.log.txt( LLOG_DEBUG,
                        "ii : address %s aquired from %s pool\n",
                        txtaddr,
                        name() );

                  break;
            }
      }

      pool4_lock.unlock();

      return ( index < pool4_total );
}

bool _IKED_XCONF::pool4_rel( in_addr & addr )
{
      pool4_lock.lock();

      long index = 0;
      for( ; index < pool4_total; index++ )
      {
            if( pool4_array[ index ].used )
            {
                  if( addr.s_addr == pool4_array[ index ].addr.s_addr )
                  {
                        pool4_array[ index ].used = false;

                        char txtaddr[ LIBIKE_MAX_TEXTADDR ];
                        iked.text_addr( txtaddr, addr );

                        iked.log.txt( LLOG_DEBUG,
                              "ii : address %s returned to %s pool\n",
                              txtaddr,
                              name() );

                        break;
                  }
            }
      }

      pool4_lock.unlock();

      return ( index < pool4_total );
}

//
// XCONF - LOCAL CONFIG DB
//

static const char * iked_xconf_local_name = "local";

_IKED_XCONF_LOCAL::_IKED_XCONF_LOCAL()
{
}

_IKED_XCONF_LOCAL::~_IKED_XCONF_LOCAL()
{
}

const char * _IKED_XCONF_LOCAL::name()
{
      return iked_xconf_local_name;
}

bool _IKED_XCONF_LOCAL::rslt( IDB_TUNNEL * tunnel )
{
      tunnel->xconf.opts = tunnel->xconf.rqst;
      tunnel->xconf.opts &= config.opts;

      if( tunnel->xconf.opts & IPSEC_OPTS_ADDR )
            pool4_get( tunnel->xconf.addr );

      if( tunnel->xconf.opts & IPSEC_OPTS_MASK )
            tunnel->xconf.mask = config.mask;

      if( tunnel->xconf.opts & IPSEC_OPTS_DNSS )
      {
            memcpy( tunnel->xconf.nscfg.dnss_list,
                  config.nscfg.dnss_list,
                  sizeof( config.nscfg.dnss_list ) );

            tunnel->xconf.nscfg.dnss_count = config.nscfg.dnss_count;
      }

      if( tunnel->xconf.opts & IPSEC_OPTS_DOMAIN )
            memcpy( tunnel->xconf.nscfg.dnss_suffix,
                  config.nscfg.dnss_suffix, CONF_STRLEN );

      if( tunnel->xconf.opts & IPSEC_OPTS_SPLITDNS )
      {
            BDATA suffix;
            long index = 0;
            while( domains.get( suffix, index++ ) )
                  tunnel->domains.add( suffix );
      }

      if( tunnel->xconf.opts & IPSEC_OPTS_NBNS )
      {
            memcpy( tunnel->xconf.nscfg.nbns_list,
                  config.nscfg.nbns_list,
                  sizeof( config.nscfg.nbns_list ) );

            tunnel->xconf.nscfg.nbns_count = config.nscfg.nbns_count;
      }

      if( tunnel->xconf.opts & IPSEC_OPTS_PFS )
            tunnel->xconf.dhgr = config.dhgr;

      if( tunnel->xconf.opts & IPSEC_OPTS_BANNER )
            tunnel->banner.set( banner );

      return true;
}

Generated by  Doxygen 1.6.0   Back to index