[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data structures and backend interfaces for the three evil clones ip_tables, ip6_tables and arp_tables. In an ideal world we would never have allowed this kind of copy+paste programming... but well, our world isn't (yet?) ideal. o introduce a new x_tables module o {ip,arp,ip6}_tables depend on this x_tables module o registration functions for tables, matches and targets are only wrappers around x_tables provided functions o all matches/targets that are used from ip_tables and ip6_tables are now implemented as xt_FOOBAR.c files and provide module aliases to ipt_FOOBAR and ip6t_FOOBAR o header files for xt_matches are in include/linux/netfilter/, include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers around the xt_FOOBAR.h headers Based on this patchset we're going to further unify the code, gradually getting rid of all the layer 3 specific assumptions. Signed-off-by: Harald Welte <laforge@netfilter.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
880b005f29
commit
2e4e6a17af
@@ -15,6 +15,7 @@
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/if_arp.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
|
@@ -182,6 +182,7 @@ config IP_NF_QUEUE
|
||||
|
||||
config IP_NF_IPTABLES
|
||||
tristate "IP tables support (required for filtering/masq/NAT)"
|
||||
depends on NETFILTER_XTABLES
|
||||
help
|
||||
iptables is a general, extensible packet identification framework.
|
||||
The packet filtering and full NAT (masquerading, port forwarding,
|
||||
@@ -191,16 +192,6 @@ config IP_NF_IPTABLES
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
# The matches.
|
||||
config IP_NF_MATCH_LIMIT
|
||||
tristate "limit match support"
|
||||
depends on IP_NF_IPTABLES
|
||||
help
|
||||
limit matching allows you to control the rate at which a rule can be
|
||||
matched: mainly useful in combination with the LOG target ("LOG
|
||||
target support", below) and to avoid some Denial of Service attacks.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP_NF_MATCH_IPRANGE
|
||||
tristate "IP range match support"
|
||||
depends on IP_NF_IPTABLES
|
||||
@@ -210,37 +201,6 @@ config IP_NF_MATCH_IPRANGE
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP_NF_MATCH_MAC
|
||||
tristate "MAC address match support"
|
||||
depends on IP_NF_IPTABLES
|
||||
help
|
||||
MAC matching allows you to match packets based on the source
|
||||
Ethernet address of the packet.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP_NF_MATCH_PKTTYPE
|
||||
tristate "Packet type match support"
|
||||
depends on IP_NF_IPTABLES
|
||||
help
|
||||
Packet type matching allows you to match a packet by
|
||||
its "class", eg. BROADCAST, MULTICAST, ...
|
||||
|
||||
Typical usage:
|
||||
iptables -A INPUT -m pkttype --pkt-type broadcast -j LOG
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP_NF_MATCH_MARK
|
||||
tristate "netfilter MARK match support"
|
||||
depends on IP_NF_IPTABLES
|
||||
help
|
||||
Netfilter mark matching allows you to match packets based on the
|
||||
`nfmark' value in the packet. This can be set by the MARK target
|
||||
(see below).
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP_NF_MATCH_MULTIPORT
|
||||
tristate "Multiple port match support"
|
||||
depends on IP_NF_IPTABLES
|
||||
@@ -301,15 +261,6 @@ config IP_NF_MATCH_AH_ESP
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP_NF_MATCH_LENGTH
|
||||
tristate "LENGTH match support"
|
||||
depends on IP_NF_IPTABLES
|
||||
help
|
||||
This option allows you to match the length of a packet against a
|
||||
specific value or range of values.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP_NF_MATCH_TTL
|
||||
tristate "TTL match support"
|
||||
depends on IP_NF_IPTABLES
|
||||
@@ -319,50 +270,6 @@ config IP_NF_MATCH_TTL
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP_NF_MATCH_TCPMSS
|
||||
tristate "tcpmss match support"
|
||||
depends on IP_NF_IPTABLES
|
||||
help
|
||||
This option adds a `tcpmss' match, which allows you to examine the
|
||||
MSS value of TCP SYN packets, which control the maximum packet size
|
||||
for that connection.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP_NF_MATCH_HELPER
|
||||
tristate "Helper match support"
|
||||
depends on IP_NF_IPTABLES
|
||||
depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4
|
||||
help
|
||||
Helper matching allows you to match packets in dynamic connections
|
||||
tracked by a conntrack-helper, ie. ip_conntrack_ftp
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say Y.
|
||||
|
||||
config IP_NF_MATCH_STATE
|
||||
tristate "Connection state match support"
|
||||
depends on IP_NF_IPTABLES
|
||||
depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4
|
||||
help
|
||||
Connection state matching allows you to match packets based on their
|
||||
relationship to a tracked connection (ie. previous packets). This
|
||||
is a powerful tool for packet classification.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP_NF_MATCH_CONNTRACK
|
||||
tristate "Connection tracking match support"
|
||||
depends on IP_NF_IPTABLES
|
||||
depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4
|
||||
help
|
||||
This is a general conntrack match module, a superset of the state match.
|
||||
|
||||
It allows matching on additional conntrack information, which is
|
||||
useful in complex configurations, such as NAT gateways with multiple
|
||||
internet links or tunnels.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP_NF_MATCH_OWNER
|
||||
tristate "Owner match support"
|
||||
depends on IP_NF_IPTABLES
|
||||
@@ -372,15 +279,6 @@ config IP_NF_MATCH_OWNER
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP_NF_MATCH_PHYSDEV
|
||||
tristate "Physdev match support"
|
||||
depends on IP_NF_IPTABLES && BRIDGE_NETFILTER
|
||||
help
|
||||
Physdev packet matching matches against the physical bridge ports
|
||||
the IP packet arrived on or will leave by.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP_NF_MATCH_ADDRTYPE
|
||||
tristate 'address type match support'
|
||||
depends on IP_NF_IPTABLES
|
||||
@@ -391,75 +289,6 @@ config IP_NF_MATCH_ADDRTYPE
|
||||
If you want to compile it as a module, say M here and read
|
||||
<file:Documentation/modules.txt>. If unsure, say `N'.
|
||||
|
||||
config IP_NF_MATCH_REALM
|
||||
tristate 'realm match support'
|
||||
depends on IP_NF_IPTABLES
|
||||
select NET_CLS_ROUTE
|
||||
help
|
||||
This option adds a `realm' match, which allows you to use the realm
|
||||
key from the routing subsystem inside iptables.
|
||||
|
||||
This match pretty much resembles the CONFIG_NET_CLS_ROUTE4 option
|
||||
in tc world.
|
||||
|
||||
If you want to compile it as a module, say M here and read
|
||||
<file:Documentation/modules.txt>. If unsure, say `N'.
|
||||
|
||||
config IP_NF_MATCH_SCTP
|
||||
tristate 'SCTP protocol match support'
|
||||
depends on IP_NF_IPTABLES
|
||||
help
|
||||
With this option enabled, you will be able to use the iptables
|
||||
`sctp' match in order to match on SCTP source/destination ports
|
||||
and SCTP chunk types.
|
||||
|
||||
If you want to compile it as a module, say M here and read
|
||||
<file:Documentation/modules.txt>. If unsure, say `N'.
|
||||
|
||||
config IP_NF_MATCH_DCCP
|
||||
tristate 'DCCP protocol match support'
|
||||
depends on IP_NF_IPTABLES
|
||||
help
|
||||
With this option enabled, you will be able to use the iptables
|
||||
`dccp' match in order to match on DCCP source/destination ports
|
||||
and DCCP flags.
|
||||
|
||||
If you want to compile it as a module, say M here and read
|
||||
<file:Documentation/modules.txt>. If unsure, say `N'.
|
||||
|
||||
config IP_NF_MATCH_COMMENT
|
||||
tristate 'comment match support'
|
||||
depends on IP_NF_IPTABLES
|
||||
help
|
||||
This option adds a `comment' dummy-match, which allows you to put
|
||||
comments in your iptables ruleset.
|
||||
|
||||
If you want to compile it as a module, say M here and read
|
||||
<file:Documentation/modules.txt>. If unsure, say `N'.
|
||||
|
||||
config IP_NF_MATCH_CONNMARK
|
||||
tristate 'Connection mark match support'
|
||||
depends on IP_NF_IPTABLES
|
||||
depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || (NF_CONNTRACK_MARK && NF_CONNTRACK_IPV4)
|
||||
help
|
||||
This option adds a `connmark' match, which allows you to match the
|
||||
connection mark value previously set for the session by `CONNMARK'.
|
||||
|
||||
If you want to compile it as a module, say M here and read
|
||||
<file:Documentation/modules.txt>. The module will be called
|
||||
ipt_connmark.o. If unsure, say `N'.
|
||||
|
||||
config IP_NF_MATCH_CONNBYTES
|
||||
tristate 'Connection byte/packet counter match support'
|
||||
depends on IP_NF_IPTABLES
|
||||
depends on (IP_NF_CONNTRACK && IP_NF_CT_ACCT) || (NF_CT_ACCT && NF_CONNTRACK_IPV4)
|
||||
help
|
||||
This option adds a `connbytes' match, which allows you to match the
|
||||
number of bytes and/or packets for each direction within a connection.
|
||||
|
||||
If you want to compile it as a module, say M here and read
|
||||
<file:Documentation/modules.txt>. If unsure, say `N'.
|
||||
|
||||
config IP_NF_MATCH_HASHLIMIT
|
||||
tristate 'hashlimit match support'
|
||||
depends on IP_NF_IPTABLES
|
||||
@@ -474,19 +303,6 @@ config IP_NF_MATCH_HASHLIMIT
|
||||
destination IP' or `500pps from any given source IP' with a single
|
||||
IPtables rule.
|
||||
|
||||
config IP_NF_MATCH_STRING
|
||||
tristate 'string match support'
|
||||
depends on IP_NF_IPTABLES
|
||||
select TEXTSEARCH
|
||||
select TEXTSEARCH_KMP
|
||||
select TEXTSEARCH_BM
|
||||
select TEXTSEARCH_FSM
|
||||
help
|
||||
This option adds a `string' match, which allows you to look for
|
||||
pattern matchings in packets.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP_NF_MATCH_POLICY
|
||||
tristate "IPsec policy match support"
|
||||
depends on IP_NF_IPTABLES && XFRM
|
||||
@@ -572,17 +388,6 @@ config IP_NF_TARGET_TCPMSS
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP_NF_TARGET_NFQUEUE
|
||||
tristate "NFQUEUE Target Support"
|
||||
depends on IP_NF_IPTABLES
|
||||
help
|
||||
This Target replaced the old obsolete QUEUE target.
|
||||
|
||||
As opposed to QUEUE, it supports 65535 different queues,
|
||||
not just one.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
# NAT + specific targets
|
||||
config IP_NF_NAT
|
||||
tristate "Full NAT"
|
||||
@@ -735,31 +540,6 @@ config IP_NF_TARGET_DSCP
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP_NF_TARGET_MARK
|
||||
tristate "MARK target support"
|
||||
depends on IP_NF_MANGLE
|
||||
help
|
||||
This option adds a `MARK' target, which allows you to create rules
|
||||
in the `mangle' table which alter the netfilter mark (nfmark) field
|
||||
associated with the packet prior to routing. This can change
|
||||
the routing method (see `Use netfilter MARK value as routing
|
||||
key') and can also be used by other subsystems to change their
|
||||
behavior.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP_NF_TARGET_CLASSIFY
|
||||
tristate "CLASSIFY target support"
|
||||
depends on IP_NF_MANGLE
|
||||
help
|
||||
This option adds a `CLASSIFY' target, which enables the user to set
|
||||
the priority of a packet. Some qdiscs can use this value for
|
||||
classification, among these are:
|
||||
|
||||
atm, cbq, dsmark, pfifo_fast, htb, prio
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP_NF_TARGET_TTL
|
||||
tristate 'TTL target support'
|
||||
depends on IP_NF_MANGLE
|
||||
@@ -774,19 +554,6 @@ config IP_NF_TARGET_TTL
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP_NF_TARGET_CONNMARK
|
||||
tristate 'CONNMARK target support'
|
||||
depends on IP_NF_MANGLE
|
||||
depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || (NF_CONNTRACK_MARK && NF_CONNTRACK_IPV4)
|
||||
help
|
||||
This option adds a `CONNMARK' target, which allows one to manipulate
|
||||
the connection mark value. Similar to the MARK target, but
|
||||
affects the connection mark value rather than the packet mark value.
|
||||
|
||||
If you want to compile it as a module, say M here and read
|
||||
<file:Documentation/modules.txt>. The module will be called
|
||||
ipt_CONNMARK.o. If unsure, say `N'.
|
||||
|
||||
config IP_NF_TARGET_CLUSTERIP
|
||||
tristate "CLUSTERIP target support (EXPERIMENTAL)"
|
||||
depends on IP_NF_MANGLE && EXPERIMENTAL
|
||||
@@ -810,23 +577,10 @@ config IP_NF_RAW
|
||||
If you want to compile it as a module, say M here and read
|
||||
<file:Documentation/modules.txt>. If unsure, say `N'.
|
||||
|
||||
config IP_NF_TARGET_NOTRACK
|
||||
tristate 'NOTRACK target support'
|
||||
depends on IP_NF_RAW
|
||||
depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4
|
||||
help
|
||||
The NOTRACK target allows a select rule to specify
|
||||
which packets *not* to enter the conntrack/NAT
|
||||
subsystem with all the consequences (no ICMP error tracking,
|
||||
no protocol helpers for the selected packets).
|
||||
|
||||
If you want to compile it as a module, say M here and read
|
||||
<file:Documentation/modules.txt>. If unsure, say `N'.
|
||||
|
||||
|
||||
# ARP tables
|
||||
config IP_NF_ARPTABLES
|
||||
tristate "ARP tables support"
|
||||
depends on NETFILTER_XTABLES
|
||||
help
|
||||
arptables is a general, extensible packet identification framework.
|
||||
The ARP packet filtering and mangling (manipulation)subsystems
|
||||
|
@@ -47,14 +47,8 @@ obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o
|
||||
|
||||
# matches
|
||||
obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_HASHLIMIT) += ipt_hashlimit.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_SCTP) += ipt_sctp.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_DCCP) += ipt_dccp.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_MARK) += ipt_mark.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_MAC) += ipt_mac.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_PKTTYPE) += ipt_pkttype.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o
|
||||
@@ -62,40 +56,25 @@ obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_DSCP) += ipt_dscp.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_AH_ESP) += ipt_ah.o ipt_esp.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_LENGTH) += ipt_length.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_CONNMARK) += ipt_connmark.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_CONNBYTES) += ipt_connbytes.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_POLICY) += ipt_policy.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_COMMENT) += ipt_comment.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_STRING) += ipt_string.o
|
||||
|
||||
# targets
|
||||
obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
|
||||
obj-$(CONFIG_IP_NF_TARGET_TOS) += ipt_TOS.o
|
||||
obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o
|
||||
obj-$(CONFIG_IP_NF_TARGET_DSCP) += ipt_DSCP.o
|
||||
obj-$(CONFIG_IP_NF_TARGET_MARK) += ipt_MARK.o
|
||||
obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o
|
||||
obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
|
||||
obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o
|
||||
obj-$(CONFIG_IP_NF_TARGET_SAME) += ipt_SAME.o
|
||||
obj-$(CONFIG_IP_NF_TARGET_CLASSIFY) += ipt_CLASSIFY.o
|
||||
obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o
|
||||
obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o
|
||||
obj-$(CONFIG_IP_NF_TARGET_CONNMARK) += ipt_CONNMARK.o
|
||||
obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
|
||||
obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o
|
||||
obj-$(CONFIG_IP_NF_TARGET_NOTRACK) += ipt_NOTRACK.o
|
||||
obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o
|
||||
obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
|
||||
obj-$(CONFIG_IP_NF_TARGET_NFQUEUE) += ipt_NFQUEUE.o
|
||||
|
||||
# generic ARP tables
|
||||
obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o
|
||||
|
@@ -24,6 +24,7 @@
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/semaphore.h>
|
||||
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include <linux/netfilter_arp/arp_tables.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -55,28 +56,9 @@ do { \
|
||||
#else
|
||||
#define ARP_NF_ASSERT(x)
|
||||
#endif
|
||||
#define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1))
|
||||
|
||||
static DECLARE_MUTEX(arpt_mutex);
|
||||
|
||||
#define ASSERT_READ_LOCK(x) ARP_NF_ASSERT(down_trylock(&arpt_mutex) != 0)
|
||||
#define ASSERT_WRITE_LOCK(x) ARP_NF_ASSERT(down_trylock(&arpt_mutex) != 0)
|
||||
#include <linux/netfilter_ipv4/listhelp.h>
|
||||
|
||||
struct arpt_table_info {
|
||||
unsigned int size;
|
||||
unsigned int number;
|
||||
unsigned int initial_entries;
|
||||
unsigned int hook_entry[NF_ARP_NUMHOOKS];
|
||||
unsigned int underflow[NF_ARP_NUMHOOKS];
|
||||
void *entries[NR_CPUS];
|
||||
};
|
||||
|
||||
static LIST_HEAD(arpt_target);
|
||||
static LIST_HEAD(arpt_tables);
|
||||
#define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0)
|
||||
#define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0)
|
||||
|
||||
static inline int arp_devaddr_compare(const struct arpt_devaddr_info *ap,
|
||||
char *hdr_addr, int len)
|
||||
{
|
||||
@@ -223,9 +205,9 @@ static inline int arp_checkentry(const struct arpt_arp *arp)
|
||||
}
|
||||
|
||||
static unsigned int arpt_error(struct sk_buff **pskb,
|
||||
unsigned int hooknum,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
unsigned int hooknum,
|
||||
const void *targinfo,
|
||||
void *userinfo)
|
||||
{
|
||||
@@ -254,6 +236,7 @@ unsigned int arpt_do_table(struct sk_buff **pskb,
|
||||
struct arpt_entry *e, *back;
|
||||
const char *indev, *outdev;
|
||||
void *table_base;
|
||||
struct xt_table_info *private = table->private;
|
||||
|
||||
/* ARP header, plus 2 device addresses, plus 2 IP addresses. */
|
||||
if (!pskb_may_pull((*pskb), (sizeof(struct arphdr) +
|
||||
@@ -265,9 +248,9 @@ unsigned int arpt_do_table(struct sk_buff **pskb,
|
||||
outdev = out ? out->name : nulldevname;
|
||||
|
||||
read_lock_bh(&table->lock);
|
||||
table_base = (void *)table->private->entries[smp_processor_id()];
|
||||
e = get_entry(table_base, table->private->hook_entry[hook]);
|
||||
back = get_entry(table_base, table->private->underflow[hook]);
|
||||
table_base = (void *)private->entries[smp_processor_id()];
|
||||
e = get_entry(table_base, private->hook_entry[hook]);
|
||||
back = get_entry(table_base, private->underflow[hook]);
|
||||
|
||||
arp = (*pskb)->nh.arph;
|
||||
do {
|
||||
@@ -315,8 +298,8 @@ unsigned int arpt_do_table(struct sk_buff **pskb,
|
||||
* abs. verdicts
|
||||
*/
|
||||
verdict = t->u.kernel.target->target(pskb,
|
||||
hook,
|
||||
in, out,
|
||||
hook,
|
||||
t->data,
|
||||
userdata);
|
||||
|
||||
@@ -341,106 +324,6 @@ unsigned int arpt_do_table(struct sk_buff **pskb,
|
||||
return verdict;
|
||||
}
|
||||
|
||||
/*
|
||||
* These are weird, but module loading must not be done with mutex
|
||||
* held (since they will register), and we have to have a single
|
||||
* function to use try_then_request_module().
|
||||
*/
|
||||
|
||||
/* Find table by name, grabs mutex & ref. Returns ERR_PTR() on error. */
|
||||
static inline struct arpt_table *find_table_lock(const char *name)
|
||||
{
|
||||
struct arpt_table *t;
|
||||
|
||||
if (down_interruptible(&arpt_mutex) != 0)
|
||||
return ERR_PTR(-EINTR);
|
||||
|
||||
list_for_each_entry(t, &arpt_tables, list)
|
||||
if (strcmp(t->name, name) == 0 && try_module_get(t->me))
|
||||
return t;
|
||||
up(&arpt_mutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Find target, grabs ref. Returns ERR_PTR() on error. */
|
||||
static inline struct arpt_target *find_target(const char *name, u8 revision)
|
||||
{
|
||||
struct arpt_target *t;
|
||||
int err = 0;
|
||||
|
||||
if (down_interruptible(&arpt_mutex) != 0)
|
||||
return ERR_PTR(-EINTR);
|
||||
|
||||
list_for_each_entry(t, &arpt_target, list) {
|
||||
if (strcmp(t->name, name) == 0) {
|
||||
if (t->revision == revision) {
|
||||
if (try_module_get(t->me)) {
|
||||
up(&arpt_mutex);
|
||||
return t;
|
||||
}
|
||||
} else
|
||||
err = -EPROTOTYPE; /* Found something. */
|
||||
}
|
||||
}
|
||||
up(&arpt_mutex);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
struct arpt_target *arpt_find_target(const char *name, u8 revision)
|
||||
{
|
||||
struct arpt_target *target;
|
||||
|
||||
target = try_then_request_module(find_target(name, revision),
|
||||
"arpt_%s", name);
|
||||
if (IS_ERR(target) || !target)
|
||||
return NULL;
|
||||
return target;
|
||||
}
|
||||
|
||||
static int target_revfn(const char *name, u8 revision, int *bestp)
|
||||
{
|
||||
struct arpt_target *t;
|
||||
int have_rev = 0;
|
||||
|
||||
list_for_each_entry(t, &arpt_target, list) {
|
||||
if (strcmp(t->name, name) == 0) {
|
||||
if (t->revision > *bestp)
|
||||
*bestp = t->revision;
|
||||
if (t->revision == revision)
|
||||
have_rev =1;
|
||||
}
|
||||
}
|
||||
return have_rev;
|
||||
}
|
||||
|
||||
/* Returns true or false (if no such extension at all) */
|
||||
static inline int find_revision(const char *name, u8 revision,
|
||||
int (*revfn)(const char *, u8, int *),
|
||||
int *err)
|
||||
{
|
||||
int have_rev, best = -1;
|
||||
|
||||
if (down_interruptible(&arpt_mutex) != 0) {
|
||||
*err = -EINTR;
|
||||
return 1;
|
||||
}
|
||||
have_rev = revfn(name, revision, &best);
|
||||
up(&arpt_mutex);
|
||||
|
||||
/* Nothing at all? Return 0 to try loading module. */
|
||||
if (best == -1) {
|
||||
*err = -ENOENT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*err = best;
|
||||
if (!have_rev)
|
||||
*err = -EPROTONOSUPPORT;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* All zeroes == unconditional rule. */
|
||||
static inline int unconditional(const struct arpt_arp *arp)
|
||||
{
|
||||
@@ -456,7 +339,7 @@ static inline int unconditional(const struct arpt_arp *arp)
|
||||
/* Figures out from what hook each rule can be called: returns 0 if
|
||||
* there are loops. Puts hook bitmask in comefrom.
|
||||
*/
|
||||
static int mark_source_chains(struct arpt_table_info *newinfo,
|
||||
static int mark_source_chains(struct xt_table_info *newinfo,
|
||||
unsigned int valid_hooks, void *entry0)
|
||||
{
|
||||
unsigned int hook;
|
||||
@@ -587,8 +470,8 @@ static inline int check_entry(struct arpt_entry *e, const char *name, unsigned i
|
||||
}
|
||||
|
||||
t = arpt_get_target(e);
|
||||
target = try_then_request_module(find_target(t->u.user.name,
|
||||
t->u.user.revision),
|
||||
target = try_then_request_module(xt_find_target(NF_ARP, t->u.user.name,
|
||||
t->u.user.revision),
|
||||
"arpt_%s", t->u.user.name);
|
||||
if (IS_ERR(target) || !target) {
|
||||
duprintf("check_entry: `%s' not found\n", t->u.user.name);
|
||||
@@ -622,7 +505,7 @@ out:
|
||||
}
|
||||
|
||||
static inline int check_entry_size_and_hooks(struct arpt_entry *e,
|
||||
struct arpt_table_info *newinfo,
|
||||
struct xt_table_info *newinfo,
|
||||
unsigned char *base,
|
||||
unsigned char *limit,
|
||||
const unsigned int *hook_entries,
|
||||
@@ -656,7 +539,7 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e,
|
||||
< 0 (not ARPT_RETURN). --RR */
|
||||
|
||||
/* Clear counters and comefrom */
|
||||
e->counters = ((struct arpt_counters) { 0, 0 });
|
||||
e->counters = ((struct xt_counters) { 0, 0 });
|
||||
e->comefrom = 0;
|
||||
|
||||
(*i)++;
|
||||
@@ -683,7 +566,7 @@ static inline int cleanup_entry(struct arpt_entry *e, unsigned int *i)
|
||||
*/
|
||||
static int translate_table(const char *name,
|
||||
unsigned int valid_hooks,
|
||||
struct arpt_table_info *newinfo,
|
||||
struct xt_table_info *newinfo,
|
||||
void *entry0,
|
||||
unsigned int size,
|
||||
unsigned int number,
|
||||
@@ -764,34 +647,9 @@ static int translate_table(const char *name,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct arpt_table_info *replace_table(struct arpt_table *table,
|
||||
unsigned int num_counters,
|
||||
struct arpt_table_info *newinfo,
|
||||
int *error)
|
||||
{
|
||||
struct arpt_table_info *oldinfo;
|
||||
|
||||
/* Do the substitution. */
|
||||
write_lock_bh(&table->lock);
|
||||
/* Check inside lock: is the old number correct? */
|
||||
if (num_counters != table->private->number) {
|
||||
duprintf("num_counters != table->private->number (%u/%u)\n",
|
||||
num_counters, table->private->number);
|
||||
write_unlock_bh(&table->lock);
|
||||
*error = -EAGAIN;
|
||||
return NULL;
|
||||
}
|
||||
oldinfo = table->private;
|
||||
table->private = newinfo;
|
||||
newinfo->initial_entries = oldinfo->initial_entries;
|
||||
write_unlock_bh(&table->lock);
|
||||
|
||||
return oldinfo;
|
||||
}
|
||||
|
||||
/* Gets counters. */
|
||||
static inline int add_entry_to_counter(const struct arpt_entry *e,
|
||||
struct arpt_counters total[],
|
||||
struct xt_counters total[],
|
||||
unsigned int *i)
|
||||
{
|
||||
ADD_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt);
|
||||
@@ -801,7 +659,7 @@ static inline int add_entry_to_counter(const struct arpt_entry *e,
|
||||
}
|
||||
|
||||
static inline int set_entry_to_counter(const struct arpt_entry *e,
|
||||
struct arpt_counters total[],
|
||||
struct xt_counters total[],
|
||||
unsigned int *i)
|
||||
{
|
||||
SET_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt);
|
||||
@@ -810,8 +668,8 @@ static inline int set_entry_to_counter(const struct arpt_entry *e,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void get_counters(const struct arpt_table_info *t,
|
||||
struct arpt_counters counters[])
|
||||
static void get_counters(const struct xt_table_info *t,
|
||||
struct xt_counters counters[])
|
||||
{
|
||||
unsigned int cpu;
|
||||
unsigned int i;
|
||||
@@ -849,7 +707,8 @@ static int copy_entries_to_user(unsigned int total_size,
|
||||
{
|
||||
unsigned int off, num, countersize;
|
||||
struct arpt_entry *e;
|
||||
struct arpt_counters *counters;
|
||||
struct xt_counters *counters;
|
||||
struct xt_table_info *private = table->private;
|
||||
int ret = 0;
|
||||
void *loc_cpu_entry;
|
||||
|
||||
@@ -857,18 +716,18 @@ static int copy_entries_to_user(unsigned int total_size,
|
||||
* (other than comefrom, which userspace doesn't care
|
||||
* about).
|
||||
*/
|
||||
countersize = sizeof(struct arpt_counters) * table->private->number;
|
||||
counters = vmalloc(countersize);
|
||||
countersize = sizeof(struct xt_counters) * private->number;
|
||||
counters = vmalloc_node(countersize, numa_node_id());
|
||||
|
||||
if (counters == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
/* First, sum counters... */
|
||||
write_lock_bh(&table->lock);
|
||||
get_counters(table->private, counters);
|
||||
get_counters(private, counters);
|
||||
write_unlock_bh(&table->lock);
|
||||
|
||||
loc_cpu_entry = table->private->entries[raw_smp_processor_id()];
|
||||
loc_cpu_entry = private->entries[raw_smp_processor_id()];
|
||||
/* ... then copy entire thing ... */
|
||||
if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) {
|
||||
ret = -EFAULT;
|
||||
@@ -911,75 +770,34 @@ static int get_entries(const struct arpt_get_entries *entries,
|
||||
int ret;
|
||||
struct arpt_table *t;
|
||||
|
||||
t = find_table_lock(entries->name);
|
||||
t = xt_find_table_lock(NF_ARP, entries->name);
|
||||
if (t || !IS_ERR(t)) {
|
||||
struct xt_table_info *private = t->private;
|
||||
duprintf("t->private->number = %u\n",
|
||||
t->private->number);
|
||||
if (entries->size == t->private->size)
|
||||
ret = copy_entries_to_user(t->private->size,
|
||||
private->number);
|
||||
if (entries->size == private->size)
|
||||
ret = copy_entries_to_user(private->size,
|
||||
t, uptr->entrytable);
|
||||
else {
|
||||
duprintf("get_entries: I've got %u not %u!\n",
|
||||
t->private->size,
|
||||
entries->size);
|
||||
private->size, entries->size);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
module_put(t->me);
|
||||
up(&arpt_mutex);
|
||||
xt_table_unlock(t);
|
||||
} else
|
||||
ret = t ? PTR_ERR(t) : -ENOENT;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void free_table_info(struct arpt_table_info *info)
|
||||
{
|
||||
int cpu;
|
||||
for_each_cpu(cpu) {
|
||||
if (info->size <= PAGE_SIZE)
|
||||
kfree(info->entries[cpu]);
|
||||
else
|
||||
vfree(info->entries[cpu]);
|
||||
}
|
||||
kfree(info);
|
||||
}
|
||||
|
||||
static struct arpt_table_info *alloc_table_info(unsigned int size)
|
||||
{
|
||||
struct arpt_table_info *newinfo;
|
||||
int cpu;
|
||||
|
||||
newinfo = kzalloc(sizeof(struct arpt_table_info), GFP_KERNEL);
|
||||
if (!newinfo)
|
||||
return NULL;
|
||||
|
||||
newinfo->size = size;
|
||||
|
||||
for_each_cpu(cpu) {
|
||||
if (size <= PAGE_SIZE)
|
||||
newinfo->entries[cpu] = kmalloc_node(size,
|
||||
GFP_KERNEL,
|
||||
cpu_to_node(cpu));
|
||||
else
|
||||
newinfo->entries[cpu] = vmalloc_node(size,
|
||||
cpu_to_node(cpu));
|
||||
|
||||
if (newinfo->entries[cpu] == NULL) {
|
||||
free_table_info(newinfo);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return newinfo;
|
||||
}
|
||||
|
||||
static int do_replace(void __user *user, unsigned int len)
|
||||
{
|
||||
int ret;
|
||||
struct arpt_replace tmp;
|
||||
struct arpt_table *t;
|
||||
struct arpt_table_info *newinfo, *oldinfo;
|
||||
struct arpt_counters *counters;
|
||||
struct xt_table_info *newinfo, *oldinfo;
|
||||
struct xt_counters *counters;
|
||||
void *loc_cpu_entry, *loc_cpu_old_entry;
|
||||
|
||||
if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
|
||||
@@ -989,11 +807,7 @@ static int do_replace(void __user *user, unsigned int len)
|
||||
if (len != sizeof(tmp) + tmp.size)
|
||||
return -ENOPROTOOPT;
|
||||
|
||||
/* Pedantry: prevent them from hitting BUG() in vmalloc.c --RR */
|
||||
if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages)
|
||||
return -ENOMEM;
|
||||
|
||||
newinfo = alloc_table_info(tmp.size);
|
||||
newinfo = xt_alloc_table_info(tmp.size);
|
||||
if (!newinfo)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -1005,7 +819,7 @@ static int do_replace(void __user *user, unsigned int len)
|
||||
goto free_newinfo;
|
||||
}
|
||||
|
||||
counters = vmalloc(tmp.num_counters * sizeof(struct arpt_counters));
|
||||
counters = vmalloc(tmp.num_counters * sizeof(struct xt_counters));
|
||||
if (!counters) {
|
||||
ret = -ENOMEM;
|
||||
goto free_newinfo;
|
||||
@@ -1019,7 +833,7 @@ static int do_replace(void __user *user, unsigned int len)
|
||||
|
||||
duprintf("arp_tables: Translated table\n");
|
||||
|
||||
t = try_then_request_module(find_table_lock(tmp.name),
|
||||
t = try_then_request_module(xt_find_table_lock(NF_ARP, tmp.name),
|
||||
"arptable_%s", tmp.name);
|
||||
if (!t || IS_ERR(t)) {
|
||||
ret = t ? PTR_ERR(t) : -ENOENT;
|
||||
@@ -1034,7 +848,7 @@ static int do_replace(void __user *user, unsigned int len)
|
||||
goto put_module;
|
||||
}
|
||||
|
||||
oldinfo = replace_table(t, tmp.num_counters, newinfo, &ret);
|
||||
oldinfo = xt_replace_table(t, tmp.num_counters, newinfo, &ret);
|
||||
if (!oldinfo)
|
||||
goto put_module;
|
||||
|
||||
@@ -1054,23 +868,23 @@ static int do_replace(void __user *user, unsigned int len)
|
||||
loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()];
|
||||
ARPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL);
|
||||
|
||||
free_table_info(oldinfo);
|
||||
xt_free_table_info(oldinfo);
|
||||
if (copy_to_user(tmp.counters, counters,
|
||||
sizeof(struct arpt_counters) * tmp.num_counters) != 0)
|
||||
sizeof(struct xt_counters) * tmp.num_counters) != 0)
|
||||
ret = -EFAULT;
|
||||
vfree(counters);
|
||||
up(&arpt_mutex);
|
||||
xt_table_unlock(t);
|
||||
return ret;
|
||||
|
||||
put_module:
|
||||
module_put(t->me);
|
||||
up(&arpt_mutex);
|
||||
xt_table_unlock(t);
|
||||
free_newinfo_counters_untrans:
|
||||
ARPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL);
|
||||
free_newinfo_counters:
|
||||
vfree(counters);
|
||||
free_newinfo:
|
||||
free_table_info(newinfo);
|
||||
xt_free_table_info(newinfo);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1078,7 +892,7 @@ static int do_replace(void __user *user, unsigned int len)
|
||||
* and everything is OK.
|
||||
*/
|
||||
static inline int add_counter_to_entry(struct arpt_entry *e,
|
||||
const struct arpt_counters addme[],
|
||||
const struct xt_counters addme[],
|
||||
unsigned int *i)
|
||||
{
|
||||
|
||||
@@ -1091,15 +905,16 @@ static inline int add_counter_to_entry(struct arpt_entry *e,
|
||||
static int do_add_counters(void __user *user, unsigned int len)
|
||||
{
|
||||
unsigned int i;
|
||||
struct arpt_counters_info tmp, *paddc;
|
||||
struct xt_counters_info tmp, *paddc;
|
||||
struct arpt_table *t;
|
||||
struct xt_table_info *private;
|
||||
int ret = 0;
|
||||
void *loc_cpu_entry;
|
||||
|
||||
if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
|
||||
return -EFAULT;
|
||||
|
||||
if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct arpt_counters))
|
||||
if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct xt_counters))
|
||||
return -EINVAL;
|
||||
|
||||
paddc = vmalloc(len);
|
||||
@@ -1111,29 +926,30 @@ static int do_add_counters(void __user *user, unsigned int len)
|
||||
goto free;
|
||||
}
|
||||
|
||||
t = find_table_lock(tmp.name);
|
||||
t = xt_find_table_lock(NF_ARP, tmp.name);
|
||||
if (!t || IS_ERR(t)) {
|
||||
ret = t ? PTR_ERR(t) : -ENOENT;
|
||||
goto free;
|
||||
}
|
||||
|
||||
write_lock_bh(&t->lock);
|
||||
if (t->private->number != paddc->num_counters) {
|
||||
private = t->private;
|
||||
if (private->number != paddc->num_counters) {
|
||||
ret = -EINVAL;
|
||||
goto unlock_up_free;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
/* Choose the copy that is on our node */
|
||||
loc_cpu_entry = t->private->entries[smp_processor_id()];
|
||||
loc_cpu_entry = private->entries[smp_processor_id()];
|
||||
ARPT_ENTRY_ITERATE(loc_cpu_entry,
|
||||
t->private->size,
|
||||
private->size,
|
||||
add_counter_to_entry,
|
||||
paddc->counters,
|
||||
&i);
|
||||
unlock_up_free:
|
||||
write_unlock_bh(&t->lock);
|
||||
up(&arpt_mutex);
|
||||
xt_table_unlock(t);
|
||||
module_put(t->me);
|
||||
free:
|
||||
vfree(paddc);
|
||||
@@ -1190,25 +1006,26 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len
|
||||
}
|
||||
name[ARPT_TABLE_MAXNAMELEN-1] = '\0';
|
||||
|
||||
t = try_then_request_module(find_table_lock(name),
|
||||
t = try_then_request_module(xt_find_table_lock(NF_ARP, name),
|
||||
"arptable_%s", name);
|
||||
if (t && !IS_ERR(t)) {
|
||||
struct arpt_getinfo info;
|
||||
struct xt_table_info *private = t->private;
|
||||
|
||||
info.valid_hooks = t->valid_hooks;
|
||||
memcpy(info.hook_entry, t->private->hook_entry,
|
||||
memcpy(info.hook_entry, private->hook_entry,
|
||||
sizeof(info.hook_entry));
|
||||
memcpy(info.underflow, t->private->underflow,
|
||||
memcpy(info.underflow, private->underflow,
|
||||
sizeof(info.underflow));
|
||||
info.num_entries = t->private->number;
|
||||
info.size = t->private->size;
|
||||
info.num_entries = private->number;
|
||||
info.size = private->size;
|
||||
strcpy(info.name, name);
|
||||
|
||||
if (copy_to_user(user, &info, *len) != 0)
|
||||
ret = -EFAULT;
|
||||
else
|
||||
ret = 0;
|
||||
up(&arpt_mutex);
|
||||
xt_table_unlock(t);
|
||||
module_put(t->me);
|
||||
} else
|
||||
ret = t ? PTR_ERR(t) : -ENOENT;
|
||||
@@ -1233,7 +1050,7 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len
|
||||
}
|
||||
|
||||
case ARPT_SO_GET_REVISION_TARGET: {
|
||||
struct arpt_get_revision rev;
|
||||
struct xt_get_revision rev;
|
||||
|
||||
if (*len != sizeof(rev)) {
|
||||
ret = -EINVAL;
|
||||
@@ -1244,8 +1061,8 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len
|
||||
break;
|
||||
}
|
||||
|
||||
try_then_request_module(find_revision(rev.name, rev.revision,
|
||||
target_revfn, &ret),
|
||||
try_then_request_module(xt_find_revision(NF_ARP, rev.name,
|
||||
rev.revision, 1, &ret),
|
||||
"arpt_%s", rev.name);
|
||||
break;
|
||||
}
|
||||
@@ -1258,38 +1075,16 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Registration hooks for targets. */
|
||||
int arpt_register_target(struct arpt_target *target)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = down_interruptible(&arpt_mutex);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
list_add(&target->list, &arpt_target);
|
||||
up(&arpt_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void arpt_unregister_target(struct arpt_target *target)
|
||||
{
|
||||
down(&arpt_mutex);
|
||||
LIST_DELETE(&arpt_target, target);
|
||||
up(&arpt_mutex);
|
||||
}
|
||||
|
||||
int arpt_register_table(struct arpt_table *table,
|
||||
const struct arpt_replace *repl)
|
||||
{
|
||||
int ret;
|
||||
struct arpt_table_info *newinfo;
|
||||
static struct arpt_table_info bootstrap
|
||||
struct xt_table_info *newinfo;
|
||||
static struct xt_table_info bootstrap
|
||||
= { 0, 0, 0, { 0 }, { 0 }, { } };
|
||||
void *loc_cpu_entry;
|
||||
|
||||
newinfo = alloc_table_info(repl->size);
|
||||
newinfo = xt_alloc_table_info(repl->size);
|
||||
if (!newinfo) {
|
||||
ret = -ENOMEM;
|
||||
return ret;
|
||||
@@ -1304,60 +1099,33 @@ int arpt_register_table(struct arpt_table *table,
|
||||
repl->num_entries,
|
||||
repl->hook_entry,
|
||||
repl->underflow);
|
||||
|
||||
duprintf("arpt_register_table: translate table gives %d\n", ret);
|
||||
if (ret != 0) {
|
||||
free_table_info(newinfo);
|
||||
xt_free_table_info(newinfo);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = down_interruptible(&arpt_mutex);
|
||||
if (ret != 0) {
|
||||
free_table_info(newinfo);
|
||||
if (xt_register_table(table, &bootstrap, newinfo) != 0) {
|
||||
xt_free_table_info(newinfo);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Don't autoload: we'd eat our tail... */
|
||||
if (list_named_find(&arpt_tables, table->name)) {
|
||||
ret = -EEXIST;
|
||||
goto free_unlock;
|
||||
}
|
||||
|
||||
/* Simplifies replace_table code. */
|
||||
table->private = &bootstrap;
|
||||
if (!replace_table(table, 0, newinfo, &ret))
|
||||
goto free_unlock;
|
||||
|
||||
duprintf("table->private->number = %u\n",
|
||||
table->private->number);
|
||||
|
||||
/* save number of initial entries */
|
||||
table->private->initial_entries = table->private->number;
|
||||
|
||||
rwlock_init(&table->lock);
|
||||
list_prepend(&arpt_tables, table);
|
||||
|
||||
unlock:
|
||||
up(&arpt_mutex);
|
||||
return ret;
|
||||
|
||||
free_unlock:
|
||||
free_table_info(newinfo);
|
||||
goto unlock;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void arpt_unregister_table(struct arpt_table *table)
|
||||
{
|
||||
struct xt_table_info *private;
|
||||
void *loc_cpu_entry;
|
||||
|
||||
down(&arpt_mutex);
|
||||
LIST_DELETE(&arpt_tables, table);
|
||||
up(&arpt_mutex);
|
||||
private = xt_unregister_table(table);
|
||||
|
||||
/* Decrease module usage counts and free resources */
|
||||
loc_cpu_entry = table->private->entries[raw_smp_processor_id()];
|
||||
ARPT_ENTRY_ITERATE(loc_cpu_entry, table->private->size,
|
||||
loc_cpu_entry = private->entries[raw_smp_processor_id()];
|
||||
ARPT_ENTRY_ITERATE(loc_cpu_entry, private->size,
|
||||
cleanup_entry, NULL);
|
||||
free_table_info(table->private);
|
||||
xt_free_table_info(private);
|
||||
}
|
||||
|
||||
/* The built-in targets: standard (NULL) and error. */
|
||||
@@ -1380,52 +1148,15 @@ static struct nf_sockopt_ops arpt_sockopts = {
|
||||
.get = do_arpt_get_ctl,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
static inline int print_name(const struct arpt_table *t,
|
||||
off_t start_offset, char *buffer, int length,
|
||||
off_t *pos, unsigned int *count)
|
||||
{
|
||||
if ((*count)++ >= start_offset) {
|
||||
unsigned int namelen;
|
||||
|
||||
namelen = sprintf(buffer + *pos, "%s\n", t->name);
|
||||
if (*pos + namelen > length) {
|
||||
/* Stop iterating */
|
||||
return 1;
|
||||
}
|
||||
*pos += namelen;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int arpt_get_tables(char *buffer, char **start, off_t offset, int length)
|
||||
{
|
||||
off_t pos = 0;
|
||||
unsigned int count = 0;
|
||||
|
||||
if (down_interruptible(&arpt_mutex) != 0)
|
||||
return 0;
|
||||
|
||||
LIST_FIND(&arpt_tables, print_name, struct arpt_table *,
|
||||
offset, buffer, length, &pos, &count);
|
||||
|
||||
up(&arpt_mutex);
|
||||
|
||||
/* `start' hack - see fs/proc/generic.c line ~105 */
|
||||
*start=(char *)((unsigned long)count-offset);
|
||||
return pos;
|
||||
}
|
||||
#endif /*CONFIG_PROC_FS*/
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
xt_proto_init(NF_ARP);
|
||||
|
||||
/* Noone else will be downing sem now, so we won't sleep */
|
||||
down(&arpt_mutex);
|
||||
list_append(&arpt_target, &arpt_standard_target);
|
||||
list_append(&arpt_target, &arpt_error_target);
|
||||
up(&arpt_mutex);
|
||||
xt_register_target(NF_ARP, &arpt_standard_target);
|
||||
xt_register_target(NF_ARP, &arpt_error_target);
|
||||
|
||||
/* Register setsockopt */
|
||||
ret = nf_register_sockopt(&arpt_sockopts);
|
||||
@@ -1434,19 +1165,6 @@ static int __init init(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
{
|
||||
struct proc_dir_entry *proc;
|
||||
|
||||
proc = proc_net_create("arp_tables_names", 0, arpt_get_tables);
|
||||
if (!proc) {
|
||||
nf_unregister_sockopt(&arpt_sockopts);
|
||||
return -ENOMEM;
|
||||
}
|
||||
proc->owner = THIS_MODULE;
|
||||
}
|
||||
#endif
|
||||
|
||||
printk("arp_tables: (C) 2002 David S. Miller\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -1454,16 +1172,12 @@ static int __init init(void)
|
||||
static void __exit fini(void)
|
||||
{
|
||||
nf_unregister_sockopt(&arpt_sockopts);
|
||||
#ifdef CONFIG_PROC_FS
|
||||
proc_net_remove("arp_tables_names");
|
||||
#endif
|
||||
xt_proto_fini(NF_ARP);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(arpt_register_table);
|
||||
EXPORT_SYMBOL(arpt_unregister_table);
|
||||
EXPORT_SYMBOL(arpt_do_table);
|
||||
EXPORT_SYMBOL(arpt_register_target);
|
||||
EXPORT_SYMBOL(arpt_unregister_target);
|
||||
|
||||
module_init(init);
|
||||
module_exit(fini);
|
||||
|
@@ -8,8 +8,9 @@ MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>");
|
||||
MODULE_DESCRIPTION("arptables arp payload mangle target");
|
||||
|
||||
static unsigned int
|
||||
target(struct sk_buff **pskb, unsigned int hooknum, const struct net_device *in,
|
||||
const struct net_device *out, const void *targinfo, void *userinfo)
|
||||
target(struct sk_buff **pskb, const struct net_device *in,
|
||||
const struct net_device *out, unsigned int hooknum, const void *targinfo,
|
||||
void *userinfo)
|
||||
{
|
||||
const struct arpt_mangle *mangle = targinfo;
|
||||
struct arphdr *arp;
|
||||
@@ -64,7 +65,7 @@ target(struct sk_buff **pskb, unsigned int hooknum, const struct net_device *in,
|
||||
}
|
||||
|
||||
static int
|
||||
checkentry(const char *tablename, const struct arpt_entry *e, void *targinfo,
|
||||
checkentry(const char *tablename, const void *e, void *targinfo,
|
||||
unsigned int targinfosize, unsigned int hook_mask)
|
||||
{
|
||||
const struct arpt_mangle *mangle = targinfo;
|
||||
|
@@ -145,6 +145,7 @@ static struct arpt_table packet_filter = {
|
||||
.lock = RW_LOCK_UNLOCKED,
|
||||
.private = NULL,
|
||||
.me = THIS_MODULE,
|
||||
.af = NF_ARP,
|
||||
};
|
||||
|
||||
/* The work comes in here from netfilter.c */
|
||||
|
@@ -944,7 +944,7 @@ module_exit(fini);
|
||||
|
||||
/* Some modules need us, but don't depend directly on any symbol.
|
||||
They should call this. */
|
||||
void need_ip_conntrack(void)
|
||||
void need_conntrack(void)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -962,7 +962,7 @@ EXPORT_SYMBOL(ip_ct_get_tuple);
|
||||
EXPORT_SYMBOL(invert_tuplepr);
|
||||
EXPORT_SYMBOL(ip_conntrack_alter_reply);
|
||||
EXPORT_SYMBOL(ip_conntrack_destroyed);
|
||||
EXPORT_SYMBOL(need_ip_conntrack);
|
||||
EXPORT_SYMBOL(need_conntrack);
|
||||
EXPORT_SYMBOL(ip_conntrack_helper_register);
|
||||
EXPORT_SYMBOL(ip_conntrack_helper_unregister);
|
||||
EXPORT_SYMBOL(ip_ct_iterate_cleanup);
|
||||
|
@@ -95,6 +95,7 @@ static struct ipt_table nat_table = {
|
||||
.valid_hooks = NAT_VALID_HOOKS,
|
||||
.lock = RW_LOCK_UNLOCKED,
|
||||
.me = THIS_MODULE,
|
||||
.af = AF_INET,
|
||||
};
|
||||
|
||||
/* Source NAT */
|
||||
@@ -168,7 +169,7 @@ static unsigned int ipt_dnat_target(struct sk_buff **pskb,
|
||||
}
|
||||
|
||||
static int ipt_snat_checkentry(const char *tablename,
|
||||
const struct ipt_entry *e,
|
||||
const void *entry,
|
||||
void *targinfo,
|
||||
unsigned int targinfosize,
|
||||
unsigned int hook_mask)
|
||||
@@ -201,7 +202,7 @@ static int ipt_snat_checkentry(const char *tablename,
|
||||
}
|
||||
|
||||
static int ipt_dnat_checkentry(const char *tablename,
|
||||
const struct ipt_entry *e,
|
||||
const void *entry,
|
||||
void *targinfo,
|
||||
unsigned int targinfosize,
|
||||
unsigned int hook_mask)
|
||||
|
@@ -364,7 +364,7 @@ static int init_or_cleanup(int init)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
need_ip_conntrack();
|
||||
need_conntrack();
|
||||
|
||||
if (!init) goto cleanup;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -379,12 +379,13 @@ target(struct sk_buff **pskb,
|
||||
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const struct ipt_entry *e,
|
||||
const void *e_void,
|
||||
void *targinfo,
|
||||
unsigned int targinfosize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
struct ipt_clusterip_tgt_info *cipinfo = targinfo;
|
||||
const struct ipt_entry *e = e_void;
|
||||
|
||||
struct clusterip_config *config;
|
||||
|
||||
|
@@ -57,7 +57,7 @@ target(struct sk_buff **pskb,
|
||||
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const struct ipt_entry *e,
|
||||
const void *e_void,
|
||||
void *targinfo,
|
||||
unsigned int targinfosize,
|
||||
unsigned int hook_mask)
|
||||
|
@@ -113,12 +113,13 @@ target(struct sk_buff **pskb,
|
||||
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const struct ipt_entry *e,
|
||||
const void *e_void,
|
||||
void *targinfo,
|
||||
unsigned int targinfosize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
const struct ipt_ECN_info *einfo = (struct ipt_ECN_info *)targinfo;
|
||||
const struct ipt_entry *e = e_void;
|
||||
|
||||
if (targinfosize != IPT_ALIGN(sizeof(struct ipt_ECN_info))) {
|
||||
printk(KERN_WARNING "ECN: targinfosize %u != %Zu\n",
|
||||
|
@@ -431,7 +431,7 @@ ipt_log_target(struct sk_buff **pskb,
|
||||
}
|
||||
|
||||
static int ipt_log_checkentry(const char *tablename,
|
||||
const struct ipt_entry *e,
|
||||
const void *e,
|
||||
void *targinfo,
|
||||
unsigned int targinfosize,
|
||||
unsigned int hook_mask)
|
||||
|
@@ -40,7 +40,7 @@ static DEFINE_RWLOCK(masq_lock);
|
||||
/* FIXME: Multiple targets. --RR */
|
||||
static int
|
||||
masquerade_check(const char *tablename,
|
||||
const struct ipt_entry *e,
|
||||
const void *e,
|
||||
void *targinfo,
|
||||
unsigned int targinfosize,
|
||||
unsigned int hook_mask)
|
||||
|
@@ -31,7 +31,7 @@ MODULE_DESCRIPTION("iptables 1:1 NAT mapping of IP networks target");
|
||||
|
||||
static int
|
||||
check(const char *tablename,
|
||||
const struct ipt_entry *e,
|
||||
const void *e,
|
||||
void *targinfo,
|
||||
unsigned int targinfosize,
|
||||
unsigned int hook_mask)
|
||||
|
@@ -1,70 +0,0 @@
|
||||
/* iptables module for using new netfilter netlink queue
|
||||
*
|
||||
* (C) 2005 by Harald Welte <laforge@netfilter.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
#include <linux/netfilter_ipv4/ipt_NFQUEUE.h>
|
||||
|
||||
MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
|
||||
MODULE_DESCRIPTION("iptables NFQUEUE target");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
static unsigned int
|
||||
target(struct sk_buff **pskb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
unsigned int hooknum,
|
||||
const void *targinfo,
|
||||
void *userinfo)
|
||||
{
|
||||
const struct ipt_NFQ_info *tinfo = targinfo;
|
||||
|
||||
return NF_QUEUE_NR(tinfo->queuenum);
|
||||
}
|
||||
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const struct ipt_entry *e,
|
||||
void *targinfo,
|
||||
unsigned int targinfosize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
if (targinfosize != IPT_ALIGN(sizeof(struct ipt_NFQ_info))) {
|
||||
printk(KERN_WARNING "NFQUEUE: targinfosize %u != %Zu\n",
|
||||
targinfosize,
|
||||
IPT_ALIGN(sizeof(struct ipt_NFQ_info)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct ipt_target ipt_NFQ_reg = {
|
||||
.name = "NFQUEUE",
|
||||
.target = target,
|
||||
.checkentry = checkentry,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
return ipt_register_target(&ipt_NFQ_reg);
|
||||
}
|
||||
|
||||
static void __exit fini(void)
|
||||
{
|
||||
ipt_unregister_target(&ipt_NFQ_reg);
|
||||
}
|
||||
|
||||
module_init(init);
|
||||
module_exit(fini);
|
@@ -33,7 +33,7 @@ MODULE_DESCRIPTION("iptables REDIRECT target module");
|
||||
/* FIXME: Take multiple ranges --RR */
|
||||
static int
|
||||
redirect_check(const char *tablename,
|
||||
const struct ipt_entry *e,
|
||||
const void *e,
|
||||
void *targinfo,
|
||||
unsigned int targinfosize,
|
||||
unsigned int hook_mask)
|
||||
|
@@ -282,12 +282,13 @@ static unsigned int reject(struct sk_buff **pskb,
|
||||
}
|
||||
|
||||
static int check(const char *tablename,
|
||||
const struct ipt_entry *e,
|
||||
const void *e_void,
|
||||
void *targinfo,
|
||||
unsigned int targinfosize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
const struct ipt_reject_info *rejinfo = targinfo;
|
||||
const struct ipt_entry *e = e_void;
|
||||
|
||||
if (targinfosize != IPT_ALIGN(sizeof(struct ipt_reject_info))) {
|
||||
DEBUGP("REJECT: targinfosize %u != 0\n", targinfosize);
|
||||
|
@@ -49,7 +49,7 @@ MODULE_DESCRIPTION("iptables special SNAT module for consistent sourceip");
|
||||
|
||||
static int
|
||||
same_check(const char *tablename,
|
||||
const struct ipt_entry *e,
|
||||
const void *e,
|
||||
void *targinfo,
|
||||
unsigned int targinfosize,
|
||||
unsigned int hook_mask)
|
||||
|
@@ -210,12 +210,13 @@ static inline int find_syn_match(const struct ipt_entry_match *m)
|
||||
/* Must specify -p tcp --syn/--tcp-flags SYN */
|
||||
static int
|
||||
ipt_tcpmss_checkentry(const char *tablename,
|
||||
const struct ipt_entry *e,
|
||||
const void *e_void,
|
||||
void *targinfo,
|
||||
unsigned int targinfosize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
const struct ipt_tcpmss_info *tcpmssinfo = targinfo;
|
||||
const struct ipt_entry *e = e_void;
|
||||
|
||||
if (targinfosize != IPT_ALIGN(sizeof(struct ipt_tcpmss_info))) {
|
||||
DEBUGP("ipt_tcpmss_checkentry: targinfosize %u != %u\n",
|
||||
|
@@ -52,7 +52,7 @@ target(struct sk_buff **pskb,
|
||||
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const struct ipt_entry *e,
|
||||
const void *e_void,
|
||||
void *targinfo,
|
||||
unsigned int targinfosize,
|
||||
unsigned int hook_mask)
|
||||
|
@@ -66,7 +66,7 @@ ipt_ttl_target(struct sk_buff **pskb, const struct net_device *in,
|
||||
}
|
||||
|
||||
static int ipt_ttl_checkentry(const char *tablename,
|
||||
const struct ipt_entry *e,
|
||||
const void *e,
|
||||
void *targinfo,
|
||||
unsigned int targinfosize,
|
||||
unsigned int hook_mask)
|
||||
|
@@ -330,7 +330,7 @@ static void ipt_logfn(unsigned int pf,
|
||||
}
|
||||
|
||||
static int ipt_ulog_checkentry(const char *tablename,
|
||||
const struct ipt_entry *e,
|
||||
const void *e,
|
||||
void *targinfo,
|
||||
unsigned int targinfosize,
|
||||
unsigned int hookmask)
|
||||
|
@@ -29,7 +29,7 @@ static inline int match_type(u_int32_t addr, u_int16_t mask)
|
||||
|
||||
static int match(const struct sk_buff *skb, const struct net_device *in,
|
||||
const struct net_device *out, const void *matchinfo,
|
||||
int offset, int *hotdrop)
|
||||
int offset, unsigned int protoff, int *hotdrop)
|
||||
{
|
||||
const struct ipt_addrtype_info *info = matchinfo;
|
||||
const struct iphdr *iph = skb->nh.iph;
|
||||
@@ -43,7 +43,7 @@ static int match(const struct sk_buff *skb, const struct net_device *in,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int checkentry(const char *tablename, const struct ipt_ip *ip,
|
||||
static int checkentry(const char *tablename, const void *ip,
|
||||
void *matchinfo, unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
|
@@ -41,6 +41,7 @@ match(const struct sk_buff *skb,
|
||||
const struct net_device *out,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
struct ip_auth_hdr _ahdr, *ah;
|
||||
@@ -50,7 +51,7 @@ match(const struct sk_buff *skb,
|
||||
if (offset)
|
||||
return 0;
|
||||
|
||||
ah = skb_header_pointer(skb, skb->nh.iph->ihl * 4,
|
||||
ah = skb_header_pointer(skb, protoff,
|
||||
sizeof(_ahdr), &_ahdr);
|
||||
if (ah == NULL) {
|
||||
/* We've been asked to examine this packet, and we
|
||||
@@ -69,12 +70,13 @@ match(const struct sk_buff *skb,
|
||||
/* Called when user tries to insert an entry of this type. */
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const struct ipt_ip *ip,
|
||||
const void *ip_void,
|
||||
void *matchinfo,
|
||||
unsigned int matchinfosize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
const struct ipt_ah *ahinfo = matchinfo;
|
||||
const struct ipt_ip *ip = ip_void;
|
||||
|
||||
/* Must specify proto == AH, and no unknown invflags */
|
||||
if (ip->proto != IPPROTO_AH || (ip->invflags & IPT_INV_PROTO)) {
|
||||
|
@@ -21,7 +21,7 @@ MODULE_LICENSE("GPL");
|
||||
|
||||
static int match(const struct sk_buff *skb, const struct net_device *in,
|
||||
const struct net_device *out, const void *matchinfo,
|
||||
int offset, int *hotdrop)
|
||||
int offset, unsigned int protoff, int *hotdrop)
|
||||
{
|
||||
const struct ipt_dscp_info *info = matchinfo;
|
||||
const struct iphdr *iph = skb->nh.iph;
|
||||
@@ -31,7 +31,7 @@ static int match(const struct sk_buff *skb, const struct net_device *in,
|
||||
return ((iph->tos&IPT_DSCP_MASK) == sh_dscp) ^ info->invert;
|
||||
}
|
||||
|
||||
static int checkentry(const char *tablename, const struct ipt_ip *ip,
|
||||
static int checkentry(const char *tablename, const void *ip,
|
||||
void *matchinfo, unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
|
@@ -67,7 +67,7 @@ static inline int match_tcp(const struct sk_buff *skb,
|
||||
|
||||
static int match(const struct sk_buff *skb, const struct net_device *in,
|
||||
const struct net_device *out, const void *matchinfo,
|
||||
int offset, int *hotdrop)
|
||||
int offset, unsigned int protoff, int *hotdrop)
|
||||
{
|
||||
const struct ipt_ecn_info *info = matchinfo;
|
||||
|
||||
@@ -85,11 +85,12 @@ static int match(const struct sk_buff *skb, const struct net_device *in,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int checkentry(const char *tablename, const struct ipt_ip *ip,
|
||||
static int checkentry(const char *tablename, const void *ip_void,
|
||||
void *matchinfo, unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
const struct ipt_ecn_info *info = matchinfo;
|
||||
const struct ipt_ip *ip = ip_void;
|
||||
|
||||
if (matchsize != IPT_ALIGN(sizeof(struct ipt_ecn_info)))
|
||||
return 0;
|
||||
|
@@ -42,6 +42,7 @@ match(const struct sk_buff *skb,
|
||||
const struct net_device *out,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
struct ip_esp_hdr _esp, *eh;
|
||||
@@ -51,7 +52,7 @@ match(const struct sk_buff *skb,
|
||||
if (offset)
|
||||
return 0;
|
||||
|
||||
eh = skb_header_pointer(skb, skb->nh.iph->ihl * 4,
|
||||
eh = skb_header_pointer(skb, protoff,
|
||||
sizeof(_esp), &_esp);
|
||||
if (eh == NULL) {
|
||||
/* We've been asked to examine this packet, and we
|
||||
@@ -70,12 +71,13 @@ match(const struct sk_buff *skb,
|
||||
/* Called when user tries to insert an entry of this type. */
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const struct ipt_ip *ip,
|
||||
const void *ip_void,
|
||||
void *matchinfo,
|
||||
unsigned int matchinfosize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
const struct ipt_esp *espinfo = matchinfo;
|
||||
const struct ipt_ip *ip = ip_void;
|
||||
|
||||
/* Must specify proto == ESP, and no unknown invflags */
|
||||
if (ip->proto != IPPROTO_ESP || (ip->invflags & IPT_INV_PROTO)) {
|
||||
|
@@ -429,6 +429,7 @@ hashlimit_match(const struct sk_buff *skb,
|
||||
const struct net_device *out,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
struct ipt_hashlimit_info *r =
|
||||
@@ -504,7 +505,7 @@ hashlimit_match(const struct sk_buff *skb,
|
||||
|
||||
static int
|
||||
hashlimit_checkentry(const char *tablename,
|
||||
const struct ipt_ip *ip,
|
||||
const void *inf,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
|
@@ -28,7 +28,7 @@ match(const struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
const void *matchinfo,
|
||||
int offset, int *hotdrop)
|
||||
int offset, unsigned int protoff, int *hotdrop)
|
||||
{
|
||||
const struct ipt_iprange_info *info = matchinfo;
|
||||
const struct iphdr *iph = skb->nh.iph;
|
||||
@@ -63,7 +63,7 @@ match(const struct sk_buff *skb,
|
||||
}
|
||||
|
||||
static int check(const char *tablename,
|
||||
const struct ipt_ip *ip,
|
||||
const void *inf,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
|
@@ -1,64 +0,0 @@
|
||||
/* Kernel module to match packet length. */
|
||||
/* (C) 1999-2001 James Morris <jmorros@intercode.com.au>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
|
||||
#include <linux/netfilter_ipv4/ipt_length.h>
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
|
||||
MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>");
|
||||
MODULE_DESCRIPTION("IP tables packet length matching module");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
static int
|
||||
match(const struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
int *hotdrop)
|
||||
{
|
||||
const struct ipt_length_info *info = matchinfo;
|
||||
u_int16_t pktlen = ntohs(skb->nh.iph->tot_len);
|
||||
|
||||
return (pktlen >= info->min && pktlen <= info->max) ^ info->invert;
|
||||
}
|
||||
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const struct ipt_ip *ip,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
if (matchsize != IPT_ALIGN(sizeof(struct ipt_length_info)))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct ipt_match length_match = {
|
||||
.name = "length",
|
||||
.match = &match,
|
||||
.checkentry = &checkentry,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
return ipt_register_match(&length_match);
|
||||
}
|
||||
|
||||
static void __exit fini(void)
|
||||
{
|
||||
ipt_unregister_match(&length_match);
|
||||
}
|
||||
|
||||
module_init(init);
|
||||
module_exit(fini);
|
@@ -97,6 +97,7 @@ match(const struct sk_buff *skb,
|
||||
const struct net_device *out,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
u16 _ports[2], *pptr;
|
||||
@@ -105,7 +106,7 @@ match(const struct sk_buff *skb,
|
||||
if (offset)
|
||||
return 0;
|
||||
|
||||
pptr = skb_header_pointer(skb, skb->nh.iph->ihl * 4,
|
||||
pptr = skb_header_pointer(skb, protoff,
|
||||
sizeof(_ports), _ports);
|
||||
if (pptr == NULL) {
|
||||
/* We've been asked to examine this packet, and we
|
||||
@@ -128,6 +129,7 @@ match_v1(const struct sk_buff *skb,
|
||||
const struct net_device *out,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
u16 _ports[2], *pptr;
|
||||
@@ -136,7 +138,7 @@ match_v1(const struct sk_buff *skb,
|
||||
if (offset)
|
||||
return 0;
|
||||
|
||||
pptr = skb_header_pointer(skb, skb->nh.iph->ihl * 4,
|
||||
pptr = skb_header_pointer(skb, protoff,
|
||||
sizeof(_ports), _ports);
|
||||
if (pptr == NULL) {
|
||||
/* We've been asked to examine this packet, and we
|
||||
@@ -154,7 +156,7 @@ match_v1(const struct sk_buff *skb,
|
||||
/* Called when user tries to insert an entry of this type. */
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const struct ipt_ip *ip,
|
||||
const void *ip,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
@@ -164,7 +166,7 @@ checkentry(const char *tablename,
|
||||
|
||||
static int
|
||||
checkentry_v1(const char *tablename,
|
||||
const struct ipt_ip *ip,
|
||||
const void *ip,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
|
@@ -27,6 +27,7 @@ match(const struct sk_buff *skb,
|
||||
const struct net_device *out,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
const struct ipt_owner_info *info = matchinfo;
|
||||
@@ -51,7 +52,7 @@ match(const struct sk_buff *skb,
|
||||
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const struct ipt_ip *ip,
|
||||
const void *ip,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
|
@@ -1,135 +0,0 @@
|
||||
/* Kernel module to match the bridge port in and
|
||||
* out device for IP packets coming into contact with a bridge. */
|
||||
|
||||
/* (C) 2001-2003 Bart De Schuymer <bdschuym@pandora.be>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/netfilter_ipv4/ipt_physdev.h>
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
#include <linux/netfilter_bridge.h>
|
||||
#define MATCH 1
|
||||
#define NOMATCH 0
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>");
|
||||
MODULE_DESCRIPTION("iptables bridge physical device match module");
|
||||
|
||||
static int
|
||||
match(const struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
int *hotdrop)
|
||||
{
|
||||
int i;
|
||||
static const char nulldevname[IFNAMSIZ];
|
||||
const struct ipt_physdev_info *info = matchinfo;
|
||||
unsigned int ret;
|
||||
const char *indev, *outdev;
|
||||
struct nf_bridge_info *nf_bridge;
|
||||
|
||||
/* Not a bridged IP packet or no info available yet:
|
||||
* LOCAL_OUT/mangle and LOCAL_OUT/nat don't know if
|
||||
* the destination device will be a bridge. */
|
||||
if (!(nf_bridge = skb->nf_bridge)) {
|
||||
/* Return MATCH if the invert flags of the used options are on */
|
||||
if ((info->bitmask & IPT_PHYSDEV_OP_BRIDGED) &&
|
||||
!(info->invert & IPT_PHYSDEV_OP_BRIDGED))
|
||||
return NOMATCH;
|
||||
if ((info->bitmask & IPT_PHYSDEV_OP_ISIN) &&
|
||||
!(info->invert & IPT_PHYSDEV_OP_ISIN))
|
||||
return NOMATCH;
|
||||
if ((info->bitmask & IPT_PHYSDEV_OP_ISOUT) &&
|
||||
!(info->invert & IPT_PHYSDEV_OP_ISOUT))
|
||||
return NOMATCH;
|
||||
if ((info->bitmask & IPT_PHYSDEV_OP_IN) &&
|
||||
!(info->invert & IPT_PHYSDEV_OP_IN))
|
||||
return NOMATCH;
|
||||
if ((info->bitmask & IPT_PHYSDEV_OP_OUT) &&
|
||||
!(info->invert & IPT_PHYSDEV_OP_OUT))
|
||||
return NOMATCH;
|
||||
return MATCH;
|
||||
}
|
||||
|
||||
/* This only makes sense in the FORWARD and POSTROUTING chains */
|
||||
if ((info->bitmask & IPT_PHYSDEV_OP_BRIDGED) &&
|
||||
(!!(nf_bridge->mask & BRNF_BRIDGED) ^
|
||||
!(info->invert & IPT_PHYSDEV_OP_BRIDGED)))
|
||||
return NOMATCH;
|
||||
|
||||
if ((info->bitmask & IPT_PHYSDEV_OP_ISIN &&
|
||||
(!nf_bridge->physindev ^ !!(info->invert & IPT_PHYSDEV_OP_ISIN))) ||
|
||||
(info->bitmask & IPT_PHYSDEV_OP_ISOUT &&
|
||||
(!nf_bridge->physoutdev ^ !!(info->invert & IPT_PHYSDEV_OP_ISOUT))))
|
||||
return NOMATCH;
|
||||
|
||||
if (!(info->bitmask & IPT_PHYSDEV_OP_IN))
|
||||
goto match_outdev;
|
||||
indev = nf_bridge->physindev ? nf_bridge->physindev->name : nulldevname;
|
||||
for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) {
|
||||
ret |= (((const unsigned int *)indev)[i]
|
||||
^ ((const unsigned int *)info->physindev)[i])
|
||||
& ((const unsigned int *)info->in_mask)[i];
|
||||
}
|
||||
|
||||
if ((ret == 0) ^ !(info->invert & IPT_PHYSDEV_OP_IN))
|
||||
return NOMATCH;
|
||||
|
||||
match_outdev:
|
||||
if (!(info->bitmask & IPT_PHYSDEV_OP_OUT))
|
||||
return MATCH;
|
||||
outdev = nf_bridge->physoutdev ?
|
||||
nf_bridge->physoutdev->name : nulldevname;
|
||||
for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) {
|
||||
ret |= (((const unsigned int *)outdev)[i]
|
||||
^ ((const unsigned int *)info->physoutdev)[i])
|
||||
& ((const unsigned int *)info->out_mask)[i];
|
||||
}
|
||||
|
||||
return (ret != 0) ^ !(info->invert & IPT_PHYSDEV_OP_OUT);
|
||||
}
|
||||
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const struct ipt_ip *ip,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
const struct ipt_physdev_info *info = matchinfo;
|
||||
|
||||
if (matchsize != IPT_ALIGN(sizeof(struct ipt_physdev_info)))
|
||||
return 0;
|
||||
if (!(info->bitmask & IPT_PHYSDEV_OP_MASK) ||
|
||||
info->bitmask & ~IPT_PHYSDEV_OP_MASK)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct ipt_match physdev_match = {
|
||||
.name = "physdev",
|
||||
.match = &match,
|
||||
.checkentry = &checkentry,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
return ipt_register_match(&physdev_match);
|
||||
}
|
||||
|
||||
static void __exit fini(void)
|
||||
{
|
||||
ipt_unregister_match(&physdev_match);
|
||||
}
|
||||
|
||||
module_init(init);
|
||||
module_exit(fini);
|
@@ -104,6 +104,7 @@ match(const struct sk_buff *skb,
|
||||
const struct net_device *out,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop);
|
||||
|
||||
/* Function to hash a given address into the hash table of table_size size */
|
||||
@@ -317,7 +318,7 @@ static int ip_recent_ctrl(struct file *file, const char __user *input, unsigned
|
||||
skb->nh.iph->daddr = 0;
|
||||
/* Clear ttl since we have no way of knowing it */
|
||||
skb->nh.iph->ttl = 0;
|
||||
match(skb,NULL,NULL,info,0,NULL);
|
||||
match(skb,NULL,NULL,info,0,0,NULL);
|
||||
|
||||
kfree(skb->nh.iph);
|
||||
out_free_skb:
|
||||
@@ -357,6 +358,7 @@ match(const struct sk_buff *skb,
|
||||
const struct net_device *out,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
int pkt_count, hits_found, ans;
|
||||
@@ -654,7 +656,7 @@ match(const struct sk_buff *skb,
|
||||
*/
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const struct ipt_ip *ip,
|
||||
const void *ip,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
|
@@ -23,6 +23,7 @@ match(const struct sk_buff *skb,
|
||||
const struct net_device *out,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
const struct ipt_tos_info *info = matchinfo;
|
||||
@@ -32,7 +33,7 @@ match(const struct sk_buff *skb,
|
||||
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const struct ipt_ip *ip,
|
||||
const void *ip,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
|
@@ -21,7 +21,7 @@ MODULE_LICENSE("GPL");
|
||||
|
||||
static int match(const struct sk_buff *skb, const struct net_device *in,
|
||||
const struct net_device *out, const void *matchinfo,
|
||||
int offset, int *hotdrop)
|
||||
int offset, unsigned int protoff, int *hotdrop)
|
||||
{
|
||||
const struct ipt_ttl_info *info = matchinfo;
|
||||
|
||||
@@ -47,7 +47,7 @@ static int match(const struct sk_buff *skb, const struct net_device *in,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int checkentry(const char *tablename, const struct ipt_ip *ip,
|
||||
static int checkentry(const char *tablename, const void *ip,
|
||||
void *matchinfo, unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
|
@@ -78,7 +78,8 @@ static struct ipt_table packet_filter = {
|
||||
.name = "filter",
|
||||
.valid_hooks = FILTER_VALID_HOOKS,
|
||||
.lock = RW_LOCK_UNLOCKED,
|
||||
.me = THIS_MODULE
|
||||
.me = THIS_MODULE,
|
||||
.af = AF_INET,
|
||||
};
|
||||
|
||||
/* The work comes in here from netfilter.c. */
|
||||
|
@@ -109,6 +109,7 @@ static struct ipt_table packet_mangler = {
|
||||
.valid_hooks = MANGLE_VALID_HOOKS,
|
||||
.lock = RW_LOCK_UNLOCKED,
|
||||
.me = THIS_MODULE,
|
||||
.af = AF_INET,
|
||||
};
|
||||
|
||||
/* The work comes in here from netfilter.c. */
|
||||
|
@@ -83,7 +83,8 @@ static struct ipt_table packet_raw = {
|
||||
.name = "raw",
|
||||
.valid_hooks = RAW_VALID_HOOKS,
|
||||
.lock = RW_LOCK_UNLOCKED,
|
||||
.me = THIS_MODULE
|
||||
.me = THIS_MODULE,
|
||||
.af = AF_INET,
|
||||
};
|
||||
|
||||
/* The work comes in here from netfilter.c. */
|
||||
|
@@ -575,7 +575,7 @@ MODULE_LICENSE("GPL");
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
need_nf_conntrack();
|
||||
need_conntrack();
|
||||
return init_or_cleanup(1);
|
||||
}
|
||||
|
||||
@@ -587,9 +587,4 @@ static void __exit fini(void)
|
||||
module_init(init);
|
||||
module_exit(fini);
|
||||
|
||||
void need_ip_conntrack(void)
|
||||
{
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(need_ip_conntrack);
|
||||
EXPORT_SYMBOL(nf_ct_ipv4_gather_frags);
|
||||
|
@@ -41,6 +41,7 @@ config IP6_NF_QUEUE
|
||||
|
||||
config IP6_NF_IPTABLES
|
||||
tristate "IP6 tables support (required for filtering/masq/NAT)"
|
||||
depends on NETFILTER_XTABLES
|
||||
help
|
||||
ip6tables is a general, extensible packet identification framework.
|
||||
Currently only the packet filtering and packet mangling subsystem
|
||||
@@ -50,25 +51,6 @@ config IP6_NF_IPTABLES
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
# The simple matches.
|
||||
config IP6_NF_MATCH_LIMIT
|
||||
tristate "limit match support"
|
||||
depends on IP6_NF_IPTABLES
|
||||
help
|
||||
limit matching allows you to control the rate at which a rule can be
|
||||
matched: mainly useful in combination with the LOG target ("LOG
|
||||
target support", below) and to avoid some Denial of Service attacks.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP6_NF_MATCH_MAC
|
||||
tristate "MAC address match support"
|
||||
depends on IP6_NF_IPTABLES
|
||||
help
|
||||
mac matching allows you to match packets based on the source
|
||||
Ethernet address of the packet.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP6_NF_MATCH_RT
|
||||
tristate "Routing header match support"
|
||||
depends on IP6_NF_IPTABLES
|
||||
@@ -124,16 +106,6 @@ config IP6_NF_MATCH_OWNER
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP6_NF_MATCH_MARK
|
||||
tristate "netfilter MARK match support"
|
||||
depends on IP6_NF_IPTABLES
|
||||
help
|
||||
Netfilter mark matching allows you to match packets based on the
|
||||
`nfmark' value in the packet. This can be set by the MARK target
|
||||
(see below).
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP6_NF_MATCH_IPV6HEADER
|
||||
tristate "IPv6 Extension Headers Match"
|
||||
depends on IP6_NF_IPTABLES
|
||||
@@ -151,15 +123,6 @@ config IP6_NF_MATCH_AHESP
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP6_NF_MATCH_LENGTH
|
||||
tristate "Packet Length match support"
|
||||
depends on IP6_NF_IPTABLES
|
||||
help
|
||||
This option allows you to match the length of a packet against a
|
||||
specific value or range of values.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP6_NF_MATCH_EUI64
|
||||
tristate "EUI64 address check"
|
||||
depends on IP6_NF_IPTABLES
|
||||
@@ -170,15 +133,6 @@ config IP6_NF_MATCH_EUI64
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP6_NF_MATCH_PHYSDEV
|
||||
tristate "Physdev match support"
|
||||
depends on IP6_NF_IPTABLES && BRIDGE_NETFILTER
|
||||
help
|
||||
Physdev packet matching matches against the physical bridge ports
|
||||
the IP packet arrived on or will leave by.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP6_NF_MATCH_POLICY
|
||||
tristate "IPsec policy match support"
|
||||
depends on IP6_NF_IPTABLES && XFRM
|
||||
@@ -219,17 +173,6 @@ config IP6_NF_TARGET_REJECT
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP6_NF_TARGET_NFQUEUE
|
||||
tristate "NFQUEUE Target Support"
|
||||
depends on IP6_NF_IPTABLES
|
||||
help
|
||||
This Target replaced the old obsolete QUEUE target.
|
||||
|
||||
As opposed to QUEUE, it supports 65535 different queues,
|
||||
not just one.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP6_NF_MANGLE
|
||||
tristate "Packet mangling"
|
||||
depends on IP6_NF_IPTABLES
|
||||
@@ -240,19 +183,6 @@ config IP6_NF_MANGLE
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP6_NF_TARGET_MARK
|
||||
tristate "MARK target support"
|
||||
depends on IP6_NF_MANGLE
|
||||
help
|
||||
This option adds a `MARK' target, which allows you to create rules
|
||||
in the `mangle' table which alter the netfilter mark (nfmark) field
|
||||
associated with the packet packet prior to routing. This can change
|
||||
the routing method (see `Use netfilter MARK value as routing
|
||||
key') and can also be used by other subsystems to change their
|
||||
behavior.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP6_NF_TARGET_HL
|
||||
tristate 'HL (hoplimit) target support'
|
||||
depends on IP6_NF_MANGLE
|
||||
|
@@ -4,10 +4,7 @@
|
||||
|
||||
# Link order matters here.
|
||||
obj-$(CONFIG_IP6_NF_IPTABLES) += ip6_tables.o
|
||||
obj-$(CONFIG_IP6_NF_MATCH_LIMIT) += ip6t_limit.o
|
||||
obj-$(CONFIG_IP6_NF_MATCH_MARK) += ip6t_mark.o
|
||||
obj-$(CONFIG_IP6_NF_MATCH_LENGTH) += ip6t_length.o
|
||||
obj-$(CONFIG_IP6_NF_MATCH_MAC) += ip6t_mac.o
|
||||
obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o
|
||||
obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o ip6t_dst.o
|
||||
obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o
|
||||
@@ -17,12 +14,9 @@ obj-$(CONFIG_IP6_NF_MATCH_POLICY) += ip6t_policy.o
|
||||
obj-$(CONFIG_IP6_NF_MATCH_EUI64) += ip6t_eui64.o
|
||||
obj-$(CONFIG_IP6_NF_MATCH_MULTIPORT) += ip6t_multiport.o
|
||||
obj-$(CONFIG_IP6_NF_MATCH_OWNER) += ip6t_owner.o
|
||||
obj-$(CONFIG_IP6_NF_MATCH_PHYSDEV) += ip6t_physdev.o
|
||||
obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o
|
||||
obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o
|
||||
obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o
|
||||
obj-$(CONFIG_IP6_NF_TARGET_HL) += ip6t_HL.o
|
||||
obj-$(CONFIG_IP6_NF_TARGET_NFQUEUE) += ip6t_NFQUEUE.o
|
||||
obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o
|
||||
obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o
|
||||
obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -62,7 +62,7 @@ static unsigned int ip6t_hl_target(struct sk_buff **pskb,
|
||||
}
|
||||
|
||||
static int ip6t_hl_checkentry(const char *tablename,
|
||||
const struct ip6t_entry *e,
|
||||
const void *entry,
|
||||
void *targinfo,
|
||||
unsigned int targinfosize,
|
||||
unsigned int hook_mask)
|
||||
|
@@ -444,7 +444,7 @@ ip6t_log_target(struct sk_buff **pskb,
|
||||
|
||||
|
||||
static int ip6t_log_checkentry(const char *tablename,
|
||||
const struct ip6t_entry *e,
|
||||
const void *entry,
|
||||
void *targinfo,
|
||||
unsigned int targinfosize,
|
||||
unsigned int hook_mask)
|
||||
|
@@ -1,81 +0,0 @@
|
||||
/* This is a module which is used for setting the NFMARK field of an skb. */
|
||||
|
||||
/* (C) 1999-2001 Marc Boucher <marc@mbsi.ca>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/ip.h>
|
||||
#include <net/checksum.h>
|
||||
|
||||
#include <linux/netfilter_ipv6/ip6_tables.h>
|
||||
#include <linux/netfilter_ipv6/ip6t_MARK.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
|
||||
|
||||
static unsigned int
|
||||
target(struct sk_buff **pskb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
unsigned int hooknum,
|
||||
const void *targinfo,
|
||||
void *userinfo)
|
||||
{
|
||||
const struct ip6t_mark_target_info *markinfo = targinfo;
|
||||
|
||||
if((*pskb)->nfmark != markinfo->mark)
|
||||
(*pskb)->nfmark = markinfo->mark;
|
||||
|
||||
return IP6T_CONTINUE;
|
||||
}
|
||||
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const struct ip6t_entry *e,
|
||||
void *targinfo,
|
||||
unsigned int targinfosize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_mark_target_info))) {
|
||||
printk(KERN_WARNING "MARK: targinfosize %u != %Zu\n",
|
||||
targinfosize,
|
||||
IP6T_ALIGN(sizeof(struct ip6t_mark_target_info)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strcmp(tablename, "mangle") != 0) {
|
||||
printk(KERN_WARNING "MARK: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct ip6t_target ip6t_mark_reg = {
|
||||
.name = "MARK",
|
||||
.target = target,
|
||||
.checkentry = checkentry,
|
||||
.me = THIS_MODULE
|
||||
};
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
printk(KERN_DEBUG "registering ipv6 mark target\n");
|
||||
if (ip6t_register_target(&ip6t_mark_reg))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit fini(void)
|
||||
{
|
||||
ip6t_unregister_target(&ip6t_mark_reg);
|
||||
}
|
||||
|
||||
module_init(init);
|
||||
module_exit(fini);
|
@@ -1,70 +0,0 @@
|
||||
/* ip6tables module for using new netfilter netlink queue
|
||||
*
|
||||
* (C) 2005 by Harald Welte <laforge@netfilter.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/netfilter_ipv6/ip6_tables.h>
|
||||
#include <linux/netfilter_ipv4/ipt_NFQUEUE.h>
|
||||
|
||||
MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
|
||||
MODULE_DESCRIPTION("ip6tables NFQUEUE target");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
static unsigned int
|
||||
target(struct sk_buff **pskb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
unsigned int hooknum,
|
||||
const void *targinfo,
|
||||
void *userinfo)
|
||||
{
|
||||
const struct ipt_NFQ_info *tinfo = targinfo;
|
||||
|
||||
return NF_QUEUE_NR(tinfo->queuenum);
|
||||
}
|
||||
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const struct ip6t_entry *e,
|
||||
void *targinfo,
|
||||
unsigned int targinfosize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
if (targinfosize != IP6T_ALIGN(sizeof(struct ipt_NFQ_info))) {
|
||||
printk(KERN_WARNING "NFQUEUE: targinfosize %u != %Zu\n",
|
||||
targinfosize,
|
||||
IP6T_ALIGN(sizeof(struct ipt_NFQ_info)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct ip6t_target ipt_NFQ_reg = {
|
||||
.name = "NFQUEUE",
|
||||
.target = target,
|
||||
.checkentry = checkentry,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
return ip6t_register_target(&ipt_NFQ_reg);
|
||||
}
|
||||
|
||||
static void __exit fini(void)
|
||||
{
|
||||
ip6t_unregister_target(&ipt_NFQ_reg);
|
||||
}
|
||||
|
||||
module_init(init);
|
||||
module_exit(fini);
|
@@ -218,12 +218,13 @@ static unsigned int reject6_target(struct sk_buff **pskb,
|
||||
}
|
||||
|
||||
static int check(const char *tablename,
|
||||
const struct ip6t_entry *e,
|
||||
const void *entry,
|
||||
void *targinfo,
|
||||
unsigned int targinfosize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
const struct ip6t_reject_info *rejinfo = targinfo;
|
||||
const struct ip6t_entry *e = entry;
|
||||
|
||||
if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_reject_info))) {
|
||||
DEBUGP("ip6t_REJECT: targinfosize %u != 0\n", targinfosize);
|
||||
|
@@ -98,7 +98,7 @@ match(const struct sk_buff *skb,
|
||||
/* Called when user tries to insert an entry of this type. */
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const struct ip6t_ip6 *ip,
|
||||
const void *entry,
|
||||
void *matchinfo,
|
||||
unsigned int matchinfosize,
|
||||
unsigned int hook_mask)
|
||||
|
@@ -178,7 +178,7 @@ match(const struct sk_buff *skb,
|
||||
/* Called when user tries to insert an entry of this type. */
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const struct ip6t_ip6 *ip,
|
||||
const void *info,
|
||||
void *matchinfo,
|
||||
unsigned int matchinfosize,
|
||||
unsigned int hook_mask)
|
||||
|
@@ -76,7 +76,7 @@ match(const struct sk_buff *skb,
|
||||
/* Called when user tries to insert an entry of this type. */
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const struct ip6t_ip6 *ip,
|
||||
const void *ip,
|
||||
void *matchinfo,
|
||||
unsigned int matchinfosize,
|
||||
unsigned int hook_mask)
|
||||
|
@@ -62,7 +62,7 @@ match(const struct sk_buff *skb,
|
||||
|
||||
static int
|
||||
ip6t_eui64_checkentry(const char *tablename,
|
||||
const struct ip6t_ip6 *ip,
|
||||
const void *ip,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
|
@@ -115,7 +115,7 @@ match(const struct sk_buff *skb,
|
||||
/* Called when user tries to insert an entry of this type. */
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const struct ip6t_ip6 *ip,
|
||||
const void *ip,
|
||||
void *matchinfo,
|
||||
unsigned int matchinfosize,
|
||||
unsigned int hook_mask)
|
||||
|
@@ -178,7 +178,7 @@ match(const struct sk_buff *skb,
|
||||
/* Called when user tries to insert an entry of this type. */
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const struct ip6t_ip6 *ip,
|
||||
const void *entry,
|
||||
void *matchinfo,
|
||||
unsigned int matchinfosize,
|
||||
unsigned int hook_mask)
|
||||
|
@@ -48,7 +48,7 @@ static int match(const struct sk_buff *skb, const struct net_device *in,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int checkentry(const char *tablename, const struct ip6t_ip6 *ip,
|
||||
static int checkentry(const char *tablename, const void *entry,
|
||||
void *matchinfo, unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
|
@@ -124,7 +124,7 @@ ipv6header_match(const struct sk_buff *skb,
|
||||
|
||||
static int
|
||||
ipv6header_checkentry(const char *tablename,
|
||||
const struct ip6t_ip6 *ip,
|
||||
const void *ip,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
|
@@ -1,66 +0,0 @@
|
||||
/* Length Match - IPv6 Port */
|
||||
|
||||
/* (C) 1999-2001 James Morris <jmorros@intercode.com.au>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/netfilter_ipv6/ip6t_length.h>
|
||||
#include <linux/netfilter_ipv6/ip6_tables.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>");
|
||||
MODULE_DESCRIPTION("IPv6 packet length match");
|
||||
|
||||
static int
|
||||
match(const struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
const struct ip6t_length_info *info = matchinfo;
|
||||
u_int16_t pktlen = ntohs(skb->nh.ipv6h->payload_len) + sizeof(struct ipv6hdr);
|
||||
|
||||
return (pktlen >= info->min && pktlen <= info->max) ^ info->invert;
|
||||
}
|
||||
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const struct ip6t_ip6 *ip,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_length_info)))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct ip6t_match length_match = {
|
||||
.name = "length",
|
||||
.match = &match,
|
||||
.checkentry = &checkentry,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
return ip6t_register_match(&length_match);
|
||||
}
|
||||
|
||||
static void __exit fini(void)
|
||||
{
|
||||
ip6t_unregister_match(&length_match);
|
||||
}
|
||||
|
||||
module_init(init);
|
||||
module_exit(fini);
|
@@ -1,147 +0,0 @@
|
||||
/* Kernel module to control the rate
|
||||
*
|
||||
* 2 September 1999: Changed from the target RATE to the match
|
||||
* `limit', removed logging. Did I mention that
|
||||
* Alexey is a fucking genius?
|
||||
* Rusty Russell (rusty@rustcorp.com.au). */
|
||||
|
||||
/* (C) 1999 J<>r<EFBFBD>me de Vivie <devivie@info.enserb.u-bordeaux.fr>
|
||||
* (C) 1999 Herv<72> Eychenne <eychenne@info.enserb.u-bordeaux.fr>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include <linux/netfilter_ipv6/ip6_tables.h>
|
||||
#include <linux/netfilter_ipv6/ip6t_limit.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Herve Eychenne <rv@wallfire.org>");
|
||||
MODULE_DESCRIPTION("rate limiting within ip6tables");
|
||||
|
||||
/* The algorithm used is the Simple Token Bucket Filter (TBF)
|
||||
* see net/sched/sch_tbf.c in the linux source tree
|
||||
*/
|
||||
|
||||
static DEFINE_SPINLOCK(limit_lock);
|
||||
|
||||
/* Rusty: This is my (non-mathematically-inclined) understanding of
|
||||
this algorithm. The `average rate' in jiffies becomes your initial
|
||||
amount of credit `credit' and the most credit you can ever have
|
||||
`credit_cap'. The `peak rate' becomes the cost of passing the
|
||||
test, `cost'.
|
||||
|
||||
`prev' tracks the last packet hit: you gain one credit per jiffy.
|
||||
If you get credit balance more than this, the extra credit is
|
||||
discarded. Every time the match passes, you lose `cost' credits;
|
||||
if you don't have that many, the test fails.
|
||||
|
||||
See Alexey's formal explanation in net/sched/sch_tbf.c.
|
||||
|
||||
To avoid underflow, we multiply by 128 (ie. you get 128 credits per
|
||||
jiffy). Hence a cost of 2^32-1, means one pass per 32768 seconds
|
||||
at 1024HZ (or one every 9 hours). A cost of 1 means 12800 passes
|
||||
per second at 100HZ. */
|
||||
|
||||
#define CREDITS_PER_JIFFY 128
|
||||
|
||||
static int
|
||||
ip6t_limit_match(const struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
struct ip6t_rateinfo *r = ((struct ip6t_rateinfo *)matchinfo)->master;
|
||||
unsigned long now = jiffies;
|
||||
|
||||
spin_lock_bh(&limit_lock);
|
||||
r->credit += (now - xchg(&r->prev, now)) * CREDITS_PER_JIFFY;
|
||||
if (r->credit > r->credit_cap)
|
||||
r->credit = r->credit_cap;
|
||||
|
||||
if (r->credit >= r->cost) {
|
||||
/* We're not limited. */
|
||||
r->credit -= r->cost;
|
||||
spin_unlock_bh(&limit_lock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
spin_unlock_bh(&limit_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Precision saver. */
|
||||
static u_int32_t
|
||||
user2credits(u_int32_t user)
|
||||
{
|
||||
/* If multiplying would overflow... */
|
||||
if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY))
|
||||
/* Divide first. */
|
||||
return (user / IP6T_LIMIT_SCALE) * HZ * CREDITS_PER_JIFFY;
|
||||
|
||||
return (user * HZ * CREDITS_PER_JIFFY) / IP6T_LIMIT_SCALE;
|
||||
}
|
||||
|
||||
static int
|
||||
ip6t_limit_checkentry(const char *tablename,
|
||||
const struct ip6t_ip6 *ip,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
struct ip6t_rateinfo *r = matchinfo;
|
||||
|
||||
if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_rateinfo)))
|
||||
return 0;
|
||||
|
||||
/* Check for overflow. */
|
||||
if (r->burst == 0
|
||||
|| user2credits(r->avg * r->burst) < user2credits(r->avg)) {
|
||||
printk("Call rusty: overflow in ip6t_limit: %u/%u\n",
|
||||
r->avg, r->burst);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* User avg in seconds * IP6T_LIMIT_SCALE: convert to jiffies *
|
||||
128. */
|
||||
r->prev = jiffies;
|
||||
r->credit = user2credits(r->avg * r->burst); /* Credits full. */
|
||||
r->credit_cap = user2credits(r->avg * r->burst); /* Credits full. */
|
||||
r->cost = user2credits(r->avg);
|
||||
|
||||
/* For SMP, we only want to use one set of counters. */
|
||||
r->master = r;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct ip6t_match ip6t_limit_reg = {
|
||||
.name = "limit",
|
||||
.match = ip6t_limit_match,
|
||||
.checkentry = ip6t_limit_checkentry,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
if (ip6t_register_match(&ip6t_limit_reg))
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit fini(void)
|
||||
{
|
||||
ip6t_unregister_match(&ip6t_limit_reg);
|
||||
}
|
||||
|
||||
module_init(init);
|
||||
module_exit(fini);
|
@@ -1,81 +0,0 @@
|
||||
/* Kernel module to match MAC address parameters. */
|
||||
|
||||
/* (C) 1999-2001 Paul `Rusty' Russell
|
||||
* (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/etherdevice.h>
|
||||
|
||||
#include <linux/netfilter_ipv6/ip6t_mac.h>
|
||||
#include <linux/netfilter_ipv6/ip6_tables.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("MAC address matching module for IPv6");
|
||||
MODULE_AUTHOR("Netfilter Core Teaam <coreteam@netfilter.org>");
|
||||
|
||||
static int
|
||||
match(const struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
const struct ip6t_mac_info *info = matchinfo;
|
||||
|
||||
/* Is mac pointer valid? */
|
||||
return (skb->mac.raw >= skb->head
|
||||
&& (skb->mac.raw + ETH_HLEN) <= skb->data
|
||||
/* If so, compare... */
|
||||
&& ((!compare_ether_addr(eth_hdr(skb)->h_source, info->srcaddr))
|
||||
^ info->invert));
|
||||
}
|
||||
|
||||
static int
|
||||
ip6t_mac_checkentry(const char *tablename,
|
||||
const struct ip6t_ip6 *ip,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
if (hook_mask
|
||||
& ~((1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_IN)
|
||||
| (1 << NF_IP6_FORWARD))) {
|
||||
printk("ip6t_mac: only valid for PRE_ROUTING, LOCAL_IN or"
|
||||
" FORWARD\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_mac_info)))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct ip6t_match mac_match = {
|
||||
.name = "mac",
|
||||
.match = &match,
|
||||
.checkentry = &ip6t_mac_checkentry,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
return ip6t_register_match(&mac_match);
|
||||
}
|
||||
|
||||
static void __exit fini(void)
|
||||
{
|
||||
ip6t_unregister_match(&mac_match);
|
||||
}
|
||||
|
||||
module_init(init);
|
||||
module_exit(fini);
|
@@ -1,66 +0,0 @@
|
||||
/* Kernel module to match NFMARK values. */
|
||||
|
||||
/* (C) 1999-2001 Marc Boucher <marc@mbsi.ca>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
|
||||
#include <linux/netfilter_ipv6/ip6t_mark.h>
|
||||
#include <linux/netfilter_ipv6/ip6_tables.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
|
||||
MODULE_DESCRIPTION("ip6tables mark match");
|
||||
|
||||
static int
|
||||
match(const struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
const struct ip6t_mark_info *info = matchinfo;
|
||||
|
||||
return ((skb->nfmark & info->mask) == info->mark) ^ info->invert;
|
||||
}
|
||||
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const struct ip6t_ip6 *ip,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_mark_info)))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct ip6t_match mark_match = {
|
||||
.name = "mark",
|
||||
.match = &match,
|
||||
.checkentry = &checkentry,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
return ip6t_register_match(&mark_match);
|
||||
}
|
||||
|
||||
static void __exit fini(void)
|
||||
{
|
||||
ip6t_unregister_match(&mark_match);
|
||||
}
|
||||
|
||||
module_init(init);
|
||||
module_exit(fini);
|
@@ -84,11 +84,12 @@ match(const struct sk_buff *skb,
|
||||
/* Called when user tries to insert an entry of this type. */
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const struct ip6t_ip6 *ip,
|
||||
const void *info,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
const struct ip6t_ip6 *ip = info;
|
||||
const struct ip6t_multiport *multiinfo = matchinfo;
|
||||
|
||||
if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_multiport)))
|
||||
|
@@ -53,7 +53,7 @@ match(const struct sk_buff *skb,
|
||||
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const struct ip6t_ip6 *ip,
|
||||
const void *ip,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
|
@@ -183,7 +183,7 @@ match(const struct sk_buff *skb,
|
||||
/* Called when user tries to insert an entry of this type. */
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const struct ip6t_ip6 *ip,
|
||||
const void *entry,
|
||||
void *matchinfo,
|
||||
unsigned int matchinfosize,
|
||||
unsigned int hook_mask)
|
||||
|
@@ -97,6 +97,7 @@ static struct ip6t_table packet_filter = {
|
||||
.valid_hooks = FILTER_VALID_HOOKS,
|
||||
.lock = RW_LOCK_UNLOCKED,
|
||||
.me = THIS_MODULE,
|
||||
.af = AF_INET6,
|
||||
};
|
||||
|
||||
/* The work comes in here from netfilter.c. */
|
||||
|
@@ -127,6 +127,7 @@ static struct ip6t_table packet_mangler = {
|
||||
.valid_hooks = MANGLE_VALID_HOOKS,
|
||||
.lock = RW_LOCK_UNLOCKED,
|
||||
.me = THIS_MODULE,
|
||||
.af = AF_INET6,
|
||||
};
|
||||
|
||||
/* The work comes in here from netfilter.c. */
|
||||
|
@@ -106,11 +106,12 @@ static struct
|
||||
}
|
||||
};
|
||||
|
||||
static struct ip6t_table packet_raw = {
|
||||
static struct xt_table packet_raw = {
|
||||
.name = "raw",
|
||||
.valid_hooks = RAW_VALID_HOOKS,
|
||||
.lock = RW_LOCK_UNLOCKED,
|
||||
.me = THIS_MODULE
|
||||
.me = THIS_MODULE,
|
||||
.af = AF_INET6,
|
||||
};
|
||||
|
||||
/* The work comes in here from netfilter.c. */
|
||||
|
@@ -584,7 +584,7 @@ MODULE_AUTHOR("Yasuyuki KOZAKAI @USAGI <yasuyuki.kozakai@toshiba.co.jp>");
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
need_nf_conntrack();
|
||||
need_conntrack();
|
||||
return init_or_cleanup(1);
|
||||
}
|
||||
|
||||
@@ -595,9 +595,3 @@ static void __exit fini(void)
|
||||
|
||||
module_init(init);
|
||||
module_exit(fini);
|
||||
|
||||
void need_ip6_conntrack(void)
|
||||
{
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(need_ip6_conntrack);
|
||||
|
@@ -70,8 +70,8 @@ struct nf_ct_frag6_skb_cb
|
||||
|
||||
struct nf_ct_frag6_queue
|
||||
{
|
||||
struct nf_ct_frag6_queue *next;
|
||||
struct list_head lru_list; /* lru list member */
|
||||
struct hlist_node list;
|
||||
struct list_head lru_list; /* lru list member */
|
||||
|
||||
__u32 id; /* fragment id */
|
||||
struct in6_addr saddr;
|
||||
@@ -90,14 +90,13 @@ struct nf_ct_frag6_queue
|
||||
#define FIRST_IN 2
|
||||
#define LAST_IN 1
|
||||
__u16 nhoffset;
|
||||
struct nf_ct_frag6_queue **pprev;
|
||||
};
|
||||
|
||||
/* Hash table. */
|
||||
|
||||
#define FRAG6Q_HASHSZ 64
|
||||
|
||||
static struct nf_ct_frag6_queue *nf_ct_frag6_hash[FRAG6Q_HASHSZ];
|
||||
static struct hlist_head nf_ct_frag6_hash[FRAG6Q_HASHSZ];
|
||||
static DEFINE_RWLOCK(nf_ct_frag6_lock);
|
||||
static u32 nf_ct_frag6_hash_rnd;
|
||||
static LIST_HEAD(nf_ct_frag6_lru_list);
|
||||
@@ -105,9 +104,7 @@ int nf_ct_frag6_nqueues = 0;
|
||||
|
||||
static __inline__ void __fq_unlink(struct nf_ct_frag6_queue *fq)
|
||||
{
|
||||
if (fq->next)
|
||||
fq->next->pprev = fq->pprev;
|
||||
*fq->pprev = fq->next;
|
||||
hlist_del(&fq->list);
|
||||
list_del(&fq->lru_list);
|
||||
nf_ct_frag6_nqueues--;
|
||||
}
|
||||
@@ -158,28 +155,18 @@ static void nf_ct_frag6_secret_rebuild(unsigned long dummy)
|
||||
get_random_bytes(&nf_ct_frag6_hash_rnd, sizeof(u32));
|
||||
for (i = 0; i < FRAG6Q_HASHSZ; i++) {
|
||||
struct nf_ct_frag6_queue *q;
|
||||
struct hlist_node *p, *n;
|
||||
|
||||
q = nf_ct_frag6_hash[i];
|
||||
while (q) {
|
||||
struct nf_ct_frag6_queue *next = q->next;
|
||||
hlist_for_each_entry_safe(q, p, n, &nf_ct_frag6_hash[i], list) {
|
||||
unsigned int hval = ip6qhashfn(q->id,
|
||||
&q->saddr,
|
||||
&q->daddr);
|
||||
|
||||
if (hval != i) {
|
||||
/* Unlink. */
|
||||
if (q->next)
|
||||
q->next->pprev = q->pprev;
|
||||
*q->pprev = q->next;
|
||||
|
||||
hlist_del(&q->list);
|
||||
/* Relink to new hash chain. */
|
||||
if ((q->next = nf_ct_frag6_hash[hval]) != NULL)
|
||||
q->next->pprev = &q->next;
|
||||
nf_ct_frag6_hash[hval] = q;
|
||||
q->pprev = &nf_ct_frag6_hash[hval];
|
||||
hlist_add_head(&q->list,
|
||||
&nf_ct_frag6_hash[hval]);
|
||||
}
|
||||
|
||||
q = next;
|
||||
}
|
||||
}
|
||||
write_unlock(&nf_ct_frag6_lock);
|
||||
@@ -314,15 +301,17 @@ out:
|
||||
|
||||
/* Creation primitives. */
|
||||
|
||||
|
||||
static struct nf_ct_frag6_queue *nf_ct_frag6_intern(unsigned int hash,
|
||||
struct nf_ct_frag6_queue *fq_in)
|
||||
{
|
||||
struct nf_ct_frag6_queue *fq;
|
||||
#ifdef CONFIG_SMP
|
||||
struct hlist_node *n;
|
||||
#endif
|
||||
|
||||
write_lock(&nf_ct_frag6_lock);
|
||||
#ifdef CONFIG_SMP
|
||||
for (fq = nf_ct_frag6_hash[hash]; fq; fq = fq->next) {
|
||||
hlist_for_each_entry(fq, n, &nf_ct_frag6_hash[hash], list) {
|
||||
if (fq->id == fq_in->id &&
|
||||
!ipv6_addr_cmp(&fq_in->saddr, &fq->saddr) &&
|
||||
!ipv6_addr_cmp(&fq_in->daddr, &fq->daddr)) {
|
||||
@@ -340,10 +329,7 @@ static struct nf_ct_frag6_queue *nf_ct_frag6_intern(unsigned int hash,
|
||||
atomic_inc(&fq->refcnt);
|
||||
|
||||
atomic_inc(&fq->refcnt);
|
||||
if ((fq->next = nf_ct_frag6_hash[hash]) != NULL)
|
||||
fq->next->pprev = &fq->next;
|
||||
nf_ct_frag6_hash[hash] = fq;
|
||||
fq->pprev = &nf_ct_frag6_hash[hash];
|
||||
hlist_add_head(&fq->list, &nf_ct_frag6_hash[hash]);
|
||||
INIT_LIST_HEAD(&fq->lru_list);
|
||||
list_add_tail(&fq->lru_list, &nf_ct_frag6_lru_list);
|
||||
nf_ct_frag6_nqueues++;
|
||||
@@ -384,10 +370,11 @@ static __inline__ struct nf_ct_frag6_queue *
|
||||
fq_find(u32 id, struct in6_addr *src, struct in6_addr *dst)
|
||||
{
|
||||
struct nf_ct_frag6_queue *fq;
|
||||
struct hlist_node *n;
|
||||
unsigned int hash = ip6qhashfn(id, src, dst);
|
||||
|
||||
read_lock(&nf_ct_frag6_lock);
|
||||
for (fq = nf_ct_frag6_hash[hash]; fq; fq = fq->next) {
|
||||
hlist_for_each_entry(fq, n, &nf_ct_frag6_hash[hash], list) {
|
||||
if (fq->id == id &&
|
||||
!ipv6_addr_cmp(src, &fq->saddr) &&
|
||||
!ipv6_addr_cmp(dst, &fq->daddr)) {
|
||||
|
@@ -103,3 +103,261 @@ config NF_CT_NETLINK
|
||||
This option enables support for a netlink-based userspace interface
|
||||
|
||||
endmenu
|
||||
|
||||
config NETFILTER_XTABLES
|
||||
tristate "Netfilter Xtables support (required for ip_tables)"
|
||||
help
|
||||
This is required if you intend to use any of ip_tables,
|
||||
ip6_tables or arp_tables.
|
||||
|
||||
# alphabetically ordered list of targets
|
||||
|
||||
config NETFILTER_XT_TARGET_CLASSIFY
|
||||
tristate '"CLASSIFY" target support'
|
||||
depends on NETFILTER_XTABLES
|
||||
help
|
||||
This option adds a `CLASSIFY' target, which enables the user to set
|
||||
the priority of a packet. Some qdiscs can use this value for
|
||||
classification, among these are:
|
||||
|
||||
atm, cbq, dsmark, pfifo_fast, htb, prio
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config NETFILTER_XT_TARGET_CONNMARK
|
||||
tristate '"CONNMARK" target support'
|
||||
depends on NETFILTER_XTABLES
|
||||
depends on IP_NF_MANGLE || IP6_NF_MANGLE
|
||||
depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || (NF_CONNTRACK_MARK && NF_CONNTRACK_IPV4)
|
||||
help
|
||||
This option adds a `CONNMARK' target, which allows one to manipulate
|
||||
the connection mark value. Similar to the MARK target, but
|
||||
affects the connection mark value rather than the packet mark value.
|
||||
|
||||
If you want to compile it as a module, say M here and read
|
||||
<file:Documentation/modules.txt>. The module will be called
|
||||
ipt_CONNMARK.o. If unsure, say `N'.
|
||||
|
||||
config NETFILTER_XT_TARGET_MARK
|
||||
tristate '"MARK" target support'
|
||||
depends on NETFILTER_XTABLES
|
||||
help
|
||||
This option adds a `MARK' target, which allows you to create rules
|
||||
in the `mangle' table which alter the netfilter mark (nfmark) field
|
||||
associated with the packet prior to routing. This can change
|
||||
the routing method (see `Use netfilter MARK value as routing
|
||||
key') and can also be used by other subsystems to change their
|
||||
behavior.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config NETFILTER_XT_TARGET_NFQUEUE
|
||||
tristate '"NFQUEUE" target Support'
|
||||
depends on NETFILTER_XTABLES
|
||||
help
|
||||
This Target replaced the old obsolete QUEUE target.
|
||||
|
||||
As opposed to QUEUE, it supports 65535 different queues,
|
||||
not just one.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config NETFILTER_XT_TARGET_NOTRACK
|
||||
tristate '"NOTRACK" target support'
|
||||
depends on NETFILTER_XTABLES
|
||||
depends on IP_NF_RAW || IP6_NF_RAW
|
||||
depends on IP_NF_CONNTRACK || NF_CONNTRACK
|
||||
help
|
||||
The NOTRACK target allows a select rule to specify
|
||||
which packets *not* to enter the conntrack/NAT
|
||||
subsystem with all the consequences (no ICMP error tracking,
|
||||
no protocol helpers for the selected packets).
|
||||
|
||||
If you want to compile it as a module, say M here and read
|
||||
<file:Documentation/modules.txt>. If unsure, say `N'.
|
||||
|
||||
config NETFILTER_XT_MATCH_COMMENT
|
||||
tristate '"comment" match support'
|
||||
depends on NETFILTER_XTABLES
|
||||
help
|
||||
This option adds a `comment' dummy-match, which allows you to put
|
||||
comments in your iptables ruleset.
|
||||
|
||||
If you want to compile it as a module, say M here and read
|
||||
<file:Documentation/modules.txt>. If unsure, say `N'.
|
||||
|
||||
config NETFILTER_XT_MATCH_CONNBYTES
|
||||
tristate '"connbytes" per-connection counter match support'
|
||||
depends on NETFILTER_XTABLES
|
||||
depends on (IP_NF_CONNTRACK && IP_NF_CT_ACCT) || NF_CT_ACCT
|
||||
help
|
||||
This option adds a `connbytes' match, which allows you to match the
|
||||
number of bytes and/or packets for each direction within a connection.
|
||||
|
||||
If you want to compile it as a module, say M here and read
|
||||
<file:Documentation/modules.txt>. If unsure, say `N'.
|
||||
|
||||
config NETFILTER_XT_MATCH_CONNMARK
|
||||
tristate '"connmark" connection mark match support'
|
||||
depends on NETFILTER_XTABLES
|
||||
depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || NF_CONNTRACK_MARK
|
||||
help
|
||||
This option adds a `connmark' match, which allows you to match the
|
||||
connection mark value previously set for the session by `CONNMARK'.
|
||||
|
||||
If you want to compile it as a module, say M here and read
|
||||
<file:Documentation/modules.txt>. The module will be called
|
||||
ipt_connmark.o. If unsure, say `N'.
|
||||
|
||||
config NETFILTER_XT_MATCH_CONNTRACK
|
||||
tristate '"conntrack" connection tracking match support'
|
||||
depends on NETFILTER_XTABLES
|
||||
depends on IP_NF_CONNTRACK || NF_CONNTRACK
|
||||
help
|
||||
This is a general conntrack match module, a superset of the state match.
|
||||
|
||||
It allows matching on additional conntrack information, which is
|
||||
useful in complex configurations, such as NAT gateways with multiple
|
||||
internet links or tunnels.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config NETFILTER_XT_MATCH_DCCP
|
||||
tristate '"DCCP" protocol match support'
|
||||
depends on NETFILTER_XTABLES
|
||||
help
|
||||
With this option enabled, you will be able to use the iptables
|
||||
`dccp' match in order to match on DCCP source/destination ports
|
||||
and DCCP flags.
|
||||
|
||||
If you want to compile it as a module, say M here and read
|
||||
<file:Documentation/modules.txt>. If unsure, say `N'.
|
||||
|
||||
config NETFILTER_XT_MATCH_HELPER
|
||||
tristate '"helper" match support'
|
||||
depends on NETFILTER_XTABLES
|
||||
depends on IP_NF_CONNTRACK || NF_CONNTRACK
|
||||
help
|
||||
Helper matching allows you to match packets in dynamic connections
|
||||
tracked by a conntrack-helper, ie. ip_conntrack_ftp
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say Y.
|
||||
|
||||
config NETFILTER_XT_MATCH_LENGTH
|
||||
tristate '"length" match support'
|
||||
depends on NETFILTER_XTABLES
|
||||
help
|
||||
This option allows you to match the length of a packet against a
|
||||
specific value or range of values.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config NETFILTER_XT_MATCH_LIMIT
|
||||
tristate '"limit" match support'
|
||||
depends on NETFILTER_XTABLES
|
||||
help
|
||||
limit matching allows you to control the rate at which a rule can be
|
||||
matched: mainly useful in combination with the LOG target ("LOG
|
||||
target support", below) and to avoid some Denial of Service attacks.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config NETFILTER_XT_MATCH_MAC
|
||||
tristate '"mac" address match support'
|
||||
depends on NETFILTER_XTABLES
|
||||
help
|
||||
MAC matching allows you to match packets based on the source
|
||||
Ethernet address of the packet.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config NETFILTER_XT_MATCH_MARK
|
||||
tristate '"mark" match support'
|
||||
depends on NETFILTER_XTABLES
|
||||
help
|
||||
Netfilter mark matching allows you to match packets based on the
|
||||
`nfmark' value in the packet. This can be set by the MARK target
|
||||
(see below).
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config NETFILTER_XT_MATCH_PHYSDEV
|
||||
tristate '"physdev" match support'
|
||||
depends on NETFILTER_XTABLES && BRIDGE_NETFILTER
|
||||
help
|
||||
Physdev packet matching matches against the physical bridge ports
|
||||
the IP packet arrived on or will leave by.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config NETFILTER_XT_MATCH_PKTTYPE
|
||||
tristate '"pkttype" packet type match support'
|
||||
depends on NETFILTER_XTABLES
|
||||
help
|
||||
Packet type matching allows you to match a packet by
|
||||
its "class", eg. BROADCAST, MULTICAST, ...
|
||||
|
||||
Typical usage:
|
||||
iptables -A INPUT -m pkttype --pkt-type broadcast -j LOG
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config NETFILTER_XT_MATCH_REALM
|
||||
tristate '"realm" match support'
|
||||
depends on NETFILTER_XTABLES
|
||||
select NET_CLS_ROUTE
|
||||
help
|
||||
This option adds a `realm' match, which allows you to use the realm
|
||||
key from the routing subsystem inside iptables.
|
||||
|
||||
This match pretty much resembles the CONFIG_NET_CLS_ROUTE4 option
|
||||
in tc world.
|
||||
|
||||
If you want to compile it as a module, say M here and read
|
||||
<file:Documentation/modules.txt>. If unsure, say `N'.
|
||||
|
||||
config NETFILTER_XT_MATCH_SCTP
|
||||
tristate '"sctp" protocol match support'
|
||||
depends on NETFILTER_XTABLES
|
||||
help
|
||||
With this option enabled, you will be able to use the
|
||||
`sctp' match in order to match on SCTP source/destination ports
|
||||
and SCTP chunk types.
|
||||
|
||||
If you want to compile it as a module, say M here and read
|
||||
<file:Documentation/modules.txt>. If unsure, say `N'.
|
||||
|
||||
config NETFILTER_XT_MATCH_STATE
|
||||
tristate '"state" match support'
|
||||
depends on NETFILTER_XTABLES
|
||||
depends on IP_NF_CONNTRACK || NF_CONNTRACK
|
||||
help
|
||||
Connection state matching allows you to match packets based on their
|
||||
relationship to a tracked connection (ie. previous packets). This
|
||||
is a powerful tool for packet classification.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config NETFILTER_XT_MATCH_STRING
|
||||
tristate '"string" match support'
|
||||
depends on NETFILTER_XTABLES
|
||||
select TEXTSEARCH
|
||||
select TEXTSEARCH_KMP
|
||||
select TEXTSEARCH_BM
|
||||
select TEXTSEARCH_FSM
|
||||
help
|
||||
This option adds a `string' match, which allows you to look for
|
||||
pattern matchings in packets.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config NETFILTER_XT_MATCH_TCPMSS
|
||||
tristate '"tcpmss" match support'
|
||||
depends on NETFILTER_XTABLES
|
||||
help
|
||||
This option adds a `tcpmss' match, which allows you to examine the
|
||||
MSS value of TCP SYN packets, which control the maximum packet size
|
||||
for that connection.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
|
@@ -1,4 +1,5 @@
|
||||
netfilter-objs := core.o nf_log.o nf_queue.o nf_sockopt.o
|
||||
nf_conntrack-objs := nf_conntrack_core.o nf_conntrack_standalone.o nf_conntrack_l3proto_generic.o nf_conntrack_proto_generic.o nf_conntrack_proto_tcp.o nf_conntrack_proto_udp.o
|
||||
|
||||
obj-$(CONFIG_NETFILTER) = netfilter.o
|
||||
|
||||
@@ -6,13 +7,43 @@ obj-$(CONFIG_NETFILTER_NETLINK) += nfnetlink.o
|
||||
obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += nfnetlink_queue.o
|
||||
obj-$(CONFIG_NETFILTER_NETLINK_LOG) += nfnetlink_log.o
|
||||
|
||||
nf_conntrack-objs := nf_conntrack_core.o nf_conntrack_standalone.o nf_conntrack_l3proto_generic.o nf_conntrack_proto_generic.o nf_conntrack_proto_tcp.o nf_conntrack_proto_udp.o
|
||||
|
||||
# connection tracking
|
||||
obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o
|
||||
obj-$(CONFIG_NF_CONNTRACK_FTP) += nf_conntrack_ftp.o
|
||||
|
||||
# SCTP protocol connection tracking
|
||||
obj-$(CONFIG_NF_CT_PROTO_SCTP) += nf_conntrack_proto_sctp.o
|
||||
|
||||
# netlink interface for nf_conntrack
|
||||
obj-$(CONFIG_NF_CT_NETLINK) += nf_conntrack_netlink.o
|
||||
|
||||
# connection tracking helpers
|
||||
obj-$(CONFIG_NF_CONNTRACK_FTP) += nf_conntrack_ftp.o
|
||||
|
||||
# generic X tables
|
||||
obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o
|
||||
|
||||
# targets
|
||||
obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIFY) += xt_CLASSIFY.o
|
||||
obj-$(CONFIG_NETFILTER_XT_TARGET_CONNMARK) += xt_CONNMARK.o
|
||||
obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o
|
||||
obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o
|
||||
obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o
|
||||
|
||||
# matches
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_COMMENT) += xt_comment.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_CONNBYTES) += xt_connbytes.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_CONNMARK) += xt_connmark.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_CONNTRACK) += xt_conntrack.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_DCCP) += xt_dccp.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_HELPER) += xt_helper.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_LENGTH) += xt_length.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_LIMIT) += xt_limit.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_MAC) += xt_mac.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_MARK) += xt_mark.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_PKTTYPE) += xt_pkttype.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o
|
||||
|
@@ -821,7 +821,7 @@ module_exit(fini);
|
||||
|
||||
/* Some modules need us, but don't depend directly on any symbol.
|
||||
They should call this. */
|
||||
void need_nf_conntrack(void)
|
||||
void need_conntrack(void)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -841,7 +841,7 @@ EXPORT_SYMBOL(nf_conntrack_protocol_unregister);
|
||||
EXPORT_SYMBOL(nf_ct_invert_tuplepr);
|
||||
EXPORT_SYMBOL(nf_conntrack_alter_reply);
|
||||
EXPORT_SYMBOL(nf_conntrack_destroyed);
|
||||
EXPORT_SYMBOL(need_nf_conntrack);
|
||||
EXPORT_SYMBOL(need_conntrack);
|
||||
EXPORT_SYMBOL(nf_conntrack_helper_register);
|
||||
EXPORT_SYMBOL(nf_conntrack_helper_unregister);
|
||||
EXPORT_SYMBOL(nf_ct_iterate_cleanup);
|
||||
|
624
net/netfilter/x_tables.c
Normal file
624
net/netfilter/x_tables.c
Normal file
@@ -0,0 +1,624 @@
|
||||
/*
|
||||
* x_tables core - Backend for {ip,ip6,arp}_tables
|
||||
*
|
||||
* Copyright (C) 2006-2006 Harald Welte <laforge@netfilter.org>
|
||||
*
|
||||
* Based on existing ip_tables code which is
|
||||
* Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
|
||||
* Copyright (C) 2000-2005 Netfilter Core Team <coreteam@netfilter.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/socket.h>
|
||||
#include <linux/net.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include <linux/netfilter_arp.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
|
||||
MODULE_DESCRIPTION("[ip,ip6,arp]_tables backend module");
|
||||
|
||||
#define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1))
|
||||
|
||||
struct xt_af {
|
||||
struct semaphore mutex;
|
||||
struct list_head match;
|
||||
struct list_head target;
|
||||
struct list_head tables;
|
||||
};
|
||||
|
||||
static struct xt_af *xt;
|
||||
|
||||
#ifdef DEBUG_IP_FIREWALL_USER
|
||||
#define duprintf(format, args...) printk(format , ## args)
|
||||
#else
|
||||
#define duprintf(format, args...)
|
||||
#endif
|
||||
|
||||
enum {
|
||||
TABLE,
|
||||
TARGET,
|
||||
MATCH,
|
||||
};
|
||||
|
||||
/* Registration hooks for targets. */
|
||||
int
|
||||
xt_register_target(int af, struct xt_target *target)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = down_interruptible(&xt[af].mutex);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
list_add(&target->list, &xt[af].target);
|
||||
up(&xt[af].mutex);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(xt_register_target);
|
||||
|
||||
void
|
||||
xt_unregister_target(int af, struct xt_target *target)
|
||||
{
|
||||
down(&xt[af].mutex);
|
||||
LIST_DELETE(&xt[af].target, target);
|
||||
up(&xt[af].mutex);
|
||||
}
|
||||
EXPORT_SYMBOL(xt_unregister_target);
|
||||
|
||||
int
|
||||
xt_register_match(int af, struct xt_match *match)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = down_interruptible(&xt[af].mutex);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
list_add(&match->list, &xt[af].match);
|
||||
up(&xt[af].mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(xt_register_match);
|
||||
|
||||
void
|
||||
xt_unregister_match(int af, struct xt_match *match)
|
||||
{
|
||||
down(&xt[af].mutex);
|
||||
LIST_DELETE(&xt[af].match, match);
|
||||
up(&xt[af].mutex);
|
||||
}
|
||||
EXPORT_SYMBOL(xt_unregister_match);
|
||||
|
||||
|
||||
/*
|
||||
* These are weird, but module loading must not be done with mutex
|
||||
* held (since they will register), and we have to have a single
|
||||
* function to use try_then_request_module().
|
||||
*/
|
||||
|
||||
/* Find match, grabs ref. Returns ERR_PTR() on error. */
|
||||
struct xt_match *xt_find_match(int af, const char *name, u8 revision)
|
||||
{
|
||||
struct xt_match *m;
|
||||
int err = 0;
|
||||
|
||||
if (down_interruptible(&xt[af].mutex) != 0)
|
||||
return ERR_PTR(-EINTR);
|
||||
|
||||
list_for_each_entry(m, &xt[af].match, list) {
|
||||
if (strcmp(m->name, name) == 0) {
|
||||
if (m->revision == revision) {
|
||||
if (try_module_get(m->me)) {
|
||||
up(&xt[af].mutex);
|
||||
return m;
|
||||
}
|
||||
} else
|
||||
err = -EPROTOTYPE; /* Found something. */
|
||||
}
|
||||
}
|
||||
up(&xt[af].mutex);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
EXPORT_SYMBOL(xt_find_match);
|
||||
|
||||
/* Find target, grabs ref. Returns ERR_PTR() on error. */
|
||||
struct xt_target *xt_find_target(int af, const char *name, u8 revision)
|
||||
{
|
||||
struct xt_target *t;
|
||||
int err = 0;
|
||||
|
||||
if (down_interruptible(&xt[af].mutex) != 0)
|
||||
return ERR_PTR(-EINTR);
|
||||
|
||||
list_for_each_entry(t, &xt[af].target, list) {
|
||||
if (strcmp(t->name, name) == 0) {
|
||||
if (t->revision == revision) {
|
||||
if (try_module_get(t->me)) {
|
||||
up(&xt[af].mutex);
|
||||
return t;
|
||||
}
|
||||
} else
|
||||
err = -EPROTOTYPE; /* Found something. */
|
||||
}
|
||||
}
|
||||
up(&xt[af].mutex);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
EXPORT_SYMBOL(xt_find_target);
|
||||
|
||||
static const char *xt_prefix[NPROTO] = {
|
||||
[AF_INET] = "ipt_%s",
|
||||
[AF_INET6] = "ip6t_%s",
|
||||
[NF_ARP] = "arpt_%s",
|
||||
};
|
||||
|
||||
struct xt_target *xt_request_find_target(int af, const char *name, u8 revision)
|
||||
{
|
||||
struct xt_target *target;
|
||||
|
||||
target = try_then_request_module(xt_find_target(af, name, revision),
|
||||
xt_prefix[af], name);
|
||||
if (IS_ERR(target) || !target)
|
||||
return NULL;
|
||||
return target;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xt_request_find_target);
|
||||
|
||||
static int match_revfn(int af, const char *name, u8 revision, int *bestp)
|
||||
{
|
||||
struct xt_match *m;
|
||||
int have_rev = 0;
|
||||
|
||||
list_for_each_entry(m, &xt[af].match, list) {
|
||||
if (strcmp(m->name, name) == 0) {
|
||||
if (m->revision > *bestp)
|
||||
*bestp = m->revision;
|
||||
if (m->revision == revision)
|
||||
have_rev = 1;
|
||||
}
|
||||
}
|
||||
return have_rev;
|
||||
}
|
||||
|
||||
static int target_revfn(int af, const char *name, u8 revision, int *bestp)
|
||||
{
|
||||
struct xt_target *t;
|
||||
int have_rev = 0;
|
||||
|
||||
list_for_each_entry(t, &xt[af].target, list) {
|
||||
if (strcmp(t->name, name) == 0) {
|
||||
if (t->revision > *bestp)
|
||||
*bestp = t->revision;
|
||||
if (t->revision == revision)
|
||||
have_rev = 1;
|
||||
}
|
||||
}
|
||||
return have_rev;
|
||||
}
|
||||
|
||||
/* Returns true or false (if no such extension at all) */
|
||||
int xt_find_revision(int af, const char *name, u8 revision, int target,
|
||||
int *err)
|
||||
{
|
||||
int have_rev, best = -1;
|
||||
|
||||
if (down_interruptible(&xt[af].mutex) != 0) {
|
||||
*err = -EINTR;
|
||||
return 1;
|
||||
}
|
||||
if (target == 1)
|
||||
have_rev = target_revfn(af, name, revision, &best);
|
||||
else
|
||||
have_rev = match_revfn(af, name, revision, &best);
|
||||
up(&xt[af].mutex);
|
||||
|
||||
/* Nothing at all? Return 0 to try loading module. */
|
||||
if (best == -1) {
|
||||
*err = -ENOENT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*err = best;
|
||||
if (!have_rev)
|
||||
*err = -EPROTONOSUPPORT;
|
||||
return 1;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xt_find_revision);
|
||||
|
||||
struct xt_table_info *xt_alloc_table_info(unsigned int size)
|
||||
{
|
||||
struct xt_table_info *newinfo;
|
||||
int cpu;
|
||||
|
||||
/* Pedantry: prevent them from hitting BUG() in vmalloc.c --RR */
|
||||
if ((SMP_ALIGN(size) >> PAGE_SHIFT) + 2 > num_physpages)
|
||||
return NULL;
|
||||
|
||||
newinfo = kzalloc(sizeof(struct xt_table_info), GFP_KERNEL);
|
||||
if (!newinfo)
|
||||
return NULL;
|
||||
|
||||
newinfo->size = size;
|
||||
|
||||
for_each_cpu(cpu) {
|
||||
if (size <= PAGE_SIZE)
|
||||
newinfo->entries[cpu] = kmalloc_node(size,
|
||||
GFP_KERNEL,
|
||||
cpu_to_node(cpu));
|
||||
else
|
||||
newinfo->entries[cpu] = vmalloc_node(size,
|
||||
cpu_to_node(cpu));
|
||||
|
||||
if (newinfo->entries[cpu] == NULL) {
|
||||
xt_free_table_info(newinfo);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return newinfo;
|
||||
}
|
||||
EXPORT_SYMBOL(xt_alloc_table_info);
|
||||
|
||||
void xt_free_table_info(struct xt_table_info *info)
|
||||
{
|
||||
int cpu;
|
||||
|
||||
for_each_cpu(cpu) {
|
||||
if (info->size <= PAGE_SIZE)
|
||||
kfree(info->entries[cpu]);
|
||||
else
|
||||
vfree(info->entries[cpu]);
|
||||
}
|
||||
kfree(info);
|
||||
}
|
||||
EXPORT_SYMBOL(xt_free_table_info);
|
||||
|
||||
/* Find table by name, grabs mutex & ref. Returns ERR_PTR() on error. */
|
||||
struct xt_table *xt_find_table_lock(int af, const char *name)
|
||||
{
|
||||
struct xt_table *t;
|
||||
|
||||
if (down_interruptible(&xt[af].mutex) != 0)
|
||||
return ERR_PTR(-EINTR);
|
||||
|
||||
list_for_each_entry(t, &xt[af].tables, list)
|
||||
if (strcmp(t->name, name) == 0 && try_module_get(t->me))
|
||||
return t;
|
||||
up(&xt[af].mutex);
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xt_find_table_lock);
|
||||
|
||||
void xt_table_unlock(struct xt_table *table)
|
||||
{
|
||||
up(&xt[table->af].mutex);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xt_table_unlock);
|
||||
|
||||
|
||||
struct xt_table_info *
|
||||
xt_replace_table(struct xt_table *table,
|
||||
unsigned int num_counters,
|
||||
struct xt_table_info *newinfo,
|
||||
int *error)
|
||||
{
|
||||
struct xt_table_info *oldinfo, *private;
|
||||
|
||||
/* Do the substitution. */
|
||||
write_lock_bh(&table->lock);
|
||||
private = table->private;
|
||||
/* Check inside lock: is the old number correct? */
|
||||
if (num_counters != private->number) {
|
||||
duprintf("num_counters != table->private->number (%u/%u)\n",
|
||||
num_counters, private->number);
|
||||
write_unlock_bh(&table->lock);
|
||||
*error = -EAGAIN;
|
||||
return NULL;
|
||||
}
|
||||
oldinfo = private;
|
||||
table->private = newinfo;
|
||||
newinfo->initial_entries = oldinfo->initial_entries;
|
||||
write_unlock_bh(&table->lock);
|
||||
|
||||
return oldinfo;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xt_replace_table);
|
||||
|
||||
int xt_register_table(struct xt_table *table,
|
||||
struct xt_table_info *bootstrap,
|
||||
struct xt_table_info *newinfo)
|
||||
{
|
||||
int ret;
|
||||
struct xt_table_info *private;
|
||||
|
||||
ret = down_interruptible(&xt[table->af].mutex);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
/* Don't autoload: we'd eat our tail... */
|
||||
if (list_named_find(&xt[table->af].tables, table->name)) {
|
||||
ret = -EEXIST;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
/* Simplifies replace_table code. */
|
||||
table->private = bootstrap;
|
||||
if (!xt_replace_table(table, 0, newinfo, &ret))
|
||||
goto unlock;
|
||||
|
||||
private = table->private;
|
||||
duprintf("table->private->number = %u\n", private->number);
|
||||
|
||||
/* save number of initial entries */
|
||||
private->initial_entries = private->number;
|
||||
|
||||
rwlock_init(&table->lock);
|
||||
list_prepend(&xt[table->af].tables, table);
|
||||
|
||||
ret = 0;
|
||||
unlock:
|
||||
up(&xt[table->af].mutex);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xt_register_table);
|
||||
|
||||
void *xt_unregister_table(struct xt_table *table)
|
||||
{
|
||||
struct xt_table_info *private;
|
||||
|
||||
down(&xt[table->af].mutex);
|
||||
private = table->private;
|
||||
LIST_DELETE(&xt[table->af].tables, table);
|
||||
up(&xt[table->af].mutex);
|
||||
|
||||
return private;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xt_unregister_table);
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
static char *xt_proto_prefix[NPROTO] = {
|
||||
[AF_INET] = "ip",
|
||||
[AF_INET6] = "ip6",
|
||||
[NF_ARP] = "arp",
|
||||
};
|
||||
|
||||
static struct list_head *xt_get_idx(struct list_head *list, struct seq_file *seq, loff_t pos)
|
||||
{
|
||||
struct list_head *head = list->next;
|
||||
|
||||
if (!head || list_empty(list))
|
||||
return NULL;
|
||||
|
||||
while (pos && (head = head->next)) {
|
||||
if (head == list)
|
||||
return NULL;
|
||||
pos--;
|
||||
}
|
||||
return pos ? NULL : head;
|
||||
}
|
||||
|
||||
static struct list_head *type2list(u_int16_t af, u_int16_t type)
|
||||
{
|
||||
struct list_head *list;
|
||||
|
||||
switch (type) {
|
||||
case TARGET:
|
||||
list = &xt[af].target;
|
||||
break;
|
||||
case MATCH:
|
||||
list = &xt[af].match;
|
||||
break;
|
||||
case TABLE:
|
||||
list = &xt[af].tables;
|
||||
break;
|
||||
default:
|
||||
list = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
static void *xt_tgt_seq_start(struct seq_file *seq, loff_t *pos)
|
||||
{
|
||||
struct proc_dir_entry *pde = (struct proc_dir_entry *) seq->private;
|
||||
u_int16_t af = (unsigned long)pde->data & 0xffff;
|
||||
u_int16_t type = (unsigned long)pde->data >> 16;
|
||||
struct list_head *list;
|
||||
|
||||
if (af >= NPROTO)
|
||||
return NULL;
|
||||
|
||||
list = type2list(af, type);
|
||||
if (!list)
|
||||
return NULL;
|
||||
|
||||
if (down_interruptible(&xt[af].mutex) != 0)
|
||||
return NULL;
|
||||
|
||||
return xt_get_idx(list, seq, *pos);
|
||||
}
|
||||
|
||||
static void *xt_tgt_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
||||
{
|
||||
struct proc_dir_entry *pde = seq->private;
|
||||
u_int16_t af = (unsigned long)pde->data & 0xffff;
|
||||
u_int16_t type = (unsigned long)pde->data >> 16;
|
||||
struct list_head *list;
|
||||
|
||||
if (af >= NPROTO)
|
||||
return NULL;
|
||||
|
||||
list = type2list(af, type);
|
||||
if (!list)
|
||||
return NULL;
|
||||
|
||||
(*pos)++;
|
||||
return xt_get_idx(list, seq, *pos);
|
||||
}
|
||||
|
||||
static void xt_tgt_seq_stop(struct seq_file *seq, void *v)
|
||||
{
|
||||
struct proc_dir_entry *pde = seq->private;
|
||||
u_int16_t af = (unsigned long)pde->data & 0xffff;
|
||||
|
||||
up(&xt[af].mutex);
|
||||
}
|
||||
|
||||
static int xt_name_seq_show(struct seq_file *seq, void *v)
|
||||
{
|
||||
char *name = (char *)v + sizeof(struct list_head);
|
||||
|
||||
if (strlen(name))
|
||||
return seq_printf(seq, "%s\n", name);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct seq_operations xt_tgt_seq_ops = {
|
||||
.start = xt_tgt_seq_start,
|
||||
.next = xt_tgt_seq_next,
|
||||
.stop = xt_tgt_seq_stop,
|
||||
.show = xt_name_seq_show,
|
||||
};
|
||||
|
||||
static int xt_tgt_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = seq_open(file, &xt_tgt_seq_ops);
|
||||
if (!ret) {
|
||||
struct seq_file *seq = file->private_data;
|
||||
struct proc_dir_entry *pde = PDE(inode);
|
||||
|
||||
seq->private = pde;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct file_operations xt_file_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = xt_tgt_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = seq_release,
|
||||
};
|
||||
|
||||
#define FORMAT_TABLES "_tables_names"
|
||||
#define FORMAT_MATCHES "_tables_matches"
|
||||
#define FORMAT_TARGETS "_tables_targets"
|
||||
|
||||
#endif /* CONFIG_PROC_FS */
|
||||
|
||||
int xt_proto_init(int af)
|
||||
{
|
||||
#ifdef CONFIG_PROC_FS
|
||||
char buf[XT_FUNCTION_MAXNAMELEN];
|
||||
struct proc_dir_entry *proc;
|
||||
#endif
|
||||
|
||||
if (af >= NPROTO)
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
strlcpy(buf, xt_proto_prefix[af], sizeof(buf));
|
||||
strlcat(buf, FORMAT_TABLES, sizeof(buf));
|
||||
proc = proc_net_fops_create(buf, 0440, &xt_file_ops);
|
||||
if (!proc)
|
||||
goto out;
|
||||
proc->data = (void *) ((unsigned long) af | (TABLE << 16));
|
||||
|
||||
|
||||
strlcpy(buf, xt_proto_prefix[af], sizeof(buf));
|
||||
strlcat(buf, FORMAT_MATCHES, sizeof(buf));
|
||||
proc = proc_net_fops_create(buf, 0440, &xt_file_ops);
|
||||
if (!proc)
|
||||
goto out_remove_tables;
|
||||
proc->data = (void *) ((unsigned long) af | (MATCH << 16));
|
||||
|
||||
strlcpy(buf, xt_proto_prefix[af], sizeof(buf));
|
||||
strlcat(buf, FORMAT_TARGETS, sizeof(buf));
|
||||
proc = proc_net_fops_create(buf, 0440, &xt_file_ops);
|
||||
if (!proc)
|
||||
goto out_remove_matches;
|
||||
proc->data = (void *) ((unsigned long) af | (TARGET << 16));
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
out_remove_matches:
|
||||
strlcpy(buf, xt_proto_prefix[af], sizeof(buf));
|
||||
strlcat(buf, FORMAT_MATCHES, sizeof(buf));
|
||||
proc_net_remove(buf);
|
||||
|
||||
out_remove_tables:
|
||||
strlcpy(buf, xt_proto_prefix[af], sizeof(buf));
|
||||
strlcat(buf, FORMAT_TABLES, sizeof(buf));
|
||||
proc_net_remove(buf);
|
||||
out:
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xt_proto_init);
|
||||
|
||||
void xt_proto_fini(int af)
|
||||
{
|
||||
#ifdef CONFIG_PROC_FS
|
||||
char buf[XT_FUNCTION_MAXNAMELEN];
|
||||
|
||||
strlcpy(buf, xt_proto_prefix[af], sizeof(buf));
|
||||
strlcat(buf, FORMAT_TABLES, sizeof(buf));
|
||||
proc_net_remove(buf);
|
||||
|
||||
strlcpy(buf, xt_proto_prefix[af], sizeof(buf));
|
||||
strlcat(buf, FORMAT_TARGETS, sizeof(buf));
|
||||
proc_net_remove(buf);
|
||||
|
||||
strlcpy(buf, xt_proto_prefix[af], sizeof(buf));
|
||||
strlcat(buf, FORMAT_MATCHES, sizeof(buf));
|
||||
proc_net_remove(buf);
|
||||
#endif /*CONFIG_PROC_FS*/
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xt_proto_fini);
|
||||
|
||||
|
||||
static int __init xt_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
xt = kmalloc(sizeof(struct xt_af) * NPROTO, GFP_KERNEL);
|
||||
if (!xt)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < NPROTO; i++) {
|
||||
init_MUTEX(&xt[i].mutex);
|
||||
INIT_LIST_HEAD(&xt[i].target);
|
||||
INIT_LIST_HEAD(&xt[i].match);
|
||||
INIT_LIST_HEAD(&xt[i].tables);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit xt_fini(void)
|
||||
{
|
||||
kfree(xt);
|
||||
}
|
||||
|
||||
module_init(xt_init);
|
||||
module_exit(xt_fini);
|
||||
|
@@ -15,12 +15,13 @@
|
||||
#include <linux/ip.h>
|
||||
#include <net/checksum.h>
|
||||
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
#include <linux/netfilter_ipv4/ipt_CLASSIFY.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include <linux/netfilter/xt_CLASSIFY.h>
|
||||
|
||||
MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("iptables qdisc classification target module");
|
||||
MODULE_ALIAS("ipt_CLASSIFY");
|
||||
|
||||
static unsigned int
|
||||
target(struct sk_buff **pskb,
|
||||
@@ -30,25 +31,25 @@ target(struct sk_buff **pskb,
|
||||
const void *targinfo,
|
||||
void *userinfo)
|
||||
{
|
||||
const struct ipt_classify_target_info *clinfo = targinfo;
|
||||
const struct xt_classify_target_info *clinfo = targinfo;
|
||||
|
||||
if((*pskb)->priority != clinfo->priority)
|
||||
if ((*pskb)->priority != clinfo->priority)
|
||||
(*pskb)->priority = clinfo->priority;
|
||||
|
||||
return IPT_CONTINUE;
|
||||
return XT_CONTINUE;
|
||||
}
|
||||
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const struct ipt_entry *e,
|
||||
const void *e,
|
||||
void *targinfo,
|
||||
unsigned int targinfosize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
if (targinfosize != IPT_ALIGN(sizeof(struct ipt_classify_target_info))){
|
||||
if (targinfosize != XT_ALIGN(sizeof(struct xt_classify_target_info))){
|
||||
printk(KERN_ERR "CLASSIFY: invalid size (%u != %Zu).\n",
|
||||
targinfosize,
|
||||
IPT_ALIGN(sizeof(struct ipt_classify_target_info)));
|
||||
XT_ALIGN(sizeof(struct xt_classify_target_info)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -69,21 +70,39 @@ checkentry(const char *tablename,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct ipt_target ipt_classify_reg = {
|
||||
static struct xt_target classify_reg = {
|
||||
.name = "CLASSIFY",
|
||||
.target = target,
|
||||
.checkentry = checkentry,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
static struct xt_target classify6_reg = {
|
||||
.name = "CLASSIFY",
|
||||
.target = target,
|
||||
.checkentry = checkentry,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
return ipt_register_target(&ipt_classify_reg);
|
||||
int ret;
|
||||
|
||||
ret = xt_register_target(AF_INET, &classify_reg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = xt_register_target(AF_INET6, &classify6_reg);
|
||||
if (ret)
|
||||
xt_unregister_target(AF_INET, &classify_reg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit fini(void)
|
||||
{
|
||||
ipt_unregister_target(&ipt_classify_reg);
|
||||
xt_unregister_target(AF_INET, &classify_reg);
|
||||
xt_unregister_target(AF_INET6, &classify6_reg);
|
||||
}
|
||||
|
||||
module_init(init);
|
@@ -26,9 +26,10 @@
|
||||
MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>");
|
||||
MODULE_DESCRIPTION("IP tables CONNMARK matching module");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ipt_CONNMARK");
|
||||
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
#include <linux/netfilter_ipv4/ipt_CONNMARK.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include <linux/netfilter/xt_CONNMARK.h>
|
||||
#include <net/netfilter/nf_conntrack_compat.h>
|
||||
|
||||
static unsigned int
|
||||
@@ -39,7 +40,7 @@ target(struct sk_buff **pskb,
|
||||
const void *targinfo,
|
||||
void *userinfo)
|
||||
{
|
||||
const struct ipt_connmark_target_info *markinfo = targinfo;
|
||||
const struct xt_connmark_target_info *markinfo = targinfo;
|
||||
u_int32_t diff;
|
||||
u_int32_t nfmark;
|
||||
u_int32_t newmark;
|
||||
@@ -48,17 +49,17 @@ target(struct sk_buff **pskb,
|
||||
|
||||
if (ctmark) {
|
||||
switch(markinfo->mode) {
|
||||
case IPT_CONNMARK_SET:
|
||||
case XT_CONNMARK_SET:
|
||||
newmark = (*ctmark & ~markinfo->mask) | markinfo->mark;
|
||||
if (newmark != *ctmark)
|
||||
*ctmark = newmark;
|
||||
break;
|
||||
case IPT_CONNMARK_SAVE:
|
||||
case XT_CONNMARK_SAVE:
|
||||
newmark = (*ctmark & ~markinfo->mask) | ((*pskb)->nfmark & markinfo->mask);
|
||||
if (*ctmark != newmark)
|
||||
*ctmark = newmark;
|
||||
break;
|
||||
case IPT_CONNMARK_RESTORE:
|
||||
case XT_CONNMARK_RESTORE:
|
||||
nfmark = (*pskb)->nfmark;
|
||||
diff = (*ctmark ^ nfmark) & markinfo->mask;
|
||||
if (diff != 0)
|
||||
@@ -67,25 +68,25 @@ target(struct sk_buff **pskb,
|
||||
}
|
||||
}
|
||||
|
||||
return IPT_CONTINUE;
|
||||
return XT_CONTINUE;
|
||||
}
|
||||
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const struct ipt_entry *e,
|
||||
const void *entry,
|
||||
void *targinfo,
|
||||
unsigned int targinfosize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
struct ipt_connmark_target_info *matchinfo = targinfo;
|
||||
if (targinfosize != IPT_ALIGN(sizeof(struct ipt_connmark_target_info))) {
|
||||
struct xt_connmark_target_info *matchinfo = targinfo;
|
||||
if (targinfosize != XT_ALIGN(sizeof(struct xt_connmark_target_info))) {
|
||||
printk(KERN_WARNING "CONNMARK: targinfosize %u != %Zu\n",
|
||||
targinfosize,
|
||||
IPT_ALIGN(sizeof(struct ipt_connmark_target_info)));
|
||||
XT_ALIGN(sizeof(struct xt_connmark_target_info)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (matchinfo->mode == IPT_CONNMARK_RESTORE) {
|
||||
if (matchinfo->mode == XT_CONNMARK_RESTORE) {
|
||||
if (strcmp(tablename, "mangle") != 0) {
|
||||
printk(KERN_WARNING "CONNMARK: restore can only be called from \"mangle\" table, not \"%s\"\n", tablename);
|
||||
return 0;
|
||||
@@ -100,7 +101,13 @@ checkentry(const char *tablename,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct ipt_target ipt_connmark_reg = {
|
||||
static struct xt_target connmark_reg = {
|
||||
.name = "CONNMARK",
|
||||
.target = &target,
|
||||
.checkentry = &checkentry,
|
||||
.me = THIS_MODULE
|
||||
};
|
||||
static struct xt_target connmark6_reg = {
|
||||
.name = "CONNMARK",
|
||||
.target = &target,
|
||||
.checkentry = &checkentry,
|
||||
@@ -109,13 +116,25 @@ static struct ipt_target ipt_connmark_reg = {
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
need_ip_conntrack();
|
||||
return ipt_register_target(&ipt_connmark_reg);
|
||||
int ret;
|
||||
|
||||
need_conntrack();
|
||||
|
||||
ret = xt_register_target(AF_INET, &connmark_reg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = xt_register_target(AF_INET6, &connmark6_reg);
|
||||
if (ret)
|
||||
xt_unregister_target(AF_INET, &connmark_reg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit fini(void)
|
||||
{
|
||||
ipt_unregister_target(&ipt_connmark_reg);
|
||||
xt_unregister_target(AF_INET, &connmark_reg);
|
||||
xt_unregister_target(AF_INET6, &connmark6_reg);
|
||||
}
|
||||
|
||||
module_init(init);
|
@@ -12,12 +12,14 @@
|
||||
#include <linux/ip.h>
|
||||
#include <net/checksum.h>
|
||||
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
#include <linux/netfilter_ipv4/ipt_MARK.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include <linux/netfilter/xt_MARK.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
|
||||
MODULE_DESCRIPTION("iptables MARK modification module");
|
||||
MODULE_DESCRIPTION("ip[6]tables MARK modification module");
|
||||
MODULE_ALIAS("ipt_MARK");
|
||||
MODULE_ALIAS("ip6t_MARK");
|
||||
|
||||
static unsigned int
|
||||
target_v0(struct sk_buff **pskb,
|
||||
@@ -27,12 +29,12 @@ target_v0(struct sk_buff **pskb,
|
||||
const void *targinfo,
|
||||
void *userinfo)
|
||||
{
|
||||
const struct ipt_mark_target_info *markinfo = targinfo;
|
||||
const struct xt_mark_target_info *markinfo = targinfo;
|
||||
|
||||
if((*pskb)->nfmark != markinfo->mark)
|
||||
(*pskb)->nfmark = markinfo->mark;
|
||||
|
||||
return IPT_CONTINUE;
|
||||
return XT_CONTINUE;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
@@ -43,19 +45,19 @@ target_v1(struct sk_buff **pskb,
|
||||
const void *targinfo,
|
||||
void *userinfo)
|
||||
{
|
||||
const struct ipt_mark_target_info_v1 *markinfo = targinfo;
|
||||
const struct xt_mark_target_info_v1 *markinfo = targinfo;
|
||||
int mark = 0;
|
||||
|
||||
switch (markinfo->mode) {
|
||||
case IPT_MARK_SET:
|
||||
case XT_MARK_SET:
|
||||
mark = markinfo->mark;
|
||||
break;
|
||||
|
||||
case IPT_MARK_AND:
|
||||
case XT_MARK_AND:
|
||||
mark = (*pskb)->nfmark & markinfo->mark;
|
||||
break;
|
||||
|
||||
case IPT_MARK_OR:
|
||||
case XT_MARK_OR:
|
||||
mark = (*pskb)->nfmark | markinfo->mark;
|
||||
break;
|
||||
}
|
||||
@@ -63,23 +65,23 @@ target_v1(struct sk_buff **pskb,
|
||||
if((*pskb)->nfmark != mark)
|
||||
(*pskb)->nfmark = mark;
|
||||
|
||||
return IPT_CONTINUE;
|
||||
return XT_CONTINUE;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
checkentry_v0(const char *tablename,
|
||||
const struct ipt_entry *e,
|
||||
const void *entry,
|
||||
void *targinfo,
|
||||
unsigned int targinfosize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
struct ipt_mark_target_info *markinfo = targinfo;
|
||||
struct xt_mark_target_info *markinfo = targinfo;
|
||||
|
||||
if (targinfosize != IPT_ALIGN(sizeof(struct ipt_mark_target_info))) {
|
||||
if (targinfosize != XT_ALIGN(sizeof(struct xt_mark_target_info))) {
|
||||
printk(KERN_WARNING "MARK: targinfosize %u != %Zu\n",
|
||||
targinfosize,
|
||||
IPT_ALIGN(sizeof(struct ipt_mark_target_info)));
|
||||
XT_ALIGN(sizeof(struct xt_mark_target_info)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -98,17 +100,17 @@ checkentry_v0(const char *tablename,
|
||||
|
||||
static int
|
||||
checkentry_v1(const char *tablename,
|
||||
const struct ipt_entry *e,
|
||||
const void *entry,
|
||||
void *targinfo,
|
||||
unsigned int targinfosize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
struct ipt_mark_target_info_v1 *markinfo = targinfo;
|
||||
struct xt_mark_target_info_v1 *markinfo = targinfo;
|
||||
|
||||
if (targinfosize != IPT_ALIGN(sizeof(struct ipt_mark_target_info_v1))){
|
||||
if (targinfosize != XT_ALIGN(sizeof(struct xt_mark_target_info_v1))){
|
||||
printk(KERN_WARNING "MARK: targinfosize %u != %Zu\n",
|
||||
targinfosize,
|
||||
IPT_ALIGN(sizeof(struct ipt_mark_target_info_v1)));
|
||||
XT_ALIGN(sizeof(struct xt_mark_target_info_v1)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -117,9 +119,9 @@ checkentry_v1(const char *tablename,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (markinfo->mode != IPT_MARK_SET
|
||||
&& markinfo->mode != IPT_MARK_AND
|
||||
&& markinfo->mode != IPT_MARK_OR) {
|
||||
if (markinfo->mode != XT_MARK_SET
|
||||
&& markinfo->mode != XT_MARK_AND
|
||||
&& markinfo->mode != XT_MARK_OR) {
|
||||
printk(KERN_WARNING "MARK: unknown mode %u\n",
|
||||
markinfo->mode);
|
||||
return 0;
|
||||
@@ -133,7 +135,7 @@ checkentry_v1(const char *tablename,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct ipt_target ipt_mark_reg_v0 = {
|
||||
static struct xt_target ipt_mark_reg_v0 = {
|
||||
.name = "MARK",
|
||||
.target = target_v0,
|
||||
.checkentry = checkentry_v0,
|
||||
@@ -141,7 +143,7 @@ static struct ipt_target ipt_mark_reg_v0 = {
|
||||
.revision = 0,
|
||||
};
|
||||
|
||||
static struct ipt_target ipt_mark_reg_v1 = {
|
||||
static struct xt_target ipt_mark_reg_v1 = {
|
||||
.name = "MARK",
|
||||
.target = target_v1,
|
||||
.checkentry = checkentry_v1,
|
||||
@@ -149,23 +151,40 @@ static struct ipt_target ipt_mark_reg_v1 = {
|
||||
.revision = 1,
|
||||
};
|
||||
|
||||
static struct xt_target ip6t_mark_reg_v0 = {
|
||||
.name = "MARK",
|
||||
.target = target_v0,
|
||||
.checkentry = checkentry_v0,
|
||||
.me = THIS_MODULE,
|
||||
.revision = 0,
|
||||
};
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = ipt_register_target(&ipt_mark_reg_v0);
|
||||
if (!err) {
|
||||
err = ipt_register_target(&ipt_mark_reg_v1);
|
||||
if (err)
|
||||
ipt_unregister_target(&ipt_mark_reg_v0);
|
||||
err = xt_register_target(AF_INET, &ipt_mark_reg_v0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = xt_register_target(AF_INET, &ipt_mark_reg_v1);
|
||||
if (err)
|
||||
xt_unregister_target(AF_INET, &ipt_mark_reg_v0);
|
||||
|
||||
err = xt_register_target(AF_INET6, &ip6t_mark_reg_v0);
|
||||
if (err) {
|
||||
xt_unregister_target(AF_INET, &ipt_mark_reg_v0);
|
||||
xt_unregister_target(AF_INET, &ipt_mark_reg_v1);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void __exit fini(void)
|
||||
{
|
||||
ipt_unregister_target(&ipt_mark_reg_v0);
|
||||
ipt_unregister_target(&ipt_mark_reg_v1);
|
||||
xt_unregister_target(AF_INET, &ipt_mark_reg_v0);
|
||||
xt_unregister_target(AF_INET, &ipt_mark_reg_v1);
|
||||
xt_unregister_target(AF_INET6, &ip6t_mark_reg_v0);
|
||||
}
|
||||
|
||||
module_init(init);
|
107
net/netfilter/xt_NFQUEUE.c
Normal file
107
net/netfilter/xt_NFQUEUE.c
Normal file
@@ -0,0 +1,107 @@
|
||||
/* iptables module for using new netfilter netlink queue
|
||||
*
|
||||
* (C) 2005 by Harald Welte <laforge@netfilter.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/netfilter_arp.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include <linux/netfilter/xt_NFQUEUE.h>
|
||||
|
||||
MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
|
||||
MODULE_DESCRIPTION("[ip,ip6,arp]_tables NFQUEUE target");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ipt_NFQUEUE");
|
||||
MODULE_ALIAS("ip6t_NFQUEUE");
|
||||
MODULE_ALIAS("arpt_NFQUEUE");
|
||||
|
||||
static unsigned int
|
||||
target(struct sk_buff **pskb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
unsigned int hooknum,
|
||||
const void *targinfo,
|
||||
void *userinfo)
|
||||
{
|
||||
const struct xt_NFQ_info *tinfo = targinfo;
|
||||
|
||||
return NF_QUEUE_NR(tinfo->queuenum);
|
||||
}
|
||||
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const void *entry,
|
||||
void *targinfo,
|
||||
unsigned int targinfosize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
if (targinfosize != XT_ALIGN(sizeof(struct xt_NFQ_info))) {
|
||||
printk(KERN_WARNING "NFQUEUE: targinfosize %u != %Zu\n",
|
||||
targinfosize,
|
||||
XT_ALIGN(sizeof(struct xt_NFQ_info)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct xt_target ipt_NFQ_reg = {
|
||||
.name = "NFQUEUE",
|
||||
.target = target,
|
||||
.checkentry = checkentry,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static struct xt_target ip6t_NFQ_reg = {
|
||||
.name = "NFQUEUE",
|
||||
.target = target,
|
||||
.checkentry = checkentry,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static struct xt_target arpt_NFQ_reg = {
|
||||
.name = "NFQUEUE",
|
||||
.target = target,
|
||||
.checkentry = checkentry,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
int ret;
|
||||
ret = xt_register_target(AF_INET, &ipt_NFQ_reg);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = xt_register_target(AF_INET6, &ip6t_NFQ_reg);
|
||||
if (ret)
|
||||
goto out_ip;
|
||||
ret = xt_register_target(NF_ARP, &arpt_NFQ_reg);
|
||||
if (ret)
|
||||
goto out_ip6;
|
||||
|
||||
return ret;
|
||||
out_ip6:
|
||||
xt_unregister_target(AF_INET6, &ip6t_NFQ_reg);
|
||||
out_ip:
|
||||
xt_unregister_target(AF_INET, &ipt_NFQ_reg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit fini(void)
|
||||
{
|
||||
xt_unregister_target(NF_ARP, &arpt_NFQ_reg);
|
||||
xt_unregister_target(AF_INET6, &ip6t_NFQ_reg);
|
||||
xt_unregister_target(AF_INET, &ipt_NFQ_reg);
|
||||
}
|
||||
|
||||
module_init(init);
|
||||
module_exit(fini);
|
@@ -4,9 +4,12 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include <net/netfilter/nf_conntrack_compat.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ipt_NOTRACK");
|
||||
|
||||
static unsigned int
|
||||
target(struct sk_buff **pskb,
|
||||
const struct net_device *in,
|
||||
@@ -17,7 +20,7 @@ target(struct sk_buff **pskb,
|
||||
{
|
||||
/* Previously seen (loopback)? Ignore. */
|
||||
if ((*pskb)->nfct != NULL)
|
||||
return IPT_CONTINUE;
|
||||
return XT_CONTINUE;
|
||||
|
||||
/* Attach fake conntrack entry.
|
||||
If there is a real ct entry correspondig to this packet,
|
||||
@@ -27,12 +30,12 @@ target(struct sk_buff **pskb,
|
||||
(*pskb)->nfctinfo = IP_CT_NEW;
|
||||
nf_conntrack_get((*pskb)->nfct);
|
||||
|
||||
return IPT_CONTINUE;
|
||||
return XT_CONTINUE;
|
||||
}
|
||||
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const struct ipt_entry *e,
|
||||
const void *entry,
|
||||
void *targinfo,
|
||||
unsigned int targinfosize,
|
||||
unsigned int hook_mask)
|
||||
@@ -51,26 +54,39 @@ checkentry(const char *tablename,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct ipt_target ipt_notrack_reg = {
|
||||
static struct xt_target notrack_reg = {
|
||||
.name = "NOTRACK",
|
||||
.target = target,
|
||||
.checkentry = checkentry,
|
||||
.me = THIS_MODULE
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
static struct xt_target notrack6_reg = {
|
||||
.name = "NOTRACK",
|
||||
.target = target,
|
||||
.checkentry = checkentry,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
if (ipt_register_target(&ipt_notrack_reg))
|
||||
return -EINVAL;
|
||||
int ret;
|
||||
|
||||
return 0;
|
||||
ret = xt_register_target(AF_INET, ¬rack_reg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = xt_register_target(AF_INET6, ¬rack6_reg);
|
||||
if (ret)
|
||||
xt_unregister_target(AF_INET, ¬rack_reg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit fini(void)
|
||||
{
|
||||
ipt_unregister_target(&ipt_notrack_reg);
|
||||
xt_unregister_target(AF_INET6, ¬rack6_reg);
|
||||
xt_unregister_target(AF_INET, ¬rack_reg);
|
||||
}
|
||||
|
||||
module_init(init);
|
||||
module_exit(fini);
|
||||
MODULE_LICENSE("GPL");
|
@@ -6,12 +6,14 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
#include <linux/netfilter_ipv4/ipt_comment.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include <linux/netfilter/xt_comment.h>
|
||||
|
||||
MODULE_AUTHOR("Brad Fisher <brad@info-link.net>");
|
||||
MODULE_DESCRIPTION("iptables comment match module");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ipt_comment");
|
||||
MODULE_ALIAS("ip6t_comment");
|
||||
|
||||
static int
|
||||
match(const struct sk_buff *skb,
|
||||
@@ -19,6 +21,7 @@ match(const struct sk_buff *skb,
|
||||
const struct net_device *out,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protooff,
|
||||
int *hotdrop)
|
||||
{
|
||||
/* We always match */
|
||||
@@ -27,18 +30,25 @@ match(const struct sk_buff *skb,
|
||||
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const struct ipt_ip *ip,
|
||||
const void *ip,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
/* Check the size */
|
||||
if (matchsize != IPT_ALIGN(sizeof(struct ipt_comment_info)))
|
||||
if (matchsize != XT_ALIGN(sizeof(struct xt_comment_info)))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct ipt_match comment_match = {
|
||||
static struct xt_match comment_match = {
|
||||
.name = "comment",
|
||||
.match = match,
|
||||
.checkentry = checkentry,
|
||||
.me = THIS_MODULE
|
||||
};
|
||||
|
||||
static struct xt_match comment6_match = {
|
||||
.name = "comment",
|
||||
.match = match,
|
||||
.checkentry = checkentry,
|
||||
@@ -47,12 +57,23 @@ static struct ipt_match comment_match = {
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
return ipt_register_match(&comment_match);
|
||||
int ret;
|
||||
|
||||
ret = xt_register_match(AF_INET, &comment_match);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = xt_register_match(AF_INET6, &comment6_match);
|
||||
if (ret)
|
||||
xt_unregister_match(AF_INET, &comment_match);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit fini(void)
|
||||
{
|
||||
ipt_unregister_match(&comment_match);
|
||||
xt_unregister_match(AF_INET, &comment_match);
|
||||
xt_unregister_match(AF_INET6, &comment6_match);
|
||||
}
|
||||
|
||||
module_init(init);
|
@@ -6,13 +6,15 @@
|
||||
* - add functionality to match number of packets
|
||||
* - add functionality to match average packet size
|
||||
* - add support to match directions seperately
|
||||
* 2005-10-16 Harald Welte <laforge@netfilter.org>
|
||||
* - Port to x_tables
|
||||
*
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <net/netfilter/nf_conntrack_compat.h>
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
#include <linux/netfilter_ipv4/ipt_connbytes.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include <linux/netfilter/xt_connbytes.h>
|
||||
|
||||
#include <asm/div64.h>
|
||||
#include <asm/bitops.h>
|
||||
@@ -20,6 +22,7 @@
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
|
||||
MODULE_DESCRIPTION("iptables match for matching number of pkts/bytes per connection");
|
||||
MODULE_ALIAS("ipt_connbytes");
|
||||
|
||||
/* 64bit divisor, dividend and result. dynamic precision */
|
||||
static u_int64_t div64_64(u_int64_t dividend, u_int64_t divisor)
|
||||
@@ -43,9 +46,10 @@ match(const struct sk_buff *skb,
|
||||
const struct net_device *out,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
const struct ipt_connbytes_info *sinfo = matchinfo;
|
||||
const struct xt_connbytes_info *sinfo = matchinfo;
|
||||
u_int64_t what = 0; /* initialize to make gcc happy */
|
||||
const struct ip_conntrack_counter *counters;
|
||||
|
||||
@@ -53,45 +57,45 @@ match(const struct sk_buff *skb,
|
||||
return 0; /* no match */
|
||||
|
||||
switch (sinfo->what) {
|
||||
case IPT_CONNBYTES_PKTS:
|
||||
case XT_CONNBYTES_PKTS:
|
||||
switch (sinfo->direction) {
|
||||
case IPT_CONNBYTES_DIR_ORIGINAL:
|
||||
case XT_CONNBYTES_DIR_ORIGINAL:
|
||||
what = counters[IP_CT_DIR_ORIGINAL].packets;
|
||||
break;
|
||||
case IPT_CONNBYTES_DIR_REPLY:
|
||||
case XT_CONNBYTES_DIR_REPLY:
|
||||
what = counters[IP_CT_DIR_REPLY].packets;
|
||||
break;
|
||||
case IPT_CONNBYTES_DIR_BOTH:
|
||||
case XT_CONNBYTES_DIR_BOTH:
|
||||
what = counters[IP_CT_DIR_ORIGINAL].packets;
|
||||
what += counters[IP_CT_DIR_REPLY].packets;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case IPT_CONNBYTES_BYTES:
|
||||
case XT_CONNBYTES_BYTES:
|
||||
switch (sinfo->direction) {
|
||||
case IPT_CONNBYTES_DIR_ORIGINAL:
|
||||
case XT_CONNBYTES_DIR_ORIGINAL:
|
||||
what = counters[IP_CT_DIR_ORIGINAL].bytes;
|
||||
break;
|
||||
case IPT_CONNBYTES_DIR_REPLY:
|
||||
case XT_CONNBYTES_DIR_REPLY:
|
||||
what = counters[IP_CT_DIR_REPLY].bytes;
|
||||
break;
|
||||
case IPT_CONNBYTES_DIR_BOTH:
|
||||
case XT_CONNBYTES_DIR_BOTH:
|
||||
what = counters[IP_CT_DIR_ORIGINAL].bytes;
|
||||
what += counters[IP_CT_DIR_REPLY].bytes;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case IPT_CONNBYTES_AVGPKT:
|
||||
case XT_CONNBYTES_AVGPKT:
|
||||
switch (sinfo->direction) {
|
||||
case IPT_CONNBYTES_DIR_ORIGINAL:
|
||||
case XT_CONNBYTES_DIR_ORIGINAL:
|
||||
what = div64_64(counters[IP_CT_DIR_ORIGINAL].bytes,
|
||||
counters[IP_CT_DIR_ORIGINAL].packets);
|
||||
break;
|
||||
case IPT_CONNBYTES_DIR_REPLY:
|
||||
case XT_CONNBYTES_DIR_REPLY:
|
||||
what = div64_64(counters[IP_CT_DIR_REPLY].bytes,
|
||||
counters[IP_CT_DIR_REPLY].packets);
|
||||
break;
|
||||
case IPT_CONNBYTES_DIR_BOTH:
|
||||
case XT_CONNBYTES_DIR_BOTH:
|
||||
{
|
||||
u_int64_t bytes;
|
||||
u_int64_t pkts;
|
||||
@@ -117,30 +121,36 @@ match(const struct sk_buff *skb,
|
||||
}
|
||||
|
||||
static int check(const char *tablename,
|
||||
const struct ipt_ip *ip,
|
||||
const void *ip,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
const struct ipt_connbytes_info *sinfo = matchinfo;
|
||||
const struct xt_connbytes_info *sinfo = matchinfo;
|
||||
|
||||
if (matchsize != IPT_ALIGN(sizeof(struct ipt_connbytes_info)))
|
||||
if (matchsize != XT_ALIGN(sizeof(struct xt_connbytes_info)))
|
||||
return 0;
|
||||
|
||||
if (sinfo->what != IPT_CONNBYTES_PKTS &&
|
||||
sinfo->what != IPT_CONNBYTES_BYTES &&
|
||||
sinfo->what != IPT_CONNBYTES_AVGPKT)
|
||||
if (sinfo->what != XT_CONNBYTES_PKTS &&
|
||||
sinfo->what != XT_CONNBYTES_BYTES &&
|
||||
sinfo->what != XT_CONNBYTES_AVGPKT)
|
||||
return 0;
|
||||
|
||||
if (sinfo->direction != IPT_CONNBYTES_DIR_ORIGINAL &&
|
||||
sinfo->direction != IPT_CONNBYTES_DIR_REPLY &&
|
||||
sinfo->direction != IPT_CONNBYTES_DIR_BOTH)
|
||||
if (sinfo->direction != XT_CONNBYTES_DIR_ORIGINAL &&
|
||||
sinfo->direction != XT_CONNBYTES_DIR_REPLY &&
|
||||
sinfo->direction != XT_CONNBYTES_DIR_BOTH)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct ipt_match state_match = {
|
||||
static struct xt_match connbytes_match = {
|
||||
.name = "connbytes",
|
||||
.match = &match,
|
||||
.checkentry = &check,
|
||||
.me = THIS_MODULE
|
||||
};
|
||||
static struct xt_match connbytes6_match = {
|
||||
.name = "connbytes",
|
||||
.match = &match,
|
||||
.checkentry = &check,
|
||||
@@ -149,12 +159,21 @@ static struct ipt_match state_match = {
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
return ipt_register_match(&state_match);
|
||||
int ret;
|
||||
ret = xt_register_match(AF_INET, &connbytes_match);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = xt_register_match(AF_INET6, &connbytes6_match);
|
||||
if (ret)
|
||||
xt_unregister_match(AF_INET, &connbytes_match);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit fini(void)
|
||||
{
|
||||
ipt_unregister_match(&state_match);
|
||||
xt_unregister_match(AF_INET, &connbytes_match);
|
||||
xt_unregister_match(AF_INET6, &connbytes6_match);
|
||||
}
|
||||
|
||||
module_init(init);
|
@@ -25,9 +25,10 @@
|
||||
MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>");
|
||||
MODULE_DESCRIPTION("IP tables connmark match module");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ipt_connmark");
|
||||
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
#include <linux/netfilter_ipv4/ipt_connmark.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include <linux/netfilter/xt_connmark.h>
|
||||
#include <net/netfilter/nf_conntrack_compat.h>
|
||||
|
||||
static int
|
||||
@@ -36,9 +37,10 @@ match(const struct sk_buff *skb,
|
||||
const struct net_device *out,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
const struct ipt_connmark_info *info = matchinfo;
|
||||
const struct xt_connmark_info *info = matchinfo;
|
||||
u_int32_t ctinfo;
|
||||
const u_int32_t *ctmark = nf_ct_get_mark(skb, &ctinfo);
|
||||
if (!ctmark)
|
||||
@@ -49,14 +51,14 @@ match(const struct sk_buff *skb,
|
||||
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const struct ipt_ip *ip,
|
||||
const void *ip,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
struct ipt_connmark_info *cm =
|
||||
(struct ipt_connmark_info *)matchinfo;
|
||||
if (matchsize != IPT_ALIGN(sizeof(struct ipt_connmark_info)))
|
||||
struct xt_connmark_info *cm =
|
||||
(struct xt_connmark_info *)matchinfo;
|
||||
if (matchsize != XT_ALIGN(sizeof(struct xt_connmark_info)))
|
||||
return 0;
|
||||
|
||||
if (cm->mark > 0xffffffff || cm->mask > 0xffffffff) {
|
||||
@@ -67,21 +69,40 @@ checkentry(const char *tablename,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct ipt_match connmark_match = {
|
||||
static struct xt_match connmark_match = {
|
||||
.name = "connmark",
|
||||
.match = &match,
|
||||
.checkentry = &checkentry,
|
||||
.me = THIS_MODULE
|
||||
};
|
||||
static struct xt_match connmark6_match = {
|
||||
.name = "connmark",
|
||||
.match = &match,
|
||||
.checkentry = &checkentry,
|
||||
.me = THIS_MODULE
|
||||
};
|
||||
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
return ipt_register_match(&connmark_match);
|
||||
int ret;
|
||||
|
||||
need_conntrack();
|
||||
|
||||
ret = xt_register_match(AF_INET, &connmark_match);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = xt_register_match(AF_INET6, &connmark6_match);
|
||||
if (ret)
|
||||
xt_unregister_match(AF_INET, &connmark_match);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit fini(void)
|
||||
{
|
||||
ipt_unregister_match(&connmark_match);
|
||||
xt_unregister_match(AF_INET6, &connmark6_match);
|
||||
xt_unregister_match(AF_INET, &connmark_match);
|
||||
}
|
||||
|
||||
module_init(init);
|
@@ -18,12 +18,13 @@
|
||||
#include <net/netfilter/nf_conntrack.h>
|
||||
#endif
|
||||
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
#include <linux/netfilter_ipv4/ipt_conntrack.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include <linux/netfilter/xt_conntrack.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
|
||||
MODULE_DESCRIPTION("iptables connection tracking match module");
|
||||
MODULE_ALIAS("ipt_conntrack");
|
||||
|
||||
#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)
|
||||
|
||||
@@ -33,9 +34,10 @@ match(const struct sk_buff *skb,
|
||||
const struct net_device *out,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
const struct ipt_conntrack_info *sinfo = matchinfo;
|
||||
const struct xt_conntrack_info *sinfo = matchinfo;
|
||||
struct ip_conntrack *ct;
|
||||
enum ip_conntrack_info ctinfo;
|
||||
unsigned int statebit;
|
||||
@@ -45,58 +47,58 @@ match(const struct sk_buff *skb,
|
||||
#define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg))
|
||||
|
||||
if (ct == &ip_conntrack_untracked)
|
||||
statebit = IPT_CONNTRACK_STATE_UNTRACKED;
|
||||
statebit = XT_CONNTRACK_STATE_UNTRACKED;
|
||||
else if (ct)
|
||||
statebit = IPT_CONNTRACK_STATE_BIT(ctinfo);
|
||||
statebit = XT_CONNTRACK_STATE_BIT(ctinfo);
|
||||
else
|
||||
statebit = IPT_CONNTRACK_STATE_INVALID;
|
||||
statebit = XT_CONNTRACK_STATE_INVALID;
|
||||
|
||||
if(sinfo->flags & IPT_CONNTRACK_STATE) {
|
||||
if(sinfo->flags & XT_CONNTRACK_STATE) {
|
||||
if (ct) {
|
||||
if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip !=
|
||||
ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip)
|
||||
statebit |= IPT_CONNTRACK_STATE_SNAT;
|
||||
statebit |= XT_CONNTRACK_STATE_SNAT;
|
||||
|
||||
if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip !=
|
||||
ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip)
|
||||
statebit |= IPT_CONNTRACK_STATE_DNAT;
|
||||
statebit |= XT_CONNTRACK_STATE_DNAT;
|
||||
}
|
||||
|
||||
if (FWINV((statebit & sinfo->statemask) == 0, IPT_CONNTRACK_STATE))
|
||||
if (FWINV((statebit & sinfo->statemask) == 0, XT_CONNTRACK_STATE))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(sinfo->flags & IPT_CONNTRACK_PROTO) {
|
||||
if (!ct || FWINV(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum, IPT_CONNTRACK_PROTO))
|
||||
if(sinfo->flags & XT_CONNTRACK_PROTO) {
|
||||
if (!ct || FWINV(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum, XT_CONNTRACK_PROTO))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(sinfo->flags & IPT_CONNTRACK_ORIGSRC) {
|
||||
if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip&sinfo->sipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip, IPT_CONNTRACK_ORIGSRC))
|
||||
if(sinfo->flags & XT_CONNTRACK_ORIGSRC) {
|
||||
if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip&sinfo->sipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip, XT_CONNTRACK_ORIGSRC))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(sinfo->flags & IPT_CONNTRACK_ORIGDST) {
|
||||
if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip&sinfo->dipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip, IPT_CONNTRACK_ORIGDST))
|
||||
if(sinfo->flags & XT_CONNTRACK_ORIGDST) {
|
||||
if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip&sinfo->dipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip, XT_CONNTRACK_ORIGDST))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(sinfo->flags & IPT_CONNTRACK_REPLSRC) {
|
||||
if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip&sinfo->sipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].src.ip, IPT_CONNTRACK_REPLSRC))
|
||||
if(sinfo->flags & XT_CONNTRACK_REPLSRC) {
|
||||
if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip&sinfo->sipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].src.ip, XT_CONNTRACK_REPLSRC))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(sinfo->flags & IPT_CONNTRACK_REPLDST) {
|
||||
if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip&sinfo->dipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].dst.ip, IPT_CONNTRACK_REPLDST))
|
||||
if(sinfo->flags & XT_CONNTRACK_REPLDST) {
|
||||
if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip&sinfo->dipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].dst.ip, XT_CONNTRACK_REPLDST))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(sinfo->flags & IPT_CONNTRACK_STATUS) {
|
||||
if (!ct || FWINV((ct->status & sinfo->statusmask) == 0, IPT_CONNTRACK_STATUS))
|
||||
if(sinfo->flags & XT_CONNTRACK_STATUS) {
|
||||
if (!ct || FWINV((ct->status & sinfo->statusmask) == 0, XT_CONNTRACK_STATUS))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(sinfo->flags & IPT_CONNTRACK_EXPIRES) {
|
||||
if(sinfo->flags & XT_CONNTRACK_EXPIRES) {
|
||||
unsigned long expires;
|
||||
|
||||
if(!ct)
|
||||
@@ -104,7 +106,7 @@ match(const struct sk_buff *skb,
|
||||
|
||||
expires = timer_pending(&ct->timeout) ? (ct->timeout.expires - jiffies)/HZ : 0;
|
||||
|
||||
if (FWINV(!(expires >= sinfo->expires_min && expires <= sinfo->expires_max), IPT_CONNTRACK_EXPIRES))
|
||||
if (FWINV(!(expires >= sinfo->expires_min && expires <= sinfo->expires_max), XT_CONNTRACK_EXPIRES))
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -118,9 +120,10 @@ match(const struct sk_buff *skb,
|
||||
const struct net_device *out,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
const struct ipt_conntrack_info *sinfo = matchinfo;
|
||||
const struct xt_conntrack_info *sinfo = matchinfo;
|
||||
struct nf_conn *ct;
|
||||
enum ip_conntrack_info ctinfo;
|
||||
unsigned int statebit;
|
||||
@@ -130,58 +133,58 @@ match(const struct sk_buff *skb,
|
||||
#define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg))
|
||||
|
||||
if (ct == &nf_conntrack_untracked)
|
||||
statebit = IPT_CONNTRACK_STATE_UNTRACKED;
|
||||
statebit = XT_CONNTRACK_STATE_UNTRACKED;
|
||||
else if (ct)
|
||||
statebit = IPT_CONNTRACK_STATE_BIT(ctinfo);
|
||||
statebit = XT_CONNTRACK_STATE_BIT(ctinfo);
|
||||
else
|
||||
statebit = IPT_CONNTRACK_STATE_INVALID;
|
||||
statebit = XT_CONNTRACK_STATE_INVALID;
|
||||
|
||||
if(sinfo->flags & IPT_CONNTRACK_STATE) {
|
||||
if(sinfo->flags & XT_CONNTRACK_STATE) {
|
||||
if (ct) {
|
||||
if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip !=
|
||||
ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip)
|
||||
statebit |= IPT_CONNTRACK_STATE_SNAT;
|
||||
statebit |= XT_CONNTRACK_STATE_SNAT;
|
||||
|
||||
if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip !=
|
||||
ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip)
|
||||
statebit |= IPT_CONNTRACK_STATE_DNAT;
|
||||
statebit |= XT_CONNTRACK_STATE_DNAT;
|
||||
}
|
||||
|
||||
if (FWINV((statebit & sinfo->statemask) == 0, IPT_CONNTRACK_STATE))
|
||||
if (FWINV((statebit & sinfo->statemask) == 0, XT_CONNTRACK_STATE))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(sinfo->flags & IPT_CONNTRACK_PROTO) {
|
||||
if (!ct || FWINV(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum, IPT_CONNTRACK_PROTO))
|
||||
if(sinfo->flags & XT_CONNTRACK_PROTO) {
|
||||
if (!ct || FWINV(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum, XT_CONNTRACK_PROTO))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(sinfo->flags & IPT_CONNTRACK_ORIGSRC) {
|
||||
if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip&sinfo->sipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip, IPT_CONNTRACK_ORIGSRC))
|
||||
if(sinfo->flags & XT_CONNTRACK_ORIGSRC) {
|
||||
if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip&sinfo->sipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip, XT_CONNTRACK_ORIGSRC))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(sinfo->flags & IPT_CONNTRACK_ORIGDST) {
|
||||
if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip&sinfo->dipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip, IPT_CONNTRACK_ORIGDST))
|
||||
if(sinfo->flags & XT_CONNTRACK_ORIGDST) {
|
||||
if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip&sinfo->dipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip, XT_CONNTRACK_ORIGDST))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(sinfo->flags & IPT_CONNTRACK_REPLSRC) {
|
||||
if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip&sinfo->sipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].src.ip, IPT_CONNTRACK_REPLSRC))
|
||||
if(sinfo->flags & XT_CONNTRACK_REPLSRC) {
|
||||
if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip&sinfo->sipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].src.ip, XT_CONNTRACK_REPLSRC))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(sinfo->flags & IPT_CONNTRACK_REPLDST) {
|
||||
if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip&sinfo->dipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].dst.ip, IPT_CONNTRACK_REPLDST))
|
||||
if(sinfo->flags & XT_CONNTRACK_REPLDST) {
|
||||
if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip&sinfo->dipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].dst.ip, XT_CONNTRACK_REPLDST))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(sinfo->flags & IPT_CONNTRACK_STATUS) {
|
||||
if (!ct || FWINV((ct->status & sinfo->statusmask) == 0, IPT_CONNTRACK_STATUS))
|
||||
if(sinfo->flags & XT_CONNTRACK_STATUS) {
|
||||
if (!ct || FWINV((ct->status & sinfo->statusmask) == 0, XT_CONNTRACK_STATUS))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(sinfo->flags & IPT_CONNTRACK_EXPIRES) {
|
||||
if(sinfo->flags & XT_CONNTRACK_EXPIRES) {
|
||||
unsigned long expires;
|
||||
|
||||
if(!ct)
|
||||
@@ -189,7 +192,7 @@ match(const struct sk_buff *skb,
|
||||
|
||||
expires = timer_pending(&ct->timeout) ? (ct->timeout.expires - jiffies)/HZ : 0;
|
||||
|
||||
if (FWINV(!(expires >= sinfo->expires_min && expires <= sinfo->expires_max), IPT_CONNTRACK_EXPIRES))
|
||||
if (FWINV(!(expires >= sinfo->expires_min && expires <= sinfo->expires_max), XT_CONNTRACK_EXPIRES))
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -199,18 +202,18 @@ match(const struct sk_buff *skb,
|
||||
#endif /* CONFIG_NF_IP_CONNTRACK */
|
||||
|
||||
static int check(const char *tablename,
|
||||
const struct ipt_ip *ip,
|
||||
const void *ip,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
if (matchsize != IPT_ALIGN(sizeof(struct ipt_conntrack_info)))
|
||||
if (matchsize != XT_ALIGN(sizeof(struct xt_conntrack_info)))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct ipt_match conntrack_match = {
|
||||
static struct xt_match conntrack_match = {
|
||||
.name = "conntrack",
|
||||
.match = &match,
|
||||
.checkentry = &check,
|
||||
@@ -219,13 +222,16 @@ static struct ipt_match conntrack_match = {
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
need_ip_conntrack();
|
||||
return ipt_register_match(&conntrack_match);
|
||||
int ret;
|
||||
need_conntrack();
|
||||
ret = xt_register_match(AF_INET, &conntrack_match);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit fini(void)
|
||||
{
|
||||
ipt_unregister_match(&conntrack_match);
|
||||
xt_unregister_match(AF_INET, &conntrack_match);
|
||||
}
|
||||
|
||||
module_init(init);
|
@@ -14,8 +14,16 @@
|
||||
#include <net/ip.h>
|
||||
#include <linux/dccp.h>
|
||||
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include <linux/netfilter/xt_dccp.h>
|
||||
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
#include <linux/netfilter_ipv4/ipt_dccp.h>
|
||||
#include <linux/netfilter_ipv6/ip6_tables.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
|
||||
MODULE_DESCRIPTION("Match for DCCP protocol packets");
|
||||
MODULE_ALIAS("ipt_dccp");
|
||||
|
||||
#define DCCHECK(cond, option, flag, invflag) (!((flag) & (option)) \
|
||||
|| (!!((invflag) & (option)) ^ (cond)))
|
||||
@@ -26,6 +34,7 @@ static DEFINE_SPINLOCK(dccp_buflock);
|
||||
static inline int
|
||||
dccp_find_option(u_int8_t option,
|
||||
const struct sk_buff *skb,
|
||||
unsigned int protoff,
|
||||
const struct dccp_hdr *dh,
|
||||
int *hotdrop)
|
||||
{
|
||||
@@ -44,9 +53,7 @@ dccp_find_option(u_int8_t option,
|
||||
return 0;
|
||||
|
||||
spin_lock_bh(&dccp_buflock);
|
||||
op = skb_header_pointer(skb,
|
||||
skb->nh.iph->ihl*4 + optoff,
|
||||
optlen, dccp_optbuf);
|
||||
op = skb_header_pointer(skb, protoff + optoff, optlen, dccp_optbuf);
|
||||
if (op == NULL) {
|
||||
/* If we don't have the whole header, drop packet. */
|
||||
spin_unlock_bh(&dccp_buflock);
|
||||
@@ -78,10 +85,10 @@ match_types(const struct dccp_hdr *dh, u_int16_t typemask)
|
||||
}
|
||||
|
||||
static inline int
|
||||
match_option(u_int8_t option, const struct sk_buff *skb,
|
||||
match_option(u_int8_t option, const struct sk_buff *skb, unsigned int protoff,
|
||||
const struct dccp_hdr *dh, int *hotdrop)
|
||||
{
|
||||
return dccp_find_option(option, skb, dh, hotdrop);
|
||||
return dccp_find_option(option, skb, protoff, dh, hotdrop);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -90,16 +97,17 @@ match(const struct sk_buff *skb,
|
||||
const struct net_device *out,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
const struct ipt_dccp_info *info =
|
||||
(const struct ipt_dccp_info *)matchinfo;
|
||||
const struct xt_dccp_info *info =
|
||||
(const struct xt_dccp_info *)matchinfo;
|
||||
struct dccp_hdr _dh, *dh;
|
||||
|
||||
if (offset)
|
||||
return 0;
|
||||
|
||||
dh = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_dh), &_dh);
|
||||
dh = skb_header_pointer(skb, protoff, sizeof(_dh), &_dh);
|
||||
if (dh == NULL) {
|
||||
*hotdrop = 1;
|
||||
return 0;
|
||||
@@ -107,42 +115,73 @@ match(const struct sk_buff *skb,
|
||||
|
||||
return DCCHECK(((ntohs(dh->dccph_sport) >= info->spts[0])
|
||||
&& (ntohs(dh->dccph_sport) <= info->spts[1])),
|
||||
IPT_DCCP_SRC_PORTS, info->flags, info->invflags)
|
||||
XT_DCCP_SRC_PORTS, info->flags, info->invflags)
|
||||
&& DCCHECK(((ntohs(dh->dccph_dport) >= info->dpts[0])
|
||||
&& (ntohs(dh->dccph_dport) <= info->dpts[1])),
|
||||
IPT_DCCP_DEST_PORTS, info->flags, info->invflags)
|
||||
XT_DCCP_DEST_PORTS, info->flags, info->invflags)
|
||||
&& DCCHECK(match_types(dh, info->typemask),
|
||||
IPT_DCCP_TYPE, info->flags, info->invflags)
|
||||
&& DCCHECK(match_option(info->option, skb, dh, hotdrop),
|
||||
IPT_DCCP_OPTION, info->flags, info->invflags);
|
||||
XT_DCCP_TYPE, info->flags, info->invflags)
|
||||
&& DCCHECK(match_option(info->option, skb, protoff, dh,
|
||||
hotdrop),
|
||||
XT_DCCP_OPTION, info->flags, info->invflags);
|
||||
}
|
||||
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const struct ipt_ip *ip,
|
||||
const void *inf,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
const struct ipt_dccp_info *info;
|
||||
const struct ipt_ip *ip = inf;
|
||||
const struct xt_dccp_info *info;
|
||||
|
||||
info = (const struct ipt_dccp_info *)matchinfo;
|
||||
info = (const struct xt_dccp_info *)matchinfo;
|
||||
|
||||
return ip->proto == IPPROTO_DCCP
|
||||
&& !(ip->invflags & IPT_INV_PROTO)
|
||||
&& matchsize == IPT_ALIGN(sizeof(struct ipt_dccp_info))
|
||||
&& !(info->flags & ~IPT_DCCP_VALID_FLAGS)
|
||||
&& !(info->invflags & ~IPT_DCCP_VALID_FLAGS)
|
||||
&& !(ip->invflags & XT_INV_PROTO)
|
||||
&& matchsize == XT_ALIGN(sizeof(struct xt_dccp_info))
|
||||
&& !(info->flags & ~XT_DCCP_VALID_FLAGS)
|
||||
&& !(info->invflags & ~XT_DCCP_VALID_FLAGS)
|
||||
&& !(info->invflags & ~info->flags);
|
||||
}
|
||||
|
||||
static struct ipt_match dccp_match =
|
||||
static int
|
||||
checkentry6(const char *tablename,
|
||||
const void *inf,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
const struct ip6t_ip6 *ip = inf;
|
||||
const struct xt_dccp_info *info;
|
||||
|
||||
info = (const struct xt_dccp_info *)matchinfo;
|
||||
|
||||
return ip->proto == IPPROTO_DCCP
|
||||
&& !(ip->invflags & XT_INV_PROTO)
|
||||
&& matchsize == XT_ALIGN(sizeof(struct xt_dccp_info))
|
||||
&& !(info->flags & ~XT_DCCP_VALID_FLAGS)
|
||||
&& !(info->invflags & ~XT_DCCP_VALID_FLAGS)
|
||||
&& !(info->invflags & ~info->flags);
|
||||
}
|
||||
|
||||
|
||||
static struct xt_match dccp_match =
|
||||
{
|
||||
.name = "dccp",
|
||||
.match = &match,
|
||||
.checkentry = &checkentry,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
static struct xt_match dccp6_match =
|
||||
{
|
||||
.name = "dccp",
|
||||
.match = &match,
|
||||
.checkentry = &checkentry6,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
@@ -154,23 +193,29 @@ static int __init init(void)
|
||||
dccp_optbuf = kmalloc(256 * 4, GFP_KERNEL);
|
||||
if (!dccp_optbuf)
|
||||
return -ENOMEM;
|
||||
ret = ipt_register_match(&dccp_match);
|
||||
ret = xt_register_match(AF_INET, &dccp_match);
|
||||
if (ret)
|
||||
kfree(dccp_optbuf);
|
||||
goto out_kfree;
|
||||
ret = xt_register_match(AF_INET6, &dccp6_match);
|
||||
if (ret)
|
||||
goto out_unreg;
|
||||
|
||||
return ret;
|
||||
|
||||
out_unreg:
|
||||
xt_unregister_match(AF_INET, &dccp_match);
|
||||
out_kfree:
|
||||
kfree(dccp_optbuf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit fini(void)
|
||||
{
|
||||
ipt_unregister_match(&dccp_match);
|
||||
xt_unregister_match(AF_INET6, &dccp6_match);
|
||||
xt_unregister_match(AF_INET, &dccp_match);
|
||||
kfree(dccp_optbuf);
|
||||
}
|
||||
|
||||
module_init(init);
|
||||
module_exit(fini);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
|
||||
MODULE_DESCRIPTION("Match for DCCP protocol packets");
|
||||
|
@@ -13,7 +13,6 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/interrupt.h>
|
||||
#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)
|
||||
#include <linux/netfilter_ipv4/ip_conntrack.h>
|
||||
#include <linux/netfilter_ipv4/ip_conntrack_core.h>
|
||||
@@ -23,12 +22,14 @@
|
||||
#include <net/netfilter/nf_conntrack_core.h>
|
||||
#include <net/netfilter/nf_conntrack_helper.h>
|
||||
#endif
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
#include <linux/netfilter_ipv4/ipt_helper.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include <linux/netfilter/xt_helper.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Martin Josefsson <gandalf@netfilter.org>");
|
||||
MODULE_DESCRIPTION("iptables helper match module");
|
||||
MODULE_ALIAS("ipt_helper");
|
||||
MODULE_ALIAS("ip6t_helper");
|
||||
|
||||
#if 0
|
||||
#define DEBUGP printk
|
||||
@@ -43,27 +44,28 @@ match(const struct sk_buff *skb,
|
||||
const struct net_device *out,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
const struct ipt_helper_info *info = matchinfo;
|
||||
const struct xt_helper_info *info = matchinfo;
|
||||
struct ip_conntrack *ct;
|
||||
enum ip_conntrack_info ctinfo;
|
||||
int ret = info->invert;
|
||||
|
||||
ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
|
||||
if (!ct) {
|
||||
DEBUGP("ipt_helper: Eek! invalid conntrack?\n");
|
||||
DEBUGP("xt_helper: Eek! invalid conntrack?\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!ct->master) {
|
||||
DEBUGP("ipt_helper: conntrack %p has no master\n", ct);
|
||||
DEBUGP("xt_helper: conntrack %p has no master\n", ct);
|
||||
return ret;
|
||||
}
|
||||
|
||||
read_lock_bh(&ip_conntrack_lock);
|
||||
if (!ct->master->helper) {
|
||||
DEBUGP("ipt_helper: master ct %p has no helper\n",
|
||||
DEBUGP("xt_helper: master ct %p has no helper\n",
|
||||
exp->expectant);
|
||||
goto out_unlock;
|
||||
}
|
||||
@@ -89,27 +91,28 @@ match(const struct sk_buff *skb,
|
||||
const struct net_device *out,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
const struct ipt_helper_info *info = matchinfo;
|
||||
const struct xt_helper_info *info = matchinfo;
|
||||
struct nf_conn *ct;
|
||||
enum ip_conntrack_info ctinfo;
|
||||
int ret = info->invert;
|
||||
|
||||
ct = nf_ct_get((struct sk_buff *)skb, &ctinfo);
|
||||
if (!ct) {
|
||||
DEBUGP("ipt_helper: Eek! invalid conntrack?\n");
|
||||
DEBUGP("xt_helper: Eek! invalid conntrack?\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!ct->master) {
|
||||
DEBUGP("ipt_helper: conntrack %p has no master\n", ct);
|
||||
DEBUGP("xt_helper: conntrack %p has no master\n", ct);
|
||||
return ret;
|
||||
}
|
||||
|
||||
read_lock_bh(&nf_conntrack_lock);
|
||||
if (!ct->master->helper) {
|
||||
DEBUGP("ipt_helper: master ct %p has no helper\n",
|
||||
DEBUGP("xt_helper: master ct %p has no helper\n",
|
||||
exp->expectant);
|
||||
goto out_unlock;
|
||||
}
|
||||
@@ -129,23 +132,29 @@ out_unlock:
|
||||
#endif
|
||||
|
||||
static int check(const char *tablename,
|
||||
const struct ipt_ip *ip,
|
||||
const void *inf,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
struct ipt_helper_info *info = matchinfo;
|
||||
struct xt_helper_info *info = matchinfo;
|
||||
|
||||
info->name[29] = '\0';
|
||||
|
||||
/* verify size */
|
||||
if (matchsize != IPT_ALIGN(sizeof(struct ipt_helper_info)))
|
||||
if (matchsize != XT_ALIGN(sizeof(struct xt_helper_info)))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct ipt_match helper_match = {
|
||||
static struct xt_match helper_match = {
|
||||
.name = "helper",
|
||||
.match = &match,
|
||||
.checkentry = &check,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
static struct xt_match helper6_match = {
|
||||
.name = "helper",
|
||||
.match = &match,
|
||||
.checkentry = &check,
|
||||
@@ -154,13 +163,24 @@ static struct ipt_match helper_match = {
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
need_ip_conntrack();
|
||||
return ipt_register_match(&helper_match);
|
||||
int ret;
|
||||
need_conntrack();
|
||||
|
||||
ret = xt_register_match(AF_INET, &helper_match);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = xt_register_match(AF_INET6, &helper6_match);
|
||||
if (ret < 0)
|
||||
xt_unregister_match(AF_INET, &helper_match);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit fini(void)
|
||||
{
|
||||
ipt_unregister_match(&helper_match);
|
||||
xt_unregister_match(AF_INET, &helper_match);
|
||||
xt_unregister_match(AF_INET6, &helper6_match);
|
||||
}
|
||||
|
||||
module_init(init);
|
98
net/netfilter/xt_length.c
Normal file
98
net/netfilter/xt_length.c
Normal file
@@ -0,0 +1,98 @@
|
||||
/* Kernel module to match packet length. */
|
||||
/* (C) 1999-2001 James Morris <jmorros@intercode.com.au>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <net/ip.h>
|
||||
|
||||
#include <linux/netfilter/xt_length.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
|
||||
MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>");
|
||||
MODULE_DESCRIPTION("IP tables packet length matching module");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ipt_length");
|
||||
MODULE_ALIAS("ip6t_length");
|
||||
|
||||
static int
|
||||
match(const struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
const struct xt_length_info *info = matchinfo;
|
||||
u_int16_t pktlen = ntohs(skb->nh.iph->tot_len);
|
||||
|
||||
return (pktlen >= info->min && pktlen <= info->max) ^ info->invert;
|
||||
}
|
||||
|
||||
static int
|
||||
match6(const struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
const struct xt_length_info *info = matchinfo;
|
||||
u_int16_t pktlen = ntohs(skb->nh.ipv6h->payload_len) + sizeof(struct ipv6hdr);
|
||||
|
||||
return (pktlen >= info->min && pktlen <= info->max) ^ info->invert;
|
||||
}
|
||||
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const void *ip,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
if (matchsize != XT_ALIGN(sizeof(struct xt_length_info)))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct xt_match length_match = {
|
||||
.name = "length",
|
||||
.match = &match,
|
||||
.checkentry = &checkentry,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
static struct xt_match length6_match = {
|
||||
.name = "length",
|
||||
.match = &match6,
|
||||
.checkentry = &checkentry,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
int ret;
|
||||
ret = xt_register_match(AF_INET, &length_match);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = xt_register_match(AF_INET6, &length6_match);
|
||||
if (ret)
|
||||
xt_unregister_match(AF_INET, &length_match);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit fini(void)
|
||||
{
|
||||
xt_unregister_match(AF_INET, &length_match);
|
||||
xt_unregister_match(AF_INET6, &length6_match);
|
||||
}
|
||||
|
||||
module_init(init);
|
||||
module_exit(fini);
|
@@ -18,12 +18,14 @@
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
#include <linux/netfilter_ipv4/ipt_limit.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include <linux/netfilter/xt_limit.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Herve Eychenne <rv@wallfire.org>");
|
||||
MODULE_DESCRIPTION("iptables rate limit match");
|
||||
MODULE_ALIAS("ipt_limit");
|
||||
MODULE_ALIAS("ip6t_limit");
|
||||
|
||||
/* The algorithm used is the Simple Token Bucket Filter (TBF)
|
||||
* see net/sched/sch_tbf.c in the linux source tree
|
||||
@@ -68,9 +70,10 @@ ipt_limit_match(const struct sk_buff *skb,
|
||||
const struct net_device *out,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
struct ipt_rateinfo *r = ((struct ipt_rateinfo *)matchinfo)->master;
|
||||
struct xt_rateinfo *r = ((struct xt_rateinfo *)matchinfo)->master;
|
||||
unsigned long now = jiffies;
|
||||
|
||||
spin_lock_bh(&limit_lock);
|
||||
@@ -96,32 +99,32 @@ user2credits(u_int32_t user)
|
||||
/* If multiplying would overflow... */
|
||||
if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY))
|
||||
/* Divide first. */
|
||||
return (user / IPT_LIMIT_SCALE) * HZ * CREDITS_PER_JIFFY;
|
||||
return (user / XT_LIMIT_SCALE) * HZ * CREDITS_PER_JIFFY;
|
||||
|
||||
return (user * HZ * CREDITS_PER_JIFFY) / IPT_LIMIT_SCALE;
|
||||
return (user * HZ * CREDITS_PER_JIFFY) / XT_LIMIT_SCALE;
|
||||
}
|
||||
|
||||
static int
|
||||
ipt_limit_checkentry(const char *tablename,
|
||||
const struct ipt_ip *ip,
|
||||
const void *inf,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
struct ipt_rateinfo *r = matchinfo;
|
||||
struct xt_rateinfo *r = matchinfo;
|
||||
|
||||
if (matchsize != IPT_ALIGN(sizeof(struct ipt_rateinfo)))
|
||||
if (matchsize != XT_ALIGN(sizeof(struct xt_rateinfo)))
|
||||
return 0;
|
||||
|
||||
/* Check for overflow. */
|
||||
if (r->burst == 0
|
||||
|| user2credits(r->avg * r->burst) < user2credits(r->avg)) {
|
||||
printk("Overflow in ipt_limit, try lower: %u/%u\n",
|
||||
printk("Overflow in xt_limit, try lower: %u/%u\n",
|
||||
r->avg, r->burst);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* User avg in seconds * IPT_LIMIT_SCALE: convert to jiffies *
|
||||
/* User avg in seconds * XT_LIMIT_SCALE: convert to jiffies *
|
||||
128. */
|
||||
r->prev = jiffies;
|
||||
r->credit = user2credits(r->avg * r->burst); /* Credits full. */
|
||||
@@ -134,7 +137,13 @@ ipt_limit_checkentry(const char *tablename,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct ipt_match ipt_limit_reg = {
|
||||
static struct xt_match ipt_limit_reg = {
|
||||
.name = "limit",
|
||||
.match = ipt_limit_match,
|
||||
.checkentry = ipt_limit_checkentry,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
static struct xt_match limit6_reg = {
|
||||
.name = "limit",
|
||||
.match = ipt_limit_match,
|
||||
.checkentry = ipt_limit_checkentry,
|
||||
@@ -143,14 +152,23 @@ static struct ipt_match ipt_limit_reg = {
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
if (ipt_register_match(&ipt_limit_reg))
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
int ret;
|
||||
|
||||
ret = xt_register_match(AF_INET, &ipt_limit_reg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = xt_register_match(AF_INET6, &limit6_reg);
|
||||
if (ret)
|
||||
xt_unregister_match(AF_INET, &ipt_limit_reg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit fini(void)
|
||||
{
|
||||
ipt_unregister_match(&ipt_limit_reg);
|
||||
xt_unregister_match(AF_INET, &ipt_limit_reg);
|
||||
xt_unregister_match(AF_INET6, &limit6_reg);
|
||||
}
|
||||
|
||||
module_init(init);
|
@@ -13,12 +13,15 @@
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/etherdevice.h>
|
||||
|
||||
#include <linux/netfilter_ipv4/ipt_mac.h>
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
#include <linux/netfilter_ipv4.h>
|
||||
#include <linux/netfilter/xt_mac.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
|
||||
MODULE_DESCRIPTION("iptables mac matching module");
|
||||
MODULE_ALIAS("ipt_mac");
|
||||
MODULE_ALIAS("ip6t_mac");
|
||||
|
||||
static int
|
||||
match(const struct sk_buff *skb,
|
||||
@@ -26,9 +29,10 @@ match(const struct sk_buff *skb,
|
||||
const struct net_device *out,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
const struct ipt_mac_info *info = matchinfo;
|
||||
const struct xt_mac_info *info = matchinfo;
|
||||
|
||||
/* Is mac pointer valid? */
|
||||
return (skb->mac.raw >= skb->head
|
||||
@@ -40,7 +44,7 @@ match(const struct sk_buff *skb,
|
||||
|
||||
static int
|
||||
ipt_mac_checkentry(const char *tablename,
|
||||
const struct ipt_ip *ip,
|
||||
const void *inf,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
@@ -49,17 +53,23 @@ ipt_mac_checkentry(const char *tablename,
|
||||
if (hook_mask
|
||||
& ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN)
|
||||
| (1 << NF_IP_FORWARD))) {
|
||||
printk("ipt_mac: only valid for PRE_ROUTING, LOCAL_IN or FORWARD.\n");
|
||||
printk("xt_mac: only valid for PRE_ROUTING, LOCAL_IN or FORWARD.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (matchsize != IPT_ALIGN(sizeof(struct ipt_mac_info)))
|
||||
if (matchsize != XT_ALIGN(sizeof(struct xt_mac_info)))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct ipt_match mac_match = {
|
||||
static struct xt_match mac_match = {
|
||||
.name = "mac",
|
||||
.match = &match,
|
||||
.checkentry = &ipt_mac_checkentry,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
static struct xt_match mac6_match = {
|
||||
.name = "mac",
|
||||
.match = &match,
|
||||
.checkentry = &ipt_mac_checkentry,
|
||||
@@ -68,12 +78,22 @@ static struct ipt_match mac_match = {
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
return ipt_register_match(&mac_match);
|
||||
int ret;
|
||||
ret = xt_register_match(AF_INET, &mac_match);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = xt_register_match(AF_INET6, &mac6_match);
|
||||
if (ret)
|
||||
xt_unregister_match(AF_INET, &mac_match);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit fini(void)
|
||||
{
|
||||
ipt_unregister_match(&mac_match);
|
||||
xt_unregister_match(AF_INET, &mac_match);
|
||||
xt_unregister_match(AF_INET6, &mac6_match);
|
||||
}
|
||||
|
||||
module_init(init);
|
@@ -10,12 +10,14 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
|
||||
#include <linux/netfilter_ipv4/ipt_mark.h>
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
#include <linux/netfilter/xt_mark.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
|
||||
MODULE_DESCRIPTION("iptables mark matching module");
|
||||
MODULE_ALIAS("ipt_mark");
|
||||
MODULE_ALIAS("ip6t_mark");
|
||||
|
||||
static int
|
||||
match(const struct sk_buff *skb,
|
||||
@@ -23,23 +25,24 @@ match(const struct sk_buff *skb,
|
||||
const struct net_device *out,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
const struct ipt_mark_info *info = matchinfo;
|
||||
const struct xt_mark_info *info = matchinfo;
|
||||
|
||||
return ((skb->nfmark & info->mask) == info->mark) ^ info->invert;
|
||||
}
|
||||
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const struct ipt_ip *ip,
|
||||
const void *entry,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
struct ipt_mark_info *minfo = (struct ipt_mark_info *) matchinfo;
|
||||
struct xt_mark_info *minfo = (struct xt_mark_info *) matchinfo;
|
||||
|
||||
if (matchsize != IPT_ALIGN(sizeof(struct ipt_mark_info)))
|
||||
if (matchsize != XT_ALIGN(sizeof(struct xt_mark_info)))
|
||||
return 0;
|
||||
|
||||
if (minfo->mark > 0xffffffff || minfo->mask > 0xffffffff) {
|
||||
@@ -50,7 +53,14 @@ checkentry(const char *tablename,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct ipt_match mark_match = {
|
||||
static struct xt_match mark_match = {
|
||||
.name = "mark",
|
||||
.match = &match,
|
||||
.checkentry = &checkentry,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static struct xt_match mark6_match = {
|
||||
.name = "mark",
|
||||
.match = &match,
|
||||
.checkentry = &checkentry,
|
||||
@@ -59,12 +69,22 @@ static struct ipt_match mark_match = {
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
return ipt_register_match(&mark_match);
|
||||
int ret;
|
||||
ret = xt_register_match(AF_INET, &mark_match);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = xt_register_match(AF_INET6, &mark6_match);
|
||||
if (ret)
|
||||
xt_unregister_match(AF_INET, &mark_match);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit fini(void)
|
||||
{
|
||||
ipt_unregister_match(&mark_match);
|
||||
xt_unregister_match(AF_INET, &mark_match);
|
||||
xt_unregister_match(AF_INET6, &mark6_match);
|
||||
}
|
||||
|
||||
module_init(init);
|
@@ -10,8 +10,8 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/netfilter_ipv6/ip6t_physdev.h>
|
||||
#include <linux/netfilter_ipv6/ip6_tables.h>
|
||||
#include <linux/netfilter/xt_physdev.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include <linux/netfilter_bridge.h>
|
||||
#define MATCH 1
|
||||
#define NOMATCH 0
|
||||
@@ -19,6 +19,8 @@
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>");
|
||||
MODULE_DESCRIPTION("iptables bridge physical device match module");
|
||||
MODULE_ALIAS("ipt_physdev");
|
||||
MODULE_ALIAS("ip6t_physdev");
|
||||
|
||||
static int
|
||||
match(const struct sk_buff *skb,
|
||||
@@ -31,7 +33,7 @@ match(const struct sk_buff *skb,
|
||||
{
|
||||
int i;
|
||||
static const char nulldevname[IFNAMSIZ];
|
||||
const struct ip6t_physdev_info *info = matchinfo;
|
||||
const struct xt_physdev_info *info = matchinfo;
|
||||
unsigned int ret;
|
||||
const char *indev, *outdev;
|
||||
struct nf_bridge_info *nf_bridge;
|
||||
@@ -41,37 +43,37 @@ match(const struct sk_buff *skb,
|
||||
* the destination device will be a bridge. */
|
||||
if (!(nf_bridge = skb->nf_bridge)) {
|
||||
/* Return MATCH if the invert flags of the used options are on */
|
||||
if ((info->bitmask & IP6T_PHYSDEV_OP_BRIDGED) &&
|
||||
!(info->invert & IP6T_PHYSDEV_OP_BRIDGED))
|
||||
if ((info->bitmask & XT_PHYSDEV_OP_BRIDGED) &&
|
||||
!(info->invert & XT_PHYSDEV_OP_BRIDGED))
|
||||
return NOMATCH;
|
||||
if ((info->bitmask & IP6T_PHYSDEV_OP_ISIN) &&
|
||||
!(info->invert & IP6T_PHYSDEV_OP_ISIN))
|
||||
if ((info->bitmask & XT_PHYSDEV_OP_ISIN) &&
|
||||
!(info->invert & XT_PHYSDEV_OP_ISIN))
|
||||
return NOMATCH;
|
||||
if ((info->bitmask & IP6T_PHYSDEV_OP_ISOUT) &&
|
||||
!(info->invert & IP6T_PHYSDEV_OP_ISOUT))
|
||||
if ((info->bitmask & XT_PHYSDEV_OP_ISOUT) &&
|
||||
!(info->invert & XT_PHYSDEV_OP_ISOUT))
|
||||
return NOMATCH;
|
||||
if ((info->bitmask & IP6T_PHYSDEV_OP_IN) &&
|
||||
!(info->invert & IP6T_PHYSDEV_OP_IN))
|
||||
if ((info->bitmask & XT_PHYSDEV_OP_IN) &&
|
||||
!(info->invert & XT_PHYSDEV_OP_IN))
|
||||
return NOMATCH;
|
||||
if ((info->bitmask & IP6T_PHYSDEV_OP_OUT) &&
|
||||
!(info->invert & IP6T_PHYSDEV_OP_OUT))
|
||||
if ((info->bitmask & XT_PHYSDEV_OP_OUT) &&
|
||||
!(info->invert & XT_PHYSDEV_OP_OUT))
|
||||
return NOMATCH;
|
||||
return MATCH;
|
||||
}
|
||||
|
||||
/* This only makes sense in the FORWARD and POSTROUTING chains */
|
||||
if ((info->bitmask & IP6T_PHYSDEV_OP_BRIDGED) &&
|
||||
if ((info->bitmask & XT_PHYSDEV_OP_BRIDGED) &&
|
||||
(!!(nf_bridge->mask & BRNF_BRIDGED) ^
|
||||
!(info->invert & IP6T_PHYSDEV_OP_BRIDGED)))
|
||||
!(info->invert & XT_PHYSDEV_OP_BRIDGED)))
|
||||
return NOMATCH;
|
||||
|
||||
if ((info->bitmask & IP6T_PHYSDEV_OP_ISIN &&
|
||||
(!nf_bridge->physindev ^ !!(info->invert & IP6T_PHYSDEV_OP_ISIN))) ||
|
||||
(info->bitmask & IP6T_PHYSDEV_OP_ISOUT &&
|
||||
(!nf_bridge->physoutdev ^ !!(info->invert & IP6T_PHYSDEV_OP_ISOUT))))
|
||||
if ((info->bitmask & XT_PHYSDEV_OP_ISIN &&
|
||||
(!nf_bridge->physindev ^ !!(info->invert & XT_PHYSDEV_OP_ISIN))) ||
|
||||
(info->bitmask & XT_PHYSDEV_OP_ISOUT &&
|
||||
(!nf_bridge->physoutdev ^ !!(info->invert & XT_PHYSDEV_OP_ISOUT))))
|
||||
return NOMATCH;
|
||||
|
||||
if (!(info->bitmask & IP6T_PHYSDEV_OP_IN))
|
||||
if (!(info->bitmask & XT_PHYSDEV_OP_IN))
|
||||
goto match_outdev;
|
||||
indev = nf_bridge->physindev ? nf_bridge->physindev->name : nulldevname;
|
||||
for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) {
|
||||
@@ -80,11 +82,11 @@ match(const struct sk_buff *skb,
|
||||
& ((const unsigned int *)info->in_mask)[i];
|
||||
}
|
||||
|
||||
if ((ret == 0) ^ !(info->invert & IP6T_PHYSDEV_OP_IN))
|
||||
if ((ret == 0) ^ !(info->invert & XT_PHYSDEV_OP_IN))
|
||||
return NOMATCH;
|
||||
|
||||
match_outdev:
|
||||
if (!(info->bitmask & IP6T_PHYSDEV_OP_OUT))
|
||||
if (!(info->bitmask & XT_PHYSDEV_OP_OUT))
|
||||
return MATCH;
|
||||
outdev = nf_bridge->physoutdev ?
|
||||
nf_bridge->physoutdev->name : nulldevname;
|
||||
@@ -94,27 +96,34 @@ match_outdev:
|
||||
& ((const unsigned int *)info->out_mask)[i];
|
||||
}
|
||||
|
||||
return (ret != 0) ^ !(info->invert & IP6T_PHYSDEV_OP_OUT);
|
||||
return (ret != 0) ^ !(info->invert & XT_PHYSDEV_OP_OUT);
|
||||
}
|
||||
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const struct ip6t_ip6 *ip,
|
||||
const void *ip,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
const struct ip6t_physdev_info *info = matchinfo;
|
||||
const struct xt_physdev_info *info = matchinfo;
|
||||
|
||||
if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_physdev_info)))
|
||||
if (matchsize != XT_ALIGN(sizeof(struct xt_physdev_info)))
|
||||
return 0;
|
||||
if (!(info->bitmask & IP6T_PHYSDEV_OP_MASK) ||
|
||||
info->bitmask & ~IP6T_PHYSDEV_OP_MASK)
|
||||
if (!(info->bitmask & XT_PHYSDEV_OP_MASK) ||
|
||||
info->bitmask & ~XT_PHYSDEV_OP_MASK)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct ip6t_match physdev_match = {
|
||||
static struct xt_match physdev_match = {
|
||||
.name = "physdev",
|
||||
.match = &match,
|
||||
.checkentry = &checkentry,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static struct xt_match physdev6_match = {
|
||||
.name = "physdev",
|
||||
.match = &match,
|
||||
.checkentry = &checkentry,
|
||||
@@ -123,12 +132,23 @@ static struct ip6t_match physdev_match = {
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
return ip6t_register_match(&physdev_match);
|
||||
int ret;
|
||||
|
||||
ret = xt_register_match(AF_INET, &physdev_match);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = xt_register_match(AF_INET6, &physdev6_match);
|
||||
if (ret < 0)
|
||||
xt_unregister_match(AF_INET, &physdev_match);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit fini(void)
|
||||
{
|
||||
ip6t_unregister_match(&physdev_match);
|
||||
xt_unregister_match(AF_INET, &physdev_match);
|
||||
xt_unregister_match(AF_INET6, &physdev6_match);
|
||||
}
|
||||
|
||||
module_init(init);
|
@@ -10,60 +10,72 @@
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/if_packet.h>
|
||||
|
||||
#include <linux/netfilter_ipv4/ipt_pkttype.h>
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
#include <linux/netfilter/xt_pkttype.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Michal Ludvig <michal@logix.cz>");
|
||||
MODULE_DESCRIPTION("IP tables match to match on linklayer packet type");
|
||||
MODULE_ALIAS("ipt_pkttype");
|
||||
MODULE_ALIAS("ip6t_pkttype");
|
||||
|
||||
static int match(const struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
const struct ipt_pkttype_info *info = matchinfo;
|
||||
const struct xt_pkttype_info *info = matchinfo;
|
||||
|
||||
return (skb->pkt_type == info->pkttype) ^ info->invert;
|
||||
return (skb->pkt_type == info->pkttype) ^ info->invert;
|
||||
}
|
||||
|
||||
static int checkentry(const char *tablename,
|
||||
const struct ipt_ip *ip,
|
||||
const void *ip,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
/*
|
||||
if (hook_mask
|
||||
& ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN)
|
||||
| (1 << NF_IP_FORWARD))) {
|
||||
printk("ipt_pkttype: only valid for PRE_ROUTING, LOCAL_IN or FORWARD.\n");
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
if (matchsize != IPT_ALIGN(sizeof(struct ipt_pkttype_info)))
|
||||
if (matchsize != XT_ALIGN(sizeof(struct xt_pkttype_info)))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct ipt_match pkttype_match = {
|
||||
static struct xt_match pkttype_match = {
|
||||
.name = "pkttype",
|
||||
.match = &match,
|
||||
.checkentry = &checkentry,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
static struct xt_match pkttype6_match = {
|
||||
.name = "pkttype",
|
||||
.match = &match,
|
||||
.checkentry = &checkentry,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
return ipt_register_match(&pkttype_match);
|
||||
int ret;
|
||||
ret = xt_register_match(AF_INET, &pkttype_match);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = xt_register_match(AF_INET6, &pkttype6_match);
|
||||
if (ret)
|
||||
xt_unregister_match(AF_INET, &pkttype_match);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit fini(void)
|
||||
{
|
||||
ipt_unregister_match(&pkttype_match);
|
||||
xt_unregister_match(AF_INET, &pkttype_match);
|
||||
xt_unregister_match(AF_INET6, &pkttype6_match);
|
||||
}
|
||||
|
||||
module_init(init);
|
@@ -14,12 +14,14 @@
|
||||
#include <linux/netdevice.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#include <linux/netfilter_ipv4/ipt_realm.h>
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
#include <linux/netfilter_ipv4.h>
|
||||
#include <linux/netfilter/xt_realm.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
|
||||
MODULE_AUTHOR("Sampsa Ranta <sampsa@netsonic.fi>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("iptables realm match");
|
||||
MODULE_DESCRIPTION("X_tables realm match");
|
||||
MODULE_ALIAS("ipt_realm");
|
||||
|
||||
static int
|
||||
match(const struct sk_buff *skb,
|
||||
@@ -27,16 +29,17 @@ match(const struct sk_buff *skb,
|
||||
const struct net_device *out,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
const struct ipt_realm_info *info = matchinfo;
|
||||
const struct xt_realm_info *info = matchinfo;
|
||||
struct dst_entry *dst = skb->dst;
|
||||
|
||||
return (info->id == (dst->tclassid & info->mask)) ^ info->invert;
|
||||
}
|
||||
|
||||
static int check(const char *tablename,
|
||||
const struct ipt_ip *ip,
|
||||
const void *ip,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
@@ -44,18 +47,18 @@ static int check(const char *tablename,
|
||||
if (hook_mask
|
||||
& ~((1 << NF_IP_POST_ROUTING) | (1 << NF_IP_FORWARD) |
|
||||
(1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_LOCAL_IN))) {
|
||||
printk("ipt_realm: only valid for POST_ROUTING, LOCAL_OUT, "
|
||||
printk("xt_realm: only valid for POST_ROUTING, LOCAL_OUT, "
|
||||
"LOCAL_IN or FORWARD.\n");
|
||||
return 0;
|
||||
}
|
||||
if (matchsize != IPT_ALIGN(sizeof(struct ipt_realm_info))) {
|
||||
printk("ipt_realm: invalid matchsize.\n");
|
||||
if (matchsize != XT_ALIGN(sizeof(struct xt_realm_info))) {
|
||||
printk("xt_realm: invalid matchsize.\n");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct ipt_match realm_match = {
|
||||
static struct xt_match realm_match = {
|
||||
.name = "realm",
|
||||
.match = match,
|
||||
.checkentry = check,
|
||||
@@ -64,12 +67,12 @@ static struct ipt_match realm_match = {
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
return ipt_register_match(&realm_match);
|
||||
return xt_register_match(AF_INET, &realm_match);
|
||||
}
|
||||
|
||||
static void __exit fini(void)
|
||||
{
|
||||
ipt_unregister_match(&realm_match);
|
||||
xt_unregister_match(AF_INET, &realm_match);
|
||||
}
|
||||
|
||||
module_init(init);
|
@@ -1,10 +1,18 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <net/ip.h>
|
||||
#include <net/ipv6.h>
|
||||
#include <linux/sctp.h>
|
||||
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include <linux/netfilter/xt_sctp.h>
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
#include <linux/netfilter_ipv4/ipt_sctp.h>
|
||||
#include <linux/netfilter_ipv6/ip6_tables.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Kiran Kumar Immidi");
|
||||
MODULE_DESCRIPTION("Match for SCTP protocol packets");
|
||||
MODULE_ALIAS("ipt_sctp");
|
||||
|
||||
#ifdef DEBUG_SCTP
|
||||
#define duprintf(format, args...) printk(format , ## args)
|
||||
@@ -16,7 +24,7 @@
|
||||
|| (!!((invflag) & (option)) ^ (cond)))
|
||||
|
||||
static int
|
||||
match_flags(const struct ipt_sctp_flag_info *flag_info,
|
||||
match_flags(const struct xt_sctp_flag_info *flag_info,
|
||||
const int flag_count,
|
||||
u_int8_t chunktype,
|
||||
u_int8_t chunkflags)
|
||||
@@ -32,15 +40,15 @@ match_flags(const struct ipt_sctp_flag_info *flag_info,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
static inline int
|
||||
match_packet(const struct sk_buff *skb,
|
||||
unsigned int offset,
|
||||
const u_int32_t *chunkmap,
|
||||
int chunk_match_type,
|
||||
const struct ipt_sctp_flag_info *flag_info,
|
||||
const struct xt_sctp_flag_info *flag_info,
|
||||
const int flag_count,
|
||||
int *hotdrop)
|
||||
{
|
||||
int offset;
|
||||
u_int32_t chunkmapcopy[256 / sizeof (u_int32_t)];
|
||||
sctp_chunkhdr_t _sch, *sch;
|
||||
|
||||
@@ -52,7 +60,6 @@ match_packet(const struct sk_buff *skb,
|
||||
SCTP_CHUNKMAP_COPY(chunkmapcopy, chunkmap);
|
||||
}
|
||||
|
||||
offset = skb->nh.iph->ihl * 4 + sizeof (sctp_sctphdr_t);
|
||||
do {
|
||||
sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch);
|
||||
if (sch == NULL) {
|
||||
@@ -118,19 +125,20 @@ match(const struct sk_buff *skb,
|
||||
const struct net_device *out,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
const struct ipt_sctp_info *info;
|
||||
const struct xt_sctp_info *info;
|
||||
sctp_sctphdr_t _sh, *sh;
|
||||
|
||||
info = (const struct ipt_sctp_info *)matchinfo;
|
||||
info = (const struct xt_sctp_info *)matchinfo;
|
||||
|
||||
if (offset) {
|
||||
duprintf("Dropping non-first fragment.. FIXME\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
sh = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_sh), &_sh);
|
||||
sh = skb_header_pointer(skb, protoff, sizeof(_sh), &_sh);
|
||||
if (sh == NULL) {
|
||||
duprintf("Dropping evil TCP offset=0 tinygram.\n");
|
||||
*hotdrop = 1;
|
||||
@@ -140,64 +148,103 @@ match(const struct sk_buff *skb,
|
||||
|
||||
return SCCHECK(((ntohs(sh->source) >= info->spts[0])
|
||||
&& (ntohs(sh->source) <= info->spts[1])),
|
||||
IPT_SCTP_SRC_PORTS, info->flags, info->invflags)
|
||||
XT_SCTP_SRC_PORTS, info->flags, info->invflags)
|
||||
&& SCCHECK(((ntohs(sh->dest) >= info->dpts[0])
|
||||
&& (ntohs(sh->dest) <= info->dpts[1])),
|
||||
IPT_SCTP_DEST_PORTS, info->flags, info->invflags)
|
||||
&& SCCHECK(match_packet(skb, info->chunkmap, info->chunk_match_type,
|
||||
XT_SCTP_DEST_PORTS, info->flags, info->invflags)
|
||||
&& SCCHECK(match_packet(skb, protoff,
|
||||
info->chunkmap, info->chunk_match_type,
|
||||
info->flag_info, info->flag_count,
|
||||
hotdrop),
|
||||
IPT_SCTP_CHUNK_TYPES, info->flags, info->invflags);
|
||||
XT_SCTP_CHUNK_TYPES, info->flags, info->invflags);
|
||||
}
|
||||
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const struct ipt_ip *ip,
|
||||
const void *inf,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
const struct ipt_sctp_info *info;
|
||||
const struct xt_sctp_info *info;
|
||||
const struct ipt_ip *ip = inf;
|
||||
|
||||
info = (const struct ipt_sctp_info *)matchinfo;
|
||||
info = (const struct xt_sctp_info *)matchinfo;
|
||||
|
||||
return ip->proto == IPPROTO_SCTP
|
||||
&& !(ip->invflags & IPT_INV_PROTO)
|
||||
&& matchsize == IPT_ALIGN(sizeof(struct ipt_sctp_info))
|
||||
&& !(info->flags & ~IPT_SCTP_VALID_FLAGS)
|
||||
&& !(info->invflags & ~IPT_SCTP_VALID_FLAGS)
|
||||
&& !(ip->invflags & XT_INV_PROTO)
|
||||
&& matchsize == XT_ALIGN(sizeof(struct xt_sctp_info))
|
||||
&& !(info->flags & ~XT_SCTP_VALID_FLAGS)
|
||||
&& !(info->invflags & ~XT_SCTP_VALID_FLAGS)
|
||||
&& !(info->invflags & ~info->flags)
|
||||
&& ((!(info->flags & IPT_SCTP_CHUNK_TYPES)) ||
|
||||
&& ((!(info->flags & XT_SCTP_CHUNK_TYPES)) ||
|
||||
(info->chunk_match_type &
|
||||
(SCTP_CHUNK_MATCH_ALL
|
||||
| SCTP_CHUNK_MATCH_ANY
|
||||
| SCTP_CHUNK_MATCH_ONLY)));
|
||||
}
|
||||
|
||||
static struct ipt_match sctp_match =
|
||||
static int
|
||||
checkentry6(const char *tablename,
|
||||
const void *inf,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
const struct xt_sctp_info *info;
|
||||
const struct ip6t_ip6 *ip = inf;
|
||||
|
||||
info = (const struct xt_sctp_info *)matchinfo;
|
||||
|
||||
return ip->proto == IPPROTO_SCTP
|
||||
&& !(ip->invflags & XT_INV_PROTO)
|
||||
&& matchsize == XT_ALIGN(sizeof(struct xt_sctp_info))
|
||||
&& !(info->flags & ~XT_SCTP_VALID_FLAGS)
|
||||
&& !(info->invflags & ~XT_SCTP_VALID_FLAGS)
|
||||
&& !(info->invflags & ~info->flags)
|
||||
&& ((!(info->flags & XT_SCTP_CHUNK_TYPES)) ||
|
||||
(info->chunk_match_type &
|
||||
(SCTP_CHUNK_MATCH_ALL
|
||||
| SCTP_CHUNK_MATCH_ANY
|
||||
| SCTP_CHUNK_MATCH_ONLY)));
|
||||
}
|
||||
|
||||
|
||||
static struct xt_match sctp_match =
|
||||
{
|
||||
.list = { NULL, NULL},
|
||||
.name = "sctp",
|
||||
.match = &match,
|
||||
.checkentry = &checkentry,
|
||||
.destroy = NULL,
|
||||
.me = THIS_MODULE
|
||||
};
|
||||
static struct xt_match sctp6_match =
|
||||
{
|
||||
.name = "sctp",
|
||||
.match = &match,
|
||||
.checkentry = &checkentry6,
|
||||
.me = THIS_MODULE
|
||||
};
|
||||
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
return ipt_register_match(&sctp_match);
|
||||
int ret;
|
||||
ret = xt_register_match(AF_INET, &sctp_match);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = xt_register_match(AF_INET6, &sctp6_match);
|
||||
if (ret)
|
||||
xt_unregister_match(AF_INET, &sctp_match);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit fini(void)
|
||||
{
|
||||
ipt_unregister_match(&sctp_match);
|
||||
xt_unregister_match(AF_INET6, &sctp6_match);
|
||||
xt_unregister_match(AF_INET, &sctp_match);
|
||||
}
|
||||
|
||||
module_init(init);
|
||||
module_exit(fini);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Kiran Kumar Immidi");
|
||||
MODULE_DESCRIPTION("Match for SCTP protocol packets");
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/* Kernel module to match connection tracking information. */
|
||||
|
||||
/* (C) 1999-2001 Paul `Rusty' Russell
|
||||
* (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
|
||||
* (C) 2002-2005 Netfilter Core Team <coreteam@netfilter.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
@@ -11,12 +11,14 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <net/netfilter/nf_conntrack_compat.h>
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
#include <linux/netfilter_ipv4/ipt_state.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include <linux/netfilter/xt_state.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Rusty Russell <rusty@rustcorp.com.au>");
|
||||
MODULE_DESCRIPTION("iptables connection tracking state match module");
|
||||
MODULE_DESCRIPTION("ip[6]_tables connection tracking state match module");
|
||||
MODULE_ALIAS("ipt_state");
|
||||
MODULE_ALIAS("ip6t_state");
|
||||
|
||||
static int
|
||||
match(const struct sk_buff *skb,
|
||||
@@ -24,35 +26,43 @@ match(const struct sk_buff *skb,
|
||||
const struct net_device *out,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
const struct ipt_state_info *sinfo = matchinfo;
|
||||
const struct xt_state_info *sinfo = matchinfo;
|
||||
enum ip_conntrack_info ctinfo;
|
||||
unsigned int statebit;
|
||||
|
||||
if (nf_ct_is_untracked(skb))
|
||||
statebit = IPT_STATE_UNTRACKED;
|
||||
statebit = XT_STATE_UNTRACKED;
|
||||
else if (!nf_ct_get_ctinfo(skb, &ctinfo))
|
||||
statebit = IPT_STATE_INVALID;
|
||||
statebit = XT_STATE_INVALID;
|
||||
else
|
||||
statebit = IPT_STATE_BIT(ctinfo);
|
||||
statebit = XT_STATE_BIT(ctinfo);
|
||||
|
||||
return (sinfo->statemask & statebit);
|
||||
}
|
||||
|
||||
static int check(const char *tablename,
|
||||
const struct ipt_ip *ip,
|
||||
const void *ip,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
if (matchsize != IPT_ALIGN(sizeof(struct ipt_state_info)))
|
||||
if (matchsize != XT_ALIGN(sizeof(struct xt_state_info)))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct ipt_match state_match = {
|
||||
static struct xt_match state_match = {
|
||||
.name = "state",
|
||||
.match = &match,
|
||||
.checkentry = &check,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static struct xt_match state6_match = {
|
||||
.name = "state",
|
||||
.match = &match,
|
||||
.checkentry = &check,
|
||||
@@ -61,13 +71,25 @@ static struct ipt_match state_match = {
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
need_ip_conntrack();
|
||||
return ipt_register_match(&state_match);
|
||||
int ret;
|
||||
|
||||
need_conntrack();
|
||||
|
||||
ret = xt_register_match(AF_INET, &state_match);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = xt_register_match(AF_INET6, &state6_match);
|
||||
if (ret < 0)
|
||||
xt_unregister_match(AF_INET,&state_match);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit fini(void)
|
||||
{
|
||||
ipt_unregister_match(&state_match);
|
||||
xt_unregister_match(AF_INET, &state_match);
|
||||
xt_unregister_match(AF_INET6, &state6_match);
|
||||
}
|
||||
|
||||
module_init(init);
|
@@ -11,23 +11,26 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
#include <linux/netfilter_ipv4/ipt_string.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include <linux/netfilter/xt_string.h>
|
||||
#include <linux/textsearch.h>
|
||||
|
||||
MODULE_AUTHOR("Pablo Neira Ayuso <pablo@eurodev.net>");
|
||||
MODULE_DESCRIPTION("IP tables string match module");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ipt_string");
|
||||
MODULE_ALIAS("ip6t_string");
|
||||
|
||||
static int match(const struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
struct ts_state state;
|
||||
struct ipt_string_info *conf = (struct ipt_string_info *) matchinfo;
|
||||
struct xt_string_info *conf = (struct xt_string_info *) matchinfo;
|
||||
|
||||
memset(&state, 0, sizeof(struct ts_state));
|
||||
|
||||
@@ -36,18 +39,18 @@ static int match(const struct sk_buff *skb,
|
||||
!= UINT_MAX) && !conf->invert;
|
||||
}
|
||||
|
||||
#define STRING_TEXT_PRIV(m) ((struct ipt_string_info *) m)
|
||||
#define STRING_TEXT_PRIV(m) ((struct xt_string_info *) m)
|
||||
|
||||
static int checkentry(const char *tablename,
|
||||
const struct ipt_ip *ip,
|
||||
const void *ip,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
struct ipt_string_info *conf = matchinfo;
|
||||
struct xt_string_info *conf = matchinfo;
|
||||
struct ts_config *ts_conf;
|
||||
|
||||
if (matchsize != IPT_ALIGN(sizeof(struct ipt_string_info)))
|
||||
if (matchsize != XT_ALIGN(sizeof(struct xt_string_info)))
|
||||
return 0;
|
||||
|
||||
/* Damn, can't handle this case properly with iptables... */
|
||||
@@ -69,7 +72,14 @@ static void destroy(void *matchinfo, unsigned int matchsize)
|
||||
textsearch_destroy(STRING_TEXT_PRIV(matchinfo)->config);
|
||||
}
|
||||
|
||||
static struct ipt_match string_match = {
|
||||
static struct xt_match string_match = {
|
||||
.name = "string",
|
||||
.match = match,
|
||||
.checkentry = checkentry,
|
||||
.destroy = destroy,
|
||||
.me = THIS_MODULE
|
||||
};
|
||||
static struct xt_match string6_match = {
|
||||
.name = "string",
|
||||
.match = match,
|
||||
.checkentry = checkentry,
|
||||
@@ -79,12 +89,22 @@ static struct ipt_match string_match = {
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
return ipt_register_match(&string_match);
|
||||
int ret;
|
||||
|
||||
ret = xt_register_match(AF_INET, &string_match);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = xt_register_match(AF_INET6, &string6_match);
|
||||
if (ret)
|
||||
xt_unregister_match(AF_INET, &string_match);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit fini(void)
|
||||
{
|
||||
ipt_unregister_match(&string_match);
|
||||
xt_unregister_match(AF_INET, &string_match);
|
||||
xt_unregister_match(AF_INET6, &string6_match);
|
||||
}
|
||||
|
||||
module_init(init);
|
@@ -1,6 +1,7 @@
|
||||
/* Kernel module to match TCP MSS values. */
|
||||
|
||||
/* Copyright (C) 2000 Marc Boucher <marc@mbsi.ca>
|
||||
* Portions (C) 2005 by Harald Welte <laforge@netfilter.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
@@ -11,19 +12,24 @@
|
||||
#include <linux/skbuff.h>
|
||||
#include <net/tcp.h>
|
||||
|
||||
#include <linux/netfilter_ipv4/ipt_tcpmss.h>
|
||||
#include <linux/netfilter/xt_tcpmss.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
#include <linux/netfilter_ipv6/ip6_tables.h>
|
||||
|
||||
#define TH_SYN 0x02
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
|
||||
MODULE_DESCRIPTION("iptables TCP MSS match module");
|
||||
MODULE_ALIAS("ipt_tcpmss");
|
||||
|
||||
/* Returns 1 if the mss option is set and matched by the range, 0 otherwise */
|
||||
static inline int
|
||||
mssoption_match(u_int16_t min, u_int16_t max,
|
||||
const struct sk_buff *skb,
|
||||
unsigned int protoff,
|
||||
int invert,
|
||||
int *hotdrop)
|
||||
{
|
||||
@@ -33,8 +39,7 @@ mssoption_match(u_int16_t min, u_int16_t max,
|
||||
unsigned int i, optlen;
|
||||
|
||||
/* If we don't have the whole header, drop packet. */
|
||||
th = skb_header_pointer(skb, skb->nh.iph->ihl * 4,
|
||||
sizeof(_tcph), &_tcph);
|
||||
th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph);
|
||||
if (th == NULL)
|
||||
goto dropit;
|
||||
|
||||
@@ -47,8 +52,7 @@ mssoption_match(u_int16_t min, u_int16_t max,
|
||||
goto out;
|
||||
|
||||
/* Truncated options. */
|
||||
op = skb_header_pointer(skb, skb->nh.iph->ihl * 4 + sizeof(*th),
|
||||
optlen, _opt);
|
||||
op = skb_header_pointer(skb, protoff + sizeof(*th), optlen, _opt);
|
||||
if (op == NULL)
|
||||
goto dropit;
|
||||
|
||||
@@ -79,22 +83,24 @@ match(const struct sk_buff *skb,
|
||||
const struct net_device *out,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
const struct ipt_tcpmss_match_info *info = matchinfo;
|
||||
const struct xt_tcpmss_match_info *info = matchinfo;
|
||||
|
||||
return mssoption_match(info->mss_min, info->mss_max, skb,
|
||||
return mssoption_match(info->mss_min, info->mss_max, skb, protoff,
|
||||
info->invert, hotdrop);
|
||||
}
|
||||
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const struct ipt_ip *ip,
|
||||
const void *ipinfo,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
if (matchsize != IPT_ALIGN(sizeof(struct ipt_tcpmss_match_info)))
|
||||
const struct ipt_ip *ip = ipinfo;
|
||||
if (matchsize != XT_ALIGN(sizeof(struct xt_tcpmss_match_info)))
|
||||
return 0;
|
||||
|
||||
/* Must specify -p tcp */
|
||||
@@ -106,21 +112,60 @@ checkentry(const char *tablename,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct ipt_match tcpmss_match = {
|
||||
static int
|
||||
checkentry6(const char *tablename,
|
||||
const void *ipinfo,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
const struct ip6t_ip6 *ip = ipinfo;
|
||||
|
||||
if (matchsize != XT_ALIGN(sizeof(struct xt_tcpmss_match_info)))
|
||||
return 0;
|
||||
|
||||
/* Must specify -p tcp */
|
||||
if (ip->proto != IPPROTO_TCP || (ip->invflags & XT_INV_PROTO)) {
|
||||
printk("tcpmss: Only works on TCP packets\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct xt_match tcpmss_match = {
|
||||
.name = "tcpmss",
|
||||
.match = &match,
|
||||
.checkentry = &checkentry,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static struct xt_match tcpmss6_match = {
|
||||
.name = "tcpmss",
|
||||
.match = &match,
|
||||
.checkentry = &checkentry6,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
return ipt_register_match(&tcpmss_match);
|
||||
int ret;
|
||||
ret = xt_register_match(AF_INET, &tcpmss_match);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = xt_register_match(AF_INET6, &tcpmss6_match);
|
||||
if (ret)
|
||||
xt_unregister_match(AF_INET, &tcpmss_match);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit fini(void)
|
||||
{
|
||||
ipt_unregister_match(&tcpmss_match);
|
||||
xt_unregister_match(AF_INET6, &tcpmss6_match);
|
||||
xt_unregister_match(AF_INET, &tcpmss_match);
|
||||
}
|
||||
|
||||
module_init(init);
|
333
net/netfilter/xt_tcpudp.c
Normal file
333
net/netfilter/xt_tcpudp.c
Normal file
@@ -0,0 +1,333 @@
|
||||
#include <linux/types.h>
|
||||
#include <linux/module.h>
|
||||
#include <net/ip.h>
|
||||
#include <net/ipv6.h>
|
||||
#include <net/tcp.h>
|
||||
#include <net/udp.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include <linux/netfilter/xt_tcpudp.h>
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
#include <linux/netfilter_ipv6/ip6_tables.h>
|
||||
|
||||
MODULE_DESCRIPTION("x_tables match for TCP and UDP, supports IPv4 and IPv6");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("xt_tcp");
|
||||
MODULE_ALIAS("xt_udp");
|
||||
MODULE_ALIAS("ipt_udp");
|
||||
MODULE_ALIAS("ipt_tcp");
|
||||
MODULE_ALIAS("ip6t_udp");
|
||||
MODULE_ALIAS("ip6t_tcp");
|
||||
|
||||
#ifdef DEBUG_IP_FIREWALL_USER
|
||||
#define duprintf(format, args...) printk(format , ## args)
|
||||
#else
|
||||
#define duprintf(format, args...)
|
||||
#endif
|
||||
|
||||
|
||||
/* Returns 1 if the port is matched by the range, 0 otherwise */
|
||||
static inline int
|
||||
port_match(u_int16_t min, u_int16_t max, u_int16_t port, int invert)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = (port >= min && port <= max) ^ invert;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
tcp_find_option(u_int8_t option,
|
||||
const struct sk_buff *skb,
|
||||
unsigned int protoff,
|
||||
unsigned int optlen,
|
||||
int invert,
|
||||
int *hotdrop)
|
||||
{
|
||||
/* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */
|
||||
u_int8_t _opt[60 - sizeof(struct tcphdr)], *op;
|
||||
unsigned int i;
|
||||
|
||||
duprintf("tcp_match: finding option\n");
|
||||
|
||||
if (!optlen)
|
||||
return invert;
|
||||
|
||||
/* If we don't have the whole header, drop packet. */
|
||||
op = skb_header_pointer(skb, protoff + sizeof(struct tcphdr),
|
||||
optlen, _opt);
|
||||
if (op == NULL) {
|
||||
*hotdrop = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < optlen; ) {
|
||||
if (op[i] == option) return !invert;
|
||||
if (op[i] < 2) i++;
|
||||
else i += op[i+1]?:1;
|
||||
}
|
||||
|
||||
return invert;
|
||||
}
|
||||
|
||||
static int
|
||||
tcp_match(const struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
struct tcphdr _tcph, *th;
|
||||
const struct xt_tcp *tcpinfo = matchinfo;
|
||||
|
||||
if (offset) {
|
||||
/* To quote Alan:
|
||||
|
||||
Don't allow a fragment of TCP 8 bytes in. Nobody normal
|
||||
causes this. Its a cracker trying to break in by doing a
|
||||
flag overwrite to pass the direction checks.
|
||||
*/
|
||||
if (offset == 1) {
|
||||
duprintf("Dropping evil TCP offset=1 frag.\n");
|
||||
*hotdrop = 1;
|
||||
}
|
||||
/* Must not be a fragment. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define FWINVTCP(bool,invflg) ((bool) ^ !!(tcpinfo->invflags & invflg))
|
||||
|
||||
th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph);
|
||||
if (th == NULL) {
|
||||
/* We've been asked to examine this packet, and we
|
||||
can't. Hence, no choice but to drop. */
|
||||
duprintf("Dropping evil TCP offset=0 tinygram.\n");
|
||||
*hotdrop = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!port_match(tcpinfo->spts[0], tcpinfo->spts[1],
|
||||
ntohs(th->source),
|
||||
!!(tcpinfo->invflags & XT_TCP_INV_SRCPT)))
|
||||
return 0;
|
||||
if (!port_match(tcpinfo->dpts[0], tcpinfo->dpts[1],
|
||||
ntohs(th->dest),
|
||||
!!(tcpinfo->invflags & XT_TCP_INV_DSTPT)))
|
||||
return 0;
|
||||
if (!FWINVTCP((((unsigned char *)th)[13] & tcpinfo->flg_mask)
|
||||
== tcpinfo->flg_cmp,
|
||||
XT_TCP_INV_FLAGS))
|
||||
return 0;
|
||||
if (tcpinfo->option) {
|
||||
if (th->doff * 4 < sizeof(_tcph)) {
|
||||
*hotdrop = 1;
|
||||
return 0;
|
||||
}
|
||||
if (!tcp_find_option(tcpinfo->option, skb, protoff,
|
||||
th->doff*4 - sizeof(_tcph),
|
||||
tcpinfo->invflags & XT_TCP_INV_OPTION,
|
||||
hotdrop))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Called when user tries to insert an entry of this type. */
|
||||
static int
|
||||
tcp_checkentry(const char *tablename,
|
||||
const void *info,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
const struct ipt_ip *ip = info;
|
||||
const struct xt_tcp *tcpinfo = matchinfo;
|
||||
|
||||
/* Must specify proto == TCP, and no unknown invflags */
|
||||
return ip->proto == IPPROTO_TCP
|
||||
&& !(ip->invflags & XT_INV_PROTO)
|
||||
&& matchsize == XT_ALIGN(sizeof(struct xt_tcp))
|
||||
&& !(tcpinfo->invflags & ~XT_TCP_INV_MASK);
|
||||
}
|
||||
|
||||
/* Called when user tries to insert an entry of this type. */
|
||||
static int
|
||||
tcp6_checkentry(const char *tablename,
|
||||
const void *entry,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
const struct ip6t_ip6 *ipv6 = entry;
|
||||
const struct xt_tcp *tcpinfo = matchinfo;
|
||||
|
||||
/* Must specify proto == TCP, and no unknown invflags */
|
||||
return ipv6->proto == IPPROTO_TCP
|
||||
&& !(ipv6->invflags & XT_INV_PROTO)
|
||||
&& matchsize == XT_ALIGN(sizeof(struct xt_tcp))
|
||||
&& !(tcpinfo->invflags & ~XT_TCP_INV_MASK);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
udp_match(const struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
struct udphdr _udph, *uh;
|
||||
const struct xt_udp *udpinfo = matchinfo;
|
||||
|
||||
/* Must not be a fragment. */
|
||||
if (offset)
|
||||
return 0;
|
||||
|
||||
uh = skb_header_pointer(skb, protoff, sizeof(_udph), &_udph);
|
||||
if (uh == NULL) {
|
||||
/* We've been asked to examine this packet, and we
|
||||
can't. Hence, no choice but to drop. */
|
||||
duprintf("Dropping evil UDP tinygram.\n");
|
||||
*hotdrop = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return port_match(udpinfo->spts[0], udpinfo->spts[1],
|
||||
ntohs(uh->source),
|
||||
!!(udpinfo->invflags & XT_UDP_INV_SRCPT))
|
||||
&& port_match(udpinfo->dpts[0], udpinfo->dpts[1],
|
||||
ntohs(uh->dest),
|
||||
!!(udpinfo->invflags & XT_UDP_INV_DSTPT));
|
||||
}
|
||||
|
||||
/* Called when user tries to insert an entry of this type. */
|
||||
static int
|
||||
udp_checkentry(const char *tablename,
|
||||
const void *info,
|
||||
void *matchinfo,
|
||||
unsigned int matchinfosize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
const struct ipt_ip *ip = info;
|
||||
const struct xt_udp *udpinfo = matchinfo;
|
||||
|
||||
/* Must specify proto == UDP, and no unknown invflags */
|
||||
if (ip->proto != IPPROTO_UDP || (ip->invflags & XT_INV_PROTO)) {
|
||||
duprintf("ipt_udp: Protocol %u != %u\n", ip->proto,
|
||||
IPPROTO_UDP);
|
||||
return 0;
|
||||
}
|
||||
if (matchinfosize != XT_ALIGN(sizeof(struct xt_udp))) {
|
||||
duprintf("ipt_udp: matchsize %u != %u\n",
|
||||
matchinfosize, XT_ALIGN(sizeof(struct xt_udp)));
|
||||
return 0;
|
||||
}
|
||||
if (udpinfo->invflags & ~XT_UDP_INV_MASK) {
|
||||
duprintf("ipt_udp: unknown flags %X\n",
|
||||
udpinfo->invflags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Called when user tries to insert an entry of this type. */
|
||||
static int
|
||||
udp6_checkentry(const char *tablename,
|
||||
const void *entry,
|
||||
void *matchinfo,
|
||||
unsigned int matchinfosize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
const struct ip6t_ip6 *ipv6 = entry;
|
||||
const struct xt_udp *udpinfo = matchinfo;
|
||||
|
||||
/* Must specify proto == UDP, and no unknown invflags */
|
||||
if (ipv6->proto != IPPROTO_UDP || (ipv6->invflags & XT_INV_PROTO)) {
|
||||
duprintf("ip6t_udp: Protocol %u != %u\n", ipv6->proto,
|
||||
IPPROTO_UDP);
|
||||
return 0;
|
||||
}
|
||||
if (matchinfosize != XT_ALIGN(sizeof(struct xt_udp))) {
|
||||
duprintf("ip6t_udp: matchsize %u != %u\n",
|
||||
matchinfosize, XT_ALIGN(sizeof(struct xt_udp)));
|
||||
return 0;
|
||||
}
|
||||
if (udpinfo->invflags & ~XT_UDP_INV_MASK) {
|
||||
duprintf("ip6t_udp: unknown flags %X\n",
|
||||
udpinfo->invflags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct xt_match tcp_matchstruct = {
|
||||
.name = "tcp",
|
||||
.match = &tcp_match,
|
||||
.checkentry = &tcp_checkentry,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
static struct xt_match tcp6_matchstruct = {
|
||||
.name = "tcp",
|
||||
.match = &tcp_match,
|
||||
.checkentry = &tcp6_checkentry,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static struct xt_match udp_matchstruct = {
|
||||
.name = "udp",
|
||||
.match = &udp_match,
|
||||
.checkentry = &udp_checkentry,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
static struct xt_match udp6_matchstruct = {
|
||||
.name = "udp",
|
||||
.match = &udp_match,
|
||||
.checkentry = &udp6_checkentry,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
int ret;
|
||||
ret = xt_register_match(AF_INET, &tcp_matchstruct);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = xt_register_match(AF_INET6, &tcp6_matchstruct);
|
||||
if (ret)
|
||||
goto out_unreg_tcp;
|
||||
|
||||
ret = xt_register_match(AF_INET, &udp_matchstruct);
|
||||
if (ret)
|
||||
goto out_unreg_tcp6;
|
||||
|
||||
ret = xt_register_match(AF_INET6, &udp6_matchstruct);
|
||||
if (ret)
|
||||
goto out_unreg_udp;
|
||||
|
||||
return ret;
|
||||
|
||||
out_unreg_udp:
|
||||
xt_unregister_match(AF_INET, &tcp_matchstruct);
|
||||
out_unreg_tcp6:
|
||||
xt_unregister_match(AF_INET6, &tcp6_matchstruct);
|
||||
out_unreg_tcp:
|
||||
xt_unregister_match(AF_INET, &tcp_matchstruct);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit fini(void)
|
||||
{
|
||||
xt_unregister_match(AF_INET6, &udp6_matchstruct);
|
||||
xt_unregister_match(AF_INET, &udp_matchstruct);
|
||||
xt_unregister_match(AF_INET6, &tcp6_matchstruct);
|
||||
xt_unregister_match(AF_INET, &tcp_matchstruct);
|
||||
}
|
||||
|
||||
module_init(init);
|
||||
module_exit(fini);
|
@@ -62,7 +62,7 @@ ipt_init_target(struct ipt_entry_target *t, char *table, unsigned int hook)
|
||||
struct ipt_target *target;
|
||||
int ret = 0;
|
||||
|
||||
target = ipt_find_target(t->u.user.name, t->u.user.revision);
|
||||
target = xt_find_target(AF_INET, t->u.user.name, t->u.user.revision);
|
||||
if (!target)
|
||||
return -ENOENT;
|
||||
|
||||
|
Reference in New Issue
Block a user