diff -Nur linux-2.6.0-test7.org/include/linux/netfilter.h linux-2.6.0-test7/include/linux/netfilter.h --- linux-2.6.0-test7.org/include/linux/netfilter.h 2003-10-08 21:24:06.000000000 +0200 +++ linux-2.6.0-test7/include/linux/netfilter.h 2003-10-10 11:53:17.000000000 +0200 @@ -23,6 +23,7 @@ <= 0x2000 is used for protocol-flags. */ #define NFC_UNKNOWN 0x4000 #define NFC_ALTERED 0x8000 +#define NFC_TRACE 0x10000 #ifdef __KERNEL__ #include @@ -99,6 +100,24 @@ extern struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS]; +typedef void nf_logfn(unsigned int hooknum, + const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const char *prefix); + +/* Function to register/unregister log function. */ +int nf_log_register(int pf, nf_logfn *logfn); +void nf_log_unregister(int pf, nf_logfn *logfn); + +/* Calls the registered backend logging function */ +void nf_log_packet(int pf, + unsigned int hooknum, + const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const char *fmt, ...); + /* Activate hook; either okfn or kfree_skb called, unless a hook returns NF_STOLEN (in which case, it's up to the hook to deal with the consequences). diff -Nur linux-2.6.0-test7.org/include/linux/netfilter_ipv4/ip_conntrack.h linux-2.6.0-test7/include/linux/netfilter_ipv4/ip_conntrack.h --- linux-2.6.0-test7.org/include/linux/netfilter_ipv4/ip_conntrack.h 2003-10-08 21:24:48.000000000 +0200 +++ linux-2.6.0-test7/include/linux/netfilter_ipv4/ip_conntrack.h 2003-10-10 11:53:17.000000000 +0200 @@ -268,6 +268,9 @@ extern unsigned int ip_conntrack_htable_size; +/* A fake conntrack entry which never vanishes. */ +extern struct ip_conntrack ip_conntrack_untracked; + /* eg. PROVIDES_CONNTRACK(ftp); */ #define PROVIDES_CONNTRACK(name) \ int needs_ip_conntrack_##name; \ diff -Nur linux-2.6.0-test7.org/include/linux/netfilter_ipv4/ip_tables.h linux-2.6.0-test7/include/linux/netfilter_ipv4/ip_tables.h --- linux-2.6.0-test7.org/include/linux/netfilter_ipv4/ip_tables.h 2003-10-08 21:24:07.000000000 +0200 +++ linux-2.6.0-test7/include/linux/netfilter_ipv4/ip_tables.h 2003-10-10 11:53:17.000000000 +0200 @@ -134,6 +134,12 @@ /* Back pointer */ unsigned int comefrom; + /* Name of the chain */ + char *chainname; + + /* Rule number in the chain. */ + u_int32_t rulenum; + /* Packet and byte counters. */ struct ipt_counters counters; diff -Nur linux-2.6.0-test7.org/include/linux/netfilter_ipv4/ipt_ULOG.h linux-2.6.0-test7/include/linux/netfilter_ipv4/ipt_ULOG.h --- linux-2.6.0-test7.org/include/linux/netfilter_ipv4/ipt_ULOG.h 2003-10-08 21:24:04.000000000 +0200 +++ linux-2.6.0-test7/include/linux/netfilter_ipv4/ipt_ULOG.h 2003-10-10 11:52:57.000000000 +0200 @@ -11,6 +11,9 @@ #define NETLINK_NFLOG 5 #endif +#define NFLOG_DEFAULT_NLGROUP 1 +#define NFLOG_DEFAULT_QTHRESHOLD 1 + #define ULOG_MAC_LEN 80 #define ULOG_PREFIX_LEN 32 diff -Nur linux-2.6.0-test7.org/include/linux/netfilter_ipv4/ipt_conntrack.h linux-2.6.0-test7/include/linux/netfilter_ipv4/ipt_conntrack.h --- linux-2.6.0-test7.org/include/linux/netfilter_ipv4/ipt_conntrack.h 2003-10-08 21:24:26.000000000 +0200 +++ linux-2.6.0-test7/include/linux/netfilter_ipv4/ipt_conntrack.h 2003-10-10 11:53:17.000000000 +0200 @@ -10,6 +10,7 @@ #define IPT_CONNTRACK_STATE_SNAT (1 << (IP_CT_NUMBER + 1)) #define IPT_CONNTRACK_STATE_DNAT (1 << (IP_CT_NUMBER + 2)) +#define IPT_CONNTRACK_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 3)) /* flags, invflags: */ #define IPT_CONNTRACK_STATE 0x01 diff -Nur linux-2.6.0-test7.org/include/linux/netfilter_ipv4/ipt_sctp.h linux-2.6.0-test7/include/linux/netfilter_ipv4/ipt_sctp.h --- linux-2.6.0-test7.org/include/linux/netfilter_ipv4/ipt_sctp.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.0-test7/include/linux/netfilter_ipv4/ipt_sctp.h 2003-10-10 11:53:27.000000000 +0200 @@ -0,0 +1,25 @@ +/* iptables module for matching the SCTP header + * + * (C) 2003 Harald Welte + * + * This software is distributed under GNU GPL v2, 1991 + * + * $Id$ + */ +#ifndef _IPT_SCTP_H +#define _IPT_SCTP_H + +struct ipt_sctp_info { + u_int16_t spts[2]; /* Souce port range */ + u_int16_t dpts[2]; /* Destination port range */ + u_int32_t chunks; /* chunks to be matched */ + u_int32_t chunk_mask; /* chunk mask to be matched */ + u_int8_t invflags; /* Inverse flags */ +}; + +#define IPT_SCTP_INV_SRCPT 0x01 /* Invert the sense of source ports */ +#define IPT_SCTP_INV_DSTPT 0x02 /* Invert the sense of dest ports */ +#define IPT_SCTP_INV_CHUNKS 0x03 /* Invert the sense of chunks */ +#define IPT_SCTP_INV_MASK 0x03 /* All possible flags */ + +#endif /* _IPT_SCTP_H */ diff -Nur linux-2.6.0-test7.org/include/linux/netfilter_ipv4/ipt_state.h linux-2.6.0-test7/include/linux/netfilter_ipv4/ipt_state.h --- linux-2.6.0-test7.org/include/linux/netfilter_ipv4/ipt_state.h 2003-10-08 21:24:42.000000000 +0200 +++ linux-2.6.0-test7/include/linux/netfilter_ipv4/ipt_state.h 2003-10-10 11:53:17.000000000 +0200 @@ -4,6 +4,8 @@ #define IPT_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1)) #define IPT_STATE_INVALID (1 << 0) +#define IPT_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 1)) + struct ipt_state_info { unsigned int statemask; diff -Nur linux-2.6.0-test7.org/include/linux/netfilter_ipv4.h linux-2.6.0-test7/include/linux/netfilter_ipv4.h --- linux-2.6.0-test7.org/include/linux/netfilter_ipv4.h 2003-10-08 21:24:32.000000000 +0200 +++ linux-2.6.0-test7/include/linux/netfilter_ipv4.h 2003-10-10 11:53:17.000000000 +0200 @@ -51,6 +51,8 @@ enum nf_ip_hook_priorities { NF_IP_PRI_FIRST = INT_MIN, + NF_IP_PRI_CONNTRACK_DEFRAG = -400, + NF_IP_PRI_RAW = -300, NF_IP_PRI_CONNTRACK = -200, NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD = -175, NF_IP_PRI_MANGLE = -150, diff -Nur linux-2.6.0-test7.org/include/linux/netfilter_ipv6/ip6_tables.h linux-2.6.0-test7/include/linux/netfilter_ipv6/ip6_tables.h --- linux-2.6.0-test7.org/include/linux/netfilter_ipv6/ip6_tables.h 2003-10-08 21:24:51.000000000 +0200 +++ linux-2.6.0-test7/include/linux/netfilter_ipv6/ip6_tables.h 2003-10-10 11:53:17.000000000 +0200 @@ -140,6 +140,12 @@ /* Back pointer */ unsigned int comefrom; + /* Name of the chain */ + char *chainname; + + /* Rule number in the chain. */ + u_int32_t rulenum; + /* Packet and byte counters. */ struct ip6t_counters counters; diff -Nur linux-2.6.0-test7.org/net/core/netfilter.c linux-2.6.0-test7/net/core/netfilter.c --- linux-2.6.0-test7.org/net/core/netfilter.c 2003-10-08 21:24:04.000000000 +0200 +++ linux-2.6.0-test7/net/core/netfilter.c 2003-10-10 11:52:57.000000000 +0200 @@ -8,8 +8,10 @@ * * February 2000: Modified by James Morris to have 1 queue per protocol. * 15-Mar-2000: Added NF_REPEAT --RR. + * 08-May-2003: Internal logging interface added by Jozsef Kadlecsik. */ #include +#include #include #include #include @@ -743,7 +745,70 @@ EXPORT_SYMBOL(skb_ip_make_writable); #endif /*CONFIG_INET*/ +/* Internal logging interface, which relies on the real + LOG target modules */ +#define NF_LOG_PREFIXLEN 128 + +static nf_logfn *nf_logging[NPROTO]; /* = NULL */ +static int reported = 0; +static spinlock_t nf_log_lock = SPIN_LOCK_UNLOCKED; + +int nf_log_register(int pf, nf_logfn *logfn) +{ + int ret = -EBUSY; + + /* Any setup of logging members must be done before + * substituting pointer. */ + smp_wmb(); + spin_lock(&nf_log_lock); + if (!nf_logging[pf]) { + nf_logging[pf] = logfn; + ret = 0; + } + spin_unlock(&nf_log_lock); + return ret; +} + +void nf_log_unregister(int pf, nf_logfn *logfn) +{ + spin_lock(&nf_log_lock); + if (nf_logging[pf] == logfn) + nf_logging[pf] = NULL; + spin_unlock(&nf_log_lock); + + /* Give time to concurrent readers. */ + synchronize_net(); +} + +void nf_log_packet(int pf, + unsigned int hooknum, + const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const char *fmt, ...) +{ + va_list args; + char prefix[NF_LOG_PREFIXLEN]; + nf_logfn *logfn; + + rcu_read_lock(); + logfn = nf_logging[pf]; + if (logfn) { + va_start(args, fmt); + vsnprintf(prefix, sizeof(prefix), fmt, args); + va_end(args); + /* We must read logging before nf_logfn[pf] */ + smp_read_barrier_depends(); + logfn(hooknum, skb, in, out, prefix); + } else if (!reported) { + printk(KERN_WARNING "nf_log_packet: can\'t log yet, " + "no backend logging module loaded in!\n"); + reported++; + } + rcu_read_unlock(); +} + /* This does not belong here, but ipt_REJECT needs it if connection tracking in use: without this, connection may not be in hash table, and hence manufactured ICMP or RST packets will not be associated @@ -773,3 +838,6 @@ EXPORT_SYMBOL(nf_unregister_hook); EXPORT_SYMBOL(nf_unregister_queue_handler); EXPORT_SYMBOL(nf_unregister_sockopt); +EXPORT_SYMBOL(nf_log_register); +EXPORT_SYMBOL(nf_log_unregister); +EXPORT_SYMBOL(nf_log_packet); diff -Nur linux-2.6.0-test7.org/net/ipv4/netfilter/Kconfig linux-2.6.0-test7/net/ipv4/netfilter/Kconfig --- linux-2.6.0-test7.org/net/ipv4/netfilter/Kconfig 2003-10-08 21:24:27.000000000 +0200 +++ linux-2.6.0-test7/net/ipv4/netfilter/Kconfig 2003-10-10 11:53:27.000000000 +0200 @@ -197,6 +197,15 @@ To compile it as a module, choose M here. If unsure, say N. +config IP_NF_MATCH_SCTP + tristate "SCTP match support" + depends on IP_NF_IPTABLES + help + This match allows iptables to match on the SCTP header. + + If you want to compile it as a module, say M here and read + . If unsure, say `N'. + config IP_NF_MATCH_LENGTH tristate "LENGTH match support" depends on IP_NF_IPTABLES @@ -527,6 +536,42 @@ To compile it as a module, choose M here. If unsure, say N. +config IP_NF_RAW + tristate "Raw table" + depends on IP_NF_IPTABLES + help + This option adds a `raw' table to iptables: see the man page for + iptables(8). This table is the very first in the netfilter + framework and hooks in at the PREROUTING and OUTPUT chains. + The TRACE and NOTRACK targets can be used in this table only. + + To compile it as a module, choose M here. If unsure, say N. + +config IP_NF_TARGET_TRACE + tristate "TRACE target support" + depends on IP_NF_RAW + help + The TRACE target allows packets to be traced as those matches + any subsequent rule in any table/rule. The matched rule and + the packet is logged with the prefix + + TRACE: tablename/chainname/rulenum + + if the ipt_LOG or ipt_ULOG targets are loaded in. + + To compile it as a module, choose M here. If unsure, say N. + +config IP_NF_TARGET_NOTRACK + tristate "NOTRACK target support" + depends on IP_NF_RAW + help + The NOTRACK target allows a select rule to specify which + packets *not* to enter the conntrack/NAT subsystems + with all the consequences (no ICMP error tracking, + no protocol helpers for the selected packets). + + To compile it as a module, choose M here. If unsure, say N. + config IP_NF_ARPTABLES tristate "ARP tables support" diff -Nur linux-2.6.0-test7.org/net/ipv4/netfilter/Makefile linux-2.6.0-test7/net/ipv4/netfilter/Makefile --- linux-2.6.0-test7.org/net/ipv4/netfilter/Makefile 2003-10-08 21:24:02.000000000 +0200 +++ linux-2.6.0-test7/net/ipv4/netfilter/Makefile 2003-10-10 11:53:27.000000000 +0200 @@ -34,12 +34,14 @@ # generic IP tables obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o -# the three instances of ip_tables +# the four instances of ip_tables obj-$(CONFIG_IP_NF_FILTER) += iptable_filter.o obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o obj-$(CONFIG_IP_NF_NAT) += iptable_nat.o +obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o # matches +obj-$(CONFIG_IP_NF_MATCH_SCTP) += ipt_sctp.o obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o obj-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit.o obj-$(CONFIG_IP_NF_MATCH_MARK) += ipt_mark.o @@ -81,6 +83,8 @@ obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.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_TRACE) += ipt_TRACE.o # generic ARP tables obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o diff -Nur linux-2.6.0-test7.org/net/ipv4/netfilter/ip_conntrack_amanda.c linux-2.6.0-test7/net/ipv4/netfilter/ip_conntrack_amanda.c --- linux-2.6.0-test7.org/net/ipv4/netfilter/ip_conntrack_amanda.c 2003-10-08 21:24:17.000000000 +0200 +++ linux-2.6.0-test7/net/ipv4/netfilter/ip_conntrack_amanda.c 2003-10-10 11:52:23.000000000 +0200 @@ -210,5 +210,7 @@ PROVIDES_CONNTRACK(amanda); EXPORT_SYMBOL(ip_amanda_lock); +EXPORT_SYMBOL(ip_amanda_lock); + module_init(init); module_exit(fini); diff -Nur linux-2.6.0-test7.org/net/ipv4/netfilter/ip_conntrack_core.c linux-2.6.0-test7/net/ipv4/netfilter/ip_conntrack_core.c --- linux-2.6.0-test7.org/net/ipv4/netfilter/ip_conntrack_core.c 2003-10-08 21:24:00.000000000 +0200 +++ linux-2.6.0-test7/net/ipv4/netfilter/ip_conntrack_core.c 2003-10-10 11:53:17.000000000 +0200 @@ -29,8 +29,7 @@ #include #include #include -/* For ERR_PTR(). Yeah, I know... --RR */ -#include +#include /* This rwlock protects the main hash table, protocol/helper/expected registrations, conntrack timers*/ @@ -63,6 +62,7 @@ static atomic_t ip_conntrack_count = ATOMIC_INIT(0); struct list_head *ip_conntrack_hash; static kmem_cache_t *ip_conntrack_cachep; +struct ip_conntrack ip_conntrack_untracked; extern struct ip_conntrack_protocol ip_conntrack_generic_protocol; @@ -808,18 +808,10 @@ } #endif - /* Previously seen (loopback)? Ignore. Do this before - fragment check. */ + /* Previously seen (loopback or untracked)? Ignore. */ if ((*pskb)->nfct) return NF_ACCEPT; - /* Gather fragments. */ - if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) { - *pskb = ip_ct_gather_frags(*pskb); - if (!*pskb) - return NF_STOLEN; - } - proto = ip_ct_find_proto((*pskb)->nh.iph->protocol); /* It may be an icmp error... */ @@ -953,7 +945,6 @@ } } else if (related_to->helper->max_expected && related_to->expecting >= related_to->helper->max_expected) { - struct list_head *cur_item; /* old == NULL */ if (!(related_to->helper->flags & IP_CT_HELPER_F_REUSE_EXPECT)) { @@ -978,21 +969,14 @@ NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip)); /* choose the the oldest expectation to evict */ - list_for_each(cur_item, &related_to->sibling_list) { - struct ip_conntrack_expect *cur; - - cur = list_entry(cur_item, - struct ip_conntrack_expect, - expected_list); - if (cur->sibling == NULL) { - old = cur; + list_for_each_entry(old, &related_to->sibling_list, + expected_list) + if (old->sibling == NULL) break; - } - } - /* (!old) cannot happen, since related_to->expecting is the - * number of unconfirmed expects */ - IP_NF_ASSERT(old); + /* We cannot fail since related_to->expecting is the number + * of unconfirmed expectations */ + IP_NF_ASSERT(old && old->sibling == NULL); /* newnat14 does not reuse the real allocated memory * structures but rather unexpects the old and @@ -1024,7 +1008,7 @@ atomic_set(&new->use, 1); /* add to expected list for this connection */ - list_add(&new->expected_list, &related_to->sibling_list); + list_add_tail(&new->expected_list, &related_to->sibling_list); /* add to global list of expectations */ list_prepend(&ip_conntrack_expect_list, &new->list); /* add and start timer if required */ @@ -1419,6 +1403,15 @@ /* For use by ipt_REJECT */ ip_ct_attach = ip_conntrack_attach; + + /* Set up fake conntrack: + - to never be deleted, not in any hashes */ + atomic_set(&ip_conntrack_untracked.ct_general.use, 1); + /* - and look it like as a confirmed connection */ + set_bit(IPS_CONFIRMED_BIT, &ip_conntrack_untracked.status); + /* - and prepare the ctinfo field for NAT. */ + ip_conntrack_untracked.infos[IP_CT_NEW].master = &ip_conntrack_untracked.ct_general; + return ret; err_free_hash: diff -Nur linux-2.6.0-test7.org/net/ipv4/netfilter/ip_conntrack_standalone.c linux-2.6.0-test7/net/ipv4/netfilter/ip_conntrack_standalone.c --- linux-2.6.0-test7.org/net/ipv4/netfilter/ip_conntrack_standalone.c 2003-10-08 21:24:04.000000000 +0200 +++ linux-2.6.0-test7/net/ipv4/netfilter/ip_conntrack_standalone.c 2003-10-10 11:53:17.000000000 +0200 @@ -186,6 +186,26 @@ return ip_conntrack_confirm(*pskb); } +static unsigned int ip_conntrack_defrag(unsigned int hooknum, + struct sk_buff **pskb, + const struct net_device *in, + const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + /* Previously seen (loopback)? Ignore. Do this before + fragment check. */ + if ((*pskb)->nfct) + return NF_ACCEPT; + + /* Gather fragments. */ + if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) { + *pskb = ip_ct_gather_frags(*pskb); + if (!*pskb) + return NF_STOLEN; + } + return NF_ACCEPT; +} + static unsigned int ip_refrag(unsigned int hooknum, struct sk_buff **pskb, const struct net_device *in, @@ -225,6 +245,15 @@ return ip_conntrack_in(hooknum, pskb, in, out, okfn); } +/* At the very first: defragment */ +static struct nf_hook_ops ip_conntrack_defrag_ops = { + .hook = ip_conntrack_defrag, + .owner = THIS_MODULE, + .pf = PF_INET, + .hooknum = NF_IP_PRE_ROUTING, + .priority = NF_IP_PRI_CONNTRACK_DEFRAG, +}; + /* Connection tracking may drop packets, but never alters them, so make it the first hook. */ static struct nf_hook_ops ip_conntrack_in_ops = { @@ -367,10 +396,15 @@ if (!proc) goto cleanup_init; proc->owner = THIS_MODULE; + ret = nf_register_hook(&ip_conntrack_defrag_ops); + if (ret < 0) { + printk("ip_conntrack: can't register pre-routing hook to defrag.\n"); + goto cleanup_proc; + } ret = nf_register_hook(&ip_conntrack_in_ops); if (ret < 0) { printk("ip_conntrack: can't register pre-routing hook.\n"); - goto cleanup_proc; + goto cleanup_defragops; } ret = nf_register_hook(&ip_conntrack_local_out_ops); if (ret < 0) { @@ -408,6 +442,8 @@ nf_unregister_hook(&ip_conntrack_local_out_ops); cleanup_inops: nf_unregister_hook(&ip_conntrack_in_ops); + cleanup_defragops: + nf_unregister_hook(&ip_conntrack_defrag_ops); cleanup_proc: proc_net_remove("ip_conntrack"); cleanup_init: @@ -499,5 +535,6 @@ EXPORT_SYMBOL(ip_conntrack_expect_list); EXPORT_SYMBOL(ip_conntrack_lock); EXPORT_SYMBOL(ip_conntrack_hash); +EXPORT_SYMBOL(ip_conntrack_untracked); EXPORT_SYMBOL_GPL(ip_conntrack_find_get); EXPORT_SYMBOL_GPL(ip_conntrack_put); diff -Nur linux-2.6.0-test7.org/net/ipv4/netfilter/ip_conntrack_tftp.c linux-2.6.0-test7/net/ipv4/netfilter/ip_conntrack_tftp.c --- linux-2.6.0-test7.org/net/ipv4/netfilter/ip_conntrack_tftp.c 2003-10-08 21:24:03.000000000 +0200 +++ linux-2.6.0-test7/net/ipv4/netfilter/ip_conntrack_tftp.c 2003-10-10 11:52:47.000000000 +0200 @@ -97,8 +97,6 @@ for (i = 0 ; (i < MAX_PORTS) && ports[i] ; i++) { /* Create helper structure */ - memset(&tftp[i], 0, sizeof(struct ip_conntrack_helper)); - tftp[i].tuple.dst.protonum = IPPROTO_UDP; tftp[i].tuple.src.u.udp.port = htons(ports[i]); tftp[i].mask.dst.protonum = 0xFFFF; diff -Nur linux-2.6.0-test7.org/net/ipv4/netfilter/ip_nat_amanda.c linux-2.6.0-test7/net/ipv4/netfilter/ip_nat_amanda.c --- linux-2.6.0-test7.org/net/ipv4/netfilter/ip_nat_amanda.c 2003-10-08 21:24:02.000000000 +0200 +++ linux-2.6.0-test7/net/ipv4/netfilter/ip_nat_amanda.c 2003-10-10 11:52:47.000000000 +0200 @@ -195,8 +195,6 @@ struct ip_nat_helper *hlpr; hlpr = &ip_nat_amanda_helper; - memset(hlpr, 0, sizeof(struct ip_nat_helper)); - hlpr->tuple.dst.protonum = IPPROTO_UDP; hlpr->tuple.src.u.udp.port = htons(10080); hlpr->mask.src.u.udp.port = 0xFFFF; diff -Nur linux-2.6.0-test7.org/net/ipv4/netfilter/ip_nat_core.c linux-2.6.0-test7/net/ipv4/netfilter/ip_nat_core.c --- linux-2.6.0-test7.org/net/ipv4/netfilter/ip_nat_core.c 2003-10-08 21:24:02.000000000 +0200 +++ linux-2.6.0-test7/net/ipv4/netfilter/ip_nat_core.c 2003-10-10 11:53:17.000000000 +0200 @@ -809,7 +809,7 @@ /* Have to grab read lock before sibling_list traversal */ READ_LOCK(&ip_conntrack_lock); - list_for_each(cur_item, &ct->sibling_list) { + list_for_each_prev(cur_item, &ct->sibling_list) { exp = list_entry(cur_item, struct ip_conntrack_expect, expected_list); @@ -1009,7 +1009,11 @@ /* FIXME: Man, this is a hack. */ IP_NF_ASSERT(ip_conntrack_destroyed == NULL); ip_conntrack_destroyed = &ip_nat_cleanup_conntrack; - + + /* Initialize fake conntrack so that NAT will skip it */ + ip_conntrack_untracked.nat.info.initialized |= + (1 << IP_NAT_MANIP_SRC) | (1 << IP_NAT_MANIP_DST); + return 0; } diff -Nur linux-2.6.0-test7.org/net/ipv4/netfilter/ip_nat_rule.c linux-2.6.0-test7/net/ipv4/netfilter/ip_nat_rule.c --- linux-2.6.0-test7.org/net/ipv4/netfilter/ip_nat_rule.c 2003-10-08 21:24:04.000000000 +0200 +++ linux-2.6.0-test7/net/ipv4/netfilter/ip_nat_rule.c 2003-10-10 11:53:17.000000000 +0200 @@ -67,7 +67,7 @@ 0, sizeof(struct ipt_entry), sizeof(struct ipt_standard), - 0, { 0, 0 }, { } }, + 0, NULL, 0, { 0, 0 }, { } }, { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } }, -NF_ACCEPT - 1 } }, /* POST_ROUTING */ @@ -75,7 +75,7 @@ 0, sizeof(struct ipt_entry), sizeof(struct ipt_standard), - 0, { 0, 0 }, { } }, + 0, NULL, 0, { 0, 0 }, { } }, { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } }, -NF_ACCEPT - 1 } }, /* LOCAL_OUT */ @@ -83,7 +83,7 @@ 0, sizeof(struct ipt_entry), sizeof(struct ipt_standard), - 0, { 0, 0 }, { } }, + 0, NULL, 0, { 0, 0 }, { } }, { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } }, -NF_ACCEPT - 1 } } }, @@ -92,7 +92,7 @@ 0, sizeof(struct ipt_entry), sizeof(struct ipt_error), - 0, { 0, 0 }, { } }, + 0, NULL, 0, { 0, 0 }, { } }, { { { { IPT_ALIGN(sizeof(struct ipt_error_target)), IPT_ERROR_TARGET } }, { } }, "ERROR" diff -Nur linux-2.6.0-test7.org/net/ipv4/netfilter/ip_nat_tftp.c linux-2.6.0-test7/net/ipv4/netfilter/ip_nat_tftp.c --- linux-2.6.0-test7.org/net/ipv4/netfilter/ip_nat_tftp.c 2003-10-08 21:24:03.000000000 +0200 +++ linux-2.6.0-test7/net/ipv4/netfilter/ip_nat_tftp.c 2003-10-10 11:52:47.000000000 +0200 @@ -164,8 +164,6 @@ ports[0] = TFTP_PORT; for (i = 0 ; (i < MAX_PORTS) && ports[i] ; i++) { - memset(&tftp[i], 0, sizeof(struct ip_nat_helper)); - tftp[i].tuple.dst.protonum = IPPROTO_UDP; tftp[i].tuple.src.u.udp.port = htons(ports[i]); tftp[i].mask.dst.protonum = 0xFFFF; diff -Nur linux-2.6.0-test7.org/net/ipv4/netfilter/ip_tables.c linux-2.6.0-test7/net/ipv4/netfilter/ip_tables.c --- linux-2.6.0-test7.org/net/ipv4/netfilter/ip_tables.c 2003-10-08 21:24:02.000000000 +0200 +++ linux-2.6.0-test7/net/ipv4/netfilter/ip_tables.c 2003-10-10 11:53:17.000000000 +0200 @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -23,8 +24,17 @@ #include #include +#include #include +static const char *hooknames[] = { + [NF_IP_PRE_ROUTING] "PREROUTING", + [NF_IP_LOCAL_IN] "INPUT", + [NF_IP_FORWARD] "FORWARD", + [NF_IP_LOCAL_OUT] "OUTPUT", + [NF_IP_POST_ROUTING] "POSTROUTING", +}; + MODULE_LICENSE("GPL"); MODULE_AUTHOR("Netfilter Core Team "); MODULE_DESCRIPTION("IPv4 packet filter"); @@ -322,6 +332,12 @@ t = ipt_get_target(e); IP_NF_ASSERT(t->u.kernel.target); + + /* The packet traced and the rule isn't an unconditional return/END. */ + if (((*pskb)->nfcache & NFC_TRACE) && e->rulenum) { + nf_log_packet(AF_INET, hook, *pskb, in, out, "TRACE: %s/%s/%u ", + table->name, e->chainname, e->rulenum); + } /* Standard target? */ if (!t->u.kernel.target->target) { int v; @@ -474,6 +490,29 @@ return find_inlist_lock(&ipt_target, name, "ipt_", error, mutex); } +static inline int +find_error_target(struct ipt_entry *s, + struct ipt_entry *e, + char **chainname) +{ + struct ipt_entry_target *t; + static struct ipt_entry *found = NULL; + + if (s == e) { + if (!found) + return 0; + t = ipt_get_target(found); + if (strcmp(t->u.user.name, + IPT_ERROR_TARGET) == 0) { + *chainname = t->data; + return 1; + } + } else + found = s; + + return 0; +} + /* All zeroes == unconditional rule. */ static inline int unconditional(const struct ipt_ip *ip) @@ -493,6 +532,8 @@ mark_source_chains(struct ipt_table_info *newinfo, unsigned int valid_hooks) { unsigned int hook; + char *chainname = NULL; + u_int32_t rulenum; /* No recursion; use packet counter to save back ptrs (reset to 0 as we leave), and comefrom to save source hook bitmask */ @@ -506,6 +547,8 @@ /* Set initial back pointer. */ e->counters.pcnt = pos; + rulenum = 1; + chainname = (char *) hooknames[hook]; for (;;) { struct ipt_standard_target *t @@ -518,6 +561,8 @@ } e->comefrom |= ((1 << hook) | (1 << NF_IP_NUMHOOKS)); + e->rulenum = rulenum++; + e->chainname = chainname; /* Unconditional return/END. */ if (e->target_offset == sizeof(struct ipt_entry) @@ -527,6 +572,10 @@ && unconditional(&e->ip)) { unsigned int oldpos, size; + /* Set unconditional rulenum to zero. */ + e->rulenum = 0; + e->counters.bcnt = 0; + /* Return: backtrack through the last big jump. */ do { @@ -552,6 +601,11 @@ (newinfo->entries + pos); } while (oldpos == pos + e->next_offset); + /* Restore chainname, rulenum. */ + chainname = e->chainname; + rulenum = e->counters.bcnt; + e->counters.bcnt = 0; + /* Move along one */ size = e->next_offset; e = (struct ipt_entry *) @@ -567,6 +621,17 @@ /* This a jump; chase it. */ duprintf("Jump rule %u -> %u\n", pos, newpos); + e->counters.bcnt = rulenum++; + rulenum = 1; + e = (struct ipt_entry *) + (newinfo->entries + newpos); + if (IPT_ENTRY_ITERATE(newinfo->entries, + newinfo->size, + find_error_target, + e, &chainname) == 0) { + printk("ip_tables: table screwed up!\n"); + return 0; + } } else { /* ... this is a fallthru */ newpos = pos + e->next_offset; diff -Nur linux-2.6.0-test7.org/net/ipv4/netfilter/ipt_LOG.c linux-2.6.0-test7/net/ipv4/netfilter/ipt_LOG.c --- linux-2.6.0-test7.org/net/ipv4/netfilter/ipt_LOG.c 2003-10-08 21:24:43.000000000 +0200 +++ linux-2.6.0-test7/net/ipv4/netfilter/ipt_LOG.c 2003-10-10 11:52:57.000000000 +0200 @@ -4,12 +4,14 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include @@ -17,6 +19,10 @@ MODULE_AUTHOR("Netfilter Core Team "); MODULE_DESCRIPTION("iptables syslog logging module"); +static unsigned int nflog = 1; +MODULE_PARM(nflog, "i"); +MODULE_PARM_DESC(nflog, "register as internal netfilter logging module"); + #if 0 #define DEBUGP printk #else @@ -315,28 +321,25 @@ /* maxlen = 230+ 91 + 230 + 252 = 803 */ } -static unsigned int -ipt_log_target(struct sk_buff **pskb, +static void +ipt_log_packet(unsigned int hooknum, + const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, - unsigned int hooknum, - const void *targinfo, - void *userinfo) + const struct ipt_log_info *loginfo, + const char *level_string, + const char *prefix) { - const struct ipt_log_info *loginfo = targinfo; - char level_string[4] = "< >"; - - level_string[1] = '0' + (loginfo->level % 8); spin_lock_bh(&log_lock); printk(level_string); printk("%sIN=%s OUT=%s ", - loginfo->prefix, + prefix == NULL ? loginfo->prefix : prefix, in ? in->name : "", out ? out->name : ""); #ifdef CONFIG_BRIDGE_NETFILTER - if ((*pskb)->nf_bridge) { - struct net_device *physindev = (*pskb)->nf_bridge->physindev; - struct net_device *physoutdev = (*pskb)->nf_bridge->physoutdev; + if (skb->nf_bridge) { + struct net_device *physindev = skb->nf_bridge->physindev; + struct net_device *physoutdev = skb->nf_bridge->physoutdev; if (physindev && in != physindev) printk("PHYSIN=%s ", physindev->name); @@ -348,25 +351,56 @@ if (in && !out) { /* MAC logging for input chain only. */ printk("MAC="); - if ((*pskb)->dev && (*pskb)->dev->hard_header_len - && (*pskb)->mac.raw != (void*)(*pskb)->nh.iph) { + if (skb->dev && skb->dev->hard_header_len + && skb->mac.raw != (void*)skb->nh.iph) { int i; - unsigned char *p = (*pskb)->mac.raw; - for (i = 0; i < (*pskb)->dev->hard_header_len; i++,p++) + unsigned char *p = skb->mac.raw; + for (i = 0; i < skb->dev->hard_header_len; i++,p++) printk("%02x%c", *p, - i==(*pskb)->dev->hard_header_len - 1 + i==skb->dev->hard_header_len - 1 ? ' ':':'); } else printk(" "); } - dump_packet(loginfo, *pskb, 0); + dump_packet(loginfo, skb, 0); printk("\n"); spin_unlock_bh(&log_lock); +} + +static unsigned int +ipt_log_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_log_info *loginfo = targinfo; + char level_string[4] = "< >"; + + level_string[1] = '0' + (loginfo->level % 8); + ipt_log_packet(hooknum, *pskb, in, out, loginfo, level_string, NULL); return IPT_CONTINUE; } +static void +ipt_logfn(unsigned int hooknum, + const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const char *prefix) +{ + struct ipt_log_info loginfo = { + .level = 0, + .logflags = IPT_LOG_MASK, + .prefix = "" + }; + + ipt_log_packet(hooknum, skb, in, out, &loginfo, KERN_WARNING, prefix); +} + static int ipt_log_checkentry(const char *tablename, const struct ipt_entry *e, void *targinfo, @@ -406,12 +440,17 @@ { if (ipt_register_target(&ipt_log_reg)) return -EINVAL; + if (nflog) + nf_log_register(PF_INET, &ipt_logfn); return 0; } static void __exit fini(void) { + if (nflog) + nf_log_unregister(PF_INET, &ipt_logfn); + ipt_unregister_target(&ipt_log_reg); } diff -Nur linux-2.6.0-test7.org/net/ipv4/netfilter/ipt_NOTRACK.c linux-2.6.0-test7/net/ipv4/netfilter/ipt_NOTRACK.c --- linux-2.6.0-test7.org/net/ipv4/netfilter/ipt_NOTRACK.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.0-test7/net/ipv4/netfilter/ipt_NOTRACK.c 2003-10-10 11:53:17.000000000 +0200 @@ -0,0 +1,79 @@ +/* This is a module which is used for setting up fake conntracks + * on packets so that they are not seen by the conntrack/NAT code. + */ +#include +#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) +{ + /* Previously seen (loopback)? Ignore. */ + if ((*pskb)->nfct != NULL) + return IPT_CONTINUE; + + /* Attach fake conntrack entry. + If there is a real ct entry correspondig to this packet, + it'll hang aroun till timing out. We don't deal with it + for performance reasons. JK */ + (*pskb)->nfct = &ip_conntrack_untracked.infos[IP_CT_NEW]; + nf_conntrack_get((*pskb)->nfct); + + 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 != 0) { + printk(KERN_WARNING "NOTRACK: targinfosize %u != 0\n", + targinfosize); + return 0; + } + + if (strcmp(tablename, "raw") != 0) { + printk(KERN_WARNING "NOTRACK: can only be called from \"raw\" table, not \"%s\"\n", tablename); + return 0; + } + + return 1; +} + +static struct ipt_target ipt_notrack_reg = { + .name = "NOTRACK", + .target = target, + .checkentry = checkentry, + .destroy = NULL, + .me = THIS_MODULE, +}; + +static int __init init(void) +{ + if (ipt_register_target(&ipt_notrack_reg)) + return -EINVAL; + + return 0; +} + +static void __exit fini(void) +{ + ipt_unregister_target(&ipt_notrack_reg); +} + +module_init(init); +module_exit(fini); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Netfilter Core Team "); +MODULE_DESCRIPTION("IPv4 NOTRACK target"); diff -Nur linux-2.6.0-test7.org/net/ipv4/netfilter/ipt_TRACE.c linux-2.6.0-test7/net/ipv4/netfilter/ipt_TRACE.c --- linux-2.6.0-test7.org/net/ipv4/netfilter/ipt_TRACE.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.0-test7/net/ipv4/netfilter/ipt_TRACE.c 2003-10-10 11:53:17.000000000 +0200 @@ -0,0 +1,67 @@ +/* This is a module which is used for setting + * the NFC_TRACE flag in the nfcache field of an skb. + */ +#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) +{ + (*pskb)->nfcache |= NFC_TRACE; + 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 != 0) { + printk(KERN_WARNING "TRACE: targinfosize %u != 0\n", + targinfosize); + return 0; + } + + if (strcmp(tablename, "raw") != 0) { + printk(KERN_WARNING "TRACE: can only be called from \"raw\" table, not \"%s\"\n", tablename); + return 0; + } + + return 1; +} + +static struct ipt_target ipt_trace_reg = { + .name = "TRACE", + .target = target, + .checkentry = checkentry, + .destroy = NULL, + .me = THIS_MODULE, +}; + +static int __init init(void) +{ + if (ipt_register_target(&ipt_trace_reg)) + return -EINVAL; + + return 0; +} + +static void __exit fini(void) +{ + ipt_unregister_target(&ipt_trace_reg); +} + +module_init(init); +module_exit(fini); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Netfilter Core Team "); +MODULE_DESCRIPTION("IPv4 TRACE target"); diff -Nur linux-2.6.0-test7.org/net/ipv4/netfilter/ipt_ULOG.c linux-2.6.0-test7/net/ipv4/netfilter/ipt_ULOG.c --- linux-2.6.0-test7.org/net/ipv4/netfilter/ipt_ULOG.c 2003-10-08 21:24:03.000000000 +0200 +++ linux-2.6.0-test7/net/ipv4/netfilter/ipt_ULOG.c 2003-10-10 11:52:57.000000000 +0200 @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -75,6 +76,10 @@ MODULE_PARM(flushtimeout, "i"); MODULE_PARM_DESC(flushtimeout, "buffer flush timeout"); +static unsigned int nflog = 1; +MODULE_PARM(nflog, "i"); +MODULE_PARM_DESC(nflog, "register as internal netfilter logging module"); + /* global data structures */ typedef struct { @@ -152,17 +157,17 @@ return skb; } -static unsigned int ipt_ulog_target(struct sk_buff **pskb, - const struct net_device *in, - const struct net_device *out, - unsigned int hooknum, - const void *targinfo, void *userinfo) +static void ipt_ulog_packet(unsigned int hooknum, + const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const struct ipt_ulog_info *loginfo, + const char *prefix) { ulog_buff_t *ub; ulog_packet_msg_t *pm; size_t size, copy_len; struct nlmsghdr *nlh; - struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo; /* ffs == find first bit set, necessary because userspace * is already shifting groupnumber, but we need unshifted. @@ -171,8 +176,8 @@ /* calculate the size of the skb needed */ if ((loginfo->copy_range == 0) || - (loginfo->copy_range > (*pskb)->len)) { - copy_len = (*pskb)->len; + (loginfo->copy_range > skb->len)) { + copy_len = skb->len; } else { copy_len = loginfo->copy_range; } @@ -209,19 +214,21 @@ /* copy hook, prefix, timestamp, payload, etc. */ pm->data_len = copy_len; - pm->timestamp_sec = (*pskb)->stamp.tv_sec; - pm->timestamp_usec = (*pskb)->stamp.tv_usec; - pm->mark = (*pskb)->nfmark; + pm->timestamp_sec = skb->stamp.tv_sec; + pm->timestamp_usec = skb->stamp.tv_usec; + pm->mark = skb->nfmark; pm->hook = hooknum; - if (loginfo->prefix[0] != '\0') + if (prefix != NULL) + strncpy(pm->prefix, prefix, sizeof(pm->prefix)); + else if (loginfo->prefix[0] != '\0') strncpy(pm->prefix, loginfo->prefix, sizeof(pm->prefix)); else *(pm->prefix) = '\0'; if (in && in->hard_header_len > 0 - && (*pskb)->mac.raw != (void *) (*pskb)->nh.iph + && skb->mac.raw != (void *) skb->nh.iph && in->hard_header_len <= ULOG_MAC_LEN) { - memcpy(pm->mac, (*pskb)->mac.raw, in->hard_header_len); + memcpy(pm->mac, skb->mac.raw, in->hard_header_len); pm->mac_len = in->hard_header_len; } else pm->mac_len = 0; @@ -236,8 +243,8 @@ else pm->outdev_name[0] = '\0'; - /* copy_len <= (*pskb)->len, so can't fail. */ - if (skb_copy_bits(*pskb, 0, pm->payload, copy_len) < 0) + /* copy_len <= skb->len, so can't fail. */ + if (skb_copy_bits(skb, 0, pm->payload, copy_len) < 0) BUG(); /* check if we are building multi-part messages */ @@ -261,8 +268,7 @@ UNLOCK_BH(&ulog_lock); - return IPT_CONTINUE; - + return; nlmsg_failure: PRINTR("ipt_ULOG: error during NLMSG_PUT\n"); @@ -271,8 +277,35 @@ PRINTR("ipt_ULOG: Error building netlink message\n"); UNLOCK_BH(&ulog_lock); +} + +static unsigned int ipt_ulog_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_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo; - return IPT_CONTINUE; + ipt_ulog_packet(hooknum, *pskb, in, out, loginfo, NULL); + + return IPT_CONTINUE; +} + +static void ipt_logfn(unsigned int hooknum, + const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const char *prefix) +{ + struct ipt_ulog_info loginfo = { + .nl_group = NFLOG_DEFAULT_NLGROUP, + .copy_range = 0, + .qthreshold = NFLOG_DEFAULT_QTHRESHOLD, + .prefix = "" + }; + + ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix); } static int ipt_ulog_checkentry(const char *tablename, @@ -337,6 +370,9 @@ return -EINVAL; } + if (nflog) + nf_log_register(PF_INET, &ipt_logfn); + return 0; } @@ -347,6 +383,9 @@ DEBUGP("ipt_ULOG: cleanup_module\n"); + if (nflog) + nf_log_unregister(PF_INET, &ipt_logfn); + ipt_unregister_target(&ipt_ulog_reg); sock_release(nflognl->sk_socket); diff -Nur linux-2.6.0-test7.org/net/ipv4/netfilter/ipt_conntrack.c linux-2.6.0-test7/net/ipv4/netfilter/ipt_conntrack.c --- linux-2.6.0-test7.org/net/ipv4/netfilter/ipt_conntrack.c 2003-10-08 21:24:44.000000000 +0200 +++ linux-2.6.0-test7/net/ipv4/netfilter/ipt_conntrack.c 2003-10-10 11:53:17.000000000 +0200 @@ -29,7 +29,9 @@ #define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg)) - if (ct) + if (skb->nfct == &ip_conntrack_untracked.infos[IP_CT_NEW]) + statebit = IPT_CONNTRACK_STATE_UNTRACKED; + else if (ct) statebit = IPT_CONNTRACK_STATE_BIT(ctinfo); else statebit = IPT_CONNTRACK_STATE_INVALID; diff -Nur linux-2.6.0-test7.org/net/ipv4/netfilter/ipt_sctp.c linux-2.6.0-test7/net/ipv4/netfilter/ipt_sctp.c --- linux-2.6.0-test7.org/net/ipv4/netfilter/ipt_sctp.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.0-test7/net/ipv4/netfilter/ipt_sctp.c 2003-10-10 11:53:27.000000000 +0200 @@ -0,0 +1,125 @@ +/* IP tables module for matching the SCTP header + * + * $ipt_sctp.c,v 1.3 2002/05/29 15:09:00 laforge Exp$ + * + * (C) 2003 by Harald Welte + * + * This software is distributed under the terms GNU GPL v2 + */ + +#include +#include +#include + +#include +#include + +MODULE_AUTHOR("Harald Welte "); +MODULE_DESCRIPTION("IP tables SCTP matching module"); +MODULE_LICENSE("GPL"); + +/* 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 chunk_match(const struct sk_buff *skb, u_int32_t chunks, u_int32_t chunk_mask) +{ + sctp_chunkhdr_t *ch = (sctp_chunkhdr_t *) skb->data; + + u_int32_t chunks_present = 0; + + do { + u_int8_t *ch_end; + ch_end = ((u_int8_t *) ch) + WORD_ROUND(ntohs(ch->length)); + + if (ch->type < 32) + chunks_present |= (1 << ch_type); + else if (ch->type == SCTP_CID_ASCONF) + chunks_present |= (1 << 31); + else if (ch->type == SCTP_CID_ASCONF_ACK) + chunks_present |= (1 << 30); + + ch = (sctp_chunkhdr_t *) ch_end; + } while (ch_end < skb->tail); + + return ((chunks_present& chunk_mask) == chunks); +} + +static int match(const struct sk_buff *skb, const struct net_device *in, + const struct net_device *out, const void *matchinfo, + int offset, const void *hdr, u_int16_t datalen, + int *hotdrop) +{ + const struct ipt_sctp_info *info = matchinfo; + const struct iphdr *iph = skb->nh.iph; + const struct sctphdr *sh = (struct sctphdr *) skb->h.raw; + + if (iph->protocol != IPPROTO_SCTP) + return 0; + + if (offset == 1) { + duprintf("Dropping evil SCTP offset=1 frag.\n"); + *hotdrop = 1; + return 0; + } else if (offset == 0 && datalen < sizeof(struct sctphdr)) { + /* We've been askd o examine this packet, and we can't. + * Hence, no choice but to drop. */ + duprintf("Dropping evil SCTP offset=0 tinygram.\n"); + *hotdrop = 1; + return 0; + } + + return (!offset + && port_match(info->spts[0], info->spts[1], + ntohs(sh->source), + !!(info->invflags & IPT_SCTP_INV_SRCPT)) + && port_match(info->dpts[0], info->dpts[1], + ntohs(sh->dest), + !!(info->invflags & IPT_SCTP_INV_DSTPT)) + && chunk_match(skb, info->chunks, info->chunk_mask) + ); +} + +static int checkentry(const char *tablename, const struct ipt_ip *ip, + void *matchinfo, unsigned int matchsize, + unsigned int hook_mask) +{ + const struct ipt_sctp_info *info = matchinfo; + + if (matchsize != IPT_ALIGN(sizeof(struct ipt_sctp_info))) + return 0; + + if (ip->proto != IPPROTO_SCTP && !(ip->invflags & IPT_INV_PROTO)) + return 0; + + if !(info->invflags & ~IPT_SCTP_INV_MASK) + return 0; + + return 1; +} + +static struct ipt_match sctp_match = { + .name = "sctp", + .match = &match, + .checkentry = &checkentry, + .me = THIS_MODULE, +}; + +static int __init init(void) +{ + return ipt_register_match(&sctp_match); +} + +static void __exit fini(void) +{ + ipt_unregister_match(&sctp_match); +} + +module_init(init); +module_exit(fini); diff -Nur linux-2.6.0-test7.org/net/ipv4/netfilter/ipt_state.c linux-2.6.0-test7/net/ipv4/netfilter/ipt_state.c --- linux-2.6.0-test7.org/net/ipv4/netfilter/ipt_state.c 2003-10-08 21:24:53.000000000 +0200 +++ linux-2.6.0-test7/net/ipv4/netfilter/ipt_state.c 2003-10-10 11:53:17.000000000 +0200 @@ -23,10 +23,12 @@ enum ip_conntrack_info ctinfo; unsigned int statebit; - if (!ip_conntrack_get((struct sk_buff *)skb, &ctinfo)) - statebit = IPT_STATE_INVALID; - else + if (skb->nfct == &ip_conntrack_untracked.infos[IP_CT_NEW]) + statebit = IPT_STATE_UNTRACKED; + else if (ip_conntrack_get((struct sk_buff *)skb, &ctinfo)) statebit = IPT_STATE_BIT(ctinfo); + else + statebit = IPT_STATE_INVALID; return (sinfo->statemask & statebit); } diff -Nur linux-2.6.0-test7.org/net/ipv4/netfilter/iptable_filter.c linux-2.6.0-test7/net/ipv4/netfilter/iptable_filter.c --- linux-2.6.0-test7.org/net/ipv4/netfilter/iptable_filter.c 2003-10-08 21:24:04.000000000 +0200 +++ linux-2.6.0-test7/net/ipv4/netfilter/iptable_filter.c 2003-10-10 11:53:17.000000000 +0200 @@ -52,7 +52,7 @@ 0, sizeof(struct ipt_entry), sizeof(struct ipt_standard), - 0, { 0, 0 }, { } }, + 0, NULL, 0, { 0, 0 }, { } }, { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } }, -NF_ACCEPT - 1 } }, /* FORWARD */ @@ -60,7 +60,7 @@ 0, sizeof(struct ipt_entry), sizeof(struct ipt_standard), - 0, { 0, 0 }, { } }, + 0, NULL, 0, { 0, 0 }, { } }, { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } }, -NF_ACCEPT - 1 } }, /* LOCAL_OUT */ @@ -68,7 +68,7 @@ 0, sizeof(struct ipt_entry), sizeof(struct ipt_standard), - 0, { 0, 0 }, { } }, + 0, NULL, 0, { 0, 0 }, { } }, { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } }, -NF_ACCEPT - 1 } } }, @@ -77,7 +77,7 @@ 0, sizeof(struct ipt_entry), sizeof(struct ipt_error), - 0, { 0, 0 }, { } }, + 0, NULL, 0, { 0, 0 }, { } }, { { { { IPT_ALIGN(sizeof(struct ipt_error_target)), IPT_ERROR_TARGET } }, { } }, "ERROR" diff -Nur linux-2.6.0-test7.org/net/ipv4/netfilter/iptable_mangle.c linux-2.6.0-test7/net/ipv4/netfilter/iptable_mangle.c --- linux-2.6.0-test7.org/net/ipv4/netfilter/iptable_mangle.c 2003-10-08 21:24:43.000000000 +0200 +++ linux-2.6.0-test7/net/ipv4/netfilter/iptable_mangle.c 2003-10-10 11:53:17.000000000 +0200 @@ -69,7 +69,7 @@ 0, sizeof(struct ipt_entry), sizeof(struct ipt_standard), - 0, { 0, 0 }, { } }, + 0, NULL, 0, { 0, 0 }, { } }, { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } }, -NF_ACCEPT - 1 } }, /* LOCAL_IN */ @@ -77,7 +77,7 @@ 0, sizeof(struct ipt_entry), sizeof(struct ipt_standard), - 0, { 0, 0 }, { } }, + 0, NULL, 0, { 0, 0 }, { } }, { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } }, -NF_ACCEPT - 1 } }, /* FORWARD */ @@ -85,7 +85,7 @@ 0, sizeof(struct ipt_entry), sizeof(struct ipt_standard), - 0, { 0, 0 }, { } }, + 0, NULL, 0, { 0, 0 }, { } }, { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } }, -NF_ACCEPT - 1 } }, /* LOCAL_OUT */ @@ -93,7 +93,7 @@ 0, sizeof(struct ipt_entry), sizeof(struct ipt_standard), - 0, { 0, 0 }, { } }, + 0, NULL, 0, { 0, 0 }, { } }, { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } }, -NF_ACCEPT - 1 } }, /* POST_ROUTING */ @@ -101,7 +101,7 @@ 0, sizeof(struct ipt_entry), sizeof(struct ipt_standard), - 0, { 0, 0 }, { } }, + 0, NULL, 0, { 0, 0 }, { } }, { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } }, -NF_ACCEPT - 1 } }, }, @@ -110,7 +110,7 @@ 0, sizeof(struct ipt_entry), sizeof(struct ipt_error), - 0, { 0, 0 }, { } }, + 0, NULL, 0, { 0, 0 }, { } }, { { { { IPT_ALIGN(sizeof(struct ipt_error_target)), IPT_ERROR_TARGET } }, { } }, "ERROR" diff -Nur linux-2.6.0-test7.org/net/ipv4/netfilter/iptable_raw.c linux-2.6.0-test7/net/ipv4/netfilter/iptable_raw.c --- linux-2.6.0-test7.org/net/ipv4/netfilter/iptable_raw.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.0-test7/net/ipv4/netfilter/iptable_raw.c 2003-10-10 11:53:17.000000000 +0200 @@ -0,0 +1,153 @@ +/* + * 'raw' table, which is the very first hooked in at PRE_ROUTING and LOCAL_OUT . + * + * Copyright (C) 2003 Jozsef Kadlecsik + */ +#include +#include + +#define RAW_VALID_HOOKS ((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT)) + +/* Standard entry. */ +struct ipt_standard +{ + struct ipt_entry entry; + struct ipt_standard_target target; +}; + +struct ipt_error_target +{ + struct ipt_entry_target target; + char errorname[IPT_FUNCTION_MAXNAMELEN]; +}; + +struct ipt_error +{ + struct ipt_entry entry; + struct ipt_error_target target; +}; + +static struct +{ + struct ipt_replace repl; + struct ipt_standard entries[2]; + struct ipt_error term; +} initial_table __initdata += { { "raw", RAW_VALID_HOOKS, 3, + sizeof(struct ipt_standard) * 2 + sizeof(struct ipt_error), + { [NF_IP_PRE_ROUTING] 0, + [NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) }, + { [NF_IP_PRE_ROUTING] 0, + [NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) }, + 0, NULL, { } }, + { + /* PRE_ROUTING */ + { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 }, + 0, + sizeof(struct ipt_entry), + sizeof(struct ipt_standard), + 0, NULL, 0, { 0, 0 }, { } }, + { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } }, + -NF_ACCEPT - 1 } }, + /* LOCAL_OUT */ + { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 }, + 0, + sizeof(struct ipt_entry), + sizeof(struct ipt_standard), + 0, NULL, 0, { 0, 0 }, { } }, + { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } }, + -NF_ACCEPT - 1 } } + }, + /* ERROR */ + { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 }, + 0, + sizeof(struct ipt_entry), + sizeof(struct ipt_error), + 0, NULL, 0, { 0, 0 }, { } }, + { { { { IPT_ALIGN(sizeof(struct ipt_error_target)), IPT_ERROR_TARGET } }, + { } }, + "ERROR" + } + } +}; + +static struct ipt_table packet_raw = { + .name = "raw", + .table = &initial_table.repl, + .valid_hooks = RAW_VALID_HOOKS, + .lock = RW_LOCK_UNLOCKED, + .me = THIS_MODULE, +}; + +/* The work comes in here from netfilter.c. */ +static unsigned int +ipt_hook(unsigned int hook, + struct sk_buff **pskb, + const struct net_device *in, + const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + return ipt_do_table(pskb, hook, in, out, &packet_raw, NULL); +} + +/* 'raw' is the very first table. */ +static struct nf_hook_ops ipt_ops[] = { + { /* PRE_ROUTING hook */ + .hook = ipt_hook, + .owner = THIS_MODULE, + .pf = PF_INET, + .hooknum = NF_IP_PRE_ROUTING, + .priority = NF_IP_PRI_RAW, + }, + { /* LOCAL_OUT hook */ + .hook = ipt_hook, + .owner = THIS_MODULE, + .pf = PF_INET, + .hooknum = NF_IP_LOCAL_OUT, + .priority = NF_IP_PRI_RAW, + }, +}; + +static int __init init(void) +{ + int ret; + + /* Register table */ + ret = ipt_register_table(&packet_raw); + if (ret < 0) + return ret; + + /* Register hooks */ + ret = nf_register_hook(&ipt_ops[0]); + if (ret < 0) + goto cleanup_table; + + ret = nf_register_hook(&ipt_ops[1]); + if (ret < 0) + goto cleanup_hook0; + + return ret; + + cleanup_hook0: + nf_unregister_hook(&ipt_ops[0]); + cleanup_table: + ipt_unregister_table(&packet_raw); + + return ret; +} + +static void __exit fini(void) +{ + unsigned int i; + + for (i = 0; i < sizeof(ipt_ops)/sizeof(struct nf_hook_ops); i++) + nf_unregister_hook(&ipt_ops[i]); + + ipt_unregister_table(&packet_raw); +} + +module_init(init); +module_exit(fini); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Netfilter Core Team "); +MODULE_DESCRIPTION("IPv4 raw table"); diff -Nur linux-2.6.0-test7.org/net/ipv6/netfilter/Kconfig linux-2.6.0-test7/net/ipv6/netfilter/Kconfig --- linux-2.6.0-test7.org/net/ipv6/netfilter/Kconfig 2003-10-08 21:24:43.000000000 +0200 +++ linux-2.6.0-test7/net/ipv6/netfilter/Kconfig 2003-10-10 11:53:17.000000000 +0200 @@ -217,6 +217,31 @@ To compile it as a module, choose M here. If unsure, say N. +config IP6_NF_RAW + tristate "Raw table" + depends on IP6_NF_IPTABLES + help + This option adds a `raw' table to iptables: see the man page for + iptables(8). This table is the very first in the netfilter + framework and hooks in at the PREROUTING and OUTPUT chains. + The TRACE target can be used in this table only. + + To compile it as a module, choose M here. If unsure, say N. + +config IP6_NF_TARGET_TRACE + tristate "TRACE target support" + depends on IP6_NF_RAW + help + The TRACE target allows packets to be traced as those matches + any subsequent rule in any IPv6 netfilter table/rule. The matched + rule and the packet is logged with the prefix + + TRACE: tablename/chainname/rulenum + + if the ip6t_LOG target is loaded in. + + To compile it as a module, choose M here. If unsure, say N. + #dep_tristate ' LOG target support' CONFIG_IP6_NF_TARGET_LOG $CONFIG_IP6_NF_IPTABLES endmenu diff -Nur linux-2.6.0-test7.org/net/ipv6/netfilter/Makefile linux-2.6.0-test7/net/ipv6/netfilter/Makefile --- linux-2.6.0-test7.org/net/ipv6/netfilter/Makefile 2003-10-08 21:24:15.000000000 +0200 +++ linux-2.6.0-test7/net/ipv6/netfilter/Makefile 2003-10-10 11:53:17.000000000 +0200 @@ -18,7 +18,9 @@ obj-$(CONFIG_IP6_NF_MATCH_OWNER) += ip6t_owner.o obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o +obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o +obj-$(CONFIG_IP6_NF_TARGET_TRACE) += ip6t_TRACE.o obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o diff -Nur linux-2.6.0-test7.org/net/ipv6/netfilter/ip6_tables.c linux-2.6.0-test7/net/ipv6/netfilter/ip6_tables.c --- linux-2.6.0-test7.org/net/ipv6/netfilter/ip6_tables.c 2003-10-08 21:24:43.000000000 +0200 +++ linux-2.6.0-test7/net/ipv6/netfilter/ip6_tables.c 2003-10-10 11:53:18.000000000 +0200 @@ -12,6 +12,7 @@ */ #include #include +#include #include #include #include @@ -24,8 +25,17 @@ #include #include +#include #include +static const char *hook6names[] = { + [NF_IP6_PRE_ROUTING] "PREROUTING", + [NF_IP6_LOCAL_IN] "INPUT", + [NF_IP6_FORWARD] "FORWARD", + [NF_IP6_LOCAL_OUT] "OUTPUT", + [NF_IP6_POST_ROUTING] "POSTROUTING", +}; + MODULE_LICENSE("GPL"); MODULE_AUTHOR("Netfilter Core Team "); MODULE_DESCRIPTION("IPv6 packet filter"); @@ -403,6 +413,12 @@ t = ip6t_get_target(e); IP_NF_ASSERT(t->u.kernel.target); + + /* The packet traced and the rule isn't an unconditional return/END. */ + if (((*pskb)->nfcache & NFC_TRACE) && e->rulenum) { + nf_log_packet(AF_INET6, hook, *pskb, in, out, "TRACE: %s/%s/%u ", + table->name, e->chainname, e->rulenum); + } /* Standard target? */ if (!t->u.kernel.target->target) { int v; @@ -556,6 +572,29 @@ return find_inlist_lock(&ip6t_target, name, "ip6t_", error, mutex); } +static inline int +find_error_target(struct ip6t_entry *s, + struct ip6t_entry *e, + char **chainname) +{ + struct ip6t_entry_target *t; + static struct ip6t_entry *found = NULL; + + if (s == e) { + if (!found) + return 0; + t = ip6t_get_target(found); + if (strcmp(t->u.user.name, + IP6T_ERROR_TARGET) == 0) { + *chainname = t->data; + return 1; + } + } else + found = s; + + return 0; +} + /* All zeroes == unconditional rule. */ static inline int unconditional(const struct ip6t_ip6 *ipv6) @@ -575,6 +614,8 @@ mark_source_chains(struct ip6t_table_info *newinfo, unsigned int valid_hooks) { unsigned int hook; + char *chainname = NULL; + u_int32_t rulenum; /* No recursion; use packet counter to save back ptrs (reset to 0 as we leave), and comefrom to save source hook bitmask */ @@ -588,6 +629,8 @@ /* Set initial back pointer. */ e->counters.pcnt = pos; + rulenum = 1; + chainname = (char *) hook6names[hook]; for (;;) { struct ip6t_standard_target *t @@ -600,6 +643,8 @@ } e->comefrom |= ((1 << hook) | (1 << NF_IP6_NUMHOOKS)); + e->rulenum = rulenum++; + e->chainname = chainname; /* Unconditional return/END. */ if (e->target_offset == sizeof(struct ip6t_entry) @@ -609,6 +654,10 @@ && unconditional(&e->ipv6)) { unsigned int oldpos, size; + /* Set unconditional rulenum to zero. */ + e->rulenum = 0; + e->counters.bcnt = 0; + /* Return: backtrack through the last big jump. */ do { @@ -634,6 +683,11 @@ (newinfo->entries + pos); } while (oldpos == pos + e->next_offset); + /* Restore chainname, rulenum. */ + chainname = e->chainname; + rulenum = e->counters.bcnt; + e->counters.bcnt = 0; + /* Move along one */ size = e->next_offset; e = (struct ip6t_entry *) @@ -649,6 +703,17 @@ /* This a jump; chase it. */ duprintf("Jump rule %u -> %u\n", pos, newpos); + e->counters.bcnt = rulenum++; + rulenum = 1; + e = (struct ip6t_entry *) + (newinfo->entries + newpos); + if (IP6T_ENTRY_ITERATE(newinfo->entries, + newinfo->size, + find_error_target, + e, &chainname) == 0) { + printk("ip6_tables: table screwed up!\n"); + return 0; + } } else { /* ... this is a fallthru */ newpos = pos + e->next_offset; diff -Nur linux-2.6.0-test7.org/net/ipv6/netfilter/ip6t_LOG.c linux-2.6.0-test7/net/ipv6/netfilter/ip6t_LOG.c --- linux-2.6.0-test7.org/net/ipv6/netfilter/ip6t_LOG.c 2003-10-08 21:24:03.000000000 +0200 +++ linux-2.6.0-test7/net/ipv6/netfilter/ip6t_LOG.c 2003-10-10 11:52:57.000000000 +0200 @@ -3,18 +3,24 @@ */ #include #include +#include #include #include #include #include #include #include +#include #include MODULE_AUTHOR("Jan Rekorajski "); MODULE_DESCRIPTION("IP6 tables LOG target module"); MODULE_LICENSE("GPL"); +static unsigned int nflog = 1; +MODULE_PARM(nflog, "i"); +MODULE_PARM_DESC(nflog, "register as internal netfilter logging module"); + struct in_device; #include #include @@ -256,40 +262,38 @@ } } -static unsigned int -ip6t_log_target(struct sk_buff **pskb, - unsigned int hooknum, - const struct net_device *in, - const struct net_device *out, - const void *targinfo, - void *userinfo) +static void +ip6t_log_packet(unsigned int hooknum, + const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const struct ip6t_log_info *loginfo, + const char *level_string, + const char *prefix) { - struct ipv6hdr *ipv6h = (*pskb)->nh.ipv6h; - const struct ip6t_log_info *loginfo = targinfo; - char level_string[4] = "< >"; + struct ipv6hdr *ipv6h = skb->nh.ipv6h; - level_string[1] = '0' + (loginfo->level % 8); spin_lock_bh(&log_lock); printk(level_string); printk("%sIN=%s OUT=%s ", - loginfo->prefix, + prefix == NULL ? loginfo->prefix : prefix, in ? in->name : "", out ? out->name : ""); if (in && !out) { /* MAC logging for input chain only. */ printk("MAC="); - if ((*pskb)->dev && (*pskb)->dev->hard_header_len && (*pskb)->mac.raw != (void*)ipv6h) { - if ((*pskb)->dev->type != ARPHRD_SIT){ + if (skb->dev && skb->dev->hard_header_len && skb->mac.raw != (void*)ipv6h) { + if (skb->dev->type != ARPHRD_SIT){ int i; - unsigned char *p = (*pskb)->mac.raw; - for (i = 0; i < (*pskb)->dev->hard_header_len; i++,p++) + unsigned char *p = skb->mac.raw; + for (i = 0; i < skb->dev->hard_header_len; i++,p++) printk("%02x%c", *p, - i==(*pskb)->dev->hard_header_len - 1 + i==skb->dev->hard_header_len - 1 ? ' ':':'); } else { int i; - unsigned char *p = (*pskb)->mac.raw; - if ( p - (ETH_ALEN*2+2) > (*pskb)->head ){ + unsigned char *p = skb->mac.raw; + if ( p - (ETH_ALEN*2+2) > skb->head ){ p -= (ETH_ALEN+2); for (i = 0; i < (ETH_ALEN); i++,p++) printk("%02x%s", *p, @@ -300,10 +304,10 @@ i == ETH_ALEN-1 ? ' ' : ':'); } - if (((*pskb)->dev->addr_len == 4) && - (*pskb)->dev->hard_header_len > 20){ + if ((skb->dev->addr_len == 4) && + skb->dev->hard_header_len > 20){ printk("TUNNEL="); - p = (*pskb)->mac.raw + 12; + p = skb->mac.raw + 12; for (i = 0; i < 4; i++,p++) printk("%3d%s", *p, i == 3 ? "->" : "."); @@ -319,10 +323,41 @@ dump_packet(loginfo, ipv6h, 1); printk("\n"); spin_unlock_bh(&log_lock); +} + +static unsigned int +ip6t_log_target(struct sk_buff **pskb, + unsigned int hooknum, + const struct net_device *in, + const struct net_device *out, + const void *targinfo, + void *userinfo) +{ + const struct ip6t_log_info *loginfo = targinfo; + char level_string[4] = "< >"; + + level_string[1] = '0' + (loginfo->level % 8); + ip6t_log_packet(hooknum, *pskb, in, out, loginfo, level_string, NULL); return IP6T_CONTINUE; } +static void +ip6t_logfn(unsigned int hooknum, + const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const char *prefix) +{ + struct ip6t_log_info loginfo = { + .level = 0, + .logflags = IP6T_LOG_MASK, + .prefix = "" + }; + + ip6t_log_packet(hooknum, skb, in, out, &loginfo, KERN_WARNING, prefix); +} + static int ip6t_log_checkentry(const char *tablename, const struct ip6t_entry *e, void *targinfo, @@ -359,12 +394,17 @@ { if (ip6t_register_target(&ip6t_log_reg)) return -EINVAL; + if (nflog) + nf_log_register(PF_INET6, &ip6t_logfn); return 0; } static void __exit fini(void) { + if (nflog) + nf_log_register(PF_INET6, &ip6t_logfn); + ip6t_unregister_target(&ip6t_log_reg); } diff -Nur linux-2.6.0-test7.org/net/ipv6/netfilter/ip6t_TRACE.c linux-2.6.0-test7/net/ipv6/netfilter/ip6t_TRACE.c --- linux-2.6.0-test7.org/net/ipv6/netfilter/ip6t_TRACE.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.0-test7/net/ipv6/netfilter/ip6t_TRACE.c 2003-10-10 11:53:18.000000000 +0200 @@ -0,0 +1,69 @@ +/* This is a module which is used for setting + * the NFC_TRACE flag in the nfcache field of an skb. + */ +#include +#include + +#include + +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) +{ + (*pskb)->nfcache |= NFC_TRACE; + 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 != 0) { + printk(KERN_WARNING "TRACE: targinfosize %u != 0\n", + targinfosize); + return 0; + } + + if (strcmp(tablename, "raw") != 0) { + printk(KERN_WARNING "TRACE: can only be called from \"raw\" table, not \"%s\"\n", tablename); + return 0; + } + + return 1; +} + +static struct ip6t_target ip6t_trace_reg = { + .name = "TRACE", + .target = target, + .checkentry = checkentry, + .destroy = NULL, + .me = THIS_MODULE, +}; + +static int __init init(void) +{ + if (ip6t_register_target(&ip6t_trace_reg)) + return -EINVAL; + + return 0; +} + +static void __exit fini(void) +{ + ip6t_unregister_target(&ip6t_trace_reg); +} + +module_init(init); +module_exit(fini); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Netfilter Core Team "); +MODULE_DESCRIPTION("IPv6 TRACE target"); + \ No newline at end of file diff -Nur linux-2.6.0-test7.org/net/ipv6/netfilter/ip6table_filter.c linux-2.6.0-test7/net/ipv6/netfilter/ip6table_filter.c --- linux-2.6.0-test7.org/net/ipv6/netfilter/ip6table_filter.c 2003-10-08 21:24:01.000000000 +0200 +++ linux-2.6.0-test7/net/ipv6/netfilter/ip6table_filter.c 2003-10-10 11:53:18.000000000 +0200 @@ -52,7 +52,7 @@ 0, sizeof(struct ip6t_entry), sizeof(struct ip6t_standard), - 0, { 0, 0 }, { } }, + 0, NULL, 0, { 0, 0 }, { } }, { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } }, -NF_ACCEPT - 1 } }, /* FORWARD */ @@ -60,7 +60,7 @@ 0, sizeof(struct ip6t_entry), sizeof(struct ip6t_standard), - 0, { 0, 0 }, { } }, + 0, NULL, 0, { 0, 0 }, { } }, { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } }, -NF_ACCEPT - 1 } }, /* LOCAL_OUT */ @@ -68,7 +68,7 @@ 0, sizeof(struct ip6t_entry), sizeof(struct ip6t_standard), - 0, { 0, 0 }, { } }, + 0, NULL, 0, { 0, 0 }, { } }, { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } }, -NF_ACCEPT - 1 } } }, @@ -77,7 +77,7 @@ 0, sizeof(struct ip6t_entry), sizeof(struct ip6t_error), - 0, { 0, 0 }, { } }, + 0, NULL, 0, { 0, 0 }, { } }, { { { { IP6T_ALIGN(sizeof(struct ip6t_error_target)), IP6T_ERROR_TARGET } }, { } }, "ERROR" diff -Nur linux-2.6.0-test7.org/net/ipv6/netfilter/ip6table_mangle.c linux-2.6.0-test7/net/ipv6/netfilter/ip6table_mangle.c --- linux-2.6.0-test7.org/net/ipv6/netfilter/ip6table_mangle.c 2003-10-08 21:24:04.000000000 +0200 +++ linux-2.6.0-test7/net/ipv6/netfilter/ip6table_mangle.c 2003-10-10 11:53:18.000000000 +0200 @@ -66,7 +66,7 @@ 0, sizeof(struct ip6t_entry), sizeof(struct ip6t_standard), - 0, { 0, 0 }, { } }, + 0, NULL, 0, { 0, 0 }, { } }, { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } }, -NF_ACCEPT - 1 } }, /* LOCAL_IN */ @@ -74,7 +74,7 @@ 0, sizeof(struct ip6t_entry), sizeof(struct ip6t_standard), - 0, { 0, 0 }, { } }, + 0, NULL, 0, { 0, 0 }, { } }, { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } }, -NF_ACCEPT - 1 } }, /* FORWARD */ @@ -82,7 +82,7 @@ 0, sizeof(struct ip6t_entry), sizeof(struct ip6t_standard), - 0, { 0, 0 }, { } }, + 0, NULL, 0, { 0, 0 }, { } }, { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } }, -NF_ACCEPT - 1 } }, /* LOCAL_OUT */ @@ -90,7 +90,7 @@ 0, sizeof(struct ip6t_entry), sizeof(struct ip6t_standard), - 0, { 0, 0 }, { } }, + 0, NULL, 0, { 0, 0 }, { } }, { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } }, -NF_ACCEPT - 1 } }, /* POST_ROUTING */ @@ -98,7 +98,7 @@ 0, sizeof(struct ip6t_entry), sizeof(struct ip6t_standard), - 0, { 0, 0 }, { } }, + 0, NULL, 0, { 0, 0 }, { } }, { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } }, -NF_ACCEPT - 1 } } }, @@ -107,7 +107,7 @@ 0, sizeof(struct ip6t_entry), sizeof(struct ip6t_error), - 0, { 0, 0 }, { } }, + 0, NULL, 0, { 0, 0 }, { } }, { { { { IP6T_ALIGN(sizeof(struct ip6t_error_target)), IP6T_ERROR_TARGET } }, { } }, "ERROR" diff -Nur linux-2.6.0-test7.org/net/ipv6/netfilter/ip6table_raw.c linux-2.6.0-test7/net/ipv6/netfilter/ip6table_raw.c --- linux-2.6.0-test7.org/net/ipv6/netfilter/ip6table_raw.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.0-test7/net/ipv6/netfilter/ip6table_raw.c 2003-10-10 11:53:18.000000000 +0200 @@ -0,0 +1,158 @@ +/* + * IPv6 raw table, a port of the IPv4 raw table to IPv6 + * + * Copyright (C) 2003 Jozsef Kadlecsik + */ +#include +#include + +#define RAW_VALID_HOOKS ((1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_OUT)) + +#if 0 +#define DEBUGP(x, args...) printk(KERN_DEBUG x, ## args) +#else +#define DEBUGP(x, args...) +#endif + +/* Standard entry. */ +struct ip6t_standard +{ + struct ip6t_entry entry; + struct ip6t_standard_target target; +}; + +struct ip6t_error_target +{ + struct ip6t_entry_target target; + char errorname[IP6T_FUNCTION_MAXNAMELEN]; +}; + +struct ip6t_error +{ + struct ip6t_entry entry; + struct ip6t_error_target target; +}; + +static struct +{ + struct ip6t_replace repl; + struct ip6t_standard entries[2]; + struct ip6t_error term; +} initial_table __initdata += { { "raw", RAW_VALID_HOOKS, 3, + sizeof(struct ip6t_standard) * 2 + sizeof(struct ip6t_error), + { [NF_IP6_PRE_ROUTING] 0, + [NF_IP6_LOCAL_OUT] sizeof(struct ip6t_standard) }, + { [NF_IP6_PRE_ROUTING] 0, + [NF_IP6_LOCAL_OUT] sizeof(struct ip6t_standard) }, + 0, NULL, { } }, + { + /* PRE_ROUTING */ + { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 }, + 0, + sizeof(struct ip6t_entry), + sizeof(struct ip6t_standard), + 0, NULL, 0, { 0, 0 }, { } }, + { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } }, + -NF_ACCEPT - 1 } }, + /* LOCAL_OUT */ + { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 }, + 0, + sizeof(struct ip6t_entry), + sizeof(struct ip6t_standard), + 0, NULL, 0, { 0, 0 }, { } }, + { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } }, + -NF_ACCEPT - 1 } }, + }, + /* ERROR */ + { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 }, + 0, + sizeof(struct ip6t_entry), + sizeof(struct ip6t_error), + 0, NULL, 0, { 0, 0 }, { } }, + { { { { IP6T_ALIGN(sizeof(struct ip6t_error_target)), IP6T_ERROR_TARGET } }, + { } }, + "ERROR" + } + } +}; + +static struct ip6t_table packet_raw = { + .name = "raw", + .table = &initial_table.repl, + .valid_hooks = RAW_VALID_HOOKS, + .lock = RW_LOCK_UNLOCKED, + .me = THIS_MODULE +}; + +/* The work comes in here from netfilter.c. */ +static unsigned int +ip6t_hook(unsigned int hook, + struct sk_buff **pskb, + const struct net_device *in, + const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + return ip6t_do_table(pskb, hook, in, out, &packet_raw, NULL); +} + +static struct nf_hook_ops ip6t_ops[] = { + { /* PRE_ROUTING */ + .hook = ip6t_hook, + .owner = THIS_MODULE, + .pf = PF_INET6, + .hooknum = NF_IP6_PRE_ROUTING, + .priority = NF_IP6_PRI_FIRST, + }, + { /* LOCAL_OUT */ + .hook = ip6t_hook, + .owner = THIS_MODULE, + .pf = PF_INET6, + .hooknum = NF_IP6_LOCAL_OUT, + .priority = NF_IP6_PRI_FIRST, + }, +}; + +static int __init init(void) +{ + int ret; + + /* Register table */ + ret = ip6t_register_table(&packet_raw); + if (ret < 0) + return ret; + + /* Register hooks */ + ret = nf_register_hook(&ip6t_ops[0]); + if (ret < 0) + goto cleanup_table; + + ret = nf_register_hook(&ip6t_ops[1]); + if (ret < 0) + goto cleanup_hook0; + + return ret; + + cleanup_hook0: + nf_unregister_hook(&ip6t_ops[0]); + cleanup_table: + ip6t_unregister_table(&packet_raw); + + return ret; +} + +static void __exit fini(void) +{ + unsigned int i; + + for (i = 0; i < sizeof(ip6t_ops)/sizeof(struct nf_hook_ops); i++) + nf_unregister_hook(&ip6t_ops[i]); + + ip6t_unregister_table(&packet_raw); +} + +module_init(init); +module_exit(fini); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Netfilter Core Team "); +MODULE_DESCRIPTION("IPv6 raw table"); diff -Nur linux-2.6.0-test7.org/netfilter-patch-o-matic/patches linux-2.6.0-test7/netfilter-patch-o-matic/patches --- linux-2.6.0-test7.org/netfilter-patch-o-matic/patches 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.0-test7/netfilter-patch-o-matic/patches 2003-10-10 11:54:22.000000000 +0200 @@ -0,0 +1,23 @@ +./base/01_sctp_match.patch +./pending/23_REJECT-headroom-tcprst.patch +./pending/24_rcu.patch +./pending/25-err-ptr.patch +./pending/26-memsets.patch +./pending/40_nf-log.patch +./pending/70_expect-evict-order.patch +./pending/71_raw.patch +./submitted/02_REJECT-headroom-tcprst.patch +./submitted/03_260t4-mirror-remove.patch +./submitted/03_physdev_bridged.patch +./submitted/04_260t4-unclean-remove.patch +./submitted/04_config-fix.patch +./submitted/75_nathelper-udp-csum.patch +./submitted/76_mangle_udp-sizecheck.patch +./submitted/77_destroy-conntrack.patch +./submitted/78_reject-localout.patch +./submitted/80_ip_conntrack-proc.patch +./submitted/82_irc-conntrack-mirc-serverlookup.patch +./submitted/83_nolocalout.patch +./submitted/84_local-nullbinding.patch +./submitted/85_ipv6header.patch +./submitted/86_getorigdst-tuple-zero.patch