2 * $Id: ebtables.c,v 1.03 2002/01/19
4 * Copyright (C) 2001-2002 Bart De Schuymer
6 * This code is stongly inspired on the iptables code which is
7 * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
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.
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.
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.
26 #include <netinet/in.h>
27 #include <linux/netfilter_bridge/ebtables.h>
30 #define IPPROTO_SCTP 132
33 #define IPPROTO_DCCP 33
36 #define EXEC_STYLE_PRG 0
37 #define EXEC_STYLE_DAEMON 1
40 #define EBT_MIN_ALIGN (__alignof__(struct ebt_entry_target))
42 #define EBT_ALIGN(s) (((s) + (EBT_MIN_ALIGN-1)) & ~(EBT_MIN_ALIGN-1))
43 #define ERRORMSG_MAXLEN 128
48 unsigned int nentries
;
49 /* counter offset for this chain */
50 unsigned int counter_offset
;
52 unsigned int hook_mask
;
54 char name
[EBT_CHAIN_MAXNAMELEN
];
55 struct ebt_u_entry
*entries
;
61 unsigned short change
; /* determines incremental/decremental/change */
62 struct ebt_cntchanges
*prev
;
63 struct ebt_cntchanges
*next
;
66 #define EBT_ORI_MAX_CHAINS 10
69 char name
[EBT_TABLE_MAXNAMELEN
];
70 unsigned int valid_hooks
;
71 /* nr of rules in the table */
72 unsigned int nentries
;
73 unsigned int num_chains
;
74 unsigned int max_chains
;
75 struct ebt_u_entries
**chains
;
76 /* nr of counters userspace expects back */
77 unsigned int num_counters
;
78 /* where the kernel will put the old counters */
79 struct ebt_counter
*counters
;
81 * can be used e.g. to know if a standard option
82 * has been specified twice
85 /* we stick the specified command (e.g. -A) in here */
88 * here we stick the chain to do our thing on (can be -1 if unspecified)
91 /* used for the atomic option */
93 /* tells what happened to the old rules (counter changes) */
94 struct ebt_cntchanges
*cc
;
99 char name
[EBT_TABLE_MAXNAMELEN
];
100 void (*check
)(struct ebt_u_replace
*repl
);
101 void (*help
)(const char **);
102 struct ebt_u_table
*next
;
105 struct ebt_u_match_list
107 struct ebt_u_match_list
*next
;
108 struct ebt_entry_match
*m
;
111 struct ebt_u_watcher_list
113 struct ebt_u_watcher_list
*next
;
114 struct ebt_entry_watcher
*w
;
119 unsigned int bitmask
;
120 unsigned int invflags
;
123 char logical_in
[IFNAMSIZ
];
125 char logical_out
[IFNAMSIZ
];
126 unsigned char sourcemac
[ETH_ALEN
];
127 unsigned char sourcemsk
[ETH_ALEN
];
128 unsigned char destmac
[ETH_ALEN
];
129 unsigned char destmsk
[ETH_ALEN
];
130 struct ebt_u_match_list
*m_list
;
131 struct ebt_u_watcher_list
*w_list
;
132 struct ebt_entry_target
*t
;
133 struct ebt_u_entry
*prev
;
134 struct ebt_u_entry
*next
;
135 struct ebt_counter cnt
;
136 struct ebt_counter cnt_surplus
; /* for increasing/decreasing a counter and for option 'C' */
137 struct ebt_cntchanges
*cc
;
138 /* the standard target needs this to know the name of a udc when
139 * printing out rules. */
140 struct ebt_u_replace
*replace
;
145 char name
[EBT_FUNCTION_MAXNAMELEN
];
146 /* size of the real match data */
149 void (*init
)(struct ebt_entry_match
*m
);
150 int (*parse
)(int c
, char **argv
, int argc
,
151 const struct ebt_u_entry
*entry
, unsigned int *flags
,
152 struct ebt_entry_match
**match
);
153 void (*final_check
)(const struct ebt_u_entry
*entry
,
154 const struct ebt_entry_match
*match
,
155 const char *name
, unsigned int hookmask
, unsigned int time
);
156 void (*print
)(const struct ebt_u_entry
*entry
,
157 const struct ebt_entry_match
*match
);
158 int (*compare
)(const struct ebt_entry_match
*m1
,
159 const struct ebt_entry_match
*m2
);
160 const struct option
*extra_ops
;
162 * can be used e.g. to check for multiple occurance of the same option
165 unsigned int option_offset
;
166 struct ebt_entry_match
*m
;
168 * if used == 1 we no longer have to add it to
169 * the match chain of the new entry
170 * be sure to put it back on 0 when finished
173 struct ebt_u_match
*next
;
178 char name
[EBT_FUNCTION_MAXNAMELEN
];
181 void (*init
)(struct ebt_entry_watcher
*w
);
182 int (*parse
)(int c
, char **argv
, int argc
,
183 const struct ebt_u_entry
*entry
, unsigned int *flags
,
184 struct ebt_entry_watcher
**watcher
);
185 void (*final_check
)(const struct ebt_u_entry
*entry
,
186 const struct ebt_entry_watcher
*watch
, const char *name
,
187 unsigned int hookmask
, unsigned int time
);
188 void (*print
)(const struct ebt_u_entry
*entry
,
189 const struct ebt_entry_watcher
*watcher
);
190 int (*compare
)(const struct ebt_entry_watcher
*w1
,
191 const struct ebt_entry_watcher
*w2
);
192 const struct option
*extra_ops
;
194 unsigned int option_offset
;
195 struct ebt_entry_watcher
*w
;
197 struct ebt_u_watcher
*next
;
202 char name
[EBT_FUNCTION_MAXNAMELEN
];
205 void (*init
)(struct ebt_entry_target
*t
);
206 int (*parse
)(int c
, char **argv
, int argc
,
207 const struct ebt_u_entry
*entry
, unsigned int *flags
,
208 struct ebt_entry_target
**target
);
209 void (*final_check
)(const struct ebt_u_entry
*entry
,
210 const struct ebt_entry_target
*target
, const char *name
,
211 unsigned int hookmask
, unsigned int time
);
212 void (*print
)(const struct ebt_u_entry
*entry
,
213 const struct ebt_entry_target
*target
);
214 int (*compare
)(const struct ebt_entry_target
*t1
,
215 const struct ebt_entry_target
*t2
);
216 const struct option
*extra_ops
;
217 unsigned int option_offset
;
219 struct ebt_entry_target
*t
;
221 struct ebt_u_target
*next
;
226 extern struct ebt_u_table
*ebt_tables
;
227 extern struct ebt_u_match
*ebt_matches
;
228 extern struct ebt_u_watcher
*ebt_watchers
;
229 extern struct ebt_u_target
*ebt_targets
;
231 void ebt_register_table(struct ebt_u_table
*);
232 void ebt_register_match(struct ebt_u_match
*);
233 void ebt_register_watcher(struct ebt_u_watcher
*);
234 void ebt_register_target(struct ebt_u_target
*t
);
235 int ebt_get_kernel_table(struct ebt_u_replace
*replace
, int init
);
236 struct ebt_u_target
*ebt_find_target(const char *name
);
237 struct ebt_u_match
*ebt_find_match(const char *name
);
238 struct ebt_u_watcher
*ebt_find_watcher(const char *name
);
239 struct ebt_u_table
*ebt_find_table(const char *name
);
240 int ebtables_insmod(const char *modname
);
241 void ebt_list_extensions();
242 void ebt_initialize_entry(struct ebt_u_entry
*e
);
243 void ebt_cleanup_replace(struct ebt_u_replace
*replace
);
244 void ebt_reinit_extensions();
245 void ebt_double_chains(struct ebt_u_replace
*replace
);
246 void ebt_free_u_entry(struct ebt_u_entry
*e
);
247 struct ebt_u_entries
*ebt_name_to_chain(const struct ebt_u_replace
*replace
,
249 struct ebt_u_entries
*ebt_name_to_chain(const struct ebt_u_replace
*replace
,
251 int ebt_get_chainnr(const struct ebt_u_replace
*replace
, const char* arg
);
253 void ebt_change_policy(struct ebt_u_replace
*replace
, int policy
);
254 void ebt_flush_chains(struct ebt_u_replace
*replace
);
255 int ebt_check_rule_exists(struct ebt_u_replace
*replace
,
256 struct ebt_u_entry
*new_entry
);
257 void ebt_add_rule(struct ebt_u_replace
*replace
, struct ebt_u_entry
*new_entry
,
259 void ebt_delete_rule(struct ebt_u_replace
*replace
,
260 struct ebt_u_entry
*new_entry
, int begin
, int end
);
261 void ebt_zero_counters(struct ebt_u_replace
*replace
);
262 void ebt_change_counters(struct ebt_u_replace
*replace
,
263 struct ebt_u_entry
*new_entry
, int begin
, int end
,
264 struct ebt_counter
*cnt
, int mask
);
265 void ebt_new_chain(struct ebt_u_replace
*replace
, const char *name
, int policy
);
266 void ebt_delete_chain(struct ebt_u_replace
*replace
);
267 void ebt_rename_chain(struct ebt_u_replace
*replace
, const char *name
);
269 void ebt_do_final_checks(struct ebt_u_replace
*replace
, struct ebt_u_entry
*e
,
270 struct ebt_u_entries
*entries
);
271 int ebt_check_for_references(struct ebt_u_replace
*replace
, int print_err
);
272 int ebt_check_for_references2(struct ebt_u_replace
*replace
, int chain_nr
,
274 void ebt_check_for_loops(struct ebt_u_replace
*replace
);
275 void ebt_add_match(struct ebt_u_entry
*new_entry
, struct ebt_u_match
*m
);
276 void ebt_add_watcher(struct ebt_u_entry
*new_entry
, struct ebt_u_watcher
*w
);
277 void ebt_iterate_matches(void (*f
)(struct ebt_u_match
*));
278 void ebt_iterate_watchers(void (*f
)(struct ebt_u_watcher
*));
279 void ebt_iterate_targets(void (*f
)(struct ebt_u_target
*));
280 void __ebt_print_bug(char *file
, int line
, char *format
, ...);
281 void __ebt_print_error(char *format
, ...);
283 /* communication.c */
285 int ebt_get_table(struct ebt_u_replace
*repl
, int init
);
286 void ebt_deliver_counters(struct ebt_u_replace
*repl
);
287 void ebt_deliver_table(struct ebt_u_replace
*repl
);
289 /* useful_functions.c */
291 extern int ebt_invert
;
292 void ebt_check_option(unsigned int *flags
, unsigned int mask
);
293 #define ebt_check_inverse(arg) _ebt_check_inverse(arg, argc, argv)
294 int _ebt_check_inverse(const char option
[], int argc
, char **argv
);
295 void ebt_print_mac(const unsigned char *mac
);
296 void ebt_print_mac_and_mask(const unsigned char *mac
, const unsigned char *mask
);
297 int ebt_get_mac_and_mask(const char *from
, unsigned char *to
, unsigned char *mask
);
298 void ebt_parse_ip_address(char *address
, uint32_t *addr
, uint32_t *msk
);
299 char *ebt_mask_to_dotted(uint32_t mask
);
300 void ebt_parse_ip6_address(char *address
, struct in6_addr
*addr
,
301 struct in6_addr
*msk
);
302 char *ebt_ip6_to_numeric(const struct in6_addr
*addrp
);
305 int do_command(int argc
, char *argv
[], int exec_style
,
306 struct ebt_u_replace
*replace_
);
308 struct ethertypeent
*parseethertypebynumber(int type
);
310 #define ebt_to_chain(repl) \
311 ({struct ebt_u_entries *_ch = NULL; \
312 if (repl->selected_chain != -1) \
313 _ch = repl->chains[repl->selected_chain]; \
315 #define ebt_print_bug(format, args...) \
316 __ebt_print_bug(__FILE__, __LINE__, format, ##args)
317 #define ebt_print_error(format,args...) __ebt_print_error(format, ##args);
318 #define ebt_print_error2(format, args...) do {__ebt_print_error(format, ##args); \
319 return -1;} while (0)
320 #define ebt_check_option2(flags,mask) \
321 ({ebt_check_option(flags,mask); \
322 if (ebt_errormsg[0] != '\0') \
324 #define ebt_check_inverse2(option) \
325 ({int __ret = ebt_check_inverse(option); \
326 if (ebt_errormsg[0] != '\0') \
329 __ebt_print_error("Option without (mandatory) argument"); \
333 #define ebt_print_memory() do {printf("Ebtables: " __FILE__ \
334 " %s %d :Out of memory.\n", __FUNCTION__, __LINE__); exit(-1);} while (0)
336 /* used for keeping the rule counters right during rule adds or deletes */
342 extern const char *ebt_hooknames
[NF_BR_NUMHOOKS
];
343 extern const char *ebt_standard_targets
[NUM_STANDARD_TARGETS
];
344 extern char ebt_errormsg
[ERRORMSG_MAXLEN
];
345 extern char *ebt_modprobe
;
346 extern int ebt_silent
;
347 extern int ebt_printstyle_mac
;
350 * Transforms a target string into the right integer,
351 * returns 0 on success.
353 #define FILL_TARGET(_str, _pos) ({ \
355 for (_i = 0; _i < NUM_STANDARD_TARGETS; _i++) \
356 if (!strcmp(_str, ebt_standard_targets[_i])) {\
360 if (_i == NUM_STANDARD_TARGETS) \
365 /* Transforms the target value to an index into standard_targets[] */
366 #define TARGET_INDEX(_value) (-_value - 1)
367 /* Returns a target string corresponding to the value */
368 #define TARGET_NAME(_value) (ebt_standard_targets[TARGET_INDEX(_value)])
369 /* True if the hook mask denotes that the rule is in a base chain */
370 #define BASE_CHAIN (hookmask & (1 << NF_BR_NUMHOOKS))
371 /* Clear the bit in the hook_mask that tells if the rule is on a base chain */
372 #define CLEAR_BASE_CHAIN_BIT (hookmask &= ~(1 << NF_BR_NUMHOOKS))
373 #define PRINT_VERSION printf(PROGNAME" v"PROGVERSION" ("PROGDATE")\n")
374 #ifndef PROC_SYS_MODPROBE
375 #define PROC_SYS_MODPROBE "/proc/sys/kernel/modprobe"
377 #define ATOMIC_ENV_VARIABLE "EBTABLES_ATOMIC_FILE"
378 #endif /* EBTABLES_U_H */