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
11bde9b1
Commit
11bde9b1
authored
Oct 25, 2004
by
David S. Miller
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://212.42.230.204/nf-2.6
into nuts.davemloft.net:/disk1/BK/net-2.6
parents
c3efef68
d110bbcc
Changes
23
Show whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
744 additions
and
670 deletions
+744
-670
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
+5
-6
net/ipv4/netfilter/ipt_CONNMARK.c
net/ipv4/netfilter/ipt_CONNMARK.c
+1
-1
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
+57
-46
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
+56
-45
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 @
11bde9b1
...
...
@@ -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 @
11bde9b1
...
...
@@ -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
;
...
...
@@ -436,13 +434,14 @@ __ip_conntrack_confirm(struct sk_buff *skb)
add_timer
(
&
ct
->
timeout
);
atomic_inc
(
&
ct
->
ct_general
.
use
);
set_bit
(
IPS_CONFIRMED_BIT
,
&
ct
->
status
);
WRITE_UNLOCK
(
&
ip_conntrack_lock
);
CONNTRACK_STAT_INC
(
insert
);
WRITE_UNLOCK
(
&
ip_conntrack_lock
);
return
NF_ACCEPT
;
}
WRITE_UNLOCK
(
&
ip_conntrack_lock
);
CONNTRACK_STAT_INC
(
insert_failed
);
WRITE_UNLOCK
(
&
ip_conntrack_lock
);
return
NF_DROP
;
}
...
...
net/ipv4/netfilter/ipt_CONNMARK.c
View file @
11bde9b1
...
...
@@ -60,7 +60,7 @@ target(struct sk_buff **pskb,
break
;
case
IPT_CONNMARK_RESTORE
:
nfmark
=
(
*
pskb
)
->
nfmark
;
diff
=
(
ct
->
mark
^
nfmark
&
markinfo
->
mask
)
;
diff
=
(
ct
->
mark
^
nfmark
)
&
markinfo
->
mask
;
if
(
diff
!=
0
)
{
(
*
pskb
)
->
nfmark
=
nfmark
^
diff
;
(
*
pskb
)
->
nfcache
|=
NFC_ALTERED
;
...
...
net/ipv4/netfilter/ipt_MASQUERADE.c
View file @
11bde9b1
...
...
@@ -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 @
11bde9b1
...
...
@@ -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 @
11bde9b1
...
...
@@ -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 @
11bde9b1
...
...
@@ -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 @
11bde9b1
...
...
@@ -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 @
11bde9b1
...
...
@@ -7,7 +7,6 @@
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/ipv6.h>
...
...
@@ -20,8 +19,6 @@
#include <linux/netfilter_ipv6/ip6_tables.h>
#include <linux/netfilter_ipv6/ip6t_opts.h>
#define LOW(n) (n & 0x00FF)
#define HOPBYHOP 0
MODULE_LICENSE
(
"GPL"
);
...
...
@@ -48,8 +45,8 @@ MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
* 0 -> invariant
* 1 -> can change the routing
* (Type & 0x1F) Type
* 0 -> P
AD0
(only 1 byte!)
* 1 -> P
AD1
LENGTH info (total length = length + 2)
* 0 -> P
ad1
(only 1 byte!)
* 1 -> P
adN
LENGTH info (total length = length + 2)
* C0 | 2 -> JUMBO 4 x x x x ( xxxx > 64k )
* 5 -> RTALERT 2 x x
*/
...
...
@@ -60,11 +57,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_opt_hdr
*
optsh
=
NULL
;
struct
ipv6_opt_hdr
_optsh
,
*
oh
;
const
struct
ip6t_opts
*
optinfo
=
matchinfo
;
unsigned
int
temp
;
unsigned
int
len
;
...
...
@@ -72,7 +68,9 @@ match(const struct sk_buff *skb,
unsigned
int
ptr
;
unsigned
int
hdrlen
=
0
;
unsigned
int
ret
=
0
;
u_int16_t
*
optdesc
=
NULL
;
u8
_opttype
,
*
tp
=
NULL
;
u8
_optlen
,
*
lp
=
NULL
;
unsigned
int
optlen
;
/* type of the 1st exthdr */
nexthdr
=
skb
->
nh
.
ipv6h
->
nexthdr
;
...
...
@@ -83,7 +81,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_opts header iteration
\n
"
);
...
...
@@ -99,15 +97,16 @@ match(const struct sk_buff *skb,
break
;
}
hdr
=
(
void
*
)(
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
);
/* OPTS -> evaluate */
#if HOPBYHOP
...
...
@@ -135,7 +134,7 @@ match(const struct sk_buff *skb,
break
;
}
nexthdr
=
h
dr
->
nexthdr
;
nexthdr
=
h
p
->
nexthdr
;
len
-=
hdrlen
;
ptr
+=
hdrlen
;
if
(
ptr
>
skb
->
len
)
{
...
...
@@ -161,9 +160,10 @@ match(const struct sk_buff *skb,
return
0
;
}
optsh
=
(
void
*
)(
skb
->
data
)
+
ptr
;
oh
=
skb_header_pointer
(
skb
,
ptr
,
sizeof
(
_optsh
),
&
_optsh
);
BUG_ON
(
oh
==
NULL
);
DEBUGP
(
"IPv6 OPTS LEN %u %u "
,
hdrlen
,
o
pts
h
->
hdrlen
);
DEBUGP
(
"IPv6 OPTS LEN %u %u "
,
hdrlen
,
oh
->
hdrlen
);
DEBUGP
(
"len %02X %04X %02X "
,
optinfo
->
hdrlen
,
hdrlen
,
...
...
@@ -171,13 +171,12 @@ match(const struct sk_buff *skb,
((
optinfo
->
hdrlen
==
hdrlen
)
^
!!
(
optinfo
->
invflags
&
IP6T_OPTS_INV_LEN
))));
ret
=
(
o
pts
h
!=
NULL
)
ret
=
(
oh
!=
NULL
)
&&
(
!
(
optinfo
->
flags
&
IP6T_OPTS_LEN
)
||
((
optinfo
->
hdrlen
==
hdrlen
)
^
!!
(
optinfo
->
invflags
&
IP6T_OPTS_INV_LEN
)));
temp
=
len
=
0
;
ptr
+=
2
;
hdrlen
-=
2
;
if
(
!
(
optinfo
->
flags
&
IP6T_OPTS_OPTS
)
){
...
...
@@ -188,48 +187,59 @@ match(const struct sk_buff *skb,
DEBUGP
(
"Strict "
);
DEBUGP
(
"#%d "
,
optinfo
->
optsnr
);
for
(
temp
=
0
;
temp
<
optinfo
->
optsnr
;
temp
++
){
optdesc
=
(
void
*
)(
skb
->
data
)
+
ptr
;
/* type field exists ? */
if
(
hdrlen
<
1
)
break
;
tp
=
skb_header_pointer
(
skb
,
ptr
,
sizeof
(
_opttype
),
&
_opttype
);
if
(
tp
==
NULL
)
break
;
/* Type check */
if
(
(
unsigned
char
)
*
optdesc
!=
(
optinfo
->
opts
[
temp
]
&
0xFF00
)
>>
8
){
if
(
*
tp
!=
(
optinfo
->
opts
[
temp
]
&
0xFF00
)
>>
8
){
DEBUGP
(
"Tbad %02X %02X
\n
"
,
(
unsigned
char
)
*
optdesc
,
(
optinfo
->
opts
[
temp
]
&
0xFF00
)
>>
8
);
*
tp
,
(
optinfo
->
opts
[
temp
]
&
0xFF00
)
>>
8
);
return
0
;
}
else
{
DEBUGP
(
"Tok "
);
}
/* Length check */
if
(((
optinfo
->
opts
[
temp
]
&
0x00FF
)
!=
0xFF
)
&&
(
unsigned
char
)
*
optdesc
!=
0
){
if
(
ntohs
((
u16
)
*
optdesc
)
!=
optinfo
->
opts
[
temp
]
){
DEBUGP
(
"Lbad %02X %04X %04X
\n
"
,
(
unsigned
char
)
*
optdesc
,
ntohs
((
u16
)
*
optdesc
),
optinfo
->
opts
[
temp
]);
if
(
*
tp
)
{
u16
spec_len
;
/* length field exists ? */
if
(
hdrlen
<
2
)
break
;
lp
=
skb_header_pointer
(
skb
,
ptr
+
1
,
sizeof
(
_optlen
),
&
_optlen
);
if
(
lp
==
NULL
)
break
;
spec_len
=
optinfo
->
opts
[
temp
]
&
0x00FF
;
if
(
spec_len
!=
0x00FF
&&
spec_len
!=
*
lp
)
{
DEBUGP
(
"Lbad %02X %04X
\n
"
,
*
lp
,
spec_len
);
return
0
;
}
else
{
DEBUGP
(
"Lok "
);
}
}
/* Step to the next */
if
((
unsigned
char
)
*
optdesc
==
0
){
DEBUGP
(
"PAD0
\n
"
);
ptr
++
;
hdrlen
--
;
DEBUGP
(
"Lok "
);
optlen
=
*
lp
+
2
;
}
else
{
ptr
+=
LOW
(
ntohs
(
*
optdesc
));
hdrlen
-=
LOW
(
ntohs
(
*
optdesc
));
DEBUGP
(
"len%04X
\n
"
,
LOW
(
ntohs
(
*
optdesc
)));
DEBUGP
(
"Pad1
\n
"
);
optlen
=
1
;
}
if
(
ptr
>
skb
->
len
||
(
!
hdrlen
&&
(
temp
!=
optinfo
->
optsnr
-
1
)))
{
/* Step to the next */
DEBUGP
(
"len%04X
\n
"
,
optlen
);
if
((
ptr
>
skb
->
len
-
optlen
||
hdrlen
<
optlen
)
&&
(
temp
<
optinfo
->
optsnr
-
1
))
{
DEBUGP
(
"new pointer is too large!
\n
"
);
break
;
}
ptr
+=
optlen
;
hdrlen
-=
optlen
;
}
if
(
temp
==
optinfo
->
optsnr
)
return
ret
;
...
...
@@ -271,6 +281,7 @@ static struct ip6t_match opts_match = {
#endif
.
match
=
&
match
,
.
checkentry
=
&
checkentry
,
.
me
=
THIS_MODULE
,
};
static
int
__init
init
(
void
)
...
...
net/ipv6/netfilter/ip6t_esp.c
View file @
11bde9b1
...
...
@@ -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 @
11bde9b1
...
...
@@ -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 @
11bde9b1
...
...
@@ -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 @
11bde9b1
...
...
@@ -19,8 +19,6 @@
#include <linux/netfilter_ipv6/ip6_tables.h>
#include <linux/netfilter_ipv6/ip6t_opts.h>
#define LOW(n) (n & 0x00FF)
#define HOPBYHOP 1
MODULE_LICENSE
(
"GPL"
);
...
...
@@ -47,8 +45,8 @@ MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
* 0 -> invariant
* 1 -> can change the routing
* (Type & 0x1F) Type
* 0 -> P
AD0
(only 1 byte!)
* 1 -> P
AD1
LENGTH info (total length = length + 2)
* 0 -> P
ad1
(only 1 byte!)
* 1 -> P
adN
LENGTH info (total length = length + 2)
* C0 | 2 -> JUMBO 4 x x x x ( xxxx > 64k )
* 5 -> RTALERT 2 x x
*/
...
...
@@ -59,11 +57,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_opt_hdr
*
optsh
=
NULL
;
struct
ipv6_opt_hdr
_optsh
,
*
oh
;
const
struct
ip6t_opts
*
optinfo
=
matchinfo
;
unsigned
int
temp
;
unsigned
int
len
;
...
...
@@ -71,7 +68,9 @@ match(const struct sk_buff *skb,
unsigned
int
ptr
;
unsigned
int
hdrlen
=
0
;
unsigned
int
ret
=
0
;
u_int16_t
*
optdesc
=
NULL
;
u8
_opttype
,
*
tp
=
NULL
;
u8
_optlen
,
*
lp
=
NULL
;
unsigned
int
optlen
;
/* type of the 1st exthdr */
nexthdr
=
skb
->
nh
.
ipv6h
->
nexthdr
;
...
...
@@ -82,7 +81,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_opts header iteration
\n
"
);
...
...
@@ -98,15 +97,16 @@ match(const struct sk_buff *skb,
break
;
}
hdr
=
(
void
*
)(
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
);
/* OPTS -> evaluate */
#if HOPBYHOP
...
...
@@ -134,7 +134,7 @@ match(const struct sk_buff *skb,
break
;
}
nexthdr
=
h
dr
->
nexthdr
;
nexthdr
=
h
p
->
nexthdr
;
len
-=
hdrlen
;
ptr
+=
hdrlen
;
if
(
ptr
>
skb
->
len
)
{
...
...
@@ -160,9 +160,10 @@ match(const struct sk_buff *skb,
return
0
;
}
optsh
=
(
void
*
)(
skb
->
data
)
+
ptr
;
oh
=
skb_header_pointer
(
skb
,
ptr
,
sizeof
(
_optsh
),
&
_optsh
);
BUG_ON
(
oh
==
NULL
);
DEBUGP
(
"IPv6 OPTS LEN %u %u "
,
hdrlen
,
o
pts
h
->
hdrlen
);
DEBUGP
(
"IPv6 OPTS LEN %u %u "
,
hdrlen
,
oh
->
hdrlen
);
DEBUGP
(
"len %02X %04X %02X "
,
optinfo
->
hdrlen
,
hdrlen
,
...
...
@@ -170,13 +171,12 @@ match(const struct sk_buff *skb,
((
optinfo
->
hdrlen
==
hdrlen
)
^
!!
(
optinfo
->
invflags
&
IP6T_OPTS_INV_LEN
))));
ret
=
(
o
pts
h
!=
NULL
)
ret
=
(
oh
!=
NULL
)
&&
(
!
(
optinfo
->
flags
&
IP6T_OPTS_LEN
)
||
((
optinfo
->
hdrlen
==
hdrlen
)
^
!!
(
optinfo
->
invflags
&
IP6T_OPTS_INV_LEN
)));
temp
=
len
=
0
;
ptr
+=
2
;
hdrlen
-=
2
;
if
(
!
(
optinfo
->
flags
&
IP6T_OPTS_OPTS
)
){
...
...
@@ -187,48 +187,59 @@ match(const struct sk_buff *skb,
DEBUGP
(
"Strict "
);
DEBUGP
(
"#%d "
,
optinfo
->
optsnr
);
for
(
temp
=
0
;
temp
<
optinfo
->
optsnr
;
temp
++
){
optdesc
=
(
void
*
)(
skb
->
data
)
+
ptr
;
/* type field exists ? */
if
(
hdrlen
<
1
)
break
;
tp
=
skb_header_pointer
(
skb
,
ptr
,
sizeof
(
_opttype
),
&
_opttype
);
if
(
tp
==
NULL
)
break
;
/* Type check */
if
(
(
unsigned
char
)
*
optdesc
!=
(
optinfo
->
opts
[
temp
]
&
0xFF00
)
>>
8
){
if
(
*
tp
!=
(
optinfo
->
opts
[
temp
]
&
0xFF00
)
>>
8
){
DEBUGP
(
"Tbad %02X %02X
\n
"
,
(
unsigned
char
)
*
optdesc
,
(
optinfo
->
opts
[
temp
]
&
0xFF00
)
>>
8
);
*
tp
,
(
optinfo
->
opts
[
temp
]
&
0xFF00
)
>>
8
);
return
0
;
}
else
{
DEBUGP
(
"Tok "
);
}
/* Length check */
if
(((
optinfo
->
opts
[
temp
]
&
0x00FF
)
!=
0xFF
)
&&
(
unsigned
char
)
*
optdesc
!=
0
){
if
(
ntohs
((
u16
)
*
optdesc
)
!=
optinfo
->
opts
[
temp
]
){
DEBUGP
(
"Lbad %02X %04X %04X
\n
"
,
(
unsigned
char
)
*
optdesc
,
ntohs
((
u16
)
*
optdesc
),
optinfo
->
opts
[
temp
]);
if
(
*
tp
)
{
u16
spec_len
;
/* length field exists ? */
if
(
hdrlen
<
2
)
break
;
lp
=
skb_header_pointer
(
skb
,
ptr
+
1
,
sizeof
(
_optlen
),
&
_optlen
);
if
(
lp
==
NULL
)
break
;
spec_len
=
optinfo
->
opts
[
temp
]
&
0x00FF
;
if
(
spec_len
!=
0x00FF
&&
spec_len
!=
*
lp
)
{
DEBUGP
(
"Lbad %02X %04X
\n
"
,
*
lp
,
spec_len
);
return
0
;
}
else
{
DEBUGP
(
"Lok "
);
}
}
/* Step to the next */
if
((
unsigned
char
)
*
optdesc
==
0
){
DEBUGP
(
"PAD0
\n
"
);
ptr
++
;
hdrlen
--
;
DEBUGP
(
"Lok "
);
optlen
=
*
lp
+
2
;
}
else
{
ptr
+=
LOW
(
ntohs
(
*
optdesc
));
hdrlen
-=
LOW
(
ntohs
(
*
optdesc
));
DEBUGP
(
"len%04X
\n
"
,
LOW
(
ntohs
(
*
optdesc
)));
DEBUGP
(
"Pad1
\n
"
);
optlen
=
1
;
}
if
(
ptr
>
skb
->
len
||
(
!
hdrlen
&&
(
temp
!=
optinfo
->
optsnr
-
1
)))
{
/* Step to the next */
DEBUGP
(
"len%04X
\n
"
,
optlen
);
if
((
ptr
>
skb
->
len
-
optlen
||
hdrlen
<
optlen
)
&&
(
temp
<
optinfo
->
optsnr
-
1
))
{
DEBUGP
(
"new pointer is too large!
\n
"
);
break
;
}
ptr
+=
optlen
;
hdrlen
-=
optlen
;
}
if
(
temp
==
optinfo
->
optsnr
)
return
ret
;
...
...
net/ipv6/netfilter/ip6t_hl.c
View file @
11bde9b1
...
...
@@ -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 @
11bde9b1
...
...
@@ -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 @
11bde9b1
...
...
@@ -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 @
11bde9b1
...
...
@@ -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 @
11bde9b1
...
...
@@ -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 @
11bde9b1
...
...
@@ -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 @
11bde9b1
...
...
@@ -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 @
11bde9b1
...
...
@@ -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 @
11bde9b1
...
...
@@ -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 @
11bde9b1
...
...
@@ -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