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; +} +