Module Name: src
Committed By: rjs
Date: Thu Aug 2 08:40:48 UTC 2018
Modified Files:
src/distrib/sets/lists/base: shl.mi
src/distrib/sets/lists/comp: mi
src/distrib/sets/lists/debug: shl.mi
src/lib/libc: shlib_version
src/lib/libc/net: Makefile.inc
Added Files:
src/lib/libc/net: sctp_bindx.3 sctp_connectx.3 sctp_freepaddrs.3
sctp_getaddrlen.3 sctp_getassocid.3 sctp_getpaddrs.3
sctp_opt_info.3 sctp_peeloff.3 sctp_send.3 sctp_sendmsg.3
sctp_sys_calls.c
Log Message:
Add userland support for SCTP and manpages.
To generate a diff of this commit:
cvs rdiff -u -r1.843 -r1.844 src/distrib/sets/lists/base/shl.mi
cvs rdiff -u -r1.2214 -r1.2215 src/distrib/sets/lists/comp/mi
cvs rdiff -u -r1.202 -r1.203 src/distrib/sets/lists/debug/shl.mi
cvs rdiff -u -r1.280 -r1.281 src/lib/libc/shlib_version
cvs rdiff -u -r1.87 -r1.88 src/lib/libc/net/Makefile.inc
cvs rdiff -u -r0 -r1.1 src/lib/libc/net/sctp_bindx.3 \
src/lib/libc/net/sctp_connectx.3 src/lib/libc/net/sctp_freepaddrs.3 \
src/lib/libc/net/sctp_getaddrlen.3 src/lib/libc/net/sctp_getassocid.3 \
src/lib/libc/net/sctp_getpaddrs.3 src/lib/libc/net/sctp_opt_info.3 \
src/lib/libc/net/sctp_peeloff.3 src/lib/libc/net/sctp_send.3 \
src/lib/libc/net/sctp_sendmsg.3 src/lib/libc/net/sctp_sys_calls.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/distrib/sets/lists/base/shl.mi
diff -u src/distrib/sets/lists/base/shl.mi:1.843 src/distrib/sets/lists/base/shl.mi:1.844
--- src/distrib/sets/lists/base/shl.mi:1.843 Tue Jul 31 13:04:09 2018
+++ src/distrib/sets/lists/base/shl.mi Thu Aug 2 08:40:47 2018
@@ -1,4 +1,4 @@
-# $NetBSD: shl.mi,v 1.843 2018/07/31 13:04:09 rjs Exp $
+# $NetBSD: shl.mi,v 1.844 2018/08/02 08:40:47 rjs Exp $
#
# Note: Don't delete entries from here - mark them as "obsolete" instead,
# unless otherwise stated below.
@@ -18,7 +18,7 @@
./lib/libblacklist.so.0.0 base-sys-shlib dynamicroot
./lib/libc.so base-sys-shlib dynamicroot
./lib/libc.so.12 base-sys-shlib dynamicroot
-./lib/libc.so.12.210 base-sys-shlib dynamicroot
+./lib/libc.so.12.211 base-sys-shlib dynamicroot
./lib/libcrypt.so base-sys-shlib dynamicroot
./lib/libcrypt.so.1 base-sys-shlib dynamicroot
./lib/libcrypt.so.1.0 base-sys-shlib dynamicroot
@@ -221,7 +221,7 @@
./usr/lib/libc++.so.1.0 base-sys-shlib compatfile,libcxx
./usr/lib/libc.so base-sys-shlib compatfile
./usr/lib/libc.so.12 base-sys-shlib compatfile
-./usr/lib/libc.so.12.210 base-sys-shlib compatfile
+./usr/lib/libc.so.12.211 base-sys-shlib compatfile
./usr/lib/libcdk.so base-obsolete compatfile,obsolete
./usr/lib/libcom_err.so base-krb5-shlib compatfile,kerberos
./usr/lib/libcom_err.so.8 base-krb5-shlib compatfile,kerberos
Index: src/distrib/sets/lists/comp/mi
diff -u src/distrib/sets/lists/comp/mi:1.2214 src/distrib/sets/lists/comp/mi:1.2215
--- src/distrib/sets/lists/comp/mi:1.2214 Tue Jul 31 16:44:28 2018
+++ src/distrib/sets/lists/comp/mi Thu Aug 2 08:40:47 2018
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.2214 2018/07/31 16:44:28 khorben Exp $
+# $NetBSD: mi,v 1.2215 2018/08/02 08:40:47 rjs Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
./etc/mtree/set.comp comp-sys-root
@@ -16992,6 +16992,17 @@
./usr/share/man/html3/scrl.html comp-c-htmlman html
./usr/share/man/html3/scroll.html comp-c-htmlman html
./usr/share/man/html3/scrollok.html comp-c-htmlman html
+./usr/share/man/html3/sctp_bindx.html comp-c-htmlman html
+./usr/share/man/html3/sctp_connectx.html comp-c-htmlman html
+./usr/share/man/html3/sctp_freepaddrs.html comp-c-htmlman html
+./usr/share/man/html3/sctp_getaddrlen.html comp-c-htmlman html
+./usr/share/man/html3/sctp_getassocid.html comp-c-htmlman html
+./usr/share/man/html3/sctp_getpaddrs.html comp-c-htmlman html
+./usr/share/man/html3/sctp_opt_info.html comp-c-htmlman html
+./usr/share/man/html3/sctp_peeloff.html comp-c-htmlman html
+./usr/share/man/html3/sctp_recvmsg.html comp-c-htmlman html
+./usr/share/man/html3/sctp_send.html comp-c-htmlman html
+./usr/share/man/html3/sctp_sendmsg.html comp-c-htmlman html
./usr/share/man/html3/sdp.html comp-c-htmlman html
./usr/share/man/html3/sdp_attr2desc.html comp-obsolete obsolete
./usr/share/man/html3/sdp_change_service.html comp-obsolete obsolete
@@ -24777,6 +24788,17 @@
./usr/share/man/man3/scrl.3 comp-c-man .man
./usr/share/man/man3/scroll.3 comp-c-man .man
./usr/share/man/man3/scrollok.3 comp-c-man .man
+./usr/share/man/man3/sctp_bindx.3 comp-c-man .man
+./usr/share/man/man3/sctp_connectx.3 comp-c-man .man
+./usr/share/man/man3/sctp_freepaddrs.3 comp-c-man .man
+./usr/share/man/man3/sctp_getaddrlen.3 comp-c-man .man
+./usr/share/man/man3/sctp_getassocid.3 comp-c-man .man
+./usr/share/man/man3/sctp_getpaddrs.3 comp-c-man .man
+./usr/share/man/man3/sctp_opt_info.3 comp-c-man .man
+./usr/share/man/man3/sctp_peeloff.3 comp-c-man .man
+./usr/share/man/man3/sctp_recvmsg.3 comp-c-man .man
+./usr/share/man/man3/sctp_send.3 comp-c-man .man
+./usr/share/man/man3/sctp_sendmsg.3 comp-c-man .man
./usr/share/man/man3/sdp.3 comp-c-man .man
./usr/share/man/man3/sdp_attr2desc.3 comp-obsolete obsolete
./usr/share/man/man3/sdp_change_service.3 comp-obsolete obsolete
Index: src/distrib/sets/lists/debug/shl.mi
diff -u src/distrib/sets/lists/debug/shl.mi:1.202 src/distrib/sets/lists/debug/shl.mi:1.203
--- src/distrib/sets/lists/debug/shl.mi:1.202 Tue Jul 31 22:29:55 2018
+++ src/distrib/sets/lists/debug/shl.mi Thu Aug 2 08:40:48 2018
@@ -1,8 +1,8 @@
-# $NetBSD: shl.mi,v 1.202 2018/07/31 22:29:55 kre Exp $
+# $NetBSD: shl.mi,v 1.203 2018/08/02 08:40:48 rjs Exp $
./usr/lib/libbfd_g.a comp-c-debuglib debuglib,compatfile,binutils
./usr/libdata/debug/lib base-sys-usr debug,dynamicroot,compatdir
./usr/libdata/debug/lib/libblacklist.so.0.0.debug comp-sys-debug debug,dynamicroot
-./usr/libdata/debug/lib/libc.so.12.210.debug comp-sys-debug debug,dynamicroot
+./usr/libdata/debug/lib/libc.so.12.211.debug comp-sys-debug debug,dynamicroot
./usr/libdata/debug/lib/libcrypt.so.1.0.debug comp-sys-debug debug,dynamicroot
./usr/libdata/debug/lib/libcrypto.so.12.0.debug comp-sys-debug debug,dynamicroot,openssl=10
./usr/libdata/debug/lib/libcrypto.so.13.0.debug comp-sys-debug debug,dynamicroot,openssl=11
@@ -72,7 +72,7 @@
./usr/libdata/debug/usr/lib/libbsdmalloc.so.0.0.debug comp-sys-debug debug,compatfile
./usr/libdata/debug/usr/lib/libbz2.so.1.1.debug comp-sys-debug debug,compatfile
./usr/libdata/debug/usr/lib/libc++.so.1.0.debug comp-sys-debug debug,compatfile,libcxx
-./usr/libdata/debug/usr/lib/libc.so.12.210.debug comp-sys-debug debug,compatfile
+./usr/libdata/debug/usr/lib/libc.so.12.211.debug comp-sys-debug debug,compatfile
./usr/libdata/debug/usr/lib/libcom_err.so.8.0.debug comp-krb5-debug debug,compatfile,kerberos
./usr/libdata/debug/usr/lib/libcrypt.so.1.0.debug comp-sys-debug debug,compatfile
./usr/libdata/debug/usr/lib/libcrypto.so.12.0.debug comp-crypto-debug debug,compatfile,openssl=10
Index: src/lib/libc/shlib_version
diff -u src/lib/libc/shlib_version:1.280 src/lib/libc/shlib_version:1.281
--- src/lib/libc/shlib_version:1.280 Tue Jul 31 13:04:10 2018
+++ src/lib/libc/shlib_version Thu Aug 2 08:40:48 2018
@@ -1,4 +1,4 @@
-# $NetBSD: shlib_version,v 1.280 2018/07/31 13:04:10 rjs Exp $
+# $NetBSD: shlib_version,v 1.281 2018/08/02 08:40:48 rjs Exp $
# Remember to update distrib/sets/lists/base/shl.* when changing
#
# things we wish to do on next major version bump:
@@ -53,4 +53,4 @@
# - move environ and __ps_strings from crt0.o into libc.
# - move statfs() to libcompat since we have statvfs()
major=12
-minor=210
+minor=211
Index: src/lib/libc/net/Makefile.inc
diff -u src/lib/libc/net/Makefile.inc:1.87 src/lib/libc/net/Makefile.inc:1.88
--- src/lib/libc/net/Makefile.inc:1.87 Sun Jun 18 04:03:44 2017
+++ src/lib/libc/net/Makefile.inc Thu Aug 2 08:40:48 2018
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile.inc,v 1.87 2017/06/18 04:03:44 manu Exp $
+# $NetBSD: Makefile.inc,v 1.88 2018/08/02 08:40:48 rjs Exp $
# @(#)Makefile.inc 8.2 (Berkeley) 9/5/93
# net sources
@@ -13,7 +13,7 @@ SRCS+= base64.c ethers.c gethnamaddr.c g
iso_addr.c linkaddr.c \
nsdispatch.c nslexer.l nsparser.y nsap_addr.c \
rcmd.c recv.c send.c sethostent.c \
- sockatmark.c
+ sctp_sys_calls.c sockatmark.c
.if (${MKHESIOD} != "no")
SRCS+= hesiod.c
@@ -145,3 +145,8 @@ MLINKS+=getaddrinfo.3 freeaddrinfo.3 \
inet6_rth_space.3 inet6_rth_getaddr.3 \
rcmd.3 rcmd_af.3 rcmd.3 iruserok_sa.3 rcmd.3 rresvport_af.3 \
rcmd.3 orcmd_af.3
+
+# SCTP
+MAN+= sctp_bindx.3 sctp_connectx.3 sctp_freepaddrs.3 sctp_getaddrlen.3 \
+ sctp_getassocid.3 sctp_getpaddrs.3 sctp_opt_info.3 sctp_peeloff.3 \
+ sctp_recvmsg.3 sctp_send.3 sctp_sendmsg.3
Added files:
Index: src/lib/libc/net/sctp_bindx.3
diff -u /dev/null src/lib/libc/net/sctp_bindx.3:1.1
--- /dev/null Thu Aug 2 08:40:48 2018
+++ src/lib/libc/net/sctp_bindx.3 Thu Aug 2 08:40:48 2018
@@ -0,0 +1,120 @@
+.\" $NetBSD: sctp_bindx.3,v 1.1 2018/08/02 08:40:48 rjs Exp $
+.\"
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" From: @(#)send.2 8.2 (Berkeley) 2/21/94
+.\"
+.Dd August 1, 2018
+.Dt SCTP_BINDX 3
+.Os
+.Sh NAME
+.Nm sctp_bindx
+.Nd bind or unbind an SCTP socket to a list of addresses.
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/socket.h
+.In netinet/sctp.h
+.Ft int
+.Fn sctp_bindx "int s" "struct sockaddr *addrs" "int num" "int type"
+.Sh DESCRIPTION
+The
+.Fn sctp_bindx
+call binds or unbinds a address or a list of addresses to an
+SCTP endpoint.
+This allows a user to bind a subset of
+addresses.
+The
+.Fn sctp_bindx
+call operates similarly to
+.Fn bind
+but allows a list of addresses and also allows a bind or an
+unbind.
+The argument
+.Fa s
+must be a valid SCTP socket descriptor.
+The argument
+.Fa addrs
+is a list of addresses (where the list may be only 1 in
+length) that the user wishes to bind or unbind to the
+socket.
+The argument
+.Fa type
+must be one of the following values.
+.Pp
+.Dv SCTP_BINDX_ADD_ADDR
+This value indicates that the listed address(es) need to
+be added to the endpoint.
+.Pp
+.Dv SCTP_BINDX_DEL_ADDR
+This value indicates that the listed address(es) need to
+be removed from the endpoint.
+.Pp
+Note that when a user adds or deletes an address to an
+association if the dynamic address flag
+.Va net.inet.sctp.auto_asconf
+is enabled any associations in the endpoint will attempt to
+have the address(es) added dynamically to the existing
+association.
+.Sh RETURN VALUES
+The call returns 0 on success and -1 upon failure.
+.Sh ERRORS
+The
+.Fn sctp_bindx
+function can return the following errors:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+This value is returned if the
+.Fa type
+field is not one of the allowed values (see above).
+.It Bq Er ENOMEM
+This value is returned if the number of addresses
+being added causes a memory allocation failure in
+the call.
+.It Bq Er EBADF
+The argument
+.Fa s
+is not a valid descriptor.
+.It Bq Er ENOTSOCK
+The argument
+.Fa s
+is not a socket.
+.El
+.Sh SEE ALSO
+.Xr bind 2 ,
+.Xr sctp 4
+.Rs
+.%R RFC
+.%N 6458
+.%T "Sockets API Extensions for the Stream Control Transmission Protocol (SCTP)"
+.%D December 2011
+.Re
+.Sh HISTORY
+This function first appeared in
+.Nx 9.0 .
Index: src/lib/libc/net/sctp_connectx.3
diff -u /dev/null src/lib/libc/net/sctp_connectx.3:1.1
--- /dev/null Thu Aug 2 08:40:48 2018
+++ src/lib/libc/net/sctp_connectx.3 Thu Aug 2 08:40:48 2018
@@ -0,0 +1,111 @@
+.\" $NetBSD: sctp_connectx.3,v 1.1 2018/08/02 08:40:48 rjs Exp $
+.\"
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd August 1, 2018
+.Dt SCTP_CONNECTX 3
+.Os
+.Sh NAME
+.Nm sctp_connectx
+.Nd connect an SCTP socket with multiple destination addresses
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/socket.h
+.In netinet/sctp.h
+.Ft int
+.Fn sctp_connectx "int sd" "struct sockaddr *addrs" "int addrcnt" "sctp_assoc_t *id"
+.Sh DESCRIPTION
+The
+.Fn sctp_connectx
+call attempts to initiate an association to a peer SCTP
+endpoint.
+The call operates similarly to
+.Fn connect
+but it also provides the ability to specify multiple destination
+addresses for the peer.
+This allows a fault tolerant method
+of initiating an association.
+When one of the peers addresses
+is unreachable, the subsequent listed addresses will also be used
+to set up the association with the peer.
+.Pp
+The user also needs to consider that any address listed in an
+.Fn sctp_connectx
+call is also considered "confirmed".
+A confirmed address is one in
+which the SCTP transport will trust is a part of the association
+and it will not send a confirmation heartbeat to it with
+a random nonce.
+.Pp
+If the peer SCTP stack does not list one or more of
+the provided addresses in its response message then
+the extra addresses sent in the
+.Fn sctp_connectx
+call will be silently discarded from the association.
+On
+successful completion the provided
+.Fa id
+will be
+filled in with the association identification of the newly
+forming association.
+.Sh RETURN VALUES
+The call returns 0 on success and -1 upon failure.
+.Sh ERRORS
+The
+.Fn sctp_connectx
+function can return the following errors:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+An address listed has an invalid family or no
+addresses were provided.
+.It Bq Er E2BIG
+The size of the address list exceeds the amount of
+data provided.
+.It Bq Er EBADF
+The argument
+.Fa s
+is not a valid descriptor.
+.It Bq Er ENOTSOCK
+The argument
+.Fa s
+is not a socket.
+.El
+.Sh SEE ALSO
+.Xr connect 2 ,
+.Xr sctp 4
+.Rs
+.%R RFC
+.%N 6458
+.%T "Sockets API Extensions for the Stream Control Transmission Protocol (SCTP)"
+.%D December 2011
+.Re
+.Sh HISTORY
+This function first appeared in
+.Nx 9.0 .
Index: src/lib/libc/net/sctp_freepaddrs.3
diff -u /dev/null src/lib/libc/net/sctp_freepaddrs.3:1.1
--- /dev/null Thu Aug 2 08:40:48 2018
+++ src/lib/libc/net/sctp_freepaddrs.3 Thu Aug 2 08:40:48 2018
@@ -0,0 +1,75 @@
+.\" $NetBSD: sctp_freepaddrs.3,v 1.1 2018/08/02 08:40:48 rjs Exp $
+.\"
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" From: @(#)send.2 8.2 (Berkeley) 2/21/94
+.\"
+.Dd August 1, 2018
+.Dt SCTP_FREEPADDRS 3
+.Os
+.Sh NAME
+.Nm sctp_freepaddrs ,
+.Nm sctp_freeladdrs
+.Nd release the memory returned from a previous call
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/socket.h
+.In netinet/sctp.h
+.Ft void
+.Fn sctp_freepaddrs "struct sockaddr *"
+.Ft void
+.Fn sctp_freeladdrs "struct sockaddr *"
+.Sh DESCRIPTION
+The
+.Fn sctp_freepaddrs
+and
+.Fn sctp_freeladdrs
+functions are used to release the memory allocated by previous
+calls to
+.Fn sctp_getpaddrs
+or
+.Fn sctp_getladdrs
+respectively.
+.Sh RETURN VALUES
+none.
+.Sh SEE ALSO
+.Xr sctp_getladdrs 3 ,
+.Xr sctp_getpaddrs 3 ,
+.Xr sctp 4
+.Rs
+.%R RFC
+.%N 6458
+.%T "Sockets API Extensions for the Stream Control Transmission Protocol (SCTP)"
+.%D December 2011
+.Re
+.Sh HISTORY
+These functions first appeared in
+.Nx 9.0 .
+
Index: src/lib/libc/net/sctp_getaddrlen.3
diff -u /dev/null src/lib/libc/net/sctp_getaddrlen.3:1.1
--- /dev/null Thu Aug 2 08:40:48 2018
+++ src/lib/libc/net/sctp_getaddrlen.3 Thu Aug 2 08:40:48 2018
@@ -0,0 +1,93 @@
+.\" $NetBSD: sctp_getaddrlen.3,v 1.1 2018/08/02 08:40:48 rjs Exp $
+.\"
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" From: @(#)send.2 8.2 (Berkeley) 2/21/94
+.\"
+.Dd August 1, 2018
+.Dt SCTP_GETADDRLEN 3
+.Os
+.Sh NAME
+.Nm sctp_getaddrlen
+.Nd return the address length of an address family
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/socket.h
+.In netinet/sctp.h
+.Ft int
+.Fn sctp_getaddrlen "sa_family_t family"
+.Sh DESCRIPTION
+The
+.Fn sctp_getaddrlen
+function returns the size of a specific address family.
+This function
+is provided for application binary compatibility since it
+provides the application with the size the operating system
+thinks the specific address family is.
+Note that the function
+will actually create an SCTP socket and then gather the
+information via a
+.Fn getsockopt
+system calls.
+If for some reason a SCTP socket cannot
+be created or the
+.Fn getsockopt
+call fails, an error will be returned
+with
+.Va errno
+set as specified in the
+.Fn socket
+or
+.Fn getsockopt
+system call.
+.Sh RETURN VALUES
+The call returns the number of bytes that the operating
+system expects for the specific address family or -1.
+.Sh ERRORS
+The
+.Fn sctp_getaddrlen
+function can return the following errors:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The address family specified does NOT exist.
+.El
+.Sh SEE ALSO
+.Xr getsockopt 2 ,
+.Xr socket 2 ,
+.Xr sctp 4
+.Rs
+.%R RFC
+.%N 6458
+.%T "Sockets API Extensions for the Stream Control Transmission Protocol (SCTP)"
+.%D December 2011
+.Re
+.Sh HISTORY
+This function first appeared in
+.Nx 9.0 .
Index: src/lib/libc/net/sctp_getassocid.3
diff -u /dev/null src/lib/libc/net/sctp_getassocid.3:1.1
--- /dev/null Thu Aug 2 08:40:48 2018
+++ src/lib/libc/net/sctp_getassocid.3 Thu Aug 2 08:40:48 2018
@@ -0,0 +1,79 @@
+.\" $NetBSD: sctp_getassocid.3,v 1.1 2018/08/02 08:40:48 rjs Exp $
+.\"
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd August 1, 2018
+.Dt SCTP_GETASSOCID 3
+.Os
+.Sh NAME
+.Nm sctp_getassocid
+.Nd return an association id for a specified socket address.
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/socket.h
+.In netinet/sctp.h
+.Ft sctp_assoc_t
+.Fn sctp_getassocid "int s" "struct sockaddr *addr"
+.Sh DESCRIPTION
+The
+.Fn sctp_getassocid
+call attempts to look up the specified socket address
+.Fa addr
+and find the respective association identification.
+.Sh RETURN VALUES
+The call returns the association id upon success and
+0 is returned upon failure.
+.Sh ERRORS
+The
+.Fn sctp_getassocid
+function can return the following errors:
+.Bl -tag -width Er
+.It Bq Er ENOENT
+The address does not have an association setup to it.
+.It Bq Er EBADF
+The argument
+.Fa s
+is not a valid descriptor.
+.It Bq Er ENOTSOCK
+The argument
+.Fa s
+is not a socket.
+.El
+.Sh SEE ALSO
+.Xr sctp 4
+.Rs
+.%R RFC
+.%N 6458
+.%T "Sockets API Extensions for the Stream Control Transmission Protocol (SCTP)"
+.%D December 2011
+.Re
+.Sh HISTORY
+This function first appeared in
+.Nx 9.0 .
Index: src/lib/libc/net/sctp_getpaddrs.3
diff -u /dev/null src/lib/libc/net/sctp_getpaddrs.3:1.1
--- /dev/null Thu Aug 2 08:40:48 2018
+++ src/lib/libc/net/sctp_getpaddrs.3 Thu Aug 2 08:40:48 2018
@@ -0,0 +1,106 @@
+.\" $NetBSD: sctp_getpaddrs.3,v 1.1 2018/08/02 08:40:48 rjs Exp $
+.\"
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" From: @(#)send.2 8.2 (Berkeley) 2/21/94
+.\"
+.Dd August 1, 2018
+.Dt SCTP_GETPADDRS 3
+.Os
+.Sh NAME
+.Nm sctp_getpaddrs ,
+.Nm sctp_getladdrs
+.Nd return a list of addresses to the caller
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/socket.h
+.In netinet/sctp.h
+.Ft int
+.Fn sctp_getpaddrs "int s" "sctp_assoc_t asocid" "struct sockaddr **addrs"
+.Ft int
+.Fn sctp_getladdrs "int s" "sctp_assoc_t asocid" "struct sockaddr **addrs"
+.Sh DESCRIPTION
+The
+.Fn sctp_getpaddrs
+function is used to get the list of the peers addresses.
+The
+.Fn sctp_getladdrs
+function is used to get the list of the local addresses.
+The association of interest is identified by the
+.Fa asocid
+argument.
+The addresses are returned in a newly allocated
+array of socket addresses returned in the argument
+.Fa addrs
+upon success.
+.Pp
+After the caller is finished, the function
+.Fn sctp_freepaddrs
+or
+.Fn sctp_freeladdrs
+should be used to release the memory allocated by these
+calls.
+.Sh RETURN VALUES
+The call returns -1 upon failure and a count of
+the number of addresses returned in
+.Fa addrs
+upon success.
+.Sh ERRORS
+The functions can return the following errors:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+An address listed has an invalid family or no
+addresses were provided.
+.It Bq Er ENOMEM
+The call cannot allocate memory to hold the
+socket addresses.
+.It Bq Er EBADF
+The argument
+.Fa s
+is not a valid descriptor.
+.It Bq Er ENOTSOCK
+The argument
+.Fa s
+is not a socket.
+.El
+.Sh SEE ALSO
+.Xr getsockopt 2 ,
+.Xr sctp_freeladdrs 3 ,
+.Xr sctp_freepaddrs 3 ,
+.Xr sctp 4
+.Rs
+.%R RFC
+.%N 6458
+.%T "Sockets API Extensions for the Stream Control Transmission Protocol (SCTP)"
+.%D December 2011
+.Re
+.Sh HISTORY
+These functions first appeared in
+.Nx 9.0 .
Index: src/lib/libc/net/sctp_opt_info.3
diff -u /dev/null src/lib/libc/net/sctp_opt_info.3:1.1
--- /dev/null Thu Aug 2 08:40:48 2018
+++ src/lib/libc/net/sctp_opt_info.3 Thu Aug 2 08:40:48 2018
@@ -0,0 +1,129 @@
+.\" $NetBSD: sctp_opt_info.3,v 1.1 2018/08/02 08:40:48 rjs Exp $
+.\"
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" From: @(#)send.2 8.2 (Berkeley) 2/21/94
+.\"
+.Dd August 1, 2018
+.Dt SCTP_OPT_INFO 3
+.Os
+.Sh NAME
+.Nm sctp_opt_info
+.Nd get SCTP socket information
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/socket.h
+.In netinet/sctp.h
+.Ft int
+.Fn sctp_opt_info "int sd" "sctp_assoc_t id" "int opt" "void *arg" "socklen_t *size"
+.Sh DESCRIPTION
+The
+.Fn sctp_opt_info
+call provides a multi-os compatible method for getting
+specific
+.Fn getsockopt
+data where an association identification needs to be passed
+into the operating system.
+For those
+who wish to write portable code amongst multiple operating systems
+this call should be used for the following SCTP
+socket options.
+.Pp
+.Dv SCTP_RTOINFO
+.Pp
+.Dv SCTP_ASSOCINFO
+.Pp
+.Dv SCTP_PRIMARY_ADDR
+.Pp
+.Dv SCTP_PEER_ADDR_PARAMS
+.Pp
+.Dv SCTP_DEFAULT_SEND_PARAM
+.Pp
+.Dv SCTP_MAX_SEG
+.Pp
+.Dv SCTP_AUTH_ACTIVE_KEY
+.Pp
+.Dv SCTP_DELAYED_SACK
+.Pp
+.Dv SCTP_MAX_BURST
+.Pp
+.Dv SCTP_CONTEXT
+.Pp
+.Dv SCTP_EVENT
+.Pp
+.Dv SCTP_DEFAULT_SNDINFO
+.Pp
+.Dv SCTP_DEFAULT_PRINFO
+.Pp
+.Dv SCTP_STATUS
+.Pp
+.Dv SCTP_GET_PEER_ADDR_INFO
+.Pp
+.Dv SCTP_PEER_AUTH_CHUNKS
+.Pp
+.Dv SCTP_LOCAL_AUTH_CHUNKS
+.Sh RETURN VALUES
+The call returns 0 on success and -1 upon error.
+.Sh ERRORS
+The
+.Fn sctp_opt_info
+function can return the following errors:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The argument
+.Fa arg
+value was invalid.
+.It Bq Er EOPNOTSUPP
+The argument
+.Fa opt
+was not one of the above listed SCTP socket
+options.
+.It Bq Er EBADF
+The argument
+.Fa s
+is not a valid descriptor.
+.It Bq Er ENOTSOCK
+The argument
+.Fa s
+is not a socket.
+.El
+.Sh SEE ALSO
+.Xr getsockopt 2 ,
+.Xr getsockopt2 2,
+.Xr sctp 4
+.Rs
+.%R RFC
+.%N 6458
+.%T "Sockets API Extensions for the Stream Control Transmission Protocol (SCTP)"
+.%D December 2011
+.Re
+.Sh HISTORY
+This function first appeared in
+.Nx 9.0 .
Index: src/lib/libc/net/sctp_peeloff.3
diff -u /dev/null src/lib/libc/net/sctp_peeloff.3:1.1
--- /dev/null Thu Aug 2 08:40:48 2018
+++ src/lib/libc/net/sctp_peeloff.3 Thu Aug 2 08:40:48 2018
@@ -0,0 +1,85 @@
+.\" $NetBSD: sctp_peeloff.3,v 1.1 2018/08/02 08:40:48 rjs Exp $
+.\"
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd August 1, 2018
+.Dt SCTP_PEELOFF 3
+.Os
+.Sh NAME
+.Nm sctp_peeloff
+.Nd detach an association from a one-to-many socket to its own fd
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/socket.h
+.In netinet/sctp.h
+.Ft int
+.Fn sctp_peeloff "int s" "sctp_assoc_t id"
+.Sh DESCRIPTION
+The
+.Fn sctp_peeloff
+function attempts detach the association specified by
+.Fa id
+into its own separate socket.
+.Sh RETURN VALUES
+The call returns -1 on failure and the new socket descriptor
+upon success.
+.Sh ERRORS
+The
+.Fn sctp_peeloff
+function can return the following errors:
+.Bl -tag -width Er
+.It Bq Er ENOTCONN
+The
+.Fa id
+given to the call does not map to a valid
+association.
+.It Bq Er E2BIG
+The size of the address list exceeds the amount of
+data provided.
+.It Bq Er EBADF
+The argument
+.Fa s
+is not a valid descriptor.
+.It Bq Er ENOTSOCK
+The argument
+.Fa s
+is not a socket.
+.El
+.Sh SEE ALSO
+.Xr sctp 4
+.Rs
+.%R RFC
+.%N 6458
+.%T "Sockets API Extensions for the Stream Control Transmission Protocol (SCTP)"
+.%D December 2011
+.Re
+.Sh HISTORY
+This function first appeared in
+.Nx 9.0 .
Index: src/lib/libc/net/sctp_send.3
diff -u /dev/null src/lib/libc/net/sctp_send.3:1.1
--- /dev/null Thu Aug 2 08:40:48 2018
+++ src/lib/libc/net/sctp_send.3 Thu Aug 2 08:40:48 2018
@@ -0,0 +1,359 @@
+.\" $NetBSD: sctp_send.3,v 1.1 2018/08/02 08:40:48 rjs Exp $
+.\"
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd August 1, 2018
+.Dt SCTP_SEND 3
+.Os
+.Sh NAME
+.Nm sctp_send ,
+.Nm sctp_sendx
+.Nd send a message from an SCTP socket
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/socket.h
+.In netinet/sctp.h
+.Ft ssize_t
+.Fo sctp_send
+.Fa "int sd" "const void *msg" "size_t len"
+.Fa "const struct sctp_sndrcvinfo *sinfo" "int flags"
+.Fc
+.Ft ssize_t
+.Fo sctp_sendx
+.Fa "int sd" "const void *msg" "size_t len" "struct sockaddr *addrs"
+.Fa "int addrcnt" "const struct sctp_sndrcvinfo *sinfo" "int flags"
+.Fc
+.Sh DESCRIPTION
+The
+.Fn sctp_send
+system call
+is used to transmit a message to another SCTP endpoint.
+.Fn sctp_send
+may be used to send data to an existing association for both
+one-to-many (SOCK_SEQPACKET) and one-to-one (SOCK_STREAM) socket types.
+The length of the message
+.Fa msg
+is given by
+.Fa len .
+If the message is too long to pass atomically through the
+underlying protocol,
+.Va errno
+is set to
+.Er EMSGSIZE ,
+-1 is returned, and
+the message is not transmitted.
+.Pp
+No indication of failure to deliver is implicit in a
+.Fn sctp_send .
+Locally detected errors are indicated by a return value of -1.
+.Pp
+If no space is available at the socket to hold
+the message to be transmitted, then
+.Fn sctp_send
+normally blocks, unless the socket has been placed in
+non-blocking I/O mode.
+The
+.Xr select 2
+system call may be used to determine when it is possible to
+send more data on one-to-one type (SOCK_STREAM) sockets.
+.Pp
+The
+.Fa sinfo
+structure is used to control various SCTP features
+and has the following format:
+.Bd -literal
+struct sctp_sndrcvinfo {
+ uint16_t sinfo_stream; /* Stream sending to */
+ uint16_t sinfo_ssn; /* valid for recv only */
+ uint16_t sinfo_flags; /* flags to control sending */
+ uint32_t sinfo_ppid; /* ppid field */
+ uint32_t sinfo_context; /* context field */
+ uint32_t sinfo_timetolive; /* timetolive for PR-SCTP */
+ uint32_t sinfo_tsn; /* valid for recv only */
+ uint32_t sinfo_cumtsn; /* valid for recv only */
+ sctp_assoc_t sinfo_assoc_id; /* The association id */
+};
+.Ed
+.Pp
+The
+.Fa sinfo->sinfo_ppid
+argument is an opaque 32 bit value that is passed transparently
+through the stack to the peer endpoint. It will be available on
+reception of a message (see
+.Xr sctp_recvmsg 3 ) .
+Note that the stack passes this value without regard to byte
+order.
+.Pp
+The
+.Fa sinfo->sinfo_flags
+argument may include one or more of the following:
+.Bd -literal
+#define SCTP_EOF 0x0100 /* Start a shutdown procedures */
+#define SCTP_ABORT 0x0200 /* Send an ABORT to peer */
+#define SCTP_UNORDERED 0x0400 /* Message is un-ordered */
+#define SCTP_ADDR_OVER 0x0800 /* Override the primary-address */
+#define SCTP_SENDALL 0x1000 /* Send this on all associations */
+ /* for the endpoint */
+/* The lower byte is an enumeration of PR-SCTP policies */
+#define SCTP_PR_SCTP_TTL 0x0001 /* Time based PR-SCTP */
+#define SCTP_PR_SCTP_BUF 0x0002 /* Buffer based PR-SCTP */
+#define SCTP_PR_SCTP_RTX 0x0003 /* Number of retransmissions based PR-SCTP */
+.Ed
+.Pp
+The flag
+.Dv SCTP_EOF
+is used to instruct the SCTP stack to queue this message
+and then start a graceful shutdown of the association.
+All
+remaining data in queue will be sent after which the association
+will be shut down.
+.Pp
+.Dv SCTP_ABORT
+is used to immediately terminate an association.
+An abort
+is sent to the peer and the local TCB is destroyed.
+.Pp
+.Dv SCTP_UNORDERED
+is used to specify that the message being sent has no
+specific order and should be delivered to the peer application
+as soon as possible.
+When this flag is absent messages
+are delivered in order within the stream they are sent, but without
+respect to order to peer streams.
+.Pp
+The flag
+.Dv SCTP_ADDR_OVER
+is used to specify that a specific address should be used.
+Normally
+SCTP will use only one of a multi-homed peers addresses as the primary
+address to send to.
+By default, no matter what the
+.Fa to
+argument is, this primary address is used to send data.
+By specifying
+this flag, the user is asking the stack to ignore the primary address
+and instead use the specified address not only as a lookup mechanism
+to find the association but also as the actual address to send to.
+.Pp
+For a one-to-many type (SOCK_SEQPACKET) socket the flag
+.Dv SCTP_SENDALL
+can be used as a convenient way to make one send call and have
+all associations that are under the socket get a copy of the message.
+Note that this mechanism is quite efficient and makes only one actual
+copy of the data which is shared by all the associations for sending.
+.Pp
+The remaining flags are used for the partial reliability extension (RFC3758)
+and will only be effective if the peer endpoint supports this extension.
+This option specifies what local policy the local endpoint should use
+in skipping data.
+If none of these options are set, then data is
+never skipped over.
+.Pp
+.Dv SCTP_PR_SCTP_TTL
+is used to indicate that a time based lifetime is being applied
+to the data.
+The
+.Fa sinfo->sinfo_timetolive
+argument is then a number of milliseconds for which the data is
+attempted to be transmitted.
+If that many milliseconds elapse
+and the peer has not acknowledged the data, the data will be
+skipped and no longer transmitted.
+Note that this policy does
+not even assure that the data will ever be sent.
+In times of a congestion
+with large amounts of data being queued, the
+.Fa sinfo->sinfo_timetolive
+may expire before the first transmission is ever made.
+.Pp
+The
+.Dv SCTP_PR_SCTP_BUF
+based policy transforms the
+.Fa sinfo->sinfo_timetolive
+field into a total number of bytes allowed on the outbound
+send queue.
+If that number or more bytes are in queue, then
+other buffer-based sends are looked to be removed and
+skipped.
+Note that this policy may also result in the data
+never being sent if no buffer based sends are in queue and
+the maximum specified by
+.Fa timetolive
+bytes is in queue.
+.Pp
+The
+.Dv SCTP_PR_SCTP_RTX
+policy transforms the
+.Fa sinfo->sinfo_timetolive
+into a number of retransmissions to allow.
+This policy
+always assures that at a minimum one send attempt is
+made of the data.
+After which no more than
+.Fa sinfo->sinfo_timetolive
+retransmissions will be made before the data is skipped.
+.Pp
+.Fa sinfo->sinfo_stream
+is the SCTP stream that you wish to send the
+message on.
+Streams in SCTP are reliable (or partially reliable) flows of ordered
+messages.
+.Pp
+The
+.Fa sinfo->sinfo_assoc_id
+field is used to
+select the association to send to on a one-to-many socket.
+For a one-to-one socket, this field is ignored.
+.Pp
+The
+.Fa sinfo->sinfo_context
+field is used only in the event the message cannot be sent.
+This is an opaque
+value that the stack retains and will give to the user when a failed send
+is given if that notification is enabled (see
+.Xr sctp 4 ) .
+Normally a user process can use this value to index some application
+specific data structure when a send cannot be fulfilled.
+.Pp
+The
+.Fa flags
+argument holds the same meaning and values as those found in
+.Xr sendmsg 2
+but is generally ignored by SCTP.
+.Pp
+The fields
+.Fa sinfo->sinfo_ssn ,
+.Fa sinfo->sinfo_tsn ,
+and
+.Fa sinfo->sinfo_cumtsn
+are used only when receiving messages and are thus ignored by
+.Fn sctp_send .
+The function
+.Fn sctp_sendx
+has the same properties as
+.Fn sctp_send
+with the additional arguments of an array of sockaddr structures
+passed in.
+With the
+.Fa addrs
+argument being given as an array of addresses to be sent to and
+the
+.Fa addrcnt
+argument indicating how many socket addresses are in the passed
+in array.
+Note that all of the addresses will only be used
+when an implicit association is being set up.
+This allows the
+user the equivalent behavior as doing a
+.Fn sctp_connectx
+followed by a
+.Fn sctp_send
+to the association.
+Note that if the
+.Fa sinfo->sinfo_assoc_id
+field is 0, then the first address will be used to look up
+the association in place of the association id.
+If both
+an address and an association id are specified, the association
+id has priority.
+.Sh RETURN VALUES
+The call returns the number of characters sent, or -1
+if an error occurred.
+.Sh ERRORS
+The
+.Fn sctp_send
+system call
+fails if:
+.Bl -tag -width Er
+.It Bq Er EBADF
+An invalid descriptor was specified.
+.It Bq Er ENOTSOCK
+The argument
+.Fa s
+is not a socket.
+.It Bq Er EFAULT
+An invalid user space address was specified for an argument.
+.It Bq Er EMSGSIZE
+The socket requires that message be sent atomically,
+and the size of the message to be sent made this impossible.
+.It Bq Er EAGAIN
+The socket is marked non-blocking and the requested operation
+would block.
+.It Bq Er ENOBUFS
+The system was unable to allocate an internal buffer.
+The operation may succeed when buffers become available.
+.It Bq Er ENOBUFS
+The output queue for a network interface was full.
+This generally indicates that the interface has stopped sending,
+but may be caused by transient congestion.
+.It Bq Er EHOSTUNREACH
+The remote host was unreachable.
+.It Bq Er ENOTCONN
+On a one-to-one style socket no association exists.
+.It Bq Er ECONNRESET
+An abort was received by the stack while the user was
+attempting to send data to the peer.
+.It Bq Er ENOENT
+On a one-to-many style socket no address is specified
+so that the association cannot be located or the
+SCTP_ABORT flag was specified on a non-existing association.
+.It Bq Er EPIPE
+The socket is unable to send anymore data
+.Dv ( SBS_CANTSENDMORE
+has been set on the socket).
+This typically means that the socket
+is not connected and is a one-to-one style socket.
+.El
+.Sh SEE ALSO
+.Xr getsockopt 2 ,
+.Xr recv 2 ,
+.Xr select 2 ,
+.Xr sendmsg 2 ,
+.Xr socket 2 ,
+.Xr write 2
+.Xr sctp_connectx 3 ,
+.Xr sctp_recvmsg 3 ,
+.Xr sctp_sendmsg 3 ,
+.Xr sctp 4
+.Rs
+.%R RFC
+.%N 6458
+.%T "Sockets API Extensions for the Stream Control Transmission Protocol (SCTP)"
+.%D December 2011
+.Re
+.Sh HISTORY
+These functions first appeared in
+.Nx 9.0 .
+.Sh BUGS
+Because
+.Fn sctp_send
+may have multiple associations under one endpoint, a
+select on write will only work for a one-to-one style
+socket.
Index: src/lib/libc/net/sctp_sendmsg.3
diff -u /dev/null src/lib/libc/net/sctp_sendmsg.3:1.1
--- /dev/null Thu Aug 2 08:40:48 2018
+++ src/lib/libc/net/sctp_sendmsg.3 Thu Aug 2 08:40:48 2018
@@ -0,0 +1,339 @@
+.\" $NetBSD: sctp_sendmsg.3,v 1.1 2018/08/02 08:40:48 rjs Exp $
+.\"
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" From: @(#)send.2 8.2 (Berkeley) 2/21/94
+.\"
+.Dd August 1, 2018
+.Dt SCTP_SENDMSG 3
+.Os
+.Sh NAME
+.Nm sctp_sendmsg ,
+.Nm sctp_sendmsgx
+.Nd send a message from an SCTP socket
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/socket.h
+.In netinet/sctp.h
+.Ft ssize_t
+.Fo sctp_sendmsg
+.Fa "int s" "const void *msg" "size_t len" "const struct sockaddr *to"
+.Fa "socklen_t tolen" "uint32_t ppid" "uint32_t flags" "uint16_t stream_no"
+.Fa "uint32_t timetolive" "uint32_t context"
+.Fc
+.Ft ssize_t
+.Fo sctp_sendmsgx
+.Fa "int s" "const void *msg" "size_t len" "const struct sockaddr *to"
+.Fa "int addrcnt" "uint32_t ppid" "uint32_t flags" "uint16_t stream_no"
+.Fa "uint32_t timetolive" "uint32_t context"
+.Fc
+.Sh DESCRIPTION
+The
+.Fn sctp_sendmsg
+system call
+is used to transmit a message to another SCTP endpoint.
+The
+.Fn sctp_sendmsg
+may be used at any time.
+If the socket is a one-to-many type (SOCK_SEQPACKET)
+socket then an attempt to send to an address that no association exists to will
+implicitly create a new association.
+Data sent in such an instance will result in
+the data being sent on the third leg of the SCTP four-way handshake.
+Note that if
+the socket is a one-to-one type (SOCK_STREAM) socket then an association must
+be in existence (by use of the
+.Xr connect 2
+system call).
+Calling
+.Fn sctp_sendmsg
+or
+.Fn sctp_sendmsgx
+on a non-connected one-to-one socket will result in
+.Va errno
+being set to
+.Er ENOTCONN ,
+-1 being returned, and the message not being transmitted.
+.Pp
+The address of the target is given by
+.Fa to
+with
+.Fa tolen
+specifying its size.
+The length of the message
+.Fa msg
+is given by
+.Fa len .
+If the message is too long to pass atomically through the
+underlying protocol,
+.Va errno
+is set to
+.Er EMSGSIZE ,
+-1 is returned, and
+the message is not transmitted.
+.Pp
+No indication of failure to deliver is implicit in a
+.Xr sctp_sendmsg 3
+call.
+Locally detected errors are indicated by a return value of -1.
+.Pp
+If no space is available at the socket to hold
+the message to be transmitted, then
+.Xr sctp_sendmsg 3
+normally blocks, unless the socket has been placed in
+non-blocking I/O mode.
+The
+.Xr select 2
+system call may be used to determine when it is possible to
+send more data on one-to-one type (SOCK_STREAM) sockets.
+.Pp
+The
+.Fa ppid
+argument is an opaque 32 bit value that is passed transparently
+through the stack to the peer endpoint.
+It will be available on
+reception of a message (see
+.Xr sctp_recvmsg 3 ) .
+Note that the stack passes this value without regard to byte
+order.
+.Pp
+The
+.Fa flags
+argument may include one or more of the following:
+.Bd -literal
+#define SCTP_EOF 0x0100 /* Start a shutdown procedures */
+#define SCTP_ABORT 0x0200 /* Send an ABORT to peer */
+#define SCTP_UNORDERED 0x0400 /* Message is un-ordered */
+#define SCTP_ADDR_OVER 0x0800 /* Override the primary-address */
+#define SCTP_SENDALL 0x1000 /* Send this on all associations */
+ /* for the endpoint */
+/* The lower byte is an enumeration of PR-SCTP policies */
+#define SCTP_PR_SCTP_TTL 0x0001 /* Time based PR-SCTP */
+#define SCTP_PR_SCTP_BUF 0x0002 /* Buffer based PR-SCTP */
+#define SCTP_PR_SCTP_RTX 0x0003 /* Number of retransmissions based PR-SCTP */
+.Ed
+.Pp
+The flag
+.Dv SCTP_EOF
+is used to instruct the SCTP stack to queue this message
+and then start a graceful shutdown of the association.
+All
+remaining data in queue will be sent after which the association
+will be shut down.
+.Pp
+.Dv SCTP_ABORT
+is used to immediately terminate an association.
+An abort
+is sent to the peer and the local TCB is destroyed.
+.Pp
+.Dv SCTP_UNORDERED
+is used to specify that the message being sent has no
+specific order and should be delivered to the peer application
+as soon as possible.
+When this flag is absent messages
+are delivered in order within the stream they are sent, but without
+respect to order to peer streams.
+.Pp
+The flag
+.Dv SCTP_ADDR_OVER
+is used to specify that an specific address should be used.
+Normally
+SCTP will use only one of a multi-homed peers addresses as the primary
+address to send to.
+By default, no matter what the
+.Fa to
+argument is, this primary address is used to send data.
+By specifying
+this flag, the user is asking the stack to ignore the primary address
+and instead use the specified address not only as a lookup mechanism
+to find the association but also as the actual address to send to.
+.Pp
+For a one-to-many type (SOCK_SEQPACKET) socket the flag
+.Dv SCTP_SENDALL
+can be used as a convenient way to make one send call and have
+all associations that are under the socket get a copy of the message.
+Note that this mechanism is quite efficient and makes only one actual
+copy of the data which is shared by all the associations for sending.
+.Pp
+The remaining flags are used for the partial reliability extension (RFC3758)
+and will only be effective if the peer endpoint supports this extension.
+This option specifies what local policy the local endpoint should use
+in skipping data.
+If none of these options are set, then data is
+never skipped over.
+.Pp
+.Dv SCTP_PR_SCTP_TTL
+is used to indicate that a time based lifetime is being applied
+to the data.
+The
+.Fa timetolive
+argument is then a number of milliseconds for which the data is
+attempted to be transmitted.
+If that many milliseconds elapse
+and the peer has not acknowledged the data, the data will be
+skipped and no longer transmitted.
+Note that this policy does
+not even assure that the data will ever be sent.
+In times of a congestion
+with large amounts of data being queued, the
+.Fa timetolive
+may expire before the first transmission is ever made.
+.Pp
+The
+.Dv SCTP_PR_SCTP_BUF
+based policy transforms the
+.Fa timetolive
+field into a total number of bytes allowed on the outbound
+send queue.
+If that number or more bytes are in queue, then
+other buffer based sends are looked to be removed and
+skipped.
+Note that this policy may also result in the data
+never being sent if no buffer based sends are in queue and
+the maximum specified by
+.Fa timetolive
+bytes is in queue.
+.Pp
+The
+.Dv SCTP_PR_SCTP_RTX
+policy transforms the
+.Fa timetolive
+into a number of retransmissions to allow.
+This policy
+always assures that at a minimum one send attempt is
+made of the data.
+After which no more than
+.Fa timetolive
+retransmissions will be made before the data is skipped.
+.Pp
+.Fa stream_no
+is the SCTP stream that you wish to send the
+message on.
+Streams in SCTP are reliable (or partially reliable) flows of ordered
+messages.
+The
+.Fa context
+field is used only in the event the message cannot be sent.
+This is an opaque
+value that the stack retains and will give to the user when a failed send
+is given if that notification is enabled (see
+.Xr sctp 4 ) .
+Normally a user process can use this value to index some application
+specific data structure when a send cannot be fulfilled.
+.Fn sctp_sendmsgx
+is identical to
+.Fn sctp_sendmsg
+with the exception that it takes an array of sockaddr structures in the
+argument
+.Fa to
+and adds the additional argument
+.Fa addrcnt
+which specifies how many addresses are in the array.
+This allows a
+caller to implicitly set up an association passing multiple addresses
+as if
+.Fn sctp_connectx
+had been called to set up the association.
+.Sh RETURN VALUES
+The call returns the number of characters sent, or -1
+if an error occurred.
+.Sh ERRORS
+The
+.Fn sctp_sendmsg
+system call
+fails if:
+.Bl -tag -width Er
+.It Bq Er EBADF
+An invalid descriptor was specified.
+.It Bq Er ENOTSOCK
+The argument
+.Fa s
+is not a socket.
+.It Bq Er EFAULT
+An invalid user space address was specified for an argument.
+.It Bq Er EMSGSIZE
+The socket requires that message be sent atomically,
+and the size of the message to be sent made this impossible.
+.It Bq Er EAGAIN
+The socket is marked non-blocking and the requested operation
+would block.
+.It Bq Er ENOBUFS
+The system was unable to allocate an internal buffer.
+The operation may succeed when buffers become available.
+.It Bq Er ENOBUFS
+The output queue for a network interface was full.
+This generally indicates that the interface has stopped sending,
+but may be caused by transient congestion.
+.It Bq Er EHOSTUNREACH
+The remote host was unreachable.
+.It Bq Er ENOTCONN
+On a one-to-one style socket no association exists.
+.It Bq Er ECONNRESET
+An abort was received by the stack while the user was
+attempting to send data to the peer.
+.It Bq Er ENOENT
+On a one-to-many style socket no address is specified
+so that the association cannot be located or the
+.Dv SCTP_ABORT
+flag was specified on a non-existing association.
+.It Bq Er EPIPE
+The socket is unable to send anymore data
+.Dv ( SBS_CANTSENDMORE
+has been set on the socket).
+This typically means that the socket
+is not connected and is a one-to-one style socket.
+.El
+.Sh SEE ALSO
+.Xr connect 2 ,
+.Xr getsockopt 2 ,
+.Xr recv 2 ,
+.Xr select 2 ,
+.Xr socket 2 ,
+.Xr write 2 ,
+.Xr sctp_connectx 3 ,
+.Xr sendmsg 2 ,
+.Xr sctp 4
+.Rs
+.%R RFC
+.%N 6458
+.%T "Sockets API Extensions for the Stream Control Transmission Protocol (SCTP)"
+.%D December 2011
+.Re
+.Sh HISTORY
+These functions first appeared in
+.Nx 9.0 .
+.Sh BUGS
+Because in the one-to-many style socket
+.Fn sctp_sendmsg
+or
+.Fn sctp_sendmsgx
+may have multiple associations under one endpoint, a
+select on write will only work for a one-to-one style
+socket.
Index: src/lib/libc/net/sctp_sys_calls.c
diff -u /dev/null src/lib/libc/net/sctp_sys_calls.c:1.1
--- /dev/null Thu Aug 2 08:40:48 2018
+++ src/lib/libc/net/sctp_sys_calls.c Thu Aug 2 08:40:48 2018
@@ -0,0 +1,963 @@
+/* $KAME: sctp_sys_calls.c,v 1.10 2005/03/06 16:04:16 itojun Exp $ */
+/* $NetBSD: sctp_sys_calls.c,v 1.1 2018/08/02 08:40:48 rjs Exp $ */
+
+/*
+ * Copyright (C) 2002, 2003, 2004 Cisco Systems Inc,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/errno.h>
+#include <sys/syscall.h>
+#include <sys/ioctl.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netinet/sctp_uio.h>
+#include <netinet/sctp.h>
+
+#include <net/if_dl.h>
+
+#ifndef IN6_IS_ADDR_V4MAPPED
+#define IN6_IS_ADDR_V4MAPPED(a) \
+ ((*(const u_int32_t *)(const void *)(&(a)->s6_addr[0]) == 0) && \
+ (*(const u_int32_t *)(const void *)(&(a)->s6_addr[4]) == 0) && \
+ (*(const u_int32_t *)(const void *)(&(a)->s6_addr[8]) == ntohl(0x0000ffff)))
+#endif
+
+#define SCTP_CONTROL_VEC_SIZE_RCV 16384
+
+#ifdef SCTP_DEBUG_PRINT_ADDRESS
+static void
+SCTPPrintAnAddress(struct sockaddr *a)
+{
+ char stringToPrint[256];
+ u_short prt;
+ char *srcaddr, *txt;
+
+ if (a == NULL) {
+ printf("NULL\n");
+ return;
+ }
+ if (a->sa_family == AF_INET) {
+ srcaddr = (char *)&((struct sockaddr_in *)a)->sin_addr;
+ txt = "IPv4 Address: ";
+ prt = ntohs(((struct sockaddr_in *)a)->sin_port);
+ } else if (a->sa_family == AF_INET6) {
+ srcaddr = (char *)&((struct sockaddr_in6 *)a)->sin6_addr;
+ prt = ntohs(((struct sockaddr_in6 *)a)->sin6_port);
+ txt = "IPv6 Address: ";
+ } else if (a->sa_family == AF_LINK) {
+ int i;
+ char tbuf[200];
+ u_char adbuf[200];
+ struct sockaddr_dl *dl;
+
+ dl = (struct sockaddr_dl *)a;
+ strncpy(tbuf, dl->sdl_data, dl->sdl_nlen);
+ tbuf[dl->sdl_nlen] = 0;
+ printf("Intf:%s (len:%d)Interface index:%d type:%x(%d) ll-len:%d ",
+ tbuf, dl->sdl_nlen, dl->sdl_index, dl->sdl_type,
+ dl->sdl_type, dl->sdl_alen);
+ memcpy(adbuf, LLADDR(dl), dl->sdl_alen);
+ for (i = 0; i < dl->sdl_alen; i++){
+ printf("%2.2x", adbuf[i]);
+ if (i < (dl->sdl_alen - 1))
+ printf(":");
+ }
+ printf("\n");
+ /* u_short sdl_route[16];*/ /* source routing information */
+ return;
+ } else {
+ return;
+ }
+ if (inet_ntop(a->sa_family, srcaddr, stringToPrint,
+ sizeof(stringToPrint))) {
+ if (a->sa_family == AF_INET6) {
+ printf("%s%s:%d scope:%d\n", txt, stringToPrint, prt,
+ ((struct sockaddr_in6 *)a)->sin6_scope_id);
+ } else {
+ printf("%s%s:%d\n", txt, stringToPrint, prt);
+ }
+
+ } else {
+ printf("%s unprintable?\n", txt);
+ }
+}
+#endif /* SCTP_DEBUG_PRINT_ADDRESS */
+
+void
+in6_sin6_2_sin(struct sockaddr_in *sin, struct sockaddr_in6 *sin6)
+{
+ memset(sin, 0, sizeof(*sin));
+ sin->sin_len = sizeof(struct sockaddr_in);
+ sin->sin_family = AF_INET;
+ sin->sin_port = sin6->sin6_port;
+ sin->sin_addr.s_addr = sin6->sin6_addr.__u6_addr.__u6_addr32[3];
+}
+
+int
+sctp_connectx(int sd, struct sockaddr *addrs, int addrcnt,
+ sctp_assoc_t *id)
+{
+ int i, ret, cnt;
+ struct sockaddr *at;
+ struct sctp_connectx_addrs sca;
+#if 0
+ char *cpto;
+#endif
+ size_t len;
+
+ at = addrs;
+ cnt = 0;
+ len = 0;
+ /* validate all the addresses and get the size */
+ for (i = 0; i < addrcnt; i++) {
+ if (at->sa_family == AF_INET) {
+ len += at->sa_len;
+ } else if (at->sa_family == AF_INET6){
+ if (IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)at)->sin6_addr)){
+ len += sizeof(struct sockaddr_in);
+#if 0
+ in6_sin6_2_sin((struct sockaddr_in *)cpto,
+ (struct sockaddr_in6 *)at);
+ cpto = ((caddr_t)cpto + sizeof(struct sockaddr_in));
+ len += sizeof(struct sockaddr_in);
+#endif
+ } else {
+ len += at->sa_len;
+ }
+ } else {
+ errno = EINVAL;
+ return (-1);
+ }
+ at = (struct sockaddr *)((caddr_t)at + at->sa_len);
+ cnt++;
+ }
+ /* do we have any? */
+ if (cnt == 0) {
+ errno = EINVAL;
+ return(-1);
+ }
+
+ sca.cx_num = cnt;
+ sca.cx_len = len;
+ sca.cx_addrs = addrs;
+ ret = ioctl(sd, SIOCCONNECTX, (void *)&sca);
+ if ((ret == 0) && (id != NULL)) {
+ memcpy(id, &sca.cx_num, sizeof(sctp_assoc_t));
+ }
+ return (ret);
+}
+
+int
+sctp_bindx(int sd, struct sockaddr *addrs, int addrcnt, int flags)
+{
+ struct sctp_getaddresses *gaddrs;
+ struct sockaddr *sa;
+ int i, sz, fam, argsz;
+
+ if ((flags != SCTP_BINDX_ADD_ADDR) &&
+ (flags != SCTP_BINDX_REM_ADDR)) {
+ errno = EFAULT;
+ return(-1);
+ }
+ argsz = (sizeof(struct sockaddr_storage) +
+ sizeof(struct sctp_getaddresses));
+ gaddrs = (struct sctp_getaddresses *)calloc(1, argsz);
+ if (gaddrs == NULL) {
+ errno = ENOMEM;
+ return(-1);
+ }
+ gaddrs->sget_assoc_id = 0;
+ sa = addrs;
+ for (i = 0; i < addrcnt; i++) {
+ sz = sa->sa_len;
+ fam = sa->sa_family;
+ ((struct sockaddr_in *)&addrs[i])->sin_port = ((struct sockaddr_in *)sa)->sin_port;
+ if ((fam != AF_INET) && (fam != AF_INET6)) {
+ errno = EINVAL;
+ return(-1);
+ }
+ memcpy(gaddrs->addr, sa, sz);
+ if (setsockopt(sd, IPPROTO_SCTP, flags, gaddrs,
+ (unsigned int)argsz) != 0) {
+ free(gaddrs);
+ return(-1);
+ }
+ memset(gaddrs, 0, argsz);
+ sa = (struct sockaddr *)((caddr_t)sa + sz);
+ }
+ free(gaddrs);
+ return(0);
+}
+
+
+int
+sctp_opt_info(int sd, sctp_assoc_t id, int opt, void *arg, socklen_t *size)
+{
+ if ((opt == SCTP_RTOINFO) ||
+ (opt == SCTP_ASSOCINFO) ||
+ (opt == SCTP_PRIMARY_ADDR) ||
+ (opt == SCTP_SET_PEER_PRIMARY_ADDR) ||
+ (opt == SCTP_PEER_ADDR_PARAMS) ||
+ (opt == SCTP_STATUS) ||
+ (opt == SCTP_GET_PEER_ADDR_INFO)) {
+ *(sctp_assoc_t *)arg = id;
+ return(getsockopt2(sd, IPPROTO_SCTP, opt, arg, size));
+ } else {
+ errno = EOPNOTSUPP;
+ return(-1);
+ }
+}
+
+int
+sctp_getpaddrs(int sd, sctp_assoc_t id, struct sockaddr **raddrs)
+{
+ struct sctp_getaddresses *addrs;
+ struct sockaddr *sa;
+ struct sockaddr *re;
+ sctp_assoc_t asoc;
+ caddr_t lim;
+ unsigned int siz;
+ int cnt;
+
+ if (raddrs == NULL) {
+ errno = EFAULT;
+ return(-1);
+ }
+ asoc = id;
+ siz = sizeof(sctp_assoc_t);
+ if (getsockopt2(sd, IPPROTO_SCTP, SCTP_GET_REMOTE_ADDR_SIZE,
+ &asoc, &siz) != 0) {
+ return(-1);
+ }
+ siz = (unsigned int)asoc;
+ siz += sizeof(struct sctp_getaddresses);
+ addrs = calloc((unsigned long)1, (unsigned long)siz);
+ if (addrs == NULL) {
+ errno = ENOMEM;
+ return(-1);
+ }
+ memset(addrs, 0, (size_t)siz);
+ addrs->sget_assoc_id = id;
+ /* Now lets get the array of addresses */
+ if (getsockopt2(sd, IPPROTO_SCTP, SCTP_GET_PEER_ADDRESSES,
+ addrs, &siz) != 0) {
+ free(addrs);
+ return(-1);
+ }
+ re = (struct sockaddr *)&addrs->addr[0];
+ *raddrs = re;
+ cnt = 0;
+ sa = (struct sockaddr *)&addrs->addr[0];
+ lim = (caddr_t)addrs + siz;
+ while ((caddr_t)sa < lim) {
+ cnt++;
+ sa = (struct sockaddr *)((caddr_t)sa + sa->sa_len);
+ if (sa->sa_len == 0)
+ break;
+ }
+ return(cnt);
+}
+
+void sctp_freepaddrs(struct sockaddr *addrs)
+{
+ /* Take away the hidden association id */
+ void *fr_addr;
+ fr_addr = (void *)((caddr_t)addrs - sizeof(sctp_assoc_t));
+ /* Now free it */
+ free(fr_addr);
+}
+
+int
+sctp_getladdrs (int sd, sctp_assoc_t id, struct sockaddr **raddrs)
+{
+ struct sctp_getaddresses *addrs;
+ struct sockaddr *re;
+ caddr_t lim;
+ struct sockaddr *sa;
+ int size_of_addresses;
+ unsigned int siz;
+ int cnt;
+
+ if (raddrs == NULL) {
+ errno = EFAULT;
+ return(-1);
+ }
+ size_of_addresses = 0;
+ siz = sizeof(int);
+ if (getsockopt2(sd, IPPROTO_SCTP, SCTP_GET_LOCAL_ADDR_SIZE,
+ &size_of_addresses, &siz) != 0) {
+ return(-1);
+ }
+ if (size_of_addresses == 0) {
+ errno = ENOTCONN;
+ return(-1);
+ }
+ siz = size_of_addresses + sizeof(struct sockaddr_storage);
+ siz += sizeof(struct sctp_getaddresses);
+ addrs = calloc((unsigned long)1, (unsigned long)siz);
+ if (addrs == NULL) {
+ errno = ENOMEM;
+ return(-1);
+ }
+ memset(addrs, 0, (size_t)siz);
+ addrs->sget_assoc_id = id;
+ /* Now lets get the array of addresses */
+ if (getsockopt2(sd, IPPROTO_SCTP, SCTP_GET_LOCAL_ADDRESSES, addrs,
+ &siz) != 0) {
+ free(addrs);
+ return(-1);
+ }
+ re = (struct sockaddr *)&addrs->addr[0];
+ *raddrs = re;
+ cnt = 0;
+ sa = (struct sockaddr *)&addrs->addr[0];
+ lim = (caddr_t)addrs + siz;
+ while ((caddr_t)sa < lim) {
+ cnt++;
+ sa = (struct sockaddr *)((caddr_t)sa + sa->sa_len);
+ if (sa->sa_len == 0)
+ break;
+ }
+ return(cnt);
+}
+
+void sctp_freeladdrs(struct sockaddr *addrs)
+{
+ /* Take away the hidden association id */
+ void *fr_addr;
+ fr_addr = (void *)((caddr_t)addrs - sizeof(sctp_assoc_t));
+ /* Now free it */
+ free(fr_addr);
+}
+
+ssize_t
+sctp_sendmsg(int s,
+ const void *data,
+ size_t len,
+ const struct sockaddr *to,
+ socklen_t tolen __attribute__((unused)),
+ u_int32_t ppid,
+ u_int32_t flags,
+ u_int16_t stream_no,
+ u_int32_t timetolive,
+ u_int32_t context)
+{
+ int sz;
+ struct msghdr msg;
+ struct iovec iov[2];
+ char controlVector[256];
+ struct sctp_sndrcvinfo *s_info;
+ struct cmsghdr *cmsg;
+ struct sockaddr *who=NULL;
+ union {
+ struct sockaddr_in in;
+ struct sockaddr_in6 in6;
+ } addr;
+
+#if 0
+ fprintf(io, "sctp_sendmsg(sd:%d, data:%x, len:%d, to:%x, tolen:%d, ppid:%x, flags:%x str:%d ttl:%d ctx:%x\n",
+ s, (u_int)data, (int)len, (u_int)to, (int)tolen, ppid, flags,
+ (int)stream_no, (int)timetolive, (u_int)context);
+ fflush(io);
+#endif
+ if (to) {
+ if (to->sa_len == 0) {
+ /*
+ * For the lazy app, that did not
+ * set sa_len, we attempt to set for them.
+ */
+ switch (to->sa_family) {
+ case AF_INET:
+ memcpy(&addr, to, sizeof(struct sockaddr_in));
+ addr.in.sin_len = sizeof(struct sockaddr_in);
+ break;
+ case AF_INET6:
+ memcpy(&addr, to, sizeof(struct sockaddr_in6));
+ addr.in6.sin6_len = sizeof(struct sockaddr_in6);
+ break;
+ default:
+ errno = EAFNOSUPPORT;
+ return -1;
+ }
+ } else {
+ memcpy (&addr, to, to->sa_len);
+ }
+ who = (struct sockaddr *)&addr;
+ }
+ iov[0].iov_base = (void *)(unsigned long)data;
+ iov[0].iov_len = len;
+ iov[1].iov_base = NULL;
+ iov[1].iov_len = 0;
+
+ if (to) {
+ msg.msg_name = (caddr_t)who;
+ msg.msg_namelen = who->sa_len;
+ } else {
+ msg.msg_name = (caddr_t)NULL;
+ msg.msg_namelen = 0;
+ }
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = (caddr_t)controlVector;
+
+ cmsg = (struct cmsghdr *)controlVector;
+
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN (sizeof(struct sctp_sndrcvinfo) );
+ s_info = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+
+ s_info->sinfo_stream = stream_no;
+ s_info->sinfo_ssn = 0;
+ s_info->sinfo_flags = flags;
+ s_info->sinfo_ppid = ppid;
+ s_info->sinfo_context = context;
+ s_info->sinfo_assoc_id = 0;
+ s_info->sinfo_timetolive = timetolive;
+ errno = 0;
+ msg.msg_controllen = cmsg->cmsg_len;
+ sz = sendmsg(s, &msg, 0);
+ return(sz);
+}
+
+sctp_assoc_t
+sctp_getassocid(int sd, struct sockaddr *sa)
+{
+ struct sctp_paddrparams sp;
+ socklen_t siz;
+
+ /* First get the assoc id */
+ siz = sizeof(struct sctp_paddrparams);
+ memset(&sp, 0, sizeof(sp));
+ memcpy((caddr_t)&sp.spp_address, sa, sa->sa_len);
+ errno = 0;
+ if (getsockopt2(sd, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, &sp, &siz) != 0)
+ return((sctp_assoc_t)0);
+ /* We depend on the fact that 0 can never be returned */
+ return(sp.spp_assoc_id);
+}
+
+
+
+ssize_t
+sctp_send(int sd, const void *data, size_t len,
+ const struct sctp_sndrcvinfo *sinfo,
+ int flags)
+{
+ int sz;
+ struct msghdr msg;
+ struct iovec iov[2];
+ struct sctp_sndrcvinfo *s_info;
+ char controlVector[256];
+ struct cmsghdr *cmsg;
+
+ iov[0].iov_base = (void *)(unsigned long)data;
+ iov[0].iov_len = len;
+ iov[1].iov_base = NULL;
+ iov[1].iov_len = 0;
+
+ msg.msg_name = 0;
+ msg.msg_namelen = 0;
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = (caddr_t)controlVector;
+
+ cmsg = (struct cmsghdr *)controlVector;
+
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN (sizeof(struct sctp_sndrcvinfo) );
+ s_info = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+ /* copy in the data */
+ *s_info = *sinfo;
+ errno = 0;
+ msg.msg_controllen = cmsg->cmsg_len;
+ sz = sendmsg(sd, &msg, flags);
+ return(sz);
+}
+
+
+ssize_t
+sctp_sendx(int sd, const void *msg, size_t len,
+ struct sockaddr *addrs, int addrcnt,
+ struct sctp_sndrcvinfo *sinfo,
+ int flags)
+{
+ int i, ret, cnt, saved_errno;
+ int add_len;
+ struct sockaddr *at;
+ struct sctp_connectx_addrs sca;
+
+ len = 0;
+ at = addrs;
+ cnt = 0;
+ /* validate all the addresses and get the size */
+ for (i = 0; i < addrcnt; i++) {
+ if (at->sa_family == AF_INET) {
+ add_len = sizeof(struct sockaddr_in);
+ } else if (at->sa_family == AF_INET6) {
+ add_len = sizeof(struct sockaddr_in6);
+ } else {
+ errno = EINVAL;
+ return (-1);
+ }
+ len += add_len;
+ at = (struct sockaddr *)((caddr_t)at + add_len);
+ cnt++;
+ }
+ /* do we have any? */
+ if (cnt == 0) {
+ errno = EINVAL;
+ return(-1);
+ }
+
+ sca.cx_num = cnt;
+ sca.cx_len = len;
+ sca.cx_addrs = addrs;
+ ret = ioctl(sd, SIOCCONNECTXDEL, (void *)&sca);
+ if (ret != 0) {
+ return(ret);
+ }
+ sinfo->sinfo_assoc_id = sctp_getassocid(sd, addrs);
+ if (sinfo->sinfo_assoc_id == 0) {
+ printf("Huh, can't get associd? TSNH!\n");
+ (void)setsockopt(sd, IPPROTO_SCTP, SCTP_CONNECT_X_COMPLETE, (void *)addrs,
+ (unsigned int)addrs->sa_len);
+ errno = ENOENT;
+ return (-1);
+ }
+ ret = sctp_send(sd, msg, len, sinfo, flags);
+ saved_errno = errno;
+ (void)setsockopt(sd, IPPROTO_SCTP, SCTP_CONNECT_X_COMPLETE, (void *)addrs,
+ (unsigned int)addrs->sa_len);
+
+ errno = saved_errno;
+ return (ret);
+}
+
+ssize_t
+sctp_sendmsgx(int sd,
+ const void *msg,
+ size_t len,
+ struct sockaddr *addrs,
+ int addrcnt,
+ u_int32_t ppid,
+ u_int32_t flags,
+ u_int16_t stream_no,
+ u_int32_t timetolive,
+ u_int32_t context)
+{
+ struct sctp_sndrcvinfo sinfo;
+
+ memset((void *) &sinfo, 0, sizeof(struct sctp_sndrcvinfo));
+ sinfo.sinfo_ppid = ppid;
+ sinfo.sinfo_flags = flags;
+ sinfo.sinfo_ssn = stream_no;
+ sinfo.sinfo_timetolive = timetolive;
+ sinfo.sinfo_context = context;
+ return sctp_sendx(sd, msg, len, addrs, addrcnt, &sinfo, 0);
+}
+
+ssize_t
+sctp_recvmsg (int s,
+ void *dbuf,
+ size_t len,
+ struct sockaddr *from,
+ socklen_t *fromlen,
+ struct sctp_sndrcvinfo *sinfo,
+ int *msg_flags)
+{
+ struct sctp_sndrcvinfo *s_info;
+ ssize_t sz;
+ struct msghdr msg;
+ struct iovec iov[2];
+ char controlVector[2048];
+ struct cmsghdr *cmsg;
+ iov[0].iov_base = dbuf;
+ iov[0].iov_len = len;
+ iov[1].iov_base = NULL;
+ iov[1].iov_len = 0;
+ msg.msg_name = (caddr_t)from;
+ msg.msg_namelen = *fromlen;
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = (caddr_t)controlVector;
+ msg.msg_controllen = sizeof(controlVector);
+ errno = 0;
+ sz = recvmsg(s, &msg, 0);
+
+ s_info = NULL;
+ len = sz;
+ *msg_flags = msg.msg_flags;
+ *fromlen = msg.msg_namelen;
+ if ((msg.msg_controllen) && sinfo) {
+ /* parse through and see if we find
+ * the sctp_sndrcvinfo (if the user wants it).
+ */
+ cmsg = (struct cmsghdr *)controlVector;
+ while (cmsg) {
+ if (cmsg->cmsg_level == IPPROTO_SCTP) {
+ if (cmsg->cmsg_type == SCTP_SNDRCV) {
+ /* Got it */
+ s_info = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+ /* Copy it to the user */
+ *sinfo = *s_info;
+ break;
+ }
+ }
+ cmsg = CMSG_NXTHDR(&msg, cmsg);
+ }
+ }
+ return(sz);
+}
+
+ssize_t
+sctp_recvv(int sd,
+ const struct iovec *iov,
+ int iovlen,
+ struct sockaddr *from,
+ socklen_t * fromlen,
+ void *info,
+ socklen_t * infolen,
+ unsigned int *infotype,
+ int *flags)
+{
+ char cmsgbuf[SCTP_CONTROL_VEC_SIZE_RCV];
+ struct msghdr msg;
+ struct cmsghdr *cmsg;
+ ssize_t ret;
+ struct sctp_rcvinfo *rcvinfo;
+ struct sctp_nxtinfo *nxtinfo;
+
+ if (((info != NULL) && (infolen == NULL)) ||
+ ((info == NULL) && (infolen != NULL) && (*infolen != 0)) ||
+ ((info != NULL) && (infotype == NULL))) {
+ errno = EINVAL;
+ return (-1);
+ }
+ if (infotype) {
+ *infotype = SCTP_RECVV_NOINFO;
+ }
+ msg.msg_name = from;
+ if (fromlen == NULL) {
+ msg.msg_namelen = 0;
+ } else {
+ msg.msg_namelen = *fromlen;
+ }
+ msg.msg_iov = __UNCONST(iov);
+ msg.msg_iovlen = iovlen;
+ msg.msg_control = cmsgbuf;
+ msg.msg_controllen = sizeof(cmsgbuf);
+ msg.msg_flags = 0;
+ ret = recvmsg(sd, &msg, *flags);
+ *flags = msg.msg_flags;
+ if ((ret > 0) &&
+ (msg.msg_controllen > 0) &&
+ (infotype != NULL) &&
+ (infolen != NULL) &&
+ (*infolen > 0)) {
+ rcvinfo = NULL;
+ nxtinfo = NULL;
+ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+ if (cmsg->cmsg_level != IPPROTO_SCTP) {
+ continue;
+ }
+ if (cmsg->cmsg_type == SCTP_RCVINFO) {
+ rcvinfo = (struct sctp_rcvinfo *)CMSG_DATA(cmsg);
+ if (nxtinfo != NULL) {
+ break;
+ } else {
+ continue;
+ }
+ }
+ if (cmsg->cmsg_type == SCTP_NXTINFO) {
+ nxtinfo = (struct sctp_nxtinfo *)CMSG_DATA(cmsg);
+ if (rcvinfo != NULL) {
+ break;
+ } else {
+ continue;
+ }
+ }
+ }
+ if (rcvinfo != NULL) {
+ if ((nxtinfo != NULL) && (*infolen >= sizeof(struct sctp_recvv_rn))) {
+ struct sctp_recvv_rn *rn_info;
+
+ rn_info = (struct sctp_recvv_rn *)info;
+ rn_info->recvv_rcvinfo = *rcvinfo;
+ rn_info->recvv_nxtinfo = *nxtinfo;
+ *infolen = (socklen_t) sizeof(struct sctp_recvv_rn);
+ *infotype = SCTP_RECVV_RN;
+ } else if (*infolen >= sizeof(struct sctp_rcvinfo)) {
+ memcpy(info, rcvinfo, sizeof(struct sctp_rcvinfo));
+ *infolen = (socklen_t) sizeof(struct sctp_rcvinfo);
+ *infotype = SCTP_RECVV_RCVINFO;
+ }
+ } else if (nxtinfo != NULL) {
+ if (*infolen >= sizeof(struct sctp_nxtinfo)) {
+ memcpy(info, nxtinfo, sizeof(struct sctp_nxtinfo));
+ *infolen = (socklen_t) sizeof(struct sctp_nxtinfo);
+ *infotype = SCTP_RECVV_NXTINFO;
+ }
+ }
+ }
+ return (ret);
+}
+
+ssize_t
+sctp_sendv(int sd,
+ const struct iovec *iov, int iovcnt,
+ struct sockaddr *addrs, int addrcnt,
+ void *info, socklen_t infolen, unsigned int infotype,
+ int flags)
+{
+ ssize_t ret;
+ int i;
+ socklen_t addr_len;
+ struct msghdr msg;
+ in_port_t port;
+ struct sctp_sendv_spa *spa_info;
+ struct cmsghdr *cmsg;
+ char *cmsgbuf;
+ struct sockaddr *addr;
+ struct sockaddr_in *addr_in;
+ struct sockaddr_in6 *addr_in6;
+ void *assoc_id_ptr;
+ sctp_assoc_t assoc_id;
+
+ if ((addrcnt < 0) ||
+ (iovcnt < 0) ||
+ ((addrs == NULL) && (addrcnt > 0)) ||
+ ((addrs != NULL) && (addrcnt == 0)) ||
+ ((iov == NULL) && (iovcnt > 0)) ||
+ ((iov != NULL) && (iovcnt == 0))) {
+ errno = EINVAL;
+ return (-1);
+ }
+ cmsgbuf = malloc(CMSG_SPACE(sizeof(struct sctp_sndinfo)) +
+ CMSG_SPACE(sizeof(struct sctp_prinfo)) +
+ CMSG_SPACE(sizeof(struct sctp_authinfo)) +
+ (size_t)addrcnt * CMSG_SPACE(sizeof(struct in6_addr)));
+ if (cmsgbuf == NULL) {
+ errno = ENOMEM;
+ return (-1);
+ }
+ assoc_id_ptr = NULL;
+ msg.msg_control = cmsgbuf;
+ msg.msg_controllen = 0;
+ cmsg = (struct cmsghdr *)cmsgbuf;
+ switch (infotype) {
+ case SCTP_SENDV_NOINFO:
+ if ((infolen != 0) || (info != NULL)) {
+ free(cmsgbuf);
+ errno = EINVAL;
+ return (-1);
+ }
+ break;
+ case SCTP_SENDV_SNDINFO:
+ if ((info == NULL) || (infolen < sizeof(struct sctp_sndinfo))) {
+ free(cmsgbuf);
+ errno = EINVAL;
+ return (-1);
+ }
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDINFO;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndinfo));
+ memcpy(CMSG_DATA(cmsg), info, sizeof(struct sctp_sndinfo));
+ msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndinfo));
+ cmsg = (struct cmsghdr *)((caddr_t)cmsg + CMSG_SPACE(sizeof(struct sctp_sndinfo)));
+ assoc_id_ptr = &(((struct sctp_sndinfo *)info)->snd_assoc_id);
+ break;
+ case SCTP_SENDV_PRINFO:
+ if ((info == NULL) || (infolen < sizeof(struct sctp_prinfo))) {
+ free(cmsgbuf);
+ errno = EINVAL;
+ return (-1);
+ }
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_PRINFO;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_prinfo));
+ memcpy(CMSG_DATA(cmsg), info, sizeof(struct sctp_prinfo));
+ msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_prinfo));
+ cmsg = (struct cmsghdr *)((caddr_t)cmsg + CMSG_SPACE(sizeof(struct sctp_prinfo)));
+ break;
+ case SCTP_SENDV_AUTHINFO:
+ if ((info == NULL) || (infolen < sizeof(struct sctp_authinfo))) {
+ free(cmsgbuf);
+ errno = EINVAL;
+ return (-1);
+ }
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_AUTHINFO;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_authinfo));
+ memcpy(CMSG_DATA(cmsg), info, sizeof(struct sctp_authinfo));
+ msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_authinfo));
+ cmsg = (struct cmsghdr *)((caddr_t)cmsg + CMSG_SPACE(sizeof(struct sctp_authinfo)));
+ break;
+ case SCTP_SENDV_SPA:
+ if ((info == NULL) || (infolen < sizeof(struct sctp_sendv_spa))) {
+ free(cmsgbuf);
+ errno = EINVAL;
+ return (-1);
+ }
+ spa_info = (struct sctp_sendv_spa *)info;
+ if (spa_info->sendv_flags & SCTP_SEND_SNDINFO_VALID) {
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDINFO;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndinfo));
+ memcpy(CMSG_DATA(cmsg), &spa_info->sendv_sndinfo, sizeof(struct sctp_sndinfo));
+ msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndinfo));
+ cmsg = (struct cmsghdr *)((caddr_t)cmsg + CMSG_SPACE(sizeof(struct sctp_sndinfo)));
+ assoc_id_ptr = &(spa_info->sendv_sndinfo.snd_assoc_id);
+ }
+ if (spa_info->sendv_flags & SCTP_SEND_PRINFO_VALID) {
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_PRINFO;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_prinfo));
+ memcpy(CMSG_DATA(cmsg), &spa_info->sendv_prinfo, sizeof(struct sctp_prinfo));
+ msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_prinfo));
+ cmsg = (struct cmsghdr *)((caddr_t)cmsg + CMSG_SPACE(sizeof(struct sctp_prinfo)));
+ }
+ if (spa_info->sendv_flags & SCTP_SEND_AUTHINFO_VALID) {
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_AUTHINFO;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_authinfo));
+ memcpy(CMSG_DATA(cmsg), &spa_info->sendv_authinfo, sizeof(struct sctp_authinfo));
+ msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_authinfo));
+ cmsg = (struct cmsghdr *)((caddr_t)cmsg + CMSG_SPACE(sizeof(struct sctp_authinfo)));
+ }
+ break;
+ default:
+ free(cmsgbuf);
+ errno = EINVAL;
+ return (-1);
+ }
+ addr = addrs;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+
+ for (i = 0; i < addrcnt; i++) {
+ switch (addr->sa_family) {
+ case AF_INET:
+ addr_len = (socklen_t) sizeof(struct sockaddr_in);
+ addr_in = (struct sockaddr_in *)addr;
+ if (addr_in->sin_len != addr_len) {
+ free(cmsgbuf);
+ errno = EINVAL;
+ return (-1);
+ }
+ if (i == 0) {
+ port = addr_in->sin_port;
+ } else {
+ if (port == addr_in->sin_port) {
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_DSTADDRV4;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
+ memcpy(CMSG_DATA(cmsg), &addr_in->sin_addr, sizeof(struct in_addr));
+ msg.msg_controllen += CMSG_SPACE(sizeof(struct in_addr));
+ cmsg = (struct cmsghdr *)((caddr_t)cmsg + CMSG_SPACE(sizeof(struct in_addr)));
+ } else {
+ free(cmsgbuf);
+ errno = EINVAL;
+ return (-1);
+ }
+ }
+ break;
+ case AF_INET6:
+ addr_len = (socklen_t) sizeof(struct sockaddr_in6);
+ addr_in6 = (struct sockaddr_in6 *)addr;
+ if (addr_in6->sin6_len != addr_len) {
+ free(cmsgbuf);
+ errno = EINVAL;
+ return (-1);
+ }
+ if (i == 0) {
+ port = addr_in6->sin6_port;
+ } else {
+ if (port == addr_in6->sin6_port) {
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_DSTADDRV6;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_addr));
+ memcpy(CMSG_DATA(cmsg), &addr_in6->sin6_addr, sizeof(struct in6_addr));
+ msg.msg_controllen += CMSG_SPACE(sizeof(struct in6_addr));
+ cmsg = (struct cmsghdr *)((caddr_t)cmsg + CMSG_SPACE(sizeof(struct in6_addr)));
+ } else {
+ free(cmsgbuf);
+ errno = EINVAL;
+ return (-1);
+ }
+ }
+ break;
+ default:
+ free(cmsgbuf);
+ errno = EINVAL;
+ return (-1);
+ }
+ if (i == 0) {
+ msg.msg_name = addr;
+ msg.msg_namelen = addr_len;
+ }
+ addr = (struct sockaddr *)((caddr_t)addr + addr_len);
+ }
+ if (msg.msg_controllen == 0) {
+ msg.msg_control = NULL;
+ }
+ msg.msg_iov = __UNCONST(iov);
+ msg.msg_iovlen = iovcnt;
+ msg.msg_flags = 0;
+ ret = sendmsg(sd, &msg, flags);
+ free(cmsgbuf);
+ if ((ret >= 0) && (addrs != NULL) && (assoc_id_ptr != NULL)) {
+ assoc_id = sctp_getassocid(sd, addrs);
+ memcpy(assoc_id_ptr, &assoc_id, sizeof(assoc_id));
+ }
+ return (ret);
+}
+
+int
+sctp_peeloff(int sd, sctp_assoc_t assoc_id)
+{
+ int ret;
+ uint32_t val;
+
+ val = assoc_id;
+ ret = ioctl(sd, SIOCPEELOFF, &val);
+ if (ret == -1)
+ return ret;
+ else
+ return (int) val;
+}
+