ip6tables-restore.c revision 5065afa11159f4d8cfad672ac01f2958379fad4b
12f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó/* Code to restore the iptables state, from file by ip6tables-save. 22f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó * Author: Andras Kis-Szabo <kisza@sch.bme.hu> 32f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó * 42f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó * based on iptables-restore 52f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó * Authors: 62f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó * Harald Welte <laforge@gnumonks.org> 72f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó * Rusty Russell <rusty@linuxcare.com.au> 80c4188f446e7c0ed07076c69d1d7f336a92efc8bAndrás Kis-Szabó * This code is distributed under the terms of GNU GPL v2 92f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó * 105065afa11159f4d8cfad672ac01f2958379fad4bMartin Josefsson * $Id: ip6tables-restore.c,v 1.15 2004/01/31 19:28:13 gandalf Exp $ 112f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó */ 122f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 132f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó#include <getopt.h> 142f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó#include <sys/errno.h> 152f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó#include <string.h> 162f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó#include <stdio.h> 172f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó#include <stdlib.h> 182f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó#include "ip6tables.h" 192f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó#include "libiptc/libip6tc.h" 202f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 212f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó#ifdef DEBUG 222f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó#define DEBUGP(x, args...) fprintf(stderr, x, ## args) 232f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó#else 242f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó#define DEBUGP(x, args...) 252f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó#endif 262f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 272f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabóstatic int binary = 0, counters = 0, verbose = 0, noflush = 0; 282f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 292f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó/* Keeping track of external matches and targets. */ 302f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabóstatic struct option options[] = { 312f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó { "binary", 0, 0, 'b' }, 322f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó { "counters", 0, 0, 'c' }, 33ec7897120d739896eff4f9b2c5a1de15364382b7Martin Josefsson { "verbose", 0, 0, 'v' }, 342f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó { "help", 0, 0, 'h' }, 352f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó { "noflush", 0, 0, 'n'}, 3658918654563975e7bf3a6ec26af92a3bc222c229Harald Welte { "modprobe", 1, 0, 'M'}, 372f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó { 0 } 382f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó}; 392f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 402f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabóstatic void print_usage(const char *name, const char *version) __attribute__((noreturn)); 412f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 422f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabóstatic void print_usage(const char *name, const char *version) 432f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó{ 442f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó fprintf(stderr, "Usage: %s [-b] [-c] [-v] [-h]\n" 452f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó " [ --binary ]\n" 462f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó " [ --counters ]\n" 472f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó " [ --verbose ]\n" 482f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó " [ --help ]\n" 4958918654563975e7bf3a6ec26af92a3bc222c229Harald Welte " [ --noflush ]\n" 5058918654563975e7bf3a6ec26af92a3bc222c229Harald Welte " [ --modprobe=<command>]\n", name); 512f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 522f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó exit(1); 532f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó} 542f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 5558918654563975e7bf3a6ec26af92a3bc222c229Harald Welteip6tc_handle_t create_handle(const char *tablename, const char* modprobe) 562f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó{ 572f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó ip6tc_handle_t handle; 582f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 592f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó handle = ip6tc_init(tablename); 6058918654563975e7bf3a6ec26af92a3bc222c229Harald Welte 6158918654563975e7bf3a6ec26af92a3bc222c229Harald Welte if (!handle) { 6297fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó /* try to insmod the module if iptc_init failed */ 6397fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó ip6tables_insmod("ip6_tables", modprobe); 6497fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó handle = ip6tc_init(tablename); 6558918654563975e7bf3a6ec26af92a3bc222c229Harald Welte } 6658918654563975e7bf3a6ec26af92a3bc222c229Harald Welte 672f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó if (!handle) { 682f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó exit_error(PARAMETER_PROBLEM, "%s: unable to initialize" 692f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó "table '%s'\n", program_name, tablename); 702f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó exit(1); 712f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó } 722f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó return handle; 732f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó} 742f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 752f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabóint parse_counters(char *string, struct ip6t_counters *ctr) 762f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó{ 772f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó return (sscanf(string, "[%llu:%llu]", &ctr->pcnt, &ctr->bcnt) == 2); 782f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó} 792f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 80885c6eb5ec8a186c77a4710808374dd612e82b20Harald Welte/* global new argv and argc */ 81885c6eb5ec8a186c77a4710808374dd612e82b20Harald Weltestatic char *newargv[255]; 82885c6eb5ec8a186c77a4710808374dd612e82b20Harald Weltestatic int newargc; 83885c6eb5ec8a186c77a4710808374dd612e82b20Harald Welte 84885c6eb5ec8a186c77a4710808374dd612e82b20Harald Welte/* function adding one argument to newargv, updating newargc 8597fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó * returns true if argument added, false otherwise */ 86885c6eb5ec8a186c77a4710808374dd612e82b20Harald Weltestatic int add_argv(char *what) { 8797fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó DEBUGP("add_argv: %s\n", what); 8897fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó if (what && ((newargc + 1) < sizeof(newargv)/sizeof(char *))) { 8997fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó newargv[newargc] = strdup(what); 9097fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó newargc++; 9197fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó return 1; 9297fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó } else 9397fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó return 0; 94885c6eb5ec8a186c77a4710808374dd612e82b20Harald Welte} 95885c6eb5ec8a186c77a4710808374dd612e82b20Harald Welte 96885c6eb5ec8a186c77a4710808374dd612e82b20Harald Weltestatic void free_argv(void) { 9797fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó int i; 98885c6eb5ec8a186c77a4710808374dd612e82b20Harald Welte 9997fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó for (i = 0; i < newargc; i++) 10097fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó free(newargv[i]); 101885c6eb5ec8a186c77a4710808374dd612e82b20Harald Welte} 102885c6eb5ec8a186c77a4710808374dd612e82b20Harald Welte 1032f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabóint main(int argc, char *argv[]) 1042f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó{ 105841e4aed2349046eb2c0b1375139c06569a93bd0Martin Josefsson ip6tc_handle_t handle = NULL; 1062f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó char buffer[10240]; 1072f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó int c; 1082f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó char curtable[IP6T_TABLE_MAXNAMELEN + 1]; 1092f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó FILE *in; 11058918654563975e7bf3a6ec26af92a3bc222c229Harald Welte const char *modprobe = 0; 111a8658ca43fba82f7761f774f4daeb29b3e335053Harald Welte int in_table = 0; 1122f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 1132f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó program_name = "ip6tables-restore"; 11480fe35d6339b53a12ddaec41885613e4e37ed031Harald Welte program_version = IPTABLES_VERSION; 115a8658ca43fba82f7761f774f4daeb29b3e335053Harald Welte line = 0; 1162f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 1173efb6ead2e51fe1eca55bcb2b06afb4dc4b8cb7cHarald Welte#ifdef NO_SHARED_LIBS 1183efb6ead2e51fe1eca55bcb2b06afb4dc4b8cb7cHarald Welte init_extensions(); 1193efb6ead2e51fe1eca55bcb2b06afb4dc4b8cb7cHarald Welte#endif 1203efb6ead2e51fe1eca55bcb2b06afb4dc4b8cb7cHarald Welte 12158918654563975e7bf3a6ec26af92a3bc222c229Harald Welte while ((c = getopt_long(argc, argv, "bcvhnM:", options, NULL)) != -1) { 1222f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó switch (c) { 1232f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó case 'b': 1242f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó binary = 1; 1252f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó break; 1262f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó case 'c': 1272f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó counters = 1; 1282f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó break; 12997fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó case 'v': 13097fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó verbose = 1; 13197fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó break; 1322f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó case 'h': 1332f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó print_usage("ip6tables-restore", 13480fe35d6339b53a12ddaec41885613e4e37ed031Harald Welte IPTABLES_VERSION); 1352f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó break; 1362f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó case 'n': 1372f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó noflush = 1; 1382f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó break; 13958918654563975e7bf3a6ec26af92a3bc222c229Harald Welte case 'M': 14058918654563975e7bf3a6ec26af92a3bc222c229Harald Welte modprobe = optarg; 14158918654563975e7bf3a6ec26af92a3bc222c229Harald Welte break; 1422f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó } 1432f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó } 1442f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 1452f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó if (optind == argc - 1) { 1462f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó in = fopen(argv[optind], "r"); 1472f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó if (!in) { 1482f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó fprintf(stderr, "Can't open %s: %s", argv[optind], 1492f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó strerror(errno)); 1502f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó exit(1); 1512f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó } 1522f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó } 1532f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó else if (optind < argc) { 1542f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó fprintf(stderr, "Unknown arguments found on commandline"); 1552f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó exit(1); 1562f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó } 1572f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó else in = stdin; 15897fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó 1592f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó /* Grab standard input. */ 1602f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó while (fgets(buffer, sizeof(buffer), in)) { 1612f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó int ret; 1622f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 1632f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó line++; 1645065afa11159f4d8cfad672ac01f2958379fad4bMartin Josefsson if (buffer[0] == '\n') 1655065afa11159f4d8cfad672ac01f2958379fad4bMartin Josefsson continue; 1662f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó else if (buffer[0] == '#') { 1672f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó if (verbose) fputs(buffer, stdout); 1682f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó continue; 169a8658ca43fba82f7761f774f4daeb29b3e335053Harald Welte } else if ((strcmp(buffer, "COMMIT\n") == 0) && (in_table)) { 1702f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó DEBUGP("Calling commit\n"); 1712f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó ret = ip6tc_commit(&handle); 172a8658ca43fba82f7761f774f4daeb29b3e335053Harald Welte in_table = 0; 173a8658ca43fba82f7761f774f4daeb29b3e335053Harald Welte } else if ((buffer[0] == '*') && (!in_table)) { 1742f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó /* New table */ 1752f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó char *table; 1762f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 1772f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó table = strtok(buffer+1, " \t\n"); 1782f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó DEBUGP("line %u, table '%s'\n", line, table); 1792f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó if (!table) { 1802f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó exit_error(PARAMETER_PROBLEM, 1812f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó "%s: line %u table name invalid\n", 1822f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó program_name, line); 1832f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó exit(1); 1842f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó } 1852f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó strncpy(curtable, table, IP6T_TABLE_MAXNAMELEN); 186073df8feb0a8c4023ce40138e519ac9b341b1ca2Karsten Desler curtable[IP6T_TABLE_MAXNAMELEN] = '\0'; 1872f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 188841e4aed2349046eb2c0b1375139c06569a93bd0Martin Josefsson if (handle) 189841e4aed2349046eb2c0b1375139c06569a93bd0Martin Josefsson ip6tc_free(&handle); 190841e4aed2349046eb2c0b1375139c06569a93bd0Martin Josefsson 19158918654563975e7bf3a6ec26af92a3bc222c229Harald Welte handle = create_handle(table, modprobe); 1922f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó if (noflush == 0) { 1932f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó DEBUGP("Cleaning all chains of table '%s'\n", 1942f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó table); 1952f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó for_each_chain(flush_entries, verbose, 1, 1962f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó &handle); 1972f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 1982f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó DEBUGP("Deleting all user-defined chains " 1992f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó "of table '%s'\n", table); 2002f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó for_each_chain(delete_chain, verbose, 0, 2012f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó &handle) ; 2022f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó } 2032f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 2042f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó ret = 1; 205a8658ca43fba82f7761f774f4daeb29b3e335053Harald Welte in_table = 1; 2062f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 207a8658ca43fba82f7761f774f4daeb29b3e335053Harald Welte } else if ((buffer[0] == ':') && (in_table)) { 2082f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó /* New chain. */ 2092f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó char *policy, *chain; 2102f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 2112f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó chain = strtok(buffer+1, " \t\n"); 2122f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó DEBUGP("line %u, chain '%s'\n", line, chain); 2132f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó if (!chain) { 2142f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó exit_error(PARAMETER_PROBLEM, 2152f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó "%s: line %u chain name invalid\n", 2162f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó program_name, line); 2172f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó exit(1); 2182f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó } 2192f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 220885c6eb5ec8a186c77a4710808374dd612e82b20Harald Welte if (!ip6tc_builtin(chain, handle)) { 22197fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó DEBUGP("Creating new chain '%s'\n", chain); 222885c6eb5ec8a186c77a4710808374dd612e82b20Harald Welte if (!ip6tc_create_chain(chain, &handle)) 22397fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó exit_error(PARAMETER_PROBLEM, 22497fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó "error creating chain " 22597fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó "'%s':%s\n", chain, 22697fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó strerror(errno)); 227885c6eb5ec8a186c77a4710808374dd612e82b20Harald Welte } 2282f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 2292f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó policy = strtok(NULL, " \t\n"); 2302f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó DEBUGP("line %u, policy '%s'\n", line, policy); 2312f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó if (!policy) { 2322f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó exit_error(PARAMETER_PROBLEM, 2332f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó "%s: line %u policy invalid\n", 2342f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó program_name, line); 2352f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó exit(1); 2362f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó } 2372f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 2382f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó if (strcmp(policy, "-") != 0) { 2392f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó struct ip6t_counters count; 2402f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 2412f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó if (counters) { 2422f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó char *ctrs; 2432f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó ctrs = strtok(NULL, " \t\n"); 2442f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 2452f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó parse_counters(ctrs, &count); 2462f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 2472f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó } else { 2482f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó memset(&count, 0, 2492f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó sizeof(struct ip6t_counters)); 2502f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó } 2512f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 2522f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó DEBUGP("Setting policy of chain %s to %s\n", 2532f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó chain, policy); 2542f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 2552f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó if (!ip6tc_set_policy(chain, policy, &count, 2562f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó &handle)) 2572f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó exit_error(OTHER_PROBLEM, 2582f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó "Can't set policy `%s'" 2592f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó " on `%s' line %u: %s\n", 2602f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó chain, policy, line, 2612f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó ip6tc_strerror(errno)); 2622f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó } 2632f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 2642f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó ret = 1; 2652f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 266a8658ca43fba82f7761f774f4daeb29b3e335053Harald Welte } else if (in_table) { 267885c6eb5ec8a186c77a4710808374dd612e82b20Harald Welte int a; 2682f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó char *ptr = buffer; 2692f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó char *pcnt = NULL; 2702f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó char *bcnt = NULL; 27197fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó char *parsestart; 272885c6eb5ec8a186c77a4710808374dd612e82b20Harald Welte 27397fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó /* the parser */ 27497fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó char *param_start, *curchar; 27597fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó int quote_open; 276885c6eb5ec8a186c77a4710808374dd612e82b20Harald Welte 27797fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó /* reset the newargv */ 27897fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó newargc = 0; 2792f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 2802f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó if (buffer[0] == '[') { 28197fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó /* we have counters in our input */ 2822f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó ptr = strchr(buffer, ']'); 2832f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó if (!ptr) 2842f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó exit_error(PARAMETER_PROBLEM, 2852f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó "Bad line %u: need ]\n", 2862f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó line); 2872f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 288885c6eb5ec8a186c77a4710808374dd612e82b20Harald Welte pcnt = strtok(buffer+1, ":"); 28997fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó if (!pcnt) 29097fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó exit_error(PARAMETER_PROBLEM, 29197fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó "Bad line %u: need :\n", 29297fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó line); 2932f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 294885c6eb5ec8a186c77a4710808374dd612e82b20Harald Welte bcnt = strtok(NULL, "]"); 29597fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó if (!bcnt) 29697fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó exit_error(PARAMETER_PROBLEM, 29797fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó "Bad line %u: need ]\n", 29897fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó line); 299885c6eb5ec8a186c77a4710808374dd612e82b20Harald Welte 30097fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó /* start command parsing after counter */ 30197fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó parsestart = ptr + 1; 30297fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó } else { 30397fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó /* start command parsing at start of line */ 30497fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó parsestart = buffer; 30597fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó } 30697fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó 30797fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó add_argv(argv[0]); 30897fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó add_argv("-t"); 30997fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó add_argv((char *) &curtable); 31097fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó 3112f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó if (counters && pcnt && bcnt) { 31297fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó add_argv("--set-counters"); 31397fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó add_argv((char *) pcnt); 31497fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó add_argv((char *) bcnt); 3152f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó } 316bb41f8879f5743d683ff3e66ef440b7b7bb5f6d2Harald Welte 31797fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó /* After fighting with strtok enough, here's now 31897fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó * a 'real' parser. According to Rusty I'm now no 31997fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó * longer a real hacker, but I can live with that */ 32097fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó 32197fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó quote_open = 0; 32297fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó param_start = parsestart; 32397fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó 32497fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó for (curchar = parsestart; *curchar; curchar++) { 32597fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó if (*curchar == '"') { 32629cdbd047cdc757aec98db308114c1c250ae0d22Michael Rash /* quote_open cannot be true if there 32729cdbd047cdc757aec98db308114c1c250ae0d22Michael Rash * was no previous character. Thus, 32829cdbd047cdc757aec98db308114c1c250ae0d22Michael Rash * curchar-1 has to be within bounds */ 32929cdbd047cdc757aec98db308114c1c250ae0d22Michael Rash if (quote_open && 33029cdbd047cdc757aec98db308114c1c250ae0d22Michael Rash *(curchar-1) != '\\') { 33197fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó quote_open = 0; 33297fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó *curchar = ' '; 33397fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó } else { 33497fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó quote_open = 1; 33597fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó param_start++; 33697fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó } 33797fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó } 33897fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó if (*curchar == ' ' 33997fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó || *curchar == '\t' 34097fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó || * curchar == '\n') { 34197fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó char param_buffer[1024]; 34297fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó int param_len = curchar-param_start; 34397fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó 34497fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó if (quote_open) 34597fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó continue; 34697fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó 34797fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó if (!param_len) { 34897fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó /* two spaces? */ 34997fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó param_start++; 35097fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó continue; 35197fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó } 35297fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó 35397fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó /* end of one parameter */ 35497fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó strncpy(param_buffer, param_start, 35597fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó param_len); 35697fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó *(param_buffer+param_len) = '\0'; 35797fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó 35897fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó /* check if table name specified */ 35948a6f900fa25a4dd2d9b39cff4bf1ab83356d967Harald Welte if (!strncmp(param_buffer, "-t", 3) 36048a6f900fa25a4dd2d9b39cff4bf1ab83356d967Harald Welte || !strncmp(param_buffer, "--table", 8)) { 361bb41f8879f5743d683ff3e66ef440b7b7bb5f6d2Harald Welte exit_error(PARAMETER_PROBLEM, 362bb41f8879f5743d683ff3e66ef440b7b7bb5f6d2Harald Welte "Line %u seems to have a " 363bb41f8879f5743d683ff3e66ef440b7b7bb5f6d2Harald Welte "-t table option.\n", line); 364bb41f8879f5743d683ff3e66ef440b7b7bb5f6d2Harald Welte exit(1); 365bb41f8879f5743d683ff3e66ef440b7b7bb5f6d2Harald Welte } 366bb41f8879f5743d683ff3e66ef440b7b7bb5f6d2Harald Welte 36797fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó add_argv(param_buffer); 36897fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó param_start += param_len + 1; 36997fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó } else { 37097fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó /* regular character, skip */ 37197fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó } 37297fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó } 373885c6eb5ec8a186c77a4710808374dd612e82b20Harald Welte 374885c6eb5ec8a186c77a4710808374dd612e82b20Harald Welte DEBUGP("calling do_command6(%u, argv, &%s, handle):\n", 37597fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó newargc, curtable); 376885c6eb5ec8a186c77a4710808374dd612e82b20Harald Welte 37797fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó for (a = 0; a < newargc; a++) 3782f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó DEBUGP("argv[%u]: %s\n", a, newargv[a]); 3792f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 380885c6eb5ec8a186c77a4710808374dd612e82b20Harald Welte ret = do_command6(newargc, newargv, 38197fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó &newargv[2], &handle); 382885c6eb5ec8a186c77a4710808374dd612e82b20Harald Welte 38397fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó free_argv(); 3842f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó } 3852f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó if (!ret) { 3862f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó fprintf(stderr, "%s: line %u failed\n", 3872f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó program_name, line); 3882f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó exit(1); 3892f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó } 3902f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó } 3912f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 3922f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó return 0; 3932f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó} 394