blob: 377ac46412669a6a34c40960571975c78b2371af [file] [log] [blame]
yuezonghe824eb0c2024-06-27 02:32:26 -07001#include <stdio.h>
2#include <stdlib.h>
3#include <unistd.h>
4#include <string.h>
5#include <errno.h>
6#include <arpa/inet.h>
7#include <linux/netlink.h>
8#include <linux/socket.h>
9#include <sys/socket.h>
10#include <syslog.h>
11#include <sys/klog.h>
12#include <stdarg.h>
13#include "ipsec_api.h"
14#include <assert.h>
15
16static void LOG_PRINT(int priority, const char* fmt, ...)
17{
18 va_list args = {0};
19 char buff[512];
20 memset(buff, 0x00, sizeof(buff));
21 va_start(args, fmt);
22 vsnprintf(buff, sizeof(buff), fmt, args);
23 va_end(args);
24 syslog(priority,"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%s", buff);
25 printf("%s\n", buff);
26
27}
28
29//ÓÉÓÚiprouteÖв»´æÔÚ½«¡°udp¡±¡¢¡°tcp¡±×Ô¶¯×ª»»ÎªÏàÓ¦´«Êä²ãЭÒéºÅµÄ¹¦ÄÜ£¬Òò´ËÔÚÅäÖÃipsecʱ£¬Ö±½ÓʹÓô«Êä²ãЭÒéºÅÅäÖÃproto²ÎÊý
30int ipsec_set(int s, void *data, int datalen)
31{
32
33 ipsec_set_msg *set_msg = (ipsec_set_msg *)data;
34 unsigned short client_port, server_port;
35 int spi;
36 char * source_addr, *dest_addr, *auth_key, *crypto_key, *xfrmproto, *mode, *ealg, *alg, *dir;
37 char cmd[512];
38
39 if(s < 0)
40 {
41 LOG_PRINT(LOG_ALERT,"ipsec_set:socket s is not legal");
42 return -1;
43 }
44 if (data == NULL)
45 {
46 LOG_PRINT(LOG_ALERT,"ipsec_set:data is not legal");
47 return -1;
48 }
49
50 if(datalen != sizeof(ipsec_set_msg))
51 {
52 LOG_PRINT(LOG_ALERT,"ipsec_set:The length of msg is not legal");
53 return -1;
54 }
55
56 crypto_key = set_msg->Ckey;
57 xfrmproto = set_msg->Prot;
58 mode = set_msg->Mod;
59 ealg = set_msg->Ealg;
60 alg = set_msg->Alg;
61 dir = set_msg->dir;
62 auth_key = set_msg->Ikey;
63 client_port = set_msg->PortC;
64 server_port = set_msg->PortS;
65 spi = set_msg->Spi;
66
67 if (1 == set_msg->IsIpv4)
68 {
69 source_addr = set_msg->SrcIpv4;
70 dest_addr = set_msg->DestIpv4;
71 }
72 else
73 {
74 source_addr = set_msg->SrcIpv6;
75 dest_addr = set_msg->DestIpv6;
76 }
77
78 if(0 == strcmp(alg,"hmac-md5-96"))
79 {
80 memset(alg,0x00,strlen(alg));
81 sprintf(alg,"md5");
82 }
83 else if (0 == strcmp(alg,"hmac-sha-1-96"))
84 {
85 memset(alg,0x00,strlen(alg));
86 sprintf(alg,"sha1");
87 }
88 else
89 {
90 LOG_PRINT(LOG_ALERT,"ipsec_set:ONLY support md5 and sha1 algorithm now, alg %s is not valid",alg);
91 return -1;
92 }
93
94 if(0 == strcmp(ealg,"aes-cbc"))
95 {
96 memset(ealg,0x00,strlen(ealg));
97 sprintf(ealg,"aes");
98 }
99 else if(0 == strcmp(ealg,"des-ede3-cbc"))
100 {
101 memset(ealg,0x00,strlen(ealg));
102 sprintf(ealg,"des3_ede");
103 }
104 else if(0 == strcmp(ealg,"null"))
105 {
106 memset(ealg,0x00,strlen(ealg));
107 sprintf(ealg,"cipher_null");
108 memset(crypto_key,0x00,strlen(crypto_key));
109 sprintf(crypto_key,"\"\"");
110 }
111 else
112 {
113 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);
114 return -1;
115 }
116
117 memset(cmd, 0x00, sizeof(cmd));
118 if(0 != strcmp(ealg,"cipher_null"))
119 {
120 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",
121 source_addr, dest_addr, xfrmproto, spi, alg,auth_key, ealg,crypto_key, mode);
122 }
123 else
124 {
125 sprintf(cmd, "ip xfrm state add src %s dst %s proto %s spi 0x%x auth %s 0x%s enc %s %s mode %s",
126 source_addr, dest_addr, xfrmproto, spi, alg,auth_key, ealg,crypto_key, mode);
127 }
128 soft_system(cmd);
129
130 LOG_PRINT(LOG_ALERT,"ipsec_set:%s\n", cmd);
131
132 memset(cmd, 0x00, sizeof(cmd));
133 //ÅäÖÃudpЭÒéipsec²ÎÊý£¬udp´«Êä²ãЭÒéºÅΪ17
134 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",
135 dir, source_addr, dest_addr, client_port, server_port, source_addr, dest_addr, spi);
136 soft_system(cmd);
137 LOG_PRINT(LOG_ALERT,"ipsec_set:%s\n", cmd);
138
139 memset(cmd, 0x00, sizeof(cmd));
140 //ÅäÖÃtcpЭÒéipsec²ÎÊý£¬tcp´«Êä²ãЭÒéºÅΪ6
141 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",
142 dir, source_addr, dest_addr, client_port, server_port, source_addr, dest_addr, spi);
143 soft_system(cmd);
144
145 LOG_PRINT(LOG_ALERT,"ipsec_set:%s\n", cmd);
146
147
148 return 0;
149}
150
151
152int ipsec_del(int s, void *data, int datalen)
153{
154 ipsec_del_msg * p_del_msg = (ipsec_del_msg *)data;
155 ipsec_del_msg * del_msg = NULL;
156 unsigned short client_port, server_port;
157 int spi, i;
158 char * source_addr, *dest_addr, *auth_key, *crypto_key, *xfrmproto, *mode, *ealg, *alg, *dir;
159 char cmd[512];
160
161 if(s < 0)
162 {
163 LOG_PRINT(LOG_ALERT,"ipsec_del:socket s is not legal");
164 return -1;
165 }
166
167 if (data == NULL)
168 {
169 LOG_PRINT(LOG_ALERT,"ipsec_del:data is not legal");
170 return -1;
171 }
172
173 if( 0!= datalen%sizeof(ipsec_del_msg))
174 {
175 LOG_PRINT(LOG_ALERT,"ipsec_del:The length of msg is not legal");
176 return -1;
177 }
178
179
180 for(i = 0;i<datalen/sizeof(ipsec_del_msg);i++)
181 {
182 del_msg = p_del_msg+i;
183
184 crypto_key = del_msg->Ckey;
185 xfrmproto = del_msg->Prot;
186 mode = del_msg->Mod;
187 ealg = del_msg->Ealg;
188 alg = del_msg->Alg;
189 dir = del_msg->dir;
190 auth_key = del_msg->Ikey;
191 client_port = del_msg->PortC;
192 server_port = del_msg->PortS;
193 spi = del_msg->Spi;
194
195 if (1 == del_msg->IsIpv4)
196 {
197 source_addr = del_msg->SrcIpv4;
198 dest_addr = del_msg->DestIpv4;
199 }
200 else
201 {
202 source_addr = del_msg->SrcIpv6;
203 dest_addr = del_msg->DestIpv6;
204 }
205
206 memset(cmd, 0x00, sizeof(cmd));
207
208 sprintf(cmd,"ip xfrm state delall spi 0x%x",spi);
209 soft_system(cmd);
210
211 LOG_PRINT(LOG_ALERT,"ipsec_del:%s\n", cmd);
212
213 memset(cmd, 0x00, sizeof(cmd));
214 //ɾ³ýudpЭÒéipsecÅäÖÃ
215 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);
216 soft_system(cmd);
217 LOG_PRINT(LOG_ALERT,"ipsec_del:%s\n", cmd);
218
219 memset(cmd, 0x00, sizeof(cmd));
220 //ɾ³ýtcpЭÒéipsecÅäÖÃ
221 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);
222 soft_system(cmd);
223
224 LOG_PRINT(LOG_ALERT,"ipsec_del:%s\n", cmd);
225 }
226 return 0;
227}
228
229#if 0
230int ipsec_set_sa(int s, void *data, int datalen)
231{
232
233 ipsec_set_sa_msg * set_sa_msg = (ipsec_set_sa_msg *)data;
234 int spi;
235 char * source_addr, *dest_addr, *auth_key, *crypto_key, *xfrmproto, *mode, *ealg, *alg;
236 char cmd[512];
237
238 if(s < 0)
239 {
240 LOG_PRINT(LOG_ALERT,"ipsec_set_sa:socket s is not legal");
241 return -1;
242 }
243
244 if (data == NULL)
245 {
246 LOG_PRINT(LOG_ALERT,"ipsec_set_sa:data is not legal");
247 return -1;
248 }
249
250 if(datalen != sizeof(ipsec_set_sa_msg))
251 {
252 LOG_PRINT(LOG_ALERT,"ipsec_set_sa:The length of msg is not legal");
253 return -1;
254 }
255
256 crypto_key = set_sa_msg->Ckey;
257 xfrmproto = set_sa_msg->XfrmProt;
258 mode = set_sa_msg->Mod;
259 ealg = set_sa_msg->Ealg;
260 alg = set_sa_msg->Alg;
261 auth_key = set_sa_msg->Ikey;
262 spi = set_sa_msg->Spi;
263
264 if (1 == set_sa_msg->IsIpv4)
265 {
266 source_addr = set_sa_msg->SrcIpv4;
267 dest_addr = set_sa_msg->DestIpv4;
268 }
269 else
270 {
271 source_addr = set_sa_msg->SrcIpv6;
272 dest_addr = set_sa_msg->DestIpv6;
273 }
274
275 if(0 == strcmp(alg,"hmac-md5-96"))
276 {
277 memset(alg,0x00,sizeof(alg));
278 sprintf(alg,"md5");
279 }
280 else if (0 == strcmp(alg,"hmac-sha-1-96"))
281 {
282 memset(alg,0x00,sizeof(alg));
283 sprintf(alg,"sha1");
284 }
285 else
286 {
287 LOG_PRINT(LOG_ALERT,"ipsec_set_sa:ONLY support md5 and sha1 algorithm now, alg %s is not valid",alg);
288 return -1;
289 }
290
291 if(0 == strcmp(ealg,"aes-cbc"))
292 {
293 memset(ealg,0x00,sizeof(ealg));
294 sprintf(ealg,"aes");
295 }
296 else if(0 == strcmp(ealg,"des-ede3-cbc"))
297 {
298 memset(ealg,0x00,sizeof(ealg));
299 sprintf(ealg,"des3_ede");
300 }
301 else if(0 == strcmp(ealg,"null"))
302 {
303 memset(ealg,0x00,sizeof(ealg));
304 sprintf(ealg,"cipher_null");
305 memset(crypto_key,0x00,sizeof(crypto_key));
306 sprintf(crypto_key,"\"\"");
307 }
308 else
309 {
310 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);
311 return -1;
312 }
313
314 memset(cmd, 0x00, sizeof(cmd));
315 if(0 != strcmp(ealg,"cipher_null"))
316 {
317 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",
318 source_addr, dest_addr, xfrmproto, spi, alg,auth_key, ealg,crypto_key, mode);
319 }
320 else
321 {
322 sprintf(cmd, "ip xfrm state add src %s dst %s proto %s spi 0x%x auth %s 0x%s enc %s %s mode %s",
323 source_addr, dest_addr, xfrmproto, spi, alg,auth_key, ealg, crypto_key, mode);
324 }
325 system(cmd);
326
327 LOG_PRINT(LOG_ALERT,"ipsec_set_sa:%s\n", cmd);
328 return 0;
329}
330
331
332int ipsec_set_sp(int s, void *data, int datalen)
333{
334 ipsec_set_sp_msg * set_sp_msg = (ipsec_set_sp_msg *)data;
335 unsigned short client_port, server_port;
336 int proto;
337 char * source_addr, *dest_addr, *dir;
338 char cmd[512], cmd_tcp[512];
339 int offset = 0, offset_tcp = 0;
340
341 if(s < 0)
342 {
343 LOG_PRINT(LOG_ALERT,"ipsec_set_sp:socket s is not legal");
344 return -1;
345 }
346
347 if (data == NULL)
348 {
349 LOG_PRINT(LOG_ALERT,"ipsec_set_sp:data is not legal");
350 return -1;
351 }
352
353 if(datalen != sizeof(ipsec_set_sp_msg))
354 {
355 LOG_PRINT(LOG_ALERT,"ipsec_del_sp:The length of msg is not legal");
356 return -1;
357 }
358
359 proto = set_sp_msg->Prot;
360 dir = set_sp_msg->dir;
361 client_port = set_sp_msg->PortC;
362 server_port = set_sp_msg->PortS;
363 if (1 == set_sp_msg->IsIpv4)
364 {
365 source_addr = set_sp_msg->SrcIpv4;
366 dest_addr = set_sp_msg->DestIpv4;
367 }
368 else
369 {
370 source_addr = set_sp_msg->SrcIpv6;
371 dest_addr = set_sp_msg->DestIpv6;
372 }
373
374
375 if( proto < IPSEC_PROTO_BASE || proto > IPSEC_PROTO_MAX)
376 {
377 LOG_PRINT(LOG_ALERT,"ipsec_set_sp:ipsec protocol only support tcp and udp now!\n");
378 return -1;
379 }
380
381 memset(cmd, 0x00, sizeof(cmd));
382
383 offset += sprintf(cmd + offset, "ip xfrm policy add ");
384
385 if( 0 != strlen(dir))
386 {
387 offset += sprintf(cmd + offset,"dir %s ", dir);
388 }
389
390 if( 0 != strlen(source_addr))
391 {
392 offset += sprintf(cmd + offset, "src %s ", source_addr);
393 }
394
395 if( 0 != strlen(dest_addr))
396 {
397 offset += sprintf(cmd + offset, "dst %s ", dest_addr);
398 }
399
400 if( (IPSEC_PROTO_UNKOWN == proto) && (client_port || server_port))
401 {
402
403 LOG_PRINT(LOG_ALERT,"ipsec_set_sp:ipsec_del_sp : msg must have protocol messages when port is not equal to zero!\n");
404 return -1;
405
406 }
407 else if( IPSEC_PROTO_UNKOWN == proto)
408 {
409 system(cmd);
410 LOG_PRINT(LOG_ALERT,"ipsec_set_sp:%s\n", cmd);
411 }
412 else
413 {
414 offset_tcp += sprintf(cmd_tcp + offset_tcp, "%s",cmd);
415
416 if( proto&IPSEC_PROTO_UDP)
417 {
418 offset += sprintf(cmd + offset, "proto 17 ");
419 if(client_port)
420 {
421 offset += sprintf(cmd + offset,"sport %d ", client_port);
422 }
423 if(server_port)
424 {
425 offset += sprintf(cmd + offset,"dport %d ", server_port);
426 }
427 system(cmd);
428 LOG_PRINT(LOG_ALERT,"ipsec_set_sp:%s\n", cmd);
429 }
430
431 if(proto&IPSEC_PROTO_TCP)
432 {
433 offset_tcp += sprintf(cmd_tcp + offset_tcp, "proto 6 ");
434 if(client_port)
435 {
436 offset_tcp += sprintf(cmd_tcp + offset_tcp,"sport %d ", client_port);
437 }
438 if(server_port)
439 {
440 offset_tcp += sprintf(cmd_tcp + offset_tcp,"dport %d ", server_port);
441 }
442 system(cmd_tcp);
443 LOG_PRINT(LOG_ALERT,"ipsec_set_sp:%s\n", cmd_tcp);
444 }
445 }
446 return 0;
447}
448
449int ipsec_del_sa(int s, void *data, int datalen)
450{
451 ipsec_del_sa_msg * del_sa_msg = (ipsec_del_sa_msg *)data;
452 int spi;
453 char * source_addr, *dest_addr, *xfrmproto, *mode;
454 int offset = 0;
455 char cmd[512];
456
457 if(s < 0)
458 {
459 LOG_PRINT(LOG_ALERT,"ipsec_del_sa:socket s is not legal");
460 return -1;
461 }
462
463 if (data == NULL)
464 {
465 LOG_PRINT(LOG_ALERT,"ipsec_del_sa:data is not legal");
466 return -1;
467 }
468
469 if(datalen != sizeof(ipsec_del_sa_msg))
470 {
471 LOG_PRINT(LOG_ALERT,"ipsec_del_sa:The length of msg is not legal");
472 return -1;
473 }
474
475 xfrmproto = del_sa_msg->XfrmProt;
476 mode = del_sa_msg->Mod;
477 spi = del_sa_msg->Spi;
478
479 if (1 == del_sa_msg->IsIpv4)
480 {
481 source_addr = del_sa_msg->SrcIpv4;
482 dest_addr = del_sa_msg->DestIpv4;
483 }
484 else
485 {
486 source_addr = del_sa_msg->SrcIpv6;
487 dest_addr = del_sa_msg->DestIpv6;
488 }
489
490
491 memset(cmd, 0x00, sizeof(cmd));
492
493
494 offset += sprintf(cmd + offset, "ip xfrm state delall ");
495
496 if( 0 != strlen(source_addr))
497 {
498 offset += sprintf(cmd + offset, "src %s ",source_addr);
499 }
500
501 if( 0 != strlen(dest_addr))
502 {
503 offset += sprintf(cmd + offset, "dst %s ",dest_addr);
504 }
505
506 if( 0 != strlen(xfrmproto))
507 {
508 offset += sprintf(cmd + offset, "proto %s ", xfrmproto);
509 }
510
511 if( 0 != spi)
512 {
513 offset += sprintf(cmd + offset, "spi 0x%x ",spi);
514 }
515
516 if( 0 != strlen(mode))
517 {
518 offset += sprintf(cmd + offset, "mode %s ", mode);
519 }
520
521 system(cmd);
522
523 LOG_PRINT(LOG_ALERT,"ipsec_del_sa:%s\n", cmd);
524
525 return 0;
526
527}
528
529
530int ipsec_del_sp(int s, void *data, int datalen)
531{
532 ipsec_del_sp_msg * del_sp_msg = (ipsec_del_sp_msg *)data;
533 unsigned short client_port, server_port;
534 int proto;
535 char * source_addr, *dest_addr, *dir;
536 char cmd[512], cmd_tcp[512];
537 int offset = 0, offset_tcp = 0;
538
539 if(s < 0)
540 {
541 LOG_PRINT(LOG_ALERT,"ipsec_del_sp:socket s is not legal");
542 return -1;
543 }
544
545 if (data == NULL)
546 {
547 LOG_PRINT(LOG_ALERT,"ipsec_del_sp:data is not legal");
548 return -1;
549 }
550
551 if(datalen != sizeof(ipsec_del_sp_msg))
552 {
553 LOG_PRINT(LOG_ALERT,"ipsec_del_sp:The length of msg is not legal");
554 return -1;
555 }
556
557 proto = del_sp_msg->Prot;
558 dir = del_sp_msg->dir;
559 client_port = del_sp_msg->PortC;
560 server_port = del_sp_msg->PortS;
561 if (1 == del_sp_msg->IsIpv4)
562 {
563 source_addr = del_sp_msg->SrcIpv4;
564 dest_addr = del_sp_msg->DestIpv4;
565 }
566 else
567 {
568 source_addr = del_sp_msg->SrcIpv6;
569 dest_addr = del_sp_msg->DestIpv6;
570 }
571
572
573 if( proto < IPSEC_PROTO_BASE || proto > IPSEC_PROTO_MAX)
574 {
575 LOG_PRINT(LOG_ALERT,"ipsec_del_sp:ipsec protocol only support tcp and udp now!\n");
576 return -1;
577 }
578
579 memset(cmd, 0x00, sizeof(cmd));
580
581 offset += sprintf(cmd + offset, "ip xfrm policy delall ");
582
583 if( 0 != strlen(dir))
584 {
585 offset += sprintf(cmd + offset,"dir %s ", dir);
586 }
587
588 if( 0 != strlen(source_addr))
589 {
590 offset += sprintf(cmd + offset, "src %s ", source_addr);
591 }
592
593 if( 0 != strlen(dest_addr))
594 {
595 offset += sprintf(cmd + offset, "dst %s ", dest_addr);
596 }
597
598 if( (IPSEC_PROTO_UNKOWN == proto) && (client_port || server_port))
599 {
600
601 LOG_PRINT(LOG_ALERT,"ipsec_del_sp:ipsec_del_sp : msg must have protocol messages when port is not equal to zero!\n");
602 return -1;
603
604 }
605 else if( IPSEC_PROTO_UNKOWN == proto)
606 {
607 system(cmd);
608 LOG_PRINT(LOG_ALERT,"ipsec_del_sp:%s\n", cmd);
609 }
610 else
611 {
612 offset_tcp += sprintf(cmd_tcp + offset_tcp, "%s",cmd);
613
614 if( proto&IPSEC_PROTO_UDP)
615 {
616 offset += sprintf(cmd + offset, "proto 17 ");
617 if(client_port)
618 {
619 offset += sprintf(cmd + offset,"sport %d ", client_port);
620 }
621 if(server_port)
622 {
623 offset += sprintf(cmd + offset,"dport %d ", server_port);
624 }
625 system(cmd);
626 LOG_PRINT(LOG_ALERT,"ipsec_del_sp:%s\n", cmd);
627 }
628
629 if(proto&IPSEC_PROTO_TCP)
630 {
631 offset_tcp += sprintf(cmd_tcp + offset_tcp, "proto 6 ");
632 if(client_port)
633 {
634 offset_tcp += sprintf(cmd_tcp + offset_tcp,"sport %d ", client_port);
635 }
636 if(server_port)
637 {
638 offset_tcp += sprintf(cmd_tcp + offset_tcp,"dport %d ", server_port);
639 }
640 system(cmd_tcp);
641 LOG_PRINT(LOG_ALERT,"ipsec_del_sp:%s\n", cmd_tcp);
642 }
643 }
644 return 0;
645}
646#endif