IPsec/IKE Examples

Jump to: navigation, search

Table of Contents >> IPsec/IKE Programmer's Reference

The IP addresses in the following examples are fictitious. User is responsible to substitute them with real addresses. We use IPv4 address as an example, IPv6 is similar. The examples assume user is already familiar with Treck TCP/IP stack for normal usage, and it is listed here emphasizing how to use IPsec and IKE only. (If the user does not wish to use IPsec or IKE, see the Treck User's Manual for other details.)


IKE and IPsec Configuration

{
    struct sockaddr_storage     myIp4Addr;
    struct sockaddr_storage     remoteAddr;
    ttIpsecPolicyPair           policyPair;
    ttIpsecSelectorInString     selectorInString;
    ttPolicyContentInString     policyContentInString;
    int                         errorCode;
    ttUser16Bit                 priority;
 
 
    tm_bzero(&myIp4Addr, sizeof(struct sockaddr_storage));
    tm_bzero(&remoteAddr, sizeof(struct sockaddr_storage));
 
    inet_pton(AF_INET,
              "1.1.1.1.",
              &(myIp4Addr.addr.ipv4.sin_addr));
    myIp4Addr.ss_len = sizeof(struct sockaddr_storage);
    myIp4Addr.ss_family = AF_INET;
 
    inet_pton(AF_INET,
              "2.2.2.2",
              &(remoteAddr.addr.ipv4.sin_addr));
    remoteAddr.ss_len = sizeof(struct sockaddr_storage);
    remoteAddr.ss_family = AF_INET;
 
 
/* Setup IPsec */
    errorCode = tfUseIpsec();
    assert(errorCode == TM_ENOERROR);
 
/* Add a simple bypass policy */
#ifdef ADD_BYPASS_POLICY
    tm_bzero(&policyPair, sizeof(ttIpsecPolicyPair));
    tm_bzero(&selectorInString, sizeof(ttIpsecSelectorInString));
    tm_bzero(&policyContentInString, sizeof(ttPolicyContentInString));
    policyPair.ippPriority = 20;
    policyPair.ippDirection = TM_IPSEC_BOTH_DIRECTION;
    policyContentInString.pctstrRuleFlags = TM_PFLAG_BYPASS;
    errorCode = tfPolicyRestore(&policyPair,
                                &selectorInString,
                                &policyContentInString,
                                1);
    assert(errorCode == TM_ENOERROR);
#endif /* ADD_BYPASS_POLICY */
 
/* Add a policy between 1.1.1.1 and 2.2.2.2 with wildcarded ports */
    tm_bzero(&policyPair, sizeof(ttIpsecPolicyPair));
    tm_bzero(&selectorInString, sizeof(ttIpsecSelectorInString));
    tm_bzero(&policyContentInString, sizeof(ttPolicyContentInString));
    policyPair.ippPriority = 10;
    policyPair.ippDirection = TM_IPSEC_BOTH_DIRECTION;
#ifdef TM_USE_IKE_POLICIES
/* IKE policies and IPsec policies cannot overlap */
    policyPair.ippIkePolicy = 10*5;
#endif /* TM_USE_IKE_POLICIES */
    policyPair.ippProposalNumber = 1;
    policyPair.ippTransformNumber = 1;
    selectorInString.selstrIpFlags =   TM_SELECTOR_LOCIP_HOST
                                     | TM_SELECTOR_REMTIP_HOST;
    selectorInString.selstrLocIp1 = "1.1.1.1";
    selectorInString.selstrRemtIp1 = "2.2.2.2";
    policyContentInString.pctstrRuleFlags = TM_PFLAG_ESP | TM_PFLAG_TRANSPORT;
    policyContentInString.pctstrLocIpAddr = "1.1.1.1";
    policyContentInString.pctstrRemtIpAddr = "2.2.2.2";
    policyContentInString.pctstrEncryptAlg = SADB_EALG_3DESCBC;
    policyContentInString.pctstrAuthAlg = SADB_AALG_SHA1HMAC;
    policyContentInString.pctstrProposalNumber = 1;
    policyContentInString.pctstrTransformNumber = 1;
    policyContentInString.pctstrLifeKbytes = 1000;
    policyContentInString.pctstrLifeSeconds = 3600;
    errorCode = tfPolicyRestore(&policyPair,
                                &selectorInString,
                                &policyContentInString,
                                1);
    assert(errorCode == TM_ENOERROR);
 
 
/* Setup IKE */
#ifndef TM_USE_IKE_POLICIES
   errorCode = tfPresharedKeyAdd("2.2.2.2",
                                 "-presharedKey#1-",
                                 0);
   assert(errorCode == TM_ENOERROR);
#else /* !TM_USE_IKE_POLICIES */
    tm_bzero(&plcyInStr, sizeof(ttIkePolicyInString));
    plcyInStr.ikpsSelectorString.selstrLocIp1 = "1.1.1.1";
    plcyInStr.ikpsSelectorString.selstrRemtIp1 = "2.2.2.2";
    plcyInStr.ikpsSelectorString.selstrIpFlags =   TM_SELECTOR_LOCIP_HOST
                                                 | TM_SELECTOR_REMTIP_HOST;
    plcyInStr.ikpsAttributes =   TM_IKE_ROLE_INITIATOR
                               | TM_IKE_ROLE_RESPONDER
                               | TM_IKE_MODE_MAIN
                               | TM_IKE_TRECK;
    plcyInStr.ikpsPhase2Dhgroup = (ttUser8Bit)0;
    plcyInStr.ikpsPskPtr = "-presharedKey#1-";
    plcyInStr.ikpsPskLen = (ttUser16Bit)(tm_strlen(plcyInStr.ikpsPskPtr));
 
    tm_bzero(&transDataList, sizeof(ttIsakmpTransData));
    transDataList.transLifeSeconds = 240;
    transDataList.transLifeKbytes =  10;
    transDataList.transKeyLength = 0;
    transDataList.transEncryptAlg = TM_IKE_3DES_CBC;
    transDataList.transHashAlg = TM_IKE_MD5;
    transDataList.transAuthMethod = TM_IKE_PRESHARED_KEY;
    transDataList.transDhgroup = TM_DHGROUP_2;
    transCount = (ttUser8Bit)1;
/* IKE policies and IPsec policies cannot overlap */
    priority = (ttUser16Bit)10*5;
    errorCode = tfIkePolicyAddByPriority(&plcyInStr,
                                         &transDataList,
                                         transCount,
                                         priority);
    assert(errorCode == TM_ENOERROR);
#endif /* !TM_USE_IKE_POLICIES */
}


Manual keying

/*
 * Define the Policy
 * Since IPSEC will be used, for any traffic(even the bypass one), we need to 
 * have its policy.
 * Policies at 1.1.1.1, in the order of preference:
 * --- Any protocol, any port traffic between 1.1.1.0/24 and 2.2.1.0/24, use
 * ESP tunnel mode + AH transport mode to protect. ESP algorithm: 3DES-CBC+
 * MD5-HMAC-96 and, AH algorithm: SHA1-HMAC-96. Tunneled between 1.1.1.1 to
 * 2.2.2.1, use packet value for upper layer protocols.
 * --- Any to Any, BYPASS IPsec.
 */
/*
 * Set trsystem.h
 * Define TM_USE_IPSEC in trsystem.h
 */
#include <stdio.h>
#include <trsecapi.h>
#define TM_BUF_ARRAY_SIZE 4000
 
char bufferArray[TM_BUF_ARRAY_SIZE];
char bufferReceive[TM_BUF_ARRAY_SIZE];
static void testUdp(ttUserIpAddress clientIpAddr,
                    ttUserIpAddress peerIpAddr,
                    int iterations);
static int addPolicyAndSa(void);
static int testIpsecDifferentPolicy(ttUserIpAddress clientIpAddr,
                                    ttUserIpAddress peerIpAddr,
                                    int iterations);
int main()
{
    ttUserLinkLayer linkLayerHandle;
    ttUserInterface interfaceHandle;
    ttUserIpAddress clientIPAddr;
    ttUserIpAddress peerIPAddr;
    ttUserIpAddress mask;
    int configFlags;
    int scatteredBufferCount;
    int errorCode;
    int iterations;
 
    /* Allow scatter send */
    configFlags = TM_DEV_SCATTER_SEND_ENB;
    iterations = 100;
    clientIPAddr = inet_addr("1.1.1.1");
    peerIPAddr = inet_addr("2.2.2.1");
    mask = inet_addr("255.255.255.0");
 
    if (configFlags & TM_DEV_SCATTER_SEND_ENB)
    {
        scatteredBufferCount = 1501;
    }
    else
    {
        scatteredBufferCount = 1;
    }
/* Start Treck */
    errorCode = tfStartTreck();
    if (errorCode != TM_ENOERROR)
    {
        printf( "tfStartTreck failed '%s'\n", tfStrError(errorCode));
        return errorCode;
    }
/* Add driver interface below Ethernet link layer */
    linkLayerHandle = tfUseEthernet();
    interfaceHandle = tfUseLinuxDriver("TEST",
                                        linkLayerHandle,
                                        &errorCode);
    if (errorCode != TM_ENOERROR)
    {
        printf("Adding interface driver failed '%s'",
        tfStrError(errorCode) );
        return errorCode;
    }
/*
 * Call tfUseIpsec
 * Initialize IPsec global variables
 */
    errorCode = tfUseIpsec();
    if (errorCode != TM_ENOERROR)
    {
        printf("tfUseIpsec failed '%s'\n");
        return errorCode;
    }
/*
 * Add policy and SA
 * add SdbRecord should be done manually in current stage
 */
    errorCode = addPolicyAndSa();
    if (errorCode != TM_ENOERROR)
    {
        printf("addPolicyAndSa failed \n");
        return errorCode;
    }
/* Open the added interface */
    errorCode = tfOpenInterface( interfaceHandle,
                                    clientIPAddr,
                                    mask,
                                    configFlags,
                                    scatteredBufferCount );
/* for IPv6, you may need to call tfNgOpenInterface*/
    if (errorCode != TM_ENOERROR)
    {
        printf("tfConfigInterface failed '%s'\n", tfStrError(errorCode));
        return errorCode;
    }
/* Run different policy combinations */
    testIpsecDifferentPolicy(clientIPAddr, peerIPAddr, iterations);
    return errorCode;
}
/* Procedure addPolicyAndSa */
static int addPolicyAndSa (void)
{
    const char keyMat1[] = "abcdefghijklmnopqrstabcdefghijklmnopqrstuvwx";
    const char keyMat2[] = "13fhalsafdyijkafaslfdsfsafghijklmnopqrstuvwx";
#ifdef TEST_USE_BUNDLE
    const char keyMat3[] = "idsaoaejnuoafjklaoipdsads";
    const char keyMat4[] = "afd09rewtjkl891trewxc9765";
#endif /* TEST_USE_BUNDLE */
    ttSadbRecordPtr sadbPtr;
 
    int errorCode = 0;
/* 
 * Input Selector, Policy Content, Policy Matching Pairs. 
 * Call tfPolicyRestore 
 */
    ttIpsecSelectorInString plcySelector[] =
    {
/* selector #0, ANY to ANY */
        {
/* local ip and mask, or ipmin and ipmax if selector is a range */
            (char*)0, 0,
/* remote ip and mask,or ipmin and ipmax if selector is a range */
            (char*)0, 0,
/* ip flags */
            (tt16Bit)0 ,
/* local and remote port */
            TM_SELECTOR_WILD_PORT, TM_SELECTOR_WILD_PORT,
/* protocol */
            TM_SELECTOR_WILD_PROTOCOL,
        },
/* selector #1, From 1.1.1.0/24 to 2.2.2.1, any port, any protocol */
        {
            "1.1.1.0", 24,
            "2.2.2.1", (char *)0,
            TM_SELECTOR_LOCIP_SUBNET +
            TM_SELECTOR_USE_PREFIX_LENGTH +
            TM_SELECTOR_REMTIP_HOST,
            TM_SELECTOR_WILD_PORT, TM_SELECTOR_WILD_PORT,
            TM_SELECTOR_WILD_PROTOCOL,
        },
/* selector #2, From 1.1.1.0/24 to 2.2.2.1, any port, UDP protocol */
        {
            "1.1.1.0", 24,
            "2.2.2.1", (char *)0,
            TM_SELECTOR_LOCIP_SUBNET +
            TM_SELECTOR_USE_PREFIX_LENGTH +
            TM_SELECTOR_REMTIP_HOST,
            TM_SELECTOR_WILD_PORT, TM_SELECTOR_WILD_PORT,
            IPPROTO_UDP,
        }
    };
 
    ttPolicyContentInString plcyContent[] =
    {
/* policy content #0 */
        {
/* tunnel local IP, don't care if not for tunnel mode */
            (char*)0,
/* tunnel remote IP, don't care if not for tunnel mode */
            (char*)0,
/* policy rules */
            TM_PFLAG_BYPASS,
/* authentication algorithm */
            0,
/* encryption algorithm */
            0,
/* lifetime in seconds, if zero, use default value */
            0,
/* lifetime in kilo-bytes, if zero, use default value */
            0,
        },
/* policy content #1 */
        {
            "1.1.1.1",
            "2.2.2.1",
            TM_PFLAG_ESP + TM_PFLAG_TUNNEL + TM_PFLAG_PROTO_PACKET,
            SADB_AALG_MD5HMAC,
            SADB_EALG_3DESCBC,
            0,
            0
        },
/* policy content #2 */
        {
            (char*)0,
            (char*)0,
            TM_PFLAG_AH + TM_PFLAG_TRANSPORT + TM_PFLAG_PROTO_PACKET,
            SADB_AALG_SHA1HMAC,
            0,
            0,
            0
        }
    };
/* This is a VERY important table. This specifies which rules are
 * applied to received packets (TM_IPSEC_INBOUND), sent packets
 * (TM_IPSEC_OUTBOUND), AND IN WHAT ORDER. 
 */
    ttIpsecPolicyPair plcyPair[] =
    {
        {0, 0, TM_IPSEC_BOTH_DIRECTION},
        {1, 1, TM_IPSEC_BOTH_DIRECTION},
        {1, 2, TM_IPSEC_BOTH_DIRECTION}
/* 
 *In the last entry, selector index (1) is same as the previous entry,
 * that means they are bundled policy contents, they must worked
 * together to protect the traffic. The inner policy content (index =1,
 * the ESP tunnel one) will be applied first, followed by the outer
 * policy content (index = 2, the AH transport one) 
 */
/* 
 * Also notice that selector index 2 is not used here. We are going to use
 * it to generate SA manually 
 */
    };
    errorCode = tfPolicyRestore(plcyPair,
                                plcySelector,
                                plcyContent,
                                3);
    if(errorCode != TM_ENOERROR )
    {
        return errorCode;
    }
/*
 * Manually add four SAs for UDP packet
 * User is responsible to add SAs for TCP, ICMP packets. Each policy
 * content needs two SAs (inbound + outboud), we have bundle policy
 * contents, so we need to add four SAs for protecting UDP packets. 
 */
 
/* 
 *Add one pair of SA according to the inner policy (policy content =
 * 1),inbound SPI = 1000, use keymaterial keyMat1; outbound SPI = 1100,
 * use keymaterial keyMat2. plcySelector[2] is specified selector for UDP
 * packet \
 */
 
    errorCode = tfSadbRecordManualAdd(&sadbPtr,
                                        TM_IPSEC_INBOUND,
                                        1000,
                                        &plcySelector[2],
                                    /* the ESP tunnel content*/
                                        1,
                                        keyMat1,
                                    /* 3des + md5: we need at least 40 bytes */
                                        44);
    if (errorCode)
    {
        goto COMMON_RETURN;
    }
 
    errorCode = tfSadbRecordManualAdd(&sadbPtr,
                                        TM_IPSEC_OUTBOUND,
                                        1100,
                                        &plcySelector[2],
                                        1,
                                        keyMat2,
                                        44);
    if (errorCode)
    {
        goto COMMON_RETURN;
    }
/* 
 * Add one pair of SA according to the outer policy (policy content = 2),
 * inbound SPI = 2000, use keymaterial keyMat3; outbound SPI = 2100, use
 * keymaterial keyMat4. plcySelector[2] is specified selector for UDP
 * packet 
 */
 
    errorCode = tfSadbRecordManualAdd(&sadbPtr,
                                        TM_IPSEC_INBOUND,
                                        2000,
                                        &plcySelector[2],
                                        2,
                                        keyMat3,
                                        25);/*sha1, we need at least 20*/
    if (errorCode)
    {
        goto COMMON_RETURN;
    }
 
    errorCode = tfSadbRecordManualAdd(&sadbPtr,
                                        TM_IPSEC_OUTBOUND,
                                        2100,
                                        &plcySelector[2],
                                        2,
                                        keyMat4,
                                        25);
COMMON_RETURN:
    return errorCode;
}
 
/* Procedure testIpsecDifferentPolicy */
 
static int testIpsecDifferentPolicy(ttUserIpAddress clientIPAddr,
ttUserIpAddress peerIPAddr,
int iterations)
{
    ttIpsecSelector selector;
    ttSadbRecordPtr sadbPtr;
    ttPolicyEntryPtr plcyPtr;
    int errorCode = 0;
 
    errorCode = tfIpsecPolicyQueryByIndex(1, &plcyPtr);
 
    if(errorCode != TM_ENOERROR)
    {
        return errorCode;
    }
 
    tm_bzero(&selector, sizeof(ttIpsecSelector));
/* UDP IPsec test*/
 
    printf("Case 1: UDP in IPsec, no IKE. Use the manaully input SA \n");
    testUdp( clientIPAddr, peerIPAddr,iterations);
    selector.selLocIp1.ss_family = PF_INET;
    selector.selRemtIp1.ss_family = PF_INET;
    selector.selLocIp1.ss_len = sizeof(struct sockaddr_in);
    selector.selRemtIp1.ss_len = sizeof(struct sockaddr_in);
    selector.selLocIp1.addr.ipv4.sin_addr_s_addr = inet_addr("1.1.1.1");
    selector.selRemtIp1.addr.ipv4.sin_addr.s_addr = inet_addr("2.2.2.1");
    selector.selRemtPort = 0;
    selector.selLocPort = 0; /* not used anyway*/
    selector.selProtocol = TM_IP_UDP;
    selector.selIpFlags = TM_SELECTOR_BOTHIP_HOST;
    /* Delete the outer SA and test again, should drop the packet */
    tfSadbRecordFind(0,
                    &selector,
                    &sadbPtr, plcyPtr,
                    plcyPtr->plcyContentPtr->pctOuterContentPtr,
                    TM_IPSEC_OUTBOUND);
    if(sadbPtr)
    {
        errorCode = tfSadbRecordDelete(0, sadbPtr);
        if(errorCode != TM_ENOERROR)
        {
            return errorCode;
        }
    }
 
    printf("\nCase 2: UDP in IPsec, without outer outbound SA,"
                "drop the packet\n");
 
    testUdp( clientIPAddr, peerIPAddr,iterations);
 
/* 
 * Delete the outbound Policy, will use the BYPASS policy, incoming policy
 * check fails 
 */
    tfPolicyDelete(plcyPtr, TM_IPSEC_OUTBOUND);
    printf("\nCase 3: UDP in IPsec, no outbound policy, will "
                "use the bypass policy.(Will fail in "
                "the inbound policy check ) \n");
    testUdp( clientIPAddr, peerIPAddr,iterations);
/* Delete the inbound policy, use BYPASS policy */
    tfPolicyDelete(plcyPtr, TM_IPSEC_INBOUND);
    printf("\nCase 4: UDP in IPsec, no specific policy except "
                "bypass, should pass\n");
    testUdp( clientIPAddr, peerIPAddr,iterations);
/* delete all policies, fail because no policy found */
    tfPolicyClear();
    printf("\nCase 5: No bypass policy, send-out error\n");
    testUdp(clientIPAddr, peerIPAddr, iterations);
    return TM_ENOERROR;
}
/* 
 * The testUdp is just a UDP send /receive example, user may refer to
 * Treck User Manual for details. It is not provided here. 
 */


IKE (Automatic keying)

/*
 * IKE (Automatic keying)
 * Define the Policy
 * Since IPSEC will be used, for any traffic(even the bypass one), we need
 * to have its policy.
 * Policies at 1.1.1.1, in the order of preference:
 * Any protocol, any port traffic between 1.1.1.0/24 and 2.2.1.0/24, use
 * ESP tunnel mode + AH transport mode to protect. ESP algorithm: 3DES
 * CBC+ MD5-HMAC-96 and, AH algorithm: SHA1-HMAC-96. Tunneled between
 * 1.1.1.1 to 2.2.2.1, use packet value for upper layer protocols.
 * Any to Any, BYPASS IPsec.
 */
/*
 * Settings in trsystem.h
 * Define TM_USE_IPSEC
 * Define TM_USE_IKE
 * And make sure you need PFS feature or not, are you going to use
 * Aggressive mode or not. See section 3 for the settings of each
 * IPsec|IKE related macros 
 */
 
#include <stdio.h>
#include <trsecapi.h>
#define TM_BUF_ARRAY_SIZE 4000
 
char bufferArray[TM_BUF_ARRAY_SIZE];
char bufferReceive[TM_BUF_ARRAY_SIZE];
static void testUdp(ttUserIpAddress clientIpAddr,
                        ttUserIpAddress peerIpAddr,
                        int iterations);
static int addPolicyAndPsk(void);
static int testIpsecDifferentPolicy(ttUserIpAddress clientIpAddr,
                        ttUserIpAddress peerIpAddr,
                        int iterations);
 
int main ()
{
    ttUserLinkLayer linkLayerHandle;
    ttUserInterface interfaceHandle;
    ttUserIpAddress clientIPAddr;
    ttUserIpAddress peerIPAddr;
    ttUserIpAddress mask;
    int configFlags;
    int scatteredBufferCount;
    int errorCode;
    int iterations;
 
/* Allow scatter send */
    configFlags = TM_DEV_SCATTER_SEND_ENB;
    iterations = 100;
 
    clientIPAddr = inet_addr("1.1.1.1");
    peerIPAddr = inet_addr("2.2.2.1");
    mask = inet_addr("255.255.255.0");
    if (configFlags & TM_DEV_SCATTER_SEND_ENB)
    {
        scatteredBufferCount = 1501;
    }
    else
    {
        scatteredBufferCount = 1;
    }
/*
 * Start Treck
 */
    errorCode = tfStartTreck();
    if (errorCode != TM_ENOERROR)
    {
        printf( "tfStartTreck failed '%s'\n", tfStrError(errorCode));
        return errorCode;
    }
/*
 * Add driver interface below Ethernet link layer
 */
    linkLayerHandle = tfUseEthernet();
    interfaceHandle = tfUseLinuxDriver("TEST",
                                        linkLayerHandle,
                                        &errorCode);
    if (errorCode != TM_ENOERROR)
    {
        printf("Adding interface driver failed '%s'",
        tfStrError(errorCode) );
        return errorCode;
    }
/*
 * Call tfUseIpsec
 * Initialize IPsec global variables
 */
    errorCode = tfUseIpsec();
    if (errorCode != TM_ENOERROR)
    {
        printf( "tfUseIpsec failed '%s'\n");
        return errorCode;
    }
/*
 *  Add policy
 * For IKE, you don't need to add SA
 */
 
    errorCode = addPolicy();
    if (errorCode != TM_ENOERROR)
    {
        printf( "addPolicy failed \n");
        return errorCode;
    }
/* Open the added interface */
 
    errorCode = tfOpenInterface( interfaceHandle,
                                    clientIPAddr,
                                    mask,
                                    configFlags,
                                    scatteredBufferCount );
    if (errorCode != TM_ENOERROR)
    {
        printf("tfConfigInterface failed '%s'\n", tfStrError(errorCode));
        return errorCode;
    }
/*
 * Call tfStartIke
 * start IKE
 */
    errorCode = tfStartIke(TM_DOI_ID_IPV4_ADDR, 4, (void*)&clientIPAddr);
    if (errorCode != TM_ENOERROR)
    {
        printf( "tfUseIpsec failed '%s'\n");
        return errorCode;
    }
/*
 * Add Preshared-key
 * For IKE, you don't need to add SA
 */
    errorCode = tfPresharedKeyAdd("2.2.2.1", "presharedKey#1", 0);
    if (errorCode != TM_ENOERROR)
    {
        printf( "add preshared key failed \n");
        return errorCode;
    }
/*
 * Test case
 * Run different policy combinations
 */
 
    testIpsecDifferentPolicy(clientIPAddr, peerIPAddr, iterations);
    return errorCode;
}
/* Procedure addPolicy */
static int addPolicy (void)
{
    int errorCode = 0;
    ttIpsecSelectorInString plcySelector[] =
    {
/* selector #0, ANY to ANY */
        {
            (char*)0, 0,
            (char*)0, 0,
            (tt16Bit)0 ,
            TM_SELECTOR_WILD_PORT, TM_SELECTOR_WILD_PORT,
            TM_SELECTOR_WILD_PROTOCOL,
        },
/* selector #1, From 1.1.1.0/24 to 2.2.2.1, any port, any protocol */
        {
            "1.1.1.0", int)"255.255.255.0",
            "2.2.2.1", 0,
            TM_SELECTOR_LOCIP_SUBNET + TM_SELECTOR_REMTIP_HOST,
            TM_SELECTOR_WILD_PORT, TM_SELECTOR_WILD_PORT,
            TM_SELECTOR_WILD_PROTOCOL,
        }
    };
 
    ttPolicyContentInString plcyContent[] =
    {
/* policy content #0 */
        {
            (char*)0,
            (char*)0,
            TM_PFLAG_BYPASS,
            0,
            0,
            0,
            0
            },
/* policy content #1 */
        {
            "1.1.1.1",
            "2.2.2.1",
            TM_PFLAG_ESP + TM_PFLAG_TUNNEL + TM_PFLAG_PROTO_PACKET,
            Treck IPsec/IKE User Manual
            127
            SADB_AALG_MD5HMAC,
            SADB_EALG_3DESCBC,
            0,
            0
        },
/* policy content #2 */
        {
            (char*)0,
            (char*)0,
            TM_PFLAG_AH + TM_PFLAG_TRANSPORT + TM_PFLAG_PROTO_PACKET,
            SADB_AALG_SHA1HMAC,
            0,
            0,
            0
        }
    };
 
    ttIpsecPolicyPair plcyPair[] =
    {
        {0, 0, TM_IPSEC_BOTH_DIRECTION},
        {1, 1, TM_IPSEC_BOTH_DIRECTION},
        {1, 2, TM_IPSEC_BOTH_DIRECTION}
    };
 
    errorCode = tfPolicyRestore(plcyPair,
                                    plcySelector,
                                    plcyContent,
                                    3);
 
    if(errorCode != TM_ENOERROR )
    {
        return errorCode;
    }
COMMON_RETURN:
    return errorCode;
}
/* Procedure testIpsecDifferentPolicy */
static int testIpsecDifferentPolicy(ttUserIpAddress clientIPAddr,
                                    ttUserIpAddress peerIPAddr,
                                    int iterations)
{
    ttIpsecSelector selector;
    ttSadbRecordPtr sadbPtr;
    ttPolicyEntryPtr plcyPtr;
 
    int errorCode = 0;
    errorCode = tfIpsecPolicyQueryByIndex(1, &plcyPtr);
    if(errorCode != TM_ENOERROR) return errorCode;
    tm_bzero(&selector, sizeof(selector));
/* UDP IPsec test*/
    printf("Case 1: UDP in IPsec, Should trigger IKE and after IKE, "
                    "send the packets \n");
    testUdp( clientIPAddr, peerIPAddr,iterations);
 
    selector.selLocIp1.ss_family = PF_INET;
    selector.selRemtIp1.ss_family = PF_INET;
    selector.selLocIp1.ss_len = sizeof(struct sockaddr_in);
    selector.selRemtIp1.ss_len = sizeof(struct sockaddr_in);
    selector.selLocIp1.addr.ipv4.sin_addr_s_addr = inet_addr("1.1.1.1");
    selector.selRemtIp1.addr.ipv4.sin_addr.s_addr = inet_addr("2.2.2.1");
    selector.selRemtPort = 0;
    selector.selLocPort = 0; /* not used anyway*/
    selector.selProtocol = TM_IP_UDP;
    selector.selIpFlags = TM_SELECTOR_BOTHIP_HOST;
 
/* 
 * Delete the outer SA and test again, should trigger IKE again to
 * negotiate an outer SA 
 */
    tfSadbRecordFind(0,
                    &selector,
                    &sadbPtr,
                    plcyPtr,
                    plcyPtr->plcyContentPtr->pctOuterContentPtr,
                    TM_IPSEC_OUTBOUND);
    if(sadbPtr)
    {
        errorCode = tfSadbRecordDelete(0, sadbPtr);
 
        if(errorCode != TM_ENOERROR) 
        {
            return errorCode;
        }
    }
 
    printf("\nCase 2: UDP in IPsec, without outer outbound SA, "
                    "trigger IKE again \n");
 
    testUdp( clientIPAddr, peerIPAddr,iterations);
/* 
 * Delete the outbound Policy, will use the BYPASS policy, incoming policy
 * check fails 
 */
    tfPolicyDelete(plcyPtr, TM_IPSEC_OUTBOUND);
    printf("\nCase 3: UDP in IPsec, no outbound policy, will "
                    "use the bypass policy.(Will fail in "
                    "the inbound policy check ) \n");
    testUdp( clientIPAddr, peerIPAddr,iterations);
 
/* Delete the inbound policy, use BYPASS policy*/
    tfPolicyDelete(plcyPtr, TM_IPSEC_INBOUND);
    printf("\nCase 4: UDP in IPsec, no specific policy except "
                    "bypass, should pass\n");
    testUdp( clientIPAddr, peerIPAddr,iterations);
 
/* delete all policies, fail because no policy found */
    tfPolicyClear();
    printf("\nCase 5: No bypass policy, send-out error\n");
    testUdp(clientIPAddr, peerIPAddr, iterations);
 
    return TM_ENOERROR;
}
/* 
 * The testUdp is just a UDP send /receive example, user may refer to
 * Treck User Manual for details. It is not provided here. 
 */
 


Table of Contents >> IPsec/IKE Programmer's Reference