提交 587aa641 编写于 作者: P Patrick McHardy 提交者: David S. Miller

[NETFILTER]: Remove IPv4 only connection tracking/NAT

Remove the obsolete IPv4 only connection tracking/NAT as scheduled in
feature-removal-schedule.
Signed-off-by: NPatrick McHardy <kaber@trash.net>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 ce18afe5
......@@ -211,15 +211,6 @@ Who: Adrian Bunk <bunk@stusta.de>
---------------------------
What: IPv4 only connection tracking/NAT/helpers
When: 2.6.22
Why: The new layer 3 independant connection tracking replaces the old
IPv4 only version. After some stabilization of the new code the
old one will be removed.
Who: Patrick McHardy <kaber@trash.net>
---------------------------
What: ACPI hooks (X86_SPEEDSTEP_CENTRINO_ACPI) in speedstep-centrino driver
When: December 2006
Why: Speedstep-centrino driver with ACPI hooks and acpi-cpufreq driver are
......
header-y += ip_conntrack_helper.h
header-y += ip_conntrack_protocol.h
header-y += ip_conntrack_sctp.h
header-y += ip_conntrack_tcp.h
header-y += ip_conntrack_tftp.h
header-y += ip_nat_pptp.h
header-y += ipt_addrtype.h
header-y += ipt_ah.h
header-y += ipt_CLASSIFY.h
......@@ -49,13 +43,5 @@ header-y += ipt_ttl.h
header-y += ipt_TTL.h
header-y += ipt_ULOG.h
unifdef-y += ip_conntrack.h
unifdef-y += ip_conntrack_h323.h
unifdef-y += ip_conntrack_irc.h
unifdef-y += ip_conntrack_pptp.h
unifdef-y += ip_conntrack_proto_gre.h
unifdef-y += ip_conntrack_tuple.h
unifdef-y += ip_nat.h
unifdef-y += ip_nat_rule.h
unifdef-y += ip_queue.h
unifdef-y += ip_tables.h
#ifndef _IP_CONNTRACK_H
#define _IP_CONNTRACK_H
#include <linux/netfilter/nf_conntrack_common.h>
#ifdef __KERNEL__
#include <linux/netfilter_ipv4/ip_conntrack_tuple.h>
#include <linux/bitops.h>
#include <linux/compiler.h>
#include <asm/atomic.h>
#include <linux/timer.h>
#include <linux/netfilter_ipv4/ip_conntrack_tcp.h>
#include <linux/netfilter_ipv4/ip_conntrack_icmp.h>
#include <linux/netfilter_ipv4/ip_conntrack_proto_gre.h>
#include <linux/netfilter_ipv4/ip_conntrack_sctp.h>
/* per conntrack: protocol private data */
union ip_conntrack_proto {
/* insert conntrack proto private data here */
struct ip_ct_gre gre;
struct ip_ct_sctp sctp;
struct ip_ct_tcp tcp;
struct ip_ct_icmp icmp;
};
union ip_conntrack_expect_proto {
/* insert expect proto private data here */
};
/* Add protocol helper include file here */
#include <linux/netfilter_ipv4/ip_conntrack_h323.h>
#include <linux/netfilter_ipv4/ip_conntrack_pptp.h>
#include <linux/netfilter_ipv4/ip_conntrack_amanda.h>
#include <linux/netfilter_ipv4/ip_conntrack_ftp.h>
#include <linux/netfilter_ipv4/ip_conntrack_irc.h>
/* per conntrack: application helper private data */
union ip_conntrack_help {
/* insert conntrack helper private data (master) here */
struct ip_ct_h323_master ct_h323_info;
struct ip_ct_pptp_master ct_pptp_info;
struct ip_ct_ftp_master ct_ftp_info;
struct ip_ct_irc_master ct_irc_info;
};
#ifdef CONFIG_IP_NF_NAT_NEEDED
#include <linux/netfilter_ipv4/ip_nat.h>
#include <linux/netfilter_ipv4/ip_nat_pptp.h>
/* per conntrack: nat application helper private data */
union ip_conntrack_nat_help {
/* insert nat helper private data here */
struct ip_nat_pptp nat_pptp_info;
};
#endif
#include <linux/types.h>
#include <linux/skbuff.h>
#ifdef CONFIG_NETFILTER_DEBUG
#define IP_NF_ASSERT(x) \
do { \
if (!(x)) \
/* Wooah! I'm tripping my conntrack in a frenzy of \
netplay... */ \
printk("NF_IP_ASSERT: %s:%i(%s)\n", \
__FILE__, __LINE__, __FUNCTION__); \
} while(0)
#else
#define IP_NF_ASSERT(x)
#endif
struct ip_conntrack_helper;
struct ip_conntrack
{
/* Usage count in here is 1 for hash table/destruct timer, 1 per skb,
plus 1 for any connection(s) we are `master' for */
struct nf_conntrack ct_general;
/* Have we seen traffic both ways yet? (bitset) */
unsigned long status;
/* Timer function; drops refcnt when it goes off. */
struct timer_list timeout;
#ifdef CONFIG_IP_NF_CT_ACCT
/* Accounting Information (same cache line as other written members) */
struct ip_conntrack_counter counters[IP_CT_DIR_MAX];
#endif
/* If we were expected by an expectation, this will be it */
struct ip_conntrack *master;
/* Current number of expected connections */
unsigned int expecting;
/* Unique ID that identifies this conntrack*/
unsigned int id;
/* Helper, if any. */
struct ip_conntrack_helper *helper;
/* Storage reserved for other modules: */
union ip_conntrack_proto proto;
union ip_conntrack_help help;
#ifdef CONFIG_IP_NF_NAT_NEEDED
struct {
struct ip_nat_info info;
union ip_conntrack_nat_help help;
#if defined(CONFIG_IP_NF_TARGET_MASQUERADE) || \
defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE)
int masq_index;
#endif
} nat;
#endif /* CONFIG_IP_NF_NAT_NEEDED */
#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
u_int32_t mark;
#endif
#ifdef CONFIG_IP_NF_CONNTRACK_SECMARK
u_int32_t secmark;
#endif
/* Traversed often, so hopefully in different cacheline to top */
/* These are my tuples; original and reply */
struct ip_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX];
};
struct ip_conntrack_expect
{
/* Internal linked list (global expectation list) */
struct list_head list;
/* We expect this tuple, with the following mask */
struct ip_conntrack_tuple tuple, mask;
/* Function to call after setup and insertion */
void (*expectfn)(struct ip_conntrack *new,
struct ip_conntrack_expect *this);
/* The conntrack of the master connection */
struct ip_conntrack *master;
/* Timer function; deletes the expectation. */
struct timer_list timeout;
/* Usage count. */
atomic_t use;
/* Unique ID */
unsigned int id;
/* Flags */
unsigned int flags;
#ifdef CONFIG_IP_NF_NAT_NEEDED
__be32 saved_ip;
/* This is the original per-proto part, used to map the
* expected connection the way the recipient expects. */
union ip_conntrack_manip_proto saved_proto;
/* Direction relative to the master connection. */
enum ip_conntrack_dir dir;
#endif
};
#define IP_CT_EXPECT_PERMANENT 0x1
static inline struct ip_conntrack *
tuplehash_to_ctrack(const struct ip_conntrack_tuple_hash *hash)
{
return container_of(hash, struct ip_conntrack,
tuplehash[hash->tuple.dst.dir]);
}
/* get master conntrack via master expectation */
#define master_ct(conntr) (conntr->master)
/* Alter reply tuple (maybe alter helper). */
extern void
ip_conntrack_alter_reply(struct ip_conntrack *conntrack,
const struct ip_conntrack_tuple *newreply);
/* Is this tuple taken? (ignoring any belonging to the given
conntrack). */
extern int
ip_conntrack_tuple_taken(const struct ip_conntrack_tuple *tuple,
const struct ip_conntrack *ignored_conntrack);
/* Return conntrack_info and tuple hash for given skb. */
static inline struct ip_conntrack *
ip_conntrack_get(const struct sk_buff *skb, enum ip_conntrack_info *ctinfo)
{
*ctinfo = skb->nfctinfo;
return (struct ip_conntrack *)skb->nfct;
}
/* decrement reference count on a conntrack */
static inline void
ip_conntrack_put(struct ip_conntrack *ct)
{
IP_NF_ASSERT(ct);
nf_conntrack_put(&ct->ct_general);
}
extern int invert_tuplepr(struct ip_conntrack_tuple *inverse,
const struct ip_conntrack_tuple *orig);
extern void __ip_ct_refresh_acct(struct ip_conntrack *ct,
enum ip_conntrack_info ctinfo,
const struct sk_buff *skb,
unsigned long extra_jiffies,
int do_acct);
/* Refresh conntrack for this many jiffies and do accounting */
static inline void ip_ct_refresh_acct(struct ip_conntrack *ct,
enum ip_conntrack_info ctinfo,
const struct sk_buff *skb,
unsigned long extra_jiffies)
{
__ip_ct_refresh_acct(ct, ctinfo, skb, extra_jiffies, 1);
}
/* Refresh conntrack for this many jiffies */
static inline void ip_ct_refresh(struct ip_conntrack *ct,
const struct sk_buff *skb,
unsigned long extra_jiffies)
{
__ip_ct_refresh_acct(ct, 0, skb, extra_jiffies, 0);
}
/* These are for NAT. Icky. */
/* Update TCP window tracking data when NAT mangles the packet */
extern void ip_conntrack_tcp_update(struct sk_buff *skb,
struct ip_conntrack *conntrack,
enum ip_conntrack_dir dir);
/* Call me when a conntrack is destroyed. */
extern void (*ip_conntrack_destroyed)(struct ip_conntrack *conntrack);
/* Fake conntrack entry for untracked connections */
extern struct ip_conntrack ip_conntrack_untracked;
/* Returns new sk_buff, or NULL */
struct sk_buff *
ip_ct_gather_frags(struct sk_buff *skb, u_int32_t user);
/* Iterate over all conntracks: if iter returns true, it's deleted. */
extern void
ip_ct_iterate_cleanup(int (*iter)(struct ip_conntrack *i, void *data),
void *data);
extern struct ip_conntrack_helper *
__ip_conntrack_helper_find_byname(const char *);
extern struct ip_conntrack_helper *
ip_conntrack_helper_find_get(const struct ip_conntrack_tuple *tuple);
extern void ip_conntrack_helper_put(struct ip_conntrack_helper *helper);
extern struct ip_conntrack_protocol *
__ip_conntrack_proto_find(u_int8_t protocol);
extern struct ip_conntrack_protocol *
ip_conntrack_proto_find_get(u_int8_t protocol);
extern void ip_conntrack_proto_put(struct ip_conntrack_protocol *proto);
extern void ip_ct_remove_expectations(struct ip_conntrack *ct);
extern struct ip_conntrack *ip_conntrack_alloc(struct ip_conntrack_tuple *,
struct ip_conntrack_tuple *);
extern void ip_conntrack_free(struct ip_conntrack *ct);
extern void ip_conntrack_hash_insert(struct ip_conntrack *ct);
extern struct ip_conntrack_expect *
__ip_conntrack_expect_find(const struct ip_conntrack_tuple *tuple);
extern struct ip_conntrack_expect *
ip_conntrack_expect_find_get(const struct ip_conntrack_tuple *tuple);
extern struct ip_conntrack_tuple_hash *
__ip_conntrack_find(const struct ip_conntrack_tuple *tuple,
const struct ip_conntrack *ignored_conntrack);
extern void ip_conntrack_flush(void);
/* It's confirmed if it is, or has been in the hash table. */
static inline int is_confirmed(struct ip_conntrack *ct)
{
return test_bit(IPS_CONFIRMED_BIT, &ct->status);
}
static inline int is_dying(struct ip_conntrack *ct)
{
return test_bit(IPS_DYING_BIT, &ct->status);
}
extern unsigned int ip_conntrack_htable_size;
extern int ip_conntrack_checksum;
#define CONNTRACK_STAT_INC(count) (__get_cpu_var(ip_conntrack_stat).count++)
#define CONNTRACK_STAT_INC_ATOMIC(count) \
do { \
local_bh_disable(); \
__get_cpu_var(ip_conntrack_stat).count++; \
local_bh_enable(); \
} while (0)
#ifdef CONFIG_IP_NF_CONNTRACK_EVENTS
#include <linux/notifier.h>
#include <linux/interrupt.h>
struct ip_conntrack_ecache {
struct ip_conntrack *ct;
unsigned int events;
};
DECLARE_PER_CPU(struct ip_conntrack_ecache, ip_conntrack_ecache);
#define CONNTRACK_ECACHE(x) (__get_cpu_var(ip_conntrack_ecache).x)
extern struct atomic_notifier_head ip_conntrack_chain;
extern struct atomic_notifier_head ip_conntrack_expect_chain;
static inline int ip_conntrack_register_notifier(struct notifier_block *nb)
{
return atomic_notifier_chain_register(&ip_conntrack_chain, nb);
}
static inline int ip_conntrack_unregister_notifier(struct notifier_block *nb)
{
return atomic_notifier_chain_unregister(&ip_conntrack_chain, nb);
}
static inline int
ip_conntrack_expect_register_notifier(struct notifier_block *nb)
{
return atomic_notifier_chain_register(&ip_conntrack_expect_chain, nb);
}
static inline int
ip_conntrack_expect_unregister_notifier(struct notifier_block *nb)
{
return atomic_notifier_chain_unregister(&ip_conntrack_expect_chain,
nb);
}
extern void ip_ct_deliver_cached_events(const struct ip_conntrack *ct);
extern void __ip_ct_event_cache_init(struct ip_conntrack *ct);
static inline void
ip_conntrack_event_cache(enum ip_conntrack_events event,
const struct sk_buff *skb)
{
struct ip_conntrack *ct = (struct ip_conntrack *)skb->nfct;
struct ip_conntrack_ecache *ecache;
local_bh_disable();
ecache = &__get_cpu_var(ip_conntrack_ecache);
if (ct != ecache->ct)
__ip_ct_event_cache_init(ct);
ecache->events |= event;
local_bh_enable();
}
static inline void ip_conntrack_event(enum ip_conntrack_events event,
struct ip_conntrack *ct)
{
if (is_confirmed(ct) && !is_dying(ct))
atomic_notifier_call_chain(&ip_conntrack_chain, event, ct);
}
static inline void
ip_conntrack_expect_event(enum ip_conntrack_expect_events event,
struct ip_conntrack_expect *exp)
{
atomic_notifier_call_chain(&ip_conntrack_expect_chain, event, exp);
}
#else /* CONFIG_IP_NF_CONNTRACK_EVENTS */
static inline void ip_conntrack_event_cache(enum ip_conntrack_events event,
const struct sk_buff *skb) {}
static inline void ip_conntrack_event(enum ip_conntrack_events event,
struct ip_conntrack *ct) {}
static inline void ip_ct_deliver_cached_events(const struct ip_conntrack *ct) {}
static inline void
ip_conntrack_expect_event(enum ip_conntrack_expect_events event,
struct ip_conntrack_expect *exp) {}
#endif /* CONFIG_IP_NF_CONNTRACK_EVENTS */
#ifdef CONFIG_IP_NF_NAT_NEEDED
static inline int ip_nat_initialized(struct ip_conntrack *conntrack,
enum ip_nat_manip_type manip)
{
if (manip == IP_NAT_MANIP_SRC)
return test_bit(IPS_SRC_NAT_DONE_BIT, &conntrack->status);
return test_bit(IPS_DST_NAT_DONE_BIT, &conntrack->status);
}
#endif /* CONFIG_IP_NF_NAT_NEEDED */
#endif /* __KERNEL__ */
#endif /* _IP_CONNTRACK_H */
#ifndef _IP_CONNTRACK_AMANDA_H
#define _IP_CONNTRACK_AMANDA_H
/* AMANDA tracking. */
struct ip_conntrack_expect;
extern unsigned int (*ip_nat_amanda_hook)(struct sk_buff **pskb,
enum ip_conntrack_info ctinfo,
unsigned int matchoff,
unsigned int matchlen,
struct ip_conntrack_expect *exp);
#endif /* _IP_CONNTRACK_AMANDA_H */
#ifndef _IP_CONNTRACK_CORE_H
#define _IP_CONNTRACK_CORE_H
#include <linux/netfilter.h>
#define MAX_IP_CT_PROTO 256
extern struct ip_conntrack_protocol *ip_ct_protos[MAX_IP_CT_PROTO];
/* This header is used to share core functionality between the
standalone connection tracking module, and the compatibility layer's use
of connection tracking. */
extern unsigned int ip_conntrack_in(unsigned int hooknum,
struct sk_buff **pskb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *));
extern int ip_conntrack_init(void);
extern void ip_conntrack_cleanup(void);
struct ip_conntrack_protocol;
extern int
ip_ct_get_tuple(const struct iphdr *iph,
const struct sk_buff *skb,
unsigned int dataoff,
struct ip_conntrack_tuple *tuple,
const struct ip_conntrack_protocol *protocol);
extern int
ip_ct_invert_tuple(struct ip_conntrack_tuple *inverse,
const struct ip_conntrack_tuple *orig,
const struct ip_conntrack_protocol *protocol);
/* Find a connection corresponding to a tuple. */
struct ip_conntrack_tuple_hash *
ip_conntrack_find_get(const struct ip_conntrack_tuple *tuple,
const struct ip_conntrack *ignored_conntrack);
extern int __ip_conntrack_confirm(struct sk_buff **pskb);
/* Confirm a connection: returns NF_DROP if packet must be dropped. */
static inline int ip_conntrack_confirm(struct sk_buff **pskb)
{
struct ip_conntrack *ct = (struct ip_conntrack *)(*pskb)->nfct;
int ret = NF_ACCEPT;
if (ct) {
if (!is_confirmed(ct) && !is_dying(ct))
ret = __ip_conntrack_confirm(pskb);
ip_ct_deliver_cached_events(ct);
}
return ret;
}
extern void ip_ct_unlink_expect(struct ip_conntrack_expect *exp);
extern struct list_head *ip_conntrack_hash;
extern struct list_head ip_conntrack_expect_list;
extern rwlock_t ip_conntrack_lock;
#endif /* _IP_CONNTRACK_CORE_H */
#ifndef _IP_CONNTRACK_FTP_H
#define _IP_CONNTRACK_FTP_H
/* FTP tracking. */
/* This enum is exposed to userspace */
enum ip_ct_ftp_type
{
/* PORT command from client */
IP_CT_FTP_PORT,
/* PASV response from server */
IP_CT_FTP_PASV,
/* EPRT command from client */
IP_CT_FTP_EPRT,
/* EPSV response from server */
IP_CT_FTP_EPSV,
};
#ifdef __KERNEL__
#define FTP_PORT 21
#define NUM_SEQ_TO_REMEMBER 2
/* This structure exists only once per master */
struct ip_ct_ftp_master {
/* Valid seq positions for cmd matching after newline */
u_int32_t seq_aft_nl[IP_CT_DIR_MAX][NUM_SEQ_TO_REMEMBER];
/* 0 means seq_match_aft_nl not set */
int seq_aft_nl_num[IP_CT_DIR_MAX];
};
struct ip_conntrack_expect;
/* For NAT to hook in when we find a packet which describes what other
* connection we should expect. */
extern unsigned int (*ip_nat_ftp_hook)(struct sk_buff **pskb,
enum ip_conntrack_info ctinfo,
enum ip_ct_ftp_type type,
unsigned int matchoff,
unsigned int matchlen,
struct ip_conntrack_expect *exp,
u32 *seq);
#endif /* __KERNEL__ */
#endif /* _IP_CONNTRACK_FTP_H */
#ifndef _IP_CONNTRACK_H323_H
#define _IP_CONNTRACK_H323_H
#ifdef __KERNEL__
#include <linux/netfilter/nf_conntrack_h323_asn1.h>
#define RAS_PORT 1719
#define Q931_PORT 1720
#define H323_RTP_CHANNEL_MAX 4 /* Audio, video, FAX and other */
/* This structure exists only once per master */
struct ip_ct_h323_master {
/* Original and NATed Q.931 or H.245 signal ports */
u_int16_t sig_port[IP_CT_DIR_MAX];
/* Original and NATed RTP ports */
u_int16_t rtp_port[H323_RTP_CHANNEL_MAX][IP_CT_DIR_MAX];
union {
/* RAS connection timeout */
u_int32_t timeout;
/* Next TPKT length (for separate TPKT header and data) */
u_int16_t tpkt_len[IP_CT_DIR_MAX];
};
};
struct ip_conntrack_expect;
extern int get_h225_addr(unsigned char *data, TransportAddress * addr,
__be32 * ip, u_int16_t * port);
extern void ip_conntrack_h245_expect(struct ip_conntrack *new,
struct ip_conntrack_expect *this);
extern void ip_conntrack_q931_expect(struct ip_conntrack *new,
struct ip_conntrack_expect *this);
extern int (*set_h245_addr_hook) (struct sk_buff ** pskb,
unsigned char **data, int dataoff,
H245_TransportAddress * addr,
__be32 ip, u_int16_t port);
extern int (*set_h225_addr_hook) (struct sk_buff ** pskb,
unsigned char **data, int dataoff,
TransportAddress * addr,
__be32 ip, u_int16_t port);
extern int (*set_sig_addr_hook) (struct sk_buff ** pskb,
struct ip_conntrack * ct,
enum ip_conntrack_info ctinfo,
unsigned char **data,
TransportAddress * addr, int count);
extern int (*set_ras_addr_hook) (struct sk_buff ** pskb,
struct ip_conntrack * ct,
enum ip_conntrack_info ctinfo,
unsigned char **data,
TransportAddress * addr, int count);
extern int (*nat_rtp_rtcp_hook) (struct sk_buff ** pskb,
struct ip_conntrack * ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, int dataoff,
H245_TransportAddress * addr,
u_int16_t port, u_int16_t rtp_port,
struct ip_conntrack_expect * rtp_exp,
struct ip_conntrack_expect * rtcp_exp);
extern int (*nat_t120_hook) (struct sk_buff ** pskb, struct ip_conntrack * ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, int dataoff,
H245_TransportAddress * addr, u_int16_t port,
struct ip_conntrack_expect * exp);
extern int (*nat_h245_hook) (struct sk_buff ** pskb, struct ip_conntrack * ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, int dataoff,
TransportAddress * addr, u_int16_t port,
struct ip_conntrack_expect * exp);
extern int (*nat_callforwarding_hook) (struct sk_buff ** pskb,
struct ip_conntrack * ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, int dataoff,
TransportAddress * addr,
u_int16_t port,
struct ip_conntrack_expect * exp);
extern int (*nat_q931_hook) (struct sk_buff ** pskb, struct ip_conntrack * ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, TransportAddress * addr,
int idx, u_int16_t port,
struct ip_conntrack_expect * exp);
#endif
#endif
/* IP connection tracking helpers. */
#ifndef _IP_CONNTRACK_HELPER_H
#define _IP_CONNTRACK_HELPER_H
#include <linux/netfilter_ipv4/ip_conntrack.h>
struct module;
struct ip_conntrack_helper
{
struct list_head list; /* Internal use. */
const char *name; /* name of the module */
struct module *me; /* pointer to self */
unsigned int max_expected; /* Maximum number of concurrent
* expected connections */
unsigned int timeout; /* timeout for expecteds */
/* Mask of things we will help (compared against server response) */
struct ip_conntrack_tuple tuple;
struct ip_conntrack_tuple mask;
/* Function to call when data passes; return verdict, or -1 to
invalidate. */
int (*help)(struct sk_buff **pskb,
struct ip_conntrack *ct,
enum ip_conntrack_info conntrackinfo);
void (*destroy)(struct ip_conntrack *ct);
int (*to_nfattr)(struct sk_buff *skb, const struct ip_conntrack *ct);
};
extern int ip_conntrack_helper_register(struct ip_conntrack_helper *);
extern void ip_conntrack_helper_unregister(struct ip_conntrack_helper *);
/* Allocate space for an expectation: this is mandatory before calling
ip_conntrack_expect_related. You will have to call put afterwards. */
extern struct ip_conntrack_expect *
ip_conntrack_expect_alloc(struct ip_conntrack *master);
extern void ip_conntrack_expect_put(struct ip_conntrack_expect *exp);
/* Add an expected connection: can have more than one per connection */
extern int ip_conntrack_expect_related(struct ip_conntrack_expect *exp);
extern void ip_conntrack_unexpect_related(struct ip_conntrack_expect *exp);
#endif /*_IP_CONNTRACK_HELPER_H*/
#ifndef _IP_CONNTRACK_ICMP_H
#define _IP_CONNTRACK_ICMP_H
#include <net/netfilter/ipv4/nf_conntrack_icmp.h>
#endif /* _IP_CONNTRACK_ICMP_H */
/* IRC extension for IP connection tracking.
* (C) 2000 by Harald Welte <laforge@gnumonks.org>
* based on RR's ip_conntrack_ftp.h
*
* ip_conntrack_irc.h,v 1.6 2000/11/07 18:26:42 laforge Exp
*
* 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.
*
*
*/
#ifndef _IP_CONNTRACK_IRC_H
#define _IP_CONNTRACK_IRC_H
/* This structure exists only once per master */
struct ip_ct_irc_master {
};
#ifdef __KERNEL__
extern unsigned int (*ip_nat_irc_hook)(struct sk_buff **pskb,
enum ip_conntrack_info ctinfo,
unsigned int matchoff,
unsigned int matchlen,
struct ip_conntrack_expect *exp);
#define IRC_PORT 6667
#endif /* __KERNEL__ */
#endif /* _IP_CONNTRACK_IRC_H */
/* PPTP constants and structs */
#ifndef _CONNTRACK_PPTP_H
#define _CONNTRACK_PPTP_H
/* state of the control session */
enum pptp_ctrlsess_state {
PPTP_SESSION_NONE, /* no session present */
PPTP_SESSION_ERROR, /* some session error */
PPTP_SESSION_STOPREQ, /* stop_sess request seen */
PPTP_SESSION_REQUESTED, /* start_sess request seen */
PPTP_SESSION_CONFIRMED, /* session established */
};
/* state of the call inside the control session */
enum pptp_ctrlcall_state {
PPTP_CALL_NONE,
PPTP_CALL_ERROR,
PPTP_CALL_OUT_REQ,
PPTP_CALL_OUT_CONF,
PPTP_CALL_IN_REQ,
PPTP_CALL_IN_REP,
PPTP_CALL_IN_CONF,
PPTP_CALL_CLEAR_REQ,
};
/* conntrack private data */
struct ip_ct_pptp_master {
enum pptp_ctrlsess_state sstate; /* session state */
/* everything below is going to be per-expectation in newnat,
* since there could be more than one call within one session */
enum pptp_ctrlcall_state cstate; /* call state */
__be16 pac_call_id; /* call id of PAC, host byte order */
__be16 pns_call_id; /* call id of PNS, host byte order */
/* in pre-2.6.11 this used to be per-expect. Now it is per-conntrack
* and therefore imposes a fixed limit on the number of maps */
struct ip_ct_gre_keymap *keymap_orig, *keymap_reply;
};
/* conntrack_expect private member */
struct ip_ct_pptp_expect {
enum pptp_ctrlcall_state cstate; /* call state */
__be16 pac_call_id; /* call id of PAC */
__be16 pns_call_id; /* call id of PNS */
};
#ifdef __KERNEL__
#define IP_CONNTR_PPTP PPTP_CONTROL_PORT
#define PPTP_CONTROL_PORT 1723
#define PPTP_PACKET_CONTROL 1
#define PPTP_PACKET_MGMT 2
#define PPTP_MAGIC_COOKIE 0x1a2b3c4d
struct pptp_pkt_hdr {
__u16 packetLength;
__be16 packetType;
__be32 magicCookie;
};
/* PptpControlMessageType values */
#define PPTP_START_SESSION_REQUEST 1
#define PPTP_START_SESSION_REPLY 2
#define PPTP_STOP_SESSION_REQUEST 3
#define PPTP_STOP_SESSION_REPLY 4
#define PPTP_ECHO_REQUEST 5
#define PPTP_ECHO_REPLY 6
#define PPTP_OUT_CALL_REQUEST 7
#define PPTP_OUT_CALL_REPLY 8
#define PPTP_IN_CALL_REQUEST 9
#define PPTP_IN_CALL_REPLY 10
#define PPTP_IN_CALL_CONNECT 11
#define PPTP_CALL_CLEAR_REQUEST 12
#define PPTP_CALL_DISCONNECT_NOTIFY 13
#define PPTP_WAN_ERROR_NOTIFY 14
#define PPTP_SET_LINK_INFO 15
#define PPTP_MSG_MAX 15
/* PptpGeneralError values */
#define PPTP_ERROR_CODE_NONE 0
#define PPTP_NOT_CONNECTED 1
#define PPTP_BAD_FORMAT 2
#define PPTP_BAD_VALUE 3
#define PPTP_NO_RESOURCE 4
#define PPTP_BAD_CALLID 5
#define PPTP_REMOVE_DEVICE_ERROR 6
struct PptpControlHeader {
__be16 messageType;
__u16 reserved;
};
/* FramingCapability Bitmap Values */
#define PPTP_FRAME_CAP_ASYNC 0x1
#define PPTP_FRAME_CAP_SYNC 0x2
/* BearerCapability Bitmap Values */
#define PPTP_BEARER_CAP_ANALOG 0x1
#define PPTP_BEARER_CAP_DIGITAL 0x2
struct PptpStartSessionRequest {
__be16 protocolVersion;
__u16 reserved1;
__be32 framingCapability;
__be32 bearerCapability;
__be16 maxChannels;
__be16 firmwareRevision;
__u8 hostName[64];
__u8 vendorString[64];
};
/* PptpStartSessionResultCode Values */
#define PPTP_START_OK 1
#define PPTP_START_GENERAL_ERROR 2
#define PPTP_START_ALREADY_CONNECTED 3
#define PPTP_START_NOT_AUTHORIZED 4
#define PPTP_START_UNKNOWN_PROTOCOL 5
struct PptpStartSessionReply {
__be16 protocolVersion;
__u8 resultCode;
__u8 generalErrorCode;
__be32 framingCapability;
__be32 bearerCapability;
__be16 maxChannels;
__be16 firmwareRevision;
__u8 hostName[64];
__u8 vendorString[64];
};
/* PptpStopReasons */
#define PPTP_STOP_NONE 1
#define PPTP_STOP_PROTOCOL 2
#define PPTP_STOP_LOCAL_SHUTDOWN 3
struct PptpStopSessionRequest {
__u8 reason;
__u8 reserved1;
__u16 reserved2;
};
/* PptpStopSessionResultCode */
#define PPTP_STOP_OK 1
#define PPTP_STOP_GENERAL_ERROR 2
struct PptpStopSessionReply {
__u8 resultCode;
__u8 generalErrorCode;
__u16 reserved1;
};
struct PptpEchoRequest {
__be32 identNumber;
};
/* PptpEchoReplyResultCode */
#define PPTP_ECHO_OK 1
#define PPTP_ECHO_GENERAL_ERROR 2
struct PptpEchoReply {
__be32 identNumber;
__u8 resultCode;
__u8 generalErrorCode;
__u16 reserved;
};
/* PptpFramingType */
#define PPTP_ASYNC_FRAMING 1
#define PPTP_SYNC_FRAMING 2
#define PPTP_DONT_CARE_FRAMING 3
/* PptpCallBearerType */
#define PPTP_ANALOG_TYPE 1
#define PPTP_DIGITAL_TYPE 2
#define PPTP_DONT_CARE_BEARER_TYPE 3
struct PptpOutCallRequest {
__be16 callID;
__be16 callSerialNumber;
__be32 minBPS;
__be32 maxBPS;
__be32 bearerType;
__be32 framingType;
__be16 packetWindow;
__be16 packetProcDelay;
__be16 phoneNumberLength;
__u16 reserved1;
__u8 phoneNumber[64];
__u8 subAddress[64];
};
/* PptpCallResultCode */
#define PPTP_OUTCALL_CONNECT 1
#define PPTP_OUTCALL_GENERAL_ERROR 2
#define PPTP_OUTCALL_NO_CARRIER 3
#define PPTP_OUTCALL_BUSY 4
#define PPTP_OUTCALL_NO_DIAL_TONE 5
#define PPTP_OUTCALL_TIMEOUT 6
#define PPTP_OUTCALL_DONT_ACCEPT 7
struct PptpOutCallReply {
__be16 callID;
__be16 peersCallID;
__u8 resultCode;
__u8 generalErrorCode;
__be16 causeCode;
__be32 connectSpeed;
__be16 packetWindow;
__be16 packetProcDelay;
__be32 physChannelID;
};
struct PptpInCallRequest {
__be16 callID;
__be16 callSerialNumber;
__be32 callBearerType;
__be32 physChannelID;
__be16 dialedNumberLength;
__be16 dialingNumberLength;
__u8 dialedNumber[64];
__u8 dialingNumber[64];
__u8 subAddress[64];
};
/* PptpInCallResultCode */
#define PPTP_INCALL_ACCEPT 1
#define PPTP_INCALL_GENERAL_ERROR 2
#define PPTP_INCALL_DONT_ACCEPT 3
struct PptpInCallReply {
__be16 callID;
__be16 peersCallID;
__u8 resultCode;
__u8 generalErrorCode;
__be16 packetWindow;
__be16 packetProcDelay;
__u16 reserved;
};
struct PptpInCallConnected {
__be16 peersCallID;
__u16 reserved;
__be32 connectSpeed;
__be16 packetWindow;
__be16 packetProcDelay;
__be32 callFramingType;
};
struct PptpClearCallRequest {
__be16 callID;
__u16 reserved;
};
struct PptpCallDisconnectNotify {
__be16 callID;
__u8 resultCode;
__u8 generalErrorCode;
__be16 causeCode;
__u16 reserved;
__u8 callStatistics[128];
};
struct PptpWanErrorNotify {
__be16 peersCallID;
__u16 reserved;
__be32 crcErrors;
__be32 framingErrors;
__be32 hardwareOverRuns;
__be32 bufferOverRuns;
__be32 timeoutErrors;
__be32 alignmentErrors;
};
struct PptpSetLinkInfo {
__be16 peersCallID;
__u16 reserved;
__be32 sendAccm;
__be32 recvAccm;
};
union pptp_ctrl_union {
struct PptpStartSessionRequest sreq;
struct PptpStartSessionReply srep;
struct PptpStopSessionRequest streq;
struct PptpStopSessionReply strep;
struct PptpOutCallRequest ocreq;
struct PptpOutCallReply ocack;
struct PptpInCallRequest icreq;
struct PptpInCallReply icack;
struct PptpInCallConnected iccon;
struct PptpClearCallRequest clrreq;
struct PptpCallDisconnectNotify disc;
struct PptpWanErrorNotify wanerr;
struct PptpSetLinkInfo setlink;
};
extern int
(*ip_nat_pptp_hook_outbound)(struct sk_buff **pskb,
struct ip_conntrack *ct,
enum ip_conntrack_info ctinfo,
struct PptpControlHeader *ctlh,
union pptp_ctrl_union *pptpReq);
extern int
(*ip_nat_pptp_hook_inbound)(struct sk_buff **pskb,
struct ip_conntrack *ct,
enum ip_conntrack_info ctinfo,
struct PptpControlHeader *ctlh,
union pptp_ctrl_union *pptpReq);
extern void
(*ip_nat_pptp_hook_exp_gre)(struct ip_conntrack_expect *exp_orig,
struct ip_conntrack_expect *exp_reply);
extern void
(*ip_nat_pptp_hook_expectfn)(struct ip_conntrack *ct,
struct ip_conntrack_expect *exp);
#endif /* __KERNEL__ */
#endif /* _CONNTRACK_PPTP_H */
#ifndef _CONNTRACK_PROTO_GRE_H
#define _CONNTRACK_PROTO_GRE_H
#include <asm/byteorder.h>
/* GRE PROTOCOL HEADER */
/* GRE Version field */
#define GRE_VERSION_1701 0x0
#define GRE_VERSION_PPTP 0x1
/* GRE Protocol field */
#define GRE_PROTOCOL_PPTP 0x880B
/* GRE Flags */
#define GRE_FLAG_C 0x80
#define GRE_FLAG_R 0x40
#define GRE_FLAG_K 0x20
#define GRE_FLAG_S 0x10
#define GRE_FLAG_A 0x80
#define GRE_IS_C(f) ((f)&GRE_FLAG_C)
#define GRE_IS_R(f) ((f)&GRE_FLAG_R)
#define GRE_IS_K(f) ((f)&GRE_FLAG_K)
#define GRE_IS_S(f) ((f)&GRE_FLAG_S)
#define GRE_IS_A(f) ((f)&GRE_FLAG_A)
/* GRE is a mess: Four different standards */
struct gre_hdr {
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u16 rec:3,
srr:1,
seq:1,
key:1,
routing:1,
csum:1,
version:3,
reserved:4,
ack:1;
#elif defined(__BIG_ENDIAN_BITFIELD)
__u16 csum:1,
routing:1,
key:1,
seq:1,
srr:1,
rec:3,
ack:1,
reserved:4,
version:3;
#else
#error "Adjust your <asm/byteorder.h> defines"
#endif
__be16 protocol;
};
/* modified GRE header for PPTP */
struct gre_hdr_pptp {
__u8 flags; /* bitfield */
__u8 version; /* should be GRE_VERSION_PPTP */
__be16 protocol; /* should be GRE_PROTOCOL_PPTP */
__be16 payload_len; /* size of ppp payload, not inc. gre header */
__be16 call_id; /* peer's call_id for this session */
__be32 seq; /* sequence number. Present if S==1 */
__be32 ack; /* seq number of highest packet recieved by */
/* sender in this session */
};
/* this is part of ip_conntrack */
struct ip_ct_gre {
unsigned int stream_timeout;
unsigned int timeout;
};
#ifdef __KERNEL__
struct ip_conntrack_expect;
struct ip_conntrack;
/* structure for original <-> reply keymap */
struct ip_ct_gre_keymap {
struct list_head list;
struct ip_conntrack_tuple tuple;
};
/* add new tuple->key_reply pair to keymap */
int ip_ct_gre_keymap_add(struct ip_conntrack *ct,
struct ip_conntrack_tuple *t,
int reply);
/* delete keymap entries */
void ip_ct_gre_keymap_destroy(struct ip_conntrack *ct);
/* get pointer to gre key, if present */
static inline __be32 *gre_key(struct gre_hdr *greh)
{
if (!greh->key)
return NULL;
if (greh->csum || greh->routing)
return (__be32 *) (greh+sizeof(*greh)+4);
return (__be32 *) (greh+sizeof(*greh));
}
/* get pointer ot gre csum, if present */
static inline __sum16 *gre_csum(struct gre_hdr *greh)
{
if (!greh->csum)
return NULL;
return (__sum16 *) (greh+sizeof(*greh));
}
#endif /* __KERNEL__ */
#endif /* _CONNTRACK_PROTO_GRE_H */
/* Header for use in defining a given protocol for connection tracking. */
#ifndef _IP_CONNTRACK_PROTOCOL_H
#define _IP_CONNTRACK_PROTOCOL_H
#include <linux/netfilter_ipv4/ip_conntrack.h>
#include <linux/netfilter/nfnetlink_conntrack.h>
struct seq_file;
struct ip_conntrack_protocol
{
/* Protocol number. */
u_int8_t proto;
/* Protocol name */
const char *name;
/* Try to fill in the third arg: dataoff is offset past IP
hdr. Return true if possible. */
int (*pkt_to_tuple)(const struct sk_buff *skb,
unsigned int dataoff,
struct ip_conntrack_tuple *tuple);
/* Invert the per-proto part of the tuple: ie. turn xmit into reply.
* Some packets can't be inverted: return 0 in that case.
*/
int (*invert_tuple)(struct ip_conntrack_tuple *inverse,
const struct ip_conntrack_tuple *orig);
/* Print out the per-protocol part of the tuple. Return like seq_* */
int (*print_tuple)(struct seq_file *,
const struct ip_conntrack_tuple *);
/* Print out the private part of the conntrack. */
int (*print_conntrack)(struct seq_file *, const struct ip_conntrack *);
/* Returns verdict for packet, or -1 for invalid. */
int (*packet)(struct ip_conntrack *conntrack,
const struct sk_buff *skb,
enum ip_conntrack_info ctinfo);
/* Called when a new connection for this protocol found;
* returns TRUE if it's OK. If so, packet() called next. */
int (*new)(struct ip_conntrack *conntrack, const struct sk_buff *skb);
/* Called when a conntrack entry is destroyed */
void (*destroy)(struct ip_conntrack *conntrack);
int (*error)(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
unsigned int hooknum);
/* convert protoinfo to nfnetink attributes */
int (*to_nfattr)(struct sk_buff *skb, struct nfattr *nfa,
const struct ip_conntrack *ct);
/* convert nfnetlink attributes to protoinfo */
int (*from_nfattr)(struct nfattr *tb[], struct ip_conntrack *ct);
int (*tuple_to_nfattr)(struct sk_buff *skb,
const struct ip_conntrack_tuple *t);
int (*nfattr_to_tuple)(struct nfattr *tb[],
struct ip_conntrack_tuple *t);
/* Module (if any) which this is connected to. */
struct module *me;
};
/* Protocol registration. */
extern int ip_conntrack_protocol_register(struct ip_conntrack_protocol *proto);
extern void ip_conntrack_protocol_unregister(struct ip_conntrack_protocol *proto);
/* Existing built-in protocols */
extern struct ip_conntrack_protocol ip_conntrack_protocol_tcp;
extern struct ip_conntrack_protocol ip_conntrack_protocol_udp;
extern struct ip_conntrack_protocol ip_conntrack_protocol_icmp;
extern struct ip_conntrack_protocol ip_conntrack_generic_protocol;
extern int ip_conntrack_protocol_tcp_init(void);
/* Log invalid packets */
extern unsigned int ip_ct_log_invalid;
extern int ip_ct_port_tuple_to_nfattr(struct sk_buff *,
const struct ip_conntrack_tuple *);
extern int ip_ct_port_nfattr_to_tuple(struct nfattr *tb[],
struct ip_conntrack_tuple *);
#ifdef CONFIG_SYSCTL
#ifdef DEBUG_INVALID_PACKETS
#define LOG_INVALID(proto) \
(ip_ct_log_invalid == (proto) || ip_ct_log_invalid == IPPROTO_RAW)
#else
#define LOG_INVALID(proto) \
((ip_ct_log_invalid == (proto) || ip_ct_log_invalid == IPPROTO_RAW) \
&& net_ratelimit())
#endif
#else
#define LOG_INVALID(proto) 0
#endif /* CONFIG_SYSCTL */
#endif /*_IP_CONNTRACK_PROTOCOL_H*/
#ifndef _IP_CONNTRACK_SCTP_H
#define _IP_CONNTRACK_SCTP_H
#include <linux/netfilter/nf_conntrack_sctp.h>
#endif /* _IP_CONNTRACK_SCTP_H */
#ifndef __IP_CONNTRACK_SIP_H__
#define __IP_CONNTRACK_SIP_H__
#ifdef __KERNEL__
#define SIP_PORT 5060
#define SIP_TIMEOUT 3600
enum sip_header_pos {
POS_REG_REQ_URI,
POS_REQ_URI,
POS_FROM,
POS_TO,
POS_VIA,
POS_CONTACT,
POS_CONTENT,
POS_MEDIA,
POS_OWNER,
POS_CONNECTION,
POS_SDP_HEADER,
};
extern unsigned int (*ip_nat_sip_hook)(struct sk_buff **pskb,
enum ip_conntrack_info ctinfo,
struct ip_conntrack *ct,
const char **dptr);
extern unsigned int (*ip_nat_sdp_hook)(struct sk_buff **pskb,
enum ip_conntrack_info ctinfo,
struct ip_conntrack_expect *exp,
const char *dptr);
extern int ct_sip_get_info(const char *dptr, size_t dlen,
unsigned int *matchoff,
unsigned int *matchlen,
enum sip_header_pos pos);
extern int ct_sip_lnlen(const char *line, const char *limit);
extern const char *ct_sip_search(const char *needle, const char *haystack,
size_t needle_len, size_t haystack_len,
int case_sensitive);
#endif /* __KERNEL__ */
#endif /* __IP_CONNTRACK_SIP_H__ */
#ifndef _IP_CONNTRACK_TCP_H
#define _IP_CONNTRACK_TCP_H
#include <linux/netfilter/nf_conntrack_tcp.h>
#endif /* _IP_CONNTRACK_TCP_H */
#ifndef _IP_CT_TFTP
#define _IP_CT_TFTP
#define TFTP_PORT 69
struct tftphdr {
__be16 opcode;
};
#define TFTP_OPCODE_READ 1
#define TFTP_OPCODE_WRITE 2
#define TFTP_OPCODE_DATA 3
#define TFTP_OPCODE_ACK 4
#define TFTP_OPCODE_ERROR 5
extern unsigned int (*ip_nat_tftp_hook)(struct sk_buff **pskb,
enum ip_conntrack_info ctinfo,
struct ip_conntrack_expect *exp);
#endif /* _IP_CT_TFTP */
#ifndef _IP_CONNTRACK_TUPLE_H
#define _IP_CONNTRACK_TUPLE_H
#include <linux/types.h>
#include <linux/netfilter/nf_conntrack_tuple_common.h>
/* A `tuple' is a structure containing the information to uniquely
identify a connection. ie. if two packets have the same tuple, they
are in the same connection; if not, they are not.
We divide the structure along "manipulatable" and
"non-manipulatable" lines, for the benefit of the NAT code.
*/
/* The protocol-specific manipulable parts of the tuple: always in
network order! */
union ip_conntrack_manip_proto
{
/* Add other protocols here. */
u_int16_t all;
struct {
__be16 port;
} tcp;
struct {
__be16 port;
} udp;
struct {
__be16 id;
} icmp;
struct {
__be16 port;
} sctp;
struct {
__be16 key; /* key is 32bit, pptp only uses 16 */
} gre;
};
/* The manipulable part of the tuple. */
struct ip_conntrack_manip
{
__be32 ip;
union ip_conntrack_manip_proto u;
};
/* This contains the information to distinguish a connection. */
struct ip_conntrack_tuple
{
struct ip_conntrack_manip src;
/* These are the parts of the tuple which are fixed. */
struct {
__be32 ip;
union {
/* Add other protocols here. */
u_int16_t all;
struct {
__be16 port;
} tcp;
struct {
__be16 port;
} udp;
struct {
u_int8_t type, code;
} icmp;
struct {
__be16 port;
} sctp;
struct {
__be16 key; /* key is 32bit,
* pptp only uses 16 */
} gre;
} u;
/* The protocol. */
u_int8_t protonum;
/* The direction (for tuplehash) */
u_int8_t dir;
} dst;
};
/* This is optimized opposed to a memset of the whole structure. Everything we
* really care about is the source/destination unions */
#define IP_CT_TUPLE_U_BLANK(tuple) \
do { \
(tuple)->src.u.all = 0; \
(tuple)->dst.u.all = 0; \
} while (0)
#ifdef __KERNEL__
#define DUMP_TUPLE(tp) \
DEBUGP("tuple %p: %u %u.%u.%u.%u:%hu -> %u.%u.%u.%u:%hu\n", \
(tp), (tp)->dst.protonum, \
NIPQUAD((tp)->src.ip), ntohs((tp)->src.u.all), \
NIPQUAD((tp)->dst.ip), ntohs((tp)->dst.u.all))
/* If we're the first tuple, it's the original dir. */
#define DIRECTION(h) ((enum ip_conntrack_dir)(h)->tuple.dst.dir)
/* Connections have two entries in the hash table: one for each way */
struct ip_conntrack_tuple_hash
{
struct list_head list;
struct ip_conntrack_tuple tuple;
};
#endif /* __KERNEL__ */
static inline int ip_ct_tuple_src_equal(const struct ip_conntrack_tuple *t1,
const struct ip_conntrack_tuple *t2)
{
return t1->src.ip == t2->src.ip
&& t1->src.u.all == t2->src.u.all;
}
static inline int ip_ct_tuple_dst_equal(const struct ip_conntrack_tuple *t1,
const struct ip_conntrack_tuple *t2)
{
return t1->dst.ip == t2->dst.ip
&& t1->dst.u.all == t2->dst.u.all
&& t1->dst.protonum == t2->dst.protonum;
}
static inline int ip_ct_tuple_equal(const struct ip_conntrack_tuple *t1,
const struct ip_conntrack_tuple *t2)
{
return ip_ct_tuple_src_equal(t1, t2) && ip_ct_tuple_dst_equal(t1, t2);
}
static inline int ip_ct_tuple_mask_cmp(const struct ip_conntrack_tuple *t,
const struct ip_conntrack_tuple *tuple,
const struct ip_conntrack_tuple *mask)
{
return !(((t->src.ip ^ tuple->src.ip) & mask->src.ip)
|| ((t->dst.ip ^ tuple->dst.ip) & mask->dst.ip)
|| ((t->src.u.all ^ tuple->src.u.all) & mask->src.u.all)
|| ((t->dst.u.all ^ tuple->dst.u.all) & mask->dst.u.all)
|| ((t->dst.protonum ^ tuple->dst.protonum)
& mask->dst.protonum));
}
#endif /* _IP_CONNTRACK_TUPLE_H */
#ifndef _IP_NAT_H
#define _IP_NAT_H
#include <linux/netfilter_ipv4.h>
#include <linux/netfilter_ipv4/ip_conntrack_tuple.h>
#define IP_NAT_MAPPING_TYPE_MAX_NAMELEN 16
enum ip_nat_manip_type
{
IP_NAT_MANIP_SRC,
IP_NAT_MANIP_DST
};
/* SRC manip occurs POST_ROUTING or LOCAL_IN */
#define HOOK2MANIP(hooknum) ((hooknum) != NF_IP_POST_ROUTING && (hooknum) != NF_IP_LOCAL_IN)
#define IP_NAT_RANGE_MAP_IPS 1
#define IP_NAT_RANGE_PROTO_SPECIFIED 2
#define IP_NAT_RANGE_PROTO_RANDOM 4 /* add randomness to "port" selection */
/* NAT sequence number modifications */
struct ip_nat_seq {
/* position of the last TCP sequence number
* modification (if any) */
u_int32_t correction_pos;
/* sequence number offset before and after last modification */
int16_t offset_before, offset_after;
};
/* Single range specification. */
struct ip_nat_range
{
/* Set to OR of flags above. */
unsigned int flags;
/* Inclusive: network order. */
__be32 min_ip, max_ip;
/* Inclusive: network order */
union ip_conntrack_manip_proto min, max;
};
/* For backwards compat: don't use in modern code. */
struct ip_nat_multi_range_compat
{
unsigned int rangesize; /* Must be 1. */
/* hangs off end. */
struct ip_nat_range range[1];
};
#ifdef __KERNEL__
#include <linux/list.h>
/* Protects NAT hash tables, and NAT-private part of conntracks. */
extern rwlock_t ip_nat_lock;
/* The structure embedded in the conntrack structure. */
struct ip_nat_info
{
struct list_head bysource;
struct ip_nat_seq seq[IP_CT_DIR_MAX];
};
struct ip_conntrack;
/* Set up the info structure to map into this range. */
extern unsigned int ip_nat_setup_info(struct ip_conntrack *conntrack,
const struct ip_nat_range *range,
unsigned int hooknum);
/* Is this tuple already taken? (not by us)*/
extern int ip_nat_used_tuple(const struct ip_conntrack_tuple *tuple,
const struct ip_conntrack *ignored_conntrack);
#else /* !__KERNEL__: iptables wants this to compile. */
#define ip_nat_multi_range ip_nat_multi_range_compat
#endif /*__KERNEL__*/
#endif
#ifndef _IP_NAT_CORE_H
#define _IP_NAT_CORE_H
#include <linux/list.h>
#include <linux/netfilter_ipv4/ip_conntrack.h>
/* This header used to share core functionality between the standalone
NAT module, and the compatibility layer's use of NAT for masquerading. */
extern unsigned int ip_nat_packet(struct ip_conntrack *ct,
enum ip_conntrack_info conntrackinfo,
unsigned int hooknum,
struct sk_buff **pskb);
extern int ip_nat_icmp_reply_translation(struct ip_conntrack *ct,
enum ip_conntrack_info ctinfo,
unsigned int hooknum,
struct sk_buff **pskb);
#endif /* _IP_NAT_CORE_H */
#ifndef _IP_NAT_HELPER_H
#define _IP_NAT_HELPER_H
/* NAT protocol helper routines. */
#include <linux/netfilter_ipv4/ip_conntrack.h>
#include <linux/module.h>
struct sk_buff;
/* These return true or false. */
extern int ip_nat_mangle_tcp_packet(struct sk_buff **skb,
struct ip_conntrack *ct,
enum ip_conntrack_info ctinfo,
unsigned int match_offset,
unsigned int match_len,
const char *rep_buffer,
unsigned int rep_len);
extern int ip_nat_mangle_udp_packet(struct sk_buff **skb,
struct ip_conntrack *ct,
enum ip_conntrack_info ctinfo,
unsigned int match_offset,
unsigned int match_len,
const char *rep_buffer,
unsigned int rep_len);
extern int ip_nat_seq_adjust(struct sk_buff **pskb,
struct ip_conntrack *ct,
enum ip_conntrack_info ctinfo);
/* Setup NAT on this expected conntrack so it follows master, but goes
* to port ct->master->saved_proto. */
extern void ip_nat_follow_master(struct ip_conntrack *ct,
struct ip_conntrack_expect *this);
#endif
/* PPTP constants and structs */
#ifndef _NAT_PPTP_H
#define _NAT_PPTP_H
/* conntrack private data */
struct ip_nat_pptp {
__be16 pns_call_id; /* NAT'ed PNS call id */
__be16 pac_call_id; /* NAT'ed PAC call id */
};
#endif /* _NAT_PPTP_H */
/* Header for use in defining a given protocol. */
#ifndef _IP_NAT_PROTOCOL_H
#define _IP_NAT_PROTOCOL_H
#include <linux/init.h>
#include <linux/list.h>
#include <linux/netfilter_ipv4/ip_nat.h>
#include <linux/netfilter/nfnetlink_conntrack.h>
struct iphdr;
struct ip_nat_range;
struct ip_nat_protocol
{
/* Protocol name */
const char *name;
/* Protocol number. */
unsigned int protonum;
struct module *me;
/* Translate a packet to the target according to manip type.
Return true if succeeded. */
int (*manip_pkt)(struct sk_buff **pskb,
unsigned int iphdroff,
const struct ip_conntrack_tuple *tuple,
enum ip_nat_manip_type maniptype);
/* Is the manipable part of the tuple between min and max incl? */
int (*in_range)(const struct ip_conntrack_tuple *tuple,
enum ip_nat_manip_type maniptype,
const union ip_conntrack_manip_proto *min,
const union ip_conntrack_manip_proto *max);
/* Alter the per-proto part of the tuple (depending on
maniptype), to give a unique tuple in the given range if
possible; return false if not. Per-protocol part of tuple
is initialized to the incoming packet. */
int (*unique_tuple)(struct ip_conntrack_tuple *tuple,
const struct ip_nat_range *range,
enum ip_nat_manip_type maniptype,
const struct ip_conntrack *conntrack);
int (*range_to_nfattr)(struct sk_buff *skb,
const struct ip_nat_range *range);
int (*nfattr_to_range)(struct nfattr *tb[],
struct ip_nat_range *range);
};
/* Protocol registration. */
extern int ip_nat_protocol_register(struct ip_nat_protocol *proto);
extern void ip_nat_protocol_unregister(struct ip_nat_protocol *proto);
extern struct ip_nat_protocol *ip_nat_proto_find_get(u_int8_t protocol);
extern void ip_nat_proto_put(struct ip_nat_protocol *proto);
/* Built-in protocols. */
extern struct ip_nat_protocol ip_nat_protocol_tcp;
extern struct ip_nat_protocol ip_nat_protocol_udp;
extern struct ip_nat_protocol ip_nat_protocol_icmp;
extern struct ip_nat_protocol ip_nat_unknown_protocol;
extern int init_protocols(void) __init;
extern void cleanup_protocols(void);
extern struct ip_nat_protocol *find_nat_proto(u_int16_t protonum);
extern int ip_nat_port_range_to_nfattr(struct sk_buff *skb,
const struct ip_nat_range *range);
extern int ip_nat_port_nfattr_to_range(struct nfattr *tb[],
struct ip_nat_range *range);
#endif /*_IP_NAT_PROTO_H*/
#ifndef _IP_NAT_RULE_H
#define _IP_NAT_RULE_H
#include <linux/netfilter_ipv4/ip_conntrack.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv4/ip_nat.h>
#ifdef __KERNEL__
extern int ip_nat_rule_init(void) __init;
extern void ip_nat_rule_cleanup(void);
extern int ip_nat_rule_find(struct sk_buff **pskb,
unsigned int hooknum,
const struct net_device *in,
const struct net_device *out,
struct ip_conntrack *ct,
struct ip_nat_info *info);
extern unsigned int
alloc_null_binding(struct ip_conntrack *conntrack,
struct ip_nat_info *info,
unsigned int hooknum);
extern unsigned int
alloc_null_binding_confirmed(struct ip_conntrack *conntrack,
struct ip_nat_info *info,
unsigned int hooknum);
#endif
#endif /* _IP_NAT_RULE_H */
......@@ -13,7 +13,7 @@ struct ipt_same_info
u_int32_t *iparray;
/* hangs off end. */
struct ip_nat_range range[IPT_SAME_MAX_RANGE];
struct nf_nat_range range[IPT_SAME_MAX_RANGE];
};
#endif /*_IPT_SAME_H*/
......@@ -250,6 +250,11 @@ static inline int nf_ct_is_dying(struct nf_conn *ct)
return test_bit(IPS_DYING_BIT, &ct->status);
}
static inline int nf_ct_is_untracked(const struct sk_buff *skb)
{
return (skb->nfct == &nf_conntrack_untracked.ct_general);
}
extern unsigned int nf_conntrack_htable_size;
extern int nf_conntrack_checksum;
extern atomic_t nf_conntrack_count;
......
#ifndef _NF_CONNTRACK_COMPAT_H
#define _NF_CONNTRACK_COMPAT_H
#ifdef __KERNEL__
#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)
#include <linux/netfilter_ipv4/ip_conntrack.h>
#include <linux/socket.h>
#ifdef CONFIG_IP_NF_CONNTRACK_MARK
static inline u_int32_t *nf_ct_get_mark(const struct sk_buff *skb,
u_int32_t *ctinfo)
{
struct ip_conntrack *ct = ip_conntrack_get(skb, ctinfo);
if (ct)
return &ct->mark;
else
return NULL;
}
#endif /* CONFIG_IP_NF_CONNTRACK_MARK */
#ifdef CONFIG_IP_NF_CONNTRACK_SECMARK
static inline u_int32_t *nf_ct_get_secmark(const struct sk_buff *skb,
u_int32_t *ctinfo)
{
struct ip_conntrack *ct = ip_conntrack_get(skb, ctinfo);
if (ct)
return &ct->secmark;
else
return NULL;
}
#endif /* CONFIG_IP_NF_CONNTRACK_SECMARK */
#ifdef CONFIG_IP_NF_CT_ACCT
static inline struct ip_conntrack_counter *
nf_ct_get_counters(const struct sk_buff *skb)
{
enum ip_conntrack_info ctinfo;
struct ip_conntrack *ct = ip_conntrack_get(skb, &ctinfo);
if (ct)
return ct->counters;
else
return NULL;
}
#endif /* CONFIG_IP_NF_CT_ACCT */
static inline int nf_ct_is_untracked(const struct sk_buff *skb)
{
return (skb->nfct == &ip_conntrack_untracked.ct_general);
}
static inline void nf_ct_untrack(struct sk_buff *skb)
{
skb->nfct = &ip_conntrack_untracked.ct_general;
}
static inline int nf_ct_get_ctinfo(const struct sk_buff *skb,
enum ip_conntrack_info *ctinfo)
{
struct ip_conntrack *ct = ip_conntrack_get(skb, ctinfo);
return (ct != NULL);
}
static inline int nf_ct_l3proto_try_module_get(unsigned short l3proto)
{
need_conntrack();
return l3proto == PF_INET ? 0 : -1;
}
static inline void nf_ct_l3proto_module_put(unsigned short l3proto)
{
}
#else /* CONFIG_IP_NF_CONNTRACK */
#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
#include <net/netfilter/nf_conntrack.h>
#ifdef CONFIG_NF_CONNTRACK_MARK
static inline u_int32_t *nf_ct_get_mark(const struct sk_buff *skb,
u_int32_t *ctinfo)
{
struct nf_conn *ct = nf_ct_get(skb, ctinfo);
if (ct)
return &ct->mark;
else
return NULL;
}
#endif /* CONFIG_NF_CONNTRACK_MARK */
#ifdef CONFIG_NF_CONNTRACK_SECMARK
static inline u_int32_t *nf_ct_get_secmark(const struct sk_buff *skb,
u_int32_t *ctinfo)
{
struct nf_conn *ct = nf_ct_get(skb, ctinfo);
if (ct)
return &ct->secmark;
else
return NULL;
}
#endif /* CONFIG_NF_CONNTRACK_MARK */
#ifdef CONFIG_NF_CT_ACCT
static inline struct ip_conntrack_counter *
nf_ct_get_counters(const struct sk_buff *skb)
{
enum ip_conntrack_info ctinfo;
struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
if (ct)
return ct->counters;
else
return NULL;
}
#endif /* CONFIG_NF_CT_ACCT */
static inline int nf_ct_is_untracked(const struct sk_buff *skb)
{
return (skb->nfct == &nf_conntrack_untracked.ct_general);
}
static inline void nf_ct_untrack(struct sk_buff *skb)
{
skb->nfct = &nf_conntrack_untracked.ct_general;
}
static inline int nf_ct_get_ctinfo(const struct sk_buff *skb,
enum ip_conntrack_info *ctinfo)
{
struct nf_conn *ct = nf_ct_get(skb, ctinfo);
return (ct != NULL);
}
#endif /* CONFIG_IP_NF_CONNTRACK */
#endif /* __KERNEL__ */
#endif /* _NF_CONNTRACK_COMPAT_H */
......@@ -4,16 +4,6 @@
#include <net/netfilter/nf_nat.h>
#include <linux/netfilter_ipv4/ip_tables.h>
/* Compatibility definitions for ipt_FOO modules */
#define ip_nat_range nf_nat_range
#define ip_conntrack_tuple nf_conntrack_tuple
#define ip_conntrack_get nf_ct_get
#define ip_conntrack nf_conn
#define ip_nat_setup_info nf_nat_setup_info
#define ip_nat_multi_range_compat nf_nat_multi_range_compat
#define ip_ct_iterate_cleanup nf_ct_iterate_cleanup
#define IP_NF_ASSERT NF_CT_ASSERT
extern int nf_nat_rule_init(void) __init;
extern void nf_nat_rule_cleanup(void);
extern int nf_nat_rule_find(struct sk_buff **pskb,
......
......@@ -30,188 +30,6 @@ config NF_CONNTRACK_PROC_COMPAT
If unsure, say Y.
# connection tracking, helpers and protocols
config IP_NF_CT_ACCT
bool "Connection tracking flow accounting"
depends on IP_NF_CONNTRACK
help
If this option is enabled, the connection tracking code will
keep per-flow packet and byte counters.
Those counters can be used for flow-based accounting or the
`connbytes' match.
If unsure, say `N'.
config IP_NF_CONNTRACK_MARK
bool 'Connection mark tracking support'
depends on IP_NF_CONNTRACK
help
This option enables support for connection marks, used by the
`CONNMARK' target and `connmark' match. Similar to the mark value
of packets, but this mark value is kept in the conntrack session
instead of the individual packets.
config IP_NF_CONNTRACK_SECMARK
bool 'Connection tracking security mark support'
depends on IP_NF_CONNTRACK && NETWORK_SECMARK
help
This option enables security markings to be applied to
connections. Typically they are copied to connections from
packets using the CONNSECMARK target and copied back from
connections to packets with the same target, with the packets
being originally labeled via SECMARK.
If unsure, say 'N'.
config IP_NF_CONNTRACK_EVENTS
bool "Connection tracking events (EXPERIMENTAL)"
depends on EXPERIMENTAL && IP_NF_CONNTRACK
help
If this option is enabled, the connection tracking code will
provide a notifier chain that can be used by other kernel code
to get notified about changes in the connection tracking state.
IF unsure, say `N'.
config IP_NF_CONNTRACK_NETLINK
tristate 'Connection tracking netlink interface (EXPERIMENTAL)'
depends on EXPERIMENTAL && IP_NF_CONNTRACK && NETFILTER_NETLINK
depends on IP_NF_CONNTRACK!=y || NETFILTER_NETLINK!=m
depends on IP_NF_NAT=n || IP_NF_NAT
help
This option enables support for a netlink-based userspace interface
config IP_NF_CT_PROTO_SCTP
tristate 'SCTP protocol connection tracking support (EXPERIMENTAL)'
depends on IP_NF_CONNTRACK && EXPERIMENTAL
help
With this option enabled, the connection tracking code will
be able to do state tracking on SCTP connections.
If you want to compile it as a module, say M here and read
<file:Documentation/modules.txt>. If unsure, say `N'.
config IP_NF_FTP
tristate "FTP protocol support"
depends on IP_NF_CONNTRACK
help
Tracking FTP connections is problematic: special helpers are
required for tracking them, and doing masquerading and other forms
of Network Address Translation on them.
To compile it as a module, choose M here. If unsure, say Y.
config IP_NF_IRC
tristate "IRC protocol support"
depends on IP_NF_CONNTRACK
---help---
There is a commonly-used extension to IRC called
Direct Client-to-Client Protocol (DCC). This enables users to send
files to each other, and also chat to each other without the need
of a server. DCC Sending is used anywhere you send files over IRC,
and DCC Chat is most commonly used by Eggdrop bots. If you are
using NAT, this extension will enable you to send files and initiate
chats. Note that you do NOT need this extension to get files or
have others initiate chats, or everything else in IRC.
To compile it as a module, choose M here. If unsure, say Y.
config IP_NF_NETBIOS_NS
tristate "NetBIOS name service protocol support (EXPERIMENTAL)"
depends on IP_NF_CONNTRACK && EXPERIMENTAL
help
NetBIOS name service requests are sent as broadcast messages from an
unprivileged port and responded to with unicast messages to the
same port. This make them hard to firewall properly because connection
tracking doesn't deal with broadcasts. This helper tracks locally
originating NetBIOS name service requests and the corresponding
responses. It relies on correct IP address configuration, specifically
netmask and broadcast address. When properly configured, the output
of "ip address show" should look similar to this:
$ ip -4 address show eth0
4: eth0: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 1000
inet 172.16.2.252/24 brd 172.16.2.255 scope global eth0
To compile it as a module, choose M here. If unsure, say N.
config IP_NF_TFTP
tristate "TFTP protocol support"
depends on IP_NF_CONNTRACK
help
TFTP connection tracking helper, this is required depending
on how restrictive your ruleset is.
If you are using a tftp client behind -j SNAT or -j MASQUERADING
you will need this.
To compile it as a module, choose M here. If unsure, say Y.
config IP_NF_AMANDA
tristate "Amanda backup protocol support"
depends on IP_NF_CONNTRACK
select TEXTSEARCH
select TEXTSEARCH_KMP
help
If you are running the Amanda backup package <http://www.amanda.org/>
on this machine or machines that will be MASQUERADED through this
machine, then you may want to enable this feature. This allows the
connection tracking and natting code to allow the sub-channels that
Amanda requires for communication of the backup data, messages and
index.
To compile it as a module, choose M here. If unsure, say Y.
config IP_NF_PPTP
tristate 'PPTP protocol support'
depends on IP_NF_CONNTRACK
help
This module adds support for PPTP (Point to Point Tunnelling
Protocol, RFC2637) connection tracking and NAT.
If you are running PPTP sessions over a stateful firewall or NAT
box, you may want to enable this feature.
Please note that not all PPTP modes of operation are supported yet.
For more info, read top of the file
net/ipv4/netfilter/ip_conntrack_pptp.c
If you want to compile it as a module, say M here and read
Documentation/modules.txt. If unsure, say `N'.
config IP_NF_H323
tristate 'H.323 protocol support (EXPERIMENTAL)'
depends on IP_NF_CONNTRACK && EXPERIMENTAL
help
H.323 is a VoIP signalling protocol from ITU-T. As one of the most
important VoIP protocols, it is widely used by voice hardware and
software including voice gateways, IP phones, Netmeeting, OpenPhone,
Gnomemeeting, etc.
With this module you can support H.323 on a connection tracking/NAT
firewall.
This module supports RAS, Fast Start, H.245 Tunnelling, Call
Forwarding, RTP/RTCP and T.120 based audio, video, fax, chat,
whiteboard, file transfer, etc. For more information, please
visit http://nath323.sourceforge.net/.
If you want to compile it as a module, say 'M' here and read
Documentation/modules.txt. If unsure, say 'N'.
config IP_NF_SIP
tristate "SIP protocol support (EXPERIMENTAL)"
depends on IP_NF_CONNTRACK && EXPERIMENTAL
help
SIP is an application-layer control protocol that can establish,
modify, and terminate multimedia sessions (conferences) such as
Internet telephony calls. With the ip_conntrack_sip and
the ip_nat_sip modules you can support the protocol on a connection
tracking/NATing firewall.
To compile it as a module, choose M here. If unsure, say Y.
config IP_NF_QUEUE
tristate "IP Userspace queueing via NETLINK (OBSOLETE)"
help
......@@ -361,17 +179,6 @@ config IP_NF_TARGET_ULOG
To compile it as a module, choose M here. If unsure, say N.
# NAT + specific targets: ip_conntrack
config IP_NF_NAT
tristate "Full NAT"
depends on IP_NF_IPTABLES && IP_NF_CONNTRACK
help
The Full NAT option allows masquerading, port forwarding and other
forms of full Network Address Port Translation. It is controlled by
the `nat' table in iptables: see the man page for iptables(8).
To compile it as a module, choose M here. If unsure, say N.
# NAT + specific targets: nf_conntrack
config NF_NAT
tristate "Full NAT"
......@@ -383,11 +190,6 @@ config NF_NAT
To compile it as a module, choose M here. If unsure, say N.
config IP_NF_NAT_NEEDED
bool
depends on IP_NF_NAT
default y
config NF_NAT_NEEDED
bool
depends on NF_NAT
......@@ -395,7 +197,7 @@ config NF_NAT_NEEDED
config IP_NF_TARGET_MASQUERADE
tristate "MASQUERADE target support"
depends on (NF_NAT || IP_NF_NAT)
depends on NF_NAT
help
Masquerading is a special case of NAT: all outgoing connections are
changed to seem to come from a particular interface's address, and
......@@ -407,7 +209,7 @@ config IP_NF_TARGET_MASQUERADE
config IP_NF_TARGET_REDIRECT
tristate "REDIRECT target support"
depends on (NF_NAT || IP_NF_NAT)
depends on NF_NAT
help
REDIRECT is a special case of NAT: all incoming connections are
mapped onto the incoming interface's address, causing the packets to
......@@ -418,7 +220,7 @@ config IP_NF_TARGET_REDIRECT
config IP_NF_TARGET_NETMAP
tristate "NETMAP target support"
depends on (NF_NAT || IP_NF_NAT)
depends on NF_NAT
help
NETMAP is an implementation of static 1:1 NAT mapping of network
addresses. It maps the network address part, while keeping the host
......@@ -429,28 +231,13 @@ config IP_NF_TARGET_NETMAP
config IP_NF_TARGET_SAME
tristate "SAME target support"
depends on (NF_NAT || IP_NF_NAT)
depends on NF_NAT
help
This option adds a `SAME' target, which works like the standard SNAT
target, but attempts to give clients the same IP for all connections.
To compile it as a module, choose M here. If unsure, say N.
config IP_NF_NAT_SNMP_BASIC
tristate "Basic SNMP-ALG support (EXPERIMENTAL)"
depends on EXPERIMENTAL && IP_NF_NAT
---help---
This module implements an Application Layer Gateway (ALG) for
SNMP payloads. In conjunction with NAT, it allows a network
management system to access multiple private networks with
conflicting addresses. It works by modifying IP addresses
inside SNMP payloads to match IP-layer NAT mapping.
This is the "basic" form of SNMP-ALG, as described in RFC 2962
To compile it as a module, choose M here. If unsure, say N.
config NF_NAT_SNMP_BASIC
tristate "Basic SNMP-ALG support (EXPERIMENTAL)"
depends on EXPERIMENTAL && NF_NAT
......@@ -477,78 +264,37 @@ config NF_NAT_PROTO_GRE
tristate
depends on NF_NAT && NF_CT_PROTO_GRE
config IP_NF_NAT_FTP
tristate
depends on IP_NF_IPTABLES && IP_NF_CONNTRACK && IP_NF_NAT
default IP_NF_NAT && IP_NF_FTP
config NF_NAT_FTP
tristate
depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
default NF_NAT && NF_CONNTRACK_FTP
config IP_NF_NAT_IRC
tristate
depends on IP_NF_IPTABLES!=n && IP_NF_CONNTRACK!=n && IP_NF_NAT!=n
default IP_NF_NAT if IP_NF_IRC=y
default m if IP_NF_IRC=m
config NF_NAT_IRC
tristate
depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
default NF_NAT && NF_CONNTRACK_IRC
config IP_NF_NAT_TFTP
tristate
depends on IP_NF_IPTABLES!=n && IP_NF_CONNTRACK!=n && IP_NF_NAT!=n
default IP_NF_NAT if IP_NF_TFTP=y
default m if IP_NF_TFTP=m
config NF_NAT_TFTP
tristate
depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
default NF_NAT && NF_CONNTRACK_TFTP
config IP_NF_NAT_AMANDA
tristate
depends on IP_NF_IPTABLES!=n && IP_NF_CONNTRACK!=n && IP_NF_NAT!=n
default IP_NF_NAT if IP_NF_AMANDA=y
default m if IP_NF_AMANDA=m
config NF_NAT_AMANDA
tristate
depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
default NF_NAT && NF_CONNTRACK_AMANDA
config IP_NF_NAT_PPTP
tristate
depends on IP_NF_NAT!=n && IP_NF_PPTP!=n
default IP_NF_NAT if IP_NF_PPTP=y
default m if IP_NF_PPTP=m
config NF_NAT_PPTP
tristate
depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
default NF_NAT && NF_CONNTRACK_PPTP
select NF_NAT_PROTO_GRE
config IP_NF_NAT_H323
tristate
depends on IP_NF_IPTABLES!=n && IP_NF_CONNTRACK!=n && IP_NF_NAT!=n
default IP_NF_NAT if IP_NF_H323=y
default m if IP_NF_H323=m
config NF_NAT_H323
tristate
depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
default NF_NAT && NF_CONNTRACK_H323
config IP_NF_NAT_SIP
tristate
depends on IP_NF_IPTABLES!=n && IP_NF_CONNTRACK!=n && IP_NF_NAT!=n
default IP_NF_NAT if IP_NF_SIP=y
default m if IP_NF_SIP=m
config NF_NAT_SIP
tristate
depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
......@@ -606,9 +352,8 @@ config IP_NF_TARGET_TTL
config IP_NF_TARGET_CLUSTERIP
tristate "CLUSTERIP target support (EXPERIMENTAL)"
depends on IP_NF_MANGLE && EXPERIMENTAL
depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4
select IP_NF_CONNTRACK_MARK if IP_NF_CONNTRACK
select NF_CONNTRACK_MARK if NF_CONNTRACK_IPV4
depends on NF_CONNTRACK_IPV4
select NF_CONNTRACK_MARK
help
The CLUSTERIP target allows you to build load-balancing clusters of
network servers without having a dedicated load-balancing
......
......@@ -2,8 +2,6 @@
# Makefile for the netfilter modules on top of IPv4.
#
# objects for the standalone - connection tracking / NAT
ip_conntrack-objs := ip_conntrack_standalone.o ip_conntrack_core.o ip_conntrack_proto_generic.o ip_conntrack_proto_tcp.o ip_conntrack_proto_udp.o ip_conntrack_proto_icmp.o
# objects for l3 independent conntrack
nf_conntrack_ipv4-objs := nf_conntrack_l3proto_ipv4.o nf_conntrack_proto_icmp.o
ifeq ($(CONFIG_NF_CONNTRACK_PROC_COMPAT),y)
......@@ -12,53 +10,14 @@ nf_conntrack_ipv4-objs += nf_conntrack_l3proto_ipv4_compat.o
endif
endif
ip_nat-objs := ip_nat_core.o ip_nat_helper.o ip_nat_proto_unknown.o ip_nat_proto_tcp.o ip_nat_proto_udp.o ip_nat_proto_icmp.o
nf_nat-objs := nf_nat_core.o nf_nat_helper.o nf_nat_proto_unknown.o nf_nat_proto_tcp.o nf_nat_proto_udp.o nf_nat_proto_icmp.o
ifneq ($(CONFIG_NF_NAT),)
nf_nat-objs := nf_nat_core.o nf_nat_helper.o nf_nat_proto_unknown.o nf_nat_proto_tcp.o nf_nat_proto_udp.o nf_nat_proto_icmp.o
iptable_nat-objs := nf_nat_rule.o nf_nat_standalone.o
else
iptable_nat-objs := ip_nat_rule.o ip_nat_standalone.o
endif
ip_conntrack_pptp-objs := ip_conntrack_helper_pptp.o ip_conntrack_proto_gre.o
ip_nat_pptp-objs := ip_nat_helper_pptp.o ip_nat_proto_gre.o
ip_conntrack_h323-objs := ip_conntrack_helper_h323.o ../../netfilter/nf_conntrack_h323_asn1.o
ip_nat_h323-objs := ip_nat_helper_h323.o
# connection tracking
obj-$(CONFIG_IP_NF_CONNTRACK) += ip_conntrack.o
obj-$(CONFIG_NF_CONNTRACK_IPV4) += nf_conntrack_ipv4.o
obj-$(CONFIG_IP_NF_NAT) += ip_nat.o
obj-$(CONFIG_NF_NAT) += nf_nat.o
# conntrack netlink interface
obj-$(CONFIG_IP_NF_CONNTRACK_NETLINK) += ip_conntrack_netlink.o
# SCTP protocol connection tracking
obj-$(CONFIG_IP_NF_CT_PROTO_SCTP) += ip_conntrack_proto_sctp.o
# connection tracking helpers
obj-$(CONFIG_IP_NF_H323) += ip_conntrack_h323.o
obj-$(CONFIG_IP_NF_PPTP) += ip_conntrack_pptp.o
obj-$(CONFIG_IP_NF_AMANDA) += ip_conntrack_amanda.o
obj-$(CONFIG_IP_NF_TFTP) += ip_conntrack_tftp.o
obj-$(CONFIG_IP_NF_FTP) += ip_conntrack_ftp.o
obj-$(CONFIG_IP_NF_IRC) += ip_conntrack_irc.o
obj-$(CONFIG_IP_NF_SIP) += ip_conntrack_sip.o
obj-$(CONFIG_IP_NF_NETBIOS_NS) += ip_conntrack_netbios_ns.o
# NAT helpers (ip_conntrack)
obj-$(CONFIG_IP_NF_NAT_H323) += ip_nat_h323.o
obj-$(CONFIG_IP_NF_NAT_PPTP) += ip_nat_pptp.o
obj-$(CONFIG_IP_NF_NAT_AMANDA) += ip_nat_amanda.o
obj-$(CONFIG_IP_NF_NAT_TFTP) += ip_nat_tftp.o
obj-$(CONFIG_IP_NF_NAT_FTP) += ip_nat_ftp.o
obj-$(CONFIG_IP_NF_NAT_IRC) += ip_nat_irc.o
obj-$(CONFIG_IP_NF_NAT_SIP) += ip_nat_sip.o
# NAT helpers (nf_conntrack)
obj-$(CONFIG_NF_NAT_AMANDA) += nf_nat_amanda.o
obj-$(CONFIG_NF_NAT_FTP) += nf_nat_ftp.o
......@@ -78,7 +37,6 @@ obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o
# the three 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_NF_NAT) += iptable_nat.o
obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o
......@@ -100,7 +58,6 @@ obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o
obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o
obj-$(CONFIG_IP_NF_TARGET_SAME) += ipt_SAME.o
obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o
obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o
obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o
......
/* Amanda extension for IP connection tracking, Version 0.2
* (C) 2002 by Brian J. Murrell <netfilter@interlinx.bc.ca>
* based on HW's ip_conntrack_irc.c as well as other modules
*
* 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.
*
* Module load syntax:
* insmod ip_conntrack_amanda.o [master_timeout=n]
*
* Where master_timeout is the timeout (in seconds) of the master
* connection (port 10080). This defaults to 5 minutes but if
* your clients take longer than 5 minutes to do their work
* before getting back to the Amanda server, you can increase
* this value.
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/textsearch.h>
#include <linux/skbuff.h>
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/udp.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
#include <linux/netfilter_ipv4/ip_conntrack_amanda.h>
static unsigned int master_timeout = 300;
static char *ts_algo = "kmp";
MODULE_AUTHOR("Brian J. Murrell <netfilter@interlinx.bc.ca>");
MODULE_DESCRIPTION("Amanda connection tracking module");
MODULE_LICENSE("GPL");
module_param(master_timeout, uint, 0600);
MODULE_PARM_DESC(master_timeout, "timeout for the master connection");
module_param(ts_algo, charp, 0400);
MODULE_PARM_DESC(ts_algo, "textsearch algorithm to use (default kmp)");
unsigned int (*ip_nat_amanda_hook)(struct sk_buff **pskb,
enum ip_conntrack_info ctinfo,
unsigned int matchoff,
unsigned int matchlen,
struct ip_conntrack_expect *exp);
EXPORT_SYMBOL_GPL(ip_nat_amanda_hook);
enum amanda_strings {
SEARCH_CONNECT,
SEARCH_NEWLINE,
SEARCH_DATA,
SEARCH_MESG,
SEARCH_INDEX,
};
static struct {
char *string;
size_t len;
struct ts_config *ts;
} search[] = {
[SEARCH_CONNECT] = {
.string = "CONNECT ",
.len = 8,
},
[SEARCH_NEWLINE] = {
.string = "\n",
.len = 1,
},
[SEARCH_DATA] = {
.string = "DATA ",
.len = 5,
},
[SEARCH_MESG] = {
.string = "MESG ",
.len = 5,
},
[SEARCH_INDEX] = {
.string = "INDEX ",
.len = 6,
},
};
static int help(struct sk_buff **pskb,
struct ip_conntrack *ct, enum ip_conntrack_info ctinfo)
{
struct ts_state ts;
struct ip_conntrack_expect *exp;
unsigned int dataoff, start, stop, off, i;
char pbuf[sizeof("65535")], *tmp;
u_int16_t port, len;
int ret = NF_ACCEPT;
typeof(ip_nat_amanda_hook) ip_nat_amanda;
/* Only look at packets from the Amanda server */
if (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL)
return NF_ACCEPT;
/* increase the UDP timeout of the master connection as replies from
* Amanda clients to the server can be quite delayed */
ip_ct_refresh(ct, *pskb, master_timeout * HZ);
/* No data? */
dataoff = ip_hdrlen(*pskb) + sizeof(struct udphdr);
if (dataoff >= (*pskb)->len) {
if (net_ratelimit())
printk("amanda_help: skblen = %u\n", (*pskb)->len);
return NF_ACCEPT;
}
memset(&ts, 0, sizeof(ts));
start = skb_find_text(*pskb, dataoff, (*pskb)->len,
search[SEARCH_CONNECT].ts, &ts);
if (start == UINT_MAX)
goto out;
start += dataoff + search[SEARCH_CONNECT].len;
memset(&ts, 0, sizeof(ts));
stop = skb_find_text(*pskb, start, (*pskb)->len,
search[SEARCH_NEWLINE].ts, &ts);
if (stop == UINT_MAX)
goto out;
stop += start;
for (i = SEARCH_DATA; i <= SEARCH_INDEX; i++) {
memset(&ts, 0, sizeof(ts));
off = skb_find_text(*pskb, start, stop, search[i].ts, &ts);
if (off == UINT_MAX)
continue;
off += start + search[i].len;
len = min_t(unsigned int, sizeof(pbuf) - 1, stop - off);
if (skb_copy_bits(*pskb, off, pbuf, len))
break;
pbuf[len] = '\0';
port = simple_strtoul(pbuf, &tmp, 10);
len = tmp - pbuf;
if (port == 0 || len > 5)
break;
exp = ip_conntrack_expect_alloc(ct);
if (exp == NULL) {
ret = NF_DROP;
goto out;
}
exp->expectfn = NULL;
exp->flags = 0;
exp->tuple.src.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
exp->tuple.src.u.tcp.port = 0;
exp->tuple.dst.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip;
exp->tuple.dst.protonum = IPPROTO_TCP;
exp->tuple.dst.u.tcp.port = htons(port);
exp->mask.src.ip = htonl(0xFFFFFFFF);
exp->mask.src.u.tcp.port = 0;
exp->mask.dst.ip = htonl(0xFFFFFFFF);
exp->mask.dst.protonum = 0xFF;
exp->mask.dst.u.tcp.port = htons(0xFFFF);
/* RCU read locked by nf_hook_slow */
ip_nat_amanda = rcu_dereference(ip_nat_amanda_hook);
if (ip_nat_amanda)
ret = ip_nat_amanda(pskb, ctinfo, off - dataoff,
len, exp);
else if (ip_conntrack_expect_related(exp) != 0)
ret = NF_DROP;
ip_conntrack_expect_put(exp);
}
out:
return ret;
}
static struct ip_conntrack_helper amanda_helper = {
.max_expected = 3,
.timeout = 180,
.me = THIS_MODULE,
.help = help,
.name = "amanda",
.tuple = { .src = { .u = { .udp = {.port = __constant_htons(10080) } } },
.dst = { .protonum = IPPROTO_UDP },
},
.mask = { .src = { .u = { 0xFFFF } },
.dst = { .protonum = 0xFF },
},
};
static void __exit ip_conntrack_amanda_fini(void)
{
int i;
ip_conntrack_helper_unregister(&amanda_helper);
for (i = 0; i < ARRAY_SIZE(search); i++)
textsearch_destroy(search[i].ts);
}
static int __init ip_conntrack_amanda_init(void)
{
int ret, i;
ret = -ENOMEM;
for (i = 0; i < ARRAY_SIZE(search); i++) {
search[i].ts = textsearch_prepare(ts_algo, search[i].string,
search[i].len,
GFP_KERNEL, TS_AUTOLOAD);
if (search[i].ts == NULL)
goto err;
}
ret = ip_conntrack_helper_register(&amanda_helper);
if (ret < 0)
goto err;
return 0;
err:
for (; i >= 0; i--) {
if (search[i].ts)
textsearch_destroy(search[i].ts);
}
return ret;
}
module_init(ip_conntrack_amanda_init);
module_exit(ip_conntrack_amanda_fini);
此差异已折叠。
/* FTP extension for IP connection tracking. */
/* (C) 1999-2001 Paul `Rusty' Russell
* (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/netfilter.h>
#include <linux/ip.h>
#include <linux/ctype.h>
#include <net/checksum.h>
#include <net/tcp.h>
#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
#include <linux/netfilter_ipv4/ip_conntrack_ftp.h>
#include <linux/moduleparam.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Rusty Russell <rusty@rustcorp.com.au>");
MODULE_DESCRIPTION("ftp connection tracking helper");
/* This is slow, but it's simple. --RR */
static char *ftp_buffer;
static DEFINE_SPINLOCK(ip_ftp_lock);
#define MAX_PORTS 8
static unsigned short ports[MAX_PORTS];
static int ports_c;
module_param_array(ports, ushort, &ports_c, 0400);
static int loose;
module_param(loose, bool, 0600);
unsigned int (*ip_nat_ftp_hook)(struct sk_buff **pskb,
enum ip_conntrack_info ctinfo,
enum ip_ct_ftp_type type,
unsigned int matchoff,
unsigned int matchlen,
struct ip_conntrack_expect *exp,
u32 *seq);
EXPORT_SYMBOL_GPL(ip_nat_ftp_hook);
#if 0
#define DEBUGP printk
#else
#define DEBUGP(format, args...)
#endif
static int try_rfc959(const char *, size_t, u_int32_t [], char);
static int try_eprt(const char *, size_t, u_int32_t [], char);
static int try_epsv_response(const char *, size_t, u_int32_t [], char);
static const struct ftp_search {
const char *pattern;
size_t plen;
char skip;
char term;
enum ip_ct_ftp_type ftptype;
int (*getnum)(const char *, size_t, u_int32_t[], char);
} search[IP_CT_DIR_MAX][2] = {
[IP_CT_DIR_ORIGINAL] = {
{
.pattern = "PORT",
.plen = sizeof("PORT") - 1,
.skip = ' ',
.term = '\r',
.ftptype = IP_CT_FTP_PORT,
.getnum = try_rfc959,
},
{
.pattern = "EPRT",
.plen = sizeof("EPRT") - 1,
.skip = ' ',
.term = '\r',
.ftptype = IP_CT_FTP_EPRT,
.getnum = try_eprt,
},
},
[IP_CT_DIR_REPLY] = {
{
.pattern = "227 ",
.plen = sizeof("227 ") - 1,
.skip = '(',
.term = ')',
.ftptype = IP_CT_FTP_PASV,
.getnum = try_rfc959,
},
{
.pattern = "229 ",
.plen = sizeof("229 ") - 1,
.skip = '(',
.term = ')',
.ftptype = IP_CT_FTP_EPSV,
.getnum = try_epsv_response,
},
},
};
static int try_number(const char *data, size_t dlen, u_int32_t array[],
int array_size, char sep, char term)
{
u_int32_t i, len;
memset(array, 0, sizeof(array[0])*array_size);
/* Keep data pointing at next char. */
for (i = 0, len = 0; len < dlen && i < array_size; len++, data++) {
if (*data >= '0' && *data <= '9') {
array[i] = array[i]*10 + *data - '0';
}
else if (*data == sep)
i++;
else {
/* Unexpected character; true if it's the
terminator and we're finished. */
if (*data == term && i == array_size - 1)
return len;
DEBUGP("Char %u (got %u nums) `%u' unexpected\n",
len, i, *data);
return 0;
}
}
DEBUGP("Failed to fill %u numbers separated by %c\n", array_size, sep);
return 0;
}
/* Returns 0, or length of numbers: 192,168,1,1,5,6 */
static int try_rfc959(const char *data, size_t dlen, u_int32_t array[6],
char term)
{
return try_number(data, dlen, array, 6, ',', term);
}
/* Grab port: number up to delimiter */
static int get_port(const char *data, int start, size_t dlen, char delim,
u_int32_t array[2])
{
u_int16_t port = 0;
int i;
for (i = start; i < dlen; i++) {
/* Finished? */
if (data[i] == delim) {
if (port == 0)
break;
array[0] = port >> 8;
array[1] = port;
return i + 1;
}
else if (data[i] >= '0' && data[i] <= '9')
port = port*10 + data[i] - '0';
else /* Some other crap */
break;
}
return 0;
}
/* Returns 0, or length of numbers: |1|132.235.1.2|6275| */
static int try_eprt(const char *data, size_t dlen, u_int32_t array[6],
char term)
{
char delim;
int length;
/* First character is delimiter, then "1" for IPv4, then
delimiter again. */
if (dlen <= 3) return 0;
delim = data[0];
if (isdigit(delim) || delim < 33 || delim > 126
|| data[1] != '1' || data[2] != delim)
return 0;
DEBUGP("EPRT: Got |1|!\n");
/* Now we have IP address. */
length = try_number(data + 3, dlen - 3, array, 4, '.', delim);
if (length == 0)
return 0;
DEBUGP("EPRT: Got IP address!\n");
/* Start offset includes initial "|1|", and trailing delimiter */
return get_port(data, 3 + length + 1, dlen, delim, array+4);
}
/* Returns 0, or length of numbers: |||6446| */
static int try_epsv_response(const char *data, size_t dlen, u_int32_t array[6],
char term)
{
char delim;
/* Three delimiters. */
if (dlen <= 3) return 0;
delim = data[0];
if (isdigit(delim) || delim < 33 || delim > 126
|| data[1] != delim || data[2] != delim)
return 0;
return get_port(data, 3, dlen, delim, array+4);
}
/* Return 1 for match, 0 for accept, -1 for partial. */
static int find_pattern(const char *data, size_t dlen,
const char *pattern, size_t plen,
char skip, char term,
unsigned int *numoff,
unsigned int *numlen,
u_int32_t array[6],
int (*getnum)(const char *, size_t, u_int32_t[], char))
{
size_t i;
DEBUGP("find_pattern `%s': dlen = %u\n", pattern, dlen);
if (dlen == 0)
return 0;
if (dlen <= plen) {
/* Short packet: try for partial? */
if (strnicmp(data, pattern, dlen) == 0)
return -1;
else return 0;
}
if (strnicmp(data, pattern, plen) != 0) {
#if 0
size_t i;
DEBUGP("ftp: string mismatch\n");
for (i = 0; i < plen; i++) {
DEBUGP("ftp:char %u `%c'(%u) vs `%c'(%u)\n",
i, data[i], data[i],
pattern[i], pattern[i]);
}
#endif
return 0;
}
DEBUGP("Pattern matches!\n");
/* Now we've found the constant string, try to skip
to the 'skip' character */
for (i = plen; data[i] != skip; i++)
if (i == dlen - 1) return -1;
/* Skip over the last character */
i++;
DEBUGP("Skipped up to `%c'!\n", skip);
*numoff = i;
*numlen = getnum(data + i, dlen - i, array, term);
if (!*numlen)
return -1;
DEBUGP("Match succeeded!\n");
return 1;
}
/* Look up to see if we're just after a \n. */
static int find_nl_seq(u32 seq, const struct ip_ct_ftp_master *info, int dir)
{
unsigned int i;
for (i = 0; i < info->seq_aft_nl_num[dir]; i++)
if (info->seq_aft_nl[dir][i] == seq)
return 1;
return 0;
}
/* We don't update if it's older than what we have. */
static void update_nl_seq(u32 nl_seq, struct ip_ct_ftp_master *info, int dir,
struct sk_buff *skb)
{
unsigned int i, oldest = NUM_SEQ_TO_REMEMBER;
/* Look for oldest: if we find exact match, we're done. */
for (i = 0; i < info->seq_aft_nl_num[dir]; i++) {
if (info->seq_aft_nl[dir][i] == nl_seq)
return;
if (oldest == info->seq_aft_nl_num[dir]
|| before(info->seq_aft_nl[dir][i], oldest))
oldest = i;
}
if (info->seq_aft_nl_num[dir] < NUM_SEQ_TO_REMEMBER) {
info->seq_aft_nl[dir][info->seq_aft_nl_num[dir]++] = nl_seq;
ip_conntrack_event_cache(IPCT_HELPINFO_VOLATILE, skb);
} else if (oldest != NUM_SEQ_TO_REMEMBER) {
info->seq_aft_nl[dir][oldest] = nl_seq;
ip_conntrack_event_cache(IPCT_HELPINFO_VOLATILE, skb);
}
}
static int help(struct sk_buff **pskb,
struct ip_conntrack *ct,
enum ip_conntrack_info ctinfo)
{
unsigned int dataoff, datalen;
struct tcphdr _tcph, *th;
char *fb_ptr;
int ret;
u32 seq, array[6] = { 0 };
int dir = CTINFO2DIR(ctinfo);
unsigned int matchlen, matchoff;
struct ip_ct_ftp_master *ct_ftp_info = &ct->help.ct_ftp_info;
struct ip_conntrack_expect *exp;
unsigned int i;
int found = 0, ends_in_nl;
typeof(ip_nat_ftp_hook) ip_nat_ftp;
/* Until there's been traffic both ways, don't look in packets. */
if (ctinfo != IP_CT_ESTABLISHED
&& ctinfo != IP_CT_ESTABLISHED+IP_CT_IS_REPLY) {
DEBUGP("ftp: Conntrackinfo = %u\n", ctinfo);
return NF_ACCEPT;
}
th = skb_header_pointer(*pskb, ip_hdrlen(*pskb),
sizeof(_tcph), &_tcph);
if (th == NULL)
return NF_ACCEPT;
dataoff = ip_hdrlen(*pskb) + th->doff * 4;
/* No data? */
if (dataoff >= (*pskb)->len) {
DEBUGP("ftp: pskblen = %u\n", (*pskb)->len);
return NF_ACCEPT;
}
datalen = (*pskb)->len - dataoff;
spin_lock_bh(&ip_ftp_lock);
fb_ptr = skb_header_pointer(*pskb, dataoff,
(*pskb)->len - dataoff, ftp_buffer);
BUG_ON(fb_ptr == NULL);
ends_in_nl = (fb_ptr[datalen - 1] == '\n');
seq = ntohl(th->seq) + datalen;
/* Look up to see if we're just after a \n. */
if (!find_nl_seq(ntohl(th->seq), ct_ftp_info, dir)) {
/* Now if this ends in \n, update ftp info. */
DEBUGP("ip_conntrack_ftp_help: wrong seq pos %s(%u) or %s(%u)\n",
ct_ftp_info->seq_aft_nl[0][dir]
old_seq_aft_nl_set ? "":"(UNSET) ", old_seq_aft_nl);
ret = NF_ACCEPT;
goto out_update_nl;
}
/* Initialize IP array to expected address (it's not mentioned
in EPSV responses) */
array[0] = (ntohl(ct->tuplehash[dir].tuple.src.ip) >> 24) & 0xFF;
array[1] = (ntohl(ct->tuplehash[dir].tuple.src.ip) >> 16) & 0xFF;
array[2] = (ntohl(ct->tuplehash[dir].tuple.src.ip) >> 8) & 0xFF;
array[3] = ntohl(ct->tuplehash[dir].tuple.src.ip) & 0xFF;
for (i = 0; i < ARRAY_SIZE(search[dir]); i++) {
found = find_pattern(fb_ptr, (*pskb)->len - dataoff,
search[dir][i].pattern,
search[dir][i].plen,
search[dir][i].skip,
search[dir][i].term,
&matchoff, &matchlen,
array,
search[dir][i].getnum);
if (found) break;
}
if (found == -1) {
/* We don't usually drop packets. After all, this is
connection tracking, not packet filtering.
However, it is necessary for accurate tracking in
this case. */
if (net_ratelimit())
printk("conntrack_ftp: partial %s %u+%u\n",
search[dir][i].pattern,
ntohl(th->seq), datalen);
ret = NF_DROP;
goto out;
} else if (found == 0) { /* No match */
ret = NF_ACCEPT;
goto out_update_nl;
}
DEBUGP("conntrack_ftp: match `%s' (%u bytes at %u)\n",
fb_ptr + matchoff, matchlen, ntohl(th->seq) + matchoff);
/* Allocate expectation which will be inserted */
exp = ip_conntrack_expect_alloc(ct);
if (exp == NULL) {
ret = NF_DROP;
goto out;
}
/* We refer to the reverse direction ("!dir") tuples here,
* because we're expecting something in the other direction.
* Doesn't matter unless NAT is happening. */
exp->tuple.dst.ip = ct->tuplehash[!dir].tuple.dst.ip;
if (htonl((array[0] << 24) | (array[1] << 16) | (array[2] << 8) | array[3])
!= ct->tuplehash[dir].tuple.src.ip) {
/* Enrico Scholz's passive FTP to partially RNAT'd ftp
server: it really wants us to connect to a
different IP address. Simply don't record it for
NAT. */
DEBUGP("conntrack_ftp: NOT RECORDING: %u,%u,%u,%u != %u.%u.%u.%u\n",
array[0], array[1], array[2], array[3],
NIPQUAD(ct->tuplehash[dir].tuple.src.ip));
/* Thanks to Cristiano Lincoln Mattos
<lincoln@cesar.org.br> for reporting this potential
problem (DMZ machines opening holes to internal
networks, or the packet filter itself). */
if (!loose) {
ret = NF_ACCEPT;
goto out_put_expect;
}
exp->tuple.dst.ip = htonl((array[0] << 24) | (array[1] << 16)
| (array[2] << 8) | array[3]);
}
exp->tuple.src.ip = ct->tuplehash[!dir].tuple.src.ip;
exp->tuple.dst.u.tcp.port = htons(array[4] << 8 | array[5]);
exp->tuple.src.u.tcp.port = 0; /* Don't care. */
exp->tuple.dst.protonum = IPPROTO_TCP;
exp->mask = ((struct ip_conntrack_tuple)
{ { htonl(0xFFFFFFFF), { 0 } },
{ htonl(0xFFFFFFFF), { .tcp = { htons(0xFFFF) } }, 0xFF }});
exp->expectfn = NULL;
exp->flags = 0;
/* Now, NAT might want to mangle the packet, and register the
* (possibly changed) expectation itself. */
ip_nat_ftp = rcu_dereference(ip_nat_ftp_hook);
if (ip_nat_ftp)
ret = ip_nat_ftp(pskb, ctinfo, search[dir][i].ftptype,
matchoff, matchlen, exp, &seq);
else {
/* Can't expect this? Best to drop packet now. */
if (ip_conntrack_expect_related(exp) != 0)
ret = NF_DROP;
else
ret = NF_ACCEPT;
}
out_put_expect:
ip_conntrack_expect_put(exp);
out_update_nl:
/* Now if this ends in \n, update ftp info. Seq may have been
* adjusted by NAT code. */
if (ends_in_nl)
update_nl_seq(seq, ct_ftp_info,dir, *pskb);
out:
spin_unlock_bh(&ip_ftp_lock);
return ret;
}
static struct ip_conntrack_helper ftp[MAX_PORTS];
static char ftp_names[MAX_PORTS][sizeof("ftp-65535")];
/* Not __exit: called from init() */
static void ip_conntrack_ftp_fini(void)
{
int i;
for (i = 0; i < ports_c; i++) {
DEBUGP("ip_ct_ftp: unregistering helper for port %d\n",
ports[i]);
ip_conntrack_helper_unregister(&ftp[i]);
}
kfree(ftp_buffer);
}
static int __init ip_conntrack_ftp_init(void)
{
int i, ret;
char *tmpname;
ftp_buffer = kmalloc(65536, GFP_KERNEL);
if (!ftp_buffer)
return -ENOMEM;
if (ports_c == 0)
ports[ports_c++] = FTP_PORT;
for (i = 0; i < ports_c; i++) {
ftp[i].tuple.src.u.tcp.port = htons(ports[i]);
ftp[i].tuple.dst.protonum = IPPROTO_TCP;
ftp[i].mask.src.u.tcp.port = htons(0xFFFF);
ftp[i].mask.dst.protonum = 0xFF;
ftp[i].max_expected = 1;
ftp[i].timeout = 5 * 60; /* 5 minutes */
ftp[i].me = THIS_MODULE;
ftp[i].help = help;
tmpname = &ftp_names[i][0];
if (ports[i] == FTP_PORT)
sprintf(tmpname, "ftp");
else
sprintf(tmpname, "ftp-%d", ports[i]);
ftp[i].name = tmpname;
DEBUGP("ip_ct_ftp: registering helper for port %d\n",
ports[i]);
ret = ip_conntrack_helper_register(&ftp[i]);
if (ret) {
ip_conntrack_ftp_fini();
return ret;
}
}
return 0;
}
module_init(ip_conntrack_ftp_init);
module_exit(ip_conntrack_ftp_fini);
此差异已折叠。
此差异已折叠。
/* IRC extension for IP connection tracking, Version 1.21
* (C) 2000-2002 by Harald Welte <laforge@gnumonks.org>
* based on RR's ip_conntrack_ftp.c
*
* ip_conntrack_irc.c,v 1.21 2002/02/05 14:49:26 laforge Exp
*
* 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.
**
* Module load syntax:
* insmod ip_conntrack_irc.o ports=port1,port2,...port<MAX_PORTS>
* max_dcc_channels=n dcc_timeout=secs
*
* please give the ports of all IRC servers You wish to connect to.
* If You don't specify ports, the default will be port 6667.
* With max_dcc_channels you can define the maximum number of not
* yet answered DCC channels per IRC session (default 8).
* With dcc_timeout you can specify how long the system waits for
* an expected DCC channel (default 300 seconds).
*
*/
#include <linux/module.h>
#include <linux/netfilter.h>
#include <linux/ip.h>
#include <net/checksum.h>
#include <net/tcp.h>
#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
#include <linux/netfilter_ipv4/ip_conntrack_irc.h>
#include <linux/moduleparam.h>
#define MAX_PORTS 8
static unsigned short ports[MAX_PORTS];
static int ports_c;
static unsigned int max_dcc_channels = 8;
static unsigned int dcc_timeout = 300;
/* This is slow, but it's simple. --RR */
static char *irc_buffer;
static DEFINE_SPINLOCK(irc_buffer_lock);
unsigned int (*ip_nat_irc_hook)(struct sk_buff **pskb,
enum ip_conntrack_info ctinfo,
unsigned int matchoff,
unsigned int matchlen,
struct ip_conntrack_expect *exp);
EXPORT_SYMBOL_GPL(ip_nat_irc_hook);
MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
MODULE_DESCRIPTION("IRC (DCC) connection tracking helper");
MODULE_LICENSE("GPL");
module_param_array(ports, ushort, &ports_c, 0400);
MODULE_PARM_DESC(ports, "port numbers of IRC servers");
module_param(max_dcc_channels, uint, 0400);
MODULE_PARM_DESC(max_dcc_channels, "max number of expected DCC channels per IRC session");
module_param(dcc_timeout, uint, 0400);
MODULE_PARM_DESC(dcc_timeout, "timeout on for unestablished DCC channels");
static const char *dccprotos[] = { "SEND ", "CHAT ", "MOVE ", "TSEND ", "SCHAT " };
#define MINMATCHLEN 5
#if 0
#define DEBUGP(format, args...) printk(KERN_DEBUG "%s:%s:" format, \
__FILE__, __FUNCTION__ , ## args)
#else
#define DEBUGP(format, args...)
#endif
static int parse_dcc(char *data, char *data_end, u_int32_t *ip,
u_int16_t *port, char **ad_beg_p, char **ad_end_p)
/* tries to get the ip_addr and port out of a dcc command
return value: -1 on failure, 0 on success
data pointer to first byte of DCC command data
data_end pointer to last byte of dcc command data
ip returns parsed ip of dcc command
port returns parsed port of dcc command
ad_beg_p returns pointer to first byte of addr data
ad_end_p returns pointer to last byte of addr data */
{
/* at least 12: "AAAAAAAA P\1\n" */
while (*data++ != ' ')
if (data > data_end - 12)
return -1;
*ad_beg_p = data;
*ip = simple_strtoul(data, &data, 10);
/* skip blanks between ip and port */
while (*data == ' ') {
if (data >= data_end)
return -1;
data++;
}
*port = simple_strtoul(data, &data, 10);
*ad_end_p = data;
return 0;
}
static int help(struct sk_buff **pskb,
struct ip_conntrack *ct, enum ip_conntrack_info ctinfo)
{
unsigned int dataoff;
struct tcphdr _tcph, *th;
char *data, *data_limit, *ib_ptr;
int dir = CTINFO2DIR(ctinfo);
struct ip_conntrack_expect *exp;
u32 seq;
u_int32_t dcc_ip;
u_int16_t dcc_port;
int i, ret = NF_ACCEPT;
char *addr_beg_p, *addr_end_p;
typeof(ip_nat_irc_hook) ip_nat_irc;
DEBUGP("entered\n");
/* If packet is coming from IRC server */
if (dir == IP_CT_DIR_REPLY)
return NF_ACCEPT;
/* Until there's been traffic both ways, don't look in packets. */
if (ctinfo != IP_CT_ESTABLISHED
&& ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
DEBUGP("Conntrackinfo = %u\n", ctinfo);
return NF_ACCEPT;
}
/* Not a full tcp header? */
th = skb_header_pointer(*pskb, ip_hdrlen(*pskb),
sizeof(_tcph), &_tcph);
if (th == NULL)
return NF_ACCEPT;
/* No data? */
dataoff = ip_hdrlen(*pskb) + th->doff * 4;
if (dataoff >= (*pskb)->len)
return NF_ACCEPT;
spin_lock_bh(&irc_buffer_lock);
ib_ptr = skb_header_pointer(*pskb, dataoff,
(*pskb)->len - dataoff, irc_buffer);
BUG_ON(ib_ptr == NULL);
data = ib_ptr;
data_limit = ib_ptr + (*pskb)->len - dataoff;
/* strlen("\1DCC SENT t AAAAAAAA P\1\n")=24
* 5+MINMATCHLEN+strlen("t AAAAAAAA P\1\n")=14 */
while (data < (data_limit - (19 + MINMATCHLEN))) {
if (memcmp(data, "\1DCC ", 5)) {
data++;
continue;
}
data += 5;
/* we have at least (19+MINMATCHLEN)-5 bytes valid data left */
DEBUGP("DCC found in master %u.%u.%u.%u:%u %u.%u.%u.%u:%u...\n",
NIPQUAD(iph->saddr), ntohs(th->source),
NIPQUAD(iph->daddr), ntohs(th->dest));
for (i = 0; i < ARRAY_SIZE(dccprotos); i++) {
if (memcmp(data, dccprotos[i], strlen(dccprotos[i]))) {
/* no match */
continue;
}
DEBUGP("DCC %s detected\n", dccprotos[i]);
data += strlen(dccprotos[i]);
/* we have at least
* (19+MINMATCHLEN)-5-dccprotos[i].matchlen bytes valid
* data left (== 14/13 bytes) */
if (parse_dcc((char *)data, data_limit, &dcc_ip,
&dcc_port, &addr_beg_p, &addr_end_p)) {
/* unable to parse */
DEBUGP("unable to parse dcc command\n");
continue;
}
DEBUGP("DCC bound ip/port: %u.%u.%u.%u:%u\n",
HIPQUAD(dcc_ip), dcc_port);
/* dcc_ip can be the internal OR external (NAT'ed) IP
* Tiago Sousa <mirage@kaotik.org> */
if (ct->tuplehash[dir].tuple.src.ip != htonl(dcc_ip)
&& ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip != htonl(dcc_ip)) {
if (net_ratelimit())
printk(KERN_WARNING
"Forged DCC command from "
"%u.%u.%u.%u: %u.%u.%u.%u:%u\n",
NIPQUAD(ct->tuplehash[dir].tuple.src.ip),
HIPQUAD(dcc_ip), dcc_port);
continue;
}
exp = ip_conntrack_expect_alloc(ct);
if (exp == NULL) {
ret = NF_DROP;
goto out;
}
/* save position of address in dcc string,
* necessary for NAT */
DEBUGP("tcph->seq = %u\n", th->seq);
seq = ntohl(th->seq) + (addr_beg_p - ib_ptr);
/* We refer to the reverse direction ("!dir")
* tuples here, because we're expecting
* something in the other * direction.
* Doesn't matter unless NAT is happening. */
exp->tuple = ((struct ip_conntrack_tuple)
{ { 0, { 0 } },
{ ct->tuplehash[!dir].tuple.dst.ip,
{ .tcp = { htons(dcc_port) } },
IPPROTO_TCP }});
exp->mask = ((struct ip_conntrack_tuple)
{ { 0, { 0 } },
{ htonl(0xFFFFFFFF),
{ .tcp = { htons(0xFFFF) } }, 0xFF }});
exp->expectfn = NULL;
exp->flags = 0;
ip_nat_irc = rcu_dereference(ip_nat_irc_hook);
if (ip_nat_irc)
ret = ip_nat_irc(pskb, ctinfo,
addr_beg_p - ib_ptr,
addr_end_p - addr_beg_p,
exp);
else if (ip_conntrack_expect_related(exp) != 0)
ret = NF_DROP;
ip_conntrack_expect_put(exp);
goto out;
} /* for .. NUM_DCCPROTO */
} /* while data < ... */
out:
spin_unlock_bh(&irc_buffer_lock);
return ret;
}
static struct ip_conntrack_helper irc_helpers[MAX_PORTS];
static char irc_names[MAX_PORTS][sizeof("irc-65535")];
static void ip_conntrack_irc_fini(void);
static int __init ip_conntrack_irc_init(void)
{
int i, ret;
struct ip_conntrack_helper *hlpr;
char *tmpname;
if (max_dcc_channels < 1) {
printk("ip_conntrack_irc: max_dcc_channels must be a positive integer\n");
return -EBUSY;
}
irc_buffer = kmalloc(65536, GFP_KERNEL);
if (!irc_buffer)
return -ENOMEM;
/* If no port given, default to standard irc port */
if (ports_c == 0)
ports[ports_c++] = IRC_PORT;
for (i = 0; i < ports_c; i++) {
hlpr = &irc_helpers[i];
hlpr->tuple.src.u.tcp.port = htons(ports[i]);
hlpr->tuple.dst.protonum = IPPROTO_TCP;
hlpr->mask.src.u.tcp.port = htons(0xFFFF);
hlpr->mask.dst.protonum = 0xFF;
hlpr->max_expected = max_dcc_channels;
hlpr->timeout = dcc_timeout;
hlpr->me = THIS_MODULE;
hlpr->help = help;
tmpname = &irc_names[i][0];
if (ports[i] == IRC_PORT)
sprintf(tmpname, "irc");
else
sprintf(tmpname, "irc-%d", i);
hlpr->name = tmpname;
DEBUGP("port #%d: %d\n", i, ports[i]);
ret = ip_conntrack_helper_register(hlpr);
if (ret) {
printk("ip_conntrack_irc: ERROR registering port %d\n",
ports[i]);
ip_conntrack_irc_fini();
return -EBUSY;
}
}
return 0;
}
/* This function is intentionally _NOT_ defined as __exit, because
* it is needed by the init function */
static void ip_conntrack_irc_fini(void)
{
int i;
for (i = 0; i < ports_c; i++) {
DEBUGP("unregistering port %d\n",
ports[i]);
ip_conntrack_helper_unregister(&irc_helpers[i]);
}
kfree(irc_buffer);
}
module_init(ip_conntrack_irc_init);
module_exit(ip_conntrack_irc_fini);
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -33,7 +33,7 @@ static int set_addr(struct sk_buff **pskb,
unsigned int addroff, __be32 ip, __be16 port)
{
enum ip_conntrack_info ctinfo;
struct nf_conn *ct = ip_conntrack_get(*pskb, &ctinfo);
struct nf_conn *ct = nf_ct_get(*pskb, &ctinfo);
struct {
__be32 ip;
__be16 port;
......@@ -383,7 +383,7 @@ static int nat_h245(struct sk_buff **pskb, struct nf_conn *ct,
static void ip_nat_q931_expect(struct nf_conn *new,
struct nf_conntrack_expect *this)
{
struct ip_nat_range range;
struct nf_nat_range range;
if (this->tuple.src.u3.ip != 0) { /* Only accept calls from GK */
nf_nat_follow_master(new, this);
......
......@@ -53,7 +53,7 @@ static void pptp_nat_expected(struct nf_conn *ct,
struct nf_conntrack_tuple t;
struct nf_ct_pptp_master *ct_pptp_info;
struct nf_nat_pptp *nat_pptp_info;
struct ip_nat_range range;
struct nf_nat_range range;
ct_pptp_info = &nfct_help(master)->help.ct_pptp_info;
nat_pptp_info = &nfct_nat(master)->help.nat_pptp_info;
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -5,7 +5,7 @@
#include <linux/skbuff.h>
#include <linux/netfilter/x_tables.h>
#include <net/netfilter/nf_conntrack_compat.h>
#include <net/netfilter/nf_conntrack.h>
MODULE_LICENSE("GPL");
MODULE_ALIAS("ipt_NOTRACK");
......@@ -26,7 +26,7 @@ target(struct sk_buff **pskb,
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 */
nf_ct_untrack(*pskb);
(*pskb)->nfct = &nf_conntrack_untracked.ct_general;
(*pskb)->nfctinfo = IP_CT_NEW;
nf_conntrack_get((*pskb)->nfct);
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册