2 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 #include <arpa/inet.h>
25 #include <linux/netfilter.h>
26 #include <linux/netfilter/xt_cgroup.h>
27 #include <linux/netfilter/xt_nfacct.h>
28 #include <linux/netfilter/xt_iprange.h>
29 #include <linux/netfilter/xt_NFLOG.h>
30 #include <linux/netfilter_ipv6/ip6t_LOG.h>
32 #include "stc-iptables-error.h"
33 #include "helper-ip6tables.h"
34 #include "helper-log.h"
36 #define IP6T_ALIGN XT_ALIGN
37 #define IP6TC_TABLE "filter"
38 #define IP6TC_TCP "tcp"
39 #define IP6TC_UDP "udp"
40 #define IP6TC_CGROUP "cgroup"
41 #define IP6TC_NFACCT "nfacct"
42 #define IP6TC_IPRANGE "iprange"
43 #define IP6TC_LOG "LOG"
44 #define IP6TC_NFLOG "NFLOG"
46 #define IP6TC_MASK "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF"
48 #define IP6TC_INSERT_RULENUM 0
51 typedef struct xtc_handle ip6t_handle_t;
54 typedef struct ip6t_entry ip6t_entry_t;
55 typedef struct ip6t_entry_match ip6t_entry_match_t;
56 typedef struct ip6t_entry_target ip6t_entry_target_t;
59 typedef struct xt_tcp ip6t_tcp_info_t;
60 typedef struct xt_udp ip6t_udp_info_t;
61 typedef struct xt_cgroup_info_v0 ip6t_cgroup_info_t;
62 typedef struct xt_nfacct_match_info ip6t_nfacct_info_t;
63 typedef struct xt_iprange_mtinfo ip6t_iprange_info_t;
66 typedef struct ip6t_log_info ip6t_log_info_t;
67 typedef struct xt_nflog_info ip6t_nflog_info_t;
69 #define SIZE_ENTRY IP6T_ALIGN(sizeof(ip6t_entry_t))
70 #define SIZE_TCP_MATCH IP6T_ALIGN(sizeof(ip6t_entry_match_t)) + IP6T_ALIGN(sizeof(ip6t_tcp_info_t))
71 #define SIZE_UDP_MATCH IP6T_ALIGN(sizeof(ip6t_entry_match_t)) + IP6T_ALIGN(sizeof(ip6t_udp_info_t))
72 #define SIZE_CGROUP_MATCH IP6T_ALIGN(sizeof(ip6t_entry_match_t)) + IP6T_ALIGN(sizeof(ip6t_cgroup_info_t))
73 #define SIZE_NFACCT_MATCH IP6T_ALIGN(sizeof(ip6t_entry_match_t)) + IP6T_ALIGN(sizeof(ip6t_nfacct_info_t))
74 #define SIZE_IPRANGE_MATCH IP6T_ALIGN(sizeof(ip6t_entry_match_t)) + IP6T_ALIGN(sizeof(ip6t_iprange_info_t))
75 #define SIZE_TARGET IP6T_ALIGN(sizeof(ip6t_entry_target_t)) + IP6T_ALIGN(sizeof(int))
76 #define SIZE_TARGET_LOG IP6T_ALIGN(sizeof(ip6t_log_info_t))
77 #define SIZE_TARGET_NFLOG IP6T_ALIGN(sizeof(ip6t_nflog_info_t))
78 #define SIZE_TOTAL SIZE_ENTRY + SIZE_TCP_MATCH + SIZE_UDP_MATCH + SIZE_CGROUP_MATCH \
79 + SIZE_NFACCT_MATCH + SIZE_IPRANGE_MATCH + SIZE_TARGET \
80 + SIZE_TARGET_LOG + SIZE_TARGET_NFLOG
82 static unsigned int __add_match(const char *name, ip6t_entry_match_t *start,
83 int revision, size_t size, void *data)
85 ip6t_entry_match_t *match = start;
87 match->u.match_size = IP6T_ALIGN(sizeof(ip6t_entry_match_t)) + IP6T_ALIGN(size);
89 g_strlcpy(match->u.user.name, name, XT_EXTENSION_MAXNAMELEN);
90 memcpy(match->data, data, size);
91 match->u.user.revision = revision;
93 return match->u.match_size;
96 static unsigned int __add_target(const char *name, ip6t_entry_target_t *start, size_t size, void *data)
98 ip6t_entry_target_t *target = start;
100 target->u.target_size = IP6T_ALIGN(sizeof(ip6t_entry_target_t)) + IP6T_ALIGN(size);
102 g_strlcpy(target->u.user.name, name, XT_EXTENSION_MAXNAMELEN);
103 memcpy(target->data, data, size);
105 return target->u.target_size;
108 static unsigned int __add_iprange_match(ip6tables_ip_type_e sip_type,
109 struct in6_addr sip1, struct in6_addr sip2, ip6tables_ip_type_e dip_type,
110 struct in6_addr dip1, struct in6_addr dip2, ip6t_entry_match_t *start)
112 ip6t_iprange_info_t iprange;
113 memset(&iprange, 0, sizeof(ip6t_iprange_info_t));
115 /* iprange => "--src-range " */
116 if (sip_type == IP6TABLES_IP_RANGE) {
117 memcpy(&(iprange.src_min.in6), &sip1, sizeof(struct in6_addr));
118 memcpy(&(iprange.src_max.in6), &sip2, sizeof(struct in6_addr));
119 iprange.flags |= IPRANGE_SRC;
122 /* iprange => "--dst-range " */
123 if (dip_type == IP6TABLES_IP_RANGE) {
124 memcpy(&(iprange.dst_min.in6), &dip1, sizeof(struct in6_addr));
125 memcpy(&(iprange.dst_max.in6), &dip2, sizeof(struct in6_addr));
126 iprange.flags |= IPRANGE_DST;
129 /* match_iprange => "-m iprange" */
130 return __add_match(IP6TC_IPRANGE, start, 1, sizeof(ip6t_iprange_info_t), &iprange);
133 static void __add_iprange(unsigned char *entry, unsigned int *size_mask,
134 unsigned int *size_match, ip6tables_rule_s *rule)
136 ip6t_entry_t *e = (ip6t_entry_t *)(entry);
138 (*size_match) += __add_iprange_match(rule->s_ip_type,
139 rule->s_ip1, rule->s_ip2, rule->d_ip_type, rule->d_ip1,
140 rule->d_ip2, (ip6t_entry_match_t *)(e->elems + (*size_match)));
142 (*size_mask) += sizeof(ip6t_entry_match_t);
143 e->target_offset += SIZE_IPRANGE_MATCH;
144 e->next_offset += SIZE_IPRANGE_MATCH;
147 static unsigned int __add_port_match(ip6tables_protocol_type_e prot_type,
148 ip6tables_port_type_e sport_type, unsigned short sport1, unsigned short sport2,
149 ip6tables_port_type_e dport_type, unsigned short dport1, unsigned short dport2,
150 ip6t_entry_match_t *start)
153 case IP6TABLES_PROTOCOL_TCP:
156 memset(&tcp, 0, sizeof(ip6t_tcp_info_t));
159 case IP6TABLES_PORT_SINGLE:
160 tcp.spts[0] = ntohs(htons(sport1));
161 tcp.spts[1] = ntohs(htons(sport1));
163 /* --sport 0:59136 */
164 case IP6TABLES_PORT_RANGE:
165 tcp.spts[0] = ntohs(htons(sport1));
166 tcp.spts[1] = ntohs(htons(sport2));
173 case IP6TABLES_PORT_SINGLE:
174 tcp.dpts[0] = ntohs(htons(dport1));
175 tcp.dpts[1] = ntohs(htons(dport1));
177 /* --dport 0:59136 */
178 case IP6TABLES_PORT_RANGE:
179 tcp.dpts[0] = ntohs(htons(dport1));
180 tcp.dpts[1] = ntohs(htons(dport2));
185 return __add_match(IP6TC_TCP, start, 0, sizeof(ip6t_tcp_info_t), &tcp);
187 case IP6TABLES_PROTOCOL_UDP:
190 memset(&udp, 0, sizeof(ip6t_udp_info_t));
193 case IP6TABLES_PORT_SINGLE:
194 udp.spts[0] = ntohs(htons(sport1));
195 udp.spts[1] = ntohs(htons(sport1));
197 /* --sport 0:59136 */
198 case IP6TABLES_PORT_RANGE:
199 udp.spts[0] = ntohs(htons(sport1));
200 udp.spts[1] = ntohs(htons(sport2));
207 case IP6TABLES_PORT_SINGLE:
208 udp.dpts[0] = ntohs(htons(dport1));
209 udp.dpts[1] = ntohs(htons(dport1));
211 /* --dport 0:59136 */
212 case IP6TABLES_PORT_RANGE:
213 udp.dpts[0] = ntohs(htons(dport1));
214 udp.dpts[1] = ntohs(htons(dport2));
219 return __add_match(IP6TC_UDP, start, 0, sizeof(ip6t_udp_info_t), &udp);
228 static void __add_port(unsigned char *entry, unsigned int *size_mask,
229 unsigned int *size_match, ip6tables_rule_s *rule, unsigned int match_size)
231 if ((rule->s_port_type > IP6TABLES_PORT_NONE &&
232 rule->s_port_type <= IP6TABLES_PORT_RANGE) ||
233 (rule->d_port_type > IP6TABLES_PORT_NONE &&
234 rule->d_port_type <= IP6TABLES_PORT_RANGE)) {
236 ip6t_entry_t *e = (ip6t_entry_t *)(entry);
238 (*size_match) += __add_port_match(rule->protocol,
239 rule->s_port_type, rule->s_port1, rule->s_port2,
240 rule->d_port_type, rule->d_port1, rule->d_port2,
241 (ip6t_entry_match_t *) (e->elems + (*size_match)));
243 (*size_mask) += sizeof(ip6t_entry_match_t);
244 e->target_offset += match_size;
245 e->next_offset += match_size;
249 static unsigned int __add_cgroup_match(unsigned int classid, ip6t_entry_match_t *start)
251 /* cgroup => "--cgroup 0" */
252 ip6t_cgroup_info_t cgroup;
253 memset(&cgroup, 0, sizeof(ip6t_cgroup_info_t));
255 /* match_cgroup => "-m cgroup" */
256 return __add_match(IP6TC_CGROUP, start, 0, sizeof(ip6t_cgroup_info_t), &cgroup);
259 static unsigned int __add_nfacct_match(const char *nfacct_name, ip6t_entry_match_t *start)
261 /* nfacct => "--nfacct_name " */
262 ip6t_nfacct_info_t nfacct;
263 memset(&nfacct, 0, sizeof(ip6t_nfacct_info_t));
264 g_strlcpy(nfacct.name, nfacct_name, NFACCT_NAME_MAX);
265 /* match_nfacct => "-m nfacct" */
266 return __add_match(IP6TC_NFACCT, start, 0, sizeof(ip6t_nfacct_info_t), &nfacct);
269 static unsigned int __add_log_target(unsigned char level, const char *prefix,
270 ip6t_entry_target_t *start)
272 /* log => "--log-level --log-prefix" */
274 memset(&log, 0, sizeof(ip6t_log_info_t));
276 g_strlcpy(log.prefix, prefix, 30);
278 return __add_target(IP6TC_LOG, start, sizeof(ip6t_log_info_t), &log);
281 static unsigned int __add_nflog_target(unsigned int group, const char *prefix,
282 unsigned int range, unsigned int threshold, ip6t_entry_target_t *start)
284 /* nflog => "--nflog-group --nflog-prefix --nflog-range --nflog-threshold" */
285 ip6t_nflog_info_t nflog;
286 memset(&nflog, 0, sizeof(ip6t_nflog_info_t));
288 g_strlcpy(nflog.prefix, prefix, 64);
290 nflog.threshold = threshold;
292 return __add_target(IP6TC_NFLOG, start, sizeof(ip6t_nflog_info_t), &nflog);
295 static int __create_entry_data(unsigned char *entry, unsigned char *mask,
296 ip6tables_rule_s *rule)
298 ip6t_entry_t *e = NULL;
299 ip6t_entry_target_t *target = NULL;
300 unsigned int size_mask = 0;
301 unsigned int size_match = 0;
304 STC_LOGE("Invalid parameters"); //LCOV_EXCL_LINE
305 return STC_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
308 e = (ip6t_entry_t *)(entry);
311 e->target_offset = SIZE_ENTRY;
312 e->next_offset = SIZE_ENTRY;
313 size_mask = sizeof(ip6t_entry_t);
315 if (rule->ifname && rule->ifname[0] != '\0') {
316 switch (rule->direction) {
317 case IP6TABLES_DIRECTION_IN:
318 /* entry => "-i wlan0" */
319 g_strlcpy(e->ipv6.iniface, rule->ifname, IFNAMSIZ);
320 memset(&(e->ipv6.iniface_mask), 0xFF, IFNAMSIZ);
322 case IP6TABLES_DIRECTION_OUT:
323 /* entry => "-o wlan0" */
324 g_strlcpy(e->ipv6.outiface, rule->ifname, IFNAMSIZ);
325 memset(&(e->ipv6.outiface_mask), 0xFF, IFNAMSIZ);
328 STC_LOGE("Invalid parameter"); //LCOV_EXCL_LINE
329 return STC_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
333 switch (rule->s_ip_type) {
334 case IP6TABLES_IP_SINGLE:
335 /* -s 2001:DB8::5/128 */
336 e->ipv6.src.s6_addr32[0] = rule->s_ip1.s6_addr32[0];
337 e->ipv6.src.s6_addr32[1] = rule->s_ip1.s6_addr32[1];
338 e->ipv6.src.s6_addr32[2] = rule->s_ip1.s6_addr32[2];
339 e->ipv6.src.s6_addr32[3] = rule->s_ip1.s6_addr32[3];
340 inet_pton(AF_INET6, IP6TC_MASK, &(e->ipv6.smsk));
342 case IP6TABLES_IP_MASK:
343 /* -s 2001:DB8::5/64 */
344 e->ipv6.src.s6_addr32[0] = rule->s_ip1.s6_addr32[0];
345 e->ipv6.src.s6_addr32[1] = rule->s_ip1.s6_addr32[1];
346 e->ipv6.src.s6_addr32[2] = rule->s_ip1.s6_addr32[2];
347 e->ipv6.src.s6_addr32[3] = rule->s_ip1.s6_addr32[3];
348 e->ipv6.smsk.s6_addr32[0] = rule->s_ip2.s6_addr32[0];
349 e->ipv6.smsk.s6_addr32[1] = rule->s_ip2.s6_addr32[1];
350 e->ipv6.smsk.s6_addr32[2] = rule->s_ip2.s6_addr32[2];
351 e->ipv6.smsk.s6_addr32[3] = rule->s_ip2.s6_addr32[3];
357 switch (rule->d_ip_type) {
358 case IP6TABLES_IP_SINGLE:
359 /* -d 2001:DB8::5/128 */
360 e->ipv6.dst.s6_addr32[0] = rule->d_ip1.s6_addr32[0];
361 e->ipv6.dst.s6_addr32[1] = rule->d_ip1.s6_addr32[1];
362 e->ipv6.dst.s6_addr32[2] = rule->d_ip1.s6_addr32[2];
363 e->ipv6.dst.s6_addr32[3] = rule->d_ip1.s6_addr32[3];
364 inet_pton(AF_INET6, IP6TC_MASK, &(e->ipv6.dmsk));
366 case IP6TABLES_IP_MASK:
367 /* -d 2001:DB8::5/128 */
368 e->ipv6.dst.s6_addr32[0] = rule->d_ip1.s6_addr32[0];
369 e->ipv6.dst.s6_addr32[1] = rule->d_ip1.s6_addr32[1];
370 e->ipv6.dst.s6_addr32[2] = rule->d_ip1.s6_addr32[2];
371 e->ipv6.dst.s6_addr32[3] = rule->d_ip1.s6_addr32[3];
372 e->ipv6.dmsk.s6_addr32[0] = rule->d_ip2.s6_addr32[0];
373 e->ipv6.dmsk.s6_addr32[1] = rule->d_ip2.s6_addr32[1];
374 e->ipv6.dmsk.s6_addr32[2] = rule->d_ip2.s6_addr32[2];
375 e->ipv6.dmsk.s6_addr32[3] = rule->d_ip2.s6_addr32[3];
381 if (rule->s_ip_type == IP6TABLES_IP_RANGE ||
382 rule->d_ip_type == IP6TABLES_IP_RANGE)
383 __add_iprange(entry, &size_mask, &size_match, rule);
386 switch (rule->protocol) {
387 case IP6TABLES_PROTOCOL_TCP:
388 e->ipv6.proto = IPPROTO_TCP;
389 __add_port(entry, &size_mask, &size_match, rule, SIZE_TCP_MATCH);
391 case IP6TABLES_PROTOCOL_UDP:
392 e->ipv6.proto = IPPROTO_UDP;
393 __add_port(entry, &size_mask, &size_match, rule, SIZE_UDP_MATCH);
395 case IP6TABLES_PROTOCOL_ICMP:
396 e->ipv6.proto = IPPROTO_ICMP;
398 case IP6TABLES_PROTOCOL_ESP:
399 e->ipv6.proto = IPPROTO_ESP;
401 case IP6TABLES_PROTOCOL_AH:
402 e->ipv6.proto = IPPROTO_AH;
404 case IP6TABLES_PROTOCOL_SCTP:
405 e->ipv6.proto = IPPROTO_SCTP;
407 case IP6TABLES_PROTOCOL_MH:
408 e->ipv6.proto = IPPROTO_MH;
410 case IP6TABLES_PROTOCOL_ALL:
418 /* -m cgroup --cgroup 33 */
419 if (rule->classid > 0) {
420 size_match += __add_cgroup_match(rule->classid, (ip6t_entry_match_t *) e->elems);
421 size_mask += sizeof(ip6t_entry_match_t);
422 e->target_offset += SIZE_CGROUP_MATCH;
423 e->next_offset += SIZE_CGROUP_MATCH;
426 /* -m nfacct --nfacct-name c2_1_33_seth_w0 */
427 if (rule->nfacct_name && rule->nfacct_name[0] != '\0') {
428 size_match += __add_nfacct_match(rule->nfacct_name, (ip6t_entry_match_t *) (e->elems + size_match));
429 size_mask += sizeof(ip6t_entry_match_t);
430 e->target_offset += SIZE_NFACCT_MATCH;
431 e->next_offset += SIZE_NFACCT_MATCH;
434 /* target => "-j ACCEPT" */
435 target = (ip6t_entry_target_t *) (e->elems + size_match);
436 switch (rule->target_type) {
437 case IP6TABLES_ACTION_LOG:
438 e->next_offset += __add_log_target(rule->log_level, rule->log_prefix, target);
440 case IP6TABLES_ACTION_NFLOG:
441 e->next_offset += __add_nflog_target(rule->nflog_group,
442 rule->nflog_prefix, rule->nflog_range, rule->nflog_threshold, target);
445 target->u.target_size = SIZE_TARGET;
446 if (rule->target && rule->target[0] != '\0')
447 g_strlcpy(target->u.user.name, rule->target, XT_EXTENSION_MAXNAMELEN);
448 e->next_offset += SIZE_TARGET;
452 memset(mask, 0xFF, size_mask);
454 return STC_ERROR_NONE;
457 int ip6tables_add_rule(ip6tables_rule_s *rule)
459 ip6t_handle_t *handle;
460 unsigned char entry[SIZE_TOTAL] = {0, };
461 unsigned char mask[SIZE_TOTAL] = {0, };
463 const char *chain = rule->chain;
465 if (__create_entry_data(entry, mask, rule) != 0) {
466 STC_LOGE("Failed to create entry"); //LCOV_EXCL_LINE
467 return STC_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
470 handle = ip6tc_init(IP6TC_TABLE);
471 if (handle == NULL) {
472 STC_LOGE("ip6tc_init failed [%s]", ip6tc_strerror(errno)); //LCOV_EXCL_LINE
473 return STC_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
476 if (!ip6tc_is_chain(chain, handle)) {
477 STC_LOGW("chain not present [%s]", ip6tc_strerror(errno)); //LCOV_EXCL_LINE
478 ip6tc_free(handle); //LCOV_EXCL_LINE
479 return STC_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
482 if (ip6tc_check_entry(chain, (const ip6t_entry_t *)entry, mask, handle)) {
483 STC_LOGW("Entry already present"); //LCOV_EXCL_LINE
484 ip6tc_free(handle); //LCOV_EXCL_LINE
485 return STC_ERROR_NONE; //LCOV_EXCL_LINE
488 if (!ip6tc_append_entry(chain, (const ip6t_entry_t *)entry, handle)) {
489 STC_LOGW("ip6tc_append_entry failed [%s]", ip6tc_strerror(errno)); //LCOV_EXCL_LINE
490 ip6tc_free(handle); //LCOV_EXCL_LINE
491 return STC_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
494 if (!ip6tc_commit(handle)) {
495 STC_LOGE("Failed to ip6tc_commit [%s]", ip6tc_strerror(errno)); //LCOV_EXCL_LINE
496 ip6tc_free(handle); //LCOV_EXCL_LINE
497 return STC_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
502 STC_LOGI("Success adding rule");
503 return STC_ERROR_NONE;
506 int ip6tables_add_rule_list(GSList *rule_list)
509 ip6t_handle_t *handle;
511 handle = ip6tc_init(IP6TC_TABLE);
512 if (handle == NULL) {
513 STC_LOGE("ip6tc_init failed [%s]", ip6tc_strerror(errno));
514 return STC_ERROR_OPERATION_FAILED;
517 for (list = rule_list; list; list = list->next) {
518 ip6tables_rule_s *rule = list->data;
519 const char *chain = rule->chain;
520 unsigned char entry[SIZE_TOTAL] = {0, };
521 unsigned char mask[SIZE_TOTAL] = {0, };
523 if (!ip6tc_is_chain(chain, handle)) {
524 STC_LOGE("chain not present [%s]", ip6tc_strerror(errno));
528 if (__create_entry_data(entry, mask, rule) != 0) {
529 STC_LOGE("Failed to create entry");
533 if (ip6tc_check_entry(chain, (const ip6t_entry_t *)entry, mask, handle)) {
534 STC_LOGD("Entry already present");
538 if (!ip6tc_append_entry(chain, (const ip6t_entry_t *)entry, handle)) {
539 STC_LOGE("ip6tc_append_entry failed [%s]", ip6tc_strerror(errno));
543 STC_LOGD("Append entry [%s : %s]", rule->chain, rule->nfacct_name);
546 if (!ip6tc_commit(handle)) {
547 STC_LOGE("Failed to ip6tc_commit [%s]", ip6tc_strerror(errno));
549 return STC_ERROR_OPERATION_FAILED;
552 STC_LOGI("Successed to add rule list");
554 return STC_ERROR_NONE;
558 int ip6tables_insert_rule(ip6tables_rule_s *rule)
560 ip6t_handle_t *handle;
561 unsigned char entry[SIZE_TOTAL] = {0, };
562 unsigned char mask[SIZE_TOTAL] = {0, };
564 const char *chain = rule->chain;
566 if (__create_entry_data(entry, mask, rule) != 0) {
567 STC_LOGE("Failed to create entry"); //LCOV_EXCL_LINE
568 return STC_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
571 handle = ip6tc_init(IP6TC_TABLE);
572 if (handle == NULL) {
573 STC_LOGE("ip6tc_init failed [%s]", ip6tc_strerror(errno)); //LCOV_EXCL_LINE
574 return STC_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
577 if (!ip6tc_is_chain(chain, handle)) {
578 STC_LOGW("chain not present [%s]", ip6tc_strerror(errno)); //LCOV_EXCL_LINE
579 ip6tc_free(handle); //LCOV_EXCL_LINE
580 return STC_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
583 if (ip6tc_check_entry(chain, (const ip6t_entry_t *)entry, mask, handle)) {
584 STC_LOGW("Entry already present"); //LCOV_EXCL_LINE
585 ip6tc_free(handle); //LCOV_EXCL_LINE
586 return STC_ERROR_NONE; //LCOV_EXCL_LINE
589 if (!ip6tc_insert_entry(chain, (const ip6t_entry_t *)entry, IP6TC_INSERT_RULENUM, handle)) {
590 STC_LOGW("ip6tc_insert_entry failed [%s]", ip6tc_strerror(errno)); //LCOV_EXCL_LINE
591 ip6tc_free(handle); //LCOV_EXCL_LINE
592 return STC_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
595 if (!ip6tc_commit(handle)) {
596 STC_LOGE("Failed to ip6tc_commit [%s]", ip6tc_strerror(errno)); //LCOV_EXCL_LINE
597 ip6tc_free(handle); //LCOV_EXCL_LINE
598 return STC_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
603 STC_LOGI("Success adding rule");
604 return STC_ERROR_NONE;
607 int ip6tables_remove_rule(ip6tables_rule_s *rule)
609 ip6t_handle_t *handle;
610 unsigned char entry[SIZE_TOTAL] = {0, };
611 unsigned char mask[SIZE_TOTAL] = {0, };
613 const char *chain = rule->chain;
615 if (__create_entry_data(entry, mask, rule) != 0) {
616 STC_LOGE("Failed to create entry"); //LCOV_EXCL_LINE
617 return STC_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
620 handle = ip6tc_init(IP6TC_TABLE);
621 if (handle == NULL) {
622 STC_LOGE("ip6tc_init failed [%s]", ip6tc_strerror(errno)); //LCOV_EXCL_LINE
623 return STC_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
626 if (!ip6tc_is_chain(chain, handle)) {
627 STC_LOGW("chain not present [%s]", ip6tc_strerror(errno)); //LCOV_EXCL_LINE
628 ip6tc_free(handle); //LCOV_EXCL_LINE
629 return STC_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
632 if (!ip6tc_delete_entry(chain, (const ip6t_entry_t *)entry, mask, handle)) {
633 STC_LOGW("ip6tc_delete_entry failed [%s]", ip6tc_strerror(errno)); //LCOV_EXCL_LINE
634 ip6tc_free(handle); //LCOV_EXCL_LINE
635 return STC_ERROR_NONE; //LCOV_EXCL_LINE
638 if (!ip6tc_commit(handle)) {
639 STC_LOGE("Failed to ip6tc_commit [%s]", ip6tc_strerror(errno)); //LCOV_EXCL_LINE
640 ip6tc_free(handle); //LCOV_EXCL_LINE
641 return STC_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
646 STC_LOGI("Success removing rule");
647 return STC_ERROR_NONE;
650 int ip6tables_remove_rule_list(GSList *rule_list)
653 ip6t_handle_t *handle;
655 handle = ip6tc_init(IP6TC_TABLE);
656 if (handle == NULL) {
657 STC_LOGE("ip6tc_init failed [%s]", ip6tc_strerror(errno));
658 return STC_ERROR_OPERATION_FAILED;
661 for (list = rule_list; list; list = list->next) {
662 ip6tables_rule_s *rule = list->data;
663 const char *chain = rule->chain;
664 unsigned char entry[SIZE_TOTAL] = {0, };
665 unsigned char mask[SIZE_TOTAL] = {0, };
667 if (!ip6tc_is_chain(chain, handle)) {
668 STC_LOGE("chain not present [%s]", ip6tc_strerror(errno));
672 if (__create_entry_data(entry, mask, rule) != 0) {
673 STC_LOGE("Failed to create entry");
677 if (!ip6tc_delete_entry(chain, (const ip6t_entry_t *)entry, mask, handle)) {
678 STC_LOGE("ip6tc_append_entry failed [%s]", ip6tc_strerror(errno));
682 STC_LOGD("Append entry [%s : %s]", rule->chain, rule->nfacct_name);
685 if (!ip6tc_commit(handle)) {
686 STC_LOGE("Failed to ip6tc_commit [%s]", ip6tc_strerror(errno));
688 return STC_ERROR_OPERATION_FAILED;
691 STC_LOGI("Successed to remove rule list");
693 return STC_ERROR_NONE;
696 int ip6tables_add_chain(const char *chain)
698 ip6t_handle_t *handle;
700 handle = ip6tc_init(IP6TC_TABLE);
701 if (handle == NULL) {
702 STC_LOGE("ip6tc_init failed [%s]", ip6tc_strerror(errno)); //LCOV_EXCL_LINE
703 return STC_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
706 if (ip6tc_is_chain(chain, handle)) {
707 STC_LOGW("chain already exists"); //LCOV_EXCL_LINE
708 ip6tc_free(handle); //LCOV_EXCL_LINE
709 return STC_ERROR_NONE; //LCOV_EXCL_LINE
712 if (!ip6tc_create_chain(chain, handle)) {
713 STC_LOGE("Failed to create chaing [%s]", ip6tc_strerror(errno)); //LCOV_EXCL_LINE
714 ip6tc_free(handle); //LCOV_EXCL_LINE
715 return STC_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
718 if (!ip6tc_commit(handle)) {
719 STC_LOGE("Failed to ip6tc_commit [%s]", ip6tc_strerror(errno)); //LCOV_EXCL_LINE
720 ip6tc_free(handle); //LCOV_EXCL_LINE
721 return STC_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
726 STC_LOGI("Success adding chain");
730 int ip6tables_remove_chain(const char *chain)
732 ip6t_handle_t *handle;
734 handle = ip6tc_init(IP6TC_TABLE);
735 if (handle == NULL) {
736 STC_LOGE("ip6tc_init failed [%s]", ip6tc_strerror(errno)); //LCOV_EXCL_LINE
737 return STC_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
740 if (!ip6tc_is_chain(chain, handle)) {
741 STC_LOGW("chain not present"); //LCOV_EXCL_LINE
742 ip6tc_free(handle); //LCOV_EXCL_LINE
743 return STC_ERROR_NONE; //LCOV_EXCL_LINE
746 ip6tc_flush_entries(chain, handle);
748 if (!ip6tc_delete_chain(chain, handle)) {
749 STC_LOGE("Failed to delete chain [%s]", ip6tc_strerror(errno)); //LCOV_EXCL_LINE
750 ip6tc_free(handle); //LCOV_EXCL_LINE
751 return STC_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
754 if (!ip6tc_commit(handle)) {
755 STC_LOGE("Failed to ip6tc_commit [%s]", ip6tc_strerror(errno)); //LCOV_EXCL_LINE
756 ip6tc_free(handle); //LCOV_EXCL_LINE
757 return STC_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
762 STC_LOGI("Success removing chain");
763 return STC_ERROR_NONE;
766 int ip6tables_flush_chain(const char *chain)
768 ip6t_handle_t *handle;
770 handle = ip6tc_init(IP6TC_TABLE);
771 if (handle == NULL) {
772 STC_LOGE("ip6tc_init failed [%s]", ip6tc_strerror(errno)); //LCOV_EXCL_LINE
773 return STC_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
776 if (!ip6tc_is_chain(chain, handle)) {
777 STC_LOGW("chain not present"); //LCOV_EXCL_LINE
778 ip6tc_free(handle); //LCOV_EXCL_LINE
779 return STC_ERROR_NONE; //LCOV_EXCL_LINE
782 if(!ip6tc_flush_entries(chain, handle)) {
783 STC_LOGE("Failed to flush chain [%s]", ip6tc_strerror(errno)); //LCOV_EXCL_LINE
784 ip6tc_free(handle); //LCOV_EXCL_LINE
785 return STC_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
788 if (!ip6tc_commit(handle)) {
789 STC_LOGE("Failed to ip6tc_commit [%s]", ip6tc_strerror(errno)); //LCOV_EXCL_LINE
790 ip6tc_free(handle); //LCOV_EXCL_LINE
791 return STC_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
796 STC_LOGI("Success removing chain");
797 return STC_ERROR_NONE;