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

ike.nethlp.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"

//
// general network helper functions
//

void _IKED::text_prot( char * text, int prot )
{
      static const char * prot_00 = "ANY";
      static const char * prot_01 = "ICMP";
      static const char * prot_04 = "IPIP";
      static const char * prot_06 = "TCP";
      static const char * prot_17 = "UDP";
      static const char * prot_47 = "GRE";
      static const char * prot_50 = "ESP";
      static const char * prot_51 = "AH";

      const char * temp = NULL;

      switch( prot )
      {
            case 0:
                  temp = prot_00;
                  break;

            case 1:
                  temp = prot_01;
                  break;

            case 4:
                  temp = prot_04;
                  break;

            case 6:
                  temp = prot_06;
                  break;

            case 17:
                  temp = prot_17;
                  break;

            case 47:
                  temp = prot_47;
                  break;

            case 50:
                  temp = prot_50;
                  break;

            case 51:
                  temp = prot_51;
                  break;
      }

      if( temp != NULL )
            strcpy_s(
                  text,
                  LIBIKE_MAX_TEXTPROT,
                  temp );
      else
            sprintf_s(
                  text,
                  LIBIKE_MAX_TEXTPROT,
                  "%i",
                  prot );
}

void _IKED::text_addr( char * text, in_addr & addr )
{
      unsigned long haddr = ntohl( addr.s_addr );

      sprintf_s( text, LIBIKE_MAX_TEXTADDR,
            "%lu.%lu.%lu.%lu",
            0xff & ( haddr >> 24 ),
            0xff & ( haddr >> 16 ),
            0xff & ( haddr >>  8 ),
            0xff & haddr );
}

void _IKED::text_mask( char * text, in_addr & addr )
{
      unsigned long bits;
      unsigned long mask;

      bits = 0;
      mask = ntohl( addr.s_addr );

      while( mask & 0x80000000 )
      {
            mask <<= 1;
            bits++;
      }

      sprintf_s(
            text,
            LIBIKE_MAX_TEXTADDR,
            "%lu",
            bits );
}

void _IKED::text_port( char * text, int port )
{
      if( !port )
            strcpy_s(
                  text,
                  LIBIKE_MAX_TEXTPORT,
                  "*" );
      else
            sprintf_s(
                  text,
                  LIBIKE_MAX_TEXTPORT,
                  "%i",
                  ntohs( port ) );
}

void _IKED::text_addr( char * text, sockaddr * saddr, bool port )
{
      switch( saddr->sa_family )
      {
            case AF_INET:
            {
                  sockaddr_in * saddr_in = ( sockaddr_in * ) saddr;

                  char txtaddr[ LIBIKE_MAX_TEXTADDR ];
                  text_addr( txtaddr, saddr_in->sin_addr );

                  if( port )
                  {
                        sprintf_s(
                              text,
                              LIBIKE_MAX_TEXTADDR,
                              "%s:%u",
                              txtaddr,
                              ntohs( saddr_in->sin_port ) );
                  }
                  else
                  {
                        sprintf_s(
                              text,
                              LIBIKE_MAX_TEXTADDR,
                              "%s",
                              txtaddr );
                  }

                  break;
            }

            default:

                  sprintf_s(
                        text,
                        LIBIKE_MAX_TEXTADDR,
                        "<UNKNOWN AF>" );
      }
}

void _IKED::text_addr( char * text, IKE_SADDR * iaddr, bool port )
{
      text_addr( text, &iaddr->saddr, port );
}

void _IKED::text_addr( char * text, PFKI_ADDR * paddr, bool port, bool netmask )
{
      char txtaddr[ LIBIKE_MAX_TEXTADDR ];
      text_addr( txtaddr, &paddr->saddr, port );

      if( netmask && paddr->prefix )
      {
            sprintf_s(
                  text,
                  LIBIKE_MAX_TEXTADDR,
                  "%s/%u",
                  txtaddr,
                  paddr->prefix );
      }
      else
      {
            sprintf_s(
                  text,
                  LIBIKE_MAX_TEXTADDR,
                  "%s",
                  txtaddr );
      }
}

void _IKED::text_ph1id( char * text, IKE_PH1ID * ph1id )
{
      switch( ph1id->type )
      {
            case ISAKMP_ID_NONE:
            {
                  sprintf_s(
                        text,
                        LIBIKE_MAX_TEXTP1ID,
                        "%s",
                        find_name( NAME_IDENT, ph1id->type ) );

                  break;
            }

            case ISAKMP_ID_IPV4_ADDR:
            {
                  char txtaddr[ LIBIKE_MAX_TEXTADDR ];
                  text_addr( txtaddr, ph1id->addr );

                  sprintf_s(
                        text,
                        LIBIKE_MAX_TEXTP1ID,
                        "%s %s",
                        find_name( NAME_IDENT, ph1id->type ),
                        txtaddr );

                  break;
            }

            case ISAKMP_ID_FQDN:
            case ISAKMP_ID_USER_FQDN:
            {
                  BDATA varid;
                  varid.set( ph1id->varid );
                  varid.add( 0, 1 );

                  sprintf_s(
                        text,
                        LIBIKE_MAX_TEXTP1ID,
                        "%s %s",
                        find_name( NAME_IDENT, ph1id->type ),
                        varid.buff() );

                  break;
            }

            case ISAKMP_ID_ASN1_DN:
            case ISAKMP_ID_ASN1_GN:
            {
                  BDATA varid;
                  asn1_text( ph1id->varid, varid );
                  varid.add( 0, 1 );

                  sprintf_s(
                        text,
                        LIBIKE_MAX_TEXTP1ID,
                        "%s %s",
                        find_name( NAME_IDENT, ph1id->type ),
                        varid.buff() );

                  break;
            }

            case ISAKMP_ID_KEY_ID:
            {
                  sprintf_s(
                        text,
                        LIBIKE_MAX_TEXTP1ID,
                        "%s [ %lu bytes ]",
                        find_name( NAME_IDENT, ph1id->type ),
                        ph1id->varid.size() );

                  break;
            }

            default:

                  sprintf_s(
                        text,
                        LIBIKE_MAX_TEXTP1ID,
                        "<UNKNOWN P1ID>" );
      }
}

void _IKED::text_ph2id( char * text, IKE_PH2ID * ph2id )
{
      char txtprot[ LIBIKE_MAX_TEXTPROT ];
      char txtaddr1[ LIBIKE_MAX_TEXTADDR ];
      char txtaddr2[ LIBIKE_MAX_TEXTADDR ];
      char txtport[ LIBIKE_MAX_TEXTPORT ];

      switch( ph2id->type )
      {
            case ISAKMP_ID_IPV4_ADDR:

                  text_prot( txtprot, ph2id->prot );
                  text_addr( txtaddr1, ph2id->addr1 );
                  text_port( txtport, ph2id->port );

                  sprintf_s(
                        text,
                        LIBIKE_MAX_TEXTP2ID,
                        "%s:%s:%s",
                        txtprot,
                        txtaddr1,
                        txtport );

                  break;

            case ISAKMP_ID_IPV4_ADDR_SUBNET:

                  text_prot( txtprot, ph2id->prot );
                  text_addr( txtaddr1, ph2id->addr1 );
                  text_mask( txtaddr2, ph2id->addr2 );
                  text_port( txtport, ph2id->port );

                  sprintf_s(
                        text,
                        LIBIKE_MAX_TEXTP2ID,
                        "%s:%s/%s:%s",
                        txtprot,
                        txtaddr1,
                        txtaddr2,
                        txtport );

                  break;

            case ISAKMP_ID_IPV4_ADDR_RANGE:

                  text_prot( txtprot, ph2id->prot );
                  text_addr( txtaddr1, ph2id->addr1 );
                  text_addr( txtaddr2, ph2id->addr2 );
                  text_port( txtport, ph2id->port );

                  sprintf_s(
                        text,
                        LIBIKE_MAX_TEXTP2ID,
                        "%s:%s-%s:%s",
                        txtprot,
                        txtaddr1,
                        txtaddr2,
                        txtport );

                  break;

            default:

                  sprintf_s(
                        text,
                        LIBIKE_MAX_TEXTP2ID,
                        "<UNKNOWN P2ID>" );
      }
}

bool has_sockaddr( sockaddr * saddr )
{
      switch( saddr->sa_family )
      {
            case AF_INET:
            {
                  sockaddr_in * saddr_in = ( sockaddr_in * ) saddr;
                  if( saddr_in->sin_addr.s_addr )
                        return true;
            }
      }

      return false;
}

bool cmp_sockaddr( sockaddr & saddr1, sockaddr & saddr2, bool port )
{
      if( saddr1.sa_family !=
            saddr2.sa_family )
            return false;

      switch( saddr1.sa_family )
      {
            case AF_INET:
            {
                  sockaddr_in * saddr1_in = ( sockaddr_in * ) &saddr1;
                  sockaddr_in * saddr2_in = ( sockaddr_in * ) &saddr2;

                  if( saddr1_in->sin_addr.s_addr !=
                        saddr2_in->sin_addr.s_addr )
                        return false;

                  if( port )
                        if( saddr1_in->sin_port !=
                              saddr2_in->sin_port )
                              return false;

                  return true;
            }
      }

      return false;
}

bool cpy_sockaddr( sockaddr & saddr1, sockaddr & saddr2, bool port )
{
      switch( saddr1.sa_family )
      {
            case AF_INET:
            {
                  sockaddr_in * saddr1_in = ( sockaddr_in * ) &saddr1;
                  sockaddr_in * saddr2_in = ( sockaddr_in * ) &saddr2;

                  SET_SALEN( saddr2_in, sizeof( sockaddr_in  ) );
                  saddr2_in->sin_family = AF_INET;
                  saddr2_in->sin_addr = saddr1_in->sin_addr;

                  if( port )
                        saddr2_in->sin_port = saddr1_in->sin_port;
                  else
                        saddr2_in->sin_port = 0;

                  return true;
            }
      }

      return false;
}

bool get_sockport( sockaddr & saddr, u_int16_t & port )
{
      switch( saddr.sa_family )
      {
            case AF_INET:
            {
                  sockaddr_in * saddr_in = ( sockaddr_in * ) &saddr;
                  port = saddr_in->sin_port;

                  return true;
            }
      }

      return false;
}

bool set_sockport( sockaddr & saddr, u_int16_t port )
{
      switch( saddr.sa_family )
      {
            case AF_INET:
            {
                  sockaddr_in * saddr_in = ( sockaddr_in * ) &saddr;
                  saddr_in->sin_port = port;

                  return true;
            }
      }

      return false;
}

bool cmp_ikeaddr( IKE_SADDR & addr1, IKE_SADDR & addr2, bool port )
{
      return cmp_sockaddr( addr1.saddr, addr2.saddr, port );
}

Generated by  Doxygen 1.6.0   Back to index