├── userspace ├── Android.mk └── ebtables2 │ └── Android.mk ├── THANKS ├── ebtables-standalone.c ├── extensions ├── ebtable_broute.c ├── ebtable_nat.c ├── ebtable_filter.c ├── Makefile ├── ebt_standard.c ├── ebt_redirect.c ├── ebt_pkttype.c ├── ebt_mark_m.c ├── ebt_802_3.c ├── ebt_arpreply.c ├── ebt_nflog.c ├── ebt_limit.c ├── ebt_ulog.c ├── ebt_mark.c ├── ebt_vlan.c ├── ebt_log.c ├── ebt_nat.c ├── ebt_ip.c ├── ebt_arp.c ├── ebt_inat.c └── ebt_stp.c ├── ethertypes ├── ebtables-config ├── ebtables-save ├── Android.mk ├── include ├── ethernetdb.h └── ebtables.h ├── INSTALL ├── ebtablesu.c ├── ebtables.spec ├── ebtables-restore ├── ebtables.sysv ├── getethertype.c ├── ebtables-restore.c ├── examples ├── perf_test │ └── perf_test └── ulog │ └── test_ulog.c ├── ChangeLog ├── Makefile ├── ebtablesd.c └── useful_functions.c /userspace/Android.mk: -------------------------------------------------------------------------------- 1 | include $(call all-subdir-makefiles) 2 | -------------------------------------------------------------------------------- /THANKS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArrowOS/android_external_ebtables/arrow-9.x/THANKS -------------------------------------------------------------------------------- /ebtables-standalone.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "include/ebtables_u.h" 3 | 4 | static struct ebt_u_replace replace; 5 | void ebt_early_init_once(); 6 | 7 | int main(int argc, char *argv[]) 8 | { 9 | ebt_silent = 0; 10 | ebt_early_init_once(); 11 | strcpy(replace.name, "filter"); 12 | do_command(argc, argv, EXEC_STYLE_PRG, &replace); 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /extensions/ebtable_broute.c: -------------------------------------------------------------------------------- 1 | /* ebtable_broute 2 | * 3 | * Authors: 4 | * Bart De Schuymer 5 | * 6 | * April, 2002 7 | */ 8 | 9 | #include 10 | #include "../include/ebtables_u.h" 11 | 12 | 13 | static void print_help(const char **hn) 14 | { 15 | printf("Supported chain for the broute table:\n"); 16 | printf("%s\n",hn[NF_BR_BROUTING]); 17 | } 18 | 19 | static struct 20 | ebt_u_table table = 21 | { 22 | .name = "broute", 23 | .help = print_help, 24 | }; 25 | 26 | void _t_broute_init(void) 27 | { 28 | ebt_register_table(&table); 29 | } 30 | -------------------------------------------------------------------------------- /extensions/ebtable_nat.c: -------------------------------------------------------------------------------- 1 | /* ebtable_nat 2 | * 3 | * Authors: 4 | * Bart De Schuymer 5 | * 6 | * April, 2002 7 | */ 8 | 9 | #include 10 | #include "../include/ebtables_u.h" 11 | 12 | #define NAT_VALID_HOOKS ((1 << NF_BR_PRE_ROUTING) | (1 << NF_BR_LOCAL_OUT) | \ 13 | (1 << NF_BR_POST_ROUTING)) 14 | 15 | static void print_help(const char **hn) 16 | { 17 | int i; 18 | 19 | printf("Supported chains for the nat table:\n"); 20 | for (i = 0; i < NF_BR_NUMHOOKS; i++) 21 | if (NAT_VALID_HOOKS & (1 << i)) 22 | printf("%s ", hn[i]); 23 | printf("\n"); 24 | } 25 | 26 | static struct 27 | ebt_u_table table = 28 | { 29 | .name = "nat", 30 | .help = print_help, 31 | }; 32 | 33 | void _t_nat_init(void) 34 | { 35 | ebt_register_table(&table); 36 | } 37 | -------------------------------------------------------------------------------- /extensions/ebtable_filter.c: -------------------------------------------------------------------------------- 1 | /* ebtable_filter 2 | * 3 | * Authors: 4 | * Bart De Schuymer 5 | * 6 | * April, 2002 7 | */ 8 | 9 | #include 10 | #include "../include/ebtables_u.h" 11 | 12 | #define FILTER_VALID_HOOKS ((1 << NF_BR_LOCAL_IN) | (1 << NF_BR_FORWARD) | \ 13 | (1 << NF_BR_LOCAL_OUT)) 14 | 15 | static void print_help(const char **hn) 16 | { 17 | int i; 18 | 19 | printf("Supported chains for the filter table:\n"); 20 | for (i = 0; i < NF_BR_NUMHOOKS; i++) 21 | if (FILTER_VALID_HOOKS & (1 << i)) 22 | printf("%s ", hn[i]); 23 | printf("\n"); 24 | } 25 | 26 | static struct ebt_u_table table = 27 | { 28 | .name = "filter", 29 | .help = print_help, 30 | }; 31 | 32 | void _t_filter_init(void) 33 | { 34 | ebt_register_table(&table); 35 | } 36 | -------------------------------------------------------------------------------- /extensions/Makefile: -------------------------------------------------------------------------------- 1 | #! /usr/bin/make 2 | 3 | EXT_FUNC+=802_3 nat arp arpreply ip ip6 standard log redirect vlan mark_m mark \ 4 | pkttype stp among limit ulog nflog 5 | EXT_TABLES+=filter nat broute 6 | EXT_OBJS+=$(foreach T,$(EXT_FUNC), extensions/ebt_$(T).o) 7 | EXT_OBJS+=$(foreach T,$(EXT_TABLES), extensions/ebtable_$(T).o) 8 | EXT_LIBS+=$(foreach T,$(EXT_FUNC), extensions/libebt_$(T).so) 9 | EXT_LIBS+=$(foreach T,$(EXT_TABLES), extensions/libebtable_$(T).so) 10 | EXT_LIBSI+=$(foreach T,$(EXT_FUNC), -lebt_$(T)) 11 | EXT_LIBSI+=$(foreach T,$(EXT_TABLES), -lebtable_$(T)) 12 | 13 | extensions/ebt_%.so: extensions/ebt_%.o 14 | $(CC) $(LDFLAGS) -shared -o $@ -lc $< -nostartfiles 15 | 16 | extensions/libebt_%.so: extensions/ebt_%.so 17 | mv $< $@ 18 | 19 | extensions/ebtable_%.so: extensions/ebtable_%.o 20 | $(CC) $(LDFLAGS) -shared -o $@ -lc $< -nostartfiles 21 | 22 | extensions/libebtable_%.so: extensions/ebtable_%.so 23 | mv $< $@ 24 | 25 | extensions/ebt_%.o: extensions/ebt_%.c include/ebtables_u.h 26 | $(CC) $(CFLAGS) $(CFLAGS_SH_LIB) $(PROGSPECS) -c -o $@ $< -I$(KERNEL_INCLUDES) 27 | 28 | extensions/ebtable_%.o: extensions/ebtable_%.c 29 | $(CC) $(CFLAGS) $(CFLAGS_SH_LIB) $(PROGSPECS) -c -o $@ $< -I$(KERNEL_INCLUDES) 30 | 31 | -------------------------------------------------------------------------------- /ethertypes: -------------------------------------------------------------------------------- 1 | # 2 | # Ethernet frame types 3 | # This file describes some of the various Ethernet 4 | # protocol types that are used on Ethernet networks. 5 | # 6 | # This list could be found on: 7 | # http://www.iana.org/assignments/ethernet-numbers 8 | # 9 | # ... #Comment 10 | # 11 | IPv4 0800 ip ip4 # Internet IP (IPv4) 12 | X25 0805 13 | ARP 0806 ether-arp # 14 | FR_ARP 0808 # Frame Relay ARP [RFC1701] 15 | BPQ 08FF # G8BPQ AX.25 Ethernet Packet 16 | DEC 6000 # DEC Assigned proto 17 | DNA_DL 6001 # DEC DNA Dump/Load 18 | DNA_RC 6002 # DEC DNA Remote Console 19 | DNA_RT 6003 # DEC DNA Routing 20 | LAT 6004 # DEC LAT 21 | DIAG 6005 # DEC Diagnostics 22 | CUST 6006 # DEC Customer use 23 | SCA 6007 # DEC Systems Comms Arch 24 | TEB 6558 # Trans Ether Bridging [RFC1701] 25 | RAW_FR 6559 # Raw Frame Relay [RFC1701] 26 | AARP 80F3 # Appletalk AARP 27 | ATALK 809B # Appletalk 28 | 802_1Q 8100 8021q 1q 802.1q dot1q # 802.1Q Virtual LAN tagged frame 29 | IPX 8137 # Novell IPX 30 | NetBEUI 8191 # NetBEUI 31 | IPv6 86DD ip6 # IP version 6 32 | PPP 880B # PPP 33 | ATMMPOA 884C # MultiProtocol over ATM 34 | PPP_DISC 8863 # PPPoE discovery messages 35 | PPP_SES 8864 # PPPoE session messages 36 | ATMFATE 8884 # Frame-based ATM Transport over Ethernet 37 | LOOP 9000 loopback # loop proto 38 | -------------------------------------------------------------------------------- /ebtables-config: -------------------------------------------------------------------------------- 1 | # Save (and possibly restore) in text format. 2 | # Value: yes|no, default: yes 3 | # Save the firewall rules in text format to __SYSCONFIG__/ebtables 4 | # If EBTABLES_BINARY_FORMAT="no" then restoring the firewall rules 5 | # is done using this text format. 6 | EBTABLES_TEXT_FORMAT="yes" 7 | 8 | # Save (and restore) in binary format. 9 | # Value: yes|no, default: yes 10 | # Save (and restore) the firewall rules in binary format to (and from) 11 | # __SYSCONFIG__/ebtables.. Enabling this option will make 12 | # firewall initialisation a lot faster. 13 | EBTABLES_BINARY_FORMAT="yes" 14 | 15 | # Unload modules on restart and stop 16 | # Value: yes|no, default: yes 17 | # This option has to be 'yes' to get to a sane state for a firewall 18 | # restart or stop. Only set to 'no' if there are problems unloading netfilter 19 | # modules. 20 | EBTABLES_MODULES_UNLOAD="yes" 21 | 22 | # Save current firewall rules on stop. 23 | # Value: yes|no, default: no 24 | # Saves all firewall rules if firewall gets stopped 25 | # (e.g. on system shutdown). 26 | EBTABLES_SAVE_ON_STOP="no" 27 | 28 | # Save current firewall rules on restart. 29 | # Value: yes|no, default: no 30 | # Saves all firewall rules if firewall gets restarted. 31 | EBTABLES_SAVE_ON_RESTART="no" 32 | 33 | # Save (and restore) rule counters. 34 | # Value: yes|no, default: no 35 | # Save rule counters when saving a kernel table to a file. If the 36 | # rule counters were saved, they will be restored when restoring the table. 37 | EBTABLES_SAVE_COUNTER="no" 38 | -------------------------------------------------------------------------------- /ebtables-save: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | # 3 | # 4 | # A script that generates text output of the ebtables rules. 5 | # Similar to iptables-save. 6 | # 7 | # It can be used to store active configuration to /etc/sysconfig/ebtables 8 | 9 | use strict; 10 | my $table; 11 | my $ebtables = "__EXEC_PATH__/ebtables"; 12 | my $cnt = ""; 13 | my $version = "1.0"; 14 | my $table_name; 15 | 16 | # ======================================================== 17 | # Process filter table 18 | # ======================================================== 19 | sub process_table { 20 | my $chain = ""; 21 | my $rules = ""; 22 | my $chains = ""; 23 | my $line = ""; 24 | 25 | foreach $line (split("\n",$_[0])) { 26 | if ($line =~ m/Bridge table: (.*)/) { 27 | print "*$1\n"; 28 | next; 29 | } 30 | if ($line =~ m/Bridge chain: (.*?), entries:.* policy: (.*)/) { 31 | $chains = $chains . ":$1 $2\n"; 32 | $chain = $1; 33 | next; 34 | } 35 | if ($line =~ m/^$/) { 36 | next; 37 | } 38 | if ($cnt eq "--Lc") { 39 | $line =~ s/, pcnt = (.*) -- bcnt = (.*)/-c $1 $2/; 40 | } else { 41 | $line =~ s/ $//; 42 | } 43 | $rules = $rules . "-A $chain $line\n"; 44 | } 45 | 46 | print $chains; 47 | print $rules; 48 | print "\n"; 49 | } 50 | # ======================================================== 51 | 52 | unless (-x $ebtables) { exit -1 }; 53 | print "# Generated by ebtables-save v$version on " . `date`; 54 | if (defined($ENV{'EBTABLES_SAVE_COUNTER'}) && $ENV{'EBTABLES_SAVE_COUNTER'} eq "yes") { 55 | $cnt = "--Lc"; 56 | } 57 | foreach $table_name (split("\n", `grep -E '^ebtable_' /proc/modules | cut -f1 -d' ' | sed s/ebtable_//`)) { 58 | $table =`$ebtables -t $table_name -L $cnt`; 59 | unless ($? == 0) { print $table; exit -1 }; 60 | &process_table($table); 61 | } 62 | -------------------------------------------------------------------------------- /Android.mk: -------------------------------------------------------------------------------- 1 | # BUILD libebtc.so 2 | 3 | LOCAL_PATH:= $(call my-dir) 4 | 5 | cflags := -O2 -g \ 6 | -DPROGNAME=\"ebtables\" \ 7 | -DPROGVERSION=\"2.0.10\" \ 8 | -DPROGDATE=\"December\ 2011\" \ 9 | -Wno-sign-compare -Wno-missing-field-initializers \ 10 | -Wno-ignored-qualifiers -Wno-unused-parameter \ 11 | -Wno-error \ 12 | -Wno-#pragma-messages 13 | 14 | extensions_src_files := \ 15 | extensions/ebt_802_3.c \ 16 | extensions/ebt_among.c \ 17 | extensions/ebt_arp.c \ 18 | extensions/ebt_arpreply.c \ 19 | extensions/ebt_ip.c \ 20 | extensions/ebt_ip6.c \ 21 | extensions/ebt_limit.c \ 22 | extensions/ebt_log.c \ 23 | extensions/ebt_mark.c \ 24 | extensions/ebt_mark_m.c \ 25 | extensions/ebt_nat.c \ 26 | extensions/ebt_nflog.c \ 27 | extensions/ebt_pkttype.c \ 28 | extensions/ebt_redirect.c \ 29 | extensions/ebt_standard.c \ 30 | extensions/ebt_stp.c \ 31 | extensions/ebt_vlan.c \ 32 | extensions/ebtable_broute.c \ 33 | extensions/ebtable_filter.c \ 34 | extensions/ebtable_nat.c 35 | 36 | include $(CLEAR_VARS) 37 | 38 | LOCAL_SRC_FILES := \ 39 | getethertype.c \ 40 | communication.c \ 41 | libebtc.c \ 42 | useful_functions.c \ 43 | ebtables.c \ 44 | $(extensions_src_files) \ 45 | ebtables-standalone.c 46 | 47 | LOCAL_C_INCLUDES := $(LOCAL_PATH)/include 48 | LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include 49 | LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr 50 | 51 | LOCAL_CFLAGS := $(cflags) 52 | LOCAL_LDFLAGS := -nostartfiles 53 | LOCAL_MODULE := ebtables 54 | 55 | LOCAL_MODULE_TAGS := optional 56 | 57 | include $(BUILD_EXECUTABLE) 58 | 59 | 60 | #######dss_test_104########## 61 | include $(CLEAR_VARS) 62 | LOCAL_MODULE:= ethertypes 63 | LOCAL_MODULE_CLASS := EXECUTABLES 64 | LOCAL_SRC_FILES := ethertypes 65 | LOCAL_MODULE_TAGS := optional 66 | LOCAL_MODULE_PATH := $(TARGET_OUT_ETC) 67 | include $(BUILD_PREBUILT) 68 | 69 | -------------------------------------------------------------------------------- /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 | #define __THROW 34 | 35 | struct ethertypeent { 36 | char *e_name; /* Official ethernet type name. */ 37 | char **e_aliases; /* Alias list. */ 38 | int e_ethertype; /* Ethernet type number. */ 39 | }; 40 | 41 | /* Open ethertype data base files and mark them as staying open even 42 | after a later search if STAY_OPEN is non-zero. */ 43 | extern void setethertypeent(int __stay_open) __THROW; 44 | 45 | /* Close ethertype data base files and clear `stay open' flag. */ 46 | extern void endethertypeent(void) __THROW; 47 | 48 | /* Get next entry from ethertype data base file. Open data base if 49 | necessary. */ 50 | extern struct ethertypeent *getethertypeent(void) __THROW; 51 | 52 | /* Return entry from ethertype data base for network with NAME. */ 53 | extern struct ethertypeent *getethertypebyname(__const char *__name) 54 | __THROW; 55 | 56 | /* Return entry from ethertype data base which number is PROTO. */ 57 | extern struct ethertypeent *getethertypebynumber(int __ethertype) __THROW; 58 | 59 | 60 | #endif /* ethernetdb.h */ 61 | -------------------------------------------------------------------------------- /extensions/ebt_standard.c: -------------------------------------------------------------------------------- 1 | /* ebt_standard 2 | * 3 | * Authors: 4 | * Bart De Schuymer 5 | * 6 | * April, 2002 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include "../include/ebtables_u.h" 13 | 14 | static struct option opts[] = 15 | { 16 | {0} 17 | }; 18 | 19 | static void print_help() 20 | { 21 | printf("Standard targets: DROP, ACCEPT, RETURN or CONTINUE;\n" 22 | "The target can also be a user defined chain.\n"); 23 | } 24 | 25 | static void init(struct ebt_entry_target *t) 26 | { 27 | ((struct ebt_standard_target *)t)->verdict = EBT_CONTINUE; 28 | } 29 | 30 | static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, 31 | unsigned int *flags, struct ebt_entry_target **target) 32 | { 33 | return 0; 34 | } 35 | 36 | static void final_check(const struct ebt_u_entry *entry, 37 | const struct ebt_entry_target *target, const char *name, 38 | unsigned int hookmask, unsigned int time) 39 | { 40 | } 41 | 42 | static void print(const struct ebt_u_entry *entry, 43 | const struct ebt_entry_target *target) 44 | { 45 | int verdict = ((struct ebt_standard_target *)target)->verdict; 46 | 47 | if (verdict >= 0) { 48 | struct ebt_u_entries *entries; 49 | 50 | entries = entry->replace->chains[verdict + NF_BR_NUMHOOKS]; 51 | printf("%s", entries->name); 52 | return; 53 | } 54 | if (verdict == EBT_CONTINUE) 55 | printf("CONTINUE "); 56 | else if (verdict == EBT_ACCEPT) 57 | printf("ACCEPT "); 58 | else if (verdict == EBT_DROP) 59 | printf("DROP "); 60 | else if (verdict == EBT_RETURN) 61 | printf("RETURN "); 62 | else 63 | ebt_print_bug("Bad standard target"); 64 | } 65 | 66 | static int compare(const struct ebt_entry_target *t1, 67 | const struct ebt_entry_target *t2) 68 | { 69 | return ((struct ebt_standard_target *)t1)->verdict == 70 | ((struct ebt_standard_target *)t2)->verdict; 71 | } 72 | 73 | static struct ebt_u_target standard = 74 | { 75 | .name = "standard", 76 | .size = sizeof(struct ebt_standard_target) - 77 | sizeof(struct ebt_entry_target), 78 | .help = print_help, 79 | .init = init, 80 | .parse = parse, 81 | .final_check = final_check, 82 | .print = print, 83 | .compare = compare, 84 | .extra_ops = opts, 85 | }; 86 | 87 | void _standard_init(void) 88 | { 89 | ebt_register_target(&standard); 90 | } 91 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | FOLLOW THESE SIMPLE GUIDELINES: 2 | ------------------------------- 3 | 4 | Compiling the source code: 5 | %make 6 | Put the files in the right directories: 7 | %make install 8 | 9 | If you are using the CVS code or need your own kernel includes, do this 10 | instead (change the include directory to the appropriate one): 11 | %make install KERNEL_INCLUDES=/usr/src/linux/include 12 | 13 | If you want to make a static binary for ebtables, containing all the 14 | extensions, without shared libraries, do this (this will make a 15 | binary called 'static', which you can rename): 16 | %make static 17 | 18 | WHAT GETS INSTALLED AND WHAT OPTIONS ARE AVAILABLE? 19 | --------------------------------------------------- 20 | 21 | - The ebtables manual gets installed in /usr/local/man/man8 22 | To put the manual somewhere else, include MANDIR=<> as 23 | option on the command line. 24 | The Makefile will append /man8/ebtables.8. 25 | - ethertypes is by default placed in /etc/, if you 26 | want to change this, include ETHERTYPESPATH=<>. 27 | - The userspace programs ebtables ebtables-save and ebtables-restore are 28 | are copied by default to /usr/local/sbin/ebtables. If you want to put 29 | the executables somewhere else, include BINPATH=<>. 30 | - The ebtables initialisation file (enabling use of 'service ebtables') is 31 | copied to /etc/rc.d/init.d (change with option INITDIR) 32 | - The ebtables configuration file (ebtables-config) is copied to /etc/sysconfig 33 | - ebtables can use a lock file to enable concurrent execution of the ebtables 34 | tool. The standard location of the lock file is /var/lib/ebtables/lock. 35 | Include LOCKFILE=<> if you want to use another file. 36 | 37 | That's all 38 | 39 | You can also use a base directory different from the root directory (/), 40 | using the DESTDIR option. See the Makefile for more details. 41 | 42 | 43 | ADDITIONAL PROGRAMS: 44 | ---------------------- 45 | -- examples/ulog/test_ulog.c -- 46 | 47 | Contains an example to receive and parse netlink messages containing 48 | packets seen by the ebtables ulog watcher. 49 | 50 | Compile with: 51 | %make test_ulog KERNEL_INCLUDES=/usr/src/linux/include 52 | 53 | Usage: 54 | %examples/ulog/test_ulog NETLINK_GROUP 55 | %ebtables -A chain --ulog-nlgroup NETLINK_GROUP 56 | 57 | -- examples/perf_test/perf_test -- 58 | 59 | A test script to compare the performance for the different ways to 60 | construct an ebtables table. This is deprecated and should probably 61 | be ignored. 62 | -------------------------------------------------------------------------------- /ebtablesu.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | static void print_help() 11 | { 12 | printf("ebtablesu v"PROGVERSION" ("PROGDATE")\n"); 13 | printf( 14 | "Usage:\n" 15 | "ebtablesu open table : copy the kernel table\n" 16 | "ebtablesu fopen table file : copy the table from the specified file\n" 17 | "ebtablesu free table : remove the table from memory\n" 18 | "ebtablesu commit table : commit the table to the kernel\n" 19 | "ebtablesu fcommit table file : commit the table to the specified file\n\n" 20 | "ebtablesu : the ebtables specifications\n" 21 | " use spaces only to separate options and commands\n" 22 | "For the ebtables options, see\n# ebtables -h\nor\n# man ebtables\n" 23 | ); 24 | } 25 | int main(int argc, char *argv[]) 26 | { 27 | char *arguments, *pos; 28 | int i, writefd, len = 0; 29 | 30 | if (argc > EBTD_ARGC_MAX) { 31 | fprintf(stderr, "ebtablesd accepts at most %d arguments, %d " 32 | "arguments were specified. If you need this many " 33 | "arguments, recompile this tool with a higher value for" 34 | " EBTD_ARGC_MAX.\n", EBTD_ARGC_MAX - 1, argc - 1); 35 | return -1; 36 | } else if (argc == 1) { 37 | fprintf(stderr, "At least one argument is needed.\n"); 38 | print_help(); 39 | exit(0); 40 | } 41 | 42 | for (i = 0; i < argc; i++) 43 | len += strlen(argv[i]); 44 | /* Don't forget '\0' */ 45 | len += argc; 46 | if (len > EBTD_CMDLINE_MAXLN) { 47 | fprintf(stderr, "ebtablesd has a maximum command line argument " 48 | "length of %d, an argument length of %d was received. " 49 | "If a smaller length is unfeasible, recompile this tool " 50 | "with a higher value for EBTD_CMDLINE_MAXLN.\n", 51 | EBTD_CMDLINE_MAXLN, len); 52 | return -1; 53 | } 54 | 55 | if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) { 56 | if (argc != 2) { 57 | fprintf(stderr, "%s does not accept options.\n", argv[1]); 58 | return -1; 59 | } 60 | print_help(); 61 | exit(0); 62 | } 63 | 64 | if (!(arguments = (char *)malloc(len))) { 65 | fprintf(stderr, "ebtablesu: out of memory.\n"); 66 | return -1; 67 | } 68 | 69 | if ((writefd = open(EBTD_PIPE, O_WRONLY, 0)) == -1) { 70 | fprintf(stderr, "Could not open the pipe, perhaps ebtablesd is " 71 | "not running or you don't have write permission (try " 72 | "running as root).\n"); 73 | return -1; 74 | } 75 | 76 | pos = arguments; 77 | for (i = 0; i < argc; i++) { 78 | strcpy(pos, argv[i]); 79 | pos += strlen(argv[i]); 80 | *(pos++) = ' '; 81 | } 82 | 83 | *(pos-1) = '\n'; 84 | if (write(writefd, arguments, len) == -1) { 85 | perror("write"); 86 | return -1; 87 | } 88 | return 0; 89 | } 90 | -------------------------------------------------------------------------------- /ebtables.spec: -------------------------------------------------------------------------------- 1 | # spec file originally from Dag Wieers, altered by Bart De Schuymer 2 | 3 | %define _sbindir /usr/local/sbin 4 | %define _mysysconfdir %{_sysconfdir}/sysconfig 5 | 6 | Summary: Ethernet Bridge frame table administration tool 7 | Name: ebtables 8 | Version: $(VERSION) 9 | Release: $(RELEASE) 10 | License: GPL 11 | Group: System Environment/Base 12 | URL: http://ebtables.sourceforge.net/ 13 | 14 | Packager: Bart De Schuymer 15 | 16 | Source: http://dl.sf.net/ebtables/ebtables-v%{version}-%{release}.tar.gz 17 | BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root 18 | 19 | %description 20 | Ethernet bridge tables is a firewalling tool to transparantly filter network 21 | traffic passing a bridge. The filtering possibilities are limited to link 22 | layer filtering and some basic filtering on higher network layers. 23 | 24 | The ebtables tool can be used together with the other Linux filtering tools, 25 | like iptables. There are no incompatibility issues. 26 | 27 | %prep 28 | %setup -n ebtables-v%{version}-%{release} 29 | 30 | %build 31 | %{__make} %{?_smp_mflags} \ 32 | CFLAGS="%{optflags}" 33 | 34 | %install 35 | %{__rm} -rf %{buildroot} 36 | %{__install} -D -m0755 ebtables %{buildroot}%{_sbindir}/ebtables 37 | %{__install} -D -m0755 ebtables-restore %{buildroot}%{_sbindir}/ebtables-restore 38 | %{__install} -D -m0644 ethertypes %{buildroot}%{_sysconfdir}/ethertypes 39 | %{__install} -D -m0644 ebtables.8 %{buildroot}%{_mandir}/man8/ebtables.8 40 | %{__mkdir} -p %{buildroot}%{_libdir}/ebtables/ 41 | %{__mkdir} -p %{buildroot}%{_sbindir} 42 | %{__mkdir} -p %{buildroot}%{_initrddir} 43 | %{__mkdir} -p %{buildroot}%{_mysysconfdir} 44 | %{__install} -m0755 extensions/*.so %{buildroot}%{_libdir}/ebtables/ 45 | %{__install} -m0755 *.so %{buildroot}%{_libdir}/ebtables/ 46 | export __iets=`printf %{_sbindir} | sed 's/\\//\\\\\\//g'` 47 | export __iets2=`printf %{_mysysconfdir} | sed 's/\\//\\\\\\//g'` 48 | sed -i "s/__EXEC_PATH__/$__iets/g" ebtables-save 49 | %{__install} -m 0755 -o root -g root ebtables-save %{buildroot}%{_sbindir}/ebtables-save 50 | sed -i "s/__EXEC_PATH__/$__iets/g" ebtables.sysv; sed -i "s/__SYSCONFIG__/$__iets2/g" ebtables.sysv 51 | %{__install} -m 0755 -o root -g root ebtables.sysv %{buildroot}%{_initrddir}/ebtables 52 | sed -i "s/__SYSCONFIG__/$__iets2/g" ebtables-config 53 | %{__install} -m 0600 -o root -g root ebtables-config %{buildroot}%{_mysysconfdir}/ebtables-config 54 | unset __iets 55 | unset __iets2 56 | 57 | %clean 58 | %{__rm} -rf %{buildroot} 59 | 60 | %post 61 | /sbin/chkconfig --add ebtables 62 | 63 | %preun 64 | if [ $1 -eq 0 ]; then 65 | /sbin/service ebtables stop &>/dev/null || : 66 | /sbin/chkconfig --del ebtables 67 | fi 68 | 69 | %files 70 | %defattr(-, root, root, 0755) 71 | %doc ChangeLog COPYING INSTALL THANKS 72 | %doc %{_mandir}/man8/ebtables.8* 73 | %config %{_sysconfdir}/ethertypes 74 | %config %{_mysysconfdir}/ebtables-config 75 | %config %{_initrddir}/ebtables 76 | %{_sbindir}/ebtables 77 | %{_sbindir}/ebtables-save 78 | %{_sbindir}/ebtables-restore 79 | %{_libdir}/ebtables/ 80 | 81 | %changelog 82 | * Mon Nov 07 2005 Bart De Schuymer - 2.0.8-rc1 83 | - Initial package. 84 | -------------------------------------------------------------------------------- /extensions/ebt_redirect.c: -------------------------------------------------------------------------------- 1 | /* ebt_redirect 2 | * 3 | * Authors: 4 | * Bart De Schuymer 5 | * 6 | * April, 2002 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "../include/ebtables_u.h" 14 | #include 15 | 16 | #define REDIRECT_TARGET '1' 17 | static struct option opts[] = 18 | { 19 | { "redirect-target", required_argument, 0, REDIRECT_TARGET }, 20 | { 0 } 21 | }; 22 | 23 | static void print_help() 24 | { 25 | printf( 26 | "redirect option:\n" 27 | " --redirect-target target : ACCEPT, DROP, RETURN or CONTINUE\n"); 28 | } 29 | 30 | static void init(struct ebt_entry_target *target) 31 | { 32 | struct ebt_redirect_info *redirectinfo = 33 | (struct ebt_redirect_info *)target->data; 34 | 35 | redirectinfo->target = EBT_ACCEPT; 36 | return; 37 | } 38 | 39 | #define OPT_REDIRECT_TARGET 0x01 40 | static int parse(int c, char **argv, int argc, 41 | const struct ebt_u_entry *entry, unsigned int *flags, 42 | struct ebt_entry_target **target) 43 | { 44 | struct ebt_redirect_info *redirectinfo = 45 | (struct ebt_redirect_info *)(*target)->data; 46 | 47 | switch (c) { 48 | case REDIRECT_TARGET: 49 | ebt_check_option2(flags, OPT_REDIRECT_TARGET); 50 | if (FILL_TARGET(optarg, redirectinfo->target)) 51 | ebt_print_error2("Illegal --redirect-target target"); 52 | break; 53 | default: 54 | return 0; 55 | } 56 | return 1; 57 | } 58 | 59 | static void final_check(const struct ebt_u_entry *entry, 60 | const struct ebt_entry_target *target, const char *name, 61 | unsigned int hookmask, unsigned int time) 62 | { 63 | struct ebt_redirect_info *redirectinfo = 64 | (struct ebt_redirect_info *)target->data; 65 | 66 | if (BASE_CHAIN && redirectinfo->target == EBT_RETURN) { 67 | ebt_print_error("--redirect-target RETURN not allowed on base chain"); 68 | return; 69 | } 70 | CLEAR_BASE_CHAIN_BIT; 71 | if ( ((hookmask & ~(1 << NF_BR_PRE_ROUTING)) || strcmp(name, "nat")) && 72 | ((hookmask & ~(1 << NF_BR_BROUTING)) || strcmp(name, "broute")) ) 73 | ebt_print_error("Wrong chain for redirect"); 74 | } 75 | 76 | static void print(const struct ebt_u_entry *entry, 77 | const struct ebt_entry_target *target) 78 | { 79 | struct ebt_redirect_info *redirectinfo = 80 | (struct ebt_redirect_info *)target->data; 81 | 82 | if (redirectinfo->target == EBT_ACCEPT) 83 | return; 84 | printf(" --redirect-target %s", TARGET_NAME(redirectinfo->target)); 85 | } 86 | 87 | static int compare(const struct ebt_entry_target *t1, 88 | const struct ebt_entry_target *t2) 89 | { 90 | struct ebt_redirect_info *redirectinfo1 = 91 | (struct ebt_redirect_info *)t1->data; 92 | struct ebt_redirect_info *redirectinfo2 = 93 | (struct ebt_redirect_info *)t2->data; 94 | 95 | return redirectinfo1->target == redirectinfo2->target; 96 | } 97 | 98 | static struct ebt_u_target redirect_target = 99 | { 100 | .name = "redirect", 101 | .size = sizeof(struct ebt_redirect_info), 102 | .help = print_help, 103 | .init = init, 104 | .parse = parse, 105 | .final_check = final_check, 106 | .print = print, 107 | .compare = compare, 108 | .extra_ops = opts, 109 | }; 110 | 111 | void _redirect_init(void) 112 | { 113 | ebt_register_target(&redirect_target); 114 | } 115 | -------------------------------------------------------------------------------- /extensions/ebt_pkttype.c: -------------------------------------------------------------------------------- 1 | /* ebt_pkttype 2 | * 3 | * Authors: 4 | * Bart De Schuymer 5 | * 6 | * April, 2003 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "../include/ebtables_u.h" 15 | #include 16 | #include 17 | 18 | char *classes[] = 19 | { 20 | "host", 21 | "broadcast", 22 | "multicast", 23 | "otherhost", 24 | "outgoing", 25 | "loopback", 26 | "fastroute", 27 | "\0" 28 | }; 29 | 30 | static struct option opts[] = 31 | { 32 | { "pkttype-type" , required_argument, 0, '1' }, 33 | { 0 } 34 | }; 35 | 36 | static void print_help() 37 | { 38 | printf( 39 | "pkttype options:\n" 40 | "--pkttype-type [!] type: class the packet belongs to\n" 41 | "Possible values: broadcast, multicast, host, otherhost, or any other byte value (which would be pretty useless).\n"); 42 | } 43 | 44 | static void init(struct ebt_entry_match *match) 45 | { 46 | struct ebt_pkttype_info *pt = (struct ebt_pkttype_info *)match->data; 47 | 48 | pt->invert = 0; 49 | } 50 | 51 | static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, 52 | unsigned int *flags, struct ebt_entry_match **match) 53 | { 54 | struct ebt_pkttype_info *ptinfo = (struct ebt_pkttype_info *)(*match)->data; 55 | char *end; 56 | long int i; 57 | 58 | switch (c) { 59 | case '1': 60 | ebt_check_option2(flags, 1); 61 | if (ebt_check_inverse2(optarg)) 62 | ptinfo->invert = 1; 63 | i = strtol(optarg, &end, 16); 64 | if (*end != '\0') { 65 | int j = 0; 66 | i = -1; 67 | while (classes[j][0]) 68 | if (!strcasecmp(optarg, classes[j++])) { 69 | i = j - 1; 70 | break; 71 | } 72 | } 73 | if (i < 0 || i > 255) 74 | ebt_print_error2("Problem with specified pkttype class"); 75 | ptinfo->pkt_type = (uint8_t)i; 76 | break; 77 | default: 78 | return 0; 79 | } 80 | return 1; 81 | } 82 | 83 | static void final_check(const struct ebt_u_entry *entry, 84 | const struct ebt_entry_match *match, const char *name, 85 | unsigned int hookmask, unsigned int time) 86 | { 87 | } 88 | 89 | static void print(const struct ebt_u_entry *entry, 90 | const struct ebt_entry_match *match) 91 | { 92 | struct ebt_pkttype_info *pt = (struct ebt_pkttype_info *)match->data; 93 | int i = 0; 94 | 95 | printf("--pkttype-type %s", pt->invert ? "! " : ""); 96 | while (classes[i++][0]); 97 | if (pt->pkt_type < i - 1) 98 | printf("%s ", classes[pt->pkt_type]); 99 | else 100 | printf("%d ", pt->pkt_type); 101 | } 102 | 103 | static int compare(const struct ebt_entry_match *m1, 104 | const struct ebt_entry_match *m2) 105 | { 106 | struct ebt_pkttype_info *pt1 = (struct ebt_pkttype_info *)m1->data; 107 | struct ebt_pkttype_info *pt2 = (struct ebt_pkttype_info *)m2->data; 108 | 109 | if (pt1->invert != pt2->invert || 110 | pt1->pkt_type != pt2->pkt_type) 111 | return 0; 112 | return 1; 113 | } 114 | 115 | static struct ebt_u_match pkttype_match = 116 | { 117 | .name = "pkttype", 118 | .size = sizeof(struct ebt_pkttype_info), 119 | .help = print_help, 120 | .init = init, 121 | .parse = parse, 122 | .final_check = final_check, 123 | .print = print, 124 | .compare = compare, 125 | .extra_ops = opts, 126 | }; 127 | 128 | void _pkttype_init(void) 129 | { 130 | ebt_register_match(&pkttype_match); 131 | } 132 | -------------------------------------------------------------------------------- /extensions/ebt_mark_m.c: -------------------------------------------------------------------------------- 1 | /* ebt_mark_m 2 | * 3 | * Authors: 4 | * Bart De Schuymer 5 | * 6 | * July, 2002 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "../include/ebtables_u.h" 14 | #include 15 | 16 | #define MARK '1' 17 | 18 | static struct option opts[] = 19 | { 20 | { "mark", required_argument, 0, MARK }, 21 | { 0 } 22 | }; 23 | 24 | static void print_help() 25 | { 26 | printf( 27 | "mark option:\n" 28 | "--mark [!] [value][/mask]: Match nfmask value (see man page)\n"); 29 | } 30 | 31 | static void init(struct ebt_entry_match *match) 32 | { 33 | struct ebt_mark_m_info *markinfo = (struct ebt_mark_m_info *)match->data; 34 | 35 | markinfo->mark = 0; 36 | markinfo->mask = 0; 37 | markinfo->invert = 0; 38 | markinfo->bitmask = 0; 39 | } 40 | 41 | #define OPT_MARK 0x01 42 | static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, 43 | unsigned int *flags, struct ebt_entry_match **match) 44 | { 45 | struct ebt_mark_m_info *markinfo = (struct ebt_mark_m_info *) 46 | (*match)->data; 47 | char *end; 48 | 49 | switch (c) { 50 | case MARK: 51 | ebt_check_option2(flags, MARK); 52 | if (ebt_check_inverse2(optarg)) 53 | markinfo->invert = 1; 54 | markinfo->mark = strtoul(optarg, &end, 0); 55 | markinfo->bitmask = EBT_MARK_AND; 56 | if (*end == '/') { 57 | if (end == optarg) 58 | markinfo->bitmask = EBT_MARK_OR; 59 | markinfo->mask = strtoul(end+1, &end, 0); 60 | } else 61 | markinfo->mask = 0xffffffff; 62 | if ( *end != '\0' || end == optarg) 63 | ebt_print_error2("Bad mark value '%s'", optarg); 64 | break; 65 | default: 66 | return 0; 67 | } 68 | return 1; 69 | } 70 | 71 | static void final_check(const struct ebt_u_entry *entry, 72 | const struct ebt_entry_match *match, const char *name, 73 | unsigned int hookmask, unsigned int time) 74 | { 75 | } 76 | 77 | static void print(const struct ebt_u_entry *entry, 78 | const struct ebt_entry_match *match) 79 | { 80 | struct ebt_mark_m_info *markinfo = 81 | (struct ebt_mark_m_info *)match->data; 82 | 83 | printf("--mark "); 84 | if (markinfo->invert) 85 | printf("! "); 86 | if (markinfo->bitmask == EBT_MARK_OR) 87 | printf("/0x%lx ", markinfo->mask); 88 | else if(markinfo->mask != 0xffffffff) 89 | printf("0x%lx/0x%lx ", markinfo->mark, markinfo->mask); 90 | else 91 | printf("0x%lx ", markinfo->mark); 92 | } 93 | 94 | static int compare(const struct ebt_entry_match *m1, 95 | const struct ebt_entry_match *m2) 96 | { 97 | struct ebt_mark_m_info *markinfo1 = (struct ebt_mark_m_info *)m1->data; 98 | struct ebt_mark_m_info *markinfo2 = (struct ebt_mark_m_info *)m2->data; 99 | 100 | if (markinfo1->invert != markinfo2->invert) 101 | return 0; 102 | if (markinfo1->mark != markinfo2->mark) 103 | return 0; 104 | if (markinfo1->mask != markinfo2->mask) 105 | return 0; 106 | if (markinfo1->bitmask != markinfo2->bitmask) 107 | return 0; 108 | return 1; 109 | } 110 | 111 | static struct ebt_u_match mark_match = 112 | { 113 | .name = "mark_m", 114 | .size = sizeof(struct ebt_mark_m_info), 115 | .help = print_help, 116 | .init = init, 117 | .parse = parse, 118 | .final_check = final_check, 119 | .print = print, 120 | .compare = compare, 121 | .extra_ops = opts, 122 | }; 123 | 124 | void _mark_m_init(void) 125 | { 126 | ebt_register_match(&mark_match); 127 | } 128 | -------------------------------------------------------------------------------- /ebtables-restore: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | # 3 | # 4 | # A script that imports text ebtables rules. Similar to iptables-restore. 5 | # It can be used to restore configuration from /etc/sysconfig/ebtables. 6 | # 7 | 8 | use strict; 9 | my $ebtables = "__EXEC_PATH__/ebtables"; 10 | my $table = ""; 11 | my $rc; 12 | my $child; 13 | my $line; 14 | 15 | # ============================== 16 | # Check table 17 | # Creates user chains. 18 | # ============================== 19 | sub check_chain { 20 | if ($table eq "filter") { 21 | if ($_[1] eq "INPUT") { return; } 22 | if ($_[1] eq "FORWARD") { return; } 23 | if ($_[1] eq "OUTPUT") { return; } 24 | } 25 | if ($table eq "nat") { 26 | if ($_[1] eq "PREROUTING") { return; } 27 | if ($_[1] eq "POSTROUTING") { return; } 28 | if ($_[1] eq "OUTPUT") { return; } 29 | } 30 | if ($table eq "broute") { 31 | if ($_[1] eq "BROUTING") { return; } 32 | } 33 | $rc = `$ebtables -t $_[0] -N $_[1]`; 34 | unless($? == 0) {print "ERROR: $rc\n"; exit -1}; 35 | } 36 | # ============================== 37 | 38 | if (-x "__EXEC_PATH__/ebtablesd" && -x "__EXEC_PATH__/ebtablesu") { 39 | `killall ebtablesd 2>/dev/null`; 40 | $child = fork(); 41 | if ($child == 0) { 42 | $rc = `__EXEC_PATH__/ebtablesd`; 43 | if (!($rc eq "")) { 44 | exit -1; 45 | } 46 | exit 0; 47 | } 48 | $ebtables = "__EXEC_PATH__/ebtablesu"; 49 | while (!(-e "__PIPE__")) { 50 | if ((kill 0) < $child) { 51 | exit -1; 52 | } 53 | } 54 | } else { 55 | unless (-x $ebtables) { print "ERROR: $ebtables isn't executable\n"; exit -1; }; 56 | } 57 | 58 | $line = 0; 59 | while(<>) { 60 | $line++; 61 | if(m/^#/) { next; }; 62 | if(m/^$/) { next; }; 63 | if ($ebtables eq "__EXEC_PATH__/ebtablesu") { 64 | if ((kill 0) < $child) { 65 | exit -1; 66 | } 67 | } 68 | if(m/^\*(.*)/) { 69 | if (!($table eq "")) { 70 | if (!defined($ENV{'EBTABLES_SAVE_COUNTER'}) || !($ENV{'EBTABLES_SAVE_COUNTER'} eq "yes")) { 71 | $rc = `$ebtables -t $table -Z`; 72 | unless($? == 0) {print "ERROR: $rc\n"; exit -1}; 73 | } 74 | if ($ebtables eq "__EXEC_PATH__/ebtablesu") { 75 | $rc = `$ebtables commit $table`; 76 | $rc = `$ebtables free $table`; 77 | unless($? == 0) {print "ERROR: $rc\n"; exit -1}; 78 | } 79 | } 80 | $table = $1; 81 | if ($ebtables eq "__EXEC_PATH__/ebtablesu") { 82 | $rc = `$ebtables open $table`; 83 | unless($? == 0) {print "ERROR: $rc\n"; exit -1}; 84 | $rc = `$ebtables -F`; 85 | unless($? == 0) {print "ERROR: $rc\n"; exit -1}; 86 | } else { 87 | $rc = `$ebtables -t filter --init-table`; 88 | unless($? == 0) {print "ERROR: $rc\n"; exit -1}; 89 | } 90 | next; 91 | } 92 | if(m/^\:(.*?)\s(.*)/) { 93 | &check_chain($table,$1); 94 | $rc = `$ebtables -t $table -P $1 $2`; 95 | unless($? == 0) {print "ERROR(line $line): $rc\n"; exit -1}; 96 | next; 97 | } 98 | $rc = `$ebtables -t $table $_`; 99 | unless($? == 0) {print "ERROR(line $line): $rc\n"; exit -1}; 100 | } 101 | 102 | if (!($table eq "")) { 103 | if (!defined($ENV{'EBTABLES_SAVE_COUNTER'}) || !($ENV{'EBTABLES_SAVE_COUNTER'} eq "yes")) { 104 | $rc = `$ebtables -t $table -Z`; 105 | unless($? == 0) {print "ERROR: '-t $table -Z' failed\n"; exit -1}; 106 | } 107 | if ($ebtables eq "__EXEC_PATH__/ebtablesu") { 108 | $rc = `$ebtables commit $table`; 109 | unless($? == 0) {print "ERROR: $rc\n"; exit -1}; 110 | } 111 | } 112 | 113 | if ($ebtables eq "__EXEC_PATH__/ebtablesu") { 114 | $rc = `$ebtables quit`; 115 | unless($? == 0) {print "ERROR: $rc\n"; exit -1}; 116 | waitpid($child,0); 117 | exit 0; 118 | } 119 | -------------------------------------------------------------------------------- /ebtables.sysv: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # init script for the Ethernet Bridge filter tables 4 | # 5 | # Written by Dag Wieers 6 | # Modified by Rok Papez 7 | # Bart De Schuymer 8 | # 9 | # chkconfig: - 15 85 10 | # description: Ethernet Bridge filtering tables 11 | # 12 | # config: __SYSCONFIG__/ebtables (text) 13 | # __SYSCONFIG__/ebtables. (binary) 14 | 15 | source /etc/init.d/functions 16 | source /etc/sysconfig/network 17 | 18 | # Check that networking is up. 19 | [ ${NETWORKING} = "no" ] && exit 0 20 | 21 | [ -x __EXEC_PATH__/ebtables ] || exit 1 22 | [ -x __EXEC_PATH__/ebtables-save ] || exit 1 23 | [ -x __EXEC_PATH__/ebtables-restore ] || exit 1 24 | 25 | RETVAL=0 26 | prog="ebtables" 27 | desc="Ethernet bridge filtering" 28 | umask 0077 29 | 30 | #default configuration 31 | EBTABLES_TEXT_FORMAT="yes" 32 | EBTABLES_BINARY_FORMAT="yes" 33 | EBTABLES_MODULES_UNLOAD="yes" 34 | EBTABLES_SAVE_ON_STOP="no" 35 | EBTABLES_SAVE_ON_RESTART="no" 36 | EBTABLES_SAVE_COUNTER="no" 37 | 38 | config=__SYSCONFIG__/$prog-config 39 | [ -f "$config" ] && . "$config" 40 | 41 | start() { 42 | echo -n $"Starting $desc ($prog): " 43 | if [ "$EBTABLES_BINARY_FORMAT" = "yes" ]; then 44 | for table in $(ls __SYSCONFIG__/ebtables.* 2>/dev/null | sed -e 's/.*ebtables\.//' -e '/save/d' ); do 45 | __EXEC_PATH__/ebtables -t $table --atomic-file __SYSCONFIG__/ebtables.$table --atomic-commit || RETVAL=1 46 | done 47 | else 48 | __EXEC_PATH__/ebtables-restore < /etc/sysconfig/ebtables || RETVAL=1 49 | fi 50 | 51 | if [ $RETVAL -eq 0 ]; then 52 | success "$prog startup" 53 | rm -f /var/lock/subsys/$prog 54 | else 55 | failure "$prog startup" 56 | fi 57 | echo 58 | } 59 | 60 | stop() { 61 | echo -n $"Stopping $desc ($prog): " 62 | for table in $(grep '^ebtable_' /proc/modules | sed -e 's/ebtable_\([^ ]*\).*/\1/'); do 63 | __EXEC_PATH__/ebtables -t $table --init-table || RETVAL=1 64 | done 65 | 66 | if [ "$EBTABLES_MODULES_UNLOAD" = "yes" ]; then 67 | for mod in $(grep -E '^(ebt|ebtable)_' /proc/modules | cut -f1 -d' ') ebtables; do 68 | rmmod $mod 2> /dev/null 69 | done 70 | fi 71 | 72 | if [ $RETVAL -eq 0 ]; then 73 | success "$prog shutdown" 74 | rm -f /var/lock/subsys/$prog 75 | else 76 | failure "$prog shutdown" 77 | fi 78 | echo 79 | } 80 | 81 | restart() { 82 | stop 83 | start 84 | } 85 | 86 | save() { 87 | echo -n $"Saving $desc ($prog): " 88 | if [ "$EBTABLES_TEXT_FORMAT" = "yes" ]; then 89 | if [ -e __SYSCONFIG__/ebtables ]; then 90 | chmod 0600 __SYSCONFIG__/ebtables 91 | mv -f __SYSCONFIG__/ebtables __SYSCONFIG__/ebtables.save 92 | fi 93 | __EXEC_PATH__/ebtables-save > __SYSCONFIG__/ebtables || RETVAL=1 94 | fi 95 | if [ "$EBTABLES_BINARY_FORMAT" = "yes" ]; then 96 | rm -f __SYSCONFIG__/ebtables.*.save 97 | for oldtable in $(ls __SYSCONFIG__/ebtables.* 2>/dev/null | grep -vF 'ebtables.save'); do 98 | chmod 0600 $oldtable 99 | mv -f $oldtable $oldtable.save 100 | done 101 | for table in $(grep '^ebtable_' /proc/modules | sed -e 's/ebtable_\([^ ]*\).*/\1/'); do 102 | __EXEC_PATH__/ebtables -t $table --atomic-file __SYSCONFIG__/ebtables.$table --atomic-save || RETVAL=1 103 | if [ "$EBTABLES_SAVE_COUNTER" = "no" ]; then 104 | __EXEC_PATH__/ebtables -t $table --atomic-file __SYSCONFIG__/ebtables.$table -Z || RETVAL=1 105 | fi 106 | done 107 | fi 108 | 109 | if [ $RETVAL -eq 0 ]; then 110 | success "$prog saved" 111 | else 112 | failure "$prog saved" 113 | fi 114 | echo 115 | } 116 | 117 | case "$1" in 118 | start) 119 | start 120 | ;; 121 | stop) 122 | [ "$EBTABLES_SAVE_ON_STOP" = "yes" ] && save 123 | stop 124 | ;; 125 | restart|reload) 126 | [ "$EBTABLES_SAVE_ON_RESTART" = "yes" ] && save 127 | restart 128 | ;; 129 | condrestart) 130 | [ -e /var/lock/subsys/$prog ] && restart 131 | RETVAL=$? 132 | ;; 133 | save) 134 | save 135 | ;; 136 | status) 137 | __EXEC_PATH__/ebtables-save 138 | RETVAL=$? 139 | ;; 140 | *) 141 | echo $"Usage $0 {start|stop|restart|condrestart|save|status}" 142 | RETVAL=1 143 | esac 144 | 145 | exit $RETVAL 146 | -------------------------------------------------------------------------------- /extensions/ebt_802_3.c: -------------------------------------------------------------------------------- 1 | /* 802_3 2 | * 3 | * Author: 4 | * Chris Vitale 5 | * 6 | * May 2003 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "../include/ebtables_u.h" 14 | #include "../include/ethernetdb.h" 15 | #include 16 | 17 | #define _802_3_SAP '1' 18 | #define _802_3_TYPE '2' 19 | 20 | static struct option opts[] = 21 | { 22 | { "802_3-sap" , required_argument, 0, _802_3_SAP }, 23 | { "802_3-type" , required_argument, 0, _802_3_TYPE }, 24 | { 0 } 25 | }; 26 | 27 | static void print_help() 28 | { 29 | printf( 30 | "802_3 options:\n" 31 | "--802_3-sap [!] protocol : 802.3 DSAP/SSAP- 1 byte value (hex)\n" 32 | " DSAP and SSAP are always the same. One SAP applies to both fields\n" 33 | "--802_3-type [!] protocol : 802.3 SNAP Type- 2 byte value (hex)\n" 34 | " Type implies SAP value 0xaa\n"); 35 | } 36 | 37 | static void init(struct ebt_entry_match *match) 38 | { 39 | struct ebt_802_3_info *info = (struct ebt_802_3_info *)match->data; 40 | 41 | info->invflags = 0; 42 | info->bitmask = 0; 43 | } 44 | 45 | static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, 46 | unsigned int *flags, struct ebt_entry_match **match) 47 | { 48 | struct ebt_802_3_info *info = (struct ebt_802_3_info *) (*match)->data; 49 | unsigned int i; 50 | char *end; 51 | 52 | switch (c) { 53 | case _802_3_SAP: 54 | ebt_check_option2(flags, _802_3_SAP); 55 | if (ebt_check_inverse2(optarg)) 56 | info->invflags |= EBT_802_3_SAP; 57 | i = strtoul(optarg, &end, 16); 58 | if (i > 255 || *end != '\0') 59 | ebt_print_error2("Problem with specified " 60 | "sap hex value, %x",i); 61 | info->sap = i; /* one byte, so no byte order worries */ 62 | info->bitmask |= EBT_802_3_SAP; 63 | break; 64 | case _802_3_TYPE: 65 | ebt_check_option2(flags, _802_3_TYPE); 66 | if (ebt_check_inverse2(optarg)) 67 | info->invflags |= EBT_802_3_TYPE; 68 | i = strtoul(optarg, &end, 16); 69 | if (i > 65535 || *end != '\0') { 70 | ebt_print_error2("Problem with the specified " 71 | "type hex value, %x",i); 72 | } 73 | info->type = htons(i); 74 | info->bitmask |= EBT_802_3_TYPE; 75 | break; 76 | default: 77 | return 0; 78 | } 79 | return 1; 80 | } 81 | 82 | static void final_check(const struct ebt_u_entry *entry, 83 | const struct ebt_entry_match *match, const char *name, 84 | unsigned int hookmask, unsigned int time) 85 | { 86 | if (!(entry->bitmask & EBT_802_3)) 87 | ebt_print_error("For 802.3 DSAP/SSAP filtering the protocol " 88 | "must be LENGTH"); 89 | } 90 | 91 | static void print(const struct ebt_u_entry *entry, 92 | const struct ebt_entry_match *match) 93 | { 94 | struct ebt_802_3_info *info = (struct ebt_802_3_info *)match->data; 95 | 96 | if (info->bitmask & EBT_802_3_SAP) { 97 | printf("--802_3-sap "); 98 | if (info->invflags & EBT_802_3_SAP) 99 | printf("! "); 100 | printf("0x%.2x ", info->sap); 101 | } 102 | if (info->bitmask & EBT_802_3_TYPE) { 103 | printf("--802_3-type "); 104 | if (info->invflags & EBT_802_3_TYPE) 105 | printf("! "); 106 | printf("0x%.4x ", ntohs(info->type)); 107 | } 108 | } 109 | 110 | static int compare(const struct ebt_entry_match *m1, 111 | const struct ebt_entry_match *m2) 112 | { 113 | struct ebt_802_3_info *info1 = (struct ebt_802_3_info *)m1->data; 114 | struct ebt_802_3_info *info2 = (struct ebt_802_3_info *)m2->data; 115 | 116 | if (info1->bitmask != info2->bitmask) 117 | return 0; 118 | if (info1->invflags != info2->invflags) 119 | return 0; 120 | if (info1->bitmask & EBT_802_3_SAP) { 121 | if (info1->sap != info2->sap) 122 | return 0; 123 | } 124 | if (info1->bitmask & EBT_802_3_TYPE) { 125 | if (info1->type != info2->type) 126 | return 0; 127 | } 128 | return 1; 129 | } 130 | 131 | static struct ebt_u_match _802_3_match = 132 | { 133 | .name = "802_3", 134 | .size = sizeof(struct ebt_802_3_info), 135 | .help = print_help, 136 | .init = init, 137 | .parse = parse, 138 | .final_check = final_check, 139 | .print = print, 140 | .compare = compare, 141 | .extra_ops = opts, 142 | }; 143 | 144 | void _802_3_init(void) 145 | { 146 | ebt_register_match(&_802_3_match); 147 | } 148 | -------------------------------------------------------------------------------- /extensions/ebt_arpreply.c: -------------------------------------------------------------------------------- 1 | /* ebt_arpreply 2 | * 3 | * Authors: 4 | * Grzegorz Borowiak 5 | * Bart De Schuymer 6 | * 7 | * August, 2003 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "../include/ebtables_u.h" 15 | #include 16 | #include 17 | 18 | static int mac_supplied; 19 | 20 | #define REPLY_MAC '1' 21 | #define REPLY_TARGET '2' 22 | static struct option opts[] = 23 | { 24 | { "arpreply-mac" , required_argument, 0, REPLY_MAC }, 25 | { "arpreply-target" , required_argument, 0, REPLY_TARGET }, 26 | { 0 } 27 | }; 28 | 29 | static void print_help() 30 | { 31 | printf( 32 | "arpreply target options:\n" 33 | " --arpreply-mac address : source MAC of generated reply\n" 34 | " --arpreply-target target : ACCEPT, DROP, RETURN or CONTINUE\n" 35 | " (standard target is DROP)\n"); 36 | } 37 | 38 | static void init(struct ebt_entry_target *target) 39 | { 40 | struct ebt_arpreply_info *replyinfo = 41 | (struct ebt_arpreply_info *)target->data; 42 | 43 | replyinfo->target = EBT_DROP; 44 | memset(replyinfo->mac, 0, ETH_ALEN); 45 | mac_supplied = 0; 46 | } 47 | 48 | #define OPT_REPLY_MAC 0x01 49 | #define OPT_REPLY_TARGET 0x02 50 | static int parse(int c, char **argv, int argc, 51 | const struct ebt_u_entry *entry, unsigned int *flags, 52 | struct ebt_entry_target **target) 53 | { 54 | struct ebt_arpreply_info *replyinfo = 55 | (struct ebt_arpreply_info *)(*target)->data; 56 | struct ether_addr *addr; 57 | 58 | switch (c) { 59 | case REPLY_MAC: 60 | ebt_check_option2(flags, OPT_REPLY_MAC); 61 | if (!(addr = ether_aton(optarg))) 62 | ebt_print_error2("Problem with specified --arpreply-mac mac"); 63 | memcpy(replyinfo->mac, addr, ETH_ALEN); 64 | mac_supplied = 1; 65 | break; 66 | case REPLY_TARGET: 67 | ebt_check_option2(flags, OPT_REPLY_TARGET); 68 | if (FILL_TARGET(optarg, replyinfo->target)) 69 | ebt_print_error2("Illegal --arpreply-target target"); 70 | break; 71 | 72 | default: 73 | return 0; 74 | } 75 | return 1; 76 | } 77 | 78 | static void final_check(const struct ebt_u_entry *entry, 79 | const struct ebt_entry_target *target, const char *name, 80 | unsigned int hookmask, unsigned int time) 81 | { 82 | struct ebt_arpreply_info *replyinfo = 83 | (struct ebt_arpreply_info *)target->data; 84 | 85 | if (entry->ethproto != ETH_P_ARP || entry->invflags & EBT_IPROTO) { 86 | ebt_print_error("For ARP replying the protocol must be specified as ARP"); 87 | } else if (time == 0 && mac_supplied == 0) { 88 | ebt_print_error("No arpreply mac supplied"); 89 | } else if (BASE_CHAIN && replyinfo->target == EBT_RETURN) { 90 | ebt_print_error("--arpreply-target RETURN not allowed on base chain"); 91 | } else { 92 | CLEAR_BASE_CHAIN_BIT; 93 | if (strcmp(name, "nat") || hookmask & ~(1 << NF_BR_PRE_ROUTING)) 94 | ebt_print_error("arpreply only allowed in PREROUTING"); 95 | } 96 | } 97 | 98 | static void print(const struct ebt_u_entry *entry, 99 | const struct ebt_entry_target *target) 100 | { 101 | struct ebt_arpreply_info *replyinfo = 102 | (struct ebt_arpreply_info *)target->data; 103 | 104 | printf("--arpreply-mac "); 105 | ebt_print_mac(replyinfo->mac); 106 | if (replyinfo->target == EBT_DROP) 107 | return; 108 | printf(" --arpreply-target %s", TARGET_NAME(replyinfo->target)); 109 | } 110 | 111 | static int compare(const struct ebt_entry_target *t1, 112 | const struct ebt_entry_target *t2) 113 | { 114 | struct ebt_arpreply_info *replyinfo1 = 115 | (struct ebt_arpreply_info *)t1->data; 116 | struct ebt_arpreply_info *replyinfo2 = 117 | (struct ebt_arpreply_info *)t2->data; 118 | 119 | return memcmp(replyinfo1->mac, replyinfo2->mac, ETH_ALEN) == 0 120 | && replyinfo1->target == replyinfo2->target; 121 | } 122 | 123 | static struct ebt_u_target arpreply_target = 124 | { 125 | .name = "arpreply", 126 | .size = sizeof(struct ebt_arpreply_info), 127 | .help = print_help, 128 | .init = init, 129 | .parse = parse, 130 | .final_check = final_check, 131 | .print = print, 132 | .compare = compare, 133 | .extra_ops = opts, 134 | }; 135 | 136 | void _arpreply_init(void) 137 | { 138 | ebt_register_target(&arpreply_target); 139 | } 140 | -------------------------------------------------------------------------------- /userspace/ebtables2/Android.mk: -------------------------------------------------------------------------------- 1 | # BUILD libebtc.so 2 | 3 | LOCAL_PATH:= $(call my-dir) 4 | 5 | include $(CLEAR_VARS) 6 | 7 | LOCAL_SRC_FILES := getethertype.c 8 | LOCAL_SRC_FILES += communication.c 9 | LOCAL_SRC_FILES += libebtc.c 10 | LOCAL_SRC_FILES += useful_functions.c 11 | LOCAL_SRC_FILES += ebtables.c 12 | 13 | LOCAL_C_INCLUDES := $(LOCAL_PATH)/include 14 | LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include 15 | LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr 16 | 17 | LOCAL_CFLAGS += -DPROGNAME=\"ebtables\" \ 18 | -DPROGVERSION=\"2.0.10\" \ 19 | -DPROGDATE=\"December\ 2011\" \ 20 | -D__THROW= 21 | 22 | LOCAL_CFLAGS += -O2 -g -Wno-ignored-qualifiers 23 | LOCAL_CFLAGS += -Wno-sign-compare \ 24 | -Wno-missing-field-initializers \ 25 | -Wno-pointer-arith 26 | 27 | LOCAL_MODULE := libebtc 28 | 29 | LOCAL_MODULE_TAGS := optional 30 | 31 | include $(BUILD_SHARED_LIBRARY) 32 | 33 | # sources and intermediate files are separated 34 | 35 | c_includes := $(LOCAL_PATH)/include 36 | c_includes += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include 37 | local_additional_dependencies := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr 38 | 39 | cflags := -O2 -g \ 40 | -DPROGNAME=\"ebtables\" \ 41 | -DPROGVERSION=\"2.0.10\" \ 42 | -DPROGDATE=\"December\ 2011\" \ 43 | -Wno-sign-compare -Wno-missing-field-initializers \ 44 | -Wno-ignored-qualifiers 45 | 46 | extensions_src_files := \ 47 | extensions/ebt_802_3.c \ 48 | extensions/ebt_among.c \ 49 | extensions/ebt_arp.c \ 50 | extensions/ebt_arpreply.c \ 51 | extensions/ebt_ip.c \ 52 | extensions/ebt_ip6.c \ 53 | extensions/ebt_limit.c \ 54 | extensions/ebt_log.c \ 55 | extensions/ebt_mark.c \ 56 | extensions/ebt_mark_m.c \ 57 | extensions/ebt_nat.c \ 58 | extensions/ebt_nflog.c \ 59 | extensions/ebt_pkttype.c \ 60 | extensions/ebt_redirect.c \ 61 | extensions/ebt_standard.c \ 62 | extensions/ebt_stp.c \ 63 | extensions/ebt_vlan.c \ 64 | extensions/ebtable_broute.c \ 65 | extensions/ebtable_filter.c \ 66 | extensions/ebtable_nat.c 67 | 68 | ld_flags := -nostartfiles 69 | shared_libs := libebtc 70 | module_tags := eng 71 | 72 | $(foreach file,$(extensions_src_files), \ 73 | $(eval include $(CLEAR_VARS)) \ 74 | $(eval LOCAL_C_INCLUDES := $(c_includes)) \ 75 | $(eval LOCAL_ADDITIONAL_DEPENDENCIES := $(local_additional_dependencies)) \ 76 | $(eval LOCAL_SRC_FILES := $(file)) \ 77 | $(eval tmp_file := $(notdir $(file:%.c=%))) \ 78 | $(eval tmp_file := $(addprefix lib, $(tmp_file))) \ 79 | $(eval LOCAL_MODULE := $(tmp_file)) \ 80 | $(eval LOCAL_MODULE_TAGS := $(module_tags)) \ 81 | $(eval LOCAL_LDFLAGS := $(ld_flags)) \ 82 | $(eval LOCAL_CFLAGS := $(cflags)) \ 83 | $(eval LOCAL_SHARED_LIBRARIES := $(shared_libs)) \ 84 | $(eval include $(BUILD_SHARED_LIBRARY)) \ 85 | ) 86 | 87 | 88 | ############################### 89 | include $(CLEAR_VARS) 90 | 91 | LOCAL_C_INCLUDES := $(LOCAL_PATH)/include 92 | LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include 93 | LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr 94 | 95 | LOCAL_CFLAGS += -DPROGNAME=\"ebtables\" \ 96 | -DPROGVERSION=\"2.0.10\" \ 97 | -DPROGDATE=\"December\ 2011\" 98 | 99 | LOCAL_SRC_FILES := ebtables-standalone.c 100 | 101 | LOCAL_SHARED_LIBRARIES += \ 102 | libebtc \ 103 | libebt_802_3 \ 104 | libebt_among \ 105 | libebt_arp \ 106 | libebt_arpreply \ 107 | libebt_ip \ 108 | libebt_ip6 \ 109 | libebt_limit \ 110 | libebt_log \ 111 | libebt_mark \ 112 | libebt_mark_m \ 113 | libebt_nat \ 114 | libebt_nflog \ 115 | libebt_pkttype \ 116 | libebt_redirect \ 117 | libebt_standard \ 118 | libebt_stp \ 119 | libebt_vlan \ 120 | libebtable_broute \ 121 | libebtable_filter \ 122 | libebtable_nat 123 | 124 | LOCAL_MODULE := ebtables 125 | 126 | LOCAL_MODULE_TAGS := optional 127 | 128 | include $(BUILD_EXECUTABLE) 129 | 130 | 131 | #######dss_test_104########## 132 | include $(CLEAR_VARS) 133 | LOCAL_MODULE:= ethertypes 134 | LOCAL_MODULE_CLASS := EXECUTABLES 135 | LOCAL_SRC_FILES := ethertypes 136 | LOCAL_MODULE_TAGS := optional 137 | LOCAL_MODULE_PATH := $(TARGET_OUT_ETC) 138 | include $(BUILD_PREBUILT) 139 | 140 | -------------------------------------------------------------------------------- /getethertype.c: -------------------------------------------------------------------------------- 1 | /* 2 | * getethertype.c 3 | * 4 | * This file was part of the NYS Library. 5 | * 6 | ** The NYS Library is free software; you can redistribute it and/or 7 | ** modify it under the terms of the GNU Library General Public License as 8 | ** published by the Free Software Foundation; either version 2 of the 9 | ** License, or (at your option) any later version. 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License 22 | * along with this program; if not, write to the Free Software 23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 | */ 25 | 26 | /******************************************************************** 27 | * Description: Ethertype name service switch and the ethertypes 28 | * database access functions 29 | * Author: Nick Fedchik 30 | * Checker: Bart De Schuymer 31 | * Origin: uClibc-0.9.16/libc/inet/getproto.c 32 | * Created at: Mon Nov 11 12:20:11 EET 2002 33 | ********************************************************************/ 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | 46 | #include "ethernetdb.h" 47 | 48 | #define MAXALIASES 35 49 | 50 | static FILE *etherf = NULL; 51 | static char line[BUFSIZ + 1]; 52 | static struct ethertypeent et_ent; 53 | static char *ethertype_aliases[MAXALIASES]; 54 | static int ethertype_stayopen; 55 | 56 | void setethertypeent(int f) 57 | { 58 | if (etherf == NULL) 59 | etherf = fopen(_PATH_ETHERTYPES, "r"); 60 | else 61 | rewind(etherf); 62 | ethertype_stayopen |= f; 63 | } 64 | 65 | void endethertypeent(void) 66 | { 67 | if (etherf) { 68 | fclose(etherf); 69 | etherf = NULL; 70 | } 71 | ethertype_stayopen = 0; 72 | } 73 | 74 | struct ethertypeent *getethertypeent(void) 75 | { 76 | char *e; 77 | char *endptr; 78 | register char *cp, **q; 79 | 80 | if (etherf == NULL 81 | && (etherf = fopen(_PATH_ETHERTYPES, "r")) == NULL) { 82 | return (NULL); 83 | } 84 | 85 | again: 86 | if ((e = fgets(line, BUFSIZ, etherf)) == NULL) { 87 | return (NULL); 88 | } 89 | if (*e == '#') 90 | goto again; 91 | cp = strpbrk(e, "#\n"); 92 | if (cp == NULL) 93 | goto again; 94 | *cp = '\0'; 95 | et_ent.e_name = e; 96 | cp = strpbrk(e, " \t"); 97 | if (cp == NULL) 98 | goto again; 99 | *cp++ = '\0'; 100 | while (*cp == ' ' || *cp == '\t') 101 | cp++; 102 | e = strpbrk(cp, " \t"); 103 | if (e != NULL) 104 | *e++ = '\0'; 105 | // Check point 106 | et_ent.e_ethertype = strtol(cp, &endptr, 16); 107 | if (*endptr != '\0' 108 | || (et_ent.e_ethertype < ETH_ZLEN 109 | || et_ent.e_ethertype > 0xFFFF)) 110 | goto again; // Skip invalid etherproto type entry 111 | q = et_ent.e_aliases = ethertype_aliases; 112 | if (e != NULL) { 113 | cp = e; 114 | while (cp && *cp) { 115 | if (*cp == ' ' || *cp == '\t') { 116 | cp++; 117 | continue; 118 | } 119 | if (q < ðertype_aliases[MAXALIASES - 1]) 120 | *q++ = cp; 121 | cp = strpbrk(cp, " \t"); 122 | if (cp != NULL) 123 | *cp++ = '\0'; 124 | } 125 | } 126 | *q = NULL; 127 | return (&et_ent); 128 | } 129 | 130 | 131 | struct ethertypeent *getethertypebyname(const char *name) 132 | { 133 | register struct ethertypeent *e; 134 | register char **cp; 135 | 136 | setethertypeent(ethertype_stayopen); 137 | while ((e = getethertypeent()) != NULL) { 138 | if (strcasecmp(e->e_name, name) == 0) 139 | break; 140 | for (cp = e->e_aliases; *cp != 0; cp++) 141 | if (strcasecmp(*cp, name) == 0) 142 | goto found; 143 | } 144 | found: 145 | if (!ethertype_stayopen) 146 | endethertypeent(); 147 | return (e); 148 | } 149 | 150 | struct ethertypeent *getethertypebynumber(int type) 151 | { 152 | register struct ethertypeent *e; 153 | 154 | setethertypeent(ethertype_stayopen); 155 | while ((e = getethertypeent()) != NULL) 156 | if (e->e_ethertype == type) 157 | break; 158 | if (!ethertype_stayopen) 159 | endethertypeent(); 160 | return (e); 161 | } 162 | -------------------------------------------------------------------------------- /ebtables-restore.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ebtables-restore.c, October 2005 3 | * 4 | * Author: Bart De Schuymer 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License as 8 | * published by the Free Software Foundation; either version 2 of the 9 | * License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, but 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 | */ 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include "include/ebtables_u.h" 26 | 27 | static struct ebt_u_replace replace[3]; 28 | void ebt_early_init_once(); 29 | 30 | #define OPT_KERNELDATA 0x800 /* Also defined in ebtables.c */ 31 | 32 | static void copy_table_names() 33 | { 34 | strcpy(replace[0].name, "filter"); 35 | strcpy(replace[1].name, "nat"); 36 | strcpy(replace[2].name, "broute"); 37 | } 38 | 39 | #define ebtrest_print_error(format, args...) do {fprintf(stderr, "ebtables-restore: "\ 40 | "line %d: "format".\n", line, ##args); exit(-1);} while (0) 41 | int main(int argc_, char *argv_[]) 42 | { 43 | char *argv[EBTD_ARGC_MAX], cmdline[EBTD_CMDLINE_MAXLN]; 44 | int i, offset, quotemode = 0, argc, table_nr = -1, line = 0, whitespace; 45 | char ebtables_str[] = "ebtables"; 46 | 47 | if (argc_ != 1) 48 | ebtrest_print_error("options are not supported"); 49 | ebt_silent = 0; 50 | copy_table_names(); 51 | ebt_early_init_once(); 52 | argv[0] = ebtables_str; 53 | 54 | while (fgets(cmdline, EBTD_CMDLINE_MAXLN, stdin)) { 55 | line++; 56 | if (*cmdline == '#' || *cmdline == '\n') 57 | continue; 58 | *strchr(cmdline, '\n') = '\0'; 59 | if (*cmdline == '*') { 60 | if (table_nr != -1) { 61 | ebt_deliver_table(&replace[table_nr]); 62 | ebt_deliver_counters(&replace[table_nr]); 63 | } 64 | for (i = 0; i < 3; i++) 65 | if (!strcmp(replace[i].name, cmdline+1)) 66 | break; 67 | if (i == 3) 68 | ebtrest_print_error("table '%s' was not recognized", cmdline+1); 69 | table_nr = i; 70 | replace[table_nr].command = 11; 71 | ebt_get_kernel_table(&replace[table_nr], 1); 72 | replace[table_nr].command = 0; 73 | replace[table_nr].flags = OPT_KERNELDATA; /* Prevent do_command from initialising replace */ 74 | continue; 75 | } else if (table_nr == -1) 76 | ebtrest_print_error("no table specified"); 77 | if (*cmdline == ':') { 78 | int policy, chain_nr; 79 | char *ch; 80 | 81 | if (!(ch = strchr(cmdline, ' '))) 82 | ebtrest_print_error("no policy specified"); 83 | *ch = '\0'; 84 | for (i = 0; i < NUM_STANDARD_TARGETS; i++) 85 | if (!strcmp(ch+1, ebt_standard_targets[i])) { 86 | policy = -i -1; 87 | if (policy == EBT_CONTINUE) 88 | i = NUM_STANDARD_TARGETS; 89 | break; 90 | } 91 | if (i == NUM_STANDARD_TARGETS) 92 | ebtrest_print_error("invalid policy specified"); 93 | /* No need to check chain name for consistency, since 94 | * we're supposed to be reading an automatically generated 95 | * file. */ 96 | if ((chain_nr = ebt_get_chainnr(&replace[table_nr], cmdline+1)) == -1) 97 | ebt_new_chain(&replace[table_nr], cmdline+1, policy); 98 | else 99 | replace[table_nr].chains[chain_nr]->policy = policy; 100 | continue; 101 | } 102 | argv[1] = cmdline; 103 | offset = whitespace = 0; 104 | argc = 2; 105 | while (cmdline[offset] != '\0') { 106 | if (cmdline[offset] == '\"') { 107 | whitespace = 0; 108 | quotemode ^= 1; 109 | if (quotemode) 110 | argv[argc++] = &cmdline[offset+1]; 111 | else if (cmdline[offset+1] != ' ' && cmdline[offset+1] != '\0') 112 | ebtrest_print_error("syntax error at \""); 113 | cmdline[offset] = '\0'; 114 | } else if (!quotemode && cmdline[offset] == ' ') { 115 | whitespace = 1; 116 | cmdline[offset] = '\0'; 117 | } else if (whitespace == 1) { 118 | argv[argc++] = &cmdline[offset]; 119 | whitespace = 0; 120 | } 121 | offset++; 122 | } 123 | if (quotemode) 124 | ebtrest_print_error("wrong use of '\"'"); 125 | optind = 0; /* Setting optind = 1 causes serious annoyances */ 126 | do_command(argc, argv, EXEC_STYLE_DAEMON, &replace[table_nr]); 127 | ebt_reinit_extensions(); 128 | } 129 | 130 | if (table_nr != -1) { 131 | ebt_deliver_table(&replace[table_nr]); 132 | ebt_deliver_counters(&replace[table_nr]); 133 | } 134 | return 0; 135 | } 136 | -------------------------------------------------------------------------------- /extensions/ebt_nflog.c: -------------------------------------------------------------------------------- 1 | /* ebt_nflog 2 | * 3 | * Authors: 4 | * Peter Warasin 5 | * 6 | * February, 2008 7 | * 8 | * Based on: 9 | * ebt_ulog.c, (C) 2004, Bart De Schuymer 10 | * libxt_NFLOG.c 11 | */ 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "../include/ebtables_u.h" 18 | #include 19 | 20 | enum { 21 | NFLOG_GROUP = 0x1, 22 | NFLOG_PREFIX = 0x2, 23 | NFLOG_RANGE = 0x4, 24 | NFLOG_THRESHOLD = 0x8, 25 | NFLOG_NFLOG = 0x16, 26 | }; 27 | 28 | static struct option nflog_opts[] = { 29 | {"nflog-group", required_argument, NULL, NFLOG_GROUP}, 30 | {"nflog-prefix", required_argument, NULL, NFLOG_PREFIX}, 31 | {"nflog-range", required_argument, NULL, NFLOG_RANGE}, 32 | {"nflog-threshold", required_argument, NULL, NFLOG_THRESHOLD}, 33 | {"nflog", no_argument, NULL, NFLOG_NFLOG}, 34 | {.name = NULL} 35 | }; 36 | 37 | static void nflog_help() 38 | { 39 | printf("nflog options:\n" 40 | "--nflog : use the default nflog parameters\n" 41 | "--nflog-prefix prefix : Prefix string for log message\n" 42 | "--nflog-group group : NETLINK group used for logging\n" 43 | "--nflog-range range : Number of byte to copy\n" 44 | "--nflog-threshold : Message threshold of" 45 | "in-kernel queue\n"); 46 | } 47 | 48 | static void init(struct ebt_entry_watcher *watcher) 49 | { 50 | struct ebt_nflog_info *info = (struct ebt_nflog_info *)watcher->data; 51 | 52 | info->prefix[0] = '\0'; 53 | info->group = EBT_NFLOG_DEFAULT_GROUP; 54 | info->threshold = EBT_NFLOG_DEFAULT_THRESHOLD; 55 | } 56 | 57 | static int nflog_parse(int c, char **argv, int argc, 58 | const struct ebt_u_entry *entry, unsigned int *flags, 59 | struct ebt_entry_watcher **watcher) 60 | { 61 | struct ebt_nflog_info *info; 62 | unsigned int i; 63 | char *end; 64 | 65 | info = (struct ebt_nflog_info *)(*watcher)->data; 66 | switch (c) { 67 | case NFLOG_PREFIX: 68 | if (ebt_check_inverse2(optarg)) 69 | goto inverse_invalid; 70 | ebt_check_option2(flags, NFLOG_PREFIX); 71 | if (strlen(optarg) > EBT_NFLOG_PREFIX_SIZE - 1) 72 | ebt_print_error("Prefix too long for nflog-prefix"); 73 | strcpy(info->prefix, optarg); 74 | break; 75 | 76 | case NFLOG_GROUP: 77 | if (ebt_check_inverse2(optarg)) 78 | goto inverse_invalid; 79 | ebt_check_option2(flags, NFLOG_GROUP); 80 | i = strtoul(optarg, &end, 10); 81 | if (*end != '\0') 82 | ebt_print_error2("--nflog-group must be a number!"); 83 | info->group = i; 84 | break; 85 | 86 | case NFLOG_RANGE: 87 | if (ebt_check_inverse2(optarg)) 88 | goto inverse_invalid; 89 | ebt_check_option2(flags, NFLOG_RANGE); 90 | i = strtoul(optarg, &end, 10); 91 | if (*end != '\0') 92 | ebt_print_error2("--nflog-range must be a number!"); 93 | info->len = i; 94 | break; 95 | 96 | case NFLOG_THRESHOLD: 97 | if (ebt_check_inverse2(optarg)) 98 | goto inverse_invalid; 99 | ebt_check_option2(flags, NFLOG_THRESHOLD); 100 | i = strtoul(optarg, &end, 10); 101 | if (*end != '\0') 102 | ebt_print_error2("--nflog-threshold must be a number!"); 103 | info->threshold = i; 104 | break; 105 | case NFLOG_NFLOG: 106 | if (ebt_check_inverse(optarg)) 107 | goto inverse_invalid; 108 | ebt_check_option2(flags, NFLOG_NFLOG); 109 | break; 110 | 111 | default: 112 | return 0; 113 | } 114 | return 1; 115 | 116 | inverse_invalid: 117 | ebt_print_error("The use of '!' makes no sense for the nflog watcher"); 118 | return 1; 119 | } 120 | 121 | static void nflog_final_check(const struct ebt_u_entry *entry, 122 | const struct ebt_entry_watcher *watcher, 123 | const char *name, unsigned int hookmask, 124 | unsigned int time) 125 | { 126 | } 127 | 128 | static void nflog_print(const struct ebt_u_entry *entry, 129 | const struct ebt_entry_watcher *watcher) 130 | { 131 | struct ebt_nflog_info *info = (struct ebt_nflog_info *)watcher->data; 132 | 133 | if (info->prefix[0] != '\0') 134 | printf("--nflog-prefix \"%s\"", info->prefix); 135 | if (info->group) 136 | printf("--nflog-group %d ", info->group); 137 | if (info->len) 138 | printf("--nflog-range %d", info->len); 139 | if (info->threshold != EBT_NFLOG_DEFAULT_THRESHOLD) 140 | printf(" --nflog-threshold %d ", info->threshold); 141 | } 142 | 143 | static int nflog_compare(const struct ebt_entry_watcher *w1, 144 | const struct ebt_entry_watcher *w2) 145 | { 146 | struct ebt_nflog_info *info1 = (struct ebt_nflog_info *)w1->data; 147 | struct ebt_nflog_info *info2 = (struct ebt_nflog_info *)w2->data; 148 | 149 | if (info1->group != info2->group || 150 | info1->len != info2->len || 151 | info1->threshold != info2->threshold || 152 | strcmp(info1->prefix, info2->prefix)) 153 | return 0; 154 | return 1; 155 | } 156 | 157 | static struct ebt_u_watcher nflog_watcher = { 158 | .name = "nflog", 159 | .size = sizeof(struct ebt_nflog_info), 160 | .help = nflog_help, 161 | .init = init, 162 | .parse = nflog_parse, 163 | .final_check = nflog_final_check, 164 | .print = nflog_print, 165 | .compare = nflog_compare, 166 | .extra_ops = nflog_opts, 167 | }; 168 | 169 | void _nflog_init(void) 170 | { 171 | ebt_register_watcher(&nflog_watcher); 172 | } 173 | -------------------------------------------------------------------------------- /extensions/ebt_limit.c: -------------------------------------------------------------------------------- 1 | /* ebt_limit 2 | * 3 | * Authors: 4 | * Tom Marshall 5 | * 6 | * Mostly copied from iptables' limit match. 7 | * 8 | * September, 2003 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include "../include/ebtables_u.h" 17 | #include 18 | 19 | #define EBT_LIMIT_AVG "3/hour" 20 | #define EBT_LIMIT_BURST 5 21 | 22 | static int string_to_number(const char *s, unsigned int min, unsigned int max, 23 | unsigned int *ret) 24 | { 25 | long number; 26 | char *end; 27 | 28 | errno = 0; 29 | number = strtol(s, &end, 0); 30 | if (*end == '\0' && end != s) { 31 | if (errno != ERANGE && min <= number && number <= max) { 32 | *ret = number; 33 | return 0; 34 | } 35 | } 36 | return -1; 37 | } 38 | 39 | #define FLAG_LIMIT 0x01 40 | #define FLAG_LIMIT_BURST 0x02 41 | #define ARG_LIMIT '1' 42 | #define ARG_LIMIT_BURST '2' 43 | 44 | static struct option opts[] = 45 | { 46 | { "limit", required_argument, 0, ARG_LIMIT }, 47 | { "limit-burst", required_argument, 0, ARG_LIMIT_BURST }, 48 | { 0 } 49 | }; 50 | 51 | static void print_help(void) 52 | { 53 | printf( 54 | "limit options:\n" 55 | "--limit avg : max average match rate: default "EBT_LIMIT_AVG"\n" 56 | " [Packets per second unless followed by \n" 57 | " /sec /minute /hour /day postfixes]\n" 58 | "--limit-burst number : number to match in a burst, -1 < number < 10001,\n" 59 | " default %u\n", EBT_LIMIT_BURST); 60 | } 61 | 62 | static int parse_rate(const char *rate, u_int32_t *val) 63 | { 64 | const char *delim; 65 | u_int32_t r; 66 | u_int32_t mult = 1; /* Seconds by default. */ 67 | 68 | delim = strchr(rate, '/'); 69 | if (delim) { 70 | if (strlen(delim+1) == 0) 71 | return 0; 72 | 73 | if (strncasecmp(delim+1, "second", strlen(delim+1)) == 0) 74 | mult = 1; 75 | else if (strncasecmp(delim+1, "minute", strlen(delim+1)) == 0) 76 | mult = 60; 77 | else if (strncasecmp(delim+1, "hour", strlen(delim+1)) == 0) 78 | mult = 60*60; 79 | else if (strncasecmp(delim+1, "day", strlen(delim+1)) == 0) 80 | mult = 24*60*60; 81 | else 82 | return 0; 83 | } 84 | r = atoi(rate); 85 | if (!r) 86 | return 0; 87 | 88 | /* This would get mapped to infinite (1/day is minimum they 89 | can specify, so we're ok at that end). */ 90 | if (r / mult > EBT_LIMIT_SCALE) 91 | return 0; 92 | 93 | *val = EBT_LIMIT_SCALE * mult / r; 94 | return 1; 95 | } 96 | 97 | /* Initialize the match. */ 98 | static void init(struct ebt_entry_match *m) 99 | { 100 | struct ebt_limit_info *r = (struct ebt_limit_info *)m->data; 101 | 102 | parse_rate(EBT_LIMIT_AVG, &r->avg); 103 | r->burst = EBT_LIMIT_BURST; 104 | } 105 | 106 | /* FIXME: handle overflow: 107 | if (r->avg*r->burst/r->burst != r->avg) 108 | exit_error(PARAMETER_PROBLEM, 109 | "Sorry: burst too large for that avg rate.\n"); 110 | */ 111 | 112 | static int parse(int c, char **argv, int argc, 113 | const struct ebt_u_entry *entry, 114 | unsigned int *flags, 115 | struct ebt_entry_match **match) 116 | { 117 | struct ebt_limit_info *r = (struct ebt_limit_info *)(*match)->data; 118 | unsigned int num; 119 | 120 | switch(c) { 121 | case ARG_LIMIT: 122 | ebt_check_option2(flags, FLAG_LIMIT); 123 | if (ebt_check_inverse2(optarg)) 124 | ebt_print_error2("Unexpected `!' after --limit"); 125 | if (!parse_rate(optarg, &r->avg)) 126 | ebt_print_error2("bad rate `%s'", optarg); 127 | break; 128 | 129 | case ARG_LIMIT_BURST: 130 | ebt_check_option2(flags, FLAG_LIMIT_BURST); 131 | if (ebt_check_inverse2(optarg)) 132 | ebt_print_error2("Unexpected `!' after --limit-burst"); 133 | if (string_to_number(optarg, 0, 10000, &num) == -1) 134 | ebt_print_error2("bad --limit-burst `%s'", optarg); 135 | r->burst = num; 136 | break; 137 | 138 | default: 139 | return 0; 140 | } 141 | 142 | return 1; 143 | } 144 | 145 | static void final_check(const struct ebt_u_entry *entry, 146 | const struct ebt_entry_match *match, const char *name, 147 | unsigned int hookmask, unsigned int time) 148 | { 149 | } 150 | 151 | struct rates 152 | { 153 | const char *name; 154 | u_int32_t mult; 155 | }; 156 | 157 | static struct rates g_rates[] = 158 | { 159 | { "day", EBT_LIMIT_SCALE*24*60*60 }, 160 | { "hour", EBT_LIMIT_SCALE*60*60 }, 161 | { "min", EBT_LIMIT_SCALE*60 }, 162 | { "sec", EBT_LIMIT_SCALE } 163 | }; 164 | 165 | static void print_rate(u_int32_t period) 166 | { 167 | unsigned int i; 168 | 169 | for (i = 1; i < sizeof(g_rates)/sizeof(struct rates); i++) 170 | if (period > g_rates[i].mult || 171 | g_rates[i].mult/period < g_rates[i].mult%period) 172 | break; 173 | 174 | printf("%u/%s ", g_rates[i-1].mult / period, g_rates[i-1].name); 175 | } 176 | 177 | static void print(const struct ebt_u_entry *entry, 178 | const struct ebt_entry_match *match) 179 | { 180 | struct ebt_limit_info *r = (struct ebt_limit_info *)match->data; 181 | 182 | printf("--limit "); 183 | print_rate(r->avg); 184 | printf("--limit-burst %u ", r->burst); 185 | } 186 | 187 | static int compare(const struct ebt_entry_match* m1, 188 | const struct ebt_entry_match *m2) 189 | { 190 | struct ebt_limit_info* li1 = (struct ebt_limit_info*)m1->data; 191 | struct ebt_limit_info* li2 = (struct ebt_limit_info*)m2->data; 192 | 193 | if (li1->avg != li2->avg) 194 | return 0; 195 | 196 | if (li1->burst != li2->burst) 197 | return 0; 198 | 199 | return 1; 200 | } 201 | 202 | static struct ebt_u_match limit_match = 203 | { 204 | .name = "limit", 205 | .size = sizeof(struct ebt_limit_info), 206 | .help = print_help, 207 | .init = init, 208 | .parse = parse, 209 | .final_check = final_check, 210 | .print = print, 211 | .compare = compare, 212 | .extra_ops = opts, 213 | }; 214 | 215 | void _limit_init(void) 216 | { 217 | ebt_register_match(&limit_match); 218 | } 219 | -------------------------------------------------------------------------------- /extensions/ebt_ulog.c: -------------------------------------------------------------------------------- 1 | /* ebt_ulog 2 | * 3 | * Authors: 4 | * Bart De Schuymer 5 | * 6 | * November, 2004 7 | */ 8 | 9 | #define __need_time_t 10 | #define __need_suseconds_t 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include "../include/ebtables_u.h" 16 | #include 17 | #include 18 | 19 | #define CP_NO_LIMIT_S "default_cprange" 20 | #define CP_NO_LIMIT_N 0 21 | 22 | #define ULOG_PREFIX '1' 23 | #define ULOG_NLGROUP '2' 24 | #define ULOG_CPRANGE '3' 25 | #define ULOG_QTHRESHOLD '4' 26 | #define ULOG_ULOG '5' 27 | static struct option opts[] = 28 | { 29 | { "ulog-prefix" , required_argument, 0, ULOG_PREFIX }, 30 | { "ulog-nlgroup" , required_argument, 0, ULOG_NLGROUP }, 31 | { "ulog-cprange" , required_argument, 0, ULOG_CPRANGE }, 32 | { "ulog-qthreshold", required_argument, 0, ULOG_QTHRESHOLD }, 33 | { "ulog" , no_argument , 0, ULOG_ULOG }, 34 | { 0 } 35 | }; 36 | 37 | static void print_help() 38 | { 39 | printf( 40 | "ulog options:\n" 41 | "--ulog : use the default ulog parameters\n" 42 | "--ulog-prefix prefix : max %d characters (default is no prefix)\n" 43 | "--ulog-nlgroup group : 0 < group number < %d (default = %d)\n" 44 | "--ulog-cprange range : max copy range (default is " CP_NO_LIMIT_S ")\n" 45 | "--ulog-qthreshold : 0 < queueing threshold < %d (default = %d)\n", 46 | EBT_ULOG_PREFIX_LEN - 1, EBT_ULOG_MAXNLGROUPS + 1, 47 | EBT_ULOG_DEFAULT_NLGROUP + 1, EBT_ULOG_MAX_QLEN + 1, 48 | EBT_ULOG_DEFAULT_QTHRESHOLD); 49 | } 50 | 51 | static void init(struct ebt_entry_watcher *watcher) 52 | { 53 | struct ebt_ulog_info *uloginfo = (struct ebt_ulog_info *)watcher->data; 54 | 55 | uloginfo->prefix[0] = '\0'; 56 | uloginfo->nlgroup = EBT_ULOG_DEFAULT_NLGROUP; 57 | uloginfo->cprange = CP_NO_LIMIT_N; /* Use default netlink buffer size */ 58 | uloginfo->qthreshold = EBT_ULOG_DEFAULT_QTHRESHOLD; 59 | } 60 | 61 | #define OPT_PREFIX 0x01 62 | #define OPT_NLGROUP 0x02 63 | #define OPT_CPRANGE 0x04 64 | #define OPT_QTHRESHOLD 0x08 65 | #define OPT_ULOG 0x10 66 | static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, 67 | unsigned int *flags, struct ebt_entry_watcher **watcher) 68 | { 69 | struct ebt_ulog_info *uloginfo; 70 | unsigned int i; 71 | char *end; 72 | 73 | uloginfo = (struct ebt_ulog_info *)(*watcher)->data; 74 | switch (c) { 75 | case ULOG_PREFIX: 76 | if (ebt_check_inverse2(optarg)) 77 | goto inverse_invalid; 78 | ebt_check_option2(flags, OPT_PREFIX); 79 | if (strlen(optarg) > EBT_ULOG_PREFIX_LEN - 1) 80 | ebt_print_error("Prefix too long for ulog-prefix"); 81 | strcpy(uloginfo->prefix, optarg); 82 | break; 83 | 84 | case ULOG_NLGROUP: 85 | if (ebt_check_inverse2(optarg)) 86 | goto inverse_invalid; 87 | ebt_check_option2(flags, OPT_NLGROUP); 88 | i = strtoul(optarg, &end, 10); 89 | if (*end != '\0') 90 | ebt_print_error2("Problem with ulog-nlgroup: %s", optarg); 91 | if (i < 1 || i > EBT_ULOG_MAXNLGROUPS) 92 | ebt_print_error2("the ulog-nlgroup number must be between 1 and 32"); 93 | uloginfo->nlgroup = i - 1; 94 | break; 95 | 96 | case ULOG_CPRANGE: 97 | if (ebt_check_inverse2(optarg)) 98 | goto inverse_invalid; 99 | ebt_check_option2(flags, OPT_CPRANGE); 100 | i = strtoul(optarg, &end, 10); 101 | if (*end != '\0') { 102 | if (strcasecmp(optarg, CP_NO_LIMIT_S)) 103 | ebt_print_error2("Problem with ulog-cprange: %s", optarg); 104 | i = CP_NO_LIMIT_N; 105 | } 106 | uloginfo->cprange = i; 107 | break; 108 | 109 | case ULOG_QTHRESHOLD: 110 | if (ebt_check_inverse2(optarg)) 111 | goto inverse_invalid; 112 | ebt_check_option2(flags, OPT_QTHRESHOLD); 113 | i = strtoul(optarg, &end, 10); 114 | if (*end != '\0') 115 | ebt_print_error2("Problem with ulog-qthreshold: %s", optarg); 116 | if (i > EBT_ULOG_MAX_QLEN) 117 | ebt_print_error2("ulog-qthreshold argument %d exceeds the maximum of %d", i, EBT_ULOG_MAX_QLEN); 118 | uloginfo->qthreshold = i; 119 | break; 120 | case ULOG_ULOG: 121 | if (ebt_check_inverse(optarg)) 122 | goto inverse_invalid; 123 | ebt_check_option2(flags, OPT_ULOG); 124 | break; 125 | 126 | default: 127 | return 0; 128 | } 129 | return 1; 130 | 131 | inverse_invalid: 132 | ebt_print_error("The use of '!' makes no sense for the ulog watcher"); 133 | return 1; 134 | } 135 | 136 | static void final_check(const struct ebt_u_entry *entry, 137 | const struct ebt_entry_watcher *watcher, const char *name, 138 | unsigned int hookmask, unsigned int time) 139 | { 140 | } 141 | 142 | static void print(const struct ebt_u_entry *entry, 143 | const struct ebt_entry_watcher *watcher) 144 | { 145 | struct ebt_ulog_info *uloginfo = (struct ebt_ulog_info *)watcher->data; 146 | 147 | printf("--ulog-prefix \"%s\" --ulog-nlgroup %d --ulog-cprange ", 148 | uloginfo->prefix, uloginfo->nlgroup + 1); 149 | if (uloginfo->cprange == CP_NO_LIMIT_N) 150 | printf(CP_NO_LIMIT_S); 151 | else 152 | printf("%d", uloginfo->cprange); 153 | printf(" --ulog-qthreshold %d ", uloginfo->qthreshold); 154 | } 155 | 156 | static int compare(const struct ebt_entry_watcher *w1, 157 | const struct ebt_entry_watcher *w2) 158 | { 159 | struct ebt_ulog_info *uloginfo1 = (struct ebt_ulog_info *)w1->data; 160 | struct ebt_ulog_info *uloginfo2 = (struct ebt_ulog_info *)w2->data; 161 | 162 | if (uloginfo1->nlgroup != uloginfo2->nlgroup || 163 | uloginfo1->cprange != uloginfo2->cprange || 164 | uloginfo1->qthreshold != uloginfo2->qthreshold || 165 | strcmp(uloginfo1->prefix, uloginfo2->prefix)) 166 | return 0; 167 | return 1; 168 | } 169 | 170 | static struct ebt_u_watcher ulog_watcher = 171 | { 172 | .name = "ulog", 173 | .size = sizeof(struct ebt_ulog_info), 174 | .help = print_help, 175 | .init = init, 176 | .parse = parse, 177 | .final_check = final_check, 178 | .print = print, 179 | .compare = compare, 180 | .extra_ops = opts, 181 | }; 182 | 183 | void _ulog_init(void) 184 | { 185 | ebt_register_watcher(&ulog_watcher); 186 | } 187 | -------------------------------------------------------------------------------- /extensions/ebt_mark.c: -------------------------------------------------------------------------------- 1 | /* ebt_mark 2 | * 3 | * Authors: 4 | * Bart De Schuymer 5 | * 6 | * July, 2002, September 2006 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "../include/ebtables_u.h" 14 | #include 15 | 16 | static int mark_supplied; 17 | 18 | #define MARK_TARGET '1' 19 | #define MARK_SETMARK '2' 20 | #define MARK_ORMARK '3' 21 | #define MARK_ANDMARK '4' 22 | #define MARK_XORMARK '5' 23 | static struct option opts[] = 24 | { 25 | { "mark-target" , required_argument, 0, MARK_TARGET }, 26 | /* an oldtime messup, we should have always used the scheme 27 | * -