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
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