Add core networking support for SCTP.

This commit is contained in:
rjs 2015-10-13 21:28:34 +00:00
parent 29160715bc
commit 8c2654abca
41 changed files with 43010 additions and 21 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.1996 2015/10/02 05:22:49 msaitoh Exp $
# $NetBSD: mi,v 1.1997 2015/10/13 21:28:34 rjs Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@ -2290,6 +2290,8 @@
./usr/include/netinet/pim_var.h comp-c-include
./usr/include/netinet/portalgo.h comp-c-include
./usr/include/netinet/rfc6056.h comp-obsolete obsolete
./usr/include/netinet/sctp.h comp-c-include
./usr/include/netinet/sctp_uio.h comp-c-include
./usr/include/netinet/tcp.h comp-c-include
./usr/include/netinet/tcp_debug.h comp-c-include
./usr/include/netinet/tcp_fsm.h comp-c-include

View File

@ -1,4 +1,4 @@
/* $NetBSD: uipc_socket.c,v 1.246 2015/08/24 22:21:26 pooka Exp $ */
/* $NetBSD: uipc_socket.c,v 1.247 2015/10/13 21:28:35 rjs Exp $ */
/*-
* Copyright (c) 2002, 2007, 2008, 2009 The NetBSD Foundation, Inc.
@ -71,7 +71,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.246 2015/08/24 22:21:26 pooka Exp $");
__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.247 2015/10/13 21:28:35 rjs Exp $");
#ifdef _KERNEL_OPT
#include "opt_compat_netbsd.h"
@ -80,6 +80,7 @@ __KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.246 2015/08/24 22:21:26 pooka Exp
#include "opt_mbuftrace.h"
#include "opt_somaxkva.h"
#include "opt_multiprocessor.h" /* XXX */
#include "opt_sctp.h"
#endif
#include <sys/param.h>
@ -644,6 +645,7 @@ int
solisten(struct socket *so, int backlog, struct lwp *l)
{
int error;
short oldopt, oldqlimit;
solock(so);
if ((so->so_state & (SS_ISCONNECTED | SS_ISCONNECTING |
@ -651,16 +653,21 @@ solisten(struct socket *so, int backlog, struct lwp *l)
sounlock(so);
return EINVAL;
}
error = (*so->so_proto->pr_usrreqs->pr_listen)(so, l);
if (error != 0) {
sounlock(so);
return error;
}
oldopt = so->so_options;
oldqlimit = so->so_qlimit;
if (TAILQ_EMPTY(&so->so_q))
so->so_options |= SO_ACCEPTCONN;
if (backlog < 0)
backlog = 0;
so->so_qlimit = min(backlog, somaxconn);
error = (*so->so_proto->pr_usrreqs->pr_listen)(so, l);
if (error != 0) {
so->so_options = oldopt;
so->so_qlimit = oldqlimit;
sounlock(so);
return error;
}
sounlock(so);
return 0;
}
@ -1323,6 +1330,31 @@ soreceive(struct socket *so, struct mbuf **paddr, struct uio *uio,
sbsync(&so->so_rcv, nextrecord);
}
}
if (pr->pr_flags & PR_ADDR_OPT) {
/*
* For SCTP we may be getting a
* whole message OR a partial delivery.
*/
if (m->m_type == MT_SONAME) {
orig_resid = 0;
if (flags & MSG_PEEK) {
if (paddr)
*paddr = m_copy(m, 0, m->m_len);
m = m->m_next;
} else {
sbfree(&so->so_rcv, m);
if (paddr) {
*paddr = m;
so->so_rcv.sb_mb = m->m_next;
m->m_next = 0;
m = so->so_rcv.sb_mb;
} else {
MFREE(m, so->so_rcv.sb_mb);
m = so->so_rcv.sb_mb;
}
}
}
}
/*
* Process one or more MT_CONTROL mbufs present before any data mbufs
@ -1457,6 +1489,10 @@ soreceive(struct socket *so, struct mbuf **paddr, struct uio *uio,
if (len == m->m_len - moff) {
if (m->m_flags & M_EOR)
flags |= MSG_EOR;
#ifdef SCTP
if (m->m_flags & M_NOTIFICATION)
flags |= MSG_NOTIFICATION;
#endif /* SCTP */
if (flags & MSG_PEEK) {
m = m->m_next;
moff = 0;

View File

@ -1,4 +1,4 @@
/* $NetBSD: rtsock.c,v 1.173 2015/08/07 08:11:33 ozaki-r Exp $ */
/* $NetBSD: rtsock.c,v 1.174 2015/10/13 21:28:34 rjs Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -61,12 +61,13 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.173 2015/08/07 08:11:33 ozaki-r Exp $");
__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.174 2015/10/13 21:28:34 rjs Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
#include "opt_mpls.h"
#include "opt_compat_netbsd.h"
#include "opt_sctp.h"
#endif
#include <sys/param.h>
@ -90,6 +91,11 @@ __KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.173 2015/08/07 08:11:33 ozaki-r Exp $")
#include <netmpls/mpls.h>
#ifdef SCTP
extern void sctp_add_ip_address(struct ifaddr *);
extern void sctp_delete_ip_address(struct ifaddr *);
#endif
#if defined(COMPAT_14) || defined(COMPAT_50)
#include <compat/net/if.h>
#include <compat/net/route.h>
@ -1056,6 +1062,14 @@ COMPATNAME(rt_newaddrmsg)(int cmd, struct ifaddr *ifa, int error,
KASSERT(ifa != NULL);
ifp = ifa->ifa_ifp;
#ifdef SCTP
if (cmd == RTM_ADD) {
sctp_add_ip_address(ifa);
} else if (cmd == RTM_DELETE) {
sctp_delete_ip_address(ifa);
}
#endif
COMPATCALL(rt_newaddrmsg, (cmd, ifa, error, rt));
if (COMPATNAME(route_info).ri_cb.any_count == 0)
return;

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.26 2015/02/10 19:11:52 rjs Exp $
# $NetBSD: Makefile,v 1.27 2015/10/13 21:28:35 rjs Exp $
INCSDIR= /usr/include/netinet
@ -7,6 +7,7 @@ INCS= dccp.h icmp6.h icmp_var.h if_atm.h if_ether.h if_inarp.h igmp.h \
in_selsrc.h in_systm.h \
in_var.h ip.h ip_carp.h ip6.h ip_ecn.h ip_encap.h \
ip_icmp.h ip_mroute.h ip_var.h pim.h pim_var.h portalgo.h \
sctp.h sctp_uio.h \
tcp.h tcp_debug.h tcp_fsm.h tcp_seq.h tcp_timer.h tcp_var.h \
tcpip.h udp.h udp_var.h \
tcp_vtw.h

View File

@ -1,4 +1,4 @@
# $NetBSD: files.netinet,v 1.26 2015/02/10 19:11:52 rjs Exp $
# $NetBSD: files.netinet,v 1.27 2015/10/13 21:28:35 rjs Exp $
defflag opt_tcp_debug.h TCP_DEBUG
defparam opt_tcp_debug.h TCP_NDEBUG
@ -20,6 +20,12 @@ defparam opt_tcp_congctl.h TCP_CONGCTL_DEFAULT
defflag opt_dccp.h DCCP DCCP_TFRC DCCPSTATES DCCPBHASHSIZE
DCCP_DEBUG_ON ACKDEBUG
defflag opt_sctp.h SCTP SCTP_DEBUG SCTP_WITH_NO_CSUM
SCTP_LOCK_LOGGING SCTP_MBUF_LOGGING
SCTP_MBCNT_LOGGING SCTP_PACKET_LOGGING
SCTP_LTRACE_CHUNKS SCTP_LTRACE_ERRORS
SCTP_USE_PERCPU_STAT SCTP_MCORE_INPUT
file netinet/igmp.c inet
file netinet/in.c inet
file netinet/in_offload.c inet
@ -53,3 +59,15 @@ file netinet/dccp_cc_sw.c inet & dccp | inet6 & dccp
file netinet/dccp_tcplike.c inet & dccp | inet6 & dccp
file netinet/dccp_tfrc.c inet & dccp | inet6 & dccp
file netinet/dccp_usrreq.c inet & dccp | inet6 & dccp
file netinet/sctp_asconf.c inet & sctp | inet6 & sctp
file netinet/sctp_crc32.c inet & sctp | inet6 & sctp
file netinet/sctp_hashdriver.c inet & sctp | inet6 & sctp
file netinet/sctp_indata.c inet & sctp | inet6 & sctp
file netinet/sctp_input.c inet & sctp | inet6 & sctp
file netinet/sctp_output.c inet & sctp | inet6 & sctp
file netinet/sctp_pcb.c inet & sctp | inet6 & sctp
file netinet/sctp_peeloff.c inet & sctp | inet6 & sctp
file netinet/sctp_timer.c inet & sctp | inet6 & sctp
file netinet/sctp_usrreq.c inet & sctp | inet6 & sctp
file netinet/sctputil.c inet & sctp | inet6 & sctp

View File

@ -1,4 +1,4 @@
/* $NetBSD: in.h,v 1.97 2015/05/02 14:41:32 roy Exp $ */
/* $NetBSD: in.h,v 1.98 2015/10/13 21:28:35 rjs Exp $ */
/*
* Copyright (c) 1982, 1986, 1990, 1993
@ -105,6 +105,7 @@ typedef __sa_family_t sa_family_t;
#define IPPROTO_IPCOMP 108 /* IP Payload Comp. Protocol */
#define IPPROTO_VRRP 112 /* VRRP RFC 2338 */
#define IPPROTO_CARP 112 /* Common Address Resolution Protocol */
#define IPPROTO_SCTP 132 /* SCTP */
#define IPPROTO_PFSYNC 240 /* PFSYNC */
#define IPPROTO_RAW 255 /* raw IP packet */
#define IPPROTO_MAX 256

View File

@ -1,4 +1,4 @@
/* $NetBSD: in_proto.c,v 1.114 2015/08/31 08:05:20 ozaki-r Exp $ */
/* $NetBSD: in_proto.c,v 1.115 2015/10/13 21:28:35 rjs Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: in_proto.c,v 1.114 2015/08/31 08:05:20 ozaki-r Exp $");
__KERNEL_RCSID(0, "$NetBSD: in_proto.c,v 1.115 2015/10/13 21:28:35 rjs Exp $");
#ifdef _KERNEL_OPT
#include "opt_mrouting.h"
@ -70,6 +70,7 @@ __KERNEL_RCSID(0, "$NetBSD: in_proto.c,v 1.114 2015/08/31 08:05:20 ozaki-r Exp $
#include "opt_pim.h"
#include "opt_gateway.h"
#include "opt_dccp.h"
#include "opt_sctp.h"
#include "opt_compat_netbsd.h"
#endif
@ -120,6 +121,11 @@ __KERNEL_RCSID(0, "$NetBSD: in_proto.c,v 1.114 2015/08/31 08:05:20 ozaki-r Exp $
#include <netinet/dccp_var.h>
#endif
#ifdef SCTP
#include <netinet/sctp.h>
#include <netinet/sctp_var.h>
#endif
/*
* TCP/IP protocol family: IP, ICMP, UDP, TCP.
*/
@ -173,6 +179,14 @@ PR_WRAP_CTLOUTPUT(dccp_ctloutput)
#define dccp_ctloutput dccp_ctloutput_wrapper
#endif
#ifdef SCTP
PR_WRAP_CTLINPUT(sctp_ctlinput)
PR_WRAP_CTLOUTPUT(sctp_ctloutput)
#define sctp_ctlinput sctp_ctlinput_wrapper
#define sctp_ctloutput sctp_ctloutput_wrapper
#endif
#if defined(IPSEC)
PR_WRAP_CTLINPUT(ah4_ctlinput)
@ -224,6 +238,39 @@ const struct protosw inetsw[] = {
.pr_init = dccp_init,
},
#endif
#ifdef SCTP
{ .pr_type = SOCK_DGRAM,
.pr_domain = &inetdomain,
.pr_protocol = IPPROTO_SCTP,
.pr_flags = PR_ADDR_OPT|PR_WANTRCVD,
.pr_input = sctp_input,
.pr_ctlinput = sctp_ctlinput,
.pr_ctloutput = sctp_ctloutput,
.pr_usrreqs = &sctp_usrreqs,
.pr_init = sctp_init,
.pr_drain = sctp_drain
},
{ .pr_type = SOCK_SEQPACKET,
.pr_domain = &inetdomain,
.pr_protocol = IPPROTO_SCTP,
.pr_flags = PR_ADDR_OPT|PR_WANTRCVD,
.pr_input = sctp_input,
.pr_ctlinput = sctp_ctlinput,
.pr_ctloutput = sctp_ctloutput,
.pr_usrreqs = &sctp_usrreqs,
.pr_drain = sctp_drain
},
{ .pr_type = SOCK_STREAM,
.pr_domain = &inetdomain,
.pr_protocol = IPPROTO_SCTP,
.pr_flags = PR_CONNREQUIRED|PR_ADDR_OPT|PR_WANTRCVD|PR_LISTEN,
.pr_input = sctp_input,
.pr_ctlinput = sctp_ctlinput,
.pr_ctloutput = sctp_ctloutput,
.pr_usrreqs = &sctp_usrreqs,
.pr_drain = sctp_drain
},
#endif /* SCTP */
{ .pr_type = SOCK_RAW,
.pr_domain = &inetdomain,
.pr_protocol = IPPROTO_RAW,

301
sys/netinet/sctp.h Normal file
View File

@ -0,0 +1,301 @@
/* $KAME: sctp.h,v 1.18 2005/03/06 16:04:16 itojun Exp $ */
/* $NetBSD: sctp.h,v 1.1 2015/10/13 21:28:35 rjs Exp $ */
#ifndef _NETINET_SCTP_H_
#define _NETINET_SCTP_H_
/*
* Copyright (c) 2001, 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Cisco Systems, Inc.
* 4. 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 CISCO SYSTEMS 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 CISCO SYSTEMS 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 <sys/types.h>
/*
* SCTP protocol - RFC2960.
*/
struct sctphdr {
u_int16_t src_port; /* source port */
u_int16_t dest_port; /* destination port */
u_int32_t v_tag; /* verification tag of packet */
u_int32_t checksum; /* Adler32 C-Sum */
/* chunks follow... */
};
/*
* SCTP Chunks
*/
struct sctp_chunkhdr {
u_int8_t chunk_type; /* chunk type */
u_int8_t chunk_flags; /* chunk flags */
u_int16_t chunk_length; /* chunk length */
/* optional params follow */
};
/*
* SCTP chunk parameters
*/
struct sctp_paramhdr {
u_int16_t param_type; /* parameter type */
u_int16_t param_length; /* parameter length */
};
/*
* user socket options
*/
/* read-write options */
#define SCTP_NODELAY 0x00000001
#define SCTP_MAXSEG 0x00000002
#define SCTP_ASSOCINFO 0x00000003
#define SCTP_INITMSG 0x00000004
#define SCTP_AUTOCLOSE 0x00000005
#define SCTP_SET_PEER_PRIMARY_ADDR 0x00000006
#define SCTP_PRIMARY_ADDR 0x00000007
/* read-only options */
#define SCTP_STATUS 0x00000008
#define SCTP_PCB_STATUS 0x00000009
/* ancillary data/notification interest options */
#define SCTP_EVENTS 0x0000000a
/* sctp_opt_info params */
#define SCTP_PEER_ADDR_PARAMS 0x0000000b
#define SCTP_GET_PEER_ADDR_INFO 0x0000000c
/* Hidden socket option that gets the addresses */
#define SCTP_GET_PEER_ADDRESSES 0x0000000d
#define SCTP_GET_LOCAL_ADDRESSES 0x0000000e
/*
* Blocking I/O is enabled on any TCP type socket by default.
* For the UDP model if this is turned on then the socket buffer is
* shared for send resources amongst all associations. The default
* for the UDP model is that is SS_NBIO is set. Which means all associations
* have a seperate send limit BUT they will NOT ever BLOCK instead
* you will get an error back EAGAIN if you try to send to much. If
* you want the blocking symantics you set this option at the cost
* of sharing one socket send buffer size amongst all associations.
* Peeled off sockets turn this option off and block... but since both TCP and
* peeled off sockets have only one assoc per socket this is fine.
* It probably does NOT make sense to set this on SS_NBIO on a TCP model OR
* peeled off UDP model, but we do allow you to do so. You just use
* the normal syscall to toggle SS_NBIO the way you want.
*/
/* Blocking I/O is controled by the SS_NBIO flag on the
* socket state so_state field.
*/
#define SCTP_GET_SNDBUF_USE 0x0000000f
/* latter added read/write */
#define SCTP_ADAPTION_LAYER 0x00000010
#define SCTP_DISABLE_FRAGMENTS 0x00000011
/* sctp_bindx() flags as socket options */
#define SCTP_BINDX_ADD_ADDR 0x00000012
#define SCTP_BINDX_REM_ADDR 0x00000013
/* return the total count in bytes needed to hold all local addresses bound */
#define SCTP_GET_LOCAL_ADDR_SIZE 0x00000014
/* Without this applied we will give V4 and V6 addresses on a V6 socket */
#define SCTP_I_WANT_MAPPED_V4_ADDR 0x00000015
/* Return the total count in bytes needed to hold the remote address */
#define SCTP_GET_REMOTE_ADDR_SIZE 0x00000016
#define SCTP_GET_PEGS 0x00000017
#define SCTP_DEFAULT_SEND_PARAM 0x00000018
#define SCTP_SET_DEBUG_LEVEL 0x00000019
#define SCTP_RTOINFO 0x0000001a
#define SCTP_AUTO_ASCONF 0x0000001b
#define SCTP_MAXBURST 0x0000001c
#define SCTP_GET_STAT_LOG 0x0000001d
#define SCTP_CONNECT_X 0x0000001e /* hidden opt for connectx */
#define SCTP_RESET_STREAMS 0x0000001f
#define SCTP_CONNECT_X_DELAYED 0x00000020 /* hidden opt for connectx_delayed
* part of sctp_sendx()
*/
#define SCTP_CONNECT_X_COMPLETE 0x00000021
#define SCTP_GET_ASOC_ID_LIST 0x00000022
/* Other BSD items */
#define SCTP_GET_NONCE_VALUES 0x00000023
#define SCTP_DELAYED_ACK_TIME 0x00000024
/* Things for the AUTH draft possibly */
#define SCTP_PEER_PUBLIC_KEY 0x00000100 /* get the peers public key */
#define SCTP_MY_PUBLIC_KEY 0x00000101 /* get/set my endpoints public key */
#define SCTP_SET_AUTH_SECRET 0x00000102 /* get/set my shared secret */
#define SCTP_SET_AUTH_CHUNKS 0x00000103/* specify what chunks you want
* the system may have additional requirments
* as well. I.e. probably ASCONF/ASCONF-ACK no matter
* if you want it or not.
*/
/* Debug things that need to be purged */
#define SCTP_SET_INITIAL_DBG_SEQ 0x00001f00
#define SCTP_RESET_PEGS 0x00002000
#define SCTP_CLR_STAT_LOG 0x00002100
/*
* user state values
*/
#define SCTP_CLOSED 0x0000
#define SCTP_BOUND 0x1000
#define SCTP_LISTEN 0x2000
#define SCTP_COOKIE_WAIT 0x0002
#define SCTP_COOKIE_ECHOED 0x0004
#define SCTP_ESTABLISHED 0x0008
#define SCTP_SHUTDOWN_SENT 0x0010
#define SCTP_SHUTDOWN_RECEIVED 0x0020
#define SCTP_SHUTDOWN_ACK_SENT 0x0040
#define SCTP_SHUTDOWN_PENDING 0x0080
/*
* SCTP operational error codes (user visible)
*/
#define SCTP_ERROR_NO_ERROR 0x0000
#define SCTP_ERROR_INVALID_STREAM 0x0001
#define SCTP_ERROR_MISSING_PARAM 0x0002
#define SCTP_ERROR_STALE_COOKIE 0x0003
#define SCTP_ERROR_OUT_OF_RESOURCES 0x0004
#define SCTP_ERROR_UNRESOLVABLE_ADDR 0x0005
#define SCTP_ERROR_UNRECOG_CHUNK 0x0006
#define SCTP_ERROR_INVALID_PARAM 0x0007
#define SCTP_ERROR_UNRECOG_PARAM 0x0008
#define SCTP_ERROR_NO_USER_DATA 0x0009
#define SCTP_ERROR_COOKIE_IN_SHUTDOWN 0x000a
/* draft-ietf-tsvwg-sctpimpguide */
#define SCTP_ERROR_RESTART_NEWADDRS 0x000b
/* draft-ietf-tsvwg-addip-sctp */
#define SCTP_ERROR_DELETE_LAST_ADDR 0x0100
#define SCTP_ERROR_RESOURCE_SHORTAGE 0x0101
#define SCTP_ERROR_DELETE_SOURCE_ADDR 0x0102
#define SCTP_ERROR_ILLEGAL_ASCONF_ACK 0x0103
/*
* error cause parameters (user visisble)
*/
struct sctp_error_cause {
u_int16_t code;
u_int16_t length;
/* optional cause-specific info may follow */
};
struct sctp_error_invalid_stream {
struct sctp_error_cause cause; /* code=SCTP_ERROR_INVALID_STREAM */
u_int16_t stream_id; /* stream id of the DATA in error */
u_int16_t reserved;
};
struct sctp_error_missing_param {
struct sctp_error_cause cause; /* code=SCTP_ERROR_MISSING_PARAM */
u_int32_t num_missing_params; /* number of missing parameters */
/* u_int16_t param_type's follow */
};
struct sctp_error_stale_cookie {
struct sctp_error_cause cause; /* code=SCTP_ERROR_STALE_COOKIE */
u_int32_t stale_time; /* time in usec of staleness */
};
struct sctp_error_out_of_resource {
struct sctp_error_cause cause; /* code=SCTP_ERROR_OUT_OF_RESOURCES */
};
struct sctp_error_unresolv_addr {
struct sctp_error_cause cause; /* code=SCTP_ERROR_UNRESOLVABLE_ADDR */
};
struct sctp_error_unrecognized_chunk {
struct sctp_error_cause cause; /* code=SCTP_ERROR_UNRECOG_CHUNK */
struct sctp_chunkhdr ch; /* header from chunk in error */
};
#define HAVE_SCTP 1
#define HAVE_KERNEL_SCTP 1
#define HAVE_SCTP_PRSCTP 1
#define HAVE_SCTP_ADDIP 1
#define HAVE_SCTP_CANSET_PRIMARY 1
#define HAVE_SCTP_SAT_NETWORK_CAPABILITY1
#define HAVE_SCTP_MULTIBUF 1
#define HAVE_SCTP_NOCONNECT 0
#define HAVE_SCTP_ECN_NONCE 1 /* ECN Nonce option */
/* Main SCTP chunk types, we place
* these here since that way natd and f/w's
* in user land can find them.
*/
#define SCTP_DATA 0x00
#define SCTP_INITIATION 0x01
#define SCTP_INITIATION_ACK 0x02
#define SCTP_SELECTIVE_ACK 0x03
#define SCTP_HEARTBEAT_REQUEST 0x04
#define SCTP_HEARTBEAT_ACK 0x05
#define SCTP_ABORT_ASSOCIATION 0x06
#define SCTP_SHUTDOWN 0x07
#define SCTP_SHUTDOWN_ACK 0x08
#define SCTP_OPERATION_ERROR 0x09
#define SCTP_COOKIE_ECHO 0x0a
#define SCTP_COOKIE_ACK 0x0b
#define SCTP_ECN_ECHO 0x0c
#define SCTP_ECN_CWR 0x0d
#define SCTP_SHUTDOWN_COMPLETE 0x0e
/* draft-ietf-tsvwg-addip-sctp */
#define SCTP_ASCONF 0xc1
#define SCTP_ASCONF_ACK 0x80
/* draft-ietf-stewart-prsctp */
#define SCTP_FORWARD_CUM_TSN 0xc0
/* draft-ietf-stewart-pktdrpsctp */
#define SCTP_PACKET_DROPPED 0x81
/* draft-ietf-stewart-strreset-xxx */
#define SCTP_STREAM_RESET 0x82
/* ABORT and SHUTDOWN COMPLETE FLAG */
#define SCTP_HAD_NO_TCB 0x01
/* Packet dropped flags */
#define SCTP_FROM_MIDDLE_BOX SCTP_HAD_NO_TCB
#define SCTP_BADCRC 0x02
#define SCTP_PACKET_TRUNCATED 0x04
#define SCTP_SAT_NETWORK_MIN 400 /* min ms for RTT to set satellite time */
#define SCTP_SAT_NETWORK_BURST_INCR 2 /* how many times to multiply maxburst in sat */
/* Data Chuck Specific Flags */
#define SCTP_DATA_FRAG_MASK 0x03
#define SCTP_DATA_MIDDLE_FRAG 0x00
#define SCTP_DATA_LAST_FRAG 0x01
#define SCTP_DATA_FIRST_FRAG 0x02
#define SCTP_DATA_NOT_FRAG 0x03
#define SCTP_DATA_UNORDERED 0x04
/* ECN Nonce: SACK Chunk Specific Flags */
#define SCTP_SACK_NONCE_SUM 0x01
#include <netinet/sctp_uio.h>
#endif /* !_NETINET_SCTP_H_ */

2876
sys/netinet/sctp_asconf.c Normal file

File diff suppressed because it is too large Load Diff

66
sys/netinet/sctp_asconf.h Normal file
View File

@ -0,0 +1,66 @@
/* $KAME: sctp_asconf.h,v 1.8 2005/03/06 16:04:16 itojun Exp $ */
/* $NetBSD: sctp_asconf.h,v 1.1 2015/10/13 21:28:35 rjs Exp $ */
#ifndef _NETINET_SCTP_ASCONF_H_
#define _NETINET_SCTP_ASCONF_H_
/*
* Copyright (c) 2001, 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 CISCO SYSTEMS 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 CISCO SYSTEMS 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 <sys/malloc.h>
#if defined(_KERNEL)
extern void sctp_asconf_cleanup(struct sctp_tcb *, struct sctp_nets *);
extern struct mbuf *sctp_compose_asconf(struct sctp_tcb *);
extern void sctp_handle_asconf(struct mbuf *, unsigned int, struct sctp_asconf_chunk *,
struct sctp_tcb *, struct sctp_nets *);
extern void sctp_handle_asconf_ack(struct mbuf *, int,
struct sctp_asconf_ack_chunk *, struct sctp_tcb *, struct sctp_nets *);
extern uint32_t sctp_addr_mgmt_ep_sa(struct sctp_inpcb *, struct sockaddr *,
uint16_t);
extern void sctp_add_ip_address(struct ifaddr *);
extern void sctp_delete_ip_address(struct ifaddr *);
extern int32_t sctp_set_primary_ip_address_sa(struct sctp_tcb *,
struct sockaddr *);
extern void sctp_set_primary_ip_address(struct ifaddr *);
extern void sctp_check_address_list(struct sctp_tcb *, struct mbuf *, int, int,
struct sockaddr *, uint16_t, uint16_t, uint16_t, uint16_t);
#endif /* _KERNEL */
#endif /* !_NETINET_SCTP_ASCONF_H_ */

View File

@ -0,0 +1,832 @@
/* $KAME: sctp_constants.h,v 1.17 2005/03/06 16:04:17 itojun Exp $ */
/* $NetBSD: sctp_constants.h,v 1.1 2015/10/13 21:28:35 rjs Exp $ */
#ifndef __SCTP_CONSTANTS_H__
#define __SCTP_CONSTANTS_H__
/*
* Copyright (c) 2001, 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Cisco Systems, Inc.
* 4. 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 CISCO SYSTEMS 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 CISCO SYSTEMS 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.
*/
#define SCTP_VERSION_STRING "KAME-BSD 1.1"
/*#define SCTP_AUDITING_ENABLED 1 used for debug/auditing */
#define SCTP_AUDIT_SIZE 256
#define SCTP_STAT_LOG_SIZE 80000
/* Places that CWND log can happen from */
#define SCTP_CWND_LOG_FROM_FR 1
#define SCTP_CWND_LOG_FROM_RTX 2
#define SCTP_CWND_LOG_FROM_BRST 3
#define SCTP_CWND_LOG_FROM_SS 4
#define SCTP_CWND_LOG_FROM_CA 5
#define SCTP_CWND_LOG_FROM_SAT 6
#define SCTP_BLOCK_LOG_INTO_BLK 7
#define SCTP_BLOCK_LOG_OUTOF_BLK 8
#define SCTP_BLOCK_LOG_CHECK 9
#define SCTP_STR_LOG_FROM_INTO_STRD 10
#define SCTP_STR_LOG_FROM_IMMED_DEL 11
#define SCTP_STR_LOG_FROM_INSERT_HD 12
#define SCTP_STR_LOG_FROM_INSERT_MD 13
#define SCTP_STR_LOG_FROM_INSERT_TL 14
#define SCTP_STR_LOG_FROM_MARK_TSN 15
#define SCTP_STR_LOG_FROM_EXPRS_DEL 16
#define SCTP_FR_LOG_BIGGEST_TSNS 17
#define SCTP_FR_LOG_STRIKE_TEST 18
#define SCTP_FR_LOG_STRIKE_CHUNK 19
#define SCTP_FR_T3_TIMEOUT 20
#define SCTP_MAP_PREPARE_SLIDE 21
#define SCTP_MAP_SLIDE_FROM 22
#define SCTP_MAP_SLIDE_RESULT 23
#define SCTP_MAP_SLIDE_CLEARED 24
#define SCTP_MAP_SLIDE_NONE 25
#define SCTP_FR_T3_MARK_TIME 26
#define SCTP_FR_T3_MARKED 27
#define SCTP_FR_T3_STOPPED 28
#define SCTP_FR_MARKED 30
#define SCTP_CWND_LOG_NOADV_SS 31
#define SCTP_CWND_LOG_NOADV_CA 32
#define SCTP_MAX_BURST_APPLIED 33
#define SCTP_MAX_IFP_APPLIED 34
#define SCTP_MAX_BURST_ERROR_STOP 35
#define SCTP_INCREASE_PEER_RWND 36
#define SCTP_DECREASE_PEER_RWND 37
#define SCTP_SET_PEER_RWND_VIA_SACK 38
#define SCTP_LOG_MBCNT_INCREASE 39
#define SCTP_LOG_MBCNT_DECREASE 40
#define SCTP_LOG_MBCNT_CHKSET 41
/*
* To turn on various logging, you must first define SCTP_STAT_LOGGING.
* Then to get something to log you define one of the logging defines i.e.
*
* SCTP_CWND_LOGGING
* SCTP_BLK_LOGGING
* SCTP_STR_LOGGING
* SCTP_FR_LOGGING
*
* Any one or a combination of the logging can be turned on.
*/
#define SCTP_LOG_EVENT_CWND 1
#define SCTP_LOG_EVENT_BLOCK 2
#define SCTP_LOG_EVENT_STRM 3
#define SCTP_LOG_EVENT_FR 4
#define SCTP_LOG_EVENT_MAP 5
#define SCTP_LOG_EVENT_MAXBURST 6
#define SCTP_LOG_EVENT_RWND 7
#define SCTP_LOG_EVENT_MBCNT 8
/* number of associations by default for zone allocation */
#define SCTP_MAX_NUM_OF_ASOC 40000
/* how many addresses per assoc remote and local */
#define SCTP_SCALE_FOR_ADDR 2
/* default AUTO_ASCONF mode enable(1)/disable(0) value (sysctl) */
#define SCTP_DEFAULT_AUTO_ASCONF 0
/*
* If you wish to use MD5 instead of SLA uncomment the line below.
* Why you would like to do this:
* a) There may be IPR on SHA-1, or so the FIP-180-1 page says,
* b) MD5 is 3 times faster (has coded here).
*
* The disadvantage is it is thought that MD5 has been cracked... see RFC2104.
*/
/*#define USE_MD5 1 */
/*
* Note: I can't seem to get this to compile now for some reason- the
* kernel can't link in the md5 crypto
*/
/* DEFINE HERE WHAT CRC YOU WANT TO USE */
#define SCTP_USECRC_RFC2960 1
/*#define SCTP_USECRC_FLETCHER 1*/
/*#define SCTP_USECRC_SSHCRC32 1*/
/*#define SCTP_USECRC_FASTCRC32 1*/
/*#define SCTP_USECRC_CRC32 1*/
/*#define SCTP_USECRC_TCP32 1*/
/*#define SCTP_USECRC_CRC16SMAL 1*/
/*#define SCTP_USECRC_CRC16 1 */
/*#define SCTP_USECRC_MODADLER 1*/
#ifndef SCTP_ADLER32_BASE
#define SCTP_ADLER32_BASE 65521
#endif
#define SCTP_CWND_POSTS_LIST 256
/*
* the SCTP protocol signature
* this includes the version number encoded in the last 4 bits
* of the signature.
*/
#define PROTO_SIGNATURE_A 0x30000000
#define SCTP_VERSION_NUMBER 0x3
#define MAX_TSN 0xffffffff
#define MAX_SEQ 0xffff
/* how many executions every N tick's */
#define SCTP_MAX_ITERATOR_AT_ONCE 20
/* number of clock ticks between iterator executions */
#define SCTP_ITERATOR_TICKS 1
/* option:
* If you comment out the following you will receive the old
* behavior of obeying cwnd for the fast retransmit algorithm.
* With this defined a FR happens right away with-out waiting
* for the flightsize to drop below the cwnd value (which is
* reduced by the FR to 1/2 the inflight packets).
*/
#define SCTP_IGNORE_CWND_ON_FR 1
/*
* Adds implementors guide behavior to only use newest highest
* update in SACK gap ack's to figure out if you need to stroke
* a chunk for FR.
*/
#define SCTP_NO_FR_UNLESS_SEGMENT_SMALLER 1
/* default max I can burst out after a fast retransmit */
#define SCTP_DEF_MAX_BURST 8
/* Packet transmit states in the sent field */
#define SCTP_DATAGRAM_UNSENT 0
#define SCTP_DATAGRAM_SENT 1
#define SCTP_DATAGRAM_RESEND1 2 /* not used (in code, but may hit this value) */
#define SCTP_DATAGRAM_RESEND2 3 /* not used (in code, but may hit this value) */
#define SCTP_DATAGRAM_RESEND3 4 /* not used (in code, but may hit this value) */
#define SCTP_DATAGRAM_RESEND 5
#define SCTP_DATAGRAM_ACKED 10010
#define SCTP_DATAGRAM_INBOUND 10011
#define SCTP_READY_TO_TRANSMIT 10012
#define SCTP_DATAGRAM_MARKED 20010
#define SCTP_FORWARD_TSN_SKIP 30010
/* SCTP chunk types */
/* Moved to sctp.h so f/w and natd
* boxes can find the chunk types.
*/
/* align to 32-bit sizes */
#define SCTP_SIZE32(x) ((((x)+3) >> 2) << 2)
#define IS_SCTP_CONTROL(a) ((a)->chunk_type != SCTP_DATA)
#define IS_SCTP_DATA(a) ((a)->chunk_type == SCTP_DATA)
/* SCTP parameter types */
#define SCTP_HEARTBEAT_INFO 0x0001
#define SCTP_IPV4_ADDRESS 0x0005
#define SCTP_IPV6_ADDRESS 0x0006
#define SCTP_STATE_COOKIE 0x0007
#define SCTP_UNRECOG_PARAM 0x0008
#define SCTP_COOKIE_PRESERVE 0x0009
#define SCTP_HOSTNAME_ADDRESS 0x000b
#define SCTP_SUPPORTED_ADDRTYPE 0x000c
#define SCTP_ECN_CAPABLE 0x8000
/* draft-ietf-stewart-strreset-xxx */
#define SCTP_STR_RESET_REQUEST 0x000d
#define SCTP_STR_RESET_RESPONSE 0x000e
/* ECN Nonce: draft-ladha-sctp-ecn-nonce */
#define SCTP_ECN_NONCE_SUPPORTED 0x8001
/*
* draft-ietf-stewart-strreset-xxx
* param=0x8001 len=0xNNNN
* Byte | Byte | Byte | Byte
* Byte | Byte ...
*
* Where each Byte is a chunk type
* extension supported so for example
* to support all chunks one would have (in hex):
*
* 80 01 00 09
* C0 C1 80 81
* 82 00 00 00
*
* Has the parameter.
* C0 = PR-SCTP (RFC3758)
* C1, 80 = ASCONF (addip draft)
* 81 = Packet Drop
* 82 = Stream Reset
*/
/* draft-ietf-tsvwg-prsctp */
#define SCTP_SUPPORTED_CHUNK_EXT 0x8008
/* number of extensions we support */
#define SCTP_EXT_COUNT 5 /* num of extensions we support chunk wise */
#define SCTP_PAD_EXT_COUNT 3 /* num of pad bytes needed to get to 32 bit boundary */
#define SCTP_PRSCTP_SUPPORTED 0xc000
/* draft-ietf-tsvwg-addip-sctp */
#define SCTP_ADD_IP_ADDRESS 0xc001
#define SCTP_DEL_IP_ADDRESS 0xc002
#define SCTP_ERROR_CAUSE_IND 0xc003
#define SCTP_SET_PRIM_ADDR 0xc004
#define SCTP_SUCCESS_REPORT 0xc005
#define SCTP_ULP_ADAPTION 0xc006
/* Notification error codes */
#define SCTP_NOTIFY_DATAGRAM_UNSENT 0x0001
#define SCTP_NOTIFY_DATAGRAM_SENT 0x0002
#define SCTP_FAILED_THRESHOLD 0x0004
#define SCTP_HEARTBEAT_SUCCESS 0x0008
#define SCTP_RESPONSE_TO_USER_REQ 0x000f
#define SCTP_INTERNAL_ERROR 0x0010
#define SCTP_SHUTDOWN_GUARD_EXPIRES 0x0020
#define SCTP_RECEIVED_SACK 0x0040
#define SCTP_PEER_FAULTY 0x0080
/* Error causes used in SCTP op-err's and aborts */
#define SCTP_CAUSE_INV_STRM 0x001
#define SCTP_CAUSE_MISS_PARAM 0x002
#define SCTP_CAUSE_STALE_COOKIE 0x003
#define SCTP_CAUSE_OUT_OF_RESC 0x004
#define SCTP_CAUSE_UNRESOLV_ADDR 0x005
#define SCTP_CAUSE_UNRECOG_CHUNK 0x006
#define SCTP_CAUSE_INVALID_PARAM 0x007
/* This one is also the same as SCTP_UNRECOG_PARAM above */
#define SCTP_CAUSE_UNRECOG_PARAM 0x008
#define SCTP_CAUSE_NOUSER_DATA 0x009
#define SCTP_CAUSE_COOKIE_IN_SHUTDOWN 0x00a
#define SCTP_CAUSE_RESTART_W_NEWADDR 0x00b
#define SCTP_CAUSE_USER_INITIATED_ABT 0x00c
#define SCTP_CAUSE_PROTOCOL_VIOLATION 0x00d
/* Error's from add ip */
#define SCTP_CAUSE_DELETEING_LAST_ADDR 0x100
#define SCTP_CAUSE_OPERATION_REFUSED 0x101
#define SCTP_CAUSE_DELETING_SRC_ADDR 0x102
#define SCTP_CAUSE_ILLEGAL_ASCONF 0x103
/* bits for TOS field */
#define SCTP_ECT0_BIT 0x02
#define SCTP_ECT1_BIT 0x01
#define SCTP_CE_BITS 0x03
/* below turns off above */
#define SCTP_FLEXIBLE_ADDRESS 0x20
#define SCTP_NO_HEARTBEAT 0x40
/* mask to get sticky */
#define SCTP_STICKY_OPTIONS_MASK 0x0c
/* MTU discovery flags */
#define SCTP_DONT_FRAGMENT 0x0100
#define SCTP_FRAGMENT_OK 0x0200
#define SCTP_PR_SCTP_ENABLED 0x0400
#define SCTP_PR_SCTP_BUFFER 0x0800
/* Chunk flags */
#define SCTP_WINDOW_PROBE 0x01
/*
* SCTP states for internal state machine
* XXX (should match "user" values)
*/
#define SCTP_STATE_EMPTY 0x0000
#define SCTP_STATE_INUSE 0x0001
#define SCTP_STATE_COOKIE_WAIT 0x0002
#define SCTP_STATE_COOKIE_ECHOED 0x0004
#define SCTP_STATE_OPEN 0x0008
#define SCTP_STATE_SHUTDOWN_SENT 0x0010
#define SCTP_STATE_SHUTDOWN_RECEIVED 0x0020
#define SCTP_STATE_SHUTDOWN_ACK_SENT 0x0040
#define SCTP_STATE_SHUTDOWN_PENDING 0x0080
#define SCTP_STATE_CLOSED_SOCKET 0x0100
#define SCTP_STATE_MASK 0x007f
#define SCTP_GET_STATE(asoc) ((asoc)->state & SCTP_STATE_MASK)
/* SCTP reachability state for each address */
#define SCTP_ADDR_REACHABLE 0x001
#define SCTP_ADDR_NOT_REACHABLE 0x002
#define SCTP_ADDR_NOHB 0x004
#define SCTP_ADDR_BEING_DELETED 0x008
#define SCTP_ADDR_NOT_IN_ASSOC 0x010
#define SCTP_ADDR_WAS_PRIMARY 0x020
#define SCTP_ADDR_SWITCH_PRIMARY 0x040
#define SCTP_ADDR_OUT_OF_SCOPE 0x080
#define SCTP_ADDR_DOUBLE_SWITCH 0x100
#define SCTP_ADDR_UNCONFIRMED 0x200
#define SCTP_REACHABLE_MASK 0x203
/* bound address types (e.g. valid address types to allow) */
#define SCTP_BOUND_V6 0x01
#define SCTP_BOUND_V4 0x02
/* How long a cookie lives in seconds */
#define SCTP_DEFAULT_COOKIE_LIFE 60
/* resource limit of streams */
#define MAX_SCTP_STREAMS 2048
/* Maximum the mapping array will grow to (TSN mapping array) */
#define SCTP_MAPPING_ARRAY 512
/* size of the inital malloc on the mapping array */
#define SCTP_INITIAL_MAPPING_ARRAY 16
/* how much we grow the mapping array each call */
#define SCTP_MAPPING_ARRAY_INCR 32
/*
* Here we define the timer types used by the implementation
* as arguments in the set/get timer type calls.
*/
#define SCTP_TIMER_INIT 0
#define SCTP_TIMER_RECV 1
#define SCTP_TIMER_SEND 2
#define SCTP_TIMER_HEARTBEAT 3
#define SCTP_TIMER_PMTU 4
#define SCTP_TIMER_MAXSHUTDOWN 5
#define SCTP_TIMER_SIGNATURE 6
/*
* number of timer types in the base SCTP structure used in
* the set/get and has the base default.
*/
#define SCTP_NUM_TMRS 7
/* timer types */
#define SCTP_TIMER_TYPE_NONE 0
#define SCTP_TIMER_TYPE_SEND 1
#define SCTP_TIMER_TYPE_INIT 2
#define SCTP_TIMER_TYPE_RECV 3
#define SCTP_TIMER_TYPE_SHUTDOWN 4
#define SCTP_TIMER_TYPE_HEARTBEAT 5
#define SCTP_TIMER_TYPE_COOKIE 6
#define SCTP_TIMER_TYPE_NEWCOOKIE 7
#define SCTP_TIMER_TYPE_PATHMTURAISE 8
#define SCTP_TIMER_TYPE_SHUTDOWNACK 9
#define SCTP_TIMER_TYPE_ASCONF 10
#define SCTP_TIMER_TYPE_SHUTDOWNGUARD 11
#define SCTP_TIMER_TYPE_AUTOCLOSE 12
#define SCTP_TIMER_TYPE_EVENTWAKE 13
#define SCTP_TIMER_TYPE_STRRESET 14
#define SCTP_TIMER_TYPE_INPKILL 15
/*
* Number of ticks before the soxwakeup() event that
* is delayed is sent AFTER the accept() call
*/
#define SCTP_EVENTWAKEUP_WAIT_TICKS 3000
/*
* Of course we really don't collect stale cookies, being folks
* of decerning taste. However we do count them, if we get too
* many before the association comes up.. we give up. Below is
* the constant that dictates when we give it up...this is a
* implemenation dependent treatment. In ours we do not ask for
* a extension of time, but just retry this many times...
*/
#define SCTP_MAX_STALE_COOKIES_I_COLLECT 10
/* max number of TSN's dup'd that I will hold */
#define SCTP_MAX_DUP_TSNS 20
#define SCTP_TIMER_TYPE_ITERATOR 16
/*
* Here we define the types used when setting the retry amounts.
*/
/* constants for type of set */
#define SCTP_MAXATTEMPT_INIT 2
#define SCTP_MAXATTEMPT_SEND 3
/* Maximum TSN's we will summarize in a drop report */
#define SCTP_MAX_DROP_REPORT 16
/* How many drop re-attempts we make on INIT/COOKIE-ECHO */
#define SCTP_RETRY_DROPPED_THRESH 4
/* And the max we will keep a history of in the tcb
* which MUST be lower than 256.
*/
#define SCTP_MAX_DROP_SAVE_REPORT 16
/*
* Here we define the default timers and the default number
* of attemts we make for each respective side (send/init).
*/
/* Maxmium number of chunks a single association can have
* on it. Note that this is a squishy number since
* the count can run over this if the user sends a large
* message down .. the fragmented chunks don't count until
* AFTER the message is on queue.. it would be the next
* send that blocks things. This number will get tuned
* up at boot in the sctp_init and use the number
* of clusters as a base. This way high bandwidth
* environments will not get impacted by the lower
* bandwidth sending a bunch of 1 byte chunks
*/
#define SCTP_ASOC_MAX_CHUNKS_ON_QUEUE 512
#define MSEC_TO_TICKS(x) (((x) * hz) / 1000)
#define TICKS_TO_MSEC(x) (((x) * 1000) / hz)
#define SEC_TO_TICKS(x) ((x) * hz)
/* init timer def = 1 sec */
#define SCTP_INIT_SEC 1
/* send timer def = 1 seconds */
#define SCTP_SEND_SEC 1
/* recv timer def = 200ms */
#define SCTP_RECV_MSEC 200
/* 30 seconds + RTO (in ms) */
#define SCTP_HB_DEFAULT_MSEC 30000
/* Max time I will wait for Shutdown to complete */
#define SCTP_DEF_MAX_SHUTDOWN_SEC 180
/* This is how long a secret lives, NOT how long a cookie lives
* how many ticks the current secret will live.
*/
#define SCTP_DEFAULT_SECRET_LIFE_SEC 3600
#define SCTP_RTO_UPPER_BOUND (60000) /* 60 sec in ms */
#define SCTP_RTO_UPPER_BOUND_SEC 60 /* for the init timer */
#define SCTP_RTO_LOWER_BOUND (1000) /* 1 sec in ms */
#define SCTP_RTO_INITIAL (3000) /* 3 sec in ms */
#define SCTP_INP_KILL_TIMEOUT 1000 /* number of ms to retry kill of inpcb*/
#define SCTP_DEF_MAX_INIT 8
#define SCTP_DEF_MAX_SEND 10
#define SCTP_DEF_PMTU_RAISE_SEC 600 /* 10 min between raise attempts */
#define SCTP_DEF_PMTU_MIN 600
#define SCTP_MSEC_IN_A_SEC 1000
#define SCTP_USEC_IN_A_SEC 1000000
#define SCTP_NSEC_IN_A_SEC 1000000000
#define SCTP_MAX_OUTSTANDING_DG 10000
/* How many streams I request initally by default */
#define SCTP_OSTREAM_INITIAL 10
#define SCTP_SEG_TO_RWND_UPD 32 /* How many smallest_mtu's need to increase before
* a window update sack is sent (should be a
* power of 2).
*/
#define SCTP_SCALE_OF_RWND_TO_UPD 4 /* Incr * this > hiwat, send
* window update. Should be a
* power of 2.
*/
#define SCTP_MINIMAL_RWND (4096) /* minimal rwnd */
#define SCTP_ADDRMAX 20
/* SCTP DEBUG Switch parameters */
#define SCTP_DEBUG_TIMER1 0x00000001
#define SCTP_DEBUG_TIMER2 0x00000002
#define SCTP_DEBUG_TIMER3 0x00000004
#define SCTP_DEBUG_TIMER4 0x00000008
#define SCTP_DEBUG_OUTPUT1 0x00000010
#define SCTP_DEBUG_OUTPUT2 0x00000020
#define SCTP_DEBUG_OUTPUT3 0x00000040
#define SCTP_DEBUG_OUTPUT4 0x00000080
#define SCTP_DEBUG_UTIL1 0x00000100
#define SCTP_DEBUG_UTIL2 0x00000200
#define SCTP_DEBUG_INPUT1 0x00001000
#define SCTP_DEBUG_INPUT2 0x00002000
#define SCTP_DEBUG_INPUT3 0x00004000
#define SCTP_DEBUG_INPUT4 0x00008000
#define SCTP_DEBUG_ASCONF1 0x00010000
#define SCTP_DEBUG_ASCONF2 0x00020000
#define SCTP_DEBUG_OUTPUT5 0x00040000
#define SCTP_DEBUG_PCB1 0x00100000
#define SCTP_DEBUG_PCB2 0x00200000
#define SCTP_DEBUG_PCB3 0x00400000
#define SCTP_DEBUG_PCB4 0x00800000
#define SCTP_DEBUG_INDATA1 0x01000000
#define SCTP_DEBUG_INDATA2 0x02000000
#define SCTP_DEBUG_INDATA3 0x04000000
#define SCTP_DEBUG_INDATA4 0x08000000
#define SCTP_DEBUG_USRREQ1 0x10000000
#define SCTP_DEBUG_USRREQ2 0x20000000
#define SCTP_DEBUG_PEEL1 0x40000000
#define SCTP_DEBUG_ALL 0x7ff3f3ff
#define SCTP_DEBUG_NOISY 0x00040000
/* What sender needs to see to avoid SWS or we consider peers rwnd 0 */
#define SCTP_SWS_SENDER_DEF 1420
/*
* SWS is scaled to the sb_hiwat of the socket.
* A value of 2 is hiwat/4, 1 would be hiwat/2 etc.
*/
/* What receiver needs to see in sockbuf or we tell peer its 1 */
#define SCTP_SWS_RECEIVER_DEF 3000
#define SCTP_INITIAL_CWND 4380
/* amount peer is obligated to have in rwnd or I will abort */
#define SCTP_MIN_RWND 1500
#define SCTP_WINDOW_MIN 1500 /* smallest rwnd can be */
#define SCTP_WINDOW_MAX 1048576 /* biggest I can grow rwnd to
* My playing around suggests a
* value greater than 64k does not
* do much, I guess via the kernel
* limitations on the stream/socket.
*/
#define SCTP_MAX_BUNDLE_UP 256 /* max number of chunks to bundle */
/* I can handle a 1meg re-assembly */
#define SCTP_DEFAULT_MAXMSGREASM 1048576
#define SCTP_DEFAULT_MAXSEGMENT 65535
#define DEFAULT_CHUNK_BUFFER 2048
#define DEFAULT_PARAM_BUFFER 512
#define SCTP_DEFAULT_MINSEGMENT 512 /* MTU size ... if no mtu disc */
#define SCTP_HOW_MANY_SECRETS 2 /* how many secrets I keep */
#define SCTP_NUMBER_OF_SECRETS 8 /* or 8 * 4 = 32 octets */
#define SCTP_SECRET_SIZE 32 /* number of octets in a 256 bits */
#ifdef USE_MD5
#define SCTP_SIGNATURE_SIZE 16 /* size of a MD5 signature */
#else
#define SCTP_SIGNATURE_SIZE 20 /* size of a SLA-1 signature */
#endif /* USE_MD5 */
#define SCTP_SIGNATURE_ALOC_SIZE 20
/*
* SCTP upper layer notifications
*/
#define SCTP_NOTIFY_ASSOC_UP 1
#define SCTP_NOTIFY_ASSOC_DOWN 2
#define SCTP_NOTIFY_INTERFACE_DOWN 3
#define SCTP_NOTIFY_INTERFACE_UP 4
#define SCTP_NOTIFY_DG_FAIL 5
#define SCTP_NOTIFY_STRDATA_ERR 6
#define SCTP_NOTIFY_ASSOC_ABORTED 7
#define SCTP_NOTIFY_PEER_OPENED_STREAM 8
#define SCTP_NOTIFY_STREAM_OPENED_OK 9
#define SCTP_NOTIFY_ASSOC_RESTART 10
#define SCTP_NOTIFY_HB_RESP 11
#define SCTP_NOTIFY_ASCONF_SUCCESS 12
#define SCTP_NOTIFY_ASCONF_FAILED 13
#define SCTP_NOTIFY_PEER_SHUTDOWN 14
#define SCTP_NOTIFY_ASCONF_ADD_IP 15
#define SCTP_NOTIFY_ASCONF_DELETE_IP 16
#define SCTP_NOTIFY_ASCONF_SET_PRIMARY 17
#define SCTP_NOTIFY_PARTIAL_DELVIERY_INDICATION 18
#define SCTP_NOTIFY_ADAPTION_INDICATION 19
#define SCTP_NOTIFY_INTERFACE_CONFIRMED 20
#define SCTP_NOTIFY_STR_RESET_RECV 21
#define SCTP_NOTIFY_STR_RESET_SEND 22
#define SCTP_NOTIFY_MAX 22
/* clock variance is 10ms */
#define SCTP_CLOCK_GRANULARITY 10
#define IP_HDR_SIZE 40 /* we use the size of a IP6 header here
* this detracts a small amount for ipv4
* but it simplifies the ipv6 addition
*/
#ifndef IPPROTO_SCTP
#define IPPROTO_SCTP 132 /* the Official IANA number :-) */
#endif /* !IPPROTO_SCTP */
#define SCTP_MAX_DATA_BUNDLING 256
#define SCTP_MAX_CONTROL_BUNDLING 20
/* modular comparison */
/* True if a > b (mod = M) */
#define compare_with_wrap(a, b, M) (((a > b) && ((a - b) < ((M >> 1) + 1))) || \
((b > a) && ((b - a) > ((M >> 1) + 1))))
/* Mapping array manipulation routines */
#define SCTP_IS_TSN_PRESENT(arry, gap) ((arry[(gap >> 3)] >> (gap & 0x07)) & 0x01)
#define SCTP_SET_TSN_PRESENT(arry, gap) (arry[(gap >> 3)] |= (0x01 << ((gap & 0x07))))
#define SCTP_UNSET_TSN_PRESENT(arry, gap) (arry[(gap >> 3)] &= ((~(0x01 << ((gap & 0x07)))) & 0xff))
/* pegs */
#define SCTP_NUMBER_OF_PEGS 96
/* peg index's */
#define SCTP_PEG_SACKS_SEEN 0
#define SCTP_PEG_SACKS_SENT 1
#define SCTP_PEG_TSNS_SENT 2
#define SCTP_PEG_TSNS_RCVD 3
#define SCTP_DATAGRAMS_SENT 4
#define SCTP_DATAGRAMS_RCVD 5
#define SCTP_RETRANTSN_SENT 6
#define SCTP_DUPTSN_RECVD 7
#define SCTP_HB_RECV 8
#define SCTP_HB_ACK_RECV 9
#define SCTP_HB_SENT 10
#define SCTP_WINDOW_PROBES 11
#define SCTP_DATA_DG_RECV 12
#define SCTP_TMIT_TIMER 13
#define SCTP_RECV_TIMER 14
#define SCTP_HB_TIMER 15
#define SCTP_FAST_RETRAN 16
#define SCTP_TIMERS_EXP 17
#define SCTP_FR_INAWINDOW 18
#define SCTP_RWND_BLOCKED 19
#define SCTP_CWND_BLOCKED 20
#define SCTP_RWND_DROPS 21
#define SCTP_BAD_STRMNO 22
#define SCTP_BAD_SSN_WRAP 23
#define SCTP_DROP_NOMEMORY 24
#define SCTP_DROP_FRAG 25
#define SCTP_BAD_VTAGS 26
#define SCTP_BAD_CSUM 27
#define SCTP_INPKTS 28
#define SCTP_IN_MCAST 29
#define SCTP_HDR_DROPS 30
#define SCTP_NOPORTS 31
#define SCTP_CWND_NOFILL 32
#define SCTP_CALLS_TO_CO 33
#define SCTP_CO_NODATASNT 34
#define SCTP_CWND_NOUSE_SS 35
#define SCTP_MAX_BURST_APL 36
#define SCTP_EXPRESS_ROUTE 37
#define SCTP_NO_COPY_IN 38
#define SCTP_CACHED_SRC 39
#define SCTP_CWND_NOCUM 40
#define SCTP_CWND_SS 41
#define SCTP_CWND_CA 42
#define SCTP_CWND_SKIP 43
#define SCTP_CWND_NOUSE_CA 44
#define SCTP_MAX_CWND 45
#define SCTP_CWND_DIFF_CA 46
#define SCTP_CWND_DIFF_SA 47
#define SCTP_OQS_AT_SS 48
#define SCTP_SQQ_AT_SS 49
#define SCTP_OQS_AT_CA 50
#define SCTP_SQQ_AT_CA 51
#define SCTP_MOVED_MTU 52
#define SCTP_MOVED_QMAX 53
#define SCTP_SQC_AT_SS 54
#define SCTP_SQC_AT_CA 55
#define SCTP_MOVED_MAX 56
#define SCTP_MOVED_NLEF 57
#define SCTP_NAGLE_NOQ 58
#define SCTP_NAGLE_OFF 59
#define SCTP_OUTPUT_FRM_SND 60
#define SCTP_SOS_NOSNT 61
#define SCTP_NOS_NOSNT 62
#define SCTP_SOSE_NOSNT 63
#define SCTP_NOSE_NOSNT 64
#define SCTP_DATA_OUT_ERR 65
#define SCTP_DUP_SSN_RCVD 66
#define SCTP_DUP_FR 67
#define SCTP_VTAG_EXPR 68
#define SCTP_VTAG_BOGUS 69
#define SCTP_T3_SAFEGRD 70
#define SCTP_PDRP_FMBOX 71
#define SCTP_PDRP_FEHOS 72
#define SCTP_PDRP_MB_DA 73
#define SCTP_PDRP_MB_CT 74
#define SCTP_PDRP_BWRPT 75
#define SCTP_PDRP_CRUPT 76
#define SCTP_PDRP_NEDAT 77
#define SCTP_PDRP_PDBRK 78
#define SCTP_PDRP_TSNNF 79
#define SCTP_PDRP_DNFND 80
#define SCTP_PDRP_DIWNP 81
#define SCTP_PDRP_DIZRW 82
#define SCTP_PDRP_BADD 83
#define SCTP_PDRP_MARK 84
#define SCTP_ECNE_RCVD 85
#define SCTP_CWR_PERFO 86
#define SCTP_ECNE_SENT 87
#define SCTP_MSGC_DROP 88
#define SCTP_SEND_QUEUE_POP 89
#define SCTP_ERROUT_FRM_USR 90
#define SCTP_SENDTO_FULL_CWND 91
#define SCTP_QUEONLY_BURSTLMT 92
#define SCTP_IFP_QUEUE_FULL 93
#define SCTP_RESV2 94
#define SCTP_RESV3 95
/*
* This value defines the number of vtag block time wait entry's
* per list element. Each entry will take 2 4 byte ints (and of
* course the overhead of the next pointer as well). Using 15 as
* an example will yield * ((8 * 15) + 8) or 128 bytes of overhead
* for each timewait block that gets initialized. Increasing it to
* 31 would yeild 256 bytes per block.
*/
/* Undef the following turns on per EP behavior */
#define SCTP_VTAG_TIMEWAIT_PER_STACK 1
#ifdef SCTP_VTAG_TIMEWAIT_PER_STACK
#define SCTP_NUMBER_IN_VTAG_BLOCK 15
#else
/* The hash list is smaller if we are on a ep basis */
#define SCTP_NUMBER_IN_VTAG_BLOCK 3
#endif
/*
* If we use the STACK option, we have an array of this size head
* pointers. This array is mod'd the with the size to find which
* bucket and then all entries must be searched to see if the tag
* is in timed wait. If so we reject it.
*/
#define SCTP_STACK_VTAG_HASH_SIZE 31
/*
* If we use the per-endpoint model than we do not have a hash
* table of entries but instead have a single head pointer and
* we must crawl through the entire list.
*/
/*
* Number of seconds of time wait, tied to MSL value (2 minutes),
* so 2 * MSL = 4 minutes or 480 seconds.
*/
#define SCTP_TIME_WAIT 480
#define IN4_ISPRIVATE_ADDRESS(a) \
((((const u_char *)&(a)->s_addr)[0] == 10) || \
((((const u_char *)&(a)->s_addr)[0] == 172) && \
(((const u_char *)&(a)->s_addr)[1] >= 16) && \
(((const u_char *)&(a)->s_addr)[1] <= 32)) || \
((((const u_char *)&(a)->s_addr)[0] == 192) && \
(((const u_char *)&(a)->s_addr)[1] == 168)))
#define IN4_ISLOOPBACK_ADDRESS(a) \
((((const u_char *)&(a)->s_addr)[0] == 127) && \
(((const u_char *)&(a)->s_addr)[1] == 0) && \
(((const u_char *)&(a)->s_addr)[2] == 0) && \
(((const u_char *)&(a)->s_addr)[3] == 1))
#if defined(_KERNEL) || (defined(__APPLE__) && defined(KERNEL))
#if defined(__FreeBSD__) || defined(__APPLE__)
#define SCTP_GETTIME_TIMEVAL(x) (microuptime(x))
#define SCTP_GETTIME_TIMESPEC(x) (nanouptime(x))
#else
#define SCTP_GETTIME_TIMEVAL(x) (microtime(x))
#define SCTP_GETTIME_TIMESPEC(x) (nanotime(x))
#endif /* __FreeBSD__ */
#define sctp_sowwakeup(inp, so) \
do { \
if (inp->sctp_flags & SCTP_PCB_FLAGS_DONT_WAKE) { \
inp->sctp_flags |= SCTP_PCB_FLAGS_WAKEOUTPUT; \
} else { \
sowwakeup(so); \
} \
} while (0)
#define sctp_sorwakeup(inp, so) \
do { \
if (inp->sctp_flags & SCTP_PCB_FLAGS_DONT_WAKE) { \
inp->sctp_flags |= SCTP_PCB_FLAGS_WAKEINPUT; \
} else { \
sorwakeup(so); \
} \
} while (0)
#endif /* _KERNEL */
#endif

184
sys/netinet/sctp_crc32.c Normal file
View File

@ -0,0 +1,184 @@
/* $KAME: sctp_crc32.c,v 1.12 2005/03/06 16:04:17 itojun Exp $ */
/* $NetBSD: sctp_crc32.c,v 1.1 2015/10/13 21:28:35 rjs Exp $ */
/*
* Copyright (c) 2001, 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Cisco Systems, Inc.
* 4. 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 CISCO SYSTEMS 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 CISCO SYSTEMS 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 <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sctp_crc32.c,v 1.1 2015/10/13 21:28:35 rjs Exp $");
#ifdef _KERNEL_OPT
#include "opt_sctp.h"
#endif /* _KERNEL_OPT */
#include <sys/param.h>
#include <netinet/sctp_crc32.h>
#ifndef SCTP_USE_ADLER32
#define SCTP_CRC32C_POLY 0x1EDC6F41
#define SCTP_CRC32C(c, d) (c = ((c) >> 8) ^ sctp_crc_c[((c) ^ (d)) & 0xFF])
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Copyright 2001, D. Otis. Use this program, code or tables */
/* extracted from it, as desired without restriction. */
/* */
/* 32 Bit Reflected CRC table generation for SCTP. */
/* To accommodate serial byte data being shifted out least */
/* significant bit first, the table's 32 bit words are reflected */
/* which flips both byte and bit MS and LS positions. The CRC */
/* is calculated MS bits first from the perspective of the serial*/
/* stream. The x^32 term is implied and the x^0 term may also */
/* be shown as +1. The polynomial code used is 0x1EDC6F41. */
/* Castagnoli93 */
/* x^32+x^28+x^27+x^26+x^25+x^23+x^22+x^20+x^19+x^18+x^14+x^13+ */
/* x^11+x^10+x^9+x^8+x^6+x^0 */
/* Guy Castagnoli Stefan Braeuer and Martin Herrman */
/* "Optimization of Cyclic Redundancy-Check Codes */
/* with 24 and 32 Parity Bits", */
/* IEEE Transactions on Communications, Vol.41, No.6, June 1993 */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
unsigned long sctp_crc_c[256] = {
0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,
0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,
0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,
0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,
0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L,
0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,
0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL,
0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L,
0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,
0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L,
0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,
0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,
0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L,
0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L,
0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L,
0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,
0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L,
0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,
0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,
0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L,
0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,
0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L,
0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L,
0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,
0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL,
0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,
0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L,
0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,
0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL,
0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L,
0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,
0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL,
0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,
0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,
0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L,
0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,
0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L,
0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL,
0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,
0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL,
0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,
0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL,
0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,
0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L,
0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L,
0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,
0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL,
0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L,
};
u_int32_t
update_crc32(u_int32_t crc32c,
unsigned char *buffer,
unsigned int length)
{
unsigned int i;
for (i = 0; i < length; i++) {
SCTP_CRC32C(crc32c, buffer[i]);
}
return (crc32c);
}
u_int32_t
sctp_csum_finalize(u_int32_t crc32c)
{
u_int32_t result;
#if BYTE_ORDER == BIG_ENDIAN
u_int8_t byte0, byte1, byte2, byte3;
#endif
/* Complement the result */
result = ~crc32c;
#if BYTE_ORDER == BIG_ENDIAN
/*
* For BIG-ENDIAN.. aka Motorola byte order the result is in
* little-endian form. So we must manually swap the bytes. Then
* we can call htonl() which does nothing...
*/
byte0 = result & 0x000000ff;
byte1 = (result >> 8) & 0x000000ff;
byte2 = (result >> 16) & 0x000000ff;
byte3 = (result >> 24) & 0x000000ff;
result = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3);
crc32c = htonl(result);
#else
/*
* For INTEL platforms the result comes out in network order.
* No htonl is required or the swap above. So we optimize out
* both the htonl and the manual swap above.
*/
crc32c = result;
#endif
return (crc32c);
}
#endif

49
sys/netinet/sctp_crc32.h Normal file
View File

@ -0,0 +1,49 @@
/* $KAME: sctp_crc32.h,v 1.5 2004/08/17 04:06:16 itojun Exp $ */
/* $NetBSD: sctp_crc32.h,v 1.1 2015/10/13 21:28:35 rjs Exp $ */
#ifndef __SCTP_CRC32C_H__
#define __SCTP_CRC32C_H__
/*
* Copyright (c) 2001, 2002, 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Cisco Systems, Inc.
* 4. 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 CISCO SYSTEMS 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 CISCO SYSTEMS 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 <sys/types.h>
#ifndef SCTP_USE_ADLER32
#if defined(_KERNEL)
u_int32_t update_crc32(u_int32_t, unsigned char *, unsigned int);
u_int32_t sctp_csum_finalize(u_int32_t);
#endif /* _KERNEL */
#endif /* !SCTP_USE_ADLER32 */
#endif /* __SCTP_CRC32C_H__ */

View File

@ -0,0 +1,265 @@
/* $KAME: sctp_hashdriver.c,v 1.6 2004/02/24 21:52:26 itojun Exp $ */
/* $NetBSD: sctp_hashdriver.c,v 1.1 2015/10/13 21:28:35 rjs Exp $ */
/*
* Copyright (c) 2001, 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Cisco Systems, Inc.
* 4. 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 CISCO SYSTEMS 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 CISCO SYSTEMS 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 <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sctp_hashdriver.c,v 1.1 2015/10/13 21:28:35 rjs Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/domain.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/proc.h>
#include <sys/kernel.h>
#include <sys/sysctl.h>
#include <sys/types.h>
#include <netinet/sctp_constants.h>
#ifdef USE_MD5
#include <sys/md5.h>
#else
#include <sys/sha1.h>
#endif
#include <netinet/sctp_hashdriver.h>
/*
* Main driver for SCTP's hashing.
* passing a two pointers and two lengths, returning a digest pointer
* filled. The md5 code was taken directly from the RFC (2104) so to
* understand it you may want to go look at the RFC referenced in the
* SCTP spec. We did modify this code to either user OURs implementation
* of SLA1 or the MD5 that comes from its RFC. SLA1 may have IPR issues
* so you need to check in to this if you wish to use it... Or at least
* that is what the FIP-180.1 web page says.
*/
void sctp_hash_digest(char *key, int key_len, char *text, int text_len,
unsigned char *digest)
{
#ifdef USE_MD5
MD5Context context;
#else
SHA1_CTX context;
#endif /* USE_MD5 */
/* inner padding - key XORd with ipad */
unsigned char k_ipad[65];
/* outer padding - key XORd with opad */
unsigned char k_opad[65];
unsigned char tk[20];
int i;
if (key_len > 64) {
#ifdef USE_MD5
md5_ctxt tctx;
MD5Init(&tctx);
MD5Update(&tctx, key, key_len);
MD5Final(tk, &tctx);
key = tk;
key_len = 16;
#else
SHA1_CTX tctx;
SHA1Init(&tctx);
SHA1Update(&tctx, key, key_len);
SHA1Final(tk, &tctx);
key = tk;
key_len = 20;
#endif /* USE_MD5 */
}
/*
* the HMAC_MD5 transform looks like:
*
* MD5(K XOR opad, MD5(K XOR ipad, text))
*
* where K is an n byte key
* ipad is the byte 0x36 repeated 64 times
* opad is the byte 0x5c repeated 64 times
* and text is the data being protected
*/
/* start out by storing key in pads */
memset(k_ipad, 0, sizeof k_ipad);
memset(k_opad, 0, sizeof k_opad);
bcopy(key, k_ipad, key_len);
bcopy(key, k_opad, key_len);
/* XOR key with ipad and opad values */
for (i = 0; i < 64; i++) {
k_ipad[i] ^= 0x36;
k_opad[i] ^= 0x5c;
}
/*
* perform inner MD5
*/
#ifdef USE_MD5
MD5Init(&context); /* init context for 1st pass */
MD5Update(&context, k_ipad, 64); /* start with inner pad */
MD5Update(&context, text, text_len); /* then text of datagram */
MD5Final(digest, &context); /* finish up 1st pass */
#else
SHA1Init(&context); /* init context for 1st pass */
SHA1Update(&context, k_ipad, 64); /* start with inner pad */
SHA1Update(&context, text, text_len); /* then text of datagram */
SHA1Final(digest, &context); /* finish up 1st pass */
#endif /* USE_MD5 */
/*
* perform outer MD5
*/
#ifdef USE_MD5
MD5Init(&context); /* init context for 2nd pass */
MD5Update(&context, k_opad, 64); /* start with outer pad */
MD5Update(&context, digest, 16); /* then results of 1st hash */
MD5Final(digest, &context); /* finish up 2nd pass */
#else
SHA1Init(&context); /* init context for 2nd pass */
SHA1Update(&context, k_opad, 64); /* start with outer pad */
SHA1Update(&context, digest, 20); /* then results of 1st hash */
SHA1Final(digest, &context); /* finish up 2nd pass */
#endif /* USE_MD5 */
}
void sctp_hash_digest_m(char *key, int key_len, struct mbuf *m, int offset,
unsigned char *digest)
{
struct mbuf *m_at;
#ifdef USE_MD5
MD5Context context;
#else
SHA1_CTX context;
#endif /* USE_MD5 */
/* inner padding - key XORd with ipad */
unsigned char k_ipad[65];
/* outer padding - key XORd with opad */
unsigned char k_opad[65];
unsigned char tk[20];
int i;
if (key_len > 64) {
#ifdef USE_MD5
MD5Context tctx;
MD5Init(&tctx);
MD5Update(&tctx, key, key_len);
MD5Final(tk, &tctx);
key = tk;
key_len = 16;
#else
SHA1_CTX tctx;
SHA1Init(&tctx);
SHA1Update(&tctx, key, key_len);
SHA1Final(tk, &tctx);
key = tk;
key_len = 20;
#endif /* USE_MD5 */
}
/*
* the HMAC_MD5 transform looks like:
*
* MD5(K XOR opad, MD5(K XOR ipad, text))
*
* where K is an n byte key
* ipad is the byte 0x36 repeated 64 times
* opad is the byte 0x5c repeated 64 times
* and text is the data being protected
*/
/* start out by storing key in pads */
memset(k_ipad, 0, sizeof k_ipad);
memset(k_opad, 0, sizeof k_opad);
bcopy(key, k_ipad, key_len);
bcopy(key, k_opad, key_len);
/* XOR key with ipad and opad values */
for (i = 0; i < 64; i++) {
k_ipad[i] ^= 0x36;
k_opad[i] ^= 0x5c;
}
/* find the correct mbuf and offset into mbuf */
m_at = m;
while ((m_at != NULL) && (offset > m_at->m_len)) {
offset -= m_at->m_len; /* update remaining offset left */
m_at = m_at->m_next;
}
/*
* perform inner MD5
*/
#ifdef USE_MD5
MD5Init(&context); /* init context for 1st pass */
MD5Update(&context, k_ipad, 64); /* start with inner pad */
/******/
while (m_at != NULL) {
/* then text of datagram... */
MD5Update(&context, mtod(m_at, char *)+offset,
m_at->m_len-offset);
/* only offset on the first mbuf */
offset = 0;
m_at = m_at->m_next;
}
/******/
MD5Final(digest, &context); /* finish up 1st pass */
#else
SHA1Init(&context); /* init context for 1st pass */
SHA1Update(&context, k_ipad, 64); /* start with inner pad */
/******/
while (m_at != NULL) {
/* then text of datagram */
SHA1Update(&context, mtod(m_at, char *)+offset,
m_at->m_len-offset);
/* only offset on the first mbuf */
offset = 0;
m_at = m_at->m_next;
}
/******/
SHA1Final(digest, &context); /* finish up 1st pass */
#endif /* USE_MD5 */
/*
* perform outer MD5
*/
#ifdef USE_MD5
MD5Init(&context); /* init context for 2nd pass */
MD5Update(&context, k_opad, 64); /* start with outer pad */
MD5Update(&context, digest, 16); /* then results of 1st hash */
MD5Final(digest, &context); /* finish up 2nd pass */
#else
SHA1Init(&context); /* init context for 2nd pass */
SHA1Update(&context, k_opad, 64); /* start with outer pad */
SHA1Update(&context, digest, 20); /* then results of 1st hash */
SHA1Final(digest, &context); /* finish up 2nd pass */
#endif /* USE_MD5 */
}

View File

@ -0,0 +1,43 @@
/* $KAME: sctp_hashdriver.h,v 1.4 2003/11/25 06:40:52 ono Exp $ */
/* $NetBSD: sctp_hashdriver.h,v 1.1 2015/10/13 21:28:35 rjs Exp $ */
#ifndef __SCTP_HASHDRIVER_H__
#define __SCTP_HASHDRIVER_H__
/*
* Copyright (c) 2001, 2002 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Cisco Systems, Inc.
* 4. 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 CISCO SYSTEMS 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 CISCO SYSTEMS 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.
*/
void sctp_hash_digest(char *, int, char *, int, unsigned char *);
void sctp_hash_digest_m(char *, int, struct mbuf *, int, unsigned char *);
#endif

489
sys/netinet/sctp_header.h Normal file
View File

@ -0,0 +1,489 @@
/* $KAME: sctp_header.h,v 1.14 2005/03/06 16:04:17 itojun Exp $ */
/* $NetBSD: sctp_header.h,v 1.1 2015/10/13 21:28:35 rjs Exp $ */
#ifndef __SCTP_HEADER_H__
#define __SCTP_HEADER_H__
/*
* Copyright (c) 2001, 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Cisco Systems, Inc.
* 4. 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 CISCO SYSTEMS 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 CISCO SYSTEMS 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 <sys/time.h>
#include <netinet/sctp.h>
#include <netinet/sctp_constants.h>
/*
* Parameter structures
*/
struct sctp_ipv4addr_param {
struct sctp_paramhdr ph; /* type=SCTP_IPV4_PARAM_TYPE, len=8 */
u_int32_t addr; /* IPV4 address */
};
struct sctp_ipv6addr_param {
struct sctp_paramhdr ph; /* type=SCTP_IPV6_PARAM_TYPE, len=20 */
u_int8_t addr[16]; /* IPV6 address */
};
/* Cookie Preservative */
struct sctp_cookie_perserve_param {
struct sctp_paramhdr ph; /* type=SCTP_COOKIE_PRESERVE, len=8 */
u_int32_t time; /* time in ms to extend cookie */
};
/* Host Name Address */
struct sctp_host_name_param {
struct sctp_paramhdr ph; /* type=SCTP_HOSTNAME_ADDRESS */
char name[1]; /* host name */
};
/* supported address type */
struct sctp_supported_addr_param {
struct sctp_paramhdr ph; /* type=SCTP_SUPPORTED_ADDRTYPE */
u_int16_t addr_type[1]; /* array of supported address types */
};
/* ECN parameter */
struct sctp_ecn_supported_param {
struct sctp_paramhdr ph; /* type=SCTP_ECN_CAPABLE */
};
/* heartbeat info parameter */
struct sctp_heartbeat_info_param {
struct sctp_paramhdr ph;
u_int32_t time_value_1;
u_int32_t time_value_2;
u_int32_t random_value1;
u_int32_t random_value2;
u_int16_t user_req;
u_int8_t addr_family;
u_int8_t addr_len;
char address[SCTP_ADDRMAX];
};
/* draft-ietf-tsvwg-prsctp */
/* PR-SCTP supported parameter */
struct sctp_prsctp_supported_param {
struct sctp_paramhdr ph;
};
/* draft-ietf-tsvwg-addip-sctp */
struct sctp_asconf_paramhdr { /* an ASCONF "parameter" */
struct sctp_paramhdr ph; /* a SCTP parameter header */
u_int32_t correlation_id; /* correlation id for this param */
};
struct sctp_asconf_addr_param { /* an ASCONF address parameter */
struct sctp_asconf_paramhdr aph; /* asconf "parameter" */
struct sctp_ipv6addr_param addrp; /* max storage size */
};
struct sctp_asconf_addrv4_param { /* an ASCONF address (v4) parameter */
struct sctp_asconf_paramhdr aph; /* asconf "parameter" */
struct sctp_ipv4addr_param addrp; /* max storage size */
};
/* ECN Nonce: draft-ladha-sctp-ecn-nonce */
struct sctp_ecn_nonce_supported_param {
struct sctp_paramhdr ph; /* type = 0x8001 len = 4 */
};
struct sctp_supported_chunk_types_param {
struct sctp_paramhdr ph; /* type = 0x8002 len = x */
u_int8_t chunk_types[0];
};
/*
* Structures for DATA chunks
*/
struct sctp_data {
u_int32_t tsn;
u_int16_t stream_id;
u_int16_t stream_sequence;
u_int32_t protocol_id;
/* user data follows */
};
struct sctp_data_chunk {
struct sctp_chunkhdr ch;
struct sctp_data dp;
};
/*
* Structures for the control chunks
*/
/* Initiate (INIT)/Initiate Ack (INIT ACK) */
struct sctp_init {
u_int32_t initiate_tag; /* initiate tag */
u_int32_t a_rwnd; /* a_rwnd */
u_int16_t num_outbound_streams; /* OS */
u_int16_t num_inbound_streams; /* MIS */
u_int32_t initial_tsn; /* I-TSN */
/* optional param's follow */
};
/* state cookie header */
struct sctp_state_cookie { /* this is our definition... */
u_int8_t identification[16]; /* id of who we are */
u_int32_t cookie_life; /* life I will award this cookie */
u_int32_t tie_tag_my_vtag; /* my tag in old association */
u_int32_t tie_tag_peer_vtag; /* peers tag in old association */
u_int32_t peers_vtag; /* peers tag in INIT (for quick ref) */
u_int32_t my_vtag; /* my tag in INIT-ACK (for quick ref) */
struct timeval time_entered; /* the time I built cookie */
u_int32_t address[4]; /* 4 ints/128 bits */
u_int32_t addr_type; /* address type */
u_int32_t laddress[4]; /* my local from address */
u_int32_t laddr_type; /* my local from address type */
u_int32_t scope_id; /* v6 scope id for link-locals */
u_int16_t peerport; /* port address of the peer in the INIT */
u_int16_t myport; /* my port address used in the INIT */
u_int8_t ipv4_addr_legal; /* Are V4 addr legal? */
u_int8_t ipv6_addr_legal; /* Are V6 addr legal? */
u_int8_t local_scope; /* IPv6 local scope flag */
u_int8_t site_scope; /* IPv6 site scope flag */
u_int8_t ipv4_scope; /* IPv4 private addr scope */
u_int8_t loopback_scope; /* loopback scope information */
u_int16_t reserved;
/*
* at the end is tacked on the INIT chunk and the
* INIT-ACK chunk (minus the cookie).
*/
};
struct sctp_inv_mandatory_param {
u_int16_t cause;
u_int16_t length;
u_int32_t num_param;
u_int16_t param;
/*
* We include this to 0 it since only a missing cookie
* will cause this error.
*/
u_int16_t resv;
};
struct sctp_unresolv_addr {
u_int16_t cause;
u_int16_t length;
u_int16_t addr_type;
u_int16_t reserved; /* Only one invalid addr type */
};
/* state cookie parameter */
struct sctp_state_cookie_param {
struct sctp_paramhdr ph;
struct sctp_state_cookie cookie;
};
struct sctp_init_chunk {
struct sctp_chunkhdr ch;
struct sctp_init init;
};
struct sctp_init_msg {
struct sctphdr sh;
struct sctp_init_chunk msg;
};
/* ... used for both INIT and INIT ACK */
#define sctp_init_ack sctp_init
#define sctp_init_ack_chunk sctp_init_chunk
#define sctp_init_ack_msg sctp_init_msg
/* Selective Ack (SACK) */
struct sctp_gap_ack_block {
u_int16_t start; /* Gap Ack block start */
u_int16_t end; /* Gap Ack block end */
};
struct sctp_sack {
u_int32_t cum_tsn_ack; /* cumulative TSN Ack */
u_int32_t a_rwnd; /* updated a_rwnd of sender */
u_int16_t num_gap_ack_blks; /* number of Gap Ack blocks */
u_int16_t num_dup_tsns; /* number of duplicate TSNs */
/* struct sctp_gap_ack_block's follow */
/* u_int32_t duplicate_tsn's follow */
};
struct sctp_sack_chunk {
struct sctp_chunkhdr ch;
struct sctp_sack sack;
};
/* Heartbeat Request (HEARTBEAT) */
struct sctp_heartbeat {
struct sctp_heartbeat_info_param hb_info;
};
struct sctp_heartbeat_chunk {
struct sctp_chunkhdr ch;
struct sctp_heartbeat heartbeat;
};
/* ... used for Heartbeat Ack (HEARTBEAT ACK) */
#define sctp_heartbeat_ack sctp_heartbeat
#define sctp_heartbeat_ack_chunk sctp_heartbeat_chunk
/* Abort Asssociation (ABORT) */
struct sctp_abort_chunk {
struct sctp_chunkhdr ch;
/* optional error cause may follow */
};
struct sctp_abort_msg {
struct sctphdr sh;
struct sctp_abort_chunk msg;
};
/* Shutdown Association (SHUTDOWN) */
struct sctp_shutdown_chunk {
struct sctp_chunkhdr ch;
u_int32_t cumulative_tsn_ack;
};
/* Shutdown Acknowledgment (SHUTDOWN ACK) */
struct sctp_shutdown_ack_chunk {
struct sctp_chunkhdr ch;
};
/* Operation Error (ERROR) */
struct sctp_error_chunk {
struct sctp_chunkhdr ch;
/* optional error causes follow */
};
/* Cookie Echo (COOKIE ECHO) */
struct sctp_cookie_echo_chunk {
struct sctp_chunkhdr ch;
struct sctp_state_cookie cookie;
};
/* Cookie Acknowledgment (COOKIE ACK) */
struct sctp_cookie_ack_chunk {
struct sctp_chunkhdr ch;
};
/* Explicit Congestion Notification Echo (ECNE) */
struct sctp_ecne_chunk {
struct sctp_chunkhdr ch;
u_int32_t tsn;
};
/* Congestion Window Reduced (CWR) */
struct sctp_cwr_chunk {
struct sctp_chunkhdr ch;
u_int32_t tsn;
};
/* Shutdown Complete (SHUTDOWN COMPLETE) */
struct sctp_shutdown_complete_chunk {
struct sctp_chunkhdr ch;
};
/* Oper error holding a stale cookie */
struct sctp_stale_cookie_msg {
struct sctp_paramhdr ph; /* really an error cause */
u_int32_t time_usec;
};
struct sctp_adaption_layer_indication {
struct sctp_paramhdr ph;
u_int32_t indication;
};
struct sctp_cookie_while_shutting_down {
struct sctphdr sh;
struct sctp_chunkhdr ch;
struct sctp_paramhdr ph; /* really an error cause */
};
struct sctp_shutdown_complete_msg {
struct sctphdr sh;
struct sctp_shutdown_complete_chunk shut_cmp;
};
/* draft-ietf-tsvwg-addip-sctp */
/* Address/Stream Configuration Change (ASCONF) */
struct sctp_asconf_chunk {
struct sctp_chunkhdr ch;
u_int32_t serial_number;
/* lookup address parameter (mandatory) */
/* asconf parameters follow */
};
/* Address/Stream Configuration Acknowledge (ASCONF ACK) */
struct sctp_asconf_ack_chunk {
struct sctp_chunkhdr ch;
u_int32_t serial_number;
/* asconf parameters follow */
};
/* draft-ietf-tsvwg-prsctp */
/* Forward Cumulative TSN (FORWARD TSN) */
struct sctp_forward_tsn_chunk {
struct sctp_chunkhdr ch;
u_int32_t new_cumulative_tsn;
/* stream/sequence pairs (sctp_strseq) follow */
};
struct sctp_strseq {
u_int16_t stream;
u_int16_t sequence;
};
struct sctp_forward_tsn_msg {
struct sctphdr sh;
struct sctp_forward_tsn_chunk msg;
};
/* should be a multiple of 4 - 1 aka 3/7/11 etc. */
#define SCTP_NUM_DB_TO_VERIFY 3
struct sctp_chunk_desc {
u_int8_t chunk_type;
u_int8_t data_bytes[SCTP_NUM_DB_TO_VERIFY];
u_int32_t tsn_ifany;
};
struct sctp_pktdrop_chunk {
struct sctp_chunkhdr ch;
u_int32_t bottle_bw;
u_int32_t current_onq;
u_int16_t trunc_len;
u_int16_t reserved;
u_int8_t data[0];
};
#define SCTP_RESET_YOUR 0x01 /* reset your streams and send response */
#define SCTP_RESET_ALL 0x02 /* reset all of your streams */
#define SCTP_RECIPRICAL 0x04 /* reset my streams too */
struct sctp_stream_reset_request {
struct sctp_paramhdr ph;
u_int8_t reset_flags; /* actual request */
u_int8_t reset_pad[3];
u_int32_t reset_req_seq; /* monotonically increasing seq no */
u_int16_t list_of_streams[0]; /* if not all list of streams */
};
#define SCTP_RESET_PERFORMED 0x01 /* Peers sending str was reset */
#define SCTP_RESET_DENIED 0x02 /* Asked for but refused */
struct sctp_stream_reset_response {
struct sctp_paramhdr ph;
u_int8_t reset_flags; /* actual request */
u_int8_t reset_pad[3];
u_int32_t reset_req_seq_resp; /* copied from reset_req reset_req_seq */
u_int32_t reset_at_tsn; /* resetters next TSN to be assigned send wise */
u_int32_t cumulative_tsn; /* resetters cum-ack point receive wise */
u_int16_t list_of_streams[0]; /* if not all list of streams */
};
/* convience structures, note that if you
* are making a request for specific streams
* then the request will need to be an overlay
* structure.
*/
struct sctp_stream_reset_req {
struct sctp_chunkhdr ch;
struct sctp_stream_reset_request sr_req;
};
struct sctp_stream_reset_resp {
struct sctp_chunkhdr ch;
struct sctp_stream_reset_response sr_resp;
};
/*
* we pre-reserve enough room for a ECNE or CWR AND a SACK with no
* missing pieces. If ENCE is missing we could have a couple of blocks.
* This way we optimize so we MOST likely can bundle a SACK/ECN with
* the smallest size data chunk I will split into. We could increase
* throughput slightly by taking out these two but the 24-sack/8-CWR
* i.e. 32 bytes I pre-reserve I feel is worth it for now.
*/
#ifndef SCTP_MAX_OVERHEAD
#ifdef AF_INET6
#define SCTP_MAX_OVERHEAD (sizeof(struct sctp_data_chunk) + \
sizeof(struct sctphdr) + \
sizeof(struct sctp_ecne_chunk) + \
sizeof(struct sctp_sack_chunk) + \
sizeof(struct ip6_hdr))
#define SCTP_MED_OVERHEAD (sizeof(struct sctp_data_chunk) + \
sizeof(struct sctphdr) + \
sizeof(struct ip6_hdr))
#define SCTP_MIN_OVERHEAD (sizeof(struct ip6_hdr) + \
sizeof(struct sctphdr))
#else
#define SCTP_MAX_OVERHEAD (sizeof(struct sctp_data_chunk) + \
sizeof(struct sctphdr) + \
sizeof(struct sctp_ecne_chunk) + \
sizeof(struct sctp_sack_chunk) + \
sizeof(struct ip))
#define SCTP_MED_OVERHEAD (sizeof(struct sctp_data_chunk) + \
sizeof(struct sctphdr) + \
sizeof(struct ip))
#define SCTP_MIN_OVERHEAD (sizeof(struct ip) + \
sizeof(struct sctphdr))
#endif /* AF_INET6 */
#endif /* !SCTP_MAX_OVERHEAD */
#define SCTP_MED_V4_OVERHEAD (sizeof(struct sctp_data_chunk) + \
sizeof(struct sctphdr) + \
sizeof(struct ip))
#define SCTP_MIN_V4_OVERHEAD (sizeof(struct ip) + \
sizeof(struct sctphdr))
#endif /* !__SCTP_HEADER_H__ */

4704
sys/netinet/sctp_indata.c Normal file

File diff suppressed because it is too large Load Diff

63
sys/netinet/sctp_indata.h Normal file
View File

@ -0,0 +1,63 @@
/* $KAME: sctp_indata.h,v 1.9 2005/03/06 16:04:17 itojun Exp $ */
/* $NetBSD: sctp_indata.h,v 1.1 2015/10/13 21:28:35 rjs Exp $ */
#ifndef __SCTP_INDATA_H__
#define __SCTP_INDATA_H__
/*
* 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.
*/
#if defined(_KERNEL)
int sctp_deliver_data(struct sctp_tcb *, struct sctp_association *,
struct sctp_tmit_chunk *, int);
void sctp_set_rwnd(struct sctp_tcb *, struct sctp_association *);
void sctp_handle_sack(struct sctp_sack_chunk *, struct sctp_tcb *,
struct sctp_nets *, int *);
/* draft-ietf-tsvwg-usctp */
void sctp_handle_forward_tsn(struct sctp_tcb *,
struct sctp_forward_tsn_chunk *, int *);
struct sctp_tmit_chunk *
sctp_try_advance_peer_ack_point(struct sctp_tcb *, struct sctp_association *);
void sctp_service_queues(struct sctp_tcb *, struct sctp_association *, int have_lock);
void sctp_update_acked(struct sctp_tcb *, struct sctp_shutdown_chunk *,
struct sctp_nets *, int *);
int sctp_process_data(struct mbuf **, int, int *, int, struct sctphdr *,
struct sctp_inpcb *, struct sctp_tcb *, struct sctp_nets *, u_int32_t *);
void sctp_sack_check(struct sctp_tcb *, int, int, int *);
#endif
#endif

4300
sys/netinet/sctp_input.c Normal file

File diff suppressed because it is too large Load Diff

45
sys/netinet/sctp_input.h Normal file
View File

@ -0,0 +1,45 @@
/* $KAME: sctp_input.h,v 1.6 2005/03/06 16:04:17 itojun Exp $ */
/* $NetBSD: sctp_input.h,v 1.1 2015/10/13 21:28:35 rjs Exp $ */
#ifndef __SCTP_INPUT_H__
#define __SCTP_INPUT_H__
/*
* Copyright (C) 2002 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.
*/
#if defined(_KERNEL)
int sctp_common_input_processing(struct mbuf **, int, int, int,
struct sctphdr *, struct sctp_chunkhdr *, struct sctp_inpcb *,
struct sctp_tcb *, struct sctp_nets *, u_int8_t);
void
sctp_handle_stream_reset_response(struct sctp_tcb *, struct sctp_stream_reset_response *resp);
#endif
#endif

10179
sys/netinet/sctp_output.c Normal file

File diff suppressed because it is too large Load Diff

122
sys/netinet/sctp_output.h Normal file
View File

@ -0,0 +1,122 @@
/* $KAME: sctp_output.h,v 1.14 2005/03/06 16:04:18 itojun Exp $ */
/* $NetBSD: sctp_output.h,v 1.1 2015/10/13 21:28:35 rjs Exp $ */
#ifndef __SCTP_OUTPUT_H__
#define __SCTP_OUTPUT_H__
/*
* 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 <netinet/sctp_header.h>
#if defined(_KERNEL)
void sctp_send_initiate(struct sctp_inpcb *, struct sctp_tcb *);
void sctp_send_initiate_ack(struct sctp_inpcb *, struct sctp_tcb *,
struct mbuf *, int, int, struct sctphdr *, struct sctp_init_chunk *);
struct mbuf *sctp_arethere_unrecognized_parameters(struct mbuf *, int, int *,
struct sctp_chunkhdr *);
void sctp_queue_op_err(struct sctp_tcb *, struct mbuf *);
int sctp_send_cookie_echo(struct mbuf *, int, struct sctp_tcb *,
struct sctp_nets *);
int sctp_send_cookie_ack(struct sctp_tcb *);
void sctp_send_heartbeat_ack(struct sctp_tcb *, struct mbuf *, int, int,
struct sctp_nets *);
int sctp_is_addr_restricted(struct sctp_tcb *, struct sockaddr *);
struct in_addr sctp_ipv4_source_address_selection(struct sctp_inpcb *,
struct sctp_tcb *, struct route *, struct sctp_nets *, int);
struct in6_addr sctp_ipv6_source_address_selection(struct sctp_inpcb *,
struct sctp_tcb *, struct route *, struct sctp_nets *, int);
int sctp_send_shutdown(struct sctp_tcb *, struct sctp_nets *);
int sctp_send_shutdown_ack(struct sctp_tcb *, struct sctp_nets *);
int sctp_send_shutdown_complete(struct sctp_tcb *, struct sctp_nets *);
int sctp_send_shutdown_complete2(struct mbuf *, int, struct sctphdr *);
int sctp_send_asconf(struct sctp_tcb *, struct sctp_nets *);
int sctp_send_asconf_ack(struct sctp_tcb *, uint32_t);
int sctp_get_frag_point(struct sctp_tcb *, struct sctp_association *);
void sctp_toss_old_cookies(struct sctp_association *);
void sctp_toss_old_asconf(struct sctp_tcb *);
void sctp_fix_ecn_echo(struct sctp_association *);
int sctp_output(struct sctp_inpcb *, struct mbuf *, struct sockaddr *,
struct mbuf *, struct lwp *, int);
int sctp_chunk_output(struct sctp_inpcb *, struct sctp_tcb *, int);
void sctp_send_abort_tcb(struct sctp_tcb *, struct mbuf *);
void send_forward_tsn(struct sctp_tcb *, struct sctp_association *);
void sctp_send_sack(struct sctp_tcb *);
int sctp_send_hb(struct sctp_tcb *, int, struct sctp_nets *);
void sctp_send_ecn_echo(struct sctp_tcb *, struct sctp_nets *, uint32_t);
void
sctp_send_packet_dropped(struct sctp_tcb *, struct sctp_nets *, struct mbuf *,
int, int);
void sctp_send_cwr(struct sctp_tcb *, struct sctp_nets *, uint32_t);
void
sctp_send_str_reset_ack(struct sctp_tcb *, struct sctp_stream_reset_request *);
void
sctp_send_str_reset_req(struct sctp_tcb *, int, uint16_t *, uint8_t, uint8_t);
void sctp_send_abort(struct mbuf *, int, struct sctphdr *, uint32_t,
struct mbuf *);
void sctp_send_operr_to(struct mbuf *, int, struct mbuf *, uint32_t);
int
sctp_sosend(struct socket *, struct sockaddr *, struct uio *,
struct mbuf *, struct mbuf *, int, struct lwp *);
#endif
#endif

4818
sys/netinet/sctp_pcb.c Normal file

File diff suppressed because it is too large Load Diff

761
sys/netinet/sctp_pcb.h Normal file
View File

@ -0,0 +1,761 @@
/* $KAME: sctp_pcb.h,v 1.21 2005/07/16 01:18:47 suz Exp $ */
/* $NetBSD: sctp_pcb.h,v 1.1 2015/10/13 21:28:35 rjs Exp $ */
#ifndef __SCTP_PCB_H__
#define __SCTP_PCB_H__
/*
* Copyright (c) 2001, 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Cisco Systems, Inc.
* 4. 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 CISCO SYSTEMS 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 CISCO SYSTEMS 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.
*/
/*
* We must have V6 so the size of the proto can be calculated. Otherwise
* we would not allocate enough for Net/Open BSD :-<
*/
#include <net/if.h>
#include <netinet/ip6.h>
#include <netinet6/ip6_var.h>
#include <netinet6/ip6protosw.h>
#include <netinet6/in6_var.h>
#include <netinet6/in6_pcb.h>
#include <netinet/sctp.h>
#include <netinet/sctp_constants.h>
LIST_HEAD(sctppcbhead, sctp_inpcb);
LIST_HEAD(sctpasochead, sctp_tcb);
TAILQ_HEAD(sctpsocketq, sctp_socket_q_list);
LIST_HEAD(sctpladdr, sctp_laddr);
LIST_HEAD(sctpvtaghead, sctp_tagblock);
#include <netinet/sctp_structs.h>
#include <netinet/sctp_uio.h>
/*
* PCB flags
*/
#define SCTP_PCB_FLAGS_UDPTYPE 0x00000001
#define SCTP_PCB_FLAGS_TCPTYPE 0x00000002
#define SCTP_PCB_FLAGS_BOUNDALL 0x00000004
#define SCTP_PCB_FLAGS_ACCEPTING 0x00000008
#define SCTP_PCB_FLAGS_UNBOUND 0x00000010
#define SCTP_PCB_FLAGS_DO_ASCONF 0x00000020
#define SCTP_PCB_FLAGS_AUTO_ASCONF 0x00000040
/* socket options */
#define SCTP_PCB_FLAGS_NODELAY 0x00000100
#define SCTP_PCB_FLAGS_AUTOCLOSE 0x00000200
#define SCTP_PCB_FLAGS_RECVDATAIOEVNT 0x00000400
#define SCTP_PCB_FLAGS_RECVASSOCEVNT 0x00000800
#define SCTP_PCB_FLAGS_RECVPADDREVNT 0x00001000
#define SCTP_PCB_FLAGS_RECVPEERERR 0x00002000
#define SCTP_PCB_FLAGS_RECVSENDFAILEVNT 0x00004000
#define SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT 0x00008000
#define SCTP_PCB_FLAGS_ADAPTIONEVNT 0x00010000
#define SCTP_PCB_FLAGS_PDAPIEVNT 0x00020000
#define SCTP_PCB_FLAGS_STREAM_RESETEVNT 0x00040000
#define SCTP_PCB_FLAGS_NO_FRAGMENT 0x00080000
/* TCP model support */
#define SCTP_PCB_FLAGS_CONNECTED 0x00100000
#define SCTP_PCB_FLAGS_IN_TCPPOOL 0x00200000
#define SCTP_PCB_FLAGS_DONT_WAKE 0x00400000
#define SCTP_PCB_FLAGS_WAKEOUTPUT 0x00800000
#define SCTP_PCB_FLAGS_WAKEINPUT 0x01000000
#define SCTP_PCB_FLAGS_BOUND_V6 0x02000000
#define SCTP_PCB_FLAGS_NEEDS_MAPPED_V4 0x04000000
#define SCTP_PCB_FLAGS_BLOCKING_IO 0x08000000
#define SCTP_PCB_FLAGS_SOCKET_GONE 0x10000000
#define SCTP_PCB_FLAGS_SOCKET_ALLGONE 0x20000000
/* flags to copy to new PCB */
#define SCTP_PCB_COPY_FLAGS 0x0707ff64
#define SCTP_PCBHASH_ALLADDR(port, mask) (port & mask)
#define SCTP_PCBHASH_ASOC(tag, mask) (tag & mask)
struct sctp_laddr {
LIST_ENTRY(sctp_laddr) sctp_nxt_addr; /* next in list */
struct ifaddr *ifa;
};
struct sctp_timewait {
uint32_t tv_sec_at_expire; /* the seconds from boot to expire */
uint32_t v_tag; /* the vtag that can not be reused */
};
struct sctp_tagblock {
LIST_ENTRY(sctp_tagblock) sctp_nxt_tagblock;
struct sctp_timewait vtag_block[SCTP_NUMBER_IN_VTAG_BLOCK];
};
struct sctp_epinfo {
struct sctpasochead *sctp_asochash;
u_long hashasocmark;
struct sctppcbhead *sctp_ephash;
u_long hashmark;
/*
* The TCP model represents a substantial overhead in that we get
* an additional hash table to keep explicit connections in. The
* listening TCP endpoint will exist in the usual ephash above and
* accept only INIT's. It will be incapable of sending off an INIT.
* When a dg arrives we must look in the normal ephash. If we find
* a TCP endpoint that will tell us to go to the specific endpoint
* hash and re-hash to find the right assoc/socket. If we find a
* UDP model socket we then must complete the lookup. If this fails,
* i.e. no association can be found then we must continue to see if
* a sctp_peeloff()'d socket is in the tcpephash (a spun off socket
* acts like a TCP model connected socket).
*/
struct sctppcbhead *sctp_tcpephash;
u_long hashtcpmark;
uint32_t hashtblsize;
struct sctppcbhead listhead;
struct sctpiterators iteratorhead;
/* ep zone info */
#if defined(__FreeBSD__) || defined(__APPLE__)
#if __FreeBSD_version >= 500000
struct uma_zone *ipi_zone_ep;
struct uma_zone *ipi_zone_asoc;
struct uma_zone *ipi_zone_laddr;
struct uma_zone *ipi_zone_net;
struct uma_zone *ipi_zone_chunk;
struct uma_zone *ipi_zone_sockq;
#else
struct vm_zone *ipi_zone_ep;
struct vm_zone *ipi_zone_asoc;
struct vm_zone *ipi_zone_laddr;
struct vm_zone *ipi_zone_net;
struct vm_zone *ipi_zone_chunk;
struct vm_zone *ipi_zone_sockq;
#endif
#endif
#if defined(__NetBSD__) || defined(__OpenBSD__)
struct pool ipi_zone_ep;
struct pool ipi_zone_asoc;
struct pool ipi_zone_laddr;
struct pool ipi_zone_net;
struct pool ipi_zone_chunk;
struct pool ipi_zone_sockq;
struct pool ipi_zone_hash;
#endif
#if defined(__FreeBSD__) && __FreeBSD_version >= 503000
struct mtx ipi_ep_mtx;
struct mtx it_mtx;
#elif 0 /* defined(__NetBSD__) */
krwlock_t ipi_ep_mtx;
kmutex_t it_mtx;
#endif
u_int ipi_count_ep;
u_quad_t ipi_gencnt_ep;
/* assoc/tcb zone info */
u_int ipi_count_asoc;
u_quad_t ipi_gencnt_asoc;
/* local addrlist zone info */
u_int ipi_count_laddr;
u_quad_t ipi_gencnt_laddr;
/* remote addrlist zone info */
u_int ipi_count_raddr;
u_quad_t ipi_gencnt_raddr;
/* chunk structure list for output */
u_int ipi_count_chunk;
u_quad_t ipi_gencnt_chunk;
/* socket queue zone info */
u_int ipi_count_sockq;
u_quad_t ipi_gencnt_sockq;
struct sctpvtaghead vtag_timewait[SCTP_STACK_VTAG_HASH_SIZE];
#ifdef _SCTP_NEEDS_CALLOUT_
struct calloutlist callqueue;
#endif /* _SCTP_NEEDS_CALLOUT_ */
uint32_t mbuf_track;
/* for port allocations */
uint16_t lastport;
uint16_t lastlow;
uint16_t lasthi;
};
extern uint32_t sctp_pegs[SCTP_NUMBER_OF_PEGS];
/*
* Here we have all the relevant information for each SCTP entity created.
* We will need to modify this as approprate. We also need to figure out
* how to access /dev/random.
*/
struct sctp_pcb {
unsigned int time_of_secret_change; /* number of seconds from timeval.tv_sec */
uint32_t secret_key[SCTP_HOW_MANY_SECRETS][SCTP_NUMBER_OF_SECRETS];
unsigned int size_of_a_cookie;
unsigned int sctp_timeoutticks[SCTP_NUM_TMRS];
unsigned int sctp_minrto;
unsigned int sctp_maxrto;
unsigned int initial_rto;
int initial_init_rto_max;
uint32_t sctp_sws_sender;
uint32_t sctp_sws_receiver;
/* various thresholds */
/* Max times I will init at a guy */
uint16_t max_init_times;
/* Max times I will send before we consider someone dead */
uint16_t max_send_times;
uint16_t def_net_failure;
/* number of streams to pre-open on a association */
uint16_t pre_open_stream_count;
uint16_t max_open_streams_intome;
/* random number generator */
uint32_t random_counter;
uint8_t random_numbers[SCTP_SIGNATURE_ALOC_SIZE];
uint8_t random_store[SCTP_SIGNATURE_ALOC_SIZE];
/*
* This timer is kept running per endpoint. When it fires it
* will change the secret key. The default is once a hour
*/
struct sctp_timer signature_change;
int def_cookie_life;
/* defaults to 0 */
int auto_close_time;
uint32_t initial_sequence_debug;
uint32_t adaption_layer_indicator;
char store_at;
uint8_t max_burst;
char current_secret_number;
char last_secret_number;
};
#ifndef SCTP_ALIGNMENT
#define SCTP_ALIGNMENT 32
#endif
#ifndef SCTP_ALIGNM1
#define SCTP_ALIGNM1 (SCTP_ALIGNMENT-1)
#endif
#define sctp_lport ip_inp.inp.inp_lport
struct sctp_socket_q_list {
struct sctp_tcb *tcb;
TAILQ_ENTRY(sctp_socket_q_list) next_sq;
};
struct sctp_inpcb {
/*
* put an inpcb in front of it all, kind of a waste but we need
* to for compatability with all the other stuff.
*/
union {
struct inpcb inp;
char align[(sizeof(struct in6pcb) + SCTP_ALIGNM1) &
~SCTP_ALIGNM1];
} ip_inp;
LIST_ENTRY(sctp_inpcb) sctp_list; /* lists all endpoints */
/* hash of all endpoints for model */
LIST_ENTRY(sctp_inpcb) sctp_hash;
/* count of local addresses bound, 0 if bound all */
int laddr_count;
/* list of addrs in use by the EP */
struct sctpladdr sctp_addr_list;
/* used for source address selection rotation */
struct sctp_laddr *next_addr_touse;
struct ifnet *next_ifn_touse;
/* back pointer to our socket */
struct socket *sctp_socket;
uint32_t sctp_flags; /* flag set */
struct sctp_pcb sctp_ep; /* SCTP ep data */
/* head of the hash of all associations */
struct sctpasochead *sctp_tcbhash;
u_long sctp_hashmark;
/* head of the list of all associations */
struct sctpasochead sctp_asoc_list;
/* queue of TCB's waiting to stuff data up the socket */
struct sctpsocketq sctp_queue_list;
void *sctp_tcb_at_block;
struct sctp_iterator *inp_starting_point_for_iterator;
int error_on_block;
uint32_t sctp_frag_point;
uint32_t sctp_vtag_first;
struct mbuf *pkt, *pkt_last, *sb_last_mpkt;
struct mbuf *control;
#if !(defined(__FreeBSD__) || defined(__APPLE__))
#ifndef INP_IPV6
#define INP_IPV6 0x1
#endif
#ifndef INP_IPV4
#define INP_IPV4 0x2
#endif
u_char inp_vflag;
u_char inp_ip_ttl;
u_char inp_ip_tos;
u_char inp_ip_resv;
#endif
#if defined(__FreeBSD__) && __FreeBSD_version >= 503000
struct mtx inp_mtx;
struct mtx inp_create_mtx;
u_int32_t refcount;
#elif defined(__NetBSD__)
kmutex_t inp_mtx;
kmutex_t inp_create_mtx;
u_int32_t refcount;
#endif
};
struct sctp_tcb {
struct socket *sctp_socket; /* back pointer to socket */
struct sctp_inpcb *sctp_ep; /* back pointer to ep */
LIST_ENTRY(sctp_tcb) sctp_tcbhash; /* next link in hash table */
LIST_ENTRY(sctp_tcb) sctp_tcblist; /* list of all of the TCB's */
LIST_ENTRY(sctp_tcb) sctp_asocs;
struct sctp_association asoc;
uint16_t rport; /* remote port in network format */
uint16_t resv;
#if defined(__FreeBSD__) && __FreeBSD_version >= 503000
struct mtx tcb_mtx;
#elif defined(__NetBSD__)
kmutex_t tcb_mtx;
#endif
};
#if defined(__FreeBSD__) && __FreeBSD_version >= 503000
/* General locking concepts:
* The goal of our locking is to of course provide
* consistency and yet minimize overhead. We will
* attempt to use non-recursive locks which are supposed
* to be quite inexpensive. Now in order to do this the goal
* is that most functions are not aware of locking. Once we
* have a TCB we lock it and unlock when we are through. This
* means that the TCB lock is kind-of a "global" lock when
* working on an association. Caution must be used when
* asserting a TCB_LOCK since if we recurse we deadlock.
*
* Most other locks (INP and INFO) attempt to localize
* the locking i.e. we try to contain the lock and
* unlock within the function that needs to lock it. This
* sometimes mean we do extra locks and unlocks and loose
* a bit of efficency, but if the performance statements about
* non-recursive locks are true this should not be a problem.
* One issue that arises with this only lock when needed
* is that if an implicit association setup is done we
* have a problem. If at the time I lookup an association
* I have NULL in the tcb return, by the time I call to
* create the association some other processor could
* have created it. This is what the CREATE lock on
* the endpoint. Places where we will be implicitly
* creating the association OR just creating an association
* (the connect call) will assert the CREATE_INP lock. This
* will assure us that during all the lookup of INP and INFO
* if another creator is also locking/looking up we can
* gate the two to synchronize. So the CREATE_INP lock is
* also another one we must use extreme caution in locking
* to make sure we don't hit a re-entrancy issue.
*
* For non FreeBSD 5.x and above we provide a bunch
* of EMPTY lock macro's so we can blatantly put locks
* everywhere and they reduce to nothing on NetBSD/OpenBSD
* and FreeBSD 4.x
*
*/
/* When working with the global SCTP lists we lock and unlock
* the INP_INFO lock. So when we go to lookup an association
* we will want to do a SCTP_INP_INFO_RLOCK() and then when
* we want to add a new association to the sctppcbinfo list's
* we will do a SCTP_INP_INFO_WLOCK().
*/
/*
* FIX ME, all locks right now have a
* recursive check/panic to validate that I
* don't have any lock recursion going on.
*/
#define SCTP_INP_INFO_LOCK_INIT() \
mtx_init(&sctppcbinfo.ipi_ep_mtx, "sctp", "inp_info", MTX_DEF)
#ifdef xyzzy
#define SCTP_INP_INFO_RLOCK() do { \
if (mtx_owned(&sctppcbinfo.ipi_ep_mtx)) \
panic("INP INFO Recursive Lock-R"); \
mtx_lock(&sctppcbinfo.ipi_ep_mtx); \
} while (0)
#define SCTP_INP_INFO_WLOCK() do { \
if (mtx_owned(&sctppcbinfo.ipi_ep_mtx)) \
panic("INP INFO Recursive Lock-W"); \
mtx_lock(&sctppcbinfo.ipi_ep_mtx); \
} while (0)
#else
void SCTP_INP_INFO_RLOCK(void);
void SCTP_INP_INFO_WLOCK(void);
#endif
#define SCTP_INP_INFO_RUNLOCK() mtx_unlock(&sctppcbinfo.ipi_ep_mtx)
#define SCTP_INP_INFO_WUNLOCK() mtx_unlock(&sctppcbinfo.ipi_ep_mtx)
/* The INP locks we will use for locking an SCTP endpoint, so for
* example if we want to change something at the endpoint level for
* example random_store or cookie secrets we lock the INP level.
*/
#define SCTP_INP_LOCK_INIT(_inp) \
mtx_init(&(_inp)->inp_mtx, "sctp", "inp", MTX_DEF | MTX_DUPOK)
#define SCTP_ASOC_CREATE_LOCK_INIT(_inp) \
mtx_init(&(_inp)->inp_create_mtx, "sctp", "inp_create", \
MTX_DEF | MTX_DUPOK)
#define SCTP_INP_LOCK_DESTROY(_inp) mtx_destroy(&(_inp)->inp_mtx)
#define SCTP_ASOC_CREATE_LOCK_DESTROY(_inp) mtx_destroy(&(_inp)->inp_create_mtx)
#ifdef xyzzy
#define SCTP_INP_RLOCK(_inp) do { \
struct sctp_tcb *xx_stcb; \
xx_stcb = LIST_FIRST(&_inp->sctp_asoc_list); \
if (xx_stcb) \
if (mtx_owned(&(xx_stcb)->tcb_mtx)) \
panic("I own TCB lock?"); \
if (mtx_owned(&(_inp)->inp_mtx)) \
panic("INP Recursive Lock-R"); \
mtx_lock(&(_inp)->inp_mtx); \
} while (0)
#define SCTP_INP_WLOCK(_inp) do { \
struct sctp_tcb *xx_stcb; \
xx_stcb = LIST_FIRST(&_inp->sctp_asoc_list); \
if (xx_stcb) \
if (mtx_owned(&(xx_stcb)->tcb_mtx)) \
panic("I own TCB lock?"); \
if (mtx_owned(&(_inp)->inp_mtx)) \
panic("INP Recursive Lock-W"); \
mtx_lock(&(_inp)->inp_mtx); \
} while (0)
#else
void SCTP_INP_RLOCK(struct sctp_inpcb *);
void SCTP_INP_WLOCK(struct sctp_inpcb *);
#endif
#define SCTP_INP_INCR_REF(_inp) _inp->refcount++
#define SCTP_INP_DECR_REF(_inp) do { \
if (_inp->refcount > 0) \
_inp->refcount--; \
else \
panic("bad inp refcount"); \
}while (0)
#define SCTP_ASOC_CREATE_LOCK(_inp) do { \
if (mtx_owned(&(_inp)->inp_create_mtx)) \
panic("INP Recursive CREATE"); \
mtx_lock(&(_inp)->inp_create_mtx); \
} while (0)
#define SCTP_INP_RUNLOCK(_inp) mtx_unlock(&(_inp)->inp_mtx)
#define SCTP_INP_WUNLOCK(_inp) mtx_unlock(&(_inp)->inp_mtx)
#define SCTP_ASOC_CREATE_UNLOCK(_inp) mtx_unlock(&(_inp)->inp_create_mtx)
/* For the majority of things (once we have found the association) we
* will lock the actual association mutex. This will protect all
* the assoiciation level queues and streams and such. We will
* need to lock the socket layer when we stuff data up into
* the receiving sb_mb. I.e. we will need to do an extra
* SOCKBUF_LOCK(&so->so_rcv) even though the association is
* locked.
*/
#define SCTP_TCB_LOCK_INIT(_tcb) \
mutex_init(&(_tcb)->tcb_mtx, MUTEX_DEFAULT, IPL_NET)
#define SCTP_TCB_LOCK_DESTROY(_tcb) mtx_destroy(&(_tcb)->tcb_mtx)
#define SCTP_TCB_LOCK(_tcb) do { \
if (!mtx_owned(&(_tcb->sctp_ep->inp_mtx))) \
panic("TCB locking and no INP lock"); \
if (mtx_owned(&(_tcb)->tcb_mtx)) \
panic("TCB Lock-recursive"); \
mtx_lock(&(_tcb)->tcb_mtx); \
} while (0)
#define SCTP_TCB_UNLOCK(_tcb) mtx_unlock(&(_tcb)->tcb_mtx)
#define SCTP_ITERATOR_LOCK_INIT() \
mtx_init(&sctppcbinfo.it_mtx, "sctp", "iterator", MTX_DEF)
#define SCTP_ITERATOR_LOCK() do { \
if (mtx_owned(&sctppcbinfo.it_mtx)) \
panic("Iterator Lock"); \
mtx_lock(&sctppcbinfo.it_mtx); \
} while (0)
#define SCTP_ITERATOR_UNLOCK() mtx_unlock(&sctppcbinfo.it_mtx)
#define SCTP_ITERATOR_LOCK_DESTROY() mtx_destroy(&sctppcbinfo.it_mtx)
#elif 0 /* defined(__NetBSD__) */
#define SCTP_INP_INFO_LOCK_INIT() \
rw_init(&sctppcbinfo.ipi_ep_mtx)
#define SCTP_INP_INFO_RLOCK() do { \
rw_enter(&sctppcbinfo.ipi_ep_mtx, RW_READER); \
} while (0)
#define SCTP_INP_INFO_WLOCK() do { \
rw_enter(&sctppcbinfo.ipi_ep_mtx, RW_WRITER); \
} while (0)
#define SCTP_INP_INFO_RUNLOCK() rw_exit(&sctppcbinfo.ipi_ep_mtx)
#define SCTP_INP_INFO_WUNLOCK() rw_exit(&sctppcbinfo.ipi_ep_mtx)
/* The INP locks we will use for locking an SCTP endpoint, so for
* example if we want to change something at the endpoint level for
* example random_store or cookie secrets we lock the INP level.
*/
#define SCTP_INP_LOCK_INIT(_inp) \
mutex_init(&(_inp)->inp_mtx, MUTEX_DEFAULT, IPL_NET)
#define SCTP_ASOC_CREATE_LOCK_INIT(_inp) \
mutex_init(&(_inp)->inp_create_mtx, MUTEX_DEFAULT, IPL_NET)
#define SCTP_INP_LOCK_DESTROY(_inp) mutex_destroy(&(_inp)->inp_mtx)
#define SCTP_ASOC_CREATE_LOCK_DESTROY(_inp) mutex_destroy(&(_inp)->inp_create_mtx)
#define SCTP_INP_RLOCK(_inp) do { \
mutex_enter(&(_inp)->inp_mtx); \
} while (0)
#define SCTP_INP_WLOCK(_inp) do { \
mutex_enter(&(_inp)->inp_mtx); \
} while (0)
#define SCTP_INP_INCR_REF(_inp) atomic_add_int(&((_inp)->refcount), 1)
#define SCTP_INP_DECR_REF(_inp) atomic_add_int(&((_inp)->refcount), -1)
#define SCTP_ASOC_CREATE_LOCK(_inp) do { \
mutex_enter(&(_inp)->inp_create_mtx); \
} while (0)
#define SCTP_INP_RUNLOCK(_inp) mutex_exit(&(_inp)->inp_mtx)
#define SCTP_INP_WUNLOCK(_inp) mutex_exit(&(_inp)->inp_mtx)
#define SCTP_ASOC_CREATE_UNLOCK(_inp) mutex_exit(&(_inp)->inp_create_mtx)
/* For the majority of things (once we have found the association) we
* will lock the actual association mutex. This will protect all
* the assoiciation level queues and streams and such. We will
* need to lock the socket layer when we stuff data up into
* the receiving sb_mb. I.e. we will need to do an extra
* SOCKBUF_LOCK(&so->so_rcv) even though the association is
* locked.
*/
#define SCTP_TCB_LOCK_INIT(_tcb) \
mutex_init(&(_tcb)->tcb_mtx, MUTEX_DEFAULT, IPL_NET)
#define SCTP_TCB_LOCK_DESTROY(_tcb) mutex_destroy(&(_tcb)->tcb_mtx)
#define SCTP_TCB_LOCK(_tcb) do { \
mutex_enter(&(_tcb)->tcb_mtx); \
} while (0)
#define SCTP_TCB_UNLOCK(_tcb) mutex_exit(&(_tcb)->tcb_mtx)
#define SCTP_ITERATOR_LOCK_INIT() \
mutex_init(&sctppcbinfo.it_mtx, MUTEX_DEFAULT, IPL_NET)
#define SCTP_ITERATOR_LOCK() do { \
if (mutex_owned(&sctppcbinfo.it_mtx)) \
panic("Iterator Lock"); \
mutex_enter(&sctppcbinfo.it_mtx); \
} while (0)
#define SCTP_ITERATOR_UNLOCK() mutex_exit(&sctppcbinfo.it_mtx)
#define SCTP_ITERATOR_LOCK_DESTROY() mutex_destroy(&sctppcbinfo.it_mtx)
#else
/* Empty Lock declarations for all other
* platforms pre-process away to nothing.
*/
/* Lock for INFO stuff */
#define SCTP_INP_INFO_LOCK_INIT()
#define SCTP_INP_INFO_RLOCK()
#define SCTP_INP_INFO_RLOCK()
#define SCTP_INP_INFO_WLOCK()
#define SCTP_INP_INFO_RUNLOCK()
#define SCTP_INP_INFO_WUNLOCK()
/* Lock for INP */
#define SCTP_INP_LOCK_INIT(_inp)
#define SCTP_INP_LOCK_DESTROY(_inp)
#define SCTP_INP_RLOCK(_inp)
#define SCTP_INP_RUNLOCK(_inp)
#define SCTP_INP_WLOCK(_inp)
#define SCTP_INP_INCR_REF(_inp)
#define SCTP_INP_DECR_REF(_inp)
#define SCTP_INP_WUNLOCK(_inp)
#define SCTP_ASOC_CREATE_LOCK_INIT(_inp)
#define SCTP_ASOC_CREATE_LOCK_DESTROY(_inp)
#define SCTP_ASOC_CREATE_LOCK(_inp)
#define SCTP_ASOC_CREATE_UNLOCK(_inp)
/* Lock for TCB */
#define SCTP_TCB_LOCK_INIT(_tcb)
#define SCTP_TCB_LOCK_DESTROY(_tcb)
#define SCTP_TCB_LOCK(_tcb)
#define SCTP_TCB_UNLOCK(_tcb)
/* iterator locks */
#define SCTP_ITERATOR_LOCK_INIT()
#define SCTP_ITERATOR_LOCK()
#define SCTP_ITERATOR_UNLOCK()
#define SCTP_ITERATOR_LOCK_DESTROY()
#endif
#if defined(_KERNEL)
extern struct sctp_epinfo sctppcbinfo;
extern int sctp_auto_asconf;
int SCTP6_ARE_ADDR_EQUAL(const struct in6_addr *a, const struct in6_addr *b);
void sctp_fill_pcbinfo(struct sctp_pcbinfo *);
struct sctp_nets *sctp_findnet(struct sctp_tcb *, struct sockaddr *);
struct sctp_inpcb *sctp_pcb_findep(struct sockaddr *, int, int);
int sctp_inpcb_bind(struct socket *, struct sockaddr *, struct lwp *);
struct sctp_tcb *sctp_findassociation_addr(struct mbuf *, int, int,
struct sctphdr *, struct sctp_chunkhdr *, struct sctp_inpcb **,
struct sctp_nets **);
struct sctp_tcb *sctp_findassociation_addr_sa(struct sockaddr *,
struct sockaddr *, struct sctp_inpcb **, struct sctp_nets **, int);
void sctp_move_pcb_and_assoc(struct sctp_inpcb *, struct sctp_inpcb *,
struct sctp_tcb *);
/*
* For this call ep_addr, the to is the destination endpoint address
* of the peer (relative to outbound). The from field is only used if
* the TCP model is enabled and helps distingush amongst the subset
* bound (non-boundall). The TCP model MAY change the actual ep field,
* this is why it is passed.
*/
struct sctp_tcb *sctp_findassociation_ep_addr(struct sctp_inpcb **,
struct sockaddr *, struct sctp_nets **, struct sockaddr *, struct sctp_tcb *);
struct sctp_tcb *sctp_findassociation_ep_asocid(struct sctp_inpcb *, vaddr_t);
struct sctp_tcb *sctp_findassociation_ep_asconf(struct mbuf *, int, int,
struct sctphdr *, struct sctp_inpcb **, struct sctp_nets **);
int sctp_inpcb_alloc(struct socket *);
int sctp_is_address_on_local_host(struct sockaddr *addr);
void sctp_inpcb_free(struct sctp_inpcb *, int);
struct sctp_tcb *sctp_aloc_assoc(struct sctp_inpcb *, struct sockaddr *,
int, int *, uint32_t);
void sctp_free_assoc(struct sctp_inpcb *, struct sctp_tcb *);
int sctp_add_local_addr_ep(struct sctp_inpcb *, struct ifaddr *);
int sctp_insert_laddr(struct sctpladdr *, struct ifaddr *);
void sctp_remove_laddr(struct sctp_laddr *);
int sctp_del_local_addr_ep(struct sctp_inpcb *, struct ifaddr *);
int sctp_del_local_addr_ep_sa(struct sctp_inpcb *, struct sockaddr *);
int sctp_add_remote_addr(struct sctp_tcb *, struct sockaddr *, int, int);
int sctp_del_remote_addr(struct sctp_tcb *, struct sockaddr *);
void sctp_pcb_init(void);
void sctp_free_remote_addr(struct sctp_nets *);
int sctp_add_local_addr_assoc(struct sctp_tcb *, struct ifaddr *);
int sctp_del_local_addr_assoc(struct sctp_tcb *, struct ifaddr *);
int sctp_del_local_addr_assoc_sa(struct sctp_tcb *, struct sockaddr *);
int sctp_load_addresses_from_init(struct sctp_tcb *, struct mbuf *, int, int,
int, struct sctphdr *, struct sockaddr *);
int sctp_set_primary_addr(struct sctp_tcb *, struct sockaddr *, struct sctp_nets *);
int sctp_is_vtag_good(struct sctp_inpcb *, uint32_t, struct timeval *);
/*void sctp_drain(void);*/
int sctp_destination_is_reachable(struct sctp_tcb *, const struct sockaddr *);
int sctp_add_to_socket_q(struct sctp_inpcb *, struct sctp_tcb *);
struct sctp_tcb *sctp_remove_from_socket_q(struct sctp_inpcb *);
/* Null in last arg inpcb indicate run on ALL ep's. Specific
* inp in last arg indicates run on ONLY assoc's of the
* specified endpoint.
*/
int
sctp_initiate_iterator(asoc_func af, uint32_t, uint32_t, void *, uint32_t,
end_func ef, struct sctp_inpcb *);
extern void in6_sin6_2_sin (struct sockaddr_in *,
struct sockaddr_in6 *sin6);
#endif /* _KERNEL */
#endif /* !__SCTP_PCB_H__ */

200
sys/netinet/sctp_peeloff.c Normal file
View File

@ -0,0 +1,200 @@
/* $KAME: sctp_peeloff.c,v 1.13 2005/03/06 16:04:18 itojun Exp $ */
/* $NetBSD: sctp_peeloff.c,v 1.1 2015/10/13 21:28:35 rjs Exp $ */
/*
* Copyright (C) 2002, 2003 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 <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sctp_peeloff.c,v 1.1 2015/10/13 21:28:35 rjs Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
#include "opt_ipsec.h"
#include "opt_sctp.h"
#endif /* _KERNEL_OPT */
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/domain.h>
#include <sys/proc.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/sysctl.h>
#include <sys/syslog.h>
#include <net/if.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#ifdef INET6
#include <netinet/ip6.h>
#endif
#include <netinet/in_pcb.h>
#include <netinet/in_var.h>
#include <netinet/ip_var.h>
#ifdef INET6
#include <netinet6/ip6_var.h>
#endif
#include <netinet/ip_icmp.h>
#include <netinet/icmp_var.h>
#include <netinet/sctp_pcb.h>
#include <netinet/sctp.h>
#include <netinet/sctp_uio.h>
#include <netinet/sctp_var.h>
#include <netinet/sctp_peeloff.h>
#include <netinet/sctputil.h>
#ifdef IPSEC
#include <netinet6/ipsec.h>
#include <netkey/key.h>
#endif /*IPSEC*/
#ifdef SCTP_DEBUG
extern u_int32_t sctp_debug_on;
#endif /* SCTP_DEBUG */
int
sctp_can_peel_off(struct socket *head, u_int32_t assoc_id)
{
struct sctp_inpcb *inp;
struct sctp_tcb *stcb;
inp = (struct sctp_inpcb *)head->so_pcb;
if (inp == NULL) {
return (EFAULT);
}
stcb = sctp_findassociation_ep_asocid(inp, assoc_id);
if (stcb == NULL) {
return (ENOTCONN);
}
/* We are clear to peel this one off */
return (0);
}
int
sctp_do_peeloff(struct socket *head, struct socket *so, u_int32_t assoc_id)
{
struct sctp_inpcb *inp, *n_inp;
struct sctp_tcb *stcb;
inp = (struct sctp_inpcb *)head->so_pcb;
if (inp == NULL)
return (EFAULT);
stcb = sctp_findassociation_ep_asocid(inp, assoc_id);
if (stcb == NULL)
return (ENOTCONN);
n_inp = (struct sctp_inpcb *)so->so_pcb;
n_inp->sctp_flags = (SCTP_PCB_FLAGS_UDPTYPE |
SCTP_PCB_FLAGS_CONNECTED |
SCTP_PCB_FLAGS_IN_TCPPOOL | /* Turn on Blocking IO */
(SCTP_PCB_COPY_FLAGS & inp->sctp_flags));
n_inp->sctp_socket = so;
/*
* Now we must move it from one hash table to another and get
* the stcb in the right place.
*/
sctp_move_pcb_and_assoc(inp, n_inp, stcb);
/*
* And now the final hack. We move data in the
* pending side i.e. head to the new socket
* buffer. Let the GRUBBING begin :-0
*/
sctp_grub_through_socket_buffer(inp, head, so, stcb);
return (0);
}
struct socket *
sctp_get_peeloff(struct socket *head, u_int32_t assoc_id, int *error)
{
struct socket *newso;
struct sctp_inpcb *inp, *n_inp;
struct sctp_tcb *stcb;
#ifdef SCTP_DEBUG
if (sctp_debug_on & SCTP_DEBUG_PEEL1) {
printf("SCTP peel-off called\n");
}
#endif /* SCTP_DEBUG */
inp = (struct sctp_inpcb *)head->so_pcb;
if (inp == NULL) {
*error = EFAULT;
return (NULL);
}
stcb = sctp_findassociation_ep_asocid(inp, assoc_id);
if (stcb == NULL) {
*error = ENOTCONN;
return (NULL);
}
newso = sonewconn(head, SS_ISCONNECTED);
if (newso == NULL) {
#ifdef SCTP_DEBUG
if (sctp_debug_on & SCTP_DEBUG_PEEL1) {
printf("sctp_peeloff:sonewconn failed err\n");
}
#endif /* SCTP_DEBUG */
*error = ENOMEM;
SCTP_TCB_UNLOCK(stcb);
return (NULL);
}
n_inp = (struct sctp_inpcb *)newso->so_pcb;
SCTP_INP_WLOCK(n_inp);
n_inp->sctp_flags = (SCTP_PCB_FLAGS_UDPTYPE |
SCTP_PCB_FLAGS_CONNECTED |
SCTP_PCB_FLAGS_IN_TCPPOOL | /* Turn on Blocking IO */
(SCTP_PCB_COPY_FLAGS & inp->sctp_flags));
n_inp->sctp_socket = newso;
/* Turn off any non-blocking symantic. */
newso->so_state &= ~SS_NBIO;
newso->so_state |= SS_ISCONNECTED;
/* We remove it right away */
newso = TAILQ_FIRST(&head->so_q);
if (soqremque(newso, 1) == 0)
panic("sctp_peeloff");
/*
* Now we must move it from one hash table to another and get
* the stcb in the right place.
*/
SCTP_INP_WUNLOCK(n_inp);
sctp_move_pcb_and_assoc(inp, n_inp, stcb);
/*
* And now the final hack. We move data in the
* pending side i.e. head to the new socket
* buffer. Let the GRUBBING begin :-0
*/
sctp_grub_through_socket_buffer(inp, head, newso, stcb);
SCTP_TCB_UNLOCK(stcb);
return (newso);
}

View File

@ -0,0 +1,50 @@
/* $KAME: sctp_peeloff.h,v 1.6 2005/03/06 16:04:18 itojun Exp $ */
/* $NetBSD: sctp_peeloff.h,v 1.1 2015/10/13 21:28:35 rjs Exp $ */
#ifndef __SCTP_PEELOFF_H__
#define __SCTP_PEELOFF_H__
/*
* Copyright (C) 2002, 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 <sys/types.h>
#include <sys/socketvar.h>
#include <sys/socket.h>
#if defined(_KERNEL)
int sctp_can_peel_off(struct socket *, u_int32_t);
int sctp_do_peeloff(struct socket *, struct socket *, u_int32_t);
struct socket *sctp_get_peeloff(struct socket *, u_int32_t, int *);
#endif /* _KERNEL */
#endif

648
sys/netinet/sctp_structs.h Normal file
View File

@ -0,0 +1,648 @@
/* $KAME: sctp_structs.h,v 1.13 2005/03/06 16:04:18 itojun Exp $ */
/* $NetBSD: sctp_structs.h,v 1.1 2015/10/13 21:28:35 rjs Exp $ */
#ifndef __SCTP_STRUCTS_H__
#define __SCTP_STRUCTS_H__
/*
* Copyright (c) 2001, 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Cisco Systems, Inc.
* 4. 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 CISCO SYSTEMS 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 CISCO SYSTEMS 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 <sys/queue.h>
#include <sys/callout.h>
#ifdef IPSEC
#include <netinet6/ipsec.h>
#include <netkey/key.h>
#endif
#include <netinet/sctp_header.h>
#include <netinet/sctp_uio.h>
struct sctp_timer {
struct callout timer;
int type;
/*
* Depending on the timer type these will be setup and cast with
* the appropriate entity.
*/
void *ep;
void *tcb;
void *net;
};
/*
* This is the information we track on each interface that we know about * from the distant end.
*/
TAILQ_HEAD(sctpnetlisthead, sctp_nets);
/*
* Users of the iterator need to malloc a iterator with a call to
* sctp_initiate_iterator(func, pcb_flags, asoc_state, void-ptr-arg, u_int32_t,
* u_int32-arg, end_func, inp);
*
* Use the following two defines if you don't care what pcb flags are on the
* EP and/or you don't care what state the association is in.
*
* Note that if you specify an INP as the last argument then ONLY each
* association of that single INP will be executed upon. Note that the
* pcb flags STILL apply so if the inp you specify has different pcb_flags
* then what you put in pcb_flags nothing will happen. use SCTP_PCB_ANY_FLAGS
* to assure the inp you specify gets treated.
*/
#define SCTP_PCB_ANY_FLAGS 0x00000000
#define SCTP_ASOC_ANY_STATE 0x00000000
typedef void (*asoc_func)(struct sctp_inpcb *, struct sctp_tcb *, void *ptr,
u_int32_t val);
typedef void (*end_func)(void *ptr, u_int32_t val);
#define SCTP_ITERATOR_DO_ALL_INP 0x00000001
#define SCTP_ITERATOR_DO_SINGLE_INP 0x00000002
struct sctp_iterator {
LIST_ENTRY(sctp_iterator) sctp_nxt_itr;
struct sctp_timer tmr;
struct sctp_inpcb *inp; /* ep */
struct sctp_tcb *stcb; /* assoc */
asoc_func function_toapply;
end_func function_atend;
void *pointer; /* pointer for apply func to use */
u_int32_t val; /* value for apply func to use */
u_int32_t pcb_flags;
u_int32_t asoc_state;
u_int32_t iterator_flags;
};
LIST_HEAD(sctpiterators, sctp_iterator);
struct sctp_copy_all {
struct sctp_inpcb *inp; /* ep */
struct mbuf *m;
struct sctp_sndrcvinfo sndrcv;
int sndlen;
int cnt_sent;
int cnt_failed;
};
union sctp_sockstore {
#ifdef AF_INET
struct sockaddr_in sin;
#endif
#ifdef AF_INET6
struct sockaddr_in6 sin6;
#endif
struct sockaddr sa;
};
struct sctp_nets {
TAILQ_ENTRY(sctp_nets) sctp_next; /* next link */
/* Things on the top half may be able to be split
* into a common structure shared by all.
*/
struct sctp_timer pmtu_timer;
/*
* The following two in combination equate to a route entry for
* v6 or v4.
*/
#if 0
struct sctp_route {
struct rtentry *ro_rt;
union sctp_sockstore _l_addr; /* remote peer addr */
union sctp_sockstore _s_addr; /* our selected src addr */
} ro;
#endif
struct route ro;
/* union sctp_sockstore _l_addr; */
union sctp_sockstore _s_addr;
/* mtu discovered so far */
u_int32_t mtu;
u_int32_t ssthresh; /* not sure about this one for split */
/* smoothed average things for RTT and RTO itself */
int lastsa;
int lastsv;
unsigned int RTO;
/* This is used for SHUTDOWN/SHUTDOWN-ACK/SEND or INIT timers */
struct sctp_timer rxt_timer;
/* last time in seconds I sent to it */
struct timeval last_sent_time;
int ref_count;
/* Congestion stats per destination */
/*
* flight size variables and such, sorry Vern, I could not avoid
* this if I wanted performance :>
*/
u_int32_t flight_size;
u_int32_t cwnd; /* actual cwnd */
u_int32_t prev_cwnd; /* cwnd before any processing */
u_int32_t partial_bytes_acked; /* in CA tracks when to incr a MTU */
/* tracking variables to avoid the aloc/free in sack processing */
unsigned int net_ack;
unsigned int net_ack2;
/*
* These only are valid if the primary dest_sstate holds the
* SCTP_ADDR_SWITCH_PRIMARY flag
*/
u_int32_t next_tsn_at_change;
u_int32_t heartbeat_random1;
u_int32_t heartbeat_random2;
/* if this guy is ok or not ... status */
u_int16_t dest_state;
/* number of transmit failures to down this guy */
u_int16_t failure_threshold;
/* error stats on destination */
u_int16_t error_count;
/* Flags that probably can be combined into dest_state */
u_int8_t rto_pending; /* is segment marked for RTO update ** if we split?*/
u_int8_t fast_retran_ip; /* fast retransmit in progress */
u_int8_t hb_responded;
u_int8_t cacc_saw_newack; /* CACC algorithm flag */
u_int8_t src_addr_selected; /* if we split we move */
u_int8_t indx_of_eligible_next_to_use;
u_int8_t addr_is_local; /* its a local address (if known) could move in split */
#ifdef SCTP_HIGH_SPEED
u_int8_t last_hs_used; /* index into the last HS table entry we used */
#endif
};
struct sctp_data_chunkrec {
u_int32_t TSN_seq; /* the TSN of this transmit */
u_int16_t stream_seq; /* the stream sequence number of this transmit */
u_int16_t stream_number; /* the stream number of this guy */
u_int32_t payloadtype;
u_int32_t context; /* from send */
/* ECN Nonce: Nonce Value for this chunk */
u_int8_t ect_nonce;
/* part of the Highest sacked algorithm to be able to
* stroke counts on ones that are FR'd.
*/
u_int32_t fast_retran_tsn; /* sending_seq at the time of FR */
struct timeval timetodrop; /* time we drop it from queue */
u_int8_t doing_fast_retransmit;
u_int8_t rcv_flags; /* flags pulled from data chunk on inbound
* for outbound holds sending flags.
*/
u_int8_t state_flags;
};
TAILQ_HEAD(sctpchunk_listhead, sctp_tmit_chunk);
#define CHUNK_FLAGS_FRAGMENT_OK 0x0001
struct sctp_tmit_chunk {
union {
struct sctp_data_chunkrec data;
int chunk_id;
} rec;
int32_t sent; /* the send status */
int32_t snd_count; /* number of times I sent */
u_int32_t flags; /* flags, such as FRAGMENT_OK */
u_int32_t send_size;
u_int32_t book_size;
u_int32_t mbcnt;
struct sctp_association *asoc; /* bp to asoc this belongs to */
struct timeval sent_rcv_time; /* filled in if RTT being calculated */
struct mbuf *data; /* pointer to mbuf chain of data */
struct sctp_nets *whoTo;
TAILQ_ENTRY(sctp_tmit_chunk) sctp_next; /* next link */
uint8_t do_rtt;
};
/*
* this struct contains info that is used to track inbound stream data
* and help with ordering.
*/
TAILQ_HEAD(sctpwheelunrel_listhead, sctp_stream_in);
struct sctp_stream_in {
struct sctpchunk_listhead inqueue;
TAILQ_ENTRY(sctp_stream_in) next_spoke;
uint16_t stream_no;
uint16_t last_sequence_delivered; /* used for re-order */
};
/* This struct is used to track the traffic on outbound streams */
TAILQ_HEAD(sctpwheel_listhead, sctp_stream_out);
struct sctp_stream_out {
struct sctpchunk_listhead outqueue;
TAILQ_ENTRY(sctp_stream_out) next_spoke; /* next link in wheel */
uint16_t stream_no;
uint16_t next_sequence_sent; /* next one I expect to send out */
};
/* used to keep track of the addresses yet to try to add/delete */
TAILQ_HEAD(sctp_asconf_addrhead, sctp_asconf_addr);
struct sctp_asconf_addr {
TAILQ_ENTRY(sctp_asconf_addr) next;
struct sctp_asconf_addr_param ap;
struct ifaddr *ifa; /* save the ifa for add/del ip */
uint8_t sent; /* has this been sent yet? */
};
/*
* Here we have information about each individual association that we
* track. We probably in production would be more dynamic. But for ease
* of implementation we will have a fixed array that we hunt for in a
* linear fashion.
*/
struct sctp_association {
/* association state */
int state;
/* queue of pending addrs to add/delete */
struct sctp_asconf_addrhead asconf_queue;
struct timeval time_entered; /* time we entered state */
struct timeval time_last_rcvd;
struct timeval time_last_sent;
struct timeval time_last_sat_advance;
struct sctp_sndrcvinfo def_send; /* default send parameters */
/* timers and such */
struct sctp_timer hb_timer; /* hb timer */
struct sctp_timer dack_timer; /* Delayed ack timer */
struct sctp_timer asconf_timer; /* Asconf */
struct sctp_timer strreset_timer; /* stream reset */
struct sctp_timer shut_guard_timer; /* guard */
struct sctp_timer autoclose_timer; /* automatic close timer */
struct sctp_timer delayed_event_timer; /* timer for delayed events */
/* list of local addresses when add/del in progress */
struct sctpladdr sctp_local_addr_list;
struct sctpnetlisthead nets;
/* Control chunk queue */
struct sctpchunk_listhead control_send_queue;
/* Once a TSN hits the wire it is moved to the sent_queue. We
* maintain two counts here (don't know if any but retran_cnt
* is needed). The idea is that the sent_queue_retran_cnt
* reflects how many chunks have been marked for retranmission
* by either T3-rxt or FR.
*/
struct sctpchunk_listhead sent_queue;
struct sctpchunk_listhead send_queue;
/* re-assembly queue for fragmented chunks on the inbound path */
struct sctpchunk_listhead reasmqueue;
/*
* this queue is used when we reach a condition that we can NOT
* put data into the socket buffer. We track the size of this
* queue and set our rwnd to the space in the socket minus also
* the size_on_delivery_queue.
*/
struct sctpchunk_listhead delivery_queue;
struct sctpwheel_listhead out_wheel;
/* If an iterator is looking at me, this is it */
struct sctp_iterator *stcb_starting_point_for_iterator;
/* ASCONF destination address last sent to */
struct sctp_nets *asconf_last_sent_to;
/* ASCONF save the last ASCONF-ACK so we can resend it if necessary */
struct mbuf *last_asconf_ack_sent;
/*
* if Source Address Selection happening, this will rotate through
* the link list.
*/
struct sctp_laddr *last_used_address;
/* stream arrays */
struct sctp_stream_in *strmin;
struct sctp_stream_out *strmout;
u_int8_t *mapping_array;
/* primary destination to use */
struct sctp_nets *primary_destination;
/* last place I got a data chunk from */
struct sctp_nets *last_data_chunk_from;
/* last place I got a control from */
struct sctp_nets *last_control_chunk_from;
/* circular looking for output selection */
struct sctp_stream_out *last_out_stream;
/* wait to the point the cum-ack passes
* pending_reply->sr_resp.reset_at_tsn.
*/
struct sctp_stream_reset_response *pending_reply;
struct sctpchunk_listhead pending_reply_queue;
u_int32_t cookie_preserve_req;
/* ASCONF next seq I am sending out, inits at init-tsn */
uint32_t asconf_seq_out;
/* ASCONF last received ASCONF from peer, starts at peer's TSN-1 */
uint32_t asconf_seq_in;
/* next seq I am sending in str reset messages */
uint32_t str_reset_seq_out;
/* next seq I am expecting in str reset messages */
uint32_t str_reset_seq_in;
u_int32_t str_reset_sending_seq;
/* various verification tag information */
u_int32_t my_vtag; /*
* The tag to be used. if assoc is
* re-initited by remote end, and
* I have unlocked this will be
* regenrated to a new random value.
*/
u_int32_t peer_vtag; /* The peers last tag */
u_int32_t my_vtag_nonce;
u_int32_t peer_vtag_nonce;
/* This is the SCTP fragmentation threshold */
u_int32_t smallest_mtu;
/*
* Special hook for Fast retransmit, allows us to track the highest
* TSN that is NEW in this SACK if gap ack blocks are present.
*/
u_int32_t this_sack_highest_gap;
/*
* The highest consecutive TSN that has been acked by peer on my
* sends
*/
u_int32_t last_acked_seq;
/* The next TSN that I will use in sending. */
u_int32_t sending_seq;
/* Original seq number I used ??questionable to keep?? */
u_int32_t init_seq_number;
/*
* We use this value to know if FR's are allowed, i.e. did the
* cum-ack pass this point or equal it so FR's are now allowed.
*/
u_int32_t t3timeout_highest_marked;
/* The Advanced Peer Ack Point, as required by the PR-SCTP */
/* (A1 in Section 4.2) */
u_int32_t advanced_peer_ack_point;
/*
* The highest consequetive TSN at the bottom of the mapping
* array (for his sends).
*/
u_int32_t cumulative_tsn;
/*
* Used to track the mapping array and its offset bits. This
* MAY be lower then cumulative_tsn.
*/
u_int32_t mapping_array_base_tsn;
/*
* used to track highest TSN we have received and is listed in
* the mapping array.
*/
u_int32_t highest_tsn_inside_map;
u_int32_t last_echo_tsn;
u_int32_t last_cwr_tsn;
u_int32_t fast_recovery_tsn;
u_int32_t sat_t3_recovery_tsn;
u_int32_t tsn_last_delivered;
/*
* window state information and smallest MTU that I use to bound
* segmentation
*/
u_int32_t peers_rwnd;
u_int32_t my_rwnd;
u_int32_t my_last_reported_rwnd;
u_int32_t my_rwnd_control_len;
u_int32_t total_output_queue_size;
u_int32_t total_output_mbuf_queue_size;
/* 32 bit nonce stuff */
u_int32_t nonce_resync_tsn;
u_int32_t nonce_wait_tsn;
int ctrl_queue_cnt; /* could be removed REM */
/*
* All outbound datagrams queue into this list from the
* individual stream queue. Here they get assigned a TSN
* and then await sending. The stream seq comes when it
* is first put in the individual str queue
*/
unsigned int stream_queue_cnt;
unsigned int send_queue_cnt;
unsigned int sent_queue_cnt;
unsigned int sent_queue_cnt_removeable;
/*
* Number on sent queue that are marked for retran until this
* value is 0 we only send one packet of retran'ed data.
*/
unsigned int sent_queue_retran_cnt;
unsigned int size_on_reasm_queue;
unsigned int cnt_on_reasm_queue;
/* amount of data (bytes) currently in flight (on all destinations) */
unsigned int total_flight;
/* Total book size in flight */
unsigned int total_flight_count; /* count of chunks used with book total */
/* count of destinaton nets and list of destination nets */
unsigned int numnets;
/* Total error count on this association */
unsigned int overall_error_count;
unsigned int size_on_delivery_queue;
unsigned int cnt_on_delivery_queue;
unsigned int cnt_msg_on_sb;
/* All stream count of chunks for delivery */
unsigned int size_on_all_streams;
unsigned int cnt_on_all_streams;
/* Heart Beat delay in ticks */
unsigned int heart_beat_delay;
/* autoclose */
unsigned int sctp_autoclose_ticks;
/* how many preopen streams we have */
unsigned int pre_open_streams;
/* How many streams I support coming into me */
unsigned int max_inbound_streams;
/* the cookie life I award for any cookie, in seconds */
unsigned int cookie_life;
unsigned int numduptsns;
int dup_tsns[SCTP_MAX_DUP_TSNS];
unsigned int initial_init_rto_max; /* initial RTO for INIT's */
unsigned int initial_rto; /* initial send RTO */
unsigned int minrto; /* per assoc RTO-MIN */
unsigned int maxrto; /* per assoc RTO-MAX */
/* Being that we have no bag to collect stale cookies, and
* that we really would not want to anyway.. we will count
* them in this counter. We of course feed them to the
* pigeons right away (I have always thought of pigeons
* as flying rats).
*/
u_int16_t stale_cookie_count;
/* For the partial delivery API, if up, invoked
* this is what last TSN I delivered
*/
u_int16_t str_of_pdapi;
u_int16_t ssn_of_pdapi;
/* counts of actual built streams. Allocation may be more however */
/* could re-arrange to optimize space here. */
u_int16_t streamincnt;
u_int16_t streamoutcnt;
/* my maximum number of retrans of INIT and SEND */
/* copied from SCTP but should be individually setable */
u_int16_t max_init_times;
u_int16_t max_send_times;
u_int16_t def_net_failure;
/*
* lock flag: 0 is ok to send, 1+ (duals as a retran count) is
* awaiting ACK
*/
u_int16_t asconf_sent; /* possibly removable REM */
u_int16_t mapping_array_size;
u_int16_t chunks_on_out_queue; /* total chunks floating around */
int16_t num_send_timers_up;
/*
* This flag indicates that we need to send the first SACK. If
* in place it says we have NOT yet sent a SACK and need to.
*/
u_int8_t first_ack_sent;
/* max burst after fast retransmit completes */
u_int8_t max_burst;
u_int8_t sat_network; /* RTT is in range of sat net or greater */
u_int8_t sat_network_lockout;/* lockout code */
u_int8_t burst_limit_applied; /* Burst limit in effect at last send? */
/* flag goes on when we are doing a partial delivery api */
u_int8_t hb_random_values[4];
u_int8_t fragmented_delivery_inprogress;
u_int8_t fragment_flags;
u_int8_t hb_ect_randombit;
u_int8_t hb_random_idx;
/* ECN Nonce stuff */
u_int8_t receiver_nonce_sum; /* nonce I sum and put in my sack */
u_int8_t ecn_nonce_allowed; /* Tells us if ECN nonce is on */
u_int8_t nonce_sum_check; /* On off switch used during re-sync */
u_int8_t nonce_wait_for_ecne;/* flag when we expect a ECN */
u_int8_t peer_supports_ecn_nonce;
/*
* This value, plus all other ack'd but above cum-ack is added
* together to cross check against the bit that we have yet to
* define (probably in the SACK).
* When the cum-ack is updated, this sum is updated as well.
*/
u_int8_t nonce_sum_expect_base;
/* Flag to tell if ECN is allowed */
u_int8_t ecn_allowed;
/* flag to indicate if peer can do asconf */
uint8_t peer_supports_asconf;
uint8_t peer_supports_asconf_setprim; /* possibly removable REM */
/* pr-sctp support flag */
uint8_t peer_supports_prsctp;
/* stream resets are supported by the peer */
uint8_t peer_supports_strreset;
/*
* packet drop's are supported by the peer, we don't really care
* about this but we bookkeep it anyway.
*/
uint8_t peer_supports_pktdrop;
/* Do we allow V6/V4? */
u_int8_t ipv4_addr_legal;
u_int8_t ipv6_addr_legal;
/* Address scoping flags */
/* scope value for IPv4 */
u_int8_t ipv4_local_scope;
/* scope values for IPv6 */
u_int8_t local_scope;
u_int8_t site_scope;
/* loopback scope */
u_int8_t loopback_scope;
/* flags to handle send alternate net tracking */
u_int8_t used_alt_onsack;
u_int8_t used_alt_asconfack;
u_int8_t fast_retran_loss_recovery;
u_int8_t sat_t3_loss_recovery;
u_int8_t dropped_special_cnt;
u_int8_t seen_a_sack_this_pkt;
u_int8_t stream_reset_outstanding;
u_int8_t delayed_connection;
u_int8_t ifp_had_enobuf;
u_int8_t saw_sack_with_frags;
/*
* The mapping array is used to track out of order sequences above
* last_acked_seq. 0 indicates packet missing 1 indicates packet
* rec'd. We slide it up every time we raise last_acked_seq and 0
* trailing locactions out. If I get a TSN above the array
* mappingArraySz, I discard the datagram and let retransmit happen.
*/
};
#endif

1534
sys/netinet/sctp_timer.c Normal file

File diff suppressed because it is too large Load Diff

74
sys/netinet/sctp_timer.h Normal file
View File

@ -0,0 +1,74 @@
/* $KAME: sctp_timer.h,v 1.6 2005/03/06 16:04:18 itojun Exp $ */
/* $NetBSD: sctp_timer.h,v 1.1 2015/10/13 21:28:35 rjs Exp $ */
#ifndef __SCTP_TIMER_H__
#define __SCTP_TIMER_H__
/*
* Copyright (C) 2002, 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.
*/
#if defined(_KERNEL)
struct sctp_nets *sctp_find_alternate_net(struct sctp_tcb *,
struct sctp_nets *);
int sctp_threshold_management(struct sctp_inpcb *, struct sctp_tcb *,
struct sctp_nets *, uint16_t);
int sctp_t3rxt_timer(struct sctp_inpcb *, struct sctp_tcb *,
struct sctp_nets *);
int sctp_t1init_timer(struct sctp_inpcb *, struct sctp_tcb *,
struct sctp_nets *);
int sctp_shutdown_timer(struct sctp_inpcb *, struct sctp_tcb *,
struct sctp_nets *);
int sctp_heartbeat_timer(struct sctp_inpcb *, struct sctp_tcb *,
struct sctp_nets *);
int sctp_cookie_timer(struct sctp_inpcb *, struct sctp_tcb *,
struct sctp_nets *);
void sctp_pathmtu_timer(struct sctp_inpcb *, struct sctp_tcb *,
struct sctp_nets *);
int sctp_shutdownack_timer(struct sctp_inpcb *, struct sctp_tcb *,
struct sctp_nets *);
int sctp_strreset_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
struct sctp_nets *net);
int sctp_asconf_timer(struct sctp_inpcb *, struct sctp_tcb *,
struct sctp_nets *);
void sctp_autoclose_timer(struct sctp_inpcb *, struct sctp_tcb *,
struct sctp_nets *net);
void sctp_audit_retranmission_queue(struct sctp_association *);
void sctp_iterator_timer(struct sctp_iterator *it);
#endif
#endif

524
sys/netinet/sctp_uio.h Normal file
View File

@ -0,0 +1,524 @@
/* $KAME: sctp_uio.h,v 1.11 2005/03/06 16:04:18 itojun Exp $ */
/* $NetBSD: sctp_uio.h,v 1.1 2015/10/13 21:28:35 rjs Exp $ */
#ifndef __SCTP_UIO_H__
#define __SCTP_UIO_H__
/*
* Copyright (c) 2001, 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Cisco Systems, Inc.
* 4. 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 CISCO SYSTEMS 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 CISCO SYSTEMS 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 <sys/types.h>
#include <sys/socket.h>
typedef u_int32_t sctp_assoc_t;
/* On/Off setup for subscription to events */
struct sctp_event_subscribe {
u_int8_t sctp_data_io_event;
u_int8_t sctp_association_event;
u_int8_t sctp_address_event;
u_int8_t sctp_send_failure_event;
u_int8_t sctp_peer_error_event;
u_int8_t sctp_shutdown_event;
u_int8_t sctp_partial_delivery_event;
u_int8_t sctp_adaption_layer_event;
u_int8_t sctp_stream_reset_events;
};
/* ancillary data types */
#define SCTP_INIT 0x0001
#define SCTP_SNDRCV 0x0002
/*
* ancillary data structures
*/
struct sctp_initmsg {
u_int32_t sinit_num_ostreams;
u_int32_t sinit_max_instreams;
u_int16_t sinit_max_attempts;
u_int16_t sinit_max_init_timeo;
};
struct sctp_sndrcvinfo {
u_int16_t sinfo_stream;
u_int16_t sinfo_ssn;
u_int16_t sinfo_flags;
u_int32_t sinfo_ppid;
u_int32_t sinfo_context;
u_int32_t sinfo_timetolive;
u_int32_t sinfo_tsn;
u_int32_t sinfo_cumtsn;
sctp_assoc_t sinfo_assoc_id;
};
struct sctp_snd_all_completes {
u_int16_t sall_stream;
u_int16_t sall_flags;
u_int32_t sall_ppid;
u_int32_t sall_context;
u_int32_t sall_num_sent;
u_int32_t sall_num_failed;
};
/* send/recv flags */
/* MSG_EOF (0x0100) is reused from sys/socket.h */
#define MSG_SENDALL 0x0200
#define MSG_PR_SCTP_TTL 0x0400 /* Partial Reliable on this msg */
#define MSG_PR_SCTP_BUF 0x0800 /* Buffer based PR-SCTP */
#ifndef MSG_EOF
#define MSG_EOF 0x1000 /* Start shutdown procedures */
#endif
#define MSG_UNORDERED 0x2000 /* Message is un-ordered */
#define MSG_ADDR_OVER 0x4000 /* Override the primary-address */
#define MSG_ABORT 0x8000 /* Send an ABORT to peer */
/* Stat's */
struct sctp_pcbinfo {
u_int32_t ep_count;
u_int32_t asoc_count;
u_int32_t laddr_count;
u_int32_t raddr_count;
u_int32_t chk_count;
u_int32_t sockq_count;
u_int32_t mbuf_track;
};
struct sctp_sockstat {
sctp_assoc_t ss_assoc_id;
u_int32_t ss_total_sndbuf;
u_int32_t ss_total_mbuf_sndbuf;
u_int32_t ss_total_recv_buf;
};
/*
* notification event structures
*/
/* association change events */
struct sctp_assoc_change {
u_int16_t sac_type;
u_int16_t sac_flags;
u_int32_t sac_length;
u_int16_t sac_state;
u_int16_t sac_error;
u_int16_t sac_outbound_streams;
u_int16_t sac_inbound_streams;
sctp_assoc_t sac_assoc_id;
};
/* sac_state values */
#define SCTP_COMM_UP 0x0001
#define SCTP_COMM_LOST 0x0002
#define SCTP_RESTART 0x0003
#define SCTP_SHUTDOWN_COMP 0x0004
#define SCTP_CANT_STR_ASSOC 0x0005
/* Address events */
struct sctp_paddr_change {
u_int16_t spc_type;
u_int16_t spc_flags;
u_int32_t spc_length;
struct sockaddr_storage spc_aaddr;
u_int32_t spc_state;
u_int32_t spc_error;
sctp_assoc_t spc_assoc_id;
};
/* paddr state values */
#define SCTP_ADDR_AVAILABLE 0x0001
#define SCTP_ADDR_UNREACHABLE 0x0002
#define SCTP_ADDR_REMOVED 0x0003
#define SCTP_ADDR_ADDED 0x0004
#define SCTP_ADDR_MADE_PRIM 0x0005
#define SCTP_ADDR_CONFIRMED 0x0006
/*
* CAUTION: these are user exposed SCTP addr reachability states
* must be compatible with SCTP_ADDR states in sctp_constants.h
*/
#ifdef SCTP_ACTIVE
#undef SCTP_ACTIVE
#endif
#define SCTP_ACTIVE 0x0001 /* SCTP_ADDR_REACHABLE */
#ifdef SCTP_INACTIVE
#undef SCTP_INACTIVE
#endif
#define SCTP_INACTIVE 0x0002 /* SCTP_ADDR_NOT_REACHABLE */
#ifdef SCTP_UNCONFIRMED
#undef SCTP_UNCONFIRMED
#endif
#define SCTP_UNCONFIRMED 0x0200 /* SCTP_ADDR_UNCONFIRMED */
#ifdef SCTP_NOHEARTBEAT
#undef SCTP_NOHEARTBEAT
#endif
#define SCTP_NOHEARTBEAT 0x0040 /* SCTP_ADDR_NOHB */
/* remote error events */
struct sctp_remote_error {
u_int16_t sre_type;
u_int16_t sre_flags;
u_int32_t sre_length;
u_int16_t sre_error;
sctp_assoc_t sre_assoc_id;
u_int8_t sre_data[4];
};
/* data send failure event */
struct sctp_send_failed {
u_int16_t ssf_type;
u_int16_t ssf_flags;
u_int32_t ssf_length;
u_int32_t ssf_error;
struct sctp_sndrcvinfo ssf_info;
sctp_assoc_t ssf_assoc_id;
u_int8_t ssf_data[4];
};
/* flag that indicates state of data */
#define SCTP_DATA_UNSENT 0x0001 /* inqueue never on wire */
#define SCTP_DATA_SENT 0x0002 /* on wire at failure */
/* shutdown event */
struct sctp_shutdown_event {
u_int16_t sse_type;
u_int16_t sse_flags;
u_int32_t sse_length;
sctp_assoc_t sse_assoc_id;
};
/* Adaption layer indication stuff */
struct sctp_adaption_event {
u_int16_t sai_type;
u_int16_t sai_flags;
u_int32_t sai_length;
u_int32_t sai_adaption_ind;
sctp_assoc_t sai_assoc_id;
};
struct sctp_setadaption {
u_int32_t ssb_adaption_ind;
};
/* pdapi indications */
struct sctp_pdapi_event {
u_int16_t pdapi_type;
u_int16_t pdapi_flags;
u_int32_t pdapi_length;
u_int32_t pdapi_indication;
sctp_assoc_t pdapi_assoc_id;
};
#define SCTP_PARTIAL_DELIVERY_ABORTED 0x0001
/* stream reset stuff */
struct sctp_stream_reset_event {
u_int16_t strreset_type;
u_int16_t strreset_flags;
u_int32_t strreset_length;
sctp_assoc_t strreset_assoc_id;
u_int16_t strreset_list[0];
};
/* flags in strreset_flags filed */
#define SCTP_STRRESET_INBOUND_STR 0x0001
#define SCTP_STRRESET_OUTBOUND_STR 0x0002
#define SCTP_STRRESET_ALL_STREAMS 0x0004
#define SCTP_STRRESET_STREAM_LIST 0x0008
#define MAX_ASOC_IDS_RET 255
struct sctp_assoc_ids {
u_int16_t asls_assoc_start; /* array of index's start at 0 */
u_int8_t asls_numb_present;
u_int8_t asls_more_to_get;
sctp_assoc_t asls_assoc_id[MAX_ASOC_IDS_RET];
};
/* notification types */
#define SCTP_ASSOC_CHANGE 0x0001
#define SCTP_PEER_ADDR_CHANGE 0x0002
#define SCTP_REMOTE_ERROR 0x0003
#define SCTP_SEND_FAILED 0x0004
#define SCTP_SHUTDOWN_EVENT 0x0005
#define SCTP_ADAPTION_INDICATION 0x0006
#define SCTP_PARTIAL_DELIVERY_EVENT 0x0007
#define SCTP_STREAM_RESET_EVENT 0x0008
struct sctp_tlv {
u_int16_t sn_type;
u_int16_t sn_flags;
u_int32_t sn_length;
};
/* notification event */
union sctp_notification {
struct sctp_tlv sn_header;
struct sctp_assoc_change sn_assoc_change;
struct sctp_paddr_change sn_paddr_change;
struct sctp_remote_error sn_remote_error;
struct sctp_send_failed sn_send_failed;
struct sctp_shutdown_event sn_shutdown_event;
struct sctp_adaption_event sn_adaption_event;
struct sctp_pdapi_event sn_pdapi_event;
struct sctp_stream_reset_event sn_strreset_event;
};
/*
* socket option structs
*/
#define SCTP_ISSUE_HB 0xffffffff /* get a on-demand hb */
#define SCTP_NO_HB 0x0 /* turn off hb's */
struct sctp_paddrparams {
sctp_assoc_t spp_assoc_id;
struct sockaddr_storage spp_address;
u_int32_t spp_hbinterval;
u_int16_t spp_pathmaxrxt;
};
struct sctp_paddrinfo {
sctp_assoc_t spinfo_assoc_id;
struct sockaddr_storage spinfo_address;
int32_t spinfo_state;
u_int32_t spinfo_cwnd;
u_int32_t spinfo_srtt;
u_int32_t spinfo_rto;
u_int32_t spinfo_mtu;
};
struct sctp_rtoinfo {
sctp_assoc_t srto_assoc_id;
u_int32_t srto_initial;
u_int32_t srto_max;
u_int32_t srto_min;
};
struct sctp_assocparams {
sctp_assoc_t sasoc_assoc_id;
u_int16_t sasoc_asocmaxrxt;
u_int16_t sasoc_number_peer_destinations;
u_int32_t sasoc_peer_rwnd;
u_int32_t sasoc_local_rwnd;
u_int32_t sasoc_cookie_life;
};
struct sctp_setprim {
sctp_assoc_t ssp_assoc_id;
struct sockaddr_storage ssp_addr;
};
struct sctp_setpeerprim {
sctp_assoc_t sspp_assoc_id;
struct sockaddr_storage sspp_addr;
};
struct sctp_getaddresses {
sctp_assoc_t sget_assoc_id;
/* addr is filled in for N * sockaddr_storage */
struct sockaddr addr[1];
};
struct sctp_setstrm_timeout {
sctp_assoc_t ssto_assoc_id;
u_int32_t ssto_timeout;
u_int32_t ssto_streamid_start;
u_int32_t ssto_streamid_end;
};
struct sctp_status {
sctp_assoc_t sstat_assoc_id;
int32_t sstat_state;
u_int32_t sstat_rwnd;
u_int16_t sstat_unackdata;
u_int16_t sstat_penddata;
u_int16_t sstat_instrms;
u_int16_t sstat_outstrms;
u_int32_t sstat_fragmentation_point;
struct sctp_paddrinfo sstat_primary;
};
struct sctp_cwnd_args {
struct sctp_nets *net; /* network to */
u_int32_t cwnd_new_value; /* cwnd in k */
u_int32_t inflight; /* flightsize in k */
int cwnd_augment; /* increment to it */
};
struct sctp_blk_args {
u_int32_t onmb; /* in 1k bytes */
u_int32_t onsb; /* in 1k bytes */
u_int16_t maxmb; /* in 1k bytes */
u_int16_t maxsb; /* in 1k bytes */
u_int16_t send_sent_qcnt; /* chnk cnt */
u_int16_t stream_qcnt; /* chnk cnt */
};
/*
* Max we can reset in one setting, note this is dictated not by the
* define but the size of a mbuf cluster so don't change this define
* and think you can specify more. You must do multiple resets if you
* want to reset more than SCTP_MAX_EXPLICIT_STR_RESET.
*/
#define SCTP_MAX_EXPLICT_STR_RESET 1000
#define SCTP_RESET_LOCAL_RECV 0x0001
#define SCTP_RESET_LOCAL_SEND 0x0002
#define SCTP_RESET_BOTH 0x0003
struct sctp_stream_reset {
sctp_assoc_t strrst_assoc_id;
u_int16_t strrst_flags;
u_int16_t strrst_num_streams; /* 0 == ALL */
u_int16_t strrst_list[0]; /* list if strrst_num_streams is not 0*/
};
struct sctp_get_nonce_values {
sctp_assoc_t gn_assoc_id;
u_int32_t gn_peers_tag;
u_int32_t gn_local_tag;
};
/* Debugging logs */
struct sctp_str_log{
u_int32_t n_tsn;
u_int32_t e_tsn;
u_int16_t n_sseq;
u_int16_t e_sseq;
};
struct sctp_fr_log {
u_int32_t largest_tsn;
u_int32_t largest_new_tsn;
u_int32_t tsn;
};
struct sctp_fr_map {
u_int32_t base;
u_int32_t cum;
u_int32_t high;
};
struct sctp_rwnd_log {
u_int32_t rwnd;
u_int32_t send_size;
u_int32_t overhead;
u_int32_t new_rwnd;
};
struct sctp_mbcnt_log {
u_int32_t total_queue_size;
u_int32_t size_change;
u_int32_t total_queue_mb_size;
u_int32_t mbcnt_change;
};
struct sctp_cwnd_log{
union {
struct sctp_blk_args blk;
struct sctp_cwnd_args cwnd;
struct sctp_str_log strlog;
struct sctp_fr_log fr;
struct sctp_fr_map map;
struct sctp_rwnd_log rwnd;
struct sctp_mbcnt_log mbcnt;
}x;
u_int8_t from;
u_int8_t event_type;
};
struct sctp_cwnd_log_req{
int num_in_log; /* Number in log */
int num_ret; /* Number returned */
int start_at; /* start at this one */
int end_at; /* end at this one */
struct sctp_cwnd_log log[0];
};
/*
* API system calls
*/
#if !defined(_KERNEL)
__BEGIN_DECLS
int sctp_peeloff(int, sctp_assoc_t);
int sctp_bindx(int, struct sockaddr *, int, int);
int sctp_connectx(int, struct sockaddr *, int);
int sctp_getpaddrs(int, sctp_assoc_t, struct sockaddr **);
void sctp_freepaddrs(struct sockaddr *);
int sctp_getladdrs(int, sctp_assoc_t, struct sockaddr **);
void sctp_freeladdrs(struct sockaddr *);
int sctp_opt_info(int, sctp_assoc_t, int, void *, socklen_t *);
ssize_t sctp_sendmsg(int, const void *, size_t,
const struct sockaddr *,
socklen_t, u_int32_t, u_int32_t, u_int16_t, u_int32_t, u_int32_t);
ssize_t sctp_send(int sd, const void *msg, size_t len,
const struct sctp_sndrcvinfo *sinfo,int flags);
ssize_t
sctp_sendx(int sd, const void *msg, size_t len,
struct sockaddr *addrs, int addrcnt,
struct sctp_sndrcvinfo *sinfo, int flags);
ssize_t
sctp_sendmsgx(int sd, const void *, size_t,
struct sockaddr *, int,
u_int32_t, u_int32_t, u_int16_t, u_int32_t, u_int32_t);
sctp_assoc_t
sctp_getassocid(int sd, struct sockaddr *sa);
ssize_t sctp_recvmsg(int, void *, size_t, struct sockaddr *,
socklen_t *, struct sctp_sndrcvinfo *, int *);
__END_DECLS
#endif /* !_KERNEL */
#endif /* !__SCTP_UIO_H__ */

4021
sys/netinet/sctp_usrreq.c Normal file

File diff suppressed because it is too large Load Diff

243
sys/netinet/sctp_var.h Normal file
View File

@ -0,0 +1,243 @@
/* $KAME: sctp_var.h,v 1.24 2005/03/06 16:04:19 itojun Exp $ */
/* $NetBSD: sctp_var.h,v 1.1 2015/10/13 21:28:35 rjs Exp $ */
/*
* Copyright (c) 2001, 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Cisco Systems, Inc.
* 4. 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 CISCO SYSTEMS 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 CISCO SYSTEMS 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.
*/
#ifndef _NETINET_SCTP_VAR_H_
#define _NETINET_SCTP_VAR_H_
#include <sys/socketvar.h>
#include <netinet/sctp_uio.h>
/* SCTP Kernel structures */
/*
* Names for SCTP sysctl objects
*/
#ifndef __APPLE__
#define SCTPCTL_MAXDGRAM 1 /* max datagram size */
#define SCTPCTL_RECVSPACE 2 /* default receive buffer space */
#define SCTPCTL_AUTOASCONF 3 /* auto asconf enable/disable flag */
#define SCTPCTL_ECN_ENABLE 4 /* Is ecn allowed */
#define SCTPCTL_ECN_NONCE 5 /* Is ecn nonce allowed */
#define SCTPCTL_STRICT_SACK 6 /* strictly require sack'd TSN's to be
* smaller than sndnxt.
*/
#define SCTPCTL_NOCSUM_LO 7 /* Require that the Loopback NOT have
* the crc32 checksum on packets routed over
* it.
*/
#define SCTPCTL_STRICT_INIT 8
#define SCTPCTL_PEER_CHK_OH 9
#define SCTPCTL_MAXBURST 10
#define SCTPCTL_MAXCHUNKONQ 11
#define SCTPCTL_DELAYED_SACK 12
#define SCTPCTL_HB_INTERVAL 13
#define SCTPCTL_PMTU_RAISE 14
#define SCTPCTL_SHUTDOWN_GUARD 15
#define SCTPCTL_SECRET_LIFETIME 16
#define SCTPCTL_RTO_MAX 17
#define SCTPCTL_RTO_MIN 18
#define SCTPCTL_RTO_INITIAL 19
#define SCTPCTL_INIT_RTO_MAX 20
#define SCTPCTL_COOKIE_LIFE 21
#define SCTPCTL_INIT_RTX_MAX 22
#define SCTPCTL_ASSOC_RTX_MAX 23
#define SCTPCTL_PATH_RTX_MAX 24
#define SCTPCTL_NR_OUTGOING_STREAMS 25
#ifdef SCTP_DEBUG
#define SCTPCTL_DEBUG 26
#define SCTPCTL_MAXID 27
#else
#define SCTPCTL_MAXID 26
#endif
#endif
#ifdef SCTP_DEBUG
#define SCTPCTL_NAMES { \
{ 0, 0 }, \
{ "maxdgram", CTLTYPE_INT }, \
{ "recvspace", CTLTYPE_INT }, \
{ "autoasconf", CTLTYPE_INT }, \
{ "ecn_enable", CTLTYPE_INT }, \
{ "ecn_nonce", CTLTYPE_INT }, \
{ "strict_sack", CTLTYPE_INT }, \
{ "looback_nocsum", CTLTYPE_INT }, \
{ "strict_init", CTLTYPE_INT }, \
{ "peer_chkoh", CTLTYPE_INT }, \
{ "maxburst", CTLTYPE_INT }, \
{ "maxchunks", CTLTYPE_INT }, \
{ "delayed_sack_time", CTLTYPE_INT }, \
{ "heartbeat_interval", CTLTYPE_INT }, \
{ "pmtu_raise_time", CTLTYPE_INT }, \
{ "shutdown_guard_time", CTLTYPE_INT }, \
{ "secret_lifetime", CTLTYPE_INT }, \
{ "rto_max", CTLTYPE_INT }, \
{ "rto_min", CTLTYPE_INT }, \
{ "rto_initial", CTLTYPE_INT }, \
{ "init_rto_max", CTLTYPE_INT }, \
{ "valid_cookie_life", CTLTYPE_INT }, \
{ "init_rtx_max", CTLTYPE_INT }, \
{ "assoc_rtx_max", CTLTYPE_INT }, \
{ "path_rtx_max", CTLTYPE_INT }, \
{ "nr_outgoing_streams", CTLTYPE_INT }, \
{ "debug", CTLTYPE_INT }, \
}
#else
#define SCTPCTL_NAMES { \
{ 0, 0 }, \
{ "maxdgram", CTLTYPE_INT }, \
{ "recvspace", CTLTYPE_INT }, \
{ "autoasconf", CTLTYPE_INT }, \
{ "ecn_enable", CTLTYPE_INT }, \
{ "ecn_nonce", CTLTYPE_INT }, \
{ "strict_sack", CTLTYPE_INT }, \
{ "looback_nocsum", CTLTYPE_INT }, \
{ "strict_init", CTLTYPE_INT }, \
{ "peer_chkoh", CTLTYPE_INT }, \
{ "maxburst", CTLTYPE_INT }, \
{ "maxchunks", CTLTYPE_INT }, \
{ "delayed_sack_time", CTLTYPE_INT }, \
{ "heartbeat_interval", CTLTYPE_INT }, \
{ "pmtu_raise_time", CTLTYPE_INT }, \
{ "shutdown_guard_time", CTLTYPE_INT }, \
{ "secret_lifetime", CTLTYPE_INT }, \
{ "rto_max", CTLTYPE_INT }, \
{ "rto_min", CTLTYPE_INT }, \
{ "rto_initial", CTLTYPE_INT }, \
{ "init_rto_max", CTLTYPE_INT }, \
{ "valid_cookie_life", CTLTYPE_INT }, \
{ "init_rtx_max", CTLTYPE_INT }, \
{ "assoc_rtx_max", CTLTYPE_INT }, \
{ "path_rtx_max", CTLTYPE_INT }, \
{ "nr_outgoing_streams", CTLTYPE_INT }, \
}
#endif
#if defined(_KERNEL)
extern const struct pr_usrreqs sctp_usrreqs;
int sctp_usrreq(struct socket *, int, struct mbuf *, struct mbuf *,
struct mbuf *, struct lwp *);
#define sctp_sbspace(sb) ((long) (((sb)->sb_hiwat > (sb)->sb_cc) ? ((sb)->sb_hiwat - (sb)->sb_cc) : 0))
#define sctp_sbspace_sub(a,b) ((a > b) ? (a - b) : 0)
extern int sctp_sendspace;
extern int sctp_recvspace;
extern int sctp_ecn;
extern int sctp_ecn_nonce;
#define sctp_ucount_incr(val) { \
val++; \
}
#define sctp_ucount_decr(val) { \
if (val > 0) { \
val--; \
} else { \
val = 0; \
} \
}
#define sctp_flight_size_decrease(tp1) do { \
if (tp1->whoTo->flight_size >= tp1->book_size) \
tp1->whoTo->flight_size -= tp1->book_size; \
else \
tp1->whoTo->flight_size = 0; \
} while (0)
#define sctp_flight_size_increase(tp1) do { \
(tp1)->whoTo->flight_size += (tp1)->book_size; \
} while (0)
#define sctp_total_flight_decrease(stcb, tp1) do { \
if (stcb->asoc.total_flight >= tp1->book_size) { \
stcb->asoc.total_flight -= tp1->book_size; \
if (stcb->asoc.total_flight_count > 0) \
stcb->asoc.total_flight_count--; \
} else { \
stcb->asoc.total_flight = 0; \
stcb->asoc.total_flight_count = 0; \
} \
} while (0)
#define sctp_total_flight_increase(stcb, tp1) do { \
(stcb)->asoc.total_flight_count++; \
(stcb)->asoc.total_flight += (tp1)->book_size; \
} while (0)
struct sctp_nets;
struct sctp_inpcb;
struct sctp_tcb;
struct sctphdr;
void* sctp_ctlinput(int, const struct sockaddr *, void *);
int sctp_ctloutput(int, struct socket *, struct sockopt *);
void sctp_input(struct mbuf *, ... );
void sctp_drain(void);
void sctp_init(void);
int sctp_shutdown(struct socket *);
void sctp_notify(struct sctp_inpcb *, int, struct sctphdr *,
struct sockaddr *, struct sctp_tcb *,
struct sctp_nets *);
int sctp_rcvd(struct socket *, int, struct lwp *);
int sctp_send(struct socket *, struct mbuf *, struct sockaddr *,
struct mbuf *, struct lwp *);
#if defined(INET6)
void ip_2_ip6_hdr(struct ip6_hdr *, struct ip *);
#endif
int sctp_bindx(struct socket *, int, struct sockaddr_storage *,
int, int, struct lwp *);
/* can't use sctp_assoc_t here */
int sctp_peeloff(struct socket *, struct socket *, int, vaddr_t, int *);
sctp_assoc_t sctp_getassocid(struct sockaddr *);
int sctp_sockaddr(struct socket *, struct sockaddr *);
int sctp_peeraddr(struct socket *, struct sockaddr *);
int sctp_listen(struct socket *, struct lwp *);
int sctp_accept(struct socket *, struct sockaddr *);
int sctp_sysctl(int *, u_int, void *, size_t *, void *, size_t);
#endif /* _KERNEL */
#endif /* !_NETINET_SCTP_VAR_H_ */

3742
sys/netinet/sctputil.c Normal file

File diff suppressed because it is too large Load Diff

279
sys/netinet/sctputil.h Normal file
View File

@ -0,0 +1,279 @@
/* $KAME: sctputil.h,v 1.15 2005/03/06 16:04:19 itojun Exp $ */
/* $NetBSD: sctputil.h,v 1.1 2015/10/13 21:28:35 rjs Exp $ */
#ifndef __SCTPUTIL_H__
#define __SCTPUTIL_H__
/*
* 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.
*/
#if defined(_KERNEL)
#ifdef SCTP_MBUF_DEBUG
#define sctp_m_freem(m) do { \
printf("m_freem(%p) m->nxtpkt:%p at %s[%d]\n", \
(m), (m)->m_next, __FILE__, __LINE__); \
m_freem(m); \
} while (0);
#else
#define sctp_m_freem m_freem
#endif
#define sctp_m_copym m_copym
/*
* Zone(pool) allocation routines: MUST be defined for each OS
* zone = zone/pool pointer
* name = string name of the zone/pool
* size = size of each zone/pool element
* number = number of elements in zone/pool
*/
#if defined(__FreeBSD__)
#if __FreeBSD_version >= 500000
#include <vm/uma.h>
#else
#include <vm/vm_zone.h>
#endif
#elif defined(__NetBSD__) || defined(__OpenBSD__)
#include <sys/pool.h>
#endif
/* SCTP_ZONE_INIT: initialize the zone */
#if defined(__FreeBSD__)
#if __FreeBSD_version >= 500000
#define UMA_ZFLAG_FULL 0x0020
#define SCTP_ZONE_INIT(zone, name, size, number) { \
zone = uma_zcreate(name, size, NULL, NULL, NULL, NULL, UMA_ALIGN_PTR,\
UMA_ZFLAG_FULL); \
uma_zone_set_max(zone, number); \
}
#else
#define SCTP_ZONE_INIT(zone, name, size, number) \
zone = zinit(name, size, number, ZONE_INTERRUPT, 0);
#endif
#elif defined(__APPLE__)
#define SCTP_ZONE_INIT(zone, name, size, number) \
zone = (void *)zinit(size, number * size, number, name);
#elif defined(__OpenBSD__) || defined(__NetBSD__)
#define SCTP_ZONE_INIT(zone, name, size, number) \
pool_init(&(zone), size, 0, 0, 0, name, NULL, IPL_NET);
#else
/* don't know this OS! */
force_comile_error;
#endif
/* SCTP_ZONE_GET: allocate element from the zone */
#if defined(__FreeBSD__)
#if __FreeBSD_version >= 500000
#define SCTP_ZONE_GET(zone) \
uma_zalloc(zone, M_NOWAIT);
#else
#define SCTP_ZONE_GET(zone) \
zalloci(zone);
#endif
#elif defined(__APPLE__)
#define SCTP_ZONE_GET(zone) \
zalloc(zone);
#elif defined(__NetBSD__) || defined(__OpenBSD__)
#define SCTP_ZONE_GET(zone) \
pool_get(&zone, PR_NOWAIT);
#else
/* don't know this OS! */
force_comile_error;
#endif
/* SCTP_ZONE_FREE: free element from the zone */
#if defined(__FreeBSD__)
#if __FreeBSD_version >= 500000
#define SCTP_ZONE_FREE(zone, element) \
uma_zfree(zone, element);
#else
#define SCTP_ZONE_FREE(zone, element) \
zfreei(zone, element);
#endif
#elif defined(__APPLE__)
#define SCTP_ZONE_FREE(zone, element) \
zfree(zone, element);
#elif defined(__NetBSD__) || defined(__OpenBSD__)
#define SCTP_ZONE_FREE(zone, element) \
pool_put(&zone, element);
#else
/* don't know this OS! */
force_comile_error;
#endif
#define sctp_get_associd(stcb) ((sctp_assoc_t)stcb->asoc.my_vtag)
/*
* Function prototypes
*/
struct ifaddr *sctp_find_ifa_by_addr(struct sockaddr *sa);
u_int32_t sctp_select_initial_TSN(struct sctp_pcb *);
u_int32_t sctp_select_a_tag(struct sctp_inpcb *);
int sctp_init_asoc(struct sctp_inpcb *, struct sctp_association *, int, uint32_t);
void sctp_fill_random_store(struct sctp_pcb *);
int sctp_timer_start(int, struct sctp_inpcb *, struct sctp_tcb *,
struct sctp_nets *);
int sctp_timer_stop(int, struct sctp_inpcb *, struct sctp_tcb *,
struct sctp_nets *);
u_int32_t sctp_calculate_sum(struct mbuf *, int32_t *, u_int32_t);
void sctp_mtu_size_reset(struct sctp_inpcb *, struct sctp_association *,
u_long);
int find_next_best_mtu(int);
u_int32_t sctp_calculate_rto(struct sctp_tcb *, struct sctp_association *,
struct sctp_nets *, struct timeval *);
u_int32_t sctp_calculate_len(struct mbuf *);
void *sctp_m_getptr(struct mbuf *, int, int, u_int8_t *);
struct sctp_paramhdr *sctp_get_next_param(struct mbuf *, int,
struct sctp_paramhdr *, int);
int sctp_add_pad_tombuf(struct mbuf *, int);
int sctp_pad_lastmbuf(struct mbuf *, int);
void sctp_ulp_notify(u_int32_t, struct sctp_tcb *, u_int32_t, void *);
void sctp_report_all_outbound(struct sctp_tcb *);
int sctp_expand_mapping_array(struct sctp_association *);
void sctp_abort_notification(struct sctp_tcb *, int);
/* We abort responding to an IP packet for some reason */
void sctp_abort_association(struct sctp_inpcb *, struct sctp_tcb *,
struct mbuf *, int, struct sctphdr *, struct mbuf *);
/* We choose to abort via user input */
void sctp_abort_an_association(struct sctp_inpcb *, struct sctp_tcb *, int,
struct mbuf *);
void sctp_handle_ootb(struct mbuf *, int, int, struct sctphdr *,
struct sctp_inpcb *, struct mbuf *);
int sctp_is_there_an_abort_here(struct mbuf *, int, int *);
uint32_t sctp_is_same_scope(struct sockaddr_in6 *, struct sockaddr_in6 *);
const struct sockaddr_in6 *sctp_recover_scope(const struct sockaddr_in6 *,
struct sockaddr_in6 *);
int sctp_cmpaddr(const struct sockaddr *, const struct sockaddr *);
void sctp_print_address(const struct sockaddr *);
void sctp_print_address_pkt(struct ip *, struct sctphdr *);
int sbappendaddr_nocheck(struct sockbuf *, const struct sockaddr *,
struct mbuf *, struct mbuf *, u_int32_t, struct sctp_inpcb *);
int sctp_release_pr_sctp_chunk(struct sctp_tcb *, struct sctp_tmit_chunk *,
int, struct sctpchunk_listhead *);
struct mbuf *sctp_generate_invmanparam(int);
/*
* this is an evil layer violation that I think is a hack.. but I stand
* alone on the tsvwg in this thought... everyone else considers it part
* of the sockets layer (along with all of the peeloff code :<)
*/
u_int32_t sctp_get_first_vtag_from_sb(struct socket *);
void sctp_grub_through_socket_buffer(struct sctp_inpcb *, struct socket *,
struct socket *, struct sctp_tcb *);
void sctp_free_bufspace(struct sctp_tcb *, struct sctp_association *,
struct sctp_tmit_chunk *);
#ifdef SCTP_STAT_LOGGING
void sctp_log_strm_del_alt(u_int32_t, u_int16_t, int);
void sctp_log_strm_del(struct sctp_tmit_chunk *, struct sctp_tmit_chunk *, int);
void sctp_log_cwnd(struct sctp_nets *, int, uint8_t);
void sctp_log_maxburst(struct sctp_nets *, int, int, uint8_t);
void sctp_log_block(uint8_t, struct socket *, struct sctp_association *);
void sctp_log_rwnd(uint8_t, u_int32_t, u_int32_t, u_int32_t );
void sctp_log_mbcnt(uint8_t, u_int32_t, u_int32_t, u_int32_t, u_int32_t);
void sctp_log_rwnd_set(uint8_t, u_int32_t, u_int32_t, u_int32_t, u_int32_t);
int sctp_fill_stat_log(struct mbuf *);
void sctp_log_fr(uint32_t, uint32_t, uint32_t, int);
void sctp_log_map(uint32_t, uint32_t, uint32_t, int);
void sctp_clr_stat_log(void);
#endif
#ifdef SCTP_AUDITING_ENABLED
void sctp_auditing(int, struct sctp_inpcb *, struct sctp_tcb *,
struct sctp_nets *);
void sctp_audit_log(u_int8_t, u_int8_t);
#endif
#ifdef SCTP_BASE_FREEBSD
/* Note: these are in <sys/time.h>, but not in kernel space */
#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0
#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
#define timercmp(tvp, uvp, cmp) \
(((tvp)->tv_sec == (uvp)->tv_sec) ? \
((tvp)->tv_usec cmp (uvp)->tv_usec) : \
((tvp)->tv_sec cmp (uvp)->tv_sec))
#define timeradd(tvp, uvp, vvp) \
do { \
(vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \
(vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \
if ((vvp)->tv_usec >= 1000000) { \
(vvp)->tv_sec++; \
(vvp)->tv_usec -= 1000000; \
} \
} while (/* CONSTCOND */ 0)
#define timersub(tvp, uvp, vvp) \
do { \
(vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
(vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
if ((vvp)->tv_usec < 0) { \
(vvp)->tv_sec--; \
(vvp)->tv_usec += 1000000; \
} \
} while (/* CONSTCOND */ 0)
#endif /* SCTP_BASE_FREEBSD */
#endif /* _KERNEL */
#endif

View File

@ -1,4 +1,4 @@
# $NetBSD: files.netinet6,v 1.10 2015/02/10 19:11:52 rjs Exp $
# $NetBSD: files.netinet6,v 1.11 2015/10/13 21:28:35 rjs Exp $
defflag opt_inet6.h RFC2292
@ -33,3 +33,5 @@ file netinet6/udp6_output.c inet6
file netinet6/udp6_usrreq.c inet6
file netinet6/dccp6_usrreq.c inet6 & dccp
file netinet6/sctp6_usrreq.c inet6 & sctp

View File

@ -1,4 +1,4 @@
/* $NetBSD: in6_proto.c,v 1.106 2015/08/24 22:21:27 pooka Exp $ */
/* $NetBSD: in6_proto.c,v 1.107 2015/10/13 21:28:35 rjs Exp $ */
/* $KAME: in6_proto.c,v 1.66 2000/10/10 15:35:47 itojun Exp $ */
/*
@ -62,13 +62,14 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: in6_proto.c,v 1.106 2015/08/24 22:21:27 pooka Exp $");
__KERNEL_RCSID(0, "$NetBSD: in6_proto.c,v 1.107 2015/10/13 21:28:35 rjs Exp $");
#ifdef _KERNEL_OPT
#include "opt_gateway.h"
#include "opt_inet.h"
#include "opt_ipsec.h"
#include "opt_dccp.h"
#include "opt_sctp.h"
#endif
#include <sys/param.h>
@ -111,6 +112,13 @@ __KERNEL_RCSID(0, "$NetBSD: in6_proto.c,v 1.106 2015/08/24 22:21:27 pooka Exp $"
#include <netinet6/dccp6_var.h>
#endif
#ifdef SCTP
#include <netinet/sctp_pcb.h>
#include <netinet/sctp.h>
#include <netinet/sctp_var.h>
#include <netinet6/sctp6_var.h>
#endif
#include <netinet6/pim6_var.h>
#include <netinet6/nd6.h>
@ -172,6 +180,14 @@ PR_WRAP_CTLOUTPUT(dccp_ctloutput)
#define dccp_ctloutput dccp_ctloutput_wrapper
#endif
#if defined(SCTP)
PR_WRAP_CTLINPUT(sctp6_ctlinput)
PR_WRAP_CTLOUTPUT(sctp_ctloutput)
#define sctp6_ctlinput sctp6_ctlinput_wrapper
#define sctp_ctloutput sctp_ctloutput_wrapper
#endif
#if defined(IPSEC)
PR_WRAP_CTLINPUT(ah6_ctlinput)
@ -237,6 +253,36 @@ const struct ip6protosw inet6sw[] = {
#endif
},
#endif /* DCCP */
#ifdef SCTP
{ .pr_type = SOCK_DGRAM,
.pr_domain = &inet6domain,
.pr_protocol = IPPROTO_SCTP,
.pr_flags = PR_ADDR_OPT|PR_WANTRCVD,
.pr_input = sctp6_input,
.pr_ctlinput = sctp6_ctlinput,
.pr_ctloutput = sctp_ctloutput,
.pr_usrreqs = &sctp6_usrreqs,
.pr_drain = sctp_drain,
},
{ .pr_type = SOCK_SEQPACKET,
.pr_domain = &inet6domain,
.pr_protocol = IPPROTO_SCTP,
.pr_flags = PR_ADDR_OPT|PR_WANTRCVD,
.pr_input = sctp6_input,
.pr_ctlinput = sctp6_ctlinput,
.pr_ctloutput = sctp_ctloutput,
.pr_drain = sctp_drain,
},
{ .pr_type = SOCK_STREAM,
.pr_domain = &inet6domain,
.pr_protocol = IPPROTO_SCTP,
.pr_flags = PR_CONNREQUIRED|PR_ADDR_OPT|PR_WANTRCVD|PR_LISTEN,
.pr_input = sctp6_input,
.pr_ctlinput = sctp6_ctlinput,
.pr_ctloutput = sctp_ctloutput,
.pr_drain = sctp_drain,
},
#endif /* SCTP */
{ .pr_type = SOCK_RAW,
.pr_domain = &inet6domain,
.pr_protocol = IPPROTO_RAW,

1355
sys/netinet6/sctp6_usrreq.c Normal file

File diff suppressed because it is too large Load Diff

51
sys/netinet6/sctp6_var.h Normal file
View File

@ -0,0 +1,51 @@
/* $KAME: sctp6_var.h,v 1.7 2004/08/17 04:06:22 itojun Exp $ */
/* $NetBSD: sctp6_var.h,v 1.1 2015/10/13 21:28:35 rjs Exp $ */
/*
* Copyright (c) 2001, 2002, 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Cisco Systems, Inc.
* 4. 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 CISCO SYSTEMS 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 CISCO SYSTEMS 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.
*/
#ifndef _NETINET6_SCTP6_VAR_H_
#define _NETINET6_SCTP6_VAR_H_
#if defined(_KERNEL)
extern const struct pr_usrreqs sctp6_usrreqs;
int sctp6_ctloutput(int, struct socket *, int, int, struct mbuf **);
int sctp6_usrreq(struct socket *, int, struct mbuf *, struct mbuf *,
struct mbuf *, struct lwp *);
int sctp6_input(struct mbuf **, int *, int);
int sctp6_output(struct sctp_inpcb *, struct mbuf *, struct sockaddr *,
struct mbuf *, struct lwp *);
void * sctp6_ctlinput(int, const struct sockaddr *, void *);
#endif /* _KERNEL */
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: mbuf.h,v 1.158 2015/06/04 09:19:59 ozaki-r Exp $ */
/* $NetBSD: mbuf.h,v 1.159 2015/10/13 21:28:34 rjs Exp $ */
/*-
* Copyright (c) 1996, 1997, 1999, 2001, 2007 The NetBSD Foundation, Inc.
@ -360,6 +360,7 @@ MBUF_DEFINE(mbuf, MHLEN, MLEN);
/* for source-level compatibility */
#define M_CLUSTER M_EXT_CLUSTER
#define M_NOTIFICATION M_PROTO1
#define M_FLAGS_BITS \
"\20\1EXT\2PKTHDR\3EOR\4PROTO1\5AUTHIPHDR\6DECRYPTED\7LOOP\10AUTHIPDGM" \

View File

@ -1,4 +1,4 @@
/* $NetBSD: protosw.h,v 1.64 2015/05/02 17:18:04 rtr Exp $ */
/* $NetBSD: protosw.h,v 1.65 2015/10/13 21:28:34 rjs Exp $ */
/*-
* Copyright (c) 1982, 1986, 1993
@ -119,6 +119,8 @@ struct protosw {
#define PR_PURGEIF 0x100 /* might store struct ifnet pointer;
pr_purgeif() must be called on ifnet
deletion */
#define PR_ADDR_OPT 0x200 /* Allow address during delivery */
/*
* The arguments to usrreq are:

View File

@ -1,4 +1,4 @@
/* $NetBSD: socket.h,v 1.117 2015/04/03 20:01:08 rtr Exp $ */
/* $NetBSD: socket.h,v 1.118 2015/10/13 21:28:34 rjs Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -521,6 +521,7 @@ struct msghdr {
#define MSG_CMSG_CLOEXEC 0x0800 /* close on exec receiving fd */
#define MSG_NBIO 0x1000 /* use non-blocking I/O */
#define MSG_WAITFORONE 0x2000 /* recvmmsg() wait for one message */
#define MSG_NOTIFICATION 0x4000 /* SCTP notification */
struct mmsghdr {
struct msghdr msg_hdr;