Commit 268c6aa1 authored by Arturo Borrero Gonzalez's avatar Arturo Borrero Gonzalez
Browse files

Merge tag 'debian/1.8.5-3' into debian/buster-backports



Debian package 1.8.5-3
Signed-off-by: default avatarArturo Borrero Gonzalez <arturo@debian.org>
parents ada8a2c9 9fa0e185
#!/bin/bash
[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; }
# make sure none of the commands invoking nft_xt_builtin_init() override
# non-default chain policies via needless chain add.
RC=0
do_test() {
$XT_MULTI $@
$XT_MULTI iptables -S | grep -q -- '-P FORWARD DROP' && return
echo "command '$@' kills chain policies"
$XT_MULTI iptables -P FORWARD DROP
RC=1
}
$XT_MULTI iptables -P FORWARD DROP
do_test iptables -A OUTPUT -j ACCEPT
do_test iptables -F
do_test iptables -N foo
do_test iptables -E foo foo2
do_test iptables -I OUTPUT -j ACCEPT
do_test iptables -nL
do_test iptables -S
exit $RC
...@@ -181,7 +181,6 @@ int command_default(struct iptables_command_state *cs, ...@@ -181,7 +181,6 @@ int command_default(struct iptables_command_state *cs,
xtables_error(PARAMETER_PROBLEM, "unknown option " xtables_error(PARAMETER_PROBLEM, "unknown option "
"\"%s\"", cs->argv[optind-1]); "\"%s\"", cs->argv[optind-1]);
xtables_error(PARAMETER_PROBLEM, "Unknown arg \"%s\"", optarg); xtables_error(PARAMETER_PROBLEM, "Unknown arg \"%s\"", optarg);
return 0;
} }
static mainfunc_t subcmd_get(const char *cmd, const struct subcommand *cb) static mainfunc_t subcmd_get(const char *cmd, const struct subcommand *cb)
...@@ -374,6 +373,43 @@ int parse_counters(const char *string, struct xt_counters *ctr) ...@@ -374,6 +373,43 @@ int parse_counters(const char *string, struct xt_counters *ctr)
return ret == 2; return ret == 2;
} }
/* Tokenize counters argument of typical iptables-restore format rule.
*
* If *bufferp contains counters, update *pcntp and *bcntp to point at them,
* change bytes after counters in *bufferp to nul-bytes, update *bufferp to
* point to after the counters and return true.
* If *bufferp does not contain counters, return false.
* If syntax is wrong in *bufferp, call xtables_error() and hence exit().
* */
bool tokenize_rule_counters(char **bufferp, char **pcntp, char **bcntp, int line)
{
char *ptr, *buffer = *bufferp, *pcnt, *bcnt;
if (buffer[0] != '[')
return false;
/* we have counters in our input */
ptr = strchr(buffer, ']');
if (!ptr)
xtables_error(PARAMETER_PROBLEM, "Bad line %u: need ]\n", line);
pcnt = strtok(buffer+1, ":");
if (!pcnt)
xtables_error(PARAMETER_PROBLEM, "Bad line %u: need :\n", line);
bcnt = strtok(NULL, "]");
if (!bcnt)
xtables_error(PARAMETER_PROBLEM, "Bad line %u: need ]\n", line);
*pcntp = pcnt;
*bcntp = bcnt;
/* start command parsing after counter */
*bufferp = ptr + 1;
return true;
}
inline bool xs_has_arg(int argc, char *argv[]) inline bool xs_has_arg(int argc, char *argv[])
{ {
return optind < argc && return optind < argc &&
...@@ -381,56 +417,48 @@ inline bool xs_has_arg(int argc, char *argv[]) ...@@ -381,56 +417,48 @@ inline bool xs_has_arg(int argc, char *argv[])
argv[optind][0] != '!'; argv[optind][0] != '!';
} }
/* global new argv and argc */ /* function adding one argument to store, updating argc
char *newargv[255]; * returns if argument added, does not return otherwise */
int newargc = 0; void add_argv(struct argv_store *store, const char *what, int quoted)
/* saved newargv and newargc from save_argv() */
char *oldargv[255];
int oldargc = 0;
/* arg meta data, were they quoted, frinstance */
int newargvattr[255];
/* function adding one argument to newargv, updating newargc
* returns true if argument added, false otherwise */
int add_argv(const char *what, int quoted)
{ {
DEBUGP("add_argv: %s\n", what); DEBUGP("add_argv: %s\n", what);
if (what && newargc + 1 < ARRAY_SIZE(newargv)) {
newargv[newargc] = strdup(what); if (store->argc + 1 >= MAX_ARGC)
newargvattr[newargc] = quoted;
newargv[++newargc] = NULL;
return 1;
} else {
xtables_error(PARAMETER_PROBLEM, xtables_error(PARAMETER_PROBLEM,
"Parser cannot handle more arguments\n"); "Parser cannot handle more arguments\n");
} if (!what)
xtables_error(PARAMETER_PROBLEM,
"Trying to store NULL argument\n");
store->argv[store->argc] = strdup(what);
store->argvattr[store->argc] = quoted;
store->argv[++store->argc] = NULL;
} }
void free_argv(void) void free_argv(struct argv_store *store)
{ {
while (newargc) while (store->argc) {
free(newargv[--newargc]); store->argc--;
while (oldargc) free(store->argv[store->argc]);
free(oldargv[--oldargc]); store->argvattr[store->argc] = 0;
}
} }
/* Save parsed rule for comparison with next rule to perform action aggregation /* Save parsed rule for comparison with next rule to perform action aggregation
* on duplicate conditions. * on duplicate conditions.
*/ */
void save_argv(void) void save_argv(struct argv_store *dst, struct argv_store *src)
{ {
unsigned int i; int i;
while (oldargc)
free(oldargv[--oldargc]);
oldargc = newargc; free_argv(dst);
newargc = 0; for (i = 0; i < src->argc; i++) {
for (i = 0; i < oldargc; i++) { dst->argvattr[i] = src->argvattr[i];
oldargv[i] = newargv[i]; dst->argv[i] = src->argv[i];
src->argv[i] = NULL;
} }
dst->argc = src->argc;
src->argc = 0;
} }
struct xt_param_buf { struct xt_param_buf {
...@@ -446,9 +474,9 @@ static void add_param(struct xt_param_buf *param, const char *curchar) ...@@ -446,9 +474,9 @@ static void add_param(struct xt_param_buf *param, const char *curchar)
"Parameter too long!"); "Parameter too long!");
} }
void add_param_to_argv(char *parsestart, int line) void add_param_to_argv(struct argv_store *store, char *parsestart, int line)
{ {
int quote_open = 0, escaped = 0; int quote_open = 0, escaped = 0, quoted = 0;
struct xt_param_buf param = {}; struct xt_param_buf param = {};
char *curchar; char *curchar;
...@@ -467,7 +495,6 @@ void add_param_to_argv(char *parsestart, int line) ...@@ -467,7 +495,6 @@ void add_param_to_argv(char *parsestart, int line)
continue; continue;
} else if (*curchar == '"') { } else if (*curchar == '"') {
quote_open = 0; quote_open = 0;
*curchar = '"';
} else { } else {
add_param(&param, curchar); add_param(&param, curchar);
continue; continue;
...@@ -475,6 +502,7 @@ void add_param_to_argv(char *parsestart, int line) ...@@ -475,6 +502,7 @@ void add_param_to_argv(char *parsestart, int line)
} else { } else {
if (*curchar == '"') { if (*curchar == '"') {
quote_open = 1; quote_open = 1;
quoted = 1;
continue; continue;
} }
} }
...@@ -497,22 +525,25 @@ void add_param_to_argv(char *parsestart, int line) ...@@ -497,22 +525,25 @@ void add_param_to_argv(char *parsestart, int line)
} }
param.buffer[param.len] = '\0'; param.buffer[param.len] = '\0';
add_argv(store, param.buffer, quoted);
/* check if table name specified */
if ((param.buffer[0] == '-' &&
param.buffer[1] != '-' &&
strchr(param.buffer, 't')) ||
(!strncmp(param.buffer, "--t", 3) &&
!strncmp(param.buffer, "--table", strlen(param.buffer)))) {
xtables_error(PARAMETER_PROBLEM,
"The -t option (seen in line %u) cannot be used in %s.\n",
line, xt_params->program_name);
}
add_argv(param.buffer, 0);
param.len = 0; param.len = 0;
quoted = 0;
} }
if (param.len) {
param.buffer[param.len] = '\0';
add_argv(store, param.buffer, 0);
}
}
#ifdef DEBUG
void debug_print_argv(struct argv_store *store)
{
int i;
for (i = 0; i < store->argc; i++)
fprintf(stderr, "argv[%d]: %s\n", i, store->argv[i]);
} }
#endif
static const char *ipv4_addr_to_string(const struct in_addr *addr, static const char *ipv4_addr_to_string(const struct in_addr *addr,
const struct in_addr *mask, const struct in_addr *mask,
...@@ -704,3 +735,42 @@ void command_jump(struct iptables_command_state *cs, const char *jumpto) ...@@ -704,3 +735,42 @@ void command_jump(struct iptables_command_state *cs, const char *jumpto)
xtables_error(OTHER_PROBLEM, "can't alloc memory!"); xtables_error(OTHER_PROBLEM, "can't alloc memory!");
xt_params->opts = opts; xt_params->opts = opts;
} }
char cmd2char(int option)
{
/* cmdflags index corresponds with position of bit in CMD_* values */
static const char cmdflags[] = { 'I', 'D', 'D', 'R', 'A', 'L', 'F', 'Z',
'N', 'X', 'P', 'E', 'S', 'Z', 'C' };
int i;
for (i = 0; option > 1; option >>= 1, i++)
;
if (i >= ARRAY_SIZE(cmdflags))
xtables_error(OTHER_PROBLEM,
"cmd2char(): Invalid command number %u.\n",
1 << i);
return cmdflags[i];
}
void add_command(unsigned int *cmd, const int newcmd,
const int othercmds, int invert)
{
if (invert)
xtables_error(PARAMETER_PROBLEM, "unexpected '!' flag");
if (*cmd & (~othercmds))
xtables_error(PARAMETER_PROBLEM, "Cannot use -%c with -%c\n",
cmd2char(newcmd), cmd2char(*cmd & (~othercmds)));
*cmd |= newcmd;
}
/* Can't be zero. */
int parse_rulenumber(const char *rule)
{
unsigned int rulenum;
if (!xtables_strtoui(rule, NULL, &rulenum, 1, INT_MAX))
xtables_error(PARAMETER_PROBLEM,
"Invalid rule number `%s'", rule);
return rulenum;
}
...@@ -6,12 +6,13 @@ ...@@ -6,12 +6,13 @@
#include <stdint.h> #include <stdint.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <net/if.h> #include <net/if.h>
#include <sys/time.h>
#include <linux/netfilter_arp/arp_tables.h> #include <linux/netfilter_arp/arp_tables.h>
#include <linux/netfilter_ipv4/ip_tables.h> #include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv6/ip6_tables.h> #include <linux/netfilter_ipv6/ip6_tables.h>
#ifdef DEBUG #ifdef DEBUG
#define DEBUGP(x, args...) fprintf(stdout, x, ## args) #define DEBUGP(x, args...) fprintf(stderr, x, ## args)
#else #else
#define DEBUGP(x, args...) #define DEBUGP(x, args...)
#endif #endif
...@@ -29,8 +30,35 @@ enum { ...@@ -29,8 +30,35 @@ enum {
OPT_VIANAMEOUT = 1 << 8, OPT_VIANAMEOUT = 1 << 8,
OPT_LINENUMBERS = 1 << 9, OPT_LINENUMBERS = 1 << 9,
OPT_COUNTERS = 1 << 10, OPT_COUNTERS = 1 << 10,
/* below are for arptables only */
OPT_S_MAC = 1 << 11,
OPT_D_MAC = 1 << 12,
OPT_H_LENGTH = 1 << 13,
OPT_OPCODE = 1 << 14,
OPT_H_TYPE = 1 << 15,
OPT_P_TYPE = 1 << 16,
}; };
enum {
CMD_NONE = 0,
CMD_INSERT = 1 << 0,
CMD_DELETE = 1 << 1,
CMD_DELETE_NUM = 1 << 2,
CMD_REPLACE = 1 << 3,
CMD_APPEND = 1 << 4,
CMD_LIST = 1 << 5,
CMD_FLUSH = 1 << 6,
CMD_ZERO = 1 << 7,
CMD_NEW_CHAIN = 1 << 8,
CMD_DELETE_CHAIN = 1 << 9,
CMD_SET_POLICY = 1 << 10,
CMD_RENAME_CHAIN = 1 << 11,
CMD_LIST_RULES = 1 << 12,
CMD_ZERO_NUM = 1 << 13,
CMD_CHECK = 1 << 14,
};
#define NUMBER_OF_CMD 16
struct xtables_globals; struct xtables_globals;
struct xtables_rule_match; struct xtables_rule_match;
struct xtables_target; struct xtables_target;
...@@ -151,22 +179,27 @@ extern int xtables_lock_or_exit(int wait, struct timeval *tv); ...@@ -151,22 +179,27 @@ extern int xtables_lock_or_exit(int wait, struct timeval *tv);
int parse_wait_time(int argc, char *argv[]); int parse_wait_time(int argc, char *argv[]);
void parse_wait_interval(int argc, char *argv[], struct timeval *wait_interval); void parse_wait_interval(int argc, char *argv[], struct timeval *wait_interval);
int parse_counters(const char *string, struct xt_counters *ctr); int parse_counters(const char *string, struct xt_counters *ctr);
bool tokenize_rule_counters(char **bufferp, char **pcnt, char **bcnt, int line);
bool xs_has_arg(int argc, char *argv[]); bool xs_has_arg(int argc, char *argv[]);
extern const struct xtables_afinfo *afinfo; extern const struct xtables_afinfo *afinfo;
extern char *newargv[]; #define MAX_ARGC 255
extern int newargc; struct argv_store {
int argc;
extern char *oldargv[]; char *argv[MAX_ARGC];
extern int oldargc; int argvattr[MAX_ARGC];
};
extern int newargvattr[];
int add_argv(const char *what, int quoted); void add_argv(struct argv_store *store, const char *what, int quoted);
void free_argv(void); void free_argv(struct argv_store *store);
void save_argv(void); void save_argv(struct argv_store *dst, struct argv_store *src);
void add_param_to_argv(char *parsestart, int line); void add_param_to_argv(struct argv_store *store, char *parsestart, int line);
#ifdef DEBUG
void debug_print_argv(struct argv_store *store);
#else
# define debug_print_argv(...) /* nothing */
#endif
void print_ipv4_addresses(const struct ipt_entry *fw, unsigned int format); void print_ipv4_addresses(const struct ipt_entry *fw, unsigned int format);
void print_ipv6_addresses(const struct ip6t_entry *fw6, unsigned int format); void print_ipv6_addresses(const struct ip6t_entry *fw6, unsigned int format);
...@@ -178,4 +211,9 @@ void command_match(struct iptables_command_state *cs); ...@@ -178,4 +211,9 @@ void command_match(struct iptables_command_state *cs);
const char *xt_parse_target(const char *targetname); const char *xt_parse_target(const char *targetname);
void command_jump(struct iptables_command_state *cs, const char *jumpto); void command_jump(struct iptables_command_state *cs, const char *jumpto);
char cmd2char(int option);
void add_command(unsigned int *cmd, const int newcmd,
const int othercmds, int invert);
int parse_rulenumber(const char *rule);
#endif /* IPTABLES_XSHARED_H */ #endif /* IPTABLES_XSHARED_H */
...@@ -56,6 +56,7 @@ int xtables_arp_main(int argc, char *argv[]) ...@@ -56,6 +56,7 @@ int xtables_arp_main(int argc, char *argv[])
ret = nft_commit(&h); ret = nft_commit(&h);
nft_fini(&h); nft_fini(&h);
xtables_fini();
if (!ret) if (!ret)
fprintf(stderr, "arptables: %s\n", nft_strerror(errno)); fprintf(stderr, "arptables: %s\n", nft_strerror(errno));
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
This tool is not luser-proof: you can specify an Ethernet source address This tool is not luser-proof: you can specify an Ethernet source address
and set hardware length to something different than 6, f.e. and set hardware length to something different than 6, f.e.
*/ */
#include "config.h"
#include <getopt.h> #include <getopt.h>
#include <string.h> #include <string.h>
#include <netdb.h> #include <netdb.h>
...@@ -53,56 +53,6 @@ ...@@ -53,56 +53,6 @@
#include "nft-arp.h" #include "nft-arp.h"
#include <linux/netfilter_arp/arp_tables.h> #include <linux/netfilter_arp/arp_tables.h>
typedef char arpt_chainlabel[32];
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
/* XXX: command defined by nft-shared.h do not overlap with these two */
#undef CMD_CHECK
#undef CMD_RENAME_CHAIN
#define CMD_NONE 0x0000U
#define CMD_INSERT 0x0001U
#define CMD_DELETE 0x0002U
#define CMD_DELETE_NUM 0x0004U
#define CMD_REPLACE 0x0008U
#define CMD_APPEND 0x0010U
#define CMD_LIST 0x0020U
#define CMD_FLUSH 0x0040U
#define CMD_ZERO 0x0080U
#define CMD_NEW_CHAIN 0x0100U
#define CMD_DELETE_CHAIN 0x0200U
#define CMD_SET_POLICY 0x0400U
#define CMD_CHECK 0x0800U
#define CMD_RENAME_CHAIN 0x1000U
#define NUMBER_OF_CMD 13
static const char cmdflags[] = { 'I', 'D', 'D', 'R', 'A', 'L', 'F', 'Z',
'N', 'X', 'P', 'E' };
#define OPTION_OFFSET 256
#define OPT_NONE 0x00000U
#define OPT_NUMERIC 0x00001U
#define OPT_S_IP 0x00002U
#define OPT_D_IP 0x00004U
#define OPT_S_MAC 0x00008U
#define OPT_D_MAC 0x00010U
#define OPT_H_LENGTH 0x00020U
#define OPT_P_LENGTH 0x00040U
#define OPT_OPCODE 0x00080U
#define OPT_H_TYPE 0x00100U
#define OPT_P_TYPE 0x00200U
#define OPT_JUMP 0x00400U
#define OPT_VERBOSE 0x00800U
#define OPT_VIANAMEIN 0x01000U
#define OPT_VIANAMEOUT 0x02000U
#define OPT_LINENUMBERS 0x04000U
#define OPT_COUNTERS 0x08000U
#define NUMBER_OF_OPT 16 #define NUMBER_OF_OPT 16
static const char optflags[NUMBER_OF_OPT] static const char optflags[NUMBER_OF_OPT]
= { 'n', 's', 'd', 2, 3, 7, 8, 4, 5, 6, 'j', 'v', 'i', 'o', '0', 'c'}; = { 'n', 's', 'd', 2, 3, 7, 8, 4, 5, 6, 'j', 'v', 'i', 'o', '0', 'c'};
...@@ -148,85 +98,39 @@ static struct option original_opts[] = { ...@@ -148,85 +98,39 @@ static struct option original_opts[] = {
{ 0 } { 0 }
}; };
int RUNTIME_NF_ARP_NUMHOOKS = 3;
#define opts xt_params->opts #define opts xt_params->opts
extern void xtables_exit_error(enum xtables_exittype status, const char *msg, ...) __attribute__((noreturn, format(printf,2,3))); extern void xtables_exit_error(enum xtables_exittype status, const char *msg, ...) __attribute__((noreturn, format(printf,2,3)));
struct xtables_globals arptables_globals = { struct xtables_globals arptables_globals = {
.option_offset = 0, .option_offset = 0,
.program_version = IPTABLES_VERSION, .program_version = PACKAGE_VERSION,
.orig_opts = original_opts, .orig_opts = original_opts,
.exit_err = xtables_exit_error, .exit_err = xtables_exit_error,
.compat_rev = nft_compatible_revision, .compat_rev = nft_compatible_revision,
}; };
/* Table of legal combinations of commands and options. If any of the /* index relates to bit of each OPT_* value */
* given commands make an option legal, that option is legal (applies to static int inverse_for_options[] =
* CMD_LIST and CMD_ZERO only).
* Key:
* + compulsory
* x illegal
* optional
*/
static char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] =
/* Well, it's better than "Re: Linux vs FreeBSD" */
{
/* -n -s -d -p -j -v -x -i -o -f --line */
/*INSERT*/ {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '},
/*DELETE*/ {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '},
/*DELETE_NUM*/{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '},
/*REPLACE*/ {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '},
/*APPEND*/ {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '},
/*LIST*/ {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '},
/*FLUSH*/ {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '},
/*ZERO*/ {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '},
/*NEW_CHAIN*/ {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '},
/*DEL_CHAIN*/ {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '},
/*SET_POLICY*/{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '},
/*CHECK*/ {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '},
/*RENAME*/ {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}
};
static int inverse_for_options[NUMBER_OF_OPT] =
{ {
/* -n */ 0, /* -n */ 0,
/* -s */ ARPT_INV_SRCIP, /* -s */ ARPT_INV_SRCIP,
/* -d */ ARPT_INV_TGTIP, /* -d */ ARPT_INV_TGTIP,
/* 2 */ ARPT_INV_SRCDEVADDR, /* -p */ 0,
/* 3 */ ARPT_INV_TGTDEVADDR,
/* -l */ ARPT_INV_ARPHLN,
/* 8 */ 0,
/* 4 */ ARPT_INV_ARPOP,
/* 5 */ ARPT_INV_ARPHRD,
/* 6 */ ARPT_INV_ARPPRO,
/* -j */ 0, /* -j */ 0,
/* -v */ 0, /* -v */ 0,
/* -x */ 0,
/* -i */ ARPT_INV_VIA_IN, /* -i */ ARPT_INV_VIA_IN,
/* -o */ ARPT_INV_VIA_OUT, /* -o */ ARPT_INV_VIA_OUT,
/*--line*/ 0, /*--line*/ 0,
/* -c */ 0, /* -c */ 0,
/* 2 */ ARPT_INV_SRCDEVADDR,
/* 3 */ ARPT_INV_TGTDEVADDR,
/* -l */ ARPT_INV_ARPHLN,
/* 4 */ ARPT_INV_ARPOP,
/* 5 */ ARPT_INV_ARPHRD,
/* 6 */ ARPT_INV_ARPPRO,
}; };
/* A few hardcoded protocols for 'all' and in case the user has no
/etc/protocols */
struct pprot {
char *name;
u_int8_t num;
};
/* Primitive headers... */
/* defined in netinet/in.h */
#if 0
#ifndef IPPROTO_ESP
#define IPPROTO_ESP 50
#endif
#ifndef IPPROTO_AH
#define IPPROTO_AH 51
#endif
#endif
/***********************************************/ /***********************************************/
/* ARPTABLES SPECIFIC NEW FUNCTIONS ADDED HERE */ /* ARPTABLES SPECIFIC NEW FUNCTIONS ADDED HERE */
/***********************************************/ /***********************************************/
...@@ -317,89 +221,10 @@ static int get16_and_mask(char *from, uint16_t *to, uint16_t *mask, int base) ...@@ -317,89 +221,10 @@ static int get16_and_mask(char *from, uint16_t *to, uint16_t *mask, int base)
return 0; return 0;
} }
static int
string_to_number(const char *s, unsigned int min, unsigned int max,
unsigned int *ret)
{
long number;
char *end;
/* Handle hex, octal, etc. */
errno = 0;
number = strtol(s, &end, 0);
if (*end == '\0' && end != s) {
/* we parsed a number, let's see if we want this */
if (errno != ERANGE && min <= number && number <= max) {
*ret = number;
return 0;
}
}
return -1;
}
/*********************************************/ /*********************************************/
/* ARPTABLES SPECIFIC NEW FUNCTIONS END HERE */ /* ARPTABLES SPECIFIC NEW FUNCTIONS END HERE */
/*********************************************/ /*********************************************/
static struct in_addr *
dotted_to_addr(const char *dotted)
{
static struct in_addr addr;
unsigned char *addrp;
char *p, *q;
unsigned int onebyte;
int i;
char buf[20];
/* copy dotted string, because we need to modify it */
strncpy(buf, dotted, sizeof(buf) - 1);
addrp = (unsigned char *) &(addr.s_addr);
p = buf;
for (i = 0; i < 3; i++) {
if ((q = strchr(p, '.')) == NULL)
return (struct in_addr *) NULL;
*q = '\0';
if (string_to_number(p, 0, 255, &onebyte) == -1)
return (struct in_addr *) NULL;
addrp[i] = (unsigned char) onebyte;
p = q + 1;
}
/* we've checked 3 bytes, now we check the last one */
if (string_to_number(p, 0, 255, &onebyte) == -1)
return (struct in_addr *) NULL;
addrp[3] = (unsigned char) onebyte;
return &addr;
}
static struct in_addr *
network_to_addr(const char *name)
{
struct netent *net;
static struct in_addr addr;
if ((net = getnetbyname(name)) != NULL) {
if (net->n_addrtype != AF_INET)
return (struct in_addr *) NULL;
addr.s_addr = htonl((unsigned long) net->n_net);
return &addr;
}
return (struct in_addr *) NULL;
}
static void
inaddrcpy(struct in_addr *dst, struct in_addr *src)
{
/* memcpy(dst, src, sizeof(struct in_addr)); */
dst->s_addr = src->s_addr;
}
static void static void
exit_tryhelp(int status) exit_tryhelp(int status)
{ {
...@@ -410,7 +235,7 @@ exit_tryhelp(int status) ...@@ -410,7 +235,7 @@ exit_tryhelp(int status)
} }
static void static void
exit_printhelp(void) printhelp(void)
{ {
struct xtables_target *t = NULL; struct xtables_target *t = NULL;
int i; int i;
...@@ -500,43 +325,6 @@ exit_printhelp(void) ...@@ -500,43 +325,6 @@ exit_printhelp(void)
printf("\n"); printf("\n");
t->help(); t->help();
} }
exit(0);
}
static void
generic_opt_check(int command, int options)
{
int i, j, legal = 0;
/* Check that commands are valid with options. Complicated by the
* fact that if an option is legal with *any* command given, it is
* legal overall (ie. -z and -l).
*/
for (i = 0; i < NUMBER_OF_OPT; i++) {
legal = 0; /* -1 => illegal, 1 => legal, 0 => undecided. */
for (j = 0; j < NUMBER_OF_CMD; j++) {
if (!(command & (1<<j)))
continue;
if (!(options & (1<<i))) {
if (commands_v_options[j][i] == '+')
xtables_error(PARAMETER_PROBLEM,
"You need to supply the `-%c' "
"option for this command\n",
optflags[i]);
} else {
if (commands_v_options[j][i] != 'x')
legal = 1;
else if (legal == 0)
legal = -1;
}
}
if (legal == -1)
xtables_error(PARAMETER_PROBLEM,
"Illegal option `-%c' with this command\n",
optflags[i]);
}
} }
static char static char
...@@ -548,26 +336,6 @@ opt2char(int option) ...@@ -548,26 +336,6 @@ opt2char(int option)
return *ptr; return *ptr;
} }
static char
cmd2char(int option)
{
const char *ptr;
for (ptr = cmdflags; option > 1; option >>= 1, ptr++);
return *ptr;
}
static void
add_command(unsigned int *cmd, const int newcmd, const unsigned int othercmds, int invert)
{
if (invert)
xtables_error(PARAMETER_PROBLEM, "unexpected ! flag");
if (*cmd & (~othercmds))
xtables_error(PARAMETER_PROBLEM, "Can't use -%c with -%c\n",
cmd2char(newcmd), cmd2char(*cmd & (~othercmds)));
*cmd |= newcmd;
}
static int static int
check_inverse(const char option[], int *invert, int *optidx, int argc) check_inverse(const char option[], int *invert, int *optidx, int argc)
{ {
...@@ -575,7 +343,7 @@ check_inverse(const char option[], int *invert, int *optidx, int argc) ...@@ -575,7 +343,7 @@ check_inverse(const char option[], int *invert, int *optidx, int argc)
if (*invert) if (*invert)
xtables_error(PARAMETER_PROBLEM, xtables_error(PARAMETER_PROBLEM,
"Multiple `!' flags not allowed"); "Multiple `!' flags not allowed");
*invert = TRUE; *invert = true;
if (optidx) { if (optidx) {
*optidx = *optidx+1; *optidx = *optidx+1;
if (argc && *optidx > argc) if (argc && *optidx > argc)
...@@ -583,181 +351,9 @@ check_inverse(const char option[], int *invert, int *optidx, int argc) ...@@ -583,181 +351,9 @@ check_inverse(const char option[], int *invert, int *optidx, int argc)
"no argument following `!'"); "no argument following `!'");
} }
return TRUE; return true;
} }
return FALSE; return false;
}
static struct in_addr *
host_to_addr(const char *name, unsigned int *naddr)
{
struct in_addr *addr;
struct addrinfo hints = {
.ai_flags = AI_CANONNAME,
.ai_family = AF_INET,
.ai_socktype = SOCK_RAW,
};;
struct addrinfo *res, *p;
int err;
unsigned int i;
*naddr = 0;
err = getaddrinfo(name, NULL, &hints, &res);
if (err != 0)
return NULL;
else {
for (p = res; p != NULL; p = p->ai_next)
(*naddr)++;
addr = xtables_calloc(*naddr, sizeof(struct in_addr));
for (i = 0, p = res; p != NULL; p = p->ai_next)
memcpy(&addr[i++],
&((const struct sockaddr_in *)p->ai_addr)->sin_addr,
sizeof(struct in_addr));
freeaddrinfo(res);
return addr;
}
return (struct in_addr *) NULL;
}
/*
* All functions starting with "parse" should succeed, otherwise
* the program fails.
* Most routines return pointers to static data that may change
* between calls to the same or other routines with a few exceptions:
* "host_to_addr", "parse_hostnetwork", and "parse_hostnetworkmask"
* return global static data.
*/
static struct in_addr *
parse_hostnetwork(const char *name, unsigned int *naddrs)
{
struct in_addr *addrp, *addrptmp;
if ((addrptmp = dotted_to_addr(name)) != NULL ||
(addrptmp = network_to_addr(name)) != NULL) {
addrp = xtables_malloc(sizeof(struct in_addr));
inaddrcpy(addrp, addrptmp);
*naddrs = 1;
return addrp;
}
if ((addrp = host_to_addr(name, naddrs)) != NULL)
return addrp;
xtables_error(PARAMETER_PROBLEM, "host/network `%s' not found", name);
}
static struct in_addr *
parse_mask(char *mask)
{
static struct in_addr maskaddr;
struct in_addr *addrp;
unsigned int bits;
if (mask == NULL) {
/* no mask at all defaults to 32 bits */
maskaddr.s_addr = 0xFFFFFFFF;
return &maskaddr;
}
if ((addrp = dotted_to_addr(mask)) != NULL)
/* dotted_to_addr already returns a network byte order addr */
return addrp;
if (string_to_number(mask, 0, 32, &bits) == -1)
xtables_error(PARAMETER_PROBLEM,
"invalid mask `%s' specified", mask);
if (bits != 0) {
maskaddr.s_addr = htonl(0xFFFFFFFF << (32 - bits));
return &maskaddr;
}
maskaddr.s_addr = 0L;
return &maskaddr;
}
static void
parse_hostnetworkmask(const char *name, struct in_addr **addrpp,
struct in_addr *maskp, unsigned int *naddrs)
{
struct in_addr *addrp;
char buf[256];
char *p;
int i, j, k, n;
strncpy(buf, name, sizeof(buf) - 1);
if ((p = strrchr(buf, '/')) != NULL) {
*p = '\0';
addrp = parse_mask(p + 1);
} else
addrp = parse_mask(NULL);
inaddrcpy(maskp, addrp);
/* if a null mask is given, the name is ignored, like in "any/0" */
if (maskp->s_addr == 0L)
strcpy(buf, "0.0.0.0");
addrp = *addrpp = parse_hostnetwork(buf, naddrs);
n = *naddrs;
for (i = 0, j = 0; i < n; i++) {
addrp[j++].s_addr &= maskp->s_addr;
for (k = 0; k < j - 1; k++) {
if (addrp[k].s_addr == addrp[j - 1].s_addr) {
(*naddrs)--;
j--;
break;
}
}
}
}
static void
parse_interface(const char *arg, char *vianame, unsigned char *mask)
{
int vialen = strlen(arg);
unsigned int i;
memset(mask, 0, IFNAMSIZ);
memset(vianame, 0, IFNAMSIZ);
if (vialen + 1 > IFNAMSIZ)
xtables_error(PARAMETER_PROBLEM,
"interface name `%s' must be shorter than IFNAMSIZ"
" (%i)", arg, IFNAMSIZ-1);
strcpy(vianame, arg);
if (vialen == 0)
memset(mask, 0, IFNAMSIZ);
else if (vianame[vialen - 1] == '+') {
memset(mask, 0xFF, vialen - 1);
memset(mask + vialen - 1, 0, IFNAMSIZ - vialen + 1);
/* Don't remove `+' here! -HW */
} else {
/* Include nul-terminator in match */
memset(mask, 0xFF, vialen + 1);
memset(mask + vialen + 1, 0, IFNAMSIZ - vialen - 1);
for (i = 0; vianame[i]; i++) {
if (!isalnum(vianame[i])
&& vianame[i] != '_'
&& vianame[i] != '.') {
printf("Warning: weird character in interface"
" `%s' (No aliases, :, ! or *).\n",
vianame);
break;
}
}
}
}
/* Can't be zero. */
static int
parse_rulenumber(const char *rule)
{
unsigned int rulenum;
if (!xtables_strtoui(rule, NULL, &rulenum, 1, INT_MAX))
xtables_error(PARAMETER_PROBLEM,
"Invalid rule number `%s'", rule);
return rulenum;
} }
static void static void
...@@ -803,7 +399,7 @@ list_entries(struct nft_handle *h, const char *chain, const char *table, ...@@ -803,7 +399,7 @@ list_entries(struct nft_handle *h, const char *chain, const char *table,
if (linenumbers) if (linenumbers)
format |= FMT_LINENUMBERS; format |= FMT_LINENUMBERS;
return nft_rule_list(h, chain, table, rulenum, format); return nft_cmd_rule_list(h, chain, table, rulenum, format);
} }
static int static int
...@@ -814,8 +410,10 @@ append_entry(struct nft_handle *h, ...@@ -814,8 +410,10 @@ append_entry(struct nft_handle *h,
int rulenum, int rulenum,
unsigned int nsaddrs, unsigned int nsaddrs,
const struct in_addr saddrs[], const struct in_addr saddrs[],
const struct in_addr smasks[],
unsigned int ndaddrs, unsigned int ndaddrs,
const struct in_addr daddrs[], const struct in_addr daddrs[],
const struct in_addr dmasks[],
bool verbose, bool append) bool verbose, bool append)
{ {
unsigned int i, j; unsigned int i, j;
...@@ -823,13 +421,15 @@ append_entry(struct nft_handle *h, ...@@ -823,13 +421,15 @@ append_entry(struct nft_handle *h,
for (i = 0; i < nsaddrs; i++) { for (i = 0; i < nsaddrs; i++) {
cs->arp.arp.src.s_addr = saddrs[i].s_addr; cs->arp.arp.src.s_addr = saddrs[i].s_addr;
cs->arp.arp.smsk.s_addr = smasks[i].s_addr;
for (j = 0; j < ndaddrs; j++) { for (j = 0; j < ndaddrs; j++) {
cs->arp.arp.tgt.s_addr = daddrs[j].s_addr; cs->arp.arp.tgt.s_addr = daddrs[j].s_addr;
cs->arp.arp.tmsk.s_addr = dmasks[j].s_addr;
if (append) { if (append) {
ret = nft_rule_append(h, chain, table, cs, NULL, ret = nft_cmd_rule_append(h, chain, table, cs, NULL,
verbose); verbose);
} else { } else {
ret = nft_rule_insert(h, chain, table, cs, ret = nft_cmd_rule_insert(h, chain, table, cs,
rulenum, verbose); rulenum, verbose);
} }
} }
...@@ -844,13 +444,17 @@ replace_entry(const char *chain, ...@@ -844,13 +444,17 @@ replace_entry(const char *chain,
struct iptables_command_state *cs, struct iptables_command_state *cs,
unsigned int rulenum, unsigned int rulenum,
const struct in_addr *saddr, const struct in_addr *saddr,
const struct in_addr *smask,
const struct in_addr *daddr, const struct in_addr *daddr,
const struct in_addr *dmask,
bool verbose, struct nft_handle *h) bool verbose, struct nft_handle *h)
{ {
cs->arp.arp.src.s_addr = saddr->s_addr; cs->arp.arp.src.s_addr = saddr->s_addr;
cs->arp.arp.tgt.s_addr = daddr->s_addr; cs->arp.arp.tgt.s_addr = daddr->s_addr;
cs->arp.arp.smsk.s_addr = smask->s_addr;
cs->arp.arp.tmsk.s_addr = dmask->s_addr;
return nft_rule_replace(h, chain, table, cs, rulenum, verbose); return nft_cmd_rule_replace(h, chain, table, cs, rulenum, verbose);
} }
static int static int
...@@ -859,8 +463,10 @@ delete_entry(const char *chain, ...@@ -859,8 +463,10 @@ delete_entry(const char *chain,
struct iptables_command_state *cs, struct iptables_command_state *cs,
unsigned int nsaddrs, unsigned int nsaddrs,
const struct in_addr saddrs[], const struct in_addr saddrs[],
const struct in_addr smasks[],
unsigned int ndaddrs, unsigned int ndaddrs,
const struct in_addr daddrs[], const struct in_addr daddrs[],
const struct in_addr dmasks[],
bool verbose, struct nft_handle *h) bool verbose, struct nft_handle *h)
{ {
unsigned int i, j; unsigned int i, j;
...@@ -868,9 +474,11 @@ delete_entry(const char *chain, ...@@ -868,9 +474,11 @@ delete_entry(const char *chain,
for (i = 0; i < nsaddrs; i++) { for (i = 0; i < nsaddrs; i++) {
cs->arp.arp.src.s_addr = saddrs[i].s_addr; cs->arp.arp.src.s_addr = saddrs[i].s_addr;
cs->arp.arp.smsk.s_addr = smasks[i].s_addr;
for (j = 0; j < ndaddrs; j++) { for (j = 0; j < ndaddrs; j++) {
cs->arp.arp.tgt.s_addr = daddrs[j].s_addr; cs->arp.arp.tgt.s_addr = daddrs[j].s_addr;
ret = nft_rule_delete(h, chain, table, cs, verbose); cs->arp.arp.tmsk.s_addr = dmasks[j].s_addr;
ret = nft_cmd_rule_delete(h, chain, table, cs, verbose);
} }
} }
...@@ -891,17 +499,10 @@ int nft_init_arp(struct nft_handle *h, const char *pname) ...@@ -891,17 +499,10 @@ int nft_init_arp(struct nft_handle *h, const char *pname)
init_extensionsa(); init_extensionsa();
#endif #endif
memset(h, 0, sizeof(*h)); if (nft_init(h, NFPROTO_ARP, xtables_arp) < 0)
h->family = NFPROTO_ARP;
if (nft_init(h, xtables_arp) < 0)
xtables_error(OTHER_PROBLEM, xtables_error(OTHER_PROBLEM,
"Could not initialize nftables layer."); "Could not initialize nftables layer.");
h->ops = nft_family_ops_lookup(h->family);
if (h->ops == NULL)
xtables_error(PARAMETER_PROBLEM, "Unknown family");
return 0; return 0;
} }
...@@ -919,7 +520,8 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table, ...@@ -919,7 +520,8 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table,
}; };
int invert = 0; int invert = 0;
unsigned int nsaddrs = 0, ndaddrs = 0; unsigned int nsaddrs = 0, ndaddrs = 0;
struct in_addr *saddrs = NULL, *daddrs = NULL; struct in_addr *saddrs = NULL, *smasks = NULL;
struct in_addr *daddrs = NULL, *dmasks = NULL;
int c, verbose = 0; int c, verbose = 0;
const char *chain = NULL; const char *chain = NULL;
...@@ -1063,18 +665,19 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table, ...@@ -1063,18 +665,19 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table,
if (!optarg) if (!optarg)
optarg = argv[optind]; optarg = argv[optind];
exit_printhelp(); printhelp();
command = CMD_NONE;
break; break;
case 's': case 's':
check_inverse(optarg, &invert, &optind, argc); check_inverse(optarg, &invert, &optind, argc);
set_option(&options, OPT_S_IP, &cs.arp.arp.invflags, set_option(&options, OPT_SOURCE, &cs.arp.arp.invflags,
invert); invert);
shostnetworkmask = argv[optind-1]; shostnetworkmask = argv[optind-1];
break; break;
case 'd': case 'd':
check_inverse(optarg, &invert, &optind, argc); check_inverse(optarg, &invert, &optind, argc);
set_option(&options, OPT_D_IP, &cs.arp.arp.invflags, set_option(&options, OPT_DESTINATION, &cs.arp.arp.invflags,
invert); invert);
dhostnetworkmask = argv[optind-1]; dhostnetworkmask = argv[optind-1];
break; break;
...@@ -1168,7 +771,7 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table, ...@@ -1168,7 +771,7 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table,
check_inverse(optarg, &invert, &optind, argc); check_inverse(optarg, &invert, &optind, argc);
set_option(&options, OPT_VIANAMEIN, &cs.arp.arp.invflags, set_option(&options, OPT_VIANAMEIN, &cs.arp.arp.invflags,
invert); invert);
parse_interface(argv[optind-1], xtables_parse_interface(argv[optind-1],
cs.arp.arp.iniface, cs.arp.arp.iniface,
cs.arp.arp.iniface_mask); cs.arp.arp.iniface_mask);
break; break;
...@@ -1177,7 +780,7 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table, ...@@ -1177,7 +780,7 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table,
check_inverse(optarg, &invert, &optind, argc); check_inverse(optarg, &invert, &optind, argc);
set_option(&options, OPT_VIANAMEOUT, &cs.arp.arp.invflags, set_option(&options, OPT_VIANAMEOUT, &cs.arp.arp.invflags,
invert); invert);
parse_interface(argv[optind-1], xtables_parse_interface(argv[optind-1],
cs.arp.arp.outiface, cs.arp.arp.outiface,
cs.arp.arp.outiface_mask); cs.arp.arp.outiface_mask);
break; break;
...@@ -1255,7 +858,7 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table, ...@@ -1255,7 +858,7 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table,
xtables_error(PARAMETER_PROBLEM, xtables_error(PARAMETER_PROBLEM,
"multiple consecutive ! not" "multiple consecutive ! not"
" allowed"); " allowed");
invert = TRUE; invert = true;
optarg[0] = '\0'; optarg[0] = '\0';
continue; continue;
} }
...@@ -1269,7 +872,7 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table, ...@@ -1269,7 +872,7 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table,
} }
break; break;
} }
invert = FALSE; invert = false;
} }
if (cs.target) if (cs.target)
...@@ -1278,26 +881,24 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table, ...@@ -1278,26 +881,24 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table,
if (optind < argc) if (optind < argc)
xtables_error(PARAMETER_PROBLEM, xtables_error(PARAMETER_PROBLEM,
"unknown arguments found on commandline"); "unknown arguments found on commandline");
if (!command)
xtables_error(PARAMETER_PROBLEM, "no command specified");
if (invert) if (invert)
xtables_error(PARAMETER_PROBLEM, xtables_error(PARAMETER_PROBLEM,
"nothing appropriate following !"); "nothing appropriate following !");
if (command & (CMD_REPLACE | CMD_INSERT | CMD_DELETE | CMD_APPEND)) { if (command & (CMD_REPLACE | CMD_INSERT | CMD_DELETE | CMD_APPEND)) {
if (!(options & OPT_D_IP)) if (!(options & OPT_DESTINATION))
dhostnetworkmask = "0.0.0.0/0"; dhostnetworkmask = "0.0.0.0/0";
if (!(options & OPT_S_IP)) if (!(options & OPT_SOURCE))
shostnetworkmask = "0.0.0.0/0"; shostnetworkmask = "0.0.0.0/0";
} }
if (shostnetworkmask) if (shostnetworkmask)
parse_hostnetworkmask(shostnetworkmask, &saddrs, xtables_ipparse_multiple(shostnetworkmask, &saddrs,
&(cs.arp.arp.smsk), &nsaddrs); &smasks, &nsaddrs);
if (dhostnetworkmask) if (dhostnetworkmask)
parse_hostnetworkmask(dhostnetworkmask, &daddrs, xtables_ipparse_multiple(dhostnetworkmask, &daddrs,
&(cs.arp.arp.tmsk), &ndaddrs); &dmasks, &ndaddrs);
if ((nsaddrs > 1 || ndaddrs > 1) && if ((nsaddrs > 1 || ndaddrs > 1) &&
(cs.arp.arp.invflags & (ARPT_INV_SRCIP | ARPT_INV_TGTIP))) (cs.arp.arp.invflags & (ARPT_INV_SRCIP | ARPT_INV_TGTIP)))
...@@ -1308,8 +909,6 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table, ...@@ -1308,8 +909,6 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table,
xtables_error(PARAMETER_PROBLEM, "Replacement rule does not " xtables_error(PARAMETER_PROBLEM, "Replacement rule does not "
"specify a unique address"); "specify a unique address");
generic_opt_check(command, options);
if (chain && strlen(chain) > ARPT_FUNCTION_MAXNAMELEN) if (chain && strlen(chain) > ARPT_FUNCTION_MAXNAMELEN)
xtables_error(PARAMETER_PROBLEM, xtables_error(PARAMETER_PROBLEM,
"chain name `%s' too long (must be under %i chars)", "chain name `%s' too long (must be under %i chars)",
...@@ -1343,24 +942,28 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table, ...@@ -1343,24 +942,28 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table,
switch (command) { switch (command) {
case CMD_APPEND: case CMD_APPEND:
ret = append_entry(h, chain, *table, &cs, 0, ret = append_entry(h, chain, *table, &cs, 0,
nsaddrs, saddrs, ndaddrs, daddrs, nsaddrs, saddrs, smasks,
ndaddrs, daddrs, dmasks,
options&OPT_VERBOSE, true); options&OPT_VERBOSE, true);
break; break;
case CMD_DELETE: case CMD_DELETE:
ret = delete_entry(chain, *table, &cs, ret = delete_entry(chain, *table, &cs,
nsaddrs, saddrs, ndaddrs, daddrs, nsaddrs, saddrs, smasks,
ndaddrs, daddrs, dmasks,
options&OPT_VERBOSE, h); options&OPT_VERBOSE, h);
break; break;
case CMD_DELETE_NUM: case CMD_DELETE_NUM:
ret = nft_rule_delete_num(h, chain, *table, rulenum - 1, verbose); ret = nft_cmd_rule_delete_num(h, chain, *table, rulenum - 1, verbose);
break; break;
case CMD_REPLACE: case CMD_REPLACE:
ret = replace_entry(chain, *table, &cs, rulenum - 1, ret = replace_entry(chain, *table, &cs, rulenum - 1,
saddrs, daddrs, options&OPT_VERBOSE, h); saddrs, smasks, daddrs, dmasks,
options&OPT_VERBOSE, h);
break; break;
case CMD_INSERT: case CMD_INSERT:
ret = append_entry(h, chain, *table, &cs, rulenum - 1, ret = append_entry(h, chain, *table, &cs, rulenum - 1,
nsaddrs, saddrs, ndaddrs, daddrs, nsaddrs, saddrs, smasks,
ndaddrs, daddrs, dmasks,
options&OPT_VERBOSE, false); options&OPT_VERBOSE, false);
break; break;
case CMD_LIST: case CMD_LIST:
...@@ -1372,10 +975,10 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table, ...@@ -1372,10 +975,10 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table,
options&OPT_LINENUMBERS); options&OPT_LINENUMBERS);
break; break;
case CMD_FLUSH: case CMD_FLUSH:
ret = nft_rule_flush(h, chain, *table, options & OPT_VERBOSE); ret = nft_cmd_rule_flush(h, chain, *table, options & OPT_VERBOSE);
break; break;
case CMD_ZERO: case CMD_ZERO:
ret = nft_chain_zero_counters(h, chain, *table, ret = nft_cmd_chain_zero_counters(h, chain, *table,
options & OPT_VERBOSE); options & OPT_VERBOSE);
break; break;
case CMD_LIST|CMD_ZERO: case CMD_LIST|CMD_ZERO:
...@@ -1385,38 +988,38 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table, ...@@ -1385,38 +988,38 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table,
/*options&OPT_EXPANDED*/0, /*options&OPT_EXPANDED*/0,
options&OPT_LINENUMBERS); options&OPT_LINENUMBERS);
if (ret) if (ret)
ret = nft_chain_zero_counters(h, chain, *table, ret = nft_cmd_chain_zero_counters(h, chain, *table,
options & OPT_VERBOSE); options & OPT_VERBOSE);
break; break;
case CMD_NEW_CHAIN: case CMD_NEW_CHAIN:
ret = nft_chain_user_add(h, chain, *table); ret = nft_cmd_chain_user_add(h, chain, *table);
break; break;
case CMD_DELETE_CHAIN: case CMD_DELETE_CHAIN:
ret = nft_chain_user_del(h, chain, *table, ret = nft_cmd_chain_user_del(h, chain, *table,
options & OPT_VERBOSE); options & OPT_VERBOSE);
break; break;
case CMD_RENAME_CHAIN: case CMD_RENAME_CHAIN:
ret = nft_chain_user_rename(h, chain, *table, newname); ret = nft_cmd_chain_user_rename(h, chain, *table, newname);
break; break;
case CMD_SET_POLICY: case CMD_SET_POLICY:
ret = nft_chain_set(h, *table, chain, policy, NULL); ret = nft_cmd_chain_set(h, *table, chain, policy, NULL);
if (ret < 0) if (ret < 0)
xtables_error(PARAMETER_PROBLEM, "Wrong policy `%s'\n", xtables_error(PARAMETER_PROBLEM, "Wrong policy `%s'\n",
policy); policy);
break; break;
case CMD_NONE:
break;
default: default:
/* We should never reach this... */ /* We should never reach this... */
exit_tryhelp(2); exit_tryhelp(2);
} }
if (nsaddrs)
free(saddrs); free(saddrs);
if (ndaddrs) free(smasks);
free(daddrs); free(daddrs);
free(dmasks);
if (cs.target) nft_clear_iptables_command_state(&cs);
free(cs.target->t);
xtables_free_opts(1); xtables_free_opts(1);
/* if (verbose > 1) /* if (verbose > 1)
......
%{
/*
* (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software has been sponsored by Sophos Astaro <http://www.sophos.com>
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <stdarg.h>
#include <libiptc/linux_list.h>
#include <libnftnl/table.h>
#include <libnftnl/chain.h>
#include <netinet/in.h>
#include <linux/netfilter.h>
extern char *yytext;
extern int yylineno;
static LIST_HEAD(xtables_stack);
struct stack_elem {
struct list_head head;
int token;
size_t size;
char data[];
};
static void *stack_push(int token, size_t size)
{
struct stack_elem *e;
e = calloc(1, sizeof(struct stack_elem) + size);
e->token = token;
e->size = size;
list_add(&e->head, &xtables_stack);
return e->data;
}
static struct stack_elem *stack_pop(void)
{
struct stack_elem *e;
e = list_entry(xtables_stack.next, struct stack_elem, head);
if (&e->head == &xtables_stack)
return NULL;
list_del(&e->head);
return e;
}
static inline void stack_put_i32(void *data, int value)
{
memcpy(data, &value, sizeof(int));
}
static inline void stack_put_str(void *data, const char *str)
{
memcpy(data, str, strlen(str));
}
static void stack_free(struct stack_elem *e)
{
free(e);
}
%}
%union {
int val;
char *string;
}
%token T_FAMILY
%token T_TABLE
%token T_CHAIN
%token T_HOOK
%token T_PRIO
%token <string> T_STRING
%token <val> T_INTEGER
%%
configfile :
| lines
;
lines : line
| lines line
;
line : family
;
family : T_FAMILY T_STRING '{' tables '}'
{
void *data = stack_push(T_FAMILY, strlen($2)+1);
stack_put_str(data, $2);
}
;
tables : table
| tables table
;
table : T_TABLE T_STRING '{' chains '}'
{
/* added in reverse order to pop it in order */
void *data = stack_push(T_TABLE, strlen($2)+1);
stack_put_str(data, $2);
}
;
chains : chain
| chains chain
;
chain : T_CHAIN T_STRING T_HOOK T_STRING T_PRIO T_INTEGER
{
/* added in reverse order to pop it in order */
void *data = stack_push(T_PRIO, sizeof(int32_t));
stack_put_i32(data, $6);
data = stack_push(T_HOOK, strlen($4)+1);
stack_put_str(data, $4);
data = stack_push(T_CHAIN, strlen($2)+1);
stack_put_str(data, $2);
}
;
%%
int __attribute__((noreturn))
yyerror(char *msg)
{
fprintf(stderr, "parsing config file in line (%d), symbol '%s': %s\n",
yylineno, yytext, msg);
exit(EXIT_FAILURE);
}
static int hooknametonum(const char *hookname)
{
if (strcmp(hookname, "NF_INET_LOCAL_IN") == 0)
return NF_INET_LOCAL_IN;
else if (strcmp(hookname, "NF_INET_FORWARD") == 0)
return NF_INET_FORWARD;
else if (strcmp(hookname, "NF_INET_LOCAL_OUT") == 0)
return NF_INET_LOCAL_OUT;
else if (strcmp(hookname, "NF_INET_PRE_ROUTING") == 0)
return NF_INET_PRE_ROUTING;
else if (strcmp(hookname, "NF_INET_POST_ROUTING") == 0)
return NF_INET_POST_ROUTING;
return -1;
}
static int32_t familytonumber(const char *family)
{
if (strcmp(family, "ipv4") == 0)
return AF_INET;
else if (strcmp(family, "ipv6") == 0)
return AF_INET6;
return -1;
}
int xtables_config_parse(char *filename, struct nftnl_table_list *table_list,
struct nftnl_chain_list *chain_list)
{
FILE *fp;
struct stack_elem *e;
struct nftnl_table *table = NULL;
struct nftnl_chain *chain = NULL;
int prio = 0;
int32_t family = 0;
fp = fopen(filename, "r");
if (!fp)
return -1;
yyrestart(fp);
yyparse();
fclose(fp);
for (e = stack_pop(); e != NULL; e = stack_pop()) {
switch(e->token) {
case T_FAMILY:
family = familytonumber(e->data);
if (family == -1)
return -1;
break;
case T_TABLE:
table = nftnl_table_alloc();
if (table == NULL)
return -1;
nftnl_table_set_u32(table, NFTNL_TABLE_FAMILY, family);
nftnl_table_set(table, NFTNL_TABLE_NAME, e->data);
/* This is intentionally prepending, instead of
* appending, since the elements in the stack are in
* the reverse order that chains appear in the
* configuration file.
*/
nftnl_table_list_add(table, table_list);
break;
case T_PRIO:
memcpy(&prio, e->data, sizeof(int32_t));
break;
case T_CHAIN:
chain = nftnl_chain_alloc();
if (chain == NULL)
return -1;
nftnl_chain_set(chain, NFTNL_CHAIN_TABLE,
(char *)nftnl_table_get(table, NFTNL_TABLE_NAME));
nftnl_chain_set_u32(chain, NFTNL_CHAIN_FAMILY,
nftnl_table_get_u32(table, NFTNL_TABLE_FAMILY));
nftnl_chain_set_s32(chain, NFTNL_CHAIN_PRIO, prio);
nftnl_chain_set(chain, NFTNL_CHAIN_NAME, e->data);
/* Intentionally prepending, instead of appending */
nftnl_chain_list_add(chain, chain_list);
break;
case T_HOOK:
nftnl_chain_set_u32(chain, NFTNL_CHAIN_HOOKNUM,
hooknametonum(e->data));
break;
default:
printf("unknown token type %d\n", e->token);
break;
}
stack_free(e);
}
return 0;
}
%{
/*
* (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software has been sponsored by Sophos Astaro <http://www.sophos.com>
*/
#include <string.h>
#include "xtables-config-parser.h"
%}
%option yylineno
%option noinput
%option nounput
ws [ \t]+
comment #.*$
nl [\n\r]
is_on [o|O][n|N]
is_off [o|O][f|F][f|F]
integer [\-\+]?[0-9]+
string [a-zA-Z][a-zA-Z0-9\.\-\_]*
%%
"family" { return T_FAMILY; }
"table" { return T_TABLE; }
"chain" { return T_CHAIN; }
"hook" { return T_HOOK; }
"prio" { return T_PRIO; }
{integer} { yylval.val = atoi(yytext); return T_INTEGER; }
{string} { yylval.string = strdup(yytext); return T_STRING; }
{comment} ;
{ws} ;
{nl} ;
<<EOF>> { yyterminate(); }
. { return yytext[0]; }
%%
int
yywrap()
{
return 1;
}
...@@ -51,7 +51,9 @@ int xtables_eb_main(int argc, char *argv[]) ...@@ -51,7 +51,9 @@ int xtables_eb_main(int argc, char *argv[])
ret = do_commandeb(&h, argc, argv, &table, false); ret = do_commandeb(&h, argc, argv, &table, false);
if (ret) if (ret)
ret = nft_commit(&h); ret = nft_bridge_commit(&h);
nft_fini_eb(&h);
if (!ret) if (!ret)
fprintf(stderr, "ebtables: %s\n", nft_strerror(errno)); fprintf(stderr, "ebtables: %s\n", nft_strerror(errno));
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#include "config.h"
#include <ctype.h> #include <ctype.h>
#include <errno.h> #include <errno.h>
#include <getopt.h> #include <getopt.h>
...@@ -150,9 +150,9 @@ append_entry(struct nft_handle *h, ...@@ -150,9 +150,9 @@ append_entry(struct nft_handle *h,
int ret = 1; int ret = 1;
if (append) if (append)
ret = nft_rule_append(h, chain, table, cs, NULL, verbose); ret = nft_cmd_rule_append(h, chain, table, cs, NULL, verbose);
else else
ret = nft_rule_insert(h, chain, table, cs, rule_nr, verbose); ret = nft_cmd_rule_insert(h, chain, table, cs, rule_nr, verbose);
return ret; return ret;
} }
...@@ -169,10 +169,10 @@ delete_entry(struct nft_handle *h, ...@@ -169,10 +169,10 @@ delete_entry(struct nft_handle *h,
int ret = 1; int ret = 1;
if (rule_nr == -1) if (rule_nr == -1)
ret = nft_rule_delete(h, chain, table, cs, verbose); ret = nft_cmd_rule_delete(h, chain, table, cs, verbose);
else { else {
do { do {
ret = nft_rule_delete_num(h, chain, table, ret = nft_cmd_rule_delete_num(h, chain, table,
rule_nr, verbose); rule_nr, verbose);
rule_nr++; rule_nr++;
} while (rule_nr < rule_nr_end); } while (rule_nr < rule_nr_end);
...@@ -197,7 +197,8 @@ int ebt_get_current_chain(const char *chain) ...@@ -197,7 +197,8 @@ int ebt_get_current_chain(const char *chain)
else if (strcmp(chain, "POSTROUTING") == 0) else if (strcmp(chain, "POSTROUTING") == 0)
return NF_BR_POST_ROUTING; return NF_BR_POST_ROUTING;
return -1; /* placeholder for user defined chain */
return NF_BR_NUMHOOKS;
} }
/* /*
...@@ -273,7 +274,7 @@ struct option ebt_original_options[] = ...@@ -273,7 +274,7 @@ struct option ebt_original_options[] =
extern void xtables_exit_error(enum xtables_exittype status, const char *msg, ...) __attribute__((noreturn, format(printf,2,3))); extern void xtables_exit_error(enum xtables_exittype status, const char *msg, ...) __attribute__((noreturn, format(printf,2,3)));
struct xtables_globals ebtables_globals = { struct xtables_globals ebtables_globals = {
.option_offset = 0, .option_offset = 0,
.program_version = IPTABLES_VERSION, .program_version = PACKAGE_VERSION,
.orig_opts = ebt_original_options, .orig_opts = ebt_original_options,
.exit_err = xtables_exit_error, .exit_err = xtables_exit_error,
.compat_rev = nft_compatible_revision, .compat_rev = nft_compatible_revision,
...@@ -410,7 +411,7 @@ static int list_rules(struct nft_handle *h, const char *chain, const char *table ...@@ -410,7 +411,7 @@ static int list_rules(struct nft_handle *h, const char *chain, const char *table
{ {
unsigned int format; unsigned int format;
format = FMT_OPTIONS; format = FMT_OPTIONS | FMT_C_COUNTS;
if (verbose) if (verbose)
format |= FMT_VIA; format |= FMT_VIA;
...@@ -426,7 +427,7 @@ static int list_rules(struct nft_handle *h, const char *chain, const char *table ...@@ -426,7 +427,7 @@ static int list_rules(struct nft_handle *h, const char *chain, const char *table
if (!counters) if (!counters)
format |= FMT_NOCOUNTS; format |= FMT_NOCOUNTS;
return nft_rule_list(h, chain, table, rule_nr, format); return nft_cmd_rule_list(h, chain, table, rule_nr, format);
} }
static int parse_rule_range(const char *argv, int *rule_nr, int *rule_nr_end) static int parse_rule_range(const char *argv, int *rule_nr, int *rule_nr_end)
...@@ -593,6 +594,7 @@ void ebt_load_match_extensions(void) ...@@ -593,6 +594,7 @@ void ebt_load_match_extensions(void)
ebt_load_match("pkttype"); ebt_load_match("pkttype");
ebt_load_match("vlan"); ebt_load_match("vlan");
ebt_load_match("stp"); ebt_load_match("stp");
ebt_load_match("among");
ebt_load_watcher("log"); ebt_load_watcher("log");
ebt_load_watcher("nflog"); ebt_load_watcher("nflog");
...@@ -737,16 +739,9 @@ int nft_init_eb(struct nft_handle *h, const char *pname) ...@@ -737,16 +739,9 @@ int nft_init_eb(struct nft_handle *h, const char *pname)
init_extensionsb(); init_extensionsb();
#endif #endif
memset(h, 0, sizeof(*h)); if (nft_init(h, NFPROTO_BRIDGE, xtables_bridge) < 0)
h->family = NFPROTO_BRIDGE;
if (nft_init(h, xtables_bridge) < 0)
xtables_error(OTHER_PROBLEM, xtables_error(OTHER_PROBLEM,
"Could not initialize nftables layer."); "Could not initialize nftables layer.");
h->ops = nft_family_ops_lookup(h->family);
if (!h->ops)
xtables_error(PARAMETER_PROBLEM, "Unknown family");
/* manually registering ebt matches, given the original ebtables parser /* manually registering ebt matches, given the original ebtables parser
* don't use '-m matchname' and the match can't be loaded dynamically when * don't use '-m matchname' and the match can't be loaded dynamically when
...@@ -757,6 +752,24 @@ int nft_init_eb(struct nft_handle *h, const char *pname) ...@@ -757,6 +752,24 @@ int nft_init_eb(struct nft_handle *h, const char *pname)
return 0; return 0;
} }
void nft_fini_eb(struct nft_handle *h)
{
struct xtables_match *match;
struct xtables_target *target;
for (match = xtables_matches; match; match = match->next) {
free(match->m);
}
for (target = xtables_targets; target; target = target->next) {
free(target->t);
}
free(opts);
nft_fini(h);
xtables_fini();
}
int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table, int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table,
bool restore) bool restore)
{ {
...@@ -779,6 +792,7 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table, ...@@ -779,6 +792,7 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table,
int selected_chain = -1; int selected_chain = -1;
struct xtables_rule_match *xtrm_i; struct xtables_rule_match *xtrm_i;
struct ebt_match *match; struct ebt_match *match;
bool table_set = false;
/* prevent getopt to spoil our error reporting */ /* prevent getopt to spoil our error reporting */
optind = 0; optind = 0;
...@@ -817,7 +831,7 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table, ...@@ -817,7 +831,7 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table,
flags |= OPT_COMMAND; flags |= OPT_COMMAND;
if (c == 'N') { if (c == 'N') {
ret = nft_chain_user_add(h, chain, *table); ret = nft_cmd_chain_user_add(h, chain, *table);
break; break;
} else if (c == 'X') { } else if (c == 'X') {
/* X arg is optional, optarg is NULL */ /* X arg is optional, optarg is NULL */
...@@ -825,7 +839,7 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table, ...@@ -825,7 +839,7 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table,
chain = argv[optind]; chain = argv[optind];
optind++; optind++;
} }
ret = nft_chain_user_del(h, chain, *table, 0); ret = nft_cmd_chain_user_del(h, chain, *table, 0);
break; break;
} }
...@@ -839,7 +853,7 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table, ...@@ -839,7 +853,7 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table,
else if (strchr(argv[optind], ' ') != NULL) else if (strchr(argv[optind], ' ') != NULL)
xtables_error(PARAMETER_PROBLEM, "Use of ' ' not allowed in chain names"); xtables_error(PARAMETER_PROBLEM, "Use of ' ' not allowed in chain names");
ret = nft_chain_user_rename(h, chain, *table, ret = nft_cmd_chain_user_rename(h, chain, *table,
argv[optind]); argv[optind]);
if (ret != 0 && errno == ENOENT) if (ret != 0 && errno == ENOENT)
xtables_error(PARAMETER_PROBLEM, "Chain '%s' doesn't exists", chain); xtables_error(PARAMETER_PROBLEM, "Chain '%s' doesn't exists", chain);
...@@ -946,11 +960,16 @@ print_zero: ...@@ -946,11 +960,16 @@ print_zero:
break; break;
case 't': /* Table */ case 't': /* Table */
ebt_check_option2(&flags, OPT_TABLE); ebt_check_option2(&flags, OPT_TABLE);
if (restore && table_set)
xtables_error(PARAMETER_PROBLEM,
"The -t option (seen in line %u) cannot be used in %s.\n",
line, xt_params->program_name);
if (strlen(optarg) > EBT_TABLE_MAXNAMELEN - 1) if (strlen(optarg) > EBT_TABLE_MAXNAMELEN - 1)
xtables_error(PARAMETER_PROBLEM, xtables_error(PARAMETER_PROBLEM,
"Table name length cannot exceed %d characters", "Table name length cannot exceed %d characters",
EBT_TABLE_MAXNAMELEN - 1); EBT_TABLE_MAXNAMELEN - 1);
*table = optarg; *table = optarg;
table_set = true;
break; break;
case 'i': /* Input interface */ case 'i': /* Input interface */
case 2 : /* Logical input interface */ case 2 : /* Logical input interface */
...@@ -1136,7 +1155,7 @@ print_zero: ...@@ -1136,7 +1155,7 @@ print_zero:
/*case 7 :*/ /* atomic-init */ /*case 7 :*/ /* atomic-init */
/*case 10:*/ /* atomic-save */ /*case 10:*/ /* atomic-save */
case 11: /* init-table */ case 11: /* init-table */
nft_table_flush(h, *table); nft_cmd_table_flush(h, *table);
return 1; return 1;
/* /*
replace->command = c; replace->command = c;
...@@ -1180,7 +1199,7 @@ print_zero: ...@@ -1180,7 +1199,7 @@ print_zero:
if (ebt_command_default(&cs)) if (ebt_command_default(&cs))
xtables_error(PARAMETER_PROBLEM, xtables_error(PARAMETER_PROBLEM,
"Unknown argument: '%s'", "Unknown argument: '%s'",
argv[optind - 1]); argv[optind]);
if (command != 'A' && command != 'I' && if (command != 'A' && command != 'I' &&
command != 'D' && command != 'C') command != 'D' && command != 'C')
...@@ -1199,7 +1218,7 @@ print_zero: ...@@ -1199,7 +1218,7 @@ print_zero:
if (command == 'h' && !(flags & OPT_ZERO)) { if (command == 'h' && !(flags & OPT_ZERO)) {
print_help(cs.target, cs.matches, *table); print_help(cs.target, cs.matches, *table);
exit(0); ret = 1;
} }
/* Do the final checks */ /* Do the final checks */
...@@ -1223,14 +1242,14 @@ print_zero: ...@@ -1223,14 +1242,14 @@ print_zero:
cs.eb.ethproto = htons(cs.eb.ethproto); cs.eb.ethproto = htons(cs.eb.ethproto);
if (command == 'P') { if (command == 'P') {
if (selected_chain < 0) { if (selected_chain >= NF_BR_NUMHOOKS) {
ret = ebt_set_user_chain_policy(h, *table, chain, policy); ret = ebt_cmd_user_chain_policy(h, *table, chain, policy);
} else { } else {
if (strcmp(policy, "RETURN") == 0) { if (strcmp(policy, "RETURN") == 0) {
xtables_error(PARAMETER_PROBLEM, xtables_error(PARAMETER_PROBLEM,
"Policy RETURN only allowed for user defined chains"); "Policy RETURN only allowed for user defined chains");
} }
ret = nft_chain_set(h, *table, chain, policy, NULL); ret = nft_cmd_chain_set(h, *table, chain, policy, NULL);
if (ret < 0) if (ret < 0)
xtables_error(PARAMETER_PROBLEM, "Wrong policy"); xtables_error(PARAMETER_PROBLEM, "Wrong policy");
} }
...@@ -1243,9 +1262,9 @@ print_zero: ...@@ -1243,9 +1262,9 @@ print_zero:
flags&LIST_C); flags&LIST_C);
} }
if (flags & OPT_ZERO) { if (flags & OPT_ZERO) {
ret = nft_chain_zero_counters(h, chain, *table, 0); ret = nft_cmd_chain_zero_counters(h, chain, *table, 0);
} else if (command == 'F') { } else if (command == 'F') {
ret = nft_rule_flush(h, chain, *table, 0); ret = nft_cmd_rule_flush(h, chain, *table, 0);
} else if (command == 'A') { } else if (command == 'A') {
ret = append_entry(h, chain, *table, &cs, 0, 0, true); ret = append_entry(h, chain, *table, &cs, 0, 0, true);
} else if (command == 'I') { } else if (command == 'I') {
......
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
*/ */
#define _GNU_SOURCE #define _GNU_SOURCE
#include "config.h"
#include <errno.h>
#include <stdlib.h> #include <stdlib.h>
#include <time.h> #include <time.h>
#include <string.h> #include <string.h>
...@@ -40,6 +42,7 @@ ...@@ -40,6 +42,7 @@
struct cb_arg { struct cb_arg {
uint32_t nfproto; uint32_t nfproto;
bool is_event; bool is_event;
struct nft_handle *h;
}; };
static int table_cb(const struct nlmsghdr *nlh, void *data) static int table_cb(const struct nlmsghdr *nlh, void *data)
...@@ -105,7 +108,7 @@ static int rule_cb(const struct nlmsghdr *nlh, void *data) ...@@ -105,7 +108,7 @@ static int rule_cb(const struct nlmsghdr *nlh, void *data)
} }
printf("-t %s ", nftnl_rule_get_str(r, NFTNL_RULE_TABLE)); printf("-t %s ", nftnl_rule_get_str(r, NFTNL_RULE_TABLE));
nft_rule_print_save(r, type == NFT_MSG_NEWRULE ? NFT_RULE_APPEND : nft_rule_print_save(arg->h, r, type == NFT_MSG_NEWRULE ? NFT_RULE_APPEND :
NFT_RULE_DEL, NFT_RULE_DEL,
counters ? 0 : FMT_NOCOUNTS); counters ? 0 : FMT_NOCOUNTS);
err_free: err_free:
...@@ -592,7 +595,10 @@ int xtables_monitor_main(int argc, char *argv[]) ...@@ -592,7 +595,10 @@ int xtables_monitor_main(int argc, char *argv[])
struct mnl_socket *nl; struct mnl_socket *nl;
char buf[MNL_SOCKET_BUFFER_SIZE]; char buf[MNL_SOCKET_BUFFER_SIZE];
uint32_t nfgroup = 0; uint32_t nfgroup = 0;
struct cb_arg cb_arg = {}; struct nft_handle h = {};
struct cb_arg cb_arg = {
.h = &h,
};
int ret, c; int ret, c;
xtables_globals.program_name = "xtables-monitor"; xtables_globals.program_name = "xtables-monitor";
...@@ -609,6 +615,14 @@ int xtables_monitor_main(int argc, char *argv[]) ...@@ -609,6 +615,14 @@ int xtables_monitor_main(int argc, char *argv[])
init_extensions4(); init_extensions4();
#endif #endif
if (nft_init(&h, AF_INET, xtables_ipv4)) {
fprintf(stderr, "%s/%s Failed to initialize nft: %s\n",
xtables_globals.program_name,
xtables_globals.program_version,
strerror(errno));
exit(EXIT_FAILURE);
}
opterr = 0; opterr = 0;
while ((c = getopt_long(argc, argv, "ceht46V", options, NULL)) != -1) { while ((c = getopt_long(argc, argv, "ceht46V", options, NULL)) != -1) {
switch (c) { switch (c) {
...@@ -631,10 +645,10 @@ int xtables_monitor_main(int argc, char *argv[]) ...@@ -631,10 +645,10 @@ int xtables_monitor_main(int argc, char *argv[])
cb_arg.nfproto = NFPROTO_IPV6; cb_arg.nfproto = NFPROTO_IPV6;
break; break;
case 'V': case 'V':
printf("xtables-monitor %s\n", IPTABLES_VERSION); printf("xtables-monitor %s\n", PACKAGE_VERSION);
exit(0); exit(0);
default: default:
fprintf(stderr, "xtables-monitor %s: Bad argument.\n", IPTABLES_VERSION); fprintf(stderr, "xtables-monitor %s: Bad argument.\n", PACKAGE_VERSION);
fprintf(stderr, "Try `xtables-monitor -h' for more information.\n"); fprintf(stderr, "Try `xtables-monitor -h' for more information.\n");
exit(PARAMETER_PROBLEM); exit(PARAMETER_PROBLEM);
} }
...@@ -674,6 +688,8 @@ int xtables_monitor_main(int argc, char *argv[]) ...@@ -674,6 +688,8 @@ int xtables_monitor_main(int argc, char *argv[])
} }
mnl_socket_close(nl); mnl_socket_close(nl);
xtables_fini();
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
...@@ -4,9 +4,10 @@ ...@@ -4,9 +4,10 @@
* *
* This code is distributed under the terms of GNU GPL v2 * This code is distributed under the terms of GNU GPL v2
*/ */
#include "config.h"
#include <getopt.h> #include <getopt.h>
#include <errno.h> #include <errno.h>
#include <libgen.h>
#include <stdbool.h> #include <stdbool.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
...@@ -17,6 +18,7 @@ ...@@ -17,6 +18,7 @@
#include "xtables-multi.h" #include "xtables-multi.h"
#include "nft.h" #include "nft.h"
#include "nft-bridge.h" #include "nft-bridge.h"
#include "nft-cache.h"
#include <libnftnl/chain.h> #include <libnftnl/chain.h>
static int counters, verbose; static int counters, verbose;
...@@ -43,7 +45,7 @@ static const struct option options[] = { ...@@ -43,7 +45,7 @@ static const struct option options[] = {
static void print_usage(const char *name, const char *version) static void print_usage(const char *name, const char *version)
{ {
fprintf(stderr, "Usage: %s [-c] [-v] [-V] [-t] [-h] [-n] [-T table] [-M command] [-4] [-6]\n" fprintf(stderr, "Usage: %s [-c] [-v] [-V] [-t] [-h] [-n] [-T table] [-M command] [-4] [-6] [file]\n"
" [ --counters ]\n" " [ --counters ]\n"
" [ --verbose ]\n" " [ --verbose ]\n"
" [ --version]\n" " [ --version]\n"
...@@ -56,59 +58,41 @@ static void print_usage(const char *name, const char *version) ...@@ -56,59 +58,41 @@ static void print_usage(const char *name, const char *version)
" [ --ipv6 ]\n", name); " [ --ipv6 ]\n", name);
} }
static struct nftnl_chain_list *get_chain_list(struct nft_handle *h, static const struct nft_xt_restore_cb restore_cb = {
const char *table)
{
struct nftnl_chain_list *chain_list;
chain_list = nft_chain_list_get(h, table);
if (chain_list == NULL)
xtables_error(OTHER_PROBLEM, "cannot retrieve chain list\n");
return chain_list;
}
struct nft_xt_restore_cb restore_cb = {
.chain_list = get_chain_list,
.commit = nft_commit, .commit = nft_commit,
.abort = nft_abort, .abort = nft_abort,
.table_new = nft_table_new, .table_new = nft_cmd_table_new,
.table_flush = nft_table_flush, .table_flush = nft_cmd_table_flush,
.do_command = do_commandx, .do_command = do_commandx,
.chain_set = nft_chain_set, .chain_set = nft_cmd_chain_set,
.chain_restore = nft_chain_restore, .chain_restore = nft_cmd_chain_restore,
}; };
static const struct xtc_ops xtc_ops = { struct nft_xt_restore_state {
.strerror = nft_strerror, const struct builtin_table *curtable;
struct argv_store av_store;
bool in_table;
}; };
void xtables_restore_parse(struct nft_handle *h, static void xtables_restore_parse_line(struct nft_handle *h,
struct nft_xt_restore_parse *p, const struct nft_xt_restore_parse *p,
struct nft_xt_restore_cb *cb, struct nft_xt_restore_state *state,
int argc, char *argv[]) char *buffer)
{ {
const struct builtin_table *curtable = NULL; const struct nft_xt_restore_cb *cb = p->cb;
char buffer[10240];
int in_table = 0;
const struct xtc_ops *ops = &xtc_ops;
line = 0;
/* Grab standard input. */
while (fgets(buffer, sizeof(buffer), p->in)) {
int ret = 0; int ret = 0;
line++;
h->error.lineno = line;
if (buffer[0] == '\n') if (buffer[0] == '\n')
continue; return;
else if (buffer[0] == '#') { else if (buffer[0] == '#') {
if (verbose) if (verbose) {
fputs(buffer, stdout); fputs(buffer, stdout);
continue; fflush(stdout);
} else if ((strcmp(buffer, "COMMIT\n") == 0) && (in_table)) { }
return;
} else if (state->in_table &&
(strncmp(buffer, "COMMIT", 6) == 0) &&
(buffer[6] == '\0' || buffer[6] == '\n')) {
if (!p->testing) { if (!p->testing) {
/* Commit per table, although we support /* Commit per table, although we support
* global commit at once, stick by now to * global commit at once, stick by now to
...@@ -122,168 +106,128 @@ void xtables_restore_parse(struct nft_handle *h, ...@@ -122,168 +106,128 @@ void xtables_restore_parse(struct nft_handle *h,
if (cb->abort) if (cb->abort)
ret = cb->abort(h); ret = cb->abort(h);
} }
in_table = 0; state->in_table = false;
} else if ((buffer[0] == '*') && (!in_table || !p->commit)) { } else if ((buffer[0] == '*') && (!state->in_table || !p->commit)) {
/* New table */ /* New table */
char *table; char *table;
table = strtok(buffer+1, " \t\n"); table = strtok(buffer+1, " \t\n");
DEBUGP("line %u, table '%s'\n", line, table); DEBUGP("line %u, table '%s'\n", line, table);
if (!table) { if (!table)
xtables_error(PARAMETER_PROBLEM, xtables_error(PARAMETER_PROBLEM,
"%s: line %u table name invalid\n", "%s: line %u table name invalid\n",
xt_params->program_name, line); xt_params->program_name, line);
exit(1);
} state->curtable = nft_table_builtin_find(h, table);
curtable = nft_table_builtin_find(h, table); if (!state->curtable)
if (!curtable)
xtables_error(PARAMETER_PROBLEM, xtables_error(PARAMETER_PROBLEM,
"%s: line %u table name '%s' invalid\n", "%s: line %u table name '%s' invalid\n",
xt_params->program_name, line, table); xt_params->program_name, line, table);
if (p->tablename && (strcmp(p->tablename, table) != 0)) if (p->tablename && (strcmp(p->tablename, table) != 0))
continue; return;
nft_build_cache(h); /* implicit commit if no explicit COMMIT supported */
if (!p->commit)
cb->commit(h);
if (h->noflush == 0) { if (h->noflush == 0) {
DEBUGP("Cleaning all chains of table '%s'\n", DEBUGP("Cleaning all chains of table '%s'\n", table);
table);
if (cb->table_flush) if (cb->table_flush)
cb->table_flush(h, table); cb->table_flush(h, table);
} }
ret = 1; ret = 1;
in_table = 1; state->in_table = true;
if (cb->table_new) if (cb->table_new)
cb->table_new(h, table); cb->table_new(h, table);
} else if ((buffer[0] == ':') && (in_table)) { } else if ((buffer[0] == ':') && state->in_table) {
/* New chain. */ /* New chain. */
char *policy, *chain = NULL; char *policy, *chain = NULL;
struct xt_counters count = {}; struct xt_counters count = {};
chain = strtok(buffer+1, " \t\n"); chain = strtok(buffer+1, " \t\n");
DEBUGP("line %u, chain '%s'\n", line, chain); DEBUGP("line %u, chain '%s'\n", line, chain);
if (!chain) { if (!chain)
xtables_error(PARAMETER_PROBLEM, xtables_error(PARAMETER_PROBLEM,
"%s: line %u chain name invalid\n", "%s: line %u chain name invalid\n",
xt_params->program_name, line); xt_params->program_name, line);
exit(1);
}
if (strlen(chain) >= XT_EXTENSION_MAXNAMELEN) if (strlen(chain) >= XT_EXTENSION_MAXNAMELEN)
xtables_error(PARAMETER_PROBLEM, xtables_error(PARAMETER_PROBLEM,
"Invalid chain name `%s' " "Invalid chain name `%s' (%u chars max)",
"(%u chars max)",
chain, XT_EXTENSION_MAXNAMELEN - 1); chain, XT_EXTENSION_MAXNAMELEN - 1);
policy = strtok(NULL, " \t\n"); policy = strtok(NULL, " \t\n");
DEBUGP("line %u, policy '%s'\n", line, policy); DEBUGP("line %u, policy '%s'\n", line, policy);
if (!policy) { if (!policy)
xtables_error(PARAMETER_PROBLEM, xtables_error(PARAMETER_PROBLEM,
"%s: line %u policy invalid\n", "%s: line %u policy invalid\n",
xt_params->program_name, line); xt_params->program_name, line);
exit(1);
}
if (nft_chain_builtin_find(curtable, chain)) { if (nft_chain_builtin_find(state->curtable, chain)) {
if (counters) { if (counters) {
char *ctrs; char *ctrs;
ctrs = strtok(NULL, " \t\n"); ctrs = strtok(NULL, " \t\n");
if (!ctrs || !parse_counters(ctrs, &count)) if (!ctrs || !parse_counters(ctrs, &count))
xtables_error(PARAMETER_PROBLEM, xtables_error(PARAMETER_PROBLEM,
"invalid policy counters " "invalid policy counters for chain '%s'\n",
"for chain '%s'\n", chain); chain);
} }
if (cb->chain_set && if (cb->chain_set &&
cb->chain_set(h, curtable->name, cb->chain_set(h, state->curtable->name,
chain, policy, &count) < 0) { chain, policy, &count) < 0) {
xtables_error(OTHER_PROBLEM, xtables_error(OTHER_PROBLEM,
"Can't set policy `%s'" "Can't set policy `%s' on `%s' line %u: %s\n",
" on `%s' line %u: %s\n",
policy, chain, line, policy, chain, line,
ops->strerror(errno)); strerror(errno));
} }
DEBUGP("Setting policy of chain %s to %s\n", DEBUGP("Setting policy of chain %s to %s\n",
chain, policy); chain, policy);
} else if (cb->chain_restore(h, chain, curtable->name) < 0 && } else if (cb->chain_restore(h, chain, state->curtable->name) < 0 &&
errno != EEXIST) { errno != EEXIST) {
xtables_error(PARAMETER_PROBLEM, xtables_error(PARAMETER_PROBLEM,
"cannot create chain " "cannot create chain '%s' (%s)\n",
"'%s' (%s)\n", chain, chain, strerror(errno));
strerror(errno));
} else if (h->family == NFPROTO_BRIDGE && } else if (h->family == NFPROTO_BRIDGE &&
!ebt_set_user_chain_policy(h, curtable->name, !ebt_cmd_user_chain_policy(h, state->curtable->name,
chain, policy)) { chain, policy)) {
xtables_error(OTHER_PROBLEM, xtables_error(OTHER_PROBLEM,
"Can't set policy `%s'" "Can't set policy `%s' on `%s' line %u: %s\n",
" on `%s' line %u: %s\n",
policy, chain, line, policy, chain, line,
ops->strerror(errno)); strerror(errno));
} }
ret = 1; ret = 1;
} else if (in_table) { } else if (state->in_table) {
int a;
char *pcnt = NULL; char *pcnt = NULL;
char *bcnt = NULL; char *bcnt = NULL;
char *parsestart; char *parsestart = buffer;
/* reset the newargv */
newargc = 0;
if (buffer[0] == '[') {
/* we have counters in our input */
char *ptr = strchr(buffer, ']');
if (!ptr)
xtables_error(PARAMETER_PROBLEM,
"Bad line %u: need ]\n",
line);
pcnt = strtok(buffer+1, ":");
if (!pcnt)
xtables_error(PARAMETER_PROBLEM,
"Bad line %u: need :\n",
line);
bcnt = strtok(NULL, "]");
if (!bcnt)
xtables_error(PARAMETER_PROBLEM,
"Bad line %u: need ]\n",
line);
/* start command parsing after counter */
parsestart = ptr + 1;
} else {
/* start command parsing at start of line */
parsestart = buffer;
}
add_argv(argv[0], 0); add_argv(&state->av_store, xt_params->program_name, 0);
add_argv("-t", 0); add_argv(&state->av_store, "-t", 0);
add_argv(curtable->name, 0); add_argv(&state->av_store, state->curtable->name, 0);
tokenize_rule_counters(&parsestart, &pcnt, &bcnt, line);
if (counters && pcnt && bcnt) { if (counters && pcnt && bcnt) {
add_argv("--set-counters", 0); add_argv(&state->av_store, "--set-counters", 0);
add_argv((char *) pcnt, 0); add_argv(&state->av_store, pcnt, 0);
add_argv((char *) bcnt, 0); add_argv(&state->av_store, bcnt, 0);
} }
add_param_to_argv(parsestart, line); add_param_to_argv(&state->av_store, parsestart, line);
DEBUGP("calling do_command4(%u, argv, &%s, handle):\n", DEBUGP("calling do_command4(%u, argv, &%s, handle):\n",
newargc, curtable->name); state->av_store.argc, state->curtable->name);
debug_print_argv(&state->av_store);
for (a = 0; a < newargc; a++) ret = cb->do_command(h, state->av_store.argc,
DEBUGP("argv[%u]: %s\n", a, newargv[a]); state->av_store.argv,
&state->av_store.argv[2], true);
ret = cb->do_command(h, newargc, newargv,
&newargv[2], true);
if (ret < 0) { if (ret < 0) {
if (cb->abort) if (cb->abort)
ret = cb->abort(h); ret = cb->abort(h);
...@@ -291,29 +235,45 @@ void xtables_restore_parse(struct nft_handle *h, ...@@ -291,29 +235,45 @@ void xtables_restore_parse(struct nft_handle *h,
ret = 0; ret = 0;
if (ret < 0) { if (ret < 0) {
fprintf(stderr, "failed to abort " fprintf(stderr,
"commit operation\n"); "failed to abort commit operation\n");
} }
exit(1); exit(1);
} }
free_argv(); free_argv(&state->av_store);
fflush(stdout); fflush(stdout);
} }
if (p->tablename && curtable && if (p->tablename && state->curtable &&
(strcmp(p->tablename, curtable->name) != 0)) (strcmp(p->tablename, state->curtable->name) != 0))
continue; return;
if (!ret) { if (!ret) {
fprintf(stderr, "%s: line %u failed\n", fprintf(stderr, "%s: line %u failed\n",
xt_params->program_name, line); xt_params->program_name, line);
exit(1); exit(1);
} }
}
void xtables_restore_parse(struct nft_handle *h,
const struct nft_xt_restore_parse *p)
{
struct nft_xt_restore_state state = {};
char buffer[10240] = {};
if (!h->noflush)
nft_cache_level_set(h, NFT_CL_FAKE, NULL);
line = 0;
while (fgets(buffer, sizeof(buffer), p->in)) {
h->error.lineno = ++line;
DEBUGP("%s: input line %d: '%s'\n", __func__, line, buffer);
xtables_restore_parse_line(h, p, &state, buffer);
} }
if (in_table && p->commit) { if (state.in_table && p->commit) {
fprintf(stderr, "%s: COMMIT expected at line %u\n", fprintf(stderr, "%s: COMMIT expected at line %u\n",
xt_params->program_name, line + 1); xt_params->program_name, line + 1);
exit(1); exit(1);
} else if (in_table && cb->commit && !cb->commit(h)) { } else if (state.in_table && p->cb->commit && !p->cb->commit(h)) {
xtables_error(OTHER_PROBLEM, "%s: final implicit COMMIT failed", xtables_error(OTHER_PROBLEM, "%s: final implicit COMMIT failed",
xt_params->program_name); xt_params->program_name);
} }
...@@ -323,14 +283,13 @@ static int ...@@ -323,14 +283,13 @@ static int
xtables_restore_main(int family, const char *progname, int argc, char *argv[]) xtables_restore_main(int family, const char *progname, int argc, char *argv[])
{ {
const struct builtin_table *tables; const struct builtin_table *tables;
struct nft_handle h = {
.family = family,
.restore = true,
};
int c;
struct nft_xt_restore_parse p = { struct nft_xt_restore_parse p = {
.commit = true, .commit = true,
.cb = &restore_cb,
}; };
bool noflush = false;
struct nft_handle h;
int c;
line = 0; line = 0;
...@@ -343,7 +302,7 @@ xtables_restore_main(int family, const char *progname, int argc, char *argv[]) ...@@ -343,7 +302,7 @@ xtables_restore_main(int family, const char *progname, int argc, char *argv[])
exit(1); exit(1);
} }
while ((c = getopt_long(argc, argv, "bcvVthnM:T:46wW", options, NULL)) != -1) { while ((c = getopt_long(argc, argv, "bcvVthnM:T:wW", options, NULL)) != -1) {
switch (c) { switch (c) {
case 'b': case 'b':
fprintf(stderr, "-b/--binary option is not implemented\n"); fprintf(stderr, "-b/--binary option is not implemented\n");
...@@ -361,11 +320,10 @@ xtables_restore_main(int family, const char *progname, int argc, char *argv[]) ...@@ -361,11 +320,10 @@ xtables_restore_main(int family, const char *progname, int argc, char *argv[])
p.testing = 1; p.testing = 1;
break; break;
case 'h': case 'h':
print_usage("xtables-restore", print_usage(prog_name, PACKAGE_VERSION);
IPTABLES_VERSION);
exit(0); exit(0);
case 'n': case 'n':
h.noflush = 1; noflush = true;
break; break;
case 'M': case 'M':
xtables_modprobe_program = optarg; xtables_modprobe_program = optarg;
...@@ -373,13 +331,6 @@ xtables_restore_main(int family, const char *progname, int argc, char *argv[]) ...@@ -373,13 +331,6 @@ xtables_restore_main(int family, const char *progname, int argc, char *argv[])
case 'T': case 'T':
p.tablename = optarg; p.tablename = optarg;
break; break;
case '4':
h.family = AF_INET;
break;
case '6':
h.family = AF_INET6;
xtables_set_nfproto(AF_INET6);
break;
case 'w': /* fallthrough. Ignored by xt-restore */ case 'w': /* fallthrough. Ignored by xt-restore */
case 'W': case 'W':
if (!optarg && xs_has_arg(argc, argv)) if (!optarg && xs_has_arg(argc, argv))
...@@ -387,7 +338,8 @@ xtables_restore_main(int family, const char *progname, int argc, char *argv[]) ...@@ -387,7 +338,8 @@ xtables_restore_main(int family, const char *progname, int argc, char *argv[])
break; break;
default: default:
fprintf(stderr, fprintf(stderr,
"Try `xtables-restore -h' for more information.\n"); "Try `%s -h' for more information.\n",
prog_name);
exit(1); exit(1);
} }
} }
...@@ -426,48 +378,43 @@ xtables_restore_main(int family, const char *progname, int argc, char *argv[]) ...@@ -426,48 +378,43 @@ xtables_restore_main(int family, const char *progname, int argc, char *argv[])
return 1; return 1;
} }
if (nft_init(&h, tables) < 0) { if (nft_init(&h, family, tables) < 0) {
fprintf(stderr, "%s/%s Failed to initialize nft: %s\n", fprintf(stderr, "%s/%s Failed to initialize nft: %s\n",
xtables_globals.program_name, xtables_globals.program_name,
xtables_globals.program_version, xtables_globals.program_version,
strerror(errno)); strerror(errno));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
h.noflush = noflush;
h.restore = true;
xtables_restore_parse(&h, &p, &restore_cb, argc, argv); xtables_restore_parse(&h, &p);
nft_fini(&h); nft_fini(&h);
xtables_fini();
fclose(p.in); fclose(p.in);
return 0; return 0;
} }
int xtables_ip4_restore_main(int argc, char *argv[]) int xtables_ip4_restore_main(int argc, char *argv[])
{ {
return xtables_restore_main(NFPROTO_IPV4, "iptables-restore", return xtables_restore_main(NFPROTO_IPV4, basename(*argv),
argc, argv); argc, argv);
} }
int xtables_ip6_restore_main(int argc, char *argv[]) int xtables_ip6_restore_main(int argc, char *argv[])
{ {
return xtables_restore_main(NFPROTO_IPV6, "ip6tables-restore", return xtables_restore_main(NFPROTO_IPV6, basename(*argv),
argc, argv); argc, argv);
} }
static int ebt_table_flush(struct nft_handle *h, const char *table) static const struct nft_xt_restore_cb ebt_restore_cb = {
{ .commit = nft_bridge_commit,
/* drop any pending policy rule add/removal jobs */ .table_new = nft_cmd_table_new,
nft_abort_policy_rule(h, table); .table_flush = nft_cmd_table_flush,
return nft_table_flush(h, table);
}
struct nft_xt_restore_cb ebt_restore_cb = {
.chain_list = get_chain_list,
.commit = nft_commit,
.table_new = nft_table_new,
.table_flush = ebt_table_flush,
.do_command = do_commandeb, .do_command = do_commandeb,
.chain_set = nft_chain_set, .chain_set = nft_cmd_chain_set,
.chain_restore = nft_chain_restore, .chain_restore = nft_cmd_chain_restore,
}; };
static const struct option ebt_restore_options[] = { static const struct option ebt_restore_options[] = {
...@@ -479,6 +426,7 @@ int xtables_eb_restore_main(int argc, char *argv[]) ...@@ -479,6 +426,7 @@ int xtables_eb_restore_main(int argc, char *argv[])
{ {
struct nft_xt_restore_parse p = { struct nft_xt_restore_parse p = {
.in = stdin, .in = stdin,
.cb = &ebt_restore_cb,
}; };
bool noflush = false; bool noflush = false;
struct nft_handle h; struct nft_handle h;
...@@ -500,32 +448,33 @@ int xtables_eb_restore_main(int argc, char *argv[]) ...@@ -500,32 +448,33 @@ int xtables_eb_restore_main(int argc, char *argv[])
nft_init_eb(&h, "ebtables-restore"); nft_init_eb(&h, "ebtables-restore");
h.noflush = noflush; h.noflush = noflush;
xtables_restore_parse(&h, &p, &ebt_restore_cb, argc, argv); xtables_restore_parse(&h, &p);
nft_fini(&h); nft_fini_eb(&h);
return 0; return 0;
} }
struct nft_xt_restore_cb arp_restore_cb = { static const struct nft_xt_restore_cb arp_restore_cb = {
.chain_list = get_chain_list,
.commit = nft_commit, .commit = nft_commit,
.table_new = nft_table_new, .table_new = nft_cmd_table_new,
.table_flush = nft_table_flush, .table_flush = nft_cmd_table_flush,
.do_command = do_commandarp, .do_command = do_commandarp,
.chain_set = nft_chain_set, .chain_set = nft_cmd_chain_set,
.chain_restore = nft_chain_restore, .chain_restore = nft_cmd_chain_restore,
}; };
int xtables_arp_restore_main(int argc, char *argv[]) int xtables_arp_restore_main(int argc, char *argv[])
{ {
struct nft_xt_restore_parse p = { struct nft_xt_restore_parse p = {
.in = stdin, .in = stdin,
.cb = &arp_restore_cb,
}; };
struct nft_handle h; struct nft_handle h;
nft_init_arp(&h, "arptables-restore"); nft_init_arp(&h, "arptables-restore");
xtables_restore_parse(&h, &p, &arp_restore_cb, argc, argv); xtables_restore_parse(&h, &p);
nft_fini(&h); nft_fini(&h);
xtables_fini();
return 0; return 0;
} }
...@@ -6,8 +6,10 @@ ...@@ -6,8 +6,10 @@
* This code is distributed under the terms of GNU GPL v2 * This code is distributed under the terms of GNU GPL v2
* *
*/ */
#include "config.h"
#include <getopt.h> #include <getopt.h>
#include <errno.h> #include <errno.h>
#include <libgen.h>
#include <stdio.h> #include <stdio.h>
#include <fcntl.h> #include <fcntl.h>
#include <stdlib.h> #include <stdlib.h>
...@@ -19,6 +21,7 @@ ...@@ -19,6 +21,7 @@
#include "iptables.h" #include "iptables.h"
#include "xtables-multi.h" #include "xtables-multi.h"
#include "nft.h" #include "nft.h"
#include "nft-cache.h"
#include <libnftnl/chain.h> #include <libnftnl/chain.h>
...@@ -29,20 +32,18 @@ ...@@ -29,20 +32,18 @@
#define prog_name xtables_globals.program_name #define prog_name xtables_globals.program_name
#define prog_vers xtables_globals.program_version #define prog_vers xtables_globals.program_version
static bool show_counters = false; static const char *ipt_save_optstring = "bcdt:M:f:V";
static const struct option ipt_save_options[] = {
static const struct option options[] = {
{.name = "counters", .has_arg = false, .val = 'c'}, {.name = "counters", .has_arg = false, .val = 'c'},
{.name = "version", .has_arg = false, .val = 'V'}, {.name = "version", .has_arg = false, .val = 'V'},
{.name = "dump", .has_arg = false, .val = 'd'}, {.name = "dump", .has_arg = false, .val = 'd'},
{.name = "table", .has_arg = true, .val = 't'}, {.name = "table", .has_arg = true, .val = 't'},
{.name = "modprobe", .has_arg = true, .val = 'M'}, {.name = "modprobe", .has_arg = true, .val = 'M'},
{.name = "file", .has_arg = true, .val = 'f'}, {.name = "file", .has_arg = true, .val = 'f'},
{.name = "ipv4", .has_arg = false, .val = '4'},
{.name = "ipv6", .has_arg = false, .val = '6'},
{NULL}, {NULL},
}; };
static const char *arp_save_optstring = "cM:V";
static const struct option arp_save_options[] = { static const struct option arp_save_options[] = {
{.name = "counters", .has_arg = false, .val = 'c'}, {.name = "counters", .has_arg = false, .val = 'c'},
{.name = "version", .has_arg = false, .val = 'V'}, {.name = "version", .has_arg = false, .val = 'V'},
...@@ -50,6 +51,7 @@ static const struct option arp_save_options[] = { ...@@ -50,6 +51,7 @@ static const struct option arp_save_options[] = {
{NULL}, {NULL},
}; };
static const char *ebt_save_optstring = "ct:M:V";
static const struct option ebt_save_options[] = { static const struct option ebt_save_options[] = {
{.name = "counters", .has_arg = false, .val = 'c'}, {.name = "counters", .has_arg = false, .val = 'c'},
{.name = "version", .has_arg = false, .val = 'V'}, {.name = "version", .has_arg = false, .val = 'V'},
...@@ -58,49 +60,55 @@ static const struct option ebt_save_options[] = { ...@@ -58,49 +60,55 @@ static const struct option ebt_save_options[] = {
{NULL}, {NULL},
}; };
static bool ebt_legacy_counter_format; struct do_output_data {
unsigned int format;
bool commit;
};
static int static int
__do_output(struct nft_handle *h, const char *tablename, bool counters) __do_output(struct nft_handle *h, const char *tablename, void *data)
{ {
struct nftnl_chain_list *chain_list; struct nftnl_chain_list *chain_list;
struct do_output_data *d = data;
time_t now;
if (!nft_is_table_compatible(h, tablename)) {
if (!nft_table_builtin_find(h, tablename)) if (!nft_table_builtin_find(h, tablename))
return 0;
if (!nft_is_table_compatible(h, tablename, NULL)) {
printf("# Table `%s' is incompatible, use 'nft' tool.\n", printf("# Table `%s' is incompatible, use 'nft' tool.\n",
tablename); tablename);
return 0; return 0;
} }
chain_list = nft_chain_list_get(h, tablename); chain_list = nft_chain_list_get(h, tablename, NULL);
if (!chain_list) if (!chain_list)
return 0; return 0;
time_t now = time(NULL); now = time(NULL);
printf("# Generated by %s v%s on %s", prog_name,
prog_vers, ctime(&now));
printf("# Generated by xtables-save v%s on %s",
IPTABLES_VERSION, ctime(&now));
printf("*%s\n", tablename); printf("*%s\n", tablename);
/* Dump out chain names first, /* Dump out chain names first,
* thereby preventing dependency conflicts */ * thereby preventing dependency conflicts */
nft_chain_save(h, chain_list); nft_chain_save(h, chain_list);
nft_rule_save(h, tablename, counters ? 0 : FMT_NOCOUNTS); nft_rule_save(h, tablename, d->format);
if (d->commit)
printf("COMMIT\n");
now = time(NULL); now = time(NULL);
printf("COMMIT\n");
printf("# Completed on %s", ctime(&now)); printf("# Completed on %s", ctime(&now));
return 0; return 0;
} }
static int static int
do_output(struct nft_handle *h, const char *tablename, bool counters) do_output(struct nft_handle *h, const char *tablename, struct do_output_data *d)
{ {
int ret; int ret;
if (!tablename) { if (!tablename) {
ret = nft_for_each_table(h, __do_output, counters); ret = nft_for_each_table(h, __do_output, d);
nft_check_xt_legacy(h->family, true); nft_check_xt_legacy(h->family, true);
return !!ret; return !!ret;
} }
...@@ -111,7 +119,7 @@ do_output(struct nft_handle *h, const char *tablename, bool counters) ...@@ -111,7 +119,7 @@ do_output(struct nft_handle *h, const char *tablename, bool counters)
return 1; return 1;
} }
ret = __do_output(h, tablename, counters); ret = __do_output(h, tablename, d);
nft_check_xt_legacy(h->family, true); nft_check_xt_legacy(h->family, true);
return ret; return ret;
} }
...@@ -121,18 +129,20 @@ do_output(struct nft_handle *h, const char *tablename, bool counters) ...@@ -121,18 +129,20 @@ do_output(struct nft_handle *h, const char *tablename, bool counters)
* rule * rule
*/ */
static int static int
xtables_save_main(int family, const char *progname, int argc, char *argv[]) xtables_save_main(int family, int argc, char *argv[],
const char *optstring, const struct option *longopts)
{ {
const struct builtin_table *tables; const struct builtin_table *tables;
const char *tablename = NULL; const char *tablename = NULL;
bool dump = false; struct do_output_data d = {
struct nft_handle h = { .format = FMT_NOCOUNTS,
.family = family,
}; };
struct nft_handle h;
bool dump = false;
FILE *file = NULL; FILE *file = NULL;
int ret, c; int ret, c;
xtables_globals.program_name = progname; xtables_globals.program_name = basename(*argv);;
c = xtables_init_all(&xtables_globals, family); c = xtables_init_all(&xtables_globals, family);
if (c < 0) { if (c < 0) {
fprintf(stderr, "%s/%s Failed to initialize xtables\n", fprintf(stderr, "%s/%s Failed to initialize xtables\n",
...@@ -141,13 +151,13 @@ xtables_save_main(int family, const char *progname, int argc, char *argv[]) ...@@ -141,13 +151,13 @@ xtables_save_main(int family, const char *progname, int argc, char *argv[])
exit(1); exit(1);
} }
while ((c = getopt_long(argc, argv, "bcdt:M:f:46V", options, NULL)) != -1) { while ((c = getopt_long(argc, argv, optstring, longopts, NULL)) != -1) {
switch (c) { switch (c) {
case 'b': case 'b':
fprintf(stderr, "-b/--binary option is not implemented\n"); fprintf(stderr, "-b/--binary option is not implemented\n");
break; break;
case 'c': case 'c':
show_counters = true; d.format &= ~FMT_NOCOUNTS;
break; break;
case 't': case 't':
...@@ -175,13 +185,6 @@ xtables_save_main(int family, const char *progname, int argc, char *argv[]) ...@@ -175,13 +185,6 @@ xtables_save_main(int family, const char *progname, int argc, char *argv[])
case 'd': case 'd':
dump = true; dump = true;
break; break;
case '4':
h.family = AF_INET;
break;
case '6':
h.family = AF_INET6;
xtables_set_nfproto(AF_INET6);
break;
case 'V': case 'V':
printf("%s v%s (nf_tables)\n", prog_name, prog_vers); printf("%s v%s (nf_tables)\n", prog_name, prog_vers);
exit(0); exit(0);
...@@ -206,19 +209,29 @@ xtables_save_main(int family, const char *progname, int argc, char *argv[]) ...@@ -206,19 +209,29 @@ xtables_save_main(int family, const char *progname, int argc, char *argv[])
init_extensions4(); init_extensions4();
#endif #endif
tables = xtables_ipv4; tables = xtables_ipv4;
d.commit = true;
break; break;
case NFPROTO_ARP: case NFPROTO_ARP:
tables = xtables_arp; tables = xtables_arp;
break; break;
case NFPROTO_BRIDGE: case NFPROTO_BRIDGE: {
const char *ctr = getenv("EBTABLES_SAVE_COUNTER");
if (!(d.format & FMT_NOCOUNTS)) {
d.format |= FMT_EBT_SAVE;
} else if (ctr && !strcmp(ctr, "yes")) {
d.format &= ~FMT_NOCOUNTS;
d.format |= FMT_C_COUNTS | FMT_EBT_SAVE;
}
tables = xtables_bridge; tables = xtables_bridge;
break; break;
}
default: default:
fprintf(stderr, "Unknown family %d\n", family); fprintf(stderr, "Unknown family %d\n", family);
return 1; return 1;
} }
if (nft_init(&h, tables) < 0) { if (nft_init(&h, family, tables) < 0) {
fprintf(stderr, "%s/%s Failed to initialize nft: %s\n", fprintf(stderr, "%s/%s Failed to initialize nft: %s\n",
xtables_globals.program_name, xtables_globals.program_name,
xtables_globals.program_version, xtables_globals.program_version,
...@@ -226,8 +239,12 @@ xtables_save_main(int family, const char *progname, int argc, char *argv[]) ...@@ -226,8 +239,12 @@ xtables_save_main(int family, const char *progname, int argc, char *argv[])
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
ret = do_output(&h, tablename, show_counters); nft_cache_level_set(&h, NFT_CL_RULES, NULL);
nft_cache_build(&h);
ret = do_output(&h, tablename, &d);
nft_fini(&h); nft_fini(&h);
xtables_fini();
if (dump) if (dump)
exit(0); exit(0);
...@@ -236,178 +253,24 @@ xtables_save_main(int family, const char *progname, int argc, char *argv[]) ...@@ -236,178 +253,24 @@ xtables_save_main(int family, const char *progname, int argc, char *argv[])
int xtables_ip4_save_main(int argc, char *argv[]) int xtables_ip4_save_main(int argc, char *argv[])
{ {
return xtables_save_main(NFPROTO_IPV4, "iptables-save", argc, argv); return xtables_save_main(NFPROTO_IPV4, argc, argv,
ipt_save_optstring, ipt_save_options);
} }
int xtables_ip6_save_main(int argc, char *argv[]) int xtables_ip6_save_main(int argc, char *argv[])
{ {
return xtables_save_main(NFPROTO_IPV6, "ip6tables-save", argc, argv); return xtables_save_main(NFPROTO_IPV6, argc, argv,
ipt_save_optstring, ipt_save_options);
} }
static int __ebt_save(struct nft_handle *h, const char *tablename, bool counters) int xtables_eb_save_main(int argc, char *argv[])
{ {
struct nftnl_chain_list *chain_list; return xtables_save_main(NFPROTO_BRIDGE, argc, argv,
unsigned int format = FMT_NOCOUNTS; ebt_save_optstring, ebt_save_options);
static bool first = true;
time_t now;
if (!nft_table_find(h, tablename)) {
printf("Table `%s' does not exist\n", tablename);
return 1;
}
if (!nft_is_table_compatible(h, tablename)) {
printf("# Table `%s' is incompatible, use 'nft' tool.\n", tablename);
return 0;
}
chain_list = nft_chain_list_get(h, tablename);
if (first) {
now = time(NULL);
printf("# Generated by ebtables-save v%s on %s",
IPTABLES_VERSION, ctime(&now));
first = false;
}
printf("*%s\n", tablename);
if (counters)
format = ebt_legacy_counter_format ? FMT_EBT_SAVE : 0;
/* Dump out chain names first,
* thereby preventing dependency conflicts */
nft_chain_save(h, chain_list);
nft_rule_save(h, tablename, format);
printf("\n");
return 0;
}
static int ebt_save(struct nft_handle *h, const char *tablename, bool counters)
{
if (!tablename)
return nft_for_each_table(h, __ebt_save, counters);
return __ebt_save(h, tablename, counters);
} }
int xtables_eb_save_main(int argc_, char *argv_[]) int xtables_arp_save_main(int argc, char *argv[])
{ {
const char *ctr = getenv("EBTABLES_SAVE_COUNTER"); return xtables_save_main(NFPROTO_ARP, argc, argv,
const char *tablename = NULL; arp_save_optstring, arp_save_options);
struct nft_handle h = {
.family = NFPROTO_BRIDGE,
};
int c;
if (ctr) {
if (strcmp(ctr, "yes") == 0) {
ebt_legacy_counter_format = true;
show_counters = true;
}
}
xtables_globals.program_name = "ebtables-save";
c = xtables_init_all(&xtables_globals, h.family);
if (c < 0) {
fprintf(stderr, "%s/%s Failed to initialize xtables\n",
xtables_globals.program_name,
xtables_globals.program_version);
exit(1);
}
while ((c = getopt_long(argc_, argv_, "ct:M:V", ebt_save_options, NULL)) != -1) {
switch (c) {
case 'c':
unsetenv("EBTABLES_SAVE_COUNTER");
show_counters = true;
ebt_legacy_counter_format = false;
break;
case 't':
/* Select specific table. */
tablename = optarg;
break;
case 'M':
xtables_modprobe_program = optarg;
break;
case 'V':
printf("%s v%s (nf_tables)\n", prog_name, prog_vers);
exit(0);
default:
fprintf(stderr,
"Look at manual page `%s.8' for more information.\n",
prog_name);
exit(1);
}
}
if (nft_init(&h, xtables_bridge) < 0) {
fprintf(stderr, "%s/%s Failed to initialize nft: %s\n",
xtables_globals.program_name,
xtables_globals.program_version,
strerror(errno));
exit(EXIT_FAILURE);
}
ebt_save(&h, tablename, show_counters);
nft_fini(&h);
return 0;
}
int xtables_arp_save_main(int argc, char **argv)
{
struct nft_handle h = {
.family = NFPROTO_ARP,
};
int c;
xtables_globals.program_name = "arptables-save";
c = xtables_init_all(&xtables_globals, h.family);
if (c < 0) {
fprintf(stderr, "%s/%s Failed to initialize xtables\n",
xtables_globals.program_name,
xtables_globals.program_version);
exit(1);
}
while ((c = getopt_long(argc, argv, "cM:V", arp_save_options, NULL)) != -1) {
switch (c) {
case 'c':
show_counters = true;
break;
case 'M':
xtables_modprobe_program = optarg;
break;
case 'V':
printf("%s v%s (nf_tables)\n", prog_name, prog_vers);
exit(0);
default:
fprintf(stderr,
"Look at manual page `%s.8' for more information.\n",
prog_name);
exit(1);
}
}
if (nft_init(&h, xtables_arp) < 0) {
fprintf(stderr, "%s/%s Failed to initialize nft: %s\n",
xtables_globals.program_name,
xtables_globals.program_version,
strerror(errno));
exit(EXIT_FAILURE);
}
if (!nft_table_find(&h, "filter"))
return 0;
if (!nft_is_table_compatible(&h, "filter")) {
printf("# Table `filter' is incompatible, use 'nft' tool.\n");
return 0;
}
printf("*filter\n");
nft_chain_save(&h, nft_chain_list_get(&h, "filter"));
nft_rule_save(&h, "filter", show_counters ? 0 : FMT_NOCOUNTS);
printf("\n");
nft_fini(&h);
return 0;
} }
...@@ -44,9 +44,7 @@ xtables_main(int family, const char *progname, int argc, char *argv[]) ...@@ -44,9 +44,7 @@ xtables_main(int family, const char *progname, int argc, char *argv[])
{ {
int ret; int ret;
char *table = "filter"; char *table = "filter";
struct nft_handle h = { struct nft_handle h;
.family = family,
};
xtables_globals.program_name = progname; xtables_globals.program_name = progname;
ret = xtables_init_all(&xtables_globals, family); ret = xtables_init_all(&xtables_globals, family);
...@@ -61,7 +59,7 @@ xtables_main(int family, const char *progname, int argc, char *argv[]) ...@@ -61,7 +59,7 @@ xtables_main(int family, const char *progname, int argc, char *argv[])
init_extensions4(); init_extensions4();
#endif #endif
if (nft_init(&h, xtables_ipv4) < 0) { if (nft_init(&h, family, xtables_ipv4) < 0) {
fprintf(stderr, "%s/%s Failed to initialize nft: %s\n", fprintf(stderr, "%s/%s Failed to initialize nft: %s\n",
xtables_globals.program_name, xtables_globals.program_name,
xtables_globals.program_version, xtables_globals.program_version,
...@@ -74,6 +72,7 @@ xtables_main(int family, const char *progname, int argc, char *argv[]) ...@@ -74,6 +72,7 @@ xtables_main(int family, const char *progname, int argc, char *argv[])
ret = nft_commit(&h); ret = nft_commit(&h);
nft_fini(&h); nft_fini(&h);
xtables_fini();
if (!ret) { if (!ret) {
if (errno == EINVAL) { if (errno == EINVAL) {
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* by the Free Software Foundation; either version 2 of the License, or * by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
*/ */
#include "config.h"
#include <time.h> #include <time.h>
#include "xtables-multi.h" #include "xtables-multi.h"
#include "nft.h" #include "nft.h"
...@@ -32,16 +32,38 @@ ...@@ -32,16 +32,38 @@
void xlate_ifname(struct xt_xlate *xl, const char *nftmeta, const char *ifname, void xlate_ifname(struct xt_xlate *xl, const char *nftmeta, const char *ifname,
bool invert) bool invert)
{ {
char iface[IFNAMSIZ]; int ifaclen = strlen(ifname), i, j;
int ifaclen; char iface[IFNAMSIZ * 2];
if (ifaclen < 1 || ifaclen >= IFNAMSIZ)
return;
for (i = 0, j = 0; i < ifaclen + 1; i++, j++) {
switch (ifname[i]) {
case '*':
iface[j++] = '\\';
/* fall through */
default:
iface[j] = ifname[i];
break;
}
}
if (ifname[0] == '\0') if (ifaclen == 1 && ifname[0] == '+') {
/* Nftables does not support wildcard only string. Workaround
* is easy, given that this will match always or never
* depending on 'invert' value. To match always, simply don't
* generate an expression. To match never, use an invalid
* interface name (kernel doesn't accept '/' in names) to match
* against. */
if (!invert)
return; return;
strcpy(iface, "INVAL/D");
invert = false;
}
strcpy(iface, ifname); if (iface[j - 2] == '+')
ifaclen = strlen(iface); iface[j - 2] = '*';
if (iface[ifaclen - 1] == '+')
iface[ifaclen - 1] = '*';
xt_xlate_add(xl, "%s %s\"%s\" ", nftmeta, invert ? "!= " : "", iface); xt_xlate_add(xl, "%s %s\"%s\" ", nftmeta, invert ? "!= " : "", iface);
} }
...@@ -413,7 +435,7 @@ static int dummy_compat_rev(const char *name, uint8_t rev, int opt) ...@@ -413,7 +435,7 @@ static int dummy_compat_rev(const char *name, uint8_t rev, int opt)
return 1; return 1;
} }
static struct nft_xt_restore_cb cb_xlate = { static const struct nft_xt_restore_cb cb_xlate = {
.table_new = xlate_table_new, .table_new = xlate_table_new,
.chain_set = xlate_chain_set, .chain_set = xlate_chain_set,
.chain_restore = xlate_chain_user_restore, .chain_restore = xlate_chain_user_restore,
...@@ -458,7 +480,7 @@ static int xtables_xlate_main_common(struct nft_handle *h, ...@@ -458,7 +480,7 @@ static int xtables_xlate_main_common(struct nft_handle *h,
return 1; return 1;
} }
if (nft_init(h, tables) < 0) { if (nft_init(h, family, tables) < 0) {
fprintf(stderr, "%s/%s Failed to initialize nft: %s\n", fprintf(stderr, "%s/%s Failed to initialize nft: %s\n",
xtables_globals.program_name, xtables_globals.program_name,
xtables_globals.program_version, xtables_globals.program_version,
...@@ -487,6 +509,7 @@ static int xtables_xlate_main(int family, const char *progname, int argc, ...@@ -487,6 +509,7 @@ static int xtables_xlate_main(int family, const char *progname, int argc,
fprintf(stderr, "Translation not implemented\n"); fprintf(stderr, "Translation not implemented\n");
nft_fini(&h); nft_fini(&h);
xtables_fini();
exit(!ret); exit(!ret);
} }
...@@ -498,7 +521,9 @@ static int xtables_restore_xlate_main(int family, const char *progname, ...@@ -498,7 +521,9 @@ static int xtables_restore_xlate_main(int family, const char *progname,
.family = family, .family = family,
}; };
const char *file = NULL; const char *file = NULL;
struct nft_xt_restore_parse p = {}; struct nft_xt_restore_parse p = {
.cb = &cb_xlate,
};
time_t now = time(NULL); time_t now = time(NULL);
int c; int c;
...@@ -510,20 +535,20 @@ static int xtables_restore_xlate_main(int family, const char *progname, ...@@ -510,20 +535,20 @@ static int xtables_restore_xlate_main(int family, const char *progname,
while ((c = getopt_long(argc, argv, "hf:V", options, NULL)) != -1) { while ((c = getopt_long(argc, argv, "hf:V", options, NULL)) != -1) {
switch (c) { switch (c) {
case 'h': case 'h':
print_usage(argv[0], IPTABLES_VERSION); print_usage(argv[0], PACKAGE_VERSION);
exit(0); exit(0);
case 'f': case 'f':
file = optarg; file = optarg;
break; break;
case 'V': case 'V':
printf("%s v%s\n", argv[0], IPTABLES_VERSION); printf("%s v%s\n", argv[0], PACKAGE_VERSION);
exit(0); exit(0);
} }
} }
if (file == NULL) { if (file == NULL) {
fprintf(stderr, "ERROR: missing file name\n"); fprintf(stderr, "ERROR: missing file name\n");
print_usage(argv[0], IPTABLES_VERSION); print_usage(argv[0], PACKAGE_VERSION);
exit(0); exit(0);
} }
...@@ -534,11 +559,12 @@ static int xtables_restore_xlate_main(int family, const char *progname, ...@@ -534,11 +559,12 @@ static int xtables_restore_xlate_main(int family, const char *progname,
} }
printf("# Translated by %s v%s on %s", printf("# Translated by %s v%s on %s",
argv[0], IPTABLES_VERSION, ctime(&now)); argv[0], PACKAGE_VERSION, ctime(&now));
xtables_restore_parse(&h, &p, &cb_xlate, argc, argv); xtables_restore_parse(&h, &p);
printf("# Completed on %s", ctime(&now)); printf("# Completed on %s", ctime(&now));
nft_fini(&h); nft_fini(&h);
xtables_fini();
fclose(p.in); fclose(p.in);
exit(0); exit(0);
} }
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#include "config.h"
#include <getopt.h> #include <getopt.h>
#include <string.h> #include <string.h>
#include <netdb.h> #include <netdb.h>
...@@ -43,17 +43,6 @@ ...@@ -43,17 +43,6 @@
#include "nft-shared.h" #include "nft-shared.h"
#include "nft.h" #include "nft.h"
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#define NUMBER_OF_CMD 16
static const char cmdflags[] = { 'I', 'D', 'D', 'R', 'A', 'L', 'F', 'Z',
'N', 'X', 'P', 'E', 'S', 'Z', 'C' };
#define OPT_FRAGMENT 0x00800U #define OPT_FRAGMENT 0x00800U
#define NUMBER_OF_OPT ARRAY_SIZE(optflags) #define NUMBER_OF_OPT ARRAY_SIZE(optflags)
static const char optflags[] static const char optflags[]
...@@ -104,7 +93,7 @@ void xtables_exit_error(enum xtables_exittype status, const char *msg, ...) __at ...@@ -104,7 +93,7 @@ void xtables_exit_error(enum xtables_exittype status, const char *msg, ...) __at
struct xtables_globals xtables_globals = { struct xtables_globals xtables_globals = {
.option_offset = 0, .option_offset = 0,
.program_version = IPTABLES_VERSION, .program_version = PACKAGE_VERSION,
.orig_opts = original_opts, .orig_opts = original_opts,
.exit_err = xtables_exit_error, .exit_err = xtables_exit_error,
.compat_rev = nft_compatible_revision, .compat_rev = nft_compatible_revision,
...@@ -172,7 +161,7 @@ exit_tryhelp(int status) ...@@ -172,7 +161,7 @@ exit_tryhelp(int status)
} }
static void static void
exit_printhelp(const struct xtables_rule_match *matches) printhelp(const struct xtables_rule_match *matches)
{ {
printf("%s v%s\n\n" printf("%s v%s\n\n"
"Usage: %s -[ACD] chain rule-specification [options]\n" "Usage: %s -[ACD] chain rule-specification [options]\n"
...@@ -251,7 +240,6 @@ exit_printhelp(const struct xtables_rule_match *matches) ...@@ -251,7 +240,6 @@ exit_printhelp(const struct xtables_rule_match *matches)
"[!] --version -V print package version.\n"); "[!] --version -V print package version.\n");
print_extension_helps(xtables_targets, matches); print_extension_helps(xtables_targets, matches);
exit(0);
} }
void void
...@@ -319,27 +307,6 @@ opt2char(int option) ...@@ -319,27 +307,6 @@ opt2char(int option)
return *ptr; return *ptr;
} }
static char
cmd2char(int option)
{
const char *ptr;
for (ptr = cmdflags; option > 1; option >>= 1, ptr++);
return *ptr;
}
static void
add_command(unsigned int *cmd, const int newcmd, const int othercmds,
int invert)
{
if (invert)
xtables_error(PARAMETER_PROBLEM, "unexpected ! flag");
if (*cmd & (~othercmds))
xtables_error(PARAMETER_PROBLEM, "Cannot use -%c with -%c\n",
cmd2char(newcmd), cmd2char(*cmd & (~othercmds)));
*cmd |= newcmd;
}
/* /*
* All functions starting with "parse" should succeed, otherwise * All functions starting with "parse" should succeed, otherwise
* the program fails. * the program fails.
...@@ -350,18 +317,6 @@ add_command(unsigned int *cmd, const int newcmd, const int othercmds, ...@@ -350,18 +317,6 @@ add_command(unsigned int *cmd, const int newcmd, const int othercmds,
*/ */
/* Christophe Burki wants `-p 6' to imply `-m tcp'. */ /* Christophe Burki wants `-p 6' to imply `-m tcp'. */
/* Can't be zero. */
static int
parse_rulenumber(const char *rule)
{
unsigned int rulenum;
if (!xtables_strtoui(rule, NULL, &rulenum, 1, INT_MAX))
xtables_error(PARAMETER_PROBLEM,
"Invalid rule number `%s'", rule);
return rulenum;
}
static void static void
set_option(unsigned int *options, unsigned int option, uint8_t *invflg, set_option(unsigned int *options, unsigned int option, uint8_t *invflg,
...@@ -405,11 +360,11 @@ add_entry(const char *chain, ...@@ -405,11 +360,11 @@ add_entry(const char *chain,
cs->fw.ip.dmsk.s_addr = d.mask.v4[j].s_addr; cs->fw.ip.dmsk.s_addr = d.mask.v4[j].s_addr;
if (append) { if (append) {
ret = nft_rule_append(h, chain, table, ret = nft_cmd_rule_append(h, chain, table,
cs, NULL, cs, NULL,
verbose); verbose);
} else { } else {
ret = nft_rule_insert(h, chain, table, ret = nft_cmd_rule_insert(h, chain, table,
cs, rulenum, cs, rulenum,
verbose); verbose);
} }
...@@ -425,11 +380,11 @@ add_entry(const char *chain, ...@@ -425,11 +380,11 @@ add_entry(const char *chain,
memcpy(&cs->fw6.ipv6.dmsk, memcpy(&cs->fw6.ipv6.dmsk,
&d.mask.v6[j], sizeof(struct in6_addr)); &d.mask.v6[j], sizeof(struct in6_addr));
if (append) { if (append) {
ret = nft_rule_append(h, chain, table, ret = nft_cmd_rule_append(h, chain, table,
cs, NULL, cs, NULL,
verbose); verbose);
} else { } else {
ret = nft_rule_insert(h, chain, table, ret = nft_cmd_rule_insert(h, chain, table,
cs, rulenum, cs, rulenum,
verbose); verbose);
} }
...@@ -462,7 +417,7 @@ replace_entry(const char *chain, const char *table, ...@@ -462,7 +417,7 @@ replace_entry(const char *chain, const char *table,
} else } else
return 1; return 1;
return nft_rule_replace(h, chain, table, cs, rulenum, verbose); return nft_cmd_rule_replace(h, chain, table, cs, rulenum, verbose);
} }
static int static int
...@@ -484,7 +439,7 @@ delete_entry(const char *chain, const char *table, ...@@ -484,7 +439,7 @@ delete_entry(const char *chain, const char *table,
for (j = 0; j < d.naddrs; j++) { for (j = 0; j < d.naddrs; j++) {
cs->fw.ip.dst.s_addr = d.addr.v4[j].s_addr; cs->fw.ip.dst.s_addr = d.addr.v4[j].s_addr;
cs->fw.ip.dmsk.s_addr = d.mask.v4[j].s_addr; cs->fw.ip.dmsk.s_addr = d.mask.v4[j].s_addr;
ret = nft_rule_delete(h, chain, ret = nft_cmd_rule_delete(h, chain,
table, cs, verbose); table, cs, verbose);
} }
} else if (family == AF_INET6) { } else if (family == AF_INET6) {
...@@ -497,7 +452,7 @@ delete_entry(const char *chain, const char *table, ...@@ -497,7 +452,7 @@ delete_entry(const char *chain, const char *table,
&d.addr.v6[j], sizeof(struct in6_addr)); &d.addr.v6[j], sizeof(struct in6_addr));
memcpy(&cs->fw6.ipv6.dmsk, memcpy(&cs->fw6.ipv6.dmsk,
&d.mask.v6[j], sizeof(struct in6_addr)); &d.mask.v6[j], sizeof(struct in6_addr));
ret = nft_rule_delete(h, chain, ret = nft_cmd_rule_delete(h, chain,
table, cs, verbose); table, cs, verbose);
} }
} }
...@@ -524,7 +479,7 @@ check_entry(const char *chain, const char *table, ...@@ -524,7 +479,7 @@ check_entry(const char *chain, const char *table,
for (j = 0; j < d.naddrs; j++) { for (j = 0; j < d.naddrs; j++) {
cs->fw.ip.dst.s_addr = d.addr.v4[j].s_addr; cs->fw.ip.dst.s_addr = d.addr.v4[j].s_addr;
cs->fw.ip.dmsk.s_addr = d.mask.v4[j].s_addr; cs->fw.ip.dmsk.s_addr = d.mask.v4[j].s_addr;
ret = nft_rule_check(h, chain, ret = nft_cmd_rule_check(h, chain,
table, cs, verbose); table, cs, verbose);
} }
} else if (family == AF_INET6) { } else if (family == AF_INET6) {
...@@ -537,7 +492,7 @@ check_entry(const char *chain, const char *table, ...@@ -537,7 +492,7 @@ check_entry(const char *chain, const char *table,
&d.addr.v6[j], sizeof(struct in6_addr)); &d.addr.v6[j], sizeof(struct in6_addr));
memcpy(&cs->fw6.ipv6.dmsk, memcpy(&cs->fw6.ipv6.dmsk,
&d.mask.v6[j], sizeof(struct in6_addr)); &d.mask.v6[j], sizeof(struct in6_addr));
ret = nft_rule_check(h, chain, ret = nft_cmd_rule_check(h, chain,
table, cs, verbose); table, cs, verbose);
} }
} }
...@@ -568,7 +523,7 @@ list_entries(struct nft_handle *h, const char *chain, const char *table, ...@@ -568,7 +523,7 @@ list_entries(struct nft_handle *h, const char *chain, const char *table,
if (linenumbers) if (linenumbers)
format |= FMT_LINENUMBERS; format |= FMT_LINENUMBERS;
return nft_rule_list(h, chain, table, rulenum, format); return nft_cmd_rule_list(h, chain, table, rulenum, format);
} }
static int static int
...@@ -578,7 +533,7 @@ list_rules(struct nft_handle *h, const char *chain, const char *table, ...@@ -578,7 +533,7 @@ list_rules(struct nft_handle *h, const char *chain, const char *table,
if (counters) if (counters)
counters = -1; /* iptables -c format */ counters = -1; /* iptables -c format */
return nft_rule_list_save(h, chain, table, rulenum, counters); return nft_cmd_rule_list_save(h, chain, table, rulenum, counters);
} }
void do_parse(struct nft_handle *h, int argc, char *argv[], void do_parse(struct nft_handle *h, int argc, char *argv[],
...@@ -590,6 +545,7 @@ void do_parse(struct nft_handle *h, int argc, char *argv[], ...@@ -590,6 +545,7 @@ void do_parse(struct nft_handle *h, int argc, char *argv[],
bool wait_interval_set = false; bool wait_interval_set = false;
struct timeval wait_interval; struct timeval wait_interval;
struct xtables_target *t; struct xtables_target *t;
bool table_set = false;
int wait = 0; int wait = 0;
memset(cs, 0, sizeof(*cs)); memset(cs, 0, sizeof(*cs));
...@@ -614,10 +570,6 @@ void do_parse(struct nft_handle *h, int argc, char *argv[], ...@@ -614,10 +570,6 @@ void do_parse(struct nft_handle *h, int argc, char *argv[],
demand-load a protocol. */ demand-load a protocol. */
opterr = 0; opterr = 0;
h->ops = nft_family_ops_lookup(h->family);
if (h->ops == NULL)
xtables_error(PARAMETER_PROBLEM, "Unknown family");
opts = xt_params->orig_opts; opts = xt_params->orig_opts;
while ((cs->c = getopt_long(argc, argv, while ((cs->c = getopt_long(argc, argv,
"-:A:C:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:fbvw::W::nt:m:xc:g:46", "-:A:C:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:fbvw::W::nt:m:xc:g:46",
...@@ -771,7 +723,9 @@ void do_parse(struct nft_handle *h, int argc, char *argv[], ...@@ -771,7 +723,9 @@ void do_parse(struct nft_handle *h, int argc, char *argv[],
xtables_find_match(cs->protocol, xtables_find_match(cs->protocol,
XTF_TRY_LOAD, &cs->matches); XTF_TRY_LOAD, &cs->matches);
exit_printhelp(cs->matches); printhelp(cs->matches);
p->command = CMD_NONE;
return;
/* /*
* Option selection * Option selection
...@@ -879,11 +833,16 @@ void do_parse(struct nft_handle *h, int argc, char *argv[], ...@@ -879,11 +833,16 @@ void do_parse(struct nft_handle *h, int argc, char *argv[],
if (cs->invert) if (cs->invert)
xtables_error(PARAMETER_PROBLEM, xtables_error(PARAMETER_PROBLEM,
"unexpected ! flag before --table"); "unexpected ! flag before --table");
if (p->restore && table_set)
xtables_error(PARAMETER_PROBLEM,
"The -t option (seen in line %u) cannot be used in %s.\n",
line, xt_params->program_name);
if (!nft_table_builtin_find(h, optarg)) if (!nft_table_builtin_find(h, optarg))
xtables_error(VERSION_PROBLEM, xtables_error(VERSION_PROBLEM,
"table '%s' does not exist", "table '%s' does not exist",
optarg); optarg);
p->table = optarg; p->table = optarg;
table_set = true;
break; break;
case 'x': case 'x':
...@@ -955,21 +914,22 @@ void do_parse(struct nft_handle *h, int argc, char *argv[], ...@@ -955,21 +914,22 @@ void do_parse(struct nft_handle *h, int argc, char *argv[],
break; break;
case '4': case '4':
if (args->family != AF_INET) if (args->family == AF_INET)
break;
if (p->restore && args->family == AF_INET6)
return;
exit_tryhelp(2); exit_tryhelp(2);
h->ops = nft_family_ops_lookup(args->family); case '6':
if (args->family == AF_INET6)
break; break;
case '6': if (p->restore && args->family == AF_INET)
args->family = AF_INET6; return;
xtables_set_nfproto(AF_INET6);
h->ops = nft_family_ops_lookup(args->family); exit_tryhelp(2);
if (h->ops == NULL)
xtables_error(PARAMETER_PROBLEM,
"Unknown family");
break;
case 1: /* non option */ case 1: /* non option */
if (optarg[0] == '!' && optarg[1] == '\0') { if (optarg[0] == '!' && optarg[1] == '\0') {
...@@ -977,7 +937,7 @@ void do_parse(struct nft_handle *h, int argc, char *argv[], ...@@ -977,7 +937,7 @@ void do_parse(struct nft_handle *h, int argc, char *argv[],
xtables_error(PARAMETER_PROBLEM, xtables_error(PARAMETER_PROBLEM,
"multiple consecutive ! not" "multiple consecutive ! not"
" allowed"); " allowed");
cs->invert = TRUE; cs->invert = true;
optarg[0] = '\0'; optarg[0] = '\0';
continue; continue;
} }
...@@ -990,7 +950,7 @@ void do_parse(struct nft_handle *h, int argc, char *argv[], ...@@ -990,7 +950,7 @@ void do_parse(struct nft_handle *h, int argc, char *argv[],
continue; continue;
break; break;
} }
cs->invert = FALSE; cs->invert = false;
} }
if (strcmp(p->table, "nat") == 0 && if (strcmp(p->table, "nat") == 0 &&
...@@ -1063,11 +1023,6 @@ void do_parse(struct nft_handle *h, int argc, char *argv[], ...@@ -1063,11 +1023,6 @@ void do_parse(struct nft_handle *h, int argc, char *argv[],
opt2char(OPT_VIANAMEIN), opt2char(OPT_VIANAMEIN),
p->chain); p->chain);
} }
if (!p->xlate && !cs->target && strlen(cs->jumpto) > 0 &&
!nft_chain_exists(h, p->table, cs->jumpto))
xtables_error(PARAMETER_PROBLEM,
"Chain '%s' does not exist", cs->jumpto);
} }
} }
...@@ -1098,7 +1053,7 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table, ...@@ -1098,7 +1053,7 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table,
cs.options & OPT_VERBOSE, h); cs.options & OPT_VERBOSE, h);
break; break;
case CMD_DELETE_NUM: case CMD_DELETE_NUM:
ret = nft_rule_delete_num(h, p.chain, p.table, ret = nft_cmd_rule_delete_num(h, p.chain, p.table,
p.rulenum - 1, p.verbose); p.rulenum - 1, p.verbose);
break; break;
case CMD_CHECK: case CMD_CHECK:
...@@ -1117,15 +1072,15 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table, ...@@ -1117,15 +1072,15 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table,
cs.options&OPT_VERBOSE, h, false); cs.options&OPT_VERBOSE, h, false);
break; break;
case CMD_FLUSH: case CMD_FLUSH:
ret = nft_rule_flush(h, p.chain, p.table, ret = nft_cmd_rule_flush(h, p.chain, p.table,
cs.options & OPT_VERBOSE); cs.options & OPT_VERBOSE);
break; break;
case CMD_ZERO: case CMD_ZERO:
ret = nft_chain_zero_counters(h, p.chain, p.table, ret = nft_cmd_chain_zero_counters(h, p.chain, p.table,
cs.options & OPT_VERBOSE); cs.options & OPT_VERBOSE);
break; break;
case CMD_ZERO_NUM: case CMD_ZERO_NUM:
ret = nft_rule_zero_counters(h, p.chain, p.table, ret = nft_cmd_rule_zero_counters(h, p.chain, p.table,
p.rulenum - 1); p.rulenum - 1);
break; break;
case CMD_LIST: case CMD_LIST:
...@@ -1137,11 +1092,11 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table, ...@@ -1137,11 +1092,11 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table,
cs.options & OPT_EXPANDED, cs.options & OPT_EXPANDED,
cs.options & OPT_LINENUMBERS); cs.options & OPT_LINENUMBERS);
if (ret && (p.command & CMD_ZERO)) { if (ret && (p.command & CMD_ZERO)) {
ret = nft_chain_zero_counters(h, p.chain, p.table, ret = nft_cmd_chain_zero_counters(h, p.chain, p.table,
cs.options & OPT_VERBOSE); cs.options & OPT_VERBOSE);
} }
if (ret && (p.command & CMD_ZERO_NUM)) { if (ret && (p.command & CMD_ZERO_NUM)) {
ret = nft_rule_zero_counters(h, p.chain, p.table, ret = nft_cmd_rule_zero_counters(h, p.chain, p.table,
p.rulenum - 1); p.rulenum - 1);
} }
nft_check_xt_legacy(h->family, false); nft_check_xt_legacy(h->family, false);
...@@ -1152,27 +1107,30 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table, ...@@ -1152,27 +1107,30 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table,
ret = list_rules(h, p.chain, p.table, p.rulenum, ret = list_rules(h, p.chain, p.table, p.rulenum,
cs.options & OPT_VERBOSE); cs.options & OPT_VERBOSE);
if (ret && (p.command & CMD_ZERO)) { if (ret && (p.command & CMD_ZERO)) {
ret = nft_chain_zero_counters(h, p.chain, p.table, ret = nft_cmd_chain_zero_counters(h, p.chain, p.table,
cs.options & OPT_VERBOSE); cs.options & OPT_VERBOSE);
} }
if (ret && (p.command & CMD_ZERO_NUM)) { if (ret && (p.command & CMD_ZERO_NUM)) {
ret = nft_rule_zero_counters(h, p.chain, p.table, ret = nft_cmd_rule_zero_counters(h, p.chain, p.table,
p.rulenum - 1); p.rulenum - 1);
} }
nft_check_xt_legacy(h->family, false); nft_check_xt_legacy(h->family, false);
break; break;
case CMD_NEW_CHAIN: case CMD_NEW_CHAIN:
ret = nft_chain_user_add(h, p.chain, p.table); ret = nft_cmd_chain_user_add(h, p.chain, p.table);
break; break;
case CMD_DELETE_CHAIN: case CMD_DELETE_CHAIN:
ret = nft_chain_user_del(h, p.chain, p.table, ret = nft_cmd_chain_user_del(h, p.chain, p.table,
cs.options & OPT_VERBOSE); cs.options & OPT_VERBOSE);
break; break;
case CMD_RENAME_CHAIN: case CMD_RENAME_CHAIN:
ret = nft_chain_user_rename(h, p.chain, p.table, p.newname); ret = nft_cmd_chain_user_rename(h, p.chain, p.table, p.newname);
break; break;
case CMD_SET_POLICY: case CMD_SET_POLICY:
ret = nft_chain_set(h, p.table, p.chain, p.policy, NULL); ret = nft_cmd_chain_set(h, p.table, p.chain, p.policy, NULL);
break;
case CMD_NONE:
/* do_parse ignored the line (eg: -4 with ip6tables-restore) */
break; break;
default: default:
/* We should never reach this... */ /* We should never reach this... */
...@@ -1181,11 +1139,7 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table, ...@@ -1181,11 +1139,7 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table,
*table = p.table; *table = p.table;
xtables_rule_matches_free(&cs.matches); nft_clear_iptables_command_state(&cs);
if (cs.target) {
free(cs.target->t);
cs.target->t = NULL;
}
if (h->family == AF_INET) { if (h->family == AF_INET) {
free(args.s.addr.v4); free(args.s.addr.v4);
......
# Makefile.in generated by automake 1.15 from Makefile.am. # Makefile.in generated by automake 1.16.1 from Makefile.am.
# @configure_input@ # @configure_input@
# Copyright (C) 1994-2014 Free Software Foundation, Inc. # Copyright (C) 1994-2018 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation # This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
...@@ -92,10 +92,10 @@ build_triplet = @build@ ...@@ -92,10 +92,10 @@ build_triplet = @build@
host_triplet = @host@ host_triplet = @host@
subdir = libipq subdir = libipq
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_linker_flags.m4 \ am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4) $(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
...@@ -154,7 +154,8 @@ am__v_at_0 = @ ...@@ -154,7 +154,8 @@ am__v_at_0 = @
am__v_at_1 = am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
am__depfiles_maybe = depfiles am__maybe_remake_depfiles = depfiles
am__depfiles_remade = ./$(DEPDIR)/libipq.Plo
am__mv = mv -f am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
...@@ -241,9 +242,6 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ ...@@ -241,9 +242,6 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@ LD = @LD@
LDFLAGS = @LDFLAGS@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
LIBOBJS = @LIBOBJS@ LIBOBJS = @LIBOBJS@
LIBS = @LIBS@ LIBS = @LIBS@
LIBTOOL = @LIBTOOL@ LIBTOOL = @LIBTOOL@
...@@ -277,8 +275,6 @@ SET_MAKE = @SET_MAKE@ ...@@ -277,8 +275,6 @@ SET_MAKE = @SET_MAKE@
SHELL = @SHELL@ SHELL = @SHELL@
STRIP = @STRIP@ STRIP = @STRIP@
VERSION = @VERSION@ VERSION = @VERSION@
YACC = @YACC@
YFLAGS = @YFLAGS@
abs_builddir = @abs_builddir@ abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@ abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@ abs_top_builddir = @abs_top_builddir@
...@@ -323,7 +319,6 @@ kinclude_CPPFLAGS = @kinclude_CPPFLAGS@ ...@@ -323,7 +319,6 @@ kinclude_CPPFLAGS = @kinclude_CPPFLAGS@
ksourcedir = @ksourcedir@ ksourcedir = @ksourcedir@
libdir = @libdir@ libdir = @libdir@
libexecdir = @libexecdir@ libexecdir = @libexecdir@
libiptc_LDFLAGS2 = @libiptc_LDFLAGS2@
libmnl_CFLAGS = @libmnl_CFLAGS@ libmnl_CFLAGS = @libmnl_CFLAGS@
libmnl_LIBS = @libmnl_LIBS@ libmnl_LIBS = @libmnl_LIBS@
libnetfilter_conntrack_CFLAGS = @libnetfilter_conntrack_CFLAGS@ libnetfilter_conntrack_CFLAGS = @libnetfilter_conntrack_CFLAGS@
...@@ -389,8 +384,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status ...@@ -389,8 +384,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
*config.status*) \ *config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \ *) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
esac; esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
...@@ -448,7 +443,13 @@ mostlyclean-compile: ...@@ -448,7 +443,13 @@ mostlyclean-compile:
distclean-compile: distclean-compile:
-rm -f *.tab.c -rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libipq.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libipq.Plo@am__quote@ # am--include-marker
$(am__depfiles_remade):
@$(MKDIR_P) $(@D)
@echo '# dummy' >$@-t && $(am__mv) $@-t $@
am--depfiles: $(am__depfiles_remade)
.c.o: .c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
...@@ -593,7 +594,10 @@ cscopelist-am: $(am__tagged_files) ...@@ -593,7 +594,10 @@ cscopelist-am: $(am__tagged_files)
distclean-tags: distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES) distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \ list='$(DISTFILES)'; \
...@@ -666,7 +670,7 @@ clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ ...@@ -666,7 +670,7 @@ clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
mostlyclean-am mostlyclean-am
distclean: distclean-am distclean: distclean-am
-rm -rf ./$(DEPDIR) -rm -f ./$(DEPDIR)/libipq.Plo
-rm -f Makefile -rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \ distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags distclean-tags
...@@ -712,7 +716,7 @@ install-ps-am: ...@@ -712,7 +716,7 @@ install-ps-am:
installcheck-am: installcheck-am:
maintainer-clean: maintainer-clean-am maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR) -rm -f ./$(DEPDIR)/libipq.Plo
-rm -f Makefile -rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic maintainer-clean-am: distclean-am maintainer-clean-generic
...@@ -736,9 +740,9 @@ uninstall-man: uninstall-man3 ...@@ -736,9 +740,9 @@ uninstall-man: uninstall-man3
.MAKE: install-am install-strip .MAKE: install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \ clean-generic clean-libLTLIBRARIES clean-libtool cscopelist-am \
ctags-am distclean distclean-compile distclean-generic \ ctags ctags-am distclean distclean-compile distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \ distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \ html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \ install-data-am install-dvi install-dvi-am install-exec \
......
...@@ -30,7 +30,7 @@ The ...@@ -30,7 +30,7 @@ The
.B ipq_set_verdict .B ipq_set_verdict
function issues a verdict on a packet previously obtained with function issues a verdict on a packet previously obtained with
.BR ipq_read , .BR ipq_read ,
specifing the intended disposition of the packet, and optionally specifying the intended disposition of the packet, and optionally
supplying a modified version of the payload data. supplying a modified version of the payload data.
.PP .PP
The The
......
...@@ -5,11 +5,8 @@ AM_CPPFLAGS = ${regular_CPPFLAGS} -I${top_builddir}/include -I${top_srcdir} ...@@ -5,11 +5,8 @@ AM_CPPFLAGS = ${regular_CPPFLAGS} -I${top_builddir}/include -I${top_srcdir}
pkgconfig_DATA = libiptc.pc libip4tc.pc libip6tc.pc pkgconfig_DATA = libiptc.pc libip4tc.pc libip6tc.pc
lib_LTLIBRARIES = libip4tc.la libip6tc.la libiptc.la lib_LTLIBRARIES = libip4tc.la libip6tc.la
libiptc_la_SOURCES =
libiptc_la_LIBADD = libip4tc.la libip6tc.la
libiptc_la_LDFLAGS = -version-info 0:0:0 ${libiptc_LDFLAGS2}
libip4tc_la_SOURCES = libip4tc.c libip4tc_la_SOURCES = libip4tc.c
libip4tc_la_LDFLAGS = -version-info 2:0:0 libip4tc_la_LDFLAGS = -version-info 2:0:0
libip6tc_la_SOURCES = libip6tc.c libip6tc_la_SOURCES = libip6tc.c
libip6tc_la_LDFLAGS = -version-info 2:0:0 ${libiptc_LDFLAGS2} libip6tc_la_LDFLAGS = -version-info 2:0:0
# Makefile.in generated by automake 1.15 from Makefile.am. # Makefile.in generated by automake 1.16.1 from Makefile.am.
# @configure_input@ # @configure_input@
# Copyright (C) 1994-2014 Free Software Foundation, Inc. # Copyright (C) 1994-2018 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation # This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
...@@ -92,10 +92,10 @@ build_triplet = @build@ ...@@ -92,10 +92,10 @@ build_triplet = @build@
host_triplet = @host@ host_triplet = @host@
subdir = libiptc subdir = libiptc
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_linker_flags.m4 \ am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4) $(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
...@@ -148,12 +148,6 @@ libip6tc_la_OBJECTS = $(am_libip6tc_la_OBJECTS) ...@@ -148,12 +148,6 @@ libip6tc_la_OBJECTS = $(am_libip6tc_la_OBJECTS)
libip6tc_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ libip6tc_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(libip6tc_la_LDFLAGS) $(LDFLAGS) -o $@ $(libip6tc_la_LDFLAGS) $(LDFLAGS) -o $@
libiptc_la_DEPENDENCIES = libip4tc.la libip6tc.la
am_libiptc_la_OBJECTS =
libiptc_la_OBJECTS = $(am_libiptc_la_OBJECTS)
libiptc_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(libiptc_la_LDFLAGS) $(LDFLAGS) -o $@
AM_V_P = $(am__v_P_@AM_V@) AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false am__v_P_0 = false
...@@ -168,7 +162,9 @@ am__v_at_0 = @ ...@@ -168,7 +162,9 @@ am__v_at_0 = @
am__v_at_1 = am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
am__depfiles_maybe = depfiles am__maybe_remake_depfiles = depfiles
am__depfiles_remade = ./$(DEPDIR)/libip4tc.Plo \
./$(DEPDIR)/libip6tc.Plo
am__mv = mv -f am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
...@@ -188,10 +184,8 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) ...@@ -188,10 +184,8 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 = am__v_CCLD_1 =
SOURCES = $(libip4tc_la_SOURCES) $(libip6tc_la_SOURCES) \ SOURCES = $(libip4tc_la_SOURCES) $(libip6tc_la_SOURCES)
$(libiptc_la_SOURCES) DIST_SOURCES = $(libip4tc_la_SOURCES) $(libip6tc_la_SOURCES)
DIST_SOURCES = $(libip4tc_la_SOURCES) $(libip6tc_la_SOURCES) \
$(libiptc_la_SOURCES)
am__can_run_installinfo = \ am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \ case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \ n|no|NO) false;; \
...@@ -255,9 +249,6 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ ...@@ -255,9 +249,6 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@ LD = @LD@
LDFLAGS = @LDFLAGS@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
LIBOBJS = @LIBOBJS@ LIBOBJS = @LIBOBJS@
LIBS = @LIBS@ LIBS = @LIBS@
LIBTOOL = @LIBTOOL@ LIBTOOL = @LIBTOOL@
...@@ -291,8 +282,6 @@ SET_MAKE = @SET_MAKE@ ...@@ -291,8 +282,6 @@ SET_MAKE = @SET_MAKE@
SHELL = @SHELL@ SHELL = @SHELL@
STRIP = @STRIP@ STRIP = @STRIP@
VERSION = @VERSION@ VERSION = @VERSION@
YACC = @YACC@
YFLAGS = @YFLAGS@
abs_builddir = @abs_builddir@ abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@ abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@ abs_top_builddir = @abs_top_builddir@
...@@ -337,7 +326,6 @@ kinclude_CPPFLAGS = @kinclude_CPPFLAGS@ ...@@ -337,7 +326,6 @@ kinclude_CPPFLAGS = @kinclude_CPPFLAGS@
ksourcedir = @ksourcedir@ ksourcedir = @ksourcedir@
libdir = @libdir@ libdir = @libdir@
libexecdir = @libexecdir@ libexecdir = @libexecdir@
libiptc_LDFLAGS2 = @libiptc_LDFLAGS2@
libmnl_CFLAGS = @libmnl_CFLAGS@ libmnl_CFLAGS = @libmnl_CFLAGS@
libmnl_LIBS = @libmnl_LIBS@ libmnl_LIBS = @libmnl_LIBS@
libnetfilter_conntrack_CFLAGS = @libnetfilter_conntrack_CFLAGS@ libnetfilter_conntrack_CFLAGS = @libnetfilter_conntrack_CFLAGS@
...@@ -375,14 +363,11 @@ xtlibdir = @xtlibdir@ ...@@ -375,14 +363,11 @@ xtlibdir = @xtlibdir@
AM_CFLAGS = ${regular_CFLAGS} AM_CFLAGS = ${regular_CFLAGS}
AM_CPPFLAGS = ${regular_CPPFLAGS} -I${top_builddir}/include -I${top_srcdir}/include ${kinclude_CPPFLAGS} AM_CPPFLAGS = ${regular_CPPFLAGS} -I${top_builddir}/include -I${top_srcdir}/include ${kinclude_CPPFLAGS}
pkgconfig_DATA = libiptc.pc libip4tc.pc libip6tc.pc pkgconfig_DATA = libiptc.pc libip4tc.pc libip6tc.pc
lib_LTLIBRARIES = libip4tc.la libip6tc.la libiptc.la lib_LTLIBRARIES = libip4tc.la libip6tc.la
libiptc_la_SOURCES =
libiptc_la_LIBADD = libip4tc.la libip6tc.la
libiptc_la_LDFLAGS = -version-info 0:0:0 ${libiptc_LDFLAGS2}
libip4tc_la_SOURCES = libip4tc.c libip4tc_la_SOURCES = libip4tc.c
libip4tc_la_LDFLAGS = -version-info 2:0:0 libip4tc_la_LDFLAGS = -version-info 2:0:0
libip6tc_la_SOURCES = libip6tc.c libip6tc_la_SOURCES = libip6tc.c
libip6tc_la_LDFLAGS = -version-info 2:0:0 ${libiptc_LDFLAGS2} libip6tc_la_LDFLAGS = -version-info 2:0:0
all: all-am all: all-am
.SUFFIXES: .SUFFIXES:
...@@ -404,8 +389,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status ...@@ -404,8 +389,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
*config.status*) \ *config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \ *) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
esac; esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
...@@ -464,17 +449,20 @@ libip4tc.la: $(libip4tc_la_OBJECTS) $(libip4tc_la_DEPENDENCIES) $(EXTRA_libip4tc ...@@ -464,17 +449,20 @@ libip4tc.la: $(libip4tc_la_OBJECTS) $(libip4tc_la_DEPENDENCIES) $(EXTRA_libip4tc
libip6tc.la: $(libip6tc_la_OBJECTS) $(libip6tc_la_DEPENDENCIES) $(EXTRA_libip6tc_la_DEPENDENCIES) libip6tc.la: $(libip6tc_la_OBJECTS) $(libip6tc_la_DEPENDENCIES) $(EXTRA_libip6tc_la_DEPENDENCIES)
$(AM_V_CCLD)$(libip6tc_la_LINK) -rpath $(libdir) $(libip6tc_la_OBJECTS) $(libip6tc_la_LIBADD) $(LIBS) $(AM_V_CCLD)$(libip6tc_la_LINK) -rpath $(libdir) $(libip6tc_la_OBJECTS) $(libip6tc_la_LIBADD) $(LIBS)
libiptc.la: $(libiptc_la_OBJECTS) $(libiptc_la_DEPENDENCIES) $(EXTRA_libiptc_la_DEPENDENCIES)
$(AM_V_CCLD)$(libiptc_la_LINK) -rpath $(libdir) $(libiptc_la_OBJECTS) $(libiptc_la_LIBADD) $(LIBS)
mostlyclean-compile: mostlyclean-compile:
-rm -f *.$(OBJEXT) -rm -f *.$(OBJEXT)
distclean-compile: distclean-compile:
-rm -f *.tab.c -rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libip4tc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libip4tc.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libip6tc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libip6tc.Plo@am__quote@ # am--include-marker
$(am__depfiles_remade):
@$(MKDIR_P) $(@D)
@echo '# dummy' >$@-t && $(am__mv) $@-t $@
am--depfiles: $(am__depfiles_remade)
.c.o: .c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
...@@ -576,7 +564,10 @@ cscopelist-am: $(am__tagged_files) ...@@ -576,7 +564,10 @@ cscopelist-am: $(am__tagged_files)
distclean-tags: distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES) distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \ list='$(DISTFILES)'; \
...@@ -649,7 +640,8 @@ clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ ...@@ -649,7 +640,8 @@ clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
mostlyclean-am mostlyclean-am
distclean: distclean-am distclean: distclean-am
-rm -rf ./$(DEPDIR) -rm -f ./$(DEPDIR)/libip4tc.Plo
-rm -f ./$(DEPDIR)/libip6tc.Plo
-rm -f Makefile -rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \ distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags distclean-tags
...@@ -695,7 +687,8 @@ install-ps-am: ...@@ -695,7 +687,8 @@ install-ps-am:
installcheck-am: installcheck-am:
maintainer-clean: maintainer-clean-am maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR) -rm -f ./$(DEPDIR)/libip4tc.Plo
-rm -f ./$(DEPDIR)/libip6tc.Plo
-rm -f Makefile -rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic maintainer-clean-am: distclean-am maintainer-clean-generic
...@@ -716,9 +709,9 @@ uninstall-am: uninstall-libLTLIBRARIES uninstall-pkgconfigDATA ...@@ -716,9 +709,9 @@ uninstall-am: uninstall-libLTLIBRARIES uninstall-pkgconfigDATA
.MAKE: install-am install-strip .MAKE: install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \ clean-generic clean-libLTLIBRARIES clean-libtool cscopelist-am \
ctags-am distclean distclean-compile distclean-generic \ ctags ctags-am distclean distclean-compile distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \ distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \ html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \ install-data-am install-dvi install-dvi-am install-exec \
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#define inline #define inline
#endif #endif
#if !defined(__GLIBC__) || (__GLIBC__ < 2) #if !defined(__BIONIC__) && (!defined(__GLIBC__) || (__GLIBC__ < 2))
typedef unsigned int socklen_t; typedef unsigned int socklen_t;
#endif #endif
...@@ -308,178 +308,4 @@ check_entry(const STRUCT_ENTRY *e, unsigned int *i, unsigned int *off, ...@@ -308,178 +308,4 @@ check_entry(const STRUCT_ENTRY *e, unsigned int *i, unsigned int *off,
(*i)++; (*i)++;
return 0; return 0;
} }
#ifdef IPTC_DEBUG
/* Do every conceivable sanity check on the handle */
static void
do_check(struct xtc_handle *h, unsigned int line)
{
unsigned int i, n;
unsigned int user_offset; /* Offset of first user chain */
int was_return;
assert(h->changed == 0 || h->changed == 1);
if (strcmp(h->info.name, "filter") == 0) {
assert(h->info.valid_hooks
== (1 << NF_IP_LOCAL_IN
| 1 << NF_IP_FORWARD
| 1 << NF_IP_LOCAL_OUT));
/* Hooks should be first three */
assert(h->info.hook_entry[NF_IP_LOCAL_IN] == 0);
n = get_chain_end(h, 0);
n += get_entry(h, n)->next_offset;
assert(h->info.hook_entry[NF_IP_FORWARD] == n);
n = get_chain_end(h, n);
n += get_entry(h, n)->next_offset;
assert(h->info.hook_entry[NF_IP_LOCAL_OUT] == n);
user_offset = h->info.hook_entry[NF_IP_LOCAL_OUT];
} else if (strcmp(h->info.name, "nat") == 0) {
assert((h->info.valid_hooks
== (1 << NF_IP_PRE_ROUTING
| 1 << NF_IP_POST_ROUTING
| 1 << NF_IP_LOCAL_OUT)) ||
(h->info.valid_hooks
== (1 << NF_IP_PRE_ROUTING
| 1 << NF_IP_LOCAL_IN
| 1 << NF_IP_POST_ROUTING
| 1 << NF_IP_LOCAL_OUT)));
assert(h->info.hook_entry[NF_IP_PRE_ROUTING] == 0);
n = get_chain_end(h, 0);
n += get_entry(h, n)->next_offset;
assert(h->info.hook_entry[NF_IP_POST_ROUTING] == n);
n = get_chain_end(h, n);
n += get_entry(h, n)->next_offset;
assert(h->info.hook_entry[NF_IP_LOCAL_OUT] == n);
user_offset = h->info.hook_entry[NF_IP_LOCAL_OUT];
if (h->info.valid_hooks & (1 << NF_IP_LOCAL_IN)) {
n = get_chain_end(h, n);
n += get_entry(h, n)->next_offset;
assert(h->info.hook_entry[NF_IP_LOCAL_IN] == n);
user_offset = h->info.hook_entry[NF_IP_LOCAL_IN];
}
} else if (strcmp(h->info.name, "mangle") == 0) {
/* This code is getting ugly because linux < 2.4.18-pre6 had
* two mangle hooks, linux >= 2.4.18-pre6 has five mangle hooks
* */
assert((h->info.valid_hooks
== (1 << NF_IP_PRE_ROUTING
| 1 << NF_IP_LOCAL_OUT)) ||
(h->info.valid_hooks
== (1 << NF_IP_PRE_ROUTING
| 1 << NF_IP_LOCAL_IN
| 1 << NF_IP_FORWARD
| 1 << NF_IP_LOCAL_OUT
| 1 << NF_IP_POST_ROUTING)));
/* Hooks should be first five */
assert(h->info.hook_entry[NF_IP_PRE_ROUTING] == 0);
n = get_chain_end(h, 0);
if (h->info.valid_hooks & (1 << NF_IP_LOCAL_IN)) {
n += get_entry(h, n)->next_offset;
assert(h->info.hook_entry[NF_IP_LOCAL_IN] == n);
n = get_chain_end(h, n);
}
if (h->info.valid_hooks & (1 << NF_IP_FORWARD)) {
n += get_entry(h, n)->next_offset;
assert(h->info.hook_entry[NF_IP_FORWARD] == n);
n = get_chain_end(h, n);
}
n += get_entry(h, n)->next_offset;
assert(h->info.hook_entry[NF_IP_LOCAL_OUT] == n);
user_offset = h->info.hook_entry[NF_IP_LOCAL_OUT];
if (h->info.valid_hooks & (1 << NF_IP_POST_ROUTING)) {
n = get_chain_end(h, n);
n += get_entry(h, n)->next_offset;
assert(h->info.hook_entry[NF_IP_POST_ROUTING] == n);
user_offset = h->info.hook_entry[NF_IP_POST_ROUTING];
}
} else if (strcmp(h->info.name, "raw") == 0) {
assert(h->info.valid_hooks
== (1 << NF_IP_PRE_ROUTING
| 1 << NF_IP_LOCAL_OUT));
/* Hooks should be first three */
assert(h->info.hook_entry[NF_IP_PRE_ROUTING] == 0);
n = get_chain_end(h, n);
n += get_entry(h, n)->next_offset;
assert(h->info.hook_entry[NF_IP_LOCAL_OUT] == n);
user_offset = h->info.hook_entry[NF_IP_LOCAL_OUT];
} else {
fprintf(stderr, "Unknown table `%s'\n", h->info.name);
abort();
}
/* User chain == end of last builtin + policy entry */
user_offset = get_chain_end(h, user_offset);
user_offset += get_entry(h, user_offset)->next_offset;
/* Overflows should be end of entry chains, and unconditional
policy nodes. */
for (i = 0; i < NUMHOOKS; i++) {
STRUCT_ENTRY *e;
STRUCT_STANDARD_TARGET *t;
if (!(h->info.valid_hooks & (1 << i)))
continue;
assert(h->info.underflow[i]
== get_chain_end(h, h->info.hook_entry[i]));
e = get_entry(h, get_chain_end(h, h->info.hook_entry[i]));
assert(unconditional(&e->ip));
assert(e->target_offset == sizeof(*e));
t = (STRUCT_STANDARD_TARGET *)GET_TARGET(e);
assert(t->target.u.target_size == ALIGN(sizeof(*t)));
assert(e->next_offset == sizeof(*e) + ALIGN(sizeof(*t)));
assert(strcmp(t->target.u.user.name, STANDARD_TARGET)==0);
assert(t->verdict == -NF_DROP-1 || t->verdict == -NF_ACCEPT-1);
/* Hooks and underflows must be valid entries */
entry2index(h, get_entry(h, h->info.hook_entry[i]));
entry2index(h, get_entry(h, h->info.underflow[i]));
}
assert(h->info.size
>= h->info.num_entries * (sizeof(STRUCT_ENTRY)
+sizeof(STRUCT_STANDARD_TARGET)));
assert(h->entries.size
>= (h->new_number
* (sizeof(STRUCT_ENTRY)
+ sizeof(STRUCT_STANDARD_TARGET))));
assert(strcmp(h->info.name, h->entries.name) == 0);
i = 0; n = 0;
was_return = 0;
/* Check all the entries. */
ENTRY_ITERATE(h->entries.entrytable, h->entries.size,
check_entry, &i, &n, user_offset, &was_return, h);
assert(i == h->new_number);
assert(n == h->entries.size);
/* Final entry must be error node */
assert(strcmp(GET_TARGET(index2entry(h, h->new_number-1))
->u.user.name,
ERROR_TARGET) == 0);
}
#endif /*IPTC_DEBUG*/
#endif #endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment