diff options
Diffstat (limited to 'include/linux/netfilter_bridge')
-rw-r--r-- | include/linux/netfilter_bridge/ebt_802_3.h | 69 | ||||
-rw-r--r-- | include/linux/netfilter_bridge/ebt_among.h | 65 | ||||
-rw-r--r-- | include/linux/netfilter_bridge/ebt_arp.h | 32 | ||||
-rw-r--r-- | include/linux/netfilter_bridge/ebt_arpreply.h | 11 | ||||
-rw-r--r-- | include/linux/netfilter_bridge/ebt_ip.h | 43 | ||||
-rw-r--r-- | include/linux/netfilter_bridge/ebt_limit.h | 23 | ||||
-rw-r--r-- | include/linux/netfilter_bridge/ebt_log.h | 17 | ||||
-rw-r--r-- | include/linux/netfilter_bridge/ebt_mark_m.h | 15 | ||||
-rw-r--r-- | include/linux/netfilter_bridge/ebt_mark_t.h | 12 | ||||
-rw-r--r-- | include/linux/netfilter_bridge/ebt_nat.h | 13 | ||||
-rw-r--r-- | include/linux/netfilter_bridge/ebt_pkttype.h | 11 | ||||
-rw-r--r-- | include/linux/netfilter_bridge/ebt_redirect.h | 11 | ||||
-rw-r--r-- | include/linux/netfilter_bridge/ebt_stp.h | 46 | ||||
-rw-r--r-- | include/linux/netfilter_bridge/ebt_ulog.h | 36 | ||||
-rw-r--r-- | include/linux/netfilter_bridge/ebt_vlan.h | 20 | ||||
-rw-r--r-- | include/linux/netfilter_bridge/ebtables.h | 363 |
16 files changed, 787 insertions, 0 deletions
diff --git a/include/linux/netfilter_bridge/ebt_802_3.h b/include/linux/netfilter_bridge/ebt_802_3.h new file mode 100644 index 00000000000..b9f712c14a0 --- /dev/null +++ b/include/linux/netfilter_bridge/ebt_802_3.h @@ -0,0 +1,69 @@ +#ifndef __LINUX_BRIDGE_EBT_802_3_H +#define __LINUX_BRIDGE_EBT_802_3_H + +#define EBT_802_3_SAP 0x01 +#define EBT_802_3_TYPE 0x02 + +#define EBT_802_3_MATCH "802_3" + +/* + * If frame has DSAP/SSAP value 0xaa you must check the SNAP type + * to discover what kind of packet we're carrying. + */ +#define CHECK_TYPE 0xaa + +/* + * Control field may be one or two bytes. If the first byte has + * the value 0x03 then the entire length is one byte, otherwise it is two. + * One byte controls are used in Unnumbered Information frames. + * Two byte controls are used in Numbered Information frames. + */ +#define IS_UI 0x03 + +#define EBT_802_3_MASK (EBT_802_3_SAP | EBT_802_3_TYPE | EBT_802_3) + +/* ui has one byte ctrl, ni has two */ +struct hdr_ui { + uint8_t dsap; + uint8_t ssap; + uint8_t ctrl; + uint8_t orig[3]; + uint16_t type; +}; + +struct hdr_ni { + uint8_t dsap; + uint8_t ssap; + uint16_t ctrl; + uint8_t orig[3]; + uint16_t type; +}; + +struct ebt_802_3_hdr { + uint8_t daddr[6]; + uint8_t saddr[6]; + uint16_t len; + union { + struct hdr_ui ui; + struct hdr_ni ni; + } 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.raw; +} +#endif + +struct ebt_802_3_info +{ + uint8_t sap; + uint16_t type; + uint8_t bitmask; + uint8_t invflags; +}; + +#endif diff --git a/include/linux/netfilter_bridge/ebt_among.h b/include/linux/netfilter_bridge/ebt_among.h new file mode 100644 index 00000000000..307c1fed851 --- /dev/null +++ b/include/linux/netfilter_bridge/ebt_among.h @@ -0,0 +1,65 @@ +#ifndef __LINUX_BRIDGE_EBT_AMONG_H +#define __LINUX_BRIDGE_EBT_AMONG_H + +#define EBT_AMONG_DST 0x01 +#define EBT_AMONG_SRC 0x02 + +/* Grzegorz Borowiak <grzes@gnu.univ.gda.pl> 2003 + * + * Write-once-read-many hash table, used for checking if a given + * MAC address belongs to a set or not and possibly for checking + * if it is related with a given IPv4 address. + * + * The hash value of an address is its last byte. + * + * In real-world ethernet addresses, values of the last byte are + * evenly distributed and there is no need to consider other bytes. + * It would only slow the routines down. + * + * For MAC address comparison speedup reasons, we introduce a trick. + * MAC address is mapped onto an array of two 32-bit integers. + * This pair of integers is compared with MAC addresses in the + * hash table, which are stored also in form of pairs of integers + * (in `cmp' array). This is quick as it requires only two elementary + * number comparisons in worst case. Further, we take advantage of + * fact that entropy of 3 last bytes of address is larger than entropy + * of 3 first bytes. So first we compare 4 last bytes of addresses and + * if they are the same we compare 2 first. + * + * Yes, it is a memory overhead, but in 2003 AD, who cares? + */ + +struct ebt_mac_wormhash_tuple +{ + uint32_t cmp[2]; + uint32_t ip; +}; + +struct ebt_mac_wormhash +{ + int table[257]; + int poolsize; + struct ebt_mac_wormhash_tuple pool[0]; +}; + +#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 +{ + int wh_dst_ofs; + int wh_src_ofs; + int bitmask; +}; + +#define EBT_AMONG_DST_NEG 0x1 +#define EBT_AMONG_SRC_NEG 0x2 + +#define ebt_among_wh_dst(x) ((x)->wh_dst_ofs ? \ + (struct ebt_mac_wormhash*)((char*)(x) + (x)->wh_dst_ofs) : NULL) +#define ebt_among_wh_src(x) ((x)->wh_src_ofs ? \ + (struct ebt_mac_wormhash*)((char*)(x) + (x)->wh_src_ofs) : NULL) + +#define EBT_AMONG_MATCH "among" + +#endif diff --git a/include/linux/netfilter_bridge/ebt_arp.h b/include/linux/netfilter_bridge/ebt_arp.h new file mode 100644 index 00000000000..537ec6b487a --- /dev/null +++ b/include/linux/netfilter_bridge/ebt_arp.h @@ -0,0 +1,32 @@ +#ifndef __LINUX_BRIDGE_EBT_ARP_H +#define __LINUX_BRIDGE_EBT_ARP_H + +#define EBT_ARP_OPCODE 0x01 +#define EBT_ARP_HTYPE 0x02 +#define EBT_ARP_PTYPE 0x04 +#define EBT_ARP_SRC_IP 0x08 +#define EBT_ARP_DST_IP 0x10 +#define EBT_ARP_SRC_MAC 0x20 +#define EBT_ARP_DST_MAC 0x40 +#define EBT_ARP_MASK (EBT_ARP_OPCODE | EBT_ARP_HTYPE | EBT_ARP_PTYPE | \ + EBT_ARP_SRC_IP | EBT_ARP_DST_IP | EBT_ARP_SRC_MAC | EBT_ARP_DST_MAC) +#define EBT_ARP_MATCH "arp" + +struct ebt_arp_info +{ + uint16_t htype; + uint16_t ptype; + uint16_t opcode; + uint32_t saddr; + uint32_t smsk; + uint32_t daddr; + uint32_t dmsk; + unsigned char smaddr[ETH_ALEN]; + unsigned char smmsk[ETH_ALEN]; + unsigned char dmaddr[ETH_ALEN]; + unsigned char dmmsk[ETH_ALEN]; + uint8_t bitmask; + uint8_t invflags; +}; + +#endif diff --git a/include/linux/netfilter_bridge/ebt_arpreply.h b/include/linux/netfilter_bridge/ebt_arpreply.h new file mode 100644 index 00000000000..96a8339960e --- /dev/null +++ b/include/linux/netfilter_bridge/ebt_arpreply.h @@ -0,0 +1,11 @@ +#ifndef __LINUX_BRIDGE_EBT_ARPREPLY_H +#define __LINUX_BRIDGE_EBT_ARPREPLY_H + +struct ebt_arpreply_info +{ + unsigned char mac[ETH_ALEN]; + int target; +}; +#define EBT_ARPREPLY_TARGET "arpreply" + +#endif diff --git a/include/linux/netfilter_bridge/ebt_ip.h b/include/linux/netfilter_bridge/ebt_ip.h new file mode 100644 index 00000000000..7247385cdcb --- /dev/null +++ b/include/linux/netfilter_bridge/ebt_ip.h @@ -0,0 +1,43 @@ +/* + * ebt_ip + * + * Authors: + * Bart De Schuymer <bart.de.schuymer@pandora.be> + * + * April, 2002 + * + * Changes: + * added ip-sport and ip-dport + * Innominate Security Technologies AG <mhopf@innominate.com> + * September, 2002 + */ + +#ifndef __LINUX_BRIDGE_EBT_IP_H +#define __LINUX_BRIDGE_EBT_IP_H + +#define EBT_IP_SOURCE 0x01 +#define EBT_IP_DEST 0x02 +#define EBT_IP_TOS 0x04 +#define EBT_IP_PROTO 0x08 +#define EBT_IP_SPORT 0x10 +#define EBT_IP_DPORT 0x20 +#define EBT_IP_MASK (EBT_IP_SOURCE | EBT_IP_DEST | EBT_IP_TOS | EBT_IP_PROTO |\ + EBT_IP_SPORT | EBT_IP_DPORT ) +#define EBT_IP_MATCH "ip" + +/* the same values are used for the invflags */ +struct ebt_ip_info +{ + uint32_t saddr; + uint32_t daddr; + uint32_t smsk; + uint32_t dmsk; + uint8_t tos; + uint8_t protocol; + uint8_t bitmask; + uint8_t invflags; + uint16_t sport[2]; + uint16_t dport[2]; +}; + +#endif diff --git a/include/linux/netfilter_bridge/ebt_limit.h b/include/linux/netfilter_bridge/ebt_limit.h new file mode 100644 index 00000000000..d8b65000afe --- /dev/null +++ b/include/linux/netfilter_bridge/ebt_limit.h @@ -0,0 +1,23 @@ +#ifndef __LINUX_BRIDGE_EBT_LIMIT_H +#define __LINUX_BRIDGE_EBT_LIMIT_H + +#define EBT_LIMIT_MATCH "limit" + +/* timings are in milliseconds. */ +#define EBT_LIMIT_SCALE 10000 + +/* 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. */ + + /* Used internally by the kernel */ + unsigned long prev; + u_int32_t credit; + u_int32_t credit_cap, cost; +}; + +#endif diff --git a/include/linux/netfilter_bridge/ebt_log.h b/include/linux/netfilter_bridge/ebt_log.h new file mode 100644 index 00000000000..358fbc84fb5 --- /dev/null +++ b/include/linux/netfilter_bridge/ebt_log.h @@ -0,0 +1,17 @@ +#ifndef __LINUX_BRIDGE_EBT_LOG_H +#define __LINUX_BRIDGE_EBT_LOG_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_MASK (EBT_LOG_IP | EBT_LOG_ARP) +#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; +}; + +#endif diff --git a/include/linux/netfilter_bridge/ebt_mark_m.h b/include/linux/netfilter_bridge/ebt_mark_m.h new file mode 100644 index 00000000000..301524ff106 --- /dev/null +++ b/include/linux/netfilter_bridge/ebt_mark_m.h @@ -0,0 +1,15 @@ +#ifndef __LINUX_BRIDGE_EBT_MARK_M_H +#define __LINUX_BRIDGE_EBT_MARK_M_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 +{ + unsigned long mark, mask; + uint8_t invert; + uint8_t bitmask; +}; +#define EBT_MARK_MATCH "mark_m" + +#endif diff --git a/include/linux/netfilter_bridge/ebt_mark_t.h b/include/linux/netfilter_bridge/ebt_mark_t.h new file mode 100644 index 00000000000..110fec6a40a --- /dev/null +++ b/include/linux/netfilter_bridge/ebt_mark_t.h @@ -0,0 +1,12 @@ +#ifndef __LINUX_BRIDGE_EBT_MARK_T_H +#define __LINUX_BRIDGE_EBT_MARK_T_H + +struct ebt_mark_t_info +{ + unsigned long mark; + /* EBT_ACCEPT, EBT_DROP, EBT_CONTINUE or EBT_RETURN */ + int target; +}; +#define EBT_MARK_TARGET "mark" + +#endif diff --git a/include/linux/netfilter_bridge/ebt_nat.h b/include/linux/netfilter_bridge/ebt_nat.h new file mode 100644 index 00000000000..26fd90da4cd --- /dev/null +++ b/include/linux/netfilter_bridge/ebt_nat.h @@ -0,0 +1,13 @@ +#ifndef __LINUX_BRIDGE_EBT_NAT_H +#define __LINUX_BRIDGE_EBT_NAT_H + +struct ebt_nat_info +{ + unsigned char mac[ETH_ALEN]; + /* EBT_ACCEPT, EBT_DROP, EBT_CONTINUE or EBT_RETURN */ + int target; +}; +#define EBT_SNAT_TARGET "snat" +#define EBT_DNAT_TARGET "dnat" + +#endif diff --git a/include/linux/netfilter_bridge/ebt_pkttype.h b/include/linux/netfilter_bridge/ebt_pkttype.h new file mode 100644 index 00000000000..0d64bbb29c6 --- /dev/null +++ b/include/linux/netfilter_bridge/ebt_pkttype.h @@ -0,0 +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; +}; +#define EBT_PKTTYPE_MATCH "pkttype" + +#endif diff --git a/include/linux/netfilter_bridge/ebt_redirect.h b/include/linux/netfilter_bridge/ebt_redirect.h new file mode 100644 index 00000000000..5c67990fce3 --- /dev/null +++ b/include/linux/netfilter_bridge/ebt_redirect.h @@ -0,0 +1,11 @@ +#ifndef __LINUX_BRIDGE_EBT_REDIRECT_H +#define __LINUX_BRIDGE_EBT_REDIRECT_H + +struct ebt_redirect_info +{ + /* EBT_ACCEPT, EBT_DROP, EBT_CONTINUE or EBT_RETURN */ + int target; +}; +#define EBT_REDIRECT_TARGET "redirect" + +#endif diff --git a/include/linux/netfilter_bridge/ebt_stp.h b/include/linux/netfilter_bridge/ebt_stp.h new file mode 100644 index 00000000000..e5fd67850f4 --- /dev/null +++ b/include/linux/netfilter_bridge/ebt_stp.h @@ -0,0 +1,46 @@ +#ifndef __LINUX_BRIDGE_EBT_STP_H +#define __LINUX_BRIDGE_EBT_STP_H + +#define EBT_STP_TYPE 0x0001 + +#define EBT_STP_FLAGS 0x0002 +#define EBT_STP_ROOTPRIO 0x0004 +#define EBT_STP_ROOTADDR 0x0008 +#define EBT_STP_ROOTCOST 0x0010 +#define EBT_STP_SENDERPRIO 0x0020 +#define EBT_STP_SENDERADDR 0x0040 +#define EBT_STP_PORT 0x0080 +#define EBT_STP_MSGAGE 0x0100 +#define EBT_STP_MAXAGE 0x0200 +#define EBT_STP_HELLOTIME 0x0400 +#define EBT_STP_FWDD 0x0800 + +#define EBT_STP_MASK 0x0fff +#define EBT_STP_CONFIG_MASK 0x0ffe + +#define EBT_STP_MATCH "stp" + +struct ebt_stp_config_info +{ + uint8_t flags; + uint16_t root_priol, root_priou; + char root_addr[6], root_addrmsk[6]; + uint32_t root_costl, root_costu; + uint16_t 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; +}; + +struct ebt_stp_info +{ + uint8_t type; + struct ebt_stp_config_info config; + uint16_t bitmask; + uint16_t invflags; +}; + +#endif diff --git a/include/linux/netfilter_bridge/ebt_ulog.h b/include/linux/netfilter_bridge/ebt_ulog.h new file mode 100644 index 00000000000..b677e267154 --- /dev/null +++ b/include/linux/netfilter_bridge/ebt_ulog.h @@ -0,0 +1,36 @@ +#ifndef _EBT_ULOG_H +#define _EBT_ULOG_H + +#define EBT_ULOG_DEFAULT_NLGROUP 0 +#define EBT_ULOG_DEFAULT_QTHRESHOLD 1 +#define EBT_ULOG_MAXNLGROUPS 32 /* hardcoded netlink max */ +#define EBT_ULOG_PREFIX_LEN 32 +#define EBT_ULOG_MAX_QLEN 50 +#define EBT_ULOG_WATCHER "ulog" +#define EBT_ULOG_VERSION 1 + +struct ebt_ulog_info { + uint32_t nlgroup; + unsigned int cprange; + unsigned int qthreshold; + char prefix[EBT_ULOG_PREFIX_LEN]; +}; + +typedef struct ebt_ulog_packet_msg { + int version; + char indev[IFNAMSIZ]; + char outdev[IFNAMSIZ]; + char physindev[IFNAMSIZ]; + char physoutdev[IFNAMSIZ]; + char prefix[EBT_ULOG_PREFIX_LEN]; + struct timeval stamp; + unsigned long mark; + unsigned int hook; + size_t data_len; + /* The complete packet, including Ethernet header and perhaps + * the VLAN header is appended */ + unsigned char data[0] __attribute__ + ((aligned (__alignof__(struct ebt_ulog_info)))); +} ebt_ulog_packet_msg_t; + +#endif /* _EBT_ULOG_H */ diff --git a/include/linux/netfilter_bridge/ebt_vlan.h b/include/linux/netfilter_bridge/ebt_vlan.h new file mode 100644 index 00000000000..cb1fcc41565 --- /dev/null +++ b/include/linux/netfilter_bridge/ebt_vlan.h @@ -0,0 +1,20 @@ +#ifndef __LINUX_BRIDGE_EBT_VLAN_H +#define __LINUX_BRIDGE_EBT_VLAN_H + +#define EBT_VLAN_ID 0x01 +#define EBT_VLAN_PRIO 0x02 +#define EBT_VLAN_ENCAP 0x04 +#define EBT_VLAN_MASK (EBT_VLAN_ID | EBT_VLAN_PRIO | EBT_VLAN_ENCAP) +#define EBT_VLAN_MATCH "vlan" + +struct ebt_vlan_info { + uint16_t id; /* VLAN ID {1-4095} */ + uint8_t prio; /* VLAN User Priority {0-7} */ + uint16_t encap; /* VLAN Encapsulated frame code {0-65535} */ + uint8_t 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, + bit 2=1 - inversed Pirority arg */ +}; + +#endif diff --git a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h new file mode 100644 index 00000000000..b1a7cc90877 --- /dev/null +++ b/include/linux/netfilter_bridge/ebtables.h @@ -0,0 +1,363 @@ +/* + * ebtables + * + * Authors: + * Bart De Schuymer <bdschuym@pandora.be> + * + * ebtables.c,v 2.0, April, 2002 + * + * This code is stongly inspired on the iptables code which is + * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling + */ + +#ifndef __LINUX_BRIDGE_EFF_H +#define __LINUX_BRIDGE_EFF_H +#include <linux/if.h> +#include <linux/netfilter_bridge.h> +#include <linux/if_ether.h> + +#define EBT_TABLE_MAXNAMELEN 32 +#define EBT_CHAIN_MAXNAMELEN EBT_TABLE_MAXNAMELEN +#define EBT_FUNCTION_MAXNAMELEN EBT_TABLE_MAXNAMELEN + +/* verdicts >0 are "branches" */ +#define EBT_ACCEPT -1 +#define EBT_DROP -2 +#define EBT_CONTINUE -3 +#define EBT_RETURN -4 +#define NUM_STANDARD_TARGETS 4 + +struct ebt_counter +{ + uint64_t pcnt; + uint64_t bcnt; +}; + +struct ebt_replace +{ + char name[EBT_TABLE_MAXNAMELEN]; + unsigned int valid_hooks; + /* nr of rules in the table */ + unsigned int nentries; + /* total size of the entries */ + unsigned int entries_size; + /* start of the chains */ + struct ebt_entries *hook_entry[NF_BR_NUMHOOKS]; + /* nr of counters userspace expects back */ + unsigned int num_counters; + /* where the kernel will put the old counters */ + struct ebt_counter *counters; + char *entries; +}; + +struct ebt_entries { + /* this field is always set to zero + * See EBT_ENTRY_OR_ENTRIES. + * Must be same size as ebt_entry.bitmask */ + unsigned int distinguisher; + /* the chain name */ + char name[EBT_CHAIN_MAXNAMELEN]; + /* counter offset for this chain */ + unsigned int counter_offset; + /* one standard (accept, drop, return) per hook */ + int policy; + /* nr. of entries */ + unsigned int nentries; + /* entry list */ + char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); +}; + +/* used for the bitmask of struct ebt_entry */ + +/* This is a hack to make a difference between an ebt_entry struct and an + * ebt_entries struct when traversing the entries from start to end. + * Using this simplifies the code alot, while still being able to use + * ebt_entries. + * Contrary, iptables doesn't use something like ebt_entries and therefore uses + * different techniques for naming the policy and such. So, iptables doesn't + * need a hack like this. + */ +#define EBT_ENTRY_OR_ENTRIES 0x01 +/* these are the normal masks */ +#define EBT_NOPROTO 0x02 +#define EBT_802_3 0x04 +#define EBT_SOURCEMAC 0x08 +#define EBT_DESTMAC 0x10 +#define EBT_F_MASK (EBT_NOPROTO | EBT_802_3 | EBT_SOURCEMAC | EBT_DESTMAC \ + | EBT_ENTRY_OR_ENTRIES) + +#define EBT_IPROTO 0x01 +#define EBT_IIN 0x02 +#define EBT_IOUT 0x04 +#define EBT_ISOURCE 0x8 +#define EBT_IDEST 0x10 +#define EBT_ILOGICALIN 0x20 +#define EBT_ILOGICALOUT 0x40 +#define EBT_INV_MASK (EBT_IPROTO | EBT_IIN | EBT_IOUT | EBT_ILOGICALIN \ + | EBT_ILOGICALOUT | EBT_ISOURCE | EBT_IDEST) + +struct ebt_entry_match +{ + union { + char name[EBT_FUNCTION_MAXNAMELEN]; + struct ebt_match *match; + } u; + /* size of data */ + unsigned int match_size; + unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); +}; + +struct ebt_entry_watcher +{ + union { + char name[EBT_FUNCTION_MAXNAMELEN]; + struct ebt_watcher *watcher; + } u; + /* size of data */ + unsigned int watcher_size; + unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); +}; + +struct ebt_entry_target +{ + union { + char name[EBT_FUNCTION_MAXNAMELEN]; + struct ebt_target *target; + } u; + /* size of data */ + unsigned int target_size; + unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); +}; + +#define EBT_STANDARD_TARGET "standard" +struct ebt_standard_target +{ + struct ebt_entry_target target; + int verdict; +}; + +/* one entry */ +struct ebt_entry { + /* this needs to be the first field */ + unsigned int bitmask; + unsigned int invflags; + uint16_t ethproto; + /* the physical in-dev */ + char in[IFNAMSIZ]; + /* the logical in-dev */ + char logical_in[IFNAMSIZ]; + /* the physical out-dev */ + char out[IFNAMSIZ]; + /* the logical out-dev */ + char logical_out[IFNAMSIZ]; + unsigned char sourcemac[ETH_ALEN]; + unsigned char sourcemsk[ETH_ALEN]; + unsigned char destmac[ETH_ALEN]; + unsigned char destmsk[ETH_ALEN]; + /* sizeof ebt_entry + matches */ + unsigned int watchers_offset; + /* sizeof ebt_entry + matches + watchers */ + unsigned int target_offset; + /* sizeof ebt_entry + matches + watchers + target */ + unsigned int next_offset; + unsigned char elems[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); +}; + +/* {g,s}etsockopt numbers */ +#define EBT_BASE_CTL 128 + +#define EBT_SO_SET_ENTRIES (EBT_BASE_CTL) +#define EBT_SO_SET_COUNTERS (EBT_SO_SET_ENTRIES+1) +#define EBT_SO_SET_MAX (EBT_SO_SET_COUNTERS+1) + +#define EBT_SO_GET_INFO (EBT_BASE_CTL) +#define EBT_SO_GET_ENTRIES (EBT_SO_GET_INFO+1) +#define EBT_SO_GET_INIT_INFO (EBT_SO_GET_ENTRIES+1) +#define EBT_SO_GET_INIT_ENTRIES (EBT_SO_GET_INIT_INFO+1) +#define EBT_SO_GET_MAX (EBT_SO_GET_INIT_ENTRIES+1) + +#ifdef __KERNEL__ + +/* return values for match() functions */ +#define EBT_MATCH 0 +#define EBT_NOMATCH 1 + +struct ebt_match +{ + struct list_head list; + const char name[EBT_FUNCTION_MAXNAMELEN]; + /* 0 == it matches */ + int (*match)(const struct sk_buff *skb, const struct net_device *in, + const struct net_device *out, const void *matchdata, + unsigned int datalen); + /* 0 == let it in */ + int (*check)(const char *tablename, unsigned int hookmask, + const struct ebt_entry *e, void *matchdata, unsigned int datalen); + void (*destroy)(void *matchdata, unsigned int datalen); + struct module *me; +}; + +struct ebt_watcher +{ + struct list_head list; + const char name[EBT_FUNCTION_MAXNAMELEN]; + void (*watcher)(const struct sk_buff *skb, unsigned int hooknr, + const struct net_device *in, const struct net_device *out, + const void *watcherdata, unsigned int datalen); + /* 0 == let it in */ + int (*check)(const char *tablename, unsigned int hookmask, + const struct ebt_entry *e, void *watcherdata, unsigned int datalen); + void (*destroy)(void *watcherdata, unsigned int datalen); + struct module *me; +}; + +struct ebt_target +{ + struct list_head list; + const char name[EBT_FUNCTION_MAXNAMELEN]; + /* returns one of the standard verdicts */ + int (*target)(struct sk_buff **pskb, unsigned int hooknr, + const struct net_device *in, const struct net_device *out, + const void *targetdata, unsigned int datalen); + /* 0 == let it in */ + int (*check)(const char *tablename, unsigned int hookmask, + const struct ebt_entry *e, void *targetdata, unsigned int datalen); + void (*destroy)(void *targetdata, unsigned int datalen); + struct module *me; +}; + +/* used for jumping from and into user defined chains (udc) */ +struct ebt_chainstack +{ + struct ebt_entries *chaininfo; /* pointer to chain data */ + struct ebt_entry *e; /* pointer to entry data */ + unsigned int n; /* n'th entry */ +}; + +struct ebt_table_info +{ + /* total size of the entries */ + unsigned int entries_size; + unsigned int nentries; + /* pointers to the start of the chains */ + struct ebt_entries *hook_entry[NF_BR_NUMHOOKS]; + /* room to maintain the stack used for jumping from and into udc */ + struct ebt_chainstack **chainstack; + char *entries; + struct ebt_counter counters[0] ____cacheline_aligned; +}; + +struct ebt_table +{ + struct list_head list; + char name[EBT_TABLE_MAXNAMELEN]; + struct ebt_replace *table; + unsigned int valid_hooks; + rwlock_t lock; + /* e.g. could be the table explicitly only allows certain + * matches, targets, ... 0 == let it in */ + int (*check)(const struct ebt_table_info *info, + unsigned int valid_hooks); + /* the data used by the kernel */ + struct ebt_table_info *private; + struct module *me; +}; + +#define EBT_ALIGN(s) (((s) + (__alignof__(struct ebt_replace)-1)) & \ + ~(__alignof__(struct ebt_replace)-1)) +extern int ebt_register_table(struct ebt_table *table); +extern void ebt_unregister_table(struct ebt_table *table); +extern int ebt_register_match(struct ebt_match *match); +extern void ebt_unregister_match(struct ebt_match *match); +extern int ebt_register_watcher(struct ebt_watcher *watcher); +extern void ebt_unregister_watcher(struct ebt_watcher *watcher); +extern int ebt_register_target(struct ebt_target *target); +extern void ebt_unregister_target(struct ebt_target *target); +extern unsigned int ebt_do_table(unsigned int hook, struct sk_buff **pskb, + const struct net_device *in, const struct net_device *out, + struct ebt_table *table); + +/* Used in the kernel match() functions */ +#define FWINV(bool,invflg) ((bool) ^ !!(info->invflags & invflg)) +/* True if the hook mask denotes that the rule is in a base chain, + * used in the check() functions */ +#define BASE_CHAIN (hookmask & (1 << NF_BR_NUMHOOKS)) +/* Clear the bit in the hook mask that tells if the rule is on a base chain */ +#define CLEAR_BASE_CHAIN_BIT (hookmask &= ~(1 << NF_BR_NUMHOOKS)) +/* True if the target is not a standard target */ +#define INVALID_TARGET (info->target < -NUM_STANDARD_TARGETS || info->target >= 0) + +#endif /* __KERNEL__ */ + +/* blatently stolen from ip_tables.h + * fn returns 0 to continue iteration */ +#define EBT_MATCH_ITERATE(e, fn, args...) \ +({ \ + unsigned int __i; \ + int __ret = 0; \ + struct ebt_entry_match *__match; \ + \ + for (__i = sizeof(struct ebt_entry); \ + __i < (e)->watchers_offset; \ + __i += __match->match_size + \ + sizeof(struct ebt_entry_match)) { \ + __match = (void *)(e) + __i; \ + \ + __ret = fn(__match , ## args); \ + if (__ret != 0) \ + break; \ + } \ + if (__ret == 0) { \ + if (__i != (e)->watchers_offset) \ + __ret = -EINVAL; \ + } \ + __ret; \ +}) + +#define EBT_WATCHER_ITERATE(e, fn, args...) \ +({ \ + unsigned int __i; \ + int __ret = 0; \ + struct ebt_entry_watcher *__watcher; \ + \ + for (__i = e->watchers_offset; \ + __i < (e)->target_offset; \ + __i += __watcher->watcher_size + \ + sizeof(struct ebt_entry_watcher)) { \ + __watcher = (void *)(e) + __i; \ + \ + __ret = fn(__watcher , ## args); \ + if (__ret != 0) \ + break; \ + } \ + if (__ret == 0) { \ + if (__i != (e)->target_offset) \ + __ret = -EINVAL; \ + } \ + __ret; \ +}) + +#define EBT_ENTRY_ITERATE(entries, size, fn, args...) \ +({ \ + unsigned int __i; \ + int __ret = 0; \ + struct ebt_entry *__entry; \ + \ + for (__i = 0; __i < (size);) { \ + __entry = (void *)(entries) + __i; \ + __ret = fn(__entry , ## args); \ + if (__ret != 0) \ + break; \ + if (__entry->bitmask != 0) \ + __i += __entry->next_offset; \ + else \ + __i += sizeof(struct ebt_entries); \ + } \ + if (__ret == 0) { \ + if (__i != (size)) \ + __ret = -EINVAL; \ + } \ + __ret; \ +}) + +#endif |