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
Expand all
Hide 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,36 +96,13 @@ 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
"
);
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
;
}
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
;
}
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
;
WRITE_UNLOCK
(
&
masq_lock
);
...
...
@@ -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
This diff is collapsed.
Click to expand it.
net/ipv6/netfilter/ip6t_LOG.c
View file @
11bde9b1
This diff is collapsed.
Click to expand it.
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
...
...
@@ -31,12 +31,12 @@ MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
static
inline
int
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
;
DEBUGP
(
" result %s
\n
"
,
r
?
"PASS
\n
"
:
"FAILED
\n
"
);
return
r
;
int
r
=
0
;
DEBUGP
(
"ah spi_match:%c 0x%x <= 0x%x <= 0x%x"
,
invert
?
'!'
:
' '
,
min
,
spi
,
max
);
r
=
(
spi
>=
min
&&
spi
<=
max
)
^
invert
;
DEBUGP
(
" result %s
\n
"
,
r
?
"PASS
\n
"
:
"FAILED
\n
"
);
return
r
;
}
static
int
...
...
@@ -45,125 +45,124 @@ 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
;
const
struct
ip6t_ah
*
ahinfo
=
matchinfo
;
unsigned
int
temp
;
int
len
;
u8
nexthdr
;
unsigned
int
ptr
;
unsigned
int
hdrlen
=
0
;
/*DEBUGP("IPv6 AH entered\n");*/
/* if (opt->auth == 0) return 0;
* It does not filled on output */
/* type of the 1st exthdr */
nexthdr
=
skb
->
nh
.
ipv6h
->
nexthdr
;
/* pointer to the 1st exthdr */
ptr
=
sizeof
(
struct
ipv6hdr
);
/* available length */
len
=
skb
->
len
-
ptr
;
temp
=
0
;
while
(
ip6t_ext_hdr
(
nexthdr
))
{
struct
ipv6_opt_hdr
*
hdr
;
DEBUGP
(
"ipv6_ah header iteration
\n
"
);
/* Is there enough space for the next ext header? */
if
(
len
<
(
int
)
sizeof
(
struct
ipv6_opt_hdr
))
return
0
;
/* No more exthdr -> evaluate */
if
(
nexthdr
==
NEXTHDR_NONE
)
{
break
;
}
/* ESP -> evaluate */
if
(
nexthdr
==
NEXTHDR_ESP
)
{
break
;
}
hdr
=
(
struct
ipv6_opt_hdr
*
)
skb
->
data
+
ptr
;
/* Calculate the header length */
if
(
nexthdr
==
NEXTHDR_FRAGMENT
)
{
hdrlen
=
8
;
}
else
if
(
nexthdr
==
NEXTHDR_AUTH
)
hdrlen
=
(
hdr
->
hdrlen
+
2
)
<<
2
;
else
hdrlen
=
ipv6_optlen
(
hdr
);
/* AH -> evaluate */
if
(
nexthdr
==
NEXTHDR_AUTH
)
{
temp
|=
MASK_AH
;
break
;
}
/* set the flag */
switch
(
nexthdr
){
case
NEXTHDR_HOP
:
case
NEXTHDR_ROUTING
:
case
NEXTHDR_FRAGMENT
:
case
NEXTHDR_AUTH
:
case
NEXTHDR_DEST
:
break
;
default:
DEBUGP
(
"ipv6_ah match: unknown nextheader %u
\n
"
,
nexthdr
);
return
0
;
break
;
}
nexthdr
=
hdr
->
nexthdr
;
len
-=
hdrlen
;
ptr
+=
hdrlen
;
if
(
ptr
>
skb
->
len
)
{
struct
ip_auth_hdr
*
ah
=
NULL
,
_ah
;
const
struct
ip6t_ah
*
ahinfo
=
matchinfo
;
unsigned
int
temp
;
int
len
;
u8
nexthdr
;
unsigned
int
ptr
;
unsigned
int
hdrlen
=
0
;
/*DEBUGP("IPv6 AH entered\n");*/
/* if (opt->auth == 0) return 0;
* It does not filled on output */
/* type of the 1st exthdr */
nexthdr
=
skb
->
nh
.
ipv6h
->
nexthdr
;
/* pointer to the 1st exthdr */
ptr
=
sizeof
(
struct
ipv6hdr
);
/* available length */
len
=
skb
->
len
-
ptr
;
temp
=
0
;
while
(
ip6t_ext_hdr
(
nexthdr
))
{
struct
ipv6_opt_hdr
_hdr
,
*
hp
;
DEBUGP
(
"ipv6_ah header iteration
\n
"
);
/* Is there enough space for the next ext header? */
if
(
len
<
sizeof
(
struct
ipv6_opt_hdr
))
return
0
;
/* No more exthdr -> evaluate */
if
(
nexthdr
==
NEXTHDR_NONE
)
break
;
/* ESP -> evaluate */
if
(
nexthdr
==
NEXTHDR_ESP
)
break
;
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
=
(
hp
->
hdrlen
+
2
)
<<
2
;
else
hdrlen
=
ipv6_optlen
(
hp
);
/* AH -> evaluate */
if
(
nexthdr
==
NEXTHDR_AUTH
)
{
temp
|=
MASK_AH
;
break
;
}
/* set the flag */
switch
(
nexthdr
)
{
case
NEXTHDR_HOP
:
case
NEXTHDR_ROUTING
:
case
NEXTHDR_FRAGMENT
:
case
NEXTHDR_AUTH
:
case
NEXTHDR_DEST
:
break
;
default:
DEBUGP
(
"ipv6_ah match: unknown nextheader %u
\n
"
,
nexthdr
);
return
0
;
}
nexthdr
=
hp
->
nexthdr
;
len
-=
hdrlen
;
ptr
+=
hdrlen
;
if
(
ptr
>
skb
->
len
)
{
DEBUGP
(
"ipv6_ah: new pointer too large!
\n
"
);
break
;
}
}
/* AH header not found */
if
(
temp
!=
MASK_AH
)
return
0
;
if
(
len
<
(
int
)
sizeof
(
struct
ip_auth_hdr
)){
*
hotdrop
=
1
;
return
0
;
}
ah
=
(
struct
ip_auth_hdr
*
)
(
skb
->
data
+
ptr
);
DEBUGP
(
"IPv6 AH LEN %u %u "
,
hdrlen
,
ah
->
hdrlen
);
DEBUGP
(
"RES %04X "
,
ah
->
reserved
);
DEBUGP
(
"SPI %u %08X
\n
"
,
ntohl
(
ah
->
spi
),
ntohl
(
ah
->
spi
));
DEBUGP
(
"IPv6 AH spi %02X "
,
(
spi_match
(
ahinfo
->
spis
[
0
],
ahinfo
->
spis
[
1
],
ntohl
(
ah
->
spi
),
!!
(
ahinfo
->
invflags
&
IP6T_AH_INV_SPI
))));
DEBUGP
(
"len %02X %04X %02X "
,
ahinfo
->
hdrlen
,
hdrlen
,
(
!
ahinfo
->
hdrlen
||
(
ahinfo
->
hdrlen
==
hdrlen
)
^
!!
(
ahinfo
->
invflags
&
IP6T_AH_INV_LEN
)));
DEBUGP
(
"res %02X %04X %02X
\n
"
,
ahinfo
->
hdrres
,
ah
->
reserved
,
!
(
ahinfo
->
hdrres
&&
ah
->
reserved
));
return
(
ah
!=
NULL
)
&&
(
spi_match
(
ahinfo
->
spis
[
0
],
ahinfo
->
spis
[
1
],
ntohl
(
ah
->
spi
),
!!
(
ahinfo
->
invflags
&
IP6T_AH_INV_SPI
)))
&&
(
!
ahinfo
->
hdrlen
||
(
ahinfo
->
hdrlen
==
hdrlen
)
^
!!
(
ahinfo
->
invflags
&
IP6T_AH_INV_LEN
))
&&
!
(
ahinfo
->
hdrres
&&
ah
->
reserved
);
}
/* AH header not found */
if
(
temp
!=
MASK_AH
)
return
0
;
if
(
len
<
sizeof
(
struct
ip_auth_hdr
)){
*
hotdrop
=
1
;
return
0
;
}
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
);
DEBUGP
(
"SPI %u %08X
\n
"
,
ntohl
(
ah
->
spi
),
ntohl
(
ah
->
spi
));
DEBUGP
(
"IPv6 AH spi %02X "
,
(
spi_match
(
ahinfo
->
spis
[
0
],
ahinfo
->
spis
[
1
],
ntohl
(
ah
->
spi
),
!!
(
ahinfo
->
invflags
&
IP6T_AH_INV_SPI
))));
DEBUGP
(
"len %02X %04X %02X "
,
ahinfo
->
hdrlen
,
hdrlen
,
(
!
ahinfo
->
hdrlen
||
(
ahinfo
->
hdrlen
==
hdrlen
)
^
!!
(
ahinfo
->
invflags
&
IP6T_AH_INV_LEN
)));
DEBUGP
(
"res %02X %04X %02X
\n
"
,
ahinfo
->
hdrres
,
ah
->
reserved
,
!
(
ahinfo
->
hdrres
&&
ah
->
reserved
));
return
(
ah
!=
NULL
)
&&
(
spi_match
(
ahinfo
->
spis
[
0
],
ahinfo
->
spis
[
1
],
ntohl
(
ah
->
spi
),
!!
(
ahinfo
->
invflags
&
IP6T_AH_INV_SPI
)))
&&
(
!
ahinfo
->
hdrlen
||
(
ahinfo
->
hdrlen
==
hdrlen
)
^
!!
(
ahinfo
->
invflags
&
IP6T_AH_INV_LEN
))
&&
!
(
ahinfo
->
hdrres
&&
ah
->
reserved
);
}
/* Called when user tries to insert an entry of this type. */
...
...
@@ -174,20 +173,18 @@ checkentry(const char *tablename,
unsigned
int
matchinfosize
,
unsigned
int
hook_mask
)
{
const
struct
ip6t_ah
*
ahinfo
=
matchinfo
;
if
(
matchinfosize
!=
IP6T_ALIGN
(
sizeof
(
struct
ip6t_ah
)))
{
DEBUGP
(
"ip6t_ah: matchsize %u != %u
\n
"
,
matchinfosize
,
IP6T_ALIGN
(
sizeof
(
struct
ip6t_ah
)));
return
0
;
}
if
(
ahinfo
->
invflags
&
~
IP6T_AH_INV_MASK
)
{
DEBUGP
(
"ip6t_ah: unknown flags %X
\n
"
,
ahinfo
->
invflags
);
return
0
;
}
return
1
;
const
struct
ip6t_ah
*
ahinfo
=
matchinfo
;
if
(
matchinfosize
!=
IP6T_ALIGN
(
sizeof
(
struct
ip6t_ah
)))
{
DEBUGP
(
"ip6t_ah: matchsize %u != %u
\n
"
,
matchinfosize
,
IP6T_ALIGN
(
sizeof
(
struct
ip6t_ah
)));
return
0
;
}
if
(
ahinfo
->
invflags
&
~
IP6T_AH_INV_MASK
)
{
DEBUGP
(
"ip6t_ah: unknown flags %X
\n
"
,
ahinfo
->
invflags
);
return
0
;
}
return
1
;
}
static
struct
ip6t_match
ah_match
=
{
...
...
@@ -199,12 +196,12 @@ static struct ip6t_match ah_match = {
static
int
__init
init
(
void
)
{
return
ip6t_register_match
(
&
ah_match
);
return
ip6t_register_match
(
&
ah_match
);
}
static
void
__exit
cleanup
(
void
)
{
ip6t_unregister_match
(
&
ah_match
);
ip6t_unregister_match
(
&
ah_match
);
}
module_init
(
init
);
...
...
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
...
...
@@ -32,8 +32,8 @@ static inline int
spi_match
(
u_int32_t
min
,
u_int32_t
max
,
u_int32_t
spi
,
int
invert
)
{
int
r
=
0
;
DEBUGP
(
"esp spi_match:%c 0x%x <= 0x%x <= 0x%x"
,
invert
?
'!'
:
' '
,
min
,
spi
,
max
);
DEBUGP
(
"esp spi_match:%c 0x%x <= 0x%x <= 0x%x"
,
invert
?
'!'
:
' '
,
min
,
spi
,
max
);
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_esp_hdr
*
esp
=
NULL
;
struct
ip_esp_hdr
_esp
,
*
eh
=
NULL
;
const
struct
ip6t_esp
*
espinfo
=
matchinfo
;
unsigned
int
temp
;
int
len
;
...
...
@@ -67,73 +66,74 @@ match(const struct sk_buff *skb,
len
=
skb
->
len
-
ptr
;
temp
=
0
;
while
(
ip6t_ext_hdr
(
nexthdr
))
{
struct
ipv6_opt_hdr
*
hdr
;
int
hdrlen
;
while
(
ip6t_ext_hdr
(
nexthdr
))
{
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
))
return
0
;
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
)
{
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
)
{
hdrlen
=
8
;
}
else
if
(
nexthdr
==
NEXTHDR_AUTH
)
hdrlen
=
(
hdr
->
hdrlen
+
2
)
<<
2
;
else
hdrlen
=
ipv6_optlen
(
hdr
);
if
(
nexthdr
==
NEXTHDR_FRAGMENT
)
hdrlen
=
8
;
else
if
(
nexthdr
==
NEXTHDR_AUTH
)
hdrlen
=
(
hp
->
hdrlen
+
2
)
<<
2
;
else
hdrlen
=
ipv6_optlen
(
hp
);
/* set the flag */
switch
(
nexthdr
){
case
NEXTHDR_HOP
:
case
NEXTHDR_ROUTING
:
case
NEXTHDR_FRAGMENT
:
case
NEXTHDR_AUTH
:
case
NEXTHDR_DEST
:
break
;
default:
DEBUGP
(
"ipv6_esp match: unknown nextheader %u
\n
"
,
nexthdr
);
return
0
;
break
;
switch
(
nexthdr
)
{
case
NEXTHDR_HOP
:
case
NEXTHDR_ROUTING
:
case
NEXTHDR_FRAGMENT
:
case
NEXTHDR_AUTH
:
case
NEXTHDR_DEST
:
break
;
default:
DEBUGP
(
"ipv6_esp match: unknown nextheader %u
\n
"
,
nexthdr
);
return
0
;
}
nexthdr
=
hdr
->
nexthdr
;
len
-=
hdrlen
;
ptr
+=
hdrlen
;
if
(
ptr
>
skb
->
len
)
{
nexthdr
=
hp
->
nexthdr
;
len
-=
hdrlen
;
ptr
+=
hdrlen
;
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
))
{
*
hotdrop
=
1
;
return
0
;
}
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. */
duprintf
(
"ip6t_multiport:"
" Dropping evil offset=0 tinygram.
\n
"
);
*
hotdrop
=
1
;
return
0
;
* 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
,
multiinfo
->
flags
,
multiinfo
->
count
,
ntohs
(
udp
->
source
),
ntohs
(
udp
->
dest
));
return
ports_match
(
multiinfo
->
ports
,
multiinfo
->
flags
,
multiinfo
->
count
,
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
;
}
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
);
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
(
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