ims_ipsec_pcscf: fixed possible use of uninitialized value in ipsec_forward()
[sip-router] / src / modules / ims_ipsec_pcscf / ipsec.c
1 /*
2  * IMS IPSEC PCSCF module
3  *
4  * Copyright (C) 2018 Alexander Yosifov
5  * Copyright (C) 2018 Tsvetomir Dimitrov
6  *
7  * This file is part of Kamailio, a free SIP server.
8  *
9  * Kamailio is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version
13  *
14  * Kamailio is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22  *
23  */
24
25 #include "ipsec.h"
26
27 #include "../../core/dprint.h"
28 #include "../../core/mem/pkg.h"
29 #include "../../core/ip_addr.h"
30
31 #include <errno.h>
32 #include <arpa/inet.h>
33 #include <libmnl/libmnl.h>
34 #include <linux/xfrm.h>
35 #include <time.h>
36 //#include <stdio.h>
37 //#include <string.h>
38
39
40 #define XFRM_TMPLS_BUF_SIZE 1024
41 #define NLMSG_BUF_SIZE 4096
42 #define NLMSG_DELETEALL_BUF_SIZE 8192
43
44
45 extern int xfrm_user_selector;
46 extern int spi_id_start;
47 extern int spi_id_range;
48
49 struct xfrm_buffer {
50     char buf[NLMSG_DELETEALL_BUF_SIZE];
51     int offset;
52 };
53
54
55 //
56 // This file contains all Linux specific IPSec code.
57 //
58
59 struct mnl_socket* init_mnl_socket()
60 {
61     struct mnl_socket*  mnl_socket = mnl_socket_open(NETLINK_XFRM);
62     if(NULL == mnl_socket) {
63         LM_ERR("Error opening a MNL socket\n");
64         return NULL;
65     }
66
67     if(mnl_socket_bind(mnl_socket, 0, MNL_SOCKET_AUTOPID) < 0) {
68         LM_ERR("Error binding a MNL socket\n");
69         return NULL;
70     }
71
72     return mnl_socket;
73 }
74
75 void close_mnl_socket(struct mnl_socket* sock)
76 {
77     if(mnl_socket_close(sock) != 0) {
78         LM_WARN("Error closing netlink socket\n");
79     }
80 }
81
82 static void string_to_key(char* dst, const str key_string)
83 {
84     int i = 0;
85     char *pos = key_string.s;
86
87     for (i = 0; i < key_string.len/2; i++) {
88         sscanf(pos, "%2hhx", &dst[i]);
89         pos += 2;
90     }
91 }
92
93 // Converts the protocol enum used in Kamailio to the constants used in Linux
94 unsigned short kamailio_to_linux_proto(const unsigned short kamailio_proto)
95 {
96     switch(kamailio_proto) {
97         case PROTO_UDP:
98             return IPPROTO_UDP;
99         case PROTO_TCP:
100             return IPPROTO_TCP;
101         case PROTO_NONE:
102         case PROTO_TLS:
103         case PROTO_SCTP:
104             case PROTO_WS:
105         case PROTO_WSS:
106         case PROTO_OTHER:
107         default:
108             return IPPROTO_MAX;
109     };
110 }
111
112 int add_sa(struct mnl_socket* nl_sock, unsigned short proto, const struct ip_addr *src_addr_param, const struct ip_addr *dest_addr_param, int s_port, int d_port, int long id, str ck, str ik, str r_alg)
113 {
114     char l_msg_buf[MNL_SOCKET_BUFFER_SIZE];
115     char l_auth_algo_buf[XFRM_TMPLS_BUF_SIZE];
116     char l_enc_algo_buf[XFRM_TMPLS_BUF_SIZE];
117     struct nlmsghdr* l_nlh = NULL;
118     struct xfrm_usersa_info* l_xsainfo = NULL;
119
120     struct xfrm_algo* l_auth_algo = NULL;
121     struct xfrm_algo* l_enc_algo  = NULL;
122
123
124     memset(l_msg_buf, 0, sizeof(l_msg_buf));
125     memset(l_auth_algo_buf, 0, sizeof(l_auth_algo_buf));
126     memset(l_enc_algo_buf, 0, sizeof(l_enc_algo_buf));
127
128     unsigned sel_proto = 0;
129     if((sel_proto = kamailio_to_linux_proto(proto)) == IPPROTO_MAX) {
130         LM_ERR("Invalid port was passed to the function: %d\n", proto);
131         return -1;
132     }
133
134     // nlmsghdr initialization
135     l_nlh = mnl_nlmsg_put_header(l_msg_buf);
136     l_nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
137     l_nlh->nlmsg_type = XFRM_MSG_NEWSA;
138     l_nlh->nlmsg_seq = time(NULL);
139     l_nlh->nlmsg_pid = id;
140
141     // add Security association
142     l_xsainfo = (struct xfrm_usersa_info*)mnl_nlmsg_put_extra_header(l_nlh, sizeof(struct xfrm_usersa_info));
143     l_xsainfo->sel.family       = dest_addr_param->af;
144     if(dest_addr_param->af == AF_INET6) {
145         memcpy(l_xsainfo->sel.daddr.a6, dest_addr_param->u.addr32, sizeof(l_xsainfo->sel.daddr.a6));
146         memcpy(l_xsainfo->sel.saddr.a6, src_addr_param->u.addr32, sizeof(l_xsainfo->sel.saddr.a6));
147         l_xsainfo->sel.prefixlen_d  = 128;
148         l_xsainfo->sel.prefixlen_s  = 128;
149     }
150     else {
151         l_xsainfo->sel.daddr.a4     = dest_addr_param->u.addr32[0];
152         l_xsainfo->sel.saddr.a4     = src_addr_param->u.addr32[0];
153         l_xsainfo->sel.prefixlen_d  = 32;
154         l_xsainfo->sel.prefixlen_s  = 32;
155     }
156     l_xsainfo->sel.dport        = htons(d_port);
157     l_xsainfo->sel.dport_mask   = 0xFFFF;
158     l_xsainfo->sel.sport        = htons(s_port);
159     l_xsainfo->sel.sport_mask   = 0xFFFF;
160     //l_xsainfo->sel.proto        = sel_proto;
161     l_xsainfo->sel.user         = htonl(xfrm_user_selector);
162
163     if(dest_addr_param->af == AF_INET6) {
164         memcpy(l_xsainfo->id.daddr.a6, dest_addr_param->u.addr32, sizeof(l_xsainfo->id.daddr.a6));
165         memcpy(l_xsainfo->saddr.a6, src_addr_param->u.addr32, sizeof(l_xsainfo->saddr.a6));
166     }
167     else {
168         l_xsainfo->id.daddr.a4      = dest_addr_param->u.addr32[0];
169         l_xsainfo->saddr.a4         = src_addr_param->u.addr32[0];
170     }
171     l_xsainfo->id.spi           = htonl(id);
172     l_xsainfo->id.proto         = IPPROTO_ESP;
173
174     l_xsainfo->lft.soft_byte_limit      = XFRM_INF;
175     l_xsainfo->lft.hard_byte_limit      = XFRM_INF;
176     l_xsainfo->lft.soft_packet_limit    = XFRM_INF;
177     l_xsainfo->lft.hard_packet_limit    = XFRM_INF;
178     l_xsainfo->reqid                    = id;
179     l_xsainfo->family                   = dest_addr_param->af;
180     l_xsainfo->mode                     = XFRM_MODE_TRANSPORT;
181     l_xsainfo->replay_window            = 32;
182     //l_xsainfo->flags                    = XFRM_STATE_NOECN;
183
184     // Add authentication algorithm for this SA
185
186     // The cast below is performed because alg_key from struct xfrm_algo is char[0]
187     // The point is to provide a continuous chunk of memory with the key in it
188     l_auth_algo = (struct xfrm_algo *)l_auth_algo_buf;
189
190     // Set the proper algorithm by r_alg str
191     if(strncasecmp(r_alg.s, "hmac-md5-96", r_alg.len) == 0) {
192         strcpy(l_auth_algo->alg_name,"md5");
193     }
194     else if(strncasecmp(r_alg.s, "hmac-sha1-96", r_alg.len) == 0) {
195         strcpy(l_auth_algo->alg_name,"sha1");
196     } else {
197         // set default algorithm to sha1
198         strcpy(l_auth_algo->alg_name,"sha1");
199     }
200
201     l_auth_algo->alg_key_len = ik.len * 4;
202     string_to_key(l_auth_algo->alg_key, ik);
203
204     mnl_attr_put(l_nlh, XFRMA_ALG_AUTH, sizeof(struct xfrm_algo) + l_auth_algo->alg_key_len, l_auth_algo);
205
206     // add encription algorithm for this SA
207     l_enc_algo = (struct xfrm_algo *)l_enc_algo_buf;
208     strcpy(l_enc_algo->alg_name,"cipher_null");
209
210     mnl_attr_put(l_nlh, XFRMA_ALG_CRYPT, sizeof(struct xfrm_algo) + l_enc_algo->alg_key_len, l_enc_algo);
211
212     // send it to Netlink socket
213     if(mnl_socket_sendto(nl_sock, l_nlh, l_nlh->nlmsg_len) < 0)
214     {
215         LM_ERR("Failed to send Netlink message for SA creation, error: %s\n", strerror(errno));
216         return -3;
217     }
218
219     return 0;
220 }
221
222
223 int remove_sa(struct mnl_socket* nl_sock, str src_addr_param, str dest_addr_param, int s_port, int d_port, int long id)
224 {
225     char* src_addr = NULL;
226     char* dest_addr = NULL;
227
228     // convert input IP addresses to char*
229     if((src_addr = pkg_malloc(src_addr_param.len+1)) == NULL) {
230         LM_ERR("Error allocating memory for src addr during SA removal\n");
231         return -1;
232     }
233
234     if((dest_addr = pkg_malloc(dest_addr_param.len+1)) == NULL) {
235         pkg_free(src_addr);
236         LM_ERR("Error allocating memory for dest addr during SA removal\n");
237         return -2;
238     }
239
240     memset(src_addr, 0, src_addr_param.len+1);
241     memset(dest_addr, 0, dest_addr_param.len+1);
242
243     memcpy(src_addr, src_addr_param.s, src_addr_param.len);
244     memcpy(dest_addr, dest_addr_param.s, dest_addr_param.len);
245
246
247     struct {
248         struct nlmsghdr n;
249         struct xfrm_usersa_id   xsid;
250         char buf[XFRM_TMPLS_BUF_SIZE];
251
252     } req = {
253         .n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xsid)),
254         .n.nlmsg_flags = NLM_F_REQUEST,
255         .n.nlmsg_type = XFRM_MSG_DELSA,
256         .xsid.spi = htonl(id),
257         .xsid.family = AF_INET,
258         .xsid.proto = IPPROTO_ESP,
259         .xsid.daddr.a4 = inet_addr(dest_addr)
260     };
261
262     // SADDR
263     xfrm_address_t saddr;
264     memset(&saddr, 0, sizeof(saddr));
265     saddr.a4 = inet_addr(src_addr);
266
267     mnl_attr_put(&req.n, XFRMA_SRCADDR, sizeof(saddr), (void *)&saddr);
268
269     if(mnl_socket_sendto(nl_sock, &req.n, req.n.nlmsg_len) < 0)
270     {
271         LM_ERR("Failed to send Netlink message, error: %s\n", strerror(errno));
272         pkg_free(src_addr);
273         pkg_free(dest_addr);
274         return -1;
275     }
276
277     pkg_free(src_addr);
278     pkg_free(dest_addr);
279
280     return 0;
281 }
282
283
284 int add_policy(struct mnl_socket* mnl_socket, unsigned short proto, const struct ip_addr *src_addr_param, const struct ip_addr *dest_addr_param, int src_port, int dst_port, int long p_id, enum ipsec_policy_direction dir)
285 {
286     char                            l_msg_buf[MNL_SOCKET_BUFFER_SIZE];
287     char                            l_tmpls_buf[XFRM_TMPLS_BUF_SIZE];
288     struct nlmsghdr*                l_nlh;
289     struct xfrm_userpolicy_info*    l_xpinfo;
290
291     unsigned sel_proto = 0;
292     if((sel_proto = kamailio_to_linux_proto(proto)) == IPPROTO_MAX) {
293         LM_ERR("Invalid port was passed to the function: %d\n", proto);
294         return -1;
295     }
296
297     memset(l_msg_buf, 0, sizeof(l_msg_buf));
298     memset(l_tmpls_buf, 0, sizeof(l_tmpls_buf));
299
300     // nlmsghdr initialization
301     l_nlh = mnl_nlmsg_put_header(l_msg_buf);
302     l_nlh->nlmsg_flags  = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
303     l_nlh->nlmsg_type   = XFRM_MSG_NEWPOLICY;
304     l_nlh->nlmsg_seq    = time(NULL);
305     l_nlh->nlmsg_pid    = p_id;
306
307     // add OUT policy
308     l_xpinfo = (struct xfrm_userpolicy_info*)mnl_nlmsg_put_extra_header(l_nlh, sizeof(struct xfrm_userpolicy_info));
309     l_xpinfo->sel.family        = dest_addr_param->af;
310     if(dest_addr_param->af == AF_INET6) {
311         memcpy(l_xpinfo->sel.daddr.a6, dest_addr_param->u.addr32, sizeof(l_xpinfo->sel.daddr.a6));
312         memcpy(l_xpinfo->sel.saddr.a6, src_addr_param->u.addr32, sizeof(l_xpinfo->sel.saddr.a6));
313         l_xpinfo->sel.prefixlen_d  = 128;
314         l_xpinfo->sel.prefixlen_s  = 128;
315     }
316     else {
317         l_xpinfo->sel.daddr.a4     = dest_addr_param->u.addr32[0];
318         l_xpinfo->sel.saddr.a4     = src_addr_param->u.addr32[0];
319         l_xpinfo->sel.prefixlen_d  = 32;
320         l_xpinfo->sel.prefixlen_s  = 32;
321     }
322     l_xpinfo->sel.dport         = htons(dst_port);
323     l_xpinfo->sel.dport_mask    = 0xFFFF;
324     l_xpinfo->sel.sport         = htons(src_port);
325     l_xpinfo->sel.sport_mask    = 0xFFFF;
326     //l_xpinfo->sel.proto         = sel_proto;
327     l_xpinfo->sel.user          = htonl(xfrm_user_selector);
328
329     l_xpinfo->lft.soft_byte_limit   = XFRM_INF;
330     l_xpinfo->lft.hard_byte_limit   = XFRM_INF;
331     l_xpinfo->lft.soft_packet_limit = XFRM_INF;
332     l_xpinfo->lft.hard_packet_limit = XFRM_INF;
333     l_xpinfo->priority              = 2080;
334     l_xpinfo->action                = XFRM_POLICY_ALLOW;
335     l_xpinfo->share                 = XFRM_SHARE_ANY;
336
337     if (dir == IPSEC_POLICY_DIRECTION_IN) {
338         l_xpinfo->dir               = XFRM_POLICY_IN;
339     }
340     else if(dir == IPSEC_POLICY_DIRECTION_OUT) {
341         l_xpinfo->dir               = XFRM_POLICY_OUT;
342     }
343     else {
344         LM_ERR("Invalid direction parameter passed to add_policy: %d\n", dir);
345
346         return -3;
347     }
348
349     // xfrm_user_tmpl initialization
350     struct xfrm_user_tmpl* l_tmpl = (struct xfrm_user_tmpl*)l_tmpls_buf;
351     l_tmpl->id.proto    = IPPROTO_ESP;
352     l_tmpl->family      = dest_addr_param->af;
353     if(dest_addr_param->af == AF_INET6) {
354         memcpy(l_tmpl->id.daddr.a6, dest_addr_param->u.addr32, sizeof(l_tmpl->id.daddr.a6));
355         memcpy(l_tmpl->saddr.a6, src_addr_param->u.addr32, sizeof(l_tmpl->saddr.a6));
356     }
357     else {
358         l_tmpl->id.daddr.a4        = dest_addr_param->u.addr32[0];
359         l_tmpl->saddr.a4           = src_addr_param->u.addr32[0];
360     }
361     l_tmpl->reqid       = p_id;
362     l_tmpl->mode        = XFRM_MODE_TRANSPORT;
363     l_tmpl->aalgos      = (~(__u32)0);
364     l_tmpl->ealgos      = (~(__u32)0);
365     l_tmpl->calgos      = (~(__u32)0);
366
367     mnl_attr_put(l_nlh, XFRMA_TMPL, sizeof(struct xfrm_user_tmpl), l_tmpl);
368
369     if(mnl_socket_sendto(mnl_socket, l_nlh, l_nlh->nlmsg_len) < 0)
370     {
371         LM_ERR("Failed to send Netlink message, error: %s\n", strerror(errno));
372         return -4;
373     }
374
375     return 0;
376 }
377
378 int remove_policy(struct mnl_socket* mnl_socket, unsigned short proto, str src_addr_param, str dest_addr_param, int src_port, int dst_port, int long p_id, enum ipsec_policy_direction dir)
379 {
380     unsigned sel_proto = 0;
381     if((sel_proto = kamailio_to_linux_proto(proto)) == IPPROTO_MAX) {
382         LM_ERR("Invalid port was passed to the function: %d\n", proto);
383         return -1;
384     }
385
386     unsigned char policy_dir = 0;
387
388     if(dir == IPSEC_POLICY_DIRECTION_IN) {
389          policy_dir = XFRM_POLICY_IN;
390     }
391     else if(dir == IPSEC_POLICY_DIRECTION_OUT) {
392          policy_dir = XFRM_POLICY_OUT;
393     }
394     else {
395         LM_ERR("Invalid direction parameter passed to add_policy: %d\n", dir);
396         return -1;
397     }
398
399     char* src_addr = NULL;
400     char* dest_addr = NULL;
401
402     // convert input IP addresses to char*
403     if((src_addr = pkg_malloc(src_addr_param.len+1)) == NULL) {
404         LM_ERR("Error allocating memory for src addr during SA removal\n");
405         return -1;
406     }
407
408     if((dest_addr = pkg_malloc(dest_addr_param.len+1)) == NULL) {
409         pkg_free(src_addr);
410         LM_ERR("Error allocating memory for dest addr during SA removal\n");
411         return -2;
412     }
413
414     memset(src_addr, 0, src_addr_param.len+1);
415     memset(dest_addr, 0, dest_addr_param.len+1);
416
417     memcpy(src_addr, src_addr_param.s, src_addr_param.len);
418     memcpy(dest_addr, dest_addr_param.s, dest_addr_param.len);
419
420     struct {
421         struct nlmsghdr n;
422         struct xfrm_userpolicy_id xpid;
423         char buf[XFRM_TMPLS_BUF_SIZE];
424     } req = {
425         .n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xpid)),
426         .n.nlmsg_flags = NLM_F_REQUEST,
427         .n.nlmsg_type = XFRM_MSG_DELPOLICY,
428         .xpid.dir               = policy_dir,
429         .xpid.sel.family        = AF_INET,
430         .xpid.sel.daddr.a4      = inet_addr(dest_addr),
431         .xpid.sel.saddr.a4      = inet_addr(src_addr),
432         .xpid.sel.dport         = htons(dst_port),
433         .xpid.sel.dport_mask    = 0xFFFF,
434         .xpid.sel.prefixlen_d   = 32,
435         .xpid.sel.sport         = htons(src_port),
436         .xpid.sel.sport_mask    = 0xFFFF,
437         .xpid.sel.prefixlen_s   = 32//,
438         //.xpid.sel.proto         = sel_proto
439     };
440
441     if(mnl_socket_sendto(mnl_socket, &req.n, req.n.nlmsg_len) < 0)
442     {
443         LM_ERR("Failed to send Netlink message, error: %s\n", strerror(errno));
444         pkg_free(src_addr);
445         pkg_free(dest_addr);
446         return -1;
447     }
448
449     pkg_free(src_addr);
450     pkg_free(dest_addr);
451
452     return 0;
453 }
454
455 static int delsa_data_cb(const struct nlmsghdr *nlh, void *data)
456 {
457     struct xfrm_usersa_info *xsinfo = NLMSG_DATA(nlh);
458     int xfrm_userid = ntohl(xsinfo->sel.user);
459
460     //Check if user id is different from Kamailio's
461     if(xfrm_userid != xfrm_user_selector)
462         return MNL_CB_OK;
463
464     struct xfrm_buffer* delmsg_buf = (struct xfrm_buffer*)data;
465     uint32_t new_delmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_id));
466
467     if(delmsg_buf->offset + new_delmsg_len > sizeof(delmsg_buf->buf)/sizeof(delmsg_buf->buf[0])) {
468         LM_ERR("Not enough memory allocated for delete SAs netlink command\n");
469         return MNL_CB_ERROR;
470     }
471
472     struct nlmsghdr *new_delmsg = (struct nlmsghdr *)&delmsg_buf->buf[delmsg_buf->offset];
473     new_delmsg->nlmsg_len = new_delmsg_len;
474     new_delmsg->nlmsg_flags = NLM_F_REQUEST;
475     new_delmsg->nlmsg_type = XFRM_MSG_DELSA;
476     new_delmsg->nlmsg_seq = time(NULL);
477
478     struct xfrm_usersa_id *xsid = NLMSG_DATA(new_delmsg);
479     xsid->family = xsinfo->family;
480     memcpy(&xsid->daddr, &xsinfo->id.daddr, sizeof(xsid->daddr));
481     xsid->spi = xsinfo->id.spi;
482     xsid->proto = xsinfo->id.proto;
483
484     mnl_attr_put(new_delmsg, XFRMA_SRCADDR, sizeof(xsid->daddr), &xsinfo->saddr);
485
486     delmsg_buf->offset += new_delmsg->nlmsg_len;
487
488     return MNL_CB_OK;
489 }
490
491 static int delpolicy_data_cb(const struct nlmsghdr *nlh, void *data)
492 {
493     struct xfrm_userpolicy_info *xpinfo = NLMSG_DATA(nlh);
494     int xfrm_userid = ntohl(xpinfo->sel.user);
495
496     //Check if user id is different from Kamailio's
497     if(xfrm_userid != xfrm_user_selector)
498         return MNL_CB_OK;
499
500     struct xfrm_buffer* delmsg_buf = (struct xfrm_buffer*)data;
501     uint32_t new_delmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_id));
502
503     if(delmsg_buf->offset + new_delmsg_len > sizeof(delmsg_buf->buf)/sizeof(delmsg_buf->buf[0])) {
504         LM_ERR("Not enough memory allocated for delete policies netlink command\n");
505         return MNL_CB_ERROR;
506     }
507
508     struct nlmsghdr *new_delmsg = (struct nlmsghdr *)&delmsg_buf->buf[delmsg_buf->offset];
509     new_delmsg->nlmsg_len = new_delmsg_len;
510     new_delmsg->nlmsg_flags = NLM_F_REQUEST;
511     new_delmsg->nlmsg_type = XFRM_MSG_DELPOLICY;
512     new_delmsg->nlmsg_seq = time(NULL);
513
514     struct xfrm_userpolicy_id *xpid = NLMSG_DATA(new_delmsg);
515     memcpy(&xpid->sel, &xpinfo->sel, sizeof(xpid->sel));
516     xpid->dir = xpinfo->dir;
517     xpid->index = xpinfo->index;
518
519     delmsg_buf->offset += new_delmsg->nlmsg_len;
520
521     return MNL_CB_OK;
522 }
523
524 int clean_sa(struct mnl_socket*  mnl_socket)
525 {
526     struct {
527         struct nlmsghdr n;
528         //char buf[NLMSG_BUF_SIZE];
529     } req = {
530         .n.nlmsg_len = NLMSG_HDRLEN,
531         .n.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST,
532         .n.nlmsg_type = XFRM_MSG_GETSA,
533         .n.nlmsg_seq = time(NULL),
534     };
535
536     if(mnl_socket_sendto(mnl_socket, &req, req.n.nlmsg_len) == -1) {
537         LM_ERR("Error sending get all SAs command via netlink socket: %s\n", strerror(errno));
538         return 1;
539     }
540
541     char buf[NLMSG_BUF_SIZE];
542     memset(&buf, 0, sizeof(buf));
543
544     struct xfrm_buffer delmsg_buf;
545     memset(&delmsg_buf, 0, sizeof(struct xfrm_buffer));
546
547     int ret = mnl_socket_recvfrom(mnl_socket, buf, sizeof(buf));
548     while (ret > 0) {
549         ret = mnl_cb_run(buf, ret, req.n.nlmsg_seq, mnl_socket_get_portid(mnl_socket), delsa_data_cb, &delmsg_buf);
550         if (ret <= MNL_CB_STOP) {
551
552             break;
553         }
554         ret = mnl_socket_recvfrom(mnl_socket, buf, sizeof(buf));
555     }
556
557     // DELETE SAs
558     if(mnl_socket_sendto(mnl_socket, &delmsg_buf.buf, delmsg_buf.offset) == -1) {
559         LM_ERR("Error sending delete SAs command via netlink socket: %s\n", strerror(errno));
560         return 1;
561     }
562
563     return 0;
564 }
565
566 int clean_policy(struct mnl_socket*  mnl_socket)
567 {
568     struct {
569         struct nlmsghdr n;
570         //char buf[NLMSG_BUF_SIZE];
571     } req = {
572         .n.nlmsg_len = NLMSG_HDRLEN,
573         .n.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST,
574         .n.nlmsg_type = XFRM_MSG_GETPOLICY,
575         .n.nlmsg_seq = time(NULL),
576     };
577
578     if(mnl_socket_sendto(mnl_socket, &req, req.n.nlmsg_len) == -1) {
579         LM_ERR("Error sending get all policies command via netlink socket: %s\n", strerror(errno));
580         return 1;
581     }
582
583     char buf[NLMSG_BUF_SIZE];
584     memset(&buf, 0, sizeof(buf));
585
586     struct xfrm_buffer delmsg_buf;
587     memset(&delmsg_buf, 0, sizeof(struct xfrm_buffer));
588
589     int ret = mnl_socket_recvfrom(mnl_socket, buf, sizeof(buf));
590     while (ret > 0) {
591         ret = mnl_cb_run(buf, ret, req.n.nlmsg_seq, mnl_socket_get_portid(mnl_socket), delpolicy_data_cb, &delmsg_buf);
592         if (ret <= MNL_CB_STOP) {
593
594             break;
595         }
596         ret = mnl_socket_recvfrom(mnl_socket, buf, sizeof(buf));
597     }
598
599     // DELETE POLICIES
600     if(mnl_socket_sendto(mnl_socket, &delmsg_buf.buf, delmsg_buf.offset) == -1) {
601         LM_ERR("Error sending delete policies command via netlink socket: %s\n", strerror(errno));
602         return 1;
603     }
604
605     return 0;
606 }