|
Packit Service |
e7ae83 |
/*
|
|
Packit Service |
e7ae83 |
* Copyright (c) 2013-2015 Pablo Neira Ayuso <pablo@netfilter.org>
|
|
Packit Service |
e7ae83 |
* Copyright (c) 2015 Arturo Borrero Gonzalez <arturo@debian.org>
|
|
Packit Service |
e7ae83 |
*
|
|
Packit Service |
e7ae83 |
* This program is free software; you can redistribute it and/or modifyi
|
|
Packit Service |
e7ae83 |
* it under the terms of the GNU General Public License version 2 as
|
|
Packit Service |
e7ae83 |
* published by the Free Software Foundation.
|
|
Packit Service |
e7ae83 |
*/
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
#include <stdlib.h>
|
|
Packit Service |
e7ae83 |
#include <time.h>
|
|
Packit Service |
e7ae83 |
#include <string.h>
|
|
Packit Service |
e7ae83 |
#include <net/if.h>
|
|
Packit Service |
e7ae83 |
#include <getopt.h>
|
|
Packit Service |
e7ae83 |
#include <ctype.h> /* for isspace */
|
|
Packit Service |
e7ae83 |
#include <statement.h>
|
|
Packit Service |
e7ae83 |
#include <netlink.h>
|
|
Packit Service |
e7ae83 |
#include <xt.h>
|
|
Packit Service |
e7ae83 |
#include <erec.h>
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
#include <libmnl/libmnl.h>
|
|
Packit Service |
e7ae83 |
#include <linux/netfilter/nfnetlink.h>
|
|
Packit Service |
e7ae83 |
#include <linux/netfilter/nf_tables_compat.h>
|
|
Packit Service |
e7ae83 |
#include <linux/netfilter_ipv4/ip_tables.h>
|
|
Packit Service |
e7ae83 |
#include <linux/netfilter_ipv6/ip6_tables.h>
|
|
Packit Service |
e7ae83 |
#include <linux/netfilter_arp/arp_tables.h>
|
|
Packit Service |
e7ae83 |
#include <linux/netfilter_bridge/ebtables.h>
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
#ifdef HAVE_LIBXTABLES
|
|
Packit Service |
e7ae83 |
#include <xtables.h>
|
|
Packit Service |
e7ae83 |
#endif
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
void xt_stmt_xlate(const struct stmt *stmt, struct output_ctx *octx)
|
|
Packit Service |
e7ae83 |
{
|
|
Packit Service |
e7ae83 |
#ifdef HAVE_LIBXTABLES
|
|
Packit Service |
e7ae83 |
struct xt_xlate *xl = xt_xlate_alloc(10240);
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
switch (stmt->xt.type) {
|
|
Packit Service |
e7ae83 |
case NFT_XT_MATCH:
|
|
Packit Service |
e7ae83 |
if (stmt->xt.match->xlate) {
|
|
Packit Service |
e7ae83 |
struct xt_xlate_mt_params params = {
|
|
Packit Service |
e7ae83 |
.ip = stmt->xt.entry,
|
|
Packit Service |
e7ae83 |
.match = stmt->xt.match->m,
|
|
Packit Service |
e7ae83 |
.numeric = 0,
|
|
Packit Service |
e7ae83 |
};
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
stmt->xt.match->xlate(xl, ¶ms);
|
|
Packit Service |
e7ae83 |
nft_print(octx, "%s", xt_xlate_get(xl));
|
|
Packit Service |
e7ae83 |
} else if (stmt->xt.match->print) {
|
|
Packit Service |
e7ae83 |
printf("#");
|
|
Packit Service |
e7ae83 |
stmt->xt.match->print(&stmt->xt.entry,
|
|
Packit Service |
e7ae83 |
stmt->xt.match->m, 0);
|
|
Packit Service |
e7ae83 |
}
|
|
Packit Service |
e7ae83 |
break;
|
|
Packit Service |
e7ae83 |
case NFT_XT_WATCHER:
|
|
Packit Service |
e7ae83 |
case NFT_XT_TARGET:
|
|
Packit Service |
e7ae83 |
if (stmt->xt.target->xlate) {
|
|
Packit Service |
e7ae83 |
struct xt_xlate_tg_params params = {
|
|
Packit Service |
e7ae83 |
.ip = stmt->xt.entry,
|
|
Packit Service |
e7ae83 |
.target = stmt->xt.target->t,
|
|
Packit Service |
e7ae83 |
.numeric = 0,
|
|
Packit Service |
e7ae83 |
};
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
stmt->xt.target->xlate(xl, ¶ms);
|
|
Packit Service |
e7ae83 |
nft_print(octx, "%s", xt_xlate_get(xl));
|
|
Packit Service |
e7ae83 |
} else if (stmt->xt.target->print) {
|
|
Packit Service |
e7ae83 |
printf("#");
|
|
Packit Service |
e7ae83 |
stmt->xt.target->print(NULL, stmt->xt.target->t, 0);
|
|
Packit Service |
e7ae83 |
}
|
|
Packit Service |
e7ae83 |
break;
|
|
Packit Service |
e7ae83 |
default:
|
|
Packit Service |
e7ae83 |
break;
|
|
Packit Service |
e7ae83 |
}
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
xt_xlate_free(xl);
|
|
Packit Service |
e7ae83 |
#else
|
|
Packit Service |
e7ae83 |
nft_print(octx, "# xt_%s", stmt->xt.name);
|
|
Packit Service |
e7ae83 |
#endif
|
|
Packit Service |
e7ae83 |
}
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
void xt_stmt_destroy(struct stmt *stmt)
|
|
Packit Service |
e7ae83 |
{
|
|
Packit Service |
e7ae83 |
#ifdef HAVE_LIBXTABLES
|
|
Packit Service |
e7ae83 |
switch (stmt->xt.type) {
|
|
Packit Service |
e7ae83 |
case NFT_XT_MATCH:
|
|
Packit Service |
e7ae83 |
if (!stmt->xt.match)
|
|
Packit Service |
e7ae83 |
break;
|
|
Packit Service |
e7ae83 |
if (stmt->xt.match->m)
|
|
Packit Service |
e7ae83 |
xfree(stmt->xt.match->m);
|
|
Packit Service |
e7ae83 |
xfree(stmt->xt.match);
|
|
Packit Service |
e7ae83 |
break;
|
|
Packit Service |
e7ae83 |
case NFT_XT_WATCHER:
|
|
Packit Service |
e7ae83 |
case NFT_XT_TARGET:
|
|
Packit Service |
e7ae83 |
if (!stmt->xt.target)
|
|
Packit Service |
e7ae83 |
break;
|
|
Packit Service |
e7ae83 |
if (stmt->xt.target->t)
|
|
Packit Service |
e7ae83 |
xfree(stmt->xt.target->t);
|
|
Packit Service |
e7ae83 |
xfree(stmt->xt.target);
|
|
Packit Service |
e7ae83 |
break;
|
|
Packit Service |
e7ae83 |
default:
|
|
Packit Service |
e7ae83 |
break;
|
|
Packit Service |
e7ae83 |
}
|
|
Packit Service |
e7ae83 |
#endif
|
|
Packit Service |
e7ae83 |
xfree(stmt->xt.entry);
|
|
Packit Service |
e7ae83 |
xfree(stmt->xt.name);
|
|
Packit Service |
e7ae83 |
}
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
#ifdef HAVE_LIBXTABLES
|
|
Packit Service |
e7ae83 |
static void *xt_entry_alloc(struct xt_stmt *xt, uint32_t af)
|
|
Packit Service |
e7ae83 |
{
|
|
Packit Service |
e7ae83 |
union nft_entry {
|
|
Packit Service |
e7ae83 |
struct ipt_entry ipt;
|
|
Packit Service |
e7ae83 |
struct ip6t_entry ip6t;
|
|
Packit Service |
e7ae83 |
struct arpt_entry arpt;
|
|
Packit Service |
e7ae83 |
struct ebt_entry ebt;
|
|
Packit Service |
e7ae83 |
} *entry;
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
entry = xmalloc(sizeof(union nft_entry));
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
switch (af) {
|
|
Packit Service |
e7ae83 |
case NFPROTO_IPV4:
|
|
Packit Service |
e7ae83 |
entry->ipt.ip.proto = xt->proto;
|
|
Packit Service |
e7ae83 |
break;
|
|
Packit Service |
e7ae83 |
case NFPROTO_IPV6:
|
|
Packit Service |
e7ae83 |
entry->ip6t.ipv6.proto = xt->proto;
|
|
Packit Service |
e7ae83 |
break;
|
|
Packit Service |
e7ae83 |
case NFPROTO_BRIDGE:
|
|
Packit Service |
e7ae83 |
entry->ebt.ethproto = xt->proto;
|
|
Packit Service |
e7ae83 |
break;
|
|
Packit Service |
e7ae83 |
case NFPROTO_ARP:
|
|
Packit Service |
e7ae83 |
entry->arpt.arp.arhln_mask = 0xff;
|
|
Packit Service |
e7ae83 |
entry->arpt.arp.arhln = 6;
|
|
Packit Service |
e7ae83 |
break;
|
|
Packit Service |
e7ae83 |
default:
|
|
Packit Service |
e7ae83 |
break;
|
|
Packit Service |
e7ae83 |
}
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
return entry;
|
|
Packit Service |
e7ae83 |
}
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
static uint32_t xt_proto(const struct proto_ctx *pctx)
|
|
Packit Service |
e7ae83 |
{
|
|
Packit Service |
e7ae83 |
const struct proto_desc *desc = NULL;
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
if (pctx->family == NFPROTO_BRIDGE) {
|
|
Packit Service |
e7ae83 |
desc = pctx->protocol[PROTO_BASE_NETWORK_HDR].desc;
|
|
Packit Service |
e7ae83 |
if (desc == NULL)
|
|
Packit Service |
e7ae83 |
return 0;
|
|
Packit Service |
e7ae83 |
if (strcmp(desc->name, "ip") == 0)
|
|
Packit Service |
e7ae83 |
return __constant_htons(ETH_P_IP);
|
|
Packit Service |
e7ae83 |
if (strcmp(desc->name, "ip6") == 0)
|
|
Packit Service |
e7ae83 |
return __constant_htons(ETH_P_IPV6);
|
|
Packit Service |
e7ae83 |
return 0;
|
|
Packit Service |
e7ae83 |
}
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
desc = pctx->protocol[PROTO_BASE_TRANSPORT_HDR].desc;
|
|
Packit Service |
e7ae83 |
if (desc == NULL)
|
|
Packit Service |
e7ae83 |
return 0;
|
|
Packit Service |
e7ae83 |
if (strcmp(desc->name, "tcp") == 0)
|
|
Packit Service |
e7ae83 |
return IPPROTO_TCP;
|
|
Packit Service |
e7ae83 |
else if (strcmp(desc->name, "udp") == 0)
|
|
Packit Service |
e7ae83 |
return IPPROTO_UDP;
|
|
Packit Service |
e7ae83 |
else if (strcmp(desc->name, "udplite") == 0)
|
|
Packit Service |
e7ae83 |
return IPPROTO_UDPLITE;
|
|
Packit Service |
e7ae83 |
else if (strcmp(desc->name, "sctp") == 0)
|
|
Packit Service |
e7ae83 |
return IPPROTO_SCTP;
|
|
Packit Service |
e7ae83 |
else if (strcmp(desc->name, "dccp") == 0)
|
|
Packit Service |
e7ae83 |
return IPPROTO_DCCP;
|
|
Packit Service |
e7ae83 |
else if (strcmp(desc->name, "esp") == 0)
|
|
Packit Service |
e7ae83 |
return IPPROTO_ESP;
|
|
Packit Service |
e7ae83 |
else if (strcmp(desc->name, "ah") == 0)
|
|
Packit Service |
e7ae83 |
return IPPROTO_AH;
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
return 0;
|
|
Packit Service |
e7ae83 |
}
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
static struct xtables_target *xt_target_clone(struct xtables_target *t)
|
|
Packit Service |
e7ae83 |
{
|
|
Packit Service |
e7ae83 |
struct xtables_target *clone;
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
clone = xzalloc(sizeof(struct xtables_target));
|
|
Packit Service |
e7ae83 |
memcpy(clone, t, sizeof(struct xtables_target));
|
|
Packit Service |
e7ae83 |
return clone;
|
|
Packit Service |
e7ae83 |
}
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
static struct xtables_match *xt_match_clone(struct xtables_match *m)
|
|
Packit Service |
e7ae83 |
{
|
|
Packit Service |
e7ae83 |
struct xtables_match *clone;
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
clone = xzalloc(sizeof(struct xtables_match));
|
|
Packit Service |
e7ae83 |
memcpy(clone, m, sizeof(struct xtables_match));
|
|
Packit Service |
e7ae83 |
return clone;
|
|
Packit Service |
e7ae83 |
}
|
|
Packit Service |
e7ae83 |
#endif
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
/*
|
|
Packit Service |
e7ae83 |
* Delinearization
|
|
Packit Service |
e7ae83 |
*/
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
void netlink_parse_match(struct netlink_parse_ctx *ctx,
|
|
Packit Service |
e7ae83 |
const struct location *loc,
|
|
Packit Service |
e7ae83 |
const struct nftnl_expr *nle)
|
|
Packit Service |
e7ae83 |
{
|
|
Packit Service |
e7ae83 |
struct stmt *stmt;
|
|
Packit Service |
e7ae83 |
const char *name;
|
|
Packit Service |
e7ae83 |
#ifdef HAVE_LIBXTABLES
|
|
Packit Service |
e7ae83 |
struct xtables_match *mt;
|
|
Packit Service |
e7ae83 |
const char *mtinfo;
|
|
Packit Service |
e7ae83 |
struct xt_entry_match *m;
|
|
Packit Service |
e7ae83 |
uint32_t mt_len;
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
xtables_set_nfproto(ctx->table->handle.family);
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
name = nftnl_expr_get_str(nle, NFTNL_EXPR_MT_NAME);
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
mt = xtables_find_match(name, XTF_TRY_LOAD, NULL);
|
|
Packit Service |
e7ae83 |
if (!mt) {
|
|
Packit Service |
e7ae83 |
fprintf(stderr, "XT match %s not found\n", name);
|
|
Packit Service |
e7ae83 |
return;
|
|
Packit Service |
e7ae83 |
}
|
|
Packit Service |
e7ae83 |
mtinfo = nftnl_expr_get(nle, NFTNL_EXPR_MT_INFO, &mt_len);
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
m = xzalloc(sizeof(struct xt_entry_match) + mt_len);
|
|
Packit Service |
e7ae83 |
memcpy(&m->data, mtinfo, mt_len);
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
m->u.match_size = mt_len + XT_ALIGN(sizeof(struct xt_entry_match));
|
|
Packit Service |
e7ae83 |
m->u.user.revision = nftnl_expr_get_u32(nle, NFTNL_EXPR_MT_REV);
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
stmt = xt_stmt_alloc(loc);
|
|
Packit Service |
e7ae83 |
stmt->xt.name = strdup(name);
|
|
Packit Service |
e7ae83 |
stmt->xt.type = NFT_XT_MATCH;
|
|
Packit Service |
e7ae83 |
stmt->xt.match = xt_match_clone(mt);
|
|
Packit Service |
e7ae83 |
stmt->xt.match->m = m;
|
|
Packit Service |
e7ae83 |
#else
|
|
Packit Service |
e7ae83 |
name = nftnl_expr_get_str(nle, NFTNL_EXPR_MT_NAME);
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
stmt = xt_stmt_alloc(loc);
|
|
Packit Service |
e7ae83 |
stmt->xt.name = strdup(name);
|
|
Packit Service |
e7ae83 |
stmt->xt.type = NFT_XT_MATCH;
|
|
Packit Service |
e7ae83 |
#endif
|
|
Packit Service |
e7ae83 |
list_add_tail(&stmt->list, &ctx->rule->stmts);
|
|
Packit Service |
e7ae83 |
}
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
void netlink_parse_target(struct netlink_parse_ctx *ctx,
|
|
Packit Service |
e7ae83 |
const struct location *loc,
|
|
Packit Service |
e7ae83 |
const struct nftnl_expr *nle)
|
|
Packit Service |
e7ae83 |
{
|
|
Packit Service |
e7ae83 |
struct stmt *stmt;
|
|
Packit Service |
e7ae83 |
const char *name;
|
|
Packit Service |
e7ae83 |
#ifdef HAVE_LIBXTABLES
|
|
Packit Service |
e7ae83 |
struct xtables_target *tg;
|
|
Packit Service |
e7ae83 |
const void *tginfo;
|
|
Packit Service |
e7ae83 |
struct xt_entry_target *t;
|
|
Packit Service |
e7ae83 |
size_t size;
|
|
Packit Service |
e7ae83 |
uint32_t tg_len;
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
xtables_set_nfproto(ctx->table->handle.family);
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
name = nftnl_expr_get_str(nle, NFTNL_EXPR_TG_NAME);
|
|
Packit Service |
e7ae83 |
tg = xtables_find_target(name, XTF_TRY_LOAD);
|
|
Packit Service |
e7ae83 |
if (!tg) {
|
|
Packit Service |
e7ae83 |
fprintf(stderr, "XT target %s not found\n", name);
|
|
Packit Service |
e7ae83 |
return;
|
|
Packit Service |
e7ae83 |
}
|
|
Packit Service |
e7ae83 |
tginfo = nftnl_expr_get(nle, NFTNL_EXPR_TG_INFO, &tg_len);
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
size = XT_ALIGN(sizeof(struct xt_entry_target)) + tg_len;
|
|
Packit Service |
e7ae83 |
t = xzalloc(size);
|
|
Packit Service |
e7ae83 |
memcpy(&t->data, tginfo, tg_len);
|
|
Packit Service |
e7ae83 |
t->u.target_size = size;
|
|
Packit Service |
e7ae83 |
t->u.user.revision = nftnl_expr_get_u32(nle, NFTNL_EXPR_TG_REV);
|
|
Packit Service |
e7ae83 |
strcpy(t->u.user.name, tg->name);
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
stmt = xt_stmt_alloc(loc);
|
|
Packit Service |
e7ae83 |
stmt->xt.name = strdup(name);
|
|
Packit Service |
e7ae83 |
stmt->xt.type = NFT_XT_TARGET;
|
|
Packit Service |
e7ae83 |
stmt->xt.target = xt_target_clone(tg);
|
|
Packit Service |
e7ae83 |
stmt->xt.target->t = t;
|
|
Packit Service |
e7ae83 |
#else
|
|
Packit Service |
e7ae83 |
name = nftnl_expr_get_str(nle, NFTNL_EXPR_TG_NAME);
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
stmt = xt_stmt_alloc(loc);
|
|
Packit Service |
e7ae83 |
stmt->xt.name = strdup(name);
|
|
Packit Service |
e7ae83 |
stmt->xt.type = NFT_XT_TARGET;
|
|
Packit Service |
e7ae83 |
#endif
|
|
Packit Service |
e7ae83 |
list_add_tail(&stmt->list, &ctx->rule->stmts);
|
|
Packit Service |
e7ae83 |
}
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
#ifdef HAVE_LIBXTABLES
|
|
Packit Service |
e7ae83 |
static bool is_watcher(uint32_t family, struct stmt *stmt)
|
|
Packit Service |
e7ae83 |
{
|
|
Packit Service |
e7ae83 |
if (family != NFPROTO_BRIDGE ||
|
|
Packit Service |
e7ae83 |
stmt->xt.type != NFT_XT_TARGET)
|
|
Packit Service |
e7ae83 |
return false;
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
/* this has to be hardcoded :-( */
|
|
Packit Service |
e7ae83 |
if (strcmp(stmt->xt.name, "log") == 0)
|
|
Packit Service |
e7ae83 |
return true;
|
|
Packit Service |
e7ae83 |
else if (strcmp(stmt->xt.name, "nflog") == 0)
|
|
Packit Service |
e7ae83 |
return true;
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
return false;
|
|
Packit Service |
e7ae83 |
}
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
void stmt_xt_postprocess(struct rule_pp_ctx *rctx, struct stmt *stmt,
|
|
Packit Service |
e7ae83 |
struct rule *rule)
|
|
Packit Service |
e7ae83 |
{
|
|
Packit Service |
e7ae83 |
if (is_watcher(rctx->pctx.family, stmt))
|
|
Packit Service |
e7ae83 |
stmt->xt.type = NFT_XT_WATCHER;
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
stmt->xt.proto = xt_proto(&rctx->pctx);
|
|
Packit Service |
e7ae83 |
stmt->xt.entry = xt_entry_alloc(&stmt->xt, rctx->pctx.family);
|
|
Packit Service |
e7ae83 |
}
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
static int nft_xt_compatible_revision(const char *name, uint8_t rev, int opt)
|
|
Packit Service |
e7ae83 |
{
|
|
Packit Service |
e7ae83 |
struct mnl_socket *nl;
|
|
Packit Service |
e7ae83 |
char buf[MNL_SOCKET_BUFFER_SIZE];
|
|
Packit Service |
e7ae83 |
struct nlmsghdr *nlh;
|
|
Packit Service |
e7ae83 |
uint32_t portid, seq, type, family;
|
|
Packit Service |
e7ae83 |
struct nfgenmsg *nfg;
|
|
Packit Service |
e7ae83 |
int ret = 0;
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
switch (rev) {
|
|
Packit Service |
e7ae83 |
case IPT_SO_GET_REVISION_MATCH:
|
|
Packit Service |
e7ae83 |
family = NFPROTO_IPV4;
|
|
Packit Service |
e7ae83 |
type = 0;
|
|
Packit Service |
e7ae83 |
break;
|
|
Packit Service |
e7ae83 |
case IPT_SO_GET_REVISION_TARGET:
|
|
Packit Service |
e7ae83 |
family = NFPROTO_IPV4;
|
|
Packit Service |
e7ae83 |
type = 1;
|
|
Packit Service |
e7ae83 |
break;
|
|
Packit Service |
e7ae83 |
case IP6T_SO_GET_REVISION_MATCH:
|
|
Packit Service |
e7ae83 |
family = NFPROTO_IPV6;
|
|
Packit Service |
e7ae83 |
type = 0;
|
|
Packit Service |
e7ae83 |
break;
|
|
Packit Service |
e7ae83 |
case IP6T_SO_GET_REVISION_TARGET:
|
|
Packit Service |
e7ae83 |
family = NFPROTO_IPV6;
|
|
Packit Service |
e7ae83 |
type = 1;
|
|
Packit Service |
e7ae83 |
break;
|
|
Packit Service |
e7ae83 |
default: /* No revision support, assume ok */
|
|
Packit Service |
e7ae83 |
return 1;
|
|
Packit Service |
e7ae83 |
}
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
nlh = mnl_nlmsg_put_header(buf);
|
|
Packit Service |
e7ae83 |
nlh->nlmsg_type = (NFNL_SUBSYS_NFT_COMPAT << 8) | NFNL_MSG_COMPAT_GET;
|
|
Packit Service |
e7ae83 |
nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
|
|
Packit Service |
e7ae83 |
nlh->nlmsg_seq = seq = time(NULL);
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg));
|
|
Packit Service |
e7ae83 |
nfg->nfgen_family = family;
|
|
Packit Service |
e7ae83 |
nfg->version = NFNETLINK_V0;
|
|
Packit Service |
e7ae83 |
nfg->res_id = 0;
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
mnl_attr_put_strz(nlh, NFTA_COMPAT_NAME, name);
|
|
Packit Service |
e7ae83 |
mnl_attr_put_u32(nlh, NFTA_COMPAT_REV, htonl(rev));
|
|
Packit Service |
e7ae83 |
mnl_attr_put_u32(nlh, NFTA_COMPAT_TYPE, htonl(type));
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
nl = mnl_socket_open(NETLINK_NETFILTER);
|
|
Packit Service |
e7ae83 |
if (nl == NULL)
|
|
Packit Service |
e7ae83 |
return 0;
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0)
|
|
Packit Service |
e7ae83 |
goto err;
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
portid = mnl_socket_get_portid(nl);
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0)
|
|
Packit Service |
e7ae83 |
goto err;
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
|
|
Packit Service |
e7ae83 |
if (ret == -1)
|
|
Packit Service |
e7ae83 |
goto err;
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
ret = mnl_cb_run(buf, ret, seq, portid, NULL, NULL);
|
|
Packit Service |
e7ae83 |
if (ret == -1)
|
|
Packit Service |
e7ae83 |
goto err;
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
err:
|
|
Packit Service |
e7ae83 |
mnl_socket_close(nl);
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
return ret < 0 ? 0 : 1;
|
|
Packit Service |
e7ae83 |
}
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
static struct option original_opts[] = {
|
|
Packit Service |
e7ae83 |
{ NULL },
|
|
Packit Service |
e7ae83 |
};
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
static struct xtables_globals xt_nft_globals = {
|
|
Packit Service |
e7ae83 |
.program_name = "nft",
|
|
Packit Service |
e7ae83 |
.program_version = PACKAGE_VERSION,
|
|
Packit Service |
e7ae83 |
.orig_opts = original_opts,
|
|
Packit Service |
e7ae83 |
.compat_rev = nft_xt_compatible_revision,
|
|
Packit Service |
e7ae83 |
};
|
|
Packit Service |
e7ae83 |
|
|
Packit Service |
e7ae83 |
void xt_init(void)
|
|
Packit Service |
e7ae83 |
{
|
|
Packit Service |
e7ae83 |
/* Default to IPv4, but this changes in runtime */
|
|
Packit Service |
e7ae83 |
xtables_init_all(&xt_nft_globals, NFPROTO_IPV4);
|
|
Packit Service |
e7ae83 |
}
|
|
Packit Service |
e7ae83 |
#endif
|