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
f8dfb3b0
Commit
f8dfb3b0
authored
Nov 08, 2002
by
Jon Grimm
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[SCTP] Addr family cleanup part 2. (jgrimm)
Splitting out yet more code. New af and pf specific functions.
parent
d9a91e70
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
195 additions
and
208 deletions
+195
-208
include/net/sctp/structs.h
include/net/sctp/structs.h
+7
-4
net/sctp/bind_addr.c
net/sctp/bind_addr.c
+8
-107
net/sctp/input.c
net/sctp/input.c
+2
-2
net/sctp/ipv6.c
net/sctp/ipv6.c
+74
-5
net/sctp/protocol.c
net/sctp/protocol.c
+82
-27
net/sctp/sm_make_chunk.c
net/sctp/sm_make_chunk.c
+4
-40
net/sctp/socket.c
net/sctp/socket.c
+18
-23
No files found.
include/net/sctp/structs.h
View file @
f8dfb3b0
...
...
@@ -2,7 +2,7 @@
* Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
* Copyright (c) 2001 Intel Corp.
* Copyright (c) 2001 International Business Machines Corp.
* Copyright (c) 2001
-2002
International Business Machines Corp.
*
* This file is part of the SCTP kernel reference Implementation
*
...
...
@@ -257,6 +257,8 @@ typedef struct sctp_func {
void
(
*
from_skb
)
(
union
sctp_addr
*
,
struct
sk_buff
*
skb
,
int
saddr
);
int
(
*
addr_valid
)
(
union
sctp_addr
*
);
sctp_scope_t
(
*
scope
)
(
union
sctp_addr
*
);
__u16
net_header_len
;
int
sockaddr_len
;
sa_family_t
sa_family
;
...
...
@@ -269,6 +271,7 @@ sctp_func_t *sctp_get_af_specific(sa_family_t);
typedef
struct
sctp_pf
{
void
(
*
event_msgname
)(
sctp_ulpevent_t
*
,
char
*
,
int
*
);
void
(
*
skb_msgname
)(
struct
sk_buff
*
,
char
*
,
int
*
);
int
(
*
af_supported
)(
sa_family_t
);
}
sctp_pf_t
;
/* SCTP Socket type: UDP or TCP style. */
...
...
@@ -505,7 +508,7 @@ void *sctp_addto_chunk(sctp_chunk_t *chunk, int len, const void *data);
int
sctp_user_addto_chunk
(
sctp_chunk_t
*
chunk
,
int
len
,
struct
iovec
*
data
);
sctp_chunk_t
*
sctp_chunkify
(
struct
sk_buff
*
,
const
sctp_association_t
*
,
struct
sock
*
);
void
sctp_init_addrs
(
sctp_chunk_t
*
chunk
);
void
sctp_init_addrs
(
sctp_chunk_t
*
,
union
sctp_addr
*
,
union
sctp_addr
*
);
const
union
sctp_addr
*
sctp_source
(
const
sctp_chunk_t
*
chunk
);
/* This is a structure for holding either an IPv6 or an IPv4 address. */
...
...
net/sctp/bind_addr.c
View file @
f8dfb3b0
/* SCTP kernel reference Implementation
* Copyright (c) Cisco 1999,2000
* Copyright (c) Motorola 1999,2000,2001
* Copyright (c) International Business Machines Corp., 2001
* Copyright (c) International Business Machines Corp., 2001
,2002
* Copyright (c) La Monte H.P. Yarroll 2001
*
* This file is part of the SCTP kernel reference implementation.
...
...
@@ -422,110 +422,11 @@ int sctp_in_scope(const union sctp_addr *addr, sctp_scope_t scope)
/* What is the scope of 'addr'? */
sctp_scope_t
sctp_scope
(
const
union
sctp_addr
*
addr
)
{
s
ctp_scope_t
retval
=
SCTP_SCOPE_GLOBAL
;
s
truct
sctp_func
*
af
;
switch
(
addr
->
sa
.
sa_family
)
{
case
AF_INET
:
/* We are checking the loopback, private and other address
* scopes as defined in RFC 1918.
* The IPv4 scoping is based on the draft for SCTP IPv4
* scoping <draft-stewart-tsvwg-sctp-ipv4-00.txt>.
* The set of SCTP address scope hopefully can cover both
* types of addresses.
*/
/* Should IPv4 scoping be a sysctl configurable option
* so users can turn it off (default on) for certain
* unconventional networking environments?
*/
/* Check for unusable SCTP addresses. */
if
(
IS_IPV4_UNUSABLE_ADDRESS
(
&
addr
->
v4
.
sin_addr
.
s_addr
))
{
retval
=
SCTP_SCOPE_UNUSABLE
;
}
else
if
(
LOOPBACK
(
addr
->
v4
.
sin_addr
.
s_addr
))
{
retval
=
SCTP_SCOPE_LOOPBACK
;
}
else
if
(
IS_IPV4_LINK_ADDRESS
(
&
addr
->
v4
.
sin_addr
.
s_addr
))
{
retval
=
SCTP_SCOPE_LINK
;
}
else
if
(
IS_IPV4_PRIVATE_ADDRESS
(
&
addr
->
v4
.
sin_addr
.
s_addr
))
{
retval
=
SCTP_SCOPE_PRIVATE
;
}
else
{
retval
=
SCTP_SCOPE_GLOBAL
;
}
break
;
case
AF_INET6
:
{
SCTP_V6
(
int
v6scope
;
v6scope
=
ipv6_addr_scope
((
struct
in6_addr
*
)
&
addr
->
v6
.
sin6_addr
);
/* The IPv6 scope is really a set of bit
* fields. See IFA_* in <net/if_inet6.h>.
* Mapping them to the generic SCTP scope
* set is an attempt to have code
* consistencies with the IPv4 scoping.
*/
switch
(
v6scope
)
{
case
IFA_HOST
:
retval
=
SCTP_SCOPE_LOOPBACK
;
break
;
case
IFA_LINK
:
retval
=
SCTP_SCOPE_LINK
;
break
;
case
IFA_SITE
:
retval
=
SCTP_SCOPE_PRIVATE
;
break
;
default:
retval
=
SCTP_SCOPE_GLOBAL
;
break
;
};
);
break
;
}
default:
retval
=
SCTP_SCOPE_GLOBAL
;
break
;
};
af
=
sctp_get_af_specific
(
addr
->
sa
.
sa_family
);
if
(
!
af
)
return
SCTP_SCOPE_UNUSABLE
;
return
retval
;
}
/* This function checks if the address is a valid address to be used for
* SCTP.
*
* Output:
* Return 0 - If the address is a non-unicast or an illegal address.
* Return 1 - If the address is a unicast.
*/
int
sctp_addr_is_valid
(
const
union
sctp_addr
*
addr
)
{
unsigned
short
sa_family
=
addr
->
sa
.
sa_family
;
switch
(
sa_family
)
{
case
AF_INET
:
/* Is this a non-unicast address or a unusable SCTP address? */
if
(
IS_IPV4_UNUSABLE_ADDRESS
(
&
addr
->
v4
.
sin_addr
.
s_addr
))
return
0
;
break
;
case
AF_INET6
:
SCTP_V6
(
{
int
ret
=
sctp_ipv6_addr_type
(
&
addr
->
v6
.
sin6_addr
);
/* Is this a non-unicast address */
if
(
!
(
ret
&
IPV6_ADDR_UNICAST
))
return
0
;
break
;
});
default:
return
0
;
};
return
1
;
return
af
->
scope
((
union
sctp_addr
*
)
addr
);
}
net/sctp/input.c
View file @
f8dfb3b0
...
...
@@ -132,7 +132,7 @@ int sctp_rcv(struct sk_buff *skb)
* IP broadcast addresses cannot be used in an SCTP transport
* address."
*/
if
(
!
sctp_addr_is_valid
(
&
src
)
||
!
sctp_addr_is
_valid
(
&
dest
))
if
(
!
af
->
addr_valid
(
&
src
)
||
!
af
->
addr
_valid
(
&
dest
))
goto
discard_it
;
asoc
=
__sctp_rcv_lookup
(
skb
,
&
src
,
&
dest
,
&
transport
);
...
...
@@ -172,7 +172,7 @@ int sctp_rcv(struct sk_buff *skb)
chunk
->
sctp_hdr
=
sh
;
/* Set the source and destination addresses of the incoming chunk. */
sctp_init_addrs
(
chunk
);
sctp_init_addrs
(
chunk
,
&
src
,
&
dest
);
/* Remember where we came from. */
chunk
->
transport
=
transport
;
...
...
net/sctp/ipv6.c
View file @
f8dfb3b0
...
...
@@ -262,13 +262,62 @@ static void sctp_v6_from_skb(union sctp_addr *addr,struct sk_buff *skb,
}
/* Check if the dst entry's source addr matches the given source addr. */
int
sctp_v6_cmp_saddr
(
struct
dst_entry
*
dst
,
union
sctp_addr
*
saddr
)
static
int
sctp_v6_cmp_saddr
(
struct
dst_entry
*
dst
,
union
sctp_addr
*
saddr
)
{
struct
rt6_info
*
rt
=
(
struct
rt6_info
*
)
dst
;
return
ipv6_addr_cmp
(
&
rt
->
rt6i_src
.
addr
,
&
saddr
->
v6
.
sin6_addr
);
}
/* This function checks if the address is a valid address to be used for
* SCTP.
*
* Output:
* Return 0 - If the address is a non-unicast or an illegal address.
* Return 1 - If the address is a unicast.
*/
static
int
sctp_v6_addr_valid
(
union
sctp_addr
*
addr
)
{
int
ret
=
sctp_ipv6_addr_type
(
&
addr
->
v6
.
sin6_addr
);
/* FIXME: v4-mapped-v6 address support. */
/* Is this a non-unicast address */
if
(
!
(
ret
&
IPV6_ADDR_UNICAST
))
return
0
;
return
1
;
}
/* What is the scope of 'addr'? */
static
sctp_scope_t
sctp_v6_scope
(
union
sctp_addr
*
addr
)
{
int
v6scope
;
sctp_scope_t
retval
;
/* The IPv6 scope is really a set of bit fields.
* See IFA_* in <net/if_inet6.h>. Map to a generic SCTP scope.
*/
v6scope
=
ipv6_addr_scope
(
&
addr
->
v6
.
sin6_addr
);
switch
(
v6scope
)
{
case
IFA_HOST
:
retval
=
SCTP_SCOPE_LOOPBACK
;
break
;
case
IFA_LINK
:
retval
=
SCTP_SCOPE_LINK
;
break
;
case
IFA_SITE
:
retval
=
SCTP_SCOPE_PRIVATE
;
break
;
default:
retval
=
SCTP_SCOPE_GLOBAL
;
break
;
};
return
retval
;
}
/* Initialize a PF_INET6 socket msg_name. */
static
void
sctp_inet6_msgname
(
char
*
msgname
,
int
*
addr_len
)
{
...
...
@@ -344,6 +393,23 @@ static void sctp_inet6_skb_msgname(struct sk_buff *skb, char *msgname,
}
}
/* Do we support this AF? */
static
int
sctp_inet6_af_supported
(
sa_family_t
family
)
{
/* FIXME: v4-mapped-v6 addresses. The I-D is still waffling
* on what to do with sockaddr formats for PF_INET6 sockets.
* For now assume we'll support both.
*/
switch
(
family
)
{
case
AF_INET6
:
case
AF_INET
:
return
1
;
default:
return
0
;
}
}
static
struct
proto_ops
inet6_seqpacket_ops
=
{
.
family
=
PF_INET6
,
.
release
=
inet6_release
,
...
...
@@ -386,6 +452,8 @@ static sctp_func_t sctp_ipv6_specific = {
.
copy_addrlist
=
sctp_v6_copy_addrlist
,
.
from_skb
=
sctp_v6_from_skb
,
.
cmp_saddr
=
sctp_v6_cmp_saddr
,
.
scope
=
sctp_v6_scope
,
.
addr_valid
=
sctp_v6_addr_valid
,
.
net_header_len
=
sizeof
(
struct
ipv6hdr
),
.
sockaddr_len
=
sizeof
(
struct
sockaddr_in6
),
.
sa_family
=
AF_INET6
,
...
...
@@ -394,6 +462,7 @@ static sctp_func_t sctp_ipv6_specific = {
static
sctp_pf_t
sctp_pf_inet6_specific
=
{
.
event_msgname
=
sctp_inet6_event_msgname
,
.
skb_msgname
=
sctp_inet6_skb_msgname
,
.
af_supported
=
sctp_inet6_af_supported
,
};
/* Initialize IPv6 support and register with inet6 stack. */
...
...
net/sctp/protocol.c
View file @
f8dfb3b0
...
...
@@ -283,6 +283,51 @@ int sctp_v4_cmp_saddr(struct dst_entry *dst, union sctp_addr *saddr)
return
(
rt
->
rt_src
==
saddr
->
v4
.
sin_addr
.
s_addr
);
}
/* This function checks if the address is a valid address to be used for
* SCTP.
*
* Output:
* Return 0 - If the address is a non-unicast or an illegal address.
* Return 1 - If the address is a unicast.
*/
static
int
sctp_v4_addr_valid
(
union
sctp_addr
*
addr
)
{
/* Is this a non-unicast address or a unusable SCTP address? */
if
(
IS_IPV4_UNUSABLE_ADDRESS
(
&
addr
->
v4
.
sin_addr
.
s_addr
))
return
0
;
return
1
;
}
/* Checking the loopback, private and other address scopes as defined in
* RFC 1918. The IPv4 scoping is based on the draft for SCTP IPv4
* scoping <draft-stewart-tsvwg-sctp-ipv4-00.txt>.
*/
static
sctp_scope_t
sctp_v4_scope
(
union
sctp_addr
*
addr
)
{
sctp_scope_t
retval
;
/* Should IPv4 scoping be a sysctl configurable option
* so users can turn it off (default on) for certain
* unconventional networking environments?
*/
/* Check for unusable SCTP addresses. */
if
(
IS_IPV4_UNUSABLE_ADDRESS
(
&
addr
->
v4
.
sin_addr
.
s_addr
))
{
retval
=
SCTP_SCOPE_UNUSABLE
;
}
else
if
(
LOOPBACK
(
addr
->
v4
.
sin_addr
.
s_addr
))
{
retval
=
SCTP_SCOPE_LOOPBACK
;
}
else
if
(
IS_IPV4_LINK_ADDRESS
(
&
addr
->
v4
.
sin_addr
.
s_addr
))
{
retval
=
SCTP_SCOPE_LINK
;
}
else
if
(
IS_IPV4_PRIVATE_ADDRESS
(
&
addr
->
v4
.
sin_addr
.
s_addr
))
{
retval
=
SCTP_SCOPE_PRIVATE
;
}
else
{
retval
=
SCTP_SCOPE_GLOBAL
;
}
return
retval
;
}
/* Event handler for inet device events.
* Basically, whenever there is an event, we re-build our local address list.
*/
...
...
@@ -374,13 +419,13 @@ static void sctp_inet_event_msgname(sctp_ulpevent_t *event, char *msgname, int *
}
/* Initialize and copy out a msgname from an inbound skb. */
static
void
sctp_inet_skb_msgname
(
struct
sk_buff
*
skb
,
char
*
msgname
,
int
*
addr_
len
)
static
void
sctp_inet_skb_msgname
(
struct
sk_buff
*
skb
,
char
*
msgname
,
int
*
len
)
{
struct
sctphdr
*
sh
;
struct
sockaddr_in
*
sin
;
if
(
msgname
)
{
sctp_inet_msgname
(
msgname
,
addr_
len
);
sctp_inet_msgname
(
msgname
,
len
);
sin
=
(
struct
sockaddr_in
*
)
msgname
;
sh
=
(
struct
sctphdr
*
)
skb
->
h
.
raw
;
sin
->
sin_port
=
sh
->
source
;
...
...
@@ -388,9 +433,17 @@ static void sctp_inet_skb_msgname(struct sk_buff *skb, char *msgname, int *addr_
}
}
/* Do we support this AF? */
static
int
sctp_inet_af_supported
(
sa_family_t
family
)
{
/* PF_INET only supports AF_INET addresses. */
return
(
AF_INET
==
family
);
}
static
sctp_pf_t
sctp_pf_inet
=
{
.
event_msgname
=
sctp_inet_event_msgname
,
.
skb_msgname
=
sctp_inet_skb_msgname
,
.
af_supported
=
sctp_inet_af_supported
,
};
...
...
@@ -446,6 +499,8 @@ struct sctp_func sctp_ipv4_specific = {
.
copy_addrlist
=
sctp_v4_copy_addrlist
,
.
from_skb
=
sctp_v4_from_skb
,
.
cmp_saddr
=
sctp_v4_cmp_saddr
,
.
addr_valid
=
sctp_v4_addr_valid
,
.
scope
=
sctp_v4_scope
,
.
net_header_len
=
sizeof
(
struct
iphdr
),
.
sockaddr_len
=
sizeof
(
struct
sockaddr_in
),
.
sa_family
=
AF_INET
,
...
...
net/sctp/sm_make_chunk.c
View file @
f8dfb3b0
...
...
@@ -1031,47 +1031,11 @@ sctp_chunk_t *sctp_chunkify(struct sk_buff *skb, const sctp_association_t *asoc,
}
/* Set chunk->source and dest based on the IP header in chunk->skb. */
void
sctp_init_addrs
(
sctp_chunk_t
*
chunk
)
void
sctp_init_addrs
(
sctp_chunk_t
*
chunk
,
union
sctp_addr
*
src
,
union
sctp_addr
*
dest
)
{
union
sctp_addr
*
source
,
*
dest
;
struct
sk_buff
*
skb
;
struct
sctphdr
*
sh
;
struct
iphdr
*
ih4
;
struct
ipv6hdr
*
ih6
;
source
=
&
chunk
->
source
;
dest
=
&
chunk
->
dest
;
skb
=
chunk
->
skb
;
ih4
=
skb
->
nh
.
iph
;
ih6
=
skb
->
nh
.
ipv6h
;
sh
=
chunk
->
sctp_hdr
;
switch
(
ih4
->
version
)
{
case
4
:
source
->
v4
.
sin_family
=
AF_INET
;
source
->
v4
.
sin_port
=
ntohs
(
sh
->
source
);
source
->
v4
.
sin_addr
.
s_addr
=
ih4
->
saddr
;
dest
->
v4
.
sin_family
=
AF_INET
;
dest
->
v4
.
sin_port
=
ntohs
(
sh
->
dest
);
dest
->
v4
.
sin_addr
.
s_addr
=
ih4
->
daddr
;
break
;
case
6
:
SCTP_V6
(
source
->
v6
.
sin6_family
=
AF_INET6
;
source
->
v6
.
sin6_port
=
ntohs
(
sh
->
source
);
source
->
v6
.
sin6_addr
=
ih6
->
saddr
;
dest
->
v6
.
sin6_family
=
AF_INET6
;
dest
->
v6
.
sin6_port
=
ntohs
(
sh
->
dest
);
dest
->
v6
.
sin6_addr
=
ih6
->
daddr
;
/* FIXME: What do we do with scope, etc. ? */
break
;
)
default:
/* This is a bogus address type, just bail. */
break
;
};
memcpy
(
&
chunk
->
source
,
src
,
sizeof
(
union
sctp_addr
));
memcpy
(
&
chunk
->
dest
,
dest
,
sizeof
(
union
sctp_addr
));
}
/* Extract the source address from a chunk. */
...
...
net/sctp/socket.c
View file @
f8dfb3b0
...
...
@@ -2691,35 +2691,30 @@ static struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags, int no
return
NULL
;
}
static
inline
int
sctp_verify_addr
(
struct
sock
*
sk
,
struct
sockaddr
*
addr
,
int
addrlen
)
/* Verify that this is a valid address. */
static
int
sctp_verify_addr
(
struct
sock
*
sk
,
struct
sockaddr
*
addr
,
int
len
)
{
union
sctp_addr
*
sa
;
struct
sctp_func
*
af
;
if
(
addrlen
<
sizeof
(
struct
sockaddr
))
/* Check minimum size. */
if
(
len
<
sizeof
(
struct
sockaddr
))
return
-
EINVAL
;
sa
=
(
union
sctp_addr
*
)
addr
;
switch
(
sa
->
sa
.
sa_family
)
{
case
AF_INET
:
if
(
addrlen
<
sizeof
(
struct
sockaddr_in
))
/* Do we support this address family in general? */
af
=
sctp_get_af_specific
(
addr
->
sa_family
);
if
(
!
af
)
return
-
EINVAL
;
break
;
case
AF_INET6
:
if
(
PF_INET
==
sk
->
family
)
return
-
EINVAL
;
SCTP_V6
(
if
(
addrlen
<
sizeof
(
struct
sockaddr_in6
))
/* Does this PF support this AF? */
if
(
!
sctp_sk
(
sk
)
->
pf
->
af_supported
(
addr
->
sa_family
))
return
-
EINVAL
;
break
;
);
default:
/* Verify the minimum for this AF sockaddr. */
if
(
len
<
af
->
sockaddr_len
)
return
-
EINVAL
;
};
/*
Disallow any illegal addresses to be used as destinations.
*/
if
(
!
sctp_addr_is_valid
(
sa
))
/*
Is this a valid SCTP address?
*/
if
(
!
af
->
addr_valid
((
union
sctp_addr
*
)
addr
))
return
-
EINVAL
;
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