├── .gitignore ├── LICENSE.txt ├── MANIFEST.in ├── README.md ├── ebtables.py ├── include ├── ebtables.h ├── ebtables_u.h ├── ethernetdb.h └── linux │ ├── if_ether.h │ ├── netfilter_bridge.h │ ├── netfilter_bridge │ ├── ebt_802_3.h │ ├── ebt_among.h │ ├── ebt_arp.h │ ├── ebt_arpreply.h │ ├── ebt_ip.h │ ├── ebt_ip6.h │ ├── ebt_limit.h │ ├── ebt_log.h │ ├── ebt_mark_m.h │ ├── ebt_mark_t.h │ ├── ebt_nat.h │ ├── ebt_nflog.h │ ├── ebt_pkttype.h │ ├── ebt_redirect.h │ ├── ebt_stp.h │ ├── ebt_ulog.h │ ├── ebt_vlan.h │ └── ebtables.h │ └── types.h ├── requirements.txt ├── setup.py └── test.py /.gitignore: -------------------------------------------------------------------------------- 1 | /build/ 2 | /dist/ 3 | 4 | /README.rst 5 | 6 | __pycache__/ 7 | *.egg-info/ 8 | 9 | *.pyc 10 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | This programs is dual-licensed under both the GPL version 2 and BSD 2 | license (the one with advertisement clause removed). Either license 3 | may be used at your option. 4 | 5 | 6 | GPL v2: 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License version 2 as 10 | published by the Free Software Foundation. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | 21 | 22 | Alternatively, this software may be distributed, used, and modified 23 | under the terms of BSD license: 24 | 25 | Redistribution and use in source and binary forms, with or without 26 | modification, are permitted provided that the following conditions are 27 | met: 28 | 29 | 1. Redistributions of source code must retain the above copyright 30 | notice, this list of conditions and the following disclaimer. 31 | 32 | 2. Redistributions in binary form must reproduce the above copyright 33 | notice, this list of conditions and the following disclaimer in the 34 | documentation and/or other materials provided with the distribution. 35 | 36 | 3. Neither the name(s) of the above-listed copyright holder(s) nor the 37 | names of its contributors may be used to endorse or promote products 38 | derived from this software without specific prior written permission. 39 | 40 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 41 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 42 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 43 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 44 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 46 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 47 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 48 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 49 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 50 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 51 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include requirements.txt 2 | recursive-include include * 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Ebtables 2 | ======== 3 | 4 | Ebtables is used for Ethernet bridge frame table administration on Linux. Python-ebtables is a simple Python binding for Ebtables. 5 | 6 | If you are looking for `iptables` bindings, check [python-iptables](https://github.com/ldx/python-iptables). 7 | 8 | Build 9 | ----- 10 | 11 | You will need [CFFI](https://cffi.readthedocs.org/). 12 | 13 | $ python setup.py build 14 | [...] 15 | $ python setup.py install 16 | [...] 17 | 18 | Check that you can import `ebtables`: 19 | 20 | $ python 21 | >>> import ebtables 22 | >>> 23 | 24 | Usage 25 | ----- 26 | 27 | Python-ebtables exposes an API that resembles the command line interface. For example: 28 | 29 | >>> import ebtables 30 | >>> rc, out, err = ebtables.nat('-L') 31 | >>> rc 32 | 0 33 | >>> print out.split('\n') 34 | ['Bridge table: nat', '', 'Bridge chain: PREROUTING, entries: 0, policy: ACCEPT', '', 'Bridge chain: OUTPUT, entries: 0, policy: ACCEPT', '', 'Bridge chain: POSTROUTING, entries: 0, policy: ACCEPT', ''] 35 | >>> err 36 | '' 37 | 38 | Ebtables needs administrator privileges. However, if you don't want to run your python app as root, you only need the `CAP_NET_RAW` capability. For example: 39 | 40 | $ sudo PATH=$PATH capsh --caps="cap_net_raw+p" -- -c "python" 41 | [sudo] password for user: 42 | Python 2.7.9 (default, Dec 11 2014, 08:58:12) 43 | [GCC 4.9.2] on linux2 44 | Type "help", "copyright", "credits" or "license" for more information. 45 | >>> import ebtables 46 | >>> ebtables.filter('-L') 47 | (0, 'Bridge table: filter\n\nBridge chain: INPUT, entries: 0, policy: ACCEPT\n\nBridge chain: FORWARD, entries: 0, policy: ACCEPT\n\nBridge chain: OUTPUT, entries: 0, policy: ACCEPT\n', '') 48 | >>> 49 | -------------------------------------------------------------------------------- /ebtables.py: -------------------------------------------------------------------------------- 1 | import fcntl 2 | import hashlib 3 | import os 4 | import sys 5 | from cffi import FFI 6 | 7 | __version__ = '0.3.0.dev1' 8 | 9 | EBTABLES_LIBRARY_PATH = os.getenv('EBTABLES_LIBRARY_PATH') or '/lib/ebtables' 10 | 11 | 12 | class EbtablesException(Exception): 13 | pass 14 | 15 | 16 | def _get_libname(f): 17 | prefix = f.find('lib') 18 | if prefix != -1: 19 | f = f[prefix + 3:] 20 | if f.endswith('.so'): 21 | f = f[:-3] 22 | return f 23 | 24 | 25 | def _get_libraries(): 26 | files = os.listdir(EBTABLES_LIBRARY_PATH) 27 | return [_get_libname(f) for f in files if f.endswith('.so')] 28 | 29 | 30 | ffi = FFI() 31 | 32 | _cdef = """ 33 | #define EBT_TABLE_MAXNAMELEN 32 34 | 35 | #define ERRORMSG_MAXLEN 128 36 | 37 | #define EXEC_STYLE_PRG ... 38 | #define EXEC_STYLE_DAEMON ... 39 | 40 | /* 41 | * Fields are not in order, but CFFI will take care of it since we use 42 | * '...' at the end. 43 | */ 44 | struct ebt_u_replace { 45 | char name[EBT_TABLE_MAXNAMELEN]; 46 | struct ebt_u_entries **chains; 47 | struct ebt_cntchanges *cc; 48 | unsigned int flags; 49 | char command; 50 | ...; 51 | }; 52 | 53 | extern char ebt_errormsg[ERRORMSG_MAXLEN]; 54 | 55 | extern int ebt_silent; 56 | 57 | extern char *optarg; 58 | extern int optind; 59 | 60 | unsigned int OPT_KERNELDATA = 0x800; 61 | 62 | int do_command(int argc, char *argv[], int exec_style, 63 | struct ebt_u_replace *replace_); 64 | int ebt_get_kernel_table(struct ebt_u_replace *replace, int init); 65 | void ebt_deliver_table(struct ebt_u_replace *u_repl); 66 | void ebt_cleanup_replace(struct ebt_u_replace *replace); 67 | void ebt_early_init_once(void); 68 | void ebt_reinit_extensions(); 69 | 70 | char *strcpy(char *dest, const char *src); 71 | void free(void *ptr); 72 | """ 73 | 74 | _verify = """ 75 | #include 76 | #include 77 | #include 78 | #include 79 | #include 80 | #include "include/ebtables.h" 81 | #include "include/ebtables_u.h" 82 | 83 | unsigned int OPT_KERNELDATA = 0x800; 84 | 85 | void ebt_early_init_once(void); 86 | """ 87 | 88 | # Changed this to be python3 compatible which requires string encoding 89 | _hash = hashlib.sha1(_cdef.encode('utf-8') + _verify.encode('utf-8')).hexdigest() 90 | 91 | ffi.cdef(_cdef) 92 | 93 | _ebtc = ffi.verify(_verify, 94 | libraries=_get_libraries(), 95 | include_dirs=[os.path.dirname(os.path.abspath(__file__))], 96 | library_dirs=[EBTABLES_LIBRARY_PATH], 97 | runtime_library_dirs=[EBTABLES_LIBRARY_PATH], 98 | modulename='ebtables_%s' % _hash) 99 | 100 | _ebtc.ebt_early_init_once() 101 | 102 | _ebtc.ebt_silent = 1 103 | # Changed this to be python3 compatible which requires string encoding 104 | _ebtc.ebt_errormsg[0] = '\0'.encode("ascii") 105 | 106 | 107 | def _get_errormsg(): 108 | # Read last error message, and reset ebt_errormsg. 109 | msg = ffi.string(_ebtc.ebt_errormsg) 110 | _ebtc.ebt_errormsg[0] = '\0' 111 | return msg 112 | 113 | 114 | def _do_command(rpl, args): 115 | _get_errormsg() # Make sure there's no unread error. 116 | rc = _ebtc.do_command(len(args), args, _ebtc.EXEC_STYLE_DAEMON, rpl) 117 | err = _get_errormsg() 118 | 119 | if rc == 0 and rpl.command in ['A', 'I', 'D']: 120 | # This needs to be called after an add. 121 | _ebtc.ebt_reinit_extensions() 122 | 123 | if rc == 0 and not err: 124 | _ebtc.ebt_deliver_table(rpl) # Commit result. 125 | err = _get_errormsg() 126 | if err: 127 | rc = -1 128 | err = 'ebt_deliver_table() failed %s' % err 129 | 130 | return rc, err 131 | 132 | 133 | def _cmd(rpl, args): 134 | sys.stdout.flush() 135 | stdout = os.dup(1) 136 | pipes = (None, None) 137 | cmd_out = '' 138 | cmd_err = '' 139 | try: 140 | pipes = os.pipe() 141 | fcntl.fcntl(pipes[0], fcntl.F_SETFL, os.O_NONBLOCK) 142 | os.dup2(pipes[1], 1) 143 | 144 | rc, cmd_err = _do_command(rpl, args) 145 | 146 | tmp_out = [] 147 | while True: 148 | try: 149 | buf = os.read(pipes[0], 1024) 150 | except OSError as e: 151 | if e.errno == 11: 152 | break 153 | else: 154 | raise 155 | if not buf: 156 | break 157 | tmp_out.append(buf) 158 | cmd_out = ''.join(tmp_out) 159 | return rc, cmd_out, cmd_err 160 | except: 161 | return -1, cmd_out, cmd_err 162 | finally: 163 | for p in pipes: 164 | if p is not None: 165 | os.close(p) 166 | os.dup2(stdout, 1) 167 | os.close(stdout) 168 | 169 | 170 | def _free_replace(rc, rpl): 171 | _ebtc.ebt_cleanup_replace(rpl) 172 | # These two fields are not freed by ebtables. 173 | if rpl.chains: 174 | _ebtc.free(rpl.chains) 175 | rpl.chains = ffi.NULL 176 | if rpl.cc: 177 | _ebtc.free(rpl.cc) 178 | rpl.cc = ffi.NULL 179 | rpl.flags &= ~_ebtc.OPT_KERNELDATA 180 | 181 | 182 | def cmd(table, params): 183 | if isinstance(params, str): 184 | params = params.split() 185 | 186 | _ebtc.optarg = ffi.NULL 187 | _ebtc.optind = 0 188 | 189 | args_list = [ffi.new('char []', './ebtables')] 190 | for p in params: 191 | args_list.append(ffi.new('char []', p)) 192 | args = ffi.new('char *[]', args_list) 193 | 194 | # Allocate and set up an ebt_u_replace struct. 195 | rpl = ffi.new('struct ebt_u_replace *') 196 | _ebtc.strcpy(rpl.name, ffi.new('char[]', table)) 197 | if _ebtc.ebt_get_kernel_table(rpl, 0) != 0: 198 | raise EbtablesException('ebt_get_kernel_table() failed %s' % 199 | _get_errormsg()) 200 | rpl.flags |= _ebtc.OPT_KERNELDATA 201 | 202 | result = _cmd(rpl, args) 203 | 204 | _free_replace(result[0], rpl) 205 | return result 206 | 207 | 208 | def filter(params): 209 | return cmd('filter', params) 210 | 211 | 212 | def nat(params): 213 | return cmd('nat', params) 214 | 215 | 216 | def broute(params): 217 | return cmd('broute', params) 218 | -------------------------------------------------------------------------------- /include/ebtables.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ebtables 3 | * 4 | * Authors: 5 | * Bart De Schuymer 6 | * 7 | * ebtables.c,v 2.0, April, 2002 8 | * 9 | * This code is stongly inspired on the iptables code which is 10 | * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling 11 | */ 12 | 13 | /* Local copy of the kernel file, needed for Sparc64 support */ 14 | #ifndef __LINUX_BRIDGE_EFF_H 15 | #define __LINUX_BRIDGE_EFF_H 16 | #include 17 | #include 18 | #include 19 | 20 | #define EBT_TABLE_MAXNAMELEN 32 21 | #define EBT_CHAIN_MAXNAMELEN EBT_TABLE_MAXNAMELEN 22 | #define EBT_FUNCTION_MAXNAMELEN EBT_TABLE_MAXNAMELEN 23 | 24 | /* verdicts >0 are "branches" */ 25 | #define EBT_ACCEPT -1 26 | #define EBT_DROP -2 27 | #define EBT_CONTINUE -3 28 | #define EBT_RETURN -4 29 | #define NUM_STANDARD_TARGETS 4 30 | /* ebtables target modules store the verdict inside an int. We can 31 | * reclaim a part of this int for backwards compatible extensions. 32 | * The 4 lsb are more than enough to store the verdict. */ 33 | #define EBT_VERDICT_BITS 0x0000000F 34 | 35 | struct ebt_counter 36 | { 37 | uint64_t pcnt; 38 | uint64_t bcnt; 39 | }; 40 | 41 | struct ebt_replace 42 | { 43 | char name[EBT_TABLE_MAXNAMELEN]; 44 | unsigned int valid_hooks; 45 | /* nr of rules in the table */ 46 | unsigned int nentries; 47 | /* total size of the entries */ 48 | unsigned int entries_size; 49 | /* start of the chains */ 50 | #ifdef KERNEL_64_USERSPACE_32 51 | uint64_t hook_entry[NF_BR_NUMHOOKS]; 52 | #else 53 | struct ebt_entries *hook_entry[NF_BR_NUMHOOKS]; 54 | #endif 55 | /* nr of counters userspace expects back */ 56 | unsigned int num_counters; 57 | /* where the kernel will put the old counters */ 58 | #ifdef KERNEL_64_USERSPACE_32 59 | uint64_t counters; 60 | uint64_t entries; 61 | #else 62 | struct ebt_counter *counters; 63 | char *entries; 64 | #endif 65 | }; 66 | 67 | struct ebt_entries { 68 | /* this field is always set to zero 69 | * See EBT_ENTRY_OR_ENTRIES. 70 | * Must be same size as ebt_entry.bitmask */ 71 | unsigned int distinguisher; 72 | /* the chain name */ 73 | char name[EBT_CHAIN_MAXNAMELEN]; 74 | /* counter offset for this chain */ 75 | unsigned int counter_offset; 76 | /* one standard (accept, drop, return) per hook */ 77 | int policy; 78 | /* nr. of entries */ 79 | unsigned int nentries; 80 | /* entry list */ 81 | char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); 82 | }; 83 | 84 | /* used for the bitmask of struct ebt_entry */ 85 | 86 | /* This is a hack to make a difference between an ebt_entry struct and an 87 | * ebt_entries struct when traversing the entries from start to end. 88 | * Using this simplifies the code alot, while still being able to use 89 | * ebt_entries. 90 | * Contrary, iptables doesn't use something like ebt_entries and therefore uses 91 | * different techniques for naming the policy and such. So, iptables doesn't 92 | * need a hack like this. 93 | */ 94 | #define EBT_ENTRY_OR_ENTRIES 0x01 95 | /* these are the normal masks */ 96 | #define EBT_NOPROTO 0x02 97 | #define EBT_802_3 0x04 98 | #define EBT_SOURCEMAC 0x08 99 | #define EBT_DESTMAC 0x10 100 | #define EBT_F_MASK (EBT_NOPROTO | EBT_802_3 | EBT_SOURCEMAC | EBT_DESTMAC \ 101 | | EBT_ENTRY_OR_ENTRIES) 102 | 103 | #define EBT_IPROTO 0x01 104 | #define EBT_IIN 0x02 105 | #define EBT_IOUT 0x04 106 | #define EBT_ISOURCE 0x8 107 | #define EBT_IDEST 0x10 108 | #define EBT_ILOGICALIN 0x20 109 | #define EBT_ILOGICALOUT 0x40 110 | #define EBT_INV_MASK (EBT_IPROTO | EBT_IIN | EBT_IOUT | EBT_ILOGICALIN \ 111 | | EBT_ILOGICALOUT | EBT_ISOURCE | EBT_IDEST) 112 | 113 | struct ebt_entry_match 114 | { 115 | union { 116 | char name[EBT_FUNCTION_MAXNAMELEN]; 117 | struct ebt_match *match; 118 | } u; 119 | /* size of data */ 120 | unsigned int match_size; 121 | #ifdef KERNEL_64_USERSPACE_32 122 | unsigned int pad; 123 | #endif 124 | unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); 125 | }; 126 | 127 | struct ebt_entry_watcher 128 | { 129 | union { 130 | char name[EBT_FUNCTION_MAXNAMELEN]; 131 | struct ebt_watcher *watcher; 132 | } u; 133 | /* size of data */ 134 | unsigned int watcher_size; 135 | #ifdef KERNEL_64_USERSPACE_32 136 | unsigned int pad; 137 | #endif 138 | unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); 139 | }; 140 | 141 | struct ebt_entry_target 142 | { 143 | union { 144 | char name[EBT_FUNCTION_MAXNAMELEN]; 145 | struct ebt_target *target; 146 | } u; 147 | /* size of data */ 148 | unsigned int target_size; 149 | #ifdef KERNEL_64_USERSPACE_32 150 | unsigned int pad; 151 | #endif 152 | unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); 153 | }; 154 | 155 | #define EBT_STANDARD_TARGET "standard" 156 | struct ebt_standard_target 157 | { 158 | struct ebt_entry_target target; 159 | int verdict; 160 | #ifdef KERNEL_64_USERSPACE_32 161 | unsigned int pad; 162 | #endif 163 | }; 164 | 165 | /* one entry */ 166 | struct ebt_entry { 167 | /* this needs to be the first field */ 168 | unsigned int bitmask; 169 | unsigned int invflags; 170 | uint16_t ethproto; 171 | /* the physical in-dev */ 172 | char in[IFNAMSIZ]; 173 | /* the logical in-dev */ 174 | char logical_in[IFNAMSIZ]; 175 | /* the physical out-dev */ 176 | char out[IFNAMSIZ]; 177 | /* the logical out-dev */ 178 | char logical_out[IFNAMSIZ]; 179 | unsigned char sourcemac[ETH_ALEN]; 180 | unsigned char sourcemsk[ETH_ALEN]; 181 | unsigned char destmac[ETH_ALEN]; 182 | unsigned char destmsk[ETH_ALEN]; 183 | /* sizeof ebt_entry + matches */ 184 | unsigned int watchers_offset; 185 | /* sizeof ebt_entry + matches + watchers */ 186 | unsigned int target_offset; 187 | /* sizeof ebt_entry + matches + watchers + target */ 188 | unsigned int next_offset; 189 | unsigned char elems[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); 190 | }; 191 | 192 | /* {g,s}etsockopt numbers */ 193 | #define EBT_BASE_CTL 128 194 | 195 | #define EBT_SO_SET_ENTRIES (EBT_BASE_CTL) 196 | #define EBT_SO_SET_COUNTERS (EBT_SO_SET_ENTRIES+1) 197 | #define EBT_SO_SET_MAX (EBT_SO_SET_COUNTERS+1) 198 | 199 | #define EBT_SO_GET_INFO (EBT_BASE_CTL) 200 | #define EBT_SO_GET_ENTRIES (EBT_SO_GET_INFO+1) 201 | #define EBT_SO_GET_INIT_INFO (EBT_SO_GET_ENTRIES+1) 202 | #define EBT_SO_GET_INIT_ENTRIES (EBT_SO_GET_INIT_INFO+1) 203 | #define EBT_SO_GET_MAX (EBT_SO_GET_INIT_ENTRIES+1) 204 | 205 | /* blatently stolen from ip_tables.h 206 | * fn returns 0 to continue iteration */ 207 | #define EBT_MATCH_ITERATE(e, fn, args...) \ 208 | ({ \ 209 | unsigned int __i; \ 210 | int __ret = 0; \ 211 | struct ebt_entry_match *__match; \ 212 | \ 213 | for (__i = sizeof(struct ebt_entry); \ 214 | __i < (e)->watchers_offset; \ 215 | __i += __match->match_size + \ 216 | sizeof(struct ebt_entry_match)) { \ 217 | __match = (void *)(e) + __i; \ 218 | \ 219 | __ret = fn(__match , ## args); \ 220 | if (__ret != 0) \ 221 | break; \ 222 | } \ 223 | if (__ret == 0) { \ 224 | if (__i != (e)->watchers_offset) \ 225 | __ret = -EINVAL; \ 226 | } \ 227 | __ret; \ 228 | }) 229 | 230 | #define EBT_WATCHER_ITERATE(e, fn, args...) \ 231 | ({ \ 232 | unsigned int __i; \ 233 | int __ret = 0; \ 234 | struct ebt_entry_watcher *__watcher; \ 235 | \ 236 | for (__i = e->watchers_offset; \ 237 | __i < (e)->target_offset; \ 238 | __i += __watcher->watcher_size + \ 239 | sizeof(struct ebt_entry_watcher)) { \ 240 | __watcher = (void *)(e) + __i; \ 241 | \ 242 | __ret = fn(__watcher , ## args); \ 243 | if (__ret != 0) \ 244 | break; \ 245 | } \ 246 | if (__ret == 0) { \ 247 | if (__i != (e)->target_offset) \ 248 | __ret = -EINVAL; \ 249 | } \ 250 | __ret; \ 251 | }) 252 | 253 | #define EBT_ENTRY_ITERATE(entries, size, fn, args...) \ 254 | ({ \ 255 | unsigned int __i; \ 256 | int __ret = 0; \ 257 | struct ebt_entry *__entry; \ 258 | \ 259 | for (__i = 0; __i < (size);) { \ 260 | __entry = (void *)(entries) + __i; \ 261 | __ret = fn(__entry , ## args); \ 262 | if (__ret != 0) \ 263 | break; \ 264 | if (__entry->bitmask != 0) \ 265 | __i += __entry->next_offset; \ 266 | else \ 267 | __i += sizeof(struct ebt_entries); \ 268 | } \ 269 | if (__ret == 0) { \ 270 | if (__i != (size)) \ 271 | __ret = -EINVAL; \ 272 | } \ 273 | __ret; \ 274 | }) 275 | 276 | #endif 277 | -------------------------------------------------------------------------------- /include/ebtables_u.h: -------------------------------------------------------------------------------- 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 26 | #include 27 | #include 28 | #include 29 | 30 | #ifndef IPPROTO_SCTP 31 | #define IPPROTO_SCTP 132 32 | #endif 33 | #ifndef IPPROTO_DCCP 34 | #define IPPROTO_DCCP 33 35 | #endif 36 | 37 | #define EXEC_STYLE_PRG 0 38 | #define EXEC_STYLE_DAEMON 1 39 | 40 | #ifndef EBT_MIN_ALIGN 41 | #define EBT_MIN_ALIGN (__alignof__(struct _xt_align)) 42 | #endif 43 | #define EBT_ALIGN(s) (((s) + (EBT_MIN_ALIGN-1)) & ~(EBT_MIN_ALIGN-1)) 44 | #define ERRORMSG_MAXLEN 128 45 | 46 | struct ebt_u_entries 47 | { 48 | int policy; 49 | unsigned int nentries; 50 | /* counter offset for this chain */ 51 | unsigned int counter_offset; 52 | /* used for udc */ 53 | unsigned int hook_mask; 54 | char *kernel_start; 55 | char name[EBT_CHAIN_MAXNAMELEN]; 56 | struct ebt_u_entry *entries; 57 | }; 58 | 59 | struct ebt_cntchanges 60 | { 61 | unsigned short type; 62 | unsigned short change; /* determines incremental/decremental/change */ 63 | struct ebt_cntchanges *prev; 64 | struct ebt_cntchanges *next; 65 | }; 66 | 67 | #define EBT_ORI_MAX_CHAINS 10 68 | struct ebt_u_replace 69 | { 70 | char name[EBT_TABLE_MAXNAMELEN]; 71 | unsigned int valid_hooks; 72 | /* nr of rules in the table */ 73 | unsigned int nentries; 74 | unsigned int num_chains; 75 | unsigned int max_chains; 76 | struct ebt_u_entries **chains; 77 | /* nr of counters userspace expects back */ 78 | unsigned int num_counters; 79 | /* where the kernel will put the old counters */ 80 | struct ebt_counter *counters; 81 | /* 82 | * can be used e.g. to know if a standard option 83 | * has been specified twice 84 | */ 85 | unsigned int flags; 86 | /* we stick the specified command (e.g. -A) in here */ 87 | char command; 88 | /* 89 | * here we stick the chain to do our thing on (can be -1 if unspecified) 90 | */ 91 | int selected_chain; 92 | /* used for the atomic option */ 93 | char *filename; 94 | /* tells what happened to the old rules (counter changes) */ 95 | struct ebt_cntchanges *cc; 96 | }; 97 | 98 | struct ebt_u_table 99 | { 100 | char name[EBT_TABLE_MAXNAMELEN]; 101 | void (*check)(struct ebt_u_replace *repl); 102 | void (*help)(const char **); 103 | struct ebt_u_table *next; 104 | }; 105 | 106 | struct ebt_u_match_list 107 | { 108 | struct ebt_u_match_list *next; 109 | struct ebt_entry_match *m; 110 | }; 111 | 112 | struct ebt_u_watcher_list 113 | { 114 | struct ebt_u_watcher_list *next; 115 | struct ebt_entry_watcher *w; 116 | }; 117 | 118 | struct ebt_u_entry 119 | { 120 | unsigned int bitmask; 121 | unsigned int invflags; 122 | uint16_t ethproto; 123 | char in[IFNAMSIZ]; 124 | char logical_in[IFNAMSIZ]; 125 | char out[IFNAMSIZ]; 126 | char logical_out[IFNAMSIZ]; 127 | unsigned char sourcemac[ETH_ALEN]; 128 | unsigned char sourcemsk[ETH_ALEN]; 129 | unsigned char destmac[ETH_ALEN]; 130 | unsigned char destmsk[ETH_ALEN]; 131 | struct ebt_u_match_list *m_list; 132 | struct ebt_u_watcher_list *w_list; 133 | struct ebt_entry_target *t; 134 | struct ebt_u_entry *prev; 135 | struct ebt_u_entry *next; 136 | struct ebt_counter cnt; 137 | struct ebt_counter cnt_surplus; /* for increasing/decreasing a counter and for option 'C' */ 138 | struct ebt_cntchanges *cc; 139 | /* the standard target needs this to know the name of a udc when 140 | * printing out rules. */ 141 | struct ebt_u_replace *replace; 142 | }; 143 | 144 | struct ebt_u_match 145 | { 146 | char name[EBT_FUNCTION_MAXNAMELEN]; 147 | /* size of the real match data */ 148 | unsigned int size; 149 | void (*help)(void); 150 | void (*init)(struct ebt_entry_match *m); 151 | int (*parse)(int c, char **argv, int argc, 152 | const struct ebt_u_entry *entry, unsigned int *flags, 153 | struct ebt_entry_match **match); 154 | void (*final_check)(const struct ebt_u_entry *entry, 155 | const struct ebt_entry_match *match, 156 | const char *name, unsigned int hookmask, unsigned int time); 157 | void (*print)(const struct ebt_u_entry *entry, 158 | const struct ebt_entry_match *match); 159 | int (*compare)(const struct ebt_entry_match *m1, 160 | const struct ebt_entry_match *m2); 161 | const struct option *extra_ops; 162 | /* 163 | * can be used e.g. to check for multiple occurance of the same option 164 | */ 165 | unsigned int flags; 166 | unsigned int option_offset; 167 | struct ebt_entry_match *m; 168 | /* 169 | * if used == 1 we no longer have to add it to 170 | * the match chain of the new entry 171 | * be sure to put it back on 0 when finished 172 | */ 173 | unsigned int used; 174 | struct ebt_u_match *next; 175 | }; 176 | 177 | struct ebt_u_watcher 178 | { 179 | char name[EBT_FUNCTION_MAXNAMELEN]; 180 | unsigned int size; 181 | void (*help)(void); 182 | void (*init)(struct ebt_entry_watcher *w); 183 | int (*parse)(int c, char **argv, int argc, 184 | const struct ebt_u_entry *entry, unsigned int *flags, 185 | struct ebt_entry_watcher **watcher); 186 | void (*final_check)(const struct ebt_u_entry *entry, 187 | const struct ebt_entry_watcher *watch, const char *name, 188 | unsigned int hookmask, unsigned int time); 189 | void (*print)(const struct ebt_u_entry *entry, 190 | const struct ebt_entry_watcher *watcher); 191 | int (*compare)(const struct ebt_entry_watcher *w1, 192 | const struct ebt_entry_watcher *w2); 193 | const struct option *extra_ops; 194 | unsigned int flags; 195 | unsigned int option_offset; 196 | struct ebt_entry_watcher *w; 197 | unsigned int used; 198 | struct ebt_u_watcher *next; 199 | }; 200 | 201 | struct ebt_u_target 202 | { 203 | char name[EBT_FUNCTION_MAXNAMELEN]; 204 | unsigned int size; 205 | void (*help)(void); 206 | void (*init)(struct ebt_entry_target *t); 207 | int (*parse)(int c, char **argv, int argc, 208 | const struct ebt_u_entry *entry, unsigned int *flags, 209 | struct ebt_entry_target **target); 210 | void (*final_check)(const struct ebt_u_entry *entry, 211 | const struct ebt_entry_target *target, const char *name, 212 | unsigned int hookmask, unsigned int time); 213 | void (*print)(const struct ebt_u_entry *entry, 214 | const struct ebt_entry_target *target); 215 | int (*compare)(const struct ebt_entry_target *t1, 216 | const struct ebt_entry_target *t2); 217 | const struct option *extra_ops; 218 | unsigned int option_offset; 219 | unsigned int flags; 220 | struct ebt_entry_target *t; 221 | unsigned int used; 222 | struct ebt_u_target *next; 223 | }; 224 | 225 | /* libebtc.c */ 226 | 227 | extern struct ebt_u_table *ebt_tables; 228 | extern struct ebt_u_match *ebt_matches; 229 | extern struct ebt_u_watcher *ebt_watchers; 230 | extern struct ebt_u_target *ebt_targets; 231 | 232 | extern int use_lockfd; 233 | 234 | void ebt_register_table(struct ebt_u_table *); 235 | void ebt_register_match(struct ebt_u_match *); 236 | void ebt_register_watcher(struct ebt_u_watcher *); 237 | void ebt_register_target(struct ebt_u_target *t); 238 | int ebt_get_kernel_table(struct ebt_u_replace *replace, int init); 239 | struct ebt_u_target *ebt_find_target(const char *name); 240 | struct ebt_u_match *ebt_find_match(const char *name); 241 | struct ebt_u_watcher *ebt_find_watcher(const char *name); 242 | struct ebt_u_table *ebt_find_table(const char *name); 243 | int ebtables_insmod(const char *modname); 244 | void ebt_list_extensions(); 245 | void ebt_initialize_entry(struct ebt_u_entry *e); 246 | void ebt_cleanup_replace(struct ebt_u_replace *replace); 247 | void ebt_reinit_extensions(); 248 | void ebt_double_chains(struct ebt_u_replace *replace); 249 | void ebt_free_u_entry(struct ebt_u_entry *e); 250 | struct ebt_u_entries *ebt_name_to_chain(const struct ebt_u_replace *replace, 251 | const char* arg); 252 | struct ebt_u_entries *ebt_name_to_chain(const struct ebt_u_replace *replace, 253 | const char* arg); 254 | int ebt_get_chainnr(const struct ebt_u_replace *replace, const char* arg); 255 | /**/ 256 | void ebt_change_policy(struct ebt_u_replace *replace, int policy); 257 | void ebt_flush_chains(struct ebt_u_replace *replace); 258 | int ebt_check_rule_exists(struct ebt_u_replace *replace, 259 | struct ebt_u_entry *new_entry); 260 | void ebt_add_rule(struct ebt_u_replace *replace, struct ebt_u_entry *new_entry, 261 | int rule_nr); 262 | void ebt_delete_rule(struct ebt_u_replace *replace, 263 | struct ebt_u_entry *new_entry, int begin, int end); 264 | void ebt_zero_counters(struct ebt_u_replace *replace); 265 | void ebt_change_counters(struct ebt_u_replace *replace, 266 | struct ebt_u_entry *new_entry, int begin, int end, 267 | struct ebt_counter *cnt, int mask); 268 | void ebt_new_chain(struct ebt_u_replace *replace, const char *name, int policy); 269 | void ebt_delete_chain(struct ebt_u_replace *replace); 270 | void ebt_rename_chain(struct ebt_u_replace *replace, const char *name); 271 | /**/ 272 | void ebt_do_final_checks(struct ebt_u_replace *replace, struct ebt_u_entry *e, 273 | struct ebt_u_entries *entries); 274 | int ebt_check_for_references(struct ebt_u_replace *replace, int print_err); 275 | int ebt_check_for_references2(struct ebt_u_replace *replace, int chain_nr, 276 | int print_err); 277 | void ebt_check_for_loops(struct ebt_u_replace *replace); 278 | void ebt_add_match(struct ebt_u_entry *new_entry, struct ebt_u_match *m); 279 | void ebt_add_watcher(struct ebt_u_entry *new_entry, struct ebt_u_watcher *w); 280 | void ebt_iterate_matches(void (*f)(struct ebt_u_match *)); 281 | void ebt_iterate_watchers(void (*f)(struct ebt_u_watcher *)); 282 | void ebt_iterate_targets(void (*f)(struct ebt_u_target *)); 283 | void __ebt_print_bug(char *file, int line, char *format, ...); 284 | void __ebt_print_error(char *format, ...); 285 | 286 | /* communication.c */ 287 | 288 | int ebt_get_table(struct ebt_u_replace *repl, int init); 289 | void ebt_deliver_counters(struct ebt_u_replace *repl); 290 | void ebt_deliver_table(struct ebt_u_replace *repl); 291 | 292 | /* useful_functions.c */ 293 | 294 | extern int ebt_invert; 295 | void ebt_check_option(unsigned int *flags, unsigned int mask); 296 | #define ebt_check_inverse(arg) _ebt_check_inverse(arg, argc, argv) 297 | int _ebt_check_inverse(const char option[], int argc, char **argv); 298 | void ebt_print_mac(const unsigned char *mac); 299 | void ebt_print_mac_and_mask(const unsigned char *mac, const unsigned char *mask); 300 | int ebt_get_mac_and_mask(const char *from, unsigned char *to, unsigned char *mask); 301 | void ebt_parse_ip_address(char *address, uint32_t *addr, uint32_t *msk); 302 | char *ebt_mask_to_dotted(uint32_t mask); 303 | void ebt_parse_ip6_address(char *address, struct in6_addr *addr, 304 | struct in6_addr *msk); 305 | char *ebt_ip6_to_numeric(const struct in6_addr *addrp); 306 | 307 | 308 | int do_command(int argc, char *argv[], int exec_style, 309 | struct ebt_u_replace *replace_); 310 | 311 | struct ethertypeent *parseethertypebynumber(int type); 312 | 313 | #define ebt_to_chain(repl) \ 314 | ({struct ebt_u_entries *_ch = NULL; \ 315 | if (repl->selected_chain != -1) \ 316 | _ch = repl->chains[repl->selected_chain]; \ 317 | _ch;}) 318 | #define ebt_print_bug(format, args...) \ 319 | __ebt_print_bug(__FILE__, __LINE__, format, ##args) 320 | #define ebt_print_error(format,args...) __ebt_print_error(format, ##args); 321 | #define ebt_print_error2(format, args...) do {__ebt_print_error(format, ##args); \ 322 | return -1;} while (0) 323 | #define ebt_check_option2(flags,mask) \ 324 | ({ebt_check_option(flags,mask); \ 325 | if (ebt_errormsg[0] != '\0') \ 326 | return -1;}) 327 | #define ebt_check_inverse2(option) \ 328 | ({int __ret = ebt_check_inverse(option); \ 329 | if (ebt_errormsg[0] != '\0') \ 330 | return -1; \ 331 | if (!optarg) { \ 332 | __ebt_print_error("Option without (mandatory) argument"); \ 333 | return -1; \ 334 | } \ 335 | __ret;}) 336 | #define ebt_print_memory() do {printf("Ebtables: " __FILE__ \ 337 | " %s %d :Out of memory.\n", __FUNCTION__, __LINE__); exit(-1);} while (0) 338 | 339 | /* used for keeping the rule counters right during rule adds or deletes */ 340 | #define CNT_NORM 0 341 | #define CNT_DEL 1 342 | #define CNT_ADD 2 343 | #define CNT_CHANGE 3 344 | 345 | extern const char *ebt_hooknames[NF_BR_NUMHOOKS]; 346 | extern const char *ebt_standard_targets[NUM_STANDARD_TARGETS]; 347 | extern char ebt_errormsg[ERRORMSG_MAXLEN]; 348 | extern char *ebt_modprobe; 349 | extern int ebt_silent; 350 | extern int ebt_printstyle_mac; 351 | 352 | /* 353 | * Transforms a target string into the right integer, 354 | * returns 0 on success. 355 | */ 356 | #define FILL_TARGET(_str, _pos) ({ \ 357 | int _i, _ret = 0; \ 358 | for (_i = 0; _i < NUM_STANDARD_TARGETS; _i++) \ 359 | if (!strcmp(_str, ebt_standard_targets[_i])) {\ 360 | _pos = -_i - 1; \ 361 | break; \ 362 | } \ 363 | if (_i == NUM_STANDARD_TARGETS) \ 364 | _ret = 1; \ 365 | _ret; \ 366 | }) 367 | 368 | /* Transforms the target value to an index into standard_targets[] */ 369 | #define TARGET_INDEX(_value) (-_value - 1) 370 | /* Returns a target string corresponding to the value */ 371 | #define TARGET_NAME(_value) (ebt_standard_targets[TARGET_INDEX(_value)]) 372 | /* True if the hook mask denotes that the rule is in a base chain */ 373 | #define BASE_CHAIN (hookmask & (1 << NF_BR_NUMHOOKS)) 374 | /* Clear the bit in the hook_mask that tells if the rule is on a base chain */ 375 | #define CLEAR_BASE_CHAIN_BIT (hookmask &= ~(1 << NF_BR_NUMHOOKS)) 376 | #define PRINT_VERSION printf(PROGNAME" v"PROGVERSION" ("PROGDATE")\n") 377 | #ifndef PROC_SYS_MODPROBE 378 | #define PROC_SYS_MODPROBE "/proc/sys/kernel/modprobe" 379 | #endif 380 | #define ATOMIC_ENV_VARIABLE "EBTABLES_ATOMIC_FILE" 381 | 382 | #ifndef ARRAY_SIZE 383 | # define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 384 | #endif 385 | #endif /* EBTABLES_U_H */ 386 | -------------------------------------------------------------------------------- /include/ethernetdb.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation; either version 2 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 15 | */ 16 | 17 | /* All data returned by the network data base library are supplied in 18 | host order and returned in network order (suitable for use in 19 | system calls). */ 20 | 21 | #ifndef _ETHERNETDB_H 22 | #define _ETHERNETDB_H 1 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | /* Absolute file name for network data base files. */ 29 | #ifndef _PATH_ETHERTYPES 30 | #define _PATH_ETHERTYPES "/etc/ethertypes" 31 | #endif /* _PATH_ETHERTYPES */ 32 | 33 | struct ethertypeent { 34 | char *e_name; /* Official ethernet type name. */ 35 | char **e_aliases; /* Alias list. */ 36 | int e_ethertype; /* Ethernet type number. */ 37 | }; 38 | 39 | /* Open ethertype data base files and mark them as staying open even 40 | after a later search if STAY_OPEN is non-zero. */ 41 | extern void setethertypeent(int __stay_open) __THROW; 42 | 43 | /* Close ethertype data base files and clear `stay open' flag. */ 44 | extern void endethertypeent(void) __THROW; 45 | 46 | /* Get next entry from ethertype data base file. Open data base if 47 | necessary. */ 48 | extern struct ethertypeent *getethertypeent(void) __THROW; 49 | 50 | /* Return entry from ethertype data base for network with NAME. */ 51 | extern struct ethertypeent *getethertypebyname(__const char *__name) 52 | __THROW; 53 | 54 | /* Return entry from ethertype data base which number is PROTO. */ 55 | extern struct ethertypeent *getethertypebynumber(int __ethertype) __THROW; 56 | 57 | 58 | #endif /* ethernetdb.h */ 59 | -------------------------------------------------------------------------------- /include/linux/if_ether.h: -------------------------------------------------------------------------------- 1 | /* 2 | * INET An implementation of the TCP/IP protocol suite for the LINUX 3 | * operating system. INET is implemented using the BSD Socket 4 | * interface as the means of communication with the user level. 5 | * 6 | * Global definitions for the Ethernet IEEE 802.3 interface. 7 | * 8 | * Version: @(#)if_ether.h 1.0.1a 02/08/94 9 | * 10 | * Author: Fred N. van Kempen, 11 | * Donald Becker, 12 | * Alan Cox, 13 | * Steve Whitehouse, 14 | * 15 | * This program is free software; you can redistribute it and/or 16 | * modify it under the terms of the GNU General Public License 17 | * as published by the Free Software Foundation; either version 18 | * 2 of the License, or (at your option) any later version. 19 | */ 20 | 21 | #ifndef _LINUX_IF_ETHER_H 22 | #define _LINUX_IF_ETHER_H 23 | 24 | #include 25 | 26 | /* 27 | * IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble 28 | * and FCS/CRC (frame check sequence). 29 | */ 30 | 31 | #define ETH_ALEN 6 /* Octets in one ethernet addr */ 32 | #define ETH_HLEN 14 /* Total octets in header. */ 33 | #define ETH_ZLEN 60 /* Min. octets in frame sans FCS */ 34 | #define ETH_DATA_LEN 1500 /* Max. octets in payload */ 35 | #define ETH_FRAME_LEN 1514 /* Max. octets in frame sans FCS */ 36 | #define ETH_FCS_LEN 4 /* Octets in the FCS */ 37 | 38 | /* 39 | * These are the defined Ethernet Protocol ID's. 40 | */ 41 | 42 | #define ETH_P_LOOP 0x0060 /* Ethernet Loopback packet */ 43 | #define ETH_P_PUP 0x0200 /* Xerox PUP packet */ 44 | #define ETH_P_PUPAT 0x0201 /* Xerox PUP Addr Trans packet */ 45 | #define ETH_P_IP 0x0800 /* Internet Protocol packet */ 46 | #define ETH_P_X25 0x0805 /* CCITT X.25 */ 47 | #define ETH_P_ARP 0x0806 /* Address Resolution packet */ 48 | #define ETH_P_BPQ 0x08FF /* G8BPQ AX.25 Ethernet Packet [ NOT AN OFFICIALLY REGISTERED ID ] */ 49 | #define ETH_P_IEEEPUP 0x0a00 /* Xerox IEEE802.3 PUP packet */ 50 | #define ETH_P_IEEEPUPAT 0x0a01 /* Xerox IEEE802.3 PUP Addr Trans packet */ 51 | #define ETH_P_DEC 0x6000 /* DEC Assigned proto */ 52 | #define ETH_P_DNA_DL 0x6001 /* DEC DNA Dump/Load */ 53 | #define ETH_P_DNA_RC 0x6002 /* DEC DNA Remote Console */ 54 | #define ETH_P_DNA_RT 0x6003 /* DEC DNA Routing */ 55 | #define ETH_P_LAT 0x6004 /* DEC LAT */ 56 | #define ETH_P_DIAG 0x6005 /* DEC Diagnostics */ 57 | #define ETH_P_CUST 0x6006 /* DEC Customer use */ 58 | #define ETH_P_SCA 0x6007 /* DEC Systems Comms Arch */ 59 | #define ETH_P_TEB 0x6558 /* Trans Ether Bridging */ 60 | #define ETH_P_RARP 0x8035 /* Reverse Addr Res packet */ 61 | #define ETH_P_ATALK 0x809B /* Appletalk DDP */ 62 | #define ETH_P_AARP 0x80F3 /* Appletalk AARP */ 63 | #define ETH_P_8021Q 0x8100 /* 802.1Q VLAN Extended Header */ 64 | #define ETH_P_IPX 0x8137 /* IPX over DIX */ 65 | #define ETH_P_IPV6 0x86DD /* IPv6 over bluebook */ 66 | #define ETH_P_PAUSE 0x8808 /* IEEE Pause frames. See 802.3 31B */ 67 | #define ETH_P_SLOW 0x8809 /* Slow Protocol. See 802.3ad 43B */ 68 | #define ETH_P_WCCP 0x883E /* Web-cache coordination protocol 69 | * defined in draft-wilson-wrec-wccp-v2-00.txt */ 70 | #define ETH_P_PPP_DISC 0x8863 /* PPPoE discovery messages */ 71 | #define ETH_P_PPP_SES 0x8864 /* PPPoE session messages */ 72 | #define ETH_P_MPLS_UC 0x8847 /* MPLS Unicast traffic */ 73 | #define ETH_P_MPLS_MC 0x8848 /* MPLS Multicast traffic */ 74 | #define ETH_P_ATMMPOA 0x884c /* MultiProtocol Over ATM */ 75 | #define ETH_P_LINK_CTL 0x886c /* HPNA, wlan link local tunnel */ 76 | #define ETH_P_ATMFATE 0x8884 /* Frame-based ATM Transport 77 | * over Ethernet 78 | */ 79 | #define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */ 80 | #define ETH_P_AOE 0x88A2 /* ATA over Ethernet */ 81 | #define ETH_P_TIPC 0x88CA /* TIPC */ 82 | #define ETH_P_1588 0x88F7 /* IEEE 1588 Timesync */ 83 | #define ETH_P_FCOE 0x8906 /* Fibre Channel over Ethernet */ 84 | #define ETH_P_FIP 0x8914 /* FCoE Initialization Protocol */ 85 | #define ETH_P_EDSA 0xDADA /* Ethertype DSA [ NOT AN OFFICIALLY REGISTERED ID ] */ 86 | 87 | /* 88 | * Non DIX types. Won't clash for 1500 types. 89 | */ 90 | 91 | #define ETH_P_802_3 0x0001 /* Dummy type for 802.3 frames */ 92 | #define ETH_P_AX25 0x0002 /* Dummy protocol id for AX.25 */ 93 | #define ETH_P_ALL 0x0003 /* Every packet (be careful!!!) */ 94 | #define ETH_P_802_2 0x0004 /* 802.2 frames */ 95 | #define ETH_P_SNAP 0x0005 /* Internal only */ 96 | #define ETH_P_DDCMP 0x0006 /* DEC DDCMP: Internal only */ 97 | #define ETH_P_WAN_PPP 0x0007 /* Dummy type for WAN PPP frames*/ 98 | #define ETH_P_PPP_MP 0x0008 /* Dummy type for PPP MP frames */ 99 | #define ETH_P_LOCALTALK 0x0009 /* Localtalk pseudo type */ 100 | #define ETH_P_CAN 0x000C /* Controller Area Network */ 101 | #define ETH_P_PPPTALK 0x0010 /* Dummy type for Atalk over PPP*/ 102 | #define ETH_P_TR_802_2 0x0011 /* 802.2 frames */ 103 | #define ETH_P_MOBITEX 0x0015 /* Mobitex (kaz@cafe.net) */ 104 | #define ETH_P_CONTROL 0x0016 /* Card specific control frames */ 105 | #define ETH_P_IRDA 0x0017 /* Linux-IrDA */ 106 | #define ETH_P_ECONET 0x0018 /* Acorn Econet */ 107 | #define ETH_P_HDLC 0x0019 /* HDLC frames */ 108 | #define ETH_P_ARCNET 0x001A /* 1A for ArcNet :-) */ 109 | #define ETH_P_DSA 0x001B /* Distributed Switch Arch. */ 110 | #define ETH_P_TRAILER 0x001C /* Trailer switch tagging */ 111 | #define ETH_P_PHONET 0x00F5 /* Nokia Phonet frames */ 112 | #define ETH_P_IEEE802154 0x00F6 /* IEEE802.15.4 frame */ 113 | #define ETH_P_CAIF 0x00F7 /* ST-Ericsson CAIF protocol */ 114 | 115 | /* 116 | * This is an Ethernet frame header. 117 | */ 118 | 119 | struct ethhdr { 120 | unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ 121 | unsigned char h_source[ETH_ALEN]; /* source ether addr */ 122 | __be16 h_proto; /* packet type ID field */ 123 | } __attribute__((packed)); 124 | 125 | 126 | #endif /* _LINUX_IF_ETHER_H */ 127 | -------------------------------------------------------------------------------- /include/linux/netfilter_bridge.h: -------------------------------------------------------------------------------- 1 | #ifndef __LINUX_BRIDGE_NETFILTER_H 2 | #define __LINUX_BRIDGE_NETFILTER_H 3 | 4 | /* bridge-specific defines for netfilter. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | /* Bridge Hooks */ 13 | /* After promisc drops, checksum checks. */ 14 | #define NF_BR_PRE_ROUTING 0 15 | /* If the packet is destined for this box. */ 16 | #define NF_BR_LOCAL_IN 1 17 | /* If the packet is destined for another interface. */ 18 | #define NF_BR_FORWARD 2 19 | /* Packets coming from a local process. */ 20 | #define NF_BR_LOCAL_OUT 3 21 | /* Packets about to hit the wire. */ 22 | #define NF_BR_POST_ROUTING 4 23 | /* Not really a hook, but used for the ebtables broute table */ 24 | #define NF_BR_BROUTING 5 25 | #define NF_BR_NUMHOOKS 6 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /include/linux/netfilter_bridge/ebt_802_3.h: -------------------------------------------------------------------------------- 1 | #ifndef __LINUX_BRIDGE_EBT_802_3_H 2 | #define __LINUX_BRIDGE_EBT_802_3_H 3 | 4 | #include 5 | 6 | #define EBT_802_3_SAP 0x01 7 | #define EBT_802_3_TYPE 0x02 8 | 9 | #define EBT_802_3_MATCH "802_3" 10 | 11 | /* 12 | * If frame has DSAP/SSAP value 0xaa you must check the SNAP type 13 | * to discover what kind of packet we're carrying. 14 | */ 15 | #define CHECK_TYPE 0xaa 16 | 17 | /* 18 | * Control field may be one or two bytes. If the first byte has 19 | * the value 0x03 then the entire length is one byte, otherwise it is two. 20 | * One byte controls are used in Unnumbered Information frames. 21 | * Two byte controls are used in Numbered Information frames. 22 | */ 23 | #define IS_UI 0x03 24 | 25 | #define EBT_802_3_MASK (EBT_802_3_SAP | EBT_802_3_TYPE | EBT_802_3) 26 | 27 | /* ui has one byte ctrl, ni has two */ 28 | struct hdr_ui { 29 | __u8 dsap; 30 | __u8 ssap; 31 | __u8 ctrl; 32 | __u8 orig[3]; 33 | __be16 type; 34 | }; 35 | 36 | struct hdr_ni { 37 | __u8 dsap; 38 | __u8 ssap; 39 | __be16 ctrl; 40 | __u8 orig[3]; 41 | __be16 type; 42 | }; 43 | 44 | struct ebt_802_3_hdr { 45 | __u8 daddr[6]; 46 | __u8 saddr[6]; 47 | __be16 len; 48 | union { 49 | struct hdr_ui ui; 50 | struct hdr_ni ni; 51 | } llc; 52 | }; 53 | 54 | 55 | struct ebt_802_3_info { 56 | __u8 sap; 57 | __be16 type; 58 | __u8 bitmask; 59 | __u8 invflags; 60 | }; 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /include/linux/netfilter_bridge/ebt_among.h: -------------------------------------------------------------------------------- 1 | #ifndef __LINUX_BRIDGE_EBT_AMONG_H 2 | #define __LINUX_BRIDGE_EBT_AMONG_H 3 | 4 | #include 5 | 6 | #define EBT_AMONG_DST 0x01 7 | #define EBT_AMONG_SRC 0x02 8 | 9 | /* Grzegorz Borowiak 2003 10 | * 11 | * Write-once-read-many hash table, used for checking if a given 12 | * MAC address belongs to a set or not and possibly for checking 13 | * if it is related with a given IPv4 address. 14 | * 15 | * The hash value of an address is its last byte. 16 | * 17 | * In real-world ethernet addresses, values of the last byte are 18 | * evenly distributed and there is no need to consider other bytes. 19 | * It would only slow the routines down. 20 | * 21 | * For MAC address comparison speedup reasons, we introduce a trick. 22 | * MAC address is mapped onto an array of two 32-bit integers. 23 | * This pair of integers is compared with MAC addresses in the 24 | * hash table, which are stored also in form of pairs of integers 25 | * (in `cmp' array). This is quick as it requires only two elementary 26 | * number comparisons in worst case. Further, we take advantage of 27 | * fact that entropy of 3 last bytes of address is larger than entropy 28 | * of 3 first bytes. So first we compare 4 last bytes of addresses and 29 | * if they are the same we compare 2 first. 30 | * 31 | * Yes, it is a memory overhead, but in 2003 AD, who cares? 32 | */ 33 | 34 | struct ebt_mac_wormhash_tuple { 35 | __u32 cmp[2]; 36 | __be32 ip; 37 | }; 38 | 39 | struct ebt_mac_wormhash { 40 | int table[257]; 41 | int poolsize; 42 | struct ebt_mac_wormhash_tuple pool[0]; 43 | }; 44 | 45 | #define ebt_mac_wormhash_size(x) ((x) ? sizeof(struct ebt_mac_wormhash) \ 46 | + (x)->poolsize * sizeof(struct ebt_mac_wormhash_tuple) : 0) 47 | 48 | struct ebt_among_info { 49 | int wh_dst_ofs; 50 | int wh_src_ofs; 51 | int bitmask; 52 | }; 53 | 54 | #define EBT_AMONG_DST_NEG 0x1 55 | #define EBT_AMONG_SRC_NEG 0x2 56 | 57 | #define ebt_among_wh_dst(x) ((x)->wh_dst_ofs ? \ 58 | (struct ebt_mac_wormhash*)((char*)(x) + (x)->wh_dst_ofs) : NULL) 59 | #define ebt_among_wh_src(x) ((x)->wh_src_ofs ? \ 60 | (struct ebt_mac_wormhash*)((char*)(x) + (x)->wh_src_ofs) : NULL) 61 | 62 | #define EBT_AMONG_MATCH "among" 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /include/linux/netfilter_bridge/ebt_arp.h: -------------------------------------------------------------------------------- 1 | #ifndef __LINUX_BRIDGE_EBT_ARP_H 2 | #define __LINUX_BRIDGE_EBT_ARP_H 3 | 4 | #include 5 | 6 | #define EBT_ARP_OPCODE 0x01 7 | #define EBT_ARP_HTYPE 0x02 8 | #define EBT_ARP_PTYPE 0x04 9 | #define EBT_ARP_SRC_IP 0x08 10 | #define EBT_ARP_DST_IP 0x10 11 | #define EBT_ARP_SRC_MAC 0x20 12 | #define EBT_ARP_DST_MAC 0x40 13 | #define EBT_ARP_GRAT 0x80 14 | #define EBT_ARP_MASK (EBT_ARP_OPCODE | EBT_ARP_HTYPE | EBT_ARP_PTYPE | \ 15 | EBT_ARP_SRC_IP | EBT_ARP_DST_IP | EBT_ARP_SRC_MAC | EBT_ARP_DST_MAC | \ 16 | EBT_ARP_GRAT) 17 | #define EBT_ARP_MATCH "arp" 18 | 19 | struct ebt_arp_info 20 | { 21 | __be16 htype; 22 | __be16 ptype; 23 | __be16 opcode; 24 | __be32 saddr; 25 | __be32 smsk; 26 | __be32 daddr; 27 | __be32 dmsk; 28 | unsigned char smaddr[ETH_ALEN]; 29 | unsigned char smmsk[ETH_ALEN]; 30 | unsigned char dmaddr[ETH_ALEN]; 31 | unsigned char dmmsk[ETH_ALEN]; 32 | __u8 bitmask; 33 | __u8 invflags; 34 | }; 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /include/linux/netfilter_bridge/ebt_arpreply.h: -------------------------------------------------------------------------------- 1 | #ifndef __LINUX_BRIDGE_EBT_ARPREPLY_H 2 | #define __LINUX_BRIDGE_EBT_ARPREPLY_H 3 | 4 | struct ebt_arpreply_info { 5 | unsigned char mac[ETH_ALEN]; 6 | int target; 7 | }; 8 | #define EBT_ARPREPLY_TARGET "arpreply" 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /include/linux/netfilter_bridge/ebt_ip.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ebt_ip 3 | * 4 | * Authors: 5 | * Bart De Schuymer 6 | * 7 | * April, 2002 8 | * 9 | * Changes: 10 | * added ip-sport and ip-dport 11 | * Innominate Security Technologies AG 12 | * September, 2002 13 | */ 14 | 15 | #ifndef __LINUX_BRIDGE_EBT_IP_H 16 | #define __LINUX_BRIDGE_EBT_IP_H 17 | 18 | #include 19 | 20 | #define EBT_IP_SOURCE 0x01 21 | #define EBT_IP_DEST 0x02 22 | #define EBT_IP_TOS 0x04 23 | #define EBT_IP_PROTO 0x08 24 | #define EBT_IP_SPORT 0x10 25 | #define EBT_IP_DPORT 0x20 26 | #define EBT_IP_MASK (EBT_IP_SOURCE | EBT_IP_DEST | EBT_IP_TOS | EBT_IP_PROTO |\ 27 | EBT_IP_SPORT | EBT_IP_DPORT ) 28 | #define EBT_IP_MATCH "ip" 29 | 30 | /* the same values are used for the invflags */ 31 | struct ebt_ip_info { 32 | __be32 saddr; 33 | __be32 daddr; 34 | __be32 smsk; 35 | __be32 dmsk; 36 | __u8 tos; 37 | __u8 protocol; 38 | __u8 bitmask; 39 | __u8 invflags; 40 | __u16 sport[2]; 41 | __u16 dport[2]; 42 | }; 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /include/linux/netfilter_bridge/ebt_ip6.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ebt_ip6 3 | * 4 | * Authors: 5 | * Kuo-Lang Tseng 6 | * Manohar Castelino 7 | * 8 | * Jan 11, 2008 9 | * 10 | */ 11 | 12 | #ifndef __LINUX_BRIDGE_EBT_IP6_H 13 | #define __LINUX_BRIDGE_EBT_IP6_H 14 | 15 | #include 16 | 17 | #define EBT_IP6_SOURCE 0x01 18 | #define EBT_IP6_DEST 0x02 19 | #define EBT_IP6_TCLASS 0x04 20 | #define EBT_IP6_PROTO 0x08 21 | #define EBT_IP6_SPORT 0x10 22 | #define EBT_IP6_DPORT 0x20 23 | #define EBT_IP6_ICMP6 0x40 24 | 25 | #define EBT_IP6_MASK (EBT_IP6_SOURCE | EBT_IP6_DEST | EBT_IP6_TCLASS |\ 26 | EBT_IP6_PROTO | EBT_IP6_SPORT | EBT_IP6_DPORT | \ 27 | EBT_IP6_ICMP6) 28 | #define EBT_IP6_MATCH "ip6" 29 | 30 | /* the same values are used for the invflags */ 31 | struct ebt_ip6_info { 32 | struct in6_addr saddr; 33 | struct in6_addr daddr; 34 | struct in6_addr smsk; 35 | struct in6_addr dmsk; 36 | __u8 tclass; 37 | __u8 protocol; 38 | __u8 bitmask; 39 | __u8 invflags; 40 | union { 41 | __u16 sport[2]; 42 | __u8 icmpv6_type[2]; 43 | }; 44 | union { 45 | __u16 dport[2]; 46 | __u8 icmpv6_code[2]; 47 | }; 48 | }; 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /include/linux/netfilter_bridge/ebt_limit.h: -------------------------------------------------------------------------------- 1 | #ifndef __LINUX_BRIDGE_EBT_LIMIT_H 2 | #define __LINUX_BRIDGE_EBT_LIMIT_H 3 | 4 | #include 5 | 6 | #define EBT_LIMIT_MATCH "limit" 7 | 8 | /* timings are in milliseconds. */ 9 | #define EBT_LIMIT_SCALE 10000 10 | 11 | /* 1/10,000 sec period => max of 10,000/sec. Min rate is then 429490 12 | seconds, or one every 59 hours. */ 13 | 14 | struct ebt_limit_info { 15 | __u32 avg; /* Average secs between packets * scale */ 16 | __u32 burst; /* Period multiplier for upper limit. */ 17 | 18 | /* Used internally by the kernel */ 19 | unsigned long prev; 20 | __u32 credit; 21 | __u32 credit_cap, cost; 22 | }; 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /include/linux/netfilter_bridge/ebt_log.h: -------------------------------------------------------------------------------- 1 | #ifndef __LINUX_BRIDGE_EBT_LOG_H 2 | #define __LINUX_BRIDGE_EBT_LOG_H 3 | 4 | #include 5 | 6 | #define EBT_LOG_IP 0x01 /* if the frame is made by ip, log the ip information */ 7 | #define EBT_LOG_ARP 0x02 8 | #define EBT_LOG_NFLOG 0x04 9 | #define EBT_LOG_IP6 0x08 10 | #define EBT_LOG_MASK (EBT_LOG_IP | EBT_LOG_ARP | EBT_LOG_IP6) 11 | #define EBT_LOG_PREFIX_SIZE 30 12 | #define EBT_LOG_WATCHER "log" 13 | 14 | struct ebt_log_info { 15 | __u8 loglevel; 16 | __u8 prefix[EBT_LOG_PREFIX_SIZE]; 17 | __u32 bitmask; 18 | }; 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /include/linux/netfilter_bridge/ebt_mark_m.h: -------------------------------------------------------------------------------- 1 | #ifndef __LINUX_BRIDGE_EBT_MARK_M_H 2 | #define __LINUX_BRIDGE_EBT_MARK_M_H 3 | 4 | #include 5 | 6 | #define EBT_MARK_AND 0x01 7 | #define EBT_MARK_OR 0x02 8 | #define EBT_MARK_MASK (EBT_MARK_AND | EBT_MARK_OR) 9 | struct ebt_mark_m_info { 10 | unsigned long mark, mask; 11 | __u8 invert; 12 | __u8 bitmask; 13 | }; 14 | #define EBT_MARK_MATCH "mark_m" 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /include/linux/netfilter_bridge/ebt_mark_t.h: -------------------------------------------------------------------------------- 1 | #ifndef __LINUX_BRIDGE_EBT_MARK_T_H 2 | #define __LINUX_BRIDGE_EBT_MARK_T_H 3 | 4 | /* The target member is reused for adding new actions, the 5 | * value of the real target is -1 to -NUM_STANDARD_TARGETS. 6 | * For backward compatibility, the 4 lsb (2 would be enough, 7 | * but let's play it safe) are kept to designate this target. 8 | * The remaining bits designate the action. By making the set 9 | * action 0xfffffff0, the result will look ok for older 10 | * versions. [September 2006] */ 11 | #define MARK_SET_VALUE (0xfffffff0) 12 | #define MARK_OR_VALUE (0xffffffe0) 13 | #define MARK_AND_VALUE (0xffffffd0) 14 | #define MARK_XOR_VALUE (0xffffffc0) 15 | 16 | struct ebt_mark_t_info { 17 | unsigned long mark; 18 | /* EBT_ACCEPT, EBT_DROP, EBT_CONTINUE or EBT_RETURN */ 19 | int target; 20 | }; 21 | #define EBT_MARK_TARGET "mark" 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /include/linux/netfilter_bridge/ebt_nat.h: -------------------------------------------------------------------------------- 1 | #ifndef __LINUX_BRIDGE_EBT_NAT_H 2 | #define __LINUX_BRIDGE_EBT_NAT_H 3 | 4 | #define NAT_ARP_BIT (0x00000010) 5 | struct ebt_nat_info { 6 | unsigned char mac[ETH_ALEN]; 7 | /* EBT_ACCEPT, EBT_DROP, EBT_CONTINUE or EBT_RETURN */ 8 | int target; 9 | }; 10 | #define EBT_SNAT_TARGET "snat" 11 | #define EBT_DNAT_TARGET "dnat" 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /include/linux/netfilter_bridge/ebt_nflog.h: -------------------------------------------------------------------------------- 1 | #ifndef __LINUX_BRIDGE_EBT_NFLOG_H 2 | #define __LINUX_BRIDGE_EBT_NFLOG_H 3 | 4 | #include 5 | 6 | #define EBT_NFLOG_MASK 0x0 7 | 8 | #define EBT_NFLOG_PREFIX_SIZE 64 9 | #define EBT_NFLOG_WATCHER "nflog" 10 | 11 | #define EBT_NFLOG_DEFAULT_GROUP 0x1 12 | #define EBT_NFLOG_DEFAULT_THRESHOLD 1 13 | 14 | struct ebt_nflog_info { 15 | __u32 len; 16 | __u16 group; 17 | __u16 threshold; 18 | __u16 flags; 19 | __u16 pad; 20 | char prefix[EBT_NFLOG_PREFIX_SIZE]; 21 | }; 22 | 23 | #endif /* __LINUX_BRIDGE_EBT_NFLOG_H */ 24 | -------------------------------------------------------------------------------- /include/linux/netfilter_bridge/ebt_pkttype.h: -------------------------------------------------------------------------------- 1 | #ifndef __LINUX_BRIDGE_EBT_PKTTYPE_H 2 | #define __LINUX_BRIDGE_EBT_PKTTYPE_H 3 | 4 | #include 5 | 6 | struct ebt_pkttype_info { 7 | __u8 pkt_type; 8 | __u8 invert; 9 | }; 10 | #define EBT_PKTTYPE_MATCH "pkttype" 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /include/linux/netfilter_bridge/ebt_redirect.h: -------------------------------------------------------------------------------- 1 | #ifndef __LINUX_BRIDGE_EBT_REDIRECT_H 2 | #define __LINUX_BRIDGE_EBT_REDIRECT_H 3 | 4 | struct ebt_redirect_info { 5 | /* EBT_ACCEPT, EBT_DROP, EBT_CONTINUE or EBT_RETURN */ 6 | int target; 7 | }; 8 | #define EBT_REDIRECT_TARGET "redirect" 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /include/linux/netfilter_bridge/ebt_stp.h: -------------------------------------------------------------------------------- 1 | #ifndef __LINUX_BRIDGE_EBT_STP_H 2 | #define __LINUX_BRIDGE_EBT_STP_H 3 | 4 | #include 5 | 6 | #define EBT_STP_TYPE 0x0001 7 | 8 | #define EBT_STP_FLAGS 0x0002 9 | #define EBT_STP_ROOTPRIO 0x0004 10 | #define EBT_STP_ROOTADDR 0x0008 11 | #define EBT_STP_ROOTCOST 0x0010 12 | #define EBT_STP_SENDERPRIO 0x0020 13 | #define EBT_STP_SENDERADDR 0x0040 14 | #define EBT_STP_PORT 0x0080 15 | #define EBT_STP_MSGAGE 0x0100 16 | #define EBT_STP_MAXAGE 0x0200 17 | #define EBT_STP_HELLOTIME 0x0400 18 | #define EBT_STP_FWDD 0x0800 19 | 20 | #define EBT_STP_MASK 0x0fff 21 | #define EBT_STP_CONFIG_MASK 0x0ffe 22 | 23 | #define EBT_STP_MATCH "stp" 24 | 25 | struct ebt_stp_config_info { 26 | __u8 flags; 27 | __u16 root_priol, root_priou; 28 | char root_addr[6], root_addrmsk[6]; 29 | __u32 root_costl, root_costu; 30 | __u16 sender_priol, sender_priou; 31 | char sender_addr[6], sender_addrmsk[6]; 32 | __u16 portl, portu; 33 | __u16 msg_agel, msg_ageu; 34 | __u16 max_agel, max_ageu; 35 | __u16 hello_timel, hello_timeu; 36 | __u16 forward_delayl, forward_delayu; 37 | }; 38 | 39 | struct ebt_stp_info { 40 | __u8 type; 41 | struct ebt_stp_config_info config; 42 | __u16 bitmask; 43 | __u16 invflags; 44 | }; 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /include/linux/netfilter_bridge/ebt_ulog.h: -------------------------------------------------------------------------------- 1 | #ifndef _EBT_ULOG_H 2 | #define _EBT_ULOG_H 3 | 4 | #include 5 | 6 | #define EBT_ULOG_DEFAULT_NLGROUP 0 7 | #define EBT_ULOG_DEFAULT_QTHRESHOLD 1 8 | #define EBT_ULOG_MAXNLGROUPS 32 /* hardcoded netlink max */ 9 | #define EBT_ULOG_PREFIX_LEN 32 10 | #define EBT_ULOG_MAX_QLEN 50 11 | #define EBT_ULOG_WATCHER "ulog" 12 | #define EBT_ULOG_VERSION 1 13 | 14 | struct ebt_ulog_info { 15 | __u32 nlgroup; 16 | unsigned int cprange; 17 | unsigned int qthreshold; 18 | char prefix[EBT_ULOG_PREFIX_LEN]; 19 | }; 20 | 21 | typedef struct ebt_ulog_packet_msg { 22 | int version; 23 | char indev[IFNAMSIZ]; 24 | char outdev[IFNAMSIZ]; 25 | char physindev[IFNAMSIZ]; 26 | char physoutdev[IFNAMSIZ]; 27 | char prefix[EBT_ULOG_PREFIX_LEN]; 28 | struct timeval stamp; 29 | unsigned long mark; 30 | unsigned int hook; 31 | size_t data_len; 32 | /* The complete packet, including Ethernet header and perhaps 33 | * the VLAN header is appended */ 34 | unsigned char data[0] __attribute__ 35 | ((aligned (__alignof__(struct ebt_ulog_info)))); 36 | } ebt_ulog_packet_msg_t; 37 | 38 | #endif /* _EBT_ULOG_H */ 39 | -------------------------------------------------------------------------------- /include/linux/netfilter_bridge/ebt_vlan.h: -------------------------------------------------------------------------------- 1 | #ifndef __LINUX_BRIDGE_EBT_VLAN_H 2 | #define __LINUX_BRIDGE_EBT_VLAN_H 3 | 4 | #include 5 | 6 | #define EBT_VLAN_ID 0x01 7 | #define EBT_VLAN_PRIO 0x02 8 | #define EBT_VLAN_ENCAP 0x04 9 | #define EBT_VLAN_MASK (EBT_VLAN_ID | EBT_VLAN_PRIO | EBT_VLAN_ENCAP) 10 | #define EBT_VLAN_MATCH "vlan" 11 | 12 | struct ebt_vlan_info { 13 | __u16 id; /* VLAN ID {1-4095} */ 14 | __u8 prio; /* VLAN User Priority {0-7} */ 15 | __be16 encap; /* VLAN Encapsulated frame code {0-65535} */ 16 | __u8 bitmask; /* Args bitmask bit 1=1 - ID arg, 17 | bit 2=1 User-Priority arg, bit 3=1 encap*/ 18 | __u8 invflags; /* Inverse bitmask bit 1=1 - inversed ID arg, 19 | bit 2=1 - inversed Pirority arg */ 20 | }; 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /include/linux/netfilter_bridge/ebtables.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ebtables 3 | * 4 | * Authors: 5 | * Bart De Schuymer 6 | * 7 | * ebtables.c,v 2.0, April, 2002 8 | * 9 | * This code is stongly inspired on the iptables code which is 10 | * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling 11 | */ 12 | 13 | /* Local copy of the kernel file, needed for Sparc64 support */ 14 | #ifndef __LINUX_BRIDGE_EFF_H 15 | #define __LINUX_BRIDGE_EFF_H 16 | #include 17 | #include 18 | #include 19 | 20 | #define EBT_TABLE_MAXNAMELEN 32 21 | #define EBT_CHAIN_MAXNAMELEN EBT_TABLE_MAXNAMELEN 22 | #define EBT_FUNCTION_MAXNAMELEN EBT_TABLE_MAXNAMELEN 23 | 24 | /* verdicts >0 are "branches" */ 25 | #define EBT_ACCEPT -1 26 | #define EBT_DROP -2 27 | #define EBT_CONTINUE -3 28 | #define EBT_RETURN -4 29 | #define NUM_STANDARD_TARGETS 4 30 | /* ebtables target modules store the verdict inside an int. We can 31 | * reclaim a part of this int for backwards compatible extensions. 32 | * The 4 lsb are more than enough to store the verdict. */ 33 | #define EBT_VERDICT_BITS 0x0000000F 34 | 35 | struct ebt_counter 36 | { 37 | uint64_t pcnt; 38 | uint64_t bcnt; 39 | }; 40 | 41 | struct ebt_replace 42 | { 43 | char name[EBT_TABLE_MAXNAMELEN]; 44 | unsigned int valid_hooks; 45 | /* nr of rules in the table */ 46 | unsigned int nentries; 47 | /* total size of the entries */ 48 | unsigned int entries_size; 49 | /* start of the chains */ 50 | #ifdef KERNEL_64_USERSPACE_32 51 | uint64_t hook_entry[NF_BR_NUMHOOKS]; 52 | #else 53 | struct ebt_entries *hook_entry[NF_BR_NUMHOOKS]; 54 | #endif 55 | /* nr of counters userspace expects back */ 56 | unsigned int num_counters; 57 | /* where the kernel will put the old counters */ 58 | #ifdef KERNEL_64_USERSPACE_32 59 | uint64_t counters; 60 | uint64_t entries; 61 | #else 62 | struct ebt_counter *counters; 63 | char *entries; 64 | #endif 65 | }; 66 | 67 | struct ebt_entries { 68 | /* this field is always set to zero 69 | * See EBT_ENTRY_OR_ENTRIES. 70 | * Must be same size as ebt_entry.bitmask */ 71 | unsigned int distinguisher; 72 | /* the chain name */ 73 | char name[EBT_CHAIN_MAXNAMELEN]; 74 | /* counter offset for this chain */ 75 | unsigned int counter_offset; 76 | /* one standard (accept, drop, return) per hook */ 77 | int policy; 78 | /* nr. of entries */ 79 | unsigned int nentries; 80 | /* entry list */ 81 | char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); 82 | }; 83 | 84 | /* used for the bitmask of struct ebt_entry */ 85 | 86 | /* This is a hack to make a difference between an ebt_entry struct and an 87 | * ebt_entries struct when traversing the entries from start to end. 88 | * Using this simplifies the code alot, while still being able to use 89 | * ebt_entries. 90 | * Contrary, iptables doesn't use something like ebt_entries and therefore uses 91 | * different techniques for naming the policy and such. So, iptables doesn't 92 | * need a hack like this. 93 | */ 94 | #define EBT_ENTRY_OR_ENTRIES 0x01 95 | /* these are the normal masks */ 96 | #define EBT_NOPROTO 0x02 97 | #define EBT_802_3 0x04 98 | #define EBT_SOURCEMAC 0x08 99 | #define EBT_DESTMAC 0x10 100 | #define EBT_F_MASK (EBT_NOPROTO | EBT_802_3 | EBT_SOURCEMAC | EBT_DESTMAC \ 101 | | EBT_ENTRY_OR_ENTRIES) 102 | 103 | #define EBT_IPROTO 0x01 104 | #define EBT_IIN 0x02 105 | #define EBT_IOUT 0x04 106 | #define EBT_ISOURCE 0x8 107 | #define EBT_IDEST 0x10 108 | #define EBT_ILOGICALIN 0x20 109 | #define EBT_ILOGICALOUT 0x40 110 | #define EBT_INV_MASK (EBT_IPROTO | EBT_IIN | EBT_IOUT | EBT_ILOGICALIN \ 111 | | EBT_ILOGICALOUT | EBT_ISOURCE | EBT_IDEST) 112 | 113 | struct ebt_entry_match 114 | { 115 | union { 116 | char name[EBT_FUNCTION_MAXNAMELEN]; 117 | struct ebt_match *match; 118 | } u; 119 | /* size of data */ 120 | unsigned int match_size; 121 | #ifdef KERNEL_64_USERSPACE_32 122 | unsigned int pad; 123 | #endif 124 | unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); 125 | }; 126 | 127 | struct ebt_entry_watcher 128 | { 129 | union { 130 | char name[EBT_FUNCTION_MAXNAMELEN]; 131 | struct ebt_watcher *watcher; 132 | } u; 133 | /* size of data */ 134 | unsigned int watcher_size; 135 | #ifdef KERNEL_64_USERSPACE_32 136 | unsigned int pad; 137 | #endif 138 | unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); 139 | }; 140 | 141 | struct ebt_entry_target 142 | { 143 | union { 144 | char name[EBT_FUNCTION_MAXNAMELEN]; 145 | struct ebt_target *target; 146 | } u; 147 | /* size of data */ 148 | unsigned int target_size; 149 | #ifdef KERNEL_64_USERSPACE_32 150 | unsigned int pad; 151 | #endif 152 | unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); 153 | }; 154 | 155 | #define EBT_STANDARD_TARGET "standard" 156 | struct ebt_standard_target 157 | { 158 | struct ebt_entry_target target; 159 | int verdict; 160 | #ifdef KERNEL_64_USERSPACE_32 161 | unsigned int pad; 162 | #endif 163 | }; 164 | 165 | /* one entry */ 166 | struct ebt_entry { 167 | /* this needs to be the first field */ 168 | unsigned int bitmask; 169 | unsigned int invflags; 170 | uint16_t ethproto; 171 | /* the physical in-dev */ 172 | char in[IFNAMSIZ]; 173 | /* the logical in-dev */ 174 | char logical_in[IFNAMSIZ]; 175 | /* the physical out-dev */ 176 | char out[IFNAMSIZ]; 177 | /* the logical out-dev */ 178 | char logical_out[IFNAMSIZ]; 179 | unsigned char sourcemac[ETH_ALEN]; 180 | unsigned char sourcemsk[ETH_ALEN]; 181 | unsigned char destmac[ETH_ALEN]; 182 | unsigned char destmsk[ETH_ALEN]; 183 | /* sizeof ebt_entry + matches */ 184 | unsigned int watchers_offset; 185 | /* sizeof ebt_entry + matches + watchers */ 186 | unsigned int target_offset; 187 | /* sizeof ebt_entry + matches + watchers + target */ 188 | unsigned int next_offset; 189 | unsigned char elems[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); 190 | }; 191 | 192 | /* {g,s}etsockopt numbers */ 193 | #define EBT_BASE_CTL 128 194 | 195 | #define EBT_SO_SET_ENTRIES (EBT_BASE_CTL) 196 | #define EBT_SO_SET_COUNTERS (EBT_SO_SET_ENTRIES+1) 197 | #define EBT_SO_SET_MAX (EBT_SO_SET_COUNTERS+1) 198 | 199 | #define EBT_SO_GET_INFO (EBT_BASE_CTL) 200 | #define EBT_SO_GET_ENTRIES (EBT_SO_GET_INFO+1) 201 | #define EBT_SO_GET_INIT_INFO (EBT_SO_GET_ENTRIES+1) 202 | #define EBT_SO_GET_INIT_ENTRIES (EBT_SO_GET_INIT_INFO+1) 203 | #define EBT_SO_GET_MAX (EBT_SO_GET_INIT_ENTRIES+1) 204 | 205 | /* blatently stolen from ip_tables.h 206 | * fn returns 0 to continue iteration */ 207 | #define EBT_MATCH_ITERATE(e, fn, args...) \ 208 | ({ \ 209 | unsigned int __i; \ 210 | int __ret = 0; \ 211 | struct ebt_entry_match *__match; \ 212 | \ 213 | for (__i = sizeof(struct ebt_entry); \ 214 | __i < (e)->watchers_offset; \ 215 | __i += __match->match_size + \ 216 | sizeof(struct ebt_entry_match)) { \ 217 | __match = (void *)(e) + __i; \ 218 | \ 219 | __ret = fn(__match , ## args); \ 220 | if (__ret != 0) \ 221 | break; \ 222 | } \ 223 | if (__ret == 0) { \ 224 | if (__i != (e)->watchers_offset) \ 225 | __ret = -EINVAL; \ 226 | } \ 227 | __ret; \ 228 | }) 229 | 230 | #define EBT_WATCHER_ITERATE(e, fn, args...) \ 231 | ({ \ 232 | unsigned int __i; \ 233 | int __ret = 0; \ 234 | struct ebt_entry_watcher *__watcher; \ 235 | \ 236 | for (__i = e->watchers_offset; \ 237 | __i < (e)->target_offset; \ 238 | __i += __watcher->watcher_size + \ 239 | sizeof(struct ebt_entry_watcher)) { \ 240 | __watcher = (void *)(e) + __i; \ 241 | \ 242 | __ret = fn(__watcher , ## args); \ 243 | if (__ret != 0) \ 244 | break; \ 245 | } \ 246 | if (__ret == 0) { \ 247 | if (__i != (e)->target_offset) \ 248 | __ret = -EINVAL; \ 249 | } \ 250 | __ret; \ 251 | }) 252 | 253 | #define EBT_ENTRY_ITERATE(entries, size, fn, args...) \ 254 | ({ \ 255 | unsigned int __i; \ 256 | int __ret = 0; \ 257 | struct ebt_entry *__entry; \ 258 | \ 259 | for (__i = 0; __i < (size);) { \ 260 | __entry = (void *)(entries) + __i; \ 261 | __ret = fn(__entry , ## args); \ 262 | if (__ret != 0) \ 263 | break; \ 264 | if (__entry->bitmask != 0) \ 265 | __i += __entry->next_offset; \ 266 | else \ 267 | __i += sizeof(struct ebt_entries); \ 268 | } \ 269 | if (__ret == 0) { \ 270 | if (__i != (size)) \ 271 | __ret = -EINVAL; \ 272 | } \ 273 | __ret; \ 274 | }) 275 | 276 | #endif 277 | -------------------------------------------------------------------------------- /include/linux/types.h: -------------------------------------------------------------------------------- 1 | #ifndef _LINUX_TYPES_H 2 | #define _LINUX_TYPES_H 3 | 4 | #include 5 | 6 | #ifndef __ASSEMBLY__ 7 | 8 | #include 9 | 10 | 11 | /* 12 | * Below are truly Linux-specific types that should never collide with 13 | * any application/library that wants linux/types.h. 14 | */ 15 | 16 | #ifdef __CHECKER__ 17 | #define __bitwise__ __attribute__((bitwise)) 18 | #else 19 | #define __bitwise__ 20 | #endif 21 | #ifdef __CHECK_ENDIAN__ 22 | #define __bitwise __bitwise__ 23 | #else 24 | #define __bitwise 25 | #endif 26 | 27 | typedef __u16 __bitwise __le16; 28 | typedef __u16 __bitwise __be16; 29 | typedef __u32 __bitwise __le32; 30 | typedef __u32 __bitwise __be32; 31 | typedef __u64 __bitwise __le64; 32 | typedef __u64 __bitwise __be64; 33 | 34 | typedef __u16 __bitwise __sum16; 35 | typedef __u32 __bitwise __wsum; 36 | 37 | /* 38 | * aligned_u64 should be used in defining kernel<->userspace ABIs to avoid 39 | * common 32/64-bit compat problems. 40 | * 64-bit values align to 4-byte boundaries on x86_32 (and possibly other 41 | * architectures) and to 8-byte boundaries on 64-bit architetures. The new 42 | * aligned_64 type enforces 8-byte alignment so that structs containing 43 | * aligned_64 values have the same alignment on 32-bit and 64-bit architectures. 44 | * No conversions are necessary between 32-bit user-space and a 64-bit kernel. 45 | */ 46 | #define __aligned_u64 __u64 __attribute__((aligned(8))) 47 | #define __aligned_be64 __be64 __attribute__((aligned(8))) 48 | #define __aligned_le64 __le64 __attribute__((aligned(8))) 49 | 50 | #endif /* __ASSEMBLY__ */ 51 | #endif /* _LINUX_TYPES_H */ 52 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | cffi>=0.5.0 2 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import os 2 | import subprocess 3 | from setuptools import setup 4 | 5 | """python-ebtables setup script""" 6 | 7 | import ebtables 8 | 9 | long_description = """Ebtables is used for Ethernet bridge frame table 10 | administration on Linux. Python-ebtables is a simple Python binding for 11 | Ebtables.""" 12 | 13 | try: 14 | create_rst = True 15 | if os.path.exists('README.rst'): 16 | s1 = os.stat('README.md') 17 | s2 = os.stat('README.rst') 18 | if s1.st_mtime <= s2.st_mtime: 19 | create_rst = False 20 | if create_rst: 21 | rc = subprocess.call(['pandoc', 22 | '-o', 'README.rst', 23 | '-f', 'markdown', 24 | '-t', 'rst', 25 | 'README.md'], 26 | shell=False, 27 | stdout=subprocess.PIPE) 28 | if rc == 0: 29 | with open('README.rst') as f: 30 | long_description = f.read() 31 | except: 32 | pass 33 | 34 | 35 | setup( 36 | name='ebtables', 37 | version=ebtables.__version__, 38 | author='Vilmos Nebehaj', 39 | author_email='v.nebehaj@gmail.com', 40 | url='https://github.com/ldx/python-ebtables', 41 | description='Linux Ebtables bindings', 42 | long_description=long_description, 43 | py_modules=['ebtables'], 44 | setup_requires=['cffi'], 45 | install_requires=['cffi'], 46 | ext_modules=[ebtables.ffi.verifier.get_extension()], 47 | zip_safe=False, 48 | ) 49 | -------------------------------------------------------------------------------- /test.py: -------------------------------------------------------------------------------- 1 | import ebtables 2 | import functools 3 | import pytest 4 | import random 5 | import string 6 | 7 | 8 | # A few basic rules to test in all three tables. 9 | TEST_RULES = [ 10 | '-p ARP -j ACCEPT', 11 | '-p IPv4 -j ACCEPT', 12 | '-p Length -j ACCEPT', 13 | '-p IPv4 -i eth0 --ip-dst 172.16.1.1 -j ACCEPT', 14 | '-p ARP -d 11:22:33:44:55:66 -o eth0 -j ACCEPT', 15 | '-p ARP -i eth0 --arp-ip-dst 172.16.1.1 -j ACCEPT', 16 | '-p IPv4 --log-level info --log-prefix FW --log-ip --log-arp -j ACCEPT', 17 | '-p 802_1Q --vlan-id 1 -j mark --mark-set 0x1 --mark-target ACCEPT'] 18 | 19 | 20 | @pytest.fixture(params=TEST_RULES) 21 | def rule(request): 22 | return request.param 23 | 24 | 25 | @pytest.fixture 26 | def chain(): 27 | rnd = ''.join(random.choice(string.ascii_uppercase + string.digits) 28 | for _ in range(16)) 29 | chain = 'test_chain_%s' % rnd 30 | return chain 31 | 32 | 33 | @pytest.fixture(params=['filter', 'nat', 'broute']) 34 | def table(request, chain): 35 | t = request.param 36 | cmd = functools.partial(ebtables.cmd, t) 37 | 38 | def remove(): 39 | cmd('-F %s' % chain) 40 | cmd('-X %s' % chain) 41 | request.addfinalizer(remove) 42 | 43 | rc, out, err = cmd('-L %s' % chain) 44 | if rc == 0: 45 | cmd('-F %s' % chain) 46 | cmd('-X %s' % chain) 47 | rc, out, err = cmd('-N %s' % chain) 48 | assert rc == 0, "Error removing %s; out: %s; err: %s" % (chain, out, err) 49 | return cmd 50 | 51 | 52 | def _test_add(table, chain, rule, cmd): 53 | rc, out, err = table('%s %s %s' % (cmd, chain, rule)) 54 | assert rc == 0, "Error adding %s; out: %s; err: %s" % (rule, out, err) 55 | rc, out, err = table('-L %s' % chain) 56 | assert rc == 0, "Error listing %s; out: %s; err: %s" % (chain, out, err) 57 | for line in out.split('\n'): 58 | if line.strip().replace('"', '').startswith(rule): 59 | break 60 | else: 61 | assert 0, "Missing rule '%s'; output: %s" % (rule, out) 62 | rc, out, err = table('-D %s %s' % (chain, rule)) 63 | assert rc == 0, "Error removing %s; out: %s; err: %s" % (rule, out, err) 64 | 65 | 66 | # 67 | # Test inserting and then removing a rule. 68 | # 69 | def test_insert(table, chain, rule): 70 | _test_add(table, chain, rule, '-I') 71 | 72 | 73 | # 74 | # Test appending and then removing a rule. 75 | # 76 | def test_append(table, chain, rule): 77 | _test_add(table, chain, rule, '-A') 78 | --------------------------------------------------------------------------------