summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2018-04-11 10:24:37 +0200
committerFlorian Westphal <fw@strlen.de>2018-04-11 10:51:46 +0200
commit03ecffe6c2cc0c71f5ece161d39368d56930e241 (patch)
tree1c6ab0aacf902c707004b27000a5a586df6ba3b0
parent57af67de905c9f68b9f011b9a7cfcff12ada8012 (diff)
ebtables-compat: add initial translations
add translations for ip, limit, log, mark, mark_m, nflog. Signed-off-by: Florian Westphal <fw@strlen.de>
-rw-r--r--extensions/libebt_ip.c128
-rw-r--r--extensions/libebt_limit.c26
-rw-r--r--extensions/libebt_log.c22
-rw-r--r--extensions/libebt_mark.c44
-rw-r--r--extensions/libebt_mark_m.c25
-rw-r--r--extensions/libebt_nflog.c25
6 files changed, 270 insertions, 0 deletions
diff --git a/extensions/libebt_ip.c b/extensions/libebt_ip.c
index 4ca63e93..1a87585c 100644
--- a/extensions/libebt_ip.c
+++ b/extensions/libebt_ip.c
@@ -291,6 +291,133 @@ static void brip_print(const void *ip, const struct xt_entry_match *match,
}
}
+static const char *brip_xlate_proto_to_name(uint8_t proto)
+{
+ switch (proto) {
+ case IPPROTO_TCP:
+ return "tcp";
+ case IPPROTO_UDP:
+ return "udp";
+ case IPPROTO_UDPLITE:
+ return "udplite";
+ case IPPROTO_SCTP:
+ return "sctp";
+ case IPPROTO_DCCP:
+ return "dccp";
+ default:
+ return NULL;
+ }
+}
+
+static void brip_xlate_th(struct xt_xlate *xl,
+ const struct ebt_ip_info *info, int bit,
+ const char *pname)
+{
+ const uint16_t *ports;
+
+ if ((info->bitmask & bit) == 0)
+ return;
+
+ switch (bit) {
+ case EBT_IP_SPORT:
+ if (pname)
+ xt_xlate_add(xl, "%s sport ", pname);
+ else
+ xt_xlate_add(xl, "@th,0,16 ");
+
+ ports = info->sport;
+ break;
+ case EBT_IP_DPORT:
+ if (pname)
+ xt_xlate_add(xl, "%s dport ", pname);
+ else
+ xt_xlate_add(xl, "@th,16,16 ");
+
+ ports = info->dport;
+ break;
+ default:
+ return;
+ }
+
+ if (info->invflags & bit)
+ xt_xlate_add(xl, "!= ");
+
+ if (ports[0] == ports[1])
+ xt_xlate_add(xl, "%d ", ports[0]);
+ else
+ xt_xlate_add(xl, "%d-%d ", ports[0], ports[1]);
+}
+
+static void brip_xlate_nh(struct xt_xlate *xl,
+ const struct ebt_ip_info *info, int bit)
+{
+ struct in_addr *addrp, *maskp;
+
+ if ((info->bitmask & bit) == 0)
+ return;
+
+ switch (bit) {
+ case EBT_IP_SOURCE:
+ xt_xlate_add(xl, "ip saddr ");
+ addrp = (struct in_addr *)&info->saddr;
+ maskp = (struct in_addr *)&info->smsk;
+ break;
+ case EBT_IP_DEST:
+ xt_xlate_add(xl, "ip daddr ");
+ addrp = (struct in_addr *)&info->daddr;
+ maskp = (struct in_addr *)&info->dmsk;
+ break;
+ default:
+ return;
+ }
+
+ if (info->invflags & bit)
+ xt_xlate_add(xl, "!= ");
+
+ xt_xlate_add(xl, "%s%s ", xtables_ipaddr_to_numeric(addrp),
+ xtables_ipmask_to_numeric(maskp));
+}
+
+static int brip_xlate(struct xt_xlate *xl,
+ const struct xt_xlate_mt_params *params)
+{
+ const struct ebt_ip_info *info = (const void *)params->match->data;
+ const char *pname = NULL;
+
+ brip_xlate_nh(xl, info, EBT_IP_SOURCE);
+ brip_xlate_nh(xl, info, EBT_IP_DEST);
+
+ if (info->bitmask & EBT_IP_TOS) {
+ xt_xlate_add(xl, "ip dscp ");
+ if (info->invflags & EBT_IP_TOS)
+ xt_xlate_add(xl, "!= ");
+ xt_xlate_add(xl, "0x%02X ", info->tos & ~0x3); /* remove ECN bits */
+ }
+ if (info->bitmask & EBT_IP_PROTO) {
+ struct protoent *pe;
+
+ if (info->bitmask & (EBT_IP_SPORT|EBT_IP_DPORT) &&
+ (info->invflags & EBT_IP_PROTO) == 0) {
+ /* port number given and not inverted, no need to print this */
+ pname = brip_xlate_proto_to_name(info->protocol);
+ } else {
+ xt_xlate_add(xl, "ip protocol ");
+ if (info->invflags & EBT_IP_PROTO)
+ xt_xlate_add(xl, "!= ");
+ pe = getprotobynumber(info->protocol);
+ if (pe == NULL)
+ xt_xlate_add(xl, "%d ", info->protocol);
+ else
+ xt_xlate_add(xl, "%s ", pe->p_name);
+ }
+ }
+
+ brip_xlate_th(xl, info, EBT_IP_SPORT, pname);
+ brip_xlate_th(xl, info, EBT_IP_DPORT, pname);
+
+ return 1;
+}
+
static struct xtables_match brip_match = {
.name = "ip",
.revision = 0,
@@ -303,6 +430,7 @@ static struct xtables_match brip_match = {
.parse = brip_parse,
.final_check = brip_final_check,
.print = brip_print,
+ .xlate = brip_xlate,
.extra_opts = brip_opts,
};
diff --git a/extensions/libebt_limit.c b/extensions/libebt_limit.c
index 988f678a..75c066bf 100644
--- a/extensions/libebt_limit.c
+++ b/extensions/libebt_limit.c
@@ -159,6 +159,31 @@ static void brlimit_print(const void *ip, const struct xt_entry_match *match,
printf("--limit-burst %u ", r->burst);
}
+static void print_rate_xlate(struct xt_xlate *xl, uint32_t period)
+{
+ unsigned int i;
+
+ for (i = 1; i < sizeof(g_rates)/sizeof(struct rates); i++)
+ if (period > g_rates[i].mult ||
+ g_rates[i].mult/period < g_rates[i].mult%period)
+ break;
+
+ xt_xlate_add(xl, "%u/%s ", g_rates[i-1].mult / period, g_rates[i-1].name);
+}
+
+static int brlimit_xlate(struct xt_xlate *xl,
+ const struct xt_xlate_mt_params *params)
+{
+ const struct ebt_limit_info *r = (const void *)params->match->data;
+
+ xt_xlate_add(xl, "limit rate ");
+ print_rate_xlate(xl, r->avg);
+ if (r->burst != 0)
+ xt_xlate_add(xl, " burst %u packets", r->burst);
+
+ return 1;
+}
+
static struct xtables_match brlimit_match = {
.name = "limit",
.revision = 0,
@@ -170,6 +195,7 @@ static struct xtables_match brlimit_match = {
.help = brlimit_print_help,
.parse = brlimit_parse,
.print = brlimit_print,
+ .xlate = brlimit_xlate,
.extra_opts = brlimit_opts,
};
diff --git a/extensions/libebt_log.c b/extensions/libebt_log.c
index f170af03..a86bdeba 100644
--- a/extensions/libebt_log.c
+++ b/extensions/libebt_log.c
@@ -176,6 +176,27 @@ static void brlog_print(const void *ip, const struct xt_entry_target *target,
printf(" ");
}
+static int brlog_xlate(struct xt_xlate *xl,
+ const struct xt_xlate_tg_params *params)
+{
+ const struct ebt_log_info *loginfo = (const void *)params->target->data;
+
+ xt_xlate_add(xl, "log");
+ if (loginfo->prefix[0]) {
+ if (params->escape_quotes)
+ xt_xlate_add(xl, " prefix \\\"%s\\\"", loginfo->prefix);
+ else
+ xt_xlate_add(xl, " prefix \"%s\"", loginfo->prefix);
+ }
+
+ if (loginfo->loglevel != LOG_DEFAULT_LEVEL)
+ xt_xlate_add(xl, " level %s", eight_priority[loginfo->loglevel].c_name);
+
+ xt_xlate_add(xl, " flags ether ");
+
+ return 1;
+}
+
static struct xtables_target brlog_target = {
.name = "log",
.revision = 0,
@@ -188,6 +209,7 @@ static struct xtables_target brlog_target = {
.parse = brlog_parse,
.final_check = brlog_final_check,
.print = brlog_print,
+ .xlate = brlog_xlate,
.extra_opts = brlog_opts,
};
diff --git a/extensions/libebt_mark.c b/extensions/libebt_mark.c
index 7b80b22e..94f489e3 100644
--- a/extensions/libebt_mark.c
+++ b/extensions/libebt_mark.c
@@ -170,6 +170,49 @@ static void brmark_final_check(unsigned int flags)
"You must specify some option");
}
+static const char* brmark_verdict(int verdict)
+{
+ switch (verdict) {
+ case EBT_ACCEPT: return "accept";
+ case EBT_DROP: return "drop";
+ case EBT_CONTINUE: return "continue";
+ case EBT_RETURN: return "return";
+ }
+
+ return "";
+}
+
+static int brmark_xlate(struct xt_xlate *xl,
+ const struct xt_xlate_tg_params *params)
+{
+ const struct ebt_mark_t_info *info = (const void*)params->target->data;
+ int tmp;
+
+ tmp = info->target & ~EBT_VERDICT_BITS;
+
+ xt_xlate_add(xl, "meta mark set ");
+
+ switch (tmp) {
+ case MARK_SET_VALUE:
+ break;
+ case MARK_OR_VALUE:
+ xt_xlate_add(xl, "meta mark or ");
+ break;
+ case MARK_XOR_VALUE:
+ xt_xlate_add(xl, "meta mark xor ");
+ break;
+ case MARK_AND_VALUE:
+ xt_xlate_add(xl, "meta mark and ");
+ break;
+ default:
+ return 0;
+ }
+
+ tmp = info->target & EBT_VERDICT_BITS;
+ xt_xlate_add(xl, "0x%lx %s ", info->mark, brmark_verdict(tmp));
+ return 1;
+}
+
static struct xtables_target brmark_target = {
.name = "mark",
.revision = 0,
@@ -182,6 +225,7 @@ static struct xtables_target brmark_target = {
.parse = brmark_parse,
.final_check = brmark_final_check,
.print = brmark_print,
+ .xlate = brmark_xlate,
.extra_opts = brmark_opts,
};
diff --git a/extensions/libebt_mark_m.c b/extensions/libebt_mark_m.c
index eb08dbab..1e8d21db 100644
--- a/extensions/libebt_mark_m.c
+++ b/extensions/libebt_mark_m.c
@@ -97,6 +97,30 @@ static void brmark_m_print(const void *ip, const struct xt_entry_match *match,
printf("0x%lx ", info->mark);
}
+static int brmark_m_xlate(struct xt_xlate *xl,
+ const struct xt_xlate_mt_params *params)
+{
+ const struct ebt_mark_m_info *info = (const void*)params->match->data;
+ enum xt_op op = XT_OP_EQ;
+
+ if (info->invert)
+ op = XT_OP_NEQ;
+
+ xt_xlate_add(xl, "meta mark ");
+
+ if (info->bitmask == EBT_MARK_OR) {
+ xt_xlate_add(xl, " and %0x%x %s0", info->mask,
+ info->invert ? "" : "!= ");
+ } else if (info->mask != 0xffffffffU) {
+ xt_xlate_add(xl, " and 0x%x %s 0x%x", info->mask,
+ op == XT_OP_EQ ? "==" : "!=", info->mark);
+ } else {
+ xt_xlate_add(xl, " %s0x%x",
+ op == XT_OP_EQ ? "" : "!= ", info->mark);
+ }
+
+ return 1;
+}
static struct xtables_match brmark_m_match = {
.name = "mark_m",
.revision = 0,
@@ -109,6 +133,7 @@ static struct xtables_match brmark_m_match = {
.parse = brmark_m_parse,
.final_check = brmark_m_final_check,
.print = brmark_m_print,
+ .xlate = brmark_m_xlate,
.extra_opts = brmark_m_opts,
};
diff --git a/extensions/libebt_nflog.c b/extensions/libebt_nflog.c
index 5f1d13b1..57f09291 100644
--- a/extensions/libebt_nflog.c
+++ b/extensions/libebt_nflog.c
@@ -124,6 +124,30 @@ brnflog_print(const void *ip, const struct xt_entry_target *target,
printf("--nflog-threshold %d ", info->threshold);
}
+static int brnflog_xlate(struct xt_xlate *xl,
+ const struct xt_xlate_tg_params *params)
+{
+ const struct ebt_nflog_info *info = (void *)params->target->data;
+
+ xt_xlate_add(xl, "log ");
+ if (info->prefix[0] != '\0') {
+ if (params->escape_quotes)
+ xt_xlate_add(xl, "prefix \\\"%s\\\" ", info->prefix);
+ else
+ xt_xlate_add(xl, "prefix \"%s\" ", info->prefix);
+
+ }
+
+ xt_xlate_add(xl, "group %u ", info->group);
+
+ if (info->len)
+ xt_xlate_add(xl, "snaplen %u ", info->len);
+ if (info->threshold != EBT_NFLOG_DEFAULT_THRESHOLD)
+ xt_xlate_add(xl, "queue-threshold %u ", info->threshold);
+
+ return 1;
+}
+
static struct xtables_target brnflog_watcher = {
.name = "nflog",
.revision = 0,
@@ -135,6 +159,7 @@ static struct xtables_target brnflog_watcher = {
.help = brnflog_help,
.parse = brnflog_parse,
.print = brnflog_print,
+ .xlate = brnflog_xlate,
.extra_opts = brnflog_opts,
};