Ok, here it is, we finally add SCTP to current. Note that this

work is not just mine, but it is also the works of Peter Lei
and Michael Tuexen. They both are my two key other developers
working on the project.. and they need ata-boy's too:
****
peterlei@cisco.com
tuexen@fh-muenster.de
****
I did do a make sysent which updated the
syscall's and sysproto.. I hope that is correct... without
it you don't build since we have new syscalls for SCTP :-0

So go out and look at the NOTES, add
option SCTP (make sure inet and inet6 are present too)
and play with SCTP.

I will see about comitting some test tools I have after I
figure out where I should place them. I also have a
lib (libsctp.a) that adds some of the missing socketapi
functions that I need to put into lib's.. I will talk
to George about this :-)

There may still be some 64 bit issues in here, none of
us have a 64 bit processor to test with yet.. Michael
may have a MAC but thats another beast too..

If you have a mac and want to use SCTP contact Michael
he maintains a web site with a loadable module with
this code :-)

Reviewed by:	gnn
Approved by:	gnn
This commit is contained in:
Randall Stewart 2006-11-03 15:23:16 +00:00
parent 957d7c8f9c
commit f8829a4a40
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=163953
51 changed files with 54873 additions and 6 deletions

View File

@ -771,3 +771,13 @@
468 AUE_NULL UNIMPL nosys
469 AUE_NULL UNIMPL __getpath_fromfd
470 AUE_NULL UNIMPL __getpath_fromaddr
471 AUE_NULL STD { int sctp_peeloff(int sd, uint32_t name); }
472 AUE_NULL STD { int sctp_generic_sendmsg(int sd, caddr_t msg, int mlen, \
caddr_t to, __socklen_t tolen, \
struct sctp_sndrcvinfo *sinfo, int flags); }
473 AUE_NULL STD { int sctp_generic_sendmsg_iov(int sd, struct iovec *iov, int iovlen, \
caddr_t to, __socklen_t tolen, \
struct sctp_sndrcvinfo *sinfo, int flags); }
474 AUE_NULL STD { int sctp_generic_recvmsg(int sd, struct iovec *iov, int iovlen, \
struct sockaddr * from, __socklen_t *fromlenaddr, \
struct sctp_sndrcvinfo *sinfo, int *msg_flags); }

View File

@ -506,6 +506,97 @@ options LIBMCHAIN
# libalias library, performing NAT
options LIBALIAS
#
# SCTP is a NEW transport protocol defined by
# RFC2960 updated by RFC3309 and RFC3758.. and
# soon to have a new base RFC and many many more
# extensions. This release supports all the extensions
# including many drafts (most about to become RFC's).
# It is the premeier SCTP implementation in the NET
# and is quite well tested.
#
# Note YOU MUST have both INET and INET6 defined.
# you don't have to enable V6, but SCTP is
# dual stacked and so far we have not teased apart
# the V6 and V4.. since an association can span
# both a V6 and V4 address at the SAME time :-)
#
options SCTP
# There are bunches of options:
# this one turns on all sorts of
# nastly printing that you can
# do. Its all controled by a
# bit mask (settable by socket opt and
# by sysctl). Including will not cause
# logging until you set the bits.. but it
# can be quite verbose.. so without this
# option we don't do any of the tests for
# bits and prints.. which makes the code run
# faster.. if you are not debugging don't use.
options SCTP_DEBUG
#
# High speed enables sally floyds HS TCP optioin
# for congestion control increase, use only in
# very HS networks and with caution since I doubt
# it will compete fairly with peers. For the big-bad
# internet its best NOT to enable.
#
options SCTP_HIGH_SPEED
#
# This option turns off the CRC32c checksum. Basically
# You will not be able to talk to anyone else that
# has not done this. Its more for expermentation to
# see how much CPU the CRC32c really takes. Most new
# cards for TCP support checksum offload.. so this
# option gives you a "view" into what SCTP would be
# like with such an offload (which only exists in
# high in iSCSI boards so far). With the new
# splitting 8's algorithm its not as bad as it used
# to be.. but it does speed things up try only
# for in a captured lab environment :-)
options SCTP_WITH_NO_CSUM
#
# Logging, this is another debug tool thats way
# cool.. but does take resources so its off
# by default. To do any logging you must first
# enable SCTP_STAT_LOGGING. This gets the utilities
# into the code base that actually do the logging and
# alocates a hugh fixed circular buffer that logging
# uses (about 80,000 entires that are probably 8 long
# words or so long.. so it does take a LOT of memory).
# Its cool for real-time debugging though.
#
options SCTP_STAT_LOGGING
#
# All that options after that turn on specific types of
# logging. You can monitor CWND growth, flight size
# and all sorts of things. Go look at the code and
# see. I have used this to produce interesting
# charts and graphs as well :->
#
# I have not yet commited the tools to get and print
# the logs, I will do that eventually .. before then
# if you want them send me an email rrs@freebsd.org
#
options SCTP_LOG_MAXBURST
options SCTP_LOG_RWND
options SCTP_CWND_LOGGING
options SCTP_CWND_MONITOR
options SCTP_BLK_LOGGING
options SCTP_STR_LOGGING
options SCTP_FR_LOGGING
options SCTP_MAP_LOGGING
options SCTP_SACK_LOGGING
options SCTP_LOCK_LOGGING
options SCTP_RTTVAR_LOGGING
options SCTP_SB_LOGGING
options SCTP_EARLYFR_LOGGING
options SCTP_NAGLE_LOGGING
options SCTP_WAKE_LOGGING
options SCTP_RECV_RWND_LOGGING
options SCTP_SACK_RWND_LOGGING
options SCTP_MBUF_LOGGING
# altq(9). Enable the base part of the hooks with the ALTQ option.
# Individual disciplines must be built into the base system and can not be
# loaded as modules at this point. ALTQ requires a stable TSC so if yours is

View File

@ -349,8 +349,9 @@ crypto/rijndael/rijndael-alg-fst.c optional crypto | geom_bde | \
crypto/rijndael/rijndael-api-fst.c optional geom_bde | random
crypto/rijndael/rijndael-api.c optional crypto | ipsec | wlan_ccmp
crypto/sha1.c optional carp | crypto | ipsec | \
netgraph_mppc_encryption
crypto/sha2/sha2.c optional crypto | geom_bde | ipsec | random
netgraph_mppc_encryption | sctp
crypto/sha2/sha2.c optional crypto | geom_bde | ipsec | random | \
sctp
ddb/db_access.c optional ddb
ddb/db_break.c optional ddb
ddb/db_command.c optional ddb
@ -1748,6 +1749,18 @@ netinet/ip_mroute.c optional mrouting
netinet/ip_options.c optional inet
netinet/ip_output.c optional inet
netinet/raw_ip.c optional inet
netinet/sctp_usrreq.c optional inet inet6 sctp
netinet/sctp_pcb.c optional inet inet6 sctp
netinet/sctputil.c optional inet inet6 sctp
netinet/sctp_bsd_addr.c optional inet inet6 sctp
netinet/sctp_timer.c optional inet inet6 sctp
netinet/sctp_input.c optional inet inet6 sctp
netinet/sctp_output.c optional inet inet6 sctp
netinet/sctp_indata.c optional inet inet6 sctp
netinet/sctp_asconf.c optional inet inet6 sctp
netinet/sctp_peeloff.c optional inet inet6 sctp
netinet/sctp_crc32.c optional inet inet6 sctp
netinet/sctp_auth.c optional inet inet6 sctp
netinet/tcp_debug.c optional tcpdebug
netinet/tcp_hostcache.c optional inet
netinet/tcp_input.c optional inet
@ -1800,6 +1813,7 @@ netinet6/nd6_rtr.c optional inet6
netinet6/raw_ip6.c optional inet6
netinet6/route6.c optional inet6
netinet6/scope6.c optional inet6
netinet6/sctp6_usrreq.c optional inet6 inet6 sctp
netinet6/udp6_output.c optional inet6
netinet6/udp6_usrreq.c optional inet6
netipsec/ipsec.c optional fast_ipsec

View File

@ -395,6 +395,33 @@ DEV_VLAN opt_vlan.h
VLAN_ARRAY opt_vlan.h
XBONEHACK
#
# SCTP
#
SCTP opt_sctp.h
SCTP_DEBUG opt_sctp.h
SCTP_HIGH_SPEED opt_sctp.h
SCTP_LOG_MAXBURST opt_sctp.h
SCTP_LOG_RWND opt_sctp.h
SCTP_STAT_LOGGING opt_sctp.h
SCTP_CWND_LOGGING opt_sctp.h
SCTP_CWND_MONITOR opt_sctp.h
SCTP_BLK_LOGGING opt_sctp.h
SCTP_STR_LOGGING opt_sctp.h
SCTP_FR_LOGGING opt_sctp.h
SCTP_MAP_LOGGING opt_sctp.h
SCTP_SACK_LOGGING opt_sctp.h
SCTP_LOCK_LOGGING opt_sctp.h
SCTP_RTTVAR_LOGGING opt_sctp.h
SCTP_SB_LOGGING opt_sctp.h
SCTP_WITH_NO_CSUM opt_sctp.h
SCTP_EARLYFR_LOGGING opt_sctp.h
SCTP_NAGLE_LOGGING opt_sctp.h
SCTP_WAKE_LOGGING opt_sctp.h
SCTP_RECV_RWND_LOGGING opt_sctp.h
SCTP_SACK_RWND_LOGGING opt_sctp.h
SCTP_MBUF_LOGGING opt_sctp.h
# Netgraph(4). Use option NETGRAPH to enable the base netgraph code.
# Each netgraph node type can be either be compiled into the kernel
# or loaded dynamically. To get the former, include the corresponding

View File

@ -500,4 +500,8 @@ struct sysent sysent[] = {
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 }, /* 468 = nosys */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 }, /* 469 = __getpath_fromfd */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 }, /* 470 = __getpath_fromaddr */
{ AS(sctp_peeloff_args), (sy_call_t *)sctp_peeloff, AUE_NULL, NULL, 0, 0 }, /* 471 = sctp_peeloff */
{ AS(sctp_generic_sendmsg_args), (sy_call_t *)sctp_generic_sendmsg, AUE_NULL, NULL, 0, 0 }, /* 472 = sctp_generic_sendmsg */
{ AS(sctp_generic_sendmsg_iov_args), (sy_call_t *)sctp_generic_sendmsg_iov, AUE_NULL, NULL, 0, 0 }, /* 473 = sctp_generic_sendmsg_iov */
{ AS(sctp_generic_recvmsg_args), (sy_call_t *)sctp_generic_recvmsg, AUE_NULL, NULL, 0, 0 }, /* 474 = sctp_generic_recvmsg */
};

View File

@ -478,4 +478,8 @@ const char *syscallnames[] = {
"#468", /* 468 = nosys */
"#469", /* 469 = __getpath_fromfd */
"#470", /* 470 = __getpath_fromaddr */
"sctp_peeloff", /* 471 = sctp_peeloff */
"sctp_generic_sendmsg", /* 472 = sctp_generic_sendmsg */
"sctp_generic_sendmsg_iov", /* 473 = sctp_generic_sendmsg_iov */
"sctp_generic_recvmsg", /* 474 = sctp_generic_recvmsg */
};

View File

@ -825,5 +825,15 @@
468 AUE_NULL UNIMPL nosys
469 AUE_NULL UNIMPL __getpath_fromfd
470 AUE_NULL UNIMPL __getpath_fromaddr
471 AUE_NULL STD { int sctp_peeloff(int sd, uint32_t name); }
472 AUE_NULL STD { int sctp_generic_sendmsg(int sd, caddr_t msg, int mlen, \
caddr_t to, __socklen_t tolen, \
struct sctp_sndrcvinfo *sinfo, int flags); }
473 AUE_NULL STD { int sctp_generic_sendmsg_iov(int sd, struct iovec *iov, int iovlen, \
caddr_t to, __socklen_t tolen, \
struct sctp_sndrcvinfo *sinfo, int flags); }
474 AUE_NULL STD { int sctp_generic_recvmsg(int sd, struct iovec *iov, int iovlen, \
struct sockaddr * from, __socklen_t *fromlenaddr, \
struct sctp_sndrcvinfo *sinfo, int *msg_flags); }
; Please copy any additions and changes to the following compatability tables:
; sys/compat/freebsd32/syscalls.master

View File

@ -2758,6 +2758,53 @@ systrace_args(int sysnum, void *params, u_int64_t *uarg, int *n_args)
*n_args = 3;
break;
}
/* sctp_peeloff */
case 471: {
struct sctp_peeloff_args *p = params;
iarg[0] = p->sd; /* int */
uarg[1] = p->name; /* uint32_t */
*n_args = 2;
break;
}
/* sctp_generic_sendmsg */
case 472: {
struct sctp_generic_sendmsg_args *p = params;
iarg[0] = p->sd; /* int */
uarg[1] = (intptr_t) p->msg; /* caddr_t */
iarg[2] = p->mlen; /* int */
uarg[3] = (intptr_t) p->to; /* caddr_t */
iarg[4] = p->tolen; /* __socklen_t */
uarg[5] = (intptr_t) p->sinfo; /* struct sctp_sndrcvinfo * */
iarg[6] = p->flags; /* int */
*n_args = 7;
break;
}
/* sctp_generic_sendmsg_iov */
case 473: {
struct sctp_generic_sendmsg_iov_args *p = params;
iarg[0] = p->sd; /* int */
uarg[1] = (intptr_t) p->iov; /* struct iovec * */
iarg[2] = p->iovlen; /* int */
uarg[3] = (intptr_t) p->to; /* caddr_t */
iarg[4] = p->tolen; /* __socklen_t */
uarg[5] = (intptr_t) p->sinfo; /* struct sctp_sndrcvinfo * */
iarg[6] = p->flags; /* int */
*n_args = 7;
break;
}
/* sctp_generic_recvmsg */
case 474: {
struct sctp_generic_recvmsg_args *p = params;
iarg[0] = p->sd; /* int */
uarg[1] = (intptr_t) p->iov; /* struct iovec * */
iarg[2] = p->iovlen; /* int */
uarg[3] = (intptr_t) p->from; /* struct sockaddr * */
uarg[4] = (intptr_t) p->fromlenaddr; /* __socklen_t * */
uarg[5] = (intptr_t) p->sinfo; /* struct sctp_sndrcvinfo * */
uarg[6] = (intptr_t) p->msg_flags; /* int * */
*n_args = 7;
break;
}
default:
*n_args = 0;
break;

View File

@ -35,6 +35,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_sctp.h"
#include "opt_compat.h"
#include "opt_ktrace.h"
#include "opt_mac.h"
@ -76,6 +77,11 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_kern.h>
#include <vm/vm_extern.h>
#ifdef SCTP
#include <netinet/sctp.h>
#include <netinet/sctp_peeloff.h>
#endif /* SCTP */
static int sendit(struct thread *td, int s, struct msghdr *mp, int flags);
static int recvit(struct thread *td, int s, struct msghdr *mp, void *namelenp);
@ -2319,3 +2325,448 @@ kern_sendfile(struct thread *td, struct sendfile_args *uap,
return (error);
}
int
sctp_peeloff(td, uap)
struct thread *td;
register struct sctp_peeloff_args /* {
int sd;
caddr_t name;
} */ *uap;
{
#ifdef SCTP
struct filedesc *fdp;
struct file *nfp = NULL;
int error;
struct socket *head, *so;
int fd;
u_int fflag;
fdp = td->td_proc->p_fd;
error = fgetsock(td, uap->sd, &head, &fflag);
if (error)
goto done2;
error = sctp_can_peel_off(head, (sctp_assoc_t)uap->name);
if (error)
goto done2;
/*
* At this point we know we do have a assoc to pull
* we proceed to get the fd setup. This may block
* but that is ok.
*/
error = falloc(td, &nfp, &fd);
if (error)
goto done;
td->td_retval[0] = fd;
so = sonewconn(head, SS_ISCONNECTED);
if (so == NULL)
goto noconnection;
/*
* Before changing the flags on the socket, we have to bump the
* reference count. Otherwise, if the protocol calls sofree(),
* the socket will be released due to a zero refcount.
*/
SOCK_LOCK(so);
soref(so); /* file descriptor reference */
SOCK_UNLOCK(so);
ACCEPT_LOCK();
TAILQ_REMOVE(&head->so_comp, so, so_list);
head->so_qlen--;
so->so_state |= (head->so_state & SS_NBIO);
so->so_state &= ~SS_NOFDREF;
so->so_qstate &= ~SQ_COMP;
so->so_head = NULL;
ACCEPT_UNLOCK();
error = sctp_do_peeloff(head, so, (sctp_assoc_t)uap->name);
if (error)
goto noconnection;
if (head->so_sigio != NULL)
fsetown(fgetown(&head->so_sigio), &so->so_sigio);
FILE_LOCK(nfp);
nfp->f_data = so;
nfp->f_flag = fflag;
nfp->f_ops = &socketops;
nfp->f_type = DTYPE_SOCKET;
FILE_UNLOCK(nfp);
noconnection:
/*
* close the new descriptor, assuming someone hasn't ripped it
* out from under us.
*/
if (error)
fdclose(fdp, nfp, fd, td);
/*
* Release explicitly held references before returning.
*/
done:
if (nfp != NULL)
fdrop(nfp, td);
fputsock(head);
done2:
return (error);
#else
return (EOPNOTSUPP);
#endif
}
int sctp_generic_sendmsg (td, uap)
struct thread *td;
register struct sctp_generic_sendmsg_args /* {
int sd,
caddr_t msg,
int mlen,
caddr_t to,
__socklen_t tolen,
struct sctp_sndrcvinfo *sinfo,
int flags
} */ *uap;
{
#ifdef SCTP
struct sctp_sndrcvinfo sinfo, *u_sinfo=NULL;
struct socket *so;
struct file *fp;
int use_rcvinfo=1;
int error=0, len;
struct sockaddr *to=NULL;
#ifdef KTRACE
struct uio *ktruio = NULL;
#endif
struct uio auio;
struct iovec iov[1];
if(uap->sinfo) {
error = copyin(uap->sinfo, &sinfo, sizeof (sinfo));
if (error)
return (error);
u_sinfo = &sinfo;
}
if(uap->tolen) {
error = getsockaddr(&to, uap->to, uap->tolen);
if (error) {
to = NULL;
goto sctp_bad2;
}
}
error = getsock(td->td_proc->p_fd, uap->sd, &fp, NULL);
if (error)
goto sctp_bad;
iov[0].iov_base = uap->msg;
iov[0].iov_len = uap->mlen;
so = (struct socket *)fp->f_data;
#ifdef MAC
SOCK_LOCK(so);
error = mac_check_socket_send(td->td_ucred, so);
SOCK_UNLOCK(so);
if (error)
goto sctp_bad;
#endif
auio.uio_iov = iov;
auio.uio_iovcnt = 1;
auio.uio_segflg = UIO_USERSPACE;
auio.uio_rw = UIO_WRITE;
auio.uio_td = td;
auio.uio_offset = 0; /* XXX */
auio.uio_resid = 0;
len = auio.uio_resid = uap->mlen;
error = sctp_lower_sosend(so,
to,
&auio,
(struct mbuf *)NULL,
(struct mbuf *)NULL,
uap->flags,
use_rcvinfo,
u_sinfo,
td );
if (error) {
if (auio.uio_resid != len && (error == ERESTART ||
error == EINTR || error == EWOULDBLOCK))
error = 0;
/* Generation of SIGPIPE can be controlled per socket */
if (error == EPIPE && !(so->so_options & SO_NOSIGPIPE) &&
!(uap->flags & MSG_NOSIGNAL)) {
PROC_LOCK(td->td_proc);
psignal(td->td_proc, SIGPIPE);
PROC_UNLOCK(td->td_proc);
}
}
if (error == 0)
td->td_retval[0] = len - auio.uio_resid;
#ifdef KTRACE
if (ktruio != NULL) {
ktruio->uio_resid = td->td_retval[0];
ktrgenio(uap->sd, UIO_WRITE, ktruio, error);
}
#endif
sctp_bad:
fdrop(fp, td);
sctp_bad2:
if (to)
FREE(to, M_SONAME);
return (error);
#else
return (EOPNOTSUPP);
#endif
}
int sctp_generic_sendmsg_iov(td, uap)
struct thread *td;
register struct sctp_generic_sendmsg_iov_args /* {
int sd,
struct iovec *iov,
int iovlen,
caddr_t to,
__socklen_t tolen,
struct sctp_sndrcvinfo *sinfo,
int flags
} */ *uap;
{
#ifdef SCTP
struct sctp_sndrcvinfo sinfo, *u_sinfo=NULL;
struct socket *so;
struct file *fp;
int use_rcvinfo=1;
int error=0, len, i;
struct sockaddr *to=NULL;
#ifdef KTRACE
struct uio *ktruio = NULL;
#endif
struct uio auio;
struct iovec *iov, *tiov;
if(uap->sinfo) {
error = copyin(uap->sinfo, &sinfo, sizeof (sinfo));
if (error)
return (error);
u_sinfo = &sinfo;
}
if(uap->tolen) {
error = getsockaddr(&to, uap->to, uap->tolen);
if (error) {
to = NULL;
goto sctp_bad2;
}
}
error = getsock(td->td_proc->p_fd, uap->sd, &fp, NULL);
if (error)
goto sctp_bad1;
error = copyiniov(uap->iov, uap->iovlen, &iov, EMSGSIZE);
if (error)
goto sctp_bad1;
so = (struct socket *)fp->f_data;
#ifdef MAC
SOCK_LOCK(so);
error = mac_check_socket_send(td->td_ucred, so);
SOCK_UNLOCK(so);
if (error)
goto sctp_bad;
#endif
auio.uio_iov = iov;
auio.uio_iovcnt = uap->iovlen;
auio.uio_segflg = UIO_USERSPACE;
auio.uio_rw = UIO_WRITE;
auio.uio_td = td;
auio.uio_offset = 0; /* XXX */
auio.uio_resid = 0;
tiov = iov;
for (i = 0; i <uap->iovlen; i++, tiov++) {
if ((auio.uio_resid += tiov->iov_len) < 0) {
error = EINVAL;
goto sctp_bad;
}
}
len = auio.uio_resid;
error = sctp_lower_sosend(so,
to,
&auio,
(struct mbuf *)NULL,
(struct mbuf *)NULL,
uap->flags,
use_rcvinfo,
u_sinfo,
td );
if (error) {
if (auio.uio_resid != len && (error == ERESTART ||
error == EINTR || error == EWOULDBLOCK))
error = 0;
/* Generation of SIGPIPE can be controlled per socket */
if (error == EPIPE && !(so->so_options & SO_NOSIGPIPE) &&
!(uap->flags & MSG_NOSIGNAL)) {
PROC_LOCK(td->td_proc);
psignal(td->td_proc, SIGPIPE);
PROC_UNLOCK(td->td_proc);
}
}
if (error == 0)
td->td_retval[0] = len - auio.uio_resid;
#ifdef KTRACE
if (ktruio != NULL) {
ktruio->uio_resid = td->td_retval[0];
ktrgenio(uap->sd, UIO_WRITE, ktruio, error);
}
#endif
sctp_bad:
free(iov, M_IOV);
sctp_bad1:
fdrop(fp, td);
sctp_bad2:
if (to)
FREE(to, M_SONAME);
return (error);
#else
return (EOPNOTSUPP);
#endif
}
int sctp_generic_recvmsg(td, uap)
struct thread *td;
register struct sctp_generic_recvmsg_args /* {
int sd,
struct iovec *iov,
int iovlen,
struct sockaddr *from,
__socklen_t *fromlenaddr,
struct sctp_sndrcvinfo *sinfo,
int *msg_flags
} */ *uap;
{
#ifdef SCTP
u_int8_t sockbufstore[256];
struct uio auio;
struct iovec *iov, *tiov;
struct sctp_sndrcvinfo sinfo;
struct socket *so;
struct file *fp;
struct sockaddr *fromsa;
int fromlen;
int len, i, msg_flags=0;
int error=0;
#ifdef KTRACE
struct uio *ktruio = NULL;
#endif
error = getsock(td->td_proc->p_fd, uap->sd, &fp, NULL);
if (error) {
return (error);
}
error = copyiniov(uap->iov, uap->iovlen, &iov, EMSGSIZE);
if (error) {
goto out1;
}
so = fp->f_data;
#ifdef MAC
SOCK_LOCK(so);
error = mac_check_socket_receive(td->td_ucred, so);
SOCK_UNLOCK(so);
if (error) {
goto out;
return (error);
}
#endif
if (uap->fromlenaddr) {
error = copyin(uap->fromlenaddr,
&fromlen, sizeof (fromlen));
if (error) {
goto out;
}
} else {
fromlen = 0;
}
auio.uio_iov = iov;
auio.uio_iovcnt = uap->iovlen;
auio.uio_segflg = UIO_USERSPACE;
auio.uio_rw = UIO_READ;
auio.uio_td = td;
auio.uio_offset = 0; /* XXX */
auio.uio_resid = 0;
tiov = iov;
for (i = 0; i <uap->iovlen; i++, tiov++) {
if ((auio.uio_resid += tiov->iov_len) < 0) {
error = EINVAL;
goto out;
}
}
len = auio.uio_resid;
fromsa = (struct sockaddr *)sockbufstore;
#ifdef KTRACE
if (KTRPOINT(td, KTR_GENIO))
ktruio = cloneuio(&auio);
#endif
error = sctp_sorecvmsg(so, &auio, (struct mbuf **)NULL,
fromsa, fromlen, &msg_flags, (struct sctp_sndrcvinfo *)&sinfo,
1);
if (error) {
if (auio.uio_resid != (int)len && (error == ERESTART ||
error == EINTR || error == EWOULDBLOCK))
error = 0;
} else {
if(uap->sinfo)
error = copyout(&sinfo, uap->sinfo, sizeof (sinfo));
}
#ifdef KTRACE
if (ktruio != NULL) {
ktruio->uio_resid = (int)len - auio.uio_resid;
ktrgenio(uap->sd, UIO_READ, ktruio, error);
}
#endif
if (error)
goto out;
td->td_retval[0] = (int)len - auio.uio_resid;
if (fromlen && uap->from) {
len = fromlen;
if (len <= 0 || fromsa == 0)
len = 0;
else {
len = MIN(len, fromsa->sa_len);
error = copyout(fromsa, uap->from, (unsigned)len);
if (error)
goto out;
}
error = copyout(&len, uap->fromlenaddr, sizeof (socklen_t));
if(error) {
goto out;
}
}
if (uap->msg_flags) {
error = copyout(&msg_flags, uap->msg_flags, sizeof (int));
if(error) {
goto out;
}
}
out:
free(iov, M_IOV);
out1:
fdrop(fp, td);
return (error);
#else
return (EOPNOTSUPP);
#endif
}

View File

@ -29,7 +29,7 @@
* @(#)rtsock.c 8.7 (Berkeley) 10/12/95
* $FreeBSD$
*/
#include "opt_sctp.h"
#include <sys/param.h>
#include <sys/domain.h>
#include <sys/kernel.h>
@ -51,6 +51,10 @@
#include <netinet/in.h>
#ifdef SCTP
extern void sctp_addr_change(struct ifaddr *ifa, int cmd);
#endif /* SCTP */
MALLOC_DEFINE(M_RTABLE, "routetbl", "routing tables");
/* NB: these are not modified */
@ -879,7 +883,14 @@ rt_newaddrmsg(int cmd, struct ifaddr *ifa, int error, struct rtentry *rt)
KASSERT(cmd == RTM_ADD || cmd == RTM_DELETE,
("unexpected cmd %u", cmd));
#ifdef SCTP
/*
* notify the SCTP stack
* this will only get called when an address is added/deleted
* XXX pass the ifaddr struct instead if ifa->ifa_addr...
*/
sctp_addr_change(ifa, cmd);
#endif /* SCTP */
if (route_cb.any_count == 0)
return;
for (pass = 1; pass < 3; pass++) {

View File

@ -36,6 +36,7 @@
#include "opt_inet6.h"
#include "opt_pf.h"
#include "opt_carp.h"
#include "opt_sctp.h"
#include <sys/param.h>
#include <sys/systm.h>
@ -88,6 +89,13 @@ static struct pr_usrreqs nousrreqs;
#include <netipx/ipx_ip.h>
#endif
#ifdef SCTP
#include <netinet/in_pcb.h>
#include <netinet/sctp_pcb.h>
#include <netinet/sctp.h>
#include <netinet/sctp_var.h>
#endif /* SCTP */
#ifdef DEV_PFSYNC
#include <net/pfvar.h>
#include <net/if_pfsync.h>
@ -141,6 +149,43 @@ struct protosw inetsw[] = {
.pr_drain = tcp_drain,
.pr_usrreqs = &tcp_usrreqs
},
#ifdef SCTP
{
.pr_type = SOCK_DGRAM,
.pr_domain = &inetdomain,
.pr_protocol = IPPROTO_SCTP,
.pr_flags = PR_WANTRCVD,
.pr_input = sctp_input,
.pr_ctlinput = sctp_ctlinput,
.pr_ctloutput = sctp_ctloutput,
.pr_init = sctp_init,
.pr_drain = sctp_drain,
.pr_usrreqs = &sctp_usrreqs
},
{
.pr_type = SOCK_SEQPACKET,
.pr_domain = &inetdomain,
.pr_protocol = IPPROTO_SCTP,
.pr_flags = PR_WANTRCVD,
.pr_input = sctp_input,
.pr_ctlinput = sctp_ctlinput,
.pr_ctloutput = sctp_ctloutput,
.pr_drain = sctp_drain,
.pr_usrreqs = &sctp_usrreqs
},
{
.pr_type = SOCK_STREAM,
.pr_domain = &inetdomain,
.pr_protocol = IPPROTO_SCTP,
.pr_flags = PR_WANTRCVD,
.pr_input = sctp_input,
.pr_ctlinput = sctp_ctlinput,
.pr_ctloutput = sctp_ctloutput,
.pr_drain = sctp_drain,
.pr_usrreqs = &sctp_usrreqs
},
#endif /* SCTP */
{
.pr_type = SOCK_RAW,
.pr_domain = &inetdomain,
@ -376,6 +421,9 @@ SYSCTL_NODE(_net_inet, IPPROTO_IP, ip, CTLFLAG_RW, 0, "IP");
SYSCTL_NODE(_net_inet, IPPROTO_ICMP, icmp, CTLFLAG_RW, 0, "ICMP");
SYSCTL_NODE(_net_inet, IPPROTO_UDP, udp, CTLFLAG_RW, 0, "UDP");
SYSCTL_NODE(_net_inet, IPPROTO_TCP, tcp, CTLFLAG_RW, 0, "TCP");
#ifdef SCTP
SYSCTL_NODE(_net_inet, IPPROTO_SCTP, sctp, CTLFLAG_RW, 0, "SCTP");
#endif
SYSCTL_NODE(_net_inet, IPPROTO_IGMP, igmp, CTLFLAG_RW, 0, "IGMP");
#ifdef FAST_IPSEC
/* XXX no protocol # to use, pick something "reserved" */

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

@ -0,0 +1,349 @@
/*-
* Copyright (c) 2001-2006, 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:
*
* a) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* b) 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.
*
* c) Neither the name of Cisco Systems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
*/
/* $KAME: sctp.h,v 1.18 2005/03/06 16:04:16 itojun Exp $ */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#ifndef _NETINET_SCTP_H_
#define _NETINET_SCTP_H_
#include <sys/types.h>
/*
* SCTP protocol - RFC2960.
*/
struct sctphdr {
uint16_t src_port; /* source port */
uint16_t dest_port; /* destination port */
uint32_t v_tag; /* verification tag of packet */
uint32_t checksum; /* Adler32 C-Sum */
/* chunks follow... */
};
/*
* SCTP Chunks
*/
struct sctp_chunkhdr {
uint8_t chunk_type; /* chunk type */
uint8_t chunk_flags; /* chunk flags */
uint16_t chunk_length; /* chunk length */
/* optional params follow */
};
/*
* SCTP chunk parameters
*/
struct sctp_paramhdr {
uint16_t param_type; /* parameter type */
uint16_t param_length; /* parameter length */
};
/*
* user socket options: socket API defined
*/
/*
* read-write options
*/
#define SCTP_RTOINFO 0x00000001
#define SCTP_ASSOCINFO 0x00000002
#define SCTP_INITMSG 0x00000003
#define SCTP_NODELAY 0x00000004
#define SCTP_AUTOCLOSE 0x00000005
#define SCTP_SET_PEER_PRIMARY_ADDR 0x00000006
#define SCTP_PRIMARY_ADDR 0x00000007
#define SCTP_ADAPTATION_LAYER 0x00000008
/* same as above */
#define SCTP_ADAPTION_LAYER 0x00000008
#define SCTP_DISABLE_FRAGMENTS 0x00000009
#define SCTP_PEER_ADDR_PARAMS 0x0000000a
#define SCTP_DEFAULT_SEND_PARAM 0x0000000b
/* ancillary data/notification interest options */
#define SCTP_EVENTS 0x0000000c
/* Without this applied we will give V4 and V6 addresses on a V6 socket */
#define SCTP_I_WANT_MAPPED_V4_ADDR 0x0000000d
#define SCTP_MAXSEG 0x0000000e
#define SCTP_DELAYED_ACK_TIME 0x0000000f
#define SCTP_FRAGMENT_INTERLEAVE 0x00000010
#define SCTP_PARTIAL_DELIVERY_POINT 0x00000011
/* authentication support */
#define SCTP_AUTH_CHUNK 0x00000012
#define SCTP_AUTH_KEY 0x00000013
#define SCTP_HMAC_IDENT 0x00000014
#define SCTP_AUTH_ACTIVE_KEY 0x00000015
#define SCTP_AUTH_DELETE_KEY 0x00000016
#define SCTP_USE_EXT_RCVINFO 0x00000017
#define SCTP_AUTO_ASCONF 0x00000018 /* rw */
#define SCTP_MAXBURST 0x00000019 /* rw */
/* assoc level context */
#define SCTP_CONTEXT 0x0000001a /* rw */
/* explict EOR signalling */
#define SCTP_EXPLICIT_EOR 0x0000001b
/*
* read-only options
*/
#define SCTP_STATUS 0x00000100
#define SCTP_GET_PEER_ADDR_INFO 0x00000101
/* authentication support */
#define SCTP_PEER_AUTH_CHUNKS 0x00000102
#define SCTP_LOCAL_AUTH_CHUNKS 0x00000103
/*
* user socket options: BSD implementation specific
*/
/*
* 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.
*/
/* these should probably go into sockets API */
#define SCTP_RESET_STREAMS 0x00001004 /* wo */
/* here on down are more implementation specific */
#define SCTP_SET_DEBUG_LEVEL 0x00001005
#define SCTP_CLR_STAT_LOG 0x00001007
/* CMT ON/OFF socket option */
#define SCTP_CMT_ON_OFF 0x00001200
#define SCTP_CMT_USE_DAC 0x00001201
/* read only */
#define SCTP_GET_SNDBUF_USE 0x00001101
#define SCTP_GET_STAT_LOG 0x00001103
#define SCTP_GET_ASOC_ID_LIST 0x00001104 /* ro */
#define SCTP_PCB_STATUS 0x00001105
#define SCTP_GET_NONCE_VALUES 0x00001106
/*
* hidden implementation specific options these are NOT user visible (should
* move out of sctp.h)
*/
/* sctp_bindx() flags as hidden socket options */
#define SCTP_BINDX_ADD_ADDR 0x00008001
#define SCTP_BINDX_REM_ADDR 0x00008002
/* Hidden socket option that gets the addresses */
#define SCTP_GET_PEER_ADDRESSES 0x00008003
#define SCTP_GET_LOCAL_ADDRESSES 0x00008004
/* return the total count in bytes needed to hold all local addresses bound */
#define SCTP_GET_LOCAL_ADDR_SIZE 0x00008005
/* Return the total count in bytes needed to hold the remote address */
#define SCTP_GET_REMOTE_ADDR_SIZE 0x00008006
/* hidden option for connectx */
#define SCTP_CONNECT_X 0x00008007
/* hidden option for connectx_delayed, part of sendx */
#define SCTP_CONNECT_X_DELAYED 0x00008008
#define SCTP_CONNECT_X_COMPLETE 0x00008009
/* hidden socket option based sctp_peeloff */
#define SCTP_PEELOFF 0x0000800a
/* the real worker for sctp_getaddrlen() */
#define SCTP_GET_ADDR_LEN 0x0000800b
/* temporary workaround for Apple listen() issue, no args used */
#define SCTP_LISTEN_FIX 0x0000800c
/* Debug things that need to be purged */
#define SCTP_SET_INITIAL_DBG_SEQ 0x00009f00
/*
* 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_CAUSE_NO_ERROR 0x0000
#define SCTP_CAUSE_INVALID_STREAM 0x0001
#define SCTP_CAUSE_MISSING_PARAM 0x0002
#define SCTP_CAUSE_STALE_COOKIE 0x0003
#define SCTP_CAUSE_OUT_OF_RESC 0x0004
#define SCTP_CAUSE_UNRESOLVABLE_ADDR 0x0005
#define SCTP_CAUSE_UNRECOG_CHUNK 0x0006
#define SCTP_CAUSE_INVALID_PARAM 0x0007
#define SCTP_CAUSE_UNRECOG_PARAM 0x0008
#define SCTP_CAUSE_NO_USER_DATA 0x0009
#define SCTP_CAUSE_COOKIE_IN_SHUTDOWN 0x000a
#define SCTP_CAUSE_RESTART_W_NEWADDR 0x000b
#define SCTP_CAUSE_USER_INITIATED_ABT 0x000c
#define SCTP_CAUSE_PROTOCOL_VIOLATION 0x000d
/* Error causes from draft-ietf-tsvwg-addip-sctp */
#define SCTP_CAUSE_DELETING_LAST_ADDR 0x0100
#define SCTP_CAUSE_RESOURCE_SHORTAGE 0x0101
#define SCTP_CAUSE_DELETING_SRC_ADDR 0x0102
#define SCTP_CAUSE_ILLEGAL_ASCONF_ACK 0x0103
#define SCTP_CAUSE_REQUEST_REFUSED 0x0104
/* Error causes from draft-ietf-tsvwg-sctp-auth */
#define SCTP_CAUSE_UNSUPPORTED_HMACID 0x0105
/*
* error cause parameters (user visisble)
*/
struct sctp_error_cause {
uint16_t code;
uint16_t length;
/* optional cause-specific info may follow */
};
struct sctp_error_invalid_stream {
struct sctp_error_cause cause; /* code=SCTP_ERROR_INVALID_STREAM */
uint16_t stream_id; /* stream id of the DATA in error */
uint16_t reserved;
};
struct sctp_error_missing_param {
struct sctp_error_cause cause; /* code=SCTP_ERROR_MISSING_PARAM */
uint32_t num_missing_params; /* number of missing parameters */
/* uint16_t param_type's follow */
};
struct sctp_error_stale_cookie {
struct sctp_error_cause cause; /* code=SCTP_ERROR_STALE_COOKIE */
uint32_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_CAPABILITY 1
#define HAVE_SCTP_MULTIBUF 1
#define HAVE_SCTP_NOCONNECT 0
#define HAVE_SCTP_ECN_NONCE 1 /* ECN Nonce option */
#define HAVE_SCTP_AUTH 1
#define HAVE_SCTP_EXT_RCVINFO 1
#define HAVE_SCTP_CONNECTX 1
/*
* Main SCTP chunk types we place these here so natd and f/w's in user land
* can find them.
*/
/************0x00 series ***********/
#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-sctp-auth */
#define SCTP_AUTHENTICATION 0x0f
/************0x40 series ***********/
/************0x80 series ***********/
/* draft-ietf-tsvwg-addip-sctp */
#define SCTP_ASCONF_ACK 0x80
/* draft-ietf-stewart-pktdrpsctp */
#define SCTP_PACKET_DROPPED 0x81
/* draft-ietf-stewart-strreset-xxx */
#define SCTP_STREAM_RESET 0x82
/************0xc0 series ***********/
/* RFC3758 */
#define SCTP_FORWARD_CUM_TSN 0xc0
/* draft-ietf-tsvwg-addip-sctp */
#define SCTP_ASCONF 0xc1
/* 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
/* CMT DAC algorithm SACK flag */
#define SCTP_SACK_CMT_DAC 0x80
#include <netinet/sctp_uio.h>
#endif /* !_NETINET_SCTP_H_ */

2856
sys/netinet/sctp_asconf.c Normal file

File diff suppressed because it is too large Load Diff

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

@ -0,0 +1,80 @@
/*-
* Copyright (c) 2001-2006, 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:
*
* a) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* b) 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.
*
* c) Neither the name of Cisco Systems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
*/
/* $KAME: sctp_asconf.h,v 1.8 2005/03/06 16:04:16 itojun Exp $ */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#ifndef _NETINET_SCTP_ASCONF_H_
#define _NETINET_SCTP_ASCONF_H_
#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 *);
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 void sctp_addr_change(struct ifaddr *ifa, int cmd);
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_ */

2389
sys/netinet/sctp_auth.c Normal file

File diff suppressed because it is too large Load Diff

262
sys/netinet/sctp_auth.h Normal file
View File

@ -0,0 +1,262 @@
/*-
* Copyright (c) 2001-2006, 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:
*
* a) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* b) 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.
*
* c) Neither the name of Cisco Systems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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>
__FBSDID("$FreeBSD$");
#define HAVE_SHA2
#ifndef __SCTP_AUTH_H__
#define __SCTP_AUTH_H__
#include <sys/queue.h>
#include <sys/mbuf.h>
#ifdef USE_SCTP_SHA1
#include <netinet/sctp_sha1.h>
#else
#include <crypto/sha1.h>
/* map standard crypto API names */
#define SHA1_Init SHA1Init
#define SHA1_Update SHA1Update
#define SHA1_Final(x,y) SHA1Final((caddr_t)x, y)
#endif
#if defined(HAVE_SHA2)
#include <crypto/sha2/sha2.h>
#endif
#include <sys/md5.h>
/* map standard crypto API names */
#define MD5_Init MD5Init
#define MD5_Update MD5Update
#define MD5_Final MD5Final
/* digest lengths */
#define SCTP_AUTH_DIGEST_LEN_SHA1 20
#define SCTP_AUTH_DIGEST_LEN_MD5 16
#define SCTP_AUTH_DIGEST_LEN_SHA224 28
#define SCTP_AUTH_DIGEST_LEN_SHA256 32
#define SCTP_AUTH_DIGEST_LEN_SHA384 48
#define SCTP_AUTH_DIGEST_LEN_SHA512 64
#define SCTP_AUTH_DIGEST_LEN_MAX 64
/* random sizes */
#define SCTP_AUTH_RANDOM_SIZE_DEFAULT 32
#define SCTP_AUTH_RANDOM_SIZE_REQUIRED 32
#define SCTP_AUTH_RANDOM_SIZE_MAX 256
/* union of all supported HMAC algorithm contexts */
typedef union sctp_hash_context {
SHA1_CTX sha1;
MD5_CTX md5;
#ifdef HAVE_SHA2
SHA256_CTX sha256;
SHA384_CTX sha384;
SHA512_CTX sha512;
#endif
} sctp_hash_context_t;
typedef struct sctp_key {
uint32_t keylen;
uint8_t key[0];
} sctp_key_t;
typedef struct sctp_shared_key {
LIST_ENTRY(sctp_shared_key) next;
sctp_key_t *key; /* key text */
uint16_t keyid; /* shared key ID */
} sctp_sharedkey_t;
LIST_HEAD(sctp_keyhead, sctp_shared_key);
/* authentication chunks list */
typedef struct sctp_auth_chklist {
uint8_t chunks[256];
uint8_t num_chunks;
} sctp_auth_chklist_t;
/* hmac algos supported list */
typedef struct sctp_hmaclist {
uint16_t max_algo; /* max algorithms allocated */
uint16_t num_algo; /* num algorithms used */
uint16_t hmac[0];
} sctp_hmaclist_t;
/* authentication info */
typedef struct sctp_authinfo {
sctp_key_t *random; /* local random key (concatenated) */
uint32_t random_len; /* local random number length for param */
sctp_key_t *peer_random;/* peer's random key (concatenated) */
uint16_t assoc_keyid; /* current send keyid (cached) */
uint16_t recv_keyid; /* last recv keyid (cached) */
sctp_key_t *assoc_key; /* cached send key */
sctp_key_t *recv_key; /* cached recv key */
} sctp_authinfo_t;
/*
* global variables
*/
extern uint32_t sctp_asconf_auth_nochk; /* sysctl to disable ASCONF auth chk */
extern uint32_t sctp_auth_disable; /* sysctl for temp feature interop */
extern uint32_t sctp_auth_random_len; /* sysctl */
/*
* Macros
*/
#define sctp_auth_is_required_chunk(chunk, list) ((list == NULL) ? (0) : (list->chunks[chunk] != 0))
/*
* function prototypes
*/
/* socket option api functions */
extern sctp_auth_chklist_t *sctp_alloc_chunklist(void);
extern void sctp_free_chunklist(sctp_auth_chklist_t * chklist);
extern void sctp_clear_chunklist(sctp_auth_chklist_t * chklist);
extern sctp_auth_chklist_t *sctp_copy_chunklist(sctp_auth_chklist_t * chklist);
extern int sctp_auth_add_chunk(uint8_t chunk, sctp_auth_chklist_t * list);
extern int sctp_auth_delete_chunk(uint8_t chunk, sctp_auth_chklist_t * list);
extern int sctp_auth_get_chklist_size(const sctp_auth_chklist_t * list);
extern void sctp_auth_set_default_chunks(sctp_auth_chklist_t * list);
extern int
sctp_serialize_auth_chunks(const sctp_auth_chklist_t * list,
uint8_t * ptr);
extern int sctp_pack_auth_chunks(const sctp_auth_chklist_t * list, uint8_t * ptr);
extern int
sctp_unpack_auth_chunks(const uint8_t * ptr, uint8_t num_chunks,
sctp_auth_chklist_t * list);
/* key handling */
extern sctp_key_t *sctp_alloc_key(uint32_t keylen);
extern void sctp_free_key(sctp_key_t * key);
extern void sctp_print_key(sctp_key_t * key, const char *str);
extern void sctp_show_key(sctp_key_t * key, const char *str);
extern sctp_key_t *sctp_generate_random_key(uint32_t keylen);
extern sctp_key_t *sctp_set_key(uint8_t * key, uint32_t keylen);
extern sctp_key_t *
sctp_compute_hashkey(sctp_key_t * key1, sctp_key_t * key2,
sctp_key_t * shared);
/* shared key handling */
extern sctp_sharedkey_t *sctp_alloc_sharedkey(void);
extern void sctp_free_sharedkey(sctp_sharedkey_t * skey);
extern sctp_sharedkey_t *
sctp_find_sharedkey(struct sctp_keyhead *shared_keys,
uint16_t key_id);
extern void
sctp_insert_sharedkey(struct sctp_keyhead *shared_keys,
sctp_sharedkey_t * new_skey);
extern int
sctp_copy_skeylist(const struct sctp_keyhead *src,
struct sctp_keyhead *dest);
/* hmac list handling */
extern sctp_hmaclist_t *sctp_alloc_hmaclist(uint8_t num_hmacs);
extern void sctp_free_hmaclist(sctp_hmaclist_t * list);
extern int sctp_auth_add_hmacid(sctp_hmaclist_t * list, uint16_t hmac_id);
extern sctp_hmaclist_t *sctp_copy_hmaclist(sctp_hmaclist_t * list);
extern sctp_hmaclist_t *sctp_default_supported_hmaclist(void);
extern uint16_t
sctp_negotiate_hmacid(sctp_hmaclist_t * peer,
sctp_hmaclist_t * local);
extern int sctp_serialize_hmaclist(sctp_hmaclist_t * list, uint8_t * ptr);
extern int
sctp_verify_hmac_param(struct sctp_auth_hmac_algo *hmacs,
uint32_t num_hmacs);
extern sctp_authinfo_t *sctp_alloc_authinfo(void);
extern void sctp_free_authinfo(sctp_authinfo_t * authinfo);
/* keyed-HMAC functions */
extern uint32_t sctp_get_auth_chunk_len(uint16_t hmac_algo);
extern uint32_t sctp_get_hmac_digest_len(uint16_t hmac_algo);
extern uint32_t
sctp_hmac(uint16_t hmac_algo, uint8_t * key, uint32_t keylen,
const uint8_t * text, uint32_t textlen, uint8_t * digest);
extern int
sctp_verify_hmac(uint16_t hmac_algo, uint8_t * key, uint32_t keylen,
const uint8_t * text, uint32_t textlen, uint8_t * digest,
uint32_t digestlen);
extern uint32_t
sctp_compute_hmac(uint16_t hmac_algo, sctp_key_t * key,
const uint8_t * text, uint32_t textlen, uint8_t * digest);
extern int sctp_auth_is_supported_hmac(sctp_hmaclist_t * list, uint16_t id);
/* mbuf versions */
extern uint32_t
sctp_hmac_m(uint16_t hmac_algo, uint8_t * key, uint32_t keylen,
struct mbuf *m, uint32_t m_offset, uint8_t * digest);
extern uint32_t
sctp_compute_hmac_m(uint16_t hmac_algo, sctp_key_t * key, struct mbuf *m,
uint32_t m_offset, uint8_t * digest);
/*
* authentication routines
*/
extern void sctp_clear_cachedkeys(struct sctp_tcb *stcb, uint16_t keyid);
extern void sctp_clear_cachedkeys_ep(struct sctp_inpcb *inp, uint16_t keyid);
extern int sctp_delete_sharedkey(struct sctp_tcb *stcb, uint16_t keyid);
extern int sctp_delete_sharedkey_ep(struct sctp_inpcb *inp, uint16_t keyid);
extern int sctp_auth_setactivekey(struct sctp_tcb *stcb, uint16_t keyid);
extern int sctp_auth_setactivekey_ep(struct sctp_inpcb *inp, uint16_t keyid);
extern void
sctp_auth_get_cookie_params(struct sctp_tcb *stcb, struct mbuf *m,
uint32_t offset, uint32_t length);
extern void
sctp_fill_hmac_digest_m(struct mbuf *m, uint32_t auth_offset,
struct sctp_auth_chunk *auth,
struct sctp_tcb *stcb);
extern struct mbuf *
sctp_add_auth_chunk(struct mbuf *m, struct mbuf **m_end,
struct sctp_auth_chunk **auth_ret,
uint32_t * offset, struct sctp_tcb *stcb,
uint8_t chunk);
extern int
sctp_handle_auth(struct sctp_tcb *stcb, struct sctp_auth_chunk *ch,
struct mbuf *m, uint32_t offset);
extern void
sctp_notify_authentication(struct sctp_tcb *stcb,
uint32_t indication, uint16_t keyid,
uint16_t alt_keyid);
extern int
sctp_validate_init_auth_params(struct mbuf *m, int offset, int limit);
extern void
sctp_initialize_auth_params(struct sctp_inpcb *inp, struct sctp_tcb *stcb);
/* test functions */
extern void sctp_test_hmac_sha1(void);
extern void sctp_test_hmac_md5(void);
extern void sctp_test_authkey(void);
#endif /* __SCTP_AUTH_H__ */

2032
sys/netinet/sctp_bsd_addr.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,70 @@
/*-
* Copyright (c) 2001-2006, 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:
*
* a) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* b) 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.
*
* c) Neither the name of Cisco Systems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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>
__FBSDID("$FreeBSD$");
#ifndef __sctp_bsd_addr_h__
#define __sctp_bsd_addr_h__
#include <netinet/sctp_header.h>
#if defined(_KERNEL)
int sctp_is_addr_restricted(struct sctp_tcb *, struct sockaddr *);
struct in_addr
sctp_ipv4_source_address_selection(struct sctp_inpcb *inp,
struct sctp_tcb *stcb,
struct route *ro, struct sctp_nets *net,
int non_asoc_addr_ok);
struct in6_addr
sctp_ipv6_source_address_selection(struct sctp_inpcb *,
struct sctp_tcb *, struct route *,
struct sctp_nets *, int);
struct mbuf *
sctp_add_addresses_to_i_ia(struct sctp_inpcb *inp,
struct sctp_scoping *scope,
struct mbuf *m_at,
int cnt_inits_to);
#endif
#endif

View File

@ -0,0 +1,903 @@
/*-
* Copyright (c) 2001-2006, 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:
*
* a) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* b) 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.
*
* c) Neither the name of Cisco Systems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
*/
/* $KAME: sctp_constants.h,v 1.17 2005/03/06 16:04:17 itojun Exp $ */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#ifndef __sctp_constants_h__
#define __sctp_constants_h__
#if defined(_KERNEL)
#include <sys/kernel.h>
#endif
#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
#define SCTP_LOG_NEW_SACK 42
#define SCTP_LOG_TSN_ACKED 43
#define SCTP_LOG_TSN_REVOKED 44
#define SCTP_LOG_LOCK_TCB 45
#define SCTP_LOG_LOCK_INP 46
#define SCTP_LOG_LOCK_SOCK 47
#define SCTP_LOG_LOCK_SOCKBUF_R 48
#define SCTP_LOG_LOCK_SOCKBUF_S 49
#define SCTP_LOG_LOCK_CREATE 50
#define SCTP_LOG_INITIAL_RTT 51
#define SCTP_LOG_RTTVAR 52
#define SCTP_LOG_SBALLOC 53
#define SCTP_LOG_SBFREE 54
#define SCTP_LOG_SBRESULT 55
#define SCTP_FR_DUPED 56
#define SCTP_FR_MARKED_EARLY 57
#define SCTP_FR_CWND_REPORT 58
#define SCTP_FR_CWND_REPORT_START 59
#define SCTP_FR_CWND_REPORT_STOP 60
#define SCTP_CWND_LOG_FROM_SEND 61
#define SCTP_CWND_INITIALIZATION 62
#define SCTP_CWND_LOG_FROM_T3 63
#define SCTP_CWND_LOG_FROM_SACK 64
#define SCTP_CWND_LOG_NO_CUMACK 65
#define SCTP_CWND_LOG_FROM_RESEND 66
#define SCTP_FR_LOG_CHECK_STRIKE 67
#define SCTP_SEND_NOW_COMPLETES 68
#define SCTP_CWND_LOG_FILL_OUTQ_CALLED 69
#define SCTP_CWND_LOG_FILL_OUTQ_FILLS 70
#define SCTP_LOG_FREE_SENT 71
#define SCTP_NAGLE_APPLIED 72
#define SCTP_NAGLE_SKIPPED 73
#define SCTP_WAKESND_FROM_SACK 74
#define SCTP_WAKESND_FROM_FWDTSN 75
#define SCTP_NOWAKE_FROM_SACK 76
#define SCTP_CWNDLOG_PRESEND 77
#define SCTP_CWNDLOG_ENDSEND 78
#define SCTP_AT_END_OF_SACK 79
#define SCTP_REASON_FOR_SC 80
#define SCTP_BLOCK_LOG_INTO_BLKA 81
#define SCTP_ENTER_USER_RECV 82
#define SCTP_USER_RECV_SACKS 83
#define SCTP_SORECV_BLOCKSA 84
#define SCTP_SORECV_BLOCKSB 85
#define SCTP_SORECV_DONE 86
#define SCTP_SACK_RWND_UPDATE 87
#define SCTP_SORECV_ENTER 88
#define SCTP_SORECV_ENTERPL 89
#define SCTP_MBUF_INPUT 90
#define SCTP_MBUF_IALLOC 91
#define SCTP_MBUF_IFREE 92
#define SCTP_MBUF_ICOPY 93
#define SCTP_SORCV_FREECTL 94
#define SCTP_SORCV_DOESCPY 95
#define SCTP_SORCV_DOESLCK 96
#define SCTP_SORCV_DOESADJ 97
#define SCTP_SORCV_BOTWHILE 98
#define SCTP_SORCV_PASSBF 99
#define SCTP_SORCV_ADJD 100
#define SCTP_UNKNOWN_MAX 101
#define SCTP_RANDY_STUFF 102
#define SCTP_RANDY_STUFF1 103
#define SCTP_LOG_MAX_TYPES 104
/*
* 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_UNKNOWN 0
#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
#define SCTP_LOG_EVENT_SACK 9
#define SCTP_LOG_LOCK_EVENT 10
#define SCTP_LOG_EVENT_RTT 11
#define SCTP_LOG_EVENT_SB 12
#define SCTP_LOG_EVENT_NAGLE 13
#define SCTP_LOG_EVENT_WAKE 14
#define SCTP_LOG_MISC_EVENT 15
#define SCTP_LOG_EVENT_CLOSE 16
#define SCTP_LOG_EVENT_MBUF 17
#define SCTP_LOG_MAX_EVENT 18
#define SCTP_LOCK_UNKNOWN 2
/* 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
/*
* Theshold for rwnd updates, we have to read (sb_hiwat >>
* SCTP_RWND_HIWAT_SHIFT) before we will look to see if we need to send a
* window update sack. When we look, we compare the last rwnd we sent vs the
* current rwnd. It too must be greater than this value. Using 3 divdes the
* hiwat by 8, so for 200k rwnd we need to read 24k. For a 64k rwnd we need
* to read 8k. This seems about right.. I hope :-D.. we do set a
* min of a MTU on it so if the rwnd is real small we will insist
* on a full MTU of 1500 bytes.
*/
#define SCTP_RWND_HIWAT_SHIFT 3
/* How much of the rwnd must the
* message be taking up to start partial delivery.
* We calculate this by shifing the hi_water (recv_win)
* left the following .. set to 1, when a message holds
* 1/2 the rwnd. If we set it to 2 when a message holds
* 1/4 the rwnd...etc..
*/
#define SCTP_PARTIAL_DELIVERY_SHIFT 1
/* Minimum number of bytes read by user before we
* condsider doing a rwnd update
*/
#define SCTP_MIN_READ_BEFORE_CONSIDERING 3000
/*
* default HMAC for cookies, etc... use one of the AUTH HMAC id's
* SCTP_HMAC is the HMAC_ID to use
* SCTP_SIGNATURE_SIZE is the digest length
*/
#define SCTP_HMAC SCTP_AUTH_HMAC_ID_SHA1
#define SCTP_SIGNATURE_SIZE SCTP_AUTH_DIGEST_LEN_SHA1
#define SCTP_SIGNATURE_ALOC_SIZE SCTP_SIGNATURE_SIZE
/* 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
/*
* 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_ITERATOR_MAX_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 4
/* IP hdr (20/40) + 12+2+2 (enet) + sctp common 12 */
#define SCTP_FIRST_MBUF_RESV 68
/* 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_RESEND 4
#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
/* chunk output send from locations */
#define SCTP_OUTPUT_FROM_USR_SEND 0
#define SCTP_OUTPUT_FROM_T3 1
#define SCTP_OUTPUT_FROM_INPUT_ERROR 2
#define SCTP_OUTPUT_FROM_CONTROL_PROC 3
#define SCTP_OUTPUT_FROM_SACK_TMR 4
#define SCTP_OUTPUT_FROM_SHUT_TMR 5
#define SCTP_OUTPUT_FROM_HB_TMR 6
#define SCTP_OUTPUT_FROM_SHUT_ACK_TMR 7
#define SCTP_OUTPUT_FROM_ASCONF_TMR 8
#define SCTP_OUTPUT_FROM_STRRST_TMR 9
#define SCTP_OUTPUT_FROM_AUTOCLOSE_TMR 10
#define SCTP_OUTPUT_FROM_EARLY_FR_TMR 11
#define SCTP_OUTPUT_FROM_STRRST_REQ 12
#define SCTP_OUTPUT_FROM_USR_RCVD 13
/* SCTP chunk types are moved sctp.h for application (NAT, FW) use */
/* 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 */
/*************0x0000 series*************/
#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
/* draft-ietf-stewart-strreset-xxx */
#define SCTP_STR_RESET_OUT_REQUEST 0x000d
#define SCTP_STR_RESET_IN_REQUEST 0x000e
#define SCTP_STR_RESET_TSN_REQUEST 0x000f
#define SCTP_STR_RESET_RESPONSE 0x0010
#define SCTP_MAX_RESET_PARAMS 2
#define SCTP_STREAM_RESET_TSN_DELTA 0x1000
/*************0x4000 series*************/
/*************0x8000 series*************/
#define SCTP_ECN_CAPABLE 0x8000
/* ECN Nonce: draft-ladha-sctp-ecn-nonce */
#define SCTP_ECN_NONCE_SUPPORTED 0x8001
/* draft-ietf-tsvwg-auth-xxx */
#define SCTP_RANDOM 0x8002
#define SCTP_CHUNK_LIST 0x8003
#define SCTP_HMAC_LIST 0x8004
/*
* draft-ietf-tsvwg-addip-sctp-xx param=0x8008 len=0xNNNN Byte | Byte | Byte
* | Byte Byte | Byte ...
*
* Where each byte is a chunk type extension supported. 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 83 = Authentication
*/
#define SCTP_SUPPORTED_CHUNK_EXT 0x8008
/*************0xC000 series*************/
#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_ADAPTATION 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
/* 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
/* 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_ABOUT_TO_BE_FREED 0x0200
#define SCTP_STATE_PARTIAL_MSG_LEFT 0x0400
#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
/*
* what is the default number of mbufs in a chain I allow before switching to
* a cluster
*/
#define SCTP_DEFAULT_MBUFS_IN_CHAIN 5
/* 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
#define SCTP_TIMER_TYPE_ITERATOR 16
#define SCTP_TIMER_TYPE_EARLYFR 17
#define SCTP_TIMER_TYPE_ASOCKILL 18
#define SCTP_TIMER_TYPE_ADDR_WQ 19
/* add new timers here - and increment LAST */
#define SCTP_TIMER_TYPE_LAST 20
#define SCTP_IS_TIMER_TYPE_VALID(t) (((t) > SCTP_TIMER_TYPE_NONE) && \
((t) < SCTP_TIMER_TYPE_LAST))
/*
* 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
/*
* 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) ((hz == 1000) ? x : (((x) * hz) / 1000))
#define TICKS_TO_MSEC(x) ((hz == 1000) ? x : (((x) * 1000) / hz));
#define SEC_TO_TICKS(x) ((x) * hz)
#define TICKS_TO_SEC(x) ((x) / hz)
/*
* Basically the minimum amount of time before I do a early FR. Making this
* value to low will cause duplicate retransmissions.
*/
#define SCTP_MINFR_MSEC_TIMER 250
/* The floor this value is allowed to fall to when starting a timer. */
#define SCTP_MINFR_MSEC_FLOOR 20
/* 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 20/* number of ms to retry kill of inpcb */
#define SCTP_ASOC_KILL_TIMEOUT 10 /* number of ms to retry kill of inpcb */
#define SCTP_DEF_MAX_INIT 8
#define SCTP_DEF_MAX_SEND 10
#define SCTP_DEF_MAX_PATH_RTX 4
#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
/*
* How many smallest_mtu's need to increase before a window update sack is
* sent (should be a power of 2).
*/
#define SCTP_SEG_TO_RWND_UPD 32
/* Send window update (incr * this > hiwat). Should be a power of 2 */
#define SCTP_SCALE_OF_RWND_TO_UPD 4
#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_AUTH1 0x00000400
#define SCTP_DEBUG_AUTH2 0x00000800
#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_XXX 0x00080000
#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_XXXXX 0x80000000
#define SCTP_DEBUG_ALL 0x7ff3ffff
#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. */
/* 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 */
/*
* 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_ADAPTATION_INDICATION 19
/* same as above */
#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_STR_RESET_FAILED_OUT 23
#define SCTP_NOTIFY_STR_RESET_FAILED_IN 24
#define SCTP_NOTIFY_AUTH_NEW_KEY 25
#define SCTP_NOTIFY_AUTH_KEY_CONFLICT 26
#define SCTP_NOTIFY_SPECIAL_SP_FAIL 27
#define SCTP_NOTIFY_MAX 27
/* This is the value for messages that are NOT completely
* copied down where we will start to split the message.
* So, with our default, we split only if the piece we
* want to take will fill up a full MTU (assuming
* a 1500 byte MTU).
*/
#define SCTP_DEFAULT_SPLIT_POINT_MIN 1452
/* This value determines the default for when
* we try to add more on the send queue., if
* there is room. This prevents us from cycling
* into the copy_resume routine to often if
* we have not got enough space to add a decent
* enough size message. Note that if we have enough
* space to complete the message copy we will always
* add to the message, no matter what the size. Its
* only when we reach the point that we have some left
* to add, there is only room for part of it that we
* will use this threshold. Its also a sysctl.
*/
#define SCTP_DEFAULT_ADD_MORE 1452
#ifndef SCTP_PCBHASHSIZE
/* default number of association hash buckets in each endpoint */
#define SCTP_PCBHASHSIZE 256
#endif
#ifndef SCTP_TCBHASHSIZE
#define SCTP_TCBHASHSIZE 1024
#endif
#ifndef SCTP_CHUNKQUEUE_SCALE
#define SCTP_CHUNKQUEUE_SCALE 10
#endif
/* clock variance is 1 ms */
#define SCTP_CLOCK_GRANULARITY 1
#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))
/*
* 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.
*/
#define SCTP_NUMBER_IN_VTAG_BLOCK 15
/*
* 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
/* The system retains a cache of free chunks such to
* cut down on calls the memory allocation system. There
* is a per association limit of free items and a overall
* system limit. If either one gets hit then the resource
* stops being cached.
*/
#define SCTP_DEF_ASOC_RESC_LIMIT 10
#define SCTP_DEF_SYSTEM_RESC_LIMIT 1000
#define IN4_ISPRIVATE_ADDRESS(a) \
((((u_char *)&(a)->s_addr)[0] == 10) || \
((((u_char *)&(a)->s_addr)[0] == 172) && \
(((u_char *)&(a)->s_addr)[1] >= 16) && \
(((u_char *)&(a)->s_addr)[1] <= 32)) || \
((((u_char *)&(a)->s_addr)[0] == 192) && \
(((u_char *)&(a)->s_addr)[1] == 168)))
#define IN4_ISLOOPBACK_ADDRESS(a) \
((((u_char *)&(a)->s_addr)[0] == 127) && \
(((u_char *)&(a)->s_addr)[1] == 0) && \
(((u_char *)&(a)->s_addr)[2] == 0) && \
(((u_char *)&(a)->s_addr)[3] == 1))
#if defined(_KERNEL)
#define SCTP_GETTIME_TIMEVAL(x) (getmicrouptime(x))
#define SCTP_GETPTIME_TIMEVAL(x) (microuptime(x))
/*#if defined(__FreeBSD__) || defined(__APPLE__)*/
/*#define SCTP_GETTIME_TIMEVAL(x) { \*/
/* (x)->tv_sec = ticks / 1000; \*/
/* (x)->tv_usec = (ticks % 1000) * 1000; \*/
/*}*/
/*#else*/
/*#define SCTP_GETTIME_TIMEVAL(x) (microtime(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_sowwakeup_locked(inp, so) \
do { \
if (inp->sctp_flags & SCTP_PCB_FLAGS_DONT_WAKE) { \
SOCKBUF_UNLOCK(&((so)->so_snd)); \
inp->sctp_flags |= SCTP_PCB_FLAGS_WAKEOUTPUT; \
} else { \
sowwakeup_locked(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)
/* FIXME */
#define sctp_sorwakeup_locked(inp, so) \
do { \
if (inp->sctp_flags & SCTP_PCB_FLAGS_DONT_WAKE) { \
inp->sctp_flags |= SCTP_PCB_FLAGS_WAKEINPUT; \
SOCKBUF_UNLOCK(&((so)->so_rcv)); \
} else { \
sorwakeup_locked(so); \
} \
} while (0)
#endif /* _KERNEL */
#endif

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

@ -0,0 +1,713 @@
/*-
* Copyright (c) 2001-2006, 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:
*
* a) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* b) 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.
*
* c) Neither the name of Cisco Systems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
*/
/* $KAME: sctp_crc32.c,v 1.12 2005/03/06 16:04:17 itojun Exp $ */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_sctp.h"
#include <sys/param.h>
#include <netinet/sctp_crc32.h>
#ifndef SCTP_USE_ADLER32
/**
*
* Routine Description:
*
* Computes the CRC32c checksum for the specified buffer using the slicing by 8
* algorithm over 64 bit quantities.
*
* Arguments:
*
* p_running_crc - pointer to the initial or final remainder value
* used in CRC computations. It should be set to
* non-NULL if the mode argument is equal to CONT or END
* p_buf - the packet buffer where crc computations are being performed
* length - the length of p_buf in bytes
* init_bytes - the number of initial bytes that need to be procesed before
* aligning p_buf to multiples of 4 bytes
* mode - can be any of the following: BEGIN, CONT, END, BODY, ALIGN
*
* Return value:
*
* The computed CRC32c value
*/
/*
* Copyright (c) 2004-2006 Intel Corporation - All Rights Reserved
*
*
* This software program is licensed subject to the BSD License, available at
* http://www.opensource.org/licenses/bsd-license.html.
*
* Abstract:
*
* Tables for software CRC generation
*/
/*
* The following CRC lookup table was generated automagically using the
* following model parameters:
*
* Generator Polynomial = ................. 0x1EDC6F41 Generator Polynomial
* Length = .......... 32 bits Reflected Bits = ....................... TRUE
* Table Generation Offset = .............. 32 bits Number of Slices =
* ..................... 8 slices Slice Lengths = ........................ 8
* 8 8 8 8 8 8 8 Directory Name = ....................... .\ File Name =
* ............................ 8x256_tables.c
*/
uint32_t sctp_crc_tableil8_o32[256] =
{
0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4, 0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B, 0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B, 0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54, 0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A, 0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5, 0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45, 0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A, 0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48, 0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687, 0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927, 0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8, 0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096, 0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859, 0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9, 0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36, 0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C, 0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043, 0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3, 0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C, 0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652, 0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D, 0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D, 0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2, 0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530, 0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF, 0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F, 0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90, 0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE, 0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321, 0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81, 0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E, 0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351
};
/*
* end of the CRC lookup table crc_tableil8_o32
*/
/*
* The following CRC lookup table was generated automagically using the
* following model parameters:
*
* Generator Polynomial = ................. 0x1EDC6F41 Generator Polynomial
* Length = .......... 32 bits Reflected Bits = ....................... TRUE
* Table Generation Offset = .............. 32 bits Number of Slices =
* ..................... 8 slices Slice Lengths = ........................ 8
* 8 8 8 8 8 8 8 Directory Name = ....................... .\ File Name =
* ............................ 8x256_tables.c
*/
uint32_t sctp_crc_tableil8_o40[256] =
{
0x00000000, 0x13A29877, 0x274530EE, 0x34E7A899, 0x4E8A61DC, 0x5D28F9AB, 0x69CF5132, 0x7A6DC945,
0x9D14C3B8, 0x8EB65BCF, 0xBA51F356, 0xA9F36B21, 0xD39EA264, 0xC03C3A13, 0xF4DB928A, 0xE7790AFD,
0x3FC5F181, 0x2C6769F6, 0x1880C16F, 0x0B225918, 0x714F905D, 0x62ED082A, 0x560AA0B3, 0x45A838C4,
0xA2D13239, 0xB173AA4E, 0x859402D7, 0x96369AA0, 0xEC5B53E5, 0xFFF9CB92, 0xCB1E630B, 0xD8BCFB7C,
0x7F8BE302, 0x6C297B75, 0x58CED3EC, 0x4B6C4B9B, 0x310182DE, 0x22A31AA9, 0x1644B230, 0x05E62A47,
0xE29F20BA, 0xF13DB8CD, 0xC5DA1054, 0xD6788823, 0xAC154166, 0xBFB7D911, 0x8B507188, 0x98F2E9FF,
0x404E1283, 0x53EC8AF4, 0x670B226D, 0x74A9BA1A, 0x0EC4735F, 0x1D66EB28, 0x298143B1, 0x3A23DBC6,
0xDD5AD13B, 0xCEF8494C, 0xFA1FE1D5, 0xE9BD79A2, 0x93D0B0E7, 0x80722890, 0xB4958009, 0xA737187E,
0xFF17C604, 0xECB55E73, 0xD852F6EA, 0xCBF06E9D, 0xB19DA7D8, 0xA23F3FAF, 0x96D89736, 0x857A0F41,
0x620305BC, 0x71A19DCB, 0x45463552, 0x56E4AD25, 0x2C896460, 0x3F2BFC17, 0x0BCC548E, 0x186ECCF9,
0xC0D23785, 0xD370AFF2, 0xE797076B, 0xF4359F1C, 0x8E585659, 0x9DFACE2E, 0xA91D66B7, 0xBABFFEC0,
0x5DC6F43D, 0x4E646C4A, 0x7A83C4D3, 0x69215CA4, 0x134C95E1, 0x00EE0D96, 0x3409A50F, 0x27AB3D78,
0x809C2506, 0x933EBD71, 0xA7D915E8, 0xB47B8D9F, 0xCE1644DA, 0xDDB4DCAD, 0xE9537434, 0xFAF1EC43,
0x1D88E6BE, 0x0E2A7EC9, 0x3ACDD650, 0x296F4E27, 0x53028762, 0x40A01F15, 0x7447B78C, 0x67E52FFB,
0xBF59D487, 0xACFB4CF0, 0x981CE469, 0x8BBE7C1E, 0xF1D3B55B, 0xE2712D2C, 0xD69685B5, 0xC5341DC2,
0x224D173F, 0x31EF8F48, 0x050827D1, 0x16AABFA6, 0x6CC776E3, 0x7F65EE94, 0x4B82460D, 0x5820DE7A,
0xFBC3FAF9, 0xE861628E, 0xDC86CA17, 0xCF245260, 0xB5499B25, 0xA6EB0352, 0x920CABCB, 0x81AE33BC,
0x66D73941, 0x7575A136, 0x419209AF, 0x523091D8, 0x285D589D, 0x3BFFC0EA, 0x0F186873, 0x1CBAF004,
0xC4060B78, 0xD7A4930F, 0xE3433B96, 0xF0E1A3E1, 0x8A8C6AA4, 0x992EF2D3, 0xADC95A4A, 0xBE6BC23D,
0x5912C8C0, 0x4AB050B7, 0x7E57F82E, 0x6DF56059, 0x1798A91C, 0x043A316B, 0x30DD99F2, 0x237F0185,
0x844819FB, 0x97EA818C, 0xA30D2915, 0xB0AFB162, 0xCAC27827, 0xD960E050, 0xED8748C9, 0xFE25D0BE,
0x195CDA43, 0x0AFE4234, 0x3E19EAAD, 0x2DBB72DA, 0x57D6BB9F, 0x447423E8, 0x70938B71, 0x63311306,
0xBB8DE87A, 0xA82F700D, 0x9CC8D894, 0x8F6A40E3, 0xF50789A6, 0xE6A511D1, 0xD242B948, 0xC1E0213F,
0x26992BC2, 0x353BB3B5, 0x01DC1B2C, 0x127E835B, 0x68134A1E, 0x7BB1D269, 0x4F567AF0, 0x5CF4E287,
0x04D43CFD, 0x1776A48A, 0x23910C13, 0x30339464, 0x4A5E5D21, 0x59FCC556, 0x6D1B6DCF, 0x7EB9F5B8,
0x99C0FF45, 0x8A626732, 0xBE85CFAB, 0xAD2757DC, 0xD74A9E99, 0xC4E806EE, 0xF00FAE77, 0xE3AD3600,
0x3B11CD7C, 0x28B3550B, 0x1C54FD92, 0x0FF665E5, 0x759BACA0, 0x663934D7, 0x52DE9C4E, 0x417C0439,
0xA6050EC4, 0xB5A796B3, 0x81403E2A, 0x92E2A65D, 0xE88F6F18, 0xFB2DF76F, 0xCFCA5FF6, 0xDC68C781,
0x7B5FDFFF, 0x68FD4788, 0x5C1AEF11, 0x4FB87766, 0x35D5BE23, 0x26772654, 0x12908ECD, 0x013216BA,
0xE64B1C47, 0xF5E98430, 0xC10E2CA9, 0xD2ACB4DE, 0xA8C17D9B, 0xBB63E5EC, 0x8F844D75, 0x9C26D502,
0x449A2E7E, 0x5738B609, 0x63DF1E90, 0x707D86E7, 0x0A104FA2, 0x19B2D7D5, 0x2D557F4C, 0x3EF7E73B,
0xD98EEDC6, 0xCA2C75B1, 0xFECBDD28, 0xED69455F, 0x97048C1A, 0x84A6146D, 0xB041BCF4, 0xA3E32483
};
/*
* end of the CRC lookup table crc_tableil8_o40
*/
/*
* The following CRC lookup table was generated automagically using the
* following model parameters:
*
* Generator Polynomial = ................. 0x1EDC6F41 Generator Polynomial
* Length = .......... 32 bits Reflected Bits = ....................... TRUE
* Table Generation Offset = .............. 32 bits Number of Slices =
* ..................... 8 slices Slice Lengths = ........................ 8
* 8 8 8 8 8 8 8 Directory Name = ....................... .\ File Name =
* ............................ 8x256_tables.c
*/
uint32_t sctp_crc_tableil8_o48[256] =
{
0x00000000, 0xA541927E, 0x4F6F520D, 0xEA2EC073, 0x9EDEA41A, 0x3B9F3664, 0xD1B1F617, 0x74F06469,
0x38513EC5, 0x9D10ACBB, 0x773E6CC8, 0xD27FFEB6, 0xA68F9ADF, 0x03CE08A1, 0xE9E0C8D2, 0x4CA15AAC,
0x70A27D8A, 0xD5E3EFF4, 0x3FCD2F87, 0x9A8CBDF9, 0xEE7CD990, 0x4B3D4BEE, 0xA1138B9D, 0x045219E3,
0x48F3434F, 0xEDB2D131, 0x079C1142, 0xA2DD833C, 0xD62DE755, 0x736C752B, 0x9942B558, 0x3C032726,
0xE144FB14, 0x4405696A, 0xAE2BA919, 0x0B6A3B67, 0x7F9A5F0E, 0xDADBCD70, 0x30F50D03, 0x95B49F7D,
0xD915C5D1, 0x7C5457AF, 0x967A97DC, 0x333B05A2, 0x47CB61CB, 0xE28AF3B5, 0x08A433C6, 0xADE5A1B8,
0x91E6869E, 0x34A714E0, 0xDE89D493, 0x7BC846ED, 0x0F382284, 0xAA79B0FA, 0x40577089, 0xE516E2F7,
0xA9B7B85B, 0x0CF62A25, 0xE6D8EA56, 0x43997828, 0x37691C41, 0x92288E3F, 0x78064E4C, 0xDD47DC32,
0xC76580D9, 0x622412A7, 0x880AD2D4, 0x2D4B40AA, 0x59BB24C3, 0xFCFAB6BD, 0x16D476CE, 0xB395E4B0,
0xFF34BE1C, 0x5A752C62, 0xB05BEC11, 0x151A7E6F, 0x61EA1A06, 0xC4AB8878, 0x2E85480B, 0x8BC4DA75,
0xB7C7FD53, 0x12866F2D, 0xF8A8AF5E, 0x5DE93D20, 0x29195949, 0x8C58CB37, 0x66760B44, 0xC337993A,
0x8F96C396, 0x2AD751E8, 0xC0F9919B, 0x65B803E5, 0x1148678C, 0xB409F5F2, 0x5E273581, 0xFB66A7FF,
0x26217BCD, 0x8360E9B3, 0x694E29C0, 0xCC0FBBBE, 0xB8FFDFD7, 0x1DBE4DA9, 0xF7908DDA, 0x52D11FA4,
0x1E704508, 0xBB31D776, 0x511F1705, 0xF45E857B, 0x80AEE112, 0x25EF736C, 0xCFC1B31F, 0x6A802161,
0x56830647, 0xF3C29439, 0x19EC544A, 0xBCADC634, 0xC85DA25D, 0x6D1C3023, 0x8732F050, 0x2273622E,
0x6ED23882, 0xCB93AAFC, 0x21BD6A8F, 0x84FCF8F1, 0xF00C9C98, 0x554D0EE6, 0xBF63CE95, 0x1A225CEB,
0x8B277743, 0x2E66E53D, 0xC448254E, 0x6109B730, 0x15F9D359, 0xB0B84127, 0x5A968154, 0xFFD7132A,
0xB3764986, 0x1637DBF8, 0xFC191B8B, 0x595889F5, 0x2DA8ED9C, 0x88E97FE2, 0x62C7BF91, 0xC7862DEF,
0xFB850AC9, 0x5EC498B7, 0xB4EA58C4, 0x11ABCABA, 0x655BAED3, 0xC01A3CAD, 0x2A34FCDE, 0x8F756EA0,
0xC3D4340C, 0x6695A672, 0x8CBB6601, 0x29FAF47F, 0x5D0A9016, 0xF84B0268, 0x1265C21B, 0xB7245065,
0x6A638C57, 0xCF221E29, 0x250CDE5A, 0x804D4C24, 0xF4BD284D, 0x51FCBA33, 0xBBD27A40, 0x1E93E83E,
0x5232B292, 0xF77320EC, 0x1D5DE09F, 0xB81C72E1, 0xCCEC1688, 0x69AD84F6, 0x83834485, 0x26C2D6FB,
0x1AC1F1DD, 0xBF8063A3, 0x55AEA3D0, 0xF0EF31AE, 0x841F55C7, 0x215EC7B9, 0xCB7007CA, 0x6E3195B4,
0x2290CF18, 0x87D15D66, 0x6DFF9D15, 0xC8BE0F6B, 0xBC4E6B02, 0x190FF97C, 0xF321390F, 0x5660AB71,
0x4C42F79A, 0xE90365E4, 0x032DA597, 0xA66C37E9, 0xD29C5380, 0x77DDC1FE, 0x9DF3018D, 0x38B293F3,
0x7413C95F, 0xD1525B21, 0x3B7C9B52, 0x9E3D092C, 0xEACD6D45, 0x4F8CFF3B, 0xA5A23F48, 0x00E3AD36,
0x3CE08A10, 0x99A1186E, 0x738FD81D, 0xD6CE4A63, 0xA23E2E0A, 0x077FBC74, 0xED517C07, 0x4810EE79,
0x04B1B4D5, 0xA1F026AB, 0x4BDEE6D8, 0xEE9F74A6, 0x9A6F10CF, 0x3F2E82B1, 0xD50042C2, 0x7041D0BC,
0xAD060C8E, 0x08479EF0, 0xE2695E83, 0x4728CCFD, 0x33D8A894, 0x96993AEA, 0x7CB7FA99, 0xD9F668E7,
0x9557324B, 0x3016A035, 0xDA386046, 0x7F79F238, 0x0B899651, 0xAEC8042F, 0x44E6C45C, 0xE1A75622,
0xDDA47104, 0x78E5E37A, 0x92CB2309, 0x378AB177, 0x437AD51E, 0xE63B4760, 0x0C158713, 0xA954156D,
0xE5F54FC1, 0x40B4DDBF, 0xAA9A1DCC, 0x0FDB8FB2, 0x7B2BEBDB, 0xDE6A79A5, 0x3444B9D6, 0x91052BA8
};
/*
* end of the CRC lookup table crc_tableil8_o48
*/
/*
* The following CRC lookup table was generated automagically using the
* following model parameters:
*
* Generator Polynomial = ................. 0x1EDC6F41 Generator Polynomial
* Length = .......... 32 bits Reflected Bits = ....................... TRUE
* Table Generation Offset = .............. 32 bits Number of Slices =
* ..................... 8 slices Slice Lengths = ........................ 8
* 8 8 8 8 8 8 8 Directory Name = ....................... .\ File Name =
* ............................ 8x256_tables.c
*/
uint32_t sctp_crc_tableil8_o56[256] =
{
0x00000000, 0xDD45AAB8, 0xBF672381, 0x62228939, 0x7B2231F3, 0xA6679B4B, 0xC4451272, 0x1900B8CA,
0xF64463E6, 0x2B01C95E, 0x49234067, 0x9466EADF, 0x8D665215, 0x5023F8AD, 0x32017194, 0xEF44DB2C,
0xE964B13D, 0x34211B85, 0x560392BC, 0x8B463804, 0x924680CE, 0x4F032A76, 0x2D21A34F, 0xF06409F7,
0x1F20D2DB, 0xC2657863, 0xA047F15A, 0x7D025BE2, 0x6402E328, 0xB9474990, 0xDB65C0A9, 0x06206A11,
0xD725148B, 0x0A60BE33, 0x6842370A, 0xB5079DB2, 0xAC072578, 0x71428FC0, 0x136006F9, 0xCE25AC41,
0x2161776D, 0xFC24DDD5, 0x9E0654EC, 0x4343FE54, 0x5A43469E, 0x8706EC26, 0xE524651F, 0x3861CFA7,
0x3E41A5B6, 0xE3040F0E, 0x81268637, 0x5C632C8F, 0x45639445, 0x98263EFD, 0xFA04B7C4, 0x27411D7C,
0xC805C650, 0x15406CE8, 0x7762E5D1, 0xAA274F69, 0xB327F7A3, 0x6E625D1B, 0x0C40D422, 0xD1057E9A,
0xABA65FE7, 0x76E3F55F, 0x14C17C66, 0xC984D6DE, 0xD0846E14, 0x0DC1C4AC, 0x6FE34D95, 0xB2A6E72D,
0x5DE23C01, 0x80A796B9, 0xE2851F80, 0x3FC0B538, 0x26C00DF2, 0xFB85A74A, 0x99A72E73, 0x44E284CB,
0x42C2EEDA, 0x9F874462, 0xFDA5CD5B, 0x20E067E3, 0x39E0DF29, 0xE4A57591, 0x8687FCA8, 0x5BC25610,
0xB4868D3C, 0x69C32784, 0x0BE1AEBD, 0xD6A40405, 0xCFA4BCCF, 0x12E11677, 0x70C39F4E, 0xAD8635F6,
0x7C834B6C, 0xA1C6E1D4, 0xC3E468ED, 0x1EA1C255, 0x07A17A9F, 0xDAE4D027, 0xB8C6591E, 0x6583F3A6,
0x8AC7288A, 0x57828232, 0x35A00B0B, 0xE8E5A1B3, 0xF1E51979, 0x2CA0B3C1, 0x4E823AF8, 0x93C79040,
0x95E7FA51, 0x48A250E9, 0x2A80D9D0, 0xF7C57368, 0xEEC5CBA2, 0x3380611A, 0x51A2E823, 0x8CE7429B,
0x63A399B7, 0xBEE6330F, 0xDCC4BA36, 0x0181108E, 0x1881A844, 0xC5C402FC, 0xA7E68BC5, 0x7AA3217D,
0x52A0C93F, 0x8FE56387, 0xEDC7EABE, 0x30824006, 0x2982F8CC, 0xF4C75274, 0x96E5DB4D, 0x4BA071F5,
0xA4E4AAD9, 0x79A10061, 0x1B838958, 0xC6C623E0, 0xDFC69B2A, 0x02833192, 0x60A1B8AB, 0xBDE41213,
0xBBC47802, 0x6681D2BA, 0x04A35B83, 0xD9E6F13B, 0xC0E649F1, 0x1DA3E349, 0x7F816A70, 0xA2C4C0C8,
0x4D801BE4, 0x90C5B15C, 0xF2E73865, 0x2FA292DD, 0x36A22A17, 0xEBE780AF, 0x89C50996, 0x5480A32E,
0x8585DDB4, 0x58C0770C, 0x3AE2FE35, 0xE7A7548D, 0xFEA7EC47, 0x23E246FF, 0x41C0CFC6, 0x9C85657E,
0x73C1BE52, 0xAE8414EA, 0xCCA69DD3, 0x11E3376B, 0x08E38FA1, 0xD5A62519, 0xB784AC20, 0x6AC10698,
0x6CE16C89, 0xB1A4C631, 0xD3864F08, 0x0EC3E5B0, 0x17C35D7A, 0xCA86F7C2, 0xA8A47EFB, 0x75E1D443,
0x9AA50F6F, 0x47E0A5D7, 0x25C22CEE, 0xF8878656, 0xE1873E9C, 0x3CC29424, 0x5EE01D1D, 0x83A5B7A5,
0xF90696D8, 0x24433C60, 0x4661B559, 0x9B241FE1, 0x8224A72B, 0x5F610D93, 0x3D4384AA, 0xE0062E12,
0x0F42F53E, 0xD2075F86, 0xB025D6BF, 0x6D607C07, 0x7460C4CD, 0xA9256E75, 0xCB07E74C, 0x16424DF4,
0x106227E5, 0xCD278D5D, 0xAF050464, 0x7240AEDC, 0x6B401616, 0xB605BCAE, 0xD4273597, 0x09629F2F,
0xE6264403, 0x3B63EEBB, 0x59416782, 0x8404CD3A, 0x9D0475F0, 0x4041DF48, 0x22635671, 0xFF26FCC9,
0x2E238253, 0xF36628EB, 0x9144A1D2, 0x4C010B6A, 0x5501B3A0, 0x88441918, 0xEA669021, 0x37233A99,
0xD867E1B5, 0x05224B0D, 0x6700C234, 0xBA45688C, 0xA345D046, 0x7E007AFE, 0x1C22F3C7, 0xC167597F,
0xC747336E, 0x1A0299D6, 0x782010EF, 0xA565BA57, 0xBC65029D, 0x6120A825, 0x0302211C, 0xDE478BA4,
0x31035088, 0xEC46FA30, 0x8E647309, 0x5321D9B1, 0x4A21617B, 0x9764CBC3, 0xF54642FA, 0x2803E842
};
/*
* end of the CRC lookup table crc_tableil8_o56
*/
/*
* The following CRC lookup table was generated automagically using the
* following model parameters:
*
* Generator Polynomial = ................. 0x1EDC6F41 Generator Polynomial
* Length = .......... 32 bits Reflected Bits = ....................... TRUE
* Table Generation Offset = .............. 32 bits Number of Slices =
* ..................... 8 slices Slice Lengths = ........................ 8
* 8 8 8 8 8 8 8 Directory Name = ....................... .\ File Name =
* ............................ 8x256_tables.c
*/
uint32_t sctp_crc_tableil8_o64[256] =
{
0x00000000, 0x38116FAC, 0x7022DF58, 0x4833B0F4, 0xE045BEB0, 0xD854D11C, 0x906761E8, 0xA8760E44,
0xC5670B91, 0xFD76643D, 0xB545D4C9, 0x8D54BB65, 0x2522B521, 0x1D33DA8D, 0x55006A79, 0x6D1105D5,
0x8F2261D3, 0xB7330E7F, 0xFF00BE8B, 0xC711D127, 0x6F67DF63, 0x5776B0CF, 0x1F45003B, 0x27546F97,
0x4A456A42, 0x725405EE, 0x3A67B51A, 0x0276DAB6, 0xAA00D4F2, 0x9211BB5E, 0xDA220BAA, 0xE2336406,
0x1BA8B557, 0x23B9DAFB, 0x6B8A6A0F, 0x539B05A3, 0xFBED0BE7, 0xC3FC644B, 0x8BCFD4BF, 0xB3DEBB13,
0xDECFBEC6, 0xE6DED16A, 0xAEED619E, 0x96FC0E32, 0x3E8A0076, 0x069B6FDA, 0x4EA8DF2E, 0x76B9B082,
0x948AD484, 0xAC9BBB28, 0xE4A80BDC, 0xDCB96470, 0x74CF6A34, 0x4CDE0598, 0x04EDB56C, 0x3CFCDAC0,
0x51EDDF15, 0x69FCB0B9, 0x21CF004D, 0x19DE6FE1, 0xB1A861A5, 0x89B90E09, 0xC18ABEFD, 0xF99BD151,
0x37516AAE, 0x0F400502, 0x4773B5F6, 0x7F62DA5A, 0xD714D41E, 0xEF05BBB2, 0xA7360B46, 0x9F2764EA,
0xF236613F, 0xCA270E93, 0x8214BE67, 0xBA05D1CB, 0x1273DF8F, 0x2A62B023, 0x625100D7, 0x5A406F7B,
0xB8730B7D, 0x806264D1, 0xC851D425, 0xF040BB89, 0x5836B5CD, 0x6027DA61, 0x28146A95, 0x10050539,
0x7D1400EC, 0x45056F40, 0x0D36DFB4, 0x3527B018, 0x9D51BE5C, 0xA540D1F0, 0xED736104, 0xD5620EA8,
0x2CF9DFF9, 0x14E8B055, 0x5CDB00A1, 0x64CA6F0D, 0xCCBC6149, 0xF4AD0EE5, 0xBC9EBE11, 0x848FD1BD,
0xE99ED468, 0xD18FBBC4, 0x99BC0B30, 0xA1AD649C, 0x09DB6AD8, 0x31CA0574, 0x79F9B580, 0x41E8DA2C,
0xA3DBBE2A, 0x9BCAD186, 0xD3F96172, 0xEBE80EDE, 0x439E009A, 0x7B8F6F36, 0x33BCDFC2, 0x0BADB06E,
0x66BCB5BB, 0x5EADDA17, 0x169E6AE3, 0x2E8F054F, 0x86F90B0B, 0xBEE864A7, 0xF6DBD453, 0xCECABBFF,
0x6EA2D55C, 0x56B3BAF0, 0x1E800A04, 0x269165A8, 0x8EE76BEC, 0xB6F60440, 0xFEC5B4B4, 0xC6D4DB18,
0xABC5DECD, 0x93D4B161, 0xDBE70195, 0xE3F66E39, 0x4B80607D, 0x73910FD1, 0x3BA2BF25, 0x03B3D089,
0xE180B48F, 0xD991DB23, 0x91A26BD7, 0xA9B3047B, 0x01C50A3F, 0x39D46593, 0x71E7D567, 0x49F6BACB,
0x24E7BF1E, 0x1CF6D0B2, 0x54C56046, 0x6CD40FEA, 0xC4A201AE, 0xFCB36E02, 0xB480DEF6, 0x8C91B15A,
0x750A600B, 0x4D1B0FA7, 0x0528BF53, 0x3D39D0FF, 0x954FDEBB, 0xAD5EB117, 0xE56D01E3, 0xDD7C6E4F,
0xB06D6B9A, 0x887C0436, 0xC04FB4C2, 0xF85EDB6E, 0x5028D52A, 0x6839BA86, 0x200A0A72, 0x181B65DE,
0xFA2801D8, 0xC2396E74, 0x8A0ADE80, 0xB21BB12C, 0x1A6DBF68, 0x227CD0C4, 0x6A4F6030, 0x525E0F9C,
0x3F4F0A49, 0x075E65E5, 0x4F6DD511, 0x777CBABD, 0xDF0AB4F9, 0xE71BDB55, 0xAF286BA1, 0x9739040D,
0x59F3BFF2, 0x61E2D05E, 0x29D160AA, 0x11C00F06, 0xB9B60142, 0x81A76EEE, 0xC994DE1A, 0xF185B1B6,
0x9C94B463, 0xA485DBCF, 0xECB66B3B, 0xD4A70497, 0x7CD10AD3, 0x44C0657F, 0x0CF3D58B, 0x34E2BA27,
0xD6D1DE21, 0xEEC0B18D, 0xA6F30179, 0x9EE26ED5, 0x36946091, 0x0E850F3D, 0x46B6BFC9, 0x7EA7D065,
0x13B6D5B0, 0x2BA7BA1C, 0x63940AE8, 0x5B856544, 0xF3F36B00, 0xCBE204AC, 0x83D1B458, 0xBBC0DBF4,
0x425B0AA5, 0x7A4A6509, 0x3279D5FD, 0x0A68BA51, 0xA21EB415, 0x9A0FDBB9, 0xD23C6B4D, 0xEA2D04E1,
0x873C0134, 0xBF2D6E98, 0xF71EDE6C, 0xCF0FB1C0, 0x6779BF84, 0x5F68D028, 0x175B60DC, 0x2F4A0F70,
0xCD796B76, 0xF56804DA, 0xBD5BB42E, 0x854ADB82, 0x2D3CD5C6, 0x152DBA6A, 0x5D1E0A9E, 0x650F6532,
0x081E60E7, 0x300F0F4B, 0x783CBFBF, 0x402DD013, 0xE85BDE57, 0xD04AB1FB, 0x9879010F, 0xA0686EA3
};
/*
* end of the CRC lookup table crc_tableil8_o64
*/
/*
* The following CRC lookup table was generated automagically using the
* following model parameters:
*
* Generator Polynomial = ................. 0x1EDC6F41 Generator Polynomial
* Length = .......... 32 bits Reflected Bits = ....................... TRUE
* Table Generation Offset = .............. 32 bits Number of Slices =
* ..................... 8 slices Slice Lengths = ........................ 8
* 8 8 8 8 8 8 8 Directory Name = ....................... .\ File Name =
* ............................ 8x256_tables.c
*/
uint32_t sctp_crc_tableil8_o72[256] =
{
0x00000000, 0xEF306B19, 0xDB8CA0C3, 0x34BCCBDA, 0xB2F53777, 0x5DC55C6E, 0x697997B4, 0x8649FCAD,
0x6006181F, 0x8F367306, 0xBB8AB8DC, 0x54BAD3C5, 0xD2F32F68, 0x3DC34471, 0x097F8FAB, 0xE64FE4B2,
0xC00C303E, 0x2F3C5B27, 0x1B8090FD, 0xF4B0FBE4, 0x72F90749, 0x9DC96C50, 0xA975A78A, 0x4645CC93,
0xA00A2821, 0x4F3A4338, 0x7B8688E2, 0x94B6E3FB, 0x12FF1F56, 0xFDCF744F, 0xC973BF95, 0x2643D48C,
0x85F4168D, 0x6AC47D94, 0x5E78B64E, 0xB148DD57, 0x370121FA, 0xD8314AE3, 0xEC8D8139, 0x03BDEA20,
0xE5F20E92, 0x0AC2658B, 0x3E7EAE51, 0xD14EC548, 0x570739E5, 0xB83752FC, 0x8C8B9926, 0x63BBF23F,
0x45F826B3, 0xAAC84DAA, 0x9E748670, 0x7144ED69, 0xF70D11C4, 0x183D7ADD, 0x2C81B107, 0xC3B1DA1E,
0x25FE3EAC, 0xCACE55B5, 0xFE729E6F, 0x1142F576, 0x970B09DB, 0x783B62C2, 0x4C87A918, 0xA3B7C201,
0x0E045BEB, 0xE13430F2, 0xD588FB28, 0x3AB89031, 0xBCF16C9C, 0x53C10785, 0x677DCC5F, 0x884DA746,
0x6E0243F4, 0x813228ED, 0xB58EE337, 0x5ABE882E, 0xDCF77483, 0x33C71F9A, 0x077BD440, 0xE84BBF59,
0xCE086BD5, 0x213800CC, 0x1584CB16, 0xFAB4A00F, 0x7CFD5CA2, 0x93CD37BB, 0xA771FC61, 0x48419778,
0xAE0E73CA, 0x413E18D3, 0x7582D309, 0x9AB2B810, 0x1CFB44BD, 0xF3CB2FA4, 0xC777E47E, 0x28478F67,
0x8BF04D66, 0x64C0267F, 0x507CEDA5, 0xBF4C86BC, 0x39057A11, 0xD6351108, 0xE289DAD2, 0x0DB9B1CB,
0xEBF65579, 0x04C63E60, 0x307AF5BA, 0xDF4A9EA3, 0x5903620E, 0xB6330917, 0x828FC2CD, 0x6DBFA9D4,
0x4BFC7D58, 0xA4CC1641, 0x9070DD9B, 0x7F40B682, 0xF9094A2F, 0x16392136, 0x2285EAEC, 0xCDB581F5,
0x2BFA6547, 0xC4CA0E5E, 0xF076C584, 0x1F46AE9D, 0x990F5230, 0x763F3929, 0x4283F2F3, 0xADB399EA,
0x1C08B7D6, 0xF338DCCF, 0xC7841715, 0x28B47C0C, 0xAEFD80A1, 0x41CDEBB8, 0x75712062, 0x9A414B7B,
0x7C0EAFC9, 0x933EC4D0, 0xA7820F0A, 0x48B26413, 0xCEFB98BE, 0x21CBF3A7, 0x1577387D, 0xFA475364,
0xDC0487E8, 0x3334ECF1, 0x0788272B, 0xE8B84C32, 0x6EF1B09F, 0x81C1DB86, 0xB57D105C, 0x5A4D7B45,
0xBC029FF7, 0x5332F4EE, 0x678E3F34, 0x88BE542D, 0x0EF7A880, 0xE1C7C399, 0xD57B0843, 0x3A4B635A,
0x99FCA15B, 0x76CCCA42, 0x42700198, 0xAD406A81, 0x2B09962C, 0xC439FD35, 0xF08536EF, 0x1FB55DF6,
0xF9FAB944, 0x16CAD25D, 0x22761987, 0xCD46729E, 0x4B0F8E33, 0xA43FE52A, 0x90832EF0, 0x7FB345E9,
0x59F09165, 0xB6C0FA7C, 0x827C31A6, 0x6D4C5ABF, 0xEB05A612, 0x0435CD0B, 0x308906D1, 0xDFB96DC8,
0x39F6897A, 0xD6C6E263, 0xE27A29B9, 0x0D4A42A0, 0x8B03BE0D, 0x6433D514, 0x508F1ECE, 0xBFBF75D7,
0x120CEC3D, 0xFD3C8724, 0xC9804CFE, 0x26B027E7, 0xA0F9DB4A, 0x4FC9B053, 0x7B757B89, 0x94451090,
0x720AF422, 0x9D3A9F3B, 0xA98654E1, 0x46B63FF8, 0xC0FFC355, 0x2FCFA84C, 0x1B736396, 0xF443088F,
0xD200DC03, 0x3D30B71A, 0x098C7CC0, 0xE6BC17D9, 0x60F5EB74, 0x8FC5806D, 0xBB794BB7, 0x544920AE,
0xB206C41C, 0x5D36AF05, 0x698A64DF, 0x86BA0FC6, 0x00F3F36B, 0xEFC39872, 0xDB7F53A8, 0x344F38B1,
0x97F8FAB0, 0x78C891A9, 0x4C745A73, 0xA344316A, 0x250DCDC7, 0xCA3DA6DE, 0xFE816D04, 0x11B1061D,
0xF7FEE2AF, 0x18CE89B6, 0x2C72426C, 0xC3422975, 0x450BD5D8, 0xAA3BBEC1, 0x9E87751B, 0x71B71E02,
0x57F4CA8E, 0xB8C4A197, 0x8C786A4D, 0x63480154, 0xE501FDF9, 0x0A3196E0, 0x3E8D5D3A, 0xD1BD3623,
0x37F2D291, 0xD8C2B988, 0xEC7E7252, 0x034E194B, 0x8507E5E6, 0x6A378EFF, 0x5E8B4525, 0xB1BB2E3C
};
/*
* end of the CRC lookup table crc_tableil8_o72
*/
/*
* The following CRC lookup table was generated automagically using the
* following model parameters:
*
* Generator Polynomial = ................. 0x1EDC6F41 Generator Polynomial
* Length = .......... 32 bits Reflected Bits = ....................... TRUE
* Table Generation Offset = .............. 32 bits Number of Slices =
* ..................... 8 slices Slice Lengths = ........................ 8
* 8 8 8 8 8 8 8 Directory Name = ....................... .\ File Name =
* ............................ 8x256_tables.c
*/
uint32_t sctp_crc_tableil8_o80[256] =
{
0x00000000, 0x68032CC8, 0xD0065990, 0xB8057558, 0xA5E0C5D1, 0xCDE3E919, 0x75E69C41, 0x1DE5B089,
0x4E2DFD53, 0x262ED19B, 0x9E2BA4C3, 0xF628880B, 0xEBCD3882, 0x83CE144A, 0x3BCB6112, 0x53C84DDA,
0x9C5BFAA6, 0xF458D66E, 0x4C5DA336, 0x245E8FFE, 0x39BB3F77, 0x51B813BF, 0xE9BD66E7, 0x81BE4A2F,
0xD27607F5, 0xBA752B3D, 0x02705E65, 0x6A7372AD, 0x7796C224, 0x1F95EEEC, 0xA7909BB4, 0xCF93B77C,
0x3D5B83BD, 0x5558AF75, 0xED5DDA2D, 0x855EF6E5, 0x98BB466C, 0xF0B86AA4, 0x48BD1FFC, 0x20BE3334,
0x73767EEE, 0x1B755226, 0xA370277E, 0xCB730BB6, 0xD696BB3F, 0xBE9597F7, 0x0690E2AF, 0x6E93CE67,
0xA100791B, 0xC90355D3, 0x7106208B, 0x19050C43, 0x04E0BCCA, 0x6CE39002, 0xD4E6E55A, 0xBCE5C992,
0xEF2D8448, 0x872EA880, 0x3F2BDDD8, 0x5728F110, 0x4ACD4199, 0x22CE6D51, 0x9ACB1809, 0xF2C834C1,
0x7AB7077A, 0x12B42BB2, 0xAAB15EEA, 0xC2B27222, 0xDF57C2AB, 0xB754EE63, 0x0F519B3B, 0x6752B7F3,
0x349AFA29, 0x5C99D6E1, 0xE49CA3B9, 0x8C9F8F71, 0x917A3FF8, 0xF9791330, 0x417C6668, 0x297F4AA0,
0xE6ECFDDC, 0x8EEFD114, 0x36EAA44C, 0x5EE98884, 0x430C380D, 0x2B0F14C5, 0x930A619D, 0xFB094D55,
0xA8C1008F, 0xC0C22C47, 0x78C7591F, 0x10C475D7, 0x0D21C55E, 0x6522E996, 0xDD279CCE, 0xB524B006,
0x47EC84C7, 0x2FEFA80F, 0x97EADD57, 0xFFE9F19F, 0xE20C4116, 0x8A0F6DDE, 0x320A1886, 0x5A09344E,
0x09C17994, 0x61C2555C, 0xD9C72004, 0xB1C40CCC, 0xAC21BC45, 0xC422908D, 0x7C27E5D5, 0x1424C91D,
0xDBB77E61, 0xB3B452A9, 0x0BB127F1, 0x63B20B39, 0x7E57BBB0, 0x16549778, 0xAE51E220, 0xC652CEE8,
0x959A8332, 0xFD99AFFA, 0x459CDAA2, 0x2D9FF66A, 0x307A46E3, 0x58796A2B, 0xE07C1F73, 0x887F33BB,
0xF56E0EF4, 0x9D6D223C, 0x25685764, 0x4D6B7BAC, 0x508ECB25, 0x388DE7ED, 0x808892B5, 0xE88BBE7D,
0xBB43F3A7, 0xD340DF6F, 0x6B45AA37, 0x034686FF, 0x1EA33676, 0x76A01ABE, 0xCEA56FE6, 0xA6A6432E,
0x6935F452, 0x0136D89A, 0xB933ADC2, 0xD130810A, 0xCCD53183, 0xA4D61D4B, 0x1CD36813, 0x74D044DB,
0x27180901, 0x4F1B25C9, 0xF71E5091, 0x9F1D7C59, 0x82F8CCD0, 0xEAFBE018, 0x52FE9540, 0x3AFDB988,
0xC8358D49, 0xA036A181, 0x1833D4D9, 0x7030F811, 0x6DD54898, 0x05D66450, 0xBDD31108, 0xD5D03DC0,
0x8618701A, 0xEE1B5CD2, 0x561E298A, 0x3E1D0542, 0x23F8B5CB, 0x4BFB9903, 0xF3FEEC5B, 0x9BFDC093,
0x546E77EF, 0x3C6D5B27, 0x84682E7F, 0xEC6B02B7, 0xF18EB23E, 0x998D9EF6, 0x2188EBAE, 0x498BC766,
0x1A438ABC, 0x7240A674, 0xCA45D32C, 0xA246FFE4, 0xBFA34F6D, 0xD7A063A5, 0x6FA516FD, 0x07A63A35,
0x8FD9098E, 0xE7DA2546, 0x5FDF501E, 0x37DC7CD6, 0x2A39CC5F, 0x423AE097, 0xFA3F95CF, 0x923CB907,
0xC1F4F4DD, 0xA9F7D815, 0x11F2AD4D, 0x79F18185, 0x6414310C, 0x0C171DC4, 0xB412689C, 0xDC114454,
0x1382F328, 0x7B81DFE0, 0xC384AAB8, 0xAB878670, 0xB66236F9, 0xDE611A31, 0x66646F69, 0x0E6743A1,
0x5DAF0E7B, 0x35AC22B3, 0x8DA957EB, 0xE5AA7B23, 0xF84FCBAA, 0x904CE762, 0x2849923A, 0x404ABEF2,
0xB2828A33, 0xDA81A6FB, 0x6284D3A3, 0x0A87FF6B, 0x17624FE2, 0x7F61632A, 0xC7641672, 0xAF673ABA,
0xFCAF7760, 0x94AC5BA8, 0x2CA92EF0, 0x44AA0238, 0x594FB2B1, 0x314C9E79, 0x8949EB21, 0xE14AC7E9,
0x2ED97095, 0x46DA5C5D, 0xFEDF2905, 0x96DC05CD, 0x8B39B544, 0xE33A998C, 0x5B3FECD4, 0x333CC01C,
0x60F48DC6, 0x08F7A10E, 0xB0F2D456, 0xD8F1F89E, 0xC5144817, 0xAD1764DF, 0x15121187, 0x7D113D4F
};
/*
* end of the CRC lookup table crc_tableil8_o80
*/
/*
* The following CRC lookup table was generated automagically using the
* following model parameters:
*
* Generator Polynomial = ................. 0x1EDC6F41 Generator Polynomial
* Length = .......... 32 bits Reflected Bits = ....................... TRUE
* Table Generation Offset = .............. 32 bits Number of Slices =
* ..................... 8 slices Slice Lengths = ........................ 8
* 8 8 8 8 8 8 8 Directory Name = ....................... .\ File Name =
* ............................ 8x256_tables.c
*/
uint32_t sctp_crc_tableil8_o88[256] =
{
0x00000000, 0x493C7D27, 0x9278FA4E, 0xDB448769, 0x211D826D, 0x6821FF4A, 0xB3657823, 0xFA590504,
0x423B04DA, 0x0B0779FD, 0xD043FE94, 0x997F83B3, 0x632686B7, 0x2A1AFB90, 0xF15E7CF9, 0xB86201DE,
0x847609B4, 0xCD4A7493, 0x160EF3FA, 0x5F328EDD, 0xA56B8BD9, 0xEC57F6FE, 0x37137197, 0x7E2F0CB0,
0xC64D0D6E, 0x8F717049, 0x5435F720, 0x1D098A07, 0xE7508F03, 0xAE6CF224, 0x7528754D, 0x3C14086A,
0x0D006599, 0x443C18BE, 0x9F789FD7, 0xD644E2F0, 0x2C1DE7F4, 0x65219AD3, 0xBE651DBA, 0xF759609D,
0x4F3B6143, 0x06071C64, 0xDD439B0D, 0x947FE62A, 0x6E26E32E, 0x271A9E09, 0xFC5E1960, 0xB5626447,
0x89766C2D, 0xC04A110A, 0x1B0E9663, 0x5232EB44, 0xA86BEE40, 0xE1579367, 0x3A13140E, 0x732F6929,
0xCB4D68F7, 0x827115D0, 0x593592B9, 0x1009EF9E, 0xEA50EA9A, 0xA36C97BD, 0x782810D4, 0x31146DF3,
0x1A00CB32, 0x533CB615, 0x8878317C, 0xC1444C5B, 0x3B1D495F, 0x72213478, 0xA965B311, 0xE059CE36,
0x583BCFE8, 0x1107B2CF, 0xCA4335A6, 0x837F4881, 0x79264D85, 0x301A30A2, 0xEB5EB7CB, 0xA262CAEC,
0x9E76C286, 0xD74ABFA1, 0x0C0E38C8, 0x453245EF, 0xBF6B40EB, 0xF6573DCC, 0x2D13BAA5, 0x642FC782,
0xDC4DC65C, 0x9571BB7B, 0x4E353C12, 0x07094135, 0xFD504431, 0xB46C3916, 0x6F28BE7F, 0x2614C358,
0x1700AEAB, 0x5E3CD38C, 0x857854E5, 0xCC4429C2, 0x361D2CC6, 0x7F2151E1, 0xA465D688, 0xED59ABAF,
0x553BAA71, 0x1C07D756, 0xC743503F, 0x8E7F2D18, 0x7426281C, 0x3D1A553B, 0xE65ED252, 0xAF62AF75,
0x9376A71F, 0xDA4ADA38, 0x010E5D51, 0x48322076, 0xB26B2572, 0xFB575855, 0x2013DF3C, 0x692FA21B,
0xD14DA3C5, 0x9871DEE2, 0x4335598B, 0x0A0924AC, 0xF05021A8, 0xB96C5C8F, 0x6228DBE6, 0x2B14A6C1,
0x34019664, 0x7D3DEB43, 0xA6796C2A, 0xEF45110D, 0x151C1409, 0x5C20692E, 0x8764EE47, 0xCE589360,
0x763A92BE, 0x3F06EF99, 0xE44268F0, 0xAD7E15D7, 0x572710D3, 0x1E1B6DF4, 0xC55FEA9D, 0x8C6397BA,
0xB0779FD0, 0xF94BE2F7, 0x220F659E, 0x6B3318B9, 0x916A1DBD, 0xD856609A, 0x0312E7F3, 0x4A2E9AD4,
0xF24C9B0A, 0xBB70E62D, 0x60346144, 0x29081C63, 0xD3511967, 0x9A6D6440, 0x4129E329, 0x08159E0E,
0x3901F3FD, 0x703D8EDA, 0xAB7909B3, 0xE2457494, 0x181C7190, 0x51200CB7, 0x8A648BDE, 0xC358F6F9,
0x7B3AF727, 0x32068A00, 0xE9420D69, 0xA07E704E, 0x5A27754A, 0x131B086D, 0xC85F8F04, 0x8163F223,
0xBD77FA49, 0xF44B876E, 0x2F0F0007, 0x66337D20, 0x9C6A7824, 0xD5560503, 0x0E12826A, 0x472EFF4D,
0xFF4CFE93, 0xB67083B4, 0x6D3404DD, 0x240879FA, 0xDE517CFE, 0x976D01D9, 0x4C2986B0, 0x0515FB97,
0x2E015D56, 0x673D2071, 0xBC79A718, 0xF545DA3F, 0x0F1CDF3B, 0x4620A21C, 0x9D642575, 0xD4585852,
0x6C3A598C, 0x250624AB, 0xFE42A3C2, 0xB77EDEE5, 0x4D27DBE1, 0x041BA6C6, 0xDF5F21AF, 0x96635C88,
0xAA7754E2, 0xE34B29C5, 0x380FAEAC, 0x7133D38B, 0x8B6AD68F, 0xC256ABA8, 0x19122CC1, 0x502E51E6,
0xE84C5038, 0xA1702D1F, 0x7A34AA76, 0x3308D751, 0xC951D255, 0x806DAF72, 0x5B29281B, 0x1215553C,
0x230138CF, 0x6A3D45E8, 0xB179C281, 0xF845BFA6, 0x021CBAA2, 0x4B20C785, 0x906440EC, 0xD9583DCB,
0x613A3C15, 0x28064132, 0xF342C65B, 0xBA7EBB7C, 0x4027BE78, 0x091BC35F, 0xD25F4436, 0x9B633911,
0xA777317B, 0xEE4B4C5C, 0x350FCB35, 0x7C33B612, 0x866AB316, 0xCF56CE31, 0x14124958, 0x5D2E347F,
0xE54C35A1, 0xAC704886, 0x7734CFEF, 0x3E08B2C8, 0xC451B7CC, 0x8D6DCAEB, 0x56294D82, 0x1F1530A5
};
/*
* end of the CRC lookup table crc_tableil8_o88
*/
static uint32_t
sctp_crc32c_sb8_64_bit(uint32_t crc,
unsigned char *p_buf,
uint32_t length,
uint32_t init_bytes)
{
uint32_t li;
uint32_t term1, term2;
uint32_t running_length;
uint32_t end_bytes;
running_length = ((length - init_bytes) / 8) * 8;
end_bytes = length - init_bytes - running_length;
for (li = 0; li < init_bytes; li++)
crc = sctp_crc_tableil8_o32[(crc ^ *p_buf++) & 0x000000FF] ^
(crc >> 8);
for (li = 0; li < running_length / 8; li++) {
#if BYTE_ORDER == BIG_ENDIAN
crc ^= *p_buf++;
crc ^= (*p_buf++) << 8;
crc ^= (*p_buf++) << 16;
crc ^= (*p_buf++) << 24;
#else
crc ^= *(uint32_t *) p_buf;
p_buf += 4;
#endif
term1 = sctp_crc_tableil8_o88[crc & 0x000000FF] ^
sctp_crc_tableil8_o80[(crc >> 8) & 0x000000FF];
term2 = crc >> 16;
crc = term1 ^
sctp_crc_tableil8_o72[term2 & 0x000000FF] ^
sctp_crc_tableil8_o64[(term2 >> 8) & 0x000000FF];
#if BYTE_ORDER == BIG_ENDIAN
crc ^= sctp_crc_tableil8_o56[*p_buf++];
crc ^= sctp_crc_tableil8_o48[*p_buf++];
crc ^= sctp_crc_tableil8_o40[*p_buf++];
crc ^= sctp_crc_tableil8_o32[*p_buf++];
#else
term1 = sctp_crc_tableil8_o56[(*(uint32_t *) p_buf) & 0x000000FF] ^
sctp_crc_tableil8_o48[((*(uint32_t *) p_buf) >> 8) & 0x000000FF];
term2 = (*(uint32_t *) p_buf) >> 16;
crc = crc ^
term1 ^
sctp_crc_tableil8_o40[term2 & 0x000000FF] ^
sctp_crc_tableil8_o32[(term2 >> 8) & 0x000000FF];
p_buf += 4;
#endif
}
for (li = 0; li < end_bytes; li++)
crc = sctp_crc_tableil8_o32[(crc ^ *p_buf++) & 0x000000FF] ^
(crc >> 8);
return crc;
}
/**
*
* Routine Description:
*
* warms the tables
*
* Arguments:
*
* none
*
* Return value:
*
* none
*/
uint32_t
update_crc32(uint32_t crc32,
unsigned char *buffer,
unsigned int length)
{
uint32_t offset;
if (length == 0) {
return (crc32);
}
offset = ((uint32_t) buffer - ((uint32_t) buffer & 0xfffffffc));
return (sctp_crc32c_sb8_64_bit(crc32, buffer, length, offset));
}
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,
};
#define SCTP_CRC32C(c,d) (c=(c>>8)^sctp_crc_c[(c^(d))&0xFF])
u_int32_t
old_update_crc32(u_int32_t crc32,
unsigned char *buffer,
unsigned int length)
{
unsigned int i;
for (i = 0; i < length; i++) {
SCTP_CRC32C(crc32, buffer[i]);
}
return (crc32);
}
uint32_t
sctp_csum_finalize(uint32_t crc32)
{
uint32_t result;
#if BYTE_ORDER == BIG_ENDIAN
uint8_t byte0, byte1, byte2, byte3;
#endif
/* Complement the result */
result = ~crc32;
#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;
crc32 = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3);
#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.
*/
crc32 = result;
#endif
return (crc32);
}
#endif

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

@ -0,0 +1,56 @@
/*-
* Copyright (c) 2001-2006, 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:
*
* a) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* b) 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.
*
* c) Neither the name of Cisco Systems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
*/
/* $KAME: sctp_crc32.h,v 1.5 2004/08/17 04:06:16 itojun Exp $ */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#ifndef __crc32c_h__
#define __crc32c_h__
#include <sys/types.h>
#ifndef SCTP_USE_ADLER32
#if defined(_KERNEL)
uint32_t update_crc32(uint32_t, unsigned char *, unsigned int);
uint32_t old_update_crc32(uint32_t, unsigned char *, unsigned int);
uint32_t sctp_csum_finalize(uint32_t);
#endif /* _KERNEL */
#endif /* !SCTP_USE_ADLER32 */
#endif /* __crc32c_h__ */

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

@ -0,0 +1,562 @@
/*-
* Copyright (c) 2001-2006, 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:
*
* a) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* b) 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.
*
* c) Neither the name of Cisco Systems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
*/
/* $KAME: sctp_header.h,v 1.14 2005/03/06 16:04:17 itojun Exp $ */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#ifndef __sctp_header_h__
#define __sctp_header_h__
#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 */
uint32_t addr; /* IPV4 address */
};
struct sctp_ipv6addr_param {
struct sctp_paramhdr ph;/* type=SCTP_IPV6_PARAM_TYPE, len=20 */
uint8_t addr[16]; /* IPV6 address */
};
/* Cookie Preservative */
struct sctp_cookie_perserve_param {
struct sctp_paramhdr ph;/* type=SCTP_COOKIE_PRESERVE, len=8 */
uint32_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 */
uint16_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;
uint32_t time_value_1;
uint32_t time_value_2;
uint32_t random_value1;
uint32_t random_value2;
uint16_t user_req;
uint8_t addr_family;
uint8_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 */
uint32_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 */
};
struct sctp_supported_chunk_types_param {
struct sctp_paramhdr ph;/* type = 0x8008 len = x */
uint8_t chunk_types[0];
};
/* ECN Nonce: draft-ladha-sctp-ecn-nonce */
struct sctp_ecn_nonce_supported_param {
struct sctp_paramhdr ph;/* type = 0x8001 len = 4 */
};
/*
* Structures for DATA chunks
*/
struct sctp_data {
uint32_t tsn;
uint16_t stream_id;
uint16_t stream_sequence;
uint32_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 {
uint32_t initiate_tag; /* initiate tag */
uint32_t a_rwnd; /* a_rwnd */
uint16_t num_outbound_streams; /* OS */
uint16_t num_inbound_streams; /* MIS */
uint32_t initial_tsn; /* I-TSN */
/* optional param's follow */
};
/* state cookie header */
struct sctp_state_cookie { /* this is our definition... */
uint8_t identification[16]; /* id of who we are */
uint32_t cookie_life; /* life I will award this cookie */
uint32_t tie_tag_my_vtag; /* my tag in old association */
uint32_t tie_tag_peer_vtag; /* peers tag in old association */
uint32_t peers_vtag; /* peers tag in INIT (for quick ref) */
uint32_t my_vtag; /* my tag in INIT-ACK (for quick ref) */
struct timeval time_entered; /* the time I built cookie */
uint32_t address[4]; /* 4 ints/128 bits */
uint32_t addr_type; /* address type */
uint32_t laddress[4]; /* my local from address */
uint32_t laddr_type; /* my local from address type */
uint32_t scope_id; /* v6 scope id for link-locals */
uint16_t peerport; /* port address of the peer in the INIT */
uint16_t myport; /* my port address used in the INIT */
uint8_t ipv4_addr_legal;/* Are V4 addr legal? */
uint8_t ipv6_addr_legal;/* Are V6 addr legal? */
uint8_t local_scope; /* IPv6 local scope flag */
uint8_t site_scope; /* IPv6 site scope flag */
uint8_t ipv4_scope; /* IPv4 private addr scope */
uint8_t loopback_scope; /* loopback scope information */
uint16_t reserved;
/*
* at the end is tacked on the INIT chunk and the INIT-ACK chunk
* (minus the cookie).
*/
};
struct sctp_inv_mandatory_param {
uint16_t cause;
uint16_t length;
uint32_t num_param;
uint16_t param;
/*
* We include this to 0 it since only a missing cookie will cause
* this error.
*/
uint16_t resv;
};
struct sctp_unresolv_addr {
uint16_t cause;
uint16_t length;
uint16_t addr_type;
uint16_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 {
uint16_t start; /* Gap Ack block start */
uint16_t end; /* Gap Ack block end */
};
struct sctp_sack {
uint32_t cum_tsn_ack; /* cumulative TSN Ack */
uint32_t a_rwnd; /* updated a_rwnd of sender */
uint16_t num_gap_ack_blks; /* number of Gap Ack blocks */
uint16_t num_dup_tsns; /* number of duplicate TSNs */
/* struct sctp_gap_ack_block's follow */
/* uint32_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;
uint32_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;
uint32_t tsn;
};
/* Congestion Window Reduced (CWR) */
struct sctp_cwr_chunk {
struct sctp_chunkhdr ch;
uint32_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 */
uint32_t time_usec;
};
struct sctp_adaptation_layer_indication {
struct sctp_paramhdr ph;
uint32_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;
uint32_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;
uint32_t serial_number;
/* asconf parameters follow */
};
/* draft-ietf-tsvwg-prsctp */
/* Forward Cumulative TSN (FORWARD TSN) */
struct sctp_forward_tsn_chunk {
struct sctp_chunkhdr ch;
uint32_t new_cumulative_tsn;
/* stream/sequence pairs (sctp_strseq) follow */
};
struct sctp_strseq {
uint16_t stream;
uint16_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 31
struct sctp_chunk_desc {
uint8_t chunk_type;
uint8_t data_bytes[SCTP_NUM_DB_TO_VERIFY];
uint32_t tsn_ifany;
};
struct sctp_pktdrop_chunk {
struct sctp_chunkhdr ch;
uint32_t bottle_bw;
uint32_t current_onq;
uint16_t trunc_len;
uint16_t reserved;
uint8_t data[0];
};
/**********STREAM RESET STUFF ******************/
struct sctp_stream_reset_out_request {
struct sctp_paramhdr ph;
uint32_t request_seq; /* monotonically increasing seq no */
uint32_t response_seq; /* if a response, the resp seq no */
uint32_t send_reset_at_tsn; /* last TSN I assigned outbound */
uint16_t list_of_streams[0]; /* if not all list of streams */
};
struct sctp_stream_reset_in_request {
struct sctp_paramhdr ph;
uint32_t request_seq;
uint16_t list_of_streams[0]; /* if not all list of streams */
};
struct sctp_stream_reset_tsn_request {
struct sctp_paramhdr ph;
uint32_t request_seq;
};
struct sctp_stream_reset_response {
struct sctp_paramhdr ph;
uint32_t response_seq; /* if a response, the resp seq no */
uint32_t result;
};
struct sctp_stream_reset_response_tsn {
struct sctp_paramhdr ph;
uint32_t response_seq; /* if a response, the resp seq no */
uint32_t result;
uint32_t senders_next_tsn;
uint32_t receivers_next_tsn;
};
#define SCTP_STREAM_RESET_NOTHING 0x00000000 /* Nothing for me to do */
#define SCTP_STREAM_RESET_PERFORMED 0x00000001 /* Did it */
#define SCTP_STREAM_RESET_DENIED 0x00000002 /* refused to do it */
#define SCTP_STREAM_RESET_ERROR_STR 0x00000003 /* bad Stream no */
#define SCTP_STREAM_RESET_TRY_LATER 0x00000004 /* collision, try again */
#define SCTP_STREAM_RESET_BAD_SEQNO 0x00000005 /* bad str-reset seq no */
/*
* 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_out_req {
struct sctp_chunkhdr ch;
struct sctp_stream_reset_out_request sr_req;
};
struct sctp_stream_reset_in_req {
struct sctp_chunkhdr ch;
struct sctp_stream_reset_in_request sr_req;
};
struct sctp_stream_reset_tsn_req {
struct sctp_chunkhdr ch;
struct sctp_stream_reset_tsn_request sr_req;
};
struct sctp_stream_reset_resp {
struct sctp_chunkhdr ch;
struct sctp_stream_reset_response sr_resp;
};
/* respone only valid with a TSN request */
struct sctp_stream_reset_resp_tsn {
struct sctp_chunkhdr ch;
struct sctp_stream_reset_response_tsn sr_resp;
};
/****************************************************/
/*
* Authenticated chunks support draft-ietf-tsvwg-sctp-auth
*/
struct sctp_auth_random {
struct sctp_paramhdr ph;/* type = 0x8002 */
uint8_t random_data[0];
};
struct sctp_auth_chunk_list {
struct sctp_paramhdr ph;/* type = 0x8003 */
uint8_t chunk_types[0];
};
struct sctp_auth_hmac_algo {
struct sctp_paramhdr ph;/* type = 0x8004 */
uint16_t hmac_ids[0];
};
struct sctp_auth_chunk {
struct sctp_chunkhdr ch;
uint16_t shared_key_id;
uint16_t hmac_id;
uint8_t hmac[0];
};
struct sctp_auth_invalid_hmac {
struct sctp_paramhdr ph;
uint16_t hmac_id;
uint16_t padding;
};
/*
* 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__ */

5588
sys/netinet/sctp_indata.c Normal file

File diff suppressed because it is too large Load Diff

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

@ -0,0 +1,118 @@
/*-
* Copyright (c) 2001-2006, 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:
*
* a) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* b) 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.
*
* c) Neither the name of Cisco Systems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
*/
/* $KAME: sctp_indata.h,v 1.9 2005/03/06 16:04:17 itojun Exp $ */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#ifndef __sctp_indata_h__
#define __sctp_indata_h__
#if defined(_KERNEL)
struct sctp_queued_to_read *
sctp_build_readq_entry(struct sctp_tcb *stcb,
struct sctp_nets *net,
uint32_t tsn, uint32_t ppid,
uint32_t context, uint16_t stream_no,
uint16_t stream_seq, uint8_t flags,
struct mbuf *dm);
#define sctp_build_readq_entry_mac(_ctl, in_it, a, net, tsn, ppid, context, stream_no, stream_seq, flags, dm) do { \
if (_ctl) { \
(_ctl)->sinfo_context = a; \
(_ctl)->stcb = (in_it); \
(_ctl)->sinfo_assoc_id = sctp_get_associd((in_it)); \
(_ctl)->port_from = (in_it)->rport; \
(_ctl)->sinfo_stream = stream_no; \
(_ctl)->sinfo_ssn = stream_seq; \
(_ctl)->sinfo_flags = (flags << 8); \
(_ctl)->sinfo_ppid = ppid; \
(_ctl)->sinfo_timetolive = 0; \
(_ctl)->sinfo_tsn = tsn; \
(_ctl)->sinfo_cumtsn = tsn; \
(_ctl)->whoFrom = net; \
(_ctl)->length = 0; \
atomic_add_int(&((net)->ref_count), 1); \
(_ctl)->data = dm; \
(_ctl)->tail_mbuf = NULL; \
(_ctl)->do_not_ref_stcb = 0; \
(_ctl)->end_added = 0; \
} \
} while (0)
struct mbuf *
sctp_build_ctl_nchunk(struct sctp_inpcb *inp,
struct sctp_sndrcvinfo *sinfo);
void sctp_set_rwnd(struct sctp_tcb *, struct sctp_association *);
uint32_t
sctp_calc_rwnd(struct sctp_tcb *stcb, struct sctp_association *asoc);
void
sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
uint32_t rwnd, int nonce_sum_flag, int *abort_now);
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 *);
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 *, uint32_t *);
void sctp_sack_check(struct sctp_tcb *, int, int, int *);
#endif
#endif

4749
sys/netinet/sctp_input.c Normal file

File diff suppressed because it is too large Load Diff

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

@ -0,0 +1,57 @@
/*-
* Copyright (c) 2001-2006, 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:
*
* a) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* b) 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.
*
* c) Neither the name of Cisco Systems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
*/
/* $KAME: sctp_input.h,v 1.6 2005/03/06 16:04:17 itojun Exp $ */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#ifndef __sctp_input_h__
#define __sctp_input_h__
#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 *, uint8_t);
struct sctp_stream_reset_out_request *
sctp_find_stream_reset(struct sctp_tcb *stcb, uint32_t seq, struct sctp_tmit_chunk **bchk);
void
sctp_reset_in_stream(struct sctp_tcb *stcb, int number_entries, uint16_t * list);
#endif
#endif

355
sys/netinet/sctp_lock_bsd.h Normal file
View File

@ -0,0 +1,355 @@
#ifndef __sctp_lock_bsd_h__
#define __sctp_lock_bsd_h__
/*-
* Copyright (c) 2001-2006, 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:
*
* a) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* b) 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.
*
* c) Neither the name of Cisco Systems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
*/
/*
* 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 lose 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 we provide a bunch of EMPTY lock macros 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().
*/
__FBSDID("$FreeBSD$");
#define SCTP_IPI_COUNT_INIT()
#define SCTP_STATLOG_INIT_LOCK()
#define SCTP_STATLOG_LOCK()
#define SCTP_STATLOG_UNLOCK()
#define SCTP_STATLOG_DESTROY()
#define SCTP_STATLOG_GETREF(x) { \
x = atomic_fetchadd_int(&global_sctp_cwnd_log_at, 1); \
if(x == SCTP_STAT_LOG_SIZE) { \
global_sctp_cwnd_log_at = 1; \
x = 0; \
global_sctp_cwnd_log_rolled = 1; \
} \
}
#define SCTP_INP_INFO_LOCK_INIT() \
mtx_init(&sctppcbinfo.ipi_ep_mtx, "sctp-info", "inp_info", MTX_DEF)
#define SCTP_INP_INFO_RLOCK() do { \
mtx_lock(&sctppcbinfo.ipi_ep_mtx); \
} while (0)
#define SCTP_INP_INFO_WLOCK() do { \
mtx_lock(&sctppcbinfo.ipi_ep_mtx); \
} while (0)
#define SCTP_IPI_ADDR_INIT() \
mtx_init(&sctppcbinfo.ipi_addr_mtx, "sctp-addr-wq", "sctp_addr_wq", MTX_DEF)
#define SCTP_IPI_ADDR_DESTROY() \
mtx_destroy(&sctppcbinfo.ipi_addr_mtx)
#define SCTP_IPI_ADDR_LOCK() do { \
mtx_lock(&sctppcbinfo.ipi_addr_mtx); \
} while (0)
#define SCTP_IPI_ADDR_UNLOCK() mtx_unlock(&sctppcbinfo.ipi_addr_mtx)
#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_READ_INIT(_inp) \
mtx_init(&(_inp)->inp_rdata_mtx, "sctp-read", "inpr", MTX_DEF | MTX_DUPOK)
#define SCTP_INP_READ_DESTROY(_inp) \
mtx_destroy(&(_inp)->inp_rdata_mtx)
#define SCTP_INP_READ_LOCK(_inp) do { \
mtx_lock(&(_inp)->inp_rdata_mtx); \
} while (0)
#define SCTP_INP_READ_UNLOCK(_inp) mtx_unlock(&(_inp)->inp_rdata_mtx)
#define SCTP_INP_LOCK_INIT(_inp) \
mtx_init(&(_inp)->inp_mtx, "sctp-inp", "inp", MTX_DEF | MTX_DUPOK)
#define SCTP_ASOC_CREATE_LOCK_INIT(_inp) \
mtx_init(&(_inp)->inp_create_mtx, "sctp-create", "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 SCTP_LOCK_LOGGING
#define SCTP_INP_RLOCK(_inp) do { \
sctp_log_lock(_inp, (struct sctp_tcb *)NULL, SCTP_LOG_LOCK_INP);\
mtx_lock(&(_inp)->inp_mtx); \
} while (0)
#define SCTP_INP_WLOCK(_inp) do { \
sctp_log_lock(_inp, (struct sctp_tcb *)NULL, SCTP_LOG_LOCK_INP);\
mtx_lock(&(_inp)->inp_mtx); \
} while (0)
#else
#define SCTP_INP_RLOCK(_inp) do { \
mtx_lock(&(_inp)->inp_mtx); \
} while (0)
#define SCTP_INP_WLOCK(_inp) do { \
mtx_lock(&(_inp)->inp_mtx); \
} while (0)
#endif
#define SCTP_TCB_SEND_LOCK_INIT(_tcb) \
mtx_init(&(_tcb)->tcb_send_mtx, "sctp-send-tcb", "tcbs", MTX_DEF | MTX_DUPOK)
#define SCTP_TCB_SEND_LOCK_DESTROY(_tcb) mtx_destroy(&(_tcb)->tcb_send_mtx)
#define SCTP_TCB_SEND_LOCK(_tcb) do { \
mtx_lock(&(_tcb)->tcb_send_mtx); \
} while (0)
#define SCTP_TCB_SEND_UNLOCK(_tcb) mtx_unlock(&(_tcb)->tcb_send_mtx)
#define SCTP_INP_INCR_REF(_inp) atomic_add_int(&((_inp)->refcount), 1)
#define SCTP_INP_DECR_REF(_inp) atomic_add_int(&((_inp)->refcount), -1)
#ifdef SCTP_LOCK_LOGGING
#define SCTP_ASOC_CREATE_LOCK(_inp) \
do { \
sctp_log_lock(_inp, (struct sctp_tcb *)NULL, SCTP_LOG_LOCK_CREATE); \
mtx_lock(&(_inp)->inp_create_mtx); \
} while (0)
#else
#define SCTP_ASOC_CREATE_LOCK(_inp) \
do { \
mtx_lock(&(_inp)->inp_create_mtx); \
} while (0)
#endif
#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) \
mtx_init(&(_tcb)->tcb_mtx, "sctp-tcb", "tcb", MTX_DEF | MTX_DUPOK)
#define SCTP_TCB_LOCK_DESTROY(_tcb) mtx_destroy(&(_tcb)->tcb_mtx)
#ifdef SCTP_LOCK_LOGGING
#define SCTP_TCB_LOCK(_tcb) do { \
sctp_log_lock(_tcb->sctp_ep, _tcb, SCTP_LOG_LOCK_TCB); \
mtx_lock(&(_tcb)->tcb_mtx); \
} while (0)
#else
#define SCTP_TCB_LOCK(_tcb) do { \
mtx_lock(&(_tcb)->tcb_mtx); \
} while (0)
#endif
#define SCTP_TCB_TRYLOCK(_tcb) mtx_trylock(&(_tcb)->tcb_mtx)
#define SCTP_TCB_UNLOCK(_tcb) mtx_unlock(&(_tcb)->tcb_mtx)
#define SCTP_TCB_UNLOCK_IFOWNED(_tcb) do { \
if (mtx_owned(&(_tcb)->tcb_mtx)) \
mtx_unlock(&(_tcb)->tcb_mtx); \
} while (0)
#ifdef INVARIANTS
#define SCTP_TCB_LOCK_ASSERT(_tcb) do { \
if (mtx_owned(&(_tcb)->tcb_mtx) == 0) \
panic("Don't own TCB lock"); \
} while (0)
#else
#define SCTP_TCB_LOCK_ASSERT(_tcb)
#endif
#define SCTP_ITERATOR_LOCK_INIT() \
mtx_init(&sctppcbinfo.it_mtx, "sctp-it", "iterator", MTX_DEF)
#ifdef INVARIANTS
#define SCTP_ITERATOR_LOCK() \
do { \
if (mtx_owned(&sctppcbinfo.it_mtx)) \
panic("Iterator Lock"); \
mtx_lock(&sctppcbinfo.it_mtx); \
} while (0)
#else
#define SCTP_ITERATOR_LOCK() \
do { \
mtx_lock(&sctppcbinfo.it_mtx); \
} while (0)
#endif
#define SCTP_ITERATOR_UNLOCK() mtx_unlock(&sctppcbinfo.it_mtx)
#define SCTP_ITERATOR_LOCK_DESTROY() mtx_destroy(&sctppcbinfo.it_mtx)
#define SCTP_INCR_EP_COUNT() \
do { \
atomic_add_int(&sctppcbinfo.ipi_count_ep, 1); \
} while (0)
#define SCTP_DECR_EP_COUNT() \
do { \
atomic_add_int(&sctppcbinfo.ipi_count_ep,-1); \
} while (0)
#define SCTP_INCR_ASOC_COUNT() \
do { \
atomic_add_int(&sctppcbinfo.ipi_count_asoc, 1); \
} while (0)
#define SCTP_DECR_ASOC_COUNT() \
do { \
atomic_add_int(&sctppcbinfo.ipi_count_asoc, -1); \
} while (0)
#define SCTP_INCR_LADDR_COUNT() \
do { \
atomic_add_int(&sctppcbinfo.ipi_count_laddr, 1); \
} while (0)
#define SCTP_DECR_LADDR_COUNT() \
do { \
atomic_add_int(&sctppcbinfo.ipi_count_laddr, -1); \
} while (0)
#define SCTP_INCR_RADDR_COUNT() \
do { \
atomic_add_int(&sctppcbinfo.ipi_count_raddr,1); \
} while (0)
#define SCTP_DECR_RADDR_COUNT() \
do { \
atomic_add_int(&sctppcbinfo.ipi_count_raddr,-1); \
} while (0)
#define SCTP_INCR_CHK_COUNT() \
do { \
atomic_add_int(&sctppcbinfo.ipi_count_chunk, 1); \
} while (0)
#define SCTP_DECR_CHK_COUNT() \
do { \
if(sctppcbinfo.ipi_count_chunk == 0) \
panic("chunk count to 0?"); \
atomic_add_int(&sctppcbinfo.ipi_count_chunk,-1); \
} while (0)
#define SCTP_INCR_READQ_COUNT() \
do { \
atomic_add_int(&sctppcbinfo.ipi_count_readq,1); \
} while (0)
#define SCTP_DECR_READQ_COUNT() \
do { \
atomic_add_int(&sctppcbinfo.ipi_count_readq, -1); \
} while (0)
#define SCTP_INCR_STRMOQ_COUNT() \
do { \
atomic_add_int(&sctppcbinfo.ipi_count_strmoq, 1); \
} while (0)
#define SCTP_DECR_STRMOQ_COUNT() \
do { \
atomic_add_int(&sctppcbinfo.ipi_count_strmoq,-1); \
} while (0)
#endif

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

@ -0,0 +1,66 @@
/*-
* Copyright (c) 2006, 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:
*
* a) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* b) 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.
*
* c) Neither the name of Cisco Systems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
*/
__FBSDID("$FreeBSD$");
#ifndef __sctp_os_h__
#define __sctp_os_h__
/*
* General kernel memory allocation:
* SCTP_MALLOC(element, type, size, name)
* SCTP_FREE(element)
* Kernel memory allocation for "soname"- memory must be zeroed.
* SCTP_MALLOC_SONAME(name, type, size)
* SCTP_FREE_SONAME(name)
*/
/*
* 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.
*
* sctp_zone_t
* SCTP_ZONE_INIT(zone, name, size, number)
* SCTP_ZONE_GET(zone)
* SCTP_ZONE_FREE(zone, element)
* SCTP_ZONE_DESTROY(zone)
*/
/*
* Functions:
* sctp_read_random(void *buffer, uint32_t bytes)
*/
#include <netinet/sctp_os_bsd.h>
#endif

89
sys/netinet/sctp_os_bsd.h Normal file
View File

@ -0,0 +1,89 @@
/*-
* Copyright (c) 2006, 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:
*
* a) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* b) 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.
*
* c) Neither the name of Cisco Systems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
*/
__FBSDID("$FreeBSD$");
#ifndef __sctp_os_bsd_h__
#define __sctp_os_bsd_h__
/*
* includes
*/
#include <sys/random.h>
/*
*
*/
typedef struct mbuf *sctp_mbuf_t;
/*
* general memory allocation
*/
#define SCTP_MALLOC(var, type, size, name) \
do { \
MALLOC(var, type, size, M_PCB, M_NOWAIT); \
} while (0)
#define SCTP_FREE(var) FREE(var, M_PCB)
#define SCTP_MALLOC_SONAME(var, type, size) \
do { \
MALLOC(var, type, size, M_SONAME, M_WAITOK | M_ZERO); \
} while (0)
#define SCTP_FREE_SONAME(var) FREE(var, M_SONAME)
/*
* zone allocation functions
*/
#include <vm/uma.h>
/* SCTP_ZONE_INIT: initialize the zone */
typedef struct uma_zone *sctp_zone_t;
#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); \
}
/* SCTP_ZONE_GET: allocate element from the zone */
#define SCTP_ZONE_GET(zone) \
uma_zalloc(zone, M_NOWAIT);
/* SCTP_ZONE_FREE: free element from the zone */
#define SCTP_ZONE_FREE(zone, element) \
uma_zfree(zone, element);
/*
* Functions
*/
#define sctp_read_random(buf, len) read_random(buf, len)
#endif

10378
sys/netinet/sctp_output.c Normal file

File diff suppressed because it is too large Load Diff

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

@ -0,0 +1,171 @@
/*-
* Copyright (c) 2001-2006, 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:
*
* a) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* b) 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.
*
* c) Neither the name of Cisco Systems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
*/
/* $KAME: sctp_output.h,v 1.14 2005/03/06 16:04:18 itojun Exp $ */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#ifndef __sctp_output_h__
#define __sctp_output_h__
#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_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_tcb *, 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 thread *, int);
void
sctp_insert_on_wheel(struct sctp_tcb *stcb,
struct sctp_association *asoc,
struct sctp_stream_out *strq, int holdslock);
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);
struct mbuf *
sctp_get_mbuf_for_msg(unsigned int space_needed,
int want_header, int how, int allonebuf, int type);
void
sctp_add_stream_reset_out(struct sctp_tmit_chunk *chk,
int number_entries, uint16_t * list,
uint32_t seq, uint32_t resp_seq, uint32_t last_sent);
void
sctp_add_stream_reset_in(struct sctp_tmit_chunk *chk,
int number_entries, uint16_t * list,
uint32_t seq);
void
sctp_add_stream_reset_tsn(struct sctp_tmit_chunk *chk,
uint32_t seq);
void
sctp_add_stream_reset_result(struct sctp_tmit_chunk *chk,
uint32_t resp_seq, uint32_t result);
void
sctp_add_stream_reset_result_tsn(struct sctp_tmit_chunk *chk,
uint32_t resp_seq, uint32_t result,
uint32_t send_una, uint32_t recv_next);
int
sctp_send_str_reset_req(struct sctp_tcb *stcb,
int number_entries, uint16_t * list,
uint8_t send_out_req, uint32_t resp_seq,
uint8_t send_in_req,
uint8_t send_tsn_req);
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 *so,
struct sockaddr *addr,
struct uio *uio,
struct mbuf *top,
struct mbuf *control,
int flags,
struct thread *p
);
#endif
#endif

5283
sys/netinet/sctp_pcb.c Normal file

File diff suppressed because it is too large Load Diff

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

@ -0,0 +1,504 @@
/*-
* Copyright (c) 2001-2006, 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:
*
* a) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* b) 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.
*
* c) Neither the name of Cisco Systems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
*/
/* $KAME: sctp_pcb.h,v 1.21 2005/07/16 01:18:47 suz Exp $ */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#ifndef __sctp_pcb_h__
#define __sctp_pcb_h__
/*
* We must have V6 so the size of the proto can be calculated. Otherwise we
* would not allocate enough for Net/Open BSD :-<
*/
#if defined(_KERNEL)
#include <net/pfil.h>
#endif
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <net/if.h>
#include <net/if_types.h>
#include <net/if_var.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/ip6.h>
#include <netinet6/ip6_var.h>
#include <netinet6/ip6protosw.h>
#include <netinet6/in6_var.h>
#include <netinet6/in6_pcb.h>
#ifndef in6pcb
#define in6pcb inpcb
#endif
#include <netinet/sctp.h>
#include <netinet/sctp_os.h>
#include <netinet/sctp_constants.h>
LIST_HEAD(sctppcbhead, sctp_inpcb);
LIST_HEAD(sctpasochead, sctp_tcb);
LIST_HEAD(sctpladdr, sctp_laddr);
LIST_HEAD(sctpvtaghead, sctp_tagblock);
TAILQ_HEAD(sctp_readhead, sctp_queued_to_read);
TAILQ_HEAD(sctp_streamhead, sctp_stream_queue_pending);
#include <netinet/sctp_structs.h>
#include <netinet/sctp_uio.h>
#include <netinet/sctp_auth.h>
/*
* PCB flags (in sctp_flags bitmask)
*/
#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_CLOSE_IP 0x00040000
#define SCTP_PCB_FLAGS_WAS_CONNECTED 0x00080000
#define SCTP_PCB_FLAGS_WAS_ABORTED 0x00100000
/* TCP model support */
#define SCTP_PCB_FLAGS_CONNECTED 0x00200000
#define SCTP_PCB_FLAGS_IN_TCPPOOL 0x00400000
#define SCTP_PCB_FLAGS_DONT_WAKE 0x00800000
#define SCTP_PCB_FLAGS_WAKEOUTPUT 0x01000000
#define SCTP_PCB_FLAGS_WAKEINPUT 0x02000000
#define SCTP_PCB_FLAGS_BOUND_V6 0x04000000
#define SCTP_PCB_FLAGS_NEEDS_MAPPED_V4 0x08000000
#define SCTP_PCB_FLAGS_BLOCKING_IO 0x10000000
#define SCTP_PCB_FLAGS_SOCKET_GONE 0x20000000
#define SCTP_PCB_FLAGS_SOCKET_ALLGONE 0x40000000
/* flags to copy to new PCB */
#define SCTP_PCB_COPY_FLAGS 0x0e000004
/*
* PCB Features (in sctp_features bitmask)
*/
#define SCTP_PCB_FLAGS_EXT_RCVINFO 0x00000004
#define SCTP_PCB_FLAGS_DONOT_HEARTBEAT 0x00000008
#define SCTP_PCB_FLAGS_FRAG_INTERLEAVE 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_ADAPTATIONEVNT 0x00010000
#define SCTP_PCB_FLAGS_PDAPIEVNT 0x00020000
#define SCTP_PCB_FLAGS_AUTHEVNT 0x00040000
#define SCTP_PCB_FLAGS_STREAM_RESETEVNT 0x00080000
#define SCTP_PCB_FLAGS_NO_FRAGMENT 0x00100000
#define SCTP_PCB_FLAGS_EXPLICIT_EOR 0x00200000
#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;
int action; /* Only used in delayed asconf stuff */
};
struct sctp_block_entry {
int error;
};
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;
struct sctpasochead *sctp_restarthash;
u_long hashrestartmark;
/*
* 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 sctpladdr addr_wq;
struct sctpiterators iteratorhead;
/* ep zone info */
sctp_zone_t ipi_zone_ep;
sctp_zone_t ipi_zone_asoc;
sctp_zone_t ipi_zone_laddr;
sctp_zone_t ipi_zone_net;
sctp_zone_t ipi_zone_chunk;
sctp_zone_t ipi_zone_readq;
sctp_zone_t ipi_zone_strmoq;
struct mtx ipi_ep_mtx;
struct mtx it_mtx;
struct mtx ipi_addr_mtx;
uint32_t ipi_count_ep;
/* assoc/tcb zone info */
uint32_t ipi_count_asoc;
/* local addrlist zone info */
uint32_t ipi_count_laddr;
/* remote addrlist zone info */
uint32_t ipi_count_raddr;
/* chunk structure list for output */
uint32_t ipi_count_chunk;
/* socket queue zone info */
uint32_t ipi_count_readq;
/* socket queue zone info */
uint32_t ipi_count_strmoq;
/* system wide number of free chunks hanging around */
uint32_t ipi_free_chunks;
uint32_t ipi_free_strmoq;
struct sctpvtaghead vtag_timewait[SCTP_STACK_VTAG_HASH_SIZE];
struct sctp_timer addr_wq_timer;
/* for port allocations */
uint16_t lastport;
uint16_t lastlow;
uint16_t lasthi;
};
extern struct sctpstat sctpstat;
/*
* 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;
/* authentication related fields */
struct sctp_keyhead shared_keys;
sctp_auth_chklist_t *local_auth_chunks;
sctp_hmaclist_t *local_hmacs;
uint16_t default_keyid;
/* 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 adaptation_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_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;
/* Socket buffer lock protects read_queue and of course sb_cc */
struct sctp_readhead read_queue;
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; /* INP state flag set */
uint32_t sctp_features; /* Feature flags */
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;
struct sctp_iterator *inp_starting_point_for_iterator;
uint32_t sctp_frag_point;
uint32_t partial_delivery_point;
uint32_t sctp_context;
struct sctp_sndrcvinfo def_send;
/*
* These three are here for the sosend_dgram (pkt, pkt_last and
* control). routine. However, I don't think anyone in the current
* FreeBSD kernel calls this. So they are candidates with sctp_sendm
* for de-supporting.
*/
struct mbuf *pkt, *pkt_last;
struct mbuf *control;
struct mtx inp_mtx;
struct mtx inp_create_mtx;
struct mtx inp_rdata_mtx;
int32_t refcount;
};
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_tcbrestarhash; /* next link in restart
* hash table */
LIST_ENTRY(sctp_tcb) sctp_asocs; /* vtag hash list */
struct sctp_block_entry *block_entry; /* pointer locked by socket
* send buffer */
struct sctp_association asoc;
/*
* freed_by_sorcv_sincelast is protected by the sockbuf_lock NOT the
* tcb_lock. Its special in this way to help avoid extra mutex calls
* in the reading of data.
*/
uint32_t freed_by_sorcv_sincelast;
uint16_t rport; /* remote port in network format */
uint16_t resv;
struct mtx tcb_mtx;
struct mtx tcb_send_mtx;
};
#include <netinet/sctp_lock_bsd.h>
#if defined(_KERNEL)
extern struct sctp_epinfo sctppcbinfo;
extern int sctp_auto_asconf;
int SCTP6_ARE_ADDR_EQUAL(struct in6_addr *a, 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 thread *);
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 *,
sctp_assoc_t, int);
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, int);
struct sctp_tcb *
sctp_aloc_assoc(struct sctp_inpcb *, struct sockaddr *,
int, int *, uint32_t);
int sctp_free_assoc(struct sctp_inpcb *, struct sctp_tcb *, int);
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);
void sctp_remove_net(struct sctp_tcb *, struct sctp_nets *);
int sctp_del_remote_addr(struct sctp_tcb *, struct sockaddr *);
void sctp_pcb_init(void);
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 *, struct sockaddr *);
/*
* 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(inp_func inpf, asoc_func af, uint32_t, uint32_t,
uint32_t, void *, uint32_t, end_func ef, struct sctp_inpcb *, uint8_t co_off);
#endif /* _KERNEL */
#endif /* !__sctp_pcb_h__ */

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

@ -0,0 +1,240 @@
/*-
* Copyright (c) 2001-2006, 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:
*
* a) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* b) 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.
*
* c) Neither the name of Cisco Systems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
*/
/* $KAME: sctp_peeloff.c,v 1.13 2005/03/06 16:04:18 itojun Exp $ */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_ipsec.h"
#include "opt_inet6.h"
#include "opt_inet.h"
#include "opt_sctp.h"
#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_os.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>
#include <netinet/sctp_auth.h>
#ifdef IPSEC
#include <netinet6/ipsec.h>
#include <netkey/key.h>
#endif /* IPSEC */
#ifdef SCTP_DEBUG
extern uint32_t sctp_debug_on;
#endif /* SCTP_DEBUG */
int
sctp_can_peel_off(struct socket *head, sctp_assoc_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, 1);
if (stcb == NULL) {
return (ENOTCONN);
}
SCTP_TCB_UNLOCK(stcb);
/* We are clear to peel this one off */
return (0);
}
int
sctp_do_peeloff(struct socket *head, struct socket *so, sctp_assoc_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, 1);
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;
n_inp->sctp_features = inp->sctp_features;
n_inp->sctp_frag_point = inp->sctp_frag_point;
n_inp->partial_delivery_point = inp->partial_delivery_point;
n_inp->sctp_context = inp->sctp_context;
n_inp->inp_starting_point_for_iterator = NULL;
/*
* 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);
sctp_pull_off_control_to_new_inp(inp, n_inp, stcb);
SCTP_TCB_UNLOCK(stcb);
return (0);
}
struct socket *
sctp_get_peeloff(struct socket *head, sctp_assoc_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, 1);
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;
SOCK_LOCK(head);
SCTP_INP_WLOCK(inp);
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_features = inp->sctp_features;
n_inp->sctp_frag_point = inp->sctp_frag_point;
n_inp->partial_delivery_point = inp->partial_delivery_point;
n_inp->sctp_context = inp->sctp_context;
n_inp->inp_starting_point_for_iterator = NULL;
/* copy in the authentication parameters from the original endpoint */
if (n_inp->sctp_ep.local_hmacs)
sctp_free_hmaclist(n_inp->sctp_ep.local_hmacs);
n_inp->sctp_ep.local_hmacs =
sctp_copy_hmaclist(inp->sctp_ep.local_hmacs);
if (n_inp->sctp_ep.local_auth_chunks)
sctp_free_chunklist(n_inp->sctp_ep.local_auth_chunks);
n_inp->sctp_ep.local_auth_chunks =
sctp_copy_chunklist(inp->sctp_ep.local_auth_chunks);
(void)sctp_copy_skeylist(&inp->sctp_ep.shared_keys,
&n_inp->sctp_ep.shared_keys);
n_inp->sctp_socket = newso;
if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTOCLOSE)) {
sctp_feature_off(n_inp, SCTP_PCB_FLAGS_AUTOCLOSE);
n_inp->sctp_ep.auto_close_time = 0;
sctp_timer_stop(SCTP_TIMER_TYPE_AUTOCLOSE, n_inp, stcb, NULL);
}
/* Turn off any non-blocking semantic. */
newso->so_state &= ~SS_NBIO;
newso->so_state |= SS_ISCONNECTED;
/* We remove it right away */
#ifdef SCTP_LOCK_LOGGING
sctp_log_lock(inp, (struct sctp_tcb *)NULL, SCTP_LOG_LOCK_SOCK);
#endif
TAILQ_REMOVE(&head->so_comp, newso, so_list);
head->so_qlen--;
SOCK_UNLOCK(head);
/*
* 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_INP_WUNLOCK(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_pull_off_control_to_new_inp(inp, n_inp, stcb);
SCTP_TCB_UNLOCK(stcb);
return (newso);
}

View File

@ -0,0 +1,56 @@
/*-
* Copyright (c) 2001-2006, 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:
*
* a) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* b) 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.
*
* c) Neither the name of Cisco Systems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
*/
/* $KAME: sctp_peeloff.h,v 1.6 2005/03/06 16:04:18 itojun Exp $ */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#ifndef __sctp_peeloff_h__
#define __sctp_peeloff_h__
#include <sys/types.h>
#include <sys/socketvar.h>
#include <sys/socket.h>
#if defined(_KERNEL)
int sctp_can_peel_off(struct socket *, sctp_assoc_t);
int sctp_do_peeloff(struct socket *, struct socket *, sctp_assoc_t);
struct socket *sctp_get_peeloff(struct socket *, sctp_assoc_t, int *);
#endif /* _KERNEL */
#endif

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

@ -0,0 +1,892 @@
/*-
* Copyright (c) 2001-2006, 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:
*
* a) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* b) 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.
*
* c) Neither the name of Cisco Systems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
*/
/* $KAME: sctp_structs.h,v 1.13 2005/03/06 16:04:18 itojun Exp $ */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#ifndef __sctp_structs_h__
#define __sctp_structs_h__
#include <sys/queue.h>
#include <sys/callout.h>
#include <sys/socket.h>
#ifdef IPSEC
#include <netinet6/ipsec.h>
#include <netkey/key.h>
#endif
#include <netinet/sctp_header.h>
#include <netinet/sctp_uio.h>
#include <netinet/sctp_auth.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;
/* for sanity checking */
void *self;
uint32_t ticks;
};
struct sctp_nonpad_sndrcvinfo {
uint16_t sinfo_stream;
uint16_t sinfo_ssn;
uint16_t sinfo_flags;
uint32_t sinfo_ppid;
uint32_t sinfo_context;
uint32_t sinfo_timetolive;
uint32_t sinfo_tsn;
uint32_t sinfo_cumtsn;
sctp_assoc_t sinfo_assoc_id;
};
/*
* This is the information we track on each interface that we know about from
* the distant end.
*/
TAILQ_HEAD(sctpnetlisthead, sctp_nets);
struct sctp_stream_reset_list {
TAILQ_ENTRY(sctp_stream_reset_list) next_resp;
uint32_t tsn;
int number_entries;
struct sctp_stream_reset_out_request req;
};
TAILQ_HEAD(sctp_resethead, sctp_stream_reset_list);
/*
* Users of the iterator need to malloc a iterator with a call to
* sctp_initiate_iterator(inp_func, assoc_func, pcb_flags, pcb_features,
* asoc_state, void-ptr-arg, uint32-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_PCB_ANY_FEATURES 0x00000000
#define SCTP_ASOC_ANY_STATE 0x00000000
typedef void (*asoc_func) (struct sctp_inpcb *, struct sctp_tcb *, void *ptr,
uint32_t val);
typedef void (*inp_func) (struct sctp_inpcb *, void *ptr, uint32_t val);
typedef void (*end_func) (void *ptr, uint32_t val);
struct sctp_iterator {
LIST_ENTRY(sctp_iterator) sctp_nxt_itr;
struct sctp_timer tmr;
struct sctp_inpcb *inp; /* current endpoint */
struct sctp_tcb *stcb; /* current* assoc */
asoc_func function_assoc; /* per assoc function */
inp_func function_inp; /* per endpoint function */
end_func function_atend;/* iterator completion function */
void *pointer; /* pointer for apply func to use */
uint32_t val; /* value for apply func to use */
uint32_t pcb_flags; /* endpoint flags being checked */
uint32_t pcb_features; /* endpoint features being checked */
uint32_t asoc_state; /* assoc state being checked */
uint32_t iterator_flags;
uint8_t no_chunk_output;
};
/* iterator_flags values */
#define SCTP_ITERATOR_DO_ALL_INP 0x00000001
#define SCTP_ITERATOR_DO_SINGLE_INP 0x00000002
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.
*/
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;
/* mtu discovered so far */
uint32_t mtu;
uint32_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;
struct sctp_timer fr_timer; /* for early fr */
/* 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 :>
*/
uint32_t flight_size;
uint32_t cwnd; /* actual cwnd */
uint32_t prev_cwnd; /* cwnd before any processing */
uint32_t partial_bytes_acked; /* in CA tracks when to incr a MTU */
uint32_t rtt_variance;
uint32_t prev_rtt;
/* tracking variables to avoid the aloc/free in sack processing */
unsigned int net_ack;
unsigned int net_ack2;
/*
* CMT variables (iyengar@cis.udel.edu)
*/
uint32_t this_sack_highest_newack; /* tracks highest TSN newly
* acked for a given dest in
* the current SACK. Used in
* SFR and HTNA algos */
uint32_t pseudo_cumack; /* CMT CUC algorithm. Maintains next expected
* pseudo-cumack for this destination */
uint32_t rtx_pseudo_cumack; /* CMT CUC algorithm. Maintains next
* expected pseudo-cumack for this
* destination */
/* CMT fast recovery variables */
uint32_t fast_recovery_tsn;
uint32_t heartbeat_random1;
uint32_t heartbeat_random2;
uint32_t tos_flowlabel;
/* if this guy is ok or not ... status */
uint16_t dest_state;
/* number of transmit failures to down this guy */
uint16_t failure_threshold;
/* error stats on destination */
uint16_t error_count;
uint8_t fast_retran_loss_recovery;
uint8_t will_exit_fast_recovery;
/* Flags that probably can be combined into dest_state */
uint8_t rto_variance_dir; /* increase = 1, decreasing = 0 */
uint8_t rto_pending; /* is segment marked for RTO update ** if we
* split? */
uint8_t fast_retran_ip; /* fast retransmit in progress */
uint8_t hb_responded;
uint8_t saw_newack; /* CMT's SFR algorithm flag */
uint8_t src_addr_selected; /* if we split we move */
uint8_t indx_of_eligible_next_to_use;
uint8_t addr_is_local; /* its a local address (if known) could move
* in split */
/*
* CMT variables (iyengar@cis.udel.edu)
*/
uint8_t find_pseudo_cumack; /* CMT CUC algorithm. Flag used to
* find a new pseudocumack. This flag
* is set after a new pseudo-cumack
* has been received and indicates
* that the sender should find the
* next pseudo-cumack expected for
* this destination */
uint8_t find_rtx_pseudo_cumack; /* CMT CUCv2 algorithm. Flag used to
* find a new rtx-pseudocumack. This
* flag is set after a new
* rtx-pseudo-cumack has been received
* and indicates that the sender
* should find the next
* rtx-pseudo-cumack expected for this
* destination */
uint8_t new_pseudo_cumack; /* CMT CUC algorithm. Flag used to
* indicate if a new pseudo-cumack or
* rtx-pseudo-cumack has been received */
#ifdef SCTP_HIGH_SPEED
uint8_t last_hs_used; /* index into the last HS table entry we used */
#endif
};
struct sctp_data_chunkrec {
uint32_t TSN_seq; /* the TSN of this transmit */
uint16_t stream_seq; /* the stream sequence number of this transmit */
uint16_t stream_number; /* the stream number of this guy */
uint32_t payloadtype;
uint32_t context; /* from send */
/* ECN Nonce: Nonce Value for this chunk */
uint8_t ect_nonce;
/*
* part of the Highest sacked algorithm to be able to stroke counts
* on ones that are FR'd.
*/
uint32_t fast_retran_tsn; /* sending_seq at the time of FR */
struct timeval timetodrop; /* time we drop it from queue */
uint8_t doing_fast_retransmit;
uint8_t rcv_flags; /* flags pulled from data chunk on inbound for
* outbound holds sending flags. */
uint8_t state_flags;
uint8_t chunk_was_revoked;
};
TAILQ_HEAD(sctpchunk_listhead, sctp_tmit_chunk);
/* The lower byte is used to enumerate PR_SCTP policies */
#define CHUNK_FLAGS_PR_SCTP_TTL SCTP_PR_SCTP_TTL
#define CHUNK_FLAGS_PR_SCTP_BUF SCTP_PR_SCTP_BUF
#define CHUNK_FLAGS_PR_SCTP_RTX SCTP_PR_SCTP_RTX
/* The upper byte is used a a bit mask */
#define CHUNK_FLAGS_FRAGMENT_OK 0x0100
struct chk_id {
uint16_t id;
uint16_t can_take_data;
};
struct sctp_tmit_chunk {
union {
struct sctp_data_chunkrec data;
struct chk_id chunk_id;
} rec;
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 mbuf *last_mbuf; /* pointer to last mbuf in chain */
struct sctp_nets *whoTo;
TAILQ_ENTRY(sctp_tmit_chunk) sctp_next; /* next link */
int32_t sent; /* the send status */
uint16_t snd_count; /* number of times I sent */
uint16_t flags; /* flags, such as FRAGMENT_OK */
uint16_t send_size;
uint16_t book_size;
uint16_t mbcnt;
uint8_t pad_inplace;
uint8_t do_rtt;
uint8_t book_size_scale;
uint8_t addr_over; /* flag which is set if the dest address for
* this chunk is overridden by user. Used for
* CMT (iyengar@cis.udel.edu, 2005/06/21) */
uint8_t no_fr_allowed;
uint8_t pr_sctp_on;
uint8_t copy_by_ref;
};
/*
* The first part of this structure MUST be the entire sinfo structure. Maybe
* I should have made it a sub structure... we can circle back later and do
* that if we want.
*/
struct sctp_queued_to_read { /* sinfo structure Pluse more */
uint16_t sinfo_stream; /* off the wire */
uint16_t sinfo_ssn; /* off the wire */
uint16_t sinfo_flags; /* SCTP_UNORDERED from wire use SCTP_EOF for
* EOR */
uint32_t sinfo_ppid; /* off the wire */
uint32_t sinfo_context; /* pick this up from assoc def context? */
uint32_t sinfo_timetolive; /* not used by kernel */
uint32_t sinfo_tsn; /* Use this in reassembly as first TSN */
uint32_t sinfo_cumtsn; /* Use this in reassembly as last TSN */
sctp_assoc_t sinfo_assoc_id; /* our assoc id */
/* Non sinfo stuff */
uint32_t length; /* length of data */
uint32_t held_length; /* length held in sb */
struct sctp_nets *whoFrom; /* where it came from */
struct mbuf *data; /* front of the mbuf chain of data with
* PKT_HDR */
struct mbuf *tail_mbuf; /* used for multi-part data */
struct sctp_tcb *stcb; /* assoc, used for window update */
TAILQ_ENTRY(sctp_queued_to_read) next;
uint16_t port_from;
uint8_t do_not_ref_stcb;
uint8_t end_added;
};
/* This data structure will be on the outbound
* stream queues. Data will be pulled off from
* the front of the mbuf data and chunk-ified
* by the output routines. We will custom
* fit every chunk we pull to the send/sent
* queue to make up the next full packet
* if we can. An entry cannot be removed
* from the stream_out queue until
* the msg_is_complete flag is set. This
* means at times data/tail_mbuf MIGHT
* be NULL.. If that occurs it happens
* for one of two reasons. Either the user
* is blocked on a send() call and has not
* awoken to copy more data down... OR
* the user is in the explict MSG_EOR mode
* and wrote some data, but has not completed
* sending.
*/
struct sctp_stream_queue_pending {
struct mbuf *data;
struct mbuf *tail_mbuf;
struct timeval ts;
struct sctp_nets *net;
TAILQ_ENTRY(sctp_stream_queue_pending) next;
uint32_t length;
uint32_t timetolive;
uint32_t ppid;
uint32_t context;
uint16_t sinfo_flags;
uint16_t stream;
uint16_t strseq;
uint8_t msg_is_complete;
uint8_t some_taken;
uint8_t addr_over;
uint8_t act_flags;
uint8_t pr_sctp_on;
uint8_t resv;
};
/*
* 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 sctp_readhead 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 sctp_streamhead 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 */
uint8_t last_msg_incomplete;
};
/* 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? */
};
struct sctp_scoping {
uint8_t ipv4_addr_legal;
uint8_t ipv6_addr_legal;
uint8_t loopback_scope;
uint8_t ipv4_local_scope;
uint8_t local_scope;
uint8_t site_scope;
};
/*
* 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;
/* Free chunk list */
struct sctpchunk_listhead free_chunks;
/* Free stream output control list */
struct sctp_streamhead free_strmoq;
/* 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 sctpwheel_listhead out_wheel;
/*
* This pointer will be set to NULL most of the time. But when we
* have a fragmented message, where we could not get out all of the
* message at the last send then this will point to the stream to go
* get data from.
*/
struct sctp_stream_out *locked_on_sending;
/* 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;*/
/* Peter, greppign for the above shows only on strange set
* I don't think we need it so I have commented it out.
*/
/* ASCONF save the last ASCONF-ACK so we can resend it if necessary */
struct mbuf *last_asconf_ack_sent;
/*
* pointer to last stream reset queued to control queue by us with
* requests.
*/
struct sctp_tmit_chunk *str_reset;
/*
* 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;
uint8_t *mapping_array;
/* primary destination to use */
struct sctp_nets *primary_destination;
/* For CMT */
struct sctp_nets *last_net_data_came_from;
/* 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 req->send_reset_at_tsn for
* any req on the list.
*/
struct sctp_resethead resetHead;
/* queue of chunks waiting to be sent into the local stack */
struct sctp_readhead pending_reply_queue;
uint32_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;
/* various verification tag information */
uint32_t my_vtag; /* The tag to be used. if assoc is re-initited
* by remote end, and I have unlocked this
* will be regenerated to a new random value. */
uint32_t peer_vtag; /* The peers last tag */
uint32_t my_vtag_nonce;
uint32_t peer_vtag_nonce;
uint32_t assoc_id;
/* This is the SCTP fragmentation threshold */
uint32_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.
*/
uint32_t this_sack_highest_gap;
/*
* The highest consecutive TSN that has been acked by peer on my
* sends
*/
uint32_t last_acked_seq;
/* The next TSN that I will use in sending. */
uint32_t sending_seq;
/* Original seq number I used ??questionable to keep?? */
uint32_t init_seq_number;
/* The Advanced Peer Ack Point, as required by the PR-SCTP */
/* (A1 in Section 4.2) */
uint32_t advanced_peer_ack_point;
/*
* The highest consequetive TSN at the bottom of the mapping array
* (for his sends).
*/
uint32_t cumulative_tsn;
/*
* Used to track the mapping array and its offset bits. This MAY be
* lower then cumulative_tsn.
*/
uint32_t mapping_array_base_tsn;
/*
* used to track highest TSN we have received and is listed in the
* mapping array.
*/
uint32_t highest_tsn_inside_map;
uint32_t last_echo_tsn;
uint32_t last_cwr_tsn;
uint32_t fast_recovery_tsn;
uint32_t sat_t3_recovery_tsn;
uint32_t tsn_last_delivered;
/*
* For the pd-api we should re-write this a bit more efficent. We
* could have multiple sctp_queued_to_read's that we are building at
* once. Now we only do this when we get ready to deliver to the
* socket buffer. Note that we depend on the fact that the struct is
* "stuck" on the read queue until we finish all the pd-api.
*/
struct sctp_queued_to_read *control_pdapi;
uint32_t tsn_of_pdapi_last_delivered;
uint32_t pdapi_ppid;
uint32_t context;
uint32_t last_reset_action[SCTP_MAX_RESET_PARAMS];
uint32_t last_sending_seq[SCTP_MAX_RESET_PARAMS];
uint32_t last_base_tsnsent[SCTP_MAX_RESET_PARAMS];
/*
* window state information and smallest MTU that I use to bound
* segmentation
*/
uint32_t peers_rwnd;
uint32_t my_rwnd;
uint32_t my_last_reported_rwnd;
uint32_t my_rwnd_control_len;
uint32_t total_output_queue_size;
uint32_t sb_cc; /* shadow of sb_cc in one-2-one */
uint32_t sb_mbcnt; /* shadow of sb_mbcnt in one-2-one */
/* 32 bit nonce stuff */
uint32_t nonce_resync_tsn;
uint32_t nonce_wait_tsn;
uint32_t default_flowlabel;
uint32_t pr_sctp_cnt;
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 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;
/* time to delay acks for */
unsigned int delayed_ack;
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 */
/* authentication fields */
sctp_auth_chklist_t *local_auth_chunks;
sctp_auth_chklist_t *peer_auth_chunks;
sctp_hmaclist_t *local_hmacs; /* local HMACs supported */
sctp_hmaclist_t *peer_hmacs; /* peer HMACs supported */
struct sctp_keyhead shared_keys; /* assoc's shared keys */
sctp_authinfo_t authinfo; /* randoms, cached keys */
uint16_t peer_hmac_id; /* peer HMAC id to send */
/*
* refcnt to block freeing when a sender or receiver is off coping
* user data in.
*/
uint16_t refcnt;
/*
* 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).
*/
uint16_t stale_cookie_count;
/*
* For the partial delivery API, if up, invoked this is what last
* TSN I delivered
*/
uint16_t str_of_pdapi;
uint16_t ssn_of_pdapi;
/* counts of actual built streams. Allocation may be more however */
/* could re-arrange to optimize space here. */
uint16_t streamincnt;
uint16_t streamoutcnt;
/* my maximum number of retrans of INIT and SEND */
/* copied from SCTP but should be individually setable */
uint16_t max_init_times;
uint16_t max_send_times;
uint16_t def_net_failure;
/*
* lock flag: 0 is ok to send, 1+ (duals as a retran count) is
* awaiting ACK
*/
uint16_t asconf_sent; /* possibly removable REM */
uint16_t mapping_array_size;
uint16_t last_strm_seq_delivered;
uint16_t last_strm_no_delivered;
uint16_t chunks_on_out_queue; /* total chunks floating around,
* locked by send socket buffer */
uint16_t last_revoke_count;
int16_t num_send_timers_up;
uint16_t stream_locked_on;
uint16_t ecn_echo_cnt_onq;
uint16_t free_chunk_cnt;
uint16_t free_strmoq_cnt;
uint8_t stream_locked;
uint8_t authenticated; /* packet authenticated ok */
/*
* 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.
*/
uint8_t first_ack_sent;
/* max burst after fast retransmit completes */
uint8_t max_burst;
uint8_t sat_network; /* RTT is in range of sat net or greater */
uint8_t sat_network_lockout; /* lockout code */
uint8_t burst_limit_applied; /* Burst limit in effect at last send? */
/* flag goes on when we are doing a partial delivery api */
uint8_t hb_random_values[4];
uint8_t fragmented_delivery_inprogress;
uint8_t fragment_flags;
uint8_t last_flags_delivered;
uint8_t hb_ect_randombit;
uint8_t hb_random_idx;
uint8_t hb_is_disabled; /* is the hb disabled? */
uint8_t default_tos;
/* ECN Nonce stuff */
uint8_t receiver_nonce_sum; /* nonce I sum and put in my sack */
uint8_t ecn_nonce_allowed; /* Tells us if ECN nonce is on */
uint8_t nonce_sum_check;/* On off switch used during re-sync */
uint8_t nonce_wait_for_ecne; /* flag when we expect a ECN */
uint8_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.
*/
uint8_t nonce_sum_expect_base;
/* Flag to tell if ECN is allowed */
uint8_t ecn_allowed;
/* flag to indicate if peer can do asconf */
uint8_t peer_supports_asconf;
/* pr-sctp support flag */
uint8_t peer_supports_prsctp;
/* peer authentication support flag */
uint8_t peer_supports_auth;
/* 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? */
uint8_t ipv4_addr_legal;
uint8_t ipv6_addr_legal;
/* Address scoping flags */
/* scope value for IPv4 */
uint8_t ipv4_local_scope;
/* scope values for IPv6 */
uint8_t local_scope;
uint8_t site_scope;
/* loopback scope */
uint8_t loopback_scope;
/* flags to handle send alternate net tracking */
uint8_t used_alt_onsack;
uint8_t used_alt_asconfack;
uint8_t fast_retran_loss_recovery;
uint8_t sat_t3_loss_recovery;
uint8_t dropped_special_cnt;
uint8_t seen_a_sack_this_pkt;
uint8_t stream_reset_outstanding;
uint8_t stream_reset_out_is_outstanding;
uint8_t delayed_connection;
uint8_t ifp_had_enobuf;
uint8_t saw_sack_with_frags;
uint8_t in_restart_hash;
uint8_t assoc_up_sent;
/* CMT variables */
uint8_t cmt_dac_pkts_rcvd;
uint8_t sctp_cmt_on_off;
uint8_t iam_blocking;
/*
* 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

1736
sys/netinet/sctp_timer.c Normal file

File diff suppressed because it is too large Load Diff

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

@ -0,0 +1,99 @@
/*-
* Copyright (c) 2001-2006, 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:
*
* a) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* b) 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.
*
* c) Neither the name of Cisco Systems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
*/
/* $KAME: sctp_timer.h,v 1.6 2005/03/06 16:04:18 itojun Exp $ */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#ifndef __sctp_timer_h__
#define __sctp_timer_h__
#if defined(_KERNEL)
void
sctp_early_fr_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
struct sctp_nets *net);
struct sctp_nets *
sctp_find_alternate_net(struct sctp_tcb *,
struct sctp_nets *, int high_ssthresh);
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);
int sctp_is_hb_timer_running(struct sctp_tcb *stcb);
int sctp_is_sack_timer_running(struct sctp_tcb *stcb);
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

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

@ -0,0 +1,946 @@
/*-
* Copyright (c) 2001-2006, 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:
*
* a) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* b) 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.
*
* c) Neither the name of Cisco Systems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
*/
/* $KAME: sctp_uio.h,v 1.11 2005/03/06 16:04:18 itojun Exp $ */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#ifndef __sctp_uio_h__
#define __sctp_uio_h__
#if ! defined(_KERNEL)
#include <stdint.h>
#endif
#include <sys/types.h>
#include <sys/socket.h>
typedef uint32_t sctp_assoc_t;
/* On/Off setup for subscription to events */
struct sctp_event_subscribe {
uint8_t sctp_data_io_event;
uint8_t sctp_association_event;
uint8_t sctp_address_event;
uint8_t sctp_send_failure_event;
uint8_t sctp_peer_error_event;
uint8_t sctp_shutdown_event;
uint8_t sctp_partial_delivery_event;
uint8_t sctp_adaptation_layer_event;
uint8_t sctp_authentication_event;
uint8_t sctp_stream_reset_events;
};
/* ancillary data types */
#define SCTP_INIT 0x0001
#define SCTP_SNDRCV 0x0002
#define SCTP_EXTRCV 0x0003
/*
* ancillary data structures
*/
struct sctp_initmsg {
uint32_t sinit_num_ostreams;
uint32_t sinit_max_instreams;
uint16_t sinit_max_attempts;
uint16_t sinit_max_init_timeo;
};
/* We add 96 bytes to the size of sctp_sndrcvinfo.
* This makes the current structure 128 bytes long
* which is nicely 64 bit aligned but also has room
* for us to add more and keep ABI compatability.
* For example, already we have the sctp_extrcvinfo
* when enabled which is 48 bytes.
*/
#define SCTP_ALIGN_RESV_PAD 96
struct sctp_sndrcvinfo {
uint16_t sinfo_stream;
uint16_t sinfo_ssn;
uint16_t sinfo_flags;
uint32_t sinfo_ppid;
uint32_t sinfo_context;
uint32_t sinfo_timetolive;
uint32_t sinfo_tsn;
uint32_t sinfo_cumtsn;
sctp_assoc_t sinfo_assoc_id;
uint8_t __reserve_pad[SCTP_ALIGN_RESV_PAD];
};
struct sctp_extrcvinfo {
uint16_t sinfo_stream;
uint16_t sinfo_ssn;
uint16_t sinfo_flags;
uint32_t sinfo_ppid;
uint32_t sinfo_context;
uint32_t sinfo_timetolive;
uint32_t sinfo_tsn;
uint32_t sinfo_cumtsn;
sctp_assoc_t sinfo_assoc_id;
uint16_t next_flags;
uint16_t next_stream;
uint32_t next_asocid;
uint32_t next_length;
uint32_t next_ppid;
};
#define SCTP_NO_NEXT_MSG 0x0000
#define SCTP_NEXT_MSG_AVAIL 0x0001
#define SCTP_NEXT_MSG_ISCOMPLETE 0x0002
#define SCTP_NEXT_MSG_IS_UNORDERED 0x0004
struct sctp_snd_all_completes {
uint16_t sall_stream;
uint16_t sall_flags;
uint32_t sall_ppid;
uint32_t sall_context;
uint32_t sall_num_sent;
uint32_t sall_num_failed;
};
/* Flags that go into the sinfo->sinfo_flags field */
#define SCTP_EOF 0x0100/* Start shutdown procedures */
#define SCTP_ABORT 0x0200/* Send an ABORT to peer */
#define SCTP_UNORDERED 0x0400/* Message is un-ordered */
#define SCTP_ADDR_OVER 0x0800/* Override the primary-address */
#define SCTP_SENDALL 0x1000/* Send this on all associations */
#define SCTP_EOR 0x2000/* end of message signal */
/* for the endpoint */
/* The lower byte is an enumeration of PR-SCTP policies */
#define SCTP_PR_SCTP_TTL 0x0001/* Time based PR-SCTP */
#define SCTP_PR_SCTP_BUF 0x0002/* Buffer based PR-SCTP */
#define SCTP_PR_SCTP_RTX 0x0003/* Number of retransmissions based PR-SCTP */
#define PR_SCTP_POLICY(x) ((x) & 0xff)
#define PR_SCTP_ENABLED(x) (PR_SCTP_POLICY(x) != 0)
#define PR_SCTP_TTL_ENABLED(x) (PR_SCTP_POLICY(x) == SCTP_PR_SCTP_TTL)
#define PR_SCTP_BUF_ENABLED(x) (PR_SCTP_POLICY(x) == SCTP_PR_SCTP_BUF)
#define PR_SCTP_RTX_ENABLED(x) (PR_SCTP_POLICY(x) == SCTP_PR_SCTP_RTX)
/* Stat's */
struct sctp_pcbinfo {
uint32_t ep_count;
uint32_t asoc_count;
uint32_t laddr_count;
uint32_t raddr_count;
uint32_t chk_count;
uint32_t readq_count;
uint32_t free_chunks;
uint32_t stream_oque;
};
struct sctp_sockstat {
sctp_assoc_t ss_assoc_id;
uint32_t ss_total_sndbuf;
uint32_t ss_total_recv_buf;
};
/*
* notification event structures
*/
/*
* association change event
*/
struct sctp_assoc_change {
uint16_t sac_type;
uint16_t sac_flags;
uint32_t sac_length;
uint16_t sac_state;
uint16_t sac_error;
uint16_t sac_outbound_streams;
uint16_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 event
*/
struct sctp_paddr_change {
uint16_t spc_type;
uint16_t spc_flags;
uint32_t spc_length;
struct sockaddr_storage spc_aaddr;
uint32_t spc_state;
uint32_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 {
uint16_t sre_type;
uint16_t sre_flags;
uint32_t sre_length;
uint16_t sre_error;
sctp_assoc_t sre_assoc_id;
uint8_t sre_data[4];
};
/* data send failure event */
struct sctp_send_failed {
uint16_t ssf_type;
uint16_t ssf_flags;
uint32_t ssf_length;
uint32_t ssf_error;
struct sctp_sndrcvinfo ssf_info;
sctp_assoc_t ssf_assoc_id;
uint8_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 {
uint16_t sse_type;
uint16_t sse_flags;
uint32_t sse_length;
sctp_assoc_t sse_assoc_id;
};
/* Adaptation layer indication stuff */
struct sctp_adaptation_event {
uint16_t sai_type;
uint16_t sai_flags;
uint32_t sai_length;
uint32_t sai_adaptation_ind;
sctp_assoc_t sai_assoc_id;
};
struct sctp_setadaptation {
uint32_t ssb_adaptation_ind;
};
/* compatable old spelling */
struct sctp_adaption_event {
uint16_t sai_type;
uint16_t sai_flags;
uint32_t sai_length;
uint32_t sai_adaption_ind;
sctp_assoc_t sai_assoc_id;
};
struct sctp_setadaption {
uint32_t ssb_adaption_ind;
};
/*
* Partial Delivery API event
*/
struct sctp_pdapi_event {
uint16_t pdapi_type;
uint16_t pdapi_flags;
uint32_t pdapi_length;
uint32_t pdapi_indication;
sctp_assoc_t pdapi_assoc_id;
};
/* indication values */
#define SCTP_PARTIAL_DELIVERY_ABORTED 0x0001
/*
* authentication key event
*/
struct sctp_authkey_event {
uint16_t auth_type;
uint16_t auth_flags;
uint32_t auth_length;
uint16_t auth_keynumber;
uint16_t auth_altkeynumber;
uint32_t auth_indication;
sctp_assoc_t auth_assoc_id;
};
/* indication values */
#define SCTP_AUTH_NEWKEY 0x0001
/*
* stream reset event
*/
struct sctp_stream_reset_event {
uint16_t strreset_type;
uint16_t strreset_flags;
uint32_t strreset_length;
sctp_assoc_t strreset_assoc_id;
uint16_t strreset_list[0];
};
/* flags in strreset_flags field */
#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 SCTP_STRRESET_FAILED 0x0010
/* SCTP notification event */
struct sctp_tlv {
uint16_t sn_type;
uint16_t sn_flags;
uint32_t sn_length;
};
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_adaptation_event sn_adaptation_event;
/* compatability same as above */
struct sctp_adaption_event sn_adaption_event;
struct sctp_pdapi_event sn_pdapi_event;
struct sctp_authkey_event sn_auth_event;
struct sctp_stream_reset_event sn_strreset_event;
};
/* 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_ADAPTATION_INDICATION 0x0006
/* same as above */
#define SCTP_ADAPTION_INDICATION 0x0006
#define SCTP_PARTIAL_DELIVERY_EVENT 0x0007
#define SCTP_AUTHENTICATION_EVENT 0x0008
#define SCTP_STREAM_RESET_EVENT 0x0009
/*
* socket option structs
*/
struct sctp_paddrparams {
sctp_assoc_t spp_assoc_id;
struct sockaddr_storage spp_address;
uint32_t spp_hbinterval;
uint16_t spp_pathmaxrxt;
uint32_t spp_pathmtu;
uint32_t spp_sackdelay;
uint32_t spp_flags;
uint32_t spp_ipv6_flowlabel;
uint8_t spp_ipv4_tos;
};
#define SPP_HB_ENABLE 0x00000001
#define SPP_HB_DISABLE 0x00000002
#define SPP_HB_DEMAND 0x00000004
#define SPP_PMTUD_ENABLE 0x00000008
#define SPP_PMTUD_DISABLE 0x00000010
#define SPP_SACKDELAY_ENABLE 0x00000020
#define SPP_SACKDELAY_DISABLE 0x00000040
#define SPP_HB_TIME_IS_ZERO 0x00000080
#define SPP_IPV6_FLOWLABEL 0x00000100
#define SPP_IPV4_TOS 0x00000200
struct sctp_paddrinfo {
sctp_assoc_t spinfo_assoc_id;
struct sockaddr_storage spinfo_address;
int32_t spinfo_state;
uint32_t spinfo_cwnd;
uint32_t spinfo_srtt;
uint32_t spinfo_rto;
uint32_t spinfo_mtu;
};
struct sctp_rtoinfo {
sctp_assoc_t srto_assoc_id;
uint32_t srto_initial;
uint32_t srto_max;
uint32_t srto_min;
};
struct sctp_assocparams {
sctp_assoc_t sasoc_assoc_id;
uint16_t sasoc_asocmaxrxt;
uint16_t sasoc_number_peer_destinations;
uint32_t sasoc_peer_rwnd;
uint32_t sasoc_local_rwnd;
uint32_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;
uint32_t ssto_timeout;
uint32_t ssto_streamid_start;
uint32_t ssto_streamid_end;
};
struct sctp_status {
sctp_assoc_t sstat_assoc_id;
int32_t sstat_state;
uint32_t sstat_rwnd;
uint16_t sstat_unackdata;
uint16_t sstat_penddata;
uint16_t sstat_instrms;
uint16_t sstat_outstrms;
uint32_t sstat_fragmentation_point;
struct sctp_paddrinfo sstat_primary;
};
/*
* AUTHENTICATION support
*/
/* SCTP_AUTH_CHUNK */
struct sctp_authchunk {
uint8_t sauth_chunk;
};
/* SCTP_AUTH_KEY */
struct sctp_authkey {
sctp_assoc_t sca_assoc_id;
uint16_t sca_keynumber;
uint8_t sca_key[0];
};
/* SCTP_HMAC_IDENT */
struct sctp_hmacalgo {
uint16_t shmac_idents[0];
};
/* AUTH hmac_id */
#define SCTP_AUTH_HMAC_ID_RSVD 0x0000
#define SCTP_AUTH_HMAC_ID_SHA1 0x0001 /* default, mandatory */
#define SCTP_AUTH_HMAC_ID_MD5 0x0002 /* deprecated */
#define SCTP_AUTH_HMAC_ID_SHA256 0x0003
#define SCTP_AUTH_HMAC_ID_SHA224 0x8001
#define SCTP_AUTH_HMAC_ID_SHA384 0x8002
#define SCTP_AUTH_HMAC_ID_SHA512 0x8003
/* SCTP_AUTH_ACTIVE_KEY / SCTP_AUTH_DELETE_KEY */
struct sctp_authkeyid {
sctp_assoc_t scact_assoc_id;
uint16_t scact_keynumber;
};
/* SCTP_PEER_AUTH_CHUNKS / SCTP_LOCAL_AUTH_CHUNKS */
struct sctp_authchunks {
sctp_assoc_t gauth_assoc_id;
uint8_t gauth_chunks[0];
};
struct sctp_assoc_value {
sctp_assoc_t assoc_id;
uint32_t assoc_value;
};
#define MAX_ASOC_IDS_RET 255
struct sctp_assoc_ids {
uint16_t asls_assoc_start; /* array of index's start at 0 */
uint8_t asls_numb_present;
uint8_t asls_more_to_get;
sctp_assoc_t asls_assoc_id[MAX_ASOC_IDS_RET];
};
struct sctp_cwnd_args {
struct sctp_nets *net; /* network to */
uint32_t cwnd_new_value;/* cwnd in k */
uint32_t inflight; /* flightsize in k */
uint32_t pseudo_cumack;
int cwnd_augment; /* increment to it */
uint8_t meets_pseudo_cumack;
uint8_t need_new_pseudo_cumack;
uint8_t cnt_in_send;
uint8_t cnt_in_str;
};
struct sctp_blk_args {
uint32_t onsb; /* in 1k bytes */
uint32_t sndlen; /* len of send being attempted */
uint32_t peer_rwnd; /* rwnd of peer */
uint16_t send_sent_qcnt;/* chnk cnt */
uint16_t stream_qcnt; /* chnk cnt */
uint16_t chunks_on_oque;/* chunks out */
uint16_t flight_size; /* flight size in k */
};
/*
* 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
#define SCTP_RESET_TSN 0x0004
struct sctp_stream_reset {
sctp_assoc_t strrst_assoc_id;
uint16_t strrst_flags;
uint16_t strrst_num_streams; /* 0 == ALL */
uint16_t strrst_list[0];/* list if strrst_num_streams is not 0 */
};
struct sctp_get_nonce_values {
sctp_assoc_t gn_assoc_id;
uint32_t gn_peers_tag;
uint32_t gn_local_tag;
};
/* Debugging logs */
struct sctp_str_log {
uint32_t n_tsn;
uint32_t e_tsn;
uint16_t n_sseq;
uint16_t e_sseq;
};
struct sctp_sb_log {
uint32_t stcb;
uint32_t so_sbcc;
uint32_t stcb_sbcc;
uint32_t incr;
};
struct sctp_fr_log {
uint32_t largest_tsn;
uint32_t largest_new_tsn;
uint32_t tsn;
};
struct sctp_fr_map {
uint32_t base;
uint32_t cum;
uint32_t high;
};
struct sctp_rwnd_log {
uint32_t rwnd;
uint32_t send_size;
uint32_t overhead;
uint32_t new_rwnd;
};
struct sctp_mbcnt_log {
uint32_t total_queue_size;
uint32_t size_change;
uint32_t total_queue_mb_size;
uint32_t mbcnt_change;
};
struct sctp_sack_log {
uint32_t cumack;
uint32_t oldcumack;
uint32_t tsn;
uint16_t numGaps;
uint16_t numDups;
};
struct sctp_lock_log {
uint32_t sock;
uint32_t inp;
uint8_t tcb_lock;
uint8_t inp_lock;
uint8_t info_lock;
uint8_t sock_lock;
uint8_t sockrcvbuf_lock;
uint8_t socksndbuf_lock;
uint8_t create_lock;
uint8_t resv;
};
struct sctp_rto_log {
uint32_t net;
uint32_t rtt;
uint32_t rttvar;
uint8_t direction;
};
struct sctp_nagle_log {
uint32_t stcb;
uint32_t total_flight;
uint32_t total_in_queue;
uint16_t count_in_queue;
uint16_t count_in_flight;
};
struct sctp_sbwake_log {
uint32_t stcb;
uint16_t send_q;
uint16_t sent_q;
uint16_t flight;
uint16_t wake_cnt;
uint8_t stream_qcnt; /* chnk cnt */
uint8_t chunks_on_oque; /* chunks out */
uint8_t sbflags;
uint8_t sctpflags;
};
struct sctp_misc_info {
uint32_t log1;
uint32_t log2;
uint32_t log3;
uint32_t log4;
};
struct sctp_log_closing {
uint32_t inp;
uint32_t stcb;
uint32_t sctp_flags;
uint16_t state;
int16_t loc;
};
struct sctp_mbuf_log {
struct mbuf *mp;
caddr_t ext;
caddr_t data;
uint16_t size;
uint8_t refcnt;
uint8_t mbuf_flags;
};
struct sctp_cwnd_log {
uint32_t time_event;
uint8_t from;
uint8_t event_type;
uint8_t resv[2];
union {
struct sctp_log_closing close;
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;
struct sctp_sack_log sack;
struct sctp_lock_log lock;
struct sctp_rto_log rto;
struct sctp_sb_log sb;
struct sctp_nagle_log nagle;
struct sctp_sbwake_log wake;
struct sctp_mbuf_log mb;
struct sctp_misc_info misc;
} x;
};
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];
};
struct sctpstat {
/* MIB according to RFC 3873 */
u_long sctps_currestab; /* sctpStats 1 (Gauge32) */
u_long sctps_activeestab; /* sctpStats 2 (Counter32) */
u_long sctps_passiveestab; /* sctpStats 3 (Counter32) */
u_long sctps_aborted; /* sctpStats 4 (Counter32) */
u_long sctps_shutdown; /* sctpStats 5 (Counter32) */
u_long sctps_outoftheblue; /* sctpStats 6 (Counter32) */
u_long sctps_checksumerrors; /* sctpStats 7 (Counter32) */
u_long sctps_outcontrolchunks; /* sctpStats 8 (Counter64) */
u_long sctps_outorderchunks; /* sctpStats 9 (Counter64) */
u_long sctps_outunorderchunks; /* sctpStats 10 (Counter64) */
u_long sctps_incontrolchunks; /* sctpStats 11 (Counter64) */
u_long sctps_inorderchunks; /* sctpStats 12 (Counter64) */
u_long sctps_inunorderchunks; /* sctpStats 13 (Counter64) */
u_long sctps_fragusrmsgs; /* sctpStats 14 (Counter64) */
u_long sctps_reasmusrmsgs; /* sctpStats 15 (Counter64) */
u_long sctps_outpackets;/* sctpStats 16 (Counter64) */
u_long sctps_inpackets; /* sctpStats 17 (Counter64) */
u_long sctps_discontinuitytime; /* sctpStats 18 (TimeStamp) */
/* input statistics: */
u_long sctps_recvpackets; /* total input packets */
u_long sctps_recvdatagrams; /* total input datagrams */
u_long sctps_recvpktwithdata;
u_long sctps_recvsacks; /* total input SACK chunks */
u_long sctps_recvdata; /* total input DATA chunks */
u_long sctps_recvdupdata; /* total input duplicate DATA chunks */
u_long sctps_recvheartbeat; /* total input HB chunks */
u_long sctps_recvheartbeatack; /* total input HB-ACK chunks */
u_long sctps_recvecne; /* total input ECNE chunks */
u_long sctps_recvauth; /* total input AUTH chunks */
u_long sctps_recvauthmissing; /* total input chunks missing AUTH */
u_long sctps_recvivalhmacid; /* total number of invalid HMAC ids
* received */
u_long sctps_recvivalkeyid; /* total number of invalid secret ids
* received */
u_long sctps_recvauthfailed; /* total number of auth failed */
u_long sctps_recvexpress; /* total fast path receives all one
* chunk */
u_long sctps_recvexpressm; /* total fast path multi-part data */
/* output statistics: */
u_long sctps_sendpackets; /* total output packets */
u_long sctps_sendsacks; /* total output SACKs */
u_long sctps_senddata; /* total output DATA chunks */
u_long sctps_sendretransdata; /* total output retransmitted DATA
* chunks */
u_long sctps_sendfastretrans; /* total output fast retransmitted
* DATA chunks */
u_long sctps_sendmultfastretrans; /* U-del */
u_long sctps_sendheartbeat; /* total output HB chunks */
u_long sctps_sendecne; /* total output ECNE chunks */
u_long sctps_sendauth; /* total output AUTH chunks FIXME */
u_long sctps_senderrors;/* ip_output error counter */
/* PCKDROPREP statistics: */
u_long sctps_pdrpfmbox; /* */
u_long sctps_pdrpfehos; /* */
u_long sctps_pdrpmbda; /* */
u_long sctps_pdrpmbct; /* */
u_long sctps_pdrpbwrpt; /* */
u_long sctps_pdrpcrupt; /* */
u_long sctps_pdrpnedat; /* */
u_long sctps_pdrppdbrk; /* */
u_long sctps_pdrptsnnf; /* */
u_long sctps_pdrpdnfnd; /* */
u_long sctps_pdrpdiwnp; /* */
u_long sctps_pdrpdizrw; /* */
u_long sctps_pdrpbadd; /* */
u_long sctps_pdrpmark; /* */
/* timeouts */
u_long sctps_timoiterator; /* */
u_long sctps_timodata; /* */
u_long sctps_timowindowprobe; /* */
u_long sctps_timoinit; /* */
u_long sctps_timosack; /* */
u_long sctps_timoshutdown; /* */
u_long sctps_timoheartbeat; /* */
u_long sctps_timocookie;/* */
u_long sctps_timosecret;/* */
u_long sctps_timopathmtu; /* */
u_long sctps_timoshutdownack; /* */
u_long sctps_timoshutdownguard; /* */
u_long sctps_timostrmrst; /* */
u_long sctps_timoearlyfr; /* */
u_long sctps_timoasconf;/* */
u_long sctps_timoautoclose; /* */
u_long sctps_timoassockill; /* */
u_long sctps_timoinpkill; /* */
/* Early fast retransmission counters */
u_long sctps_earlyfrstart;
u_long sctps_earlyfrstop;
u_long sctps_earlyfrmrkretrans;
u_long sctps_earlyfrstpout;
u_long sctps_earlyfrstpidsck1;
u_long sctps_earlyfrstpidsck2;
u_long sctps_earlyfrstpidsck3;
u_long sctps_earlyfrstpidsck4;
u_long sctps_earlyfrstrid;
u_long sctps_earlyfrstrout;
u_long sctps_earlyfrstrtmr;
/* otheres */
u_long sctps_hdrops; /* packet shorter than header */
u_long sctps_badsum; /* checksum error */
u_long sctps_noport; /* no endpoint for port */
u_long sctps_badvtag; /* bad v-tag */
u_long sctps_badsid; /* bad SID */
u_long sctps_nomem; /* no memory */
u_long sctps_fastretransinrtt; /* number of multiple FR in a RTT
* window */
u_long sctps_markedretrans;
u_long sctps_naglesent; /* nagle allowed sending */
u_long sctps_naglequeued; /* nagle does't allow sending */
u_long sctps_maxburstqueued; /* max burst dosn't allow sending */
u_long sctps_ifnomemqueued; /* */
u_long sctps_windowprobed; /* total number of window probes sent */
u_long sctps_lowlevelerr;
u_long sctps_lowlevelerrusr;
u_long sctps_datadropchklmt;
u_long sctps_datadroprwnd;
u_long sctps_ecnereducedcwnd;
u_long sctps_vtagexpress; /* Used express lookup via vtag */
u_long sctps_vtagbogus; /* Collision in express lookup. */
u_long sctps_primary_randry; /* Number of times the sender ran dry
* of user data on primary */
u_long sctps_cmt_randry;/* Same for above */
u_long sctps_slowpath_sack; /* Sacks the slow way */
u_long sctps_wu_sacks_sent; /* Window Update only sacks sent */
u_long sctps_locks_in_rcv; /* How man so_rcv buf locks we did */
u_long sctps_locks_in_rcva; /* How man so_rcv buf locks we did */
u_long sctps_locks_in_rcvb; /* How man so_rcv buf locks we did */
u_long sctps_locks_in_rcvc; /* How man so_rcv buf locks we did */
u_long sctps_locks_in_rcvd; /* How man so_rcv buf locks we did */
u_long sctps_locks_in_rcve; /* How man so_rcv buf locks we did */
u_long sctps_locks_in_rcvf; /* How man so_rcv buf locks we did */
};
#define SCTP_STAT_INCR(_x) SCTP_STAT_INCR_BY(_x,1)
#define SCTP_STAT_DECR(_x) SCTP_STAT_DECR_BY(_x,1)
#define SCTP_STAT_INCR_BY(_x,_d) atomic_add_long(&sctpstat._x, _d)
#define SCTP_STAT_DECR_BY(_x,_d) atomic_add_long(&sctpstat._x, -(_d))
/* The following macros are for handling MIB values, */
#define SCTP_STAT_INCR_COUNTER32(_x) SCTP_STAT_INCR(_x)
#define SCTP_STAT_INCR_COUNTER64(_x) SCTP_STAT_INCR(_x)
#define SCTP_STAT_INCR_GAUGE32(_x) SCTP_STAT_INCR(_x)
#define SCTP_STAT_DECR_COUNTER32(_x) SCTP_STAT_DECR(_x)
#define SCTP_STAT_DECR_COUNTER64(_x) SCTP_STAT_DECR(_x)
#define SCTP_STAT_DECR_GAUGE32(_x) SCTP_STAT_DECR(_x)
/*
* Kernel defined for sctp_send
*/
#if defined(_KERNEL)
int
sctp_lower_sosend(struct socket *so,
struct sockaddr *addr,
struct uio *uio,
struct mbuf *top,
struct mbuf *control,
int flags,
int use_rcvinfo,
struct sctp_sndrcvinfo *srcv,
struct thread *p
);
int
sctp_sorecvmsg(struct socket *so,
struct uio *uio,
struct mbuf **mp,
struct sockaddr *from,
int fromlen,
int *msg_flags,
struct sctp_sndrcvinfo *sinfo,
int filling_sinfo);
#endif
/*
* API system calls
*/
#if !(defined(_KERNEL))
__BEGIN_DECLS
int sctp_peeloff __P((int, sctp_assoc_t));
int sctp_bindx __P((int, struct sockaddr *, int, int));
int sctp_connectx __P((int, const struct sockaddr *, int));
int sctp_getaddrlen __P((sa_family_t));
int sctp_getpaddrs __P((int, sctp_assoc_t, struct sockaddr **));
void sctp_freepaddrs __P((struct sockaddr *));
int sctp_getladdrs __P((int, sctp_assoc_t, struct sockaddr **));
void sctp_freeladdrs __P((struct sockaddr *));
int sctp_opt_info __P((int, sctp_assoc_t, int, void *, socklen_t *));
ssize_t sctp_sendmsg
__P((int, const void *, size_t,
const struct sockaddr *,
socklen_t, uint32_t, uint32_t, uint16_t, uint32_t, uint32_t));
ssize_t sctp_send __P((int sd, const void *msg, size_t len,
const struct sctp_sndrcvinfo *sinfo, int flags));
ssize_t
sctp_sendx __P((int sd, const void *msg, size_t len,
struct sockaddr *addrs, int addrcnt,
struct sctp_sndrcvinfo *sinfo, int flags));
ssize_t
sctp_sendmsgx __P((int sd, const void *, size_t,
struct sockaddr *, int,
uint32_t, uint32_t, uint16_t, uint32_t, uint32_t));
sctp_assoc_t
sctp_getassocid __P((int sd, struct sockaddr *sa));
ssize_t sctp_recvmsg __P((int, void *, size_t, struct sockaddr *,
socklen_t *, struct sctp_sndrcvinfo *, int *));
__END_DECLS
#endif /* !_KERNEL */
#endif /* !__sctp_uio_h__ */

4852
sys/netinet/sctp_usrreq.c Normal file

File diff suppressed because it is too large Load Diff

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

@ -0,0 +1,476 @@
/*-
* Copyright (c) 2001-2006, 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:
*
* a) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* b) 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.
*
* c) Neither the name of Cisco Systems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
*/
/* $KAME: sctp_var.h,v 1.24 2005/03/06 16:04:19 itojun Exp $ */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#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
*/
#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
#define SCTPCTL_CMT_ON_OFF 26
#define SCTPCTL_CWND_MAXBURST 27
#define SCTPCTL_EARLY_FR 28
#define SCTPCTL_RTTVAR_CC 29
#define SCTPCTL_DEADLOCK_DET 30
#define SCTPCTL_EARLY_FR_MSEC 31
#define SCTPCTL_ASCONF_AUTH_NOCHK 32
#define SCTPCTL_AUTH_DISABLE 33
#define SCTPCTL_AUTH_RANDOM_LEN 34
#define SCTPCTL_AUTH_HMAC_ID 35
#define SCTPCTL_ABC_L_VAR 36
#define SCTPCTL_MAX_MBUF_CHAIN 37
#define SCTPCTL_CMT_USE_DAC 38
#define SCTPCTL_DO_DRAIN 39
#define SCTPCTL_WARM_CRC32 40
#define SCTPCTL_QLIMIT_ABORT 41
#define SCTPCTL_STRICT_ORDER 42
#define SCTPCTL_TCBHASHSIZE 43
#define SCTPCTL_PCBHASHSIZE 44
#define SCTPCTL_CHUNKSCALE 45
#define SCTPCTL_MINSPLIT 46
#define SCTPCTL_ADD_MORE 47
#define SCTPCTL_SYS_RESC 48
#define SCTPCTL_ASOC_RESC 49
#ifdef SCTP_DEBUG
#define SCTPCTL_DEBUG 50
#define SCTPCTL_MAXID 50
#else
#define SCTPCTL_MAXID 49
#endif
#ifdef SCTP_DEBUG
#define SCTPCTL_NAMES { \
{ 0, 0 }, \
{ "sendspace", 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 }, \
{ "cmt_on_off", CTLTYPE_INT }, \
{ "cwnd_maxburst", CTLTYPE_INT }, \
{ "early_fast_retran", CTLTYPE_INT }, \
{ "use_rttvar_congctrl", CTLTYPE_INT }, \
{ "deadlock_detect", CTLTYPE_INT }, \
{ "early_fast_retran_msec", CTLTYPE_INT }, \
{ "asconf_auth_nochk", CTLTYPE_INT }, \
{ "auth_disable", CTLTYPE_INT }, \
{ "auth_random_len", CTLTYPE_INT }, \
{ "auth_hmac_id", CTLTYPE_INT }, \
{ "abc_l_var", CTLTYPE_INT }, \
{ "max_mbuf_chain", CTLTYPE_INT }, \
{ "cmt_use_dac", CTLTYPE_INT }, \
{ "do_sctp_drain", CTLTYPE_INT }, \
{ "warm_crc_table", CTLTYPE_INT }, \
{ "abort_at_limit", CTLTYPE_INT }, \
{ "strict_data_order", CTLTYPE_INT }, \
{ "tcbhashsize", CTLTYPE_INT }, \
{ "pcbhashsize", CTLTYPE_INT }, \
{ "chunkscale", CTLTYPE_INT }, \
{ "min_split_point", CTLTYPE_INT }, \
{ "add_more_on_output", CTLTYPE_INT }, \
{ "sys_resource", CTLTYPE_INT }, \
{ "asoc_resource", CTLTYPE_INT }, \
{ "debug", CTLTYPE_INT }, \
}
#else
#define SCTPCTL_NAMES { \
{ 0, 0 }, \
{ "sendspace", 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 }, \
{ "cmt_on_off", CTLTYPE_INT }, \
{ "cwnd_maxburst", CTLTYPE_INT }, \
{ "early_fast_retran", CTLTYPE_INT }, \
{ "use_rttvar_congctrl", CTLTYPE_INT }, \
{ "deadlock_detect", CTLTYPE_INT }, \
{ "early_fast_retran_msec", CTLTYPE_INT }, \
{ "asconf_auth_nochk", CTLTYPE_INT }, \
{ "auth_disable", CTLTYPE_INT }, \
{ "auth_random_len", CTLTYPE_INT }, \
{ "auth_hmac_id", CTLTYPE_INT }, \
{ "abc_l_var", CTLTYPE_INT }, \
{ "max_mbuf_chain", CTLTYPE_INT }, \
{ "cmt_use_dac", CTLTYPE_INT }, \
{ "do_sctp_drain", CTLTYPE_INT }, \
{ "warm_crc_table", CTLTYPE_INT }, \
{ "abort_at_limit", CTLTYPE_INT }, \
{ "strict_data_order", CTLTYPE_INT }, \
{ "tcbhashsize", CTLTYPE_INT }, \
{ "pcbhashsize", CTLTYPE_INT }, \
{ "chunkscale", CTLTYPE_INT }, \
{ "min_split_point", CTLTYPE_INT }, \
{ "add_more_on_output", CTLTYPE_INT }, \
{ "sys_resource", CTLTYPE_INT }, \
{ "asoc_resource", CTLTYPE_INT }, \
}
#endif
#if defined(_KERNEL)
#ifdef SYSCTL_DECL
SYSCTL_DECL(_net_inet_sctp);
#endif
extern struct pr_usrreqs sctp_usrreqs;
#define sctp_feature_on(inp, feature) (inp->sctp_features |= feature)
#define sctp_feature_off(inp, feature) (inp->sctp_features &= ~feature)
#define sctp_is_feature_on(inp, feature) (inp->sctp_features & feature)
#define sctp_is_feature_off(inp, feature) ((inp->sctp_features & feature) == 0)
#define sctp_sbspace(asoc, sb) ((long) (((sb)->sb_hiwat > (asoc)->sb_cc) ? ((sb)->sb_hiwat - (asoc)->sb_cc) : 0))
#define sctp_sbspace_failedmsgs(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 uint32_t sctp_asoc_free_resc_limit;
extern uint32_t sctp_system_free_resc_limit;
/* I tried to cache the readq entries at one
* point. But the reality is that it did not
* add any performance since this meant
* we had to lock the STCB on read. And at that point
* once you have to do an extra lock, it really does
* not matter if the lock is in the ZONE stuff or
* in our code. Note that this same problem would
* occur with an mbuf cache as well so it is
* not really worth doing, at least right now :-D
*/
#define sctp_free_a_readq(_stcb, _readq) { \
SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_readq, (_readq)); \
SCTP_DECR_READQ_COUNT(); \
}
#define sctp_alloc_a_readq(_stcb, _readq) { \
(_readq) = (struct sctp_queued_to_read *)SCTP_ZONE_GET(sctppcbinfo.ipi_zone_readq); \
if ((_readq)) { \
SCTP_INCR_READQ_COUNT(); \
} \
}
#define sctp_free_a_strmoq(_stcb, _strmoq) { \
if (((_stcb)->asoc.free_strmoq_cnt > sctp_asoc_free_resc_limit) || \
(sctppcbinfo.ipi_free_strmoq > sctp_system_free_resc_limit)) { \
SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_strmoq, (_strmoq)); \
SCTP_DECR_STRMOQ_COUNT(); \
} else { \
TAILQ_INSERT_TAIL(&(_stcb)->asoc.free_strmoq, (_strmoq), next); \
(_stcb)->asoc.free_strmoq_cnt++; \
atomic_add_int(&sctppcbinfo.ipi_free_strmoq, 1); \
} \
}
#define sctp_alloc_a_strmoq(_stcb, _strmoq) { \
if(TAILQ_EMPTY(&(_stcb)->asoc.free_strmoq)) { \
(_strmoq) = (struct sctp_stream_queue_pending *)SCTP_ZONE_GET(sctppcbinfo.ipi_zone_strmoq); \
if ((_strmoq)) { \
SCTP_INCR_STRMOQ_COUNT(); \
} \
} else { \
(_strmoq) = TAILQ_FIRST(&(_stcb)->asoc.free_strmoq); \
TAILQ_REMOVE(&(_stcb)->asoc.free_strmoq, (_strmoq), next); \
atomic_subtract_int(&sctppcbinfo.ipi_free_strmoq, 1); \
(_stcb)->asoc.free_strmoq_cnt--; \
} \
}
#define sctp_free_a_chunk(_stcb, _chk) { \
if (((_stcb)->asoc.free_chunk_cnt > sctp_asoc_free_resc_limit) || \
(sctppcbinfo.ipi_free_chunks > sctp_system_free_resc_limit)) { \
SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_chunk, (_chk)); \
SCTP_DECR_CHK_COUNT(); \
} else { \
TAILQ_INSERT_TAIL(&(_stcb)->asoc.free_chunks, (_chk), sctp_next); \
(_stcb)->asoc.free_chunk_cnt++; \
atomic_add_int(&sctppcbinfo.ipi_free_chunks, 1); \
} \
}
#define sctp_alloc_a_chunk(_stcb, _chk) { \
if(TAILQ_EMPTY(&(_stcb)->asoc.free_chunks)) { \
(_chk) = (struct sctp_tmit_chunk *)SCTP_ZONE_GET(sctppcbinfo.ipi_zone_chunk); \
if ((_chk)) { \
SCTP_INCR_CHK_COUNT(); \
} \
} else { \
(_chk) = TAILQ_FIRST(&(_stcb)->asoc.free_chunks); \
TAILQ_REMOVE(&(_stcb)->asoc.free_chunks, (_chk), sctp_next); \
atomic_subtract_int(&sctppcbinfo.ipi_free_chunks, 1); \
(_stcb)->asoc.free_chunk_cnt--; \
} \
}
#define sctp_free_remote_addr(__net) { \
if ((__net)) { \
if (atomic_fetchadd_int(&(__net)->ref_count, -1) == 1) { \
callout_stop(&(__net)->rxt_timer.timer); \
callout_stop(&(__net)->pmtu_timer.timer); \
callout_stop(&(__net)->fr_timer.timer); \
(__net)->dest_state = SCTP_ADDR_NOT_REACHABLE; \
SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_net, (__net)); \
SCTP_DECR_RADDR_COUNT(); \
} \
} \
}
#define sctp_sbfree(ctl, stcb, sb, m) { \
uint32_t val; \
val = atomic_fetchadd_int(&(sb)->sb_cc,-((m)->m_len)); \
if(val < (m)->m_len) { \
panic("sb_cc goes negative"); \
} \
val = atomic_fetchadd_int(&(sb)->sb_mbcnt,-(MSIZE)); \
if(val < MSIZE) { \
panic("sb_mbcnt goes negative"); \
} \
if ((m)->m_flags & M_EXT) { \
val = atomic_fetchadd_int(&(sb)->sb_mbcnt,-((m)->m_ext.ext_size)); \
if(val < (m)->m_ext.ext_size) { \
panic("sb_mbcnt goes negative2"); \
} \
} \
if (((ctl)->do_not_ref_stcb == 0) && stcb) {\
val = atomic_fetchadd_int(&(stcb)->asoc.sb_cc,-((m)->m_len)); \
if(val < (m)->m_len) {\
panic("stcb->sb_cc goes negative"); \
} \
val = atomic_fetchadd_int(&(stcb)->asoc.sb_mbcnt,-(MSIZE)); \
if(val < MSIZE) { \
panic("asoc->mbcnt goes negative"); \
} \
if ((m)->m_flags & M_EXT) { \
val = atomic_fetchadd_int(&(stcb)->asoc.sb_mbcnt,-((m)->m_ext.ext_size)); \
if(val < (m)->m_ext.ext_size) { \
panic("assoc stcb->mbcnt would go negative"); \
} \
} \
} \
if ((m)->m_type != MT_DATA && (m)->m_type != MT_HEADER && \
(m)->m_type != MT_OOBDATA) \
atomic_subtract_int(&(sb)->sb_ctl,(m)->m_len); \
}
#define sctp_sballoc(stcb, sb, m) { \
atomic_add_int(&(sb)->sb_cc,(m)->m_len); \
atomic_add_int(&(sb)->sb_mbcnt, MSIZE); \
if ((m)->m_flags & M_EXT) \
atomic_add_int(&(sb)->sb_mbcnt,(m)->m_ext.ext_size); \
if(stcb) { \
atomic_add_int(&(stcb)->asoc.sb_cc,(m)->m_len); \
atomic_add_int(&(stcb)->asoc.sb_mbcnt, MSIZE); \
if ((m)->m_flags & M_EXT) \
atomic_add_int(&(stcb)->asoc.sb_mbcnt,(m)->m_ext.ext_size); \
} \
if ((m)->m_type != MT_DATA && (m)->m_type != MT_HEADER && \
(m)->m_type != MT_OOBDATA) \
atomic_add_int(&(sb)->sb_ctl,(m)->m_len); \
}
#define sctp_ucount_incr(val) { \
val++; \
}
#define sctp_ucount_decr(val) { \
if (val > 0) { \
val--; \
} else { \
val = 0; \
} \
}
#define sctp_mbuf_crush(data) do { \
struct mbuf *_m; \
_m = (data); \
while(_m && (_m->m_len == 0)) { \
(data) = _m->m_next; \
_m->m_next = NULL; \
sctp_m_free(_m); \
_m = (data); \
} \
} while (0)
extern int sctp_sendspace;
extern int sctp_recvspace;
extern int sctp_ecn_enable;
extern int sctp_ecn_nonce;
extern int sctp_use_cwnd_based_maxburst;
extern unsigned int sctp_cmt_on_off;
extern unsigned int sctp_cmt_use_dac;
extern unsigned int sctp_cmt_sockopt_on_off;
struct sctp_nets;
struct sctp_inpcb;
struct sctp_tcb;
struct sctphdr;
void sctp_ctlinput __P((int, struct sockaddr *, void *));
int sctp_ctloutput __P((struct socket *, struct sockopt *));
void sctp_input __P((struct mbuf *, int));
void sctp_drain __P((void));
void sctp_init __P((void));
int sctp_shutdown __P((struct socket *));
void sctp_notify
__P((struct sctp_inpcb *, int, struct sctphdr *,
struct sockaddr *, struct sctp_tcb *,
struct sctp_nets *));
#if defined(INET6)
void ip_2_ip6_hdr __P((struct ip6_hdr *, struct ip *));
#endif
int sctp_bindx(struct socket *, int, struct sockaddr_storage *,
int, int, struct proc *);
/* can't use sctp_assoc_t here */
int sctp_peeloff(struct socket *, struct socket *, int, caddr_t, int *);
sctp_assoc_t sctp_getassocid(struct sockaddr *);
int sctp_ingetaddr(struct socket *,
struct sockaddr **
);
int sctp_peeraddr(struct socket *,
struct sockaddr **
);
int sctp_listen(struct socket *, int, struct thread *);
int sctp_accept(struct socket *, struct sockaddr **);
#endif /* _KERNEL */
#endif /* !_NETINET_SCTP_VAR_H_ */

5390
sys/netinet/sctputil.c Normal file

File diff suppressed because it is too large Load Diff

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

@ -0,0 +1,314 @@
/*-
* Copyright (c) 2001-2006, 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:
*
* a) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* b) 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.
*
* c) Neither the name of Cisco Systems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
*/
/* $KAME: sctputil.h,v 1.15 2005/03/06 16:04:19 itojun Exp $ */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#ifndef __sctputil_h__
#define __sctputil_h__
#if defined(_KERNEL)
#ifdef SCTP_MBUF_LOGGING
struct mbuf *sctp_m_free(struct mbuf *m);
void sctp_m_freem(struct mbuf *m);
#else
#define sctp_m_free m_free
#define sctp_m_freem m_freem
#endif
#define sctp_m_copym m_copym
#define sctp_get_associd(stcb) ((sctp_assoc_t)stcb->asoc.assoc_id)
/*
* Function prototypes
*/
struct ifaddr *sctp_find_ifa_by_addr(struct sockaddr *sa);
uint32_t sctp_select_initial_TSN(struct sctp_pcb *);
uint32_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 *);
uint32_t sctp_calculate_sum(struct mbuf *, int32_t *, uint32_t);
void
sctp_mtu_size_reset(struct sctp_inpcb *, struct sctp_association *,
u_long);
void
sctp_add_to_readq(struct sctp_inpcb *inp,
struct sctp_tcb *stcb,
struct sctp_queued_to_read *control,
struct sockbuf *sb,
int end);
int
sctp_append_to_readq(struct sctp_inpcb *inp,
struct sctp_tcb *stcb,
struct sctp_queued_to_read *control,
struct mbuf *m,
int end,
int new_cumack,
struct sockbuf *sb);
int find_next_best_mtu(int);
void
sctp_timeout_handler(void *);
uint32_t
sctp_calculate_rto(struct sctp_tcb *, struct sctp_association *,
struct sctp_nets *, struct timeval *);
uint32_t sctp_calculate_len(struct mbuf *);
caddr_t sctp_m_getptr(struct mbuf *, int, int, uint8_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, struct mbuf *);
void sctp_ulp_notify(uint32_t, struct sctp_tcb *, uint32_t, void *);
void
sctp_pull_off_control_to_new_inp(struct sctp_inpcb *old_inp,
struct sctp_inpcb *new_inp,
struct sctp_tcb *stcb);
void sctp_stop_timers_for_shutdown(struct sctp_tcb *);
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, uint32_t *);
uint32_t sctp_is_same_scope(struct sockaddr_in6 *, struct sockaddr_in6 *);
struct sockaddr_in6 *
sctp_recover_scope(struct sockaddr_in6 *,
struct sockaddr_in6 *);
#define sctp_recover_scope_mac(addr, store) do { \
if ((addr->sin6_family == AF_INET6) && \
(IN6_IS_SCOPE_LINKLOCAL(&addr->sin6_addr)) && \
(addr->sin6_scope_id == 0)) { \
*store = *addr; \
if (!sa6_recoverscope(store)) { \
addr = store; \
} \
} \
} while (0)
int sctp_cmpaddr(struct sockaddr *, struct sockaddr *);
void sctp_print_address(struct sockaddr *);
void sctp_print_address_pkt(struct ip *, struct sctphdr *);
void
sctp_notify_partial_delivery_indication(struct sctp_tcb *stcb,
uint32_t error, int no_lock);
int
sctp_release_pr_sctp_chunk(struct sctp_tcb *, struct sctp_tmit_chunk *,
int, struct sctpchunk_listhead *);
struct mbuf *sctp_generate_invmanparam(int);
#ifdef SCTP_MBCNT_LOGGING
void
sctp_free_bufspace(struct sctp_tcb *, struct sctp_association *,
struct sctp_tmit_chunk *);
#else
#define sctp_free_bufspace(stcb, asoc, tp1, chk_cnt) \
do { \
if (tp1->data != NULL) { \
atomic_add_16(&((asoc)->chunks_on_out_queue), -chk_cnt); \
if ((asoc)->total_output_queue_size >= tp1->book_size) { \
atomic_add_int(&((asoc)->total_output_queue_size), -tp1->book_size); \
} else { \
(asoc)->total_output_queue_size = 0; \
} \
if (stcb->sctp_socket && ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || \
(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL))) { \
if (stcb->sctp_socket->so_snd.sb_cc >= tp1->book_size) { \
atomic_add_int(&((stcb)->sctp_socket->so_snd.sb_cc), -tp1->book_size); \
} else { \
stcb->sctp_socket->so_snd.sb_cc = 0; \
} \
} \
} \
} while (0)
#endif
#define sctp_free_spbufspace(stcb, asoc, sp) \
do { \
if (sp->data != NULL) { \
atomic_add_16(&(asoc)->chunks_on_out_queue, -1); \
if ((asoc)->total_output_queue_size >= sp->length) { \
atomic_add_int(&(asoc)->total_output_queue_size,sp->length); \
} else { \
(asoc)->total_output_queue_size = 0; \
} \
if (stcb->sctp_socket && ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || \
(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL))) { \
if (stcb->sctp_socket->so_snd.sb_cc >= sp->length) { \
atomic_add_int(&stcb->sctp_socket->so_snd.sb_cc,sp->length); \
} else { \
stcb->sctp_socket->so_snd.sb_cc = 0; \
} \
} \
} \
} while (0)
#define sctp_snd_sb_alloc(stcb, sz) \
do { \
atomic_add_int(&stcb->asoc.total_output_queue_size,sz); \
if ((stcb->sctp_socket != NULL) && \
((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || \
(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL))) { \
atomic_add_int(&stcb->sctp_socket->so_snd.sb_cc,sz); \
} \
} while (0)
int
sctp_soreceive(struct socket *so, struct sockaddr **psa,
struct uio *uio,
struct mbuf **mp0,
struct mbuf **controlp,
int *flagsp);
#ifdef SCTP_STAT_LOGGING
void
sctp_misc_ints(uint8_t from, uint32_t a, uint32_t b, uint32_t c, uint32_t d);
void
sctp_wakeup_log(struct sctp_tcb *stcb,
uint32_t cumtsn,
uint32_t wake_cnt, int from);
void sctp_log_strm_del_alt(uint32_t, uint16_t, int);
void sctp_log_nagle_event(struct sctp_tcb *stcb, int action);
void
sctp_log_mb(struct mbuf *m, int from);
void
sctp_sblog(struct sockbuf *sb,
struct sctp_tcb *stcb, int from, int incr);
void
sctp_log_strm_del(struct sctp_queued_to_read *control,
struct sctp_queued_to_read *poschk,
int from);
void sctp_log_cwnd(struct sctp_tcb *stcb, struct sctp_nets *, int, uint8_t);
void rto_logging(struct sctp_nets *net, int from);
void sctp_log_closing(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int16_t loc);
void sctp_log_lock(struct sctp_inpcb *inp, struct sctp_tcb *stcb, uint8_t from);
void sctp_log_maxburst(struct sctp_tcb *stcb, struct sctp_nets *, int, int, uint8_t);
void sctp_log_block(uint8_t, struct socket *, struct sctp_association *, int);
void sctp_log_rwnd(uint8_t, uint32_t, uint32_t, uint32_t);
void sctp_log_mbcnt(uint8_t, uint32_t, uint32_t, uint32_t, uint32_t);
void sctp_log_rwnd_set(uint8_t, uint32_t, uint32_t, uint32_t, uint32_t);
int sctp_fill_stat_log(struct mbuf *);
void sctp_log_fr(uint32_t, uint32_t, uint32_t, int);
void sctp_log_sack(uint32_t, uint32_t, uint32_t, uint16_t, uint16_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(uint8_t, uint8_t);
#endif
#endif /* _KERNEL */
#endif

View File

@ -66,6 +66,7 @@
#include "opt_ipsec.h"
#include "opt_ipstealth.h"
#include "opt_carp.h"
#include "opt_sctp.h"
#include <sys/param.h>
#include <sys/socket.h>
@ -127,6 +128,14 @@
#include <netinet/ip_carp.h>
#endif
#ifdef SCTP
#include <netinet/in_pcb.h>
#include <netinet/sctp_pcb.h>
#include <netinet/sctp.h>
#include <netinet/sctp_var.h>
#include <netinet6/sctp6_var.h>
#endif /* SCTP */
#ifdef FAST_IPSEC
#include <netipsec/ipsec6.h>
#define IPSEC
@ -184,6 +193,42 @@ struct ip6protosw inet6sw[] = {
.pr_drain = tcp_drain,
.pr_usrreqs = &tcp6_usrreqs,
},
#ifdef SCTP
{
.pr_type = SOCK_DGRAM,
.pr_domain = &inet6domain,
.pr_protocol = IPPROTO_SCTP,
.pr_flags = PR_WANTRCVD,
.pr_input = sctp6_input,
.pr_ctlinput = sctp6_ctlinput,
.pr_ctloutput = sctp_ctloutput,
.pr_drain = sctp_drain,
.pr_usrreqs = &sctp6_usrreqs
},
{
.pr_type = SOCK_SEQPACKET,
.pr_domain = &inet6domain,
.pr_protocol = IPPROTO_SCTP,
.pr_flags = PR_WANTRCVD,
.pr_input = sctp6_input,
.pr_ctlinput = sctp6_ctlinput,
.pr_ctloutput = sctp_ctloutput,
.pr_drain = sctp_drain,
.pr_usrreqs = &sctp6_usrreqs
},
{
.pr_type = SOCK_STREAM,
.pr_domain = &inet6domain,
.pr_protocol = IPPROTO_SCTP,
.pr_flags = PR_WANTRCVD,
.pr_input = sctp6_input,
.pr_ctlinput = sctp6_ctlinput,
.pr_ctloutput = sctp_ctloutput,
.pr_drain = sctp_drain,
.pr_usrreqs = &sctp6_usrreqs
},
#endif /* SCTP */
{
.pr_type = SOCK_RAW,
.pr_domain = &inet6domain,
@ -416,6 +461,9 @@ SYSCTL_NODE(_net_inet6, IPPROTO_IPV6, ip6, CTLFLAG_RW, 0, "IP6");
SYSCTL_NODE(_net_inet6, IPPROTO_ICMPV6, icmp6, CTLFLAG_RW, 0, "ICMP6");
SYSCTL_NODE(_net_inet6, IPPROTO_UDP, udp6, CTLFLAG_RW, 0, "UDP6");
SYSCTL_NODE(_net_inet6, IPPROTO_TCP, tcp6, CTLFLAG_RW, 0, "TCP6");
#ifdef SCTP
SYSCTL_NODE(_net_inet6, IPPROTO_SCTP, sctp6, CTLFLAG_RW, 0, "SCTP6");
#endif
#ifdef IPSEC
SYSCTL_NODE(_net_inet6, IPPROTO_ESP, ipsec6, CTLFLAG_RW, 0, "IPSEC6");
#endif /* IPSEC */

1370
sys/netinet6/sctp6_usrreq.c Normal file

File diff suppressed because it is too large Load Diff

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

@ -0,0 +1,52 @@
/*-
* Copyright (c) 2001-2006, 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:
*
* a) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* b) 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.
*
* c) Neither the name of Cisco Systems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
*/
/* $KAME: sctp6_var.h,v 1.7 2004/08/17 04:06:22 itojun Exp $ */
__FBSDID("$FreeBSD$");
#ifndef _NETINET6_SCTP6_VAR_H_
#define _NETINET6_SCTP6_VAR_H_
#if defined(_KERNEL)
SYSCTL_DECL(_net_inet6_sctp6);
extern struct pr_usrreqs sctp6_usrreqs;
int sctp6_ctloutput __P((struct socket *, struct sockopt *));
int sctp6_input __P((struct mbuf **, int *, int));
int sctp6_output
__P((struct sctp_inpcb *, struct mbuf *, struct sockaddr *,
struct mbuf *, struct proc *));
void sctp6_ctlinput __P((int, struct sockaddr *, void *));
#endif /* _KERNEL */
#endif

View File

@ -169,6 +169,7 @@ struct mbuf {
#define M_PROTO3 0x0040 /* protocol-specific */
#define M_PROTO4 0x0080 /* protocol-specific */
#define M_PROTO5 0x0100 /* protocol-specific */
#define M_NOTIFICATION 0x2000 /* SCTP notification */
#define M_SKIP_FIREWALL 0x4000 /* skip firewall processing */
#define M_FREELIST 0x8000 /* mbuf is on the free list */

View File

@ -394,6 +394,7 @@ struct msghdr {
#define MSG_TRUNC 0x10 /* data discarded before delivery */
#define MSG_CTRUNC 0x20 /* control data lost before delivery */
#define MSG_WAITALL 0x40 /* wait for full request or error */
#define MSG_NOTIFICATION 0x2000 /* SCTP notification */
#if __BSD_VISIBLE
#define MSG_DONTWAIT 0x80 /* this message should be nonblocking */
#define MSG_EOF 0x100 /* data completes connection */

View File

@ -390,4 +390,8 @@
#define SYS_thr_set_name 464
#define SYS_aio_fsync 465
#define SYS_rtprio_thread 466
#define SYS_MAXSYSCALL 471
#define SYS_sctp_peeloff 471
#define SYS_sctp_generic_sendmsg 472
#define SYS_sctp_generic_sendmsg_iov 473
#define SYS_sctp_generic_recvmsg 474
#define SYS_MAXSYSCALL 475

View File

@ -331,4 +331,8 @@ MIASM = \
abort2.o \
thr_set_name.o \
aio_fsync.o \
rtprio_thread.o
rtprio_thread.o \
sctp_peeloff.o \
sctp_generic_sendmsg.o \
sctp_generic_sendmsg_iov.o \
sctp_generic_recvmsg.o

View File

@ -1451,6 +1451,37 @@ struct rtprio_thread_args {
char lwpid_l_[PADL_(lwpid_t)]; lwpid_t lwpid; char lwpid_r_[PADR_(lwpid_t)];
char rtp_l_[PADL_(struct rtprio *)]; struct rtprio * rtp; char rtp_r_[PADR_(struct rtprio *)];
};
struct sctp_peeloff_args {
char sd_l_[PADL_(int)]; int sd; char sd_r_[PADR_(int)];
char name_l_[PADL_(uint32_t)]; uint32_t name; char name_r_[PADR_(uint32_t)];
};
struct sctp_generic_sendmsg_args {
char sd_l_[PADL_(int)]; int sd; char sd_r_[PADR_(int)];
char msg_l_[PADL_(caddr_t)]; caddr_t msg; char msg_r_[PADR_(caddr_t)];
char mlen_l_[PADL_(int)]; int mlen; char mlen_r_[PADR_(int)];
char to_l_[PADL_(caddr_t)]; caddr_t to; char to_r_[PADR_(caddr_t)];
char tolen_l_[PADL_(__socklen_t)]; __socklen_t tolen; char tolen_r_[PADR_(__socklen_t)];
char sinfo_l_[PADL_(struct sctp_sndrcvinfo *)]; struct sctp_sndrcvinfo * sinfo; char sinfo_r_[PADR_(struct sctp_sndrcvinfo *)];
char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
};
struct sctp_generic_sendmsg_iov_args {
char sd_l_[PADL_(int)]; int sd; char sd_r_[PADR_(int)];
char iov_l_[PADL_(struct iovec *)]; struct iovec * iov; char iov_r_[PADR_(struct iovec *)];
char iovlen_l_[PADL_(int)]; int iovlen; char iovlen_r_[PADR_(int)];
char to_l_[PADL_(caddr_t)]; caddr_t to; char to_r_[PADR_(caddr_t)];
char tolen_l_[PADL_(__socklen_t)]; __socklen_t tolen; char tolen_r_[PADR_(__socklen_t)];
char sinfo_l_[PADL_(struct sctp_sndrcvinfo *)]; struct sctp_sndrcvinfo * sinfo; char sinfo_r_[PADR_(struct sctp_sndrcvinfo *)];
char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
};
struct sctp_generic_recvmsg_args {
char sd_l_[PADL_(int)]; int sd; char sd_r_[PADR_(int)];
char iov_l_[PADL_(struct iovec *)]; struct iovec * iov; char iov_r_[PADR_(struct iovec *)];
char iovlen_l_[PADL_(int)]; int iovlen; char iovlen_r_[PADR_(int)];
char from_l_[PADL_(struct sockaddr *)]; struct sockaddr * from; char from_r_[PADR_(struct sockaddr *)];
char fromlenaddr_l_[PADL_(__socklen_t *)]; __socklen_t * fromlenaddr; char fromlenaddr_r_[PADR_(__socklen_t *)];
char sinfo_l_[PADL_(struct sctp_sndrcvinfo *)]; struct sctp_sndrcvinfo * sinfo; char sinfo_r_[PADR_(struct sctp_sndrcvinfo *)];
char msg_flags_l_[PADL_(int *)]; int * msg_flags; char msg_flags_r_[PADR_(int *)];
};
int nosys(struct thread *, struct nosys_args *);
void sys_exit(struct thread *, struct sys_exit_args *);
int fork(struct thread *, struct fork_args *);
@ -1779,6 +1810,10 @@ int abort2(struct thread *, struct abort2_args *);
int thr_set_name(struct thread *, struct thr_set_name_args *);
int aio_fsync(struct thread *, struct aio_fsync_args *);
int rtprio_thread(struct thread *, struct rtprio_thread_args *);
int sctp_peeloff(struct thread *, struct sctp_peeloff_args *);
int sctp_generic_sendmsg(struct thread *, struct sctp_generic_sendmsg_args *);
int sctp_generic_sendmsg_iov(struct thread *, struct sctp_generic_sendmsg_iov_args *);
int sctp_generic_recvmsg(struct thread *, struct sctp_generic_recvmsg_args *);
#ifdef COMPAT_43
@ -2326,6 +2361,10 @@ int freebsd4_sigreturn(struct thread *, struct freebsd4_sigreturn_args *);
#define SYS_AUE_thr_set_name AUE_NULL
#define SYS_AUE_aio_fsync AUE_NULL
#define SYS_AUE_rtprio_thread AUE_RTPRIO
#define SYS_AUE_sctp_peeloff AUE_NULL
#define SYS_AUE_sctp_generic_sendmsg AUE_NULL
#define SYS_AUE_sctp_generic_sendmsg_iov AUE_NULL
#define SYS_AUE_sctp_generic_recvmsg AUE_NULL
#undef PAD_
#undef PADL_