/*****************************************************************************
* Copyright (c) 2005 Digi International Inc., All Rights Reserved
*
* This software contains proprietary and confidential information of Digi
* International Inc.  By accepting transfer of this copy, Recipient agrees
* to retain this software in confidence, to prevent disclosure to others,
* and to make no use of this software other than that for which it was
* delivered.  This is an unpublished copyrighted work of Digi International
* Inc.  Except as permitted by federal law, 17 USC 117, copying is strictly
* prohibited.
*
* Restricted Rights Legend
*
* Use, duplication, or disclosure by the Government is subject to
* restrictions set forth in sub-paragraph (c)(1)(ii) of The Rights in
* Technical Data and Computer Software clause at DFARS 252.227-7031 or
* subparagraphs (c)(1) and (2) of the Commercial Computer Software -
* Restricted Rights at 48 CFR 52.227-19, as applicable.
*
* Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
*
*****************************************************************************/

#ifndef ipsec_h

#define ipsec_h

#include "Npttypes.h"
#include "nastatus.h"
#include <sockapi.h>



/*ad*
 * Use this value to naIpsecPolicySelectorSetLocalPort and
 * naIpsecPolicySelectorSetRemotePort to select packets with any port number.
 *
 * @since   7.0
 * @external
 * @category Networking:IPSEC
*ad*/
#define NA_IPSEC_ANY_PORT           (0)


/*ad*
 * Use this value to naIpsecPolicySelectorSetProtocol to select packets
 * using any IP protocol.
 *
 * @since   7.0
 * @external
 * @category Networking:IPSEC
*ad*/
#define NA_IPSEC_ANY_PROTOCOL       (0)

/*ad*
 * Maximum length of a Fully Qualified Domain Name (FQDN), or of a
 * user FQDN.
 *
 * @since   7.0
 * @external
 * @category Networking:IPSEC
*ad*/
#define IPSEC_MAX_FQDN_LENGTH       (255)



/*ad*
 * Use the values in this enumerated type to specify the type
 * of ID used in an NaIkeIdentifier_t structure.
 *
 * @since   7.0
 * @external
 * @category Networking:IPSEC:IKE
 * @see @link NaIkeIdentifier_t
 *
 * @param IPSEC_ID_IPADDRESS        identifier is an IPv4 or IPv6 address
 * @param IPSEC_ID_FQDN             identifier is a fully qualified domain name, for example
 *                                  "foobar.digi.com".
 * @param IPSEC_ID_USER_FQDN        identifier is a fully qualified user domain name, for
 *                                  example "dlee@foobar.digi.com".
*ad*/
typedef enum
{
    IPSEC_ID_IPADDRESS,
    IPSEC_ID_FQDN,
    IPSEC_ID_USER_FQDN
} NaIkeIdentifierSelector_t;



/*ad*
 * Use this type to store VPN peer IDs used by IKE.
 *
 * @since   7.0
 * @external
 * @category Networking:IPSEC:IKE
 *
 * @param address       use this field to store the ID if it is an IPv4 or IPv6 address.
 * @param fqdn          use this field to store the ID if it is a fully qualified domain name, or
 *                      a fully qualified user domain name.
 * @param id            union of address and fqdn
 * @param idType        use this field to determine what format of ID is being used.
*ad*/
typedef struct NaIkeIdentifier_t
{
    union
    {
        struct sockaddr_storage address;
        char fqdn[IPSEC_MAX_FQDN_LENGTH+1];
    } id;
    NaIkeIdentifierSelector_t idType;
} NaIkeIdentifier_t;



/*ad*
 * Use the values in this enumerated type to specify the negotiation mode
 * used in IKE phase 1.
 *
 * @since   7.0
 * @external
 * @category Networking:IPSEC:IKE
 *
 * @param NA_IKE_AGGRESSIVE_MODE    Use aggressive mode.
 * @param NA_IKE_MAIN_MODE          Use main mode.
*ad*/
typedef enum
{
    NA_IKE_AGGRESSIVE_MODE,
    NA_IKE_MAIN_MODE
} NaIpsecIkeMode_t;






/*ad*
 * Use the values in this enumerated type to specify the ICMP bypass mode
 * for IPSEC.
 *
 * @since   7.0
 * @external
 * @category Networking:IPSEC
 *
 * @param NA_IPSEC_ICMP_BYPASS_NONE     Apply IPSEC policy checking to all ICMP messages.
 * @param NA_IPSEC_ICMP_BYPASS_ALL      Do not apply IPSEC policy checking to any ICMP messages.
 * @param NA_IPSEC_ICMP_BYPASS_DONT_CHECK_SOURCE_ADDRESS     Apply IPSEC policy checking to all ICMP messages, but
 *                                                           don't check the source address.
*ad*/
typedef enum
{
    NA_IPSEC_ICMP_BYPASS_NONE,
    NA_IPSEC_ICMP_BYPASS_ALL,
    NA_IPSEC_ICMP_BYPASS_DONT_CHECK_SOURCE_ADDRESS
} NaIpsecIcmpBypassMode_t;








/*ad*
 * Use the values in this enumerated type to specify how the don't fragment
 * bit in IPSEC tunnel messages should be set.
 *
 * @since   7.0
 * @external
 * @category Networking:IPSEC
 *
 * @param NA_IPSEC_DONT_FRAGMENT_SET_BIT        Always set the bit.
 * @param NA_IPSEC_DONT_FRAGMENT_CLEAR_BIT      Always clear the bit.
 * @param NA_IPSEC_DONT_FRAGMENT_INHERIT_BIT    Set the bit the same way it was set in the
 *                                              packet that is being tunnelled.
*ad*/
typedef enum
{
    NA_IPSEC_DONT_FRAGMENT_SET_BIT,
    NA_IPSEC_DONT_FRAGMENT_CLEAR_BIT,
    NA_IPSEC_DONT_FRAGMENT_INHERIT_BIT
} NaIpsecDontFragmentMode_t;



/*ad*
 * Use the values in this enumerated type to specify direction of traffic to be
 * selected by an SA or a policy selector.
 *
 * @since   7.0
 * @external
 * @category Networking:IPSEC
 *
 * @param NA_IPSEC_DIRECTION_INBOUND        select inbound traffic
 * @param NA_IPSEC_DIRECTION_OUTBOUND       select outbound traffic
 * @param NA_IPSEC_DIRECTION_BOTH           select inbound and outbound traffic
*ad*/
typedef enum
{
    NA_IPSEC_DIRECTION_INBOUND = 1,     /* values from trsecapi.h */
    NA_IPSEC_DIRECTION_OUTBOUND,
    NA_IPSEC_DIRECTION_BOTH
} NaIpsecDirection_t;


/*ad*
 * Use this type for IKE phase 1 transform handles.
 *
 * @since   7.0
 * @external
 * @category Networking:IPSEC:IKE:Phase1
*ad*/
typedef unsigned NaIkePhase1TransformHandle_t;



/*ad*
 * Use this type for IPSEC policy table handles.
 *
 * @since   7.0
 * @external
 * @category Networking:IPSEC:Policy
*ad*/
typedef unsigned NaIpsecPolicyTableHandle_t;


/*ad*
 * Use this type for IPSEC policy selector table handles.
 *
 * @since   7.0
 * @external
 * @category Networking:IPSEC:Policy:Selector
*ad*/
typedef unsigned NaIpsecPolicySelectorHandle_t;



/*ad*
 * Use this type for IPSEC policy content table handles.
 *
 * @since   7.0
 * @external
 * @category Networking:IPSEC:Policy:Content
*ad*/
typedef unsigned NaIpsecPolicyContentHandle_t;



/*ad*
 * Use this type for IPSEC manually keyed SA handles.
 *
 * @since   7.0
 * @external
 * @category Networking:IPSEC:SA
*ad*/
typedef unsigned NaIpsecSaHandle_t;




/*ad*
 * Possible formats to represent a range of IP addresses that are selected for
 * tunnelling.
 *
 * @since   7.0
 * @external
 * @category Networking:IPSEC
 *
 * @param NA_IPSEC_RANGE_FIRST_LAST      first and last fields specify a range of addresses
 * @param NA_IPSEC_RANGE_SUBNET          first and last fields are a network address and subnet mask respectively
 * @param NA_IPSEC_RANGE_ALL             selects all possible addresses.
 * @param NA_IPSEC_RANGE_HOST            selects a single IP address stored in first field
*ad*/
typedef enum
{
    NA_IPSEC_RANGE_FIRST_LAST,
    NA_IPSEC_RANGE_SUBNET,
    NA_IPSEC_RANGE_ALL,
    NA_IPSEC_RANGE_HOST
} NaIpsecAddressRangeFormat_t;




/*ad*
 * This data type is used to represent a selection of addresses to be routed
 * through a VPN tunnel.
 *
 * @since   7.0
 * @external
 * @category Networking:IPSEC
 *
 * @param first     first IP address in range or network address of IPv4 subnet, or a host IP address
 *                  if format is set to NA_IPSEC_RANGE_SINGLE.
 * @param last      last IP address in range or subnet mask of IPv4 subnet
 * @param format    specifies what format of the the range of IP addresses
*ad*/
typedef struct NaIpsecAddressRange_t
{
    struct sockaddr_storage first;
    struct sockaddr_storage last;
    NaIpsecAddressRangeFormat_t format;
} NaIpsecAddressRange_t;




/*ad*
 * Use the values in this enumerated type to specify encryption algorithms.
 *
 * @since   7.0
 * @external
 * @category Networking:IPSEC
 *
 * @param NA_IPSEC_ENCRYPTION_DES       DES encryption
 * @param NA_IPSEC_ENCRYPTION_3DES      Triple DES encryption
 * @param NA_IPSEC_ENCRYPTION_AES       AES encryption
*ad*/
typedef enum
{
    NA_IPSEC_ENCRYPTION_DES = 8,        /* from trsecapi.h: SADB_EALG_DESCBC */
    NA_IPSEC_ENCRYPTION_3DES = 9,       /* SADB_EALG_3DESCBC */
    NA_IPSEC_ENCRYPTION_AES = 16        /* SADB_EALG_AESCBC */
} NaIpsecEncryptionAlgorthm_t;



/*ad*
 * Use the values in this enumerated type to specify hash algorithms.
 *
 * @since   7.0
 * @external
 * @category Networking:IPSEC
 *
 * @param NA_IPSEC_AUTHENTICATION_MD5   MD5 hash algorithm
 * @param NA_IPSEC_AUTHENTICATION_SHA1  SHA1 hash algorithm
*ad*/
typedef enum
{
    NA_IPSEC_AUTHENTICATION_MD5 = 1,    /* from trsecapi.h: SADB_AALG_MD5HMAC */
    NA_IPSEC_AUTHENTICATION_SHA1 = 2    /* SADB_AALG_SHA1HMAC */
} NaIpsecAuthenticationAlgorithm_t;




/*ad*
 * Bit field values for policy content rules flag.
 *
 * @category Networking:IPSEC:Policy:Content
 * @since 7.0
 * @external
 *
 * @note NA_IPSEC_CONTENT_BYPASS_IPSEC_POLICY_CHECKING and NA_IPSEC_CONTENT_DISCARD_MATCHING_PACKETS
 *       are mutually exclusive.
 *
 * @name IpsecPolicyContentRuleFlags    "IPSEC Policy Content Rule Flag Bit Definitions"
 *
 * @param NA_IPSEC_CONTENT_TUNNEL_MODE                                Set this bit to select tunnel mode, or leave it clear to select transport mode.
 * @param NA_IPSEC_CONTENT_ESP                                        Set this bit to select Encapsulating Security Protocol (ESP), or leave it clear to select Authentication Header (AH) protocol.
 * @param NA_IPSEC_CONTENT_SEPERATE_SA_FOR_EACH_REMOTE_IP_ADDRESS     Set this bit if a seperate SA is required for each remote IP address
 * @param NA_IPSEC_CONTENT_SEPERATE_SA_FOR_EACH_REMOTE_IP_PORT        Set this bit if a seperate SA is required for each remote IP port
 * @param NA_IPSEC_CONTENT_SEPERATE_SA_FOR_EACH_LOCAL_IP_ADDRESS      Set this bit if a seperate SA is required for each local IP address
 * @param NA_IPSEC_CONTENT_SEPERATE_SA_FOR_EACH_LOCAL_IP_PORT         Set this bit if a seperate SA is required for each local IP port
 * @param NA_IPSEC_CONTENT_SEPERATE_SA_FOR_EACH_PROTOCOL              Set this bit if a seperate SA is required for each IP protocol
 * @param NA_IPSEC_CONTENT_BYPASS_IPSEC_POLICY_CHECKING               Set this bit if packets that match the associated selector should bypass IPSEC policy checking
 * @param NA_IPSEC_CONTENT_DISCARD_MATCHING_PACKETS                   Set this bit if packets that match the associated selector should be discarded
 *
 * @see @link naIpsecPolicyContentSetRules
*ad*/
#define NA_IPSEC_CONTENT_TUNNEL_MODE                                (0x001)
#define NA_IPSEC_CONTENT_ESP                                        (0x008)
#define NA_IPSEC_CONTENT_SEPERATE_SA_FOR_EACH_REMOTE_IP_ADDRESS     (0x010)
#define NA_IPSEC_CONTENT_SEPERATE_SA_FOR_EACH_REMOTE_IP_PORT        (0x020)
#define NA_IPSEC_CONTENT_SEPERATE_SA_FOR_EACH_LOCAL_IP_ADDRESS      (0x040)
#define NA_IPSEC_CONTENT_SEPERATE_SA_FOR_EACH_LOCAL_IP_PORT         (0x080)
#define NA_IPSEC_CONTENT_SEPERATE_SA_FOR_EACH_PROTOCOL              (0x100)
#define NA_IPSEC_CONTENT_BYPASS_IPSEC_POLICY_CHECKING               (0x200)
#define NA_IPSEC_CONTENT_DISCARD_MATCHING_PACKETS                   (0x400)


/*ad*
 * Set the port field in an IPSEC Policy Selector to this value to select packets using
 * any port number.
 *
 * @external
 * @category Networking:IPSEC:Policy:Selector
 * @since 7.0
 *
*ad*/
#define IPSEC_POLICY_SELECTOR_ANY_PORT          (0)

/*ad*
 * Set the protocol field in an IPSEC Policy Selector to this value to select packets using
 * any protocol.
 *
 * @external
 * @category Networking:IPSEC:Policy:Selector
 * @since 7.0
 *
*ad*/
#define IPSEC_POLICY_SELECTOR_ANY_PROTOCOL      (0)


NaStatus naIpsecInitialize(void);
NaStatus naIpsecUninitialize(void);
NaStatus naIpsecIkeStart(NaIkeIdentifier_t *identifier, struct sockaddr_storage *address);
NaStatus naIpsecIkeSetPhase1Mode(NaIpsecIkeMode_t mode);
NaStatus naIpsecIkeSetPhase1AggressiveModeDHGroup(unsigned aggressiveDHGroup);
NaStatus naIpsecSetAntireplay(BOOLEAN enableAntireplay);
NaStatus naIpsecIkePhase2SetPfs(BOOLEAN enablePFS);
NaStatus naIpsecSetIcmpBypassMode(NaIpsecIcmpBypassMode_t mode);
NaStatus naIpsecSetIcmpv6BypassMode(BOOLEAN shouldBypass);
NaStatus naIpsecNestedIkeBypassMode(BOOLEAN shouldBypass);
NaStatus naIpsecIkeInitialContactMessageEnable(BOOLEAN enableInitialContactMessage);
NaStatus naIpsecIpDontFragmentBitSet(NaIpsecDontFragmentMode_t mode);
NaStatus naIpsecPresharedKeyAdd(NaIkeIdentifier_t *peerId, unsigned char *key);
NaStatus naIpsecPresharedKeyDelete(NaIkeIdentifier_t *peerId);
NaStatus naIpsecIkePhase1GetTransformHandle(NaIkePhase1TransformHandle_t *handle);
NaStatus naIpsecIkePhase1DeleteTransformHandle(NaIkePhase1TransformHandle_t handle);
NaStatus naIpsecIkePhase1SetEncryption(NaIkePhase1TransformHandle_t handle, NaIpsecEncryptionAlgorthm_t algorithm, unsigned keylength);
NaStatus naIpsecIkePhase1SetAuthentication(NaIkePhase1TransformHandle_t handle, NaIpsecAuthenticationAlgorithm_t algorithm);
NaStatus naIpsecIkePhase1SetDHGroup(NaIkePhase1TransformHandle_t handle, unsigned group);
NaStatus naIpsecIkePhase1SetLifetime(NaIkePhase1TransformHandle_t handle, unsigned seconds, unsigned kBytes);
NaStatus naIpsecIkePhase1TransformSet(NaIkePhase1TransformHandle_t handle, unsigned idx);
NaStatus naIpsecIkePhase1TransformDelete(unsigned idx);
NaStatus naIpsecIkeSendSaLifetimes(BOOLEAN wantToSendSaLifetimes);
NaStatus naIpsecPolicyTableCreate(NaIpsecPolicyTableHandle_t * handle, unsigned numberOfEntries);
NaStatus naIpsecPolicySet(NaIpsecPolicyTableHandle_t handle, unsigned idx,
                                unsigned selectorIndex, unsigned policyIndex,
                                NaIpsecDirection_t direction);
NaStatus naIpsecPolicyTableFree(NaIpsecPolicyTableHandle_t handle);
NaStatus naIpsecPolicyCheckingStart(NaIpsecPolicyTableHandle_t policyTable,
                                    NaIpsecPolicySelectorHandle_t selectorTable,
                                    NaIpsecPolicyContentHandle_t contentTable);
NaStatus naIpsecPolicyCheckingStop(void);
NaStatus naIpsecPolicySelectorTableCreate(NaIpsecPolicySelectorHandle_t * selector,
                                          unsigned numberOfEntries);
NaStatus naIpsecPolicySelectorTableDestroy(NaIpsecPolicySelectorHandle_t selector);
NaStatus naIpsecPolicySelectorSetLocalAddresses(NaIpsecPolicySelectorHandle_t selector,
                                        unsigned idx, NaIpsecAddressRange_t * range);
NaStatus naIpsecPolicySelectorSetRemoteAddresses(NaIpsecPolicySelectorHandle_t selector, unsigned idx, NaIpsecAddressRange_t * range);
NaStatus naIpsecPolicySelectorSetLocalPort(NaIpsecPolicySelectorHandle_t selector,
                                           unsigned idx, unsigned port);
NaStatus naIpsecPolicySelectorSetRemotePort(NaIpsecPolicySelectorHandle_t selector,
                                            unsigned idx, unsigned port);
NaStatus naIpsecPolicySelectorSetProtocol(NaIpsecPolicySelectorHandle_t selector,
                                    unsigned idx, unsigned protocol);
NaStatus naIpsecPolicyContentTableCreate(NaIpsecPolicyContentHandle_t * content,
                                         unsigned numberOfEntries);
NaStatus naIpsecPolicyContentTableDelete(NaIpsecPolicyContentHandle_t content);
NaStatus naIpsecPolicyContentSetLocalAddress(NaIpsecPolicyContentHandle_t content,
                                             unsigned idx,
                                             struct sockaddr_storage *address);
NaStatus naIpsecPolicyContentSetRemoteAddress(NaIpsecPolicyContentHandle_t content,
                                              unsigned idx,
                                              struct sockaddr_storage *address);
NaStatus naIpsecPolicyContentSetRules(NaIpsecPolicyContentHandle_t content,
                                      unsigned idx,
                                      unsigned rules);
NaStatus naIpsecPolicyContentSetAuthentication(NaIpsecPolicyContentHandle_t content,
                                               unsigned idx,
                                               NaIpsecAuthenticationAlgorithm_t algorithm);
NaStatus naIpsecPolicyContentSetEncryption(NaIpsecPolicyContentHandle_t content,
                                               unsigned idx,
                                               NaIpsecEncryptionAlgorthm_t algorithm);
NaStatus naIpsecPolicyContentSetLifetimes(NaIpsecPolicyContentHandle_t content,
                                               unsigned idx,
                                               unsigned seconds,
                                               unsigned kilobytes);
NaStatus naIpsecSaCreate(NaIpsecSaHandle_t * handle);
NaStatus naIpsecSaDestroy(NaIpsecSaHandle_t handle);
NaStatus naIpsecSaSetDirection(NaIpsecSaHandle_t handle, NaIpsecDirection_t direction);
NaStatus naIpsecSaSetSpi(NaIpsecSaHandle_t handle, unsigned spi);
NaStatus naIpsecSaSetPolicySelector(NaIpsecSaHandle_t handle, NaIpsecPolicySelectorHandle_t selectorTable, unsigned idx);
NaStatus naIpsecSaSetPolicyContent(NaIpsecSaHandle_t handle, NaIpsecPolicyContentHandle_t contentTable, unsigned idx);
NaStatus naIpsecSaSetEncryptionKey(NaIpsecSaHandle_t handle, unsigned char *key);
NaStatus naIpsecSaSetAuthenticationKey(NaIpsecSaHandle_t handle, unsigned char *key);
NaStatus naIpsecSaSetFate(NaIpsecSaHandle_t handle, BOOLEAN isPermanent);
NaStatus naIpsecSaActivate(NaIpsecSaHandle_t handle);
NaStatus naIpsecSaDeactive(NaIpsecSaHandle_t handle);









#endif
