ebtables update to v2.0.10-4

arm-sdk7
Shibby 11 years ago
parent d779775889
commit b3b623d84d

@ -1,3 +1,32 @@
20111215
Changelog for v2.0.10-4
* really fix counter setting bug (thanks to James' persistence)
20111204
Changelog for v2.0.10-3
* fix counter setting bug (reported by James Sinclair)
20110710
Changelog for v2.0.10-2
* enable compiler optimizations (-O3)
* small changes to remove the compiler warnings due to optimization being
turned on (thanks to Peter Volkov)
* respect LDFLAGS in Makefiles (Peter Volkov)
20110710
Changelog for v2.0.10-1
* fix --among-dst-file, which translated to --among-src
(reported by Thierry Watelet)
* fix bug in test_ulog.c example
* Makefile: respect LDFLAGS during ebtables build (Peter Volkov)
* Makefile: create directories to avoid build failure when DESTDIR is
supplied (Peter Volkov)
* incorporate fixes for possible issues found by Coverity analysis
(thanks to Jiri Popelka)
* define __EXPORTED_HEADERS__ to get access to the Linux kernel headers
* extend ebt_ip6 to allow matching on ipv6-icmp types/codes (by Florian
Westphal)
* Print a more useful error message when an update of the kernel table
failed.
* Add --concurrent option, which enables using a file lock to support
concurrent scripts updating the ebtables kernel tables
20100203
Changelog for v2.0.9-2
* fix unwanted zeroing of counters in the last user-defined chain

@ -15,8 +15,8 @@ extensions, without shared libraries, do this (this will make a
binary called 'static', which you can rename):
%make static
WHAT GETS INSTALLED?
--------------------
WHAT GETS INSTALLED AND WHAT OPTIONS ARE AVAILABLE?
---------------------------------------------------
- The ebtables manual gets installed in /usr/local/man/man8
To put the manual somewhere else, include MANDIR=<<man-path/man>> as
@ -30,6 +30,9 @@ WHAT GETS INSTALLED?
- The ebtables initialisation file (enabling use of 'service ebtables') is
copied to /etc/rc.d/init.d (change with option INITDIR)
- The ebtables configuration file (ebtables-config) is copied to /etc/sysconfig
- ebtables can use a lock file to enable concurrent execution of the ebtables
tool. The standard location of the lock file is /var/lib/ebtables/lock.
Include LOCKFILE=<<path-to-file>> if you want to use another file.
That's all
@ -37,7 +40,7 @@ You can also use a base directory different from the root directory (/),
using the DESTDIR option. See the Makefile for more details.
ADDITIONAL PROGRAM(S):
ADDITIONAL PROGRAMS:
----------------------
-- examples/ulog/test_ulog.c --

@ -1,10 +1,12 @@
# ebtables Makefile
PROGNAME:=ebtables
PROGRELEASE:=2
PROGVERSION_:=2.0.9
PROGRELEASE:=4
PROGVERSION_:=2.0.10
PROGVERSION:=$(PROGVERSION_)-$(PROGRELEASE)
PROGDATE:=June\ 2009
PROGDATE:=December\ 2011
LOCKFILE?=/var/lib/ebtables/lock
LOCKDIR:=$(shell echo $(LOCKFILE) | sed 's/\(.*\)\/.*/\1/')/
# default paths
LIBDIR:=/usr/lib
@ -15,8 +17,8 @@ INITDIR:=/etc/rc.d/init.d
SYSCONFIGDIR:=/etc/sysconfig
DESTDIR:=
CFLAGS:=-Wall -Wunused
CFLAGS_SH_LIB:=-fPIC
CFLAGS:=-Wall -Wunused -Werror
CFLAGS_SH_LIB:=-fPIC -O3
CC:=gcc
ifeq ($(shell uname -m),sparc64)
@ -45,7 +47,9 @@ PROGSPECS:=-DPROGVERSION=\"$(PROGVERSION)\" \
-DPROGDATE=\"$(PROGDATE)\" \
-D_PATH_ETHERTYPES=\"$(ETHERTYPESFILE)\" \
-DEBTD_ARGC_MAX=$(EBTD_ARGC_MAX) \
-DEBTD_CMDLINE_MAXLN=$(EBTD_CMDLINE_MAXLN)
-DEBTD_CMDLINE_MAXLN=$(EBTD_CMDLINE_MAXLN) \
-DLOCKFILE=\"$(LOCKFILE)\" \
-DLOCKDIR=\"$(LOCKDIR)\"
# You can probably ignore this, ebtables{u,d} are normally not used
PROGSPECSD:=-DPROGVERSION=\"$(PROGVERSION)\" \
@ -82,11 +86,10 @@ ebtables.o: ebtables.c include/ebtables_u.h
ebtables-standalone.o: ebtables-standalone.c include/ebtables_u.h
$(CC) $(CFLAGS) $(CFLAGS_SH_LIB) $(PROGSPECS) -c $< -o $@ -I$(KERNEL_INCLUDES)
.PHONY: libebtc
libebtc: $(OBJECTS2)
libebtc.so: $(OBJECTS2)
$(CC) -shared $(LDFLAGS) -Wl,-soname,libebtc.so -o libebtc.so -lc $(OBJECTS2)
ebtables: $(OBJECTS) ebtables-standalone.o libebtc
ebtables: $(OBJECTS) ebtables-standalone.o libebtc.so
$(CC) $(CFLAGS) $(CFLAGS_SH_LIB) $(LDFLAGS) -o $@ ebtables-standalone.o -I$(KERNEL_INCLUDES) -L. -Lextensions -lebtc $(EXT_LIBSI) \
-Wl,-rpath,$(LIBDIR)
@ -96,14 +99,14 @@ ebtablesu: ebtablesu.c
ebtablesd.o: ebtablesd.c include/ebtables_u.h
$(CC) $(CFLAGS) $(PROGSPECSD) -c $< -o $@ -I$(KERNEL_INCLUDES)
ebtablesd: $(OBJECTS) ebtablesd.o libebtc
ebtablesd: $(OBJECTS) ebtablesd.o libebtc.so
$(CC) $(CFLAGS) -o $@ ebtablesd.o -I$(KERNEL_INCLUDES) -L. -Lextensions -lebtc $(EXT_LIBSI) \
-Wl,-rpath,$(LIBDIR)
ebtables-restore.o: ebtables-restore.c include/ebtables_u.h
$(CC) $(CFLAGS) $(PROGSPECS) -c $< -o $@ -I$(KERNEL_INCLUDES)
ebtables-restore: $(OBJECTS) ebtables-restore.o libebtc
ebtables-restore: $(OBJECTS) ebtables-restore.o libebtc.so
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ ebtables-restore.o -I$(KERNEL_INCLUDES) -L. -Lextensions -lebtc $(EXT_LIBSI) \
-Wl,-rpath,$(LIBDIR)
@ -133,7 +136,7 @@ static: extensions/ebt_*.c extensions/ebtable_*.c ebtables.c communication.c ebt
printf "extern void %s();\n" _t_$${arg}_init >> include/ebtables_u.h ; \
done ; \
printf "\n\tpseudomain(argc, argv);\n\treturn 0;\n}\n" >> ebtables-standalone.c ;\
$(CC) $(CFLAGS) $(PROGSPECS) -o $@ $^ -I$(KERNEL_INCLUDES) -Iinclude ; \
$(CC) $(CFLAGS) $(LDFLAGS) $(PROGSPECS) -o $@ $^ -I$(KERNEL_INCLUDES) -Iinclude ; \
for arg in $(EXT_FUNC) \
; do \
sed "s/ .*_init/ _init/" extensions/ebt_$${arg}.c > extensions/ebt_$${arg}.c_ ; \
@ -153,22 +156,26 @@ tmp3:=$(shell printf $(PIPE) | sed 's/\//\\\//g')
.PHONY: scripts
scripts: ebtables-save ebtables.sysv ebtables-config
cat ebtables-save | sed 's/__EXEC_PATH__/$(tmp1)/g' > ebtables-save_
mkdir -p $(DESTDIR)$(BINDIR)
install -m 0755 -o root -g root ebtables-save_ $(DESTDIR)$(BINDIR)/ebtables-save
cat ebtables.sysv | sed 's/__EXEC_PATH__/$(tmp1)/g' | sed 's/__SYSCONFIG__/$(tmp2)/g' > ebtables.sysv_
install -m 0755 -o root -g root ebtables.sysv_ $(DESTDIR)$(INITDIR)/ebtables
if [ "$(DESTDIR)" != "" ]; then mkdir -p $(DESTDIR)$(INITDIR); fi
if test -d $(DESTDIR)$(INITDIR); then install -m 0755 -o root -g root ebtables.sysv_ $(DESTDIR)$(INITDIR)/ebtables; fi
cat ebtables-config | sed 's/__SYSCONFIG__/$(tmp2)/g' > ebtables-config_
install -m 0600 -o root -g root ebtables-config_ $(DESTDIR)$(SYSCONFIGDIR)/ebtables-config
if [ "$(DESTDIR)" != "" ]; then mkdir -p $(DESTDIR)$(SYSCONFIGDIR); fi
if test -d $(DESTDIR)$(SYSCONFIGDIR); then install -m 0600 -o root -g root ebtables-config_ $(DESTDIR)$(SYSCONFIGDIR)/ebtables-config; fi
rm -f ebtables-save_ ebtables.sysv_ ebtables-config_
tmp4:=$(shell printf $(LOCKFILE) | sed 's/\//\\\//g')
$(MANDIR)/man8/ebtables.8: ebtables.8
mkdir -p $(DESTDIR)$(@D)
sed 's/$$(VERSION)/$(PROGVERSION)/' ebtables.8 | sed 's/$$(DATE)/$(PROGDATE)/' > ebtables.8_
sed -e 's/$$(VERSION)/$(PROGVERSION)/' -e 's/$$(DATE)/$(PROGDATE)/' -e 's/$$(LOCKFILE)/$(tmp4)/' ebtables.8 > ebtables.8_
install -m 0644 -o root -g root ebtables.8_ $(DESTDIR)$@
rm -f ebtables.8_
$(ETHERTYPESFILE): ethertypes
mkdir -p $(DESTDIR)$(@D)
install -m 0644 -o root -g root $< $(DESTDIR)$@
$(DESTDIR)$(ETHERTYPESFILE): ethertypes
mkdir -p $(@D)
install -m 0644 -o root -g root $< $@
.PHONY: exec
exec: ebtables ebtables-restore
@ -177,7 +184,7 @@ exec: ebtables ebtables-restore
install -m 0755 -o root -g root ebtables-restore $(DESTDIR)$(BINDIR)/ebtables-restore
.PHONY: install
install: $(MANDIR)/man8/ebtables.8 $(ETHERTYPESFILE) exec scripts
install: $(MANDIR)/man8/ebtables.8 $(DESTDIR)$(ETHERTYPESFILE) exec scripts
mkdir -p $(DESTDIR)$(LIBDIR)
install -m 0755 extensions/*.so $(DESTDIR)$(LIBDIR)
install -m 0755 *.so $(DESTDIR)$(LIBDIR)
@ -217,10 +224,8 @@ release:
touch include/*
touch include/linux/*
touch include/linux/netfilter_bridge/*
sed -i 's/$$(VERSION)/$(PROGVERSION)/' ebtables.8
sed -i 's/$$(DATE)/$(PROGDATE)/' ebtables.8
sed -i 's/$$(VERSION)/$(PROGVERSION_)/' ebtables.spec
sed -i 's/$$(RELEASE)/$(PROGRELEASE)/' ebtables.spec
sed -i -e 's/$$(VERSION)/$(PROGVERSION)/' -e 's/$$(DATE)/$(PROGDATE)/' -e 's/$$(LOCKFILE)/$(tmp4)/' ebtables.8
sed -i -e 's/$$(VERSION)/$(PROGVERSION_)/' -e 's/$$(RELEASE)/$(PROGRELEASE)/' ebtables.spec
cd ..;tar -c $(DIR) | gzip >$(DIR).tar.gz; cd -
rm -rf include/linux

@ -66,7 +66,9 @@ static struct ebt_replace *translate_user2kernel(struct ebt_u_replace *u_repl)
new->nentries = u_repl->nentries;
new->num_counters = u_repl->num_counters;
new->counters = sparc_cast u_repl->counters;
chain_offsets = (unsigned int *)malloc(u_repl->num_chains * sizeof(unsigned int));
chain_offsets = (unsigned int *)calloc(u_repl->num_chains, sizeof(unsigned int));
if (!chain_offsets)
ebt_print_memory();
/* Determine size */
for (i = 0; i < u_repl->num_chains; i++) {
if (!(entries = u_repl->chains[i]))
@ -238,9 +240,13 @@ void ebt_deliver_table(struct ebt_u_replace *u_repl)
goto free_repl;
}
ebt_print_error("The kernel doesn't support a certain ebtables"
" extension, consider recompiling your kernel or insmod"
" the extension");
ebt_print_error("Unable to update the kernel. Two possible causes:\n"
"1. Multiple ebtables programs were executing simultaneously. The ebtables\n"
" userspace tool doesn't by default support multiple ebtables programs running\n"
" concurrently. The ebtables option --concurrent or a tool like flock can be\n"
" used to support concurrent scripts that update the ebtables kernel tables.\n"
"2. The kernel doesn't support a certain ebtables extension, consider\n"
" recompiling your kernel or insmod the extension.\n");
free_repl:
if (repl) {
free(repl->entries);
@ -287,9 +293,9 @@ void ebt_deliver_counters(struct ebt_u_replace *u_repl)
socklen_t optlen;
struct ebt_replace repl;
struct ebt_cntchanges *cc = u_repl->cc->next, *cc2;
struct ebt_u_entries *entries;
struct ebt_u_entries *entries = NULL;
struct ebt_u_entry *next = NULL;
int i, chainnr = 0;
int i, chainnr = -1;
if (u_repl->nentries == 0)
return;
@ -303,12 +309,15 @@ void ebt_deliver_counters(struct ebt_u_replace *u_repl)
new = newcounters;
while (cc != u_repl->cc) {
if (!next || next == entries->entries) {
chainnr++;
while (chainnr < u_repl->num_chains && (!(entries = u_repl->chains[chainnr]) ||
(next = entries->entries->next) == entries->entries))
chainnr++;
if (chainnr == u_repl->num_chains)
break;
}
if (next == NULL)
ebt_print_bug("next == NULL");
if (cc->type == CNT_NORM) {
/* 'Normal' rule, meaning we didn't do anything to it
* So, we just copy */
@ -636,9 +645,9 @@ static int retrieve_from_file(char *filename, struct ebt_replace *repl,
!= repl->entries_size ||
fseek(file, sizeof(struct ebt_replace) + repl->entries_size,
SEEK_SET)
|| fread((char *)repl->counters, sizeof(char),
|| (repl->counters && fread((char *)repl->counters, sizeof(char),
repl->nentries * sizeof(struct ebt_counter), file)
!= repl->nentries * sizeof(struct ebt_counter)) {
!= repl->nentries * sizeof(struct ebt_counter))) {
ebt_print_error("File %s is corrupt", filename);
free(entries);
repl->entries = NULL;
@ -700,8 +709,8 @@ int ebt_get_table(struct ebt_u_replace *u_repl, int init)
{
int i, j, k, hook;
struct ebt_replace repl;
struct ebt_u_entry *u_e;
struct ebt_cntchanges *new_cc, *cc;
struct ebt_u_entry *u_e = NULL;
struct ebt_cntchanges *new_cc = NULL, *cc;
strcpy(repl.name, u_repl->name);
if (u_repl->filename != NULL) {

@ -1,4 +1,4 @@
.TH EBTABLES 8 "June 2009"
.TH EBTABLES 8 "December 2011"
.\"
.\" Man page written by Bart De Schuymer <bdschuym@pandora.be>
.\" It is based on the iptables man page.
@ -24,7 +24,7 @@
.\"
.\"
.SH NAME
ebtables (v2.0.9-2) \- Ethernet bridge frame table administration
ebtables (v2.0.10-4) \- Ethernet bridge frame table administration
.SH SYNOPSIS
.BR "ebtables " [ -t " table ] " - [ ACDI "] chain rule specification [match extensions] [watcher extensions] target"
.br
@ -404,6 +404,9 @@ is setting the
When talking to the kernel, use this
.I program
to try to automatically load missing kernel modules.
.TP
.B --concurrent
Use a file lock to support concurrent scripts updating the ebtables kernel tables.
.SS
RULE SPECIFICATIONS
@ -700,6 +703,17 @@ If
The flag
.B --ip6-dport
is an alias for this option.
.TP
.BR "--ip6-icmp-type " "[!] {\fItype\fP[:\fItype\fP]/\fIcode\fP[:\fIcode\fP]|\fItypename\fP}"
Specify ipv6\-icmp type and code to match.
Ranges for both type and code are supported. Type and code are
separated by a slash. Valid numbers for type and range are 0 to 255.
To match a single type including all valid codes, symbolic names can
be used instead of numbers. The list of known type names is shown by the command
.nf
ebtables \-\-help ip6
.fi
This option is only valid for \-\-ip6-prococol ipv6-icmp.
.SS limit
This module matches at a limited rate using a token bucket filter.
A rule using this extension will match until this limit is reached.
@ -1089,11 +1103,12 @@ arp message and the hardware address length in the arp header is 6 bytes.
.br
.SH FILES
.I /etc/ethertypes
.I /var/lib/ebtables/lock
.SH ENVIRONMENT VARIABLES
.I EBTABLES_ATOMIC_FILE
.SH MAILINGLISTS
.I ebtables-user@lists.sourceforge.net
.br
.I ebtables-devel@lists.sourceforge.net
.BR "" "See " http://netfilter.org/mailinglists.html
.SH SEE ALSO
.BR iptables "(8), " brctl "(8), " ifconfig "(8), " route (8)
.PP
.BR "" "See " http://ebtables.sf.net

@ -26,6 +26,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <signal.h>
#include "include/ebtables_u.h"
#include "include/ethernetdb.h"
@ -91,6 +92,7 @@ static struct option ebt_original_options[] =
{ "atomic-file" , required_argument, 0, 9 },
{ "atomic-save" , no_argument , 0, 10 },
{ "init-table" , no_argument , 0, 11 },
{ "concurrent" , no_argument , 0, 13 },
{ 0 }
};
@ -322,7 +324,7 @@ static void list_em(struct ebt_u_entries *entries)
uint64_t bcnt = hlp->cnt.bcnt;
if (replace->flags & LIST_X)
printf("-c %llu %llu", pcnt, bcnt);
printf("-c %"PRIu64" %"PRIu64, pcnt, bcnt);
else
printf(", pcnt = %"PRIu64" -- bcnt = %"PRIu64, pcnt, bcnt);
}
@ -374,6 +376,7 @@ static void print_help()
"--set-counters -c chain\n"
" pcnt bcnt : set the counters of the to be added rule\n"
"--modprobe -M program : try to insert modules using this program\n"
"--concurrent : use a file lock to support concurrent scripts\n"
"--version -V : print package version\n\n"
"Environment variable:\n"
ATOMIC_ENV_VARIABLE " : if set <FILE> (see above) will equal its value"
@ -525,6 +528,12 @@ void ebt_early_init_once()
ebt_iterate_targets(merge_target);
}
/* signal handler, installed when the option --concurrent is specified. */
static void sighandler(int signum)
{
exit(-1);
}
/* We use exec_style instead of #ifdef's because ebtables.so is a shared object. */
int do_command(int argc, char *argv[], int exec_style,
struct ebt_u_replace *replace_)
@ -532,7 +541,7 @@ int do_command(int argc, char *argv[], int exec_style,
char *buffer;
int c, i;
int zerochain = -1; /* Needed for the -Z option (we can have -Z <this> -L <that>) */
int chcounter; /* Needed for -C */
int chcounter = 0; /* Needed for -C */
int policy = 0;
int rule_nr = 0;
int rule_nr_end = 0;
@ -1037,6 +1046,11 @@ big_iface_length:
replace->filename = (char *)malloc(strlen(optarg) + 1);
strcpy(replace->filename, optarg);
break;
case 13 : /* concurrent */
signal(SIGINT, sighandler);
signal(SIGTERM, sighandler);
use_lockfd = 1;
break;
case 1 :
if (!strcmp(optarg, "!"))
ebt_check_inverse2(optarg);

@ -5,8 +5,8 @@
Summary: Ethernet Bridge frame table administration tool
Name: ebtables
Version: 2.0.9
Release: 2
Version: 2.0.10
Release: 4
License: GPL
Group: System Environment/Base
URL: http://ebtables.sourceforge.net/

@ -96,15 +96,15 @@ recv_new:
pkts_per_msg = 0;
len = recvfrom(sfd, buf, BUFLEN, 0,
(struct sockaddr *)&sa_kernel, &addrlen);
if (errno == EINTR)
goto recv_new;
if (addrlen != sizeof(sa_kernel)) {
printf("addrlen %d != %d\n", addrlen,
sizeof(sa_kernel));
printf("addrlen %u != %u\n", addrlen,
(uint32_t)sizeof(sa_kernel));
exit(-1);
}
if (len == -1) {
perror("recvmsg");
if (errno == EINTR)
goto recv_new;
exit(-1);
}
nlh = (struct nlmsghdr *)buf;
@ -281,7 +281,7 @@ truncated_icmp:
printf("ICMP_ECHO SEQ NR=%u\n", ntohs(icmph->un.echo.sequence));
letscontinue:
printf("===>Total Packet length: %d, of which we examined "
printf("===>Total Packet length: %ld, of which we examined "
"%d bytes\n", msg->data_len, curr_len);
printf("###############################\n"
"######END#OF##PACKET#DUMP######\n"

@ -2,15 +2,12 @@
#EXT_FUNC+=802_3 nat arp arpreply ip ip6 standard log redirect vlan mark_m mark \
# pkttype stp among limit ulog nflog
#EXT_TABLES+=filter nat broute
EXT_FUNC+=nat arp arpreply ip standard log redirect vlan mark \
pkttype stp limit
ifeq ($(DO_IPV6), 1)
#EXT_FUNC+=ip6
EXT_FUNC+=ip6
endif
EXT_TABLES+=filter nat broute
EXT_OBJS+=$(foreach T,$(EXT_FUNC), extensions/ebt_$(T).o)
EXT_OBJS+=$(foreach T,$(EXT_TABLES), extensions/ebtable_$(T).o)
EXT_LIBS+=$(foreach T,$(EXT_FUNC), extensions/libebt_$(T).so)
@ -19,7 +16,7 @@ EXT_LIBSI+=$(foreach T,$(EXT_FUNC), -lebt_$(T))
EXT_LIBSI+=$(foreach T,$(EXT_TABLES), -lebtable_$(T))
extensions/ebt_%.so: extensions/ebt_%.o
$(CC) -shared -o $@ -lc $< -nostartfiles
$(CC) $(LDFLAGS) -shared -o $@ -lc $< -nostartfiles
extensions/libebt_%.so: extensions/ebt_%.so
mv $< $@

@ -12,8 +12,8 @@
#include <getopt.h>
#include <ctype.h>
#include <unistd.h>
#include <netinet/ether.h>
#include "../include/ebtables_u.h"
#include <netinet/ether.h>
#include "../include/ethernetdb.h"
#include <linux/if_ether.h>
#include <linux/netfilter_bridge/ebt_among.h>
@ -202,11 +202,13 @@ static struct ebt_mac_wormhash *create_wormhash(const char *arg)
if (read_until(&pc, ":", token, 2) < 0
|| token[0] == 0) {
ebt_print_error("MAC parse error: %.20s", anchor);
free(workcopy);
return NULL;
}
mac[i] = strtol(token, &endptr, 16);
if (*endptr) {
ebt_print_error("MAC parse error: %.20s", anchor);
free(workcopy);
return NULL;
}
pc++;
@ -245,7 +247,7 @@ static struct ebt_mac_wormhash *create_wormhash(const char *arg)
ebt_print_error("IP parse error: %.20s", anchor);
return NULL;
}
if (*(uint32_t*)ip == 0) {
if (ip[0] == 0 && ip[1] == 0 && ip[2] == 0 && ip[3] == 0) {
ebt_print_error("Illegal IP 0.0.0.0");
return NULL;
}
@ -256,7 +258,7 @@ static struct ebt_mac_wormhash *create_wormhash(const char *arg)
/* we have collected MAC and IP, so we add an entry */
memcpy(((char *) workcopy->pool[nmacs].cmp) + 2, mac, 6);
workcopy->pool[nmacs].ip = *(const uint32_t *) ip;
memcpy(&(workcopy->pool[nmacs].ip), ip, 4);
nmacs++;
/* re-allocate memory if needed */
@ -311,8 +313,8 @@ static int parse(int c, char **argv, int argc,
struct ebt_mac_wormhash *wh;
struct ebt_entry_match *h;
int new_size;
long flen;
int fd;
long flen = 0;
int fd = -1;
switch (c) {
case AMONG_DST_F:
@ -365,7 +367,7 @@ static int parse(int c, char **argv, int argc,
ebt_mac_wormhash_size(wh));
h->match_size = EBT_ALIGN(new_size);
info = (struct ebt_among_info *) h->data;
if (c == AMONG_DST) {
if (c == AMONG_DST || c == AMONG_DST_F) {
info->wh_dst_ofs = old_size;
} else {
info->wh_src_ofs = old_size;

@ -10,9 +10,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/ether.h>
#include <getopt.h>
#include "../include/ebtables_u.h"
#include <netinet/ether.h>
#include <linux/netfilter_bridge/ebt_arpreply.h>
static int mac_supplied;

@ -11,13 +11,16 @@
*
*/
#include <errno.h>
#include <inttypes.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <netdb.h>
#include "../include/ebtables_u.h"
#include "../include/linux/netfilter_bridge/ebt_ip6.h"
#include <linux/netfilter_bridge/ebt_ip6.h>
@ -27,8 +30,9 @@
#define IP_PROTO '4'
#define IP_SPORT '5'
#define IP_DPORT '6'
#define IP_ICMP6 '7'
static struct option opts[] =
static const struct option opts[] =
{
{ "ip6-source" , required_argument, 0, IP_SOURCE },
{ "ip6-src" , required_argument, 0, IP_SOURCE },
@ -42,9 +46,55 @@ static struct option opts[] =
{ "ip6-sport" , required_argument, 0, IP_SPORT },
{ "ip6-destination-port" , required_argument, 0, IP_DPORT },
{ "ip6-dport" , required_argument, 0, IP_DPORT },
{ "ip6-icmp-type" , required_argument, 0, IP_ICMP6 },
{ 0 }
};
struct icmpv6_names {
const char *name;
u_int8_t type;
u_int8_t code_min, code_max;
};
static const struct icmpv6_names icmpv6_codes[] = {
{ "destination-unreachable", 1, 0, 0xFF },
{ "no-route", 1, 0, 0 },
{ "communication-prohibited", 1, 1, 1 },
{ "address-unreachable", 1, 3, 3 },
{ "port-unreachable", 1, 4, 4 },
{ "packet-too-big", 2, 0, 0xFF },
{ "time-exceeded", 3, 0, 0xFF },
/* Alias */ { "ttl-exceeded", 3, 0, 0xFF },
{ "ttl-zero-during-transit", 3, 0, 0 },
{ "ttl-zero-during-reassembly", 3, 1, 1 },
{ "parameter-problem", 4, 0, 0xFF },
{ "bad-header", 4, 0, 0 },
{ "unknown-header-type", 4, 1, 1 },
{ "unknown-option", 4, 2, 2 },
{ "echo-request", 128, 0, 0xFF },
/* Alias */ { "ping", 128, 0, 0xFF },
{ "echo-reply", 129, 0, 0xFF },
/* Alias */ { "pong", 129, 0, 0xFF },
{ "router-solicitation", 133, 0, 0xFF },
{ "router-advertisement", 134, 0, 0xFF },
{ "neighbour-solicitation", 135, 0, 0xFF },
/* Alias */ { "neighbor-solicitation", 135, 0, 0xFF },
{ "neighbour-advertisement", 136, 0, 0xFF },
/* Alias */ { "neighbor-advertisement", 136, 0, 0xFF },
{ "redirect", 137, 0, 0xFF },
};
/* transform a protocol and service name into a port number */
static uint16_t parse_port(const char *protocol, const char *name)
{
@ -91,6 +141,97 @@ parse_port_range(const char *protocol, const char *portstring, uint16_t *ports)
free(buffer);
}
static char*
parse_num(const char *str, long min, long max, long *num)
{
char *end;
errno = 0;
*num = strtol(str, &end, 10);
if (errno && (*num == LONG_MIN || *num == LONG_MAX)) {
ebt_print_error("Invalid number %s: %s", str, strerror(errno));
return NULL;
}
if (min <= max) {
if (*num > max || *num < min) {
ebt_print_error("Value %ld out of range (%ld, %ld)", *num, min, max);
return NULL;
}
}
if (*num == 0 && str == end)
return NULL;
return end;
}
static char *
parse_range(const char *str, long min, long max, long num[])
{
char *next;
next = parse_num(str, min, max, num);
if (next == NULL)
return NULL;
if (next && *next == ':')
next = parse_num(next+1, min, max, &num[1]);
else
num[1] = num[0];
return next;
}
static int
parse_icmpv6(const char *icmpv6type, uint8_t type[], uint8_t code[])
{
static const unsigned int limit = ARRAY_SIZE(icmpv6_codes);
unsigned int match = limit;
unsigned int i;
long number[2];
for (i = 0; i < limit; i++) {
if (strncasecmp(icmpv6_codes[i].name, icmpv6type, strlen(icmpv6type)))
continue;
if (match != limit)
ebt_print_error("Ambiguous ICMPv6 type `%s':"
" `%s' or `%s'?",
icmpv6type, icmpv6_codes[match].name,
icmpv6_codes[i].name);
match = i;
}
if (match < limit) {
type[0] = type[1] = icmpv6_codes[match].type;
code[0] = icmpv6_codes[match].code_min;
code[1] = icmpv6_codes[match].code_max;
} else {
char *next = parse_range(icmpv6type, 0, 255, number);
if (!next) {
ebt_print_error("Unknown ICMPv6 type `%s'",
icmpv6type);
return -1;
}
type[0] = (uint8_t) number[0];
type[1] = (uint8_t) number[1];
switch (*next) {
case 0:
code[0] = 0;
code[1] = 255;
return 0;
case '/':
next = parse_range(next+1, 0, 255, number);
code[0] = (uint8_t) number[0];
code[1] = (uint8_t) number[1];
if (next == NULL)
return -1;
if (next && *next == 0)
return 0;
/* fallthrough */
default:
ebt_print_error("unknown character %c", *next);
return -1;
}
}
return 0;
}
static void print_port_range(uint16_t *ports)
{
if (ports[0] == ports[1])
@ -99,6 +240,58 @@ static void print_port_range(uint16_t *ports)
printf("%d:%d ", ports[0], ports[1]);
}
static void print_icmp_code(uint8_t *code)
{
if (code[0] == code[1])
printf("/%"PRIu8 " ", code[0]);
else
printf("/%"PRIu8":%"PRIu8 " ", code[0], code[1]);
}
static void print_icmp_type(uint8_t *type, uint8_t *code)
{
unsigned int i;
if (type[0] != type[1]) {
printf("%"PRIu8 ":%" PRIu8, type[0], type[1]);
print_icmp_code(code);
return;
}
for (i = 0; i < ARRAY_SIZE(icmpv6_codes); i++) {
if (icmpv6_codes[i].type != type[0])
continue;
if (icmpv6_codes[i].code_min == code[0] &&
icmpv6_codes[i].code_max == code[1]) {
printf("%s ", icmpv6_codes[i].name);
return;
}
}
printf("%"PRIu8, type[0]);
print_icmp_code(code);
}
static void print_icmpv6types(void)
{
unsigned int i;
printf("Valid ICMPv6 Types:");
for (i=0; i < ARRAY_SIZE(icmpv6_codes); i++) {
if (i && icmpv6_codes[i].type == icmpv6_codes[i-1].type) {
if (icmpv6_codes[i].code_min == icmpv6_codes[i-1].code_min
&& (icmpv6_codes[i].code_max
== icmpv6_codes[i-1].code_max))
printf(" (%s)", icmpv6_codes[i].name);
else
printf("\n %s", icmpv6_codes[i].name);
}
else
printf("\n%s", icmpv6_codes[i].name);
}
printf("\n");
}
static void print_help()
{
printf(
@ -108,7 +301,9 @@ static void print_help()
"--ip6-tclass [!] tclass : ipv6 traffic class specification\n"
"--ip6-proto [!] protocol : ipv6 protocol specification\n"
"--ip6-sport [!] port[:port] : tcp/udp source port or port range\n"
"--ip6-dport [!] port[:port] : tcp/udp destination port or port range\n");
"--ip6-dport [!] port[:port] : tcp/udp destination port or port range\n"
"--ip6-icmp-type [!] type[[:type]/code[:code]] : ipv6-icmp type/code or type/code range\n");
print_icmpv6types();
}
static void init(struct ebt_entry_match *match)
@ -170,6 +365,15 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
parse_port_range(NULL, optarg, ipinfo->dport);
break;
case IP_ICMP6:
ebt_check_option2(flags, EBT_IP6_ICMP6);
ipinfo->bitmask |= EBT_IP6_ICMP6;
if (ebt_check_inverse2(optarg))
ipinfo->invflags |= EBT_IP6_ICMP6;
if (parse_icmpv6(optarg, ipinfo->icmpv6_type, ipinfo->icmpv6_code))
return 0;
break;
case IP_TCLASS:
ebt_check_option2(flags, OPT_TCLASS);
if (ebt_check_inverse2(optarg))
@ -223,6 +427,12 @@ static void final_check(const struct ebt_u_entry *entry,
ebt_print_error("For port filtering the IP protocol must be "
"either 6 (tcp), 17 (udp), 33 (dccp) or "
"132 (sctp)");
if ((ipinfo->bitmask & EBT_IP6_ICMP6) &&
(!(ipinfo->bitmask & EBT_IP6_PROTO) ||
ipinfo->invflags & EBT_IP6_PROTO ||
ipinfo->protocol != IPPROTO_ICMPV6))
ebt_print_error("For ipv6-icmp filtering the IP protocol must be "
"58 (ipv6-icmp)");
}
static void print(const struct ebt_u_entry *entry,
@ -275,6 +485,12 @@ static void print(const struct ebt_u_entry *entry,
printf("! ");
print_port_range(ipinfo->dport);
}
if (ipinfo->bitmask & EBT_IP6_ICMP6) {
printf("--ip6-icmp-type ");
if (ipinfo->invflags & EBT_IP6_ICMP6)
printf("! ");
print_icmp_type(ipinfo->icmpv6_type, ipinfo->icmpv6_code);
}
}
static int compare(const struct ebt_entry_match *m1,
@ -317,6 +533,13 @@ static int compare(const struct ebt_entry_match *m1,
ipinfo1->dport[1] != ipinfo2->dport[1])
return 0;
}
if (ipinfo1->bitmask & EBT_IP6_ICMP6) {
if (ipinfo1->icmpv6_type[0] != ipinfo2->icmpv6_type[0] ||
ipinfo1->icmpv6_type[1] != ipinfo2->icmpv6_type[1] ||
ipinfo1->icmpv6_code[0] != ipinfo2->icmpv6_code[0] ||
ipinfo1->icmpv6_code[1] != ipinfo2->icmpv6_code[1])
return 0;
}
return 1;
}

@ -9,9 +9,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/ether.h>
#include <getopt.h>
#include "../include/ebtables_u.h"
#include <netinet/ether.h>
#include <linux/netfilter_bridge/ebt_nat.h>
static int to_source_supplied, to_dest_supplied;

@ -80,8 +80,6 @@ static int nflog_parse(int c, char **argv, int argc,
i = strtoul(optarg, &end, 10);
if (*end != '\0')
ebt_print_error2("--nflog-group must be a number!");
if (i < 0)
ebt_print_error2("--nflog-group can not be negative");
info->group = i;
break;
@ -92,8 +90,6 @@ static int nflog_parse(int c, char **argv, int argc,
i = strtoul(optarg, &end, 10);
if (*end != '\0')
ebt_print_error2("--nflog-range must be a number!");
if (i < 0)
ebt_print_error2("--nflog-range can not be negative");
info->len = i;
break;
@ -104,9 +100,6 @@ static int nflog_parse(int c, char **argv, int argc,
i = strtoul(optarg, &end, 10);
if (*end != '\0')
ebt_print_error2("--nflog-threshold must be a number!");
if (i < 0)
ebt_print_error2
("--nflog-threshold can not be negative");
info->threshold = i;
break;
case NFLOG_NFLOG:

@ -32,7 +32,6 @@
* Created at: Mon Nov 11 12:20:11 EET 2002
********************************************************************/
#include <ctype.h>
#include <features.h>
#include <sys/types.h>

@ -229,6 +229,8 @@ extern struct ebt_u_match *ebt_matches;
extern struct ebt_u_watcher *ebt_watchers;
extern struct ebt_u_target *ebt_targets;
extern int use_lockfd;
void ebt_register_table(struct ebt_u_table *);
void ebt_register_match(struct ebt_u_match *);
void ebt_register_watcher(struct ebt_u_watcher *);
@ -376,4 +378,8 @@ extern int ebt_printstyle_mac;
#define PROC_SYS_MODPROBE "/proc/sys/kernel/modprobe"
#endif
#define ATOMIC_ENV_VARIABLE "EBTABLES_ATOMIC_FILE"
#ifndef ARRAY_SIZE
# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#endif
#endif /* EBTABLES_U_H */

@ -72,6 +72,7 @@
#define ETH_P_MPLS_UC 0x8847 /* MPLS Unicast traffic */
#define ETH_P_MPLS_MC 0x8848 /* MPLS Multicast traffic */
#define ETH_P_ATMMPOA 0x884c /* MultiProtocol Over ATM */
#define ETH_P_LINK_CTL 0x886c /* HPNA, wlan link local tunnel */
#define ETH_P_ATMFATE 0x8884 /* Frame-based ATM Transport
* over Ethernet
*/
@ -109,6 +110,7 @@
#define ETH_P_TRAILER 0x001C /* Trailer switch tagging */
#define ETH_P_PHONET 0x00F5 /* Nokia Phonet frames */
#define ETH_P_IEEE802154 0x00F6 /* IEEE802.15.4 frame */
#define ETH_P_CAIF 0x00F7 /* ST-Ericsson CAIF protocol */
/*
* This is an Ethernet frame header.
@ -120,30 +122,5 @@ struct ethhdr {
__be16 h_proto; /* packet type ID field */
} __attribute__((packed));
#ifdef __KERNEL__
#include <linux/skbuff.h>
static inline struct ethhdr *eth_hdr(const struct sk_buff *skb)
{
return (struct ethhdr *)skb_mac_header(skb);
}
int eth_header_parse(const struct sk_buff *skb, unsigned char *haddr);
#ifdef CONFIG_SYSCTL
extern struct ctl_table ether_table[];
#endif
extern ssize_t sysfs_format_mac(char *buf, const unsigned char *addr, int len);
/*
* Display a 6 byte device address (MAC) in a readable format.
*/
extern char *print_mac(char *buf, const unsigned char *addr);
#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
#define MAC_BUF_SIZE 18
#define DECLARE_MAC_BUF(var) char var[MAC_BUF_SIZE] __maybe_unused
#endif
#endif /* _LINUX_IF_ETHER_H */

@ -24,69 +24,4 @@
#define NF_BR_BROUTING 5
#define NF_BR_NUMHOOKS 6
#ifdef __KERNEL__
enum nf_br_hook_priorities {
NF_BR_PRI_FIRST = INT_MIN,
NF_BR_PRI_NAT_DST_BRIDGED = -300,
NF_BR_PRI_FILTER_BRIDGED = -200,
NF_BR_PRI_BRNF = 0,
NF_BR_PRI_NAT_DST_OTHER = 100,
NF_BR_PRI_FILTER_OTHER = 200,
NF_BR_PRI_NAT_SRC = 300,
NF_BR_PRI_LAST = INT_MAX,
};
#ifdef CONFIG_BRIDGE_NETFILTER
#define BRNF_PKT_TYPE 0x01
#define BRNF_BRIDGED_DNAT 0x02
#define BRNF_DONT_TAKE_PARENT 0x04
#define BRNF_BRIDGED 0x08
#define BRNF_NF_BRIDGE_PREROUTING 0x10
/* Only used in br_forward.c */
extern int nf_bridge_copy_header(struct sk_buff *skb);
static inline int nf_bridge_maybe_copy_header(struct sk_buff *skb)
{
if (skb->nf_bridge &&
skb->nf_bridge->mask & (BRNF_BRIDGED | BRNF_BRIDGED_DNAT))
return nf_bridge_copy_header(skb);
return 0;
}
static inline unsigned int nf_bridge_encap_header_len(const struct sk_buff *skb)
{
switch (skb->protocol) {
case __cpu_to_be16(ETH_P_8021Q):
return VLAN_HLEN;
case __cpu_to_be16(ETH_P_PPP_SES):
return PPPOE_SES_HLEN;
default:
return 0;
}
}
/* This is called by the IP fragmenting code and it ensures there is
* enough room for the encapsulating header (if there is one). */
static inline unsigned int nf_bridge_pad(const struct sk_buff *skb)
{
if (skb->nf_bridge)
return nf_bridge_encap_header_len(skb);
return 0;
}
struct bridge_skb_cb {
union {
__be32 ipv4;
} daddr;
};
#else
#define nf_bridge_maybe_copy_header(skb) (0)
#define nf_bridge_pad(skb) (0)
#endif /* CONFIG_BRIDGE_NETFILTER */
#endif /* __KERNEL__ */
#endif

@ -1,6 +1,8 @@
#ifndef __LINUX_BRIDGE_EBT_802_3_H
#define __LINUX_BRIDGE_EBT_802_3_H
#include <linux/types.h>
#define EBT_802_3_SAP 0x01
#define EBT_802_3_TYPE 0x02
@ -24,24 +26,24 @@
/* ui has one byte ctrl, ni has two */
struct hdr_ui {
uint8_t dsap;
uint8_t ssap;
uint8_t ctrl;
uint8_t orig[3];
__u8 dsap;
__u8 ssap;
__u8 ctrl;
__u8 orig[3];
__be16 type;
};
struct hdr_ni {
uint8_t dsap;
uint8_t ssap;
__u8 dsap;
__u8 ssap;
__be16 ctrl;
uint8_t orig[3];
__u8 orig[3];
__be16 type;
};
struct ebt_802_3_hdr {
uint8_t daddr[6];
uint8_t saddr[6];
__u8 daddr[6];
__u8 saddr[6];
__be16 len;
union {
struct hdr_ui ui;
@ -49,21 +51,12 @@ struct ebt_802_3_hdr {
} llc;
};
#ifdef __KERNEL__
#include <linux/skbuff.h>
static inline struct ebt_802_3_hdr *ebt_802_3_hdr(const struct sk_buff *skb)
{
return (struct ebt_802_3_hdr *)skb_mac_header(skb);
}
#endif
struct ebt_802_3_info
{
uint8_t sap;
struct ebt_802_3_info {
__u8 sap;
__be16 type;
uint8_t bitmask;
uint8_t invflags;
__u8 bitmask;
__u8 invflags;
};
#endif

@ -1,6 +1,8 @@
#ifndef __LINUX_BRIDGE_EBT_AMONG_H
#define __LINUX_BRIDGE_EBT_AMONG_H
#include <linux/types.h>
#define EBT_AMONG_DST 0x01
#define EBT_AMONG_SRC 0x02
@ -29,14 +31,12 @@
* Yes, it is a memory overhead, but in 2003 AD, who cares?
*/
struct ebt_mac_wormhash_tuple
{
uint32_t cmp[2];
struct ebt_mac_wormhash_tuple {
__u32 cmp[2];
__be32 ip;
};
struct ebt_mac_wormhash
{
struct ebt_mac_wormhash {
int table[257];
int poolsize;
struct ebt_mac_wormhash_tuple pool[0];
@ -45,8 +45,7 @@ struct ebt_mac_wormhash
#define ebt_mac_wormhash_size(x) ((x) ? sizeof(struct ebt_mac_wormhash) \
+ (x)->poolsize * sizeof(struct ebt_mac_wormhash_tuple) : 0)
struct ebt_among_info
{
struct ebt_among_info {
int wh_dst_ofs;
int wh_src_ofs;
int bitmask;

@ -1,6 +1,8 @@
#ifndef __LINUX_BRIDGE_EBT_ARP_H
#define __LINUX_BRIDGE_EBT_ARP_H
#include <linux/types.h>
#define EBT_ARP_OPCODE 0x01
#define EBT_ARP_HTYPE 0x02
#define EBT_ARP_PTYPE 0x04
@ -27,8 +29,8 @@ struct ebt_arp_info
unsigned char smmsk[ETH_ALEN];
unsigned char dmaddr[ETH_ALEN];
unsigned char dmmsk[ETH_ALEN];
uint8_t bitmask;
uint8_t invflags;
__u8 bitmask;
__u8 invflags;
};
#endif

@ -1,8 +1,7 @@
#ifndef __LINUX_BRIDGE_EBT_ARPREPLY_H
#define __LINUX_BRIDGE_EBT_ARPREPLY_H
struct ebt_arpreply_info
{
struct ebt_arpreply_info {
unsigned char mac[ETH_ALEN];
int target;
};

@ -15,6 +15,8 @@
#ifndef __LINUX_BRIDGE_EBT_IP_H
#define __LINUX_BRIDGE_EBT_IP_H
#include <linux/types.h>
#define EBT_IP_SOURCE 0x01
#define EBT_IP_DEST 0x02
#define EBT_IP_TOS 0x04
@ -26,18 +28,17 @@
#define EBT_IP_MATCH "ip"
/* the same values are used for the invflags */
struct ebt_ip_info
{
struct ebt_ip_info {
__be32 saddr;
__be32 daddr;
__be32 smsk;
__be32 dmsk;
uint8_t tos;
uint8_t protocol;
uint8_t bitmask;
uint8_t invflags;
uint16_t sport[2];
uint16_t dport[2];
__u8 tos;
__u8 protocol;
__u8 bitmask;
__u8 invflags;
__u16 sport[2];
__u16 dport[2];
};
#endif

@ -12,29 +12,39 @@
#ifndef __LINUX_BRIDGE_EBT_IP6_H
#define __LINUX_BRIDGE_EBT_IP6_H
#include <linux/types.h>
#define EBT_IP6_SOURCE 0x01
#define EBT_IP6_DEST 0x02
#define EBT_IP6_TCLASS 0x04
#define EBT_IP6_PROTO 0x08
#define EBT_IP6_SPORT 0x10
#define EBT_IP6_DPORT 0x20
#define EBT_IP6_ICMP6 0x40
#define EBT_IP6_MASK (EBT_IP6_SOURCE | EBT_IP6_DEST | EBT_IP6_TCLASS |\
EBT_IP6_PROTO | EBT_IP6_SPORT | EBT_IP6_DPORT)
EBT_IP6_PROTO | EBT_IP6_SPORT | EBT_IP6_DPORT | \
EBT_IP6_ICMP6)
#define EBT_IP6_MATCH "ip6"
/* the same values are used for the invflags */
struct ebt_ip6_info
{
struct ebt_ip6_info {
struct in6_addr saddr;
struct in6_addr daddr;
struct in6_addr smsk;
struct in6_addr dmsk;
uint8_t tclass;
uint8_t protocol;
uint8_t bitmask;
uint8_t invflags;
uint16_t sport[2];
uint16_t dport[2];
__u8 tclass;
__u8 protocol;
__u8 bitmask;
__u8 invflags;
union {
__u16 sport[2];
__u8 icmpv6_type[2];
};
union {
__u16 dport[2];
__u8 icmpv6_code[2];
};
};
#endif

@ -1,6 +1,8 @@
#ifndef __LINUX_BRIDGE_EBT_LIMIT_H
#define __LINUX_BRIDGE_EBT_LIMIT_H
#include <linux/types.h>
#define EBT_LIMIT_MATCH "limit"
/* timings are in milliseconds. */
@ -9,15 +11,14 @@
/* 1/10,000 sec period => max of 10,000/sec. Min rate is then 429490
seconds, or one every 59 hours. */
struct ebt_limit_info
{
u_int32_t avg; /* Average secs between packets * scale */
u_int32_t burst; /* Period multiplier for upper limit. */
struct ebt_limit_info {
__u32 avg; /* Average secs between packets * scale */
__u32 burst; /* Period multiplier for upper limit. */
/* Used internally by the kernel */
unsigned long prev;
u_int32_t credit;
u_int32_t credit_cap, cost;
__u32 credit;
__u32 credit_cap, cost;
};
#endif

@ -1,6 +1,8 @@
#ifndef __LINUX_BRIDGE_EBT_LOG_H
#define __LINUX_BRIDGE_EBT_LOG_H
#include <linux/types.h>
#define EBT_LOG_IP 0x01 /* if the frame is made by ip, log the ip information */
#define EBT_LOG_ARP 0x02
#define EBT_LOG_NFLOG 0x04
@ -9,11 +11,10 @@
#define EBT_LOG_PREFIX_SIZE 30
#define EBT_LOG_WATCHER "log"
struct ebt_log_info
{
uint8_t loglevel;
uint8_t prefix[EBT_LOG_PREFIX_SIZE];
uint32_t bitmask;
struct ebt_log_info {
__u8 loglevel;
__u8 prefix[EBT_LOG_PREFIX_SIZE];
__u32 bitmask;
};
#endif

@ -1,14 +1,15 @@
#ifndef __LINUX_BRIDGE_EBT_MARK_M_H
#define __LINUX_BRIDGE_EBT_MARK_M_H
#include <linux/types.h>
#define EBT_MARK_AND 0x01
#define EBT_MARK_OR 0x02
#define EBT_MARK_MASK (EBT_MARK_AND | EBT_MARK_OR)
struct ebt_mark_m_info
{
struct ebt_mark_m_info {
unsigned long mark, mask;
uint8_t invert;
uint8_t bitmask;
__u8 invert;
__u8 bitmask;
};
#define EBT_MARK_MATCH "mark_m"

@ -13,8 +13,7 @@
#define MARK_AND_VALUE (0xffffffd0)
#define MARK_XOR_VALUE (0xffffffc0)
struct ebt_mark_t_info
{
struct ebt_mark_t_info {
unsigned long mark;
/* EBT_ACCEPT, EBT_DROP, EBT_CONTINUE or EBT_RETURN */
int target;

@ -2,8 +2,7 @@
#define __LINUX_BRIDGE_EBT_NAT_H
#define NAT_ARP_BIT (0x00000010)
struct ebt_nat_info
{
struct ebt_nat_info {
unsigned char mac[ETH_ALEN];
/* EBT_ACCEPT, EBT_DROP, EBT_CONTINUE or EBT_RETURN */
int target;

@ -1,6 +1,8 @@
#ifndef __LINUX_BRIDGE_EBT_NFLOG_H
#define __LINUX_BRIDGE_EBT_NFLOG_H
#include <linux/types.h>
#define EBT_NFLOG_MASK 0x0
#define EBT_NFLOG_PREFIX_SIZE 64
@ -10,11 +12,11 @@
#define EBT_NFLOG_DEFAULT_THRESHOLD 1
struct ebt_nflog_info {
u_int32_t len;
u_int16_t group;
u_int16_t threshold;
u_int16_t flags;
u_int16_t pad;
__u32 len;
__u16 group;
__u16 threshold;
__u16 flags;
__u16 pad;
char prefix[EBT_NFLOG_PREFIX_SIZE];
};

@ -1,10 +1,11 @@
#ifndef __LINUX_BRIDGE_EBT_PKTTYPE_H
#define __LINUX_BRIDGE_EBT_PKTTYPE_H
struct ebt_pkttype_info
{
uint8_t pkt_type;
uint8_t invert;
#include <linux/types.h>
struct ebt_pkttype_info {
__u8 pkt_type;
__u8 invert;
};
#define EBT_PKTTYPE_MATCH "pkttype"

@ -1,8 +1,7 @@
#ifndef __LINUX_BRIDGE_EBT_REDIRECT_H
#define __LINUX_BRIDGE_EBT_REDIRECT_H
struct ebt_redirect_info
{
struct ebt_redirect_info {
/* EBT_ACCEPT, EBT_DROP, EBT_CONTINUE or EBT_RETURN */
int target;
};

@ -1,6 +1,8 @@
#ifndef __LINUX_BRIDGE_EBT_STP_H
#define __LINUX_BRIDGE_EBT_STP_H
#include <linux/types.h>
#define EBT_STP_TYPE 0x0001
#define EBT_STP_FLAGS 0x0002
@ -20,27 +22,25 @@
#define EBT_STP_MATCH "stp"
struct ebt_stp_config_info
{
uint8_t flags;
uint16_t root_priol, root_priou;
struct ebt_stp_config_info {
__u8 flags;
__u16 root_priol, root_priou;
char root_addr[6], root_addrmsk[6];
uint32_t root_costl, root_costu;
uint16_t sender_priol, sender_priou;
__u32 root_costl, root_costu;
__u16 sender_priol, sender_priou;
char sender_addr[6], sender_addrmsk[6];
uint16_t portl, portu;
uint16_t msg_agel, msg_ageu;
uint16_t max_agel, max_ageu;
uint16_t hello_timel, hello_timeu;
uint16_t forward_delayl, forward_delayu;
__u16 portl, portu;
__u16 msg_agel, msg_ageu;
__u16 max_agel, max_ageu;
__u16 hello_timel, hello_timeu;
__u16 forward_delayl, forward_delayu;
};
struct ebt_stp_info
{
uint8_t type;
struct ebt_stp_info {
__u8 type;
struct ebt_stp_config_info config;
uint16_t bitmask;
uint16_t invflags;
__u16 bitmask;
__u16 invflags;
};
#endif

@ -1,6 +1,8 @@
#ifndef _EBT_ULOG_H
#define _EBT_ULOG_H
#include <linux/types.h>
#define EBT_ULOG_DEFAULT_NLGROUP 0
#define EBT_ULOG_DEFAULT_QTHRESHOLD 1
#define EBT_ULOG_MAXNLGROUPS 32 /* hardcoded netlink max */
@ -10,7 +12,7 @@
#define EBT_ULOG_VERSION 1
struct ebt_ulog_info {
uint32_t nlgroup;
__u32 nlgroup;
unsigned int cprange;
unsigned int qthreshold;
char prefix[EBT_ULOG_PREFIX_LEN];

@ -1,6 +1,8 @@
#ifndef __LINUX_BRIDGE_EBT_VLAN_H
#define __LINUX_BRIDGE_EBT_VLAN_H
#include <linux/types.h>
#define EBT_VLAN_ID 0x01
#define EBT_VLAN_PRIO 0x02
#define EBT_VLAN_ENCAP 0x04
@ -8,12 +10,12 @@
#define EBT_VLAN_MATCH "vlan"
struct ebt_vlan_info {
uint16_t id; /* VLAN ID {1-4095} */
uint8_t prio; /* VLAN User Priority {0-7} */
__u16 id; /* VLAN ID {1-4095} */
__u8 prio; /* VLAN User Priority {0-7} */
__be16 encap; /* VLAN Encapsulated frame code {0-65535} */
uint8_t bitmask; /* Args bitmask bit 1=1 - ID arg,
__u8 bitmask; /* Args bitmask bit 1=1 - ID arg,
bit 2=1 User-Priority arg, bit 3=1 encap*/
uint8_t invflags; /* Inverse bitmask bit 1=1 - inversed ID arg,
__u8 invflags; /* Inverse bitmask bit 1=1 - inversed ID arg,
bit 2=1 - inversed Pirority arg */
};

@ -4,150 +4,9 @@
#include <asm/types.h>
#ifndef __ASSEMBLY__
#ifdef __KERNEL__
#define DECLARE_BITMAP(name,bits) \
unsigned long name[BITS_TO_LONGS(bits)]
#endif
#include <linux/posix_types.h>
#ifdef __KERNEL__
typedef __u32 __kernel_dev_t;
typedef __kernel_fd_set fd_set;
typedef __kernel_dev_t dev_t;
typedef __kernel_ino_t ino_t;
typedef __kernel_mode_t mode_t;
typedef __kernel_nlink_t nlink_t;
typedef __kernel_off_t off_t;
typedef __kernel_pid_t pid_t;
typedef __kernel_daddr_t daddr_t;
typedef __kernel_key_t key_t;
typedef __kernel_suseconds_t suseconds_t;
typedef __kernel_timer_t timer_t;
typedef __kernel_clockid_t clockid_t;
typedef __kernel_mqd_t mqd_t;
typedef _Bool bool;
typedef __kernel_uid32_t uid_t;
typedef __kernel_gid32_t gid_t;
typedef __kernel_uid16_t uid16_t;
typedef __kernel_gid16_t gid16_t;
typedef unsigned long uintptr_t;
#ifdef CONFIG_UID16
/* This is defined by include/asm-{arch}/posix_types.h */
typedef __kernel_old_uid_t old_uid_t;
typedef __kernel_old_gid_t old_gid_t;
#endif /* CONFIG_UID16 */
#if defined(__GNUC__)
typedef __kernel_loff_t loff_t;
#endif
/*
* The following typedefs are also protected by individual ifdefs for
* historical reasons:
*/
#ifndef _SIZE_T
#define _SIZE_T
typedef __kernel_size_t size_t;
#endif
#ifndef _SSIZE_T
#define _SSIZE_T
typedef __kernel_ssize_t ssize_t;
#endif
#ifndef _PTRDIFF_T
#define _PTRDIFF_T
typedef __kernel_ptrdiff_t ptrdiff_t;
#endif
#ifndef _TIME_T
#define _TIME_T
typedef __kernel_time_t time_t;
#endif
#ifndef _CLOCK_T
#define _CLOCK_T
typedef __kernel_clock_t clock_t;
#endif
#ifndef _CADDR_T
#define _CADDR_T
typedef __kernel_caddr_t caddr_t;
#endif
/* bsd */
typedef unsigned char u_char;
typedef unsigned short u_short;
typedef unsigned int u_int;
typedef unsigned long u_long;
/* sysv */
typedef unsigned char unchar;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned long ulong;
#ifndef __BIT_TYPES_DEFINED__
#define __BIT_TYPES_DEFINED__
typedef __u8 u_int8_t;
typedef __s8 int8_t;
typedef __u16 u_int16_t;
typedef __s16 int16_t;
typedef __u32 u_int32_t;
typedef __s32 int32_t;
#endif /* !(__BIT_TYPES_DEFINED__) */
typedef __u8 uint8_t;
typedef __u16 uint16_t;
typedef __u32 uint32_t;
#if defined(__GNUC__)
typedef __u64 uint64_t;
typedef __u64 u_int64_t;
typedef __s64 int64_t;
#endif
/* this is a special 64bit data type that is 8-byte aligned */
#define aligned_u64 __u64 __attribute__((aligned(8)))
#define aligned_be64 __be64 __attribute__((aligned(8)))
#define aligned_le64 __le64 __attribute__((aligned(8)))
/**
* The type used for indexing onto a disc or disc partition.
*
* Linux always considers sectors to be 512 bytes long independently
* of the devices real block size.
*
* blkcnt_t is the type of the inode's block count.
*/
#ifdef CONFIG_LBDAF
typedef u64 sector_t;
typedef u64 blkcnt_t;
#else
typedef unsigned long sector_t;
typedef unsigned long blkcnt_t;
#endif
/*
* The type of an index into the pagecache. Use a #define so asm/types.h
* can override it.
*/
#ifndef pgoff_t
#define pgoff_t unsigned long
#endif
#endif /* __KERNEL__ */
/*
* Below are truly Linux-specific types that should never collide with
@ -175,35 +34,18 @@ typedef __u64 __bitwise __be64;
typedef __u16 __bitwise __sum16;
typedef __u32 __bitwise __wsum;
#ifdef __KERNEL__
typedef unsigned __bitwise__ gfp_t;
typedef unsigned __bitwise__ fmode_t;
#ifdef CONFIG_PHYS_ADDR_T_64BIT
typedef u64 phys_addr_t;
#else
typedef u32 phys_addr_t;
#endif
typedef phys_addr_t resource_size_t;
typedef struct {
volatile int counter;
} atomic_t;
#ifdef CONFIG_64BIT
typedef struct {
volatile long counter;
} atomic64_t;
#endif
struct ustat {
__kernel_daddr_t f_tfree;
__kernel_ino_t f_tinode;
char f_fname[6];
char f_fpack[6];
};
/*
* aligned_u64 should be used in defining kernel<->userspace ABIs to avoid
* common 32/64-bit compat problems.
* 64-bit values align to 4-byte boundaries on x86_32 (and possibly other
* architectures) and to 8-byte boundaries on 64-bit architetures. The new
* aligned_64 type enforces 8-byte alignment so that structs containing
* aligned_64 values have the same alignment on 32-bit and 64-bit architectures.
* No conversions are necessary between 32-bit user-space and a 64-bit kernel.
*/
#define __aligned_u64 __u64 __attribute__((aligned(8)))
#define __aligned_be64 __be64 __attribute__((aligned(8)))
#define __aligned_le64 __le64 __attribute__((aligned(8)))
#endif /* __KERNEL__ */
#endif /* __ASSEMBLY__ */
#endif /* _LINUX_TYPES_H */

@ -32,6 +32,9 @@
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
static void decrease_chain_jumps(struct ebt_u_replace *replace);
static int iterate_entries(struct ebt_u_replace *replace, int type);
@ -130,16 +133,84 @@ void ebt_list_extensions()
}
}
#ifndef LOCKFILE
#define LOCKDIR "/var/lib/ebtables"
#define LOCKFILE LOCKDIR"/lock"
#endif
static int lockfd = -1, locked;
int use_lockfd;
/* Returns 0 on success, -1 when the file is locked by another process
* or -2 on any other error. */
static int lock_file()
{
int try = 0;
int ret = 0;
sigset_t sigset;
tryagain:
/* the SIGINT handler will call unlock_file. To make sure the state
* of the variable locked is correct, we need to temporarily mask the
* SIGINT interrupt. */
sigemptyset(&sigset);
sigaddset(&sigset, SIGINT);
sigprocmask(SIG_BLOCK, &sigset, NULL);
lockfd = open(LOCKFILE, O_CREAT | O_EXCL | O_WRONLY, 00600);
if (lockfd < 0) {
if (errno == EEXIST)
ret = -1;
else if (try == 1)
ret = -2;
else {
if (mkdir(LOCKDIR, 00700))
ret = -2;
else {
try = 1;
goto tryagain;
}
}
} else {
close(lockfd);
locked = 1;
}
sigprocmask(SIG_UNBLOCK, &sigset, NULL);
return ret;
}
void unlock_file()
{
if (locked) {
remove(LOCKFILE);
locked = 0;
}
}
void __attribute__ ((destructor)) onexit()
{
if (use_lockfd)
unlock_file();
}
/* Get the table from the kernel or from a binary file
* init: 1 = ask the kernel for the initial contents of a table, i.e. the
* way it looks when the table is insmod'ed
* 0 = get the current data in the table */
int ebt_get_kernel_table(struct ebt_u_replace *replace, int init)
{
int ret;
if (!ebt_find_table(replace->name)) {
ebt_print_error("Bad table name '%s'", replace->name);
return -1;
}
while (use_lockfd && (ret = lock_file())) {
if (ret == -2) {
/* if we get an error we can't handle, we exit. This
* doesn't break backwards compatibility since using
* this file locking is disabled by default. */
ebt_print_error2("Unable to create lock file "LOCKFILE);
}
fprintf(stderr, "Trying to obtain lock %s\n", LOCKFILE);
sleep(1);
}
/* Get the kernel's information */
if (ebt_get_table(replace, init)) {
if (ebt_errormsg[0] != '\0')
@ -406,7 +477,7 @@ void ebt_delete_cc(struct ebt_cntchanges *cc)
cc->prev->next = cc->next;
cc->next->prev = cc->prev;
free(cc);
}
} else
cc->type = CNT_DEL;
}

Loading…
Cancel
Save