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 | 0976590 | 2002-06-23 08:15:51 +0000 | [diff] [blame] | 33 | // counter offset for this chain |
| 34 | unsigned int counter_offset; |
| 35 | // used for udc |
| 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 | efed5bc | 2002-07-25 12:29:11 +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; |
| 53 | // nr of rules in the table |
| 54 | unsigned int nentries; |
| 55 | struct ebt_u_entries *hook_entry[NF_BR_NUMHOOKS]; |
Bart De Schuymer | 0976590 | 2002-06-23 08:15:51 +0000 | [diff] [blame] | 56 | // user defined chains (udc) list |
| 57 | struct ebt_u_chain_list *udc; |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 58 | // nr of counters userspace expects back |
| 59 | unsigned int num_counters; |
| 60 | // where the kernel will put the old counters |
| 61 | struct ebt_counter *counters; |
| 62 | // can be used e.g. to know if a standard option |
| 63 | // has been specified twice |
| 64 | unsigned int flags; |
| 65 | // we stick the specified command (e.g. -A) in here |
| 66 | char command; |
| 67 | // here we stick the hook to do our thing on (can be -1 if unspecified) |
| 68 | int selected_hook; |
Bart De Schuymer | 8330e89 | 2002-07-14 19:06:47 +0000 | [diff] [blame] | 69 | // used for the atomic option |
| 70 | char *filename; |
Bart De Schuymer | ed05343 | 2002-07-21 19:35:39 +0000 | [diff] [blame] | 71 | // tells what happened to the old rules |
| 72 | unsigned short *counterchanges; |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 73 | }; |
| 74 | |
| 75 | struct ebt_u_table |
| 76 | { |
| 77 | char name[EBT_TABLE_MAXNAMELEN]; |
Bart De Schuymer | f57f50f | 2002-08-29 16:52:36 +0000 | [diff] [blame] | 78 | void (*check)(struct ebt_u_replace *repl); |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 79 | void (*help)(char **); |
| 80 | struct ebt_u_table *next; |
| 81 | }; |
| 82 | |
| 83 | struct ebt_u_match_list |
| 84 | { |
| 85 | struct ebt_u_match_list *next; |
| 86 | struct ebt_entry_match *m; |
| 87 | }; |
| 88 | |
| 89 | struct ebt_u_watcher_list |
| 90 | { |
| 91 | struct ebt_u_watcher_list *next; |
| 92 | struct ebt_entry_watcher *w; |
| 93 | }; |
| 94 | |
| 95 | struct ebt_u_entry |
| 96 | { |
Bart De Schuymer | 376ccfb | 2002-07-23 20:52:18 +0000 | [diff] [blame] | 97 | unsigned int bitmask; |
| 98 | unsigned int invflags; |
Bart De Schuymer | 9cfd654 | 2002-08-13 16:08:08 +0000 | [diff] [blame] | 99 | uint16_t ethproto; |
Bart De Schuymer | 376ccfb | 2002-07-23 20:52:18 +0000 | [diff] [blame] | 100 | char in[IFNAMSIZ]; |
| 101 | char logical_in[IFNAMSIZ]; |
| 102 | char out[IFNAMSIZ]; |
| 103 | char logical_out[IFNAMSIZ]; |
Bart De Schuymer | e3cceb7 | 2002-07-26 12:47:33 +0000 | [diff] [blame] | 104 | unsigned char sourcemac[ETH_ALEN]; |
| 105 | unsigned char sourcemsk[ETH_ALEN]; |
| 106 | unsigned char destmac[ETH_ALEN]; |
| 107 | unsigned char destmsk[ETH_ALEN]; |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 108 | struct ebt_u_match_list *m_list; |
| 109 | struct ebt_u_watcher_list *w_list; |
| 110 | struct ebt_entry_target *t; |
| 111 | struct ebt_u_entry *next; |
| 112 | }; |
| 113 | |
| 114 | struct ebt_u_match |
| 115 | { |
| 116 | char name[EBT_FUNCTION_MAXNAMELEN]; |
Bart De Schuymer | 76712df | 2002-08-25 21:54:06 +0000 | [diff] [blame] | 117 | // size of the real match data |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 118 | unsigned int size; |
| 119 | void (*help)(void); |
| 120 | void (*init)(struct ebt_entry_match *m); |
| 121 | int (*parse)(int c, char **argv, int argc, |
| 122 | const struct ebt_u_entry *entry, unsigned int *flags, |
| 123 | struct ebt_entry_match **match); |
| 124 | void (*final_check)(const struct ebt_u_entry *entry, |
| 125 | const struct ebt_entry_match *match, |
Bart De Schuymer | 76712df | 2002-08-25 21:54:06 +0000 | [diff] [blame] | 126 | const char *name, unsigned int hookmask, unsigned int time); |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 127 | void (*print)(const struct ebt_u_entry *entry, |
| 128 | const struct ebt_entry_match *match); |
| 129 | int (*compare)(const struct ebt_entry_match *m1, |
| 130 | const struct ebt_entry_match *m2); |
| 131 | const struct option *extra_ops; |
| 132 | // can be used e.g. to check for multiple occurance of the same option |
| 133 | unsigned int flags; |
| 134 | unsigned int option_offset; |
| 135 | struct ebt_entry_match *m; |
| 136 | // if used == 1 we no longer have to add it to |
| 137 | // the match chain of the new entry |
| 138 | unsigned int used; |
| 139 | struct ebt_u_match *next; |
| 140 | }; |
| 141 | |
| 142 | struct ebt_u_watcher |
| 143 | { |
| 144 | char name[EBT_FUNCTION_MAXNAMELEN]; |
| 145 | unsigned int size; |
| 146 | void (*help)(void); |
| 147 | void (*init)(struct ebt_entry_watcher *w); |
| 148 | int (*parse)(int c, char **argv, int argc, |
| 149 | const struct ebt_u_entry *entry, unsigned int *flags, |
| 150 | struct ebt_entry_watcher **watcher); |
| 151 | void (*final_check)(const struct ebt_u_entry *entry, |
| 152 | const struct ebt_entry_watcher *watch, const char *name, |
Bart De Schuymer | 76712df | 2002-08-25 21:54:06 +0000 | [diff] [blame] | 153 | unsigned int hookmask, unsigned int time); |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 154 | void (*print)(const struct ebt_u_entry *entry, |
| 155 | const struct ebt_entry_watcher *watcher); |
| 156 | int (*compare)(const struct ebt_entry_watcher *w1, |
| 157 | const struct ebt_entry_watcher *w2); |
| 158 | const struct option *extra_ops; |
| 159 | unsigned int flags; |
| 160 | unsigned int option_offset; |
| 161 | struct ebt_entry_watcher *w; |
| 162 | unsigned int used; |
| 163 | struct ebt_u_watcher *next; |
| 164 | }; |
| 165 | |
| 166 | struct ebt_u_target |
| 167 | { |
| 168 | char name[EBT_FUNCTION_MAXNAMELEN]; |
| 169 | unsigned int size; |
| 170 | void (*help)(void); |
| 171 | void (*init)(struct ebt_entry_target *t); |
| 172 | int (*parse)(int c, char **argv, int argc, |
| 173 | const struct ebt_u_entry *entry, unsigned int *flags, |
| 174 | struct ebt_entry_target **target); |
| 175 | void (*final_check)(const struct ebt_u_entry *entry, |
| 176 | const struct ebt_entry_target *target, const char *name, |
Bart De Schuymer | 76712df | 2002-08-25 21:54:06 +0000 | [diff] [blame] | 177 | unsigned int hookmask, unsigned int time); |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 178 | void (*print)(const struct ebt_u_entry *entry, |
| 179 | const struct ebt_entry_target *target); |
| 180 | int (*compare)(const struct ebt_entry_target *t1, |
| 181 | const struct ebt_entry_target *t2); |
| 182 | const struct option *extra_ops; |
| 183 | unsigned int option_offset; |
| 184 | unsigned int flags; |
| 185 | struct ebt_entry_target *t; |
| 186 | unsigned int used; |
| 187 | struct ebt_u_target *next; |
| 188 | }; |
| 189 | |
| 190 | void register_table(struct ebt_u_table *); |
| 191 | void register_match(struct ebt_u_match *); |
| 192 | void register_watcher(struct ebt_u_watcher *); |
| 193 | void register_target(struct ebt_u_target *t); |
Bart De Schuymer | 9ce6ee9 | 2002-06-14 21:56:35 +0000 | [diff] [blame] | 194 | int get_table(struct ebt_u_replace *repl); |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 195 | struct ebt_u_target *find_target(const char *name); |
| 196 | struct ebt_u_match *find_match(const char *name); |
| 197 | struct ebt_u_watcher *find_watcher(const char *name); |
Bart De Schuymer | 8330e89 | 2002-07-14 19:06:47 +0000 | [diff] [blame] | 198 | struct ebt_u_table *find_table(char *name); |
Bart De Schuymer | ed05343 | 2002-07-21 19:35:39 +0000 | [diff] [blame] | 199 | void deliver_counters(struct ebt_u_replace *repl); |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 200 | void deliver_table(struct ebt_u_replace *repl); |
Bart De Schuymer | 9cfd654 | 2002-08-13 16:08:08 +0000 | [diff] [blame] | 201 | int name_to_number(char *name, uint16_t *proto); |
fnm3 | 8453274 | 2002-06-25 16:39:46 +0000 | [diff] [blame] | 202 | int number_to_name(unsigned short proto, char *name); |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 203 | void check_option(unsigned int *flags, unsigned int mask); |
| 204 | int check_inverse(const char option[]); |
Bart De Schuymer | d458648 | 2002-08-11 16:15:55 +0000 | [diff] [blame] | 205 | void __print_bug(char *file, int line, char *format, ...); |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 206 | #define print_bug(format, args...) \ |
Bart De Schuymer | d458648 | 2002-08-11 16:15:55 +0000 | [diff] [blame] | 207 | __print_bug(__FILE__, __LINE__, format, ##args) |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 208 | #define print_error(format, args...) {printf(format".\n", ##args); exit(-1);} |
| 209 | #define print_memory() {printf("Ebtables: " __FILE__ " " __FUNCTION__ \ |
| 210 | " %d :Out of memory.\n", __LINE__); exit(-1);} |
| 211 | |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 212 | // used for keeping the rule counters right during rule adds or deletes |
| 213 | #define CNT_NORM 0 |
| 214 | #define CNT_DEL 1 |
| 215 | #define CNT_ADD 2 |
| 216 | #define CNT_END 3 |
| 217 | #define CNT_ZERO 4 |
| 218 | |
Bart De Schuymer | 9cfd654 | 2002-08-13 16:08:08 +0000 | [diff] [blame] | 219 | extern char *standard_targets[NUM_STANDARD_TARGETS]; |
| 220 | // Transforms a target string into the right integer, |
| 221 | // returns 0 on success. |
| 222 | #define FILL_TARGET(_str, _pos) ({ \ |
| 223 | int _i, _ret = 0; \ |
| 224 | for (_i = 0; _i < NUM_STANDARD_TARGETS; _i++) \ |
| 225 | if (!strcmp(_str, standard_targets[_i])) {\ |
| 226 | _pos = -_i - 1; \ |
| 227 | break; \ |
| 228 | } \ |
| 229 | if (_i == NUM_STANDARD_TARGETS) \ |
| 230 | _ret = 1; \ |
| 231 | _ret; \ |
| 232 | }) |
| 233 | |
| 234 | // Transforms the target value to an index into standard_targets[] |
| 235 | #define TARGET_INDEX(_value) (-_value - 1) |
| 236 | // Returns a target string corresponding to the value |
| 237 | #define TARGET_NAME(_value) (standard_targets[TARGET_INDEX(_value)]) |
| 238 | // 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] | 239 | #define BASE_CHAIN (hookmask & (1 << NF_BR_NUMHOOKS)) |
Bart De Schuymer | 9cfd654 | 2002-08-13 16:08:08 +0000 | [diff] [blame] | 240 | // 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] | 241 | #define CLEAR_BASE_CHAIN_BIT (hookmask &= ~(1 << NF_BR_NUMHOOKS)) |
Bart De Schuymer | 1abc55d | 2002-06-01 19:23:47 +0000 | [diff] [blame] | 242 | #endif /* EBTABLES_U_H */ |