Commit af9b4549 authored by David S. Miller's avatar David S. Miller

Merge nuts.davemloft.net:/disk1/BK/nf-2.6.9

into nuts.davemloft.net:/disk1/BK/net-2.6
parents 0b8cf496 b677b829
......@@ -51,10 +51,12 @@ enum ip_conntrack_status {
#include <linux/netfilter_ipv4/ip_conntrack_tcp.h>
#include <linux/netfilter_ipv4/ip_conntrack_icmp.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_sctp sctp;
struct ip_ct_tcp tcp;
struct ip_ct_icmp icmp;
};
......@@ -156,6 +158,12 @@ struct ip_conntrack_expect
union ip_conntrack_expect_help help;
};
struct ip_conntrack_counter
{
u_int64_t packets;
u_int64_t bytes;
};
struct ip_conntrack_helper;
struct ip_conntrack
......@@ -173,6 +181,11 @@ struct ip_conntrack
/* 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're expecting another related connection, this will be
in expected linked list */
struct list_head sibling_list;
......@@ -245,10 +258,17 @@ extern int invert_tuplepr(struct ip_conntrack_tuple *inverse,
const struct ip_conntrack_tuple *orig);
/* Refresh conntrack for this many jiffies */
extern void ip_ct_refresh(struct ip_conntrack *ct,
unsigned long extra_jiffies);
extern void ip_ct_refresh_acct(struct ip_conntrack *ct,
enum ip_conntrack_info ctinfo,
const struct sk_buff *skb,
unsigned long extra_jiffies);
/* These are for NAT. Icky. */
/* Update TCP window tracking data when NAT mangles the packet */
extern int ip_conntrack_tcp_update(struct sk_buff *skb,
struct ip_conntrack *conntrack,
int dir);
/* Call me when a conntrack is destroyed. */
extern void (*ip_conntrack_destroyed)(struct ip_conntrack *conntrack);
......@@ -271,6 +291,26 @@ static inline int is_confirmed(struct ip_conntrack *ct)
}
extern unsigned int ip_conntrack_htable_size;
struct ip_conntrack_stat
{
unsigned int searched;
unsigned int found;
unsigned int new;
unsigned int invalid;
unsigned int ignore;
unsigned int delete;
unsigned int delete_list;
unsigned int insert;
unsigned int insert_failed;
unsigned int drop;
unsigned int early_drop;
unsigned int icmp_error;
unsigned int expect_new;
unsigned int expect_create;
unsigned int expect_delete;
};
/* eg. PROVIDES_CONNTRACK(ftp); */
#define PROVIDES_CONNTRACK(name) \
......
......@@ -21,15 +21,17 @@ extern struct ip_conntrack_protocol *ip_ct_find_proto(u_int8_t protocol);
extern struct ip_conntrack_protocol *__ip_ct_find_proto(u_int8_t protocol);
extern struct list_head protocol_list;
/* Returns conntrack if it dealt with ICMP, and filled in skb->nfct */
extern struct ip_conntrack *icmp_error_track(struct sk_buff *skb,
enum ip_conntrack_info *ctinfo,
unsigned int hooknum);
extern int 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_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 *
......
......@@ -3,6 +3,11 @@
#define _IP_CONNTRACK_PROTOCOL_H
#include <linux/netfilter_ipv4/ip_conntrack.h>
/* length of buffer to which print_tuple/print_conntrack members are
* writing */
#define IP_CT_PRINT_BUFLEN 100
struct ip_conntrack_protocol
{
/* Next pointer. */
......@@ -50,6 +55,9 @@ struct ip_conntrack_protocol
int (*exp_matches_pkt)(struct ip_conntrack_expect *exp,
const struct sk_buff *skb);
int (*error)(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
unsigned int hooknum);
/* Module (if any) which this is connected to. */
struct module *me;
};
......@@ -63,4 +71,17 @@ 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 int ip_conntrack_protocol_tcp_init(void);
/* Log invalid packets */
extern unsigned int ip_ct_log_invalid;
#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
#endif /*_IP_CONNTRACK_PROTOCOL_H*/
#ifndef _IP_CONNTRACK_SCTP_H
#define _IP_CONNTRACK_SCTP_H
/* SCTP tracking. */
enum sctp_conntrack {
SCTP_CONNTRACK_NONE,
SCTP_CONNTRACK_CLOSED,
SCTP_CONNTRACK_COOKIE_WAIT,
SCTP_CONNTRACK_COOKIE_ECHOED,
SCTP_CONNTRACK_ESTABLISHED,
SCTP_CONNTRACK_SHUTDOWN_SENT,
SCTP_CONNTRACK_SHUTDOWN_RECD,
SCTP_CONNTRACK_SHUTDOWN_ACK_SENT,
SCTP_CONNTRACK_MAX
};
struct ip_ct_sctp
{
enum sctp_conntrack state;
u_int32_t vtag[IP_CT_DIR_MAX];
u_int32_t ttag[IP_CT_DIR_MAX];
};
#endif /* _IP_CONNTRACK_SCTP_H */
......@@ -4,25 +4,44 @@
enum tcp_conntrack {
TCP_CONNTRACK_NONE,
TCP_CONNTRACK_ESTABLISHED,
TCP_CONNTRACK_SYN_SENT,
TCP_CONNTRACK_SYN_RECV,
TCP_CONNTRACK_ESTABLISHED,
TCP_CONNTRACK_FIN_WAIT,
TCP_CONNTRACK_TIME_WAIT,
TCP_CONNTRACK_CLOSE,
TCP_CONNTRACK_CLOSE_WAIT,
TCP_CONNTRACK_LAST_ACK,
TCP_CONNTRACK_TIME_WAIT,
TCP_CONNTRACK_CLOSE,
TCP_CONNTRACK_LISTEN,
TCP_CONNTRACK_MAX
TCP_CONNTRACK_MAX,
TCP_CONNTRACK_IGNORE
};
/* Window scaling is advertised by the sender */
#define IP_CT_TCP_STATE_FLAG_WINDOW_SCALE 0x01
/* SACK is permitted by the sender */
#define IP_CT_TCP_FLAG_SACK_PERM 0x02
struct ip_ct_tcp_state {
u_int32_t td_end; /* max of seq + len */
u_int32_t td_maxend; /* max of ack + max(win, 1) */
u_int32_t td_maxwin; /* max(win) */
u_int8_t td_scale; /* window scale factor */
u_int8_t loose; /* used when connection picked up from the middle */
u_int8_t flags; /* per direction state flags */
};
struct ip_ct_tcp
{
enum tcp_conntrack state;
/* Poor man's window tracking: sequence number of valid ACK
handshake completion packet */
u_int32_t handshake_ack;
struct ip_ct_tcp_state seen[2]; /* connection parameters per direction */
u_int8_t state; /* state of the connection (enum tcp_conntrack) */
/* For detecting stale connections */
u_int8_t last_dir; /* Direction of the last packet (enum ip_conntrack_dir) */
u_int8_t retrans; /* Number of retransmitted packets */
u_int8_t last_index; /* Index of the last packet */
u_int32_t last_seq; /* Last sequence number seen in dir */
u_int32_t last_end; /* Last seq + len */
};
#endif /* _IP_CONNTRACK_TCP_H */
......@@ -25,6 +25,9 @@ union ip_conntrack_manip_proto
struct {
u_int16_t id;
} icmp;
struct {
u_int16_t port;
} sctp;
};
/* The manipulable part of the tuple. */
......@@ -55,6 +58,9 @@ struct ip_conntrack_tuple
struct {
u_int8_t type, code;
} icmp;
struct {
u_int16_t port;
} sctp;
} u;
/* The protocol. */
......
......@@ -38,11 +38,12 @@ struct ip_nat_helper
struct ip_nat_info *info);
};
extern struct list_head helpers;
extern int ip_nat_helper_register(struct ip_nat_helper *me);
extern void ip_nat_helper_unregister(struct ip_nat_helper *me);
extern struct ip_nat_helper *
ip_nat_find_helper(const struct ip_conntrack_tuple *tuple);
/* These return true or false. */
extern int ip_nat_mangle_tcp_packet(struct sk_buff **skb,
struct ip_conntrack *ct,
......
......@@ -336,7 +336,6 @@ ipt_get_target(struct ipt_entry *e)
* Main firewall chains definitions and global var's definitions.
*/
#ifdef __KERNEL__
static DECLARE_MUTEX(ipt_mutex);
#include <linux/init.h>
extern void ipt_init(void) __init;
......
#ifndef _IPT_SCTP_H_
#define _IPT_SCTP_H_
#define IPT_SCTP_SRC_PORTS 0x01
#define IPT_SCTP_DEST_PORTS 0x02
#define IPT_SCTP_CHUNK_TYPES 0x04
#define IPT_SCTP_VALID_FLAGS 0x07
#define ELEMCOUNT(x) (sizeof(x)/sizeof(x[0]))
struct ipt_sctp_flag_info {
u_int8_t chunktype;
u_int8_t flag;
u_int8_t flag_mask;
};
#define IPT_NUM_SCTP_FLAGS 4
struct ipt_sctp_info {
u_int16_t dpts[2]; /* Min, Max */
u_int16_t spts[2]; /* Min, Max */
u_int32_t chunkmap[256 / sizeof (u_int32_t)]; /* Bit mask of chunks to be matched according to RFC 2960 */
#define SCTP_CHUNK_MATCH_ANY 0x01 /* Match if any of the chunk types are present */
#define SCTP_CHUNK_MATCH_ALL 0x02 /* Match if all of the chunk types are present */
#define SCTP_CHUNK_MATCH_ONLY 0x04 /* Match if these are the only chunk types present */
u_int32_t chunk_match_type;
struct ipt_sctp_flag_info flag_info[IPT_NUM_SCTP_FLAGS];
int flag_count;
u_int32_t flags;
u_int32_t invflags;
};
#define bytes(type) (sizeof(type) * 8)
#define SCTP_CHUNKMAP_SET(chunkmap, type) \
do { \
chunkmap[type / bytes(u_int32_t)] |= \
1 << (type % bytes(u_int32_t)); \
} while (0)
#define SCTP_CHUNKMAP_CLEAR(chunkmap, type) \
do { \
chunkmap[type / bytes(u_int32_t)] &= \
~(1 << (type % bytes(u_int32_t))); \
} while (0)
#define SCTP_CHUNKMAP_IS_SET(chunkmap, type) \
({ \
(chunkmap[type / bytes (u_int32_t)] & \
(1 << (type % bytes (u_int32_t)))) ? 1: 0; \
})
#define SCTP_CHUNKMAP_RESET(chunkmap) \
do { \
int i; \
for (i = 0; i < ELEMCOUNT(chunkmap); i++) \
chunkmap[i] = 0; \
} while (0)
#define SCTP_CHUNKMAP_SET_ALL(chunkmap) \
do { \
int i; \
for (i = 0; i < ELEMCOUNT(chunkmap); i++) \
chunkmap[i] = ~0; \
} while (0)
#define SCTP_CHUNKMAP_COPY(destmap, srcmap) \
do { \
int i; \
for (i = 0; i < ELEMCOUNT(chunkmap); i++) \
destmap[i] = srcmap[i]; \
} while (0)
#define SCTP_CHUNKMAP_IS_CLEAR(chunkmap) \
({ \
int i; \
int flag = 1; \
for (i = 0; i < ELEMCOUNT(chunkmap); i++) { \
if (chunkmap[i]) { \
flag = 0; \
break; \
} \
} \
flag; \
})
#define SCTP_CHUNKMAP_IS_ALL_SET(chunkmap) \
({ \
int i; \
int flag = 1; \
for (i = 0; i < ELEMCOUNT(chunkmap); i++) { \
if (chunkmap[i] != ~0) { \
flag = 0; \
break; \
} \
} \
flag; \
})
#endif /* _IPT_SCTP_H_ */
......@@ -107,10 +107,6 @@ struct ip6t_counters
u_int64_t pcnt, bcnt; /* Packet and byte counters */
};
#ifdef __KERNEL__
static DECLARE_MUTEX(ip6t_mutex);
#endif
/* Values for "flag" field in struct ip6t_ip6 (general ip6 structure). */
#define IP6T_F_PROTO 0x01 /* Set if rule cares about upper
protocols */
......
......@@ -410,6 +410,18 @@ enum
NET_IPV4_NF_CONNTRACK_ICMP_TIMEOUT=12,
NET_IPV4_NF_CONNTRACK_GENERIC_TIMEOUT=13,
NET_IPV4_NF_CONNTRACK_BUCKETS=14,
NET_IPV4_NF_CONNTRACK_LOG_INVALID=15,
NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS=16,
NET_IPV4_NF_CONNTRACK_TCP_LOOSE=17,
NET_IPV4_NF_CONNTRACK_TCP_BE_LIBERAL=18,
NET_IPV4_NF_CONNTRACK_TCP_MAX_RETRANS=19,
NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED=20,
NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT=21,
NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED=22,
NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED=23,
NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT=24,
NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD=25,
NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT=26,
};
/* /proc/sys/net/ipv6 */
......
......@@ -628,5 +628,17 @@ config IP_NF_MATCH_REALM
If you want to compile it as a module, say M here and read
Documentation/modules.txt. If unsure, say `N'.
config IP_NF_CT_ACCT
bool "Connection tracking flow accounting"
depends on IP_NF_CONNTRACK
config IP_NF_MATCH_SCTP
tristate 'SCTP protocol match support'
depends on IP_NF_IPTABLES
config IP_NF_CT_PROTO_SCTP
tristate 'SCTP protocol connection tracking support (EXPERIMENTAL)'
depends on IP_NF_CONNTRACK && EXPERIMENTAL
endmenu
......@@ -19,6 +19,9 @@ ipchains-objs := $(ip_nf_compat-objs) ipchains_core.o
# connection tracking
obj-$(CONFIG_IP_NF_CONNTRACK) += ip_conntrack.o
# SCTP protocol connection tracking
obj-$(CONFIG_IP_NF_CT_PROTO_SCTP) += ip_conntrack_proto_sctp.o
# connection tracking helpers
obj-$(CONFIG_IP_NF_AMANDA) += ip_conntrack_amanda.o
obj-$(CONFIG_IP_NF_TFTP) += ip_conntrack_tftp.o
......@@ -43,6 +46,7 @@ obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o
# matches
obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o
obj-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit.o
obj-$(CONFIG_IP_NF_MATCH_SCTP) += ipt_sctp.o
obj-$(CONFIG_IP_NF_MATCH_MARK) += ipt_mark.o
obj-$(CONFIG_IP_NF_MATCH_MAC) += ipt_mac.o
obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o
......
......@@ -22,6 +22,7 @@
#include <linux/module.h>
#include <linux/netfilter.h>
#include <linux/ip.h>
#include <linux/moduleparam.h>
#include <net/checksum.h>
#include <net/udp.h>
......@@ -34,7 +35,7 @@ static unsigned int master_timeout = 300;
MODULE_AUTHOR("Brian J. Murrell <netfilter@interlinx.bc.ca>");
MODULE_DESCRIPTION("Amanda connection tracking module");
MODULE_LICENSE("GPL");
MODULE_PARM(master_timeout, "i");
module_param(master_timeout, int, 0600);
MODULE_PARM_DESC(master_timeout, "timeout for the master connection");
static char *conns[] = { "DATA ", "MESG ", "INDEX " };
......@@ -58,7 +59,7 @@ static int help(struct sk_buff *skb,
/* increase the UDP timeout of the master connection as replies from
* Amanda clients to the server can be quite delayed */
ip_ct_refresh(ct, master_timeout * HZ);
ip_ct_refresh_acct(ct, ctinfo, NULL, master_timeout * HZ);
/* No data? */
dataoff = skb->nh.iph->ihl*4 + sizeof(struct udphdr);
......
This diff is collapsed.
......@@ -19,6 +19,7 @@
#include <linux/netfilter_ipv4/lockhelp.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>");
......@@ -33,10 +34,10 @@ struct module *ip_conntrack_ftp = THIS_MODULE;
#define MAX_PORTS 8
static int ports[MAX_PORTS];
static int ports_c;
MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i");
module_param_array(ports, int, ports_c, 0400);
static int loose;
MODULE_PARM(loose, "i");
module_param(loose, int, 0600);
#if 0
#define DEBUGP printk
......@@ -420,10 +421,10 @@ static int __init init(void)
int i, ret;
char *tmpname;
if (ports[0] == 0)
ports[0] = FTP_PORT;
if (ports_c == 0)
ports[ports_c++] = FTP_PORT;
for (i = 0; (i < MAX_PORTS) && ports[i]; i++) {
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 = 0xFFFF;
......@@ -449,7 +450,6 @@ static int __init init(void)
fini();
return ret;
}
ports_c++;
}
return 0;
}
......
......@@ -32,6 +32,7 @@
#include <linux/netfilter_ipv4/lockhelp.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 int ports[MAX_PORTS];
......@@ -44,11 +45,11 @@ static char irc_buffer[65536];
MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
MODULE_DESCRIPTION("IRC (DCC) connection tracking helper");
MODULE_LICENSE("GPL");
MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i");
module_param_array(ports, int, ports_c, 0400);
MODULE_PARM_DESC(ports, "port numbers of IRC servers");
MODULE_PARM(max_dcc_channels, "i");
module_param(max_dcc_channels, int, 0400);
MODULE_PARM_DESC(max_dcc_channels, "max number of expected DCC channels per IRC session");
MODULE_PARM(dcc_timeout, "i");
module_param(dcc_timeout, int, 0400);
MODULE_PARM_DESC(dcc_timeout, "timeout on for unestablished DCC channels");
static char *dccprotos[] = { "SEND ", "CHAT ", "MOVE ", "TSEND ", "SCHAT " };
......@@ -252,10 +253,10 @@ static int __init init(void)
}
/* If no port given, default to standard irc port */
if (ports[0] == 0)
ports[0] = IRC_PORT;
if (ports_c == 0)
ports[ports_c++] = IRC_PORT;
for (i = 0; (i < MAX_PORTS) && ports[i]; i++) {
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;
......@@ -284,7 +285,6 @@ static int __init init(void)
fini();
return -EBUSY;
}
ports_c++;
}
return 0;
}
......
......@@ -50,9 +50,9 @@ static unsigned int generic_print_conntrack(char *buffer,
/* Returns verdict for packet, or -1 for invalid. */
static int packet(struct ip_conntrack *conntrack,
const struct sk_buff *skb,
enum ip_conntrack_info conntrackinfo)
enum ip_conntrack_info ctinfo)
{
ip_ct_refresh(conntrack, ip_ct_generic_timeout);
ip_ct_refresh_acct(conntrack, ctinfo, skb, ip_ct_generic_timeout);
return NF_ACCEPT;
}
......@@ -62,8 +62,14 @@ static int new(struct ip_conntrack *conntrack, const struct sk_buff *skb)
return 1;
}
struct ip_conntrack_protocol ip_conntrack_generic_protocol
= { { NULL, NULL }, 0, "unknown",
generic_pkt_to_tuple, generic_invert_tuple, generic_print_tuple,
generic_print_conntrack, packet, new, NULL, NULL, NULL };
struct ip_conntrack_protocol ip_conntrack_generic_protocol =
{
.proto = 0,
.name = "unknown",
.pkt_to_tuple = generic_pkt_to_tuple,
.invert_tuple = generic_invert_tuple,
.print_tuple = generic_print_tuple,
.print_conntrack = generic_print_conntrack,
.packet = packet,
.new = new,
};
......@@ -12,6 +12,11 @@
#include <linux/netfilter.h>
#include <linux/in.h>
#include <linux/icmp.h>
#include <net/ip.h>
#include <net/checksum.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4/ip_conntrack.h>
#include <linux/netfilter_ipv4/ip_conntrack_core.h>
#include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
unsigned long ip_ct_icmp_timeout = 30*HZ;
......@@ -94,7 +99,7 @@ static int icmp_packet(struct ip_conntrack *ct,
ct->timeout.function((unsigned long)ct);
} else {
atomic_inc(&ct->proto.icmp.count);
ip_ct_refresh(ct, ip_ct_icmp_timeout);
ip_ct_refresh_acct(ct, ctinfo, skb, ip_ct_icmp_timeout);
}
return NF_ACCEPT;
......@@ -122,7 +127,147 @@ static int icmp_new(struct ip_conntrack *conntrack,
return 1;
}
struct ip_conntrack_protocol ip_conntrack_protocol_icmp
= { { NULL, NULL }, IPPROTO_ICMP, "icmp",
icmp_pkt_to_tuple, icmp_invert_tuple, icmp_print_tuple,
icmp_print_conntrack, icmp_packet, icmp_new, NULL, NULL, NULL };
static int
icmp_error_message(struct sk_buff *skb,
enum ip_conntrack_info *ctinfo,
unsigned int hooknum)
{
struct ip_conntrack_tuple innertuple, origtuple;
struct {
struct icmphdr icmp;
struct iphdr ip;
} inside;
struct ip_conntrack_protocol *innerproto;
struct ip_conntrack_tuple_hash *h;
int dataoff;
IP_NF_ASSERT(skb->nfct == NULL);
/* Not enough header? */
if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &inside, sizeof(inside))!=0)
return NF_ACCEPT;
/* Ignore ICMP's containing fragments (shouldn't happen) */
if (inside.ip.frag_off & htons(IP_OFFSET)) {
DEBUGP("icmp_error_track: fragment of proto %u\n",
inside.ip.protocol);
return NF_ACCEPT;
}
innerproto = ip_ct_find_proto(inside.ip.protocol);
dataoff = skb->nh.iph->ihl*4 + sizeof(inside.icmp) + inside.ip.ihl*4;
/* Are they talking about one of our connections? */
if (!ip_ct_get_tuple(&inside.ip, skb, dataoff, &origtuple, innerproto)) {
DEBUGP("icmp_error: ! get_tuple p=%u", inside.ip.protocol);
return NF_ACCEPT;
}
/* Ordinarily, we'd expect the inverted tupleproto, but it's
been preserved inside the ICMP. */
if (!ip_ct_invert_tuple(&innertuple, &origtuple, innerproto)) {
DEBUGP("icmp_error_track: Can't invert tuple\n");
return NF_ACCEPT;
}
*ctinfo = IP_CT_RELATED;
h = ip_conntrack_find_get(&innertuple, NULL);
if (!h) {
/* Locally generated ICMPs will match inverted if they
haven't been SNAT'ed yet */
/* FIXME: NAT code has to handle half-done double NAT --RR */
if (hooknum == NF_IP_LOCAL_OUT)
h = ip_conntrack_find_get(&origtuple, NULL);
if (!h) {
DEBUGP("icmp_error_track: no match\n");
return NF_ACCEPT;
}
/* Reverse direction from that found */
if (DIRECTION(h) != IP_CT_DIR_REPLY)
*ctinfo += IP_CT_IS_REPLY;
} else {
if (DIRECTION(h) == IP_CT_DIR_REPLY)
*ctinfo += IP_CT_IS_REPLY;
}
/* Update skb to refer to this connection */
skb->nfct = &h->ctrack->infos[*ctinfo];
return -NF_ACCEPT;
}
/* Small and modified version of icmp_rcv */
static int
icmp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
unsigned int hooknum)
{
struct icmphdr icmph;
/* Not enough header? */
if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &icmph, sizeof(icmph))!=0) {
if (LOG_INVALID(IPPROTO_ICMP))
nf_log_packet(PF_INET, 0, skb, NULL, NULL,
"ip_ct_icmp: short packet ");
return -NF_ACCEPT;
}
/* See ip_conntrack_proto_tcp.c */
if (hooknum != NF_IP_PRE_ROUTING)
goto checksum_skipped;
switch (skb->ip_summed) {
case CHECKSUM_HW:
if (!(u16)csum_fold(skb->csum))
break;
if (LOG_INVALID(IPPROTO_ICMP))
nf_log_packet(PF_INET, 0, skb, NULL, NULL,
"ip_ct_icmp: bad HW ICMP checksum ");
return -NF_ACCEPT;
case CHECKSUM_NONE:
if ((u16)csum_fold(skb_checksum(skb, 0, skb->len, 0))) {
if (LOG_INVALID(IPPROTO_ICMP))
nf_log_packet(PF_INET, 0, skb, NULL, NULL,
"ip_ct_icmp: bad ICMP checksum ");
return -NF_ACCEPT;
}
default:
break;
}
checksum_skipped:
/*
* 18 is the highest 'known' ICMP type. Anything else is a mystery
*
* RFC 1122: 3.2.2 Unknown ICMP messages types MUST be silently
* discarded.
*/
if (icmph.type > NR_ICMP_TYPES) {
if (LOG_INVALID(IPPROTO_ICMP))
nf_log_packet(PF_INET, 0, skb, NULL, NULL,
"ip_ct_icmp: invalid ICMP type ");
return -NF_ACCEPT;
}
/* Need to track icmp error message? */
if (icmph.type != ICMP_DEST_UNREACH
&& icmph.type != ICMP_SOURCE_QUENCH
&& icmph.type != ICMP_TIME_EXCEEDED
&& icmph.type != ICMP_PARAMETERPROB
&& icmph.type != ICMP_REDIRECT)
return NF_ACCEPT;
return icmp_error_message(skb, ctinfo, hooknum);
}
struct ip_conntrack_protocol ip_conntrack_protocol_icmp =
{
.proto = IPPROTO_ICMP,
.name = "icmp",
.pkt_to_tuple = icmp_pkt_to_tuple,
.invert_tuple = icmp_invert_tuple,
.print_tuple = icmp_print_tuple,
.print_conntrack = icmp_print_conntrack,
.packet = icmp_packet,
.new = icmp_new,
.error = icmp_error,
};
This diff is collapsed.
This diff is collapsed.
......@@ -12,6 +12,8 @@
#include <linux/netfilter.h>
#include <linux/in.h>
#include <linux/udp.h>
#include <net/checksum.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
unsigned long ip_ct_udp_timeout = 30*HZ;
......@@ -60,16 +62,17 @@ static unsigned int udp_print_conntrack(char *buffer,
/* Returns verdict for packet, and may modify conntracktype */
static int udp_packet(struct ip_conntrack *conntrack,
const struct sk_buff *skb,
enum ip_conntrack_info conntrackinfo)
enum ip_conntrack_info ctinfo)
{
/* If we've seen traffic both ways, this is some kind of UDP
stream. Extend timeout. */
if (test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {
ip_ct_refresh(conntrack, ip_ct_udp_timeout_stream);
ip_ct_refresh_acct(conntrack, ctinfo, skb,
ip_ct_udp_timeout_stream);
/* Also, more likely to be important, and not a probe */
set_bit(IPS_ASSURED_BIT, &conntrack->status);
} else
ip_ct_refresh(conntrack, ip_ct_udp_timeout);
ip_ct_refresh_acct(conntrack, ctinfo, skb, ip_ct_udp_timeout);
return NF_ACCEPT;
}
......@@ -80,7 +83,60 @@ static int udp_new(struct ip_conntrack *conntrack, const struct sk_buff *skb)
return 1;
}
struct ip_conntrack_protocol ip_conntrack_protocol_udp
= { { NULL, NULL }, IPPROTO_UDP, "udp",
udp_pkt_to_tuple, udp_invert_tuple, udp_print_tuple, udp_print_conntrack,
udp_packet, udp_new, NULL, NULL, NULL };
static int udp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
unsigned int hooknum)
{
struct iphdr *iph = skb->nh.iph;
unsigned int udplen = skb->len - iph->ihl * 4;
struct udphdr hdr;
/* Header is too small? */
if (skb_copy_bits(skb, iph->ihl*4, &hdr, sizeof(hdr)) != 0) {
if (LOG_INVALID(IPPROTO_UDP))
nf_log_packet(PF_INET, 0, skb, NULL, NULL,
"ip_ct_udp: short packet ");
return -NF_ACCEPT;
}
/* Truncated/malformed packets */
if (ntohs(hdr.len) > udplen || ntohs(hdr.len) < sizeof(hdr)) {
if (LOG_INVALID(IPPROTO_UDP))
nf_log_packet(PF_INET, 0, skb, NULL, NULL,
"ip_ct_udp: truncated/malformed packet ");
return -NF_ACCEPT;
}
/* Packet with no checksum */
if (!hdr.check)
return NF_ACCEPT;
/* Checksum invalid? Ignore.
* We skip checking packets on the outgoing path
* because the semantic of CHECKSUM_HW is different there
* and moreover root might send raw packets.
* FIXME: Source route IP option packets --RR */
if (hooknum == NF_IP_PRE_ROUTING
&& csum_tcpudp_magic(iph->saddr, iph->daddr, udplen, IPPROTO_UDP,
skb->ip_summed == CHECKSUM_HW ? skb->csum
: skb_checksum(skb, iph->ihl*4, udplen, 0))) {
if (LOG_INVALID(IPPROTO_UDP))
nf_log_packet(PF_INET, 0, skb, NULL, NULL,
"ip_ct_udp: bad UDP checksum ");
return -NF_ACCEPT;
}
return NF_ACCEPT;
}
struct ip_conntrack_protocol ip_conntrack_protocol_udp =
{
.proto = IPPROTO_UDP,
.name = "udp",
.pkt_to_tuple = udp_pkt_to_tuple,
.invert_tuple = udp_invert_tuple,
.print_tuple = udp_print_tuple,
.print_conntrack = udp_print_conntrack,
.packet = udp_packet,
.new = udp_new,
.error = udp_error,
};
......@@ -19,6 +19,7 @@
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
#include <linux/netfilter_ipv4/ip_conntrack_tftp.h>
#include <linux/moduleparam.h>
MODULE_AUTHOR("Magnus Boden <mb@ozaba.mine.nu>");
MODULE_DESCRIPTION("tftp connection tracking helper");
......@@ -27,7 +28,7 @@ MODULE_LICENSE("GPL");
#define MAX_PORTS 8
static int ports[MAX_PORTS];
static int ports_c;
MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i");
module_param_array(ports, int, ports_c, 0400);
MODULE_PARM_DESC(ports, "port numbers of tftp servers");
#if 0
......@@ -104,10 +105,10 @@ static int __init init(void)
int i, ret;
char *tmpname;
if (!ports[0])
ports[0]=TFTP_PORT;
if (ports_c == 0)
ports[ports_c++] = TFTP_PORT;
for (i = 0 ; (i < MAX_PORTS) && ports[i] ; i++) {
for (i = 0; i < ports_c; i++) {
/* Create helper structure */
memset(&tftp[i], 0, sizeof(struct ip_conntrack_helper));
......@@ -137,7 +138,6 @@ static int __init init(void)
fini();
return(ret);
}
ports_c++;
}
return(0);
}
......
......@@ -31,6 +31,7 @@
#include <linux/netfilter_ipv4/ip_conntrack.h>
#include <linux/netfilter_ipv4/ip_conntrack_core.h>
#include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
#include <linux/netfilter_ipv4/ip_nat.h>
#include <linux/netfilter_ipv4/ip_nat_core.h>
#include <linux/netfilter_ipv4/listhelp.h>
......@@ -144,7 +145,8 @@ check_for_demasq(struct sk_buff **pskb)
switch ((*pskb)->nh.iph->protocol) {
case IPPROTO_ICMP:
/* ICMP errors. */
ct = icmp_error_track(*pskb, &ctinfo, NF_IP_PRE_ROUTING);
protocol->error(*pskb, &ctinfo, NF_IP_PRE_ROUTING);
ct = (struct ip_conntrack *)(*pskb)->nfct->master;
if (ct) {
/* We only do SNAT in the compatibility layer.
So we can manipulate ICMP errors from
......@@ -165,7 +167,8 @@ check_for_demasq(struct sk_buff **pskb)
case IPPROTO_UDP:
IP_NF_ASSERT(((*pskb)->nh.iph->frag_off & htons(IP_OFFSET)) == 0);
if (!get_tuple((*pskb)->nh.iph, *pskb, (*pskb)->nh.iph->ihl*4, &tuple, protocol)) {
if (!ip_ct_get_tuple((*pskb)->nh.iph, *pskb,
(*pskb)->nh.iph->ihl*4, &tuple, protocol)) {
if (net_ratelimit())
printk("ip_fw_compat_masq: Can't get tuple\n");
return NF_ACCEPT;
......
......@@ -49,7 +49,6 @@ static unsigned int ip_nat_htable_size;
static struct list_head *bysource;
static struct list_head *byipsproto;
LIST_HEAD(protos);
LIST_HEAD(helpers);
extern struct ip_nat_protocol unknown_nat_protocol;
......@@ -498,13 +497,6 @@ get_unique_tuple(struct ip_conntrack_tuple *tuple,
return ret;
}
static inline int
helper_cmp(const struct ip_nat_helper *helper,
const struct ip_conntrack_tuple *tuple)
{
return ip_ct_tuple_mask_cmp(tuple, &helper->tuple, &helper->mask);
}
/* Where to manip the reply packets (will be reverse manip). */
static unsigned int opposite_hook[NF_IP_NUMHOOKS]
= { [NF_IP_PRE_ROUTING] = NF_IP_POST_ROUTING,
......@@ -643,8 +635,7 @@ ip_nat_setup_info(struct ip_conntrack *conntrack,
/* If there's a helper, assign it; based on new tuple. */
if (!conntrack->master)
info->helper = LIST_FIND(&helpers, helper_cmp, struct ip_nat_helper *,
&reply);
info->helper = ip_nat_find_helper(&reply);
/* It's done. */
info->initialized |= (1 << HOOK2MANIP(hooknum));
......
......@@ -12,6 +12,7 @@
#include <linux/netfilter_ipv4.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/moduleparam.h>
#include <net/tcp.h>
#include <linux/netfilter_ipv4/ip_nat.h>
#include <linux/netfilter_ipv4/ip_nat_helper.h>
......@@ -33,7 +34,7 @@ MODULE_DESCRIPTION("ftp NAT helper");
static int ports[MAX_PORTS];
static int ports_c;
MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i");
module_param_array(ports, int, ports_c, 0400);
DECLARE_LOCK_EXTERN(ip_ftp_lock);
......@@ -313,10 +314,10 @@ static int __init init(void)
int i, ret = 0;
char *tmpname;
if (ports[0] == 0)
ports[0] = FTP_PORT;
if (ports_c == 0)
ports[ports_c] = FTP_PORT;
for (i = 0; (i < MAX_PORTS) && ports[i]; i++) {
for (i = 0; i < ports_c; i++) {
ftp[i].tuple.dst.protonum = IPPROTO_TCP;
ftp[i].tuple.src.u.tcp.port = htons(ports[i]);
ftp[i].mask.dst.protonum = 0xFFFF;
......@@ -343,7 +344,6 @@ static int __init init(void)
fini();
return ret;
}
ports_c++;
}
return ret;
......
......@@ -47,6 +47,7 @@
#define DUMP_OFFSET(x)
#endif
static LIST_HEAD(helpers);
DECLARE_LOCK(ip_nat_seqofs_lock);
/* Setup TCP sequence correction given this change at this sequence */
......@@ -419,6 +420,18 @@ int ip_nat_helper_register(struct ip_nat_helper *me)
return ret;
}
struct ip_nat_helper *
ip_nat_find_helper(const struct ip_conntrack_tuple *tuple)
{
struct ip_nat_helper *h;
READ_LOCK(&ip_nat_lock);
h = LIST_FIND(&helpers, helper_cmp, struct ip_nat_helper *, tuple);
READ_UNLOCK(&ip_nat_lock);
return h;
}
static int
kill_helper(const struct ip_conntrack *i, void *helper)
{
......
......@@ -27,6 +27,7 @@
#include <linux/netfilter_ipv4/ip_nat_rule.h>
#include <linux/netfilter_ipv4/ip_conntrack_irc.h>
#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
#include <linux/moduleparam.h>
#if 0
#define DEBUGP printk
......@@ -41,7 +42,7 @@ static int ports_c;
MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
MODULE_DESCRIPTION("IRC (DCC) NAT helper");
MODULE_LICENSE("GPL");
MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i");
module_param_array(ports, int, ports_c, 0400);
MODULE_PARM_DESC(ports, "port numbers of IRC servers");
/* protects irc part of conntracks */
......@@ -235,11 +236,10 @@ static int __init init(void)
struct ip_nat_helper *hlpr;
char *tmpname;
if (ports[0] == 0) {
ports[0] = IRC_PORT;
}
if (ports_c == 0)
ports[ports_c++] = IRC_PORT;
for (i = 0; (i < MAX_PORTS) && ports[i] != 0; i++) {
for (i = 0; i < ports_c; i++) {
hlpr = &ip_nat_irc_helpers[i];
hlpr->tuple.dst.protonum = IPPROTO_TCP;
hlpr->tuple.src.u.tcp.port = htons(ports[i]);
......@@ -269,7 +269,6 @@ static int __init init(void)
fini();
return 1;
}
ports_c++;
}
return ret;
}
......
......@@ -132,7 +132,8 @@ static unsigned int ipt_snat_target(struct sk_buff **pskb,
ct = ip_conntrack_get(*pskb, &ctinfo);
/* Connection must be valid and new. */
IP_NF_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED));
IP_NF_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED
|| ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY));
IP_NF_ASSERT(out);
return ip_nat_setup_info(ct, targinfo, hooknum);
......
......@@ -47,6 +47,7 @@
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/moduleparam.h>
#include <linux/netfilter_ipv4.h>
#include <linux/netfilter_ipv4/ip_nat.h>
#include <linux/netfilter_ipv4/ip_nat_helper.h>
......@@ -1252,6 +1253,9 @@ static unsigned int nat_help(struct ip_conntrack *ct,
int dir = CTINFO2DIR(ctinfo);
struct iphdr *iph = (*pskb)->nh.iph;
struct udphdr *udph = (struct udphdr *)((u_int32_t *)iph + iph->ihl);
if (!skb_ip_make_writable(pskb, (*pskb)->len))
return NF_DROP;
spin_lock_bh(&snmp_lock);
......@@ -1357,4 +1361,4 @@ static void __exit fini(void)
module_init(init);
module_exit(fini);
MODULE_PARM(debug, "i");
module_param(debug, bool, 0600);
......@@ -32,6 +32,7 @@
#include <linux/netfilter_ipv4/ip_conntrack_tftp.h>
#include <linux/netfilter_ipv4/ip_nat_helper.h>
#include <linux/netfilter_ipv4/ip_nat_rule.h>
#include <linux/moduleparam.h>
MODULE_AUTHOR("Magnus Boden <mb@ozaba.mine.nu>");
MODULE_DESCRIPTION("tftp NAT helper");
......@@ -41,7 +42,7 @@ MODULE_LICENSE("GPL");
static int ports[MAX_PORTS];
static int ports_c = 0;
MODULE_PARM(ports,"1-" __MODULE_STRING(MAX_PORTS) "i");
module_param_array(ports, int, ports_c, 0400);
MODULE_PARM_DESC(ports, "port numbers of tftp servers");
#if 0
......@@ -162,10 +163,10 @@ static int __init init(void)
int i, ret = 0;
char *tmpname;
if (!ports[0])
ports[0] = TFTP_PORT;
if (ports_c == 0)
ports[ports_c++] = TFTP_PORT;
for (i = 0 ; (i < MAX_PORTS) && ports[i] ; i++) {
for (i = 0; i < ports_c; i++) {
memset(&tftp[i], 0, sizeof(struct ip_nat_helper));
tftp[i].tuple.dst.protonum = IPPROTO_UDP;
......@@ -194,7 +195,6 @@ static int __init init(void)
fini();
return ret;
}
ports_c++;
}
return ret;
}
......
......@@ -61,6 +61,8 @@ do { \
#endif
#define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1))
static DECLARE_MUTEX(ipt_mutex);
/* Must have mutex */
#define ASSERT_READ_LOCK(x) IP_NF_ASSERT(down_trylock(&ipt_mutex) != 0)
#define ASSERT_WRITE_LOCK(x) IP_NF_ASSERT(down_trylock(&ipt_mutex) != 0)
......
......@@ -28,7 +28,7 @@ MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
MODULE_DESCRIPTION("iptables syslog logging module");
static unsigned int nflog = 1;
MODULE_PARM(nflog, "i");
module_param(nflog, int, 0400);
MODULE_PARM_DESC(nflog, "register as internal netfilter logging module");
#if 0
......
......@@ -92,8 +92,8 @@ masquerade_target(struct sk_buff **pskb,
return NF_ACCEPT;
ct = ip_conntrack_get(*pskb, &ctinfo);
IP_NF_ASSERT(ct && (ctinfo == IP_CT_NEW
|| ctinfo == IP_CT_RELATED));
IP_NF_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED
|| ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY));
mr = targinfo;
......
......@@ -34,8 +34,8 @@
* by that factor.
*
* flushtimeout:
* Specify, after how many clock ticks (intel: 100 per second) the queue
* should be flushed even if it is not full yet.
* Specify, after how many hundredths of a second the queue should be
* flushed even if it is not full yet.
*
* ipt_ULOG.c,v 1.22 2002/10/30 09:07:31 laforge Exp
*/
......@@ -50,6 +50,7 @@
#include <linux/netlink.h>
#include <linux/netdevice.h>
#include <linux/mm.h>
#include <linux/moduleparam.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv4/ipt_ULOG.h>
......@@ -74,15 +75,15 @@ MODULE_DESCRIPTION("iptables userspace logging module");
#define PRINTR(format, args...) do { if (net_ratelimit()) printk(format , ## args); } while (0)
static unsigned int nlbufsiz = 4096;
MODULE_PARM(nlbufsiz, "i");
module_param(nlbufsiz, uint, 0600); /* FIXME: Check size < 128k --RR */
MODULE_PARM_DESC(nlbufsiz, "netlink buffer size");
static unsigned int flushtimeout = 10 * HZ;
MODULE_PARM(flushtimeout, "i");
MODULE_PARM_DESC(flushtimeout, "buffer flush timeout");
static unsigned int flushtimeout = 10;
module_param(flushtimeout, int, 0600);
MODULE_PARM_DESC(flushtimeout, "buffer flush timeout (hundredths of a second)");
static unsigned int nflog = 1;
MODULE_PARM(nflog, "i");
module_param(nflog, int, 0400);
MODULE_PARM_DESC(nflog, "register as internal netfilter logging module");
/* global data structures */
......@@ -97,7 +98,6 @@ typedef struct {
static ulog_buff_t ulog_buffers[ULOG_MAXNLGROUPS]; /* array of buffers */
static struct sock *nflognl; /* our socket */
static size_t qlen; /* current length of multipart-nlmsg */
DECLARE_LOCK(ulog_lock); /* spinlock */
/* send one ulog_buff_t to userspace */
......@@ -116,7 +116,7 @@ static void ulog_send(unsigned int nlgroupnum)
NETLINK_CB(ub->skb).dst_groups = (1 << nlgroupnum);
DEBUGP("ipt_ULOG: throwing %d packets to netlink mask %u\n",
ub->qlen, nlgroup);
ub->qlen, nlgroupnum);
netlink_broadcast(nflognl, ub->skb, 0, (1 << nlgroupnum), GFP_ATOMIC);
ub->qlen = 0;
......@@ -126,7 +126,7 @@ static void ulog_send(unsigned int nlgroupnum)
}
/* timer function to flush queue in ULOG_FLUSH_INTERVAL time */
/* timer function to flush queue in flushtimeout time */
static void ulog_timer(unsigned long data)
{
DEBUGP("ipt_ULOG: timer function called, calling ulog_send\n");
......@@ -261,20 +261,21 @@ static void ipt_ulog_packet(unsigned int hooknum,
ub->lastnlh->nlmsg_flags |= NLM_F_MULTI;
}
/* if threshold is reached, send message to userspace */
if (qlen >= loginfo->qthreshold) {
if (loginfo->qthreshold > 1)
nlh->nlmsg_type = NLMSG_DONE;
}
ub->lastnlh = nlh;
/* if timer isn't already running, start it */
if (!timer_pending(&ub->timer)) {
ub->timer.expires = jiffies + flushtimeout;
ub->timer.expires = jiffies + flushtimeout * HZ / 100;
add_timer(&ub->timer);
}
/* if threshold is reached, send message to userspace */
if (ub->qlen >= loginfo->qthreshold) {
if (loginfo->qthreshold > 1)
nlh->nlmsg_type = NLMSG_DONE;
ulog_send(groupnum);
}
UNLOCK_BH(&ulog_lock);
return;
......
......@@ -15,6 +15,7 @@
#include <linux/ctype.h>
#include <linux/ip.h>
#include <linux/vmalloc.h>
#include <linux/moduleparam.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv4/ipt_recent.h>
......@@ -37,12 +38,12 @@ KERN_INFO RECENT_NAME " " RECENT_VER ": Stephen Frost <sfrost@snowman.net>. htt
MODULE_AUTHOR("Stephen Frost <sfrost@snowman.net>");
MODULE_DESCRIPTION("IP tables recently seen matching module " RECENT_VER);
MODULE_LICENSE("GPL");
MODULE_PARM(ip_list_tot,"i");
MODULE_PARM(ip_pkt_list_tot,"i");
MODULE_PARM(ip_list_hash_size,"i");
MODULE_PARM(ip_list_perms,"i");
module_param(ip_list_tot, int, 0400);
module_param(ip_pkt_list_tot, int, 0400);
module_param(ip_list_hash_size, int, 0400);
module_param(ip_list_perms, int, 0400);
#ifdef DEBUG
MODULE_PARM(debug,"i");
module_param(debug, int, 0600);
MODULE_PARM_DESC(debug,"debugging level, defaults to 1");
#endif
MODULE_PARM_DESC(ip_list_tot,"number of IPs to remember per list");
......
#include <linux/module.h>
#include <linux/skbuff.h>
#include <net/ip.h>
#include <linux/sctp.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv4/ipt_sctp.h>
#ifdef DEBUG_SCTP
#define duprintf(format, args...) printk(format , ## args)
#else
#define duprintf(format, args...)
#endif
#define SCCHECK(cond, option, flag, invflag) (!((flag) & (option)) \
|| (!!((invflag) & (option)) ^ (cond)))
static int
match_flags(const struct ipt_sctp_flag_info *flag_info,
const int flag_count,
u_int8_t chunktype,
u_int8_t chunkflags)
{
int i;
for (i = 0; i < flag_count; i++) {
if (flag_info[i].chunktype == chunktype) {
return (chunkflags & flag_info[i].flag_mask) == flag_info[i].flag;
}
}
return 1;
}
static int
match_packet(const struct sk_buff *skb,
const u_int32_t *chunkmap,
int chunk_match_type,
const struct ipt_sctp_flag_info *flag_info,
const int flag_count,
int *hotdrop)
{
int offset;
u_int32_t chunkmapcopy[256 / sizeof (u_int32_t)];
sctp_chunkhdr_t sch;
#ifdef DEBUG_SCTP
int i = 0;
#endif
if (chunk_match_type == SCTP_CHUNK_MATCH_ALL) {
SCTP_CHUNKMAP_COPY(chunkmapcopy, chunkmap);
}
offset = skb->nh.iph->ihl * 4 + sizeof (sctp_sctphdr_t);
do {
if (skb_copy_bits(skb, offset, &sch, sizeof(sch)) < 0) {
duprintf("Dropping invalid SCTP packet.\n");
*hotdrop = 1;
return 0;
}
duprintf("Chunk num: %d\toffset: %d\ttype: %d\tlength: %d\tflags: %x\n",
++i, offset, sch.type, htons(sch.length), sch.flags);
offset += (htons(sch.length) + 3) & ~3;
duprintf("skb->len: %d\toffset: %d\n", skb->len, offset);
if (SCTP_CHUNKMAP_IS_SET(chunkmap, sch.type)) {
switch (chunk_match_type) {
case SCTP_CHUNK_MATCH_ANY:
if (match_flags(flag_info, flag_count,
sch.type, sch.flags)) {
return 1;
}
break;
case SCTP_CHUNK_MATCH_ALL:
if (match_flags(flag_info, flag_count,
sch.type, sch.flags)) {
SCTP_CHUNKMAP_CLEAR(chunkmapcopy, sch.type);
}
break;
case SCTP_CHUNK_MATCH_ONLY:
if (!match_flags(flag_info, flag_count,
sch.type, sch.flags)) {
return 0;
}
break;
}
} else {
switch (chunk_match_type) {
case SCTP_CHUNK_MATCH_ONLY:
return 0;
}
}
} while (offset < skb->len);
switch (chunk_match_type) {
case SCTP_CHUNK_MATCH_ALL:
return SCTP_CHUNKMAP_IS_CLEAR(chunkmap);
case SCTP_CHUNK_MATCH_ANY:
return 0;
case SCTP_CHUNK_MATCH_ONLY:
return 1;
}
/* This will never be reached, but required to stop compiler whine */
return 0;
}
static int
match(const struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
const void *matchinfo,
int offset,
int *hotdrop)
{
const struct ipt_sctp_info *info;
sctp_sctphdr_t sh;
info = (const struct ipt_sctp_info *)matchinfo;
if (offset) {
duprintf("Dropping non-first fragment.. FIXME\n");
return 0;
}
if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &sh, sizeof(sh)) < 0) {
duprintf("Dropping evil TCP offset=0 tinygram.\n");
*hotdrop = 1;
return 0;
}
duprintf("spt: %d\tdpt: %d\n", ntohs(sh.source), ntohs(sh.dest));
return SCCHECK(((ntohs(sh.source) >= info->spts[0])
&& (ntohs(sh.source) <= info->spts[1])),
IPT_SCTP_SRC_PORTS, info->flags, info->invflags)
&& SCCHECK(((ntohs(sh.dest) >= info->dpts[0])
&& (ntohs(sh.dest) <= info->dpts[1])),
IPT_SCTP_DEST_PORTS, info->flags, info->invflags)
&& SCCHECK(match_packet(skb, info->chunkmap, info->chunk_match_type,
info->flag_info, info->flag_count,
hotdrop),
IPT_SCTP_CHUNK_TYPES, info->flags, info->invflags);
}
static int
checkentry(const char *tablename,
const struct ipt_ip *ip,
void *matchinfo,
unsigned int matchsize,
unsigned int hook_mask)
{
const struct ipt_sctp_info *info;
info = (const struct ipt_sctp_info *)matchinfo;
return ip->proto == IPPROTO_SCTP
&& !(ip->invflags & IPT_INV_PROTO)
&& matchsize == IPT_ALIGN(sizeof(struct ipt_sctp_info))
&& !(info->flags & ~IPT_SCTP_VALID_FLAGS)
&& !(info->invflags & ~IPT_SCTP_VALID_FLAGS)
&& !(info->invflags & ~info->flags)
&& ((!(info->flags & IPT_SCTP_CHUNK_TYPES)) ||
(info->chunk_match_type &
(SCTP_CHUNK_MATCH_ALL
| SCTP_CHUNK_MATCH_ANY
| SCTP_CHUNK_MATCH_ONLY)));
}
static struct ipt_match sctp_match =
{
.list = { NULL, NULL},
.name = "sctp",
.match = &match,
.checkentry = &checkentry,
.destroy = NULL,
.me = THIS_MODULE
};
static int __init init(void)
{
return ipt_register_match(&sctp_match);
}
static void __exit fini(void)
{
ipt_unregister_match(&sctp_match);
}
module_init(init);
module_exit(fini);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kiran Kumar Immidi");
MODULE_DESCRIPTION("Match for SCTP protocol packets");
......@@ -11,6 +11,7 @@
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/netfilter_ipv4/ip_tables.h>
MODULE_LICENSE("GPL");
......@@ -155,7 +156,7 @@ static struct nf_hook_ops ipt_ops[] = {
/* Default to forward because I got too much mail already. */
static int forward = NF_ACCEPT;
MODULE_PARM(forward, "i");
module_param(forward, bool, 0000);
static int __init init(void)
{
......
......@@ -66,6 +66,7 @@ do { \
#endif
#define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1))
static DECLARE_MUTEX(ip6t_mutex);
/* Must have mutex */
#define ASSERT_READ_LOCK(x) IP_NF_ASSERT(down_trylock(&ip6t_mutex) != 0)
......
......@@ -11,6 +11,7 @@
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <linux/spinlock.h>
......@@ -26,7 +27,7 @@ MODULE_DESCRIPTION("IP6 tables LOG target module");
MODULE_LICENSE("GPL");
static unsigned int nflog = 1;
MODULE_PARM(nflog, "i");
module_param(nflog, int, 0400);
MODULE_PARM_DESC(nflog, "register as internal netfilter logging module");
struct in_device;
......
......@@ -10,6 +10,7 @@
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
MODULE_LICENSE("GPL");
......@@ -156,7 +157,7 @@ static struct nf_hook_ops ip6t_ops[] = {
/* Default to forward because I got too much mail already. */
static int forward = NF_ACCEPT;
MODULE_PARM(forward, "i");
module_param(forward, bool, 0000);
static int __init init(void)
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment