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
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
Show 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
...
...
@@ -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
,
para
m
,
asoc
->
peer
.
port
);
addrparm
=
(
sctp_addr_param_t
*
)
param
.
v
;
sctp_param2sockaddr
(
&
addr
,
addrpar
m
,
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
)
{
/* Rethink this as we may need to keep for
* restart considerations.
*/
if
(
PF_INET6
==
asoc
->
base
.
sk
->
family
)
{
sctp_param2sockaddr
(
&
addr
,
param
,
asoc
->
peer
.
port
);
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
);
}
sctp_assoc_add_peer
(
asoc
,
&
addr
,
priority
);
}
break
;
...
...
@@ -1833,7 +1833,6 @@ __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
;
get_random_bytes
(
&
retval
,
sizeof
(
__u32
));
...
...
@@ -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,59 +1339,13 @@ 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
...
...
@@ -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
;
}
...
...
@@ -4145,9 +4214,16 @@ sctp_packet_t *sctp_ootb_pkt_new(const sctp_association_t *asoc,
*/
if
(
asoc
)
{
vtag
=
asoc
->
peer
.
i
.
init_tag
;
}
else
{
/* 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... */
transport
=
sctp_transport_new
(
sctp_source
(
chunk
),
GFP_ATOMIC
);
...
...
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