[Feature]add MT2731_MP2_MR2_SVN388 baseline version
Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/connectivity/libipsecims/Makefile b/src/connectivity/libipsecims/Makefile
new file mode 100644
index 0000000..4e7063a
--- /dev/null
+++ b/src/connectivity/libipsecims/Makefile
@@ -0,0 +1,39 @@
+CANLIB=libipsec_ims
+VERSION=1
+TARGET= $(CANLIB).so
+
+
+SO_CFLAGS= -shared
+CFLAGS?= -O2
+H_FILE = ${wildcard *.h}
+CUR_SOURCE=${wildcard *.c}
+CUR_OBJS=${patsubst %.c, %.o, $(CUR_SOURCE)}
+
+
+all: $(TARGET)
+
+
+install: install_headers
+ @mkdir -p $(DEST_DIR)/usr/lib
+ install -m 0644 $(CANLIB).so $(DEST_DIR)/usr/lib
+ install -m 0644 $(CANLIB).so.$(VERSION) $(DEST_DIR)/usr/lib
+
+install_headers:
+ @mkdir -p $(DEST_DIR)/usr/include
+ install -m 0644 *.h $(DEST_DIR)/usr/include
+
+
+%.o: %.c
+ $(CC) -Wall -fPIC $(CFLAGS) -c $^ -o $@
+$(TARGET).$(VERSION) : $(CUR_OBJS)
+ $(CC) -shared -nostartfiles -Wl,-soname,$@ $^ -o $@ $(LDFLAGS) -lpthread -lsncfg -llog
+
+
+
+$(TARGET): $(CANLIB).so.$(VERSION)
+ ln -s $< $@
+
+
+.PHONY: clean
+clean:
+ rm -f $(CANLIB).* $(CUR_OBJS)
\ No newline at end of file
diff --git a/src/connectivity/libipsecims/MediatekProprietary b/src/connectivity/libipsecims/MediatekProprietary
new file mode 100644
index 0000000..e6e7948
--- /dev/null
+++ b/src/connectivity/libipsecims/MediatekProprietary
@@ -0,0 +1,31 @@
+Copyright Statement:
+
+This software/firmware and related documentation ("MediaTek Software") are
+protected under relevant copyright laws. The information contained herein is
+confidential and proprietary to MediaTek Inc. and/or its licensors. Without
+the prior written permission of MediaTek inc. and/or its licensors, any
+reproduction, modification, use or disclosure of MediaTek Software, and
+information contained herein, in whole or in part, shall be strictly
+prohibited.
+
+MediaTek Inc. (C) 2015. All rights reserved.
+
+BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
+RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
+TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
+SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
+RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
+ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
+RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
+MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
\ No newline at end of file
diff --git a/src/connectivity/libipsecims/rtnl_socket.c b/src/connectivity/libipsecims/rtnl_socket.c
new file mode 100644
index 0000000..538066d
--- /dev/null
+++ b/src/connectivity/libipsecims/rtnl_socket.c
@@ -0,0 +1,152 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <errno.h>
+#include <netdb.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <time.h>
+#include "utils_xfrm.h"
+#include "setkey_xfrm_parse.h"
+#define LOG_TAG "setkey"
+#include <log/log.h>
+#include <cutils/log.h>
+
+
+void rtnl_close_xfrm(struct rtnl_handle_xfrm *rth_xfrm)
+{
+ if (rth_xfrm->fd >= 0) {
+ close(rth_xfrm->fd);
+ rth_xfrm->fd = -1;
+ }
+}
+
+int rtnl_open_byproto_xfrm(struct rtnl_handle_xfrm *rth_xfrm, unsigned subscriptions,
+ int protocol)
+{
+ //socklen_t addr_len;
+ //int sndbuf = 32768;
+
+ memset(rth_xfrm, 0, sizeof(*rth_xfrm));
+
+ rth_xfrm->fd = socket(AF_NETLINK, SOCK_RAW, protocol);
+ if (rth_xfrm->fd < 0) {
+ ALOGD("Cannot open netlink socket,errno:%d\n",errno);
+ return -1;
+ }
+
+
+ memset(&rth_xfrm->local, 0, sizeof(rth_xfrm->local));
+ rth_xfrm->local.nl_family = AF_NETLINK;
+ rth_xfrm->local.nl_groups = subscriptions;
+
+ if (bind(rth_xfrm->fd, (struct sockaddr*)&rth_xfrm->local, sizeof(rth_xfrm->local)) < 0) {
+ ALOGD("Cannot bind netlink socket\n");
+ return -1;
+ }
+ return 0;
+}
+
+int rtnl_listen_xfrm(struct rtnl_handle_xfrm *rtnl_xfrm, rtnl_filter_t_xfrm handler)
+{
+ int status;
+ struct nlmsghdr *h_xfrm;
+ struct sockaddr_nl nladdr_xfrm;
+ struct iovec iov;
+ struct msghdr msg_xfrm = {
+ .msg_name = &nladdr_xfrm,
+ .msg_namelen = sizeof(nladdr_xfrm),
+ .msg_iov = &iov,
+ .msg_iovlen = 1,
+ };
+ char buf[16384];
+
+ memset(&nladdr_xfrm, 0, sizeof(nladdr_xfrm));
+ nladdr_xfrm.nl_family = AF_NETLINK;
+ nladdr_xfrm.nl_pid = 0;
+ nladdr_xfrm.nl_groups = 0;
+ iov.iov_base = buf;
+
+ iov.iov_len = sizeof(buf);
+ status = recvmsg(rtnl_xfrm->fd, &msg_xfrm, 0);
+ ALOGD("netlink receive msg status:%d\n",status);
+ if (status < 0) {
+ if (errno == EINTR || errno == EAGAIN || errno == ENOBUFS)
+ return -1;
+ }
+ if (status == 0) {
+ ALOGE("EOF on netlink\n");
+ return -1;
+ }
+ if (msg_xfrm.msg_namelen != sizeof(nladdr_xfrm)) {
+ ALOGE("Sender address length == %d\n", msg_xfrm.msg_namelen);
+ return -1;
+ }
+ for (h_xfrm = (struct nlmsghdr*)buf; status >= sizeof(*h_xfrm); ) {
+ int err;
+ int len = h_xfrm->nlmsg_len;
+ int l = len - sizeof(*h_xfrm);
+
+ if (l<0 || len>status) {
+ if (msg_xfrm.msg_flags & MSG_TRUNC) {
+ ALOGE("Truncated message\n");
+ return -1;
+ }
+ ALOGE("!!!malformed message: len=%d\n", len);
+ return -1;
+ }
+ err = handler(rtnl_xfrm,h_xfrm);
+ if (err == -2) /*no sa & sp entries*/
+ {
+ return err;
+ }
+
+ status -= NLMSG_ALIGN(len);
+ h_xfrm = (struct nlmsghdr*)((char*)h_xfrm + NLMSG_ALIGN(len));
+ }
+
+ return 0;
+}
+
+/*
+ -2: no previous volte_stack policy&& state is set;
+ -1: unknown message type && delete policy or state failed
+ 0: everything is good
+*/
+int rtnl_accept_msg_xfrm(struct rtnl_handle_xfrm * rth ,struct nlmsghdr *n)
+{
+ char pid[128] = {0};
+ property_get("net.ims.volte.pid",pid,"-1");
+ pid_t volte_pid =atoi(pid);
+ /*no previous volte_stack policy&& state is set*/
+ switch (n->nlmsg_type) {
+ case XFRM_MSG_NEWSA:
+ case XFRM_MSG_UPDSA:
+ return xfrm_state_process_delete_exist( rth,n, volte_pid);
+ case XFRM_MSG_NEWPOLICY:
+ case XFRM_MSG_UPDPOLICY:
+ return xfrm_policy_process_delete_exist( rth,n, volte_pid);
+ case XFRM_MSG_EXPIRE:
+ case XFRM_MSG_DELSA:
+ case XFRM_MSG_FLUSHSA:
+ case XFRM_MSG_GETPOLICY:
+ case XFRM_MSG_FLUSHPOLICY:
+ case XFRM_MSG_ACQUIRE:
+ case XFRM_MSG_DELPOLICY:
+ case XFRM_MSG_POLEXPIRE:
+ default:
+ ALOGD("receive netlink message: %08d 0x%08x 0x%08x\n",
+ n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
+ break;
+ }
+
+ if (n->nlmsg_type != NLMSG_ERROR && n->nlmsg_type != NLMSG_NOOP &&
+ n->nlmsg_type != NLMSG_DONE) {
+ ALOGE("Unknown message: %08d 0x%08x 0x%08x\n",
+ n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
+ }
+ return -2;
+}
+
diff --git a/src/connectivity/libipsecims/setkey_fileio.c b/src/connectivity/libipsecims/setkey_fileio.c
new file mode 100644
index 0000000..5bc8d14
--- /dev/null
+++ b/src/connectivity/libipsecims/setkey_fileio.c
@@ -0,0 +1,1112 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <errno.h>
+#include <netdb.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <time.h>
+#include <linux/capability.h>
+#include <sys/capability.h>
+#include <cutils/properties.h>
+#include "setkey_fileio.h"
+#if 0
+#include "../setkey/log_setky.h"
+#endif
+#define LOG_TAG "setkey"
+#include <log/log.h>
+#include <cutils/log.h>
+
+#if 0
+extern void plog_android(int level, char *format, ...);
+extern int setkey_main(int argc, char ** argv);
+
+#define POLICY_LEN 640
+#define POLICY_MODE 320
+#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
+#define BUFF_SIZE 128
+#define RM_FILE_LEN 64
+
+char setkey_conf[]="/data/misc/setkey/setkey.conf";
+char setkey_conf_bak[]="/data/misc/setkey/setkey_bak.conf";
+char setkey_conf_latest[]="/data/misc/setkey/setkey_latest.conf";
+
+
+static int RemoveString(char * src,char * dst,char * ipsec_type,char * spi_src)
+{
+ FILE *fpSrc = NULL;
+ FILE *fpDst = NULL;
+
+ char achBuf[POLICY_LEN] = {0};
+ fpSrc = fopen(setkey_conf, "rt");
+ if (NULL == fpSrc)
+ {
+ plog_android(LLV_WARNING, "RemoveString:can't open %s,errno:%d",setkey_conf,errno);
+ return -1;
+ }
+ chown(setkey_conf,0,1000);
+ fpDst = fopen(setkey_conf_bak, "wt");
+ if (NULL== fpDst)
+ {
+ plog_android(LLV_WARNING,"RemoveString:Create source file: %s failed,errno:%d\n", setkey_conf_bak,errno);
+ fclose(fpSrc);
+ return -1;
+ }
+ chown(setkey_conf_bak,0,1000);
+ while (!feof(fpSrc))
+ {
+ memset(achBuf, 0, sizeof(achBuf));
+ fgets(achBuf, sizeof(achBuf), fpSrc);
+ /* include below parameter is right*/
+ if ((strstr(achBuf, "add")!=NULL)&&(strstr(achBuf, "spdadd")==NULL)&&(strstr(achBuf, dst)!=NULL)&&(strstr(achBuf,ipsec_type)!=NULL)&&(strstr(achBuf, spi_src)!=NULL))
+ {
+ /*to make sure sequence,first src,then dst*/
+ if(strstr(achBuf, src)<strstr(achBuf, dst))
+ plog_android(LLV_WARNING,"Has found SA,%s,remove it\n",achBuf);
+ else
+ fputs(achBuf, fpDst);
+ } else {
+ fputs(achBuf, fpDst);
+ }
+
+ }
+ fclose(fpSrc);
+ fclose(fpDst);
+
+ return 0;
+}
+
+
+static int RemoveString_SP(char * src,char * dst,int protocol,char * src_port,char * dst_port,char * direction)
+{
+ FILE *fpSrc = NULL;
+ FILE *fpDst = NULL;
+
+ char protocol_str[16]={0};
+ char achBuf[POLICY_LEN] = {0};
+ sprintf(protocol_str,"%d",protocol);
+
+ fpSrc = fopen(setkey_conf, "rt");
+ if (NULL == fpSrc)
+ {
+ plog_android(LLV_WARNING, "RemoveString_SP:can't open %s,errno:%d",setkey_conf,errno);
+ return -1;
+ }
+ chown(setkey_conf,0,1000);
+ fpDst = fopen(setkey_conf_bak, "wt");
+ if (NULL== fpDst)
+ {
+ plog_android(LLV_WARNING,"RemoveString_SP:Create source file: %s failed,errno:%d\n", setkey_conf_bak,errno);
+ fclose(fpSrc);
+ return -1;
+ }
+ chown(setkey_conf_bak,0,1000);
+ while (!feof(fpSrc))
+ {
+ memset(achBuf, 0, sizeof(achBuf));
+ fgets(achBuf, sizeof(achBuf), fpSrc);
+ if ((strstr(achBuf, "spdadd")!=NULL)&&(strstr(achBuf, dst)!=NULL)&&(strstr(achBuf, src)!=NULL)&&(strstr(achBuf, src_port)!=NULL)
+ &&(strstr(achBuf, dst_port)!=NULL)&&(strstr(achBuf, protocol_str)!=NULL)&&(strstr(achBuf, direction)!=NULL))
+ {
+ if((strstr(achBuf, src)<strstr(achBuf, dst))&&(strstr(achBuf, src_port)<strstr(achBuf, dst_port)))
+ plog_android(LLV_WARNING,"Has found SP policy,%s,remove it\n",achBuf);
+ else
+ fputs(achBuf, fpDst);
+ }
+ else
+ {
+ fputs(achBuf, fpDst);
+ }
+ }
+ fclose(fpSrc);
+ fclose(fpDst);
+
+ return 0;
+}
+
+
+/* 1: some error; 0: process successfully */
+int shell(char * cmd)
+{
+ FILE * fp = NULL,* fp_exit_code =NULL;
+ int bufflen;
+ char * buffer = (char *)malloc((BUFF_SIZE));
+ if(buffer == NULL)
+ {
+ plog_android(LLV_WARNING, "run shell command buffer is null");
+ return -1;
+ }
+ char * buffer_retcode = NULL;
+ char * cmd_exit_code = (char *)malloc((BUFF_SIZE));
+ int ret_code = 0;
+ if(cmd_exit_code == NULL)
+ {
+ plog_android(LLV_WARNING, "alloc cmd_exit_code failed ");
+ goto ret_sec;
+ }
+ if(cmd == NULL)
+ {
+ plog_android(LLV_WARNING, "run shell command is null");
+ goto ret_fir;
+ }
+ buffer[0] = 0;
+ strcpy(cmd_exit_code,cmd);
+ strcat(cmd_exit_code,";echo ret_code:$?");
+ fp = popen(cmd_exit_code,"r");
+ if(fp == NULL)
+ {
+ plog_android(LLV_WARNING, "can't run shell command");
+ goto ret_fir;
+ }
+ //plog_android(LLV_WARNING, "run shell command:%s ...",cmd);
+ while(fgets(buffer,BUFF_SIZE,fp)!=NULL)
+ {
+ plog_android(LLV_WARNING, "%s",buffer);
+ }
+ buffer_retcode = strstr(buffer,"ret_code:");
+ if(buffer_retcode)
+ {
+ ret_code = atoi(buffer_retcode+strlen("ret_code:"));
+ plog_android(LLV_WARNING, "processing cmd:%s return code:%d",cmd,ret_code);
+ }
+ pclose(fp);
+
+
+ret_fir:
+ if(cmd_exit_code)
+ free(cmd_exit_code);
+ret_sec:
+ if(buffer)
+ free(buffer);
+ return ret_code;
+}
+
+/*rm setkey.conf file*/
+int shell_rm(void)
+{
+ char rm_file[RM_FILE_LEN];
+ int ret = 1;
+ memset(rm_file,0,RM_FILE_LEN);
+ snprintf(rm_file,sizeof(rm_file),"rm %s",setkey_conf);
+ if(access(setkey_conf,0) == 0)
+ {
+ ret = shell(rm_file);
+ if(ret != 0)
+ {
+ plog_android(LLV_WARNING,"shell %s failed,errno:%d",rm_file,errno);
+ return -1;
+ }
+ }
+ return 0;
+
+}
+
+/*setkey -f setkey.conf */
+int function_setkey(char * file_conf)
+{
+ char * argv[4];
+
+ argv[0] = "setkey";
+ argv[1] = "-f";
+ argv[2] = file_conf;
+ argv[3] = NULL;
+ int ret = setkey_main(3,(char **)argv);
+ if(ret != 0)
+ {
+ plog_android(LLV_WARNING," setkey -f %s failed,errno:%d",file_conf,errno);
+ return ret;
+ }
+ return 0;
+
+}
+#endif
+/*flush all SA*/
+int setkey_flushSAD(void)
+{
+#if 0
+ char * argv[3];
+
+ argv[0] = "setkey";
+ argv[1] = "-F";
+ argv[2] = NULL;
+ if(shell_rm() == -1)
+ {
+ return -1;
+ }
+
+ int ret = setkey_main(2,(char **)argv);
+ if(ret != 0)
+ {
+ plog_android(LLV_WARNING,"setkey -F failed,errno:%d",errno);
+ return ret;
+ }
+ return 0;
+#endif
+ int ret = setkey_flushSAD_xfrm("esp");
+ return ret;
+}
+
+/*flush all SP*/
+int setkey_flushSPD(void)
+{
+#if 0
+ char * argv[4];
+
+ argv[0] = "setkey";
+ argv[1] = "-F";
+ argv[2] = "-P";
+ argv[3] = NULL;
+ if(shell_rm() == -1)
+ {
+ return -1;
+ }
+ int ret = setkey_main(3,(char **)argv);
+ if(ret != 0)
+ {
+ plog_android(LLV_WARNING,"setkey -FP failed,errno:%d",errno);
+ return ret;
+ }
+ return 0;
+#endif
+ int ret = setkey_flushSPD_xfrm();
+ return ret;
+}
+
+/*delete one SA entry*/
+int setkey_deleteSA(char * src,char * dst,char * ipsec_type,char * spi_src)
+{
+#if 0
+ char delSA[POLICY_LEN];
+ FILE * fd_config = NULL;
+
+
+
+ memset(delSA,0,sizeof(delSA));
+
+ snprintf(delSA,sizeof(delSA),"delete %s %s %s %s;\n",src,dst,ipsec_type,spi_src);
+ fd_config = fopen(setkey_conf_latest, "w+");
+ if(fd_config == NULL)
+ {
+ plog_android(LLV_WARNING,"open %s failed,errno:%d",setkey_conf,errno);
+ return -1;
+
+ }
+ chown(setkey_conf_latest,0,1000);
+ fwrite( delSA, strlen(delSA),1,fd_config);
+ plog_android(LLV_WARNING,"setkey_deleteSA:%s",delSA);
+ fclose(fd_config);
+ if(function_setkey(setkey_conf_latest)== -1)
+ return -1;
+ else
+ {
+ /*update setkey.conf to record how many pairs of SA have been established*/
+
+ if(RemoveString(src,dst,ipsec_type,spi_src) == 0)
+ {
+ if(shell_rm() == -1)
+ {
+ return -1;
+ }
+ if(rename(setkey_conf_bak,setkey_conf)<0)
+ {
+ plog_android(LLV_WARNING,"rename setkey.conf failed,errno:%d",errno);
+ return -1;
+ }
+ }
+ else
+ {
+ plog_android(LLV_WARNING,"RemoveString failed");
+ return -1;
+ }
+ }
+ return 0;
+#endif
+ int ret = setkey_deleteSA_xfrm(src,dst,ipsec_type,spi_src);
+ return ret;
+}
+
+/*delete one SP entry*/
+int setkey_deleteSP(char * src,char * dst,enum PROTOCOL_TYPE protocol,char * src_port,char * dst_port,char * direction)
+{
+#if 0
+ char delSP[POLICY_LEN];
+
+ FILE * fd_config = NULL;
+
+
+
+ memset(delSP,0,sizeof(delSP));
+
+ snprintf(delSP,sizeof(delSP),"spddelete %s[%s] %s[%s] %d -P %s;\n",src,src_port,dst,dst_port,protocol,direction);
+ fd_config = fopen(setkey_conf_latest, "w+");
+ if(fd_config == NULL)
+ {
+ plog_android(LLV_WARNING,"open %s failed,errno:%d",setkey_conf,errno);
+ return -1;
+
+ }
+ chown(setkey_conf_latest,0,1000);
+ fwrite( delSP, strlen(delSP),1,fd_config);
+ plog_android(LLV_WARNING,"setkey_deleteSP:%s",delSP);
+ fclose(fd_config);
+ if(function_setkey(setkey_conf_latest)==-1)
+ return -1;
+ else
+ {
+ /*update setkey.conf to record how many pairs of SP policy have been established*/
+
+ if(RemoveString_SP( src, dst, protocol, src_port, dst_port, direction) == 0)
+ {
+ if(shell_rm() == -1)
+ {
+ return -1;
+ }
+ if(rename(setkey_conf_bak,setkey_conf)<0)
+ {
+ plog_android(LLV_WARNING,"rename setkey.conf failed,errno:%d",errno);
+ return -1;
+ }
+ }
+ else
+ {
+ plog_android(LLV_WARNING,"RemoveString---%s failed",delSP);
+ return -1;
+ }
+ }
+ return 0;
+#endif
+ int ret = setkey_deleteSP_xfrm(src,dst,protocol,src_port,dst_port,direction);
+ return ret;
+}
+
+/*dump SA */
+int dump_setkeySA(void)
+{
+/*To do*/
+#if 0
+ char * argv[3];
+
+ argv[0] = "setkey";
+ argv[1] = "-D";
+ argv[2] = NULL;
+ int ret = setkey_main(2,(char **)argv);
+ if(ret != 0)
+ {
+ plog_android(LLV_WARNING," setkey -D failed,errno:%d",errno);
+ return -1;
+ }
+#endif
+ return 0;
+
+}
+
+/*dump SP */
+int dump_setkeySP(void)
+{
+/*To do*/
+#if 0
+ char * argv[4];
+
+ argv[0] = "setkey";
+ argv[1] = "-D";
+ argv[2] = "-P";
+ argv[3] = NULL;
+ int ret = setkey_main(3,(char **)argv);
+ if(ret != 0)
+ {
+ plog_android(LLV_WARNING,"setkey -DP failed,errno:%d",errno);
+ return ret;
+ }
+#endif
+ return 0;
+
+}
+#if 0
+void setkey_get_aid_and_cap() {
+
+ plog_android(LLV_WARNING,"Warning: gid:%d,uid:%d,pid:%d !\n",getgid(),getuid(),getpid());
+ struct __user_cap_header_struct header;
+ struct __user_cap_data_struct cap;
+ header.version = _LINUX_CAPABILITY_VERSION;
+ header.pid = getpid();
+ capget(&header, &cap);
+ plog_android(LLV_WARNING, "Warning: permitted:%x,cap.effective:%x !\n",cap.permitted,cap.effective);
+}
+#endif
+/*set one SA*/
+/*ipsec_type:ah esp
+ mode:transport tunnel
+ encrp_algo_src:encryption algorithm,des-cbc,3des-cbc...
+ encrp_algo_src:key of encryption algorithm
+ intergrity_algo_src:authentication algorithm ,hmac-md5,hmac-sha1
+ intergrity_key_src:key of authentication algorithm
+*/
+int setkey_setSA(char * ip_src,char * ip_dst,char * ipsec_type,char * spi_src,char * mode,
+ char * encrp_algo_src,char * encrp_key_src,char * intergrity_algo_src,char * intergrity_key_src,int u_id)
+{
+#if 0
+ char sad_policy[POLICY_LEN];
+
+ FILE * fd_config = NULL;
+ FILE * fd_config_tmp = NULL;
+
+ memset(sad_policy,0,sizeof(sad_policy));
+
+ setkey_get_aid_and_cap();
+
+ fd_config_tmp = fopen(setkey_conf_latest, "w+" );
+ if(fd_config_tmp == NULL)
+ {
+ plog_android(LLV_WARNING,"open %s failed,errno:%d",setkey_conf_latest,errno);
+ return -1;
+ }
+ chown(setkey_conf_latest,0,1000);
+ if(strcmp(encrp_algo_src,"null")==0)
+ {
+ if(u_id ==0 )
+ snprintf(sad_policy,sizeof(sad_policy),"add %s %s %s %s -m %s -E null -A %s %s;\n",ip_src,ip_dst,ipsec_type,spi_src,mode,
+ intergrity_algo_src,intergrity_key_src);
+ else
+ snprintf(sad_policy,sizeof(sad_policy),"add %s %s %s %s -u %d -m %s -E null -A %s %s;\n",ip_src,ip_dst,ipsec_type,spi_src,u_id,mode,
+ intergrity_algo_src,intergrity_key_src);
+ }
+ else
+ {
+ if(u_id ==0 )
+ snprintf(sad_policy,sizeof(sad_policy),"add %s %s %s %s -m %s -E %s %s -A %s %s;\n",ip_src,ip_dst,ipsec_type,spi_src,mode,
+ encrp_algo_src,encrp_key_src,intergrity_algo_src,intergrity_key_src);
+ else
+ snprintf(sad_policy,sizeof(sad_policy),"add %s %s %s %s -u %d -m %s -E %s %s -A %s %s;\n",ip_src,ip_dst,ipsec_type,spi_src,u_id,mode,
+ encrp_algo_src,encrp_key_src,intergrity_algo_src,intergrity_key_src);
+ }
+ fwrite( sad_policy, strlen(sad_policy),1,fd_config_tmp );
+ plog_android(LLV_WARNING,"setkey_SA:%s",sad_policy);
+ fclose(fd_config_tmp);
+
+ if(function_setkey(setkey_conf_latest)==0)
+ {
+ fd_config = fopen(setkey_conf, "a+" );
+ if(fd_config == NULL)
+ {
+ plog_android(LLV_WARNING,"open %s failed,errno:%d",setkey_conf,errno);
+ return -1;
+ }
+ chown(setkey_conf,0,1000);
+ fwrite( sad_policy, strlen(sad_policy),1,fd_config );
+ fclose(fd_config);
+ }
+ else
+ return -1;
+
+ return 0;
+#endif
+ int ret = setkey_setSA_xfrm(XFRM_MSG_NEWSA,ip_src,ip_dst,ipsec_type,spi_src,mode,
+ encrp_algo_src,encrp_key_src,intergrity_algo_src,intergrity_key_src,u_id);
+ return ret;
+}
+int setkey_setSA_update(char * ip_src,char * ip_dst,char * ipsec_type,char * spi_src,char * mode,
+ char * encrp_algo_src,char * encrp_key_src,char * intergrity_algo_src,char * intergrity_key_src,int u_id)
+{
+ int ret = setkey_setSA_xfrm(XFRM_MSG_UPDSA,ip_src,ip_dst,ipsec_type,spi_src,mode,
+ encrp_algo_src,encrp_key_src,intergrity_algo_src,intergrity_key_src,u_id);
+ return ret;
+}
+/*set one SP of one direction, just for transport mode*/
+/*protocol:tcp icmp udp icmp6 ip4 gre
+ direction:src->dst */
+int setkey_SP(char * src_range,char * dst_range,enum PROTOCOL_TYPE protocol,char * port_src,char * port_dst,char * ipsec_type,char * mode, char * direction,int u_id)
+{
+#if 0
+ char spd_policy[POLICY_LEN];
+ FILE * fd_config = NULL;
+ FILE * fd_config_tmp = NULL;
+ memset(spd_policy,0,sizeof(spd_policy));
+
+
+ fd_config_tmp = fopen(setkey_conf_latest, "w+" );
+ if(fd_config_tmp == NULL)
+ {
+ plog_android(LLV_WARNING,"open %s failed,errno:%d",setkey_conf_latest,errno);
+ return -1;
+ }
+ chown(setkey_conf_latest,0,1000);
+ if(u_id ==0)
+ snprintf(spd_policy,sizeof(spd_policy),"spdadd %s[%s] %s[%s] %d -P %s ipsec %s/%s//require;\n",src_range,port_src,dst_range,port_dst,protocol,direction,ipsec_type,mode);
+ else
+ snprintf(spd_policy,sizeof(spd_policy),"spdadd %s[%s] %s[%s] %d -P %s ipsec %s/%s//unique:%d;\n",src_range,port_src,dst_range,port_dst,protocol,direction,ipsec_type,mode,u_id);
+ fwrite( spd_policy, strlen(spd_policy),1,fd_config_tmp );
+ plog_android(LLV_WARNING,"setkey_SP:%s",spd_policy);
+ fclose(fd_config_tmp);
+
+ if(function_setkey(setkey_conf_latest) == 0)
+ {
+ fd_config = fopen(setkey_conf, "a+" );
+ if(fd_config == NULL)
+ {
+ plog_android(LLV_WARNING,"open %s failed,errno:%d",setkey_conf,errno);
+ return -1;
+ }
+ chown(setkey_conf,0,1000);
+ fwrite( spd_policy, strlen(spd_policy),1,fd_config );
+ fclose(fd_config);
+ }
+ else
+ return -1;
+ return 0;
+#endif
+ mode = "transport";
+ int ret = setkey_SP_xfrm(XFRM_MSG_NEWPOLICY,src_range,dst_range,protocol,port_src,port_dst,NULL,NULL,ipsec_type,mode,direction,u_id);
+ return ret;
+}
+
+/*set one SP of one direction, just for tunnel mode*/
+/*protocol:tcp icmp udp icmp6 ip4 gre
+ direction:src->dst
+src_tunnel,dst_tunnel: tunnel src ip tunnel dst ip */
+int setkey_SP_tunnel(char * src_range,char * dst_range,enum PROTOCOL_TYPE protocol,char * port_src,char * port_dst,char * src_tunnel,char * dst_tunnel,char * ipsec_type,char * mode, char * direction,int u_id)
+{
+#if 0
+ char spd_policy[POLICY_LEN];
+ FILE * fd_config = NULL;
+ FILE * fd_config_tmp = NULL;
+ memset(spd_policy,0,sizeof(spd_policy));
+
+
+ fd_config_tmp = fopen(setkey_conf_latest, "w+" );
+ if(fd_config_tmp == NULL)
+ {
+ plog_android(LLV_WARNING,"open %s failed,errno:%d",setkey_conf_latest,errno);
+ return -1;
+ }
+ chown(setkey_conf_latest,0,1000);
+ if(u_id ==0)
+ snprintf(spd_policy,sizeof(spd_policy),"spdadd %s[%s] %s[%s] %d -P %s ipsec %s/%s/%s-%s/require;\n",src_range,port_src,dst_range,port_dst,protocol,direction,ipsec_type,mode,src_tunnel, dst_tunnel);
+ else
+ snprintf(spd_policy,sizeof(spd_policy),"spdadd %s[%s] %s[%s] %d -P %s ipsec %s/%s/%s-%s/unique:%d;\n",src_range,port_src,dst_range,port_dst,protocol,direction,ipsec_type,mode,src_tunnel, dst_tunnel,u_id);
+ fwrite( spd_policy, strlen(spd_policy),1,fd_config_tmp );
+ plog_android(LLV_WARNING,"setkey_SP_tunnel:%s",spd_policy);
+ fclose(fd_config_tmp);
+
+ if(function_setkey(setkey_conf_latest) == 0)
+ {
+ fd_config = fopen(setkey_conf, "a+" );
+ if(fd_config == NULL)
+ {
+ plog_android(LLV_WARNING,"open %s failed,errno:%d",setkey_conf,errno);
+ return -1;
+ }
+ chown(setkey_conf,0,1000);
+ fwrite( spd_policy, strlen(spd_policy),1,fd_config );
+ fclose(fd_config);
+ }
+ else
+ return -1;
+ return 0;
+#endif
+ mode = "tunnel";
+ int ret = setkey_SP_xfrm(XFRM_MSG_NEWPOLICY,src_range,dst_range,protocol,port_src,port_dst,src_tunnel,dst_tunnel,ipsec_type,mode,direction,u_id);
+ return ret;
+}
+
+/*set one SP of one direction, for 2 layers' ipsec--tunnel mode+transport mode or transport mode+tunnel mode*/
+/*protocol:tcp icmp udp icmp6 ip4 gre
+ direction:src->dst
+src_tunnel,dst_tunnel: tunnel src ip tunnel dst ip */
+int setkey_SP_tunnel_transport(char * src_range,char * dst_range,enum PROTOCOL_TYPE protocol,char * port_src,char * port_dst,char * src_tunnel,char * dst_tunnel,char * ipsec_type1,char * mode1, char * ipsec_type2,char * mode2,char * direction,int u_id1,int u_id2)
+{
+
+ char version[128] = {0};
+ int ret_mapping = 0;
+ property_get("net.ims.ipsec.version",version,"");
+ //plog_android(LLV_WARNING,"getproperty-- net.ims.ipsec.version :%s\n",version);
+ if(strcmp(version,"2.0")==0)
+ {
+ ret_mapping = setkey_SP(src_range,dst_range,protocol,port_src,port_dst,ipsec_type1,mode1, direction,u_id1);
+ return ret_mapping;
+ }
+
+#if 0
+ char spd_policy[POLICY_LEN]={0};
+ char * spd_policy_mode1= (char *)malloc(POLICY_MODE);
+
+ FILE * fd_config = NULL;
+ FILE * fd_config_tmp = NULL;
+
+
+ if(spd_policy_mode1==NULL)
+ {
+ plog_android(LLV_WARNING,"malloc spd_policy_mode1 failed,errno:%d",errno);
+ return -1;
+ }
+ memset(spd_policy_mode1,0,POLICY_MODE);
+
+ char * spd_policy_mode2= (char *)malloc(POLICY_MODE);
+ if(spd_policy_mode2==NULL)
+ {
+ plog_android(LLV_WARNING,"malloc spd_policy_mode2 failed,errno:%d",errno);
+ if(spd_policy_mode1)
+ free(spd_policy_mode1);
+ return -1;
+ }
+ memset(spd_policy_mode2,0,POLICY_MODE);
+
+ fd_config_tmp = fopen(setkey_conf_latest, "w+" );
+ if(fd_config_tmp == NULL)
+ {
+ plog_android(LLV_WARNING,"open %s failed,errno:%d",setkey_conf_latest,errno);
+ if(spd_policy_mode1)
+ free(spd_policy_mode1);
+ if(spd_policy_mode2)
+ free(spd_policy_mode2);
+ return -1;
+ }
+ chown(setkey_conf_latest,0,1000);
+ if(u_id1 ==0)
+ if(strcmp(mode1,"transport")==0)
+ snprintf(spd_policy_mode1,POLICY_MODE,"%s/%s//require",ipsec_type1,mode1);
+ else
+ snprintf(spd_policy_mode1,POLICY_MODE,"%s/%s/%s-%s/require",ipsec_type1,mode1,src_tunnel,dst_tunnel);
+ else
+ if(strcmp(mode1,"transport")==0)
+ snprintf(spd_policy_mode1,POLICY_MODE,"%s/%s//unique:%d",ipsec_type1,mode1,u_id1);
+ else
+ snprintf(spd_policy_mode1,POLICY_MODE,"%s/%s/%s-%s/unique:%d",ipsec_type1,mode1,src_tunnel,dst_tunnel,u_id1);
+ if(u_id2 ==0)
+ if(strcmp(mode2,"transport")==0)
+ snprintf(spd_policy_mode2,POLICY_MODE,"%s/%s//require;\n",ipsec_type2,mode2);
+ else
+ snprintf(spd_policy_mode2,POLICY_MODE,"%s/%s/%s-%s/require;\n",ipsec_type2,mode2,src_tunnel,dst_tunnel);
+ else
+ if(strcmp(mode2,"transport")==0)
+ snprintf(spd_policy_mode2,POLICY_MODE,"%s/%s//unique:%d;\n",ipsec_type2,mode2,u_id2);
+ else
+ snprintf(spd_policy_mode2,POLICY_MODE,"%s/%s/%s-%s/unique:%d;\n",ipsec_type2,mode2,src_tunnel,dst_tunnel,u_id2);
+
+ snprintf(spd_policy,sizeof(spd_policy),"spdadd %s[%s] %s[%s] %d -P %s prio 2147482648 ipsec %s %s",src_range,port_src,dst_range,port_dst,protocol,direction,spd_policy_mode1,spd_policy_mode2);
+ fwrite( spd_policy, strlen(spd_policy),1,fd_config_tmp );
+ plog_android(LLV_WARNING,"setkey_SP_tunnel_transport:%s",spd_policy);
+ fclose(fd_config_tmp);
+ if(spd_policy_mode1)
+ free(spd_policy_mode1);
+ if(spd_policy_mode2)
+ free(spd_policy_mode2);
+ if(function_setkey(setkey_conf_latest) == 0)
+ {
+ fd_config = fopen(setkey_conf, "a+" );
+ if(fd_config == NULL)
+ {
+ plog_android(LLV_WARNING,"open %s failed,errno:%d",setkey_conf,errno);
+ return -1;
+ }
+ chown(setkey_conf,0,1000);
+ fwrite( spd_policy, strlen(spd_policy),1,fd_config );
+ fclose(fd_config);
+ }
+ else
+ return -1;
+ return 0;
+#endif
+ int ret = setkey_SP_2layer_xfrm(XFRM_MSG_UPDPOLICY,src_range,dst_range,protocol,port_src,port_dst,src_tunnel,dst_tunnel,ipsec_type1,mode1,ipsec_type2,mode2,direction,u_id1,u_id2);
+ return ret;
+}
+
+
+/*update one SP of one direction, just for transport mode*/
+/*protocol:tcp icmp udp icmp6 ip4 gre
+ direction:src->dst*/
+int setkey_SP_update_transport(char * src_range,char * dst_range,enum PROTOCOL_TYPE protocol,char * port_src,char * port_dst,char * ipsec_type, char * direction,int u_id)
+{
+#if 0
+ char spd_policy[POLICY_LEN];
+ FILE * fd_config = NULL;
+ FILE * fd_config_tmp = NULL;
+ memset(spd_policy,0,sizeof(spd_policy));
+
+
+ fd_config_tmp = fopen(setkey_conf_latest, "w+" );
+ if(fd_config_tmp == NULL)
+ {
+ plog_android(LLV_WARNING,"open %s failed,errno:%d",setkey_conf_latest,errno);
+ return -1;
+ }
+ chown(setkey_conf_latest,0,1000);
+ if(u_id ==0)
+ snprintf(spd_policy,sizeof(spd_policy),"spdupdate %s[%s] %s[%s] %d -P %s ipsec %s/transport//require;\n",src_range,port_src,dst_range,port_dst,protocol,direction,ipsec_type);
+ else
+ snprintf(spd_policy,sizeof(spd_policy),"spdupdate %s[%s] %s[%s] %d -P %s ipsec %s/transport//unique:%d;\n",src_range,port_src,dst_range,port_dst,protocol,direction,ipsec_type,u_id);
+ fwrite( spd_policy, strlen(spd_policy),1,fd_config_tmp );
+ plog_android(LLV_WARNING,"setkey_SP_update_transport:%s",spd_policy);
+ fclose(fd_config_tmp);
+
+ if(function_setkey(setkey_conf_latest) == 0)
+ {
+ fd_config = fopen(setkey_conf, "a+" );
+ if(fd_config == NULL)
+ {
+ plog_android(LLV_WARNING,"open %s failed,errno:%d",setkey_conf,errno);
+ return -1;
+ }
+ chown(setkey_conf,0,1000);
+ fwrite( spd_policy, strlen(spd_policy),1,fd_config );
+ fclose(fd_config);
+ }
+ else
+ return -1;
+ return 0;
+#endif
+ int ret = setkey_SP_xfrm(XFRM_MSG_UPDPOLICY,src_range,dst_range,protocol,port_src,port_dst,NULL,NULL,ipsec_type,"transport",direction,u_id);
+ return ret;
+}
+
+/*update one SP of one direction, for 2 layers' ipsec--tunnel mode+transport mode or transport mode+tunnel mode*/
+/*protocol:tcp icmp udp icmp6 ip4 gre
+ direction:src->dst
+src_tunnel,dst_tunnel: tunnel src ip tunnel dst ip */
+int setkey_SP_update_tunnel_transport(char * src_range,char * dst_range,enum PROTOCOL_TYPE protocol,char * port_src,char * port_dst,char * src_tunnel,char * dst_tunnel,char * ipsec_type1,char * mode1, char * ipsec_type2,char * mode2,char * direction,int u_id1,int u_id2)
+{
+#if 0
+ char spd_policy[POLICY_LEN]={0};
+ char * spd_policy_mode1= (char *)malloc(POLICY_MODE);
+ FILE * fd_config = NULL;
+ FILE * fd_config_tmp = NULL;
+
+
+ if(spd_policy_mode1==NULL)
+ {
+ plog_android(LLV_WARNING,"malloc spd_policy_mode1 failed,errno:%d",errno);
+ return -1;
+ }
+ memset(spd_policy_mode1,0,POLICY_MODE);
+ char * spd_policy_mode2= (char *)malloc(POLICY_MODE);
+ if(spd_policy_mode2==NULL)
+ {
+ plog_android(LLV_WARNING,"malloc spd_policy_mode2 failed,errno:%d",errno);
+ if(spd_policy_mode1)
+ free(spd_policy_mode1);
+ return -1;
+ }
+ memset(spd_policy_mode2,0,POLICY_MODE);
+
+ fd_config_tmp = fopen(setkey_conf_latest, "w+" );
+ if(fd_config_tmp == NULL)
+ {
+ plog_android(LLV_WARNING,"open %s failed,errno:%d",setkey_conf_latest,errno);
+ if(spd_policy_mode1)
+ free(spd_policy_mode1);
+ if(spd_policy_mode2)
+ free(spd_policy_mode2);
+ return -1;
+ }
+ chown(setkey_conf_latest,0,1000);
+ if(u_id1 ==0)
+ if(strcmp(mode1,"transport")==0)
+ snprintf(spd_policy_mode1,POLICY_MODE,"%s/%s//require",ipsec_type1,mode1);
+ else
+ snprintf(spd_policy_mode1,POLICY_MODE,"%s/%s/%s-%s/require",ipsec_type1,mode1,src_tunnel,dst_tunnel);
+ else
+ if(strcmp(mode1,"transport")==0)
+ snprintf(spd_policy_mode1,POLICY_MODE,"%s/%s//unique:%d",ipsec_type1,mode1,u_id1);
+ else
+ snprintf(spd_policy_mode1,POLICY_MODE,"%s/%s/%s-%s/unique:%d",ipsec_type1,mode1,src_tunnel,dst_tunnel,u_id1);
+ if(u_id2 ==0)
+ if(strcmp(mode2,"transport")==0)
+ snprintf(spd_policy_mode2,POLICY_MODE,"%s/%s//require;\n",ipsec_type2,mode2);
+ else
+ snprintf(spd_policy_mode2,POLICY_MODE,"%s/%s/%s-%s/require;\n",ipsec_type2,mode2,src_tunnel,dst_tunnel);
+ else
+ if(strcmp(mode2,"transport")==0)
+ snprintf(spd_policy_mode2,POLICY_MODE,"%s/%s//unique:%d;\n",ipsec_type2,mode2,u_id2);
+ else
+ snprintf(spd_policy_mode2,POLICY_MODE,"%s/%s/%s-%s/unique:%d;\n",ipsec_type2,mode2,src_tunnel,dst_tunnel,u_id2);
+
+ snprintf(spd_policy,sizeof(spd_policy),"spdupdate %s[%s] %s[%s] %d -P %s prio 2147482648 ipsec %s %s",src_range,port_src,dst_range,port_dst,protocol,direction,spd_policy_mode1,spd_policy_mode2);
+ fwrite( spd_policy, strlen(spd_policy),1,fd_config_tmp );
+ plog_android(LLV_WARNING,"setkey_SP_update_tunnel_transport:%s",spd_policy);
+ fclose(fd_config_tmp);
+ if(spd_policy_mode1)
+ free(spd_policy_mode1);
+ if(spd_policy_mode2)
+ free(spd_policy_mode2);
+ if(function_setkey(setkey_conf_latest) == 0)
+ {
+ fd_config = fopen(setkey_conf, "a+" );
+ if(fd_config == NULL)
+ {
+ plog_android(LLV_WARNING,"open %s failed,errno:%d",setkey_conf,errno);
+ return -1;
+ }
+ chown(setkey_conf,0,1000);
+ fwrite( spd_policy, strlen(spd_policy),1,fd_config );
+ fclose(fd_config);
+ }
+ else
+ return -1;
+ return 0;
+#endif
+ int ret = setkey_SP_2layer_xfrm(XFRM_MSG_UPDPOLICY,src_range,dst_range,protocol,port_src,port_dst,src_tunnel,dst_tunnel,ipsec_type1,mode1,ipsec_type2,mode2,direction,u_id1,u_id2);
+ return ret;
+}
+
+
+/*flush SA\SP from setkey.conf*/
+int flush_SA_SP_exist()
+{
+#if 0
+ FILE *fpSrc = NULL;
+ FILE *fpDst = NULL;
+ char * p_add = NULL;
+ char * p_spdadd = NULL;
+ char * p = NULL;
+ char * sp = NULL;
+ char * sp_ipsec = NULL;
+ char * sp_prio = NULL;
+#if 0
+ char * sp_tmp = NULL;
+ char * sp_src_tmp = NULL;
+ char * sp_dst_tmp = NULL;
+ char * sp_dst = NULL;
+#endif
+ if(access(setkey_conf,0) != 0)
+ {
+ plog_android(LLV_WARNING,"There is no SA before\n");
+ return 0;
+ }
+
+
+ char * achBuf = (char *)malloc(POLICY_LEN);
+ if(achBuf == NULL)
+ {
+ plog_android(LLV_WARNING,"malloc achBuf failed\n");
+ return -1;
+ }
+ char * achBuf_deletmp = (char *)malloc(POLICY_LEN);
+ if(achBuf_deletmp == NULL)
+ {
+ plog_android(LLV_WARNING,"malloc achBuf_deletmp failed\n");
+ if(achBuf)
+ free(achBuf);
+
+ return -1;
+ }
+ char * achBuf_delet = (char *)malloc(POLICY_LEN);
+ if(achBuf_delet == NULL)
+ {
+ plog_android(LLV_WARNING,"malloc achBuf_delet failed\n");
+ if(achBuf)
+ free(achBuf);
+ if(achBuf_deletmp)
+ free(achBuf_deletmp);
+ return -1;
+ }
+
+
+ fpSrc = fopen(setkey_conf, "rt");
+ if (NULL == fpSrc)
+ {
+ plog_android(LLV_WARNING, "can't open %s,errno:%d",setkey_conf,errno);
+ if(achBuf)
+ free(achBuf);
+ if(achBuf_deletmp)
+ free(achBuf_deletmp);
+ if(achBuf_delet)
+ free(achBuf_delet);
+ return -1;
+ }
+ chown(setkey_conf,0,1000);
+ fpDst = fopen(setkey_conf_latest, "w+");
+ if (NULL== fpDst)
+ {
+ if(achBuf)
+ free(achBuf);
+ if(achBuf_deletmp)
+ free(achBuf_deletmp);
+ if(achBuf_delet)
+ free(achBuf_delet);
+ plog_android(LLV_WARNING,"Create source file: %s failed,errno:%d\n", setkey_conf_bak,errno);
+ if(fpSrc)
+ fclose(fpSrc);
+ return -1;
+ }
+ chown(setkey_conf_latest,0,1000);
+ fseek(fpSrc,0L,SEEK_SET);
+ while (!feof(fpSrc))
+ {
+ memset(achBuf, 0, POLICY_LEN);
+ memset(achBuf_deletmp, 0, POLICY_LEN);
+ memset(achBuf_delet, 0, POLICY_LEN);
+ fgets(achBuf, POLICY_LEN, fpSrc);
+
+ if (((p_add = strstr(achBuf, "add")) != NULL)&&(strstr(achBuf, "spdadd") == NULL) )
+ {
+
+ p = strstr(p_add,"-m");
+ if(p!= NULL)
+ {
+ memcpy(achBuf_deletmp,p_add + strlen("add"),p-p_add-strlen("add"));
+ snprintf(achBuf_delet,POLICY_LEN-1,"delete %s;\n",achBuf_deletmp) ;
+ plog_android(LLV_WARNING,"delete SA:%s\n", achBuf_delet);
+ fputs(achBuf_delet, fpDst);
+ }
+ else
+ {
+ plog_android(LLV_WARNING,"There are some cmd error in %s,then flush all SAs and SPs\n", setkey_conf);
+ setkey_flushSAD();
+ setkey_flushSPD();
+ if(achBuf)
+ free(achBuf);
+ if(achBuf_deletmp)
+ free(achBuf_deletmp);
+ if(achBuf_delet)
+ free(achBuf_delet);
+ if(fpSrc)
+ fclose(fpSrc);
+ if(fpDst)
+ fclose(fpDst);
+ return -1;
+ }
+ }
+
+ if((p_spdadd = strstr(achBuf, "spdadd")) != NULL)
+ {
+ sp = p_spdadd+strlen("spdadd");
+ if((sp_prio =strstr(sp,"prio"))!=NULL)
+ {
+ memset(achBuf_deletmp, 0, POLICY_LEN);
+ memset(achBuf_delet, 0, POLICY_LEN);
+ strncpy(achBuf_deletmp,sp,sp_prio-sp);
+ snprintf(achBuf_delet,POLICY_LEN-1,"spddelete %s",achBuf_deletmp);
+ strcat(achBuf_delet,";\n");
+ fputs(achBuf_delet, fpDst);
+ plog_android(LLV_WARNING,"delete policy: %s\n", achBuf_delet);
+ }
+ else if((sp_ipsec =strstr(sp,"ipsec"))!=NULL)
+ {
+ memset(achBuf_deletmp, 0, POLICY_LEN);
+ memset(achBuf_delet, 0, POLICY_LEN);
+ strncpy(achBuf_deletmp,sp,sp_ipsec-sp);
+ snprintf(achBuf_delet,POLICY_LEN-1,"spddelete %s",achBuf_deletmp);
+ strcat(achBuf_delet,";\n");
+ fputs(achBuf_delet, fpDst);
+ plog_android(LLV_WARNING,"delete policy: %s\n", achBuf_delet);
+ }
+ else
+ {
+ plog_android(LLV_WARNING,"There are some cmd error in %s,no ,then flush all SAs and SPs\n", setkey_conf);
+ setkey_flushSAD();
+ setkey_flushSPD();
+ if(achBuf)
+ free(achBuf);
+ if(achBuf_deletmp)
+ free(achBuf_deletmp);
+ if(achBuf_delet)
+ free(achBuf_delet);
+ if(fpSrc)
+ fclose(fpSrc);
+ if(fpDst)
+ fclose(fpDst);
+ return -1;
+ }
+#if 0
+ if((sp_tmp =strchr(sp,'['))!=NULL)
+ {
+ memset(achBuf_deletmp, 0, POLICY_LEN);
+ memset(achBuf_delet, 0, POLICY_LEN);
+ strncpy(achBuf_deletmp,sp,sp_tmp-sp);
+ snprintf(achBuf_delet,POLICY_LEN-1,"spddelete %s",achBuf_deletmp);
+ plog_android(LLV_WARNING,"src[ achBuf_delet: %s,sp_tmp:%s\n", achBuf_deletmp,sp_tmp);
+ if((sp_src_tmp =strchr(sp_tmp,']'))!=NULL)
+ {
+
+ if((sp_dst_tmp =strchr(sp_src_tmp,'['))!=NULL)
+ {
+ memset(achBuf_deletmp, 0, POLICY_LEN);
+ strncpy(achBuf_deletmp,sp_src_tmp+strlen("]"),sp_dst_tmp-sp_src_tmp-strlen("]"));
+ strcat(achBuf_delet,achBuf_deletmp);
+ plog_android(LLV_WARNING,"src]_achBuf_delet: %s,achBuf:%s,sp_dst_tmp:%s\n", achBuf_deletmp,achBuf,sp_dst_tmp);
+ if((sp_dst =strchr(sp_dst_tmp,']'))!=NULL)
+ {
+ if((sp_ipsec =strstr(sp_dst,"ipsec"))!=NULL)
+ {
+ memset(achBuf_deletmp, 0, POLICY_LEN);
+ strncpy(achBuf_deletmp,sp_dst+strlen("]"),sp_ipsec-sp_dst-strlen("]"));
+ strcat(achBuf_delet,achBuf_deletmp);
+ strcat(achBuf_delet,";\n");
+ fputs(achBuf_delet, fpDst);
+ plog_android(LLV_WARNING,"spdadd :%s\n",achBuf_delet);
+ }
+ else
+ {
+ plog_android(LLV_WARNING,"There are some cmd error in %s,before ipsec,then flush all SAs and SPs\n", setkey_conf);
+ setkey_flushSAD();
+ setkey_flushSPD();
+ return -1;
+ }
+ }
+ else
+ {
+ plog_android(LLV_WARNING,"There are some cmd error in %s,no dst],then flush all SAs and SPs\n", setkey_conf);
+ setkey_flushSAD();
+ setkey_flushSPD();
+ return -1;
+ }
+ }
+ else
+ {
+ plog_android(LLV_WARNING,"There are some cmd error in %s,no dst[,then flush all SAs and SPs\n", setkey_conf);
+ setkey_flushSAD();
+ setkey_flushSPD();
+ return -1;
+ }
+ }
+ else
+ {
+ plog_android(LLV_WARNING,"There are some cmd error in %s,no ],then flush all SAs and SPs\n", setkey_conf);
+ setkey_flushSAD();
+ setkey_flushSPD();
+ return -1;
+ }
+
+ }
+ else
+ {
+ plog_android(LLV_WARNING,"There are some cmd error in %s,no [,then flush all SAs and SPs\n", setkey_conf);
+ setkey_flushSAD();
+ setkey_flushSPD();
+ return -1;
+ }
+#endif
+ }
+
+
+ }
+ fclose(fpSrc);
+ fclose(fpDst);
+ if(achBuf)
+ free(achBuf);
+ if(achBuf_deletmp)
+ free(achBuf_deletmp);
+ if(achBuf_delet)
+ free(achBuf_delet);
+ if(function_setkey(setkey_conf_latest) == -1)
+ {
+ return -1;
+ }
+ else
+ {
+ if(shell_rm() == -1)
+ {
+ return -1;
+ }
+ }
+ return 0;
+#endif
+ int ret = flush_SA_SP_exist_xfrm();
+ return ret;
+}
+
+
+
+
diff --git a/src/connectivity/libipsecims/setkey_fileio.h b/src/connectivity/libipsecims/setkey_fileio.h
new file mode 100644
index 0000000..141ecb3
--- /dev/null
+++ b/src/connectivity/libipsecims/setkey_fileio.h
@@ -0,0 +1,83 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <errno.h>
+#include <netdb.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <time.h>
+#include "utils_xfrm.h"
+
+
+/*flush all SA*/
+extern int setkey_flushSAD(void);
+extern int setkey_flushSAD_xfrm(char * ipsec_type);
+/*flush all SP*/
+extern int setkey_flushSPD(void);
+extern int setkey_flushSPD_xfrm(void);
+/*delete one SA entry*/
+extern int setkey_deleteSA(char * src,char * dst,char * ipsec_type,char * spi_src);
+extern int setkey_deleteSA_xfrm(char * src,char * dst,char * ipsec_type,char * spi_src);
+
+/*delete one SP entry*/
+int setkey_deleteSP(char * src,char * dst,enum PROTOCOL_TYPE protocol,char * src_port,char * dst_port,char * direction);
+int setkey_deleteSP_xfrm(char * src,char * dst,enum PROTOCOL_TYPE protocol,char * src_port,char * dst_port,char * direction);
+
+/*dump all SA */
+extern int dump_setkeySA(void);
+
+/*dump all SP */
+extern int dump_setkeySP(void);
+
+/*set one SA*/
+/*ipsec_type:ah esp
+ mode:transport tunnel
+ encrp_algo_src:encryption algorithm,des-cbc,3des-cbc...
+ encrp_algo_src:key of encryption algorithm
+ intergrity_algo_src:authentication algorithm ,hmac-md5,hmac-sha1
+ intergrity_key_src:key of authentication algorithm
+*/
+extern int setkey_setSA(char * ip_src,char * ip_dst,char * ipsec_type,char * spi_src,char * mode, char * encrp_algo_src,char * encrp_key_src,char * intergrity_algo_src,char * intergrity_key_src,int u_id);
+extern int setkey_setSA_xfrm(int cmd,char * ip_src,char * ip_dst,char * ipsec_type,char * spi_src,char * mode, char * encrp_algo_src,char * encrp_key_src,char * intergrity_algo_src,char * intergrity_key_src,int u_id);
+
+extern int setkey_setSA_update(char * ip_src,char * ip_dst,char * ipsec_type,char * spi_src,char * mode,
+ char * encrp_algo_src,char * encrp_key_src,char * intergrity_algo_src,char * intergrity_key_src,int u_id);
+
+/*set one SP of one direction just for transport mode*/
+/*protocol:tcp icmp udp icmp6 ip4 gre
+ direction:src->dst */
+extern int setkey_SP(char * src_range,char * dst_range,enum PROTOCOL_TYPE protocol,char * port_src,char * port_dst,char * ipsec_type,char * mode, char * direction,int u_id);
+extern int setkey_SP_xfrm(int cmd,char * src_range,char * dst_range,enum PROTOCOL_TYPE protocol,char * port_src,char * port_dst,char * src_tunnel,char * dst_tunnel,char * ipsec_type,char * mode, char * direction,int u_id);
+
+/*set one SP of one direction, just for tunnel mode*/
+/*protocol:tcp icmp udp icmp6 ip4 gre
+ direction:src->dst
+src_tunnel,dst_tunnel: tunnel src ip tunnel dst ip */
+extern int setkey_SP_tunnel(char * src_range,char * dst_range,enum PROTOCOL_TYPE protocol,char * port_src,char * port_dst,char * src_tunnel,char * dst_tunnel,char * ipsec_type,char * mode, char * direction,int u_id);
+
+
+/*set one SP of one direction, for 2 layers' ipsec--tunnel mode+transport mode or transport mode+tunnel mode*/
+/*protocol:tcp icmp udp icmp6 ip4 gre
+ direction:src->dst
+src_tunnel,dst_tunnel: tunnel src ip tunnel dst ip */
+extern int setkey_SP_tunnel_transport(char * src_range,char * dst_range,enum PROTOCOL_TYPE protocol,char * port_src,char * port_dst,char * src_tunnel,char * dst_tunnel,char * ipsec_type1,char * mode1, char * ipsec_type2,char * mode2,char * direction,int u_id1,int u_id2);
+
+/*update one SP of one direction, just for transport mode*/
+/*protocol:tcp icmp udp icmp6 ip4 gre
+ direction:src->dst*/
+int setkey_SP_update_transport(char * src_range,char * dst_range,enum PROTOCOL_TYPE protocol,char * port_src,char * port_dst,char * ipsec_type, char * direction,int u_id);
+
+
+/*update one SP of one direction, for 2 layers' ipsec--tunnel mode+transport mode or transport mode+tunnel mode*/
+/*protocol:tcp icmp udp icmp6 ip4 gre
+ direction:src->dst
+src_tunnel,dst_tunnel: tunnel src ip tunnel dst ip */
+int setkey_SP_update_tunnel_transport(char * src_range,char * dst_range,enum PROTOCOL_TYPE protocol,char * port_src,char * port_dst,char * src_tunnel,char * dst_tunnel,char * ipsec_type1,char * mode1, char * ipsec_type2,char * mode2,char * direction,int u_id1,int u_id2);
+int setkey_SP_2layer_xfrm(int cmd,char * src_range,char * dst_range,enum PROTOCOL_TYPE protocol,char * port_src,char * port_dst,char * src_tunnel,char * dst_tunnel,char * ipsec_type1,char * mode1, char * ipsec_type2,char * mode2,char * direction,int u_id1,int u_id2);
+
+/*flush SA\SP from setkey.conf*/
+extern int flush_SA_SP_exist();
+extern int flush_SA_SP_exist_xfrm();
+
diff --git a/src/connectivity/libipsecims/setkey_xfrm.c b/src/connectivity/libipsecims/setkey_xfrm.c
new file mode 100644
index 0000000..c2cffba
--- /dev/null
+++ b/src/connectivity/libipsecims/setkey_xfrm.c
@@ -0,0 +1,833 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <errno.h>
+#include <netdb.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <time.h>
+#include <linux/capability.h>
+#include <sys/capability.h>
+#include <cutils/properties.h>
+#include "setkey_fileio.h"
+#include "setkey_xfrm_parse.h"
+#include "utils_xfrm.h"
+#define LOG_TAG "setkey"
+#include <log/log.h>
+#include <cutils/log.h>
+
+int volte_pid = -1;
+extern program_invocation_name;
+/*only record volte_stack's pid for flush_SA_SP_exist's use*/
+void set_property_volte()
+{
+ char pid[8] ={0};
+ if(program_invocation_name!=NULL)
+ {
+ ALOGE("program_invocation_name:%s\n",program_invocation_name);
+ }
+ if(strstr(program_invocation_name,"volte")!= NULL)
+ if(volte_pid ==-1)
+ {
+ sprintf(pid,"%d",getpid());
+ int ret = property_set("net.ims.volte.pid",pid);
+ if(ret != 0)
+ {
+ ALOGE("set property failed,errno:%d\n",errno);
+ return;
+ }
+ volte_pid =getpid();
+ }
+}
+
+static int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data,
+ int alen)
+{
+ int len = RTA_LENGTH(alen);
+ struct rtattr *rta = NULL;
+
+ if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) {
+ ALOGD( "addattr_l ERROR: message exceeded bound of %d\n",maxlen);
+ return -1;
+ }
+
+ rta = NLMSG_TAIL(n);
+ rta->rta_type = type;
+ rta->rta_len = len;
+ memcpy(RTA_DATA(rta), data, alen);
+ n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len);
+ return 0;
+}
+
+int setkey_deleteSP_xfrm(char * src,char * dst,enum PROTOCOL_TYPE protocol,char * src_port,char * dst_port,char * direction)
+{
+
+ char src_arr[128] = {0};
+ char dst_arr[128] = {0};
+ unsigned groups = ~((unsigned)0); /* XXX */
+ struct rtnl_handle_xfrm rth = { -1,{0},{0},0,0 };
+
+
+ memcpy(src_arr,src,strlen(src));
+ memcpy(dst_arr,dst,strlen(dst));
+
+
+/*fragment delete policy netlink msg*/
+ struct {
+ struct nlmsghdr n;
+ struct xfrm_userpolicy_id xpid;
+ char buf[RTA_BUF_SIZE];
+ } req;
+
+ memset(&req, 0, sizeof(req));
+
+ req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xpid));
+ req.n.nlmsg_flags = NLM_F_REQUEST;
+ req.n.nlmsg_type = XFRM_MSG_DELPOLICY;
+
+ req.xpid.dir = xfrm_dir_parse(direction);
+ if(req.xpid.dir == XFRM_POLICY_ERROR)
+ {
+ ALOGD("setkey_deleteSP_xfrm dir:%s is wrong\n",direction);
+ return -1;
+ }
+ xfrm_selector_parse(&req.xpid.sel, src_arr,dst_arr,protocol,src_port,dst_port);
+
+ groups |= (nl_mgrp_xfrm(XFRMNLGRP_ACQUIRE)|nl_mgrp_xfrm(XFRMNLGRP_EXPIRE)|nl_mgrp_xfrm(XFRMNLGRP_SA)|nl_mgrp_xfrm(XFRMNLGRP_POLICY));
+ if (rtnl_open_byproto_xfrm(&rth, groups, NETLINK_XFRM) < 0)
+ return -1;
+
+ if(send(rth.fd, (void*)&req, sizeof(req), 0)<0)
+ {
+ ALOGD("set2layeripsecrules_xfrm send failed,errno:%d\n",errno);
+ rtnl_close_xfrm(&rth);
+ return -1;
+ }
+ if(req.xpid.dir ==XFRM_POLICY_IN)
+ {
+ req.xpid.dir = XFRM_POLICY_FWD;
+ if(send(rth.fd, (void*)&req, sizeof(req), 0)<0)
+ {
+ ALOGD("setkey_deleteSP_xfrm send POLICY_FWD failed,errno:%d",errno);
+ rtnl_close_xfrm(&rth);
+ return -1;
+ }
+ }
+#ifdef INIT_ENG_BUILD
+ ALOGD("setkey_deleteSP_xfrm successed fd:%d --spddelete %s[%s] %s[%s] %d -P %s;\n",rth.fd,src,src_port,dst,dst_port,protocol,direction);
+#endif
+ rtnl_close_xfrm(&rth);
+ return 0;
+}
+
+int setkey_deleteSA_xfrm(char * src,char * dst,char * ipsec_type,char * spi_src)
+{
+
+ char src_arr[128] = {0};
+ char dst_arr[128] = {0};
+ unsigned groups = ~((unsigned)0); /* XXX */
+ struct rtnl_handle_xfrm rth = { -1,{0},{0},0,0 };
+
+ memcpy(src_arr,src,strlen(src));
+ memcpy(dst_arr,dst,strlen(dst));
+
+ /*fragment delete state netlink msg*/
+ struct {
+ struct nlmsghdr n;
+ struct xfrm_usersa_id xsid;
+ char buf[RTA_BUF_SIZE];
+ } req;
+
+ memset(&req, 0, sizeof(req));
+
+ req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xsid));
+ req.n.nlmsg_flags = NLM_F_REQUEST;
+ req.n.nlmsg_type = XFRM_MSG_DELSA;
+ req.xsid.family = AF_UNSPEC;
+
+ /* ID */
+ struct xfrm_id id ;
+ xfrm_address_t saddr_xfrm;
+ memset(&id, 0, sizeof(id));
+ memset(&saddr_xfrm, 0, sizeof(saddr_xfrm));
+ xfrm_id_parse(&saddr_xfrm, &id, &req.xsid.family,src_arr,dst_arr,ipsec_type);
+ __u32 spi;
+ if (get_u32(&spi, spi_src, 0))
+ {
+ ALOGD("xfrm_id_parse spi:%s is wrong\n",spi_src);
+ return -1;
+ }
+
+ spi = htonl(spi);
+ id.spi = spi;
+ memcpy(&req.xsid.daddr, &id.daddr, sizeof(req.xsid.daddr));
+ req.xsid.spi = id.spi;
+ req.xsid.proto = id.proto;
+
+ addattr_l(&req.n, sizeof(req.buf), XFRMA_SRCADDR,
+ (void *)&saddr_xfrm, sizeof(saddr_xfrm));
+
+ groups |= (nl_mgrp_xfrm(XFRMNLGRP_ACQUIRE)|nl_mgrp_xfrm(XFRMNLGRP_EXPIRE)|nl_mgrp_xfrm(XFRMNLGRP_SA)|nl_mgrp_xfrm(XFRMNLGRP_POLICY));
+
+ if (rtnl_open_byproto_xfrm(&rth, groups, NETLINK_XFRM) < 0)
+ return -1;
+ if(send(rth.fd, (void*)&req, sizeof(req), 0)<0)
+ {
+ ALOGD("set2layeripsecrules_xfrm send failed,errno:%d\n",errno);
+ rtnl_close_xfrm(&rth);
+ return -1;
+ }
+#ifdef INIT_ENG_BUILD
+ ALOGD("setkey_deleteSA_xfrm successed fd:%d --delete %s %s %s %s;\n",rth.fd,src,dst,ipsec_type,spi_src);
+#endif
+ rtnl_close_xfrm(&rth);
+ return 0;
+}
+
+int setkey_setSA_xfrm(int cmd,char * ip_src,char * ip_dst,char * ipsec_type,char * spi_src,char * mode,
+ char * encrp_algo_src,char * encrp_key_src,char * intergrity_algo_src,char * intergrity_key_src,int u_id)
+{
+
+ char encrp_algo_arr[128] = {0};
+ char intergrity_algo_arr[128] = {0};
+ char srcport_arr[64] = {0};
+ char dstport_arr[64] = {0};
+ char * port_head = NULL;
+ char * port_tail = NULL;
+ char src_arr[128] = {0};
+ char dst_arr[128] = {0};
+ unsigned groups = ~((unsigned)0); /* XXX */
+ struct rtnl_handle_xfrm rth = { -1,{0},{0},0,0 };
+
+ set_property_volte();
+
+ /*sepearte src addr and src port\dst addr and dst port, state's format often is add xx[xx] xx[xx] esp xx ....*/
+ port_head = strchr(ip_src,'[');
+ if(port_head == NULL)
+ {
+ memcpy(src_arr,ip_src,strlen(ip_src));
+ memcpy(srcport_arr,"0",1);
+ }
+ else
+ {
+ port_tail = strchr(ip_src,']');
+ if (port_tail == NULL)
+ {
+#ifdef INIT_ENG_BUILD
+ ALOGD("setkey_SA_xfrm wrong src ip:%s \n",ip_src);
+#endif
+ return -1;
+ }
+ else
+ {
+ memcpy(srcport_arr,port_head+1,port_tail-port_head-1);
+ memcpy(src_arr,ip_src,port_head-ip_src);
+ }
+ }
+ port_head = strchr(ip_dst,'[');
+ if(port_head==NULL)
+ {
+ memcpy(dst_arr,ip_dst,strlen(ip_dst));
+ memcpy(dstport_arr,"0",1);
+ }
+ else
+ {
+ port_tail = strchr(ip_dst,']');
+ if (port_tail == NULL)
+ {
+#ifdef INIT_ENG_BUILD
+ ALOGD("setkey_SA_xfrm wrong dst ip:%s \n",ip_dst);
+#endif
+ return -1;
+ }
+ else
+ {
+ memcpy(dstport_arr,port_head+1,port_tail-port_head-1);
+ memcpy(dst_arr,ip_dst,port_head-ip_dst);
+ }
+ }
+
+ /*fragment add/modify state netlink msg*/
+ struct {
+ struct nlmsghdr n;
+ struct xfrm_usersa_info xsinfo;
+ char buf[RTA_BUF_SIZE];
+ } req;
+
+ memset(&req, 0, sizeof(req));
+
+ req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xsinfo));
+ req.n.nlmsg_flags = NLM_F_REQUEST;
+ req.n.nlmsg_type = cmd;
+
+
+ req.xsinfo.family = AF_UNSPEC;
+ req.xsinfo.lft.soft_byte_limit = XFRM_INF;
+ req.xsinfo.lft.hard_byte_limit = XFRM_INF;
+ req.xsinfo.lft.soft_packet_limit = XFRM_INF;
+ req.xsinfo.lft.hard_packet_limit = XFRM_INF;
+ req.xsinfo.reqid = u_id;
+ /* ID */
+ if(xfrm_mode_parse(&req.xsinfo.mode, mode) ==-1)
+ {
+ ALOGD("setkey_SA_xfrm mode:%s is wrong\n",mode);
+ return -1;
+ }
+ __u32 spi;
+ if (get_u32(&spi, spi_src, 0))
+ {
+ ALOGD("xfrm_id_parse spi:%s is wrong\n",spi_src);
+ return -1;
+ }
+
+ spi = htonl(spi);
+ req.xsinfo.id.spi = spi;
+ if(xfrm_id_parse(&req.xsinfo.saddr, &req.xsinfo.id,&req.xsinfo.family,
+ src_arr,dst_arr,ipsec_type)<0)
+ {
+#ifdef INIT_ENG_BUILD
+ ALOGD("setkey_SA_xfrm->xfrm_id_parse failed ip_src:%s,ip_dst:%s,ipsec_type:%s",ip_src,ip_dst,ipsec_type);
+#endif
+ return -1;
+ }
+ xfrm_selector_parse(&req.xsinfo.sel, src_arr,dst_arr,0,srcport_arr,dstport_arr);
+ /* ALGO */
+ struct {
+ union {
+ struct xfrm_algo alg;
+ struct xfrm_algo_aead aead;
+ struct xfrm_algo_auth auth;
+ } u;
+ char buf[XFRM_ALGO_KEY_BUF_SIZE];
+ } alg;
+ int len;
+ char *buf = NULL;
+ memset(&alg, 0, sizeof(alg));
+ buf = alg.u.alg.alg_key;
+ len = sizeof(alg.u.alg);
+
+ xfrm_encry_algo_parse(encrp_algo_src, encrp_algo_arr);
+ if(strcmp(encrp_algo_arr,"not-supported") == 0)
+ return -1;
+
+ if((encrp_algo_src == NULL)||(strcmp(encrp_algo_src,"null")==0))
+ {
+ alg.u.alg.alg_key_len = 0;
+ memcpy(alg.u.alg.alg_name, "ecb(cipher_null)", strlen("ecb(cipher_null)"));
+ }
+ else
+ if(xfrm_algo_parse((void *)&alg, encrp_algo_arr, encrp_key_src,
+ buf, sizeof(alg.buf))==-1)
+ {
+#ifdef INIT_ENG_BUILD
+ ALOGD("setkey_SA_xfrm->xfrm_algo_parse failed encrp_algo:%s,encrp_key:%s,",encrp_algo_src, encrp_key_src);
+#endif
+ return -1;
+ }
+ len += alg.u.alg.alg_key_len;
+ addattr_l(&req.n, sizeof(req.buf), XFRMA_ALG_CRYPT,(void *)&alg, len);
+
+ memset((void *)&alg, 0,sizeof(alg));
+ buf = alg.u.alg.alg_key;
+ len = sizeof(alg.u.alg);
+ xfrm_interg_algo_parse(intergrity_algo_src, intergrity_algo_arr);
+ if(strcmp(intergrity_algo_arr ,"not-supported") == 0)
+ return -1;
+ if((intergrity_algo_src == NULL)||(strcmp(intergrity_algo_src,"null")==0))
+ {
+ alg.u.alg.alg_key_len = 0;
+ memcpy(alg.u.alg.alg_name, "digest_null", strlen("digest_null"));
+ }
+ else
+ if(xfrm_algo_parse((void *)&alg, intergrity_algo_arr, intergrity_key_src,
+ buf, sizeof(alg.buf))<-1)
+ {
+#ifdef INIT_ENG_BUILD
+ ALOGD("setkey_SA_xfrm->xfrm_algo_parse failed intergrity crp_algo:%s,intergrity _key:%s,",intergrity_algo_src, intergrity_key_src);
+#endif
+ return -1;
+ }
+ len += alg.u.alg.alg_key_len;
+ addattr_l(&req.n, sizeof(req.buf), XFRMA_ALG_AUTH,(void *)&alg, len);
+
+ groups |= (nl_mgrp_xfrm(XFRMNLGRP_ACQUIRE)|nl_mgrp_xfrm(XFRMNLGRP_EXPIRE)|nl_mgrp_xfrm(XFRMNLGRP_SA)|nl_mgrp_xfrm(XFRMNLGRP_POLICY));
+
+ if (rtnl_open_byproto_xfrm(&rth, groups, NETLINK_XFRM) < 0)
+ return -1;
+
+ if(send(rth.fd, (void*)&req, sizeof(req), 0)<0)
+ {
+ ALOGD("set2layeripsecrules_xfrm send failed,errno:%d",errno);
+ rtnl_close_xfrm(&rth);
+ return -1;
+ }
+#ifdef INIT_ENG_BUILD
+ ALOGD("setkey_SA_xfrm successed fd:%d ---add %s %s %s %s -m %s -E %s %s -A %s %s -u %d; spi:%d\n",rth.fd,ip_src,ip_dst,ipsec_type,spi_src,mode,
+ encrp_algo_src,encrp_key_src,intergrity_algo_src,intergrity_key_src,u_id,req.xsinfo.id.spi);
+#endif
+ rtnl_close_xfrm(&rth);
+ return 0;
+}
+
+
+int setkey_SP_xfrm(int cmd,char * src_range,char * dst_range,enum PROTOCOL_TYPE protocol,char * port_src,char * port_dst,char * src_tunnel,char * dst_tunnel,char * ipsec_type,char * mode, char * direction,int u_id)
+{
+ char src_arr[128] = {0};
+ char dst_arr[128] = {0};
+ char src_tunnel_arr[128] = {0};
+ char dst_tunnel_arr[128] = {0};
+ unsigned groups = ~((unsigned)0); /* XXX */
+ struct rtnl_handle_xfrm rth = { -1,{0},{0},0,0 };
+
+ memcpy(src_arr,src_range,strlen(src_range));
+ memcpy(dst_arr,dst_range,strlen(dst_range));
+ if(src_tunnel)
+ memcpy(src_tunnel_arr,src_tunnel,strlen(src_tunnel));
+ if(dst_tunnel)
+ memcpy(dst_tunnel_arr,dst_tunnel,strlen(dst_tunnel));
+
+ set_property_volte();
+
+
+
+ struct req_handle_xfrm req;
+ char tmpls_buf[XFRM_TMPLS_BUF_SIZE];
+ struct xfrm_user_tmpl *tmpl = NULL;
+ int tmpls_len = 0;
+
+
+ memset(&req, 0, sizeof(req));
+ memset(&tmpls_buf, 0, sizeof(tmpls_buf));
+
+ req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xpinfo));
+ req.n.nlmsg_flags = NLM_F_REQUEST;
+ req.n.nlmsg_type = cmd;
+
+ req.xpinfo.lft.soft_byte_limit = XFRM_INF;
+ req.xpinfo.lft.hard_byte_limit = XFRM_INF;
+ req.xpinfo.lft.soft_packet_limit = XFRM_INF;
+ req.xpinfo.lft.hard_packet_limit = XFRM_INF;
+ req.xpinfo.dir = xfrm_dir_parse(direction);
+ req.xpinfo.priority = 1000;
+ xfrm_selector_parse(&req.xpinfo.sel, src_arr,dst_arr,protocol,port_src,port_dst);
+
+ if(req.xpinfo.dir == XFRM_POLICY_ERROR)
+ {
+ ALOGD("setkey_SP_xfrm dir:%s is wrong",direction);
+ return -1;
+ }
+ tmpl = (struct xfrm_user_tmpl *)((char *)tmpls_buf + tmpls_len);
+
+ if(xfrm_mode_parse(&tmpl->mode, mode) ==-1)
+ {
+ ALOGD("setkey_SP_xfrm mode:%s is wrong",mode);
+ return -1;
+ }
+ tmpl->family = req.xpinfo.sel.family;
+ if(tmpl->mode == XFRM_MODE_TUNNEL)
+ {
+ xfrm_id_parse(&tmpl->saddr, &tmpl->id, &tmpl->family,
+ src_tunnel_arr,dst_tunnel_arr,ipsec_type);
+ }
+
+ tmpl->aalgos = (~(__u32)0);
+ tmpl->ealgos = (~(__u32)0);
+ tmpl->calgos = (~(__u32)0);
+ tmpl->reqid = u_id;
+ tmpl->id.proto = xfrm_xfrmproto_getbyname(ipsec_type);
+ if(tmpl->id.proto <0)
+ {
+ ALOGD("setkey_SP_xfrm ipsec_type:%s is wrong",ipsec_type);
+ return -1;
+ }
+ tmpls_len += sizeof(*tmpl);
+ if (tmpls_len > 0) {
+ addattr_l(&req.n, sizeof(req), XFRMA_TMPL,
+ (void *)tmpls_buf, tmpls_len);
+ }
+
+ groups |= (nl_mgrp_xfrm(XFRMNLGRP_ACQUIRE)|nl_mgrp_xfrm(XFRMNLGRP_EXPIRE)|nl_mgrp_xfrm(XFRMNLGRP_SA)|nl_mgrp_xfrm(XFRMNLGRP_POLICY));
+
+ if (rtnl_open_byproto_xfrm(&rth, groups, NETLINK_XFRM) < 0)
+ return -1;
+
+ if(send(rth.fd, (void*)&req, sizeof(req), 0)<0)
+ {
+ ALOGD("set2layeripsecrules_xfrm send failed,errno:%d",errno);
+ rtnl_close_xfrm(&rth);
+ return -1;
+ }
+ if(req.xpinfo.dir ==XFRM_POLICY_IN)
+ {
+ req.xpinfo.dir = XFRM_POLICY_FWD;
+ if(send(rth.fd, (void*)&req, sizeof(req), 0)<0)
+ {
+ ALOGD("set2layeripsecrules_xfrm send POLICY_FWD failed,errno:%d",errno);
+ rtnl_close_xfrm(&rth);
+ return -1;
+ }
+ }
+#ifdef INIT_ENG_BUILD
+ ALOGD("setkey_SP_xfrm successed fd:%d --spdadd %s[%s] %s[%s] %d -P %s ipsec %s/%s//unique:%d;\n",rth.fd,src_range,port_src,dst_range,port_dst,protocol,direction,ipsec_type,mode,u_id);
+#endif
+ rtnl_close_xfrm(&rth);
+ return 0;
+}
+
+int setkey_SP_2layer_xfrm(int cmd,char * src_range,char * dst_range,enum PROTOCOL_TYPE protocol,char * port_src,char * port_dst,char * src_tunnel,char * dst_tunnel,char * ipsec_type1,char * mode1, char * ipsec_type2,char * mode2,char * direction,int u_id1,int u_id2)
+{
+ char src_arr[128] = {0};
+ char dst_arr[128] = {0};
+ char src_tunnel_arr[128] = {0};
+ char dst_tunnel_arr[128] = {0};
+ unsigned groups = ~((unsigned)0); /* XXX */
+ struct rtnl_handle_xfrm rth = { -1,{0},{0},0,0 };
+
+ memcpy(src_arr,src_range,strlen(src_range));
+ memcpy(dst_arr,dst_range,strlen(dst_range));
+ if(src_tunnel)
+ memcpy(src_tunnel_arr,src_tunnel,strlen(src_tunnel));
+ if(dst_tunnel)
+ memcpy(dst_tunnel_arr,dst_tunnel,strlen(dst_tunnel));
+
+
+ struct req_handle_xfrm req;
+ char tmpls_buf[XFRM_TMPLS_BUF_SIZE];
+ struct xfrm_user_tmpl *tmpl = NULL;
+ int tmpls_len = 0;
+
+ set_property_volte();
+
+ memset(&req, 0, sizeof(req));
+ memset(&tmpls_buf, 0, sizeof(tmpls_buf));
+
+ req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xpinfo));
+ req.n.nlmsg_flags = NLM_F_REQUEST;
+ req.n.nlmsg_type = cmd;
+
+ req.xpinfo.lft.soft_byte_limit = XFRM_INF;
+ req.xpinfo.lft.hard_byte_limit = XFRM_INF;
+ req.xpinfo.lft.soft_packet_limit = XFRM_INF;
+ req.xpinfo.lft.hard_packet_limit = XFRM_INF;
+ req.xpinfo.dir = xfrm_dir_parse(direction);
+ req.xpinfo.priority = 1000;
+ xfrm_selector_parse(&req.xpinfo.sel, src_arr,dst_arr,protocol,port_src,port_dst);
+
+ if(req.xpinfo.dir == XFRM_POLICY_ERROR)
+ {
+ ALOGD("setkey_SP_xfrm dir:%s is wrong",direction);
+ return -1;
+ }
+ tmpl = (struct xfrm_user_tmpl *)((char *)tmpls_buf + tmpls_len);
+
+ if(xfrm_mode_parse(&tmpl->mode, mode1) ==-1)
+ {
+ ALOGD("setkey_SP_xfrm mode:%s is wrong",mode1);
+ return -1;
+ }
+ tmpl->family = req.xpinfo.sel.family;
+ if(tmpl->mode == XFRM_MODE_TUNNEL)
+ {
+ xfrm_id_parse(&tmpl->saddr, &tmpl->id, &tmpl->family,
+ src_tunnel_arr,dst_tunnel_arr,ipsec_type1);
+ }
+
+ tmpl->aalgos = (~(__u32)0);
+ tmpl->ealgos = (~(__u32)0);
+ tmpl->calgos = (~(__u32)0);
+ tmpl->reqid = u_id1;
+ tmpl->id.proto = xfrm_xfrmproto_getbyname(ipsec_type1);
+ if(tmpl->id.proto <0)
+ {
+ ALOGD("setkey_SP_xfrm ipsec_type:%s is wrong",ipsec_type1);
+ return -1;
+ }
+ tmpls_len += sizeof(*tmpl);
+ tmpl = (struct xfrm_user_tmpl *)((char *)tmpls_buf + tmpls_len);
+
+ if(xfrm_mode_parse(&tmpl->mode, mode2) ==-1)
+ {
+ ALOGD("setkey_SP_xfrm mode:%s is wrong",mode1);
+ return -1;
+ }
+ tmpl->family = req.xpinfo.sel.family;
+ if(tmpl->mode == XFRM_MODE_TUNNEL)
+ {
+ xfrm_id_parse(&tmpl->saddr, &tmpl->id, &tmpl->family,
+ src_tunnel_arr,dst_tunnel_arr,ipsec_type2);
+ }
+ tmpl->aalgos = (~(__u32)0);
+ tmpl->ealgos = (~(__u32)0);
+ tmpl->calgos = (~(__u32)0);
+ tmpl->reqid = u_id2;
+ tmpl->id.proto = xfrm_xfrmproto_getbyname(ipsec_type2);
+ if(tmpl->id.proto <0)
+ {
+ ALOGD("setkey_SP_xfrm ipsec_type:%s is wrong",ipsec_type2);
+ return -1;
+ }
+ tmpls_len += sizeof(*tmpl);
+ if (tmpls_len > 0) {
+ addattr_l(&req.n, sizeof(req), XFRMA_TMPL,
+ (void *)tmpls_buf, tmpls_len);
+ }
+
+ groups |= (nl_mgrp_xfrm(XFRMNLGRP_ACQUIRE)|nl_mgrp_xfrm(XFRMNLGRP_EXPIRE)|nl_mgrp_xfrm(XFRMNLGRP_SA)|nl_mgrp_xfrm(XFRMNLGRP_POLICY));
+
+ if (rtnl_open_byproto_xfrm(&rth, groups, NETLINK_XFRM) < 0)
+ return -1;
+
+ if(send(rth.fd, (void*)&req, sizeof(req), 0)<0)
+ {
+ ALOGD("set2layeripsecrules_xfrm send failed,errno:%d",errno);
+ rtnl_close_xfrm(&rth);
+ return -1;
+ }
+ if(req.xpinfo.dir ==XFRM_POLICY_IN)
+ {
+ req.xpinfo.dir = XFRM_POLICY_FWD;
+ if(send(rth.fd, (void*)&req, sizeof(req), 0)<0)
+ {
+ ALOGD("set2layeripsecrules_xfrm send POLICY_FWD failed,errno:%d",errno);
+ rtnl_close_xfrm(&rth);
+ return -1;
+ }
+ }
+#ifdef INIT_ENG_BUILD
+ ALOGD("setkey_SP_2layer_xfrm successed fd:%d --spdupdate %s[%s] %s[%s] %d -P %s prio 1000 ipsec %s/%s//unique:%d %s/%s/%s-%s/unique:%d;\n",rth.fd,src_range,port_src,dst_range,port_dst,protocol,direction,ipsec_type1,mode1,u_id1,ipsec_type2,mode2,src_tunnel,dst_tunnel,u_id2);
+#endif
+ rtnl_close_xfrm(&rth);
+ return 0;
+}
+int setkey_flushSAD_xfrm(char * ipsec_type)
+{
+ unsigned groups = ~((unsigned)0); /* XXX */
+ struct rtnl_handle_xfrm rth = { -1,{0},{0},0,0 };
+
+ struct {
+ struct nlmsghdr n;
+ struct xfrm_usersa_flush xsf;
+ } req;
+
+
+ memset(&req, 0, sizeof(req));
+
+ req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xsf));
+ req.n.nlmsg_flags = NLM_F_REQUEST;
+ req.n.nlmsg_type = XFRM_MSG_FLUSHSA;
+ req.xsf.proto = 0;
+
+ req.xsf.proto = (__u8)xfrm_xfrmproto_getbyname(ipsec_type);
+ if (req.xsf.proto < 0)
+ {
+ ALOGD("setkey_flushSAD_xfrm :%s is wrong",ipsec_type);
+ return -1;
+ }
+
+ groups |= (nl_mgrp_xfrm(XFRMNLGRP_ACQUIRE)|nl_mgrp_xfrm(XFRMNLGRP_EXPIRE)|nl_mgrp_xfrm(XFRMNLGRP_SA)|nl_mgrp_xfrm(XFRMNLGRP_POLICY));
+
+ if (rtnl_open_byproto_xfrm(&rth, groups, NETLINK_XFRM) < 0)
+ return -1;
+
+ if(send(rth.fd, (void*)&req, sizeof(req), 0)<0)
+ {
+ ALOGD("set2layeripsecrules_xfrm send POLICY_FWD failed,errno:%d",errno);
+ rtnl_close_xfrm(&rth);
+ return -1;
+ }
+ ALOGD("setkey_flushSAD_xfrm successed fd:%d --flush ;\n",rth.fd);
+ rtnl_close_xfrm(&rth);
+
+ return 0;
+}
+int setkey_flushSPD_xfrm(void)
+{
+ unsigned groups = ~((unsigned)0); /* XXX */
+ struct rtnl_handle_xfrm rth = { -1,{0},{0},0,0 };
+
+
+ struct {
+ struct nlmsghdr n;
+ char buf[RTA_BUF_SIZE];
+ } req;
+
+ memset(&req, 0, sizeof(req));
+
+
+ req.n.nlmsg_len = NLMSG_LENGTH(0); /* nlmsg data is nothing */
+ req.n.nlmsg_flags = NLM_F_REQUEST;
+ req.n.nlmsg_type = XFRM_MSG_FLUSHPOLICY;
+
+ groups |= (nl_mgrp_xfrm(XFRMNLGRP_ACQUIRE)|nl_mgrp_xfrm(XFRMNLGRP_EXPIRE)|nl_mgrp_xfrm(XFRMNLGRP_SA)|nl_mgrp_xfrm(XFRMNLGRP_POLICY));
+
+ if (rtnl_open_byproto_xfrm(&rth, groups, NETLINK_XFRM) < 0)
+ return -1;
+ if(send(rth.fd, (void*)&req, sizeof(req), 0)<0)
+ {
+ ALOGD("set2layeripsecrules_xfrm send POLICY_FWD failed,errno:%d",errno);
+ rtnl_close_xfrm(&rth);
+ return -1;
+ }
+ ALOGD("setkey_flushSPD_xfrm successed fd:%d --flush ;\n",rth.fd);
+
+ rtnl_close_xfrm(&rth);
+
+ return 0;
+}
+int flush_SA_SP_exist_xfrm()
+{
+ unsigned groups = ~((unsigned)0); /* XXX */
+ struct rtnl_handle_xfrm rth = { -1,{0},{0},0,0 };
+
+ struct {
+ struct nlmsghdr nlh;
+ struct rtgenmsg g;
+ __u16 align_rta; /* attribute has to be 32bit aligned */
+ struct rtattr ext_req;
+ __u32 ext_filter_mask;
+ } req;
+
+ memset(&req, 0, sizeof(req));
+ req.nlh.nlmsg_len = sizeof(req);
+ req.nlh.nlmsg_type = XFRM_MSG_GETPOLICY;
+ req.nlh.nlmsg_flags = NLM_F_DUMP|NLM_F_REQUEST;
+ req.nlh.nlmsg_seq = rth.dump = ++rth.seq;
+ req.g.rtgen_family = AF_UNSPEC;
+
+ req.ext_req.rta_type = IFLA_EXT_MASK;
+ req.ext_req.rta_len = RTA_LENGTH(sizeof(__u32));
+ req.ext_filter_mask = RTEXT_FILTER_VF;
+
+ groups |= (nl_mgrp_xfrm(XFRMNLGRP_ACQUIRE)|nl_mgrp_xfrm(XFRMNLGRP_EXPIRE)|nl_mgrp_xfrm(XFRMNLGRP_SA)|nl_mgrp_xfrm(XFRMNLGRP_POLICY));
+
+ if (rtnl_open_byproto_xfrm(&rth, groups, NETLINK_XFRM) < 0)
+ return -1;
+ if(send(rth.fd, (void*)&req, sizeof(req), 0)<0)
+ {
+ ALOGD("flush_SA_SP_exist_xfrm send msg failed,errno:%d",errno);
+ rtnl_close_xfrm(&rth);
+ return -1;
+ }
+ if (rtnl_listen_xfrm(&rth, rtnl_accept_msg_xfrm) < 0)
+ {
+ rtnl_close_xfrm(&rth);
+ ALOGD("flush_SA_SP_exist_xfrm <0 done");
+ return -2;
+ }
+ ALOGD("flush_SA_SP_exist_xfrm done");
+ rtnl_close_xfrm(&rth);
+
+ return 0;
+}
+
+int xfrm_policy_process_delete_exist( struct rtnl_handle_xfrm * rth,struct nlmsghdr *n,pid_t volte_pid)
+{
+
+ struct xfrm_userpolicy_info *xpinfo = NULL;
+ int len = n->nlmsg_len;
+
+
+ xpinfo = NLMSG_DATA(n);
+ len -= NLMSG_SPACE(sizeof(*xpinfo));
+ if (len < 0) {
+ ALOGE( "BUG: wrong nlmsg len %d\n", len);
+ return -1;
+ }
+ if(xpinfo->sel.user != volte_pid)
+ {
+ ALOGE( "we donot need to process:%d's policy\n", xpinfo->sel.user);
+ return 0;
+ }
+
+/*fragment delete policy*/
+ struct {
+ struct nlmsghdr n;
+ struct xfrm_userpolicy_id xpid;
+ char buf[RTA_BUF_SIZE];
+ } req;
+
+ memset(&req, 0, sizeof(req));
+
+ req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xpid));
+ req.n.nlmsg_flags = NLM_F_REQUEST;
+ req.n.nlmsg_type = XFRM_MSG_DELPOLICY;
+
+ req.xpid.dir = xpinfo->dir;
+
+ memcpy(&req.xpid.sel,&xpinfo->sel,sizeof(req.xpid.sel));
+
+
+ if(send(rth->fd, (void*)&req, sizeof(req), 0)<0)
+ {
+ ALOGD("xfrm_policy_process_delete_exist send failed,errno:%d",errno);
+ return -1;
+ }
+#ifdef INIT_ENG_BUILD
+ if(req.xpid.sel.family == AF_INET)
+ ALOGD("xfrm_policy_process_delete_exist successed fd:%d --spddelete 0x%x[%d] 0x%x[%d] %d -P %d;\n",rth->fd,req.xpid.sel.saddr.a4,req.xpid.sel.sport,req.xpid.sel.daddr.a4,req.xpid.sel.dport,req.xpid.sel.proto,req.xpid.dir);
+ else
+ ALOGD("xfrm_policy_process_delete_exist successed fd:%d --spddelete 0x%x %x %x %x[%d] 0x%x %x %x %x[%d] %d -P %d;\n",rth->fd,
+ req.xpid.sel.saddr.a6[0],req.xpid.sel.saddr.a6[1],req.xpid.sel.saddr.a6[2],req.xpid.sel.saddr.a6[3],req.xpid.sel.sport,
+ req.xpid.sel.daddr.a6[0],req.xpid.sel.daddr.a6[1],req.xpid.sel.daddr.a6[2],req.xpid.sel.daddr.a6[3],req.xpid.sel.dport,
+ req.xpid.sel.proto,req.xpid.dir);
+#endif
+ return 0;
+}
+
+int xfrm_state_process_delete_exist( struct rtnl_handle_xfrm * rth,struct nlmsghdr *n,pid_t volte_pid)
+{
+
+ struct xfrm_usersa_info * xsinfo = NULL;
+ int len = n->nlmsg_len;
+ xfrm_address_t saddr;
+
+ xsinfo = NLMSG_DATA(n);
+ len -= NLMSG_SPACE(sizeof(*xsinfo));
+ if (len < 0) {
+ ALOGE( "BUG: wrong nlmsg len %d\n", len);
+ return -1;
+ }
+
+ if(xsinfo->sel.user != volte_pid)
+ {
+ ALOGE( "we donot need to process:%d's policy\n", xsinfo->sel.user);
+ return 0;
+ }
+
+/*fragment delete state*/
+ struct {
+ struct nlmsghdr n;
+ struct xfrm_usersa_id xsid;
+ char buf[RTA_BUF_SIZE];
+ } req;
+
+ memset(&req, 0, sizeof(req));
+
+ req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xsid));
+ req.n.nlmsg_flags = NLM_F_REQUEST;
+ req.n.nlmsg_type = XFRM_MSG_DELSA;
+
+ req.xsid.family = xsinfo->family;
+ memcpy(&req.xsid.daddr,&xsinfo->sel.daddr,sizeof(xsinfo->sel.daddr));
+ memcpy(&saddr,&xsinfo->saddr,sizeof(xsinfo->saddr));
+ addattr_l(&req.n, sizeof(req.buf), XFRMA_SRCADDR,
+ (void *)&saddr, sizeof(saddr));
+ if(send(rth->fd, (void*)&req, sizeof(req), 0)<0)
+ {
+ ALOGD("xfrm_state_process_delete_exist send failed,errno:%d",errno);
+ return -1;
+ }
+#ifdef INIT_ENG_BUILD
+ if(xsinfo->sel.family == AF_INET)
+ ALOGD("xfrm_state_process_delete_exist successed fd:%d --delete 0x%x 0x%x %d;\n",rth->fd,xsinfo->sel.saddr.a4,xsinfo->sel.daddr.a4,xsinfo->id.spi);
+ else
+ ALOGD("xfrm_state_process_delete_exist successed fd:%d --delete 0x%x %x %x %x 0x%x %x %x %x %d ;\n",rth->fd,
+ xsinfo->sel.saddr.a6[0],xsinfo->sel.saddr.a6[1],xsinfo->sel.saddr.a6[2],xsinfo->sel.saddr.a6[3],
+ xsinfo->sel.daddr.a6[0],xsinfo->sel.daddr.a6[1],xsinfo->sel.daddr.a6[2],xsinfo->sel.daddr.a6[3],
+ xsinfo->id.spi);
+#endif
+ return 0;
+}
+
diff --git a/src/connectivity/libipsecims/setkey_xfrm_parse.c b/src/connectivity/libipsecims/setkey_xfrm_parse.c
new file mode 100644
index 0000000..44e1aeb
--- /dev/null
+++ b/src/connectivity/libipsecims/setkey_xfrm_parse.c
@@ -0,0 +1,272 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <errno.h>
+#include <netdb.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <time.h>
+#include <linux/capability.h>
+#include <sys/capability.h>
+#include <cutils/properties.h>
+#include "setkey_fileio.h"
+#include "utils_xfrm.h"
+#include "setkey_xfrm_parse.h"
+#define LOG_TAG "setkey"
+#include <log/log.h>
+#include <cutils/log.h>
+
+
+const struct typeent xfrmproto_types[]= {
+ { "esp", IPPROTO_ESP }, { "ah", IPPROTO_AH }, { "comp", IPPROTO_COMP },
+ { "route2", IPPROTO_ROUTING }, { "hao", IPPROTO_DSTOPTS },
+ { "ipsec-any", IPSEC_PROTO_ANY },
+ { NULL, -1 }
+};
+
+
+int xfrm_xfrmproto_getbyname(char *name)
+{
+ int i;
+
+ for (i = 0; ; i++) {
+ const struct typeent *t = &xfrmproto_types[i];
+ if (!t->t_name || t->t_type == -1)
+ break;
+
+ if (strcmp(t->t_name, name) == 0)
+ return t->t_type;
+ }
+
+ return -1;
+}
+
+
+int xfrm_id_parse(xfrm_address_t *saddr_xfrm, struct xfrm_id *id, __u16 *family,
+ char * src,char * dst,char * ipsec_type)
+{
+
+ inet_prefix dst_prefix;
+ inet_prefix src_prefix;
+
+ memset(&dst_prefix, 0, sizeof(dst_prefix));
+ memset(&src_prefix, 0, sizeof(src_prefix));
+
+ get_prefix(&src_prefix, src, AF_UNSPEC);
+ if (family)
+ *family = src_prefix.family;
+ memcpy(saddr_xfrm, &src_prefix.data, sizeof(*saddr_xfrm));
+ get_prefix(&dst_prefix, dst, AF_UNSPEC);
+ memcpy(&id->daddr, &dst_prefix.data, sizeof(id->daddr));
+
+ int ret = xfrm_xfrmproto_getbyname(ipsec_type);
+ if(ret<0)
+ {
+ ALOGD("xfrm_id_parse %s is wrong\n",ipsec_type);
+ return -1;
+ }
+ id->proto = (__u8)ret;
+
+
+ return 0;
+}
+
+void xfrm_encry_algo_parse(char * encry_src, char *name)
+{
+ if(encry_src == NULL)
+ memcpy(name,"ecb(cipher_null)",strlen("ecb(cipher_null)"));
+ else if(strcmp(encry_src,"des-cbc")==0)
+ memcpy(name,"cbc(des)",strlen("cbc(des)"));
+ else if(strcmp(encry_src,"des-ede3-cbc")==0)
+ memcpy(name,"cbc(des3_ede)",strlen("cbc(des3_ede)"));
+ else if(strcmp(encry_src,"3des-cbc")==0)
+ memcpy(name,"cbc(des3_ede)",strlen("cbc(des3_ede)"));
+ else if(strcmp(encry_src,"cast5-cbc")==0)
+ memcpy(name,"cbc(cast5)",strlen("cbc(cast5)"));
+ else if(strcmp(encry_src,"blowfish-cbc")==0)
+ memcpy(name,"cbc(blowfish)",strlen("cbc(blowfish)"));
+ else if(strcmp(encry_src,"aes-cbc")==0)
+ memcpy(name,"cbc(aes)",strlen("cbc(aes)"));
+ else if(strcmp(encry_src,"serpent-cbc")==0)
+ memcpy(name,"cbc(serpent)",strlen("cbc(serpent)"));
+ else if(strcmp(encry_src,"camellia-cbc")==0)
+ memcpy(name,"cbc(camellia)",strlen("cbc(camellia)"));
+ else if(strcmp(encry_src,"twofish-cbc")==0)
+ memcpy(name,"cbc(twofish)",strlen("cbc(twofish)"));
+ else if(strcmp(encry_src,"aes-ctr-rfc3686")==0)
+ memcpy(name,"rfc3686(ctr(aes))",strlen("rfc3686(ctr(aes))"));
+ else if(strcmp(encry_src,"null")==0)
+ memcpy(name,"ecb(cipher_null)",strlen("ecb(cipher_null)"));
+ else
+ {
+ memcpy(name,"not-supported",strlen("not-supported"));
+ ALOGD("xfrm_encry_algo_parse not supported algorithm--%s\n",encry_src);
+ }
+}
+
+void xfrm_interg_algo_parse(char * interg_src, char *name)
+{
+ if(interg_src == NULL)
+ memcpy(name,"digest_null",strlen("digest_null"));
+ else if(strcmp(interg_src,"hmac-md5")==0)
+ memcpy(name,"hmac(md5)",strlen("hmac(md5)"));
+ else if(strcmp(interg_src,"hmac-sha1")==0)
+ memcpy(name,"hmac(sha1)",strlen("hmac(sha1)"));
+ else if(strcmp(interg_src,"hmac-sha256")==0)
+ memcpy(name,"hmac(sha256)",strlen("hmac(sha256)"));
+ else if(strcmp(interg_src,"hmac-sha384)")==0)
+ memcpy(name,"hmac(sha384)",strlen("hmac(sha384)"));
+ else if(strcmp(interg_src,"hmac-sha512")==0)
+ memcpy(name,"hmac(sha512)",strlen("hmac(sha512)"));
+ else if(strcmp(interg_src,"hmac-rmd160")==0)
+ memcpy(name,"hmac(rmd160)",strlen("hmac(rmd160)"));
+ else if(strcmp(interg_src,"aes-xcbc")==0)
+ memcpy(name,"xcbc(aes)",strlen("xcbc(aes)"));
+ else if(strcmp(interg_src,"cmac(aes)")==0)
+ memcpy(name,"aes-cmac",strlen("aes-cmac"));
+ else if(strcmp(interg_src,"null")==0)
+ memcpy(name,"digest_null",strlen("digest_null"));
+ else
+ {
+ memcpy(name,"not-supported",strlen("not-supported"));
+ ALOGD("xfrm_interg_algo_parse not supported algorithm--%s\n",interg_src);
+ }
+}
+
+
+int xfrm_algo_parse(struct xfrm_algo *alg, char *name, char *key, char *buf, int max)
+{
+ int len;
+ int slen = strlen(key);
+
+ strncpy(alg->alg_name, name, sizeof(alg->alg_name));
+
+ if (slen > 2 && strncmp(key, "0x", 2) == 0) {
+ /* split two chars "0x" from the top */
+ char *p = key + 2;
+ int plen = slen - 2;
+ int i;
+ int j;
+
+ /* Converting hexadecimal numbered string into real key;
+ * Convert each two chars into one char(value). If number
+ * of the length is odd, add zero on the top for rounding.
+ */
+
+ /* calculate length of the converted values(real key) */
+ len = (plen + 1) / 2;
+ if (len > max)
+ {
+ ALOGD("xfrm_algo_parse key(len:%d) makes buffer overflow\n",len);
+ return -1;
+ }
+
+ for (i = - (plen % 2), j = 0; j < len; i += 2, j++) {
+ char vbuf[3];
+ __u8 val;
+
+ vbuf[0] = i >= 0 ? p[i] : '0';
+ vbuf[1] = p[i + 1];
+ vbuf[2] = '\0';
+
+ if (get_u8(&val, vbuf, 16))
+ {
+ ALOGD("xfrm_algo_parse key(len:%s) is invalid\n",key);
+ return -1;
+ }
+ buf[j] = val;
+ }
+ } else {
+ len = slen;
+ if (len > 0) {
+ if (len > max)
+ {
+ ALOGD("xfrm_algo_parse key(len:%d) makes buffer overflow\n",len);
+ return -1;
+ }
+
+ strncpy(buf, key, len);
+ }
+ }
+
+ alg->alg_key_len = len * 8;
+
+ return 0;
+}
+
+__u8 xfrm_dir_parse(char * dir_str)
+{
+ __u8 dir;
+ if(strcmp(dir_str,"out")==0)
+ dir = XFRM_POLICY_OUT;
+ else if(strcmp(dir_str,"in")==0)
+ dir = XFRM_POLICY_IN;
+ else if(strcmp(dir_str,"fwd")==0)
+ dir = XFRM_POLICY_FWD;
+ else
+ dir = XFRM_POLICY_ERROR;
+ return dir;
+}
+
+int xfrm_mode_parse(__u8 *mode, char * mode_str)
+{
+
+
+ if (strcmp(mode_str, "transport") == 0)
+ *mode = XFRM_MODE_TRANSPORT;
+ else if (strcmp(mode_str, "tunnel") == 0)
+ *mode = XFRM_MODE_TUNNEL;
+ else if (strcmp(mode_str, "ro") == 0)
+ *mode = XFRM_MODE_ROUTEOPTIMIZATION;
+ else if (strcmp(mode_str, "in_trigger") == 0)
+ *mode = XFRM_MODE_IN_TRIGGER;
+ else if (strcmp(mode_str, "beet") == 0)
+ *mode = XFRM_MODE_BEET;
+ else
+ return -1;
+
+
+ return 0;
+}
+
+void xfrm_selector_parse(struct xfrm_selector *sel, char * src,char * dst,enum PROTOCOL_TYPE protocol,char * src_port,char * dst_port)
+{
+
+ inet_prefix dst_prefix;
+ inet_prefix src_prefix;
+
+ memset(&dst_prefix, 0, sizeof(dst_prefix));
+ memset(&src_prefix, 0, sizeof(src_prefix));
+
+
+ get_prefix(&src_prefix, src, AF_UNSPEC);
+ memcpy(&sel->saddr, &src_prefix.data, sizeof(sel->saddr));
+ sel->prefixlen_s = src_prefix.bitlen;
+
+ get_prefix(&dst_prefix, dst, AF_UNSPEC);
+ memcpy(&sel->daddr, &dst_prefix.data, sizeof(sel->daddr));
+ sel->prefixlen_d = dst_prefix.bitlen;
+
+ sel->family = dst_prefix.family;
+
+ sel->sport = htons(atoi(src_port));
+ sel->dport = htons(atoi(dst_port));
+ sel->dport_mask = ~((__u16)0);
+ sel->sport_mask = ~((__u16)0);
+
+ sel->user = getpid();
+
+ sel->proto = protocol;
+#ifdef INIT_ENG_BUILD
+ if(sel->family == AF_INET)
+ ALOGD("xfrm_selector_parse family:%u,prefix_d:%u,prefix_s:%u,daddr:0x%x,saddr:0x%x,sel->sport:%d,sel->dport:%d,proto:%u,user:%u\n",sel->family,sel->prefixlen_d,sel->prefixlen_s,sel->daddr.a4,sel->daddr.a4,sel->sport,sel->dport,sel->proto,sel->user);
+ else
+ ALOGD("xfrm_selector_parse family:%u,prefix_d:%u,prefix_s:%u,daddr:0x%x %x %x %x,saddr:0x%x %x %x %x ,sel->sport:%d,sel->dport:%d,proto:%u,user:%u\n",sel->family,sel->prefixlen_d,sel->prefixlen_s,sel->daddr.a6[0],sel->daddr.a6[1],sel->daddr.a6[2],sel->daddr.a6[3],sel->saddr.a6[0],sel->saddr.a6[1],sel->saddr.a6[2],sel->saddr.a6[3],sel->sport,sel->dport,sel->proto,sel->user);
+#endif
+}
+
+
+
diff --git a/src/connectivity/libipsecims/setkey_xfrm_parse.h b/src/connectivity/libipsecims/setkey_xfrm_parse.h
new file mode 100644
index 0000000..0ce4635
--- /dev/null
+++ b/src/connectivity/libipsecims/setkey_xfrm_parse.h
@@ -0,0 +1,32 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <errno.h>
+#include <netdb.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <time.h>
+#include <linux/capability.h>
+#include <linux/ipsec.h>
+#include <sys/capability.h>
+#include <cutils/properties.h>
+#include "utils_xfrm.h"
+
+struct typeent {
+ const char *t_name;
+ int t_type;
+};
+
+
+
+extern int xfrm_xfrmproto_getbyname(char *name);
+extern int xfrm_id_parse(xfrm_address_t *saddr_xfrm, struct xfrm_id *id, __u16 *family,
+ char * src,char * dst,char * ipsec_type);
+extern int xfrm_algo_parse(struct xfrm_algo *alg, char *name, char *key, char *buf, int max);
+extern __u8 xfrm_dir_parse(char * dir_str);
+extern int xfrm_mode_parse(__u8 *mode, char * mode_str);
+extern void xfrm_selector_parse(struct xfrm_selector *sel, char * src,char * dst,enum PROTOCOL_TYPE protocol,char * src_port,char * dst_port);
+extern void xfrm_encry_algo_parse(char * encry_src, char *name);
+extern void xfrm_interg_algo_parse(char * interg_src, char *name);
diff --git a/src/connectivity/libipsecims/utils_xfrm.c b/src/connectivity/libipsecims/utils_xfrm.c
new file mode 100644
index 0000000..178a19b
--- /dev/null
+++ b/src/connectivity/libipsecims/utils_xfrm.c
@@ -0,0 +1,230 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <string.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#include <resolv.h>
+#include <asm/types.h>
+#include <linux/pkt_sched.h>
+#include <time.h>
+#include <sys/time.h>
+#include <errno.h>
+#include "utils_xfrm.h"
+#define LOG_TAG "setkey"
+#include <log/log.h>
+#include <cutils/log.h>
+
+
+int mask2bits(__u32 netmask_xfrm)
+{
+ unsigned bits_xfrm = 0;
+ __u32 mask_xfrm = ntohl(netmask_xfrm);
+ __u32 host_xfrm = ~mask_xfrm;
+
+ /* a valid netmask must be 2^n - 1 */
+ if ((host_xfrm & (host_xfrm + 1)) != 0)
+ return -1;
+
+ for (; mask_xfrm; mask_xfrm <<= 1)
+ ++bits_xfrm;
+ return bits_xfrm;
+}
+
+int get_netmask(unsigned *val_xfrm, const char *arg_xfrm, int base_xfrm)
+{
+ inet_prefix addr_xfrm;
+
+ if (!get_unsigned(val_xfrm, arg_xfrm, base_xfrm))
+ return 0;
+
+ /* try coverting dotted quad to CIDR */
+ if (!get_addr_1(&addr_xfrm, arg_xfrm, AF_INET) && addr_xfrm.family == AF_INET) {
+ int b_xfrm = mask2bits(addr_xfrm.data[0]);
+
+ if (b_xfrm >= 0) {
+ *val_xfrm = b_xfrm;
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+int get_unsigned(unsigned *val_xfrm, const char *arg_xfrm, int base_xfrm)
+{
+ unsigned long res_xfrm = 0;
+ char *ptr_xfrm = NULL;
+
+ if (!arg_xfrm || !*arg_xfrm)
+ return -1;
+ res_xfrm = strtoul(arg_xfrm, &ptr_xfrm, base_xfrm);
+ if (!ptr_xfrm || ptr_xfrm == arg_xfrm || *ptr_xfrm || res_xfrm > UINT_MAX)
+ return -1;
+ *val_xfrm = res_xfrm;
+ return 0;
+}
+
+
+int get_u32(__u32 *val_xfrm, const char *arg_xfrm, int base_xfrm)
+{
+ unsigned long res_xfrm = 0;
+ char *ptr_xfrm = NULL;
+
+ if (!arg_xfrm || !*arg_xfrm)
+ return -1;
+ res_xfrm = strtoul(arg_xfrm, &ptr_xfrm, base_xfrm);
+ if (!ptr_xfrm || ptr_xfrm == arg_xfrm || *ptr_xfrm || res_xfrm > 0xFFFFFFFFUL)
+ return -1;
+ *val_xfrm = res_xfrm;
+ return 0;
+}
+
+
+int get_u8(__u8 *val_xfrm, const char *arg_xfrm, int base_xfrm)
+{
+ unsigned long res_xfrm = 0;
+ char *ptr_xfrm = NULL;
+
+ if (!arg_xfrm || !*arg_xfrm)
+ return -1;
+ res_xfrm = strtoul(arg_xfrm, &ptr_xfrm, base_xfrm);
+ if (!ptr_xfrm || ptr_xfrm == arg_xfrm || *ptr_xfrm || res_xfrm > 0xFF)
+ return -1;
+ *val_xfrm = res_xfrm;
+ return 0;
+}
+
+
+
+/* This uses a non-standard parsing (ie not inet_aton, or inet_pton)
+ * because of legacy choice to parse 10.8 as 10.8.0.0 not 10.0.0.8
+ */
+int get_addr_ipv4(__u8 *ap_xfrm, const char *cp_xfrm)
+{
+ int i_xfrm = 0;
+
+ for (i_xfrm = 0; i_xfrm < 4; i_xfrm++) {
+ unsigned long n_xfrm = 0;
+ char *endp_xfrm = NULL;
+
+ n_xfrm = strtoul(cp_xfrm, &endp_xfrm, 0);
+ if (n_xfrm > 255)
+ return -1; /* bogus network value */
+
+ if (endp_xfrm == cp_xfrm) /* no digits */
+ return -1;
+
+ ap_xfrm[i_xfrm] = n_xfrm;
+
+ if (*endp_xfrm == '\0')
+ break;
+
+ if (i_xfrm == 3 || *endp_xfrm != '.')
+ return -1; /* extra characters */
+ cp_xfrm = endp_xfrm + 1;
+ }
+
+ return 1;
+}
+
+int get_addr_1(inet_prefix *addr_xfrm, const char *name_xfrm, int family)
+{
+ memset(addr_xfrm, 0, sizeof(*addr_xfrm));
+
+ if (strcmp(name_xfrm, "default") == 0 ||
+ strcmp(name_xfrm, "all") == 0 ||
+ strcmp(name_xfrm, "any") == 0) {
+ if (family == AF_DECnet)
+ return -1;
+ addr_xfrm->family = family;
+ addr_xfrm->bytelen = (family == AF_INET6 ? 16 : 4);
+ addr_xfrm->bitlen = -1;
+ return 0;
+ }
+
+ if (strchr(name_xfrm, ':')) {
+ addr_xfrm->family = AF_INET6;
+ if (family != AF_UNSPEC && family != AF_INET6)
+ return -1;
+ if (inet_pton(AF_INET6, name_xfrm, addr_xfrm->data) <= 0)
+ return -1;
+ addr_xfrm->bytelen = 16;
+ addr_xfrm->bitlen = -1;
+ return 0;
+ }
+
+
+ addr_xfrm->family = AF_INET;
+ if (family != AF_UNSPEC && family != AF_INET)
+ return -1;
+
+ if (get_addr_ipv4((__u8 *)addr_xfrm->data, name_xfrm) <= 0)
+ return -1;
+
+ addr_xfrm->bytelen = 4;
+ addr_xfrm->bitlen = -1;
+ return 0;
+}
+
+int get_prefix(inet_prefix *dst_xfrm, char *arg_xfrm, int family)
+{
+ int err = 0 ;
+ unsigned plen = 0;
+ char *slash = NULL;
+
+ memset(dst_xfrm, 0, sizeof(*dst_xfrm));
+
+ if (strcmp(arg_xfrm, "default") == 0 ||
+ strcmp(arg_xfrm, "any") == 0 ||
+ strcmp(arg_xfrm, "all") == 0) {
+ if (family == AF_DECnet)
+ return -1;
+ dst_xfrm->family = family;
+ dst_xfrm->bytelen = 0;
+ dst_xfrm->bitlen = 0;
+ return 0;
+ }
+
+ slash = strchr(arg_xfrm, '/');
+ if (slash)
+ *slash = 0;
+
+ err = get_addr_1(dst_xfrm, arg_xfrm, family);
+ if (err == 0) {
+ switch(dst_xfrm->family) {
+ case AF_INET6:
+ dst_xfrm->bitlen = 128;
+ break;
+ case AF_DECnet:
+ dst_xfrm->bitlen = 16;
+ break;
+ default:
+ case AF_INET:
+ dst_xfrm->bitlen = 32;
+ }
+ if (slash) {
+ if (get_netmask(&plen, slash+1, 0)
+ || plen > dst_xfrm->bitlen) {
+ err = -1;
+ goto done;
+ }
+ dst_xfrm->flags |= PREFIXLEN_SPECIFIED;
+ dst_xfrm->bitlen = plen;
+ }
+ }
+done:
+ if (slash)
+ *slash = '/';
+ return err;
+}
+
+
+
+
+
diff --git a/src/connectivity/libipsecims/utils_xfrm.h b/src/connectivity/libipsecims/utils_xfrm.h
new file mode 100644
index 0000000..60d519a
--- /dev/null
+++ b/src/connectivity/libipsecims/utils_xfrm.h
@@ -0,0 +1,109 @@
+#ifndef __UTILS_XFRM_H__
+#define __UTILS_XFRM_H__ 1
+#include <string.h>
+#include <asm/types.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <linux/if_link.h>
+#include <linux/if_addr.h>
+#include <linux/neighbour.h>
+#include <cutils/properties.h>
+#include <asm/types.h>
+#include <stdlib.h>
+#include <arpa/inet.h>
+#include <linux/xfrm.h>
+
+
+//#define NLMSG_DELETEALL_BUF_SIZE (4096-512)
+#define NLMSG_DELETEALL_BUF_SIZE 8192
+
+/*
+ * Receiving buffer defines:
+ * nlmsg
+ * data = struct xfrm_userpolicy_info
+ * rtattr
+ * data = struct xfrm_user_tmpl[]
+ */
+#define NLMSG_BUF_SIZE 4096
+#define RTA_BUF_SIZE 2048
+#define XFRM_TMPLS_BUF_SIZE 1024
+#define CTX_BUF_SIZE 256
+#define XFRM_ALGO_KEY_BUF_SIZE 512
+
+#undef NLMSG_TAIL
+#define NLMSG_TAIL(nmsg) \
+ ((struct rtattr *) (((char *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
+
+#define XFRM_POLICY_ERROR 255
+enum PROTOCOL_TYPE{
+ PROTOCOL_ICMP=1,
+ PROTOCOL_IPV4=4,
+ PROTOCOL_TCP=6,
+ PROTOCOL_UDP=17,
+ PROTOCOL_IPV6=41,
+ PROTOCOL_GRE=47,
+ PROTOCOL_ESP=50,
+ PROTOCOL_AH=51,
+ PROTOCOL_ICMPV6=58,
+ PROTOCOL_IPCOMP=108,
+ PROTOCOL_L2TP=115
+};
+
+struct rtnl_handle_xfrm
+{
+ int fd;
+ struct sockaddr_nl local;
+ struct sockaddr_nl peer;
+ __u32 seq;
+ __u32 dump;
+};
+
+struct req_handle_xfrm {
+ struct nlmsghdr n;
+ struct xfrm_userpolicy_info xpinfo;
+ char buf[RTA_BUF_SIZE];
+ } ;
+
+typedef struct
+{
+ __u8 family;
+ __u8 bytelen;
+ __s16 bitlen;
+ __u32 flags;
+ __u32 data[8];
+} inet_prefix;
+
+#define PREFIXLEN_SPECIFIED 1
+
+static inline __u32 nl_mgrp_xfrm(__u32 group)
+{
+ if (group > 31 ) {
+ //ALOGD("Use setsockopt for this group %d\n", group);
+ return -1;
+ }
+ return group ? (1 << (group - 1)) : 0;
+}
+
+
+extern int mask2bits(__u32 netmask_xfrm);
+extern int get_netmask(unsigned *val_xfrm, const char *arg_xfrm, int base_xfrm);
+extern int get_unsigned(unsigned *val_xfrm, const char *arg_xfrm, int base_xfrm);
+extern int get_u32(__u32 *val_xfrm, const char *arg_xfrm, int base_xfrm);
+extern int get_u8(__u8 *val_xfrm, const char *arg_xfrm, int base_xfrm);
+extern int get_addr_ipv4(__u8 *ap_xfrm, const char *cp_xfrm);
+extern int get_addr_1(inet_prefix *addr_xfrm, const char *name_xfrm, int family);
+extern int get_prefix(inet_prefix *dst_xfrm, char *arg_xfrm, int family);
+
+
+
+typedef int (*rtnl_filter_t_xfrm)(struct rtnl_handle_xfrm * rth,struct nlmsghdr *n);
+
+extern int xfrm_policy_process_delete_exist( struct rtnl_handle_xfrm * rth,struct nlmsghdr *n, pid_t volte_pid);
+extern int xfrm_state_process_delete_exist( struct rtnl_handle_xfrm * rth,struct nlmsghdr *n, pid_t volte_pid);
+
+extern void rtnl_close_xfrm(struct rtnl_handle_xfrm *rth);
+extern int rtnl_open_byproto_xfrm(struct rtnl_handle_xfrm *rth, unsigned subscriptions,
+ int protocol);
+extern int rtnl_listen_xfrm(struct rtnl_handle_xfrm *rtnl, rtnl_filter_t_xfrm handler);
+extern int rtnl_accept_msg_xfrm(struct rtnl_handle_xfrm * rth,struct nlmsghdr *n);
+#endif /* __UTILS_XFRM_H__ */