Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 1 | /* |
| 2 | * $Id: ebtables.c,v 1.03 2002/01/19 |
| 3 | * |
| 4 | * Copyright (C) 2001-2002 Bart De Schuymer |
| 5 | * |
| 6 | * This code is stongly inspired on the iptables code which is |
| 7 | * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling |
| 8 | * |
| 9 | * This program is free software; you can redistribute it and/or |
| 10 | * modify it under the terms of the GNU General Public License as |
| 11 | * published by the Free Software Foundation; either version 2 of the |
| 12 | * License, or (at your option) any later version. |
| 13 | * |
| 14 | * This program is distributed in the hope that it will be useful, but |
| 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 17 | * General Public License for more details. |
| 18 | * |
| 19 | * You should have received a copy of the GNU General Public License |
| 20 | * along with this program; if not, write to the Free Software |
| 21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| 22 | */ |
| 23 | |
| 24 | #ifndef EBTABLES_U_H |
| 25 | #define EBTABLES_U_H |
Bart De Schuymer | 9cfd654 | 2002-08-13 16:08:08 +0000 | [diff] [blame] | 26 | #include <netinet/in.h> |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 27 | #include <linux/netfilter_bridge/ebtables.h> |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 28 | |
| 29 | struct ebt_u_entries |
| 30 | { |
Bart De Schuymer | 0976590 | 2002-06-23 08:15:51 +0000 | [diff] [blame] | 31 | int policy; |
Bart De Schuymer | 376ccfb | 2002-07-23 20:52:18 +0000 | [diff] [blame] | 32 | unsigned int nentries; |
Bart De Schuymer | 9895a8e | 2003-01-11 10:14:24 +0000 | [diff] [blame] | 33 | /* counter offset for this chain */ |
Bart De Schuymer | 0976590 | 2002-06-23 08:15:51 +0000 | [diff] [blame] | 34 | unsigned int counter_offset; |
Bart De Schuymer | 9895a8e | 2003-01-11 10:14:24 +0000 | [diff] [blame] | 35 | /* used for udc */ |
Bart De Schuymer | 0976590 | 2002-06-23 08:15:51 +0000 | [diff] [blame] | 36 | unsigned int hook_mask; |
| 37 | char name[EBT_CHAIN_MAXNAMELEN]; |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 38 | struct ebt_u_entry *entries; |
| 39 | }; |
| 40 | |
Bart De Schuymer | 0976590 | 2002-06-23 08:15:51 +0000 | [diff] [blame] | 41 | struct ebt_u_chain_list |
| 42 | { |
| 43 | struct ebt_u_entries *udc; |
| 44 | struct ebt_u_chain_list *next; |
Bart De Schuymer | 9895a8e | 2003-01-11 10:14:24 +0000 | [diff] [blame] | 45 | /* this is only used internally, in communication.c */ |
Bart De Schuymer | 0976590 | 2002-06-23 08:15:51 +0000 | [diff] [blame] | 46 | char *kernel_start; |
| 47 | }; |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 48 | |
| 49 | struct ebt_u_replace |
| 50 | { |
| 51 | char name[EBT_TABLE_MAXNAMELEN]; |
| 52 | unsigned int valid_hooks; |
Bart De Schuymer | 9895a8e | 2003-01-11 10:14:24 +0000 | [diff] [blame] | 53 | /* nr of rules in the table */ |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 54 | unsigned int nentries; |
| 55 | struct ebt_u_entries *hook_entry[NF_BR_NUMHOOKS]; |
Bart De Schuymer | 9895a8e | 2003-01-11 10:14:24 +0000 | [diff] [blame] | 56 | /* user defined chains (udc) list */ |
Bart De Schuymer | 0976590 | 2002-06-23 08:15:51 +0000 | [diff] [blame] | 57 | struct ebt_u_chain_list *udc; |
Bart De Schuymer | 9895a8e | 2003-01-11 10:14:24 +0000 | [diff] [blame] | 58 | /* nr of counters userspace expects back */ |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 59 | unsigned int num_counters; |
Bart De Schuymer | 9895a8e | 2003-01-11 10:14:24 +0000 | [diff] [blame] | 60 | /* where the kernel will put the old counters */ |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 61 | struct ebt_counter *counters; |
Bart De Schuymer | 9895a8e | 2003-01-11 10:14:24 +0000 | [diff] [blame] | 62 | /* |
| 63 | * can be used e.g. to know if a standard option |
| 64 | * has been specified twice |
| 65 | */ |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 66 | unsigned int flags; |
Bart De Schuymer | 9895a8e | 2003-01-11 10:14:24 +0000 | [diff] [blame] | 67 | /* we stick the specified command (e.g. -A) in here */ |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 68 | char command; |
Bart De Schuymer | 9895a8e | 2003-01-11 10:14:24 +0000 | [diff] [blame] | 69 | /* |
| 70 | * here we stick the hook to do our thing on (can be -1 if unspecified) |
| 71 | */ |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 72 | int selected_hook; |
Bart De Schuymer | 9895a8e | 2003-01-11 10:14:24 +0000 | [diff] [blame] | 73 | /* used for the atomic option */ |
Bart De Schuymer | 8330e89 | 2002-07-14 19:06:47 +0000 | [diff] [blame] | 74 | char *filename; |
Bart De Schuymer | 9895a8e | 2003-01-11 10:14:24 +0000 | [diff] [blame] | 75 | /* tells what happened to the old rules */ |
Bart De Schuymer | ed05343 | 2002-07-21 19:35:39 +0000 | [diff] [blame] | 76 | unsigned short *counterchanges; |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 77 | }; |
| 78 | |
| 79 | struct ebt_u_table |
| 80 | { |
| 81 | char name[EBT_TABLE_MAXNAMELEN]; |
Bart De Schuymer | f57f50f | 2002-08-29 16:52:36 +0000 | [diff] [blame] | 82 | void (*check)(struct ebt_u_replace *repl); |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 83 | void (*help)(char **); |
| 84 | struct ebt_u_table *next; |
| 85 | }; |
| 86 | |
| 87 | struct ebt_u_match_list |
| 88 | { |
| 89 | struct ebt_u_match_list *next; |
| 90 | struct ebt_entry_match *m; |
| 91 | }; |
| 92 | |
| 93 | struct ebt_u_watcher_list |
| 94 | { |
| 95 | struct ebt_u_watcher_list *next; |
| 96 | struct ebt_entry_watcher *w; |
| 97 | }; |
| 98 | |
| 99 | struct ebt_u_entry |
| 100 | { |
Bart De Schuymer | 376ccfb | 2002-07-23 20:52:18 +0000 | [diff] [blame] | 101 | unsigned int bitmask; |
| 102 | unsigned int invflags; |
Bart De Schuymer | 9cfd654 | 2002-08-13 16:08:08 +0000 | [diff] [blame] | 103 | uint16_t ethproto; |
Bart De Schuymer | 376ccfb | 2002-07-23 20:52:18 +0000 | [diff] [blame] | 104 | char in[IFNAMSIZ]; |
| 105 | char logical_in[IFNAMSIZ]; |
| 106 | char out[IFNAMSIZ]; |
| 107 | char logical_out[IFNAMSIZ]; |
Bart De Schuymer | e3cceb7 | 2002-07-26 12:47:33 +0000 | [diff] [blame] | 108 | unsigned char sourcemac[ETH_ALEN]; |
| 109 | unsigned char sourcemsk[ETH_ALEN]; |
| 110 | unsigned char destmac[ETH_ALEN]; |
| 111 | unsigned char destmsk[ETH_ALEN]; |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 112 | struct ebt_u_match_list *m_list; |
| 113 | struct ebt_u_watcher_list *w_list; |
| 114 | struct ebt_entry_target *t; |
| 115 | struct ebt_u_entry *next; |
| 116 | }; |
| 117 | |
| 118 | struct ebt_u_match |
| 119 | { |
| 120 | char name[EBT_FUNCTION_MAXNAMELEN]; |
Bart De Schuymer | 9895a8e | 2003-01-11 10:14:24 +0000 | [diff] [blame] | 121 | /* size of the real match data */ |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 122 | unsigned int size; |
| 123 | void (*help)(void); |
| 124 | void (*init)(struct ebt_entry_match *m); |
| 125 | int (*parse)(int c, char **argv, int argc, |
| 126 | const struct ebt_u_entry *entry, unsigned int *flags, |
| 127 | struct ebt_entry_match **match); |
| 128 | void (*final_check)(const struct ebt_u_entry *entry, |
| 129 | const struct ebt_entry_match *match, |
Bart De Schuymer | 76712df | 2002-08-25 21:54:06 +0000 | [diff] [blame] | 130 | const char *name, unsigned int hookmask, unsigned int time); |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 131 | void (*print)(const struct ebt_u_entry *entry, |
| 132 | const struct ebt_entry_match *match); |
| 133 | int (*compare)(const struct ebt_entry_match *m1, |
| 134 | const struct ebt_entry_match *m2); |
| 135 | const struct option *extra_ops; |
Bart De Schuymer | 9895a8e | 2003-01-11 10:14:24 +0000 | [diff] [blame] | 136 | /* |
| 137 | * can be used e.g. to check for multiple occurance of the same option |
| 138 | */ |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 139 | unsigned int flags; |
| 140 | unsigned int option_offset; |
| 141 | struct ebt_entry_match *m; |
Bart De Schuymer | 9895a8e | 2003-01-11 10:14:24 +0000 | [diff] [blame] | 142 | /* |
| 143 | * if used == 1 we no longer have to add it to |
| 144 | * the match chain of the new entry |
| 145 | */ |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 146 | unsigned int used; |
| 147 | struct ebt_u_match *next; |
| 148 | }; |
| 149 | |
| 150 | struct ebt_u_watcher |
| 151 | { |
| 152 | char name[EBT_FUNCTION_MAXNAMELEN]; |
| 153 | unsigned int size; |
| 154 | void (*help)(void); |
| 155 | void (*init)(struct ebt_entry_watcher *w); |
| 156 | int (*parse)(int c, char **argv, int argc, |
| 157 | const struct ebt_u_entry *entry, unsigned int *flags, |
| 158 | struct ebt_entry_watcher **watcher); |
| 159 | void (*final_check)(const struct ebt_u_entry *entry, |
| 160 | const struct ebt_entry_watcher *watch, const char *name, |
Bart De Schuymer | 76712df | 2002-08-25 21:54:06 +0000 | [diff] [blame] | 161 | unsigned int hookmask, unsigned int time); |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 162 | void (*print)(const struct ebt_u_entry *entry, |
| 163 | const struct ebt_entry_watcher *watcher); |
| 164 | int (*compare)(const struct ebt_entry_watcher *w1, |
| 165 | const struct ebt_entry_watcher *w2); |
| 166 | const struct option *extra_ops; |
| 167 | unsigned int flags; |
| 168 | unsigned int option_offset; |
| 169 | struct ebt_entry_watcher *w; |
| 170 | unsigned int used; |
| 171 | struct ebt_u_watcher *next; |
| 172 | }; |
| 173 | |
| 174 | struct ebt_u_target |
| 175 | { |
| 176 | char name[EBT_FUNCTION_MAXNAMELEN]; |
| 177 | unsigned int size; |
| 178 | void (*help)(void); |
| 179 | void (*init)(struct ebt_entry_target *t); |
| 180 | int (*parse)(int c, char **argv, int argc, |
| 181 | const struct ebt_u_entry *entry, unsigned int *flags, |
| 182 | struct ebt_entry_target **target); |
| 183 | void (*final_check)(const struct ebt_u_entry *entry, |
| 184 | const struct ebt_entry_target *target, const char *name, |
Bart De Schuymer | 76712df | 2002-08-25 21:54:06 +0000 | [diff] [blame] | 185 | unsigned int hookmask, unsigned int time); |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 186 | void (*print)(const struct ebt_u_entry *entry, |
| 187 | const struct ebt_entry_target *target); |
| 188 | int (*compare)(const struct ebt_entry_target *t1, |
| 189 | const struct ebt_entry_target *t2); |
| 190 | const struct option *extra_ops; |
| 191 | unsigned int option_offset; |
| 192 | unsigned int flags; |
| 193 | struct ebt_entry_target *t; |
| 194 | unsigned int used; |
| 195 | struct ebt_u_target *next; |
| 196 | }; |
| 197 | |
| 198 | void register_table(struct ebt_u_table *); |
| 199 | void register_match(struct ebt_u_match *); |
| 200 | void register_watcher(struct ebt_u_watcher *); |
| 201 | void register_target(struct ebt_u_target *t); |
Bart De Schuymer | 9ce6ee9 | 2002-06-14 21:56:35 +0000 | [diff] [blame] | 202 | int get_table(struct ebt_u_replace *repl); |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 203 | struct ebt_u_target *find_target(const char *name); |
| 204 | struct ebt_u_match *find_match(const char *name); |
| 205 | struct ebt_u_watcher *find_watcher(const char *name); |
Bart De Schuymer | 8330e89 | 2002-07-14 19:06:47 +0000 | [diff] [blame] | 206 | struct ebt_u_table *find_table(char *name); |
Bart De Schuymer | ed05343 | 2002-07-21 19:35:39 +0000 | [diff] [blame] | 207 | void deliver_counters(struct ebt_u_replace *repl); |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 208 | void deliver_table(struct ebt_u_replace *repl); |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 209 | void check_option(unsigned int *flags, unsigned int mask); |
| 210 | int check_inverse(const char option[]); |
Bart De Schuymer | d458648 | 2002-08-11 16:15:55 +0000 | [diff] [blame] | 211 | void __print_bug(char *file, int line, char *format, ...); |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 212 | #define print_bug(format, args...) \ |
Bart De Schuymer | d458648 | 2002-08-11 16:15:55 +0000 | [diff] [blame] | 213 | __print_bug(__FILE__, __LINE__, format, ##args) |
Bart De Schuymer | 7f72d26 | 2002-11-20 19:39:02 +0000 | [diff] [blame] | 214 | #define print_error(format,args...) {printf(format".\n",##args); exit(-1);} |
Bart De Schuymer | 1f7f002 | 2003-01-19 10:36:29 +0000 | [diff] [blame] | 215 | #define print_memory() {printf("Ebtables: " __FILE__ \ |
| 216 | " %s %d :Out of memory.\n", __FUNCTION__, __LINE__); exit(-1);} |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 217 | |
Bart De Schuymer | 9895a8e | 2003-01-11 10:14:24 +0000 | [diff] [blame] | 218 | /* used for keeping the rule counters right during rule adds or deletes */ |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 219 | #define CNT_NORM 0 |
| 220 | #define CNT_DEL 1 |
| 221 | #define CNT_ADD 2 |
| 222 | #define CNT_END 3 |
| 223 | #define CNT_ZERO 4 |
| 224 | |
Bart De Schuymer | 9cfd654 | 2002-08-13 16:08:08 +0000 | [diff] [blame] | 225 | extern char *standard_targets[NUM_STANDARD_TARGETS]; |
Bart De Schuymer | 9895a8e | 2003-01-11 10:14:24 +0000 | [diff] [blame] | 226 | /* |
| 227 | * Transforms a target string into the right integer, |
| 228 | * returns 0 on success. |
| 229 | */ |
Bart De Schuymer | 9cfd654 | 2002-08-13 16:08:08 +0000 | [diff] [blame] | 230 | #define FILL_TARGET(_str, _pos) ({ \ |
| 231 | int _i, _ret = 0; \ |
| 232 | for (_i = 0; _i < NUM_STANDARD_TARGETS; _i++) \ |
| 233 | if (!strcmp(_str, standard_targets[_i])) {\ |
| 234 | _pos = -_i - 1; \ |
| 235 | break; \ |
| 236 | } \ |
| 237 | if (_i == NUM_STANDARD_TARGETS) \ |
| 238 | _ret = 1; \ |
| 239 | _ret; \ |
| 240 | }) |
| 241 | |
Bart De Schuymer | 9895a8e | 2003-01-11 10:14:24 +0000 | [diff] [blame] | 242 | /* Transforms the target value to an index into standard_targets[] */ |
Bart De Schuymer | 9cfd654 | 2002-08-13 16:08:08 +0000 | [diff] [blame] | 243 | #define TARGET_INDEX(_value) (-_value - 1) |
Bart De Schuymer | 9895a8e | 2003-01-11 10:14:24 +0000 | [diff] [blame] | 244 | /* Returns a target string corresponding to the value */ |
Bart De Schuymer | 9cfd654 | 2002-08-13 16:08:08 +0000 | [diff] [blame] | 245 | #define TARGET_NAME(_value) (standard_targets[TARGET_INDEX(_value)]) |
Bart De Schuymer | 9895a8e | 2003-01-11 10:14:24 +0000 | [diff] [blame] | 246 | /* True if the hook mask denotes that the rule is in a base chain */ |
Bart De Schuymer | 76712df | 2002-08-25 21:54:06 +0000 | [diff] [blame] | 247 | #define BASE_CHAIN (hookmask & (1 << NF_BR_NUMHOOKS)) |
Bart De Schuymer | 9895a8e | 2003-01-11 10:14:24 +0000 | [diff] [blame] | 248 | /* Clear the bit in the hook_mask that tells if the rule is on a base chain */ |
Bart De Schuymer | 76712df | 2002-08-25 21:54:06 +0000 | [diff] [blame] | 249 | #define CLEAR_BASE_CHAIN_BIT (hookmask &= ~(1 << NF_BR_NUMHOOKS)) |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 250 | #endif /* EBTABLES_U_H */ |