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
3c417db9
Commit
3c417db9
authored
Sep 27, 2004
by
Patrick McHardy
Browse files
Options
Browse Files
Download
Plain Diff
Merge coreworks.de:/home/kaber/src/bk-repos/linux-2.6
into coreworks.de:/home/kaber/src/nf/netfilter-2.6
parents
beb0e5c2
4eb6a871
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
108 additions
and
97 deletions
+108
-97
include/linux/skbuff.h
include/linux/skbuff.h
+1
-1
net/ipv4/netfilter/ip_conntrack_proto_icmp.c
net/ipv4/netfilter/ip_conntrack_proto_icmp.c
+18
-16
net/ipv4/netfilter/ip_conntrack_proto_sctp.c
net/ipv4/netfilter/ip_conntrack_proto_sctp.c
+65
-59
net/ipv4/netfilter/ip_conntrack_proto_udp.c
net/ipv4/netfilter/ip_conntrack_proto_udp.c
+5
-4
net/ipv4/netfilter/ip_conntrack_standalone.c
net/ipv4/netfilter/ip_conntrack_standalone.c
+0
-1
net/ipv4/netfilter/ipt_helper.c
net/ipv4/netfilter/ipt_helper.c
+1
-0
net/ipv4/netfilter/ipt_sctp.c
net/ipv4/netfilter/ipt_sctp.c
+18
-16
No files found.
include/linux/skbuff.h
View file @
3c417db9
...
@@ -250,8 +250,8 @@ struct sk_buff {
...
@@ -250,8 +250,8 @@ struct sk_buff {
#ifdef CONFIG_NETFILTER
#ifdef CONFIG_NETFILTER
unsigned
long
nfmark
;
unsigned
long
nfmark
;
__u32
nfcache
;
__u32
nfcache
;
struct
nf_conntrack
*
nfct
;
__u32
nfctinfo
;
__u32
nfctinfo
;
struct
nf_conntrack
*
nfct
;
#ifdef CONFIG_NETFILTER_DEBUG
#ifdef CONFIG_NETFILTER_DEBUG
unsigned
int
nf_debug
;
unsigned
int
nf_debug
;
#endif
#endif
...
...
net/ipv4/netfilter/ip_conntrack_proto_icmp.c
View file @
3c417db9
...
@@ -139,7 +139,7 @@ icmp_error_message(struct sk_buff *skb,
...
@@ -139,7 +139,7 @@ icmp_error_message(struct sk_buff *skb,
struct
{
struct
{
struct
icmphdr
icmp
;
struct
icmphdr
icmp
;
struct
iphdr
ip
;
struct
iphdr
ip
;
}
inside
;
}
_in
,
*
inside
;
struct
ip_conntrack_protocol
*
innerproto
;
struct
ip_conntrack_protocol
*
innerproto
;
struct
ip_conntrack_tuple_hash
*
h
;
struct
ip_conntrack_tuple_hash
*
h
;
int
dataoff
;
int
dataoff
;
...
@@ -147,21 +147,22 @@ icmp_error_message(struct sk_buff *skb,
...
@@ -147,21 +147,22 @@ icmp_error_message(struct sk_buff *skb,
IP_NF_ASSERT
(
skb
->
nfct
==
NULL
);
IP_NF_ASSERT
(
skb
->
nfct
==
NULL
);
/* Not enough header? */
/* Not enough header? */
if
(
skb_copy_bits
(
skb
,
skb
->
nh
.
iph
->
ihl
*
4
,
&
inside
,
sizeof
(
inside
))
!=
0
)
inside
=
skb_header_pointer
(
skb
,
skb
->
nh
.
iph
->
ihl
*
4
,
sizeof
(
_in
),
&
_in
);
if
(
inside
==
NULL
)
return
NF_ACCEPT
;
return
NF_ACCEPT
;
/* Ignore ICMP's containing fragments (shouldn't happen) */
/* Ignore ICMP's containing fragments (shouldn't happen) */
if
(
inside
.
ip
.
frag_off
&
htons
(
IP_OFFSET
))
{
if
(
inside
->
ip
.
frag_off
&
htons
(
IP_OFFSET
))
{
DEBUGP
(
"icmp_error_track: fragment of proto %u
\n
"
,
DEBUGP
(
"icmp_error_track: fragment of proto %u
\n
"
,
inside
.
ip
.
protocol
);
inside
->
ip
.
protocol
);
return
NF_ACCEPT
;
return
NF_ACCEPT
;
}
}
innerproto
=
ip_ct_find_proto
(
inside
.
ip
.
protocol
);
innerproto
=
ip_ct_find_proto
(
inside
->
ip
.
protocol
);
dataoff
=
skb
->
nh
.
iph
->
ihl
*
4
+
sizeof
(
inside
.
icmp
)
+
inside
.
ip
.
ihl
*
4
;
dataoff
=
skb
->
nh
.
iph
->
ihl
*
4
+
sizeof
(
inside
->
icmp
)
+
inside
->
ip
.
ihl
*
4
;
/* Are they talking about one of our connections? */
/* Are they talking about one of our connections? */
if
(
!
ip_ct_get_tuple
(
&
inside
.
ip
,
skb
,
dataoff
,
&
origtuple
,
innerproto
))
{
if
(
!
ip_ct_get_tuple
(
&
inside
->
ip
,
skb
,
dataoff
,
&
origtuple
,
innerproto
))
{
DEBUGP
(
"icmp_error: ! get_tuple p=%u"
,
inside
.
ip
.
protocol
);
DEBUGP
(
"icmp_error: ! get_tuple p=%u"
,
inside
->
ip
.
protocol
);
return
NF_ACCEPT
;
return
NF_ACCEPT
;
}
}
...
@@ -205,10 +206,11 @@ static int
...
@@ -205,10 +206,11 @@ static int
icmp_error
(
struct
sk_buff
*
skb
,
enum
ip_conntrack_info
*
ctinfo
,
icmp_error
(
struct
sk_buff
*
skb
,
enum
ip_conntrack_info
*
ctinfo
,
unsigned
int
hooknum
)
unsigned
int
hooknum
)
{
{
struct
icmphdr
icmph
;
struct
icmphdr
_ih
,
*
icmph
;
/* Not enough header? */
/* Not enough header? */
if
(
skb_copy_bits
(
skb
,
skb
->
nh
.
iph
->
ihl
*
4
,
&
icmph
,
sizeof
(
icmph
))
!=
0
)
{
icmph
=
skb_header_pointer
(
skb
,
skb
->
nh
.
iph
->
ihl
*
4
,
sizeof
(
_ih
),
&
_ih
);
if
(
icmph
==
NULL
)
{
if
(
LOG_INVALID
(
IPPROTO_ICMP
))
if
(
LOG_INVALID
(
IPPROTO_ICMP
))
nf_log_packet
(
PF_INET
,
0
,
skb
,
NULL
,
NULL
,
nf_log_packet
(
PF_INET
,
0
,
skb
,
NULL
,
NULL
,
"ip_ct_icmp: short packet "
);
"ip_ct_icmp: short packet "
);
...
@@ -245,7 +247,7 @@ icmp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
...
@@ -245,7 +247,7 @@ icmp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
* RFC 1122: 3.2.2 Unknown ICMP messages types MUST be silently
* RFC 1122: 3.2.2 Unknown ICMP messages types MUST be silently
* discarded.
* discarded.
*/
*/
if
(
icmph
.
type
>
NR_ICMP_TYPES
)
{
if
(
icmph
->
type
>
NR_ICMP_TYPES
)
{
if
(
LOG_INVALID
(
IPPROTO_ICMP
))
if
(
LOG_INVALID
(
IPPROTO_ICMP
))
nf_log_packet
(
PF_INET
,
0
,
skb
,
NULL
,
NULL
,
nf_log_packet
(
PF_INET
,
0
,
skb
,
NULL
,
NULL
,
"ip_ct_icmp: invalid ICMP type "
);
"ip_ct_icmp: invalid ICMP type "
);
...
@@ -253,11 +255,11 @@ icmp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
...
@@ -253,11 +255,11 @@ icmp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
}
}
/* Need to track icmp error message? */
/* Need to track icmp error message? */
if
(
icmph
.
type
!=
ICMP_DEST_UNREACH
if
(
icmph
->
type
!=
ICMP_DEST_UNREACH
&&
icmph
.
type
!=
ICMP_SOURCE_QUENCH
&&
icmph
->
type
!=
ICMP_SOURCE_QUENCH
&&
icmph
.
type
!=
ICMP_TIME_EXCEEDED
&&
icmph
->
type
!=
ICMP_TIME_EXCEEDED
&&
icmph
.
type
!=
ICMP_PARAMETERPROB
&&
icmph
->
type
!=
ICMP_PARAMETERPROB
&&
icmph
.
type
!=
ICMP_REDIRECT
)
&&
icmph
->
type
!=
ICMP_REDIRECT
)
return
NF_ACCEPT
;
return
NF_ACCEPT
;
return
icmp_error_message
(
skb
,
ctinfo
,
hooknum
);
return
icmp_error_message
(
skb
,
ctinfo
,
hooknum
);
...
...
net/ipv4/netfilter/ip_conntrack_proto_sctp.c
View file @
3c417db9
...
@@ -152,18 +152,18 @@ static int sctp_pkt_to_tuple(const struct sk_buff *skb,
...
@@ -152,18 +152,18 @@ static int sctp_pkt_to_tuple(const struct sk_buff *skb,
unsigned
int
dataoff
,
unsigned
int
dataoff
,
struct
ip_conntrack_tuple
*
tuple
)
struct
ip_conntrack_tuple
*
tuple
)
{
{
sctp_sctphdr_t
hdr
;
sctp_sctphdr_t
_hdr
,
*
hp
;
DEBUGP
(
__FUNCTION__
);
DEBUGP
(
__FUNCTION__
);
DEBUGP
(
"
\n
"
);
DEBUGP
(
"
\n
"
);
/* Actually only need first 8 bytes. */
/* Actually only need first 8 bytes. */
if
(
skb_copy_bits
(
skb
,
dataoff
,
&
hdr
,
8
)
!=
0
)
hp
=
skb_header_pointer
(
skb
,
dataoff
,
8
,
&
_hdr
);
if
(
hp
==
NULL
)
return
0
;
return
0
;
tuple
->
src
.
u
.
sctp
.
port
=
hdr
.
source
;
tuple
->
src
.
u
.
sctp
.
port
=
hp
->
source
;
tuple
->
dst
.
u
.
sctp
.
port
=
hdr
.
dest
;
tuple
->
dst
.
u
.
sctp
.
port
=
hp
->
dest
;
return
1
;
return
1
;
}
}
...
@@ -206,10 +206,11 @@ static int sctp_print_conntrack(struct seq_file *s,
...
@@ -206,10 +206,11 @@ static int sctp_print_conntrack(struct seq_file *s,
return
seq_printf
(
s
,
"%s "
,
sctp_conntrack_names
[
state
]);
return
seq_printf
(
s
,
"%s "
,
sctp_conntrack_names
[
state
]);
}
}
#define for_each_sctp_chunk(skb, sch, offset, count) \
#define for_each_sctp_chunk(skb, sch, _sch, offset, count) \
for (offset = skb->nh.iph->ihl * 4 + sizeof (sctp_sctphdr_t), count = 0; \
for (offset = skb->nh.iph->ihl * 4 + sizeof(sctp_sctphdr_t), count = 0; \
offset < skb->len && !skb_copy_bits(skb, offset, &sch, sizeof(sch)); \
offset < skb->len && \
offset += (htons(sch.length) + 3) & ~3, count++)
(sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch)); \
offset += (htons(sch->length) + 3) & ~3, count++)
/* Some validity checks to make sure the chunks are fine */
/* Some validity checks to make sure the chunks are fine */
static
int
do_basic_checks
(
struct
ip_conntrack
*
conntrack
,
static
int
do_basic_checks
(
struct
ip_conntrack
*
conntrack
,
...
@@ -217,7 +218,7 @@ static int do_basic_checks(struct ip_conntrack *conntrack,
...
@@ -217,7 +218,7 @@ static int do_basic_checks(struct ip_conntrack *conntrack,
char
*
map
)
char
*
map
)
{
{
u_int32_t
offset
,
count
;
u_int32_t
offset
,
count
;
sctp_chunkhdr_t
sch
;
sctp_chunkhdr_t
_sch
,
*
sch
;
int
flag
;
int
flag
;
DEBUGP
(
__FUNCTION__
);
DEBUGP
(
__FUNCTION__
);
...
@@ -225,19 +226,19 @@ static int do_basic_checks(struct ip_conntrack *conntrack,
...
@@ -225,19 +226,19 @@ static int do_basic_checks(struct ip_conntrack *conntrack,
flag
=
0
;
flag
=
0
;
for_each_sctp_chunk
(
skb
,
sch
,
offset
,
count
)
{
for_each_sctp_chunk
(
skb
,
sch
,
_sch
,
offset
,
count
)
{
DEBUGP
(
"Chunk Num: %d Type: %d
\n
"
,
count
,
sch
.
type
);
DEBUGP
(
"Chunk Num: %d Type: %d
\n
"
,
count
,
sch
->
type
);
if
(
sch
.
type
==
SCTP_CID_INIT
if
(
sch
->
type
==
SCTP_CID_INIT
||
sch
.
type
==
SCTP_CID_INIT_ACK
||
sch
->
type
==
SCTP_CID_INIT_ACK
||
sch
.
type
==
SCTP_CID_SHUTDOWN_COMPLETE
)
{
||
sch
->
type
==
SCTP_CID_SHUTDOWN_COMPLETE
)
{
flag
=
1
;
flag
=
1
;
}
}
/* Cookie Ack/Echo chunks not the first OR
/* Cookie Ack/Echo chunks not the first OR
Init / Init Ack / Shutdown compl chunks not the only chunks */
Init / Init Ack / Shutdown compl chunks not the only chunks */
if
((
sch
.
type
==
SCTP_CID_COOKIE_ACK
if
((
sch
->
type
==
SCTP_CID_COOKIE_ACK
||
sch
.
type
==
SCTP_CID_COOKIE_ECHO
||
sch
->
type
==
SCTP_CID_COOKIE_ECHO
||
flag
)
||
flag
)
&&
count
!=
0
)
{
&&
count
!=
0
)
{
DEBUGP
(
"Basic checks failed
\n
"
);
DEBUGP
(
"Basic checks failed
\n
"
);
...
@@ -245,7 +246,7 @@ static int do_basic_checks(struct ip_conntrack *conntrack,
...
@@ -245,7 +246,7 @@ static int do_basic_checks(struct ip_conntrack *conntrack,
}
}
if
(
map
)
{
if
(
map
)
{
set_bit
(
sch
.
type
,
(
void
*
)
map
);
set_bit
(
sch
->
type
,
(
void
*
)
map
);
}
}
}
}
...
@@ -313,15 +314,17 @@ static int sctp_packet(struct ip_conntrack *conntrack,
...
@@ -313,15 +314,17 @@ static int sctp_packet(struct ip_conntrack *conntrack,
enum
ip_conntrack_info
ctinfo
)
enum
ip_conntrack_info
ctinfo
)
{
{
enum
sctp_conntrack
newconntrack
,
oldsctpstate
;
enum
sctp_conntrack
newconntrack
,
oldsctpstate
;
sctp_sctphdr_t
sctph
;
struct
iphdr
*
iph
=
skb
->
nh
.
iph
;
sctp_chunkhdr_t
sch
;
sctp_sctphdr_t
_sctph
,
*
sh
;
sctp_chunkhdr_t
_sch
,
*
sch
;
u_int32_t
offset
,
count
;
u_int32_t
offset
,
count
;
char
map
[
256
/
sizeof
(
char
)]
=
{
0
};
char
map
[
256
/
sizeof
(
char
)]
=
{
0
};
DEBUGP
(
__FUNCTION__
);
DEBUGP
(
__FUNCTION__
);
DEBUGP
(
"
\n
"
);
DEBUGP
(
"
\n
"
);
if
(
skb_copy_bits
(
skb
,
skb
->
nh
.
iph
->
ihl
*
4
,
&
sctph
,
sizeof
(
sctph
))
!=
0
)
sh
=
skb_header_pointer
(
skb
,
iph
->
ihl
*
4
,
sizeof
(
_sctph
),
&
_sctph
);
if
(
sh
==
NULL
)
return
-
1
;
return
-
1
;
if
(
do_basic_checks
(
conntrack
,
skb
,
map
)
!=
0
)
if
(
do_basic_checks
(
conntrack
,
skb
,
map
)
!=
0
)
...
@@ -333,71 +336,72 @@ static int sctp_packet(struct ip_conntrack *conntrack,
...
@@ -333,71 +336,72 @@ static int sctp_packet(struct ip_conntrack *conntrack,
&&
!
test_bit
(
SCTP_CID_COOKIE_ECHO
,
(
void
*
)
map
)
&&
!
test_bit
(
SCTP_CID_COOKIE_ECHO
,
(
void
*
)
map
)
&&
!
test_bit
(
SCTP_CID_ABORT
,
(
void
*
)
map
)
&&
!
test_bit
(
SCTP_CID_ABORT
,
(
void
*
)
map
)
&&
!
test_bit
(
SCTP_CID_SHUTDOWN_ACK
,
(
void
*
)
map
)
&&
!
test_bit
(
SCTP_CID_SHUTDOWN_ACK
,
(
void
*
)
map
)
&&
(
s
ctph
.
vtag
!=
conntrack
->
proto
.
sctp
.
vtag
[
CTINFO2DIR
(
ctinfo
)]))
{
&&
(
s
h
->
vtag
!=
conntrack
->
proto
.
sctp
.
vtag
[
CTINFO2DIR
(
ctinfo
)]))
{
DEBUGP
(
"Verification tag check failed
\n
"
);
DEBUGP
(
"Verification tag check failed
\n
"
);
return
-
1
;
return
-
1
;
}
}
oldsctpstate
=
newconntrack
=
SCTP_CONNTRACK_MAX
;
oldsctpstate
=
newconntrack
=
SCTP_CONNTRACK_MAX
;
for_each_sctp_chunk
(
skb
,
sch
,
offset
,
count
)
{
for_each_sctp_chunk
(
skb
,
sch
,
_sch
,
offset
,
count
)
{
WRITE_LOCK
(
&
sctp_lock
);
WRITE_LOCK
(
&
sctp_lock
);
/* Special cases of Verification tag check (Sec 8.5.1) */
/* Special cases of Verification tag check (Sec 8.5.1) */
if
(
sch
.
type
==
SCTP_CID_INIT
)
{
if
(
sch
->
type
==
SCTP_CID_INIT
)
{
/* Sec 8.5.1 (A) */
/* Sec 8.5.1 (A) */
if
(
s
ctph
.
vtag
!=
0
)
{
if
(
s
h
->
vtag
!=
0
)
{
WRITE_UNLOCK
(
&
sctp_lock
);
WRITE_UNLOCK
(
&
sctp_lock
);
return
-
1
;
return
-
1
;
}
}
}
else
if
(
sch
.
type
==
SCTP_CID_ABORT
)
{
}
else
if
(
sch
->
type
==
SCTP_CID_ABORT
)
{
/* Sec 8.5.1 (B) */
/* Sec 8.5.1 (B) */
if
(
!
(
s
ctph
.
vtag
==
conntrack
->
proto
.
sctp
.
vtag
[
CTINFO2DIR
(
ctinfo
)])
if
(
!
(
s
h
->
vtag
==
conntrack
->
proto
.
sctp
.
vtag
[
CTINFO2DIR
(
ctinfo
)])
&&
!
(
s
ctph
.
vtag
==
conntrack
->
proto
.
sctp
.
vtag
&&
!
(
s
h
->
vtag
==
conntrack
->
proto
.
sctp
.
vtag
[
1
-
CTINFO2DIR
(
ctinfo
)]))
{
[
1
-
CTINFO2DIR
(
ctinfo
)]))
{
WRITE_UNLOCK
(
&
sctp_lock
);
WRITE_UNLOCK
(
&
sctp_lock
);
return
-
1
;
return
-
1
;
}
}
}
else
if
(
sch
.
type
==
SCTP_CID_SHUTDOWN_COMPLETE
)
{
}
else
if
(
sch
->
type
==
SCTP_CID_SHUTDOWN_COMPLETE
)
{
/* Sec 8.5.1 (C) */
/* Sec 8.5.1 (C) */
if
(
!
(
s
ctph
.
vtag
==
conntrack
->
proto
.
sctp
.
vtag
[
CTINFO2DIR
(
ctinfo
)])
if
(
!
(
s
h
->
vtag
==
conntrack
->
proto
.
sctp
.
vtag
[
CTINFO2DIR
(
ctinfo
)])
&&
!
(
s
ctph
.
vtag
==
conntrack
->
proto
.
sctp
.
vtag
&&
!
(
s
h
->
vtag
==
conntrack
->
proto
.
sctp
.
vtag
[
1
-
CTINFO2DIR
(
ctinfo
)]
[
1
-
CTINFO2DIR
(
ctinfo
)]
&&
(
sch
.
flags
&
1
)))
{
&&
(
sch
->
flags
&
1
)))
{
WRITE_UNLOCK
(
&
sctp_lock
);
WRITE_UNLOCK
(
&
sctp_lock
);
return
-
1
;
return
-
1
;
}
}
}
else
if
(
sch
.
type
==
SCTP_CID_COOKIE_ECHO
)
{
}
else
if
(
sch
->
type
==
SCTP_CID_COOKIE_ECHO
)
{
/* Sec 8.5.1 (D) */
/* Sec 8.5.1 (D) */
if
(
!
(
s
ctph
.
vtag
==
conntrack
->
proto
.
sctp
.
vtag
[
CTINFO2DIR
(
ctinfo
)]))
{
if
(
!
(
s
h
->
vtag
==
conntrack
->
proto
.
sctp
.
vtag
[
CTINFO2DIR
(
ctinfo
)]))
{
WRITE_UNLOCK
(
&
sctp_lock
);
WRITE_UNLOCK
(
&
sctp_lock
);
return
-
1
;
return
-
1
;
}
}
}
}
oldsctpstate
=
conntrack
->
proto
.
sctp
.
state
;
oldsctpstate
=
conntrack
->
proto
.
sctp
.
state
;
newconntrack
=
new_state
(
CTINFO2DIR
(
ctinfo
),
oldsctpstate
,
sch
.
type
);
newconntrack
=
new_state
(
CTINFO2DIR
(
ctinfo
),
oldsctpstate
,
sch
->
type
);
/* Invalid */
/* Invalid */
if
(
newconntrack
==
SCTP_CONNTRACK_MAX
)
{
if
(
newconntrack
==
SCTP_CONNTRACK_MAX
)
{
DEBUGP
(
"ip_conntrack_sctp: Invalid dir=%i ctype=%u conntrack=%u
\n
"
,
DEBUGP
(
"ip_conntrack_sctp: Invalid dir=%i ctype=%u conntrack=%u
\n
"
,
CTINFO2DIR
(
ctinfo
),
sch
.
type
,
oldsctpstate
);
CTINFO2DIR
(
ctinfo
),
sch
->
type
,
oldsctpstate
);
WRITE_UNLOCK
(
&
sctp_lock
);
WRITE_UNLOCK
(
&
sctp_lock
);
return
-
1
;
return
-
1
;
}
}
/* If it is an INIT or an INIT ACK note down the vtag */
/* If it is an INIT or an INIT ACK note down the vtag */
if
(
sch
.
type
==
SCTP_CID_INIT
if
(
sch
->
type
==
SCTP_CID_INIT
||
sch
.
type
==
SCTP_CID_INIT_ACK
)
{
||
sch
->
type
==
SCTP_CID_INIT_ACK
)
{
sctp_inithdr_t
inithdr
;
sctp_inithdr_t
_inithdr
,
*
ih
;
if
(
skb_copy_bits
(
skb
,
offset
+
sizeof
(
sctp_chunkhdr_t
),
ih
=
skb_header_pointer
(
skb
,
offset
+
sizeof
(
sctp_chunkhdr_t
),
&
inithdr
,
sizeof
(
inithdr
))
!=
0
)
{
sizeof
(
_inithdr
),
&
_inithdr
);
if
(
ih
==
NULL
)
{
WRITE_UNLOCK
(
&
sctp_lock
);
WRITE_UNLOCK
(
&
sctp_lock
);
return
-
1
;
return
-
1
;
}
}
DEBUGP
(
"Setting vtag %x for dir %d
\n
"
,
DEBUGP
(
"Setting vtag %x for dir %d
\n
"
,
i
nithdr
.
init_tag
,
CTINFO2DIR
(
ctinfo
));
i
h
->
init_tag
,
CTINFO2DIR
(
ctinfo
));
conntrack
->
proto
.
sctp
.
vtag
[
IP_CT_DIR_ORIGINAL
]
=
i
nithdr
.
init_tag
;
conntrack
->
proto
.
sctp
.
vtag
[
IP_CT_DIR_ORIGINAL
]
=
i
h
->
init_tag
;
}
}
conntrack
->
proto
.
sctp
.
state
=
newconntrack
;
conntrack
->
proto
.
sctp
.
state
=
newconntrack
;
...
@@ -421,15 +425,17 @@ static int sctp_new(struct ip_conntrack *conntrack,
...
@@ -421,15 +425,17 @@ static int sctp_new(struct ip_conntrack *conntrack,
const
struct
sk_buff
*
skb
)
const
struct
sk_buff
*
skb
)
{
{
enum
sctp_conntrack
newconntrack
;
enum
sctp_conntrack
newconntrack
;
sctp_sctphdr_t
sctph
;
struct
iphdr
*
iph
=
skb
->
nh
.
iph
;
sctp_chunkhdr_t
sch
;
sctp_sctphdr_t
_sctph
,
*
sh
;
sctp_chunkhdr_t
_sch
,
*
sch
;
u_int32_t
offset
,
count
;
u_int32_t
offset
,
count
;
char
map
[
256
/
sizeof
(
char
)]
=
{
0
};
char
map
[
256
/
sizeof
(
char
)]
=
{
0
};
DEBUGP
(
__FUNCTION__
);
DEBUGP
(
__FUNCTION__
);
DEBUGP
(
"
\n
"
);
DEBUGP
(
"
\n
"
);
if
(
skb_copy_bits
(
skb
,
skb
->
nh
.
iph
->
ihl
*
4
,
&
sctph
,
sizeof
(
sctph
))
!=
0
)
sh
=
skb_header_pointer
(
skb
,
iph
->
ihl
*
4
,
sizeof
(
_sctph
),
&
_sctph
);
if
(
sh
==
NULL
)
return
0
;
return
0
;
if
(
do_basic_checks
(
conntrack
,
skb
,
map
)
!=
0
)
if
(
do_basic_checks
(
conntrack
,
skb
,
map
)
!=
0
)
...
@@ -443,10 +449,10 @@ static int sctp_new(struct ip_conntrack *conntrack,
...
@@ -443,10 +449,10 @@ static int sctp_new(struct ip_conntrack *conntrack,
}
}
newconntrack
=
SCTP_CONNTRACK_MAX
;
newconntrack
=
SCTP_CONNTRACK_MAX
;
for_each_sctp_chunk
(
skb
,
sch
,
offset
,
count
)
{
for_each_sctp_chunk
(
skb
,
sch
,
_sch
,
offset
,
count
)
{
/* Don't need lock here: this conntrack not in circulation yet */
/* Don't need lock here: this conntrack not in circulation yet */
newconntrack
=
new_state
(
IP_CT_DIR_ORIGINAL
,
newconntrack
=
new_state
(
IP_CT_DIR_ORIGINAL
,
SCTP_CONNTRACK_NONE
,
sch
.
type
);
SCTP_CONNTRACK_NONE
,
sch
->
type
);
/* Invalid: delete conntrack */
/* Invalid: delete conntrack */
if
(
newconntrack
==
SCTP_CONNTRACK_MAX
)
{
if
(
newconntrack
==
SCTP_CONNTRACK_MAX
)
{
...
@@ -455,20 +461,20 @@ static int sctp_new(struct ip_conntrack *conntrack,
...
@@ -455,20 +461,20 @@ static int sctp_new(struct ip_conntrack *conntrack,
}
}
/* Copy the vtag into the state info */
/* Copy the vtag into the state info */
if
(
sch
.
type
==
SCTP_CID_INIT
)
{
if
(
sch
->
type
==
SCTP_CID_INIT
)
{
if
(
s
ctph
.
vtag
==
0
)
{
if
(
s
h
->
vtag
==
0
)
{
sctp_inithdr_t
inithdr
;
sctp_inithdr_t
_inithdr
,
*
ih
;
if
(
skb_copy_bits
(
skb
,
offset
+
sizeof
(
sctp_chunkhdr_t
),
ih
=
skb_header_pointer
(
skb
,
offset
+
sizeof
(
sctp_chunkhdr_t
),
&
inithdr
,
sizeof
(
inithdr
))
!=
0
)
{
sizeof
(
_inithdr
),
&
_inithdr
);
if
(
ih
==
NULL
)
return
0
;
return
0
;
}
DEBUGP
(
"Setting vtag %x for new conn
\n
"
,
DEBUGP
(
"Setting vtag %x for new conn
\n
"
,
i
nithdr
.
init_tag
);
i
h
->
init_tag
);
conntrack
->
proto
.
sctp
.
vtag
[
IP_CT_DIR_REPLY
]
=
conntrack
->
proto
.
sctp
.
vtag
[
IP_CT_DIR_REPLY
]
=
i
nithdr
.
init_tag
;
i
h
->
init_tag
;
}
else
{
}
else
{
/* Sec 8.5.1 (A) */
/* Sec 8.5.1 (A) */
return
0
;
return
0
;
...
@@ -478,8 +484,8 @@ static int sctp_new(struct ip_conntrack *conntrack,
...
@@ -478,8 +484,8 @@ static int sctp_new(struct ip_conntrack *conntrack,
shutdown complete, otherwise an ABORT Sec 8.4 (5) and (8) */
shutdown complete, otherwise an ABORT Sec 8.4 (5) and (8) */
else
{
else
{
DEBUGP
(
"Setting vtag %x for new conn OOTB
\n
"
,
DEBUGP
(
"Setting vtag %x for new conn OOTB
\n
"
,
s
ctph
.
vtag
);
s
h
->
vtag
);
conntrack
->
proto
.
sctp
.
vtag
[
IP_CT_DIR_REPLY
]
=
s
ctph
.
vtag
;
conntrack
->
proto
.
sctp
.
vtag
[
IP_CT_DIR_REPLY
]
=
s
h
->
vtag
;
}
}
conntrack
->
proto
.
sctp
.
state
=
newconntrack
;
conntrack
->
proto
.
sctp
.
state
=
newconntrack
;
...
...
net/ipv4/netfilter/ip_conntrack_proto_udp.c
View file @
3c417db9
...
@@ -91,10 +91,11 @@ static int udp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
...
@@ -91,10 +91,11 @@ static int udp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
{
{
struct
iphdr
*
iph
=
skb
->
nh
.
iph
;
struct
iphdr
*
iph
=
skb
->
nh
.
iph
;
unsigned
int
udplen
=
skb
->
len
-
iph
->
ihl
*
4
;
unsigned
int
udplen
=
skb
->
len
-
iph
->
ihl
*
4
;
struct
udphdr
hdr
;
struct
udphdr
_hdr
,
*
hdr
;
/* Header is too small? */
/* Header is too small? */
if
(
skb_copy_bits
(
skb
,
iph
->
ihl
*
4
,
&
hdr
,
sizeof
(
hdr
))
!=
0
)
{
hdr
=
skb_header_pointer
(
skb
,
iph
->
ihl
*
4
,
sizeof
(
_hdr
),
&
_hdr
);
if
(
hdr
==
NULL
)
{
if
(
LOG_INVALID
(
IPPROTO_UDP
))
if
(
LOG_INVALID
(
IPPROTO_UDP
))
nf_log_packet
(
PF_INET
,
0
,
skb
,
NULL
,
NULL
,
nf_log_packet
(
PF_INET
,
0
,
skb
,
NULL
,
NULL
,
"ip_ct_udp: short packet "
);
"ip_ct_udp: short packet "
);
...
@@ -102,7 +103,7 @@ static int udp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
...
@@ -102,7 +103,7 @@ static int udp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
}
}
/* Truncated/malformed packets */
/* Truncated/malformed packets */
if
(
ntohs
(
hdr
.
len
)
>
udplen
||
ntohs
(
hdr
.
len
)
<
sizeof
(
hdr
))
{
if
(
ntohs
(
hdr
->
len
)
>
udplen
||
ntohs
(
hdr
->
len
)
<
sizeof
(
*
hdr
))
{
if
(
LOG_INVALID
(
IPPROTO_UDP
))
if
(
LOG_INVALID
(
IPPROTO_UDP
))
nf_log_packet
(
PF_INET
,
0
,
skb
,
NULL
,
NULL
,
nf_log_packet
(
PF_INET
,
0
,
skb
,
NULL
,
NULL
,
"ip_ct_udp: truncated/malformed packet "
);
"ip_ct_udp: truncated/malformed packet "
);
...
@@ -110,7 +111,7 @@ static int udp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
...
@@ -110,7 +111,7 @@ static int udp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
}
}
/* Packet with no checksum */
/* Packet with no checksum */
if
(
!
hdr
.
check
)
if
(
!
hdr
->
check
)
return
NF_ACCEPT
;
return
NF_ACCEPT
;
/* Checksum invalid? Ignore.
/* Checksum invalid? Ignore.
...
...
net/ipv4/netfilter/ip_conntrack_standalone.c
View file @
3c417db9
...
@@ -871,7 +871,6 @@ EXPORT_SYMBOL(ip_conntrack_protocol_unregister);
...
@@ -871,7 +871,6 @@ EXPORT_SYMBOL(ip_conntrack_protocol_unregister);
EXPORT_SYMBOL
(
invert_tuplepr
);
EXPORT_SYMBOL
(
invert_tuplepr
);
EXPORT_SYMBOL
(
ip_conntrack_alter_reply
);
EXPORT_SYMBOL
(
ip_conntrack_alter_reply
);
EXPORT_SYMBOL
(
ip_conntrack_destroyed
);
EXPORT_SYMBOL
(
ip_conntrack_destroyed
);
EXPORT_SYMBOL
(
ip_conntrack_get
);
EXPORT_SYMBOL
(
need_ip_conntrack
);
EXPORT_SYMBOL
(
need_ip_conntrack
);
EXPORT_SYMBOL
(
ip_conntrack_helper_register
);
EXPORT_SYMBOL
(
ip_conntrack_helper_register
);
EXPORT_SYMBOL
(
ip_conntrack_helper_unregister
);
EXPORT_SYMBOL
(
ip_conntrack_helper_unregister
);
...
...
net/ipv4/netfilter/ipt_helper.c
View file @
3c417db9
...
@@ -107,6 +107,7 @@ static struct ipt_match helper_match = {
...
@@ -107,6 +107,7 @@ static struct ipt_match helper_match = {
static
int
__init
init
(
void
)
static
int
__init
init
(
void
)
{
{
need_ip_conntrack
();
return
ipt_register_match
(
&
helper_match
);
return
ipt_register_match
(
&
helper_match
);
}
}
...
...
net/ipv4/netfilter/ipt_sctp.c
View file @
3c417db9
...
@@ -42,7 +42,7 @@ match_packet(const struct sk_buff *skb,
...
@@ -42,7 +42,7 @@ match_packet(const struct sk_buff *skb,
{
{
int
offset
;
int
offset
;
u_int32_t
chunkmapcopy
[
256
/
sizeof
(
u_int32_t
)];
u_int32_t
chunkmapcopy
[
256
/
sizeof
(
u_int32_t
)];
sctp_chunkhdr_t
sch
;
sctp_chunkhdr_t
_sch
,
*
sch
;
#ifdef DEBUG_SCTP
#ifdef DEBUG_SCTP
int
i
=
0
;
int
i
=
0
;
...
@@ -54,38 +54,39 @@ match_packet(const struct sk_buff *skb,
...
@@ -54,38 +54,39 @@ match_packet(const struct sk_buff *skb,
offset
=
skb
->
nh
.
iph
->
ihl
*
4
+
sizeof
(
sctp_sctphdr_t
);
offset
=
skb
->
nh
.
iph
->
ihl
*
4
+
sizeof
(
sctp_sctphdr_t
);
do
{
do
{
if
(
skb_copy_bits
(
skb
,
offset
,
&
sch
,
sizeof
(
sch
))
<
0
)
{
sch
=
skb_header_pointer
(
skb
,
offset
,
sizeof
(
_sch
),
&
_sch
);
if
(
sch
==
NULL
)
{
duprintf
(
"Dropping invalid SCTP packet.
\n
"
);
duprintf
(
"Dropping invalid SCTP packet.
\n
"
);
*
hotdrop
=
1
;
*
hotdrop
=
1
;
return
0
;
return
0
;
}
}
duprintf
(
"Chunk num: %d
\t
offset: %d
\t
type: %d
\t
length: %d
\t
flags: %x
\n
"
,
duprintf
(
"Chunk num: %d
\t
offset: %d
\t
type: %d
\t
length: %d
\t
flags: %x
\n
"
,
++
i
,
offset
,
sch
.
type
,
htons
(
sch
.
length
),
sch
.
flags
);
++
i
,
offset
,
sch
->
type
,
htons
(
sch
->
length
),
sch
->
flags
);
offset
+=
(
htons
(
sch
.
length
)
+
3
)
&
~
3
;
offset
+=
(
htons
(
sch
->
length
)
+
3
)
&
~
3
;
duprintf
(
"skb->len: %d
\t
offset: %d
\n
"
,
skb
->
len
,
offset
);
duprintf
(
"skb->len: %d
\t
offset: %d
\n
"
,
skb
->
len
,
offset
);
if
(
SCTP_CHUNKMAP_IS_SET
(
chunkmap
,
sch
.
type
))
{
if
(
SCTP_CHUNKMAP_IS_SET
(
chunkmap
,
sch
->
type
))
{
switch
(
chunk_match_type
)
{
switch
(
chunk_match_type
)
{
case
SCTP_CHUNK_MATCH_ANY
:
case
SCTP_CHUNK_MATCH_ANY
:
if
(
match_flags
(
flag_info
,
flag_count
,
if
(
match_flags
(
flag_info
,
flag_count
,
sch
.
type
,
sch
.
flags
))
{
sch
->
type
,
sch
->
flags
))
{
return
1
;
return
1
;
}
}
break
;
break
;
case
SCTP_CHUNK_MATCH_ALL
:
case
SCTP_CHUNK_MATCH_ALL
:
if
(
match_flags
(
flag_info
,
flag_count
,
if
(
match_flags
(
flag_info
,
flag_count
,
sch
.
type
,
sch
.
flags
))
{
sch
->
type
,
sch
->
flags
))
{
SCTP_CHUNKMAP_CLEAR
(
chunkmapcopy
,
sch
.
type
);
SCTP_CHUNKMAP_CLEAR
(
chunkmapcopy
,
sch
->
type
);
}
}
break
;
break
;
case
SCTP_CHUNK_MATCH_ONLY
:
case
SCTP_CHUNK_MATCH_ONLY
:
if
(
!
match_flags
(
flag_info
,
flag_count
,
if
(
!
match_flags
(
flag_info
,
flag_count
,
sch
.
type
,
sch
.
flags
))
{
sch
->
type
,
sch
->
flags
))
{
return
0
;
return
0
;
}
}
break
;
break
;
...
@@ -120,7 +121,7 @@ match(const struct sk_buff *skb,
...
@@ -120,7 +121,7 @@ match(const struct sk_buff *skb,
int
*
hotdrop
)
int
*
hotdrop
)
{
{
const
struct
ipt_sctp_info
*
info
;
const
struct
ipt_sctp_info
*
info
;
sctp_sctphdr_t
sh
;
sctp_sctphdr_t
_sh
,
*
sh
;
info
=
(
const
struct
ipt_sctp_info
*
)
matchinfo
;
info
=
(
const
struct
ipt_sctp_info
*
)
matchinfo
;
...
@@ -129,18 +130,19 @@ match(const struct sk_buff *skb,
...
@@ -129,18 +130,19 @@ match(const struct sk_buff *skb,
return
0
;
return
0
;
}
}
if
(
skb_copy_bits
(
skb
,
skb
->
nh
.
iph
->
ihl
*
4
,
&
sh
,
sizeof
(
sh
))
<
0
)
{
sh
=
skb_header_pointer
(
skb
,
skb
->
nh
.
iph
->
ihl
*
4
,
sizeof
(
_sh
),
&
_sh
);
if
(
sh
==
NULL
)
{
duprintf
(
"Dropping evil TCP offset=0 tinygram.
\n
"
);
duprintf
(
"Dropping evil TCP offset=0 tinygram.
\n
"
);
*
hotdrop
=
1
;
*
hotdrop
=
1
;
return
0
;
return
0
;
}
}
duprintf
(
"spt: %d
\t
dpt: %d
\n
"
,
ntohs
(
sh
.
source
),
ntohs
(
sh
.
dest
));
duprintf
(
"spt: %d
\t
dpt: %d
\n
"
,
ntohs
(
sh
->
source
),
ntohs
(
sh
->
dest
));
return
SCCHECK
(((
ntohs
(
sh
.
source
)
>=
info
->
spts
[
0
])
return
SCCHECK
(((
ntohs
(
sh
->
source
)
>=
info
->
spts
[
0
])
&&
(
ntohs
(
sh
.
source
)
<=
info
->
spts
[
1
])),
&&
(
ntohs
(
sh
->
source
)
<=
info
->
spts
[
1
])),
IPT_SCTP_SRC_PORTS
,
info
->
flags
,
info
->
invflags
)
IPT_SCTP_SRC_PORTS
,
info
->
flags
,
info
->
invflags
)
&&
SCCHECK
(((
ntohs
(
sh
.
dest
)
>=
info
->
dpts
[
0
])
&&
SCCHECK
(((
ntohs
(
sh
->
dest
)
>=
info
->
dpts
[
0
])
&&
(
ntohs
(
sh
.
dest
)
<=
info
->
dpts
[
1
])),
&&
(
ntohs
(
sh
->
dest
)
<=
info
->
dpts
[
1
])),
IPT_SCTP_DEST_PORTS
,
info
->
flags
,
info
->
invflags
)
IPT_SCTP_DEST_PORTS
,
info
->
flags
,
info
->
invflags
)
&&
SCCHECK
(
match_packet
(
skb
,
info
->
chunkmap
,
info
->
chunk_match_type
,
&&
SCCHECK
(
match_packet
(
skb
,
info
->
chunkmap
,
info
->
chunk_match_type
,
info
->
flag_info
,
info
->
flag_count
,
info
->
flag_info
,
info
->
flag_count
,
...
...
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