[T106][ZXW-22]7520V3SCV2.01.01.02P42U09_VEC_V0.8_AP_VEC origin source commit

Change-Id: Ic6e05d89ecd62fc34f82b23dcf306c93764aec4b
diff --git a/ap/lib/libsoftap/ipsec_api.c b/ap/lib/libsoftap/ipsec_api.c
new file mode 100644
index 0000000..377ac46
--- /dev/null
+++ b/ap/lib/libsoftap/ipsec_api.c
@@ -0,0 +1,646 @@
+#include <stdio.h>

+#include <stdlib.h>

+#include <unistd.h>

+#include <string.h>

+#include <errno.h>

+#include <arpa/inet.h>

+#include <linux/netlink.h>

+#include <linux/socket.h>

+#include <sys/socket.h>

+#include <syslog.h>

+#include <sys/klog.h>

+#include <stdarg.h>

+#include "ipsec_api.h"

+#include <assert.h>

+

+static void LOG_PRINT(int priority, const char* fmt, ...)

+{

+    va_list args = {0};

+	char buff[512];

+	memset(buff, 0x00, sizeof(buff));

+    va_start(args, fmt); 

+	vsnprintf(buff, sizeof(buff), fmt, args);

+	va_end(args);  

+	syslog(priority,"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%s", buff); 

+	printf("%s\n", buff);

+	

+}

+

+//ÓÉÓÚiprouteÖв»´æÔÚ½«¡°udp¡±¡¢¡°tcp¡±×Ô¶¯×ª»»ÎªÏàÓ¦´«Êä²ãЭÒéºÅµÄ¹¦ÄÜ£¬Òò´ËÔÚÅäÖÃipsecʱ£¬Ö±½ÓʹÓô«Êä²ãЭÒéºÅÅäÖÃproto²ÎÊý

+int ipsec_set(int s, void *data, int datalen)

+{

+

+	ipsec_set_msg *set_msg = (ipsec_set_msg *)data;

+	unsigned short client_port, server_port;

+	int spi;

+	char * source_addr, *dest_addr, *auth_key, *crypto_key, *xfrmproto, *mode, *ealg, *alg, *dir;

+	char cmd[512];

+	

+	if(s < 0)

+	{

+		LOG_PRINT(LOG_ALERT,"ipsec_set:socket s is not legal");

+		return -1;		

+	}

+	if (data == NULL)

+	{

+		LOG_PRINT(LOG_ALERT,"ipsec_set:data is not legal");

+		return -1;

+	}

+	

+	if(datalen != sizeof(ipsec_set_msg))

+	{

+		LOG_PRINT(LOG_ALERT,"ipsec_set:The length of msg is not legal");

+		return -1;

+	}

+

+	crypto_key = set_msg->Ckey;

+	xfrmproto = set_msg->Prot;

+	mode = set_msg->Mod;

+	ealg = set_msg->Ealg;

+	alg = set_msg->Alg;

+	dir = set_msg->dir;

+	auth_key = set_msg->Ikey;

+	client_port = set_msg->PortC;

+	server_port = set_msg->PortS;

+	spi = set_msg->Spi;

+	

+	if (1 == set_msg->IsIpv4)

+	{

+		source_addr = set_msg->SrcIpv4;

+		dest_addr = set_msg->DestIpv4;

+	}

+	else

+	{

+		source_addr = set_msg->SrcIpv6;

+		dest_addr = set_msg->DestIpv6;

+	}

+	

+	if(0 == strcmp(alg,"hmac-md5-96"))

+	{

+		memset(alg,0x00,strlen(alg));

+		sprintf(alg,"md5");

+	}

+	else if (0 == strcmp(alg,"hmac-sha-1-96"))

+	{

+		memset(alg,0x00,strlen(alg));

+		sprintf(alg,"sha1");

+	}

+	else

+	{

+		LOG_PRINT(LOG_ALERT,"ipsec_set:ONLY support md5 and sha1 algorithm now, alg %s is not valid",alg);

+		return -1;

+	}

+	

+	if(0 == strcmp(ealg,"aes-cbc"))

+	{

+		memset(ealg,0x00,strlen(ealg));

+		sprintf(ealg,"aes");

+	}

+	else if(0 == strcmp(ealg,"des-ede3-cbc"))

+	{

+		memset(ealg,0x00,strlen(ealg));

+		sprintf(ealg,"des3_ede");

+	}

+	else if(0 == strcmp(ealg,"null"))

+	{

+		memset(ealg,0x00,strlen(ealg));

+		sprintf(ealg,"cipher_null");

+		memset(crypto_key,0x00,strlen(crypto_key));

+		sprintf(crypto_key,"\"\"");

+	}

+	else

+	{

+		LOG_PRINT(LOG_ALERT,"ipsec_set:ONLY support aes-cbc£¬des-ede3-cbc and null three crypto algorithm, the alg %s is not valid", ealg);

+		return -1;

+	}

+	

+	memset(cmd, 0x00, sizeof(cmd)); 

+	if(0 != strcmp(ealg,"cipher_null"))

+	{

+		sprintf(cmd, "ip xfrm state add src %s dst %s proto %s spi 0x%x  auth %s 0x%s enc %s 0x%s mode %s", 

+								source_addr, dest_addr, xfrmproto, spi, alg,auth_key, ealg,crypto_key, mode);

+	}

+	else

+	{

+		sprintf(cmd, "ip xfrm state add src %s dst %s proto %s spi 0x%x  auth %s 0x%s enc %s %s mode %s", 

+								source_addr, dest_addr, xfrmproto, spi, alg,auth_key, ealg,crypto_key, mode);

+	}

+	soft_system(cmd);

+

+	LOG_PRINT(LOG_ALERT,"ipsec_set:%s\n", cmd);

+	

+	memset(cmd, 0x00, sizeof(cmd)); 

+	//ÅäÖÃudpЭÒéipsec²ÎÊý£¬udp´«Êä²ãЭÒéºÅΪ17

+	sprintf(cmd, "ip xfrm policy add dir %s src %s dst %s proto 17 sport %d dport %d ptype main tmpl src %s dst %s proto esp spi %d mode transport",

+		                                dir, source_addr, dest_addr, client_port, server_port, source_addr, dest_addr, spi);

+	soft_system(cmd);

+	LOG_PRINT(LOG_ALERT,"ipsec_set:%s\n", cmd);

+	

+	memset(cmd, 0x00, sizeof(cmd)); 

+	//ÅäÖÃtcpЭÒéipsec²ÎÊý£¬tcp´«Êä²ãЭÒéºÅΪ6

+	sprintf(cmd, "ip xfrm policy add dir %s src %s dst %s proto 6 sport %d dport %d ptype main tmpl src %s dst %s proto esp spi %d mode transport",

+		                                dir, source_addr, dest_addr, client_port, server_port, source_addr, dest_addr, spi);

+	soft_system(cmd);

+	

+	LOG_PRINT(LOG_ALERT,"ipsec_set:%s\n", cmd);

+	

+	

+	return 0;

+}

+

+

+int ipsec_del(int s, void *data, int datalen)

+{

+	ipsec_del_msg * p_del_msg = (ipsec_del_msg *)data;

+	ipsec_del_msg * del_msg = NULL;

+	unsigned short client_port, server_port;

+	int spi, i;

+	char * source_addr, *dest_addr, *auth_key, *crypto_key, *xfrmproto, *mode, *ealg, *alg, *dir;

+	char cmd[512];

+	

+	if(s < 0)

+	{

+		LOG_PRINT(LOG_ALERT,"ipsec_del:socket s is not legal");

+		return -1;		

+	}

+	

+	if (data == NULL)

+	{

+		LOG_PRINT(LOG_ALERT,"ipsec_del:data is not legal");

+		return -1;

+	}

+	

+	if( 0!= datalen%sizeof(ipsec_del_msg))

+	{

+		LOG_PRINT(LOG_ALERT,"ipsec_del:The length of msg is not legal");

+		return -1;

+	}

+	

+

+	for(i = 0;i<datalen/sizeof(ipsec_del_msg);i++)

+	{

+		del_msg = p_del_msg+i;

+

+		crypto_key = del_msg->Ckey;

+		xfrmproto = del_msg->Prot;

+		mode = del_msg->Mod;

+		ealg = del_msg->Ealg;

+		alg = del_msg->Alg;

+		dir = del_msg->dir;

+		auth_key = del_msg->Ikey;

+		client_port = del_msg->PortC;

+		server_port = del_msg->PortS;

+		spi = del_msg->Spi;

+		

+		if (1 == del_msg->IsIpv4)

+		{

+			source_addr = del_msg->SrcIpv4;

+			dest_addr = del_msg->DestIpv4;

+		}

+		else

+		{

+			source_addr = del_msg->SrcIpv6;

+			dest_addr = del_msg->DestIpv6;

+		}

+		

+		memset(cmd, 0x00, sizeof(cmd)); 

+		

+		sprintf(cmd,"ip xfrm state delall spi 0x%x",spi);

+		soft_system(cmd);

+

+		LOG_PRINT(LOG_ALERT,"ipsec_del:%s\n", cmd);

+		

+		memset(cmd, 0x00, sizeof(cmd)); 

+		//ɾ³ýudpЭÒéipsecÅäÖÃ

+		sprintf(cmd, "ip xfrm policy delall dir %s src %s dst %s proto 17 sport %d dport %d",dir, source_addr, dest_addr, client_port, server_port);

+		soft_system(cmd);

+		LOG_PRINT(LOG_ALERT,"ipsec_del:%s\n", cmd);

+		

+		memset(cmd, 0x00, sizeof(cmd)); 

+		//ɾ³ýtcpЭÒéipsecÅäÖÃ

+		sprintf(cmd, "ip xfrm policy delall dir %s src %s dst %s proto 6 sport %d dport %d ",dir, source_addr, dest_addr, client_port, server_port);

+		soft_system(cmd);

+		

+		LOG_PRINT(LOG_ALERT,"ipsec_del:%s\n", cmd);

+	}

+	return 0;

+}

+

+#if 0

+int ipsec_set_sa(int s, void *data, int datalen)

+{

+	

+	ipsec_set_sa_msg * set_sa_msg = (ipsec_set_sa_msg *)data;

+	int spi;

+	char * source_addr, *dest_addr, *auth_key, *crypto_key, *xfrmproto, *mode, *ealg, *alg;

+	char cmd[512];

+	

+	if(s < 0)

+	{

+		LOG_PRINT(LOG_ALERT,"ipsec_set_sa:socket s is not legal");

+		return -1;		

+	}

+	

+	if (data == NULL)

+	{

+		LOG_PRINT(LOG_ALERT,"ipsec_set_sa:data is not legal");

+		return -1;

+	}

+	

+	if(datalen != sizeof(ipsec_set_sa_msg))

+	{

+		LOG_PRINT(LOG_ALERT,"ipsec_set_sa:The length of msg is not legal");

+		return -1;

+	}

+	

+	crypto_key = set_sa_msg->Ckey;

+	xfrmproto = set_sa_msg->XfrmProt;

+	mode = set_sa_msg->Mod;

+	ealg = set_sa_msg->Ealg;

+	alg = set_sa_msg->Alg;

+	auth_key = set_sa_msg->Ikey;

+	spi = set_sa_msg->Spi;

+	

+	if (1 == set_sa_msg->IsIpv4)

+	{

+		source_addr = set_sa_msg->SrcIpv4;

+		dest_addr = set_sa_msg->DestIpv4;

+	}

+	else

+	{

+		source_addr = set_sa_msg->SrcIpv6;

+		dest_addr = set_sa_msg->DestIpv6;

+	}

+	

+	if(0 == strcmp(alg,"hmac-md5-96"))

+	{

+		memset(alg,0x00,sizeof(alg));

+		sprintf(alg,"md5");

+	}

+	else if (0 == strcmp(alg,"hmac-sha-1-96"))

+	{

+		memset(alg,0x00,sizeof(alg));

+		sprintf(alg,"sha1");

+	}

+	else

+	{

+		LOG_PRINT(LOG_ALERT,"ipsec_set_sa:ONLY support md5 and sha1 algorithm now, alg %s is not valid",alg);

+		return -1;

+	}

+	

+	if(0 == strcmp(ealg,"aes-cbc"))

+	{

+		memset(ealg,0x00,sizeof(ealg));

+		sprintf(ealg,"aes");

+	}

+	else if(0 == strcmp(ealg,"des-ede3-cbc"))

+	{

+		memset(ealg,0x00,sizeof(ealg));

+		sprintf(ealg,"des3_ede");

+	}

+	else if(0 == strcmp(ealg,"null"))

+	{

+		memset(ealg,0x00,sizeof(ealg));

+		sprintf(ealg,"cipher_null");

+		memset(crypto_key,0x00,sizeof(crypto_key));

+		sprintf(crypto_key,"\"\"");

+	}

+	else

+	{

+		LOG_PRINT(LOG_ALERT,"ipsec_set_sa:ONLY support aes-cbc£¬des-ede3-cbc and null three crypto algorithm, the alg %s is not valid", ealg);

+		return -1;

+	}

+	

+	memset(cmd, 0x00, sizeof(cmd)); 

+	if(0 != strcmp(ealg,"cipher_null"))

+	{

+		sprintf(cmd, "ip xfrm state add src %s dst %s proto %s spi 0x%x auth %s 0x%s enc %s 0x%s mode %s", 

+								source_addr, dest_addr, xfrmproto, spi, alg,auth_key, ealg,crypto_key, mode);

+	}

+	else

+	{

+		sprintf(cmd, "ip xfrm state add src %s dst %s proto %s spi 0x%x  auth %s 0x%s enc %s %s mode %s", 

+								source_addr, dest_addr, xfrmproto, spi, alg,auth_key, ealg, crypto_key, mode);

+	}

+	system(cmd);

+

+	LOG_PRINT(LOG_ALERT,"ipsec_set_sa:%s\n", cmd);

+	return 0;

+}

+

+

+int ipsec_set_sp(int s, void *data, int datalen)

+{

+	ipsec_set_sp_msg * set_sp_msg = (ipsec_set_sp_msg *)data;

+	unsigned short client_port, server_port;

+	int  proto;

+	char * source_addr, *dest_addr, *dir;

+	char cmd[512], cmd_tcp[512];

+	int offset = 0, offset_tcp = 0;

+

+	if(s < 0)

+	{

+		LOG_PRINT(LOG_ALERT,"ipsec_set_sp:socket s is not legal");

+		return -1;		

+	}

+	

+	if (data == NULL)

+	{

+		LOG_PRINT(LOG_ALERT,"ipsec_set_sp:data is not legal");

+		return -1;

+	}

+	

+	if(datalen != sizeof(ipsec_set_sp_msg))

+	{

+		LOG_PRINT(LOG_ALERT,"ipsec_del_sp:The length of msg is not legal");

+		return -1;

+	}

+	

+	proto = set_sp_msg->Prot;

+	dir = set_sp_msg->dir;

+	client_port = set_sp_msg->PortC;

+	server_port = set_sp_msg->PortS;

+	if (1 == set_sp_msg->IsIpv4)

+	{

+		source_addr = set_sp_msg->SrcIpv4;

+		dest_addr = set_sp_msg->DestIpv4;

+	}

+	else

+	{

+		source_addr = set_sp_msg->SrcIpv6;

+		dest_addr = set_sp_msg->DestIpv6;

+	}

+	

+

+	if( proto < IPSEC_PROTO_BASE || proto > IPSEC_PROTO_MAX)

+	{

+		LOG_PRINT(LOG_ALERT,"ipsec_set_sp:ipsec protocol only support tcp and udp now!\n");

+		return -1;

+	}

+	

+	memset(cmd, 0x00, sizeof(cmd));

+

+	offset += sprintf(cmd + offset, "ip xfrm policy add ");

+	

+	if( 0 != strlen(dir))

+	{

+		offset += sprintf(cmd + offset,"dir %s ", dir);

+	}

+

+	if( 0 != strlen(source_addr))

+	{

+			offset += sprintf(cmd + offset, "src %s ", source_addr);

+	}

+

+	if( 0 != strlen(dest_addr))

+	{

+			offset += sprintf(cmd + offset, "dst %s ", dest_addr);

+	}

+

+	if( (IPSEC_PROTO_UNKOWN == proto) && (client_port || server_port))

+	{

+

+		LOG_PRINT(LOG_ALERT,"ipsec_set_sp:ipsec_del_sp : msg must have protocol messages when port is not equal to zero!\n");

+		return -1;

+		

+	}

+	else if( IPSEC_PROTO_UNKOWN == proto)

+	{

+		system(cmd);

+		LOG_PRINT(LOG_ALERT,"ipsec_set_sp:%s\n", cmd);

+	}

+	else

+	{

+		offset_tcp += sprintf(cmd_tcp + offset_tcp, "%s",cmd);

+		

+		if( proto&IPSEC_PROTO_UDP)

+		{

+			offset += sprintf(cmd + offset, "proto 17 ");

+			if(client_port)

+			{

+				offset += sprintf(cmd + offset,"sport %d ", client_port);

+			}

+			if(server_port)

+			{

+				offset += sprintf(cmd + offset,"dport %d ", server_port);

+			}

+			system(cmd);

+			LOG_PRINT(LOG_ALERT,"ipsec_set_sp:%s\n", cmd);

+		}

+

+		if(proto&IPSEC_PROTO_TCP)

+		{

+			offset_tcp += sprintf(cmd_tcp + offset_tcp, "proto 6 ");

+			if(client_port)

+			{

+				offset_tcp += sprintf(cmd_tcp + offset_tcp,"sport %d ", client_port);

+			}

+			if(server_port)

+			{

+				offset_tcp += sprintf(cmd_tcp + offset_tcp,"dport %d ", server_port);

+			}

+			system(cmd_tcp);

+			LOG_PRINT(LOG_ALERT,"ipsec_set_sp:%s\n", cmd_tcp);

+		}

+	}

+	return 0;

+}

+

+int ipsec_del_sa(int s, void *data, int datalen)

+{

+	ipsec_del_sa_msg * del_sa_msg = (ipsec_del_sa_msg *)data;

+	int spi;

+	char * source_addr, *dest_addr,  *xfrmproto, *mode;

+	int offset = 0;

+	char cmd[512];

+	

+	if(s < 0)

+	{

+		LOG_PRINT(LOG_ALERT,"ipsec_del_sa:socket s is not legal");

+		return -1;		

+	}

+	

+	if (data == NULL)

+	{

+		LOG_PRINT(LOG_ALERT,"ipsec_del_sa:data is not legal");

+		return -1;

+	}

+	

+	if(datalen != sizeof(ipsec_del_sa_msg))

+	{

+		LOG_PRINT(LOG_ALERT,"ipsec_del_sa:The length of msg is not legal");

+		return -1;

+	}

+	

+	xfrmproto = del_sa_msg->XfrmProt;

+	mode = del_sa_msg->Mod;

+	spi = del_sa_msg->Spi;

+	

+	if (1 == del_sa_msg->IsIpv4)

+	{

+		source_addr = del_sa_msg->SrcIpv4;

+		dest_addr = del_sa_msg->DestIpv4;

+	}

+	else

+	{

+		source_addr = del_sa_msg->SrcIpv6;

+		dest_addr = del_sa_msg->DestIpv6;

+	}

+

+

+	memset(cmd, 0x00, sizeof(cmd));

+

+

+	offset += sprintf(cmd + offset, "ip xfrm state delall ");

+

+	if( 0 != strlen(source_addr))

+	{

+		offset += sprintf(cmd + offset, "src %s ",source_addr);

+	}

+

+	if( 0 != strlen(dest_addr))

+	{

+		offset += sprintf(cmd + offset, "dst %s ",dest_addr);

+	}

+

+	if( 0 != strlen(xfrmproto))

+	{

+		offset += sprintf(cmd + offset, "proto %s ", xfrmproto);

+	}

+

+	if( 0 != spi)

+	{

+		offset += sprintf(cmd + offset, "spi 0x%x ",spi);

+	}

+

+	if( 0 != strlen(mode))

+	{

+		offset += sprintf(cmd + offset, "mode %s ", mode);

+	}

+	

+	system(cmd);

+

+	LOG_PRINT(LOG_ALERT,"ipsec_del_sa:%s\n", cmd);

+	

+	return 0;

+

+}

+

+

+int ipsec_del_sp(int s, void *data, int datalen)

+{

+	ipsec_del_sp_msg * del_sp_msg = (ipsec_del_sp_msg *)data;

+	unsigned short client_port, server_port;

+	int  proto;

+	char * source_addr, *dest_addr, *dir;

+	char cmd[512], cmd_tcp[512];

+	int offset = 0, offset_tcp = 0;

+

+	if(s < 0)

+	{

+		LOG_PRINT(LOG_ALERT,"ipsec_del_sp:socket s is not legal");

+		return -1;		

+	}

+	

+	if (data == NULL)

+	{

+		LOG_PRINT(LOG_ALERT,"ipsec_del_sp:data is not legal");

+		return -1;

+	}

+	

+	if(datalen != sizeof(ipsec_del_sp_msg))

+	{

+		LOG_PRINT(LOG_ALERT,"ipsec_del_sp:The length of msg is not legal");

+		return -1;

+	}

+	

+	proto = del_sp_msg->Prot;

+	dir = del_sp_msg->dir;

+	client_port = del_sp_msg->PortC;

+	server_port = del_sp_msg->PortS;

+	if (1 == del_sp_msg->IsIpv4)

+	{

+		source_addr = del_sp_msg->SrcIpv4;

+		dest_addr = del_sp_msg->DestIpv4;

+	}

+	else

+	{

+		source_addr = del_sp_msg->SrcIpv6;

+		dest_addr = del_sp_msg->DestIpv6;

+	}

+	

+

+	if( proto < IPSEC_PROTO_BASE || proto > IPSEC_PROTO_MAX)

+	{

+		LOG_PRINT(LOG_ALERT,"ipsec_del_sp:ipsec protocol only support tcp and udp now!\n");

+		return -1;

+	}

+	

+	memset(cmd, 0x00, sizeof(cmd));

+

+	offset += sprintf(cmd + offset, "ip xfrm policy delall ");

+	

+	if( 0 != strlen(dir))

+	{

+		offset += sprintf(cmd + offset,"dir %s ", dir);

+	}

+

+	if( 0 != strlen(source_addr))

+	{

+			offset += sprintf(cmd + offset, "src %s ", source_addr);

+	}

+

+	if( 0 != strlen(dest_addr))

+	{

+			offset += sprintf(cmd + offset, "dst %s ", dest_addr);

+	}

+

+	if( (IPSEC_PROTO_UNKOWN == proto) && (client_port || server_port))

+	{

+

+		LOG_PRINT(LOG_ALERT,"ipsec_del_sp:ipsec_del_sp : msg must have protocol messages when port is not equal to zero!\n");

+		return -1;

+		

+	}

+	else if( IPSEC_PROTO_UNKOWN == proto)

+	{

+		system(cmd);

+		LOG_PRINT(LOG_ALERT,"ipsec_del_sp:%s\n", cmd);

+	}

+	else

+	{

+		offset_tcp += sprintf(cmd_tcp + offset_tcp, "%s",cmd);

+		

+		if( proto&IPSEC_PROTO_UDP)

+		{

+			offset += sprintf(cmd + offset, "proto 17 ");

+			if(client_port)

+			{

+				offset += sprintf(cmd + offset,"sport %d ", client_port);

+			}

+			if(server_port)

+			{

+				offset += sprintf(cmd + offset,"dport %d ", server_port);

+			}

+			system(cmd);

+			LOG_PRINT(LOG_ALERT,"ipsec_del_sp:%s\n", cmd);

+		}

+

+		if(proto&IPSEC_PROTO_TCP)

+		{

+			offset_tcp += sprintf(cmd_tcp + offset_tcp, "proto 6 ");

+			if(client_port)

+			{

+				offset_tcp += sprintf(cmd_tcp + offset_tcp,"sport %d ", client_port);

+			}

+			if(server_port)

+			{

+				offset_tcp += sprintf(cmd_tcp + offset_tcp,"dport %d ", server_port);

+			}

+			system(cmd_tcp);

+			LOG_PRINT(LOG_ALERT,"ipsec_del_sp:%s\n", cmd_tcp);

+		}

+	}

+	return 0;

+}

+#endif