Bart De Schuymer | 005f638 | 2005-09-28 19:27:55 +0000 | [diff] [blame] | 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 | |
| 27 | static struct ebt_u_replace replace[3]; |
| 28 | void ebt_early_init_once(); |
| 29 | |
| 30 | #define OPT_KERNELDATA 0x800 /* Also defined in ebtables.c */ |
| 31 | |
| 32 | static 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 | |
Bart De Schuymer | 1f7a7df | 2005-09-29 20:37:23 +0000 | [diff] [blame] | 39 | #define ebtrest_print_error(format, args...) {fprintf(stderr, "ebtables-restore: "\ |
| 40 | "line %d: "format".\n", line, ##args); exit(-1);} |
Bart De Schuymer | 005f638 | 2005-09-28 19:27:55 +0000 | [diff] [blame] | 41 | int 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 | |
Bart De Schuymer | 1f7a7df | 2005-09-29 20:37:23 +0000 | [diff] [blame] | 47 | if (argc_ != 1) |
| 48 | ebtrest_print_error("options are not supported"); |
Bart De Schuymer | 005f638 | 2005-09-28 19:27:55 +0000 | [diff] [blame] | 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; |
Bart De Schuymer | 1f7a7df | 2005-09-29 20:37:23 +0000 | [diff] [blame] | 67 | if (i == 3) |
| 68 | ebtrest_print_error("table '%s' was not recognized", cmdline+1); |
Bart De Schuymer | 005f638 | 2005-09-28 19:27:55 +0000 | [diff] [blame] | 69 | table_nr = i; |
| 70 | replace[table_nr].command = 11; |
| 71 | ebt_get_kernel_table(replace, 1); |
| 72 | replace[table_nr].command = 0; |
| 73 | replace[table_nr].flags = OPT_KERNELDATA; /* Prevent do_command from initialising replace */ |
| 74 | continue; |
Bart De Schuymer | 1f7a7df | 2005-09-29 20:37:23 +0000 | [diff] [blame] | 75 | } else if (table_nr == -1) |
| 76 | ebtrest_print_error("no table specified\n"); |
Bart De Schuymer | 005f638 | 2005-09-28 19:27:55 +0000 | [diff] [blame] | 77 | if (*cmdline == ':') { |
| 78 | int policy; |
| 79 | char *ch; |
| 80 | |
Bart De Schuymer | 1f7a7df | 2005-09-29 20:37:23 +0000 | [diff] [blame] | 81 | if (!(ch = strchr(cmdline, ' '))) |
| 82 | ebtrest_print_error("no policy specified"); |
Bart De Schuymer | 005f638 | 2005-09-28 19:27:55 +0000 | [diff] [blame] | 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 | } |
Bart De Schuymer | 1f7a7df | 2005-09-29 20:37:23 +0000 | [diff] [blame] | 91 | if (i == NUM_STANDARD_TARGETS) |
| 92 | ebtrest_print_error("invalid policy specified"); |
Bart De Schuymer | 005f638 | 2005-09-28 19:27:55 +0000 | [diff] [blame] | 93 | if (ebt_get_chainnr(&replace[table_nr], cmdline+1) == -1) { |
| 94 | ebt_new_chain(&replace[table_nr], cmdline+1, policy); |
| 95 | } |
| 96 | continue; |
| 97 | } |
| 98 | argv[1] = cmdline; |
| 99 | offset = whitespace = 0; |
| 100 | argc = 2; |
| 101 | while (cmdline[offset] != '\0') { |
| 102 | if (cmdline[offset] == '\"') { |
| 103 | whitespace = 0; |
| 104 | quotemode ^= 1; |
| 105 | if (quotemode) |
| 106 | argv[argc++] = &cmdline[offset+1]; |
| 107 | cmdline[offset] = '\0'; |
| 108 | } else if (!quotemode && cmdline[offset] == ' ') { |
| 109 | whitespace = 1; |
| 110 | cmdline[offset] = '\0'; |
| 111 | } else if (whitespace == 1) { |
| 112 | argv[argc++] = &cmdline[offset]; |
| 113 | whitespace = 0; |
| 114 | } |
| 115 | offset++; |
| 116 | } |
Bart De Schuymer | 1f7a7df | 2005-09-29 20:37:23 +0000 | [diff] [blame] | 117 | if (quotemode) |
| 118 | ebtrest_print_error("wrong use of '\"'"); |
Bart De Schuymer | 005f638 | 2005-09-28 19:27:55 +0000 | [diff] [blame] | 119 | optind = 0; /* Setting optind = 1 causes serious annoyances */ |
| 120 | do_command(argc, argv, EXEC_STYLE_DAEMON, &replace[table_nr]); |
| 121 | ebt_reinit_extensions(); |
| 122 | } |
| 123 | |
| 124 | if (table_nr != -1) { |
| 125 | ebt_deliver_table(&replace[table_nr]); |
| 126 | ebt_deliver_counters(&replace[table_nr]); |
| 127 | } |
| 128 | return 0; |
| 129 | } |