From 9a41dccb8e83bf7a7b3c12e6caf371010cf748cb Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Mon, 27 May 2013 11:17:06 +0200 Subject: [PATCH] Fix compatibility with older libiptc/libip6tc --- iptables.c | 51 +++++------------ iptables.h | 10 +++- xtables-10.h | 114 +++++++++++++++++++++++++++++++++++++ xtables-5.h | 183 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 321 insertions(+), 37 deletions(-) create mode 100644 xtables-10.h create mode 100644 xtables-5.h diff --git a/iptables.c b/iptables.c index 2684933..a189745 100644 --- a/iptables.c +++ b/iptables.c @@ -39,7 +39,7 @@ static struct xtables_globals xtg6 = { }; /* Required by certain extensions like SNAT and DNAT */ -int kernel_version; +int kernel_version = 0; void get_kernel_version(void) @@ -51,7 +51,7 @@ get_kernel_version(void) sprintf(uts.release, "3.0.0"); sscanf(uts.release, "%d.%d.%d", &x, &y, &z); - kernel_version = LINUX_VERSION(x, y, z); + kernel_version = 0x10000 * x + 0x100 * y + z; } #undef __ipt_module @@ -358,16 +358,14 @@ init_match(struct fw3_ipt_rule *r, struct xtables_match *m, bool no_clone) s = XT_ALIGN(sizeof(struct xt_entry_match)) + m->size; m->m = fw3_alloc(s); - strcpy(m->m->u.user.name, m->real_name ? m->real_name : m->name); + + fw3_xt_set_match_name(m); + m->m->u.user.revision = m->revision; m->m->u.match_size = s; /* free previous userspace data */ - if (m->udata_size) - { - free(m->udata); - m->udata = fw3_alloc(m->udata_size); - } + fw3_xt_free_match_udata(m); if (m->init) m->init(m->m); @@ -378,14 +376,7 @@ init_match(struct fw3_ipt_rule *r, struct xtables_match *m, bool no_clone) /* merge option table */ g = (r->h->family == FW3_FAMILY_V6) ? &xtg6 : &xtg; - - if (m->x6_options) - g->opts = xtables_options_xfrm(g->orig_opts, g->opts, - m->x6_options, &m->option_offset); - - if (m->extra_opts) - g->opts = xtables_merge_options(g->orig_opts, g->opts, - m->extra_opts, &m->option_offset); + fw3_xt_merge_match_options(g, m); } static bool @@ -431,32 +422,20 @@ get_target(struct fw3_ipt_rule *r, const char *name) s = XT_ALIGN(sizeof(struct xt_entry_target)) + t->size; t->t = fw3_alloc(s); - if (!t->real_name) - strcpy(t->t->u.user.name, name); - else - strcpy(t->t->u.user.name, t->real_name); + fw3_xt_set_target_name(t, name); t->t->u.user.revision = t->revision; t->t->u.target_size = s; - if (t->udata_size) - { - free(t->udata); - t->udata = fw3_alloc(t->udata_size); - } + /* free previous userspace data */ + fw3_xt_free_target_udata(t); if (t->init) t->init(t->t); /* merge option table */ g = (r->h->family == FW3_FAMILY_V6) ? &xtg6 : &xtg; - - if (t->x6_options) - g->opts = xtables_options_xfrm(g->orig_opts, g->opts, - t->x6_options, &t->option_offset); - else - g->opts = xtables_merge_options(g->orig_opts, g->opts, - t->extra_opts, &t->option_offset); + fw3_xt_merge_target_options(g, t); r->target = t; @@ -1028,7 +1007,7 @@ rule_print(struct fw3_ipt_rule *r, const char *chain) for (rm = r->matches; rm; rm = rm->next) { m = rm->match; - printf(" -m %s", m->alias ? m->alias(m->m) : m->m->u.user.name); + printf(" -m %s", fw3_xt_get_match_name(m)); if (m->save) m->save(&r->e.ip, m->m); @@ -1037,7 +1016,7 @@ rule_print(struct fw3_ipt_rule *r, const char *chain) if (r->target) { t = r->target; - printf(" -j %s", t->alias ? t->alias(t->t) : t->t->u.user.name); + printf(" -j %s", fw3_xt_get_target_name(t)); if (t->save) t->save(&r->e.ip, t->t); @@ -1053,7 +1032,7 @@ parse_option(struct fw3_ipt_rule *r, int optc, bool inv) struct xtables_match *em; /* is a target option */ - if (r->target && (r->target->parse || r->target->x6_parse) && + if (r->target && fw3_xt_has_target_parse(r->target) && optc >= r->target->option_offset && optc < (r->target->option_offset + 256)) { @@ -1066,7 +1045,7 @@ parse_option(struct fw3_ipt_rule *r, int optc, bool inv) { em = m->match; - if (m->completed || (!em->parse && !em->x6_parse)) + if (m->completed || !fw3_xt_has_match_parse(em)) continue; if (optc < em->option_offset || diff --git a/iptables.h b/iptables.h index c8c86ec..05a1c72 100644 --- a/iptables.h +++ b/iptables.h @@ -30,6 +30,14 @@ #include "options.h" +#if (XTABLES_VERSION_CODE == 10) +# include "xtables-10.h" +#elif (XTABLES_VERSION_CODE == 5) +# include "xtables-5.h" +#else +# error "Unsupported xtables version" +#endif + extern struct xtables_match *xtables_pending_matches; extern struct xtables_target *xtables_pending_targets; @@ -74,7 +82,7 @@ void get_kernel_version(void); struct fw3_ipt_handle { enum fw3_family family; enum fw3_table table; - struct xtc_handle *handle; + void *handle; }; struct fw3_ipt_rule { diff --git a/xtables-10.h b/xtables-10.h new file mode 100644 index 0000000..6b52fff --- /dev/null +++ b/xtables-10.h @@ -0,0 +1,114 @@ +/* + * firewall3 - 3rd OpenWrt UCI firewall implementation + * + * Copyright (C) 2013 Jo-Philipp Wich + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __FW3_XTABLES_10_H +#define __FW3_XTABLES_10_H + +static inline const char * +fw3_xt_get_match_name(struct xtables_match *m) +{ + if (m->alias) + return m->alias(m->m); + + return m->m->u.user.name; +} + +static inline void +fw3_xt_set_match_name(struct xtables_match *m) +{ + if (m->real_name) + strcpy(m->m->u.user.name, m->real_name); + else + strcpy(m->m->u.user.name, m->name); +} + +static inline bool +fw3_xt_has_match_parse(struct xtables_match *m) +{ + return (m->parse || m->x6_parse); +} + +static inline void +fw3_xt_free_match_udata(struct xtables_match *m) +{ + if (m->udata_size) + { + free(m->udata); + m->udata = fw3_alloc(m->udata_size); + } +} + +static inline void +fw3_xt_merge_match_options(struct xtables_globals *g, struct xtables_match *m) +{ + if (m->x6_options) + g->opts = xtables_options_xfrm(g->orig_opts, g->opts, + m->x6_options, &m->option_offset); + + if (m->extra_opts) + g->opts = xtables_merge_options(g->orig_opts, g->opts, + m->extra_opts, &m->option_offset); +} + + +static inline const char * +fw3_xt_get_target_name(struct xtables_target *t) +{ + if (t->alias) + return t->alias(t->t); + + return t->t->u.user.name; +} + +static inline void +fw3_xt_set_target_name(struct xtables_target *t, const char *name) +{ + if (t->real_name) + strcpy(t->t->u.user.name, t->real_name); + else + strcpy(t->t->u.user.name, name); +} + +static inline bool +fw3_xt_has_target_parse(struct xtables_target *t) +{ + return (t->parse || t->x6_parse); +} + +static inline void +fw3_xt_free_target_udata(struct xtables_target *t) +{ + if (t->udata_size) + { + free(t->udata); + t->udata = fw3_alloc(t->udata_size); + } +} + +static inline void +fw3_xt_merge_target_options(struct xtables_globals *g, struct xtables_target *t) +{ + if (t->x6_options) + g->opts = xtables_options_xfrm(g->orig_opts, g->opts, + t->x6_options, &t->option_offset); + else + g->opts = xtables_merge_options(g->orig_opts, g->opts, + t->extra_opts, &t->option_offset); +} + +#endif diff --git a/xtables-5.h b/xtables-5.h new file mode 100644 index 0000000..263d012 --- /dev/null +++ b/xtables-5.h @@ -0,0 +1,183 @@ +/* + * firewall3 - 3rd OpenWrt UCI firewall implementation + * + * Copyright (C) 2013 Jo-Philipp Wich + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __FW3_XTABLES_5_H +#define __FW3_XTABLES_5_H + +static inline const char * +fw3_xt_get_match_name(struct xtables_match *m) +{ + return m->m->u.user.name; +} + +static inline void +fw3_xt_set_match_name(struct xtables_match *m) +{ + strcpy(m->m->u.user.name, m->name); +} + +static inline bool +fw3_xt_has_match_parse(struct xtables_match *m) +{ + return !!m->parse; +} + +static inline void +fw3_xt_free_match_udata(struct xtables_match *m) +{ + return; +} + +static inline void +fw3_xt_merge_match_options(struct xtables_globals *g, struct xtables_match *m) +{ + g->opts = xtables_merge_options(g->opts, m->extra_opts, &m->option_offset); +} + + +static inline const char * +fw3_xt_get_target_name(struct xtables_target *t) +{ + return t->t->u.user.name; +} + +static inline void +fw3_xt_set_target_name(struct xtables_target *t, const char *name) +{ + strcpy(t->t->u.user.name, name); +} + +static inline bool +fw3_xt_has_target_parse(struct xtables_target *t) +{ + return !!t->parse; +} + +static inline void +fw3_xt_free_target_udata(struct xtables_target *t) +{ + return; +} + +static inline void +fw3_xt_merge_target_options(struct xtables_globals *g, struct xtables_target *t) +{ + g->opts = xtables_merge_options(g->opts, t->extra_opts, &t->option_offset); +} + + +/* xtables api addons */ + +static inline void +xtables_option_mpcall(unsigned int c, char **argv, bool invert, + struct xtables_match *m, void *fw) +{ + if (m->parse) + m->parse(c - m->option_offset, argv, invert, &m->mflags, fw, &m->m); +} + +static inline void +xtables_option_mfcall(struct xtables_match *m) +{ + if (m->final_check) + m->final_check(m->mflags); +} + +static inline void +xtables_option_tpcall(unsigned int c, char **argv, bool invert, + struct xtables_target *t, void *fw) +{ + if (t->parse) + t->parse(c - t->option_offset, argv, invert, &t->tflags, fw, &t->t); +} + +static inline void +xtables_option_tfcall(struct xtables_target *t) +{ + if (t->final_check) + t->final_check(t->tflags); +} + +static inline void +xtables_rule_matches_free(struct xtables_rule_match **matches) +{ + struct xtables_rule_match *mp, *tmp; + + for (mp = *matches; mp;) + { + tmp = mp->next; + + if (mp->match->m) + { + free(mp->match->m); + mp->match->m = NULL; + } + + if (mp->match == mp->match->next) + { + free(mp->match); + mp->match = NULL; + } + + free(mp); + mp = tmp; + } + + *matches = NULL; +} + +static inline int +xtables_ipmask_to_cidr(const struct in_addr *mask) +{ + int bits; + uint32_t m; + + for (m = ntohl(mask->s_addr), bits = 0; m & 0x80000000; m <<= 1) + bits++; + + return bits; +} + +static inline int +xtables_ip6mask_to_cidr(const struct in6_addr *mask) +{ + int bits = 0; + uint32_t a, b, c, d; + + a = ntohl(mask->s6_addr32[0]); + b = ntohl(mask->s6_addr32[1]); + c = ntohl(mask->s6_addr32[2]); + d = ntohl(mask->s6_addr32[3]); + + while (a & 0x80000000U) + { + a <<= 1; + a |= (b >> 31) & 1; + b <<= 1; + b |= (c >> 31) & 1; + c <<= 1; + c |= (d >> 31) & 1; + d <<= 1; + + bits++; + } + + return bits; +} + +#endif -- 2.11.0