Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
eccf6f14
Commit
eccf6f14
authored
Apr 15, 2004
by
David S. Miller
Browse files
Options
Browse Files
Download
Plain Diff
Merge
parents
0180f946
516e49e0
Changes
31
Hide whitespace changes
Inline
Side-by-side
Showing
31 changed files
with
1004 additions
and
177 deletions
+1004
-177
include/linux/netfilter.h
include/linux/netfilter.h
+18
-0
include/linux/netfilter_ipv4.h
include/linux/netfilter_ipv4.h
+2
-0
include/linux/netfilter_ipv4/ip_conntrack.h
include/linux/netfilter_ipv4/ip_conntrack.h
+3
-0
include/linux/netfilter_ipv4/ip_conntrack_helper.h
include/linux/netfilter_ipv4/ip_conntrack_helper.h
+6
-2
include/linux/netfilter_ipv4/ip_logging.h
include/linux/netfilter_ipv4/ip_logging.h
+20
-0
include/linux/netfilter_ipv4/ipt_ULOG.h
include/linux/netfilter_ipv4/ipt_ULOG.h
+3
-0
include/linux/netfilter_ipv4/ipt_conntrack.h
include/linux/netfilter_ipv4/ipt_conntrack.h
+1
-0
include/linux/netfilter_ipv4/ipt_state.h
include/linux/netfilter_ipv4/ipt_state.h
+2
-0
include/linux/netfilter_ipv6/ip6_logging.h
include/linux/netfilter_ipv6/ip6_logging.h
+20
-0
include/linux/netfilter_logging.h
include/linux/netfilter_logging.h
+33
-0
net/core/netfilter.c
net/core/netfilter.c
+68
-0
net/ipv4/netfilter/Kconfig
net/ipv4/netfilter/Kconfig
+24
-0
net/ipv4/netfilter/Makefile
net/ipv4/netfilter/Makefile
+2
-0
net/ipv4/netfilter/ip_conntrack_amanda.c
net/ipv4/netfilter/ip_conntrack_amanda.c
+25
-17
net/ipv4/netfilter/ip_conntrack_core.c
net/ipv4/netfilter/ip_conntrack_core.c
+82
-48
net/ipv4/netfilter/ip_conntrack_ftp.c
net/ipv4/netfilter/ip_conntrack_ftp.c
+12
-5
net/ipv4/netfilter/ip_conntrack_irc.c
net/ipv4/netfilter/ip_conntrack_irc.c
+9
-5
net/ipv4/netfilter/ip_conntrack_proto_tcp.c
net/ipv4/netfilter/ip_conntrack_proto_tcp.c
+21
-19
net/ipv4/netfilter/ip_conntrack_standalone.c
net/ipv4/netfilter/ip_conntrack_standalone.c
+53
-1
net/ipv4/netfilter/ip_conntrack_tftp.c
net/ipv4/netfilter/ip_conntrack_tftp.c
+14
-11
net/ipv4/netfilter/ip_nat_core.c
net/ipv4/netfilter/ip_nat_core.c
+4
-0
net/ipv4/netfilter/ipt_LOG.c
net/ipv4/netfilter/ipt_LOG.c
+60
-20
net/ipv4/netfilter/ipt_NOTRACK.c
net/ipv4/netfilter/ipt_NOTRACK.c
+75
-0
net/ipv4/netfilter/ipt_ULOG.c
net/ipv4/netfilter/ipt_ULOG.c
+57
-20
net/ipv4/netfilter/ipt_conntrack.c
net/ipv4/netfilter/ipt_conntrack.c
+7
-5
net/ipv4/netfilter/ipt_state.c
net/ipv4/netfilter/ipt_state.c
+3
-1
net/ipv4/netfilter/iptable_raw.c
net/ipv4/netfilter/iptable_raw.c
+149
-0
net/ipv6/netfilter/Kconfig
net/ipv6/netfilter/Kconfig
+12
-0
net/ipv6/netfilter/Makefile
net/ipv6/netfilter/Makefile
+1
-0
net/ipv6/netfilter/ip6t_LOG.c
net/ipv6/netfilter/ip6t_LOG.c
+64
-23
net/ipv6/netfilter/ip6table_raw.c
net/ipv6/netfilter/ip6table_raw.c
+154
-0
No files found.
include/linux/netfilter.h
View file @
eccf6f14
...
...
@@ -99,6 +99,24 @@ void nf_unregister_sockopt(struct nf_sockopt_ops *reg);
extern
struct
list_head
nf_hooks
[
NPROTO
][
NF_MAX_HOOKS
];
typedef
void
nf_logfn
(
unsigned
int
hooknum
,
const
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
const
char
*
prefix
);
/* Function to register/unregister log function. */
int
nf_log_register
(
int
pf
,
nf_logfn
*
logfn
);
void
nf_log_unregister
(
int
pf
,
nf_logfn
*
logfn
);
/* Calls the registered backend logging function */
void
nf_log_packet
(
int
pf
,
unsigned
int
hooknum
,
const
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
const
char
*
fmt
,
...);
/* Activate hook; either okfn or kfree_skb called, unless a hook
returns NF_STOLEN (in which case, it's up to the hook to deal with
the consequences).
...
...
include/linux/netfilter_ipv4.h
View file @
eccf6f14
...
...
@@ -51,6 +51,8 @@
enum
nf_ip_hook_priorities
{
NF_IP_PRI_FIRST
=
INT_MIN
,
NF_IP_PRI_CONNTRACK_DEFRAG
=
-
400
,
NF_IP_PRI_RAW
=
-
300
,
NF_IP_PRI_SELINUX_FIRST
=
-
225
,
NF_IP_PRI_CONNTRACK
=
-
200
,
NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD
=
-
175
,
...
...
include/linux/netfilter_ipv4/ip_conntrack.h
View file @
eccf6f14
...
...
@@ -252,6 +252,9 @@ extern void ip_ct_refresh(struct ip_conntrack *ct,
/* 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
);
...
...
include/linux/netfilter_ipv4/ip_conntrack_helper.h
View file @
eccf6f14
...
...
@@ -35,9 +35,13 @@ extern void ip_conntrack_helper_unregister(struct ip_conntrack_helper *);
extern
struct
ip_conntrack_helper
*
ip_ct_find_helper
(
const
struct
ip_conntrack_tuple
*
tuple
);
/* Allocate space for an expectation: this is mandatory before calling
ip_conntrack_expect_related. */
extern
struct
ip_conntrack_expect
*
ip_conntrack_expect_alloc
(
void
);
/* Add an expected connection: can have more than one per connection */
extern
int
ip_conntrack_expect_related
(
struct
ip_conntrack
*
related_to
,
struct
ip_conntrack
_expect
*
exp
);
extern
int
ip_conntrack_expect_related
(
struct
ip_conntrack
_expect
*
exp
,
struct
ip_conntrack
*
related_to
);
extern
int
ip_conntrack_change_expect
(
struct
ip_conntrack_expect
*
expect
,
struct
ip_conntrack_tuple
*
newtuple
);
extern
void
ip_conntrack_unexpect_related
(
struct
ip_conntrack_expect
*
exp
);
...
...
include/linux/netfilter_ipv4/ip_logging.h
0 → 100644
View file @
eccf6f14
/* IPv4 macros for the internal logging interface. */
#ifndef __IP_LOGGING_H
#define __IP_LOGGING_H
#ifdef __KERNEL__
#include <linux/socket.h>
#include <linux/netfilter_logging.h>
#define nf_log_ip_packet(pskb,hooknum,in,out,fmt,args...) \
nf_log_packet(AF_INET,pskb,hooknum,in,out,fmt,##args)
#define nf_log_ip(pfh,len,fmt,args...) \
nf_log(AF_INET,pfh,len,fmt,##args)
#define nf_ip_log_register(logging) nf_log_register(AF_INET,logging)
#define nf_ip_log_unregister(logging) nf_log_unregister(AF_INET,logging)
#endif
/*__KERNEL__*/
#endif
/*__IP_LOGGING_H*/
include/linux/netfilter_ipv4/ipt_ULOG.h
View file @
eccf6f14
...
...
@@ -11,6 +11,9 @@
#define NETLINK_NFLOG 5
#endif
#define ULOG_DEFAULT_NLGROUP 1
#define ULOG_DEFAULT_QTHRESHOLD 1
#define ULOG_MAC_LEN 80
#define ULOG_PREFIX_LEN 32
...
...
include/linux/netfilter_ipv4/ipt_conntrack.h
View file @
eccf6f14
...
...
@@ -10,6 +10,7 @@
#define IPT_CONNTRACK_STATE_SNAT (1 << (IP_CT_NUMBER + 1))
#define IPT_CONNTRACK_STATE_DNAT (1 << (IP_CT_NUMBER + 2))
#define IPT_CONNTRACK_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 3))
/* flags, invflags: */
#define IPT_CONNTRACK_STATE 0x01
...
...
include/linux/netfilter_ipv4/ipt_state.h
View file @
eccf6f14
...
...
@@ -4,6 +4,8 @@
#define IPT_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1))
#define IPT_STATE_INVALID (1 << 0)
#define IPT_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 1))
struct
ipt_state_info
{
unsigned
int
statemask
;
...
...
include/linux/netfilter_ipv6/ip6_logging.h
0 → 100644
View file @
eccf6f14
/* IPv6 macros for the nternal logging interface. */
#ifndef __IP6_LOGGING_H
#define __IP6_LOGGING_H
#ifdef __KERNEL__
#include <linux/socket.h>
#include <linux/netfilter_logging.h>
#define nf_log_ip6_packet(pskb,hooknum,in,out,fmt,args...) \
nf_log_packet(AF_INET6,pskb,hooknum,in,out,fmt,##args)
#define nf_log_ip6(pfh,len,fmt,args...) \
nf_log(AF_INET6,pfh,len,fmt,##args)
#define nf_ip6_log_register(logging) nf_log_register(AF_INET6,logging)
#define nf_ip6_log_unregister(logging) nf_log_unregister(AF_INET6,logging)
#endif
/*__KERNEL__*/
#endif
/*__IP6_LOGGING_H*/
include/linux/netfilter_logging.h
0 → 100644
View file @
eccf6f14
/* Internal logging interface, which relies on the real
LOG target modules */
#ifndef __LINUX_NETFILTER_LOGGING_H
#define __LINUX_NETFILTER_LOGGING_H
#ifdef __KERNEL__
#include <asm/atomic.h>
struct
nf_logging_t
{
void
(
*
nf_log_packet
)(
struct
sk_buff
**
pskb
,
unsigned
int
hooknum
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
const
char
*
prefix
);
void
(
*
nf_log
)(
char
*
pfh
,
size_t
len
,
const
char
*
prefix
);
};
extern
void
nf_log_register
(
int
pf
,
const
struct
nf_logging_t
*
logging
);
extern
void
nf_log_unregister
(
int
pf
,
const
struct
nf_logging_t
*
logging
);
extern
void
nf_log_packet
(
int
pf
,
struct
sk_buff
**
pskb
,
unsigned
int
hooknum
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
const
char
*
fmt
,
...);
extern
void
nf_log
(
int
pf
,
char
*
pfh
,
size_t
len
,
const
char
*
fmt
,
...);
#endif
/*__KERNEL__*/
#endif
/*__LINUX_NETFILTER_LOGGING_H*/
net/core/netfilter.c
View file @
eccf6f14
...
...
@@ -8,8 +8,10 @@
*
* February 2000: Modified by James Morris to have 1 queue per protocol.
* 15-Mar-2000: Added NF_REPEAT --RR.
* 08-May-2003: Internal logging interface added by Jozsef Kadlecsik.
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/netfilter.h>
#include <net/protocol.h>
#include <linux/init.h>
...
...
@@ -741,6 +743,72 @@ int skb_ip_make_writable(struct sk_buff **pskb, unsigned int writable_len)
EXPORT_SYMBOL
(
skb_ip_make_writable
);
#endif
/*CONFIG_INET*/
/* Internal logging interface, which relies on the real
LOG target modules */
#define NF_LOG_PREFIXLEN 128
static
nf_logfn
*
nf_logging
[
NPROTO
];
/* = NULL */
static
int
reported
=
0
;
static
spinlock_t
nf_log_lock
=
SPIN_LOCK_UNLOCKED
;
int
nf_log_register
(
int
pf
,
nf_logfn
*
logfn
)
{
int
ret
=
-
EBUSY
;
/* Any setup of logging members must be done before
* substituting pointer. */
smp_wmb
();
spin_lock
(
&
nf_log_lock
);
if
(
!
nf_logging
[
pf
])
{
nf_logging
[
pf
]
=
logfn
;
ret
=
0
;
}
spin_unlock
(
&
nf_log_lock
);
return
ret
;
}
void
nf_log_unregister
(
int
pf
,
nf_logfn
*
logfn
)
{
spin_lock
(
&
nf_log_lock
);
if
(
nf_logging
[
pf
]
==
logfn
)
nf_logging
[
pf
]
=
NULL
;
spin_unlock
(
&
nf_log_lock
);
/* Give time to concurrent readers. */
synchronize_net
();
}
void
nf_log_packet
(
int
pf
,
unsigned
int
hooknum
,
const
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
const
char
*
fmt
,
...)
{
va_list
args
;
char
prefix
[
NF_LOG_PREFIXLEN
];
nf_logfn
*
logfn
;
rcu_read_lock
();
logfn
=
nf_logging
[
pf
];
if
(
logfn
)
{
va_start
(
args
,
fmt
);
vsnprintf
(
prefix
,
sizeof
(
prefix
),
fmt
,
args
);
va_end
(
args
);
/* We must read logging before nf_logfn[pf] */
smp_read_barrier_depends
();
logfn
(
hooknum
,
skb
,
in
,
out
,
prefix
);
}
else
if
(
!
reported
)
{
printk
(
KERN_WARNING
"nf_log_packet: can
\'
t log yet, "
"no backend logging module loaded in!
\n
"
);
reported
++
;
}
rcu_read_unlock
();
}
EXPORT_SYMBOL
(
nf_log_register
);
EXPORT_SYMBOL
(
nf_log_unregister
);
EXPORT_SYMBOL
(
nf_log_packet
);
/* This does not belong here, but ipt_REJECT needs it if connection
tracking in use: without this, connection may not be in hash table,
...
...
net/ipv4/netfilter/Kconfig
View file @
eccf6f14
...
...
@@ -579,5 +579,29 @@ config IP_NF_COMPAT_IPFWADM
To compile it as a module, choose M here. If unsure, say N.
config IP_NF_TARGET_NOTRACK
tristate 'NOTRACK target support'
depends on IP_NF_RAW
help
The NOTRACK target allows a select rule to specify
which packets *not* to enter the conntrack/NAT
subsystem with all the consequences (no ICMP error tracking,
no protocol helpers for the selected packets).
If you want to compile it as a module, say M here and read
<file:Documentation/modules.txt>. If unsure, say `N'.
config IP_NF_RAW
tristate 'raw table support (required for NOTRACK/TRACE)'
depends on IP_NF_IPTABLES
help
This option adds a `raw' table to iptables. This table is the very
first in the netfilter framework and hooks in at the PREROUTING
and OUTPUT chains.
If you want to compile it as a module, say M here and read
<file:Documentation/modules.txt>. If unsure, say `N'.
help
endmenu
net/ipv4/netfilter/Makefile
View file @
eccf6f14
...
...
@@ -38,6 +38,7 @@ obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o
obj-$(CONFIG_IP_NF_FILTER)
+=
iptable_filter.o
obj-$(CONFIG_IP_NF_MANGLE)
+=
iptable_mangle.o
obj-$(CONFIG_IP_NF_NAT)
+=
iptable_nat.o
obj-$(CONFIG_IP_NF_RAW)
+=
iptable_raw.o
# matches
obj-$(CONFIG_IP_NF_MATCH_HELPER)
+=
ipt_helper.o
...
...
@@ -81,6 +82,7 @@ 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_TCPMSS)
+=
ipt_TCPMSS.o
obj-$(CONFIG_IP_NF_TARGET_NOTRACK)
+=
ipt_NOTRACK.o
# generic ARP tables
obj-$(CONFIG_IP_NF_ARPTABLES)
+=
arp_tables.o
...
...
net/ipv4/netfilter/ip_conntrack_amanda.c
View file @
eccf6f14
...
...
@@ -46,10 +46,11 @@ static DECLARE_LOCK(amanda_buffer_lock);
static
int
help
(
struct
sk_buff
*
skb
,
struct
ip_conntrack
*
ct
,
enum
ip_conntrack_info
ctinfo
)
{
struct
ip_conntrack_expect
exp
;
struct
ip_conntrack_expect
*
exp
;
struct
ip_ct_amanda_expect
*
exp_amanda_info
;
char
*
data
,
*
data_limit
,
*
tmp
;
unsigned
int
dataoff
,
i
;
u_int16_t
port
,
len
;
/* Only look at packets from the Amanda server */
if
(
CTINFO2DIR
(
ctinfo
)
==
IP_CT_DIR_ORIGINAL
)
...
...
@@ -79,33 +80,40 @@ static int help(struct sk_buff *skb,
goto
out
;
data
+=
strlen
(
"CONNECT "
);
memset
(
&
exp
,
0
,
sizeof
(
exp
));
exp
.
tuple
.
src
.
ip
=
ct
->
tuplehash
[
IP_CT_DIR_ORIGINAL
].
tuple
.
src
.
ip
;
exp
.
tuple
.
dst
.
ip
=
ct
->
tuplehash
[
IP_CT_DIR_ORIGINAL
].
tuple
.
dst
.
ip
;
exp
.
tuple
.
dst
.
protonum
=
IPPROTO_TCP
;
exp
.
mask
.
src
.
ip
=
0xFFFFFFFF
;
exp
.
mask
.
dst
.
ip
=
0xFFFFFFFF
;
exp
.
mask
.
dst
.
protonum
=
0xFFFF
;
exp
.
mask
.
dst
.
u
.
tcp
.
port
=
0xFFFF
;
/* Only search first line. */
if
((
tmp
=
strchr
(
data
,
'\n'
)))
*
tmp
=
'\0'
;
exp_amanda_info
=
&
exp
.
help
.
exp_amanda_info
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
conns
);
i
++
)
{
char
*
match
=
strstr
(
data
,
conns
[
i
]);
if
(
!
match
)
continue
;
tmp
=
data
=
match
+
strlen
(
conns
[
i
]);
exp_amanda_info
->
offset
=
data
-
amanda_buffer
;
exp_amanda_info
->
port
=
simple_strtoul
(
data
,
&
data
,
10
);
exp_amanda_info
->
len
=
data
-
tmp
;
if
(
exp_amanda_info
->
port
==
0
||
exp_amanda_info
->
len
>
5
)
port
=
simple_strtoul
(
data
,
&
data
,
10
);
len
=
data
-
tmp
;
if
(
port
==
0
||
len
>
5
)
break
;
exp
.
tuple
.
dst
.
u
.
tcp
.
port
=
htons
(
exp_amanda_info
->
port
);
ip_conntrack_expect_related
(
ct
,
&
exp
);
exp
=
ip_conntrack_expect_alloc
();
if
(
exp
==
NULL
)
goto
out
;
exp
->
tuple
.
src
.
ip
=
ct
->
tuplehash
[
IP_CT_DIR_ORIGINAL
].
tuple
.
src
.
ip
;
exp
->
tuple
.
dst
.
ip
=
ct
->
tuplehash
[
IP_CT_DIR_ORIGINAL
].
tuple
.
dst
.
ip
;
exp
->
tuple
.
dst
.
protonum
=
IPPROTO_TCP
;
exp
->
mask
.
src
.
ip
=
0xFFFFFFFF
;
exp
->
mask
.
dst
.
ip
=
0xFFFFFFFF
;
exp
->
mask
.
dst
.
protonum
=
0xFFFF
;
exp
->
mask
.
dst
.
u
.
tcp
.
port
=
0xFFFF
;
exp_amanda_info
=
&
exp
->
help
.
exp_amanda_info
;
exp_amanda_info
->
offset
=
data
-
amanda_buffer
;
exp_amanda_info
->
port
=
port
;
exp_amanda_info
->
len
=
len
;
exp
->
tuple
.
dst
.
u
.
tcp
.
port
=
htons
(
port
);
ip_conntrack_expect_related
(
exp
,
ct
);
}
out:
...
...
net/ipv4/netfilter/ip_conntrack_core.c
View file @
eccf6f14
...
...
@@ -67,6 +67,7 @@ int ip_conntrack_max;
static
atomic_t
ip_conntrack_count
=
ATOMIC_INIT
(
0
);
struct
list_head
*
ip_conntrack_hash
;
static
kmem_cache_t
*
ip_conntrack_cachep
;
struct
ip_conntrack
ip_conntrack_untracked
;
extern
struct
ip_conntrack_protocol
ip_conntrack_generic_protocol
;
...
...
@@ -794,6 +795,15 @@ unsigned int ip_conntrack_in(unsigned int hooknum,
int
set_reply
;
int
ret
;
/* Never happen */
if
((
*
pskb
)
->
nh
.
iph
->
frag_off
&
htons
(
IP_OFFSET
))
{
if
(
net_ratelimit
())
{
printk
(
KERN_ERR
"ip_conntrack_in: Frag of proto %u (hook=%u)
\n
"
,
(
*
pskb
)
->
nh
.
iph
->
protocol
,
hooknum
);
}
return
NF_DROP
;
}
/* FIXME: Do this right please. --RR */
(
*
pskb
)
->
nfcache
|=
NFC_UNKNOWN
;
...
...
@@ -812,18 +822,10 @@ unsigned int ip_conntrack_in(unsigned int hooknum,
}
#endif
/* Previously seen (loopback)? Ignore. Do this before
fragment check. */
/* Previously seen (loopback or untracked)? Ignore. */
if
((
*
pskb
)
->
nfct
)
return
NF_ACCEPT
;
/* Gather fragments. */
if
((
*
pskb
)
->
nh
.
iph
->
frag_off
&
htons
(
IP_MF
|
IP_OFFSET
))
{
*
pskb
=
ip_ct_gather_frags
(
*
pskb
);
if
(
!*
pskb
)
return
NF_STOLEN
;
}
proto
=
ip_ct_find_proto
((
*
pskb
)
->
nh
.
iph
->
protocol
);
/* It may be an icmp error... */
...
...
@@ -917,11 +919,55 @@ static void expectation_timed_out(unsigned long ul_expect)
WRITE_UNLOCK
(
&
ip_conntrack_lock
);
}
struct
ip_conntrack_expect
*
ip_conntrack_expect_alloc
()
{
struct
ip_conntrack_expect
*
new
;
new
=
(
struct
ip_conntrack_expect
*
)
kmalloc
(
sizeof
(
struct
ip_conntrack_expect
),
GFP_ATOMIC
);
if
(
!
new
)
{
DEBUGP
(
"expect_related: OOM allocating expect
\n
"
);
return
NULL
;
}
/* tuple_cmp compares whole union, we have to initialized cleanly */
memset
(
new
,
0
,
sizeof
(
struct
ip_conntrack_expect
));
return
new
;
}
static
void
ip_conntrack_expect_insert
(
struct
ip_conntrack_expect
*
new
,
struct
ip_conntrack
*
related_to
)
{
DEBUGP
(
"new expectation %p of conntrack %p
\n
"
,
new
,
related_to
);
new
->
expectant
=
related_to
;
new
->
sibling
=
NULL
;
atomic_set
(
&
new
->
use
,
1
);
/* add to expected list for this connection */
list_add
(
&
new
->
expected_list
,
&
related_to
->
sibling_list
);
/* add to global list of expectations */
list_prepend
(
&
ip_conntrack_expect_list
,
&
new
->
list
);
/* add and start timer if required */
if
(
related_to
->
helper
->
timeout
)
{
init_timer
(
&
new
->
timeout
);
new
->
timeout
.
data
=
(
unsigned
long
)
new
;
new
->
timeout
.
function
=
expectation_timed_out
;
new
->
timeout
.
expires
=
jiffies
+
related_to
->
helper
->
timeout
*
HZ
;
add_timer
(
&
new
->
timeout
);
}
related_to
->
expecting
++
;
}
/* Add a related connection. */
int
ip_conntrack_expect_related
(
struct
ip_conntrack
*
related_to
,
struct
ip_conntrack
_expect
*
expect
)
int
ip_conntrack_expect_related
(
struct
ip_conntrack
_expect
*
expect
,
struct
ip_conntrack
*
related_to
)
{
struct
ip_conntrack_expect
*
old
,
*
new
;
struct
ip_conntrack_expect
*
old
;
int
ret
=
0
;
WRITE_LOCK
(
&
ip_conntrack_lock
);
...
...
@@ -943,7 +989,7 @@ int ip_conntrack_expect_related(struct ip_conntrack *related_to,
if
(
related_to
->
helper
->
timeout
)
{
if
(
!
del_timer
(
&
old
->
timeout
))
{
/* expectation is dying. Fall through */
old
=
NULL
;
goto
out
;
}
else
{
old
->
timeout
.
expires
=
jiffies
+
related_to
->
helper
->
timeout
*
HZ
;
...
...
@@ -951,10 +997,10 @@ int ip_conntrack_expect_related(struct ip_conntrack *related_to,
}
}
if
(
old
)
{
WRITE_UNLOCK
(
&
ip_conntrack_lock
);
return
-
EEXIST
;
}
WRITE_UNLOCK
(
&
ip_conntrack_lock
);
kfree
(
expect
);
return
-
EEXIST
;
}
else
if
(
related_to
->
helper
->
max_expected
&&
related_to
->
expecting
>=
related_to
->
helper
->
max_expected
)
{
struct
list_head
*
cur_item
;
...
...
@@ -971,6 +1017,7 @@ int ip_conntrack_expect_related(struct ip_conntrack *related_to,
related_to
->
helper
->
name
,
NIPQUAD
(
related_to
->
tuplehash
[
IP_CT_DIR_ORIGINAL
].
tuple
.
src
.
ip
),
NIPQUAD
(
related_to
->
tuplehash
[
IP_CT_DIR_ORIGINAL
].
tuple
.
dst
.
ip
));
kfree
(
expect
);
return
-
EPERM
;
}
DEBUGP
(
"ip_conntrack: max number of expected "
...
...
@@ -1010,37 +1057,12 @@ int ip_conntrack_expect_related(struct ip_conntrack *related_to,
&
expect
->
mask
))
{
WRITE_UNLOCK
(
&
ip_conntrack_lock
);
DEBUGP
(
"expect_related: busy!
\n
"
);
kfree
(
expect
);
return
-
EBUSY
;
}
new
=
(
struct
ip_conntrack_expect
*
)
kmalloc
(
sizeof
(
struct
ip_conntrack_expect
),
GFP_ATOMIC
);
if
(
!
new
)
{
WRITE_UNLOCK
(
&
ip_conntrack_lock
);
DEBUGP
(
"expect_relaed: OOM allocating expect
\n
"
);
return
-
ENOMEM
;
}
DEBUGP
(
"new expectation %p of conntrack %p
\n
"
,
new
,
related_to
);
memcpy
(
new
,
expect
,
sizeof
(
*
expect
));
new
->
expectant
=
related_to
;
new
->
sibling
=
NULL
;
atomic_set
(
&
new
->
use
,
1
);
/* add to expected list for this connection */
list_add
(
&
new
->
expected_list
,
&
related_to
->
sibling_list
);
/* add to global list of expectations */
list_prepend
(
&
ip_conntrack_expect_list
,
&
new
->
list
);
/* add and start timer if required */
if
(
related_to
->
helper
->
timeout
)
{
init_timer
(
&
new
->
timeout
);
new
->
timeout
.
data
=
(
unsigned
long
)
new
;
new
->
timeout
.
function
=
expectation_timed_out
;
new
->
timeout
.
expires
=
jiffies
+
related_to
->
helper
->
timeout
*
HZ
;
add_timer
(
&
new
->
timeout
);
}
related_to
->
expecting
++
;
out:
ip_conntrack_expect_insert
(
expect
,
related_to
);
WRITE_UNLOCK
(
&
ip_conntrack_lock
);
...
...
@@ -1158,18 +1180,18 @@ void ip_ct_refresh(struct ip_conntrack *ct, unsigned long extra_jiffies)
{
IP_NF_ASSERT
(
ct
->
timeout
.
data
==
(
unsigned
long
)
ct
);
WRITE_LOCK
(
&
ip_conntrack_lock
);
/* If not in hash table, timer will not be active yet */
if
(
!
is_confirmed
(
ct
))
ct
->
timeout
.
expires
=
extra_jiffies
;
else
{
WRITE_LOCK
(
&
ip_conntrack_lock
);
/* Need del_timer for race avoidance (may already be dying). */
if
(
del_timer
(
&
ct
->
timeout
))
{
ct
->
timeout
.
expires
=
jiffies
+
extra_jiffies
;
add_timer
(
&
ct
->
timeout
);
}
WRITE_UNLOCK
(
&
ip_conntrack_lock
);
}
WRITE_UNLOCK
(
&
ip_conntrack_lock
);
}
/* Returns new sk_buff, or NULL */
...
...
@@ -1422,6 +1444,18 @@ int __init ip_conntrack_init(void)
/* For use by ipt_REJECT */
ip_ct_attach
=
ip_conntrack_attach
;
/* Set up fake conntrack:
- to never be deleted, not in any hashes */
atomic_set
(
&
ip_conntrack_untracked
.
ct_general
.
use
,
1
);
/* - and look it like as a confirmed connection */
set_bit
(
IPS_CONFIRMED_BIT
,
&
ip_conntrack_untracked
.
status
);
/* - and prepare the ctinfo field for REJECT & NAT. */
ip_conntrack_untracked
.
infos
[
IP_CT_NEW
].
master
=
ip_conntrack_untracked
.
infos
[
IP_CT_RELATED
].
master
=
ip_conntrack_untracked
.
infos
[
IP_CT_RELATED
+
IP_CT_IS_REPLY
].
master
=
&
ip_conntrack_untracked
.
ct_general
;
return
ret
;
err_free_hash:
...
...
net/ipv4/netfilter/ip_conntrack_ftp.c
View file @
eccf6f14
...
...
@@ -256,8 +256,8 @@ static int help(struct sk_buff *skb,
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
expect
,
*
exp
=
&
expect
;
struct
ip_ct_ftp_expect
*
exp_ftp_info
=
&
exp
->
help
.
exp_ftp_info
;
struct
ip_conntrack_expect
*
exp
;
struct
ip_ct_ftp_expect
*
exp_ftp_info
;
unsigned
int
i
;
int
found
=
0
;
...
...
@@ -346,8 +346,15 @@ static int help(struct sk_buff *skb,
DEBUGP
(
"conntrack_ftp: match `%.*s' (%u bytes at %u)
\n
"
,
(
int
)
matchlen
,
data
+
matchoff
,
matchlen
,
ntohl
(
tcph
.
seq
)
+
matchoff
);
memset
(
&
expect
,
0
,
sizeof
(
expect
));
/* Allocate expectation which will be inserted */
exp
=
ip_conntrack_expect_alloc
();
if
(
exp
==
NULL
)
{
ret
=
NF_ACCEPT
;
goto
out
;
}
exp_ftp_info
=
&
exp
->
help
.
exp_ftp_info
;
/* Update the ftp info */
if
(
htonl
((
array
[
0
]
<<
24
)
|
(
array
[
1
]
<<
16
)
|
(
array
[
2
]
<<
8
)
|
array
[
3
])
...
...
@@ -389,7 +396,7 @@ static int help(struct sk_buff *skb,
exp
->
expectfn
=
NULL
;
/* Ignore failure; should only happen with NAT */
ip_conntrack_expect_related
(
ct
,
&
expe
ct
);
ip_conntrack_expect_related
(
exp
,
ct
);
ret
=
NF_ACCEPT
;
out:
UNLOCK_BH
(
&
ip_ftp_lock
);
...
...
net/ipv4/netfilter/ip_conntrack_irc.c
View file @
eccf6f14
...
...
@@ -106,8 +106,8 @@ static int help(struct sk_buff *skb,
struct
tcphdr
tcph
;
char
*
data
,
*
data_limit
;
int
dir
=
CTINFO2DIR
(
ctinfo
);
struct
ip_conntrack_expect
expect
,
*
exp
=
&
expect
;
struct
ip_ct_irc_expect
*
exp_irc_info
=
&
exp
->
help
.
exp_irc_info
;
struct
ip_conntrack_expect
*
exp
;
struct
ip_ct_irc_expect
*
exp_irc_info
=
NULL
;
u_int32_t
dcc_ip
;
u_int16_t
dcc_port
;
...
...
@@ -190,8 +190,12 @@ static int help(struct sk_buff *skb,
continue
;
}
memset
(
&
expect
,
0
,
sizeof
(
expect
));
exp
=
ip_conntrack_expect_alloc
();
if
(
exp
==
NULL
)
goto
out
;
exp_irc_info
=
&
exp
->
help
.
exp_irc_info
;
/* save position of address in dcc string,
* necessary for NAT */
...
...
@@ -218,7 +222,7 @@ static int help(struct sk_buff *skb,
NIPQUAD
(
exp
->
tuple
.
dst
.
ip
),
ntohs
(
exp
->
tuple
.
dst
.
u
.
tcp
.
port
));
ip_conntrack_expect_related
(
ct
,
&
expe
ct
);
ip_conntrack_expect_related
(
exp
,
ct
);
goto
out
;
}
/* for .. NUM_DCCPROTO */
...
...
net/ipv4/netfilter/ip_conntrack_proto_tcp.c
View file @
eccf6f14
...
...
@@ -178,6 +178,16 @@ static int tcp_packet(struct ip_conntrack *conntrack,
if
(
skb_copy_bits
(
skb
,
skb
->
nh
.
iph
->
ihl
*
4
,
&
tcph
,
sizeof
(
tcph
))
!=
0
)
return
-
1
;
/* If only reply is a RST, we can consider ourselves not to
have an established connection: this is a fairly common
problem case, so we can delete the conntrack
immediately. --RR */
if
(
!
test_bit
(
IPS_SEEN_REPLY_BIT
,
&
conntrack
->
status
)
&&
tcph
.
rst
)
{
if
(
del_timer
(
&
conntrack
->
timeout
))
conntrack
->
timeout
.
function
((
unsigned
long
)
conntrack
);
return
NF_ACCEPT
;
}
WRITE_LOCK
(
&
tcp_lock
);
oldtcpstate
=
conntrack
->
proto
.
tcp
.
state
;
newconntrack
...
...
@@ -199,29 +209,21 @@ static int tcp_packet(struct ip_conntrack *conntrack,
/* Poor man's window tracking: record SYN/ACK for handshake check */
if
(
oldtcpstate
==
TCP_CONNTRACK_SYN_SENT
&&
CTINFO2DIR
(
ctinfo
)
==
IP_CT_DIR_REPLY
&&
tcph
.
syn
&&
tcph
.
ack
)
&&
tcph
.
syn
&&
tcph
.
ack
)
{
conntrack
->
proto
.
tcp
.
handshake_ack
=
htonl
(
ntohl
(
tcph
.
seq
)
+
1
);
goto
out
;
}
/* If only reply is a RST, we can consider ourselves not to
have an established connection: this is a fairly common
problem case, so we can delete the conntrack
immediately. --RR */
if
(
!
test_bit
(
IPS_SEEN_REPLY_BIT
,
&
conntrack
->
status
)
&&
tcph
.
rst
)
{
WRITE_UNLOCK
(
&
tcp_lock
);
if
(
del_timer
(
&
conntrack
->
timeout
))
conntrack
->
timeout
.
function
((
unsigned
long
)
conntrack
);
}
else
{
/* Set ASSURED if we see see valid ack in ESTABLISHED after SYN_RECV */
if
(
oldtcpstate
==
TCP_CONNTRACK_SYN_RECV
&&
CTINFO2DIR
(
ctinfo
)
==
IP_CT_DIR_ORIGINAL
&&
tcph
.
ack
&&
!
tcph
.
syn
&&
tcph
.
ack_seq
==
conntrack
->
proto
.
tcp
.
handshake_ack
)
set_bit
(
IPS_ASSURED_BIT
,
&
conntrack
->
status
);
/* Set ASSURED if we see valid ack in ESTABLISHED after SYN_RECV */
if
(
oldtcpstate
==
TCP_CONNTRACK_SYN_RECV
&&
CTINFO2DIR
(
ctinfo
)
==
IP_CT_DIR_ORIGINAL
&&
tcph
.
ack
&&
!
tcph
.
syn
&&
tcph
.
ack_seq
==
conntrack
->
proto
.
tcp
.
handshake_ack
)
set_bit
(
IPS_ASSURED_BIT
,
&
conntrack
->
status
);
WRITE_UNLOCK
(
&
tcp_lock
);
ip_ct_refresh
(
conntrack
,
*
tcp_timeouts
[
newconntrack
]);
}
out:
WRITE_UNLOCK
(
&
tcp_lock
);
ip_ct_refresh
(
conntrack
,
*
tcp_timeouts
[
newconntrack
]);
return
NF_ACCEPT
;
}
...
...
net/ipv4/netfilter/ip_conntrack_standalone.c
View file @
eccf6f14
...
...
@@ -194,6 +194,26 @@ static unsigned int ip_confirm(unsigned int hooknum,
return
ip_conntrack_confirm
(
*
pskb
);
}
static
unsigned
int
ip_conntrack_defrag
(
unsigned
int
hooknum
,
struct
sk_buff
**
pskb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
{
/* Previously seen (loopback)? Ignore. Do this before
fragment check. */
if
((
*
pskb
)
->
nfct
)
return
NF_ACCEPT
;
/* Gather fragments. */
if
((
*
pskb
)
->
nh
.
iph
->
frag_off
&
htons
(
IP_MF
|
IP_OFFSET
))
{
*
pskb
=
ip_ct_gather_frags
(
*
pskb
);
if
(
!*
pskb
)
return
NF_STOLEN
;
}
return
NF_ACCEPT
;
}
static
unsigned
int
ip_refrag
(
unsigned
int
hooknum
,
struct
sk_buff
**
pskb
,
const
struct
net_device
*
in
,
...
...
@@ -236,6 +256,14 @@ static unsigned int ip_conntrack_local(unsigned int hooknum,
/* Connection tracking may drop packets, but never alters them, so
make it the first hook. */
static
struct
nf_hook_ops
ip_conntrack_defrag_ops
=
{
.
hook
=
ip_conntrack_defrag
,
.
owner
=
THIS_MODULE
,
.
pf
=
PF_INET
,
.
hooknum
=
NF_IP_PRE_ROUTING
,
.
priority
=
NF_IP_PRI_CONNTRACK_DEFRAG
,
};
static
struct
nf_hook_ops
ip_conntrack_in_ops
=
{
.
hook
=
ip_conntrack_in
,
.
owner
=
THIS_MODULE
,
...
...
@@ -244,6 +272,14 @@ static struct nf_hook_ops ip_conntrack_in_ops = {
.
priority
=
NF_IP_PRI_CONNTRACK
,
};
static
struct
nf_hook_ops
ip_conntrack_defrag_local_out_ops
=
{
.
hook
=
ip_conntrack_defrag
,
.
owner
=
THIS_MODULE
,
.
pf
=
PF_INET
,
.
hooknum
=
NF_IP_LOCAL_OUT
,
.
priority
=
NF_IP_PRI_CONNTRACK_DEFRAG
,
};
static
struct
nf_hook_ops
ip_conntrack_local_out_ops
=
{
.
hook
=
ip_conntrack_local
,
.
owner
=
THIS_MODULE
,
...
...
@@ -470,10 +506,20 @@ static int init_or_cleanup(int init)
if
(
!
proc
)
goto
cleanup_init
;
proc
->
owner
=
THIS_MODULE
;
ret
=
nf_register_hook
(
&
ip_conntrack_defrag_ops
);
if
(
ret
<
0
)
{
printk
(
"ip_conntrack: can't register pre-routing defrag hook.
\n
"
);
goto
cleanup_proc
;
}
ret
=
nf_register_hook
(
&
ip_conntrack_defrag_local_out_ops
);
if
(
ret
<
0
)
{
printk
(
"ip_conntrack: can't register local_out defrag hook.
\n
"
);
goto
cleanup_defragops
;
}
ret
=
nf_register_hook
(
&
ip_conntrack_in_ops
);
if
(
ret
<
0
)
{
printk
(
"ip_conntrack: can't register pre-routing hook.
\n
"
);
goto
cleanup_
proc
;
goto
cleanup_
defraglocalops
;
}
ret
=
nf_register_hook
(
&
ip_conntrack_local_out_ops
);
if
(
ret
<
0
)
{
...
...
@@ -511,6 +557,10 @@ static int init_or_cleanup(int init)
nf_unregister_hook
(
&
ip_conntrack_local_out_ops
);
cleanup_inops:
nf_unregister_hook
(
&
ip_conntrack_in_ops
);
cleanup_defraglocalops:
nf_unregister_hook
(
&
ip_conntrack_defrag_local_out_ops
);
cleanup_defragops:
nf_unregister_hook
(
&
ip_conntrack_defrag_ops
);
cleanup_proc:
proc_net_remove
(
"ip_conntrack"
);
cleanup_init:
...
...
@@ -591,6 +641,7 @@ EXPORT_SYMBOL(ip_ct_refresh);
EXPORT_SYMBOL
(
ip_ct_find_proto
);
EXPORT_SYMBOL
(
__ip_ct_find_proto
);
EXPORT_SYMBOL
(
ip_ct_find_helper
);
EXPORT_SYMBOL
(
ip_conntrack_expect_alloc
);
EXPORT_SYMBOL
(
ip_conntrack_expect_related
);
EXPORT_SYMBOL
(
ip_conntrack_change_expect
);
EXPORT_SYMBOL
(
ip_conntrack_unexpect_related
);
...
...
@@ -602,5 +653,6 @@ EXPORT_SYMBOL(ip_conntrack_htable_size);
EXPORT_SYMBOL
(
ip_conntrack_expect_list
);
EXPORT_SYMBOL
(
ip_conntrack_lock
);
EXPORT_SYMBOL
(
ip_conntrack_hash
);
EXPORT_SYMBOL
(
ip_conntrack_untracked
);
EXPORT_SYMBOL_GPL
(
ip_conntrack_find_get
);
EXPORT_SYMBOL_GPL
(
ip_conntrack_put
);
net/ipv4/netfilter/ip_conntrack_tftp.c
View file @
eccf6f14
...
...
@@ -44,7 +44,7 @@ static int tftp_help(struct sk_buff *skb,
enum
ip_conntrack_info
ctinfo
)
{
struct
tftphdr
tftph
;
struct
ip_conntrack_expect
exp
;
struct
ip_conntrack_expect
*
exp
;
if
(
skb_copy_bits
(
skb
,
skb
->
nh
.
iph
->
ihl
*
4
+
sizeof
(
struct
udphdr
),
&
tftph
,
sizeof
(
tftph
))
!=
0
)
...
...
@@ -57,19 +57,22 @@ static int tftp_help(struct sk_buff *skb,
DEBUGP
(
""
);
DUMP_TUPLE
(
&
ct
->
tuplehash
[
IP_CT_DIR_ORIGINAL
].
tuple
);
DUMP_TUPLE
(
&
ct
->
tuplehash
[
IP_CT_DIR_REPLY
].
tuple
);
memset
(
&
exp
,
0
,
sizeof
(
exp
));
exp
.
tuple
=
ct
->
tuplehash
[
IP_CT_DIR_REPLY
].
tuple
;
exp
.
mask
.
src
.
ip
=
0xffffffff
;
exp
.
mask
.
dst
.
ip
=
0xffffffff
;
exp
.
mask
.
dst
.
u
.
udp
.
port
=
0xffff
;
exp
.
mask
.
dst
.
protonum
=
0xffff
;
exp
.
expectfn
=
NULL
;
exp
=
ip_conntrack_expect_alloc
();
if
(
exp
==
NULL
)
return
NF_ACCEPT
;
exp
->
tuple
=
ct
->
tuplehash
[
IP_CT_DIR_REPLY
].
tuple
;
exp
->
mask
.
src
.
ip
=
0xffffffff
;
exp
->
mask
.
dst
.
ip
=
0xffffffff
;
exp
->
mask
.
dst
.
u
.
udp
.
port
=
0xffff
;
exp
->
mask
.
dst
.
protonum
=
0xffff
;
exp
->
expectfn
=
NULL
;
DEBUGP
(
"expect: "
);
DUMP_TUPLE
(
&
exp
.
tuple
);
DUMP_TUPLE
(
&
exp
.
mask
);
ip_conntrack_expect_related
(
ct
,
&
exp
);
DUMP_TUPLE
(
&
exp
->
tuple
);
DUMP_TUPLE
(
&
exp
->
mask
);
ip_conntrack_expect_related
(
exp
,
ct
);
break
;
case
TFTP_OPCODE_DATA
:
case
TFTP_OPCODE_ACK
:
...
...
net/ipv4/netfilter/ip_nat_core.c
View file @
eccf6f14
...
...
@@ -1016,6 +1016,10 @@ int __init ip_nat_init(void)
/* FIXME: Man, this is a hack. <SIGH> */
IP_NF_ASSERT
(
ip_conntrack_destroyed
==
NULL
);
ip_conntrack_destroyed
=
&
ip_nat_cleanup_conntrack
;
/* Initialize fake conntrack so that NAT will skip it */
ip_conntrack_untracked
.
nat
.
info
.
initialized
|=
(
1
<<
IP_NAT_MANIP_SRC
)
|
(
1
<<
IP_NAT_MANIP_DST
);
return
0
;
}
...
...
net/ipv4/netfilter/ipt_LOG.c
View file @
eccf6f14
...
...
@@ -19,6 +19,7 @@
#include <net/tcp.h>
#include <net/route.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv4/ipt_LOG.h>
...
...
@@ -26,6 +27,10 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR
(
"Netfilter Core Team <coreteam@netfilter.org>"
);
MODULE_DESCRIPTION
(
"iptables syslog logging module"
);
static
unsigned
int
nflog
=
1
;
MODULE_PARM
(
nflog
,
"i"
);
MODULE_PARM_DESC
(
nflog
,
"register as internal netfilter logging module"
);
#if 0
#define DEBUGP printk
#else
...
...
@@ -324,28 +329,25 @@ static void dump_packet(const struct ipt_log_info *info,
/* maxlen = 230+ 91 + 230 + 252 = 803 */
}
static
unsigned
int
ipt_log_target
(
struct
sk_buff
**
pskb
,
static
void
ipt_log_packet
(
unsigned
int
hooknum
,
const
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
unsigned
int
hooknum
,
const
void
*
targinfo
,
void
*
userinfo
)
const
struct
ipt_log_info
*
loginfo
,
const
char
*
level_string
,
const
char
*
prefix
)
{
const
struct
ipt_log_info
*
loginfo
=
targinfo
;
char
level_string
[
4
]
=
"< >"
;
level_string
[
1
]
=
'0'
+
(
loginfo
->
level
%
8
);
spin_lock_bh
(
&
log_lock
);
printk
(
level_string
);
printk
(
"%sIN=%s OUT=%s "
,
loginfo
->
prefix
,
prefix
==
NULL
?
loginfo
->
prefix
:
prefix
,
in
?
in
->
name
:
""
,
out
?
out
->
name
:
""
);
#ifdef CONFIG_BRIDGE_NETFILTER
if
(
(
*
pskb
)
->
nf_bridge
)
{
struct
net_device
*
physindev
=
(
*
pskb
)
->
nf_bridge
->
physindev
;
struct
net_device
*
physoutdev
=
(
*
pskb
)
->
nf_bridge
->
physoutdev
;
if
(
skb
->
nf_bridge
)
{
struct
net_device
*
physindev
=
skb
->
nf_bridge
->
physindev
;
struct
net_device
*
physoutdev
=
skb
->
nf_bridge
->
physoutdev
;
if
(
physindev
&&
in
!=
physindev
)
printk
(
"PHYSIN=%s "
,
physindev
->
name
);
...
...
@@ -357,25 +359,56 @@ ipt_log_target(struct sk_buff **pskb,
if
(
in
&&
!
out
)
{
/* MAC logging for input chain only. */
printk
(
"MAC="
);
if
(
(
*
pskb
)
->
dev
&&
(
*
pskb
)
->
dev
->
hard_header_len
&&
(
*
pskb
)
->
mac
.
raw
!=
(
void
*
)(
*
pskb
)
->
nh
.
iph
)
{
if
(
skb
->
dev
&&
skb
->
dev
->
hard_header_len
&&
skb
->
mac
.
raw
!=
(
void
*
)
skb
->
nh
.
iph
)
{
int
i
;
unsigned
char
*
p
=
(
*
pskb
)
->
mac
.
raw
;
for
(
i
=
0
;
i
<
(
*
pskb
)
->
dev
->
hard_header_len
;
i
++
,
p
++
)
unsigned
char
*
p
=
skb
->
mac
.
raw
;
for
(
i
=
0
;
i
<
skb
->
dev
->
hard_header_len
;
i
++
,
p
++
)
printk
(
"%02x%c"
,
*
p
,
i
==
(
*
pskb
)
->
dev
->
hard_header_len
-
1
i
==
skb
->
dev
->
hard_header_len
-
1
?
' '
:
':'
);
}
else
printk
(
" "
);
}
dump_packet
(
loginfo
,
*
p
skb
,
0
);
dump_packet
(
loginfo
,
skb
,
0
);
printk
(
"
\n
"
);
spin_unlock_bh
(
&
log_lock
);
}
static
unsigned
int
ipt_log_target
(
struct
sk_buff
**
pskb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
unsigned
int
hooknum
,
const
void
*
targinfo
,
void
*
userinfo
)
{
const
struct
ipt_log_info
*
loginfo
=
targinfo
;
char
level_string
[
4
]
=
"< >"
;
level_string
[
1
]
=
'0'
+
(
loginfo
->
level
%
8
);
ipt_log_packet
(
hooknum
,
*
pskb
,
in
,
out
,
loginfo
,
level_string
,
NULL
);
return
IPT_CONTINUE
;
}
static
void
ipt_logfn
(
unsigned
int
hooknum
,
const
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
const
char
*
prefix
)
{
struct
ipt_log_info
loginfo
=
{
.
level
=
0
,
.
logflags
=
IPT_LOG_MASK
,
.
prefix
=
""
};
ipt_log_packet
(
hooknum
,
skb
,
in
,
out
,
&
loginfo
,
KERN_WARNING
,
prefix
);
}
static
int
ipt_log_checkentry
(
const
char
*
tablename
,
const
struct
ipt_entry
*
e
,
void
*
targinfo
,
...
...
@@ -413,11 +446,18 @@ static struct ipt_target ipt_log_reg = {
static
int
__init
init
(
void
)
{
return
ipt_register_target
(
&
ipt_log_reg
);
if
(
ipt_register_target
(
&
ipt_log_reg
))
return
-
EINVAL
;
if
(
nflog
)
nf_log_register
(
PF_INET
,
&
ipt_logfn
);
return
0
;
}
static
void
__exit
fini
(
void
)
{
if
(
nflog
)
nf_log_unregister
(
PF_INET
,
&
ipt_logfn
);
ipt_unregister_target
(
&
ipt_log_reg
);
}
...
...
net/ipv4/netfilter/ipt_NOTRACK.c
0 → 100644
View file @
eccf6f14
/* This is a module which is used for setting up fake conntracks
* on packets so that they are not seen by the conntrack/NAT code.
*/
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv4/ip_conntrack.h>
static
unsigned
int
target
(
struct
sk_buff
**
pskb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
unsigned
int
hooknum
,
const
void
*
targinfo
,
void
*
userinfo
)
{
/* Previously seen (loopback)? Ignore. */
if
((
*
pskb
)
->
nfct
!=
NULL
)
return
IPT_CONTINUE
;
/* Attach fake conntrack entry.
If there is a real ct entry correspondig to this packet,
it'll hang aroun till timing out. We don't deal with it
for performance reasons. JK */
(
*
pskb
)
->
nfct
=
&
ip_conntrack_untracked
.
infos
[
IP_CT_NEW
];
nf_conntrack_get
((
*
pskb
)
->
nfct
);
return
IPT_CONTINUE
;
}
static
int
checkentry
(
const
char
*
tablename
,
const
struct
ipt_entry
*
e
,
void
*
targinfo
,
unsigned
int
targinfosize
,
unsigned
int
hook_mask
)
{
if
(
targinfosize
!=
0
)
{
printk
(
KERN_WARNING
"NOTRACK: targinfosize %u != 0
\n
"
,
targinfosize
);
return
0
;
}
if
(
strcmp
(
tablename
,
"raw"
)
!=
0
)
{
printk
(
KERN_WARNING
"NOTRACK: can only be called from
\"
raw
\"
table, not
\"
%s
\"\n
"
,
tablename
);
return
0
;
}
return
1
;
}
static
struct
ipt_target
ipt_notrack_reg
=
{
.
name
=
"NOTRACK"
,
.
target
=
target
,
.
checkentry
=
checkentry
,
.
me
=
THIS_MODULE
};
static
int
__init
init
(
void
)
{
if
(
ipt_register_target
(
&
ipt_notrack_reg
))
return
-
EINVAL
;
return
0
;
}
static
void
__exit
fini
(
void
)
{
ipt_unregister_target
(
&
ipt_notrack_reg
);
}
module_init
(
init
);
module_exit
(
fini
);
MODULE_LICENSE
(
"GPL"
);
net/ipv4/netfilter/ipt_ULOG.c
View file @
eccf6f14
...
...
@@ -50,6 +50,7 @@
#include <linux/netlink.h>
#include <linux/netdevice.h>
#include <linux/mm.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv4/ipt_ULOG.h>
#include <linux/netfilter_ipv4/lockhelp.h>
...
...
@@ -80,6 +81,10 @@ static unsigned int flushtimeout = 10 * HZ;
MODULE_PARM
(
flushtimeout
,
"i"
);
MODULE_PARM_DESC
(
flushtimeout
,
"buffer flush timeout"
);
static
unsigned
int
nflog
=
1
;
MODULE_PARM
(
nflog
,
"i"
);
MODULE_PARM_DESC
(
nflog
,
"register as internal netfilter logging module"
);
/* global data structures */
typedef
struct
{
...
...
@@ -157,17 +162,17 @@ struct sk_buff *ulog_alloc_skb(unsigned int size)
return
skb
;
}
static
unsigned
int
ipt_ulog_target
(
struct
sk_buff
**
pskb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
unsigned
int
hooknum
,
const
void
*
targinfo
,
void
*
userinfo
)
static
void
ipt_ulog_packet
(
unsigned
int
hooknum
,
const
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
const
struct
ipt_ulog_info
*
loginfo
,
const
char
*
prefix
)
{
ulog_buff_t
*
ub
;
ulog_packet_msg_t
*
pm
;
size_t
size
,
copy_len
;
struct
nlmsghdr
*
nlh
;
struct
ipt_ulog_info
*
loginfo
=
(
struct
ipt_ulog_info
*
)
targinfo
;
/* ffs == find first bit set, necessary because userspace
* is already shifting groupnumber, but we need unshifted.
...
...
@@ -176,8 +181,8 @@ static unsigned int ipt_ulog_target(struct sk_buff **pskb,
/* calculate the size of the skb needed */
if
((
loginfo
->
copy_range
==
0
)
||
(
loginfo
->
copy_range
>
(
*
pskb
)
->
len
))
{
copy_len
=
(
*
pskb
)
->
len
;
(
loginfo
->
copy_range
>
skb
->
len
))
{
copy_len
=
skb
->
len
;
}
else
{
copy_len
=
loginfo
->
copy_range
;
}
...
...
@@ -214,19 +219,21 @@ static unsigned int ipt_ulog_target(struct sk_buff **pskb,
/* copy hook, prefix, timestamp, payload, etc. */
pm
->
data_len
=
copy_len
;
pm
->
timestamp_sec
=
(
*
pskb
)
->
stamp
.
tv_sec
;
pm
->
timestamp_usec
=
(
*
pskb
)
->
stamp
.
tv_usec
;
pm
->
mark
=
(
*
pskb
)
->
nfmark
;
pm
->
timestamp_sec
=
skb
->
stamp
.
tv_sec
;
pm
->
timestamp_usec
=
skb
->
stamp
.
tv_usec
;
pm
->
mark
=
skb
->
nfmark
;
pm
->
hook
=
hooknum
;
if
(
loginfo
->
prefix
[
0
]
!=
'\0'
)
if
(
prefix
!=
NULL
)
strncpy
(
pm
->
prefix
,
prefix
,
sizeof
(
pm
->
prefix
));
else
if
(
loginfo
->
prefix
[
0
]
!=
'\0'
)
strncpy
(
pm
->
prefix
,
loginfo
->
prefix
,
sizeof
(
pm
->
prefix
));
else
*
(
pm
->
prefix
)
=
'\0'
;
if
(
in
&&
in
->
hard_header_len
>
0
&&
(
*
pskb
)
->
mac
.
raw
!=
(
void
*
)
(
*
pskb
)
->
nh
.
iph
&&
skb
->
mac
.
raw
!=
(
void
*
)
skb
->
nh
.
iph
&&
in
->
hard_header_len
<=
ULOG_MAC_LEN
)
{
memcpy
(
pm
->
mac
,
(
*
pskb
)
->
mac
.
raw
,
in
->
hard_header_len
);
memcpy
(
pm
->
mac
,
skb
->
mac
.
raw
,
in
->
hard_header_len
);
pm
->
mac_len
=
in
->
hard_header_len
;
}
else
pm
->
mac_len
=
0
;
...
...
@@ -241,8 +248,8 @@ static unsigned int ipt_ulog_target(struct sk_buff **pskb,
else
pm
->
outdev_name
[
0
]
=
'\0'
;
/* copy_len <=
(*pskb)
->len, so can't fail. */
if
(
skb_copy_bits
(
*
p
skb
,
0
,
pm
->
payload
,
copy_len
)
<
0
)
/* copy_len <=
skb
->len, so can't fail. */
if
(
skb_copy_bits
(
skb
,
0
,
pm
->
payload
,
copy_len
)
<
0
)
BUG
();
/* check if we are building multi-part messages */
...
...
@@ -266,8 +273,7 @@ static unsigned int ipt_ulog_target(struct sk_buff **pskb,
UNLOCK_BH
(
&
ulog_lock
);
return
IPT_CONTINUE
;
return
;
nlmsg_failure:
PRINTR
(
"ipt_ULOG: error during NLMSG_PUT
\n
"
);
...
...
@@ -276,8 +282,35 @@ static unsigned int ipt_ulog_target(struct sk_buff **pskb,
PRINTR
(
"ipt_ULOG: Error building netlink message
\n
"
);
UNLOCK_BH
(
&
ulog_lock
);
}
return
IPT_CONTINUE
;
static
unsigned
int
ipt_ulog_target
(
struct
sk_buff
**
pskb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
unsigned
int
hooknum
,
const
void
*
targinfo
,
void
*
userinfo
)
{
struct
ipt_ulog_info
*
loginfo
=
(
struct
ipt_ulog_info
*
)
targinfo
;
ipt_ulog_packet
(
hooknum
,
*
pskb
,
in
,
out
,
loginfo
,
NULL
);
return
IPT_CONTINUE
;
}
static
void
ipt_logfn
(
unsigned
int
hooknum
,
const
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
const
char
*
prefix
)
{
struct
ipt_ulog_info
loginfo
=
{
.
nl_group
=
ULOG_DEFAULT_NLGROUP
,
.
copy_range
=
0
,
.
qthreshold
=
ULOG_DEFAULT_QTHRESHOLD
,
.
prefix
=
""
};
ipt_ulog_packet
(
hooknum
,
skb
,
in
,
out
,
&
loginfo
,
prefix
);
}
static
int
ipt_ulog_checkentry
(
const
char
*
tablename
,
...
...
@@ -341,7 +374,9 @@ static int __init init(void)
sock_release
(
nflognl
->
sk_socket
);
return
-
EINVAL
;
}
if
(
nflog
)
nf_log_register
(
PF_INET
,
&
ipt_logfn
);
return
0
;
}
...
...
@@ -352,6 +387,8 @@ static void __exit fini(void)
DEBUGP
(
"ipt_ULOG: cleanup_module
\n
"
);
if
(
nflog
)
nf_log_unregister
(
PF_INET
,
&
ipt_logfn
);
ipt_unregister_target
(
&
ipt_ulog_reg
);
sock_release
(
nflognl
->
sk_socket
);
...
...
net/ipv4/netfilter/ipt_conntrack.c
View file @
eccf6f14
...
...
@@ -35,11 +35,13 @@ match(const struct sk_buff *skb,
#define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg))
if
(
ct
)
statebit
=
IPT_CONNTRACK_STATE_BIT
(
ctinfo
);
else
statebit
=
IPT_CONNTRACK_STATE_INVALID
;
if
(
skb
->
nfct
==
&
ip_conntrack_untracked
.
infos
[
IP_CT_NEW
])
statebit
=
IPT_CONNTRACK_STATE_UNTRACKED
;
else
if
(
ct
)
statebit
=
IPT_CONNTRACK_STATE_BIT
(
ctinfo
);
else
statebit
=
IPT_CONNTRACK_STATE_INVALID
;
if
(
sinfo
->
flags
&
IPT_CONNTRACK_STATE
)
{
if
(
ct
)
{
if
(
ct
->
tuplehash
[
IP_CT_DIR_ORIGINAL
].
tuple
.
src
.
ip
!=
...
...
net/ipv4/netfilter/ipt_state.c
View file @
eccf6f14
...
...
@@ -30,7 +30,9 @@ match(const struct sk_buff *skb,
enum
ip_conntrack_info
ctinfo
;
unsigned
int
statebit
;
if
(
!
ip_conntrack_get
((
struct
sk_buff
*
)
skb
,
&
ctinfo
))
if
(
skb
->
nfct
==
&
ip_conntrack_untracked
.
infos
[
IP_CT_NEW
])
statebit
=
IPT_STATE_UNTRACKED
;
else
if
(
!
ip_conntrack_get
((
struct
sk_buff
*
)
skb
,
&
ctinfo
))
statebit
=
IPT_STATE_INVALID
;
else
statebit
=
IPT_STATE_BIT
(
ctinfo
);
...
...
net/ipv4/netfilter/iptable_raw.c
0 → 100644
View file @
eccf6f14
/*
* 'raw' table, which is the very first hooked in at PRE_ROUTING and LOCAL_OUT .
*
* Copyright (C) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
*/
#include <linux/module.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#define RAW_VALID_HOOKS ((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT))
/* Standard entry. */
struct
ipt_standard
{
struct
ipt_entry
entry
;
struct
ipt_standard_target
target
;
};
struct
ipt_error_target
{
struct
ipt_entry_target
target
;
char
errorname
[
IPT_FUNCTION_MAXNAMELEN
];
};
struct
ipt_error
{
struct
ipt_entry
entry
;
struct
ipt_error_target
target
;
};
static
struct
{
struct
ipt_replace
repl
;
struct
ipt_standard
entries
[
2
];
struct
ipt_error
term
;
}
initial_table
__initdata
=
{
{
"raw"
,
RAW_VALID_HOOKS
,
3
,
sizeof
(
struct
ipt_standard
)
*
2
+
sizeof
(
struct
ipt_error
),
{
[
NF_IP_PRE_ROUTING
]
0
,
[
NF_IP_LOCAL_OUT
]
sizeof
(
struct
ipt_standard
)
},
{
[
NF_IP_PRE_ROUTING
]
0
,
[
NF_IP_LOCAL_OUT
]
sizeof
(
struct
ipt_standard
)
},
0
,
NULL
,
{
}
},
{
/* PRE_ROUTING */
{
{
{
{
0
},
{
0
},
{
0
},
{
0
},
""
,
""
,
{
0
},
{
0
},
0
,
0
,
0
},
0
,
sizeof
(
struct
ipt_entry
),
sizeof
(
struct
ipt_standard
),
0
,
{
0
,
0
},
{
}
},
{
{
{
{
IPT_ALIGN
(
sizeof
(
struct
ipt_standard_target
)),
""
}
},
{
}
},
-
NF_ACCEPT
-
1
}
},
/* LOCAL_OUT */
{
{
{
{
0
},
{
0
},
{
0
},
{
0
},
""
,
""
,
{
0
},
{
0
},
0
,
0
,
0
},
0
,
sizeof
(
struct
ipt_entry
),
sizeof
(
struct
ipt_standard
),
0
,
{
0
,
0
},
{
}
},
{
{
{
{
IPT_ALIGN
(
sizeof
(
struct
ipt_standard_target
)),
""
}
},
{
}
},
-
NF_ACCEPT
-
1
}
}
},
/* ERROR */
{
{
{
{
0
},
{
0
},
{
0
},
{
0
},
""
,
""
,
{
0
},
{
0
},
0
,
0
,
0
},
0
,
sizeof
(
struct
ipt_entry
),
sizeof
(
struct
ipt_error
),
0
,
{
0
,
0
},
{
}
},
{
{
{
{
IPT_ALIGN
(
sizeof
(
struct
ipt_error_target
)),
IPT_ERROR_TARGET
}
},
{
}
},
"ERROR"
}
}
};
static
struct
ipt_table
packet_raw
=
{
.
name
=
"raw"
,
.
table
=
&
initial_table
.
repl
,
.
valid_hooks
=
RAW_VALID_HOOKS
,
.
lock
=
RW_LOCK_UNLOCKED
,
.
me
=
THIS_MODULE
};
/* The work comes in here from netfilter.c. */
static
unsigned
int
ipt_hook
(
unsigned
int
hook
,
struct
sk_buff
**
pskb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
{
return
ipt_do_table
(
pskb
,
hook
,
in
,
out
,
&
packet_raw
,
NULL
);
}
/* 'raw' is the very first table. */
static
struct
nf_hook_ops
ipt_ops
[]
=
{
{
.
hook
=
ipt_hook
,
.
pf
=
PF_INET
,
.
hooknum
=
NF_IP_PRE_ROUTING
,
.
priority
=
NF_IP_PRI_RAW
},
{
.
hook
=
ipt_hook
,
.
pf
=
PF_INET
,
.
hooknum
=
NF_IP_LOCAL_OUT
,
.
priority
=
NF_IP_PRI_RAW
},
};
static
int
__init
init
(
void
)
{
int
ret
;
/* Register table */
ret
=
ipt_register_table
(
&
packet_raw
);
if
(
ret
<
0
)
return
ret
;
/* Register hooks */
ret
=
nf_register_hook
(
&
ipt_ops
[
0
]);
if
(
ret
<
0
)
goto
cleanup_table
;
ret
=
nf_register_hook
(
&
ipt_ops
[
1
]);
if
(
ret
<
0
)
goto
cleanup_hook0
;
return
ret
;
cleanup_hook0:
nf_unregister_hook
(
&
ipt_ops
[
0
]);
cleanup_table:
ipt_unregister_table
(
&
packet_raw
);
return
ret
;
}
static
void
__exit
fini
(
void
)
{
unsigned
int
i
;
for
(
i
=
0
;
i
<
sizeof
(
ipt_ops
)
/
sizeof
(
struct
nf_hook_ops
);
i
++
)
nf_unregister_hook
(
&
ipt_ops
[
i
]);
ipt_unregister_table
(
&
packet_raw
);
}
module_init
(
init
);
module_exit
(
fini
);
MODULE_LICENSE
(
"GPL"
);
net/ipv6/netfilter/Kconfig
View file @
eccf6f14
...
...
@@ -218,5 +218,17 @@ config IP6_NF_TARGET_MARK
To compile it as a module, choose M here. If unsure, say N.
#dep_tristate ' LOG target support' CONFIG_IP6_NF_TARGET_LOG $CONFIG_IP6_NF_IPTABLES
config IP6_NF_RAW
tristate 'raw table support (required for TRACE)'
depends on IP6_NF_IPTABLES
help
This option adds a `raw' table to ip6tables. This table is the very
first in the netfilter framework and hooks in at the PREROUTING
and OUTPUT chains.
If you want to compile it as a module, say M here and read
<file:Documentation/modules.txt>. If unsure, say `N'.
help
endmenu
net/ipv6/netfilter/Makefile
View file @
eccf6f14
...
...
@@ -21,4 +21,5 @@ obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o
obj-$(CONFIG_IP6_NF_TARGET_MARK)
+=
ip6t_MARK.o
obj-$(CONFIG_IP6_NF_QUEUE)
+=
ip6_queue.o
obj-$(CONFIG_IP6_NF_TARGET_LOG)
+=
ip6t_LOG.o
obj-$(CONFIG_IP6_NF_RAW)
+=
ip6table_raw.o
obj-$(CONFIG_IP6_NF_MATCH_HL)
+=
ip6t_hl.o
net/ipv6/netfilter/ip6t_LOG.c
View file @
eccf6f14
...
...
@@ -18,12 +18,17 @@
#include <net/udp.h>
#include <net/tcp.h>
#include <net/ipv6.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
MODULE_AUTHOR
(
"Jan Rekorajski <baggins@pld.org.pl>"
);
MODULE_DESCRIPTION
(
"IP6 tables LOG target module"
);
MODULE_LICENSE
(
"GPL"
);
static
unsigned
int
nflog
=
1
;
MODULE_PARM
(
nflog
,
"i"
);
MODULE_PARM_DESC
(
nflog
,
"register as internal netfilter logging module"
);
struct
in_device
;
#include <net/route.h>
#include <linux/netfilter_ipv6/ip6t_LOG.h>
...
...
@@ -265,40 +270,38 @@ static void dump_packet(const struct ip6t_log_info *info,
}
}
static
unsigned
int
ip6t_log_
target
(
struct
sk_buff
**
pskb
,
unsigned
int
hooknum
,
static
void
ip6t_log_
packet
(
unsigned
int
hooknum
,
const
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
const
void
*
targinfo
,
void
*
userinfo
)
const
struct
ip6t_log_info
*
loginfo
,
const
char
*
level_string
,
const
char
*
prefix
)
{
struct
ipv6hdr
*
ipv6h
=
(
*
pskb
)
->
nh
.
ipv6h
;
const
struct
ip6t_log_info
*
loginfo
=
targinfo
;
char
level_string
[
4
]
=
"< >"
;
struct
ipv6hdr
*
ipv6h
=
skb
->
nh
.
ipv6h
;
level_string
[
1
]
=
'0'
+
(
loginfo
->
level
%
8
);
spin_lock_bh
(
&
log_lock
);
printk
(
level_string
);
printk
(
"%sIN=%s OUT=%s "
,
loginfo
->
prefix
,
prefix
==
NULL
?
loginfo
->
prefix
:
prefix
,
in
?
in
->
name
:
""
,
out
?
out
->
name
:
""
);
if
(
in
&&
!
out
)
{
/* MAC logging for input chain only. */
printk
(
"MAC="
);
if
(
(
*
pskb
)
->
dev
&&
(
*
pskb
)
->
dev
->
hard_header_len
&&
(
*
pskb
)
->
mac
.
raw
!=
(
void
*
)
ipv6h
)
{
if
(
(
*
pskb
)
->
dev
->
type
!=
ARPHRD_SIT
){
if
(
skb
->
dev
&&
skb
->
dev
->
hard_header_len
&&
skb
->
mac
.
raw
!=
(
void
*
)
ipv6h
)
{
if
(
skb
->
dev
->
type
!=
ARPHRD_SIT
){
int
i
;
unsigned
char
*
p
=
(
*
pskb
)
->
mac
.
raw
;
for
(
i
=
0
;
i
<
(
*
pskb
)
->
dev
->
hard_header_len
;
i
++
,
p
++
)
unsigned
char
*
p
=
skb
->
mac
.
raw
;
for
(
i
=
0
;
i
<
skb
->
dev
->
hard_header_len
;
i
++
,
p
++
)
printk
(
"%02x%c"
,
*
p
,
i
==
(
*
pskb
)
->
dev
->
hard_header_len
-
1
i
==
skb
->
dev
->
hard_header_len
-
1
?
' '
:
':'
);
}
else
{
int
i
;
unsigned
char
*
p
=
(
*
pskb
)
->
mac
.
raw
;
if
(
p
-
(
ETH_ALEN
*
2
+
2
)
>
(
*
pskb
)
->
head
){
unsigned
char
*
p
=
skb
->
mac
.
raw
;
if
(
p
-
(
ETH_ALEN
*
2
+
2
)
>
skb
->
head
){
p
-=
(
ETH_ALEN
+
2
);
for
(
i
=
0
;
i
<
(
ETH_ALEN
);
i
++
,
p
++
)
printk
(
"%02x%s"
,
*
p
,
...
...
@@ -309,10 +312,10 @@ ip6t_log_target(struct sk_buff **pskb,
i
==
ETH_ALEN
-
1
?
' '
:
':'
);
}
if
((
(
*
pskb
)
->
dev
->
addr_len
==
4
)
&&
(
*
pskb
)
->
dev
->
hard_header_len
>
20
){
if
((
skb
->
dev
->
addr_len
==
4
)
&&
skb
->
dev
->
hard_header_len
>
20
){
printk
(
"TUNNEL="
);
p
=
(
*
pskb
)
->
mac
.
raw
+
12
;
p
=
skb
->
mac
.
raw
+
12
;
for
(
i
=
0
;
i
<
4
;
i
++
,
p
++
)
printk
(
"%3d%s"
,
*
p
,
i
==
3
?
"->"
:
"."
);
...
...
@@ -328,10 +331,41 @@ ip6t_log_target(struct sk_buff **pskb,
dump_packet
(
loginfo
,
ipv6h
,
1
);
printk
(
"
\n
"
);
spin_unlock_bh
(
&
log_lock
);
}
static
unsigned
int
ip6t_log_target
(
struct
sk_buff
**
pskb
,
unsigned
int
hooknum
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
const
void
*
targinfo
,
void
*
userinfo
)
{
const
struct
ip6t_log_info
*
loginfo
=
targinfo
;
char
level_string
[
4
]
=
"< >"
;
level_string
[
1
]
=
'0'
+
(
loginfo
->
level
%
8
);
ip6t_log_packet
(
hooknum
,
*
pskb
,
in
,
out
,
loginfo
,
level_string
,
NULL
);
return
IP6T_CONTINUE
;
}
static
void
ip6t_logfn
(
unsigned
int
hooknum
,
const
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
const
char
*
prefix
)
{
struct
ip6t_log_info
loginfo
=
{
.
level
=
0
,
.
logflags
=
IP6T_LOG_MASK
,
.
prefix
=
""
};
ip6t_log_packet
(
hooknum
,
skb
,
in
,
out
,
&
loginfo
,
KERN_WARNING
,
prefix
);
}
static
int
ip6t_log_checkentry
(
const
char
*
tablename
,
const
struct
ip6t_entry
*
e
,
void
*
targinfo
,
...
...
@@ -360,20 +394,27 @@ static int ip6t_log_checkentry(const char *tablename,
return
1
;
}
static
struct
ip6t_target
ip6t_log_reg
=
{
{
NULL
,
NULL
},
"LOG"
,
ip6t_log_target
,
ip6t_log_checkentry
,
NULL
,
THIS_MODULE
};
static
struct
ip6t_target
ip6t_log_reg
=
{
.
name
=
"LOG"
,
.
target
=
ip6t_log_target
,
.
checkentry
=
ip6t_log_checkentry
,
.
me
=
THIS_MODULE
,
};
static
int
__init
init
(
void
)
{
if
(
ip6t_register_target
(
&
ip6t_log_reg
))
return
-
EINVAL
;
if
(
nflog
)
nf_log_register
(
PF_INET6
,
&
ip6t_logfn
);
return
0
;
}
static
void
__exit
fini
(
void
)
{
if
(
nflog
)
nf_log_unregister
(
PF_INET6
,
&
ip6t_logfn
);
ip6t_unregister_target
(
&
ip6t_log_reg
);
}
...
...
net/ipv6/netfilter/ip6table_raw.c
0 → 100644
View file @
eccf6f14
/*
* IPv6 raw table, a port of the IPv4 raw table to IPv6
*
* Copyright (C) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
*/
#include <linux/module.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
#define RAW_VALID_HOOKS ((1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_OUT))
#if 0
#define DEBUGP(x, args...) printk(KERN_DEBUG x, ## args)
#else
#define DEBUGP(x, args...)
#endif
/* Standard entry. */
struct
ip6t_standard
{
struct
ip6t_entry
entry
;
struct
ip6t_standard_target
target
;
};
struct
ip6t_error_target
{
struct
ip6t_entry_target
target
;
char
errorname
[
IP6T_FUNCTION_MAXNAMELEN
];
};
struct
ip6t_error
{
struct
ip6t_entry
entry
;
struct
ip6t_error_target
target
;
};
static
struct
{
struct
ip6t_replace
repl
;
struct
ip6t_standard
entries
[
2
];
struct
ip6t_error
term
;
}
initial_table
__initdata
=
{
{
"raw"
,
RAW_VALID_HOOKS
,
3
,
sizeof
(
struct
ip6t_standard
)
*
2
+
sizeof
(
struct
ip6t_error
),
{
[
NF_IP6_PRE_ROUTING
]
0
,
[
NF_IP6_LOCAL_OUT
]
sizeof
(
struct
ip6t_standard
)
},
{
[
NF_IP6_PRE_ROUTING
]
0
,
[
NF_IP6_LOCAL_OUT
]
sizeof
(
struct
ip6t_standard
)
},
0
,
NULL
,
{
}
},
{
/* PRE_ROUTING */
{
{
{
{
{
{
0
}
}
},
{
{
{
0
}
}
},
{
{
{
0
}
}
},
{
{
{
0
}
}
},
""
,
""
,
{
0
},
{
0
},
0
,
0
,
0
},
0
,
sizeof
(
struct
ip6t_entry
),
sizeof
(
struct
ip6t_standard
),
0
,
{
0
,
0
},
{
}
},
{
{
{
{
IP6T_ALIGN
(
sizeof
(
struct
ip6t_standard_target
)),
""
}
},
{
}
},
-
NF_ACCEPT
-
1
}
},
/* LOCAL_OUT */
{
{
{
{
{
{
0
}
}
},
{
{
{
0
}
}
},
{
{
{
0
}
}
},
{
{
{
0
}
}
},
""
,
""
,
{
0
},
{
0
},
0
,
0
,
0
},
0
,
sizeof
(
struct
ip6t_entry
),
sizeof
(
struct
ip6t_standard
),
0
,
{
0
,
0
},
{
}
},
{
{
{
{
IP6T_ALIGN
(
sizeof
(
struct
ip6t_standard_target
)),
""
}
},
{
}
},
-
NF_ACCEPT
-
1
}
},
},
/* ERROR */
{
{
{
{
{
{
0
}
}
},
{
{
{
0
}
}
},
{
{
{
0
}
}
},
{
{
{
0
}
}
},
""
,
""
,
{
0
},
{
0
},
0
,
0
,
0
},
0
,
sizeof
(
struct
ip6t_entry
),
sizeof
(
struct
ip6t_error
),
0
,
{
0
,
0
},
{
}
},
{
{
{
{
IP6T_ALIGN
(
sizeof
(
struct
ip6t_error_target
)),
IP6T_ERROR_TARGET
}
},
{
}
},
"ERROR"
}
}
};
static
struct
ip6t_table
packet_raw
=
{
.
name
=
"raw"
,
.
table
=
&
initial_table
.
repl
,
.
valid_hooks
=
RAW_VALID_HOOKS
,
.
lock
=
RW_LOCK_UNLOCKED
,
.
me
=
THIS_MODULE
};
/* The work comes in here from netfilter.c. */
static
unsigned
int
ip6t_hook
(
unsigned
int
hook
,
struct
sk_buff
**
pskb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
{
return
ip6t_do_table
(
pskb
,
hook
,
in
,
out
,
&
packet_raw
,
NULL
);
}
static
struct
nf_hook_ops
ip6t_ops
[]
=
{
{
.
hook
=
ip6t_hook
,
.
pf
=
PF_INET6
,
.
hooknum
=
NF_IP6_PRE_ROUTING
,
.
priority
=
NF_IP6_PRI_FIRST
},
{
.
hook
=
ip6t_hook
,
.
pf
=
PF_INET6
,
.
hooknum
=
NF_IP6_LOCAL_OUT
,
.
priority
=
NF_IP6_PRI_FIRST
},
};
static
int
__init
init
(
void
)
{
int
ret
;
/* Register table */
ret
=
ip6t_register_table
(
&
packet_raw
);
if
(
ret
<
0
)
return
ret
;
/* Register hooks */
ret
=
nf_register_hook
(
&
ip6t_ops
[
0
]);
if
(
ret
<
0
)
goto
cleanup_table
;
ret
=
nf_register_hook
(
&
ip6t_ops
[
1
]);
if
(
ret
<
0
)
goto
cleanup_hook0
;
return
ret
;
cleanup_hook0:
nf_unregister_hook
(
&
ip6t_ops
[
0
]);
cleanup_table:
ip6t_unregister_table
(
&
packet_raw
);
return
ret
;
}
static
void
__exit
fini
(
void
)
{
unsigned
int
i
;
for
(
i
=
0
;
i
<
sizeof
(
ip6t_ops
)
/
sizeof
(
struct
nf_hook_ops
);
i
++
)
nf_unregister_hook
(
&
ip6t_ops
[
i
]);
ip6t_unregister_table
(
&
packet_raw
);
}
module_init
(
init
);
module_exit
(
fini
);
MODULE_LICENSE
(
"GPL"
);
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment