[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