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
b2928fba
Commit
b2928fba
authored
Oct 24, 2004
by
Patrick McHardy
Browse files
Options
Browse Files
Download
Plain Diff
Merge coreworks.de:/home/kaber/src/bk-repos/net-2.6
into coreworks.de:/home/kaber/src/nf/nf-2.6
parents
4b684d78
e1d8928e
Changes
22
Show whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
629 additions
and
580 deletions
+629
-580
include/linux/netfilter_ipv6/ip6_tables.h
include/linux/netfilter_ipv6/ip6_tables.h
+8
-4
net/ipv4/netfilter/ip_conntrack_core.c
net/ipv4/netfilter/ip_conntrack_core.c
+2
-4
net/ipv4/netfilter/ipt_MASQUERADE.c
net/ipv4/netfilter/ipt_MASQUERADE.c
+20
-29
net/ipv6/netfilter/ip6_tables.c
net/ipv6/netfilter/ip6_tables.c
+119
-129
net/ipv6/netfilter/ip6t_LOG.c
net/ipv6/netfilter/ip6t_LOG.c
+179
-100
net/ipv6/netfilter/ip6t_MARK.c
net/ipv6/netfilter/ip6t_MARK.c
+1
-1
net/ipv6/netfilter/ip6t_ah.c
net/ipv6/netfilter/ip6t_ah.c
+133
-136
net/ipv6/netfilter/ip6t_dst.c
net/ipv6/netfilter/ip6t_dst.c
+1
-2
net/ipv6/netfilter/ip6t_esp.c
net/ipv6/netfilter/ip6t_esp.c
+45
-46
net/ipv6/netfilter/ip6t_eui64.c
net/ipv6/netfilter/ip6t_eui64.c
+1
-2
net/ipv6/netfilter/ip6t_frag.c
net/ipv6/netfilter/ip6t_frag.c
+32
-31
net/ipv6/netfilter/ip6t_hbh.c
net/ipv6/netfilter/ip6t_hbh.c
+1
-2
net/ipv6/netfilter/ip6t_hl.c
net/ipv6/netfilter/ip6t_hl.c
+1
-1
net/ipv6/netfilter/ip6t_ipv6header.c
net/ipv6/netfilter/ip6t_ipv6header.c
+1
-2
net/ipv6/netfilter/ip6t_length.c
net/ipv6/netfilter/ip6t_length.c
+1
-2
net/ipv6/netfilter/ip6t_limit.c
net/ipv6/netfilter/ip6t_limit.c
+1
-2
net/ipv6/netfilter/ip6t_mac.c
net/ipv6/netfilter/ip6t_mac.c
+1
-2
net/ipv6/netfilter/ip6t_mark.c
net/ipv6/netfilter/ip6t_mark.c
+1
-2
net/ipv6/netfilter/ip6t_multiport.c
net/ipv6/netfilter/ip6t_multiport.c
+19
-15
net/ipv6/netfilter/ip6t_owner.c
net/ipv6/netfilter/ip6t_owner.c
+1
-2
net/ipv6/netfilter/ip6t_physdev.c
net/ipv6/netfilter/ip6t_physdev.c
+1
-2
net/ipv6/netfilter/ip6t_rt.c
net/ipv6/netfilter/ip6t_rt.c
+60
-64
No files found.
include/linux/netfilter_ipv6/ip6_tables.h
View file @
b2928fba
...
...
@@ -355,13 +355,15 @@ struct ip6t_match
/* Return true or false: return FALSE and set *hotdrop = 1 to
force immediate packet drop. */
/* Arguments changed since 2.6.9, as this must now handle
non-linear skb, using skb_header_pointer and
skb_ip_make_writable. */
int
(
*
match
)(
const
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
unsigned
int
protoff
,
int
*
hotdrop
);
/* Called when user tries to insert an entry of this type. */
...
...
@@ -386,11 +388,13 @@ struct ip6t_target
const
char
name
[
IP6T_FUNCTION_MAXNAMELEN
];
/* Returns verdict. */
/* Returns verdict. Argument order changed since 2.6.9, as this
must now handle non-linear skbs, using skb_copy_bits and
skb_ip_make_writable. */
unsigned
int
(
*
target
)(
struct
sk_buff
**
pskb
,
unsigned
int
hooknum
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
unsigned
int
hooknum
,
const
void
*
targinfo
,
void
*
userdata
);
...
...
net/ipv4/netfilter/ip_conntrack_core.c
View file @
b2928fba
...
...
@@ -352,16 +352,14 @@ __ip_conntrack_find(const struct ip_conntrack_tuple *tuple,
{
struct
ip_conntrack_tuple_hash
*
h
;
unsigned
int
hash
=
hash_conntrack
(
tuple
);
/* use per_cpu() to avoid multiple calls to smp_processor_id() */
unsigned
int
cpu
=
smp_processor_id
();
MUST_BE_READ_LOCKED
(
&
ip_conntrack_lock
);
list_for_each_entry
(
h
,
&
ip_conntrack_hash
[
hash
],
list
)
{
if
(
conntrack_tuple_cmp
(
h
,
tuple
,
ignored_conntrack
))
{
per_cpu
(
ip_conntrack_stat
,
cpu
).
found
++
;
CONNTRACK_STAT_INC
(
found
)
;
return
h
;
}
per_cpu
(
ip_conntrack_stat
,
cpu
).
searched
++
;
CONNTRACK_STAT_INC
(
searched
)
;
}
return
NULL
;
...
...
net/ipv4/netfilter/ipt_MASQUERADE.c
View file @
b2928fba
...
...
@@ -81,8 +81,8 @@ masquerade_target(struct sk_buff **pskb,
enum
ip_conntrack_info
ctinfo
;
const
struct
ip_nat_multi_range
*
mr
;
struct
ip_nat_multi_range
newrange
;
u_int32_t
newsrc
;
struct
rtable
*
rt
;
u_int32_t
newsrc
;
IP_NF_ASSERT
(
hooknum
==
NF_IP_POST_ROUTING
);
...
...
@@ -96,35 +96,12 @@ masquerade_target(struct sk_buff **pskb,
||
ctinfo
==
IP_CT_RELATED
+
IP_CT_IS_REPLY
));
mr
=
targinfo
;
{
struct
flowi
fl
=
{
.
nl_u
=
{
.
ip4_u
=
{
.
daddr
=
(
*
pskb
)
->
nh
.
iph
->
daddr
,
.
tos
=
(
RT_TOS
((
*
pskb
)
->
nh
.
iph
->
tos
)
|
RTO_CONN
),
#ifdef CONFIG_IP_ROUTE_FWMARK
.
fwmark
=
(
*
pskb
)
->
nfmark
#endif
}
}
};
if
(
ip_route_output_key
(
&
rt
,
&
fl
)
!=
0
)
{
/* Funky routing can do this. */
if
(
net_ratelimit
())
printk
(
"MASQUERADE:"
" No route: Rusty's brain broke!
\n
"
);
rt
=
(
struct
rtable
*
)(
*
pskb
)
->
dst
;
newsrc
=
inet_select_addr
(
out
,
rt
->
rt_gateway
,
RT_SCOPE_UNIVERSE
);
if
(
!
newsrc
)
{
printk
(
"MASQUERADE: %s ate my IP address
\n
"
,
out
->
name
);
return
NF_DROP
;
}
if
(
rt
->
u
.
dst
.
dev
!=
out
)
{
if
(
net_ratelimit
())
printk
(
"MASQUERADE:"
" Route sent us somewhere else.
\n
"
);
ip_rt_put
(
rt
);
return
NF_DROP
;
}
}
newsrc
=
rt
->
rt_src
;
DEBUGP
(
"newsrc = %u.%u.%u.%u
\n
"
,
NIPQUAD
(
newsrc
));
ip_rt_put
(
rt
);
WRITE_LOCK
(
&
masq_lock
);
ct
->
nat
.
masq_index
=
out
->
ifindex
;
...
...
@@ -157,6 +134,18 @@ device_cmp(const struct ip_conntrack *i, void *_ina)
return
ret
;
}
static
inline
int
connect_unassure
(
const
struct
ip_conntrack
*
i
,
void
*
_ina
)
{
struct
in_ifaddr
*
ina
=
_ina
;
/* We reset the ASSURED bit on all connections, so they will
* get reaped under memory pressure. */
if
(
i
->
nat
.
masq_index
==
ina
->
ifa_dev
->
dev
->
ifindex
)
clear_bit
(
IPS_ASSURED_BIT
,
(
unsigned
long
*
)
&
i
->
status
);
return
0
;
}
static
int
masq_inet_event
(
struct
notifier_block
*
this
,
unsigned
long
event
,
void
*
ptr
)
...
...
@@ -166,6 +155,8 @@ static int masq_inet_event(struct notifier_block *this,
* entries. */
if
(
event
==
NETDEV_UP
)
ip_ct_selective_cleanup
(
device_cmp
,
ptr
);
else
if
(
event
==
NETDEV_DOWN
)
ip_ct_selective_cleanup
(
connect_unassure
,
ptr
);
return
NOTIFY_DONE
;
}
...
...
net/ipv6/netfilter/ip6_tables.c
View file @
b2928fba
...
...
@@ -158,14 +158,15 @@ ip6t_ext_hdr(u8 nexthdr)
/* Returns whether matches rule or not. */
static
inline
int
ip6_packet_match
(
const
struct
sk_buff
*
skb
,
const
struct
ipv6hdr
*
ipv6
,
const
char
*
indev
,
const
char
*
outdev
,
const
struct
ip6t_ip6
*
ip6info
,
int
isfrag
)
unsigned
int
*
protoff
,
int
*
fragoff
)
{
size_t
i
;
unsigned
long
ret
;
const
struct
ipv6hdr
*
ipv6
=
skb
->
nh
.
ipv6h
;
#define FWINV(bool,invflg) ((bool) ^ !!(ip6info->invflags & invflg))
...
...
@@ -216,9 +217,10 @@ ip6_packet_match(const struct sk_buff *skb,
/* look for the desired protocol header */
if
((
ip6info
->
flags
&
IP6T_F_PROTO
))
{
u_int8_t
currenthdr
=
ipv6
->
nexthdr
;
struct
ipv6_opt_hdr
*
hdrptr
;
struct
ipv6_opt_hdr
_hdr
,
*
hp
;
u_int16_t
ptr
;
/* Header offset in skb */
u_int16_t
hdrlen
;
/* Header */
u_int16_t
_fragoff
=
0
,
*
fp
=
NULL
;
ptr
=
IPV6_HDR_LEN
;
...
...
@@ -234,22 +236,40 @@ ip6_packet_match(const struct sk_buff *skb,
(
currenthdr
==
IPPROTO_ESP
))
return
0
;
hdrptr
=
(
struct
ipv6_opt_hdr
*
)(
skb
->
data
+
ptr
);
hp
=
skb_header_pointer
(
skb
,
ptr
,
sizeof
(
_hdr
),
&
_hdr
);
BUG_ON
(
hp
==
NULL
);
/* Size calculation */
if
(
currenthdr
==
IPPROTO_FRAGMENT
)
{
fp
=
skb_header_pointer
(
skb
,
ptr
+
offsetof
(
struct
frag_hdr
,
frag_off
),
sizeof
(
_fragoff
),
&
_fragoff
);
if
(
fp
==
NULL
)
return
0
;
_fragoff
=
ntohs
(
*
fp
)
&
~
0x7
;
hdrlen
=
8
;
}
else
if
(
currenthdr
==
IPPROTO_AH
)
hdrlen
=
(
h
drptr
->
hdrlen
+
2
)
<<
2
;
hdrlen
=
(
h
p
->
hdrlen
+
2
)
<<
2
;
else
hdrlen
=
ipv6_optlen
(
h
drptr
);
hdrlen
=
ipv6_optlen
(
h
p
);
currenthdr
=
h
drptr
->
nexthdr
;
currenthdr
=
h
p
->
nexthdr
;
ptr
+=
hdrlen
;
/* ptr is too large */
if
(
ptr
>
skb
->
len
)
return
0
;
if
(
_fragoff
)
{
if
(
ip6t_ext_hdr
(
currenthdr
))
return
0
;
break
;
}
}
*
protoff
=
ptr
;
*
fragoff
=
_fragoff
;
/* currenthdr contains the protocol header */
...
...
@@ -292,9 +312,9 @@ ip6_checkentry(const struct ip6t_ip6 *ipv6)
static
unsigned
int
ip6t_error
(
struct
sk_buff
**
pskb
,
unsigned
int
hooknum
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
unsigned
int
hooknum
,
const
void
*
targinfo
,
void
*
userinfo
)
{
...
...
@@ -310,13 +330,12 @@ int do_match(struct ip6t_entry_match *m,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
unsigned
int
protoff
,
int
*
hotdrop
)
{
/* Stop iteration if it doesn't match */
if
(
!
m
->
u
.
kernel
.
match
->
match
(
skb
,
in
,
out
,
m
->
data
,
offset
,
hdr
,
datalen
,
hotdrop
))
offset
,
protoff
,
hotdrop
))
return
1
;
else
return
0
;
...
...
@@ -338,10 +357,8 @@ ip6t_do_table(struct sk_buff **pskb,
void
*
userdata
)
{
static
const
char
nulldevname
[
IFNAMSIZ
];
u_int16_t
offset
=
0
;
struct
ipv6hdr
*
ipv6
;
void
*
protohdr
;
u_int16_t
datalen
;
int
offset
=
0
;
unsigned
int
protoff
=
0
;
int
hotdrop
=
0
;
/* Initializing verdict to NF_DROP keeps gcc happy. */
unsigned
int
verdict
=
NF_DROP
;
...
...
@@ -354,9 +371,6 @@ ip6t_do_table(struct sk_buff **pskb,
return
NF_DROP
;
/* Initialization */
ipv6
=
(
*
pskb
)
->
nh
.
ipv6h
;
protohdr
=
(
u_int32_t
*
)((
char
*
)
ipv6
+
IPV6_HDR_LEN
);
datalen
=
(
*
pskb
)
->
len
-
IPV6_HDR_LEN
;
indev
=
in
?
in
->
name
:
nulldevname
;
outdev
=
out
?
out
->
name
:
nulldevname
;
...
...
@@ -393,17 +407,19 @@ ip6t_do_table(struct sk_buff **pskb,
IP_NF_ASSERT
(
e
);
IP_NF_ASSERT
(
back
);
(
*
pskb
)
->
nfcache
|=
e
->
nfcache
;
if
(
ip6_packet_match
(
*
pskb
,
i
pv6
,
indev
,
outdev
,
&
e
->
ipv6
,
offset
))
{
if
(
ip6_packet_match
(
*
pskb
,
i
ndev
,
outdev
,
&
e
->
ipv6
,
&
protoff
,
&
offset
))
{
struct
ip6t_entry_target
*
t
;
if
(
IP6T_MATCH_ITERATE
(
e
,
do_match
,
*
pskb
,
in
,
out
,
offset
,
protohdr
,
datalen
,
&
hotdrop
)
!=
0
)
offset
,
protoff
,
&
hotdrop
)
!=
0
)
goto
no_match
;
ADD_COUNTER
(
e
->
counters
,
ntohs
(
ipv6
->
payload_len
)
+
IPV6_HDR_LEN
,
1
);
ADD_COUNTER
(
e
->
counters
,
ntohs
((
*
pskb
)
->
nh
.
ipv6h
->
payload_len
)
+
IPV6_HDR_LEN
,
1
);
t
=
ip6t_get_target
(
e
);
IP_NF_ASSERT
(
t
->
u
.
kernel
.
target
);
...
...
@@ -443,8 +459,8 @@ ip6t_do_table(struct sk_buff **pskb,
=
0xeeeeeeec
;
#endif
verdict
=
t
->
u
.
kernel
.
target
->
target
(
pskb
,
hook
,
in
,
out
,
hook
,
t
->
data
,
userdata
);
...
...
@@ -459,11 +475,6 @@ ip6t_do_table(struct sk_buff **pskb,
((
struct
ip6t_entry
*
)
table_base
)
->
comefrom
=
0x57acc001
;
#endif
/* Target might have changed stuff. */
ipv6
=
(
*
pskb
)
->
nh
.
ipv6h
;
protohdr
=
(
u_int32_t
*
)((
void
*
)
ipv6
+
IPV6_HDR_LEN
);
datalen
=
(
*
pskb
)
->
len
-
IPV6_HDR_LEN
;
if
(
verdict
==
IP6T_CONTINUE
)
e
=
(
void
*
)
e
+
e
->
next_offset
;
else
...
...
@@ -1535,26 +1546,31 @@ port_match(u_int16_t min, u_int16_t max, u_int16_t port, int invert)
static
int
tcp_find_option
(
u_int8_t
option
,
const
struct
tcphdr
*
tcp
,
u_int16_t
datalen
,
const
struct
sk_buff
*
skb
,
unsigned
int
tcpoff
,
unsigned
int
optlen
,
int
invert
,
int
*
hotdrop
)
{
unsigned
int
i
=
sizeof
(
struct
tcphdr
);
const
u_int8_t
*
opt
=
(
u_int8_t
*
)
tcp
;
/* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */
u_int8_t
_opt
[
60
-
sizeof
(
struct
tcphdr
)],
*
op
;
unsigned
int
i
;
duprintf
(
"tcp_match: finding option
\n
"
);
if
(
!
optlen
)
return
invert
;
/* If we don't have the whole header, drop packet. */
if
(
tcp
->
doff
*
4
<
sizeof
(
struct
tcphdr
)
||
tcp
->
doff
*
4
>
datalen
)
{
op
=
skb_header_pointer
(
skb
,
tcpoff
+
sizeof
(
struct
tcphdr
),
optlen
,
_opt
);
if
(
op
==
NULL
)
{
*
hotdrop
=
1
;
return
0
;
}
while
(
i
<
tcp
->
doff
*
4
)
{
if
(
op
t
[
i
]
==
option
)
return
!
invert
;
if
(
op
t
[
i
]
<
2
)
i
++
;
else
i
+=
op
t
[
i
+
1
]
?:
1
;
for
(
i
=
0
;
i
<
optlen
;
)
{
if
(
op
[
i
]
==
option
)
return
!
invert
;
if
(
op
[
i
]
<
2
)
i
++
;
else
i
+=
op
[
i
+
1
]
?:
1
;
}
return
invert
;
...
...
@@ -1566,27 +1582,31 @@ tcp_match(const struct sk_buff *skb,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
unsigned
int
protoff
,
int
*
hotdrop
)
{
const
struct
tcphdr
*
tcp
;
struct
tcphdr
_tcph
,
*
th
;
const
struct
ip6t_tcp
*
tcpinfo
=
matchinfo
;
int
tcpoff
;
u8
nexthdr
=
skb
->
nh
.
ipv6h
->
nexthdr
;
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
)
{
duprintf
(
"Dropping evil TCP offset=1 frag.
\n
"
);
*
hotdrop
=
1
;
}
/* Must not be a fragment. */
return
0
;
}
else
if
(
offset
==
0
&&
datalen
<
sizeof
(
struct
tcphdr
))
{
}
#define FWINVTCP(bool,invflg) ((bool) ^ !!(tcpinfo->invflags & invflg))
th
=
skb_header_pointer
(
skb
,
protoff
,
sizeof
(
_tcph
),
&
_tcph
);
if
(
th
==
NULL
)
{
/* We've been asked to examine this packet, and we
can't. Hence, no choice but to drop. */
duprintf
(
"Dropping evil TCP offset=0 tinygram.
\n
"
);
...
...
@@ -1594,45 +1614,30 @@ tcp_match(const struct sk_buff *skb,
return
0
;
}
tcpoff
=
(
u8
*
)(
skb
->
nh
.
ipv6h
+
1
)
-
skb
->
data
;
tcpoff
=
ipv6_skip_exthdr
(
skb
,
tcpoff
,
&
nexthdr
,
skb
->
len
-
tcpoff
);
if
(
tcpoff
<
0
||
tcpoff
>
skb
->
len
)
{
duprintf
(
"tcp_match: cannot skip exthdr. Dropping.
\n
"
);
*
hotdrop
=
1
;
if
(
!
port_match
(
tcpinfo
->
spts
[
0
],
tcpinfo
->
spts
[
1
],
ntohs
(
th
->
source
),
!!
(
tcpinfo
->
invflags
&
IP6T_TCP_INV_SRCPT
)))
return
0
;
}
else
if
(
nexthdr
==
IPPROTO_FRAGMENT
)
if
(
!
port_match
(
tcpinfo
->
dpts
[
0
],
tcpinfo
->
dpts
[
1
],
ntohs
(
th
->
dest
),
!!
(
tcpinfo
->
invflags
&
IP6T_TCP_INV_DSTPT
)))
return
0
;
else
if
(
nexthdr
!=
IPPROTO_TCP
||
skb
->
len
-
tcpoff
<
sizeof
(
struct
tcphdr
))
{
/* cannot be occured */
duprintf
(
"tcp_match: cannot get TCP header. Dropping.
\n
"
);
if
(
!
FWINVTCP
((((
unsigned
char
*
)
th
)[
13
]
&
tcpinfo
->
flg_mask
)
==
tcpinfo
->
flg_cmp
,
IP6T_TCP_INV_FLAGS
))
return
0
;
if
(
tcpinfo
->
option
)
{
if
(
th
->
doff
*
4
<
sizeof
(
_tcph
))
{
*
hotdrop
=
1
;
return
0
;
}
tcp
=
(
struct
tcphdr
*
)(
skb
->
data
+
tcpoff
);
/* FIXME: Try tcp doff >> packet len against various stacks --RR */
#define FWINVTCP(bool,invflg) ((bool) ^ !!(tcpinfo->invflags & invflg))
/* Must not be a fragment. */
return
!
offset
&&
port_match
(
tcpinfo
->
spts
[
0
],
tcpinfo
->
spts
[
1
],
ntohs
(
tcp
->
source
),
!!
(
tcpinfo
->
invflags
&
IP6T_TCP_INV_SRCPT
))
&&
port_match
(
tcpinfo
->
dpts
[
0
],
tcpinfo
->
dpts
[
1
],
ntohs
(
tcp
->
dest
),
!!
(
tcpinfo
->
invflags
&
IP6T_TCP_INV_DSTPT
))
&&
FWINVTCP
((((
unsigned
char
*
)
tcp
)[
13
]
&
tcpinfo
->
flg_mask
)
==
tcpinfo
->
flg_cmp
,
IP6T_TCP_INV_FLAGS
)
&&
(
!
tcpinfo
->
option
||
tcp_find_option
(
tcpinfo
->
option
,
tcp
,
datalen
,
tcpinfo
->
invflags
&
IP6T_TCP_INV_OPTION
,
hotdrop
));
if
(
!
tcp_find_option
(
tcpinfo
->
option
,
skb
,
protoff
,
th
->
doff
*
4
-
sizeof
(
*
th
),
tcpinfo
->
invflags
&
IP6T_TCP_INV_OPTION
,
hotdrop
))
return
0
;
}
return
1
;
}
/* Called when user tries to insert an entry of this type. */
...
...
@@ -1658,16 +1663,18 @@ udp_match(const struct sk_buff *skb,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
unsigned
int
protoff
,
int
*
hotdrop
)
{
const
struct
udphdr
*
udp
;
struct
udphdr
_udph
,
*
uh
;
const
struct
ip6t_udp
*
udpinfo
=
matchinfo
;
int
udpoff
;
u8
nexthdr
=
skb
->
nh
.
ipv6h
->
nexthdr
;
if
(
offset
==
0
&&
datalen
<
sizeof
(
struct
udphdr
))
{
/* Must not be a fragment. */
if
(
offset
)
return
0
;
uh
=
skb_header_pointer
(
skb
,
protoff
,
sizeof
(
_udph
),
&
_udph
);
if
(
uh
==
NULL
)
{
/* We've been asked to examine this packet, and we
can't. Hence, no choice but to drop. */
duprintf
(
"Dropping evil UDP tinygram.
\n
"
);
...
...
@@ -1675,30 +1682,11 @@ udp_match(const struct sk_buff *skb,
return
0
;
}
udpoff
=
(
u8
*
)(
skb
->
nh
.
ipv6h
+
1
)
-
skb
->
data
;
udpoff
=
ipv6_skip_exthdr
(
skb
,
udpoff
,
&
nexthdr
,
skb
->
len
-
udpoff
);
if
(
udpoff
<
0
||
udpoff
>
skb
->
len
)
{
duprintf
(
"udp_match: cannot skip exthdr. Dropping.
\n
"
);
*
hotdrop
=
1
;
return
0
;
}
else
if
(
nexthdr
==
IPPROTO_FRAGMENT
)
return
0
;
else
if
(
nexthdr
!=
IPPROTO_UDP
||
skb
->
len
-
udpoff
<
sizeof
(
struct
udphdr
))
{
duprintf
(
"udp_match: cannot get UDP header. Dropping.
\n
"
);
*
hotdrop
=
1
;
return
0
;
}
udp
=
(
struct
udphdr
*
)(
skb
->
data
+
udpoff
);
/* Must not be a fragment. */
return
!
offset
&&
port_match
(
udpinfo
->
spts
[
0
],
udpinfo
->
spts
[
1
],
ntohs
(
udp
->
source
),
return
port_match
(
udpinfo
->
spts
[
0
],
udpinfo
->
spts
[
1
],
ntohs
(
uh
->
source
),
!!
(
udpinfo
->
invflags
&
IP6T_UDP_INV_SRCPT
))
&&
port_match
(
udpinfo
->
dpts
[
0
],
udpinfo
->
dpts
[
1
],
ntohs
(
u
dp
->
dest
),
ntohs
(
u
h
->
dest
),
!!
(
udpinfo
->
invflags
&
IP6T_UDP_INV_DSTPT
));
}
...
...
@@ -1748,14 +1736,18 @@ icmp6_match(const struct sk_buff *skb,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
unsigned
int
protoff
,
int
*
hotdrop
)
{
const
struct
icmp6hdr
*
icmp
=
hdr
;
struct
icmp6hdr
_icmp
,
*
ic
;
const
struct
ip6t_icmp
*
icmpinfo
=
matchinfo
;
if
(
offset
==
0
&&
datalen
<
2
)
{
/* Must not be a fragment. */
if
(
offset
)
return
0
;
ic
=
skb_header_pointer
(
skb
,
protoff
,
sizeof
(
_icmp
),
&
_icmp
);
if
(
ic
==
NULL
)
{
/* We've been asked to examine this packet, and we
can't. Hence, no choice but to drop. */
duprintf
(
"Dropping evil ICMP tinygram.
\n
"
);
...
...
@@ -1763,12 +1755,10 @@ icmp6_match(const struct sk_buff *skb,
return
0
;
}
/* Must not be a fragment. */
return
!
offset
&&
icmp6_type_code_match
(
icmpinfo
->
type
,
return
icmp6_type_code_match
(
icmpinfo
->
type
,
icmpinfo
->
code
[
0
],
icmpinfo
->
code
[
1
],
icmp
->
icmp6_type
,
icmp
->
icmp6_code
,
ic
->
icmp6_type
,
ic
->
icmp6_code
,
!!
(
icmpinfo
->
invflags
&
IP6T_ICMP_INV
));
}
...
...
net/ipv6/netfilter/ip6t_LOG.c
View file @
b2928fba
...
...
@@ -40,120 +40,166 @@ struct in_device;
#define DEBUGP(format, args...)
#endif
struct
esphdr
{
__u32
spi
;
};
/* FIXME evil kludge */
/* Use lock to serialize, so printks don't overlap */
static
spinlock_t
log_lock
=
SPIN_LOCK_UNLOCKED
;
/* takes in current header and pointer to the header */
/* if another header exists, sets hdrptr to the next header
and returns the new header value, else returns IPPROTO_NONE */
static
u_int8_t
ip6_nexthdr
(
u_int8_t
currenthdr
,
u_int8_t
**
hdrptr
)
{
u_int8_t
hdrlen
,
nexthdr
=
IPPROTO_NONE
;
switch
(
currenthdr
){
case
IPPROTO_AH
:
/* whoever decided to do the length of AUTH for ipv6
in 32bit units unlike other headers should be beaten...
repeatedly...with a large stick...no, an even LARGER
stick...no, you're still not thinking big enough */
nexthdr
=
**
hdrptr
;
hdrlen
=
(
*
hdrptr
)[
1
]
*
4
+
8
;
*
hdrptr
=
*
hdrptr
+
hdrlen
;
break
;
/*stupid rfc2402 */
case
IPPROTO_DSTOPTS
:
case
IPPROTO_ROUTING
:
case
IPPROTO_HOPOPTS
:
nexthdr
=
**
hdrptr
;
hdrlen
=
(
*
hdrptr
)[
1
]
*
8
+
8
;
*
hdrptr
=
*
hdrptr
+
hdrlen
;
break
;
case
IPPROTO_FRAGMENT
:
nexthdr
=
**
hdrptr
;
*
hdrptr
=
*
hdrptr
+
8
;
break
;
}
return
nexthdr
;
}
/* One level of recursion won't kill us */
static
void
dump_packet
(
const
struct
ip6t_log_info
*
info
,
struct
ipv6hdr
*
ipv6h
,
int
recurse
)
const
struct
sk_buff
*
skb
,
unsigned
int
ip6hoff
,
int
recurse
)
{
u_int8_t
currenthdr
=
ipv6h
->
nexthdr
;
u_int8_t
*
hdrptr
;
u_int8_t
currenthdr
;
int
fragment
;
struct
ipv6hdr
_ip6h
,
*
ih
;
unsigned
int
ptr
;
unsigned
int
hdrlen
=
0
;
ih
=
skb_header_pointer
(
skb
,
ip6hoff
,
sizeof
(
_ip6h
),
&
_ip6h
);
if
(
ih
==
NULL
)
{
printk
(
"TRUNCATED"
);
return
;
}
/* Max length: 88 "SRC=0000.0000.0000.0000.0000.0000.0000.0000 DST=0000.0000.0000.0000.0000.0000.0000.0000" */
printk
(
"SRC=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x "
,
NIP6
(
i
pv6
h
->
saddr
));
printk
(
"DST=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x "
,
NIP6
(
i
pv6
h
->
daddr
));
printk
(
"SRC=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x "
,
NIP6
(
ih
->
saddr
));
printk
(
"DST=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x "
,
NIP6
(
ih
->
daddr
));
/* Max length: 44 "LEN=65535 TC=255 HOPLIMIT=255 FLOWLBL=FFFFF " */
printk
(
"LEN=%Zu TC=%u HOPLIMIT=%u FLOWLBL=%u "
,
ntohs
(
i
pv6
h
->
payload_len
)
+
sizeof
(
struct
ipv6hdr
),
(
ntohl
(
*
(
u_int32_t
*
)
i
pv6
h
)
&
0x0ff00000
)
>>
20
,
i
pv6
h
->
hop_limit
,
(
ntohl
(
*
(
u_int32_t
*
)
i
pv6
h
)
&
0x000fffff
));
ntohs
(
ih
->
payload_len
)
+
sizeof
(
struct
ipv6hdr
),
(
ntohl
(
*
(
u_int32_t
*
)
ih
)
&
0x0ff00000
)
>>
20
,
ih
->
hop_limit
,
(
ntohl
(
*
(
u_int32_t
*
)
ih
)
&
0x000fffff
));
fragment
=
0
;
hdrptr
=
(
u_int8_t
*
)(
ipv6h
+
1
);
while
(
currenthdr
!=
IPPROTO_NONE
)
{
if
((
currenthdr
==
IPPROTO_TCP
)
||
(
currenthdr
==
IPPROTO_UDP
)
||
(
currenthdr
==
IPPROTO_ICMPV6
))
break
;
ptr
=
ip6hoff
+
sizeof
(
struct
ipv6hdr
);
currenthdr
=
ih
->
nexthdr
;
while
(
currenthdr
!=
NEXTHDR_NONE
&&
ip6t_ext_hdr
(
currenthdr
))
{
struct
ipv6_opt_hdr
_hdr
,
*
hp
;
hp
=
skb_header_pointer
(
skb
,
ptr
,
sizeof
(
_hdr
),
&
_hdr
);
if
(
hp
==
NULL
)
{
printk
(
"TRUNCATED"
);
return
;
}
/* Max length: 48 "OPT (...) " */
if
(
info
->
logflags
&
IP6T_LOG_IPOPT
)
printk
(
"OPT ( "
);
switch
(
currenthdr
)
{
case
IPPROTO_FRAGMENT
:
{
struct
frag_hdr
*
fhdr
=
(
struct
frag_hdr
*
)
hdrptr
;
struct
frag_hdr
_fhdr
,
*
fh
;
printk
(
"FRAG:"
);
fh
=
skb_header_pointer
(
skb
,
ptr
,
sizeof
(
_fhdr
),
&
_fhdr
);
if
(
fh
==
NULL
)
{
printk
(
"TRUNCATED "
);
return
;
}
/* Max length:
11 "FRAG:
65535 " */
printk
(
"
FRAG:%u "
,
ntohs
(
fhdr
->
frag_off
)
&
0xFFF8
);
/* Max length:
6 "
65535 " */
printk
(
"
%u "
,
ntohs
(
fh
->
frag_off
)
&
0xFFF8
);
/* Max length: 11 "INCOMPLETE " */
if
(
fh
dr
->
frag_off
&
htons
(
0x0001
))
if
(
fh
->
frag_off
&
htons
(
0x0001
))
printk
(
"INCOMPLETE "
);
printk
(
"ID:%08x "
,
fhdr
->
identification
);
printk
(
"ID:%08x "
,
ntohl
(
fh
->
identification
)
);
if
(
ntohs
(
fh
dr
->
frag_off
)
&
0xFFF8
)
if
(
ntohs
(
fh
->
frag_off
)
&
0xFFF8
)
fragment
=
1
;
hdrlen
=
8
;
break
;
}
case
IPPROTO_DSTOPTS
:
case
IPPROTO_ROUTING
:
case
IPPROTO_HOPOPTS
:
if
(
fragment
)
{
if
(
info
->
logflags
&
IP6T_LOG_IPOPT
)
printk
(
")"
);
return
;
}
hdrlen
=
ipv6_optlen
(
hp
);
break
;
/* Max Length */
case
IPPROTO_AH
:
if
(
info
->
logflags
&
IP6T_LOG_IPOPT
)
{
struct
ip_auth_hdr
_ahdr
,
*
ah
;
/* Max length: 3 "AH " */
printk
(
"AH "
);
if
(
fragment
)
{
printk
(
")"
);
return
;
}
ah
=
skb_header_pointer
(
skb
,
ptr
,
sizeof
(
_ahdr
),
&
_ahdr
);
if
(
ah
==
NULL
)
{
/*
* Max length: 26 "INCOMPLETE [65535
* bytes] )"
*/
printk
(
"INCOMPLETE [%u bytes] )"
,
skb
->
len
-
ptr
);
return
;
}
/* Length: 15 "SPI=0xF1234567 */
printk
(
"SPI=0x%x "
,
ntohl
(
ah
->
spi
));
}
hdrlen
=
(
hp
->
hdrlen
+
2
)
<<
2
;
break
;
case
IPPROTO_ESP
:
if
(
info
->
logflags
&
IP6T_LOG_IPOPT
)
{
struct
esphdr
*
esph
=
(
struct
esphdr
*
)
hdrptr
;
int
esp
=
(
currenthdr
==
IPPROTO_ESP
);
struct
ip_esp_hdr
_esph
,
*
eh
;
/* Max length: 4 "ESP " */
printk
(
"
%s "
,
esp
?
"ESP"
:
"AH
"
);
printk
(
"
ESP
"
);
/* Length: 15 "SPI=0xF1234567 " */
printk
(
"SPI=0x%x "
,
ntohl
(
esph
->
spi
)
);
break
;
if
(
fragment
)
{
printk
(
")"
);
return
;
}
/*
* Max length: 26 "INCOMPLETE [65535 bytes] )"
*/
eh
=
skb_header_pointer
(
skb
,
ptr
,
sizeof
(
_esph
),
&
_esph
);
if
(
eh
==
NULL
)
{
printk
(
"INCOMPLETE [%u bytes] )"
,
skb
->
len
-
ptr
);
return
;
}
/* Length: 16 "SPI=0xF1234567 )" */
printk
(
"SPI=0x%x )"
,
ntohl
(
eh
->
spi
)
);
}
return
;
default:
break
;
/* Max length: 20 "Unknown Ext Hdr 255" */
printk
(
"Unknown Ext Hdr %u"
,
currenthdr
);
return
;
}
if
(
info
->
logflags
&
IP6T_LOG_IPOPT
)
printk
(
") "
);
currenthdr
=
ip6_nexthdr
(
currenthdr
,
&
hdrptr
);
currenthdr
=
hp
->
nexthdr
;
ptr
+=
hdrlen
;
}
switch
(
currenthdr
)
{
case
IPPROTO_TCP
:
{
struct
tcphdr
*
tcph
=
(
struct
tcphdr
*
)
hdrptr
;
struct
tcphdr
_tcph
,
*
th
;
/* Max length: 10 "PROTO=TCP " */
printk
(
"PROTO=TCP "
);
...
...
@@ -161,51 +207,69 @@ static void dump_packet(const struct ip6t_log_info *info,
if
(
fragment
)
break
;
/* Max length: 25 "INCOMPLETE [65535 bytes] " */
th
=
skb_header_pointer
(
skb
,
ptr
,
sizeof
(
_tcph
),
&
_tcph
);
if
(
th
==
NULL
)
{
printk
(
"INCOMPLETE [%u bytes] "
,
skb
->
len
-
ptr
);
return
;
}
/* Max length: 20 "SPT=65535 DPT=65535 " */
printk
(
"SPT=%u DPT=%u "
,
ntohs
(
t
cph
->
source
),
ntohs
(
tcp
h
->
dest
));
ntohs
(
t
h
->
source
),
ntohs
(
t
h
->
dest
));
/* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */
if
(
info
->
logflags
&
IP6T_LOG_TCPSEQ
)
printk
(
"SEQ=%u ACK=%u "
,
ntohl
(
t
cph
->
seq
),
ntohl
(
tcp
h
->
ack_seq
));
ntohl
(
t
h
->
seq
),
ntohl
(
t
h
->
ack_seq
));
/* Max length: 13 "WINDOW=65535 " */
printk
(
"WINDOW=%u "
,
ntohs
(
t
cp
h
->
window
));
/* Max length: 9 "RES=0x3
F
" */
printk
(
"RES=0x%02x "
,
(
u_int8_t
)(
ntohl
(
tcp_flag_word
(
t
cp
h
)
&
TCP_RESERVED_BITS
)
>>
22
));
printk
(
"WINDOW=%u "
,
ntohs
(
th
->
window
));
/* Max length: 9 "RES=0x3
C
" */
printk
(
"RES=0x%02x "
,
(
u_int8_t
)(
ntohl
(
tcp_flag_word
(
th
)
&
TCP_RESERVED_BITS
)
>>
22
));
/* Max length: 32 "CWR ECE URG ACK PSH RST SYN FIN " */
if
(
t
cp
h
->
cwr
)
if
(
th
->
cwr
)
printk
(
"CWR "
);
if
(
t
cp
h
->
ece
)
if
(
th
->
ece
)
printk
(
"ECE "
);
if
(
t
cp
h
->
urg
)
if
(
th
->
urg
)
printk
(
"URG "
);
if
(
t
cp
h
->
ack
)
if
(
th
->
ack
)
printk
(
"ACK "
);
if
(
t
cp
h
->
psh
)
if
(
th
->
psh
)
printk
(
"PSH "
);
if
(
t
cp
h
->
rst
)
if
(
th
->
rst
)
printk
(
"RST "
);
if
(
t
cp
h
->
syn
)
if
(
th
->
syn
)
printk
(
"SYN "
);
if
(
t
cp
h
->
fin
)
if
(
th
->
fin
)
printk
(
"FIN "
);
/* Max length: 11 "URGP=65535 " */
printk
(
"URGP=%u "
,
ntohs
(
t
cp
h
->
urg_ptr
));
printk
(
"URGP=%u "
,
ntohs
(
th
->
urg_ptr
));
if
((
info
->
logflags
&
IP6T_LOG_TCPOPT
)
&&
tcph
->
doff
*
4
!=
sizeof
(
struct
tcphdr
))
{
&&
th
->
doff
*
4
>
sizeof
(
struct
tcphdr
))
{
u_int8_t
_opt
[
60
-
sizeof
(
struct
tcphdr
)],
*
op
;
unsigned
int
i
;
unsigned
int
optsize
=
th
->
doff
*
4
-
sizeof
(
struct
tcphdr
);
op
=
skb_header_pointer
(
skb
,
ptr
+
sizeof
(
struct
tcphdr
),
optsize
,
_opt
);
if
(
op
==
NULL
)
{
printk
(
"OPT (TRUNCATED)"
);
return
;
}
/* Max length: 127 "OPT (" 15*4*2chars ") " */
printk
(
"OPT ("
);
for
(
i
=
sizeof
(
struct
tcphdr
);
i
<
tcph
->
doff
*
4
;
i
++
)
printk
(
"%02X"
,
((
u_int8_t
*
)
tcph
)
[
i
]);
for
(
i
=
0
;
i
<
optsize
;
i
++
)
printk
(
"%02X"
,
op
[
i
]);
printk
(
") "
);
}
break
;
}
case
IPPROTO_UDP
:
{
struct
udphdr
*
udph
=
(
struct
udphdr
*
)
hdrptr
;
struct
udphdr
_udph
,
*
uh
;
/* Max length: 10 "PROTO=UDP " */
printk
(
"PROTO=UDP "
);
...
...
@@ -213,14 +277,21 @@ static void dump_packet(const struct ip6t_log_info *info,
if
(
fragment
)
break
;
/* Max length: 25 "INCOMPLETE [65535 bytes] " */
uh
=
skb_header_pointer
(
skb
,
ptr
,
sizeof
(
_udph
),
&
_udph
);
if
(
uh
==
NULL
)
{
printk
(
"INCOMPLETE [%u bytes] "
,
skb
->
len
-
ptr
);
return
;
}
/* Max length: 20 "SPT=65535 DPT=65535 " */
printk
(
"SPT=%u DPT=%u LEN=%u "
,
ntohs
(
u
dph
->
source
),
ntohs
(
udp
h
->
dest
),
ntohs
(
u
dp
h
->
len
));
ntohs
(
u
h
->
source
),
ntohs
(
u
h
->
dest
),
ntohs
(
uh
->
len
));
break
;
}
case
IPPROTO_ICMPV6
:
{
struct
icmp6hdr
*
icmp6h
=
(
struct
icmp6hdr
*
)
hdrptr
;
struct
icmp6hdr
_icmp6h
,
*
ic
;
/* Max length: 13 "PROTO=ICMPv6 " */
printk
(
"PROTO=ICMPv6 "
);
...
...
@@ -228,16 +299,23 @@ static void dump_packet(const struct ip6t_log_info *info,
if
(
fragment
)
break
;
/* Max length: 25 "INCOMPLETE [65535 bytes] " */
ic
=
skb_header_pointer
(
skb
,
ptr
,
sizeof
(
_icmp6h
),
&
_icmp6h
);
if
(
ic
==
NULL
)
{
printk
(
"INCOMPLETE [%u bytes] "
,
skb
->
len
-
ptr
);
return
;
}
/* Max length: 18 "TYPE=255 CODE=255 " */
printk
(
"TYPE=%u CODE=%u "
,
ic
mp6h
->
icmp6_type
,
icmp6h
->
icmp6_code
);
printk
(
"TYPE=%u CODE=%u "
,
ic
->
icmp6_type
,
ic
->
icmp6_code
);
switch
(
ic
mp6h
->
icmp6_type
)
{
switch
(
ic
->
icmp6_type
)
{
case
ICMPV6_ECHO_REQUEST
:
case
ICMPV6_ECHO_REPLY
:
/* Max length: 19 "ID=65535 SEQ=65535 " */
printk
(
"ID=%u SEQ=%u "
,
ntohs
(
ic
mp6h
->
icmp6_identifier
),
ntohs
(
ic
mp6h
->
icmp6_sequence
));
ntohs
(
ic
->
icmp6_identifier
),
ntohs
(
ic
->
icmp6_sequence
));
break
;
case
ICMPV6_MGM_QUERY
:
case
ICMPV6_MGM_REPORT
:
...
...
@@ -246,7 +324,7 @@ static void dump_packet(const struct ip6t_log_info *info,
case
ICMPV6_PARAMPROB
:
/* Max length: 17 "POINTER=ffffffff " */
printk
(
"POINTER=%08x "
,
ntohl
(
ic
mp6h
->
icmp6_pointer
));
printk
(
"POINTER=%08x "
,
ntohl
(
ic
->
icmp6_pointer
));
/* Fall through */
case
ICMPV6_DEST_UNREACH
:
case
ICMPV6_PKT_TOOBIG
:
...
...
@@ -254,13 +332,14 @@ static void dump_packet(const struct ip6t_log_info *info,
/* Max length: 3+maxlen */
if
(
recurse
)
{
printk
(
"["
);
dump_packet
(
info
,
(
struct
ipv6hdr
*
)(
icmp6h
+
1
),
0
);
dump_packet
(
info
,
skb
,
ptr
+
sizeof
(
_icmp6h
),
0
);
printk
(
"] "
);
}
/* Max length: 10 "MTU=65535 " */
if
(
ic
mp6h
->
icmp6_type
==
ICMPV6_PKT_TOOBIG
)
printk
(
"MTU=%u "
,
ntohl
(
ic
mp6h
->
icmp6_mtu
));
if
(
ic
->
icmp6_type
==
ICMPV6_PKT_TOOBIG
)
printk
(
"MTU=%u "
,
ntohl
(
ic
->
icmp6_mtu
));
}
break
;
}
...
...
@@ -328,16 +407,16 @@ ip6t_log_packet(unsigned int hooknum,
printk
(
" "
);
}
dump_packet
(
loginfo
,
ipv6h
,
1
);
dump_packet
(
loginfo
,
skb
,
(
u8
*
)
skb
->
nh
.
ipv6h
-
skb
->
data
,
1
);
printk
(
"
\n
"
);
spin_unlock_bh
(
&
log_lock
);
}
static
unsigned
int
ip6t_log_target
(
struct
sk_buff
**
pskb
,
unsigned
int
hooknum
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
unsigned
int
hooknum
,
const
void
*
targinfo
,
void
*
userinfo
)
{
...
...
net/ipv6/netfilter/ip6t_MARK.c
View file @
b2928fba
...
...
@@ -20,9 +20,9 @@ MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
static
unsigned
int
target
(
struct
sk_buff
**
pskb
,
unsigned
int
hooknum
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
unsigned
int
hooknum
,
const
void
*
targinfo
,
void
*
userinfo
)
{
...
...
net/ipv6/netfilter/ip6t_ah.c
View file @
b2928fba
...
...
@@ -34,7 +34,7 @@ spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, int invert)
int
r
=
0
;
DEBUGP
(
"ah spi_match:%c 0x%x <= 0x%x <= 0x%x"
,
invert
?
'!'
:
' '
,
min
,
spi
,
max
);
r
=
(
spi
>=
min
&&
spi
<=
max
)
^
invert
;
r
=
(
spi
>=
min
&&
spi
<=
max
)
^
invert
;
DEBUGP
(
" result %s
\n
"
,
r
?
"PASS
\n
"
:
"FAILED
\n
"
);
return
r
;
}
...
...
@@ -45,11 +45,10 @@ match(const struct sk_buff *skb,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
int
offset
,
const
void
*
protohdr
,
u_int16_t
datalen
,
unsigned
int
protoff
,
int
*
hotdrop
)
{
struct
ip_auth_hdr
*
ah
=
NULL
;
struct
ip_auth_hdr
*
ah
=
NULL
,
_ah
;
const
struct
ip6t_ah
*
ahinfo
=
matchinfo
;
unsigned
int
temp
;
int
len
;
...
...
@@ -70,31 +69,30 @@ match(const struct sk_buff *skb,
temp
=
0
;
while
(
ip6t_ext_hdr
(
nexthdr
))
{
struct
ipv6_opt_hdr
*
hdr
;
struct
ipv6_opt_hdr
_hdr
,
*
hp
;
DEBUGP
(
"ipv6_ah header iteration
\n
"
);
/* Is there enough space for the next ext header? */
if
(
len
<
(
int
)
sizeof
(
struct
ipv6_opt_hdr
))
if
(
len
<
sizeof
(
struct
ipv6_opt_hdr
))
return
0
;
/* No more exthdr -> evaluate */
if
(
nexthdr
==
NEXTHDR_NONE
)
{
if
(
nexthdr
==
NEXTHDR_NONE
)
break
;
}
/* ESP -> evaluate */
if
(
nexthdr
==
NEXTHDR_ESP
)
{
if
(
nexthdr
==
NEXTHDR_ESP
)
break
;
}
hdr
=
(
struct
ipv6_opt_hdr
*
)
skb
->
data
+
ptr
;
hp
=
skb_header_pointer
(
skb
,
ptr
,
sizeof
(
_hdr
),
&
_hdr
);
BUG_ON
(
hp
==
NULL
);
/* Calculate the header length */
if
(
nexthdr
==
NEXTHDR_FRAGMENT
)
{
if
(
nexthdr
==
NEXTHDR_FRAGMENT
)
hdrlen
=
8
;
}
else
if
(
nexthdr
==
NEXTHDR_AUTH
)
hdrlen
=
(
hdr
->
hdrlen
+
2
)
<<
2
;
else
if
(
nexthdr
==
NEXTHDR_AUTH
)
hdrlen
=
(
hp
->
hdrlen
+
2
)
<<
2
;
else
hdrlen
=
ipv6_optlen
(
hdr
);
hdrlen
=
ipv6_optlen
(
hp
);
/* AH -> evaluate */
if
(
nexthdr
==
NEXTHDR_AUTH
)
{
...
...
@@ -104,7 +102,7 @@ match(const struct sk_buff *skb,
/* set the flag */
switch
(
nexthdr
)
{
switch
(
nexthdr
)
{
case
NEXTHDR_HOP
:
case
NEXTHDR_ROUTING
:
case
NEXTHDR_FRAGMENT
:
...
...
@@ -114,27 +112,28 @@ match(const struct sk_buff *skb,
default:
DEBUGP
(
"ipv6_ah match: unknown nextheader %u
\n
"
,
nexthdr
);
return
0
;
break
;
}
nexthdr
=
hdr
->
nexthdr
;
nexthdr
=
hp
->
nexthdr
;
len
-=
hdrlen
;
ptr
+=
hdrlen
;
if
(
ptr
>
skb
->
len
)
{
if
(
ptr
>
skb
->
len
)
{
DEBUGP
(
"ipv6_ah: new pointer too large!
\n
"
);
break
;
}
}
/* AH header not found */
if
(
temp
!=
MASK_AH
)
return
0
;
if
(
temp
!=
MASK_AH
)
return
0
;
if
(
len
<
(
int
)
sizeof
(
struct
ip_auth_hdr
)){
if
(
len
<
sizeof
(
struct
ip_auth_hdr
)){
*
hotdrop
=
1
;
return
0
;
}
ah
=
(
struct
ip_auth_hdr
*
)
(
skb
->
data
+
ptr
);
ah
=
skb_header_pointer
(
skb
,
ptr
,
sizeof
(
_ah
),
&
_ah
);
BUG_ON
(
ah
==
NULL
);
DEBUGP
(
"IPv6 AH LEN %u %u "
,
hdrlen
,
ah
->
hdrlen
);
DEBUGP
(
"RES %04X "
,
ah
->
reserved
);
...
...
@@ -182,11 +181,9 @@ checkentry(const char *tablename,
return
0
;
}
if
(
ahinfo
->
invflags
&
~
IP6T_AH_INV_MASK
)
{
DEBUGP
(
"ip6t_ah: unknown flags %X
\n
"
,
ahinfo
->
invflags
);
DEBUGP
(
"ip6t_ah: unknown flags %X
\n
"
,
ahinfo
->
invflags
);
return
0
;
}
return
1
;
}
...
...
net/ipv6/netfilter/ip6t_dst.c
View file @
b2928fba
...
...
@@ -60,8 +60,7 @@ match(const struct sk_buff *skb,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
int
offset
,
const
void
*
protohdr
,
u_int16_t
datalen
,
unsigned
int
protoff
,
int
*
hotdrop
)
{
struct
ipv6_opt_hdr
*
optsh
=
NULL
;
...
...
net/ipv6/netfilter/ip6t_esp.c
View file @
b2928fba
...
...
@@ -45,11 +45,10 @@ match(const struct sk_buff *skb,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
int
offset
,
const
void
*
protohdr
,
u_int16_t
datalen
,
unsigned
int
protoff
,
int
*
hotdrop
)
{
struct
ip_esp_hdr
*
esp
=
NULL
;
struct
ip_esp_hdr
_esp
,
*
eh
=
NULL
;
const
struct
ip6t_esp
*
espinfo
=
matchinfo
;
unsigned
int
temp
;
int
len
;
...
...
@@ -68,36 +67,36 @@ match(const struct sk_buff *skb,
temp
=
0
;
while
(
ip6t_ext_hdr
(
nexthdr
))
{
struct
ipv6_opt_hdr
*
hdr
;
struct
ipv6_opt_hdr
_hdr
,
*
hp
;
int
hdrlen
;
DEBUGP
(
"ipv6_esp header iteration
\n
"
);
/* Is there enough space for the next ext header? */
if
(
len
<
(
int
)
sizeof
(
struct
ipv6_opt_hdr
))
if
(
len
<
sizeof
(
struct
ipv6_opt_hdr
))
return
0
;
/* No more exthdr -> evaluate */
if
(
nexthdr
==
NEXTHDR_NONE
)
{
if
(
nexthdr
==
NEXTHDR_NONE
)
break
;
}
/* ESP -> evaluate */
if
(
nexthdr
==
NEXTHDR_ESP
)
{
temp
|=
MASK_ESP
;
break
;
}
hdr
=
(
struct
ipv6_opt_hdr
*
)
skb
->
data
+
ptr
;
hp
=
skb_header_pointer
(
skb
,
ptr
,
sizeof
(
_hdr
),
&
_hdr
);
BUG_ON
(
hp
==
NULL
);
/* Calculate the header length */
if
(
nexthdr
==
NEXTHDR_FRAGMENT
)
{
if
(
nexthdr
==
NEXTHDR_FRAGMENT
)
hdrlen
=
8
;
}
else
if
(
nexthdr
==
NEXTHDR_AUTH
)
hdrlen
=
(
hdr
->
hdrlen
+
2
)
<<
2
;
else
if
(
nexthdr
==
NEXTHDR_AUTH
)
hdrlen
=
(
hp
->
hdrlen
+
2
)
<<
2
;
else
hdrlen
=
ipv6_optlen
(
hdr
);
hdrlen
=
ipv6_optlen
(
hp
);
/* set the flag */
switch
(
nexthdr
){
switch
(
nexthdr
)
{
case
NEXTHDR_HOP
:
case
NEXTHDR_ROUTING
:
case
NEXTHDR_FRAGMENT
:
...
...
@@ -107,33 +106,34 @@ match(const struct sk_buff *skb,
default:
DEBUGP
(
"ipv6_esp match: unknown nextheader %u
\n
"
,
nexthdr
);
return
0
;
break
;
}
nexthdr
=
hdr
->
nexthdr
;
nexthdr
=
hp
->
nexthdr
;
len
-=
hdrlen
;
ptr
+=
hdrlen
;
if
(
ptr
>
skb
->
len
)
{
if
(
ptr
>
skb
->
len
)
{
DEBUGP
(
"ipv6_esp: new pointer too large!
\n
"
);
break
;
}
}
/* ESP header not found */
if
(
temp
!=
MASK_ESP
)
return
0
;
if
(
temp
!=
MASK_ESP
)
return
0
;
if
(
len
<
(
int
)
sizeof
(
struct
ip_esp_hdr
))
{
if
(
len
<
sizeof
(
struct
ip_esp_hdr
))
{
*
hotdrop
=
1
;
return
0
;
}
esp
=
(
struct
ip_esp_hdr
*
)
(
skb
->
data
+
ptr
);
eh
=
skb_header_pointer
(
skb
,
ptr
,
sizeof
(
_esp
),
&
_esp
);
BUG_ON
(
eh
==
NULL
);
DEBUGP
(
"IPv6 ESP SPI %u %08X
\n
"
,
ntohl
(
e
sp
->
spi
),
ntohl
(
esp
->
spi
));
DEBUGP
(
"IPv6 ESP SPI %u %08X
\n
"
,
ntohl
(
e
h
->
spi
),
ntohl
(
eh
->
spi
));
return
(
e
sp
!=
NULL
)
return
(
e
h
!=
NULL
)
&&
spi_match
(
espinfo
->
spis
[
0
],
espinfo
->
spis
[
1
],
ntohl
(
e
sp
->
spi
),
ntohl
(
e
h
->
spi
),
!!
(
espinfo
->
invflags
&
IP6T_ESP_INV_SPI
));
}
...
...
@@ -157,7 +157,6 @@ checkentry(const char *tablename,
espinfo
->
invflags
);
return
0
;
}
return
1
;
}
...
...
net/ipv6/netfilter/ip6t_eui64.c
View file @
b2928fba
...
...
@@ -24,8 +24,7 @@ match(const struct sk_buff *skb,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
unsigned
int
protoff
,
int
*
hotdrop
)
{
...
...
net/ipv6/netfilter/ip6t_frag.c
View file @
b2928fba
...
...
@@ -45,11 +45,10 @@ match(const struct sk_buff *skb,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
int
offset
,
const
void
*
protohdr
,
u_int16_t
datalen
,
unsigned
int
protoff
,
int
*
hotdrop
)
{
struct
frag_hdr
*
frag
=
NULL
;
struct
frag_hdr
_frag
,
*
fh
=
NULL
;
const
struct
ip6t_frag
*
fraginfo
=
matchinfo
;
unsigned
int
temp
;
int
len
;
...
...
@@ -66,7 +65,7 @@ match(const struct sk_buff *skb,
temp
=
0
;
while
(
ip6t_ext_hdr
(
nexthdr
))
{
struct
ipv6_opt_hdr
*
hdr
;
struct
ipv6_opt_hdr
_hdr
,
*
hp
;
DEBUGP
(
"ipv6_frag header iteration
\n
"
);
...
...
@@ -82,15 +81,16 @@ match(const struct sk_buff *skb,
break
;
}
hdr
=
(
struct
ipv6_opt_hdr
*
)(
skb
->
data
+
ptr
);
hp
=
skb_header_pointer
(
skb
,
ptr
,
sizeof
(
_hdr
),
&
_hdr
);
BUG_ON
(
hp
==
NULL
);
/* Calculate the header length */
if
(
nexthdr
==
NEXTHDR_FRAGMENT
)
{
hdrlen
=
8
;
}
else
if
(
nexthdr
==
NEXTHDR_AUTH
)
hdrlen
=
(
h
dr
->
hdrlen
+
2
)
<<
2
;
hdrlen
=
(
h
p
->
hdrlen
+
2
)
<<
2
;
else
hdrlen
=
ipv6_optlen
(
h
dr
);
hdrlen
=
ipv6_optlen
(
h
p
);
/* FRAG -> evaluate */
if
(
nexthdr
==
NEXTHDR_FRAGMENT
)
{
...
...
@@ -113,7 +113,7 @@ match(const struct sk_buff *skb,
break
;
}
nexthdr
=
h
dr
->
nexthdr
;
nexthdr
=
h
p
->
nexthdr
;
len
-=
hdrlen
;
ptr
+=
hdrlen
;
if
(
ptr
>
skb
->
len
)
{
...
...
@@ -130,57 +130,58 @@ match(const struct sk_buff *skb,
return
0
;
}
frag
=
(
struct
frag_hdr
*
)
(
skb
->
data
+
ptr
);
fh
=
skb_header_pointer
(
skb
,
ptr
,
sizeof
(
_frag
),
&
_frag
);
BUG_ON
(
fh
==
NULL
);
DEBUGP
(
"INFO %04X "
,
f
rag
->
frag_off
);
DEBUGP
(
"OFFSET %04X "
,
ntohs
(
f
rag
->
frag_off
)
&
~
0x7
);
DEBUGP
(
"RES %02X %04X"
,
f
rag
->
reserved
,
ntohs
(
frag
->
frag_off
)
&
0x6
);
DEBUGP
(
"MF %04X "
,
f
rag
->
frag_off
&
htons
(
IP6_MF
));
DEBUGP
(
"ID %u %08X
\n
"
,
ntohl
(
f
rag
->
identification
),
ntohl
(
f
rag
->
identification
));
DEBUGP
(
"INFO %04X "
,
f
h
->
frag_off
);
DEBUGP
(
"OFFSET %04X "
,
ntohs
(
f
h
->
frag_off
)
&
~
0x7
);
DEBUGP
(
"RES %02X %04X"
,
f
h
->
reserved
,
ntohs
(
fh
->
frag_off
)
&
0x6
);
DEBUGP
(
"MF %04X "
,
f
h
->
frag_off
&
htons
(
IP6_MF
));
DEBUGP
(
"ID %u %08X
\n
"
,
ntohl
(
f
h
->
identification
),
ntohl
(
f
h
->
identification
));
DEBUGP
(
"IPv6 FRAG id %02X "
,
(
id_match
(
fraginfo
->
ids
[
0
],
fraginfo
->
ids
[
1
],
ntohl
(
f
rag
->
identification
),
ntohl
(
f
h
->
identification
),
!!
(
fraginfo
->
invflags
&
IP6T_FRAG_INV_IDS
))));
DEBUGP
(
"res %02X %02X%04X %02X "
,
(
fraginfo
->
flags
&
IP6T_FRAG_RES
),
f
rag
->
reserved
,
ntohs
(
f
rag
->
frag_off
)
&
0x6
,
(
fraginfo
->
flags
&
IP6T_FRAG_RES
),
f
h
->
reserved
,
ntohs
(
f
h
->
frag_off
)
&
0x6
,
!
((
fraginfo
->
flags
&
IP6T_FRAG_RES
)
&&
(
f
rag
->
reserved
||
(
ntohs
(
frag
->
frag_off
)
&
0x
6
))));
&&
(
f
h
->
reserved
||
(
ntohs
(
fh
->
frag_off
)
&
0x0
6
))));
DEBUGP
(
"first %02X %02X %02X "
,
(
fraginfo
->
flags
&
IP6T_FRAG_FST
),
ntohs
(
f
rag
->
frag_off
)
&
~
0x7
,
ntohs
(
f
h
->
frag_off
)
&
~
0x7
,
!
((
fraginfo
->
flags
&
IP6T_FRAG_FST
)
&&
(
ntohs
(
f
rag
->
frag_off
)
&
~
0x7
)));
&&
(
ntohs
(
f
h
->
frag_off
)
&
~
0x7
)));
DEBUGP
(
"mf %02X %02X %02X "
,
(
fraginfo
->
flags
&
IP6T_FRAG_MF
),
ntohs
(
f
rag
->
frag_off
)
&
IP6_MF
,
ntohs
(
f
h
->
frag_off
)
&
IP6_MF
,
!
((
fraginfo
->
flags
&
IP6T_FRAG_MF
)
&&
!
((
ntohs
(
f
rag
->
frag_off
)
&
IP6_MF
))));
&&
!
((
ntohs
(
f
h
->
frag_off
)
&
IP6_MF
))));
DEBUGP
(
"last %02X %02X %02X
\n
"
,
(
fraginfo
->
flags
&
IP6T_FRAG_NMF
),
ntohs
(
f
rag
->
frag_off
)
&
IP6_MF
,
ntohs
(
f
h
->
frag_off
)
&
IP6_MF
,
!
((
fraginfo
->
flags
&
IP6T_FRAG_NMF
)
&&
(
ntohs
(
f
rag
->
frag_off
)
&
IP6_MF
)));
&&
(
ntohs
(
f
h
->
frag_off
)
&
IP6_MF
)));
return
(
f
rag
!=
NULL
)
return
(
f
h
!=
NULL
)
&&
(
id_match
(
fraginfo
->
ids
[
0
],
fraginfo
->
ids
[
1
],
ntohl
(
f
rag
->
identification
),
ntohl
(
f
h
->
identification
),
!!
(
fraginfo
->
invflags
&
IP6T_FRAG_INV_IDS
)))
&&
!
((
fraginfo
->
flags
&
IP6T_FRAG_RES
)
&&
(
f
rag
->
reserved
||
(
ntohs
(
frag
->
frag_off
)
&
0x6
)))
&&
(
f
h
->
reserved
||
(
ntohs
(
fh
->
frag_off
)
&
0x6
)))
&&
!
((
fraginfo
->
flags
&
IP6T_FRAG_FST
)
&&
(
ntohs
(
f
rag
->
frag_off
)
&
~
0x7
))
&&
(
ntohs
(
f
h
->
frag_off
)
&
~
0x7
))
&&
!
((
fraginfo
->
flags
&
IP6T_FRAG_MF
)
&&
!
(
ntohs
(
f
rag
->
frag_off
)
&
IP6_MF
))
&&
!
(
ntohs
(
f
h
->
frag_off
)
&
IP6_MF
))
&&
!
((
fraginfo
->
flags
&
IP6T_FRAG_NMF
)
&&
(
ntohs
(
f
rag
->
frag_off
)
&
IP6_MF
));
&&
(
ntohs
(
f
h
->
frag_off
)
&
IP6_MF
));
}
/* Called when user tries to insert an entry of this type. */
...
...
net/ipv6/netfilter/ip6t_hbh.c
View file @
b2928fba
...
...
@@ -59,8 +59,7 @@ match(const struct sk_buff *skb,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
int
offset
,
const
void
*
protohdr
,
u_int16_t
datalen
,
unsigned
int
protoff
,
int
*
hotdrop
)
{
struct
ipv6_opt_hdr
*
optsh
=
NULL
;
...
...
net/ipv6/netfilter/ip6t_hl.c
View file @
b2928fba
...
...
@@ -20,7 +20,7 @@ MODULE_LICENSE("GPL");
static
int
match
(
const
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
int
offset
,
unsigned
int
protoff
,
int
*
hotdrop
)
{
const
struct
ip6t_hl_info
*
info
=
matchinfo
;
...
...
net/ipv6/netfilter/ip6t_ipv6header.c
View file @
b2928fba
...
...
@@ -31,8 +31,7 @@ ipv6header_match(const struct sk_buff *skb,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
int
offset
,
const
void
*
protohdr
,
u_int16_t
datalen
,
unsigned
int
protoff
,
int
*
hotdrop
)
{
const
struct
ip6t_ipv6header_info
*
info
=
matchinfo
;
...
...
net/ipv6/netfilter/ip6t_length.c
View file @
b2928fba
...
...
@@ -23,8 +23,7 @@ match(const struct sk_buff *skb,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
unsigned
int
protoff
,
int
*
hotdrop
)
{
const
struct
ip6t_length_info
*
info
=
matchinfo
;
...
...
net/ipv6/netfilter/ip6t_limit.c
View file @
b2928fba
...
...
@@ -57,8 +57,7 @@ ip6t_limit_match(const struct sk_buff *skb,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
unsigned
int
protoff
,
int
*
hotdrop
)
{
struct
ip6t_rateinfo
*
r
=
((
struct
ip6t_rateinfo
*
)
matchinfo
)
->
master
;
...
...
net/ipv6/netfilter/ip6t_mac.c
View file @
b2928fba
...
...
@@ -25,8 +25,7 @@ match(const struct sk_buff *skb,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
unsigned
int
protoff
,
int
*
hotdrop
)
{
const
struct
ip6t_mac_info
*
info
=
matchinfo
;
...
...
net/ipv6/netfilter/ip6t_mark.c
View file @
b2928fba
...
...
@@ -24,8 +24,7 @@ match(const struct sk_buff *skb,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
unsigned
int
protoff
,
int
*
hotdrop
)
{
const
struct
ip6t_mark_info
*
info
=
matchinfo
;
...
...
net/ipv6/netfilter/ip6t_multiport.c
View file @
b2928fba
...
...
@@ -53,28 +53,32 @@ match(const struct sk_buff *skb,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
unsigned
int
protoff
,
int
*
hotdrop
)
{
const
struct
udphdr
*
udp
=
hd
r
;
u16
_ports
[
2
],
*
ppt
r
;
const
struct
ip6t_multiport
*
multiinfo
=
matchinfo
;
/* Must be big enough to read ports. */
if
(
offset
==
0
&&
datalen
<
sizeof
(
struct
udphdr
))
{
/* Must not be a fragment. */
if
(
offset
)
return
0
;
/* Must be big enough to read ports (both UDP and TCP have
them at the start). */
pptr
=
skb_header_pointer
(
skb
,
protoff
,
sizeof
(
_ports
),
&
_ports
[
0
]);
if
(
pptr
==
NULL
)
{
/* 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
(
"ip6t_multiport:"
" Dropping evil offset=0 tinygram.
\n
"
);
*
hotdrop
=
1
;
return
0
;
}
/* Must not be a fragment. */
return
!
offset
&&
ports_match
(
multiinfo
->
ports
,
return
ports_match
(
multiinfo
->
ports
,
multiinfo
->
flags
,
multiinfo
->
count
,
ntohs
(
udp
->
source
),
ntohs
(
udp
->
dest
));
ntohs
(
pptr
[
0
]),
ntohs
(
pptr
[
1
]
));
}
/* Called when user tries to insert an entry of this type. */
...
...
net/ipv6/netfilter/ip6t_owner.c
View file @
b2928fba
...
...
@@ -92,8 +92,7 @@ match(const struct sk_buff *skb,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
unsigned
int
protoff
,
int
*
hotdrop
)
{
const
struct
ip6t_owner_info
*
info
=
matchinfo
;
...
...
net/ipv6/netfilter/ip6t_physdev.c
View file @
b2928fba
...
...
@@ -26,8 +26,7 @@ match(const struct sk_buff *skb,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
int
offset
,
const
void
*
hdr
,
u_int16_t
datalen
,
unsigned
int
protoff
,
int
*
hotdrop
)
{
int
i
;
...
...
net/ipv6/netfilter/ip6t_rt.c
View file @
b2928fba
...
...
@@ -47,11 +47,10 @@ match(const struct sk_buff *skb,
const
struct
net_device
*
out
,
const
void
*
matchinfo
,
int
offset
,
const
void
*
protohdr
,
u_int16_t
datalen
,
unsigned
int
protoff
,
int
*
hotdrop
)
{
struct
ipv6_rt_hdr
*
route
=
NULL
;
struct
ipv6_rt_hdr
_route
,
*
rh
=
NULL
;
const
struct
ip6t_rt
*
rtinfo
=
matchinfo
;
unsigned
int
temp
;
unsigned
int
len
;
...
...
@@ -59,6 +58,7 @@ match(const struct sk_buff *skb,
unsigned
int
ptr
;
unsigned
int
hdrlen
=
0
;
unsigned
int
ret
=
0
;
struct
in6_addr
*
ap
,
_addr
;
/* type of the 1st exthdr */
nexthdr
=
skb
->
nh
.
ipv6h
->
nexthdr
;
...
...
@@ -69,7 +69,7 @@ match(const struct sk_buff *skb,
temp
=
0
;
while
(
ip6t_ext_hdr
(
nexthdr
))
{
struct
ipv6_opt_hdr
*
hdr
;
struct
ipv6_opt_hdr
_hdr
,
*
hp
;
DEBUGP
(
"ipv6_rt header iteration
\n
"
);
...
...
@@ -85,15 +85,16 @@ match(const struct sk_buff *skb,
break
;
}
hdr
=
(
struct
ipv6_opt_hdr
*
)(
skb
->
data
+
ptr
);
hp
=
skb_header_pointer
(
skb
,
ptr
,
sizeof
(
_hdr
),
&
_hdr
);
BUG_ON
(
hp
==
NULL
);
/* Calculate the header length */
if
(
nexthdr
==
NEXTHDR_FRAGMENT
)
{
hdrlen
=
8
;
}
else
if
(
nexthdr
==
NEXTHDR_AUTH
)
hdrlen
=
(
h
dr
->
hdrlen
+
2
)
<<
2
;
hdrlen
=
(
h
p
->
hdrlen
+
2
)
<<
2
;
else
hdrlen
=
ipv6_optlen
(
h
dr
);
hdrlen
=
ipv6_optlen
(
h
p
);
/* ROUTING -> evaluate */
if
(
nexthdr
==
NEXTHDR_ROUTING
)
{
...
...
@@ -116,7 +117,7 @@ match(const struct sk_buff *skb,
break
;
}
nexthdr
=
h
dr
->
nexthdr
;
nexthdr
=
h
p
->
nexthdr
;
len
-=
hdrlen
;
ptr
+=
hdrlen
;
if
(
ptr
>
skb
->
len
)
{
...
...
@@ -138,20 +139,21 @@ match(const struct sk_buff *skb,
return
0
;
}
route
=
(
struct
ipv6_rt_hdr
*
)
(
skb
->
data
+
ptr
);
rh
=
skb_header_pointer
(
skb
,
ptr
,
sizeof
(
_route
),
&
_route
);
BUG_ON
(
rh
==
NULL
);
DEBUGP
(
"IPv6 RT LEN %u %u "
,
hdrlen
,
r
oute
->
hdrlen
);
DEBUGP
(
"TYPE %04X "
,
r
oute
->
type
);
DEBUGP
(
"SGS_LEFT %u %02X
\n
"
,
r
oute
->
segments_left
,
route
->
segments_left
);
DEBUGP
(
"IPv6 RT LEN %u %u "
,
hdrlen
,
r
h
->
hdrlen
);
DEBUGP
(
"TYPE %04X "
,
r
h
->
type
);
DEBUGP
(
"SGS_LEFT %u %02X
\n
"
,
r
h
->
segments_left
,
rh
->
segments_left
);
DEBUGP
(
"IPv6 RT segsleft %02X "
,
(
segsleft_match
(
rtinfo
->
segsleft
[
0
],
rtinfo
->
segsleft
[
1
],
r
oute
->
segments_left
,
r
h
->
segments_left
,
!!
(
rtinfo
->
invflags
&
IP6T_RT_INV_SGS
))));
DEBUGP
(
"type %02X %02X %02X "
,
rtinfo
->
rt_type
,
r
oute
->
type
,
rtinfo
->
rt_type
,
r
h
->
type
,
(
!
(
rtinfo
->
flags
&
IP6T_RT_TYP
)
||
((
rtinfo
->
rt_type
==
r
oute
->
type
)
^
((
rtinfo
->
rt_type
==
r
h
->
type
)
^
!!
(
rtinfo
->
invflags
&
IP6T_RT_INV_TYP
))));
DEBUGP
(
"len %02X %04X %02X "
,
rtinfo
->
hdrlen
,
hdrlen
,
...
...
@@ -159,13 +161,13 @@ match(const struct sk_buff *skb,
((
rtinfo
->
hdrlen
==
hdrlen
)
^
!!
(
rtinfo
->
invflags
&
IP6T_RT_INV_LEN
))));
DEBUGP
(
"res %02X %02X %02X "
,
(
rtinfo
->
flags
&
IP6T_RT_RES
),
((
struct
rt0_hdr
*
)
r
oute
)
->
bitmap
,
!
((
rtinfo
->
flags
&
IP6T_RT_RES
)
&&
(((
struct
rt0_hdr
*
)
r
oute
)
->
bitmap
)));
(
rtinfo
->
flags
&
IP6T_RT_RES
),
((
struct
rt0_hdr
*
)
r
h
)
->
bitmap
,
!
((
rtinfo
->
flags
&
IP6T_RT_RES
)
&&
(((
struct
rt0_hdr
*
)
r
h
)
->
bitmap
)));
ret
=
(
r
oute
!=
NULL
)
ret
=
(
r
h
!=
NULL
)
&&
(
segsleft_match
(
rtinfo
->
segsleft
[
0
],
rtinfo
->
segsleft
[
1
],
r
oute
->
segments_left
,
r
h
->
segments_left
,
!!
(
rtinfo
->
invflags
&
IP6T_RT_INV_SGS
)))
&&
(
!
(
rtinfo
->
flags
&
IP6T_RT_LEN
)
||
...
...
@@ -173,13 +175,19 @@ match(const struct sk_buff *skb,
!!
(
rtinfo
->
invflags
&
IP6T_RT_INV_LEN
)))
&&
(
!
(
rtinfo
->
flags
&
IP6T_RT_TYP
)
||
((
rtinfo
->
rt_type
==
route
->
type
)
^
!!
(
rtinfo
->
invflags
&
IP6T_RT_INV_TYP
)))
&&
!
((
rtinfo
->
flags
&
IP6T_RT_RES
)
&&
(((
struct
rt0_hdr
*
)
route
)
->
bitmap
));
((
rtinfo
->
rt_type
==
rh
->
type
)
^
!!
(
rtinfo
->
invflags
&
IP6T_RT_INV_TYP
)));
if
(
ret
&&
(
rtinfo
->
flags
&
IP6T_RT_RES
))
{
u_int32_t
*
bp
,
_bitmap
;
bp
=
skb_header_pointer
(
skb
,
ptr
+
offsetof
(
struct
rt0_hdr
,
bitmap
),
sizeof
(
_bitmap
),
&
_bitmap
);
ret
=
(
*
bp
==
0
);
}
DEBUGP
(
"#%d "
,
rtinfo
->
addrnr
);
temp
=
len
=
ptr
=
0
;
if
(
!
(
rtinfo
->
flags
&
IP6T_RT_FST
)
){
return
ret
;
}
else
if
(
rtinfo
->
flags
&
IP6T_RT_FST_NSTRICT
)
{
...
...
@@ -188,32 +196,27 @@ match(const struct sk_buff *skb,
DEBUGP
(
"There isn't enough space
\n
"
);
return
0
;
}
else
{
unsigned
int
i
=
0
;
DEBUGP
(
"#%d "
,
rtinfo
->
addrnr
);
ptr
=
0
;
for
(
temp
=
0
;
temp
<
(
unsigned
int
)((
hdrlen
-
8
)
/
16
);
temp
++
){
len
=
0
;
while
((
u8
)(((
struct
rt0_hdr
*
)
route
)
->
addr
[
temp
].
s6_addr
[
len
])
==
(
u8
)(
rtinfo
->
addrs
[
ptr
].
s6_addr
[
len
])){
DEBUGP
(
"%02X?%02X "
,
(
u8
)(((
struct
rt0_hdr
*
)
route
)
->
addr
[
temp
].
s6_addr
[
len
]),
(
u8
)(
rtinfo
->
addrs
[
ptr
].
s6_addr
[
len
]));
len
++
;
if
(
len
==
16
)
break
;
ap
=
skb_header_pointer
(
skb
,
ptr
+
sizeof
(
struct
rt0_hdr
)
+
temp
*
sizeof
(
_addr
),
sizeof
(
_addr
),
&
_addr
);
BUG_ON
(
ap
==
NULL
);
if
(
!
ipv6_addr_cmp
(
ap
,
&
rtinfo
->
addrs
[
i
]))
{
DEBUGP
(
"i=%d temp=%d;
\n
"
,
i
,
temp
);
i
++
;
}
if
(
len
==
16
)
{
DEBUGP
(
"ptr=%d temp=%d;
\n
"
,
ptr
,
temp
);
ptr
++
;
}
else
{
DEBUGP
(
"%02X?%02X "
,
(
u8
)(((
struct
rt0_hdr
*
)
route
)
->
addr
[
temp
].
s6_addr
[
len
]),
(
u8
)(
rtinfo
->
addrs
[
ptr
].
s6_addr
[
len
]));
DEBUGP
(
"!ptr=%d temp=%d;
\n
"
,
ptr
,
temp
);
}
if
(
ptr
==
rtinfo
->
addrnr
)
break
;
if
(
i
==
rtinfo
->
addrnr
)
break
;
}
DEBUGP
(
"
ptr=%d len=%d #%d
\n
"
,
ptr
,
len
,
rtinfo
->
addrnr
);
if
(
(
len
==
16
)
&&
(
ptr
==
rtinfo
->
addrnr
)
)
DEBUGP
(
"
i=%d #%d
\n
"
,
i
,
rtinfo
->
addrnr
);
if
(
i
==
rtinfo
->
addrnr
)
return
ret
;
else
return
0
;
}
...
...
@@ -225,26 +228,19 @@ match(const struct sk_buff *skb,
}
else
{
DEBUGP
(
"#%d "
,
rtinfo
->
addrnr
);
for
(
temp
=
0
;
temp
<
rtinfo
->
addrnr
;
temp
++
){
len
=
0
;
while
((
u8
)(((
struct
rt0_hdr
*
)
route
)
->
addr
[
temp
].
s6_addr
[
len
])
==
(
u8
)(
rtinfo
->
addrs
[
temp
].
s6_addr
[
len
])){
DEBUGP
(
"%02X?%02X "
,
(
u8
)(((
struct
rt0_hdr
*
)
route
)
->
addr
[
temp
].
s6_addr
[
len
]),
(
u8
)(
rtinfo
->
addrs
[
temp
].
s6_addr
[
len
]));
len
++
;
if
(
len
==
16
)
break
;
}
if
(
len
!=
16
)
{
DEBUGP
(
"%02X?%02X "
,
(
u8
)(((
struct
rt0_hdr
*
)
route
)
->
addr
[
temp
].
s6_addr
[
len
]),
(
u8
)(
rtinfo
->
addrs
[
temp
].
s6_addr
[
len
]));
DEBUGP
(
"!len=%d temp=%d;
\n
"
,
len
,
temp
);
ap
=
skb_header_pointer
(
skb
,
ptr
+
sizeof
(
struct
rt0_hdr
)
+
temp
*
sizeof
(
_addr
),
sizeof
(
_addr
),
&
_addr
);
BUG_ON
(
ap
==
NULL
);
if
(
ipv6_addr_cmp
(
ap
,
&
rtinfo
->
addrs
[
temp
]))
break
;
}
}
DEBUGP
(
"temp=%d len=%d #%d
\n
"
,
temp
,
len
,
rtinfo
->
addrnr
);
if
(
(
len
==
16
)
&&
(
temp
==
rtinfo
->
addrnr
)
&&
(
temp
==
(
unsigned
int
)((
hdrlen
-
8
)
/
16
)))
DEBUGP
(
"temp=%d #%d
\n
"
,
temp
,
rtinfo
->
addrnr
);
if
((
temp
==
rtinfo
->
addrnr
)
&&
(
temp
==
(
unsigned
int
)((
hdrlen
-
8
)
/
16
)))
return
ret
;
else
return
0
;
}
...
...
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