Subject: spd for tunnel

From: Naveen BN <[email-masked]>
Date: Thu, 15 Oct 2009 13:05:25 +0530

Hi all,
Please find the below example code for framing tunnel mode secured 
policy for a range of ipaddress.
I am not able to create a security policy . Please help me to resolve 
this issue.

INT32   ipsec_spd_add(INT32 dir, INT32 proto, INT32 level, INT8 * addr1,
            UINT16 sPort, INT8 * addr2, UINT16 dPort, INT8 * proxy_addr) {
        INT8   *buf = NULL;
        INT32   off = 0;
        INT32   len = 0;
        INT32   so = 0;
        SEC_SOCKADDR_T sa1;
        SEC_SOCKADDR_T sa2;
        SEC_SOCKADDR_T proxy;
        struct sadb_address *proxy_ext;
        struct sadb_x_policy *policy;
        struct sadb_x_ipsecrequest *req;

        /*Address1 */
        xmemset(&sa1, 0, sizeof(SEC_SOCKADDR_T));
        sa1.sin_family = OSA_PF_INET;
        sa1.sin_port = htons(sPort);
        /* it returns zero, if input is invalid */
        if (SEC_INET_ATON(addr1, &(sa1.sin_addr)) == 0) {
            printf("invalid address\n");
            return IPSEC_ERROR;
        }

        /*Address2 */
        xmemset(&sa2, 0, sizeof(SEC_SOCKADDR_T));
        sa2.sin_family = OSA_PF_INET;
        sa2.sin_port = htons(dPort);
        /* it returns zero, if input is invalid */
        if (SEC_INET_ATON(addr2, &(sa2.sin_addr)) == 0) {
            printf("invalid address\n");
            return IPSEC_ERROR;
        }

        /*Proxy */
        if (proxy_addr) {
                        xmemset(&proxy, 0, sizeof(SEC_SOCKADDR_T));
            proxy.sin_family = OSA_PF_INET;
            proxy.sin_port = 0;
            /* it returns zero, if input is invalid */
            if (SEC_INET_ATON(proxy_addr, &(proxy.sin_addr)) == 0) {
                printf("invalid address\n");
                return IPSEC_ERROR;
            }
        }
        //buf = (INT8 *)xcalloc(1,1024);
        buf = xcalloc(1, 1024);
        if (buf == NULL) {
            printf("cant allocate enough memory\n");
            return IPSEC_ERROR;
        }
        xmemset(buf, 0, 1024);
        if ((so = pfkey_open()) < 0) {
            printf("pfkey_open() error\n");
            SEC_FREE(buf);
            return IPSEC_ERROR;
        }

        len = PFKEY_ALIGN8(sizeof(struct sadb_x_policy));

        //policy = (struct sadb_x_policy *)&pbuf->buf[pbuf->off];
        policy = (struct sadb_x_policy *)&buf[off];
        xmemset(policy, 0, sizeof(*policy));
        policy->sadb_x_policy_len = PFKEY_UNIT64(len);
        /* update later */
        policy->sadb_x_policy_exttype = SADB_X_EXT_POLICY;
        policy->sadb_x_policy_type = IPSEC_POLICY_IPSEC;
        policy->sadb_x_policy_dir = dir;    //IPSEC_DIR_OUTBOUND;

        off += len;

        len = PFKEY_ALIGN8(sizeof(struct sadb_x_ipsecrequest));

        req = (struct sadb_x_ipsecrequest *)&buf[off];
        xmemset(req, 0, sizeof(struct sadb_x_ipsecrequest));
        req->sadb_x_ipsecrequest_len = len; /* updated later */
        req->sadb_x_ipsecrequest_proto = proto;
        req->sadb_x_ipsecrequest_mode =(proxy_addr == NULL ? 
IPSEC_MODE_TRANSPORT
             : IPSEC_MODE_TUNNEL);
               req->sadb_x_ipsecrequest_level = level;

        off += len;

        if (proxy_addr) {
            len=PFKEY_ALIGN8(sizeof(struct sadb_address));
             proxy_ext=(struct sadb_address*)&buf[off];
            xmemset(proxy_ext,0,sizeof(struct sadb_address));
            proxy_ext->sadb_address_len=PFKEY_UNIT64(len);
            proxy_ext->sadb_address_exttype=SADB_EXT_ADDRESS_PROXY;
            off +=len;
            printf("\n ############ Filling proxy_addr message 
##########");             //len = PFKEY_ALIGN8(proxy->sa_len);
            len = PFKEY_ALIGN8(sizeof(SA));
            xmemset(&buf[off], 0, len);
            //xmemcpy(&pbuf->buf[pbuf->off], proxy, proxy->sa_len);
            xmemcpy(&buf[off], &proxy, sizeof(SA));
            req->sadb_x_ipsecrequest_len += len;
            off += len;
        }

        policy->sadb_x_policy_len = PFKEY_UNIT64(off);

        if ((pfkey_send_spdadd(so, (SA *) & sa1, 32, (SA *) & sa2, 32, 255,
                        (caddr_t) buf, off, 0)) < 0) {
            printf("pfkey_send_spdadd() error\n");
            SEC_FREE(buf);
            return IPSEC_ERROR;
        }
        free(buf);
        return IPSEC_SUCCESS;
}

Thanks and Regards
Naveen