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
nexedi
linux
Commits
73baeace
Commit
73baeace
authored
May 21, 2003
by
David S. Miller
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://kernel.bkbits.net/acme/net-2.5
into nuts.ninka.net:/home/davem/src/BK/net-2.5
parents
6c17d503
f989c276
Changes
39
Hide whitespace changes
Inline
Side-by-side
Showing
39 changed files
with
700 additions
and
738 deletions
+700
-738
include/linux/netfilter_ipv4/ip_tables.h
include/linux/netfilter_ipv4/ip_tables.h
+16
-13
include/net/transp_v6.h
include/net/transp_v6.h
+0
-1
net/core/dev.c
net/core/dev.c
+0
-7
net/core/dst.c
net/core/dst.c
+1
-0
net/core/dv.c
net/core/dv.c
+2
-1
net/ipv4/netfilter/ip_nat_rule.c
net/ipv4/netfilter/ip_nat_rule.c
+2
-2
net/ipv4/netfilter/ip_tables.c
net/ipv4/netfilter/ip_tables.c
+68
-76
net/ipv4/netfilter/ipt_DSCP.c
net/ipv4/netfilter/ipt_DSCP.c
+14
-20
net/ipv4/netfilter/ipt_ECN.c
net/ipv4/netfilter/ipt_ECN.c
+45
-65
net/ipv4/netfilter/ipt_LOG.c
net/ipv4/netfilter/ipt_LOG.c
+104
-76
net/ipv4/netfilter/ipt_MARK.c
net/ipv4/netfilter/ipt_MARK.c
+1
-1
net/ipv4/netfilter/ipt_MASQUERADE.c
net/ipv4/netfilter/ipt_MASQUERADE.c
+1
-1
net/ipv4/netfilter/ipt_MIRROR.c
net/ipv4/netfilter/ipt_MIRROR.c
+19
-16
net/ipv4/netfilter/ipt_REDIRECT.c
net/ipv4/netfilter/ipt_REDIRECT.c
+1
-1
net/ipv4/netfilter/ipt_REJECT.c
net/ipv4/netfilter/ipt_REJECT.c
+123
-144
net/ipv4/netfilter/ipt_TCPMSS.c
net/ipv4/netfilter/ipt_TCPMSS.c
+3
-10
net/ipv4/netfilter/ipt_TOS.c
net/ipv4/netfilter/ipt_TOS.c
+14
-19
net/ipv4/netfilter/ipt_ULOG.c
net/ipv4/netfilter/ipt_ULOG.c
+4
-3
net/ipv4/netfilter/ipt_ah.c
net/ipv4/netfilter/ipt_ah.c
+9
-9
net/ipv4/netfilter/ipt_conntrack.c
net/ipv4/netfilter/ipt_conntrack.c
+0
-2
net/ipv4/netfilter/ipt_dscp.c
net/ipv4/netfilter/ipt_dscp.c
+1
-2
net/ipv4/netfilter/ipt_ecn.c
net/ipv4/netfilter/ipt_ecn.c
+19
-15
net/ipv4/netfilter/ipt_esp.c
net/ipv4/netfilter/ipt_esp.c
+9
-9
net/ipv4/netfilter/ipt_helper.c
net/ipv4/netfilter/ipt_helper.c
+0
-2
net/ipv4/netfilter/ipt_length.c
net/ipv4/netfilter/ipt_length.c
+0
-2
net/ipv4/netfilter/ipt_limit.c
net/ipv4/netfilter/ipt_limit.c
+0
-2
net/ipv4/netfilter/ipt_mac.c
net/ipv4/netfilter/ipt_mac.c
+0
-2
net/ipv4/netfilter/ipt_mark.c
net/ipv4/netfilter/ipt_mark.c
+0
-2
net/ipv4/netfilter/ipt_multiport.c
net/ipv4/netfilter/ipt_multiport.c
+11
-10
net/ipv4/netfilter/ipt_owner.c
net/ipv4/netfilter/ipt_owner.c
+4
-3
net/ipv4/netfilter/ipt_physdev.c
net/ipv4/netfilter/ipt_physdev.c
+0
-2
net/ipv4/netfilter/ipt_pkttype.c
net/ipv4/netfilter/ipt_pkttype.c
+0
-2
net/ipv4/netfilter/ipt_state.c
net/ipv4/netfilter/ipt_state.c
+0
-2
net/ipv4/netfilter/ipt_tcpmss.c
net/ipv4/netfilter/ipt_tcpmss.c
+26
-19
net/ipv4/netfilter/ipt_tos.c
net/ipv4/netfilter/ipt_tos.c
+1
-4
net/ipv4/netfilter/ipt_ttl.c
net/ipv4/netfilter/ipt_ttl.c
+5
-7
net/ipv4/netfilter/ipt_unclean.c
net/ipv4/netfilter/ipt_unclean.c
+171
-163
net/ipv6/anycast.c
net/ipv6/anycast.c
+21
-20
net/ipv6/ndisc.c
net/ipv6/ndisc.c
+5
-3
No files found.
include/linux/netfilter_ipv4/ip_tables.h
View file @
73baeace
...
@@ -347,13 +347,14 @@ struct ipt_match
...
@@ -347,13 +347,14 @@ struct ipt_match
/* Return true or false: return FALSE and set *hotdrop = 1 to
/* Return true or false: return FALSE and set *hotdrop = 1 to
force immediate packet drop. */
force immediate packet drop. */
/* Arguments changed since 2.4, as this must now handle
non-linear skbs, using skb_copy_bits and
skb_ip_make_writable. */
int
(
*
match
)(
const
struct
sk_buff
*
skb
,
int
(
*
match
)(
const
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
const
void
*
matchinfo
,
int
offset
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
int
*
hotdrop
);
int
*
hotdrop
);
/* Called when user tries to insert an entry of this type. */
/* Called when user tries to insert an entry of this type. */
...
@@ -367,7 +368,7 @@ struct ipt_match
...
@@ -367,7 +368,7 @@ struct ipt_match
/* Called when entry of this type deleted. */
/* Called when entry of this type deleted. */
void
(
*
destroy
)(
void
*
matchinfo
,
unsigned
int
matchinfosize
);
void
(
*
destroy
)(
void
*
matchinfo
,
unsigned
int
matchinfosize
);
/* Set this to THIS_MODULE
if you are a module, otherwise NULL
*/
/* Set this to THIS_MODULE
.
*/
struct
module
*
me
;
struct
module
*
me
;
};
};
...
@@ -378,14 +379,6 @@ struct ipt_target
...
@@ -378,14 +379,6 @@ struct ipt_target
const
char
name
[
IPT_FUNCTION_MAXNAMELEN
];
const
char
name
[
IPT_FUNCTION_MAXNAMELEN
];
/* Returns verdict. */
unsigned
int
(
*
target
)(
struct
sk_buff
**
pskb
,
unsigned
int
hooknum
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
const
void
*
targinfo
,
void
*
userdata
);
/* Called when user tries to insert an entry of this type:
/* Called when user tries to insert an entry of this type:
hook_mask is a bitmask of hooks from which it can be
hook_mask is a bitmask of hooks from which it can be
called. */
called. */
...
@@ -399,7 +392,17 @@ struct ipt_target
...
@@ -399,7 +392,17 @@ struct ipt_target
/* Called when entry of this type deleted. */
/* Called when entry of this type deleted. */
void
(
*
destroy
)(
void
*
targinfo
,
unsigned
int
targinfosize
);
void
(
*
destroy
)(
void
*
targinfo
,
unsigned
int
targinfosize
);
/* Set this to THIS_MODULE if you are a module, otherwise NULL */
/* Returns verdict. Argument order changed since 2.4, as this
must now handle non-linear skbs, using skb_copy_bits and
skb_ip_make_writable. */
unsigned
int
(
*
target
)(
struct
sk_buff
**
pskb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
unsigned
int
hooknum
,
const
void
*
targinfo
,
void
*
userdata
);
/* Set this to THIS_MODULE. */
struct
module
*
me
;
struct
module
*
me
;
};
};
...
@@ -429,7 +432,7 @@ struct ipt_table
...
@@ -429,7 +432,7 @@ struct ipt_table
/* Man behind the curtain... */
/* Man behind the curtain... */
struct
ipt_table_info
*
private
;
struct
ipt_table_info
*
private
;
/* Set t
his to THIS_MODULE if you are a module, otherwise NULL
*/
/* Set t
o THIS_MODULE.
*/
struct
module
*
me
;
struct
module
*
me
;
};
};
...
...
include/net/transp_v6.h
View file @
73baeace
...
@@ -16,7 +16,6 @@ extern struct proto tcpv6_prot;
...
@@ -16,7 +16,6 @@ extern struct proto tcpv6_prot;
struct
flowi
;
struct
flowi
;
/* extention headers */
/* extention headers */
extern
void
ipv6_hopopts_init
(
void
);
extern
void
ipv6_rthdr_init
(
void
);
extern
void
ipv6_rthdr_init
(
void
);
extern
void
ipv6_frag_init
(
void
);
extern
void
ipv6_frag_init
(
void
);
extern
void
ipv6_nodata_init
(
void
);
extern
void
ipv6_nodata_init
(
void
);
...
...
net/core/dev.c
View file @
73baeace
...
@@ -2863,9 +2863,6 @@ int unregister_netdevice(struct net_device *dev)
...
@@ -2863,9 +2863,6 @@ int unregister_netdevice(struct net_device *dev)
extern
void
net_device_init
(
void
);
extern
void
net_device_init
(
void
);
extern
void
ip_auto_config
(
void
);
extern
void
ip_auto_config
(
void
);
#ifdef CONFIG_NET_DIVERT
extern
void
dv_init
(
void
);
#endif
/* CONFIG_NET_DIVERT */
/*
/*
...
@@ -2889,10 +2886,6 @@ static int __init net_dev_init(void)
...
@@ -2889,10 +2886,6 @@ static int __init net_dev_init(void)
for
(
i
=
0
;
i
<
16
;
i
++
)
for
(
i
=
0
;
i
<
16
;
i
++
)
INIT_LIST_HEAD
(
&
ptype_base
[
i
]);
INIT_LIST_HEAD
(
&
ptype_base
[
i
]);
#ifdef CONFIG_NET_DIVERT
dv_init
();
#endif
/* CONFIG_NET_DIVERT */
/*
/*
* Initialise the packet receive queues.
* Initialise the packet receive queues.
*/
*/
...
...
net/core/dst.c
View file @
73baeace
...
@@ -123,6 +123,7 @@ void * dst_alloc(struct dst_ops * ops)
...
@@ -123,6 +123,7 @@ void * dst_alloc(struct dst_ops * ops)
if
(
!
dst
)
if
(
!
dst
)
return
NULL
;
return
NULL
;
memset
(
dst
,
0
,
ops
->
entry_size
);
memset
(
dst
,
0
,
ops
->
entry_size
);
atomic_set
(
&
dst
->
__refcnt
,
0
);
dst
->
ops
=
ops
;
dst
->
ops
=
ops
;
dst
->
lastuse
=
jiffies
;
dst
->
lastuse
=
jiffies
;
dst
->
path
=
dst
;
dst
->
path
=
dst
;
...
...
net/core/dv.c
View file @
73baeace
...
@@ -40,11 +40,12 @@
...
@@ -40,11 +40,12 @@
const
char
sysctl_divert_version
[
32
]
=
"0.46"
;
/* Current version */
const
char
sysctl_divert_version
[
32
]
=
"0.46"
;
/* Current version */
int
__init
dv_init
(
void
)
static
int
__init
dv_init
(
void
)
{
{
printk
(
KERN_INFO
"NET4: Frame Diverter %s
\n
"
,
sysctl_divert_version
);
printk
(
KERN_INFO
"NET4: Frame Diverter %s
\n
"
,
sysctl_divert_version
);
return
0
;
return
0
;
}
}
module_init
(
dv_init
);
/*
/*
* Allocate a divert_blk for a device. This must be an ethernet nic.
* Allocate a divert_blk for a device. This must be an ethernet nic.
...
...
net/ipv4/netfilter/ip_nat_rule.c
View file @
73baeace
...
@@ -111,9 +111,9 @@ static struct ipt_table nat_table = {
...
@@ -111,9 +111,9 @@ static struct ipt_table nat_table = {
/* Source NAT */
/* Source NAT */
static
unsigned
int
ipt_snat_target
(
struct
sk_buff
**
pskb
,
static
unsigned
int
ipt_snat_target
(
struct
sk_buff
**
pskb
,
unsigned
int
hooknum
,
const
struct
net_device
*
in
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
const
struct
net_device
*
out
,
unsigned
int
hooknum
,
const
void
*
targinfo
,
const
void
*
targinfo
,
void
*
userinfo
)
void
*
userinfo
)
{
{
...
@@ -132,9 +132,9 @@ static unsigned int ipt_snat_target(struct sk_buff **pskb,
...
@@ -132,9 +132,9 @@ static unsigned int ipt_snat_target(struct sk_buff **pskb,
}
}
static
unsigned
int
ipt_dnat_target
(
struct
sk_buff
**
pskb
,
static
unsigned
int
ipt_dnat_target
(
struct
sk_buff
**
pskb
,
unsigned
int
hooknum
,
const
struct
net_device
*
in
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
const
struct
net_device
*
out
,
unsigned
int
hooknum
,
const
void
*
targinfo
,
const
void
*
targinfo
,
void
*
userinfo
)
void
*
userinfo
)
{
{
...
...
net/ipv4/netfilter/ip_tables.c
View file @
73baeace
...
@@ -214,9 +214,9 @@ ip_checkentry(const struct ipt_ip *ip)
...
@@ -214,9 +214,9 @@ ip_checkentry(const struct ipt_ip *ip)
static
unsigned
int
static
unsigned
int
ipt_error
(
struct
sk_buff
**
pskb
,
ipt_error
(
struct
sk_buff
**
pskb
,
unsigned
int
hooknum
,
const
struct
net_device
*
in
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
const
struct
net_device
*
out
,
unsigned
int
hooknum
,
const
void
*
targinfo
,
const
void
*
targinfo
,
void
*
userinfo
)
void
*
userinfo
)
{
{
...
@@ -232,13 +232,10 @@ int do_match(struct ipt_entry_match *m,
...
@@ -232,13 +232,10 @@ int do_match(struct ipt_entry_match *m,
const
struct
net_device
*
in
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
const
struct
net_device
*
out
,
int
offset
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
int
*
hotdrop
)
int
*
hotdrop
)
{
{
/* Stop iteration if it doesn't match */
/* Stop iteration if it doesn't match */
if
(
!
m
->
u
.
kernel
.
match
->
match
(
skb
,
in
,
out
,
m
->
data
,
if
(
!
m
->
u
.
kernel
.
match
->
match
(
skb
,
in
,
out
,
m
->
data
,
offset
,
hotdrop
))
offset
,
hdr
,
datalen
,
hotdrop
))
return
1
;
return
1
;
else
else
return
0
;
return
0
;
...
@@ -262,7 +259,6 @@ ipt_do_table(struct sk_buff **pskb,
...
@@ -262,7 +259,6 @@ ipt_do_table(struct sk_buff **pskb,
static
const
char
nulldevname
[
IFNAMSIZ
]
=
{
0
};
static
const
char
nulldevname
[
IFNAMSIZ
]
=
{
0
};
u_int16_t
offset
;
u_int16_t
offset
;
struct
iphdr
*
ip
;
struct
iphdr
*
ip
;
void
*
protohdr
;
u_int16_t
datalen
;
u_int16_t
datalen
;
int
hotdrop
=
0
;
int
hotdrop
=
0
;
/* Initializing verdict to NF_DROP keeps gcc happy. */
/* Initializing verdict to NF_DROP keeps gcc happy. */
...
@@ -271,13 +267,8 @@ ipt_do_table(struct sk_buff **pskb,
...
@@ -271,13 +267,8 @@ ipt_do_table(struct sk_buff **pskb,
void
*
table_base
;
void
*
table_base
;
struct
ipt_entry
*
e
,
*
back
;
struct
ipt_entry
*
e
,
*
back
;
/* FIXME: Push down to extensions --RR */
if
(
skb_is_nonlinear
(
*
pskb
)
&&
skb_linearize
(
*
pskb
,
GFP_ATOMIC
)
!=
0
)
return
NF_DROP
;
/* Initialization */
/* Initialization */
ip
=
(
*
pskb
)
->
nh
.
iph
;
ip
=
(
*
pskb
)
->
nh
.
iph
;
protohdr
=
(
u_int32_t
*
)
ip
+
ip
->
ihl
;
datalen
=
(
*
pskb
)
->
len
-
ip
->
ihl
*
4
;
datalen
=
(
*
pskb
)
->
len
-
ip
->
ihl
*
4
;
indev
=
in
?
in
->
name
:
nulldevname
;
indev
=
in
?
in
->
name
:
nulldevname
;
outdev
=
out
?
out
->
name
:
nulldevname
;
outdev
=
out
?
out
->
name
:
nulldevname
;
...
@@ -320,8 +311,7 @@ ipt_do_table(struct sk_buff **pskb,
...
@@ -320,8 +311,7 @@ ipt_do_table(struct sk_buff **pskb,
if
(
IPT_MATCH_ITERATE
(
e
,
do_match
,
if
(
IPT_MATCH_ITERATE
(
e
,
do_match
,
*
pskb
,
in
,
out
,
*
pskb
,
in
,
out
,
offset
,
protohdr
,
offset
,
&
hotdrop
)
!=
0
)
datalen
,
&
hotdrop
)
!=
0
)
goto
no_match
;
goto
no_match
;
ADD_COUNTER
(
e
->
counters
,
ntohs
(
ip
->
tot_len
),
1
);
ADD_COUNTER
(
e
->
counters
,
ntohs
(
ip
->
tot_len
),
1
);
...
@@ -364,8 +354,8 @@ ipt_do_table(struct sk_buff **pskb,
...
@@ -364,8 +354,8 @@ ipt_do_table(struct sk_buff **pskb,
=
0xeeeeeeec
;
=
0xeeeeeeec
;
#endif
#endif
verdict
=
t
->
u
.
kernel
.
target
->
target
(
pskb
,
verdict
=
t
->
u
.
kernel
.
target
->
target
(
pskb
,
hook
,
in
,
out
,
in
,
out
,
hook
,
t
->
data
,
t
->
data
,
userdata
);
userdata
);
...
@@ -382,7 +372,6 @@ ipt_do_table(struct sk_buff **pskb,
...
@@ -382,7 +372,6 @@ ipt_do_table(struct sk_buff **pskb,
#endif
#endif
/* Target might have changed stuff. */
/* Target might have changed stuff. */
ip
=
(
*
pskb
)
->
nh
.
iph
;
ip
=
(
*
pskb
)
->
nh
.
iph
;
protohdr
=
(
u_int32_t
*
)
ip
+
ip
->
ihl
;
datalen
=
(
*
pskb
)
->
len
-
ip
->
ihl
*
4
;
datalen
=
(
*
pskb
)
->
len
-
ip
->
ihl
*
4
;
if
(
verdict
==
IPT_CONTINUE
)
if
(
verdict
==
IPT_CONTINUE
)
...
@@ -1458,22 +1447,24 @@ port_match(u_int16_t min, u_int16_t max, u_int16_t port, int invert)
...
@@ -1458,22 +1447,24 @@ port_match(u_int16_t min, u_int16_t max, u_int16_t port, int invert)
static
int
static
int
tcp_find_option
(
u_int8_t
option
,
tcp_find_option
(
u_int8_t
option
,
const
struct
tcphdr
*
tcp
,
const
struct
sk_buff
*
skb
,
u
_int16_t
data
len
,
u
nsigned
int
opt
len
,
int
invert
,
int
invert
,
int
*
hotdrop
)
int
*
hotdrop
)
{
{
unsigned
int
i
=
sizeof
(
struct
tcphdr
);
/* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */
const
u_int8_t
*
opt
=
(
u_int8_t
*
)
tcp
;
char
opt
[
60
-
sizeof
(
struct
tcphdr
)];
unsigned
int
i
;
duprintf
(
"tcp_match: finding option
\n
"
);
duprintf
(
"tcp_match: finding option
\n
"
);
/* If we don't have the whole header, drop packet. */
/* If we don't have the whole header, drop packet. */
if
(
tcp
->
doff
*
4
>
datalen
)
{
if
(
skb_copy_bits
(
skb
,
skb
->
nh
.
iph
->
ihl
*
4
+
sizeof
(
struct
tcphdr
),
opt
,
optlen
)
<
0
)
{
*
hotdrop
=
1
;
*
hotdrop
=
1
;
return
0
;
return
0
;
}
}
while
(
i
<
tcp
->
doff
*
4
)
{
for
(
i
=
0
;
i
<
optlen
;
)
{
if
(
opt
[
i
]
==
option
)
return
!
invert
;
if
(
opt
[
i
]
==
option
)
return
!
invert
;
if
(
opt
[
i
]
<
2
)
i
++
;
if
(
opt
[
i
]
<
2
)
i
++
;
else
i
+=
opt
[
i
+
1
]
?:
1
;
else
i
+=
opt
[
i
+
1
]
?:
1
;
...
@@ -1488,25 +1479,29 @@ tcp_match(const struct sk_buff *skb,
...
@@ -1488,25 +1479,29 @@ tcp_match(const struct sk_buff *skb,
const
struct
net_device
*
out
,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
const
void
*
matchinfo
,
int
offset
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
int
*
hotdrop
)
int
*
hotdrop
)
{
{
const
struct
tcphdr
*
tcp
=
hdr
;
struct
tcphdr
tcph
;
const
struct
ipt_tcp
*
tcpinfo
=
matchinfo
;
const
struct
ipt_tcp
*
tcpinfo
=
matchinfo
;
/* To quote Alan:
if
(
offset
)
{
/* To quote Alan:
Don't allow a fragment of TCP 8 bytes in. Nobody normal
causes this. Its a cracker trying to break in by doing a
flag overwrite to pass the direction checks.
*/
if
(
offset
==
1
)
{
Don't allow a fragment of TCP 8 bytes in. Nobody normal
duprintf
(
"Dropping evil TCP offset=1 frag.
\n
"
);
causes this. Its a cracker trying to break in by doing a
*
hotdrop
=
1
;
flag overwrite to pass the direction checks.
*/
if
(
offset
==
1
)
{
duprintf
(
"Dropping evil TCP offset=1 frag.
\n
"
);
*
hotdrop
=
1
;
}
/* Must not be a fragment. */
return
0
;
return
0
;
}
else
if
(
offset
==
0
&&
datalen
<
sizeof
(
struct
tcphdr
))
{
}
#define FWINVTCP(bool,invflg) ((bool) ^ !!(tcpinfo->invflags & invflg))
if
(
skb_copy_bits
(
skb
,
skb
->
nh
.
iph
->
ihl
*
4
,
&
tcph
,
sizeof
(
tcph
))
<
0
)
{
/* We've been asked to examine this packet, and we
/* We've been asked to examine this packet, and we
can't. Hence, no choice but to drop. */
can't. Hence, no choice but to drop. */
duprintf
(
"Dropping evil TCP offset=0 tinygram.
\n
"
);
duprintf
(
"Dropping evil TCP offset=0 tinygram.
\n
"
);
...
@@ -1514,27 +1509,24 @@ tcp_match(const struct sk_buff *skb,
...
@@ -1514,27 +1509,24 @@ tcp_match(const struct sk_buff *skb,
return
0
;
return
0
;
}
}
/* FIXME: Try tcp doff >> packet len against various stacks --RR */
if
(
!
port_match
(
tcpinfo
->
spts
[
0
],
tcpinfo
->
spts
[
1
],
ntohs
(
tcph
.
source
),
#define FWINVTCP(bool,invflg) ((bool) ^ !!(tcpinfo->invflags & invflg))
!!
(
tcpinfo
->
invflags
&
IPT_TCP_INV_SRCPT
)))
return
0
;
/* Must not be a fragment. */
if
(
!
port_match
(
tcpinfo
->
dpts
[
0
],
tcpinfo
->
dpts
[
1
],
return
!
offset
ntohs
(
tcph
.
dest
),
&&
port_match
(
tcpinfo
->
spts
[
0
],
tcpinfo
->
spts
[
1
],
!!
(
tcpinfo
->
invflags
&
IPT_TCP_INV_DSTPT
)))
ntohs
(
tcp
->
source
),
return
0
;
!!
(
tcpinfo
->
invflags
&
IPT_TCP_INV_SRCPT
))
if
(
!
FWINVTCP
((((
unsigned
char
*
)
&
tcph
)[
13
]
&
tcpinfo
->
flg_mask
)
&&
port_match
(
tcpinfo
->
dpts
[
0
],
tcpinfo
->
dpts
[
1
],
==
tcpinfo
->
flg_cmp
,
ntohs
(
tcp
->
dest
),
IPT_TCP_INV_FLAGS
))
!!
(
tcpinfo
->
invflags
&
IPT_TCP_INV_DSTPT
))
return
0
;
&&
FWINVTCP
((((
unsigned
char
*
)
tcp
)[
13
]
if
(
tcpinfo
->
option
&&
&
tcpinfo
->
flg_mask
)
!
tcp_find_option
(
tcpinfo
->
option
,
skb
,
tcph
.
doff
*
4
-
sizeof
(
tcph
),
==
tcpinfo
->
flg_cmp
,
tcpinfo
->
invflags
&
IPT_TCP_INV_OPTION
,
IPT_TCP_INV_FLAGS
)
hotdrop
))
&&
(
!
tcpinfo
->
option
return
0
;
||
tcp_find_option
(
tcpinfo
->
option
,
tcp
,
datalen
,
return
1
;
tcpinfo
->
invflags
&
IPT_TCP_INV_OPTION
,
hotdrop
));
}
}
/* Called when user tries to insert an entry of this type. */
/* Called when user tries to insert an entry of this type. */
...
@@ -1560,14 +1552,16 @@ udp_match(const struct sk_buff *skb,
...
@@ -1560,14 +1552,16 @@ udp_match(const struct sk_buff *skb,
const
struct
net_device
*
out
,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
const
void
*
matchinfo
,
int
offset
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
int
*
hotdrop
)
int
*
hotdrop
)
{
{
const
struct
udphdr
*
udp
=
hdr
;
struct
udphdr
udph
;
const
struct
ipt_udp
*
udpinfo
=
matchinfo
;
const
struct
ipt_udp
*
udpinfo
=
matchinfo
;
if
(
offset
==
0
&&
datalen
<
sizeof
(
struct
udphdr
))
{
/* Must not be a fragment. */
if
(
offset
)
return
0
;
if
(
skb_copy_bits
(
skb
,
skb
->
nh
.
iph
->
ihl
*
4
,
&
udph
,
sizeof
(
udph
))
<
0
)
{
/* We've been asked to examine this packet, and we
/* We've been asked to examine this packet, and we
can't. Hence, no choice but to drop. */
can't. Hence, no choice but to drop. */
duprintf
(
"Dropping evil UDP tinygram.
\n
"
);
duprintf
(
"Dropping evil UDP tinygram.
\n
"
);
...
@@ -1575,13 +1569,11 @@ udp_match(const struct sk_buff *skb,
...
@@ -1575,13 +1569,11 @@ udp_match(const struct sk_buff *skb,
return
0
;
return
0
;
}
}
/* Must not be a fragment. */
return
port_match
(
udpinfo
->
spts
[
0
],
udpinfo
->
spts
[
1
],
return
!
offset
ntohs
(
udph
.
source
),
&&
port_match
(
udpinfo
->
spts
[
0
],
udpinfo
->
spts
[
1
],
!!
(
udpinfo
->
invflags
&
IPT_UDP_INV_SRCPT
))
ntohs
(
udp
->
source
),
!!
(
udpinfo
->
invflags
&
IPT_UDP_INV_SRCPT
))
&&
port_match
(
udpinfo
->
dpts
[
0
],
udpinfo
->
dpts
[
1
],
&&
port_match
(
udpinfo
->
dpts
[
0
],
udpinfo
->
dpts
[
1
],
ntohs
(
udp
->
dest
),
ntohs
(
udp
h
.
dest
),
!!
(
udpinfo
->
invflags
&
IPT_UDP_INV_DSTPT
));
!!
(
udpinfo
->
invflags
&
IPT_UDP_INV_DSTPT
));
}
}
...
@@ -1631,14 +1623,16 @@ icmp_match(const struct sk_buff *skb,
...
@@ -1631,14 +1623,16 @@ icmp_match(const struct sk_buff *skb,
const
struct
net_device
*
out
,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
const
void
*
matchinfo
,
int
offset
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
int
*
hotdrop
)
int
*
hotdrop
)
{
{
const
struct
icmphdr
*
icmp
=
hdr
;
struct
icmphdr
icmph
;
const
struct
ipt_icmp
*
icmpinfo
=
matchinfo
;
const
struct
ipt_icmp
*
icmpinfo
=
matchinfo
;
if
(
offset
==
0
&&
datalen
<
2
)
{
/* Must not be a fragment. */
if
(
offset
)
return
0
;
if
(
skb_copy_bits
(
skb
,
skb
->
nh
.
iph
->
ihl
*
4
,
&
icmph
,
sizeof
(
icmph
))
<
0
){
/* We've been asked to examine this packet, and we
/* We've been asked to examine this packet, and we
can't. Hence, no choice but to drop. */
can't. Hence, no choice but to drop. */
duprintf
(
"Dropping evil ICMP tinygram.
\n
"
);
duprintf
(
"Dropping evil ICMP tinygram.
\n
"
);
...
@@ -1646,13 +1640,11 @@ icmp_match(const struct sk_buff *skb,
...
@@ -1646,13 +1640,11 @@ icmp_match(const struct sk_buff *skb,
return
0
;
return
0
;
}
}
/* Must not be a fragment. */
return
icmp_type_code_match
(
icmpinfo
->
type
,
return
!
offset
icmpinfo
->
code
[
0
],
&&
icmp_type_code_match
(
icmpinfo
->
type
,
icmpinfo
->
code
[
1
],
icmpinfo
->
code
[
0
],
icmph
.
type
,
icmph
.
code
,
icmpinfo
->
code
[
1
],
!!
(
icmpinfo
->
invflags
&
IPT_ICMP_INV
));
icmp
->
type
,
icmp
->
code
,
!!
(
icmpinfo
->
invflags
&
IPT_ICMP_INV
));
}
}
/* Called when user tries to insert an entry of this type. */
/* Called when user tries to insert an entry of this type. */
...
...
net/ipv4/netfilter/ipt_DSCP.c
View file @
73baeace
...
@@ -23,37 +23,31 @@ MODULE_LICENSE("GPL");
...
@@ -23,37 +23,31 @@ MODULE_LICENSE("GPL");
static
unsigned
int
static
unsigned
int
target
(
struct
sk_buff
**
pskb
,
target
(
struct
sk_buff
**
pskb
,
unsigned
int
hooknum
,
const
struct
net_device
*
in
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
const
struct
net_device
*
out
,
unsigned
int
hooknum
,
const
void
*
targinfo
,
const
void
*
targinfo
,
void
*
userinfo
)
void
*
userinfo
)
{
{
struct
iphdr
*
iph
=
(
*
pskb
)
->
nh
.
iph
;
const
struct
ipt_DSCP_info
*
dinfo
=
targinfo
;
const
struct
ipt_DSCP_info
*
dinfo
=
targinfo
;
u_int8_t
sh_dscp
=
((
dinfo
->
dscp
<<
IPT_DSCP_SHIFT
)
&
IPT_DSCP_MASK
);
u_int8_t
sh_dscp
=
((
dinfo
->
dscp
<<
IPT_DSCP_SHIFT
)
&
IPT_DSCP_MASK
);
if
((
iph
->
tos
&
IPT_DSCP_MASK
)
!=
sh_dscp
)
{
if
((
(
*
pskb
)
->
nh
.
iph
->
tos
&
IPT_DSCP_MASK
)
!=
sh_dscp
)
{
u_int16_t
diffs
[
2
];
u_int16_t
diffs
[
2
];
/* raw socket (tcpdump) may have clone of incoming
if
(
!
skb_ip_make_writable
(
pskb
,
sizeof
(
struct
iphdr
)))
* skb: don't disturb it --RR */
return
NF_DROP
;
if
(
skb_cloned
(
*
pskb
)
&&
!
(
*
pskb
)
->
sk
)
{
struct
sk_buff
*
nskb
=
skb_copy
(
*
pskb
,
GFP_ATOMIC
);
diffs
[
0
]
=
htons
((
*
pskb
)
->
nh
.
iph
->
tos
)
^
0xFFFF
;
if
(
!
nskb
)
(
*
pskb
)
->
nh
.
iph
->
tos
=
((
*
pskb
)
->
nh
.
iph
->
tos
&
~
IPT_DSCP_MASK
)
return
NF_DROP
;
|
sh_dscp
;
kfree_skb
(
*
pskb
);
diffs
[
1
]
=
htons
((
*
pskb
)
->
nh
.
iph
->
tos
);
*
pskb
=
nskb
;
(
*
pskb
)
->
nh
.
iph
->
check
iph
=
(
*
pskb
)
->
nh
.
iph
;
=
csum_fold
(
csum_partial
((
char
*
)
diffs
,
}
sizeof
(
diffs
),
(
*
pskb
)
->
nh
.
iph
->
check
diffs
[
0
]
=
htons
(
iph
->
tos
)
^
0xFFFF
;
^
0xFFFF
));
iph
->
tos
=
(
iph
->
tos
&
~
IPT_DSCP_MASK
)
|
sh_dscp
;
diffs
[
1
]
=
htons
(
iph
->
tos
);
iph
->
check
=
csum_fold
(
csum_partial
((
char
*
)
diffs
,
sizeof
(
diffs
),
iph
->
check
^
0xFFFF
));
(
*
pskb
)
->
nfcache
|=
NFC_ALTERED
;
(
*
pskb
)
->
nfcache
|=
NFC_ALTERED
;
}
}
return
IPT_CONTINUE
;
return
IPT_CONTINUE
;
...
...
net/ipv4/netfilter/ipt_ECN.c
View file @
73baeace
...
@@ -19,105 +19,85 @@
...
@@ -19,105 +19,85 @@
MODULE_LICENSE
(
"GPL"
);
MODULE_LICENSE
(
"GPL"
);
/* set ECT codepoint from IP header.
/* set ECT codepoint from IP header.
* return 0 in case there was no ECT codepoint
* return 0 if there was an error. */
* return 1 in case ECT codepoint has been overwritten
* return < 0 in case there was error */
static
inline
int
static
inline
int
set_ect_ip
(
struct
sk_buff
**
pskb
,
struct
iphdr
*
iph
,
set_ect_ip
(
struct
sk_buff
**
pskb
,
const
struct
ipt_ECN_info
*
einfo
)
const
struct
ipt_ECN_info
*
einfo
)
{
{
if
((
iph
->
tos
&
IPT_ECN_IP_MASK
)
if
((
(
*
pskb
)
->
nh
.
iph
->
tos
&
IPT_ECN_IP_MASK
)
!=
(
einfo
->
ip_ect
&
IPT_ECN_IP_MASK
))
{
!=
(
einfo
->
ip_ect
&
IPT_ECN_IP_MASK
))
{
u_int16_t
diffs
[
2
];
u_int16_t
diffs
[
2
];
/* raw socket (tcpdump) may have clone of incoming
if
(
!
skb_ip_make_writable
(
pskb
,
sizeof
(
struct
iphdr
)))
* skb: don't disturb it --RR */
return
0
;
if
(
skb_cloned
(
*
pskb
)
&&
!
(
*
pskb
)
->
sk
)
{
struct
sk_buff
*
nskb
=
skb_copy
(
*
pskb
,
GFP_ATOMIC
);
diffs
[
0
]
=
htons
((
*
pskb
)
->
nh
.
iph
->
tos
)
^
0xFFFF
;
if
(
!
nskb
)
(
*
pskb
)
->
nh
.
iph
->
tos
&=
~
IPT_ECN_IP_MASK
;
return
NF_DROP
;
(
*
pskb
)
->
nh
.
iph
->
tos
|=
(
einfo
->
ip_ect
&
IPT_ECN_IP_MASK
);
kfree_skb
(
*
pskb
);
diffs
[
1
]
=
htons
((
*
pskb
)
->
nh
.
iph
->
tos
);
*
pskb
=
nskb
;
(
*
pskb
)
->
nh
.
iph
->
check
iph
=
(
*
pskb
)
->
nh
.
iph
;
=
csum_fold
(
csum_partial
((
char
*
)
diffs
,
}
sizeof
(
diffs
),
(
*
pskb
)
->
nh
.
iph
->
check
diffs
[
0
]
=
htons
(
iph
->
tos
)
^
0xFFFF
;
^
0xFFFF
));
iph
->
tos
=
iph
->
tos
&
~
IPT_ECN_IP_MASK
;
iph
->
tos
=
iph
->
tos
|
(
einfo
->
ip_ect
&
IPT_ECN_IP_MASK
);
diffs
[
1
]
=
htons
(
iph
->
tos
);
iph
->
check
=
csum_fold
(
csum_partial
((
char
*
)
diffs
,
sizeof
(
diffs
),
iph
->
check
^
0xFFFF
));
(
*
pskb
)
->
nfcache
|=
NFC_ALTERED
;
(
*
pskb
)
->
nfcache
|=
NFC_ALTERED
;
return
1
;
}
}
return
0
;
return
1
;
}
}
/* Return 0 if there was an error. */
static
inline
int
static
inline
int
set_ect_tcp
(
struct
sk_buff
**
pskb
,
struct
iphdr
*
iph
,
set_ect_tcp
(
struct
sk_buff
**
pskb
,
const
struct
ipt_ECN_info
*
einfo
)
const
struct
ipt_ECN_info
*
einfo
)
{
{
struct
tcphdr
tcph
;
struct
tcphdr
*
tcph
=
(
void
*
)
iph
+
iph
->
ihl
*
4
;
u_int16_t
*
tcpflags
=
(
u_int16_t
*
)
tcph
+
6
;
u_int16_t
diffs
[
2
];
u_int16_t
diffs
[
2
];
/* raw socket (tcpdump) may have clone of incoming
/* Not enought header? */
* skb: don't disturb it --RR */
if
(
skb_copy_bits
(
*
pskb
,
(
*
pskb
)
->
nh
.
iph
->
ihl
*
4
,
&
tcph
,
sizeof
(
tcph
))
if
(
skb_cloned
(
*
pskb
)
&&
!
(
*
pskb
)
->
sk
)
{
<
0
)
struct
sk_buff
*
nskb
=
skb_copy
(
*
pskb
,
GFP_ATOMIC
);
return
0
;
if
(
!
nskb
)
return
NF_DROP
;
kfree_skb
(
*
pskb
);
*
pskb
=
nskb
;
iph
=
(
*
pskb
)
->
nh
.
iph
;
}
diffs
[
0
]
=
*
tcpflags
;
diffs
[
0
]
=
((
u_int16_t
*
)
&
tcph
)[
6
];
if
(
einfo
->
operation
&
IPT_ECN_OP_SET_ECE
)
tcph
.
ece
=
einfo
->
proto
.
tcp
.
ece
;
if
(
einfo
->
operation
&
IPT_ECN_OP_SET_ECE
if
(
einfo
->
operation
&
IPT_ECN_OP_SET_CWR
)
&&
tcph
->
ece
!=
einfo
->
proto
.
tcp
.
ece
)
{
tcph
.
cwr
=
einfo
->
proto
.
tcp
.
cwr
;
tcph
->
ece
=
einfo
->
proto
.
tcp
.
ece
;
diffs
[
1
]
=
((
u_int16_t
*
)
&
tcph
)[
6
];
}
if
(
einfo
->
operation
&
IPT_ECN_OP_SET_CWR
/* Only mangle if it's changed. */
&&
tcph
->
cwr
!=
einfo
->
proto
.
tcp
.
cwr
)
{
if
(
diffs
[
0
]
!=
diffs
[
1
])
{
tcph
->
cwr
=
einfo
->
proto
.
tcp
.
cwr
;
}
if
(
diffs
[
0
]
!=
*
tcpflags
)
{
diffs
[
0
]
=
diffs
[
0
]
^
0xFFFF
;
diffs
[
0
]
=
diffs
[
0
]
^
0xFFFF
;
diffs
[
1
]
=
*
tcpflags
;
if
(
!
skb_ip_make_writable
(
pskb
,
tcph
->
check
=
csum_fold
(
csum_partial
((
char
*
)
diffs
,
(
*
pskb
)
->
nh
.
iph
->
ihl
*
4
+
sizeof
(
tcph
)))
return
0
;
tcph
.
check
=
csum_fold
(
csum_partial
((
char
*
)
diffs
,
sizeof
(
diffs
),
sizeof
(
diffs
),
tcph
->
check
^
0xFFFF
));
tcph
.
check
^
0xFFFF
));
memcpy
((
*
pskb
)
->
data
+
(
*
pskb
)
->
nh
.
iph
->
ihl
*
4
,
&
tcph
,
sizeof
(
tcph
));
(
*
pskb
)
->
nfcache
|=
NFC_ALTERED
;
(
*
pskb
)
->
nfcache
|=
NFC_ALTERED
;
return
1
;
}
}
return
1
;
return
0
;
}
}
static
unsigned
int
static
unsigned
int
target
(
struct
sk_buff
**
pskb
,
target
(
struct
sk_buff
**
pskb
,
unsigned
int
hooknum
,
const
struct
net_device
*
in
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
const
struct
net_device
*
out
,
unsigned
int
hooknum
,
const
void
*
targinfo
,
const
void
*
targinfo
,
void
*
userinfo
)
void
*
userinfo
)
{
{
struct
iphdr
*
iph
=
(
*
pskb
)
->
nh
.
iph
;
const
struct
ipt_ECN_info
*
einfo
=
targinfo
;
const
struct
ipt_ECN_info
*
einfo
=
targinfo
;
if
(
einfo
->
operation
&
IPT_ECN_OP_SET_IP
)
if
(
einfo
->
operation
&
IPT_ECN_OP_SET_IP
)
set_ect_ip
(
pskb
,
iph
,
einfo
);
if
(
!
set_ect_ip
(
pskb
,
einfo
))
return
NF_DROP
;
if
(
einfo
->
operation
&
(
IPT_ECN_OP_SET_ECE
|
IPT_ECN_OP_SET_CWR
)
if
(
einfo
->
operation
&
(
IPT_ECN_OP_SET_ECE
|
IPT_ECN_OP_SET_CWR
)
&&
iph
->
protocol
==
IPPROTO_TCP
)
&&
(
*
pskb
)
->
nh
.
iph
->
protocol
==
IPPROTO_TCP
)
set_ect_tcp
(
pskb
,
iph
,
einfo
);
if
(
!
set_ect_tcp
(
pskb
,
einfo
))
return
NF_DROP
;
return
IPT_CONTINUE
;
return
IPT_CONTINUE
;
}
}
...
...
net/ipv4/netfilter/ipt_LOG.c
View file @
73baeace
...
@@ -29,127 +29,151 @@ static spinlock_t log_lock = SPIN_LOCK_UNLOCKED;
...
@@ -29,127 +29,151 @@ static spinlock_t log_lock = SPIN_LOCK_UNLOCKED;
/* One level of recursion won't kill us */
/* One level of recursion won't kill us */
static
void
dump_packet
(
const
struct
ipt_log_info
*
info
,
static
void
dump_packet
(
const
struct
ipt_log_info
*
info
,
struct
iphdr
*
iph
,
unsigned
int
len
,
int
recurse
)
const
struct
sk_buff
*
skb
,
unsigned
int
iphoff
)
{
{
void
*
protoh
=
(
u_int32_t
*
)
iph
+
iph
->
ihl
;
struct
iphdr
iph
;
unsigned
int
datalen
=
len
-
iph
->
ihl
*
4
;
if
(
skb_copy_bits
(
skb
,
iphoff
,
&
iph
,
sizeof
(
iph
))
<
0
)
{
printk
(
"TRUNCATED"
);
return
;
}
/* Important fields:
/* Important fields:
* TOS, len, DF/MF, fragment offset, TTL, src, dst, options. */
* TOS, len, DF/MF, fragment offset, TTL, src, dst, options. */
/* Max length: 40 "SRC=255.255.255.255 DST=255.255.255.255 " */
/* Max length: 40 "SRC=255.255.255.255 DST=255.255.255.255 " */
printk
(
"SRC=%u.%u.%u.%u DST=%u.%u.%u.%u "
,
printk
(
"SRC=%u.%u.%u.%u DST=%u.%u.%u.%u "
,
NIPQUAD
(
iph
->
saddr
),
NIPQUAD
(
iph
->
daddr
));
NIPQUAD
(
iph
.
saddr
),
NIPQUAD
(
iph
.
daddr
));
/* Max length: 46 "LEN=65535 TOS=0xFF PREC=0xFF TTL=255 ID=65535 " */
/* Max length: 46 "LEN=65535 TOS=0xFF PREC=0xFF TTL=255 ID=65535 " */
printk
(
"LEN=%u TOS=0x%02X PREC=0x%02X TTL=%u ID=%u "
,
printk
(
"LEN=%u TOS=0x%02X PREC=0x%02X TTL=%u ID=%u "
,
ntohs
(
iph
->
tot_len
),
iph
->
tos
&
IPTOS_TOS_MASK
,
ntohs
(
iph
.
tot_len
),
iph
.
tos
&
IPTOS_TOS_MASK
,
iph
->
tos
&
IPTOS_PREC_MASK
,
iph
->
ttl
,
ntohs
(
iph
->
id
));
iph
.
tos
&
IPTOS_PREC_MASK
,
iph
.
ttl
,
ntohs
(
iph
.
id
));
/* Max length: 6 "CE DF MF " */
/* Max length: 6 "CE DF MF " */
if
(
ntohs
(
iph
->
frag_off
)
&
IP_CE
)
if
(
ntohs
(
iph
.
frag_off
)
&
IP_CE
)
printk
(
"CE "
);
printk
(
"CE "
);
if
(
ntohs
(
iph
->
frag_off
)
&
IP_DF
)
if
(
ntohs
(
iph
.
frag_off
)
&
IP_DF
)
printk
(
"DF "
);
printk
(
"DF "
);
if
(
ntohs
(
iph
->
frag_off
)
&
IP_MF
)
if
(
ntohs
(
iph
.
frag_off
)
&
IP_MF
)
printk
(
"MF "
);
printk
(
"MF "
);
/* Max length: 11 "FRAG:65535 " */
/* Max length: 11 "FRAG:65535 " */
if
(
ntohs
(
iph
->
frag_off
)
&
IP_OFFSET
)
if
(
ntohs
(
iph
.
frag_off
)
&
IP_OFFSET
)
printk
(
"FRAG:%u "
,
ntohs
(
iph
->
frag_off
)
&
IP_OFFSET
);
printk
(
"FRAG:%u "
,
ntohs
(
iph
.
frag_off
)
&
IP_OFFSET
);
if
((
info
->
logflags
&
IPT_LOG_IPOPT
)
if
((
info
->
logflags
&
IPT_LOG_IPOPT
)
&&
iph
->
ihl
*
4
!=
sizeof
(
struct
iphdr
))
{
&&
iph
.
ihl
*
4
!=
sizeof
(
struct
iphdr
))
{
unsigned
int
i
;
unsigned
char
opt
[
4
*
15
-
sizeof
(
struct
iphdr
)];
unsigned
int
i
,
optsize
;
optsize
=
iph
.
ihl
*
4
-
sizeof
(
struct
iphdr
);
if
(
skb_copy_bits
(
skb
,
iphoff
+
sizeof
(
iph
),
opt
,
optsize
)
<
0
)
{
printk
(
"TRUNCATED"
);
return
;
}
/* Max length: 127 "OPT (" 15*4*2chars ") " */
/* Max length: 127 "OPT (" 15*4*2chars ") " */
printk
(
"OPT ("
);
printk
(
"OPT ("
);
for
(
i
=
sizeof
(
struct
iphdr
);
i
<
iph
->
ihl
*
4
;
i
++
)
for
(
i
=
0
;
i
<
optsize
;
i
++
)
printk
(
"%02X"
,
((
u_int8_t
*
)
iph
)
[
i
]);
printk
(
"%02X"
,
opt
[
i
]);
printk
(
") "
);
printk
(
") "
);
}
}
switch
(
iph
->
protocol
)
{
switch
(
iph
.
protocol
)
{
case
IPPROTO_TCP
:
{
case
IPPROTO_TCP
:
{
struct
tcphdr
*
tcph
=
proto
h
;
struct
tcphdr
tcp
h
;
/* Max length: 10 "PROTO=TCP " */
/* Max length: 10 "PROTO=TCP " */
printk
(
"PROTO=TCP "
);
printk
(
"PROTO=TCP "
);
if
(
ntohs
(
iph
->
frag_off
)
&
IP_OFFSET
)
if
(
ntohs
(
iph
.
frag_off
)
&
IP_OFFSET
)
break
;
break
;
/* Max length: 25 "INCOMPLETE [65535 bytes] " */
/* Max length: 25 "INCOMPLETE [65535 bytes] " */
if
(
datalen
<
sizeof
(
*
tcph
))
{
if
(
skb_copy_bits
(
skb
,
iphoff
+
iph
.
ihl
*
4
,
&
tcph
,
sizeof
(
tcph
))
printk
(
"INCOMPLETE [%u bytes] "
,
datalen
);
<
0
)
{
printk
(
"INCOMPLETE [%u bytes] "
,
skb
->
len
-
iphoff
-
iph
.
ihl
*
4
);
break
;
break
;
}
}
/* Max length: 20 "SPT=65535 DPT=65535 " */
/* Max length: 20 "SPT=65535 DPT=65535 " */
printk
(
"SPT=%u DPT=%u "
,
printk
(
"SPT=%u DPT=%u "
,
ntohs
(
tcph
->
source
),
ntohs
(
tcph
->
dest
));
ntohs
(
tcph
.
source
),
ntohs
(
tcph
.
dest
));
/* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */
/* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */
if
(
info
->
logflags
&
IPT_LOG_TCPSEQ
)
if
(
info
->
logflags
&
IPT_LOG_TCPSEQ
)
printk
(
"SEQ=%u ACK=%u "
,
printk
(
"SEQ=%u ACK=%u "
,
ntohl
(
tcph
->
seq
),
ntohl
(
tcph
->
ack_seq
));
ntohl
(
tcph
.
seq
),
ntohl
(
tcph
.
ack_seq
));
/* Max length: 13 "WINDOW=65535 " */
/* Max length: 13 "WINDOW=65535 " */
printk
(
"WINDOW=%u "
,
ntohs
(
tcph
->
window
));
printk
(
"WINDOW=%u "
,
ntohs
(
tcph
.
window
));
/* Max length: 9 "RES=0x3F " */
/* Max length: 9 "RES=0x3F " */
printk
(
"RES=0x%02x "
,
(
u
_int8_t
)(
ntohl
(
tcp_flag_word
(
tcph
)
&
TCP_RESERVED_BITS
)
>>
22
));
printk
(
"RES=0x%02x "
,
(
u
8
)(
ntohl
(
tcp_flag_word
(
&
tcph
)
&
TCP_RESERVED_BITS
)
>>
22
));
/* Max length: 32 "CWR ECE URG ACK PSH RST SYN FIN " */
/* Max length: 32 "CWR ECE URG ACK PSH RST SYN FIN " */
if
(
tcph
->
cwr
)
if
(
tcph
.
cwr
)
printk
(
"CWR "
);
printk
(
"CWR "
);
if
(
tcph
->
ece
)
if
(
tcph
.
ece
)
printk
(
"ECE "
);
printk
(
"ECE "
);
if
(
tcph
->
urg
)
if
(
tcph
.
urg
)
printk
(
"URG "
);
printk
(
"URG "
);
if
(
tcph
->
ack
)
if
(
tcph
.
ack
)
printk
(
"ACK "
);
printk
(
"ACK "
);
if
(
tcph
->
psh
)
if
(
tcph
.
psh
)
printk
(
"PSH "
);
printk
(
"PSH "
);
if
(
tcph
->
rst
)
if
(
tcph
.
rst
)
printk
(
"RST "
);
printk
(
"RST "
);
if
(
tcph
->
syn
)
if
(
tcph
.
syn
)
printk
(
"SYN "
);
printk
(
"SYN "
);
if
(
tcph
->
fin
)
if
(
tcph
.
fin
)
printk
(
"FIN "
);
printk
(
"FIN "
);
/* Max length: 11 "URGP=65535 " */
/* Max length: 11 "URGP=65535 " */
printk
(
"URGP=%u "
,
ntohs
(
tcph
->
urg_ptr
));
printk
(
"URGP=%u "
,
ntohs
(
tcph
.
urg_ptr
));
if
((
info
->
logflags
&
IPT_LOG_TCPOPT
)
if
((
info
->
logflags
&
IPT_LOG_TCPOPT
)
&&
tcph
->
doff
*
4
!=
sizeof
(
struct
tcphdr
))
{
&&
tcph
.
doff
*
4
!=
sizeof
(
struct
tcphdr
))
{
unsigned
int
i
;
unsigned
char
opt
[
4
*
15
-
sizeof
(
struct
tcphdr
)];
unsigned
int
i
,
optsize
;
optsize
=
tcph
.
doff
*
4
-
sizeof
(
struct
tcphdr
);
if
(
skb_copy_bits
(
skb
,
iphoff
+
iph
.
ihl
*
4
+
sizeof
(
tcph
),
opt
,
optsize
)
<
0
)
{
printk
(
"TRUNCATED"
);
return
;
}
/* Max length: 127 "OPT (" 15*4*2chars ") " */
/* Max length: 127 "OPT (" 15*4*2chars ") " */
printk
(
"OPT ("
);
printk
(
"OPT ("
);
for
(
i
=
sizeof
(
struct
tcphdr
);
i
<
tcph
->
doff
*
4
;
i
++
)
for
(
i
=
0
;
i
<
optsize
;
i
++
)
printk
(
"%02X"
,
((
u_int8_t
*
)
tcph
)
[
i
]);
printk
(
"%02X"
,
opt
[
i
]);
printk
(
") "
);
printk
(
") "
);
}
}
break
;
break
;
}
}
case
IPPROTO_UDP
:
{
case
IPPROTO_UDP
:
{
struct
udphdr
*
udph
=
proto
h
;
struct
udphdr
udp
h
;
/* Max length: 10 "PROTO=UDP " */
/* Max length: 10 "PROTO=UDP " */
printk
(
"PROTO=UDP "
);
printk
(
"PROTO=UDP "
);
if
(
ntohs
(
iph
->
frag_off
)
&
IP_OFFSET
)
if
(
ntohs
(
iph
.
frag_off
)
&
IP_OFFSET
)
break
;
break
;
/* Max length: 25 "INCOMPLETE [65535 bytes] " */
/* Max length: 25 "INCOMPLETE [65535 bytes] " */
if
(
datalen
<
sizeof
(
*
udph
))
{
if
(
skb_copy_bits
(
skb
,
iphoff
+
iph
.
ihl
*
4
,
&
udph
,
sizeof
(
udph
))
printk
(
"INCOMPLETE [%u bytes] "
,
datalen
);
<
0
)
{
printk
(
"INCOMPLETE [%u bytes] "
,
skb
->
len
-
iphoff
-
iph
.
ihl
*
4
);
break
;
break
;
}
}
/* Max length: 20 "SPT=65535 DPT=65535 " */
/* Max length: 20 "SPT=65535 DPT=65535 " */
printk
(
"SPT=%u DPT=%u LEN=%u "
,
printk
(
"SPT=%u DPT=%u LEN=%u "
,
ntohs
(
udph
->
source
),
ntohs
(
udph
->
dest
),
ntohs
(
udph
.
source
),
ntohs
(
udph
.
dest
),
ntohs
(
udph
->
len
));
ntohs
(
udph
.
len
));
break
;
break
;
}
}
case
IPPROTO_ICMP
:
{
case
IPPROTO_ICMP
:
{
struct
icmphdr
*
icmph
=
proto
h
;
struct
icmphdr
icmp
h
;
static
size_t
required_len
[
NR_ICMP_TYPES
+
1
]
static
size_t
required_len
[
NR_ICMP_TYPES
+
1
]
=
{
[
ICMP_ECHOREPLY
]
=
4
,
=
{
[
ICMP_ECHOREPLY
]
=
4
,
[
ICMP_DEST_UNREACH
]
[
ICMP_DEST_UNREACH
]
...
@@ -171,89 +195,93 @@ static void dump_packet(const struct ipt_log_info *info,
...
@@ -171,89 +195,93 @@ static void dump_packet(const struct ipt_log_info *info,
/* Max length: 11 "PROTO=ICMP " */
/* Max length: 11 "PROTO=ICMP " */
printk
(
"PROTO=ICMP "
);
printk
(
"PROTO=ICMP "
);
if
(
ntohs
(
iph
->
frag_off
)
&
IP_OFFSET
)
if
(
ntohs
(
iph
.
frag_off
)
&
IP_OFFSET
)
break
;
break
;
/* Max length: 25 "INCOMPLETE [65535 bytes] " */
/* Max length: 25 "INCOMPLETE [65535 bytes] " */
if
(
datalen
<
4
)
{
if
(
skb_copy_bits
(
skb
,
iphoff
+
iph
.
ihl
*
4
,
&
icmph
,
sizeof
(
icmph
))
printk
(
"INCOMPLETE [%u bytes] "
,
datalen
);
<
0
)
{
printk
(
"INCOMPLETE [%u bytes] "
,
skb
->
len
-
iphoff
-
iph
.
ihl
*
4
);
break
;
break
;
}
}
/* Max length: 18 "TYPE=255 CODE=255 " */
/* Max length: 18 "TYPE=255 CODE=255 " */
printk
(
"TYPE=%u CODE=%u "
,
icmph
->
type
,
icmph
->
code
);
printk
(
"TYPE=%u CODE=%u "
,
icmph
.
type
,
icmph
.
code
);
/* Max length: 25 "INCOMPLETE [65535 bytes] " */
/* Max length: 25 "INCOMPLETE [65535 bytes] " */
if
(
icmph
->
type
<=
NR_ICMP_TYPES
if
(
icmph
.
type
<=
NR_ICMP_TYPES
&&
required_len
[
icmph
->
type
]
&&
required_len
[
icmph
.
type
]
&&
datalen
<
required_len
[
icmph
->
type
])
{
&&
skb
->
len
-
iphoff
-
iph
.
ihl
*
4
<
required_len
[
icmph
.
type
])
{
printk
(
"INCOMPLETE [%u bytes] "
,
datalen
);
printk
(
"INCOMPLETE [%u bytes] "
,
skb
->
len
-
iphoff
-
iph
.
ihl
*
4
);
break
;
break
;
}
}
switch
(
icmph
->
type
)
{
switch
(
icmph
.
type
)
{
case
ICMP_ECHOREPLY
:
case
ICMP_ECHOREPLY
:
case
ICMP_ECHO
:
case
ICMP_ECHO
:
/* Max length: 19 "ID=65535 SEQ=65535 " */
/* Max length: 19 "ID=65535 SEQ=65535 " */
printk
(
"ID=%u SEQ=%u "
,
printk
(
"ID=%u SEQ=%u "
,
ntohs
(
icmph
->
un
.
echo
.
id
),
ntohs
(
icmph
.
un
.
echo
.
id
),
ntohs
(
icmph
->
un
.
echo
.
sequence
));
ntohs
(
icmph
.
un
.
echo
.
sequence
));
break
;
break
;
case
ICMP_PARAMETERPROB
:
case
ICMP_PARAMETERPROB
:
/* Max length: 14 "PARAMETER=255 " */
/* Max length: 14 "PARAMETER=255 " */
printk
(
"PARAMETER=%u "
,
printk
(
"PARAMETER=%u "
,
ntohl
(
icmph
->
un
.
gateway
)
>>
24
);
ntohl
(
icmph
.
un
.
gateway
)
>>
24
);
break
;
break
;
case
ICMP_REDIRECT
:
case
ICMP_REDIRECT
:
/* Max length: 24 "GATEWAY=255.255.255.255 " */
/* Max length: 24 "GATEWAY=255.255.255.255 " */
printk
(
"GATEWAY=%u.%u.%u.%u "
,
NIPQUAD
(
icmph
->
un
.
gateway
));
printk
(
"GATEWAY=%u.%u.%u.%u "
,
NIPQUAD
(
icmph
.
un
.
gateway
));
/* Fall through */
/* Fall through */
case
ICMP_DEST_UNREACH
:
case
ICMP_DEST_UNREACH
:
case
ICMP_SOURCE_QUENCH
:
case
ICMP_SOURCE_QUENCH
:
case
ICMP_TIME_EXCEEDED
:
case
ICMP_TIME_EXCEEDED
:
/* Max length: 3+maxlen */
/* Max length: 3+maxlen */
if
(
recurse
)
{
if
(
!
iphoff
)
{
/* Only recurse once. */
printk
(
"["
);
printk
(
"["
);
dump_packet
(
info
,
dump_packet
(
info
,
skb
,
(
struct
iphdr
*
)(
icmph
+
1
),
iphoff
+
iph
.
ihl
*
4
+
sizeof
(
icmph
));
datalen
-
sizeof
(
struct
icmphdr
),
0
);
printk
(
"] "
);
printk
(
"] "
);
}
}
/* Max length: 10 "MTU=65535 " */
/* Max length: 10 "MTU=65535 " */
if
(
icmph
->
type
==
ICMP_DEST_UNREACH
if
(
icmph
.
type
==
ICMP_DEST_UNREACH
&&
icmph
->
code
==
ICMP_FRAG_NEEDED
)
&&
icmph
.
code
==
ICMP_FRAG_NEEDED
)
printk
(
"MTU=%u "
,
ntohs
(
icmph
->
un
.
frag
.
mtu
));
printk
(
"MTU=%u "
,
ntohs
(
icmph
.
un
.
frag
.
mtu
));
}
}
break
;
break
;
}
}
/* Max Length */
/* Max Length */
case
IPPROTO_AH
:
case
IPPROTO_AH
:
case
IPPROTO_ESP
:
{
case
IPPROTO_ESP
:
{
struct
esphdr
*
esph
=
proto
h
;
struct
esphdr
esp
h
;
int
esp
=
(
iph
->
protocol
==
IPPROTO_ESP
);
int
esp
=
(
iph
.
protocol
==
IPPROTO_ESP
);
/* Max length: 10 "PROTO=ESP " */
/* Max length: 10 "PROTO=ESP " */
printk
(
"PROTO=%s "
,
esp
?
"ESP"
:
"AH"
);
printk
(
"PROTO=%s "
,
esp
?
"ESP"
:
"AH"
);
if
(
ntohs
(
iph
->
frag_off
)
&
IP_OFFSET
)
if
(
ntohs
(
iph
.
frag_off
)
&
IP_OFFSET
)
break
;
break
;
/* Max length: 25 "INCOMPLETE [65535 bytes] " */
/* Max length: 25 "INCOMPLETE [65535 bytes] " */
if
(
datalen
<
sizeof
(
*
esph
))
{
if
(
skb_copy_bits
(
skb
,
iphoff
+
iph
.
ihl
*
4
,
&
esph
,
sizeof
(
esph
))
printk
(
"INCOMPLETE [%u bytes] "
,
datalen
);
<
0
)
{
printk
(
"INCOMPLETE [%u bytes] "
,
skb
->
len
-
iphoff
-
iph
.
ihl
*
4
);
break
;
break
;
}
}
/* Length: 15 "SPI=0xF1234567 " */
/* Length: 15 "SPI=0xF1234567 " */
printk
(
"SPI=0x%x "
,
ntohl
(
esph
->
spi
)
);
printk
(
"SPI=0x%x "
,
ntohl
(
esph
.
spi
)
);
break
;
break
;
}
}
/* Max length: 10 "PROTO 255 " */
/* Max length: 10 "PROTO 255 " */
default:
default:
printk
(
"PROTO=%u "
,
iph
->
protocol
);
printk
(
"PROTO=%u "
,
iph
.
protocol
);
}
}
/* Proto Max log string length */
/* Proto Max log string length */
...
@@ -272,13 +300,12 @@ static void dump_packet(const struct ipt_log_info *info,
...
@@ -272,13 +300,12 @@ static void dump_packet(const struct ipt_log_info *info,
static
unsigned
int
static
unsigned
int
ipt_log_target
(
struct
sk_buff
**
pskb
,
ipt_log_target
(
struct
sk_buff
**
pskb
,
unsigned
int
hooknum
,
const
struct
net_device
*
in
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
const
struct
net_device
*
out
,
unsigned
int
hooknum
,
const
void
*
targinfo
,
const
void
*
targinfo
,
void
*
userinfo
)
void
*
userinfo
)
{
{
struct
iphdr
*
iph
=
(
*
pskb
)
->
nh
.
iph
;
const
struct
ipt_log_info
*
loginfo
=
targinfo
;
const
struct
ipt_log_info
*
loginfo
=
targinfo
;
char
level_string
[
4
]
=
"< >"
;
char
level_string
[
4
]
=
"< >"
;
...
@@ -304,7 +331,8 @@ ipt_log_target(struct sk_buff **pskb,
...
@@ -304,7 +331,8 @@ ipt_log_target(struct sk_buff **pskb,
if
(
in
&&
!
out
)
{
if
(
in
&&
!
out
)
{
/* MAC logging for input chain only. */
/* MAC logging for input chain only. */
printk
(
"MAC="
);
printk
(
"MAC="
);
if
((
*
pskb
)
->
dev
&&
(
*
pskb
)
->
dev
->
hard_header_len
&&
(
*
pskb
)
->
mac
.
raw
!=
(
void
*
)
iph
)
{
if
((
*
pskb
)
->
dev
&&
(
*
pskb
)
->
dev
->
hard_header_len
&&
(
*
pskb
)
->
mac
.
raw
!=
(
void
*
)(
*
pskb
)
->
nh
.
iph
)
{
int
i
;
int
i
;
unsigned
char
*
p
=
(
*
pskb
)
->
mac
.
raw
;
unsigned
char
*
p
=
(
*
pskb
)
->
mac
.
raw
;
for
(
i
=
0
;
i
<
(
*
pskb
)
->
dev
->
hard_header_len
;
i
++
,
p
++
)
for
(
i
=
0
;
i
<
(
*
pskb
)
->
dev
->
hard_header_len
;
i
++
,
p
++
)
...
@@ -315,7 +343,7 @@ ipt_log_target(struct sk_buff **pskb,
...
@@ -315,7 +343,7 @@ ipt_log_target(struct sk_buff **pskb,
printk
(
" "
);
printk
(
" "
);
}
}
dump_packet
(
loginfo
,
iph
,
(
*
pskb
)
->
len
,
1
);
dump_packet
(
loginfo
,
*
pskb
,
0
);
printk
(
"
\n
"
);
printk
(
"
\n
"
);
spin_unlock_bh
(
&
log_lock
);
spin_unlock_bh
(
&
log_lock
);
...
...
net/ipv4/netfilter/ipt_MARK.c
View file @
73baeace
...
@@ -9,9 +9,9 @@
...
@@ -9,9 +9,9 @@
static
unsigned
int
static
unsigned
int
target
(
struct
sk_buff
**
pskb
,
target
(
struct
sk_buff
**
pskb
,
unsigned
int
hooknum
,
const
struct
net_device
*
in
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
const
struct
net_device
*
out
,
unsigned
int
hooknum
,
const
void
*
targinfo
,
const
void
*
targinfo
,
void
*
userinfo
)
void
*
userinfo
)
{
{
...
...
net/ipv4/netfilter/ipt_MASQUERADE.c
View file @
73baeace
...
@@ -57,9 +57,9 @@ masquerade_check(const char *tablename,
...
@@ -57,9 +57,9 @@ masquerade_check(const char *tablename,
static
unsigned
int
static
unsigned
int
masquerade_target
(
struct
sk_buff
**
pskb
,
masquerade_target
(
struct
sk_buff
**
pskb
,
unsigned
int
hooknum
,
const
struct
net_device
*
in
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
const
struct
net_device
*
out
,
unsigned
int
hooknum
,
const
void
*
targinfo
,
const
void
*
targinfo
,
void
*
userinfo
)
void
*
userinfo
)
{
{
...
...
net/ipv4/netfilter/ipt_MIRROR.c
View file @
73baeace
...
@@ -65,18 +65,22 @@ static int route_mirror(struct sk_buff *skb)
...
@@ -65,18 +65,22 @@ static int route_mirror(struct sk_buff *skb)
return
0
;
return
0
;
}
}
static
void
static
int
ip_rewrite
(
struct
sk_buff
**
pskb
)
ip_rewrite
(
struct
sk_buff
*
skb
)
{
{
struct
iphdr
*
iph
=
skb
->
nh
.
iph
;
u32
odaddr
,
osaddr
;
u32
odaddr
=
iph
->
saddr
;
u32
osaddr
=
iph
->
daddr
;
skb
->
nfcache
|=
NFC_ALTERED
;
if
(
!
skb_ip_make_writable
(
pskb
,
sizeof
(
struct
iphdr
)))
return
0
;
odaddr
=
(
*
pskb
)
->
nh
.
iph
->
saddr
;
osaddr
=
(
*
pskb
)
->
nh
.
iph
->
daddr
;
(
*
pskb
)
->
nfcache
|=
NFC_ALTERED
;
/* Rewrite IP header */
/* Rewrite IP header */
iph
->
daddr
=
odaddr
;
(
*
pskb
)
->
nh
.
iph
->
daddr
=
odaddr
;
iph
->
saddr
=
osaddr
;
(
*
pskb
)
->
nh
.
iph
->
saddr
=
osaddr
;
return
1
;
}
}
/* Stolen from ip_finish_output2 */
/* Stolen from ip_finish_output2 */
...
@@ -100,29 +104,28 @@ static void ip_direct_send(struct sk_buff *skb)
...
@@ -100,29 +104,28 @@ static void ip_direct_send(struct sk_buff *skb)
}
}
static
unsigned
int
ipt_mirror_target
(
struct
sk_buff
**
pskb
,
static
unsigned
int
ipt_mirror_target
(
struct
sk_buff
**
pskb
,
unsigned
int
hooknum
,
const
struct
net_device
*
in
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
const
struct
net_device
*
out
,
unsigned
int
hooknum
,
const
void
*
targinfo
,
const
void
*
targinfo
,
void
*
userinfo
)
void
*
userinfo
)
{
{
if
(((
*
pskb
)
->
dst
!=
NULL
)
&&
if
(((
*
pskb
)
->
dst
!=
NULL
)
&&
route_mirror
(
*
pskb
))
{
route_mirror
(
*
pskb
))
{
if
(
!
ip_rewrite
(
pskb
))
return
NF_DROP
;
ip_rewrite
(
*
pskb
);
/* If we are not at FORWARD hook (INPUT/PREROUTING),
/* If we are not at FORWARD hook (INPUT/PREROUTING),
* the TTL isn't decreased by the IP stack */
* the TTL isn't decreased by the IP stack */
if
(
hooknum
!=
NF_IP_FORWARD
)
{
if
(
hooknum
!=
NF_IP_FORWARD
)
{
struct
iphdr
*
iph
=
(
*
pskb
)
->
nh
.
iph
;
if
((
*
pskb
)
->
nh
.
iph
->
ttl
<=
1
)
{
if
(
iph
->
ttl
<=
1
)
{
/* this will traverse normal stack, and
/* this will traverse normal stack, and
* thus call conntrack on the icmp packet */
* thus call conntrack on the icmp packet */
icmp_send
(
*
pskb
,
ICMP_TIME_EXCEEDED
,
icmp_send
(
*
pskb
,
ICMP_TIME_EXCEEDED
,
ICMP_EXC_TTL
,
0
);
ICMP_EXC_TTL
,
0
);
return
NF_DROP
;
return
NF_DROP
;
}
}
ip_decrease_ttl
(
iph
);
/* Made writable by ip_rewrite */
ip_decrease_ttl
((
*
pskb
)
->
nh
.
iph
);
}
}
/* Don't let conntrack code see this packet:
/* Don't let conntrack code see this packet:
...
...
net/ipv4/netfilter/ipt_REDIRECT.c
View file @
73baeace
...
@@ -53,9 +53,9 @@ redirect_check(const char *tablename,
...
@@ -53,9 +53,9 @@ redirect_check(const char *tablename,
static
unsigned
int
static
unsigned
int
redirect_target
(
struct
sk_buff
**
pskb
,
redirect_target
(
struct
sk_buff
**
pskb
,
unsigned
int
hooknum
,
const
struct
net_device
*
in
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
const
struct
net_device
*
out
,
unsigned
int
hooknum
,
const
void
*
targinfo
,
const
void
*
targinfo
,
void
*
userinfo
)
void
*
userinfo
)
{
{
...
...
net/ipv4/netfilter/ipt_REJECT.c
View file @
73baeace
...
@@ -29,152 +29,140 @@ static void connection_attach(struct sk_buff *new_skb, struct nf_ct_info *nfct)
...
@@ -29,152 +29,140 @@ static void connection_attach(struct sk_buff *new_skb, struct nf_ct_info *nfct)
void
(
*
attach
)(
struct
sk_buff
*
,
struct
nf_ct_info
*
);
void
(
*
attach
)(
struct
sk_buff
*
,
struct
nf_ct_info
*
);
/* Avoid module unload race with ip_ct_attach being NULLed out */
/* Avoid module unload race with ip_ct_attach being NULLed out */
if
(
nfct
&&
(
attach
=
ip_ct_attach
)
!=
NULL
)
if
(
nfct
&&
(
attach
=
ip_ct_attach
)
!=
NULL
)
{
mb
();
/* Just to be sure: must be read before executing this */
attach
(
new_skb
,
nfct
);
attach
(
new_skb
,
nfct
);
}
}
}
/* Send RST reply */
/* Send RST reply */
static
void
send_reset
(
struct
sk_buff
*
old
skb
,
int
local
)
static
unsigned
int
send_reset
(
struct
sk_buff
**
p
skb
,
int
local
)
{
{
struct
sk_buff
*
nskb
;
struct
tcphdr
tcph
;
struct
tcphdr
*
otcph
,
*
tcph
;
struct
rtable
*
rt
;
struct
rtable
*
rt
;
unsigned
int
otcplen
;
u_int16_t
tmp_port
;
u_int16_t
tmp_port
;
u_int32_t
tmp_addr
;
u_int32_t
tmp_addr
;
int
needs_ack
;
int
needs_ack
,
hh_len
,
datalen
;
int
hh_len
;
struct
nf_ct_info
*
oldnfct
;
/* IP header checks: fragment, too short. */
/* No RSTs for fragments. */
if
(
oldskb
->
nh
.
iph
->
frag_off
&
htons
(
IP_OFFSET
)
if
((
*
pskb
)
->
nh
.
iph
->
frag_off
&
htons
(
IP_OFFSET
))
||
oldskb
->
len
<
(
oldskb
->
nh
.
iph
->
ihl
<<
2
)
+
sizeof
(
struct
tcphdr
))
return
NF_DROP
;
return
;
otcph
=
(
struct
tcphdr
*
)((
u_int32_t
*
)
oldskb
->
nh
.
iph
+
oldskb
->
nh
.
iph
->
ihl
);
if
(
skb_copy_bits
(
*
pskb
,
(
*
pskb
)
->
nh
.
iph
->
ihl
*
4
,
otcplen
=
oldskb
->
len
-
oldskb
->
nh
.
iph
->
ihl
*
4
;
&
tcph
,
sizeof
(
tcph
))
<
0
)
return
NF_DROP
;
/* No RST for RST. */
/* No RST for RST. */
if
(
otcph
->
rst
)
if
(
tcph
.
rst
)
return
;
return
NF_DROP
;
/* Check checksum. */
if
(
tcp_v4_check
(
otcph
,
otcplen
,
oldskb
->
nh
.
iph
->
saddr
,
oldskb
->
nh
.
iph
->
daddr
,
csum_partial
((
char
*
)
otcph
,
otcplen
,
0
))
!=
0
)
return
;
/* FIXME: Check checksum. */
{
{
struct
flowi
fl
=
{
.
nl_u
=
{
.
ip4_u
=
struct
flowi
fl
=
{
.
nl_u
=
{
.
ip4_u
=
{
.
daddr
=
oldskb
->
nh
.
iph
->
saddr
,
{
.
daddr
=
(
*
pskb
)
->
nh
.
iph
->
saddr
,
.
saddr
=
(
local
?
.
saddr
=
(
local
?
oldskb
->
nh
.
iph
->
daddr
:
(
*
pskb
)
->
nh
.
iph
->
daddr
:
0
),
0
),
.
tos
=
RT_TOS
(
oldskb
->
nh
.
iph
->
tos
)
}
}
};
.
tos
=
RT_TOS
(
(
*
pskb
)
->
nh
.
iph
->
tos
)
}
}
};
/* Routing: if not headed for us, route won't like source */
/* Routing: if not headed for us, route won't like source */
if
(
ip_route_output_key
(
&
rt
,
&
fl
))
if
(
ip_route_output_key
(
&
rt
,
&
fl
))
return
;
return
NF_DROP
;
hh_len
=
(
rt
->
u
.
dst
.
dev
->
hard_header_len
+
15
)
&~
15
;
hh_len
=
(
rt
->
u
.
dst
.
dev
->
hard_header_len
+
15
)
&~
15
;
}
}
/* We're going to flip the header around, drop options and data. */
/* Copy skb (even if skb is about to be dropped, we can't just
if
(
!
skb_ip_make_writable
(
pskb
,
(
*
pskb
)
->
nh
.
iph
->
ihl
*
4
+
sizeof
(
tcph
)))
{
clone it because there may be other things, such as tcpdump,
ip_rt_put
(
rt
);
interested in it). We also need to expand headroom in case
return
NF_DROP
;
hh_len of incoming interface < hh_len of outgoing interface */
nskb
=
skb_copy_expand
(
oldskb
,
hh_len
,
skb_tailroom
(
oldskb
),
GFP_ATOMIC
);
if
(
!
nskb
)
{
dst_release
(
&
rt
->
u
.
dst
);
return
;
}
}
dst_release
(
nskb
->
dst
);
(
*
pskb
)
->
h
.
th
=
(
void
*
)(
*
pskb
)
->
nh
.
iph
+
sizeof
(
tcph
);
nskb
->
dst
=
&
rt
->
u
.
dst
;
datalen
=
(
*
pskb
)
->
len
-
(
*
pskb
)
->
nh
.
iph
->
ihl
*
4
-
tcph
.
doff
*
4
;
/* Change over route. */
dst_release
((
*
pskb
)
->
dst
);
(
*
pskb
)
->
dst
=
&
rt
->
u
.
dst
;
/* This packet will not be the same as the other: clear nf fields */
/* This packet will not be the same as the other: clear nf fields */
nf_conntrack_put
(
nskb
->
nfct
);
(
*
pskb
)
->
nfcache
=
0
;
nskb
->
nfct
=
NULL
;
nskb
->
nfcache
=
0
;
#ifdef CONFIG_NETFILTER_DEBUG
#ifdef CONFIG_NETFILTER_DEBUG
nskb
->
nf_debug
=
0
;
(
*
pskb
)
->
nf_debug
=
0
;
#endif
#endif
nskb
->
nfmark
=
0
;
(
*
pskb
)
->
nfmark
=
0
;
tcph
=
(
struct
tcphdr
*
)((
u_int32_t
*
)
nskb
->
nh
.
iph
+
nskb
->
nh
.
iph
->
ihl
);
/* Swap source and dest */
/* Swap source and dest */
tmp_addr
=
nskb
->
nh
.
iph
->
saddr
;
tmp_addr
=
(
*
pskb
)
->
nh
.
iph
->
saddr
;
nskb
->
nh
.
iph
->
saddr
=
nskb
->
nh
.
iph
->
daddr
;
(
*
pskb
)
->
nh
.
iph
->
saddr
=
(
*
pskb
)
->
nh
.
iph
->
daddr
;
nskb
->
nh
.
iph
->
daddr
=
tmp_addr
;
(
*
pskb
)
->
nh
.
iph
->
daddr
=
tmp_addr
;
tmp_port
=
tcp
h
->
source
;
tmp_port
=
(
*
pskb
)
->
h
.
t
h
->
source
;
tcph
->
source
=
tcp
h
->
dest
;
(
*
pskb
)
->
h
.
th
->
source
=
(
*
pskb
)
->
h
.
t
h
->
dest
;
tcp
h
->
dest
=
tmp_port
;
(
*
pskb
)
->
h
.
t
h
->
dest
=
tmp_port
;
/* Truncate to length (no data) */
/* Truncate to length (no data) */
tcp
h
->
doff
=
sizeof
(
struct
tcphdr
)
/
4
;
(
*
pskb
)
->
h
.
t
h
->
doff
=
sizeof
(
struct
tcphdr
)
/
4
;
skb_trim
(
nskb
,
nskb
->
nh
.
iph
->
ihl
*
4
+
sizeof
(
struct
tcphdr
));
skb_trim
(
*
pskb
,
(
*
pskb
)
->
nh
.
iph
->
ihl
*
4
+
sizeof
(
struct
tcphdr
));
nskb
->
nh
.
iph
->
tot_len
=
htons
(
nskb
->
len
);
(
*
pskb
)
->
nh
.
iph
->
tot_len
=
htons
((
*
pskb
)
->
len
);
if
(
tcp
h
->
ack
)
{
if
(
(
*
pskb
)
->
h
.
t
h
->
ack
)
{
needs_ack
=
0
;
needs_ack
=
0
;
tcph
->
seq
=
otcph
->
ack_seq
;
(
*
pskb
)
->
h
.
th
->
seq
=
tcph
.
ack_seq
;
tcp
h
->
ack_seq
=
0
;
(
*
pskb
)
->
h
.
t
h
->
ack_seq
=
0
;
}
else
{
}
else
{
needs_ack
=
1
;
needs_ack
=
1
;
tcph
->
ack_seq
=
htonl
(
ntohl
(
otcph
->
seq
)
+
otcph
->
syn
+
otcph
->
fin
(
*
pskb
)
->
h
.
th
->
ack_seq
=
htonl
(
ntohl
(
tcph
.
seq
)
+
otcplen
-
(
otcph
->
doff
<<
2
));
+
tcph
.
syn
+
tcph
.
fin
tcph
->
seq
=
0
;
+
datalen
);
(
*
pskb
)
->
h
.
th
->
seq
=
0
;
}
}
/* Reset flags */
/* Reset flags */
((
u_int8_t
*
)
tcph
)[
13
]
=
0
;
memset
((
*
pskb
)
->
h
.
raw
+
13
,
0
,
1
)
;
tcp
h
->
rst
=
1
;
(
*
pskb
)
->
h
.
t
h
->
rst
=
1
;
tcp
h
->
ack
=
needs_ack
;
(
*
pskb
)
->
h
.
t
h
->
ack
=
needs_ack
;
tcp
h
->
window
=
0
;
(
*
pskb
)
->
h
.
t
h
->
window
=
0
;
tcp
h
->
urg_ptr
=
0
;
(
*
pskb
)
->
h
.
t
h
->
urg_ptr
=
0
;
/* Adjust TCP checksum */
/* Adjust TCP checksum */
tcph
->
check
=
0
;
(
*
pskb
)
->
h
.
th
->
check
=
0
;
tcph
->
check
=
tcp_v4_check
(
tcph
,
sizeof
(
struct
tcphdr
),
(
*
pskb
)
->
h
.
th
->
check
nskb
->
nh
.
iph
->
saddr
,
=
tcp_v4_check
((
*
pskb
)
->
h
.
th
,
nskb
->
nh
.
iph
->
daddr
,
sizeof
(
struct
tcphdr
),
csum_partial
((
char
*
)
tcph
,
(
*
pskb
)
->
nh
.
iph
->
saddr
,
sizeof
(
struct
tcphdr
),
0
));
(
*
pskb
)
->
nh
.
iph
->
daddr
,
csum_partial
((
*
pskb
)
->
h
.
raw
,
sizeof
(
struct
tcphdr
),
0
));
/* Adjust IP TTL, DF */
/* Adjust IP TTL, DF */
nskb
->
nh
.
iph
->
ttl
=
MAXTTL
;
(
*
pskb
)
->
nh
.
iph
->
ttl
=
MAXTTL
;
/* Set DF, id = 0 */
/* Set DF, id = 0 */
nskb
->
nh
.
iph
->
frag_off
=
htons
(
IP_DF
);
(
*
pskb
)
->
nh
.
iph
->
frag_off
=
htons
(
IP_DF
);
nskb
->
nh
.
iph
->
id
=
0
;
(
*
pskb
)
->
nh
.
iph
->
id
=
0
;
/* Adjust IP checksum */
/* Adjust IP checksum */
nskb
->
nh
.
iph
->
check
=
0
;
(
*
pskb
)
->
nh
.
iph
->
check
=
0
;
nskb
->
nh
.
iph
->
check
=
ip_fast_csum
((
unsigned
char
*
)
nskb
->
nh
.
iph
,
(
*
pskb
)
->
nh
.
iph
->
check
=
ip_fast_csum
((
*
pskb
)
->
nh
.
raw
,
nskb
->
nh
.
iph
->
ihl
);
(
*
pskb
)
->
nh
.
iph
->
ihl
);
/* "Never happens" */
/* "Never happens" */
if
(
nskb
->
len
>
dst_pmtu
(
nskb
->
dst
))
if
(
(
*
pskb
)
->
len
>
dst_pmtu
((
*
pskb
)
->
dst
))
goto
free_nskb
;
return
NF_DROP
;
connection_attach
(
nskb
,
oldskb
->
nfct
);
/* Related to old connection. */
oldnfct
=
(
*
pskb
)
->
nfct
;
connection_attach
(
*
pskb
,
oldnfct
);
nf_conntrack_put
(
oldnfct
);
NF_HOOK
(
PF_INET
,
NF_IP_LOCAL_OUT
,
nskb
,
NULL
,
nskb
->
dst
->
dev
,
NF_HOOK
(
PF_INET
,
NF_IP_LOCAL_OUT
,
*
pskb
,
NULL
,
(
*
pskb
)
->
dst
->
dev
,
ip_finish_output
);
ip_finish_output
);
return
;
return
NF_STOLEN
;
free_nskb:
kfree_skb
(
nskb
);
}
}
static
void
send_unreach
(
struct
sk_buff
*
skb_in
,
int
code
)
static
void
send_unreach
(
const
struct
sk_buff
*
skb_in
,
int
code
)
{
{
struct
iphdr
*
iph
;
struct
udphdr
*
udph
;
struct
icmphdr
*
icmph
;
struct
sk_buff
*
nskb
;
struct
sk_buff
*
nskb
;
u32
saddr
;
u32
saddr
;
u8
tos
;
u8
tos
;
...
@@ -189,8 +177,6 @@ static void send_unreach(struct sk_buff *skb_in, int code)
...
@@ -189,8 +177,6 @@ static void send_unreach(struct sk_buff *skb_in, int code)
if
(
!
xrlim_allow
(
&
rt
->
u
.
dst
,
1
*
HZ
))
if
(
!
xrlim_allow
(
&
rt
->
u
.
dst
,
1
*
HZ
))
return
;
return
;
iph
=
skb_in
->
nh
.
iph
;
/* No replies to physical multicast/broadcast */
/* No replies to physical multicast/broadcast */
if
(
skb_in
->
pkt_type
!=
PACKET_HOST
)
if
(
skb_in
->
pkt_type
!=
PACKET_HOST
)
return
;
return
;
...
@@ -200,46 +186,41 @@ static void send_unreach(struct sk_buff *skb_in, int code)
...
@@ -200,46 +186,41 @@ static void send_unreach(struct sk_buff *skb_in, int code)
return
;
return
;
/* Only reply to fragment 0. */
/* Only reply to fragment 0. */
if
(
iph
->
frag_off
&
htons
(
IP_OFFSET
))
if
(
skb_in
->
nh
.
iph
->
frag_off
&
htons
(
IP_OFFSET
))
return
;
/* Ensure we have at least 8 bytes of proto header. */
if
(
skb_in
->
len
<
skb_in
->
nh
.
iph
->
ihl
*
4
+
8
)
return
;
return
;
/* if UDP checksum is set, verify it's correct */
if
(
iph
->
protocol
==
IPPROTO_UDP
&&
skb_in
->
tail
-
(
u8
*
)
iph
>=
sizeof
(
struct
udphdr
))
{
int
datalen
=
skb_in
->
len
-
(
iph
->
ihl
<<
2
);
udph
=
(
struct
udphdr
*
)((
char
*
)
iph
+
(
iph
->
ihl
<<
2
));
if
(
udph
->
check
&&
csum_tcpudp_magic
(
iph
->
saddr
,
iph
->
daddr
,
datalen
,
IPPROTO_UDP
,
csum_partial
((
char
*
)
udph
,
datalen
,
0
))
!=
0
)
return
;
}
/* If we send an ICMP error to an ICMP error a mess would result.. */
/* If we send an ICMP error to an ICMP error a mess would result.. */
if
(
iph
->
protocol
==
IPPROTO_ICMP
if
(
skb_in
->
nh
.
iph
->
protocol
==
IPPROTO_ICMP
)
{
&&
skb_in
->
tail
-
(
u8
*
)
iph
>=
sizeof
(
struct
icmphdr
))
{
struct
icmphdr
icmph
;
icmph
=
(
struct
icmphdr
*
)((
char
*
)
iph
+
(
iph
->
ihl
<<
2
));
if
(
skb_copy_bits
(
skb_in
,
skb_in
->
nh
.
iph
->
ihl
*
4
,
&
icmph
,
sizeof
(
icmph
))
<
0
)
return
;
/* Between echo-reply (0) and timestamp (13),
/* Between echo-reply (0) and timestamp (13),
everything except echo-request (8) is an error.
everything except echo-request (8) is an error.
Also, anything greater than NR_ICMP_TYPES is
Also, anything greater than NR_ICMP_TYPES is
unknown, and hence should be treated as an error... */
unknown, and hence should be treated as an error... */
if
((
icmph
->
type
<
ICMP_TIMESTAMP
if
((
icmph
.
type
<
ICMP_TIMESTAMP
&&
icmph
->
type
!=
ICMP_ECHOREPLY
&&
icmph
.
type
!=
ICMP_ECHOREPLY
&&
icmph
->
type
!=
ICMP_ECHO
)
&&
icmph
.
type
!=
ICMP_ECHO
)
||
icmph
->
type
>
NR_ICMP_TYPES
)
||
icmph
.
type
>
NR_ICMP_TYPES
)
return
;
return
;
}
}
saddr
=
iph
->
daddr
;
saddr
=
skb_in
->
nh
.
iph
->
daddr
;
if
(
!
(
rt
->
rt_flags
&
RTCF_LOCAL
))
if
(
!
(
rt
->
rt_flags
&
RTCF_LOCAL
))
saddr
=
0
;
saddr
=
0
;
tos
=
(
iph
->
tos
&
IPTOS_TOS_MASK
)
|
IPTOS_PREC_INTERNETCONTROL
;
tos
=
(
skb_in
->
nh
.
iph
->
tos
&
IPTOS_TOS_MASK
)
|
IPTOS_PREC_INTERNETCONTROL
;
{
{
struct
flowi
fl
=
{
.
nl_u
=
{
.
ip4_u
=
struct
flowi
fl
=
{
.
nl_u
=
{
.
ip4_u
=
{
.
daddr
=
iph
->
saddr
,
{
.
daddr
=
skb_in
->
nh
.
iph
->
saddr
,
.
saddr
=
saddr
,
.
saddr
=
saddr
,
.
tos
=
RT_TOS
(
tos
)
}
}
};
.
tos
=
RT_TOS
(
tos
)
}
}
};
if
(
ip_route_output_key
(
&
rt
,
&
fl
))
if
(
ip_route_output_key
(
&
rt
,
&
fl
))
...
@@ -266,40 +247,38 @@ static void send_unreach(struct sk_buff *skb_in, int code)
...
@@ -266,40 +247,38 @@ static void send_unreach(struct sk_buff *skb_in, int code)
skb_reserve
(
nskb
,
hh_len
);
skb_reserve
(
nskb
,
hh_len
);
/* Set up IP header */
/* Set up IP header */
iph
=
nskb
->
nh
.
iph
nskb
->
nh
.
iph
=
(
struct
iphdr
*
)
skb_put
(
nskb
,
sizeof
(
struct
iphdr
));
=
(
struct
iphdr
*
)
skb_put
(
nskb
,
sizeof
(
struct
iphdr
));
nskb
->
nh
.
iph
->
version
=
4
;
iph
->
version
=
4
;
nskb
->
nh
.
iph
->
ihl
=
5
;
iph
->
ihl
=
5
;
nskb
->
nh
.
iph
->
tos
=
tos
;
iph
->
tos
=
tos
;
nskb
->
nh
.
iph
->
tot_len
=
htons
(
length
);
iph
->
tot_len
=
htons
(
length
);
/* PMTU discovery never applies to ICMP packets. */
/* PMTU discovery never applies to ICMP packets. */
iph
->
frag_off
=
0
;
nskb
->
nh
.
iph
->
frag_off
=
0
;
iph
->
ttl
=
MAXTTL
;
nskb
->
nh
.
iph
->
ttl
=
MAXTTL
;
ip_select_ident
(
iph
,
&
rt
->
u
.
dst
,
NULL
);
ip_select_ident
(
nskb
->
nh
.
iph
,
&
rt
->
u
.
dst
,
NULL
);
iph
->
protocol
=
IPPROTO_ICMP
;
nskb
->
nh
.
iph
->
protocol
=
IPPROTO_ICMP
;
iph
->
saddr
=
rt
->
rt_src
;
nskb
->
nh
.
iph
->
saddr
=
rt
->
rt_src
;
iph
->
daddr
=
rt
->
rt_dst
;
nskb
->
nh
.
iph
->
daddr
=
rt
->
rt_dst
;
iph
->
check
=
0
;
nskb
->
nh
.
iph
->
check
=
0
;
iph
->
check
=
ip_fast_csum
((
unsigned
char
*
)
iph
,
iph
->
ihl
);
nskb
->
nh
.
iph
->
check
=
ip_fast_csum
(
nskb
->
nh
.
raw
,
nskb
->
nh
.
iph
->
ihl
);
/* Set up ICMP header. */
/* Set up ICMP header. */
icmph
=
nskb
->
h
.
icmph
nskb
->
h
.
icmph
=
(
struct
icmphdr
*
)
skb_put
(
nskb
,
sizeof
(
struct
icmphdr
));
=
(
struct
icmphdr
*
)
skb_put
(
nskb
,
sizeof
(
struct
icmphdr
));
nskb
->
h
.
icmph
->
type
=
ICMP_DEST_UNREACH
;
icmph
->
type
=
ICMP_DEST_UNREACH
;
nskb
->
h
.
icmph
->
code
=
code
;
icmph
->
code
=
code
;
nskb
->
h
.
icmph
->
un
.
gateway
=
0
;
icmph
->
un
.
gateway
=
0
;
nskb
->
h
.
icmph
->
checksum
=
0
;
icmph
->
checksum
=
0
;
/* Copy as much of original packet as will fit */
/* Copy as much of original packet as will fit */
data
=
skb_put
(
nskb
,
data
=
skb_put
(
nskb
,
length
-
sizeof
(
struct
iphdr
)
-
sizeof
(
struct
icmphdr
));
length
-
sizeof
(
struct
iphdr
)
-
sizeof
(
struct
icmphdr
));
/* FIXME: won't work with nonlinear skbs --RR */
skb_copy_bits
(
skb_in
,
0
,
data
,
memcpy
(
data
,
skb_in
->
nh
.
iph
,
length
-
sizeof
(
struct
iphdr
)
-
sizeof
(
struct
icmphdr
));
length
-
sizeof
(
struct
iphdr
)
-
sizeof
(
struct
icmphdr
));
nskb
->
h
.
icmph
->
checksum
=
ip_compute_csum
(
nskb
->
h
.
raw
,
icmph
->
checksum
=
ip_compute_csum
((
unsigned
char
*
)
icmph
,
length
-
sizeof
(
struct
iphdr
));
length
-
sizeof
(
struct
iphdr
));
connection_attach
(
nskb
,
skb_in
->
nfct
);
connection_attach
(
nskb
,
skb_in
->
nfct
);
...
@@ -308,9 +287,9 @@ static void send_unreach(struct sk_buff *skb_in, int code)
...
@@ -308,9 +287,9 @@ static void send_unreach(struct sk_buff *skb_in, int code)
}
}
static
unsigned
int
reject
(
struct
sk_buff
**
pskb
,
static
unsigned
int
reject
(
struct
sk_buff
**
pskb
,
unsigned
int
hooknum
,
const
struct
net_device
*
in
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
const
struct
net_device
*
out
,
unsigned
int
hooknum
,
const
void
*
targinfo
,
const
void
*
targinfo
,
void
*
userinfo
)
void
*
userinfo
)
{
{
...
@@ -344,7 +323,7 @@ static unsigned int reject(struct sk_buff **pskb,
...
@@ -344,7 +323,7 @@ static unsigned int reject(struct sk_buff **pskb,
send_unreach
(
*
pskb
,
ICMP_HOST_ANO
);
send_unreach
(
*
pskb
,
ICMP_HOST_ANO
);
break
;
break
;
case
IPT_TCP_RESET
:
case
IPT_TCP_RESET
:
send_reset
(
*
pskb
,
hooknum
==
NF_IP_LOCAL_IN
);
return
send_reset
(
pskb
,
hooknum
==
NF_IP_LOCAL_IN
);
case
IPT_ICMP_ECHOREPLY
:
case
IPT_ICMP_ECHOREPLY
:
/* Doesn't happen. */
/* Doesn't happen. */
break
;
break
;
...
...
net/ipv4/netfilter/ipt_TCPMSS.c
View file @
73baeace
...
@@ -36,9 +36,9 @@ optlen(const u_int8_t *opt, unsigned int offset)
...
@@ -36,9 +36,9 @@ optlen(const u_int8_t *opt, unsigned int offset)
static
unsigned
int
static
unsigned
int
ipt_tcpmss_target
(
struct
sk_buff
**
pskb
,
ipt_tcpmss_target
(
struct
sk_buff
**
pskb
,
unsigned
int
hooknum
,
const
struct
net_device
*
in
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
const
struct
net_device
*
out
,
unsigned
int
hooknum
,
const
void
*
targinfo
,
const
void
*
targinfo
,
void
*
userinfo
)
void
*
userinfo
)
{
{
...
@@ -49,15 +49,8 @@ ipt_tcpmss_target(struct sk_buff **pskb,
...
@@ -49,15 +49,8 @@ ipt_tcpmss_target(struct sk_buff **pskb,
unsigned
int
i
;
unsigned
int
i
;
u_int8_t
*
opt
;
u_int8_t
*
opt
;
/* raw socket (tcpdump) may have clone of incoming skb: don't
if
(
!
skb_ip_make_writable
(
pskb
,
(
*
pskb
)
->
len
))
disturb it --RR */
return
NF_DROP
;
if
(
skb_cloned
(
*
pskb
)
&&
!
(
*
pskb
)
->
sk
)
{
struct
sk_buff
*
nskb
=
skb_copy
(
*
pskb
,
GFP_ATOMIC
);
if
(
!
nskb
)
return
NF_DROP
;
kfree_skb
(
*
pskb
);
*
pskb
=
nskb
;
}
iph
=
(
*
pskb
)
->
nh
.
iph
;
iph
=
(
*
pskb
)
->
nh
.
iph
;
tcplen
=
(
*
pskb
)
->
len
-
iph
->
ihl
*
4
;
tcplen
=
(
*
pskb
)
->
len
-
iph
->
ihl
*
4
;
...
...
net/ipv4/netfilter/ipt_TOS.c
View file @
73baeace
...
@@ -9,35 +9,30 @@
...
@@ -9,35 +9,30 @@
static
unsigned
int
static
unsigned
int
target
(
struct
sk_buff
**
pskb
,
target
(
struct
sk_buff
**
pskb
,
unsigned
int
hooknum
,
const
struct
net_device
*
in
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
const
struct
net_device
*
out
,
unsigned
int
hooknum
,
const
void
*
targinfo
,
const
void
*
targinfo
,
void
*
userinfo
)
void
*
userinfo
)
{
{
struct
iphdr
*
iph
=
(
*
pskb
)
->
nh
.
iph
;
const
struct
ipt_tos_target_info
*
tosinfo
=
targinfo
;
const
struct
ipt_tos_target_info
*
tosinfo
=
targinfo
;
if
((
iph
->
tos
&
IPTOS_TOS_MASK
)
!=
tosinfo
->
tos
)
{
if
((
(
*
pskb
)
->
nh
.
iph
->
tos
&
IPTOS_TOS_MASK
)
!=
tosinfo
->
tos
)
{
u_int16_t
diffs
[
2
];
u_int16_t
diffs
[
2
];
/* raw socket (tcpdump) may have clone of incoming
if
(
!
skb_ip_make_writable
(
pskb
,
sizeof
(
struct
iphdr
)))
skb: don't disturb it --RR */
return
NF_DROP
;
if
(
skb_cloned
(
*
pskb
)
&&
!
(
*
pskb
)
->
sk
)
{
struct
sk_buff
*
nskb
=
skb_copy
(
*
pskb
,
GFP_ATOMIC
);
if
(
!
nskb
)
return
NF_DROP
;
kfree_skb
(
*
pskb
);
*
pskb
=
nskb
;
iph
=
(
*
pskb
)
->
nh
.
iph
;
}
diffs
[
0
]
=
htons
(
iph
->
tos
)
^
0xFFFF
;
diffs
[
0
]
=
htons
((
*
pskb
)
->
nh
.
iph
->
tos
)
^
0xFFFF
;
iph
->
tos
=
(
iph
->
tos
&
IPTOS_PREC_MASK
)
|
tosinfo
->
tos
;
(
*
pskb
)
->
nh
.
iph
->
tos
diffs
[
1
]
=
htons
(
iph
->
tos
);
=
((
*
pskb
)
->
nh
.
iph
->
tos
&
IPTOS_PREC_MASK
)
iph
->
check
=
csum_fold
(
csum_partial
((
char
*
)
diffs
,
|
tosinfo
->
tos
;
sizeof
(
diffs
),
diffs
[
1
]
=
htons
((
*
pskb
)
->
nh
.
iph
->
tos
);
iph
->
check
^
0xFFFF
));
(
*
pskb
)
->
nh
.
iph
->
check
=
csum_fold
(
csum_partial
((
char
*
)
diffs
,
sizeof
(
diffs
),
(
*
pskb
)
->
nh
.
iph
->
check
^
0xFFFF
));
(
*
pskb
)
->
nfcache
|=
NFC_ALTERED
;
(
*
pskb
)
->
nfcache
|=
NFC_ALTERED
;
}
}
return
IPT_CONTINUE
;
return
IPT_CONTINUE
;
...
...
net/ipv4/netfilter/ipt_ULOG.c
View file @
73baeace
...
@@ -155,9 +155,9 @@ struct sk_buff *ulog_alloc_skb(unsigned int size)
...
@@ -155,9 +155,9 @@ struct sk_buff *ulog_alloc_skb(unsigned int size)
}
}
static
unsigned
int
ipt_ulog_target
(
struct
sk_buff
**
pskb
,
static
unsigned
int
ipt_ulog_target
(
struct
sk_buff
**
pskb
,
unsigned
int
hooknum
,
const
struct
net_device
*
in
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
const
struct
net_device
*
out
,
unsigned
int
hooknum
,
const
void
*
targinfo
,
void
*
userinfo
)
const
void
*
targinfo
,
void
*
userinfo
)
{
{
ulog_buff_t
*
ub
;
ulog_buff_t
*
ub
;
...
@@ -238,8 +238,9 @@ static unsigned int ipt_ulog_target(struct sk_buff **pskb,
...
@@ -238,8 +238,9 @@ static unsigned int ipt_ulog_target(struct sk_buff **pskb,
else
else
pm
->
outdev_name
[
0
]
=
'\0'
;
pm
->
outdev_name
[
0
]
=
'\0'
;
if
(
copy_len
)
/* copy_len <= (*pskb)->len, so can't fail. */
memcpy
(
pm
->
payload
,
(
*
pskb
)
->
data
,
copy_len
);
if
(
skb_copy_bits
(
*
pskb
,
0
,
pm
->
payload
,
copy_len
)
<
0
)
BUG
();
/* check if we are building multi-part messages */
/* check if we are building multi-part messages */
if
(
ub
->
qlen
>
1
)
{
if
(
ub
->
qlen
>
1
)
{
...
...
net/ipv4/netfilter/ipt_ah.c
View file @
73baeace
...
@@ -35,14 +35,16 @@ match(const struct sk_buff *skb,
...
@@ -35,14 +35,16 @@ match(const struct sk_buff *skb,
const
struct
net_device
*
out
,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
const
void
*
matchinfo
,
int
offset
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
int
*
hotdrop
)
int
*
hotdrop
)
{
{
const
struct
ahhdr
*
ah
=
hdr
;
struct
ahhdr
ah
;
const
struct
ipt_ah
*
ahinfo
=
matchinfo
;
const
struct
ipt_ah
*
ahinfo
=
matchinfo
;
if
(
offset
==
0
&&
datalen
<
sizeof
(
struct
ahhdr
))
{
/* Must not be a fragment. */
if
(
offset
)
return
0
;
if
(
skb_copy_bits
(
skb
,
skb
->
nh
.
iph
->
ihl
*
4
,
&
ah
,
sizeof
(
ah
))
<
0
)
{
/* We've been asked to examine this packet, and we
/* We've been asked to examine this packet, and we
can't. Hence, no choice but to drop. */
can't. Hence, no choice but to drop. */
duprintf
(
"Dropping evil AH tinygram.
\n
"
);
duprintf
(
"Dropping evil AH tinygram.
\n
"
);
...
@@ -50,11 +52,9 @@ match(const struct sk_buff *skb,
...
@@ -50,11 +52,9 @@ match(const struct sk_buff *skb,
return
0
;
return
0
;
}
}
/* Must not be a fragment. */
return
spi_match
(
ahinfo
->
spis
[
0
],
ahinfo
->
spis
[
1
],
return
!
offset
ntohl
(
ah
.
spi
),
&&
spi_match
(
ahinfo
->
spis
[
0
],
ahinfo
->
spis
[
1
],
!!
(
ahinfo
->
invflags
&
IPT_AH_INV_SPI
));
ntohl
(
ah
->
spi
),
!!
(
ahinfo
->
invflags
&
IPT_AH_INV_SPI
));
}
}
/* Called when user tries to insert an entry of this type. */
/* Called when user tries to insert an entry of this type. */
...
...
net/ipv4/netfilter/ipt_conntrack.c
View file @
73baeace
...
@@ -14,8 +14,6 @@ match(const struct sk_buff *skb,
...
@@ -14,8 +14,6 @@ match(const struct sk_buff *skb,
const
struct
net_device
*
out
,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
const
void
*
matchinfo
,
int
offset
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
int
*
hotdrop
)
int
*
hotdrop
)
{
{
const
struct
ipt_conntrack_info
*
sinfo
=
matchinfo
;
const
struct
ipt_conntrack_info
*
sinfo
=
matchinfo
;
...
...
net/ipv4/netfilter/ipt_dscp.c
View file @
73baeace
...
@@ -19,8 +19,7 @@ MODULE_LICENSE("GPL");
...
@@ -19,8 +19,7 @@ MODULE_LICENSE("GPL");
static
int
match
(
const
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
static
int
match
(
const
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
int
offset
,
int
*
hotdrop
)
int
*
hotdrop
)
{
{
const
struct
ipt_dscp_info
*
info
=
matchinfo
;
const
struct
ipt_dscp_info
*
info
=
matchinfo
;
const
struct
iphdr
*
iph
=
skb
->
nh
.
iph
;
const
struct
iphdr
*
iph
=
skb
->
nh
.
iph
;
...
...
net/ipv4/netfilter/ipt_ecn.c
View file @
73baeace
...
@@ -19,34 +19,40 @@ MODULE_DESCRIPTION("IP tables ECN matching module");
...
@@ -19,34 +19,40 @@ MODULE_DESCRIPTION("IP tables ECN matching module");
MODULE_LICENSE
(
"GPL"
);
MODULE_LICENSE
(
"GPL"
);
static
inline
int
match_ip
(
const
struct
sk_buff
*
skb
,
static
inline
int
match_ip
(
const
struct
sk_buff
*
skb
,
const
struct
iphdr
*
iph
,
const
struct
ipt_ecn_info
*
einfo
)
const
struct
ipt_ecn_info
*
einfo
)
{
{
return
((
iph
->
tos
&
IPT_ECN_IP_MASK
)
==
einfo
->
ip_ect
);
return
((
skb
->
nh
.
iph
->
tos
&
IPT_ECN_IP_MASK
)
==
einfo
->
ip_ect
);
}
}
static
inline
int
match_tcp
(
const
struct
sk_buff
*
skb
,
static
inline
int
match_tcp
(
const
struct
sk_buff
*
skb
,
const
struct
ip
hdr
*
iph
,
const
struct
ip
t_ecn_info
*
einfo
,
const
struct
ipt_ecn_info
*
einfo
)
int
*
hotdrop
)
{
{
struct
tcphdr
*
tcph
=
(
void
*
)
iph
+
iph
->
ihl
*
4
;
struct
tcphdr
tcph
;
/* In practice, TCP match does this, so can't fail. But let's
be good citizens. */
if
(
skb_copy_bits
(
skb
,
skb
->
nh
.
iph
->
ihl
*
4
,
&
tcph
,
sizeof
(
tcph
))
<
0
)
{
*
hotdrop
=
0
;
return
0
;
}
if
(
einfo
->
operation
&
IPT_ECN_OP_MATCH_ECE
)
{
if
(
einfo
->
operation
&
IPT_ECN_OP_MATCH_ECE
)
{
if
(
einfo
->
invert
&
IPT_ECN_OP_MATCH_ECE
)
{
if
(
einfo
->
invert
&
IPT_ECN_OP_MATCH_ECE
)
{
if
(
tcph
->
ece
==
1
)
if
(
tcph
.
ece
==
1
)
return
0
;
return
0
;
}
else
{
}
else
{
if
(
tcph
->
ece
==
0
)
if
(
tcph
.
ece
==
0
)
return
0
;
return
0
;
}
}
}
}
if
(
einfo
->
operation
&
IPT_ECN_OP_MATCH_CWR
)
{
if
(
einfo
->
operation
&
IPT_ECN_OP_MATCH_CWR
)
{
if
(
einfo
->
invert
&
IPT_ECN_OP_MATCH_CWR
)
{
if
(
einfo
->
invert
&
IPT_ECN_OP_MATCH_CWR
)
{
if
(
tcph
->
cwr
==
1
)
if
(
tcph
.
cwr
==
1
)
return
0
;
return
0
;
}
else
{
}
else
{
if
(
tcph
->
cwr
==
0
)
if
(
tcph
.
cwr
==
0
)
return
0
;
return
0
;
}
}
}
}
...
@@ -56,20 +62,18 @@ static inline int match_tcp(const struct sk_buff *skb,
...
@@ -56,20 +62,18 @@ static inline int match_tcp(const struct sk_buff *skb,
static
int
match
(
const
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
static
int
match
(
const
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
int
offset
,
int
*
hotdrop
)
int
*
hotdrop
)
{
{
const
struct
ipt_ecn_info
*
info
=
matchinfo
;
const
struct
ipt_ecn_info
*
info
=
matchinfo
;
const
struct
iphdr
*
iph
=
skb
->
nh
.
iph
;
if
(
info
->
operation
&
IPT_ECN_OP_MATCH_IP
)
if
(
info
->
operation
&
IPT_ECN_OP_MATCH_IP
)
if
(
!
match_ip
(
skb
,
i
ph
,
i
nfo
))
if
(
!
match_ip
(
skb
,
info
))
return
0
;
return
0
;
if
(
info
->
operation
&
(
IPT_ECN_OP_MATCH_ECE
|
IPT_ECN_OP_MATCH_CWR
))
{
if
(
info
->
operation
&
(
IPT_ECN_OP_MATCH_ECE
|
IPT_ECN_OP_MATCH_CWR
))
{
if
(
iph
->
protocol
!=
IPPROTO_TCP
)
if
(
skb
->
nh
.
iph
->
protocol
!=
IPPROTO_TCP
)
return
0
;
return
0
;
if
(
!
match_tcp
(
skb
,
i
ph
,
info
))
if
(
!
match_tcp
(
skb
,
i
nfo
,
hotdrop
))
return
0
;
return
0
;
}
}
...
...
net/ipv4/netfilter/ipt_esp.c
View file @
73baeace
...
@@ -35,14 +35,16 @@ match(const struct sk_buff *skb,
...
@@ -35,14 +35,16 @@ match(const struct sk_buff *skb,
const
struct
net_device
*
out
,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
const
void
*
matchinfo
,
int
offset
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
int
*
hotdrop
)
int
*
hotdrop
)
{
{
const
struct
esphdr
*
esp
=
hdr
;
struct
esphdr
esp
;
const
struct
ipt_esp
*
espinfo
=
matchinfo
;
const
struct
ipt_esp
*
espinfo
=
matchinfo
;
if
(
offset
==
0
&&
datalen
<
sizeof
(
struct
esphdr
))
{
/* Must not be a fragment. */
if
(
offset
)
return
0
;
if
(
skb_copy_bits
(
skb
,
skb
->
nh
.
iph
->
ihl
*
4
,
&
esp
,
sizeof
(
esp
))
<
0
)
{
/* We've been asked to examine this packet, and we
/* We've been asked to examine this packet, and we
can't. Hence, no choice but to drop. */
can't. Hence, no choice but to drop. */
duprintf
(
"Dropping evil ESP tinygram.
\n
"
);
duprintf
(
"Dropping evil ESP tinygram.
\n
"
);
...
@@ -50,11 +52,9 @@ match(const struct sk_buff *skb,
...
@@ -50,11 +52,9 @@ match(const struct sk_buff *skb,
return
0
;
return
0
;
}
}
/* Must not be a fragment. */
return
spi_match
(
espinfo
->
spis
[
0
],
espinfo
->
spis
[
1
],
return
!
offset
ntohl
(
esp
.
spi
),
&&
spi_match
(
espinfo
->
spis
[
0
],
espinfo
->
spis
[
1
],
!!
(
espinfo
->
invflags
&
IPT_ESP_INV_SPI
));
ntohl
(
esp
->
spi
),
!!
(
espinfo
->
invflags
&
IPT_ESP_INV_SPI
));
}
}
/* Called when user tries to insert an entry of this type. */
/* Called when user tries to insert an entry of this type. */
...
...
net/ipv4/netfilter/ipt_helper.c
View file @
73baeace
...
@@ -28,8 +28,6 @@ match(const struct sk_buff *skb,
...
@@ -28,8 +28,6 @@ match(const struct sk_buff *skb,
const
struct
net_device
*
out
,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
const
void
*
matchinfo
,
int
offset
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
int
*
hotdrop
)
int
*
hotdrop
)
{
{
const
struct
ipt_helper_info
*
info
=
matchinfo
;
const
struct
ipt_helper_info
*
info
=
matchinfo
;
...
...
net/ipv4/netfilter/ipt_length.c
View file @
73baeace
...
@@ -15,8 +15,6 @@ match(const struct sk_buff *skb,
...
@@ -15,8 +15,6 @@ match(const struct sk_buff *skb,
const
struct
net_device
*
out
,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
const
void
*
matchinfo
,
int
offset
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
int
*
hotdrop
)
int
*
hotdrop
)
{
{
const
struct
ipt_length_info
*
info
=
matchinfo
;
const
struct
ipt_length_info
*
info
=
matchinfo
;
...
...
net/ipv4/netfilter/ipt_limit.c
View file @
73baeace
...
@@ -47,8 +47,6 @@ ipt_limit_match(const struct sk_buff *skb,
...
@@ -47,8 +47,6 @@ ipt_limit_match(const struct sk_buff *skb,
const
struct
net_device
*
out
,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
const
void
*
matchinfo
,
int
offset
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
int
*
hotdrop
)
int
*
hotdrop
)
{
{
struct
ipt_rateinfo
*
r
=
((
struct
ipt_rateinfo
*
)
matchinfo
)
->
master
;
struct
ipt_rateinfo
*
r
=
((
struct
ipt_rateinfo
*
)
matchinfo
)
->
master
;
...
...
net/ipv4/netfilter/ipt_mac.c
View file @
73baeace
...
@@ -12,8 +12,6 @@ match(const struct sk_buff *skb,
...
@@ -12,8 +12,6 @@ match(const struct sk_buff *skb,
const
struct
net_device
*
out
,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
const
void
*
matchinfo
,
int
offset
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
int
*
hotdrop
)
int
*
hotdrop
)
{
{
const
struct
ipt_mac_info
*
info
=
matchinfo
;
const
struct
ipt_mac_info
*
info
=
matchinfo
;
...
...
net/ipv4/netfilter/ipt_mark.c
View file @
73baeace
...
@@ -11,8 +11,6 @@ match(const struct sk_buff *skb,
...
@@ -11,8 +11,6 @@ match(const struct sk_buff *skb,
const
struct
net_device
*
out
,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
const
void
*
matchinfo
,
int
offset
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
int
*
hotdrop
)
int
*
hotdrop
)
{
{
const
struct
ipt_mark_info
*
info
=
matchinfo
;
const
struct
ipt_mark_info
*
info
=
matchinfo
;
...
...
net/ipv4/netfilter/ipt_multiport.c
View file @
73baeace
...
@@ -39,15 +39,18 @@ match(const struct sk_buff *skb,
...
@@ -39,15 +39,18 @@ match(const struct sk_buff *skb,
const
struct
net_device
*
out
,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
const
void
*
matchinfo
,
int
offset
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
int
*
hotdrop
)
int
*
hotdrop
)
{
{
const
struct
udphdr
*
udp
=
hdr
;
u16
ports
[
2
]
;
const
struct
ipt_multiport
*
multiinfo
=
matchinfo
;
const
struct
ipt_multiport
*
multiinfo
=
matchinfo
;
/* Must be big enough to read ports. */
/* Must not be a fragment. */
if
(
offset
==
0
&&
datalen
<
sizeof
(
struct
udphdr
))
{
if
(
offset
)
return
0
;
/* Must be big enough to read ports (both UDP and TCP have
them at the start). */
if
(
skb_copy_bits
(
skb
,
skb
->
nh
.
iph
->
ihl
*
4
,
ports
,
sizeof
(
ports
))
<
0
)
{
/* We've been asked to examine this packet, and we
/* We've been asked to examine this packet, and we
can't. Hence, no choice but to drop. */
can't. Hence, no choice but to drop. */
duprintf
(
"ipt_multiport:"
duprintf
(
"ipt_multiport:"
...
@@ -56,11 +59,9 @@ match(const struct sk_buff *skb,
...
@@ -56,11 +59,9 @@ match(const struct sk_buff *skb,
return
0
;
return
0
;
}
}
/* Must not be a fragment. */
return
ports_match
(
multiinfo
->
ports
,
return
!
offset
multiinfo
->
flags
,
multiinfo
->
count
,
&&
ports_match
(
multiinfo
->
ports
,
ntohs
(
ports
[
0
]),
ntohs
(
ports
[
1
]));
multiinfo
->
flags
,
multiinfo
->
count
,
ntohs
(
udp
->
source
),
ntohs
(
udp
->
dest
));
}
}
/* Called when user tries to insert an entry of this type. */
/* Called when user tries to insert an entry of this type. */
...
...
net/ipv4/netfilter/ipt_owner.c
View file @
73baeace
...
@@ -115,8 +115,6 @@ match(const struct sk_buff *skb,
...
@@ -115,8 +115,6 @@ match(const struct sk_buff *skb,
const
struct
net_device
*
out
,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
const
void
*
matchinfo
,
int
offset
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
int
*
hotdrop
)
int
*
hotdrop
)
{
{
const
struct
ipt_owner_info
*
info
=
matchinfo
;
const
struct
ipt_owner_info
*
info
=
matchinfo
;
...
@@ -170,8 +168,11 @@ checkentry(const char *tablename,
...
@@ -170,8 +168,11 @@ checkentry(const char *tablename,
return
0
;
return
0
;
}
}
if
(
matchsize
!=
IPT_ALIGN
(
sizeof
(
struct
ipt_owner_info
)))
if
(
matchsize
!=
IPT_ALIGN
(
sizeof
(
struct
ipt_owner_info
)))
{
printk
(
"Matchsize %u != %Zu
\n
"
,
matchsize
,
IPT_ALIGN
(
sizeof
(
struct
ipt_owner_info
)));
return
0
;
return
0
;
}
return
1
;
return
1
;
}
}
...
...
net/ipv4/netfilter/ipt_physdev.c
View file @
73baeace
...
@@ -14,8 +14,6 @@ match(const struct sk_buff *skb,
...
@@ -14,8 +14,6 @@ match(const struct sk_buff *skb,
const
struct
net_device
*
out
,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
const
void
*
matchinfo
,
int
offset
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
int
*
hotdrop
)
int
*
hotdrop
)
{
{
int
i
;
int
i
;
...
...
net/ipv4/netfilter/ipt_pkttype.c
View file @
73baeace
...
@@ -13,8 +13,6 @@ static int match(const struct sk_buff *skb,
...
@@ -13,8 +13,6 @@ static int match(const struct sk_buff *skb,
const
struct
net_device
*
out
,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
const
void
*
matchinfo
,
int
offset
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
int
*
hotdrop
)
int
*
hotdrop
)
{
{
const
struct
ipt_pkttype_info
*
info
=
matchinfo
;
const
struct
ipt_pkttype_info
*
info
=
matchinfo
;
...
...
net/ipv4/netfilter/ipt_state.c
View file @
73baeace
...
@@ -13,8 +13,6 @@ match(const struct sk_buff *skb,
...
@@ -13,8 +13,6 @@ match(const struct sk_buff *skb,
const
struct
net_device
*
out
,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
const
void
*
matchinfo
,
int
offset
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
int
*
hotdrop
)
int
*
hotdrop
)
{
{
const
struct
ipt_state_info
*
sinfo
=
matchinfo
;
const
struct
ipt_state_info
*
sinfo
=
matchinfo
;
...
...
net/ipv4/netfilter/ipt_tcpmss.c
View file @
73baeace
...
@@ -11,24 +11,32 @@
...
@@ -11,24 +11,32 @@
/* Returns 1 if the mss option is set and matched by the range, 0 otherwise */
/* Returns 1 if the mss option is set and matched by the range, 0 otherwise */
static
inline
int
static
inline
int
mssoption_match
(
u_int16_t
min
,
u_int16_t
max
,
mssoption_match
(
u_int16_t
min
,
u_int16_t
max
,
const
struct
tcphdr
*
tcp
,
const
struct
sk_buff
*
skb
,
u_int16_t
datalen
,
int
invert
,
int
invert
,
int
*
hotdrop
)
int
*
hotdrop
)
{
{
unsigned
int
i
;
struct
tcphdr
tcph
;
const
u_int8_t
*
opt
=
(
u_int8_t
*
)
tcp
;
/* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */
u8
opt
[
15
*
4
-
sizeof
(
tcph
)];
unsigned
int
i
,
optlen
;
/* If we don't have the whole header, drop packet. */
/* If we don't have the whole header, drop packet. */
if
(
tcp
->
doff
*
4
>
datalen
)
{
if
(
skb_copy_bits
(
skb
,
skb
->
nh
.
iph
->
ihl
*
4
,
&
tcph
,
sizeof
(
tcph
))
<
0
)
*
hotdrop
=
1
;
goto
dropit
;
return
0
;
}
/* Malformed. */
if
(
tcph
.
doff
*
4
<
sizeof
(
tcph
))
for
(
i
=
sizeof
(
struct
tcphdr
);
i
<
tcp
->
doff
*
4
;
)
{
goto
dropit
;
if
((
opt
[
i
]
==
TCPOPT_MSS
)
&&
((
tcp
->
doff
*
4
-
i
)
>=
TCPOLEN_MSS
)
optlen
=
tcph
.
doff
*
4
-
sizeof
(
tcph
);
&&
(
opt
[
i
+
1
]
==
TCPOLEN_MSS
))
{
/* Truncated options. */
if
(
skb_copy_bits
(
skb
,
skb
->
nh
.
iph
->
ihl
*
4
+
sizeof
(
tcph
),
opt
,
optlen
)
<
0
)
goto
dropit
;
for
(
i
=
0
;
i
<
optlen
;
)
{
if
(
opt
[
i
]
==
TCPOPT_MSS
&&
(
optlen
-
i
)
>=
TCPOLEN_MSS
&&
opt
[
i
+
1
]
==
TCPOLEN_MSS
)
{
u_int16_t
mssval
;
u_int16_t
mssval
;
mssval
=
(
opt
[
i
+
2
]
<<
8
)
|
opt
[
i
+
3
];
mssval
=
(
opt
[
i
+
2
]
<<
8
)
|
opt
[
i
+
3
];
...
@@ -38,8 +46,11 @@ mssoption_match(u_int16_t min, u_int16_t max,
...
@@ -38,8 +46,11 @@ mssoption_match(u_int16_t min, u_int16_t max,
if
(
opt
[
i
]
<
2
)
i
++
;
if
(
opt
[
i
]
<
2
)
i
++
;
else
i
+=
opt
[
i
+
1
]
?:
1
;
else
i
+=
opt
[
i
+
1
]
?:
1
;
}
}
return
invert
;
return
invert
;
dropit:
*
hotdrop
=
1
;
return
0
;
}
}
static
int
static
int
...
@@ -48,15 +59,11 @@ match(const struct sk_buff *skb,
...
@@ -48,15 +59,11 @@ match(const struct sk_buff *skb,
const
struct
net_device
*
out
,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
const
void
*
matchinfo
,
int
offset
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
int
*
hotdrop
)
int
*
hotdrop
)
{
{
const
struct
ipt_tcpmss_match_info
*
info
=
matchinfo
;
const
struct
ipt_tcpmss_match_info
*
info
=
matchinfo
;
const
struct
tcphdr
*
tcph
=
(
void
*
)
skb
->
nh
.
iph
+
skb
->
nh
.
iph
->
ihl
*
4
;
return
mssoption_match
(
info
->
mss_min
,
info
->
mss_max
,
tcph
,
return
mssoption_match
(
info
->
mss_min
,
info
->
mss_max
,
skb
,
skb
->
len
-
skb
->
nh
.
iph
->
ihl
*
4
,
info
->
invert
,
hotdrop
);
info
->
invert
,
hotdrop
);
}
}
...
...
net/ipv4/netfilter/ipt_tos.c
View file @
73baeace
...
@@ -11,14 +11,11 @@ match(const struct sk_buff *skb,
...
@@ -11,14 +11,11 @@ match(const struct sk_buff *skb,
const
struct
net_device
*
out
,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
const
void
*
matchinfo
,
int
offset
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
int
*
hotdrop
)
int
*
hotdrop
)
{
{
const
struct
ipt_tos_info
*
info
=
matchinfo
;
const
struct
ipt_tos_info
*
info
=
matchinfo
;
const
struct
iphdr
*
iph
=
skb
->
nh
.
iph
;
return
(
iph
->
tos
==
info
->
tos
)
^
info
->
invert
;
return
(
skb
->
nh
.
iph
->
tos
==
info
->
tos
)
^
info
->
invert
;
}
}
static
int
static
int
...
...
net/ipv4/netfilter/ipt_ttl.c
View file @
73baeace
...
@@ -19,24 +19,22 @@ MODULE_LICENSE("GPL");
...
@@ -19,24 +19,22 @@ MODULE_LICENSE("GPL");
static
int
match
(
const
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
static
int
match
(
const
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
int
offset
,
int
*
hotdrop
)
int
*
hotdrop
)
{
{
const
struct
ipt_ttl_info
*
info
=
matchinfo
;
const
struct
ipt_ttl_info
*
info
=
matchinfo
;
const
struct
iphdr
*
iph
=
skb
->
nh
.
iph
;
switch
(
info
->
mode
)
{
switch
(
info
->
mode
)
{
case
IPT_TTL_EQ
:
case
IPT_TTL_EQ
:
return
(
iph
->
ttl
==
info
->
ttl
);
return
(
skb
->
nh
.
iph
->
ttl
==
info
->
ttl
);
break
;
break
;
case
IPT_TTL_NE
:
case
IPT_TTL_NE
:
return
(
!
(
iph
->
ttl
==
info
->
ttl
));
return
(
!
(
skb
->
nh
.
iph
->
ttl
==
info
->
ttl
));
break
;
break
;
case
IPT_TTL_LT
:
case
IPT_TTL_LT
:
return
(
iph
->
ttl
<
info
->
ttl
);
return
(
skb
->
nh
.
iph
->
ttl
<
info
->
ttl
);
break
;
break
;
case
IPT_TTL_GT
:
case
IPT_TTL_GT
:
return
(
iph
->
ttl
>
info
->
ttl
);
return
(
skb
->
nh
.
iph
->
ttl
>
info
->
ttl
);
break
;
break
;
default:
default:
printk
(
KERN_WARNING
"ipt_ttl: unknown mode %d
\n
"
,
printk
(
KERN_WARNING
"ipt_ttl: unknown mode %d
\n
"
,
...
...
net/ipv4/netfilter/ipt_unclean.c
View file @
73baeace
...
@@ -31,16 +31,17 @@ struct icmp_info
...
@@ -31,16 +31,17 @@ struct icmp_info
};
};
static
int
static
int
check_ip
(
struct
iphdr
*
iph
,
size_t
length
,
int
embedded
);
check_ip
(
const
struct
sk_buff
*
skb
,
unsigned
int
offset
);
/* ICMP-specific checks. */
/* ICMP-specific checks. */
static
int
static
int
check_icmp
(
const
struct
icmphdr
*
icmph
,
check_icmp
(
const
struct
sk_buff
*
skb
,
u_int16_t
datalen
,
unsigned
int
offset
,
unsigned
int
offset
,
unsigned
int
fragoff
,
int
more_frags
,
int
more_frags
,
int
embedded
)
int
embedded
)
{
{
struct
icmphdr
icmph
;
static
struct
icmp_info
info
[]
static
struct
icmp_info
info
[]
=
{
[
ICMP_ECHOREPLY
]
=
{
[
ICMP_ECHOREPLY
]
=
{
8
,
65536
,
ICMP_NOT_ERROR
,
0
,
0
},
=
{
8
,
65536
,
ICMP_NOT_ERROR
,
0
,
0
},
...
@@ -76,92 +77,95 @@ check_icmp(const struct icmphdr *icmph,
...
@@ -76,92 +77,95 @@ check_icmp(const struct icmphdr *icmph,
=
{
12
,
12
,
ICMP_NOT_ERROR
,
0
,
0
}
};
=
{
12
,
12
,
ICMP_NOT_ERROR
,
0
,
0
}
};
/* Can't do anything if it's a fragment. */
/* Can't do anything if it's a fragment. */
if
(
offset
)
if
(
fragoff
)
return
1
;
return
1
;
/*
Must cover type and code
. */
/*
CHECK: Must have whole header.
. */
if
(
datalen
<
2
)
{
if
(
skb_copy_bits
(
skb
,
offset
,
&
icmph
,
sizeof
(
icmph
))
<
0
)
{
limpk
(
"ICMP len=%u too short
\n
"
,
datalen
);
limpk
(
"ICMP len=%u too short
\n
"
,
skb
->
len
-
offset
);
return
0
;
return
0
;
}
}
/* If not embedded. */
/* If not embedded
in an ICMP error already
. */
if
(
!
embedded
)
{
if
(
!
embedded
)
{
/* Bad checksum? Don't print, just ignore. */
if
(
!
more_frags
&&
ip_compute_csum
((
unsigned
char
*
)
icmph
,
datalen
)
!=
0
)
return
0
;
/* CHECK: Truncated ICMP (even if first fragment). */
/* CHECK: Truncated ICMP (even if first fragment). */
if
(
icmph
->
type
<
sizeof
(
info
)
/
sizeof
(
struct
icmp_info
)
if
(
icmph
.
type
<
sizeof
(
info
)
/
sizeof
(
struct
icmp_info
)
&&
info
[
icmph
->
type
].
min_len
!=
0
&&
info
[
icmph
.
type
].
min_len
!=
0
&&
datalen
<
info
[
icmph
->
type
].
min_len
)
{
&&
skb
->
len
-
offset
<
info
[
icmph
.
type
].
min_len
)
{
limpk
(
"ICMP type %u len %u too short
\n
"
,
limpk
(
"ICMP type %u len %u too short
\n
"
,
icmph
->
type
,
datalen
);
icmph
.
type
,
skb
->
len
-
offset
);
return
0
;
return
0
;
}
}
/* CHECK: Check within known error ICMPs. */
/* CHECK: Check within known error ICMPs. */
if
(
icmph
->
type
<
sizeof
(
info
)
/
sizeof
(
struct
icmp_info
)
if
(
icmph
.
type
<
sizeof
(
info
)
/
sizeof
(
struct
icmp_info
)
&&
info
[
icmph
->
type
].
err
==
ICMP_IS_ERROR
)
{
&&
info
[
icmph
.
type
].
err
==
ICMP_IS_ERROR
)
{
/* Max IP header size = 60 */
char
inner
[
60
+
8
];
struct
iphdr
*
inner_ip
=
(
struct
iphdr
*
)
inner
;
/* CHECK: Embedded packet must be at least
/* CHECK: Embedded packet must be at least
length of iph + 8 bytes. */
length of iph + 8 bytes. */
struct
iphdr
*
inner
=
(
void
*
)
icmph
+
8
;
if
(
skb_copy_bits
(
skb
,
offset
+
sizeof
(
icmph
),
inner
,
sizeof
(
struct
iphdr
)
+
8
)
<
0
)
{
/* datalen > 8 since all ICMP_IS_ERROR types
have min length > 8 */
if
(
datalen
-
8
<
sizeof
(
struct
iphdr
))
{
limpk
(
"ICMP error internal way too short
\n
"
);
limpk
(
"ICMP error internal way too short
\n
"
);
return
0
;
return
0
;
}
}
if
(
datalen
-
8
<
inner
->
ihl
*
4
+
8
)
{
/* iphhdr may actually be longer: still need 8
actual protocol bytes. */
if
(
offset
+
sizeof
(
icmph
)
+
inner_ip
->
ihl
*
4
+
8
>
skb
->
len
)
{
limpk
(
"ICMP error internal too short
\n
"
);
limpk
(
"ICMP error internal too short
\n
"
);
return
0
;
return
0
;
}
}
if
(
!
check_ip
(
inner
,
datalen
-
8
,
1
))
if
(
!
check_ip
(
skb
,
offset
+
sizeof
(
icmph
)
))
return
0
;
return
0
;
}
}
}
else
{
}
else
{
/* CHECK: Can't embed ICMP unless known non-error. */
/* CHECK: Can't embed ICMP unless known non-error. */
if
(
icmph
->
type
>=
sizeof
(
info
)
/
sizeof
(
struct
icmp_info
)
if
(
icmph
.
type
>=
sizeof
(
info
)
/
sizeof
(
struct
icmp_info
)
||
info
[
icmph
->
type
].
err
!=
ICMP_NOT_ERROR
)
{
||
info
[
icmph
.
type
].
err
!=
ICMP_NOT_ERROR
)
{
limpk
(
"ICMP type %u not embeddable
\n
"
,
limpk
(
"ICMP type %u not embeddable
\n
"
,
icmph
->
type
);
icmph
.
type
);
return
0
;
return
0
;
}
}
}
}
/* CHECK: Invalid ICMP codes. */
/* CHECK: Invalid ICMP codes. */
if
(
icmph
->
type
<
sizeof
(
info
)
/
sizeof
(
struct
icmp_info
)
if
(
icmph
.
type
<
sizeof
(
info
)
/
sizeof
(
struct
icmp_info
)
&&
(
icmph
->
code
<
info
[
icmph
->
type
].
min_code
&&
(
icmph
.
code
<
info
[
icmph
.
type
].
min_code
||
icmph
->
code
>
info
[
icmph
->
type
].
max_code
))
{
||
icmph
.
code
>
info
[
icmph
.
type
].
max_code
))
{
limpk
(
"ICMP type=%u code=%u
\n
"
,
limpk
(
"ICMP type=%u code=%u
\n
"
,
icmph
->
type
,
icmph
->
code
);
icmph
.
type
,
icmph
.
code
);
return
0
;
return
0
;
}
}
/* CHECK: Above maximum length. */
/* CHECK: Above maximum length. */
if
(
icmph
->
type
<
sizeof
(
info
)
/
sizeof
(
struct
icmp_info
)
if
(
icmph
.
type
<
sizeof
(
info
)
/
sizeof
(
struct
icmp_info
)
&&
info
[
icmph
->
type
].
max_len
!=
0
&&
info
[
icmph
.
type
].
max_len
!=
0
&&
datalen
>
info
[
icmph
->
type
].
max_len
)
{
&&
skb
->
len
-
offset
>
info
[
icmph
.
type
].
max_len
)
{
limpk
(
"ICMP type=%u too long: %u bytes
\n
"
,
limpk
(
"ICMP type=%u too long: %u bytes
\n
"
,
icmph
->
type
,
datalen
);
icmph
.
type
,
skb
->
len
-
offset
);
return
0
;
return
0
;
}
}
switch
(
icmph
->
type
)
{
switch
(
icmph
.
type
)
{
case
ICMP_PARAMETERPROB
:
{
case
ICMP_PARAMETERPROB
:
{
/* CHECK: Problem param must be within error packet's
/* CHECK: Problem param must be within error packet's
* IP header. */
* IP header. */
struct
iphdr
*
iph
=
(
void
*
)
icmph
+
8
;
u_int32_t
arg
=
ntohl
(
icmph
.
un
.
gateway
);
u_int32_t
arg
=
ntohl
(
icmph
->
un
.
gateway
);
if
(
icmph
->
code
==
0
)
{
if
(
icmph
.
code
==
0
)
{
/* We've already made sure it's long enough. */
struct
iphdr
iph
;
skb_copy_bits
(
skb
,
offset
+
sizeof
(
icmph
),
&
iph
,
sizeof
(
iph
));
/* Code 0 means that upper 8 bits is pointer
/* Code 0 means that upper 8 bits is pointer
to problem. */
to problem. */
if
((
arg
>>
24
)
>=
iph
->
ihl
*
4
)
{
if
((
arg
>>
24
)
>=
iph
.
ihl
*
4
)
{
limpk
(
"ICMP PARAMETERPROB ptr = %u
\n
"
,
limpk
(
"ICMP PARAMETERPROB ptr = %u
\n
"
,
ntohl
(
icmph
->
un
.
gateway
)
>>
24
);
ntohl
(
icmph
.
un
.
gateway
)
>>
24
);
return
0
;
return
0
;
}
}
arg
&=
0x00FFFFFF
;
arg
&=
0x00FFFFFF
;
...
@@ -179,9 +183,9 @@ check_icmp(const struct icmphdr *icmph,
...
@@ -179,9 +183,9 @@ check_icmp(const struct icmphdr *icmph,
case
ICMP_TIME_EXCEEDED
:
case
ICMP_TIME_EXCEEDED
:
case
ICMP_SOURCE_QUENCH
:
case
ICMP_SOURCE_QUENCH
:
/* CHECK: Unused must be zero. */
/* CHECK: Unused must be zero. */
if
(
icmph
->
un
.
gateway
!=
0
)
{
if
(
icmph
.
un
.
gateway
!=
0
)
{
limpk
(
"ICMP type=%u unused = %u
\n
"
,
limpk
(
"ICMP type=%u unused = %u
\n
"
,
icmph
->
type
,
ntohl
(
icmph
->
un
.
gateway
));
icmph
.
type
,
ntohl
(
icmph
.
un
.
gateway
));
return
0
;
return
0
;
}
}
break
;
break
;
...
@@ -192,32 +196,26 @@ check_icmp(const struct icmphdr *icmph,
...
@@ -192,32 +196,26 @@ check_icmp(const struct icmphdr *icmph,
/* UDP-specific checks. */
/* UDP-specific checks. */
static
int
static
int
check_udp
(
const
struct
iphdr
*
iph
,
check_udp
(
const
struct
sk_buff
*
skb
,
const
struct
udphdr
*
udph
,
u_int16_t
datalen
,
unsigned
int
offset
,
unsigned
int
offset
,
unsigned
int
fragoff
,
int
more_frags
,
int
more_frags
,
int
embedded
)
int
embedded
)
{
{
struct
udphdr
udph
;
/* Can't do anything if it's a fragment. */
/* Can't do anything if it's a fragment. */
if
(
offset
)
if
(
fragoff
)
return
1
;
return
1
;
/* CHECK: Must cover UDP header. */
/* CHECK: Must cover UDP header. */
if
(
datalen
<
sizeof
(
struct
udphdr
)
)
{
if
(
skb_copy_bits
(
skb
,
offset
,
&
udph
,
sizeof
(
udph
))
<
0
)
{
limpk
(
"UDP len=%u too short
\n
"
,
datalen
);
limpk
(
"UDP len=%u too short
\n
"
,
skb
->
len
-
offset
);
return
0
;
return
0
;
}
}
/* Bad checksum? Don't print, just say it's unclean. */
/* FIXME: SRC ROUTE packets won't match checksum --RR */
if
(
!
more_frags
&&
!
embedded
&&
udph
->
check
&&
csum_tcpudp_magic
(
iph
->
saddr
,
iph
->
daddr
,
datalen
,
IPPROTO_UDP
,
csum_partial
((
char
*
)
udph
,
datalen
,
0
))
!=
0
)
return
0
;
/* CHECK: Destination port can't be zero. */
/* CHECK: Destination port can't be zero. */
if
(
!
udph
->
dest
)
{
if
(
!
udph
.
dest
)
{
limpk
(
"UDP zero destination port
\n
"
);
limpk
(
"UDP zero destination port
\n
"
);
return
0
;
return
0
;
}
}
...
@@ -225,24 +223,24 @@ check_udp(const struct iphdr *iph,
...
@@ -225,24 +223,24 @@ check_udp(const struct iphdr *iph,
if
(
!
more_frags
)
{
if
(
!
more_frags
)
{
if
(
!
embedded
)
{
if
(
!
embedded
)
{
/* CHECK: UDP length must match. */
/* CHECK: UDP length must match. */
if
(
ntohs
(
udph
->
len
)
!=
datalen
)
{
if
(
ntohs
(
udph
.
len
)
!=
skb
->
len
-
offset
)
{
limpk
(
"UDP len too short %u vs %u
\n
"
,
limpk
(
"UDP len too short %u vs %u
\n
"
,
ntohs
(
udph
->
len
),
datalen
);
ntohs
(
udph
.
len
),
skb
->
len
-
offset
);
return
0
;
return
0
;
}
}
}
else
{
}
else
{
/* CHECK: UDP length be >= this truncated pkt. */
/* CHECK: UDP length be >= this truncated pkt. */
if
(
ntohs
(
udph
->
len
)
<
datalen
)
{
if
(
ntohs
(
udph
.
len
)
<
skb
->
len
-
offset
)
{
limpk
(
"UDP len too long %u vs %u
\n
"
,
limpk
(
"UDP len too long %u vs %u
\n
"
,
ntohs
(
udph
->
len
),
datalen
);
ntohs
(
udph
.
len
),
skb
->
len
-
offset
);
return
0
;
return
0
;
}
}
}
}
}
else
{
}
else
{
/* CHECK: UDP length must be > this frag's length. */
/* CHECK: UDP length must be > this frag's length. */
if
(
ntohs
(
udph
->
len
)
<=
datalen
)
{
if
(
ntohs
(
udph
.
len
)
<=
skb
->
len
-
offset
)
{
limpk
(
"UDP fragment len too short %u vs %u
\n
"
,
limpk
(
"UDP fragment len too short %u vs %u
\n
"
,
ntohs
(
udph
->
len
),
datalen
);
ntohs
(
udph
.
len
),
skb
->
len
-
offset
);
return
0
;
return
0
;
}
}
}
}
...
@@ -250,104 +248,104 @@ check_udp(const struct iphdr *iph,
...
@@ -250,104 +248,104 @@ check_udp(const struct iphdr *iph,
return
1
;
return
1
;
}
}
#define TH_FIN 0x01
#define TH_SYN 0x02
#define TH_RST 0x04
#define TH_PUSH 0x08
#define TH_ACK 0x10
#define TH_URG 0x20
#define TH_ECE 0x40
#define TH_CWR 0x80
/* TCP-specific checks. */
/* TCP-specific checks. */
static
int
static
int
check_tcp
(
const
struct
iphdr
*
iph
,
check_tcp
(
const
struct
sk_buff
*
skb
,
const
struct
tcphdr
*
tcph
,
u_int16_t
datalen
,
unsigned
int
offset
,
unsigned
int
offset
,
unsigned
int
fragoff
,
int
more_frags
,
int
more_frags
,
int
embedded
)
int
embedded
)
{
{
u_int8_t
*
opt
=
(
u_int8_t
*
)
tcph
;
struct
tcphdr
tcph
;
u
_int8_t
*
endhdr
=
(
u_int8_t
*
)
tcph
+
tcph
->
doff
*
4
;
u
nsigned
char
opt
[
15
*
4
-
sizeof
(
struct
tcphdr
)]
;
u
_int8_t
tcpflags
;
u
32
tcpflags
;
int
end_of_options
=
0
;
int
end_of_options
=
0
;
size_t
i
;
unsigned
int
i
,
optlen
;
/* CHECK: Can't have offset=1: used to override TCP syn-checks. */
/* CHECK: Can't have offset=1: used to override TCP syn-checks. */
/* In fact, this is caught below (offset < 516). */
/* In fact, this is caught below (offset < 516). */
/* Can't do anything if it's a fragment. */
/* Can't do anything if it's a fragment. */
if
(
offset
)
if
(
fragoff
)
return
1
;
return
1
;
/* CHECK: Smaller than minimal TCP hdr. */
/* CHECK: Smaller than minimal TCP hdr. */
if
(
datalen
<
sizeof
(
struct
tcphdr
))
{
if
(
skb_copy_bits
(
skb
,
offset
,
&
tcph
,
sizeof
(
tcph
))
<
0
)
{
u16
ports
[
2
];
if
(
!
embedded
)
{
if
(
!
embedded
)
{
limpk
(
"Packet length %u < TCP header.
\n
"
,
datalen
);
limpk
(
"Packet length %u < TCP header.
\n
"
,
skb
->
len
-
offset
);
return
0
;
return
0
;
}
}
/* Must have ports available (datalen >= 8), from
/* Must have ports available (datalen >= 8), from
check_icmp which set embedded = 1 */
check_icmp which set embedded = 1 */
/* CHECK: TCP ports inside ICMP error */
/* CHECK: TCP ports inside ICMP error */
if
(
!
tcph
->
source
||
!
tcph
->
dest
)
{
skb_copy_bits
(
skb
,
offset
,
ports
,
sizeof
(
ports
));
if
(
!
ports
[
0
]
||
!
ports
[
1
])
{
limpk
(
"Zero TCP ports %u/%u.
\n
"
,
limpk
(
"Zero TCP ports %u/%u.
\n
"
,
htons
(
tcph
->
source
),
htons
(
tcph
->
dest
));
htons
(
ports
[
0
]),
htons
(
ports
[
1
]
));
return
0
;
return
0
;
}
}
return
1
;
return
1
;
}
}
/* CHECK: Smaller than actual TCP hdr. */
/* CHECK: TCP header claims tiny size. */
if
(
datalen
<
tcph
->
doff
*
4
)
{
if
(
tcph
.
doff
*
4
<
sizeof
(
tcph
))
{
limpk
(
"TCP header claims tiny size %u
\n
"
,
tcph
.
doff
*
4
);
return
0
;
}
/* CHECK: Packet smaller than actual TCP hdr. */
optlen
=
tcph
.
doff
*
4
-
sizeof
(
tcph
);
if
(
skb_copy_bits
(
skb
,
offset
+
sizeof
(
tcph
),
opt
,
optlen
)
<
0
)
{
if
(
!
embedded
)
{
if
(
!
embedded
)
{
limpk
(
"Packet length %u < actual TCP header.
\n
"
,
limpk
(
"Packet length %u < actual TCP header.
\n
"
,
datalen
);
skb
->
len
-
offset
);
return
0
;
return
0
;
}
else
}
else
return
1
;
return
1
;
}
}
/* Bad checksum? Don't print, just say it's unclean. */
/* FIXME: SRC ROUTE packets won't match checksum --RR */
if
(
!
more_frags
&&
!
embedded
&&
csum_tcpudp_magic
(
iph
->
saddr
,
iph
->
daddr
,
datalen
,
IPPROTO_TCP
,
csum_partial
((
char
*
)
tcph
,
datalen
,
0
))
!=
0
)
return
0
;
/* CHECK: TCP ports non-zero */
/* CHECK: TCP ports non-zero */
if
(
!
tcph
->
source
||
!
tcph
->
dest
)
{
if
(
!
tcph
.
source
||
!
tcph
.
dest
)
{
limpk
(
"Zero TCP ports %u/%u.
\n
"
,
limpk
(
"Zero TCP ports %u/%u.
\n
"
,
htons
(
tcph
->
source
),
htons
(
tcph
->
dest
));
htons
(
tcph
.
source
),
htons
(
tcph
.
dest
));
return
0
;
return
0
;
}
}
tcpflags
=
tcp_flag_word
(
&
tcph
);
/* CHECK: TCP reserved bits zero. */
/* CHECK: TCP reserved bits zero. */
if
(
tcp_flag_word
(
tcph
)
&
TCP_RESERVED_BITS
)
{
if
(
tcpflags
&
TCP_RESERVED_BITS
)
{
limpk
(
"TCP reserved bits not zero
\n
"
);
limpk
(
"TCP reserved bits not zero
\n
"
);
return
0
;
return
0
;
}
}
tcpflags
&=
~
(
TCP_DATA_OFFSET
|
TCP_FLAG_CWR
|
TCP_FLAG_ECE
|
__constant_htonl
(
0x0000FFFF
));
/* CHECK: TCP flags. */
/* CHECK: TCP flags. */
tcpflags
=
(((
u_int8_t
*
)
tcph
)[
13
]
&
~
(
TH_ECE
|
TH_CWR
));
if
(
tcpflags
!=
TCP_FLAG_SYN
if
(
tcpflags
!=
TH_SYN
&&
tcpflags
!=
(
TCP_FLAG_SYN
|
TCP_FLAG_ACK
)
&&
tcpflags
!=
(
TH_SYN
|
TH_ACK
)
&&
tcpflags
!=
TCP_FLAG_RST
&&
tcpflags
!=
TH_RST
&&
tcpflags
!=
(
TCP_FLAG_RST
|
TCP_FLAG_ACK
)
&&
tcpflags
!=
(
T
H_RST
|
TH_ACK
)
&&
tcpflags
!=
(
T
CP_FLAG_RST
|
TCP_FLAG_ACK
|
TCP_FLAG_PSH
)
&&
tcpflags
!=
(
T
H_RST
|
TH_ACK
|
TH_PUSH
)
&&
tcpflags
!=
(
T
CP_FLAG_FIN
|
TCP_FLAG_ACK
)
&&
tcpflags
!=
(
TH_FIN
|
TH_ACK
)
&&
tcpflags
!=
TCP_FLAG_ACK
&&
tcpflags
!=
TH_ACK
&&
tcpflags
!=
(
TCP_FLAG_ACK
|
TCP_FLAG_PSH
)
&&
tcpflags
!=
(
T
H_ACK
|
TH_PUSH
)
&&
tcpflags
!=
(
T
CP_FLAG_ACK
|
TCP_FLAG_URG
)
&&
tcpflags
!=
(
T
H_ACK
|
TH_URG
)
&&
tcpflags
!=
(
T
CP_FLAG_ACK
|
TCP_FLAG_URG
|
TCP_FLAG_PSH
)
&&
tcpflags
!=
(
T
H_ACK
|
TH_URG
|
TH_PU
SH
)
&&
tcpflags
!=
(
T
CP_FLAG_FIN
|
TCP_FLAG_ACK
|
TCP_FLAG_P
SH
)
&&
tcpflags
!=
(
T
H_FIN
|
TH_ACK
|
TH_PUSH
)
&&
tcpflags
!=
(
T
CP_FLAG_FIN
|
TCP_FLAG_ACK
|
TCP_FLAG_URG
)
&&
tcpflags
!=
(
T
H_FIN
|
TH_ACK
|
TH_URG
)
&&
tcpflags
!=
(
T
CP_FLAG_FIN
|
TCP_FLAG_ACK
|
TCP_FLAG_URG
&&
tcpflags
!=
(
TH_FIN
|
TH_ACK
|
TH_URG
|
TH_PU
SH
))
{
|
TCP_FLAG_P
SH
))
{
limpk
(
"TCP flags bad:
%u
\n
"
,
tcpflags
);
limpk
(
"TCP flags bad:
0x%04X
\n
"
,
ntohl
(
tcpflags
)
>>
16
);
return
0
;
return
0
;
}
}
for
(
i
=
sizeof
(
struct
tcphdr
);
i
<
tcph
->
doff
*
4
;
)
{
for
(
i
=
0
;
i
<
optlen
;
)
{
switch
(
opt
[
i
])
{
switch
(
opt
[
i
])
{
case
0
:
case
0
:
end_of_options
=
1
;
end_of_options
=
1
;
...
@@ -364,7 +362,7 @@ check_tcp(const struct iphdr *iph,
...
@@ -364,7 +362,7 @@ check_tcp(const struct iphdr *iph,
return
0
;
return
0
;
}
}
/* CHECK: options at tail. */
/* CHECK: options at tail. */
else
if
(
i
+
1
>=
tcph
->
doff
*
4
)
{
else
if
(
i
+
1
>=
optlen
)
{
limpk
(
"TCP option %u at tail
\n
"
,
limpk
(
"TCP option %u at tail
\n
"
,
opt
[
i
]);
opt
[
i
]);
return
0
;
return
0
;
...
@@ -376,8 +374,8 @@ check_tcp(const struct iphdr *iph,
...
@@ -376,8 +374,8 @@ check_tcp(const struct iphdr *iph,
return
0
;
return
0
;
}
}
/* CHECK: oversize options. */
/* CHECK: oversize options. */
else
if
(
&
opt
[
i
]
+
opt
[
i
+
1
]
>
endhdr
)
{
else
if
(
i
+
opt
[
i
+
1
]
>
optlen
)
{
limpk
(
"TCP option %u at %
Z
u too long
\n
"
,
limpk
(
"TCP option %u at %u too long
\n
"
,
(
unsigned
int
)
opt
[
i
],
i
);
(
unsigned
int
)
opt
[
i
],
i
);
return
0
;
return
0
;
}
}
...
@@ -392,34 +390,44 @@ check_tcp(const struct iphdr *iph,
...
@@ -392,34 +390,44 @@ check_tcp(const struct iphdr *iph,
/* Returns 1 if ok */
/* Returns 1 if ok */
/* Standard IP checks. */
/* Standard IP checks. */
static
int
static
int
check_ip
(
struct
iphdr
*
iph
,
size_t
length
,
int
embedded
)
check_ip
(
const
struct
sk_buff
*
skb
,
unsigned
int
offset
)
{
{
u_int8_t
*
opt
=
(
u_int8_t
*
)
iph
;
u_int8_t
*
endhdr
=
(
u_int8_t
*
)
iph
+
iph
->
ihl
*
4
;
int
end_of_options
=
0
;
int
end_of_options
=
0
;
void
*
protoh
;
unsigned
int
datalen
,
optlen
;
size_t
datalen
;
unsigned
int
i
;
unsigned
int
i
;
unsigned
int
offset
;
unsigned
int
fragoff
;
struct
iphdr
iph
;
unsigned
char
opt
[
15
*
4
-
sizeof
(
struct
iphdr
)];
int
embedded
=
offset
;
/* Should only happen for local outgoing raw-socket packets. */
/* Should only happen for local outgoing raw-socket packets. */
/* CHECK: length >= ip header. */
/* CHECK: length >= ip header. */
if
(
length
<
sizeof
(
struct
iphdr
)
||
length
<
iph
->
ihl
*
4
)
{
if
(
skb_copy_bits
(
skb
,
offset
,
&
iph
,
sizeof
(
iph
))
<
0
)
{
limpk
(
"Packet length %Zu < IP header.
\n
"
,
length
);
limpk
(
"Packet length %u < IP header.
\n
"
,
skb
->
len
-
offset
);
return
0
;
}
if
(
iph
.
ihl
*
4
<
sizeof
(
iph
))
{
limpk
(
"IP len %u < minimum IP header.
\n
"
,
iph
.
ihl
*
4
);
return
0
;
}
optlen
=
iph
.
ihl
*
4
-
sizeof
(
iph
);
if
(
skb_copy_bits
(
skb
,
offset
+
sizeof
(
struct
iphdr
),
opt
,
optlen
)
<
0
)
{
limpk
(
"Packet length %u < IP header %u.
\n
"
,
skb
->
len
-
offset
,
iph
.
ihl
*
4
);
return
0
;
return
0
;
}
}
offset
=
ntohs
(
iph
->
frag_off
)
&
IP_OFFSET
;
fragoff
=
(
ntohs
(
iph
.
frag_off
)
&
IP_OFFSET
);
protoh
=
(
void
*
)
iph
+
iph
->
ihl
*
4
;
datalen
=
skb
->
len
-
(
offset
+
sizeof
(
struct
iphdr
)
+
optlen
);
datalen
=
length
-
iph
->
ihl
*
4
;
/* CHECK: Embedded fragment. */
/* CHECK: Embedded fragment. */
if
(
embedded
&&
offset
)
{
if
(
offset
&&
fragoff
)
{
limpk
(
"Embedded fragment.
\n
"
);
limpk
(
"Embedded fragment.
\n
"
);
return
0
;
return
0
;
}
}
for
(
i
=
sizeof
(
struct
iphdr
);
i
<
iph
->
ihl
*
4
;
)
{
for
(
i
=
0
;
i
<
optlen
;
)
{
switch
(
opt
[
i
])
{
switch
(
opt
[
i
])
{
case
0
:
case
0
:
end_of_options
=
1
;
end_of_options
=
1
;
...
@@ -436,7 +444,7 @@ check_ip(struct iphdr *iph, size_t length, int embedded)
...
@@ -436,7 +444,7 @@ check_ip(struct iphdr *iph, size_t length, int embedded)
return
0
;
return
0
;
}
}
/* CHECK: options at tail. */
/* CHECK: options at tail. */
else
if
(
i
+
1
>=
iph
->
ihl
*
4
)
{
else
if
(
i
+
1
>=
optlen
)
{
limpk
(
"IP option %u at tail
\n
"
,
limpk
(
"IP option %u at tail
\n
"
,
opt
[
i
]);
opt
[
i
]);
return
0
;
return
0
;
...
@@ -448,7 +456,7 @@ check_ip(struct iphdr *iph, size_t length, int embedded)
...
@@ -448,7 +456,7 @@ check_ip(struct iphdr *iph, size_t length, int embedded)
return
0
;
return
0
;
}
}
/* CHECK: oversize options. */
/* CHECK: oversize options. */
else
if
(
&
opt
[
i
]
+
opt
[
i
+
1
]
>
endhdr
)
{
else
if
(
i
+
opt
[
i
+
1
]
>
optlen
)
{
limpk
(
"IP option %u at %u too long
\n
"
,
limpk
(
"IP option %u at %u too long
\n
"
,
opt
[
i
],
i
);
opt
[
i
],
i
);
return
0
;
return
0
;
...
@@ -461,30 +469,30 @@ check_ip(struct iphdr *iph, size_t length, int embedded)
...
@@ -461,30 +469,30 @@ check_ip(struct iphdr *iph, size_t length, int embedded)
/* Fragment checks. */
/* Fragment checks. */
/* CHECK: More fragments, but doesn't fill 8-byte boundary. */
/* CHECK: More fragments, but doesn't fill 8-byte boundary. */
if
((
ntohs
(
iph
->
frag_off
)
&
IP_MF
)
if
((
ntohs
(
iph
.
frag_off
)
&
IP_MF
)
&&
(
ntohs
(
iph
->
tot_len
)
%
8
)
!=
0
)
{
&&
(
ntohs
(
iph
.
tot_len
)
%
8
)
!=
0
)
{
limpk
(
"Truncated fragment %u long.
\n
"
,
ntohs
(
iph
->
tot_len
));
limpk
(
"Truncated fragment %u long.
\n
"
,
ntohs
(
iph
.
tot_len
));
return
0
;
return
0
;
}
}
/* CHECK: Oversize fragment a-la Ping of Death. */
/* CHECK: Oversize fragment a-la Ping of Death. */
if
(
offset
*
8
+
datalen
>
65535
)
{
if
(
fragoff
*
8
+
datalen
>
65535
)
{
limpk
(
"Oversize fragment to %u.
\n
"
,
offset
*
8
);
limpk
(
"Oversize fragment to %u.
\n
"
,
fragoff
*
8
);
return
0
;
return
0
;
}
}
/* CHECK: DF set and
offset
or MF set. */
/* CHECK: DF set and
fragoff
or MF set. */
if
((
ntohs
(
iph
->
frag_off
)
&
IP_DF
)
if
((
ntohs
(
iph
.
frag_off
)
&
IP_DF
)
&&
(
offset
||
(
ntohs
(
iph
->
frag_off
)
&
IP_MF
)))
{
&&
(
fragoff
||
(
ntohs
(
iph
.
frag_off
)
&
IP_MF
)))
{
limpk
(
"DF set and offset=%u, MF=%u.
\n
"
,
limpk
(
"DF set and offset=%u, MF=%u.
\n
"
,
offset
,
ntohs
(
iph
->
frag_off
)
&
IP_MF
);
fragoff
,
ntohs
(
iph
.
frag_off
)
&
IP_MF
);
return
0
;
return
0
;
}
}
/* CHECK: Zero-sized fragments. */
/* CHECK: Zero-sized fragments. */
if
((
offset
||
(
ntohs
(
iph
->
frag_off
)
&
IP_MF
))
if
((
fragoff
||
(
ntohs
(
iph
.
frag_off
)
&
IP_MF
))
&&
datalen
==
0
)
{
&&
datalen
==
0
)
{
limpk
(
"Zero size fragment offset=%u
\n
"
,
offset
);
limpk
(
"Zero size fragment offset=%u
\n
"
,
fragoff
);
return
0
;
return
0
;
}
}
...
@@ -500,52 +508,54 @@ check_ip(struct iphdr *iph, size_t length, int embedded)
...
@@ -500,52 +508,54 @@ check_ip(struct iphdr *iph, size_t length, int embedded)
here. */
here. */
#define MIN_LIKELY_MTU 128
#define MIN_LIKELY_MTU 128
/* CHECK: Min size of first frag = 128. */
/* CHECK: Min size of first frag = 128. */
if
((
ntohs
(
iph
->
frag_off
)
&
IP_MF
)
if
((
ntohs
(
iph
.
frag_off
)
&
IP_MF
)
&&
offset
==
0
&&
fragoff
==
0
&&
ntohs
(
iph
->
tot_len
)
<
MIN_LIKELY_MTU
)
{
&&
ntohs
(
iph
.
tot_len
)
<
MIN_LIKELY_MTU
)
{
limpk
(
"First fragment size %u < %u
\n
"
,
ntohs
(
iph
->
tot_len
),
limpk
(
"First fragment size %u < %u
\n
"
,
ntohs
(
iph
.
tot_len
),
MIN_LIKELY_MTU
);
MIN_LIKELY_MTU
);
return
0
;
return
0
;
}
}
/* CHECK: Min offset of frag = 128 - IP hdr len. */
/* CHECK: Min offset of frag = 128 - IP hdr len. */
if
(
offset
&&
offset
*
8
<
MIN_LIKELY_MTU
-
iph
->
ihl
*
4
)
{
if
(
fragoff
&&
fragoff
*
8
<
MIN_LIKELY_MTU
-
iph
.
ihl
*
4
)
{
limpk
(
"Fragment starts at %u < %u
\n
"
,
offset
*
8
,
limpk
(
"Fragment starts at %u < %u
\n
"
,
fragoff
*
8
,
MIN_LIKELY_MTU
-
iph
->
ihl
*
4
);
MIN_LIKELY_MTU
-
iph
.
ihl
*
4
);
return
0
;
return
0
;
}
}
/* CHECK: Protocol specification non-zero. */
/* CHECK: Protocol specification non-zero. */
if
(
iph
->
protocol
==
0
)
{
if
(
iph
.
protocol
==
0
)
{
limpk
(
"Zero protocol
\n
"
);
limpk
(
"Zero protocol
\n
"
);
return
0
;
return
0
;
}
}
/* FIXME: This is already checked for in "Oversize fragment"
above --RR */
/* CHECK: Do not use what is unused.
/* CHECK: Do not use what is unused.
* First bit of fragmentation flags should be unused.
* First bit of fragmentation flags should be unused.
* May be used by OS fingerprinting tools.
* May be used by OS fingerprinting tools.
* 04 Jun 2002, Maciej Soltysiak, solt@dns.toxicfilms.tv
* 04 Jun 2002, Maciej Soltysiak, solt@dns.toxicfilms.tv
*/
*/
if
(
ntohs
(
iph
->
frag_off
)
>>
15
)
{
if
(
ntohs
(
iph
.
frag_off
)
>>
15
)
{
limpk
(
"IP unused bit set
\n
"
);
limpk
(
"IP unused bit set
\n
"
);
return
0
;
return
0
;
}
}
/* Per-protocol checks. */
/* Per-protocol checks. */
switch
(
iph
->
protocol
)
{
switch
(
iph
.
protocol
)
{
case
IPPROTO_ICMP
:
case
IPPROTO_ICMP
:
return
check_icmp
(
protoh
,
datalen
,
offset
,
return
check_icmp
(
skb
,
offset
+
iph
.
ihl
*
4
,
fragoff
,
(
ntohs
(
iph
->
frag_off
)
&
IP_MF
),
(
ntohs
(
iph
.
frag_off
)
&
IP_MF
),
embedded
);
embedded
);
case
IPPROTO_UDP
:
case
IPPROTO_UDP
:
return
check_udp
(
iph
,
protoh
,
datalen
,
offset
,
return
check_udp
(
skb
,
offset
+
iph
.
ihl
*
4
,
fragoff
,
(
ntohs
(
iph
->
frag_off
)
&
IP_MF
),
(
ntohs
(
iph
.
frag_off
)
&
IP_MF
),
embedded
);
embedded
);
case
IPPROTO_TCP
:
case
IPPROTO_TCP
:
return
check_tcp
(
iph
,
protoh
,
datalen
,
offset
,
return
check_tcp
(
skb
,
offset
+
iph
.
ihl
*
4
,
fragoff
,
(
ntohs
(
iph
->
frag_off
)
&
IP_MF
),
(
ntohs
(
iph
.
frag_off
)
&
IP_MF
),
embedded
);
embedded
);
default:
default:
/* Ignorance is bliss. */
/* Ignorance is bliss. */
...
@@ -559,11 +569,9 @@ match(const struct sk_buff *skb,
...
@@ -559,11 +569,9 @@ match(const struct sk_buff *skb,
const
struct
net_device
*
out
,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
const
void
*
matchinfo
,
int
offset
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
int
*
hotdrop
)
int
*
hotdrop
)
{
{
return
!
check_ip
(
skb
->
nh
.
iph
,
skb
->
len
,
0
);
return
!
check_ip
(
skb
,
0
);
}
}
/* Called when user tries to insert an entry of this type. */
/* Called when user tries to insert an entry of this type. */
...
...
net/ipv6/anycast.c
View file @
73baeace
...
@@ -127,8 +127,8 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, struct in6_addr *addr)
...
@@ -127,8 +127,8 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, struct in6_addr *addr)
dev_hold
(
dev
);
dev_hold
(
dev
);
dst_release
(
&
rt
->
u
.
dst
);
dst_release
(
&
rt
->
u
.
dst
);
}
else
if
(
ishost
)
{
}
else
if
(
ishost
)
{
sock_kfree_s
(
sk
,
pac
,
sizeof
(
*
pac
))
;
err
=
-
EADDRNOTAVAIL
;
return
-
EADDRNOTAVAIL
;
goto
out_free_pac
;
}
else
{
}
else
{
/* router, no matching interface: just pick one */
/* router, no matching interface: just pick one */
...
@@ -138,18 +138,17 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, struct in6_addr *addr)
...
@@ -138,18 +138,17 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, struct in6_addr *addr)
dev
=
dev_get_by_index
(
ifindex
);
dev
=
dev_get_by_index
(
ifindex
);
if
(
dev
==
NULL
)
{
if
(
dev
==
NULL
)
{
sock_kfree_s
(
sk
,
pac
,
sizeof
(
*
pac
))
;
err
=
-
ENODEV
;
return
-
ENODEV
;
goto
out_free_pac
;
}
}
idev
=
in6_dev_get
(
dev
);
idev
=
in6_dev_get
(
dev
);
if
(
!
idev
)
{
if
(
!
idev
)
{
sock_kfree_s
(
sk
,
pac
,
sizeof
(
*
pac
));
dev_put
(
dev
);
if
(
ifindex
)
if
(
ifindex
)
return
-
ENODEV
;
err
=
-
ENODEV
;
else
else
return
-
EADDRNOTAVAIL
;
err
=
-
EADDRNOTAVAIL
;
goto
out_dev_put
;
}
}
/* reset ishost, now that we have a specific device */
/* reset ishost, now that we have a specific device */
ishost
=
!
idev
->
cnf
.
forwarding
;
ishost
=
!
idev
->
cnf
.
forwarding
;
...
@@ -170,21 +169,17 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, struct in6_addr *addr)
...
@@ -170,21 +169,17 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, struct in6_addr *addr)
err
=
-
EADDRNOTAVAIL
;
err
=
-
EADDRNOTAVAIL
;
else
if
(
!
capable
(
CAP_NET_ADMIN
))
else
if
(
!
capable
(
CAP_NET_ADMIN
))
err
=
-
EPERM
;
err
=
-
EPERM
;
if
(
err
)
{
if
(
err
)
sock_kfree_s
(
sk
,
pac
,
sizeof
(
*
pac
));
goto
out_dev_put
;
dev_put
(
dev
);
return
err
;
}
}
else
if
(
!
(
ipv6_addr_type
(
addr
)
&
IPV6_ADDR_ANYCAST
)
&&
}
else
if
(
!
(
ipv6_addr_type
(
addr
)
&
IPV6_ADDR_ANYCAST
)
&&
!
capable
(
CAP_NET_ADMIN
))
!
capable
(
CAP_NET_ADMIN
))
{
return
-
EPERM
;
err
=
-
EPERM
;
goto
out_dev_put
;
}
err
=
ipv6_dev_ac_inc
(
dev
,
addr
);
err
=
ipv6_dev_ac_inc
(
dev
,
addr
);
if
(
err
)
{
if
(
err
)
sock_kfree_s
(
sk
,
pac
,
sizeof
(
*
pac
));
goto
out_dev_put
;
dev_put
(
dev
);
return
err
;
}
write_lock_bh
(
&
ipv6_sk_ac_lock
);
write_lock_bh
(
&
ipv6_sk_ac_lock
);
pac
->
acl_next
=
np
->
ipv6_ac_list
;
pac
->
acl_next
=
np
->
ipv6_ac_list
;
...
@@ -194,6 +189,12 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, struct in6_addr *addr)
...
@@ -194,6 +189,12 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, struct in6_addr *addr)
dev_put
(
dev
);
dev_put
(
dev
);
return
0
;
return
0
;
out_dev_put:
dev_put
(
dev
);
out_free_pac:
sock_kfree_s
(
sk
,
pac
,
sizeof
(
*
pac
));
return
err
;
}
}
/*
/*
...
...
net/ipv6/ndisc.c
View file @
73baeace
...
@@ -441,8 +441,10 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
...
@@ -441,8 +441,10 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
src_addr
=
solicited_addr
;
src_addr
=
solicited_addr
;
in6_ifa_put
(
ifp
);
in6_ifa_put
(
ifp
);
}
else
{
}
else
{
if
(
ipv6_dev_get_saddr
(
dev
,
daddr
,
&
tmpaddr
,
0
))
if
(
ipv6_dev_get_saddr
(
dev
,
daddr
,
&
tmpaddr
,
0
))
{
dst_free
(
dst
);
return
;
return
;
}
src_addr
=
&
tmpaddr
;
src_addr
=
&
tmpaddr
;
}
}
...
@@ -450,11 +452,10 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
...
@@ -450,11 +452,10 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
ndisc_rt_init
(
rt
,
dev
,
neigh
);
ndisc_rt_init
(
rt
,
dev
,
neigh
);
dst
=
(
struct
dst_entry
*
)
rt
;
dst
=
(
struct
dst_entry
*
)
rt
;
dst_clone
(
dst
);
err
=
xfrm_lookup
(
&
dst
,
&
fl
,
NULL
,
0
);
err
=
xfrm_lookup
(
&
dst
,
&
fl
,
NULL
,
0
);
if
(
err
<
0
)
{
if
(
err
<
0
)
{
dst_
releas
e
(
dst
);
dst_
fre
e
(
dst
);
return
;
return
;
}
}
...
@@ -470,6 +471,7 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
...
@@ -470,6 +471,7 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
if
(
skb
==
NULL
)
{
if
(
skb
==
NULL
)
{
ND_PRINTK1
(
"send_na: alloc skb failed
\n
"
);
ND_PRINTK1
(
"send_na: alloc skb failed
\n
"
);
dst_free
(
dst
);
return
;
return
;
}
}
...
...
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