diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ip_conntrack.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ip_conntrack.h --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ip_conntrack.h 2004-03-22 08:57:53.000000000 +0000 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ip_conntrack.h 2004-03-22 09:08:35.000000000 +0000 @@ -206,6 +206,10 @@ } nat; #endif /* CONFIG_IP_NF_NAT_NEEDED */ +#if defined(CONFIG_IP_NF_CONNTRACK_MARK) + unsigned long mark; +#endif + }; /* get master conntrack via master expectation */ diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_CONNMARK.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_CONNMARK.h --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_CONNMARK.h 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_CONNMARK.h 2004-03-22 09:08:35.000000000 +0000 @@ -0,0 +1,25 @@ +#ifndef _IPT_CONNMARK_H_target +#define _IPT_CONNMARK_H_target + +/* Copyright (C) 2002,2004 MARA Systems AB + * by Henrik Nordstrom + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +enum { + IPT_CONNMARK_SET = 0, + IPT_CONNMARK_SAVE, + IPT_CONNMARK_RESTORE +}; + +struct ipt_connmark_target_info { + unsigned long mark; + unsigned long mask; + u_int8_t mode; +}; + +#endif /*_IPT_CONNMARK_H_target*/ diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_IPMARK.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_IPMARK.h --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_IPMARK.h 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_IPMARK.h 2004-03-22 09:00:56.000000000 +0000 @@ -0,0 +1,13 @@ +#ifndef _IPT_IPMARK_H_target +#define _IPT_IPMARK_H_target + +struct ipt_ipmark_target_info { + unsigned long andmask; + unsigned long ormask; + unsigned int addr; +}; + +#define IPT_IPMARK_SRC 0 +#define IPT_IPMARK_DST 1 + +#endif /*_IPT_IPMARK_H_target*/ diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_XOR.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_XOR.h --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_XOR.h 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_XOR.h 2004-03-22 09:01:18.000000000 +0000 @@ -0,0 +1,9 @@ +#ifndef _IPT_XOR_H +#define _IPT_XOR_H + +struct ipt_XOR_info { + char key[30]; + u_int8_t block_size; +}; + +#endif /* _IPT_XOR_H */ diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_addrtype.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_addrtype.h --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_addrtype.h 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_addrtype.h 2004-03-22 09:01:46.000000000 +0000 @@ -0,0 +1,11 @@ +#ifndef _IPT_ADDRTYPE_H +#define _IPT_ADDRTYPE_H + +struct ipt_addrtype_info { + u_int16_t source; /* source-type mask */ + u_int16_t dest; /* dest-type mask */ + int invert_source; + int invert_dest; +}; + +#endif diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_childlevel.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_childlevel.h --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_childlevel.h 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_childlevel.h 2004-03-22 09:01:53.000000000 +0000 @@ -0,0 +1,22 @@ +/* + By Matthew Strait , Dec 2003. + http://l7-filter.sf.net + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version + 2 of the License, or (at your option) any later version. + http://www.gnu.org/licenses/gpl.txt +*/ + +#ifndef _IPT_CHILDLEVEL_H +#define _IPT_CHILDLEVEL_H + +typedef char *(*proc_ipt_search) (u_int32_t, u_int8_t); + +struct ipt_childlevel_info { + u_int32_t childlevel; + u_int8_t invert; +}; + +#endif /* _IPT_CHILDLEVEL_H */ diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_connmark.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_connmark.h --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_connmark.h 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_connmark.h 2004-03-22 09:08:35.000000000 +0000 @@ -0,0 +1,18 @@ +#ifndef _IPT_CONNMARK_H +#define _IPT_CONNMARK_H + +/* Copyright (C) 2002,2004 MARA Systems AB + * by Henrik Nordstrom + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +struct ipt_connmark_info { + unsigned long mark, mask; + u_int8_t invert; +}; + +#endif /*_IPT_CONNMARK_H*/ diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_policy.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_policy.h --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_policy.h 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_policy.h 2004-03-22 09:02:50.000000000 +0000 @@ -0,0 +1,52 @@ +#ifndef _IPT_POLICY_H +#define _IPT_POLICY_H + +#define POLICY_MAX_ELEM 4 + +enum ipt_policy_flags +{ + POLICY_MATCH_IN = 0x1, + POLICY_MATCH_OUT = 0x2, + POLICY_MATCH_NONE = 0x4, + POLICY_MATCH_STRICT = 0x8, +}; + +enum ipt_policy_modes +{ + POLICY_MODE_TRANSPORT, + POLICY_MODE_TUNNEL +}; + +struct ipt_policy_spec +{ + u_int8_t saddr:1, + daddr:1, + proto:1, + mode:1, + spi:1, + reqid:1; +}; + +struct ipt_policy_elem +{ + u_int32_t saddr; + u_int32_t smask; + u_int32_t daddr; + u_int32_t dmask; + u_int32_t spi; + u_int32_t reqid; + u_int8_t proto; + u_int8_t mode; + + struct ipt_policy_spec match; + struct ipt_policy_spec invert; +}; + +struct ipt_policy_info +{ + struct ipt_policy_elem pol[POLICY_MAX_ELEM]; + u_int16_t flags; + u_int16_t len; +}; + +#endif /* _IPT_POLICY_H */ diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/net/tcp.h linux-2.6.5-rc2/include/net/tcp.h --- linux-2.6.5-rc2.org/include/net/tcp.h 2004-03-20 00:11:02.000000000 +0000 +++ linux-2.6.5-rc2/include/net/tcp.h 2004-03-22 09:02:35.000000000 +0000 @@ -162,6 +162,7 @@ extern void tcp_bucket_unlock(struct sock *sk); extern int tcp_port_rover; extern struct sock *tcp_v4_lookup_listener(u32 addr, unsigned short hnum, int dif); +extern struct sock *tcp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 hnum, int dif); /* These are AF independent. */ static __inline__ int tcp_bhashfn(__u16 lport) diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/net/udp.h linux-2.6.5-rc2/include/net/udp.h --- linux-2.6.5-rc2.org/include/net/udp.h 2004-03-20 00:11:34.000000000 +0000 +++ linux-2.6.5-rc2/include/net/udp.h 2004-03-22 09:02:35.000000000 +0000 @@ -74,6 +74,8 @@ extern int udp_ioctl(struct sock *sk, int cmd, unsigned long arg); extern int udp_disconnect(struct sock *sk, int flags); +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif); + DECLARE_SNMP_STAT(struct udp_mib, udp_statistics); #define UDP_INC_STATS(field) SNMP_INC_STATS(udp_statistics, field) #define UDP_INC_STATS_BH(field) SNMP_INC_STATS_BH(udp_statistics, field) diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/core/netfilter.c linux-2.6.5-rc2/net/core/netfilter.c --- linux-2.6.5-rc2.org/net/core/netfilter.c 2004-03-22 08:57:53.000000000 +0000 +++ linux-2.6.5-rc2/net/core/netfilter.c 2004-03-22 09:02:30.000000000 +0000 @@ -60,6 +60,10 @@ } queue_handler[NPROTO]; static rwlock_t queue_handler_lock = RW_LOCK_UNLOCKED; +/** + * nf_register_hook - Register with a netfilter hook + * @reg: Hook operations to be registered + */ int nf_register_hook(struct nf_hook_ops *reg) { struct list_head *i; @@ -76,6 +80,10 @@ return 0; } +/** + * nf_unregister_hook - Unregister from a netfilter hook + * @reg: hook operations to be unregistered + */ void nf_unregister_hook(struct nf_hook_ops *reg) { spin_lock_bh(&nf_hook_lock); @@ -388,6 +396,18 @@ return NF_ACCEPT; } +/** + * nf_register_queue_handler - Registere a queue handler with netfilter + * @pf: protocol family + * @outfn: function called by core to enqueue a packet + * @data: opaque parameter, passed through + * + * This function registers a queue handler with netfilter. There can only + * be one queue handler for every protocol family. + * + * A queue handler _must_ reinject every packet via nf_reinject, no + * matter what. + */ int nf_register_queue_handler(int pf, nf_queue_outfn_t outfn, void *data) { int ret; @@ -405,7 +425,12 @@ return ret; } -/* The caller must flush their queue before this */ +/** + * nf_unregister_queue_handler - Unregister queue handler from netfilter + * @pf: protocol family + * + * The caller must flush their queue before unregistering + */ int nf_unregister_queue_handler(int pf) { write_lock_bh(&queue_handler_lock); @@ -548,6 +573,15 @@ return ret; } +/** + * nf_reinject - Reinject a packet from a queue handler + * @skb: the packet to be reinjected + * @info: info which was passed to the outfn() of the queue handler + * @verdict: verdict (NF_ACCEPT, ...) for this packet + * + * This is the function called by a queue handler to reinject a + * packet. + */ void nf_reinject(struct sk_buff *skb, struct nf_info *info, unsigned int verdict) { diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/Kconfig linux-2.6.5-rc2/net/ipv4/netfilter/Kconfig --- linux-2.6.5-rc2.org/net/ipv4/netfilter/Kconfig 2004-03-22 08:57:53.000000000 +0000 +++ linux-2.6.5-rc2/net/ipv4/netfilter/Kconfig 2004-03-22 09:08:35.000000000 +0000 @@ -701,5 +701,41 @@ depends on IP_NF_IPTABLES help +config IP_NF_TARGET_IPMARK + tristate 'IPMARK target support' + depends on IP_NF_MANGLE + help + +config IP_NF_TARGET_XOR + tristate 'XOR target support' + depends on IP_NF_MANGLE + help + +config IP_NF_MATCH_ADDRTYPE + tristate 'address type match support' + depends on IP_NF_IPTABLES + help + +config IP_NF_MATCH_POLICY + tristate "IPsec policy match support" + depends on IP_NF_IPTABLES && XFRM + help + Policy matching allows you to match packets based on the + IPsec policy that was used during decapsulation/will + be used during encapsulation. + + To compile it as a module, choose M here. If unsure, say N. + help + +config IP_NF_CONNTRACK_MARK + bool 'Connection mark tracking support' +config IP_NF_TARGET_CONNMARK + tristate 'CONNMARK target support' + depends on IP_NF_MANGLE +config IP_NF_MATCH_CONNMARK + tristate ' Connection mark match support' + depends on IP_NF_IPTABLES + help + endmenu diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/Makefile linux-2.6.5-rc2/net/ipv4/netfilter/Makefile --- linux-2.6.5-rc2.org/net/ipv4/netfilter/Makefile 2004-03-22 08:57:53.000000000 +0000 +++ linux-2.6.5-rc2/net/ipv4/netfilter/Makefile 2004-03-22 09:08:35.000000000 +0000 @@ -89,12 +89,15 @@ 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_CONNLIMIT) += ipt_connlimit.o obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o +obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o +obj-$(CONFIG_IP_NF_MATCH_POLICY) += ipt_policy.o # targets obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o @@ -102,6 +105,7 @@ 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_IPMARK) += ipt_IPMARK.o obj-$(CONFIG_IP_NF_TARGET_IMQ) += ipt_IMQ.o obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o @@ -110,6 +114,8 @@ 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_XOR) += ipt_XOR.o obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o obj-$(CONFIG_IP_NF_TARGET_IPV4OPTSSTRIP) += ipt_IPV4OPTSSTRIP.o obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ip_conntrack_core.c linux-2.6.5-rc2/net/ipv4/netfilter/ip_conntrack_core.c --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ip_conntrack_core.c 2004-03-22 08:57:53.000000000 +0000 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ip_conntrack_core.c 2004-03-22 09:08:35.000000000 +0000 @@ -15,6 +15,8 @@ * 16 Jul 2002: Harald Welte * - add usage/reference counts to ip_conntrack_expect * - export ip_conntrack[_expect]_{find_get,put} functions + * 05 Aug 2002: Harald Welte + * - added DocBook-style comments for public API * */ #include @@ -90,6 +92,10 @@ return p; } +/** + * ip_ct_find_proto - Find layer 4 protocol helper for given protocol number + * @protocol: protocol number + */ struct ip_conntrack_protocol *ip_ct_find_proto(u_int8_t protocol) { struct ip_conntrack_protocol *p; @@ -113,6 +119,11 @@ static int ip_conntrack_hash_rnd_initted; static unsigned int ip_conntrack_hash_rnd; +/** + * hash_conntrack - Calculate the position of an entry in the connection + * tracking table. + * @tuple: conntrack tuple which we want to calculate the hash position + */ static u_int32_t hash_conntrack(const struct ip_conntrack_tuple *tuple) { @@ -125,6 +136,19 @@ ip_conntrack_hash_rnd) % ip_conntrack_htable_size); } +/** + * get_tuple - set all the fields of a tuple which is passed as parameter + * given a network buffer. + * @iph:pointer an IP header. + * @skb:network buffer for which we want to generate the tuple + * @dataoff: FIXME: Deprecated? + * @tuple: tuple which will be generate. Used as return parameter. + * @protocol: structure which contains pointer to protocol specific functions. + * + * Note: This function doesn't allocate space for the tuple passed as + * parameter. The function pkt_to_packet which set all the protocol specific + * fields of a given tuple. + */ int get_tuple(const struct iphdr *iph, const struct sk_buff *skb, @@ -146,6 +170,15 @@ return protocol->pkt_to_tuple(skb, dataoff, tuple); } +/** + * invert_tuple - Returns the inverse of a given tuple. It is used to + * calculate the tuple which represents the other sense of the flow + * of a connection. + * @inverse: the inverted tuple. Use as return value. + * @orig: the original tuple which will be inverted. + * @protocol: a pointer to the protocol structure which contains all the + * specifical functions available for this tuple. + */ static int invert_tuple(struct ip_conntrack_tuple *inverse, const struct ip_conntrack_tuple *orig, @@ -161,7 +194,15 @@ /* ip_conntrack_expect helper functions */ -/* Compare tuple parts depending on mask. */ +/** + * expect_cmp - compare a tuple with a expectation depending on a mask + * @i: pointer to an expectation. + * @tuple: tuple which will be compared with the expectation tuple. + * + * Actually the tuple field of an expectation is compared with a tuple + * This function is used by LIST_FIND to find a expectation which match a te + * given tuple. + */ static inline int expect_cmp(const struct ip_conntrack_expect *i, const struct ip_conntrack_tuple *tuple) { @@ -169,6 +210,10 @@ return ip_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask); } +/** + * destroy_expect - Release all the resources allocated by an expectation. + * @exp: pointer to the expectation which we want to release. + */ static void destroy_expect(struct ip_conntrack_expect *exp) { @@ -179,7 +224,11 @@ kfree(exp); } - +/** + * ip_conntrack_expect_put - it decrements the counter of use related + * associated to an expectation and it calls destroy_expect. + * @exp: pointer to the expectation which we want to release. + */ inline void ip_conntrack_expect_put(struct ip_conntrack_expect *exp) { IP_NF_ASSERT(exp); @@ -199,7 +248,14 @@ struct ip_conntrack_expect *, tuple); } -/* Find a expectation corresponding to a tuple. */ +/** + * ip_conntrack_find_get - find conntrack according to tuple + * @tuple: conntrack tuple for which we search conntrack + * @ignored_conntrack: ignore this conntrack during search + * + * This function increments the reference count of the found + * conntrack (if any). + */ struct ip_conntrack_expect * ip_conntrack_expect_find_get(const struct ip_conntrack_tuple *tuple) { @@ -382,7 +438,14 @@ return h; } -/* Find a connection corresponding to a tuple. */ +/** + * ip_conntrack_find_get - find conntrack according to tuple + * @tuple: conntrack tuple for which we search conntrack + * @ignored_conntrack: ignore this conntrack during search + * + * This function increments the reference count of the found + * conntrack (if any). + */ struct ip_conntrack_tuple_hash * ip_conntrack_find_get(const struct ip_conntrack_tuple *tuple, const struct ip_conntrack *ignored_conntrack) @@ -410,7 +473,14 @@ return ct; } -/* Return conntrack and conntrack_info given skb->nfct->master */ +/** + * ip_conntrack_get - Return conntrack and conntrack_info for given skb + * @skb: skb for which we want to find conntrack and conntrack_info + * @ctinfo: pointer to ctinfo, used as return value + * + * This function resolves the respective conntrack and conntrack_info + * structures for the connection this packet (skb) is part of. + */ struct ip_conntrack * ip_conntrack_get(struct sk_buff *skb, enum ip_conntrack_info *ctinfo) { @@ -480,8 +550,14 @@ return NF_DROP; } -/* Returns true if a connection correspondings to the tuple (required - for NAT). */ +/** + * ip_conntrack_tuple_taken - Find out if tuple is already in use + * @tuple: tuple to be used for this test + * @ignored_conntrack: conntrack which is excluded from result + * + * This function is called by the NAT code in order to find out if + * a particular tuple is already in use by some connection. + */ int ip_conntrack_tuple_taken(const struct ip_conntrack_tuple *tuple, const struct ip_conntrack *ignored_conntrack) @@ -607,7 +683,13 @@ { return ip_ct_tuple_mask_cmp(rtuple, &i->tuple, &i->mask); } - +/** + * ip_ct_find_helper - Find application helper according to tuple + * @tuple: tuple for which helper needs to be found + * + * This function is used to determine if any registered conntrack helper + * is to be used for the given tuple. + */ struct ip_conntrack_helper *ip_ct_find_helper(const struct ip_conntrack_tuple *tuple) { return LIST_FIND(&helpers, helper_cmp, @@ -714,12 +796,15 @@ conntrack, expected); /* Welcome, Mr. Bond. We've been expecting you... */ IP_NF_ASSERT(master_ct(conntrack)); - __set_bit(IPS_EXPECTED_BIT, &conntrack->status); - conntrack->master = expected; - expected->sibling = conntrack; - LIST_DELETE(&ip_conntrack_expect_list, expected); - expected->expectant->expecting--; - nf_conntrack_get(&master_ct(conntrack)->infos[0]); + __set_bit(IPS_EXPECTED_BIT, &conntrack->status); + conntrack->master = expected; + expected->sibling = conntrack; +#if CONFIG_IP_NF_CONNTRACK_MARK + conntrack->mark = expected->expectant->mark; +#endif + LIST_DELETE(&ip_conntrack_expect_list, expected); + expected->expectant->expecting--; + nf_conntrack_get(&master_ct(conntrack)->infos[0]); /* this is a braindead... --pablo */ atomic_inc(&ip_conntrack_count); @@ -910,6 +995,14 @@ return ip_ct_tuple_mask_cmp(&i->tuple, tuple, &intersect_mask); } +/** + * ip_conntrack_unexpect_related - Unexpect a related connection + * @expect: expecattin to be removed + * + * This function removes an existing expectation, that has not yet been + * confirmed (i.e. expectation was issued, but expected connection didn't + * arrive yet) + */ inline void ip_conntrack_unexpect_related(struct ip_conntrack_expect *expect) { WRITE_LOCK(&ip_conntrack_lock); @@ -927,7 +1020,20 @@ WRITE_UNLOCK(&ip_conntrack_lock); } -/* Add a related connection. */ +/** + * ip_conntrack_expect_related - Expect a related connection + * @related_to: master conntrack + * @expect: expectation with all values filled in + * + * This function is called by conntrack application helpers who + * have detected that the control (master) connection is just about + * to negotiate a related slave connection. + * + * Note: This function allocates it's own struct ip_conntrack_expect, + * copying the values from the 'expect' parameter. Thus, 'expect' can + * be allocated on the stack and does not need to be valid after this + * function returns. + */ int ip_conntrack_expect_related(struct ip_conntrack *related_to, struct ip_conntrack_expect *expect) { @@ -1057,7 +1163,15 @@ return ret; } -/* Change tuple in an existing expectation */ +/** + * ip_conntrack_change_expect - Change tuple in existing expectation + * @expect: expectation which is to be changed + * @newtuple: new tuple for expect + * + * This function is mostly called by NAT application helpers, who want to + * change an expectation issued by their respective conntrack application + * helper counterpart. + */ int ip_conntrack_change_expect(struct ip_conntrack_expect *expect, struct ip_conntrack_tuple *newtuple) { @@ -1098,8 +1212,15 @@ return ret; } -/* Alter reply tuple (maybe alter helper). If it's already taken, - return 0 and don't do alteration. */ +/** + * ip_conntrack_alter_reply - Alter reply tuple of conntrack + * @conntrack: conntrack whose reply tuple we want to alter + * @newreply: designated reply tuple for this conntrack + * + * This function alters the reply tuple of a conntrack to the given + * newreply tuple. If this newreply tuple is already taken, return 0 + * and don't do alteration + */ int ip_conntrack_alter_reply(struct ip_conntrack *conntrack, const struct ip_conntrack_tuple *newreply) { @@ -1124,6 +1245,13 @@ return 1; } +/** + * ip_conntrack_helper_register - Register a conntrack application helper + * @me: structure describing the helper + * + * This function is called by conntrack application helpers to register + * themselves with the conntrack core. + */ int ip_conntrack_helper_register(struct ip_conntrack_helper *me) { WRITE_LOCK(&ip_conntrack_lock); @@ -1145,6 +1273,13 @@ return 0; } +/** + * ip_conntrack_helper_unregister - Unregister a conntrack application helper + * @me: structure describing the helper + * + * This function is called by conntrack application helpers to unregister + * themselvers from the conntrack core. + */ void ip_conntrack_helper_unregister(struct ip_conntrack_helper *me) { unsigned int i; @@ -1163,7 +1298,14 @@ synchronize_net(); } -/* Refresh conntrack for this many jiffies. */ +/** + * ip_ct_refresh - Refresh conntrack timer for given conntrack + * @ct: conntrack which we want to refresh + * @extra_jiffies: number of jiffies to add + * + * This function is called by protocol helpers and application helpers in + * order to change the expiration timer of a conntrack entry. + */ void ip_ct_refresh(struct ip_conntrack *ct, unsigned long extra_jiffies) { IP_NF_ASSERT(ct->timeout.data == (unsigned long)ct); @@ -1182,7 +1324,16 @@ WRITE_UNLOCK(&ip_conntrack_lock); } -/* Returns new sk_buff, or NULL */ + +/** + * ip_ct_gather_frags - Gather fragments of a particular skb + * @skb: pointer to sk_buff of fragmented IP packet + * + * This code is just a wrapper around the defragmentation code in the core IPv4 + * stack. It also takes care of nonlinear skb's. + * + * Returns new sk_buff, or NULL + */ struct sk_buff * ip_ct_gather_frags(struct sk_buff *skb) { @@ -1266,6 +1417,16 @@ return h; } +/** + * ip_ct_selective_cleanup - Selectively delete a set of conntrack entries + * @kill: callback function selecting which entries to delete + * @data: opaque data pointer, becomes 2nd argument for kill function + * + * This function can be used to selectively delete elements of the conntrack + * hashtable. The function iterates over the list of conntrack entries and + * calls the 'kill' function for every entry. If the return value is true, + * the connection is deleted (death_by_timeout). + */ void ip_ct_selective_cleanup(int (*kill)(const struct ip_conntrack *i, void *data), void *data) diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ip_conntrack_standalone.c linux-2.6.5-rc2/net/ipv4/netfilter/ip_conntrack_standalone.c --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ip_conntrack_standalone.c 2004-03-22 08:57:53.000000000 +0000 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ip_conntrack_standalone.c 2004-03-22 09:08:35.000000000 +0000 @@ -110,6 +110,9 @@ len += sprintf(buffer + len, "[ASSURED] "); len += sprintf(buffer + len, "use=%u ", atomic_read(&conntrack->ct_general.use)); +#if defined(CONFIG_IP_NF_CONNTRACK_MARK) + len += sprintf(buffer + len, "mark=%ld ", conntrack->mark); +#endif len += sprintf(buffer + len, "\n"); return len; @@ -569,13 +572,20 @@ return ret; } -/* FIXME: Allow NULL functions and sub in pointers to generic for - them. --RR */ +/** + * ip_conntrack_protocol_register - Register layer 4 protocol helper + * @proto: structure describing this layer 4 protocol helper + * + * This function is called by layer 4 protocol helpers to register + * themselves with the conntrack core. + */ int ip_conntrack_protocol_register(struct ip_conntrack_protocol *proto) { int ret = 0; struct list_head *i; + /* FIXME: Allow NULL functions and sub in pointers to generic for + them. --RR */ WRITE_LOCK(&ip_conntrack_lock); list_for_each(i, &protocol_list) { if (((struct ip_conntrack_protocol *)i)->proto @@ -592,12 +602,20 @@ return ret; } +/** + * ip_conntrack_protocol_unregister - Unregister layer 4 protocol helper + * @proto: structure describing this layer 4 protocol helper + * + * This function is called byh layer 4 protocol helpers to unregister + * themselvers from the conntrack core. Please note that all conntrack + * entries for this protocol are deleted from the conntrack hash table. + */ void ip_conntrack_protocol_unregister(struct ip_conntrack_protocol *proto) { WRITE_LOCK(&ip_conntrack_lock); - /* ip_ct_find_proto() returns proto_generic in case there is no protocol - * helper. So this should be enough - HW */ + /* ip_ct_find_proto() returns proto_generic in case there is no + * protocol helper. So this should be enough - HW */ LIST_DELETE(&protocol_list, proto); WRITE_UNLOCK(&ip_conntrack_lock); diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ip_nat_core.c linux-2.6.5-rc2/net/ipv4/netfilter/ip_nat_core.c --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ip_nat_core.c 2004-03-22 08:57:53.000000000 +0000 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ip_nat_core.c 2004-03-22 09:02:30.000000000 +0000 @@ -96,9 +96,16 @@ WRITE_UNLOCK(&ip_nat_lock); } -/* We do checksum mangling, so if they were wrong before they're still - * wrong. Also works for incomplete packets (eg. ICMP dest - * unreachables.) */ +/** + * ip_nat_cheat_check - Incremental checksum change for IP/TCP checksum + * @oldvalinv: bit-inverted old value of 32bit word + * @newval: new value of 32bit word + * @oldcheck: old checksum value + * + * This function implements incremental checksum mangling, so if a checksum + * was wrong it will still be wrong after mangling. Also works for incomplete + * packets (eg. ICMP dest unreachables). Return value is the new checksum. + */ u_int16_t ip_nat_cheat_check(u_int32_t oldvalinv, u_int32_t newval, u_int16_t oldcheck) { @@ -124,7 +131,14 @@ return i; } -/* Is this tuple already taken? (not by us) */ +/** + * ip_nat_used_tuple - Is this tuple already in use? + * @tuple: tuple to be used for this check + * @ignored_conntrack: conntrack excluded from this check + * + * This function checks for the reply (inverted) tuple in the conntrack + * hash. This is necessarry with NAT, since there is no fixed mapping. + */ int ip_nat_used_tuple(const struct ip_conntrack_tuple *tuple, const struct ip_conntrack *ignored_conntrack) @@ -515,6 +529,19 @@ #endif }; +/** + * ip_nat_setup_info - Set up NAT mappings for NEW packet + * @conntrack: conntrack on which we operate + * @mr: address/port range which is valid for this NAT mapping + * @hooknum: hook at which this NAT mapping applies + * + * This function is called by NAT targets (SNAT,DNAT,...) and by + * the NAT application helper modules. It is called for the NEW packet + * of a connection in order to specify which NAT mappings shall apply to + * this connection at a given hook. + * + * Note: The reply mappings are created automagically by this function. + */ unsigned int ip_nat_setup_info(struct ip_conntrack *conntrack, const struct ip_nat_multi_range *mr, diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ip_nat_helper.c linux-2.6.5-rc2/net/ipv4/netfilter/ip_nat_helper.c --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ip_nat_helper.c 2004-03-20 00:11:02.000000000 +0000 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ip_nat_helper.c 2004-03-22 09:02:30.000000000 +0000 @@ -150,9 +150,19 @@ return 1; } -/* Generic function for mangling variable-length address changes inside - * NATed TCP connections (like the PORT XXX,XXX,XXX,XXX,XXX,XXX - * command in FTP). +/** + * ip_nat_mangle_tcp_packet - Mangle and potentially resize payload packet + * @skb: pointer to skb of packet on which we operate + * @ct: conntrack of the connection to which this packet belongs + * @ctinfo: conntrack_info of the connection to which this packet belongs + * @match_offset: offset in bytes where to-be-manipulated part starts + * @match_len: lenght of the to-be-manipulated part + * @rep_buffer: pointer to buffer containing replacement + * @rep_len: length of replacement + * + * Generic function for mangling fixed and variable-length changes inside + * NATed TCP connections (like the PORT XXX,XXX,XXX,XXX,XXX,XXX command + * in FTP). * * Takes care about all the nasty sequence number changes, checksumming, * skb enlargement, ... @@ -198,16 +208,27 @@ return 1; } -/* Generic function for mangling variable-length address changes inside - * NATed UDP connections (like the CONNECT DATA XXXXX MESG XXXXX INDEX XXXXX - * command in the Amanda protocol) +/** + * ip_nat_mangle_udp_packet - Mangle and potentially resize payload packet + * @skb: pointer to skb of packet on which we operate + * @ct: conntrack of the connection to which this packet belongs + * @ctinfo: conntrack_info of the connection to which this packet belongs + * @match_offset: offset in bytes where to-be-manipulated part starts + * @match_len: lenght of the to-be-manipulated part + * @rep_buffer: pointer to buffer containing replacement + * @rep_len: length of replacement + * + * Generic function for mangling fixed and variable-length changes inside + * NATed TCP connections (like the CONNECT DATA XXXXX MESG XXXXX INDEX XXXXX + * commad in the Amanda protocol) * * Takes care about all the nasty sequence number changes, checksumming, * skb enlargement, ... * - * XXX - This function could be merged with ip_nat_mangle_tcp_packet which - * should be fairly easy to do. - */ + * FIXME: should be unified with ip_nat_mangle_tcp_packet!! + * + * */ + int ip_nat_mangle_udp_packet(struct sk_buff **pskb, struct ip_conntrack *ct, @@ -405,6 +426,13 @@ return ip_ct_tuple_mask_cmp(tuple, &helper->tuple, &helper->mask); } +/** + * ip_nat_helper_register - Register NAT application helper + * @me: structure describing the helper + * + * This function is called by NAT application helpers to register + * themselves with the NAT core. + */ int ip_nat_helper_register(struct ip_nat_helper *me) { int ret = 0; @@ -431,6 +459,13 @@ return ret; } +/** + * ip_nat_helper_unregister - Unregister NAT application helper + * @me: structure describing the helper + * + * This function is called by NAT application helpers to unregister + * themselves from the NAT core. + */ void ip_nat_helper_unregister(struct ip_nat_helper *me) { WRITE_LOCK(&ip_nat_lock); diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ip_nat_standalone.c linux-2.6.5-rc2/net/ipv4/netfilter/ip_nat_standalone.c --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ip_nat_standalone.c 2004-03-20 00:11:34.000000000 +0000 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ip_nat_standalone.c 2004-03-22 09:02:30.000000000 +0000 @@ -266,7 +266,13 @@ }; #endif -/* Protocol registration. */ +/** + * ip_nat_protocol_register - Register a layer 4 protocol helper + * @proto: structure describing this helper + * + * This function is called by NAT layer 4 protocol helpers to register + * themselvers with the NAT core. + */ int ip_nat_protocol_register(struct ip_nat_protocol *proto) { int ret = 0; @@ -287,9 +293,16 @@ return ret; } -/* Noone stores the protocol anywhere; simply delete it. */ +/** + * ip_nat_protocol_unregister - Unregister a layer 4 protocol helper + * @proto: structure describing the helper + * + * This function is called by NAT layer 4 protocol helpers to + * unregister themselves from the NAT core. + */ void ip_nat_protocol_unregister(struct ip_nat_protocol *proto) { + /* Noone stores the protocol anywhere; simply delete it. */ WRITE_LOCK(&ip_nat_lock); LIST_DELETE(&protos, proto); WRITE_UNLOCK(&ip_nat_lock); diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ip_tables.c linux-2.6.5-rc2/net/ipv4/netfilter/ip_tables.c --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ip_tables.c 2004-03-20 00:11:03.000000000 +0000 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ip_tables.c 2004-03-22 09:02:27.000000000 +0000 @@ -8,6 +8,10 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * + * 6 Mar 2002 Robert Olsson + * 17 Apr 2003 Chris Wilson + * - mark_source_chains speedup for complex chains + * * 19 Jan 2002 Harald Welte * - increase module usage count as soon as we have rules inside * a table @@ -498,6 +502,9 @@ { unsigned int hook; + /* keep track of where we have been: */ + unsigned char *been = vmalloc(newinfo->size); + /* No recursion; use packet counter to save back ptrs (reset to 0 as we leave), and comefrom to save source hook bitmask */ for (hook = 0; hook < NF_IP_NUMHOOKS; hook++) { @@ -510,6 +517,7 @@ /* Set initial back pointer. */ e->counters.pcnt = pos; + memset(been, 0, newinfo->size); for (;;) { struct ipt_standard_target *t @@ -518,6 +526,7 @@ if (e->comefrom & (1 << NF_IP_NUMHOOKS)) { printk("iptables: loop hook %u pos %u %08X.\n", hook, pos, e->comefrom); + vfree(been); return 0; } e->comefrom @@ -565,10 +574,14 @@ } else { int newpos = t->verdict; - if (strcmp(t->target.u.user.name, + if ( (pos < 0 || pos >= newinfo->size + || !been[pos]) + && strcmp(t->target.u.user.name, IPT_STANDARD_TARGET) == 0 && newpos >= 0) { /* This a jump; chase it. */ + if (pos >= 0 && pos < newinfo->size) + been[pos]++; duprintf("Jump rule %u -> %u\n", pos, newpos); } else { @@ -584,6 +597,7 @@ next: duprintf("Finished chain %u\n", hook); } + vfree(been); return 1; } diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_CONNMARK.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_CONNMARK.c --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_CONNMARK.c 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_CONNMARK.c 2004-03-22 09:08:35.000000000 +0000 @@ -0,0 +1,118 @@ +/* This kernel module is used to modify the connection mark values, or + * to optionally restore the skb nfmark from the connection mark + * + * Copyright (C) 2002,2004 MARA Systems AB + * by Henrik Nordstrom + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include + +MODULE_AUTHOR("Henrik Nordstrom "); +MODULE_DESCRIPTION("IP tables CONNMARK matching module"); +MODULE_LICENSE("GPL"); + +#include +#include +#include + +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_connmark_target_info *markinfo = targinfo; + unsigned long diff; + unsigned long nfmark; + unsigned long newmark; + + enum ip_conntrack_info ctinfo; + struct ip_conntrack *ct = ip_conntrack_get((*pskb), &ctinfo); + if (ct) { + switch(markinfo->mode) { + case IPT_CONNMARK_SET: + newmark = (ct->mark & ~markinfo->mask) | markinfo->mark; + if (newmark != ct->mark) + ct->mark = newmark; + break; + case IPT_CONNMARK_SAVE: + newmark = (ct->mark & ~markinfo->mask) | ((*pskb)->nfmark & markinfo->mask); + if (ct->mark != newmark) + ct->mark = newmark; + break; + case IPT_CONNMARK_RESTORE: + nfmark = (*pskb)->nfmark; + diff = (ct->mark ^ nfmark & markinfo->mask); + if (diff != 0) { + (*pskb)->nfmark = nfmark ^ diff; + (*pskb)->nfcache |= NFC_ALTERED; + } + break; + } + } + + return IPT_CONTINUE; +} + +static int +checkentry(const char *tablename, + const struct ipt_entry *e, + 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))) { + printk(KERN_WARNING "CONNMARK: targinfosize %u != %Zu\n", + targinfosize, + IPT_ALIGN(sizeof(struct ipt_connmark_target_info))); + return 0; + } + + if (matchinfo->mode == IPT_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; + } + } + + return 1; +} + +static struct ipt_target ipt_connmark_reg = { + .name = "CONNMARK", + .target = &target, + .checkentry = &checkentry, + .me = THIS_MODULE +}; + +static int __init init(void) +{ + return ipt_register_target(&ipt_connmark_reg); +} + +static void __exit fini(void) +{ + ipt_unregister_target(&ipt_connmark_reg); +} + +module_init(init); +module_exit(fini); diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_IPMARK.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_IPMARK.c --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_IPMARK.c 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_IPMARK.c 2004-03-22 09:00:56.000000000 +0000 @@ -0,0 +1,81 @@ +/* This is a module which is used for setting the NFMARK field of an skb. */ +#include +#include +#include +#include + +#include +#include + +MODULE_AUTHOR("Grzegorz Janoszka "); +MODULE_DESCRIPTION("IP tables IPMARK: mark based on ip address"); +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_ipmark_target_info *ipmarkinfo = targinfo; + struct iphdr *iph = (*pskb)->nh.iph; + unsigned long mark; + + if (ipmarkinfo->addr == IPT_IPMARK_SRC) + mark = (unsigned long) ntohl(iph->saddr); + else + mark = (unsigned long) ntohl(iph->daddr); + + mark &= ipmarkinfo->andmask; + mark |= ipmarkinfo->ormask; + + if ((*pskb)->nfmark != mark) { + (*pskb)->nfmark = mark; + (*pskb)->nfcache |= NFC_ALTERED; + } + return IPT_CONTINUE; +} + +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_ipmark_target_info))) { + printk(KERN_WARNING "IPMARK: targinfosize %u != %Zu\n", + targinfosize, + IPT_ALIGN(sizeof(struct ipt_ipmark_target_info))); + return 0; + } + + if (strcmp(tablename, "mangle") != 0) { + printk(KERN_WARNING "IPMARK: can only be called from \"mangle\" table, not \"%s\"\n", tablename); + return 0; + } + + return 1; +} + +static struct ipt_target ipt_ipmark_reg = { + .name = "IPMARK", + .target = target, + .checkentry = checkentry, + .me = THIS_MODULE +}; + +static int __init init(void) +{ + return ipt_register_target(&ipt_ipmark_reg); +} + +static void __exit fini(void) +{ + ipt_unregister_target(&ipt_ipmark_reg); +} + +module_init(init); +module_exit(fini); diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_XOR.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_XOR.c --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_XOR.c 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_XOR.c 2004-03-22 09:01:18.000000000 +0000 @@ -0,0 +1,117 @@ +/* XOR target for IP tables + * (C) 2000 by Tim Vandermeersch + * Based on ipt_TTL.c + * + * Version 1.0 + * + * This software is distributed under the terms of GNU GPL + */ + +#include +#include +#include +#include +#include + +#include +#include + +MODULE_AUTHOR("Tim Vandermeersch "); +MODULE_DESCRIPTION("IP tables XOR module"); +MODULE_LICENSE("GPL"); + +static unsigned int +ipt_xor_target(struct sk_buff **pskb, + const struct net_device *in, const struct net_device *out, + unsigned int hooknum, const void *targinfo, void *userinfo) +{ + struct ipt_XOR_info *info = (void *) targinfo; + struct iphdr *iph; + struct tcphdr *tcph; + struct udphdr *udph; + int i, j, k; + + if (!skb_ip_make_writable(pskb, (*pskb)->len)) + return NF_DROP; + + iph = (*pskb)->nh.iph; + + if (iph->protocol == IPPROTO_TCP) { + tcph = (struct tcphdr *) ((*pskb)->data + iph->ihl*4); + for (i=0, j=0; i<(ntohs(iph->tot_len) - iph->ihl*4 - tcph->doff*4); ) { + for (k=0; k<=info->block_size; k++) { + (char) (*pskb)->data[ iph->ihl*4 + tcph->doff*4 + i ] ^= + info->key[j]; + i++; + } + j++; + if (info->key[j] == 0x00) + j = 0; + } + } else if (iph->protocol == IPPROTO_UDP) { + udph = (struct udphdr *) ((*pskb)->data + iph->ihl*4); + for (i=0, j=0; i<(ntohs(udph->len)-8); ) { + for (k=0; k<=info->block_size; k++) { + (char) (*pskb)->data[ iph->ihl*4 + sizeof(struct udphdr) + i ] ^= + info->key[j]; + i++; + } + j++; + if (info->key[j] == 0x00) + j = 0; + } + } + + return IPT_CONTINUE; +} + +static int ipt_xor_checkentry(const char *tablename, const struct ipt_entry *e, + void *targinfo, unsigned int targinfosize, + unsigned int hook_mask) +{ + struct ipt_XOR_info *info = targinfo; + + if (targinfosize != IPT_ALIGN(sizeof(struct ipt_XOR_info))) { + printk(KERN_WARNING "XOR: targinfosize %u != %Zu\n", + targinfosize, IPT_ALIGN(sizeof(struct ipt_XOR_info))); + return 0; + } + + if (strcmp(tablename, "mangle")) { + printk(KERN_WARNING "XOR: can only be called from" + "\"mangle\" table, not \"%s\"\n", tablename); + return 0; + } + + if (!strcmp(info->key, "")) { + printk(KERN_WARNING "XOR: You must specify a key"); + return 0; + } + + if (info->block_size == 0) { + printk(KERN_WARNING "XOR: You must specify a block-size"); + return 0; + } + + return 1; +} + +static struct ipt_target ipt_XOR = { + .name = "XOR", + .target = ipt_xor_target, + .checkentry = ipt_xor_checkentry, + .me = THIS_MODULE, +}; + +static int __init init(void) +{ + return ipt_register_target(&ipt_XOR); +} + +static void __exit fini(void) +{ + ipt_unregister_target(&ipt_XOR); +} + +module_init(init); +module_exit(fini); diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_addrtype.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_addrtype.c --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_addrtype.c 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_addrtype.c 2004-03-22 09:01:46.000000000 +0000 @@ -0,0 +1,68 @@ +/* + * iptables module to match inet_addr_type() of an ip. + */ + +#include +#include +#include +#include + +#include +#include + +MODULE_LICENSE("GPL"); + +static inline int match_type(u_int32_t addr, u_int16_t mask) +{ + return !!(mask & (1 << inet_addr_type(addr))); +} + +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_addrtype_info *info = matchinfo; + const struct iphdr *iph = skb->nh.iph; + int ret = 1; + + if (info->source) + ret &= match_type(iph->saddr, info->source)^info->invert_source; + if (info->dest) + ret &= match_type(iph->daddr, info->dest)^info->invert_dest; + + return ret; +} + +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_addrtype_info))) { + printk(KERN_ERR "ipt_addrtype: invalid size (%u != %u)\n.", + matchsize, IPT_ALIGN(sizeof(struct ipt_addrtype_info))); + return 0; + } + + return 1; +} + +static struct ipt_match addrtype_match = { + .name = "addrtype", + .match = match, + .checkentry = checkentry, + .me = THIS_MODULE +}; + +static int __init init(void) +{ + return ipt_register_match(&addrtype_match); +} + +static void __exit fini(void) +{ + ipt_unregister_match(&addrtype_match); + +} + +module_init(init); +module_exit(fini); diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_childlevel.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_childlevel.c --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_childlevel.c 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_childlevel.c 2004-03-22 09:01:53.000000000 +0000 @@ -0,0 +1,76 @@ +/* + Kernel module to match the childlevel of a connection. + i.e. The ftp control stream is childlevel 0. + The ftp data stream is childlevel 1. + + By Matthew Strait , Dec 2003. + http://l7-filter.sf.net + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version + 2 of the License, or (at your option) any later version. + http://www.gnu.org/licenses/gpl.txt +*/ + +#include +#include +#include + +#include +#include + +MODULE_AUTHOR("Matthew Strait "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Childlevel 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) +{ + struct ipt_childlevel_info * info = (struct ipt_childlevel_info *)matchinfo; + enum ip_conntrack_info ctinfo; + struct ip_conntrack * conntrack; + int childlevel = 0; + + if(!(conntrack = ip_conntrack_get((struct sk_buff *)skb, &ctinfo))){ + printk(KERN_ERR "Netfilter: childlevel: error getting conntrack, giving up.\n"); + return 0; + } + + while (master_ct(conntrack) != NULL){ + childlevel++; + conntrack = master_ct(conntrack); + } + + return ( (childlevel == info->childlevel) ^ 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_childlevel_info))) + return 0; + return 1; +} + +static struct ipt_match childlevel_match = { + .name = "childlevel", + .match = &match, + .checkentry = &checkentry, + .me = THIS_MODULE +}; + +static int __init init(void) +{ + return ipt_register_match(&childlevel_match); +} + +static void __exit fini(void) +{ + ipt_unregister_match(&childlevel_match); +} + +module_init(init); +module_exit(fini); diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_connmark.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_connmark.c --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_connmark.c 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_connmark.c 2004-03-22 09:08:35.000000000 +0000 @@ -0,0 +1,81 @@ +/* This kernel module matches connection mark values set by the + * CONNMARK target + * + * Copyright (C) 2002,2004 MARA Systems AB + * by Henrik Nordstrom + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include + +MODULE_AUTHOR("Henrik Nordstrom "); +MODULE_DESCRIPTION("IP tables connmark match module"); +MODULE_LICENSE("GPL"); + +#include +#include +#include + +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_connmark_info *info = matchinfo; + enum ip_conntrack_info ctinfo; + struct ip_conntrack *ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo); + if (!ct) + return 0; + + return ((ct->mark & info->mask) == info->mark) ^ 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_connmark_info))) + return 0; + + return 1; +} + +static struct ipt_match connmark_match = { + .name = "connmark", + .match = &match, + .checkentry = &checkentry, + .me = THIS_MODULE +}; + +static int __init init(void) +{ + return ipt_register_match(&connmark_match); +} + +static void __exit fini(void) +{ + ipt_unregister_match(&connmark_match); +} + +module_init(init); +module_exit(fini); diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_helper.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_helper.c --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_helper.c 2004-03-22 08:57:53.000000000 +0000 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_helper.c 2004-03-22 09:02:25.000000000 +0000 @@ -71,8 +71,11 @@ DEBUGP("master's name = %s , info->name = %s\n", exp->expectant->helper->name, info->name); - ret ^= !strncmp(exp->expectant->helper->name, info->name, - strlen(exp->expectant->helper->name)); + if (info->data[0] == '\0') + ret ^= 1; + else + ret ^= !strncmp(exp->expectant->helper->name, info->name, + strlen(exp->expectant->helper->name)); out_unlock: READ_UNLOCK(&ip_conntrack_lock); return ret; @@ -92,10 +95,6 @@ if (matchsize != IPT_ALIGN(sizeof(struct ipt_helper_info))) return 0; - /* verify that we actually should match anything */ - if ( strlen(info->name) == 0 ) - return 0; - return 1; } diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_owner.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_owner.c --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_owner.c 2004-03-20 00:11:50.000000000 +0000 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_owner.c 2004-03-22 09:02:35.000000000 +0000 @@ -6,12 +6,19 @@ * 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. + * + * 03/26/2003 Patrick McHardy : LOCAL_IN support */ #include #include #include +#include +#include +#include #include +#include +#include #include #include @@ -21,7 +28,7 @@ MODULE_DESCRIPTION("iptables owner match"); static int -match_comm(const struct sk_buff *skb, const char *comm) +match_comm(const struct sock *sk, const char *comm) { struct task_struct *g, *p; struct files_struct *files; @@ -38,7 +45,7 @@ spin_lock(&files->file_lock); for (i=0; i < files->max_fds; i++) { if (fcheck_files(files, i) == - skb->sk->sk_socket->file) { + sk->sk_socket->file) { spin_unlock(&files->file_lock); task_unlock(p); read_unlock(&tasklist_lock); @@ -54,7 +61,7 @@ } static int -match_pid(const struct sk_buff *skb, pid_t pid) +match_pid(const struct sock *sk, pid_t pid) { struct task_struct *p; struct files_struct *files; @@ -70,7 +77,7 @@ spin_lock(&files->file_lock); for (i=0; i < files->max_fds; i++) { if (fcheck_files(files, i) == - skb->sk->sk_socket->file) { + sk->sk_socket->file) { spin_unlock(&files->file_lock); task_unlock(p); read_unlock(&tasklist_lock); @@ -86,10 +93,10 @@ } static int -match_sid(const struct sk_buff *skb, pid_t sid) +match_sid(const struct sock *sk, pid_t sid) { struct task_struct *g, *p; - struct file *file = skb->sk->sk_socket->file; + struct file *file = sk->sk_socket->file; int i, found=0; read_lock(&tasklist_lock); @@ -129,41 +136,71 @@ int *hotdrop) { const struct ipt_owner_info *info = matchinfo; + struct iphdr *iph = skb->nh.iph; + struct sock *sk = NULL; + int ret = 0; + + if (out) { + sk = skb->sk; + } else { + if (iph->protocol == IPPROTO_TCP) { + struct tcphdr *tcph = + (struct tcphdr *)((u_int32_t *)iph + iph->ihl); + sk = tcp_v4_lookup(iph->saddr, tcph->source, + iph->daddr, tcph->dest, + skb->dev->ifindex); + if (sk && sk->sk_state == TCP_TIME_WAIT) { + tcp_tw_put((struct tcp_tw_bucket *)sk); + return ret; + } + } else if (iph->protocol == IPPROTO_UDP) { + struct udphdr *udph = + (struct udphdr *)((u_int32_t *)iph + iph->ihl); + sk = udp_v4_lookup(iph->saddr, udph->source, iph->daddr, + udph->dest, skb->dev->ifindex); + } + } - if (!skb->sk || !skb->sk->sk_socket || !skb->sk->sk_socket->file) - return 0; + if (!sk || !sk->sk_socket || !sk->sk_socket->file) + goto out; if(info->match & IPT_OWNER_UID) { - if ((skb->sk->sk_socket->file->f_uid != info->uid) ^ + if ((sk->sk_socket->file->f_uid != info->uid) ^ !!(info->invert & IPT_OWNER_UID)) - return 0; + goto out; } if(info->match & IPT_OWNER_GID) { - if ((skb->sk->sk_socket->file->f_gid != info->gid) ^ + if ((sk->sk_socket->file->f_gid != info->gid) ^ !!(info->invert & IPT_OWNER_GID)) - return 0; + goto out; } if(info->match & IPT_OWNER_PID) { - if (!match_pid(skb, info->pid) ^ + if (!match_pid(sk, info->pid) ^ !!(info->invert & IPT_OWNER_PID)) - return 0; + goto out; } if(info->match & IPT_OWNER_SID) { - if (!match_sid(skb, info->sid) ^ + if (!match_sid(sk, info->sid) ^ !!(info->invert & IPT_OWNER_SID)) - return 0; + goto out; } if(info->match & IPT_OWNER_COMM) { - if (!match_comm(skb, info->comm) ^ + if (!match_comm(sk, info->comm) ^ !!(info->invert & IPT_OWNER_COMM)) - return 0; + goto out; } - return 1; + ret = 1; + +out: + if (in && sk) + sock_put(sk); + + return ret; } static int @@ -173,11 +210,19 @@ unsigned int matchsize, unsigned int hook_mask) { - if (hook_mask - & ~((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_POST_ROUTING))) { - printk("ipt_owner: only valid for LOCAL_OUT or POST_ROUTING.\n"); - return 0; - } + if (hook_mask + & ~((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_POST_ROUTING) | + (1 << NF_IP_LOCAL_IN))) { + printk("ipt_owner: only valid for LOCAL_IN, LOCAL_OUT " + "or POST_ROUTING.\n"); + return 0; + } + + if ((hook_mask & (1 << NF_IP_LOCAL_IN)) + && ip->proto != IPPROTO_TCP && ip->proto != IPPROTO_UDP) { + printk("ipt_owner: only TCP or UDP can be used in LOCAL_IN\n"); + return 0; + } if (matchsize != IPT_ALIGN(sizeof(struct ipt_owner_info))) { printk("Matchsize %u != %Zu\n", matchsize, diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_policy.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_policy.c --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_policy.c 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_policy.c 2004-03-22 09:02:50.000000000 +0000 @@ -0,0 +1,176 @@ +/* IP tables module for matching IPsec policy + * + * Copyright (c) 2004 Patrick McHardy, + * + * 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 +#include +#include +#include +#include +#include + +#include +#include +#include + +MODULE_AUTHOR("Patrick McHardy "); +MODULE_DESCRIPTION("IPtables IPsec policy matching module"); +MODULE_LICENSE("GPL"); + + +static inline int +match_xfrm_state(struct xfrm_state *x, const struct ipt_policy_elem *e) +{ +#define MISMATCH(x,y) (e->match.x && ((e->x != (y)) ^ e->invert.x)) + + if (MISMATCH(saddr, x->props.saddr.a4 & e->smask) || + MISMATCH(daddr, x->id.daddr.a4 & e->dmask) || + MISMATCH(proto, x->id.proto) || + MISMATCH(mode, x->props.mode) || + MISMATCH(spi, x->id.spi) || + MISMATCH(reqid, x->props.reqid)) + return 0; + return 1; +} + +static int +match_policy_in(const struct sk_buff *skb, const struct ipt_policy_info *info) +{ + const struct ipt_policy_elem *e; + struct sec_path *sp = skb->sp; + int strict = info->flags & POLICY_MATCH_STRICT; + int i, pos; + + if (sp == NULL) + return -1; + if (strict && info->len != sp->len) + return 0; + + for (i = sp->len - 1; i >= 0; i--) { + pos = strict ? i - sp->len + 1 : 0; + if (pos >= info->len) + return 0; + e = &info->pol[pos]; + + if (match_xfrm_state(sp->x[i].xvec, e)) { + if (!strict) + return 1; + } else if (strict) + return 0; + } + + return strict ? 1 : 0; +} + +static int +match_policy_out(const struct sk_buff *skb, const struct ipt_policy_info *info) +{ + const struct ipt_policy_elem *e; + struct dst_entry *dst = skb->dst; + int strict = info->flags & POLICY_MATCH_STRICT; + int i, pos; + + if (dst->xfrm == NULL) + return -1; + + for (i = 0; dst && dst->xfrm; dst = dst->child, i++) { + pos = strict ? i : 0; + if (pos >= info->len) + return 0; + e = &info->pol[pos]; + + if (match_xfrm_state(dst->xfrm, e)) { + if (!strict) + return 1; + } else if (strict) + return 0; + } + + return strict ? 1 : 0; +} + +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_policy_info *info = matchinfo; + int ret; + + if (info->flags & POLICY_MATCH_IN) + ret = match_policy_in(skb, info); + else + ret = match_policy_out(skb, info); + + if (ret < 0) { + if (info->flags & POLICY_MATCH_NONE) + ret = 1; + else + ret = 0; + } else if (info->flags & POLICY_MATCH_NONE) + ret = 0; + + return ret; +} + +static int checkentry(const char *tablename, const struct ipt_ip *ip, + void *matchinfo, unsigned int matchsize, + unsigned int hook_mask) +{ + struct ipt_policy_info *info = matchinfo; + + if (matchsize != IPT_ALIGN(sizeof(*info))) { + printk(KERN_ERR "ipt_policy: matchsize %u != %u\n", + matchsize, IPT_ALIGN(sizeof(*info))); + return 0; + } + if (!(info->flags & (POLICY_MATCH_IN|POLICY_MATCH_OUT))) { + printk(KERN_ERR "ipt_policy: neither incoming nor " + "outgoing policy selected\n"); + return 0; + } + if (hook_mask & (1 << NF_IP_PRE_ROUTING | 1 << NF_IP_LOCAL_IN) + && info->flags & POLICY_MATCH_OUT) { + printk(KERN_ERR "ipt_policy: output policy not valid in " + "PRE_ROUTING and INPUT\n"); + return 0; + } + if (hook_mask & (1 << NF_IP_POST_ROUTING | 1 << NF_IP_LOCAL_OUT) + && info->flags & POLICY_MATCH_IN) { + printk(KERN_ERR "ipt_policy: input policy not valid in " + "POST_ROUTING and OUTPUT\n"); + return 0; + } + if (info->len > POLICY_MAX_ELEM) { + printk(KERN_ERR "ipt_policy: too many policy elements\n"); + return 0; + } + + return 1; +} + +static struct ipt_match policy_match = +{ + .name = "policy", + .match = match, + .checkentry = checkentry, + .me = THIS_MODULE, +}; + +static int __init init(void) +{ + return ipt_register_match(&policy_match); +} + +static void __exit fini(void) +{ + ipt_unregister_match(&policy_match); +} + +module_init(init); +module_exit(fini); diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/tcp_ipv4.c linux-2.6.5-rc2/net/ipv4/tcp_ipv4.c --- linux-2.6.5-rc2.org/net/ipv4/tcp_ipv4.c 2004-03-20 00:11:04.000000000 +0000 +++ linux-2.6.5-rc2/net/ipv4/tcp_ipv4.c 2004-03-22 09:02:35.000000000 +0000 @@ -2667,6 +2667,7 @@ EXPORT_SYMBOL(tcp_v4_connect); EXPORT_SYMBOL(tcp_v4_do_rcv); EXPORT_SYMBOL(tcp_v4_lookup_listener); +EXPORT_SYMBOL(tcp_v4_lookup); EXPORT_SYMBOL(tcp_v4_rebuild_header); EXPORT_SYMBOL(tcp_v4_remember_stamp); EXPORT_SYMBOL(tcp_v4_send_check); diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/udp.c linux-2.6.5-rc2/net/ipv4/udp.c --- linux-2.6.5-rc2.org/net/ipv4/udp.c 2004-03-20 00:11:02.000000000 +0000 +++ linux-2.6.5-rc2/net/ipv4/udp.c 2004-03-22 09:02:35.000000000 +0000 @@ -1543,6 +1543,7 @@ EXPORT_SYMBOL(udp_port_rover); EXPORT_SYMBOL(udp_prot); EXPORT_SYMBOL(udp_sendmsg); +EXPORT_SYMBOL(udp_v4_lookup); #ifdef CONFIG_PROC_FS EXPORT_SYMBOL(udp_proc_register);