diff options
Diffstat (limited to 'iptables-xml.c')
-rw-r--r-- | iptables-xml.c | 147 |
1 files changed, 83 insertions, 64 deletions
diff --git a/iptables-xml.c b/iptables-xml.c index ce3049c..daf4208 100644 --- a/iptables-xml.c +++ b/iptables-xml.c @@ -16,6 +16,8 @@ #include <stdarg.h> #include "iptables.h" #include "libiptc/libiptc.h" +#include "iptables-multi.h" +#include <xtables.h> #ifdef DEBUG #define DEBUGP(x, args...) fprintf(stderr, x, ## args) @@ -23,26 +25,18 @@ #define DEBUGP(x, args...) #endif -/* no need to link with iptables.o */ -const char *program_name; -const char *program_version; - #ifndef IPTABLES_MULTI int line = 0; -void exit_error(enum exittype status, char *msg, ...) -{ - va_list args; - - va_start(args, msg); - fprintf(stderr, "%s v%s: ", program_name, program_version); - vfprintf(stderr, msg, args); - va_end(args); - fprintf(stderr, "\n"); - /* On error paths, make sure that we don't leak memory */ - exit(status); -} #endif +struct xtables_globals iptables_xml_globals = { + .option_offset = 0, + .program_version = IPTABLES_VERSION, + .program_name = "iptables-xml", +}; +#define prog_name iptables_xml_globals.program_name +#define prog_vers iptables_xml_globals.program_version + static void print_usage(const char *name, const char *version) __attribute__ ((noreturn)); @@ -51,10 +45,10 @@ static int verbose = 0; static int combine = 0; /* Keeping track of external matches and targets. */ static struct option options[] = { - {"verbose", 0, 0, 'v'}, - {"combine", 0, 0, 'c'}, - {"help", 0, 0, 'h'}, - {0} + {"verbose", 0, NULL, 'v'}, + {"combine", 0, NULL, 'c'}, + {"help", 0, NULL, 'h'}, + { .name = NULL } }; static void @@ -70,41 +64,44 @@ print_usage(const char *name, const char *version) static int parse_counters(char *string, struct ipt_counters *ctr) { - if (string != NULL) + u_int64_t *pcnt, *bcnt; + + if (string != NULL) { + pcnt = &ctr->pcnt; + bcnt = &ctr->bcnt; return (sscanf (string, "[%llu:%llu]", - (unsigned long long *) &ctr->pcnt, - (unsigned long long *) &ctr->bcnt) == 2); - else + (unsigned long long *)pcnt, + (unsigned long long *)bcnt) == 2); + } else return (0 == 2); } /* global new argv and argc */ static char *newargv[255]; -static int newargc = 0; +static unsigned int newargc = 0; static char *oldargv[255]; -static int oldargc = 0; +static unsigned int oldargc = 0; /* arg meta data, were they quoted, frinstance */ static int newargvattr[255]; #define IPT_CHAIN_MAXNAMELEN IPT_TABLE_MAXNAMELEN -char closeActionTag[IPT_TABLE_MAXNAMELEN + 1]; -char closeRuleTag[IPT_TABLE_MAXNAMELEN + 1]; -char curTable[IPT_TABLE_MAXNAMELEN + 1]; -char curChain[IPT_CHAIN_MAXNAMELEN + 1]; +static char closeActionTag[IPT_TABLE_MAXNAMELEN + 1]; +static char closeRuleTag[IPT_TABLE_MAXNAMELEN + 1]; +static char curTable[IPT_TABLE_MAXNAMELEN + 1]; +static char curChain[IPT_CHAIN_MAXNAMELEN + 1]; -typedef struct chain -{ +struct chain { char *chain; char *policy; struct ipt_counters count; int created; -} chain; +}; #define maxChains 10240 /* max chains per table */ -static chain chains[maxChains]; +static struct chain chains[maxChains]; static int nextChain = 0; /* funCtion adding one argument to newargv, updating newargc @@ -113,7 +110,7 @@ static int add_argv(char *what, int quoted) { DEBUGP("add_argv: %d %s\n", newargc, what); - if (what && ((newargc + 1) < sizeof(newargv) / sizeof(char *))) { + if (what && newargc + 1 < ARRAY_SIZE(newargv)) { newargv[newargc] = strdup(what); newargvattr[newargc] = quoted; newargc++; @@ -125,7 +122,7 @@ add_argv(char *what, int quoted) static void free_argv(void) { - int i; + unsigned int i; for (i = 0; i < newargc; i++) { free(newargv[i]); @@ -145,7 +142,7 @@ free_argv(void) static void save_argv(void) { - int i; + unsigned int i; for (i = 0; i < oldargc; i++) free(oldargv[i]); @@ -224,7 +221,7 @@ xmlAttrI(char *name, long long int num) } static void -closeChain() +closeChain(void) { if (curChain[0] == 0) return; @@ -299,9 +296,9 @@ static void saveChain(char *chain, char *policy, struct ipt_counters *ctr) { if (nextChain >= maxChains) { - exit_error(PARAMETER_PROBLEM, + xtables_error(PARAMETER_PROBLEM, "%s: line %u chain name invalid\n", - program_name, line); + prog_name, line); exit(1); }; chains[nextChain].chain = strdup(chain); @@ -312,7 +309,7 @@ saveChain(char *chain, char *policy, struct ipt_counters *ctr) } static void -finishChains() +finishChains(void) { int c; @@ -327,7 +324,7 @@ finishChains() } static void -closeTable() +closeTable(void) { closeChain(); finishChains(); @@ -359,6 +356,18 @@ isTarget(char *arg) || strcmp((arg), "--goto") == 0)); } +// is it a terminating target like -j ACCEPT, etc +// (or I guess -j SNAT in nat table, but we don't check for that yet +static int +isTerminatingTarget(char *arg) +{ + return ((arg) + && (strcmp((arg), "ACCEPT") == 0 + || strcmp((arg), "DROP") == 0 + || strcmp((arg), "QUEUE") == 0 + || strcmp((arg), "RETURN") == 0)); +} + // part=-1 means do conditions, part=1 means do rules, part=0 means do both static void do_rule_part(char *leveltag1, char *leveltag2, int part, int argc, @@ -515,12 +524,10 @@ do_rule_part(char *leveltag1, char *leveltag2, int part, int argc, if (level1) printf("%s", leveli1); CLOSE_LEVEL(1); - - return; } static int -compareRules() +compareRules(void) { /* compare arguments up to -j or -g for match. NOTE: We don't want to combine actions if there were no criteria @@ -529,14 +536,26 @@ compareRules() is the case when processing the ACTUAL output of actual iptables-save rather than a file merely in a compatable format */ - int old = 0; - int new = 0; + unsigned int old = 0; + unsigned int new = 0; int compare = 0; while (new < newargc && old < oldargc) { if (isTarget(oldargv[old]) && isTarget(newargv[new])) { - compare = 1; + /* if oldarg was a terminating action then it makes no sense + * to combine further actions into the same xml */ + if (((strcmp((oldargv[old]), "-j") == 0 + || strcmp((oldargv[old]), "--jump") == 0) + && old+1 < oldargc + && isTerminatingTarget(oldargv[old+1]) ) + || strcmp((oldargv[old]), "-g") == 0 + || strcmp((oldargv[old]), "--goto") == 0 ) { + /* Previous rule had terminating action */ + compare = 0; + } else { + compare = 1; + } break; } // break when old!=new @@ -603,7 +622,6 @@ do_rule(char *pcnt, char *bcnt, int argc, char *argv[], int argvattr[]) do_rule_part(NULL, NULL, 1, argc, argv, argvattr); } - #ifdef IPTABLES_MULTI int iptables_xml_main(int argc, char *argv[]) @@ -616,10 +634,9 @@ main(int argc, char *argv[]) int c; FILE *in; - program_name = "iptables-xml"; - program_version = IPTABLES_VERSION; line = 0; + xtables_set_params(&iptables_xml_globals); while ((c = getopt_long(argc, argv, "cvh", options, NULL)) != -1) { switch (c) { case 'c': @@ -680,9 +697,9 @@ main(int argc, char *argv[]) table = strtok(buffer + 1, " \t\n"); DEBUGP("line %u, table '%s'\n", line, table); if (!table) { - exit_error(PARAMETER_PROBLEM, + xtables_error(PARAMETER_PROBLEM, "%s: line %u table name invalid\n", - program_name, line); + prog_name, line); exit(1); } openTable(table); @@ -697,9 +714,9 @@ main(int argc, char *argv[]) chain = strtok(buffer + 1, " \t\n"); DEBUGP("line %u, chain '%s'\n", line, chain); if (!chain) { - exit_error(PARAMETER_PROBLEM, + xtables_error(PARAMETER_PROBLEM, "%s: line %u chain name invalid\n", - program_name, line); + prog_name, line); exit(1); } @@ -708,9 +725,9 @@ main(int argc, char *argv[]) policy = strtok(NULL, " \t\n"); DEBUGP("line %u, policy '%s'\n", line, policy); if (!policy) { - exit_error(PARAMETER_PROBLEM, + xtables_error(PARAMETER_PROBLEM, "%s: line %u policy invalid\n", - program_name, line); + prog_name, line); exit(1); } @@ -720,7 +737,7 @@ main(int argc, char *argv[]) ret = 1; } else if (curTable[0]) { - int a; + unsigned int a; char *ptr = buffer; char *pcnt = NULL; char *bcnt = NULL; @@ -738,19 +755,19 @@ main(int argc, char *argv[]) /* we have counters in our input */ ptr = strchr(buffer, ']'); if (!ptr) - exit_error(PARAMETER_PROBLEM, + xtables_error(PARAMETER_PROBLEM, "Bad line %u: need ]\n", line); pcnt = strtok(buffer + 1, ":"); if (!pcnt) - exit_error(PARAMETER_PROBLEM, + xtables_error(PARAMETER_PROBLEM, "Bad line %u: need :\n", line); bcnt = strtok(NULL, "]"); if (!bcnt) - exit_error(PARAMETER_PROBLEM, + xtables_error(PARAMETER_PROBLEM, "Bad line %u: need ]\n", line); @@ -810,7 +827,7 @@ main(int argc, char *argv[]) if (!strncmp(param_buffer, "-t", 3) || !strncmp(param_buffer, "--table", 8)) { - exit_error(PARAMETER_PROBLEM, + xtables_error(PARAMETER_PROBLEM, "Line %u seems to have a " "-t table option.\n", line); @@ -843,16 +860,18 @@ main(int argc, char *argv[]) } if (!ret) { fprintf(stderr, "%s: line %u failed\n", - program_name, line); + prog_name, line); exit(1); } } if (curTable[0]) { fprintf(stderr, "%s: COMMIT expected at line %u\n", - program_name, line + 1); + prog_name, line + 1); exit(1); } + if (in != NULL) + fclose(in); printf("</iptables-rules>\n"); free_argv(); |