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
Kirill Smelkov
linux
Commits
75041b3a
Commit
75041b3a
authored
Oct 09, 2002
by
Jon Grimm
Browse files
Options
Browse Files
Download
Plain Diff
Merge touki.austin.ibm.com:/home/jgrimm/bk/lksctp-2.5
into touki.austin.ibm.com:/home/jgrimm/bk/lksctp-2.5.work
parents
6d727be7
dec5c911
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
217 additions
and
140 deletions
+217
-140
include/net/sctp/sm.h
include/net/sctp/sm.h
+2
-2
include/net/sctp/structs.h
include/net/sctp/structs.h
+1
-1
net/sctp/associola.c
net/sctp/associola.c
+0
-7
net/sctp/bind_addr.c
net/sctp/bind_addr.c
+18
-14
net/sctp/input.c
net/sctp/input.c
+15
-10
net/sctp/sm_make_chunk.c
net/sctp/sm_make_chunk.c
+33
-34
net/sctp/sm_statefuns.c
net/sctp/sm_statefuns.c
+148
-72
No files found.
include/net/sctp/sm.h
View file @
75041b3a
...
...
@@ -329,10 +329,10 @@ __u32 sctp_generate_tag(const sctp_endpoint_t *);
__u32
sctp_generate_tsn
(
const
sctp_endpoint_t
*
);
/* 4th level prototypes */
void
sctp_param2sockaddr
(
sockaddr_storage_t
*
addr
,
const
sctpParam_t
param
,
void
sctp_param2sockaddr
(
sockaddr_storage_t
*
addr
,
sctp_addr_param_t
*
,
__u16
port
);
int
sctp_addr2sockaddr
(
const
sctpParam_t
,
sockaddr_storage_t
*
);
int
sockaddr2sctp_addr
(
const
sockaddr_storage_t
*
,
sctp
Param_t
);
int
sockaddr2sctp_addr
(
const
sockaddr_storage_t
*
,
sctp
_addr_param_t
*
);
/* Extern declarations for major data structures. */
sctp_sm_table_entry_t
*
sctp_chunk_event_lookup
(
sctp_cid_t
,
sctp_state_t
);
...
...
include/net/sctp/structs.h
View file @
75041b3a
...
...
@@ -378,7 +378,7 @@ typedef union {
typedef
union
{
sctp_ipv4addr_param_t
v4
;
sctp_ipv6addr_param_t
v6
;
}
sctp
IpAddress
_t
;
}
sctp
_addr_param
_t
;
/* RFC 2960. Section 3.3.5 Heartbeat.
* Heartbeat Information: variable length
...
...
net/sctp/associola.c
View file @
75041b3a
...
...
@@ -476,13 +476,6 @@ sctp_transport_t *sctp_assoc_add_peer(sctp_association_t *asoc,
asoc
->
peer
.
retran_path
=
peer
;
}
/* If we do not yet have a primary path, set one. */
if
(
NULL
==
asoc
->
peer
.
primary_path
)
{
asoc
->
peer
.
primary_path
=
peer
;
asoc
->
peer
.
active_path
=
peer
;
asoc
->
peer
.
retran_path
=
peer
;
}
if
(
asoc
->
peer
.
active_path
==
asoc
->
peer
.
retran_path
)
asoc
->
peer
.
retran_path
=
peer
;
...
...
net/sctp/bind_addr.c
View file @
75041b3a
...
...
@@ -199,11 +199,10 @@ int sctp_del_bind_addr(sctp_bind_addr_t *bp, sockaddr_storage_t *del_addr)
sctpParam_t
sctp_bind_addrs_to_raw
(
const
sctp_bind_addr_t
*
bp
,
int
*
addrs_len
,
int
priority
)
{
sctpParam_t
rawaddr
;
sctpParam_t
addrparms
;
sctpParam_t
retval
;
int
addrparms_len
;
sctp
IpAddress_t
rawaddr_space
;
sctp
_addr_param_t
rawaddr
;
int
len
;
struct
sockaddr_storage_list
*
addr
;
struct
list_head
*
pos
;
...
...
@@ -214,7 +213,7 @@ sctpParam_t sctp_bind_addrs_to_raw(const sctp_bind_addr_t *bp, int *addrs_len,
/* Allocate enough memory at once. */
list_for_each
(
pos
,
&
bp
->
address_list
)
{
len
+=
sizeof
(
sctp_
ipv6
addr_param_t
);
len
+=
sizeof
(
sctp_addr_param_t
);
}
addrparms
.
v
=
kmalloc
(
len
,
priority
);
...
...
@@ -222,12 +221,11 @@ sctpParam_t sctp_bind_addrs_to_raw(const sctp_bind_addr_t *bp, int *addrs_len,
goto
end_raw
;
retval
=
addrparms
;
rawaddr
.
v4
=
&
rawaddr_space
.
v4
;
list_for_each
(
pos
,
&
bp
->
address_list
)
{
addr
=
list_entry
(
pos
,
struct
sockaddr_storage_list
,
list
);
len
=
sockaddr2sctp_addr
(
&
addr
->
a
,
rawaddr
);
memcpy
(
addrparms
.
v
,
rawaddr
.
v
,
len
);
len
=
sockaddr2sctp_addr
(
&
addr
->
a
,
&
rawaddr
);
memcpy
(
addrparms
.
v
,
&
rawaddr
,
len
);
addrparms
.
v
+=
len
;
addrparms_len
+=
len
;
}
...
...
@@ -244,33 +242,39 @@ sctpParam_t sctp_bind_addrs_to_raw(const sctp_bind_addr_t *bp, int *addrs_len,
int
sctp_raw_to_bind_addrs
(
sctp_bind_addr_t
*
bp
,
__u8
*
raw_addr_list
,
int
addrs_len
,
__u16
port
,
int
priority
)
{
sctpParam_t
rawaddr
;
sctp_addr_param_t
*
rawaddr
;
sctp_paramhdr_t
*
param
;
sockaddr_storage_t
addr
;
int
retval
=
0
;
int
len
;
/* Convert the raw address to standard address format */
while
(
addrs_len
)
{
rawaddr
.
v
=
raw_addr_list
;
if
(
SCTP_PARAM_IPV4_ADDRESS
==
rawaddr
.
p
->
type
||
SCTP_PARAM_IPV6_ADDRESS
==
rawaddr
.
p
->
type
)
{
param
=
(
sctp_paramhdr_t
*
)
raw_addr_list
;
rawaddr
=
(
sctp_addr_param_t
*
)
raw_addr_list
;
switch
(
param
->
type
)
{
case
SCTP_PARAM_IPV4_ADDRESS
:
case
SCTP_PARAM_IPV6_ADDRESS
:
sctp_param2sockaddr
(
&
addr
,
rawaddr
,
port
);
retval
=
sctp_add_bind_addr
(
bp
,
&
addr
,
priority
);
if
(
retval
)
{
/* Can't finish building the list, clean up. */
sctp_bind_addr_clean
(
bp
);
break
;
break
;
;
}
len
=
ntohs
(
rawaddr
.
p
->
length
);
len
=
ntohs
(
param
->
length
);
addrs_len
-=
len
;
raw_addr_list
+=
len
;
}
else
{
break
;
default:
/* Corrupted raw addr list! */
retval
=
-
EINVAL
;
sctp_bind_addr_clean
(
bp
);
break
;
}
if
(
retval
)
break
;
}
return
retval
;
...
...
net/sctp/input.c
View file @
75041b3a
...
...
@@ -584,14 +584,20 @@ static sctp_association_t *__sctp_rcv_initack_lookup(struct sk_buff *skb,
struct
sctphdr
*
sh
=
(
struct
sctphdr
*
)
skb
->
h
.
raw
;
sctp_chunkhdr_t
*
ch
;
__u8
*
ch_end
,
*
data
;
sctp
Param_t
parm
;
sctp
_paramhdr_t
*
parm
;
ch
=
(
sctp_chunkhdr_t
*
)
skb
->
data
;
ch_end
=
((
__u8
*
)
ch
)
+
WORD_ROUND
(
ntohs
(
ch
->
length
));
if
(
SCTP_CID_INIT_ACK
!=
ch
->
type
)
/* If this is INIT/INIT-ACK look inside the chunk too. */
switch
(
ch
->
type
)
{
case
SCTP_CID_INIT
:
case
SCTP_CID_INIT_ACK
:
break
;
default:
return
NULL
;
}
/*
* This code will NOT touch anything inside the chunk--it is
...
...
@@ -609,25 +615,24 @@ static sctp_association_t *__sctp_rcv_initack_lookup(struct sk_buff *skb,
/* Find the start of the TLVs and the end of the chunk. This is
* the region we search for address parameters.
*/
data
=
skb
->
data
+
sizeof
(
sctp_init_chunk_t
);
/* See sctp_process_init() for how to go thru TLVs. */
while
(
data
<
ch_end
)
{
parm
.
v
=
data
;
parm
=
(
sctp_paramhdr_t
*
)
data
;
if
(
!
parm
.
p
->
length
)
if
(
!
parm
->
length
)
break
;
data
+=
WORD_ROUND
(
ntohs
(
parm
.
p
->
length
));
data
+=
WORD_ROUND
(
ntohs
(
parm
->
length
));
/* Note: Ignoring hostname addresses. */
if
((
SCTP_PARAM_IPV4_ADDRESS
!=
parm
.
p
->
type
)
&&
(
SCTP_PARAM_IPV6_ADDRESS
!=
parm
.
p
->
type
))
if
((
SCTP_PARAM_IPV4_ADDRESS
!=
parm
->
type
)
&&
(
SCTP_PARAM_IPV6_ADDRESS
!=
parm
->
type
))
continue
;
sctp_param2sockaddr
(
paddr
,
parm
,
ntohs
(
sh
->
source
));
sctp_param2sockaddr
(
paddr
,
(
sctp_addr_param_t
*
)
parm
,
ntohs
(
sh
->
source
));
asoc
=
__sctp_rcv_lookup_association
(
laddr
,
paddr
,
transportp
);
if
(
asoc
)
return
asoc
;
...
...
net/sctp/sm_make_chunk.c
View file @
75041b3a
...
...
@@ -1454,7 +1454,7 @@ int sctp_verify_init(const sctp_association_t *asoc,
return
0
;
}
/* for (loop through all parameters) */
return
1
;
}
...
...
@@ -1710,6 +1710,7 @@ int sctp_process_param(sctp_association_t *asoc, sctpParam_t param,
sctp_cid_t
cid
,
int
priority
)
{
sockaddr_storage_t
addr
;
sctp_addr_param_t
*
addrparm
;
int
j
;
int
i
;
int
retval
=
1
;
...
...
@@ -1721,24 +1722,23 @@ int sctp_process_param(sctp_association_t *asoc, sctpParam_t param,
*/
switch
(
param
.
p
->
type
)
{
case
SCTP_PARAM_IPV4_ADDRESS
:
if
(
SCTP_CID_INIT
!=
cid
)
{
sctp_param2sockaddr
(
&
addr
,
param
,
asoc
->
peer
.
port
);
scope
=
sctp_scope
(
peer_addr
);
if
(
sctp_in_scope
(
&
addr
,
scope
))
sctp_assoc_add_peer
(
asoc
,
&
addr
,
priority
);
}
addrparm
=
(
sctp_addr_param_t
*
)
param
.
v
;
sctp_param2sockaddr
(
&
addr
,
addrparm
,
asoc
->
peer
.
port
);
scope
=
sctp_scope
(
peer_addr
);
if
(
sctp_in_scope
(
&
addr
,
scope
))
sctp_assoc_add_peer
(
asoc
,
&
addr
,
priority
);
break
;
case
SCTP_PARAM_IPV6_ADDRESS
:
if
(
SCTP_CID_INIT
!=
cid
)
{
if
(
PF_INET6
==
asoc
->
base
.
sk
->
family
)
{
sctp_param2sockaddr
(
&
addr
,
param
,
asoc
->
peer
.
port
);
scope
=
sctp_scope
(
peer_addr
)
;
if
(
sctp_in_scope
(
&
addr
,
scope
))
sctp_assoc_add_peer
(
asoc
,
&
addr
,
priority
);
}
/* Rethink this as we may need to keep for
* restart considerations.
*/
if
(
PF_INET6
==
asoc
->
base
.
sk
->
family
)
{
addrparm
=
(
sctp_addr_param_t
*
)
param
.
v
;
sctp_param2sockaddr
(
&
addr
,
addrparm
,
asoc
->
peer
.
port
);
scope
=
sctp_scope
(
peer_addr
);
if
(
sctp_in_scope
(
&
addr
,
scope
))
sctp_assoc_add_peer
(
asoc
,
&
addr
,
priority
);
}
break
;
...
...
@@ -1833,8 +1833,7 @@ __u32 sctp_generate_tag(const sctp_endpoint_t *ep)
/* Select an initial TSN to send during startup. */
__u32
sctp_generate_tsn
(
const
sctp_endpoint_t
*
ep
)
{
/* I believe that this random number generator complies with RFC1750. */
__u32
retval
;
__u32
retval
;
get_random_bytes
(
&
retval
,
sizeof
(
__u32
));
return
retval
;
...
...
@@ -1845,26 +1844,27 @@ __u32 sctp_generate_tsn(const sctp_endpoint_t *ep)
********************************************************************/
/* Convert from an SCTP IP parameter to a sockaddr_storage_t. */
void
sctp_param2sockaddr
(
sockaddr_storage_t
*
addr
,
sctpParam_t
param
,
__u16
port
)
void
sctp_param2sockaddr
(
sockaddr_storage_t
*
addr
,
sctp_addr_param_t
*
param
,
__u16
port
)
{
switch
(
param
.
p
->
type
)
{
switch
(
param
->
v4
.
param_hdr
.
type
)
{
case
SCTP_PARAM_IPV4_ADDRESS
:
addr
->
v4
.
sin_family
=
AF_INET
;
addr
->
v4
.
sin_port
=
port
;
addr
->
v4
.
sin_addr
.
s_addr
=
param
.
v4
->
addr
.
s_addr
;
addr
->
v4
.
sin_addr
.
s_addr
=
param
->
v4
.
addr
.
s_addr
;
break
;
case
SCTP_PARAM_IPV6_ADDRESS
:
addr
->
v6
.
sin6_family
=
AF_INET6
;
addr
->
v6
.
sin6_port
=
port
;
addr
->
v6
.
sin6_flowinfo
=
0
;
/* BUG */
addr
->
v6
.
sin6_addr
=
param
.
v6
->
addr
;
addr
->
v6
.
sin6_addr
=
param
->
v6
.
addr
;
addr
->
v6
.
sin6_scope_id
=
0
;
/* BUG */
break
;
default:
SCTP_DEBUG_PRINTK
(
"Illegal address type %d
\n
"
,
ntohs
(
param
.
p
->
type
));
ntohs
(
param
->
v4
.
param_hdr
.
type
));
break
;
};
}
...
...
@@ -1904,11 +1904,9 @@ int ipver2af(__u8 ipver)
case
4
:
family
=
AF_INET
;
break
;
case
6
:
family
=
AF_INET6
;
break
;
default:
family
=
0
;
break
;
...
...
@@ -1917,25 +1915,26 @@ int ipver2af(__u8 ipver)
return
family
;
}
/* Convert a sockaddr_in to IP address in an SCTP para. */
/* Returns true if a valid conversion was possible. */
int
sockaddr2sctp_addr
(
const
sockaddr_storage_t
*
sa
,
sctpParam_t
p
)
/* Convert a sockaddr_in to an IP address in an SCTP param.
* Returns len if a valid conversion was possible.
*/
int
sockaddr2sctp_addr
(
const
sockaddr_storage_t
*
sa
,
sctp_addr_param_t
*
p
)
{
int
len
=
0
;
switch
(
sa
->
v4
.
sin_family
)
{
case
AF_INET
:
p
.
p
->
type
=
SCTP_PARAM_IPV4_ADDRESS
;
p
.
p
->
length
=
ntohs
(
sizeof
(
sctp_ipv4addr_param_t
));
p
->
v4
.
param_hdr
.
type
=
SCTP_PARAM_IPV4_ADDRESS
;
p
->
v4
.
param_hdr
.
length
=
ntohs
(
sizeof
(
sctp_ipv4addr_param_t
));
len
=
sizeof
(
sctp_ipv4addr_param_t
);
p
.
v4
->
addr
.
s_addr
=
sa
->
v4
.
sin_addr
.
s_addr
;
p
->
v4
.
addr
.
s_addr
=
sa
->
v4
.
sin_addr
.
s_addr
;
break
;
case
AF_INET6
:
p
.
p
->
type
=
SCTP_PARAM_IPV6_ADDRESS
;
p
.
p
->
length
=
ntohs
(
sizeof
(
sctp_ipv6addr_param_t
));
p
->
v6
.
param_hdr
.
type
=
SCTP_PARAM_IPV6_ADDRESS
;
p
->
v6
.
param_hdr
.
length
=
ntohs
(
sizeof
(
sctp_ipv6addr_param_t
));
len
=
sizeof
(
sctp_ipv6addr_param_t
);
p
.
v6
->
addr
=
*
(
&
sa
->
v6
.
sin6_addr
);
p
->
v6
.
addr
=
*
(
&
sa
->
v6
.
sin6_addr
);
break
;
default:
...
...
net/sctp/sm_statefuns.c
View file @
75041b3a
...
...
@@ -873,6 +873,105 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const sctp_endpoint_t *ep,
return
SCTP_DISPOSITION_CONSUME
;
}
/* Helper function to send out an abort for the restart
* condition.
*/
static
int
sctp_sf_send_restart_abort
(
sockaddr_storage_t
*
ssa
,
sctp_chunk_t
*
init
,
sctp_cmd_seq_t
*
commands
)
{
int
len
;
sctp_packet_t
*
pkt
;
sctp_addr_param_t
*
addrparm
;
sctp_errhdr_t
*
errhdr
;
sctp_endpoint_t
*
ep
;
char
buffer
[
sizeof
(
sctp_errhdr_t
)
+
sizeof
(
sctp_addr_param_t
)];
/* Build the error on the stack. We are way to malloc
* malloc crazy throughout the code today.
*/
errhdr
=
(
sctp_errhdr_t
*
)
buffer
;
addrparm
=
(
sctp_addr_param_t
*
)
errhdr
->
variable
;
/* Copy into a parm format. */
len
=
sockaddr2sctp_addr
(
ssa
,
addrparm
);
len
+=
sizeof
(
sctp_errhdr_t
);
errhdr
->
cause
=
SCTP_ERROR_RESTART
;
errhdr
->
length
=
htons
(
len
);
/* Assign to the control socket. */
ep
=
sctp_sk
((
sctp_get_ctl_sock
()))
->
ep
;
/* Association is NULL since this may be a restart attack and we
* want to send back the attacker's vtag.
*/
pkt
=
sctp_abort_pkt_new
(
ep
,
NULL
,
init
,
errhdr
,
len
);
if
(
!
pkt
)
goto
out
;
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_SEND_PKT
,
SCTP_PACKET
(
pkt
));
/* Discard the rest of the inbound packet. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_DISCARD_PACKET
,
SCTP_NULL
());
out:
/* Even if there is no memory, treat as a failure so
* the packet will get dropped.
*/
return
0
;
}
/* A restart is occuring, check to make sure no new addresses
* are being added as we may be under a takeover attack.
*/
static
int
sctp_sf_check_restart_addrs
(
const
sctp_association_t
*
new_asoc
,
const
sctp_association_t
*
asoc
,
sctp_chunk_t
*
init
,
sctp_cmd_seq_t
*
commands
)
{
sctp_transport_t
*
new_addr
,
*
addr
;
struct
list_head
*
pos
,
*
pos2
;
int
found
;
/* Implementor's Guide - Sectin 5.2.2
* ...
* Before responding the endpoint MUST check to see if the
* unexpected INIT adds new addresses to the association. If new
* addresses are added to the association, the endpoint MUST respond
* with an ABORT..
*/
/* Search through all current addresses and make sure
* we aren't adding any new ones.
*/
new_addr
=
0
;
found
=
0
;
list_for_each
(
pos
,
&
new_asoc
->
peer
.
transport_addr_list
)
{
new_addr
=
list_entry
(
pos
,
sctp_transport_t
,
transports
);
found
=
0
;
list_for_each
(
pos2
,
&
asoc
->
peer
.
transport_addr_list
)
{
addr
=
list_entry
(
pos2
,
sctp_transport_t
,
transports
);
if
(
sctp_cmp_addr_exact
(
&
new_addr
->
ipaddr
,
&
addr
->
ipaddr
))
{
found
=
1
;
break
;
}
}
if
(
!
found
)
break
;
}
/* If a new address was added, ABORT the sender. */
if
(
!
found
&&
new_addr
)
{
sctp_sf_send_restart_abort
(
&
new_addr
->
ipaddr
,
init
,
commands
);
}
/* Return success if all addresses were found. */
return
found
;
}
/* Populate the verification/tie tags based on overlapping INIT
* scenario.
*
...
...
@@ -969,6 +1068,7 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
sctp_disposition_t
retval
;
sctp_chunk_t
*
chunk
=
arg
;
sctp_chunk_t
*
repl
;
sctp_association_t
*
new_asoc
;
...
...
@@ -1006,15 +1106,14 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
ntohs
(
err_chunk
->
chunk_hdr
->
length
)
-
sizeof
(
sctp_chunkhdr_t
));
sctp_free_chunk
(
err_chunk
);
if
(
packet
)
{
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_SEND_PKT
,
SCTP_PACKET
(
packet
));
ret
urn
SCTP_DISPOSITION_CONSUME
;
ret
val
=
SCTP_DISPOSITION_CONSUME
;
}
else
{
ret
urn
SCTP_DISPOSITION_NOMEM
;
ret
val
=
SCTP_DISPOSITION_NOMEM
;
}
goto
cleanup
;
}
else
{
return
sctp_sf_tabort_8_4_8
(
ep
,
asoc
,
type
,
arg
,
commands
);
...
...
@@ -1039,6 +1138,19 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
sctp_process_init
(
new_asoc
,
chunk
->
chunk_hdr
->
type
,
sctp_source
(
chunk
),
(
sctp_init_chunk_t
*
)
chunk
->
chunk_hdr
,
GFP_ATOMIC
);
/* Make sure no new addresses are being added during the
* restart. Do not do this check for COOKIE-WAIT state,
* since there are no peer addresses to check against.
* Upon return an ABORT will have been sent if needed.
*/
if
(
asoc
->
state
!=
SCTP_STATE_COOKIE_WAIT
)
{
if
(
!
sctp_sf_check_restart_addrs
(
new_asoc
,
asoc
,
chunk
,
commands
))
{
retval
=
SCTP_DISPOSITION_CONSUME
;
goto
cleanup_asoc
;
}
}
sctp_tietags_populate
(
new_asoc
,
asoc
);
/* B) "Z" shall respond immediately with an INIT ACK chunk. */
...
...
@@ -1086,13 +1198,18 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
* Otherwise, "Z" will be vulnerable to resource attacks.
*/
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_DELETE_TCB
,
SCTP_NULL
());
ret
urn
SCTP_DISPOSITION_CONSUME
;
ret
val
=
SCTP_DISPOSITION_CONSUME
;
nomem
:
cleanup
:
if
(
err_chunk
)
sctp_free_chunk
(
err_chunk
);
return
SCTP_DISPOSITION_NOMEM
;
return
retval
;
nomem:
retval
=
SCTP_DISPOSITION_NOMEM
;
goto
cleanup
;
cleanup_asoc:
sctp_association_free
(
new_asoc
);
goto
cleanup
;
}
/*
...
...
@@ -1198,6 +1315,8 @@ sctp_disposition_t sctp_sf_do_5_2_2_dupinit(const sctp_endpoint_t *ep,
return
sctp_sf_do_unexpected_init
(
ep
,
asoc
,
type
,
arg
,
commands
);
}
/* Unexpected COOKIE-ECHO handlerfor peer restart (Table 2, action 'A')
*
* Section 5.2.4
...
...
@@ -1212,9 +1331,6 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const sctp_endpoint_t *ep,
sctp_init_chunk_t
*
peer_init
;
sctp_ulpevent_t
*
ev
;
sctp_chunk_t
*
repl
;
sctp_transport_t
*
new_addr
,
*
addr
;
struct
list_head
*
pos
,
*
pos2
,
*
temp
;
int
found
,
error
;
/* new_asoc is a brand-new association, so these are not yet
* side effects--it is safe to run them here.
...
...
@@ -1223,60 +1339,14 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const sctp_endpoint_t *ep,
sctp_process_init
(
new_asoc
,
chunk
->
chunk_hdr
->
type
,
sctp_source
(
chunk
),
peer_init
,
GFP_ATOMIC
);
/* Make sure peer is not adding new addresses. */
found
=
0
;
new_addr
=
NULL
;
list_for_each
(
pos
,
&
new_asoc
->
peer
.
transport_addr_list
)
{
new_addr
=
list_entry
(
pos
,
sctp_transport_t
,
transports
);
found
=
0
;
list_for_each_safe
(
pos2
,
temp
,
&
asoc
->
peer
.
transport_addr_list
)
{
addr
=
list_entry
(
pos2
,
sctp_transport_t
,
transports
);
if
(
sctp_cmp_addr_exact
(
&
new_addr
->
ipaddr
,
&
addr
->
ipaddr
))
{
found
=
1
;
break
;
}
}
if
(
!
found
)
break
;
}
if
(
!
found
)
{
sctp_bind_addr_t
*
bp
;
sctpParam_t
rawaddr
;
int
len
;
bp
=
sctp_bind_addr_new
(
GFP_ATOMIC
);
if
(
!
bp
)
goto
nomem
;
error
=
sctp_add_bind_addr
(
bp
,
&
new_addr
->
ipaddr
,
GFP_ATOMIC
);
if
(
error
)
goto
nomem_add
;
rawaddr
=
sctp_bind_addrs_to_raw
(
bp
,
&
len
,
GFP_ATOMIC
);
if
(
!
rawaddr
.
v
)
goto
nomem_raw
;
repl
=
sctp_make_abort
(
asoc
,
chunk
,
len
+
sizeof
(
sctp_errhdr_t
));
if
(
!
repl
)
goto
nomem_abort
;
sctp_init_cause
(
repl
,
SCTP_ERROR_RESTART
,
rawaddr
.
v
,
len
);
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
repl
));
/* Discard the rest of the packet too. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_DISCARD_PACKET
,
SCTP_NULL
());
/* Make sure no new addresses are being added during the
* restart. Though this is a pretty complicated attack
* since you'd have to get inside the cookie.
*/
if
(
!
sctp_sf_check_restart_addrs
(
new_asoc
,
asoc
,
chunk
,
commands
))
{
printk
(
"cookie echo check
\n
"
);
return
SCTP_DISPOSITION_CONSUME
;
nomem_abort:
kfree
(
rawaddr
.
v
);
nomem_raw:
nomem_add:
sctp_bind_addr_free
(
bp
);
goto
nomem
;
}
}
/* For now, fail any unsent/unacked data. Consider the optional
* choice of resending of this data.
...
...
@@ -1305,7 +1375,6 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const sctp_endpoint_t *ep,
nomem_ev:
sctp_free_chunk
(
repl
);
nomem:
return
SCTP_DISPOSITION_NOMEM
;
}
...
...
@@ -2529,7 +2598,7 @@ sctp_disposition_t sctp_sf_tabort_8_4_8(const sctp_endpoint_t *ep,
if
(
packet
)
{
/* Make an ABORT. The T bit will be set if the asoc
* is NULL.
*/
*/
abort
=
sctp_make_abort
(
asoc
,
chunk
,
0
);
if
(
!
abort
)
{
sctp_ootb_pkt_free
(
packet
);
...
...
@@ -4092,10 +4161,10 @@ sctp_sackhdr_t *sctp_sm_pull_sack(sctp_chunk_t *chunk)
* error causes.
*/
sctp_packet_t
*
sctp_abort_pkt_new
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
sctp_chunk_t
*
chunk
,
const
void
*
payload
,
size_t
paylen
)
const
sctp_association_t
*
asoc
,
sctp_chunk_t
*
chunk
,
const
void
*
payload
,
size_t
paylen
)
{
sctp_packet_t
*
packet
;
sctp_chunk_t
*
abort
;
...
...
@@ -4128,7 +4197,7 @@ sctp_packet_t *sctp_abort_pkt_new(const sctp_endpoint_t *ep,
/* Allocate a packet for responding in the OOTB conditions. */
sctp_packet_t
*
sctp_ootb_pkt_new
(
const
sctp_association_t
*
asoc
,
const
sctp_chunk_t
*
chunk
)
const
sctp_chunk_t
*
chunk
)
{
sctp_packet_t
*
packet
;
sctp_transport_t
*
transport
;
...
...
@@ -4146,7 +4215,14 @@ sctp_packet_t *sctp_ootb_pkt_new(const sctp_association_t *asoc,
if
(
asoc
)
{
vtag
=
asoc
->
peer
.
i
.
init_tag
;
}
else
{
vtag
=
ntohl
(
chunk
->
sctp_hdr
->
vtag
);
/* Special case the INIT as there is no vtag yet. */
if
(
SCTP_CID_INIT
==
chunk
->
chunk_hdr
->
type
)
{
sctp_init_chunk_t
*
init
;
init
=
(
sctp_init_chunk_t
*
)
&
chunk
->
chunk_hdr
;
vtag
=
ntohl
(
init
->
init_hdr
.
init_tag
);
}
else
{
vtag
=
ntohl
(
chunk
->
sctp_hdr
->
vtag
);
}
}
/* Make a transport for the bucket, Eliza... */
...
...
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