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
fb41bd3f
Commit
fb41bd3f
authored
Sep 27, 2004
by
Patrick McHardy
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[NETFILTER]: Convert sctp conntrack protocol to skb_header_pointer
Signed-off-by:
Patrick McHardy
<
kaber@trash.net
>
parent
d12e5047
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
65 additions
and
59 deletions
+65
-59
net/ipv4/netfilter/ip_conntrack_proto_sctp.c
net/ipv4/netfilter/ip_conntrack_proto_sctp.c
+65
-59
No files found.
net/ipv4/netfilter/ip_conntrack_proto_sctp.c
View file @
fb41bd3f
...
...
@@ -152,18 +152,18 @@ static int sctp_pkt_to_tuple(const struct sk_buff *skb,
unsigned
int
dataoff
,
struct
ip_conntrack_tuple
*
tuple
)
{
sctp_sctphdr_t
hdr
;
sctp_sctphdr_t
_hdr
,
*
hp
;
DEBUGP
(
__FUNCTION__
);
DEBUGP
(
"
\n
"
);
/* 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
;
tuple
->
src
.
u
.
sctp
.
port
=
hdr
.
source
;
tuple
->
dst
.
u
.
sctp
.
port
=
hdr
.
dest
;
tuple
->
src
.
u
.
sctp
.
port
=
hp
->
source
;
tuple
->
dst
.
u
.
sctp
.
port
=
hp
->
dest
;
return
1
;
}
...
...
@@ -206,10 +206,11 @@ static int sctp_print_conntrack(struct seq_file *s,
return
seq_printf
(
s
,
"%s "
,
sctp_conntrack_names
[
state
]);
}
#define for_each_sctp_chunk(skb, sch, offset, count) \
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 += (htons(sch.length) + 3) & ~3, count++)
#define for_each_sctp_chunk(skb, sch, _sch, offset, count) \
for (offset = skb->nh.iph->ihl * 4 + sizeof(sctp_sctphdr_t), count = 0; \
offset < skb->len && \
(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 */
static
int
do_basic_checks
(
struct
ip_conntrack
*
conntrack
,
...
...
@@ -217,7 +218,7 @@ static int do_basic_checks(struct ip_conntrack *conntrack,
char
*
map
)
{
u_int32_t
offset
,
count
;
sctp_chunkhdr_t
sch
;
sctp_chunkhdr_t
_sch
,
*
sch
;
int
flag
;
DEBUGP
(
__FUNCTION__
);
...
...
@@ -225,19 +226,19 @@ static int do_basic_checks(struct ip_conntrack *conntrack,
flag
=
0
;
for_each_sctp_chunk
(
skb
,
sch
,
offset
,
count
)
{
DEBUGP
(
"Chunk Num: %d Type: %d
\n
"
,
count
,
sch
.
type
);
for_each_sctp_chunk
(
skb
,
sch
,
_sch
,
offset
,
count
)
{
DEBUGP
(
"Chunk Num: %d Type: %d
\n
"
,
count
,
sch
->
type
);
if
(
sch
.
type
==
SCTP_CID_INIT
||
sch
.
type
==
SCTP_CID_INIT_ACK
||
sch
.
type
==
SCTP_CID_SHUTDOWN_COMPLETE
)
{
if
(
sch
->
type
==
SCTP_CID_INIT
||
sch
->
type
==
SCTP_CID_INIT_ACK
||
sch
->
type
==
SCTP_CID_SHUTDOWN_COMPLETE
)
{
flag
=
1
;
}
/* Cookie Ack/Echo chunks not the first OR
Init / Init Ack / Shutdown compl chunks not the only chunks */
if
((
sch
.
type
==
SCTP_CID_COOKIE_ACK
||
sch
.
type
==
SCTP_CID_COOKIE_ECHO
if
((
sch
->
type
==
SCTP_CID_COOKIE_ACK
||
sch
->
type
==
SCTP_CID_COOKIE_ECHO
||
flag
)
&&
count
!=
0
)
{
DEBUGP
(
"Basic checks failed
\n
"
);
...
...
@@ -245,7 +246,7 @@ static int do_basic_checks(struct ip_conntrack *conntrack,
}
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,
enum
ip_conntrack_info
ctinfo
)
{
enum
sctp_conntrack
newconntrack
,
oldsctpstate
;
sctp_sctphdr_t
sctph
;
sctp_chunkhdr_t
sch
;
struct
iphdr
*
iph
=
skb
->
nh
.
iph
;
sctp_sctphdr_t
_sctph
,
*
sh
;
sctp_chunkhdr_t
_sch
,
*
sch
;
u_int32_t
offset
,
count
;
char
map
[
256
/
sizeof
(
char
)]
=
{
0
};
DEBUGP
(
__FUNCTION__
);
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
;
if
(
do_basic_checks
(
conntrack
,
skb
,
map
)
!=
0
)
...
...
@@ -333,71 +336,72 @@ static int sctp_packet(struct ip_conntrack *conntrack,
&&
!
test_bit
(
SCTP_CID_COOKIE_ECHO
,
(
void
*
)
map
)
&&
!
test_bit
(
SCTP_CID_ABORT
,
(
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
"
);
return
-
1
;
}
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
);
/* 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) */
if
(
s
ctph
.
vtag
!=
0
)
{
if
(
s
h
->
vtag
!=
0
)
{
WRITE_UNLOCK
(
&
sctp_lock
);
return
-
1
;
}
}
else
if
(
sch
.
type
==
SCTP_CID_ABORT
)
{
}
else
if
(
sch
->
type
==
SCTP_CID_ABORT
)
{
/* Sec 8.5.1 (B) */
if
(
!
(
s
ctph
.
vtag
==
conntrack
->
proto
.
sctp
.
vtag
[
CTINFO2DIR
(
ctinfo
)])
&&
!
(
s
ctph
.
vtag
==
conntrack
->
proto
.
sctp
.
vtag
if
(
!
(
s
h
->
vtag
==
conntrack
->
proto
.
sctp
.
vtag
[
CTINFO2DIR
(
ctinfo
)])
&&
!
(
s
h
->
vtag
==
conntrack
->
proto
.
sctp
.
vtag
[
1
-
CTINFO2DIR
(
ctinfo
)]))
{
WRITE_UNLOCK
(
&
sctp_lock
);
return
-
1
;
}
}
else
if
(
sch
.
type
==
SCTP_CID_SHUTDOWN_COMPLETE
)
{
}
else
if
(
sch
->
type
==
SCTP_CID_SHUTDOWN_COMPLETE
)
{
/* Sec 8.5.1 (C) */
if
(
!
(
s
ctph
.
vtag
==
conntrack
->
proto
.
sctp
.
vtag
[
CTINFO2DIR
(
ctinfo
)])
&&
!
(
s
ctph
.
vtag
==
conntrack
->
proto
.
sctp
.
vtag
if
(
!
(
s
h
->
vtag
==
conntrack
->
proto
.
sctp
.
vtag
[
CTINFO2DIR
(
ctinfo
)])
&&
!
(
s
h
->
vtag
==
conntrack
->
proto
.
sctp
.
vtag
[
1
-
CTINFO2DIR
(
ctinfo
)]
&&
(
sch
.
flags
&
1
)))
{
&&
(
sch
->
flags
&
1
)))
{
WRITE_UNLOCK
(
&
sctp_lock
);
return
-
1
;
}
}
else
if
(
sch
.
type
==
SCTP_CID_COOKIE_ECHO
)
{
}
else
if
(
sch
->
type
==
SCTP_CID_COOKIE_ECHO
)
{
/* 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
);
return
-
1
;
}
}
oldsctpstate
=
conntrack
->
proto
.
sctp
.
state
;
newconntrack
=
new_state
(
CTINFO2DIR
(
ctinfo
),
oldsctpstate
,
sch
.
type
);
newconntrack
=
new_state
(
CTINFO2DIR
(
ctinfo
),
oldsctpstate
,
sch
->
type
);
/* Invalid */
if
(
newconntrack
==
SCTP_CONNTRACK_MAX
)
{
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
);
return
-
1
;
}
/* If it is an INIT or an INIT ACK note down the vtag */
if
(
sch
.
type
==
SCTP_CID_INIT
||
sch
.
type
==
SCTP_CID_INIT_ACK
)
{
sctp_inithdr_t
inithdr
;
if
(
sch
->
type
==
SCTP_CID_INIT
||
sch
->
type
==
SCTP_CID_INIT_ACK
)
{
sctp_inithdr_t
_inithdr
,
*
ih
;
if
(
skb_copy_bits
(
skb
,
offset
+
sizeof
(
sctp_chunkhdr_t
),
&
inithdr
,
sizeof
(
inithdr
))
!=
0
)
{
ih
=
skb_header_pointer
(
skb
,
offset
+
sizeof
(
sctp_chunkhdr_t
),
sizeof
(
_inithdr
),
&
_inithdr
);
if
(
ih
==
NULL
)
{
WRITE_UNLOCK
(
&
sctp_lock
);
return
-
1
;
}
DEBUGP
(
"Setting vtag %x for dir %d
\n
"
,
i
nithdr
.
init_tag
,
CTINFO2DIR
(
ctinfo
));
conntrack
->
proto
.
sctp
.
vtag
[
IP_CT_DIR_ORIGINAL
]
=
i
nithdr
.
init_tag
;
i
h
->
init_tag
,
CTINFO2DIR
(
ctinfo
));
conntrack
->
proto
.
sctp
.
vtag
[
IP_CT_DIR_ORIGINAL
]
=
i
h
->
init_tag
;
}
conntrack
->
proto
.
sctp
.
state
=
newconntrack
;
...
...
@@ -421,15 +425,17 @@ static int sctp_new(struct ip_conntrack *conntrack,
const
struct
sk_buff
*
skb
)
{
enum
sctp_conntrack
newconntrack
;
sctp_sctphdr_t
sctph
;
sctp_chunkhdr_t
sch
;
struct
iphdr
*
iph
=
skb
->
nh
.
iph
;
sctp_sctphdr_t
_sctph
,
*
sh
;
sctp_chunkhdr_t
_sch
,
*
sch
;
u_int32_t
offset
,
count
;
char
map
[
256
/
sizeof
(
char
)]
=
{
0
};
DEBUGP
(
__FUNCTION__
);
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
;
if
(
do_basic_checks
(
conntrack
,
skb
,
map
)
!=
0
)
...
...
@@ -443,10 +449,10 @@ static int sctp_new(struct ip_conntrack *conntrack,
}
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 */
newconntrack
=
new_state
(
IP_CT_DIR_ORIGINAL
,
SCTP_CONNTRACK_NONE
,
sch
.
type
);
SCTP_CONNTRACK_NONE
,
sch
->
type
);
/* Invalid: delete conntrack */
if
(
newconntrack
==
SCTP_CONNTRACK_MAX
)
{
...
...
@@ -455,20 +461,20 @@ static int sctp_new(struct ip_conntrack *conntrack,
}
/* Copy the vtag into the state info */
if
(
sch
.
type
==
SCTP_CID_INIT
)
{
if
(
s
ctph
.
vtag
==
0
)
{
sctp_inithdr_t
inithdr
;
if
(
sch
->
type
==
SCTP_CID_INIT
)
{
if
(
s
h
->
vtag
==
0
)
{
sctp_inithdr_t
_inithdr
,
*
ih
;
i
f
(
skb_copy_bits
(
skb
,
offset
+
sizeof
(
sctp_chunkhdr_t
),
&
inithdr
,
sizeof
(
inithdr
))
!=
0
)
{
return
0
;
}
i
h
=
skb_header_pointer
(
skb
,
offset
+
sizeof
(
sctp_chunkhdr_t
),
sizeof
(
_inithdr
),
&
_inithdr
);
if
(
ih
==
NULL
)
return
0
;
DEBUGP
(
"Setting vtag %x for new conn
\n
"
,
i
nithdr
.
init_tag
);
i
h
->
init_tag
);
conntrack
->
proto
.
sctp
.
vtag
[
IP_CT_DIR_REPLY
]
=
i
nithdr
.
init_tag
;
i
h
->
init_tag
;
}
else
{
/* Sec 8.5.1 (A) */
return
0
;
...
...
@@ -478,8 +484,8 @@ static int sctp_new(struct ip_conntrack *conntrack,
shutdown complete, otherwise an ABORT Sec 8.4 (5) and (8) */
else
{
DEBUGP
(
"Setting vtag %x for new conn OOTB
\n
"
,
s
ctph
.
vtag
);
conntrack
->
proto
.
sctp
.
vtag
[
IP_CT_DIR_REPLY
]
=
s
ctph
.
vtag
;
s
h
->
vtag
);
conntrack
->
proto
.
sctp
.
vtag
[
IP_CT_DIR_REPLY
]
=
s
h
->
vtag
;
}
conntrack
->
proto
.
sctp
.
state
=
newconntrack
;
...
...
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