1/* 2 * ebtables-restore.c, October 2005 3 * 4 * Author: Bart De Schuymer 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation; either version 2 of the 9 * License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, but 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 */ 20#include <stdio.h> 21#include <stdlib.h> 22#include <string.h> 23#include <errno.h> 24#include <unistd.h> 25#include "include/ebtables_u.h" 26 27static struct ebt_u_replace replace[3]; 28void ebt_early_init_once(); 29 30#define OPT_KERNELDATA 0x800 /* Also defined in ebtables.c */ 31 32static void copy_table_names() 33{ 34 strcpy(replace[0].name, "filter"); 35 strcpy(replace[1].name, "nat"); 36 strcpy(replace[2].name, "broute"); 37} 38 39#define ebtrest_print_error(format, args...) do {fprintf(stderr, "ebtables-restore: "\ 40 "line %d: "format".\n", line, ##args); exit(-1);} while (0) 41int main(int argc_, char *argv_[]) 42{ 43 char *argv[EBTD_ARGC_MAX], cmdline[EBTD_CMDLINE_MAXLN]; 44 int i, offset, quotemode = 0, argc, table_nr = -1, line = 0, whitespace; 45 char ebtables_str[] = "ebtables"; 46 47 if (argc_ != 1) 48 ebtrest_print_error("options are not supported"); 49 ebt_silent = 0; 50 copy_table_names(); 51 ebt_early_init_once(); 52 argv[0] = ebtables_str; 53 54 while (fgets(cmdline, EBTD_CMDLINE_MAXLN, stdin)) { 55 line++; 56 if (*cmdline == '#' || *cmdline == '\n') 57 continue; 58 *strchr(cmdline, '\n') = '\0'; 59 if (*cmdline == '*') { 60 if (table_nr != -1) { 61 ebt_deliver_table(&replace[table_nr]); 62 ebt_deliver_counters(&replace[table_nr]); 63 } 64 for (i = 0; i < 3; i++) 65 if (!strcmp(replace[i].name, cmdline+1)) 66 break; 67 if (i == 3) 68 ebtrest_print_error("table '%s' was not recognized", cmdline+1); 69 table_nr = i; 70 replace[table_nr].command = 11; 71 ebt_get_kernel_table(&replace[table_nr], 1); 72 replace[table_nr].command = 0; 73 replace[table_nr].flags = OPT_KERNELDATA; /* Prevent do_command from initialising replace */ 74 continue; 75 } else if (table_nr == -1) 76 ebtrest_print_error("no table specified"); 77 if (*cmdline == ':') { 78 int policy, chain_nr; 79 char *ch; 80 81 if (!(ch = strchr(cmdline, ' '))) 82 ebtrest_print_error("no policy specified"); 83 *ch = '\0'; 84 for (i = 0; i < NUM_STANDARD_TARGETS; i++) 85 if (!strcmp(ch+1, ebt_standard_targets[i])) { 86 policy = -i -1; 87 if (policy == EBT_CONTINUE) 88 i = NUM_STANDARD_TARGETS; 89 break; 90 } 91 if (i == NUM_STANDARD_TARGETS) 92 ebtrest_print_error("invalid policy specified"); 93 /* No need to check chain name for consistency, since 94 * we're supposed to be reading an automatically generated 95 * file. */ 96 if ((chain_nr = ebt_get_chainnr(&replace[table_nr], cmdline+1)) == -1) 97 ebt_new_chain(&replace[table_nr], cmdline+1, policy); 98 else 99 replace[table_nr].chains[chain_nr]->policy = policy; 100 continue; 101 } 102 argv[1] = cmdline; 103 offset = whitespace = 0; 104 argc = 2; 105 while (cmdline[offset] != '\0') { 106 if (cmdline[offset] == '\"') { 107 whitespace = 0; 108 quotemode ^= 1; 109 if (quotemode) 110 argv[argc++] = &cmdline[offset+1]; 111 else if (cmdline[offset+1] != ' ' && cmdline[offset+1] != '\0') 112 ebtrest_print_error("syntax error at \""); 113 cmdline[offset] = '\0'; 114 } else if (!quotemode && cmdline[offset] == ' ') { 115 whitespace = 1; 116 cmdline[offset] = '\0'; 117 } else if (whitespace == 1) { 118 argv[argc++] = &cmdline[offset]; 119 whitespace = 0; 120 } 121 offset++; 122 } 123 if (quotemode) 124 ebtrest_print_error("wrong use of '\"'"); 125 optind = 0; /* Setting optind = 1 causes serious annoyances */ 126 do_command(argc, argv, EXEC_STYLE_DAEMON, &replace[table_nr]); 127 ebt_reinit_extensions(); 128 } 129 130 if (table_nr != -1) { 131 ebt_deliver_table(&replace[table_nr]); 132 ebt_deliver_counters(&replace[table_nr]); 133 } 134 return 0; 135} 136