Squashed 'third_party/lksctp-tools/' content from commit 200eca7f1

Change-Id: I8f7575513f114b205178cac5c6b3706f3d725cb5
git-subtree-dir: third_party/lksctp-tools
git-subtree-split: 200eca7f1419b1ae53958b51e8551f7e7f6cd467
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 0000000..ba219a6
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,3 @@
+We don't use pull requests anymore.  Please follow Linux netdev community patch
+posting standard instead. Post your patches to linux-sctp@vger.kernel.org and
+they will be very welcomed. Thanks!
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e92e8f8
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,21 @@
+aclocal.m4
+config.guess
+config.log
+config.status
+config.sub
+configure
+Makefile.in
+Makefile
+config.h
+config.h.in
+libsctp.pc
+libtool
+lksctp-tools.spec
+stamp-h1
+*.deps/
+*.libs/
+autom4te.cache/
+*.la
+*.lo
+*.o
+tags
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..f1b2b49
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,106 @@
+language: c
+addons:
+  apt:
+    packages:
+      - libelf-dev
+script:
+  - ./.travis/linux-build.sh
+env:
+  global:
+    - KERNEL=4.17
+  matrix:
+    - KERNEL=""
+compiler:
+  - gcc
+  - clang
+
+matrix:
+  include:
+    - os: linux
+      addons:
+        apt:
+          sources:
+            - ubuntu-toolchain-r-test
+          packages:
+            - libelf-dev
+            - g++-4.9
+      env:
+        - MATRIX_EVAL="CC=gcc-4.9 && CXX=g++-4.9"
+
+    - os: linux
+      addons:
+        apt:
+          sources:
+            - ubuntu-toolchain-r-test
+          packages:
+            - libelf-dev
+            - g++-5
+      env:
+        - MATRIX_EVAL="CC=gcc-5 && CXX=g++-5"
+
+    - os: linux
+      addons:
+        apt:
+          sources:
+            - ubuntu-toolchain-r-test
+          packages:
+            - libelf-dev
+            - g++-6
+      env:
+        - MATRIX_EVAL="CC=gcc-6 && CXX=g++-6"
+
+    - os: linux
+      addons:
+        apt:
+          sources:
+            - ubuntu-toolchain-r-test
+          packages:
+            - libelf-dev
+            - g++-7
+      env:
+        - MATRIX_EVAL="CC=gcc-7 && CXX=g++-7"
+
+    # works on Trusty
+    - os: linux
+      addons:
+        apt:
+          sources:
+            - llvm-toolchain-trusty-3.9
+          packages:
+            - libelf-dev
+            - clang-3.9
+      env:
+        - MATRIX_EVAL="CC=clang-3.9 && CXX=clang++-3.9"
+
+    # works on Trusty
+    - os: linux
+      addons:
+        apt:
+          sources:
+            - llvm-toolchain-trusty-4.0
+          packages:
+            - libelf-dev
+            - clang-4.0
+      env:
+        - MATRIX_EVAL="CC=clang-4.0 && CXX=clang++-4.0"
+
+    # works on Trusty
+    - os: linux
+      addons:
+        apt:
+          sources:
+            - llvm-toolchain-trusty-5.0
+          packages:
+            - libelf-dev
+            - clang-5.0
+      env:
+        - MATRIX_EVAL="CC=clang-5.0 && CXX=clang++-5.0"
+before_install:
+  - eval "${MATRIX_EVAL}"
+  - $CC --version
+
+notifications:
+  email:
+    on_success: change
+    on_failure: change
+    recipients: linux-sctp@vger.kernel.org
diff --git a/.travis/linux-build.sh b/.travis/linux-build.sh
new file mode 100755
index 0000000..746f172
--- /dev/null
+++ b/.travis/linux-build.sh
@@ -0,0 +1,86 @@
+#!/bin/bash -ex
+
+VERS="master v4.17 v4.16 v4.13 v4.12 v4.11 v4.10"
+
+nproc=$(/usr/bin/getconf _NPROCESSORS_ONLN)
+basedir=$(pwd)
+
+function cleanup()
+{
+	cd "$basedir"
+	[ ! -d linux ] || rm -rf linux
+	[ ! -d "linux-$KERNEL" ] || rm -rf "linux-$KERNEL"
+	make distclean || :
+}
+
+function clone_kernel()
+{
+	git clone https://github.com/torvalds/linux
+}
+
+function download_kernel()
+{
+	VER="$1"
+	URL="https://www.kernel.org/pub/linux/kernel/v4.x/linux-$VER.tar.xz"
+	wget "$URL"
+	tar xf "linux-$VER.tar.xz"
+}
+
+function __prep_kernel()
+{
+	make mrproper
+	make allmodconfig
+	make -j $nproc modules_prepare
+	make -j $nproc headers_install
+	KERNEL_HEADERS=$(pwd)/usr/include
+	popd
+}
+
+function git_prep_kernel()
+{
+	VER="$1"
+
+	pushd "linux"
+	git checkout "$VER"
+	__prep_kernel
+}
+
+function download_prep_kernel()
+{
+	VER="$1"
+
+	pushd "linux-$VER"
+	__prep_kernel
+}
+
+function build_lksctp()
+{
+	make distclean || :
+	./bootstrap
+
+	#CFLAGS="-Werror"
+	if [ -n "$KERNEL_HEADERS" ]; then
+		CFLAGS="$CFLAGS -I$KERNEL_HEADERS"
+	fi
+	export CFLAGS
+	./configure
+
+	make -j $nproc
+
+	#make -j $nproc distcheck
+
+}
+
+trap cleanup EXIT
+if [ -z "$KERNEL" ]; then
+	clone_kernel
+
+	for ver in $VERS; do
+		git_prep_kernel "$ver"
+		build_lksctp
+	done
+else
+	download_kernel "$KERNEL"
+	download_prep_kernel "$KERNEL"
+	build_lksctp
+fi
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..01c25c0
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,36 @@
+The initial developer and founder of the project:
+-------------------------------------------------
+La Monte H.P. Yarroll	<piggy@acm.org>
+
+Current Maintainer:
+-------------------
+Vlad Yasevich		<vyasevic@redhat.com>
+Daniel Borkmann		<dborkman@redhat.com>
+
+Previous Maintainers:
+--------------------
+Sridhar Samudrala	<sri@us.ibm.com>
+Jon Grimm		<jgrimm@us.ibm.com>
+
+Contributors:
+-------------
+Karl Knutson		<karl@athena.chicago.il.us>
+Xingang Guo		<xingang.guo@intel.com>
+Daisy Chang		<daisyc@us.ibm.com>
+Inaky Perez-Gonzalez	<inaky.perez-gonzalez@intel.com>
+Hui Huang		<hui.huang@nokia.com>
+Dajiang Zhang		<dajiang.ahang@nolia.com>
+Ryan Layer		<rmlayer@us.ibm.com>
+Francois-Xavier Kowalski <francois-xavier.kowalski@hp.com>
+Frank Filz		<ffilz@us.ibm.com>
+Ivan Skytte Jorgensen	<isj-sctp@i1.dk>
+Neil Horman		<nhorman@tuxdriver.com>
+Michael Biebl		<biebl@debian.org>
+Wei Yongjun		<yjwei@cn.fujitsu.com>
+Sam Miller		<samjmill@us.ibm.com>
+Andrei Pelinescu-Onciul	<andrei@iptel.org>
+Michele Baldessari	<michele@acksyn.org>
+Michael Tuexen		<tuexen@fh-muenster.de>
+Fan Du			<fan.du@windriver.com>
+
+Are you missing? drop us a line!
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..dc63aac
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,340 @@
+
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                          675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	Appendix: How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) 19yy  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) 19yy name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/COPYING.lib b/COPYING.lib
new file mode 100644
index 0000000..7d31de0
--- /dev/null
+++ b/COPYING.lib
@@ -0,0 +1,456 @@
+                 GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+                  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                            NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..3f723aa
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,917 @@
+Version 1.0.18 of the Developers' Release of the SCTP
+Linux Kernel Implementation is available from
+
+        http://www.kernel.org
+
+lksctp-1.0.18: Mon Aug 13 16:19 EDT 2016
+T:APP         Various test tools fixes
+T:LIB         Added support for sctp_peeloff_flags function
+T:LIB         Added macro definitions indicating which kernel
+              features were detected during build.
+T:LIB         Initial batch of fixes for coverity scan issues
+T:NA          Initial integration with Travis and Coverity Scan
+T:BUILD       Updated rfc listings so now 'make distcheck' works
+
+lksctp-1.0.17: Mon May  9 16:19 EDT 2016
+T:APP         Various sctp_test fixes
+T:TEST        also expect EACCES when accept on an established socket
+T:LIB         Make use of 'extern "C"'
+T:NA          Make use .git_ignore
+T:NA          Removed sysctl listing from man page
+T:BUILD       Added support for pkg-config
+T:BUILD       Allow not building tests
+
+lksctp-1.0.16: Tue Feb 18 11:01 EDT 2014
+T:APP         Code cleanups
+T:APP         Various sctp_status fixes
+T:TEST        Avoid using file descriptor 0 to get ENOTSOCK
+T:TEST        Various fixes
+T:LIB         Fix build for prefixed architectures
+
+lksctp-1.0.15: Sun May 12 11:01 EDT 2013
+T:BUILD       Allow build with no AM_SILENT_RULES support
+T:APP         Fix sctp_status
+T:APP         Fix quoted command line arguments
+
+lksctp-1.0.14: Wed Apr 05 11:54 EDT 2013
+T:BUILD       Modernize and fix autotool's build system
+T:TEST        Fix threading test
+T:TEST        Zero out flags in sendrecvmsg test
+T:HDR         Sync header with the kernel
+
+lksctp-1.0.13: Wed Jan 23 12:13 EDT 2013
+T:BUILD       Use silent rules
+T:BUILD       Fix build warnings all over the place
+T:APP         Fix memory leak in sctp_xconnect
+T:TEST        Fix deprecated values in test cases
+
+lksctp-1.0.12: Tue Jan 08 10:45 EDT 2013
+T:API         Add needed definitions for DTLS/SCTP.
+T:API         Fix data corruption in sctp_send
+T:API         Implement private SCTP_GET_ASSOC_STATS option to fetch addition
+              association data.
+T:TEST        Add more options to conformace test tool.
+T:APP         Add HEARTBEAT command to sctp_darn
+T:API         Obsolete interefaces have been removed
+T:API         Suport for SCTP_SACK_IMMEDIATELY options
+T:API         Support for non-blocking sctp-connectx
+
+lksctp-2.6.28-1.0.11: Wed Oct 21 16:53:41 EDT 2009
+T:BUILD       fix parallel build warning
+T:BUILD       fix make distcheck for lksctp-tools
+T:BUILD       fix compiler warnings in the libraray, apps and tests
+T:API         Update the sctp.h header to match the kernel.
+
+lksctp-2.6.28-1.0.10: Fri Mar 27 11:15:25 EDT 2009
+T:TEST	      Split the kernel frame test framework from lksctp-tools.  The
+              framework is very sensitive to all kernel changes, not just ones
+	      related to SCTP.  As such, it has been a gating fractor to the
+	      releases of the new tools.
+T:APP	      New tool sctp_status to be used with SCTP conformance tests.
+              http://networktest.sourceforge.net/
+T:APP	      Add -T option to sctp_test
+T:APP	      Fix the -e option to sctp_darn
+T:LIB	      Fix building of static libraries.
+T:LIB         Fix compile warning in addrs.c
+T:APP	      Update the application useage of sctp_connectx
+T:TEST        Update the sctp_connectx() functional tests.
+T:API         Update to the sctp_connectx().  Now takes additional argument.
+T:API         Let sctp_recvmsg() honor passed in MSG_ flags
+K:	      See kernel change log for details.  We'll track only tools
+              changes here from now on.
+
+lksctp-2.6.26-1.0.9: Sun Jul 13 14:51:29 PDT 2008
+T:Patch	      Make frame tests work with 2.6.26 kernel.
+T:Patch       Implement and export SCTP-AUTH API extensions based on
+              sctpsocket-16 draft
+T:NA          Process withsctp.in at build time
+K:Patch       Add documentation for sctp sysctl variable
+K:NA          Mark the tsn as received after all allocations finish
+K:NA          Make sure N * sizeof(union sctp_addr) does not overflow.
+K:NA          Correclty set changeover_active for SFR-CACC
+K:NA          Correctly cleanup procfs entries upon failure.
+K:NA          Fix ECN markings for IPv6
+K:NA          Flush the queue only once during fast retransmit.
+K:NA          Start T3-RTX timer when fast retransmitting lowest TSN
+K:NA          Correctly implement Fast Recovery cwnd manipulations.
+K:NA          Move sctp_v4_dst_saddr out of loop
+K:NA          retran_path update bug fix
+K:NA          Fix NULL dereference of asoc.
+K:NA          Fix use of uninitialized pointer
+K:NA          Add address type check while process paramaters of ASCONF chunk
+K:NA          Do not enable peer IPv6 address support on PF_INET socket
+K:NA          Initialize partial_bytes_acked to 0, when all of the data is acked
+K:NA          IPv4 vs IPv6 addresses mess in sctp_inet[6]addr_event.
+K:NA          Fix compiler warning about const qualifiers
+K:NA          Fix protocol violation when receiving an error lenght INIT-ACK
+K:NA          Add check for hmac_algo parameter in sctp_verify_param()
+K:Patch       New sctp mailing list
+K:NA          Remove an unused parameter from sctp_cmd_hb_timer_update
+K:Patch       "list_for_each()" -> "list_for_each_entry()" where appropriate.
+K:NA          Correct /proc/net/assocs formatting error
+K:Patch       Use snmp_mib_{init,free}().
+K:Patch       Remove useless assignment from __sctp_rcv_lookup_endpoint
+K:NA          fix wrong debug counting of bind_bucket
+K:NA          fix wrong debug counting of datamsg
+K:Patch       Replace socket with sock for SCTP control socket.
+K:Patch       Use inet_ctl_sock_create for control socket creation.
+K:Patch       Remove sctp_add_cmd_sf wrapper bloat
+K:Patch       Remove redundant wrapper functions.
+K:Patch       Replace char msg[] with static const char[]
+K:NA          Fix a race between module load and protosw access
+K:NA          fix misannotated __sctp_rcv_asconf_lookup()
+K:NA          Fix local_addr deletions during list traversals.
+K:Patch       Bring MAX_BURST socket option into ietf API extension compliance
+K:NA          Fix chunk parameter processing bug
+K:Patch       Kill unused static inline sctp_sysctl_jiffies_ms
+K:Patch       extend exported data in /proc/net/sctp/assoc
+K:Patch       Use proc_create to setup de->proc_fops.
+K:Patch       Update AUTH structures to match declarations in draft-16.
+K:NA          Incorrect length was used in SCTP_*_AUTH_CHUNKS socket option
+K:Patch       Clean up naming conventions of sctp protocol/address family
+              registration
+K:NA          Correctly set the length of sctp_assoc_change notification
+K:NA          Pick up an orphaned sctp_sockets_allocated counter.
+K:Patch       Convert sctp_dbg_objcnt to seq files.
+K:Patch       Use snmp_fold_field instead of a homebrew analogue.
+K:NA          Make sure the chunk is off the transmitted list prior to freeing.
+K:NA          Fix kernel panic while received ASCONF chunk with bad serial
+              number
+K:NA          Set ports in every address returned by sctp_getladdrs()
+K:NA          Correctly reap SSNs when processing FORWARD_TSN chunk
+K:NA          Fix kernel panic while received AUTH chunk with BAD shared key
+              identifier
+K:NA          Fix kernel panic while received AUTH chunk while enabled auth
+K:Patch       Kill silly inlines in ulpqueue.c
+K:NA          Do not increase rwnd when reading partial notification.
+K:Patch       Stop claiming that this is a "reference implementation"
+K:NA          Fix miss of report unrecognized HMAC Algorithm parameter
+K:NA          Correctly initialize error when parameter validation failed.
+K:Patch       Follow Add-IP security consideratiosn wrt INIT/INIT-ACK
+K:Patch       Implement ADD-IP special case processing for ABORT chunk
+K:Patch       Change use_as_src into a full address state
+K:Patch       Update ASCONF processing to conform to spec.
+K:Patch       ADD-IP updates the states where ASCONFs can be sent
+K:Patch       Update association lookup to look at ASCONF chunks as well
+K:Patch       Add the handling of "Set Primary IP Address" parameter to INIT
+K:Patch       Handle the wildcard ADD-IP Address parameter
+K:Patch       Discard unauthenticated ASCONF and ASCONF ACK chunks
+K:Patch       Use crc32c library for checksum calculations.
+K:Patch       Use ipv4_is_<type>
+
+lksctp-2.6.24-1.0.8: Fri Feb  01 14:55:00 EST 2008
+K:NA          Add back the code that accounted for FORWARD_TSN parameter in
+              INIT.
+K:NA          Correctly handle AUTH parameters in unexpected INIT
+K:NA          Fix the name of the authentication event.
+K:NA          Spelling fixes
+K:NA          Flush fragment queue when exiting partial delivery.
+K:NA          Fix the bind_addr info during migration.
+K:NA          Add bind hash locking to the migrate code
+K:NA          Fix build issues with SCTP AUTH.
+K:NA          Fix chunk acceptance when no authenticated chunks were listed.
+K:NA          Fix the supported extensions paramter
+K:NA          Fix SCTP-AUTH to correctly add HMACS paramter.
+K:NA          Fix the number of HB transmissions.
+K:NA          Add missing "space"
+K:NA          Always flush the queue when uncorcking.
+K:NA          Clean-up some defines for regressions tests.
+K:NA          Fix PR-SCTP to deliver all the accumulated ordered chunks
+K:NA          Make sctp_verify_param return multiple indications.
+K:NA          Convert custom hash lists to use hlist.
+K:NA          Use hashed lookup when looking for an association.
+K:NA          Fix a potential race between timers and receive path.
+K:NA          Allow ADD_IP to work with AUTH for backward compatibility.
+K:NA          Correctly disable ADD-IP when AUTH is not supported.
+K:NA          Update RCU handling during the ADD-IP case
+K:NA          Fix difference cases of retransmit.
+K:NA          Fix to process bundled ASCONF chunk correctly
+K:NA          Fix bad formatted comment in outqueue.c
+Patch         Use the {DEFINE|REF}_PROTO_INUSE infrastructure
+K:NA          SCTP endianness annotations regression
+K:NA          net/sctp/auth.c: make 3 functions static
+K:NA          #if 0 sctp_update_copy_cksum()
+K:NA          Consolidate sctp_ulpq_renege_xxx functions
+Patch         port randomization
+Patch         Tie ADD-IP and AUTH functionality as required by spec.
+Patch         API updates to suport SCTP-AUTH extensions.
+Patch         Implement the receive and verification of AUTH chunk
+Patch         Enable the sending of the AUTH chunk.
+Patch         Implement SCTP-AUTH parameter processing
+Patch         Implement SCTP-AUTH initializations.
+Patch         Implement SCTP-AUTH internals
+Patch         protocol definitions for SCTP-AUTH implementation
+K:NA          Move sysctl_sctp_[rw]mem definitions to protocol.
+Patch         Implement the Supported Extensions Parameter
+K:NA          net/sctp/socket.c: make 3 variables static
+K:NA          Make sctp_addto_param() static.
+Patch         Rewrite of sctp buffer management code
+K:NA          Add paramters validity check for ASCONF chunk
+K:NA          Discard OOTB packetes with bundled INIT early.
+K:NA          Clean up OOTB handling and fix infinite loop processing
+K:NA          Explicitely discard OOTB chunks
+K:NA          Send ABORT chunk with correct tag in response to INIT ACK
+K:NA          Validate buffer room when processing sequential chunks
+K:NA          Convert bind_addr_list locking to RCU
+K:NA          Add RCU synchronization around sctp_localaddr_list
+K:NA          Fix to handle invalid parameter length correctly
+K:NA          Abort on COOKIE-ECHO if backlog is exceeded.
+K:NA          Correctly disable listening when backlog is 0.
+K:NA          Do not retransmit chunks that are newer then rtt.
+K:NA          Uncomfirmed transports can't become Inactive
+K:NA          Pick the correct port when binding to 0.
+K:NA          Use net_ratelimit to suppress error messages print too fast
+K:NA          Fix to encode PROTOCOL VIOLATION error cause correctly
+K:NA          Fix sctp_addto_chunk() to add pad with correct length
+K:NA          Assign stream sequence numbers to the entire message
+K:NA          properly clean up fragment and ordering queues during FWD-TSN.
+K:NA	      remove useless code in function sctp_init_cause
+K:NA	      drop SACK if ctsn is not less than the next tsn of assoc
+K:NA	      IPv4 mapped addr not returned in SCTPv6 accept()
+K:NA          Fix whitespace errors.
+
+lksctp-2.6.22-1.0.7: Thu Jul  12 12:24:14 EDT 2007
+K:NA	      Don't disable PMTU discovery when mtu is small
+K:NA          Flag a pmtu change request
+K:NA          Update pmtu handling to be similar to tcp
+K:NA          Fix leak in sctp_getsockopt_local_addrs when copy_to_user fails
+K:NA          Allow unspecified port in sctp_bindx()
+K:NA          Correctly set daddr for IPv6 sockets during peeloff
+K:NA          Do not include ABORT chunk header in the notification.
+K:NA          Correctly copy addresses in sctp_copy_laddrs.
+K:NA          Prevent OOPS if hmac modules didn't load
+K:NA	      Set assoc_id correctly during INIT collision.
+K:NA          Re-order SCTP initializations to avoid race with sctp_rcv()
+K:NA          Fix the SO_REUSEADDR handling to be similar to TCP.
+K:NA          Verify all destination ports in sctp_connectx.
+K:NA          Fix sctp_getsockopt_local_addrs_old() to use local storage.
+K:NA          Implement SCTP_MAX_BURST socket option.
+K:NA          Implement sac_info field in SCTP_ASSOC_CHANGE notification.
+K:NA          Honor flags when setting peer address parameters
+K:NA          Implement SCTP_ADDR_CONFIRMED state for ADDR_CHNAGE event.
+K:NA          Implement SCTP_PARTIAL_DELIVERY_POINT option.
+K:NA          Implement SCTP_FRAGMENT_INTERLEAVE socket option
+K:NA          Do not interleave non-fragments when in partial delivery
+K:NA          Unmap v4mapped addresses during SCTP_BINDX_REM_ADDR operation.
+K:NA          Fix assertion (!atomic_read(&sk->sk_rmem_alloc)) failed message
+K:NA          Correctly reset ssthresh when restarting association
+K:NA          Reset some transport and association variables on restart
+K:NA          Increment error counters on user requested HBs.
+K:NA          Cleanup stale data during association restart
+K:NA          Strike the transport before updating rto.
+K:NA          Fix connection hang/slowdown with PR-SCTP.
+K:NA          Force update of the rto when processing HB-ACK
+K:NA          Fix SACK sequence during shutdown.
+K:NA          Correctly handle unexpected INIT-ACK chunk.
+K:NA          Verify some mandatory parameters.
+K:NA          Set correct error cause value for missing parameters
+K:NA          Fix err_hdr assignment in sctp_init_cause.
+T:NA          Add support for sctp_getaddrlen() API.
+K,T:NA        Fix typo adaption -> adaptation as per the latest API draft.
+K:NA          Don't export include/linux/sctp.h to userspace.
+K,T:NA        Add support for SCTP_CONTEXT socket option.
+K:NA          Enable auto loading of SCTP when creating an ipv6 SCTP socket.
+K:NA          Handle address add/delete events in a more efficient way.
+K:NA          SCTP endianness annotations.
+K:NA          Cleanup of the sctp state table code.
+K:NA          Remove temporary associations from backlog and hash.
+K:NA          Correctly set IP id for SCTP traffic.
+K:NA          Always linearize packet on input.
+K:NA          Fix the RX queue size shown in /proc/net/sctp/assocs output.
+K:NA          Fix receive buffer accounting.
+K:NA          Do not timestamp every SCTP packet.
+K:NA          Use correct mask when disabling PMTUD.
+K:NA          Include sk_buff overhead while updating the peer's receive window.
+K:NA          Enable Nagle algorithm by default.
+K:NA          Remove multiple levels of msecs to jiffies conversions.
+K:NA          Use the flags value that is passed as an arg to sctp_accept.
+K:NA          Fix IPv6 address flag setting when doing peel-off/accept.
+K:NA          Cleanup nomem handling in the state functions.
+K:NA          Extend /proc/net/sctp/snmp to provide more statistics.
+K:NA          Convert SCTP to use the new HMAC template and hash interface.
+K:NA          Fix sctp_primitive_ABORT() call in sctp_close().
+K:NA          Fix sctp_make_abort_user() to avoid use of buggy 
+              get_user_iov_size().
+K:Bug 1502698 ADDIP: Don't use an address as source until it is ASCONF-ACKed.
+K:NA          Set chunk->data_accepted only if we are going to accept it.
+K:NA          Verify all the paths to a peer via heartbeat before using them.
+K:NA          Unhash the endpoint in sctp_endpoint_free().
+K:NA          Check for NULL input to sctp_bucket_destroy().
+K:NA          Fix persistent slowdown in sctp when a gap ack consumes rx buffer.
+K:NA          Send only 1 window update SACK per message.
+K:NA          Don't do CRC32C checksum over loopback.
+K:NA          Reset rtt_in_progress for the chunk when processing its sack.
+K:NA          Reject sctp packets with broadcast addresses.
+K:NA          Limit association max_retrans setting in ASSOCINFO setsockopt.
+T:NA          updates to linux 2.6.17
+K:NA          Allow linger to abort 1-N style sockets.
+K:NA          Validate the parameter length in HB-ACK chunk.
+K:NA          A better solution to fix the race between sctp_peeloff() and
+              sctp_rcv().
+K:Bug 1439226 Set sk_err so that poll wakes up after a non-blocking connect
+              failure.
+K:NA          Fix state table entries for chunks received in CLOSED state.
+K:NA          Fix panic's when receiving fragmented SCTP control chunks.
+K:NA          Prevent possible infinite recursion with multiple bundled DATA.
+K:NA          Allow spillover of receive buffer to avoid deadlock.
+T:NA          Fix the type of 'len' argument in sctp_recvmsg() man page.
+
+lksctp-2.6.16-1.0.6: Fri Feb  3 10:54:20 PST 2006
+K:NA          Fix 'fast retransmit' to send a TSN only once.       
+K:NA          Heartbeats exceed maximum retransmission limit.
+K:NA          Correct the number of INIT retransmissions.
+K:NA          Fix sctp_rcv_ootb() to handle the last chunk of a packet
+              correctly.
+K:NA          Fix couple of races between sctp_peeloff() and sctp_rcv().
+K:NA          Fix machine check/connection hang on IA64.
+K:NA          Fix bad sysctl formatting of SCTP timeout values on 64-bit m/cs.
+K:NA          Fix sctp_assoc_seq_show() panics on big-endian systems.
+K:NA          sctp doesn't show all associations/endpoints in /proc.
+K:NA          Fix sctp_cookie alignment in the packet.
+K:NA          Fix potential race condition between sctp_close() and sctp_rcv().
+K,T:NA        Add support for SCTP_DELAYED_ACK_TIME socket option.
+K,T:NA        Update SCTP_PEER_ADDR_PARAMS socket option to the latest api.
+              draft11.
+
+lksctp-2.6.15-1.0.5: Tue Jan  3 15:49:27 PST 2006
+K:NA           Fix SCTP to not return erroneous POLLOUT events.
+K:NA           Fix getsockname for sctp when an ipv6 socket accepts a
+               connection from an ipv4 socket.
+K:NA           Return socket errors only if the receive queue is empty.
+K,T:NA         Include ulpevents in socket receive buffer accounting.
+K:Bug 1350514  Fix ia64 NaT consumption fault with sctp_sideeffect commands.
+K:NA           Remove timeouts[] array from sctp_endpoint.
+K:Bug 1350521  Fix potential NULL pointer dereference in sctp_v4_get_saddr.
+K:NA           Do not allow unprivileged programs initiating new assocs on
+               privileged ports.
+K:NA           Allow SCTP_MAXSEG to revert to default frag point with a '0'
+               value.    
+K:NA           Fix SCTP_SETADAPTION sockopt to use the correct structure.
+K,T:NA         Rename SCTP specific control message flags to use SCTP_ prefix
+               rather than MSG_ prefix.
+
+lksctp-2.6.14-1.0.4: Fri Oct 28 10:56:04 PDT 2005
+T:NA           Add sctp_send() API support, testcases and manpage.
+T:NA           Add preprocessor constants for PR-SCTP, ADDIP & CANSET_PRIMARY
+K,T:NA         Fix SCTP socket options to work with 32-bit apps on 64-bit
+               kernels.
+K,T:NA         Fix sctp_get{pl}addrs() API to work with 32-bit apps on 64-bit
+               kernels.
+T:NA           Ignore MSG_CMSG_COMPAT flag leaked to 32-bit userspace with
+               64-bit kernels <= 2.6.13.
+K,T:Bug 1122994Fix SCTP_SHUTDOWN notifications for 1-1 style sockets.
+
+lksctp-2.6.13-1.0.3: Thu Sep  1 10:54:22 PDT 2005
+T:NA           Update to 2.6.13
+K:NA           Fix potential NULL pointer dereference while handling an ICMP
+               error.
+K:NA           Make init & delayed sack timeouts configurable by user.
+K:NA           Fix incorrect setting of sk_bound_dev_if when binding/sending
+               to a ipv6 link local address.
+K:NA           Support IP_FREEBIND socket option and ip_nonlocal_bind sysctl.  
+K:NA           Extend the info exported via /proc/net/sctp to support
+               netstat for SCTP.
+K:NA           Support SO_BINDTODEVICE option on incoming packets.
+K:Bug 120804   Fix bug in restart of peeled-off association.
+K,T:NA         sctp_connectx() support.
+T:NA           Increase sk_sndbuf to address send buffer accounting changes.
+T:NA           Update SCTP internet drafts in doc directory
+T:NA           Fix inconsistencies in license stmt in the library files.
+K:Bug 1155119  Add sctp send buffer accounting.
+K:NA           Replace incorrect use of dev_alloc_skb with alloc_skb in
+               sctp_packet_transmit().
+K:NA           Fix bug in sctp_init() error handling code.
+K:NA           Use ipv6_addr_any() rather than ipv6_addr_type() in
+               sctp_v6_is_any().
+T:Bug 1150885  Fix subscript out of range bug in sctp_test.c
+K:Bug 1158878  Implement Sec 2.41 of SCTP Implementers guide.
+K:Bug 1121085  Fix SCTP_ASSOCINFO getsockopt for 1-1 style sockets.
+K:Bug 1155130  Add sctp receive buffer accounting.
+
+lksctp-2.6.10-1.0.2: Thu Dec 30 15:55:27 PST 2004 
+Bug 1074664  Fix sctp_getladdrs() to return valid local addresses on an 
+             endpoint that is bound to INADDR_ANY or inaddr6_any.
+NA           Update to 2.6.10
+Bug 1028605  Fix misc. issues in SCTP_PEER_ADDR_PARAMS set socket option.
+NA           Fix bug in setting ephemeral port while adding a bind address.
+Bug 1090392  Clean up the T3_rtx timer when deleting a transport.
+Patch 1090027Implementation of SCTP IG Section 2.35
+Bug 905731   Validate and respond to invalid chunk/parameter lengths.
+Bug 1085959  Treat ICMP protocol unreachable errors from non-SCTP capable 
+             hosts as ABORTs.
+NA           Code cleanup: remove unused code and make needlessly global code 
+             static
+Bug 1058857  Fix potential null pointer dereference in sctp_err_lookup().
+Bug 982971   Validate fromlen/msg_flags in sctp_recvmsg before dereferencing.
+Bug 860345   Fix invalid msg length to sctp_sendmsg in sctp_xconnect.c
+Bug 1008149  Fix HEARTBEAT_ACKs being sent to wrong dest. ip address in a
+             multihoming scenario after failback. (Jorge)
+NA           Update any transports that are caching a deleted address as
+             a source address.
+NA           Update cwnd/ssthresh as per the sctpimpguide modifications.
+NA           Adaption layer indication support
+NA           Change sctp_assoc_t to a sized type(s32)
+NA           Update to 2.6.9
+NA           Update to 2.6.8-rc2
+NA           Mark chunks as ineligible for fast retransmit after handling
+             retransmit.
+Bug 995918   Fix missing '+' in the computation of sack chunk size in 
+             sctp_sm_pull_sack().
+NA           Use idr_get_new_above() with a starting id of 1 to avoid returning
+             an associd of 0.
+Bug 968562   Fix issues with handling stale cookie error over multihoming
+             associations.
+Bug 991991   Fix data not being delivered in SHUTDOWN_SENT state.
+Bug 979178   Set/Get default SCTP_PEER_ADDR_PARAMS for endpoint when associd
+             and peer address are 0.
+Bug 965359   Fix missing VTAG validation on certain incoming packets.
+Bug 965278   Fix to wakeup blocking connect() after max INIT retries failed.
+Bug 965276   Fix the use of cached non-zero vtag in a INIT that is resent
+             after a stale cookie error.
+Bug 962587   Fix poll() on a 1-1 style socket so that it returns when the
+             association is aborted by peer.
+Bug 962530   Add association states to netinet/sctp.h
+Bug 954271   Fix to not start a new association on a 1-many style sendmsg()
+             with MSG_EOF/MSG_ABORT flag and no data.
+Bug 948012   Fix to not setup a new association if the endpoint is in
+             SHUTDOWN_ACK_SENT state and recognizes that the peer has restarted.
+
+lksctp-2.6.6-1.0.1: Tue May 11 10:08:56 PDT 2004
+Bug 949429   Fix multihomed connection failures on 64bit systems. (Vlad)
+Bug 932698   fix accessing gap ack blocks array with -ve index in 
+             sctp_outq_sack().
+Bug 932692   memset parameter misordering.
+NA           Fix the 3rd arg to sctp_recvmsg() to size_t instead of a ptr.
+NA           Rename SCTP_ADDR_REACHBLE as SCTP_ADDR_AVAILABLE.
+NA           Fix bugs in handling overlapping INIT and peer restart over a
+             multi-homed association.
+NA           SCTP crc table can be static const (Stephen Hemminger)
+NA           Update sctp_test message sizes to match the new frag point of 
+             1452 bytes for AF_INET sockets with 1500 mtu. 
+NA           Propagate error from sctp_proc_init. (Olaf Kirch)
+Patch 751951 Partial Reliability extension support.
+NA           Cleanup sctp_packet and sctp_outq infrastructure.
+NA           Avoid the use of constant SCTP_IP_OVERHEAD to determine the max
+             data size in a SCTP packet.
+NA           Add MSG_EOF to netinet/sctp.h
+NA           Use id to ptr translation service to assign and validate assoc ids.
+NA           Update sctp_ulpevent structure.
+NA           Fix typo in entry name of remove_proc_entry() call.
+NA           Enable association change and data io events in sctp_test.
+NA           Add set_peer_primary interactive option to sctp_darn.
+NA           Use AM_CFLAGS/AM_LDFLAGS in Makefile.am's.
+NA           Avoid the use of hackish CONFIG_IPV6_SCTP__ option.
+NA           Don't do any ppid byte-order conversions as it is opaque to SCTP.
+
+lksctp-2.6.3-1.0.0:
+Bug 905331   Fix incorrect sinit_max_init_timeo behavior. (samudrala)
+NA           Force enable crypto options needed by SCTP (samudrala)
+NA           Update to 2.6.3 (samudrala)
+NA           Add support to get/set primary addr of an assoc to sctp_darn.
+NA           Add __BEGIN_DECLS/__END_DECLS to sctp.h (Ian)
+NA           Fix sctp_getladdrs()/sctp_getpaddrs() API so that the port value
+             in the returned addresses is in network byte order. (samudrala)
+NA           Fix SCTP_INITMSG set socket option so that a parameter with 0
+             value will not change its current value. (samudrala)
+NA           Use __get_free_pages() to allocate ssnmap to avoid kmalloc's
+             128K limit. (samudrala)
+
+lksctp-2.6.2-0.9.0:
+NA           Updated withsctp to capture and replace TCP_NODELAY
+             setsockopt() (samudrala) 
+Patch 890787 RPM packaging bugfixes. (FiX)
+NA           Removed the deprecated ADLER32 checksum support. (samudrala)
+NA           Update to 2.6.2 (samudrala)
+NA           Added manpages for SCTP. (samudrala)
+Patch 887176 autoconf cleanup/ Initial RPM packaging (FiX)
+Patch 878417 Added new 1-1 style API testcases. (damien, samudrala)
+NA           Add sysctl parameters to change socket receive/send buffer sizes
+             and update the default receive buffer to 65535 bytes.
+NA           provide valid tos and oif values for ip_route_output_key.
+NA           Fix bugs in byte order conversion while processing certain
+             address related socket options. (samudrala)
+Patch 869098 ADDIP: T4 RTO timer support. (kevin.gao)
+Patch 865250 withsctp: a tool to replace TCP with SCTP. (La Monte)
+NA           Enable shared libraries in lksctp-tools. (FiX)
+Patch 843544 ADDIP: Process incoming ASCONF_ACK chunks. (kevin.gao) 
+NA           Add a testcase to verify that a SHUTDOWN_COMP notification is
+             received on a SHUT_RW one-to-one style socket. (samudrala)
+NA           Add peeloff test to src/apps. (samudrala)
+NA           Fix overflow in the macros JIFFIES_TO_MSECS/MSECS_TO_JIFFIES
+             when used with large values. (samudrala)
+NA           Fix the duplicate increment of checksum error counter and
+             counting bad packet errors as checksum errors. (samudrala)
+NA           Fix to free assocs in the acceptq of a one-to-one style socket
+             that is closed. (samudrala)
+NA           ADDIP: Add sysctl parameter to enable/disable addip (samudrala) 
+NA           Fix extra semicolon bug in sctp_cacc_skip_3_1() (Ed Rupp)
+Patch 831522 ADDIP: Testcase for delete IP (kevin.gao)
+Patch 822546 ADDIP: Process ASCONF and respond with ASCONF_ACK (kevin.gao)
+
+lksctp-2.6.0-test7-0.7.4:
+NA           Update SCTP tests so that they can be run under LTP (samudrala) 
+NA           Update to 2.6.0-test7 (samudrala)
+Patch 809137 ADDIP: Support to create ASCONF_ACK chunk. (kevin.gao)
+Patch 798988 ADDIP: ASCONF chunk send support. (kevin.gao)
+NA           lksctp-tools tree re-organization (samudrala)
+NA           Fix malloc calls in kernel tests with no error checks. (samudrala)
+NA           Fix bugs in conversions between msecs and jiffies. (samudrala)
+NA           Update to 2.6.0-test6 (samudrala)
+PARISC64     Convert tv_add() from a static inline to macro to fix an
+             obscure assembler issue with parisc64 (samudrala)
+NA           Update to 2.6.0-test5 (samudrala)
+PPC64 port   Use correct types for args passed to sctp_recvmsg() calls.
+PPC64 port   Change the last arg of sctp_opt_info() to match the last arg
+             of getsockopt(). (samudrala)
+PPC64 port   Don't overload the optval of ADDRS_NUM socket options with 
+             different types for input and output. (samudrala)
+
+lksctp-2_6_0-test4-0_7_3:
+NA           draft 07 API:                              (samudrala)
+             - listen() with 0 backlog disables listening.
+             - By default all notifications are turned off even with
+               one-to-many(UDP) style sockets.
+Bug   799468 Fixes for a couple of issues with ssnmap allocation. (samudrala)
+NA           Convert sctp_param2sockaddr() and sockaddr2sctp_addr to address
+             family specific routines. (samudrala) 
+NA           draft 07 API: sctp_bindx() update. (samudrala)
+Patch 791660 ADDIP: SCTP_SET_PEER_PRIMARY socket option support. (kevin.gao)
+NA           Update to 2.6.0-test4 (samudrala)
+NA           draft 07 API: getp/laddrs, freep/laddrs changes (samudrala) 
+NA           draft 07 API: sctp_recvmsg() arg type change. (samudrala) 
+NA           draft 07 API: sctp_peeloff() takes associd, not a ptr (samudrala)
+Patch 784504 ADDIP: Testcase to verify basic ADDIP functionality. (kevin.gao)
+Bug   787008 Bugs in sysctl set/get of sctp rto parameters. (samudrala)
+NA           Update to 2.6.0-test3 (samudrala)
+Bug   783176 Fix to avoid large kmalloc failures on 64bit platforms (samudrala)
+Patch 776732 ADDIP basic infrastructure support. (ardelle.fan)
+Patch 775227 sctp_recvmsg() API support. (rlayer)
+
+lksctp-2_6_0-test1-0_7_2:
+NA           Set output interface for link-local v6 addresses (jgrimm)
+Patch 769844 Add V6 and freebsd support to sctp_test (rlayer)
+Patch 772062 Support IPV6_V6ONLY socket option. (ardelle.fan)
+Patch 757888 Support v4-mapped-v6 addresses (ardelle.fan)	
+NA           Update API names to be compatible with draft07 (samudrala)
+NA           Update to 2.6.0-test1 (samudrala)
+Patch 767208 Shutdown transport selection fix. (rlayer)
+Patch 769792 Fix for panic on recvmsg() with MSG_PEEK & misc stuff (samudrala)
+Patch 765676 Fix nasty race on skb destructor with AF_PACKET sockets (jgrimm)
+	
+lksctp-2_5_72-0_7_1:	
+Patch 759352 Perf: Don't search for gap ack blocks past highest TSN (jgrimm) 
+Patch 758202 Perf: Remove update_pending() from SACK path (jgrimm)
+NA           Update to 2.5.72	
+NA           Fix hlist bug introduced by mainline kernel (jgrimm)	
+NA           sctp_xconnect test tool (rlayer)	
+Patch 729089 ASSOCINFO/RTOINFO sockopts (pems & rlayer)
+NA           Update to 2.5.71  (jgrimm)	
+Bug   754129 Incorrect VTAG in stale cookie error chunk (samudrala)	
+Patch 749587 Change rto sysctl vars to milliseconds (rmlayer)	
+Patch 752321 Add kamikaze test.  (ardelle.fan) 
+Bug   752808 Bug fix for input loop exiting too early on TCP-style (jgrimm)
+	
+lksctp-2_5_70-0_7_0:	
+NA           Fix hostname parameter handling, should ABORT (jgrimm)	
+NA           Fix ft_frame_unkparam testcase (rlayer)	
+Bug   751458 Fixes from InterOp  (jgrimm, samudrala)	
+Bug   746295 Fix div by 0 in sctp_jitter (jgrimm)
+NA           Make T5 timer cleanup SHUTDOWN-PENDING state.  (jgrimm)	
+Patch 744633 /proc interface to display associations/endpoints (samudrala)
+NA           Update to 2.5.70 kernel. (samudrala)
+NA           sctp_getladdrs(), sctp_getpaddrs() bug fixes. (samudrala)
+Patch 738592 sctp_sendmsg() api support. (ardelle.fan)
+Patch 738550 SCTP_SHUTDOWN_EVENT notification support. (samudrala)
+NA           Rename struct sctp_protocol as sctp_globals (samudrala)
+Patch 737395 SCTP_GET_PEER_ADDR_INFO socket option. (samudrala)
+Bug   695324 Report error cause in CANT_STR_ASSOC (ardelle.fan)	
+Bug   695322 Stale cookie might not be first err cause (ardelle.fan)	
+Patch 735933 Support for socket options that take addr & associd (samudrala)
+Patch 718726 Add CACC frametest (ardelle.fan) 	
+NA           slab cache for chunks & bind_bucket (jgrimm)	
+NA           Update to 2.5.69 kernel. (samudrala)
+Patch 733320 SCTP ECN & IPv6 (jgrimm)	
+NA           Bug in get_peer_addr_params. (jgrimm, report by yfj@stanford.edu)
+Patch 730924 Add sinfo_timetolive support. (jgrimm)
+Patch 730461 SO_LINGER support for TCP-style sockets. (samudrala)
+Bug   729234 Initialize missing v4 fields of a v6 accept socket (samudrala)
+Bug   729652 Free chunk(s) when primitive_SEND fails (jgrimm)	
+Patch 704841 SEND_FAILed for fragmented messages (jgrimm, ardelle.fan)	
+Patch 727821 sendmsg() updates for TCP-style sockets. (samudrala)
+Patch 727454 Add control chunk bundling (jgrimm)	
+Patch 718726 Add SFR-CACC support.  (ardelle.fan)
+Patch 726343 Add SCTP_MAXSEG support.  (jgrimm)	
+NA           Add some macros to help cleanup code.  (jgrimm)	
+Patch 725367 Fix for poll() on a TCP-style listening socket. (samudrala)
+Patch 725219 Add per message fragment tracking (jgrimm)	
+NA           Update to 2.5.68 kernel. (samudrala)
+
+lksctp-2_5_67-0_6_9:
+Patch 723414 Handle accept() of a CLOSED association. (samudrala)
+Patch 722206 shutdown() support for TCP-style sockets. (samudrala)
+Bug   722169 Fix can't send to routed ipv6 address bug (jgrimm) 	
+NA           Fix GFP_KERNEL allocation while spinlock.  (jgrimm)	
+Patch 721330 Allow v4 private to v4 global association. (jgrimm)	
+Patch 720930 getsockname/getpeername support for TCP-style sockets (samudrala)
+Patch 719232 optimization: csum_update_copy && ulpq short-circuit (jgrimm)
+NA           Update to 2.5.67 kernel. (samudrala)
+Patch 717587 Use kernel crypto api (jgrimm)	
+Patch 714270 listen backlog support for TCP-style sockets. (samudrala)
+Patch 712929 Fix SACK bundling bug & a few minor fixes (jgrimm)	
+Patch 711590 Add V6_LINKLOCAL & sin6_scope_id support. (jgrimm)	
+Patch 711584 Add '--interface' option to sctp_darn tool. (jgrimm)	
+Patch 704841 Add SEND_FAILED support (ardelle.fan)
+NA           Update to 2.5.66 kernel (jgrimm)	
+Patch 709527 Add icmpv6 handler and PKT_TOOBIG support.  (jgrimm)
+	
+lksctp-2_5_65-0_6_8:
+Patch 706470 Bundle SACK with outgoing DATA (jgrimm)
+NA           Add --echo option to sctp_darn (jgrimm)	
+NA           Update to 2.5.65 kernel and config changes. (jgrimm)	
+Patch 702439 New kernel test to verify TCP-style socket interfaces. (samudrala)
+Bug   701294 Invalid associd passed to getsockopt() in sctp_darn. (samudrala) 
+
+lksctp-2_5_64-0_6_7:
+NA           Update to 2.5.64 kernel. (samudrala)
+Bug   699299 Panic in close(). (jgrimm)
+Patch 698437 frametest for TCP-style sockets. (samudrala)
+Patch 698877 Receiver SWS prevention. (jgrimm) 
+Patch 689872 Nagle-like support for SCTP.  (ardelle.fan)
+Patch 694884 accept() support for TCP-style sockets. (samudrala)
+NA           Bug fix from mailing list (Norbert Kiesel)
+Patch 689872 SCTP_NODELAY testcases (ardelle.fan)
+	
+lksctp-2_5_63-0_6_6:
+NA           Update to 2.5.63 kernel. (samudrala)
+Patch 692590 Add set/getsockopt SET_PEER_PRIMARY_ADDR (jgrimm)
+Bug   601470 Fix PF_INET sockets advertise v6 support bug (jgrimm)	
+NA           Fix testframe for non-SMP build  (jgrimm)
+Bug   688408 Fix testcases for v4 only configurations (jgrimm)	
+Patch 677351 Add getsockopt for DEFAULT_SEND_PARAM  (ardelle.fan)
+Patch 689446 Renege for "fills gap" case. (jgrimm)	
+Bug   611888 Round-robin retransmit path updates. (samudrala)
+NA           Update to 2.5.61 kernel. (samudrala)
+NA           Update to 2.5.60 kernel. (samudrala)
+Bug   649355 v6 source address selection support. (samudrala)
+Patch 680361 Add testcase for partial data delivery. (jgrimm)
+Patch 677351 SET_DEFAULT_SEND_PARAM setsockopt.  (ardelle.fan)
+Patch 681914 Skinny up ulpevent and support sinfo_cumtsn (jgrimm)
+Patch 685246 Partial Data Delivery.  (jgrimm).
+Patch 683736 Override primary destination with MSG_ADDR_OVER (ardelle.fan)
+Patch 630124 SCTP snmp mib statistics update/display support. (samudrala)
+Patch 686131 Move duplicate TSN tracking to tsnmap & cleanup (jgrimm)
+NA           C99 struct initializer cleanup.                 (Art Haas)	
+	
+lksctp-2_5_59-0_6_5:
+Patch 674359 Handling for Invalid Stream in INIT & missing cookie. (jgrimm)
+Patch 676473 Add v6 scoping testcases.  (jgrimm)
+Bug   677107 af->dst_saddr doesn't fill in the port  (samudrala)
+Patch 676468 Cleanup of assoc bind addr list initialization (samudrala)
+Patch 678481 Large Message Fragmentation support (jgrimm)
+Bug   679839 Kconfig can emit bad config of ipv6=m, sctp=y (jgrimm)	
+
+lksctp-2_5_59-0_6_4:
+Patch 673715 Fix to update rwnd on partial reads. (samudrala)
+Patch 673678 Minor fixes to overlapping init. (jgrimm)
+Patch 673309 Minor fixes to icmp error handler. (samudrala)
+Bug   672878 Free chunks in rtx & control queues on teardown.(samudrala)
+Patch 672759 Advisory marker as 'unsafe' for unload. (jgrimm)
+Patch 671916 Heartbeat timer during shutdown fixes (jgrimm)
+Patch 670970 Path mtu support for v4 addresses. (samudrala)
+NA           Update to 2.5.59 kernel. (samudrala)
+Patch 667038 Add heartbeat jitter (ardelle.fan)
+Patch 670020 Remove hardcoded stream limits (jgrimm)
+NA           Update to 2.5.56 kernel. (samudrala)
+Patch 662296 Handle ip re-assembled non-linear skb's (samudrala)
+Patch 663633 get/free paddrs and laddrs support (ardelle.fan)
+Bug   664112 Retransmitting already gap-acked TSNs (jgrimm)
+NA           Update to 2.5.53 kernel. (samudrala)
+Bug   667037 ft_frame_rwnd_receiver fail with v4 only (ardelle.fan)
+
+lksctp-2_5_52-0_6_3:
+NA           Update to 2.5.52 kernel. (samudrala)
+Patch 652802 Window update SACK support. (samudrala)
+Patch 651063 Fixes for compiler issues with gcc 3.2 (samudrala)
+Patch 649819 Notifier registration for v6 addr events. (samudrala)
+Patch 638235 Stale cookie support. (ardelle.fan)
+Patch 648103 v6 source address selection support. (samudrala)
+Bug   645067 memcpy in sctp_sendmsg() may copy too much. (samudrala)
+NA           Update to 2.5.50 kernel. (samudrala)
+Patch 644936 SCTP_INITMSG socket option. (samudrala)
+NA           Update to 2.5.49 kernel. (samudrala)
+Bug   641066 Bad dereference in sctp_cmd_assoc_failed. (samudrala)
+Patch 639177 MSG_PEEK support for recvmsg(). (samudrala)
+
+lksctp-2_5_47-0_6_2:
+Patch 637943 MSG_EOR support for recvmsg(). (samudrala)
+NA           Update to 2.5.47 kernel. (samudrala)
+Patch 636734 v6 autobind (jgrimm)
+Patch 635797 Blocking connect() support. (samudrala)
+Patch 634730 udp-style connect(non-blocking) support. (samudrala)
+NA           Update to 2.5.46 kernel. (samudrala)
+Patch 555335 Peer address parameters socket option (ardelle)
+NA           Update to 2.5.45 kernel. (samudrala)
+Patch 631750 sctpParam_t cleanup (jgrimm)
+Bug   587078 sctp_process_init() can fail (jgrimm)
+Patch 633338 Handle HOST_NAME_ADDR parm and misc. (jgrimm)
+Patch 625413 sockaddr_storage_t cleanup (jgrimm)
+Patch 635246 short circuit "no route" case (jgrimm)
+Bug   581734 PF_INET6 listen can't receiving v4 addresses (jgrimm)
+
+lksctp-2_5_44-0_6_1:
+Patch 628901 Initial Source address selection support. (samudrala)
+Bug   611930 Lost CWR scenario fix (jgrimm)
+NA           2.5.44 (jgrimm)
+Patch 628333 SNMP MIB infrastructure for SCTP. (nivedita)
+Patch 628318 Checks for tcp-style sockets. (nivedita)
+Bug   547270 Retain the order of retransmission. (daisyc)
+Patch 622919 Handle User initiated ABORT. (ardelle.fan)
+Bug   611927 Bug in the calculation of highest new tsn in sack. (samudrala)
+Bug   611916 Data can end up getting sent ahead of pend. rtx data (jgrimm)
+NA           Update to 2.5.43 kernel. (samudrala)
+Bug   623286 SHUTDOWN_COMPLETE has 0 vtag on lost SDC + restart. (samudrala)
+Patch 601756 VTAG checks for ABORT and SHUTDOWN_COMPLETE chunks. (ardelle.fan)
+Patch 619993 Fixes a couple of sctp_peeloff() issues. (samudrala)
+Bug   611919 Fast retranmist should ignore cwnd limit. (daisyc)
+Bug   611840 Restart address needs to check INIT and happen earlier (jgrimm)
+
+lksctp-2_5_41-0_6_0:
+NA           Update to 2.5.41 kernel (samudrala)
+Bug   621054 v6 kernel tests pass without IPv6 configured. (daisyc)
+NA           Update to 2.5.40 kernel   (jgrimm)
+NA           Split into user/kernel repositories (inaky, daisyc)
+Bug   611928 Alloc GFP_KERNEL with locks held (jgrimm)
+Bug   602650 Dropping packets > frag_point (jgrimm, samudrala)
+Patch 601367 Handle Unrecognized Parms (daisyc)
+Patch 609744 Add abort and shutdown to sctp_darn (ardelle.fan)
+Bug   604251 Association freed twice (jgrimm)
+Bug   611835 Fix Restart address check (jgrimm)
+
+lksctp-2_5_29-0_5_0:
+Patch 588249 misc. user header file fixes (jgrimm)
+
+lksctp-2_5_29-0_4_99:
+Patch 582166 sctp_peeloff() support. (samudrala)
+Bug   583874 sendmsg/init with bad buf. has leak (jgrimm)
+Patch 581963 Handle select/poll syscalls (daisyc)
+Bug   583798 Need GFP_ATOMIC when BH disabled (samudrala)
+Bug   585351 MSG_UNORDERED not set on fragmented chunks (samudrala)
+Patch 585474 Remove old DEFAULT_STREAM sock opt (jgrimm)
+Bug   585653 Fix V6INADDR_ANY to choose a saddr (jgrimm)
+Bug   585929 more leaks in sendmsg() on error cases. (samudrala)
+Patch 574420 overlapping init/restart  (dajiang, jgrimm)
+Bug   581992 zero probe shouldn't error association (samudrala)
+Patch 587986 move to Linux 2.5.29 (samudrala)
+
+lksctp-2_5_24-0_4_12:
+Patch 569943 graceful shutdown of an individual association. (samudrala)
+Patch 572054 move to linux kernel 2.5.24. (samudrala)
+Bug   574069 bugs in fragmentation & reassembly. (samudrala)
+Patch 579301 check for No User Data error and testcase (jgrimm)
+Bug   574071 less strict rwnd check at rcvr (samudrala)
+Patch 579525 SCTP_AUTOCLOSE socket option. (samudrala)
+Patch 575712 modify sctp_darn tool to use select (daisyc)
+NA           misc.: cleanup jiffies decl., update docs. (jgrimm)
+Patch 581745 getsockname needs sk->sport (jgrimm)
+Patch 582273 handle DATA while in SHUTDOWN-SENT (jgrimm)
+Bug   581997 sctp_wait_for_sndbuf fault (jgrimm)
+Patch 573958 Overlapping Init testcases (dajiang)
+Patch 582905 misc: remove md5 files. update cause code values (jgrimm)
+
+lksctp-2_5_15-0_4_11:
+Patch 560341 assoc_hash and more locking (jgrimm)
+Bug   541062 local_addr_list not not writer safe (jgrimm)
+Patch 564637 new ep_hash and locking down address list read/writes (jgrimm)
+Patch 565087 protect against timer overfiring (jgrimm)
+Patch 565935 Collapse ep/asoc hash links into common substructure (jgrimm)
+Bug   565868 Ctl-sock (OOTB) traps sending to ipv6 dest.  (jgrimm)
+Bug   565878 Xmit to wrong peer when no asoc.  (jgrimm)
+Patch 565686 Update RTO upon Heartbeat ACK.  (samudrala)
+Patch 567028 Cleanup unneeded atomic_t fields (jgrimm)
+Patch 567061 Some sctp-socket-04.txt updates (jgrimm)
+Patch 567646 Combine sctp_func_t/sctp_af_specific_t (jgrimm)
+Patch 568562 Sysctl support for RFC 2960 variables (jgrimm)
+Patch 567514 SCTP_SET_EVENTS sock options (samudrala)
+Patch 567492 block/non-block send and SNDBUF/RCVBUF (daisyc)
+
+lksctp-2_5_15-0_4_10:
+Patch 561757 congestion control, handle SACKs indicating renege (samudrala)
+Patch 561632 v4 scoping rules (daisyc)
+lksctp-2_5_15-0_4_9:
+Patch 554705 Locking phase 1 (off the BH, use socklock and backlog) (jgrimm)
+Bug   550363 Shutdown handling of CTSN incorrect (jgrimm)
+Patch 558565 testframe ipv4 only, doesn't compile (samudrala)
+Patch 556572 Fix INADDR_ANY and some IPv4 scoping (daisyc)
+Patch 559801 Cleanup old locking stuff and various naming/style (jgrimm)
+
+lksctp-2_5_15-0_4_8:
+Patch 557034 Port to 2.5.15 (samudrala)
+Patch 550903 sys_bindx removal (inaky, samudrala)
+
+lksctp-2_4_18-0_4_8:
+Patch 546328 sctp_transport cleanup (jgrimm)
+Bug   545852 sk->err cleanup (samudrala)
+Bug   547147 association leaks the inqueue->in_progress chunk (jgrimm)
+Bug   541065 fix port_rover race conditition in bind path (jgrimm)
+Patch 544577 heartbeat ack and failover (dajiang)
+NA           Make lksctp a module (inaky)
+NA           bindx over sockopt (inaky)
+Patch 547885 Split out v6 code and cleanup module patch (jgrimm)
+Patch 544583 ft_frame_hbACK updates (dajiang, huang)
+Patch 547340 fix testframe for "run once" (samudrala)
+Patch 548772 sctp_lock primitives   (jgrimm)
+Patch 547319 naming cleanup in statefuns (daisyc)
+Patch 549266 sctp_lock unittests (jgrimm)
+Patch 548815 Disable fragments option and more tests. (samudrala)
+Patch 550400 Add OOTB testcase (daisyc)
+Patch 550520 transport & association error thresholds (samudrala)
+NA           fix ft_frame_init_timer to not conflict with OOTB (jgrimm)
+Patch 549356 Small fixes and cleanup of bindx code (inaky)
+Patch 549360 bindx through sockopt (inaky)
+Patch 551716 Start using sctp_opts field instead of endpoint (jgrimm)
+Patch 551657 RTT Measurements and RTO updates (samudrala)
+Patch 552084 sctp_endpoint_common (jgrimm)
+Patch 553100 Testcase for RTT Measurements (samudrala)
+Bug   553329 Sendmsg + INIT CMSG has path which can corrupt assoc (jgrimm)
+Patch 553394 Move sctp_association to use endpoint_common (jgrimm)
+Patch 553528 rtx and heartbeat failures cleanup (samudrala)
+Patch 553844 OOTB packet processing (daisyc)
+
+lksctp-2_4_18-0_4_7:
+Bug   541198 Old-style retval->state races with CMD (jgrimm)
+Patch 541820 listen auto-bind support (samudrala)
+Patch 543421 Complete removal of retval structs/processing (jgrimm)
+Patch 544908 Object Count Debugging facilities (jgrimm)
+Patch 544806 Fix inqueue leak of chunks (daisyc)
+Patch 544460 Fragmentation/Reassembly support (samudrala)
+
+lksctp-2_4_18-0_4_6:
+Patch 529522 Primary Addr from saddr (jgrimm, daisyc, hui_huang)
+Patch 529530 Use skb_copy_datagram_iovec (samudrala)
+Patch 529961 sctphdr, PARAM constants in net order (jgrimm)
+Patch 529707 Changes to sctp_make_data* interfaces (samudrala)
+Patch 531206 Massive linux/sctp.h changes (jgrimm)
+Patch NA     Eliminate sctp_io.h (jgrimm)
+Patch 532575 sctp_opt as a per socket structure (jgrimm)
+Patch 532245 Patch to eliminate tcp_func dependency (samudrala)
+Patch 533351 Update headers to Socket Extensions 03 draft (jgrimm)
+Patch 531647 Initialize MTU from routing information (samudrala)
+Patch NA     Update csum I-D. (jgrimm)
+Patch 529783 Send heartbeats (dajiang, hui_huang)
+Bug   529726 SACK response sent to incorrect dest (jgrimm)
+Patch NA     More cleanup, mostly naming, dead field removal. (jgrimm)
+Bug   539452 sk->err should have errno as positive value (jgrimm).
+
+lksctp-2_4_18-0_4_5:
+Bug   513536 association lookup can fail (jgrimm)
+NA           Unused file/header cleanup (jgrimm)
+NA           Move sctp_socket() to testframe (jgrimm)
+Patch 524687 Stop byteswapping the rcv skb part 1 (daisyc)
+Patch 525009 Stop byteswapping the rcv skb part 2 (daisyc)
+NA           Change CRC32C per Connectathon (jgrimm)
+Patch 526505 Change crc code to skip checksum field (jgrimm)
+Patch 526177 Incorrect use of skb->end (samudrala)
+Patch 526740 Missing bindx support (samudrala)
+NA           A few sctp_darn fixes (jgrimm)
+NA           updatelinux_sctp.sh to handle links (loretos)
+Patch 513912 Invalid stream verification (daisyc)
+Patch 528541 ABORT handling during initiation phase (jgrimm)
+Patch 528679 Misc. Cleanup. (jgrimm)
+Patch 528611 Fix testframe skb for fraglist support (samudrala)
+Patch 526156 SCTP_STATUS sockopt (samudrala)
+
+
+lksctp-2_4_17_0-4_4:
+
+Patch 515054 INIT retransmission (jgrimm)
+Patch 511394 Invalid StreamId tests (daisyc)
+	     README suggestions (baqaqi)
+Bug   519410 test_kernel spinlock initialization (sridhar)
+Patch 520992 Enable COOKIE-ECHO bundling (jgrimm)
+Patch 520627 Fix autobind twice bug (daisyc)
+Patch 520755 A couple bugs from Debug Memory Allocations (sridhar)
+Patch 521216 Fix bind_addrs_to_raw calling kmalloc(GFP_KERNL) on int. (jgrimm)
+
+lksctp-2_4_17-0_4_3:
+New          Update to 2.4.17 (sridhar)
+Patch 512680 Frame test bindx for IPv6 (hui)
+Patch 510317 Failing testcase for source addr bug (daisyc)
+
+lksctp-2_4_1-0_4_3:
+Patch 511028 New CRC32C  (dinakarjb)
+Patch 510797 Sendmsg w/associd (jgrimm)
+Patch 499262 Testcase for stream negotiation (daisyc)
+Bug   473322 Sendmsg insists on msg_name (jgrimm)
+
+
+If you would like to follow the day-to-day development of the SCTP
+kernel, refer to:
+
+   http://lists.sourceforge.net/lists/listinfo/lksctp-developers
+
+Post messages for the developers (including bug reports) to
+
+   lksctp-developers@lists.sourceforge.net
+
+If you wish to participate in development, please subscribe to the
+developers' list, drop a note to lksctp-developers.
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..88c32f1
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,92 @@
+                      HOW TO COMPILE, RUN AND INSTALL
+                      -------------------------------
+
+CONTENTS
+--------
+
+The lksctp-tools package is intended for two audiences.  
+	1) SCTP application developers
+	2) LKSCTP project developers
+
+For SCTP application developers, this package provides the user-level
+C language header files and a library for accessing SCTP specific
+application programming interfaces not provided by the standard sockets. 
+
+For LKSCTP project developers, this package provides the functional
+and API regression tests.
+
+For either role, this project provides sample code, utilities, and
+tests that one may find useful.  
+
+The below INSTALL directions are provided with in each of these roles.
+
+NOTE:  To build, run and install the lksctp-tools package, your system is 
+required to be running with linux-2.5.36, or a later version of the 
+kernel, configured with the Network options "SCTP Configuration" 
+support enabled.  
+
+______________________________________________________________________
+
+
+INSTALLATION   
+-------------
+Prerequisite:  A Linux kernel with SCTP support.  This may come stock with 
+your distrbution (some day), or you will need to build your own 2.5.36 or
+later kernel.
+
+To install/build the lksctp-tools utilities/tests do the following:
+
+1) Download and install the following binary RPMs from the lksctp sourceforge
+   website at 
+	http://sourceforge.net/project/showfiles.php?group_id=26529
+   * lksctp-tools-x.y.z-1.i386.rpm
+   * lksctp-tools-x.y.z-devel-1.i386.rpm
+   * lksctp-tools-x.y.z-doc-1.i386.rpm
+
+   lksctp-tools-x.y.z-1.i386.rpm includes 
+   * SCTP run-time library.
+   * Sample SCTP applications: sctp_darn and sctp_test.
+   * withsctp: a tool when used with existing TCP binaries replaces TCP
+               with SCTP.
+
+   lksctp-tools-x.y.z-devel-1.i386.rpm includes
+   * SCTP header file /usr/include/netinet/sctp.h
+   * SCTP man pages.
+   * Source code for sample SCTP applications.
+
+   lksctp-tools-x.y.z-doc-1.i386.rpm includes
+   * SCTP RFC's and internet drafts. 
+
+   If you want to run and play with the included sample SCTP applications or 
+   develop your own SCTP applications, you can skip the rest of the
+   instructions.
+
+   If you are interested in running the functional regression tests included
+   in the lksctp-tools package, continue with the following instructions.
+
+2) Download and install the following source RPM form the lksctp sourceforge
+   website at 
+        http://sourceforge.net/project/showfiles.php?group_id=26529
+   * lksctp-tools-x.y.z-1.src.rpm
+   This will install the lksctp-tools gzipped tarball and RPM spec file. 
+
+3) Untar the lksctp-tools directory from the gzipped tarball. This creates a 
+   subdirectory called lksctp-tools-x.y.z. 
+
+   Ensure you have autoconf, automake and libtool packages installed on your
+   system.
+
+4) Run ./bootstrap
+
+5) Run ./configure
+
+6) Run make
+
+7) To run the SCTP kernel regression tests,
+  
+   $ cd src/func_tests
+   $ make v4test (regression tests for the IPv4 socket support)
+   $ make v6test (regression tests for the IPv6 socket support)
+
+8) Run other SCTP test tools/applications in src/apps directory to verify the
+   running SCTP.
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..8577184
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,27 @@
+include $(top_srcdir)/Makefile.vars
+include $(top_srcdir)/Makefile.rules
+
+DISTCLEANFILES += config.h stamp-h libtool
+MAINTAINERCLEANFILES += aclocal.m4 config.h.in configure stamp-h.in \
+			config.h stamp-h
+
+EXTRA_DIST += ChangeLog AUTHORS COPYING COPYING.lib INSTALL \
+	README ROADMAP NEWS \
+	Makefile.vars Makefile.rules Makefile.dirs
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = libsctp.pc
+EXTRA_DIST += libsctp.pc.in
+DISTCLEANFILES += libsctp.pc
+
+# bin or src products may be required to generate stuff in test/
+SUBDIRS = man bin src doc
+
+ACLOCAL_AMFLAGS=-I m4
+
+# Libtool support
+LIBTOOL_DEPS = @LIBTOOL_DEPS@
+libtool: $(LIBTOOL_DEPS)
+	$(SHELL) ./config.status --recheck
+
+## FIXME: Your stuff here
diff --git a/Makefile.dirs b/Makefile.dirs
new file mode 100644
index 0000000..f376712
--- /dev/null
+++ b/Makefile.dirs
@@ -0,0 +1,60 @@
+# -*-makefile-*-
+#
+# Define here directories you want
+
+rootbindir = /bin
+rootsbindir = /sbin
+rootlibdir = /lib
+
+localedir = $(datadir)/locale
+pkgsysconfdir = $(sysconfdir)/@PACKAGE@
+pkgdocdir = $(datadir)/@PACKAGE@
+
+vpkgsysconfdir = $(pkgsysconfdir)/v@VERSION@
+vpkgdatadir = $(pkgdatadir)/v@VERSION@
+vpkglibdir = $(pkglibdir)/v@VERSION@
+vpkgdocdir = $(docdir)/v@VERSION@
+
+# List here all the directories you want listed in the file to be used
+# in your programs:
+
+directories := \
+	localedir \
+	pkgsysconfdir \
+	rootbindir \
+	rootlibdir \
+	rootsbindir \
+	vpkgdatadir \
+	vpkgdocdir \
+	vpkglibdir \
+	vpkgsysconfdir \
+	\
+	bindir \
+	datadir \
+	libdir \
+	pkgdatadir \
+	pkgdocdir \
+	pkglibdir \
+	sbindir
+
+# To modify this target for another language, just copy, paste and
+# modify the target to generate directories.h. We depend on
+# config.status and Makefile.dirs, as anything changed is going to be
+# reflected there.
+
+# This is for generating the list in C/C++
+directories.h: $(top_builddir)/config.status $(top_srcdir)/Makefile.dirs
+	@rm -f $@
+	@echo -n "Creating $@ ..."
+	@echo "#ifndef __$(subst .,_,$@)__" > $@
+	@echo "# define __$(subst .,_,$@)__" >> $@
+	@echo "" >> $@
+	@echo -e $(foreach v,$(directories),$(shell echo 'D_$(v) \"$($v)\"\\n')) \
+	  | sed 's/^ *D_/# define D_/' >> $@
+	@echo "#endif" >> $@
+	@echo " done"
+
+DISTCLEANFILES += directories.h
+MAINTAINERCLEANFILES += directories.h
+
+## FIXME: Your stuff here
diff --git a/Makefile.rules b/Makefile.rules
new file mode 100644
index 0000000..9488228
--- /dev/null
+++ b/Makefile.rules
@@ -0,0 +1,21 @@
+# -*-makefile-*-
+#
+# Generate pre-parsed C code.
+%.i: %.c
+	$(COMPILE) -E -c $^ -o $@
+
+.PRECIOUS: %.i
+%.ci: %.i
+	-grep -v -e "^#" -e "^ *$$" $^ | indent > $@
+	mv -f $@ $^
+
+
+## FIXME: Your stuff here
+
+edit = @sed \
+	-e "s|\@bindir\@|$(bindir)|" \
+	-e "s|\@libdir\@|$(libdir)|" \
+	-e "s|\@PACKAGE\@|$(PACKAGE)|" \
+	-e "s|\@LIBWITHSCTP_CURRENT\@|$(LIBWITHSCTP_CURRENT)|" \
+	-e "s|\@LIBWITHSCTP_REVISION\@|$(LIBWITHSCTP_REVISION)|" \
+	-e "s|\@LIBWITHSCTP_AGE\@|$(LIBWITHSCTP_AGE)|"
diff --git a/Makefile.vars b/Makefile.vars
new file mode 100644
index 0000000..068c29c
--- /dev/null
+++ b/Makefile.vars
@@ -0,0 +1,18 @@
+# -*-makefile-*-
+#
+# type: deep, strictness: gnu
+
+MAINTAINERCLEANFILES = Makefile.in
+DISTCLEANFILES = \\\#*\\\# Makefile
+CLEANFILES = 
+MOSTLYCLEANFILES = *~ *.[aios] *.bak *.ci *.io
+
+EXTRA_DIST = 
+
+LATEX = @LATEX@
+DVIPS = @DVIPS@
+DVIPDFM = @DVIPDFM@
+ENSCRIPTBIN = @ENSCRIPTBIN@
+PS2PDF = @PS2PDF@
+
+## FIXME: Your stuff here
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..62767ee
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,8 @@
+
+The Linux Kernel SCTP Reference Implementation release 0.5.0 is included in
+Linux 2.5 Kernel release 2.5.34 and up.
+
+From release 0.6.0 and on, we will adopt the new build and installation 
+process for lksctp users and developers.  Please check the INSTALL and 
+ROADMAP for more details.
+
diff --git a/README b/README
new file mode 100644
index 0000000..cfabbe5
--- /dev/null
+++ b/README
@@ -0,0 +1,178 @@
+(C) Copyright 2007 Hewlett-Packard Development Company, L.P.
+(C) Copyright IBM Corp. 2001, 2003
+Copyright 2001 Motorola, Cisco, Intel, Nokia, La Monte Yarroll.
+Copyright 2002 Nokia, La Monte Yarroll, Intel. 
+
+This is the lksctp-tools package for Linux Kernel SCTP Reference 
+Implementation.
+
+This package is intended to supplement the Linux Kernel SCTP
+Reference Implementation now available in the Linux kernel source
+tree in versions  2.5.36 and following.  For more information on LKSCTP
+see the below section titled "LKSCTP - Linux Kernel SCTP." 
+
+lksctp-tools
+____________
+
+The lksctp-tools package is intended for two audiences.  
+	1) SCTP application developers
+	2) LKSCTP project developers
+
+For SCTP application developers, this package provides the user-level
+C language header files and a library for accessing SCTP specific
+application programming interfaces not provided by the standard sockets.
+
+For LKSCTP project developers, this package provides the API
+regression and functional tests.  Developers should also check
+lksctp_tests package that provides low level kernel tests.  These
+are available from git.kernel.org.
+
+For either role, this project provides sample code, utilities, and
+tests that one may find useful.  
+
+
+LKSCTP - Linux Kernel SCTP 
+__________________________
+
+The Linux Kernel SCTP Reference Implementation is free software; you
+can redistribute it and/or modify it under the terms of the GNU
+General Public License as published by the Free Software Foundation;
+either version 2, or (at your option) any later version. For more
+information on licensing terms, please see the file COPYING in this
+directory.
+
+SCTP (Stream Control Transmission Protocol) is a message oriented,
+reliable transport protocol, with congestion control, support for
+transparent multi-homing, and multiple ordered streams of messages.
+RFC2960 defines the core protocol. The IETF SIGTRAN Working Group
+developed SCTP.  The primary architects are Randy Stewart and Qiaobing
+Xie.
+
+The Kernel Reference is first and foremost an exposition of
+RFC2960 and related documents. You will find that the comments and
+variable names tie closely back to the RFC and Internet Drafts.
+
+This work was started by a small team of developers at Motorola.
+Throughout this document, "we" refers to that team.  We intend for the
+meaning of "we" to expand to include the whole development community,
+all 27 million programmers on the planet.
+
+The Kernel Reference has loose origins in the SCTP User Space Reference
+by Randy Stewart and Qiaobing Xie.
+
+MANIFEST
+--------
+.
+|-- bin
+|-- doc
+|-- man
+|-- src
+    |-- apps
+    |-- func_tests
+    |-- include
+    |   `-- netinet
+    |-- lib
+    |-- testlib
+    `-- withsctp
+
+You may want to check the following files:
+
+COPYING.lib	Licensing terms of libsctp
+COPYING		Licensing terms of other pieces of the package
+ROADMAP		A tour around the files in the distribution of SCTP-tools.
+INSTALL       	How to install and run this beast.
+ChangeLog	What has changed since the last release?
+
+DESIGN GOALS
+------------
+
+- A primary design goal is to reflect RFC 2960 as closely as
+practical.  We have changed many names from the user space reference to
+follow the draft as closely as possible.  We have also included
+extensive quotes from the draft adjacent to the code which implements
+them.
+
+- The other primary design goal is to integrate Linux kernel data
+structures and idioms as much as possible.  The test framework (in
+directory test/) provides many of the functions which would otherwise
+come from the kernel.  The test frame does use libc features, but the
+state machine code should be libc-free.
+
+- A lesser design goal is to completely describe the actions for each
+state transition in an sctp_command_t (see sctp_command.h).  This
+means that the state functions (sctp_state_fn_t in sctp_sm.h) are NOT
+allowed to modify their endpoint, association, or chunk arguments.
+This is enforced by const modifiers--please respect the compiler
+warnings.  All actions must be described in the last argument to the
+state function.
+
+- A byte order convention for dealing with the SCTP chunk headers: 
+all SCTP chunks, regardless if the chunk is to be sent outbound
+to the network or was received inbound from the network, the header portion
+of the chunk is ALWAYS created and retained in the NETWORK BYTE ORDER.
+
+- An error code handling convention is to return negative values internally.  
+The sk->err field holds a positive valued errno values, so will need our 
+internal values negated.   
+
+- We are moving toward an XP development model.  So far we have
+adopted pair-programming, coding-to-test (functional and unit), design
+through refactoring, and story-based planning.
+
+In order to make XP work, it is very important that we have a complete
+set of tests for the code.  We can not safely refactor major parts of
+the code without a way to find the things we break.  If you decide to
+extend the SCTP Kernel Implementation we ask that you do the following:
+
+	1) Pick an XP story.  Tell lksctp-developers@lists.sourceforge.net
+	2) Write a functional test for that XP story.  The functional
+	   test defines "DONE" for the story.
+	3) Submit the functional test as a patch on SourceForge.
+	4) Write unit tests for any new "objects" you define.
+	5) Implement your feature.
+	6) Submit the feature and the unit tests as a separate
+	SourceForge patch.
+	
+Look in src/func_tests and in lksctp-tests package for examples of of tests.
+Please do not submit code that fails its own tests or any of the unit tests.
+If it fails a functional test, please document that with the submission.
+
+Another XP requirement is to code only what is you need to make the
+current test work.  Where this means omitting required features, we
+have put in prominent BUG comments describing the omitted
+functionality.
+
+FEATURES
+--------
+This implementation uses a fairly compact cookie which is isolated in
+its own substructure of SCTP_association.  We have been moving toward
+aggregating data elements which need to travel together to minimize
+copying of individual elements in favour of more efficient structure
+copies.
+
+You will find what we believe to be the smallest possible Internet
+simulator in the middle of the function test_kernel.c:simulate_internet().
+The simulator makes a few simplifying assumptions...
+
+MAILING LISTS and WEB SITES
+---------------------------
+http://www.sourceforge.net/projects/lksctp
+
+	This is the lksctp project webpage.  
+
+linux-sctp@vger.kernel.org
+	
+	This is the discussion list for developers.  Join this list if	
+	you are interested in following the day-to-day activities of
+	the SCTP Kernel Reference Implementation development community. 
+	See subscription directions at:  
+		http://vger.kernel.org/vger-lists.html#linux-sctp
+
+http://www.sctp.org
+
+	This is Randy Stewart's SCTP web site.
+
+http://sctp.de
+
+	This is Michael Tuexen's SCTP web site.  Michael has collected
+	dozens of documents related to SCTP.
diff --git a/ROADMAP b/ROADMAP
new file mode 100644
index 0000000..0a65578
--- /dev/null
+++ b/ROADMAP
@@ -0,0 +1,45 @@
+TOUR
+----
+COPYING.lib	Licensing terms of libsctp	
+
+COPYING		Licensing terms of other pieces of the package
+
+README		Read this before developing.
+
+ChangeLog	What has changed since the last release?
+
+AUTHORS		Developers name list.
+
+INSTALL		How to build and install this package.
+
+doc/		All the relevant Internet Drafts and RFC's.
+
+doc/states.txt	This is a detailed state table for SCTP.  It makes a
+		pretty good index for RFC2960 too...
+
+man/		SCTP man pages
+
+src/		Implementation of the user space library, include files - 
+		this should go, some day, into glibc - as well as a set
+		of SCTP test tools and test programs.  
+
+src/apps	SCTP test applications.
+
+src/func_tests	SCTP functional tests.
+
+src/lib		Sources for SCTP library libsctp.a.
+
+src/testlib	Sources for SCTP test library libsctputil.a.
+
+src/include/netinet
+                Header files needed for user space development.
+
+bin/		Scripts for lksctp build, installation and execution.
+
+test/		Testframe functional and unit tests. These tests use a 
+		framework which enables running lksctp code in userspace.
+
+test/linux/include
+		This include heirarchy includes special versions of
+		kernel include files needed by the user-space test
+		frame.
diff --git a/bin/.gitignore b/bin/.gitignore
new file mode 100644
index 0000000..813925f
--- /dev/null
+++ b/bin/.gitignore
@@ -0,0 +1,5 @@
+compile
+depcomp
+install-sh
+ltmain.sh
+missing
diff --git a/bin/Makefile.am b/bin/Makefile.am
new file mode 100644
index 0000000..50985cb
--- /dev/null
+++ b/bin/Makefile.am
@@ -0,0 +1,8 @@
+
+include $(top_srcdir)/Makefile.vars
+include $(top_srcdir)/Makefile.rules
+
+noinst_SCRIPTS = aaaa
+
+EXTRA_DIST += $(noinst_SCRIPTS)
+
diff --git a/bin/aaaa b/bin/aaaa
new file mode 100755
index 0000000..f4982de
--- /dev/null
+++ b/bin/aaaa
@@ -0,0 +1,20 @@
+#! /bin/sh
+#
+# Run all the stuff we need to generate the configure and Makefile.in
+# in the automake process.
+#
+# The order needs to be that. If autoheader does not run after
+# autoconf, it doesn't get all the symbols right. As automake requires
+# config.h.in, created by autoheader, it needs to run after it.
+#
+# $Id: aaaa,v 1.1.1.1 2002/08/06 22:31:05 inaky Exp $
+
+
+set -ex
+
+aclocal
+autoconf
+autoheader
+# Set GNU strictness
+#automake --foreign
+automake --gnu
diff --git a/bootstrap b/bootstrap
new file mode 100755
index 0000000..8d85a22
--- /dev/null
+++ b/bootstrap
@@ -0,0 +1,13 @@
+#!/usr/bin/env bash
+# -*- sh -*-
+set -ex					# exit on error
+libtoolize --force --copy
+aclocal
+autoheader
+automake --foreign --add-missing --copy
+autoconf
+if [ "$1" = "-a" ]; then
+	./configure --prefix=/usr --enable-shared --enable-static
+	make
+	make dist
+fi
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..5de5c76
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,133 @@
+dnl -*-autoconf-*-
+
+dnl lksctp-tools: Autoconf script
+dnl
+dnl $Id: configure.in,v 1.1.1.2 2002/08/06 23:55:45 inaky Exp $
+
+dnl (C) 2002 Intel Corporation
+dnl     Iñaky Pérez-González <inaky.perez-gonzalez@intel.com>
+dnl      - Initial packaging
+
+dnl Package info
+dnl (CONFIG_AUX_DIR is for putting stuff in $TOPSRCDIR/bin, so we
+dnl reduce clutter in the root; if we put it below AM_INIT_AUTOMAKE,
+dnl configure will fail ...)
+
+AC_INIT([lksctp-tools], [1.0.18], [], [], [http://www.lksctp.org/])
+AC_SUBST(LIBSCTP_CURRENT, 1)
+AC_SUBST(LIBSCTP_REVISION, 18)
+AC_SUBST(LIBSCTP_AGE, 0)
+AC_SUBST(LIBWITHSCTP_CURRENT, 1)
+AC_SUBST(LIBWITHSCTP_REVISION, 18)
+AC_SUBST(LIBWITHSCTP_AGE, 0)
+
+AC_CONFIG_AUX_DIR(bin)
+AC_CONFIG_SRCDIR([src/apps/sctp_darn.c])
+AC_CONFIG_HEADERS([config.h])
+AC_CONFIG_MACRO_DIR([m4])
+AC_REVISION($Revision: 1.1.1.2 $)
+AM_INIT_AUTOMAKE
+m4_ifndef([AM_SILENT_RULES], [m4_define([AM_SILENT_RULES],[])])
+AM_SILENT_RULES([yes])
+
+dnl Set defaults
+dnl CFLAGS="$CFLAGS -g -Wall"
+
+dnl Checks for programs.
+AC_PROG_AWK
+AC_PROG_CC
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_ISC_POSIX
+
+dnl Checks for libraries.
+AC_LIBTOOL_DLOPEN
+AC_PROG_LIBTOOL
+AC_SUBST(LIBTOOL_DEPS)
+
+dnl Checks for header files.
+AC_HEADER_STDC
+AC_HEADER_SYS_WAIT
+AC_CHECK_HEADERS([arpa/inet.h fcntl.h malloc.h netdb.h netinet/in.h stdint.h \
+		  stdlib.h string.h sys/ioctl.h sys/param.h sys/socket.h \
+		  sys/time.h unistd.h])
+AC_CHECK_HEADERS([linux/sctp.h], [], [], [AC_INCLUDES_DEFAULT
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+])
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_C_INLINE
+AC_TYPE_SIZE_T
+AC_HEADER_TIME
+AC_STRUCT_TM
+AC_C_VOLATILE
+
+# Checks for library functions.
+AC_FUNC_MALLOC
+AC_FUNC_MEMCMP
+AC_FUNC_REALLOC
+AC_FUNC_SELECT_ARGTYPES
+AC_FUNC_SETVBUF_REVERSED
+AC_FUNC_VPRINTF
+AC_CHECK_FUNCS([bzero gethostbyname gettimeofday memmove memset select socket \
+		strchr strerror strtol strtoul])
+
+# Support for stream reset even, added on v4.11, 35ea82d611da
+LKSCTP_CHECK_MEMBER([struct sctp_event_subscribe.sctp_stream_reset_event],
+		    [HAVE_SCTP_STREAM_RESET_EVENT])
+
+# RFC 6525 (Stream Reconf), finished on v4.12, c0d8bab6ae51
+LKSCTP_CHECK_DECL([SCTP_RECONFIG_SUPPORTED], [HAVE_SCTP_STREAM_RECONFIG])
+
+# sctp_peeloff_flags was added on v4.13, 2cb5c8e378d1
+LKSCTP_CHECK_TYPE([sctp_peeloff_flags_arg_t], [HAVE_SCTP_PEELOFF_FLAGS])
+
+# New members to sctp_pdapi_event, added on v4.16, 65f5e357839e
+LKSCTP_CHECK_MEMBER([struct sctp_pdapi_event.pdapi_stream],
+		    [HAVE_SCTP_PDAPI_EVENT_PDAPI_STREAM])
+LKSCTP_CHECK_MEMBER([struct sctp_pdapi_event.pdapi_seq],
+		    [HAVE_SCTP_PDAPI_EVENT_PDAPI_SEQ])
+
+# PR-SCTP struct used to probe for sendv/recvv support, added on v4.17
+LKSCTP_CHECK_TYPE([struct sctp_prinfo], [HAVE_SCTP_SENDV])
+
+# This event indicates that the peer does not support SCTP authentication,
+# added on v4.16, 30f6ebf65bc4
+LKSCTP_CHECK_DECL([SCTP_AUTH_NO_AUTH], [HAVE_SCTP_AUTH_NO_AUTH])
+
+# New members to sctp_paddrparams, added on v4.19, 0b0dce7a36fb
+LKSCTP_CHECK_MEMBER([struct sctp_paddrparams.spp_ipv6_flowlabel],
+		    [HAVE_SCTP_SPP_IPV6_FLOWLABEL])
+LKSCTP_CHECK_MEMBER([struct sctp_paddrparams.spp_dscp],
+		    [HAVE_SCTP_SPP_DSCP])
+
+AC_CONFIG_HEADERS([src/include/netinet/sctp.h])
+AC_CONFIG_FILES([lksctp-tools.spec
+		Makefile
+		bin/Makefile
+		man/Makefile
+		src/Makefile
+		src/apps/Makefile
+		src/func_tests/Makefile
+		src/include/Makefile
+		src/include/netinet/Makefile
+		src/lib/Makefile
+		src/testlib/Makefile
+		src/withsctp/Makefile
+		doc/Makefile
+		libsctp.pc])
+
+# Build options
+AC_ARG_ENABLE(tests,
+	AS_HELP_STRING([--disable-tests],
+	[Build tests (default: yes)]),,
+	[enable_tests=yes])
+AM_CONDITIONAL(BUILD_TESTS, [test $enable_tests != no])
+
+AC_OUTPUT
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100644
index 0000000..6ed32b8
--- /dev/null
+++ b/doc/Makefile.am
@@ -0,0 +1,12 @@
+include $(top_srcdir)/Makefile.vars
+include $(top_srcdir)/Makefile.rules
+
+internet_drafts = \
+	draft-stewart-tsvwg-sctpipv6-00.txt \
+	draft-stewart-tsvwg-sctpscore-01.txt
+
+rfcs = rfc2960.txt rfc3257.txt rfc3286.txt rfc3309.txt rfc3554.txt \
+       rfc3758.txt rfc3873.txt rfc4460.txt rfc4820.txt rfc4895.txt \
+       rfc4960.txt rfc5061.txt rfc5062.txt rfc6458.txt
+
+EXTRA_DIST += $(rfcs) $(internet_drafts)
diff --git a/doc/draft-stewart-tsvwg-sctpipv6-00.txt b/doc/draft-stewart-tsvwg-sctpipv6-00.txt
new file mode 100644
index 0000000..b89057d
--- /dev/null
+++ b/doc/draft-stewart-tsvwg-sctpipv6-00.txt
@@ -0,0 +1,161 @@
+Network Working Group                                     R. R. Stewart
+INTERNET-DRA                                                 S. Deering
+                                                                  Cisco
+
+expires in six months                                      June  1,2001
+
+
+
+         IPv6 addressing and Stream Control Transmission Protocol 
+                   <draft-stewart-tsvwg-sctpipv6-00>
+
+Status of This Memo
+
+    This document is an Internet-Draft and is in full conformance with
+    all provisions of Section 10 of [RFC2026]. Internet-Drafts are
+    working documents of the Internet Engineering Task Force (IETF), its
+    areas, and its working groups. Note that other groups may also
+    distribute working documents as Internet-Drafts.
+
+    The list of current Internet-Drafts can be accessed at
+    http://www.ietf.org/ietf/1id-abstracts.txt
+
+    The list of Internet-Draft Shadow Directories can be accessed at
+    http://www.ietf.org/shadow.html.
+
+Abstract
+
+    Stream Control Transmission Protocol [RFC2960] provides transparent
+    multi-homing to its upper layer users. This multi-homing is
+    accomplished through the passing of address parameters in the
+    initial setup message used by SCTP. In an IPv4 network all addresses
+    are passed with no consideration for their scope and routeablility.
+    In a IPv6 network special considerations MUST be made to properly
+    bring up associations between SCTP endpoints that have IPv6
+    [RFC2460] addresses bound within their association.  This document
+    defines those considerations and enumerates general rules
+    that an SCTP endpoint MUST use in formulating both the INIT and
+    INIT-ACK chunks.
+
+
+Table Of Contents
+
+
+
+
+1. Introduction
+
+
+    Stream Control Transmission Protocol [RFC2960] provides transparent
+    multi-homing to its upper layer users. This multi-homing is
+    accomplished through the passing of address parameters in the
+    initial setup message used by SCTP. In an IPv4 network all addresses
+    are passed with no consideration for their scope and routeablility.
+    In a IPv6 network special considerations MUST be made to properly
+    bring up associations between SCTP endpoints that have IPv6
+    [RFC2460] addresses bound within their association.  This document
+    defines those considerations and enumerates general rules
+    that an SCTP endpoint MUST use in formulating both the INIT and
+    INIT-ACK chunks.
+
+    The emphasis in the rules laid out in this document are to prevent
+    an SCTP endpoint from listing an IPv6 address that is outside of its
+    routeable scope to a peer endpoint. This will prevent black-hole
+    conditions that may cause the unexpected failure of SCTP associations.
+
+2. Conventions
+
+   The keywords MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD,
+   SHOULD NOT, RECOMMENDED, NOT RECOMMENDED, MAY, and OPTIONAL, when
+   they appear in this document, are to be interpreted as described in
+   [RFC2119].
+
+3. Special rules for IPv6 address scoping
+
+    When selecting IPv6 addresses to include as parameters in the INIT
+    chunk the following rules MUST be applied:
+
+    A1) The INIT chunk SHOULD NOT include any IPv6 Link Local
+        address parameters unless the source or destination address
+        in the IPv6 header is a Link Local address.
+
+    A2) If IPv6 Link Local address parameters are included in the 
+        INIT chunk, Link Local addresses that are NOT on the same 
+	physical Link as that of the destination or source
+        IPv6 address (found in the IPv6 header) MUST NOT be included.
+
+    A3) The INIT chunk SHOULD NOT include any IPv6 Site Local
+        address parameters unless the source or destination address
+        in the IPv6 header is a Site Local address.
+
+    A4) If IPv6 Site Local addresses are included in the INIT chunk,
+        Site Local address that are NOT on the same site MUST NOT 
+        be included.
+
+    A5) If the destination and source address of the INIT is an 
+        IPv6 Global address then the sender SHOULD NOT include any 
+        Site Local or Link Local IPv6 address parameters in the 
+        INIT chunk.
+
+    When responding to an INIT chunk and selecting IPv6 address
+    parameters to be included in the INIT-ACK chunk, the following rules
+    MUST be applied:
+
+    B1) The INIT-ACK chunk SHOULD NOT include any IPv6 Link Local
+        address parameters unless the source or destination address
+        in the IPv6 header of the INIT chunk is a Link Local address.
+
+    B2) If IPv6 Link Local address parameters are included in the 
+        INIT-ACK chunk, Link Local addresses that are NOT on the same 
+	physical Link as the source or destination address in the
+        IPv6 header of the INIT chunk MUST NOT be included.
+
+    B3) The INIT-ACK chunk SHOULD NOT include any IPv6 Site Local
+        address parameters unless the source or destination address
+        in the IPv6 header of the INIT chunk is a Site Local address.
+
+    B4) If IPv6 Site Local addresses are included in the INIT-ACK 
+        chunk, Site Local address that are NOT on the same site 
+        as the received INIT chunk MUST NOT be included.
+ 
+    B5) If the destination and source address of the INIT is an 
+        IPv6 Global address then the sender SHOULD NOT include any 
+        Site Local or Link Local IPv6 address parameters in the 
+        INIT-ACK chunk.
+
+4. Authors addresses
+
+
+   Randall R. Stewart
+   24 Burning Bush Trail.
+   Crystal Lake, IL 60012
+   USA
+   Phone: +1 815 477 2127
+   EMail: rrs@cisco.com
+
+   Stephen E. Deering
+   Cisco Systems, Inc.
+   170 West Tasman Drive
+   San Jose, CA 95134-1706
+   USA
+
+   Phone: +1 408 527 8213
+   Fax:   +1 408 527 8254
+   EMail: deering@cisco.com
+
+
+5. References
+
+   [RFC2026]  Bradner, S., "The Internet Standards Process -- Revision
+              3", BCP 9, RFC 2026, October 1996.
+
+   [RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
+              Requirement Levels", BCP 14, RFC 2119, March 1997.
+
+   [RFC2460]  S. Deering, R. Hinden, "Internet Protocol, 
+              Version 6 (IPv6) Specification." December 1998.
+
+   [RFC2960]  R. R. Stewart, Q. Xie, K. Morneault, C. Sharp,
+              H. J. Schwarzbauer, T. Taylor, I. Rytina, M. Kalla, L. Zhang,
+              and, V. Paxson, "Stream Control Transmission Protocol," RFC
+              2960, October 2000.
diff --git a/doc/draft-stewart-tsvwg-sctpscore-01.txt b/doc/draft-stewart-tsvwg-sctpscore-01.txt
new file mode 100644
index 0000000..8cf31ab
--- /dev/null
+++ b/doc/draft-stewart-tsvwg-sctpscore-01.txt
@@ -0,0 +1,560 @@
+
+
+Network Working Group                                         R. Stewart
+Internet-Draft                                       Cisco Systems, Inc.
+Expires: November 30, 2003                                     M. Tuexen
+                                      Univ. of Applied Sciences Muenster
+                                                               June 2003
+
+
+      Stream Control Transmission Protocol (SCTP) Bakeoff Scoring
+                draft-stewart-tsvwg-sctpscore-01.txt
+
+Status of this Memo
+
+   This document is an Internet-Draft and is in full conformance with
+   all provisions of Section 10 of RFC2026.
+
+   Internet-Drafts are working documents of the Internet Engineering
+   Task Force (IETF), its areas, and its working groups.  Note that
+   other groups may also distribute working documents as
+   Internet-Drafts.
+
+   Internet-Drafts are draft documents valid for a maximum of six months
+   and may be updated, replaced, or obsoleted by other documents at any
+   time.  It is inappropriate to use Internet-Drafts as reference
+   material or to cite them other than as "work in progress."
+
+   The list of current Internet-Drafts can be accessed at http://
+   www.ietf.org/ietf/1id-abstracts.txt.
+
+   The list of Internet-Draft Shadow Directories can be accessed at
+   http://www.ietf.org/shadow.html.
+
+   This Internet-Draft will expire on November 30, 2003.
+
+Copyright Notice
+
+   Copyright (C) The Internet Society (2003).  All Rights Reserved.
+
+Abstract
+
+   This memo describes some of the scoring to be used in the testing of
+   Stream Control Transmission Protocol (SCTP) at upcoming bakeoffs.
+
+
+
+
+
+
+
+
+
+
+
+Stewart & Tuexen       Expires November 30, 2003                [Page 1]
+
+Internet-Draft              Bakeoff Scoring                    June 2003
+
+
+Table of Contents
+
+   1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  3
+   2.  Base protocol  . . . . . . . . . . . . . . . . . . . . . . . .  3
+   2.1 Basic Communication  . . . . . . . . . . . . . . . . . . . . .  3
+   2.2 Beyond Basic Communication . . . . . . . . . . . . . . . . . .  4
+   3.  Protocol Extensions  . . . . . . . . . . . . . . . . . . . . .  6
+   3.1 Partial reliable SCTP  . . . . . . . . . . . . . . . . . . . .  6
+   3.2 AddIP  . . . . . . . . . . . . . . . . . . . . . . . . . . . .  6
+   4.  Bonus Points . . . . . . . . . . . . . . . . . . . . . . . . .  7
+       References . . . . . . . . . . . . . . . . . . . . . . . . . .  7
+       Authors' Addresses . . . . . . . . . . . . . . . . . . . . . .  8
+       Intellectual Property and Copyright Statements . . . . . . . .  9
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart & Tuexen       Expires November 30, 2003                [Page 2]
+
+Internet-Draft              Bakeoff Scoring                    June 2003
+
+
+1. Introduction
+
+   This document will be used as a basis for point scoring at upcoming
+   SCTP bakeoffs.  Its purpose is similar to that described in RFC1025.
+   It is hoped that a clear definition of where and how to score points
+   will further the development of SCTP RFC2960 [4].
+
+   Note that while attending a bakeoff no one else will score your
+   points for you.  We trust that all implementations will faithfully
+   record their points that are received honestly.  Note also that these
+   scores are NOT to be used for marketing purposes.  They are for the
+   use of the implementations to know how well they are doing.  The only
+   reporting that will be done is a basic summary to the Transport Area
+   Working Group but please note that NO company or implementation names
+   will be attached.
+
+   Note Bene: Checksums must be enforced.   No points will be awarded if
+   the checksum test is disabled.
+
+2. Base protocol
+
+   The base protocol is described in the follwing documents:
+
+      RFC2960 [4]
+
+      RFC3309 [5]
+
+      IMPLGUIDE [6]
+
+      SCTPIPV4 [9]
+
+      SCTPIPV6 [10]
+
+
+2.1 Basic Communication
+
+   These points will be scored for EACH peer implementation that you
+   successfully communicate with.
+
+      2 points for being the sender of the INIT chunk and completing
+      setup of an association.
+
+      2 points for being the sender of the INIT-ACK chunk and completing
+      setup of an association.
+
+      1 point for sending data on the association where you sent the
+      INIT.
+
+
+
+
+Stewart & Tuexen       Expires November 30, 2003                [Page 3]
+
+Internet-Draft              Bakeoff Scoring                    June 2003
+
+
+      1 point for sending data on the association where you sent the
+      INIT-ACK.
+
+      2 points for gracefully ending the conversation by being the
+      sender of the SHUTDOWN.
+
+      2 points for gracefully ending the conversation by being the
+      sender of the SHUTDOWN-ACK.
+
+      4 points for repeating the above without reinitializing the SCTP.
+
+   In order to receive all of the above points (14) an implementation
+   will need to:
+
+   o  send a INIT chunk and setup an association.
+
+   o  send a data chunk on that association.
+
+   o  receive a data chunk on that association.
+
+   o  send a SHUTDOWN chunk and bring the association to a close.
+
+   o  receive a INIT-ACK and setup a new association (after the previous
+      one is closed).
+
+   o  send a data chunk on that association.
+
+   o  receive a data chunk on that association.
+
+   o  receive a SHUTDOWN chunk and send a SHUTDOWN-ACK and close the
+      association.
+
+   o  without restarting repeat these steps once.
+
+   You can get 5 extra points if you do not include any address
+   parameter in the INIT-/INIT-ACK chunk in case you are using ony one
+   of your addresses.
+
+2.2 Beyond Basic Communication
+
+      10 points for bring up multiple associations at the same time to
+      different implementations.  The implementation must send and
+      receive data on both associations simultaneously.
+
+      15 points for correctly handling ECN.
+
+      10 points for correctly handling both Transmission Sequence Number
+      (TSN) and Stream Sequence Number (SSN) wrap around.
+
+
+
+Stewart & Tuexen       Expires November 30, 2003                [Page 4]
+
+Internet-Draft              Bakeoff Scoring                    June 2003
+
+
+      5  points for correctly being able to process a "Kamikaze" packet
+      (AKA nastygram, christmas tree packet, lamp test segment, et al.).
+      That is, correctly handle a segment with the maximum combination
+      of features at once (e.g., a  COOKIE-ECHO, SACK, ASCONF,
+      UNKNOWN-CHUNK, SHUTDOWN).
+
+      5  additional points if the response to the "Kamikaze" packet is
+      bundled.
+
+      10 additional points if the implementation supports ECN and thus
+      the "Kamikaze" packet is expanded to include COOKIE-ECHO, SACK,
+      ECN, ASCONF, UNKNOWN-CHUNK, SHUTDOWN.
+
+      30 points for KOing your opponent with legal blows.  (That is,
+      operate a connection until one SCTP or the other crashes, the
+      surviving SCTP has KOed the other.  Legal blows are chunks that
+      meet the requirements of the specification.)
+
+      20 points for KOing your opponent with dirty blows.  (Dirty blows
+      are packets or chunks that violate the requirements of the
+      specification.)
+
+      10 points for showing your opponents checksum is disabled or using
+      the old checksum aka Adler-32 RFC3309 [5].
+
+      10 points for showing you can fast-retransmit.
+
+      10 points for showing your t3-timer retransmits to an alternate
+      destination (aka uses the multi-homed facility during
+      retransmission).
+
+      10 points for properly demonstrating the partial delivery API.
+
+      10 points for demonstrating recognition and proper handling of
+      restart.
+
+      10 points for correctly handling INIT collision.
+
+      10 points for correctly handling the STALE COOKIE case (sending of
+      the error chunk).
+
+      10 points an automatic resend of the INIT in case of a STALE
+      COOKIE with an appropiate COOKIE-PRESERVATIVE parameter such that
+      the association gets established.
+
+      10 points for doing bulk transfer for over 10 Minutes at a high
+      constant rate.
+
+
+
+
+Stewart & Tuexen       Expires November 30, 2003                [Page 5]
+
+Internet-Draft              Bakeoff Scoring                    June 2003
+
+
+      5 points for handling the restart with a data transfer after that.
+
+      10 points for proving that your opponent accepts additional
+      addresses during the restart compared to the original association.
+
+      2 points for the correct handling of an unknown chunk with high
+      order bits 00, 01, 10, and 11.  2 additional points (10 in total)
+      for handling all four cases correctly.
+
+      2 points for the correct handling of an unknown parameter with
+      high  order bits 00, 01, 10, and 11.  2 additional points (10 in
+      total) for handling all four cases correctly.
+
+
+3. Protocol Extensions
+
+3.1 Partial reliable SCTP
+
+   This extension is currently being described in PRSCTP [8]
+
+      10 points for sending a FWD-TSN to skip a "timed-out" data chunk.
+
+      10 points for correctly adopting the new cumulative-ack point
+      indicated by a FWD-TSN.
+
+      10 points for freeing data chunks to the application that were
+      held awaiting the FWD-TSN.
+
+      10 points for properly handling the partial-delivery API where the
+      last part of a message already being delivered is subjected to a
+      FWD-TSN.
+
+
+3.2 AddIP
+
+   This extension is currently being described in ADDIP [7].
+
+      10 points for adding an IP address to an existing association.
+
+      10 points for deleting an IP address from an existing association.
+
+      10 points for requesting that your peer set a primary address.
+
+      10 points for showing that you honored the request to set a
+      primary address and thus adopted a new primary address.
+
+      10 points for showing that your opponent does not do the address
+      scoping as described in SCTPIPV4 [9] and SCTPIPV6 [10] correctly.
+
+
+
+Stewart & Tuexen       Expires November 30, 2003                [Page 6]
+
+Internet-Draft              Bakeoff Scoring                    June 2003
+
+
+4. Bonus Points
+
+   You can also Bonus Points (directly from RFC1025 [1] :>)
+
+      10 points for the best excuse.
+
+      20 points for the fewest excuses.
+
+      30 points for the longest conversation.
+
+      40 points for the most simultaneous connections.
+
+      50 points for the most simultaneous connections with distinct
+      SCTPs.
+
+      50 points for hijacking an existing association between other
+      participants.
+
+References
+
+   [1]   Postel, J., "TCP and IP bake off", RFC 1025, September 1987.
+
+   [2]   Bradner, S., "The Internet Standards Process -- Revision 3",
+         BCP 9, RFC 2026, October 1996.
+
+   [3]   Bradner, S., "Key words for use in RFCs to Indicate Requirement
+         Levels", BCP 14, RFC 2119, March 1997.
+
+   [4]   Stewart, R., Xie, Q., Morneault, K., Sharp, C., Schwarzbauer,
+         H., Taylor, T., Rytina, I., Kalla, M., Zhang, L. and V. Paxson,
+         "Stream Control Transmission Protocol", RFC 2960, October 2000.
+
+   [5]   Stone, J., Stewart, R. and D. Otis, "Stream Control
+         Transmission Protocol (SCTP) Checksum Change", RFC 3309,
+         September 2002.
+
+   [6]   Stewart, R., Ong, L., Arias-Rodriguez, I., Poon, K., Conrad,
+         P., Caro, A. and M. Tuexen, "Stream Control Transmission
+         Protocol (SCTP) Implementer's Guide",
+         draft-ietf-tsvwg-sctpimpguide-08 (work in progress), March
+         2003.
+
+   [7]   Stewart, R., Ramalho, M., Xie, Q., Tuexen, M., Rytina, I.,
+         Belinchon, M. and P. Conrad, "Stream Control Transmission
+         Protocol (SCTP) Dynamic Address Reconfiguration",
+         draft-ietf-tsvwg-addip-sctp-07 (work in progress), February
+         2003.
+
+
+
+
+Stewart & Tuexen       Expires November 30, 2003                [Page 7]
+
+Internet-Draft              Bakeoff Scoring                    June 2003
+
+
+   [8]   Stewart, R., Ramalho, M., Xie, Q., Tuexen, M. and P. Conrad,
+         "SCTP Partial Reliability Extension",
+         draft-stewart-tsvwg-prsctp-03 (work in progress), March 2003.
+
+   [9]   Stewart, R. and M. Tuexen, "IPv4 Address handling for SCTP",
+         draft-stewart-tsvwg-sctpipv4-00 (work in progress), May 2002.
+
+   [10]  Stewart, R. and S. Tuexen, "IPv6 addressing and Stream Control
+         Transmission Protocol", Internet-Draft
+         ddraft-stewart-tsvwg-sctpipv6-01, April 2002.
+
+
+Authors' Addresses
+
+   Randall R. Stewart
+   Cisco Systems, Inc.
+   8725 West Higgins Road
+   Suite 300
+   Chicago, IL  60631
+   USA
+
+   Phone: +1-815-477-2127
+   EMail: rrs@cisco.com
+
+
+   Michael Tuexen
+   Univ. of Applied Sciences Muenster
+   Stegerwaldstr. 39
+   48565 Steinfurt
+   Germany
+
+   EMail: tuexen@fh-muenster.de
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart & Tuexen       Expires November 30, 2003                [Page 8]
+
+Internet-Draft              Bakeoff Scoring                    June 2003
+
+
+Intellectual Property Statement
+
+   The IETF takes no position regarding the validity or scope of any
+   intellectual property or other rights that might be claimed to
+   pertain to the implementation or use of the technology described in
+   this document or the extent to which any license under such rights
+   might or might not be available; neither does it represent that it
+   has made any effort to identify any such rights.  Information on the
+   IETF's procedures with respect to rights in standards-track and
+   standards-related documentation can be found in BCP-11.  Copies of
+   claims of rights made available for publication and any assurances of
+   licenses to be made available, or the result of an attempt made to
+   obtain a general license or permission for the use of such
+   proprietary rights by implementors or users of this specification can
+   be obtained from the IETF Secretariat.
+
+   The IETF invites any interested party to bring to its attention any
+   copyrights, patents or patent applications, or other proprietary
+   rights which may cover technology that may be required to practice
+   this standard.  Please address the information to the IETF Executive
+   Director.
+
+
+Full Copyright Statement
+
+   Copyright (C) The Internet Society (2003).  All Rights Reserved.
+
+   This document and translations of it may be copied and furnished to
+   others, and derivative works that comment on or otherwise explain it
+   or assist in its implementation may be prepared, copied, published
+   and distributed, in whole or in part, without restriction of any
+   kind, provided that the above copyright notice and this paragraph are
+   included on all such copies and derivative works.  However, this
+   document itself may not be modified in any way, such as by removing
+   the copyright notice or references to the Internet Society or other
+   Internet organizations, except as needed for the purpose of
+   developing Internet standards in which case the procedures for
+   copyrights defined in the Internet Standards process must be
+   followed, or as required to translate it into languages other than
+   English.
+
+   The limited permissions granted above are perpetual and will not be
+   revoked by the Internet Society or its successors or assignees.
+
+   This document and the information contained herein is provided on an
+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+
+
+
+Stewart & Tuexen       Expires November 30, 2003                [Page 9]
+
+Internet-Draft              Bakeoff Scoring                    June 2003
+
+
+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+Acknowledgement
+
+   Funding for the RFC Editor function is currently provided by the
+   Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart & Tuexen       Expires November 30, 2003               [Page 10]
+
diff --git a/doc/ols.sty b/doc/ols.sty
new file mode 100644
index 0000000..5e5fe49
--- /dev/null
+++ b/doc/ols.sty
@@ -0,0 +1,56 @@
+
+% TEMPLATE for Usenix papers, specifically to meet requirements of
+%  TCL97 committee.
+% originally a template for producing IEEE-format articles using LaTeX.
+%   written by Matthew Ward, CS Department, Worcester Polytechnic Institute.
+% adapted by David Beazley for his excellent SWIG paper in Proceedings,
+%   Tcl 96
+% turned into a smartass generic template by De Clarke, with thanks to
+%   both the above pioneers
+% use at your own risk.  Complaints to /dev/null.
+% make it two column with no page numbering, default is 10 point
+
+% adapted for Ottawa Linux Symposium
+
+% include following in document.
+%\documentclass[twocolumn]{article}
+%\usepackage{usits,epsfig}
+\pagestyle{empty}
+
+%set dimensions of columns, gap between columns, and space between paragraphs
+%\setlength{\textheight}{8.75in}
+\setlength{\textheight}{9.0in}
+\setlength{\columnsep}{0.25in}
+\setlength{\textwidth}{6.45in}
+\setlength{\footskip}{0.0in}
+\setlength{\topmargin}{0.0in}
+\setlength{\headheight}{0.0in}
+\setlength{\headsep}{0.0in}
+\setlength{\oddsidemargin}{0in}
+%\setlength{\oddsidemargin}{-.065in}
+%\setlength{\oddsidemargin}{-.17in}
+\setlength{\parindent}{0pc}
+\setlength{\parskip}{\baselineskip}
+
+% started out with art10.sty and modified params to conform to IEEE format
+% further mods to conform to Usenix standard
+
+\makeatletter
+%as Latex considers descenders in its calculation of interline spacing,
+%to get 12 point spacing for normalsize text, must set it to 10 points
+\def\@normalsize{\@setsize\normalsize{12pt}\xpt\@xpt
+\abovedisplayskip 10pt plus2pt minus5pt\belowdisplayskip \abovedisplayskip
+\abovedisplayshortskip \z@ plus3pt\belowdisplayshortskip 6pt plus3pt
+minus3pt\let\@listi\@listI} 
+
+%need a 12 pt font size for subsection and abstract headings
+\def\subsize{\@setsize\subsize{12pt}\xipt\@xipt}
+
+%make section titles bold and 12 point, 2 blank lines before, 1 after
+\def\section{\@startsection {section}{1}{\z@}{24pt plus 2pt minus 2pt}
+{12pt plus 2pt minus 2pt}{\large\bf}}
+
+%make subsection titles bold and 11 point, 1 blank line before, 1 after
+\def\subsection{\@startsection {subsection}{2}{\z@}{12pt plus 2pt minus 2pt}
+{12pt plus 2pt minus 2pt}{\subsize\bf}}
+\makeatother
diff --git a/doc/ols.tex b/doc/ols.tex
new file mode 100644
index 0000000..1e47606
--- /dev/null
+++ b/doc/ols.tex
@@ -0,0 +1,720 @@
+% TEMPLATE for Usenix papers, specifically to meet requirements of
+%  TCL97 committee.
+% originally a template for producing IEEE-format articles using LaTeX.
+%   written by Matthew Ward, CS Department, Worcester Polytechnic Institute.
+% adapted by David Beazley for his excellent SWIG paper in Proceedings,
+%   Tcl 96
+% turned into a smartass generic template by De Clarke, with thanks to
+%   both the above pioneers
+% use at your own risk.  Complaints to /dev/null.
+% make it two column with no page numbering, default is 10 point
+
+% Munged by Fred Douglis <douglis@research.att.com> 10/97 to separate
+% the .sty file from the LaTeX source template, so that people can
+% more easily include the .sty file into an existing document.  Also
+% changed to more closely follow the style guidelines as represented
+% by the Word sample file. 
+% This version uses the latex2e styles, not the very ancient 2.09 stuff.
+
+% adapted for Ottawa Linux Symposium
+
+\documentclass[twocolumn]{article}
+\usepackage{ols,epsfig}
+\begin{document}
+
+%Remove this next line if your system defaults correctly.
+\special{papersize=8.5in,11in}
+
+%don't want date printed
+\date{}
+
+%make title bold and 14 pt font (Latex default is non-bold, 16 pt)
+\title{\Large \bf Linux Kernel SCTP : The Third Transport}
+
+%for single author (just remove % characters)
+\author{
+La~Monte H.P.\ Yarroll \\
+%{\em Your Department} \\
+{\em Motorola GTSS}\\
+%{\em Your City, State, ZIP}\\
+% is there a standard format for email/URLs??
+% remember that ~ doesn't do what you expect, use \~{}.
+{\normalsize piggy@acm.org} \\
+%
+% copy the following lines to add more authors
+\and
+Karl Knutson \\
+{\em Motorola GTSS}\\
+%% is there a standard format for email/URLs??
+{\normalsize karl@athena.chicago.il.us}
+%
+} % end author
+
+\maketitle
+
+% You have to do this to suppress page numbers.  Don't ask.
+\thispagestyle{empty}
+\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\subsection*{Abstract}
+% nuked italics -- FD
+
+The Stream Control Transmission Protocol (SCTP) is a reliable
+message-oriented protocol with transparent support for multihoming.
+It allows multiple independent complex exchanges which all share a
+single connection and congestion context.
+
+We provide an overview of the protocol, the UDP-style API and the
+details of the Linux kernel reference implementation.  The brief API
+discussion is intended for developers wishing to use SCTP.  The
+detailed implementation discussion is for developers interested in
+contributing to the kernel development effort.
+
+\section{Introduction}
+
+The developers at the Linux 2.5 Kernel Summit in San Jose achieved a
+rough consensus that 2.5 should probably support SCTP, a new transport 
+protocol from the IETF.  This paper introduces the ongoing work on
+such an implementation, providing some details for both the
+application developer and the kernel developer.
+
+The Stream Control Transmission Protocol (SCTP) is a reliable
+message-oriented protocol with transparent support for multihoming.
+It allows multiple independent complex exchanges which all share a
+single connection and congestion context.
+
+\subsection{History of SCTP}
+The SIGTRAN (Signalling Transport) Working Group of the IETF is
+concerned with the transport of telephony signalling data over IP.
+Upon reviewing the available standard transport protocols, they
+concluded that none of them met the transport requirements of
+signalling data.
+
+SIGTRAN concluded that they needed a new transport protocol which
+could provide reliable message delivery, tolerate network failures,
+and avoid the head-of-line-blocking problem.  We will discuss this
+problem later.
+
+The WG selected a proposal from Randall Stewart and Qiaobing Xie of
+Motorola as a starting point.  Stewart and Xie had developed a
+Distributed Processing Environment, Quantix, aimed at telephony
+applications.  This DPE had been successfully demonstrated at Geneva
+Telecom in 1999.
+
+The Working Group took great care in constructing the new protocol,
+SCTP, incorporating many lessons learned from TCP, such as congestion
+control, selective ACK, message fragmentation and bundling.
+
+The core transport protocol from Quantix brought support for
+multihoming, message framing, and streams.  We discuss all of these
+features at length later.
+
+The IESG decided that the resulting protocol was robust enough to be
+elevated from a specialised transport for telephony signalling to a new
+general purpose transport to stand beside UDP and TCP.  To this end,
+they moved the work from SIGTRAN to TSVWG, the general transport
+group.
+
+As of this writing, the core specification, \cite{rfc2960}, is at Proposed
+Standard.  There have been three successful bakeoffs covering over 25
+separate implementations.  Lessons learned from the most recent
+bakeoff are being written up in an ``Implementor's Guide'', \cite{impl}.
+
+\subsection{SCTP in the Linux kernel}
+
+Shortly before the first bakeoff, the IESG asked SIGTRAN to move SCTP
+from riding on UDP to riding directly on top of IP.  The long term
+goal was clearly was to move SCTP from user space into the kernel.
+
+Aside from the obvious performance gains, this has the effect of
+reducing the number of implementations to roughly one per operating
+system.  This makes it easier to verify the stability of most of the
+implementations which appear on the Internet.
+
+Randall Stewart saw the importance of this and started one of the
+authors of this paper working on a port of the user space
+implementation to the Linux kernel.  This port was intended as a
+reference for developers of implementations for other kernels to
+examine.  The Linux kernel implementation has since diverged
+significantly from the user space reference, but maintains the
+standards of a reference implementation (see Coding Standards, below).
+
+\subsection{SCTP examples}
+
+SCTP is a reliable message-oriented protocol with transparent support
+for multihoming.  It allows multiple independent complex exchanges
+which all share a single connection and congestion context.
+
+Many network applications operate by exchanging simultaneously, short,
+similar sequences of data continuously.  The traffic produced by these
+operations can be characterised as MICE (Multiple Independent Complex
+Exchanges).  It is also true that many applications which use MICE
+also have high network reliability requirements.
+
+\subsubsection{A database app}
+One example is a client/server database application.  Each request and
+each response is a message.  Each transaction is a sequence of
+dependent request/response pairs.
+
+Implemented over TCP, this application would have to provide its own
+message boundaries, since TCP sends bytes, not messages.  How do we
+implement MICE with TCP?  We have two ways of doing this:  multiple
+connections, or a single multiplexed and reused connection.
+
+With each transaction over a separate TCP connection, we gain the
+independence of transactions, but at a cost in performance. Since TCP
+(as a general purpose transport protocol) uses congestion control,
+each of the connections would have to go through slow-start and if
+most transactions were short, they would never get out of slow-start.
+
+With all transactions over a single TCP connection, we make efficient
+use of the network bandwidth, but open ourselves up to the
+head-of-line blocking problem.  This means that if one segment in one
+transaction is lost, this blocks all transactions, not just the one
+with the lost segment.
+
+If we use SCTP for the same application we gain the benefits of using
+TCP, as well as advantages peculiar to SCTP.  SCTP directly supports
+messages and guarantees TCP-like levels of bandwidth efficiency via
+bundling and fragmentation.  Each database transaction can be
+represented as an ordered stream of messages, which are independent in
+SCTP for retransmission purposes.  This means that while SCTP has the
+same congestion control mechanisms as TCP, it does not have to resort
+to multiple connections nor is it vulnerable to the head-of-line
+blocking problem.
+
+\subsubsection{A free clinic}
+
+Another example of SCTP use is for a free\footnote{Free as in ``free
+beer''.} clinic which needs a reliable way to use its IP-networked
+patient monitoring software.
+
+This has many similarities to the example above in that different
+monitoring devices would need to send simultaneous
+information---multiple independent complex exchanges.  The main
+difference is in the higher network reliability requirements.  
+
+A reasonable way to improve the network reliability is to set up a
+parallel network and use multihoming for the client and server
+applications. However, if the application is TCP-based, the
+multihoming needs to be added to the application.  With SCTP, the
+multihoming ability is built into the protocol.  All that is necessary
+is to make the appropriate socket calls and SCTP will take advantage
+of the addresses available in the existing network.  This also applies
+if one side of the connection has more addresses than the other.
+
+\section{The UDP-style API}
+
+Any new protocol needs an API.  In particular for an Internet
+protocol, it's important to have the API match the API normally used
+for IP networks.  This is the Berkeley sockets model---the SCTP
+version is defined in the Internet Draft ``Sockets API Extensions for
+SCTP''\cite{api}.  The API draft defines two complementary interfaces
+to SCTP--one for compatibility with older TCP-based applications, and
+another for new applications designed expressly to use SCTP.  The
+Linux Kernel SCTP stack does not yet implement the former, so we
+discuss only the UDP-style interface.
+
+The conceptual model of the UDP-style API is (naturally) that of plain
+UDP.  To send a message in UDP, you create a socket, bind an address
+to it and send your message using \texttt{sendmsg()}. To receive a
+message in UDP, you create a socket, bind an address to it and use
+\texttt{recvmsg()}.  It's much the same with the UDP-style API for
+SCTP.  To send a message, you create a socket, bind \textit{addresses}
+to it and use \texttt{sendmsg()}.  The SCTP stack underlying the API
+handles association startup and shutdown automatically.  The same goes
+for message reception.  To receive a message in UDP-style, you create
+a socket, bind \textit{addresses} to it and use \texttt{recvmsg()}.
+
+The important API differences between UDP and UDP-style SCTP are:
+multihoming; ancillary data; and the option of notifications from the
+SCTP stack.
+
+\subsection{Multihoming and \texttt{bindx()}}
+
+There are three ways to work with multihoming with SCTP.  One is to
+ignore multihoming and use one address.  Another way is to bind all
+your addresses through the use of \texttt{INADDR\_ANY} or
+\texttt{IN6ADDR\_ANY}.  This will ``associate the endpoint with the
+optimal subset of available local interfaces.''(Section 3.1.2,
+\cite{api})  The most flexible way is through the use of
+\texttt{sctp\_bindx()}, which allows additional addresses to be
+added to a socket after the first one is bound with \texttt{bind()},
+but before the socket is used to transfer or receive data.  The
+function \texttt{sctp\_bindx()} is further described in section 8.1 of
+\cite{api}.
+
+\subsection{Ancillary data}
+
+To use streams with the UDP-style API, you use ancillary data in the
+\texttt{struct~cmsghdr} part of the \texttt{struct~msghdr} argument to
+both \texttt{sendmsg()} and \texttt{recvmsg()}.  Ancillary data is
+used for initialisation data (\texttt{struct~sctp\_initmsg} and for
+header data (\texttt{struct~sctp\_sndrcvinfo}).
+
+Ancillary data are manipulated with the macros \texttt{CMSG\_FIRSTHDR,
+CMSG\_NEXTHDR, CMSG\_DATA, CMSG\_SPACE, \textnormal{and} CMSG\_LEN}.
+These are all defined in \cite{rfc2292}.  \cite{api} provides a nice
+example in section 5.4.2.
+
+{\tt \small
+\begin{verbatim}
+    struct sctp_initmsg {
+       uint16_t sinit_num_ostreams;
+       uint16_t sinit_max_instreams;
+       uint16_t sinit_max_attempts;
+       uint16_t sinit_max_init_timeo;
+    };
+\end{verbatim}
+}
+
+The initialisation ancillary data sets information for starting 
+new associations.
+
+{\tt \small
+\begin{verbatim}
+    struct sctp_sndrcvinfo {
+       uint16_t sinfo_stream;
+       uint16_t sinfo_ssn;
+       uint16_t sinfo_flags;
+       uint32_t sinfo_ppid;
+       uint32_t sinfo_context;
+       uint8_t sinfo_dscp;
+       sctp_assoc_t sinfo_assoc_id;
+    };
+\end{verbatim}
+}
+
+The header ancillary data reports information gleaned from the SCTP
+headers.  If requested with the \texttt{SCTP\_RECVDATAIOEVNT} socket
+option, this ancillary data is provided with every inbound data
+message.  There is a handy key (\texttt{sinfo\_assoc\_id}) which
+identifies the association for this particular message.  It also
+provides the flags needed to implement partial delivery of very large
+messages.
+
+Outbound messages should include an \texttt{sctp\_sndrcvinfo} ancillary 
+data structure to tell SCTP which SCTP stream to put this datagram
+into.  It is also possible to set a default stream so that this
+ancillary data may be omitted.
+
+\subsection{Notifications}
+
+SCTP provides for the concept of optional notifications.  These are
+messages delivered in-band about events inside the SCTP stack, such as
+a destination transport address failure or a new association coming
+up.  The notifications are marked with the \texttt{MSG\_NOTIFICATION}
+flag in the \texttt{msg\_flags} field of the \texttt{sctp\_sendrcvinfo}
+ancillary data.  The notification is delivered as the body of the
+message returned by \texttt{recvmsg()}.
+
+In \ref{notifications} we find a table of notifications.  Each
+notification delivers its own data structure which shares the same
+name (lower case, naturally) as the notification type itself.  The first
+field of every notification is a \texttt{uint16\_t} which caries the
+notification type.
+
+\begin{figure*}[t]
+\begin{center}
+{\tt
+\begin{tabular}{ l  l  l }
+   \hline
+   \textnormal{Type} & \textnormal{Socket Option} & \textnormal{Description} \\
+   \hline
+   SCTP\_ASSOC\_CHANGE 		& SCTP\_RECVASSOCEVNT	&  \textnormal{Change of association} \\
+   SCTP\_PEER\_ADDR\_CHANGE	& SCTP\_RECVADDREVNT	& \textnormal{Change in status of a given address} \\
+   SCTP\_REMOTE\_ERROR		& SCTP\_RECVPEERERR	& \textnormal{An error received from a peer} \\
+   SCTP\_SEND\_FAILED		& SCTP\_RECVSENDFAILEVNT & \textnormal{A failure to send} \\
+   SCTP\_SHUTDOWN\_EVENT	& SCTP\_RECVDOWNEVNT	& \textnormal{The reception of a \texttt{SHUTDOWN} chunk} \\
+\end{tabular}
+}
+\end{center}
+\caption{\label{notification}Useful notifications for an SCTP socket}
+\end{figure*}
+
+\section{The lksctp Project}
+
+A critical factor in the success of any new IETF protocol is of course
+a Linux implementation.  Fortunately, key personnel at Motorola
+recognised this and encouraged us to tackle such a project.  Months
+later, we have a core implementation with an ever-expanding feature
+set.  We now have significant participation from developers at IBM and
+Intel and the pace is picking up.
+
+\subsection{Coding standards}
+
+In addition to the usual requirements of kernel code, our code seeks
+to be a useful reference for people making their own kernel
+implementations of SCTP.  If a reader has some question about how to
+implement a particular section of the RFC, they need only grep for the
+relevant text in our code and they can find an example.  As much as
+practical, we draw names directly from the RFC.  We made the state
+machine into an explicit table (see \ref{states} for an
+excerpt) with names that refer directly back to the relevant section
+numbers.  Clarity is a compelling requirement for our code.
+
+\subsection{Extreme Programming}
+
+As the project grew and we added developers, we clearly needed some
+way of coordinating our work.  We decided to experiment with Extreme
+Programming, \cite{xp}.
+
+XP is a collection of practices aimed at controlling risk in a small
+to medium-sized software development project.  One important principle
+is that you should do the simplest thing that could possibly work.  A
+second important principle is to take advantage of the fact that
+programmers like to code.
+
+We use a range of XP practices, but the practices which are most
+visible to anybody who reads or works on lksctp are the tests and the
+metaphors.
+
+\section{The Tests}
+
+One of the XP practices we use is code-to-the-test.  XP asks, ``If
+testing is good, why don't we do it all the time?'' Instead of writing
+tests for working code, write tests first, and then write code to pass
+the tests.  This practice leads to a large automated test suite which
+runs several times per day.
+
+We use three kinds of test, unit tests, test frame functional tests,
+and live kernel functional tests.
+
+The most basic form of test is the unit test.  Unit tests exercise all
+the interfaces of a particular object and confirm that it behaves
+correctly.  They also encode regression checks for fixed bugs.  These
+tests all have names beginning with \texttt{test\_}.
+
+The second form of test is the test frame functional tests.  These are
+the tests with names beginning with \texttt{ft\_frame\_}.  These tests
+check for external behaviours of the system, but with a simulated
+kernel.  The simulated kernel is very light weight and gives us very
+fine control over things like timing and network properties.
+
+Ideally, functional tests should be written by the customer for a
+system---they encode the behaviours that the customer expects.  In our
+case, we play the role of customer on behalf of the RFC.  We also use
+test frame functional tests to define work items for off-site
+development groups.  The off-site group writes tests which describe the 
+feature they intend to implement and submits those tests as a
+proposal.  This has proven an excellent medium for describing work.
+
+The final form of test we use is the live kernel functional test.  We
+have many fewer of these than we would like---they are difficult to run 
+since we must install and boot a kernel to test.  This is much more
+work than simply running \texttt{make unit\_test}. We are exploring UML as 
+a possible way to automate our kernel functional tests.  These tests
+have names beginning with \texttt{ft\_kern\_}.
+
+Code-to-the-test is a practice which you can introduce at any point in 
+a project.  When you first start, it seems that you are spending more
+time writing tests than writing code, but once you begin to have a
+critical mass of interacting tests you begin to see significant
+payoffs in both code quality and development velocity.
+
+We have had several incidents where interactions between unit tests
+and functional tests have uncovered complimentary masking bugs.
+
+Tests are not a substitute for understanding code---they are a
+mechanism for encoding that understanding to share with other
+developers, including future versions of yourself.  You can learn
+nearly as much about our code by reading our tests as by reading the
+code itself.
+
+Lately, we have begun using functional tests to encode major bugs.
+These are among the best of all possible bug reports---they describe
+the failure precisely and tell exactly when the problem is gone.
+After the bugs are fixed the tests serve as part of the regression
+suite.
+
+\section{The Metaphors}
+
+XP projects are built around a unifying metaphor rather than an
+elaborate architecture.  In our case, we chose two metaphors which
+could serve quite well for nearly any protocol development project.
+
+Our metaphors are the state machine and the smart pipe.  Most readers
+are probably familiar with the state machine, but the smart pipe is a
+twist on a familiar concept.  The idea behind a smart pipe\footnote{An
+alternate term may be ``oven''.} is that raw stuff goes in one end and
+cooked stuff comes out the other end.
+
+\subsection{The State Machine}
+
+The state machine in our implementation is quite literal.  We have an
+explicit state table which keys to specific state functions which are
+tied directly back to parts of the RFC.  The core of the state machine
+(found in \texttt{sctp\_do\_sm()}) is almost purely functional---only header
+conversions are permitted.  Each state function produces a description
+of the side effects (in the form of a \texttt{struct~sctp\_sm\_retval})
+needed to handle the particular event.  A separate side effect
+processor, \texttt{sctp\_side\_effects()}, converts this structure into
+actions.
+
+Events fall into four categories.  The RFC is very explicit about
+state transitions associated with arriving chunks.  The RFC discusses
+transitions due to primitive requests from upper layers, but many of
+these are implementation dependent.  The third category of events is
+timeouts.  The final category is a catch-all for odd events like
+queues emptying.
+
+\begin{figure*}[t]
+\begin{center}
+{\tt
+\begin{tabular}{ l  l  l  l  l }
+   \hline
+   \textnormal{State:}	& CLOSED	& COOKIE-WAIT	& COOKIE-ECHOED	& ESTABLISHED \\
+   \hline
+   \hline
+   \textnormal{Chunks}	&		&		&		& \\
+   \hline
+
+   INIT         & do\_5\_1B\_init & do\_5\_2\_1\_siminit & do\_5\_2\_1\_siminit & do\_5\_2\_2\_dupinit \\
+   INIT ACK     & discard(5.2.3) & do\_5\_1C\_ack	& discard(5.2.3) & discard(5.2.3)	\\
+   COOKIE ECHO	& do\_5\_1D\_ce	& do\_5\_2\_4\_dupcook& do\_5\_2\_4\_dupcook& do\_5\_2\_4\_dupcook \\
+   COOKIE ACK	& discard	& discard(5.2.5) & do\_5\_1E\_ca & discard(5.2.5)    		\\
+   DATA		& tabort\_8\_4\_8 & discard(6.0) & discard(6.0) & eat\_data\_6\_2		\\
+   SACK		& tabort\_8\_4\_8 & discard(6.0) & eat\_sack\_6\_2\_1 & eat\_sack\_6\_2\_1      \\
+
+   \hline
+   \textnormal{Timeouts} &	&		&		& \\
+   \hline
+
+   T1-INIT TO	& bug           & do\_4\_2\_reinit & bug	& bug \\
+   T3-RTX TO	& bug           & bug		& do\_6\_3\_3\_retx & do\_6\_3\_3\_retx \\
+
+   \hline
+   \textnormal{Primitives} &	&		&		& \\
+   \hline
+
+   PRM\_ASSOCIATE & do\_PRM\_ASOC & error	& error		& error \\
+   PRM\_SEND	& error		& do\_PRM\_SENDQ6.0 & do\_PRM\_SENDQ6.0 & do\_PRM\_SEND \\
+
+\end{tabular}
+}
+\end{center}
+\caption{\label{states}Portion of SCTP state table showing association initialisation}
+\end{figure*}
+
+In order to create an explicit state machine, it was necessary to
+first create an explicit state table.  The process of creating this
+table uncovered a few minor contradictions in one of the drafts of the 
+RFC.  These mostly involved conflicting catch-all cases.  In Figure 1
+we have an excerpt which shows the state functions involved in
+initialising a new association.
+
+\subsection{The Smart Pipes}
+
+Each smart pipe has one or more structures which define its internal
+data, and a set of functions which define its external interactions.
+In this respect these smart pipes can be considered a type of object,
+in the OO sense.  All of these definitions can be found in the include 
+file \texttt{<net/sctp/sctpStructs.h>}.
+
+Most of our smart pipes have push inputs---external objects explictly
+put things in by calling methods directly.  A pull input is
+possible---the smart pipe would need to have a way to register a
+callback function which can fetch more input in response to some other 
+stimulus.
+
+Some of our pipes use pull outputs.  E.g. \texttt{SCTP\_ULPqueue} passes
+data and notifications up the protocol stack through explicit calls to
+the socket functions, usually \texttt{readmsg(2)}.  Some of our smart
+pipes use push outputs.  E.g. \texttt{SCTP\_outqueue} has a set of
+callback functions which it invokes when it needs to send chunks out
+toward the wire.
+
+There are four smart pipes in lksctp.  They are
+\texttt{SCTP\_inqueue}, \texttt{SCTP\_ULPqueue},
+\texttt{SCTP\_outqueue}, and \texttt{SCTP\_packet}.  The first two
+carry information up the stack from the wire to the user; the second
+two carry information back down the stack. 
+
+\subsubsection{\texttt{SCTP\_inqueue}}
+
+\texttt{SCTP\_inqueue} accepts packets and provides chunks.  It is
+responsible for reassembling fragments, unbundling, tracking received
+TSN's for acknowledgement, and managing rwnd for congestion control.
+There is an \texttt{SCTP\_inqueue} for each endpoint (to handle chunks
+not related to a specific association) and one for each association.
+
+The function \texttt{sctp\_v4\_rcv()} (which is the receiving function
+for SCTP registered with IPv4) calls \texttt{sctp\_push\_inqueue()} to
+push packets into the input queue for the appropriate association or
+endpoint.  The function \texttt{sctp\_push\_inqueue()} schedules
+either \texttt{sctp\_bh\_rcv\_asoc()} or \texttt{sctp\_bh\_rcv\_ep()}
+on the immediate queue to complete delivery.  These functions call
+\texttt{sctp\_pop\_inqueue()} to pull data out of the
+\texttt{SCTP\_inqueue}.  This function does most of the work for this
+smart pipe.
+
+The functions \texttt{sctp\_bh\_rcv\_ep()} and
+\texttt{sctp\_bh\_rcv\_asoc()} run the state machine on incoming
+chunks.  Among many other side effects, the state machine can generate
+events for an upper-layer-protocol (ULP), and/or chunks to go back out
+on the wire.
+
+\subsubsection{\texttt{SCTP\_ULPqueue}}
+
+\texttt{SCTP\_ULPqueue} is the smart pipe which accepts events (either
+user data messages or notifications) from the state machine and
+delivers them to the ULP through the sockets layer.  It is responsible
+for delivering streams of messages in order.  There is one
+\texttt{SCTP\_ULPqueue} for every endpoint, but this is likely to
+change at some point to one \texttt{SCTP\_ULPqueue} for each socket.
+This smart pipe uses a data structure distributed between the
+\texttt{struct~SCTP\_endpoint} and the
+\texttt{struct~SCTP\_association}.
+
+The state machine, \texttt{sctp\_do\_sm()}, pushes data into an
+\texttt{SCTP\_ULPqueue} by calling
+\texttt{sctp\_push\_chunk\_ULPqueue()}.  It pushes notifications with
+\texttt{sctp\_push\_event\_ULPqueue()}.  The sockets layer extracts
+events from an \texttt{SCTP\_ULPqueue} with
+\texttt{sctp\_pop\_ULPqueue()}. 
+
+\subsubsection{\texttt{SCTP\_outqueue}}
+
+\texttt{SCTP\_outqueue} is responsible for bundling logic, transport
+selection, outbound congestion control, fragmentation, and any
+necessary data queueing.  It knows whether or not data can go out onto
+the wire yet.  With one exception noted below, every outbound chunk
+goes through an \texttt{SCTP\_outqueue} attached to an association.
+The state machine injects chunks into an \texttt{SCTP\_outqueue} with
+\texttt{sctp\_push\_outqueue()}.  They automatically push out the other
+end through a small set of callbacks which are normally attached to an
+\texttt{SCTP\_packet}.
+
+The state machine is capable of putting a fully-formed packet directly
+on the wire.  At this point only \texttt{ABORT} uses this feature.  It is
+likely that we will refactor \texttt{INIT ACK} generation again to use
+this feature.
+
+\subsubsection{\texttt{SCTP\_packet}}
+
+An \texttt{SCTP\_packet} is a lazy packet transmitter associated with a
+specific transport.  The upper layer pushes data into the packet,
+usually with \texttt{sctp\_transmit\_chunk()}.  The packet blindly
+bundles the chunks.  If the it fills (hits the PMTU for its transport),
+it transmits the packet to make room for the new chunk.
+\texttt{SCTP\_packet} rejects packets which need fragmenting.  It is
+possible to force a packet to transmit immediately with
+\texttt{sctp\_transmit\_packet()}.  \texttt{SCTP\_packet} tracks the
+congestion counters, but handles none of the congestion logic.
+
+\section{More Data Structures}
+
+Not everything is a state table or a smart pipe---after all, this is
+the kernel and we ARE programming in C.  Here again, we have followed
+the RFC very closely.  Most of the key concepts in the RFC manifest
+themselves as explicit data structures.  For convenience, we refer to
+these data structures as ``nouns''.
+
+Nearly all of the ``noun'' structures are designed for use with the
+\texttt{sk\_buff} macros for list manipulation.  These macros provide a
+doubly-linked list with locking.
+
+\subsection{\texttt{struct~SCTP\_proto}}
+
+The entire lksctp universe is grounded in an instance of \texttt{
+struct~SCTP\_proto} accessible through \texttt{sctp\_get\_protocol()}.
+This structure holds system-wide defaults for things like the maximum
+number of permitted retransmissions.  It contains a list of all
+endpoints on the system.
+
+\subsection{\texttt{struct~SCTP\_endpoint}}
+
+Each UDP-style SCTP socket has an endpoint, represented as a
+\texttt{struct~SCTP\_endpoint}.  Once we implement high-bandwidth sockets and
+TCP-style sockets, it will be possible for multiple sockets to share a
+single endpoint structure.  The endpoint structure contains a local
+SCTP socket number and a list of local IP addresses.  These two items
+define the endpoint uniquely.  In addition to endpoint-wide default
+values and statistics, the endpoint maintains a list of associations.
+
+\subsection{\texttt{struct~SCTP\_association}}
+
+Each association structure, \texttt{struct~SCTP\_association}) is defined
+by a local endpoint (a pointer to a \texttt{struct~SCTP\_endpoint}), and
+a remote endpoint (an SCTP port number and a list of transport
+addresses).  This is one of the most complicated structures in the
+implementation as it includes a great deal of information mandated by
+the RFC.  Among many other things, this structure holds the state of
+the state machine.  The list of transport addresses for the remote
+endpoint is more elaborate than the simple list of IP addresses in the
+local endpoint data structure since SCTP needs to maintain congestion
+information about each of the remote transport addresses.
+
+\subsection{\texttt{struct~SCTP\_transport}}
+
+A \texttt{struct~SCTP\_transport} is defined by a remote SCTP port number
+and an IP address.  The structure holds congestion and reachability
+information for the given address.  This is also where we get the list 
+of functions to call to manipulate the specific address family.  For
+TCP you would find this information way up in the socket, but this is
+not possible for SCTP.
+
+\subsection{\texttt{struct~SCTP\_chunk}}
+
+Possibly the most fundamental data structure in lksctp is
+\texttt{struct~SCTP\_chunk}.  This holds SCTP chunks both inbound and
+outbound.  It is essentially an extension to \texttt{struct~sk\_buff}.
+It adds pointers to the various possible SCTP subheaders and a few
+flags needed specifically for SCTP.  One strict convention is that
+\texttt{chunk->skb->data} is the demarcation line between headers in
+network byte order and headers in host byte order.  All outbound
+chunks are ALWAYS in network byte order.  The first function which
+needs a field from an inbound chunk converts that full header to host
+byte order {\it in situ}.
+
+\section{Acknowledgements}
+
+The authors are members of a team at Motorola dedicated to producing
+open source implementations in support of IETF standardisation.  We
+would like to thank the people who make these efforts possible,
+specifically Maureen~Govern, Stephen~Spear, Qiaobing~Xie, and
+Irfan~Ali.  We are of course deeply indebted to Randall Stewart and
+Qiaobing Xie for having created SCTP and for starting the Linux Kernel
+SCTP Implementation Project.  We wish to recognizee the ongoing and
+significant contributions from developers outside Motorola, especially
+Jon Grimm and Daisy Chang of IBM, and Xingang Guo of Intel.
+
+\section{Availability}
+
+All the code discussed in this paper is available from the lksctp
+project on Source Forge:
+
+\begin{center}
+\texttt{http://sourceforge.net/projects/lksctp/}
+\end{center}
+
+\begin{thebibliography}{2001}
+
+\bibitem[RFC2960]{rfc2960} R.~Stewart, Q.~Xie, K.~Morneault, C.~Sharp,
+H.~J.~Schwarzbauer, T.~Taylor, I.~Rytina, M.~Kalla, L.~Zhang, and,
+V.~Paxson, {\em Stream Control Transmission Protocol}, RFC~2960 (Oct~2000).
+
+\bibitem[SCTPAPI]{api} R.~Stewart, Q.~Xie, L.~H.~P.~Yarroll, J.~Wood,
+K.~Poon, K.~Fujita., {\em Sockets API Extensions for SCTP}, Work In
+Progress, \texttt{draft-ietf-tsvwg-sctpsocket-00.txt} (Jun~2001).
+
+\bibitem[SCTPIMPL]{impl} R.~Stewart. {\it et al}, 
+{\em SCTP Implementor's Guide}, Work In Progress,
+\texttt{draft-ietf-tsvwg-sctpimpguide-00.txt} (Jun~2001).
+
+\bibitem[SCTPMIB]{mib} J.~Pastor, M.~Belinchon. {\em Stream Control
+Transmission Protocol Management Information Base using SMIv2}, Work
+In Progress, \texttt{draft-ietf-sigtran-sctp-mib-03.txt} (Feb~2001).
+
+\bibitem[XP]{xp} K.~Beck. {\em Extreme Programming Explained: Embrace
+Change}, Addison-Wesley Publishers (2000).
+
+\bibitem[SCTPORG]{sctporg}{\em Randall Stewart's SCTP site},\\
+\texttt{http://www.sctp.org}, (2001).
+
+\bibitem[SCTPDE]{sctpde}{\em T\"uxen/Jungmeier SCTP site},\\
+\texttt{http://www.sctp.de}, (2001).
+
+\end{thebibliography}
+
+\end{document}
diff --git a/doc/random_notes.txt b/doc/random_notes.txt
new file mode 100644
index 0000000..fba745d
--- /dev/null
+++ b/doc/random_notes.txt
@@ -0,0 +1,729 @@
+These are more random design notes I need to keep track of.
+
+Perhaps counterWork() should be replaced with direct counter
+manipulation.  This violates the functional style of the state
+functions, but only a little bit...
+
+IRRELEVANT: The vtag return value should be subsumed into repl.
+IRRELEVANT: sctp_make_chunk() should NOT be called directly from these
+IRRELEVANT: functions. 
+
+I am very unhappy with retval->link.  That means a LOT of copying.
+
+DONE: Basic principle for host or network byte order:
+DONE:       Network byte order should be as close to the network as
+DONE:       possible.
+DONE: This means that the first routine to manipulate a particular header
+DONE:       should convert from network byte order to host byte order as
+DONE:       soon as it removes it gets it from the next lowest layer.
+DONE:       Outbound, the last routine to touch a header before passing it
+DONE:       to the next lower layer should convert it to network order.  For
+DONE:       queues, the routine at the top (closer to user space) does the
+DONE:       conversion--inbound queues are converted to host order by the
+DONE:       reader, outbound queues are converted to network order by the
+DONE:       writer.
+DONE: 
+DONE: Forget that smoke.  The problem is that this entails reparsing the
+DONE: header when it comes time to pass it to the lower layer (e.g. you need
+DONE: to check the SCTP header for optional fields).  The code which fills
+DONE: in a field should put it in network order.
+DONE: 
+DONE: POSSIBLY on inbound, the code which parses the header should convert
+DONE: it to host order...  But on outbound, packets should ALWAYS be in
+DONE: network byte order!
+
+
+OK, we need to add some stream handling.  This means that we are
+updating sctp_create_asoc() among many other functions.  I think we
+want some functions for dereferencing streams...
+
+
+DONE: NOTES FOR TSNMap
+DONE: 
+DONE: Variables:
+DONE: uint8_t *TSNMap			Array counting #chunks with each TSN
+DONE: uint8_t *TSNMapEnd		TSNMap+TSN_MAP_SIZE
+DONE: uint8_t *TSNMapOverflow		counters for TSNMapBase+TSN_MAP_SIZE;
+DONE: uint8_t *TSNMapCumulativePtr	Cell for highest CumulativeTSNAck
+DONE: uint32_t TSNMapCumulative	Actual TSN for *TSNMapCumulativePtr
+DONE: uint32_t TSNMapBase		Actual TSN for *TSNMap
+DONE: long TSNMapGap			chunk.TSN - TSNMapBase
+DONE: 
+DONE: Constants:
+DONE: TSN_MAP_SIZE
+DONE: 
+DONE: TSNMap and TSNMapOverflow point at two fixed buffers each of length
+DONE: TSN_MAP_SIZE.  When TSNMapCumulativePtr passes TSNMapEnd (i.e. we send
+DONE: the SACK including that value), we swap TSNMap and TSNMapOverflow,
+DONE: clearing TSNMap.
+DONE: 
+DONE: This work should be done OUTSIDE the state functions, as it requires
+DONE: modifying the map.  It is sufficient for the state function to return
+DONE: TSNMapGap.  Take care that TSNMapGap is never 0--we reserve this value
+DONE: to mean "no TSNMapGap".
+
+
+DONE: FIGURE THIS OUT--which structures represent PEER TSN's and which
+DONE: structures represent OUR TSN's.
+DONE: 
+DONE: Rename the elements to peerTSN* and myTSN*.
+
+
+ERROR IN Section 6.1:
+
+  Note: The data sender SHOULD NOT use a TSN that is more than 
+  2**31 - 1 above the beginning TSN of the current send window.
+
+SHOULD be 2**16-1 because of the GAP ACKs.
+
+ERROR IN 12.2 Parameters necessary per association (i.e. the TCB):
+Ack State   : This flag indicates if the next received packet 
+            : is to be responded to with a SACK. This is initialized
+            : to 0.  When a packet is received it is incremented. 
+            : If this value reaches 2 or more, a SACK is sent and the 
+            : value is reset to 0. Note: This is used only when no DATA 
+            : chunks are received out of order. When DATA chunks are 
+            : out of order, SACK's are not delayed (see Section 6).
+
+NOWHERE in Section 6 is this mentioned.  We only generate immediate
+SACKs for DUPLICATED DATA chunks.  Is this an omission in Section 6 or
+a left-over note in section 12.2?
+
+
+Section 6.1:
+
+	Before an endpoint transmits a DATA chunk, if any received DATA
+	chunks have not been acknowledged (e.g., due to delayed ack), the
+	sender should create a SACK and bundle it with the outbound DATA
+	chunk, as long as the size of the final SCTP packet does not exceed
+	the current MTU. See Section 6.2.
+
+I definately won't do this.  What AWFUL layering!
+
+We have this REALLY WIERD bugoid.  We SACK the first data chunk of the
+second packet containing data chunks.  A careful reading of the spec
+suggests that this is legal.  It kinda works, but we end up with more
+SACK timeouts than we might otherwise have...  The fix is to split off
+the SACK generation code from the TSN-handling code and run it when we
+get either a NEW packet, or an empty input queue.
+
+
+
+OK: Section 6.2 does not explicitly discuss stopping T3-rtx.  The worked
+OK: example suggests that T3-rtx should be canceled when the SACK is
+OK: lined up with the data chunk...  Ah!  Section 6.3...
+
+
+We really ought to do a sctp_create_* and sctp_free_* for all of the
+major objects including SCTP_transport.
+
+{DONE: Copy af_inet.c and hack it to support SCTP.
+
+If we were going to do SCTP as a kernel module, we'd do this:
+
+We can then socket.c:sock_unregister() the whole INET address family
+and then sock_register() our hacked af_inet...
+}
+
+
+SCTP_ULP_* is really two groups of things--request types and response
+types...
+
+DONE: We want to know whether the arguments to bind in sock.h:struct proto
+DONE: are user space addresses or kernel space addresses.  To do that we
+DONE: want to find the tcp bind call.  To do THAT we are looking for the
+DONE: place that struct proto *prot gets filled in for a TCP struct sock.
+
+
+API issue--how do you set options per association?  Normal setsockopt
+will operate on an endpoint.  This is mostly an issue for the
+UDP-style api.  The current solution (v02) is that all associations on
+a single socket should all have the same options.  I still don't like
+this.
+
+Write a free_endpoint().  Remember to free debug_name if allocated...
+
+DONE: Make sure that the API specifies a way for sendto() to use some kind
+DONE: of opaque identifier for the remote endpoint of an association.  As
+DONE: observed before, it is a bad thing to use an IP address/port pair as
+DONE: the identifier for the remote endpoint...
+
+General BUG--sctp_bind() needs to check to see if somebody else is
+already using this transport address (unless REUSE_ADDR is set...)...
+
+sctp_do_sm() is responsible for actually discarding packets.  We need
+a sctp_discard_packet_from_inqueue().
+
+Be sure to schedule the top half handling in sctp_input.c:sctp_v4_rcv().
+
+Keycode 64 is Meta_L, should be Backspace (or whatever that really
+is)...
+
+DONE: Should sctp_transmit_packet() clone the skb?  [Yes.  In fact we
+DONE: need a deep copy because of a bug in loopback.  This problem
+DONE: sort of goes away with the creation of SCTP_packet.]
+
+- memcpy_toiovec() is for copying from a blob to an iovec...
+- after(), before(), and between() are for comparing 32bit wrapable
+  numbers...
+
+Where do theobromides live?  Are they fat soluable?
+
+printf "D %x\nC %x\nI %x\nP %x\nT %x\n", retval->skb->data, retval->chunk_hdr, retval->subh.init_hdr, retval->param_hdr, retval->skb->tail
+
+
+set $chunk = retval->repl->chunk_hdr
+set $init = (struct sctpInitiation *)(sizeof(struct sctpChunkDesc) + (uint8_t *)$chunk)
+set $param1 = (struct sctpParamDesc *)(sizeof(struct sctpInitiation) + (uint8_t *)$init)
+set $param2 = (struct sctpParamDesc *)(ntohs($param1->paramLength) + (uint8_t *)$param1)
+set $sc = (struct sctpStateCookie *)$param2
+
+DONE: run_queue sctp_tq_sideffects needs while wrapper.
+
+OK: Important structures:
+OK: 	  protocol.c:	struct inet_protocol tcp_protocol (IP inbound linkage)
+OK: 	  tcp_ipv4.c:	struct proto tcp_prot (exceptions to inet_stream_ops)
+OK: 	  af_inet.c:	struct proto_ops inet_stream_ops (sockets interface)
+
+Another unimplemented feature:  sctp_sendmsg() should select an
+ephemeral port if a port is not already set...
+
+Path MTU stuff:  Send shutdown with rewound CumuTSNack.  Is this a 
+protocol violation?
+
+NO: Use larger TSN increment than 1?  Allows subsequencing [This is
+NO: patently illegal.  The correct solution involves MTU calculations...]
+
+Lowest of 3 largest MTU's for fragmentation?  Probably.
+Allows 2 RWINs worth of backup?
+
+Immediate heartbeat on secondary when primary fails?
+(Use fastest response on heartbeat to select new primary, keeping MTU in mind)
+This is probably illegal.  v13 added stricter rules about generating
+heartbeats.
+
+[p- use 3 largest RWINs to select...]
+
+[jm- pick top 3 thruputs (RWIN/Latency), pick lowest MTU for the new primary
+ address ]
+
+
+Here is what we did to set up the repository:
+
+$ cd /usr/src/linux_notes
+$ bzcat ~/linux-2.4.0-test11.tar.bz2 | tar xfp -
+$ CVSROOT=:pserver:knutson@postmort.em.cig.mot.com:/opt/cvs
+$ export CVSROOT
+$ cd linux
+$ cvs import -m "plain old 2.4.0 test11" linux knutson start
+[Note that this EXCLUDES net/core.]
+$ cd ..
+$ mv linux linux-2.4.0-test11
+$ cvs co linux
+$ cd linux-2.4.0-test11/net
+$ tar cfv - core | (cd ../../linux/net;tar xfp -)
+$ cd ../../linux
+$ cvs add net/core
+$ cvs add net/core/*.c
+$ cvs add net/core/Makefile
+$ cd net
+$ cvs commit -m "add core"
+$ cd ..
+[Now we create the branch.]
+$ cvs tag -b uml
+[Move to that branch.]
+$ cvs update -r uml
+$ touch foo
+$ bzcat ~/patch-2.4.0-test11.bz2 | patch -p1
+$ for a in $(find . -newer foo | grep -v CVS); do echo $a; cvs add $a; done 2>&1 | tee ../snart
+$ cvs commit -m "UML patch for 2.4.0-test11"
+$ cvs tag latest_uml
+
+2001 Jan 11
+When we close the socket, it shouldn't de-bind the endpoint.  Any new
+socket attempting to bind that endpoint should get an error until that
+endpoint finally dies (from all of its associations dying).
+
+This issue comes up with the question of what should happen when we
+close the socket and attempt to immediately open a new socket and bind
+the same endpoint.  Currently, we could bind the same endpoint in SCTP
+terms which would be a new endpoint in data structure terms and buy
+ourselves some confusion.
+
+DONE: Tue Jan 16 23:08:51 CST 2001
+DONE: 
+DONE: We find that when we closed the socket (and nulled the ep->sk
+DONE: reference to it), we caused problems later on with chunks created for
+DONE: transmit.  When we looked at TCP, we found that closing a TCP socket
+DONE: does not destroy it immediately--TCP also has post-close transactions.
+DONE: 
+DONE: Solution:  We use the ep->moribund flag to indicate when the socket is
+DONE: closed and do not immediately null the reference in ep.
+
+Wed Jan 17 01:21:40 CST 2001
+
+What happens when loop1 == loop2 in funtest1b (i.e., when the source &
+destination endpoints are identical)?  We found out.  You get a *real*
+simultaneous init and a burning desire to designate two loop addresses
+so you don't inadvertently put yourself in the same situation again.
+
+We will investigate more later, as this situation promises to test a
+potential weak point in the protocol (cf. siminit above).
+
+Tue Jan 30 14:50:39 CST 2001
+vendor: Linus
+release tag: linux-2_4_1
+
+DONE: We really ought to have a small utility functions file for test stuff
+DONE:       (both live kernel and test frame).
+
+Here are all the timers:
+T1-init (per association)
+T1-cookie (per association)
+T3-rtx (per destination)
+heartbeat timer (per association)
+T2-shutdown (per association)
+?Per Destination Timer? (presumed to be T3-rtx)
+
+Mark each chunk with the transport it was transmitted on.
+
+When we transmit a chunk, we turn on the rtx timer for the destination
+if not on already.  The chunk is then copied to q->transmitted.  When
+we receive a sack, we turn off each timer corresponding to a TSN ACK'd
+by the SACK CTSN.  This is because either everything got through, or
+the chunk outbound longest for a given destination got through.
+We then start the timers for destinations which still have chunks on
+q->transmitted, after moving the appropriate chunks to q->sacked.
+
+When a rtx timer expires for a destination, all the chunks on
+q->transmitted for that destination get moved to q->retransmit,
+which then get transmitted (a: at that time, b: when any chunks are
+transmitted, retransmissions go first, c: other).
+
+WHEN PUSHING A CHUNK FOR TRANMISSION
+
+
+
+WHEN TRANSMITTING A CHUNK
+Assign a TSN (if it doesn't already have one).
+Select a transport.
+If the T3-rtx for the transport is not running, start it.
+Make a copy to send.  Move the original to q->transmitted.
+
+WHEN PROCESSING A SACK
+Walk q->transmitted, moving things to q->sacked if they were sacked.
+
+Walk chunk through q->sacked.
+     if chunk->TSN <= CTSN {
+	stop chunk->transport->T3RTX
+	free the chunk
+     }
+
+
+WHEN RTX TIMEOUT HAPPENS
+Walk chunk through q->transmitted
+     if chunk->transport is the one that timed out,
+     move chunk to q->retransmit.
+Trigger transmission.
+
+
+DONE: Cases for transport selection:
+DONE: 1) <silent>L</silent>User is idiot savant, picks path
+DONE: 2) Transmit on primary path
+DONE: 3) Retransmit on secondary path
+
+sctp_add_transport() does not check to see if the transport we are
+adding already exists.  This COULD lead to having to fail the same
+transport address twice (or more...).  A valid INIT packet will not
+list the same address twice (in which case the OTHER guy is screwing
+himself) and we haven't implemented add_ip.
+
+THE PLAN (for adding lost packet handling):
+DONE: Initialize the timer for each transport when the transport is created.
+Generate timer control events according to 6.3.2.
+Write the state function for 6.3.3.
+Write the timer side-effects function.
+
+      Here are random things we would put in an SCTP_packet:
+      
+      SCTP header contents:
+            	sh->source		= htons(ep->port);
+		sh->destination		= htons(asoc->c.peerInfo.port);
+		sh->verificationTag	= htonl(asoc->c.peerInfo.init.initiateTag);
+      A list of of chunks
+      The total size of the chunks (incl padding)
+      
+      Here are random things we would do to an SCTP_packet:
+      
+      sctp_chunk_fits_in_packet(packet, chunk, transport)
+      sctp_append_chunk(packet, chunk)
+      sctp_transmit_packet(packet, transport)
+      INIT_PACKET(asoc, &packet)
+
+
+
+
+/* Try to send a chunk down to the network.  */
+int
+sctp_commit_chunk_to_network(struct SCTP_packet *payload,
+                             struct SCTP_chunk *chunk,
+                             struct SCTP_transport *transport)
+{
+	int transmitted;
+        transmitted = sctp_append_chunk(payload, chunk, transport)) {
+        switch(transmitted) {
+        case SCTP_XMIT_PACKET_FULL:
+        case SCTP_XMIT_RWND_FULL:
+		sctp_transmit_packet(...);
+		INIT_PACKET(payload);
+		transmitted = sctp_append_chunk(payload, chunk, transport);
+                break;
+        default:
+                break;  /* Default is to do nothing.  */
+	}
+	return(transmitted);
+}
+
+sctp_append_chunk can fail with either SCTP_XMIT_RWND_FULL,
+SCTP_XMIT_MUST_FRAG (PMTU_FULL), or SCTP_XMIT_PACKET_FULL.
+
+
+/* This is how we handle the rtx_timeout single-packet-transmit.  */
+			if (pushdown_chunk(payload, chunk, transport)
+			    && rtx_timeout) {
+				return(error);
+			}
+
+
+Thu Apr  5 16:04:09 CDT 2001
+Our objective here is to replace the switch in inet_create() with a
+table with register/unregister methods.
+
+#define PROTOSW_PREV           
+#define PROTOSW_NEXT           
+
+struct inet_protosw inetsw[] = {
+       {list: {next: PROTOSW_NEXT,
+               prev: PROTOSW_PREV,
+               },
+        type:       SOCK_STREAM,
+        protocol:    IPPROTO_TCP,
+        prot4:       &tcp_prot,
+        prot6:       &tcpv6_prot,
+        ops4:        &inet_stream_ops,
+        ops6:        &inet6_stream_ops,
+
+        no_check:    0,
+        reuse:       0,
+        capability:  -1,
+       },
+
+#if defined(CONFIG_IP_SCTP) || defined(CONFIG_IP_SCTP_MODULE)
+       {type:       SOCK_SEQPACKET,
+        protocol:    IPPROTO_SCTP,
+        prot4:       &sctp_prot,
+        prot6:       &sctpv6_prot,
+        ops4:        &inet_seqpacket_ops,
+        ops6:        &inet6_seqpacket_ops,
+
+        no_check:    0,
+        reuse:       0,
+        capability:  -1,
+       },
+
+       {type:        SOCK_STREAM,
+        protocol:    IPPROTO_SCTP,
+        prot4:       &sctp_conn_prot,
+        prot6:       &sctpv6_conn_prot,
+        ops4:        &inet_stream_ops,
+        ops6:        &inet6_stream_ops,
+
+        no_check:    0,
+        reuse:       0,
+        capability:  -1,
+       },
+#endif /* CONFIG_IP_SCTP || CONFIG_IP_SCTP_MODULE */
+
+       {type:        SOCK_DGRAM,
+        protocol:    IPPROTO_UDP,
+        prot4:       &udp_prot,
+        prot6:       &udpv6_prot,
+        ops4:        &inet_dgram_ops,
+        ops6:        &inet6_dgram_ops,
+
+        no_check:    UDP_CSUM_DEFAULT,
+        reuse:       0,
+        capability:  -1,
+       },
+
+
+       {type:        SOCK_RAW,
+        protocol:    IPPROTO_WILD,	/* wildcard */
+        prot4:       &raw_prot,
+        prot6:       &rawv6_prot,
+        ops4:        &inet_dgram_ops,
+        ops6:        &inet6_dgram_ops,
+
+        no_check:    UDP_CSUM_DEFAULT,
+        reuse:       1,
+        capability:  CAP_NET_RAW,
+       },
+
+}; /* struct inet_protosw inetsw */
+
+Here are things that need to go in that table:
+
+The first two fields are the keys for the table.
+struct inet_protosw {
+     struct list_head   list;
+     unsigned short	type;
+     int		protocol;	/* This is the L4 protocol number.  */
+     struct proto	*prot;
+     struct proto_ops	*ops;
+
+     char               no_check;
+     unsigned char	reuse;
+     int                capability;
+};
+
+Set type to SOCK_WILD to represent a wildcard.
+Set protocol to IPPROTO_WILD to represent a wildcard.
+Set no_check to 0 if we want all checksums.
+Set reuse to 0 if we do not want to set sk->reuse.
+Set 'capability' to -1 if no special capability is needed.
+
+
+*		protocol = IPPROTO_TCP;  /* Layer 4 proto number */
+*		prot = &tcp_prot;        /* Switch table for this proto */
+*		sock->ops = &inet_stream_ops; /* Switch tbl for this type */
+
+		sk->num = protocol;
+-		sk->no_check = UDP_CSUM_DEFAULT;
+-		sk->reuse = 1;
+
+
+                
+		if (type == SOCK_RAW && protocol == IPPROTO_RAW)
+                		sk->protinfo.af_inet.hdrincl = 1;
+
+
+if (SOCK_RAW == sock->type) {
+	if (!capable(CAP_NET_RAW))
+		goto free_and_badperm;
+	if (!protocol)
+		goto free_and_noproto;
+	prot = &raw_prot;
+	sk->reuse = 1;
+	sk->num = protocol;
+	sock->ops = &inet_dgram_ops;
+	if (protocol == IPPROTO_RAW)
+		sk->protinfo.af_inet.hdrincl = 1;
+} else {
+  lookup();
+}
+
+
+Supporting routines:
+int inet_protosw_register(struct inet_protosw *p);
+int inet_protosw_unregister(struct inet_protosw *p);
+
+
+Tue Apr 10 12:57:45 CDT 2001
+Question:  Should SCTP_packet be a dependent subclass of
+SCTP_outqueue, or should SCTP_outqueue and SCTP_packet be independent
+smart pipes which we can glue together?
+
+Answer:  We feel that the independent smart pipes make independent
+testing easier.
+
+
+Sat Apr 21 18:17:06 CDT 2001
+OK, here's what's going on.  An INIT and an INIT ACK contain almost
+exactly the same parameters, except that an INIT ACK must contain a
+cookie (the one that the initiator needs to echo).  In OUR
+implementation, we put the INIT packet in the cookie, so we really do
+most of the processing on the INIT when we get the COOKIE ECHO.
+
+Dilemma:
+
+	When do we convert the INIT to host byte forder?  We want to
+	use the same code for all three cases: INIT, INIT ACK, COOKIE
+	ECHO.  But if we convert for INIT, then the INIT packet in the
+	cookie (which is processed with the COOKIE ECHO) will be in
+	host byte order.
+
+Options:
+	1. Leave the INIT in network byte order.  All access must convert
+	to host byte order as needed.  Blech.  This violates our
+	existing conventions.  Hmm.  As long as we don't walk the
+	parameters again, we might be OK...
+
+	2. Add an argument to sctp_process_param() telling whether or
+	not to convert the parameter.
+
+We chose option 1.
+
+We REALLY should unify sctp_make_init() and sctp_make_init_ack().  The
+only difference is the cookie in the INIT ACK.
+
+We might one day need a version of sctp_addto_chunk() called
+sctp_addto_param() which does NOT add extra padding.
+
+How can we get the initial TSN in sctp_unpack_cookie without first
+having processed the INIT packet buried in the cookie?
+
+Sat Apr 28 15:03:48 CDT 2001
+This MIGHT be a bug--look for places we use sizeof(struct iphdr)--
+possibly we might need to grub around in the sk_buff structure
+to find the TRUE length of the iphdr (including options).
+One of the places is where we initialize a struct SCTP_packet--we
+really need to know how big the ip header options are.
+
+I've walked all the way through to the point where we pass INIT_ACK
+down to IP--it looks OK.  We DO parse the parameters correctly...
+
+Two bugs--bind loop1a not loop1 in the second bind, and
+sctp_bind_endpoint() should not let you bind the same address twice.
+There should be an approriate errno in the bind man page.  EINVAL.
+
+
+Tue May 15 15:35:28 CDT 2001
+compaq3_paddedinitackOK.tcp 
+   We ignore ABORT.
+datakinectics_2
+   We will send extra data before we get a COOKIE ACK...
+   We really lucked out and this implementation ran fine...
+sun (lost trace)                                    
+   We have an INIT that causes an oops.
+telesoft2_lostsendings.tcp
+telesoft3_spicyinitack.tcp
+   This INIT ACK causes an oops.
+datakinectics_3
+ulticom_3
+   They transmitted GAP reports and we retransmitted a TSN which had
+   been gap ack'd.
+adax2_goodsend.tcp
+   We produce MANY SACK's in a row after delaying way too long.
+   The retransmissions did not get bundled.
+
+Mon May 21 17:06:56 CDT 2001
+sctp_make_abort() needs to build an SCTP packet, not just a chunk...
+How do we handle cause codes?
+
+I don't know, but here's some random lines pruned from
+sctp_init_packet...
+
+	packet->source_port = asoc->ep->port;
+	packet->destination_port = asoc->peer.port; 
+	packet->verificationTag = asoc->peer.i.initiateTag; 
+
+
+
+CHANGES NEEDED IN THE LINUX KERNEL to support SCTP:
+* - sockreg 
+- both saddr and daddr need to be explicit arguments to the function
+  which takes packets for transmission--move these OUT of the
+  socket... Decouple d_addr from struct sock
+- bindx()
+- glue (elt in sk->tp_pinfo, etc...)
+
+We THINK we have the following items:
+- Per packet frag control (v6)
+- Unified PMTU discovery
+- iov-like sk_buff (to minimize copies)
+
+Fri Aug 17 10:58:35 CDT 2001
+Current thinking:  
+
+INADDR_ANY semantics for TCP imply an abstraction of the IP
+interfaces--use any that exist, TCP could care less.  This means if
+you add or delete interfaces at a lower level, this doesn't require
+more configuration for TCP.
+
+What this means for SCTP is that INADDR_ANY should also abstract the
+IP interfaces, so that when an association is initiated, we use all
+available IP interfaces, even if some have been added or deleted since
+boot.
+
+At bind, we grub for all interfaces and add them to the endpoint.
+After bind, if an interface is added...we know about it because
+ a) a connection came in on it and we're bound to INADDR_ANY--we add
+    the new transport to the list and use that for the association.
+ b) we initiate and...regrub for all existing interfaces?
+ c) hooks may exist to inform us when new IP interfaces rise
+    phoenix-like from the void (not pointer).
+
+Fri Aug 17 18:24:01 CDT 2001
+
+We need to look in ip6_input.c for IPPROTO_TCP and IPPROTO_UDP.  This
+probably needs to use the registration table to do some
+comparisons...
+
+There are several functions in tcp_ipv6.c that we want for sctp.  They
+are currently static; we want them to be exported.
+
+Tue Aug 21 13:09:09 CDT 2001
+
+This is a revised list of changes we need in the 2.4.x kernels to
+support SCTP.  These are based in part on Bidulock's code:
+
+MUST HAVE:
++ inet_listen() hook for transport layer
++ Make tests for SOCK_STREAM more specific (add IPPROTO_TCP checks)
+? Look for references to IPPROTO_TCP and IPPROTO_UDP to see if they
+  are sufficiently uniform.
+
+REALLY OUGHT TO HAVE:
+- bindx() (Daisy)
+- sockreg (done, need to use)
+- netfilter
+
+Interface
+
++ inet_getname() hook for transport layer?
+  - small & simple hooks here.
+
++ The ability to append things to proc files (/proc/sys/net
+  specifically...)
+
+TCP-one-true-transport cruft
+- ip_setsockopt() hook (See SOCK_STREAM below.)
+- unified PMTU discovery (allegedly done, need to use)
+(See tcp_sync_mss)
+     SOLUTIONS:
+     - We could move the extension headers and PMTU stuff out to the socket.
+     - We could intercept this socket call in sctp_setsockopt, and do
+       the relevant fix up there.  (LY characterizes as "flippin'
+       disgusting")
+     - We could use dst->pmtu (after all, TCP does...sort of...)
+
+Performance
+- decouple d_addr from struct sock (Andi Kleen)
+- zero-copy (done, need to use)
+- per packet IPv6 fragmentation control (allegedly done, need to use)
+  - Why did LY ask for this--he doesn't recall...
+
+---------------------------------------------------------------------------
+Tue Feb 10 11:26:26 PST 2004   La Monte
+
+One significant policy change which 1.0.0 should include is a bias toward
+performance issues.  
+
+One principle I want to make sure survives performance improvements is
+readability.  In particular, I still would like to put together a site
+hyperlinking LKSCTP with RFC2960 and supporting docs.  It should be
+possible to ask "What code implements THIS section?" and "What mandated
+THIS piece of code?"
+
+Consequently, a performance enhancement should either improve readability
+or define a separate clearly marked fast-path.  In particular, that class
+of speedups which collapses multiple decisions from different sections of
+the RFCs should probably use separate fast-path code.
+
+Separate fast-path code creates a maintenance problem, so fast-path code
+REALLY needs comments which point explicitly to the slow path. The slow-
+path code should where possible point to the corresponding fast path. It
+then becomes easier to check whether fixes for one path are relevant for
+the other as well.
+
+
diff --git a/doc/rfc2960.txt b/doc/rfc2960.txt
new file mode 100644
index 0000000..7054d55
--- /dev/null
+++ b/doc/rfc2960.txt
@@ -0,0 +1,7507 @@
+

+

+

+

+

+

+Network Working Group                                         R. Stewart

+Request for Comments: 2960                                        Q. Xie

+Category: Standards Track                                       Motorola

+                                                            K. Morneault

+                                                                C. Sharp

+                                                                   Cisco

+                                                         H. Schwarzbauer

+                                                                 Siemens

+                                                               T. Taylor

+                                                         Nortel Networks

+                                                               I. Rytina

+                                                                Ericsson

+                                                                M. Kalla

+                                                               Telcordia

+                                                                L. Zhang

+                                                                    UCLA

+                                                               V. Paxson

+                                                                   ACIRI

+                                                            October 2000

+

+

+                  Stream Control Transmission Protocol

+

+Status of this Memo

+

+   This document specifies an Internet standards track protocol for the

+   Internet community, and requests discussion and suggestions for

+   improvements.  Please refer to the current edition of the "Internet

+   Official Protocol Standards" (STD 1) for the standardization state

+   and status of this protocol.  Distribution of this memo is unlimited.

+

+Copyright Notice

+

+   Copyright (C) The Internet Society (2000).  All Rights Reserved.

+

+Abstract

+

+   This document describes the Stream Control Transmission Protocol

+   (SCTP).  SCTP is designed to transport PSTN signaling messages over

+   IP networks, but is capable of broader applications.

+

+   SCTP is a reliable transport protocol operating on top of a

+   connectionless packet network such as IP.  It offers the following

+   services to its users:

+

+      -- acknowledged error-free non-duplicated transfer of user data,

+      -- data fragmentation to conform to discovered path MTU size,

+

+

+

+

+Stewart, et al.             Standards Track                     [Page 1]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+      -- sequenced delivery of user messages within multiple streams,

+         with an option for order-of-arrival delivery of individual user

+         messages,

+      -- optional bundling of multiple user messages into a single SCTP

+         packet, and

+      -- network-level fault tolerance through supporting of multi-

+         homing at either or both ends of an association.

+

+   The design of SCTP includes appropriate congestion avoidance behavior

+   and resistance to flooding and masquerade attacks.

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+Stewart, et al.             Standards Track                     [Page 2]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+Table of Contents

+

+   1.  Introduction..................................................  5

+     1.1 Motivation..................................................  6

+     1.2 Architectural View of SCTP..................................  6

+     1.3 Functional View of SCTP.....................................  7

+       1.3.1 Association Startup and Takedown........................  8

+       1.3.2 Sequenced Delivery within Streams.......................  9

+       1.3.3 User Data Fragmentation.................................  9

+       1.3.4 Acknowledgement and Congestion Avoidance................  9

+       1.3.5 Chunk Bundling ......................................... 10

+       1.3.6 Packet Validation....................................... 10

+       1.3.7 Path Management......................................... 11

+     1.4 Key Terms................................................... 11

+     1.5 Abbreviations............................................... 15

+     1.6 Serial Number Arithmetic.................................... 15

+   2. Conventions.................................................... 16

+   3.  SCTP packet Format............................................ 16

+     3.1 SCTP Common Header Field Descriptions....................... 17

+     3.2 Chunk Field Descriptions.................................... 18

+       3.2.1 Optional/Variable-length Parameter Format............... 20

+     3.3 SCTP Chunk Definitions...................................... 21

+       3.3.1 Payload Data (DATA)..................................... 22

+       3.3.2 Initiation (INIT)....................................... 24

+         3.3.2.1 Optional or Variable Length Parameters.............. 26

+       3.3.3 Initiation Acknowledgement (INIT ACK)................... 30

+         3.3.3.1 Optional or Variable Length Parameters.............. 33

+       3.3.4 Selective Acknowledgement (SACK)........................ 33

+       3.3.5 Heartbeat Request (HEARTBEAT)........................... 37

+       3.3.6 Heartbeat Acknowledgement (HEARTBEAT ACK)............... 38

+       3.3.7 Abort Association (ABORT)............................... 39

+       3.3.8 Shutdown Association (SHUTDOWN)......................... 40

+       3.3.9 Shutdown Acknowledgement (SHUTDOWN ACK)................. 40

+       3.3.10 Operation Error (ERROR)................................ 41

+         3.3.10.1 Invalid Stream Identifier.......................... 42

+         3.3.10.2 Missing Mandatory Parameter........................ 43

+         3.3.10.3 Stale Cookie Error................................. 43

+         3.3.10.4 Out of Resource.................................... 44

+         3.3.10.5 Unresolvable Address............................... 44

+         3.3.10.6 Unrecognized Chunk Type............................ 44

+         3.3.10.7 Invalid Mandatory Parameter........................ 45

+         3.3.10.8 Unrecognized Parameters............................ 45

+         3.3.10.9 No User Data....................................... 46

+         3.3.10.10 Cookie Received While Shutting Down............... 46

+       3.3.11 Cookie Echo (COOKIE ECHO).............................. 46

+       3.3.12 Cookie Acknowledgement (COOKIE ACK).................... 47

+       3.3.13 Shutdown Complete (SHUTDOWN COMPLETE).................. 48

+   4. SCTP Association State Diagram................................. 48

+

+

+

+Stewart, et al.             Standards Track                     [Page 3]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   5. Association Initialization..................................... 52

+     5.1 Normal Establishment of an Association...................... 52

+       5.1.1 Handle Stream Parameters................................ 54

+       5.1.2 Handle Address Parameters............................... 54

+       5.1.3 Generating State Cookie................................. 56

+       5.1.4 State Cookie Processing................................. 57

+       5.1.5 State Cookie Authentication............................. 57

+       5.1.6 An Example of Normal Association Establishment.......... 58

+     5.2 Handle Duplicate or unexpected INIT, INIT ACK, COOKIE ECHO,

+         and COOKIE ACK.............................................. 60

+       5.2.1 Handle Duplicate INIT in COOKIE-WAIT

+             or COOKIE-ECHOED States................................. 60

+       5.2.2 Unexpected INIT in States Other than CLOSED,

+             COOKIE-ECHOED, COOKIE-WAIT and SHUTDOWN-ACK-SENT........ 61

+       5.2.3 Unexpected INIT ACK..................................... 61

+       5.2.4 Handle a COOKIE ECHO when a TCB exists.................. 62

+         5.2.4.1 An Example of a Association Restart................. 64

+       5.2.5 Handle Duplicate COOKIE ACK............................. 66

+       5.2.6 Handle Stale COOKIE Error............................... 66

+     5.3 Other Initialization Issues................................. 67

+       5.3.1 Selection of Tag Value.................................. 67

+   6. User Data Transfer............................................. 67

+     6.1 Transmission of DATA Chunks................................. 69

+     6.2 Acknowledgement on Reception of DATA Chunks................. 70

+       6.2.1 Tracking Peer's Receive Buffer Space.................... 73

+     6.3 Management Retransmission Timer............................. 75

+       6.3.1 RTO Calculation......................................... 75

+       6.3.2 Retransmission Timer Rules.............................. 76

+       6.3.3 Handle T3-rtx Expiration................................ 77

+     6.4 Multi-homed SCTP Endpoints.................................. 78

+       6.4.1 Failover from Inactive Destination Address.............. 79

+     6.5 Stream Identifier and Stream Sequence Number................ 80

+     6.6 Ordered and Unordered Delivery.............................. 80

+     6.7 Report Gaps in Received DATA TSNs........................... 81

+     6.8 Adler-32 Checksum Calculation............................... 82

+     6.9 Fragmentation............................................... 83

+     6.10 Bundling .................................................. 84

+   7. Congestion Control   .......................................... 85

+     7.1 SCTP Differences from TCP Congestion Control................ 85

+     7.2 SCTP Slow-Start and Congestion Avoidance.................... 87

+       7.2.1 Slow-Start.............................................. 87

+       7.2.2 Congestion Avoidance.................................... 89

+       7.2.3 Congestion Control...................................... 89

+       7.2.4 Fast Retransmit on Gap Reports.......................... 90

+     7.3 Path MTU Discovery.......................................... 91

+   8.  Fault Management.............................................. 92

+     8.1 Endpoint Failure Detection.................................. 92

+     8.2 Path Failure Detection...................................... 92

+

+

+

+Stewart, et al.             Standards Track                     [Page 4]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+     8.3 Path Heartbeat.............................................. 93

+     8.4 Handle "Out of the blue" Packets............................ 95

+     8.5 Verification Tag............................................ 96

+       8.5.1 Exceptions in Verification Tag Rules.................... 97

+   9. Termination of Association..................................... 98

+     9.1 Abort of an Association..................................... 98

+     9.2 Shutdown of an Association.................................. 98

+   10. Interface with Upper Layer....................................101

+     10.1 ULP-to-SCTP................................................101

+     10.2 SCTP-to-ULP................................................111

+   11. Security Considerations.......................................114

+     11.1 Security Objectives........................................114

+     11.2 SCTP Responses To Potential Threats........................115

+       11.2.1 Countering Insider Attacks.............................115

+       11.2.2 Protecting against Data Corruption in the Network......115

+       11.2.3 Protecting Confidentiality.............................115

+       11.2.4 Protecting against Blind Denial of Service Attacks.....116

+         11.2.4.1 Flooding...........................................116

+         11.2.4.2 Blind Masquerade...................................118

+         11.2.4.3 Improper Monopolization of Services................118

+     11.3 Protection against Fraud and Repudiation...................119

+   12. Recommended Transmission Control Block (TCB) Parameters.......120

+     12.1 Parameters necessary for the SCTP instance.................120

+     12.2 Parameters necessary per association (i.e. the TCB)........120

+     12.3 Per Transport Address Data.................................122

+     12.4 General Parameters Needed..................................123

+   13. IANA Considerations...........................................123

+     13.1 IETF-defined Chunk Extension...............................123

+     13.2 IETF-defined Chunk Parameter Extension.....................124

+     13.3 IETF-defined Additional Error Causes.......................124

+     13.4 Payload Protocol Identifiers...............................125

+   14. Suggested SCTP Protocol Parameter Values......................125

+   15. Acknowledgements..............................................126

+   16. Authors' Addresses............................................126

+   17. References....................................................128

+   18. Bibliography..................................................129

+   Appendix A .......................................................131

+   Appendix B .......................................................132

+   Full Copyright Statement .........................................134

+

+1. Introduction

+

+   This section explains the reasoning behind the development of the

+   Stream Control Transmission Protocol (SCTP), the services it offers,

+   and the basic concepts needed to understand the detailed description

+   of the protocol.

+

+

+

+

+

+Stewart, et al.             Standards Track                     [Page 5]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+1.1 Motivation

+

+   TCP [RFC793] has performed immense service as the primary means of

+   reliable data transfer in IP networks.  However, an increasing number

+   of recent applications have found TCP too limiting, and have

+   incorporated their own reliable data transfer protocol on top of UDP

+   [RFC768].  The limitations which users have wished to bypass include

+   the following:

+

+      -- TCP provides both reliable data transfer and strict order-of-

+      transmission delivery of data.  Some applications need reliable

+      transfer without sequence maintenance, while others would be

+      satisfied with partial ordering of the data.  In both of these

+      cases the head-of-line blocking offered by TCP causes unnecessary

+      delay.

+

+      -- The stream-oriented nature of TCP is often an inconvenience.

+      Applications must add their own record marking to delineate their

+      messages, and must make explicit use of the push facility to

+      ensure that a complete message is transferred in a reasonable

+      time.

+

+      -- The limited scope of TCP sockets complicates the task of

+      providing highly-available data transfer capability using multi-

+      homed hosts.

+

+      -- TCP is relatively vulnerable to denial of service attacks, such

+      as SYN attacks.

+

+   Transport of PSTN signaling across the IP network is an application

+   for which all of these limitations of TCP are relevant.  While this

+   application directly motivated the development of SCTP, other

+   applications may find SCTP a good match to their requirements.

+

+1.2 Architectural View of SCTP

+

+   SCTP is viewed as a layer between the SCTP user application ("SCTP

+   user" for short) and a connectionless packet network service such as

+   IP.  The remainder of this document assumes SCTP runs on top of IP.

+   The basic service offered by SCTP is the reliable transfer of user

+   messages between peer SCTP users.  It performs this service within

+   the context of an association between two SCTP endpoints. Section 10

+   of this document sketches the API which should exist at the boundary

+   between the SCTP and the SCTP user layers.

+

+   SCTP is connection-oriented in nature, but the SCTP association is a

+   broader concept than the TCP connection.  SCTP provides the means for

+   each SCTP endpoint (Section 1.4) to provide the other endpoint

+

+

+

+Stewart, et al.             Standards Track                     [Page 6]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   (during association startup) with a list of transport addresses

+   (i.e., multiple IP addresses in combination with an SCTP port)

+   through which that endpoint can be reached and from which it will

+   originate SCTP packets.  The association spans transfers over all of

+   the possible source/destination combinations which may be generated

+   from each endpoint's lists.

+

+       _____________                                      _____________

+      |  SCTP User  |                                    |  SCTP User  |

+      | Application |                                    | Application |

+      |-------------|                                    |-------------|

+      |    SCTP     |                                    |    SCTP     |

+      |  Transport  |                                    |  Transport  |

+      |   Service   |                                    |   Service   |

+      |-------------|                                    |-------------|

+      |             |One or more    ----      One or more|             |

+      | IP Network  |IP address      \/        IP address| IP Network  |

+      |   Service   |appearances     /\       appearances|   Service   |

+      |_____________|               ----                 |_____________|

+

+        SCTP Node A |<-------- Network transport ------->| SCTP Node B

+

+                        Figure 1: An SCTP Association

+

+1.3 Functional View of SCTP

+

+   The SCTP transport service can be decomposed into a number of

+   functions.  These are depicted in Figure 2 and explained in the

+   remainder of this section.

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+Stewart, et al.             Standards Track                     [Page 7]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+                           SCTP User Application

+

+         -----------------------------------------------------

+          _____________                  ____________________

+         |             |                | Sequenced delivery |

+         | Association |                |   within streams   |

+         |             |                |____________________|

+         |   startup   |

+         |             |         ____________________________

+         |     and     |        |    User Data Fragmentation |

+         |             |        |____________________________|

+         |   takedown  |

+         |             |         ____________________________

+         |             |        |     Acknowledgement        |

+         |             |        |          and               |

+         |             |        |    Congestion Avoidance    |

+         |             |        |____________________________|

+         |             |

+         |             |         ____________________________

+         |             |        |       Chunk Bundling       |

+         |             |        |____________________________|

+         |             |

+         |             |     ________________________________

+         |             |    |      Packet Validation         |

+         |             |    |________________________________|

+         |             |

+         |             |     ________________________________

+         |             |    |     Path Management            |

+         |_____________|    |________________________________|

+

+           Figure 2: Functional View of the SCTP Transport Service

+

+1.3.1 Association Startup and Takedown

+

+   An association is initiated by a request from the SCTP user (see the

+   description of the ASSOCIATE (or SEND) primitive in Section 10).

+

+   A cookie mechanism, similar to one described by Karn and Simpson in

+   [RFC2522], is employed during the initialization to provide

+   protection against security attacks.  The cookie mechanism uses a

+   four-way handshake, the last two legs of which are allowed to carry

+   user data for fast setup.  The startup sequence is described in

+   Section 5 of this document.

+

+   SCTP provides for graceful close (i.e., shutdown) of an active

+   association on request from the SCTP user.  See the description of

+   the SHUTDOWN primitive in Section 10.  SCTP also allows ungraceful

+   close (i.e., abort), either on request from the user (ABORT

+

+

+

+Stewart, et al.             Standards Track                     [Page 8]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   primitive) or as a result of an error condition detected within the

+   SCTP layer.  Section 9 describes both the graceful and the ungraceful

+   close procedures.

+

+   SCTP does not support a half-open state (like TCP) wherein one side

+   may continue sending data while the other end is closed.  When either

+   endpoint performs a shutdown, the association on each peer will stop

+   accepting new data from its user and only deliver data in queue at

+   the time of the graceful close (see Section 9).

+

+1.3.2 Sequenced Delivery within Streams

+

+   The term "stream" is used in SCTP to refer to a sequence of user

+   messages that are to be delivered to the upper-layer protocol in

+   order with respect to other messages within the same stream.  This is

+   in contrast to its usage in TCP, where it refers to a sequence of

+   bytes (in this document a byte is assumed to be eight bits).

+

+   The SCTP user can specify at association startup time the number of

+   streams to be supported by the association.  This number is

+   negotiated with the remote end (see Section 5.1.1).  User messages

+   are associated with stream numbers (SEND, RECEIVE primitives, Section

+   10).  Internally, SCTP assigns a stream sequence number to each

+   message passed to it by the SCTP user.  On the receiving side, SCTP

+   ensures that messages are delivered to the SCTP user in sequence

+   within a given stream.  However, while one stream may be blocked

+   waiting for the next in-sequence user message, delivery from other

+   streams may proceed.

+

+   SCTP provides a mechanism for bypassing the sequenced delivery

+   service.  User messages sent using this mechanism are delivered to

+   the SCTP user as soon as they are received.

+

+1.3.3 User Data Fragmentation

+

+   When needed, SCTP fragments user messages to ensure that the SCTP

+   packet passed to the lower layer conforms to the path MTU.  On

+   receipt, fragments are reassembled into complete messages before

+   being passed to the SCTP user.

+

+1.3.4 Acknowledgement and Congestion Avoidance

+

+   SCTP assigns a Transmission Sequence Number (TSN) to each user data

+   fragment or unfragmented message.  The TSN is independent of any

+   stream sequence number assigned at the stream level.  The receiving

+

+

+

+

+

+

+Stewart, et al.             Standards Track                     [Page 9]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   end acknowledges all TSNs received, even if there are gaps in the

+   sequence.  In this way, reliable delivery is kept functionally

+   separate from sequenced stream delivery.

+

+   The acknowledgement and congestion avoidance function is responsible

+   for packet retransmission when timely acknowledgement has not been

+   received.  Packet retransmission is conditioned by congestion

+   avoidance procedures similar to those used for TCP.  See Sections 6

+   and 7 for a detailed description of the protocol procedures

+   associated with this function.

+

+1.3.5 Chunk Bundling

+

+   As described in Section 3, the SCTP packet as delivered to the lower

+   layer consists of a common header followed by one or more chunks.

+   Each chunk may contain either user data or SCTP control information.

+   The SCTP user has the option to request bundling of more than one

+   user messages into a single SCTP packet.  The chunk bundling function

+   of SCTP is responsible for assembly of the complete SCTP packet and

+   its disassembly at the receiving end.

+

+   During times of congestion an SCTP implementation MAY still perform

+   bundling even if the user has requested that SCTP not bundle.  The

+   user's disabling of bundling only affects SCTP implementations that

+   may delay a small period of time before transmission (to attempt to

+   encourage bundling).  When the user layer disables bundling, this

+   small delay is prohibited but not bundling that is performed during

+   congestion or retransmission.

+

+1.3.6 Packet Validation

+

+   A mandatory Verification Tag field and a 32 bit checksum field (see

+   Appendix B for a description of the Adler-32 checksum) are included

+   in the SCTP common header.  The Verification Tag value is chosen by

+   each end of the association during association startup.  Packets

+   received without the expected Verification Tag value are discarded,

+   as a protection against blind masquerade attacks and against stale

+   SCTP packets from a previous association.  The Adler-32 checksum

+   should be set by the sender of each SCTP packet to provide additional

+   protection against data corruption in the network.  The receiver of

+   an SCTP packet with an invalid Adler-32 checksum silently discards

+   the packet.

+

+

+

+

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 10]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+1.3.7 Path Management

+

+   The sending SCTP user is able to manipulate the set of transport

+   addresses used as destinations for SCTP packets through the

+   primitives described in Section 10.  The SCTP path management

+   function chooses the destination transport address for each outgoing

+   SCTP packet based on the SCTP user's instructions and the currently

+   perceived reachability status of the eligible destination set.  The

+   path management function monitors reachability through heartbeats

+   when other packet traffic is inadequate to provide this information

+   and advises the SCTP user when reachability of any far-end transport

+   address changes.  The path management function is also responsible

+   for reporting the eligible set of local transport addresses to the

+   far end during association startup, and for reporting the transport

+   addresses returned from the far end to the SCTP user.

+

+   At association start-up, a primary path is defined for each SCTP

+   endpoint, and is used for normal sending of SCTP packets.

+

+   On the receiving end, the path management is responsible for

+   verifying the existence of a valid SCTP association to which the

+   inbound SCTP packet belongs before passing it for further processing.

+

+   Note: Path Management and Packet Validation are done at the same

+   time, so although described separately above, in reality they cannot

+   be performed as separate items.

+

+1.4 Key Terms

+

+   Some of the language used to describe SCTP has been introduced in the

+   previous sections.  This section provides a consolidated list of the

+   key terms and their definitions.

+

+   o  Active destination transport address: A transport address on a

+      peer endpoint which a transmitting endpoint considers available

+      for receiving user messages.

+

+   o  Bundling: An optional multiplexing operation, whereby more than

+      one user message may be carried in the same SCTP packet.  Each

+      user message occupies its own DATA chunk.

+

+   o  Chunk: A unit of information within an SCTP packet, consisting of

+      a chunk header and chunk-specific content.

+

+   o  Congestion Window (cwnd): An SCTP variable that limits the data,

+      in number of bytes, a sender can send to a particular destination

+      transport address before receiving an acknowledgement.

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 11]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   o  Cumulative TSN Ack Point: The TSN of the last DATA chunk

+      acknowledged via the Cumulative TSN Ack field of a SACK.

+

+   o  Idle destination address: An address that has not had user

+      messages sent to it within some length of time, normally the

+      HEARTBEAT interval or greater.

+

+   o  Inactive destination transport address: An address which is

+      considered inactive due to errors and unavailable to transport

+      user messages.

+

+   o  Message = user message:  Data submitted to SCTP by the Upper Layer

+      Protocol (ULP).

+

+   o  Message Authentication Code (MAC):  An integrity check mechanism

+      based on cryptographic hash functions using a secret key.

+      Typically, message authentication codes are used between two

+      parties that share a secret key in order to validate information

+      transmitted between these parties.  In SCTP it is used by an

+      endpoint to validate the State Cookie information that is returned

+      from the peer in the COOKIE ECHO chunk.  The term "MAC" has

+      different meanings in different contexts.  SCTP uses this term

+      with the same meaning as in [RFC2104].

+

+   o  Network Byte Order: Most significant byte first, a.k.a., Big

+      Endian.

+

+   o  Ordered Message: A user message that is delivered in order with

+      respect to all previous user messages sent within the stream the

+      message was sent on.

+

+   o  Outstanding TSN (at an SCTP endpoint): A TSN (and the associated

+      DATA chunk) that has been sent by the endpoint but for which it

+      has not yet received an acknowledgement.

+

+   o  Path: The route taken by the SCTP packets sent by one SCTP

+      endpoint to a specific destination transport address of its peer

+      SCTP endpoint.  Sending to different destination transport

+      addresses does not necessarily guarantee getting separate paths.

+

+   o  Primary Path: The primary path is the destination and source

+      address that will be put into a packet outbound to the peer

+      endpoint by default.  The definition includes the source address

+      since an implementation MAY wish to specify both destination and

+      source address to better control the return path taken by reply

+      chunks and on which interface the packet is transmitted when the

+      data sender is multi-homed.

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 12]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   o  Receiver Window (rwnd): An SCTP variable a data sender uses to

+      store the most recently calculated receiver window of its peer, in

+      number of bytes.  This gives the sender an indication of the space

+      available in the receiver's inbound buffer.

+

+   o  SCTP association: A protocol relationship between SCTP endpoints,

+      composed of the two SCTP endpoints and protocol state information

+      including Verification Tags and the currently active set of

+      Transmission Sequence Numbers (TSNs), etc.  An association can be

+      uniquely identified by the transport addresses used by the

+      endpoints in the association.  Two SCTP endpoints MUST NOT have

+      more than one SCTP association between them at any given time.

+

+   o  SCTP endpoint: The logical sender/receiver of SCTP packets.  On a

+      multi-homed host, an SCTP endpoint is represented to its peers as

+      a combination of a set of eligible destination transport addresses

+      to which SCTP packets can be sent and a set of eligible source

+      transport addresses from which SCTP packets can be received.  All

+      transport addresses used by an SCTP endpoint must use the same

+      port number, but can use multiple IP addresses.  A transport

+      address used by an SCTP endpoint must not be used by another SCTP

+      endpoint.  In other words, a transport address is unique to an

+      SCTP endpoint.

+

+   o  SCTP packet (or packet): The unit of data delivery across the

+      interface between SCTP and the connectionless packet network

+      (e.g., IP).  An SCTP packet includes the common SCTP header,

+      possible SCTP control chunks, and user data encapsulated within

+      SCTP DATA chunks.

+

+   o  SCTP user application (SCTP user): The logical higher-layer

+      application entity which uses the services of SCTP, also called

+      the Upper-layer Protocol (ULP).

+

+   o  Slow Start Threshold (ssthresh): An SCTP variable.  This is the

+      threshold which the endpoint will use to determine whether to

+      perform slow start or congestion avoidance on a particular

+      destination transport address.  Ssthresh is in number of bytes.

+

+   o  Stream: A uni-directional logical channel established from one to

+      another associated SCTP endpoint, within which all user messages

+      are delivered in sequence except for those submitted to the

+      unordered delivery service.

+

+   Note: The relationship between stream numbers in opposite directions

+   is strictly a matter of how the applications use them.  It is the

+   responsibility of the SCTP user to create and manage these

+   correlations if they are so desired.

+

+

+

+Stewart, et al.             Standards Track                    [Page 13]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   o  Stream Sequence Number: A 16-bit sequence number used internally

+      by SCTP to assure sequenced delivery of the user messages within a

+      given stream.  One stream sequence number is attached to each user

+      message.

+

+   o  Tie-Tags: Verification Tags from a previous association.  These

+      Tags are used within a State Cookie so that the newly restarting

+      association can be linked to the original association within the

+      endpoint that did not restart.

+

+   o  Transmission Control Block (TCB): An internal data structure

+      created by an SCTP endpoint for each of its existing SCTP

+      associations to other SCTP endpoints.  TCB contains all the status

+      and operational information for the endpoint to maintain and

+      manage the corresponding association.

+

+   o  Transmission Sequence Number (TSN): A 32-bit sequence number used

+      internally by SCTP.  One TSN is attached to each chunk containing

+      user data to permit the receiving SCTP endpoint to acknowledge its

+      receipt and detect duplicate deliveries.

+

+   o  Transport address:  A Transport Address is traditionally defined

+      by Network Layer address, Transport Layer protocol and Transport

+      Layer port number.  In the case of SCTP running over IP, a

+      transport address is defined by the combination of an IP address

+      and an SCTP port number (where SCTP is the Transport protocol).

+

+   o Unacknowledged TSN (at an SCTP endpoint): A TSN (and the associated

+      DATA chunk) which has been received by the endpoint but for which

+      an acknowledgement has not yet been sent. Or in the opposite case,

+      for a packet that has been sent but no acknowledgement has been

+      received.

+

+   o  Unordered Message: Unordered messages are "unordered" with respect

+      to any other message, this includes both other unordered messages

+      as well as other ordered messages.  Unordered message might be

+      delivered prior to or later than ordered messages sent on the same

+      stream.

+

+   o  User message: The unit of data delivery across the interface

+      between SCTP and its user.

+

+   o  Verification Tag: A 32 bit unsigned integer that is randomly

+      generated.  The Verification Tag provides a key that allows a

+      receiver to verify that the SCTP packet belongs to the current

+      association and is not an old or stale packet from a previous

+      association.

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 14]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+1.5. Abbreviations

+

+   MAC    - Message Authentication Code [RFC2104]

+

+   RTO    - Retransmission Time-out

+

+   RTT    - Round-trip Time

+

+   RTTVAR - Round-trip Time Variation

+

+   SCTP   - Stream Control Transmission Protocol

+

+   SRTT   - Smoothed RTT

+

+   TCB    - Transmission Control Block

+

+   TLV    - Type-Length-Value Coding Format

+

+   TSN    - Transmission Sequence Number

+

+   ULP    - Upper-layer Protocol

+

+1.6 Serial Number Arithmetic

+

+   It is essential to remember that the actual Transmission Sequence

+   Number space is finite, though very large.  This space ranges from 0

+   to 2**32 - 1. Since the space is finite, all arithmetic dealing with

+   Transmission Sequence Numbers must be performed modulo 2**32.  This

+   unsigned arithmetic preserves the relationship of sequence numbers as

+   they cycle from 2**32 - 1 to 0 again.  There are some subtleties to

+   computer modulo arithmetic, so great care should be taken in

+   programming the comparison of such values.  When referring to TSNs,

+   the symbol "=<" means "less than or equal"(modulo 2**32).

+

+   Comparisons and arithmetic on TSNs in this document SHOULD use Serial

+   Number Arithmetic as defined in [RFC1982] where SERIAL_BITS = 32.

+

+   An endpoint SHOULD NOT transmit a DATA chunk with a TSN that is more

+   than 2**31 - 1 above the beginning TSN of its current send window.

+   Doing so will cause problems in comparing TSNs.

+

+   Transmission Sequence Numbers wrap around when they reach 2**32 - 1.

+   That is, the next TSN a DATA chunk MUST use after transmitting TSN =

+   2*32 - 1 is TSN = 0.

+

+   Any arithmetic done on Stream Sequence Numbers SHOULD use Serial

+   Number Arithmetic as defined in [RFC1982] where SERIAL_BITS = 16.

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 15]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   All other arithmetic and comparisons in this document uses normal

+   arithmetic.

+

+2. Conventions

+

+   The keywords MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD,

+   SHOULD NOT, RECOMMENDED, NOT RECOMMENDED, MAY, and OPTIONAL, when

+   they appear in this document, are to be interpreted as described in

+   [RFC2119].

+

+3.  SCTP packet Format

+

+   An SCTP packet is composed of a common header and chunks. A chunk

+   contains either control information or user data.

+

+   The SCTP packet format is shown below:

+

+       0                   1                   2                   3

+       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |                        Common Header                          |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |                          Chunk #1                             |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |                           ...                                 |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |                          Chunk #n                             |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+   Multiple chunks can be bundled into one SCTP packet up to the MTU

+   size, except for the INIT, INIT ACK, and SHUTDOWN COMPLETE chunks.

+   These chunks MUST NOT be bundled with any other chunk in a packet.

+   See Section 6.10 for more details on chunk bundling.

+

+   If a user data message doesn't fit into one SCTP packet it can be

+   fragmented into multiple chunks using the procedure defined in

+   Section 6.9.

+

+   All integer fields in an SCTP packet MUST be transmitted in network

+   byte order, unless otherwise stated.

+

+

+

+

+

+

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 16]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+3.1 SCTP Common Header Field Descriptions

+

+                         SCTP Common Header Format

+

+       0                   1                   2                   3

+       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |     Source Port Number        |     Destination Port Number   |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |                      Verification Tag                         |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |                           Checksum                            |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+   Source Port Number: 16 bits (unsigned integer)

+

+      This is the SCTP sender's port number.  It can be used by the

+      receiver in combination with the source IP address, the SCTP

+      destination port and possibly the destination IP address to

+      identify the association to which this packet belongs.

+

+   Destination Port Number: 16 bits (unsigned integer)

+

+      This is the SCTP port number to which this packet is destined.

+      The receiving host will use this port number to de-multiplex the

+      SCTP packet to the correct receiving endpoint/application.

+

+   Verification Tag: 32 bits (unsigned integer)

+

+      The receiver of this packet uses the Verification Tag to validate

+      the sender of this SCTP packet.  On transmit, the value of this

+      Verification Tag MUST be set to the value of the Initiate Tag

+      received from the peer endpoint during the association

+      initialization, with the following exceptions:

+

+      -  A packet containing an INIT chunk MUST have a zero Verification

+         Tag.

+      -  A packet containing a SHUTDOWN-COMPLETE chunk with the T-bit

+         set MUST have the Verification Tag copied from the packet with

+         the SHUTDOWN-ACK chunk.

+      -  A packet containing an ABORT chunk may have the verification

+         tag copied from the packet which caused the ABORT to be sent.

+         For details see Section 8.4 and 8.5.

+

+   An INIT chunk MUST be the only chunk in the SCTP packet carrying it.

+

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 17]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   Checksum: 32 bits (unsigned integer)

+

+         This field contains the checksum of this SCTP packet.  Its

+         calculation is discussed in Section 6.8.  SCTP uses the Adler-

+         32 algorithm as described in Appendix B for calculating the

+         checksum

+

+3.2  Chunk Field Descriptions

+

+   The figure below illustrates the field format for the chunks to be

+   transmitted in the SCTP packet.  Each chunk is formatted with a Chunk

+   Type field, a chunk-specific Flag field, a Chunk Length field, and a

+   Value field.

+

+       0                   1                   2                   3

+       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |   Chunk Type  | Chunk  Flags  |        Chunk Length           |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      \                                                               \

+      /                          Chunk Value                          /

+      \                                                               \

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+   Chunk Type: 8 bits (unsigned integer)

+

+      This field identifies the type of information contained in the

+      Chunk Value field.  It takes a value from 0 to 254.  The value of

+      255 is reserved for future use as an extension field.

+

+   The values of Chunk Types are defined as follows:

+

+   ID Value    Chunk Type

+   -----       ----------

+   0          - Payload Data (DATA)

+   1          - Initiation (INIT)

+   2          - Initiation Acknowledgement (INIT ACK)

+   3          - Selective Acknowledgement (SACK)

+   4          - Heartbeat Request (HEARTBEAT)

+   5          - Heartbeat Acknowledgement (HEARTBEAT ACK)

+   6          - Abort (ABORT)

+   7          - Shutdown (SHUTDOWN)

+   8          - Shutdown Acknowledgement (SHUTDOWN ACK)

+   9          - Operation Error (ERROR)

+   10         - State Cookie (COOKIE ECHO)

+   11         - Cookie Acknowledgement (COOKIE ACK)

+   12         - Reserved for Explicit Congestion Notification Echo (ECNE)

+   13         - Reserved for Congestion Window Reduced (CWR)

+

+

+

+Stewart, et al.             Standards Track                    [Page 18]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   14         - Shutdown Complete (SHUTDOWN COMPLETE)

+   15 to 62   - reserved by IETF

+   63         - IETF-defined Chunk Extensions

+   64 to 126  - reserved by IETF

+   127        - IETF-defined Chunk Extensions

+   128 to 190 - reserved by IETF

+   191        - IETF-defined Chunk Extensions

+   192 to 254 - reserved by IETF

+   255        - IETF-defined Chunk Extensions

+

+   Chunk Types are encoded such that the highest-order two bits specify

+   the action that must be taken if the processing endpoint does not

+   recognize the Chunk Type.

+

+   00 - Stop processing this SCTP packet and discard it, do not process

+        any further chunks within it.

+

+   01 - Stop processing this SCTP packet and discard it, do not process

+        any further chunks within it, and report the unrecognized

+        parameter in an 'Unrecognized Parameter Type' (in either an

+        ERROR or in the INIT ACK).

+

+   10 - Skip this chunk and continue processing.

+

+   11 - Skip this chunk and continue processing, but report in an ERROR

+        Chunk using the 'Unrecognized Chunk Type' cause of error.

+

+   Note: The ECNE and CWR chunk types are reserved for future use of

+   Explicit Congestion Notification (ECN).

+

+   Chunk Flags: 8 bits

+

+      The usage of these bits depends on the chunk type as given by the

+      Chunk Type.  Unless otherwise specified, they are set to zero on

+      transmit and are ignored on receipt.

+

+   Chunk Length: 16 bits (unsigned integer)

+

+      This value represents the size of the chunk in bytes including the

+      Chunk Type, Chunk Flags, Chunk Length, and Chunk Value fields.

+      Therefore, if the Chunk Value field is zero-length, the Length

+      field will be set to 4.  The Chunk Length field does not count any

+      padding.

+

+

+

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 19]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   Chunk Value: variable length

+

+      The Chunk Value field contains the actual information to be

+      transferred in the chunk.  The usage and format of this field is

+      dependent on the Chunk Type.

+

+   The total length of a chunk (including Type, Length and Value fields)

+   MUST be a multiple of 4 bytes.  If the length of the chunk is not a

+   multiple of 4 bytes, the sender MUST pad the chunk with all zero

+   bytes and this padding is not included in the chunk length field.

+   The sender should never pad with more than 3 bytes.  The receiver

+   MUST ignore the padding bytes.

+

+   SCTP defined chunks are described in detail in Section 3.3.  The

+   guidelines for IETF-defined chunk extensions can be found in Section

+   13.1 of this document.

+

+3.2.1  Optional/Variable-length Parameter Format

+

+   Chunk values of SCTP control chunks consist of a chunk-type-specific

+   header of required fields, followed by zero or more parameters.  The

+   optional and variable-length parameters contained in a chunk are

+   defined in a Type-Length-Value format as shown below.

+

+       0                   1                   2                   3

+       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |          Parameter Type       |       Parameter Length        |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      \                                                               \

+      /                       Parameter Value                         /

+      \                                                               \

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+   Chunk Parameter Type:  16 bits (unsigned integer)

+

+      The Type field is a 16 bit identifier of the type of parameter.

+      It takes a value of 0 to 65534.

+

+      The value of 65535 is reserved for IETF-defined extensions. Values

+      other than those defined in specific SCTP chunk description are

+      reserved for use by IETF.

+

+

+

+

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 20]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   Chunk Parameter Length:  16 bits (unsigned integer)

+

+      The Parameter Length field contains the size of the parameter in

+      bytes, including the Parameter Type, Parameter Length, and

+      Parameter Value fields.  Thus, a parameter with a zero-length

+      Parameter Value field would have a Length field of 4.  The

+      Parameter Length does not include any padding bytes.

+

+   Chunk Parameter Value: variable-length.

+

+      The Parameter Value field contains the actual information to be

+      transferred in the parameter.

+

+   The total length of a parameter (including Type, Parameter Length and

+   Value fields) MUST be a multiple of 4 bytes.  If the length of the

+   parameter is not a multiple of 4 bytes, the sender pads the Parameter

+   at the end (i.e., after the Parameter Value field) with all zero

+   bytes.  The length of the padding is not included in the parameter

+   length field.  A sender SHOULD NOT pad with more than 3 bytes.  The

+   receiver MUST ignore the padding bytes.

+

+   The Parameter Types are encoded such that the highest-order two bits

+   specify the action that must be taken if the processing endpoint does

+   not recognize the Parameter Type.

+

+   00 - Stop processing this SCTP packet and discard it, do not process

+        any further chunks within it.

+

+   01 - Stop processing this SCTP packet and discard it, do not process

+        any further chunks within it, and report the unrecognized

+        parameter in an 'Unrecognized Parameter Type' (in either an

+        ERROR or in the INIT ACK).

+

+   10 - Skip this parameter and continue processing.

+

+   11 - Skip this parameter and continue processing but report the

+        unrecognized parameter in an 'Unrecognized Parameter Type' (in

+        either an ERROR or in the INIT ACK).

+

+   The actual SCTP parameters are defined in the specific SCTP chunk

+   sections.  The rules for IETF-defined parameter extensions are

+   defined in Section 13.2.

+

+3.3 SCTP Chunk Definitions

+

+   This section defines the format of the different SCTP chunk types.

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 21]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+3.3.1 Payload Data (DATA) (0)

+

+   The following format MUST be used for the DATA chunk:

+

+       0                   1                   2                   3

+       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |   Type = 0    | Reserved|U|B|E|    Length                     |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |                              TSN                              |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |      Stream Identifier S      |   Stream Sequence Number n    |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |                  Payload Protocol Identifier                  |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      \                                                               \

+      /                 User Data (seq n of Stream S)                 /

+      \                                                               \

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+   Reserved: 5 bits

+

+      Should be set to all '0's and ignored by the receiver.

+

+   U bit: 1 bit

+

+      The (U)nordered bit, if set to '1', indicates that this is an

+      unordered DATA chunk, and there is no Stream Sequence Number

+      assigned to this DATA chunk.  Therefore, the receiver MUST ignore

+      the Stream Sequence Number field.

+

+      After re-assembly (if necessary), unordered DATA chunks MUST be

+      dispatched to the upper layer by the receiver without any attempt

+      to re-order.

+

+      If an unordered user message is fragmented, each fragment of the

+      message MUST have its U bit set to '1'.

+

+   B bit: 1 bit

+

+      The (B)eginning fragment bit, if set, indicates the first fragment

+      of a user message.

+

+   E bit:  1 bit

+

+      The (E)nding fragment bit, if set, indicates the last fragment of

+      a user message.

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 22]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   An unfragmented user message shall have both the B and E bits set to

+   '1'.  Setting both B and E bits to '0' indicates a middle fragment of

+   a multi-fragment user message, as summarized in the following table:

+

+            B E                  Description

+         ============================================================

+         |  1 0 | First piece of a fragmented user message          |

+         +----------------------------------------------------------+

+         |  0 0 | Middle piece of a fragmented user message         |

+         +----------------------------------------------------------+

+         |  0 1 | Last piece of a fragmented user message           |

+         +----------------------------------------------------------+

+         |  1 1 | Unfragmented Message                              |

+         ============================================================

+         |             Table 1: Fragment Description Flags          |

+         ============================================================

+

+   When a user message is fragmented into multiple chunks, the TSNs are

+   used by the receiver to reassemble the message.  This means that the

+   TSNs for each fragment of a fragmented user message MUST be strictly

+   sequential.

+

+   Length:  16 bits (unsigned integer)

+

+      This field indicates the length of the DATA chunk in bytes from

+      the beginning of the type field to the end of the user data field

+      excluding any padding.  A DATA chunk with no user data field will

+      have Length set to 16 (indicating 16 bytes).

+

+   TSN : 32 bits (unsigned integer)

+

+      This value represents the TSN for this DATA chunk.  The valid

+      range of TSN is from 0 to 4294967295 (2**32 - 1).  TSN wraps back

+      to 0 after reaching 4294967295.

+

+   Stream Identifier S: 16 bits (unsigned integer)

+

+      Identifies the stream to which the following user data belongs.

+

+   Stream Sequence Number n: 16 bits (unsigned integer)

+

+      This value represents the stream sequence number of the following

+      user data within the stream S.  Valid range is 0 to 65535.

+

+      When a user message is fragmented by SCTP for transport, the same

+      stream sequence number MUST be carried in each of the fragments of

+      the message.

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 23]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   Payload Protocol Identifier: 32 bits (unsigned integer)

+

+      This value represents an application (or upper layer) specified

+      protocol identifier.  This value is passed to SCTP by its upper

+      layer and sent to its peer.  This identifier is not used by SCTP

+      but can be used by certain network entities as well as the peer

+      application to identify the type of information being carried in

+      this DATA chunk. This field must be sent even in fragmented DATA

+      chunks (to make sure it is available for agents in the middle of

+      the network).

+

+      The value 0 indicates no application identifier is specified by

+      the upper layer for this payload data.

+

+   User Data: variable length

+

+      This is the payload user data.  The implementation MUST pad the

+      end of the data to a 4 byte boundary with all-zero bytes.  Any

+      padding MUST NOT be included in the length field.  A sender MUST

+      never add more than 3 bytes of padding.

+

+3.3.2 Initiation (INIT) (1)

+

+   This chunk is used to initiate a SCTP association between two

+   endpoints.  The format of the INIT chunk is shown below:

+

+       0                   1                   2                   3

+       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |   Type = 1    |  Chunk Flags  |      Chunk Length             |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |                         Initiate Tag                          |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |           Advertised Receiver Window Credit (a_rwnd)          |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |  Number of Outbound Streams   |  Number of Inbound Streams    |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |                          Initial TSN                          |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      \                                                               \

+      /              Optional/Variable-Length Parameters              /

+      \                                                               \

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+   The INIT chunk contains the following parameters.  Unless otherwise

+   noted, each parameter MUST only be included once in the INIT chunk.

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 24]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+         Fixed Parameters                     Status

+         ----------------------------------------------

+         Initiate Tag                        Mandatory

+         Advertised Receiver Window Credit   Mandatory

+         Number of Outbound Streams          Mandatory

+         Number of Inbound Streams           Mandatory

+         Initial TSN                         Mandatory

+

+         Variable Parameters                  Status     Type Value

+         -------------------------------------------------------------

+         IPv4 Address (Note 1)               Optional    5

+         IPv6 Address (Note 1)               Optional    6

+         Cookie Preservative                 Optional    9

+         Reserved for ECN Capable (Note 2)   Optional    32768 (0x8000)

+         Host Name Address (Note 3)          Optional    11

+         Supported Address Types (Note 4)    Optional    12

+

+   Note 1: The INIT chunks can contain multiple addresses that can be

+   IPv4 and/or IPv6 in any combination.

+

+   Note 2: The ECN capable field is reserved for future use of Explicit

+   Congestion Notification.

+

+   Note 3: An INIT chunk MUST NOT contain more than one Host Name

+   address parameter.  Moreover, the sender of the INIT MUST NOT combine

+   any other address types with the Host Name address in the INIT.  The

+   receiver of INIT MUST ignore any other address types if the Host Name

+   address parameter is present in the received INIT chunk.

+

+   Note 4: This parameter, when present, specifies all the address types

+   the sending endpoint can support.  The absence of this parameter

+   indicates that the sending endpoint can support any address type.

+

+   The Chunk Flags field in INIT is reserved and all bits in it should

+   be set to 0 by the sender and ignored by the receiver.  The sequence

+   of parameters within an INIT can be processed in any order.

+

+   Initiate Tag: 32 bits (unsigned integer)

+

+      The receiver of the INIT (the responding end) records the value of

+      the Initiate Tag parameter.  This value MUST be placed into the

+      Verification Tag field of every SCTP packet that the receiver of

+      the INIT transmits within this association.

+

+      The Initiate Tag is allowed to have any value except 0.  See

+      Section 5.3.1 for more on the selection of the tag value.

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 25]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+      If the value of the Initiate Tag in a received INIT chunk is found

+      to be 0, the receiver MUST treat it as an error and close the

+      association by transmitting an ABORT.

+

+   Advertised Receiver Window Credit (a_rwnd): 32 bits (unsigned

+      integer)

+

+      This value represents the dedicated buffer space, in number of

+      bytes, the sender of the INIT has reserved in association with

+      this window.  During the life of the association this buffer space

+      SHOULD not be lessened (i.e. dedicated buffers taken away from

+      this association); however, an endpoint MAY change the value of

+      a_rwnd it sends in SACK chunks.

+

+   Number of Outbound Streams (OS):  16 bits (unsigned integer)

+

+      Defines the number of outbound streams the sender of this INIT

+      chunk wishes to create in this association.  The value of 0 MUST

+      NOT be used.

+

+      Note: A receiver of an INIT with the OS value set to 0 SHOULD

+      abort the association.

+

+   Number of Inbound Streams (MIS) : 16 bits (unsigned integer)

+

+      Defines the maximum number of streams the sender of this INIT

+      chunk allows the peer end to create in this association.  The

+      value 0 MUST NOT be used.

+

+      Note: There is no negotiation of the actual number of streams but

+      instead the two endpoints will use the min(requested, offered).

+      See Section 5.1.1 for details.

+

+      Note: A receiver of an INIT with the MIS value of 0 SHOULD abort

+      the association.

+

+   Initial TSN (I-TSN) : 32 bits (unsigned integer)

+

+      Defines the initial TSN that the sender will use.  The valid range

+      is from 0 to 4294967295.  This field MAY be set to the value of

+      the Initiate Tag field.

+

+3.3.2.1 Optional/Variable Length Parameters in INIT

+

+   The following parameters follow the Type-Length-Value format as

+   defined in Section 3.2.1.  Any Type-Length-Value fields MUST come

+   after the fixed-length fields defined in the previous section.

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 26]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   IPv4 Address Parameter (5)

+

+       0                   1                   2                   3

+       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |        Type = 5               |      Length = 8               |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |                        IPv4 Address                           |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+

+   IPv4 Address: 32 bits (unsigned integer)

+

+      Contains an IPv4 address of the sending endpoint.  It is binary

+      encoded.

+

+   IPv6 Address Parameter (6)

+

+       0                   1                   2                   3

+       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |            Type = 6           |          Length = 20          |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |                                                               |

+      |                         IPv6 Address                          |

+      |                                                               |

+      |                                                               |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+   IPv6 Address: 128 bit (unsigned integer)

+

+      Contains an IPv6 address of the sending endpoint.  It is binary

+      encoded.

+

+      Note: A sender MUST NOT use an IPv4-mapped IPv6 address [RFC2373]

+      but should instead use an IPv4 Address Parameter for an IPv4

+      address.

+

+      Combined with the Source Port Number in the SCTP common header,

+      the value passed in an IPv4 or IPv6 Address parameter indicates a

+      transport address the sender of the INIT will support for the

+      association being initiated.  That is, during the lifetime of this

+      association, this IP address can appear in the source address

+      field of an IP datagram sent from the sender of the INIT, and can

+      be used as a destination address of an IP datagram sent from the

+      receiver of the INIT.

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 27]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+      More than one IP Address parameter can be included in an INIT

+      chunk when the INIT sender is multi-homed.  Moreover, a multi-

+      homed endpoint may have access to different types of network, thus

+      more than one address type can be present in one INIT chunk, i.e.,

+      IPv4 and IPv6 addresses are allowed in the same INIT chunk.

+

+      If the INIT contains at least one IP Address parameter, then the

+      source address of the IP datagram containing the INIT chunk and

+      any additional address(es) provided within the INIT can be used as

+      destinations by the endpoint receiving the INIT.  If the INIT does

+      not contain any IP Address parameters, the endpoint receiving the

+      INIT MUST use the source address associated with the received IP

+      datagram as its sole destination address for the association.

+

+      Note that not using any IP address parameters in the INIT and

+      INIT-ACK is an alternative to make an association more likely to

+      work across a NAT box.

+

+   Cookie Preservative (9)

+

+      The sender of the INIT shall use this parameter to suggest to the

+      receiver of the INIT for a longer life-span of the State Cookie.

+

+       0                   1                   2                   3

+       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |          Type = 9             |          Length = 8           |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |         Suggested Cookie Life-span Increment (msec.)          |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+   Suggested Cookie Life-span Increment: 32 bits (unsigned integer)

+

+      This parameter indicates to the receiver how much increment in

+      milliseconds the sender wishes the receiver to add to its default

+      cookie life-span.

+

+      This optional parameter should be added to the INIT chunk by the

+      sender when it re-attempts establishing an association with a peer

+      to which its previous attempt of establishing the association failed

+      due to a stale cookie operation error.  The receiver MAY choose to

+      ignore the suggested cookie life-span increase for its own security

+      reasons.

+

+

+

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 28]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   Host Name Address (11)

+

+      The sender of INIT uses this parameter to pass its Host Name (in

+      place of its IP addresses) to its peer.  The peer is responsible

+      for resolving the name.  Using this parameter might make it more

+      likely for the association to work across a NAT box.

+

+      0                   1                   2                   3

+      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |          Type = 11            |          Length               |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      /                          Host Name                            /

+      \                                                               \

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+   Host Name: variable length

+

+      This field contains a host name in "host name syntax" per RFC1123

+      Section 2.1 [RFC1123].  The method for resolving the host name is

+      out of scope of SCTP.

+

+      Note: At least one null terminator is included in the Host Name

+      string and must be included in the length.

+

+   Supported Address Types (12)

+

+      The sender of INIT uses this parameter to list all the address

+      types it can support.

+

+       0                   1                   2                   3

+       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |          Type = 12            |          Length               |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |        Address Type #1        |        Address Type #2        |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |        ......

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+   Address Type: 16 bits (unsigned integer)

+

+      This is filled with the type value of the corresponding address

+      TLV (e.g., IPv4 = 5, IPv6 = 6, Hostname = 11).

+

+

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 29]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+3.3.3 Initiation Acknowledgement (INIT ACK) (2):

+

+   The INIT ACK chunk is used to acknowledge the initiation of an SCTP

+   association.

+

+   The parameter part of INIT ACK is formatted similarly to the INIT

+   chunk.  It uses two extra variable parameters: The State Cookie and

+   the Unrecognized Parameter:

+

+   The format of the INIT ACK chunk is shown below:

+

+       0                   1                   2                   3

+       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |   Type = 2    |  Chunk Flags  |      Chunk Length             |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |                         Initiate Tag                          |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |              Advertised Receiver Window Credit                |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |  Number of Outbound Streams   |  Number of Inbound Streams    |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |                          Initial TSN                          |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      \                                                               \

+      /              Optional/Variable-Length Parameters              /

+      \                                                               \

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+   Initiate Tag: 32 bits (unsigned integer)

+

+      The receiver of the INIT ACK records the value of the Initiate Tag

+      parameter.  This value MUST be placed into the Verification Tag

+      field of every SCTP packet that the INIT ACK receiver transmits

+      within this association.

+

+      The Initiate Tag MUST NOT take the value 0.  See Section 5.3.1 for

+      more on the selection of the Initiate Tag value.

+

+      If the value of the Initiate Tag in a received INIT ACK chunk is

+      found to be 0, the receiver MUST treat it as an error and close

+      the association by transmitting an ABORT.

+

+

+

+

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 30]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   Advertised Receiver Window Credit (a_rwnd): 32 bits (unsigned

+   integer)

+

+      This value represents the dedicated buffer space, in number of

+      bytes, the sender of the INIT ACK has reserved in association with

+      this window.  During the life of the association this buffer space

+      SHOULD not be lessened (i.e. dedicated buffers taken away from

+      this association).

+

+   Number of Outbound Streams (OS):  16 bits (unsigned integer)

+

+      Defines the number of outbound streams the sender of this INIT ACK

+      chunk wishes to create in this association.  The value of 0 MUST

+      NOT be used.

+

+      Note: A receiver of an INIT ACK  with the OS value set to 0 SHOULD

+      destroy the association discarding its TCB.

+

+   Number of Inbound Streams (MIS) : 16 bits (unsigned integer)

+

+      Defines the maximum number of streams the sender of this INIT ACK

+      chunk allows the peer end to create in this association.  The

+      value 0 MUST NOT be used.

+

+      Note: There is no negotiation of the actual number of streams but

+      instead the two endpoints will use the min(requested, offered).

+      See Section 5.1.1 for details.

+

+      Note: A receiver of an INIT ACK  with the MIS value set to 0

+      SHOULD destroy the association discarding its TCB.

+

+   Initial TSN (I-TSN) : 32 bits (unsigned integer)

+

+      Defines the initial TSN that the INIT-ACK sender will use.  The

+      valid range is from 0 to 4294967295.  This field MAY be set to the

+      value of the Initiate Tag field.

+

+      Fixed Parameters                     Status

+      ----------------------------------------------

+      Initiate Tag                        Mandatory

+      Advertised Receiver Window Credit   Mandatory

+      Number of Outbound Streams          Mandatory

+      Number of Inbound Streams           Mandatory

+      Initial TSN                         Mandatory

+

+

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 31]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+      Variable Parameters                  Status     Type Value

+      -------------------------------------------------------------

+      State Cookie                        Mandatory   7

+      IPv4 Address (Note 1)               Optional    5

+      IPv6 Address (Note 1)               Optional    6

+      Unrecognized Parameters             Optional    8

+      Reserved for ECN Capable (Note 2)   Optional    32768 (0x8000)

+      Host Name Address (Note 3)          Optional    11

+

+   Note 1: The INIT ACK chunks can contain any number of IP address

+   parameters that can be IPv4 and/or IPv6 in any combination.

+

+   Note 2: The ECN capable field is reserved for future use of Explicit

+   Congestion Notification.

+

+   Note 3: The INIT ACK chunks MUST NOT contain more than one Host Name

+   address parameter.  Moreover, the sender of the INIT ACK MUST NOT

+   combine any other address types with the Host Name address in the

+   INIT ACK.  The receiver of the INIT ACK MUST ignore any other address

+   types if the Host Name address parameter is present.

+

+   IMPLEMENTATION NOTE: An implementation MUST be prepared to receive a

+   INIT ACK that is quite large (more than 1500 bytes) due to the

+   variable size of the state cookie AND the variable address list.  For

+   example if a responder to the INIT has 1000 IPv4 addresses it wishes

+   to send, it would need at least 8,000 bytes to encode this in the

+   INIT ACK.

+

+   In combination with the Source Port carried in the SCTP common

+   header, each IP Address parameter in the INIT ACK indicates to the

+   receiver of the INIT ACK a valid transport address supported by the

+   sender of the INIT ACK for the lifetime of the association being

+   initiated.

+

+   If the INIT ACK contains at least one IP Address parameter, then the

+   source address of the IP datagram containing the INIT ACK and any

+   additional address(es) provided within the INIT ACK may be used as

+   destinations by the receiver of the INIT-ACK.  If the INIT ACK does

+   not contain any IP Address parameters, the receiver of the INIT-ACK

+   MUST use the source address associated with the received IP datagram

+   as its sole destination address for the association.

+

+   The State Cookie and Unrecognized Parameters use the Type-Length-

+   Value format as defined in Section 3.2.1 and are described below.

+   The other fields are defined the same as their counterparts in the

+   INIT chunk.

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 32]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+3.3.3.1 Optional or Variable Length Parameters

+

+   State Cookie

+

+      Parameter Type Value: 7

+

+      Parameter Length:  variable size, depending on Size of Cookie

+

+      Parameter Value:

+

+         This parameter value MUST contain all the necessary state and

+         parameter information required for the sender of this INIT ACK

+         to create the association, along with a Message Authentication

+         Code (MAC).  See Section 5.1.3 for details on State Cookie

+         definition.

+

+   Unrecognized Parameters:

+

+      Parameter Type Value: 8

+

+      Parameter Length:  Variable Size.

+

+      Parameter Value:

+

+         This parameter is returned to the originator of the INIT chunk

+         when the INIT contains an unrecognized parameter which has a

+         value that indicates that it should be reported to the sender.

+         This parameter value field will contain unrecognized parameters

+         copied from the INIT chunk complete with Parameter Type, Length

+         and Value fields.

+

+3.3.4 Selective Acknowledgement (SACK) (3):

+

+   This chunk is sent to the peer endpoint to acknowledge received DATA

+   chunks and to inform the peer endpoint of gaps in the received

+   subsequences of DATA chunks as represented by their TSNs.

+

+   The SACK MUST contain the Cumulative TSN Ack and Advertised Receiver

+   Window Credit (a_rwnd) parameters.

+

+   By definition, the value of the Cumulative TSN Ack parameter is the

+   last TSN received before a break in the sequence of received TSNs

+   occurs; the next TSN value following this one has not yet been

+   received at the endpoint sending the SACK.  This parameter therefore

+   acknowledges receipt of all TSNs less than or equal to its value.

+

+   The handling of a_rwnd by the receiver of the SACK is discussed in

+   detail in Section 6.2.1.

+

+

+

+Stewart, et al.             Standards Track                    [Page 33]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   The SACK also contains zero or more Gap Ack Blocks.  Each Gap Ack

+   Block acknowledges a subsequence of TSNs received following a break

+   in the sequence of received TSNs.  By definition, all TSNs

+   acknowledged by Gap Ack Blocks are greater than the value of the

+   Cumulative TSN Ack.

+

+       0                   1                   2                   3

+       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |   Type = 3    |Chunk  Flags   |      Chunk Length             |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |                      Cumulative TSN Ack                       |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |          Advertised Receiver Window Credit (a_rwnd)           |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      | Number of Gap Ack Blocks = N  |  Number of Duplicate TSNs = X |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |  Gap Ack Block #1 Start       |   Gap Ack Block #1 End        |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      /                                                               /

+      \                              ...                              \

+      /                                                               /

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |   Gap Ack Block #N Start      |  Gap Ack Block #N End         |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |                       Duplicate TSN 1                         |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      /                                                               /

+      \                              ...                              \

+      /                                                               /

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |                       Duplicate TSN X                         |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+   Chunk Flags: 8 bits

+

+      Set to all zeros on transmit and ignored on receipt.

+

+   Cumulative TSN Ack: 32 bits (unsigned integer)

+

+      This parameter contains the TSN of the last DATA chunk received in

+      sequence before a gap.

+

+   Advertised Receiver Window Credit (a_rwnd): 32 bits (unsigned

+      integer)

+

+      This field indicates the updated receive buffer space in bytes of

+      the sender of this SACK, see Section 6.2.1 for details.

+

+

+

+Stewart, et al.             Standards Track                    [Page 34]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   Number of Gap Ack Blocks: 16 bits (unsigned integer)

+

+      Indicates the number of Gap Ack Blocks included in this SACK.

+

+   Number of Duplicate TSNs: 16 bit

+

+      This field contains the number of duplicate TSNs the endpoint has

+      received.  Each duplicate TSN is listed following the Gap Ack

+      Block list.

+

+   Gap Ack Blocks:

+

+      These fields contain the Gap Ack Blocks.  They are repeated for

+      each Gap Ack Block up to the number of Gap Ack Blocks defined in

+      the Number of Gap Ack Blocks field.  All DATA chunks with TSNs

+      greater than or equal to (Cumulative TSN Ack + Gap Ack Block

+      Start) and less than or equal to (Cumulative TSN Ack + Gap Ack

+      Block End) of each Gap Ack Block are assumed to have been received

+      correctly.

+

+   Gap Ack Block Start: 16 bits (unsigned integer)

+

+      Indicates the Start offset TSN for this Gap Ack Block.  To

+      calculate the actual TSN number the Cumulative TSN Ack is added to

+      this offset number.  This calculated TSN identifies the first TSN

+      in this Gap Ack Block that has been received.

+

+   Gap Ack Block End:  16 bits (unsigned integer)

+

+      Indicates the End offset TSN for this Gap Ack Block.  To calculate

+      the actual TSN number the Cumulative TSN Ack is added to this

+      offset number.  This calculated TSN identifies the TSN of the last

+      DATA chunk received in this Gap Ack Block.

+

+   For example, assume the receiver has the following DATA chunks newly

+   arrived at the time when it decides to send a Selective ACK,

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 35]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+                        ----------

+                        | TSN=17 |

+                        ----------

+                        |        | <- still missing

+                        ----------

+                        | TSN=15 |

+                        ----------

+                        | TSN=14 |

+                        ----------

+                        |        | <- still missing

+                        ----------

+                        | TSN=12 |

+                        ----------

+                        | TSN=11 |

+                        ----------

+                        | TSN=10 |

+                        ----------

+

+   then, the parameter part of the SACK MUST be constructed as follows

+   (assuming the new a_rwnd is set to 4660 by the sender):

+

+                  +--------------------------------+

+                  |   Cumulative TSN Ack = 12      |

+                  +--------------------------------+

+                  |        a_rwnd = 4660           |

+                  +----------------+---------------+

+                  | num of block=2 | num of dup=0  |

+                  +----------------+---------------+

+                  |block #1 strt=2 |block #1 end=3 |

+                  +----------------+---------------+

+                  |block #2 strt=5 |block #2 end=5 |

+                  +----------------+---------------+

+

+

+   Duplicate TSN: 32 bits (unsigned integer)

+

+      Indicates the number of times a TSN was received in duplicate

+      since the last SACK was sent.  Every time a receiver gets a

+      duplicate TSN (before sending the SACK) it adds it to the list of

+      duplicates.  The duplicate count is re-initialized to zero after

+      sending each SACK.

+

+      For example, if a receiver were to get the TSN 19 three times it

+      would list 19 twice in the outbound SACK.  After sending the SACK

+      if it received yet one more TSN 19 it would list 19 as a duplicate

+      once in the next outgoing SACK.

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 36]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+3.3.5 Heartbeat Request (HEARTBEAT) (4):

+

+   An endpoint should send this chunk to its peer endpoint to probe the

+   reachability of a particular destination transport address defined in

+   the present association.

+

+   The parameter field contains the Heartbeat Information which is a

+   variable length opaque data structure understood only by the sender.

+

+       0                   1                   2                   3

+       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |   Type = 4    | Chunk  Flags  |      Heartbeat Length         |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      \                                                               \

+      /            Heartbeat Information TLV (Variable-Length)        /

+      \                                                               \

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+   Chunk Flags: 8 bits

+

+      Set to zero on transmit and ignored on receipt.

+

+   Heartbeat Length: 16 bits (unsigned integer)

+

+      Set to the size of the chunk in bytes, including the chunk header

+      and the Heartbeat Information field.

+

+   Heartbeat Information: variable length

+

+      Defined as a variable-length parameter using the format described

+      in Section 3.2.1, i.e.:

+

+      Variable Parameters                  Status     Type Value

+      -------------------------------------------------------------

+      Heartbeat Info                       Mandatory   1

+

+       0                   1                   2                   3

+       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |    Heartbeat Info Type=1      |         HB Info Length        |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      /                  Sender-specific Heartbeat Info               /

+      \                                                               \

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 37]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+      The Sender-specific Heartbeat Info field should normally include

+      information about the sender's current time when this HEARTBEAT

+      chunk is sent and the destination transport address to which this

+      HEARTBEAT is sent (see Section 8.3).

+

+3.3.6 Heartbeat Acknowledgement (HEARTBEAT ACK) (5):

+

+   An endpoint should send this chunk to its peer endpoint as a response

+   to a HEARTBEAT chunk (see Section 8.3).  A HEARTBEAT ACK is always

+   sent to the source IP address of the IP datagram containing the

+   HEARTBEAT chunk to which this ack is responding.

+

+   The parameter field contains a variable length opaque data structure.

+

+       0                   1                   2                   3

+       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |   Type = 5    | Chunk  Flags  |    Heartbeat Ack Length       |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      \                                                               \

+      /            Heartbeat Information TLV (Variable-Length)        /

+      \                                                               \

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+   Chunk Flags: 8 bits

+

+      Set to zero on transmit and ignored on receipt.

+

+   Heartbeat Ack Length:  16 bits (unsigned integer)

+

+      Set to the size of the chunk in bytes, including the chunk header

+      and the Heartbeat Information field.

+

+   Heartbeat Information: variable length

+

+      This field MUST contain the Heartbeat Information parameter of

+      the Heartbeat Request to which this Heartbeat Acknowledgement is

+      responding.

+

+      Variable Parameters                  Status     Type Value

+      -------------------------------------------------------------

+      Heartbeat Info                       Mandatory   1

+

+

+

+

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 38]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+3.3.7 Abort Association (ABORT) (6):

+

+   The ABORT chunk is sent to the peer of an association to close the

+   association.  The ABORT chunk may contain Cause Parameters to inform

+   the receiver the reason of the abort.  DATA chunks MUST NOT be

+   bundled with ABORT.  Control chunks (except for INIT, INIT ACK and

+   SHUTDOWN COMPLETE) MAY be bundled with an ABORT but they MUST be

+   placed before the ABORT in the SCTP packet, or they will be ignored

+   by the receiver.

+

+   If an endpoint receives an ABORT with a format error or for an

+   association that doesn't exist, it MUST silently discard it.

+   Moreover, under any circumstances, an endpoint that receives an ABORT

+   MUST NOT respond to that ABORT by sending an ABORT of its own.

+

+       0                   1                   2                   3

+       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |   Type = 6    |Reserved     |T|           Length              |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      \                                                               \

+      /                   zero or more Error Causes                   /

+      \                                                               \

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+   Chunk Flags: 8 bits

+

+   Reserved:  7 bits

+

+      Set to 0 on transmit and ignored on receipt.

+

+   T bit:  1 bit

+

+      The T bit is set to 0 if the sender had a TCB that it destroyed.

+      If the sender did not have a TCB it should set this bit to 1.

+

+   Note: Special rules apply to this chunk for verification, please see

+   Section 8.5.1 for details.

+

+   Length:  16 bits (unsigned integer)

+

+      Set to the size of the chunk in bytes, including the chunk header

+      and all the Error Cause fields present.

+

+   See Section 3.3.10 for Error Cause definitions.

+

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 39]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+3.3.8 Shutdown Association (SHUTDOWN) (7):

+

+   An endpoint in an association MUST use this chunk to initiate a

+   graceful close of the association with its peer.  This chunk has the

+   following format.

+

+       0                   1                   2                   3

+       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |   Type = 7    | Chunk  Flags  |      Length = 8               |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |                      Cumulative TSN Ack                       |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+   Chunk Flags: 8 bits

+

+      Set to zero on transmit and ignored on receipt.

+

+   Length:  16 bits (unsigned integer)

+

+      Indicates the length of the parameter.  Set to 8.

+

+   Cumulative TSN Ack: 32 bits (unsigned integer)

+

+      This parameter contains the TSN of the last chunk received in

+      sequence before any gaps.

+

+      Note:  Since the SHUTDOWN message does not contain Gap Ack Blocks,

+      it cannot be used to acknowledge TSNs received out of order.  In a

+      SACK, lack of Gap Ack Blocks that were previously included

+      indicates that the data receiver reneged on the associated DATA

+      chunks.  Since SHUTDOWN does not contain Gap Ack Blocks, the

+      receiver of the SHUTDOWN shouldn't interpret the lack of a Gap Ack

+      Block as a renege. (see Section 6.2 for information on reneging)

+

+3.3.9 Shutdown Acknowledgement (SHUTDOWN ACK) (8):

+

+   This chunk MUST be used to acknowledge the receipt of the SHUTDOWN

+   chunk at the completion of the shutdown process, see Section 9.2 for

+   details.

+

+   The SHUTDOWN ACK chunk has no parameters.

+

+       0                   1                   2                   3

+       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |   Type = 8    |Chunk  Flags   |      Length = 4               |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+

+

+Stewart, et al.             Standards Track                    [Page 40]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   Chunk Flags:  8 bits

+

+      Set to zero on transmit and ignored on receipt.

+

+3.3.10 Operation Error (ERROR) (9):

+

+   An endpoint sends this chunk to its peer endpoint to notify it of

+   certain error conditions.  It contains one or more error causes.  An

+   Operation Error is not considered fatal in and of itself, but may be

+   used with an ABORT chunk to report a fatal condition.  It has the

+   following parameters:

+

+       0                   1                   2                   3

+       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |   Type = 9    | Chunk  Flags  |           Length              |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      \                                                               \

+      /                    one or more Error Causes                   /

+      \                                                               \

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+   Chunk Flags:  8 bits

+

+      Set to zero on transmit and ignored on receipt.

+

+   Length:  16 bits (unsigned integer)

+

+      Set to the size of the chunk in bytes, including the chunk header

+      and all the Error Cause fields present.

+

+   Error causes are defined as variable-length parameters using the

+   format described in 3.2.1, i.e.:

+

+       0                   1                   2                   3

+       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |           Cause Code          |       Cause Length            |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      /                    Cause-specific Information                 /

+      \                                                               \

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+   Cause Code: 16 bits (unsigned integer)

+

+      Defines the type of error conditions being reported.

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 41]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+      Cause Code

+      Value           Cause Code

+      ---------      ----------------

+       1              Invalid Stream Identifier

+       2              Missing Mandatory Parameter

+       3              Stale Cookie Error

+       4              Out of Resource

+       5              Unresolvable Address

+       6              Unrecognized Chunk Type

+       7              Invalid Mandatory Parameter

+       8              Unrecognized Parameters

+       9              No User Data

+      10              Cookie Received While Shutting Down

+

+   Cause Length: 16 bits (unsigned integer)

+

+      Set to the size of the parameter in bytes, including the Cause

+      Code, Cause Length, and Cause-Specific Information fields

+

+   Cause-specific Information: variable length

+

+      This field carries the details of the error condition.

+

+   Sections 3.3.10.1 - 3.3.10.10 define error causes for SCTP.

+   Guidelines for the IETF to define new error cause values are

+   discussed in Section 13.3.

+

+3.3.10.1 Invalid Stream Identifier (1)

+

+   Cause of error

+   ---------------

+   Invalid Stream Identifier:  Indicates endpoint received a DATA chunk

+   sent to a nonexistent stream.

+

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |     Cause Code=1              |      Cause Length=8           |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |        Stream Identifier      |         (Reserved)            |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+   Stream Identifier: 16 bits (unsigned integer)

+

+      Contains the Stream Identifier of the DATA chunk received in

+      error.

+

+

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 42]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   Reserved: 16 bits

+

+      This field is reserved.  It is set to all 0's on transmit and

+      Ignored on receipt.

+

+3.3.10.2 Missing Mandatory Parameter (2)

+

+   Cause of error

+   ---------------

+   Missing Mandatory Parameter:  Indicates that one or more mandatory

+   TLV parameters are missing in a received INIT or INIT ACK.

+

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |     Cause Code=2              |      Cause Length=8+N*2       |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |                   Number of missing params=N                  |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |   Missing Param Type #1       |   Missing Param Type #2       |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |   Missing Param Type #N-1     |   Missing Param Type #N       |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+   Number of Missing params:  32 bits (unsigned integer)

+

+      This field contains the number of parameters contained in the

+      Cause-specific Information field.

+

+   Missing Param Type:  16 bits (unsigned integer)

+

+      Each field will contain the missing mandatory parameter number.

+

+3.3.10.3 Stale Cookie Error (3)

+

+   Cause of error

+   --------------

+   Stale Cookie Error:  Indicates the receipt of a valid State Cookie

+   that has expired.

+

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |     Cause Code=3              |       Cause Length=8          |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |                 Measure of Staleness (usec.)                  |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+   Measure of Staleness:  32 bits (unsigned integer)

+

+      This field contains the difference, in microseconds, between the

+      current time and the time the State Cookie expired.

+

+

+

+Stewart, et al.             Standards Track                    [Page 43]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+      The sender of this error cause MAY choose to report how long past

+      expiration the State Cookie is by including a non-zero value in

+      the Measure of Staleness field.  If the sender does not wish to

+      provide this information it should set the Measure of Staleness

+      field to the value of zero.

+

+3.3.10.4 Out of Resource (4)

+

+   Cause of error

+   ---------------

+   Out of Resource: Indicates that the sender is out of resource.  This

+   is usually sent in combination with or within an ABORT.

+

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |     Cause Code=4              |      Cause Length=4           |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+3.3.10.5 Unresolvable Address (5)

+

+   Cause of error

+   ---------------

+   Unresolvable Address: Indicates that the sender is not able to

+   resolve the specified address parameter (e.g., type of address is not

+   supported by the sender).  This is usually sent in combination with

+   or within an ABORT.

+

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |     Cause Code=5              |      Cause Length             |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      /                  Unresolvable Address                         /

+      \                                                               \

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+   Unresolvable Address:  variable length

+

+      The unresolvable address field contains the complete Type, Length

+      and Value of the address parameter (or Host Name parameter) that

+      contains the unresolvable address or host name.

+

+3.3.10.6 Unrecognized Chunk Type (6)

+

+   Cause of error

+   ---------------

+   Unrecognized Chunk Type:  This error cause is returned to the

+   originator of the chunk if the receiver does not understand the chunk

+   and the upper bits of the 'Chunk Type' are set to 01 or 11.

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 44]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |     Cause Code=6              |      Cause Length             |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      /                  Unrecognized Chunk                           /

+      \                                                               \

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+   Unrecognized Chunk:  variable length

+

+      The Unrecognized Chunk field contains the unrecognized Chunk from

+      the SCTP packet complete with Chunk Type, Chunk Flags and Chunk

+      Length.

+

+3.3.10.7 Invalid Mandatory Parameter (7)

+

+   Cause of error

+   ---------------

+   Invalid Mandatory Parameter:  This error cause is returned to the

+   originator of an INIT or INIT ACK chunk when one of the mandatory

+   parameters is set to a invalid value.

+

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |     Cause Code=7              |      Cause Length=4           |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+3.3.10.8 Unrecognized Parameters (8)

+

+   Cause of error

+   ---------------

+   Unrecognized Parameters:  This error cause is returned to the

+   originator of the INIT ACK chunk if the receiver does not recognize

+   one or more Optional TLV parameters in the INIT ACK chunk.

+

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |     Cause Code=8              |      Cause Length             |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      /                  Unrecognized Parameters                      /

+      \                                                               \

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+   Unrecognized Parameters:  variable length

+

+      The Unrecognized Parameters field contains the unrecognized

+      parameters copied from the INIT ACK chunk complete with TLV.  This

+      error cause is normally contained in an ERROR chunk bundled with

+      the COOKIE ECHO chunk when responding to the INIT ACK, when the

+      sender of the COOKIE ECHO chunk wishes to report unrecognized

+      parameters.

+

+

+

+Stewart, et al.             Standards Track                    [Page 45]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+3.3.10.9 No User Data (9)

+

+   Cause of error

+   ---------------

+   No User Data:  This error cause is returned to the originator of a

+   DATA chunk if a received DATA chunk has no user data.

+

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |     Cause Code=9              |      Cause Length=8           |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      /                  TSN value                                    /

+      \                                                               \

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+   TSN value:  32 bits (+unsigned integer)

+

+      The TSN value field contains the TSN of the DATA chunk received

+      with no user data field.

+

+      This cause code is normally returned in an ABORT chunk (see

+      Section 6.2)

+

+3.3.10.10 Cookie Received While Shutting Down (10)

+

+   Cause of error

+   ---------------

+   Cookie Received While Shutting Down:  A COOKIE ECHO was received

+   While the endpoint was in SHUTDOWN-ACK-SENT state.  This error is

+   usually returned in an ERROR chunk bundled with the retransmitted

+   SHUTDOWN ACK.

+

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |     Cause Code=10              |      Cause Length=4          |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+3.3.11 Cookie Echo (COOKIE ECHO) (10):

+

+   This chunk is used only during the initialization of an association.

+   It is sent by the initiator of an association to its peer to complete

+   the initialization process.  This chunk MUST precede any DATA chunk

+   sent within the association, but MAY be bundled with one or more DATA

+   chunks in the same packet.

+

+

+

+

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 46]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+       0                   1                   2                   3

+       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |   Type = 10   |Chunk  Flags   |         Length                |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      /                     Cookie                                    /

+      \                                                               \

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+   Chunk Flags: 8 bit

+

+      Set to zero on transmit and ignored on receipt.

+

+   Length: 16 bits (unsigned integer)

+

+      Set to the size of the chunk in bytes, including the 4 bytes of

+      the chunk header and the size of the Cookie.

+

+   Cookie: variable size

+

+      This field must contain the exact cookie received in the State

+      Cookie parameter from the previous INIT ACK.

+

+      An implementation SHOULD make the cookie as small as possible to

+      insure interoperability.

+

+3.3.12 Cookie Acknowledgement (COOKIE ACK) (11):

+

+   This chunk is used only during the initialization of an association.

+   It is used to acknowledge the receipt of a COOKIE ECHO chunk.  This

+   chunk MUST precede any DATA or SACK chunk sent within the

+   association, but MAY be bundled with one or more DATA chunks or SACK

+   chunk in the same SCTP packet.

+

+       0                   1                   2                   3

+       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |   Type = 11   |Chunk  Flags   |     Length = 4                |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+   Chunk Flags: 8 bits

+

+      Set to zero on transmit and ignored on receipt.

+

+

+

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 47]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+3.3.13 Shutdown Complete (SHUTDOWN COMPLETE) (14):

+

+   This chunk MUST be used to acknowledge the receipt of the SHUTDOWN

+   ACK chunk at the completion of the shutdown process, see Section 9.2

+   for details.

+

+   The SHUTDOWN COMPLETE chunk has no parameters.

+

+       0                   1                   2                   3

+       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |   Type = 14   |Reserved     |T|      Length = 4               |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+   Chunk Flags: 8 bits

+

+   Reserved:  7 bits

+

+      Set to 0 on transmit and ignored on receipt.

+

+   T bit:  1 bit

+

+      The T bit is set to 0 if the sender had a TCB that it destroyed.

+      If the sender did not have a TCB it should set this bit to 1.

+

+   Note: Special rules apply to this chunk for verification, please see

+   Section 8.5.1 for details.

+

+4. SCTP Association State Diagram

+

+   During the lifetime of an SCTP association, the SCTP endpoint's

+   association progress from one state to another in response to various

+   events.  The events that may potentially advance an association's

+   state include:

+

+   o  SCTP user primitive calls, e.g., [ASSOCIATE], [SHUTDOWN], [ABORT],

+

+   o  Reception of INIT, COOKIE ECHO, ABORT, SHUTDOWN, etc., control

+      chunks, or

+

+   o  Some timeout events.

+

+   The state diagram in the figures below illustrates state changes,

+   together with the causing events and resulting actions.  Note that

+   some of the error conditions are not shown in the state diagram.

+   Full description of all special cases should be found in the text.

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 48]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   Note: Chunk names are given in all capital letters, while parameter

+   names have the first letter capitalized, e.g., COOKIE ECHO chunk type

+   vs. State Cookie parameter.  If more than one event/message can occur

+   which causes a state transition it is labeled (A), (B) etc.

+

+                       -----          -------- (frm any state)

+                     /       \      /  rcv ABORT      [ABORT]

+    rcv INIT        |         |    |   ----------  or ----------

+    --------------- |         v    v   delete TCB     snd ABORT

+    generate Cookie  \    +---------+                 delete TCB

+    snd INIT ACK       ---|  CLOSED |

+                          +---------+

+                           /      \      [ASSOCIATE]

+                          /        \     ---------------

+                         |          |    create TCB

+                         |          |    snd INIT

+                         |          |    strt init timer

+          rcv valid      |          |

+        COOKIE  ECHO     |          v

+    (1) ---------------- |      +------------+

+        create TCB       |      | COOKIE-WAIT| (2)

+        snd COOKIE ACK   |      +------------+

+                         |          |

+                         |          |    rcv INIT ACK

+                         |          |    -----------------

+                         |          |    snd COOKIE ECHO

+                         |          |    stop init timer

+                         |          |    strt cookie timer

+                         |          v

+                         |      +--------------+

+                         |      | COOKIE-ECHOED| (3)

+                         |      +--------------+

+                         |          |

+                         |          |    rcv COOKIE ACK

+                         |          |    -----------------

+                         |          |    stop cookie timer

+                         v          v

+                       +---------------+

+                       |  ESTABLISHED  |

+                       +---------------+

+

+

+

+

+

+

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 49]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+                      (from the ESTABLISHED state only)

+                                    |

+                                    |

+                           /--------+--------\

+       [SHUTDOWN]         /                   \

+       -------------------|                   |

+       check outstanding  |                   |

+       DATA chunks        |                   |

+                          v                   |

+                     +---------+              |

+                     |SHUTDOWN-|              | rcv SHUTDOWN/check

+                     |PENDING  |              | outstanding DATA

+                     +---------+              | chunks

+                          |                   |------------------

+     No more outstanding  |                   |

+     ---------------------|                   |

+     snd SHUTDOWN         |                   |

+     strt shutdown timer  |                   |

+                          v                   v

+                     +---------+        +-----------+

+                 (4) |SHUTDOWN-|        | SHUTDOWN- |  (5,6)

+                     |SENT     |        | RECEIVED  |

+                     +---------+        +-----------+

+                          |  \                |

+    (A) rcv SHUTDOWN ACK  |   \               |

+    ----------------------|    \              |

+    stop shutdown timer   |     \rcv:SHUTDOWN |

+    send SHUTDOWN COMPLETE|      \  (B)       |

+    delete TCB            |       \           |

+                          |        \          | No more outstanding

+                          |         \         |-----------------

+                          |          \        | send SHUTDOWN ACK

+    (B)rcv SHUTDOWN       |           \       | strt shutdown timer

+    ----------------------|            \      |

+    send SHUTDOWN ACK     |             \     |

+    start shutdown timer  |              \    |

+    move to SHUTDOWN-     |               \   |

+    ACK-SENT              |                |  |

+                          |                v  |

+                          |             +-----------+

+                          |             | SHUTDOWN- | (7)

+                          |             | ACK-SENT  |

+                          |             +----------+-

+                          |                   | (C)rcv SHUTDOWN COMPLETE

+                          |                   |-----------------

+                          |                   | stop shutdown timer

+                          |                   | delete TCB

+                          |                   |

+

+

+

+Stewart, et al.             Standards Track                    [Page 50]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+                          |                   | (D)rcv SHUTDOWN ACK

+                          |                   |--------------

+                          |                   | stop shutdown timer

+                          |                   | send SHUTDOWN COMPLETE

+                          |                   | delete TCB

+                          |                   |

+                          \    +---------+    /

+                           \-->| CLOSED  |<--/

+                               +---------+

+

+              Figure 3: State Transition Diagram of SCTP

+

+   Notes:

+

+   1) If the State Cookie in the received COOKIE ECHO is invalid (i.e.,

+      failed to pass the integrity check), the receiver MUST silently

+      discard the packet.  Or, if the received State Cookie is expired

+      (see Section 5.1.5), the receiver MUST send back an ERROR chunk.

+      In either case, the receiver stays in the CLOSED state.

+

+   2) If the T1-init timer expires, the endpoint MUST retransmit INIT

+      and re-start the T1-init timer without changing state.  This MUST

+      be repeated up to 'Max.Init.Retransmits' times.  After that, the

+      endpoint MUST abort the initialization process and report the

+      error to SCTP user.

+

+   3) If the T1-cookie timer expires, the endpoint MUST retransmit

+      COOKIE ECHO and re-start the T1-cookie timer without changing

+      state.  This MUST be repeated up to 'Max.Init.Retransmits' times.

+      After that, the endpoint MUST abort the initialization process and

+      report the error to SCTP user.

+

+   4) In SHUTDOWN-SENT state the endpoint MUST acknowledge any received

+      DATA chunks without delay.

+

+   5) In SHUTDOWN-RECEIVED state, the endpoint MUST NOT accept any new

+      send request from its SCTP user.

+

+   6) In SHUTDOWN-RECEIVED state, the endpoint MUST transmit or

+      retransmit data and leave this state when all data in queue is

+      transmitted.

+

+   7) In SHUTDOWN-ACK-SENT state, the endpoint MUST NOT accept any new

+      send request from its SCTP user.

+

+   The CLOSED state is used to indicate that an association is not

+   created (i.e., doesn't exist).

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 51]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+5. Association Initialization

+

+   Before the first data transmission can take place from one SCTP

+   endpoint ("A") to another SCTP endpoint ("Z"), the two endpoints must

+   complete an initialization process in order to set up an SCTP

+   association between them.

+

+   The SCTP user at an endpoint should use the ASSOCIATE primitive to

+   initialize an SCTP association to another SCTP endpoint.

+

+   IMPLEMENTATION NOTE: From an SCTP-user's point of view, an

+   association may be implicitly opened, without an ASSOCIATE primitive

+   (see 10.1 B) being invoked, by the initiating endpoint's sending of

+   the first user data to the destination endpoint.  The initiating SCTP

+   will assume default values for all mandatory and optional parameters

+   for the INIT/INIT ACK.

+

+   Once the association is established, unidirectional streams are open

+   for data transfer on both ends (see Section 5.1.1).

+

+5.1 Normal Establishment of an Association

+

+   The initialization process consists of the following steps (assuming

+   that SCTP endpoint "A" tries to set up an association with SCTP

+   endpoint "Z" and "Z" accepts the new association):

+

+   A) "A" first sends an INIT chunk to "Z".  In the INIT, "A" must

+      provide its Verification Tag (Tag_A) in the Initiate Tag field.

+      Tag_A SHOULD be a random number in the range of 1 to 4294967295

+      (see 5.3.1 for Tag value selection).  After sending the INIT, "A"

+      starts the T1-init timer and enters the COOKIE-WAIT state.

+

+   B) "Z" shall respond immediately with an INIT ACK chunk.  The

+      destination IP address of the INIT ACK MUST be set to the source

+      IP address of the INIT to which this INIT ACK is responding.  In

+      the response, besides filling in other parameters, "Z" must set

+      the Verification Tag field to Tag_A, and also provide its own

+      Verification Tag (Tag_Z) in the Initiate Tag field.

+

+      Moreover, "Z" MUST generate and send along with the INIT ACK a

+      State Cookie.  See Section 5.1.3 for State Cookie generation.

+

+      Note: After sending out INIT ACK with the State Cookie parameter,

+      "Z" MUST NOT allocate any resources, nor keep any states for the

+      new association.  Otherwise, "Z" will be vulnerable to resource

+      attacks.

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 52]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   C) Upon reception of the INIT ACK from "Z", "A" shall stop the T1-

+      init timer and leave COOKIE-WAIT state.  "A" shall then send the

+      State Cookie received in the INIT ACK chunk in a COOKIE ECHO

+      chunk, start the T1-cookie timer, and enter the COOKIE-ECHOED

+      state.

+

+      Note: The COOKIE ECHO chunk can be bundled with any pending

+      outbound DATA chunks, but it MUST be the first chunk in the packet

+      and until the COOKIE ACK is returned the sender MUST NOT send any

+      other packets to the peer.

+

+   D) Upon reception of the COOKIE ECHO chunk, Endpoint "Z" will reply

+      with a COOKIE ACK chunk after building a TCB and moving to the

+      ESTABLISHED state.  A COOKIE ACK chunk may be bundled with any

+      pending DATA chunks (and/or SACK chunks), but the COOKIE ACK chunk

+      MUST be the first chunk in the packet.

+

+      IMPLEMENTATION NOTE: An implementation may choose to send the

+      Communication Up notification to the SCTP user upon reception of a

+      valid COOKIE ECHO chunk.

+

+   E) Upon reception of the COOKIE ACK, endpoint "A" will move from the

+      COOKIE-ECHOED state to the ESTABLISHED state, stopping the T1-

+      cookie timer.  It may also notify its ULP about the successful

+      establishment of the association with a Communication Up

+      notification (see Section 10).

+

+   An INIT or INIT ACK chunk MUST NOT be bundled with any other chunk.

+   They MUST be the only chunks present in the SCTP packets that carry

+   them.

+

+   An endpoint MUST send the INIT ACK to the IP address from which it

+   received the INIT.

+

+   Note: T1-init timer and T1-cookie timer shall follow the same rules

+   given in Section 6.3.

+

+   If an endpoint receives an INIT, INIT ACK, or COOKIE ECHO chunk but

+   decides not to establish the new association due to missing mandatory

+   parameters in the received INIT or INIT ACK, invalid parameter

+   values, or lack of local resources, it MUST respond with an ABORT

+   chunk.  It SHOULD also specify the cause of abort, such as the type

+   of the missing mandatory parameters, etc., by including the error

+   cause parameters with the ABORT chunk.  The Verification Tag field in

+   the common header of the outbound SCTP packet containing the ABORT

+   chunk MUST be set to the Initiate Tag value of the peer.

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 53]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   After the reception of the first DATA chunk in an association the

+   endpoint MUST immediately respond with a SACK to acknowledge the DATA

+   chunk.  Subsequent acknowledgements should be done as described in

+   Section 6.2.

+

+   When the TCB is created, each endpoint MUST set its internal

+   Cumulative TSN Ack Point to the value of its transmitted Initial TSN

+   minus one.

+

+   IMPLEMENTATION NOTE:  The IP addresses and SCTP port are generally

+   used as the key to find the TCB within an SCTP instance.

+

+5.1.1 Handle Stream Parameters

+

+   In the INIT and INIT ACK chunks, the sender of the chunk shall

+   indicate the number of outbound streams (OS) it wishes to have in the

+   association, as well as the maximum inbound streams (MIS) it will

+   accept from the other endpoint.

+

+   After receiving the stream configuration information from the other

+   side, each endpoint shall perform the following check:  If the peer's

+   MIS is less than the endpoint's OS, meaning that the peer is

+   incapable of supporting all the outbound streams the endpoint wants

+   to configure, the endpoint MUST either use MIS outbound streams, or

+   abort the association and report to its upper layer the resources

+   shortage at its peer.

+

+   After the association is initialized, the valid outbound stream

+   identifier range for either endpoint shall be 0 to min(local OS,

+   remote MIS)-1.

+

+5.1.2 Handle Address Parameters

+

+   During the association initialization, an endpoint shall use the

+   following rules to discover and collect the destination transport

+   address(es) of its peer.

+

+   A) If there are no address parameters present in the received INIT or

+      INIT ACK chunk, the endpoint shall take the source IP address from

+      which the chunk arrives and record it, in combination with the

+      SCTP source port number, as the only destination transport address

+      for this peer.

+

+   B) If there is a Host Name parameter present in the received INIT or

+      INIT ACK chunk, the endpoint shall resolve that host name to a

+      list of IP address(es) and derive the transport address(es) of

+      this peer by combining the resolved IP address(es) with the SCTP

+      source port.

+

+

+

+Stewart, et al.             Standards Track                    [Page 54]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+      The endpoint MUST ignore any other IP address parameters if they

+      are also present in the received INIT or INIT ACK chunk.

+

+      The time at which the receiver of an INIT resolves the host name

+      has potential security implications to SCTP.  If the receiver of

+      an INIT resolves the host name upon the reception of the chunk,

+      and the mechanism the receiver uses to resolve the host name

+      involves potential long delay (e.g. DNS query), the receiver may

+      open itself up to resource attacks for the period of time while it

+      is waiting for the name resolution results before it can build the

+      State Cookie and release local resources.

+

+      Therefore, in cases where the name translation involves potential

+      long delay, the receiver of the INIT MUST postpone the name

+      resolution till the reception of the COOKIE ECHO chunk from the

+      peer.  In such a case, the receiver of the INIT SHOULD build the

+      State Cookie using the received Host Name (instead of destination

+      transport addresses) and send the INIT ACK to the source IP

+      address from which the INIT was received.

+

+      The receiver of an INIT ACK shall always immediately attempt to

+      resolve the name upon the reception of the chunk.

+

+      The receiver of the INIT or INIT ACK MUST NOT send user data

+      (piggy-backed or stand-alone) to its peer until the host name is

+      successfully resolved.

+

+      If the name resolution is not successful, the endpoint MUST

+      immediately send an ABORT with "Unresolvable Address" error cause

+      to its peer.  The ABORT shall be sent to the source IP address

+      from which the last peer packet was received.

+

+   C) If there are only IPv4/IPv6 addresses present in the received INIT

+      or INIT ACK chunk, the receiver shall derive and record all the

+      transport address(es) from the received chunk AND the source IP

+      address that sent the INIT or INIT ACK.  The transport address(es)

+      are derived by the combination of SCTP source port (from the

+      common header) and the IP address parameter(s) carried in the INIT

+      or INIT ACK chunk and the source IP address of the IP datagram.

+      The receiver should use only these transport addresses as

+      destination transport addresses when sending subsequent packets to

+      its peer.

+

+      IMPLEMENTATION NOTE: In some cases (e.g., when the implementation

+      doesn't control the source IP address that is used for

+      transmitting), an endpoint might need to include in its INIT or

+      INIT ACK all possible IP addresses from which packets to the peer

+      could be transmitted.

+

+

+

+Stewart, et al.             Standards Track                    [Page 55]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   After all transport addresses are derived from the INIT or INIT ACK

+   chunk using the above rules, the endpoint shall select one of the

+   transport addresses as the initial primary path.

+

+   Note: The INIT-ACK MUST be sent to the source address of the INIT.

+

+   The sender of INIT may include a 'Supported Address Types' parameter

+   in the INIT to indicate what types of address are acceptable.  When

+   this parameter is present, the receiver of INIT (initiatee) MUST

+   either use one of the address types indicated in the Supported

+   Address Types parameter when responding to the INIT, or abort the

+   association with an "Unresolvable Address" error cause if it is

+   unwilling or incapable of using any of the address types indicated by

+   its peer.

+

+   IMPLEMENTATION NOTE: In the case that the receiver of an INIT ACK

+   fails to resolve the address parameter due to an unsupported type, it

+   can abort the initiation process and then attempt a re-initiation by

+   using a 'Supported Address Types' parameter in the new INIT to

+   indicate what types of address it prefers.

+

+5.1.3 Generating State Cookie

+

+   When sending an INIT ACK as a response to an INIT chunk, the sender

+   of INIT ACK creates a State Cookie and sends it in the State Cookie

+   parameter of the INIT ACK.  Inside this State Cookie, the sender

+   should include a MAC (see [RFC2104] for an example), a time stamp on

+   when the State Cookie is created, and the lifespan of the State

+   Cookie, along with all the information necessary for it to establish

+   the association.

+

+   The following steps SHOULD be taken to generate the State Cookie:

+

+   1) Create an association TCB using information from both the received

+      INIT and the outgoing INIT ACK chunk,

+

+   2) In the TCB, set the creation time to the current time of day, and

+      the lifespan to the protocol parameter 'Valid.Cookie.Life',

+

+   3) From the TCB, identify and collect the minimal subset of

+      information needed to re-create the TCB, and generate a MAC using

+      this subset of information and a secret key (see [RFC2104] for an

+      example of generating a MAC), and

+

+   4) Generate the State Cookie by combining this subset of information

+      and the resultant MAC.

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 56]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   After sending the INIT ACK with the State Cookie parameter, the

+   sender SHOULD delete the TCB and any other local resource related to

+   the new association, so as to prevent resource attacks.

+

+   The hashing method used to generate the MAC is strictly a private

+   matter for the receiver of the INIT chunk.  The use of a MAC is

+   mandatory to prevent denial of service attacks.  The secret key

+   SHOULD be random ([RFC1750] provides some information on randomness

+   guidelines); it SHOULD be changed reasonably frequently, and the

+   timestamp in the State Cookie MAY be used to determine which key

+   should be used to verify the MAC.

+

+   An implementation SHOULD make the cookie as small as possible to

+   insure interoperability.

+

+5.1.4 State Cookie Processing

+

+   When an endpoint (in the COOKIE WAIT state) receives an INIT ACK

+   chunk with a State Cookie parameter, it MUST immediately send a

+   COOKIE ECHO chunk to its peer with the received State Cookie.  The

+   sender MAY also add any pending DATA chunks to the packet after the

+   COOKIE ECHO chunk.

+

+   The endpoint shall also start the T1-cookie timer after sending out

+   the COOKIE ECHO chunk.  If the timer expires, the endpoint shall

+   retransmit the COOKIE ECHO chunk and restart the T1-cookie timer.

+   This is repeated until either a COOKIE ACK is received or '

+   Max.Init.Retransmits' is reached causing the peer endpoint to be

+   marked unreachable (and thus the association enters the CLOSED

+   state).

+

+5.1.5 State Cookie Authentication

+

+   When an endpoint receives a COOKIE ECHO chunk from another endpoint

+   with which it has no association, it shall take the following

+   actions:

+

+   1) Compute a MAC using the TCB data carried in the State Cookie and

+      the secret key (note the timestamp in the State Cookie MAY be used

+      to determine which secret key to use).  Reference [RFC2104] can be

+      used as a guideline for generating the MAC,

+

+   2) Authenticate the State Cookie as one that it previously generated

+      by comparing the computed MAC against the one carried in the State

+      Cookie.  If this comparison fails, the SCTP packet, including the

+      COOKIE ECHO and any DATA chunks, should be silently discarded,

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 57]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   3) Compare the creation timestamp in the State Cookie to the current

+      local time.  If the elapsed time is longer than the lifespan

+      carried in the State Cookie, then the packet, including the COOKIE

+      ECHO and any attached DATA chunks, SHOULD be discarded and the

+      endpoint MUST transmit an ERROR chunk with a "Stale Cookie" error

+      cause to the peer endpoint,

+

+   4) If the State Cookie is valid, create an association to the sender

+      of the COOKIE ECHO chunk with the information in the TCB data

+      carried in the COOKIE ECHO, and enter the ESTABLISHED state,

+

+   5) Send a COOKIE ACK chunk to the peer acknowledging reception of the

+      COOKIE ECHO.  The COOKIE ACK MAY be bundled with an outbound DATA

+      chunk or SACK chunk; however, the COOKIE ACK MUST be the first

+      chunk in the SCTP packet.

+

+   6) Immediately acknowledge any DATA chunk bundled with the COOKIE

+      ECHO with a SACK (subsequent DATA chunk acknowledgement should

+      follow the rules defined in Section 6.2).  As mentioned in step

+      5), if the SACK is bundled with the COOKIE ACK, the COOKIE ACK

+      MUST appear first in the SCTP packet.

+

+   If a COOKIE ECHO is received from an endpoint with which the receiver

+   of the COOKIE ECHO has an existing association, the procedures in

+   Section 5.2 should be followed.

+

+5.1.6 An Example of Normal Association Establishment

+

+   In the following example, "A" initiates the association and then

+   sends a user message to "Z", then "Z" sends two user messages to "A"

+   later (assuming no bundling or fragmentation occurs):

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 58]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   Endpoint A                                          Endpoint Z

+   {app sets association with Z}

+   (build TCB)

+   INIT [I-Tag=Tag_A

+         & other info]  --------\

+   (Start T1-init timer)         \

+   (Enter COOKIE-WAIT state)      \---> (compose temp TCB and Cookie_Z)

+

+                                   /--- INIT ACK [Veri Tag=Tag_A,

+                                  /              I-Tag=Tag_Z,

+   (Cancel T1-init timer) <------/               Cookie_Z, & other info]

+                                        (destroy temp TCB)

+   COOKIE ECHO [Cookie_Z] ------\

+   (Start T1-init timer)         \

+   (Enter COOKIE-ECHOED state)    \---> (build TCB enter ESTABLISHED

+                                         state)

+

+

+                                  /---- COOKIE-ACK

+                                 /

+   (Cancel T1-init timer, <-----/

+    Enter ESTABLISHED state)

+   {app sends 1st user data; strm 0}

+   DATA [TSN=initial TSN_A

+       Strm=0,Seq=1 & user data]--\

+    (Start T3-rtx timer)            \

+                                     \->

+                                 /----- SACK [TSN Ack=init

+                                             TSN_A,Block=0]

+   (Cancel T3-rtx timer) <------/

+

+                                        ...

+                                        {app sends 2 messages;strm 0}

+                                  /---- DATA

+                                 /        [TSN=init TSN_Z

+                             <--/          Strm=0,Seq=1 & user data 1]

+   SACK [TSN Ack=init TSN_Z,      /---- DATA

+         Block=0]     --------\  /        [TSN=init TSN_Z +1,

+                               \/          Strm=0,Seq=2 & user data 2]

+                        <------/\

+                                 \

+                                  \------>

+

+                     Figure 4: INITiation Example

+

+   If the T1-init timer expires at "A" after the INIT or COOKIE ECHO

+   chunks are sent, the same INIT or COOKIE ECHO chunk with the same

+   Initiate Tag (i.e., Tag_A) or State Cookie shall be retransmitted and

+

+

+

+Stewart, et al.             Standards Track                    [Page 59]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   the timer restarted.  This shall be repeated Max.Init.Retransmits

+   times before "A" considers "Z" unreachable and reports the failure to

+   its upper layer (and thus the association enters the CLOSED state).

+   When retransmitting the INIT, the endpoint MUST follow the rules

+   defined in 6.3 to determine the proper timer value.

+

+5.2 Handle Duplicate or Unexpected INIT, INIT ACK, COOKIE ECHO, and

+   COOKIE ACK

+

+   During the lifetime of an association (in one of the possible

+   states), an endpoint may receive from its peer endpoint one of the

+   setup chunks (INIT, INIT ACK, COOKIE ECHO, and COOKIE ACK).  The

+   receiver shall treat such a setup chunk as a duplicate and process it

+   as described in this section.

+

+   Note:  An endpoint will not receive the chunk unless the chunk was

+   sent to a SCTP transport address and is from a SCTP transport address

+   associated with this endpoint.  Therefore, the endpoint processes

+   such a chunk as part of its current association.

+

+   The following scenarios can cause duplicated or unexpected chunks:

+

+   A) The peer has crashed without being detected, re-started itself and

+      sent out a new INIT chunk trying to restore the association,

+

+   B) Both sides are trying to initialize the association at about the

+      same time,

+

+   C) The chunk is from a stale packet that was used to establish the

+      present association or a past association that is no longer in

+      existence,

+

+   D) The chunk is a false packet generated by an attacker, or

+

+   E) The peer never received the COOKIE ACK and is retransmitting its

+      COOKIE ECHO.

+

+   The rules in the following sections shall be applied in order to

+   identify and correctly handle these cases.

+

+5.2.1 INIT received in COOKIE-WAIT or COOKIE-ECHOED State (Item B)

+

+   This usually indicates an initialization collision, i.e., each

+   endpoint is attempting, at about the same time, to establish an

+   association with the other endpoint.

+

+   Upon receipt of an INIT in the COOKIE-WAIT or COOKIE-ECHOED state, an

+   endpoint MUST respond with an INIT ACK using the same parameters it

+

+

+

+Stewart, et al.             Standards Track                    [Page 60]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   sent in its original INIT chunk (including its Initiation Tag,

+   unchanged).  These original parameters are combined with those from

+   the newly received INIT chunk.  The endpoint shall also generate a

+   State Cookie with the INIT ACK.  The endpoint uses the parameters

+   sent in its INIT to calculate the State Cookie.

+

+   After that, the endpoint MUST NOT change its state, the T1-init timer

+   shall be left running and the corresponding TCB MUST NOT be

+   destroyed.  The normal procedures for handling State Cookies when a

+   TCB exists will resolve the duplicate INITs to a single association.

+

+   For an endpoint that is in the COOKIE-ECHOED state it MUST populate

+   its Tie-Tags with the Tag information of itself and its peer (see

+   section 5.2.2 for a description of the Tie-Tags).

+

+5.2.2 Unexpected INIT in States Other than CLOSED, COOKIE-ECHOED,

+         COOKIE-WAIT and SHUTDOWN-ACK-SENT

+

+   Unless otherwise stated, upon reception of an unexpected INIT for

+   this association, the endpoint shall generate an INIT ACK with a

+   State Cookie.  In the outbound INIT ACK the endpoint MUST copy its

+   current Verification Tag and peer's Verification Tag into a reserved

+   place within the state cookie.  We shall refer to these locations as

+   the Peer's-Tie-Tag and the Local-Tie-Tag.  The outbound SCTP packet

+   containing this INIT ACK MUST carry a Verification Tag value equal to

+   the Initiation Tag found in the unexpected INIT.  And the INIT ACK

+   MUST contain a new Initiation Tag (randomly generated see Section

+   5.3.1).  Other parameters for the endpoint SHOULD be copied from the

+   existing parameters of the association (e.g. number of outbound

+   streams) into the INIT ACK and cookie.

+

+   After sending out the INIT ACK, the endpoint shall take no further

+   actions, i.e., the existing association, including its current state,

+   and the corresponding TCB MUST NOT be changed.

+

+   Note: Only when a TCB exists and the association is not in a COOKIE-

+   WAIT state are the Tie-Tags populated.  For a normal association INIT

+   (i.e. the endpoint is in a COOKIE-WAIT state), the Tie-Tags MUST be

+   set to 0 (indicating that no previous TCB existed).  The INIT ACK and

+   State Cookie are populated as specified in section 5.2.1.

+

+5.2.3 Unexpected INIT ACK

+

+   If an INIT ACK is received by an endpoint in any state other than the

+   COOKIE-WAIT state, the endpoint should discard the INIT ACK chunk.

+   An unexpected INIT ACK usually indicates the processing of an old or

+   duplicated INIT chunk.

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 61]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+5.2.4 Handle a COOKIE ECHO when a TCB exists

+

+   When a COOKIE ECHO chunk is received by an endpoint in any state for

+   an existing association (i.e., not in the CLOSED state) the following

+   rules shall be applied:

+

+   1) Compute a MAC as described in Step 1 of Section 5.1.5,

+

+   2) Authenticate the State Cookie as described in Step 2 of Section

+      5.1.5 (this is case C or D above).

+

+   3) Compare the timestamp in the State Cookie to the current time.  If

+      the State Cookie is older than the lifespan carried in the State

+      Cookie and the Verification Tags contained in the State Cookie do

+      not match the current association's Verification Tags, the packet,

+      including the COOKIE ECHO and any DATA chunks, should be

+      discarded.  The endpoint also MUST transmit an ERROR chunk with a

+      "Stale Cookie" error cause to the peer endpoint (this is case C or

+      D in section 5.2).

+

+      If both Verification Tags in the State Cookie match the

+      Verification Tags of the current association, consider the State

+      Cookie valid (this is case E of section 5.2) even if the lifespan

+      is exceeded.

+

+   4) If the State Cookie proves to be valid, unpack the TCB into a

+      temporary TCB.

+

+   5) Refer to Table 2 to determine the correct action to be taken.

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 62]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

++------------+------------+---------------+--------------+-------------+

+|  Local Tag | Peer's Tag | Local-Tie-Tag |Peer's-Tie-Tag|   Action/   |

+|            |            |               |              | Description |

++------------+------------+---------------+--------------+-------------+

+|    X       |     X      |      M        |      M       |     (A)     |

++------------+------------+---------------+--------------+-------------+

+|    M       |     X      |      A        |      A       |     (B)     |

++------------+------------+---------------+--------------+-------------+

+|    M       |     0      |      A        |      A       |     (B)     |

++------------+------------+---------------+--------------+-------------+

+|    X       |     M      |      0        |      0       |     (C)     |

++------------+------------+---------------+--------------+-------------+

+|    M       |     M      |      A        |      A       |     (D)     |

++======================================================================+

+|       Table 2: Handling of a COOKIE ECHO when a TCB exists           |

++======================================================================+

+

+   Legend:

+

+      X - Tag does not match the existing TCB

+      M - Tag matches the existing TCB.

+      0 - No Tie-Tag in Cookie (unknown).

+      A - All cases, i.e. M, X or 0.

+

+   Note: For any case not shown in Table 2, the cookie should be

+   silently discarded.

+

+   Action

+

+   A) In this case, the peer may have restarted.  When the endpoint

+      recognizes this potential 'restart', the existing session is

+      treated the same as if it received an ABORT followed by a new

+      COOKIE ECHO with the following exceptions:

+

+      -  Any SCTP DATA Chunks MAY be retained (this is an implementation

+         specific option).

+

+      -  A notification of RESTART SHOULD be sent to the ULP instead of

+         a "COMMUNICATION LOST" notification.

+

+      All the congestion control parameters (e.g., cwnd, ssthresh)

+      related to this peer MUST be reset to their initial values (see

+      Section 6.2.1).

+

+      After this the endpoint shall enter the ESTABLISHED state.

+

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 63]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+      If the endpoint is in the SHUTDOWN-ACK-SENT state and recognizes

+      the peer has restarted (Action A), it MUST NOT setup a new

+      association but instead resend the SHUTDOWN ACK and send an ERROR

+      chunk with a "Cookie Received while Shutting Down" error cause to

+      its peer.

+

+   B) In this case, both sides may be attempting to start an association

+      at about the same time but the peer endpoint started its INIT

+      after responding to the local endpoint's INIT.  Thus it may have

+      picked a new Verification Tag not being aware of the previous Tag

+      it had sent this endpoint.  The endpoint should stay in or enter

+      the ESTABLISHED state but it MUST update its peer's Verification

+      Tag from the State Cookie, stop any init or cookie timers that may

+      running and send a COOKIE ACK.

+

+   C) In this case, the local endpoint's cookie has arrived late.

+      Before it arrived, the local endpoint sent an INIT and received an

+      INIT-ACK and finally sent a COOKIE ECHO with the peer's same tag

+      but a new tag of its own.  The cookie should be silently

+      discarded.  The endpoint SHOULD NOT change states and should leave

+      any timers running.

+

+   D) When both local and remote tags match the endpoint should always

+      enter the ESTABLISHED state, if it has not already done so. It

+      should stop any init or cookie timers that may be running and send

+      a COOKIE ACK.

+

+   Note: The "peer's Verification Tag" is the tag received in the

+   Initiate Tag field of the INIT or INIT ACK chunk.

+

+5.2.4.1 An Example of a Association Restart

+

+   In the following example, "A" initiates the association after a

+   restart has occurred.  Endpoint "Z" had no knowledge of the restart

+   until the exchange (i.e. Heartbeats had not yet detected the failure

+   of "A").  (assuming no bundling or fragmentation occurs):

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 64]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+Endpoint A                                          Endpoint Z

+<-------------- Association is established---------------------->

+Tag=Tag_A                                             Tag=Tag_Z

+<--------------------------------------------------------------->

+{A crashes and restarts}

+{app sets up a association with Z}

+(build TCB)

+INIT [I-Tag=Tag_A'

+      & other info]  --------\

+(Start T1-init timer)         \

+(Enter COOKIE-WAIT state)      \---> (find a existing TCB

+                                      compose temp TCB and Cookie_Z

+                                      with Tie-Tags to previous

+                                      association)

+                                /--- INIT ACK [Veri Tag=Tag_A',

+                               /               I-Tag=Tag_Z',

+(Cancel T1-init timer) <------/                Cookie_Z[TieTags=

+                                               Tag_A,Tag_Z

+                                                & other info]

+                                     (destroy temp TCB,leave original

+                                      in place)

+COOKIE ECHO [Veri=Tag_Z',

+             Cookie_Z

+             Tie=Tag_A,

+             Tag_Z]----------\

+(Start T1-init timer)         \

+(Enter COOKIE-ECHOED state)    \---> (Find existing association,

+                                      Tie-Tags match old tags,

+                                      Tags do not match i.e.

+                                      case X X M M above,

+                                      Announce Restart to ULP

+                                      and reset association).

+                               /---- COOKIE-ACK

+                              /

+(Cancel T1-init timer, <-----/

+ Enter ESTABLISHED state)

+{app sends 1st user data; strm 0}

+DATA [TSN=initial TSN_A

+     Strm=0,Seq=1 & user data]--\

+(Start T3-rtx timer)            \

+                                 \->

+                              /----- SACK [TSN Ack=init TSN_A,Block=0]

+(Cancel T3-rtx timer) <------/

+

+                  Figure 5: A Restart Example

+

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 65]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+5.2.5 Handle Duplicate COOKIE-ACK.

+

+   At any state other than COOKIE-ECHOED, an endpoint should silently

+   discard a received COOKIE ACK chunk.

+

+5.2.6 Handle Stale COOKIE Error

+

+   Receipt of an ERROR chunk with a "Stale Cookie" error cause indicates

+   one of a number of possible events:

+

+   A) That the association failed to completely setup before the State

+      Cookie issued by the sender was processed.

+

+   B) An old State Cookie was processed after setup completed.

+

+   C) An old State Cookie is received from someone that the receiver is

+      not interested in having an association with and the ABORT chunk

+      was lost.

+

+   When processing an ERROR chunk with a "Stale Cookie" error cause an

+   endpoint should first examine if an association is in the process of

+   being setup, i.e. the association is in the COOKIE-ECHOED state.  In

+   all cases if the association is not in the COOKIE-ECHOED state, the

+   ERROR chunk should be silently discarded.

+

+   If the association is in the COOKIE-ECHOED state, the endpoint may

+   elect one of the following three alternatives.

+

+   1) Send a new INIT chunk to the endpoint to generate a new State

+      Cookie and re-attempt the setup procedure.

+

+   2) Discard the TCB and report to the upper layer the inability to

+      setup the association.

+

+   3) Send a new INIT chunk to the endpoint, adding a Cookie

+      Preservative parameter requesting an extension to the lifetime of

+      the State Cookie.  When calculating the time extension, an

+      implementation SHOULD use the RTT information measured based on

+      the previous COOKIE ECHO / ERROR exchange, and should add no more

+      than 1 second beyond the measured RTT, due to long State Cookie

+      lifetimes making the endpoint more subject to a replay attack.

+

+

+

+

+

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 66]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+5.3 Other Initialization Issues

+

+5.3.1 Selection of Tag Value

+

+   Initiate Tag values should be selected from the range of 1 to 2**32 -

+   1.  It is very important that the Initiate Tag value be randomized to

+   help protect against "man in the middle" and "sequence number"

+   attacks.  The methods described in [RFC1750] can be used for the

+   Initiate Tag randomization.  Careful selection of Initiate Tags is

+   also necessary to prevent old duplicate packets from previous

+   associations being mistakenly processed as belonging to the current

+   association.

+

+   Moreover, the Verification Tag value used by either endpoint in a

+   given association MUST NOT change during the lifetime of an

+   association.  A new Verification Tag value MUST be used each time the

+   endpoint tears-down and then re-establishes an association to the

+   same peer.

+

+6. User Data Transfer

+

+   Data transmission MUST only happen in the ESTABLISHED, SHUTDOWN-

+   PENDING, and SHUTDOWN-RECEIVED states.  The only exception to this is

+   that DATA chunks are allowed to be bundled with an outbound COOKIE

+   ECHO chunk when in COOKIE-WAIT state.

+

+   DATA chunks MUST only be received according to the rules below in

+   ESTABLISHED, SHUTDOWN-PENDING, SHUTDOWN-SENT.  A DATA chunk received

+   in CLOSED is out of the blue and SHOULD be handled per 8.4.  A DATA

+   chunk received in any other state SHOULD be discarded.

+

+   A SACK MUST be processed in ESTABLISHED, SHUTDOWN-PENDING, and

+   SHUTDOWN-RECEIVED.  An incoming SACK MAY be processed in COOKIE-

+   ECHOED.  A SACK in the CLOSED state is out of the blue and SHOULD be

+   processed according to the rules in 8.4.  A SACK chunk received in

+   any other state SHOULD be discarded.

+

+

+   A SCTP receiver MUST be able to receive a minimum of 1500 bytes in

+   one SCTP packet.  This means that a SCTP endpoint MUST NOT indicate

+   less than 1500 bytes in its Initial a_rwnd sent in the INIT or INIT

+   ACK.

+

+   For transmission efficiency, SCTP defines mechanisms for bundling of

+   small user messages and fragmentation of large user messages.  The

+   following diagram depicts the flow of user messages through SCTP.

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 67]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   In this section the term "data sender" refers to the endpoint that

+   transmits a DATA chunk and the term "data receiver" refers to the

+   endpoint that receives a DATA chunk.  A data receiver will transmit

+   SACK chunks.

+

+                 +--------------------------+

+                 |      User Messages       |

+                 +--------------------------+

+       SCTP user        ^  |

+      ==================|==|=======================================

+                        |  v (1)

+             +------------------+    +--------------------+

+             | SCTP DATA Chunks |    |SCTP Control Chunks |

+             +------------------+    +--------------------+

+                        ^  |             ^  |

+                        |  v (2)         |  v (2)

+                     +--------------------------+

+                     |      SCTP packets        |

+                     +--------------------------+

+       SCTP                      ^  |

+      ===========================|==|===========================

+                                 |  v

+             Connectionless Packet Transfer Service (e.g., IP)

+

+   Notes:

+

+      1) When converting user messages into DATA chunks, an endpoint

+         will fragment user messages larger than the current association

+         path MTU into multiple DATA chunks.  The data receiver will

+         normally reassemble the fragmented message from DATA chunks

+         before delivery to the user (see Section 6.9 for details).

+

+      2) Multiple DATA and control chunks may be bundled by the sender

+         into a single SCTP packet for transmission, as long as the

+         final size of the packet does not exceed the current path MTU.

+         The receiver will unbundle the packet back into the original

+         chunks.  Control chunks MUST come before DATA chunks in the

+         packet.

+

+                Figure 6: Illustration of User Data Transfer

+

+   The fragmentation and bundling mechanisms, as detailed in Sections

+   6.9 and 6.10, are OPTIONAL to implement by the data sender, but they

+   MUST be implemented by the data receiver, i.e., an endpoint MUST

+   properly receive and process bundled or fragmented data.

+

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 68]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+6.1  Transmission of DATA Chunks

+

+   This document is specified as if there is a single retransmission

+   timer per destination transport address, but implementations MAY have

+   a retransmission timer for each DATA chunk.

+

+   The following general rules MUST be applied by the data sender for

+   transmission and/or retransmission of outbound DATA chunks:

+

+   A) At any given time, the data sender MUST NOT transmit new data to

+      any destination transport address if its peer's rwnd indicates

+      that the peer has no buffer space (i.e. rwnd is 0, see Section

+      6.2.1).  However, regardless of the value of rwnd (including if it

+      is 0), the data sender can always have one DATA chunk in flight to

+      the receiver if allowed by cwnd (see rule B below).  This rule

+      allows the sender to probe for a change in rwnd that the sender

+      missed due to the SACK having been lost in transit from the data

+      receiver to the data sender.

+

+   B) At any given time, the sender MUST NOT transmit new data to a

+      given transport address if it has cwnd or more bytes of data

+      outstanding to that transport address.

+

+   C) When the time comes for the sender to transmit, before sending new

+      DATA chunks, the sender MUST first transmit any outstanding DATA

+      chunks which are marked for retransmission (limited by the current

+      cwnd).

+

+   D) Then, the sender can send out as many new DATA chunks as Rule A

+      and Rule B above allow.

+

+   Multiple DATA chunks committed for transmission MAY be bundled in a

+   single packet.  Furthermore, DATA chunks being retransmitted MAY be

+   bundled with new DATA chunks, as long as the resulting packet size

+   does not exceed the path MTU.  A ULP may request that no bundling is

+   performed but this should only turn off any delays that a SCTP

+   implementation may be using to increase bundling efficiency.  It does

+   not in itself stop all bundling from occurring (i.e. in case of

+   congestion or retransmission).

+

+   Before an endpoint transmits a DATA chunk, if any received DATA

+   chunks have not been acknowledged (e.g., due to delayed ack), the

+   sender should create a SACK and bundle it with the outbound DATA

+   chunk, as long as the size of the final SCTP packet does not exceed

+   the current MTU.  See Section 6.2.

+

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 69]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   IMPLEMENTATION NOTE: When the window is full (i.e., transmission is

+   disallowed by Rule A and/or Rule B), the sender MAY still accept send

+   requests from its upper layer, but MUST transmit no more DATA chunks

+   until some or all of the outstanding DATA chunks are acknowledged and

+   transmission is allowed by Rule A and Rule B again.

+

+   Whenever a transmission or retransmission is made to any address, if

+   the T3-rtx timer of that address is not currently running, the sender

+   MUST start that timer.  If the timer for that address is already

+   running, the sender MUST restart the timer if the earliest (i.e.,

+   lowest TSN) outstanding DATA chunk sent to that address is being

+   retransmitted.  Otherwise, the data sender MUST NOT restart the

+   timer.

+

+   When starting or restarting the T3-rtx timer, the timer value must be

+   adjusted according to the timer rules defined in Sections 6.3.2, and

+   6.3.3.

+

+   Note: The data sender SHOULD NOT use a TSN that is more than 2**31 -

+   1 above the beginning TSN of the current send window.

+

+6.2  Acknowledgement on Reception of DATA Chunks

+

+   The SCTP endpoint MUST always acknowledge the reception of each valid

+   DATA chunk.

+

+   The guidelines on delayed acknowledgement algorithm specified in

+   Section 4.2 of [RFC2581] SHOULD be followed.  Specifically, an

+   acknowledgement SHOULD be generated for at least every second packet

+   (not every second DATA chunk) received, and SHOULD be generated

+   within 200 ms of the arrival of any unacknowledged DATA chunk.  In

+   some situations it may be beneficial for an SCTP transmitter to be

+   more conservative than the algorithms detailed in this document

+   allow. However, an SCTP transmitter MUST NOT be more aggressive than

+   the following algorithms allow.

+

+   A SCTP receiver MUST NOT generate more than one SACK for every

+   incoming packet, other than to update the offered window as the

+   receiving application consumes new data.

+

+   IMPLEMENTATION NOTE: The maximum delay for generating an

+   acknowledgement may be configured by the SCTP administrator, either

+   statically or dynamically, in order to meet the specific timing

+   requirement of the protocol being carried.

+

+   An implementation MUST NOT allow the maximum delay to be configured

+   to be more than 500 ms.  In other words an implementation MAY lower

+   this value below 500ms but MUST NOT raise it above 500ms.

+

+

+

+Stewart, et al.             Standards Track                    [Page 70]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   Acknowledgements MUST be sent in SACK chunks unless shutdown was

+   requested by the ULP in which case an endpoint MAY send an

+   acknowledgement in the SHUTDOWN chunk.  A SACK chunk can acknowledge

+   the reception of multiple DATA chunks.  See Section 3.3.4 for SACK

+   chunk format.  In particular, the SCTP endpoint MUST fill in the

+   Cumulative TSN Ack field to indicate the latest sequential TSN (of a

+   valid DATA chunk) it has received.  Any received DATA chunks with TSN

+   greater than the value in the Cumulative TSN Ack field SHOULD also be

+   reported in the Gap Ack Block fields.

+

+   Note:  The SHUTDOWN chunk does not contain Gap Ack Block fields.

+   Therefore, the endpoint should use a SACK instead of the SHUTDOWN

+   chunk to acknowledge DATA chunks received out of order .

+

+   When a packet arrives with duplicate DATA chunk(s) and with no new

+   DATA chunk(s), the endpoint MUST immediately send a SACK with no

+   delay.  If a packet arrives with duplicate DATA chunk(s) bundled with

+   new DATA chunks, the endpoint MAY immediately send a SACK.  Normally

+   receipt of duplicate DATA chunks will occur when the original SACK

+   chunk was lost and the peer's RTO has expired.  The duplicate TSN

+   number(s) SHOULD be reported in the SACK as duplicate.

+

+   When an endpoint receives a SACK, it MAY use the Duplicate TSN

+   information to determine if SACK loss is occurring.  Further use of

+   this data is for future study.

+

+   The data receiver is responsible for maintaining its receive buffers.

+   The data receiver SHOULD notify the data sender in a timely manner of

+   changes in its ability to receive data.  How an implementation

+   manages its receive buffers is dependent on many factors (e.g.,

+   Operating System, memory management system, amount of memory, etc.).

+   However, the data sender strategy defined in Section 6.2.1 is based

+   on the assumption of receiver operation similar to the following:

+

+      A) At initialization of the association, the endpoint tells the

+         peer how much receive buffer space it has allocated to the

+         association in the INIT or INIT ACK.  The endpoint sets a_rwnd

+         to this value.

+

+      B) As DATA chunks are received and buffered, decrement a_rwnd by

+         the number of bytes received and buffered.  This is, in effect,

+         closing rwnd at the data sender and restricting the amount of

+         data it can transmit.

+

+      C) As DATA chunks are delivered to the ULP and released from the

+         receive buffers, increment a_rwnd by the number of bytes

+         delivered to the upper layer.  This is, in effect, opening up

+         rwnd on the data sender and allowing it to send more data.  The

+

+

+

+Stewart, et al.             Standards Track                    [Page 71]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+         data receiver SHOULD NOT increment a_rwnd unless it has

+         released bytes from its receive buffer.  For example, if the

+         receiver is holding fragmented DATA chunks in a reassembly

+         queue, it should not increment a_rwnd.

+

+      D) When sending a SACK, the data receiver SHOULD place the current

+         value of a_rwnd into the a_rwnd field.  The data receiver

+         SHOULD take into account that the data sender will not

+         retransmit DATA chunks that are acked via the Cumulative TSN

+         Ack (i.e., will drop from its retransmit queue).

+

+   Under certain circumstances, the data receiver may need to drop DATA

+   chunks that it has received but hasn't released from its receive

+   buffers (i.e., delivered to the ULP).  These DATA chunks may have

+   been acked in Gap Ack Blocks.  For example, the data receiver may be

+   holding data in its receive buffers while reassembling a fragmented

+   user message from its peer when it runs out of receive buffer space.

+   It may drop these DATA chunks even though it has acknowledged them in

+   Gap Ack Blocks.  If a data receiver drops DATA chunks, it MUST NOT

+   include them in Gap Ack Blocks in subsequent SACKs until they are

+   received again via retransmission.  In addition, the endpoint should

+   take into account the dropped data when calculating its a_rwnd.

+

+   An endpoint SHOULD NOT revoke a SACK and discard data. Only in

+   extreme circumstance should an endpoint use this procedure (such as

+   out of buffer space).  The data receiver should take into account

+   that dropping data that has been acked in Gap Ack Blocks can result

+   in suboptimal retransmission strategies in the data sender and thus

+   in suboptimal performance.

+

+   The following example illustrates the use of delayed

+   acknowledgements:

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 72]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   Endpoint A                                      Endpoint Z

+

+   {App sends 3 messages; strm 0}

+   DATA [TSN=7,Strm=0,Seq=3] ------------> (ack delayed)

+   (Start T3-rtx timer)

+

+   DATA [TSN=8,Strm=0,Seq=4] ------------> (send ack)

+                                 /------- SACK [TSN Ack=8,block=0]

+   (cancel T3-rtx timer)  <-----/

+

+   DATA [TSN=9,Strm=0,Seq=5] ------------> (ack delayed)

+   (Start T3-rtx timer)

+                                          ...

+                                          {App sends 1 message; strm 1}

+                                          (bundle SACK with DATA)

+                                   /----- SACK [TSN Ack=9,block=0] \

+                                  /         DATA [TSN=6,Strm=1,Seq=2]

+   (cancel T3-rtx timer)  <------/        (Start T3-rtx timer)

+

+   (ack delayed)

+   (send ack)

+   SACK [TSN Ack=6,block=0] -------------> (cancel T3-rtx timer)

+

+          Figure 7:  Delayed Acknowledgment Example

+

+   If an endpoint receives a DATA chunk with no user data (i.e., the

+   Length field is set to 16) it MUST send an ABORT with error cause set

+   to "No User Data".

+

+   An endpoint SHOULD NOT send a DATA chunk with no user data part.

+

+6.2.1  Processing a Received SACK

+

+   Each SACK an endpoint receives contains an a_rwnd value.  This value

+   represents the amount of buffer space the data receiver, at the time

+   of transmitting the SACK, has left of its total receive buffer space

+   (as specified in the INIT/INIT ACK).  Using a_rwnd, Cumulative TSN

+   Ack and Gap Ack Blocks, the data sender can develop a representation

+   of the peer's receive buffer space.

+

+   One of the problems the data sender must take into account when

+   processing a SACK is that a SACK can be received out of order.  That

+   is, a SACK sent by the data receiver can pass an earlier SACK and be

+   received first by the data sender.  If a SACK is received out of

+   order, the data sender can develop an incorrect view of the peer's

+   receive buffer space.

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 73]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   Since there is no explicit identifier that can be used to detect

+   out-of-order SACKs, the data sender must use heuristics to determine

+   if a SACK is new.

+

+   An endpoint SHOULD use the following rules to calculate the rwnd,

+   using the a_rwnd value, the Cumulative TSN Ack and Gap Ack Blocks in

+   a received SACK.

+

+   A) At the establishment of the association, the endpoint initializes

+      the rwnd to the Advertised Receiver Window Credit (a_rwnd) the

+      peer specified in the INIT or INIT ACK.

+

+   B) Any time a DATA chunk is transmitted (or retransmitted) to a peer,

+      the endpoint subtracts the data size of the chunk from the rwnd of

+      that peer.

+

+   C) Any time a DATA chunk is marked for retransmission (via either

+      T3-rtx timer expiration (Section 6.3.3)or via fast retransmit

+      (Section 7.2.4)), add the data size of those chunks to the rwnd.

+

+      Note: If the implementation is maintaining a timer on each DATA

+      chunk then only DATA chunks whose timer expired would be marked

+      for retransmission.

+

+   D) Any time a SACK arrives, the endpoint performs the following:

+

+         i) If Cumulative TSN Ack is less than the Cumulative TSN Ack

+         Point, then drop the SACK.   Since Cumulative TSN Ack is

+         monotonically increasing, a SACK whose Cumulative TSN Ack is

+         less than the Cumulative TSN Ack Point indicates an out-of-

+         order SACK.

+

+         ii) Set rwnd equal to the newly received a_rwnd minus the

+         number of bytes still outstanding after processing the

+         Cumulative TSN Ack and the Gap Ack Blocks.

+

+         iii) If the SACK is missing a TSN that was previously

+         acknowledged via a Gap Ack Block (e.g., the data receiver

+         reneged on the data), then mark the corresponding DATA chunk as

+         available for retransmit:  Mark it as missing for fast

+         retransmit as described in Section 7.2.4 and if no retransmit

+         timer is running for the destination address to which the DATA

+         chunk was originally transmitted, then T3-rtx is started for

+         that destination address.

+

+

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 74]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+6.3 Management of Retransmission Timer

+

+   An SCTP endpoint uses a retransmission timer T3-rtx to ensure data

+   delivery in the absence of any feedback from its peer.  The duration

+   of this timer is referred to as RTO (retransmission timeout).

+

+   When an endpoint's peer is multi-homed, the endpoint will calculate a

+   separate RTO for each different destination transport address of its

+   peer endpoint.

+

+   The computation and management of RTO in SCTP follows closely how TCP

+   manages its retransmission timer.  To compute the current RTO, an

+   endpoint maintains two state variables per destination transport

+   address: SRTT (smoothed round-trip time) and RTTVAR (round-trip time

+   variation).

+

+6.3.1 RTO Calculation

+

+   The rules governing the computation of SRTT, RTTVAR, and RTO are as

+   follows:

+

+   C1) Until an RTT measurement has been made for a packet sent to the

+       given destination transport address, set RTO to the protocol

+       parameter 'RTO.Initial'.

+

+   C2) When the first RTT measurement R is made, set SRTT <- R, RTTVAR

+       <- R/2, and RTO <- SRTT + 4 * RTTVAR.

+

+   C3) When a new RTT measurement R' is made, set

+

+       RTTVAR <- (1 - RTO.Beta) * RTTVAR + RTO.Beta * |SRTT - R'| SRTT

+       <- (1 - RTO.Alpha) * SRTT + RTO.Alpha * R'

+

+       Note: The value of SRTT used in the update to RTTVAR is its value

+       before updating SRTT itself using the second assignment.

+

+       After the computation, update RTO <- SRTT + 4 * RTTVAR.

+

+   C4) When data is in flight and when allowed by rule C5 below, a new

+       RTT measurement MUST be made each round trip.  Furthermore, new

+       RTT measurements SHOULD be made no more than once per round-trip

+       for a given destination transport address.  There are two reasons

+       for this recommendation:  First, it appears that measuring more

+       frequently often does not in practice yield any significant

+       benefit [ALLMAN99]; second, if measurements are made more often,

+       then the values of RTO.Alpha and RTO.Beta in rule C3 above should

+       be adjusted so that SRTT and RTTVAR still adjust to changes at

+       roughly the same rate (in terms of how many round trips it takes

+

+

+

+Stewart, et al.             Standards Track                    [Page 75]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+       them to reflect new values) as they would if making only one

+       measurement per round-trip and using RTO.Alpha and RTO.Beta as

+       given in rule C3.  However, the exact nature of these adjustments

+       remains a research issue.

+

+   C5) Karn's algorithm: RTT measurements MUST NOT be made using packets

+       that were retransmitted (and thus for which it is ambiguous

+       whether the reply was for the first instance of the packet or a

+       later instance).

+

+   C6) Whenever RTO is computed, if it is less than RTO.Min seconds then

+       it is rounded up to RTO.Min seconds.  The reason for this rule is

+       that RTOs that do not have a high minimum value are susceptible

+       to unnecessary timeouts [ALLMAN99].

+

+   C7) A maximum value may be placed on RTO provided it is at least

+       RTO.max seconds.

+

+   There is no requirement for the clock granularity G used for

+   computing RTT measurements and the different state variables, other

+   than:

+

+   G1) Whenever RTTVAR is computed, if RTTVAR = 0, then adjust RTTVAR <-

+       G.

+

+   Experience [ALLMAN99] has shown that finer clock granularities (<=

+   100 msec) perform somewhat better than more coarse granularities.

+

+6.3.2 Retransmission Timer Rules

+

+   The rules for managing the retransmission timer are as follows:

+

+   R1) Every time a DATA chunk is sent to any address (including a

+       retransmission), if the T3-rtx timer of that address is not

+       running, start it running so that it will expire after the RTO of

+       that address.  The RTO used here is that obtained after any

+       doubling due to previous T3-rtx timer expirations on the

+       corresponding destination address as discussed in rule E2 below.

+

+   R2) Whenever all outstanding data sent to an address have been

+       acknowledged, turn off the T3-rtx timer of that address.

+

+   R3) Whenever a SACK is received that acknowledges the DATA chunk with

+       the earliest outstanding TSN for that address, restart T3-rtx

+       timer for that address with its current RTO (if there is still

+       outstanding data on that address).

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 76]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   R4) Whenever a SACK is received missing a TSN that was previously

+       acknowledged via a Gap Ack Block, start T3-rtx for the

+       destination address to which the DATA chunk was originally

+       transmitted if it is not already running.

+

+   The following example shows the use of various timer rules (assuming

+   the receiver uses delayed acks).

+

+   Endpoint A                                         Endpoint Z

+   {App begins to send}

+   Data [TSN=7,Strm=0,Seq=3] ------------> (ack delayed)

+   (Start T3-rtx timer)

+                                           {App sends 1 message; strm 1}

+                                           (bundle ack with data)

+   DATA [TSN=8,Strm=0,Seq=4] ----\     /-- SACK [TSN Ack=7,Block=0]

+                                  \   /      DATA [TSN=6,Strm=1,Seq=2]

+                                   \ /     (Start T3-rtx timer)

+                                    \

+                                   / \

+   (Re-start T3-rtx timer) <------/   \--> (ack delayed)

+   (ack delayed)

+   {send ack}

+   SACK [TSN Ack=6,Block=0] --------------> (Cancel T3-rtx timer)

+                                           ..

+                                           (send ack)

+   (Cancel T3-rtx timer)  <-------------- SACK [TSN Ack=8,Block=0]

+

+                 Figure 8 - Timer Rule Examples

+

+6.3.3 Handle T3-rtx Expiration

+

+   Whenever the retransmission timer T3-rtx expires for a destination

+   address, do the following:

+

+   E1) For the destination address for which the timer expires, adjust

+       its ssthresh with rules defined in Section 7.2.3 and set the cwnd

+       <- MTU.

+

+   E2) For the destination address for which the timer expires, set RTO

+       <- RTO * 2 ("back off the timer").  The maximum value discussed

+       in rule C7 above (RTO.max) may be used to provide an upper bound

+       to this doubling operation.

+

+   E3) Determine how many of the earliest (i.e., lowest TSN) outstanding

+       DATA chunks for the address for which the T3-rtx has expired will

+       fit into a single packet, subject to the MTU constraint for the

+       path corresponding to the destination transport address to which

+       the retransmission is being sent (this may be different from the

+

+

+

+Stewart, et al.             Standards Track                    [Page 77]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+       address for which the timer expires [see Section 6.4]).  Call

+       this value K.  Bundle and retransmit those K DATA chunks in a

+       single packet to the destination endpoint.

+

+   E4) Start the retransmission timer T3-rtx on the destination address

+       to which the retransmission is sent, if rule R1 above indicates

+       to do so.  The RTO to be used for starting T3-rtx should be the

+       one for the destination address to which the retransmission is

+       sent, which, when the receiver is multi-homed, may be different

+       from the destination address for which the timer expired (see

+       Section 6.4 below).

+

+   After retransmitting, once a new RTT measurement is obtained (which

+   can happen only when new data has been sent and acknowledged, per

+   rule C5, or for a measurement made from a HEARTBEAT [see Section

+   8.3]), the computation in rule C3 is performed, including the

+   computation of RTO, which may result in "collapsing" RTO back down

+   after it has been subject to doubling (rule E2).

+

+   Note: Any DATA chunks that were sent to the address for which the

+   T3-rtx timer expired but did not fit in one MTU (rule E3 above),

+   should be marked for retransmission and sent as soon as cwnd allows

+   (normally when a SACK arrives).

+

+   The final rule for managing the retransmission timer concerns

+   failover (see Section 6.4.1):

+

+   F1) Whenever an endpoint switches from the current destination

+       transport address to a different one, the current retransmission

+       timers are left running.  As soon as the endpoint transmits a

+       packet containing DATA chunk(s) to the new transport address,

+       start the timer on that transport address, using the RTO value of

+       the destination address to which the data is being sent, if rule

+       R1 indicates to do so.

+

+6.4 Multi-homed SCTP Endpoints

+

+   An SCTP endpoint is considered multi-homed if there are more than one

+   transport address that can be used as a destination address to reach

+   that endpoint.

+

+   Moreover, the ULP of an endpoint shall select one of the multiple

+   destination addresses of a multi-homed peer endpoint as the primary

+   path (see Sections 5.1.2 and 10.1 for details).

+

+   By default, an endpoint SHOULD always transmit to the primary path,

+   unless the SCTP user explicitly specifies the destination transport

+   address (and possibly source transport address) to use.

+

+

+

+Stewart, et al.             Standards Track                    [Page 78]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   An endpoint SHOULD transmit reply chunks (e.g., SACK, HEARTBEAT ACK,

+   etc.) to the same destination transport address from which it

+   received the DATA or control chunk to which it is replying.  This

+   rule should also be followed if the endpoint is bundling DATA chunks

+   together with the reply chunk.

+

+   However, when acknowledging multiple DATA chunks received in packets

+   from different source addresses in a single SACK, the SACK chunk may

+   be transmitted to one of the destination transport addresses from

+   which the DATA or control chunks being acknowledged were received.

+

+   When a receiver of a duplicate DATA chunk sends a SACK to a multi-

+   homed endpoint it MAY be beneficial to vary the destination address

+   and not use the source address of the DATA chunk.  The reason being

+   that receiving a duplicate from a multi-homed endpoint might indicate

+   that the return path (as specified in the source address of the DATA

+   chunk) for the SACK is broken.

+

+   Furthermore, when its peer is multi-homed, an endpoint SHOULD try to

+   retransmit a chunk to an active destination transport address that is

+   different from the last destination address to which the DATA chunk

+   was sent.

+

+   Retransmissions do not affect the total outstanding data count.

+   However, if the DATA chunk is retransmitted onto a different

+   destination address, both the outstanding data counts on the new

+   destination address and the old destination address to which the data

+   chunk was last sent shall be adjusted accordingly.

+

+6.4.1 Failover from Inactive Destination Address

+

+   Some of the transport addresses of a multi-homed SCTP endpoint may

+   become inactive due to either the occurrence of certain error

+   conditions (see Section 8.2) or adjustments from SCTP user.

+

+   When there is outbound data to send and the primary path becomes

+   inactive (e.g., due to failures), or where the SCTP user explicitly

+   requests to send data to an inactive destination transport address,

+   before reporting an error to its ULP, the SCTP endpoint should try to

+   send the data to an alternate active destination transport address if

+   one exists.

+

+   When retransmitting data, if the endpoint is multi-homed, it should

+   consider each source-destination address pair in its retransmission

+   selection policy.  When retransmitting the endpoint should attempt to

+   pick the most divergent source-destination pair from the original

+   source-destination pair to which the packet was transmitted.

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 79]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   Note: Rules for picking the most divergent source-destination pair

+   are an implementation decision and is not specified within this

+   document.

+

+6.5 Stream Identifier and Stream Sequence Number

+

+   Every DATA chunk MUST carry a valid stream identifier.  If an

+   endpoint receives a DATA chunk with an invalid stream identifier, it

+   shall acknowledge the reception of the DATA chunk following the

+   normal procedure, immediately send an ERROR chunk with cause set to

+   "Invalid Stream Identifier" (see Section 3.3.10) and discard the DATA

+   chunk. The endpoint may bundle the ERROR chunk in the same packet as

+   the SACK as long as the ERROR follows the SACK.

+

+   The stream sequence number in all the streams shall start from 0 when

+   the association is established.  Also, when the stream sequence

+   number reaches the value 65535 the next stream sequence number shall

+   be set to 0.

+

+6.6 Ordered and Unordered Delivery

+

+   Within a stream, an endpoint MUST deliver DATA chunks received with

+   the U flag set to 0 to the upper layer according to the order of

+   their stream sequence number.  If DATA chunks arrive out of order of

+   their stream sequence number, the endpoint MUST hold the received

+   DATA chunks from delivery to the ULP until they are re-ordered.

+

+   However, an SCTP endpoint can indicate that no ordered delivery is

+   required for a particular DATA chunk transmitted within the stream by

+   setting the U flag of the DATA chunk to 1.

+

+   When an endpoint receives a DATA chunk with the U flag set to 1, it

+   must bypass the ordering mechanism and immediately deliver the data

+   to the upper layer (after re-assembly if the user data is fragmented

+   by the data sender).

+

+   This provides an effective way of transmitting "out-of-band" data in

+   a given stream.  Also, a stream can be used as an "unordered" stream

+   by simply setting the U flag to 1 in all DATA chunks sent through

+   that stream.

+

+   IMPLEMENTATION NOTE: When sending an unordered DATA chunk, an

+   implementation may choose to place the DATA chunk in an outbound

+   packet that is at the head of the outbound transmission queue if

+   possible.

+

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 80]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   The 'Stream Sequence Number' field in a DATA chunk with U flag set to

+   1 has no significance.  The sender can fill it with arbitrary value,

+   but the receiver MUST ignore the field.

+

+   Note:  When transmitting ordered and unordered data, an endpoint does

+   not increment its Stream Sequence Number when transmitting a DATA

+   chunk with U flag set to 1.

+

+6.7 Report Gaps in Received DATA TSNs

+

+   Upon the reception of a new DATA chunk, an endpoint shall examine the

+   continuity of the TSNs received.  If the endpoint detects a gap in

+   the received DATA chunk sequence, it SHOULD send a SACK with Gap Ack

+   Blocks immediately.  The data receiver continues sending a SACK after

+   receipt of each SCTP packet that doesn't fill the gap.

+

+   Based on the Gap Ack Block from the received SACK, the endpoint can

+   calculate the missing DATA chunks and make decisions on whether to

+   retransmit them (see Section 6.2.1 for details).

+

+   Multiple gaps can be reported in one single SACK (see Section 3.3.4).

+

+   When its peer is multi-homed, the SCTP endpoint SHOULD always try to

+   send the SACK to the same destination address from which the last

+   DATA chunk was received.

+

+   Upon the reception of a SACK, the endpoint MUST remove all DATA

+   chunks which have been acknowledged by the SACK's Cumulative TSN Ack

+   from its transmit queue.  The endpoint MUST also treat all the DATA

+   chunks with TSNs not included in the Gap Ack Blocks reported by the

+   SACK as "missing".  The number of "missing" reports for each

+   outstanding DATA chunk MUST be recorded by the data sender in order

+   to make retransmission decisions.  See Section 7.2.4 for details.

+

+   The following example shows the use of SACK to report a gap.

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 81]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+      Endpoint A                                    Endpoint Z

+      {App sends 3 messages; strm 0}

+      DATA [TSN=6,Strm=0,Seq=2] ---------------> (ack delayed)

+      (Start T3-rtx timer)

+

+      DATA [TSN=7,Strm=0,Seq=3] --------> X (lost)

+

+      DATA [TSN=8,Strm=0,Seq=4] ---------------> (gap detected,

+                                                  immediately send ack)

+                                      /----- SACK [TSN Ack=6,Block=1,

+                                     /             Strt=2,End=2]

+                              <-----/

+      (remove 6 from out-queue,

+       and mark 7 as "1" missing report)

+

+                 Figure 9 - Reporting a Gap using SACK

+

+   The maximum number of Gap Ack Blocks that can be reported within a

+   single SACK chunk is limited by the current path MTU.  When a single

+   SACK can not cover all the Gap Ack Blocks needed to be reported due

+   to the MTU limitation, the endpoint MUST send only one SACK,

+   reporting the Gap Ack Blocks from the lowest to highest TSNs, within

+   the size limit set by the MTU, and leave the remaining highest TSN

+   numbers unacknowledged.

+

+6.8 Adler-32 Checksum Calculation

+

+   When sending an SCTP packet, the endpoint MUST strengthen the data

+   integrity of the transmission by including the Adler-32 checksum

+   value calculated on the packet, as described below.

+

+   After the packet is constructed (containing the SCTP common header

+   and one or more control or DATA chunks), the transmitter shall:

+

+   1) Fill in the proper Verification Tag in the SCTP common header and

+      initialize the checksum field to 0's.

+

+   2) Calculate the Adler-32 checksum of the whole packet, including the

+      SCTP common header and all the chunks.  Refer to appendix B for

+      details of the Adler-32 algorithm.  And,

+

+   3) Put the resultant value into the checksum field in the common

+      header, and leave the rest of the bits unchanged.

+

+   When an SCTP packet is received, the receiver MUST first check the

+   Adler-32 checksum:

+

+   1) Store the received Adler-32 checksum value aside,

+

+

+

+Stewart, et al.             Standards Track                    [Page 82]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   2) Replace the 32 bits of the checksum field in the received SCTP

+      packet with all '0's and calculate an Adler-32 checksum value of

+      the whole received packet.  And,

+

+   3) Verify that the calculated Adler-32 checksum is the same as the

+      received Adler-32 checksum.  If not, the receiver MUST treat the

+      packet as an invalid SCTP packet.

+

+   The default procedure for handling invalid SCTP packets is to

+   silently discard them.

+

+6.9 Fragmentation and Reassembly

+

+   An endpoint MAY support fragmentation when sending DATA chunks, but

+   MUST support reassembly when receiving DATA chunks.  If an endpoint

+   supports fragmentation, it MUST fragment a user message if the size

+   of the user message to be sent causes the outbound SCTP packet size

+   to exceed the current MTU.  If an implementation does not support

+   fragmentation of outbound user messages, the endpoint must return an

+   error to its upper layer and not attempt to send the user message.

+

+   IMPLEMENTATION NOTE:  In this error case, the Send primitive

+   discussed in Section 10.1 would need to return an error to the upper

+   layer.

+

+   If its peer is multi-homed, the endpoint shall choose a size no

+   larger than the association Path MTU.  The association Path MTU is

+   the smallest Path MTU of all destination addresses.

+

+   Note: Once a message is fragmented it cannot be re-fragmented.

+   Instead if the PMTU has been reduced, then IP fragmentation must be

+   used.  Please see Section 7.3 for details of PMTU discovery.

+

+   When determining when to fragment, the SCTP implementation MUST take

+   into account the SCTP packet header as well as the DATA chunk

+   header(s).  The implementation MUST also take into account the space

+   required for a SACK chunk if bundling a SACK chunk with the DATA

+   chunk.

+

+   Fragmentation takes the following steps:

+

+   1) The data sender MUST break the user message into a series of DATA

+      chunks such that each chunk plus SCTP overhead fits into an IP

+      datagram smaller than or equal to the association Path MTU.

+

+   2) The transmitter MUST then assign, in sequence, a separate TSN to

+      each of the DATA chunks in the series.  The transmitter assigns

+      the same SSN to each of the DATA chunks.  If the user indicates

+

+

+

+Stewart, et al.             Standards Track                    [Page 83]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+      that the user message is to be delivered using unordered delivery,

+      then the U flag of each DATA chunk of the user message MUST be set

+      to 1.

+

+   3) The transmitter MUST also set the B/E bits of the first DATA chunk

+      in the series to '10', the B/E bits of the last DATA chunk in the

+      series to '01', and the B/E bits of all other DATA chunks in the

+      series to '00'.

+

+   An endpoint MUST recognize fragmented DATA chunks by examining the

+   B/E bits in each of the received DATA chunks, and queue the

+   fragmented DATA chunks for re-assembly.  Once the user message is

+   reassembled, SCTP shall pass the re-assembled user message to the

+   specific stream for possible re-ordering and final dispatching.

+

+   Note: If the data receiver runs out of buffer space while still

+   waiting for more fragments to complete the re-assembly of the

+   message, it should dispatch part of its inbound message through a

+   partial delivery API (see Section 10), freeing some of its receive

+   buffer space so that the rest of the message may be received.

+

+6.10 Bundling

+

+   An endpoint bundles chunks by simply including multiple chunks in one

+   outbound SCTP packet.  The total size of the resultant IP datagram,

+   including the SCTP packet and IP headers, MUST be less or equal to

+   the current Path MTU.

+

+   If its peer endpoint is multi-homed, the sending endpoint shall

+   choose a size no larger than the latest MTU of the current primary

+   path.

+

+   When bundling control chunks with DATA chunks, an endpoint MUST place

+   control chunks first in the outbound SCTP packet.  The transmitter

+   MUST transmit DATA chunks within a SCTP packet in increasing order of

+   TSN.

+

+   Note:  Since control chunks must be placed first in a packet and

+   since DATA chunks must be transmitted before SHUTDOWN or SHUTDOWN ACK

+   chunks, DATA chunks cannot be bundled with SHUTDOWN or SHUTDOWN ACK

+   chunks.

+

+   Partial chunks MUST NOT be placed in an SCTP packet.

+

+

+

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 84]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   An endpoint MUST process received chunks in their order in the

+   packet. The receiver uses the chunk length field to determine the end

+   of a chunk and beginning of the next chunk taking account of the fact

+   that all chunks end on a 4 byte boundary.  If the receiver detects a

+   partial chunk, it MUST drop the chunk.

+

+   An endpoint MUST NOT bundle INIT, INIT ACK or SHUTDOWN COMPLETE with

+   any other chunks.

+

+7. Congestion control

+

+   Congestion control is one of the basic functions in SCTP.  For some

+   applications, it may be likely that adequate resources will be

+   allocated to SCTP traffic to assure prompt delivery of time-critical

+   data - thus it would appear to be unlikely, during normal operations,

+   that transmissions encounter severe congestion conditions.  However

+   SCTP must operate under adverse operational conditions, which can

+   develop upon partial network failures or unexpected traffic surges.

+   In such situations SCTP must follow correct congestion control steps

+   to recover from congestion quickly in order to get data delivered as

+   soon as possible.  In the absence of network congestion, these

+   preventive congestion control algorithms should show no impact on the

+   protocol performance.

+

+   IMPLEMENTATION NOTE: As far as its specific performance requirements

+   are met, an implementation is always allowed to adopt a more

+   conservative congestion control algorithm than the one defined below.

+

+   The congestion control algorithms used by SCTP are based on

+   [RFC2581].  This section describes how the algorithms defined in

+   RFC2581 are adapted for use in SCTP.  We first list differences in

+   protocol designs between TCP and SCTP, and then describe SCTP's

+   congestion control scheme.  The description will use the same

+   terminology as in TCP congestion control whenever appropriate.

+

+   SCTP congestion control is always applied to the entire association,

+   and not to individual streams.

+

+7.1 SCTP Differences from TCP Congestion control

+

+   Gap Ack Blocks in the SCTP SACK carry the same semantic meaning as

+   the TCP SACK.  TCP considers the information carried in the SACK as

+   advisory information only.  SCTP considers the information carried in

+   the Gap Ack Blocks in the SACK chunk as advisory.  In SCTP, any DATA

+   chunk that has been acknowledged by SACK, including DATA that arrived

+   at the receiving end out of order, are not considered fully delivered

+   until the Cumulative TSN Ack Point passes the TSN of the DATA chunk

+   (i.e., the DATA chunk has been acknowledged by the Cumulative TSN Ack

+

+

+

+Stewart, et al.             Standards Track                    [Page 85]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   field in the SACK).  Consequently, the value of cwnd controls the

+   amount of outstanding data, rather than (as in the case of non-SACK

+   TCP) the upper bound between the highest acknowledged sequence number

+   and the latest DATA chunk that can be sent within the congestion

+   window.  SCTP SACK leads to different implementations of fast-

+   retransmit and fast-recovery than non-SACK TCP.  As an example see

+   [FALL96].

+

+   The biggest difference between SCTP and TCP, however, is multi-

+   homing.  SCTP is designed to establish robust communication

+   associations between two endpoints each of which may be reachable by

+   more than one transport address.  Potentially different addresses may

+   lead to different data paths between the two endpoints, thus ideally

+   one may need a separate set of congestion control parameters for each

+   of the paths.  The treatment here of congestion control for multi-

+   homed receivers is new with SCTP and may require refinement in the

+   future.  The current algorithms make the following assumptions:

+

+   o  The sender usually uses the same destination address until being

+      instructed by the upper layer otherwise; however, SCTP may change

+      to an alternate destination in the event an address is marked

+      inactive (see Section 8.2).  Also, SCTP may retransmit to a

+      different transport address than the original transmission.

+

+   o  The sender keeps a separate congestion control parameter set for

+      each of the destination addresses it can send to (not each

+      source-destination pair but for each destination).  The parameters

+      should decay if the address is not used for a long enough time

+      period.

+

+   o  For each of the destination addresses, an endpoint does slow-start

+      upon the first transmission to that address.

+

+   Note:  TCP guarantees in-sequence delivery of data to its upper-layer

+   protocol within a single TCP session.  This means that when TCP

+   notices a gap in the received sequence number, it waits until the gap

+   is filled before delivering the data that was received with sequence

+   numbers higher than that of the missing data.  On the other hand,

+   SCTP can deliver data to its upper-layer protocol even if there is a

+   gap in TSN if the Stream Sequence Numbers are in sequence for a

+   particular stream (i.e., the missing DATA chunks are for a different

+   stream) or if unordered delivery is indicated.  Although this does

+   not affect cwnd, it might affect rwnd calculation.

+

+

+

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 86]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+7.2 SCTP Slow-Start and Congestion Avoidance

+

+   The slow start and congestion avoidance algorithms MUST be used by an

+   endpoint to control the amount of data being injected into the

+   network. The congestion control in SCTP is employed in regard to the

+   association, not to an individual stream.  In some situations it may

+   be beneficial for an SCTP sender to be more conservative than the

+   algorithms allow; however, an SCTP sender MUST NOT be more aggressive

+   than the following algorithms allow.

+

+   Like TCP, an SCTP endpoint uses the following three control variables

+   to regulate its transmission rate.

+

+   o  Receiver advertised window size (rwnd, in bytes), which is set by

+      the receiver based on its available buffer space for incoming

+      packets.

+

+      Note: This variable is kept on the entire association.

+

+   o  Congestion control window (cwnd, in bytes), which is adjusted by

+      the sender based on observed network conditions.

+

+      Note: This variable is maintained on a per-destination address

+      basis.

+

+   o  Slow-start threshold (ssthresh, in bytes), which is used by the

+      sender to distinguish slow start and congestion avoidance phases.

+

+      Note: This variable is maintained on a per-destination address

+      basis.

+

+   SCTP also requires one additional control variable,

+   partial_bytes_acked, which is used during congestion avoidance phase

+   to facilitate cwnd adjustment.

+

+   Unlike TCP, an SCTP sender MUST keep a set of these control variables

+   cwnd, ssthresh and partial_bytes_acked for EACH destination address

+   of its peer (when its peer is multi-homed).  Only one rwnd is kept

+   for the whole association (no matter if the peer is multi-homed or

+   has a single address).

+

+7.2.1 Slow-Start

+

+   Beginning data transmission into a network with unknown conditions or

+   after a sufficiently long idle period requires SCTP to probe the

+   network to determine the available capacity.  The slow start

+   algorithm is used for this purpose at the beginning of a transfer, or

+   after repairing loss detected by the retransmission timer.

+

+

+

+Stewart, et al.             Standards Track                    [Page 87]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   o  The initial cwnd before DATA transmission or after a sufficiently

+      long idle period MUST be <= 2*MTU.

+

+   o  The initial cwnd after a retransmission timeout MUST be no more

+      than 1*MTU.

+

+   o  The initial value of ssthresh MAY be arbitrarily high (for

+      example, implementations MAY use the size of the receiver

+      advertised window).

+

+   o  Whenever cwnd is greater than zero, the endpoint is allowed to

+      have cwnd bytes of data outstanding on that transport address.

+

+   o  When cwnd is less than or equal to ssthresh an SCTP endpoint MUST

+      use the slow start algorithm to increase cwnd (assuming the

+      current congestion window is being fully utilized).  If an

+      incoming SACK advances the Cumulative TSN Ack Point, cwnd MUST be

+      increased by at most the lesser of 1) the total size of the

+      previously outstanding DATA chunk(s) acknowledged, and 2) the

+      destination's path MTU. This protects against the ACK-Splitting

+      attack outlined in [SAVAGE99].

+

+   In instances where its peer endpoint is multi-homed, if an endpoint

+   receives a SACK that advances its Cumulative TSN Ack Point, then it

+   should update its cwnd (or cwnds) apportioned to the destination

+   addresses to which it transmitted the acknowledged data.  However if

+   the received SACK does not advance the Cumulative TSN Ack Point, the

+   endpoint MUST NOT adjust the cwnd of any of the destination

+   addresses.

+

+   Because an endpoint's cwnd is not tied to its Cumulative TSN Ack

+   Point, as duplicate SACKs come in, even though they may not advance

+   the Cumulative TSN Ack Point an endpoint can still use them to clock

+   out new data.  That is, the data newly acknowledged by the SACK

+   diminishes the amount of data now in flight to less than cwnd; and so

+   the current, unchanged value of cwnd now allows new data to be sent.

+   On the other hand, the increase of cwnd must be tied to the

+   Cumulative TSN Ack Point advancement as specified above.  Otherwise

+   the duplicate SACKs will not only clock out new data, but also will

+   adversely clock out more new data than what has just left the

+   network, during a time of possible congestion.

+

+   o  When the endpoint does not transmit data on a given transport

+      address, the cwnd of the transport address should be adjusted to

+      max(cwnd/2, 2*MTU) per RTO.

+

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 88]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+7.2.2 Congestion Avoidance

+

+   When cwnd is greater than ssthresh, cwnd should be incremented by

+   1*MTU per RTT if the sender has cwnd or more bytes of data

+   outstanding for the corresponding transport address.

+

+   In practice an implementation can achieve this goal in the following

+   way:

+

+   o  partial_bytes_acked is initialized to 0.

+

+   o  Whenever cwnd is greater than ssthresh, upon each SACK arrival

+      that advances the Cumulative TSN Ack Point, increase

+      partial_bytes_acked by the total number of bytes of all new chunks

+      acknowledged in that SACK including chunks acknowledged by the new

+      Cumulative TSN Ack and by Gap Ack Blocks.

+

+   o  When partial_bytes_acked is equal to or greater than cwnd and

+      before the arrival of the SACK the sender had cwnd or more bytes

+      of data outstanding (i.e., before arrival of the SACK, flightsize

+      was greater than or equal to cwnd), increase cwnd by MTU, and

+      reset partial_bytes_acked to (partial_bytes_acked - cwnd).

+

+   o  Same as in the slow start, when the sender does not transmit DATA

+      on a given transport address, the cwnd of the transport address

+      should be adjusted to max(cwnd / 2, 2*MTU) per RTO.

+

+   o  When all of the data transmitted by the sender has been

+      acknowledged by the receiver, partial_bytes_acked is initialized

+      to 0.

+

+7.2.3 Congestion Control

+

+   Upon detection of packet losses from SACK  (see Section 7.2.4), An

+   endpoint should do the following:

+

+      ssthresh = max(cwnd/2, 2*MTU)

+      cwnd = ssthresh

+

+   Basically, a packet loss causes cwnd to be cut in half.

+

+   When the T3-rtx timer expires on an address, SCTP should perform slow

+   start by:

+

+      ssthresh = max(cwnd/2, 2*MTU)

+      cwnd = 1*MTU

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 89]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   and assure that no more than one SCTP packet will be in flight for

+   that address until the endpoint receives acknowledgement for

+   successful delivery of data to that address.

+

+7.2.4 Fast Retransmit on Gap Reports

+

+   In the absence of data loss, an endpoint performs delayed

+   acknowledgement.  However, whenever an endpoint notices a hole in the

+   arriving TSN sequence, it SHOULD start sending a SACK back every time

+   a packet arrives carrying data until the hole is filled.

+

+   Whenever an endpoint receives a SACK that indicates some TSN(s)

+   missing, it SHOULD wait for 3 further miss indications (via

+   subsequent SACK's) on the same TSN(s) before taking action with

+   regard to Fast Retransmit.

+

+   When the TSN(s) is reported as missing in the fourth consecutive

+   SACK, the data sender shall:

+

+   1) Mark the missing DATA chunk(s) for retransmission,

+

+   2) Adjust the ssthresh and cwnd of the destination address(es) to

+      which the missing DATA chunks were last sent, according to the

+      formula described in Section 7.2.3.

+

+   3) Determine how many of the earliest (i.e., lowest TSN) DATA chunks

+      marked for retransmission will fit into a single packet, subject

+      to constraint of the path MTU of the destination transport address

+      to which the packet is being sent.  Call this value K. Retransmit

+      those K DATA chunks in a single packet.

+

+   4) Restart T3-rtx timer only if the last SACK acknowledged the lowest

+      outstanding TSN number sent to that address, or the endpoint is

+      retransmitting the first outstanding DATA chunk sent to that

+      address.

+

+   Note: Before the above adjustments, if the received SACK also

+   acknowledges new DATA chunks and advances the Cumulative TSN Ack

+   Point, the cwnd adjustment rules defined in Sections 7.2.1 and 7.2.2

+   must be applied first.

+

+   A straightforward implementation of the above keeps a counter for

+   each TSN hole reported by a SACK. The counter increments for each

+   consecutive SACK reporting the TSN hole.  After reaching 4 and

+   starting the fast retransmit procedure, the counter resets to 0.

+

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 90]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   Because cwnd in SCTP indirectly bounds the number of outstanding

+   TSN's, the effect of TCP fast-recovery is achieved automatically with

+   no adjustment to the congestion control window size.

+

+7.3 Path MTU Discovery

+

+   [RFC1191] specifies "Path MTU Discovery", whereby an endpoint

+   maintains an estimate of the maximum transmission unit (MTU) along a

+   given Internet path and refrains from sending packets along that path

+   which exceed the MTU, other than occasional attempts to probe for a

+   change in the Path MTU (PMTU).  RFC 1191 is thorough in its

+   discussion of the MTU discovery mechanism and strategies for

+   determining the current end-to-end MTU setting as well as detecting

+   changes in this value.  [RFC1981] specifies the same mechanisms for

+   IPv6.  An SCTP sender using IPv6 MUST use Path MTU Discovery unless

+   all packets are less than the minimum IPv6 MTU [RFC2460].

+

+   An endpoint SHOULD apply these techniques, and SHOULD do so on a

+   per-destination-address basis.

+

+   There are 4 ways in which SCTP differs from the description in RFC

+   1191 of applying MTU discovery to TCP:

+

+   1) SCTP associations can span multiple addresses.  An endpoint MUST

+      maintain separate MTU estimates for each destination address of

+      its peer.

+

+   2) Elsewhere in this document, when the term "MTU" is discussed, it

+      refers to the MTU associated with the destination address

+      corresponding to the context of the discussion.

+

+   3) Unlike TCP, SCTP does not have a notion of "Maximum Segment Size".

+      Accordingly, the MTU for each destination address SHOULD be

+      initialized to a value no larger than the link MTU for the local

+      interface to which packets for that remote destination address

+      will be routed.

+

+   4) Since data transmission in SCTP is naturally structured in terms

+      of TSNs rather than bytes (as is the case for TCP), the discussion

+      in Section 6.5 of RFC 1191 applies: When retransmitting an IP

+      datagram to a remote address for which the IP datagram appears too

+      large for the path MTU to that address, the IP datagram SHOULD be

+      retransmitted without the DF bit set, allowing it to possibly be

+      fragmented.  Transmissions of new IP datagrams MUST have DF set.

+

+

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 91]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   5) The sender should track an association PMTU which will be the

+      smallest PMTU discovered for all of the peer's destination

+      addresses.  When fragmenting messages into multiple parts this

+      association PMTU should be used to calculate the size of each

+      fragment.  This will allow retransmissions to be seamlessly sent

+      to an alternate address without encountering IP fragmentation.

+

+   Other than these differences, the discussion of TCP's use of MTU

+   discovery in RFCs 1191 and 1981 applies to SCTP on a per-

+   destination-address basis.

+

+   Note: For IPv6 destination addresses the DF bit does not exist,

+   instead the IP datagram must be fragmented as described in [RFC2460].

+

+8.  Fault Management

+

+8.1 Endpoint Failure Detection

+

+   An endpoint shall keep a counter on the total number of consecutive

+   retransmissions to its peer (including retransmissions to all the

+   destination transport addresses of the peer if it is multi-homed).

+   If the value of this counter exceeds the limit indicated in the

+   protocol parameter 'Association.Max.Retrans', the endpoint shall

+   consider the peer endpoint unreachable and shall stop transmitting

+   any more data to it (and thus the association enters the CLOSED

+   state).  In addition, the endpoint shall report the failure to the

+   upper layer, and optionally report back all outstanding user data

+   remaining in its outbound queue. The association is automatically

+   closed when the peer endpoint becomes unreachable.

+

+   The counter shall be reset each time a DATA chunk sent to that peer

+   endpoint is acknowledged (by the reception of a SACK), or a

+   HEARTBEAT-ACK is received from the peer endpoint.

+

+8.2 Path Failure Detection

+

+   When its peer endpoint is multi-homed, an endpoint should keep a

+   error counter for each of the destination transport addresses of the

+   peer endpoint.

+

+   Each time the T3-rtx timer expires on any address, or when a

+   HEARTBEAT sent to an idle address is not acknowledged within a RTO,

+   the error counter of that destination address will be incremented.

+   When the value in the error counter exceeds the protocol parameter

+   'Path.Max.Retrans' of that destination address, the endpoint should

+   mark the destination transport address as inactive, and a

+   notification SHOULD be sent to the upper layer.

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 92]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   When an outstanding TSN is acknowledged or a HEARTBEAT sent to that

+   address is acknowledged with a HEARTBEAT ACK, the endpoint shall

+   clear the error counter of the destination transport address to which

+   the DATA chunk was last sent (or HEARTBEAT was sent).  When the peer

+   endpoint is multi-homed and the last chunk sent to it was a

+   retransmission to an alternate address, there exists an ambiguity as

+   to whether or not the acknowledgement should be credited to the

+   address of the last chunk sent.  However, this ambiguity does not

+   seem to bear any significant consequence to SCTP behavior.  If this

+   ambiguity is undesirable, the transmitter may choose not to clear the

+   error counter if the last chunk sent was a retransmission.

+

+   Note: When configuring the SCTP endpoint, the user should avoid

+   having the value of 'Association.Max.Retrans' larger than the

+   summation of the 'Path.Max.Retrans' of all the destination addresses

+   for the remote endpoint.  Otherwise, all the destination addresses

+   may become inactive while the endpoint still considers the peer

+   endpoint reachable.  When this condition occurs, how the SCTP chooses

+   to function is implementation specific.

+

+   When the primary path is marked inactive (due to excessive

+   retransmissions, for instance), the sender MAY automatically transmit

+   new packets to an alternate destination address if one exists and is

+   active.  If more than one alternate address is active when the

+   primary path is marked inactive only ONE transport address SHOULD be

+   chosen and used as the new destination transport address.

+

+8.3 Path Heartbeat

+

+   By default, an SCTP endpoint shall monitor the reachability of the

+   idle destination transport address(es) of its peer by sending a

+   HEARTBEAT chunk periodically to the destination transport

+   address(es).

+

+   A destination transport address is considered "idle" if no new chunk

+   which can be used for updating path RTT (usually including first

+   transmission DATA, INIT, COOKIE ECHO, HEARTBEAT etc.) and no

+   HEARTBEAT has been sent to it within the current heartbeat period of

+   that address.  This applies to both active and inactive destination

+   addresses.

+

+   The upper layer can optionally initiate the following functions:

+

+   A) Disable heartbeat on a specific destination transport address of a

+      given association,

+

+   B) Change the HB.interval,

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 93]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   C) Re-enable heartbeat on a specific destination transport address of

+      a given association, and,

+

+   D) Request an on-demand HEARTBEAT on a specific destination transport

+      address of a given association.

+

+   The endpoint should increment the respective error counter of the

+   destination transport address each time a HEARTBEAT is sent to that

+   address and not acknowledged within one RTO.

+

+   When the value of this counter reaches the protocol parameter '

+   Path.Max.Retrans', the endpoint should mark the corresponding

+   destination address as inactive if it is not so marked, and may also

+   optionally report to the upper layer the change of reachability of

+   this destination address.  After this, the endpoint should continue

+   HEARTBEAT on this destination address but should stop increasing the

+   counter.

+

+   The sender of the HEARTBEAT chunk should include in the Heartbeat

+   Information field of the chunk the current time when the packet is

+   sent out and the destination address to which the packet is sent.

+

+   IMPLEMENTATION NOTE: An alternative implementation of the heartbeat

+   mechanism that can be used is to increment the error counter variable

+   every time a HEARTBEAT is sent to a destination.  Whenever a

+   HEARTBEAT ACK arrives, the sender SHOULD clear the error counter of

+   the destination that the HEARTBEAT was sent to.  This in effect would

+   clear the previously stroked error (and any other error counts as

+   well).

+

+   The receiver of the HEARTBEAT should immediately respond with a

+   HEARTBEAT ACK that contains the Heartbeat Information field copied

+   from the received HEARTBEAT chunk.

+

+   Upon the receipt of the HEARTBEAT ACK, the sender of the HEARTBEAT

+   should clear the error counter of the destination transport address

+   to which the HEARTBEAT was sent, and mark the destination transport

+   address as active if it is not so marked.  The endpoint may

+   optionally report to the upper layer when an inactive destination

+   address is marked as active due to the reception of the latest

+   HEARTBEAT ACK.  The receiver of the HEARTBEAT ACK must also clear the

+   association overall error count as well (as defined in section 8.1).

+

+   The receiver of the HEARTBEAT ACK should also perform an RTT

+   measurement for that destination transport address using the time

+   value carried in the HEARTBEAT ACK chunk.

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 94]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   On an idle destination address that is allowed to heartbeat, a

+   HEARTBEAT chunk is RECOMMENDED to be sent once per RTO of that

+   destination address plus the protocol parameter 'HB.interval' , with

+   jittering of +/- 50%, and exponential back-off of the RTO if the

+   previous HEARTBEAT is unanswered.

+

+   A primitive is provided for the SCTP user to change the HB.interval

+   and turn on or off the heartbeat on a given destination address.  The

+   heartbeat interval set by the SCTP user is added to the RTO of that

+   destination (including any exponential backoff).  Only one heartbeat

+   should be sent each time the heartbeat timer expires (if multiple

+   destinations are idle).  It is a implementation decision on how to

+   choose which of the candidate idle destinations to heartbeat to (if

+   more than one destination is idle).

+

+   Note: When tuning the heartbeat interval, there is a side effect that

+   SHOULD be taken into account.  When this value is increased, i.e.

+   the HEARTBEAT takes longer, the detection of lost ABORT messages

+   takes longer as well.  If a peer endpoint ABORTs the association for

+   any reason and the ABORT chunk is lost, the local endpoint will only

+   discover the lost ABORT by sending a DATA chunk or HEARTBEAT chunk

+   (thus causing the peer to send another ABORT).  This must be

+   considered when tuning the HEARTBEAT timer.  If the HEARTBEAT is

+   disabled only sending DATA to the association will discover a lost

+   ABORT from the peer.

+

+8.4 Handle "Out of the blue" Packets

+

+   An SCTP packet is called an "out of the blue" (OOTB) packet if it is

+   correctly formed, i.e., passed the receiver's Adler-32 check (see

+   Section 6.8), but the receiver is not able to identify the

+   association to which this packet belongs.

+

+   The receiver of an OOTB packet MUST do the following:

+

+   1) If the OOTB packet is to or from a non-unicast address, silently

+      discard the packet.  Otherwise,

+

+   2) If the OOTB packet contains an ABORT chunk, the receiver MUST

+      silently discard the OOTB packet and take no further action.

+      Otherwise,

+

+   3) If the packet contains an INIT chunk with a Verification Tag set

+      to '0', process it as described in Section 5.1.  Otherwise,

+

+   4) If the packet contains a COOKIE ECHO in the first chunk, process

+      it as described in Section 5.1.  Otherwise,

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 95]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   5) If the packet contains a SHUTDOWN ACK chunk, the receiver should

+      respond to the sender of the OOTB packet with a SHUTDOWN COMPLETE.

+      When sending the SHUTDOWN COMPLETE, the receiver of the OOTB

+      packet must fill in the Verification Tag field of the outbound

+      packet with the Verification Tag received in the SHUTDOWN ACK and

+      set the T-bit in the Chunk Flags to indicate that no TCB was

+      found. Otherwise,

+

+   6) If the packet contains a SHUTDOWN COMPLETE chunk, the receiver

+      should silently discard the packet and take no further action.

+      Otherwise,

+

+   7) If the packet contains a "Stale cookie" ERROR or a COOKIE ACK the

+      SCTP Packet should be silently discarded.  Otherwise,

+

+   8) The receiver should respond to the sender of the OOTB packet with

+      an ABORT.  When sending the ABORT, the receiver of the OOTB packet

+      MUST fill in the Verification Tag field of the outbound packet

+      with the value found in the Verification Tag field of the OOTB

+      packet and set the T-bit in the Chunk Flags to indicate that no

+      TCB was found.  After sending this ABORT, the receiver of the OOTB

+      packet shall discard the OOTB packet and take no further action.

+

+8.5 Verification Tag

+

+   The Verification Tag rules defined in this section apply when sending

+   or receiving SCTP packets which do not contain an INIT, SHUTDOWN

+   COMPLETE, COOKIE ECHO (see Section 5.1), ABORT or SHUTDOWN ACK chunk.

+   The rules for sending and receiving SCTP packets containing one of

+   these chunk types are discussed separately in Section 8.5.1.

+

+   When sending an SCTP packet, the endpoint MUST fill in the

+   Verification Tag field of the outbound packet with the tag value in

+   the Initiate Tag parameter of the INIT or INIT ACK received from its

+   peer.

+

+   When receiving an SCTP packet, the endpoint MUST ensure that the

+   value in the Verification Tag field of the received SCTP packet

+   matches its own Tag.  If the received Verification Tag value does not

+   match the receiver's own tag value, the receiver shall silently

+   discard the packet and shall not process it any further except for

+   those cases listed in Section 8.5.1 below.

+

+

+

+

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 96]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+8.5.1 Exceptions in Verification Tag Rules

+

+   A) Rules for packet carrying INIT:

+

+      -  The sender MUST set the Verification Tag of the packet to 0.

+

+      -  When an endpoint receives an SCTP packet with the Verification

+         Tag set to 0, it should verify that the packet contains only an

+         INIT chunk.  Otherwise, the receiver MUST silently discard the

+         packet.

+

+   B) Rules for packet carrying ABORT:

+

+      -  The endpoint shall always fill in the Verification Tag field of

+         the outbound packet with the destination endpoint's tag value

+         if it is known.

+

+      -  If the ABORT is sent in response to an OOTB packet, the

+         endpoint MUST follow the procedure described in Section 8.4.

+

+      -  The receiver MUST accept the packet if the Verification Tag

+         matches either its own tag, OR the tag of its peer.  Otherwise,

+         the receiver MUST silently discard the packet and take no

+         further action.

+

+   C) Rules for packet carrying SHUTDOWN COMPLETE:

+

+      -  When sending a SHUTDOWN COMPLETE, if the receiver of the

+         SHUTDOWN ACK has a TCB then the destination endpoint's tag MUST

+         be used.  Only where no TCB exists should the sender use the

+         Verification Tag from the SHUTDOWN ACK.

+

+      -  The receiver of a SHUTDOWN COMPLETE shall accept the packet if

+         the Verification Tag field of the packet matches its own tag OR

+         it is set to its peer's tag and the T bit is set in the Chunk

+         Flags. Otherwise, the receiver MUST silently discard the packet

+         and take no further action.  An endpoint MUST ignore the

+         SHUTDOWN COMPLETE if it is not in the SHUTDOWN-ACK-SENT state.

+

+   D) Rules for packet carrying a COOKIE ECHO

+

+      -  When sending a COOKIE ECHO, the endpoint MUST use the value of

+         the Initial Tag received in the INIT ACK.

+

+      -  The receiver of a COOKIE ECHO follows the procedures in Section

+         5.

+

+

+

+

+

+Stewart, et al.             Standards Track                    [Page 97]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   E) Rules for packet carrying a SHUTDOWN ACK

+

+      -  If the receiver is in COOKIE-ECHOED or COOKIE-WAIT state the

+         procedures in section 8.4 SHOULD be followed, in other words it

+         should be treated as an Out Of The Blue packet.

+

+9. Termination of Association

+

+   An endpoint should terminate its association when it exits from

+   service.  An association can be terminated by either abort or

+   shutdown.  An abort of an association is abortive by definition in

+   that any data pending on either end of the association is discarded

+   and not delivered to the peer.  A shutdown of an association is

+   considered a graceful close where all data in queue by either

+   endpoint is delivered to the respective peers.  However, in the case

+   of a shutdown, SCTP does not support a half-open state (like TCP)

+   wherein one side may continue sending data while the other end is

+   closed.  When either endpoint performs a shutdown, the association on

+   each peer will stop accepting new data from its user and only deliver

+   data in queue at the time of sending or receiving the SHUTDOWN chunk.

+

+9.1 Abort of an Association

+

+   When an endpoint decides to abort an existing association, it shall

+   send an ABORT chunk to its peer endpoint.  The sender MUST fill in

+   the peer's Verification Tag in the outbound packet and MUST NOT

+   bundle any DATA chunk with the ABORT.

+

+   An endpoint MUST NOT respond to any received packet that contains an

+   ABORT chunk (also see Section 8.4).

+

+   An endpoint receiving an ABORT shall apply the special Verification

+   Tag check rules described in Section 8.5.1.

+

+   After checking the Verification Tag, the receiving endpoint shall

+   remove the association from its record, and shall report the

+   termination to its upper layer.

+

+9.2 Shutdown of an Association

+

+   Using the SHUTDOWN primitive (see Section 10.1), the upper layer of

+   an endpoint in an association can gracefully close the association.

+   This will allow all outstanding DATA chunks from the peer of the

+   shutdown initiator to be delivered before the association terminates.

+

+   Upon receipt of the SHUTDOWN primitive from its upper layer, the

+   endpoint enters SHUTDOWN-PENDING state and remains there until all

+   outstanding data has been acknowledged by its peer.  The endpoint

+

+

+

+Stewart, et al.             Standards Track                    [Page 98]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   accepts no new data from its upper layer, but retransmits data to the

+   far end if necessary to fill gaps.

+

+   Once all its outstanding data has been acknowledged, the endpoint

+   shall send a SHUTDOWN chunk to its peer including in the Cumulative

+   TSN Ack field the last sequential TSN it has received from the peer.

+   It shall then start the T2-shutdown timer and enter the SHUTDOWN-SENT

+   state.  If the timer expires, the endpoint must re-send the SHUTDOWN

+   with the updated last sequential TSN received from its peer.

+

+   The rules in Section 6.3 MUST be followed to determine the proper

+   timer value for T2-shutdown.  To indicate any gaps in TSN, the

+   endpoint may also bundle a SACK with the SHUTDOWN chunk in the same

+   SCTP packet.

+

+   An endpoint should limit the number of retransmissions of the

+   SHUTDOWN chunk to the protocol parameter 'Association.Max.Retrans'.

+   If this threshold is exceeded the endpoint should destroy the TCB and

+   MUST report the peer endpoint unreachable to the upper layer (and

+   thus the association enters the CLOSED state).  The reception of any

+   packet from its peer (i.e. as the peer sends all of its queued DATA

+   chunks) should clear the endpoint's retransmission count and restart

+   the T2-Shutdown timer,  giving its peer ample opportunity to transmit

+   all of its queued DATA chunks that have not yet been sent.

+

+   Upon the reception of the SHUTDOWN, the peer endpoint shall

+

+   -  enter the SHUTDOWN-RECEIVED state,

+

+   -  stop accepting new data from its SCTP user

+

+   -  verify, by checking the Cumulative TSN Ack field of the chunk,

+      that all its outstanding DATA chunks have been received by the

+      SHUTDOWN sender.

+

+   Once an endpoint as reached the SHUTDOWN-RECEIVED state it MUST NOT

+   send a SHUTDOWN in response to a ULP request, and should discard

+   subsequent SHUTDOWN chunks.

+

+   If there are still outstanding DATA chunks left, the SHUTDOWN

+   receiver shall continue to follow normal data transmission procedures

+   defined in Section 6 until all outstanding DATA chunks are

+   acknowledged; however, the SHUTDOWN receiver MUST NOT accept new data

+   from its SCTP user.

+

+   While in SHUTDOWN-SENT state, the SHUTDOWN sender MUST immediately

+   respond to each received packet containing one or more DATA chunk(s)

+   with a SACK, a SHUTDOWN chunk, and restart the T2-shutdown timer. If

+

+

+

+Stewart, et al.             Standards Track                    [Page 99]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   it has no more outstanding DATA chunks, the SHUTDOWN receiver shall

+   send a SHUTDOWN ACK and start a T2-shutdown timer of its own,

+   entering the SHUTDOWN-ACK-SENT state.  If the timer expires, the

+   endpoint must re-send the SHUTDOWN ACK.

+

+   The sender of the SHUTDOWN ACK should limit the number of

+   retransmissions of the SHUTDOWN ACK chunk to the protocol parameter '

+   Association.Max.Retrans'.  If this threshold is exceeded the endpoint

+   should destroy the TCB and may report the peer endpoint unreachable

+   to the upper layer (and thus the association enters the CLOSED

+   state).

+

+   Upon the receipt of the SHUTDOWN ACK, the SHUTDOWN sender shall stop

+   the T2-shutdown timer, send a SHUTDOWN COMPLETE chunk to its peer,

+   and remove all record of the association.

+

+   Upon reception of the SHUTDOWN COMPLETE chunk the endpoint will

+   verify that it is in SHUTDOWN-ACK-SENT state, if it is not the chunk

+   should be discarded.  If the endpoint is in the SHUTDOWN-ACK-SENT

+   state the endpoint should stop the T2-shutdown timer and remove all

+   knowledge of the association (and thus the association enters the

+   CLOSED state).

+

+   An endpoint SHOULD assure that all its outstanding DATA chunks have

+   been acknowledged before initiating the shutdown procedure.

+

+   An endpoint should reject any new data request from its upper layer

+   if it is in SHUTDOWN-PENDING, SHUTDOWN-SENT, SHUTDOWN-RECEIVED, or

+   SHUTDOWN-ACK-SENT state.

+

+   If an endpoint is in SHUTDOWN-ACK-SENT state and receives an INIT

+   chunk (e.g., if the SHUTDOWN COMPLETE was lost) with source and

+   destination transport addresses (either in the IP addresses or in the

+   INIT chunk) that belong to this association, it should discard the

+   INIT chunk and retransmit the SHUTDOWN ACK chunk.

+

+   Note: Receipt of an INIT with the same source and destination IP

+   addresses as used in transport addresses assigned to an endpoint but

+   with a different port number indicates the initialization of a

+   separate association.

+

+   The sender of the INIT or COOKIE ECHO should respond to the receipt

+   of a SHUTDOWN-ACK with a stand-alone SHUTDOWN COMPLETE in an SCTP

+   packet with the Verification Tag field of its common header set to

+   the same tag that was received in the SHUTDOWN ACK packet.  This is

+   considered an Out of the Blue packet as defined in Section 8.4.  The

+   sender of the INIT lets T1-init continue running and remains in the

+

+

+

+

+Stewart, et al.             Standards Track                   [Page 100]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   COOKIE-WAIT or COOKIE-ECHOED state.  Normal T1-init timer expiration

+   will cause the INIT or COOKIE chunk to be retransmitted and thus

+   start a new association.

+

+   If a SHUTDOWN is received in COOKIE WAIT or COOKIE ECHOED states the

+   SHUTDOWN chunk SHOULD be silently discarded.

+

+   If an endpoint is in SHUTDOWN-SENT state and receives a SHUTDOWN

+   chunk from its peer, the endpoint shall respond immediately with a

+   SHUTDOWN ACK to its peer, and move into a SHUTDOWN-ACK-SENT state

+   restarting its T2-shutdown timer.

+

+   If an endpoint is in the SHUTDOWN-ACK-SENT state and receives a

+   SHUTDOWN ACK, it shall stop the T2-shutdown timer, send a SHUTDOWN

+   COMPLETE chunk to its peer, and remove all record of the association.

+

+10. Interface with Upper Layer

+

+   The Upper Layer Protocols (ULP) shall request for services by passing

+   primitives to SCTP and shall receive notifications from SCTP for

+   various events.

+

+   The primitives and notifications described in this section should be

+   used as a guideline for implementing SCTP.  The following functional

+   description of ULP interface primitives is shown for illustrative

+   purposes.  Different SCTP implementations may have different ULP

+   interfaces.  However, all SCTPs must provide a certain minimum set of

+   services to guarantee that all SCTP implementations can support the

+   same protocol hierarchy.

+

+10.1 ULP-to-SCTP

+

+   The following sections functionally characterize a ULP/SCTP

+   interface.  The notation used is similar to most procedure or

+   function calls in high level languages.

+

+   The ULP primitives described below specify the basic functions the

+   SCTP must perform to support inter-process communication.  Individual

+   implementations must define their own exact format, and may provide

+   combinations or subsets of the basic functions in single calls.

+

+   A) Initialize

+

+   Format: INITIALIZE ([local port], [local eligible address list]) ->

+   local SCTP instance name

+

+

+

+

+

+

+Stewart, et al.             Standards Track                   [Page 101]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   This primitive allows SCTP to initialize its internal data structures

+   and allocate necessary resources for setting up its operation

+   environment.  Once SCTP is initialized, ULP can communicate directly

+   with other endpoints without re-invoking this primitive.

+

+   SCTP will return a local SCTP instance name to the ULP.

+

+   Mandatory attributes:

+

+   None.

+

+   Optional attributes:

+

+   The following types of attributes may be passed along with the

+   primitive:

+

+   o  local port - SCTP port number, if ULP wants it to be specified;

+

+   o  local eligible address list - An address list that the local SCTP

+      endpoint should bind.  By default, if an address list is not

+      included, all IP addresses assigned to the host should be used by

+      the local endpoint.

+

+   IMPLEMENTATION NOTE: If this optional attribute is supported by an

+   implementation, it will be the responsibility of the implementation

+   to enforce that the IP source address field of any SCTP packets sent

+   out by this endpoint contains one of the IP addresses indicated in

+   the local eligible address list.

+

+   B) Associate

+

+   Format: ASSOCIATE(local SCTP instance name, destination transport addr,

+           outbound stream count)

+   -> association id [,destination transport addr list] [,outbound stream

+      count]

+

+   This primitive allows the upper layer to initiate an association to a

+   specific peer endpoint.

+

+   The peer endpoint shall be specified by one of the transport

+   addresses which defines the endpoint (see Section 1.4).  If the local

+   SCTP instance has not been initialized, the ASSOCIATE is considered

+   an error.

+

+   An association id, which is a local handle to the SCTP association,

+   will be returned on successful establishment of the association.  If

+   SCTP is not able to open an SCTP association with the peer endpoint,

+   an error is returned.

+

+

+

+Stewart, et al.             Standards Track                   [Page 102]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   Other association parameters may be returned, including the complete

+   destination transport addresses of the peer as well as the outbound

+   stream count of the local endpoint.  One of the transport address

+   from the returned destination addresses will be selected by the local

+   endpoint as default primary path for sending SCTP packets to this

+   peer.  The returned "destination transport addr list" can be used by

+   the ULP to change the default primary path or to force sending a

+   packet to a specific transport address.

+

+   IMPLEMENTATION NOTE: If ASSOCIATE primitive is implemented as a

+   blocking function call, the ASSOCIATE primitive can return

+   association parameters in addition to the association id upon

+   successful establishment.  If ASSOCIATE primitive is implemented as a

+   non-blocking call, only the association id shall be returned and

+   association parameters shall be passed using the COMMUNICATION UP

+   notification.

+

+   Mandatory attributes:

+

+   o  local SCTP instance name - obtained from the INITIALIZE operation.

+

+   o  destination transport addr - specified as one of the transport

+      addresses of the peer endpoint with which the association is to be

+      established.

+

+   o  outbound stream count - the number of outbound streams the ULP

+      would like to open towards this peer endpoint.

+

+   Optional attributes:

+

+   None.

+

+   C) Shutdown

+

+   Format: SHUTDOWN(association id)

+   -> result

+

+   Gracefully closes an association.  Any locally queued user data will

+   be delivered to the peer.  The association will be terminated only

+   after the peer acknowledges all the SCTP packets sent.  A success

+   code will be returned on successful termination of the association.

+   If attempting to terminate the association results in a failure, an

+   error code shall be returned.

+

+   Mandatory attributes:

+

+   o  association id - local handle to the SCTP association

+

+

+

+

+Stewart, et al.             Standards Track                   [Page 103]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   Optional attributes:

+

+   None.

+

+   D) Abort

+

+   Format: ABORT(association id [, cause code])

+   -> result

+

+   Ungracefully closes an association.  Any locally queued user data

+   will be discarded and an ABORT chunk is sent to the peer.  A success

+   code will be returned on successful abortion of the association.  If

+   attempting to abort the association results in a failure, an error

+   code shall be returned.

+

+   Mandatory attributes:

+

+   o  association id - local handle to the SCTP association

+

+   Optional attributes:

+

+   o  cause code - reason of the abort to be passed to the peer.

+

+   None.

+

+   E) Send

+

+   Format: SEND(association id, buffer address, byte count [,context]

+           [,stream id] [,life time] [,destination transport address]

+           [,unorder flag] [,no-bundle flag] [,payload protocol-id] )

+   -> result

+

+   This is the main method to send user data via SCTP.

+

+   Mandatory attributes:

+

+   o  association id - local handle to the SCTP association

+

+   o  buffer address - the location where the user message to be

+      transmitted is stored;

+

+   o  byte count - The size of the user data in number of bytes;

+

+   Optional attributes:

+

+   o  context - an optional 32 bit integer that will be carried in the

+      sending failure notification to the ULP if the transportation of

+      this User Message fails.

+

+

+

+Stewart, et al.             Standards Track                   [Page 104]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   o  stream id - to indicate which stream to send the data on.  If not

+      specified, stream 0 will be used.

+

+   o  life time - specifies the life time of the user data.  The user

+      data will not be sent by SCTP after the life time expires.  This

+      parameter can be used to avoid efforts to transmit stale user

+      messages.  SCTP notifies the ULP if the data cannot be initiated

+      to transport (i.e. sent to the destination via SCTP's send

+      primitive) within the life time variable.  However, the user data

+      will be transmitted if SCTP has attempted to transmit a chunk

+      before the life time expired.

+

+   IMPLEMENTATION NOTE: In order to better support the data lifetime

+   option, the transmitter may hold back the assigning of the TSN number

+   to an outbound DATA chunk to the last moment.  And, for

+   implementation simplicity, once a TSN number has been assigned the

+   sender should consider the send of this DATA chunk as committed,

+   overriding any lifetime option attached to the DATA chunk.

+

+   o  destination transport address - specified as one of the

+      destination transport addresses of the peer endpoint to which this

+      packet should be sent.  Whenever possible, SCTP should use this

+      destination transport address for sending the packets, instead of

+      the current primary path.

+

+   o  unorder flag - this flag, if present, indicates that the user

+      would like the data delivered in an unordered fashion to the peer

+      (i.e., the U flag is set to 1 on all DATA chunks carrying this

+      message).

+

+   o  no-bundle flag - instructs SCTP not to bundle this user data with

+      other outbound DATA chunks.  SCTP MAY still bundle even when this

+      flag is present, when faced with network congestion.

+

+   o  payload protocol-id - A 32 bit unsigned integer that is to be

+      passed to the peer indicating the type of payload protocol data

+      being transmitted.  This value is passed as opaque data by SCTP.

+

+   F) Set Primary

+

+   Format: SETPRIMARY(association id, destination transport address,

+                      [source transport address] )

+   -> result

+

+   Instructs the local SCTP to use the specified destination transport

+   address as primary path for sending packets.

+

+

+

+

+

+Stewart, et al.             Standards Track                   [Page 105]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   The result of attempting this operation shall be returned.  If the

+   specified destination transport address is not present in the

+   "destination transport address list" returned earlier in an associate

+   command or communication up notification, an error shall be returned.

+

+   Mandatory attributes:

+

+   o  association id - local handle to the SCTP association

+

+   o  destination transport address - specified as one of the transport

+      addresses of the peer endpoint, which should be used as primary

+      address for sending packets.  This overrides the current primary

+      address information maintained by the local SCTP endpoint.

+

+   Optional attributes:

+

+   o  source transport address - optionally, some implementations may

+      allow you to set the default source address placed in all outgoing

+      IP datagrams.

+

+   G) Receive

+

+   Format: RECEIVE(association id, buffer address, buffer size

+           [,stream id])

+   -> byte count [,transport address] [,stream id] [,stream sequence

+      number] [,partial flag] [,delivery number] [,payload protocol-id]

+

+   This primitive shall read the first user message in the SCTP in-queue

+   into the buffer specified by ULP, if there is one available.  The

+   size of the message read, in bytes, will be returned.  It may,

+   depending on the specific implementation, also return other

+   information such as the sender's address, the stream id on which it

+   is received, whether there are more messages available for retrieval,

+   etc.  For ordered messages, their stream sequence number may also be

+   returned.

+

+   Depending upon the implementation, if this primitive is invoked when

+   no message is available the implementation should return an

+   indication of this condition or should block the invoking process

+   until data does become available.

+

+   Mandatory attributes:

+

+   o  association id - local handle to the SCTP association

+

+   o  buffer address - the memory location indicated by the ULP to store

+      the received message.

+

+

+

+

+Stewart, et al.             Standards Track                   [Page 106]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   o  buffer size - the maximum size of data to be received, in bytes.

+

+   Optional attributes:

+

+   o  stream id - to indicate which stream to receive the data on.

+

+   o  stream sequence number - the stream sequence number assigned by

+      the sending SCTP peer.

+

+   o  partial flag - if this returned flag is set to 1, then this

+      Receive contains  a partial delivery of the whole message.  When

+      this flag is set, the stream id and stream sequence number MUST

+      accompany this receive.  When this flag is set to 0, it indicates

+      that no more deliveries will be received for this stream sequence

+      number.

+

+   o  payload protocol-id - A 32 bit unsigned integer that is received

+      from the peer indicating the type of payload protocol of the

+      received data.  This value is passed as opaque data by SCTP.

+

+   H) Status

+

+   Format: STATUS(association id)

+   -> status data

+

+   This primitive should return a data block containing the following

+   information:

+     association connection state,

+     destination transport address list,

+     destination transport address reachability states,

+     current receiver window size,

+     current congestion window sizes,

+     number of  unacknowledged DATA chunks,

+     number of DATA chunks pending receipt,

+     primary path,

+     most recent SRTT on primary path,

+     RTO on primary path,

+     SRTT and RTO on other destination addresses, etc.

+

+   Mandatory attributes:

+

+   o association id - local handle to the SCTP association

+

+   Optional attributes:

+

+    None.

+

+

+

+

+

+Stewart, et al.             Standards Track                   [Page 107]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   I) Change Heartbeat

+

+   Format: CHANGEHEARTBEAT(association id, destination transport address,

+           new state [,interval])

+   -> result

+

+   Instructs the local endpoint to enable or disable heartbeat on the

+   specified destination transport address.

+

+   The result of attempting this operation shall be returned.

+

+   Note: Even when enabled, heartbeat will not take place if the

+   destination transport address is not idle.

+

+   Mandatory attributes:

+

+   o  association id - local handle to the SCTP association

+

+   o  destination transport address - specified as one of the transport

+      addresses of the peer endpoint.

+

+   o  new state - the new state of heartbeat for this destination

+      transport address (either enabled or disabled).

+

+   Optional attributes:

+

+   o  interval - if present, indicates the frequency of the heartbeat if

+      this is to enable heartbeat on a destination transport address.

+      This value is added to the RTO of the destination transport

+      address. This value, if present, effects all destinations.

+

+   J) Request HeartBeat

+

+   Format: REQUESTHEARTBEAT(association id, destination transport

+           address)

+   -> result

+

+   Instructs the local endpoint to perform a HeartBeat on the specified

+   destination transport address of the given association.  The returned

+   result should indicate whether the transmission of the HEARTBEAT

+   chunk to the destination address is successful.

+

+   Mandatory attributes:

+

+   o  association id - local handle to the SCTP association

+

+   o  destination transport address - the transport address of the

+      association on which a heartbeat should be issued.

+

+

+

+Stewart, et al.             Standards Track                   [Page 108]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   K) Get SRTT Report

+

+   Format: GETSRTTREPORT(association id, destination transport address)

+   -> srtt result

+

+   Instructs the local SCTP to report the current SRTT measurement on

+   the specified destination transport address of the given association.

+   The returned result can be an integer containing the most recent SRTT

+   in milliseconds.

+

+   Mandatory attributes:

+

+   o  association id - local handle to the SCTP association

+

+   o  destination transport address - the transport address of the

+      association on which the SRTT measurement is to be reported.

+

+   L) Set Failure Threshold

+

+   Format: SETFAILURETHRESHOLD(association id, destination transport

+           address, failure threshold)

+   -> result

+

+   This primitive allows the local SCTP to customize the reachability

+   failure detection threshold 'Path.Max.Retrans' for the specified

+   destination address.

+

+   Mandatory attributes:

+

+   o  association id - local handle to the SCTP association

+

+   o  destination transport address - the transport address of the

+      association on which the failure detection threshold is to be set.

+

+   o  failure threshold - the new value of 'Path.Max.Retrans' for the

+      destination address.

+

+   M) Set Protocol Parameters

+

+   Format: SETPROTOCOLPARAMETERS(association id, [,destination transport

+           address,] protocol parameter list)

+   -> result

+

+   This primitive allows the local SCTP to customize the protocol

+   parameters.

+

+

+

+

+

+

+Stewart, et al.             Standards Track                   [Page 109]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   Mandatory attributes:

+

+   o  association id - local handle to the SCTP association

+

+   o  protocol parameter list - The specific names and values of the

+      protocol parameters (e.g., Association.Max.Retrans [see Section

+      14]) that the SCTP user wishes to customize.

+

+   Optional attributes:

+

+   o  destination transport address - some of the protocol parameters

+      may be set on a per destination transport address basis.

+

+   N) Receive unsent message

+

+   Format: RECEIVE_UNSENT(data retrieval id, buffer address, buffer size

+           [,stream id] [, stream sequence number] [,partial flag]

+           [,payload protocol-id])

+

+   o  data retrieval id - The identification passed to the ULP in the

+      failure notification.

+

+   o  buffer address - the memory location indicated by the ULP to store

+      the received message.

+

+   o  buffer size - the maximum size of data to be received, in bytes.

+

+   Optional attributes:

+

+   o  stream id - this is a return value that is set to  indicate

+      which stream the data was sent to.

+

+   o  stream sequence number - this value is returned indicating

+      the stream sequence number that was associated with the message.

+

+   o  partial flag - if this returned flag is set to 1, then this

+      message is a partial delivery of the whole message.  When

+      this flag is set, the stream id and stream sequence number MUST

+      accompany this receive.  When this flag is set to 0, it indicates

+      that no more deliveries will be received for this stream sequence

+      number.

+

+   o  payload protocol-id - The 32 bit unsigned integer that was sent to

+      be sent to the peer indicating the type of payload protocol of the

+      received data.

+

+

+

+

+

+

+Stewart, et al.             Standards Track                   [Page 110]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   O)  Receive unacknowledged message

+

+   Format: RECEIVE_UNACKED(data retrieval id, buffer address, buffer size,

+           [,stream id] [, stream sequence number] [,partial flag]

+           [,payload protocol-id])

+

+   o  data retrieval id - The identification passed to the ULP in the

+      failure notification.

+

+   o  buffer address - the memory location indicated by the ULP to store

+      the received message.

+

+   o  buffer size - the maximum size of data to be received, in bytes.

+

+   Optional attributes:

+

+   o  stream id - this is a return value that is set to  indicate which

+      stream the data was sent to.

+

+   o  stream sequence number - this value is returned indicating the

+      stream sequence number that was associated with the message.

+

+   o  partial flag - if this returned flag is set to 1, then this

+      message is a partial delivery of the whole message.  When this

+      flag is set, the stream id and stream sequence number MUST

+      accompany this receive.  When this flag is set to 0, it indicates

+      that no more deliveries will be received for this stream sequence

+      number.

+

+   o  payload protocol-id - The 32 bit unsigned integer that was sent to

+      be sent to the peer indicating the type of payload protocol of the

+      received data.

+

+   P) Destroy SCTP instance

+

+   Format: DESTROY(local SCTP instance name)

+

+   o  local SCTP instance name - this is the value that was passed to

+      the application in the initialize primitive and it indicates which

+      SCTP instance to be destroyed.

+

+10.2 SCTP-to-ULP

+

+   It is assumed that the operating system or application environment

+   provides a means for the SCTP to asynchronously signal the ULP

+   process.  When SCTP does signal an ULP process, certain information

+   is passed to the ULP.

+

+

+

+

+Stewart, et al.             Standards Track                   [Page 111]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   IMPLEMENTATION NOTE: In some cases this may be done through a

+   separate socket or error channel.

+

+   A) DATA ARRIVE notification

+

+   SCTP shall invoke this notification on the ULP when a user message is

+   successfully received and ready for retrieval.

+

+   The following may be optionally be passed with the notification:

+

+   o  association id - local handle to the SCTP association

+

+   o  stream id - to indicate which stream the data is received on.

+

+   B) SEND FAILURE notification

+

+   If a message can not be delivered SCTP shall invoke this notification

+   on the ULP.

+

+   The following may be optionally be passed with the notification:

+

+   o  association id - local handle to the SCTP association

+

+   o  data retrieval id - an identification used to retrieve unsent and

+      unacknowledged data.

+

+   o  cause code - indicating the reason of the failure, e.g., size too

+      large, message life-time expiration, etc.

+

+   o  context - optional information associated with this message (see D

+      in Section 10.1).

+

+   C) NETWORK STATUS CHANGE notification

+

+   When a destination transport address is marked inactive (e.g., when

+   SCTP detects a failure), or marked active (e.g., when SCTP detects a

+   recovery), SCTP shall invoke this notification on the ULP.

+

+   The following shall be passed with the notification:

+

+   o  association id - local handle to the SCTP association

+

+   o  destination transport address - This indicates the destination

+      transport address of the peer endpoint affected by the change;

+

+   o  new-status - This indicates the new status.

+

+

+

+

+

+Stewart, et al.             Standards Track                   [Page 112]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   D) COMMUNICATION UP notification

+

+   This notification is used when SCTP becomes ready to send or receive

+   user messages, or when a lost communication to an endpoint is

+   restored.

+

+   IMPLEMENTATION NOTE: If ASSOCIATE primitive is implemented as a

+   blocking function call, the association parameters are returned as a

+   result of the ASSOCIATE primitive itself.  In that case,

+   COMMUNICATION UP notification is optional at the association

+   initiator's side.

+

+   The following shall be passed with the notification:

+

+   o  association id - local handle to the SCTP association

+

+   o  status - This indicates what type of event has occurred

+

+   o  destination transport address list - the complete set of transport

+      addresses of the peer

+

+   o  outbound stream count - the maximum number of streams allowed to

+      be used in this association by the ULP

+

+   o  inbound stream count - the number of streams the peer endpoint has

+      requested with this association (this may not be the same number

+      as 'outbound stream count').

+

+   E) COMMUNICATION LOST notification

+

+   When SCTP loses communication to an endpoint completely (e.g., via

+   Heartbeats) or detects that the endpoint has performed an abort

+   operation, it shall invoke this notification on the ULP.

+

+   The following shall be passed with the notification:

+

+   o  association id - local handle to the SCTP association

+

+   o status - This indicates what type of event has occurred; The status

+              may indicate a failure OR a normal termination event

+              occurred in response to a shutdown or abort request.

+

+   The following may be passed with the notification:

+

+   o  data retrieval id - an identification used to retrieve unsent and

+      unacknowledged data.

+

+   o  last-acked - the TSN last acked by that peer endpoint;

+

+

+

+Stewart, et al.             Standards Track                   [Page 113]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   o  last-sent - the TSN last sent to that peer endpoint;

+

+   F) COMMUNICATION ERROR notification

+

+   When SCTP receives an ERROR chunk from its peer and decides to notify

+   its ULP, it can invoke this notification on the ULP.

+

+   The following can be passed with the notification:

+

+   o  association id - local handle to the SCTP association

+

+   o  error info - this indicates the type of error and optionally some

+      additional information received through the ERROR chunk.

+

+   G) RESTART notification

+

+   When SCTP detects that the peer has restarted, it may send this

+   notification to its ULP.

+

+   The following can be passed with the notification:

+

+   o  association id - local handle to the SCTP association

+

+   H) SHUTDOWN COMPLETE notification

+

+   When SCTP completes the shutdown procedures (section 9.2) this

+   notification is passed to the upper layer.

+

+   The following can be passed with the notification:

+

+   o  association id - local handle to the SCTP association

+

+11. Security Considerations

+

+11.1 Security Objectives

+

+   As a common transport protocol designed to reliably carry time-

+   sensitive user messages, such as billing or signaling messages for

+   telephony services, between two networked endpoints, SCTP has the

+   following security objectives.

+

+   -  availability of reliable and timely data transport services

+   -  integrity of the user-to-user information carried by SCTP

+

+

+

+

+

+

+

+

+Stewart, et al.             Standards Track                   [Page 114]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+11.2 SCTP Responses To Potential Threats

+

+   SCTP may potentially be used in a wide variety of risk situations.

+   It is important for operator(s) of systems running SCTP to analyze

+   their particular situations and decide on the appropriate counter-

+   measures.

+

+   Operators of systems running SCTP should consult [RFC2196] for

+   guidance in securing their site.

+

+11.2.1 Countering Insider Attacks

+

+   The principles of [RFC2196] should be applied to minimize the risk of

+   theft of information or sabotage by insiders.  Such procedures

+   include publication of security policies, control of access at the

+   physical, software, and network levels, and separation of services.

+

+11.2.2 Protecting against Data Corruption in the Network

+

+   Where the risk of undetected errors in datagrams delivered by the

+   lower layer transport services is considered to be too great,

+   additional integrity protection is required.  If this additional

+   protection were provided in the application-layer, the SCTP header

+   would remain vulnerable to deliberate integrity attacks.  While the

+   existing SCTP mechanisms for detection of packet replays are

+   considered sufficient for normal operation, stronger protections are

+   needed to protect SCTP when the operating environment contains

+   significant risk of deliberate attacks from a sophisticated

+   adversary.

+

+   In order to promote software code-reuse, to avoid re-inventing the

+   wheel, and to avoid gratuitous complexity to SCTP, the IP

+   Authentication Header [RFC2402] SHOULD be used when the threat

+   environment requires stronger integrity protections, but does not

+   require confidentiality.

+

+   A widely implemented BSD Sockets API extension exists for

+   applications to request IP security services, such as AH or ESP from

+   an operating system kernel.  Applications can use such an API to

+   request AH whenever AH use is appropriate.

+

+11.2.3 Protecting Confidentiality

+

+   In most cases, the risk of breach of confidentiality applies to the

+   signaling data payload, not to the SCTP or lower-layer protocol

+   overheads.  If that is true, encryption of the SCTP user data only

+   might be considered.  As with the supplementary checksum service,

+   user data encryption MAY be performed by the SCTP user application.

+

+

+

+Stewart, et al.             Standards Track                   [Page 115]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   Alternately, the user application MAY use an implementation-specific

+   API to request that the IP Encapsulating Security Payload (ESP)

+   [RFC2406] be used to provide confidentiality and integrity.

+

+   Particularly for mobile users, the requirement for confidentiality

+   might include the masking of IP addresses and ports.  In this case

+   ESP SHOULD be used instead of application-level confidentiality.  If

+   ESP is used to protect confidentiality of SCTP traffic, an ESP

+   cryptographic transform that includes cryptographic integrity

+   protection MUST be used, because if there is a confidentiality threat

+   there will also be a strong integrity threat.

+

+   Whenever ESP is in use, application-level encryption is not generally

+   required.

+

+   Regardless of where confidentiality is provided, the ISAKMP [RFC2408]

+   and the Internet Key Exchange (IKE) [RFC2409] SHOULD be used for key

+   management.

+

+   Operators should consult [RFC2401] for more information on the

+   security services available at and immediately above the Internet

+   Protocol layer.

+

+11.2.4 Protecting against Blind Denial of Service Attacks

+

+   A blind attack is one where the attacker is unable to intercept or

+   otherwise see the content of data flows passing to and from the

+   target SCTP node.  Blind denial of service attacks may take the form

+   of flooding, masquerade, or improper monopolization of services.

+

+11.2.4.1 Flooding

+

+   The objective of flooding is to cause loss of service and incorrect

+   behavior at target systems through resource exhaustion, interference

+   with legitimate transactions, and exploitation of buffer-related

+   software bugs.  Flooding may be directed either at the SCTP node or

+   at resources in the intervening IP Access Links or the Internet.

+   Where the latter entities are the target, flooding will manifest

+   itself as loss of network services, including potentially the breach

+   of any firewalls in place.

+

+   In general, protection against flooding begins at the equipment

+   design level, where it includes measures such as:

+

+   -  avoiding commitment of limited resources before determining that

+      the request for service is legitimate

+

+

+

+

+

+Stewart, et al.             Standards Track                   [Page 116]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   -  giving priority to completion of processing in progress over the

+      acceptance of new work

+

+   -  identification and removal of duplicate or stale queued requests

+      for service.

+

+   -  not responding to unexpected packets sent to non-unicast

+      addresses.

+

+   Network equipment should be capable of generating an alarm and log if

+   a suspicious increase in traffic occurs.  The log should provide

+   information such as the identity of the incoming link and source

+   address(es) used which will help the network or SCTP system operator

+   to take protective measures.  Procedures should be in place for the

+   operator to act on such alarms if a clear pattern of abuse emerges.

+

+   The design of SCTP is resistant to flooding attacks, particularly in

+   its use of a four-way start-up handshake, its use of a cookie to

+   defer commitment of resources at the responding SCTP node until the

+   handshake is completed, and its use of a Verification Tag to prevent

+   insertion of extraneous packets into the flow of an established

+   association.

+

+   The IP Authentication Header and Encapsulating Security Payload might

+   be useful in reducing the risk of certain kinds of denial of service

+   attacks."

+

+   The use of the Host Name feature in the INIT chunk could be used to

+   flood a target DNS server.  A large backlog of DNS queries, resolving

+   the Host Name received in the INIT chunk to IP addresses, could be

+   accomplished by sending INIT's to multiple hosts in a given domain.

+   In addition, an attacker could use the Host Name feature in an

+   indirect attack on a third party by sending large numbers of INITs to

+   random hosts containing the host name of the target.  In addition to

+   the strain on DNS resources, this could also result in large numbers

+   of INIT ACKs being sent to the target.  One method to protect against

+   this type of attack is to verify that the IP addresses received from

+   DNS include the source IP address of the original INIT.  If the list

+   of IP addresses received from DNS does not include the source IP

+   address of the INIT, the endpoint MAY silently discard the INIT.

+   This last option will not protect against the attack against the DNS.

+

+

+

+

+

+

+

+

+

+

+Stewart, et al.             Standards Track                   [Page 117]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+11.2.4.2 Blind Masquerade

+

+   Masquerade can be used to deny service in several ways:

+

+   -  by tying up resources at the target SCTP node to which the

+      impersonated node has limited access.  For example, the target

+      node may by policy permit a maximum of one SCTP association with

+      the impersonated SCTP node.  The masquerading attacker may attempt

+      to establish an association purporting to come from the

+      impersonated node so that the latter cannot do so when it requires

+      it.

+

+   -  by deliberately allowing the impersonation to be detected, thereby

+      provoking counter-measures which cause the impersonated node to be

+      locked out of the target SCTP node.

+

+   -  by interfering with an established association by inserting

+      extraneous content such as a SHUTDOWN request.

+

+   SCTP reduces the risk of blind masquerade attacks through IP spoofing

+   by use of the four-way startup handshake.  Man-in-the-middle

+   masquerade attacks are discussed in Section 11.3 below.  Because the

+   initial exchange is memoryless, no lockout mechanism is triggered by

+   blind masquerade attacks.  In addition, the INIT ACK containing the

+   State Cookie is transmitted back to the IP address from which it

+   received the INIT.  Thus the attacker would not receive the INIT ACK

+   containing the State Cookie.  SCTP protects against insertion of

+   extraneous packets into the flow of an established association by use

+   of the Verification Tag.

+

+   Logging of received INIT requests and abnormalities such as

+   unexpected INIT ACKs might be considered as a way to detect patterns

+   of hostile activity.  However, the potential usefulness of such

+   logging must be weighed against the increased SCTP startup processing

+   it implies, rendering the SCTP node more vulnerable to flooding

+   attacks.  Logging is pointless without the establishment of operating

+   procedures to review and analyze the logs on a routine basis.

+

+11.2.4.3 Improper Monopolization of Services

+

+   Attacks under this heading are performed openly and legitimately by

+   the attacker.  They are directed against fellow users of the target

+   SCTP node or of the shared resources between the attacker and the

+   target node.  Possible attacks include the opening of a large number

+   of associations between the attacker's node and the target, or

+   transfer of large volumes of information within a legitimately-

+   established association.

+

+

+

+

+Stewart, et al.             Standards Track                   [Page 118]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   Policy limits should be placed on the number of associations per

+   adjoining SCTP node.  SCTP user applications should be capable of

+   detecting large volumes of illegitimate or "no-op" messages within a

+   given association and either logging or terminating the association

+   as a result, based on local policy.

+

+11.3 Protection against Fraud and Repudiation

+

+   The objective of fraud is to obtain services without authorization

+   and specifically without paying for them.  In order to achieve this

+   objective, the attacker must induce the SCTP user application at the

+   target SCTP node to provide the desired service while accepting

+   invalid billing data or failing to collect it.  Repudiation is a

+   related problem, since it may occur as a deliberate act of fraud or

+   simply because the repudiating party kept inadequate records of

+   service received.

+

+   Potential fraudulent attacks include interception and misuse of

+   authorizing information such as credit card numbers, blind masquerade

+   and replay, and man-in-the middle attacks which modify the packets

+   passing through a target SCTP association in real time.

+

+   The interception attack is countered by the confidentiality measures

+   discussed in Section 11.2.3 above.

+

+   Section 11.2.4.2 describes how SCTP is resistant to blind masquerade

+   attacks, as a result of the four-way startup handshake and the

+   Verification Tag.  The Verification Tag and TSN together are

+   protections against blind replay attacks, where the replay is into an

+   existing association.

+

+   However, SCTP does not protect against man-in-the-middle attacks

+   where the attacker is able to intercept and alter the packets sent

+   and received in an association.  For example, the INIT ACK will have

+   sufficient information sent on the wire for an adversary in the

+   middle to hijack an existing SCTP association.  Where a significant

+   possibility of such attacks is seen to exist, or where possible

+   repudiation is an issue, the use of the IPSEC AH service is

+   recommended to ensure both the integrity and the authenticity of the

+   SCTP packets passed.

+

+   SCTP also provides no protection against attacks originating at or

+   beyond the SCTP node and taking place within the context of an

+   existing association.  Prevention of such attacks should be covered

+   by appropriate security policies at the host site, as discussed in

+   Section 11.2.1.

+

+

+

+

+

+Stewart, et al.             Standards Track                   [Page 119]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+12. Recommended Transmission Control Block (TCB) Parameters

+

+   This section details a recommended set of parameters that should be

+   contained within the TCB for an implementation.  This section is for

+   illustrative purposes and should not be deemed as requirements on an

+   implementation or as an exhaustive list of all parameters inside an

+   SCTP TCB.  Each implementation may need its own additional parameters

+   for optimization.

+

+12.1 Parameters necessary for the SCTP instance

+

+   Associations: A list of current associations and mappings to the data

+                 consumers for each association.  This may be in the

+                 form of a hash table or other implementation dependent

+                 structure.  The data consumers may be process

+                 identification information such as file descriptors,

+                 named pipe pointer, or table pointers dependent on how

+                 SCTP is implemented.

+

+   Secret Key:   A secret key used by this endpoint to compute the MAC.

+                 This SHOULD be a cryptographic quality random number

+                 with a sufficient length.  Discussion in [RFC1750] can

+                 be helpful in selection of the key.

+

+   Address List: The list of IP addresses that this instance has bound.

+                 This information is passed to one's peer(s) in INIT and

+                 INIT ACK chunks.

+

+   SCTP Port:    The local SCTP port number the endpoint is bound to.

+

+12.2 Parameters necessary per association (i.e. the TCB)

+

+   Peer        : Tag value to be sent in every packet and is received

+   Verification: in the INIT or INIT ACK chunk.

+   Tag         :

+

+   My          : Tag expected in every inbound packet and sent in the

+   Verification: INIT or INIT ACK chunk.

+   Tag         :

+

+   State       : A state variable indicating what state the association

+               : is in, i.e. COOKIE-WAIT, COOKIE-ECHOED, ESTABLISHED,

+               : SHUTDOWN-PENDING, SHUTDOWN-SENT, SHUTDOWN-RECEIVED,

+               : SHUTDOWN-ACK-SENT.

+

+                 Note: No "CLOSED" state is illustrated since if a

+                 association is "CLOSED" its TCB SHOULD be removed.

+

+

+

+

+Stewart, et al.             Standards Track                   [Page 120]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   Peer        : A list of SCTP transport addresses that the peer is

+   Transport   : bound to.  This information is derived from the INIT or

+   Address     : INIT ACK and is used to associate an inbound packet

+   List        : with a given association.  Normally this information is

+               : hashed or keyed for quick lookup and access of the TCB.

+

+   Primary     : This is the current primary destination transport

+   Path        : address of the peer endpoint.  It may also specify a

+               : source transport address on this endpoint.

+

+   Overall     : The overall association error count.

+   Error Count :

+

+   Overall     : The threshold for this association that if the Overall

+   Error       : Error Count reaches will cause this association to be

+   Threshold   : torn down.

+

+   Peer Rwnd   : Current calculated value of the peer's rwnd.

+

+   Next TSN    : The next TSN number to be assigned to a new DATA chunk.

+               : This is sent in the INIT or INIT ACK chunk to the peer

+               : and incremented each time a DATA chunk is assigned a

+               : TSN (normally just prior to transmit or during

+               : fragmentation).

+

+   Last Rcvd   : This is the last TSN received in sequence.  This value

+   TSN         : is set initially by taking the peer's Initial TSN,

+               : received in the INIT or INIT ACK chunk, and

+               : subtracting one from it.

+

+   Mapping     : An array of bits or bytes indicating which out of

+   Array       : order TSN's have been received (relative to the

+               : Last Rcvd TSN).  If no gaps exist, i.e. no out of order

+               : packets have been received, this array will be set to

+               : all zero.  This structure may be in the form of a

+               : circular buffer or bit array.

+

+   Ack State   : This flag indicates if the next received packet

+               : is to be responded to with a SACK.  This is initialized

+               : to 0.  When a packet is received it is incremented.

+               : If this value reaches 2 or more, a SACK is sent and the

+               : value is reset to 0.  Note: This is used only when no

+               : DATA chunks are received out of order.  When DATA chunks

+               : are out of order, SACK's are not delayed (see Section

+               : 6).

+

+

+

+

+

+

+Stewart, et al.             Standards Track                   [Page 121]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   Inbound     : An array of structures to track the inbound streams.

+   Streams     : Normally including the next sequence number expected

+               : and possibly the stream number.

+

+   Outbound    : An array of structures to track the outbound streams.

+   Streams     : Normally including the next sequence number to

+               : be sent on the stream.

+

+   Reasm Queue : A re-assembly queue.

+

+   Local       : The list of local IP addresses bound in to this

+   Transport   : association.

+   Address     :

+   List        :

+

+   Association : The smallest PMTU discovered for all of the

+   PMTU        : peer's transport addresses.

+

+12.3 Per Transport Address Data

+

+   For each destination transport address in the peer's address list

+   derived from the INIT or INIT ACK chunk, a number of data elements

+   needs to be maintained including:

+

+   Error count : The current error count for this destination.

+

+   Error       : Current error threshold for this destination i.e.

+   Threshold   : what value marks the destination down if Error count

+               : reaches this value.

+

+   cwnd        : The current congestion window.

+

+   ssthresh    : The current ssthresh value.

+

+   RTO         : The current retransmission timeout value.

+

+   SRTT        : The current smoothed round trip time.

+

+   RTTVAR      : The current RTT variation.

+

+   partial     : The tracking method for increase of cwnd when in

+   bytes acked : congestion avoidance mode (see Section 6.2.2)

+

+   state       : The current state of this destination, i.e. DOWN, UP,

+               : ALLOW-HB, NO-HEARTBEAT, etc.

+

+   PMTU        : The current known path MTU.

+

+

+

+

+Stewart, et al.             Standards Track                   [Page 122]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   Per         : A timer used by each destination.

+   Destination :

+   Timer       :

+

+   RTO-Pending : A flag used to track if one of the DATA chunks sent to

+                 this address is currently being used to compute a

+                 RTT.  If this flag is 0, the next DATA chunk sent to this

+                 destination should be used to compute a RTT and this

+                 flag should be set.  Every time the RTT calculation

+                 completes (i.e. the DATA chunk is SACK'd) clear this

+                 flag.

+

+   last-time   : The time this destination was last sent to.  This can be

+   used        : used to determine if a HEARTBEAT is needed.

+

+12.4 General Parameters Needed

+

+   Out Queue   : A queue of outbound DATA chunks.

+

+   In Queue    : A queue of inbound DATA chunks.

+

+13. IANA Considerations

+

+   This protocol will require port reservation like TCP for the use of

+   "well known" servers within the Internet.  All current TCP ports

+   shall be automatically reserved in the SCTP port address space.  New

+   requests should follow IANA's current mechanisms for TCP.

+

+   This protocol may also be extended through IANA in three ways:

+

+    -- through definition of additional chunk types,

+    -- through definition of additional parameter types, or

+    -- through definition of additional cause codes within

+       ERROR chunks

+

+   In the case where a particular ULP using SCTP desires to have its own

+   ports, the ULP should be responsible for registering with IANA for

+   getting its ports assigned.

+

+13.1 IETF-defined Chunk Extension

+

+   The definition and use of new chunk types is an integral part of

+   SCTP.  Thus, new chunk types are assigned by IANA through an IETF

+   Consensus action as defined in [RFC2434].

+

+   The documentation for a new chunk code type must include the

+   following information:

+

+

+

+

+Stewart, et al.             Standards Track                   [Page 123]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   a) A long and short name for the new chunk type;

+

+   b) A detailed description of the structure of the chunk, which MUST

+      conform to the basic structure defined in Section 3.2;

+

+   c) A detailed definition and description of intended use of each

+      field within the chunk, including the chunk flags if any;

+

+   d) A detailed procedural description of the use of the new chunk type

+      within the operation of the protocol.

+

+   The last chunk type (255) is reserved for future extension if

+   necessary.

+

+13.2 IETF-defined Chunk Parameter Extension

+

+   The assignment of new chunk parameter type codes is done through an

+   IETF Consensus action as defined in [RFC2434].  Documentation of the

+   chunk parameter MUST contain the following information:

+

+   a) Name of the parameter type.

+

+   b) Detailed description of the structure of the parameter field.

+      This structure MUST conform to the general type-length-value

+      format described in Section 3.2.1.

+

+   c) Detailed definition of each component of the parameter value.

+

+   d) Detailed description of the intended use of this parameter type,

+      and an indication of whether and under what circumstances multiple

+      instances of this parameter type may be found within the same

+      chunk.

+

+13.3 IETF-defined Additional Error Causes

+

+   Additional cause codes may be allocated in the range 11 to 65535

+   through a Specification Required action as defined in [RFC2434].

+   Provided documentation must include the following information:

+

+   a) Name of the error condition.

+

+   b) Detailed description of the conditions under which an SCTP

+      endpoint should issue an ERROR (or ABORT) with this cause code.

+

+   c) Expected action by the SCTP endpoint which receives an ERROR (or

+      ABORT) chunk containing this cause code.

+

+

+

+

+

+Stewart, et al.             Standards Track                   [Page 124]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   d) Detailed description of the structure and content of data fields

+      which accompany this cause code.

+

+   The initial word (32 bits) of a cause code parameter MUST conform to

+   the format shown in Section 3.3.10, i.e.:

+

+   -- first two bytes contain the cause code value

+   -- last two bytes contain length of the Cause Parameter.

+

+13.4 Payload Protocol Identifiers

+

+   Except for value 0 which is reserved by SCTP to indicate an

+   unspecified payload protocol identifier in a DATA chunk, SCTP will

+   not be responsible for standardizing or verifying any payload

+   protocol identifiers; SCTP simply receives the identifier from the

+   upper layer and carries it with the corresponding payload data.

+

+   The upper layer, i.e., the SCTP user, SHOULD standardize any specific

+   protocol identifier with IANA if it is so desired.  The use of any

+   specific payload protocol identifier is out of the scope of SCTP.

+

+14. Suggested SCTP Protocol Parameter Values

+

+   The following protocol parameters are RECOMMENDED:

+

+   RTO.Initial              - 3  seconds

+   RTO.Min                  - 1  second

+   RTO.Max                 -  60 seconds

+   RTO.Alpha                - 1/8

+   RTO.Beta                 - 1/4

+   Valid.Cookie.Life        - 60  seconds

+   Association.Max.Retrans  - 10 attempts

+   Path.Max.Retrans         - 5  attempts (per destination address)

+   Max.Init.Retransmits     - 8  attempts

+   HB.interval              - 30 seconds

+

+   IMPLEMENTATION NOTE: The SCTP implementation may allow ULP to

+   customize some of these protocol parameters (see Section 10).

+

+   Note: RTO.Min SHOULD be set as recommended above.

+

+

+

+

+

+

+

+

+

+

+

+Stewart, et al.             Standards Track                   [Page 125]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+15. Acknowledgements

+

+   The authors wish to thank Mark Allman, R.J. Atkinson, Richard Band,

+   Scott Bradner, Steve Bellovin, Peter Butler, Ram Dantu, R.

+   Ezhirpavai, Mike Fisk, Sally Floyd, Atsushi Fukumoto, Matt Holdrege,

+   Henry Houh, Christian Huitema, Gary Lehecka, Jonathan Lee, David

+   Lehmann, John Loughney, Daniel Luan, Barry Nagelberg, Thomas Narten,

+   Erik Nordmark, Lyndon Ong, Shyamal Prasad, Kelvin Porter, Heinz

+   Prantner, Jarno Rajahalme, Raymond E. Reeves, Renee Revis, Ivan Arias

+   Rodriguez, A. Sankar, Greg Sidebottom, Brian Wyld, La Monte Yarroll,

+   and many others for their invaluable comments.

+

+16.  Authors' Addresses

+

+   Randall R. Stewart

+   24 Burning Bush Trail.

+   Crystal Lake, IL 60012

+   USA

+

+   Phone: +1-815-477-2127

+   EMail: rrs@cisco.com

+

+

+   Qiaobing Xie

+   Motorola, Inc.

+   1501 W. Shure Drive, #2309

+   Arlington Heights, IL 60004

+   USA

+

+   Phone: +1-847-632-3028

+   EMail: qxie1@email.mot.com

+

+

+   Ken Morneault

+   Cisco Systems Inc.

+   13615 Dulles Technology Drive

+   Herndon, VA. 20171

+   USA

+

+   Phone: +1-703-484-3323

+   EMail: kmorneau@cisco.com

+

+

+

+

+

+

+

+

+

+

+Stewart, et al.             Standards Track                   [Page 126]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   Chip Sharp

+   Cisco Systems Inc.

+   7025 Kit Creek Road

+   Research Triangle Park, NC  27709

+   USA

+

+   Phone: +1-919-392-3121

+   EMail: chsharp@cisco.com

+

+

+   Hanns Juergen Schwarzbauer

+   SIEMENS AG

+   Hofmannstr. 51

+   81359 Munich

+   Germany

+

+   Phone: +49-89-722-24236

+   EMail: HannsJuergen.Schwarzbauer@icn.siemens.de

+

+

+   Tom Taylor

+   Nortel Networks

+   1852 Lorraine Ave.

+   Ottawa, Ontario

+   Canada K1H 6Z8

+

+   Phone: +1-613-736-0961

+   EMail: taylor@nortelnetworks.com

+

+

+   Ian Rytina

+   Ericsson Australia

+   37/360 Elizabeth Street

+   Melbourne, Victoria 3000

+   Australia

+

+   Phone: +61-3-9301-6164

+   EMail: ian.rytina@ericsson.com

+

+

+

+

+

+

+

+

+

+

+

+

+

+Stewart, et al.             Standards Track                   [Page 127]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   Malleswar Kalla

+   Telcordia Technologies

+   3 Corporate Place

+   PYA-2J-341

+   Piscataway, NJ  08854

+   USA

+

+   Phone: +1-732-699-3728

+   EMail: mkalla@telcordia.com

+

+   Lixia Zhang

+   UCLA Computer Science Department

+   4531G Boelter Hall

+   Los Angeles, CA 90095-1596

+   USA

+

+   Phone: +1-310-825-2695

+   EMail: lixia@cs.ucla.edu

+

+   Vern Paxson

+   ACIRI

+   1947 Center St., Suite 600,

+   Berkeley, CA 94704-1198

+   USA

+

+   Phone: +1-510-666-2882

+   EMail: vern@aciri.org

+

+17. References

+

+   [RFC768]   Postel, J. (ed.), "User Datagram Protocol", STD 6, RFC

+              768, August 1980.

+

+   [RFC793]   Postel, J. (ed.), "Transmission Control Protocol", STD 7,

+              RFC 793, September 1981.

+

+   [RFC1123]  Braden, R., "Requirements for Internet hosts - application

+              and support", STD 3, RFC 1123, October 1989.

+

+   [RFC1191]  Mogul, J. and S. Deering, "Path MTU Discovery", RFC 1191,

+              November 1990.

+

+   [RFC1700]  Reynolds, J. and J. Postel, "Assigned Numbers", STD 2, RFC

+              1700, October 1994.

+

+   [RFC1981]  McCann, J., Deering, S. and J. Mogul, "Path MTU Discovery

+              for IP version 6", RFC 1981, August 1996.

+

+

+

+

+Stewart, et al.             Standards Track                   [Page 128]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   [RFC1982]  Elz, R. and R. Bush, "Serial Number Arithmetic", RFC 1982,

+              August 1996.

+

+   [RFC2026]  Bradner, S., "The Internet Standards Process -- Revision

+              3", BCP 9, RFC 2026, October 1996.

+

+   [RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate

+              Requirement Levels", BCP 14, RFC 2119, March 1997.

+

+   [RFC2401]  Kent, S. and R. Atkinson, "Security Architecture for the

+              Internet Protocol", RFC 2401,  November 1998.

+

+   [RFC2402]  Kent, S. and R. Atkinson, "IP Authentication Header", RFC

+              2402, November 1998.

+

+   [RFC2406]  Kent, S. and R. Atkinson, "IP Encapsulating Security

+              Payload (ESP)", RFC 2406, November 1998.

+

+   [RFC2408]  Maughan, D., Schertler, M., Schneider, M. and J. Turner,

+              "Internet Security Association and Key Management

+              Protocol", RFC 2408, November 1998.

+

+   [RFC2409]  Harkins, D. and D. Carrel, "The Internet Key Exchange

+              (IKE)", RFC 2409, November 1998.

+

+   [RFC2434]  Narten, T. and H. Alvestrand, "Guidelines for Writing an

+              IANA Considerations Section in RFCs", BCP 26, RFC 2434,

+              October 1998.

+

+   [RFC2460]  Deering, S. and R. Hinden, "Internet Protocol, Version 6

+              (IPv6) Specification", RFC 2460, December 1998.

+

+   [RFC2581]  Allman, M., Paxson, V. and W. Stevens, "TCP Congestion

+              Control", RFC 2581, April 1999.

+

+18. Bibliography

+

+   [ALLMAN99] Allman, M. and Paxson, V., "On Estimating End-to-End

+              Network Path Properties", Proc. SIGCOMM'99, 1999.

+

+   [FALL96]   Fall, K. and Floyd, S., Simulation-based Comparisons of

+              Tahoe, Reno, and SACK TCP, Computer Communications Review,

+              V. 26 N. 3, July 1996, pp. 5-21.

+

+   [RFC1750]  Eastlake, D. (ed.), "Randomness Recommendations for

+              Security", RFC 1750, December 1994.

+

+

+

+

+

+Stewart, et al.             Standards Track                   [Page 129]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   [RFC1950]  Deutsch P. and J. Gailly, "ZLIB Compressed Data Format

+              Specification version 3.3", RFC 1950, May 1996.

+

+   [RFC2104]  Krawczyk, H., Bellare, M. and R. Canetti, "HMAC:  Keyed-

+              Hashing for Message Authentication", RFC 2104, March 1997.

+

+   [RFC2196]  Fraser, B., "Site Security Handbook", FYI 8, RFC 2196,

+              September 1997.

+

+   [RFC2522]  Karn, P. and W. Simpson, "Photuris: Session-Key Management

+              Protocol", RFC 2522, March 1999.

+

+   [SAVAGE99] Savage, S., Cardwell, N., Wetherall, D., and Anderson, T.,

+              "TCP Congestion Control with a Misbehaving Receiver",  ACM

+              Computer Communication Review, 29(5), October 1999.

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+Stewart, et al.             Standards Track                   [Page 130]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+Appendix A: Explicit Congestion Notification

+

+   ECN (Ramakrishnan, K., Floyd, S., "Explicit Congestion Notification",

+   RFC 2481, January 1999) describes a proposed extension to IP that

+   details a method to become aware of congestion outside of datagram

+   loss.  This is an optional feature that an implementation MAY choose

+   to add to SCTP.  This appendix details the minor differences

+   implementers will need to be aware of if they choose to implement

+   this feature.  In general RFC 2481 should be followed with the

+   following exceptions.

+

+   Negotiation:

+

+   RFC2481 details negotiation of ECN during the SYN and SYN-ACK stages

+   of a TCP connection.  The sender of the SYN sets two bits in the TCP

+   flags, and the sender of the SYN-ACK sets only 1 bit.  The reasoning

+   behind this is to assure both sides are truly ECN capable.  For SCTP

+   this is not necessary.  To indicate that an endpoint is ECN capable

+   an endpoint SHOULD add to the INIT and or INIT ACK chunk the TLV

+   reserved for ECN.  This TLV contains no parameters, and thus has the

+   following format:

+

+       0                   1                   2                   3

+       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |   Parameter Type = 32768      |     Parameter Length = 4      |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+   ECN-Echo:

+

+   RFC 2481 details a specific bit for a receiver to send back in its

+   TCP acknowledgements to notify the sender of the Congestion

+   Experienced (CE) bit having arrived from the network.  For SCTP this

+   same indication is made by including the ECNE chunk.  This chunk

+   contains one data element, i.e. the lowest TSN associated with the IP

+   datagram marked with the CE bit, and looks as follows:

+

+       0                   1                   2                   3

+       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      | Chunk Type=12 | Flags=00000000|    Chunk Length = 8           |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |                      Lowest TSN Number                        |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+      Note: The ECNE is considered a Control chunk.

+

+

+

+

+

+Stewart, et al.             Standards Track                   [Page 131]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   CWR:

+

+   RFC 2481 details a specific bit for a sender to send in the header of

+   its next outbound TCP segment to indicate to its peer that it has

+   reduced its congestion window.  This is termed the CWR bit.  For

+   SCTP the same indication is made by including the CWR chunk.

+   This chunk contains one data element, i.e. the TSN number that

+   was sent in the ECNE chunk.  This element represents the lowest

+   TSN number in the datagram that was originally marked with the

+   CE bit.

+

+       0                   1                   2                   3

+       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      | Chunk Type=13 | Flags=00000000|    Chunk Length = 8           |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+      |                      Lowest TSN Number                        |

+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+      Note: The CWR is considered a Control chunk.

+

+Appendix B Alder 32 bit checksum calculation

+

+   The Adler-32 checksum calculation given in this appendix is copied from

+   [RFC1950].

+

+   Adler-32 is composed of two sums accumulated per byte: s1 is the sum

+   of all bytes, s2 is the sum of all s1 values.  Both sums are done

+   modulo 65521.  s1 is initialized to 1, s2 to zero.  The Adler-32

+   checksum is stored as s2*65536 + s1 in network byte order.

+

+   The following C code computes the Adler-32 checksum of a data buffer.

+   It is written for clarity, not for speed.  The sample code is in the

+   ANSI C programming language.  Non C users may find it easier to read

+   with these hints:

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+Stewart, et al.             Standards Track                   [Page 132]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+   &      Bitwise AND operator.

+   >>     Bitwise right shift operator.  When applied to an

+          unsigned quantity, as here, right shift inserts zero bit(s)

+          at the left.

+   <<     Bitwise left shift operator.  Left shift inserts zero

+          bit(s) at the right.

+   ++     "n++" increments the variable n.

+   %      modulo operator: a % b is the remainder of a divided by b.

+    #define BASE 65521 /* largest prime smaller than 65536 */

+    /*

+      Update a running Adler-32 checksum with the bytes buf[0..len-1]

+      and return the updated checksum.  The Adler-32 checksum should be

+      initialized to 1.

+

+       Usage example:

+

+         unsigned long adler = 1L;

+

+         while (read_buffer(buffer, length) != EOF) {

+           adler = update_adler32(adler, buffer, length);

+         }

+         if (adler != original_adler) error();

+      */

+      unsigned long update_adler32(unsigned long adler,

+         unsigned char *buf, int len)

+      {

+        unsigned long s1 = adler & 0xffff;

+        unsigned long s2 = (adler >> 16) & 0xffff;

+        int n;

+

+        for (n = 0; n < len; n++) {

+          s1 = (s1 + buf[n]) % BASE;

+          s2 = (s2 + s1)     % BASE;

+        }

+        return (s2 << 16) + s1;

+      }

+

+      /* Return the adler32 of the bytes buf[0..len-1] */

+      unsigned long adler32(unsigned char *buf, int len)

+      {

+        return update_adler32(1L, buf, len);

+      }

+

+

+

+

+

+

+

+

+

+Stewart, et al.             Standards Track                   [Page 133]

+

+RFC 2960          Stream Control Transmission Protocol      October 2000

+

+

+Full Copyright Statement

+

+   Copyright (C) The Internet Society (2000).  All Rights Reserved.

+

+   This document and translations of it may be copied and furnished to

+   others, and derivative works that comment on or otherwise explain it

+   or assist in its implementation may be prepared, copied, published

+   and distributed, in whole or in part, without restriction of any

+   kind, provided that the above copyright notice and this paragraph are

+   included on all such copies and derivative works.  However, this

+   document itself may not be modified in any way, such as by removing

+   the copyright notice or references to the Internet Society or other

+   Internet organizations, except as needed for the purpose of

+   developing Internet standards in which case the procedures for

+   copyrights defined in the Internet Standards process must be

+   followed, or as required to translate it into languages other than

+   English.

+

+   The limited permissions granted above are perpetual and will not be

+   revoked by the Internet Society or its successors or assigns.

+

+   This document and the information contained herein is provided on an

+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING

+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING

+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION

+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF

+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

+

+Acknowledgement

+

+   Funding for the RFC Editor function is currently provided by the

+   Internet Society.

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+Stewart, et al.             Standards Track                   [Page 134]

+

diff --git a/doc/rfc3257.txt b/doc/rfc3257.txt
new file mode 100644
index 0000000..c2df92b
--- /dev/null
+++ b/doc/rfc3257.txt
@@ -0,0 +1,731 @@
+
+
+
+
+
+
+Network Working Group                                           L. Coene
+Request for Comments: 3257                                       Siemens
+Category: Informational                                       April 2002
+
+
+      Stream Control Transmission Protocol Applicability Statement
+
+Status of this Memo
+
+   This memo provides information for the Internet community.  It does
+   not specify an Internet standard of any kind.  Distribution of this
+   memo is unlimited.
+
+Copyright Notice
+
+   Copyright (C) The Internet Society (2002).  All Rights Reserved.
+
+Abstract
+
+   This document describes the applicability of the Stream Control
+   Transmission Protocol (SCTP).  It also contrasts SCTP with the two
+   dominant transport protocols, User Datagram Protocol (UDP) &
+   Transmission Control Protocol (TCP), and gives some guidelines for
+   when best to use SCTP and when not best to use SCTP.
+
+Table of contents
+
+   1. Introduction ..................................................  2
+   1.1 Terminology ..................................................  2
+   2 Transport protocols ............................................  2
+   2.1 TCP service model ............................................  2
+   2.2 SCTP service model ...........................................  3
+   2.3 UDP service model ............................................  4
+   3 SCTP Multihoming issues ........................................  4
+   4 SCTP Network Address Translators (NAT) issues [RFC2663] ........  5
+   5 Security Considerations ........................................  6
+   5.1 Security issues with TCP .....................................  6
+   5.2 Security issues with SCTP ....................................  7
+   5.3 Security issues with both TCP and SCTP .......................  8
+   6 References and related work ....................................  9
+   7 Acknowledgments ................................................ 10
+   Appendix A: Major functions provided by SCTP ..................... 11
+   Editor's Address ................................................. 12
+   Full Copyright Statement ......................................... 13
+
+
+
+
+
+
+
+Coene                        Informational                      [Page 1]
+
+RFC 3257              SCTP Applicability Statement            April 2002
+
+
+1 Introduction
+
+   SCTP is a reliable transport protocol [RFC2960], which along with TCP
+   [RFC793], RTP [RFC1889], and UDP [RFC768], provides transport-layer
+   services for upper layer protocols and services.  UDP, RTP, TCP, and
+   SCTP are currently the IETF standards-track transport-layer
+   protocols.  Each protocol has a domain of applicability and services
+   it provides, albeit with some overlaps.
+
+   By clarifying the situations where the functionality of these
+   protocols are applicable, this document can guide implementers and
+   protocol designers in selecting which protocol to use.
+
+   Special attention is given to services SCTP provides which would make
+   a decision to use SCTP the right one.
+
+   Major functions provided by SCTP can be found in Appendix A.
+
+1.1 Terminology
+
+   The following terms are commonly identified in this work:
+
+   Association: SCTP connection between two endpoints.
+
+   Transport address: A combination of IP address and SCTP port number.
+
+   Upper layer: The user of the SCTP protocol, which may be an
+   adaptation layer, a session layer protocol, or the user application
+   directly.
+
+   Multihoming: Assigning more than one IP network interface to a single
+   endpoint.
+
+2 Transport protocols
+
+2.1 TCP service model
+
+   TCP is a connection-oriented (a.k.a., session-oriented) transport
+   protocol.  This means that it requires both the establishment of a
+   connection prior to the exchange of application data and a connection
+   tear-down to release system resources after the completion of data
+   transfer.
+
+   TCP is currently the most widely used connection-oriented transport
+   protocol for the Internet.
+
+
+
+
+
+
+Coene                        Informational                      [Page 2]
+
+RFC 3257              SCTP Applicability Statement            April 2002
+
+
+   TCP provides the upper layer with the following transport services:
+
+   - data reliability;
+
+   - data sequence preservation; and
+
+   - flow and congestion control.
+
+2.2 SCTP service model
+
+   SCTP is also connection-oriented and provides all the transport
+   services that TCP provides.  Many Internet applications therefore
+   should find that either TCP or SCTP will meet their transport
+   requirements.  Note, for applications conscious about processing
+   cost, there might be a difference in processing cost associated with
+   running SCTP with only a single ordered stream and one address pair
+   in comparison to running TCP.
+
+   However, SCTP has some additional capabilities that TCP lacks and
+   This can make SCTP a better choice for some applications and
+   environments:
+
+   - multi-streams support:
+
+   SCTP supports the delivery of multiple independent user message
+   streams within a single SCTP association.  This capability, when
+   properly used, can alleviate the so-called head-of-line-blocking
+   problem caused by the strict sequence delivery constraint imposed to
+   the user data by TCP.
+
+   This can be particularly useful for applications that need to
+   exchange multiple, logically separate message streams between two
+   endpoints.
+
+   - multi-homing support:
+
+   SCTP provides transparent support for communications between two
+   endpoints of which one or both is multi-homed.
+
+   SCTP provides monitoring of the reachability of the addresses on the
+   remote endpoint and in the case of failure can transparently failover
+   from the primary address to an alternate address, without upper layer
+   intervention.
+
+
+
+
+
+
+
+
+Coene                        Informational                      [Page 3]
+
+RFC 3257              SCTP Applicability Statement            April 2002
+
+
+   This capability can be used to build redundant paths between two SCTP
+   endpoints and can be particularly useful for applications that seek
+   transport-level fault tolerance.
+
+   Achieving path redundancy between two SCTP endpoints normally
+   requires that the two endpoints being equipped with multiple
+   interfaces assigned with multiple addresses and that routing is
+   configured appropriately (see Section 3).
+
+   - preservation of message boundaries:
+
+   SCTP preserves application messages boundaries.  This is useful when
+   the application data is not a continuous byte stream but comes in
+   logical chunks that the receiver handles separately.
+
+   In contrast, TCP offers a reliable data stream that has no indication
+   of what an application may consider logical chunks of the data.
+
+   - unordered reliable message delivery:
+
+   SCTP supports the transportation of user messages that have no
+   application-specified order, yet need guaranteed reliable delivery.
+
+   Applications that need to send un-ordered reliable messages or prefer
+   using their own message sequencing and ordering mechanisms may find
+   this SCTP capability useful.
+
+2.3 UDP Service model
+
+   UDP is connectionless.  This means that applications that use UDP do
+   not need to perform connection establishment or tear-down.
+
+   As transport services to its upper layer, UDP provides only:
+
+   - best-effort data delivery, and
+
+   - preservation of message boundaries.
+
+   Applications that do not require a reliable transfer of more than a
+   packet's worth of data will find UDP adequate.  Some transaction-
+   based applications fall into this category.
+
+3 SCTP Multihoming Issues
+
+   SCTP provides transport-layer support for multihoming.  Multihoming
+   has the potential of providing additional robustness against network
+   failures.  In some applications, this may be extremely important, for
+   example, in signaling transport of PSTN signaling messages [RFC2719].
+
+
+
+Coene                        Informational                      [Page 4]
+
+RFC 3257              SCTP Applicability Statement            April 2002
+
+
+   It should be noted that SCTP multihoming support only deals with
+   communication between two endpoints of which one or both is assigned
+   with multiple IP addresses on possibly multiple network interfaces.
+   It does NOT deal with communication ends that contain multiple
+   endpoints (i.e., clustered endpoints) that can switch over to an
+   alternate endpoint in case of failure of the original endpoint.
+
+   Generally, for truly fault resilient communication between two end-
+   points, the multihoming feature needs more than one IP network
+   interface for each endpoint.  The number of paths used is the minimum
+   of network interfaces used by any of the endpoints.  When an endpoint
+   selects its source address, careful consideration must be taken.  If
+   the same source address is always used, then it is possible that the
+   endpoint will be subject to the same single point of failure.  When
+   the endpoint chooses a source address, it should always select the
+   source address of the packet to correspond to the IP address of the
+   Network interface where the packet will be emitted subject to the
+   binding address constraint.  The binding address constraint is, put
+   simply, that the endpoint must never choose a source address that is
+   not part of the association i.e., the peer endpoint must recognize
+   any source address used as being part of the association.
+
+   The availability of the association will benefit greatly from having
+   multiple addresses bound to the association endpoint when the
+   endpoint is on a multi-homed host.
+
+4 SCTP Network Address Translators (NAT) issues [RFC2663]
+
+   When two endpoints are to setup an SCTP association and one (or both)
+   of them is behind a NAT (i.e., it does not have any publicly
+   available network addresses), the endpoint(s) behind the NAT should
+   consider one of the following options:
+
+   (1) When single homed sessions are to be used, no transport addresses
+   should be sent in the INIT or INIT ACK chunk(Refer to section 3.3 of
+   RFC2960 for chunk definitions).  This will force the endpoint that
+   receives this initiation message to use the source address in the IP
+   header as the only destination address for this association.  This
+   method can be used for a NAT, but any multi-homing configuration at
+   the endpoint that is behind the NAT will not be visible to its peer,
+   and thus not be taken advantage of.  See figure 1.
+
+
+
+
+
+
+
+
+
+
+Coene                        Informational                      [Page 5]
+
+RFC 3257              SCTP Applicability Statement            April 2002
+
+
+      +-------+  +---------+      *~~~~~~~~~~*           +------+
+      |Host A |  |   NAT   |     *   Cloud    *          |Host B|
+      | 10.2  +--|10.1|2.1 |----|--------------|---------+ 1.2  |
+      |       |  |    |    |     *            *          |      |
+      +-------+  +---------+      *~~~~~~~~~~*           +------+
+
+               Fig 1: SCTP through NAT without multihoming
+
+   For multihoming the NAT must have a public IP address for each
+   represented internal IP address.  The host can preconfigure an IP
+   address that the NAT can substitute, or, the NAT can have internal
+   Application Layer Gateway (ALG) which will intelligently translate
+   the IP addresses in the INIT and INIT ACK chunks.  See Figure 2.
+
+   If Network Address Port Translation is used with a multihomed SCTP
+   endpoint, then any port translation must be applied on a per-
+   association basis such that an SCTP endpoint continues to receive the
+   same port number for all messages within a given association.
+
+      +-------+   +----------+      *~~~~~~~~~~*           +------+
+      |Host A |   |    NAT   |     *   Cloud    *          |Host B|
+      | 10.2  +---+ 10.1|5.2 +-----+ 1.1<+->3.1--+---------+ 1.2  |
+      | 11.2  +---+ 11.1|6.2 |     |     +->4.2--+---------+ 2.2  |
+      |       |   |          |      *           *          |      |
+      +-------+   +----------+       *~~~~~~~~~*           +------+
+
+                Fig 2: SCTP through NAT with multihoming
+
+   (2) Another alternative is to use the hostname feature and DNS to
+   resolve the addresses.  The hostname is included in the INIT of the
+   association or in the INIT ACK.  The hostname must be resolved by DNS
+   before the association is completely set up.  There are special
+   issues regarding NAT and DNS, refer to RFC2694 for details.
+
+5 Security Considerations
+
+   In this section, some relevant security issues found in the
+   deployment of the connection-oriented transport protocols will be
+   discussed.
+
+5.1 Security issues with TCP
+
+   Some TCP implementations have been known to be vulnerable to blind
+   denial of service attacks, i.e., attacks that had been executed by an
+   attacker that could not see most of the traffic to or from the target
+   host.
+
+
+
+
+
+Coene                        Informational                      [Page 6]
+
+RFC 3257              SCTP Applicability Statement            April 2002
+
+
+   The attacker would send a large number of connection establishment
+   requests (TCP-SYN packets) to the attacked target, possibly from
+   faked IP source addresses.  The attacked host would reply by sending
+   SYN-ACK packets and entering SYN-received state, thereby allocating
+   space for a TCB.  At some point the SYN-queue would fill up, (i.e.,
+   the number of connections waiting to be established would rise to a
+   limit) and the host under attack would have to start turning down new
+   connection establishment requests.
+
+   TCP implementations with SYN-cookies algorithm [SYN-COOK] reduce the
+   risk of such blind denial of service attacks.  TCP implementations
+   can switch to using this algorithm in times when their SYN-queues are
+   filled up while still fully conforming to the TCP specification
+   [RFC793].  However, use of options such as a window scale [RFC1323],
+   is not possible, then.  With the SYN-cookie mechanism, a TCB is only
+   created when the client sends back a valid ACK packet to the server,
+   and the 3-way handshake has thus been successfully completed.
+
+   Blind connection forgery is another potential threat to TCP.  By
+   guessing valid sequence numbers, an attacker would be able to forge a
+   connection.  However, with a secure hashsum algorithm, for some of
+   the current SYN-cookie implementations the likelihood of achieving
+   this attack is on the order of magnitude of 1 in 2^24, i.e., the
+   attacker would have to send 2^24 packets before obtaining one forged
+   connection when SYN-cookies are used.
+
+5.2 Security issues with SCTP
+
+   SCTP has been designed with the experiences made with TCP in mind.
+   To make it hard for blind attackers (i.e., attackers that are not
+   man-in-the-middle) to inject forged SCTP datagrams into existing
+   associations, each side of an SCTP association uses a 32 bit value
+   called "Verification Tag" to ensure that a datagram really belongs to
+   the existing association.  So in addition to a combination of source
+   and destination transport addresses that belong to an established
+   association, a valid SCTP datagram must also have the correct tag to
+   be accepted by the recipient.
+
+   Unlike in TCP, usage of cookie in association establishment is made
+   mandatory in SCTP.  For the server, a new association is fully
+   established after three messages (containing INIT, INIT-ACK, COOKIE-
+   ECHO chunks) have been exchanged.  The cookie is a variable length
+   parameter that contains all relevant data to initialize the TCB on
+   the server side, plus a HMAC used to secure it.  This HMAC (MD5 as
+   per [RFC1321] or SHA-1 [SHA1]) is computed over the cookie and a
+   secret, server-owned key.
+
+
+
+
+
+Coene                        Informational                      [Page 7]
+
+RFC 3257              SCTP Applicability Statement            April 2002
+
+
+   As specifically prescribed for SCTP implementations [RFC2960],
+   additional resources for new associations may only be reserved in
+   case a valid COOKIE-ECHO chunk is received by a client, and the
+   computed HMAC for this new cookie matches that contained in the
+   cookie.
+
+   With SCTP the chances of an attacker being able to blindly forge a
+   connection are even lower than in the case of TCP using SYN-cookies,
+   since the attacker would have to guess a correct value for the HMAC
+   contained in the cookie, i.e., lower than 1 in 2^128 which for all
+   practical purposes is negligible.
+
+   It should be noted that SCTP only tries to increase the availability
+   of a network.  SCTP does not contain any protocol mechanisms that are
+   directly related to user message authentication, integrity and
+   confidentiality functions.  For such features, it depends on the
+   IPsec protocols and architecture and/or on security features of the
+   application protocols.
+
+   Transport Layer security(TLS)[RFC2246] using SCTP must always use
+   in-order streams.
+
+   Currently the IPSEC working group is investigating the support of
+   multi-homing by IPSEC protocols.  At the present time to use IPSEC,
+   one must use 2 * N * M security associations if one endpoint uses N
+   addresses and the other M addresses.
+
+5.3 Security Issues with both TCP and SCTP
+
+   It is important to note that neither TCP nor SCTP protect itself from
+   man-in-the-middle attacks where an established session might be
+   hijacked (assuming the attacker can see the traffic from and inject
+   its own packets to either endpoints).
+
+   Also, to prevent blind connection/session setup forgery, both TCP
+   implementations supporting SYN-cookies and SCTP implementations rely
+   on a server-known, secret key to protect the HMAC data.  It must be
+   ensured that this key is created subject to the recommendations
+   mentioned in [RFC1750].
+
+   Although SCTP has been designed carefully as to avoid some of the
+   problems that have appeared with TCP, it has as of yet not been
+   widely deployed.  It is therefore possible that new security issues
+   will be identified that will have to be addressed in further
+   revisions of [RFC2960].
+
+
+
+
+
+
+Coene                        Informational                      [Page 8]
+
+RFC 3257              SCTP Applicability Statement            April 2002
+
+
+6 References and related work
+
+   [RFC2960]   Stewart, R., Xie, Q., Morneault, K., Sharp, C.,
+               Schwarzbauer, H., Taylor, T., Rytina, I., Kalla, M.,
+               Zhang, L. and V. Paxson, "Stream Control Transmission
+               Protocol", RFC 2960, October 2000.
+
+   [RFC2401]   Kent, S. and R. Atkinson, "Security Architecture for the
+               Internet Protocol", RFC 2401, November 1998.
+
+   [RFC2663]   Srisuresh, P. and M. Holdrege, "IP Network Address
+               Translator (NAT) Terminology and Considerations", RFC
+               2663, August 1999.
+
+   [RFC2694]   Srisuresh, P., Tsirtsis, G., Akkiraju, P. and A.
+               Heffernan, "DNS extensions to Network Address Translators
+               (DNS_ALG)", RFC 2694, September 1999.
+
+   [RFC768]    Postel, J., "User Datagram Protocol", STD 6, RFC 768,
+               August 1980.
+
+   [RFC793]    Postel, J., "Transmission Control Protocol", STD 7, RFC
+               793, September 1981.
+
+   [RFC2719]   Ong, L., Rytina, I., Garcia, M., Schwarzbauer, H., Coene,
+               L., Lin, H., Juhasz, I., Holdrege, M. and C. Sharp,
+               "Architectural Framework for Signaling Transport", RFC
+               2719, October 1999.
+
+   [RFC1321]   Rivest, R., "The MD5 Message-Digest Algorithm", RFC 1321,
+               April 1992.
+
+   [RFC1323]   Jacobson, V., Braden, R. and D. Borman, "TCP Extensions
+               for High Performance", RFC 1323, May 1992.
+
+   [RFC1750]   Eastlake, D., Crocker, S. and J. Schiller, "Randomness
+               Recommendations for Security", RFC 1750, December 1994.
+
+   [SHA1]      NIST FIPS PUB 180-1, "Secure Hash Standard," National
+               Institute of Standards and Technology, U.S. Department of
+               Commerce, April 1995.
+
+   [SYNCOOK]   Dan J. Bernstein, SYN cookies, 1997, see also
+               <http://cr.yp.to/syncookies.html>
+
+   [RFC2246]   Dierks, T. and C. Allen, "The TLS Protocol Version 1.0",
+               RFC 2246, January 1999.
+
+
+
+
+Coene                        Informational                      [Page 9]
+
+RFC 3257              SCTP Applicability Statement            April 2002
+
+
+   [RFC1889]   Schulzrinne, H., Casner, S., Frederick, R. and V.
+               Jacobson, "RTP: A Transport Protocol for Real-Time
+               Applications", RFC 1889, January 1996.
+
+7 Acknowledgments
+
+   This document was initially developed by a design team consisting of
+   Lode Coene, John Loughney, Michel Tuexen, Randall R. Stewart,
+   Qiaobing Xie, Matt Holdrege, Maria-Carmen Belinchon, Andreas
+   Jungmaier, Gery Verwimp and Lyndon Ong.
+
+   The authors wish to thank Renee Revis, I. Rytina, H.J. Schwarzbauer,
+   J.P. Martin-Flatin, T. Taylor, G. Sidebottom, K. Morneault, T.
+   George, M. Stillman, N. Makinae, S. Bradner, A. Mankin, G. Camarillo,
+   H. Schulzrinne, R. Kantola, J. Rosenberg, R.J. Atkinson, and many
+   others for their invaluable comments.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Coene                        Informational                     [Page 10]
+
+RFC 3257              SCTP Applicability Statement            April 2002
+
+
+Appendix A: Major functions provided by SCTP
+
+   - Reliable Data Transfer
+
+   - Multiple streams to help avoid head-of-line blocking
+
+   - Ordered and unordered data delivery on a per-stream basis
+
+   - Bundling and fragmentation of user data
+
+   - TCP friendly Congestion and flow control
+
+   - Support continuous monitoring of reachability
+
+   - Graceful termination of association
+
+   - Support of multi-homing for added reliability
+
+   - Some protection against blind denial-of-service attacks
+
+   - Some protection against blind masquerade attacks
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Coene                        Informational                     [Page 11]
+
+RFC 3257              SCTP Applicability Statement            April 2002
+
+
+8  Editor's Address
+
+   Lode Coene
+   Siemens Atea
+   Atealaan 34
+   B-2200 Herentals
+   Belgium
+
+   Phone: +32-14-252081
+   EMail: lode.coene@siemens.atea.be
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Coene                        Informational                     [Page 12]
+
+RFC 3257              SCTP Applicability Statement            April 2002
+
+
+9.  Full Copyright Statement
+
+   Copyright (C) The Internet Society (2002).  All Rights Reserved.
+
+   This document and translations of it may be copied and furnished to
+   others, and derivative works that comment on or otherwise explain it
+   or assist in its implementation may be prepared, copied, published
+   and distributed, in whole or in part, without restriction of any
+   kind, provided that the above copyright notice and this paragraph are
+   included on all such copies and derivative works.  However, this
+   document itself may not be modified in any way, such as by removing
+   the copyright notice or references to the Internet Society or other
+   Internet organizations, except as needed for the purpose of
+   developing Internet standards in which case the procedures for
+   copyrights defined in the Internet Standards process must be
+   followed, or as required to translate it into languages other than
+   English.
+
+   The limited permissions granted above are perpetual and will not be
+   revoked by the Internet Society or its successors or assigns.
+
+   This document and the information contained herein is provided on an
+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+   Funding for the RFC Editor function is currently provided by the
+   Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Coene                        Informational                     [Page 13]
+
diff --git a/doc/rfc3286.txt b/doc/rfc3286.txt
new file mode 100644
index 0000000..aa446a4
--- /dev/null
+++ b/doc/rfc3286.txt
@@ -0,0 +1,563 @@
+
+
+
+
+
+
+Network Working Group                                             L. Ong
+Request for Comments: 3286                             Ciena Corporation
+Category: Informational                                        J. Yoakum
+                                                         Nortel Networks
+                                                                May 2002
+
+
+   An Introduction to the Stream Control Transmission Protocol (SCTP)
+
+Status of this Memo
+
+   This memo provides information for the Internet community.  It does
+   not specify an Internet standard of any kind.  Distribution of this
+   memo is unlimited.
+
+Copyright Notice
+
+   Copyright (C) The Internet Society (2002).  All Rights Reserved.
+
+Abstract
+
+   This document provides a high level introduction to the capabilities
+   supported by the Stream Control Transmission Protocol (SCTP).  It is
+   intended as a guide for potential users of SCTP as a general purpose
+   transport protocol.
+
+1. Introduction
+
+   The Stream Control Transmission Protocol (SCTP) is a new IP transport
+   protocol, existing at an equivalent level with UDP (User Datagram
+   Protocol) and TCP (Transmission Control Protocol), which provide
+   transport layer functions to many Internet applications.  SCTP has
+   been approved by the IETF as a Proposed Standard [1].  The error
+   check algorithm has since been modified [2].  Future changes and
+   updates will be reflected in the IETF RFC index.
+
+   Like TCP, SCTP provides a reliable transport service, ensuring that
+   data is transported across the network without error and in sequence.
+   Like TCP, SCTP is a session-oriented mechanism, meaning that a
+   relationship is created between the endpoints of an SCTP association
+   prior to data being transmitted, and this relationship is maintained
+   until all data transmission has been successfully completed.
+
+   Unlike TCP, SCTP provides a number of functions that are critical for
+   telephony signaling transport, and at the same time can potentially
+   benefit other applications needing transport with additional
+   performance and reliability.  The original framework for the SCTP
+   definition is described in [3].
+
+
+
+Ong & Yoakum                 Informational                      [Page 1]
+
+RFC 3286                     SCTP Overview                      May 2002
+
+
+2. Basic SCTP Features
+
+   SCTP is a unicast protocol, and supports data exchange between
+   exactly 2 endpoints, although these may be represented by multiple IP
+   addresses.
+
+   SCTP provides reliable transmission, detecting when data is
+   discarded, reordered, duplicated or corrupted, and retransmitting
+   damaged data as necessary.  SCTP transmission is full duplex.
+
+   SCTP is message oriented and supports framing of individual message
+   boundaries.  In comparison, TCP is byte oriented and does not
+   preserve any implicit structure within a transmitted byte stream
+   without enhancement.
+
+   SCTP is rate adaptive similar to TCP, and will scale back data
+   transfer to the prevailing load conditions in the network.  It is
+   designed to behave cooperatively with TCP sessions attempting to use
+   the same bandwidth.
+
+3. SCTP Multi-Streaming Feature
+
+   The name Stream Control Transmission Protocol is derived from the
+   multi-streaming function provided by SCTP.  This feature allows data
+   to be partitioned into multiple streams that have the property of
+   independently sequenced delivery, so that message loss in any one
+   stream will only initially affect delivery within that stream, and
+   not delivery in other streams.
+
+   In contrast, TCP assumes a single stream of data and ensures that
+   delivery of that stream takes place with byte sequence preservation.
+   While this is desirable for delivery of a file or record, it causes
+   additional delay when message loss or sequence error occurs within
+   the network.  When this happens, TCP must delay delivery of data
+   until the correct sequencing is restored, either by receipt of an
+   out-of-sequence message, or by retransmission of a lost message.
+
+   For a number of applications, the characteristic of strict sequence
+   preservation is not truly necessary.  In telephony signaling, it is
+   only necessary to maintain sequencing of messages that affect the
+   same resource (e.g., the same call, or the same channel).  Other
+   messages are only loosely correlated and can be delivered without
+   having to maintain overall sequence integrity.
+
+   Another example of possible use of multi-streaming is the delivery of
+   multimedia documents, such as a web page, when done over a single
+   session.  Since multimedia documents consist of objects of different
+   sizes and types, multi-streaming allows transport of these components
+
+
+
+Ong & Yoakum                 Informational                      [Page 2]
+
+RFC 3286                     SCTP Overview                      May 2002
+
+
+   to be partially ordered rather than strictly ordered, and may result
+   in improved user perception of transport.
+
+   At the same time, transport is done within a single SCTP association,
+   so that all streams are subjected to a common flow and congestion
+   control mechanism, reducing the overhead required at the transport
+   level.
+
+   SCTP accomplishes multi-streaming by creating independence between
+   data transmission and data delivery.  In particular, each payload
+   DATA "chunk" in the protocol uses two sets of sequence numbers, a
+   Transmission Sequence Number that governs the transmission of
+   messages and the detection of message loss, and the Stream ID/Stream
+   Sequence Number pair, which is used to determine the sequence of
+   delivery of received data.
+
+   This independence of mechanisms allows the receiver to determine
+   immediately when a gap in the transmission sequence occurs (e.g., due
+   to message loss), and also whether or not messages received following
+   the gap are within an affected stream.  If a message is received
+   within the affected stream, there will be a corresponding gap in the
+   Stream Sequence Number, while messages from other streams will not
+   show a gap.  The receiver can therefore continue to deliver messages
+   to the unaffected streams while buffering messages in the affected
+   stream until retransmission occurs.
+
+4. SCTP Multi-Homing Feature
+
+   Another core feature of SCTP is multi-homing, or the ability for a
+   single SCTP endpoint to support multiple IP addresses.  The benefit
+   of multi-homing is potentially greater survivability of the session
+   in the presence of network failures.  In a conventional single-homed
+   session, the failure of a local LAN access can isolate the end
+   system, while failures within the core network can cause temporary
+   unavailability of transport until the IP routing protocols can
+   reconverge around the point of failure.  Using multi-homed SCTP,
+   redundant LANs can be used to reinforce the local access, while
+   various options are possible in the core network to reduce the
+   dependency of failures for different addresses.  Use of addresses
+   with different prefixes can force routing to go through different
+   carriers, for example, route-pinning techniques or even redundant
+   core networks can also be used if there is control over the network
+   architecture and protocols.
+
+   In its current form, SCTP does not do load sharing, that is, multi-
+   homing is used for redundancy purposes only.  A single address is
+   chosen as the "primary" address and is used as the destination for
+   all DATA chunks for normal transmission.  Retransmitted DATA chunks
+
+
+
+Ong & Yoakum                 Informational                      [Page 3]
+
+RFC 3286                     SCTP Overview                      May 2002
+
+
+   use the alternate address(es) to improve the probability of reaching
+   the remote endpoint, while continued failure to send to the primary
+   address ultimately results in the decision to transmit all DATA
+   chunks to the alternate until heartbeats can reestablish the
+   reachability of the primary.
+
+   To support multi-homing, SCTP endpoints exchange lists of addresses
+   during initiation of the association.  Each endpoint must be able to
+   receive messages from any of the addresses associated with the remote
+   endpoint; in practice, certain operating systems may utilize
+   available source addresses in round robin fashion, in which case
+   receipt of messages from different source addresses will be the
+   normal case.  A single port number is used across the entire address
+   list at an endpoint for a specific session.
+
+   In order to reduce the potential for security issues, it is required
+   that some response messages be sent specifically to the source
+   address in the message that caused the response.  For example, when
+   the server receives an INIT chunk from a client to initiate an SCTP
+   association, the server always sends the response INIT ACK chunk to
+   the source address that was in the IP header of the INIT.
+
+5. Features of the SCTP Initiation Procedure
+
+   The SCTP Initiation Procedure relies on a 4-message sequence, where
+   DATA can be included on the 3rd and 4th messages of the sequence, as
+   these messages are sent when the association has already been
+   validated.  A "cookie" mechanism has been incorporated into the
+   sequence to guard against some types of denial of service attacks.
+
+5.1 Cookie Mechanism
+
+   The "cookie" mechanism guards specifically against a blind attacker
+   generating INIT chunks to try to overload the resources of an SCTP
+   server by causing it to use up memory and resources handling new INIT
+   requests.  Rather than allocating memory for a Transmission Control
+   Block (TCB), the server instead creates a Cookie parameter with the
+   TCB information, together with a valid lifetime and a signature for
+   authentication, and sends this back in the INIT ACK.  Since the INIT
+   ACK always goes back to the source address of the INIT, the blind
+   attacker will not get the Cookie.  A valid SCTP client will get the
+   Cookie and return it in the COOKIE ECHO chunk, where the SCTP server
+   can validate the Cookie and use it to rebuild the TCB.  Since the
+   server creates the Cookie, only it needs to know the format and
+   secret key, this is not exchanged with the client.
+
+
+
+
+
+
+Ong & Yoakum                 Informational                      [Page 4]
+
+RFC 3286                     SCTP Overview                      May 2002
+
+
+   Otherwise, the SCTP Initiation Procedure follows many TCP
+   conventions, so that the endpoints exchange receiver windows, initial
+   sequence numbers, etc.  In addition to this, the endpoints may
+   exchange address lists as discussed above, and also mutually confirm
+   the number of streams to be opened on each side.
+
+5.2 INIT Collision Resolution
+
+   Multi-homing adds to the potential that messages will be received out
+   of sequence or with different address pairs.  This is a particular
+   concern during initiation of the association, where without
+   procedures for resolving the collision of messages, you may easily
+   end up with multiple parallel associations between the same
+   endpoints.  To avoid this, SCTP incorporates a number of procedures
+   to resolve parallel initiation attempts into a single association.
+
+6. SCTP DATA Exchange Features
+
+   DATA chunk exchange in SCTP follows TCP's Selective ACK procedure.
+   Receipt of DATA chunks is acknowledged by sending SACK chunks, which
+   indicate not only the cumulative Transmission Sequence Number (TSN)
+   range received, but also any non-cumulative TSNs, implying gaps in
+   the received TSN sequence.  Following TCP procedures, SACKs are sent
+   using the "delayed ack" method, normally one SACK per every other
+   received packet, but with an upper limit on the delay between SACKs
+   and an increase to once per received packet when there are gaps
+   detected.
+
+   Flow and Congestion Control follow TCP algorithms.  The advertised
+   receive window indicates buffer occupancy at the receiver, while a
+   per-path congestion window is maintained to manage the packets in
+   flight.  Slow start, Congestion avoidance, Fast recovery and Fast
+   retransmit are incorporated into the procedures as described in RFC
+   2581, with the one change being that the endpoints must manage the
+   conversion between bytes sent and received and TSNs sent and
+   received, since TSN is per chunk rather than per byte.
+
+   The application can specify a lifetime for data to be transmitted, so
+   that if the lifetime has expired and the data has not yet been
+   transmitted, it can be discarded (e.g., time-sensitive signaling
+   messages).  If the data has been transmitted, it must continue to be
+   delivered to avoid creating a hole in the TSN sequence.
+
+
+
+
+
+
+
+
+
+Ong & Yoakum                 Informational                      [Page 5]
+
+RFC 3286                     SCTP Overview                      May 2002
+
+
+7. SCTP Shutdown Features
+
+   SCTP Shutdown uses a 3-message procedure to allow graceful shutdown,
+   where each endpoint has confirmation of the DATA chunks received by
+   the remote endpoint prior to completion of the shutdown.  An Abort
+   procedure is also provided for error cases when an immediate shutdown
+   must take place.
+
+   Note that SCTP does not support the function of a "half-open"
+   connection as can occur in TCP, when one side indicates that it has
+   no more data to send, but the other side can continue to send data
+   indefinitely.  SCTP assumes that once the shutdown procedure begins,
+   both sides will stop sending new data across the association, and
+   only need to clear up acknowledgements of previously sent data.
+
+8. SCTP Message Format
+
+   The SCTP Message includes a common header plus one or more chunks,
+   which can be control or data.  The common header has source and
+   destination port numbers to allow multiplexing of different SCTP
+   associations at the same address, a 32-bit verification tag that
+   guards against insertion of an out-of-date or false message into the
+   SCTP association, and a 32-bit checksum (this has been modified to
+   use the CRC-32c polynomial [2]) for error detection.
+
+   Each chunk includes chunk type, flag field, length and value.
+   Control chunks incorporate different flags and parameters depending
+   on the chunk type.  DATA chunks in particular incorporate flags for
+   control of segmentation and reassembly, and parameters for the TSN,
+   Stream ID and Stream Sequence Number, and a Payload Protocol
+   Identifier.
+
+   The Payload Protocol ID has been included for future flexibility.  It
+   is envisioned that the functions of protocol identification and port
+   number multiplexing will not be as closely linked in the future as
+   they are in current usage.  Payload Protocol ID will allow the
+   protocol being carried by SCTP to be identified independent of the
+   port numbers being used.
+
+   The SCTP message format naturally allows support of bundling of
+   multiple DATA and control chunks in a single message, to improve
+   transport efficiency.  Use of bundling is controllable by the
+   application, so that bundling of initial transmission can be
+   prohibited.  Bundling will naturally occur on retransmission of DATA
+   chunks, to further reduce any chance of congestion.
+
+
+
+
+
+
+Ong & Yoakum                 Informational                      [Page 6]
+
+RFC 3286                     SCTP Overview                      May 2002
+
+
+9. Error Handling
+
+9.1 Retransmission
+
+   Retransmission of DATA chunks occurs from either (a) timeout of the
+   retransmission timer; or (b) receipt of SACKs indicating the DATA
+   chunk has not been received.  To reduce the potential for congestion,
+   the rate of retransmission of DATA chunks is limited.  The
+   retransmission timeout (RTO) is adjusted based on estimates of the
+   round trip delay and backs off exponentially as message loss
+   increases.
+
+   In an active association with fairly constant DATA transmission,
+   SACKs are more likely to cause retransmission than the timeout.  To
+   reduce the chance of an unnecessary retransmission, a 4 SACK rule is
+   used, so that retransmission only occurs on receipt of the 4th SACK
+   that indicates that the chunk is missing.  This is intended to avoid
+   retransmits due to normal occurrences such as packets received out of
+   sequence.
+
+9.2 Path Failure
+
+   A count is maintained of the number of retransmissions to a
+   particular destination address without successful acknowledgement.
+   When this count exceeds a configured maximum, the address is declared
+   inactive, notification is given to the application, and the SCTP
+   begins to use an alternate address for the sending of DATA chunks.
+
+   Also, Heartbeat chunks are sent periodically to all idle destinations
+   (i.e., alternate addresses), and a counter is maintained on the
+   number of Heartbeats sent to an inactive destination without receipt
+   of a corresponding Heartbeat Ack.  When this counter exceeds a
+   configured maximum, that destination address is also declared
+   inactive.
+
+   Heartbeats continue to be sent to inactive destination addresses
+   until an Ack is received, at which point the address can be made
+   active again.  The rate of sending Heartbeats is tied to the RTO
+   estimation plus an additional delay parameter that allows Heartbeat
+   traffic to be tailored according to the needs of the user
+   application.
+
+9.3 Endpoint Failure
+
+   A count is maintained across all destination addresses on the number
+   of retransmits or Heartbeats sent to the remote endpoint without a
+   successful Ack.  When this exceeds a configured maximum, the endpoint
+   is declared unreachable, and the SCTP association is closed.
+
+
+
+Ong & Yoakum                 Informational                      [Page 7]
+
+RFC 3286                     SCTP Overview                      May 2002
+
+
+10. API
+
+   The specification includes a model of the primitives exchanged
+   between the application and the SCTP layer, intended as informational
+   material rather than a formal API statement.  A socket-based API is
+   being defined to simplify migration of TCP or UDP applications to the
+   use of SCTP.
+
+11. Security Considerations
+
+   In addition to the verification tag and cookie mechanisms, SCTP
+   specifies the use of IPSec if strong security and integrity
+   protection is required.  The SCTP specification does not itself
+   define any new security protocols or procedures.
+
+   Extensions to IPSec are under discussion to reduce the overhead
+   required to support multi-homing.  Also, work is in progress on the
+   use of Transport Layer Security (TLS) over SCTP [4].
+
+12. Extensions
+
+   The SCTP format allows new chunk types, flags and parameter fields to
+   be defined as extensions to the protocol.  Any extensions must be
+   based on standard agreements within the IETF, as no vendor-specific
+   extensions are supported in the protocol.
+
+   Chunk Type values are organized into four ranges to allow extensions
+   to be made with a pre-defined procedure for responding if a new Chunk
+   Type is not recognized at the remote endpoint.  Responses include:
+   whole packet discard; packet discard with reporting; ignoring the
+   chunk; ignoring with reporting.  Similar pre-defined responses are
+   specified for unrecognized Parameter Type values.
+
+   Chunk Parameter Type values are in principle independent ranges for
+   each Chunk Type.  In practice, the values defined in the SCTP
+   specification have been coordinated so that a particular parameter
+   type will have the same Chunk Parameter Type value across all Chunk
+   Types.  Further experience will determine if this alignment needs to
+   be maintained or formalized.
+
+
+
+
+
+
+
+
+
+
+
+
+Ong & Yoakum                 Informational                      [Page 8]
+
+RFC 3286                     SCTP Overview                      May 2002
+
+
+13. Informative References
+
+   [1] Stewart, R., Xie, Q., Morneault, K., Sharp, C., Schwarzbauer, H.,
+       Taylor, T., Rytina, I., Kalla, M., Zhang, L. and V. Paxson,
+       "Stream Control Transmission Protocol", RFC 2960, October 2000.
+
+   [2] Stewart, Sharp, et. al., "SCTP Checksum Change", Work in
+       Progress.
+
+   [3] Ong, L., Rytina, I., Garcia, M., Schwarzbauer, H., Coene, L.,
+       Lin, H., Juhasz, I., Holdrege, M. and C. Sharp, "Framework
+       Architecture for Signaling Transport", RFC 2719, October 1999.
+
+   [4] Jungmeier, Rescorla and Tuexen, "TLS Over SCTP", Work in
+       Progress.
+
+14. Authors' Addresses
+
+   Lyndon Ong
+   Ciena Corporation
+   10480 Ridgeview Drive
+   Cupertino, CA 95014
+
+   EMail: lyong@ciena.com
+
+
+   John Yoakum
+   Emerging Opportunities
+   Nortel Networks
+
+   EMail: yoakum@nortelnetworks.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Ong & Yoakum                 Informational                      [Page 9]
+
+RFC 3286                     SCTP Overview                      May 2002
+
+
+15.  Full Copyright Statement
+
+   Copyright (C) The Internet Society (2002).  All Rights Reserved.
+
+   This document and translations of it may be copied and furnished to
+   others, and derivative works that comment on or otherwise explain it
+   or assist in its implementation may be prepared, copied, published
+   and distributed, in whole or in part, without restriction of any
+   kind, provided that the above copyright notice and this paragraph are
+   included on all such copies and derivative works.  However, this
+   document itself may not be modified in any way, such as by removing
+   the copyright notice or references to the Internet Society or other
+   Internet organizations, except as needed for the purpose of
+   developing Internet standards in which case the procedures for
+   copyrights defined in the Internet Standards process must be
+   followed, or as required to translate it into languages other than
+   English.
+
+   The limited permissions granted above are perpetual and will not be
+   revoked by the Internet Society or its successors or assigns.
+
+   This document and the information contained herein is provided on an
+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+   Funding for the RFC Editor function is currently provided by the
+   Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Ong & Yoakum                 Informational                     [Page 10]
+
diff --git a/doc/rfc3309.txt b/doc/rfc3309.txt
new file mode 100644
index 0000000..494fee1
--- /dev/null
+++ b/doc/rfc3309.txt
@@ -0,0 +1,955 @@
+
+
+
+
+
+
+Network Working Group                                           J. Stone
+Request for Comments: 3309                                      Stanford
+Updates: 2960                                                 R. Stewart
+Category: Standards                                        Cisco Systems
+                                                                 D. Otis
+                                                                SANlight
+                                                          September 2002
+
+
+      Stream Control Transmission Protocol (SCTP) Checksum Change
+
+Status of this Memo
+
+   This document specifies an Internet standards track protocol for the
+   Internet community, and requests discussion and suggestions for
+   improvements.  Please refer to the current edition of the "Internet
+   Official Protocol Standards" (STD 1) for the standardization state
+   and status of this protocol.  Distribution of this memo is unlimited.
+
+Copyright Notice
+
+   Copyright (C) The Internet Society (2002).  All Rights Reserved.
+
+Abstract
+
+   Stream Control Transmission Protocol (SCTP) currently uses an Adler-
+   32 checksum.  For small packets Adler-32 provides weak detection of
+   errors.  This document changes that checksum and updates SCTP to use
+   a 32 bit CRC checksum.
+
+Table of Contents
+
+   1 Introduction ...................................................  2
+   2 Checksum Procedures ............................................  3
+   3 Security Considerations.........................................  6
+   4 IANA Considerations.............................................  6
+   5 Acknowledgments ................................................  6
+   6 References .....................................................  7
+   Appendix .........................................................  9
+   Authors' Addresses ............................................... 16
+   Full Copyright Statement ......................................... 17
+
+
+
+
+
+
+
+
+
+
+Stone, et. al.              Standards Track                     [Page 1]
+
+RFC 3309                  SCTP Checksum Change            September 2002
+
+
+1 Introduction
+
+   A fundamental weakness has been detected in SCTP's current Adler-32
+   checksum algorithm [STONE].  This document updates and replaces the
+   Adler-32 checksum definition in [RFC 2960].  Note that there is no
+   graceful transition mechanism for migrating to the new checksum.
+   Implementations are expected to immediately switch to the new
+   algorithm; use of the old algorithm is deprecated.
+
+   One requirement of an effective checksum is that it evenly and
+   smoothly spreads its input packets over the available check bits.
+
+   From an email from Jonathan Stone, who analyzed the Adler-32 as part
+   of his doctoral thesis:
+
+   "Briefly, the problem is that, for very short packets, Adler32 is
+   guaranteed to give poor coverage of the available bits.  Don't take
+   my word for it, ask Mark Adler.  :-)
+
+   Adler-32 uses two 16-bit counters, s1 and s2.  s1 is the sum of the
+   input, taken as 8-bit bytes.  s2 is a running sum of each value of
+   s1.  Both s1 and s2 are computed mod-65521 (the largest prime less
+   than 2^16).  Consider a packet of 128 bytes.  The *most* that each
+   byte can be is 255.  There are only 128 bytes of input, so the
+   greatest value which the s1 accumulator can have is 255 * 128 =
+   32640.  So, for 128-byte packets, s1 never wraps.  That is critical.
+   Why?
+
+   The key is to consider the distribution of the s1 values, over some
+   distribution of the values of the individual input bytes in each
+   packet.  Because s1 never wraps, s1 is simply the sum of the
+   individual input bytes.  (Even Doug's trick of adding 0x5555 doesn't
+   help here, and an even larger value doesn't really help: we can get
+   at most one mod-65521 reduction.)
+
+   Given the further assumption that the input bytes are drawn
+   independently from some distribution (they probably aren't: for file
+   system data, it's even worse than that!), the Central Limit Theorem
+   tells us that that s1 will tend to have a normal distribution.
+   That's bad: it tells us that the value of s1 will have hot-spots at
+   around 128 times the mean of the input distribution: around 16k,
+   assuming a uniform distribution.  That's bad.  We want the
+   accumulator to wrap as many times as possible, so that the resulting
+   sum has as close to a uniform distribution as possible.  (I call this
+   "fairness".)
+
+
+
+
+
+
+Stone, et. al.              Standards Track                     [Page 2]
+
+RFC 3309                  SCTP Checksum Change            September 2002
+
+
+   So, for short packets, the Adler-32 s1 sum is guaranteed to be
+   unfair.  Why is that bad?  It's bad because the space of valid
+   packets -- input data, plus checksum values -- is also small.  If all
+   packets have checksum values very close to 32640, then the likelihood
+   of even a 'small' error leaving a damaged packet with a valid
+   checksum is higher than if all checksum values are equally likely."
+
+   Due to this inherent weakness, exacerbated by the fact that SCTP will
+   first be used as a signaling transport protocol where signaling
+   messages are usually less than 128 bytes, a new checksum algorithm is
+   specified by this document, replacing the current Adler-32 algorithm
+   with CRC-32c.
+
+1.1 Conventions
+
+   The keywords MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT,
+   SHOULD,SHOULD NOT, RECOMMENDED, NOT RECOMMENDED, MAY, and OPTIONAL,
+   when they appear in this document, are to be interpreted as described
+   in [RFC2119].
+
+   Bit number order is defined in [RFC1700].
+
+2 Checksum Procedures
+
+   The procedures described in section 2.1 of this document MUST be
+   followed, replacing the current checksum defined in [RFC2960].
+
+   Furthermore any references within [RFC2960] to Adler-32 MUST be
+   treated as a reference to CRC-32c.  Section 2.1 of this document
+   describes the new calculation and verification procedures that MUST
+   be followed.
+
+2.1 Checksum Calculation
+
+   When sending an SCTP packet, the endpoint MUST strengthen the data
+   integrity of the transmission by including the CRC-32c checksum value
+   calculated on the packet, as described below.
+
+   After the packet is constructed (containing the SCTP common header
+   and one or more control or DATA chunks), the transmitter shall:
+
+   1) Fill in the proper Verification Tag in the SCTP common header and
+      initialize the Checksum field to 0's.
+
+   2) Calculate the CRC-32c of the whole packet, including the SCTP
+      common header and all the chunks.
+
+
+
+
+
+Stone, et. al.              Standards Track                     [Page 3]
+
+RFC 3309                  SCTP Checksum Change            September 2002
+
+
+   3) Put the resulting value into the Checksum field in the common
+      header, and leave the rest of the bits unchanged.
+
+   When an SCTP packet is received, the receiver MUST first check the
+   CRC-32c checksum:
+
+   1) Store the received CRC-32c value,
+
+   2) Replace the 32 bits of the Checksum field in the received SCTP
+      packet with all '0's and calculate a CRC-32c value of the whole
+      received packet.  And,
+
+   3) Verify that the calculated CRC-32c value is the same as the
+      received CRC-32c value.  If not, the receiver MUST treat the
+      packet as an invalid SCTP packet.
+
+   The default procedure for handling invalid SCTP packets is to
+   silently discard them.
+
+   Any hardware implementation SHOULD be done in a way that is
+   verifiable by the software.
+
+   We define a 'reflected value' as one that is the opposite of the
+   normal bit order of the machine.  The 32 bit CRC is calculated as
+   described for CRC-32c and uses the polynomial code 0x11EDC6F41
+   (Castagnoli93) or x^32+x^28+x^27+x^26+x^25
+   +x^23+x^22+x^20+x^19+x^18+x^14+x^13+x^11+x^10+x^9+x^8+x^6+x^0.  The
+   CRC is computed using a procedure similar to ETHERNET CRC [ITU32],
+   modified to reflect transport level usage.
+
+   CRC computation uses polynomial division.  A message bit-string M is
+   transformed to a polynomial, M(X), and the CRC is calculated from
+   M(X) using polynomial arithmetic [Peterson 72].
+
+   When CRCs are used at the link layer, the polynomial is derived from
+   on-the-wire bit ordering: the first bit 'on the wire' is the high-
+   order coefficient.  Since SCTP is a transport-level protocol, it
+   cannot know the actual serial-media bit ordering.  Moreover,
+   different links in the path between SCTP endpoints may use different
+   link-level bit orders.
+
+   A convention must therefore be established for mapping SCTP transport
+   messages to polynomials for purposes of CRC computation.  The bit-
+   ordering for mapping SCTP messages to polynomials is that bytes are
+   taken most-significant first; but within each byte, bits are taken
+   least-significant first.  The first byte of the message provides the
+   eight highest coefficients.  Within each byte, the least-significant
+   SCTP bit gives the most significant polynomial coefficient within
+
+
+
+Stone, et. al.              Standards Track                     [Page 4]
+
+RFC 3309                  SCTP Checksum Change            September 2002
+
+
+   that byte, and the most-significant SCTP bit is the least significant
+   polynomial coefficient in that byte.  (This bit ordering is sometimes
+   called 'mirrored' or 'reflected' [Williams93].)  CRC polynomials are
+   to be transformed back into SCTP transport-level byte values, using a
+   consistent mapping.
+
+   The SCTP transport-level CRC value should be calculated as follows:
+
+      -  CRC input data are assigned to a byte stream, numbered from 0
+         to N-1.
+
+      -  the transport-level byte-stream is mapped to a polynomial
+         value.  An N-byte PDU with j bytes numbered 0 to N-1, is
+         considered as coefficients of a polynomial M(x) of order 8N-1,
+         with bit 0 of byte j being coefficient x^(8(N-j)-8), bit 7 of
+         byte j being coefficient x^(8(N-j)-1).
+
+      -  the CRC remainder register is initialized with all 1s and the
+         CRC is computed with an algorithm that simultaneously
+         multiplies by x^32 and divides by the CRC polynomial.
+
+      -  the polynomial is multiplied by x^32 and divided by G(x), the
+         generator polynomial, producing a remainder R(x) of degree less
+         than or equal to 31.
+
+      -  the coefficients of R(x) are considered a 32 bit sequence.
+
+      -  the bit sequence is complemented.  The result is the CRC
+         polynomial.
+
+      -  The CRC polynomial is mapped back into SCTP transport-level
+         bytes.  Coefficient of x^31 gives the value of bit 7 of SCTP
+         byte 0, the coefficient of x^24 gives the value of bit 0 of
+         byte 0.  The coefficient of x^7 gives bit 7 of byte 3 and the
+         coefficient of x^0 gives bit 0 of byte 3.  The resulting four-
+         byte transport-level sequence is the 32-bit SCTP checksum
+         value.
+
+   IMPLEMENTATION NOTE: Standards documents, textbooks, and vendor
+   literature on CRCs often follow an alternative formulation, in which
+   the register used to hold the remainder of the long-division
+   algorithm is initialized to zero rather than all-1s, and instead the
+   first 32 bits of the message are complemented.  The long-division
+   algorithm used in our formulation is specified, such that the the
+   initial multiplication by 2^32 and the long-division are combined
+   into one simultaneous operation.  For such algorithms, and for
+   messages longer than 64 bits, the two specifications are precisely
+   equivalent.  That equivalence is the intent of this document.
+
+
+
+Stone, et. al.              Standards Track                     [Page 5]
+
+RFC 3309                  SCTP Checksum Change            September 2002
+
+
+   Implementors of SCTP are warned that both specifications are to be
+   found in the literature, sometimes with no restriction on the long-
+   division algorithm.  The choice of formulation in this document is to
+   permit non-SCTP usage, where the same CRC algorithm may be used to
+   protect messages shorter than 64 bits.
+
+   If SCTP could follow link level CRC use, the CRC would be computed
+   over the link-level bit-stream.  The first bit on the link mapping to
+   the highest-order coefficient, and so on, down to the last link-level
+   bit as the lowest-order coefficient.  The CRC value would be
+   transmitted immediately after the input message as a link-level
+   'trailer'.  The resulting link-level bit-stream would be (M(X)x) *
+   x^32) + (M(X)*x^32))/ G(x), which is divisible by G(X).  There would
+   thus be a constant CRC remainder for 'good' packets.  However, given
+   that implementations of RFC 2960 have already proliferated, the IETF
+   discussions considered that the benefit of a 'trailer' CRC did not
+   outweigh the cost of making a very large change in the protocol
+   processing.  Further, packets accepted by the SCTP 'header' CRC are
+   in one-to-one correspondence with packets accepted by a modified
+   procedure using a 'trailer' CRC value, and where the SCTP common
+   checksum header is set to zero on transmission and is received as
+   zero.
+
+   There may be a computational advantage in validating the Association
+   against the Verification Tag, prior to performing a checksum, as
+   invalid tags will result in the same action as a bad checksum in most
+   cases.  The exceptions for this technique would be INIT and some
+   SHUTDOWN-COMPLETE exchanges, as well as a stale COOKIE-ECHO.  These
+   special case exchanges must represent small packets and will minimize
+   the effect of the checksum calculation.
+
+3 Security Considerations
+
+   In general, the security considerations of RFC 2960 apply to the
+   protocol with the new checksum as well.
+
+4 IANA Considerations
+
+   There are no IANA considerations required in this document.
+
+
+
+
+
+
+
+
+
+
+
+
+Stone, et. al.              Standards Track                     [Page 6]
+
+RFC 3309                  SCTP Checksum Change            September 2002
+
+
+5 Acknowledgments
+
+   The authors would like to thank the following people that have
+   provided comments and input on the checksum issue:
+
+   Mark Adler, Ran Atkinson, Stephen Bailey, David Black, Scott Bradner,
+   Mikael Degermark, Laurent Glaude, Klaus Gradischnig, Alf Heidermark,
+   Jacob Heitz, Gareth Kiely, David Lehmann, Allision Mankin, Lyndon
+   Ong, Craig Partridge, Vern Paxson, Kacheong Poon, Michael Ramalho,
+   David Reed, Ian Rytina, Hanns Juergen Schwarzbauer, Chip Sharp, Bill
+   Sommerfeld, Michael Tuexen, Jim Williams, Jim Wendt, Michael Welzl,
+   Jonathan Wood, Lloyd Wood, Qiaobing Xie, La Monte Yarroll.
+
+   Special thanks to Dafna Scheinwald, Julian Satran, Pat Thaler, Matt
+   Wakeley, and Vince Cavanna, for selection criteria of polynomials and
+   examination of CRC polynomials, particularly CRC-32c [Castagnoli93].
+
+   Special thanks to Mr. Ross Williams and his document [Williams93].
+   This non-formal perspective on software aspects of CRCs furthered
+   understanding of authors previously unfamiliar with CRC computation.
+   More formal treatments of [Blahut 94] or [Peterson 72], was also
+   essential.
+
+6 References
+
+   [Castagnoli93]  G. Castagnoli, S. Braeuer and M. Herrman,
+                   "Optimization of Cyclic Redundancy-Check Codes with
+                   24 and 32 Parity Bits", IEEE Transactions on
+                   Communications, Vol. 41, No. 6, June 1993
+
+   [McKee75]       H. McKee, "Improved {CRC} techniques detects
+                   erroneous leading and trailing 0's in transmitted
+                   data blocks", Computer Design Volume 14 Number 10
+                   Pages 102-4,106, October 1975
+
+   [RFC1700]       Reynolds, J. and J. Postel, "ASSIGNED NUMBERS", RFC
+                   1700, October 1994.
+
+   [RFC2026]       Bradner, S., "The Internet Standards Process --
+                   Revision 3", BCP 9, RFC 2026, October 1996.
+
+   [RFC2119]       Bradner, S., "Key words for use in RFCs to Indicate
+                   Requirement Levels", BCP 14, RFC 2119, March 1997.
+
+   [RFC2960]       Stewart, R., Xie, Q., Morneault, K., Sharp, C.,
+                   Schwarzbauer, H., Taylor, T., Rytina, I., Kalla, M.,
+                   Zhang, L. and V. Paxson, "Stream Control Transmission
+                   Protocol," RFC 2960, October 2000.
+
+
+
+Stone, et. al.              Standards Track                     [Page 7]
+
+RFC 3309                  SCTP Checksum Change            September 2002
+
+
+   [ITU32]         ITU-T Recommendation V.42, "Error-correcting
+                   procedures for DCEs using asynchronous-to-synchronous
+                   conversion", section 8.1.1.6.2, October 1996.
+
+7.1 Informative References
+
+   [STONE]         Stone, J.,  "Checksums in the Internet", Doctoral
+                   dissertation - August 2001.
+
+   [Williams93]    Williams, R., "A PAINLESS GUIDE TO CRC ERROR
+                   DETECTION ALGORITHMS" - Internet publication, August
+                   1993,
+                   http://www.geocities.com/SiliconValley/Pines/
+                   8659/crc.htm.
+
+   [Blahut 1994]   R.E. Blahut, Theory and Practice of Error Control
+                   Codes, Addison-Wesley, 1994.
+
+   [Easics 2001]   http://www.easics.be/webtools/crctool.  Online tools
+                   for synthesis of CRC Verilog and VHDL.
+
+   [Feldmeier 95]  David C. Feldmeier, Fast software implementation of
+                   error detection codes, IEEE Transactions on
+                   Networking, vol 3 no 6, pp 640-651, December, 1995.
+
+   [Glaise 1997]   R.  J. Glaise, A two-step computation of cyclic
+                   redundancy code CRC-32 for ATM networks, IBM Journal
+                   of Research and Development} vol 41 no 6, 1997.
+                   http://www.research.ibm.com/journal/rd/416/
+                   glaise.html.
+
+   [Prange 1957]   E. Prange, Cyclic Error-Correcting codes in two
+                   symbols, Technical report AFCRC-TN-57-103, Air Force
+                   Cambridge Research Center, Cambridge, Mass. 1957.
+
+   [Peterson 1972] W. W. Peterson and E.J Weldon, Error Correcting
+                   Codes, 2nd. edition, MIT Press, Cambridge,
+                   Massachusetts.
+
+   [Shie2001]      Ming-Der Shieh et. al, A Systematic Approach for
+                   Parallel CRC Computations. Journal of Information
+                   Science and Engineering, Vol.17 No.3, pp.445-461
+
+   [Sprachman2001] Michael Sprachman, Automatic Generation of Parallel
+                   CRC Circuits, IEEE Design & Test May-June 2001
+
+
+
+
+
+
+Stone, et. al.              Standards Track                     [Page 8]
+
+RFC 3309                  SCTP Checksum Change            September 2002
+
+
+Appendix
+
+   This appendix is for information only and is NOT part of the
+   standard.
+
+   The anticipated deployment of SCTP ranges over several orders of
+   magnitude of link speed: from cellular-power telephony devices at
+   tens of kilobits, to local links at tens of gigabits.  Implementors
+   of SCTP should consider their link speed and choose, from the wide
+   range of CRC implementations, one which matches their own design
+   point for size, cost, and throughput.  Many techniques for computing
+   CRCs are known.  This Appendix surveys just a few, to give a feel for
+   the range of techniques available.
+
+   CRCs are derived from early work by Prange in the 1950s [Prange 57].
+   The theory underlying CRCs and choice of generator polynomial can be
+   introduced by either the theory of Galois fields [Blahut 94] or as
+   ideals of an algebra over cyclic codes [cite Peterson 72].
+
+   One of the simplest techniques is direct bit-serial hardware
+   implementations, using the generator polynomial as the taps of a
+   linear feedback shift register (LSFR).  LSFR computation follows
+   directly from the mathematics, and is generally attributed to Prange.
+   Tools exist which, a CRC generator polynomial, will produce
+   synthesizable Verilog code for CRC hardware [Easics 2001].
+
+   Since LSFRs do not scale well in speed, a variety of other techniques
+   have been explored.  One technique exploits the fact that the divisor
+   of the polynomial long-division, G, is known in advance.  It is thus
+   possible to pre-compute lookup tables giving the polynomial remainder
+   of multiple input bits --- typically 2, 4, or 8 bits of input at a
+   time.  This technique can be used either in software or in hardware.
+   Software to compute lookup tables yielding 2, 4, or 8 bits of result
+   is freely available. [Williams93]
+
+   For multi-gigabit links, the above techniques may still not be fast
+   enough.  One technique for computing CRCS at OC-48 rates is 'two-
+   stage' CRC computation [Glaise 1997].  Here, some multiple of G(x),
+   G(x)H(x), is chosen so as to minimize the number of nonzero
+   coefficients, or weight, of the product G(x)H(x).  The low weight of
+   the product polynomial makes it susceptible to efficient hardware
+   divide-by-constant implementations.  This first stage gives M(x)/
+   (G(x)H(x)), as its result.  The second stage then divides the result
+   of the first stage by H(x), yielding (M(x)/(G(x)H(x)))/H(x).  If H(x)
+   is also relatively prime to G(x), this gives M(x)/G(x).  Further
+   developments on this approach can be found in [Shie2001] and
+   [Sprachman2001].
+
+
+
+
+Stone, et. al.              Standards Track                     [Page 9]
+
+RFC 3309                  SCTP Checksum Change            September 2002
+
+
+   The literature also includes a variety of software CRC
+   implementations.  One approach is to use a carefully-tuned assembly
+   code for direct polynomial division.  [Feldmeier 95] reports that for
+   low-weight polynomials, tuned polynomial arithmetic gives higher
+   throughput than table-lookup algorithms.  Even within table-lookup
+   algorithms, the size of the table can be tuned, either for total
+   cache footprint, or (for space-restricted environments) to minimize
+   total size.
+
+   Implementors should keep in mind, the bit ordering described in
+   Section 2: the ordering of bits within bytes for computing CRCs in
+   SCTP is the least significant bit of each byte is the most-
+   significant polynomial coefficient(and vice-versa).  This 'reflected'
+   SCTP CRC bit ordering matches on-the-wire bit order for Ethernet and
+   other serial media, but is the reverse of traditional Internet bit
+   ordering.
+
+   One technique to accommodate this bit-reversal can be explained as
+   follows: sketch out a hardware implementation, assuming the bits are
+   in CRC bit order; then perform a left-to-right inversion (mirror
+   image) on the entire algorithm.  (We defer, for a moment, the issue
+   of byte order within words.)  Then compute that "mirror image" in
+   software.  The CRC from the "mirror image" algorithm will be the
+   bit-reversal of a correct hardware implementation.  When the link-
+   level media sends each byte, the byte is sent in the reverse of the
+   host CPU bit-order.  Serialization of each byte of the "reflected"
+   CRC value re-reverses the bit order, so in the end, each byte will be
+   transmitted on-the-wire in the specified bit order.
+
+   The following non-normative sample code is taken from an open-source
+   CRC generator [Williams93], using the "mirroring" technique and
+   yielding a lookup table for SCTP CRC32-c with 256 entries, each 32
+   bits wide.  While neither especially slow nor especially fast, as
+   software table-lookup CRCs go, it has the advantage of working on
+   both big-endian and little-endian CPUs, using the same (host-order)
+   lookup tables, and using only the pre-defined ntohl() and htonl()
+   operations.  The code is somewhat modified from [Williams93], to
+   ensure portability between big-endian and little-endian
+   architectures.  (Note that if the byte endian-ness of the target
+   architecture is known to be little-endian the final bit-reversal and
+   byte-reversal steps can be folded into a single operation.)
+
+
+
+
+
+
+
+
+
+
+Stone, et. al.              Standards Track                    [Page 10]
+
+RFC 3309                  SCTP Checksum Change            September 2002
+
+
+/*************************************************************/
+/* Note Definition for Ross Williams table generator would   */
+/* be: TB_WIDTH=4, TB_POLLY=0x1EDC6F41, TB_REVER=TRUE        */
+/* For Mr. Williams direct calculation code use the settings */
+/* cm_width=32, cm_poly=0x1EDC6F41, cm_init=0xFFFFFFFF,      */
+/* cm_refin=TRUE, cm_refot=TRUE, cm_xorort=0x00000000        */
+/*************************************************************/
+
+/* Example of the crc table file */
+#ifndef __crc32cr_table_h__
+#define __crc32cr_table_h__
+
+#define CRC32C_POLY 0x1EDC6F41
+#define CRC32C(c,d) (c=(c>>8)^crc_c[(c^(d))&0xFF])
+
+unsigned long  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,
+
+
+
+Stone, et. al.              Standards Track                    [Page 11]
+
+RFC 3309                  SCTP Checksum Change            September 2002
+
+
+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,
+};
+
+#endif
+
+ /* Example of table build routine */
+
+
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define OUTPUT_FILE   "crc32cr.h"
+#define CRC32C_POLY    0x1EDC6F41L
+FILE *tf;
+
+
+
+
+Stone, et. al.              Standards Track                    [Page 12]
+
+RFC 3309                  SCTP Checksum Change            September 2002
+
+
+unsigned long
+reflect_32 (unsigned long b)
+{
+  int i;
+  unsigned long rw = 0L;
+
+  for (i = 0; i < 32; i++){
+      if (b & 1)
+        rw |= 1 << (31 - i);
+      b >>= 1;
+  }
+  return (rw);
+}
+
+unsigned long
+build_crc_table (int index)
+{
+  int i;
+  unsigned long rb;
+
+  rb = reflect_32 (index);
+
+  for (i = 0; i < 8; i++){
+      if (rb & 0x80000000L)
+       rb = (rb << 1) ^ CRC32C_POLY;
+      else
+       rb <<= 1;
+  }
+  return (reflect_32 (rb));
+}
+
+main ()
+{
+  int i;
+
+  printf ("\nGenerating CRC-32c table file <%s>\n", OUTPUT_FILE);
+  if ((tf = fopen (OUTPUT_FILE, "w")) == NULL){
+      printf ("Unable to open %s\n", OUTPUT_FILE);
+      exit (1);
+  }
+  fprintf (tf, "#ifndef __crc32cr_table_h__\n");
+  fprintf (tf, "#define __crc32cr_table_h__\n\n");
+  fprintf (tf, "#define CRC32C_POLY 0x%08lX\n", CRC32C_POLY);
+  fprintf (tf, "#define CRC32C(c,d) (c=(c>>8)^crc_c[(c^(d))&0xFF])\n");
+  fprintf (tf, "\nunsigned long  crc_c[256] =\n{\n");
+  for (i = 0; i < 256; i++){
+      fprintf (tf, "0x%08lXL, ", build_crc_table (i));
+      if ((i & 3) == 3)
+
+
+
+Stone, et. al.              Standards Track                    [Page 13]
+
+RFC 3309                  SCTP Checksum Change            September 2002
+
+
+        fprintf (tf, "\n");
+  }
+   fprintf (tf, "};\n\n#endif\n");
+
+  if (fclose (tf) != 0)
+    printf ("Unable to close <%s>." OUTPUT_FILE);
+  else
+    printf ("\nThe CRC-32c table has been written to <%s>.\n",
+      OUTPUT_FILE);
+}
+
+
+
+/* Example of crc insertion */
+
+#include "crc32cr.h"
+
+unsigned long
+generate_crc32c(unsigned char *buffer, unsigned int length)
+{
+  unsigned int i;
+  unsigned long crc32 = ~0L;
+  unsigned long result;
+  unsigned char byte0,byte1,byte2,byte3;
+
+  for (i = 0; i < length; i++){
+      CRC32C(crc32, buffer[i]);
+  }
+  result = ~crc32;
+
+  /*  result  now holds the negated polynomial remainder;
+   *  since the table and algorithm is "reflected" [williams95].
+   *  That is,  result has the same value as if we mapped the message
+   *  to a polynomial, computed the host-bit-order polynomial
+   *  remainder, performed final negation, then did an end-for-end
+   *  bit-reversal.
+   *  Note that a 32-bit bit-reversal is identical to four inplace
+   *  8-bit reversals followed by an end-for-end byteswap.
+   *  In other words, the bytes of each bit are in the right order,
+   *  but the bytes have been byteswapped.  So we now do an explicit
+   *  byteswap.  On a little-endian machine, this byteswap and
+   *  the final ntohl cancel out and could be elided.
+   */
+
+  byte0 = result & 0xff;
+  byte1 = (result>>8) & 0xff;
+  byte2 = (result>>16) & 0xff;
+  byte3 = (result>>24) & 0xff;
+
+
+
+Stone, et. al.              Standards Track                    [Page 14]
+
+RFC 3309                  SCTP Checksum Change            September 2002
+
+
+  crc32 = ((byte0 << 24) |
+           (byte1 << 16) |
+           (byte2 << 8)  |
+           byte3);
+  return ( crc32 );
+}
+
+int
+insert_crc32(unsigned char *buffer, unsigned int length)
+{
+  SCTP_message *message;
+  unsigned long crc32;
+  message = (SCTP_message *) buffer;
+  message->common_header.checksum = 0L;
+  crc32 = generate_crc32c(buffer,length);
+  /* and insert it into the message */
+  message->common_header.checksum = htonl(crc32);
+  return 1;
+}
+
+int
+validate_crc32(unsigned char *buffer, unsigned int length)
+{
+  SCTP_message *message;
+  unsigned int i;
+  unsigned long original_crc32;
+  unsigned long crc32 = ~0L;
+
+  /* save and zero checksum */
+  message = (SCTP_message *) buffer;
+  original_crc32 = ntohl(message->common_header.checksum);
+  message->common_header.checksum = 0L;
+  crc32 = generate_crc32c(buffer,length);
+  return ((original_crc32 == crc32)? 1 : -1);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stone, et. al.              Standards Track                    [Page 15]
+
+RFC 3309                  SCTP Checksum Change            September 2002
+
+
+Authors' Addresses
+
+   Jonathan Stone
+   Room 446, Mail code 9040
+   Gates building 4A
+   Stanford, Ca 94305
+
+   EMail: jonathan@dsg.stanford.edu
+
+
+   Randall R. Stewart
+   24 Burning Bush Trail.
+   Crystal Lake, IL 60012
+   USA
+
+   EMail: rrs@cisco.com
+
+
+   Douglas Otis
+   800 E. Middlefield
+   Mountain View, CA 94043
+   USA
+
+   EMail: dotis@sanlight.net
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stone, et. al.              Standards Track                    [Page 16]
+
+RFC 3309                  SCTP Checksum Change            September 2002
+
+
+Full Copyright Statement
+
+   Copyright (C) The Internet Society (2002).  All Rights Reserved.
+
+   This document and translations of it may be copied and furnished to
+   others, and derivative works that comment on or otherwise explain it
+   or assist in its implementation may be prepared, copied, published
+   and distributed, in whole or in part, without restriction of any
+   kind, provided that the above copyright notice and this paragraph are
+   included on all such copies and derivative works.  However, this
+   document itself may not be modified in any way, such as by removing
+   the copyright notice or references to the Internet Society or other
+   Internet organizations, except as needed for the purpose of
+   developing Internet standards in which case the procedures for
+   copyrights defined in the Internet Standards process must be
+   followed, or as required to translate it into languages other than
+   English.
+
+   The limited permissions granted above are perpetual and will not be
+   revoked by the Internet Society or its successors or assigns.
+
+   This document and the information contained herein is provided on an
+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+   Funding for the RFC Editor function is currently provided by the
+   Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stone, et. al.              Standards Track                    [Page 17]
+
diff --git a/doc/rfc3554.txt b/doc/rfc3554.txt
new file mode 100644
index 0000000..23ae9cd
--- /dev/null
+++ b/doc/rfc3554.txt
@@ -0,0 +1,507 @@
+
+
+
+
+
+
+Network Working Group                                        S. Bellovin
+Request for Comments: 3554                                  J. Ioannidis
+Category: Standards Track                           AT&T Labs - Research
+                                                            A. Keromytis
+                                                     Columbia University
+                                                              R. Stewart
+                                                                   Cisco
+                                                               July 2003
+
+
+  On the Use of Stream Control Transmission Protocol (SCTP) with IPsec
+
+Status of this Memo
+
+   This document specifies an Internet standards track protocol for the
+   Internet community, and requests discussion and suggestions for
+   improvements.  Please refer to the current edition of the "Internet
+   Official Protocol Standards" (STD 1) for the standardization state
+   and status of this protocol.  Distribution of this memo is unlimited.
+
+Copyright Notice
+
+   Copyright (C) The Internet Society (2003).  All Rights Reserved.
+
+Abstract
+
+   This document describes functional requirements for IPsec (RFC 2401)
+   and Internet Key Exchange (IKE) (RFC 2409) to facilitate their use in
+   securing SCTP (RFC 2960) traffic.
+
+1.  Introduction
+
+   The Stream Control Transmission Protocol (SCTP) is a reliable
+   transport protocol operating on top of a connection-less packet
+   network such as IP.  SCTP is designed to transport PSTN signaling
+   messages over IP networks, but is capable of broader applications.
+
+   When SCTP is used over IP networks, it may utilize the IP security
+   protocol suite [RFC2402][RFC2406] for integrity and confidentiality.
+   To dynamically establish IPsec Security Associations (SAs), a key
+   negotiation protocol such as IKE [RFC2409] may be used.
+
+   This document describes functional requirements for IPsec and IKE to
+   facilitate their use in securing SCTP traffic.  In particular, we
+   discuss additional support in the form of a new ID type in IKE
+   [RFC2409] and implementation choices in the IPsec processing to
+   accommodate for the multiplicity of source and destination addresses
+   associated with a single SCTP association.
+
+
+
+Bellovin, et. al.           Standards Track                     [Page 1]
+
+RFC 3554                    SCTP with IPsec                    July 2003
+
+
+1.1.  Terminology
+
+   In this document, the key words "MAY", "MUST, "MUST NOT", "optional",
+   "recommended", "SHOULD", and "SHOULD NOT", are to be interpreted as
+   described in [RFC-2119].
+
+2.  SCTP over IPsec
+
+   When utilizing the Authentication Header [RFC2402] or Encapsulating
+   Security Payload [RFC2406] protocols to provide security services for
+   SCTP frames, the SCTP frame is treated as just another transport
+   layer protocol on top of IP (same as TCP, UDP, etc.)
+
+   IPsec implementations should already be able to use the SCTP
+   transport protocol number as assigned by IANA as a selector in their
+   Security Policy Database (SPD).  It should be straightforward to
+   extend existing implementations to use the SCTP source and
+   destination port numbers as selectors in the SPD.  Since the concept
+   of a port, and its location in the transport header is
+   protocol-specific, the IPsec code responsible for identifying the
+   transport protocol ports has to be suitably modified.  This, however
+   is not enough to fully support the use of SCTP in conjunction with
+   IPsec.
+
+   Since SCTP can negotiate sets of source and destination addresses
+   (not necessarily in the same subnet or address range) that may be
+   used in the context of a single association, the SPD should be able
+   to accommodate this.  The straightforward, and expensive, way is to
+   create one SPD entry for each pair of source/destination addresses
+   negotiated.  A better approach is to associate sets of addresses with
+   the source and destination selectors in each SPD entry (in the case
+   of non-SCTP traffic, these sets would contain only one element).
+   While this is an implementation decision, implementors are encouraged
+   to follow this or a similar approach when designing or modifying the
+   SPD to accommodate SCTP-specific selectors.
+
+   Similarly, SAs may have multiple associated source and destination
+   addresses.  Thus an SA is identified by the extended triplet ({set of
+   destination addresses}, SPI, Security Protocol).  A lookup in the
+   Security Association Database (SADB) using the triplet (Destination
+   Address, SPI, Security Protocol), where Destination Address is any of
+   the negotiated peer addresses, MUST return the same SA.
+
+
+
+
+
+
+
+
+
+Bellovin, et. al.           Standards Track                     [Page 2]
+
+RFC 3554                    SCTP with IPsec                    July 2003
+
+
+3.  SCTP and IKE
+
+   There are two issues relevant to the use of IKE when negotiating
+   protection for SCTP traffic:
+
+   a) Since SCTP allows for multiple source and destination network
+   addresses associated with an SCTP association, it MUST be possible
+   for IKE to efficiently negotiate these in the Phase 2 (Quick Mode)
+   exchange.  The straightforward approach is to negotiate one pair of
+   IPsec SAs for each combination of source and destination addresses.
+   This can result in an unnecessarily large number of SAs, thus wasting
+   time (in negotiating these) and memory.  All current implementations
+   of IKE support this functionality.  However, a method for specifying
+   multiple selectors in Phase 2 is desirable for efficiency purposes.
+   Conformance with this document requires that implementations adhere
+   to the guidelines in the rest of this section.
+
+   Define a new type of ID, ID_LIST, that allows for recursive inclusion
+   of IDs.  Thus, the IKE Phase 2 Initiator ID for an SCTP association
+   MAY be of type ID_LIST, which would in turn contain as many
+   ID_IPV4_ADDR IDs as necessary to describe Initiator addresses;
+   likewise for Responder IDs.  Note that other selector types MAY be
+   used when establishing SAs for use with SCTP, if there is no need to
+   use negotiate multiple addresses for each SCTP endpoint (i.e., if
+   only one address is used by each peer of an SCTP flow).
+   Implementations MUST support this new ID type.
+
+   ID_LIST IDs cannot appear inside ID_LIST ID payloads.  Any of the ID
+   types defined in [RFC2407] can be included inside an ID_LIST ID.
+   Each of the IDs contained in the ID_LIST ID must include a complete
+   Identification Payload header.
+
+   The following diagram illustrates the content of an ID_LIST ID
+   payload that contains two ID_FQDN payloads.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Bellovin, et. al.           Standards Track                     [Page 3]
+
+RFC 3554                    SCTP with IPsec                    July 2003
+
+
+    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   !  Next Payload !   RESERVED    !        Payload Length         !
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   !    ID Type    !  Protocol ID  !             Port              !
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   !  Next Payload !   RESERVED    !        Payload Length         !
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   !    ID Type    !  Protocol ID  !             Port              !
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   ~                  FQDN 1 Identification Data                   ~
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   !  Next Payload !   RESERVED    !        Payload Length         !
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   !    ID Type    !  Protocol ID  !             Port              !
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   ~                  FQDN 2 Identification Data                   ~
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   The Next Payload field in any of the included IDs (for FQDN 1 and
+   FQDN 2) MUST be ignored by the Responder.  The Payload Length, ID
+   Type, Protocol ID, and Port fields of the included Payloads should be
+   set to the appropriate values.  The Protocol ID and Port fields of
+   the ID_LIST Payload should be set to zero by the Initiator and MUST
+   be ignored by the Responder.
+
+   Different types of IDs (e.g., an ID_FQDN and an ID_IPV4_ADDR) can be
+   included inside the same ID_LIST ID.  If an ID type included in an
+   ID_LIST ID payload is invalid in the context the ID_LIST ID is used,
+   the whole ID_LIST should be considered to be at fault, e.g., if an
+   ID_LIST ID payload that contains an ID_FQDN and an ID_IPV4_ADDR is
+   received during an IKE Quick Mode exchange, the Responder should
+   signal a fault to the Initiator and stop processing of the message
+   (the same behavior it would exhibit if simply an ID_FQDN was received
+   instead).
+
+   The IANA-assigned number for the ID_LIST ID is 12.
+
+   b) For IKE to be able to validate the Phase 2 selectors, it must be
+   possible to exchange sufficient information during Phase 1.
+   Currently, IKE can directly accommodate the simple case of two peers
+   talking to each other, by using Phase 1 IDs corresponding to their IP
+   addresses, and encoding those same addresses in the SubjAltName of
+   the certificates used to authenticate the Phase 1 exchange.  For more
+   complicated scenarios, external policy (or some other mechanism)
+   needs to be consulted, to validate the Phase 2 selectors and SA
+   parameters.  All addresses presented in Phase 2 selectors MUST be
+   validated.  That is, enough evidence must be presented to the
+
+
+
+Bellovin, et. al.           Standards Track                     [Page 4]
+
+RFC 3554                    SCTP with IPsec                    July 2003
+
+
+   Responder that the Initiator is authorized to receive traffic for all
+   addresses that appear in the Phase 2 selectors.  This evidence can be
+   derived from the certificates exchanged during Phase 1 (if possible);
+   otherwise it must be acquired through out-of-band means (e.g., policy
+   mechanism, configured by the administrator, etc.).
+
+   In order to accommodate the same simple scenario in the context of
+   multiple source/destination addresses in an SCTP association, it MUST
+   be possible to:
+
+      1) Specify multiple Phase 1 IDs, which are used to validate Phase
+         2 parameters (in particular, the Phase 2 selectors).  Following
+         the discussion on an ID_LIST ID type, it is possible to use the
+         same method for specifying multiple Phase 1 IDs.
+
+      2) Authenticate the various Phase 1 IDs.  Using pre-shared key
+         authentication, this is possible by associating the same shared
+         key with all acceptable peer Phase 1 IDs.  In the case of
+         certificates, we have two alternatives:
+
+            a) The same certificate can contain multiple IDs encoded in
+            the SubjAltName field, as an ASN.1 sequence.  Since this is
+            already possible, it is the preferred solution and any
+            conformant implementations MUST support this.
+
+            b) Multiple certificates MAY be passed during the Phase 1
+            exchange, in multiple CERT payloads.  This feature is also
+            supported by the current specification.  Since only one
+            signature may be issued per IKE Phase 1 exchange, it is
+            necessary for all certificates to contain the same key as
+            their Subject.  However, this approach does not offer any
+            significant advantage over (a), thus implementations MAY
+            support it.
+
+         In either case, an IKE implementation needs to verify the
+         validity of a peer's claimed Phase 1 ID, for all such IDs
+         received over an exchange.
+
+   Although SCTP does not currently support modification of the
+   addresses associated with an SCTP association (while the latter is in
+   use), it is a feature that may be supported in the future.  Unless
+   the set of addresses changes extremely often, it is sufficient to do
+   a full Phase 1 and Phase 2 exchange to establish the appropriate
+   selectors and SAs.
+
+
+
+
+
+
+
+Bellovin, et. al.           Standards Track                     [Page 5]
+
+RFC 3554                    SCTP with IPsec                    July 2003
+
+
+   The last issue with respect to SCTP and IKE pertains to the initial
+   offer of Phase 2 selectors (IDs) by the Initiator.  Per the current
+   IKE specification, the Responder must send in the second message of
+   the Quick Mode the IDs received in the first message.  Thus, it is
+   assumed that the Initiator already knows all the Selectors relevant
+   to this SCTP association.  In most cases however, the Responder has
+   more accurate knowledge of its various addresses.  Thus, the IPsec
+   Selectors established can be potentially insufficient or inaccurate.
+
+   If the proposed set of Selectors is not accurate from the Responder's
+   point of view, the latter can start a new Quick Mode exchange.  In
+   this new Quick Mode exchange, the roles of Initiator and Responder
+   have been reversed; the new Initiator MUST copy the SA and Selectors
+   from the old Quick Mode message, and modify its set of Selectors to
+   match reality.  All SCTP-supporting IKE implementations MUST be able
+   to do this.
+
+4.  Security Considerations
+
+   This documents discusses the use of a security protocol (IPsec) in
+   the context of a new transport protocol (SCTP).  SCTP, with its
+   provision for mobility, opens up the possibility for
+   traffic-redirection attacks whereby an attacker X claims that his
+   address should be added to an SCTP session between peers A and B, and
+   be used for further communications.  In this manner, traffic between
+   A and B can be seen by X.  If X is not in the communication path
+   between A and B, SCTP offers him new attack capabilities.  Thus, all
+   such address updates of SCTP sessions should be authenticated.  Since
+   IKE negotiates IPsec SAs for use by these sessions, IKE MUST validate
+   all addresses attached to an SCTP endpoint either through validating
+   the certificates presented to it during the Phase 1 exchange, or
+   through some out-of-band method.
+
+   The Responder in a Phase 2 exchange MUST verify the Initiator's
+   authority to receive traffic for all addresses that appear in the
+   Initiator's Phase 2 selectors.  Not doing so would allow for any
+   valid peer of the Responder (i.e., anyone who can successfully
+   establish a Phase 1 SA with the Responder) to see any other valid
+   peer's traffic by claiming their address.
+
+5.  IANA Considerations
+
+   IANA has assigned number 12 for ID_LIST (defined in Section 3) in the
+   "IPSEC Identification Type" registry from the Internet Security
+   Association and Key Management Protocol (ISAKMP) Identifiers table.
+
+
+
+
+
+
+Bellovin, et. al.           Standards Track                     [Page 6]
+
+RFC 3554                    SCTP with IPsec                    July 2003
+
+
+6.  Intellectual Property Rights Notice
+
+   The IETF takes no position regarding the validity or scope of any
+   intellectual property or other rights that might be claimed to
+   pertain to the implementation or use of the technology described in
+   this document or the extent to which any license under such rights
+   might or might not be available; neither does it represent that it
+   has made any effort to identify any such rights.  Information on the
+   IETF's procedures with respect to rights in standards-track and
+   standards-related documentation can be found in BCP-11.  Copies of
+   claims of rights made available for publication and any assurances of
+   licenses to be made available, or the result of an attempt made to
+   obtain a general license or permission for the use of such
+   proprietary rights by implementors or users of this specification can
+   be obtained from the IETF Secretariat.
+
+   The IETF invites any interested party to bring to its attention any
+   copyrights, patents or patent applications, or other proprietary
+   rights which may cover technology that may be required to practice
+   this standard.  Please address the information to the IETF Executive
+   Director.
+
+Normative References
+
+   [RFC2401]  Kent, S. and R. Atkinson, "Security Architecture for the
+              Internet Protocol", RFC 2401, November 1998.
+
+   [RFC2402]  Kent, S. and R. Atkinson, "IP Authentication Header", RFC
+              2402, November 1998.
+
+   [RFC2406]  Kent, S. and R. Atkinson, "IP Encapsulating Security
+              Payload (ESP)", RFC 2406, November 1998.
+
+   [RFC2407]  Piper, D., "The Internet IP Security Domain of
+              Interpretation for ISAKMPD", RFC 2407, November 1998.
+
+   [RFC2408]  Maughan, D., Schertler, M., Schneider, M. and J. Turner,
+              "Internet Security Association and Key Management
+              Protocol", RFC 2408, November 1998.
+
+   [RFC2409]  Harkins, D. and D. Carrel, "The Internet Key Exchange
+              (IKE)", RFC 2409, November 1998.
+
+   [RFC2960]  Stewart, R., Xie, Q., Morneault, K., Sharp, C.,
+              Schwarzbauer, H., Taylor, T., Rytina, I., Kalla, M.,
+              Zhang, L. and V. Paxson, "Stream Control Transmission
+              Protocol", RFC 2960, October 2000.
+
+
+
+
+Bellovin, et. al.           Standards Track                     [Page 7]
+
+RFC 3554                    SCTP with IPsec                    July 2003
+
+
+Authors' Addresses
+
+   Steven M. Bellovin
+   AT&T Labs - Research
+   180 Park Avenue
+   Florham Park, New Jersey 07932-0971
+
+   Phone: +1 973 360 8656
+   EMail: smb@research.att.com
+
+
+   John Ioannidis
+   AT&T Labs - Research
+   180 Park Avenue
+   Florham Park, New Jersey 07932-0971
+
+   EMail: ji@research.att.com
+
+
+   Angelos D. Keromytis
+   Columbia University, CS Department
+   515 CS Building
+   1214 Amsterdam Avenue, Mailstop 0401
+   New York, New York 10027-7003
+
+   Phone: +1 212 939 7095
+   EMail: angelos@cs.columbia.edu
+
+
+   Randall R. Stewart
+   24 Burning Bush Trail.
+   Crystal Lake, IL 60012
+
+   Phone: +1-815-477-2127
+   EMail: rrs@cisco.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Bellovin, et. al.           Standards Track                     [Page 8]
+
+RFC 3554                    SCTP with IPsec                    July 2003
+
+
+Full Copyright Statement
+
+   Copyright (C) The Internet Society (2003).  All Rights Reserved.
+
+   This document and translations of it may be copied and furnished to
+   others, and derivative works that comment on or otherwise explain it
+   or assist in its implementation may be prepared, copied, published
+   and distributed, in whole or in part, without restriction of any
+   kind, provided that the above copyright notice and this paragraph are
+   included on all such copies and derivative works.  However, this
+   document itself may not be modified in any way, such as by removing
+   the copyright notice or references to the Internet Society or other
+   Internet organizations, except as needed for the purpose of
+   developing Internet standards in which case the procedures for
+   copyrights defined in the Internet Standards process must be
+   followed, or as required to translate it into languages other than
+   English.
+
+   The limited permissions granted above are perpetual and will not be
+   revoked by the Internet Society or its successors or assignees.
+
+   This document and the information contained herein is provided on an
+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+   Funding for the RFC Editor function is currently provided by the
+   Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Bellovin, et. al.           Standards Track                     [Page 9]
+
diff --git a/doc/rfc3758.txt b/doc/rfc3758.txt
new file mode 100644
index 0000000..1c0dc15
--- /dev/null
+++ b/doc/rfc3758.txt
@@ -0,0 +1,1235 @@
+
+
+
+
+
+
+Network Working Group                                         R. Stewart
+Request for Comments: 3758                                    M. Ramalho
+Category: Standards Track                            Cisco Systems, Inc.
+                                                                  Q. Xie
+                                                          Motorola, Inc.
+                                                               M. Tuexen
+                                      Univ. of Applied Sciences Muenster
+                                                               P. Conrad
+                                                  University of Delaware
+                                                                May 2004
+
+
+              Stream Control Transmission Protocol (SCTP)
+                     Partial Reliability Extension
+
+Status of this Memo
+
+   This document specifies an Internet standards track protocol for the
+   Internet community, and requests discussion and suggestions for
+   improvements.  Please refer to the current edition of the "Internet
+   Official Protocol Standards" (STD 1) for the standardization state
+   and status of this protocol.  Distribution of this memo is unlimited.
+
+Copyright Notice
+
+   Copyright (C) The Internet Society (2004).  All Rights Reserved.
+
+Abstract
+
+   This memo describes an extension to the Stream Control Transmission
+   Protocol (SCTP) that allows an SCTP endpoint to signal to its peer
+   that it should move the cumulative ack point forward.  When both
+   sides of an SCTP association support this extension, it can be used
+   by an SCTP implementation to provide partially reliable data
+   transmission service to an upper layer protocol.  This memo describes
+   the protocol extensions, which consist of a new parameter for INIT
+   and INIT ACK, and a new FORWARD TSN chunk type, and provides one
+   example of a partially reliable service that can be provided to the
+   upper layer via this mechanism.
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.             Standards Track                     [Page 1]
+
+RFC 3758           SCTP Partial Reliability Extension           May 2004
+
+
+Table of Contents
+
+   1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  2
+       1.1.  Overview of Protocol Extensions. . . . . . . . . . . . .  2
+       1.2.  Overview of New Services Provided to the Upper Layer . .  3
+       1.3.  Benefits of PR-SCTP  . . . . . . . . . . . . . . . . . .  4
+   2.  Conventions. . . . . . . . . . . . . . . . . . . . . . . . . .  5
+   3.  Protocol Changes to support PR-SCTP .  . . . . . . . . . . . .  5
+       3.1.  Forward-TSN-Supported Parameter For INIT and INIT ACK. .  5
+       3.2.  Forward Cumulative TSN Chunk Definition (FORWARD TSN). .  5
+       3.3.  Negotiation of Forward-TSN-Supported parameter . . . . .  7
+             3.3.1. Sending Forward-TSN-Supported param in INIT . . .  7
+             3.3.2. Receipt of Forward-TSN-Supported parameter in
+                    INIT or INIT-ACK. . . . . . . . . . . . . . . . .  7
+             3.3.3. Receipt of Op. Error for Forward-TSN-Supported
+                    Param . . . . . . . . . . . . . . . . . . . . . .  8
+       3.4.  Definition of "abandoned" in the context of PR-SCTP. . .  8
+       3.5.  Sender Side Implementation of PR-SCTP. . . . . . . . . .  9
+       3.6.  Receiver Side Implementation of PR-SCTP. . . . . . . . . 12
+   4.  Services provided by PR-SCTP to the upper layer. . . . . . . . 14
+       4.1.  PR-SCTP Service Definition for "timed reliability" . . . 15
+       4.2.  PR-SCTP Association Establishment. . . . . . . . . . . . 16
+       4.3.  Guidelines for defining other PR-SCTP Services . . . . . 17
+       4.4.  Usage Notes. . . . . . . . . . . . . . . . . . . . . . . 19
+   5.  Variables. . . . . . . . . . . . . . . . . . . . . . . . . . . 19
+   6.  Acknowledgments. . . . . . . . . . . . . . . . . . . . . . . . 19
+   7.  Security Considerations. . . . . . . . . . . . . . . . . . . . 19
+   8.  IANA Considerations. . . . . . . . . . . . . . . . . . . . . . 20
+   9.  References . . . . . . . . . . . . . . . . . . . . . . . . . . 20
+       9.1.  Normative References . . . . . . . . . . . . . . . . . . 20
+       9.2.  Informative References . . . . . . . . . . . . . . . . . 20
+   10. Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . 20
+   11. Full Copyright Statement . . . . . . . . . . . . . . . . . . .
+
+1.  Introduction
+
+   This memo describes an extension to the Stream Control Transmission
+   Protocol (SCTP) RFC 2960 [2] that allows an SCTP sender to signal to
+   its peer that it should no longer expect to receive one or more DATA
+   chunks.
+
+1.1.  Overview of Protocol Extensions
+
+   The protocol extension described in this document consists of two new
+   elements:
+
+   1. a single new parameter in the INIT/INIT-ACK exchange that
+      indicates whether the endpoint supports the extension
+
+
+
+Stewart, et al.             Standards Track                     [Page 2]
+
+RFC 3758           SCTP Partial Reliability Extension           May 2004
+
+
+   2. a single new chunk type, FORWARD TSN, that indicates that the
+      receiver should move its cumulative ack point forward (possibly
+      skipping past one or more DATA chunks that may not yet have been
+      received and/or acknowledged.)
+
+1.2.  Overview of New Services Provided to the Upper Layer
+
+   When this extension is supported by both sides of an SCTP
+   association, it can be used to provide partially reliable transport
+   service over an SCTP association.  We define partially reliable
+   transport service as a service that allows the user to specify, on a
+   per message basis, the rules governing how persistent the transport
+   service should be in attempting to send the message to the receiver.
+
+   One example of partially reliable service is specified in this
+   document, namely a "timed reliability" service.  This service allows
+   the service user to indicate a limit on the duration of time that the
+   sender should try to transmit/retransmit the message (this is a
+   natural extension of the "lifetime" parameter already in the base
+   protocol).
+
+   In addition to this example, we will also show that defining the
+   semantics of a particular partially reliable service involves two
+   elements, namely:
+
+   1. how the service user indicates the level of reliability required
+      for a particular message, and
+
+   2. how the sender side implementation uses that reliability level to
+      determine when to give up on further retransmissions of that
+      message.
+
+   Note that other than the fact that the FORWARD-TSN chunk is required,
+   neither of these two elements impacts the "on-the-wire" protocol;
+   only the API and the sender side implementation are affected by the
+   way in which the service is defined to the upper layer.  Therefore,
+   in principle, it is feasible to implement many varieties of partially
+   reliable services in a particular SCTP implementation without
+   changing the on-the-wire protocol.  Also, the SCTP receiver does not
+   necessarily need to know which semantics of partially reliable
+   service are being used by the sender, since the receiver's only role
+   is to correctly interpret FORWARD TSN chunks, thereby skipping past
+   messages that the sender has decided to no longer transmit (or
+   retransmit).
+
+   Nevertheless, it is recommended that a limited number of standard
+   definitions of partially reliable services be standardized by the
+   IETF so that the designers of IETF application layer protocols can
+
+
+
+Stewart, et al.             Standards Track                     [Page 3]
+
+RFC 3758           SCTP Partial Reliability Extension           May 2004
+
+
+   match the requirements of their upper layer protocols to standard
+   service definitions provided by a particular SCTP implementation.
+   One such definition, "timed reliability", is included in this
+   document.  Given the extensions proposed in this document, other
+   definitions may be standardized as the need arises without further
+   changes to the on-the-wire protocol.
+
+1.3.  Benefits of PR-SCTP
+
+   Hereafter, we use the notation "Partial Reliable Stream Control
+   Transmission Protocol (PR-SCTP)" to refer to the SCTP protocol,
+   extended as defined in this document.
+
+   The following are some of the advantages for integrating partially
+   reliable data service into SCTP, i.e., benefits of PR-SCTP:
+
+   1. Some application layer protocols may benefit from being able to
+      use a single SCTP association to carry both reliable content, --
+      such as text pages, billing and accounting information, setup
+      signaling -- and unreliable content, e.g., state that is highly
+      sensitive to timeliness, where generating a new packet is more
+      advantageous than transmitting an old one [3].
+
+   2. Partially reliable data traffic carried by PR-SCTP will enjoy the
+      same communication failure detection and protection capabilities
+      as the normal reliable SCTP data traffic does.  This includes the
+      ability to quickly detect a failed destination address, fail-over
+      to an alternate destination address, and be notified if the data
+      receiver becomes unreachable.
+
+   3. In addition to providing unordered, unreliable data transfer as
+      UDP does, PR-SCTP can provide ordered, unreliable data transfer
+      service.
+
+   4. PR-SCTP employs the same congestion control and congestion
+      avoidance for all data traffic, whether reliable or partially
+      reliable - this is very desirable since SCTP enforces TCP-
+      friendliness (unlike UDP.)
+
+   5. Because of the chunk bundling function of SCTP, reliable and
+      unreliable messages can be multiplexed over a single PR-SCTP
+      association.  Therefore, the number of IP datagrams (and hence the
+      network overhead) can be reduced instead of having to send these
+      different types of data using separate protocols.  Additionally,
+      this multiplexing allows for port savings versus using different
+      ports for reliable and unreliable connections.
+
+
+
+
+
+Stewart, et al.             Standards Track                     [Page 4]
+
+RFC 3758           SCTP Partial Reliability Extension           May 2004
+
+
+2.  Conventions
+
+   The keywords MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD,
+   SHOULD NOT, RECOMMENDED, NOT RECOMMENDED, MAY, and OPTIONAL, when
+   they appear in this document, are to be interpreted as described in
+   BCP 14, RFC 2119 [1].
+
+   Comparisons and arithmetic on Transport Sequence Numbers (TSNs) are
+   governed by the rules in Section 1.6 of RFC 2960 [2].
+
+3.  Protocol Changes to support PR-SCTP
+
+3.1.  Forward-TSN-Supported Parameter For INIT and INIT ACK
+
+   The following new OPTIONAL parameter is added to the INIT and INIT
+   ACK chunks.
+
+   Parameter Name                       Status     Type Value
+   -------------------------------------------------------------
+   Forward-TSN-Supported               OPTIONAL    49152 (0xC000)
+
+   At the initialization of the association, the sender of the INIT or
+   INIT ACK chunk MAY include this OPTIONAL parameter to inform its peer
+   that it is able to support the Forward TSN chunk (see Section 3.3 for
+   further details).  The format of this parameter is defined as
+   follows:
+
+    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |    Parameter Type = 49152     |  Parameter Length = 4         |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   Type: 16 bit u_int
+
+      49152, indicating Forward-TSN-Supported parameter
+
+   Length: 16 bit u_int
+
+      Indicates the size of the parameter, i.e., 4.
+
+3.2 Forward Cumulative TSN Chunk Definition (FORWARD TSN)
+
+   The following new chunk type is defined:
+
+   Chunk Type    Chunk Name
+   ------------------------------------------------------
+   192 (0xC0)    Forward Cumulative TSN (FORWARD TSN)
+
+
+
+
+Stewart, et al.             Standards Track                     [Page 5]
+
+RFC 3758           SCTP Partial Reliability Extension           May 2004
+
+
+   This chunk shall be used by the data sender to inform the data
+   receiver to adjust its cumulative received TSN point forward because
+   some missing TSNs are associated with data chunks that SHOULD NOT be
+   transmitted or retransmitted by the sender.
+
+   Forward Cumulative TSN chunk has the following format:
+
+    0                   1                   2                   3
+    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |   Type = 192  |  Flags = 0x00 |        Length = Variable      |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                      New Cumulative TSN                       |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |         Stream-1              |       Stream Sequence-1       |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   \                                                               /
+   /                                                               \
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |         Stream-N              |       Stream Sequence-N       |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   Chunk Flags:
+
+     Set to all zeros on transmit and ignored on receipt.
+
+   New Cumulative TSN: 32 bit u_int
+
+    This indicates the new cumulative TSN to the data receiver.  Upon
+    the reception of this value, the data receiver MUST consider
+    any missing TSNs earlier than or equal to this value as received,
+    and stop reporting them as gaps in any subsequent SACKs.
+
+   Stream-N: 16 bit u_int
+
+    This field holds a stream number that was skipped by this
+    FWD-TSN.
+
+   Stream Sequence-N: 16 bit u_int
+
+    This field holds the sequence number associated with the stream
+    that was skipped.  The stream sequence field holds the largest
+    stream sequence number in this stream being skipped.  The receiver
+    of the FWD-TSN's can use the Stream-N and Stream Sequence-N fields
+    to enable delivery of any stranded TSN's that remain on the stream
+    re-ordering queues.  This field MUST NOT report TSN's corresponding
+    to DATA chunks that are marked as unordered.  For ordered DATA
+    chunks this field MUST be filled in.
+
+
+
+Stewart, et al.             Standards Track                     [Page 6]
+
+RFC 3758           SCTP Partial Reliability Extension           May 2004
+
+
+3.3.  Negotiation of Forward-TSN-Supported parameter
+
+3.3.1.  Sending Forward-TSN-Supported param in INIT
+
+   If an SCTP endpoint supports the FORWARD TSN chunk, then any time it
+   sends an INIT during association establishment, it MAY include the
+   Forward-TSN-supported parameter in the INIT chunk to indicate this
+   fact to its peer.
+
+   Note that if the endpoint chooses NOT to include the parameter, then
+   at no time during the life of the association can it send or process
+   a FORWARD TSN.  It MUST instead act as if it does NOT support the
+   FORWARD TSN chunk, returning an ERROR to the peer upon receipt of any
+   FORWARD TSN.
+
+3.3.2.  Receipt of Forward-TSN-Supported parameter in INIT or INIT-ACK
+
+   When a receiver of an INIT detects a Forward-TSN-Supported parameter
+   and does not support the Forward-TSN chunk type, the receiver MUST
+   follow the rules defined in Section 3.3.3 of RFC 2960 [2].
+
+   When a receiver of an INIT-ACK detects a Forward-TSN-Supported
+   parameter and it does not support the Forward-TSN chunk type, the
+   receiver MUST follow the rules defined in Section 3.3.3 of RFC 2960
+   [2].
+
+   When a receiver of an INIT detects a Forward-TSN-Supported parameter
+   and it does support the Forward-TSN chunk type, the receiver MAY
+   respond with a Forward-TSN-supported parameter in the INIT-ACK chunk.
+
+   Note that if the endpoint chooses NOT to include the parameter, then
+   at no time during the life of the association can it send or process
+   a FORWARD TSN.  It MUST instead act as if it does NOT support the
+   FORWARD TSN chunk, returning an ERROR to the peer upon receipt of any
+   FORWARD TSN.
+
+   When an endpoint that supports the FORWARD TSN chunk receives an INIT
+   that does not contain the Forward-TSN-Supported Parameter, that
+   endpoint:
+
+   o  MAY include the Forward-TSN-Supported parameter in the INIT-ACK,
+   o  SHOULD record the fact that the peer does not support the FORWARD
+      TSN chunk,
+   o  MUST NOT send a FORWARD TSN chunk at any time during the
+      associations life,
+   o  SHOULD inform the upper layer if the upper layer has requested
+      such notification.
+
+
+
+
+Stewart, et al.             Standards Track                     [Page 7]
+
+RFC 3758           SCTP Partial Reliability Extension           May 2004
+
+
+3.3.3.  Receipt of Op. Error for Forward-TSN-Supported Param
+
+   When an SCTP endpoint that desires to use the FORWARD TSN chunk
+   feature for partially reliable data transfer receives an operational
+   error from the remote endpoint (either bundled with the COOKIE or as
+   an unrecognized parameter in the INIT-ACK), indicating that the
+   remote endpoint does not recognize the Forward-TSN-Supported
+   parameter, the local endpoint SHOULD inform its upper layer of the
+   remote endpoint's inability to support partially reliable data
+   transfer.
+
+   The local endpoint may then choose to either:
+
+   1) end the initiation process (in cases where the initiation process
+      has already ended, the endpoint may need to send an ABORT) in
+      consideration of the peer's inability to supply the requested
+      features for the new association, or
+
+   2) continue the initiation process (in cases where the initiation
+      process has already completed, the endpoint MUST just mark the
+      association as not supporting partial reliability), but with the
+      understanding that partially reliable data transmission is not
+      supported.  In this case, the endpoint receiving the operational
+      error SHOULD note that the FORWARD TSN chunk is not supported, and
+      MUST NOT transmit a FORWARD TSN chunk at any time during the life
+      of the association.
+
+3.4.  Definition of "abandoned" in the context of PR-SCTP
+
+   At some point, a sending PR-SCTP implementation MAY determine that a
+   particular data chunk SHOULD NOT be transmitted or retransmitted
+   further, in accordance with the rules governing some particular PR-
+   SCTP service definition (such as the definition of "timed
+   reliability" in Section 4.1.)  For purposes of this document, we
+   define the term "abandoned" to refer to any data chunk about which
+   the SCTP sender has made this determination.
+
+   Each PR-SCTP service defines the rules for determining when a TSN is
+   "abandoned", and accordingly, the rules that govern how, whether, and
+   when to "abandon" a TSN may vary from one service definition to
+   another.  However, the rules governing the actions taken when a TSN
+   is "abandoned" do NOT vary between service definitions; these rules
+   are included in Section 3.5.
+
+
+
+
+
+
+
+
+Stewart, et al.             Standards Track                     [Page 8]
+
+RFC 3758           SCTP Partial Reliability Extension           May 2004
+
+
+3.5.  Sender Side Implementation of PR-SCTP
+
+   The sender side implementation of PR-SCTP is identical to that of the
+   base SCTP protocol, except for:
+
+   o  actions a sending side PR-SCTP implementation must take when a TSN
+      is "abandoned" (as per the rules of whatever PR-SCTP service
+      definition is in effect)
+   o  special actions that a PR-SCTP implementation must take upon
+      receipt of SACK
+   o  rules governing the generation of FORWARD TSN chunks.
+
+   In detail, these exceptions are as follows:
+
+   A1) The sender maintains an "Advanced.Peer.Ack.Point" for each peer
+       to track a theoretical cumulative TSN point of the peer (Note,
+       this is a _new_ protocol variable and its value is NOT
+       necessarily the same as the SCTP "Cumulative TSN Ack Point" as
+       defined in Section 1.4 of RFC 2960 [2], and as discussed
+       throughout that document.)
+
+   A2) From time to time, as governed by the rules of a particular PR-
+       SCTP service definition (see Section 4), the SCTP data sender may
+       make a determination that a particular data chunk that has
+       already been assigned a TSN SHOULD be "abandoned".
+
+       When a data chunk is "abandoned", the sender MUST treat the data
+       chunk as being finally acked and no longer outstanding.
+
+       The sender MUST NOT credit an "abandoned" data chunk to the
+       partial_bytes_acked as defined in Section 7.2.2 of RFC 2960 [2],
+       and MUST NOT advance the cwnd based on this "abandoned" data
+       chunk.
+
+   A3) When a TSN is "abandoned", if it is part of a fragmented message,
+       all other TSN's within that fragmented message MUST be abandoned
+       at the same time.
+
+   A4) Whenever the data sender receives a SACK from the data receiver,
+       it MUST first process the SACK using the normal procedures as
+       defined in Section 6.2.1 of RFC 2960 [2].
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.             Standards Track                     [Page 9]
+
+RFC 3758           SCTP Partial Reliability Extension           May 2004
+
+
+   The data sender MUST then perform the following additional steps:
+
+       C1) Let SackCumAck be the Cumulative TSN ACK carried in the
+           received SACK.
+
+           If (Advanced.Peer.Ack.Point < SackCumAck), then update
+           Advanced.Peer.Ack.Point to be equal to SackCumAck.
+
+       C2) Try to further advance the "Advanced.Peer.Ack.Point" locally,
+           that is, to move "Advanced.Peer.Ack.Point" up as long as the
+           chunk next in the out-queue space is marked as "abandoned",
+           as shown in the following example:
+
+       Assuming that a SACK arrived with the Cumulative TSN ACK =
+       102 and the Advanced.Peer.Ack.Point is updated to this
+       value:
+
+       out-queue at the end of  ==>   out-queue after Adv.Ack.Point
+       normal SACK processing         local advancement
+
+                    ...                            ...
+       Adv.Ack.Pt-> 102 acked                      102 acked
+                    103 abandoned                    103 abandoned
+                    104 abandoned        Adv.Ack.P-> 104 abandoned
+                    105                            105
+                    106 acked                      106 acked
+                    ...                            ...
+
+       In this example, the data sender successfully advanced the
+       "Advanced.Peer.Ack.Point" from 102 to 104 locally.
+
+       C3) If, after step C1 and C2, the "Advanced.Peer.Ack.Point" is
+           greater than the Cumulative TSN ACK carried in the received
+           SACK, the data sender MUST send the data receiver a FORWARD
+           TSN chunk containing the latest value of the
+           "Advanced.Peer.Ack.Point".  Note that the sender MAY delay
+           the sending of a FORWARD TSN as defined in rule F2 below.
+           IMPLEMENTATION NOTE: It is an implementation decision as to
+           which destination address it is to be sent to, the only
+           restriction being that the address MUST be one that is
+           CONFIRMED.
+
+       C4) For each "abandoned" TSN, the sender of the FORWARD TSN MUST
+           determine if the chunk has a valid stream and sequence number
+           (i.e., it was ordered).  If the chunk has a valid stream and
+           sequence number, the sender MUST include the stream and
+           sequence number in the FORWARD TSN.  This information will
+           enable the receiver to easily find any stranded TSN's waiting
+
+
+
+Stewart, et al.             Standards Track                    [Page 10]
+
+RFC 3758           SCTP Partial Reliability Extension           May 2004
+
+
+           on stream reorder queues.  Each stream SHOULD only be
+           reported once; this means that if multiple abandoned messages
+           occur in the same stream, then only the highest abandoned
+           stream sequence number is reported.  If the total size of the
+           FORWARD TSN does NOT fit in a single MTU, then the sender of
+           the FORWARD TSN SHOULD lower the Advanced.Peer.Ack.Point to
+           the last TSN that will fit in a single MTU.
+
+       C5) If a FORWARD TSN is sent, the sender MUST assure that at
+           least one T3-rtx timer is running.  IMPLEMENTATION NOTE: Any
+           destination's timer may be used for the purposes of rule C5.
+
+   A5) Any time the T3-rtx timer expires, on any destination, the sender
+       SHOULD try to advance the "Advanced.Peer.Ack.Point" by following
+       the procedures outlined in C2 - C5.
+
+   The following additional rules govern the generation of FORWARD TSN
+   chunks:
+
+   F1) An endpoint MUST NOT use the FORWARD TSN for any purposes other
+       than circumstances described in this document.
+
+   F2) The data sender SHOULD always attempt to bundle an outgoing
+       FORWARD TSN with outbound DATA chunks for efficiency.
+
+       A sender MAY even choose to delay the sending of the FORWARD TSN
+       in the hope of bundling it with an outbound DATA chunk.
+
+       IMPLEMENTATION NOTE: An implementation may wish to limit the
+       number of duplicate FORWARD TSN chunks it sends by either only
+       sending a duplicate FORWARD TSN every other SACK or waiting a
+       full RTT before sending a duplicate FORWARD TSN.
+
+       IMPLEMENTATION NOTE: An implementation may allow the maximum
+       delay for generating a FORWARD TSN to be configured either
+       statically or dynamically in order to meet the specific timing
+       requirements of the protocol being carried, but see the next
+       rule:
+
+   F3) Any delay applied to the sending of FORWARD TSN chunk SHOULD NOT
+       exceed 200ms and MUST NOT exceed 500ms.  In other words, an
+       implementation MAY lower this value below 500ms but MUST NOT
+       raise it above 500ms.
+
+       NOTE: Delaying the sending of FORWARD TSN chunks may cause delays
+       in the receiver's ability to deliver other data being held at the
+       receiver for re-ordering.  The values of 200ms and 500ms match
+
+
+
+
+Stewart, et al.             Standards Track                    [Page 11]
+
+RFC 3758           SCTP Partial Reliability Extension           May 2004
+
+
+       the required values for the delayed acknowledgement in RFC 2960
+       [2] since delaying a FORWARD TSN has the same consequences but in
+       the reverse direction.
+
+   F4) The detection criterion for out-of-order SACKs MUST remain the
+       same as stated in RFC 2960, that is, a SACK is only considered
+       out-of-order if the Cumulative TSN ACK carried in the SACK is
+       earlier than that of the previous received SACK (i.e., the
+       comparison MUST NOT be made against "Advanced.Peer.Ack.Point").
+
+   F5) If the decision to "abandon" a chunk is made, no matter how such
+       a decision is made, the appropriate congestion adjustment MUST be
+       made as specified in RFC 2960 if the chunk would have been marked
+       for retransmission later (e.g., either by T3-Timeout or by Fast
+       Retransmit).
+
+3.6.  Receiver Side Implementation of PR-SCTP
+
+   The receiver side implementation of PR-SCTP at an SCTP endpoint A is
+   capable of supporting any PR-SCTP service definition used by the
+   sender at endpoint B, even if that service definition is not
+   supported by the sending side functionality of host A.  All that is
+   necessary is that the receiving side correctly handle the Forward-
+   TSN-Supported parameter as specified in Section 3.3, and correctly
+   handle the receipt of FORWARD TSN chunks as specified below.
+
+   DATA chunk arrival at a PR-SCTP receiver proceeds exactly as for DATA
+   chunk arrival at a base protocol SCTP receiver---that is, the
+   receiver MUST perform the same TSN handling, including duplicate
+   detection, gap detection, SACK generation, cumulative TSN
+   advancement, etc. as defined in RFC 2960 [2]---with the following
+   exceptions and additions.
+
+   When a FORWARD TSN chunk arrives, the data receiver MUST first update
+   its cumulative TSN point to the value carried in the FORWARD TSN
+   chunk, and then MUST further advance its cumulative TSN point locally
+   if possible, as shown by the following example:
+
+      Assuming that the new cumulative TSN carried in the arrived
+      FORWARD TSN is 103:
+
+       in-queue before processing      in-queue after processing
+            the FORWARD TSN      ==>   the FORWARD TSN and further
+                                                advancement
+
+
+
+
+
+
+
+Stewart, et al.             Standards Track                    [Page 12]
+
+RFC 3758           SCTP Partial Reliability Extension           May 2004
+
+
+       cum.TSN.Pt-> 102 received                   102 --
+                    103 missing                    103 --
+                    104 received                   104 --
+                    105 received      cum.TSN.Pt-> 105 received
+                    106 missing                    106 missing
+                    107 received                   107 received
+                    ...                            ...
+
+      In this example, the receiver's cumulative TSN point is first
+      updated to 103 and then further advanced to 105.
+
+   After the above processing, the data receiver MUST stop reporting any
+   missing TSNs earlier than or equal to the new cumulative TSN point.
+
+   Note, if the "New Cumulative TSN" value carried in the arrived
+   FORWARD TSN chunk is found to be behind or at the current cumulative
+   TSN point, the data receiver MUST treat this FORWARD TSN as out-of-
+   date and MUST NOT update its Cumulative TSN.  The receiver SHOULD
+   send a SACK to its peer (the sender of the FORWARD TSN) since such a
+   duplicate may indicate the previous SACK was lost in the network.
+
+   Any time a FORWARD TSN chunk arrives, for the purposes of sending a
+   SACK, the receiver MUST follow the same rules as if a DATA chunk had
+   been received (i.e., follow the delayed sack rules specified in RFC
+   2960 [2] section 6.2).
+
+   Whenever a DATA chunk arrives with the 'U' bit set to '0' (indicating
+   ordered delivery) and is out of order, the receiver must hold the
+   chunk for reordering.  Since it is possible with PR-SCTP that a DATA
+   chunk being waited upon will not be retransmitted, special actions
+   will need to be taken upon the arrival of a FORWARD TSN.
+
+   In particular, during processing of a FORWARD TSN, the receiver MUST
+   use the stream sequence information to examine all of the listed
+   stream reordering queues, and immediately make available for delivery
+   stream sequence numbers earlier than or equal to the stream sequence
+   number listed inside the FORWARD TSN.  Any such stranded data SHOULD
+   be made immediately available to the upper layer application.
+
+   An application using PR-SCTP receiving data should be aware of
+   possible missing messages.  The stream sequence number can be used,
+   in such a case, to determine that an intervening message has been
+   skipped.  When intervening messages are missing, it is an application
+   decision to process the messages or to take some other corrective
+   action.
+
+
+
+
+
+
+Stewart, et al.             Standards Track                    [Page 13]
+
+RFC 3758           SCTP Partial Reliability Extension           May 2004
+
+
+   After receiving and processing a FORWARD TSN, the data receiver MUST
+   take cautions in updating its re-assembly queue.  The receiver MUST
+   remove any partially reassembled message, which is still missing one
+   or more TSNs earlier than or equal to the new cumulative TSN point.
+   In the event that the receiver has invoked the partial delivery API,
+   a notification SHOULD also be generated to inform the upper layer API
+   that the message being partially delivered will NOT be completed.
+
+   Note that after receiving a FORWARD TSN and updating the cumulative
+   acknowledgement point, if a TSN that was skipped does arrive (i.e.,
+   due to network reordering), then the receiver will follow the normal
+   rules defined in RFC 2960 [2] for handling duplicate data.  This
+   implies that the receiver will drop the chunk and report it as a
+   duplicate in the next outbound SACK chunk.
+
+4.  Services provided by PR-SCTP to the upper layer
+
+   As described in Section 1.2, it is feasible to implement a variety of
+   partially reliable transport services using the new protocol
+   mechanisms introduced in Section 3; introducing these new services
+   requires making changes only at the sending side API, and the sending
+   side protocol implementation.  Thus, there may be a temptation to
+   standardize only the protocol, and leave the service definition as
+   "implementation specific" or leave it to be defined in
+   "informational" documents.
+
+   However, for those who may wish to write IETF standards for upper
+   layer protocols implemented over PR-SCTP, it is important to be able
+   to refer to a standard definition of services provided.  Therefore,
+   this section provides example definitions of one such service, while
+   also providing guidelines for the definition of additional services
+   as required.  Each such service may be proposed as a separate new
+   RFC.
+
+   Section 4 is organized as follows:
+
+   o  Section 4.1 provides the definition of one specific PR-SCTP
+      service: timed reliability.
+
+   o  Section 4.2 describes how a particular PR-SCTP service definition
+      is requested by the upper layer during association establishment,
+      and how the upper layer is notified if that request cannot be
+      satisfied.
+
+   o  Section 4.3 then provides guidelines for the specification of PR-
+      SCTP services other then the one defined in this memo.
+
+
+
+
+
+Stewart, et al.             Standards Track                    [Page 14]
+
+RFC 3758           SCTP Partial Reliability Extension           May 2004
+
+
+   o  Finally, Section 4.4 describes some additional usage notes that
+      upper layer protocol designers and implementors may find helpful.
+
+4.1.  PR-SCTP Service Definition for "timed reliability"
+
+   The "timed reliability" service is a natural extension of the
+   "lifetime" concept already present in the base SCTP protocol.
+
+   When this service is requested for an SCTP association, it changes
+   the meaning of the lifetime parameter specified in the SEND primitive
+   (see Section 10.1, part (E) of RFC 2960 [2]; note that the parameter
+   is spelled "life time" in that document.)
+
+   In the base SCTP protocol, the lifetime parameter is used to avoid
+   sending stale data.  When a lifetime value is indicated for a
+   particular message and that lifetime expires, SCTP cancels the
+   sending of this message, and notifies the ULP if the first
+   transmission of the data does not take place (because of rwnd or cwnd
+   limitations, or for any other reason).  However, in the base
+   protocol, if SCTP has sent the first transmission before the lifetime
+   expires, then the message MUST be sent as a normal reliable message.
+   During episodes of congestion this is particularly unfortunate, as
+   retransmission wastes bandwidth that could have been used for other
+   (non-lifetime expired) messages.
+
+   When the "timed reliability" service is invoked, this latter
+   restriction is removed.  Specifically, when the "timed reliability"
+   service is in effect, the following rules govern all messages that
+   are sent with a lifetime parameter:
+
+   TR1) If the lifetime parameter of a message is SCTP_LIFETIME_RELIABLE
+        (or unspecified see Section 5), that message is treated as a
+        normal reliable SCTP message, just as in the base SCTP protocol.
+
+   TR2) If the lifetime parameter is not SCTP_LIFETIME_RELIABLE (see
+        Section 5), then the SCTP sender MUST treat the message just as
+        if it were a normal reliable SCTP message, as long as the
+        lifetime has not yet expired.
+
+   TR3) Before assigning a TSN to any message, the SCTP sender MUST
+        evaluate the lifetime of that message.  If it is expired, the
+        SCTP sender MUST NOT assign a TSN to that message, but instead,
+        SHOULD issue a notification to the upper layer and abandon the
+        message.
+
+   TR4) Before transmitting or retransmitting a message for which a TSN
+        is already assigned, the SCTP sender MUST evaluate the lifetime
+        of the message.  If the lifetime of the message is expired, the
+
+
+
+Stewart, et al.             Standards Track                    [Page 15]
+
+RFC 3758           SCTP Partial Reliability Extension           May 2004
+
+
+        SCTP sender MUST "abandon" the message, as per the rules
+        specified in Section 3.5 marking that TSN as eligible for
+        forward TSN.  Note that this meets the requirement G1 defined in
+        Section 4.3.  IMPLEMENTATION NOTE: An implementation SHOULD
+        delay TSN assignment as mentioned in RFC 2960 [2] Section 10.1.
+        In such a case, the lifetime parameter should be checked BEFORE
+        assigning a TSN, thus allowing a message to be abandoned without
+        the need to send a FORWARD TSN.
+
+   TR5) The sending SCTP MAY evaluate the lifetime of messages at
+        anytime.  Expired messages that have not been assigned a TSN MAY
+        be handled as per rule TR3.  Expired messages that HAVE been
+        assigned a TSN MAY be handled as per rule TR4.
+
+   TR6) The sending application MUST NOT change the lifetime parameter
+        once the message is passed to the sending SCTP.
+
+   Implementation Note: Rules TR1 through TR4 are designed in such a way
+   as to avoid requiring the implementer to maintain a separate timer
+   for each message; instead, the lifetime need only be evaluated at
+   points in the life of the message where actions are already being
+   taken, such as TSN assignment, transmission, or expiration of a
+   retransmission timeout.  Rule TR5 is intended to give the SCTP
+   implementor flexibility to evaluate lifetime at any other convenient
+   opportunity, WITHOUT requiring that lifetime be evaluated immediately
+   at the point in time where it expires.
+
+4.2.  PR-SCTP Association Establishment
+
+   An upper layer protocol (ULP) that uses PR-SCTP may need to know
+   whether PR-SCTP can be supported on a given association.  Therefore,
+   the ULP needs to have some indication of whether the FORWARD-TSN
+   chunk is supported by its peer.
+
+   Section 10.1 of RFC 2960 [2] describes abstract primitives for the
+   ULP-to-SCTP interface, while noting that "individual implementations
+   must define their own exact format, and may provide combinations or
+   subsets of the basic functions in single calls."
+
+   In this section, we describe one additional return value that may be
+   added to the ASSOCIATE primitive to allow an SCTP service user to
+   indicate whether the FORWARD-TSN chunk is supported by its peer.
+
+   RFC 2960 indicates that the ASSOCIATE primitive "allows the upper
+   layer to initiate an association to a specific peer endpoint".  It is
+   structured as follows:
+
+
+
+
+
+Stewart, et al.             Standards Track                    [Page 16]
+
+RFC 3758           SCTP Partial Reliability Extension           May 2004
+
+
+   Format: ASSOCIATE(local SCTP instance name, destination transport
+         addr, outbound stream count)
+   -> association id [,destination transport addr list]
+      [,outbound stream count]
+
+   This extension adds one new OPTIONAL return value, such that the new
+   primitive reads as follows:
+
+   Format: ASSOCIATE(local SCTP instance name, destination transport
+         addr, outbound stream count )
+   -> association id [,destination transport addr list]
+      [,outbound stream count] [,forward tsn supported]
+
+   NOTE: As per RFC 2960, if the ASSOCIATE primitive is implemented as a
+   non-blocking call, the new OPTIONAL return value shall be passed with
+   the association parameters using the COMMUNICATION UP notification.
+
+   The new OPTIONAL parameter "forward tsn supported" is a boolean flag:
+
+   (0) false [default] indicates that FORWARD TSN is not enabled by both
+       endpoints.
+
+   (1) true indicates that FORWARD TSN is enabled on both endpoints.
+
+   We also add a new primitive to allow the user application to enable/
+   disable the PR-SCTP service on its endpoint before an association is
+   established.
+
+   Format: ENABLE_PRSCTP(local SCTP instance name, boolean enable)
+
+   The boolean parameter enable, if set to true, will enable PR-SCTP
+   upon future endpoint associations.  If the boolean parameter is set
+   to false, then the local endpoint will not advertise support of PR-
+   SCTP and thus disable the feature on future associations.  It is
+   recommended that this option be disabled by default, i.e., in order
+   to enable PR-SCTP, the user will need to call this API option with
+   the enable flag set to "true".
+
+4.3.  Guidelines for defining other PR-SCTP Services
+
+   Other PR-SCTP services may be defined and implemented as dictated by
+   the needs of upper layer protocols.  If such upper layer protocols
+   are to be standardized and require some particular PR-SCTP service
+   other than the one defined in this document (i.e., "timed
+   reliability"), then those additional PR-SCTP services should also be
+   specified and standardized in a new RFC.
+
+
+
+
+
+Stewart, et al.             Standards Track                    [Page 17]
+
+RFC 3758           SCTP Partial Reliability Extension           May 2004
+
+
+   It is suggested that any such additional service definitions be
+   modeled after the contents of Section 4.1.  In particular, the
+   service definition should provide:
+
+   1. A description of how the service user specifies any parameters
+      that need to be associated with a particular message (and/or any
+      other communication that takes place between the application and
+      the SCTP transport sender) that provides the SCTP transport sender
+      with the information needed to determine when to give up on
+      transmission of a particular message.
+
+      Preferably, this description should reference the primitives in
+      the abstract API provided in Section 10 of RFC 2960 [2],
+      indicating any:
+
+      *  changes to the interpretation of the existing parameters of
+         existing primitives,
+
+      *  additional parameters to be added to existing primitives (these
+         should be OPTIONAL, and default values should be indicated),
+
+      *  additional primitives that may be needed.
+
+   2. A description of the rules used by the sender side implementation
+      to determine when to give up on messages that have not yet been
+      assigned a TSN.  This description should also indicate what
+      protocol events trigger the evaluation, and what actions to take
+      (e.g., notifications.)
+
+   3. A description of the rules used by the sender side implementation
+      to determine when to give up on the transmission or retransmission
+      of messages that have already been assigned a TSN, and may have
+      been transmitted and possibly retransmitted zero or more times.
+
+   Items (2) and (3) in the list above should also indicate what
+   protocol events trigger the evaluation, and what actions to take if
+   the determination is made that the sender should give up on
+   transmitting the message (e.g., notifications to the ULP.)
+
+   Note that in any PR-SCTP service, the following rule MUST be
+   specified to avoid a protocol deadlock:
+
+   (G1) When the sender side implementation gives up on transmitting a
+        message that has been assigned a TSN (i.e., when that message is
+        "abandoned", as defined in Section 3.4), the sender side MUST
+        mark that TSN as eligible for forward TSN, and the rules in
+        Section 3.4 regarding the sending of FORWARD TSN chunks MUST be
+        followed.
+
+
+
+Stewart, et al.             Standards Track                    [Page 18]
+
+RFC 3758           SCTP Partial Reliability Extension           May 2004
+
+
+   Finally, a PR-SCTP service definition should specify a "canonical
+   service name" to uniquely identify the service, and distinguish it
+   from other PR-SCTP services.  This name can then be used in upper
+   layer protocol standards to indicate which PR-SCTP service definition
+   is required by that upper layer protocol.  It can also be used in the
+   documentation of APIs of PR-SCTP implementations to indicate how an
+   upper layer indicates which definition of PR-SCTP service should
+   apply.  The canonical service name for the PR-SCTP service defined in
+   Section 4.1 is "timed reliability".
+
+4.4.  Usage Notes
+
+   Detecting missing data in a PR-SCTP stream is useful for some
+   applications (e.g., Fibre channel or SCSI over IP).  With PR-SCTP,
+   this becomes possible - the upper layer simply needs to examine the
+   stream sequence number of the arrived user messages of that stream to
+   detect any missing data.  Note, this detection only works when all
+   the messages on that stream are sent in order, i.e., the "U" bit is
+   not set.
+
+5.  Variables
+
+   This section defines variables used throughout this document:
+
+   SCTP_LIFETIME_RELIABLE - A user interface indication defined by an
+   implementation and used to indicate when a message is to be
+   considered fully reliable.
+
+6.  Acknowledgments
+
+   The authors would like to thank Brian Bidulock, Scott Bradner, Jon
+   Berger, Armando L. Caro Jr., John Loughney, Jon Peterson, Ivan Arias
+   Rodriguez, Ian Rytina, Chip Sharp, and others for their comments.
+
+7.  Security Considerations
+
+   This document does not introduce any new security concerns to SCTP
+   other than the ones already documented in RFC 2960 [2].  In
+   particular, this document shares the same security issues as
+   unordered data within RFC 2960 [2] identified by RFC 3436 [4].  An
+   application using the PR-SCTP extension should not use transport
+   layer security; further details can be found in RFC 3436 [4].
+
+   Note that the ability to cause a message to be skipped (i.e, the
+   FORWARD TSN chunk) does not provide any new attack for a Man-In-the-
+   Middle (MIM), since the MIM already is capable of changing and/or
+   withholding data, thus effectively skipping messages.  However, the
+   FORWARD TSN chunk does provide a mechanism to make it easier for a
+
+
+
+Stewart, et al.             Standards Track                    [Page 19]
+
+RFC 3758           SCTP Partial Reliability Extension           May 2004
+
+
+   MIM to skip selective messages when the application has this feature
+   enabled since the MIM would have less state to maintain.
+
+8.  IANA Considerations
+
+   IANA has assigned 192 as a new chunk type to SCTP.
+
+   IANA has assigned 49152 as a new parameter type code to SCTP.
+
+9.  References
+
+9.1.  Normative References
+
+   [1]  Bradner, S., "Key words for use in RFCs to Indicate Requirement
+        Levels", BCP 14, RFC 2119, March 1997.
+
+   [2]  Stewart, R., Xie, Q., Morneault, K., Sharp, C., Schwarzbauer,
+        H., Taylor, T., Rytina, I., Kalla, M., Zhang, L. and V. Paxson,
+        "Stream Control Transmission Protocol", RFC 2960, October 2000.
+
+9.2.  Informative References
+
+   [3]  Clark, D. and D. Tennenhouse, "Architectural Considerations for
+        a New Generation of Protocols", SIGCOMM 1990 pp. 200-208,
+        September 1990.
+
+   [4]  Jungmaier, A., Rescorla, E. and M. Tuexen, "Transport Layer
+        Security over Stream Control Transmission Protocol", RFC 3436,
+        December 2002.
+
+10.  Authors' Addresses
+
+   Randall R. Stewart
+   Cisco Systems, Inc.
+   8725 West Higgins Road
+   Suite 300
+   Chicago, IL  60631
+   USA
+
+   Phone: +1-815-477-2127
+   EMail: rrs@cisco.com
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.             Standards Track                    [Page 20]
+
+RFC 3758           SCTP Partial Reliability Extension           May 2004
+
+
+   Michael A. Ramalho
+   Cisco Systems, Inc.
+   1802 Rue de la Porte
+   Wall Township, NJ  07719-3784
+   USA
+
+   Phone: +1.732.449.5762
+   EMail: mramalho@cisco.com
+
+
+   Qiaobing Xie
+   Motorola, Inc.
+   1501 W. Shure Drive, #2309
+   Arlington Heights, IL  60004
+   USA
+
+   Phone: +1-847-632-3028
+   EMail: qxie1@email.mot.com
+
+
+   Michael Tuexen
+   Univ. of Applied Sciences Muenster
+   Stegerwaldstr. 39
+   48565 Steinfurt
+   Germany
+
+   EMail: tuexen@fh-muenster.de
+
+
+   Phillip T. Conrad
+   University of Delaware
+   Department of Computer and Information Sciences
+   Newark, DE  19716
+   USA
+
+   Phone: +1 302 831 8622
+   EMail: conrad@acm.org
+   URI:   http://www.cis.udel.edu/~pconrad
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.             Standards Track                    [Page 21]
+
+RFC 3758           SCTP Partial Reliability Extension           May 2004
+
+
+11.  Full Copyright Statement
+
+   Copyright (C) The Internet Society (2004).  This document is subject
+   to the rights, licenses and restrictions contained in BCP 78, and
+   except as set forth therein, the authors retain all their rights.
+
+   This document and the information contained herein are provided on an
+   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
+   OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET
+   ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED,
+   INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
+   INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
+   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Intellectual Property
+
+   The IETF takes no position regarding the validity or scope of any
+   Intellectual Property Rights or other rights that might be claimed to
+   pertain to the implementation or use of the technology described in
+   this document or the extent to which any license under such rights
+   might or might not be available; nor does it represent that it has
+   made any independent effort to identify any such rights.  Information
+   on the procedures with respect to rights in RFC documents can be
+   found in BCP 78 and BCP 79.
+
+   Copies of IPR disclosures made to the IETF Secretariat and any
+   assurances of licenses to be made available, or the result of an
+   attempt made to obtain a general license or permission for the use of
+   such proprietary rights by implementers or users of this
+   specification can be obtained from the IETF on-line IPR repository at
+   http://www.ietf.org/ipr.
+
+   The IETF invites any interested party to bring to its attention any
+   copyrights, patents or patent applications, or other proprietary
+   rights that may cover technology that may be required to implement
+   this standard.  Please address the information to the IETF at ietf-
+   ipr@ietf.org.
+
+Acknowledgement
+
+   Funding for the RFC Editor function is currently provided by the
+   Internet Society.
+
+
+
+
+
+
+
+
+
+Stewart, et al.             Standards Track                    [Page 22]
+
diff --git a/doc/rfc3873.txt b/doc/rfc3873.txt
new file mode 100644
index 0000000..c583226
--- /dev/null
+++ b/doc/rfc3873.txt
@@ -0,0 +1,2579 @@
+
+
+
+
+
+
+Network Working Group                                          J. Pastor
+Request for Comments: 3873                                  M. Belinchon
+Category: Standards Track                                       Ericsson
+                                                          September 2004
+
+
+              Stream Control Transmission Protocol (SCTP)
+                   Management Information Base (MIB)
+
+Status of this Memo
+
+   This document specifies an Internet standards track protocol for the
+   Internet community, and requests discussion and suggestions for
+   improvements.  Please refer to the current edition of the "Internet
+   Official Protocol Standards" (STD 1) for the standardization state
+   and status of this protocol.  Distribution of this memo is unlimited.
+
+Copyright Notice
+
+   Copyright (C) The Internet Society (2004).
+
+
+Abstract
+
+   The Stream Control Transmission Protocol (SCTP) is a reliable
+   transport protocol operating on top of a connectionless packet
+   network such as IP.  It is designed to transport public switched
+   telephone network (PSTN) signaling messages over the connectionless
+   packet network, but is capable of broader applications.
+
+   This memo defines the Management Information Base (MIB) module which
+   describes the minimum set of objects needed to manage the
+   implementation of the SCTP.
+
+Table of Contents
+
+   1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  2
+       1.1.  Abbreviations. . . . . . . . . . . . . . . . . . . . . .  2
+   2.  The Internet-Standard Management Framework . . . . . . . . . .  3
+   3.  MIB Structure. . . . . . . . . . . . . . . . . . . . . . . . .  3
+       3.1.  SCTP Objects . . . . . . . . . . . . . . . . . . . . . .  4
+             3.1.1.  SCTP Statistics. . . . . . . . . . . . . . . . .  4
+             3.1.2.  SCTP Parameters. . . . . . . . . . . . . . . . .  5
+             3.1.3.  MIB Tables . . . . . . . . . . . . . . . . . . .  5
+                     3.1.3.1.  Association Table. . . . . . . . . . .  5
+                     3.1.3.2.  Reverse Lookup Table . . . . . . . . .  8
+       3.2.  Conformance. . . . . . . . . . . . . . . . . . . . . . .  9
+   4.  Definitions. . . . . . . . . . . . . . . . . . . . . . . . . .  9
+
+
+
+Pastor & Belinchon          Standards Track                     [Page 1]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+   5.  Compiling Notes. . . . . . . . . . . . . . . . . . . . . . . . 42
+   6.  References . . . . . . . . . . . . . . . . . . . . . . . . . . 42
+       6.1.  Normative References . . . . . . . . . . . . . . . . . . 42
+       6.2.  Informative References . . . . . . . . . . . . . . . . . 43
+   7.  Security Considerations. . . . . . . . . . . . . . . . . . . . 44
+   8.  Acknowledgments. . . . . . . . . . . . . . . . . . . . . . . . 45
+   9.  Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . 45
+   10. Full Copyright Statement . . . . . . . . . . . . . . . . . . . 46
+
+1.  Introduction
+
+   This memo defines the Management Information Base (MIB) module which
+   describes managed objects for implementations of the SCTP.
+
+   The document starts with a brief description of the SNMP framework
+   and continues with the MIB explanation and security consideration
+   sections among others.
+
+   The managed objects in this MIB module are based on [RFC2012] update:
+   "Management Information Base for the Transmission Control Protocol
+   (TCP)" referred as [TCPMIB] (work in progress), and RFC 3291 "Textual
+   Conventions for Internet Network Addresses" [RFC3291].
+
+   Terms related to the SCTP architecture are explained in [RFC2960].
+   Other specific abbreviations are listed below.
+
+   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
+   document are to be interpreted as described in [RFC2119].
+
+1.1.  Abbreviations
+
+   DNS   - Domain Name System
+   IANA  - Internet Assigned Numbers Authority
+   IETF  - Internet Engineering Task Force
+   IP    - Internet Protocol
+   MIB   - Management Information Base
+   RFC   - Request For Comments
+   RTO   - Retransmission Time Out
+   SCTP  - Stream Control Transmission Protocol
+   SMI   - Structure of Management Information
+   SNMP  - Simple Network Management Protocol
+   TCB   - Transmission Control Block
+   TCP   - Transmission Control Protocol
+
+
+
+
+
+
+
+Pastor & Belinchon          Standards Track                     [Page 2]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+2.  The Internet-Standard Management Framework
+
+   For a detailed overview of the documents that describe the current
+   Internet-Standard Management Framework, please refer to section 7 of
+   RFC 3410 [RFC3410].
+
+   Managed objects are accessed via a virtual information store, termed
+   the Management Information Base or MIB.  MIB objects are generally
+   accessed through the Simple Network Management Protocol (SNMP).
+   Objects in the MIB are defined using the mechanisms defined in the
+   Structure of Management Information (SMI).  This memo specifies a MIB
+   module that is compliant to the SMIv2, which is described in STD 58,
+   RFC 2578 [RFC2578], STD 58, RFC 2579 [RFC2579] and STD 58, RFC 2580
+   [RFC2580].
+
+3.  MIB Structure
+
+   This chapter explains the main objects this MIB defines.  A detailed
+   view of the MIB structure with the OID values is below.
+
+   MIB-2 {1 3 6 1 2 1}
+     +--(104)sctpMIB
+          |
+          +--(1) sctpObjects
+          |   |
+          |   +--(1) sctpStats
+          |   |   |
+          |   |   +-- <scalars>
+          |   |
+          |   +--(2)sctpParameters
+          |   |   |
+          |   |   +-- <scalars>
+          |   |
+          |   +--(3) sctpAssocTable
+          |   |
+          |   +--(4) sctpAssocLocalAddrTable
+          |   |
+          |   +--(5) sctpAssocRemAddrTable
+          |   |
+          |   +--(6) sctpLookupLocalPortTable
+          |   |
+          |   +--(7) sctpLookupRemPortTable
+          |   |
+          |   +--(8) sctpLookupRemHostNameTable
+          |   |
+          |   +--(9) sctpLookupRemPrimIPAddrTable
+          |   |
+          |   +--(10) sctpLookupRemIPAddrTable
+
+
+
+Pastor & Belinchon          Standards Track                     [Page 3]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+          |
+          |
+          +--(2)sctpMibConformance
+              |
+              +--(1) sctpMibCompliances
+              |   |
+              |   +--(1) sctpMibCompliance
+              |
+              +--(2) sctpMibGroups
+                  |
+                  +--(1) sctpLayerParamsGroup
+                  |
+                  +--(2) sctpStatsGroup
+                  |
+                  +--(3) sctpPerAssocParamsGroup
+                  |
+                  +--(4) sctpInverseGroup
+
+
+   The main groups are explained further in the MIB definition.
+
+3.1.  SCTP Objects
+
+   This branch contains the SCTP statistics and general parameters (both
+   of them scalars) and the SCTP MIB tables.
+
+3.1.1.  SCTP Statistics
+
+   The SCTP MIB includes both Counter32s and Counter64s to deal with
+   statistics.  Counter64s are used for those counters, which are likely
+   to wrap around in less than one hour, according to [RFC2863].
+
+   In addition Gauge32 is also used.
+
+3.1.1.1.  State-Related Statistics
+
+   These statistics are based on the TCP model, but adapted to the SCTP
+   states.  They store the number of successful association attempts,
+   how many associations have been initiated by the local or the remote
+   SCTP layer, and the number of associations terminated in a graceful
+   (by means of SHUTDOWN procedure) or ungraceful way (by means of CLOSE
+   procedure).
+
+3.1.1.2.  Statistics for traffic Measurements
+
+   This set of objects specifies statistics related to the whole SCTP
+   layer.  There are, e.g., statistics related to both SCTP packets and
+   SCTP chunks.
+
+
+
+Pastor & Belinchon          Standards Track                     [Page 4]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+   Statistics related to a specific association, or local/remote IP
+   addresses are defined inside their associated table.
+
+3.1.2.  SCTP Parameters
+
+   This section of the MIB contains the general variables for the SCTP
+   protocol.  Maximum, minimum, initial and default values are listed
+   here.
+
+   SCTP RTO mechanism definition is based on the TCP MIB [TCPMIB].  In
+   SCTP, only options 'other' and 'vanj' are valid since SCTP defines
+   Van Jacobson's algorithm (vanj) as the one to be used to calculate
+   RTO. 'Other' is left for future use.
+
+3.1.3.  MIB Tables
+
+   There are several tables included in the SCTP MIB.  The first group
+   deals with the SCTP association variables and is composed of a main
+   and two extended tables.  The second group is a bunch of tables used
+   to perform reverse lookups.
+
+   It is NOT possible to create rows in any table (sctpAssocTable,
+   sctpAssocLocalAddrTable, sctpRemAddrTable and Reverse Lookup tables)
+   using SNMP.
+
+   It is NOT possible to delete rows in any table using SNMP except in
+   sctpAssocTable under the particular conditions explained below.
+
+3.1.3.1.  Association Table
+
+   The sctpAssocTable  is the main MIB table, where all the association
+   related information is stored on a per association basis.  It is
+   structured according to expanded tables.  The main table is called
+   sctpAssocTable and is indexed by sctpAssocId (the association
+   identification).  This is a value that uniquely identifies an
+   association.  The MIB does not restrict what value must be written
+   here, however it must be unique within the table.
+
+   The sctpAssoc index is also shared by two more tables:
+      -  sctpAssocLocalAddrTable: to store the local IP address(es).
+      -  sctpAssocRemAddrTable: to store the remote addresses and the
+         per-remote-address related information.
+
+   Entries in the sctpAssocTable are created when trying to establish
+   the association, i.e., when sending the COOKIE-ECHO message
+   (originating side) or the COOKIE-ACK message (server side).  At this
+   point, i.e., at established state, all entry fields are filled in
+   with valid values.
+
+
+
+Pastor & Belinchon          Standards Track                     [Page 5]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+   Note: The following representation is a conceptual mode of describing
+   the relationship between the tables in this MIB.  Note that the real
+   relationship of the tables is by sharing an index, so tables are not
+   truly within tables.  Every entry is explained when defining the
+   corresponding objects in the MIB.
+
+   mib-2 {1 3 6 1 2 1}
+     +--(104)sctpMIB
+          |
+          +--(1) sctpObjects
+          |   |
+          .   .
+          .   .
+              |
+              +--(3) sctpAssocTable
+              |   |
+              |   +--(1) sctpAssocId (index)
+              |   |
+              |   +--(2) sctpAssocRemHostName
+              |   |
+              |   +--(3) sctpAssocLocalPort
+              |   |
+              |   +--(4) sctpAssocRemPort
+              |   |
+              |   +--(5) sctpAssocRemPrimAddrType
+              |   |
+              |   +--(6) sctpAssocRemPrimAddr
+              |   |
+              |   +--(7) sctpAssocHeartBeatInterval
+              |   |
+              |   +--(8) sctpAssocState
+              |   |
+              |   +--(9) sctpAssocInStreams
+              |   |
+              |   +--(10) sctpAssocOutStreams
+              |   |
+              |   +--(11) sctpAssocMaxRetr
+              |   |
+              |   +--(12) sctpAssocPrimProcess
+              |   |
+              |   +--(13) sctpAssocT1expireds
+              |   |
+              |   +--(14) sctpAssocT2expireds
+              |   |
+              |   +--(15) sctpAssocRtxChunks
+              |   |
+              |   +--(16) sctpAssocStartTime
+              |   |
+
+
+
+Pastor & Belinchon          Standards Track                     [Page 6]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+              |   +--(17) sctpAssocDiscontinuityTime
+              |
+              |
+              +--(4) sctpAssocLocalAddrTable
+              |   |
+              |   |--(-) sctpAssocId (shared index)
+              |   |
+              |   +--(1) sctpAssocLocalAddrType(index)
+              |   |
+              |   +--(2) sctpAssocLocalAddr (index)
+              |   |
+              |   +--(3) sctpAssocLocalAddrStartTime
+              |
+              |
+              +--(5) sctpAssocRemAddrTable
+              |   |
+              |   |--(-) sctpAssocId (shared index)
+              |   |
+              |   +--(1) sctpAssocRemAddrType (index)
+              .   |
+              .   +--(2) sctpAssocRemAddr (index)
+              .   |
+                  +--(3) sctpAssocRemAddrActive
+                  |
+                  +--(4) sctpAssocRemAddrHBActive
+                  |
+                  +--(5) sctpAssocRemAddrRTO
+                  |
+                  +--(6) sctpAssocRemAddrMaxPathRtx
+                  |
+                  +--(7) sctpAssocRemAddrRtx
+                  |
+                  +--(8) sctpAssocRemAddrStartTime
+
+   Both sctpAssocLocalAddrTable and sctpAssocRemAddrTable are indexed by
+   addresses.  'Addr' and 'AddrType' use the syntax InetAddress and
+   InetAddressType defined in the Textual Conventions for Internet
+   Network Address (RFC3291).  The InetAddressType TC has codepoints for
+   unknown, IPv4, IPv6, non-global IPv4, non-global IPv6, and DNS
+   addresses, but only the IPv4 and IPv6 address types are required to
+   be supported by implementations of this MIB module.  Implementations
+   that connect multiple zones are expected to support the non-global
+   IPv4 and non-global IPv6 address types as well.
+
+   Note that DNS addresses are not used in this MIB module.  They are
+   always resolved to the on-the-wire form prior to connection setup,
+   and the on-the-wire form is what appears in the MIB objects.
+
+
+
+
+Pastor & Belinchon          Standards Track                     [Page 7]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+   The sctpAssocLocalAddrTable table will have as many entries as local
+   IP addresses have been defined for the association.  The
+   sctpAssocRemAddrTable table will contain as many entries as remote IP
+   addresses are known to reach the peer.  For the multihoming concept
+   see reference RFC2960.
+
+   To keep the name of the remote peer (when provided by the peer at
+   initialization time), an entry has been created in the sctpAssocTable
+   called sctpAssocRemHostName.  When no DNS name is provided by the
+   remote endpoint, this value will be NULL (zero-length string).
+   Otherwise, the received DNS name will be stored here.
+
+   If it is necessary to abort an existing association, the value
+   deleteTCB(9) must be written in the variable sctpAssocState.  That is
+   the only way to delete rows in any of the mentioned tables.
+
+3.1.3.2.  Reverse Lookup Table
+
+   There are five reverse lookup tables to help management applications
+   efficiently access conceptual rows in other tables.  These tables
+   allow management applications to avoid expensive tree walks through
+   large numbers of associations.
+
+   All of these tables are optional.  If these tables are implemented,
+   an entry in them must be created after the entry in the main table
+   (sctpAssocTable) associated with it has been created.  This ensures
+   that the field indexing the lookup table exists.
+
+   The defined reverse lookup tables allow for performing a lookup using
+   the following variables:
+
+      -  Local Port: It allows a management application to find all the
+         associations that use a specific local port
+      -  Remote Port: It allows a management application to find all the
+         associations that use a specific remote port
+      -  Remote Host Name: It allows a management application to find
+         all the associations with a specific host name.
+      -  Remote Primary IP Address: It allows a management application
+         to find all the associations that use a specific remote IP
+         address as primary.
+      -  Remote IP address: a management application to find all the
+          associations that use a specific remote IP address.
+
+   As an example the picture below shows the table to look up by local
+   port.
+
+
+
+
+
+
+Pastor & Belinchon          Standards Track                     [Page 8]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+   MIB-2 {1 3 6 1 2 1}
+     +--(104)sctpMIB
+          |
+          +--(1) sctpObjects
+          |   |
+          .   .
+          .   .
+          |   |
+          |   +--(6) sctpLookupLocalPortTable
+          |   |   |
+          .   .   +--(-) sctpAssocLocalPort (shared index)
+          .   .   |
+                  +--(-) sctpAssocId (shared index)
+                  |
+                  +--(1) sctpLookupLocalPortStartTime
+
+   It is not possible for the operator to either create or delete rows
+   in these tables.  The rows in this table will dynamically appear and
+   be removed as the corresponding entries in sctpAssocTable are.
+
+3.2.  Conformance
+
+   The conformance section recommends all the inverse lookup tables in
+   this MIB as optional.  General layer and per association parameters
+   and statistics are considered mandatory.
+
+   IP addresses use the global IPv4 and global IPv6 address formats.
+   Unknown value and DNS name formats are not used.  Names, if present,
+   are stored in the sctpRemoteHostName variable.
+
+4.  Definitions
+
+   SCTP-MIB DEFINITIONS ::= BEGIN
+
+   IMPORTS
+     MODULE-IDENTITY, OBJECT-TYPE, Integer32, Unsigned32, Gauge32,
+     Counter32, Counter64, mib-2
+          FROM SNMPv2-SMI                        -- [RFC2578]
+     TimeStamp, TruthValue
+          FROM SNMPv2-TC                         -- [RFC2579]
+     MODULE-COMPLIANCE, OBJECT-GROUP
+          FROM SNMPv2-CONF                       -- [RFC2580]
+     InetAddressType, InetAddress, InetPortNumber
+          FROM INET-ADDRESS-MIB;                 -- [RFC3291]
+
+
+
+
+
+
+
+Pastor & Belinchon          Standards Track                     [Page 9]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+   sctpMIB MODULE-IDENTITY
+     LAST-UPDATED "200409020000Z"       -- 2nd September 2004
+     ORGANIZATION "IETF SIGTRAN Working Group"
+     CONTACT-INFO
+          "
+           WG EMail: sigtran@ietf.org
+
+           Web Page:
+                 http://www.ietf.org/html.charters/sigtran-charter.html
+
+           Chair:     Lyndon Ong
+                      Ciena Corporation
+                      0480 Ridgeview Drive
+                      Cupertino, CA  95014
+                      USA
+                      Tel:
+                      Email: lyong@ciena.com
+
+           Editors:   Maria-Carmen Belinchon
+                      R&D Department
+                      Ericsson Espana S. A.
+                      Via de los Poblados, 13
+                      28033 Madrid
+                      Spain
+                      Tel:   +34 91 339 3535
+                      Email: Maria.C.Belinchon@ericsson.com
+
+                      Jose-Javier Pastor-Balbas
+                      R&D Department
+                      Ericsson Espana S. A.
+                      Via de los Poblados, 13
+                      28033 Madrid
+                      Spain
+                      Tel:   +34 91 339 1397
+               Email: J.Javier.Pastor@ericsson.com
+          "
+     DESCRIPTION
+          "The MIB module for managing SCTP implementations.
+
+          Copyright (C) The Internet Society (2004).  This version of
+          this MIB module is part of RFC 3873; see the RFC itself for
+          full legal notices. "
+
+     REVISION "200409020000Z"       -- 2nd September 2004
+
+     DESCRIPTION " Initial version, published as RFC 3873"
+
+     ::= {  mib-2 104 }
+
+
+
+Pastor & Belinchon          Standards Track                    [Page 10]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+   -- the SCTP base variables group
+
+   sctpObjects OBJECT IDENTIFIER ::= { sctpMIB 1 }
+
+   sctpStats   OBJECT IDENTIFIER ::= { sctpObjects 1 }
+   sctpParams  OBJECT IDENTIFIER ::= { sctpObjects 2 }
+
+   -- STATISTICS
+   -- **********
+
+   -- STATE-RELATED STATISTICS
+
+   sctpCurrEstab OBJECT-TYPE
+     SYNTAX         Gauge32
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The number of associations for which the current state is
+          either ESTABLISHED, SHUTDOWN-RECEIVED or SHUTDOWN-PENDING."
+     REFERENCE
+          "Section 4 in RFC2960 covers the SCTP   Association state
+          diagram."
+
+     ::= { sctpStats 1 }
+
+
+   sctpActiveEstabs OBJECT-TYPE
+     SYNTAX         Counter32
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The number of times that associations have made a direct
+          transition to the ESTABLISHED state from the COOKIE-ECHOED
+          state: COOKIE-ECHOED -> ESTABLISHED. The upper layer initiated
+          the association attempt."
+     REFERENCE
+          "Section 4 in RFC2960 covers the SCTP   Association state
+          diagram."
+
+     ::= { sctpStats  2 }
+
+
+
+
+
+
+
+
+
+
+
+Pastor & Belinchon          Standards Track                    [Page 11]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+   sctpPassiveEstabs OBJECT-TYPE
+     SYNTAX         Counter32
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The number of times that associations have made a direct
+          transition to the ESTABLISHED state from the CLOSED state:
+          CLOSED -> ESTABLISHED. The remote endpoint initiated the
+          association attempt."
+     REFERENCE
+          "Section 4 in RFC2960 covers the SCTP   Association state
+          diagram."
+
+     ::= { sctpStats  3 }
+
+
+   sctpAborteds OBJECT-TYPE
+     SYNTAX         Counter32
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The number of times that associations have made a direct
+          transition to the CLOSED state from any state using the
+          primitive 'ABORT': AnyState --Abort--> CLOSED. Ungraceful
+          termination of the association."
+     REFERENCE
+          "Section 4 in RFC2960 covers the SCTP   Association state
+          diagram."
+
+     ::= { sctpStats  4 }
+
+
+   sctpShutdowns OBJECT-TYPE
+     SYNTAX         Counter32
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The number of times that associations have made a direct
+          transition to the CLOSED state from either the SHUTDOWN-SENT
+          state or the SHUTDOWN-ACK-SENT state. Graceful termination of
+          the association."
+     REFERENCE
+          "Section 4 in RFC2960 covers the SCTP   Association state
+          diagram."
+
+     ::= { sctpStats  5 }
+
+
+
+
+
+Pastor & Belinchon          Standards Track                    [Page 12]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+   -- OTHER LAYER STATISTICS
+
+   sctpOutOfBlues OBJECT-TYPE
+     SYNTAX         Counter32
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The number of out of the blue packets received by the host.
+          An out of the blue packet is an SCTP packet correctly formed,
+          including the proper checksum, but for which the receiver was
+          unable to identify an appropriate association."
+     REFERENCE
+          "Section 8.4 in RFC2960 deals with the Out-Of-The-Blue
+           (OOTB) packet definition and procedures."
+
+     ::= { sctpStats  6 }
+
+   sctpChecksumErrors OBJECT-TYPE
+     SYNTAX         Counter32
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The number of SCTP packets received with an invalid
+          checksum."
+     REFERENCE
+          "The checksum is located at the end of the SCTP packet as per
+          Section 3.1 in RFC2960. RFC3309 updates SCTP to use a 32 bit
+          CRC checksum."
+
+   ::= { sctpStats  7 }
+
+   sctpOutCtrlChunks OBJECT-TYPE
+     SYNTAX         Counter64
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The number of SCTP control chunks sent (retransmissions are
+          not included). Control chunks are those chunks different from
+          DATA."
+     REFERENCE
+          "Sections 1.3.5 and 1.4 in RFC2960 refer to control chunk as
+          those chunks different from those that contain user
+          information, i.e., DATA chunks."
+
+     ::= { sctpStats  8 }
+
+
+
+
+
+
+Pastor & Belinchon          Standards Track                    [Page 13]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+   sctpOutOrderChunks OBJECT-TYPE
+     SYNTAX         Counter64
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The number of SCTP ordered data chunks sent (retransmissions
+          are not included)."
+     REFERENCE
+          "Section 3.3.1 in RFC2960 defines the ordered data chunk."
+
+     ::= { sctpStats  9 }
+
+   sctpOutUnorderChunks OBJECT-TYPE
+     SYNTAX         Counter64
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The number of SCTP unordered chunks (data chunks in which the
+          U bit is set to 1) sent (retransmissions are not included)."
+     REFERENCE
+          "Section 3.3.1 in RFC2960 defines the unordered data chunk."
+
+     ::= { sctpStats  10 }
+
+   sctpInCtrlChunks OBJECT-TYPE
+     SYNTAX         Counter64
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The number of SCTP control chunks received (no duplicate
+          chunks included)."
+     REFERENCE
+          "Sections 1.3.5 and 1.4 in RFC2960 refer to control chunk as
+          those chunks different from those that contain user
+          information, i.e., DATA chunks."
+
+     ::= { sctpStats  11 }
+
+
+   sctpInOrderChunks OBJECT-TYPE
+     SYNTAX         Counter64
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The number of SCTP ordered data chunks received (no duplicate
+          chunks included)."
+
+
+
+
+
+Pastor & Belinchon          Standards Track                    [Page 14]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+     REFERENCE
+          "Section 3.3.1 in RFC2960 defines the ordered data chunk."
+
+     ::= { sctpStats  12 }
+
+
+   sctpInUnorderChunks OBJECT-TYPE
+     SYNTAX         Counter64
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The number of SCTP unordered chunks (data chunks in which the
+          U bit is set to 1) received (no duplicate chunks included)."
+     REFERENCE
+          "Section 3.3.1 in RFC2960 defines the unordered data chunk."
+
+     ::= { sctpStats  13 }
+
+
+
+   sctpFragUsrMsgs OBJECT-TYPE
+     SYNTAX         Counter64
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+
+          "The number of user messages that have to be fragmented
+          because of the MTU."
+
+     ::= { sctpStats  14 }
+
+
+   sctpReasmUsrMsgs OBJECT-TYPE
+     SYNTAX         Counter64
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The number of user messages reassembled, after conversion
+          into DATA chunks."
+     REFERENCE
+          "Section 6.9 in RFC2960 includes a description of the
+          reassembly process."
+
+     ::= { sctpStats  15 }
+
+
+
+
+
+
+
+Pastor & Belinchon          Standards Track                    [Page 15]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+   sctpOutSCTPPacks OBJECT-TYPE
+     SYNTAX         Counter64
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The number of SCTP packets sent. Retransmitted DATA chunks
+          are included."
+
+     ::= { sctpStats  16 }
+
+
+   sctpInSCTPPacks OBJECT-TYPE
+     SYNTAX         Counter64
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The number of SCTP packets received. Duplicates are
+          included."
+
+     ::= { sctpStats  17 }
+
+   sctpDiscontinuityTime OBJECT-TYPE
+     SYNTAX         TimeStamp
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The value of sysUpTime on the most recent occasion at which
+          any one or more of this general statistics counters suffered a
+          discontinuity.  The relevant counters are the specific
+          instances associated with this interface of any Counter32 or
+          Counter64 object contained in the SCTP layer statistics
+          (defined below sctpStats branch).  If no such discontinuities
+          have occurred since the last re-initialization of the local
+          management subsystem, then this object contains a zero value."
+     REFERENCE
+          "The inclusion of this object is recommended by RFC2578."
+
+     ::= { sctpStats 18 }
+
+
+   -- PROTOCOL GENERAL VARIABLES
+   -- **************************
+
+   sctpRtoAlgorithm OBJECT-TYPE
+     SYNTAX         INTEGER {
+                         other(1),      -- Other new one. Future use
+                         vanj(2)        -- Van Jacobson's algorithm
+                    }
+
+
+
+Pastor & Belinchon          Standards Track                    [Page 16]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The algorithm used to determine the timeout value (T3-rtx)
+          used for re-transmitting unacknowledged chunks."
+     REFERENCE
+          "Section 6.3.1 and 6.3.2 in RFC2960 cover the RTO calculation
+          and retransmission timer rules."
+     DEFVAL {vanj} -- vanj(2)
+
+     ::= { sctpParams 1 }
+
+
+   sctpRtoMin OBJECT-TYPE
+     SYNTAX         Unsigned32
+     UNITS          "milliseconds"
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The minimum value permitted by a SCTP implementation for the
+          retransmission timeout value, measured in milliseconds.  More
+          refined semantics for objects of this type depend upon the
+          algorithm used to determine the retransmission timeout value.
+
+          A retransmission time value of zero means immediate
+          retransmission.
+
+          The value of this object has to be lower than or equal to
+          stcpRtoMax's value."
+     DEFVAL {1000} -- milliseconds
+
+     ::= { sctpParams 2 }
+
+   sctpRtoMax OBJECT-TYPE
+     SYNTAX         Unsigned32
+     UNITS          "milliseconds"
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The maximum value permitted by a SCTP implementation for the
+          retransmission timeout value, measured in milliseconds.  More
+          refined semantics for objects of this type depend upon the
+          algorithm used to determine the retransmission timeout value.
+
+          A retransmission time value of zero means immediate re-
+          transmission.
+
+
+
+
+
+Pastor & Belinchon          Standards Track                    [Page 17]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+          The value of this object has to be greater than or equal to
+          stcpRtoMin's value."
+     DEFVAL {60000} -- milliseconds
+
+       ::= { sctpParams 3 }
+
+
+   sctpRtoInitial OBJECT-TYPE
+     SYNTAX         Unsigned32
+     UNITS          "milliseconds"
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The initial value for the retransmission timer.
+
+          A retransmission time value of zero means immediate re-
+          transmission."
+     DEFVAL {3000} -- milliseconds
+
+     ::= { sctpParams 4 }
+
+
+   sctpMaxAssocs OBJECT-TYPE
+     SYNTAX         Integer32 (-1 | 0..2147483647)
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The limit on the total number of associations the entity can
+          support. In entities where the maximum number of associations
+          is dynamic, this object should contain the value -1."
+
+     ::= { sctpParams 5 }
+
+
+   sctpValCookieLife OBJECT-TYPE
+     SYNTAX         Unsigned32
+     UNITS          "milliseconds"
+
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "Valid cookie life in the 4-way start-up handshake procedure."
+     REFERENCE
+          "Section 5.1.3 in RFC2960 explains the cookie generation
+          process. Recommended value is per section 14 in RFC2960."
+     DEFVAL {60000} -- milliseconds
+
+     ::= { sctpParams 6 }
+
+
+
+Pastor & Belinchon          Standards Track                    [Page 18]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+   sctpMaxInitRetr OBJECT-TYPE
+     SYNTAX         Unsigned32
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The maximum number of retransmissions at the start-up phase
+          (INIT and COOKIE ECHO chunks). "
+     REFERENCE
+          "Section 5.1.4, 5.1.6 in RFC2960 refers to Max.Init.Retransmit
+          parameter. Recommended value is per section 14 in RFC2960."
+     DEFVAL {8} -- number of attempts
+
+     ::= { sctpParams 7 }
+
+
+   -- TABLES
+   -- ******
+
+   -- the SCTP Association TABLE
+
+   -- The SCTP association table contains information about each
+   -- association in which the local endpoint is involved.
+
+
+   sctpAssocTable OBJECT-TYPE
+     SYNTAX         SEQUENCE OF SctpAssocEntry
+     MAX-ACCESS     not-accessible
+     STATUS         current
+     DESCRIPTION
+          "A table containing SCTP association-specific information."
+
+     ::= { sctpObjects 3 }
+
+
+   sctpAssocEntry OBJECT-TYPE
+     SYNTAX         SctpAssocEntry
+     MAX-ACCESS     not-accessible
+
+     STATUS         current
+     DESCRIPTION
+          "General common variables and statistics for the whole
+          association."
+     INDEX          { sctpAssocId }
+
+     ::= { sctpAssocTable 1 }
+
+
+
+
+
+
+Pastor & Belinchon          Standards Track                    [Page 19]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+   SctpAssocEntry ::= SEQUENCE {
+     sctpAssocId                        Unsigned32,
+     sctpAssocRemHostName               OCTET STRING,
+     sctpAssocLocalPort                 InetPortNumber,
+     sctpAssocRemPort                   InetPortNumber,
+     sctpAssocRemPrimAddrType           InetAddressType,
+     sctpAssocRemPrimAddr               InetAddress,
+     sctpAssocHeartBeatInterval         Unsigned32,
+     sctpAssocState                     INTEGER,
+     sctpAssocInStreams                 Unsigned32,
+     sctpAssocOutStreams                Unsigned32,
+     sctpAssocMaxRetr                   Unsigned32,
+     sctpAssocPrimProcess               Unsigned32,
+     sctpAssocT1expireds                Counter32,     -- Statistic
+     sctpAssocT2expireds                Counter32,     -- Statistic
+     sctpAssocRtxChunks                 Counter32,     -- Statistic
+     sctpAssocStartTime                 TimeStamp,
+     sctpAssocDiscontinuityTime         TimeStamp
+     }
+
+
+   sctpAssocId OBJECT-TYPE
+     SYNTAX         Unsigned32 (1..4294967295)
+     MAX-ACCESS     not-accessible
+     STATUS         current
+     DESCRIPTION
+          "Association Identification. Value identifying the
+          association. "
+
+     ::= { sctpAssocEntry 1 }
+
+
+   sctpAssocRemHostName OBJECT-TYPE
+     SYNTAX         OCTET STRING (SIZE(0..255))
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The peer's DNS name. This object needs to have the same
+          format as the encoding in the DNS protocol.  This implies that
+          the domain name can be up to 255 octets long, each octet being
+          0<=x<=255 as value with US-ASCII A-Z having a case insensitive
+          matching.
+
+          If no DNS domain name was received from the peer at init time
+          (embedded in the INIT or INIT-ACK chunk), this object is
+          meaningless. In such cases the object MUST contain a zero-
+          length string value. Otherwise, it contains the remote host
+          name received at init time."
+
+
+
+Pastor & Belinchon          Standards Track                    [Page 20]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+     ::= { sctpAssocEntry 2 }
+
+
+   sctpAssocLocalPort OBJECT-TYPE
+     SYNTAX         InetPortNumber (1..65535)
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The local SCTP port number used for this association."
+
+     ::= { sctpAssocEntry 3 }
+
+
+   sctpAssocRemPort OBJECT-TYPE
+     SYNTAX         InetPortNumber (1..65535)
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The remote SCTP port number used for this association."
+
+     ::= { sctpAssocEntry 4 }
+
+
+   sctpAssocRemPrimAddrType OBJECT-TYPE
+     SYNTAX         InetAddressType
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The internet type of primary remote IP address. "
+
+     ::= { sctpAssocEntry 5 }
+
+   sctpAssocRemPrimAddr OBJECT-TYPE
+     SYNTAX         InetAddress
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The primary remote IP address. The type of this address is
+          determined by the value of sctpAssocRemPrimAddrType.
+
+          The client side will know this value after INIT_ACK message
+          reception, the server side will know this value when sending
+          INIT_ACK message. However, values will be filled in at
+          established(4) state."
+
+     ::= { sctpAssocEntry 6 }
+
+
+
+
+
+Pastor & Belinchon          Standards Track                    [Page 21]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+   sctpAssocHeartBeatInterval OBJECT-TYPE
+     SYNTAX         Unsigned32
+     UNITS          "milliseconds"
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The current heartbeat interval..
+
+          Zero value means no HeartBeat, even when the concerned
+          sctpAssocRemAddrHBFlag object is true."
+     DEFVAL {30000} -- milliseconds
+
+     ::= { sctpAssocEntry 7 }
+
+
+   sctpAssocState OBJECT-TYPE
+     SYNTAX         INTEGER {
+                         closed(1),
+                         cookieWait(2),
+                         cookieEchoed(3),
+                         established(4),
+                         shutdownPending(5),
+                         shutdownSent(6),
+                         shutdownReceived(7),
+                         shutdownAckSent(8),
+                         deleteTCB(9)
+                         }
+     MAX-ACCESS     read-write
+     STATUS         current
+     DESCRIPTION
+          "The state of this SCTP association.
+
+          As in TCP, deleteTCB(9) is the only value that may be set by a
+          management station. If any other value is received, then the
+          agent must return a wrongValue error.
+
+          If a management station sets this object to the value
+          deleteTCB(9), then this has the effect of deleting the TCB (as
+          defined in SCTP) of the corresponding association on the
+          managed node, resulting in immediate termination of the
+          association.
+
+          As an implementation-specific option, an ABORT chunk may be
+          sent from the managed node to the other SCTP endpoint as a
+          result of setting the deleteTCB(9) value. The ABORT chunk
+          implies an ungraceful association shutdown."
+
+
+
+
+
+Pastor & Belinchon          Standards Track                    [Page 22]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+     REFERENCE
+
+          "Section 4 in RFC2960 covers the SCTP Association state
+          diagram."
+
+     ::= { sctpAssocEntry 8 }
+
+
+   sctpAssocInStreams OBJECT-TYPE
+     SYNTAX         Unsigned32 (1..65535)
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "Inbound Streams according to the negotiation at association
+          start up."
+     REFERENCE
+          "Section 1.3 in RFC2960 includes a definition of stream.
+          Section 5.1.1 in RFC2960 covers the streams negotiation
+          process."
+
+     ::= { sctpAssocEntry 9 }
+
+   sctpAssocOutStreams OBJECT-TYPE
+     SYNTAX         Unsigned32 (1..65535)
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "Outbound Streams according to the negotiation at association
+          start up. "
+     REFERENCE
+          "Section 1.3 in RFC2960 includes a definition of stream.
+          Section 5.1.1 in RFC2960 covers the streams negotiation
+          process."
+
+     ::= { sctpAssocEntry 10 }
+
+
+   sctpAssocMaxRetr OBJECT-TYPE
+     SYNTAX         Unsigned32
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The maximum number of data retransmissions in the association
+          context. This value is specific for each association and the
+          upper layer can change it by calling the appropriate
+          primitives. This value has to be smaller than the addition of
+          all the maximum number for all the paths
+          (sctpAssocRemAddrMaxPathRtx).
+
+
+
+Pastor & Belinchon          Standards Track                    [Page 23]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+          A value of zero value means no retransmissions."
+     DEFVAL {10} -- number of attempts
+
+     ::= { sctpAssocEntry 11 }
+
+   sctpAssocPrimProcess OBJECT-TYPE
+         SYNTAX      Unsigned32
+         MAX-ACCESS read-only
+         STATUS      current
+         DESCRIPTION
+          "This object identifies the system level process which holds
+          primary responsibility for the SCTP association.
+          Wherever possible, this should be the system's native unique
+          identification number. The special value 0 can be used to
+          indicate that no primary process is known.
+
+          Note that the value of this object can be used as a pointer
+          into the swRunTable of the HOST-RESOURCES-MIB(if the value is
+          smaller than 2147483647) or into the sysApplElmtRunTable of
+          the SYSAPPL-MIB."
+
+     ::= { sctpAssocEntry 12 }
+
+
+   -- Association Statistics
+
+   sctpAssocT1expireds OBJECT-TYPE
+     SYNTAX         Counter32
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The T1 timer determines how long to wait for an
+          acknowledgement after sending an INIT or COOKIE-ECHO chunk.
+          This object reflects the number of times the T1 timer expires
+          without having received the acknowledgement.
+
+          Discontinuities in the value of this counter can occur at re-
+          initialization of the management system, and at other times as
+          indicated by the value of sctpAssocDiscontinuityTime."
+     REFERENCE
+          "Section 5 in RFC2960."
+
+
+     ::= { sctpAssocEntry 13 }
+
+   sctpAssocT2expireds OBJECT-TYPE
+     SYNTAX         Counter32
+     MAX-ACCESS     read-only
+
+
+
+Pastor & Belinchon          Standards Track                    [Page 24]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+     STATUS         current
+     DESCRIPTION
+          "The T2 timer determines how long to wait for an
+          acknowledgement after sending a SHUTDOWN or SHUTDOWN-ACK
+          chunk. This object reflects the number of times that T2- timer
+          expired.
+
+          Discontinuities in the value of this counter can occur at re-
+          initialization of the management system, and at other times as
+          indicated by the value of sctpAssocDiscontinuityTime."
+   REFERENCE
+          "Section 9.2 in RFC2960."
+     ::= { sctpAssocEntry 14 }
+
+
+   sctpAssocRtxChunks OBJECT-TYPE
+     SYNTAX         Counter32
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "When T3-rtx expires, the DATA chunks that triggered the T3
+          timer will be re-sent according with the retransmissions
+          rules. Every DATA chunk that was included in the SCTP packet
+          that triggered the T3-rtx timer must be added to the value of
+          this counter.
+
+          Discontinuities in the value of this counter can occur at re-
+          initialization of the management system, and at other times as
+          indicated by the value of sctpAssocDiscontinuityTime."
+     REFERENCE
+          "Section 6 in RFC2960 covers the retransmission process and
+          rules."
+
+     ::= { sctpAssocEntry 15 }
+
+
+   sctpAssocStartTime OBJECT-TYPE
+     SYNTAX         TimeStamp
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The value of sysUpTime at the time that the association
+          represented by this row enters the ESTABLISHED state, i.e.,
+          the sctpAssocState object is set to established(4). The
+          value of this object will be zero:
+          - before the association enters the established(4)
+            state, or
+
+
+
+
+Pastor & Belinchon          Standards Track                    [Page 25]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+          - if the established(4) state was entered prior to
+            the last re-initialization of the local network management
+            subsystem."
+
+     ::= { sctpAssocEntry 16 }
+
+   sctpAssocDiscontinuityTime OBJECT-TYPE
+     SYNTAX         TimeStamp
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The value of sysUpTime on the most recent occasion at which
+          any one or more of this SCTP association counters suffered a
+          discontinuity.  The relevant counters are the specific
+          instances associated with this interface of any Counter32 or
+          Counter64 object contained in the sctpAssocTable or
+          sctpLocalAddrTable or sctpRemAddrTable.  If no such
+          discontinuities have occurred since the last re-initialization
+          of the local management subsystem, then this object contains a
+          zero value. "
+     REFERENCE
+          "The inclusion of this object is recommended by RFC2578."
+
+     ::= { sctpAssocEntry 17 }
+
+   -- Expanded tables: Including Multi-home feature
+
+   -- Local Address TABLE
+   -- *******************
+
+   sctpAssocLocalAddrTable OBJECT-TYPE
+     SYNTAX         SEQUENCE OF SctpAssocLocalAddrEntry
+     MAX-ACCESS     not-accessible
+     STATUS         current
+     DESCRIPTION
+          "Expanded table of sctpAssocTable based on the AssocId index.
+          This table shows data related to each local IP address which
+          is used by this association."
+
+     ::= { sctpObjects  4 }
+
+   sctpAssocLocalAddrEntry OBJECT-TYPE
+     SYNTAX         SctpAssocLocalAddrEntry
+     MAX-ACCESS     not-accessible
+     STATUS         current
+     DESCRIPTION
+          "Local information about the available addresses. There will
+          be an entry for every local IP address defined for this
+
+
+
+Pastor & Belinchon          Standards Track                    [Page 26]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+          association.
+          Implementors need to be aware that if the size of
+          sctpAssocLocalAddr exceeds 114 octets then OIDs of column
+          instances in this table will have more than 128 sub-
+          identifiers and cannot be accessed using SNMPv1, SNMPv2c, or
+          SNMPv3."
+     INDEX     {    sctpAssocId,   -- shared index
+                    sctpAssocLocalAddrType,
+                    sctpAssocLocalAddr }
+
+     ::= { sctpAssocLocalAddrTable 1 }
+
+
+   SctpAssocLocalAddrEntry ::= SEQUENCE {
+     sctpAssocLocalAddrType        InetAddressType,
+     sctpAssocLocalAddr            InetAddress,
+     sctpAssocLocalAddrStartTime   TimeStamp
+     }
+
+
+   sctpAssocLocalAddrType OBJECT-TYPE
+     SYNTAX         InetAddressType
+     MAX-ACCESS     not-accessible
+     STATUS         current
+     DESCRIPTION
+          "Internet type of local IP address used for this association."
+
+
+     ::= { sctpAssocLocalAddrEntry 1 }
+
+   sctpAssocLocalAddr OBJECT-TYPE
+     SYNTAX         InetAddress
+     MAX-ACCESS     not-accessible
+     STATUS         current
+     DESCRIPTION
+          "The value of a local IP address available for this
+          association. The type of this address is determined by the
+          value of sctpAssocLocalAddrType."
+
+     ::= { sctpAssocLocalAddrEntry 2 }
+
+
+
+
+
+
+
+
+
+
+
+Pastor & Belinchon          Standards Track                    [Page 27]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+   sctpAssocLocalAddrStartTime OBJECT-TYPE
+     SYNTAX         TimeStamp
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The value of sysUpTime at the time that this row was
+          created."
+
+     ::= { sctpAssocLocalAddrEntry 3 }
+
+   -- Remote Addresses TABLE
+   -- **********************
+
+   sctpAssocRemAddrTable OBJECT-TYPE
+     SYNTAX         SEQUENCE OF SctpAssocRemAddrEntry
+     MAX-ACCESS     not-accessible
+     STATUS         current
+     DESCRIPTION
+          "Expanded table of sctpAssocTable based on the AssocId index.
+          This table shows data related to each remote peer IP address
+          which is used by this association."
+
+     ::= { sctpObjects  5 }
+
+
+   sctpAssocRemAddrEntry OBJECT-TYPE
+     SYNTAX         SctpAssocRemAddrEntry
+     MAX-ACCESS     not-accessible
+     STATUS         current
+     DESCRIPTION
+          "Information about the most important variables for every
+          remote IP address. There will be an entry for every remote IP
+          address defined for this association.
+
+          Implementors need to be aware that if the size of
+          sctpAssocRemAddr exceeds 114 octets then OIDs of column
+          instances in this table will have more than 128 sub-
+          identifiers and cannot be accessed using SNMPv1, SNMPv2c, or
+          SNMPv3."
+     INDEX   { sctpAssocId,   -- shared index
+               sctpAssocRemAddrType,
+               sctpAssocRemAddr }
+
+     ::= { sctpAssocRemAddrTable 1 }
+
+
+
+
+
+
+
+Pastor & Belinchon          Standards Track                    [Page 28]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+   SctpAssocRemAddrEntry ::= SEQUENCE {
+     sctpAssocRemAddrType               InetAddressType,
+     sctpAssocRemAddr                   InetAddress,
+     sctpAssocRemAddrActive             TruthValue,
+     sctpAssocRemAddrHBActive           TruthValue,
+     sctpAssocRemAddrRTO                Unsigned32,
+     sctpAssocRemAddrMaxPathRtx         Unsigned32,
+     sctpAssocRemAddrRtx                Counter32,     -- Statistic
+     sctpAssocRemAddrStartTime          TimeStamp
+     }
+
+
+   sctpAssocRemAddrType OBJECT-TYPE
+     SYNTAX         InetAddressType
+     MAX-ACCESS     not-accessible
+     STATUS         current
+     DESCRIPTION
+          "Internet type of a remote IP address available for this
+          association."
+     ::= { sctpAssocRemAddrEntry 1 }
+
+
+   sctpAssocRemAddr OBJECT-TYPE
+     SYNTAX         InetAddress
+     MAX-ACCESS     not-accessible
+     STATUS         current
+     DESCRIPTION
+          "The value of a remote IP address available for this
+          association. The type of this address is determined by the
+          value of sctpAssocLocalAddrType."
+
+     ::= { sctpAssocRemAddrEntry 2 }
+
+
+   sctpAssocRemAddrActive OBJECT-TYPE
+     SYNTAX         TruthValue
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "This object gives information about the reachability of this
+          specific remote IP address.
+
+          When the object is set to 'true' (1), the remote IP address is
+          understood as Active. Active means that the threshold of no
+          answers received from this IP address has not been reached.
+
+
+
+
+
+
+Pastor & Belinchon          Standards Track                    [Page 29]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+          When the object is set to 'false' (2), the remote IP address
+          is understood as Inactive. Inactive means that either no
+          heartbeat or any other message was received from this address,
+          reaching the threshold defined by the protocol."
+
+     REFERENCE
+          "The remote transport states are defined as Active and
+          Inactive in the SCTP, RFC2960."
+
+     ::= { sctpAssocRemAddrEntry 3 }
+
+
+   sctpAssocRemAddrHBActive OBJECT-TYPE
+     SYNTAX         TruthValue
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "This object indicates whether the optional Heartbeat check
+          associated to one destination transport address is activated
+          or not (value equal to true or false, respectively). "
+
+     ::= { sctpAssocRemAddrEntry 4 }
+
+
+   sctpAssocRemAddrRTO OBJECT-TYPE -- T3-rtx- Timer
+     SYNTAX         Unsigned32
+     UNITS          "milliseconds"
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The current Retransmission Timeout. T3-rtx timer as defined
+          in the protocol SCTP."
+     REFERENCE
+          "Section 6.3 in RFC2960 deals with the Retransmission Timer
+          Management."
+
+     ::= { sctpAssocRemAddrEntry 5 }
+
+
+   sctpAssocRemAddrMaxPathRtx OBJECT-TYPE
+     SYNTAX         Unsigned32
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "Maximum number of DATA chunks retransmissions allowed to a
+          remote IP address before it is considered inactive, as defined
+          in RFC2960."
+
+
+
+
+Pastor & Belinchon          Standards Track                    [Page 30]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+     REFERENCE
+          "Section 8.2, 8.3 and 14 in RFC2960."
+     DEFVAL {5} -- number of attempts
+
+     ::= { sctpAssocRemAddrEntry 6 }
+
+
+   -- Remote Address Statistic
+
+   sctpAssocRemAddrRtx OBJECT-TYPE
+     SYNTAX         Counter32
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "Number of DATA chunks retransmissions to this specific IP
+          address. When T3-rtx expires, the DATA chunk that triggered
+          the T3 timer will be re-sent according to the retransmissions
+          rules. Every DATA chunk that is included in a SCTP packet and
+          was transmitted to this specific IP address before, will be
+          included in this counter.
+
+          Discontinuities in the value of this counter can occur at re-
+          initialization of the management system, and at other times as
+          indicated by the value of sctpAssocDiscontinuityTime."
+
+     ::= { sctpAssocRemAddrEntry 7 }
+
+   sctpAssocRemAddrStartTime OBJECT-TYPE
+     SYNTAX         TimeStamp
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The value of sysUpTime at the time that this row was
+          created."
+
+     ::= { sctpAssocRemAddrEntry 8 }
+
+   -- ASSOCIATION INVERSE TABLE
+   -- *************************
+
+   -- BY LOCAL PORT
+
+   sctpLookupLocalPortTable OBJECT-TYPE
+     SYNTAX         SEQUENCE OF SctpLookupLocalPortEntry
+     MAX-ACCESS     not-accessible
+     STATUS         current
+     DESCRIPTION
+          "With the use of this table, a list of associations which are
+
+
+
+Pastor & Belinchon          Standards Track                    [Page 31]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+          using the specified local port can be retrieved."
+
+     ::= { sctpObjects  6 }
+
+
+   sctpLookupLocalPortEntry OBJECT-TYPE
+     SYNTAX         SctpLookupLocalPortEntry
+     MAX-ACCESS     not-accessible
+     STATUS         current
+     DESCRIPTION
+          "This table is indexed by local port and association ID.
+          Specifying a local port, we would get a list of the
+          associations whose local port is the one specified."
+
+     INDEX         { sctpAssocLocalPort,
+                    sctpAssocId }
+
+     ::= { sctpLookupLocalPortTable 1 }
+
+
+   SctpLookupLocalPortEntry::= SEQUENCE {
+     sctpLookupLocalPortStartTime            TimeStamp
+     }
+
+
+   sctpLookupLocalPortStartTime OBJECT-TYPE
+     SYNTAX         TimeStamp
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The value of sysUpTime at the time that this row was created.
+
+          As the table will be created after the sctpAssocTable
+          creation, this value could be equal to the sctpAssocStartTime
+          object from the main table."
+
+     ::= { sctpLookupLocalPortEntry 1 }
+
+   -- BY REMOTE PORT
+
+   sctpLookupRemPortTable OBJECT-TYPE
+     SYNTAX         SEQUENCE OF SctpLookupRemPortEntry
+     MAX-ACCESS     not-accessible
+     STATUS         current
+
+
+
+
+
+
+
+Pastor & Belinchon          Standards Track                    [Page 32]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+     DESCRIPTION
+          "With the use of this table, a list of associations which are
+          using the specified remote port can be got"
+
+     ::= { sctpObjects  7 }
+
+   sctpLookupRemPortEntry OBJECT-TYPE
+     SYNTAX         SctpLookupRemPortEntry
+     MAX-ACCESS     not-accessible
+     STATUS         current
+     DESCRIPTION
+          "This table is indexed by remote port and association ID.
+          Specifying a remote port we would get a list of the
+          associations whose local port is the one specified "
+
+     INDEX         { sctpAssocRemPort,
+                    sctpAssocId }
+
+     ::= { sctpLookupRemPortTable 1 }
+
+   SctpLookupRemPortEntry::= SEQUENCE {
+     sctpLookupRemPortStartTime              TimeStamp
+     }
+
+
+   sctpLookupRemPortStartTime OBJECT-TYPE
+     SYNTAX         TimeStamp
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The value of sysUpTime at the time that this row was created.
+
+          As the table will be created after the sctpAssocTable
+          creation, this value could be equal to the sctpAssocStartTime
+          object from the main table."
+
+     ::= { sctpLookupRemPortEntry 1 }
+
+   -- BY REMOTE HOST NAME
+
+   sctpLookupRemHostNameTable OBJECT-TYPE
+     SYNTAX         SEQUENCE OF SctpLookupRemHostNameEntry
+     MAX-ACCESS     not-accessible
+     STATUS         current
+     DESCRIPTION
+          "With the use of this table, a list of associations with that
+          particular host can be retrieved."
+
+
+
+
+Pastor & Belinchon          Standards Track                    [Page 33]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+     ::= { sctpObjects  8 }
+
+
+   sctpLookupRemHostNameEntry OBJECT-TYPE
+     SYNTAX         SctpLookupRemHostNameEntry
+     MAX-ACCESS     not-accessible
+     STATUS         current
+     DESCRIPTION
+          "This table is indexed by remote host name and association ID.
+          Specifying a host name we would get a list of the associations
+          specifying that host name as the remote one.
+
+          Implementors need to be aware that if the size of
+          sctpAssocRemHostName exceeds 115 octets then OIDs of column
+          instances in this table will have more than 128 sub-
+          identifiers and cannot be accessed using SNMPv1, SNMPv2c, or
+          SNMPv3."
+
+     INDEX         { sctpAssocRemHostName,
+                    sctpAssocId }
+
+     ::= { sctpLookupRemHostNameTable 1 }
+
+
+   SctpLookupRemHostNameEntry::= SEQUENCE {
+     sctpLookupRemHostNameStartTime               TimeStamp
+     }
+
+   sctpLookupRemHostNameStartTime OBJECT-TYPE
+     SYNTAX         TimeStamp
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The value of sysUpTime at the time that this row was created.
+
+          As the table will be created after the sctpAssocTable
+          creation, this value could be equal to the sctpAssocStartTime
+          object from the main table."
+
+     ::= { sctpLookupRemHostNameEntry 1 }
+
+
+
+
+
+
+
+
+
+
+
+Pastor & Belinchon          Standards Track                    [Page 34]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+   -- BY REMOTE PRIMARY IP ADDRESS
+
+   sctpLookupRemPrimIPAddrTable OBJECT-TYPE
+     SYNTAX         SEQUENCE OF SctpLookupRemPrimIPAddrEntry
+     MAX-ACCESS     not-accessible
+     STATUS         current
+     DESCRIPTION
+          "With the use of this table, a list of associations that have
+          the specified IP address as primary within the remote set of
+          active addresses can be retrieved."
+
+     ::= { sctpObjects  9 }
+
+
+   sctpLookupRemPrimIPAddrEntry OBJECT-TYPE
+     SYNTAX         SctpLookupRemPrimIPAddrEntry
+     MAX-ACCESS     not-accessible
+     STATUS         current
+     DESCRIPTION
+          "This table is indexed by primary address and association ID.
+          Specifying a primary address, we would get a list of the
+          associations that have the specified remote IP address marked
+          as primary.
+          Implementors need to be aware that if the size of
+          sctpAssocRemPrimAddr exceeds 114 octets then OIDs of column
+          instances in this table will have more than 128 sub-
+          identifiers and cannot be accessed using SNMPv1, SNMPv2c, or
+          SNMPv3."
+
+     INDEX         { sctpAssocRemPrimAddrType,
+                    sctpAssocRemPrimAddr,
+                    sctpAssocId }
+
+     ::= { sctpLookupRemPrimIPAddrTable 1 }
+
+   SctpLookupRemPrimIPAddrEntry::= SEQUENCE {
+     sctpLookupRemPrimIPAddrStartTime             TimeStamp
+     }
+
+
+   sctpLookupRemPrimIPAddrStartTime OBJECT-TYPE
+     SYNTAX         TimeStamp
+     MAX-ACCESS     read-only
+     STATUS         current
+
+
+
+
+
+
+
+Pastor & Belinchon          Standards Track                    [Page 35]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+     DESCRIPTION
+          "The value of SysUpTime at the time that this row was created.
+
+          As the table will be created after the sctpAssocTable
+          creation, this value could be equal to the sctpAssocStartTime
+          object from the main table."
+
+     ::= { sctpLookupRemPrimIPAddrEntry 1 }
+
+
+   -- BY REMOTE IP ADDRESS
+
+   sctpLookupRemIPAddrTable OBJECT-TYPE
+     SYNTAX         SEQUENCE OF SctpLookupRemIPAddrEntry
+     MAX-ACCESS     not-accessible
+     STATUS         current
+     DESCRIPTION
+          "With the use of this table, a list of associations that have
+          the specified IP address as one of the remote ones can be
+          retrieved. "
+
+     ::= { sctpObjects  10 }
+
+
+   sctpLookupRemIPAddrEntry OBJECT-TYPE
+     SYNTAX         SctpLookupRemIPAddrEntry
+     MAX-ACCESS     not-accessible
+     STATUS         current
+     DESCRIPTION
+          "This table is indexed by a remote IP address and association
+          ID. Specifying an IP address we would get a list of the
+          associations that have the specified IP address included
+          within the set of remote IP addresses."
+
+     INDEX         { sctpAssocRemAddrType,
+                    sctpAssocRemAddr,
+                    sctpAssocId }
+
+     ::= { sctpLookupRemIPAddrTable 1 }
+
+
+   SctpLookupRemIPAddrEntry::= SEQUENCE {
+
+     sctpLookupRemIPAddrStartTime            TimeStamp
+     }
+
+
+
+
+
+
+Pastor & Belinchon          Standards Track                    [Page 36]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+   sctpLookupRemIPAddrStartTime OBJECT-TYPE
+     SYNTAX         TimeStamp
+     MAX-ACCESS     read-only
+     STATUS         current
+     DESCRIPTION
+          "The value of SysUpTime at the time that this row was created.
+
+          As the table will be created after the sctpAssocTable
+          creation, this value could be equal to the sctpAssocStartTime
+          object from the main table."
+
+     ::= { sctpLookupRemIPAddrEntry 1 }
+
+
+   -- 4.1 Conformance Information
+
+   sctpMibConformance    OBJECT IDENTIFIER ::= { sctpMIB 2 }
+   sctpMibCompliances    OBJECT IDENTIFIER ::= { sctpMibConformance 1 }
+   sctpMibGroups         OBJECT IDENTIFIER ::= { sctpMibConformance 2 }
+
+
+   -- 4.1.1 Units of conformance
+
+   --
+   -- MODULE GROUPS
+   --
+
+   sctpLayerParamsGroup OBJECT-GROUP
+     OBJECTS   { sctpRtoAlgorithm,
+                 sctpRtoMin,
+                 sctpRtoMax,
+                 sctpRtoInitial,
+                 sctpMaxAssocs,
+                 sctpValCookieLife,
+                 sctpMaxInitRetr
+               }
+
+     STATUS    current
+     DESCRIPTION
+          "Common parameters for the SCTP layer, i.e., for all the
+          associations. They can usually be referred to as configuration
+          parameters."
+
+     ::= { sctpMibGroups 1 }
+
+
+
+
+
+
+
+Pastor & Belinchon          Standards Track                    [Page 37]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+   sctpStatsGroup OBJECT-GROUP
+     OBJECTS   { sctpCurrEstab,
+                 sctpActiveEstabs,
+                 sctpPassiveEstabs,
+                 sctpAborteds,
+                 sctpShutdowns,
+                 sctpOutOfBlues,
+                 sctpChecksumErrors,
+                 sctpOutCtrlChunks,
+                 sctpOutOrderChunks,
+                 sctpOutUnorderChunks,
+                 sctpInCtrlChunks,
+                 sctpInOrderChunks,
+                 sctpInUnorderChunks,
+                 sctpFragUsrMsgs,
+                 sctpReasmUsrMsgs,
+                 sctpOutSCTPPacks,
+                 sctpInSCTPPacks,
+                 sctpDiscontinuityTime,
+                 sctpAssocT1expireds,
+                 sctpAssocT2expireds,
+                 sctpAssocRtxChunks,
+                 sctpAssocRemAddrRtx
+               }
+
+     STATUS    current
+     DESCRIPTION
+          "Statistics group. It includes the objects to collect state
+          changes in the SCTP protocol local layer and flow control
+          statistics."
+
+     ::= { sctpMibGroups 2 }
+
+
+   sctpPerAssocParamsGroup OBJECT-GROUP
+     OBJECTS   { sctpAssocRemHostName,
+                 sctpAssocLocalPort,
+                 sctpAssocRemPort,
+                 sctpAssocRemPrimAddrType,
+                 sctpAssocRemPrimAddr,
+                 sctpAssocHeartBeatInterval,
+                 sctpAssocState,
+                 sctpAssocInStreams,
+                 sctpAssocOutStreams,
+                 sctpAssocMaxRetr,
+                 sctpAssocPrimProcess,
+                 sctpAssocStartTime,
+                 sctpAssocDiscontinuityTime,
+
+
+
+Pastor & Belinchon          Standards Track                    [Page 38]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+                 sctpAssocLocalAddrStartTime,
+                 sctpAssocRemAddrActive,
+                 sctpAssocRemAddrHBActive,
+                 sctpAssocRemAddrRTO,
+                 sctpAssocRemAddrMaxPathRtx,
+                 sctpAssocRemAddrStartTime
+               }
+
+     STATUS    current
+     DESCRIPTION
+          "The SCTP group of objects to manage per-association
+          parameters. These variables include all the SCTP basic
+          features."
+
+     ::= { sctpMibGroups 3 }
+
+   sctpPerAssocStatsGroup OBJECT-GROUP
+                 OBJECTS
+               { sctpAssocT1expireds,
+                 sctpAssocT2expireds,
+                 sctpAssocRtxChunks,
+                 sctpAssocRemAddrRtx
+               }
+
+     STATUS    current
+     DESCRIPTION
+          "Per Association Statistics group. It includes the objects to
+          collect flow control statistics per association."
+
+     ::= { sctpMibGroups 4 }
+
+   sctpInverseGroup OBJECT-GROUP
+     OBJECTS   { sctpLookupLocalPortStartTime,
+                sctpLookupRemPortStartTime,
+                sctpLookupRemHostNameStartTime,
+                sctpLookupRemPrimIPAddrStartTime,
+                sctpLookupRemIPAddrStartTime
+               }
+
+     STATUS    current
+     DESCRIPTION
+          "Objects used in the inverse lookup tables."
+
+     ::= { sctpMibGroups 5 }
+
+
+
+
+
+
+
+Pastor & Belinchon          Standards Track                    [Page 39]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+   -- 4.1.2 Compliance Statements
+
+   --
+   -- MODULE COMPLIANCES
+   --
+
+   sctpMibCompliance MODULE-COMPLIANCE
+     STATUS  current
+     DESCRIPTION
+          "The compliance statement for SNMP entities which implement
+          this SCTP MIB Module.
+
+          There are a number of INDEX objects that cannot be represented
+          in the form of OBJECT clauses in SMIv2, but for which we have
+          the following compliance requirements, expressed in OBJECT
+          clause form in this description clause:
+
+   -- OBJECT        sctpAssocLocalAddrType
+   -- SYNTAX        InetAddressType {ipv4(1), ipv6(2)}
+   -- DESCRIPTION
+   --       It is only required to have IPv4 and IPv6 addresses without
+   --       zone indices.
+   --       The address with zone indices is required if an
+   --       implementation can connect multiple zones.
+   --
+   -- OBJECT        sctpAssocLocalAddr
+   -- SYNTAX        InetAddress (SIZE(4|16))
+   -- DESCRIPTION
+   --       An implementation is only required to support globally
+   --       unique IPv4 and IPv6 addresses.
+   --
+   -- OBJECT        sctpAssocRemAddrType
+   -- SYNTAX        InetAddressType {ipv4(1), ipv6(2)}
+   -- DESCRIPTION
+   --       It is only required to have IPv4 and IPv6 addresses without
+   --       zone indices.
+   --       The address with zone indices is required if an
+   --       implementation can connect multiple zones.
+   --
+   -- OBJECT        sctpAssocRemAddr
+   -- SYNTAX        InetAddress (SIZE(4|16))
+   -- DESCRIPTION
+   --       An implementation is only required to support globally
+   --       unique IPv4 and IPv6 addresses.
+   --
+          "  -- closes DESCRIPTION clause of MODULE-COMPLIANCE
+
+     MODULE  -- this module
+
+
+
+Pastor & Belinchon          Standards Track                    [Page 40]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+          MANDATORY-GROUPS    {  sctpLayerParamsGroup,
+                                 sctpPerAssocParamsGroup,
+                                 sctpStatsGroup,
+                                 sctpPerAssocStatsGroup
+                              }
+
+          OBJECT  sctpAssocRemPrimAddrType
+          SYNTAX  InetAddressType { ipv4(1),
+                                    ipv6(2)
+                                  }
+          DESCRIPTION
+               "It is only required to have IPv4 and IPv6 addresses
+               without zone indices.
+
+               The address with zone indices is required if an
+               implementation can connect multiple zones."
+
+          OBJECT  sctpAssocRemPrimAddr
+          SYNTAX  InetAddress (SIZE(4|16))
+          DESCRIPTION
+               "An implementation is only required to support globally
+               unique IPv4 and globally unique IPv6 addresses."
+
+
+          OBJECT sctpAssocState
+          WRITE-SYNTAX  INTEGER { deleteTCB(9) }
+          MIN-ACCESS read-only
+          DESCRIPTION
+               "Only the deleteTCB(9) value MAY be set by a management
+               station at most. A read-only option is also considered to
+               be compliant with this MIB module description."
+
+          GROUP sctpInverseGroup
+          DESCRIPTION
+               "Objects used in inverse lookup tables. This should be
+               implemented, at the discretion of the implementers, for
+               easier lookups in the association tables"
+
+     ::= { sctpMibCompliances 1 }
+
+   END
+
+
+
+
+
+
+
+
+
+
+Pastor & Belinchon          Standards Track                    [Page 41]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+5.  Compiling Notes
+
+   When compiling the MIB module warnings similar to the following may
+   occur:
+
+      -  warning: index of row `sctpAssocLocalAddrEntry' can exceed OID
+         size limit by 141 subidentifier(s)
+      -  warning: index of row `sctpAssocRemAddrEntry' can exceed OID
+         size limit by 141 subidentifier(s)
+      -  warning: index of row `sctpLookupRemHostNameEntry' can exceed
+         OID size limit by 140 subidentifier(s)
+      -  warning: index of row `sctpLookupRemPrimIPAddrEntry' can exceed
+         OID size limit by 141 subidentifier(s)
+      -  warning: index of row `sctpLookupRemIPAddrEntry' can exceed OID
+         size limit by 141 subidentifier(s)
+
+   These warnings are due to the fact that the row objects have index
+   objects of type InetAddress or OCTET STRING whose size limit is 255
+   octets, and if that size limit were reached the names of column
+   instances in those rows would exceed the 128 sub-identifier limit
+   imposed by current versions of the SNMP.  Actual limitations for the
+   index object sizes are noted in the conceptual row DESCRIPTION
+   clauses.  For the InetAddress index objects these size limits will
+   not be reached with any of the address types in current use.
+
+6.  References
+
+6.1.  Normative References
+
+   [RFC2578]    McCloghrie, K., Perkins, D., and J. Schoenwaelder,
+                "Structure of Management Information Version 2 (SMIv2)",
+                STD 58, RFC 2578, April 1999.
+
+   [RFC2579]    McCloghrie, K., Perkins, D., and J. Schoenwaelder,
+                "Textual Conventions for SMIv2", STD 58, RFC 2579, April
+                1999.
+
+   [RFC2580]    McCloghrie, K., Perkins, D., and J. Schoenwaelder,
+                "Conformance Statements for SMIv2", STD 58, RFC 2580,
+                April 1999.
+
+   [RFC2960]    Stewart, R., Xie, Q., Morneault, K., Sharp, C.,
+                Schwarzbauer, H., Taylor, T., Rytina, I., Kalla, M.,
+                Zhang, L., and V. Paxson, "Stream Control Transmission
+                Protocol", RFC 2960, October 2000.
+
+
+
+
+
+
+Pastor & Belinchon          Standards Track                    [Page 42]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+   [RFC3291]    Daniele, M., Haberman, B., Routhier, S., and J.
+                Schoenwaelder, "Textual Conventions for Internet Network
+                Addresses", RFC 3291, May 2002.
+
+   [RFC3309]    Stone, J., Stewart, R., and D. Otis, "Stream Control
+                Transmission Protocol (SCTP) Checksum Change", RFC 3309,
+                September 2002.
+
+6.2.  Informative References
+
+   [RFC1213]    McCloghrie, K. and M. Rose, "Management Information Base
+                for Network Management of TCP/IP-based internets:MIB-
+                II", STD 17, RFC 1213, March 1991.
+
+   [RFC2012]    McCloghrie, K., "SNMPv2 Management Information Base for
+                the Transmission Control Protocol using SMIv2", RFC
+                2012, November 1996.
+
+   [RFC3410]    Case, J., Mundy, R., Partain, D., and B. Stewart,
+                "Introduction and Applicability Statements for
+                Internet-Standard Management Framework", RFC 3410,
+                December 2002.
+
+   [VANJ]       Jacobson, V., "Congestion Avoidance and Control",
+                SIGCOMM 1988, Stanford, California.
+
+   [IPv6ARCH]   Deering, S., Haberman, B., Jinmei, T., Nordmark, E.,
+                Onoe, A., and B. Zill, "IPv6 Scoped Address
+                Architecture", Work in Progress, December 2002.
+
+   [sctpImplem] Stewart, R., Ong, L., Arias-Rodriguez, I., Caro, A., and
+                M. Tuexen, "Stream Control Transmission Protocol (SCTP)
+                Implementers Guide", Work in Progress, January 2002.
+
+   [TCPMIB]     Fenner, B., McCloghrie, K., Raghunarayan, R., and J.
+                Schoenwalder, "Management Information Base for the
+                Transmission Control Protocol (TCP)", Work in Progress,
+                November 2002.
+
+   [UDPMIB]     Fenner, B., "Management Information Base for User
+                Datagram Protocol (UDP)", Work in Progress, June 2002.
+
+   [MIBGUIDE]   Heard, C.M., "Guidelines for MIB Authors and Reviewers",
+                Work in Progress, February 2003.
+
+
+
+
+
+
+
+Pastor & Belinchon          Standards Track                    [Page 43]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+7.  Security Considerations
+
+   There are management objects defined in this MIB that have a MAX-
+   ACCESS clause of read-write and/or read-create.  Such objects may be
+   considered sensitive or vulnerable in some network environments.  The
+   support for SET operations in a non-secure environment without proper
+   protection can have a negative effect on network operations.  These
+   are the tables and objects and their sensitivity/vulnerability:
+
+   o  The sctpAssocState object has a MAX-ACCESS clause of read-write,
+      which allows termination of an arbitrary connection.  Unauthorized
+      access could cause a denial of service.
+
+   Some of the readable objects in this MIB module (i.e., objects with a
+   MAX-ACCESS other than not-accessible) may be considered sensitive or
+   vulnerable in some network environments.  Thus, it is important to
+   control even GET and/or NOTIFY access to these objects and possibly
+   to even encrypt the values of these objects when sending them over
+   the network via SNMP.  These are the tables and objects and their
+   sensitivity/vulnerability:
+
+   o  The sctpAssocTable, sctpAssocLocalAddressTable,
+      sctpAssocRemAddressTable and the lookup tables contain objects
+      providing information on the active associations on the device,
+      local and peer's IP addresses, the status of these associations
+      and the associated processes.  This information may be used by an
+      attacker to launch attacks against known/unknown weakness in
+      certain protocols/applications.
+
+   o  The sctpAssocTable contains objects providing information on local
+      and remote ports objects, that can be used to identify what ports
+      are open on the machine and can thus suggest what attacks are
+      likely to succeed, without the attacker having to run a port
+      scanner.
+
+   SNMP versions prior to SNMPv3 did not include adequate security.
+   Even if the network itself is secure (for example by using IPSec),
+   even then, there is no control as to who on the secure network is
+   allowed to access and GET/SET (read/change/create/delete) the objects
+   in this MIB module.
+
+   It is RECOMMENDED that implementers consider the security features as
+   provided by the SNMPv3 framework (see [RFC3410], section 8),
+   including full support for the SNMPv3 cryptographic mechanisms (for
+   authentication and privacy).
+
+
+
+
+
+
+Pastor & Belinchon          Standards Track                    [Page 44]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+   Further, deployment of SNMP versions prior to SNMPv3 is NOT
+   RECOMMENDED.  Instead, it is RECOMMENDED to deploy SNMPv3 and to
+   enable cryptographic security.  It is then a customer/operator
+   responsibility to ensure that the SNMP entity giving access to an
+   instance of this MIB module is properly configured to give access to
+   the objects only to those principals (users) that have legitimate
+   rights to indeed GET or SET (change/create/delete) them.
+
+   The above objects also have privacy implications, i.e., they disclose
+   who is connecting to what hosts.  These are sensitive from a
+   perspective of preventing traffic analysis, and also to protect
+   individual privacy.
+
+8.  Acknowledgments
+
+   The authors wish to thank Juergen Schoenwaelder, David Partain, Shawn
+   A. Routhier, Ed Yarwood, John Linton, Shyamal Prasad, Juan-Francisco
+   Martin, Dave Thaler, and Bert Wijnen for their invaluable comments.
+
+9.  Authors' Addresses
+
+   Javier Pastor-Balbas
+   Ericsson Espana S.A.
+   Network Signaling System Management
+   Via de los Poblados 13
+   Madrid, 28033
+   Spain
+
+   Phone: +34-91-339-1397
+   EMail: J.Javier.Pastor@ericsson.com
+
+
+   Maria-Carmen Belinchon
+   Ericsson Espana S.A.
+   Network Signaling System Management
+   Via de los Poblados 13
+   Madrid, 28033
+   Spain
+
+   Phone: +34-91-339-3535
+   EMail: maria.carmen.belinchon@ericsson.com
+
+
+
+
+
+
+
+
+
+
+Pastor & Belinchon          Standards Track                    [Page 45]
+
+RFC 3873                  SCTP MIB using SMIv2            September 2004
+
+
+10.  Full Copyright Statement
+
+   Copyright (C) The Internet Society (2004).
+
+   This document is subject to the rights, licenses and restrictions
+   contained in BCP 78, and except as set forth therein, the authors
+   retain all their rights.
+
+   This document and the information contained herein are provided on an
+   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/S HE
+   REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE
+   INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR
+   IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
+   THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
+   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Intellectual Property
+
+   The IETF takes no position regarding the validity or scope of any
+   Intellectual Property Rights or other rights that might be claimed to
+   pertain to the implementation or use of the technology described in
+   this document or the extent to which any license under such rights
+   might or might not be available; nor does it represent that it has
+   made any independent effort to identify any such rights.  Information
+   on the IETF's procedures with respect to rights in IETF Documents can
+   be found in BCP 78 and BCP 79.
+
+   Copies of IPR disclosures made to the IETF Secretariat and any
+   assurances of licenses to be made available, or the result of an
+   attempt made to obtain a general license or permission for the use of
+   such proprietary rights by implementers or users of this
+   specification can be obtained from the IETF on-line IPR repository at
+   http://www.ietf.org/ipr.
+
+   The IETF invites any interested party to bring to its attention any
+   copyrights, patents or patent applications, or other proprietary
+   rights that may cover technology that may be required to implement
+   this standard.  Please address the information to the IETF at ietf-
+   ipr@ietf.org.
+
+Acknowledgement
+
+   Funding for the RFC Editor function is currently provided by the
+   Internet Society.
+
+
+
+
+
+
+
+Pastor & Belinchon          Standards Track                    [Page 46]
+
diff --git a/doc/rfc4460.txt b/doc/rfc4460.txt
new file mode 100644
index 0000000..1345b19
--- /dev/null
+++ b/doc/rfc4460.txt
@@ -0,0 +1,6107 @@
+
+
+
+
+
+
+Network Working Group                                         R. Stewart
+Request for Comments: 4460                           Cisco Systems, Inc.
+Category: Informational                               I. Arias-Rodriguez
+                                                   Nokia Research Center
+                                                                 K. Poon
+                                                  Sun Microsystems, Inc.
+                                                                 A. Caro
+                                                        BBN Technologies
+                                                               M. Tuexen
+                                      Muenster Univ. of Applied Sciences
+                                                              April 2006
+
+
+       Stream Control Transmission Protocol (SCTP) Specification
+                           Errata and Issues
+
+
+Status of This Memo
+
+   This memo provides information for the Internet community.  It does
+   not specify an Internet standard of any kind.  Distribution of this
+   memo is unlimited.
+
+Copyright Notice
+
+   Copyright (C) The Internet Society (2006).
+
+Abstract
+
+   This document is a compilation of issues found during six
+   interoperability events and 5 years of experience with implementing,
+   testing, and using Stream Control Transmission Protocol (SCTP) along
+   with the suggested fixes.  This document provides deltas to RFC 2960
+   and is organized in a time-based way.  The issues are listed in the
+   order they were brought up.  Because some text is changed several
+   times, the last delta in the text is the one that should be applied.
+   In addition to the delta, a description of the problem and the
+   details of the solution are also provided.
+
+Table of Contents
+
+   1. Introduction ....................................................6
+      1.1. Conventions ................................................7
+   2. Corrections to RFC 2960 .........................................7
+      2.1. Incorrect Error Type During Chunk Processing. ..............7
+           2.1.1. Description of the Problem ..........................7
+           2.1.2. Text changes to the document ........................7
+           2.1.3. Solution Description ................................7
+
+
+
+Stewart, et al.              Informational                      [Page 1]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+      2.2. Parameter Processing Issue .................................7
+           2.2.1. Description of the Problem ..........................7
+           2.2.2. Text Changes to the Document ........................8
+           2.2.3. Solution Description ................................8
+      2.3. Padding Issues .............................................8
+           2.3.1. Description of the Problem ..........................8
+           2.3.2. Text Changes to the Document ........................9
+           2.3.3. Solution Description ...............................10
+      2.4. Parameter Types across All Chunk Types ....................10
+           2.4.1. Description of the Problem .........................10
+           2.4.2. Text Changes to the Document .......................10
+           2.4.3. Solution Description ...............................12
+      2.5. Stream Parameter Clarification ............................12
+           2.5.1. Description of the problem .........................12
+           2.5.2. Text Changes to the Document .......................12
+           2.5.3. Solution Description ...............................13
+      2.6. Restarting Association Security Issue .....................13
+           2.6.1. Description of the Problem .........................13
+           2.6.2. Text Changes to the Document .......................14
+           2.6.3. Solution Description ...............................18
+      2.7. Implicit Ability to Exceed cwnd by PMTU-1 Bytes ...........19
+           2.7.1. Description of the Problem .........................19
+           2.7.2. Text Changes to the Document .......................19
+           2.7.3. Solution Description ...............................19
+      2.8. Issues with Fast Retransmit ...............................19
+           2.8.1. Description of the Problem .........................19
+           2.8.2. Text Changes to the Document .......................20
+           2.8.3. Solution Description ...............................23
+      2.9. Missing Statement about partial_bytes_acked Update ........24
+           2.9.1. Description of the Problem .........................24
+           2.9.2. Text Changes to the Document .......................24
+           2.9.3. Solution Description ...............................25
+      2.10. Issues with Heartbeating and Failure Detection ...........25
+           2.10.1. Description of the Problem ........................25
+           2.10.2. Text Changes to the Document ......................26
+           2.10.3. Solution Description ..............................28
+      2.11. Security interactions with firewalls .....................29
+           2.11.1. Description of the Problem ........................29
+           2.11.2. Text Changes to the Document ......................29
+           2.11.3. Solution Description ..............................31
+      2.12. Shutdown Ambiguity .......................................31
+           2.12.1. Description of the Problem ........................31
+           2.12.2. Text Changes to the Document ......................31
+           2.12.3. Solution Description ..............................32
+      2.13. Inconsistency in ABORT Processing ........................32
+           2.13.1. Description of the Problem ........................32
+           2.13.2. Text changes to the document ......................33
+           2.13.3. Solution Description ..............................33
+
+
+
+Stewart, et al.              Informational                      [Page 2]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+      2.14. Cwnd Gated by Its Full Use ...............................34
+           2.14.1. Description of the Problem ........................34
+           2.14.2. Text Changes to the Document ......................34
+           2.14.3. Solution Description ..............................36
+      2.15. Window Probes in SCTP ....................................36
+           2.15.1. Description of the Problem ........................36
+           2.15.2. Text Changes to the Document ......................36
+           2.15.3. Solution Description ..............................38
+      2.16. Fragmentation and Path MTU Issues ........................39
+           2.16.1. Description of the Problem ........................39
+           2.16.2. Text Changes to the Document ......................39
+           2.16.3. Solution Description ..............................40
+      2.17. Initial Value of the Cumulative TSN Ack ..................40
+           2.17.1. Description of the Problem ........................40
+           2.17.2. Text Changes to the Document ......................40
+           2.17.3. Solution Description ..............................41
+      2.18. Handling of Address Parameters within the INIT or
+            INIT-ACK .................................................41
+           2.18.1. Description of the Problem ........................41
+           2.18.2. Text Changes to the Document ......................41
+           2.18.3. Solution description ..............................42
+      2.19. Handling of Stream Shortages .............................42
+           2.19.1. Description of the Problem ........................42
+           2.19.2. Text Changes to the Document ......................42
+           2.19.3. Solution Description ..............................43
+      2.20. Indefinite Postponement ..................................43
+           2.20.1. Description of the Problem ........................43
+           2.20.2. Text Changes to the Document ......................43
+           2.20.3. Solution Description ..............................44
+      2.21. User-Initiated Abort of an Association ...................44
+           2.21.1. Description of the Problem ........................44
+           2.21.2. Text changes to the document ......................44
+           2.21.3. Solution Description ..............................50
+      2.22. Handling of Invalid Initiate Tag of INIT-ACK .............50
+           2.22.1. Description of the Problem ........................50
+           2.22.2. Text Changes to the Document ......................50
+           2.22.3. Solution Description ..............................51
+      2.23. Sending an ABORT in Response to an INIT ..................51
+           2.23.1. Description of the Problem ........................51
+           2.23.2. Text Changes to the Document ......................51
+           2.23.3. Solution Description ..............................52
+      2.24. Stream Sequence Number (SSN) Initialization ..............52
+           2.24.1. Description of the Problem ........................52
+           2.24.2. Text Changes to the Document ......................52
+           2.24.3. Solution Description ..............................53
+      2.25. SACK Packet Format .......................................53
+           2.25.1. Description of the Problem ........................53
+           2.25.2. Text Changes to the Document ......................53
+
+
+
+Stewart, et al.              Informational                      [Page 3]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+           2.25.3. Solution Description ..............................53
+      2.26. Protocol Violation Error Cause ...........................53
+           2.26.1. Description of the Problem ........................53
+           2.26.2. Text Changes to the Document ......................54
+           2.26.3. Solution Description ..............................56
+      2.27. Reporting of Unrecognized Parameters .....................56
+           2.27.1. Description of the Problem ........................56
+           2.27.2. Text Changes to the Document ......................56
+           2.27.3. Solution Description ..............................57
+      2.28. Handling of IP Address Parameters ........................58
+           2.28.1. Description of the Problem ........................58
+           2.28.2. Text Changes to the Document ......................58
+           2.28.3. Solution Description ..............................58
+      2.29. Handling of COOKIE ECHO Chunks When a TCB Exists .........59
+           2.29.1. Description of the Problem ........................59
+           2.29.2. Text Changes to the Document ......................59
+           2.29.3. Solution Description ..............................59
+      2.30. The Initial Congestion Window Size .......................59
+           2.30.1. Description of the Problem ........................59
+           2.30.2. Text Changes to the Document ......................60
+           2.30.3. Solution Description ..............................61
+      2.31. Stream Sequence Numbers in Figures .......................62
+           2.31.1. Description of the Problem ........................62
+           2.31.2. Text Changes to the Document ......................63
+           2.31.3. Solution description ..............................67
+      2.32. Unrecognized Parameters ..................................67
+           2.32.1. Description of the Problem ........................67
+           2.32.2. Text Changes to the Document ......................67
+           2.32.3. Solution Description ..............................68
+      2.33. Handling of Unrecognized Parameters ......................68
+           2.33.1. Description of the Problem ........................68
+           2.33.2. Text Changes to the Document ......................68
+           2.33.3. Solution Description ..............................70
+      2.34. Tie Tags .................................................70
+           2.34.1. Description of the Problem ........................70
+           2.34.2. Text Changes to the Document ......................70
+           2.34.3. Solution Description ..............................72
+      2.35. Port Number Verification in the COOKIE-ECHO ..............72
+           2.35.1. Description of the Problem ........................72
+           2.35.2. Text Changes to the Document ......................72
+           2.35.3. Solution Description ..............................73
+      2.36. Path Initialization ......................................74
+           2.36.1. Description of the Problem ........................74
+           2.36.2. Text Changes to the Document ......................74
+           2.36.3. Solution Description ..............................76
+      2.37. ICMP Handling Procedures .................................76
+           2.37.1. Description of the Problem ........................76
+           2.37.2. Text Changes to the Document ......................77
+
+
+
+Stewart, et al.              Informational                      [Page 4]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+           2.37.3. Solution Description ..............................79
+      2.38. Checksum .................................................79
+           2.38.1. Description of the problem ........................79
+           2.38.2. Text Changes to the Document ......................79
+           2.38.3. Solution Description ..............................86
+      2.39. Retransmission Policy ....................................86
+           2.39.1. Description of the Problem ........................86
+           2.39.2. Text Changes to the Document ......................87
+           2.39.3. Solution Description ..............................87
+      2.40. Port Number 0 ............................................88
+           2.40.1. Description of the Problem ........................88
+           2.40.2. Text Changes to the Document ......................88
+           2.40.3. Solution Description ..............................89
+      2.41. T Bit ....................................................89
+           2.41.1. Description of the Problem ........................89
+           2.41.2. Text Changes to the Document ......................89
+           2.41.3. Solution Description ..............................93
+      2.42. Unknown Parameter Handling ...............................93
+           2.42.1. Description of the Problem ........................93
+           2.42.2. Text Changes to the Document ......................93
+           2.42.3. Solution Description ..............................95
+      2.43. Cookie Echo Chunk ........................................95
+           2.43.1. Description of the Problem ........................95
+           2.43.2. Text Changes to the Document ......................95
+           2.43.3. Solution Description ..............................96
+      2.44. Partial Chunks ...........................................96
+           2.44.1. Description of the Problem ........................96
+           2.44.2. Text Changes to the Document ......................96
+           2.44.3. Solution Description ..............................97
+      2.45. Non-unicast Addresses ....................................97
+           2.45.1. Description of the Problem ........................97
+           2.45.2. Text Changes to the Document ......................97
+           2.45.3. Solution Description ..............................98
+      2.46. Processing of ABORT Chunks ...............................98
+           2.46.1. Description of the Problem ........................98
+           2.46.2. Text Changes to the Document ......................98
+           2.46.3. Solution Description ..............................98
+      2.47. Sending of ABORT Chunks ..................................99
+           2.47.1. Description of the Problem ........................99
+           2.47.2. Text Changes to the Document ......................99
+           2.47.3. Solution Description ..............................99
+      2.48. Handling of Supported Address Types Parameter ............99
+           2.48.1. Description of the Problem ........................99
+           2.48.2. Text Changes to the Document .....................100
+           2.48.3. Solution Description .............................100
+      2.49. Handling of Unexpected Parameters .......................101
+           2.49.1. Description of the Problem .......................101
+           2.49.2. Text Changes to the Document .....................101
+
+
+
+Stewart, et al.              Informational                      [Page 5]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+           2.49.3. Solution Description .............................102
+      2.50. Payload Protocol Identifier .............................102
+           2.50.1. Description of the Problem .......................102
+           2.50.2. Text Changes to the Document .....................103
+           2.50.3. Solution Description .............................103
+      2.51. Karn's Algorithm ........................................104
+           2.51.1. Description of the Problem .......................104
+           2.51.2. Text Changes to the Document .....................104
+           2.51.3. Solution Description .............................104
+      2.52. Fast Retransmit Algorithm ...............................104
+           2.52.1. Description of the Problem .......................104
+           2.52.2. Text Changes to the Document .....................105
+           2.52.3. Solution Description .............................105
+   3. Security Considerations .......................................105
+   4. Acknowledgements ..............................................106
+   5. IANA Considerations ...........................................106
+   6. Normative References ..........................................106
+
+1.  Introduction
+
+   This document contains a compilation of all defects found up until
+   the publishing of this document for the Stream Control Transmission
+   Protocol (SCTP), RFC 2960 [5].  These defects may be of an editorial
+   or technical nature.  This document may be thought of as a companion
+   document to be used in the implementation of SCTP to clarify errors
+   in the original SCTP document.
+
+   This document provides a history of the changes that will be compiled
+   into RFC 2960's [5] BIS document.  Each error will be detailed within
+   this document in the form of
+
+   o  the problem description,
+
+   o  the text quoted from RFC 2960 [5],
+
+   o  the replacement text that should be placed into the BIS document,
+      and
+
+   o  a description of the solution.
+
+   This document is a historical record of sequential changes what have
+   been found necessary at various interop events and through discussion
+   on this list.
+
+   Note that because some text is changed several times, the last delta
+   for a text in the document is the erratum for that text in RFC 2960.
+
+
+
+
+
+Stewart, et al.              Informational                      [Page 6]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+1.1.  Conventions
+
+   The keywords MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD,
+   SHOULD NOT, RECOMMENDED, NOT RECOMMENDED, MAY, and OPTIONAL, when
+   they appear in this document, are to be interpreted as described in
+   RFC 2119 [2].
+
+2.  Corrections to RFC 2960
+
+2.1.  Incorrect Error Type During Chunk Processing.
+
+2.1.1.  Description of the Problem
+
+   A typo was discovered in RFC 2960 [5] that incorrectly specifies an
+   action to be taken when processing chunks of unknown identity.
+
+2.1.2.  Text changes to the document
+
+   ---------
+   Old text: (Section 3.2)
+   ---------
+
+   01 - Stop processing this SCTP packet and discard it, do not process
+        any further chunks within it, and report the unrecognized
+        parameter in an 'Unrecognized Parameter Type' (in either an
+        ERROR or in the INIT ACK).
+
+   ---------
+   New text: (Section 3.2)
+   ---------
+
+   01 - Stop processing this SCTP packet and discard it, do not process
+        any further chunks within it, and report the unrecognized
+        chunk in an 'Unrecognized Chunk Type'.
+
+2.1.3.  Solution Description
+
+   The receiver of an unrecognized chunk should not send a 'parameter'
+   error but instead should send the appropriate chunk error as
+   described above.
+
+2.2.  Parameter Processing Issue
+
+2.2.1.  Description of the Problem
+
+   A typographical error was introduced through an improper cut and
+   paste in the use of the upper two bits to describe proper handling of
+   unknown parameters.
+
+
+
+Stewart, et al.              Informational                      [Page 7]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+2.2.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 3.2.1)
+   ---------
+
+   00 - Stop processing this SCTP packet and discard it; do not process
+        any further chunks within it.
+
+   01 - Stop processing this SCTP packet and discard it, do not process
+        any further chunks within it, and report the unrecognized
+        parameter in an 'Unrecognized Parameter Type' (in either an
+        ERROR or in the INIT ACK).
+
+   ---------
+   New text: (Section 3.2.1)
+   ---------
+
+   00 - Stop processing this SCTP chunk and discard it, do not process
+        any further parameters within this chunk.
+
+   01 - Stop processing this SCTP chunk and discard it, do not process
+        any further parameters within this chunk, and report the
+        unrecognized parameter in an 'Unrecognized Parameter Type' (in
+        either an ERROR or in the INIT ACK).
+
+2.2.3.  Solution Description
+
+   It was always the intent to stop processing at the level one was at
+   in an unknown chunk or parameter with the upper bit set to 0.  Thus,
+   if you are processing a chunk, you should drop the packet.  If you
+   are processing a parameter, you should drop the chunk.
+
+2.3.  Padding Issues
+
+2.3.1.  Description of the Problem
+
+   A problem was found when a Chunk terminated in a TLV parameter.  If
+   this last TLV was not on a 32-bit boundary (as required), there was
+   confusion as to whether the last padding was included in the chunk
+   length.
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.              Informational                      [Page 8]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+2.3.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 3.2)
+   ---------
+
+   Chunk Length: 16 bits (unsigned integer)
+
+      This value represents the size of the chunk in bytes including the
+      Chunk Type, Chunk Flags, Chunk Length, and Chunk Value fields.
+      Therefore, if the Chunk Value field is zero-length, the Length
+      field will be set to 4.  The Chunk Length field does not count any
+      padding.
+
+   Chunk Value: variable length
+
+      The Chunk Value field contains the actual information to be
+      transferred in the chunk.  The usage and format of this field is
+      dependent on the Chunk Type.
+
+   The total length of a chunk (including Type, Length and Value fields)
+   MUST be a multiple of 4 bytes.  If the length of the chunk is not a
+   multiple of 4 bytes, the sender MUST pad the chunk with all zero
+   bytes and this padding is not included in the chunk length field.
+   The sender should never pad with more than 3 bytes.  The receiver
+   MUST ignore the padding bytes.
+
+   ---------
+   New text: (Section 3.2)
+   ---------
+
+   Chunk Length: 16 bits (unsigned integer)
+
+      This value represents the size of the chunk in bytes, including
+      the Chunk Type, Chunk Flags, Chunk Length, and Chunk Value fields.
+      Therefore, if the Chunk Value field is zero-length, the Length
+      field will be set to 4.  The Chunk Length field does not count any
+      chunk padding.
+
+      Chunks (including Type, Length, and Value fields) are padded out
+      by the sender with all zero bytes to be a multiple of 4 bytes
+      long.  This padding MUST NOT be more than 3 bytes in total.  The
+      Chunk Length value does not include terminating padding of the
+      chunk.  However, it does include padding of any variable-length
+      parameter except the last parameter in the chunk.  The receiver
+      MUST ignore the padding.
+
+
+
+
+
+Stewart, et al.              Informational                      [Page 9]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+      Note: A robust implementation should accept the Chunk whether or
+      not the final padding has been included in the Chunk Length.
+
+   Chunk Value: variable length
+
+      The Chunk Value field contains the actual information to be
+      transferred in the chunk.  The usage and format of this field is
+      dependent on the Chunk Type.
+
+   The total length of a chunk (including Type, Length, and Value
+   fields) MUST be a multiple of 4 bytes.  If the length of the chunk is
+   not a multiple of 4 bytes, the sender MUST pad the chunk with all
+   zero bytes, and this padding is not included in the chunk length
+   field.  The sender should never pad with more than 3 bytes.  The
+   receiver MUST ignore the padding bytes.
+
+2.3.3.  Solution Description
+
+   The above text makes clear that the padding of the last parameter is
+   not included in the Chunk Length field.  It also clarifies that the
+   padding of parameters that are not the last one must be counted in
+   the Chunk Length field.
+
+2.4.  Parameter Types across All Chunk Types
+
+2.4.1.  Description of the Problem
+
+   A problem was noted when multiple errors are needed to be sent
+   regarding unknown or unrecognized parameters.  Since often the error
+   type does not hold the chunk type field, it may become difficult to
+   tell which error was associated with which chunk.
+
+2.4.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 3.2.1)
+   ---------
+
+   The actual SCTP parameters are defined in the specific SCTP chunk
+   sections.  The rules for IETF-defined parameter extensions are
+   defined in Section 13.2.
+
+   ---------
+   New text: (Section 3.2.1)
+   ---------
+
+   The actual SCTP parameters are defined in the specific SCTP chunk
+   sections.  The rules for IETF-defined parameter extensions are
+
+
+
+Stewart, et al.              Informational                     [Page 10]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   defined in Section 13.2.  Note that a parameter type MUST be unique
+   across all chunks.  For example, the parameter type '5' is used to
+   represent an IPv4 address (see Section 3.3.2).  The value '5' then is
+   reserved across all chunks to represent an IPv4 address and MUST NOT
+   be reused with a different meaning in any other chunk.
+
+   ---------
+   Old text: (Section 13.2)
+   ---------
+
+   13.2 IETF-defined Chunk Parameter Extension
+
+   The assignment of new chunk parameter type codes is done through an
+   IETF Consensus action as defined in [RFC2434].  Documentation of the
+   chunk parameter MUST contain the following information:
+
+   a) Name of the parameter type.
+
+   b) Detailed description of the structure of the parameter field.
+      This structure MUST conform to the general type-length-value
+      format described in Section 3.2.1.
+
+   c) Detailed definition of each component of the parameter type.
+
+   d) Detailed description of the intended use of this parameter type,
+      and an indication of whether and under what circumstances multiple
+      instances of this parameter type may be found within the same
+      chunk.
+
+   ---------
+   New text: (Section 13.2)
+   ---------
+
+   13.2.  IETF-defined Chunk Parameter Extension
+
+   The assignment of new chunk parameter type codes is done through an
+   IETF Consensus action, as defined in [RFC2434].  Documentation of the
+   chunk parameter MUST contain the following information:
+
+   a) Name of the parameter type.
+
+   b) Detailed description of the structure of the parameter field.
+      This structure MUST conform to the general type-length-value
+      format described in Section 3.2.1.
+
+   c) Detailed definition of each component of the parameter type.
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 11]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   d) Detailed description of the intended use of this parameter type,
+      and an indication of whether and under what circumstances multiple
+      instances of this parameter type may be found within the same
+      chunk.
+
+   e) Each parameter type MUST be unique across all chunks.
+
+2.4.3.  Solution Description
+
+   By having all parameters unique across all chunk assignments (the
+   current assignment policy), no ambiguity exists as to what a
+   parameter means in different contexts.  The trade-off for this is a
+   smaller parameter space, i.e., 65,536 parameters versus 65,536 *
+   Number-of- chunks.
+
+2.5.  Stream Parameter Clarification
+
+2.5.1.  Description of the problem
+
+   A problem was found where the specification is unclear on the
+   legality of an endpoint asking for more stream resources than were
+   allowed in the MIS value of the INIT.  In particular, the value in
+   the INIT ACK requested in its OS value was larger than the MIS value
+   received in the INIT chunk.  This behavior is illegal, yet it was
+   unspecified in RFC 2960 [5]
+
+2.5.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 3.3.3)
+   ---------
+
+   Number of Outbound Streams (OS):  16 bits (unsigned integer)
+
+      Defines the number of outbound streams the sender of this INIT ACK
+      chunk wishes to create in this association.  The value of 0 MUST
+      NOT be used.
+
+      Note: A receiver of an INIT ACK with the OS value set to 0 SHOULD
+      destroy the association discarding its TCB.
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 12]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   ---------
+   New text: (Section 3.3.3)
+   ---------
+
+   Number of Outbound Streams (OS): 16 bits (unsigned integer)
+
+      Defines the number of outbound streams the sender of this INIT ACK
+      chunk wishes to create in this association.  The value of 0 MUST
+      NOT be used, and the value MUST NOT be greater than the MIS value
+      sent in the INIT chunk.
+
+      Note: A receiver of an INIT ACK with the OS value set to 0 SHOULD
+      destroy the association, discarding its TCB.
+
+2.5.3.  Solution Description
+
+   The change in wording, above, changes it so that a responder to an
+   INIT chunk does not specify more streams in its OS value than were
+   represented to it in the MIS value, i.e., its maximum.
+
+2.6.  Restarting Association Security Issue
+
+2.6.1.  Description of the Problem
+
+   A security problem was found when a restart occurs.  It is possible
+   for an intruder to send an INIT to an endpoint of an existing
+   association.  In the INIT the intruder would list one or more of the
+   current addresses of an association and its own.  The normal restart
+   procedures would then occur, and the intruder would have hijacked an
+   association.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 13]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+2.6.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 3.3.10)
+   ---------
+
+      Cause Code
+      Value           Cause Code
+      ---------      ----------------
+       1              Invalid Stream Identifier
+       2              Missing Mandatory Parameter
+       3              Stale Cookie Error
+       4              Out of Resource
+       5              Unresolvable Address
+       6              Unrecognized Chunk Type
+       7              Invalid Mandatory Parameter
+       8              Unrecognized Parameters
+       9              No User Data
+      10              Cookie Received While Shutting Down
+
+   Cause Length: 16 bits (unsigned integer)
+
+      Set to the size of the parameter in bytes, including the Cause
+      Code, Cause Length, and Cause-Specific Information fields
+
+   Cause-specific Information: variable length
+
+      This field carries the details of the error condition.
+
+   Sections 3.3.10.1 - 3.3.10.10 define error causes for SCTP.
+
+   Guidelines for the IETF to define new error cause values are
+   discussed in Section 13.3.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 14]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   ---------
+   New text: (Section 3.3.10)
+   ---------
+
+      Cause Code
+      Value           Cause Code
+      ---------      ----------------
+       1              Invalid Stream Identifier
+       2              Missing Mandatory Parameter
+       3              Stale Cookie Error
+       4              Out of Resource
+       5              Unresolvable Address
+       6              Unrecognized Chunk Type
+       7              Invalid Mandatory Parameter
+       8              Unrecognized Parameters
+       9              No User Data
+      10              Cookie Received While Shutting Down
+      11              Restart of an Association with New Addresses
+
+   Cause Length: 16 bits (unsigned integer)
+
+      Set to the size of the parameter in bytes, including the Cause
+      Code, Cause Length, and Cause-Specific Information fields.
+
+   Cause-specific Information: variable length
+
+      This field carries the details of the error condition.
+
+   Sections 3.3.10.1 - 3.3.10.11 define error causes for SCTP.
+   Guidelines for the IETF to define new error cause values are
+   discussed in Section 13.3.
+
+   ---------
+   New text: (Note no old text, new error cause added in section 3.3.10)
+   ---------
+
+   3.3.10.11.  Restart of an Association with New Addresses (11)
+
+    Cause of error
+    --------------
+    Restart of an association with new addresses: An INIT was received
+    on an existing association.  But the INIT added addresses to the
+    association that were previously NOT part of the association.  The
+    new addresses are listed in the error code.  This ERROR is normally
+    sent as part of an ABORT refusing the INIT (see Section 5.2).
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 15]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+      |         Cause Code=11         |      Cause Length=Variable    |
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+      /                       New Address TLVs                        /
+      \                                                               \
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+      Note: Each New Address TLV is an exact copy of the TLV
+      that was found in the INIT chunk that was new, including the
+      Parameter Type and the Parameter length.
+
+   ---------
+   Old text: (Section 5.2.1)
+   ---------
+
+   Upon receipt of an INIT in the COOKIE-WAIT or COOKIE-ECHOED state, an
+   endpoint MUST respond with an INIT ACK using the same parameters it
+   sent in its original INIT chunk (including its Initiation Tag,
+   unchanged).  These original parameters are combined with those from
+   the newly received INIT chunk.  The endpoint shall also generate a
+   State Cookie with the INIT ACK.  The endpoint uses the parameters
+   sent in its INIT to calculate the State Cookie.
+
+   ---------
+   New text: (Section 5.2.1)
+   ---------
+
+   Upon receipt of an INIT in the COOKIE-WAIT state, an endpoint MUST
+   respond with an INIT ACK using the same parameters it sent in its
+   original INIT chunk (including its Initiation Tag, unchanged).  When
+   responding, the endpoint MUST send the INIT ACK back to the same
+   address that the original INIT (sent by this endpoint) was sent to.
+
+   Upon receipt of an INIT in the COOKIE-ECHOED state, an endpoint MUST
+   respond with an INIT ACK using the same parameters it sent in its
+   original INIT chunk (including its Initiation Tag, unchanged),
+   provided that no NEW address has been added to the forming
+   association.  If the INIT message indicates that a new address has
+   been added to the association, then the entire INIT MUST be
+   discarded, and NO changes should be made to the existing association.
+   An ABORT SHOULD be sent in response that MAY include the error
+   'Restart of an association with new addresses'.  The error SHOULD
+   list the addresses that were added to the restarting association.
+
+
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 16]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   When responding in either state (COOKIE-WAIT or COOKIE-ECHOED) with
+   an INIT ACK, the original parameters are combined with those from the
+   newly received INIT chunk.  The endpoint shall also generate a State
+   Cookie with the INIT ACK.  The endpoint uses the parameters sent in
+   its INIT to calculate the State Cookie.
+
+   ---------
+   Old text: (Section 5.2.2)
+   ---------
+
+   5.2.2 Unexpected INIT in States Other than CLOSED, COOKIE-ECHOED,
+         COOKIE-WAIT and SHUTDOWN-ACK-SENT
+
+   Unless otherwise stated, upon reception of an unexpected INIT for
+   this association, the endpoint shall generate an INIT ACK with a
+   State Cookie.  In the outbound INIT ACK the endpoint MUST copy its
+   current Verification Tag and peer's Verification Tag into a reserved
+   place within the state cookie.  We shall refer to these locations as
+   the Peer's-Tie-Tag and the Local-Tie-Tag.  The outbound SCTP packet
+   containing this INIT ACK MUST carry a Verification Tag value equal to
+   the Initiation Tag found in the unexpected INIT.  And the INIT ACK
+   MUST contain a new Initiation Tag (randomly generated see Section
+   5.3.1).  Other parameters for the endpoint SHOULD be copied from the
+   existing parameters of the association (e.g., number of outbound
+   streams) into the INIT ACK and cookie.
+
+   After sending out the INIT ACK, the endpoint shall take no further
+   actions, i.e., the existing association, including its current state,
+   and the corresponding TCB MUST NOT be changed.
+
+   Note: Only when a TCB exists and the association is not in a COOKIE-
+   WAIT state are the Tie-Tags populated.  For a normal association INIT
+   (i.e., the endpoint is in a COOKIE-WAIT state), the Tie-Tags MUST be
+   set to 0 (indicating that no previous TCB existed).  The INIT ACK and
+   State Cookie are populated as specified in section 5.2.1.
+
+   ---------
+   New text: (Section 5.2.2)
+   ---------
+
+   5.2.2.  Unexpected INIT in States Other Than CLOSED, COOKIE-ECHOED,
+           COOKIE-WAIT, and SHUTDOWN-ACK-SENT
+
+   Unless otherwise stated, upon receipt of an unexpected INIT for this
+   association, the endpoint shall generate an INIT ACK with a State
+   Cookie.  Before responding, the endpoint MUST check to see if the
+   unexpected INIT adds new addresses to the association.  If new
+   addresses are added to the association, the endpoint MUST respond
+
+
+
+Stewart, et al.              Informational                     [Page 17]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   with an ABORT, copying the 'Initiation Tag' of the unexpected INIT
+   into the 'Verification Tag' of the outbound packet carrying the
+   ABORT.  In the ABORT response, the cause of error MAY be set to
+   'restart of an association with new addresses'.  The error SHOULD
+   list the addresses that were added to the restarting association.
+
+   If no new addresses are added, when responding to the INIT in the
+   outbound INIT ACK, the endpoint MUST copy its current Verification
+   Tag and peer's Verification Tag into a reserved place within the
+   state cookie.  We shall refer to these locations as the Peer's-Tie-
+   Tag and the Local-Tie-Tag.  The outbound SCTP packet containing this
+   INIT ACK MUST carry a Verification Tag value equal to the Initiation
+   Tag found in the unexpected INIT.  And the INIT ACK MUST contain a
+   new Initiation Tag (randomly generated; see Section 5.3.1).  Other
+   parameters for the endpoint SHOULD be copied from the existing
+   parameters of the association (e.g., number of outbound streams) into
+   the INIT ACK and cookie.
+
+   After sending out the INIT ACK or ABORT, the endpoint shall take no
+   further actions; i.e., the existing association, including its
+   current state, and the corresponding TCB MUST NOT be changed.
+
+   Note: Only when a TCB exists and the association is not in a COOKIE-
+   WAIT or SHUTDOWN-ACK-SENT state are the Tie-Tags populated with a
+   value other than 0.  For a normal association INIT (i.e., the
+   endpoint is in the CLOSED state), the Tie-Tags MUST be set to 0
+   (indicating that no previous TCB existed).
+
+2.6.3.  Solution Description
+
+   A new error code is being added, along with specific instructions to
+   send back an ABORT to a new association in a restart case or
+   collision case, where new addresses have been added.  The error code
+   can be used by a legitimate restart to inform the endpoint that it
+   has made a software error in adding a new address.  The endpoint then
+   can choose to wait until the OOTB ABORT tears down the old
+   association, or to restart without the new address.
+
+   Also, the note at the end of Section 5.2.2 explaining the use of the
+   Tie-Tags was modified to properly explain the states in which the
+   Tie-Tags should be set to a value different than 0.
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 18]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+2.7.  Implicit Ability to Exceed cwnd by PMTU-1 Bytes
+
+2.7.1.  Description of the Problem
+
+   Some implementations were having difficulty growing their cwnd.  This
+   was due to an improper enforcement of the congestion control rules.
+   The rules, as written, provided for a slop over of the cwnd value.
+   Without this slop over, the sender would appear NOT to be using its
+   full cwnd value and thus would never increase it.
+
+2.7.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 6.1)
+   ---------
+
+   B) At any given time, the sender MUST NOT transmit new data to a
+      given transport address if it has cwnd or more bytes of data
+      outstanding to that transport address.
+
+   ---------
+   New text: (Section 6.1)
+   ---------
+
+   B) At any given time, the sender MUST NOT transmit new data to a
+      given transport address if it has cwnd or more bytes of data
+      outstanding to that transport address.  The sender may exceed cwnd
+      by up to (PMTU-1) bytes on a new transmission if the cwnd is not
+      currently exceeded.
+
+2.7.3.  Solution Description
+
+   The text changes make clear the ability to go over the cwnd value by
+   no more than (PMTU-1) bytes.
+
+2.8.  Issues with Fast Retransmit
+
+2.8.1.  Description of the Problem
+
+   Several problems were found in the current specification of fast
+   retransmit.  The current wording did not require GAP ACK blocks to be
+   sent, even though they are essential to the workings of SCTP's
+   congestion control.  The specification left unclear how to handle the
+   fast retransmit cycle, having the implementation wait on the cwnd to
+   retransmit a TSN that was marked for fast retransmit.  No limit was
+   placed on how many times a TSN could be fast retransmitted.  Fast
+   Recovery was not specified, causing the congestion window to be
+   reduced drastically when there are multiple losses in a single RTT.
+
+
+
+Stewart, et al.              Informational                     [Page 19]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+2.8.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 6.2)
+   ---------
+
+   Acknowledgements MUST be sent in SACK chunks unless shutdown was
+   requested by the ULP in which case an endpoint MAY send an
+   acknowledgement in the SHUTDOWN chunk.  A SACK chunk can acknowledge
+   the reception of multiple DATA chunks.  See Section 3.3.4 for SACK
+   chunk format.  In particular, the SCTP endpoint MUST fill in the
+   Cumulative TSN Ack field to indicate the latest sequential TSN (of a
+   valid DATA chunk) it has received.  Any received DATA chunks with TSN
+   greater than the value in the Cumulative TSN Ack field SHOULD also be
+   reported in the Gap Ack Block fields.
+
+   ---------
+   New text: (Section 6.2)
+   ---------
+
+   Acknowledegments MUST be sent in SACK chunks unless shutdown was
+   requested by the ULP, in which case an endpoint MAY send an
+   acknowledgement in the SHUTDOWN chunk.  A SACK chunk can acknowledge
+   the reception of multiple DATA chunks.  See Section 3.3.4 for SACK
+   chunk format.  In particular, the SCTP endpoint MUST fill in the
+   Cumulative TSN Ack field to indicate the latest sequential TSN (of a
+   valid DATA chunk) it has received.  Any received DATA chunks with
+   TSN greater than the value in the Cumulative TSN Ack field are
+   reported in the Gap Ack Block fields.  The SCTP endpoint MUST
+   report as many Gap Ack Blocks as can fit in a single SACK
+   chunk limited by the current path MTU.
+
+   ---------
+   Old text: (Section 6.2.1)
+   ---------
+
+      D) Any time a SACK arrives, the endpoint performs the following:
+
+            i) If Cumulative TSN Ack is less than the Cumulative TSN Ack
+            Point, then drop the SACK.  Since Cumulative TSN Ack is
+            monotonically increasing, a SACK whose Cumulative TSN Ack is
+            less than the Cumulative TSN Ack Point indicates an out-of-
+            order SACK.
+
+            ii) Set rwnd equal to the newly received a_rwnd minus the
+            number of bytes still outstanding after processing the
+            Cumulative TSN Ack and the Gap Ack Blocks.
+
+
+
+
+Stewart, et al.              Informational                     [Page 20]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+            iii) If the SACK is missing a TSN that was previously
+            acknowledged via a Gap Ack Block (e.g., the data receiver
+            reneged on the data), then mark the corresponding DATA chunk
+            as available for retransmit:  Mark it as missing for fast
+            retransmit as described in Section 7.2.4 and if no
+            retransmit timer is running for the destination address
+            to which the DATA chunk was originally transmitted, then
+            T3-rtx is started for that destination address.
+
+   ---------
+   New text: (Section 6.2.1)
+   ---------
+
+      D) Any time a SACK arrives, the endpoint performs the following:
+
+            i) If Cumulative TSN Ack is less than the Cumulative TSN Ack
+            Point, then drop the SACK.  Since Cumulative TSN Ack is
+            monotonically increasing, a SACK whose Cumulative TSN Ack is
+            less than the Cumulative TSN Ack Point indicates an out-of-
+            order SACK.
+
+            ii) Set rwnd equal to the newly received a_rwnd minus the
+            number of bytes still outstanding after processing the
+            Cumulative TSN Ack and the Gap Ack Blocks.
+
+            iii) If the SACK is missing a TSN that was previously
+            acknowledged via a Gap Ack Block (e.g., the data receiver
+            reneged on the data), then consider the corresponding DATA
+            that might be possibly missing: Count one miss indication
+            towards fast retransmit as described in Section 7.2.4, and
+            if no retransmit timer is running for the destination
+            address to which the DATA chunk was originally transmitted,
+            then T3-rtx is started for that destination address.
+
+            iv) If the Cumulative TSN Ack matches or exceeds the Fast
+            Recovery exitpoint (Section 7.2.4), Fast Recovery is exited.
+
+   ---------
+   Old text: (Section 7.2.4)
+   ---------
+
+   Whenever an endpoint receives a SACK that indicates some TSN(s)
+   missing, it SHOULD wait for 3 further miss indications (via
+   subsequent SACK's) on the same TSN(s) before taking action with
+   regard to Fast Retransmit.
+
+   When the TSN(s) is reported as missing in the fourth consecutive
+   SACK, the data sender shall:
+
+
+
+Stewart, et al.              Informational                     [Page 21]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   1) Mark the missing DATA chunk(s) for retransmission,
+
+   2) Adjust the ssthresh and cwnd of the destination address(es) to
+      which the missing DATA chunks were last sent, according to the
+      formula described in Section 7.2.3.
+
+   3) Determine how many of the earliest (i.e., lowest TSN) DATA chunks
+      marked for retransmission will fit into a single packet, subject
+      to constraint of the path MTU of the destination transport address
+      to which the packet is being sent.  Call this value K.  Retransmit
+      those K DATA chunks in a single packet.
+
+   4) Restart T3-rtx timer only if the last SACK acknowledged the lowest
+      outstanding TSN number sent to that address, or the endpoint is
+      retransmitting the first outstanding DATA chunk sent to that
+      address.
+
+   Note: Before the above adjustments, if the received SACK also
+   acknowledges new DATA chunks and advances the Cumulative TSN Ack
+   Point, the cwnd adjustment rules defined in Sections 7.2.1 and 7.2.2
+   must be applied first.
+
+   A straightforward implementation of the above keeps a counter for
+   each TSN hole reported by a SACK.  The counter increments for each
+   consecutive SACK reporting the TSN hole.  After reaching 4 and
+   starting the fast retransmit procedure, the counter resets to 0.
+   Because cwnd in SCTP indirectly bounds the number of outstanding
+   TSN's, the effect of TCP fast-recovery is achieved automatically with
+   no adjustment to the congestion control window size.
+
+   ---------
+   New text: (Section 7.2.4)
+   ---------
+
+   Whenever an endpoint receives a SACK that indicates that some TSNs
+   are missing, it SHOULD wait for 3 further miss indications (via
+   subsequent SACKs) on the same TSN(s) before taking action with
+   regard to Fast Retransmit.
+
+   Miss indications SHOULD follow the HTNA (Highest TSN Newly
+   Acknowledged) algorithm.  For each incoming SACK, miss
+   indications are incremented only for missing TSNs prior to
+   the highest TSN newly acknowledged in the SACK.  A newly
+   acknowledged DATA chunk is one not previously acknowledged
+   in a SACK.  If an endpoint is in Fast Recovery and a SACK
+   arrives that advances the Cumulative TSN Ack Point, the
+   miss indications are incremented for all TSNs reported
+   missing in the SACK.
+
+
+
+Stewart, et al.              Informational                     [Page 22]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   When the fourth consecutive miss indication is received for a TSN(s),
+   the data sender shall do the following:
+
+   1) Mark the DATA chunk(s) with four miss indications for
+      retransmission.
+
+   2) If not in Fast Recovery, adjust the ssthresh and cwnd of the
+      destination address(es) to which the missing DATA chunks were
+      last sent, according to the formula described in Section 7.2.3.
+
+   3) Determine how many of the earliest (i.e., lowest TSN) DATA chunks
+      marked for retransmission will fit into a single packet, subject
+      to constraint of the path MTU of the destination transport address
+      to which the packet is being sent.  Call this value K.  Retransmit
+      those K DATA chunks in a single packet.  When a Fast Retransmit is
+      being performed, the sender SHOULD ignore the value of cwnd and
+      SHOULD NOT delay retransmission for this single packet.
+
+   4) Restart T3-rtx timer only if the last SACK acknowledged the lowest
+      outstanding TSN number sent to that address, or the endpoint is
+      retransmitting the first outstanding DATA chunk sent to that
+      address.
+
+   5) Mark the DATA chunk(s) as being fast retransmitted and thus
+      ineligible for a subsequent fast retransmit.  Those TSNs marked
+      for retransmission due to the Fast Retransmit algorithm that
+      did not fit in the sent datagram carrying K other TSNs are also
+      marked as ineligible for a subsequent fast retransmit.  However,
+      as they are marked for retransmission they will be retransmitted
+      later on as soon as cwnd allows.
+
+   6) If not in Fast Recovery, enter Fast Recovery and mark the highest
+      outstanding TSN as the Fast Recovery exit point.  When a SACK
+      acknowledges all TSNs up to and including this exit point, Fast
+      Recovery is exited.  While in Fast Recovery, the ssthresh and cwnd
+      SHOULD NOT change for any destinations due to a subsequent Fast
+      Recovery event (i.e., one SHOULD NOT reduce the cwnd further due
+      to a subsequent fast retransmit).
+
+   Note: Before the above adjustments, if the received SACK also
+   acknowledges new DATA chunks and advances the Cumulative TSN Ack
+   Point, the cwnd adjustment rules defined in Sections 7.2.1 and 7.2.2
+   must be applied first.
+
+2.8.3.  Solution Description
+
+   The effect of the above wording changes are as follows:
+
+
+
+
+Stewart, et al.              Informational                     [Page 23]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   o  It requires with a MUST the sending of GAP Ack blocks instead of
+      the current RFC 2960 [5] SHOULD.
+
+   o  It allows a TSN being Fast Retransmitted (FR) to be sent only once
+      via FR.
+
+   o  It ends the delay in waiting for the flight size to drop when a
+      TSN is identified as being ready to FR.
+
+   o  It changes the way chunks are marked during fast retransmit, so
+      that only new reports are counted.
+
+   o  It introduces a Fast Recovery period to avoid multiple congestion
+      window reductions when there are multiple losses in a single RTT
+      (as shown by Caro et al. [3]).
+
+   These changes will effectively allow SCTP to follow a similar model
+   as TCP+SACK in the handling of Fast Retransmit.
+
+2.9.  Missing Statement about partial_bytes_acked Update
+
+2.9.1.  Description of the Problem
+
+   SCTP uses four control variables to regulate its transmission rate:
+   rwnd, cwnd, ssthresh, and partial_bytes_acked.  Upon detection of
+   packet losses from SACK, or when the T3-rtx timer expires on an
+   address, cwnd and ssthresh should be updated as stated in Section
+   7.2.3.  However, that section should also clarify that
+   partial_bytes_acked must be updated as well; it has to be reset to 0.
+
+2.9.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 7.2.3)
+   ---------
+
+   7.2.3 Congestion Control
+
+   Upon detection of packet losses from SACK  (see Section 7.2.4), An
+   endpoint should do the following:
+
+      ssthresh = max(cwnd/2, 2*MTU)
+      cwnd = ssthresh
+
+   Basically, a packet loss causes cwnd to be cut in half.
+
+   When the T3-rtx timer expires on an address, SCTP should perform slow
+   start by:
+
+
+
+Stewart, et al.              Informational                     [Page 24]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+      ssthresh = max(cwnd/2, 2*MTU)
+      cwnd = 1*MTU
+
+   ---------
+   New text: (Section 7.2.3)
+   ---------
+
+   7.2.3.  Congestion Control
+
+   Upon detection of packet losses from SACK (see Section 7.2.4), an
+   endpoint should do the following if not in Fast Recovery:
+
+      ssthresh = max(cwnd/2, 2*MTU)
+      cwnd = ssthresh
+      partial_bytes_acked = 0
+
+   Basically, a packet loss causes cwnd to be cut in half.
+
+   When the T3-rtx timer expires on an address, SCTP should perform slow
+   start by
+
+      ssthresh = max(cwnd/2, 2*MTU)
+      cwnd = 1*MTU
+      partial_bytes_acked = 0
+
+2.9.3.  Solution Description
+
+   The missing text added solves the doubts about what to do with
+   partial_bytes_acked in the situations stated in Section 7.2.3, making
+   clear that, along with ssthresh and cwnd, partial_bytes_acked should
+   also be updated by being reset to 0.
+
+2.10.  Issues with Heartbeating and Failure Detection
+
+2.10.1.  Description of the Problem
+
+   Five basic problems have been discovered with the current heartbeat
+   procedures:
+
+   o  The current specification does not specify that you should count a
+      failed heartbeat as an error against the overall association.
+
+   o  The current specification is not specific as to when you start
+      sending heartbeats and when you should stop.
+
+   o  The current specification is not specific as to when you should
+      respond to heartbeats.
+
+
+
+
+Stewart, et al.              Informational                     [Page 25]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   o  When responding to a Heartbeat, it is unclear what to do if more
+      than a single TLV is present.
+
+   o  The jitter applied to a heartbeat was meant to be a small variance
+      of the RTO and is currently a wide variance, due to the default
+      delay time and incorrect wording within the RFC.
+
+2.10.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 8.1)
+   ---------
+
+   8.1 Endpoint Failure Detection
+
+   An endpoint shall keep a counter on the total number of consecutive
+   retransmissions to its peer (including retransmissions to all the
+   destination transport addresses of the peer if it is multi-homed).
+   If the value of this counter exceeds the limit indicated in the
+   protocol parameter 'Association.Max.Retrans', the endpoint shall
+   consider the peer endpoint unreachable and shall stop transmitting
+   any more data to it (and thus the association enters the CLOSED
+   state).  In addition, the endpoint shall report the failure to the
+   upper layer, and optionally report back all outstanding user data
+   remaining in its outbound queue.  The association is automatically
+   closed when the peer endpoint becomes unreachable.
+
+   The counter shall be reset each time a DATA chunk sent to that peer
+   endpoint is acknowledged (by the reception of a SACK), or a
+   HEARTBEAT-ACK is received from the peer endpoint.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 26]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   ---------
+   New text: (Section 8.1)
+   ---------
+
+   8.1.  Endpoint Failure Detection
+
+   An endpoint shall keep a counter on the total number of consecutive
+   retransmissions to its peer (this includes retransmissions to all the
+   destination transport addresses of the peer if it is multi-homed),
+   including unacknowledged HEARTBEAT Chunks.  If the value of this
+   counter exceeds the limit indicated in the protocol parameter
+   'Association.Max.Retrans', the endpoint shall consider the peer
+   endpoint unreachable and shall stop transmitting any more data to it
+   (and thus the association enters the CLOSED state).  In addition, the
+   endpoint MAY report the failure to the upper layer and optionally
+   report back all outstanding user data remaining in its outbound
+   queue.  The association is automatically closed when the peer
+   endpoint becomes unreachable.
+
+   The counter shall be reset each time a DATA chunk sent to that peer
+   endpoint is acknowledged (by the reception of a SACK), or a
+   HEARTBEAT-ACK is received from the peer endpoint.
+
+
+   ---------
+   Old text: (Section 8.3)
+   ---------
+
+   8.3 Path Heartbeat
+
+   By default, an SCTP endpoint shall monitor the reachability of the
+   idle destination transport address(es) of its peer by sending a
+   HEARTBEAT chunk periodically to the destination transport
+   address(es).
+
+   ---------
+   New text: (Section 8.3)
+   ---------
+
+   8.3 Path Heartbeat
+
+   By default, an SCTP endpoint SHOULD monitor the reachability of the
+   idle destination transport address(es) of its peer by sending a
+   HEARTBEAT chunk periodically to the destination transport
+   address(es).  HEARTBEAT sending MAY begin upon reaching the
+   ESTABLISHED state and is discontinued after sending either SHUTDOWN
+   or SHUTDOWN-ACK.  A receiver of a HEARTBEAT MUST respond to a
+   HEARTBEAT with a HEARTBEAT-ACK after entering the COOKIE-ECHOED state
+
+
+
+Stewart, et al.              Informational                     [Page 27]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   (INIT sender) or the ESTABLISHED state (INIT receiver), up until
+   reaching the SHUTDOWN-SENT state (SHUTDOWN sender) or the SHUTDOWN-
+   ACK-SENT state (SHUTDOWN receiver).
+
+
+   ---------
+   Old text: (Section 8.3)
+   ---------
+
+   The receiver of the HEARTBEAT should immediately respond with a
+   HEARTBEAT ACK that contains the Heartbeat Information field copied
+   from the received HEARTBEAT chunk.
+
+   ---------
+   New text: (Section 8.3)
+   ---------
+
+   The receiver of the HEARTBEAT should immediately respond with a
+   HEARTBEAT ACK that contains the Heartbeat Information TLV, together
+   with any other received TLVs, copied unchanged from the received
+   HEARTBEAT chunk.
+
+
+   ---------
+   Old text: (Section 8.3)
+   ---------
+
+   On an idle destination address that is allowed to heartbeat, a
+   HEARTBEAT chunk is RECOMMENDED to be sent once per RTO of that
+   destination address plus the protocol parameter 'HB.interval' , with
+   jittering of +/- 50%, and exponential back-off of the RTO if the
+   previous HEARTBEAT is unanswered.
+
+   ---------
+   New text: (Section 8.3)
+   ---------
+
+   On an idle destination address that is allowed to heartbeat, it is
+   recommended that a HEARTBEAT chunk is sent once per RTO of that
+   destination address plus the protocol parameter 'HB.interval', with
+   jittering of +/- 50% of the RTO value, and exponential back-off of
+   the RTO if the previous HEARTBEAT is unanswered.
+
+2.10.3.  Solution Description
+
+   The above text provides guidance as to how to respond to the five
+   issues mentioned in Section 2.10.1.  In particular, the wording
+   changes provide guidance as to when to start and stop heartbeating,
+
+
+
+Stewart, et al.              Informational                     [Page 28]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   how to respond to a heartbeat with extra parameters, and it clarifies
+   the error counting procedures for the association.
+
+2.11.  Security interactions with firewalls
+
+2.11.1.  Description of the Problem
+
+   When dealing with firewalls, it is advantageous for the firewall to
+   be able to properly determine the initial startup sequence of a
+   reliable transport protocol.  With this in mind, the following text
+   is to be added to SCTP's security section.
+
+2.11.2.  Text Changes to the Document
+
+   ---------
+   New text: (no old text, new section added)
+   ---------
+
+   11.4 SCTP Interactions with Firewalls
+
+   It is helpful for some firewalls if they can inspect
+   just the first fragment of a fragmented SCTP packet and unambiguously
+   determine whether it corresponds to an INIT chunk (for further
+   information, please refer to RFC1858).  Accordingly, we
+   stress the requirements, stated in 3.1, that (1) an INIT chunk MUST
+   NOT be bundled with any other chunk in a packet, and (2) a packet
+   containing an INIT chunk MUST have a zero Verification Tag.
+   Furthermore, we require that the receiver of an INIT chunk MUST
+   enforce these rules by silently discarding an arriving packet with an
+   INIT chunk that is bundled with other chunks.
+
+   ---------
+   Old text: (Section 18)
+   ---------
+
+   18.  Bibliography
+
+   [ALLMAN99] Allman, M. and Paxson, V., "On Estimating End-to-End
+              Network Path Properties", Proc. SIGCOMM'99, 1999.
+
+   [FALL96]   Fall, K. and Floyd, S., Simulation-based Comparisons of
+              Tahoe, Reno, and SACK TCP, Computer Communications Review,
+              V. 26 N. 3, July 1996, pp. 5-21.
+
+   [RFC1750]  Eastlake, D. (ed.), "Randomness Recommendations for
+              Security", RFC 1750, December 1994.
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 29]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   [RFC1950]  Deutsch P. and J. Gailly, "ZLIB Compressed Data Format
+              Specification version 3.3", RFC 1950, May 1996.
+
+   [RFC2104]  Krawczyk, H., Bellare, M. and R. Canetti, "HMAC: Keyed-
+              Hashing for Message Authentication", RFC 2104, March 1997.
+
+   [RFC2196]  Fraser, B., "Site Security Handbook", FYI 8, RFC 2196,
+              September 1997.
+
+   [RFC2522]  Karn, P. and W. Simpson, "Photuris: Session-Key Management
+              Protocol", RFC 2522, March 1999.
+
+   [SAVAGE99] Savage, S., Cardwell, N., Wetherall, D., and Anderson, T.,
+              "TCP Congestion Control with a Misbehaving Receiver", ACM
+              Computer Communication Review, 29(5), October 1999.
+
+   ---------
+   New text: (Section 18)
+   ---------
+
+   18.  Bibliography
+
+   [ALLMAN99] Allman, M. and Paxson, V., "On Estimating End-to-End
+              Network Path Properties", Proc. SIGCOMM'99, 1999.
+
+   [FALL96]   Fall, K. and Floyd, S., Simulation-based Comparisons of
+              Tahoe, Reno, and SACK TCP, Computer Communications Review,
+              V. 26 N. 3, July 1996, pp.  5-21.
+
+   [RFC1750]  Eastlake, D. (ed.), "Randomness Recommendations for
+              Security", RFC 1750, December 1994.
+
+   [RFC1858]  Ziemba, G., Reed, D. and Traina P., "Security
+              Considerations for IP Fragment Filtering", RFC 1858,
+              October 1995.
+
+   [RFC1950]  Deutsch P. and J. Gailly, "ZLIB Compressed Data Format
+              Specification version 3.3", RFC 1950, May 1996.
+
+   [RFC2104]  Krawczyk, H., Bellare, M. and R. Canetti, "HMAC:  Keyed-
+              Hashing for Message Authentication", RFC 2104, March 1997.
+
+   [RFC2196]  Fraser, B., "Site Security Handbook", FYI 8, RFC 2196,
+              September 1997.
+
+   [RFC2522]  Karn, P. and W. Simpson, "Photuris: Session-Key Management
+              Protocol", RFC 2522, March 1999.
+
+
+
+
+Stewart, et al.              Informational                     [Page 30]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   [SAVAGE99] Savage, S., Cardwell, N., Wetherall, D., and Anderson, T.,
+              "TCP Congestion Control with a Misbehaving Receiver", ACM
+              Computer Communication Review, 29(5), October 1999.
+
+2.11.3.  Solution Description
+
+   The above text, which adds a new subsection to the Security
+   Considerations section of RFC 2960 [5] makes clear that, to make
+   easier the interaction with firewalls, an INIT chunk must not be
+   bundled in any case with any other chunk that will silently discard
+   the packets that do not follow this rule (this rule is enforced by
+   the packet receiver).
+
+2.12.  Shutdown Ambiguity
+
+2.12.1.  Description of the Problem
+
+   Currently, there is an ambiguity between the statements in Sections
+   6.2 and 9.2.  Section 6.2 allows the sending of a SHUTDOWN chunk in
+   place of a SACK when the sender is in the process of shutting down,
+   while section 9.2 requires that both a SHUTDOWN chunk and a SACK
+   chunk be sent.
+
+   Along with this ambiguity there is a problem wherein an errant
+   SHUTDOWN receiver may fail to stop accepting user data.
+
+2.12.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 9.2)
+   ---------
+
+   If there are still outstanding DATA chunks left, the SHUTDOWN
+   receiver shall continue to follow normal data transmission procedures
+   defined in Section 6 until all outstanding DATA chunks are
+   acknowledged; however, the SHUTDOWN receiver MUST NOT accept new data
+   from its SCTP user.
+
+   While in SHUTDOWN-SENT state, the SHUTDOWN sender MUST immediately
+   respond to each received packet containing one or more DATA chunk(s)
+   with a SACK, a SHUTDOWN chunk, and restart the T2-shutdown timer.  If
+   it has no more outstanding DATA chunks, the SHUTDOWN receiver shall
+   send a SHUTDOWN ACK and start a T2-shutdown timer of its own,
+   entering the SHUTDOWN-ACK-SENT state.  If the timer expires, the
+   endpoint must re-send the SHUTDOWN ACK.
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 31]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   ---------
+   New text: (Section 9.2)
+   ---------
+
+   If there are still outstanding DATA chunks left, the SHUTDOWN
+   receiver MUST continue to follow normal data transmission procedures
+   defined in Section 6, until all outstanding DATA chunks are
+   acknowledged; however, the SHUTDOWN receiver MUST NOT accept new data
+   from its SCTP user.
+
+   While in SHUTDOWN-SENT state, the SHUTDOWN sender MUST immediately
+   respond to each received packet containing one or more DATA chunks
+   with a SHUTDOWN chunk and restart the T2-shutdown timer.  If a
+   SHUTDOWN chunk by itself cannot acknowledge all of the received DATA
+   chunks (i.e., there are TSNs that can be acknowledged that are larger
+   than the cumulative TSN, and thus gaps exist in the TSN sequence), or
+   if duplicate TSNs have been received, then a SACK chunk MUST also be
+   sent.
+
+   The sender of the SHUTDOWN MAY also start an overall guard timer
+   'T5-shutdown-guard' to bound the overall time for shutdown sequence.
+   At the expiration of this timer, the sender SHOULD abort the
+   association by sending an ABORT chunk.  If the 'T5-shutdown-guard'
+   timer is used, it SHOULD be set to the recommended value of 5 times
+   'RTO.Max'.
+
+   If the receiver of the SHUTDOWN has no more outstanding DATA chunks,
+   the SHUTDOWN receiver MUST send a SHUTDOWN ACK and start a
+   T2-shutdown timer of its own, entering the SHUTDOWN-ACK-SENT state.
+   If the timer expires, the endpoint must re-send the SHUTDOWN ACK.
+
+2.12.3.  Solution Description
+
+   The above text clarifies the use of a SACK in conjunction with a
+   SHUTDOWN chunk.  It also adds a guard timer to the SCTP shutdown
+   sequence to protect against errant receivers of SHUTDOWN chunks.
+
+2.13.  Inconsistency in ABORT Processing
+
+2.13.1.  Description of the Problem
+
+   It was noted that the wording in Section 8.5.1 did not give proper
+   directions in the use of the 'T bit' with the Verification Tags.
+
+
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 32]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+2.13.2.  Text changes to the document
+
+   ---------
+   Old text: (Section 8.5.1)
+   ---------
+
+   B) Rules for packet carrying ABORT:
+
+      -  The endpoint shall always fill in the Verification Tag field
+         of the outbound packet with the destination endpoint's tag
+         value if it is known.
+
+      -  If the ABORT is sent in response to an OOTB packet, the
+         endpoint MUST follow the procedure described in Section 8.4.
+
+      -  The receiver MUST accept the packet if the Verification Tag
+         matches either its own tag, OR the tag of its peer.  Otherwise,
+         the receiver MUST silently discard the packet and take no
+         further action.
+
+   ---------
+   New text: (Section 8.5.1)
+   ---------
+
+   B) Rules for packet carrying ABORT:
+
+      -  The endpoint MUST always fill in the Verification Tag field of
+         the outbound packet with the destination endpoint's tag value,
+         if it is known.
+
+      -  If the ABORT is sent in response to an OOTB packet, the
+         endpoint MUST follow the procedure described in Section 8.4.
+
+      -  The receiver of a ABORT MUST accept the packet if the
+         Verification Tag field of the packet matches its own tag OR if
+         it is set to its peer's tag and the T bit is set in the Chunk
+         Flags.  Otherwise, the receiver MUST silently discard the
+         packet and take no further action.
+
+2.13.3.  Solution Description
+
+   The above text change clarifies that the T bit must be set before an
+   implementation looks for the peer's tag.
+
+
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 33]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+2.14.  Cwnd Gated by Its Full Use
+
+2.14.1.  Description of the Problem
+
+   A problem was found with the current specification of the growth and
+   decay of cwnd.  The cwnd should only be increased if it is being
+   fully utilized, and after periods of underutilization, the cwnd
+   should be decreased.  In some sections, the current wording is weak
+   and is not clearly defined.  Also, the current specification
+   unnecessarily introduces the need for special case code to ensure
+   cwnd degradation.  Plus, the cwnd should not be increased during Fast
+   Recovery, since a full cwnd during Fast Recovery does not qualify the
+   cwnd as being fully utilized.  Additionally, multiple loss scenarios
+   in a single window may cause the cwnd to grow more rapidly as the
+   number of losses in a window increases [3].
+
+2.14.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 6.1)
+   ---------
+
+   D) Then, the sender can send out as many new DATA chunks as Rule A
+      and Rule B above allow.
+
+   ---------
+   New text: (Section 6.1)
+   ---------
+
+   D) When the time comes for the sender to transmit new DATA chunks,
+      the protocol parameter Max.Burst SHOULD be used to limit the
+      number of packets sent.  The limit MAY be applied by adjusting
+      cwnd as follows:
+
+      if((flightsize + Max.Burst*MTU) < cwnd)
+         cwnd = flightsize + Max.Burst*MTU
+
+      Or it MAY be applied by strictly limiting the number of packets
+      emitted by the output routine.
+
+   E) Then, the sender can send out as many new DATA chunks as Rule A
+      and Rule B allow.
+
+
+
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 34]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   ---------
+   Old text: (Section 7.2.1)
+   ---------
+
+   o  When cwnd is less than or equal to ssthresh an SCTP endpoint MUST
+      use the slow start algorithm to increase cwnd (assuming the
+      current congestion window is being fully utilized).  If an
+      incoming SACK advances the Cumulative TSN Ack Point, cwnd MUST be
+      increased by at most the lesser of 1) the total size of the
+      previously outstanding DATA chunk(s) acknowledged, and 2) the
+      destination's path MTU.  This protects against the ACK-Splitting
+      attack outlined in [SAVAGE99].
+
+   ---------
+   New text: (Section 7.2.1)
+   ---------
+
+   o  When cwnd is less than or equal to ssthresh, an SCTP endpoint MUST
+      use the slow start algorithm to increase cwnd only if the current
+      congestion window is being fully utilized, an incoming SACK
+      advances the Cumulative TSN Ack Point, and the data sender is not
+      in Fast Recovery.  Only when these three conditions are met can
+      the cwnd be increased; otherwise, the cwnd MUST not be increased.
+      If these conditions are met, then cwnd MUST be increased by, at
+      most, the lesser of 1) the total size of the previously
+      outstanding DATA chunk(s) acknowledged, and 2) the destination's
+      path MTU.  This upper bound protects against the ACK-Splitting
+      attack outlined in [SAVAGE99].
+
+
+   ---------
+   Old text: (Section 14)
+   ---------
+
+   14.  Suggested SCTP Protocol Parameter Values
+
+   The following protocol parameters are RECOMMENDED:
+
+   RTO.Initial              - 3  seconds
+   RTO.Min                  - 1  second
+   RTO.Max                 -  60 seconds
+   RTO.Alpha                - 1/8
+   RTO.Beta                 - 1/4
+   Valid.Cookie.Life        - 60  seconds
+   Association.Max.Retrans  - 10 attempts
+   Path.Max.Retrans         - 5  attempts (per destination address)
+   Max.Init.Retransmits     - 8  attempts
+   HB.interval              - 30 seconds
+
+
+
+Stewart, et al.              Informational                     [Page 35]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   ---------
+   New text: (Section 14)
+   ---------
+
+   14.  Suggested SCTP Protocol Parameter Values
+
+   The following protocol parameters are RECOMMENDED:
+
+   RTO.Initial              - 3  seconds
+   RTO.Min                  - 1  second
+   RTO.Max                  - 60 seconds
+   Max.Burst                - 4
+   RTO.Alpha                - 1/8
+   RTO.Beta                 - 1/4
+   Valid.Cookie.Life        - 60 seconds
+   Association.Max.Retrans  - 10 attempts
+   Path.Max.Retrans         - 5  attempts (per destination address)
+   Max.Init.Retransmits     - 8  attempts
+   HB.Interval              - 30 seconds
+
+2.14.3.  Solution Description
+
+   The above changes strengthen the rules and make it much more apparent
+   as to the need to block cwnd growth when the full cwnd is not being
+   utilized.  The changes also apply cwnd degradation without
+   introducing the need for complex special case code.
+
+2.15.  Window Probes in SCTP
+
+2.15.1.  Description of the Problem
+
+   When a receiver clamps its rwnd to 0 to flow control the peer, the
+   specification implies that one must continue to accept data from the
+   remote peer.  This is incorrect and needs clarification.
+
+2.15.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 6.2)
+   ---------
+
+   The SCTP endpoint MUST always acknowledge the receipt of each valid
+   DATA chunk.
+
+
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 36]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   ---------
+   New text: (Section 6.2)
+   ---------
+
+   The SCTP endpoint MUST always acknowledge the reception of each valid
+   DATA chunk when the DATA chunk received is inside its receive window.
+
+   When the receiver's advertised window is 0, the receiver MUST drop
+   any new incoming DATA chunk with a TSN larger than the largest TSN
+   received so far.  If the new incoming DATA chunk holds a TSN value
+   less than the largest TSN received so far, then the receiver SHOULD
+   drop the largest TSN held for reordering and accept the new incoming
+   DATA chunk.  In either case, if such a DATA chunk is dropped, the
+   receiver MUST immediately send back a SACK with the current receive
+   window showing only DATA chunks received and accepted so far.  The
+   dropped DATA chunk(s) MUST NOT be included in the SACK, as they were
+   not accepted.  The receiver MUST also have an algorithm for
+   advertising its receive window to avoid receiver silly window
+   syndrome (SWS), as described in RFC 813.  The algorithm can be
+   similar to the one described in Section 4.2.3.3 of RFC 1122.
+
+
+   ---------
+   Old text: (Section 6.1)
+   ---------
+
+   A) At any given time, the data sender MUST NOT transmit new data to
+      any destination transport address if its peer's rwnd indicates
+      that the peer has no buffer space (i.e., rwnd is 0, see Section
+      6.2.1).  However, regardless of the value of rwnd (including if it
+      is 0), the data sender can always have one DATA chunk in flight to
+      the receiver if allowed by cwnd (see rule B below).  This rule
+      allows the sender to probe for a change in rwnd that the sender
+      missed due to the SACK having been lost in transit from the data
+      receiver to the data sender.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 37]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   ---------
+   New text: (Section 6.1)
+   ---------
+
+   A) At any given time, the data sender MUST NOT transmit new data to
+      any destination transport address if its peer's rwnd indicates
+      that the peer has no buffer space (i.e., rwnd is 0; see Section
+      6.2.1).  However, regardless of the value of rwnd (including if it
+      is 0), the data sender can always have one DATA chunk in flight to
+      the receiver if allowed by cwnd (see rule B, below).  This rule
+      allows the sender to probe for a change in rwnd that the sender
+      missed due to the SACK's having been lost in transit from the data
+      receiver to the data sender.
+
+      When the receiver's advertised window is zero, this probe is
+      called a zero window probe.  Note that a zero window probe
+      SHOULD only be sent when all outstanding DATA chunks have
+      been cumulatively acknowledged and no DATA chunks are in
+      flight.  Zero window probing MUST be supported.
+
+      If the sender continues to receive new packets from the receiver
+      while doing zero window probing, the unacknowledged window probes
+      should not increment the error counter for the association or any
+      destination transport address.This is because the receiver MAY
+      keep its window closed for an indefinite time.  Refer to
+      Section 6.2 on the receiver behavior when it advertises a zero
+      window.  The sender SHOULD send the first zero window probe after
+      1 RTO when it detects that the receiver has closed its window
+      and SHOULD increase the probe interval exponentially afterwards.
+      Also note that the cwnd SHOULD be adjusted according to
+      Section 7.2.1.  Zero window probing does not affect the
+      calculation of cwnd.
+
+      The sender MUST also have an algorithm for sending new DATA chunks
+      to avoid silly window syndrome (SWS) as described in RFC 813.  The
+      algorithm can be similar to the one described in Section 4.2.3.4
+      of RFC 1122.
+
+2.15.3.  Solution Description
+
+   The above allows a receiver to drop new data that arrives and yet
+   still requires the receiver to send a SACK showing the conditions
+   unchanged (with the possible exception of a new a_rwnd) and the
+   dropped chunk as missing.  This will allow the association to
+   continue until the rwnd condition clears.
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 38]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+2.16.  Fragmentation and Path MTU Issues
+
+2.16.1.  Description of the Problem
+
+   The current wording of the Fragmentation and Reassembly forces an
+   implementation that supports fragmentation to always fragment.  This
+   prohibits an implementation from offering its users an option to
+   disable sends that exceed the SCTP fragmentation point.
+
+   The restriction in RFC 2960 [5], Section 6.9, was never meant to
+   restrict an implementations API from this behavior.
+
+2.16.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 6.1)
+   ---------
+
+   6.9 Fragmentation and Reassembly
+
+   An endpoint MAY support fragmentation when sending DATA chunks, but
+   MUST support reassembly when receiving DATA chunks.  If an endpoint
+   supports fragmentation, it MUST fragment a user message if the size
+   of the user message to be sent causes the outbound SCTP packet size
+   to exceed the current MTU.  If an implementation does not support
+   fragmentation of outbound user messages, the endpoint must return an
+   error to its upper layer and not attempt to send the user message.
+
+   IMPLEMENTATION NOTE:  In this error case, the Send primitive
+   discussed in Section 10.1 would need to return an error to the upper
+   layer.
+
+   ---------
+   New text: (Section 6.1)
+   ---------
+
+   6.9.  Fragmentation and Reassembly
+
+   An endpoint MAY support fragmentation when sending DATA chunks, but
+   it MUST support reassembly when receiving DATA chunks.  If an
+   endpoint supports fragmentation, it MUST fragment a user message if
+   the size of the user message to be sent causes the outbound SCTP
+   packet size to exceed the current MTU.  If an implementation does not
+   support fragmentation of outbound user messages, the endpoint MUST
+   return an error to its upper layer and not attempt to send the user
+   message.
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 39]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   Note: If an implementation that supports fragmentation makes
+   available to its upper layer a mechanism to turn off fragmentation it
+   may do so.  However, in so doing, it MUST react just like an
+   implementation that does NOT support fragmentation, i.e., it MUST
+   reject sends that exceed the current P-MTU.
+
+   IMPLEMENTATION NOTE:  In this error case, the Send primitive
+   discussed in Section 10.1 would need to return an error to the upper
+   layer.
+
+2.16.3.  Solution Description
+
+   The above wording will allow an implementation to offer the option of
+   rejecting sends that exceed the P-MTU size even when the
+   implementation supports fragmentation.
+
+2.17.  Initial Value of the Cumulative TSN Ack
+
+2.17.1.  Description of the Problem
+
+   The current description of the SACK chunk within the RFC does not
+   clearly state the value that would be put within a SACK when no DATA
+   chunk has been received.
+
+2.17.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 3.3.4)
+   ---------
+
+   Cumulative TSN Ack: 32 bits (unsigned integer)
+
+      This parameter contains the TSN of the last DATA chunk received in
+      sequence before a gap.
+
+   ---------
+   New text: (Section 3.3.4)
+   ---------
+
+   Cumulative TSN Ack: 32 bits (unsigned integer)
+
+      This parameter contains the TSN of the last DATA chunk received in
+      sequence before a gap.  In the case where no DATA chunk has
+      been received, this value is set to the peer's Initial TSN minus
+      one.
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 40]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+2.17.3.  Solution Description
+
+   This change clearly states what the initial value will be for a SACK
+   sender.
+
+2.18.  Handling of Address Parameters within the INIT or INIT-ACK
+
+2.18.1.  Description of the Problem
+
+   The current description on handling address parameters contained
+   within the INIT and INIT-ACK does not fully describe a requirement
+   for their handling.
+
+2.18.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 5.1.2)
+   ---------
+
+   C) If there are only IPv4/IPv6 addresses present in the received INIT
+      or INIT ACK chunk, the receiver shall derive and record all the
+      transport address(es) from the received chunk AND the source IP
+      address that sent the INIT or INIT ACK.  The transport address(es)
+      are derived by the combination of SCTP source port (from the
+      common header) and the IP address parameter(s) carried in the INIT
+      or INIT ACK chunk and the source IP address of the IP datagram.
+      The receiver should use only these transport addresses as
+      destination transport addresses when sending subsequent packets to
+      its peer.
+
+   ---------
+   New text: (Section 5.1.2)
+   ---------
+
+   C) If there are only IPv4/IPv6 addresses present in the received INIT
+      or INIT ACK chunk, the receiver MUST derive and record all the
+      transport addresses from the received chunk AND the source IP
+      address that sent the INIT or INIT ACK.  The transport addresses
+      are derived by the combination of SCTP source port (from the
+      common header) and the IP address parameter(s) carried in the INIT
+      or INIT ACK chunk and the source IP address of the IP datagram.
+      The receiver should use only these transport addresses as
+      destination transport addresses when sending subsequent packets to
+      its peer.
+
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 41]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   D) An INIT or INIT ACK chunk MUST be treated as belonging
+      to an already established association (or one in the
+      process of being established) if the use of any of the
+      valid address parameters contained within the chunk
+      would identify an existing TCB.
+
+2.18.3.  Solution description
+
+   This new text clearly specifies to an implementor the need to look
+   within the INIT or INIT ACK.  Any implementation that does not do
+   this may (for example) not be able to recognize an INIT chunk coming
+   from an already established association that adds new addresses (see
+   Section 2.6) or an incoming INIT ACK chunk sent from a source address
+   different from the destination address used to send the INIT chunk.
+
+2.19.  Handling of Stream Shortages
+
+2.19.1.  Description of the Problem
+
+   The current wording in the RFC places the choice of sending an ABORT
+   upon the SCTP stack when a stream shortage occurs.  This decision
+   should really be made by the upper layer, not the SCTP stack.
+
+2.19.2.  Text Changes to the Document
+
+   ---------
+   Old text:
+   ---------
+
+   5.1.1 Handle Stream Parameters
+
+   In the INIT and INIT ACK chunks, the sender of the chunk shall
+   indicate the number of outbound streams (OS) it wishes to have in
+   the association, as well as the maximum inbound streams (MIS) it
+   will accept from the other endpoint.
+
+   After receiving the stream configuration information from the other
+   side, each endpoint shall perform the following check:  If the peer's
+   MIS is less than the endpoint's OS, meaning that the peer is
+   incapable of supporting all the outbound streams the endpoint wants
+   to configure, the endpoint MUST either use MIS outbound streams, or
+   abort the association and report to its upper layer the resources
+   shortage at its peer.
+
+
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 42]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   ---------
+   New text: (Section 5.1.2)
+   ---------
+
+   5.1.1.  Handle Stream Parameters
+
+   In the INIT and INIT ACK chunks, the sender of the chunk MUST
+   indicate the number of outbound streams (OS) it wishes to have in
+   the association, as well as the maximum inbound streams (MIS) it will
+   accept from the other endpoint.
+
+   After receiving the stream configuration information from the other
+   side, each endpoint MUST perform the following check:  If the peer's
+   MIS is less than the endpoint's OS, meaning that the peer is
+   incapable of supporting all the outbound streams the endpoint wants
+   to configure, the endpoint MUST use MIS outbound streams and MAY
+   report any shortage to the upper layer.  The upper layer can then
+   choose to abort the association if the resource shortage
+   is unacceptable.
+
+2.19.3.  Solution Description
+
+   The above changes take the decision to ABORT out of the realm of the
+   SCTP stack and place it into the user's hands.
+
+2.20.  Indefinite Postponement
+
+2.20.1.  Description of the Problem
+
+   The current RFC does not provide any guidance on the assignment of
+   TSN sequence numbers to outbound messages nor reception of these
+   messages.  This could lead to a possible indefinite postponement.
+
+2.20.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 6.1)
+   ---------
+
+   Note: The data sender SHOULD NOT use a TSN that is more than 2**31 -
+   1 above the beginning TSN of the current send window.
+
+   6.2  Acknowledgement on Reception of DATA Chunks
+
+
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 43]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   ---------
+   New text: (Section 6.1)
+   ---------
+
+   Note: The data sender SHOULD NOT use a TSN that is more than 2**31 -
+   1 above the beginning TSN of the current send window.
+
+   The algorithm by which an implementation assigns sequential TSNs to
+   messages on a particular association MUST ensure that no user
+   message that has been accepted by SCTP is indefinitely postponed
+   from being assigned a TSN.  Acceptable algorithms for assigning TSNs
+   include
+
+   (a) assigning TSNs in round-robin order over all streams with
+       pending data; and
+
+   (b) preserving the linear order in which the user messages were
+       submitted to the SCTP association.
+
+   When an upper layer requests to read data on an SCTP association,
+   the SCTP receiver SHOULD choose the message with the lowest TSN from
+   among all deliverable messages.  In SCTP implementations that allow a
+   user to request data on a specific stream, this operation SHOULD NOT
+   block if data is not available, since this can lead to a deadlock
+   under certain conditions.
+
+   6.2.  Acknowledgement on Receipt of DATA Chunks
+
+2.20.3.  Solution Description
+
+   The above wording clarifies how TSNs SHOULD be assigned by the
+   sender.
+
+2.21.  User-Initiated Abort of an Association
+
+2.21.1.  Description of the Problem
+
+   It is not possible for an upper layer to abort the association and
+   provide the peer with an indication of why the association is
+   aborted.
+
+2.21.2.  Text changes to the document
+
+   Some of the changes given here already include changes suggested in
+   Section 2.6 of this document.
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 44]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   ---------
+   Old text: (Section 3.3.10)
+   ---------
+
+      Cause Code
+      Value           Cause Code
+      ---------      ----------------
+       1              Invalid Stream Identifier
+       2              Missing Mandatory Parameter
+       3              Stale Cookie Error
+       4              Out of Resource
+       5              Unresolvable Address
+       6              Unrecognized Chunk Type
+       7              Invalid Mandatory Parameter
+       8              Unrecognized Parameters
+       9              No User Data
+      10              Cookie Received While Shutting Down
+
+   Cause Length: 16 bits (unsigned integer)
+
+      Set to the size of the parameter in bytes, including the Cause
+      Code, Cause Length, and Cause-Specific Information fields
+
+   Cause-specific Information: variable length
+
+      This field carries the details of the error condition.
+
+   Sections 3.3.10.1 - 3.3.10.10 define error causes for SCTP.
+   Guidelines for the IETF to define new error cause values are
+   discussed in Section 13.3.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 45]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   ---------
+   New text: (Section 3.3.10)
+   ---------
+
+      Cause Code
+      Value           Cause Code
+      ---------      ----------------
+       1              Invalid Stream Identifier
+       2              Missing Mandatory Parameter
+       3              Stale Cookie Error
+       4              Out of Resource
+       5              Unresolvable Address
+       6              Unrecognized Chunk Type
+       7              Invalid Mandatory Parameter
+       8              Unrecognized Parameters
+       9              No User Data
+      10              Cookie Received While Shutting Down
+      11              Restart of an Association with New Addresses
+      12              User-Initiated Abort
+
+   Cause Length: 16 bits (unsigned integer)
+
+      Set to the size of the parameter in bytes, including the Cause
+      Code, Cause Length, and Cause-Specific Information fields
+
+   Cause-specific Information: variable length
+
+      This field carries the details of the error condition.
+
+   Sections 3.3.10.1 - 3.3.10.12 define error causes for SCTP.
+   Guidelines for the IETF to define new error cause values are
+   discussed in Section 13.3.
+
+   ---------
+   New text: (Note: no old text, new error added in Section 3.3.10)
+   ---------
+
+   3.3.10.12.  User-Initiated Abort (12)
+
+    Cause of error
+    --------------
+
+    This error cause MAY be included in ABORT chunks that are sent
+    because of an upper layer request.  The upper layer can specify
+    an Upper Layer Abort Reason that is transported by SCTP
+    transparently and MAY be delivered to the upper layer protocol
+    at the peer.
+
+
+
+
+Stewart, et al.              Informational                     [Page 46]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+      |         Cause Code=12         |      Cause Length=Variable    |
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+      /                    Upper Layer Abort Reason                   /
+      \                                                               \
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   ---------
+   Old text: (Section 9.1)
+   ---------
+
+   9.1 Abort of an Association
+
+      When an endpoint decides to abort an existing association, it
+      shall send an ABORT chunk to its peer endpoint.  The sender MUST
+      fill in the peer's Verification Tag in the outbound packet and
+      MUST NOT bundle any DATA chunk with the ABORT.
+
+      An endpoint MUST NOT respond to any received packet that contains
+      an ABORT chunk (also see Section 8.4).
+
+      An endpoint receiving an ABORT shall apply the special
+      Verification Tag check rules described in Section 8.5.1.
+
+      After checking the Verification Tag, the receiving endpoint shall
+      remove the association from its record and shall report the
+      termination to its upper layer.
+
+      ---------
+      New text: (Section 9.1)
+      ---------
+
+      9.1.  Abort of an Association
+
+      When an endpoint decides to abort an existing association, it MUST
+      send an ABORT chunk to its peer endpoint.  The sender MUST fill in
+      the peer's Verification Tag in the outbound packet and MUST NOT
+      bundle any DATA chunk with the ABORT.  If the association is
+      aborted on request of the upper layer, a User-Initiated Abort
+      error cause (see 3.3.10.12) SHOULD be present in the ABORT chunk.
+
+      An endpoint MUST NOT respond to any received packet that contains
+      an ABORT chunk (also see Section 8.4).
+
+      An endpoint receiving an ABORT MUST apply the special Verification
+      Tag check rules described in Section 8.5.1.
+
+      After checking the Verification Tag, the receiving endpoint MUST
+
+
+
+Stewart, et al.              Informational                     [Page 47]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+      remove the association from its record and SHOULD report the
+      termination to its upper layer.  If a User-Initiated Abort error
+      cause is present in the ABORT chunk, the Upper Layer Abort Reason
+      SHOULD be made available to the upper layer.
+
+   ---------
+   Old text: (Section 10.1)
+   ---------
+
+      D) Abort
+
+      Format: ABORT(association id [, cause code])
+      -> result
+
+      Ungracefully closes an association.  Any locally queued user
+      data will be discarded and an ABORT chunk is sent to the peer.
+      A success code will be returned on successful abortion of the
+      association.  If attempting to abort the association results
+      in a failure, an error code shall be returned.
+
+      Mandatory attributes:
+
+      o  association id - local handle to the SCTP association
+
+      Optional attributes:
+
+      o  cause code - reason of the abort to be passed to the peer.
+
+
+   ---------
+   New text: (Section 10.1)
+   ---------
+
+      D) Abort
+
+      Format: ABORT(association id [, Upper Layer Abort Reason])
+      -> result
+
+      Ungracefully closes an association.  Any locally queued user
+      data will be discarded, and an ABORT chunk is sent to the peer.
+      A success code will be returned on successful abortion of the
+      association.  If attempting to abort the association results
+      in a failure, an error code shall be returned.
+
+      Mandatory attributes:
+
+      o  association id - Local handle to the SCTP association.
+
+
+
+
+Stewart, et al.              Informational                     [Page 48]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+      Optional attributes:
+
+      o  Upper Layer Abort Reason - Reason of the abort to be passed
+         to the peer.
+
+      None.
+
+   ---------
+   Old text: (Section 10.2)
+   ---------
+
+      E) COMMUNICATION LOST notification
+
+      When SCTP loses communication to an endpoint completely (e.g., via
+      Heartbeats) or detects that the endpoint has performed an abort
+      operation, it shall invoke this notification on the ULP.
+
+      The following shall be passed with the notification:
+
+      o  association id - local handle to the SCTP association
+
+      o status - This indicates what type of event has occurred; The
+                 status may indicate a failure OR a normal termination
+                 event occurred in response to a shutdown or abort
+                 request.
+
+      The following may be passed with the notification:
+
+      o  data retrieval id - an identification used to retrieve
+         unsent and unacknowledged data.
+
+      o  last-acked - the TSN last acked by that peer endpoint;
+
+      o  last-sent - the TSN last sent to that peer endpoint;
+
+   ---------
+   New text: (Section 10.2)
+   ---------
+
+      E) COMMUNICATION LOST notification
+
+      When SCTP loses communication to an endpoint completely (e.g., via
+      Heartbeats) or detects that the endpoint has performed an abort
+      operation, it shall invoke this notification on the ULP.
+
+      The following shall be passed with the notification:
+
+      o  association id - Local handle to the SCTP association.
+
+
+
+Stewart, et al.              Informational                     [Page 49]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+      o  status - This indicates what type of event has occurred; The
+                  status may indicate that a failure OR a normal
+                  termination event occurred in response to a shutdown
+                  or abort request.
+
+      The following may be passed with the notification:
+
+      o  data retrieval id - An identification used to retrieve unsent
+         and unacknowledged data.
+
+      o  last-acked - The TSN last acked by that peer endpoint.
+
+      o  last-sent - The TSN last sent to that peer endpoint.
+
+      o  Upper Layer Abort Reason - The abort reason specified in
+                                    case of a user-initiated abort.
+
+2.21.3.  Solution Description
+
+   The above allows an upper layer to provide its peer with an
+   indication of why the association was aborted.  Therefore, an
+   addition error cause was introduced.
+
+2.22.  Handling of Invalid Initiate Tag of INIT-ACK
+
+2.22.1.  Description of the Problem
+
+   RFC 2960 requires that the receiver of an INIT-ACK with the Initiate
+   Tag set to zero handles this as an error and sends back an ABORT.
+   But the sender of the INIT-ACK normally has no TCB, and thus the
+   ABORT is useless.
+
+2.22.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 3.3.3)
+   ---------
+
+      Initiate Tag: 32 bits (unsigned integer)
+
+         The receiver of the INIT ACK records the value of the
+         Initiate Tag parameter.  This value MUST be placed into
+         the Verification Tag field of every SCTP packet that the
+         INIT ACK receiver transmits within this association.
+
+         The Initiate Tag MUST NOT take the value 0.  See Section 5.3.1
+         for more on the selection of the Initiate Tag value.
+
+
+
+
+Stewart, et al.              Informational                     [Page 50]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+         If the value of the Initiate Tag in a received INIT ACK chunk
+         is found to be 0, the receiver MUST treat it as an error and
+         close the association by transmitting an ABORT.
+
+   ---------
+   New text: (Section 3.3.3)
+   ---------
+
+      Initiate Tag: 32 bits (unsigned integer)
+
+         The receiver of the INIT ACK records the value of the
+         Initiate Tag parameter.  This value MUST be placed into
+         the Verification Tag field of every SCTP packet that the
+         INIT ACK receiver transmits within this association.
+
+         The Initiate Tag MUST NOT take the value 0.  See Section 5.3.1
+         for more on the selection of the Initiate Tag value.
+
+         If the value of the Initiate Tag in a received INIT ACK
+         chunk is found to be 0, the receiver MUST destroy the
+         association discarding its TCB.  The receiver MAY send an
+         ABORT for debugging purpose.
+
+2.22.3.  Solution Description
+
+   The new text does not require that the receiver of the invalid INIT-
+   ACK send the ABORT.  This behavior is in tune with the error case of
+   invalid stream numbers in the INIT-ACK.  However, sending an ABORT
+   for debugging purposes is allowed.
+
+2.23.  Sending an ABORT in Response to an INIT
+
+2.23.1.  Description of the Problem
+
+   Whenever the receiver of an INIT chunk has to send an ABORT chunk in
+   response, for whatever reason, it is not stated clearly which
+   Verification Tag and value of the T-bit should be used.
+
+2.23.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 8.4)
+   ---------
+
+      3) If the packet contains an INIT chunk with a Verification Tag
+         set to '0', process it as described in Section 5.1.
+         Otherwise,
+
+
+
+
+Stewart, et al.              Informational                     [Page 51]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   ---------
+   New text: (Section 8.4)
+   ---------
+
+      3) If the packet contains an INIT chunk with a Verification Tag
+         set to '0', process it as described in Section 5.1.  If, for
+         whatever reason, the INIT cannot be processed normally and
+         an ABORT has to be sent in response, the Verification Tag
+         of the packet containing the ABORT chunk MUST be the
+         Initiate tag of the received INIT chunk, and the T-Bit of
+         the ABORT chunk has to be set to 0, indicating that
+         a TCB was destroyed.  Otherwise,
+
+2.23.3.  Solution Description
+
+   The new text stated clearly which value of the Verification Tag and
+   T-bit have to be used.
+
+2.24.  Stream Sequence Number (SSN) Initialization
+
+2.24.1.  Description of the Problem
+
+   RFC 2960 does not describe the fact that the SSN has to be
+   initialized to 0, as required by RFC 2119.
+
+2.24.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 6.5)
+   ---------
+
+      The stream sequence number in all the streams shall start from 0
+      when the association is established.  Also, when the stream
+      sequence number reaches the value 65535 the next stream sequence
+      number shall be set to 0.
+
+   ---------
+   New text: (Section 6.5)
+   ---------
+
+      The stream sequence number in all the streams MUST start from 0
+      when the association is established.  Also, when the stream
+      sequence number reaches the value 65535 the next stream sequence
+      number MUST be set to 0.
+
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 52]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+2.24.3.  Solution Description
+
+   The 'shall' in the text is replaced by a 'MUST' to clearly state the
+   required behavior.
+
+2.25.  SACK Packet Format
+
+2.25.1.  Description of the Problem
+
+   It is not clear in RFC 2960 whether a SACK must contain the fields
+   Number of Gap Ack Blocks and Number of Duplicate TSNs.
+
+2.25.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 3.3.4)
+   ---------
+
+      The SACK MUST contain the Cumulative TSN Ack and
+      Advertised Receiver Window Credit (a_rwnd) parameters.
+
+   ---------
+   New text: (Section 3.3.4)
+   ---------
+
+      The SACK MUST contain the Cumulative TSN Ack,
+      Advertised Receiver Window Credit (a_rwnd), Number
+      of Gap Ack Blocks, and Number of Duplicate TSNs fields.
+
+2.25.3.  Solution Description
+
+   The text has been modified.  It is now clear that a SACK always
+   contains the fields Number of Gap Ack Blocks and Number of Duplicate
+   TSNs.
+
+2.26.  Protocol Violation Error Cause
+
+2.26.1.  Description of the Problem
+
+   There are many situations where an SCTP endpoint may detect that its
+   peer violates the protocol.  The result of such detection often
+   results in the association being destroyed by the sending of an
+   ABORT.  Currently, there are only some error causes that could be
+   used to indicate the reason for the abort, but these do not cover all
+   cases.
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 53]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+2.26.2.  Text Changes to the Document
+
+   Some of the changes given here already include changes suggested in
+   Section 2.6 and 2.21 of this document.
+
+   ---------
+   Old text: (Section 3.3.10)
+   ---------
+
+      Cause Code
+      Value           Cause Code
+      ---------      ----------------
+       1              Invalid Stream Identifier
+       2              Missing Mandatory Parameter
+       3              Stale Cookie Error
+       4              Out of Resource
+       5              Unresolvable Address
+       6              Unrecognized Chunk Type
+       7              Invalid Mandatory Parameter
+       8              Unrecognized Parameters
+       9              No User Data
+      10              Cookie Received While Shutting Down
+
+   Cause Length: 16 bits (unsigned integer)
+
+      Set to the size of the parameter in bytes, including the Cause
+      Code, Cause Length, and Cause-Specific Information fields
+
+   Cause-specific Information: variable length
+
+      This field carries the details of the error condition.
+
+   Sections 3.3.10.1 - 3.3.10.10 define error causes for SCTP.
+   Guidelines for the IETF to define new error cause values are
+   discussed in Section 13.3.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 54]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   ---------
+   New text: (Section 3.3.10)
+   ---------
+
+      Cause Code
+      Value           Cause Code
+      ---------      ----------------
+       1              Invalid Stream Identifier
+       2              Missing Mandatory Parameter
+       3              Stale Cookie Error
+       4              Out of Resource
+       5              Unresolvable Address
+       6              Unrecognized Chunk Type
+       7              Invalid Mandatory Parameter
+       8              Unrecognized Parameters
+       9              No User Data
+      10              Cookie Received While Shutting Down
+      11              Restart of an Association with New Addresses
+      12              User Initiated Abort
+      13              Protocol Violation
+
+   Cause Length: 16 bits (unsigned integer)
+
+      Set to the size of the parameter in bytes, including the Cause
+      Code, Cause Length, and Cause-Specific Information fields
+
+   Cause-specific Information: variable length
+
+      This field carries the details of the error condition.
+
+   Sections 3.3.10.1 - 3.3.10.13 define error causes for SCTP.
+   Guidelines for the IETF to define new error cause values are
+   discussed in Section 13.3.
+
+   ---------
+   New text: (Note: no old text; new error added in section 3.3.10)
+   ---------
+
+   3.3.10.13.  Protocol Violation (13)
+
+    Cause of error
+    --------------
+
+    This error cause MAY be included in ABORT chunks that are sent
+    because an SCTP endpoint detects a protocol violation of the peer
+    that is not covered by the error causes described in 3.3.10.1 to
+    3.3.10.12.  An implementation MAY provide additional information
+    specifying what kind of protocol violation has been detected.
+
+
+
+Stewart, et al.              Informational                     [Page 55]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+      |         Cause Code=13         |      Cause Length=Variable    |
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+      /                    Additional Information                     /
+      \                                                               \
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+2.26.3.  Solution Description
+
+   An additional error cause has been defined that can be used by an
+   endpoint to indicate a protocol violation of the peer.
+
+2.27.  Reporting of Unrecognized Parameters
+
+2.27.1.  Description of the Problem
+
+   It is not stated clearly in RFC 2960 [5] how unrecognized parameters
+   should be reported.  Unrecognized parameters in an INIT chunk could
+   be reported in the INIT-ACK chunk or in a separate ERROR chunk, which
+   can get lost.  Unrecognized parameters in an INIT-ACK chunk have to
+   be reported in an ERROR-chunk.  This can be bundled with the COOKIE-
+   ERROR chunk or sent separately.  If it is sent separately and
+   received before the COOKIE-ECHO, it will be handled as an OOTB
+   packet, resulting in sending out an ABORT chunk.  Therefore, the
+   association would not be established.
+
+2.27.2.  Text Changes to the Document
+
+   Some of the changes given here already include changes suggested in
+   Section 2.2 of this document.
+
+   ---------
+   Old text: (Section 3.2.1)
+   ---------
+
+   00 - Stop processing this SCTP packet and discard it, do not process
+        any further chunks within it.
+
+   01 - Stop processing this SCTP packet and discard it, do not process
+        any further chunks within it, and report the unrecognized
+        parameter in an 'Unrecognized Parameter Type' (in either an
+        ERROR or in the INIT ACK).
+
+   10 - Skip this parameter and continue processing.
+
+   11 - Skip this parameter and continue processing but report the
+        unrecognized parameter in an 'Unrecognized Parameter Type' (in
+        either an ERROR or in the INIT ACK).
+
+
+
+Stewart, et al.              Informational                     [Page 56]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   ---------
+   New text: (Section 3.2.1)
+   ---------
+
+   00 - Stop processing this SCTP chunk and discard it; do not process
+        any further parameters within this chunk.
+
+   01 - Stop processing this SCTP chunk and discard it, do not process
+        any further parameters within this chunk, and report the
+        unrecognized parameter in an 'Unrecognized Parameter Type', as
+        described in 3.2.2.
+
+   10 - Skip this parameter and continue processing.
+
+   11 - Skip this parameter and continue processing but report the
+        unrecognized parameter in an 'Unrecognized Parameter Type', as
+        described in 3.2.2.
+
+   ---------
+   New text: (Note: no old text; clarification added in Section 3.2)
+   ---------
+
+   3.2.2.  Reporting of Unrecognized Parameters
+
+      If the receiver of an INIT chunk detects unrecognized parameters
+      and has to report them according to Section 3.2.1, it MUST put
+      the 'Unrecognized Parameter' parameter(s) in the INIT-ACK chunk
+      sent in response to the INIT-chunk.  Note that if the receiver
+      of the INIT chunk is NOT going to establish an association (e.g.,
+      due to lack of resources), then no report would be sent back.
+
+      If the receiver of an INIT-ACK chunk detects unrecognized
+      parameters and has to report them according to Section 3.2.1,
+      it SHOULD bundle the ERROR chunk containing the
+      'Unrecognized Parameter' error cause with the COOKIE-ECHO
+      chunk sent in response to the INIT-ACK chunk.  If the
+      receiver of the INIT-ACK cannot bundle the COOKIE-ECHO chunk
+      with the ERROR chunk, the ERROR chunk MAY be sent separately
+      but not before the COOKIE-ACK has been received.
+
+      Note: Any time a COOKIE-ECHO is sent in a packet, it MUST be the
+      first chunk.
+
+2.27.3.  Solution Description
+
+   The procedure of reporting unrecognized parameters has been described
+   clearly.
+
+
+
+
+Stewart, et al.              Informational                     [Page 57]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+2.28.  Handling of IP Address Parameters
+
+2.28.1.  Description of the Problem
+
+   It is not stated clearly in RFC 2960 [5] how an SCTP endpoint that
+   supports either IPv4 addresses or IPv6 addresses should respond if
+   IPv4 and IPv6 addresses are presented by the peer in the INIT or
+   INIT-ACK chunk.
+
+2.28.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 5.1.2)
+   ---------
+
+      IMPLEMENTATION NOTE: In the case that the receiver of an INIT ACK
+      fails to resolve the address parameter due to an unsupported type,
+      it can abort the initiation process and then attempt a
+      re-initiation by using a 'Supported Address Types' parameter in
+      the new INIT to indicate what types of address it prefers.
+
+   ---------
+   New text: (Section 5.1.2)
+   ---------
+
+      IMPLEMENTATION NOTE: In the case that the receiver of an INIT ACK
+      fails to resolve the address parameter due to an unsupported type,
+      it can abort the initiation process and then attempt a re-
+      initiation by using a 'Supported Address Types' parameter in the
+      new INIT to indicate what types of address it prefers.
+
+      IMPLEMENTATION NOTE: If an SCTP endpoint that only supports either
+      IPv4 or IPv6 receives IPv4 and IPv6 addresses in an INIT or INIT-
+      ACK chunk from its peer, it MUST use all the addresses belonging
+      to the supported address family.  The other addresses MAY be
+      ignored.  The endpoint SHOULD NOT respond with any kind of error
+      indication.
+
+2.28.3.  Solution Description
+
+   The procedure of handling IP address parameters has been described
+   clearly.
+
+
+
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 58]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+2.29.  Handling of COOKIE ECHO Chunks When a TCB Exists
+
+2.29.1.  Description of the Problem
+
+   The description of the behavior in RFC 2960 [5] when a COOKIE ECHO
+   chunk and a TCB exist could be misunderstood.  When a COOKIE ECHO is
+   received, a TCB exists and the local tag and peer's tag match, it is
+   stated that the endpoint should enter the ESTABLISHED state if it has
+   not already done so and send a COOKIE ACK.  It was not clear that, in
+   the case the endpoint has already left the ESTABLISHED state again,
+   then it should not go back to established.  In case D, the endpoint
+   can only enter state ESTABLISHED from COOKIE-ECHOED because in state
+   CLOSED it has no TCB and in state COOKIE-WAIT it has a TCB but knows
+   nothing about the peer's tag, which is requested to match in this
+   case.
+
+2.29.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 5.2.4)
+   ---------
+      D) When both local and remote tags match the endpoint should
+         always enter the ESTABLISHED state, if it has not already
+         done so.  It should stop any init or cookie timers that may
+         be running and send a COOKIE ACK.
+
+   ---------
+   New text: (Section 5.2.4)
+   ---------
+      D) When both local and remote tags match, the endpoint should
+         enter the ESTABLISHED state, if it is in the COOKIE-ECHOED
+         state.  It should stop any cookie timer that may
+         be running and send a COOKIE ACK.
+
+2.29.3.  Solution Description
+
+   The procedure of handling of COOKIE-ECHO chunks when a TCB exists has
+   been described clearly.
+
+2.30.  The Initial Congestion Window Size
+
+2.30.1.  Description of the Problem
+
+   RFC 2960 was published with the intention of having the same
+   congestion control properties as TCP.  Since the publication of RFC
+   2960, TCP's initial congestion window size has been increased via RFC
+   3390.  This same update will be needed for SCTP to keep SCTP's
+   congestion control properties equivalent to that of TCP.
+
+
+
+Stewart, et al.              Informational                     [Page 59]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+2.30.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 7.2.1)
+   ---------
+      o  The initial cwnd before DATA transmission or after a
+         sufficiently long idle period MUST be <= 2*MTU.
+
+   ---------
+   New text: (Section 7.2.1)
+   ---------
+      o  The initial cwnd before DATA transmission or after a
+         sufficiently long idle period MUST be set to
+         min(4*MTU, max (2*MTU, 4380 bytes)).
+
+   ---------
+   Old text: (Section 7.2.1)
+   ---------
+      o  When the endpoint does not transmit data on a given transport
+         address, the cwnd of the transport address should be adjusted
+         to max(cwnd/2, 2*MTU) per RTO.
+
+   ---------
+   New text: (Section 7.2.1)
+   ---------
+      o  When the endpoint does not transmit data on a given transport
+         address, the cwnd of the transport address should be adjusted
+         to max(cwnd/2, 4*MTU) per RTO.
+
+   ---------
+   Old text: (Section 7.2.2)
+   ---------
+      o  Same as in the slow start, when the sender does not transmit
+         DATA on a given transport address, the cwnd of the transport
+         address should be adjusted to max(cwnd / 2, 2*MTU) per RTO.
+
+   ---------
+   New text: (Section 7.2.2)
+   ---------
+      o  Same as in the slow start, when the sender does not transmit
+         DATA on a given transport address, the cwnd of the transport
+         address should be adjusted to max(cwnd / 2, 4*MTU) per RTO.
+
+
+
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 60]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   ---------
+   Old text: (Section 7.2.3)
+   ---------
+
+   7.2.3.  Congestion Control
+
+      Upon detection of packet losses from SACK  (see Section 7.2.4), an
+      endpoint should do the following:
+
+         ssthresh = max(cwnd/2, 2*MTU)
+         cwnd = ssthresh
+
+      Basically, a packet loss causes cwnd to be cut in half.
+
+      When the T3-rtx timer expires on an address, SCTP should perform
+      slow start by
+
+         ssthresh = max(cwnd/2, 2*MTU)
+         cwnd = 1*MTU
+
+   ---------
+   New text: (Section 7.2.3)
+   ---------
+
+   7.2.3 Congestion Control
+
+      Upon detection of packet losses from SACK  (see Section 7.2.4), An
+      endpoint should do the following:
+
+         ssthresh = max(cwnd/2, 4*MTU)
+         cwnd = ssthresh
+
+      Basically, a packet loss causes cwnd to be cut in half.
+
+      When the T3-rtx timer expires on an address, SCTP should perform
+      slow start by:
+
+         ssthresh = max(cwnd/2, 4*MTU)
+         cwnd = 1*MTU
+
+2.30.3.  Solution Description
+
+   The change to SCTP's initial congestion window will allow it to
+   continue to maintain the same congestion control properties as TCP.
+
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 61]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+2.31.  Stream Sequence Numbers in Figures
+
+2.31.1.  Description of the Problem
+
+   In Section 2.24 of this document, it is clarified that the SSN are
+   initialized with 0.  Two figures in RFC 2960 [5] illustrate that they
+   start with 1.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 62]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+2.31.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 7.2.1)
+   ---------
+
+    Endpoint A                                          Endpoint Z
+    {app sets association with Z}
+    (build TCB)
+    INIT [I-Tag=Tag_A
+          & other info]  ------\
+    (Start T1-init timer)       \
+    (Enter COOKIE-WAIT state)    \---> (compose temp TCB and Cookie_Z)
+                                   /-- INIT ACK [Veri Tag=Tag_A,
+                                  /             I-Tag=Tag_Z,
+    (Cancel T1-init timer) <-----/               Cookie_Z, & other info]
+                                           (destroy temp TCB)
+    COOKIE ECHO [Cookie_Z] ------\
+    (Start T1-init timer)         \
+    (Enter COOKIE-ECHOED state)    \---> (build TCB enter ESTABLISHED
+                                          state)
+                                   /---- COOKIE-ACK
+                                  /
+    (Cancel T1-init timer, <-----/
+     Enter ESTABLISHED state)
+    {app sends 1st user data; strm 0}
+     DATA [TSN=initial TSN_A
+         Strm=0,Seq=1 & user data]--\
+     (Start T3-rtx timer)            \
+                                      \->
+                                  /----- SACK [TSN Ack=init
+                                 /              TSN_A,Block=0]
+   (Cancel T3-rtx timer) <------/
+                                          ...
+                                          {app sends 2 messages;strm 0}
+                                    /---- DATA
+                                   /        [TSN=init TSN_Z
+                               <--/          Strm=0,Seq=1 & user data 1]
+   SACK [TSN Ack=init TSN_Z,     /    ---- DATA
+            Block=0]     --------\  /        [TSN=init TSN_Z +1,
+                                  \/         Strm=0,Seq=2 & user data 2]
+                           <------/\
+                                    \
+                                     \------>
+
+                        Figure 4: INITiation Example
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 63]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   ---------
+   New text: (Section 7.2.1)
+   ---------
+
+
+    Endpoint A                                          Endpoint Z
+    {app sets association with Z}
+    (build TCB)
+    INIT [I-Tag=Tag_A
+          & other info]  ------\
+    (Start T1-init timer)       \
+    (Enter COOKIE-WAIT state)    \---> (compose temp TCB and Cookie_Z)
+                                    /-- INIT ACK [Veri Tag=Tag_A,
+                                   /             I-Tag=Tag_Z,
+    (Cancel T1-init timer) <------/              Cookie_Z, & other info]
+                                         (destroy temp TCB)
+    COOKIE ECHO [Cookie_Z] ------\
+    (Start T1-init timer)         \
+    (Enter COOKIE-ECHOED state)    \---> (build TCB enter ESTABLISHED
+                                          state)
+                                   /---- COOKIE-ACK
+                                  /
+    (Cancel T1-init timer, <-----/
+     Enter ESTABLISHED state)
+    {app sends 1st user data; strm 0}
+    DATA [TSN=initial TSN_A
+        Strm=0,Seq=0 & user data]--\
+    (Start T3-rtx timer)            \
+                                     \->
+                                   /----- SACK [TSN Ack=init
+                                  /           TSN_A,Block=0]
+    (Cancel T3-rtx timer) <------/
+                                          ...
+                                         {app sends 2 messages;strm 0}
+                                   /---- DATA
+                                  /        [TSN=init TSN_Z
+                              <--/          Strm=0,Seq=0 & user data 1]
+    SACK [TSN Ack=init TSN_Z,      /---- DATA
+          Block=0]     --------\  /        [TSN=init TSN_Z +1,
+                                \/          Strm=0,Seq=1 & user data 2]
+                         <------/\
+                                  \
+                                   \------>
+
+                       Figure 4: INITiation Example
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 64]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   ---------
+   Old text: (Section 5.2.4.1)
+   ---------
+
+   Endpoint A                                          Endpoint Z
+   <------------ Association is established---------------------->
+   Tag=Tag_A                                             Tag=Tag_Z
+   <------------------------------------------------------------->
+   {A crashes and restarts}
+   {app sets up a association with Z}
+   (build TCB)
+   INIT [I-Tag=Tag_A'
+         & other info]  --------\
+   (Start T1-init timer)         \
+   (Enter COOKIE-WAIT state)      \---> (find a existing TCB
+                                         compose temp TCB and Cookie_Z
+                                         with Tie-Tags to previous
+                                         association)
+                                   /--- INIT ACK [Veri Tag=Tag_A',
+                                  /               I-Tag=Tag_Z',
+   (Cancel T1-init timer) <------/                Cookie_Z[TieTags=
+                                                  Tag_A,Tag_Z
+                                                   & other info]
+                                        (destroy temp TCB,leave original
+                                         in place)
+   COOKIE ECHO [Veri=Tag_Z',
+                Cookie_Z
+                Tie=Tag_A,
+                Tag_Z]----------\
+   (Start T1-init timer)         \
+   (Enter COOKIE-ECHOED state)    \---> (Find existing association,
+                                         Tie-Tags match old tags,
+                                         Tags do not match i.e.,
+                                         case X X M M above,
+                                         Announce Restart to ULP
+                                         and reset association).
+                                  /---- COOKIE-ACK
+   (Cancel T1-init timer, <------/
+    Enter ESTABLISHED state)
+   {app sends 1st user data; strm 0}
+   DATA [TSN=initial TSN_A
+       Strm=0,Seq=1 & user data]--\
+   (Start T3-rtx timer)            \
+                                    \->
+                                 /--- SACK [TSN Ack=init TSN_A,Block=0]
+   (Cancel T3-rtx timer) <------/
+
+                     Figure 5: A Restart Example
+
+
+
+Stewart, et al.              Informational                     [Page 65]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   ---------
+   New text: (Section 5.2.4.1)
+   ---------
+
+   Endpoint A                                          Endpoint Z
+   <-------------- Association is established---------------------->
+   Tag=Tag_A                                             Tag=Tag_Z
+   <--------------------------------------------------------------->
+   {A crashes and restarts}
+   {app sets up a association with Z}
+   (build TCB)
+   INIT [I-Tag=Tag_A'
+         & other info]  --------\
+   (Start T1-init timer)         \
+   (Enter COOKIE-WAIT state)      \---> (find a existing TCB
+                                         compose temp TCB and Cookie_Z
+                                         with Tie-Tags to previous
+                                         association)
+                                   /--- INIT ACK [Veri Tag=Tag_A',
+                                  /               I-Tag=Tag_Z',
+   (Cancel T1-init timer) <------/                Cookie_Z[TieTags=
+                                                  Tag_A,Tag_Z
+                                                   & other info]
+                                        (destroy temp TCB,leave original
+                                         in place)
+   COOKIE ECHO [Veri=Tag_Z',
+                Cookie_Z
+                Tie=Tag_A,
+                Tag_Z]----------\
+   (Start T1-init timer)         \
+   (Enter COOKIE-ECHOED state)    \---> (Find existing association,
+                                         Tie-Tags match old tags,
+                                         Tags do not match i.e.,
+                                         case X X M M above,
+                                         Announce Restart to ULP
+                                         and reset association).
+                                  /---- COOKIE-ACK
+   (Cancel T1-init timer, <------/
+    Enter ESTABLISHED state)
+   {app sends 1st user data; strm 0}
+   DATA [TSN=initial TSN_A
+       Strm=0,Seq=0 & user data]--\
+   (Start T3-rtx timer)            \
+                                    \->
+                                 /--- SACK [TSN Ack=init TSN_A,Block=0]
+   (Cancel T3-rtx timer) <------/
+
+                     Figure 5: A Restart Example
+
+
+
+Stewart, et al.              Informational                     [Page 66]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+2.31.3.  Solution description
+
+   Figure 4 and 5 were changed so that the SSN starts with 0 instead of
+   1.
+
+2.32.  Unrecognized Parameters
+
+2.32.1.  Description of the Problem
+
+   The RFC does not state clearly in Section 3.3.3.1 whether one or
+   multiple unrecognized parameters are included in the 'Unrecognized
+   Parameter' parameter.
+
+2.32.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 3.3.3)
+   ---------
+         Variable Parameters                  Status     Type Value
+         -------------------------------------------------------------
+         State Cookie                        Mandatory   7
+         IPv4 Address (Note 1)               Optional    5
+         IPv6 Address (Note 1)               Optional    6
+         Unrecognized Parameters             Optional    8
+         Reserved for ECN Capable (Note 2)   Optional    32768 (0x8000)
+         Host Name Address (Note 3)          Optional    11
+
+   ---------
+   New text: (Section 3.3.3)
+   ---------
+         Variable Parameters                  Status     Type Value
+         -------------------------------------------------------------
+         State Cookie                        Mandatory   7
+         IPv4 Address (Note 1)               Optional    5
+         IPv6 Address (Note 1)               Optional    6
+         Unrecognized Parameter              Optional    8
+         Reserved for ECN Capable (Note 2)   Optional    32768 (0x8000)
+         Host Name Address (Note 3)          Optional    11
+
+
+   ---------
+   Old text: (Section 3.3.3.1)
+   ---------
+      Unrecognized Parameters:
+
+         Parameter Type Value: 8
+
+         Parameter Length:  Variable Size.
+
+
+
+Stewart, et al.              Informational                     [Page 67]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+         Parameter Value:
+            This parameter is returned to the originator of the INIT
+            chunk when the INIT contains an unrecognized parameter
+            which has a value that indicates that it should be reported
+            to the sender.  This parameter value field will contain
+            unrecognized parameters copied from the INIT chunk complete
+            with Parameter Type, Length and Value fields.
+
+   ---------
+   New text: (Section 3.3.3.1)
+   ---------
+      Unrecognized Parameter:
+
+         Parameter Type Value: 8
+
+         Parameter Length:  Variable Size.
+
+         Parameter Value:
+
+            This parameter is returned to the originator of the INIT
+            chunk when the INIT contains an unrecognized parameter
+            that has a value that indicates that it should be reported
+            to the sender.  This parameter value field will contain the
+            unrecognized parameter copied from the INIT chunk complete
+            with Parameter Type, Length, and Value fields.
+
+2.32.3.  Solution Description
+
+   The new text states clearly that only one unrecognized parameter is
+   reported per parameter.
+
+2.33.  Handling of Unrecognized Parameters
+
+2.33.1.  Description of the Problem
+
+   It is not stated clearly in RFC 2960 [5] how unrecognized parameters
+   should be handled.  The problem comes up when an INIT contains an
+   unrecognized parameter with highest bits 00.  It was not clear
+   whether an INIT-ACK should be sent.
+
+2.33.2.  Text Changes to the Document
+
+   Some of the changes given here already include changes suggested in
+   Section 2.27 of this document.
+
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 68]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   ---------
+   Old text: (Section 3.2.1)
+   ---------
+
+   00 - Stop processing this SCTP packet and discard it, do not process
+        any further chunks within it.
+
+   01 - Stop processing this SCTP packet and discard it, do not process
+        any further chunks within it, and report the unrecognized
+        parameter in an 'Unrecognized Parameter Type' (in either an
+        ERROR or in the INIT ACK).
+
+   10 - Skip this parameter and continue processing.
+
+   11 - Skip this parameter and continue processing but report the
+        unrecognized parameter in an 'Unrecognized Parameter Type' (in
+        either an ERROR or in the INIT ACK).
+
+   ---------
+   New text: (Section 3.2.1)
+   ---------
+
+   00 - Stop processing this parameter; do not process
+        any further parameters within this chunk.
+
+   01 - Stop processing this parameter, do not process
+        any further parameters within this chunk, and report the
+        unrecognized parameter in an 'Unrecognized Parameter Type', as
+        described in 3.2.2.
+
+   10 - Skip this parameter and continue processing.
+
+   11 - Skip this parameter and continue processing but report the
+        unrecognized parameter in an 'Unrecognized Parameter Type', as
+        described in 3.2.2.
+
+
+   ---------
+   New text: (Note: no old text; clarification added in section 3.2)
+   ---------
+
+   3.2.2.  Reporting of Unrecognized Parameters
+
+   If the receiver of an INIT chunk detects unrecognized parameters and
+   has to report them according to Section 3.2.1, it MUST put the
+   'Unrecognized Parameter' parameter(s) in the INIT-ACK chunk sent in
+   response to the INIT-chunk.  Note that if the receiver of the INIT
+   chunk is NOT going to establish an association (e.g., due to lack of
+
+
+
+Stewart, et al.              Informational                     [Page 69]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   resources), an 'Unrecognized Parameter' would NOT be included with
+   any ABORT being sent to the sender of the INIT.
+
+   If the receiver of an INIT-ACK chunk detects unrecognized parameters
+   and has to report them according to Section 3.2.1, it SHOULD bundle
+   the ERROR chunk containing the 'Unrecognized Parameter' error cause
+   with the COOKIE-ECHO chunk sent in response to the INIT-ACK chunk.
+   If the receiver of the INIT-ACK cannot bundle the COOKIE-ECHO chunk
+   with the ERROR chunk, the ERROR chunk MAY be sent separately but not
+   before the COOKIE-ACK has been received.
+
+   Note: Any time a COOKIE-ECHO is sent in a packet, it MUST be the
+   first chunk.
+
+2.33.3.  Solution Description
+
+   The procedure of handling unrecognized parameters has been described
+   clearly.
+
+2.34.  Tie Tags
+
+2.34.1.  Description of the Problem
+
+   RFC 2960 requires that Tie-Tags be included in the COOKIE.  The
+   cookie may not be encrypted.  An attacker could discover the value of
+   the Verification Tags by analyzing cookies received after sending an
+   INIT.
+
+2.34.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 1.4)
+   ---------
+      o  Tie-Tags: Verification Tags from a previous association.  These
+         Tags are used within a State Cookie so that the newly
+         restarting association can be linked to the original
+         association within the endpoint that did not restart.
+
+   ---------
+   New text: (Section 1.4)
+   ---------
+
+      o  Tie-Tags: Two 32-bit random numbers that together make a 64-
+         bit nonce.  These Tags are used within a State Cookie and TCB
+         so that a newly restarting association can be linked to the
+         original association within the endpoint that did not restart
+         and yet not reveal the true Verification Tags of an existing
+         association.
+
+
+
+Stewart, et al.              Informational                     [Page 70]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   ---------
+   Old text: (Section 5.2.1)
+   ---------
+
+      For an endpoint that is in the COOKIE-ECHOED state it MUST
+      populate its Tie-Tags with the Tag information of itself and
+      its peer (see Section 5.2.2 for a description of the Tie-Tags).
+
+   ---------
+   New text: (Section 5.2.1)
+   ---------
+      For an endpoint that is in the COOKIE-ECHOED state it MUST
+      populate its Tie-Tags within both the association TCB and
+      inside the State Cookie (see section 5.2.2 for a description
+      of the Tie-Tags).
+
+
+   ---------
+   Old text: (Section 5.2.2)
+   ---------
+      Unless otherwise stated, upon reception of an unexpected INIT for
+      this association, the endpoint shall generate an INIT ACK with a
+      State Cookie.  In the outbound INIT ACK the endpoint MUST copy its
+      current Verification Tag and peer's Verification Tag into a
+      reserved place within the state cookie.  We shall refer to these
+      locations as the Peer's-Tie-Tag and the Local-Tie-Tag.  The
+      outbound SCTP packet containing this INIT ACK MUST carry a
+      Verification Tag value equal to the Initiation Tag found in the
+      unexpected INIT.  And the INIT ACK MUST contain a new Initiation
+      Tag (randomly generated see Section 5.3.1).  Other parameters
+      for the endpoint SHOULD be copied from the existing parameters
+      of the association (e.g., number of outbound streams) into the
+      INIT ACK and cookie.
+
+   ---------
+   New text: (Section 5.2.2)
+   ---------
+
+      Unless otherwise stated, upon receipt of an unexpected INIT for
+      this association, the endpoint MUST generate an INIT ACK with a
+      State Cookie.  In the outbound INIT ACK, the endpoint MUST copy
+      its current Tie-Tags to a reserved place within the State Cookie
+      and the association's TCB.  We shall refer to these locations
+      inside the cookie as the Peer's-Tie-Tag and the Local-Tie-Tag.  We
+      will refer to the copy within an association's TCB as the Local
+      Tag and Peer's Tag.  The outbound SCTP packet containing this INIT
+      ACK MUST carry a Verification Tag value equal to the Initiation
+      Tag found in the unexpected INIT.  And the INIT ACK MUST contain a
+
+
+
+Stewart, et al.              Informational                     [Page 71]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+      new Initiation Tag (randomly generated; see Section 5.3.1).  Other
+      parameters for the endpoint SHOULD be copied from the existing
+      parameters of the association (e.g., number of outbound streams)
+      into the INIT ACK and cookie.
+
+2.34.3.  Solution Description
+
+   The solution to this problem is not to use the real Verification Tags
+   within the State Cookie as tie-tags.  Instead, two 32-bit random
+   numbers are created to form one 64-bit nonce and stored both in the
+   State Cookie and the existing association TCB.  This prevents
+   exposing the Verification Tags inadvertently.
+
+2.35.  Port Number Verification in the COOKIE-ECHO
+
+2.35.1.  Description of the Problem
+
+   The State Cookie sent by a listening SCTP endpoint may not contain
+   the original port numbers or the local Verification Tag.  It is then
+   possible that the endpoint, on receipt of the COOKIE-ECHO, will not
+   be able to verify that these values match the original values found
+   in the INIT and INIT-ACK that began the association setup.
+
+2.35.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 5.1.5)
+   ---------
+      3) Compare the creation timestamp in the State Cookie to the
+         current local time.  If the elapsed time is longer than the
+         lifespan carried in the State Cookie, then the packet,
+         including the COOKIE ECHO and any attached DATA chunks,
+         SHOULD be discarded and the endpoint MUST transmit an ERROR
+         chunk with a "Stale Cookie" error cause to the peer endpoint,
+
+      4) If the State Cookie is valid, create an association to the
+         sender of the COOKIE ECHO chunk with the information in the
+         TCB data carried in the COOKIE ECHO, and enter the
+         ESTABLISHED state,
+
+      5) Send a COOKIE ACK chunk to the peer acknowledging reception
+         of the COOKIE ECHO.  The COOKIE ACK MAY be bundled with an
+         outbound DATA chunk or SACK chunk; however, the COOKIE ACK
+         MUST be the first chunk in the SCTP packet.
+
+      6) Immediately acknowledge any DATA chunk bundled with the COOKIE
+         ECHO with a SACK (subsequent DATA chunk acknowledgement should
+         follow the rules defined in Section 6.2).  As mentioned in step
+
+
+
+Stewart, et al.              Informational                     [Page 72]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+         5), if the SACK is bundled with the COOKIE ACK, the COOKIE ACK
+         MUST appear first in the SCTP packet.
+
+   ---------
+   New text: (Section 5.1.5)
+   ---------
+
+      3) Compare the port numbers and the Verification Tag contained
+         within the COOKIE ECHO chunk to the actual port numbers and the
+         Verification Tag within the SCTP common header of the received
+         packet.  If these values do not match, the packet MUST be
+         silently discarded.
+
+      4) Compare the creation timestamp in the State Cookie to the
+         current local time.  If the elapsed time is longer than the
+         lifespan carried in the State Cookie, then the packet,
+         including the COOKIE ECHO and any attached DATA chunks,
+         SHOULD be discarded, and the endpoint MUST transmit an
+         ERROR chunk with a "Stale Cookie" error cause to the peer
+         endpoint.
+
+      5) If the State Cookie is valid, create an association to the
+         sender of the COOKIE ECHO chunk with the information in the
+         TCB data carried in the COOKIE ECHO and enter the
+         ESTABLISHED state.
+
+      6) Send a COOKIE ACK chunk to the peer acknowledging receipt of
+         the COOKIE ECHO.  The COOKIE ACK MAY be bundled with an
+         outbound DATA chunk or SACK chunk; however, the COOKIE ACK
+         MUST be the first chunk in the SCTP packet.
+
+      7) Immediately acknowledge any DATA chunk bundled with the COOKIE
+         ECHO with a SACK (subsequent DATA chunk acknowledgement should
+         follow the rules defined in Section 6.2).  As mentioned in step
+         5, if the SACK is bundled with the COOKIE ACK, the COOKIE ACK
+         MUST appear first in the SCTP packet.
+
+2.35.3.  Solution Description
+
+   By including both port numbers and the local Verification Tag within
+   the State Cookie and verifying these during COOKIE-ECHO processing,
+   this issue is resolved.
+
+
+
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 73]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+2.36.  Path Initialization
+
+2.36.1.  Description of the Problem
+
+   When an association enters the ESTABLISHED state, the endpoint has no
+   verification that all of the addresses presented by the peer do in
+   fact belong to the peer.  This could cause various forms of denial of
+   service attacks.
+
+2.36.2.  Text Changes to the Document
+
+   ---------
+   Old text: None
+   ---------
+
+   ---------
+   New text: (Section 5.4)
+   ---------
+   5.4.  Path Verification
+
+   During association establishment, the two peers exchange a list of
+   addresses.  In the predominant case, these lists accurately represent
+   the addresses owned by each peer.  However, it is possible that a
+   misbehaving peer may supply addresses that it does not own.  To
+   prevent this, the following rules are applied to all addresses of the
+   new association:
+
+   1) Any address passed to the sender of the INIT by its upper layer is
+      automatically considered to be CONFIRMED.
+
+   2) For the receiver of the COOKIE-ECHO the only CONFIRMED address is
+      the one that the INIT-ACK was sent to.
+
+   3) All other addresses not covered by rules 1 and 2 are considered
+      UNCONFIRMED and are subject to probing for verification.
+
+   To probe an address for verification, an endpoint will send
+   HEARTBEATs including a 64-bit random nonce and a path indicator (to
+   identify the address that the HEARTBEAT is sent to) within the
+   HEARTBEAT parameter.
+
+   Upon receipt of the HEARTBEAT-ACK, a verification is made that the
+   nonce included in the HEARTBEAT parameter is the one sent to the
+   address indicated inside the HEARTBEAT parameter.  When this match
+   occurs, the address that the original HEARTBEAT was sent to is now
+   considered CONFIRMED and available for normal data transfer.
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 74]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   These probing procedures are started when an association moves to the
+   ESTABLISHED state and are ended when all paths are confirmed.
+
+   Each RTO a probe may be sent on an active UNCONFIRMED path in an
+   attempt to move it to the CONFIRMED state.  If during this probing
+   the path becomes inactive, this rate is lowered to the normal
+   HEARTBEAT rate.  At the expiration of the RTO timer, the error
+   counter of any path that was probed but not CONFIRMED is incremented
+   by one and subjected to path failure detection, as defined in section
+   8.2.  When probing UNCONFIRMED addresses, however, the association
+   overall error count is NOT incremented.
+
+   The number of HEARTBEATS sent at each RTO SHOULD be limited by the
+   HB.Max.Burst parameter.  It is an implementation decision as to how
+   to distribute HEARTBEATS to the peer's addresses for path
+   verification.
+
+   Whenever a path is confirmed, an indication MAY be given to the upper
+   layer.
+
+   An endpoint MUST NOT send any chunks to an UNCONFIRMED address, with
+   the following exceptions:
+
+   - A HEARTBEAT including a nonce MAY be sent to an UNCONFIRMED
+     address.
+
+   - A HEARTBEAT-ACK MAY be sent to an UNCONFIRMED address.
+
+   - A COOKIE-ACK MAY be sent to an UNCONFIRMED address, but it MUST be
+     bundled with a HEARTBEAT including a nonce.  An implementation that
+     does NOT support bundling MUST NOT send a COOKIE-ACK to an
+     UNCONFIRMED address.
+
+   - A COOKE-ECHO MAY be sent to an UNCONFIRMED address, but it MUST be
+     bundled with a HEARTBEAT including a nonce, and the packet MUST NOT
+     exceed the path MTU.  If the implementation does NOT support
+     bundling or if the bundled COOKIE-ECHO plus HEARTBEAT (including
+     nonce) would exceed the path MTU, then the implementation MUST NOT
+     send a COOKIE-ECHO to an UNCONFIRMED address.
+
+   ---------
+   Old text: (Section 14)
+   ---------
+
+   14.  Suggested SCTP Protocol Parameter Values
+
+   The following protocol parameters are RECOMMENDED:
+
+
+
+
+Stewart, et al.              Informational                     [Page 75]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   RTO.Initial              - 3  seconds
+   RTO.Min                  - 1  second
+   RTO.Max                 -  60 seconds
+   RTO.Alpha                - 1/8
+   RTO.Beta                 - 1/4
+   Valid.Cookie.Life        - 60  seconds
+   Association.Max.Retrans  - 10 attempts
+   Path.Max.Retrans         - 5  attempts (per destination address)
+   Max.Init.Retransmits     - 8  attempts
+   HB.interval              - 30 seconds
+
+   ---------
+   New text: (Section 14)
+   ---------
+
+   14.  Suggested SCTP Protocol Parameter Values
+
+   The following protocol parameters are RECOMMENDED:
+
+   RTO.Initial              - 3 seconds
+   RTO.Min                  - 1 second
+   RTO.Max                  - 60 seconds
+   Max.Burst                - 4
+   RTO.Alpha                - 1/8
+   RTO.Beta                 - 1/4
+   Valid.Cookie.Life        - 60 seconds
+   Association.Max.Retrans  - 10 attempts
+   Path.Max.Retrans         - 5 attempts (per destination address)
+   Max.Init.Retransmits     - 8 attempts
+   HB.Interval              - 30 seconds
+   HB.Max.Burst             - 1
+
+2.36.3.  Solution Description
+
+   By properly setting up initial path state and accelerated probing via
+   HEARTBEAT's, a new association can verify that all addresses
+   presented by a peer belong to that peer.
+
+2.37.  ICMP Handling Procedures
+
+2.37.1.  Description of the Problem
+
+   RFC 2960 does not describe how ICMP messages should be processed by
+   an SCTP endpoint.
+
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 76]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+2.37.2.  Text Changes to the Document
+
+   --------
+   Old text: None
+   --------
+
+   ---------
+   New text
+   ---------
+
+   11.5.  Protection of Non-SCTP Capable Hosts.
+
+   To provide a non-SCTP capable host with the same level of protection
+   against attacks as for SCTP-capable ones, all SCTP stacks MUST
+   implement the ICMP handling described in Appendix C.
+
+   When an SCTP stack receives a packet containing multiple control or
+   DATA chunks and the processing of the packet requires the sending of
+   multiple chunks in response, the sender of the response chunk(s) MUST
+   NOT send more than one packet.  If bundling is supported, multiple
+   response chunks that fit into a single packet MAY be bundled together
+   into one single response packet.  If bundling is not supported, then
+   the sender MUST NOT send more than one response chunk and MUST
+   discard all other responses.  Note that this rule does NOT apply to a
+   SACK chunk, since a SACK chunk is, in itself, a response to DATA and
+   a SACK does not require a response of more DATA.
+
+   An SCTP implementation SHOULD abort the association if it receives a
+   SACK acknowledging a TSN that has not been sent.
+
+   An SCTP implementation that receives an INIT that would require a
+   large packet in response, due to the inclusion of multiple ERROR
+   parameters, MAY (at its discretion) elect to omit some or all of the
+   ERROR parameters to reduce the size of the INIT-ACK.  Due to a
+   combination of the size of the COOKIE parameter and the number of
+   addresses a receiver of an INIT may be indicating to a peer, it is
+   always possible that the INIT-ACK will be larger than the original
+   INIT.  An SCTP implementation SHOULD attempt to make the INIT-ACK as
+   small as possible to reduce the possibility of byte amplification
+   attacks.
+
+   ---------
+   Old text: None
+   ---------
+
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 77]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   ---------
+   New text: (Appendix C)
+   ---------
+
+   Appendix C ICMP Handling
+
+   Whenever an ICMP message is received by an SCTP endpoint the
+   following procedures MUST be followed to ensure proper utilization of
+   the information being provided by layer 3.
+
+   ICMP1) An implementation MAY ignore all ICMPv4 messages where the
+          type field is not set to "Destination Unreachable".
+
+   ICMP2) An implementation MAY ignore all ICMPv6 messages where the
+          type field is not "Destination Unreachable, "Parameter
+          Problem" or "Packet Too Big".
+
+   ICMP3) An implementation MAY ignore any ICMPv4 messages where the
+          code does not indicate "Protocol Unreachable" or
+          "Fragmentation Needed".
+
+   ICMP4) An implementation MAY ignore all ICMPv6 messages of type
+          "Parameter Problem" if the code is not "Unrecognized next
+          header type encountered".
+
+   ICMP5) An implementation MUST use the payload of the ICMP message (V4
+          or V6) to locate the association that sent the message that
+          ICMP is responding to.  If the association cannot be found, an
+          implementation SHOULD ignore the ICMP message.
+
+   ICMP6) An implementation MUST validate that the Verification Tag
+          contained in the ICMP message matches the verification tag of
+          the peer.  If the Verification Tag is not 0 and does NOT
+          match, discard the ICMP message.  If it is 0 and the ICMP
+          message contains enough bytes to verify that the chunk type is
+          an INIT chunk and that the initiate tag matches the tag of the
+          peer, continue with ICMP7.  If the ICMP message is too short
+          or the chunk type or the initiate tag does not match, silently
+          discard the packet.
+
+   ICMP7) If the ICMP message is either a V6 "Packet Too Big" or a V4
+          "Fragmentation Needed", an implementation MAY process this
+          information as defined for PATH MTU discovery.
+
+   ICMP8) If the ICMP code is a "Unrecognized next header type
+          encountered" or a "Protocol Unreachable", an implementation
+          MUST treat this message as an abort with the T bit set if it
+          does not contain an INIT chunk.  If it does contain an INIT
+
+
+
+Stewart, et al.              Informational                     [Page 78]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+          chunk and the association is in COOKIE-WAIT state, handle the
+          ICMP message like an ABORT.
+
+   ICMP9) If the ICMPv6 code is "Destination Unreachable", the
+          implementation MAY mark the destination into the unreachable
+          state or alternatively increment the path error counter.
+
+   Note that these procedures differ from RFC 1122 [1] and from its
+   requirements for processing of port-unreachable messages and the
+   requirements that an implementation MUST abort associations in
+   response to a "protocol unreachable" message.  Port unreachable
+   messages are not processed, since an implementation will send an
+   ABORT, not a port unreachable.  The stricter handling of the
+   "protocol unreachable" message is due to security concerns for hosts
+   that do NOT support SCTP.
+
+2.37.3.  Solution Description
+
+   The new appendix now describes proper handling of ICMP messages in
+   conjunction with SCTP.
+
+2.38.  Checksum
+
+2.38.1.  Description of the problem
+
+   RFC 3309 [6] changes the SCTP checksum due to weaknesses in the
+   original Adler 32 checksum for small messages.  This document, being
+   used as a guide for a cut and paste replacement to update RFC 2960,
+   thus also needs to incorporate the checksum changes.  The idea is
+   that one could apply all changes found in this guide to a copy of RFC
+   2960 and have a "new" document that has ALL changes (including RFC
+   3309).
+
+2.38.2.  Text Changes to the Document
+
+   ---------
+   Old text:
+   ---------
+
+   6.8 Adler-32 Checksum Calculation
+
+      When sending an SCTP packet, the endpoint MUST strengthen the data
+      integrity of the transmission by including the Adler-32 checksum
+      value calculated on the packet, as described below.
+
+      After the packet is constructed (containing the SCTP common header
+      and one or more control or DATA chunks), the transmitter shall:
+
+
+
+
+Stewart, et al.              Informational                     [Page 79]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+      1) Fill in the proper Verification Tag in the SCTP common header
+         and initialize the checksum field to 0's.
+
+      2) Calculate the Adler-32 checksum of the whole packet, including
+         the SCTP common header and all the chunks.  Refer to
+         appendix B for details of the Adler-32 algorithm.  And,
+
+      3) Put the resultant value into the checksum field in the common
+         header, and leave the rest of the bits unchanged.
+
+      When an SCTP packet is received, the receiver MUST first check the
+      Adler-32 checksum:
+
+      1) Store the received Adler-32 checksum value aside,
+
+      2) Replace the 32 bits of the checksum field in the received SCTP
+         packet with all '0's and calculate an Adler-32 checksum value
+         of the whole received packet.  And,
+
+      3) Verify that the calculated Adler-32 checksum is the same as the
+         received Adler-32 checksum.  If not, the receiver MUST treat
+         the packet as an invalid SCTP packet.
+
+      The default procedure for handling invalid SCTP packets is to
+      silently discard them.
+
+   ---------
+   New text:
+   ---------
+
+   6.8 CRC-32c Checksum Calculation
+
+      When sending an SCTP packet, the endpoint MUST strengthen the data
+      integrity of the transmission by including the CRC32c checksum
+      value calculated on the packet, as described below.
+
+      After the packet is constructed (containing the SCTP common header
+      and one or more control or DATA chunks), the transmitter MUST
+
+      1) fill in the proper Verification Tag in the SCTP common header
+         and initialize the checksum field to '0's,
+
+      2) calculate the CRC32c checksum of the whole packet, including
+         the SCTP common header and all the chunks (refer to
+         appendix B for details of the CRC32c algorithm); and
+
+      3) put the resultant value into the checksum field in the common
+         header, and leave the rest of the bits unchanged.
+
+
+
+Stewart, et al.              Informational                     [Page 80]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+      When an SCTP packet is received, the receiver MUST first check the
+      CRC32c checksum as follows:
+
+      1) Store the received CRC32c checksum value aside.
+
+      2) Replace the 32 bits of the checksum field in the received SCTP
+         packet with all '0's and calculate a CRC32c checksum value of
+         the whole received packet.
+
+      3) Verify that the calculated CRC32c checksum is the same as the
+         received CRC32c checksum.  If it is not, the receiver MUST
+         treat the packet as an invalid SCTP packet.
+
+      The default procedure for handling invalid SCTP packets is to
+      silently discard them.
+
+      Any hardware implementation SHOULD be done in a way that is
+      verifiable by the software.
+
+
+   ---------
+   Old text:
+   ---------
+
+   Appendix B Alder 32 bit checksum calculation
+
+      The Adler-32 checksum calculation given in this appendix is
+      copied from [RFC1950].
+
+      Adler-32 is composed of two sums accumulated per byte: s1 is the
+      sum of all bytes, s2 is the sum of all s1 values.  Both sums are
+      done modulo 65521.  s1 is initialized to 1, s2 to zero.  The
+      Adler-32 checksum is stored as s2*65536 + s1 in network byte
+      order.
+
+      The following C code computes the Adler-32 checksum of a data
+      buffer.  It is written for clarity, not for speed.  The sample
+      code is in the ANSI C programming language.  Non C users may
+      find it easier to read with these hints:
+
+      &      Bitwise AND operator.
+      >>     Bitwise right shift operator.  When applied to an
+             unsigned quantity, as here, right shift inserts zero bit(s)
+             at the left.
+      <<     Bitwise left shift operator.  Left shift inserts zero
+             bit(s) at the right.
+      ++     "n++" increments the variable n.
+      %      modulo operator: a % b is the remainder of a divided by b.
+
+
+
+Stewart, et al.              Informational                     [Page 81]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+       #define BASE 65521 /* largest prime smaller than 65536 */
+       /*
+         Update a running Adler-32 checksum with the bytes buf[0..len-1]
+         and return the updated checksum.  The Adler-32 checksum should
+         be initialized to 1.
+
+          Usage example:
+
+            unsigned long adler = 1L;
+
+            while (read_buffer(buffer, length) != EOF) {
+              adler = update_adler32(adler, buffer, length);
+             }
+            if (adler != original_adler) error();
+         */
+         unsigned long update_adler32(unsigned long adler,
+            unsigned char *buf, int len)
+         {
+           unsigned long s1 = adler & 0xffff;
+           unsigned long s2 = (adler >> 16) & 0xffff;
+           int n;
+
+           for (n = 0; n < len; n++) {
+             s1 = (s1 + buf[n]) % BASE;
+             s2 = (s2 + s1)     % BASE;
+           }
+           return (s2 << 16) + s1;
+         }
+
+         /* Return the adler32 of the bytes buf[0..len-1] */
+         unsigned long adler32(unsigned char *buf, int len)
+         {
+           return update_adler32(1L, buf, len);
+         }
+
+   ---------
+   New text:
+   ---------
+
+   Appendix B CRC32c Checksum Calculation
+
+      We define a 'reflected value' as one that is the opposite of the
+      normal bit order of the machine.  The 32-bit CRC is calculated as
+      described for CRC-32c and uses the polynomial code 0x11EDC6F41
+      (Castagnoli93) or x^32+x^28+x^27+x^26+x^25
+      +x^23+x^22+x^20+x^19+x^18+x^14+x^13+x^11+x^10+x^9+x^8+x^6+x^0.
+      The CRC is computed using a procedure similar to ETHERNET CRC
+      [ITU32], modified to reflect transport level usage.
+
+
+
+Stewart, et al.              Informational                     [Page 82]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+      CRC computation uses polynomial division.  A message
+      bit-string M is transformed to a polynomial, M(X), and the CRC
+      is calculated from M(X) using polynomial arithmetic [PETERSON 72].
+
+      When CRCs are used at the link layer, the polynomial is derived
+      from on-the-wire bit ordering: the first bit 'on the wire' is the
+      high-order coefficient.  Since SCTP is a transport-level protocol,
+      it cannot know the actual serial-media bit ordering.  Moreover,
+      different links in the path between SCTP endpoints may use
+      different link-level bit orders.
+
+      A convention must therefore be established for mapping SCTP
+      transport messages to polynomials for purposes of CRC computation.
+      The bit-ordering for mapping SCTP messages to polynomials is that
+      bytes are taken most-significant first; but within each byte, bits
+      are taken least-significant first.  The first byte of the message
+      provides the eight highest coefficients.  Within each byte,
+      the least-significant SCTP bit gives the most significant
+      polynomial coefficient within that byte, and the most-significant
+      SCTP bit is the least significant polynomial coefficient in that
+      byte.  (This bit ordering is sometimes called 'mirrored' or
+      'reflected' [WILLIAMS93].)  CRC polynomials are to be transformed
+      back into SCTP transport-level byte values, using a consistent
+      mapping.
+
+      The SCTP transport-level CRC value should be calculated as
+      follows:
+
+         -  CRC input data are assigned to a byte stream, numbered from
+            0 to N-1.
+
+         -  The transport-level byte-stream is mapped to a polynomial
+            value.  An N-byte PDU with j bytes numbered 0 to N-1 is
+            considered as coefficients of a polynomial M(x) of order
+            8N-1, with bit 0 of byte j being coefficient x^(8(N-j)-8),
+            and bit 7 of byte j being coefficient x^(8(N-j)-1).
+
+         -  The CRC remainder register is initialized with all 1s and
+            the CRC is computed with an algorithm that simultaneously
+            multiplies by x^32 and divides by the CRC polynomial.
+
+         -  The polynomial is multiplied by x^32 and divided by G(x),
+            the generator polynomial, producing a remainder R(x) of
+            degree less than or equal to 31.
+
+         -  The coefficients of R(x) are considered a 32-bit sequence.
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 83]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+         -  The bit sequence is complemented.  The result is the CRC
+            polynomial.
+
+         -  The CRC polynomial is mapped back into SCTP transport-level
+            bytes.  The coefficient of x^31 gives the value of bit 7 of
+            SCTP byte 0, and the coefficient of x^24 gives the value of
+            bit 0 of byte 0.  The coefficient of x^7 gives bit 7 of
+            byte 3, and the coefficient of x^0 gives bit 0 of byte 3.
+            The resulting four-byte transport-level sequence is the
+            32-bit SCTP checksum value.
+
+      IMPLEMENTATION NOTE: Standards documents, textbooks, and vendor
+      literature on CRCs often follow an alternative formulation, in
+      which the register used to hold the remainder of the
+      long-division algorithm is initialized to zero rather than
+      all-1s, and instead the first 32 bits of the message are
+      complemented.  The long-division algorithm used in our
+      formulation is specified such that the initial
+      multiplication by 2^32 and the long-division are combined into
+      one simultaneous operation.  For such algorithms, and for
+      messages longer than 64 bits, the two specifications are
+      precisely equivalent.  That equivalence is the intent of
+      this document.
+
+      Implementors of SCTP are warned that both specifications are to be
+      found in the literature, sometimes with no restriction on the
+      long-division algorithm.  The choice of formulation in this
+      document is to permit non-SCTP usage, where the same CRC
+      algorithm may be used to protect messages shorter than 64 bits.
+
+      There may be a computational advantage in validating the
+      Association against the Verification Tag, prior to performing a
+      checksum, as invalid tags will result in the same action as a bad
+      checksum in most cases.  The exceptions for this technique would
+      be INIT and some SHUTDOWN-COMPLETE exchanges, as well as a stale
+      COOKIE-ECHO.  These special case exchanges must represent small
+      packets and will minimize the effect of the checksum calculation.
+
+
+   ---------
+   Old text: (Section 18)
+   ---------
+
+   18.  Bibliography
+
+   [ALLMAN99] Allman, M. and Paxson, V., "On Estimating End-to-End
+              Network Path Properties", Proc. SIGCOMM'99, 1999.
+
+
+
+
+Stewart, et al.              Informational                     [Page 84]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   [FALL96]   Fall, K. and Floyd, S., Simulation-based Comparisons of
+              Tahoe, Reno, and SACK TCP, Computer Communications Review,
+              V. 26 N. 3, July 1996, pp.  5-21.
+
+   [RFC1750]  Eastlake, D. (ed.), "Randomness Recommendations for
+              Security", RFC 1750, December 1994.
+
+   [RFC1950]  Deutsch P. and J. Gailly, "ZLIB Compressed Data Format
+              Specification version 3.3", RFC 1950, May 1996.
+
+   [RFC2104]  Krawczyk, H., Bellare, M. and R. Canetti, "HMAC:  Keyed-
+              Hashing for Message Authentication", RFC 2104, March 1997.
+
+   [RFC2196]  Fraser, B., "Site Security Handbook", FYI 8, RFC 2196,
+              September 1997.
+
+   [RFC2522]  Karn, P. and W. Simpson, "Photuris: Session-Key Management
+              Protocol", RFC 2522, March 1999.
+
+   [SAVAGE99] Savage, S., Cardwell, N., Wetherall, D., and Anderson, T.,
+              "TCP Congestion Control with a Misbehaving Receiver",  ACM
+              Computer Communication Review, 29(5), October 1999.
+
+   ---------
+   New text: (Section 18, including changes from 2.11)
+   ---------
+
+   18.  Bibliography
+
+   [ALLMAN99] Allman, M. and Paxson, V., "On Estimating End-to-End
+              Network Path Properties", Proc. SIGCOMM'99, 1999.
+
+   [FALL96]   Fall, K. and Floyd, S., Simulation-based Comparisons of
+              Tahoe, Reno, and SACK TCP, Computer Communications Review,
+              V. 26 N. 3, July 1996, pp.  5-21.
+
+   [ITU32]         ITU-T Recommendation V.42, "Error-correcting
+                   procedures for DCEs using asynchronous-to-synchronous
+                   conversion", Section 8.1.1.6.2, October 1996.
+
+   [PETERSON 1972] W. W. Peterson and E.J Weldon, Error Correcting
+                   Codes, 2nd Edition, MIT Press, Cambridge,
+                   Massachusetts.
+
+   [RFC1750]  Eastlake, D., Ed., "Randomness Recommendations for
+              Security", RFC 1750, December 1994.
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 85]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   [RFC1858]  Ziemba, G., Reed, D. and Traina P., "Security
+              Considerations for IP Fragment Filtering", RFC 1858,
+              October 1995.
+
+   [RFC1950]  Deutsch P. and J. Gailly, "ZLIB Compressed Data Format
+              Specification version 3.3", RFC 1950, May 1996.
+
+   [RFC2104]  Krawczyk, H., Bellare, M. and R. Canetti, "HMAC:  Keyed-
+              Hashing for Message Authentication", RFC 2104, March 1997.
+
+   [RFC2196]  Fraser, B., "Site Security Handbook", FYI 8, RFC 2196,
+              September 1997.
+
+   [RFC2522]  Karn, P. and W. Simpson, "Photuris: Session-Key Management
+              Protocol", RFC 2522, March 1999.
+
+   [SAVAGE99] Savage, S., Cardwell, N., Wetherall, D., and Anderson, T.,
+              "TCP Congestion Control with a Misbehaving Receiver", ACM
+              Computer Communication Review, 29(5), October 1999.
+
+   [WILLIAMS93]    Williams, R., "A PAINLESS GUIDE TO CRC ERROR
+                   DETECTION ALGORITHMS" - Internet publication, August
+                   1993,
+                   http://www.geocities.com/SiliconValley/Pines/
+                   8659/crc.htm.
+
+2.38.3.  Solution Description
+
+   This change adds to the implementor's guide the complete set of
+   changes that, when combined with RFC 2960 [5], encompasses the
+   changes from RFC 3309 [6].
+
+2.39.  Retransmission Policy
+
+2.39.1.  Description of the Problem
+
+   The current retransmission policy (send all retransmissions an
+   alternate destination) in the specification has performance issues
+   under certain loss conditions with multihomed endpoints.  Instead,
+   fast retransmissions should be sent to the same destination, and only
+   timeout retransmissions should be sent to an alternate destination
+   [4].
+
+
+
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 86]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+2.39.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 6.4)
+   ---------
+
+   Furthermore, when its peer is multi-homed, an endpoint SHOULD try to
+   retransmit a chunk to an active destination transport address that is
+   different from the last destination address to which the DATA chunk
+   was sent.
+
+   ---------
+   New text: (Section 6.4)
+   ---------
+
+   Furthermore, when its peer is multi-homed, an endpoint SHOULD try to
+   retransmit a chunk that timed out to an active destination transport
+   address that is different from the last destination address to which
+   the DATA chunk was sent.
+
+   ---------
+   Old text: (Section 6.4.1)
+   ---------
+
+   When retransmitting data, if the endpoint is multi-homed, it should
+   consider each source-destination address pair in its retransmission
+   selection policy.  When retransmitting the endpoint should attempt to
+   pick the most divergent source-destination pair from the original
+   source-destination pair to which the packet was transmitted.
+
+   ---------
+   New text: (Section 6.4.1)
+   ---------
+
+   When retransmitting data that timed out, if the endpoint is
+   multi-homed, it should consider each source-destination address
+   pair in its retransmission selection policy.  When retransmitting
+   timed out data, the endpoint should attempt to pick the most
+   divergent source-destination pair from the original
+   source-destination pair to which the packet was transmitted.
+
+2.39.3.  Solution Description
+
+   The above wording changes clarify that only timeout retransmissions
+   should be sent to an alternate active destination.
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 87]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+2.40.  Port Number 0
+
+2.40.1.  Description of the Problem
+
+   The port number 0 has a special semantic in various APIs.  For
+   example, in the socket API, if the user specifies 0, the SCTP
+   implementation chooses an appropriate port number for the user.
+   Therefore, the port number 0 should not be used on the wire.
+
+2.40.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 3.1)
+   ---------
+
+      Source Port Number: 16 bits (unsigned integer)
+
+         This is the SCTP sender's port number.  It can be used by the
+         receiver in combination with the source IP address, the SCTP
+         destination port, and possibly the destination IP address to
+         identify the association to which this packet belongs.
+
+      Destination Port Number: 16 bits (unsigned integer)
+
+         This is the SCTP port number to which this packet is destined.
+         The receiving host will use this port number to de-multiplex
+         the SCTP packet to the correct receiving endpoint/application.
+
+   ---------
+   New text: (Section 3.1)
+   ---------
+
+      Source Port Number: 16 bits (unsigned integer)
+
+         This is the SCTP sender's port number.  It can be used by the
+         receiver in combination with the source IP address, the SCTP
+         destination port and possibly the destination IP address to
+         identify the association to which this packet belongs.
+         The port number 0 MUST NOT be used.
+
+      Destination Port Number: 16 bits (unsigned integer)
+
+         This is the SCTP port number to which this packet is destined.
+         The receiving host will use this port number to de-multiplex
+         the SCTP packet to the correct receiving endpoint/application.
+         The port number 0 MUST NOT be used.
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 88]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+2.40.3.  Solution Description
+
+   It is clearly stated that the port number 0 is an invalid value on
+   the wire.
+
+2.41.  T Bit
+
+2.41.1.  Description of the Problem
+
+   The description of the T bit as the bit describing whether a TCB has
+   been destroyed is misleading.  In addition, the procedure described
+   in Section 2.13 is not as precise as needed.
+
+2.41.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 3.3.7)
+   ---------
+
+      T bit:  1 bit
+         The T bit is set to 0 if the sender had a TCB that it
+         destroyed.  If the sender did not have a TCB it should set
+         this bit to 1.
+
+   ---------
+   New text: (Section 3.3.7)
+   ---------
+
+      T bit:  1 bit
+         The T bit is set to 0 if the sender filled in the
+         Verification Tag expected by the peer.  If the Verification
+         Tag is reflected, the T bit MUST be set to 1.  Reflecting means
+         that the sent Verification Tag is the same as the received
+         one.
+
+
+   ---------
+   Old text: (Section 3.3.13)
+   ---------
+
+      T bit:  1 bit
+         The T bit is set to 0 if the sender had a TCB that it
+         destroyed.  If the sender did not have a TCB it should set
+         this bit to 1.
+
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 89]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   ---------
+   New text: (Section 3.3.13)
+   ---------
+
+      T bit:  1 bit
+         The T bit is set to 0 if the sender filled in the
+         Verification Tag expected by the peer.  If the Verification
+         Tag is reflected, the T bit MUST be set to 1.  Reflecting means
+         that the sent Verification Tag is the same as the received
+         one.
+
+
+   ---------
+   Old text: (Section 8.4)
+   ---------
+
+       3) If the packet contains an INIT chunk with a Verification Tag
+          set to '0', process it as described in Section 5.1.
+          Otherwise,
+
+   ---------
+   New text: (Section 8.4)
+   ---------
+       3) If the packet contains an INIT chunk with a Verification Tag
+         set to '0', process it as described in Section 5.1.  If, for
+         whatever reason, the INIT cannot be processed normally and
+         an ABORT has to be sent in response, the Verification Tag of
+         the packet containing the ABORT chunk MUST be the Initiate
+         tag of the received INIT chunk, and the T-Bit of the ABORT
+         chunk has to be set to 0, indicating that the Verification
+         Tag is NOT reflected.
+
+
+   ---------
+   Old text: (Section 8.4)
+   ---------
+      5) If the packet contains a SHUTDOWN ACK chunk, the receiver
+         should respond to the sender of the OOTB packet with a
+         SHUTDOWN COMPLETE.  When sending the SHUTDOWN COMPLETE, the
+         receiver of the OOTB packet must fill in the Verification
+         Tag field of the outbound packet with the Verification Tag
+         received in the SHUTDOWN ACK and set the T-bit in the Chunk
+         Flags to indicate that no TCB was found.  Otherwise,
+
+
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 90]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   ---------
+   New text: (Section 8.4)
+   ---------
+
+      5) If the packet contains a SHUTDOWN ACK chunk, the receiver
+         should respond to the sender of the OOTB packet with a
+         SHUTDOWN COMPLETE.  When sending the SHUTDOWN COMPLETE, the
+         receiver of the OOTB packet must fill in the Verification
+         Tag field of the outbound packet with the Verification Tag
+         received in the SHUTDOWN ACK and set the T-bit in the
+         Chunk Flags to indicate that the Verification Tag is
+         reflected.  Otherwise,
+
+
+   ---------
+   Old text: (Section 8.4)
+   ---------
+
+      8) The receiver should respond to the sender of the OOTB packet
+         with an ABORT.  When sending the ABORT, the receiver of the
+         OOTB packet MUST fill in the Verification Tag field of the
+         outbound packet with the value found in the Verification
+         Tag field of the OOTB packet and set the T-bit in the Chunk
+         Flags to indicate that no TCB was found.  After sending this
+         ABORT, the receiver of the OOTB packet shall discard the
+         OOTB packet and take no further action.
+
+   ---------
+   New text: (Section 8.4)
+   ---------
+
+      8) The receiver should respond to the sender of the OOTB packet
+         with an ABORT.  When sending the ABORT, the receiver of the
+         OOTB packet MUST fill in the Verification Tag field of the
+         outbound packet with the value found in the Verification Tag
+         field of the OOTB packet and set the T-bit in the Chunk Flags
+         to indicate that the Verification Tag is reflected.  After
+         sending this ABORT, the receiver of the OOTB packet shall
+         discard the OOTB packet and take no further action.
+
+
+   ---------
+   Old text: (Section 8.5.1)
+   ---------
+
+      B) Rules for packet carrying ABORT:
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 91]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+         -  The endpoint shall always fill in the Verification Tag
+            field of the outbound packet with the destination
+            endpoint's tag value if it is known.
+
+         -  If the ABORT is sent in response to an OOTB packet, the
+            endpoint MUST follow the procedure described in
+            Section 8.4.
+
+         -  The receiver MUST accept the packet if the Verification
+            Tag matches either its own tag, OR the tag of its peer.
+            Otherwise, the receiver MUST silently discard the packet
+            and take no further action.
+
+   ---------
+   New text: (Section 8.5.1)
+   ---------
+
+     B) Rules for packet carrying ABORT:
+
+         -  The endpoint MUST always fill in the Verification Tag
+            field of the outbound packet with the destination
+            endpoint's tag value, if it is known.
+
+         -  If the ABORT is sent in response to an OOTB packet, the
+            endpoint MUST follow the procedure described in
+            Section 8.4.
+
+         -  The receiver of an ABORT MUST accept the packet
+            if the Verification Tag field of the packet matches its
+            own tag and the T bit is not set
+            OR
+            if it is set to its peer's tag and the T bit is set in
+            the Chunk Flags.
+            Otherwise, the receiver MUST silently discard the packet
+            and take no further action.
+
+
+   ---------
+   Old text: (Section 8.5.1)
+   ---------
+
+      C) Rules for packet carrying SHUTDOWN COMPLETE:
+
+         -  When sending a SHUTDOWN COMPLETE, if the receiver of the
+            SHUTDOWN ACK has a TCB then the destination endpoint's
+            tag MUST be used.  Only where no TCB exists should the
+            sender use the Verification Tag from the SHUTDOWN ACK.
+
+
+
+
+Stewart, et al.              Informational                     [Page 92]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+         -  The receiver of a SHUTDOWN COMPLETE shall accept the
+            packet if the Verification Tag field of the packet matches
+            its own tag OR it is set to its peer's tag and the T bit
+            is set in the Chunk Flags.  Otherwise, the receiver MUST
+            silently discard the packet and take no further action.
+            An endpoint MUST ignore the SHUTDOWN COMPLETE if it is
+            not in the SHUTDOWN-ACK-SENT state.
+
+   ---------
+   New text: (Section 8.5.1)
+   ---------
+
+      C) Rules for packet carrying SHUTDOWN COMPLETE:
+
+         -  When sending a SHUTDOWN COMPLETE, if the receiver of the
+            SHUTDOWN ACK has a TCB, then the destination endpoint's tag
+            MUST be used, and the T-bit MUST NOT be set.  Only where no
+            TCB exists should the sender use the Verification Tag from
+            the SHUTDOWN ACK, and MUST set the T-bit.
+
+         -  The receiver of a SHUTDOWN COMPLETE shall accept the packet
+            if the Verification Tag field of the packet matches its own
+            tag and the T bit is not set
+            OR
+            if it is set to its peer's tag and the T bit is set in the
+            Chunk Flags.
+            Otherwise, the receiver MUST silently discard the packet
+            and take no further action.  An endpoint MUST ignore the
+            SHUTDOWN COMPLETE if it is not in the SHUTDOWN-ACK-SENT
+            state.
+
+2.41.3.  Solution Description
+
+   The description of the T bit now clearly describes the semantic of
+   the bit.  The procedures for receiving the T bit have been clarified.
+
+2.42.  Unknown Parameter Handling
+
+2.42.1.  Description of the Problem
+
+   The description given in Section 2.33 does not state clearly whether
+   an INIT-ACK or COOKIE-ECHO is sent.
+
+2.42.2.  Text Changes to the Document
+
+   The changes given here already include changes suggested in Section
+   2.2, 2.27, and 2.33 of this document.
+
+
+
+
+Stewart, et al.              Informational                     [Page 93]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   ---------
+   Old text: (Section 3.2.1)
+   ---------
+
+   00 - Stop processing this SCTP packet and discard it do not process
+        any further chunks within it.
+
+   01 - Stop processing this SCTP packet and discard it, do not process
+        any further chunks within it, and report the unrecognized
+        parameter in an 'Unrecognized Parameter Type' (in either an
+        ERROR or in the INIT ACK).
+
+   10 - Skip this parameter and continue processing.
+
+   11 - Skip this parameter and continue processing but report the
+        unrecognized parameter in an 'Unrecognized Parameter Type' (in
+        either an ERROR or in the INIT ACK).
+
+   ---------
+   New text: (Section 3.2.1)
+   ---------
+
+   00 - Stop processing this parameter; do not process
+        any further parameters within this chunk.
+
+   01 - Stop processing this parameter, do not process
+        any further parameters within this chunk, and report the
+        unrecognized parameter in an 'Unrecognized Parameter', as
+        described in 3.2.2.
+
+   10 - Skip this parameter and continue processing.
+
+   11 - Skip this parameter and continue processing but report the
+        unrecognized parameter in an 'Unrecognized Parameter', as
+        described in 3.2.2.
+
+   Please note that in all four cases an INIT-ACK or COOKIE-ECHO
+   chunk is sent.  In the 00 or 01 case the processing of the
+   parameters after the unknown parameter is canceled, but no
+   processing already done is rolled back.
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 94]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   ---------
+   New text: (Note: no old text; clarification added in Section 3.2)
+   ---------
+
+   3.2.2.  Reporting of Unrecognized Parameters
+
+      If the receiver of an INIT chunk detects unrecognized parameters
+      and has to report them according to Section 3.2.1, it MUST put
+      the 'Unrecognized Parameter' parameter(s) in the INIT-ACK chunk
+      sent in response to the INIT-chunk.  Note that if the receiver
+      of the INIT chunk is NOT going to establish an association (e.g.,
+      due to lack of resources), an 'Unrecognized Parameter' would NOT
+      be included with any ABORT being sent to the sender of the INIT.
+
+      If the receiver of an INIT-ACK chunk detects unrecognized
+      parameters and has to report them according to Section 3.2.1, it
+      SHOULD bundle the ERROR chunk containing the 'Unrecognized
+      Parameters' error cause with the COOKIE-ECHO chunk sent in
+      response to the INIT-ACK chunk.  If the receiver of the INIT-ACK
+      cannot bundle the COOKIE-ECHO chunk with the ERROR chunk, the
+      ERROR chunk MAY be sent separately but not before the COOKIE-ACK
+      has been received.
+
+      Note: Any time a COOKIE-ECHO is sent in a packet, it MUST be the
+      first chunk.
+
+2.42.3.  Solution Description
+
+   The new text clearly states that an INIT-ACK or COOKIE-ECHO has to be
+   sent.
+
+2.43.  Cookie Echo Chunk
+
+2.43.1.  Description of the Problem
+
+   The description given in Section 3.3.11 of RFC 2960 [5] is unclear as
+   to how the COOKIE-ECHO is composed.
+
+2.43.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 3.3.11)
+   ---------
+      Cookie: variable size
+
+         This field must contain the exact cookie received in the State
+         Cookie parameter from the previous INIT ACK.
+
+
+
+
+Stewart, et al.              Informational                     [Page 95]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+         An implementation SHOULD make the cookie as small as possible
+         to insure interoperability.
+
+   ---------
+   New text: (Section 3.3.11)
+   ---------
+      Cookie: variable size
+
+         This field must contain the exact cookie received in the State
+         Cookie parameter from the previous INIT ACK.
+
+         An implementation SHOULD make the cookie as small as possible
+         to ensure interoperability.
+
+         Note: A Cookie Echo does NOT contain a State Cookie
+         Parameter; instead, the data within the State Cookie's
+         Parameter Value becomes the data within the Cookie Echo's
+         Chunk Value.  This allows an implementation to change only
+         the first two bytes of the State Cookie parameter to become
+         a Cookie Echo Chunk.
+
+2.43.3.  Solution Description
+
+   The new text adds a note that helps clarify that a Cookie Echo chunk
+   is nothing more than the State Cookie parameter with only two bytes
+   modified.
+
+2.44.  Partial Chunks
+
+2.44.1.  Description of the Problem
+
+   Section 6.10 of RFC 2960 [5] uses the notion of 'partial chunks'
+   without defining it.
+
+2.44.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 6.10)
+   ---------
+   Partial chunks MUST NOT be placed in an SCTP packet.
+
+   ---------
+   New text: (Section 6.10)
+   ---------
+   Partial chunks MUST NOT be placed in an SCTP packet.  A partial
+   chunk is a chunk that is not completely contained in the SCTP
+   packet; i.e., the SCTP packet is too short to contain all the bytes
+   of the chunk as indicated by the chunk length.
+
+
+
+Stewart, et al.              Informational                     [Page 96]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+2.44.3.  Solution Description
+
+   The new text adds a definition of 'partial chunks'.
+
+2.45.  Non-unicast Addresses
+
+2.45.1.  Description of the Problem
+
+   Section 8.4 of RFC 2960 [5] forces the OOTB handling to discard all
+   non-unicast addresses.  This leaves future use of anycast addresses
+   in question.  With the addition of the add-ip feature, SCTP should be
+   able to easily handle anycast INIT s that can be followed, after
+   association setup, with a delete of the anycast address from the
+   association.
+
+2.45.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 8.4)
+   ---------
+   8.4 Handle "Out of the blue" Packets
+
+      An SCTP packet is called an "out of the blue" (OOTB) packet if
+      it is correctly formed, i.e., passed the receiver's Adler-32
+      check (see Section 6.8), but the receiver is not able to
+      identify the association to which this packet belongs.
+
+      The receiver of an OOTB packet MUST do the following:
+
+      1) If the OOTB packet is to or from a non-unicast address,
+         silently discard the packet.  Otherwise,
+
+
+   ---------
+   New text: (Section 8.4)
+   ---------
+
+   8.4.  Handle "Out of the Blue" Packets
+
+      An SCTP packet is called an "out of the blue" (OOTB) packet if
+      it is correctly formed (i.e., passed the receiver's CRC32c
+      check; see Section 6.8), but the receiver is not able to identify
+      the association to which this packet belongs.
+
+      The receiver of an OOTB packet MUST do the following:
+
+      1) If the OOTB packet is to or from a non-unicast address, a
+         receiver SHOULD silently discard the packet.  Otherwise,
+
+
+
+Stewart, et al.              Informational                     [Page 97]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+2.45.3.  Solution Description
+
+   The loosening of the wording to a SHOULD will now allow future use of
+   anycast addresses.  Note that no changes are made to Section
+   11.2.4.1, since responding to broadcast addresses could lead to
+   flooding attacks and implementors should pay careful attention to
+   these words.
+
+2.46.  Processing of ABORT Chunks
+
+2.46.1.  Description of the Problem
+
+   Section 3.3.7 of RFC 2960 [5] requires an SCTP endpoint to silently
+   discard ABORT chunks received for associations that do not exist.  It
+   is not clear what this means in the COOKIE-WAIT state, for example.
+   Therefore, it was not clear whether an ABORT sent in response to an
+   INIT should be processed or silently discarded.
+
+2.46.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 3.3.7)
+   ---------
+
+      If an endpoint receives an ABORT with a format error or for an
+      association that doesn't exist, it MUST silently discard it.
+
+   ---------
+   New text: (Section 3.3.7)
+   ---------
+
+      If an endpoint receives an ABORT with a format error or no
+      TCB is found, it MUST silently discard it.
+
+2.46.3.  Solution Description
+
+   It is now clearly stated that an ABORT chunk should be processed
+   whenever a TCB is found.
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 98]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+2.47.  Sending of ABORT Chunks
+
+2.47.1.  Description of the Problem
+
+   Section 5.1 of RFC 2960 [5] requires that an ABORT chunk be sent in
+   response to an INIT chunk when there is no listening end point.  To
+   make port scanning harder, someone might not want these ABORTs to be
+   received by the sender of the INIT chunks.  Currently, the only way
+   to enforce this is by using a firewall that discards the packets
+   containing the INIT chunks or the packets containing the ABORT
+   chunks.  It is desirable that the same can be done without a middle
+   box.
+
+2.47.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 5.1)
+   ---------
+
+      If an endpoint receives an INIT, INIT ACK, or COOKIE ECHO chunk
+      but decides not to establish the new association due to missing
+      mandatory parameters in the received INIT or INIT ACK, invalid
+      parameter values, or lack of local resources, it MUST respond with
+      an ABORT chunk.
+
+   ---------
+   New text: (Section 5.1)
+   ---------
+
+      If an endpoint receives an INIT, INIT ACK, or COOKIE ECHO chunk
+      but decides not to establish the new association due to missing
+      mandatory parameters in the received INIT or INIT ACK, invalid
+      parameter values, or lack of local resources, it SHOULD respond
+      with an ABORT chunk.
+
+2.47.3.  Solution Description
+
+   The requirement of sending ABORT chunks is relaxed such that an
+   implementation can decide not to send ABORT chunks.
+
+2.48.  Handling of Supported Address Types Parameter
+
+2.48.1.  Description of the Problem
+
+   The sender of the INIT chunk can include a 'Supported Address Types'
+   parameter to indicate which address families are supported.  It is
+   unclear how an INIT chunk should be processed where the source
+   address of the packet containing the INIT chunk or listed addresses
+
+
+
+Stewart, et al.              Informational                     [Page 99]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   within the INIT chunk indicate that more address types are supported
+   than those listed in the 'Supported Address Types' parameter.
+
+2.48.2.  Text Changes to the Document
+
+   The changes given here already include changes suggested in Section
+   2.28 of this document.
+
+   ---------
+   Old text: (Section 5.1.2)
+   ---------
+
+      IMPLEMENTATION NOTE: In the case that the receiver of an INIT ACK
+      fails to resolve the address parameter due to an unsupported type,
+      it can abort the initiation process and then attempt a
+      re-initiation by using a 'Supported Address Types' parameter in
+      the new INIT to indicate what types of address it prefers.
+
+   ---------
+   New text: (Section 5.1.2)
+   ---------
+
+      IMPLEMENTATION NOTE: In the case that the receiver of an INIT ACK
+      fails to resolve the address parameter due to an unsupported type,
+      it can abort the initiation process and then attempt a re-
+      initiation by using a 'Supported Address Types' parameter in the
+      new INIT to indicate what types of address it prefers.
+
+      IMPLEMENTATION NOTE: If an SCTP endpoint that only supports either
+      IPv4 or IPv6 receives IPv4 and IPv6 addresses in an INIT or INIT-
+      ACK chunk from its peer, it MUST use all the addresses belonging
+      to the supported address family.  The other addresses MAY be
+      ignored.  The endpoint SHOULD NOT respond with any kind of error
+      indication.
+
+      IMPLEMENTATION NOTE: If an SCTP endpoint lists in the 'Supported
+      Address Types' parameter either IPv4 or IPv6, but uses the other
+      family for sending the packet containing the INIT chunk, or if it
+      also lists addresses of the other family in the INIT chunk, then
+      the address family that is not listed in the 'Supported Address
+      Types' parameter SHOULD also be considered as supported by the
+      receiver of the INIT chunk.  The receiver of the INIT chunk SHOULD
+      NOT respond with any kind of error indication.
+
+2.48.3.  Solution Description
+
+   It is now clearly described how these Supported Address Types
+   parameters with incorrect data should be handled.
+
+
+
+Stewart, et al.              Informational                    [Page 100]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+2.49.  Handling of Unexpected Parameters
+
+2.49.1.  Description of the Problem
+
+   RFC 2960 [5] clearly describes how unknown parameters in the INIT and
+   INIT-ACK chunk should be processed.  But it is not described how
+   unexpected parameters should be processed.  A parameter is unexpected
+   if it is known and is an optional parameter in either the INIT or
+   INIT-ACK chunk but is received in the chunk for which it is not an
+   optional parameter.  For example, the 'Supported Address Types'
+   parameter would be an unexpected parameter if contained in an INIT-
+   ACK chunk.
+
+2.49.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 3.3.2)
+   ---------
+
+      Note 4: This parameter, when present, specifies all the address
+      types the sending endpoint can support.  The absence of this
+      parameter indicates that the sending endpoint can support any
+      address type.
+
+   ---------
+   New text: (Section 3.3.2)
+   ---------
+
+      Note 4: This parameter, when present, specifies all the address
+      types the sending endpoint can support.  The absence of this
+      parameter indicates that the sending endpoint can support any
+      address type.
+
+      IMPLEMENTATION NOTE: If an INIT chunk is received with known
+      parameters that are not optional parameters of the INIT chunk
+      then the receiver SHOULD process the INIT chunk and send back
+      an INIT-ACK.  The receiver of the INIT chunk MAY bundle an ERROR
+      chunk with the COOKIE-ACK chunk later.  However, restrictive
+      implementations MAY send back an ABORT chunk in response to
+      the INIT chunk.
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.              Informational                    [Page 101]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   ---------
+   Old text: (Section 3.3.3)
+   ---------
+
+      IMPLEMENTATION NOTE: An implementation MUST be prepared to receive
+      a INIT ACK that is quite large (more than 1500 bytes) due to the
+      variable size of the state cookie AND the variable address list.
+      For example if a responder to the INIT has 1000 IPv4 addresses
+      it wishes to send, it would need at least 8,000 bytes to encode
+      this in the INIT ACK.
+
+   ---------
+   New text: (Section 3.3.3)
+   ---------
+
+      IMPLEMENTATION NOTE: An implementation MUST be prepared to receive
+      a INIT ACK that is quite large (more than 1500 bytes) due to the
+      variable size of the state cookie AND the variable address list.
+      For example, if a responder to the INIT has 1000 IPv4 addresses
+      it wishes to send, it would need at least 8,000 bytes to encode
+      this in the INIT ACK.
+
+      IMPLEMENTATION NOTE: If an INIT-ACK chunk is received with known
+      parameters that are not optional parameters of the INIT-ACK
+      chunk, then the receiver SHOULD process the INIT-ACK chunk and
+      send back a COOKIE-ECHO.  The receiver of the INIT-ACK chunk
+      MAY bundle an ERROR chunk with the COOKIE-ECHO chunk.  However,
+      restrictive implementations MAY send back an ABORT chunk in
+      response to the INIT-ACK chunk.
+
+2.49.3.  Solution Description
+
+   It is now stated how unexpected parameters should be processed.
+
+2.50.  Payload Protocol Identifier
+
+2.50.1.  Description of the Problem
+
+   The current description of the payload protocol identifier does NOT
+   highlight the fact that the field is NOT necessarily in network byte
+   order.
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.              Informational                    [Page 102]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+2.50.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 3.3.1)
+   ---------
+      Payload Protocol Identifier: 32 bits (unsigned integer)
+
+         This value represents an application (or upper layer) specified
+         protocol identifier.  This value is passed to SCTP by its upper
+         layer and sent to its peer.  This identifier is not used by
+         SCTP but can be used by certain network entities as well as
+         the peer application to identify the type of information being
+         carried in this DATA chunk.  This field must be sent even in
+         fragmented DATA chunks (to make sure it is available for agents
+         in the middle of the network).
+
+         The value 0 indicates no application identifier is specified by
+         the upper layer for this payload data.
+
+   ---------
+   New text: (Section 3.3.1)
+   ---------
+      Payload Protocol Identifier: 32 bits (unsigned integer)
+
+         This value represents an application (or upper layer) specified
+         protocol identifier.  This value is passed to SCTP by its upper
+         layer and sent to its peer.  This identifier is not used by
+         SCTP but can be used by certain network entities, as well as by
+         the peer application, to identify the type of information being
+         carried in this DATA chunk.  This field must be sent even in
+         fragmented DATA chunks (to make sure it is available for agents
+         in the middle of the network).  Note that this field is NOT
+         touched by an SCTP implementation, therefore its byte order is
+         NOT necessarily Big Endian.  The upper layer is responsible
+         for any byte order conversions to this field.
+
+         The value 0 indicates that no application identifier is
+         specified by the upper layer for this payload data.
+
+2.50.3.  Solution Description
+
+   It is now explicitly stated that the upper layer is responsible for
+   the byte order of this field.
+
+
+
+
+
+
+
+
+Stewart, et al.              Informational                    [Page 103]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+2.51.  Karn's Algorithm
+
+2.51.1.  Description of the Problem
+
+   The current wording of the use of Karn's algorithm is not descriptive
+   enough to ensure that an implementation in a multi-homed association
+   does not incorrectly mismeasure the RTT.
+
+2.51.2.  Text Changes to the Document
+
+   ---------
+   Old text: (Section 6.3.1)
+   ---------
+
+      C5) Karn's algorithm: RTT measurements MUST NOT be made using
+          packets that were retransmitted (and thus for which it is
+          ambiguous whether the reply was for the first instance of the
+          packet or a later instance)
+   ---------
+   New text: (Section 6.3.1)
+   ---------
+
+      C5) Karn's algorithm: RTT measurements MUST NOT be made using
+          chunks that were retransmitted (and thus for which it is
+          ambiguous whether the reply was for the first instance of
+          the chunk or for a later instance)
+
+          IMPLEMENTATION NOTE: RTT measurements should only be
+          made using a chunk with TSN r if no chunk
+          with TSN less than or equal to r is retransmitted
+          since r is first sent.
+
+2.51.3.  Solution Description
+
+   The above clarification adds an implementation note that will provide
+   additional guidance in the application of Karn's algorithm.
+
+2.52.  Fast Retransmit Algorithm
+
+2.52.1.  Description of the Problem
+
+   The original SCTP specification is overly conservative in requiring 4
+   missing reports before fast retransmitting a segment.  TCP uses 3
+   missing reports or 4 acknowledgements indicating that the same
+   segment was received.
+
+
+
+
+
+
+Stewart, et al.              Informational                    [Page 104]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+2.52.2.  Text Changes to the Document
+
+   ---------
+   Old text:
+   ---------
+
+   7.2.4 Fast Retransmit on Gap Reports
+
+      In the absence of data loss, an endpoint performs delayed
+      acknowledgement.  However, whenever an endpoint notices a hole in
+      the arriving TSN sequence, it SHOULD start sending a SACK back
+      every time a packet arrives carrying data until the
+      hole is filled.
+
+      Whenever an endpoint receives a SACK that indicates some TSN(s)
+      missing, it SHOULD wait for 3 further miss indications (via
+      subsequent SACK's) on the same TSN(s) before taking action with
+      regard to Fast Retransmit.
+
+
+   ---------
+   New text:
+   ---------
+
+   7.2.4.  Fast Retransmit on Gap Reports
+
+      In the absence of data loss, an endpoint performs delayed
+      acknowledgement.  However, whenever an endpoint notices a hole in
+      the arriving TSN sequence, it SHOULD start sending a SACK back
+      every time a packet arrives carrying data until the
+      hole is filled.
+
+      Whenever an endpoint receives a SACK that indicates that some
+      TSNs are missing, it SHOULD wait for 2 further miss indications
+      (via subsequent SACKs for a total of 3 missing reports) on the
+      same TSNs before taking action with regard to Fast Retransmit.
+
+2.52.3.  Solution Description
+
+   The above changes will make SCTP and TCP behave similarly in terms of
+   how fast they engage the Fast Retransmission algorithm upon receiving
+   missing reports.
+
+3.  Security Considerations
+
+   This document should add no additional security risks to SCTP and in
+   fact SHOULD correct some original security flaws within the original
+   document once it is incorporated into a RFC 2960 [5] BIS document.
+
+
+
+Stewart, et al.              Informational                    [Page 105]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+4.  Acknowledgements
+
+   The authors would like to thank the following people who have
+   provided comments and input for this document:
+
+   Barry Zuckerman, La Monte Yarroll, Qiaobing Xie, Wang Xiaopeng,
+   Jonathan Wood, Jeff Waskow, Mike Turner, John Townsend, Sabina
+   Torrente, Cliff Thomas, Yuji Suzuki, Manoj Solanki, Sverre Slotte,
+   Keyur Shah, Jan Rovins, Ben Robinson, Renee Revis, Ian Periam, RC
+   Monee, Sanjay Rao, Sujith Radhakrishnan, Heinz Prantner, Biren Patel,
+   Nathalie Mouellic, Mitch Miers, Bernward Meyknecht, Stan McClellan,
+   Oliver Mayor, Tomas Orti Martin, Sandeep Mahajan, David Lehmann,
+   Jonathan Lee, Philippe Langlois, Karl Knutson, Joe Keller, Gareth
+   Keily, Andreas Jungmaier, Janardhan Iyengar, Mutsuya Irie, John
+   Hebert, Kausar Hassan, Fred Hasle, Dan Harrison, Jon Grim, Laurent
+   Glaude, Steven Furniss, Atsushi Fukumoto, Ken Fujita, Steve Dimig,
+   Thomas Curran, Serkan Cil, Melissa Campbell, Peter Butler, Rob
+   Brennan, Harsh Bhondwe, Brian Bidulock, Caitlin Bestler, Jon Berger,
+   Robby Benedyk, Stephen Baucke, Sandeep Balani, and Ronnie Sellar.
+
+   A special thanks to Mark Allman, who should actually be a co-author
+   for his work on the max-burst, but managed to wiggle out due to a
+   technicality.  Also, we would like to acknowledge Lyndon Ong and Phil
+   Conrad for their valuable input and many contributions.
+
+5.  IANA Considerations
+
+   This document recommends changes for the RFC 2960 [5] BIS document.
+   As such, even though it lists new error cause code, this document in
+   itself does NOT define those new codes.  Instead, the BIS document
+   will make the needed changes to RFC 2960 [5] and thus its IANA
+   section will require changes to be made.
+
+6.  Normative References
+
+   [1]  Braden, R., "Requirements for Internet Hosts - Communication
+        Layers", STD 3, RFC 1122, October 1989.
+
+   [2]  Bradner, S., "Key words for use in RFCs to Indicate Requirement
+        Levels", BCP 14, RFC 2119, March 1997.
+
+   [3]  Caro, A., Shah, K., Iyengar, J., Amer, P., and R. Stewart, "SCTP
+        and TCP Variants: Congestion Control Under Multiple Losses",
+        Technical Report TR2003-04, Computer and Information Sciences
+        Department, University of Delaware, February 2003,
+        <http://www.armandocaro.net/papers>.
+
+
+
+
+
+Stewart, et al.              Informational                    [Page 106]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+   [4]  Caro, A., Amer, P., and R. Stewart, "Retransmission Schemes for
+        End-to-end Failover with Transport Layer Multihoming", GLOBECOM,
+        November 2004., <http://www.armandocaro.net/papers>.
+
+   [5]  Stewart, R., Xie, Q., Morneault, K., Sharp, C., Schwarzbauer,
+        H., Taylor, T., Rytina, I., Kalla, M., Zhang, L., and V.
+        Paxson, "Stream Control Transmission Protocol", RFC 2960,
+        October 2000.
+
+   [6]  Stone, J., Stewart, R., and D. Otis, "Stream Control
+        Transmission Protocol (SCTP) Checksum Change", RFC 3309,
+        September 2002.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.              Informational                    [Page 107]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+Authors' Addresses
+
+   Randall R. Stewart
+   Cisco Systems, Inc.
+   4875 Forest Drive
+   Suite 200
+   Columbia, SC  29206
+   USA
+
+   EMail: rrs@cisco.com
+
+
+   Ivan Arias-Rodriguez
+   Nokia Research Center
+   PO Box 407
+   FIN-00045 Nokia Group
+   Finland
+
+   EMail: ivan.arias-rodriguez@nokia.com
+
+
+   Kacheong Poon
+   Sun Microsystems, Inc.
+   3571 N. First St.
+   San Jose, CA  95134
+   USA
+
+   EMail: kacheong.poon@sun.com
+
+
+   Armando L. Caro Jr.
+   BBN Technologies
+   10 Moulton St.
+   Cambridge, MA 02138
+
+   EMail: acaro@bbn.com
+   URI:   http://www.armandocaro.net
+
+
+   Michael Tuexen
+   Muenster Univ. of Applied Sciences
+   Stegerwaldstr. 39
+   48565 Steinfurt
+   Germany
+
+   EMail: tuexen@fh-muenster.de
+
+
+
+
+
+Stewart, et al.              Informational                    [Page 108]
+
+RFC 4460                      SCTP Errata                     April 2006
+
+
+Full Copyright Statement
+
+   Copyright (C) The Internet Society (2006).
+
+   This document is subject to the rights, licenses and restrictions
+   contained in BCP 78, and except as set forth therein, the authors
+   retain all their rights.
+
+   This document and the information contained herein are provided on an
+   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
+   OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET
+   ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED,
+   INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
+   INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
+   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Intellectual Property
+
+   The IETF takes no position regarding the validity or scope of any
+   Intellectual Property Rights or other rights that might be claimed to
+   pertain to the implementation or use of the technology described in
+   this document or the extent to which any license under such rights
+   might or might not be available; nor does it represent that it has
+   made any independent effort to identify any such rights.  Information
+   on the procedures with respect to rights in RFC documents can be
+   found in BCP 78 and BCP 79.
+
+   Copies of IPR disclosures made to the IETF Secretariat and any
+   assurances of licenses to be made available, or the result of an
+   attempt made to obtain a general license or permission for the use of
+   such proprietary rights by implementers or users of this
+   specification can be obtained from the IETF on-line IPR repository at
+   http://www.ietf.org/ipr.
+
+   The IETF invites any interested party to bring to its attention any
+   copyrights, patents or patent applications, or other proprietary
+   rights that may cover technology that may be required to implement
+   this standard.  Please address the information to the IETF at
+   ietf-ipr@ietf.org.
+
+Acknowledgement
+
+   Funding for the RFC Editor function is provided by the IETF
+   Administrative Support Activity (IASA).
+
+
+
+
+
+
+
+Stewart, et al.              Informational                    [Page 109]
+
diff --git a/doc/rfc4820.txt b/doc/rfc4820.txt
new file mode 100644
index 0000000..4b9b241
--- /dev/null
+++ b/doc/rfc4820.txt
@@ -0,0 +1,339 @@
+
+
+
+
+
+
+Network Working Group                                          M. Tuexen
+Request for Comments: 4820            Muenster Univ. of Applied Sciences
+Category: Standards Track                                     R. Stewart
+                                                                  P. Lei
+                                                     Cisco Systems, Inc.
+                                                              March 2007
+
+
+                      Padding Chunk and Parameter
+          for the Stream Control Transmission Protocol (SCTP)
+
+Status of This Memo
+
+   This document specifies an Internet standards track protocol for the
+   Internet community, and requests discussion and suggestions for
+   improvements.  Please refer to the current edition of the "Internet
+   Official Protocol Standards" (STD 1) for the standardization state
+   and status of this protocol.  Distribution of this memo is unlimited.
+
+Copyright Notice
+
+   Copyright (C) The IETF Trust (2007).
+
+Abstract
+
+   This document defines a padding chunk and a padding parameter and
+   describes the required receiver side procedures.  The padding chunk
+   is used to pad a Stream Control Transmission Protocol (SCTP) packet
+   to an arbitrary size.  The padding parameter is used to pad an SCTP
+   INIT chunk to an arbitrary size.
+
+Table of Contents
+
+   1.  Introduction  . . . . . . . . . . . . . . . . . . . . . . . . . 2
+   2.  Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . 2
+   3.  Padding Chunk (PAD) . . . . . . . . . . . . . . . . . . . . . . 2
+   4.  Padding Parameter (PAD) . . . . . . . . . . . . . . . . . . . . 3
+   5.  IANA Considerations . . . . . . . . . . . . . . . . . . . . . . 4
+     5.1.  A New Chunk Type  . . . . . . . . . . . . . . . . . . . . . 4
+     5.2.  A New Parameter Type  . . . . . . . . . . . . . . . . . . . 4
+   6.  Security Considerations . . . . . . . . . . . . . . . . . . . . 4
+   7.  Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . 4
+   8.  References  . . . . . . . . . . . . . . . . . . . . . . . . . . 5
+     8.1.  Normative References  . . . . . . . . . . . . . . . . . . . 5
+     8.2.  Informative References  . . . . . . . . . . . . . . . . . . 5
+
+
+
+
+
+
+Tuexen, et al.              Standards Track                     [Page 1]
+
+RFC 4820          Padding Chunk and Parameter for SCTP        March 2007
+
+
+1.  Introduction
+
+   This document defines a padding chunk and a padding parameter and
+   describes the required receiver side procedures.  The padding chunk
+   is used to pad an SCTP packet to an arbitrary size.  The padding
+   parameter is used to pad an SCTP INIT chunk to an arbitrary size.
+   The usage of the PAD chunk for path MTU discovery is described in
+   PMTU [4].  The inappropriate usage of the PAD parameter or PAD chunk
+   can result in wasted bandwidth.
+
+2.  Conventions
+
+   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+   "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
+   "OPTIONAL", when they appear in this document, are to be interpreted
+   as described in RFC 2119 [1].
+
+3.  Padding Chunk (PAD)
+
+   This chunk is used to pad an SCTP packet.  A PAD chunk can be used to
+   enlarge the packet by 4 to 65536 bytes in steps of 4 bytes.  An SCTP
+   packet MAY contain multiple PAD chunks.
+
+    0                   1                   2                   3
+    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   | Type = 0x84   |   Flags=0     |             Length            |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                                                               |
+   \                         Padding Data                          /
+   /                                                               \
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+                                 Figure 1
+
+   Type: 1 byte (unsigned integer)
+      This value MUST be set to 0x84 for all PAD chunks.
+
+   Flags: 1 byte (unsigned integer)
+      This value SHOULD be set to zero on transmit and MUST be ignored
+      on receipt.
+
+   Length: 2 bytes (unsigned integer)
+      This value holds the length of the Padding Data plus 4.
+
+
+
+
+
+
+
+Tuexen, et al.              Standards Track                     [Page 2]
+
+RFC 4820          Padding Chunk and Parameter for SCTP        March 2007
+
+
+   Padding Data: n bytes (unsigned integer)
+      This holds the Padding Data.  The Padding Data MUST be ignored by
+      the receiver.
+
+   The receiver of the PAD chunk MUST discard this chunk and continue
+   processing the rest of the chunks in the packet.  Please note that
+   this is also the required processing behavior for any unknown chunk
+   having the same highest-order two bits of the type as the PAD chunk.
+
+4.  Padding Parameter (PAD)
+
+   This parameter is used to pad an INIT chunk.  A PAD parameter can be
+   used to enlarge the INIT chunk by 4 bytes as the minimum to the
+   maximum size of the INIT chunk in steps of 4 bytes.  An INIT chunk
+   MAY contain multiple PAD parameters.
+
+    0                   1                   2                   3
+    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Parameter Type = 0x8005   |       Parameter Length        |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   /                                                               /
+   \                          Padding Data                         \
+   /                                                               /
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+                                 Figure 2
+
+   Parameter Type: 2 bytes (unsigned integer)
+      This value MUST be set to 0x8005.
+
+   Parameter Length: 2 bytes (unsigned integer)
+      This value holds the length of the Padding Data plus 4.
+
+   The PAD parameter MAY be included only in the INIT chunk.  It MUST
+   NOT be included in any other chunk.  The receiver of the PAD
+   parameter MUST silently discard this parameter and continue
+   processing the rest of the INIT chunk.  This means that the size of
+   the generated COOKIE parameter in the INIT-ACK MUST NOT depend on the
+   existence of the PAD parameter in the INIT chunk.  A receiver of a
+   PAD parameter MUST NOT include the PAD parameter within any State
+   Cookie parameter it generates.
+
+
+
+
+
+
+
+
+
+Tuexen, et al.              Standards Track                     [Page 3]
+
+RFC 4820          Padding Chunk and Parameter for SCTP        March 2007
+
+
+5.  IANA Considerations
+
+   This document is the reference for all registrations described in
+   this section.  All registrations have been listed in the document
+   available at sctp-parameters [3].  The changes are described below.
+
+5.1.  A New Chunk Type
+
+   A chunk type for the PAD chunk has been assigned by IANA.  The value
+   has been assigned as described in Figure 1.  The following has been
+   added to the "CHUNK TYPES" table of sctp-parameters [3]:
+
+   CHUNK TYPES
+
+   ID Value    Chunk Type                                     Reference
+   --------    ----------                                     ---------
+   132(0x84)   Padding Chunk (PAD)                            [RFC4820]
+
+5.2.  A New Parameter Type
+
+   A parameter type has been assigned for the PAD parameter by IANA.
+   The value has been assigned as described in Figure 2.  The following
+   has been added to the "CHUNK PARAMETER TYPES" table in sctp-
+   parameters [3]:
+
+   INIT Chunk Parameter Types
+
+   Chunk Parameter Type                       Value
+   --------------------                       -----
+   Padding                            32773(0x8005)
+
+6.  Security Considerations
+
+   This document does not add any additional security considerations to
+   the ones given in RFC 2960 [2].
+
+7.  Acknowledgments
+
+   The authors wish to thank Matthew J. Zekauskas and Lars Eggert for
+   their invaluable comments.
+
+
+
+
+
+
+
+
+
+
+
+Tuexen, et al.              Standards Track                     [Page 4]
+
+RFC 4820          Padding Chunk and Parameter for SCTP        March 2007
+
+
+8.  References
+
+8.1.  Normative References
+
+   [1]  Bradner, S., "Key words for use in RFCs to Indicate Requirement
+        Levels", BCP 14, RFC 2119, March 1997.
+
+   [2]  Stewart, R., Xie, Q., Morneault, K., Sharp, C., Schwarzbauer,
+        H., Taylor, T., Rytina, I., Kalla, M., Zhang, L., and V. Paxson,
+        "Stream Control Transmission Protocol", RFC 2960, October 2000.
+
+8.2.  Informative References
+
+   [3]  "IANA registry",
+        <http://www.iana.org/assignments/sctp-parameters>.
+
+   [4]  Mathis, M. and J. Heffner, "Packetization Layer Path MTU
+        Discovery", RFC 4821, March 2007.
+
+Authors' Addresses
+
+   Michael Tuexen
+   Muenster Univ. of Applied Sciences
+   Stegerwaldstr. 39
+   48565 Steinfurt
+   Germany
+
+   EMail: tuexen@fh-muenster.de
+
+
+   Randall R. Stewart
+   Cisco Systems, Inc.
+   4875 Forest Drive
+   Suite 200
+   Columbia, SC  29206
+   USA
+
+   EMail: rrs@cisco.com
+
+
+   Peter Lei
+   Cisco Systems, Inc.
+   955 Happfield Dr.
+   Arlington Heights, IL  60004
+   US
+
+   Phone: +1 773 695-8201
+   EMail: peterlei@cisco.com
+
+
+
+Tuexen, et al.              Standards Track                     [Page 5]
+
+RFC 4820          Padding Chunk and Parameter for SCTP        March 2007
+
+
+Full Copyright Statement
+
+   Copyright (C) The IETF Trust (2007).
+
+   This document is subject to the rights, licenses and restrictions
+   contained in BCP 78, and except as set forth therein, the authors
+   retain all their rights.
+
+   This document and the information contained herein are provided on an
+   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
+   OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND
+   THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
+   THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
+   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Intellectual Property
+
+   The IETF takes no position regarding the validity or scope of any
+   Intellectual Property Rights or other rights that might be claimed to
+   pertain to the implementation or use of the technology described in
+   this document or the extent to which any license under such rights
+   might or might not be available; nor does it represent that it has
+   made any independent effort to identify any such rights.  Information
+   on the procedures with respect to rights in RFC documents can be
+   found in BCP 78 and BCP 79.
+
+   Copies of IPR disclosures made to the IETF Secretariat and any
+   assurances of licenses to be made available, or the result of an
+   attempt made to obtain a general license or permission for the use of
+   such proprietary rights by implementers or users of this
+   specification can be obtained from the IETF on-line IPR repository at
+   http://www.ietf.org/ipr.
+
+   The IETF invites any interested party to bring to its attention any
+   copyrights, patents or patent applications, or other proprietary
+   rights that may cover technology that may be required to implement
+   this standard.  Please address the information to the IETF at
+   ietf-ipr@ietf.org.
+
+Acknowledgement
+
+   Funding for the RFC Editor function is currently provided by the
+   Internet Society.
+
+
+
+
+
+
+
+Tuexen, et al.              Standards Track                     [Page 6]
+
diff --git a/doc/rfc4895.txt b/doc/rfc4895.txt
new file mode 100644
index 0000000..e877f5a
--- /dev/null
+++ b/doc/rfc4895.txt
@@ -0,0 +1,1067 @@
+
+
+
+
+
+
+Network Working Group                                          M. Tuexen
+Request for Comments: 4895            Muenster Univ. of Applied Sciences
+Category: Standards Track                                     R. Stewart
+                                                                  P. Lei
+                                                     Cisco Systems, Inc.
+                                                             E. Rescorla
+                                                              RTFM, Inc.
+                                                             August 2007
+
+
+                       Authenticated Chunks for
+            the Stream Control Transmission Protocol (SCTP)
+
+Status of This Memo
+
+   This document specifies an Internet standards track protocol for the
+   Internet community, and requests discussion and suggestions for
+   improvements.  Please refer to the current edition of the "Internet
+   Official Protocol Standards" (STD 1) for the standardization state
+   and status of this protocol.  Distribution of this memo is unlimited.
+
+Abstract
+
+   This document describes a new chunk type, several parameters, and
+   procedures for the Stream Control Transmission Protocol (SCTP).  This
+   new chunk type can be used to authenticate SCTP chunks by using
+   shared keys between the sender and receiver.  The new parameters are
+   used to establish the shared keys.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Tuexen, et al.              Standards Track                     [Page 1]
+
+RFC 4895               SCTP Authentication Chunk             August 2007
+
+
+Table of Contents
+
+   1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  3
+   2.  Conventions  . . . . . . . . . . . . . . . . . . . . . . . . .  3
+   3.  New Parameter Types  . . . . . . . . . . . . . . . . . . . . .  4
+     3.1.  Random Parameter (RANDOM)  . . . . . . . . . . . . . . . .  4
+     3.2.  Chunk List Parameter (CHUNKS)  . . . . . . . . . . . . . .  5
+     3.3.  Requested HMAC Algorithm Parameter (HMAC-ALGO) . . . . . .  6
+   4.  New Error Cause  . . . . . . . . . . . . . . . . . . . . . . .  7
+     4.1.  Unsupported HMAC Identifier Error Cause  . . . . . . . . .  7
+   5.  New Chunk Type . . . . . . . . . . . . . . . . . . . . . . . .  8
+     5.1.  Authentication Chunk (AUTH)  . . . . . . . . . . . . . . .  8
+   6.  Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . 10
+     6.1.  Establishment of an Association Shared Key . . . . . . . . 10
+     6.2.  Sending Authenticated Chunks . . . . . . . . . . . . . . . 11
+     6.3.  Receiving Authenticated Chunks . . . . . . . . . . . . . . 12
+   7.  Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
+   8.  IANA Considerations  . . . . . . . . . . . . . . . . . . . . . 15
+     8.1.  A New Chunk Type . . . . . . . . . . . . . . . . . . . . . 15
+     8.2.  Three New Parameter Types  . . . . . . . . . . . . . . . . 15
+     8.3.  A New Error Cause  . . . . . . . . . . . . . . . . . . . . 15
+     8.4.  A New Table for HMAC Identifiers . . . . . . . . . . . . . 16
+   9.  Security Considerations  . . . . . . . . . . . . . . . . . . . 16
+   10. Acknowledgments  . . . . . . . . . . . . . . . . . . . . . . . 17
+   11. Normative References . . . . . . . . . . . . . . . . . . . . . 17
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Tuexen, et al.              Standards Track                     [Page 2]
+
+RFC 4895               SCTP Authentication Chunk             August 2007
+
+
+1.  Introduction
+
+   SCTP uses 32-bit verification tags to protect itself against blind
+   attackers.  These values are not changed during the lifetime of an
+   SCTP association.
+
+   Looking at new SCTP extensions, there is the need to have a method of
+   proving that an SCTP chunk(s) was really sent by the original peer
+   that started the association and not by a malicious attacker.
+
+   Using Transport Layer Security (TLS), as defined in RFC 3436 [6],
+   does not help because it only secures SCTP user data.
+
+   Therefore, an SCTP extension that provides a mechanism for deriving
+   shared keys for each association is presented.  These association
+   shared keys are derived from endpoint pair shared keys, which are
+   configured and might be empty, and data that is exchanged during the
+   SCTP association setup.
+
+   The extension presented in this document allows an SCTP sender to
+   authenticate chunks using shared keys between the sender and
+   receiver.  The receiver can then verify that the chunks are sent from
+   the sender and not from a malicious attacker (as long as the attacker
+   does not know an association shared key).
+
+   The extension described in this document places the result of a
+   Hashed Message Authentication Code (HMAC) computation before the data
+   covered by that computation.  Placing it at the end of the packet
+   would have required placing a control chunk after DATA chunks in case
+   of authenticating DATA chunks.  This would break the rule that
+   control chunks occur before DATA chunks in SCTP packets.  It should
+   also be noted that putting the result of the HMAC computation after
+   the data being covered would not allow sending the packet during the
+   computation of the HMAC because the result of the HMAC computation is
+   needed to compute the CRC32C checksum of the SCTP packet, which is
+   placed in the common header of the SCTP packet.
+
+   The SCTP extension for Dynamic Address Reconfiguration (ADD-IP)
+   requires the usage of the extension described in this document.  The
+   SCTP Partial Reliability Extension (PR-SCTP) can be used in
+   conjunction with the extension described in this document.
+
+2.  Conventions
+
+   The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+   "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
+   "OPTIONAL", when they appear in this document, are to be interpreted
+   as described in RFC 2119 [3].
+
+
+
+Tuexen, et al.              Standards Track                     [Page 3]
+
+RFC 4895               SCTP Authentication Chunk             August 2007
+
+
+3.  New Parameter Types
+
+   This section defines the new parameter types that will be used to
+   negotiate the authentication during association setup.  Table 1
+   illustrates the new parameter types.
+
+    +----------------+------------------------------------------------+
+    | Parameter Type | Parameter Name                                 |
+    +----------------+------------------------------------------------+
+    | 0x8002         | Random Parameter (RANDOM)                      |
+    | 0x8003         | Chunk List Parameter (CHUNKS)                  |
+    | 0x8004         | Requested HMAC Algorithm Parameter (HMAC-ALGO) |
+    +----------------+------------------------------------------------+
+
+                                  Table 1
+
+   Note that the parameter format requires the receiver to ignore the
+   parameter and continue processing if the parameter is not understood.
+   This is accomplished (as described in RFC 2960 [5], Section 3.2.1.)
+   by the use of the upper bits of the parameter type.
+
+3.1.  Random Parameter (RANDOM)
+
+   This parameter is used to carry a random number of an arbitrary
+   length.
+
+    0                   1                   2                   3
+    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Parameter Type = 0x8002   |       Parameter Length        |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                                                               |
+   \                          Random Number                        /
+   /                               +-------------------------------\
+   |                               |           Padding             |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+                                 Figure 1
+
+   Parameter Type: 2 bytes (unsigned integer)
+      This value MUST be set to 0x8002.
+
+   Parameter Length: 2 bytes (unsigned integer)
+      This value is the length of the Random Number in bytes plus 4.
+
+
+
+
+
+
+
+Tuexen, et al.              Standards Track                     [Page 4]
+
+RFC 4895               SCTP Authentication Chunk             August 2007
+
+
+   Random Number: n bytes (unsigned integer)
+      This value represents an arbitrary Random Number in network byte
+      order.
+
+   Padding: 0, 1, 2, or 3 bytes (unsigned integer)
+      If the length of the Random Number is not a multiple of 4 bytes,
+      the sender MUST pad the parameter with all zero bytes to make the
+      parameter 32-bit aligned.  The Padding MUST NOT be longer than 3
+      bytes and it MUST be ignored by the receiver.
+
+   The RANDOM parameter MUST be included once in the INIT or INIT-ACK
+   chunk, if the sender wants to send or receive authenticated chunks,
+   to provide a 32-byte Random Number.  For 32-byte Random Numbers, the
+   Padding is empty.
+
+3.2.  Chunk List Parameter (CHUNKS)
+
+   This parameter is used to specify which chunk types are required to
+   be authenticated before being sent by the peer.
+
+    0                   1                   2                   3
+    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Parameter Type = 0x8003   |       Parameter Length        |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   | Chunk Type 1  | Chunk Type 2  | Chunk Type 3  | Chunk Type 4  |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   /                                                               /
+   \                              ...                              \
+   /                                                               /
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   | Chunk Type n  |                   Padding                     |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+                                 Figure 2
+
+   Parameter Type: 2 bytes (unsigned integer)
+      This value MUST be set to 0x8003.
+
+   Parameter Length: 2 bytes (unsigned integer)
+      This value is the number of listed Chunk Types plus 4.
+
+   Chunk Type n: 1 byte (unsigned integer)
+      Each Chunk Type listed is required to be authenticated when sent
+      by the peer.
+
+
+
+
+
+
+Tuexen, et al.              Standards Track                     [Page 5]
+
+RFC 4895               SCTP Authentication Chunk             August 2007
+
+
+   Padding: 0, 1, 2, or 3 bytes (unsigned integer)
+      If the number of Chunk Types is not a multiple of 4, the sender
+      MUST pad the parameter with all zero bytes to make the parameter
+      32-bit aligned.  The Padding MUST NOT be longer than 3 bytes and
+      it MUST be ignored by the receiver.
+
+   The CHUNKS parameter MUST be included once in the INIT or INIT-ACK
+   chunk if the sender wants to receive authenticated chunks.  Its
+   maximum length is 260 bytes.
+
+   The chunk types for INIT, INIT-ACK, SHUTDOWN-COMPLETE, and AUTH
+   chunks MUST NOT be listed in the CHUNKS parameter.  However, if a
+   CHUNKS parameter is received then the types for INIT, INIT-ACK,
+   SHUTDOWN-COMPLETE, and AUTH chunks MUST be ignored.
+
+3.3.  Requested HMAC Algorithm Parameter (HMAC-ALGO)
+
+   This parameter is used to list the HMAC Identifiers the peer MUST
+   use.
+
+    0                   1                   2                   3
+    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Parameter Type = 0x8004   |       Parameter Length        |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |          HMAC Identifier 1    |      HMAC Identifier 2        |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   /                                                               /
+   \                              ...                              \
+   /                                                               /
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |        HMAC Identifier n      |           Padding             |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+                                 Figure 3
+
+   Parameter Type: 2 bytes (unsigned integer)
+      This value MUST be set to 0x8004.
+
+   Parameter Length: 2 bytes (unsigned integer)
+      This value is the number of HMAC Identifiers multiplied by 2, plus
+      4.
+
+   HMAC Identifier n: 2 bytes (unsigned integer)
+      The values expressed are a list of HMAC Identifiers that may be
+      used by the peer.  The values are listed by preference, with
+      respect to the sender, where the first HMAC Identifier listed is
+      the one most preferable to the sender.
+
+
+
+Tuexen, et al.              Standards Track                     [Page 6]
+
+RFC 4895               SCTP Authentication Chunk             August 2007
+
+
+   Padding: 0 or 2 bytes (unsigned integer)
+      If the number of HMAC Identifiers is not even, the sender MUST pad
+      the parameter with all zero bytes to make the parameter 32-bit
+      aligned.  The Padding MUST be 0 or 2 bytes long and it MUST be
+      ignored by the receiver.
+
+   The HMAC-ALGO parameter MUST be included once in the INIT or INIT-ACK
+   chunk if the sender wants to send or receive authenticated chunks.
+
+   Table 2 shows the currently defined values for HMAC Identifiers.
+
+              +-----------------+--------------------------+
+              | HMAC Identifier | Message Digest Algorithm |
+              +-----------------+--------------------------+
+              | 0               | Reserved                 |
+              | 1               | SHA-1 defined in [8]     |
+              | 2               | Reserved                 |
+              | 3               | SHA-256 defined in [8]   |
+              +-----------------+--------------------------+
+
+                                  Table 2
+
+   Every endpoint supporting SCTP chunk authentication MUST support the
+   HMAC based on the SHA-1 algorithm.
+
+4.  New Error Cause
+
+   This section defines a new error cause that will be sent if an AUTH
+   chunk is received with an unsupported HMAC Identifier.  Table 3
+   illustrates the new error cause.
+
+               +------------+-----------------------------+
+               | Cause Code | Error Cause Name            |
+               +------------+-----------------------------+
+               | 0x0105     | Unsupported HMAC Identifier |
+               +------------+-----------------------------+
+
+                                  Table 3
+
+4.1.  Unsupported HMAC Identifier Error Cause
+
+   This error cause is used to indicate that an AUTH chunk has been
+   received with an unsupported HMAC Identifier.
+
+
+
+
+
+
+
+
+Tuexen, et al.              Standards Track                     [Page 7]
+
+RFC 4895               SCTP Authentication Chunk             August 2007
+
+
+    0                   1                   2                   3
+    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |      Cause Code = 0x0105      |       Cause Length = 6        |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |         HMAC Identifier       |            Padding            |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+                                 Figure 4
+
+   Cause Code: 2 bytes (unsigned integer)
+      This value MUST be set to 0x0105.
+
+   Cause Length: 2 bytes (unsigned integer)
+      This value MUST be set to 6.
+
+   HMAC Identifier: 2 bytes (unsigned integer)
+      This value is the HMAC Identifier which is not supported.
+
+   Padding: 2 bytes (unsigned integer)
+      The sender MUST pad the error cause with all zero bytes to make
+      the cause 32-bit aligned.  The Padding MUST be 2 bytes long and it
+      MUST be ignored by the receiver.
+
+5.  New Chunk Type
+
+   This section defines the new chunk type that will be used to
+   authenticate chunks.  Table 4 illustrates the new chunk type.
+
+               +------------+-----------------------------+
+               | Chunk Type | Chunk Name                  |
+               +------------+-----------------------------+
+               | 0x0F       | Authentication Chunk (AUTH) |
+               +------------+-----------------------------+
+
+                                  Table 4
+
+   It should be noted that the AUTH-chunk format requires the receiver
+   to ignore the chunk if it is not understood and silently discard all
+   chunks that follow.  This is accomplished (as described in RFC 2960
+   [5], Section 3.2.) by the use of the upper bits of the chunk type.
+
+5.1.  Authentication Chunk (AUTH)
+
+   This chunk is used to hold the result of the HMAC calculation.
+
+
+
+
+
+
+Tuexen, et al.              Standards Track                     [Page 8]
+
+RFC 4895               SCTP Authentication Chunk             August 2007
+
+
+    0                   1                   2                   3
+    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   | Type = 0x0F   |   Flags=0     |             Length            |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |    Shared Key Identifier      |        HMAC Identifier        |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                                                               |
+   \                             HMAC                              /
+   /                                                               \
+   /                               +-------------------------------\
+   |                               |           Padding             |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+                                 Figure 5
+
+   Type: 1 byte (unsigned integer)
+      This value MUST be set to 0x0F for all AUTH-chunks.
+
+   Flags: 1 byte (unsigned integer)
+      SHOULD be set to zero on transmit and MUST be ignored on receipt.
+
+   Length: 2 bytes (unsigned integer)
+      This value holds the length of the HMAC in bytes plus 8.
+
+   Shared Key Identifier: 2 bytes (unsigned integer)
+      This value describes which endpoint pair shared key is used.
+
+   HMAC Identifier: 2 bytes (unsigned integer)
+      This value describes which message digest is being used.  Table 2
+      shows the currently defined values.
+
+   HMAC: n bytes (unsigned integer)
+      This holds the result of the HMAC calculation.
+
+   Padding: 0, 1, 2, or 3 bytes (unsigned integer)
+      If the length of the HMAC is not a multiple of 4 bytes, the sender
+      MUST pad the chunk with all zero bytes to make the chunk 32-bit
+      aligned.  The Padding MUST NOT be longer than 3 bytes and it MUST
+      be ignored by the receiver.
+
+   The control chunk AUTH MUST NOT appear more than once in an SCTP
+   packet.  All control and data chunks that are placed after the AUTH
+   chunk in the packet are sent in an authenticated way.  Those chunks
+   placed in a packet before the AUTH chunk are not authenticated.
+   Please note that DATA chunks can not appear before control chunks in
+   an SCTP packet.
+
+
+
+
+Tuexen, et al.              Standards Track                     [Page 9]
+
+RFC 4895               SCTP Authentication Chunk             August 2007
+
+
+6.  Procedures
+
+6.1.  Establishment of an Association Shared Key
+
+   An SCTP endpoint willing to receive or send authenticated chunks MUST
+   send one RANDOM parameter in its INIT or INIT-ACK chunk.  The RANDOM
+   parameter MUST contain a 32-byte Random Number.  The Random Number
+   should be generated in accordance with RFC 4086 [7].  If the Random
+   Number is not 32 bytes, the association MUST be aborted.  The ABORT
+   chunk SHOULD contain the error cause 'Protocol Violation'.  In case
+   of INIT collision, the rules governing the handling of this Random
+   Number follow the same pattern as those for the Verification Tag, as
+   explained in Section 5.2.4 of RFC 2960 [5].  Therefore, each endpoint
+   knows its own Random Number and the peer's Random Number after the
+   association has been established.
+
+   An SCTP endpoint has a list of chunks it only accepts if they are
+   received in an authenticated way.  This list is included in the INIT
+   and INIT-ACK, and MAY be omitted if it is empty.  Since this list
+   does not change during the lifetime of the SCTP endpoint there is no
+   problem in case of INIT collision.
+
+   Each SCTP endpoint MUST include in the INIT and INIT-ACK a HMAC-ALGO
+   parameter containing a list of HMAC Identifiers it requests the peer
+   to use.  The receiver of an HMAC-ALGO parameter SHOULD use the first
+   listed algorithm it supports.  The HMAC algorithm based on SHA-1 MUST
+   be supported and included in the HMAC-ALGO parameter.  An SCTP
+   endpoint MUST NOT change the parameters listed in the HMAC-ALGO
+   parameter during the lifetime of the endpoint.
+
+   Both endpoints of an association MAY have endpoint pair shared keys
+   that are byte vectors and pre-configured or established by another
+   mechanism.  They are identified by the Shared Key Identifier.  For
+   each endpoint pair shared key, an association shared key is computed.
+   If there is no endpoint pair shared key, only one association shared
+   key is computed by using an empty byte vector as the endpoint pair
+   shared key.
+
+   The RANDOM parameter, the CHUNKS parameter, and the HMAC-ALGO
+   parameter sent by each endpoint are concatenated as byte vectors.
+   These parameters include the parameter type, parameter length, and
+   the parameter value, but padding is omitted; all padding MUST be
+   removed from this concatenation before proceeding with further
+   computation of keys.  Parameters that were not sent are simply
+   omitted from the concatenation process.  The resulting two vectors
+   are called the two key vectors.
+
+
+
+
+
+Tuexen, et al.              Standards Track                    [Page 10]
+
+RFC 4895               SCTP Authentication Chunk             August 2007
+
+
+   From the endpoint pair shared keys and the key vectors, the
+   association shared keys are computed.  This is performed by selecting
+   the numerically smaller key vector and concatenating it to the
+   endpoint pair shared key, and then concatenating the numerically
+   larger key vector to that.  If the key vectors are equal as numbers
+   but differ in length, then the concatenation order is the endpoint
+   shared key, followed by the shorter key vector, followed by the
+   longer key vector.  Otherwise, the key vectors are identical, and may
+   be concatenated to the endpoint pair key in any order.  The
+   concatenation is performed on byte vectors, and all numerical
+   comparisons use network byte order to convert the key vectors to a
+   number.  The result of the concatenation is the association shared
+   key.
+
+6.2.  Sending Authenticated Chunks
+
+   Endpoints MUST send all requested chunks that have been authenticated
+   where this has been requested by the peer.  The other chunks MAY be
+   sent whether or not they have been authenticated.  If endpoint pair
+   shared keys are used, one of them MUST be selected for
+   authentication.
+
+   To send chunks in an authenticated way, the sender MUST include these
+   chunks after an AUTH chunk.  This means that a sender MUST bundle
+   chunks in order to authenticate them.
+
+   If the endpoint has no endpoint pair shared key for the peer, it MUST
+   use Shared Key Identifier zero with an empty endpoint pair shared
+   key.  If there are multiple endpoint shared keys the sender selects
+   one and uses the corresponding Shared Key Identifier.
+
+   The sender MUST calculate the Message Authentication Code (MAC) (as
+   described in RFC 2104 [2]) using the hash function H as described by
+   the HMAC Identifier and the shared association key K based on the
+   endpoint pair shared key described by the Shared Key Identifier.  The
+   'data' used for the computation of the AUTH-chunk is given by the
+   AUTH chunk with its HMAC field set to zero (as shown in Figure 6)
+   followed by all the chunks that are placed after the AUTH chunk in
+   the SCTP packet.
+
+
+
+
+
+
+
+
+
+
+
+
+Tuexen, et al.              Standards Track                    [Page 11]
+
+RFC 4895               SCTP Authentication Chunk             August 2007
+
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   | Type = 0x0F   |   Flags=0     |         Chunk Length          |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |    Shared Key Identifier      |        HMAC Identifier        |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                                                               |
+   \                               0                               /
+   /                               +-------------------------------\
+   |                               |           Padding             |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+                                 Figure 6
+
+   Please note that all fields are in network byte order and that the
+   field that will contain the complete HMAC is filled with zeroes.  The
+   length of the field shown as zero is the length of the HMAC described
+   by the HMAC Identifier.  The padding of all chunks being
+   authenticated MUST be included in the HMAC computation.
+
+   The sender fills the HMAC into the HMAC field and sends the packet.
+
+6.3.  Receiving Authenticated Chunks
+
+   The receiver has a list of chunk types that it expects to be received
+   only after an AUTH-chunk.  This list has been sent to the peer during
+   the association setup.  It MUST silently discard these chunks if they
+   are not placed after an AUTH chunk in the packet.
+
+   The receiver MUST use the HMAC algorithm indicated in the HMAC
+   Identifier field.  If this algorithm was not specified by the
+   receiver in the HMAC-ALGO parameter in the INIT or INIT-ACK chunk
+   during association setup, the AUTH chunk and all the chunks after it
+   MUST be discarded and an ERROR chunk SHOULD be sent with the error
+   cause defined in Section 4.1.
+
+   If an endpoint with no shared key receives a Shared Key Identifier
+   other than 0, it MUST silently discard all authenticated chunks.  If
+   the endpoint has at least one endpoint pair shared key for the peer,
+   it MUST use the key specified by the Shared Key Identifier if a key
+   has been configured for that Shared Key Identifier.  If no endpoint
+   pair shared key has been configured for that Shared Key Identifier,
+   all authenticated chunks MUST be silently discarded.
+
+   The receiver now performs the same calculation as described for the
+   sender based on Figure 6.  If the result of the calculation is the
+
+
+
+
+
+
+Tuexen, et al.              Standards Track                    [Page 12]
+
+RFC 4895               SCTP Authentication Chunk             August 2007
+
+
+   same as given in the HMAC field, all the chunks following the AUTH
+   chunk are processed.  If the field does not match the result of the
+   calculation, all the chunks following the AUTH chunk MUST be silently
+   discarded.
+
+   It should be noted that if the receiver wants to tear down an
+   association in an authenticated way only, the handling of malformed
+   packets should not result in tearing down the association.
+
+   An SCTP implementation has to maintain state for each SCTP
+   association.  In the following, we call this data structure the SCTP
+   transmission control block (STCB).
+
+   When an endpoint requires COOKIE-ECHO chunks to be authenticated,
+   some special procedures have to be followed because the reception of
+   a COOKIE-ECHO chunk might result in the creation of an SCTP
+   association.  If a packet arrives containing an AUTH chunk as a first
+   chunk, a COOKIE-ECHO chunk as the second chunk, and possibly more
+   chunks after them, and the receiver does not have an STCB for that
+   packet, then authentication is based on the contents of the COOKIE-
+   ECHO chunk.  In this situation, the receiver MUST authenticate the
+   chunks in the packet by using the RANDOM parameters, CHUNKS
+   parameters and HMAC_ALGO parameters obtained from the COOKIE-ECHO
+   chunk, and possibly a local shared secret as inputs to the
+   authentication procedure specified in Section 6.3.  If authentication
+   fails, then the packet is discarded.  If the authentication is
+   successful, the COOKIE-ECHO and all the chunks after the COOKIE-ECHO
+   MUST be processed.  If the receiver has an STCB, it MUST process the
+   AUTH chunk as described above using the STCB from the existing
+   association to authenticate the COOKIE-ECHO chunk and all the chunks
+   after it.
+
+   If the receiver does not find an STCB for a packet containing an AUTH
+   chunk as the first chunk and does not find a COOKIE-ECHO chunk as the
+   second chunk, it MUST use the chunks after the AUTH chunk to look up
+   an existing association.  If no association is found, the packet MUST
+   be considered as out of the blue.  The out of the blue handling MUST
+   be based on the packet without taking the AUTH chunk into account.
+   If an association is found, it MUST process the AUTH chunk using the
+   STCB from the existing association as described earlier.
+
+   Requiring ABORT chunks and COOKIE-ECHO chunks to be authenticated
+   makes it impossible for an attacker to bring down or restart an
+   association as long as the attacker does not know the association
+   shared key.  But it should also be noted that if an endpoint accepts
+   ABORT chunks only in an authenticated way, it may take longer to
+   detect that the peer is no longer available.  If an endpoint accepts
+   COOKIE-ECHO chunks only in an authenticated way, the restart
+
+
+
+Tuexen, et al.              Standards Track                    [Page 13]
+
+RFC 4895               SCTP Authentication Chunk             August 2007
+
+
+   procedure does not work, because the restarting endpoint most likely
+   does not know the association shared key of the old association to be
+   restarted.  However, if the restarting endpoint does know the old
+   association shared key, he can successfully send the COOKIE-ECHO
+   chunk in a way that it is accepted by the peer by using this old
+   association shared key for the packet containing the AUTH chunk.
+   After this operation, both endpoints have to use the new association
+   shared key.
+
+   If a server has an endpoint pair shared key with some clients, it can
+   request the COOKIE_ECHO chunk to be authenticated and can ensure that
+   only associations from clients with a correct endpoint pair shared
+   key are accepted.
+
+   Furthermore, it is important that the cookie contained in an INIT-ACK
+   chunk and in a COOKIE-ECHO chunk MUST NOT contain any endpoint pair
+   shared keys.
+
+7.  Examples
+
+   This section gives examples of message exchanges for association
+   setup.
+
+   The simplest way of using the extension described in this document is
+   given by the following message exchange.
+
+       ---------- INIT[RANDOM; CHUNKS; HMAC-ALGO] ---------->
+       <------- INIT-ACK[RANDOM; CHUNKS; HMAC-ALGO] ---------
+       -------------------- COOKIE-ECHO -------------------->
+       <-------------------- COOKIE-ACK ---------------------
+
+   Please note that the CHUNKS parameter is optional in the INIT and
+   INIT-ACK.
+
+   If the server wants to receive DATA chunks in an authenticated way,
+   the following message exchange is possible:
+
+       ---------- INIT[RANDOM; CHUNKS; HMAC-ALGO] ---------->
+       <------- INIT-ACK[RANDOM; CHUNKS; HMAC-ALGO] ---------
+       --------------- COOKIE-ECHO; AUTH; DATA ------------->
+       <----------------- COOKIE-ACK; SACK ------------------
+
+   Please note that if the endpoint pair shared key depends on the
+   client and the server, and is only known by the upper layer, this
+   message exchange requires an upper layer intervention between the
+   processing of the COOKIE-ECHO chunk and the processing of the AUTH
+   and DATA chunk at the server side.  This intervention may be realized
+   by a COMMUNICATION-UP notification followed by the presentation of
+
+
+
+Tuexen, et al.              Standards Track                    [Page 14]
+
+RFC 4895               SCTP Authentication Chunk             August 2007
+
+
+   the endpoint pair shared key by the upper layer to the SCTP stack,
+   see for example Section 10 of RFC 2960 [5].  If this intervention is
+   not possible due to limitations of the API (for example, the socket
+   API), the server might discard the AUTH and DATA chunk, making a
+   retransmission of the DATA chunk necessary.  If the same endpoint
+   pair shared key is used for multiple endpoints and does not depend on
+   the client, this intervention might not be necessary.
+
+8.  IANA Considerations
+
+   This document (RFC 4895) is the reference for all registrations
+   described in this section.  All registrations need to be listed in
+   the document available at SCTP-parameters [9].  The changes are
+   described below.
+
+8.1.  A New Chunk Type
+
+   A chunk type for the AUTH chunk has been assigned by IANA.  IANA has
+   assigned the value (15), as given in Table 4.  An additional line has
+   been added in the "CHUNK TYPES" table of SCTP-parameters [9]:
+
+   CHUNK TYPES
+
+   ID Value    Chunk Type                                     Reference
+   -----       ----------                                     ---------
+   15          Authentication Chunk (AUTH)                    [RFC4895]
+
+8.2.  Three New Parameter Types
+
+   Parameter types have been assigned for the RANDOM, CHUNKS, and HMAC-
+   ALGO parameter by IANA.  The values are as given in Table 1.  This
+   required two modifications to the "CHUNK PARAMETER TYPES" tables in
+   SCTP-parameters [9]: the first is the addition of three new lines to
+   the "INIT Chunk Parameter Types" table:
+
+   Chunk Parameter Type                       Value
+   --------------------                       -----
+   Random                             32770 (0x8002)
+   Chunk List                         32771 (0x8003)
+   Requested HMAC Algorithm Parameter 32772 (0x8004)
+
+   The second required change is the addition of the same three lines to
+   the to the "INIT ACK Chunk Parameter Types" table.
+
+8.3.  A New Error Cause
+
+   An error cause for the Unsupported HMAC Identifier error cause has
+   been assigned.  The value (261) has been assigned as in Table 3.
+
+
+
+Tuexen, et al.              Standards Track                    [Page 15]
+
+RFC 4895               SCTP Authentication Chunk             August 2007
+
+
+   This requires an additional line of the "CAUSE CODES" table in SCTP-
+   parameters [9]:
+
+   VALUE            CAUSE CODE                               REFERENCE
+   -----            ----------------                         ---------
+   261 (0x0105)     Unsupported HMAC Identifier              [RFC4895]
+
+8.4.  A New Table for HMAC Identifiers
+
+   HMAC Identifiers have to be maintained by IANA.  Four initial values
+   have been assigned by IANA as described in Table 2.  This required a
+   new table "HMAC IDENTIFIERS" in SCTP-parameters [9]:
+
+   HMAC Identifier      Message Digest Algorithm             REFERENCE
+   ---------------      ------------------------             ---------
+   0                    Reserved                             [RFC4895]
+   1                    SHA-1                                [RFC4895]
+   2                    Reserved                             [RFC4895]
+   3                    SHA-256                              [RFC4895]
+
+   For registering a new HMAC Identifier with IANA, in this table, a
+   request has to be made to assign such a number.  This number must be
+   unique and a message digest algorithm usable with the HMAC defined in
+   RFC 2104 [2] MUST be specified.  The "Specification Required" policy
+   of RFC 2434 [4] MUST be applied.
+
+9.  Security Considerations
+
+   Without using endpoint shared keys, this extension only protects
+   against modification or injection of authenticated chunks by
+   attackers who did not capture the initial handshake setting up the
+   SCTP association.
+
+   If an endpoint pair shared key is used, even a true man in the middle
+   cannot inject chunks, which are required to be authenticated, even if
+   he intercepts the initial message exchange.  The endpoint also knows
+   that it is accepting authenticated chunks from a peer who knows the
+   endpoint pair shared key.
+
+   The establishment of endpoint pair shared keys is out of the scope of
+   this document.  Other mechanisms can be used, like using TLS or
+   manual configuration.
+
+   When an endpoint accepts COOKIE-ECHO chunks only in an authenticated
+   way the restart procedure does not work.  Neither an attacker nor a
+   restarted endpoint not knowing the association shared key can perform
+   an restart.  However, if the association shared key is known, it is
+   possible to restart the association.
+
+
+
+Tuexen, et al.              Standards Track                    [Page 16]
+
+RFC 4895               SCTP Authentication Chunk             August 2007
+
+
+   Because SCTP already has a built-in mechanism that handles the
+   reception of duplicated chunks, the presented solution makes use of
+   this functionality and does not provide a method to avoid replay
+   attacks by itself.  Of course, this only works within each SCTP
+   association.  Therefore, a separate shared key is used for each SCTP
+   association to handle replay attacks covering multiple SCTP
+   associations.
+
+   Each endpoint presenting a list of more than one element in the HMAC-
+   ALGO parameter must be prepared for the peer using the weakest
+   algorithm listed.
+
+   When an endpoint pair uses non-NULL endpoint pair shared keys and one
+   of the endpoints still accepts a NULL key, an attacker who captured
+   the initial handshake can still inject or modify authenticated chunks
+   by using the NULL key.
+
+10.  Acknowledgments
+
+   The authors wish to thank David Black, Sascha Grau, Russ Housley,
+   Ivan Arias Rodriguez, Irene Ruengeler, and Magnus Westerlund for
+   their invaluable comments.
+
+11.  Normative References
+
+   [1]  Rivest, R., "The MD5 Message-Digest Algorithm", RFC 1321,
+        April 1992.
+
+   [2]  Krawczyk, H., Bellare, M., and R. Canetti, "HMAC: Keyed-Hashing
+        for Message Authentication", RFC 2104, February 1997.
+
+   [3]  Bradner, S., "Key words for use in RFCs to Indicate Requirement
+        Levels", BCP 14, RFC 2119, March 1997.
+
+   [4]  Narten, T. and H. Alvestrand, "Guidelines for Writing an IANA
+        Considerations Section in RFCs", BCP 26, RFC 2434, October 1998.
+
+   [5]  Stewart, R., Xie, Q., Morneault, K., Sharp, C., Schwarzbauer,
+        H., Taylor, T., Rytina, I., Kalla, M., Zhang, L., and V. Paxson,
+        "Stream Control Transmission Protocol", RFC 2960, October 2000.
+
+   [6]  Jungmaier, A., Rescorla, E., and M. Tuexen, "Transport Layer
+        Security over Stream Control Transmission Protocol", RFC 3436,
+        December 2002.
+
+   [7]  Eastlake, D., Schiller, J., and S. Crocker, "Randomness
+        Requirements for Security", BCP 106, RFC 4086, June 2005.
+
+
+
+
+Tuexen, et al.              Standards Track                    [Page 17]
+
+RFC 4895               SCTP Authentication Chunk             August 2007
+
+
+   [8]  National Institute of Standards and Technology, "Secure Hash
+        Standard", FIPS PUB 180-2, August 2002,
+        <http://csrc.nist.gov/publications/fips/fips180-2/
+        fips180-2.pdf>.
+
+   [9]  <http://www.iana.org/assignments/sctp-parameters>
+
+Authors' Addresses
+
+   Michael Tuexen
+   Muenster Univ. of Applied Sciences
+   Stegerwaldstr. 39
+   48565 Steinfurt
+   Germany
+
+   EMail: tuexen@fh-muenster.de
+
+
+   Randall R. Stewart
+   Cisco Systems, Inc.
+   4875 Forest Drive
+   Suite 200
+   Columbia, SC  29206
+   USA
+
+   EMail: rrs@cisco.com
+
+
+   Peter Lei
+   Cisco Systems, Inc.
+   8735 West Higgins Road
+   Suite 300
+   Chicago, IL  60631
+   USA
+
+   Phone:
+   EMail: peterlei@cisco.com
+
+
+   Eric Rescorla
+   RTFM, Inc.
+   2064 Edgewood Drive
+   Palo Alto, CA 94303
+   USA
+
+   Phone: +1 650-320-8549
+   EMail: ekr@rtfm.com
+
+
+
+
+Tuexen, et al.              Standards Track                    [Page 18]
+
+RFC 4895               SCTP Authentication Chunk             August 2007
+
+
+Full Copyright Statement
+
+   Copyright (C) The IETF Trust (2007).
+
+   This document is subject to the rights, licenses and restrictions
+   contained in BCP 78, and except as set forth therein, the authors
+   retain all their rights.
+
+   This document and the information contained herein are provided on an
+   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
+   OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND
+   THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
+   THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
+   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Intellectual Property
+
+   The IETF takes no position regarding the validity or scope of any
+   Intellectual Property Rights or other rights that might be claimed to
+   pertain to the implementation or use of the technology described in
+   this document or the extent to which any license under such rights
+   might or might not be available; nor does it represent that it has
+   made any independent effort to identify any such rights.  Information
+   on the procedures with respect to rights in RFC documents can be
+   found in BCP 78 and BCP 79.
+
+   Copies of IPR disclosures made to the IETF Secretariat and any
+   assurances of licenses to be made available, or the result of an
+   attempt made to obtain a general license or permission for the use of
+   such proprietary rights by implementers or users of this
+   specification can be obtained from the IETF on-line IPR repository at
+   http://www.ietf.org/ipr.
+
+   The IETF invites any interested party to bring to its attention any
+   copyrights, patents or patent applications, or other proprietary
+   rights that may cover technology that may be required to implement
+   this standard.  Please address the information to the IETF at
+   ietf-ipr@ietf.org.
+
+
+
+
+
+
+
+
+
+
+
+
+Tuexen, et al.              Standards Track                    [Page 19]
+
diff --git a/doc/rfc4960.txt b/doc/rfc4960.txt
new file mode 100644
index 0000000..1c4f9e9
--- /dev/null
+++ b/doc/rfc4960.txt
@@ -0,0 +1,8515 @@
+
+
+
+
+
+
+Network Working Group                                    R. Stewart, Ed.
+Request for Comments: 4960                                September 2007
+Obsoletes: 2960, 3309
+Category: Standards Track
+
+
+                  Stream Control Transmission Protocol
+
+Status of This Memo
+
+   This document specifies an Internet standards track protocol for the
+   Internet community, and requests discussion and suggestions for
+   improvements.  Please refer to the current edition of the "Internet
+   Official Protocol Standards" (STD 1) for the standardization state
+   and status of this protocol.  Distribution of this memo is unlimited.
+
+Abstract
+
+   This document obsoletes RFC 2960 and RFC 3309.  It describes the
+   Stream Control Transmission Protocol (SCTP).  SCTP is designed to
+   transport Public Switched Telephone Network (PSTN) signaling messages
+   over IP networks, but is capable of broader applications.
+
+   SCTP is a reliable transport protocol operating on top of a
+   connectionless packet network such as IP.  It offers the following
+   services to its users:
+
+   --  acknowledged error-free non-duplicated transfer of user data,
+
+   --  data fragmentation to conform to discovered path MTU size,
+
+   --  sequenced delivery of user messages within multiple streams, with
+       an option for order-of-arrival delivery of individual user
+       messages,
+
+   --  optional bundling of multiple user messages into a single SCTP
+       packet, and
+
+   --  network-level fault tolerance through supporting of multi-homing
+       at either or both ends of an association.
+
+   The design of SCTP includes appropriate congestion avoidance behavior
+   and resistance to flooding and masquerade attacks.
+
+
+
+
+
+
+
+
+Stewart                     Standards Track                     [Page 1]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+Table of Contents
+
+   1. Introduction ....................................................5
+      1.1. Motivation .................................................5
+      1.2. Architectural View of SCTP .................................6
+      1.3. Key Terms ..................................................6
+      1.4. Abbreviations .............................................10
+      1.5. Functional View of SCTP ...................................10
+           1.5.1. Association Startup and Takedown ...................11
+           1.5.2. Sequenced Delivery within Streams ..................12
+           1.5.3. User Data Fragmentation ............................12
+           1.5.4. Acknowledgement and Congestion Avoidance ...........12
+           1.5.5. Chunk Bundling .....................................13
+           1.5.6. Packet Validation ..................................13
+           1.5.7. Path Management ....................................13
+      1.6. Serial Number Arithmetic ..................................14
+      1.7. Changes from RFC 2960 .....................................15
+   2. Conventions ....................................................15
+   3. SCTP Packet Format .............................................15
+      3.1. SCTP Common Header Field Descriptions .....................16
+      3.2. Chunk Field Descriptions ..................................17
+           3.2.1. Optional/Variable-Length Parameter Format ..........19
+           3.2.2. Reporting of Unrecognized Parameters ...............21
+      3.3. SCTP Chunk Definitions ....................................21
+           3.3.1. Payload Data (DATA) (0) ............................22
+           3.3.2. Initiation (INIT) (1) ..............................24
+                  3.3.2.1. Optional/Variable-Length
+                           Parameters in INIT ........................27
+           3.3.3. Initiation Acknowledgement (INIT ACK) (2) ..........30
+                  3.3.3.1. Optional or Variable-Length Parameters ....33
+           3.3.4. Selective Acknowledgement (SACK) (3) ...............34
+           3.3.5. Heartbeat Request (HEARTBEAT) (4) ..................38
+           3.3.6. Heartbeat Acknowledgement (HEARTBEAT ACK) (5) ......39
+           3.3.7. Abort Association (ABORT) (6) ......................40
+           3.3.8. Shutdown Association (SHUTDOWN) (7) ................41
+           3.3.9. Shutdown Acknowledgement (SHUTDOWN ACK) (8) ........41
+           3.3.10. Operation Error (ERROR) (9) .......................42
+                  3.3.10.1. Invalid Stream Identifier (1) ............44
+                  3.3.10.2. Missing Mandatory Parameter (2) ..........44
+                  3.3.10.3. Stale Cookie Error (3) ...................45
+                  3.3.10.4. Out of Resource (4) ......................45
+                  3.3.10.5. Unresolvable Address (5) .................46
+                  3.3.10.6. Unrecognized Chunk Type (6) ..............46
+                  3.3.10.7. Invalid Mandatory Parameter (7) ..........47
+                  3.3.10.8. Unrecognized Parameters (8) ..............47
+                  3.3.10.9. No User Data (9) .........................48
+                  3.3.10.10. Cookie Received While Shutting
+                             Down (10) ...............................48
+
+
+
+Stewart                     Standards Track                     [Page 2]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+                  3.3.10.11. Restart of an Association with
+                             New Addresses (11) ......................49
+                  3.3.10.12. User-Initiated Abort (12) ...............49
+                  3.3.10.13. Protocol Violation (13) .................50
+           3.3.11. Cookie Echo (COOKIE ECHO) (10) ....................50
+           3.3.12. Cookie Acknowledgement (COOKIE ACK) (11) ..........51
+           3.3.13. Shutdown Complete (SHUTDOWN COMPLETE) (14) ........51
+   4. SCTP Association State Diagram .................................52
+   5. Association Initialization .....................................56
+      5.1. Normal Establishment of an Association ....................56
+           5.1.1. Handle Stream Parameters ...........................58
+           5.1.2. Handle Address Parameters ..........................58
+           5.1.3. Generating State Cookie ............................61
+           5.1.4. State Cookie Processing ............................62
+           5.1.5. State Cookie Authentication ........................62
+           5.1.6. An Example of Normal Association Establishment .....64
+      5.2. Handle Duplicate or Unexpected INIT, INIT ACK,
+           COOKIE ECHO, and ..........................................65
+           5.2.1. INIT Received in COOKIE-WAIT or
+                  COOKIE-ECHOED State (Item B) .......................66
+           5.2.2. Unexpected INIT in States Other than
+                  CLOSED, COOKIE-ECHOED, .............................66
+           5.2.3. Unexpected INIT ACK ................................67
+           5.2.4. Handle a COOKIE ECHO when a TCB Exists .............67
+                  5.2.4.1. An Example of a Association Restart .......69
+           5.2.5. Handle Duplicate COOKIE-ACK. .......................71
+           5.2.6. Handle Stale COOKIE Error ..........................71
+      5.3. Other Initialization Issues ...............................72
+           5.3.1. Selection of Tag Value .............................72
+      5.4. Path Verification .........................................72
+   6. User Data Transfer .............................................73
+      6.1. Transmission of DATA Chunks ...............................75
+      6.2. Acknowledgement on Reception of DATA Chunks ...............78
+           6.2.1. Processing a Received SACK .........................81
+      6.3. Management of Retransmission Timer ........................83
+           6.3.1. RTO Calculation ....................................83
+           6.3.2. Retransmission Timer Rules .........................85
+           6.3.3. Handle T3-rtx Expiration ...........................86
+      6.4. Multi-Homed SCTP Endpoints ................................87
+           6.4.1. Failover from an Inactive Destination Address ......88
+      6.5. Stream Identifier and Stream Sequence Number ..............88
+      6.6. Ordered and Unordered Delivery ............................88
+      6.7. Report Gaps in Received DATA TSNs .........................89
+      6.8. CRC32c Checksum Calculation ...............................90
+      6.9. Fragmentation and Reassembly ..............................91
+      6.10. Bundling .................................................92
+   7. Congestion Control .............................................93
+      7.1. SCTP Differences from TCP Congestion Control ..............94
+
+
+
+Stewart                     Standards Track                     [Page 3]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+      7.2. SCTP Slow-Start and Congestion Avoidance ..................95
+           7.2.1. Slow-Start .........................................96
+           7.2.2. Congestion Avoidance ...............................97
+           7.2.3. Congestion Control .................................98
+           7.2.4. Fast Retransmit on Gap Reports .....................98
+      7.3. Path MTU Discovery .......................................100
+   8. Fault Management ..............................................100
+      8.1. Endpoint Failure Detection ...............................100
+      8.2. Path Failure Detection ...................................101
+      8.3. Path Heartbeat ...........................................102
+      8.4. Handle "Out of the Blue" Packets .........................104
+      8.5. Verification Tag .........................................105
+           8.5.1. Exceptions in Verification Tag Rules ..............105
+   9. Termination of Association ....................................106
+      9.1. Abort of an Association ..................................107
+      9.2. Shutdown of an Association ...............................107
+   10. Interface with Upper Layer ...................................110
+      10.1. ULP-to-SCTP .............................................110
+      10.2. SCTP-to-ULP .............................................120
+   11. Security Considerations ......................................123
+      11.1. Security Objectives .....................................123
+      11.2. SCTP Responses to Potential Threats .....................124
+           11.2.1. Countering Insider Attacks .......................124
+           11.2.2. Protecting against Data Corruption in the
+                   Network ..........................................124
+           11.2.3. Protecting Confidentiality .......................124
+           11.2.4. Protecting against Blind
+                   Denial-of-Service Attacks ........................125
+                  11.2.4.1. Flooding ................................125
+                  11.2.4.2. Blind Masquerade ........................126
+                  11.2.4.3. Improper Monopolization of Services .....127
+      11.3. SCTP Interactions with Firewalls ........................127
+      11.4. Protection of Non-SCTP-Capable Hosts ....................128
+   12. Network Management Considerations ............................128
+   13. Recommended Transmission Control Block (TCB) Parameters ......129
+      13.1. Parameters Necessary for the SCTP Instance ..............129
+      13.2. Parameters Necessary per Association (i.e., the TCB) ....129
+      13.3. Per Transport Address Data ..............................131
+      13.4. General Parameters Needed ...............................132
+   14. IANA Considerations ..........................................132
+      14.1. IETF-defined Chunk Extension ............................132
+      14.2. IETF-Defined Chunk Parameter Extension ..................133
+      14.3. IETF-Defined Additional Error Causes ....................133
+      14.4. Payload Protocol Identifiers ............................134
+      14.5. Port Numbers Registry ...................................134
+   15. Suggested SCTP Protocol Parameter Values .....................136
+   16. Acknowledgements .............................................137
+   Appendix A. Explicit Congestion Notification .....................139
+
+
+
+Stewart                     Standards Track                     [Page 4]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   Appendix B. CRC32c Checksum Calculation ..........................140
+   Appendix C. ICMP Handling ........................................142
+   References .......................................................149
+      Normative References ..........................................149
+      Informative References ........................................150
+
+1.  Introduction
+
+   This section explains the reasoning behind the development of the
+   Stream Control Transmission Protocol (SCTP), the services it offers,
+   and the basic concepts needed to understand the detailed description
+   of the protocol.
+
+   This document obsoletes [RFC2960] and [RFC3309].
+
+1.1.  Motivation
+
+   TCP [RFC0793] has performed immense service as the primary means of
+   reliable data transfer in IP networks.  However, an increasing number
+   of recent applications have found TCP too limiting, and have
+   incorporated their own reliable data transfer protocol on top of UDP
+   [RFC0768].  The limitations that users have wished to bypass include
+   the following:
+
+   -- TCP provides both reliable data transfer and strict order-of-
+      transmission delivery of data.  Some applications need reliable
+      transfer without sequence maintenance, while others would be
+      satisfied with partial ordering of the data.  In both of these
+      cases, the head-of-line blocking offered by TCP causes unnecessary
+      delay.
+
+   -- The stream-oriented nature of TCP is often an inconvenience.
+      Applications must add their own record marking to delineate their
+      messages, and must make explicit use of the push facility to
+      ensure that a complete message is transferred in a reasonable
+      time.
+
+   -- The limited scope of TCP sockets complicates the task of providing
+      highly-available data transfer capability using multi-homed hosts.
+
+   -- TCP is relatively vulnerable to denial-of-service attacks, such as
+      SYN attacks.
+
+   Transport of PSTN signaling across the IP network is an application
+   for which all of these limitations of TCP are relevant.  While this
+   application directly motivated the development of SCTP, other
+   applications may find SCTP a good match to their requirements.
+
+
+
+
+Stewart                     Standards Track                     [Page 5]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+1.2.  Architectural View of SCTP
+
+   SCTP is viewed as a layer between the SCTP user application ("SCTP
+   user" for short) and a connectionless packet network service such as
+   IP.  The remainder of this document assumes SCTP runs on top of IP.
+   The basic service offered by SCTP is the reliable transfer of user
+   messages between peer SCTP users.  It performs this service within
+   the context of an association between two SCTP endpoints.  Section 10
+   of this document sketches the API that should exist at the boundary
+   between the SCTP and the SCTP user layers.
+
+   SCTP is connection-oriented in nature, but the SCTP association is a
+   broader concept than the TCP connection.  SCTP provides the means for
+   each SCTP endpoint (Section 1.3) to provide the other endpoint
+   (during association startup) with a list of transport addresses
+   (i.e., multiple IP addresses in combination with an SCTP port)
+   through which that endpoint can be reached and from which it will
+   originate SCTP packets.  The association spans transfers over all of
+   the possible source/destination combinations that may be generated
+   from each endpoint's lists.
+
+       _____________                                      _____________
+      |  SCTP User  |                                    |  SCTP User  |
+      | Application |                                    | Application |
+      |-------------|                                    |-------------|
+      |    SCTP     |                                    |    SCTP     |
+      |  Transport  |                                    |  Transport  |
+      |   Service   |                                    |   Service   |
+      |-------------|                                    |-------------|
+      |             |One or more    ----      One or more|             |
+      | IP Network  |IP address      \/        IP address| IP Network  |
+      |   Service   |appearances     /\       appearances|   Service   |
+      |_____________|               ----                 |_____________|
+
+        SCTP Node A |<-------- Network transport ------->| SCTP Node B
+
+                         Figure 1: An SCTP Association
+
+1.3.  Key Terms
+
+   Some of the language used to describe SCTP has been introduced in the
+   previous sections.  This section provides a consolidated list of the
+   key terms and their definitions.
+
+   o  Active destination transport address: A transport address on a
+      peer endpoint that a transmitting endpoint considers available for
+      receiving user messages.
+
+
+
+
+Stewart                     Standards Track                     [Page 6]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   o  Bundling: An optional multiplexing operation, whereby more than
+      one user message may be carried in the same SCTP packet.  Each
+      user message occupies its own DATA chunk.
+
+   o  Chunk: A unit of information within an SCTP packet, consisting of
+      a chunk header and chunk-specific content.
+
+   o  Congestion window (cwnd): An SCTP variable that limits the data,
+      in number of bytes, a sender can send to a particular destination
+      transport address before receiving an acknowledgement.
+
+   o  Cumulative TSN Ack Point: The TSN of the last DATA chunk
+      acknowledged via the Cumulative TSN Ack field of a SACK.
+
+   o  Idle destination address: An address that has not had user
+      messages sent to it within some length of time, normally the
+      HEARTBEAT interval or greater.
+
+   o  Inactive destination transport address: An address that is
+      considered inactive due to errors and unavailable to transport
+      user messages.
+
+   o  Message = user message: Data submitted to SCTP by the Upper Layer
+      Protocol (ULP).
+
+   o  Message Authentication Code (MAC): An integrity check mechanism
+      based on cryptographic hash functions using a secret key.
+      Typically, message authentication codes are used between two
+      parties that share a secret key in order to validate information
+      transmitted between these parties.  In SCTP, it is used by an
+      endpoint to validate the State Cookie information that is returned
+      from the peer in the COOKIE ECHO chunk.  The term "MAC" has
+      different meanings in different contexts.  SCTP uses this term
+      with the same meaning as in [RFC2104].
+
+   o  Network Byte Order: Most significant byte first, a.k.a., big
+      endian.
+
+   o  Ordered Message: A user message that is delivered in order with
+      respect to all previous user messages sent within the stream on
+      which the message was sent.
+
+   o  Outstanding TSN (at an SCTP endpoint): A TSN (and the associated
+      DATA chunk) that has been sent by the endpoint but for which it
+      has not yet received an acknowledgement.
+
+
+
+
+
+
+Stewart                     Standards Track                     [Page 7]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   o  Path: The route taken by the SCTP packets sent by one SCTP
+      endpoint to a specific destination transport address of its peer
+      SCTP endpoint.  Sending to different destination transport
+      addresses does not necessarily guarantee getting separate paths.
+
+   o  Primary Path: The primary path is the destination and source
+      address that will be put into a packet outbound to the peer
+      endpoint by default.  The definition includes the source address
+      since an implementation MAY wish to specify both destination and
+      source address to better control the return path taken by reply
+      chunks and on which interface the packet is transmitted when the
+      data sender is multi-homed.
+
+   o  Receiver Window (rwnd): An SCTP variable a data sender uses to
+      store the most recently calculated receiver window of its peer, in
+      number of bytes.  This gives the sender an indication of the space
+      available in the receiver's inbound buffer.
+
+   o  SCTP association: A protocol relationship between SCTP endpoints,
+      composed of the two SCTP endpoints and protocol state information
+      including Verification Tags and the currently active set of
+      Transmission Sequence Numbers (TSNs), etc.  An association can be
+      uniquely identified by the transport addresses used by the
+      endpoints in the association.  Two SCTP endpoints MUST NOT have
+      more than one SCTP association between them at any given time.
+
+   o  SCTP endpoint: The logical sender/receiver of SCTP packets.  On a
+      multi-homed host, an SCTP endpoint is represented to its peers as
+      a combination of a set of eligible destination transport addresses
+      to which SCTP packets can be sent and a set of eligible source
+      transport addresses from which SCTP packets can be received.  All
+      transport addresses used by an SCTP endpoint must use the same
+      port number, but can use multiple IP addresses.  A transport
+      address used by an SCTP endpoint must not be used by another SCTP
+      endpoint.  In other words, a transport address is unique to an
+      SCTP endpoint.
+
+   o  SCTP packet (or packet): The unit of data delivery across the
+      interface between SCTP and the connectionless packet network
+      (e.g., IP).  An SCTP packet includes the common SCTP header,
+      possible SCTP control chunks, and user data encapsulated within
+      SCTP DATA chunks.
+
+   o  SCTP user application (SCTP user): The logical higher-layer
+      application entity which uses the services of SCTP, also called
+      the Upper-Layer Protocol (ULP).
+
+
+
+
+
+Stewart                     Standards Track                     [Page 8]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   o  Slow-Start Threshold (ssthresh): An SCTP variable.  This is the
+      threshold that the endpoint will use to determine whether to
+      perform slow start or congestion avoidance on a particular
+      destination transport address.  Ssthresh is in number of bytes.
+
+   o  Stream: A unidirectional logical channel established from one to
+      another associated SCTP endpoint, within which all user messages
+      are delivered in sequence except for those submitted to the
+      unordered delivery service.
+
+   Note: The relationship between stream numbers in opposite directions
+   is strictly a matter of how the applications use them.  It is the
+   responsibility of the SCTP user to create and manage these
+   correlations if they are so desired.
+
+   o  Stream Sequence Number: A 16-bit sequence number used internally
+      by SCTP to ensure sequenced delivery of the user messages within a
+      given stream.  One Stream Sequence Number is attached to each user
+      message.
+
+   o  Tie-Tags: Two 32-bit random numbers that together make a 64-bit
+      nonce.  These tags are used within a State Cookie and TCB so that
+      a newly restarting association can be linked to the original
+      association within the endpoint that did not restart and yet not
+      reveal the true Verification Tags of an existing association.
+
+   o  Transmission Control Block (TCB): An internal data structure
+      created by an SCTP endpoint for each of its existing SCTP
+      associations to other SCTP endpoints.  TCB contains all the status
+      and operational information for the endpoint to maintain and
+      manage the corresponding association.
+
+   o  Transmission Sequence Number (TSN): A 32-bit sequence number used
+      internally by SCTP.  One TSN is attached to each chunk containing
+      user data to permit the receiving SCTP endpoint to acknowledge its
+      receipt and detect duplicate deliveries.
+
+   o  Transport address: A transport address is traditionally defined by
+      a network-layer address, a transport-layer protocol, and a
+      transport-layer port number.  In the case of SCTP running over IP,
+      a transport address is defined by the combination of an IP address
+      and an SCTP port number (where SCTP is the transport protocol).
+
+   o  Unacknowledged TSN (at an SCTP endpoint): A TSN (and the
+      associated DATA chunk) that has been received by the endpoint but
+      for which an acknowledgement has not yet been sent.  Or in the
+      opposite case, for a packet that has been sent but no
+      acknowledgement has been received.
+
+
+
+Stewart                     Standards Track                     [Page 9]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   o  Unordered Message: Unordered messages are "unordered" with respect
+      to any other message; this includes both other unordered messages
+      as well as other ordered messages.  An unordered message might be
+      delivered prior to or later than ordered messages sent on the same
+      stream.
+
+   o  User message: The unit of data delivery across the interface
+      between SCTP and its user.
+
+   o  Verification Tag: A 32-bit unsigned integer that is randomly
+      generated.  The Verification Tag provides a key that allows a
+      receiver to verify that the SCTP packet belongs to the current
+      association and is not an old or stale packet from a previous
+      association.
+
+1.4.  Abbreviations
+
+   MAC    -  Message Authentication Code [RFC2104]
+
+   RTO    -  Retransmission Timeout
+
+   RTT    -  Round-Trip Time
+
+   RTTVAR -  Round-Trip Time Variation
+
+   SCTP   -  Stream Control Transmission Protocol
+
+   SRTT   -  Smoothed RTT
+
+   TCB    -  Transmission Control Block
+
+   TLV    -  Type-Length-Value coding format
+
+   TSN    -  Transmission Sequence Number
+
+   ULP    -  Upper-Layer Protocol
+
+1.5.  Functional View of SCTP
+
+   The SCTP transport service can be decomposed into a number of
+   functions.  These are depicted in Figure 2 and explained in the
+   remainder of this section.
+
+
+
+
+
+
+
+
+
+Stewart                     Standards Track                    [Page 10]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+                           SCTP User Application
+
+            -----------------------------------------------------
+             _____________                  ____________________
+            |             |                | Sequenced Delivery |
+            | Association |                |   within Streams   |
+            |             |                |____________________|
+            |   Startup   |
+            |             |         ____________________________
+            |     and     |        |    User Data Fragmentation |
+            |             |        |____________________________|
+            |   Takedown  |
+            |             |         ____________________________
+            |             |        |     Acknowledgement        |
+            |             |        |          and               |
+            |             |        |    Congestion Avoidance    |
+            |             |        |____________________________|
+            |             |
+            |             |         ____________________________
+            |             |        |       Chunk Bundling       |
+            |             |        |____________________________|
+            |             |
+            |             |     ________________________________
+            |             |    |      Packet Validation         |
+            |             |    |________________________________|
+            |             |
+            |             |     ________________________________
+            |             |    |     Path Management            |
+            |_____________|    |________________________________|
+
+              Figure 2: Functional View of the SCTP Transport Service
+
+1.5.1.  Association Startup and Takedown
+
+   An association is initiated by a request from the SCTP user (see the
+   description of the ASSOCIATE (or SEND) primitive in Section 10).
+
+   A cookie mechanism, similar to one described by Karn and Simpson in
+   [RFC2522], is employed during the initialization to provide
+   protection against synchronization attacks.  The cookie mechanism
+   uses a four-way handshake, the last two legs of which are allowed to
+   carry user data for fast setup.  The startup sequence is described in
+   Section 5 of this document.
+
+   SCTP provides for graceful close (i.e., shutdown) of an active
+   association on request from the SCTP user.  See the description of
+   the SHUTDOWN primitive in Section 10.  SCTP also allows ungraceful
+   close (i.e., abort), either on request from the user (ABORT
+
+
+
+Stewart                     Standards Track                    [Page 11]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   primitive) or as a result of an error condition detected within the
+   SCTP layer.  Section 9 describes both the graceful and the ungraceful
+   close procedures.
+
+   SCTP does not support a half-open state (like TCP) wherein one side
+   may continue sending data while the other end is closed.  When either
+   endpoint performs a shutdown, the association on each peer will stop
+   accepting new data from its user and only deliver data in queue at
+   the time of the graceful close (see Section 9).
+
+1.5.2.  Sequenced Delivery within Streams
+
+   The term "stream" is used in SCTP to refer to a sequence of user
+   messages that are to be delivered to the upper-layer protocol in
+   order with respect to other messages within the same stream.  This is
+   in contrast to its usage in TCP, where it refers to a sequence of
+   bytes (in this document, a byte is assumed to be 8 bits).
+
+   The SCTP user can specify at association startup time the number of
+   streams to be supported by the association.  This number is
+   negotiated with the remote end (see Section 5.1.1).  User messages
+   are associated with stream numbers (SEND, RECEIVE primitives, Section
+   10).  Internally, SCTP assigns a Stream Sequence Number to each
+   message passed to it by the SCTP user.  On the receiving side, SCTP
+   ensures that messages are delivered to the SCTP user in sequence
+   within a given stream.  However, while one stream may be blocked
+   waiting for the next in-sequence user message, delivery from other
+   streams may proceed.
+
+   SCTP provides a mechanism for bypassing the sequenced delivery
+   service.  User messages sent using this mechanism are delivered to
+   the SCTP user as soon as they are received.
+
+1.5.3.  User Data Fragmentation
+
+   When needed, SCTP fragments user messages to ensure that the SCTP
+   packet passed to the lower layer conforms to the path MTU.  On
+   receipt, fragments are reassembled into complete messages before
+   being passed to the SCTP user.
+
+1.5.4.  Acknowledgement and Congestion Avoidance
+
+   SCTP assigns a Transmission Sequence Number (TSN) to each user data
+   fragment or unfragmented message.  The TSN is independent of any
+   Stream Sequence Number assigned at the stream level.  The receiving
+   end acknowledges all TSNs received, even if there are gaps in the
+   sequence.  In this way, reliable delivery is kept functionally
+   separate from sequenced stream delivery.
+
+
+
+Stewart                     Standards Track                    [Page 12]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   The acknowledgement and congestion avoidance function is responsible
+   for packet retransmission when timely acknowledgement has not been
+   received.  Packet retransmission is conditioned by congestion
+   avoidance procedures similar to those used for TCP.  See Section 6
+   and Section 7 for a detailed description of the protocol procedures
+   associated with this function.
+
+1.5.5.  Chunk Bundling
+
+   As described in Section 3, the SCTP packet as delivered to the lower
+   layer consists of a common header followed by one or more chunks.
+   Each chunk may contain either user data or SCTP control information.
+   The SCTP user has the option to request bundling of more than one
+   user message into a single SCTP packet.  The chunk bundling function
+   of SCTP is responsible for assembly of the complete SCTP packet and
+   its disassembly at the receiving end.
+
+   During times of congestion, an SCTP implementation MAY still perform
+   bundling even if the user has requested that SCTP not bundle.  The
+   user's disabling of bundling only affects SCTP implementations that
+   may delay a small period of time before transmission (to attempt to
+   encourage bundling).  When the user layer disables bundling, this
+   small delay is prohibited but not bundling that is performed during
+   congestion or retransmission.
+
+1.5.6.  Packet Validation
+
+   A mandatory Verification Tag field and a 32-bit checksum field (see
+   Appendix B for a description of the CRC32c checksum) are included in
+   the SCTP common header.  The Verification Tag value is chosen by each
+   end of the association during association startup.  Packets received
+   without the expected Verification Tag value are discarded, as a
+   protection against blind masquerade attacks and against stale SCTP
+   packets from a previous association.  The CRC32c checksum should be
+   set by the sender of each SCTP packet to provide additional
+   protection against data corruption in the network.  The receiver of
+   an SCTP packet with an invalid CRC32c checksum silently discards the
+   packet.
+
+1.5.7.  Path Management
+
+   The sending SCTP user is able to manipulate the set of transport
+   addresses used as destinations for SCTP packets through the
+   primitives described in Section 10.  The SCTP path management
+   function chooses the destination transport address for each outgoing
+   SCTP packet based on the SCTP user's instructions and the currently
+   perceived reachability status of the eligible destination set.  The
+   path management function monitors reachability through heartbeats
+
+
+
+Stewart                     Standards Track                    [Page 13]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   when other packet traffic is inadequate to provide this information
+   and advises the SCTP user when reachability of any far-end transport
+   address changes.  The path management function is also responsible
+   for reporting the eligible set of local transport addresses to the
+   far end during association startup, and for reporting the transport
+   addresses returned from the far end to the SCTP user.
+
+   At association startup, a primary path is defined for each SCTP
+   endpoint, and is used for normal sending of SCTP packets.
+
+   On the receiving end, the path management is responsible for
+   verifying the existence of a valid SCTP association to which the
+   inbound SCTP packet belongs before passing it for further processing.
+
+   Note: Path Management and Packet Validation are done at the same
+   time, so although described separately above, in reality they cannot
+   be performed as separate items.
+
+1.6.  Serial Number Arithmetic
+
+   It is essential to remember that the actual Transmission Sequence
+   Number space is finite, though very large.  This space ranges from 0
+   to 2**32 - 1.  Since the space is finite, all arithmetic dealing with
+   Transmission Sequence Numbers must be performed modulo 2**32.  This
+   unsigned arithmetic preserves the relationship of sequence numbers as
+   they cycle from 2**32 - 1 to 0 again.  There are some subtleties to
+   computer modulo arithmetic, so great care should be taken in
+   programming the comparison of such values.  When referring to TSNs,
+   the symbol "=<" means "less than or equal"(modulo 2**32).
+
+   Comparisons and arithmetic on TSNs in this document SHOULD use Serial
+   Number Arithmetic as defined in [RFC1982] where SERIAL_BITS = 32.
+
+   An endpoint SHOULD NOT transmit a DATA chunk with a TSN that is more
+   than 2**31 - 1 above the beginning TSN of its current send window.
+   Doing so will cause problems in comparing TSNs.
+
+   Transmission Sequence Numbers wrap around when they reach 2**32 - 1.
+   That is, the next TSN a DATA chunk MUST use after transmitting TSN =
+   2*32 - 1 is TSN = 0.
+
+   Any arithmetic done on Stream Sequence Numbers SHOULD use Serial
+   Number Arithmetic as defined in [RFC1982] where SERIAL_BITS = 16.
+   All other arithmetic and comparisons in this document use normal
+   arithmetic.
+
+
+
+
+
+
+Stewart                     Standards Track                    [Page 14]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+1.7.  Changes from RFC 2960
+
+   SCTP was originally defined in [RFC2960], which this document
+   obsoletes.  Readers interested in the details of the various changes
+   that this document incorporates are asked to consult [RFC4460].
+
+2.  Conventions
+
+   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
+   document are to be interpreted as described in RFC 2119 [RFC2119].
+
+3.  SCTP Packet Format
+
+   An SCTP packet is composed of a common header and chunks.  A chunk
+   contains either control information or user data.
+
+   The SCTP packet format is shown below:
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                        Common Header                          |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                          Chunk #1                             |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                           ...                                 |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                          Chunk #n                             |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   Multiple chunks can be bundled into one SCTP packet up to the MTU
+   size, except for the INIT, INIT ACK, and SHUTDOWN COMPLETE chunks.
+   These chunks MUST NOT be bundled with any other chunk in a packet.
+   See Section 6.10 for more details on chunk bundling.
+
+   If a user data message doesn't fit into one SCTP packet it can be
+   fragmented into multiple chunks using the procedure defined in
+   Section 6.9.
+
+   All integer fields in an SCTP packet MUST be transmitted in network
+   byte order, unless otherwise stated.
+
+
+
+
+
+
+
+
+
+Stewart                     Standards Track                    [Page 15]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+3.1.  SCTP Common Header Field Descriptions
+
+                       SCTP Common Header Format
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |     Source Port Number        |     Destination Port Number   |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                      Verification Tag                         |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                           Checksum                            |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   Source Port Number: 16 bits (unsigned integer)
+
+      This is the SCTP sender's port number.  It can be used by the
+      receiver in combination with the source IP address, the SCTP
+      destination port, and possibly the destination IP address to
+      identify the association to which this packet belongs.  The port
+      number 0 MUST NOT be used.
+
+   Destination Port Number: 16 bits (unsigned integer)
+
+      This is the SCTP port number to which this packet is destined.
+      The receiving host will use this port number to de-multiplex the
+      SCTP packet to the correct receiving endpoint/application.  The
+      port number 0 MUST NOT be used.
+
+   Verification Tag: 32 bits (unsigned integer)
+
+      The receiver of this packet uses the Verification Tag to validate
+      the sender of this SCTP packet.  On transmit, the value of this
+      Verification Tag MUST be set to the value of the Initiate Tag
+      received from the peer endpoint during the association
+      initialization, with the following exceptions:
+
+      -  A packet containing an INIT chunk MUST have a zero Verification
+            Tag.
+
+      -  A packet containing a SHUTDOWN COMPLETE chunk with the T bit
+         set MUST have the Verification Tag copied from the packet with
+         the SHUTDOWN ACK chunk.
+
+      -  A packet containing an ABORT chunk may have the verification
+         tag copied from the packet that caused the ABORT to be sent.
+         For details see Section 8.4 and Section 8.5.
+
+
+
+
+Stewart                     Standards Track                    [Page 16]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   An INIT chunk MUST be the only chunk in the SCTP packet carrying it.
+
+   Checksum: 32 bits (unsigned integer)
+
+      This field contains the checksum of this SCTP packet.  Its
+      calculation is discussed in Section 6.8.  SCTP uses the CRC32c
+      algorithm as described in Appendix B for calculating the checksum.
+
+3.2.  Chunk Field Descriptions
+
+   The figure below illustrates the field format for the chunks to be
+   transmitted in the SCTP packet.  Each chunk is formatted with a Chunk
+   Type field, a chunk-specific Flag field, a Chunk Length field, and a
+   Value field.
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |   Chunk Type  | Chunk  Flags  |        Chunk Length           |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       \                                                               \
+       /                          Chunk Value                          /
+       \                                                               \
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   Chunk Type: 8 bits (unsigned integer)
+
+      This field identifies the type of information contained in the
+      Chunk Value field.  It takes a value from 0 to 254.  The value of
+      255 is reserved for future use as an extension field.
+
+      The values of Chunk Types are defined as follows:
+
+   ID Value    Chunk Type
+   -----       ----------
+   0          - Payload Data (DATA)
+   1          - Initiation (INIT)
+   2          - Initiation Acknowledgement (INIT ACK)
+   3          - Selective Acknowledgement (SACK)
+   4          - Heartbeat Request (HEARTBEAT)
+   5          - Heartbeat Acknowledgement (HEARTBEAT ACK)
+   6          - Abort (ABORT)
+   7          - Shutdown (SHUTDOWN)
+   8          - Shutdown Acknowledgement (SHUTDOWN ACK)
+   9          - Operation Error (ERROR)
+   10         - State Cookie (COOKIE ECHO)
+   11         - Cookie Acknowledgement (COOKIE ACK)
+
+
+
+
+Stewart                     Standards Track                    [Page 17]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   12         - Reserved for Explicit Congestion Notification Echo
+                (ECNE)
+   13         - Reserved for Congestion Window Reduced (CWR)
+   14         - Shutdown Complete (SHUTDOWN COMPLETE)
+   15 to 62   - available
+   63         - reserved for IETF-defined Chunk Extensions
+   64 to 126  - available
+   127        - reserved for IETF-defined Chunk Extensions
+   128 to 190 - available
+   191        - reserved for IETF-defined Chunk Extensions
+   192 to 254 - available
+   255        - reserved for IETF-defined Chunk Extensions
+
+      Chunk Types are encoded such that the highest-order 2 bits specify
+      the action that must be taken if the processing endpoint does not
+      recognize the Chunk Type.
+
+      00 -  Stop processing this SCTP packet and discard it, do not
+            process any further chunks within it.
+
+      01 -  Stop processing this SCTP packet and discard it, do not
+            process any further chunks within it, and report the
+            unrecognized chunk in an 'Unrecognized Chunk Type'.
+
+      10 -  Skip this chunk and continue processing.
+
+      11 -  Skip this chunk and continue processing, but report in an
+            ERROR chunk using the 'Unrecognized Chunk Type' cause of
+            error.
+
+      Note: The ECNE and CWR chunk types are reserved for future use of
+      Explicit Congestion Notification (ECN); see Appendix A.
+
+   Chunk Flags: 8 bits
+
+      The usage of these bits depends on the Chunk type as given by the
+      Chunk Type field.  Unless otherwise specified, they are set to 0
+      on transmit and are ignored on receipt.
+
+   Chunk Length: 16 bits (unsigned integer)
+
+      This value represents the size of the chunk in bytes, including
+      the Chunk Type, Chunk Flags, Chunk Length, and Chunk Value fields.
+      Therefore, if the Chunk Value field is zero-length, the Length
+      field will be set to 4.  The Chunk Length field does not count any
+      chunk padding.
+
+
+
+
+
+Stewart                     Standards Track                    [Page 18]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+      Chunks (including Type, Length, and Value fields) are padded out
+      by the sender with all zero bytes to be a multiple of 4 bytes
+      long.  This padding MUST NOT be more than 3 bytes in total.  The
+      Chunk Length value does not include terminating padding of the
+      chunk.  However, it does include padding of any variable-length
+      parameter except the last parameter in the chunk.  The receiver
+      MUST ignore the padding.
+
+      Note: A robust implementation should accept the chunk whether or
+      not the final padding has been included in the Chunk Length.
+
+   Chunk Value: variable length
+
+      The Chunk Value field contains the actual information to be
+      transferred in the chunk.  The usage and format of this field is
+      dependent on the Chunk Type.
+
+   The total length of a chunk (including Type, Length, and Value
+   fields) MUST be a multiple of 4 bytes.  If the length of the chunk is
+   not a multiple of 4 bytes, the sender MUST pad the chunk with all
+   zero bytes, and this padding is not included in the Chunk Length
+   field.  The sender MUST NOT pad with more than 3 bytes.  The receiver
+   MUST ignore the padding bytes.
+
+   SCTP-defined chunks are described in detail in Section 3.3.  The
+   guidelines for IETF-defined chunk extensions can be found in Section
+   14.1 of this document.
+
+3.2.1.  Optional/Variable-Length Parameter Format
+
+   Chunk values of SCTP control chunks consist of a chunk-type-specific
+   header of required fields, followed by zero or more parameters.  The
+   optional and variable-length parameters contained in a chunk are
+   defined in a Type-Length-Value format as shown below.
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |          Parameter Type       |       Parameter Length        |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       \                                                               \
+       /                       Parameter Value                         /
+       \                                                               \
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+
+
+
+
+
+Stewart                     Standards Track                    [Page 19]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   Chunk Parameter Type: 16 bits (unsigned integer)
+
+      The Type field is a 16-bit identifier of the type of parameter.
+      It takes a value of 0 to 65534.
+
+      The value of 65535 is reserved for IETF-defined extensions.
+      Values other than those defined in specific SCTP chunk
+      descriptions are reserved for use by IETF.
+
+   Chunk Parameter Length: 16 bits (unsigned integer)
+
+      The Parameter Length field contains the size of the parameter in
+      bytes, including the Parameter Type, Parameter Length, and
+      Parameter Value fields.  Thus, a parameter with a zero-length
+      Parameter Value field would have a Length field of 4.  The
+      Parameter Length does not include any padding bytes.
+
+   Chunk Parameter Value: variable length
+
+      The Parameter Value field contains the actual information to be
+      transferred in the parameter.
+
+      The total length of a parameter (including Type, Parameter Length,
+      and Value fields) MUST be a multiple of 4 bytes.  If the length of
+      the parameter is not a multiple of 4 bytes, the sender pads the
+      parameter at the end (i.e., after the Parameter Value field) with
+      all zero bytes.  The length of the padding is not included in the
+      Parameter Length field.  A sender MUST NOT pad with more than 3
+      bytes.  The receiver MUST ignore the padding bytes.
+
+      The Parameter Types are encoded such that the highest-order 2 bits
+      specify the action that must be taken if the processing endpoint
+      does not recognize the Parameter Type.
+
+      00 -  Stop processing this parameter; do not process any further
+            parameters within this chunk.
+
+      01 -  Stop processing this parameter, do not process any further
+            parameters within this chunk, and report the unrecognized
+            parameter in an 'Unrecognized Parameter', as described in
+            Section 3.2.2.
+
+      10 -  Skip this parameter and continue processing.
+
+      11 -  Skip this parameter and continue processing but report the
+            unrecognized parameter in an 'Unrecognized Parameter', as
+            described in Section 3.2.2.
+
+
+
+
+Stewart                     Standards Track                    [Page 20]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   Please note that in all four cases, an INIT ACK or COOKIE ECHO chunk
+   is sent.  In the 00 or 01 case, the processing of the parameters
+   after the unknown parameter is canceled, but no processing already
+   done is rolled back.
+
+   The actual SCTP parameters are defined in the specific SCTP chunk
+   sections.  The rules for IETF-defined parameter extensions are
+   defined in Section 14.2.  Note that a parameter type MUST be unique
+   across all chunks.  For example, the parameter type '5' is used to
+   represent an IPv4 address (see Section 3.3.2.1).  The value '5' then
+   is reserved across all chunks to represent an IPv4 address and MUST
+   NOT be reused with a different meaning in any other chunk.
+
+3.2.2.  Reporting of Unrecognized Parameters
+
+   If the receiver of an INIT chunk detects unrecognized parameters and
+   has to report them according to Section 3.2.1, it MUST put the
+   'Unrecognized Parameter' parameter(s) in the INIT ACK chunk sent in
+   response to the INIT chunk.  Note that if the receiver of the INIT
+   chunk is NOT going to establish an association (e.g., due to lack of
+   resources), an 'Unrecognized Parameter' would NOT be included with
+   any ABORT being sent to the sender of the INIT.
+
+   If the receiver of an INIT ACK chunk detects unrecognized parameters
+   and has to report them according to Section 3.2.1, it SHOULD bundle
+   the ERROR chunk containing the 'Unrecognized Parameters' error cause
+   with the COOKIE ECHO chunk sent in response to the INIT ACK chunk.
+   If the receiver of the INIT ACK cannot bundle the COOKIE ECHO chunk
+   with the ERROR chunk, the ERROR chunk MAY be sent separately but not
+   before the COOKIE ACK has been received.
+
+   Note: Any time a COOKIE ECHO is sent in a packet, it MUST be the
+   first chunk.
+
+3.3.  SCTP Chunk Definitions
+
+   This section defines the format of the different SCTP chunk types.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart                     Standards Track                    [Page 21]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+3.3.1.  Payload Data (DATA) (0)
+
+   The following format MUST be used for the DATA chunk:
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |   Type = 0    | Reserved|U|B|E|    Length                     |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                              TSN                              |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |      Stream Identifier S      |   Stream Sequence Number n    |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                  Payload Protocol Identifier                  |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       \                                                               \
+       /                 User Data (seq n of Stream S)                 /
+       \                                                               \
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   Reserved: 5 bits
+
+      Should be set to all '0's and ignored by the receiver.
+
+   U bit: 1 bit
+
+      The (U)nordered bit, if set to '1', indicates that this is an
+      unordered DATA chunk, and there is no Stream Sequence Number
+      assigned to this DATA chunk.  Therefore, the receiver MUST ignore
+      the Stream Sequence Number field.
+
+      After reassembly (if necessary), unordered DATA chunks MUST be
+      dispatched to the upper layer by the receiver without any attempt
+      to reorder.
+
+      If an unordered user message is fragmented, each fragment of the
+      message MUST have its U bit set to '1'.
+
+   B bit: 1 bit
+
+      The (B)eginning fragment bit, if set, indicates the first fragment
+      of a user message.
+
+   E bit: 1 bit
+
+      The (E)nding fragment bit, if set, indicates the last fragment of
+      a user message.
+
+
+
+
+Stewart                     Standards Track                    [Page 22]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   An unfragmented user message shall have both the B and E bits set to
+   '1'.  Setting both B and E bits to '0' indicates a middle fragment of
+   a multi-fragment user message, as summarized in the following table:
+
+               B E                  Description
+            ============================================================
+            |  1 0 | First piece of a fragmented user message          |
+            +----------------------------------------------------------+
+            |  0 0 | Middle piece of a fragmented user message         |
+            +----------------------------------------------------------+
+            |  0 1 | Last piece of a fragmented user message           |
+            +----------------------------------------------------------+
+            |  1 1 | Unfragmented message                              |
+            ============================================================
+            |             Table 1: Fragment Description Flags          |
+            ============================================================
+
+   When a user message is fragmented into multiple chunks, the TSNs are
+   used by the receiver to reassemble the message.  This means that the
+   TSNs for each fragment of a fragmented user message MUST be strictly
+   sequential.
+
+   Length: 16 bits (unsigned integer)
+
+      This field indicates the length of the DATA chunk in bytes from
+      the beginning of the type field to the end of the User Data field
+      excluding any padding.  A DATA chunk with one byte of user data
+      will have Length set to 17 (indicating 17 bytes).
+
+      A DATA chunk with a User Data field of length L will have the
+      Length field set to (16 + L) (indicating 16+L bytes) where L MUST
+      be greater than 0.
+
+   TSN: 32 bits (unsigned integer)
+
+      This value represents the TSN for this DATA chunk.  The valid
+      range of TSN is from 0 to 4294967295 (2**32 - 1).  TSN wraps back
+      to 0 after reaching 4294967295.
+
+   Stream Identifier S: 16 bits (unsigned integer)
+
+      Identifies the stream to which the following user data belongs.
+
+   Stream Sequence Number n: 16 bits (unsigned integer)
+
+      This value represents the Stream Sequence Number of the following
+      user data within the stream S.  Valid range is 0 to 65535.
+
+
+
+
+Stewart                     Standards Track                    [Page 23]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+      When a user message is fragmented by SCTP for transport, the same
+      Stream Sequence Number MUST be carried in each of the fragments of
+      the message.
+
+   Payload Protocol Identifier: 32 bits (unsigned integer)
+
+      This value represents an application (or upper layer) specified
+      protocol identifier.  This value is passed to SCTP by its upper
+      layer and sent to its peer.  This identifier is not used by SCTP
+      but can be used by certain network entities, as well as by the
+      peer application, to identify the type of information being
+      carried in this DATA chunk.  This field must be sent even in
+      fragmented DATA chunks (to make sure it is available for agents in
+      the middle of the network).  Note that this field is NOT touched
+      by an SCTP implementation; therefore, its byte order is NOT
+      necessarily big endian.  The upper layer is responsible for any
+      byte order conversions to this field.
+
+      The value 0 indicates that no application identifier is specified
+      by the upper layer for this payload data.
+
+   User Data: variable length
+
+      This is the payload user data.  The implementation MUST pad the
+      end of the data to a 4-byte boundary with all-zero bytes.  Any
+      padding MUST NOT be included in the Length field.  A sender MUST
+      never add more than 3 bytes of padding.
+
+3.3.2.  Initiation (INIT) (1)
+
+   This chunk is used to initiate an SCTP association between two
+   endpoints.  The format of the INIT chunk is shown below:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart                     Standards Track                    [Page 24]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |   Type = 1    |  Chunk Flags  |      Chunk Length             |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                         Initiate Tag                          |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |           Advertised Receiver Window Credit (a_rwnd)          |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |  Number of Outbound Streams   |  Number of Inbound Streams    |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                          Initial TSN                          |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       \                                                               \
+       /              Optional/Variable-Length Parameters              /
+       \                                                               \
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   The INIT chunk contains the following parameters.  Unless otherwise
+   noted, each parameter MUST only be included once in the INIT chunk.
+
+            Fixed Parameters                     Status
+            ----------------------------------------------
+            Initiate Tag                        Mandatory
+            Advertised Receiver Window Credit   Mandatory
+            Number of Outbound Streams          Mandatory
+            Number of Inbound Streams           Mandatory
+            Initial TSN                         Mandatory
+
+          Variable Parameters                  Status     Type Value
+          -------------------------------------------------------------
+          IPv4 Address (Note 1)               Optional    5 IPv6 Address
+          (Note 1)               Optional    6 Cookie Preservative
+          Optional    9 Reserved for ECN Capable (Note 2)   Optional
+          32768 (0x8000) Host Name Address (Note 3)          Optional
+          11 Supported Address Types (Note 4)    Optional    12
+
+   Note 1: The INIT chunks can contain multiple addresses that can be
+   IPv4 and/or IPv6 in any combination.
+
+   Note 2: The ECN Capable field is reserved for future use of Explicit
+   Congestion Notification.
+
+   Note 3: An INIT chunk MUST NOT contain more than one Host Name
+   Address parameter.  Moreover, the sender of the INIT MUST NOT combine
+   any other address types with the Host Name Address in the INIT.  The
+   receiver of INIT MUST ignore any other address types if the Host Name
+   Address parameter is present in the received INIT chunk.
+
+
+
+Stewart                     Standards Track                    [Page 25]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   Note 4: This parameter, when present, specifies all the address types
+   the sending endpoint can support.  The absence of this parameter
+   indicates that the sending endpoint can support any address type.
+
+   IMPLEMENTATION NOTE: If an INIT chunk is received with known
+   parameters that are not optional parameters of the INIT chunk, then
+   the receiver SHOULD process the INIT chunk and send back an INIT ACK.
+   The receiver of the INIT chunk MAY bundle an ERROR chunk with the
+   COOKIE ACK chunk later.  However, restrictive implementations MAY
+   send back an ABORT chunk in response to the INIT chunk.
+
+   The Chunk Flags field in INIT is reserved, and all bits in it should
+   be set to 0 by the sender and ignored by the receiver.  The sequence
+   of parameters within an INIT can be processed in any order.
+
+   Initiate Tag: 32 bits (unsigned integer)
+
+      The receiver of the INIT (the responding end) records the value of
+      the Initiate Tag parameter.  This value MUST be placed into the
+      Verification Tag field of every SCTP packet that the receiver of
+      the INIT transmits within this association.
+
+      The Initiate Tag is allowed to have any value except 0.  See
+      Section 5.3.1 for more on the selection of the tag value.
+
+      If the value of the Initiate Tag in a received INIT chunk is found
+      to be 0, the receiver MUST treat it as an error and close the
+      association by transmitting an ABORT.
+
+   Advertised Receiver Window Credit (a_rwnd): 32 bits (unsigned
+   integer)
+
+      This value represents the dedicated buffer space, in number of
+      bytes, the sender of the INIT has reserved in association with
+      this window.  During the life of the association, this buffer
+      space SHOULD NOT be lessened (i.e., dedicated buffers taken away
+      from this association); however, an endpoint MAY change the value
+      of a_rwnd it sends in SACK chunks.
+
+   Number of Outbound Streams (OS): 16 bits (unsigned integer)
+
+      Defines the number of outbound streams the sender of this INIT
+      chunk wishes to create in this association.  The value of 0 MUST
+      NOT be used.
+
+      Note: A receiver of an INIT with the OS value set to 0 SHOULD
+      abort the association.
+
+
+
+
+Stewart                     Standards Track                    [Page 26]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   Number of Inbound Streams (MIS): 16 bits (unsigned integer)
+
+      Defines the maximum number of streams the sender of this INIT
+      chunk allows the peer end to create in this association.  The
+      value 0 MUST NOT be used.
+
+      Note: There is no negotiation of the actual number of streams but
+      instead the two endpoints will use the min(requested, offered).
+      See Section 5.1.1 for details.
+
+      Note: A receiver of an INIT with the MIS value of 0 SHOULD abort
+      the association.
+
+   Initial TSN (I-TSN): 32 bits (unsigned integer)
+
+      Defines the initial TSN that the sender will use.  The valid range
+      is from 0 to 4294967295.  This field MAY be set to the value of
+      the Initiate Tag field.
+
+3.3.2.1.  Optional/Variable-Length Parameters in INIT
+
+   The following parameters follow the Type-Length-Value format as
+   defined in Section 3.2.1.  Any Type-Length-Value fields MUST come
+   after the fixed-length fields defined in the previous section.
+
+   IPv4 Address Parameter (5)
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |        Type = 5               |      Length = 8               |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                        IPv4 Address                           |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   IPv4 Address: 32 bits (unsigned integer)
+
+      Contains an IPv4 address of the sending endpoint.  It is binary
+      encoded.
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart                     Standards Track                    [Page 27]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   IPv6 Address Parameter (6)
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |            Type = 6           |          Length = 20          |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                                                               |
+       |                         IPv6 Address                          |
+       |                                                               |
+       |                                                               |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   IPv6 Address: 128 bits (unsigned integer)
+
+      Contains an IPv6 [RFC2460] address of the sending endpoint.  It is
+      binary encoded.
+
+      Note: A sender MUST NOT use an IPv4-mapped IPv6 address [RFC4291],
+      but should instead use an IPv4 Address parameter for an IPv4
+      address.
+
+      Combined with the Source Port Number in the SCTP common header,
+      the value passed in an IPv4 or IPv6 Address parameter indicates a
+      transport address the sender of the INIT will support for the
+      association being initiated.  That is, during the life time of
+      this association, this IP address can appear in the source address
+      field of an IP datagram sent from the sender of the INIT, and can
+      be used as a destination address of an IP datagram sent from the
+      receiver of the INIT.
+
+      More than one IP Address parameter can be included in an INIT
+      chunk when the INIT sender is multi-homed.  Moreover, a multi-
+      homed endpoint may have access to different types of network;
+      thus, more than one address type can be present in one INIT chunk,
+      i.e., IPv4 and IPv6 addresses are allowed in the same INIT chunk.
+
+      If the INIT contains at least one IP Address parameter, then the
+      source address of the IP datagram containing the INIT chunk and
+      any additional address(es) provided within the INIT can be used as
+      destinations by the endpoint receiving the INIT.  If the INIT does
+      not contain any IP Address parameters, the endpoint receiving the
+      INIT MUST use the source address associated with the received IP
+      datagram as its sole destination address for the association.
+
+      Note that not using any IP Address parameters in the INIT and INIT
+      ACK is an alternative to make an association more likely to work
+      across a NAT box.
+
+
+
+Stewart                     Standards Track                    [Page 28]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   Cookie Preservative (9)
+
+   The sender of the INIT shall use this parameter to suggest to the
+   receiver of the INIT for a longer life-span of the State Cookie.
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |          Type = 9             |          Length = 8           |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |         Suggested Cookie Life-Span Increment (msec.)          |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   Suggested Cookie Life-Span Increment: 32 bits (unsigned integer)
+
+      This parameter indicates to the receiver how much increment in
+      milliseconds the sender wishes the receiver to add to its default
+      cookie life-span.
+
+      This optional parameter should be added to the INIT chunk by the
+      sender when it reattempts establishing an association with a peer
+      to which its previous attempt of establishing the association
+      failed due to a stale cookie operation error.  The receiver MAY
+      choose to ignore the suggested cookie life-span increase for its
+      own security reasons.
+
+   Host Name Address (11)
+
+   The sender of INIT uses this parameter to pass its Host Name (in
+   place of its IP addresses) to its peer.  The peer is responsible for
+   resolving the name.  Using this parameter might make it more likely
+   for the association to work across a NAT box.
+
+       0                   1                   2                   3
+       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |          Type = 11            |          Length               |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       /                          Host Name                            /
+       \                                                               \
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   Host Name: variable length
+
+      This field contains a host name in "host name syntax" per RFC 1123
+      Section 2.1 [RFC1123].  The method for resolving the host name is
+      out of scope of SCTP.
+
+
+
+
+Stewart                     Standards Track                    [Page 29]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+      Note: At least one null terminator is included in the Host Name
+      string and must be included in the length.
+
+   Supported Address Types (12)
+
+   The sender of INIT uses this parameter to list all the address types
+   it can support.
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |          Type = 12            |          Length               |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |        Address Type #1        |        Address Type #2        |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                            ......                             |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-+-+-+-+-+-+-++-+-+-+
+
+   Address Type: 16 bits (unsigned integer)
+
+      This is filled with the type value of the corresponding address
+      TLV (e.g., IPv4 = 5, IPv6 = 6, Host name = 11).
+
+3.3.3.  Initiation Acknowledgement (INIT ACK) (2)
+
+   The INIT ACK chunk is used to acknowledge the initiation of an SCTP
+   association.
+
+   The parameter part of INIT ACK is formatted similarly to the INIT
+   chunk.  It uses two extra variable parameters: The State Cookie and
+   the Unrecognized Parameter:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart                     Standards Track                    [Page 30]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   The format of the INIT ACK chunk is shown below:
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |   Type = 2    |  Chunk Flags  |      Chunk Length             |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                         Initiate Tag                          |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |              Advertised Receiver Window Credit                |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |  Number of Outbound Streams   |  Number of Inbound Streams    |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                          Initial TSN                          |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       \                                                               \
+       /              Optional/Variable-Length Parameters              /
+       \                                                               \
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   Initiate Tag: 32 bits (unsigned integer)
+
+      The receiver of the INIT ACK records the value of the Initiate Tag
+      parameter.  This value MUST be placed into the Verification Tag
+      field of every SCTP packet that the INIT ACK receiver transmits
+      within this association.
+
+      The Initiate Tag MUST NOT take the value 0.  See Section 5.3.1 for
+      more on the selection of the Initiate Tag value.
+
+      If the value of the Initiate Tag in a received INIT ACK chunk is
+      found to be 0, the receiver MUST destroy the association
+      discarding its TCB.  The receiver MAY send an ABORT for debugging
+      purpose.
+
+   Advertised Receiver Window Credit (a_rwnd): 32 bits (unsigned
+   integer)
+
+      This value represents the dedicated buffer space, in number of
+      bytes, the sender of the INIT ACK has reserved in association with
+      this window.  During the life of the association, this buffer
+      space SHOULD NOT be lessened (i.e., dedicated buffers taken away
+      from this association).
+
+   Number of Outbound Streams (OS): 16 bits (unsigned integer)
+
+      Defines the number of outbound streams the sender of this INIT ACK
+      chunk wishes to create in this association.  The value of 0 MUST
+
+
+
+Stewart                     Standards Track                    [Page 31]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+      NOT be used, and the value MUST NOT be greater than the MIS value
+      sent in the INIT chunk.
+
+      Note: A receiver of an INIT ACK with the OS value set to 0 SHOULD
+      destroy the association discarding its TCB.
+
+   Number of Inbound Streams (MIS): 16 bits (unsigned integer)
+
+      Defines the maximum number of streams the sender of this INIT ACK
+      chunk allows the peer end to create in this association.  The
+      value 0 MUST NOT be used.
+
+      Note: There is no negotiation of the actual number of streams but
+      instead the two endpoints will use the min(requested, offered).
+      See Section 5.1.1 for details.
+
+      Note: A receiver of an INIT ACK with the MIS value set to 0 SHOULD
+      destroy the association discarding its TCB.
+
+   Initial TSN (I-TSN): 32 bits (unsigned integer)
+
+      Defines the initial TSN that the INIT ACK sender will use.  The
+      valid range is from 0 to 4294967295.  This field MAY be set to the
+      value of the Initiate Tag field.
+
+         Fixed Parameters                     Status
+         ----------------------------------------------
+         Initiate Tag                        Mandatory
+         Advertised Receiver Window Credit   Mandatory
+         Number of Outbound Streams          Mandatory
+         Number of Inbound Streams           Mandatory
+         Initial TSN                         Mandatory
+
+         Variable Parameters                  Status     Type Value
+         -------------------------------------------------------------
+         State Cookie                        Mandatory   7
+         IPv4 Address (Note 1)               Optional    5
+         IPv6 Address (Note 1)               Optional    6
+         Unrecognized Parameter              Optional    8
+         Reserved for ECN Capable (Note 2)   Optional    32768 (0x8000)
+         Host Name Address (Note 3)          Optional    11
+
+   Note 1: The INIT ACK chunks can contain any number of IP address
+   parameters that can be IPv4 and/or IPv6 in any combination.
+
+   Note 2: The ECN Capable field is reserved for future use of Explicit
+   Congestion Notification.
+
+
+
+
+Stewart                     Standards Track                    [Page 32]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   Note 3: The INIT ACK chunks MUST NOT contain more than one Host Name
+   Address parameter.  Moreover, the sender of the INIT ACK MUST NOT
+   combine any other address types with the Host Name Address in the
+   INIT ACK.  The receiver of the INIT ACK MUST ignore any other address
+   types if the Host Name Address parameter is present.
+
+   IMPLEMENTATION NOTE: An implementation MUST be prepared to receive an
+   INIT ACK that is quite large (more than 1500 bytes) due to the
+   variable size of the State Cookie AND the variable address list.  For
+   example if a responder to the INIT has 1000 IPv4 addresses it wishes
+   to send, it would need at least 8,000 bytes to encode this in the
+   INIT ACK.
+
+   IMPLEMENTATION NOTE: If an INIT ACK chunk is received with known
+   parameters that are not optional parameters of the INIT ACK chunk,
+   then the receiver SHOULD process the INIT ACK chunk and send back a
+   COOKIE ECHO.  The receiver of the INIT ACK chunk MAY bundle an ERROR
+   chunk with the COOKIE ECHO chunk.  However, restrictive
+   implementations MAY send back an ABORT chunk in response to the INIT
+   ACK chunk.
+
+   In combination with the Source Port carried in the SCTP common
+   header, each IP Address parameter in the INIT ACK indicates to the
+   receiver of the INIT ACK a valid transport address supported by the
+   sender of the INIT ACK for the life time of the association being
+   initiated.
+
+   If the INIT ACK contains at least one IP Address parameter, then the
+   source address of the IP datagram containing the INIT ACK and any
+   additional address(es) provided within the INIT ACK may be used as
+   destinations by the receiver of the INIT ACK.  If the INIT ACK does
+   not contain any IP Address parameters, the receiver of the INIT ACK
+   MUST use the source address associated with the received IP datagram
+   as its sole destination address for the association.
+
+   The State Cookie and Unrecognized Parameters use the Type-Length-
+   Value format as defined in Section 3.2.1 and are described below.
+   The other fields are defined the same as their counterparts in the
+   INIT chunk.
+
+3.3.3.1.  Optional or Variable-Length Parameters
+
+   State Cookie
+
+   Parameter Type Value: 7
+
+      Parameter Length: Variable size, depending on size of Cookie.
+
+
+
+
+Stewart                     Standards Track                    [Page 33]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   Parameter Value:
+
+      This parameter value MUST contain all the necessary state and
+      parameter information required for the sender of this INIT ACK to
+      create the association, along with a Message Authentication Code
+      (MAC).  See Section 5.1.3 for details on State Cookie definition.
+
+   Unrecognized Parameter:
+
+      Parameter Type Value: 8
+
+   Parameter Length: Variable size.
+
+   Parameter Value:
+
+      This parameter is returned to the originator of the INIT chunk
+      when the INIT contains an unrecognized parameter that has a value
+      that indicates it should be reported to the sender.  This
+      parameter value field will contain unrecognized parameters copied
+      from the INIT chunk complete with Parameter Type, Length, and
+      Value fields.
+
+3.3.4.  Selective Acknowledgement (SACK) (3)
+
+   This chunk is sent to the peer endpoint to acknowledge received DATA
+   chunks and to inform the peer endpoint of gaps in the received
+   subsequences of DATA chunks as represented by their TSNs.
+
+   The SACK MUST contain the Cumulative TSN Ack, Advertised Receiver
+   Window Credit (a_rwnd), Number of Gap Ack Blocks, and Number of
+   Duplicate TSNs fields.
+
+   By definition, the value of the Cumulative TSN Ack parameter is the
+   last TSN received before a break in the sequence of received TSNs
+   occurs; the next TSN value following this one has not yet been
+   received at the endpoint sending the SACK.  This parameter therefore
+   acknowledges receipt of all TSNs less than or equal to its value.
+
+   The handling of a_rwnd by the receiver of the SACK is discussed in
+   detail in Section 6.2.1.
+
+   The SACK also contains zero or more Gap Ack Blocks.  Each Gap Ack
+   Block acknowledges a subsequence of TSNs received following a break
+   in the sequence of received TSNs.  By definition, all TSNs
+   acknowledged by Gap Ack Blocks are greater than the value of the
+   Cumulative TSN Ack.
+
+
+
+
+
+Stewart                     Standards Track                    [Page 34]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |   Type = 3    |Chunk  Flags   |      Chunk Length             |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                      Cumulative TSN Ack                       |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |          Advertised Receiver Window Credit (a_rwnd)           |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       | Number of Gap Ack Blocks = N  |  Number of Duplicate TSNs = X |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |  Gap Ack Block #1 Start       |   Gap Ack Block #1 End        |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       /                                                               /
+       \                              ...                              \
+       /                                                               /
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |   Gap Ack Block #N Start      |  Gap Ack Block #N End         |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                       Duplicate TSN 1                         |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       /                                                               /
+       \                              ...                              \
+       /                                                               /
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                       Duplicate TSN X                         |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   Chunk Flags: 8 bits
+
+      Set to all '0's on transmit and ignored on receipt.
+
+   Cumulative TSN Ack: 32 bits (unsigned integer)
+
+      This parameter contains the TSN of the last DATA chunk received in
+      sequence before a gap.  In the case where no DATA chunk has been
+      received, this value is set to the peer's Initial TSN minus one.
+
+   Advertised Receiver Window Credit (a_rwnd): 32 bits (unsigned
+   integer)
+
+      This field indicates the updated receive buffer space in bytes of
+      the sender of this SACK; see Section 6.2.1 for details.
+
+   Number of Gap Ack Blocks: 16 bits (unsigned integer)
+
+      Indicates the number of Gap Ack Blocks included in this SACK.
+
+
+
+
+Stewart                     Standards Track                    [Page 35]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   Number of Duplicate TSNs: 16 bit
+
+      This field contains the number of duplicate TSNs the endpoint has
+      received.  Each duplicate TSN is listed following the Gap Ack
+      Block list.
+
+   Gap Ack Blocks:
+
+      These fields contain the Gap Ack Blocks.  They are repeated for
+      each Gap Ack Block up to the number of Gap Ack Blocks defined in
+      the Number of Gap Ack Blocks field.  All DATA chunks with TSNs
+      greater than or equal to (Cumulative TSN Ack + Gap Ack Block
+      Start) and less than or equal to (Cumulative TSN Ack + Gap Ack
+      Block End) of each Gap Ack Block are assumed to have been received
+      correctly.
+
+   Gap Ack Block Start: 16 bits (unsigned integer)
+
+      Indicates the Start offset TSN for this Gap Ack Block.  To
+      calculate the actual TSN number the Cumulative TSN Ack is added to
+      this offset number.  This calculated TSN identifies the first TSN
+      in this Gap Ack Block that has been received.
+
+   Gap Ack Block End: 16 bits (unsigned integer)
+
+      Indicates the End offset TSN for this Gap Ack Block.  To calculate
+      the actual TSN number, the Cumulative TSN Ack is added to this
+      offset number.  This calculated TSN identifies the TSN of the last
+      DATA chunk received in this Gap Ack Block.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart                     Standards Track                    [Page 36]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   For example, assume that the receiver has the following DATA chunks
+   newly arrived at the time when it decides to send a Selective ACK,
+
+                           ----------
+                           | TSN=17 |
+                           ----------
+                           |        | <- still missing
+                           ----------
+                           | TSN=15 |
+                           ----------
+                           | TSN=14 |
+                           ----------
+                           |        | <- still missing
+                           ----------
+                           | TSN=12 |
+                           ----------
+                           | TSN=11 |
+                           ----------
+                           | TSN=10 |
+                           ----------
+
+   then the parameter part of the SACK MUST be constructed as follows
+   (assuming the new a_rwnd is set to 4660 by the sender):
+
+                     +--------------------------------+
+                     |   Cumulative TSN Ack = 12      |
+                     +--------------------------------+
+                     |        a_rwnd = 4660           |
+                     +----------------+---------------+
+                     | num of block=2 | num of dup=0  |
+                     +----------------+---------------+
+                     |block #1 strt=2 |block #1 end=3 |
+                     +----------------+---------------+
+                     |block #2 strt=5 |block #2 end=5 |
+                     +----------------+---------------+
+
+   Duplicate TSN: 32 bits (unsigned integer)
+
+      Indicates the number of times a TSN was received in duplicate
+      since the last SACK was sent.  Every time a receiver gets a
+      duplicate TSN (before sending the SACK), it adds it to the list of
+      duplicates.  The duplicate count is reinitialized to zero after
+      sending each SACK.
+
+   For example, if a receiver were to get the TSN 19 three times it
+   would list 19 twice in the outbound SACK.  After sending the SACK, if
+   it received yet one more TSN 19 it would list 19 as a duplicate once
+   in the next outgoing SACK.
+
+
+
+Stewart                     Standards Track                    [Page 37]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+3.3.5.  Heartbeat Request (HEARTBEAT) (4)
+
+   An endpoint should send this chunk to its peer endpoint to probe the
+   reachability of a particular destination transport address defined in
+   the present association.
+
+   The parameter field contains the Heartbeat Information, which is a
+   variable-length opaque data structure understood only by the sender.
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |   Type = 4    | Chunk  Flags  |      Heartbeat Length         |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       \                                                               \
+       /            Heartbeat Information TLV (Variable-Length)        /
+       \                                                               \
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   Chunk Flags: 8 bits
+
+      Set to 0 on transmit and ignored on receipt.
+
+   Heartbeat Length: 16 bits (unsigned integer)
+
+      Set to the size of the chunk in bytes, including the chunk header
+      and the Heartbeat Information field.
+
+   Heartbeat Information: variable length
+
+      Defined as a variable-length parameter using the format described
+      in Section 3.2.1, i.e.:
+
+         Variable Parameters                  Status     Type Value
+         -------------------------------------------------------------
+         Heartbeat Info                       Mandatory   1
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |    Heartbeat Info Type=1      |         HB Info Length        |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       /                  Sender-Specific Heartbeat Info               /
+       \                                                               \
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+      The Sender-Specific Heartbeat Info field should normally include
+      information about the sender's current time when this HEARTBEAT
+
+
+
+Stewart                     Standards Track                    [Page 38]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+      chunk is sent and the destination transport address to which this
+      HEARTBEAT is sent (see Section 8.3).  This information is simply
+      reflected back by the receiver in the HEARTBEAT ACK message (see
+      Section 3.3.6).  Note also that the HEARTBEAT message is both for
+      reachability checking and for path verification (see Section 5.4).
+      When a HEARTBEAT chunk is being used for path verification
+      purposes, it MUST hold a 64-bit random nonce.
+
+3.3.6.  Heartbeat Acknowledgement (HEARTBEAT ACK) (5)
+
+   An endpoint should send this chunk to its peer endpoint as a response
+   to a HEARTBEAT chunk (see Section 8.3).  A HEARTBEAT ACK is always
+   sent to the source IP address of the IP datagram containing the
+   HEARTBEAT chunk to which this ack is responding.
+
+   The parameter field contains a variable-length opaque data structure.
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |   Type = 5    | Chunk  Flags  |    Heartbeat Ack Length       |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       \                                                               \
+       /            Heartbeat Information TLV (Variable-Length)        /
+       \                                                               \
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   Chunk Flags: 8 bits
+
+      Set to 0 on transmit and ignored on receipt.
+
+   Heartbeat Ack Length: 16 bits (unsigned integer)
+
+      Set to the size of the chunk in bytes, including the chunk header
+      and the Heartbeat Information field.
+
+   Heartbeat Information: variable length
+
+      This field MUST contain the Heartbeat Information parameter of the
+      Heartbeat Request to which this Heartbeat Acknowledgement is
+      responding.
+
+         Variable Parameters                  Status     Type Value
+         -------------------------------------------------------------
+         Heartbeat Info                       Mandatory   1
+
+
+
+
+
+
+Stewart                     Standards Track                    [Page 39]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+3.3.7.  Abort Association (ABORT) (6)
+
+   The ABORT chunk is sent to the peer of an association to close the
+   association.  The ABORT chunk may contain Cause Parameters to inform
+   the receiver about the reason of the abort.  DATA chunks MUST NOT be
+   bundled with ABORT.  Control chunks (except for INIT, INIT ACK, and
+   SHUTDOWN COMPLETE) MAY be bundled with an ABORT, but they MUST be
+   placed before the ABORT in the SCTP packet or they will be ignored by
+   the receiver.
+
+   If an endpoint receives an ABORT with a format error or no TCB is
+   found, it MUST silently discard it.  Moreover, under any
+   circumstances, an endpoint that receives an ABORT MUST NOT respond to
+   that ABORT by sending an ABORT of its own.
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |   Type = 6    |Reserved     |T|           Length              |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       \                                                               \
+       /                   zero or more Error Causes                   /
+       \                                                               \
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   Chunk Flags: 8 bits
+
+      Reserved: 7 bits
+
+      Set to 0 on transmit and ignored on receipt.
+
+      T bit: 1 bit
+
+      The T bit is set to 0 if the sender filled in the Verification Tag
+      expected by the peer.  If the Verification Tag is reflected, the T
+      bit MUST be set to 1.  Reflecting means that the sent Verification
+      Tag is the same as the received one.
+
+      Note: Special rules apply to this chunk for verification; please
+      see Section 8.5.1 for details.
+
+   Length: 16 bits (unsigned integer)
+
+      Set to the size of the chunk in bytes, including the chunk header
+      and all the Error Cause fields present.
+
+      See Section 3.3.10 for Error Cause definitions.
+
+
+
+
+Stewart                     Standards Track                    [Page 40]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+3.3.8.  Shutdown Association (SHUTDOWN) (7)
+
+   An endpoint in an association MUST use this chunk to initiate a
+   graceful close of the association with its peer.  This chunk has the
+   following format.
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |   Type = 7    | Chunk  Flags  |      Length = 8               |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                      Cumulative TSN Ack                       |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   Chunk Flags: 8 bits
+
+      Set to 0 on transmit and ignored on receipt.
+
+   Length: 16 bits (unsigned integer)
+
+      Indicates the length of the parameter.  Set to 8.
+
+   Cumulative TSN Ack: 32 bits (unsigned integer)
+
+      This parameter contains the TSN of the last chunk received in
+      sequence before any gaps.
+
+      Note: Since the SHUTDOWN message does not contain Gap Ack Blocks,
+      it cannot be used to acknowledge TSNs received out of order.  In a
+      SACK, lack of Gap Ack Blocks that were previously included
+      indicates that the data receiver reneged on the associated DATA
+      chunks.  Since SHUTDOWN does not contain Gap Ack Blocks, the
+      receiver of the SHUTDOWN shouldn't interpret the lack of a Gap Ack
+      Block as a renege.  (See Section 6.2 for information on reneging.)
+
+3.3.9.  Shutdown Acknowledgement (SHUTDOWN ACK) (8)
+
+   This chunk MUST be used to acknowledge the receipt of the SHUTDOWN
+   chunk at the completion of the shutdown process; see Section 9.2 for
+   details.
+
+   The SHUTDOWN ACK chunk has no parameters.
+
+
+
+
+
+
+
+
+
+Stewart                     Standards Track                    [Page 41]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |   Type = 8    |Chunk  Flags   |      Length = 4               |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   Chunk Flags: 8 bits
+
+      Set to 0 on transmit and ignored on receipt.
+
+3.3.10.  Operation Error (ERROR) (9)
+
+   An endpoint sends this chunk to its peer endpoint to notify it of
+   certain error conditions.  It contains one or more error causes.  An
+   Operation Error is not considered fatal in and of itself, but may be
+   used with an ABORT chunk to report a fatal condition.  It has the
+   following parameters:
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |   Type = 9    | Chunk  Flags  |           Length              |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       \                                                               \
+       /                    one or more Error Causes                   /
+       \                                                               \
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   Chunk Flags: 8 bits
+
+      Set to 0 on transmit and ignored on receipt.
+
+   Length: 16 bits (unsigned integer)
+
+      Set to the size of the chunk in bytes, including the chunk header
+      and all the Error Cause fields present.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart                     Standards Track                    [Page 42]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   Error causes are defined as variable-length parameters using the
+   format described in Section 3.2.1, that is:
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |           Cause Code          |       Cause Length            |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       /                    Cause-Specific Information                 /
+       \                                                               \
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   Cause Code: 16 bits (unsigned integer)
+
+      Defines the type of error conditions being reported.
+
+         Cause Code
+         Value           Cause Code
+         ---------      ----------------
+          1              Invalid Stream Identifier
+          2              Missing Mandatory Parameter
+          3              Stale Cookie Error
+          4              Out of Resource
+          5              Unresolvable Address
+          6              Unrecognized Chunk Type
+          7              Invalid Mandatory Parameter
+          8              Unrecognized Parameters
+          9              No User Data
+         10              Cookie Received While Shutting Down
+         11              Restart of an Association with New Addresses
+         12              User Initiated Abort
+         13              Protocol Violation
+
+   Cause Length: 16 bits (unsigned integer)
+
+      Set to the size of the parameter in bytes, including the Cause
+      Code, Cause Length, and Cause-Specific Information fields.
+
+   Cause-Specific Information: variable length
+
+      This field carries the details of the error condition.
+
+   Section 3.3.10.1 - Section 3.3.10.13 define error causes for SCTP.
+   Guidelines for the IETF to define new error cause values are
+   discussed in Section 14.3.
+
+
+
+
+
+
+Stewart                     Standards Track                    [Page 43]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+3.3.10.1.  Invalid Stream Identifier (1)
+
+   Cause of error
+   ---------------
+
+   Invalid Stream Identifier: Indicates endpoint received a DATA chunk
+   sent to a nonexistent stream.
+
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |     Cause Code=1              |      Cause Length=8           |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |        Stream Identifier      |         (Reserved)            |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   Stream Identifier: 16 bits (unsigned integer)
+
+      Contains the Stream Identifier of the DATA chunk received in
+      error.
+
+   Reserved: 16 bits
+
+      This field is reserved.  It is set to all 0's on transmit and
+      ignored on receipt.
+
+3.3.10.2.  Missing Mandatory Parameter (2)
+
+   Cause of error
+   ---------------
+
+   Missing Mandatory Parameter: Indicates that one or more mandatory TLV
+   parameters are missing in a received INIT or INIT ACK.
+
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |     Cause Code=2              |      Cause Length=8+N*2       |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                   Number of missing params=N                  |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |   Missing Param Type #1       |   Missing Param Type #2       |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |   Missing Param Type #N-1     |   Missing Param Type #N       |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   Number of Missing params: 32 bits (unsigned integer)
+
+      This field contains the number of parameters contained in the
+      Cause-Specific Information field.
+
+
+
+
+
+Stewart                     Standards Track                    [Page 44]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   Missing Param Type: 16 bits (unsigned integer)
+
+      Each field will contain the missing mandatory parameter number.
+
+3.3.10.3.  Stale Cookie Error (3)
+
+   Cause of error
+   --------------
+
+   Stale Cookie Error: Indicates the receipt of a valid State Cookie
+   that has expired.
+
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |     Cause Code=3              |       Cause Length=8          |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                 Measure of Staleness (usec.)                  |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   Measure of Staleness: 32 bits (unsigned integer)
+
+      This field contains the difference, in microseconds, between the
+      current time and the time the State Cookie expired.
+
+      The sender of this error cause MAY choose to report how long past
+      expiration the State Cookie is by including a non-zero value in
+      the Measure of Staleness field.  If the sender does not wish to
+      provide this information, it should set the Measure of Staleness
+      field to the value of zero.
+
+3.3.10.4.  Out of Resource (4)
+
+   Cause of error
+   ---------------
+
+   Out of Resource: Indicates that the sender is out of resource.  This
+   is usually sent in combination with or within an ABORT.
+
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |     Cause Code=4              |      Cause Length=4           |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+
+
+
+
+
+
+
+
+
+Stewart                     Standards Track                    [Page 45]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+3.3.10.5.  Unresolvable Address (5)
+
+   Cause of error
+   ---------------
+
+   Unresolvable Address: Indicates that the sender is not able to
+   resolve the specified address parameter (e.g., type of address is not
+   supported by the sender).  This is usually sent in combination with
+   or within an ABORT.
+
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |     Cause Code=5              |      Cause Length             |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       /                  Unresolvable Address                         /
+       \                                                               \
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   Unresolvable Address: variable length
+
+      The Unresolvable Address field contains the complete Type, Length,
+      and Value of the address parameter (or Host Name parameter) that
+      contains the unresolvable address or host name.
+
+3.3.10.6.  Unrecognized Chunk Type (6)
+
+   Cause of error
+   ---------------
+
+   Unrecognized Chunk Type: This error cause is returned to the
+   originator of the chunk if the receiver does not understand the chunk
+   and the upper bits of the 'Chunk Type' are set to 01 or 11.
+
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |     Cause Code=6              |      Cause Length             |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       /                  Unrecognized Chunk                           /
+       \                                                               \
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   Unrecognized Chunk: variable length
+
+      The Unrecognized Chunk field contains the unrecognized chunk from
+      the SCTP packet complete with Chunk Type, Chunk Flags, and Chunk
+      Length.
+
+
+
+
+
+
+
+Stewart                     Standards Track                    [Page 46]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+3.3.10.7.  Invalid Mandatory Parameter (7)
+
+   Cause of error
+   ---------------
+
+   Invalid Mandatory Parameter: This error cause is returned to the
+   originator of an INIT or INIT ACK chunk when one of the mandatory
+   parameters is set to an invalid value.
+
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |     Cause Code=7              |      Cause Length=4           |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+3.3.10.8.  Unrecognized Parameters (8)
+
+   Cause of error
+   ---------------
+
+   Unrecognized Parameters: This error cause is returned to the
+   originator of the INIT ACK chunk if the receiver does not recognize
+   one or more Optional TLV parameters in the INIT ACK chunk.
+
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |     Cause Code=8              |      Cause Length             |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       /                  Unrecognized Parameters                      /
+       \                                                               \
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   Unrecognized Parameters: variable length
+
+      The Unrecognized Parameters field contains the unrecognized
+      parameters copied from the INIT ACK chunk complete with TLV.  This
+      error cause is normally contained in an ERROR chunk bundled with
+      the COOKIE ECHO chunk when responding to the INIT ACK, when the
+      sender of the COOKIE ECHO chunk wishes to report unrecognized
+      parameters.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart                     Standards Track                    [Page 47]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+3.3.10.9.  No User Data (9)
+
+   Cause of error
+   ---------------
+
+   No User Data: This error cause is returned to the originator of a
+
+   DATA chunk if a received DATA chunk has no user data.
+
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |     Cause Code=9              |      Cause Length=8           |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       /                  TSN value                                    /
+       \                                                               \
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   TSN value: 32 bits (unsigned integer)
+
+      The TSN value field contains the TSN of the DATA chunk received
+      with no user data field.
+
+      This cause code is normally returned in an ABORT chunk (see
+      Section 6.2).
+
+3.3.10.10.  Cookie Received While Shutting Down (10)
+
+   Cause of error
+   ---------------
+
+   Cookie Received While Shutting Down: A COOKIE ECHO was received while
+   the endpoint was in the SHUTDOWN-ACK-SENT state.  This error is
+   usually returned in an ERROR chunk bundled with the retransmitted
+   SHUTDOWN ACK.
+
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |     Cause Code=10              |      Cause Length=4          |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart                     Standards Track                    [Page 48]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+3.3.10.11.  Restart of an Association with New Addresses (11)
+
+   Cause of error
+   --------------
+
+   Restart of an association with new addresses: An INIT was received on
+   an existing association.  But the INIT added addresses to the
+   association that were previously NOT part of the association.  The
+   new addresses are listed in the error code.  This ERROR is normally
+   sent as part of an ABORT refusing the INIT (see Section 5.2).
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |         Cause Code=11         |      Cause Length=Variable    |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       /                       New Address TLVs                        /
+       \                                                               \
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   Note: Each New Address TLV is an exact copy of the TLV that was found
+   in the INIT chunk that was new, including the Parameter Type and the
+   Parameter Length.
+
+3.3.10.12.  User-Initiated Abort (12)
+
+   Cause of error
+   --------------
+
+   This error cause MAY be included in ABORT chunks that are sent
+   because of an upper-layer request.  The upper layer can specify an
+   Upper Layer Abort Reason that is transported by SCTP transparently
+   and MAY be delivered to the upper-layer protocol at the peer.
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |         Cause Code=12         |      Cause Length=Variable    |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       /                    Upper Layer Abort Reason                   /
+       \                                                               \
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+
+
+
+
+
+
+
+Stewart                     Standards Track                    [Page 49]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+3.3.10.13.  Protocol Violation (13)
+
+   Cause of error
+   --------------
+
+   This error cause MAY be included in ABORT chunks that are sent
+   because an SCTP endpoint detects a protocol violation of the peer
+   that is not covered by the error causes described in Section 3.3.10.1
+   to Section 3.3.10.12.  An implementation MAY provide additional
+   information specifying what kind of protocol violation has been
+   detected.
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |         Cause Code=13         |      Cause Length=Variable    |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       /                    Additional Information                     /
+       \                                                               \
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+3.3.11.  Cookie Echo (COOKIE ECHO) (10)
+
+   This chunk is used only during the initialization of an association.
+   It is sent by the initiator of an association to its peer to complete
+   the initialization process.  This chunk MUST precede any DATA chunk
+   sent within the association, but MAY be bundled with one or more DATA
+   chunks in the same packet.
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |   Type = 10   |Chunk  Flags   |         Length                |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       /                     Cookie                                    /
+       \                                                               \
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   Chunk Flags: 8 bit
+
+      Set to 0 on transmit and ignored on receipt.
+
+   Length: 16 bits (unsigned integer)
+
+      Set to the size of the chunk in bytes, including the 4 bytes of
+      the chunk header and the size of the cookie.
+
+
+
+
+
+Stewart                     Standards Track                    [Page 50]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   Cookie: variable size
+
+      This field must contain the exact cookie received in the State
+      Cookie parameter from the previous INIT ACK.
+
+      An implementation SHOULD make the cookie as small as possible to
+      ensure interoperability.
+
+      Note: A Cookie Echo does NOT contain a State Cookie parameter;
+      instead, the data within the State Cookie's Parameter Value
+      becomes the data within the Cookie Echo's Chunk Value.  This
+      allows an implementation to change only the first 2 bytes of the
+      State Cookie parameter to become a COOKIE ECHO chunk.
+
+3.3.12.  Cookie Acknowledgement (COOKIE ACK) (11)
+
+   This chunk is used only during the initialization of an association.
+   It is used to acknowledge the receipt of a COOKIE ECHO chunk.  This
+   chunk MUST precede any DATA or SACK chunk sent within the
+   association, but MAY be bundled with one or more DATA chunks or SACK
+   chunk's in the same SCTP packet.
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |   Type = 11   |Chunk  Flags   |     Length = 4                |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   Chunk Flags: 8 bits
+
+      Set to 0 on transmit and ignored on receipt.
+
+3.3.13.  Shutdown Complete (SHUTDOWN COMPLETE) (14)
+
+   This chunk MUST be used to acknowledge the receipt of the SHUTDOWN
+   ACK chunk at the completion of the shutdown process; see Section 9.2
+   for details.
+
+   The SHUTDOWN COMPLETE chunk has no parameters.
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |   Type = 14   |Reserved     |T|      Length = 4               |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   Chunk Flags: 8 bits
+
+
+
+
+Stewart                     Standards Track                    [Page 51]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+      Reserved: 7 bits
+
+         Set to 0 on transmit and ignored on receipt.
+
+         T bit: 1 bit
+
+      The T bit is set to 0 if the sender filled in the Verification Tag
+      expected by the peer.  If the Verification Tag is reflected, the T
+      bit MUST be set to 1.  Reflecting means that the sent Verification
+      Tag is the same as the received one.
+
+   Note: Special rules apply to this chunk for verification, please see
+   Section 8.5.1 for details.
+
+4.  SCTP Association State Diagram
+
+   During the life time of an SCTP association, the SCTP endpoint's
+   association progresses from one state to another in response to
+   various events.  The events that may potentially advance an
+   association's state include:
+
+   o  SCTP user primitive calls, e.g., [ASSOCIATE], [SHUTDOWN], [ABORT],
+
+   o  Reception of INIT, COOKIE ECHO, ABORT, SHUTDOWN, etc., control
+      chunks, or
+
+   o  Some timeout events.
+
+   The state diagram in the figures below illustrates state changes,
+   together with the causing events and resulting actions.  Note that
+   some of the error conditions are not shown in the state diagram.
+   Full descriptions of all special cases are found in the text.
+
+   Note: Chunk names are given in all capital letters, while parameter
+   names have the first letter capitalized, e.g., COOKIE ECHO chunk type
+   vs. State Cookie parameter.  If more than one event/message can occur
+   that causes a state transition, it is labeled (A), (B), etc.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart                     Standards Track                    [Page 52]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+                      -----          -------- (from any state)
+                    /       \      /  rcv ABORT      [ABORT]
+   rcv INIT        |         |    |   ----------  or ----------
+   --------------- |         v    v   delete TCB     snd ABORT
+   generate Cookie  \    +---------+                 delete TCB
+   snd INIT ACK       ---|  CLOSED |
+                         +---------+
+                          /      \      [ASSOCIATE]
+                         /        \     ---------------
+                        |          |    create TCB
+                        |          |    snd INIT
+                        |          |    strt init timer
+         rcv valid      |          |
+       COOKIE  ECHO     |          v
+   (1) ---------------- |      +------------+
+       create TCB       |      | COOKIE-WAIT| (2)
+       snd COOKIE ACK   |      +------------+
+                        |          |
+                        |          |    rcv INIT ACK
+                        |          |    -----------------
+                        |          |    snd COOKIE ECHO
+                        |          |    stop init timer
+                        |          |    strt cookie timer
+                        |          v
+                        |      +--------------+
+                        |      | COOKIE-ECHOED| (3)
+                        |      +--------------+
+                        |          |
+                        |          |    rcv COOKIE ACK
+                        |          |    -----------------
+                        |          |    stop cookie timer
+                        v          v
+                      +---------------+
+                      |  ESTABLISHED  |
+                      +---------------+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart                     Standards Track                    [Page 53]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+                    (from the ESTABLISHED state only)
+                                  |
+                                  |
+                         /--------+--------\
+     [SHUTDOWN]         /                   \
+     -------------------|                   |
+     check outstanding  |                   |
+     DATA chunks        |                   |
+                        v                   |
+                   +---------+              |
+                   |SHUTDOWN-|              | rcv SHUTDOWN
+                   |PENDING  |              |------------------
+                   +---------+              | check outstanding
+                        |                   | DATA chunks
+   No more outstanding  |                   |
+   ---------------------|                   |
+   snd SHUTDOWN         |                   |
+   strt shutdown timer  |                   |
+                        v                   v
+                   +---------+        +-----------+
+               (4) |SHUTDOWN-|        | SHUTDOWN- |  (5,6)
+                   |SENT     |        | RECEIVED  |
+                   +---------+        +-----------+
+                        |  \                |
+   (A) rcv SHUTDOWN ACK  |   \               |
+   ----------------------|    \              |
+   stop shutdown timer   |     \rcv:SHUTDOWN |
+   send SHUTDOWN COMPLETE|      \  (B)       |
+   delete TCB            |       \           |
+                         |        \          | No more outstanding
+                         |         \         |-----------------
+                         |          \        | send SHUTDOWN ACK
+   (B)rcv SHUTDOWN       |           \       | strt shutdown timer
+   ----------------------|            \      |
+   send SHUTDOWN ACK     |             \     |
+   start shutdown timer  |              \    |
+   move to SHUTDOWN-     |               \   |
+   ACK-SENT              |                |  |
+                         |                v  |
+                         |             +-----------+
+                         |             | SHUTDOWN- | (7)
+                         |             | ACK-SENT  |
+                         |             +----------+-
+                         |                   | (C)rcv SHUTDOWN COMPLETE
+                         |                   |-----------------
+                         |                   | stop shutdown timer
+                         |                   | delete TCB
+                         |                   |
+
+
+
+Stewart                     Standards Track                    [Page 54]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+                         |                   | (D)rcv SHUTDOWN ACK
+                         |                   |--------------
+                         |                   | stop shutdown timer
+                         |                   | send SHUTDOWN COMPLETE
+                         |                   | delete TCB
+                         |                   |
+                         \    +---------+    /
+                          \-->| CLOSED  |<--/
+                              +---------+
+
+                Figure 3: State Transition Diagram of SCTP
+
+   Notes:
+
+   1)  If the State Cookie in the received COOKIE ECHO is invalid (i.e.,
+       failed to pass the integrity check), the receiver MUST silently
+       discard the packet.  Or, if the received State Cookie is expired
+       (see Section 5.1.5), the receiver MUST send back an ERROR chunk.
+       In either case, the receiver stays in the CLOSED state.
+
+   2)  If the T1-init timer expires, the endpoint MUST retransmit INIT
+       and restart the T1-init timer without changing state.  This MUST
+       be repeated up to 'Max.Init.Retransmits' times.  After that, the
+       endpoint MUST abort the initialization process and report the
+       error to the SCTP user.
+
+   3)  If the T1-cookie timer expires, the endpoint MUST retransmit
+       COOKIE ECHO and restart the T1-cookie timer without changing
+       state.  This MUST be repeated up to 'Max.Init.Retransmits' times.
+       After that, the endpoint MUST abort the initialization process
+       and report the error to the SCTP user.
+
+   4)  In the SHUTDOWN-SENT state, the endpoint MUST acknowledge any
+       received DATA chunks without delay.
+
+   5)  In the SHUTDOWN-RECEIVED state, the endpoint MUST NOT accept any
+       new send requests from its SCTP user.
+
+   6)  In the SHUTDOWN-RECEIVED state, the endpoint MUST transmit or
+       retransmit data and leave this state when all data in queue is
+       transmitted.
+
+   7)  In the SHUTDOWN-ACK-SENT state, the endpoint MUST NOT accept any
+       new send requests from its SCTP user.
+
+   The CLOSED state is used to indicate that an association is not
+   created (i.e., doesn't exist).
+
+
+
+
+Stewart                     Standards Track                    [Page 55]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+5.  Association Initialization
+
+   Before the first data transmission can take place from one SCTP
+   endpoint ("A") to another SCTP endpoint ("Z"), the two endpoints must
+   complete an initialization process in order to set up an SCTP
+   association between them.
+
+   The SCTP user at an endpoint should use the ASSOCIATE primitive to
+   initialize an SCTP association to another SCTP endpoint.
+
+   IMPLEMENTATION NOTE: From an SCTP user's point of view, an
+   association may be implicitly opened, without an ASSOCIATE primitive
+   (see Section 10.1 B) being invoked, by the initiating endpoint's
+   sending of the first user data to the destination endpoint.  The
+   initiating SCTP will assume default values for all mandatory and
+   optional parameters for the INIT/INIT ACK.
+
+   Once the association is established, unidirectional streams are open
+   for data transfer on both ends (see Section 5.1.1).
+
+5.1.  Normal Establishment of an Association
+
+   The initialization process consists of the following steps (assuming
+   that SCTP endpoint "A" tries to set up an association with SCTP
+   endpoint "Z" and "Z" accepts the new association):
+
+   A) "A" first sends an INIT chunk to "Z".  In the INIT, "A" must
+      provide its Verification Tag (Tag_A) in the Initiate Tag field.
+      Tag_A SHOULD be a random number in the range of 1 to 4294967295
+      (see Section 5.3.1 for Tag value selection).  After sending the
+      INIT, "A" starts the T1-init timer and enters the COOKIE-WAIT
+      state.
+
+   B) "Z" shall respond immediately with an INIT ACK chunk.  The
+      destination IP address of the INIT ACK MUST be set to the source
+      IP address of the INIT to which this INIT ACK is responding.  In
+      the response, besides filling in other parameters, "Z" must set
+      the Verification Tag field to Tag_A, and also provide its own
+      Verification Tag (Tag_Z) in the Initiate Tag field.
+
+      Moreover, "Z" MUST generate and send along with the INIT ACK a
+      State Cookie.  See Section 5.1.3 for State Cookie generation.
+
+      Note: After sending out INIT ACK with the State Cookie parameter,
+      "Z" MUST NOT allocate any resources or keep any states for the new
+      association.  Otherwise, "Z" will be vulnerable to resource
+      attacks.
+
+
+
+
+Stewart                     Standards Track                    [Page 56]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   C) Upon reception of the INIT ACK from "Z", "A" shall stop the T1-
+      init timer and leave the COOKIE-WAIT state.  "A" shall then send
+      the State Cookie received in the INIT ACK chunk in a COOKIE ECHO
+      chunk, start the T1-cookie timer, and enter the COOKIE-ECHOED
+      state.
+
+      Note: The COOKIE ECHO chunk can be bundled with any pending
+      outbound DATA chunks, but it MUST be the first chunk in the packet
+      and until the COOKIE ACK is returned the sender MUST NOT send any
+      other packets to the peer.
+
+   D) Upon reception of the COOKIE ECHO chunk, endpoint "Z" will reply
+      with a COOKIE ACK chunk after building a TCB and moving to the
+      ESTABLISHED state.  A COOKIE ACK chunk may be bundled with any
+      pending DATA chunks (and/or SACK chunks), but the COOKIE ACK chunk
+      MUST be the first chunk in the packet.
+
+      IMPLEMENTATION NOTE: An implementation may choose to send the
+      Communication Up notification to the SCTP user upon reception of a
+      valid COOKIE ECHO chunk.
+
+   E) Upon reception of the COOKIE ACK, endpoint "A" will move from the
+      COOKIE-ECHOED state to the ESTABLISHED state, stopping the T1-
+      cookie timer.  It may also notify its ULP about the successful
+      establishment of the association with a Communication Up
+      notification (see Section 10).
+
+   An INIT or INIT ACK chunk MUST NOT be bundled with any other chunk.
+   They MUST be the only chunks present in the SCTP packets that carry
+   them.
+
+   An endpoint MUST send the INIT ACK to the IP address from which it
+   received the INIT.
+
+   Note: T1-init timer and T1-cookie timer shall follow the same rules
+   given in Section 6.3.
+
+   If an endpoint receives an INIT, INIT ACK, or COOKIE ECHO chunk but
+   decides not to establish the new association due to missing mandatory
+   parameters in the received INIT or INIT ACK, invalid parameter
+   values, or lack of local resources, it SHOULD respond with an ABORT
+   chunk.  It SHOULD also specify the cause of abort, such as the type
+   of the missing mandatory parameters, etc., by including the error
+   cause parameters with the ABORT chunk.  The Verification Tag field in
+   the common header of the outbound SCTP packet containing the ABORT
+   chunk MUST be set to the Initiate Tag value of the peer.
+
+
+
+
+
+Stewart                     Standards Track                    [Page 57]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   Note that a COOKIE ECHO chunk that does NOT pass the integrity check
+   is NOT considered an 'invalid parameter' and requires special
+   handling; see Section 5.1.5.
+
+   After the reception of the first DATA chunk in an association the
+   endpoint MUST immediately respond with a SACK to acknowledge the DATA
+   chunk.  Subsequent acknowledgements should be done as described in
+   Section 6.2.
+
+   When the TCB is created, each endpoint MUST set its internal
+   Cumulative TSN Ack Point to the value of its transmitted Initial TSN
+   minus one.
+
+   IMPLEMENTATION NOTE: The IP addresses and SCTP port are generally
+   used as the key to find the TCB within an SCTP instance.
+
+5.1.1.  Handle Stream Parameters
+
+   In the INIT and INIT ACK chunks, the sender of the chunk MUST
+   indicate the number of outbound streams (OSs) it wishes to have in
+   the association, as well as the maximum inbound streams (MISs) it
+   will accept from the other endpoint.
+
+   After receiving the stream configuration information from the other
+   side, each endpoint MUST perform the following check: If the peer's
+   MIS is less than the endpoint's OS, meaning that the peer is
+   incapable of supporting all the outbound streams the endpoint wants
+   to configure, the endpoint MUST use MIS outbound streams and MAY
+   report any shortage to the upper layer.  The upper layer can then
+   choose to abort the association if the resource shortage is
+   unacceptable.
+
+   After the association is initialized, the valid outbound stream
+   identifier range for either endpoint shall be 0 to min(local OS,
+   remote MIS)-1.
+
+5.1.2.  Handle Address Parameters
+
+   During the association initialization, an endpoint shall use the
+   following rules to discover and collect the destination transport
+   address(es) of its peer.
+
+   A) If there are no address parameters present in the received INIT or
+      INIT ACK chunk, the endpoint shall take the source IP address from
+      which the chunk arrives and record it, in combination with the
+      SCTP source port number, as the only destination transport address
+      for this peer.
+
+
+
+
+Stewart                     Standards Track                    [Page 58]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   B) If there is a Host Name parameter present in the received INIT or
+      INIT ACK chunk, the endpoint shall resolve that host name to a
+      list of IP address(es) and derive the transport address(es) of
+      this peer by combining the resolved IP address(es) with the SCTP
+      source port.
+
+      The endpoint MUST ignore any other IP Address parameters if they
+      are also present in the received INIT or INIT ACK chunk.
+
+      The time at which the receiver of an INIT resolves the host name
+      has potential security implications to SCTP.  If the receiver of
+      an INIT resolves the host name upon the reception of the chunk,
+      and the mechanism the receiver uses to resolve the host name
+      involves potential long delay (e.g., DNS query), the receiver may
+      open itself up to resource attacks for the period of time while it
+      is waiting for the name resolution results before it can build the
+      State Cookie and release local resources.
+
+      Therefore, in cases where the name translation involves potential
+      long delay, the receiver of the INIT MUST postpone the name
+      resolution till the reception of the COOKIE ECHO chunk from the
+      peer.  In such a case, the receiver of the INIT SHOULD build the
+      State Cookie using the received Host Name (instead of destination
+      transport addresses) and send the INIT ACK to the source IP
+      address from which the INIT was received.
+
+      The receiver of an INIT ACK shall always immediately attempt to
+      resolve the name upon the reception of the chunk.
+
+      The receiver of the INIT or INIT ACK MUST NOT send user data
+      (piggy-backed or stand-alone) to its peer until the host name is
+      successfully resolved.
+
+      If the name resolution is not successful, the endpoint MUST
+      immediately send an ABORT with "Unresolvable Address" error cause
+      to its peer.  The ABORT shall be sent to the source IP address
+      from which the last peer packet was received.
+
+   C) If there are only IPv4/IPv6 addresses present in the received INIT
+      or INIT ACK chunk, the receiver MUST derive and record all the
+      transport addresses from the received chunk AND the source IP
+      address that sent the INIT or INIT ACK.  The transport addresses
+      are derived by the combination of SCTP source port (from the
+      common header) and the IP Address parameter(s) carried in the INIT
+      or INIT ACK chunk and the source IP address of the IP datagram.
+      The receiver should use only these transport addresses as
+      destination transport addresses when sending subsequent packets to
+      its peer.
+
+
+
+Stewart                     Standards Track                    [Page 59]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   D) An INIT or INIT ACK chunk MUST be treated as belonging to an
+      already established association (or one in the process of being
+      established) if the use of any of the valid address parameters
+      contained within the chunk would identify an existing TCB.
+
+   IMPLEMENTATION NOTE: In some cases (e.g., when the implementation
+   doesn't control the source IP address that is used for transmitting),
+   an endpoint might need to include in its INIT or INIT ACK all
+   possible IP addresses from which packets to the peer could be
+   transmitted.
+
+   After all transport addresses are derived from the INIT or INIT ACK
+   chunk using the above rules, the endpoint shall select one of the
+   transport addresses as the initial primary path.
+
+   Note: The INIT ACK MUST be sent to the source address of the INIT.
+
+   The sender of INIT may include a 'Supported Address Types' parameter
+   in the INIT to indicate what types of address are acceptable.  When
+   this parameter is present, the receiver of INIT (initiate) MUST
+   either use one of the address types indicated in the Supported
+   Address Types parameter when responding to the INIT, or abort the
+   association with an "Unresolvable Address" error cause if it is
+   unwilling or incapable of using any of the address types indicated by
+   its peer.
+
+   IMPLEMENTATION NOTE: In the case that the receiver of an INIT ACK
+   fails to resolve the address parameter due to an unsupported type, it
+   can abort the initiation process and then attempt a reinitiation by
+   using a 'Supported Address Types' parameter in the new INIT to
+   indicate what types of address it prefers.
+
+   IMPLEMENTATION NOTE: If an SCTP endpoint that only supports either
+   IPv4 or IPv6 receives IPv4 and IPv6 addresses in an INIT or INIT ACK
+   chunk from its peer, it MUST use all the addresses belonging to the
+   supported address family.  The other addresses MAY be ignored.  The
+   endpoint SHOULD NOT respond with any kind of error indication.
+
+   IMPLEMENTATION NOTE: If an SCTP endpoint lists in the 'Supported
+   Address Types' parameter either IPv4 or IPv6, but uses the other
+   family for sending the packet containing the INIT chunk, or if it
+   also lists addresses of the other family in the INIT chunk, then the
+   address family that is not listed in the 'Supported Address Types'
+   parameter SHOULD also be considered as supported by the receiver of
+   the INIT chunk.  The receiver of the INIT chunk SHOULD NOT respond
+   with any kind of error indication.
+
+
+
+
+
+Stewart                     Standards Track                    [Page 60]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+5.1.3.  Generating State Cookie
+
+   When sending an INIT ACK as a response to an INIT chunk, the sender
+   of INIT ACK creates a State Cookie and sends it in the State Cookie
+   parameter of the INIT ACK.  Inside this State Cookie, the sender
+   should include a MAC (see [RFC2104] for an example), a timestamp on
+   when the State Cookie is created, and the lifespan of the State
+   Cookie, along with all the information necessary for it to establish
+   the association.
+
+   The following steps SHOULD be taken to generate the State Cookie:
+
+   1)  Create an association TCB using information from both the
+       received INIT and the outgoing INIT ACK chunk,
+
+   2)  In the TCB, set the creation time to the current time of day, and
+       the lifespan to the protocol parameter 'Valid.Cookie.Life' (see
+       Section 15),
+
+   3)  From the TCB, identify and collect the minimal subset of
+       information needed to re-create the TCB, and generate a MAC using
+       this subset of information and a secret key (see [RFC2104] for an
+       example of generating a MAC), and
+
+   4)  Generate the State Cookie by combining this subset of information
+       and the resultant MAC.
+
+   After sending the INIT ACK with the State Cookie parameter, the
+   sender SHOULD delete the TCB and any other local resource related to
+   the new association, so as to prevent resource attacks.
+
+   The hashing method used to generate the MAC is strictly a private
+   matter for the receiver of the INIT chunk.  The use of a MAC is
+   mandatory to prevent denial-of-service attacks.  The secret key
+   SHOULD be random ([RFC4086] provides some information on randomness
+   guidelines); it SHOULD be changed reasonably frequently, and the
+   timestamp in the State Cookie MAY be used to determine which key
+   should be used to verify the MAC.
+
+   An implementation SHOULD make the cookie as small as possible to
+   ensure interoperability.
+
+
+
+
+
+
+
+
+
+
+Stewart                     Standards Track                    [Page 61]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+5.1.4.  State Cookie Processing
+
+   When an endpoint (in the COOKIE-WAIT state) receives an INIT ACK
+   chunk with a State Cookie parameter, it MUST immediately send a
+   COOKIE ECHO chunk to its peer with the received State Cookie.  The
+   sender MAY also add any pending DATA chunks to the packet after the
+   COOKIE ECHO chunk.
+
+   The endpoint shall also start the T1-cookie timer after sending out
+   the COOKIE ECHO chunk.  If the timer expires, the endpoint shall
+   retransmit the COOKIE ECHO chunk and restart the T1-cookie timer.
+   This is repeated until either a COOKIE ACK is received or
+   'Max.Init.Retransmits' (see Section 15) is reached causing the peer
+   endpoint to be marked unreachable (and thus the association enters
+   the CLOSED state).
+
+5.1.5.  State Cookie Authentication
+
+   When an endpoint receives a COOKIE ECHO chunk from another endpoint
+   with which it has no association, it shall take the following
+   actions:
+
+   1)  Compute a MAC using the TCB data carried in the State Cookie and
+       the secret key (note the timestamp in the State Cookie MAY be
+       used to determine which secret key to use).  [RFC2104] can be
+       used as a guideline for generating the MAC,
+
+   2)  Authenticate the State Cookie as one that it previously generated
+       by comparing the computed MAC against the one carried in the
+       State Cookie.  If this comparison fails, the SCTP packet,
+       including the COOKIE ECHO and any DATA chunks, should be silently
+       discarded,
+
+   3)  Compare the port numbers and the Verification Tag contained
+       within the COOKIE ECHO chunk to the actual port numbers and the
+       Verification Tag within the SCTP common header of the received
+       packet.  If these values do not match, the packet MUST be
+       silently discarded.
+
+   4)  Compare the creation timestamp in the State Cookie to the current
+       local time.  If the elapsed time is longer than the lifespan
+       carried in the State Cookie, then the packet, including the
+       COOKIE ECHO and any attached DATA chunks, SHOULD be discarded,
+       and the endpoint MUST transmit an ERROR chunk with a "Stale
+       Cookie" error cause to the peer endpoint.
+
+
+
+
+
+
+Stewart                     Standards Track                    [Page 62]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   5)  If the State Cookie is valid, create an association to the sender
+       of the COOKIE ECHO chunk with the information in the TCB data
+       carried in the COOKIE ECHO and enter the ESTABLISHED state.
+
+   6)  Send a COOKIE ACK chunk to the peer acknowledging receipt of the
+       COOKIE ECHO.  The COOKIE ACK MAY be bundled with an outbound DATA
+       chunk or SACK chunk; however, the COOKIE ACK MUST be the first
+       chunk in the SCTP packet.
+
+   7)  Immediately acknowledge any DATA chunk bundled with the COOKIE
+       ECHO with a SACK (subsequent DATA chunk acknowledgement should
+       follow the rules defined in Section 6.2).  As mentioned in step
+       6, if the SACK is bundled with the COOKIE ACK, the COOKIE ACK
+       MUST appear first in the SCTP packet.
+
+   If a COOKIE ECHO is received from an endpoint with which the receiver
+   of the COOKIE ECHO has an existing association, the procedures in
+   Section 5.2 should be followed.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart                     Standards Track                    [Page 63]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+5.1.6.  An Example of Normal Association Establishment
+
+   In the following example, "A" initiates the association and then
+   sends a user message to "Z", then "Z" sends two user messages to "A"
+   later (assuming no bundling or fragmentation occurs):
+
+    Endpoint A                                          Endpoint Z
+    {app sets association with Z}
+    (build TCB)
+    INIT [I-Tag=Tag_A
+          & other info]  ------\
+    (Start T1-init timer)       \
+    (Enter COOKIE-WAIT state)    \---> (compose temp TCB and Cookie_Z)
+                                    /-- INIT ACK [Veri Tag=Tag_A,
+                                   /             I-Tag=Tag_Z,
+    (Cancel T1-init timer) <------/              Cookie_Z, & other info]
+                                         (destroy temp TCB)
+    COOKIE ECHO [Cookie_Z] ------\
+    (Start T1-init timer)         \
+    (Enter COOKIE-ECHOED state)    \---> (build TCB enter ESTABLISHED
+                                          state)
+                                   /---- COOKIE-ACK
+                                  /
+    (Cancel T1-init timer, <-----/
+     Enter ESTABLISHED state)
+    {app sends 1st user data; strm 0}
+    DATA [TSN=initial TSN_A
+        Strm=0,Seq=0 & user data]--\
+    (Start T3-rtx timer)            \
+                                     \->
+                                   /----- SACK [TSN Ack=init
+                                  /           TSN_A,Block=0]
+    (Cancel T3-rtx timer) <------/
+                                          ...
+                                         {app sends 2 messages;strm 0}
+                                   /---- DATA
+                                  /        [TSN=init TSN_Z
+                              <--/          Strm=0,Seq=0 & user data 1]
+    SACK [TSN Ack=init TSN_Z,      /---- DATA
+          Block=0]     --------\  /        [TSN=init TSN_Z +1,
+                                \/          Strm=0,Seq=1 & user data 2]
+                         <------/\
+                                  \
+                                   \------>
+
+                        Figure 4: INITIATION Example
+
+
+
+
+
+Stewart                     Standards Track                    [Page 64]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   If the T1-init timer expires at "A" after the INIT or COOKIE ECHO
+   chunks are sent, the same INIT or COOKIE ECHO chunk with the same
+   Initiate Tag (i.e., Tag_A) or State Cookie shall be retransmitted and
+   the timer restarted.  This shall be repeated Max.Init.Retransmits
+   times before "A" considers "Z" unreachable and reports the failure to
+   its upper layer (and thus the association enters the CLOSED state).
+
+   When retransmitting the INIT, the endpoint MUST follow the rules
+   defined in Section 6.3 to determine the proper timer value.
+
+5.2.  Handle Duplicate or Unexpected INIT, INIT ACK, COOKIE ECHO, and
+      COOKIE ACK
+
+   During the life time of an association (in one of the possible
+   states), an endpoint may receive from its peer endpoint one of the
+   setup chunks (INIT, INIT ACK, COOKIE ECHO, and COOKIE ACK).  The
+   receiver shall treat such a setup chunk as a duplicate and process it
+   as described in this section.
+
+   Note: An endpoint will not receive the chunk unless the chunk was
+   sent to an SCTP transport address and is from an SCTP transport
+   address associated with this endpoint.  Therefore, the endpoint
+   processes such a chunk as part of its current association.
+
+   The following scenarios can cause duplicated or unexpected chunks:
+
+   A) The peer has crashed without being detected, restarted itself, and
+      sent out a new INIT chunk trying to restore the association,
+
+   B) Both sides are trying to initialize the association at about the
+      same time,
+
+   C) The chunk is from a stale packet that was used to establish the
+      present association or a past association that is no longer in
+      existence,
+
+   D) The chunk is a false packet generated by an attacker, or
+
+   E) The peer never received the COOKIE ACK and is retransmitting its
+      COOKIE ECHO.
+
+   The rules in the following sections shall be applied in order to
+   identify and correctly handle these cases.
+
+
+
+
+
+
+
+
+Stewart                     Standards Track                    [Page 65]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+5.2.1.  INIT Received in COOKIE-WAIT or COOKIE-ECHOED State (Item B)
+
+   This usually indicates an initialization collision, i.e., each
+   endpoint is attempting, at about the same time, to establish an
+   association with the other endpoint.
+
+   Upon receipt of an INIT in the COOKIE-WAIT state, an endpoint MUST
+   respond with an INIT ACK using the same parameters it sent in its
+   original INIT chunk (including its Initiate Tag, unchanged).  When
+   responding, the endpoint MUST send the INIT ACK back to the same
+   address that the original INIT (sent by this endpoint) was sent.
+
+   Upon receipt of an INIT in the COOKIE-ECHOED state, an endpoint MUST
+   respond with an INIT ACK using the same parameters it sent in its
+   original INIT chunk (including its Initiate Tag, unchanged), provided
+   that no NEW address has been added to the forming association.  If
+   the INIT message indicates that a new address has been added to the
+   association, then the entire INIT MUST be discarded, and NO changes
+   should be made to the existing association.  An ABORT SHOULD be sent
+   in response that MAY include the error 'Restart of an association
+   with new addresses'.  The error SHOULD list the addresses that were
+   added to the restarting association.
+
+   When responding in either state (COOKIE-WAIT or COOKIE-ECHOED) with
+   an INIT ACK, the original parameters are combined with those from the
+   newly received INIT chunk.  The endpoint shall also generate a State
+   Cookie with the INIT ACK.  The endpoint uses the parameters sent in
+   its INIT to calculate the State Cookie.
+
+   After that, the endpoint MUST NOT change its state, the T1-init timer
+   shall be left running, and the corresponding TCB MUST NOT be
+   destroyed.  The normal procedures for handling State Cookies when a
+   TCB exists will resolve the duplicate INITs to a single association.
+
+   For an endpoint that is in the COOKIE-ECHOED state, it MUST populate
+   its Tie-Tags within both the association TCB and inside the State
+   Cookie (see Section 5.2.2 for a description of the Tie-Tags).
+
+5.2.2.  Unexpected INIT in States Other than CLOSED, COOKIE-ECHOED,
+        COOKIE-WAIT, and SHUTDOWN-ACK-SENT
+
+   Unless otherwise stated, upon receipt of an unexpected INIT for this
+   association, the endpoint shall generate an INIT ACK with a State
+   Cookie.  Before responding, the endpoint MUST check to see if the
+   unexpected INIT adds new addresses to the association.  If new
+   addresses are added to the association, the endpoint MUST respond
+   with an ABORT, copying the 'Initiate Tag' of the unexpected INIT into
+   the 'Verification Tag' of the outbound packet carrying the ABORT.  In
+
+
+
+Stewart                     Standards Track                    [Page 66]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   the ABORT response, the cause of error MAY be set to 'restart of an
+   association with new addresses'.  The error SHOULD list the addresses
+   that were added to the restarting association.  If no new addresses
+   are added, when responding to the INIT in the outbound INIT ACK, the
+   endpoint MUST copy its current Tie-Tags to a reserved place within
+   the State Cookie and the association's TCB.  We shall refer to these
+   locations inside the cookie as the Peer's-Tie-Tag and the Local-Tie-
+   Tag.  We will refer to the copy within an association's TCB as the
+   Local Tag and Peer's Tag.  The outbound SCTP packet containing this
+   INIT ACK MUST carry a Verification Tag value equal to the Initiate
+   Tag found in the unexpected INIT.  And the INIT ACK MUST contain a
+   new Initiate Tag (randomly generated; see Section 5.3.1).  Other
+   parameters for the endpoint SHOULD be copied from the existing
+   parameters of the association (e.g., number of outbound streams) into
+   the INIT ACK and cookie.
+
+   After sending out the INIT ACK or ABORT, the endpoint shall take no
+   further actions; i.e., the existing association, including its
+   current state, and the corresponding TCB MUST NOT be changed.
+
+   Note: Only when a TCB exists and the association is not in a COOKIE-
+   WAIT or SHUTDOWN-ACK-SENT state are the Tie-Tags populated with a
+   value other than 0.  For a normal association INIT (i.e., the
+   endpoint is in the CLOSED state), the Tie-Tags MUST be set to 0
+   (indicating that no previous TCB existed).
+
+5.2.3.  Unexpected INIT ACK
+
+   If an INIT ACK is received by an endpoint in any state other than the
+   COOKIE-WAIT state, the endpoint should discard the INIT ACK chunk.
+   An unexpected INIT ACK usually indicates the processing of an old or
+   duplicated INIT chunk.
+
+5.2.4.  Handle a COOKIE ECHO when a TCB Exists
+
+   When a COOKIE ECHO chunk is received by an endpoint in any state for
+   an existing association (i.e., not in the CLOSED state) the following
+   rules shall be applied:
+
+   1)  Compute a MAC as described in step 1 of Section 5.1.5,
+
+   2)  Authenticate the State Cookie as described in step 2 of Section
+       5.1.5 (this is case C or D above).
+
+   3)  Compare the timestamp in the State Cookie to the current time.
+       If the State Cookie is older than the lifespan carried in the
+       State Cookie and the Verification Tags contained in the State
+       Cookie do not match the current association's Verification Tags,
+
+
+
+Stewart                     Standards Track                    [Page 67]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+       the packet, including the COOKIE ECHO and any DATA chunks, should
+       be discarded.  The endpoint also MUST transmit an ERROR chunk
+       with a "Stale Cookie" error cause to the peer endpoint (this is
+       case C or D in Section 5.2).
+
+       If both Verification Tags in the State Cookie match the
+       Verification Tags of the current association, consider the State
+       Cookie valid (this is case E in Section 5.2) even if the lifespan
+       is exceeded.
+
+   4)  If the State Cookie proves to be valid, unpack the TCB into a
+       temporary TCB.
+
+   5)  Refer to Table 2 to determine the correct action to be taken.
+
++------------+------------+---------------+--------------+-------------+
+|  Local Tag | Peer's Tag | Local-Tie-Tag |Peer's-Tie-Tag|   Action/   |
+|            |            |               |              | Description |
++------------+------------+---------------+--------------+-------------+
+|    X       |     X      |      M        |      M       |     (A)     |
++------------+------------+---------------+--------------+-------------+
+|    M       |     X      |      A        |      A       |     (B)     |
++------------+------------+---------------+--------------+-------------+
+|    M       |     0      |      A        |      A       |     (B)     |
++------------+------------+---------------+--------------+-------------+
+|    X       |     M      |      0        |      0       |     (C)     |
++------------+------------+---------------+--------------+-------------+
+|    M       |     M      |      A        |      A       |     (D)     |
++======================================================================+
+|       Table 2: Handling of a COOKIE ECHO when a TCB Exists           |
++======================================================================+
+
+   Legend:
+
+      X - Tag does not match the existing TCB.
+      M - Tag matches the existing TCB.
+      0 - No Tie-Tag in cookie (unknown).
+      A - All cases, i.e., M, X, or 0.
+
+   Note: For any case not shown in Table 2, the cookie should be
+   silently discarded.
+
+   Action
+
+   A) In this case, the peer may have restarted.  When the endpoint
+      recognizes this potential 'restart', the existing session is
+      treated the same as if it received an ABORT followed by a new
+      COOKIE ECHO with the following exceptions:
+
+
+
+Stewart                     Standards Track                    [Page 68]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+      -  Any SCTP DATA chunks MAY be retained (this is an
+         implementation-specific option).
+
+      -  A notification of RESTART SHOULD be sent to the ULP instead of
+         a "COMMUNICATION LOST" notification.
+
+      All the congestion control parameters (e.g., cwnd, ssthresh)
+      related to this peer MUST be reset to their initial values (see
+      Section 6.2.1).
+
+      After this, the endpoint shall enter the ESTABLISHED state.
+
+      If the endpoint is in the SHUTDOWN-ACK-SENT state and recognizes
+      that the peer has restarted (Action A), it MUST NOT set up a new
+      association but instead resend the SHUTDOWN ACK and send an ERROR
+      chunk with a "Cookie Received While Shutting Down" error cause to
+      its peer.
+
+   B) In this case, both sides may be attempting to start an association
+      at about the same time, but the peer endpoint started its INIT
+      after responding to the local endpoint's INIT.  Thus, it may have
+      picked a new Verification Tag, not being aware of the previous tag
+      it had sent this endpoint.  The endpoint should stay in or enter
+      the ESTABLISHED state, but it MUST update its peer's Verification
+      Tag from the State Cookie, stop any init or cookie timers that may
+      be running, and send a COOKIE ACK.
+
+   C) In this case, the local endpoint's cookie has arrived late.
+      Before it arrived, the local endpoint sent an INIT and received an
+      INIT ACK and finally sent a COOKIE ECHO with the peer's same tag
+      but a new tag of its own.  The cookie should be silently
+      discarded.  The endpoint SHOULD NOT change states and should leave
+      any timers running.
+
+   D) When both local and remote tags match, the endpoint should enter
+      the ESTABLISHED state, if it is in the COOKIE-ECHOED state.  It
+      should stop any cookie timer that may be running and send a COOKIE
+      ACK.
+
+   Note: The "peer's Verification Tag" is the tag received in the
+   Initiate Tag field of the INIT or INIT ACK chunk.
+
+5.2.4.1.  An Example of a Association Restart
+
+   In the following example, "A" initiates the association after a
+   restart has occurred.  Endpoint "Z" had no knowledge of the restart
+   until the exchange (i.e., Heartbeats had not yet detected the failure
+   of "A") (assuming no bundling or fragmentation occurs):
+
+
+
+Stewart                     Standards Track                    [Page 69]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   Endpoint A                                          Endpoint Z
+   <-------------- Association is established---------------------->
+   Tag=Tag_A                                             Tag=Tag_Z
+   <--------------------------------------------------------------->
+   {A crashes and restarts}
+   {app sets up a association with Z}
+   (build TCB)
+   INIT [I-Tag=Tag_A'
+         & other info]  --------\
+   (Start T1-init timer)         \
+   (Enter COOKIE-WAIT state)      \---> (find an existing TCB
+                                         compose temp TCB and Cookie_Z
+                                         with Tie-Tags to previous
+                                         association)
+                                   /--- INIT ACK [Veri Tag=Tag_A',
+                                  /               I-Tag=Tag_Z',
+   (Cancel T1-init timer) <------/                Cookie_Z[TieTags=
+                                                  Tag_A,Tag_Z
+                                                   & other info]
+                                        (destroy temp TCB,leave original
+                                         in place)
+   COOKIE ECHO [Veri=Tag_Z',
+                Cookie_Z
+                Tie=Tag_A,
+                Tag_Z]----------\
+   (Start T1-init timer)         \
+   (Enter COOKIE-ECHOED state)    \---> (Find existing association,
+                                         Tie-Tags match old tags,
+                                         Tags do not match, i.e.,
+                                         case X X M M above,
+                                         Announce Restart to ULP
+                                         and reset association).
+                                  /---- COOKIE ACK
+   (Cancel T1-init timer, <------/
+    Enter ESTABLISHED state)
+   {app sends 1st user data; strm 0}
+   DATA [TSN=initial TSN_A
+       Strm=0,Seq=0 & user data]--\
+   (Start T3-rtx timer)            \
+                                    \->
+                                 /--- SACK [TSN Ack=init TSN_A,Block=0]
+   (Cancel T3-rtx timer) <------/
+
+                        Figure 5: A Restart Example
+
+
+
+
+
+
+
+Stewart                     Standards Track                    [Page 70]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+5.2.5.  Handle Duplicate COOKIE-ACK.
+
+   At any state other than COOKIE-ECHOED, an endpoint should silently
+   discard a received COOKIE ACK chunk.
+
+5.2.6.  Handle Stale COOKIE Error
+
+   Receipt of an ERROR chunk with a "Stale Cookie" error cause indicates
+   one of a number of possible events:
+
+   A) The association failed to completely setup before the State Cookie
+      issued by the sender was processed.
+
+   B) An old State Cookie was processed after setup completed.
+
+   C) An old State Cookie is received from someone that the receiver is
+      not interested in having an association with and the ABORT chunk
+      was lost.
+
+   When processing an ERROR chunk with a "Stale Cookie" error cause an
+   endpoint should first examine if an association is in the process of
+   being set up, i.e., the association is in the COOKIE-ECHOED state.
+   In all cases, if the association is not in the COOKIE-ECHOED state,
+   the ERROR chunk should be silently discarded.
+
+   If the association is in the COOKIE-ECHOED state, the endpoint may
+   elect one of the following three alternatives.
+
+   1)  Send a new INIT chunk to the endpoint to generate a new State
+       Cookie and reattempt the setup procedure.
+
+   2)  Discard the TCB and report to the upper layer the inability to
+       set up the association.
+
+   3)  Send a new INIT chunk to the endpoint, adding a Cookie
+       Preservative parameter requesting an extension to the life time
+       of the State Cookie.  When calculating the time extension, an
+       implementation SHOULD use the RTT information measured based on
+       the previous COOKIE ECHO / ERROR exchange, and should add no more
+       than 1 second beyond the measured RTT, due to long State Cookie
+       life times making the endpoint more subject to a replay attack.
+
+
+
+
+
+
+
+
+
+
+Stewart                     Standards Track                    [Page 71]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+5.3.  Other Initialization Issues
+
+5.3.1.  Selection of Tag Value
+
+   Initiate Tag values should be selected from the range of 1 to 2**32 -
+   1.  It is very important that the Initiate Tag value be randomized to
+   help protect against "man in the middle" and "sequence number"
+   attacks.  The methods described in [RFC4086] can be used for the
+   Initiate Tag randomization.  Careful selection of Initiate Tags is
+   also necessary to prevent old duplicate packets from previous
+   associations being mistakenly processed as belonging to the current
+   association.
+
+   Moreover, the Verification Tag value used by either endpoint in a
+   given association MUST NOT change during the life time of an
+   association.  A new Verification Tag value MUST be used each time the
+   endpoint tears down and then reestablishes an association to the same
+   peer.
+
+5.4.  Path Verification
+
+   During association establishment, the two peers exchange a list of
+   addresses.  In the predominant case, these lists accurately represent
+   the addresses owned by each peer.  However, it is possible that a
+   misbehaving peer may supply addresses that it does not own.  To
+   prevent this, the following rules are applied to all addresses of the
+   new association:
+
+   1)  Any address passed to the sender of the INIT by its upper layer
+      is automatically considered to be CONFIRMED.
+
+   2)  For the receiver of the COOKIE ECHO, the only CONFIRMED address
+      is the one to which the INIT-ACK was sent.
+
+   3)  All other addresses not covered by rules 1 and 2 are considered
+      UNCONFIRMED and are subject to probing for verification.
+
+   To probe an address for verification, an endpoint will send
+   HEARTBEATs including a 64-bit random nonce and a path indicator (to
+   identify the address that the HEARTBEAT is sent to) within the
+   HEARTBEAT parameter.
+
+   Upon receipt of the HEARTBEAT ACK, a verification is made that the
+   nonce included in the HEARTBEAT parameter is the one sent to the
+   address indicated inside the HEARTBEAT parameter.  When this match
+   occurs, the address that the original HEARTBEAT was sent to is now
+   considered CONFIRMED and available for normal data transfer.
+
+
+
+
+Stewart                     Standards Track                    [Page 72]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   These probing procedures are started when an association moves to the
+   ESTABLISHED state and are ended when all paths are confirmed.
+
+   In each RTO, a probe may be sent on an active UNCONFIRMED path in an
+   attempt to move it to the CONFIRMED state.  If during this probing
+   the path becomes inactive, this rate is lowered to the normal
+   HEARTBEAT rate.  At the expiration of the RTO timer, the error
+   counter of any path that was probed but not CONFIRMED is incremented
+   by one and subjected to path failure detection, as defined in Section
+   8.2.  When probing UNCONFIRMED addresses, however, the association
+   overall error count is NOT incremented.
+
+   The number of HEARTBEATS sent at each RTO SHOULD be limited by the
+   HB.Max.Burst parameter.  It is an implementation decision as to how
+   to distribute HEARTBEATS to the peer's addresses for path
+   verification.
+
+   Whenever a path is confirmed, an indication MAY be given to the upper
+   layer.
+
+   An endpoint MUST NOT send any chunks to an UNCONFIRMED address, with
+   the following exceptions:
+
+   -  A HEARTBEAT including a nonce MAY be sent to an UNCONFIRMED
+      address.
+
+   -  A HEARTBEAT ACK MAY be sent to an UNCONFIRMED address.
+
+   -  A COOKIE ACK MAY be sent to an UNCONFIRMED address, but it MUST be
+      bundled with a HEARTBEAT including a nonce.  An implementation
+      that does NOT support bundling MUST NOT send a COOKIE ACK to an
+      UNCONFIRMED address.
+
+   -  A COOKIE ECHO MAY be sent to an UNCONFIRMED address, but it MUST
+      be bundled with a HEARTBEAT including a nonce, and the packet MUST
+      NOT exceed the path MTU.  If the implementation does NOT support
+      bundling or if the bundled COOKIE ECHO plus HEARTBEAT (including
+      nonce) would exceed the path MTU, then the implementation MUST NOT
+      send a COOKIE ECHO to an UNCONFIRMED address.
+
+6.  User Data Transfer
+
+   Data transmission MUST only happen in the ESTABLISHED, SHUTDOWN-
+   PENDING, and SHUTDOWN-RECEIVED states.  The only exception to this is
+   that DATA chunks are allowed to be bundled with an outbound COOKIE
+   ECHO chunk when in the COOKIE-WAIT state.
+
+
+
+
+
+Stewart                     Standards Track                    [Page 73]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   DATA chunks MUST only be received according to the rules below in
+   ESTABLISHED, SHUTDOWN-PENDING, and SHUTDOWN-SENT.  A DATA chunk
+   received in CLOSED is out of the blue and SHOULD be handled per
+   Section 8.4.  A DATA chunk received in any other state SHOULD be
+   discarded.
+
+   A SACK MUST be processed in ESTABLISHED, SHUTDOWN-PENDING, and
+   SHUTDOWN-RECEIVED.  An incoming SACK MAY be processed in COOKIE-
+   ECHOED.  A SACK in the CLOSED state is out of the blue and SHOULD be
+   processed according to the rules in Section 8.4.  A SACK chunk
+   received in any other state SHOULD be discarded.
+
+   An SCTP receiver MUST be able to receive a minimum of 1500 bytes in
+   one SCTP packet.  This means that an SCTP endpoint MUST NOT indicate
+   less than 1500 bytes in its initial a_rwnd sent in the INIT or INIT
+   ACK.
+
+   For transmission efficiency, SCTP defines mechanisms for bundling of
+   small user messages and fragmentation of large user messages.  The
+   following diagram depicts the flow of user messages through SCTP.
+
+   In this section, the term "data sender" refers to the endpoint that
+   transmits a DATA chunk and the term "data receiver" refers to the
+   endpoint that receives a DATA chunk.  A data receiver will transmit
+   SACK chunks.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart                     Standards Track                    [Page 74]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+                 +--------------------------+
+                 |      User Messages       |
+                 +--------------------------+
+       SCTP user        ^  |
+      ==================|==|=======================================
+                        |  v (1)
+             +------------------+    +--------------------+
+             | SCTP DATA Chunks |    |SCTP Control Chunks |
+             +------------------+    +--------------------+
+                        ^  |             ^  |
+                        |  v (2)         |  v (2)
+                     +--------------------------+
+                     |      SCTP packets        |
+                     +--------------------------+
+       SCTP                      ^  |
+      ===========================|==|===========================
+                                 |  v
+             Connectionless Packet Transfer Service (e.g., IP)
+
+   Notes:
+
+      1) When converting user messages into DATA chunks, an endpoint
+         will fragment user messages larger than the current association
+         path MTU into multiple DATA chunks.  The data receiver will
+         normally reassemble the fragmented message from DATA chunks
+         before delivery to the user (see Section 6.9 for details).
+
+      2) Multiple DATA and control chunks may be bundled by the sender
+         into a single SCTP packet for transmission, as long as the
+         final size of the packet does not exceed the current path MTU.
+         The receiver will unbundle the packet back into the original
+         chunks.  Control chunks MUST come before DATA chunks in the
+         packet.
+
+                Figure 6: Illustration of User Data Transfer
+
+   The fragmentation and bundling mechanisms, as detailed in Section 6.9
+   and Section 6.10, are OPTIONAL to implement by the data sender, but
+   they MUST be implemented by the data receiver, i.e., an endpoint MUST
+   properly receive and process bundled or fragmented data.
+
+6.1.  Transmission of DATA Chunks
+
+   This document is specified as if there is a single retransmission
+   timer per destination transport address, but implementations MAY have
+   a retransmission timer for each DATA chunk.
+
+
+
+
+
+Stewart                     Standards Track                    [Page 75]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   The following general rules MUST be applied by the data sender for
+   transmission and/or retransmission of outbound DATA chunks:
+
+   A) At any given time, the data sender MUST NOT transmit new data to
+      any destination transport address if its peer's rwnd indicates
+      that the peer has no buffer space (i.e., rwnd is 0; see Section
+      6.2.1).  However, regardless of the value of rwnd (including if it
+      is 0), the data sender can always have one DATA chunk in flight to
+      the receiver if allowed by cwnd (see rule B, below).  This rule
+      allows the sender to probe for a change in rwnd that the sender
+      missed due to the SACK's having been lost in transit from the data
+      receiver to the data sender.
+
+      When the receiver's advertised window is zero, this probe is
+      called a zero window probe.  Note that a zero window probe SHOULD
+      only be sent when all outstanding DATA chunks have been
+      cumulatively acknowledged and no DATA chunks are in flight.  Zero
+      window probing MUST be supported.
+
+      If the sender continues to receive new packets from the receiver
+      while doing zero window probing, the unacknowledged window probes
+      should not increment the error counter for the association or any
+      destination transport address.  This is because the receiver MAY
+      keep its window closed for an indefinite time.  Refer to Section
+      6.2 on the receiver behavior when it advertises a zero window.
+      The sender SHOULD send the first zero window probe after 1 RTO
+      when it detects that the receiver has closed its window and SHOULD
+      increase the probe interval exponentially afterwards.  Also note
+      that the cwnd SHOULD be adjusted according to Section 7.2.1.  Zero
+      window probing does not affect the calculation of cwnd.
+
+      The sender MUST also have an algorithm for sending new DATA chunks
+      to avoid silly window syndrome (SWS) as described in [RFC0813].
+      The algorithm can be similar to the one described in Section
+      4.2.3.4 of [RFC1122].
+
+      However, regardless of the value of rwnd (including if it is 0),
+      the data sender can always have one DATA chunk in flight to the
+      receiver if allowed by cwnd (see rule B below).  This rule allows
+      the sender to probe for a change in rwnd that the sender missed
+      due to the SACK having been lost in transit from the data receiver
+      to the data sender.
+
+   B) At any given time, the sender MUST NOT transmit new data to a
+      given transport address if it has cwnd or more bytes of data
+      outstanding to that transport address.
+
+
+
+
+
+Stewart                     Standards Track                    [Page 76]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   C) When the time comes for the sender to transmit, before sending new
+      DATA chunks, the sender MUST first transmit any outstanding DATA
+      chunks that are marked for retransmission (limited by the current
+      cwnd).
+
+   D) When the time comes for the sender to transmit new DATA chunks,
+      the protocol parameter Max.Burst SHOULD be used to limit the
+      number of packets sent.  The limit MAY be applied by adjusting
+      cwnd as follows:
+
+      if((flightsize + Max.Burst*MTU) < cwnd) cwnd = flightsize +
+      Max.Burst*MTU
+
+      Or it MAY be applied by strictly limiting the number of packets
+      emitted by the output routine.
+
+   E) Then, the sender can send out as many new DATA chunks as rule A
+      and rule B allow.
+
+   Multiple DATA chunks committed for transmission MAY be bundled in a
+   single packet.  Furthermore, DATA chunks being retransmitted MAY be
+   bundled with new DATA chunks, as long as the resulting packet size
+   does not exceed the path MTU.  A ULP may request that no bundling is
+   performed, but this should only turn off any delays that an SCTP
+   implementation may be using to increase bundling efficiency.  It does
+   not in itself stop all bundling from occurring (i.e., in case of
+   congestion or retransmission).
+
+   Before an endpoint transmits a DATA chunk, if any received DATA
+   chunks have not been acknowledged (e.g., due to delayed ack), the
+   sender should create a SACK and bundle it with the outbound DATA
+   chunk, as long as the size of the final SCTP packet does not exceed
+   the current MTU.  See Section 6.2.
+
+   IMPLEMENTATION NOTE: When the window is full (i.e., transmission is
+   disallowed by rule A and/or rule B), the sender MAY still accept send
+   requests from its upper layer, but MUST transmit no more DATA chunks
+   until some or all of the outstanding DATA chunks are acknowledged and
+   transmission is allowed by rule A and rule B again.
+
+   Whenever a transmission or retransmission is made to any address, if
+   the T3-rtx timer of that address is not currently running, the sender
+   MUST start that timer.  If the timer for that address is already
+   running, the sender MUST restart the timer if the earliest (i.e.,
+   lowest TSN) outstanding DATA chunk sent to that address is being
+   retransmitted.  Otherwise, the data sender MUST NOT restart the
+   timer.
+
+
+
+
+Stewart                     Standards Track                    [Page 77]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   When starting or restarting the T3-rtx timer, the timer value must be
+   adjusted according to the timer rules defined in Sections 6.3.2 and
+   6.3.3.
+
+   Note: The data sender SHOULD NOT use a TSN that is more than 2**31 -
+   1 above the beginning TSN of the current send window.
+
+6.2.  Acknowledgement on Reception of DATA Chunks
+
+   The SCTP endpoint MUST always acknowledge the reception of each valid
+   DATA chunk when the DATA chunk received is inside its receive window.
+
+   When the receiver's advertised window is 0, the receiver MUST drop
+   any new incoming DATA chunk with a TSN larger than the largest TSN
+   received so far.  If the new incoming DATA chunk holds a TSN value
+   less than the largest TSN received so far, then the receiver SHOULD
+   drop the largest TSN held for reordering and accept the new incoming
+   DATA chunk.  In either case, if such a DATA chunk is dropped, the
+   receiver MUST immediately send back a SACK with the current receive
+   window showing only DATA chunks received and accepted so far.  The
+   dropped DATA chunk(s) MUST NOT be included in the SACK, as they were
+   not accepted.  The receiver MUST also have an algorithm for
+   advertising its receive window to avoid receiver silly window
+   syndrome (SWS), as described in [RFC0813].  The algorithm can be
+   similar to the one described in Section 4.2.3.3 of [RFC1122].
+
+   The guidelines on delayed acknowledgement algorithm specified in
+   Section 4.2 of [RFC2581] SHOULD be followed.  Specifically, an
+   acknowledgement SHOULD be generated for at least every second packet
+   (not every second DATA chunk) received, and SHOULD be generated
+   within 200 ms of the arrival of any unacknowledged DATA chunk.  In
+   some situations, it may be beneficial for an SCTP transmitter to be
+   more conservative than the algorithms detailed in this document
+   allow.  However, an SCTP transmitter MUST NOT be more aggressive than
+   the following algorithms allow.
+
+   An SCTP receiver MUST NOT generate more than one SACK for every
+   incoming packet, other than to update the offered window as the
+   receiving application consumes new data.
+
+   IMPLEMENTATION NOTE: The maximum delay for generating an
+   acknowledgement may be configured by the SCTP administrator, either
+   statically or dynamically, in order to meet the specific timing
+   requirement of the protocol being carried.
+
+   An implementation MUST NOT allow the maximum delay to be configured
+   to be more than 500 ms.  In other words, an implementation MAY lower
+   this value below 500 ms but MUST NOT raise it above 500 ms.
+
+
+
+Stewart                     Standards Track                    [Page 78]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   Acknowledgements MUST be sent in SACK chunks unless shutdown was
+   requested by the ULP, in which case an endpoint MAY send an
+   acknowledgement in the SHUTDOWN chunk.  A SACK chunk can acknowledge
+   the reception of multiple DATA chunks.  See Section 3.3.4 for SACK
+   chunk format.  In particular, the SCTP endpoint MUST fill in the
+   Cumulative TSN Ack field to indicate the latest sequential TSN (of a
+   valid DATA chunk) it has received.  Any received DATA chunks with TSN
+   greater than the value in the Cumulative TSN Ack field are reported
+   in the Gap Ack Block fields.  The SCTP endpoint MUST report as many
+   Gap Ack Blocks as can fit in a single SACK chunk limited by the
+   current path MTU.
+
+   Note: The SHUTDOWN chunk does not contain Gap Ack Block fields.
+   Therefore, the endpoint should use a SACK instead of the SHUTDOWN
+   chunk to acknowledge DATA chunks received out of order.
+
+   When a packet arrives with duplicate DATA chunk(s) and with no new
+   DATA chunk(s), the endpoint MUST immediately send a SACK with no
+   delay.  If a packet arrives with duplicate DATA chunk(s) bundled with
+   new DATA chunks, the endpoint MAY immediately send a SACK.  Normally,
+   receipt of duplicate DATA chunks will occur when the original SACK
+   chunk was lost and the peer's RTO has expired.  The duplicate TSN
+   number(s) SHOULD be reported in the SACK as duplicate.
+
+   When an endpoint receives a SACK, it MAY use the duplicate TSN
+   information to determine if SACK loss is occurring.  Further use of
+   this data is for future study.
+
+   The data receiver is responsible for maintaining its receive buffers.
+   The data receiver SHOULD notify the data sender in a timely manner of
+   changes in its ability to receive data.  How an implementation
+   manages its receive buffers is dependent on many factors (e.g.,
+   operating system, memory management system, amount of memory, etc.).
+   However, the data sender strategy defined in Section 6.2.1 is based
+   on the assumption of receiver operation similar to the following:
+
+   A) At initialization of the association, the endpoint tells the peer
+      how much receive buffer space it has allocated to the association
+      in the INIT or INIT ACK.  The endpoint sets a_rwnd to this value.
+
+   B) As DATA chunks are received and buffered, decrement a_rwnd by the
+      number of bytes received and buffered.  This is, in effect,
+      closing rwnd at the data sender and restricting the amount of data
+      it can transmit.
+
+
+
+
+
+
+
+Stewart                     Standards Track                    [Page 79]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   C) As DATA chunks are delivered to the ULP and released from the
+      receive buffers, increment a_rwnd by the number of bytes delivered
+      to the upper layer.  This is, in effect, opening up rwnd on the
+      data sender and allowing it to send more data.  The data receiver
+      SHOULD NOT increment a_rwnd unless it has released bytes from its
+      receive buffer.  For example, if the receiver is holding
+      fragmented DATA chunks in a reassembly queue, it should not
+      increment a_rwnd.
+
+   D) When sending a SACK, the data receiver SHOULD place the current
+      value of a_rwnd into the a_rwnd field.  The data receiver SHOULD
+      take into account that the data sender will not retransmit DATA
+      chunks that are acked via the Cumulative TSN Ack (i.e., will drop
+      from its retransmit queue).
+
+   Under certain circumstances, the data receiver may need to drop DATA
+   chunks that it has received but hasn't released from its receive
+   buffers (i.e., delivered to the ULP).  These DATA chunks may have
+   been acked in Gap Ack Blocks.  For example, the data receiver may be
+   holding data in its receive buffers while reassembling a fragmented
+   user message from its peer when it runs out of receive buffer space.
+   It may drop these DATA chunks even though it has acknowledged them in
+   Gap Ack Blocks.  If a data receiver drops DATA chunks, it MUST NOT
+   include them in Gap Ack Blocks in subsequent SACKs until they are
+   received again via retransmission.  In addition, the endpoint should
+   take into account the dropped data when calculating its a_rwnd.
+
+   An endpoint SHOULD NOT revoke a SACK and discard data.  Only in
+   extreme circumstances should an endpoint use this procedure (such as
+   out of buffer space).  The data receiver should take into account
+   that dropping data that has been acked in Gap Ack Blocks can result
+   in suboptimal retransmission strategies in the data sender and thus
+   in suboptimal performance.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart                     Standards Track                    [Page 80]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   The following example illustrates the use of delayed
+   acknowledgements:
+
+    Endpoint A                                      Endpoint Z
+
+    {App sends 3 messages; strm 0}
+    DATA [TSN=7,Strm=0,Seq=3] ------------> (ack delayed)
+    (Start T3-rtx timer)
+
+    DATA [TSN=8,Strm=0,Seq=4] ------------> (send ack)
+                                  /------- SACK [TSN Ack=8,block=0]
+    (cancel T3-rtx timer)  <-----/
+
+    DATA [TSN=9,Strm=0,Seq=5] ------------> (ack delayed)
+    (Start T3-rtx timer)
+                                           ...
+                                           {App sends 1 message; strm 1}
+                                           (bundle SACK with DATA)
+                                    /----- SACK [TSN Ack=9,block=0] \
+                                   /         DATA [TSN=6,Strm=1,Seq=2]
+    (cancel T3-rtx timer)  <------/        (Start T3-rtx timer)
+
+    (ack delayed)
+    (send ack)
+    SACK [TSN Ack=6,block=0] -------------> (cancel T3-rtx timer)
+
+           Figure 7:  Delayed Acknowledgement Example
+
+   If an endpoint receives a DATA chunk with no user data (i.e., the
+   Length field is set to 16), it MUST send an ABORT with error cause
+   set to "No User Data".
+
+   An endpoint SHOULD NOT send a DATA chunk with no user data part.
+
+6.2.1.  Processing a Received SACK
+
+   Each SACK an endpoint receives contains an a_rwnd value.  This value
+   represents the amount of buffer space the data receiver, at the time
+   of transmitting the SACK, has left of its total receive buffer space
+   (as specified in the INIT/INIT ACK).  Using a_rwnd, Cumulative TSN
+   Ack, and Gap Ack Blocks, the data sender can develop a representation
+   of the peer's receive buffer space.
+
+   One of the problems the data sender must take into account when
+   processing a SACK is that a SACK can be received out of order.  That
+   is, a SACK sent by the data receiver can pass an earlier SACK and be
+   received first by the data sender.  If a SACK is received out of
+
+
+
+
+Stewart                     Standards Track                    [Page 81]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   order, the data sender can develop an incorrect view of the peer's
+   receive buffer space.
+
+   Since there is no explicit identifier that can be used to detect
+   out-of-order SACKs, the data sender must use heuristics to determine
+   if a SACK is new.
+
+   An endpoint SHOULD use the following rules to calculate the rwnd,
+   using the a_rwnd value, the Cumulative TSN Ack, and Gap Ack Blocks in
+   a received SACK.
+
+   A) At the establishment of the association, the endpoint initializes
+      the rwnd to the Advertised Receiver Window Credit (a_rwnd) the
+      peer specified in the INIT or INIT ACK.
+
+   B) Any time a DATA chunk is transmitted (or retransmitted) to a peer,
+      the endpoint subtracts the data size of the chunk from the rwnd of
+      that peer.
+
+   C) Any time a DATA chunk is marked for retransmission, either via
+      T3-rtx timer expiration (Section 6.3.3) or via Fast Retransmit
+      (Section 7.2.4), add the data size of those chunks to the rwnd.
+
+      Note: If the implementation is maintaining a timer on each DATA
+      chunk, then only DATA chunks whose timer expired would be marked
+      for retransmission.
+
+   D) Any time a SACK arrives, the endpoint performs the following:
+
+        i) If Cumulative TSN Ack is less than the Cumulative TSN Ack
+           Point, then drop the SACK.  Since Cumulative TSN Ack is
+           monotonically increasing, a SACK whose Cumulative TSN Ack is
+           less than the Cumulative TSN Ack Point indicates an out-of-
+           order SACK.
+
+       ii) Set rwnd equal to the newly received a_rwnd minus the number
+           of bytes still outstanding after processing the Cumulative
+           TSN Ack and the Gap Ack Blocks.
+
+      iii) If the SACK is missing a TSN that was previously acknowledged
+           via a Gap Ack Block (e.g., the data receiver reneged on the
+           data), then consider the corresponding DATA that might be
+           possibly missing: Count one miss indication towards Fast
+           Retransmit as described in Section 7.2.4, and if no
+           retransmit timer is running for the destination address to
+           which the DATA chunk was originally transmitted, then T3-rtx
+           is started for that destination address.
+
+
+
+
+Stewart                     Standards Track                    [Page 82]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+       iv) If the Cumulative TSN Ack matches or exceeds the Fast
+           Recovery exitpoint (Section 7.2.4), Fast Recovery is exited.
+
+6.3.  Management of Retransmission Timer
+
+   An SCTP endpoint uses a retransmission timer T3-rtx to ensure data
+   delivery in the absence of any feedback from its peer.  The duration
+   of this timer is referred to as RTO (retransmission timeout).
+
+   When an endpoint's peer is multi-homed, the endpoint will calculate a
+   separate RTO for each different destination transport address of its
+   peer endpoint.
+
+   The computation and management of RTO in SCTP follow closely how TCP
+   manages its retransmission timer.  To compute the current RTO, an
+   endpoint maintains two state variables per destination transport
+   address: SRTT (smoothed round-trip time) and RTTVAR (round-trip time
+   variation).
+
+6.3.1.  RTO Calculation
+
+   The rules governing the computation of SRTT, RTTVAR, and RTO are as
+   follows:
+
+   C1)  Until an RTT measurement has been made for a packet sent to the
+        given destination transport address, set RTO to the protocol
+        parameter 'RTO.Initial'.
+
+   C2)  When the first RTT measurement R is made, set
+
+        SRTT <- R,
+
+        RTTVAR <- R/2, and
+
+        RTO <- SRTT + 4 * RTTVAR.
+
+   C3)  When a new RTT measurement R' is made, set
+
+        RTTVAR <- (1 - RTO.Beta) * RTTVAR + RTO.Beta * |SRTT - R'|
+
+        and
+
+        SRTT <- (1 - RTO.Alpha) * SRTT + RTO.Alpha * R'
+
+        Note: The value of SRTT used in the update to RTTVAR is its
+        value before updating SRTT itself using the second assignment.
+
+        After the computation, update RTO <- SRTT + 4 * RTTVAR.
+
+
+
+Stewart                     Standards Track                    [Page 83]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   C4)  When data is in flight and when allowed by rule C5 below, a new
+        RTT measurement MUST be made each round trip.  Furthermore, new
+        RTT measurements SHOULD be made no more than once per round trip
+        for a given destination transport address.  There are two
+        reasons for this recommendation: First, it appears that
+        measuring more frequently often does not in practice yield any
+        significant benefit [ALLMAN99]; second, if measurements are made
+        more often, then the values of RTO.Alpha and RTO.Beta in rule C3
+        above should be adjusted so that SRTT and RTTVAR still adjust to
+        changes at roughly the same rate (in terms of how many round
+        trips it takes them to reflect new values) as they would if
+        making only one measurement per round-trip and using RTO.Alpha
+        and RTO.Beta as given in rule C3.  However, the exact nature of
+        these adjustments remains a research issue.
+
+   C5)  Karn's algorithm: RTT measurements MUST NOT be made using
+        packets that were retransmitted (and thus for which it is
+        ambiguous whether the reply was for the first instance of the
+        chunk or for a later instance)
+
+        IMPLEMENTATION NOTE: RTT measurements should only be made using
+        a chunk with TSN r if no chunk with TSN less than or equal to r
+        is retransmitted since r is first sent.
+
+   C6)  Whenever RTO is computed, if it is less than RTO.Min seconds
+        then it is rounded up to RTO.Min seconds.  The reason for this
+        rule is that RTOs that do not have a high minimum value are
+        susceptible to unnecessary timeouts [ALLMAN99].
+
+   C7)  A maximum value may be placed on RTO provided it is at least
+        RTO.max seconds.
+
+   There is no requirement for the clock granularity G used for
+   computing RTT measurements and the different state variables, other
+   than:
+
+   G1) Whenever RTTVAR is computed, if RTTVAR = 0, then adjust RTTVAR <-
+   G.
+
+   Experience [ALLMAN99] has shown that finer clock granularities (<=
+   100 msec) perform somewhat better than more coarse granularities.
+
+
+
+
+
+
+
+
+
+
+Stewart                     Standards Track                    [Page 84]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+6.3.2.  Retransmission Timer Rules
+
+   The rules for managing the retransmission timer are as follows:
+
+   R1)  Every time a DATA chunk is sent to any address (including a
+        retransmission), if the T3-rtx timer of that address is not
+        running, start it running so that it will expire after the RTO
+        of that address.  The RTO used here is that obtained after any
+        doubling due to previous T3-rtx timer expirations on the
+        corresponding destination address as discussed in rule E2 below.
+
+   R2)  Whenever all outstanding data sent to an address have been
+        acknowledged, turn off the T3-rtx timer of that address.
+
+   R3)  Whenever a SACK is received that acknowledges the DATA chunk
+        with the earliest outstanding TSN for that address, restart the
+        T3-rtx timer for that address with its current RTO (if there is
+        still outstanding data on that address).
+
+   R4)  Whenever a SACK is received missing a TSN that was previously
+        acknowledged via a Gap Ack Block, start the T3-rtx for the
+        destination address to which the DATA chunk was originally
+        transmitted if it is not already running.
+
+   The following example shows the use of various timer rules (assuming
+   that the receiver uses delayed acks).
+
+   Endpoint A                                         Endpoint Z
+   {App begins to send}
+   Data [TSN=7,Strm=0,Seq=3] ------------> (ack delayed)
+   (Start T3-rtx timer)
+                                           {App sends 1 message; strm 1}
+                                           (bundle ack with data)
+   DATA [TSN=8,Strm=0,Seq=4] ----\     /-- SACK [TSN Ack=7,Block=0]
+                                  \   /      DATA [TSN=6,Strm=1,Seq=2]
+                                   \ /     (Start T3-rtx timer)
+                                    \
+                                   / \
+   (Restart T3-rtx timer)  <------/   \--> (ack delayed)
+   (ack delayed)
+   {send ack}
+   SACK [TSN Ack=6,Block=0] --------------> (Cancel T3-rtx timer)
+                                           ..
+                                           (send ack)
+   (Cancel T3-rtx timer)  <-------------- SACK [TSN Ack=8,Block=0]
+
+                       Figure 8: Timer Rule Examples
+
+
+
+
+Stewart                     Standards Track                    [Page 85]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+6.3.3.  Handle T3-rtx Expiration
+
+   Whenever the retransmission timer T3-rtx expires for a destination
+   address, do the following:
+
+   E1)  For the destination address for which the timer expires, adjust
+        its ssthresh with rules defined in Section 7.2.3 and set the
+        cwnd <- MTU.
+
+   E2)  For the destination address for which the timer expires, set RTO
+        <- RTO * 2 ("back off the timer").  The maximum value discussed
+        in rule C7 above (RTO.max) may be used to provide an upper bound
+        to this doubling operation.
+
+   E3)  Determine how many of the earliest (i.e., lowest TSN)
+        outstanding DATA chunks for the address for which the T3-rtx has
+        expired will fit into a single packet, subject to the MTU
+        constraint for the path corresponding to the destination
+        transport address to which the retransmission is being sent
+        (this may be different from the address for which the timer
+        expires; see Section 6.4).  Call this value K.  Bundle and
+        retransmit those K DATA chunks in a single packet to the
+        destination endpoint.
+
+   E4)  Start the retransmission timer T3-rtx on the destination address
+        to which the retransmission is sent, if rule R1 above indicates
+        to do so.  The RTO to be used for starting T3-rtx should be the
+        one for the destination address to which the retransmission is
+        sent, which, when the receiver is multi-homed, may be different
+        from the destination address for which the timer expired (see
+        Section 6.4 below).
+
+   After retransmitting, once a new RTT measurement is obtained (which
+   can happen only when new data has been sent and acknowledged, per
+   rule C5, or for a measurement made from a HEARTBEAT; see Section
+   8.3), the computation in rule C3 is performed, including the
+   computation of RTO, which may result in "collapsing" RTO back down
+   after it has been subject to doubling (rule E2).
+
+   Note: Any DATA chunks that were sent to the address for which the
+   T3-rtx timer expired but did not fit in one MTU (rule E3 above)
+   should be marked for retransmission and sent as soon as cwnd allows
+   (normally, when a SACK arrives).
+
+   The final rule for managing the retransmission timer concerns
+   failover (see Section 6.4.1):
+
+
+
+
+
+Stewart                     Standards Track                    [Page 86]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   F1)  Whenever an endpoint switches from the current destination
+        transport address to a different one, the current retransmission
+        timers are left running.  As soon as the endpoint transmits a
+        packet containing DATA chunk(s) to the new transport address,
+        start the timer on that transport address, using the RTO value
+        of the destination address to which the data is being sent, if
+        rule R1 indicates to do so.
+
+6.4.  Multi-Homed SCTP Endpoints
+
+   An SCTP endpoint is considered multi-homed if there are more than one
+   transport address that can be used as a destination address to reach
+   that endpoint.
+
+   Moreover, the ULP of an endpoint shall select one of the multiple
+   destination addresses of a multi-homed peer endpoint as the primary
+   path (see Section 5.1.2 and Section 10.1 for details).
+
+   By default, an endpoint SHOULD always transmit to the primary path,
+   unless the SCTP user explicitly specifies the destination transport
+   address (and possibly source transport address) to use.
+
+   An endpoint SHOULD transmit reply chunks (e.g., SACK, HEARTBEAT ACK,
+   etc.) to the same destination transport address from which it
+   received the DATA or control chunk to which it is replying.  This
+   rule should also be followed if the endpoint is bundling DATA chunks
+   together with the reply chunk.
+
+   However, when acknowledging multiple DATA chunks received in packets
+   from different source addresses in a single SACK, the SACK chunk may
+   be transmitted to one of the destination transport addresses from
+   which the DATA or control chunks being acknowledged were received.
+
+   When a receiver of a duplicate DATA chunk sends a SACK to a multi-
+   homed endpoint, it MAY be beneficial to vary the destination address
+   and not use the source address of the DATA chunk.  The reason is that
+   receiving a duplicate from a multi-homed endpoint might indicate that
+   the return path (as specified in the source address of the DATA
+   chunk) for the SACK is broken.
+
+   Furthermore, when its peer is multi-homed, an endpoint SHOULD try to
+   retransmit a chunk that timed out to an active destination transport
+   address that is different from the last destination address to which
+   the DATA chunk was sent.
+
+   Retransmissions do not affect the total outstanding data count.
+   However, if the DATA chunk is retransmitted onto a different
+   destination address, both the outstanding data counts on the new
+
+
+
+Stewart                     Standards Track                    [Page 87]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   destination address and the old destination address to which the data
+   chunk was last sent shall be adjusted accordingly.
+
+6.4.1.  Failover from an Inactive Destination Address
+
+   Some of the transport addresses of a multi-homed SCTP endpoint may
+   become inactive due to either the occurrence of certain error
+   conditions (see Section 8.2) or adjustments from the SCTP user.
+
+   When there is outbound data to send and the primary path becomes
+   inactive (e.g., due to failures), or where the SCTP user explicitly
+   requests to send data to an inactive destination transport address,
+   before reporting an error to its ULP, the SCTP endpoint should try to
+   send the data to an alternate active destination transport address if
+   one exists.
+
+   When retransmitting data that timed out, if the endpoint is multi-
+   homed, it should consider each source-destination address pair in its
+   retransmission selection policy.  When retransmitting timed-out data,
+   the endpoint should attempt to pick the most divergent source-
+   destination pair from the original source-destination pair to which
+   the packet was transmitted.
+
+   Note: Rules for picking the most divergent source-destination pair
+   are an implementation decision and are not specified within this
+   document.
+
+6.5.  Stream Identifier and Stream Sequence Number
+
+   Every DATA chunk MUST carry a valid stream identifier.  If an
+   endpoint receives a DATA chunk with an invalid stream identifier, it
+   shall acknowledge the reception of the DATA chunk following the
+   normal procedure, immediately send an ERROR chunk with cause set to
+   "Invalid Stream Identifier" (see Section 3.3.10), and discard the
+   DATA chunk.  The endpoint may bundle the ERROR chunk in the same
+   packet as the SACK as long as the ERROR follows the SACK.
+
+   The Stream Sequence Number in all the streams MUST start from 0 when
+   the association is established.  Also, when the Stream Sequence
+   Number reaches the value 65535 the next Stream Sequence Number MUST
+   be set to 0.
+
+6.6.  Ordered and Unordered Delivery
+
+   Within a stream, an endpoint MUST deliver DATA chunks received with
+   the U flag set to 0 to the upper layer according to the order of
+   their Stream Sequence Number.  If DATA chunks arrive out of order of
+
+
+
+
+Stewart                     Standards Track                    [Page 88]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   their Stream Sequence Number, the endpoint MUST hold the received
+   DATA chunks from delivery to the ULP until they are reordered.
+
+   However, an SCTP endpoint can indicate that no ordered delivery is
+   required for a particular DATA chunk transmitted within the stream by
+   setting the U flag of the DATA chunk to 1.
+
+   When an endpoint receives a DATA chunk with the U flag set to 1, it
+   must bypass the ordering mechanism and immediately deliver the data
+   to the upper layer (after reassembly if the user data is fragmented
+   by the data sender).
+
+   This provides an effective way of transmitting "out-of-band" data in
+   a given stream.  Also, a stream can be used as an "unordered" stream
+   by simply setting the U flag to 1 in all DATA chunks sent through
+   that stream.
+
+   IMPLEMENTATION NOTE: When sending an unordered DATA chunk, an
+   implementation may choose to place the DATA chunk in an outbound
+   packet that is at the head of the outbound transmission queue if
+   possible.
+
+   The 'Stream Sequence Number' field in a DATA chunk with U flag set to
+   1 has no significance.  The sender can fill it with arbitrary value,
+   but the receiver MUST ignore the field.
+
+   Note: When transmitting ordered and unordered data, an endpoint does
+   not increment its Stream Sequence Number when transmitting a DATA
+   chunk with U flag set to 1.
+
+6.7.  Report Gaps in Received DATA TSNs
+
+   Upon the reception of a new DATA chunk, an endpoint shall examine the
+   continuity of the TSNs received.  If the endpoint detects a gap in
+   the received DATA chunk sequence, it SHOULD send a SACK with Gap Ack
+   Blocks immediately.  The data receiver continues sending a SACK after
+   receipt of each SCTP packet that doesn't fill the gap.
+
+   Based on the Gap Ack Block from the received SACK, the endpoint can
+   calculate the missing DATA chunks and make decisions on whether to
+   retransmit them (see Section 6.2.1 for details).
+
+   Multiple gaps can be reported in one single SACK (see Section 3.3.4).
+
+   When its peer is multi-homed, the SCTP endpoint SHOULD always try to
+   send the SACK to the same destination address from which the last
+   DATA chunk was received.
+
+
+
+
+Stewart                     Standards Track                    [Page 89]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   Upon the reception of a SACK, the endpoint MUST remove all DATA
+   chunks that have been acknowledged by the SACK's Cumulative TSN Ack
+   from its transmit queue.  The endpoint MUST also treat all the DATA
+   chunks with TSNs not included in the Gap Ack Blocks reported by the
+   SACK as "missing".  The number of "missing" reports for each
+   outstanding DATA chunk MUST be recorded by the data sender in order
+   to make retransmission decisions.  See Section 7.2.4 for details.
+
+   The following example shows the use of SACK to report a gap.
+
+       Endpoint A                                    Endpoint Z {App
+       sends 3 messages; strm 0} DATA [TSN=6,Strm=0,Seq=2] ----------
+       -----> (ack delayed) (Start T3-rtx timer)
+
+       DATA [TSN=7,Strm=0,Seq=3] --------> X (lost)
+
+       DATA [TSN=8,Strm=0,Seq=4] ---------------> (gap detected,
+                                                   immediately send ack)
+                                       /----- SACK [TSN Ack=6,Block=1,
+                                      /             Start=2,End=2]
+                               <-----/ (remove 6 from out-queue,
+        and mark 7 as "1" missing report)
+
+                  Figure 9: Reporting a Gap using SACK
+
+   The maximum number of Gap Ack Blocks that can be reported within a
+   single SACK chunk is limited by the current path MTU.  When a single
+   SACK cannot cover all the Gap Ack Blocks needed to be reported due to
+   the MTU limitation, the endpoint MUST send only one SACK, reporting
+   the Gap Ack Blocks from the lowest to highest TSNs, within the size
+   limit set by the MTU, and leave the remaining highest TSN numbers
+   unacknowledged.
+
+6.8.  CRC32c Checksum Calculation
+
+   When sending an SCTP packet, the endpoint MUST strengthen the data
+   integrity of the transmission by including the CRC32c checksum value
+   calculated on the packet, as described below.
+
+   After the packet is constructed (containing the SCTP common header
+   and one or more control or DATA chunks), the transmitter MUST
+
+   1)  fill in the proper Verification Tag in the SCTP common header and
+       initialize the checksum field to '0's,
+
+   2)  calculate the CRC32c checksum of the whole packet, including the
+       SCTP common header and all the chunks (refer to Appendix B for
+       details of the CRC32c algorithm); and
+
+
+
+Stewart                     Standards Track                    [Page 90]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   3)  put the resultant value into the checksum field in the common
+       header, and leave the rest of the bits unchanged.
+
+   When an SCTP packet is received, the receiver MUST first check the
+   CRC32c checksum as follows:
+
+   1)  Store the received CRC32c checksum value aside.
+
+   2)  Replace the 32 bits of the checksum field in the received SCTP
+       packet with all '0's and calculate a CRC32c checksum value of the
+       whole received packet.
+
+   3)  Verify that the calculated CRC32c checksum is the same as the
+       received CRC32c checksum.  If it is not, the receiver MUST treat
+       the packet as an invalid SCTP packet.
+
+   The default procedure for handling invalid SCTP packets is to
+   silently discard them.
+
+   Any hardware implementation SHOULD be done in a way that is
+   verifiable by the software.
+
+6.9.  Fragmentation and Reassembly
+
+   An endpoint MAY support fragmentation when sending DATA chunks, but
+   it MUST support reassembly when receiving DATA chunks.  If an
+   endpoint supports fragmentation, it MUST fragment a user message if
+   the size of the user message to be sent causes the outbound SCTP
+   packet size to exceed the current MTU.  If an implementation does not
+   support fragmentation of outbound user messages, the endpoint MUST
+   return an error to its upper layer and not attempt to send the user
+   message.
+
+   Note: If an implementation that supports fragmentation makes
+   available to its upper layer a mechanism to turn off fragmentation,
+   it may do so.  However, in so doing, it MUST react just like an
+   implementation that does NOT support fragmentation, i.e., it MUST
+   reject sends that exceed the current Path MTU (P-MTU).
+
+   IMPLEMENTATION NOTE: In this error case, the Send primitive discussed
+   in Section 10.1 would need to return an error to the upper layer.
+
+   If its peer is multi-homed, the endpoint shall choose a size no
+   larger than the association Path MTU.  The association Path MTU is
+   the smallest Path MTU of all destination addresses.
+
+
+
+
+
+
+Stewart                     Standards Track                    [Page 91]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   Note: Once a message is fragmented, it cannot be re-fragmented.
+   Instead, if the PMTU has been reduced, then IP fragmentation must be
+   used.  Please see Section 7.3 for details of PMTU discovery.
+
+   When determining when to fragment, the SCTP implementation MUST take
+   into account the SCTP packet header as well as the DATA chunk
+   header(s).  The implementation MUST also take into account the space
+   required for a SACK chunk if bundling a SACK chunk with the DATA
+   chunk.
+
+   Fragmentation takes the following steps:
+
+   1)  The data sender MUST break the user message into a series of DATA
+       chunks such that each chunk plus SCTP overhead fits into an IP
+       datagram smaller than or equal to the association Path MTU.
+
+   2)  The transmitter MUST then assign, in sequence, a separate TSN to
+       each of the DATA chunks in the series.  The transmitter assigns
+       the same SSN to each of the DATA chunks.  If the user indicates
+       that the user message is to be delivered using unordered
+       delivery, then the U flag of each DATA chunk of the user message
+       MUST be set to 1.
+
+   3)  The transmitter MUST also set the B/E bits of the first DATA
+       chunk in the series to '10', the B/E bits of the last DATA chunk
+       in the series to '01', and the B/E bits of all other DATA chunks
+       in the series to '00'.
+
+   An endpoint MUST recognize fragmented DATA chunks by examining the
+   B/E bits in each of the received DATA chunks, and queue the
+   fragmented DATA chunks for reassembly.  Once the user message is
+   reassembled, SCTP shall pass the reassembled user message to the
+   specific stream for possible reordering and final dispatching.
+
+   Note: If the data receiver runs out of buffer space while still
+   waiting for more fragments to complete the reassembly of the message,
+   it should dispatch part of its inbound message through a partial
+   delivery API (see Section 10), freeing some of its receive buffer
+   space so that the rest of the message may be received.
+
+6.10.  Bundling
+
+   An endpoint bundles chunks by simply including multiple chunks in one
+   outbound SCTP packet.  The total size of the resultant IP datagram,
+
+   including the SCTP packet and IP headers, MUST be less that or equal
+   to the current Path MTU.
+
+
+
+
+Stewart                     Standards Track                    [Page 92]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   If its peer endpoint is multi-homed, the sending endpoint shall
+   choose a size no larger than the latest MTU of the current primary
+   path.
+
+   When bundling control chunks with DATA chunks, an endpoint MUST place
+   control chunks first in the outbound SCTP packet.  The transmitter
+   MUST transmit DATA chunks within an SCTP packet in increasing order
+   of TSN.
+
+   Note: Since control chunks must be placed first in a packet and since
+   DATA chunks must be transmitted before SHUTDOWN or SHUTDOWN ACK
+   chunks, DATA chunks cannot be bundled with SHUTDOWN or SHUTDOWN ACK
+   chunks.
+
+   Partial chunks MUST NOT be placed in an SCTP packet.  A partial chunk
+   is a chunk that is not completely contained in the SCTP packet; i.e.,
+   the SCTP packet is too short to contain all the bytes of the chunk as
+   indicated by the chunk length.
+
+   An endpoint MUST process received chunks in their order in the
+   packet.  The receiver uses the Chunk Length field to determine the
+   end of a chunk and beginning of the next chunk taking account of the
+   fact that all chunks end on a 4-byte boundary.  If the receiver
+   detects a partial chunk, it MUST drop the chunk.
+
+   An endpoint MUST NOT bundle INIT, INIT ACK, or SHUTDOWN COMPLETE with
+   any other chunks.
+
+7.  Congestion Control
+
+   Congestion control is one of the basic functions in SCTP.  For some
+   applications, it may be likely that adequate resources will be
+   allocated to SCTP traffic to ensure prompt delivery of time-critical
+   data -- thus, it would appear to be unlikely, during normal
+   operations, that transmissions encounter severe congestion
+   conditions.  However, SCTP must operate under adverse operational
+   conditions, which can develop upon partial network failures or
+   unexpected traffic surges.  In such situations, SCTP must follow
+   correct congestion control steps to recover from congestion quickly
+   in order to get data delivered as soon as possible.  In the absence
+   of network congestion, these preventive congestion control algorithms
+   should show no impact on the protocol performance.
+
+   IMPLEMENTATION NOTE: As far as its specific performance requirements
+   are met, an implementation is always allowed to adopt a more
+   conservative congestion control algorithm than the one defined below.
+
+
+
+
+
+Stewart                     Standards Track                    [Page 93]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   The congestion control algorithms used by SCTP are based on
+   [RFC2581].  This section describes how the algorithms defined in
+   [RFC2581] are adapted for use in SCTP.  We first list differences in
+   protocol designs between TCP and SCTP, and then describe SCTP's
+   congestion control scheme.  The description will use the same
+   terminology as in TCP congestion control whenever appropriate.
+
+   SCTP congestion control is always applied to the entire association,
+   and not to individual streams.
+
+7.1.  SCTP Differences from TCP Congestion Control
+
+   Gap Ack Blocks in the SCTP SACK carry the same semantic meaning as
+   the TCP SACK.  TCP considers the information carried in the SACK as
+   advisory information only.  SCTP considers the information carried in
+   the Gap Ack Blocks in the SACK chunk as advisory.  In SCTP, any DATA
+   chunk that has been acknowledged by SACK, including DATA that arrived
+   at the receiving end out of order, is not considered fully delivered
+   until the Cumulative TSN Ack Point passes the TSN of the DATA chunk
+   (i.e., the DATA chunk has been acknowledged by the Cumulative TSN Ack
+   field in the SACK).  Consequently, the value of cwnd controls the
+   amount of outstanding data, rather than (as in the case of non-SACK
+   TCP) the upper bound between the highest acknowledged sequence number
+   and the latest DATA chunk that can be sent within the congestion
+   window.  SCTP SACK leads to different implementations of Fast
+   Retransmit and Fast Recovery than non-SACK TCP.  As an example, see
+   [FALL96].
+
+   The biggest difference between SCTP and TCP, however, is multi-
+   homing.  SCTP is designed to establish robust communication
+   associations between two endpoints each of which may be reachable by
+   more than one transport address.  Potentially different addresses may
+   lead to different data paths between the two endpoints; thus, ideally
+   one may need a separate set of congestion control parameters for each
+   of the paths.  The treatment here of congestion control for multi-
+   homed receivers is new with SCTP and may require refinement in the
+   future.  The current algorithms make the following assumptions:
+
+   o  The sender usually uses the same destination address until being
+      instructed by the upper layer to do otherwise; however, SCTP may
+      change to an alternate destination in the event an address is
+      marked inactive (see Section 8.2).  Also, SCTP may retransmit to a
+      different transport address than the original transmission.
+
+   o  The sender keeps a separate congestion control parameter set for
+      each of the destination addresses it can send to (not each
+      source-destination pair but for each destination).  The parameters
+
+
+
+
+Stewart                     Standards Track                    [Page 94]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+      should decay if the address is not used for a long enough time
+      period.
+
+   o  For each of the destination addresses, an endpoint does slow start
+      upon the first transmission to that address.
+
+   Note: TCP guarantees in-sequence delivery of data to its upper-layer
+   protocol within a single TCP session.  This means that when TCP
+   notices a gap in the received sequence number, it waits until the gap
+   is filled before delivering the data that was received with sequence
+   numbers higher than that of the missing data.  On the other hand,
+   SCTP can deliver data to its upper-layer protocol even if there is a
+   gap in TSN if the Stream Sequence Numbers are in sequence for a
+   particular stream (i.e., the missing DATA chunks are for a different
+   stream) or if unordered delivery is indicated.  Although this does
+   not affect cwnd, it might affect rwnd calculation.
+
+7.2.  SCTP Slow-Start and Congestion Avoidance
+
+   The slow-start and congestion avoidance algorithms MUST be used by an
+   endpoint to control the amount of data being injected into the
+   network.  The congestion control in SCTP is employed in regard to the
+   association, not to an individual stream.  In some situations, it may
+   be beneficial for an SCTP sender to be more conservative than the
+   algorithms allow; however, an SCTP sender MUST NOT be more aggressive
+   than the following algorithms allow.
+
+   Like TCP, an SCTP endpoint uses the following three control variables
+   to regulate its transmission rate.
+
+   o  Receiver advertised window size (rwnd, in bytes), which is set by
+      the receiver based on its available buffer space for incoming
+      packets.
+
+      Note: This variable is kept on the entire association.
+
+   o  Congestion control window (cwnd, in bytes), which is adjusted by
+      the sender based on observed network conditions.
+
+      Note: This variable is maintained on a per-destination-address
+      basis.
+
+   o  Slow-start threshold (ssthresh, in bytes), which is used by the
+      sender to distinguish slow-start and congestion avoidance phases.
+
+      Note: This variable is maintained on a per-destination-address
+      basis.
+
+
+
+
+Stewart                     Standards Track                    [Page 95]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   SCTP also requires one additional control variable,
+   partial_bytes_acked, which is used during congestion avoidance phase
+   to facilitate cwnd adjustment.
+
+   Unlike TCP, an SCTP sender MUST keep a set of these control variables
+   cwnd, ssthresh, and partial_bytes_acked for EACH destination address
+   of its peer (when its peer is multi-homed).  Only one rwnd is kept
+   for the whole association (no matter if the peer is multi-homed or
+   has a single address).
+
+7.2.1.  Slow-Start
+
+   Beginning data transmission into a network with unknown conditions or
+   after a sufficiently long idle period requires SCTP to probe the
+   network to determine the available capacity.  The slow-start
+   algorithm is used for this purpose at the beginning of a transfer, or
+   after repairing loss detected by the retransmission timer.
+
+   o  The initial cwnd before DATA transmission or after a sufficiently
+      long idle period MUST be set to min(4*MTU, max (2*MTU, 4380
+      bytes)).
+
+   o  The initial cwnd after a retransmission timeout MUST be no more
+      than 1*MTU.
+
+   o  The initial value of ssthresh MAY be arbitrarily high (for
+      example, implementations MAY use the size of the receiver
+      advertised window).
+
+   o  Whenever cwnd is greater than zero, the endpoint is allowed to
+      have cwnd bytes of data outstanding on that transport address.
+
+   o  When cwnd is less than or equal to ssthresh, an SCTP endpoint MUST
+      use the slow-start algorithm to increase cwnd only if the current
+      congestion window is being fully utilized, an incoming SACK
+      advances the Cumulative TSN Ack Point, and the data sender is not
+      in Fast Recovery.  Only when these three conditions are met can
+      the cwnd be increased; otherwise, the cwnd MUST not be increased.
+      If these conditions are met, then cwnd MUST be increased by, at
+      most, the lesser of 1) the total size of the previously
+      outstanding DATA chunk(s) acknowledged, and 2) the destination's
+      path MTU.  This upper bound protects against the ACK-Splitting
+      attack outlined in [SAVAGE99].
+
+   In instances where its peer endpoint is multi-homed, if an endpoint
+   receives a SACK that advances its Cumulative TSN Ack Point, then it
+   should update its cwnd (or cwnds) apportioned to the destination
+   addresses to which it transmitted the acknowledged data.  However, if
+
+
+
+Stewart                     Standards Track                    [Page 96]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   the received SACK does not advance the Cumulative TSN Ack Point, the
+   endpoint MUST NOT adjust the cwnd of any of the destination
+   addresses.
+
+   Because an endpoint's cwnd is not tied to its Cumulative TSN Ack
+   Point, as duplicate SACKs come in, even though they may not advance
+   the Cumulative TSN Ack Point an endpoint can still use them to clock
+   out new data.  That is, the data newly acknowledged by the SACK
+   diminishes the amount of data now in flight to less than cwnd, and so
+   the current, unchanged value of cwnd now allows new data to be sent.
+   On the other hand, the increase of cwnd must be tied to the
+   Cumulative TSN Ack Point advancement as specified above.  Otherwise,
+   the duplicate SACKs will not only clock out new data, but also will
+   adversely clock out more new data than what has just left the
+   network, during a time of possible congestion.
+
+   o  When the endpoint does not transmit data on a given transport
+      address, the cwnd of the transport address should be adjusted to
+      max(cwnd/2, 4*MTU) per RTO.
+
+7.2.2.  Congestion Avoidance
+
+   When cwnd is greater than ssthresh, cwnd should be incremented by
+   1*MTU per RTT if the sender has cwnd or more bytes of data
+   outstanding for the corresponding transport address.
+
+   In practice, an implementation can achieve this goal in the following
+   way:
+
+   o  partial_bytes_acked is initialized to 0.
+
+   o  Whenever cwnd is greater than ssthresh, upon each SACK arrival
+      that advances the Cumulative TSN Ack Point, increase
+      partial_bytes_acked by the total number of bytes of all new chunks
+      acknowledged in that SACK including chunks acknowledged by the new
+      Cumulative TSN Ack and by Gap Ack Blocks.
+
+   o  When partial_bytes_acked is equal to or greater than cwnd and
+      before the arrival of the SACK the sender had cwnd or more bytes
+      of data outstanding (i.e., before arrival of the SACK, flightsize
+      was greater than or equal to cwnd), increase cwnd by MTU, and
+      reset partial_bytes_acked to (partial_bytes_acked - cwnd).
+
+   o  Same as in the slow start, when the sender does not transmit DATA
+      on a given transport address, the cwnd of the transport address
+      should be adjusted to max(cwnd / 2, 4*MTU) per RTO.
+
+
+
+
+
+Stewart                     Standards Track                    [Page 97]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   o  When all of the data transmitted by the sender has been
+      acknowledged by the receiver, partial_bytes_acked is initialized
+      to 0.
+
+7.2.3.  Congestion Control
+
+   Upon detection of packet losses from SACK (see Section 7.2.4), an
+   endpoint should do the following:
+
+      ssthresh = max(cwnd/2, 4*MTU)
+      cwnd = ssthresh
+      partial_bytes_acked = 0
+
+   Basically, a packet loss causes cwnd to be cut in half.
+
+   When the T3-rtx timer expires on an address, SCTP should perform slow
+   start by:
+
+      ssthresh = max(cwnd/2, 4*MTU)
+      cwnd = 1*MTU
+
+   and ensure that no more than one SCTP packet will be in flight for
+   that address until the endpoint receives acknowledgement for
+   successful delivery of data to that address.
+
+7.2.4.  Fast Retransmit on Gap Reports
+
+   In the absence of data loss, an endpoint performs delayed
+   acknowledgement.  However, whenever an endpoint notices a hole in the
+   arriving TSN sequence, it SHOULD start sending a SACK back every time
+   a packet arrives carrying data until the hole is filled.
+
+   Whenever an endpoint receives a SACK that indicates that some TSNs
+   are missing, it SHOULD wait for two further miss indications (via
+   subsequent SACKs for a total of three missing reports) on the same
+   TSNs before taking action with regard to Fast Retransmit.
+
+   Miss indications SHOULD follow the HTNA (Highest TSN Newly
+   Acknowledged) algorithm.  For each incoming SACK, miss indications
+   are incremented only for missing TSNs prior to the highest TSN newly
+   acknowledged in the SACK.  A newly acknowledged DATA chunk is one not
+   previously acknowledged in a SACK.  If an endpoint is in Fast
+   Recovery and a SACK arrives that advances the Cumulative TSN Ack
+   Point, the miss indications are incremented for all TSNs reported
+   missing in the SACK.
+
+   When the third consecutive miss indication is received for a TSN(s),
+   the data sender shall do the following:
+
+
+
+Stewart                     Standards Track                    [Page 98]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   1)  Mark the DATA chunk(s) with three miss indications for
+       retransmission.
+
+   2)  If not in Fast Recovery, adjust the ssthresh and cwnd of the
+       destination address(es) to which the missing DATA chunks were
+       last sent, according to the formula described in Section 7.2.3.
+
+   3)  Determine how many of the earliest (i.e., lowest TSN) DATA chunks
+       marked for retransmission will fit into a single packet, subject
+       to constraint of the path MTU of the destination transport
+       address to which the packet is being sent.  Call this value K.
+       Retransmit those K DATA chunks in a single packet.  When a Fast
+       Retransmit is being performed, the sender SHOULD ignore the value
+       of cwnd and SHOULD NOT delay retransmission for this single
+       packet.
+
+   4)  Restart the T3-rtx timer only if the last SACK acknowledged the
+       lowest outstanding TSN number sent to that address, or the
+       endpoint is retransmitting the first outstanding DATA chunk sent
+       to that address.
+
+   5)  Mark the DATA chunk(s) as being fast retransmitted and thus
+       ineligible for a subsequent Fast Retransmit.  Those TSNs marked
+       for retransmission due to the Fast-Retransmit algorithm that did
+       not fit in the sent datagram carrying K other TSNs are also
+       marked as ineligible for a subsequent Fast Retransmit.  However,
+       as they are marked for retransmission they will be retransmitted
+       later on as soon as cwnd allows.
+
+   6)  If not in Fast Recovery, enter Fast Recovery and mark the highest
+       outstanding TSN as the Fast Recovery exit point.  When a SACK
+       acknowledges all TSNs up to and including this exit point, Fast
+       Recovery is exited.  While in Fast Recovery, the ssthresh and
+       cwnd SHOULD NOT change for any destinations due to a subsequent
+       Fast Recovery event (i.e., one SHOULD NOT reduce the cwnd further
+       due to a subsequent Fast Retransmit).
+
+   Note: Before the above adjustments, if the received SACK also
+   acknowledges new DATA chunks and advances the Cumulative TSN Ack
+   Point, the cwnd adjustment rules defined in Section 7.2.1 and Section
+   7.2.2 must be applied first.
+
+   A straightforward implementation of the above keeps a counter for
+   each TSN hole reported by a SACK.  The counter increments for each
+   consecutive SACK reporting the TSN hole.  After reaching 3 and
+   starting the Fast-Retransmit procedure, the counter resets to 0.
+
+
+
+
+
+Stewart                     Standards Track                    [Page 99]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   Because cwnd in SCTP indirectly bounds the number of outstanding
+   TSN's, the effect of TCP Fast Recovery is achieved automatically with
+   no adjustment to the congestion control window size.
+
+7.3.  Path MTU Discovery
+
+   [RFC4821], [RFC1981], and [RFC1191] specify "Packetization Layer Path
+   MTU Discovery", whereby an endpoint maintains an estimate of the
+   maximum transmission unit (MTU) along a given Internet path and
+   refrains from sending packets along that path that exceed the MTU,
+   other than occasional attempts to probe for a change in the Path MTU
+   (PMTU).  [RFC4821] is thorough in its discussion of the MTU discovery
+   mechanism and strategies for determining the current end-to-end MTU
+   setting as well as detecting changes in this value.
+
+   An endpoint SHOULD apply these techniques, and SHOULD do so on a
+   per-destination-address basis.
+
+   There are two important SCTP-specific points regarding Path MTU
+   discovery:
+
+   1)  SCTP associations can span multiple addresses.  An endpoint MUST
+       maintain separate MTU estimates for each destination address of
+       its peer.
+
+   2)  The sender should track an association PMTU that will be the
+       smallest PMTU discovered for all of the peer's destination
+       addresses.  When fragmenting messages into multiple parts this
+       association PMTU should be used to calculate the size of each
+       fragment.  This will allow retransmissions to be seamlessly sent
+       to an alternate address without encountering IP fragmentation.
+
+8.  Fault Management
+
+8.1.  Endpoint Failure Detection
+
+   An endpoint shall keep a counter on the total number of consecutive
+   retransmissions to its peer (this includes retransmissions to all the
+   destination transport addresses of the peer if it is multi-homed),
+   including unacknowledged HEARTBEAT chunks.  If the value of this
+   counter exceeds the limit indicated in the protocol parameter
+   'Association.Max.Retrans', the endpoint shall consider the peer
+   endpoint unreachable and shall stop transmitting any more data to it
+   (and thus the association enters the CLOSED state).  In addition, the
+   endpoint MAY report the failure to the upper layer and optionally
+   report back all outstanding user data remaining in its outbound
+   queue.  The association is automatically closed when the peer
+   endpoint becomes unreachable.
+
+
+
+Stewart                     Standards Track                   [Page 100]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   The counter shall be reset each time a DATA chunk sent to that peer
+   endpoint is acknowledged (by the reception of a SACK) or a HEARTBEAT
+   ACK is received from the peer endpoint.
+
+8.2.  Path Failure Detection
+
+   When its peer endpoint is multi-homed, an endpoint should keep an
+   error counter for each of the destination transport addresses of the
+   peer endpoint.
+
+   Each time the T3-rtx timer expires on any address, or when a
+   HEARTBEAT sent to an idle address is not acknowledged within an RTO,
+   the error counter of that destination address will be incremented.
+   When the value in the error counter exceeds the protocol parameter
+   'Path.Max.Retrans' of that destination address, the endpoint should
+   mark the destination transport address as inactive, and a
+   notification SHOULD be sent to the upper layer.
+
+   When an outstanding TSN is acknowledged or a HEARTBEAT sent to that
+   address is acknowledged with a HEARTBEAT ACK, the endpoint shall
+   clear the error counter of the destination transport address to which
+   the DATA chunk was last sent (or HEARTBEAT was sent).  When the peer
+   endpoint is multi-homed and the last chunk sent to it was a
+   retransmission to an alternate address, there exists an ambiguity as
+   to whether or not the acknowledgement should be credited to the
+   address of the last chunk sent.  However, this ambiguity does not
+   seem to bear any significant consequence to SCTP behavior.  If this
+   ambiguity is undesirable, the transmitter may choose not to clear the
+   error counter if the last chunk sent was a retransmission.
+
+   Note: When configuring the SCTP endpoint, the user should avoid
+   having the value of 'Association.Max.Retrans' larger than the
+   summation of the 'Path.Max.Retrans' of all the destination addresses
+   for the remote endpoint.  Otherwise, all the destination addresses
+   may become inactive while the endpoint still considers the peer
+   endpoint reachable.  When this condition occurs, how SCTP chooses to
+   function is implementation specific.
+
+   When the primary path is marked inactive (due to excessive
+   retransmissions, for instance), the sender MAY automatically transmit
+   new packets to an alternate destination address if one exists and is
+   active.  If more than one alternate address is active when the
+   primary path is marked inactive, only ONE transport address SHOULD be
+   chosen and used as the new destination transport address.
+
+
+
+
+
+
+
+Stewart                     Standards Track                   [Page 101]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+8.3.  Path Heartbeat
+
+   By default, an SCTP endpoint SHOULD monitor the reachability of the
+   idle destination transport address(es) of its peer by sending a
+   HEARTBEAT chunk periodically to the destination transport
+   address(es).  HEARTBEAT sending MAY begin upon reaching the
+   ESTABLISHED state and is discontinued after sending either SHUTDOWN
+   or SHUTDOWN-ACK.  A receiver of a HEARTBEAT MUST respond to a
+   HEARTBEAT with a HEARTBEAT-ACK after entering the COOKIE-ECHOED state
+   (INIT sender) or the ESTABLISHED state (INIT receiver), up until
+   reaching the SHUTDOWN-SENT state (SHUTDOWN sender) or the SHUTDOWN-
+   ACK-SENT state (SHUTDOWN receiver).
+
+   A destination transport address is considered "idle" if no new chunk
+   that can be used for updating path RTT (usually including first
+   transmission DATA, INIT, COOKIE ECHO, HEARTBEAT, etc.) and no
+   HEARTBEAT has been sent to it within the current heartbeat period of
+   that address.  This applies to both active and inactive destination
+   addresses.
+
+   The upper layer can optionally initiate the following functions:
+
+   A) Disable heartbeat on a specific destination transport address of a
+      given association,
+
+   B) Change the HB.interval,
+
+   C) Re-enable heartbeat on a specific destination transport address of
+      a given association, and
+
+   D) Request an on-demand HEARTBEAT on a specific destination transport
+      address of a given association.
+
+   The endpoint should increment the respective error counter of the
+   destination transport address each time a HEARTBEAT is sent to that
+   address and not acknowledged within one RTO.
+
+   When the value of this counter reaches the protocol parameter
+   'Path.Max.Retrans', the endpoint should mark the corresponding
+   destination address as inactive if it is not so marked, and may also
+   optionally report to the upper layer the change of reachability of
+   this destination address.  After this, the endpoint should continue
+   HEARTBEAT on this destination address but should stop increasing the
+   counter.
+
+   The sender of the HEARTBEAT chunk should include in the Heartbeat
+   Information field of the chunk the current time when the packet is
+   sent out and the destination address to which the packet is sent.
+
+
+
+Stewart                     Standards Track                   [Page 102]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   IMPLEMENTATION NOTE: An alternative implementation of the heartbeat
+   mechanism that can be used is to increment the error counter variable
+   every time a HEARTBEAT is sent to a destination.  Whenever a
+   HEARTBEAT ACK arrives, the sender SHOULD clear the error counter of
+   the destination that the HEARTBEAT was sent to.  This in effect would
+   clear the previously stroked error (and any other error counts as
+   well).
+
+   The receiver of the HEARTBEAT should immediately respond with a
+   HEARTBEAT ACK that contains the Heartbeat Information TLV, together
+   with any other received TLVs, copied unchanged from the received
+   HEARTBEAT chunk.
+
+   Upon the receipt of the HEARTBEAT ACK, the sender of the HEARTBEAT
+   should clear the error counter of the destination transport address
+   to which the HEARTBEAT was sent, and mark the destination transport
+   address as active if it is not so marked.  The endpoint may
+   optionally report to the upper layer when an inactive destination
+   address is marked as active due to the reception of the latest
+   HEARTBEAT ACK.  The receiver of the HEARTBEAT ACK must also clear the
+   association overall error count as well (as defined in Section 8.1).
+
+   The receiver of the HEARTBEAT ACK should also perform an RTT
+   measurement for that destination transport address using the time
+   value carried in the HEARTBEAT ACK chunk.
+
+   On an idle destination address that is allowed to heartbeat, it is
+   recommended that a HEARTBEAT chunk is sent once per RTO of that
+   destination address plus the protocol parameter 'HB.interval', with
+   jittering of +/- 50% of the RTO value, and exponential backoff of the
+   RTO if the previous HEARTBEAT is unanswered.
+
+   A primitive is provided for the SCTP user to change the HB.interval
+   and turn on or off the heartbeat on a given destination address.  The
+   heartbeat interval set by the SCTP user is added to the RTO of that
+   destination (including any exponential backoff).  Only one heartbeat
+   should be sent each time the heartbeat timer expires (if multiple
+   destinations are idle).  It is an implementation decision on how to
+   choose which of the candidate idle destinations to heartbeat to (if
+   more than one destination is idle).
+
+   Note: When tuning the heartbeat interval, there is a side effect that
+   SHOULD be taken into account.  When this value is increased, i.e.,
+   the HEARTBEAT takes longer, the detection of lost ABORT messages
+   takes longer as well.  If a peer endpoint ABORTs the association for
+   any reason and the ABORT chunk is lost, the local endpoint will only
+   discover the lost ABORT by sending a DATA chunk or HEARTBEAT chunk
+   (thus causing the peer to send another ABORT).  This must be
+
+
+
+Stewart                     Standards Track                   [Page 103]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   considered when tuning the HEARTBEAT timer.  If the HEARTBEAT is
+   disabled, only sending DATA to the association will discover a lost
+   ABORT from the peer.
+
+8.4.  Handle "Out of the Blue" Packets
+
+   An SCTP packet is called an "out of the blue" (OOTB) packet if it is
+   correctly formed (i.e., passed the receiver's CRC32c check; see
+   Section 6.8), but the receiver is not able to identify the
+   association to which this packet belongs.
+
+   The receiver of an OOTB packet MUST do the following:
+
+   1)  If the OOTB packet is to or from a non-unicast address, a
+       receiver SHOULD silently discard the packet.  Otherwise,
+
+   2)  If the OOTB packet contains an ABORT chunk, the receiver MUST
+       silently discard the OOTB packet and take no further action.
+       Otherwise,
+
+   3)  If the packet contains an INIT chunk with a Verification Tag set
+       to '0', process it as described in Section 5.1.  If, for whatever
+       reason, the INIT cannot be processed normally and an ABORT has to
+       be sent in response, the Verification Tag of the packet
+       containing the ABORT chunk MUST be the Initiate Tag of the
+       received INIT chunk, and the T bit of the ABORT chunk has to be
+       set to 0, indicating that the Verification Tag is NOT reflected.
+
+   4)  If the packet contains a COOKIE ECHO in the first chunk, process
+       it as described in Section 5.1.  Otherwise,
+
+   5)  If the packet contains a SHUTDOWN ACK chunk, the receiver should
+       respond to the sender of the OOTB packet with a SHUTDOWN
+       COMPLETE.  When sending the SHUTDOWN COMPLETE, the receiver of
+       the OOTB packet must fill in the Verification Tag field of the
+       outbound packet with the Verification Tag received in the
+       SHUTDOWN ACK and set the T bit in the Chunk Flags to indicate
+       that the Verification Tag is reflected.  Otherwise,
+
+   6)  If the packet contains a SHUTDOWN COMPLETE chunk, the receiver
+       should silently discard the packet and take no further action.
+       Otherwise,
+
+   7)  If the packet contains a "Stale Cookie" ERROR or a COOKIE ACK,
+       the SCTP packet should be silently discarded.  Otherwise,
+
+
+
+
+
+
+Stewart                     Standards Track                   [Page 104]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   8)  The receiver should respond to the sender of the OOTB packet with
+       an ABORT.  When sending the ABORT, the receiver of the OOTB
+       packet MUST fill in the Verification Tag field of the outbound
+       packet with the value found in the Verification Tag field of the
+       OOTB packet and set the T bit in the Chunk Flags to indicate that
+       the Verification Tag is reflected.  After sending this ABORT, the
+       receiver of the OOTB packet shall discard the OOTB packet and
+       take no further action.
+
+8.5.  Verification Tag
+
+   The Verification Tag rules defined in this section apply when sending
+   or receiving SCTP packets that do not contain an INIT, SHUTDOWN
+   COMPLETE, COOKIE ECHO (see Section 5.1), ABORT, or SHUTDOWN ACK
+   chunk.  The rules for sending and receiving SCTP packets containing
+   one of these chunk types are discussed separately in Section 8.5.1.
+
+   When sending an SCTP packet, the endpoint MUST fill in the
+   Verification Tag field of the outbound packet with the tag value in
+   the Initiate Tag parameter of the INIT or INIT ACK received from its
+   peer.
+
+   When receiving an SCTP packet, the endpoint MUST ensure that the
+   value in the Verification Tag field of the received SCTP packet
+   matches its own tag.  If the received Verification Tag value does not
+   match the receiver's own tag value, the receiver shall silently
+   discard the packet and shall not process it any further except for
+   those cases listed in Section 8.5.1 below.
+
+8.5.1.  Exceptions in Verification Tag Rules
+
+   A) Rules for packet carrying INIT:
+
+   -   The sender MUST set the Verification Tag of the packet to 0.
+
+   -   When an endpoint receives an SCTP packet with the Verification
+       Tag set to 0, it should verify that the packet contains only an
+       INIT chunk.  Otherwise, the receiver MUST silently discard the
+       packet.
+
+   B) Rules for packet carrying ABORT:
+
+   -   The endpoint MUST always fill in the Verification Tag field of
+       the outbound packet with the destination endpoint's tag value, if
+       it is known.
+
+   -   If the ABORT is sent in response to an OOTB packet, the endpoint
+       MUST follow the procedure described in Section 8.4.
+
+
+
+Stewart                     Standards Track                   [Page 105]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   -   The receiver of an ABORT MUST accept the packet if the
+       Verification Tag field of the packet matches its own tag and the
+       T bit is not set OR if it is set to its peer's tag and the T bit
+       is set in the Chunk Flags.  Otherwise, the receiver MUST silently
+       discard the packet and take no further action.
+
+   C) Rules for packet carrying SHUTDOWN COMPLETE:
+
+   -   When sending a SHUTDOWN COMPLETE, if the receiver of the SHUTDOWN
+       ACK has a TCB, then the destination endpoint's tag MUST be used,
+       and the T bit MUST NOT be set.  Only where no TCB exists should
+       the sender use the Verification Tag from the SHUTDOWN ACK, and
+       MUST set the T bit.
+
+   -   The receiver of a SHUTDOWN COMPLETE shall accept the packet if
+       the Verification Tag field of the packet matches its own tag and
+       the T bit is not set OR if it is set to its peer's tag and the T
+       bit is set in the Chunk Flags.  Otherwise, the receiver MUST
+       silently discard the packet and take no further action.  An
+       endpoint MUST ignore the SHUTDOWN COMPLETE if it is not in the
+       SHUTDOWN-ACK-SENT state.
+
+   D) Rules for packet carrying a COOKIE ECHO
+
+   -   When sending a COOKIE ECHO, the endpoint MUST use the value of
+       the Initiate Tag received in the INIT ACK.
+
+   -   The receiver of a COOKIE ECHO follows the procedures in Section
+       5.
+
+   E) Rules for packet carrying a SHUTDOWN ACK
+
+   -   If the receiver is in COOKIE-ECHOED or COOKIE-WAIT state the
+       procedures in Section 8.4 SHOULD be followed; in other words, it
+       should be treated as an Out Of The Blue packet.
+
+9.  Termination of Association
+
+   An endpoint should terminate its association when it exits from
+   service.  An association can be terminated by either abort or
+   shutdown.  An abort of an association is abortive by definition in
+   that any data pending on either end of the association is discarded
+   and not delivered to the peer.  A shutdown of an association is
+   considered a graceful close where all data in queue by either
+   endpoint is delivered to the respective peers.  However, in the case
+   of a shutdown, SCTP does not support a half-open state (like TCP)
+   wherein one side may continue sending data while the other end is
+   closed.  When either endpoint performs a shutdown, the association on
+
+
+
+Stewart                     Standards Track                   [Page 106]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   each peer will stop accepting new data from its user and only deliver
+   data in queue at the time of sending or receiving the SHUTDOWN chunk.
+
+9.1.  Abort of an Association
+
+   When an endpoint decides to abort an existing association, it MUST
+   send an ABORT chunk to its peer endpoint.  The sender MUST fill in
+   the peer's Verification Tag in the outbound packet and MUST NOT
+   bundle any DATA chunk with the ABORT.  If the association is aborted
+   on request of the upper layer, a User-Initiated Abort error cause
+   (see Section 3.3.10.12) SHOULD be present in the ABORT chunk.
+
+   An endpoint MUST NOT respond to any received packet that contains an
+   ABORT chunk (also see Section 8.4).
+
+   An endpoint receiving an ABORT MUST apply the special Verification
+   Tag check rules described in Section 8.5.1.
+
+   After checking the Verification Tag, the receiving endpoint MUST
+   remove the association from its record and SHOULD report the
+   termination to its upper layer.  If a User-Initiated Abort error
+   cause is present in the ABORT chunk, the Upper Layer Abort Reason
+   SHOULD be made available to the upper layer.
+
+9.2.  Shutdown of an Association
+
+   Using the SHUTDOWN primitive (see Section 10.1), the upper layer of
+   an endpoint in an association can gracefully close the association.
+   This will allow all outstanding DATA chunks from the peer of the
+   shutdown initiator to be delivered before the association terminates.
+
+   Upon receipt of the SHUTDOWN primitive from its upper layer, the
+   endpoint enters the SHUTDOWN-PENDING state and remains there until
+   all outstanding data has been acknowledged by its peer.  The endpoint
+   accepts no new data from its upper layer, but retransmits data to the
+   far end if necessary to fill gaps.
+
+   Once all its outstanding data has been acknowledged, the endpoint
+   shall send a SHUTDOWN chunk to its peer including in the Cumulative
+   TSN Ack field the last sequential TSN it has received from the peer.
+   It shall then start the T2-shutdown timer and enter the SHUTDOWN-SENT
+   state.  If the timer expires, the endpoint must resend the SHUTDOWN
+   with the updated last sequential TSN received from its peer.
+
+   The rules in Section 6.3 MUST be followed to determine the proper
+   timer value for T2-shutdown.  To indicate any gaps in TSN, the
+   endpoint may also bundle a SACK with the SHUTDOWN chunk in the same
+   SCTP packet.
+
+
+
+Stewart                     Standards Track                   [Page 107]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   An endpoint should limit the number of retransmissions of the
+   SHUTDOWN chunk to the protocol parameter 'Association.Max.Retrans'.
+   If this threshold is exceeded, the endpoint should destroy the TCB
+   and MUST report the peer endpoint unreachable to the upper layer (and
+   thus the association enters the CLOSED state).  The reception of any
+   packet from its peer (i.e., as the peer sends all of its queued DATA
+   chunks) should clear the endpoint's retransmission count and restart
+   the T2-shutdown timer, giving its peer ample opportunity to transmit
+   all of its queued DATA chunks that have not yet been sent.
+
+   Upon reception of the SHUTDOWN, the peer endpoint shall
+
+   -  enter the SHUTDOWN-RECEIVED state,
+
+   -  stop accepting new data from its SCTP user, and
+
+   -  verify, by checking the Cumulative TSN Ack field of the chunk,
+      that all its outstanding DATA chunks have been received by the
+      SHUTDOWN sender.
+
+   Once an endpoint has reached the SHUTDOWN-RECEIVED state, it MUST NOT
+   send a SHUTDOWN in response to a ULP request, and should discard
+   subsequent SHUTDOWN chunks.
+
+   If there are still outstanding DATA chunks left, the SHUTDOWN
+   receiver MUST continue to follow normal data transmission procedures
+   defined in Section 6, until all outstanding DATA chunks are
+   acknowledged; however, the SHUTDOWN receiver MUST NOT accept new data
+   from its SCTP user.
+
+   While in the SHUTDOWN-SENT state, the SHUTDOWN sender MUST
+   immediately respond to each received packet containing one or more
+   DATA chunks with a SHUTDOWN chunk and restart the T2-shutdown timer.
+   If a SHUTDOWN chunk by itself cannot acknowledge all of the received
+   DATA chunks (i.e., there are TSNs that can be acknowledged that are
+   larger than the cumulative TSN, and thus gaps exist in the TSN
+   sequence), or if duplicate TSNs have been received, then a SACK chunk
+   MUST also be sent.
+
+   The sender of the SHUTDOWN MAY also start an overall guard timer
+   'T5-shutdown-guard' to bound the overall time for the shutdown
+   sequence.  At the expiration of this timer, the sender SHOULD abort
+   the association by sending an ABORT chunk.  If the 'T5-shutdown-
+   guard' timer is used, it SHOULD be set to the recommended value of 5
+   times 'RTO.Max'.
+
+   If the receiver of the SHUTDOWN has no more outstanding DATA chunks,
+   the SHUTDOWN receiver MUST send a SHUTDOWN ACK and start a T2-
+
+
+
+Stewart                     Standards Track                   [Page 108]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   shutdown timer of its own, entering the SHUTDOWN-ACK-SENT state.  If
+   the timer expires, the endpoint must resend the SHUTDOWN ACK.
+
+   The sender of the SHUTDOWN ACK should limit the number of
+   retransmissions of the SHUTDOWN ACK chunk to the protocol parameter
+   'Association.Max.Retrans'.  If this threshold is exceeded, the
+   endpoint should destroy the TCB and may report the peer endpoint
+   unreachable to the upper layer (and thus the association enters the
+   CLOSED state).
+
+   Upon the receipt of the SHUTDOWN ACK, the SHUTDOWN sender shall stop
+   the T2-shutdown timer, send a SHUTDOWN COMPLETE chunk to its peer,
+   and remove all record of the association.
+
+   Upon reception of the SHUTDOWN COMPLETE chunk, the endpoint will
+   verify that it is in the SHUTDOWN-ACK-SENT state; if it is not, the
+   chunk should be discarded.  If the endpoint is in the SHUTDOWN-ACK-
+   SENT state, the endpoint should stop the T2-shutdown timer and remove
+   all knowledge of the association (and thus the association enters the
+   CLOSED state).
+
+   An endpoint SHOULD ensure that all its outstanding DATA chunks have
+   been acknowledged before initiating the shutdown procedure.
+
+   An endpoint should reject any new data request from its upper layer
+   if it is in the SHUTDOWN-PENDING, SHUTDOWN-SENT, SHUTDOWN-RECEIVED,
+   or SHUTDOWN-ACK-SENT state.
+
+   If an endpoint is in the SHUTDOWN-ACK-SENT state and receives an INIT
+   chunk (e.g., if the SHUTDOWN COMPLETE was lost) with source and
+   destination transport addresses (either in the IP addresses or in the
+   INIT chunk) that belong to this association, it should discard the
+   INIT chunk and retransmit the SHUTDOWN ACK chunk.
+
+   Note: Receipt of an INIT with the same source and destination IP
+   addresses as used in transport addresses assigned to an endpoint but
+   with a different port number indicates the initialization of a
+   separate association.
+
+   The sender of the INIT or COOKIE ECHO should respond to the receipt
+   of a SHUTDOWN ACK with a stand-alone SHUTDOWN COMPLETE in an SCTP
+   packet with the Verification Tag field of its common header set to
+   the same tag that was received in the SHUTDOWN ACK packet.  This is
+   considered an Out of the Blue packet as defined in Section 8.4.  The
+   sender of the INIT lets T1-init continue running and remains in the
+   COOKIE-WAIT or COOKIE-ECHOED state.  Normal T1-init timer expiration
+   will cause the INIT or COOKIE chunk to be retransmitted and thus
+   start a new association.
+
+
+
+Stewart                     Standards Track                   [Page 109]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   If a SHUTDOWN is received in the COOKIE-WAIT or COOKIE ECHOED state,
+   the SHUTDOWN chunk SHOULD be silently discarded.
+
+   If an endpoint is in the SHUTDOWN-SENT state and receives a SHUTDOWN
+   chunk from its peer, the endpoint shall respond immediately with a
+   SHUTDOWN ACK to its peer, and move into the SHUTDOWN-ACK-SENT state
+   restarting its T2-shutdown timer.
+
+   If an endpoint is in the SHUTDOWN-ACK-SENT state and receives a
+   SHUTDOWN ACK, it shall stop the T2-shutdown timer, send a SHUTDOWN
+   COMPLETE chunk to its peer, and remove all record of the association.
+
+10.  Interface with Upper Layer
+
+   The Upper Layer Protocols (ULPs) shall request services by passing
+   primitives to SCTP and shall receive notifications from SCTP for
+   various events.
+
+   The primitives and notifications described in this section should be
+   used as a guideline for implementing SCTP.  The following functional
+   description of ULP interface primitives is shown for illustrative
+   purposes.  Different SCTP implementations may have different ULP
+   interfaces.  However, all SCTPs must provide a certain minimum set of
+   services to guarantee that all SCTP implementations can support the
+   same protocol hierarchy.
+
+10.1.  ULP-to-SCTP
+
+   The following sections functionally characterize a ULP/SCTP
+   interface.  The notation used is similar to most procedure or
+   function calls in high-level languages.
+
+   The ULP primitives described below specify the basic functions that
+   SCTP must perform to support inter-process communication.  Individual
+   implementations must define their own exact format, and may provide
+   combinations or subsets of the basic functions in single calls.
+
+   A) Initialize
+
+      Format: INITIALIZE ([local port],[local eligible address list])->
+      local SCTP instance name
+
+   This primitive allows SCTP to initialize its internal data structures
+   and allocate necessary resources for setting up its operation
+   environment.  Once SCTP is initialized, ULP can communicate directly
+   with other endpoints without re-invoking this primitive.
+
+   SCTP will return a local SCTP instance name to the ULP.
+
+
+
+Stewart                     Standards Track                   [Page 110]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   Mandatory attributes:
+
+   None.
+
+   Optional attributes:
+
+   The following types of attributes may be passed along with the
+   primitive:
+
+   o  local port - SCTP port number, if ULP wants it to be specified.
+
+   o  local eligible address list - an address list that the local SCTP
+      endpoint should bind.  By default, if an address list is not
+      included, all IP addresses assigned to the host should be used by
+      the local endpoint.
+
+   IMPLEMENTATION NOTE: If this optional attribute is supported by an
+   implementation, it will be the responsibility of the implementation
+   to enforce that the IP source address field of any SCTP packets sent
+   out by this endpoint contains one of the IP addresses indicated in
+   the local eligible address list.
+
+   B) Associate
+
+      Format: ASSOCIATE(local SCTP instance name,
+              destination transport addr, outbound stream count)
+      -> association id [,destination transport addr list]
+            [,outbound stream count]
+
+   This primitive allows the upper layer to initiate an association to a
+   specific peer endpoint.
+
+   The peer endpoint shall be specified by one of the transport
+   addresses that defines the endpoint (see Section 1.3).  If the local
+   SCTP instance has not been initialized, the ASSOCIATE is considered
+   an error.
+
+   An association id, which is a local handle to the SCTP association,
+   will be returned on successful establishment of the association.  If
+   SCTP is not able to open an SCTP association with the peer endpoint,
+   an error is returned.
+
+   Other association parameters may be returned, including the complete
+   destination transport addresses of the peer as well as the outbound
+   stream count of the local endpoint.  One of the transport addresses
+   from the returned destination addresses will be selected by the local
+   endpoint as default primary path for sending SCTP packets to this
+   peer.  The returned "destination transport addr list" can be used by
+
+
+
+Stewart                     Standards Track                   [Page 111]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   the ULP to change the default primary path or to force sending a
+   packet to a specific transport address.
+
+   IMPLEMENTATION NOTE: If ASSOCIATE primitive is implemented as a
+   blocking function call, the ASSOCIATE primitive can return
+   association parameters in addition to the association id upon
+   successful establishment.  If ASSOCIATE primitive is implemented as a
+   non-blocking call, only the association id shall be returned and
+   association parameters shall be passed using the COMMUNICATION UP
+   notification.
+
+   Mandatory attributes:
+
+   o  local SCTP instance name - obtained from the INITIALIZE operation.
+
+   o  destination transport addr - specified as one of the transport
+      addresses of the peer endpoint with which the association is to be
+      established.
+
+   o  outbound stream count - the number of outbound streams the ULP
+      would like to open towards this peer endpoint.
+
+   Optional attributes:
+
+   None.
+
+   C) Shutdown
+
+      Format: SHUTDOWN(association id)
+      -> result
+
+   Gracefully closes an association.  Any locally queued user data will
+   be delivered to the peer.  The association will be terminated only
+   after the peer acknowledges all the SCTP packets sent.  A success
+   code will be returned on successful termination of the association.
+   If attempting to terminate the association results in a failure, an
+   error code shall be returned.
+
+   Mandatory attributes:
+
+   o association id - local handle to the SCTP association.
+
+   Optional attributes:
+
+   None.
+
+
+
+
+
+
+Stewart                     Standards Track                   [Page 112]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   D) Abort
+
+      Format: ABORT(association id [, Upper Layer Abort Reason]) ->
+      result
+
+   Ungracefully closes an association.  Any locally queued user data
+   will be discarded, and an ABORT chunk is sent to the peer.  A success
+   code will be returned on successful abort of the association.  If
+   attempting to abort the association results in a failure, an error
+   code shall be returned.
+
+   Mandatory attributes:
+
+   o association id - local handle to the SCTP association.
+
+   Optional attributes:
+
+   o Upper Layer Abort Reason - reason of the abort to be passed to the
+   peer.
+
+   None.
+
+   E) Send
+
+    Format: SEND(association id, buffer address, byte count [,context]
+            [,stream id] [,life time] [,destination transport address]
+            [,unordered flag] [,no-bundle flag] [,payload protocol-id] )
+    -> result
+
+   This is the main method to send user data via SCTP.
+
+   Mandatory attributes:
+
+   o  association id - local handle to the SCTP association.
+
+   o  buffer address - the location where the user message to be
+      transmitted is stored.
+
+   o  byte count - the size of the user data in number of bytes.
+
+   Optional attributes:
+
+   o  context - an optional 32-bit integer that will be carried in the
+      sending failure notification to the ULP if the transportation of
+      this user message fails.
+
+   o  stream id - to indicate which stream to send the data on.  If not
+      specified, stream 0 will be used.
+
+
+
+Stewart                     Standards Track                   [Page 113]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   o  life time - specifies the life time of the user data.  The user
+      data will not be sent by SCTP after the life time expires.  This
+      parameter can be used to avoid efforts to transmit stale user
+      messages.  SCTP notifies the ULP if the data cannot be initiated
+      to transport (i.e., sent to the destination via SCTP's send
+      primitive) within the life time variable.  However, the user data
+      will be transmitted if SCTP has attempted to transmit a chunk
+      before the life time expired.
+
+   IMPLEMENTATION NOTE: In order to better support the data life time
+   option, the transmitter may hold back the assigning of the TSN number
+   to an outbound DATA chunk to the last moment.  And, for
+   implementation simplicity, once a TSN number has been assigned the
+   sender should consider the send of this DATA chunk as committed,
+   overriding any life time option attached to the DATA chunk.
+
+   o  destination transport address - specified as one of the
+      destination transport addresses of the peer endpoint to which this
+      packet should be sent.  Whenever possible, SCTP should use this
+      destination transport address for sending the packets, instead of
+      the current primary path.
+
+   o  unordered flag - this flag, if present, indicates that the user
+      would like the data delivered in an unordered fashion to the peer
+      (i.e., the U flag is set to 1 on all DATA chunks carrying this
+      message).
+
+   o  no-bundle flag - instructs SCTP not to bundle this user data with
+      other outbound DATA chunks.  SCTP MAY still bundle even when this
+      flag is present, when faced with network congestion.
+
+   o  payload protocol-id - a 32-bit unsigned integer that is to be
+      passed to the peer indicating the type of payload protocol data
+      being transmitted.  This value is passed as opaque data by SCTP.
+
+   F) Set Primary
+
+      Format: SETPRIMARY(association id, destination transport address,
+                         [source transport address] )
+      -> result
+
+   Instructs the local SCTP to use the specified destination transport
+   address as the primary path for sending packets.
+
+   The result of attempting this operation shall be returned.  If the
+   specified destination transport address is not present in the
+   "destination transport address list" returned earlier in an associate
+   command or communication up notification, an error shall be returned.
+
+
+
+Stewart                     Standards Track                   [Page 114]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   Mandatory attributes:
+
+   o  association id - local handle to the SCTP association.
+
+   o  destination transport address - specified as one of the transport
+      addresses of the peer endpoint, which should be used as the
+      primary address for sending packets.  This overrides the current
+      primary address information maintained by the local SCTP endpoint.
+
+   Optional attributes:
+
+   o  source transport address - optionally, some implementations may
+      allow you to set the default source address placed in all outgoing
+      IP datagrams.
+
+   G) Receive
+
+    Format: RECEIVE(association id, buffer address, buffer size
+            [,stream id])
+    -> byte count [,transport address] [,stream id] [,stream sequence
+       number] [,partial flag] [,delivery number] [,payload protocol-id]
+
+   This primitive shall read the first user message in the SCTP in-queue
+   into the buffer specified by ULP, if there is one available.  The
+   size of the message read, in bytes, will be returned.  It may,
+   depending on the specific implementation, also return other
+   information such as the sender's address, the stream id on which it
+   is received, whether there are more messages available for retrieval,
+   etc.  For ordered messages, their Stream Sequence Number may also be
+   returned.
+
+   Depending upon the implementation, if this primitive is invoked when
+   no message is available the implementation should return an
+   indication of this condition or should block the invoking process
+   until data does become available.
+
+   Mandatory attributes:
+
+   o  association id - local handle to the SCTP association
+
+   o  buffer address - the memory location indicated by the ULP to store
+      the received message.
+
+   o  buffer size - the maximum size of data to be received, in bytes.
+
+   Optional attributes:
+
+   o  stream id - to indicate which stream to receive the data on.
+
+
+
+Stewart                     Standards Track                   [Page 115]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   o  Stream Sequence Number - the Stream Sequence Number assigned by
+      the sending SCTP peer.
+
+   o  partial flag - if this returned flag is set to 1, then this
+      Receive contains a partial delivery of the whole message.  When
+      this flag is set, the stream id and Stream Sequence Number MUST
+      accompany this receive.  When this flag is set to 0, it indicates
+      that no more deliveries will be received for this Stream Sequence
+      Number.
+
+   o  payload protocol-id - a 32-bit unsigned integer that is received
+      from the peer indicating the type of payload protocol of the
+      received data.  This value is passed as opaque data by SCTP.
+
+   H) Status
+
+      Format: STATUS(association id)
+      -> status data
+
+   This primitive should return a data block containing the following
+   information:
+
+      association connection state,
+      destination transport address list,
+      destination transport address reachability states,
+      current receiver window size,
+      current congestion window sizes,
+      number of unacknowledged DATA chunks,
+      number of DATA chunks pending receipt,
+      primary path,
+      most recent SRTT on primary path,
+      RTO on primary path,
+      SRTT and RTO on other destination addresses, etc.
+
+   Mandatory attributes:
+
+   o association id - local handle to the SCTP association.
+
+   Optional attributes:
+
+   None.
+
+   I) Change Heartbeat
+
+      Format: CHANGE HEARTBEAT(association id,
+              destination transport address, new state [,interval])
+      -> result
+
+
+
+
+Stewart                     Standards Track                   [Page 116]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   Instructs the local endpoint to enable or disable heartbeat on the
+   specified destination transport address.
+
+   The result of attempting this operation shall be returned.
+
+   Note: Even when enabled, heartbeat will not take place if the
+   destination transport address is not idle.
+
+   Mandatory attributes:
+
+   o  association id - local handle to the SCTP association.
+
+   o  destination transport address - specified as one of the transport
+      addresses of the peer endpoint.
+
+   o  new state - the new state of heartbeat for this destination
+      transport address (either enabled or disabled).
+
+   Optional attributes:
+
+   o  interval - if present, indicates the frequency of the heartbeat if
+      this is to enable heartbeat on a destination transport address.
+      This value is added to the RTO of the destination transport
+      address.  This value, if present, affects all destinations.
+
+   J) Request HeartBeat
+
+      Format: REQUESTHEARTBEAT(association id, destination transport
+              address)
+      -> result
+
+   Instructs the local endpoint to perform a HeartBeat on the specified
+   destination transport address of the given association.  The returned
+   result should indicate whether the transmission of the HEARTBEAT
+   chunk to the destination address is successful.
+
+   Mandatory attributes:
+
+   o  association id - local handle to the SCTP association.
+
+   o  destination transport address - the transport address of the
+      association on which a heartbeat should be issued.
+
+   K) Get SRTT Report
+
+      Format: GETSRTTREPORT(association id,
+                            destination transport address)
+      -> srtt result
+
+
+
+Stewart                     Standards Track                   [Page 117]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   Instructs the local SCTP to report the current SRTT measurement on
+   the specified destination transport address of the given association.
+   The returned result can be an integer containing the most recent SRTT
+   in milliseconds.
+
+   Mandatory attributes:
+
+   o  association id - local handle to the SCTP association.
+
+   o  destination transport address - the transport address of the
+      association on which the SRTT measurement is to be reported.
+
+   L) Set Failure Threshold
+
+      Format: SETFAILURETHRESHOLD(association id, destination transport
+              address, failure threshold)
+
+      -> result
+
+   This primitive allows the local SCTP to customize the reachability
+   failure detection threshold 'Path.Max.Retrans' for the specified
+   destination address.
+
+   Mandatory attributes:
+
+   o  association id - local handle to the SCTP association.
+
+   o  destination transport address - the transport address of the
+      association on which the failure detection threshold is to be set.
+
+   o  failure threshold - the new value of 'Path.Max.Retrans' for the
+      destination address.
+
+   M) Set Protocol Parameters
+
+      Format: SETPROTOCOLPARAMETERS(association id,
+              [,destination transport address,]
+              protocol parameter list)
+      -> result
+
+   This primitive allows the local SCTP to customize the protocol
+   parameters.
+
+   Mandatory attributes:
+
+   o  association id - local handle to the SCTP association.
+
+
+
+
+
+Stewart                     Standards Track                   [Page 118]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   o  protocol parameter list - the specific names and values of the
+      protocol parameters (e.g., Association.Max.Retrans; see Section
+      15) that the SCTP user wishes to customize.
+
+   Optional attributes:
+
+   o  destination transport address - some of the protocol parameters
+      may be set on a per destination transport address basis.
+
+   N) Receive Unsent Message
+
+      Format: RECEIVE_UNSENT(data retrieval id, buffer address, buffer
+              size [,stream id] [, stream sequence number] [,partial
+              flag] [,payload protocol-id])
+
+   o  data retrieval id - the identification passed to the ULP in the
+      failure notification.
+
+   o  buffer address - the memory location indicated by the ULP to store
+      the received message.
+
+   o  buffer size - the maximum size of data to be received, in bytes.
+
+   Optional attributes:
+
+   o  stream id - this is a return value that is set to indicate which
+      stream the data was sent to.
+
+   o  Stream Sequence Number - this value is returned indicating the
+      Stream Sequence Number that was associated with the message.
+
+   o  partial flag - if this returned flag is set to 1, then this
+      message is a partial delivery of the whole message.  When this
+      flag is set, the stream id and Stream Sequence Number MUST
+      accompany this receive.  When this flag is set to 0, it indicates
+      that no more deliveries will be received for this Stream Sequence
+      Number.
+
+   o  payload protocol-id - The 32 bit unsigned integer that was sent to
+      be sent to the peer indicating the type of payload protocol of the
+      received data.
+
+   o  Receive Unacknowledged Message
+
+      Format: RECEIVE_UNACKED(data retrieval id, buffer address, buffer
+              size, [,stream id] [, stream sequence number] [,partial
+              flag] [,payload protocol-id])
+
+
+
+
+Stewart                     Standards Track                   [Page 119]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   o  data retrieval id - the identification passed to the ULP in the
+      failure notification.
+
+   o  buffer address - the memory location indicated by the ULP to store
+      the received message.
+
+   o  buffer size - the maximum size of data to be received, in bytes.
+
+   Optional attributes:
+
+   o  stream id - this is a return value that is set to indicate which
+      stream the data was sent to.
+
+   o  Stream Sequence Number - this value is returned indicating the
+      Stream Sequence Number that was associated with the message.
+
+   o  partial flag - if this returned flag is set to 1, then this
+      message is a partial delivery of the whole message.  When this
+      flag is set, the stream id and Stream Sequence Number MUST
+      accompany this receive.  When this flag is set to 0, it indicates
+      that no more deliveries will be received for this Stream Sequence
+      Number.
+
+   o  payload protocol-id - the 32-bit unsigned integer that was sent to
+      the peer indicating the type of payload protocol of the received
+      data.
+
+   P) Destroy SCTP Instance
+
+      Format: DESTROY(local SCTP instance name)
+
+   o  local SCTP instance name - this is the value that was passed to
+      the application in the initialize primitive and it indicates which
+      SCTP instance is to be destroyed.
+
+10.2.  SCTP-to-ULP
+
+   It is assumed that the operating system or application environment
+   provides a means for the SCTP to asynchronously signal the ULP
+   process.  When SCTP does signal a ULP process, certain information is
+   passed to the ULP.
+
+   IMPLEMENTATION NOTE: In some cases, this may be done through a
+   separate socket or error channel.
+
+
+
+
+
+
+
+Stewart                     Standards Track                   [Page 120]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   A) DATA ARRIVE notification
+
+   SCTP shall invoke this notification on the ULP when a user message is
+   successfully received and ready for retrieval.
+
+   The following may optionally be passed with the notification:
+
+   o  association id - local handle to the SCTP association.
+
+   o  stream id - to indicate which stream the data is received on.
+
+   B) SEND FAILURE notification
+
+   If a message cannot be delivered, SCTP shall invoke this notification
+   on the ULP.
+
+   The following may optionally be passed with the notification:
+
+   o  association id - local handle to the SCTP association.
+
+   o  data retrieval id - an identification used to retrieve unsent and
+      unacknowledged data.
+
+   o  cause code - indicating the reason of the failure, e.g., size too
+      large, message life time expiration, etc.
+
+   o  context - optional information associated with this message (see D
+      in Section 10.1).
+
+   C) NETWORK STATUS CHANGE notification
+
+   When a destination transport address is marked inactive (e.g., when
+   SCTP detects a failure) or marked active (e.g., when SCTP detects a
+   recovery), SCTP shall invoke this notification on the ULP.
+
+   The following shall be passed with the notification:
+
+   o  association id - local handle to the SCTP association.
+
+   o  destination transport address - this indicates the destination
+      transport address of the peer endpoint affected by the change.
+
+   o  new-status - this indicates the new status.
+
+
+
+
+
+
+
+
+Stewart                     Standards Track                   [Page 121]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   D) COMMUNICATION UP notification
+
+   This notification is used when SCTP becomes ready to send or receive
+   user messages, or when a lost communication to an endpoint is
+   restored.
+
+   IMPLEMENTATION NOTE: If the ASSOCIATE primitive is implemented as a
+   blocking function call, the association parameters are returned as a
+   result of the ASSOCIATE primitive itself.  In that case,
+   COMMUNICATION UP notification is optional at the association
+   initiator's side.
+
+   The following shall be passed with the notification:
+
+   o  association id -  local handle to the SCTP association.
+
+   o  status -  This indicates what type of event has occurred.
+
+   o  destination transport address list -  the complete set of
+      transport addresses of the peer.
+
+   o  outbound stream count -  the maximum number of streams allowed to
+      be used in this association by the ULP.
+
+   o  inbound stream count -  the number of streams the peer endpoint
+      has requested with this association (this may not be the same
+      number as 'outbound stream count').
+
+   E) COMMUNICATION LOST notification
+
+   When SCTP loses communication to an endpoint completely (e.g., via
+   Heartbeats) or detects that the endpoint has performed an abort
+   operation, it shall invoke this notification on the ULP.
+
+   The following shall be passed with the notification:
+
+   o  association id -  local handle to the SCTP association.
+
+   o  status -  this indicates what type of event has occurred; the
+                status may indicate that a failure OR a normal
+                termination event occurred in response to a shutdown or
+                abort request.
+
+   The following may be passed with the notification:
+
+   o  data retrieval id -  an identification used to retrieve unsent and
+      unacknowledged data.
+
+
+
+
+Stewart                     Standards Track                   [Page 122]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   o  last-acked -  the TSN last acked by that peer endpoint.
+
+   o  last-sent -  the TSN last sent to that peer endpoint.
+
+   o  Upper Layer Abort Reason -  the abort reason specified in case of
+      a user-initiated abort.
+
+   F) COMMUNICATION ERROR notification
+
+   When SCTP receives an ERROR chunk from its peer and decides to notify
+   its ULP, it can invoke this notification on the ULP.
+
+   The following can be passed with the notification:
+
+   o  association id -  local handle to the SCTP association.
+
+   o  error info -  this indicates the type of error and optionally some
+      additional information received through the ERROR chunk.
+
+   G) RESTART notification
+
+   When SCTP detects that the peer has restarted, it may send this
+   notification to its ULP.
+
+   The following can be passed with the notification:
+
+   o  association id -  local handle to the SCTP association.
+
+   H) SHUTDOWN COMPLETE notification
+
+   When SCTP completes the shutdown procedures (Section 9.2), this
+   notification is passed to the upper layer.
+
+   The following can be passed with the notification:
+
+   o  association id -  local handle to the SCTP association.
+
+11.  Security Considerations
+
+11.1.  Security Objectives
+
+   As a common transport protocol designed to reliably carry time-
+   sensitive user messages, such as billing or signaling messages for
+   telephony services, between two networked endpoints, SCTP has the
+   following security objectives.
+
+   -  availability of reliable and timely data transport services
+
+
+
+
+Stewart                     Standards Track                   [Page 123]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   -  integrity of the user-to-user information carried by SCTP
+
+11.2.  SCTP Responses to Potential Threats
+
+   SCTP may potentially be used in a wide variety of risk situations.
+   It is important for operators of systems running SCTP to analyze
+   their particular situations and decide on the appropriate counter-
+   measures.
+
+   Operators of systems running SCTP should consult [RFC2196] for
+   guidance in securing their site.
+
+11.2.1.  Countering Insider Attacks
+
+   The principles of [RFC2196] should be applied to minimize the risk of
+   theft of information or sabotage by insiders.  Such procedures
+   include publication of security policies, control of access at the
+   physical, software, and network levels, and separation of services.
+
+11.2.2.  Protecting against Data Corruption in the Network
+
+   Where the risk of undetected errors in datagrams delivered by the
+   lower-layer transport services is considered to be too great,
+   additional integrity protection is required.  If this additional
+   protection were provided in the application layer, the SCTP header
+   would remain vulnerable to deliberate integrity attacks.  While the
+   existing SCTP mechanisms for detection of packet replays are
+   considered sufficient for normal operation, stronger protections are
+   needed to protect SCTP when the operating environment contains
+   significant risk of deliberate attacks from a sophisticated
+   adversary.
+
+   The SCTP Authentication extension SCTP-AUTH [RFC4895] MAY be used
+   when the threat environment requires stronger integrity protections,
+   but does not require confidentiality.
+
+11.2.3.  Protecting Confidentiality
+
+   In most cases, the risk of breach of confidentiality applies to the
+   signaling data payload, not to the SCTP or lower-layer protocol
+   overheads.  If that is true, encryption of the SCTP user data only
+   might be considered.  As with the supplementary checksum service,
+   user data encryption MAY be performed by the SCTP user application.
+   Alternately, the user application MAY use an implementation-specific
+   API to request that the IP Encapsulating Security Payload (ESP)
+   [RFC4303] be used to provide confidentiality and integrity.
+
+
+
+
+
+Stewart                     Standards Track                   [Page 124]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   Particularly for mobile users, the requirement for confidentiality
+   might include the masking of IP addresses and ports.  In this case,
+   ESP SHOULD be used instead of application-level confidentiality.  If
+   ESP is used to protect confidentiality of SCTP traffic, an ESP
+   cryptographic transform that includes cryptographic integrity
+   protection MUST be used, because if there is a confidentiality threat
+   there will also be a strong integrity threat.
+
+   Whenever ESP is in use, application-level encryption is not generally
+   required.
+
+   Regardless of where confidentiality is provided, the Internet Key
+   Exchange Protocol version 2 (IKEv2) [RFC4306] SHOULD be used for key
+   management.
+
+   Operators should consult [RFC4301] for more information on the
+   security services available at and immediately above the Internet
+   Protocol layer.
+
+11.2.4.  Protecting against Blind Denial-of-Service Attacks
+
+   A blind attack is one where the attacker is unable to intercept or
+   otherwise see the content of data flows passing to and from the
+   target SCTP node.  Blind denial-of-service attacks may take the form
+   of flooding, masquerade, or improper monopolization of services.
+
+11.2.4.1.  Flooding
+
+   The objective of flooding is to cause loss of service and incorrect
+   behavior at target systems through resource exhaustion, interference
+   with legitimate transactions, and exploitation of buffer-related
+   software bugs.  Flooding may be directed either at the SCTP node or
+   at resources in the intervening IP Access Links or the Internet.
+   Where the latter entities are the target, flooding will manifest
+   itself as loss of network services, including potentially the breach
+   of any firewalls in place.
+
+   In general, protection against flooding begins at the equipment
+   design level, where it includes measures such as:
+
+   -  avoiding commitment of limited resources before determining that
+      the request for service is legitimate.
+
+   -  giving priority to completion of processing in progress over the
+      acceptance of new work.
+
+   -  identification and removal of duplicate or stale queued requests
+      for service.
+
+
+
+Stewart                     Standards Track                   [Page 125]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   -  not responding to unexpected packets sent to non-unicast
+      addresses.
+
+   Network equipment should be capable of generating an alarm and log if
+   a suspicious increase in traffic occurs.  The log should provide
+   information such as the identity of the incoming link and source
+   address(es) used, which will help the network or SCTP system operator
+   to take protective measures.  Procedures should be in place for the
+   operator to act on such alarms if a clear pattern of abuse emerges.
+
+   The design of SCTP is resistant to flooding attacks, particularly in
+   its use of a four-way startup handshake, its use of a cookie to defer
+   commitment of resources at the responding SCTP node until the
+   handshake is completed, and its use of a Verification Tag to prevent
+   insertion of extraneous packets into the flow of an established
+   association.
+
+   The IP Authentication Header and Encapsulating Security Payload might
+   be useful in reducing the risk of certain kinds of denial-of-service
+   attacks.
+
+   The use of the host name feature in the INIT chunk could be used to
+   flood a target DNS server.  A large backlog of DNS queries, resolving
+   the host name received in the INIT chunk to IP addresses, could be
+   accomplished by sending INITs to multiple hosts in a given domain.
+   In addition, an attacker could use the host name feature in an
+   indirect attack on a third party by sending large numbers of INITs to
+   random hosts containing the host name of the target.  In addition to
+   the strain on DNS resources, this could also result in large numbers
+   of INIT ACKs being sent to the target.  One method to protect against
+   this type of attack is to verify that the IP addresses received from
+   DNS include the source IP address of the original INIT.  If the list
+   of IP addresses received from DNS does not include the source IP
+   address of the INIT, the endpoint MAY silently discard the INIT.
+   This last option will not protect against the attack against the DNS.
+
+11.2.4.2.  Blind Masquerade
+
+   Masquerade can be used to deny service in several ways:
+
+   -  by tying up resources at the target SCTP node to which the
+      impersonated node has limited access.  For example, the target
+      node may by policy permit a maximum of one SCTP association with
+      the impersonated SCTP node.  The masquerading attacker may attempt
+      to establish an association purporting to come from the
+      impersonated node so that the latter cannot do so when it requires
+      it.
+
+
+
+
+Stewart                     Standards Track                   [Page 126]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   -  by deliberately allowing the impersonation to be detected, thereby
+      provoking counter-measures that cause the impersonated node to be
+      locked out of the target SCTP node.
+
+   -  by interfering with an established association by inserting
+      extraneous content such as a SHUTDOWN request.
+
+   SCTP reduces the risk of blind masquerade attacks through IP spoofing
+   by use of the four-way startup handshake.  Because the initial
+   exchange is memory-less, no lockout mechanism is triggered by blind
+   masquerade attacks.  In addition, the INIT ACK containing the State
+   Cookie is transmitted back to the IP address from which it received
+   the INIT.  Thus, the attacker would not receive the INIT ACK
+   containing the State Cookie.  SCTP protects against insertion of
+   extraneous packets into the flow of an established association by use
+   of the Verification Tag.
+
+   Logging of received INIT requests and abnormalities such as
+   unexpected INIT ACKs might be considered as a way to detect patterns
+   of hostile activity.  However, the potential usefulness of such
+   logging must be weighed against the increased SCTP startup processing
+   it implies, rendering the SCTP node more vulnerable to flooding
+   attacks.  Logging is pointless without the establishment of operating
+   procedures to review and analyze the logs on a routine basis.
+
+11.2.4.3.  Improper Monopolization of Services
+
+   Attacks under this heading are performed openly and legitimately by
+   the attacker.  They are directed against fellow users of the target
+   SCTP node or of the shared resources between the attacker and the
+   target node.  Possible attacks include the opening of a large number
+   of associations between the attacker's node and the target, or
+   transfer of large volumes of information within a legitimately
+   established association.
+
+   Policy limits should be placed on the number of associations per
+   adjoining SCTP node.  SCTP user applications should be capable of
+   detecting large volumes of illegitimate or "no-op" messages within a
+   given association and either logging or terminating the association
+   as a result, based on local policy.
+
+11.3.  SCTP Interactions with Firewalls
+
+   It is helpful for some firewalls if they can inspect just the first
+   fragment of a fragmented SCTP packet and unambiguously determine
+   whether it corresponds to an INIT chunk (for further information,
+   please refer to [RFC1858]).  Accordingly, we stress the requirements,
+   stated in Section 3.1, that (1) an INIT chunk MUST NOT be bundled
+
+
+
+Stewart                     Standards Track                   [Page 127]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   with any other chunk in a packet, and (2) a packet containing an INIT
+   chunk MUST have a zero Verification Tag.  Furthermore, we require
+   that the receiver of an INIT chunk MUST enforce these rules by
+   silently discarding an arriving packet  with an INIT chunk that is
+   bundled with other chunks or has a non-zero verification tag and
+   contains an INIT-chunk.
+
+11.4.  Protection of Non-SCTP-Capable Hosts
+
+   To provide a non-SCTP-capable host with the same level of protection
+   against attacks as for SCTP-capable ones, all SCTP stacks MUST
+   implement the ICMP handling described in Appendix C.
+
+   When an SCTP stack receives a packet containing multiple control or
+   DATA chunks and the processing of the packet requires the sending of
+   multiple chunks in response, the sender of the response chunk(s) MUST
+   NOT send more than one packet.  If bundling is supported, multiple
+   response chunks that fit into a single packet MAY be bundled together
+   into one single response packet.  If bundling is not supported, then
+   the sender MUST NOT send more than one response chunk and MUST
+   discard all other responses.  Note that this rule does NOT apply to a
+   SACK chunk, since a SACK chunk is, in itself, a response to DATA and
+   a SACK does not require a response of more DATA.
+
+   An SCTP implementation SHOULD abort the association if it receives a
+   SACK acknowledging a TSN that has not been sent.
+
+   An SCTP implementation that receives an INIT that would require a
+   large packet in response, due to the inclusion of multiple ERROR
+   parameters, MAY (at its discretion) elect to omit some or all of the
+   ERROR parameters to reduce the size of the INIT ACK.  Due to a
+   combination of the size of the COOKIE parameter and the number of
+   addresses a receiver of an INIT may be indicating to a peer, it is
+   always possible that the INIT ACK will be larger than the original
+   INIT.  An SCTP implementation SHOULD attempt to make the INIT ACK as
+   small as possible to reduce the possibility of byte amplification
+   attacks.
+
+12.  Network Management Considerations
+
+   The MIB module for SCTP defined in [RFC3873] applies for the version
+   of the protocol specified in this document.
+
+
+
+
+
+
+
+
+
+Stewart                     Standards Track                   [Page 128]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+13.  Recommended Transmission Control Block (TCB) Parameters
+
+   This section details a recommended set of parameters that should be
+   contained within the TCB for an implementation.  This section is for
+   illustrative purposes and should not be deemed as requirements on an
+   implementation or as an exhaustive list of all parameters inside an
+   SCTP TCB.  Each implementation may need its own additional parameters
+   for optimization.
+
+13.1.  Parameters Necessary for the SCTP Instance
+
+   Associations: A list of current associations and mappings to the data
+                 consumers for each association.  This may be in the
+                 form of a hash table or other implementation-dependent
+                 structure.  The data consumers may be process
+                 identification information such as file descriptors,
+                 named pipe pointer, or table pointers dependent on how
+                 SCTP is implemented.
+
+   Secret Key:   A secret key used by this endpoint to compute the MAC.
+                 This SHOULD be a cryptographic quality random number
+                 with a sufficient length.  Discussion in RFC 4086 can
+                 be helpful in selection of the key.
+
+   Address List: The list of IP addresses that this instance has bound.
+                 This information is passed to one's peer(s) in INIT and
+                 INIT ACK chunks.
+
+   SCTP Port:    The local SCTP port number to which the endpoint is
+                 bound.
+
+13.2.  Parameters Necessary per Association (i.e., the TCB)
+
+   Peer        : Tag value to be sent in every packet and is received
+   Verification: in the INIT or INIT ACK chunk.
+   Tag         :
+
+   My          : Tag expected in every inbound packet and sent in the
+   Verification: INIT or INIT ACK chunk.
+   Tag         :
+
+   State       : A state variable indicating what state the association
+               : is in, i.e., COOKIE-WAIT, COOKIE-ECHOED, ESTABLISHED,
+               : SHUTDOWN-PENDING, SHUTDOWN-SENT, SHUTDOWN-RECEIVED,
+               : SHUTDOWN-ACK-SENT.
+
+                 Note: No "CLOSED" state is illustrated since if a
+                 association is "CLOSED" its TCB SHOULD be removed.
+
+
+
+Stewart                     Standards Track                   [Page 129]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   Peer        : A list of SCTP transport addresses to which the peer
+   Transport   : is bound.  This information is derived from the INIT or
+   Address     : INIT ACK and is used to associate an inbound packet
+   List        : with a given association.  Normally, this information
+               : is hashed or keyed for quick lookup and access of the
+               : TCB.
+
+   Primary     : This is the current primary destination transport
+   Path        : address of the peer endpoint.  It may also specify a
+               : source transport address on this endpoint.
+
+   Overall     : The overall association error count.
+   Error Count :
+
+   Overall     : The threshold for this association that if the Overall
+   Error       : Error Count reaches will cause this association to be
+   Threshold   : torn down.
+
+   Peer Rwnd   : Current calculated value of the peer's rwnd.
+
+   Next TSN    : The next TSN number to be assigned to a new DATA chunk.
+               : This is sent in the INIT or INIT ACK chunk to the peer
+               : and incremented each time a DATA chunk is assigned a
+               : TSN (normally just prior to transmit or during
+               : fragmentation).
+
+   Last Rcvd   : This is the last TSN received in sequence.  This value
+   TSN         : is set initially by taking the peer's initial TSN,
+               : received in the INIT or INIT ACK chunk, and
+               : subtracting one from it.
+
+   Mapping     : An array of bits or bytes indicating which out-of-
+   Array       : order TSNs have been received (relative to the
+               : Last Rcvd TSN).  If no gaps exist, i.e., no out-of-
+               : order packets have been received, this array will
+               : be set to all zero.  This structure may be in the
+               : form of a circular buffer or bit array.
+
+   Ack State   : This flag indicates if the next received packet
+               : is to be responded to with a SACK.  This is initialized
+               : to 0.  When a packet is received it is incremented.
+               : If this value reaches 2 or more, a SACK is sent and the
+               : value is reset to 0.  Note: This is used only when no
+               : DATA chunks are received out of order.  When DATA
+               : chunks are out of order, SACKs are not delayed (see
+               : Section 6).
+
+
+
+
+
+Stewart                     Standards Track                   [Page 130]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   Inbound     : An array of structures to track the inbound streams,
+   Streams     : normally including the next sequence number expected
+               : and possibly the stream number.
+
+   Outbound    : An array of structures to track the outbound streams,
+   Streams     : normally including the next sequence number to
+               : be sent on the stream.
+
+   Reasm Queue : A reassembly queue.
+
+   Local       : The list of local IP addresses bound in to this
+   Transport   : association.
+   Address     :
+   List        :
+
+   Association : The smallest PMTU discovered for all of the
+   PMTU        : peer's transport addresses.
+
+13.3.  Per Transport Address Data
+
+   For each destination transport address in the peer's address list
+   derived from the INIT or INIT ACK chunk, a number of data elements
+   need to be maintained including:
+
+   Error Count : The current error count for this destination.
+
+   Error       : Current error threshold for this destination, i.e.,
+   Threshold   : what value marks the destination down if error count
+               : reaches this value.
+
+   cwnd        : The current congestion window.
+
+   ssthresh    : The current ssthresh value.
+
+   RTO         : The current retransmission timeout value.
+
+   SRTT        : The current smoothed round-trip time.
+
+   RTTVAR      : The current RTT variation.
+
+   partial     : The tracking method for increase of cwnd when in
+   bytes acked : congestion avoidance mode (see Section 7.2.2).
+
+   state       : The current state of this destination, i.e., DOWN, UP,
+               : ALLOW-HB, NO-HEARTBEAT, etc.
+
+
+
+
+
+
+Stewart                     Standards Track                   [Page 131]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   PMTU        : The current known path MTU.
+
+   Per         : A timer used by each destination.
+   Destination :
+   Timer       :
+
+   RTO-Pending : A flag used to track if one of the DATA chunks sent to
+               : this address is currently being used to compute an
+               : RTT.  If this flag is 0, the next DATA chunk sent to
+               : this destination should be used to compute an RTT and
+               : this flag should be set.  Every time the RTT
+               : calculation completes (i.e., the DATA chunk is SACK'd),
+               : clear this flag.
+
+   last-time   : The time to which this destination was last sent.
+               : This can be to determine if a HEARTBEAT is needed.
+
+13.4.  General Parameters Needed
+
+   Out Queue : A queue of outbound DATA chunks.
+
+   In Queue  : A queue of inbound DATA chunks.
+
+14.  IANA Considerations
+
+   SCTP defines three registries that IANA maintains:
+
+   -  through definition of additional chunk types,
+   -  through definition of additional parameter types, or
+   -  through definition of additional cause codes within ERROR chunks.
+
+   SCTP requires that the IANA Port Numbers registry be opened for SCTP
+   port registrations, Section 14.5 describes how.  An IESG-appointed
+   Expert Reviewer supports IANA in evaluating SCTP port allocation
+   requests.
+
+14.1.  IETF-Defined Chunk Extension
+
+   The assignment of new chunk parameter type codes is done through an
+   IETF Consensus action, as defined in [RFC2434].  Documentation of the
+   chunk parameter MUST contain the following information:
+
+   a) A long and short name for the new chunk type.
+
+   b) A detailed description of the structure of the chunk, which MUST
+      conform to the basic structure defined in Section 3.2.
+
+
+
+
+
+Stewart                     Standards Track                   [Page 132]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   c) A detailed definition and description of intended use of each
+      field within the chunk, including the chunk flags if any.
+
+   d) A detailed procedural description of the use of the new chunk type
+      within the operation of the protocol.
+
+   The last chunk type (255) is reserved for future extension if
+   necessary.
+
+14.2.  IETF-Defined Chunk Parameter Extension
+
+   The assignment of new chunk parameter type codes is done through an
+   IETF Consensus action as defined in [RFC2434].  Documentation of the
+   chunk parameter MUST contain the following information:
+
+   a) Name of the parameter type.
+
+   b) Detailed description of the structure of the parameter field.
+      This structure MUST conform to the general Type-Length-Value
+      format described in Section 3.2.1.
+
+   c) Detailed definition of each component of the parameter value.
+
+   d) Detailed description of the intended use of this parameter type,
+      and an indication of whether and under what circumstances multiple
+      instances of this parameter type may be found within the same
+      chunk.
+
+   e) Each parameter type MUST be unique across all chunks.
+
+14.3.  IETF-Defined Additional Error Causes
+
+   Additional cause codes may be allocated in the range 11 to 65535
+   through a Specification Required action as defined in [RFC2434].
+   Provided documentation must include the following information:
+
+   a) Name of the error condition.
+
+   b) Detailed description of the conditions under which an SCTP
+      endpoint should issue an ERROR (or ABORT) with this cause code.
+
+   c) Expected action by the SCTP endpoint that receives an ERROR (or
+      ABORT) chunk containing this cause code.
+
+   d) Detailed description of the structure and content of data fields
+      that accompany this cause code.
+
+
+
+
+
+Stewart                     Standards Track                   [Page 133]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   The initial word (32 bits) of a cause code parameter MUST conform to
+   the format shown in Section 3.3.10, i.e.:
+
+   -  first 2 bytes contain the cause code value
+   -  last 2 bytes contain the length of the cause parameter.
+
+14.4.  Payload Protocol Identifiers
+
+   Except for value 0, which is reserved by SCTP to indicate an
+   unspecified payload protocol identifier in a DATA chunk, SCTP will
+   not be responsible for standardizing or verifying any payload
+   protocol identifiers; SCTP simply receives the identifier from the
+   upper layer and carries it with the corresponding payload data.
+
+   The upper layer, i.e., the SCTP user, SHOULD standardize any specific
+   protocol identifier with IANA if it is so desired.  The use of any
+   specific payload protocol identifier is out of the scope of SCTP.
+
+14.5.  Port Numbers Registry
+
+   SCTP services may use contact port numbers to provide service to
+   unknown callers, as in TCP and UDP.  IANA is therefore requested to
+   open the existing Port Numbers registry for SCTP using the following
+   rules, which we intend to mesh well with existing Port Numbers
+   registration procedures.  An IESG-appointed Expert Reviewer supports
+   IANA in evaluating SCTP port allocation requests, according to the
+   procedure defined in [RFC2434].
+
+   Port numbers are divided into three ranges.  The Well Known Ports are
+   those from 0 through 1023, the Registered Ports are those from 1024
+   through 49151, and the Dynamic and/or Private Ports are those from
+   49152 through 65535.  Well Known and Registered Ports are intended
+   for use by server applications that desire a default contact point on
+   a system.  On most systems, Well Known Ports can only be used by
+   system (or root) processes or by programs executed by privileged
+   users, while Registered Ports can be used by ordinary user processes
+   or programs executed by ordinary users.  Dynamic and/or Private Ports
+   are intended for temporary use, including client-side ports, out-of-
+   band negotiated ports, and application testing prior to registration
+   of a dedicated port; they MUST NOT be registered.
+
+   The Port Numbers registry should accept registrations for SCTP ports
+   in the Well Known Ports and Registered Ports ranges.  Well Known and
+   Registered Ports SHOULD NOT be used without registration.  Although
+   in some cases -- such as porting an application from TCP to SCTP --
+   it may seem natural to use an SCTP port before registration
+   completes, we emphasize that IANA will not guarantee registration of
+
+
+
+
+Stewart                     Standards Track                   [Page 134]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   particular Well Known and Registered Ports.  Registrations should be
+   requested as early as possible.
+
+   Each port registration SHALL include the following information:
+
+   o  A short port name, consisting entirely of letters (A-Z and a-z),
+      digits (0-9), and punctuation characters from "-_+./*" (not
+      including the quotes).
+
+   o  The port number that is requested for registration.
+
+   o  A short English phrase describing the port's purpose.
+
+   o  Name and contact information for the person or entity performing
+      the registration, and possibly a reference to a document defining
+      the port's use.  Registrations coming from IETF working groups
+      need only name the working group, but indicating a contact person
+      is recommended.
+
+   Registrants are encouraged to follow these guidelines when submitting
+   a registration.
+
+   o  A port name SHOULD NOT be registered for more than one SCTP port
+      number.
+
+   o  A port name registered for TCP MAY be registered for SCTP as well.
+      Any such registration SHOULD use the same port number as the
+      existing TCP registration.
+
+   o  Concrete intent to use a port SHOULD precede port registration.
+      For example, existing TCP ports SHOULD NOT be registered in
+      advance of any intent to use those ports for SCTP.
+
+      This document registers the following ports.  (These registrations
+      should be considered models to follow for future allocation
+      requests.)
+
+         discard    9/sctp  Discard  # IETF TSVWG
+                                     # Randall Stewart <rrs@cisco.com>
+                                     # [RFC4960]
+
+            The discard service, which accepts SCTP connections on port
+            9, discards all incoming application data and sends no data
+            in response.  Thus, SCTP's discard port is analogous to
+            TCP's discard port, and might be used to check the health
+            of an SCTP stack.
+
+
+
+
+
+Stewart                     Standards Track                   [Page 135]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+         ftp-data  20/sctp  FTP      # IETF TSVWG
+                                     # Randall Stewart <rrs@cisco.com>
+                                     # [RFC4960]
+
+         ftp       21/sctp  FTP      # IETF TSVWG
+                                     # Randall Stewart <rrs@cisco.com>
+                                     # [RFC4960]
+
+            File Transfer Protocol (FTP) data (20) and control ports
+            (21).
+
+         ssh       22/sctp  SSH      # IETF TSVWG
+                                     # Randall Stewart <rrs@cisco.com>
+                                     # [RFC4960]
+
+            The Secure Shell (SSH) remote login service, which allows
+            secure shell logins to a host.
+
+         http      80/sctp  HTTP     # IETF TSVWG
+                                     # Randall Stewart <rrs@cisco.com>
+                                     # [RFC4960]
+
+            World Wide Web HTTP over SCTP.
+
+         bgp      179/sctp  BGP      # IETF TSVWG
+                                     # Randall Stewart <rrs@cisco.com>
+                                     # [RFC4960]
+
+            Border Gateway Protocol over SCTP.
+
+         https    443/sctp  HTTPS    # IETF TSVWG
+                                     # Randall Stewart <rrs@cisco.com>
+                                     # [RFC4960]
+
+            World Wide Web HTTP over TLS/SSL over SCTP.
+
+15.  Suggested SCTP Protocol Parameter Values
+
+   The following protocol parameters are RECOMMENDED:
+
+      RTO.Initial - 3 seconds
+      RTO.Min - 1 second
+      RTO.Max - 60 seconds
+      Max.Burst - 4
+      RTO.Alpha - 1/8
+      RTO.Beta - 1/4
+      Valid.Cookie.Life - 60 seconds
+      Association.Max.Retrans - 10 attempts
+
+
+
+Stewart                     Standards Track                   [Page 136]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+      Path.Max.Retrans - 5 attempts (per destination address)
+      Max.Init.Retransmits - 8 attempts
+      HB.interval - 30 seconds
+      HB.Max.Burst - 1
+
+   IMPLEMENTATION NOTE: The SCTP implementation may allow ULP to
+   customize some of these protocol parameters (see Section 10).
+
+   Note: RTO.Min SHOULD be set as recommended above.
+
+16.  Acknowledgements
+
+   An undertaking represented by this updated document is not a small
+   feat and represents the summation of the initial authors of RFC 2960:
+   Q. Xie, K. Morneault, C. Sharp, H. Schwarzbauer, T. Taylor, I.
+   Rytina, M. Kalla, L. Zhang, and V. Paxson.
+
+   Add to that, the comments from everyone who contributed to the
+   original RFC:
+
+   Mark Allman, R.J. Atkinson, Richard Band, Scott Bradner, Steve
+   Bellovin, Peter Butler, Ram Dantu, R. Ezhirpavai, Mike Fisk, Sally
+   Floyd, Atsushi Fukumoto, Matt Holdrege, Henry Houh, Christian
+   Huitema, Gary Lehecka, Jonathan Lee, David Lehmann, John Loughney,
+   Daniel Luan, Barry Nagelberg, Thomas Narten, Erik Nordmark, Lyndon
+   Ong, Shyamal Prasad, Kelvin Porter, Heinz Prantner, Jarno Rajahalme,
+   Raymond E. Reeves, Renee Revis, Ivan Arias Rodriguez, A. Sankar, Greg
+   Sidebottom, Brian Wyld, La Monte Yarroll, and many others for their
+   invaluable comments.
+
+   Then, add the authors of the SCTP implementor's guide, I. Arias-
+   Rodriguez, K. Poon, A. Caro, and M. Tuexen.
+
+   Then add to these the efforts of all the subsequent seven SCTP
+   interoperability tests and those who commented on RFC 4460 as shown
+   in its acknowledgements:
+
+   Barry Zuckerman, La Monte Yarroll, Qiaobing Xie, Wang Xiaopeng,
+   Jonathan Wood, Jeff Waskow, Mike Turner, John Townsend, Sabina
+   Torrente, Cliff Thomas, Yuji Suzuki, Manoj Solanki, Sverre Slotte,
+   Keyur Shah, Jan Rovins, Ben Robinson, Renee Revis, Ian Periam, RC
+   Monee, Sanjay Rao, Sujith Radhakrishnan, Heinz Prantner, Biren Patel,
+   Nathalie Mouellic, Mitch Miers, Bernward Meyknecht, Stan McClellan,
+   Oliver Mayor, Tomas Orti Martin, Sandeep Mahajan, David Lehmann,
+   Jonathan Lee, Philippe Langlois, Karl Knutson, Joe Keller, Gareth
+   Keily, Andreas Jungmaier, Janardhan Iyengar, Mutsuya Irie, John
+   Hebert, Kausar Hassan, Fred Hasle, Dan Harrison, Jon Grim, Laurent
+   Glaude, Steven Furniss, Atsushi Fukumoto, Ken Fujita, Steve Dimig,
+
+
+
+Stewart                     Standards Track                   [Page 137]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   Thomas Curran, Serkan Cil, Melissa Campbell, Peter Butler, Rob
+   Brennan, Harsh Bhondwe, Brian Bidulock, Caitlin Bestler, Jon Berger,
+   Robby Benedyk, Stephen Baucke, Sandeep Balani, and Ronnie Sellar.
+
+   A special thanks to Mark Allman, who should actually be a co-author
+   for his work on the max-burst, but managed to wiggle out due to a
+   technicality.  Also, we would like to acknowledge Lyndon Ong and Phil
+   Conrad for their valuable input and many contributions.
+
+   And finally, you have this document, and those who have commented
+   upon that including Alfred Hoenes and Ronnie Sellars.
+
+   My thanks cannot be adequately expressed to all of you who have
+   participated in the coding, testing, and updating process of this
+   document.  All I can say is, Thank You!
+
+   Randall Stewart - Editor
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart                     Standards Track                   [Page 138]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+Appendix A.  Explicit Congestion Notification
+
+   ECN [RFC3168] describes a proposed extension to IP that details a
+   method to become aware of congestion outside of datagram loss.  This
+   is an optional feature that an implementation MAY choose to add to
+   SCTP.  This appendix details the minor differences implementers will
+   need to be aware of if they choose to implement this feature.  In
+   general, [RFC3168] should be followed with the following exceptions.
+
+   Negotiation:
+
+   [RFC3168] details negotiation of ECN during the SYN and SYN-ACK
+   stages of a TCP connection.  The sender of the SYN sets 2 bits in the
+   TCP flags, and the sender of the SYN-ACK sets only 1 bit.  The
+   reasoning behind this is to ensure that both sides are truly ECN
+   capable.  For SCTP, this is not necessary.  To indicate that an
+   endpoint is ECN capable, an endpoint SHOULD add to the INIT and or
+   INIT ACK chunk the TLV reserved for ECN.  This TLV contains no
+   parameters, and thus has the following format:
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |   Parameter Type = 32768      |     Parameter Length = 4      |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   ECN-Echo:
+
+   [RFC3168] details a specific bit for a receiver to send back in its
+   TCP acknowledgements to notify the sender of the Congestion
+   Experienced (CE) bit having arrived from the network.  For SCTP, this
+   same indication is made by including the ECNE chunk.  This chunk
+   contains one data element, i.e., the lowest TSN associated with the
+   IP datagram marked with the CE bit, and looks as follows:
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       | Chunk Type=12 | Flags=00000000|    Chunk Length = 8           |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                      Lowest TSN Number                        |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+       Note: The ECNE is considered a Control chunk.
+
+
+
+
+
+
+
+Stewart                     Standards Track                   [Page 139]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   CWR:
+
+   [RFC3168] details a specific bit for a sender to send in the header
+   of its next outbound TCP segment to indicate to its peer that it has
+   reduced its congestion window.  This is termed the CWR bit.  For
+   SCTP, the same indication is made by including the CWR chunk.  This
+   chunk contains one data element, i.e., the TSN number that was sent
+   in the ECNE chunk.  This element represents the lowest TSN number in
+   the datagram that was originally marked with the CE bit.
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       | Chunk Type=13 | Flags=00000000|    Chunk Length = 8           |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                      Lowest TSN Number                        |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+       Note: The CWR is considered a Control chunk.
+
+Appendix B.  CRC32c Checksum Calculation
+
+   We define a 'reflected value' as one that is the opposite of the
+   normal bit order of the machine.  The 32-bit CRC (Cyclic Redundancy
+   Check) is calculated as described for CRC32c and uses the polynomial
+   code 0x11EDC6F41 (Castagnoli93) or x^32+x^28+x^27+x^26+x^25
+   +x^23+x^22+x^20+x^19+x^18+ x^14+x^13+x^11+x^10+x^9+x^8+x^6+x^0.  The
+   CRC is computed using a procedure similar to ETHERNET CRC [ITU32],
+   modified to reflect transport-level usage.
+
+   CRC computation uses polynomial division.  A message bit-string M is
+   transformed to a polynomial, M(X), and the CRC is calculated from
+   M(X) using polynomial arithmetic.
+
+   When CRCs are used at the link layer, the polynomial is derived from
+   on-the-wire bit ordering: the first bit 'on the wire' is the high-
+   order coefficient.  Since SCTP is a transport-level protocol, it
+   cannot know the actual serial-media bit ordering.  Moreover,
+   different links in the path between SCTP endpoints may use different
+   link-level bit orders.
+
+   A convention must therefore be established for mapping SCTP transport
+   messages to polynomials for purposes of CRC computation.  The bit-
+   ordering for mapping SCTP messages to polynomials is that bytes are
+   taken most-significant first, but within each byte, bits are taken
+   least-significant first.  The first byte of the message provides the
+   eight highest coefficients.  Within each byte, the least-significant
+   SCTP bit gives the most-significant polynomial coefficient within
+
+
+
+Stewart                     Standards Track                   [Page 140]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   that byte, and the most-significant SCTP bit is the least-significant
+   polynomial coefficient in that byte.  (This bit ordering is sometimes
+   called 'mirrored' or 'reflected' [WILLIAMS93].)  CRC polynomials are
+   to be transformed back into SCTP transport-level byte values, using a
+   consistent mapping.
+
+   The SCTP transport-level CRC value should be calculated as follows:
+
+   -  CRC input data are assigned to a byte stream, numbered from 0 to
+      N-1.
+
+   -  The transport-level byte stream is mapped to a polynomial value.
+      An N-byte PDU with j bytes numbered 0 to N-1 is considered as
+      coefficients of a polynomial M(x) of order 8N-1, with bit 0 of
+      byte j being coefficient x^(8(N-j)-8), and bit 7 of byte j being
+      coefficient x^(8(N-j)-1).
+
+   -  The CRC remainder register is initialized with all 1s and the CRC
+      is computed with an algorithm that simultaneously multiplies by
+      x^32 and divides by the CRC polynomial.
+
+   -  The polynomial is multiplied by x^32 and divided by G(x), the
+      generator polynomial, producing a remainder R(x) of degree less
+      than or equal to 31.
+
+   -  The coefficients of R(x) are considered a 32-bit sequence.
+
+   -  The bit sequence is complemented.  The result is the CRC
+      polynomial.
+
+   -  The CRC polynomial is mapped back into SCTP transport-level bytes.
+      The coefficient of x^31 gives the value of bit 7 of SCTP byte 0,
+      and the coefficient of x^24 gives the value of bit 0 of byte 0.
+      The coefficient of x^7 gives bit 7 of byte 3, and the coefficient
+      of x^0 gives bit 0 of byte 3.  The resulting 4-byte transport-
+      level sequence is the 32-bit SCTP checksum value.
+
+   IMPLEMENTATION NOTE: Standards documents, textbooks, and vendor
+   literature on CRCs often follow an alternative formulation, in which
+   the register used to hold the remainder of the long-division
+   algorithm is initialized to zero rather than all-1s, and instead the
+   first 32 bits of the message are complemented.  The long-division
+   algorithm used in our formulation is specified such that the initial
+   multiplication by 2^32 and the long-division are combined into one
+   simultaneous operation.  For such algorithms, and for messages longer
+   than 64 bits, the two specifications are precisely equivalent.  That
+   equivalence is the intent of this document.
+
+
+
+
+Stewart                     Standards Track                   [Page 141]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   Implementors of SCTP are warned that both specifications are to be
+   found in the literature, sometimes with no restriction on the long-
+   division algorithm.  The choice of formulation in this document is to
+   permit non-SCTP usage, where the same CRC algorithm may be used to
+   protect messages shorter than 64 bits.
+
+   There may be a computational advantage in validating the association
+   against the Verification Tag, prior to performing a checksum, as
+   invalid tags will result in the same action as a bad checksum in most
+   cases.  The exceptions for this technique would be INIT and some
+   SHUTDOWN-COMPLETE exchanges, as well as a stale COOKIE ECHO.  These
+   special-case exchanges must represent small packets and will minimize
+   the effect of the checksum calculation.
+
+Appendix C.  ICMP Handling
+
+   Whenever an ICMP message is received by an SCTP endpoint, the
+   following procedures MUST be followed to ensure proper utilization of
+   the information being provided by layer 3.
+
+   ICMP1) An implementation MAY ignore all ICMPv4 messages where the
+          type field is not set to "Destination Unreachable".
+
+   ICMP2) An implementation MAY ignore all ICMPv6 messages where the
+          type field is not "Destination Unreachable", "Parameter
+          Problem",, or "Packet Too Big".
+
+   ICMP3) An implementation MAY ignore any ICMPv4 messages where the
+          code does not indicate "Protocol Unreachable" or
+          "Fragmentation Needed".
+
+   ICMP4) An implementation MAY ignore all ICMPv6 messages of type
+          "Parameter Problem" if the code is not "Unrecognized Next
+          Header Type Encountered".
+
+   ICMP5) An implementation MUST use the payload of the ICMP message (v4
+          or v6) to locate the association that sent the message to
+          which ICMP is responding.  If the association cannot be found,
+          an implementation SHOULD ignore the ICMP message.
+
+   ICMP6) An implementation MUST validate that the Verification Tag
+          contained in the ICMP message matches the Verification Tag of
+          the peer.  If the Verification Tag is not 0 and does NOT
+          match, discard the ICMP message.  If it is 0 and the ICMP
+          message contains enough bytes to verify that the chunk type is
+          an INIT chunk and that the Initiate Tag matches the tag of the
+
+
+
+
+
+Stewart                     Standards Track                   [Page 142]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+          peer, continue with ICMP7.  If the ICMP message is too short
+          or the chunk type or the Initiate Tag does not match, silently
+          discard the packet.
+
+   ICMP7) If the ICMP message is either a v6 "Packet Too Big" or a v4
+          "Fragmentation Needed", an implementation MAY process this
+          information as defined for PATH MTU discovery.
+
+   ICMP8) If the ICMP code is an "Unrecognized Next Header Type
+          Encountered" or a "Protocol Unreachable", an implementation
+          MUST treat this message as an abort with the T bit set if it
+          does not contain an INIT chunk.  If it does contain an INIT
+          chunk and the association is in the COOKIE-WAIT state, handle
+          the ICMP message like an ABORT.
+
+   ICMP9) If the ICMPv6 code is "Destination Unreachable", the
+          implementation MAY mark the destination into the unreachable
+          state or alternatively increment the path error counter.
+
+   Note that these procedures differ from [RFC1122] and from its
+   requirements for processing of port-unreachable messages and the
+   requirements that an implementation MUST abort associations in
+   response to a "protocol unreachable" message.  Port-unreachable
+   messages are not processed, since an implementation will send an
+   ABORT, not a port unreachable.  The stricter handling of the
+   "protocol unreachable" message is due to security concerns for hosts
+   that do NOT support SCTP.
+
+   The following non-normative sample code is taken from an open-source
+   CRC generator [WILLIAMS93], using the "mirroring" technique and
+   yielding a lookup table for SCTP CRC32c with 256 entries, each 32
+   bits wide.  While neither especially slow nor especially fast, as
+   software table-lookup CRCs go, it has the advantage of working on
+   both big-endian and little-endian CPUs, using the same (host-order)
+   lookup tables, and using only the predefined ntohl() and htonl()
+   operations.  The code is somewhat modified from [WILLIAMS93], to
+   ensure portability between big-endian and little-endian
+   architectures.  (Note that if the byte endian-ness of the target
+   architecture is known to be little-endian, the final bit-reversal and
+   byte-reversal steps can be folded into a single operation.)
+
+   /*************************************************************/
+   /* Note Definition for Ross Williams table generator would   */
+   /* be: TB_WIDTH=4, TB_POLLY=0x1EDC6F41, TB_REVER=TRUE        */
+   /* For Mr. Williams direct calculation code use the settings */
+   /* cm_width=32, cm_poly=0x1EDC6F41, cm_init=0xFFFFFFFF,      */
+   /* cm_refin=TRUE, cm_refot=TRUE, cm_xorort=0x00000000        */
+   /*************************************************************/
+
+
+
+Stewart                     Standards Track                   [Page 143]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   /* Example of the crc table file */
+   #ifndef __crc32cr_table_h__
+   #define __crc32cr_table_h__
+
+   #define CRC32C_POLY 0x1EDC6F41
+   #define CRC32C(c,d) (c=(c>>8)^crc_c[(c^(d))&0xFF])
+
+   unsigned long  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,
+
+
+
+Stewart                     Standards Track                   [Page 144]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   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,
+   };
+
+   #endif
+
+    /* Example of table build routine */
+
+   #include <stdio.h>
+   #include <stdlib.h>
+
+   #define OUTPUT_FILE   "crc32cr.h"
+   #define CRC32C_POLY    0x1EDC6F41L
+   FILE *tf;
+   unsigned long
+   reflect_32 (unsigned long b)
+   {
+     int i;
+     unsigned long rw = 0L;
+
+     for (i = 0; i < 32; i++){
+         if (b & 1)
+           rw |= 1 << (31 - i);
+
+
+
+Stewart                     Standards Track                   [Page 145]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+         b >>= 1;
+     }
+     return (rw);
+   }
+
+   unsigned long
+   build_crc_table (int index)
+   {
+     int i;
+     unsigned long rb;
+
+     rb = reflect_32 (index);
+
+     for (i = 0; i < 8; i++){
+         if (rb & 0x80000000L)
+          rb = (rb << 1) ^ CRC32C_POLY;
+         else
+          rb <<= 1;
+     }
+     return (reflect_32 (rb));
+   }
+
+   main ()
+   {
+     int i;
+
+     printf ("\nGenerating CRC-32c table file <%s>\n",
+     OUTPUT_FILE);
+     if ((tf = fopen (OUTPUT_FILE, "w")) == NULL){
+         printf ("Unable to open %s\n", OUTPUT_FILE);
+         exit (1);
+     }
+     fprintf (tf, "#ifndef __crc32cr_table_h__\n");
+     fprintf (tf, "#define __crc32cr_table_h__\n\n");
+     fprintf (tf, "#define CRC32C_POLY 0x%08lX\n",
+     CRC32C_POLY);
+     fprintf (tf,
+     "#define CRC32C(c,d) (c=(c>>8)^crc_c[(c^(d))&0xFF])\n");
+     fprintf (tf, "\nunsigned long  crc_c[256] =\n{\n");
+     for (i = 0; i < 256; i++){
+         fprintf (tf, "0x%08lXL, ", build_crc_table (i));
+         if ((i & 3) == 3)
+           fprintf (tf, "\n");
+     }
+     fprintf (tf, "};\n\n#endif\n");
+
+     if (fclose (tf) != 0)
+       printf ("Unable to close <%s>." OUTPUT_FILE);
+
+
+
+Stewart                     Standards Track                   [Page 146]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+     else
+       printf ("\nThe CRC-32c table has been written to <%s>.\n",
+         OUTPUT_FILE);
+   }
+
+   /* Example of crc insertion */
+
+   #include "crc32cr.h"
+
+   unsigned long
+   generate_crc32c(unsigned char *buffer, unsigned int length)
+   {
+     unsigned int i;
+     unsigned long crc32 = ~0L;
+     unsigned long result;
+     unsigned char byte0,byte1,byte2,byte3;
+
+     for (i = 0; i < length; i++){
+         CRC32C(crc32, buffer[i]);
+     }
+
+     result = ~crc32;
+
+     /*  result now holds the negated polynomial remainder;
+      *  since the table and algorithm is "reflected" [williams95].
+      *  That is, result has the same value as if we mapped the message
+      *  to a polynomial, computed the host-bit-order polynomial
+      *  remainder, performed final negation, then did an end-for-end
+      *  bit-reversal.
+      *  Note that a 32-bit bit-reversal is identical to four inplace
+      *  8-bit reversals followed by an end-for-end byteswap.
+      *  In other words, the bytes of each bit are in the right order,
+      *  but the bytes have been byteswapped.  So we now do an explicit
+      *  byteswap.  On a little-endian machine, this byteswap and
+      *  the final ntohl cancel out and could be elided.
+      */
+
+     byte0 = result & 0xff;
+     byte1 = (result>>8) & 0xff;
+     byte2 = (result>>16) & 0xff;
+     byte3 = (result>>24) & 0xff;
+     crc32 = ((byte0 << 24) |
+              (byte1 << 16) |
+              (byte2 << 8)  |
+              byte3);
+     return ( crc32 );
+   }
+
+
+
+
+Stewart                     Standards Track                   [Page 147]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   int
+   insert_crc32(unsigned char *buffer, unsigned int length)
+   {
+     SCTP_message *message;
+     unsigned long crc32;
+     message = (SCTP_message *) buffer;
+     message->common_header.checksum = 0L;
+     crc32 = generate_crc32c(buffer,length);
+     /* and insert it into the message */
+     message->common_header.checksum = htonl(crc32);
+     return 1;
+   }
+
+   int
+   validate_crc32(unsigned char *buffer, unsigned int length)
+   {
+     SCTP_message *message;
+     unsigned int i;
+     unsigned long original_crc32;
+     unsigned long crc32 = ~0L;
+
+     /* save and zero checksum */
+     message = (SCTP_message *) buffer;
+     original_crc32 = ntohl(message->common_header.checksum);
+     message->common_header.checksum = 0L;
+     crc32 = generate_crc32c(buffer,length);
+     return ((original_crc32 == crc32)? 1 : -1);
+   }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart                     Standards Track                   [Page 148]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+References
+
+Normative References
+
+   [ITU32]      "ITU-T Recommendation V.42, "Error-correcting procedures
+                for DCEs using asynchronous-to-synchronous
+                conversion".", ITU-T section 8.1.1.6.2.
+
+   [RFC0768]    Postel, J., "User Datagram Protocol", STD 6, RFC 768,
+                August 1980.
+
+   [RFC0793]    Postel, J., "Transmission Control Protocol", STD 7, RFC
+                793, September 1981.
+
+   [RFC1122]    Braden, R., Ed., "Requirements for Internet Hosts -
+                Communication Layers", STD 3, RFC 1122, October 1989.
+
+   [RFC1123]    Braden, R., Ed., "Requirements for Internet Hosts -
+                Application and Support", STD 3, RFC 1123, October 1989.
+
+   [RFC1191]    Mogul, J. and S. Deering, "Path MTU discovery", RFC
+                1191, November 1990.
+
+   [RFC1981]    McCann, J., Deering, S., and J. Mogul, "Path MTU
+                Discovery for IP version 6", RFC 1981, August 1996.
+
+   [RFC1982]    Elz, R. and R. Bush, "Serial Number Arithmetic", RFC
+                1982, August 1996.
+
+   [RFC2119]    Bradner, S., "Key words for use in RFCs to Indicate
+                Requirement Levels", BCP 14, RFC 2119, March 1997.
+
+   [RFC2434]    Narten, T. and H. Alvestrand, "Guidelines for Writing an
+                IANA Considerations Section in RFCs", BCP 26, RFC 2434,
+                October 1998.
+
+   [RFC2460]    Deering, S. and R. Hinden, "Internet Protocol, Version 6
+                (IPv6) Specification", RFC 2460, December 1998.
+
+   [RFC2581]    Allman, M., Paxson, V., and W. Stevens, "TCP Congestion
+                Control", RFC 2581, April 1999.
+
+   [RFC3873]    Pastor, J. and M. Belinchon, "Stream Control
+                Transmission Protocol (SCTP) Management Information Base
+                (MIB)", RFC 3873, September 2004.
+
+   [RFC4291]    Hinden, R. and S. Deering, "IP Version 6 Addressing
+                Architecture", RFC 4291, February 2006.
+
+
+
+Stewart                     Standards Track                   [Page 149]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   [RFC4301]    Kent, S. and K. Seo, "Security Architecture for the
+                Internet Protocol", RFC 4301, December 2005.
+
+   [RFC4303]    Kent, S., "IP Encapsulating Security Payload (ESP)", RFC
+                4303, December 2005.
+
+   [RFC4306]    Kaufman, C., Ed., "Internet Key Exchange (IKEv2)
+                Protocol", RFC 4306, December 2005.
+
+   [RFC4821]    Mathis, M. and J. Heffner, "Packetization Layer Path MTU
+                Discovery", RFC 4821, March 2007.
+
+Informative References
+
+   [FALL96]     Fall, K. and S. Floyd, "Simulation-based Comparisons of
+                Tahoe, Reno, and SACK TCP", SIGCOMM'99 V. 26 N. 3 pp 5-
+                21, July 1996.
+
+   [SAVAGE99]   Savage, S., Cardwell, N., Wetherall, D., and T.
+                Anderson, "TCP Congestion Control with a Misbehaving
+                Receiver", ACM Computer Communications Review 29(5),
+                October 1999.
+
+   [ALLMAN99]   Allman, M. and V. Paxson, "On Estimating End-to-End
+                Network Path Properties", SIGCOMM'99 , 1999.
+
+   [WILLIAMS93] Williams, R., "A PAINLESS GUIDE TO CRC ERROR DETECTION
+                ALGORITHMS", Internet publication,
+                http://www.geocities.com/SiliconValley/Pines/
+                8659/crc.htm, August 1993.
+
+   [RFC0813]    Clark, D., "Window and Acknowledgement Strategy in TCP",
+                RFC 813, July 1982.
+
+   [RFC1858]    Ziemba, G., Reed, D., and P. Traina, "Security
+                Considerations for IP Fragment Filtering", RFC 1858,
+                October 1995.
+
+   [RFC2104]    Krawczyk, H., Bellare, M., and R. Canetti, "HMAC:
+                Keyed-Hashing for Message Authentication", RFC 2104,
+                February 1997.
+
+   [RFC2196]    Fraser, B., "Site Security Handbook", FYI 8, RFC 2196,
+                September 1997.
+
+   [RFC2522]    Karn, P. and W. Simpson, "Photuris: Session-Key
+                Management Protocol", RFC 2522, March 1999.
+
+
+
+
+Stewart                     Standards Track                   [Page 150]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+   [RFC2960]    Stewart, R., Xie, Q., Morneault, K., Sharp, C.,
+                Schwarzbauer, H., Taylor, T., Rytina, I., Kalla, M.,
+                Zhang, L., and V. Paxson, "Stream Control Transmission
+                Protocol", RFC 2960, October 2000.
+
+   [RFC3309]    Stone, J., Stewart, R., and D. Otis, "Stream Control
+                Transmission Protocol (SCTP) Checksum Change", RFC 3309,
+                September 2002.
+
+   [RFC3168]    Ramakrishnan, K., Floyd, S., and D. Black, "The Addition
+                of Explicit Congestion Notification (ECN) to IP", RFC
+                3168, September 2001.
+
+   [RFC4086]    Eastlake, D., 3rd, Schiller, J., and S. Crocker,
+                "Randomness Requirements for Security", BCP 106, RFC
+                4086, June 2005.
+
+   [RFC4460]    Stewart, R., Arias-Rodriguez, I., Poon, K., Caro, A.,
+                and M. Tuexen, "Stream Control Transmission Protocol
+                (SCTP) Specification Errata and Issues", RFC 4460, April
+                2006.
+
+   [RFC4895]    Tuexen, M., Stewart, R., Lei, P., and E. Rescorla,
+                "Authenticated Chunks for Stream Control Transmission
+                Protocol (SCTP)", RFC 4895, August 2007.
+
+Editor's Address
+
+   Randall R. Stewart
+   4875 Forest Drive
+   Suite 200
+   Columbia, SC  29206
+   US
+
+   EMail: rrs@cisco.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart                     Standards Track                   [Page 151]
+
+RFC 4960          Stream Control Transmission Protocol    September 2007
+
+
+Full Copyright Statement
+
+   Copyright (C) The IETF Trust (2007).
+
+   This document is subject to the rights, licenses and restrictions
+   contained in BCP 78, and except as set forth therein, the authors
+   retain all their rights.
+
+   This document and the information contained herein are provided on an
+   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
+   OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND
+   THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
+   THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
+   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Intellectual Property
+
+   The IETF takes no position regarding the validity or scope of any
+   Intellectual Property Rights or other rights that might be claimed to
+   pertain to the implementation or use of the technology described in
+   this document or the extent to which any license under such rights
+   might or might not be available; nor does it represent that it has
+   made any independent effort to identify any such rights.  Information
+   on the procedures with respect to rights in RFC documents can be
+   found in BCP 78 and BCP 79.
+
+   Copies of IPR disclosures made to the IETF Secretariat and any
+   assurances of licenses to be made available, or the result of an
+   attempt made to obtain a general license or permission for the use of
+   such proprietary rights by implementers or users of this
+   specification can be obtained from the IETF on-line IPR repository at
+   http://www.ietf.org/ipr.
+
+   The IETF invites any interested party to bring to its attention any
+   copyrights, patents or patent applications, or other proprietary
+   rights that may cover technology that may be required to implement
+   this standard.  Please address the information to the IETF at
+   ietf-ipr@ietf.org.
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart                     Standards Track                   [Page 152]
+
diff --git a/doc/rfc5061.txt b/doc/rfc5061.txt
new file mode 100644
index 0000000..3738e5a
--- /dev/null
+++ b/doc/rfc5061.txt
@@ -0,0 +1,2299 @@
+
+
+
+
+
+
+Network Working Group                                         R. Stewart
+Request for Comments: 5061                           Cisco Systems, Inc.
+Category: Standards Track                                         Q. Xie
+                                                          Motorola, Inc.
+                                                               M. Tuexen
+                                      Univ. of Applied Sciences Muenster
+                                                             S. Maruyama
+                                                               M. Kozuka
+                                                        Kyoto University
+                                                          September 2007
+
+
+              Stream Control Transmission Protocol (SCTP)
+                    Dynamic Address Reconfiguration
+
+Status of This Memo
+
+   This document specifies an Internet standards track protocol for the
+   Internet community, and requests discussion and suggestions for
+   improvements.  Please refer to the current edition of the "Internet
+   Official Protocol Standards" (STD 1) for the standardization state
+   and status of this protocol.  Distribution of this memo is unlimited.
+
+Abstract
+
+   A local host may have multiple points of attachment to the Internet,
+   giving it a degree of fault tolerance from hardware failures.  Stream
+   Control Transmission Protocol (SCTP) (RFC 4960) was developed to take
+   full advantage of such a multi-homed host to provide a fast failover
+   and association survivability in the face of such hardware failures.
+   This document describes an extension to SCTP that will allow an SCTP
+   stack to dynamically add an IP address to an SCTP association,
+   dynamically delete an IP address from an SCTP association, and to
+   request to set the primary address the peer will use when sending to
+   an endpoint.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.             Standards Track                     [Page 1]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+Table of Contents
+
+   1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  3
+   2.  Conventions  . . . . . . . . . . . . . . . . . . . . . . . . .  3
+   3.  Serial Number Arithmetic . . . . . . . . . . . . . . . . . . .  4
+   4.  Additional Chunks and Parameters . . . . . . . . . . . . . . .  4
+     4.1.  New Chunk Types  . . . . . . . . . . . . . . . . . . . . .  4
+       4.1.1.  Address Configuration Change Chunk (ASCONF)  . . . . .  5
+       4.1.2.  Address Configuration Acknowledgment Chunk
+               (ASCONF-ACK) . . . . . . . . . . . . . . . . . . . . .  6
+     4.2.  New Parameter Types  . . . . . . . . . . . . . . . . . . .  7
+       4.2.1.  Add IP Address . . . . . . . . . . . . . . . . . . . .  8
+       4.2.2.  Delete IP Address  . . . . . . . . . . . . . . . . . .  9
+       4.2.3.  Error Cause Indication . . . . . . . . . . . . . . . . 10
+       4.2.4.  Set Primary IP Address . . . . . . . . . . . . . . . . 11
+       4.2.5.  Success Indication . . . . . . . . . . . . . . . . . . 12
+       4.2.6.  Adaptation Layer Indication  . . . . . . . . . . . . . 13
+       4.2.7.  Supported Extensions Parameter . . . . . . . . . . . . 13
+     4.3.  New Error Causes . . . . . . . . . . . . . . . . . . . . . 14
+       4.3.1.  Error Cause: Request to Delete Last Remaining IP
+               Address  . . . . . . . . . . . . . . . . . . . . . . . 15
+       4.3.2.  Error Cause: Operation Refused Due to Resource
+               Shortage . . . . . . . . . . . . . . . . . . . . . . . 15
+       4.3.3.  Error Cause: Request to Delete Source IP Address . . . 16
+       4.3.4.  Error Cause: Association Aborted Due to Illegal
+               ASCONF-ACK . . . . . . . . . . . . . . . . . . . . . . 17
+       4.3.5.  Error Cause: Request Refused - No Authorization. . . . 17
+   5.  Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . 18
+     5.1.  ASCONF Chunk Procedures  . . . . . . . . . . . . . . . . . 18
+       5.1.1.  Congestion Control of ASCONF Chunks  . . . . . . . . . 20
+     5.2.  Upon Reception of an ASCONF Chunk  . . . . . . . . . . . . 21
+     5.3.  General Rules for Address Manipulation . . . . . . . . . . 24
+       5.3.1.  A Special Case for OOTB ABORT Chunks . . . . . . . . . 29
+       5.3.2.  A Special Case for Changing an Address . . . . . . . . 29
+     5.4.  Setting of the Primary Address . . . . . . . . . . . . . . 29
+     5.5.  Bundling of Multiple ASCONFs . . . . . . . . . . . . . . . 30
+   6.  Security Considerations  . . . . . . . . . . . . . . . . . . . 30
+   7.  IANA Considerations  . . . . . . . . . . . . . . . . . . . . . 33
+   8.  Acknowledgments  . . . . . . . . . . . . . . . . . . . . . . . 34
+   9.  References . . . . . . . . . . . . . . . . . . . . . . . . . . 35
+     9.1.  Normative References . . . . . . . . . . . . . . . . . . . 35
+     9.2.  Informative References . . . . . . . . . . . . . . . . . . 35
+   Appendix A.  Abstract Address Handling . . . . . . . . . . . . . . 36
+     A.1.  General Remarks  . . . . . . . . . . . . . . . . . . . . . 36
+     A.2.  Generalized Endpoints  . . . . . . . . . . . . . . . . . . 36
+     A.3.  Associations . . . . . . . . . . . . . . . . . . . . . . . 37
+     A.4.  Relationship with RFC 4960 . . . . . . . . . . . . . . . . 38
+     A.5.  Rules for Address Manipulation . . . . . . . . . . . . . . 38
+
+
+
+Stewart, et al.             Standards Track                     [Page 2]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+1.  Introduction
+
+   A local host may have multiple points of attachment to the Internet,
+   giving it a degree of fault tolerance from hardware failures.  SCTP
+   was developed to take full advantage of such a multi-homed host to
+   provide a fast failover and association survivability in the face of
+   such hardware failures.  However, many modern computers allow for the
+   dynamic addition and deletion of network cards (sometimes termed a
+   hot-pluggable interface).  Complicate this with the ability of a
+   provider, in IPv6, to dynamically renumber a network, and there still
+   is a gap between full-fault tolerance and the currently defined SCTP
+   protocol.  No matter if a card is added or an interface is
+   renumbered, in order to take advantage of this new configuration, the
+   transport association must be restarted.  For many fault-tolerant
+   applications this restart is considered an outage and is undesirable.
+
+   This document describes an extension to SCTP to attempt to correct
+   this problem for the more demanding fault-tolerant application.  This
+   extension will allow an SCTP stack to:
+
+   o  Dynamically add an IP address to an association.
+
+   o  Dynamically delete an IP address from an association.
+
+   o  Request to set the primary address the peer will use when sending
+      to an endpoint.
+
+   The dynamic addition and subtraction of IP addresses allows an SCTP
+   association to continue to function through host and network
+   reconfigurations.  These changes, brought on by provider or user
+   action, may mean that the peer would be better served by using the
+   newly added address; however, this information may only be known by
+   the endpoint that had the reconfiguration occur.  In such a case this
+   extension allows the local endpoint to advise the peer as to what it
+   thinks is the better primary address that the peer should be using.
+
+   One last thing this extension adds is a small, 32-bit integer called
+   an adaptation indication that can be exchanged at startup.  This is
+   useful for applications where there are one or more specific layers
+   below the application, yet still above SCTP.  In such a case, the
+   exchange of this indication can allow the proper layer to be enabled
+   below the application.
+
+2.  Conventions
+
+   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
+   document are to be interpreted as described in [RFC2119].
+
+
+
+Stewart, et al.             Standards Track                     [Page 3]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+3.  Serial Number Arithmetic
+
+   It is essential to remember that the actual Address Configuration
+   Change Chunk (ASCONF) Sequence Number space is finite, though very
+   large.  This space ranges from 0 to 2**32 - 1.  Since the space is
+   finite, all arithmetic dealing with ASCONF Sequence Numbers MUST be
+   performed modulo 2**32.  This unsigned arithmetic preserves the
+   relationship of sequence numbers as they cycle from 2**32 - 1 to 0
+   again.  There are some subtleties to computer modulo arithmetic, so
+   great care should be taken in programming the comparison of such
+   values.  When referring to ASCONF Sequence Numbers, the symbol "=<"
+   means "less than or equal"(modulo 2**32).
+
+   Comparisons and arithmetic on ASCONF sequence numbers in this
+   document SHOULD use Serial Number Arithmetic as defined in [RFC1982]
+   where SERIAL_BITS = 32.
+
+   ASCONF Sequence Numbers wrap around when they reach 2**32 - 1.  That
+   is, the next ASCONF Sequence Number an ASCONF chunk MUST use after
+   transmitting an ASCONF Sequence Number = 2**32 - 1 is 0.
+
+   Any arithmetic done on Stream Sequence Numbers SHOULD use Serial
+   Number Arithmetic (as defined in [RFC1982]) where SERIAL_BITS = 16.
+   All other arithmetic and comparisons in this document use normal
+   arithmetic.
+
+4.  Additional Chunks and Parameters
+
+   This section describes the addition of two new chunks and seven new
+   parameters to allow:
+
+   o  Dynamic addition of IP addresses to an association.
+
+   o  Dynamic deletion of IP addresses from an association.
+
+   o  A request to set the primary address the peer will use when
+      sending to an endpoint.
+
+   Additionally, this section describes three new Error Causes that
+   support these new chunks and parameters.
+
+4.1.  New Chunk Types
+
+   This section defines two new chunk types that will be used to
+   transfer the control information reliably.  Table 1 illustrates the
+   two new chunk types.
+
+
+
+
+
+Stewart, et al.             Standards Track                     [Page 4]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+        Chunk Type  Chunk Name
+        --------------------------------------------------------------
+        0xC1    Address Configuration Change Chunk        (ASCONF)
+        0x80    Address Configuration Acknowledgment      (ASCONF-ACK)
+
+              Table 1: Address Configuration Chunks
+
+4.1.1.  Address Configuration Change Chunk (ASCONF)
+
+   This chunk is used to communicate to the remote endpoint one of the
+   configuration change requests that MUST be acknowledged.  The
+   information carried in the ASCONF Chunk uses the form of a Type-
+   Length-Value (TLV), as described in "3.2.1 Optional/Variable-length
+   Parameter Format" in [RFC4960] for all variable parameters.  This
+   chunk MUST be sent in an authenticated way by using the mechanism
+   defined in [RFC4895].  If this chunk is received unauthenticated it
+   MUST be silently discarded as described in [RFC4895].
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       | Type = 0xC1   |  Chunk Flags  |      Chunk Length             |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                      Sequence Number                          |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                    Address Parameter                          |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                     ASCONF Parameter #1                       |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       \                                                               \
+       /                             ....                              /
+       \                                                               \
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                     ASCONF Parameter #N                       |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   Sequence Number: 32 bits (unsigned integer)
+
+   This value represents a Sequence Number for the ASCONF Chunk.  The
+   valid range of a Sequence Number is from 0 to 4294967295 (2**32 - 1).
+   Sequence Numbers wrap back to 0 after reaching 4294967295.
+
+   Address Parameter: 8 or 20 bytes (depending on the address type)
+
+   This field contains an address parameter, either IPv6 or IPv4, from
+   [RFC4960].  The address is an address of the sender of the ASCONF
+   Chunk; the address MUST be considered part of the association by the
+   peer endpoint (the receiver of the ASCONF Chunk).  This field may be
+
+
+
+Stewart, et al.             Standards Track                     [Page 5]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+   used by the receiver of the ASCONF to help in finding the
+   association.  If the address 0.0.0.0 or ::0 is provided, the receiver
+   MAY lookup the association by other information provided in the
+   packet.  This parameter MUST be present in every ASCONF message, i.e.
+   it is a mandatory TLV parameter.
+
+   Note: The host name address MUST NOT be sent and MUST be ignored if
+   received in any ASCONF message.
+
+   It should be noted that the ASCONF Chunk format requires the receiver
+   to report to the sender if it does not understand the ASCONF Chunk.
+   This is accomplished by setting the upper bits in the chunk type as
+   described in [RFC4960], Section 3.2.  Note that the upper two bits in
+   the ASCONF Chunk are set to one.  As defined in [RFC4960], Section
+   3.2, when setting these upper bits in this manner the receiver that
+   does not understand this chunk MUST skip the chunk and continue
+   processing, and report in an Operation Error Chunk using the
+   'Unrecognized Chunk Type' cause of error.  This will NOT abort the
+   association but indicates to the sender that it MUST not send any
+   further ASCONF chunks.
+
+   ASCONF Parameter: TLV format
+
+   Each address configuration change is represented by a TLV parameter,
+   as defined in Section 4.2.  One or more requests may be present in an
+   ASCONF Chunk.
+
+4.1.2.  Address Configuration Acknowledgment Chunk (ASCONF-ACK)
+
+   This chunk is used by the receiver of an ASCONF Chunk to acknowledge
+   the reception.  It carries zero or more results for any ASCONF
+   parameters that were processed by the receiver.  This chunk MUST be
+   sent in an authenticated way by using the mechanism defined in
+   [RFC4895].  If this chunk is received unauthenticated it MUST be
+   silently discarded as described in [RFC4895].
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.             Standards Track                     [Page 6]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       | Type = 0x80   |  Chunk Flags  |      Chunk Length             |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                     Sequence Number                           |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                 ASCONF Parameter Response#1                   |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       \                                                               \
+       /                             ....                              /
+       \                                                               \
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                 ASCONF Parameter Response#N                   |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   Sequence Number: 32 bits (unsigned integer)
+
+   This value represents the Sequence Number for the received ASCONF
+   Chunk that is acknowledged by this chunk.  This value is copied from
+   the received ASCONF Chunk.
+
+   ASCONF Parameter Response: TLV format
+
+   The ASCONF Parameter Response is used in the ASCONF-ACK to report the
+   status of ASCONF processing.  By default, if a responding endpoint
+   does not include any Error Cause, a success is indicated.  Thus a
+   sender of an ASCONF-ACK MAY indicate complete success of all TLVs in
+   an ASCONF by returning only the Chunk Type, Chunk Flags, Chunk Length
+   (set to 8), and the Sequence Number.
+
+4.2.  New Parameter Types
+
+   The seven new parameters added follow the format defined in Section
+   3.2.1 of [RFC4960].  Tables 2, 3, and 4 describe the parameters.
+
+        Address Configuration Parameters   Parameter Type
+        -------------------------------------------------
+        Set Primary Address                  0xC004
+        Adaptation Layer Indication          0xC006
+        Supported Extensions                 0x8008
+
+        Table 2: Parameters That Can Be Used in an INIT/INIT-ACK Chunk
+
+
+
+
+
+
+
+
+Stewart, et al.             Standards Track                     [Page 7]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+        Address Configuration Parameters   Parameter Type
+        -------------------------------------------------
+        Add IP Address                       0xC001
+        Delete IP Address                    0xC002
+        Set Primary Address                  0xC004
+
+        Table 3: Parameters Used in an ASCONF Parameter
+
+
+        Address Configuration Parameters   Parameter Type
+        -------------------------------------------------
+        Error Cause Indication               0xC003
+        Success Indication                   0xC005
+
+        Table 4: Parameters Used in an ASCONF Parameter Response
+
+   Any parameter that appears where it is not allowed (for example, a
+   0xC002 parameter appearing within an INIT or INIT-ACK) MAY be
+   responded to with an ABORT by the receiver of the invalid parameter.
+   If the receiver chooses NOT to abort, the parameter MUST be ignored.
+   A robust implementation SHOULD ignore the parameter and leave the
+   association intact.
+
+4.2.1.  Add IP Address
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |        Type = 0xC001          |    Length = Variable          |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |               ASCONF-Request Correlation ID                   |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                       Address Parameter                       |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   ASCONF-Request Correlation ID: 32 bits
+
+   This is an opaque integer assigned by the sender to identify each
+   request parameter.  The receiver of the ASCONF Chunk will copy this
+   2-bit value into the ASCONF Response Correlation ID field of the
+   ASCONF-ACK response parameter.  The sender of the ASCONF can use this
+   same value in the ASCONF-ACK to find which request the response is
+   for.  Note that the receiver MUST NOT change this 32-bit value.
+
+
+
+
+
+
+
+
+Stewart, et al.             Standards Track                     [Page 8]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+   Address Parameter: TLV
+
+   This field contains an IPv4 or IPv6 address parameter as described in
+   Section 3.3.2.1 of [RFC4960].  The complete TLV is wrapped within
+   this parameter.  It informs the receiver that the address specified
+   is to be added to the existing association.  This parameter MUST NOT
+   contain a broadcast or multicast address.  If the address 0.0.0.0 or
+   ::0 is provided, the source address of the packet MUST be added.
+
+   An example TLV requesting that the IPv4 address 192.0.2.1 be added to
+   the association would look as follows:
+
+           +--------------------------------+
+           |  Type=0xC001   | Length = 16   |
+           +--------------------------------+
+           |       C-ID = 0x01023474        |
+           +--------------------------------+
+           |  Type=5        | Length = 8    |
+           +----------------+---------------+
+           |       Value=0xC0000201         |
+           +----------------+---------------+
+
+   Valid Chunk Appearance
+
+   The Add IP Address parameter may only appear in the ASCONF Chunk
+   type.
+
+4.2.2.  Delete IP Address
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |        Type =0xC002           |    Length = Variable          |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |               ASCONF-Request Correlation ID                   |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                       Address Parameter                       |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   ASCONF-Request Correlation ID: 32 bits
+
+   This is an opaque integer assigned by the sender to identify each
+   request parameter.  The receiver of the ASCONF Chunk will copy this
+   32-bit value into the ASCONF Response Correlation ID field of the
+   ASCONF-ACK response parameter.  The sender of the ASCONF can use this
+   same value in the ASCONF-ACK to find which request the response is
+   for.  Note that the receiver MUST NOT change this 32-bit value.
+
+
+
+
+Stewart, et al.             Standards Track                     [Page 9]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+   Address Parameter: TLV
+
+   This field contains an IPv4 or IPv6 address parameter, as described
+   in Section 3.3.2.1 of [RFC4960].  The complete TLV is wrapped within
+   this parameter.  It informs the receiver that the address specified
+   is to be removed from the existing association.  This parameter MUST
+   NOT contain a broadcast or multicast address.  If the address 0.0.0.0
+   or ::0 is provided, all addresses of the peer except the source
+   address of the packet MUST be deleted.
+
+   An example TLV deleting the IPv4 address 192.0.2.1 from an existing
+   association would look as follows:
+
+           +--------------------------------+
+           |  Type=0xC002   | Length = 16   |
+           +--------------------------------+
+           |       C-ID = 0x01023476        |
+           +--------------------------------+
+           |  Type=5        | Length = 8    |
+           +----------------+---------------+
+           |       Value=0xC0000201         |
+           +----------------+---------------+
+
+   Valid Chunk Appearance
+
+   The Delete IP Address parameter may only appear in the ASCONF Chunk
+   type.
+
+4.2.3.  Error Cause Indication
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |    Type = 0xC003              |      Length = Variable        |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |             ASCONF-Response Correlation ID                    |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |             Error Cause(s) or Success Indication              |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   ASCONF-Response Correlation ID: 32 bits
+
+   This is an opaque integer assigned by the sender to identify each
+   request parameter.  The receiver of the ASCONF Chunk will copy this
+   32-bit value from the ASCONF-Request Correlation ID into the ASCONF
+   Response Correlation ID field so the peer can easily correlate the
+   request to this response.  Note that the receiver MUST NOT change
+   this 32-bit value.
+
+
+
+Stewart, et al.             Standards Track                    [Page 10]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+   Error Cause(s): TLV(s)
+
+   When reporting an error, this response parameter is used to wrap one
+   or more standard Error Causes normally found within an SCTP
+   Operational Error or SCTP Abort (as defined in [RFC4960]).  The Error
+   Cause(s) follow the format defined in Section 3.3.10 of [RFC4960].
+
+   Valid Chunk Appearance
+
+   The Error Cause Indication parameter may only appear in the ASCONF-
+   ACK Chunk Type.
+
+4.2.4.  Set Primary IP Address
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |        Type =0xC004           |    Length = Variable          |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |               ASCONF-Request Correlation ID                   |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                       Address Parameter                       |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   ASCONF-Request Correlation ID: 32 bits
+
+   This is an opaque integer assigned by the sender to identify each
+   request parameter.  The receiver of the ASCONF Chunk will copy this
+   32-bit value into the ASCONF Response Correlation ID field of the
+   ASCONF-ACK response parameter.  The sender of the ASCONF can use this
+   same value in the ASCONF-ACK to find which request the response is
+   for.  Note that the receiver MUST NOT change this 32-bit value.
+
+   Address Parameter: TLV
+
+   This field contains an IPv4 or IPv6 address parameter as described in
+   Section 3.3.2.1 of [RFC4960].  The complete TLV is wrapped within
+   this parameter.  It requests the receiver to mark the specified
+   address as the primary address to send data to (see Section 5.1.2 of
+   [RFC4960]).  The receiver MAY mark this as its primary address upon
+   receiving this request.  If the address 0.0.0.0 or ::0 is provided,
+   the receiver MAY mark the source address of the packet as its
+   primary.
+
+   An example TLV requesting that the IPv4 address 192.0.2.1 be made the
+   primary destination address would look as follows:
+
+
+
+
+
+Stewart, et al.             Standards Track                    [Page 11]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+           +--------------------------------+
+           |  Type=0xC004   | Length = 16   |
+           +--------------------------------+
+           |       C-ID = 0x01023479        |
+           +--------------------------------+
+           |  Type=5        | Length = 8    |
+           +----------------+---------------+
+           |       Value=0xC0000201         |
+           +----------------+---------------+
+
+   Valid Chunk Appearance
+
+   The Set Primary IP Address parameter may appear in the ASCONF, the
+   INIT, or the INIT-ACK Chunk Type.  The inclusion of this parameter in
+   the INIT or INIT-ACK can be used to indicate an initial preference of
+   primary address.
+
+4.2.5.  Success Indication
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |        Type = 0xC005          |      Length = 8               |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |               ASCONF-Response Correlation ID                  |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   By default, if a responding endpoint does not report an error for any
+   requested TLV, a success is implicitly indicated.  Thus, a sender of
+   an ASCONF-ACK MAY indicate complete success of all TLVs in an ASCONF
+   by returning only the Chunk Type, Chunk Flags, Chunk Length (set to
+   8), and the Sequence Number.
+
+   The responding endpoint MAY also choose to explicitly report a
+   success for a requested TLV, by returning a success report ASCONF
+   Parameter Response.
+
+   ASCONF-Response Correlation ID: 32 bits
+
+   This is an opaque integer assigned by the sender to identify each
+   request parameter.  The receiver of the ASCONF Chunk will copy this
+   32-bit value from the ASCONF-Request Correlation ID into the ASCONF
+   Response Correlation ID field so the peer can easily correlate the
+   request to this response.
+
+
+
+
+
+
+
+Stewart, et al.             Standards Track                    [Page 12]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+   Valid Chunk Appearance
+
+   The Success Indication parameter may only appear in the ASCONF-ACK
+   Chunk Type.
+
+4.2.6.  Adaptation Layer Indication
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |        Type =0xC006           |    Length = 8                 |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                   Adaptation Code point                       |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   This parameter is specified for the communication of peer upper-layer
+   protocols.  It is envisioned to be used for flow control and other
+   adaptation layers that require an indication to be carried in the
+   INIT and INIT-ACK.  Each adaptation layer that is defined that wishes
+   to use this parameter MUST specify an adaptation code point in an
+   appropriate RFC defining its use and meaning.  This parameter SHOULD
+   NOT be examined by the receiving SCTP implementation and should be
+   passed opaquely to the upper-layer protocol.
+
+   Note: This parameter is not used in either the addition or deletion
+   of addresses but is for the convenience of the upper layer.  This
+   document includes this parameter to minimize the number of SCTP
+   documents.
+
+   Valid Chunk Appearance
+
+   The Adaptation Layer Indication parameter may appear in INIT or INIT-
+   ACK chunk and SHOULD be passed to the receiver's upper-layer protocol
+   based upon the upper-layer protocol configuration of the SCTP stack.
+   This parameter MUST NOT be sent in any other chunks, and if it is
+   received in another chunk, it MUST be ignored.
+
+4.2.7.  Supported Extensions Parameter
+
+   This parameter is used at startup to identify any additional
+   extensions that the sender supports.  The sender MUST support both
+   the sending and the receiving of any chunk types listed within the
+   Supported Extensions Parameter.  An implementation supporting this
+   extension MUST list the ASCONF,the ASCONF-ACK, and the AUTH chunks in
+   its INIT and INIT-ACK parameters.
+
+
+
+
+
+
+Stewart, et al.             Standards Track                    [Page 13]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+      0                   1                   2                   3
+      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |     Parameter Type = 0x8008   |      Parameter Length         |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     | CHUNK TYPE 1  |  CHUNK TYPE 2 |  CHUNK TYPE 3 |  CHUNK TYPE 4 |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |                             ....                              |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     | CHUNK TYPE N  |      PAD      |      PAD      |      PAD      |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   Parameter Type This field holds the IANA-defined parameter type for
+   the Supported Extensions Parameter.  The value of this field is
+   0x8008.
+
+   Parameter Type Length This field holds the length of the parameter,
+   including the Parameter Type, Parameter Length, and any additional
+   supported extensions.  Note: The length MUST NOT include any padding.
+
+   CHUNK TYPE X This field(s) hold the chunk type of any SCTP
+   extension(s) that are currently supported by the sending SCTP.
+   Multiple chunk types may be defined listing each additional feature
+   that the sender supports.  The sender MUST NOT include multiple
+   Supported Extensions Parameter within any chunk.
+
+   Parameter Appearance This parameter may appear in the INIT or INIT-
+   ACK chunk.  This parameter MUST NOT appear in any other chunk.
+
+4.3.  New Error Causes
+
+   Five new Error Causes are added to the SCTP Operational Errors,
+   primarily for use in the ASCONF-ACK Chunk.
+
+       Cause Code
+       Value          Cause Code
+       ---------      ----------------
+       0x00A0          Request to Delete Last Remaining IP Address
+       0x00A1          Operation Refused Due to Resource Shortage
+       0x00A2          Request to Delete Source IP Address
+       0x00A3          Association Aborted Due to Illegal ASCONF-ACK
+       0x00A4          Request Refused - No Authorization
+
+             Table 5: New Error Causes
+
+
+
+
+
+
+
+Stewart, et al.             Standards Track                    [Page 14]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+4.3.1.  Error Cause: Request to Delete Last Remaining IP Address
+
+   Cause of error
+
+   Request to Delete Last Remaining IP Address: The receiver of this
+   error sent a request to delete the last IP address from its
+   association with its peer.  This error indicates that the request is
+   rejected.
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |     Cause Code=0x00A0         |      Cause Length=Variable    |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       \                     TLV-Copied-From-ASCONF                    /
+       /                                                               \
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   An example of a failed delete in an Error Cause TLV would look as
+   follows in the response ASCONF-ACK message:
+
+           +--------------------------------+
+           | Type = 0xC003  | Length = 28   |
+           +----------------+---------------+
+           |       C-ID = 0x01023476        |
+           +--------------------------------+
+           |  Cause=0x00A0  | Length = 20   |
+           +----------------+---------------+
+           |  Type= 0xC002  | Length = 16   |
+           +----------------+---------------+
+           |       C-ID = 0x01023476        |
+           +--------------------------------+
+           |   Type=0x0005  | Length = 8    |
+           +----------------+---------------+
+           |       Value=0xC0000201         |
+           +----------------+---------------+
+
+4.3.2.  Error Cause: Operation Refused Due to Resource Shortage
+
+   Cause of error
+
+   This Error Cause is used to report a failure by the receiver to
+   perform the requested operation due to a lack of resources.  The
+   entire TLV that is refused is copied from the ASCONF into the Error
+   Cause.
+
+
+
+
+
+
+Stewart, et al.             Standards Track                    [Page 15]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |     Cause Code=0x00A1         |      Cause Length=Variable    |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       \                  TLV-Copied-From-ASCONF                      /
+       /                                                              \
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   An example of a failed addition in an Error Cause TLV would look as
+   follows in the response ASCONF-ACK message:
+
+           +--------------------------------+
+           | Type = 0xC003  | Length = 28   |
+           +--------------------------------+
+           |       C-ID = 0x01023474        |
+           +--------------------------------+
+           |  Cause=0x00A1  | Length = 20   |
+           +----------------+---------------+
+           |  Type=0xC001   | Length = 16   |
+           +--------------------------------+
+           |       C-ID = 0x01023474        |
+           +--------------------------------+
+           |  Type=0x0005   | Length = 8    |
+           +----------------+---------------+
+           |       Value=0xC0000201         |
+           +----------------+---------------+
+
+4.3.3.  Error Cause: Request to Delete Source IP Address
+
+   Cause of error
+
+   Request to Delete Source IP Address: The receiver of this error sent
+   a request to delete the source IP address of the ASCONF message.
+   This error indicates that the request is rejected.
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |     Cause Code=0x00A2         |      Cause Length=Variable    |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       \                    TLV-Copied-From-ASCONF                     /
+       /                                                               \
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+
+
+
+
+
+Stewart, et al.             Standards Track                    [Page 16]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+   An example of a failed delete in an Error Cause TLV would look as
+   follows in the response ASCONF-ACK message:
+
+           +--------------------------------+
+           | Type = 0xC003  | Length = 28   |
+           +--------------------------------+
+           |       C-ID = 0x01023476        |
+           +--------------------------------+
+           |  Cause=0x00A2  | Length = 20   |
+           +----------------+---------------+
+           |  Type=0xC002   | Length = 16   |
+           +----------------+---------------+
+           |       C-ID = 0x01023476        |
+           +--------------------------------+
+           |   Type=0x0005  | Length = 8    |
+           +----------------+---------------+
+           |       Value=0xC0000201         |
+           +----------------+---------------+
+
+   IMPLEMENTATION NOTE: It is unlikely that an endpoint would source a
+   packet from the address being deleted, unless the endpoint does not
+   do proper source address selection.
+
+4.3.4.  Error Cause: Association Aborted Due to Illegal ASCONF-ACK
+
+   This error is to be included in an ABORT that is generated due to the
+   reception of an ASCONF-ACK that was not expected but is larger than
+   the current Sequence Number (see Section 5.3, Rule F0 ).  Note that a
+   Sequence Number is larger than the last acked Sequence Number if it
+   is either the next sequence or no more than 2**31-1 greater than the
+   current Sequence Number.  Sequence Numbers smaller than the last
+   acked Sequence Number are silently ignored.
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |     Cause Code=0x00A3         |      Cause Length=4           |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+4.3.5.  Error Cause: Request Refused - No Authorization.
+
+   Cause of error
+
+   This Error Cause may be included to reject a request based on local
+   security policies.
+
+
+
+
+
+
+Stewart, et al.             Standards Track                    [Page 17]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+        0                   1                   2                   3
+        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |     Cause Code=0x00A4         |      Cause Length=Variable    |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       \                     TLV-Copied-From-ASCONF                    /
+       /                                                               \
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+5.  Procedures
+
+   This section will lay out the specific procedures for address-
+   configuration change chunk type and its processing.
+
+5.1.  ASCONF Chunk Procedures
+
+   When an endpoint has an ASCONF signaled change to be sent to the
+   remote endpoint, it MUST do the following:
+
+   A1)  Create an ASCONF Chunk as defined in Section 4.1.1.  The chunk
+        MUST contain all of the TLV(s) of information necessary to be
+        sent to the remote endpoint, and unique correlation identities
+        for each request.
+
+   A2)  A Sequence Number MUST be assigned to the Chunk.  The Sequence
+        Number MUST be larger by one.  The Sequence Number MUST be
+        initialized at the start of the association to the same value as
+        the Initial Transmission Sequence Number (TSN) and every time a
+        new ASCONF Chunk is created, it MUST be incremented by one after
+        assigning the Sequence Number to the newly created chunk.
+
+   A3)  If no SCTP packet with one or more ASCONF Chunk(s) is
+        outstanding (unacknowledged) with the remote peer, send the
+        chunk and proceed to step A4.  If an ASCONF chunk is
+        outstanding, then the ASCONF chunk should be queued for later
+        transmission and no further action should be taken until the
+        previous ASCONF is acknowledged or a timeout occurs.
+
+   A4)  The sender MUST Start a T-4 Retransmission Timeout (RTO) timer,
+        using the RTO value of the selected destination address
+        (normally the primary path; see [RFC4960], Section 6.4 for
+        details).
+
+
+
+
+
+
+
+
+
+Stewart, et al.             Standards Track                    [Page 18]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+   A5)  When the ASCONF-ACK that acknowledges the Sequence Number last
+        sent arrives, the sender MUST stop the T-4 RTO timer, and clear
+        the appropriate association and destination error counters as
+        defined in [RFC4960], Sections 8.1 and 8.2.
+
+   A6)  The endpoint MUST process all of the TLVs within the ASCONF-
+        ACK(s) to find out particular status information returned to the
+        various requests that were sent.  Use the Correlation IDs to
+        correlate the request and the responses.
+
+   A7)  If an error response is received for a TLV parameter, all TLVs
+        with no response before the failed TLV are considered successful
+        if not reported.  All TLVs after the failed response are
+        considered unsuccessful unless a specific success indication is
+        present for the parameter.
+
+   A8)  If there is no response(s) to specific TLV parameter(s), and no
+        failures are indicated, then all request(s) are considered
+        successful.
+
+   A9)  If the peer responds to an ASCONF with an ERROR Chunk reporting
+        that it did not recognize the ASCONF Chunk Type, the sender of
+        the ASCONF MUST NOT send any further ASCONF Chunks and MUST stop
+        its T-4 timer.
+
+   If the T-4 RTO timer expires the endpoint MUST do the following:
+
+   B1)  Increment the error counters and perform path failure detection
+        on the appropriate destination address as defined in [RFC4960],
+        Sections 8.1 and 8.2.
+
+   B2)  Increment the association error counters and perform endpoint
+        failure detection on the association as defined in [RFC4960],
+        Sections 8.1 and 8.2.
+
+   B3)  Backoff the destination address RTO value to which the ASCONF
+        chunk was sent by doubling the RTO timer value.
+
+        Note: The RTO value is used in the setting of all timer types
+        for SCTP.  Each destination address has a single RTO estimate.
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.             Standards Track                    [Page 19]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+   B4)  Re-transmit the ASCONF Chunk last sent and if possible choose an
+        alternate destination address (please refer to [RFC4960],
+        Section 6.4.1).  An endpoint MUST NOT add new parameters to this
+        chunk; it MUST be the same (including its Sequence Number) as
+        the last ASCONF sent.  An endpoint MAY, however, bundle an
+        additional ASCONF with new ASCONF parameters with the next
+        Sequence Number.  For details, see Section 5.5.
+
+   B5)  Restart the T-4 RTO timer.  Note that if a different destination
+        is selected, then the RTO used will be that of the new
+        destination address.
+
+   Note: The total number of retransmissions is limited by B2 above.  If
+   the maximum is reached, the association will fail and enter into the
+   CLOSED state (see [RFC4960], Section 6.4.1 for details).
+
+5.1.1.  Congestion Control of ASCONF Chunks
+
+   In defining the ASCONF Chunk transfer procedures, it is essential
+   that these transfers MUST NOT cause congestion within the network.
+   To achieve this, we place these restrictions on the transfer of
+   ASCONF Chunks:
+
+   C1)  One and only one SCTP packet-holding ASCONF Chunk(s) MAY be in
+        transit and unacknowledged at any one time.  If a sender, after
+        sending an ASCONF chunk, decides it needs to transfer another
+        ASCONF Chunk, it MUST wait until the ASCONF-ACK Chunk returns
+        from the previous ASCONF Chunk before sending a subsequent
+        ASCONF.  Note: This restriction binds each side, so at any time,
+        two ASCONF may be in-transit on any given association (one sent
+        from each endpoint).  However, when an ASCONF Chunk is
+        retransmitted due to a time-out, the additionally held ASCONF
+        Chunks can be bundled into the retransmission packet as
+        described in Section 5.5.
+
+   C2)  An ASCONF Chunk may be bundled with any other chunk type
+        including other ASCONF Chunks.  If bundled with other ASCONF
+        Chunks, the chunks MUST appear in sequential order with respect
+        to their Sequence Number.
+
+   C3)  An ASCONF-ACK Chunk may be bundled with any other chunk type
+        including other ASCONF-ACK Chunks.  If bundled with other
+        ASCONF-ACK Chunks, the chunks MUST appear in sequential order
+        with respect to their Sequence Number.
+
+
+
+
+
+
+
+Stewart, et al.             Standards Track                    [Page 20]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+   C4)  Both ASCONF and ASCONF-ACK Chunks MUST NOT be sent in any SCTP
+        state except ESTABLISHED, SHUTDOWN-PENDING, SHUTDOWN-RECEIVED,
+        and SHUTDOWN-SENT.
+
+   C5)  An ASCONF Chunk and an ASCONF-ACK Chunk SHOULD not be larger
+        than the PMTU.  If the PMTU is unknown, then the PMTU should be
+        set to the minimum PMTU.  The minimum PMTU depends on the IP
+        version used for transmission, and is the lesser of 576 octets
+        and the first-hop MTU for IPv4 [RFC1122] and 1280 octets for
+        IPv6 [RFC2460].
+
+   An ASCONF sender without these restrictions could possibly flood the
+   network with a large number of separate address-change operations,
+   thus causing network congestion.
+
+   If the sender of an ASCONF Chunk receives an Operational Error
+   indicating that the ASCONF Chunk Type is not understood, then the
+   sender MUST NOT send subsequent ASCONF Chunks to the peer.  The
+   endpoint should also inform the upper-layer application that the peer
+   endpoint does not support any of the extensions detailed in this
+   document.
+
+5.2.  Upon Reception of an ASCONF Chunk
+
+   When an endpoint receives an ASCONF Chunk from the remote peer,
+   special procedures may be needed to identify the association the
+   ASCONF Chunk is associated with.  To properly find the association,
+   the following procedures SHOULD be followed:
+
+   D1)  Use the source address and port number of the sender to attempt
+        to identify the association (i.e., use the same method defined
+        in [RFC4960] used for all other SCTP Chunks).  If found proceed
+        to rule D4.
+
+   D2)  If the association is not found, use the address found in the
+        Address Parameter TLV combined with the port number found in the
+        SCTP common header.  If found, proceed to rule D4.
+
+   D2-ext)  If more than one ASCONF Chunks are packed together, use the
+            address found in the ASCONF Address Parameter TLV of each of
+            the subsequent ASCONF Chunks.  If found, proceed to rule D4.
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.             Standards Track                    [Page 21]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+   D3)  If neither D1, D2, nor D2-ext locates the association, treat the
+        chunk as an Out Of The Blue packet as defined in [RFC4960].
+
+   D4)  Follow the normal rules to validate the SCTP verification tag
+        found in [RFC4960].
+
+   D5)  After the verification tag has been validated, normal chunk
+        processing should occur.  Prior to finding the ASCONF chunk, the
+        receiver MUST encounter an AUTH chunk as described in [RFC4895].
+        If either authentication fails, or the AUTH chunk is missing,
+        the receiver MUST silently discard this chunk and the rest of
+        the packet.
+
+   After identification and verification of the association, the
+   following should be performed to properly process the ASCONF Chunk:
+
+   E1)  If the value found in the Sequence Number of the ASCONF Chunk is
+        equal to the ('Peer-Sequence-Number' + 1) and the Sequence
+        Number of the ASCONF Chunk is the first in the SCTP Packet, the
+        endpoint MAY clean any old cached ASCONF-ACK up to the 'Peer-
+        Sequence-Number' and then proceed to rule E4.
+
+   E1-ext)  If the value found in the Sequence Number of the ASCONF
+            Chunk is equal to the ('Peer-Sequence-Number' + 1) and the
+            ASCONF chunk is NOT the first Sequence Number in the SCTP
+            packet, proceed to rule E4 but do NOT clear any cached
+            ASCONF- ACK or state information.
+
+   E2)  If the value found in the Sequence Number is less than the
+        ('Peer- Sequence-Number' + 1), simply skip to the next ASCONF,
+        and include in the outbound response packet any previously
+        cached ASCONF-ACK response that was sent and saved that matches
+        the Sequence Number of the ASCONF.  Note: It is possible that no
+        cached ASCONF-ACK Chunk exists.  This will occur when an older
+        ASCONF arrives out of order.  In such a case, the receiver
+        should skip the ASCONF Chunk and not include ASCONF-ACK Chunk
+        for that chunk.
+
+   E3)  Then, process each ASCONF one by one as above while the Sequence
+        Number of the ASCONF is less than the ('Peer-Sequence-Number' +
+        1).
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.             Standards Track                    [Page 22]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+   E4)  When the Sequence Number matches the next one expected, process
+        the ASCONF as described below and after processing the ASCONF
+        Chunk, append an ASCONF-ACK Chunk to the response packet and
+        cache a copy of it (in the event it later needs to be
+        retransmitted).
+
+        V1)  Process the TLVs contained within the Chunk performing the
+             appropriate actions as indicated by each TLV type.  The
+             TLVs MUST be processed in order within the Chunk.  For
+             example, if the sender puts 3 TLVs in one chunk, the first
+             TLV (the one closest to the Chunk Header) in the Chunk MUST
+             be processed first.  The next TLV in the chunk (the middle
+             one) MUST be processed second and finally, the last TLV in
+             the Chunk MUST be processed last.
+
+        V2)  In processing the chunk, the receiver should build a
+             response message with the appropriate error TLVs, as
+             specified in the Parameter type bits, for any ASCONF
+             Parameter it does not understand.  To indicate an
+             unrecognized parameter, Cause Type 8 should be used as
+             defined in the ERROR in Section 3.3.10.8, [RFC4960].  The
+             endpoint may also use the response to carry rejections for
+             other reasons, such as resource shortages, etc., using the
+             Error Cause TLV and an appropriate error condition.
+
+        Note: A positive response is implied if no error is indicated by
+             the sender.
+
+        V3)  All responses MUST copy the ASCONF-Request Correlation ID
+             field received in the ASCONF parameter from the TLV being
+             responded to, into the ASCONF-Request Correlation ID field
+             in the response parameter.
+
+        V4)  After processing the entire Chunk, the receiver of the
+             ASCONF MUST queue the response ASCONF-ACK Chunk for
+             transmission after the rest of the SCTP packet has been
+             processed.  This allows the ASCONF-ACK Chunk to be bundled
+             with other ASCONF-ACK Chunks as well as any additional
+             responses, e.g., a Selective Acknowledgment (SACK) Chunk.
+
+        V5)  Update the 'Peer-Sequence-Number' to the value found in the
+             Sequence Number field.
+
+
+
+
+
+
+
+
+
+Stewart, et al.             Standards Track                    [Page 23]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+   E5)  Otherwise, the ASCONF Chunk is discarded since it must be either
+        a stale packet or from an attacker.  A receiver of such a packet
+        MAY log the event for security purposes.
+
+   E6)  When all ASCONF Chunks are processed for this SCTP packet, send
+        back the accumulated single response packet with all of the
+        ASCONF-ACK Chunks.  The destination address of the SCTP packet
+        containing the ASCONF-ACK Chunks MUST be the source address of
+        the SCTP packet that held the ASCONF Chunks.
+
+   E7)  While processing the ASCONF Chunks in the SCTP packet, if the
+        response packet will exceed the PMTU of the return path, the
+        receiver MUST stop adding additional ASCONF-ACKs into the
+        response packet but MUST continue to process all of the ASCONF
+        Chunks, saving ASCONF-ACK Chunk responses in its cached copy.
+        The sender of the ASCONF Chunk will later retransmit the ASCONF
+        Chunks that were not responded to, at which time the cached
+        copies of the responses that would NOT fit in the PMTU can be
+        sent to the peer.
+
+   Note: These rules have been presented with the assumption that the
+   implementation is caching old ASCONF-ACKs in case of loss of SCTP
+   packets in the ACK path.  It is allowable for an implementation to
+   maintain this state in another form it deems appropriate, as long as
+   that form results in the same ASCONF-ACK sequences being returned to
+   the peer as outlined above.
+
+5.3.  General Rules for Address Manipulation
+
+   When building TLV parameters for the ASCONF Chunk that will add or
+   delete IP addresses, the following rules MUST be applied:
+
+   F0)  If an endpoint receives an ASCONF-ACK that is greater than or
+        equal to the next Sequence Number to be used but no ASCONF Chunk
+        is outstanding, the endpoint MUST ABORT the association.  Note
+        that a Sequence Number is greater than if it is no more than
+        2^^31-1 larger than the current Sequence Number (using serial
+        arithmetic).
+
+   F1)  When adding an IP address to an association, the IP address is
+        NOT considered fully added to the association until the ASCONF-
+        ACK arrives.  This means that until such time as the ASCONF
+        containing the add is acknowledged, the sender MUST NOT use the
+        new IP address as a source for ANY SCTP packet except on
+        carrying an ASCONF Chunk.  The receiver of the Add IP Address
+
+
+
+
+
+
+Stewart, et al.             Standards Track                    [Page 24]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+        request may use the address as a destination immediately.  The
+        receiver MUST use the path-verification procedure for the added
+        address before using that address.  The receiver MUST NOT send
+        packets to the new address except for the corresponding ASCONF-
+        ACK Chunk or HEARTBEAT Chunks for path verification before the
+        new path is verified.  If the ASCONF-ACK is sent to the new
+        address, it MAY be bundled with the HEARTBEAT chunk for path
+        verification.
+
+   F2)  After the ASCONF-ACK of an IP address Add arrives, the endpoint
+        MAY begin using the added IP address as a source address for any
+        type of SCTP chunk.
+
+   F3a) If an endpoint receives an Error Cause TLV indicating that the
+        IP address Add or IP address Deletion parameters was not
+        understood, the endpoint MUST consider the operation failed and
+        MUST NOT attempt to send any subsequent Add or Delete requests
+        to the peer.
+
+   F3b) If an endpoint receives an Error Cause TLV indicating that the
+        IP address Set Primary IP Address parameter was not understood,
+        the endpoint MUST consider the operation failed and MUST NOT
+        attempt to send any subsequent Set Primary IP Address requests
+        to the peer.
+
+   F4)  When deleting an IP address from an association, the IP address
+        MUST be considered a valid destination address for the reception
+        of SCTP packets until the ASCONF-ACK arrives and MUST NOT be
+        used as a source address for any subsequent packets.  This means
+        that any datagrams that arrive before the ASCONF-ACK destined to
+        the IP address being deleted MUST be considered part of the
+        current association.  One special consideration is that ABORT
+        Chunks arriving destined to the IP address being deleted MUST be
+        ignored (see Section 5.3.1 for further details).
+
+   F5)  An endpoint MUST NOT delete its last remaining IP address from
+        an association.  In other words, if an endpoint is NOT multi-
+        homed, it MUST NOT use the delete IP address without an Add IP
+        Address preceding the delete parameter in the ASCONF Chunk.  Or,
+        if an endpoint sends multiple requests to delete IP addresses,
+        it MUST NOT delete all of the IP addresses that the peer has
+        listed for the requester.
+
+
+
+
+
+
+
+
+
+Stewart, et al.             Standards Track                    [Page 25]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+   F6)  An endpoint MUST NOT set an IP header source address for an SCTP
+        packet holding the ASCONF Chunk to be the same as an address
+        being deleted by the ASCONF Chunk.
+
+   F7)  If a request is received to delete the last remaining IP address
+        of a peer endpoint, the receiver MUST send an Error Cause TLV
+        with the Error Cause set to the new error code 'Request to
+        Delete Last Remaining IP Address'.  The requested delete MUST
+        NOT be performed or acted upon, other than to send the ASCONF-
+        ACK.
+
+   F8)  If a request is received to delete an IP address that is also
+        the source address of the IP packet that contained the ASCONF
+        chunk, the receiver MUST reject this request.  To reject the
+        request, the receiver MUST send an Error Cause TLV set to the
+        new error code 'Request to Delete Source IP Address' (unless
+        Rule F5 has also been violated, in which case the error code
+        'Request to Delete Last Remaining IP Address' is sent).
+
+   F9)  If an endpoint receives an ADD IP Address request and does not
+        have the local resources to add this new address to the
+        association, it MUST return an Error Cause TLV set to the new
+        error code 'Operation Refused Due to Resource Shortage'.
+
+   F10) If an endpoint receives an 'Out of Resource' error in response
+        to its request to ADD an IP address to an association, it must
+        either ABORT the association or not consider the address part of
+        the association.  In other words, if the endpoint does not ABORT
+        the association, it must consider the add attempt failed and NOT
+        use this address since its peer will treat SCTP packets destined
+        to the address as Out Of The Blue packets.
+
+   F11) When an endpoint receives an ASCONF to add an IP address sends
+        an 'Out of Resource' in its response, it MUST also fail any
+        subsequent add or delete requests bundled in the ASCONF.  The
+        receiver MUST NOT reject an ADD and then accept a subsequent
+        DELETE of an IP address in the same ASCONF Chunk.  In other
+        words, once a receiver begins failing any ADD or DELETE request,
+        it must fail all subsequent ADD or DELETE requests contained in
+        that single ASCONF.
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.             Standards Track                    [Page 26]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+   F12) When an endpoint receives a request to delete an IP address that
+        is the current primary address, it is an implementation decision
+        as to how that endpoint chooses the new primary address.
+
+   F13) When an endpoint receives a valid request to DELETE an IP
+        address, the endpoint MUST consider the address no longer part
+        of the association.  It MUST NOT send SCTP packets for the
+        association to that address and it MUST treat subsequent packets
+        received from that address as Out Of The Blue.
+
+        During the time interval between sending out the ASCONF and
+        receiving the ASCONF-ACK, it MAY be possible to receive DATA
+        Chunks out of order.  The following examples illustrate these
+        problems:
+
+   F14) All addresses added by the reception of an ASCONF Chunk MUST be
+        put into the UNCONFIRMED state and MUST have path verification
+        performed on them before the address can be used as described in
+        [RFC4960], Section 5.4.
+
+       Endpoint-A                                     Endpoint-Z
+       ----------                                     ----------
+       ASCONF[Add-IP:X]------------------------------>
+                                               /--ASCONF-ACK
+                                              /
+                                    /--------/---New DATA:
+                                   /        /    Destination
+              <-------------------/        /     IP:X
+                                          /
+              <--------------------------/
+
+   In the above example, we see a new IP address (X) being added to the
+   Endpoint-A.  However, due to packet re-ordering in the network, a new
+   DATA chunk is sent and arrives at Endpoint-A before the ASCONF-ACK
+   confirms the add of the address to the association.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.             Standards Track                    [Page 27]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+   A similar problem exists with the deletion of an IP address as
+   follows:
+
+       Endpoint-A                                     Endpoint-Z
+       ----------                                     ----------
+                                    /------------New DATA:
+                                   /             Destination
+                                  /              IP:X
+       ASCONF [DEL-IP:X]---------/---------------->
+              <-----------------/------------------ASCONF-ACK
+                               /
+                              /
+               <-------------/
+
+   In this example, we see a DATA chunk destined to the IP:X (which is
+   about to be deleted) arriving after the deletion is complete.  For
+   the ADD case, an endpoint SHOULD consider the newly added IP address
+   for the purpose of sending data to the association before the ASCONF-
+   ACK has been received.  The endpoint MUST NOT source data from this
+   new address until the ASCONF-ACK arrives, but it may receive out-of-
+   order data as illustrated and MUST NOT treat this data as an OOTB
+   datagram (please see [RFC4960] section 8.4).  It MAY drop the data
+   silently or it MAY consider it part of the association, but it MUST
+   NOT respond with an ABORT.
+
+   For the DELETE case, an endpoint MAY respond to the late-arriving
+   DATA packet as an OOTB datagram or it MAY hold the deleting IP
+   address for a small period of time as still valid.  If it treats the
+   DATA packet as OOTB, the peer will silently discard the ABORT (since
+   by the time the ABORT is sent, the peer will have removed the IP
+   address from this association).  If the endpoint elects to hold the
+   IP address valid for a period of time, it MUST NOT hold it valid
+   longer than 2 RTO intervals for the destination being removed.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.             Standards Track                    [Page 28]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+5.3.1.  A Special Case for OOTB ABORT Chunks
+
+   Another case worth mentioning is illustrated below:
+
+       Endpoint-A                                     Endpoint-Z
+       ----------                                     ----------
+
+       New DATA:------------\
+       Source IP:X           \
+                              \
+       ASCONF-REQ[DEL-IP:X]----\------------------>
+                                \        /---------ASCONF-ACK
+                                 \      /
+                                  \----/-----------> OOTB
+       (Ignored <---------------------/-------------ABORT
+        by rule F4)                  /
+              <---------------------/
+
+   For this case, during the deletion of an IP address, an Abort MUST be
+   ignored if the destination address of the Abort message is that of a
+   destination being deleted.
+
+5.3.2.  A Special Case for Changing an Address
+
+   In some instances, the sender may only have one IP address in an
+   association that is being renumbered.  When this occurs, the sender
+   may not be able to send the appropriate ADD/DELETE pair to the peer,
+   and may use the old address as a source in the IP header.  For this
+   reason, the sender MUST fill in the Address Parameter field with an
+   address that is part of the association (in this case, the one being
+   deleted).  This will allow the receiver to locate the association
+   without using the source address found in the IP header.
+
+   The receiver of such a chunk MUST always first use the source address
+   found in the IP header in looking up the association.  The receiver
+   should attempt to use the address found in the Address Parameter
+   field only if the lookup using the source address from the IP header
+   fails.  The receiver MUST reply to the source address of the packet
+   in this case, which is the new address that was added by the ASCONF
+   (since the old address is no longer part of the association after
+   processing).
+
+5.4.  Setting of the Primary Address
+
+   A sender of the set primary parameter MAY elect to send this combined
+   with an add or delete of an address.  A sender MUST only send a set
+   primary request to an address that is already considered part of the
+   association.  In other words, if a sender combines a set primary with
+
+
+
+Stewart, et al.             Standards Track                    [Page 29]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+   an add new IP address request, the set primary will be discarded
+   unless the add request is to be processed BEFORE the set primary
+   (i.e., it precedes the set primary).
+
+   A request to set primary MAY also appear in an INIT or INIT-ACK
+   chunk, which can give advice to the peer endpoint as to which of its
+   addresses the sender of the INIT or INIT-ACK would prefer as the
+   primary address.
+
+   The request to set an address as the primary path is an option the
+   receiver SHOULD perform.  It is considered advice to the receiver of
+   the best-destination address to use in sending SCTP packets (in the
+   requester's view).  If a request arrives that asks the receiver to
+   set an address as primary that does not exist, the receiver SHOULD
+   NOT honor the request, leaving its existing primary address
+   unchanged.
+
+5.5.  Bundling of Multiple ASCONFs
+
+   In the normal case, a single ASCONF is sent in a packet and a single
+   reply ASCONF-ACK is received.  However, in the event of the loss of
+   an SCTP packet containing either an ASCONF or ASCONF-ACK, it is
+   allowable for a sender to bundle additional ASCONFs in the
+   retransmission.  In bundling multiple ASCONFs, the following rules
+   MUST be followed:
+
+   1.  Previously transmitted ASCONF Chunks MUST be left unchanged.
+
+   2.  Each SCTP packet containing ASCONF Chunks MUST be bundled
+       starting with the smallest ASCONF Sequence Number first in the
+       packet (closest to the Chunk header) and preceding in sequential
+       order from the lowest to highest ASCONF Sequence Number.
+
+   3.  All ASCONFs within the packet MUST be adjacent to each other,
+       i.e., no other chunk type must separate the ASCONFs.
+
+   4.  Each new ASCONF lookup address MUST be populated as if the
+       previous ASCONFs had been processed and accepted.
+
+6.  Security Considerations
+
+   The addition and or deletion of an IP address to an existing
+   association does provide an additional mechanism by which existing
+   associations can be hijacked.  Therefore, this document requires the
+   use of the authentication mechanism defined in [RFC4895] to limit the
+   ability of an attacker to hijack an association.
+
+
+
+
+
+Stewart, et al.             Standards Track                    [Page 30]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+   Hijacking an association by using the addition and deletion of an IP
+   address is only possible for an attacker who is able to intercept the
+   initial two packets of the association setup when the SCTP-AUTH
+   extension is used without pre-shared keys.  If such a threat is
+   considered a possibility, then the [RFC4895] extension MUST be used
+   with a preconfigured shared endpoint pair key to mitigate this
+   threat.  For a more detailed analysis, see [RFC4895].
+
+   When the address parameter in ASCONF chunks with Add, IP Delete IP,
+   or Set Primary IP parameters is a wildcard, the source address of the
+   packet is used.  This address is not protected by SCTP-AUTH [RFC4895]
+   and an attacker can therefore intercept such a packet and modify the
+   source address.  Even if the source address is not one presently an
+   alternate for the association, the identification of the association
+   may rely on the other information in the packet (perhaps the
+   verification tag, for example).  An on-path attacker can therefore
+   modify the source address to its liking.
+
+   If the ASCONF includes an Add IP with a wildcard address, the
+   attacker can add an address of its liking, which provides little
+   immediate damage but can set up later attacks.
+
+   If the ASCONF includes a Delete IP with a wildcard address, the
+   attacker can cause all addresses but one of its choosing to be
+   deleted from an association.  The address supplied by the attacker
+   must already belong to the association, which makes this more
+   difficult for the attacker.  However, the sole remaining address
+   might be one that the attacker controls, for example, or can monitor,
+   etc.  In the least, the sender and the deceived receiver would have
+   different ideas of what that sole remaining address would be.  This
+   will eventually cause the association to fail, but in the meantime,
+   the deceived receiver could be transmitting packets to an address the
+   sender did not intend.
+
+   If the ASCONF includes a Set Primary IP with a wildcard address, then
+   the attacker can cause an address to be used as a primary address.
+   This is limited to an address that already belongs to the
+   association, so the damage is limited.  At least, the result would be
+   that the recipient is using a primary address that the sender did not
+   intend.  However, if both a wildcard Add IP and a wildcard Set
+   Primary IP are used, then the attacker can modify the source address
+   to both add an address to its liking to the association and make it
+   the primary address.  Such a combination would present the attacker
+   with an opportunity for more damage.
+
+
+
+
+
+
+
+Stewart, et al.             Standards Track                    [Page 31]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+   Note that all these attacks are from an on-path attacker.  Endpoints
+   that believe they face a threat from on-path attackers SHOULD NOT use
+   wildcard addresses in ASCONF Add IP, Delete IP, or Set Primary IP
+   parameters.
+
+   If an SCTP endpoint that supports this extension receives an INIT
+   that indicates that the peer supports the ASCONF extension but does
+   NOT support the [RFC4895] extension, the receiver of such an INIT
+   MUST send an ABORT in response.  Note that an implementation is
+   allowed to silently discard such an INIT as an option as well, but
+   under NO circumstance is an implementation allowed to proceed with
+   the association setup by sending an INIT-ACK in response.
+
+   An implementation that receives an INIT-ACK that indicates that the
+   peer does not support the [RFC4895] extension MUST NOT send the
+   COOKIE-ECHO to establish the association.  Instead, the
+   implementation MUST discard the INIT-ACK and report to the upper-
+   layer user that an association cannot be established destroying the
+   Transmission Control Block (TCB).
+
+   Other types of attacks, e.g., bombing, are discussed in detail in
+   [RFC5062].  The bombing attack, in particular, is countered by the
+   use of a random nonce and is required by [RFC4960].
+
+   An on-path attacker can modify the INIT and INIT-ACK Supported
+   Extensions parameter (and authentication-related parameters) to
+   produce a denial of service.  If the on-path attacker removes the
+   [RFC4895]-related parameters from an INIT that indicates it supports
+   the ASCONF extension, the association will not be established.  If
+   the on-path attacker adds a Supported Extensions parameter mentioning
+   the ASCONF type to an INIT or INIT-ACK that does not carry any AUTH-
+   related parameters, the association will not be established.  If the
+   on-path attacker removes the Supported Extensions parameter (or
+   removes the ASCONF type from that parameter) from the INIT or the
+   INIT-ACK, then the association will not be able to use the ADD-IP
+   feature.  If the on-path attacker adds the Supported Extensions
+   parameter listing the ASCONF type to an INIT-ACK that did not carry
+   one (but did carry AUTH-related parameters), then the INIT sender may
+   use ASCONF where the INIT-ACK sender does not support it.  This would
+   be discovered later if the INIT sender transmitted an ASCONF, but the
+   INIT sender could have made configuration choices at that point.  As
+   the INIT and INIT-ACK are not protected by the AUTH feature, there is
+   no way to counter such attacks.  Note however that an on-path
+   attacker capable of modifying the INIT and INIT-ACK would almost
+   certainly also be able to prevent the INIT and INIT-ACK from being
+   delivered or modify the verification tags or checksum to cause the
+   packet to be discarded, so the Supported Extensions adds little
+   additional vulnerability (with respect to preventing association
+
+
+
+Stewart, et al.             Standards Track                    [Page 32]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+   formation) to the SCTP protocol.  The ability to prevent the use of
+   this new feature is an additional vulnerability to SCTP but only for
+   this new feature.
+
+   The Adaptation Layer Indication is subject to corruption, insertion,
+   or deletion from the INIT and INIT-ACK chunks by an on-path attacker.
+   This parameter SHOULD be opaque to the SCTP protocol (see Section
+   4.2.6), and so changes to the parameter will likely not affect the
+   SCTP protocol.  However, any adaptation layer that is defined SHOULD
+   consider its own vulnerabilities in the Security Considerations
+   section of the RFC that defines its adaptation code point.
+
+   The Set Primary IP Address parameter is subject to corruption,
+   insertion, or deletion by an on-path attacker when included in the
+   INIT and INIT-ACK chunks.  The attacker could use this to influence
+   the receiver to choose an address to its own purposes (one over which
+   it has control, one that would be less desirable for the sender,
+   etc.).  An on-path attacker would also have the ability to include or
+   remove addresses for the association from the INIT or INIT-ACK, so it
+   is not limited in the address it can specify in the Set Primary IP
+   Address.  Endpoints that wish to avoid this possible threat MAY defer
+   sending the initial Set Primary request and wait until the
+   association is fully established before sending a fully protected
+   ASCONF with the Set Primary as its single parameter.
+
+7.  IANA Considerations
+
+   This document defines the following new SCTP parameters, chunks, and
+   errors (http://www.iana.org/assignments/sctp-parameters):
+
+   o  two new chunk types,
+
+   o  six parameter types, and
+
+   o  five new SCTP error causes.
+
+   The chunk types with their assigned values are shown below.
+
+        Chunk Type  Chunk Name
+        --------------------------------------------------------------
+        0xC1    Address Configuration Change Chunk        (ASCONF)
+        0x80    Address Configuration Acknowledgment      (ASCONF-ACK)
+
+
+
+
+
+
+
+
+
+Stewart, et al.             Standards Track                    [Page 33]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+   The parameter types are listed below:
+
+        Parameter Type     Parameter Name
+        -------------------------------------------------
+        0x8008             Supported Extensions
+        0xC001             Add IP Address
+        0xC002             Delete IP Address
+        0xC003             Error Cause Indication
+        0xC004             Set Primary Address
+        0xC005             Success Indication
+        0xC006             Adaptation Layer Indication
+
+   The Error Causes are listed below:
+
+       Cause Code
+       Value          Cause Code
+       ---------      ----------------
+       0x00A0          Request to Delete Last Remaining IP Address
+       0x00A1          Operation Refused Due to Resource Shortage
+       0x00A2          Request to Delete Source IP Address
+       0x00A3          Association Aborted Due to Illegal ASCONF-ACK
+       0x00A4          Request Refused - No Authorization
+
+   This document also defines an adaptation code point.  The adaptation
+   code point is a 32-bit integer that is assigned by IANA through an
+   IETF Consensus action as defined in [RFC2434].  For this new
+   registry, no initial values are being added by this document;
+   however, [RDDP] will add the first entry.
+
+8.  Acknowledgments
+
+   The authors would like to express a special note of thanks to Michael
+   Ramahlo and Phillip Conrad for their extreme efforts in the early
+   formation of this draft.
+
+   The authors wish to thank Jon Berger, Mark Butler, Lars Eggert,
+   Janardhan Iyengar, Greg Kendall, Seok Koh, Salvatore Loreto, Peter
+   Lei, John Loughney, Sandy Murphy, Ivan Arias Rodriguez, Renee Revis,
+   Marshall Rose, Ronnie Sellars, Chip Sharp, and Irene Ruengeler for
+   their invaluable comments.
+
+   The authors would also like to give special mention to Maria-Carmen
+   Belinchon and Ian Rytina for their early contributions to this
+   document and their thoughtful comments.
+
+   And a special thanks to James Polk, abstract writer to the few but
+   lucky.
+
+
+
+
+Stewart, et al.             Standards Track                    [Page 34]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+9.  References
+
+9.1.  Normative References
+
+   [RFC1122]  Braden, R., "Requirements for Internet Hosts -
+              Communication Layers", STD 3, RFC 1122, October 1989.
+
+   [RFC1982]  Elz, R. and R. Bush, "Serial Number Arithmetic", RFC 1982,
+              August 1996.
+
+   [RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
+              Requirement Levels", BCP 14, RFC 2119, March 1997.
+
+   [RFC2434]  Narten, T. and H. Alvestrand, "Guidelines for Writing an
+              IANA Considerations Section in RFCs", BCP 26, RFC 2434,
+              October 1998.
+
+   [RFC2460]  Deering, S. and R. Hinden, "Internet Protocol, Version 6
+              (IPv6) Specification", RFC 2460, December 1998.
+
+   [RFC4960]  Stewart, R., Ed., "Stream Control Transmission Protocol",
+              RFC 4960, September 2007.
+
+   [RFC4895]  Tuexen, M., Stewart, R., Lei, P., and E. Rescorla,
+              "Authenticated Chunks for the Stream Control Transmission
+              Protocol (SCTP)", RFC 4895, August 2007.
+
+9.2.  Informative References
+
+   [RFC5062]  Stewart, R., Tuexen, M., and G. Camarillo, "Security
+              Attacks Found Against SCTP and Current Countermeasures",
+              RFC 5062, September 2007.
+
+   [RDDP]     Bestler, C. and R. Stewart, "Stream Control Transmission
+              Protocol (SCTP) Direct Data Placement (DDP) Adaptation",
+              Work in Progress, September 2006.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.             Standards Track                    [Page 35]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+Appendix A.  Abstract Address Handling
+
+A.1.  General Remarks
+
+   This appendix is non-normative.  It is present to give the reader a
+   concise mathematical definition of an SCTP endpoint.  The following
+   text provides a working definition of the endpoint notion to discuss
+   address reconfiguration.  It is not intended to restrict
+   implementations in any way; its goal is to provide a set of
+   definitions only.  Using these definitions should make a discussion
+   about address issues easier.
+
+A.2.  Generalized Endpoints
+
+   A generalized endpoint is a pair of a set of IP addresses and a port
+   number at any given point of time.  The precise definition is as
+   follows:
+
+   A generalized endpoint gE at time t is given by
+
+                  gE(t) = ({IP1, ..., IPn}, Port)
+
+   where {IP1, ..., IPn} is a non-empty set of IP addresses.
+
+   Please note that the dynamic addition and deletion of IP addresses
+   described in this document allows the set of IP addresses of a
+   generalized endpoint to be changed at some point of time.  The port
+   number can never be changed.
+
+   The set of IP addresses of a generalized endpoint gE at a time t is
+   defined as
+
+               Addr(gE)(t) = {IP1, ..., IPn}
+
+   if gE(t) = ({IP1, ..., IPn}, Port) holds at time t.
+
+   The port number of a generalized endpoint gE is defined as
+
+               Port(gE) = Port
+
+   if gE(t) = ({IP1, ..., IPn}, Port) holds at time t.
+
+   There is one fundamental rule that restricts all generalized
+   endpoints:
+
+   For two different generalized endpoints gE' and gE'' with the same
+   port number Port(gE') = Port(gE''), the address sets Addr(gE')(t) and
+   Addr(gE'')(t) must be disjoint at every point in time.
+
+
+
+Stewart, et al.             Standards Track                    [Page 36]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+A.3.  Associations
+
+   Associations consist of two generalized endpoints and the two address
+   sets known by the peer at any time.  The precise definition is as
+   follows:
+
+   An association A between two different generalized endpoints gE' and
+   gE'' is given by
+
+                  A = (gE', S', gE'', S'')
+
+   where S'(t) and S''(t) are a set of addresses at any time t such that
+   S'(t) is a non-empty subset of Addr(gE')(t) and S''(t) is a non-empty
+   subset of Addr(gE'')(t).
+
+   If A = (gE', S', gE'', S'') is an association between the generalized
+   endpoints gE' and gE'', the following notion is used:
+
+                  Addr(A, gE') = S'   and  Addr(A, gE'') = S''.
+
+   If the dependency on time is important the notion Addr(A, gE')(t) =
+   S'(t) will be used.
+
+   If A is an association between gE' and gE'', then Addr(A, gE') is the
+   subset of IP addresses of gE', which is known by gE'' and used by
+   gE'.
+
+   Association establishment between gE' and gE'' can be seen as:
+
+   1.  gE' and gE'' do exist before the association.
+
+   2.  If an INIT has to be sent from gE' to gE'', address-scoping rules
+       and other limitations are applied to calculate the subset S' from
+       Addr(gE').  The addresses of S' are included in the INIT chunk.
+
+   3.  If an INIT-ACK has to be sent from gE'' to gE', address-scoping
+       rules and other limitations are applied to calculate the subset
+       S'' from Addr(gE'').  The addresses of S'' are included in the
+       INIT-ACK chunk.
+
+   4.  After the handshake the association A = (gE', S', gE'', S'') has
+       been established.
+
+   5.  Right after the association establishment Addr(A, gE') and
+       Addr(A, gE'') are the addresses that have been seen on the wire
+       during the handshake.
+
+
+
+
+
+Stewart, et al.             Standards Track                    [Page 37]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+A.4.  Relationship with RFC 4960
+
+   [RFC4960] defines the notion of an endpoint.  This subsection will
+   show that these endpoints are also (special) generalized endpoints.
+
+   [RFC4960] has no notion of address-scoping or other address-handling
+   limitations and provides no mechanism to change the addresses of an
+   endpoint.
+
+   This means that an endpoint is simply a generalized endpoint that
+   does not depend on time.  Neither the port nor the address list
+   changes.
+
+   During association setup, no address-scoping rules or other
+   limitations will be applied.  This means that for an association A
+   between two endpoints gE' and gE'', the following is true:
+
+   Addr(A, gE') = Addr(gE') and Addr(A, gE'') = Addr(gE'').
+
+A.5.  Rules for Address Manipulation
+
+   The rules for address manipulation can now be stated in a simple way:
+
+   1.  An address can be added to a generalized endpoint gE only if this
+       address is not an address of a different generalized endpoint
+       with the same port number.
+
+   2.  An address can be added to an association A with generalized
+       endpoint gE if it has been added to the generalized endpoint gE
+       first.  This means that the address must be an element of
+       Addr(gE) first and then it can become an element of Addr(A, gE).
+       But this is not necessary.  If the association does not allow the
+       reconfiguration of the addresses only Addr(gE) can be modified.
+
+   3.  An address can be deleted from an association A with generalized
+       endpoint gE as long as Addr(A, gE) stays non-empty.
+
+   4.  An address can be deleted from an generalized endpoint gE only if
+       it has been removed from all associations having gE as a
+       generalized endpoint.
+
+   These rules simply make sure that the rules for the endpoints and
+   associations given above are always fulfilled.
+
+
+
+
+
+
+
+
+Stewart, et al.             Standards Track                    [Page 38]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+Authors' Addresses
+
+   Randall R. Stewart
+   Cisco Systems, Inc.
+   4875 Forest Drive
+   Suite 200
+   Columbia, SC  29206
+   US
+
+   Phone:
+   EMail: rrs@cisco.com
+
+
+   Qiaobing Xie
+   Motorola, Inc.
+   1501 W. Shure Drive, 2-3C
+   Arlington Heights, IL  60004
+   USA
+
+   Phone: +1-847-632-3028
+   EMail: Qiaobing.Xie@motorola.com
+
+
+   Michael Tuexen
+   Univ. of Applied Sciences Muenster
+   Stegerwaldstr. 39
+   48565 Steinfurt
+   Germany
+
+   EMail: tuexen@fh-muenster.de
+
+
+   Shin Maruyama
+   Kyoto University
+   Yoshida-Honmachi
+   Sakyo-ku
+   Kyoto, Kyoto  606-8501
+   JAPAN
+
+   Phone: +81-75-753-7417
+   EMail: mail@marushin.gr.jp
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.             Standards Track                    [Page 39]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+   Masahiro Kozuka
+   Kyoto University
+   Yoshida-Honmachi
+   Sakyo-ku
+   Kyoto, Kyoto  606-8501
+   JAPAN
+
+   Phone: +81-75-753-7417
+   EMail: ma-kun@kozuka.jp
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.             Standards Track                    [Page 40]
+
+RFC 5061          SCTP Dynamic Address Reconfiguration    September 2007
+
+
+Full Copyright Statement
+
+   Copyright (C) The IETF Trust (2007).
+
+   This document is subject to the rights, licenses and restrictions
+   contained in BCP 78, and except as set forth therein, the authors
+   retain all their rights.
+
+   This document and the information contained herein are provided on an
+   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
+   OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND
+   THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
+   THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
+   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Intellectual Property
+
+   The IETF takes no position regarding the validity or scope of any
+   Intellectual Property Rights or other rights that might be claimed to
+   pertain to the implementation or use of the technology described in
+   this document or the extent to which any license under such rights
+   might or might not be available; nor does it represent that it has
+   made any independent effort to identify any such rights.  Information
+   on the procedures with respect to rights in RFC documents can be
+   found in BCP 78 and BCP 79.
+
+   Copies of IPR disclosures made to the IETF Secretariat and any
+   assurances of licenses to be made available, or the result of an
+   attempt made to obtain a general license or permission for the use of
+   such proprietary rights by implementers or users of this
+   specification can be obtained from the IETF on-line IPR repository at
+   http://www.ietf.org/ipr.
+
+   The IETF invites any interested party to bring to its attention any
+   copyrights, patents or patent applications, or other proprietary
+   rights that may cover technology that may be required to implement
+   this standard.  Please address the information to the IETF at
+   ietf-ipr@ietf.org.
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.             Standards Track                    [Page 41]
+
diff --git a/doc/rfc5062.txt b/doc/rfc5062.txt
new file mode 100644
index 0000000..d008c9d
--- /dev/null
+++ b/doc/rfc5062.txt
@@ -0,0 +1,787 @@
+
+
+
+
+
+
+<.
+Network Working Group                                         R. Stewart
+Request for Comments: 5062                           Cisco Systems, Inc.
+Category: Informational                                        M. Tuexen
+                                      Muenster Univ. of Applied Sciences
+                                                            G. Camarillo
+                                                                Ericsson
+                                                          September 2007
+
+
+                    Security Attacks Found Against
+            the Stream Control Transmission Protocol (SCTP)
+                      and Current Countermeasures
+
+Status of This Memo
+
+   This memo provides information for the Internet community.  It does
+   not specify an Internet standard of any kind.  Distribution of this
+   memo is unlimited.
+
+Abstract
+
+   This document describes certain security threats to SCTP.  It also
+   describes ways to mitigate these threats, in particular by using
+   techniques from the SCTP Specification Errata and Issues memo (RFC
+   4460).  These techniques are included in RFC 4960, which obsoletes
+   RFC 2960.  It is hoped that this information will provide some useful
+   background information for many of the newest requirements spelled
+   out in the SCTP Specification Errata and Issues and included in RFC
+   4960.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.              Informational                      [Page 1]
+
+RFC 5062                 SCTP Security Attacks            September 2007
+
+
+Table of Contents
+
+   1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  2
+   2.  Address Camping or Stealing  . . . . . . . . . . . . . . . . .  2
+   3.  Association Hijacking 1  . . . . . . . . . . . . . . . . . . .  3
+   4.  Association Hijacking 2  . . . . . . . . . . . . . . . . . . .  6
+   5.  Bombing Attack (Amplification) 1 . . . . . . . . . . . . . . .  7
+   6.  Bombing Attack (Amplification) 2 . . . . . . . . . . . . . . .  9
+   7.  Association Redirection  . . . . . . . . . . . . . . . . . . . 10
+   8.  Bombing Attack (Amplification) 3 . . . . . . . . . . . . . . . 10
+   9.  Bombing Attack (Amplification) 4 . . . . . . . . . . . . . . . 11
+   10. Bombing Attack (amplification) 5 . . . . . . . . . . . . . . . 11
+   11. Security Considerations  . . . . . . . . . . . . . . . . . . . 12
+   12. References . . . . . . . . . . . . . . . . . . . . . . . . . . 12
+
+1.  Introduction
+
+   Stream Control Transmission Protocol, originally defined in
+   [RFC2960], is a multi-homed transport protocol.  As such, unique
+   security threats exists that are addressed in various ways within the
+   protocol itself.  This document describes certain security threats to
+   SCTP.  It also describes ways to mitigate these threats, in
+   particular by using techniques from the SCTP Specification Errata and
+   Issues memo [RFC4460].  These techniques are included in [RFC4960],
+   which obsoletes [RFC2960].  It is hoped that this information will
+   provide some useful background information for many of the newest
+   requirements spelled out in the [RFC4460] and included in [RFC4960].
+
+   This work and some of the changes that went into [RFC4460] and
+   [RFC4960] are much indebted to the paper on potential SCTP security
+   risks [EFFECTS] by Aura, Nikander, and Camarillo.  Without their
+   work, some of these changes would remain undocumented and potential
+   threats.
+
+   The rest of this document will concentrate on the various attacks
+   that were illustrated in [EFFECTS] and detail the preventative
+   measures now in place, if any, within the current SCTP standards.
+
+2.  Address Camping or Stealing
+
+   This attack is a form of denial of service attack crafted around
+   SCTP's multi-homing.  In effect, an illegitimate endpoint connects to
+   a server and "camps upon" or "holds up" a valid peer's address.  This
+   is done to prevent the legitimate peer from communicating with the
+   server.
+
+
+
+
+
+
+Stewart, et al.              Informational                      [Page 2]
+
+RFC 5062                 SCTP Security Attacks            September 2007
+
+
+2.1.  Attack Details
+
+      +----------+            +----------+           +----------+
+      | Evil     |            |  Server  |           | Client   |
+      |     IP-A=+------------+          +-----------+=IP-C & D |
+      | Attacker |            |          |           | Victim   |
+      +----------+            +----------+           +----------+
+
+                            Figure 1: Camping
+
+   Consider the scenario illustrated in Figure 1.  The attacker
+   legitimately holds IP-A and wishes to prevent the 'Client-Victim'
+   from communicating with the 'Server'.  Note also that the client is
+   multi-homed.  The attacker first guesses the port number our client
+   will use in its association attempt.  It then uses this port and sets
+   up an association with the server listing not only IP-A but also IP-C
+   in its initial INIT chunk.  The server will respond and set up the
+   association, noting that the attacker is multi-homed and holds both
+   IP-A and IP-C.
+
+   Next, the victim sends in an INIT message listing its two valid
+   addresses, IP-C and IP-D.  In response, it will receive an ABORT
+   message with possibly an error code indicating that a new address was
+   added in its attempt to set up an existing association (a restart
+   with new addresses).  At this point, 'Client-Victim' is now prevented
+   from setting up an association with the server until the server
+   realizes that the attacker does not hold the address IP-C at some
+   future point by using a HEARTBEAT based mechanism.  See the
+   mitigation option subsection of this section.
+
+2.2.  Analysis
+
+   This particular attack was discussed in detail on the SCTP
+   implementors list in March of 2003.  Out of that discussion, changes
+   were made in the BSD implementation that are now present in
+   [RFC4960].  In close examination, this attack depends on a number of
+   specific things to occur.
+
+   1) The attacker must set up the association before the victim and
+      must correctly guess the port number that the victim will use.  If
+      the victim uses any other port number the attack will fail.
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.              Informational                      [Page 3]
+
+RFC 5062                 SCTP Security Attacks            September 2007
+
+
+   2) SCTP's existing HEARTBEAT mechanism as defined already in
+      [RFC2960] will eventually catch this situation and abort the evil
+      attacker's association.  This may take several seconds based on
+      default HEARTBEAT timers but the attacker himself will lose any
+      association.
+
+   3) If the victim is either not multi-homed, or the address set that
+      it uses is completely camped upon by the attacker (in our example
+      if the attacker had included IP-D in its INIT as well), then the
+      client's INIT message would initiate an association between the
+      client and the server while destroying the association between the
+      attacker and the server.  From the servers' perspective, this is a
+      restart of the association.
+
+2.3.  Mitigation Option
+
+   [RFC4960] adds a new set of requirements to better counter this
+   attack.  In particular, the HEARTBEAT mechanism was modified so that
+   addresses unknown to an endpoint (i.e., presented in an INIT with no
+   pre-knowledge given by the application) enter a new state called
+   "UNCONFIRMED".  During the time that any address is UNCONFIRMED and
+   yet considered available, heartbeating will be done on those
+   UNCONFIRMED addresses at an accelerated rate.  This will lessen the
+   time that an attacker can "camp" on an address.  In particular, the
+   rate of heartbeats to UNCONFIRMED addresses is done every RTO.  Along
+   with this expanded rate of heartbeating, a new 64-bit random nonce is
+   required to be inside HEARTBEATs to UNCONFIRMED addresses.  In the
+   HEARTBEAT-ACK, the random nonce must match the value sent in the
+   HEARTBEAT before an address can leave the UNCONFIRMED state.  This
+   will prevent an attacker from generating false HEARTBEAT-ACKs with
+   the victim's source address(es).  In addition, clients that do not
+   need to use a specific port number should choose their port numbers
+   on a random basis.  This makes it hard for an attacker to guess that
+   number.
+
+3.  Association Hijacking 1
+
+   Association hijacking is the ability of some other user to assume the
+   session created by another endpoint.  In cases of a true man-in-the-
+   middle, only a strong end-to-end security model can prevent this.
+   However, with the addition of the SCTP extension specified in
+   [RFC5061], an endpoint that is NOT a man-in-the-middle may be able to
+   assume another endpoint's association.
+
+
+
+
+
+
+
+
+Stewart, et al.              Informational                      [Page 4]
+
+RFC 5062                 SCTP Security Attacks            September 2007
+
+
+3.1.  Attack Details
+
+   The attack is made possible by any mechanism that lets an endpoint
+   acquire some other IP address that was recently in use by an SCTP
+   endpoint.  For example, DHCP may be used in a mobile network with
+   short IP address lifetimes to reassign IP addresses to migrant hosts.
+
+        IP-A                 DHCP-Server's       Peer-Server
+          |
+          |
+       1  |-DHCP-Rel(IP-A)---->|
+       2  |------ASCONF(ADD-IP(IP-B), DEL-IP(IP-A)---->XXlost
+         time
+          |
+          |-DHCP-new-net------>|
+       3  |<---Assign (IP-A)
+          |
+       4  |<------------Tag:X-DATA()------------------
+          |
+          |-------------INIT()------------------------>
+       5  |<------------INIT-ACK()---------------------
+          |
+       6  |----ASCONF(ADD-IP(IP-Z),DEL-IP(IP-A))------>
+
+                   Figure 2: Association Hijack via DHCP
+
+   At point 1, our valid client releases the IP address IP-A.  It
+   presumably acquires a new address (IP-B) and sends an ASCONF to ADD
+   the new address and delete to old address at point 2, but this packet
+   is lost.  Thus, our peer (Peer-Server) has no idea that the former
+   peer is no longer at IP-A.  Now at point 3, a new "evil" peer obtains
+   an address via DHCP and it happens to get the re-assigned address
+   IP-A.  Our Peer-Server sends a chunk of DATA at point 4.  This
+   reveals to the new owner of IP-A that the former owner of IP-A had an
+   association with Peer-Server.  So at point 5, the new owner of IP-A
+   sends an INIT.  The INIT-ACK is sent back and inside it is a COOKIE.
+   The cookie would of course hold tie-tags, which would list both sets
+   of tags that could then be used at point 6 to add in any other IP
+   addresses that the owner of IP-A holds and thus acquire the
+   association.
+
+   It should be noted that this attack is possible in general whenever
+   the attacker is able to send packets with source address IP-A and
+   receive packets with destination address IP-A.
+
+
+
+
+
+
+
+Stewart, et al.              Informational                      [Page 5]
+
+RFC 5062                 SCTP Security Attacks            September 2007
+
+
+3.2.  Analysis
+
+   This attack depends on a number of events:
+
+   1) Both endpoints must support the SCTP extension specified in
+      [RFC5061].
+
+   2) One of the endpoints must be using the SCTP extension for mobility
+      specified in [RFC5061].
+
+   3) The IP address must be acquired in such a way as to make the
+      endpoint the owner of that IP address as far as the network is
+      concerned.
+
+   4) The true peer must not receive the ASCONF packet that deletes IP-A
+      and adds its new address to the peer before the new "evil" peer
+      gets control of the association.
+
+   5) The new "evil" peer must have an alternate address, aside from the
+      IP-A that it can add to the association, so it can delete IP-A,
+      preventing the real peer from re-acquiring the association when it
+      finally retransmits the ASCONF (from step 2).
+
+3.3.  Mitigation Option
+
+   [RFC4960] adds a new counter measure to this threat.  It is now
+   required that Tie-Tags in the State-Cookie parameter not be the
+   actual tags.  Instead, a new pair of two 32-bit nonces must be used
+   to represent the real tags within the association.  This prevents the
+   attacker from acquiring the real tags and thus prevents this attack.
+   Furthermore, the use of the SCTP extension specified in [RFC5061]
+   requires the use of the authentication mechanism defined in
+   [RFC4895].  This requires the attacker to be able to capture the
+   traffic during the association setup.  If in addition an endpoint-
+   pair shared key is used, capturing or intercepting these setup
+   messages does not enable the attacker to hijack the association.
+
+4.  Association Hijacking 2
+
+   Association hijacking is the ability of some other user to assume the
+   session created by another endpoint.  In cases where an attacker can
+   send packets using the victims IP-address as a source address and can
+   receive packets with the victims' address as a destination address,
+   the attacker can easily restart the association.  If the peer does
+   not pay attention to the restart notification, the attacker has taken
+   over the association.
+
+
+
+
+
+Stewart, et al.              Informational                      [Page 6]
+
+RFC 5062                 SCTP Security Attacks            September 2007
+
+
+4.1.  Attack Details
+
+   Assume that an endpoint E1 having an IP-address A has an SCTP
+   association with endpoint E2.  After the attacker is able to receive
+   packets to destination address A and send packets with source address
+   A, the attacker can perform a full four-way handshake using the IP-
+   addresses and port numbers from the received packet.  E2 will
+   consider this a restart of the association.  If and only if the SCTP
+   user of E2 does not process the restart notification, the user will
+   not recognize that the association just restarted.  From this
+   perspective, the association has been hijacked.
+
+4.2.  Analysis
+
+   This attack depends on a number of circumstances:
+
+   1) The IP address must be acquired in such a way as to make the evil
+      endpoint the owner of that IP address as far as the network or
+      local LAN is concerned.
+
+   2) The attacker must receive a packet belonging to the association or
+      connection.
+
+   3) The other endpoint's user does not pay attention to restart
+      notifications.
+
+4.3.  Mitigation Option
+
+   It is important to note that this attack is not based on a weakness
+   of the protocol, but on the ignorance of the upper layer.  This
+   attack is not possible if the upper layer processes the restart
+   notifications provided by SCTP as described in section 10 of
+   [RFC2960] or [RFC4960].  Note that other IP protocols may also be
+   affected by this attack.
+
+5.  Bombing Attack (Amplification) 1
+
+   The bombing attack is a method to get a server to amplify packets to
+   an innocent victim.
+
+5.1.  Attack Details
+
+   This attack is performed by setting up an association with a peer and
+   listing the victims IP address in the INIT's list of addresses.
+   After the association is setup, the attacker makes a request for a
+   large data transfer.  After making the request, the attacker does not
+   acknowledge data sent to it.  This then causes the server to re-
+   transmit the data to the alternate address, i.e., that of the victim.
+
+
+
+Stewart, et al.              Informational                      [Page 7]
+
+RFC 5062                 SCTP Security Attacks            September 2007
+
+
+   After waiting an appropriate time period, the attacker acknowledges
+   the data for the victim.  At some point, the attackers address is
+   considered unreachable since only data sent to the victims address is
+   acknowledged.  At this point, the attacker can send strategic
+   acknowledgments so that the server continues to send data to the
+   victim.
+
+   Alternatively, instead of stopping the sending of SACKs to enforce a
+   path failover, the attacker can use the ADD-IP extension to add the
+   address of the victim and make that address the primary path.
+
+5.2.  Analysis
+
+   This attack depends on a number of circumstances:
+
+   1) The victim must NOT support SCTP, otherwise it would respond with
+      an "out of the blue" (OOTB) abort.
+
+   2) The attacker must time its sending of acknowledgments correctly in
+      order to get its address into the failed state and the victim's
+      address as the only valid alternative.
+
+   3) The attacker must guess TSN values that are accepted by the
+      receiver once the bombing begins since it must acknowledge packets
+      it is no longer seeing.
+
+5.3.  Mitigation Option
+
+   [RFC4960] makes two changes to prevent this attack.  First, it
+   details proper handling of ICMP messages.  With SCTP, the ICMP
+   messages provide valuable clues to the SCTP stack that can be
+   verified with the tags for authenticity.  Proper handling of an ICMP
+   protocol unreachable (or equivalent) would cause the association
+   setup by the attacker to be immediately failed upon the first
+   retransmission to the victim's address.
+
+   The second change made in [RFC4960] is the requirement that no
+   address that is not CONFIRMED is allowed to have DATA chunks sent to
+   it.  This prevents the switch-over to the alternate address from
+   occurring, even when ICMP messages are lost in the network and
+   prevents any DATA chunks from being sent to any other destination
+   other then the attacker itself.  This also prevents the alternative
+   way of using ADD-IP to add the new address and make it the primary
+   address.
+
+
+
+
+
+
+
+Stewart, et al.              Informational                      [Page 8]
+
+RFC 5062                 SCTP Security Attacks            September 2007
+
+
+   An SCTP implementation should abort the association if it receives a
+   SACK acknowledging a TSN that has not been sent.  This makes TSN
+   guessing for the attacker quite hard because if the attacker
+   acknowledges one TSN too fast, the association will be aborted.
+
+6.  Bombing Attack (Amplification) 2
+
+   This attack allows an attacker to use an arbitrary SCTP endpoint to
+   send multiple packets to a victim in response to one packet.
+
+6.1.  Attack Details
+
+   The attacker sends an INIT listing multiple IP addresses of the
+   victim in the INIT's list of addresses to an arbitrary endpoint.
+   Optionally, it requests a long cookie lifetime.  Upon reception of
+   the INIT-ACK, it stores the cookie and sends it back to the other
+   endpoint.  When the other endpoint receives the COOKIE, it will send
+   back a COOKIE-ACK to the attacker and up to HB.Max.Burst HEARTBEATS
+   to the victim's address(es) (to confirm these addresses).  The victim
+   responds with ABORTs or ICMP messages resulting in the removal of the
+   TCB at the other endpoint.  The attacker can now resend the stored
+   cookie as long as it is valid, and this will again result in up to
+   HB.Max.Burst HEARTBEATs sent to the victim('s).
+
+6.2.  Analysis
+
+   The multiplication factor is limited by the number of addresses of
+   the victim and of the endpoint HB.Max.Burst.  Also, the shorter the
+   cookie lifetime, the earlier the attacker has to go through the
+   initial stage of sending an INIT instead of just sending the COOKIE.
+   It should also be noted that the attack is more effective if large
+   HEARTBEATs are used for path confirmation.
+
+6.3.  Mitigation Option
+
+   To limit the effectiveness of this attack, the new parameter
+   HB.Max.Burst was introduced in [RFC4960] and an endpoint should:
+
+   1) not allow very large cookie lifetimes, even if they are requested.
+
+   2) not use larger HB.Max.Burst parameter values than recommended.
+      Note that an endpoint may decide to send only one Heartbeat per
+      RTT instead of the maximum (i.e., HB.Max.Burst).  An endpoint that
+      chooses this approach will however slow down detection of
+      endpoints camping on valid addresses.
+
+   3) not use large HEARTBEATs for path confirmation.
+
+
+
+
+Stewart, et al.              Informational                      [Page 9]
+
+RFC 5062                 SCTP Security Attacks            September 2007
+
+
+7.  Association Redirection
+
+   This attack allows an attacker to wrongly set up an association to a
+   different endpoint.
+
+7.1.  Attack Details
+
+   The attacker sends an INIT sourced from port 'X' and directed towards
+   port 'Y'.  When the INIT-ACK is returned, the attacker sends the
+   COOKIE-ECHO chunk and either places a different destination or source
+   port in the SCTP common header, i.e., X+1 or Y+1.  This possibly sets
+   up the association using the modified port numbers.
+
+7.2.  Analysis
+
+   This attack depends on the failure of an SCTP implementation to store
+   and verify the ports within the COOKIE structure.
+
+7.3.  Mitigation Option
+
+   This attack is easily defeated by an implementation including the
+   ports of both the source and destination within the COOKIE.  If the
+   source and destination ports do not match those within the COOKIE
+   chunk when the COOKIE is returned, the SCTP implementation silently
+   discards the invalid COOKIE.
+
+8.  Bombing Attack (Amplification) 3
+
+   This attack allows an attacker to use an SCTP endpoint to send a
+   large number of packets in response to one packet.
+
+8.1.  Attack Details
+
+   The attacker sends a packet to an SCTP endpoint, which requires the
+   sending of multiple chunks.  If the SCTP endpoint does not support
+   bundling on the sending side, it might send each chunk per packet.
+   These packets can either be sent to a victim by using the victim's
+   address as the sources address, or it can be considered an attack
+   against the network.  Since the chunks, which need to be sent in
+   response to the received packet, may not fit into one packet, an
+   endpoint supporting bundling on the sending side might send multiple
+   packets.
+
+   Examples of these packets are packets containing a lot of unknown
+   chunks that require an ERROR chunk to be sent, known chunks that
+   initiate the sending of ERROR chunks, packets containing a lot of
+   HEARTBEAT chunks, and so on.
+
+
+
+
+Stewart, et al.              Informational                     [Page 10]
+
+RFC 5062                 SCTP Security Attacks            September 2007
+
+
+8.2.  Analysis
+
+   This attack depends on the fact that the SCTP endpoint does not
+   support bundling on the sending side or provides a bad implementation
+   of bundling on the sending side.
+
+8.3.  Mitigation Option
+
+   First of all, path verification must happen before sending chunks
+   other than HEARTBEATs for path verification.  This ensures that the
+   above attack cannot be used against other hosts.  To avoid the
+   attack, an SCTP endpoint should implement bundling on the sending
+   side and should not send multiple packets in response.  If the SCTP
+   endpoint does not support bundling on the sending side, it should not
+   send in general more than one packet in response to a received one.
+   The details of the required handling are described in [RFC4960].
+
+9.  Bombing Attack (Amplification) 4
+
+   This attack allows an attacker to use an SCTP server to send a larger
+   packet to a victim than it sent to the SCTP server.
+
+9.1.  Attack Details
+
+   The attacker sends packets using the victim's address as the source
+   address containing an INIT chunk to an SCTP Server.  The server then
+   sends a packet containing an INIT-ACK chunk to the victim, which is
+   most likely larger than the packet containing the INIT.
+
+9.2.  Analysis
+
+   This attack is a byte and not a packet amplification attack and,
+   without protocol changes, is hard to avoid.  A possible method to
+   avoid this attack would be the usage the PAD parameter defined in
+   [RFC4820].
+
+9.3.  Mitigation Option
+
+   A server should be implemented in a way that the generated INIT-ACK
+   chunks are as small as possible.
+
+10.  Bombing Attack (amplification) 5
+
+   This attack allows an attacker to use an SCTP endpoint to send a
+   large number of packets in response to one packet.
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 11]
+
+RFC 5062                 SCTP Security Attacks            September 2007
+
+
+10.1.  Attack Details
+
+   The attacker sends a packet to an SCTP endpoint, which requires the
+   sending of multiple chunks.  If the MTU towards the attacker is
+   smaller than the MTU towards the victim, the victim might need to
+   send more than one packet to send all the chunks.  The difference
+   between the MTUs might be extremely large if the attacker sends
+   malicious ICMP packets to make use of the path MTU discovery.
+
+10.2.  Analysis
+
+   This attack depends on the fact that an SCTP implementation might not
+   limit the number of response packets correctly.
+
+10.3.  Mitigation Option
+
+   First of all, path verification must happen before sending chunks
+   other than HEARTBEATs for path verification.  This makes sure that
+   the above attack cannot be used against other hosts.  To avoid the
+   attack, an SCTP endpoint should not send multiple packets in response
+   to a single packet.  The chunks not fitting in this packet should be
+   dropped.
+
+11.  Security Considerations
+
+   This document is about security; as such, there are no additional
+   security considerations.
+
+12.  References
+
+12.1.  Normative References
+
+   [RFC2960]  Stewart, R., Xie, Q., Morneault, K., Sharp, C.,
+              Schwarzbauer, H., Taylor, T., Rytina, I., Kalla, M.,
+              Zhang, L., and V. Paxson, "Stream Control Transmission
+              Protocol", RFC 2960, October 2000.
+
+   [RFC4460]  Stewart, R., Arias-Rodriguez, I., Poon, K., Caro, A., and
+              M. Tuexen, "Stream Control Transmission Protocol (SCTP)
+              Specification Errata and Issues", RFC 4460, April 2006.
+
+   [RFC4820]  Tuexen, M., Stewart, R., and P. Lei, "Padding Chunk and
+              Parameter for the Stream Control Transmission Protocol
+              (SCTP)", RFC 4820, March 2007.
+
+   [RFC4895]  Tuexen, M., Stewart, R., Lei, P., and E. Rescorla,
+              "Authenticated Chunks for Stream Control Transmission
+              Protocol (SCTP)", RFC 4895, August 2007.
+
+
+
+Stewart, et al.              Informational                     [Page 12]
+
+RFC 5062                 SCTP Security Attacks            September 2007
+
+
+   [RFC5061]  Stewart, R., Xie, Q., Tuexen, M., Maruyama, S., and M.
+              Kozuka, "Stream Control Transmission Protocol (SCTP)
+              Dynamic Address Reconfiguration", RFC 5061,
+              September 2007.
+
+   [RFC4960]  Stewart, R., Ed., "Stream Control Transmission Protocol",
+              RFC 4960, June 2007.
+
+12.2.  Informative References
+
+   [EFFECTS]  Aura, T., Nikander, P., and G. Camarillo, "Effects of
+              Mobility and Multihoming on Transport-Layer Security",
+              Security and Privacy 2004, IEEE Symposium , URL http://
+              research.microsoft.com/users/tuomaura/Publications/
+              aura-nikander-camarillo-ssp04.pdf, May 2004.
+
+Authors' Addresses
+
+   Randall R. Stewart
+   Cisco Systems, Inc.
+   4785 Forest Drive
+   Suite 200
+   Columbia, SC  29206
+   USA
+
+   EMail: rrs@cisco.com
+
+
+   Michael Tuexen
+   Muenster Univ. of Applied Sciences
+   Stegerwaldstr. 39
+   48565 Steinfurt
+   Germany
+
+   EMail: tuexen@fh-muenster.de
+
+
+   Gonzalo Camarillo
+   Ericsson
+   Hirsalantie 11
+   Jorvas  02420
+   Finland
+
+   EMail: Gonzalo.Camarillo@ericsson.com
+
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 13]
+
+RFC 5062                 SCTP Security Attacks            September 2007
+
+
+Full Copyright Statement
+
+   Copyright (C) The IETF Trust (2007).
+
+   This document is subject to the rights, licenses and restrictions
+   contained in BCP 78, and except as set forth therein, the authors
+   retain all their rights.
+
+   This document and the information contained herein are provided on an
+   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
+   OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND
+   THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
+   THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
+   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Intellectual Property
+
+   The IETF takes no position regarding the validity or scope of any
+   Intellectual Property Rights or other rights that might be claimed to
+   pertain to the implementation or use of the technology described in
+   this document or the extent to which any license under such rights
+   might or might not be available; nor does it represent that it has
+   made any independent effort to identify any such rights.  Information
+   on the procedures with respect to rights in RFC documents can be
+   found in BCP 78 and BCP 79.
+
+   Copies of IPR disclosures made to the IETF Secretariat and any
+   assurances of licenses to be made available, or the result of an
+   attempt made to obtain a general license or permission for the use of
+   such proprietary rights by implementers or users of this
+   specification can be obtained from the IETF on-line IPR repository at
+   http://www.ietf.org/ipr.
+
+   The IETF invites any interested party to bring to its attention any
+   copyrights, patents or patent applications, or other proprietary
+   rights that may cover technology that may be required to implement
+   this standard.  Please address the information to the IETF at
+   ietf-ipr@ietf.org.
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.              Informational                     [Page 14]
+
diff --git a/doc/rfc6458.txt b/doc/rfc6458.txt
new file mode 100644
index 0000000..115a7fd
--- /dev/null
+++ b/doc/rfc6458.txt
@@ -0,0 +1,6443 @@
+
+
+
+
+
+
+Internet Engineering Task Force (IETF)                        R. Stewart
+Request for Comments: 6458                                Adara Networks
+Category: Informational                                        M. Tuexen
+ISSN: 2070-1721                         Muenster Univ. of Appl. Sciences
+                                                                 K. Poon
+                                                      Oracle Corporation
+                                                                  P. Lei
+                                                     Cisco Systems, Inc.
+                                                             V. Yasevich
+                                                                      HP
+                                                           December 2011
+
+
+                         Sockets API Extensions
+          for the Stream Control Transmission Protocol (SCTP)
+
+Abstract
+
+   This document describes a mapping of the Stream Control Transmission
+   Protocol (SCTP) into a sockets API.  The benefits of this mapping
+   include compatibility for TCP applications, access to new SCTP
+   features, and a consolidated error and event notification scheme.
+
+Status of This Memo
+
+   This document is not an Internet Standards Track specification; it is
+   published for informational purposes.
+
+   This document is a product of the Internet Engineering Task Force
+   (IETF).  It represents the consensus of the IETF community.  It has
+   received public review and has been approved for publication by the
+   Internet Engineering Steering Group (IESG).  Not all documents
+   approved by the IESG are a candidate for any level of Internet
+   Standard; see Section 2 of RFC 5741.
+
+   Information about the current status of this document, any errata,
+   and how to provide feedback on it may be obtained at
+   http://www.rfc-editor.org/info/rfc6458.
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.               Informational                     [Page 1]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+Copyright Notice
+
+   Copyright (c) 2011 IETF Trust and the persons identified as the
+   document authors.  All rights reserved.
+
+   This document is subject to BCP 78 and the IETF Trust's Legal
+   Provisions Relating to IETF Documents
+   (http://trustee.ietf.org/license-info) in effect on the date of
+   publication of this document.  Please review these documents
+   carefully, as they describe your rights and restrictions with respect
+   to this document.  Code Components extracted from this document must
+   include Simplified BSD License text as described in Section 4.e of
+   the Trust Legal Provisions and are provided without warranty as
+   described in the Simplified BSD License.
+
+   This document may contain material from IETF Documents or IETF
+   Contributions published or made publicly available before November
+   10, 2008.  The person(s) controlling the copyright in some of this
+   material may not have granted the IETF Trust the right to allow
+   modifications of such material outside the IETF Standards Process.
+   Without obtaining an adequate license from the person(s) controlling
+   the copyright in such materials, this document may not be modified
+   outside the IETF Standards Process, and derivative works of it may
+   not be created outside the IETF Standards Process, except to format
+   it for publication as an RFC or to translate it into languages other
+   than English.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.               Informational                     [Page 2]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+Table of Contents
+
+   1. Introduction ....................................................6
+   2. Data Types ......................................................8
+   3. One-to-Many Style Interface .....................................8
+      3.1. Basic Operation ............................................8
+           3.1.1. socket() ............................................9
+           3.1.2. bind() .............................................10
+           3.1.3. listen() ...........................................11
+           3.1.4. sendmsg() and recvmsg() ............................12
+           3.1.5. close() ............................................14
+           3.1.6. connect() ..........................................14
+      3.2. Non-Blocking Mode .........................................15
+      3.3. Special Considerations ....................................16
+   4. One-to-One Style Interface .....................................18
+      4.1. Basic Operation ...........................................18
+           4.1.1. socket() ...........................................19
+           4.1.2. bind() .............................................19
+           4.1.3. listen() ...........................................21
+           4.1.4. accept() ...........................................21
+           4.1.5. connect() ..........................................22
+           4.1.6. close() ............................................23
+           4.1.7. shutdown() .........................................23
+           4.1.8. sendmsg() and recvmsg() ............................24
+           4.1.9. getpeername() ......................................24
+   5. Data Structures ................................................25
+      5.1. The msghdr and cmsghdr Structures .........................25
+      5.2. Ancillary Data Considerations and Semantics ...............26
+           5.2.1. Multiple Items and Ordering ........................27
+           5.2.2. Accessing and Manipulating Ancillary Data ..........27
+           5.2.3. Control Message Buffer Sizing ......................28
+      5.3. SCTP msg_control Structures ...............................28
+           5.3.1. SCTP Initiation Structure (SCTP_INIT) ..............29
+           5.3.2. SCTP Header Information Structure
+                  (SCTP_SNDRCV) - DEPRECATED .........................30
+           5.3.3. Extended SCTP Header Information Structure
+                  (SCTP_EXTRCV) - DEPRECATED .........................33
+           5.3.4. SCTP Send Information Structure (SCTP_SNDINFO) .....35
+           5.3.5. SCTP Receive Information Structure (SCTP_RCVINFO) ..37
+           5.3.6. SCTP Next Receive Information Structure
+                  (SCTP_NXTINFO) .....................................38
+           5.3.7. SCTP PR-SCTP Information Structure (SCTP_PRINFO) ...39
+           5.3.8. SCTP AUTH Information Structure (SCTP_AUTHINFO) ....40
+           5.3.9. SCTP Destination IPv4 Address Structure
+                  (SCTP_DSTADDRV4) ...................................41
+           5.3.10. SCTP Destination IPv6 Address Structure
+                   (SCTP_DSTADDRV6) ..................................41
+
+
+
+
+Stewart, et al.               Informational                     [Page 3]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   6. SCTP Events and Notifications ..................................41
+      6.1. SCTP Notification Structure ...............................42
+           6.1.1. SCTP_ASSOC_CHANGE ..................................43
+           6.1.2. SCTP_PEER_ADDR_CHANGE ..............................45
+           6.1.3. SCTP_REMOTE_ERROR ..................................46
+           6.1.4. SCTP_SEND_FAILED - DEPRECATED ......................47
+           6.1.5. SCTP_SHUTDOWN_EVENT ................................48
+           6.1.6. SCTP_ADAPTATION_INDICATION .........................49
+           6.1.7. SCTP_PARTIAL_DELIVERY_EVENT ........................49
+           6.1.8. SCTP_AUTHENTICATION_EVENT ..........................50
+           6.1.9. SCTP_SENDER_DRY_EVENT ..............................51
+           6.1.10. SCTP_NOTIFICATIONS_STOPPED_EVENT ..................52
+           6.1.11. SCTP_SEND_FAILED_EVENT ............................52
+      6.2. Notification Interest Options .............................54
+           6.2.1. SCTP_EVENTS Option - DEPRECATED ....................54
+           6.2.2. SCTP_EVENT Option ..................................56
+   7. Common Operations for Both Styles ..............................57
+      7.1. send(), recv(), sendto(), and recvfrom() ..................57
+      7.2. setsockopt() and getsockopt() .............................59
+      7.3. read() and write() ........................................60
+      7.4. getsockname() .............................................60
+      7.5. Implicit Association Setup ................................61
+   8. Socket Options .................................................61
+      8.1. Read/Write Options ........................................63
+           8.1.1. Retransmission Timeout Parameters (SCTP_RTOINFO) ...63
+           8.1.2. Association Parameters (SCTP_ASSOCINFO) ............64
+           8.1.3. Initialization Parameters (SCTP_INITMSG) ...........66
+           8.1.4. SO_LINGER ..........................................66
+           8.1.5. SCTP_NODELAY .......................................66
+           8.1.6. SO_RCVBUF ..........................................67
+           8.1.7. SO_SNDBUF ..........................................67
+           8.1.8. Automatic Close of Associations (SCTP_AUTOCLOSE) ...67
+           8.1.9. Set Primary Address (SCTP_PRIMARY_ADDR) ............68
+           8.1.10. Set Adaptation Layer Indicator
+                   (SCTP_ADAPTATION_LAYER) ...........................68
+           8.1.11. Enable/Disable Message Fragmentation
+                   (SCTP_DISABLE_FRAGMENTS) ..........................68
+           8.1.12. Peer Address Parameters (SCTP_PEER_ADDR_PARAMS) ...69
+           8.1.13. Set Default Send Parameters
+                   (SCTP_DEFAULT_SEND_PARAM) - DEPRECATED ............71
+           8.1.14. Set Notification and Ancillary Events
+                   (SCTP_EVENTS) - DEPRECATED ........................72
+           8.1.15. Set/Clear IPv4 Mapped Addresses
+                   (SCTP_I_WANT_MAPPED_V4_ADDR) ......................72
+           8.1.16. Get or Set the Maximum Fragmentation Size
+                   (SCTP_MAXSEG) .....................................72
+           8.1.17. Get or Set the List of Supported HMAC
+                   Identifiers (SCTP_HMAC_IDENT) .....................73
+
+
+
+Stewart, et al.               Informational                     [Page 4]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+           8.1.18. Get or Set the Active Shared Key
+                   (SCTP_AUTH_ACTIVE_KEY) ............................74
+           8.1.19. Get or Set Delayed SACK Timer
+                   (SCTP_DELAYED_SACK) ...............................74
+           8.1.20. Get or Set Fragmented Interleave
+                   (SCTP_FRAGMENT_INTERLEAVE) ........................75
+           8.1.21. Set or Get the SCTP Partial Delivery Point
+                   (SCTP_PARTIAL_DELIVERY_POINT) .....................77
+           8.1.22. Set or Get the Use of Extended Receive Info
+                   (SCTP_USE_EXT_RCVINFO) - DEPRECATED ...............77
+           8.1.23. Set or Get the Auto ASCONF Flag
+                   (SCTP_AUTO_ASCONF) ................................77
+           8.1.24. Set or Get the Maximum Burst (SCTP_MAX_BURST) .....78
+           8.1.25. Set or Get the Default Context (SCTP_CONTEXT) .....78
+           8.1.26. Enable or Disable Explicit EOR Marking
+                   (SCTP_EXPLICIT_EOR) ...............................79
+           8.1.27. Enable SCTP Port Reusage (SCTP_REUSE_PORT) ........79
+           8.1.28. Set Notification Event (SCTP_EVENT) ...............79
+           8.1.29. Enable or Disable the Delivery of SCTP_RCVINFO
+                   as Ancillary Data (SCTP_RECVRCVINFO) ..............79
+           8.1.30. Enable or Disable the Delivery of SCTP_NXTINFO
+                   as Ancillary Data (SCTP_RECVNXTINFO) ..............80
+           8.1.31. Set Default Send Parameters
+                   (SCTP_DEFAULT_SNDINFO) ............................80
+           8.1.32. Set Default PR-SCTP Parameters
+                   (SCTP_DEFAULT_PRINFO) .............................80
+      8.2. Read-Only Options .........................................81
+           8.2.1. Association Status (SCTP_STATUS) ...................81
+           8.2.2. Peer Address Information
+                  (SCTP_GET_PEER_ADDR_INFO) ..........................82
+           8.2.3. Get the List of Chunks the Peer Requires to
+                  Be Authenticated (SCTP_PEER_AUTH_CHUNKS) ...........84
+           8.2.4. Get the List of Chunks the Local Endpoint Requires
+                  to Be Authenticated (SCTP_LOCAL_AUTH_CHUNKS) .......84
+           8.2.5. Get the Current Number of Associations
+                  (SCTP_GET_ASSOC_NUMBER) ............................85
+           8.2.6. Get the Current Identifiers of Associations
+                  (SCTP_GET_ASSOC_ID_LIST) ...........................85
+      8.3. Write-Only Options ........................................85
+           8.3.1. Set Peer Primary Address
+                  (SCTP_SET_PEER_PRIMARY_ADDR) .......................86
+           8.3.2. Add a Chunk That Must Be Authenticated
+                  (SCTP_AUTH_CHUNK) ..................................86
+           8.3.3. Set a Shared Key (SCTP_AUTH_KEY) ...................86
+           8.3.4. Deactivate a Shared Key
+                  (SCTP_AUTH_DEACTIVATE_KEY) .........................87
+           8.3.5. Delete a Shared Key (SCTP_AUTH_DELETE_KEY) .........88
+
+
+
+
+Stewart, et al.               Informational                     [Page 5]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   9. New Functions ..................................................88
+      9.1. sctp_bindx() ..............................................88
+      9.2. sctp_peeloff() ............................................90
+      9.3. sctp_getpaddrs() ..........................................91
+      9.4. sctp_freepaddrs() .........................................92
+      9.5. sctp_getladdrs() ..........................................92
+      9.6. sctp_freeladdrs() .........................................93
+      9.7. sctp_sendmsg() - DEPRECATED ...............................93
+      9.8. sctp_recvmsg() - DEPRECATED ...............................94
+      9.9. sctp_connectx() ...........................................95
+      9.10. sctp_send() - DEPRECATED .................................96
+      9.11. sctp_sendx() - DEPRECATED ................................97
+      9.12. sctp_sendv() .............................................98
+      9.13. sctp_recvv() ............................................101
+   10. Security Considerations ......................................103
+   11. Acknowledgments ..............................................103
+   12. References ...................................................104
+      12.1. Normative References ....................................104
+      12.2. Informative References ..................................104
+   Appendix A. Example Using One-to-One Style Sockets ...............106
+   Appendix B. Example Using One-to-Many Style Sockets ..............109
+
+1.  Introduction
+
+   The sockets API has provided a standard mapping of the Internet
+   Protocol suite to many operating systems.  Both TCP [RFC0793] and UDP
+   [RFC0768] have benefited from this standard representation and access
+   method across many diverse platforms.  SCTP is a new protocol that
+   provides many of the characteristics of TCP but also incorporates
+   semantics more akin to UDP.  This document defines a method to map
+   the existing sockets API for use with SCTP, providing both a base for
+   access to new features and compatibility so that most existing TCP
+   applications can be migrated to SCTP with few (if any) changes.
+
+   There are three basic design objectives:
+
+   1.  Maintain consistency with existing sockets APIs: We define a
+       sockets mapping for SCTP that is consistent with other sockets
+       API protocol mappings (for instance UDP, TCP, IPv4, and IPv6).
+
+   2.  Support a one-to-many style interface: This set of semantics is
+       similar to that defined for connectionless protocols, such as
+       UDP.  A one-to-many style SCTP socket should be able to control
+       multiple SCTP associations.  This is similar to a UDP socket,
+       which can communicate with many peer endpoints.  Each of these
+       associations is assigned an association identifier so that an
+
+
+
+
+
+Stewart, et al.               Informational                     [Page 6]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+       application can use the ID to differentiate them.  Note that SCTP
+       is connection-oriented in nature, and it does not support
+       broadcast or multicast communications, as UDP does.
+
+   3.  Support a one-to-one style interface: This interface supports a
+       similar semantics as sockets for connection-oriented protocols,
+       such as TCP.  A one-to-one style SCTP socket should only control
+       one SCTP association.  One purpose of defining this interface is
+       to allow existing applications built on other connection-oriented
+       protocols to be ported to use SCTP with very little effort.
+       Developers familiar with these semantics can easily adapt to
+       SCTP.  Another purpose is to make sure that existing mechanisms
+       in most operating systems that support sockets, such as select(),
+       should continue to work with this style of socket.  Extensions
+       are added to this mapping to provide mechanisms to exploit new
+       features of SCTP.
+
+   Goals 2 and 3 are not compatible, so this document defines two modes
+   of mapping, namely the one-to-many style mapping and the one-to-one
+   style mapping.  These two modes share some common data structures and
+   operations, but will require the use of two different application
+   programming styles.  Note that all new SCTP features can be used with
+   both styles of socket.  The decision on which one to use depends
+   mainly on the nature of the applications.
+
+   A mechanism is defined to extract an SCTP association from a one-to-
+   many style socket into a one-to-one style socket.
+
+   Some of the SCTP mechanisms cannot be adequately mapped to an
+   existing socket interface.  In some cases, it is more desirable to
+   have a new interface instead of using existing socket calls.
+   Section 9 of this document describes these new interfaces.
+
+   Please note that some elements of the SCTP sockets API are declared
+   as deprecated.  During the evolution of this document, elements of
+   the API were introduced, implemented, and later on replaced by other
+   elements.  These replaced elements are declared as deprecated, since
+   they are still available in some implementations and the replacement
+   functions are not.  This applies especially to older versions of
+   operating systems supporting SCTP.  New SCTP socket implementations
+   must implement at least the non-deprecated elements.  Implementations
+   intending interoperability with older versions of the API should also
+   include the deprecated functions.
+
+
+
+
+
+
+
+
+Stewart, et al.               Informational                     [Page 7]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+2.  Data Types
+
+   Whenever possible, Portable Operating System Interface (POSIX) data
+   types defined in [IEEE-1003.1-2008] are used: uintN_t means an
+   unsigned integer of exactly N bits (e.g., uint16_t).  This document
+   also assumes the argument data types from POSIX when possible (e.g.,
+   the final argument to setsockopt() is a socklen_t value).  Whenever
+   buffer sizes are specified, the POSIX size_t data type is used.
+
+3.  One-to-Many Style Interface
+
+   In the one-to-many style interface, there is a one-to-many
+   relationship between sockets and associations.
+
+3.1.  Basic Operation
+
+   A typical server in this style uses the following socket calls in
+   sequence to prepare an endpoint for servicing requests:
+
+   o  socket()
+
+   o  bind()
+
+   o  listen()
+
+   o  recvmsg()
+
+   o  sendmsg()
+
+   o  close()
+
+   A typical client uses the following calls in sequence to set up an
+   association with a server to request services:
+
+   o  socket()
+
+   o  sendmsg()
+
+   o  recvmsg()
+
+   o  close()
+
+   In this style, by default, all of the associations connected to the
+   endpoint are represented with a single socket.  Each association is
+   assigned an association identifier (the type is sctp_assoc_t) so that
+   an application can use it to differentiate among them.  In some
+   implementations, the peer endpoints' addresses can also be used for
+   this purpose.  But this is not required for performance reasons.  If
+
+
+
+Stewart, et al.               Informational                     [Page 8]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   an implementation does not support using addresses to differentiate
+   between different associations, the sendto() call can only be used to
+   set up an association implicitly.  It cannot be used to send data to
+   an established association, as the association identifier cannot be
+   specified.
+
+   Once an association identifier is assigned to an SCTP association,
+   that identifier will not be reused until the application explicitly
+   terminates the use of the association.  The resources belonging to
+   that association will not be freed until that happens.  This is
+   similar to the close() operation on a normal socket.  The only
+   exception is when the SCTP_AUTOCLOSE option (Section 8.1.8) is set.
+   In this case, after the association is terminated gracefully and
+   automatically, the association identifier assigned to it can be
+   reused.  All applications using this option should be aware of this
+   to avoid the possible problem of sending data to an incorrect peer
+   endpoint.
+
+   If the server or client wishes to branch an existing association off
+   to a separate socket, it is required to call sctp_peeloff() and to
+   specify the association identifier.  The sctp_peeloff() call will
+   return a new one-to-one style socket that can then be used with
+   recv() and send() functions for message passing.  See Section 9.2 for
+   more on branched-off associations.
+
+   Once an association is branched off to a separate socket, it becomes
+   completely separated from the original socket.  All subsequent
+   control and data operations to that association must be done through
+   the new socket.  For example, the close() operation on the original
+   socket will not terminate any associations that have been branched
+   off to a different socket.
+
+   One-to-many style socket calls are discussed in more detail in the
+   following subsections.
+
+3.1.1.  socket()
+
+   Applications use socket() to create a socket descriptor to represent
+   an SCTP endpoint.
+
+   The function prototype is
+
+   int socket(int domain,
+              int type,
+              int protocol);
+
+   and one uses PF_INET or PF_INET6 as the domain, SOCK_SEQPACKET as the
+   type, and IPPROTO_SCTP as the protocol.
+
+
+
+Stewart, et al.               Informational                     [Page 9]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   Here, SOCK_SEQPACKET indicates the creation of a one-to-many style
+   socket.
+
+   The function returns a socket descriptor, or -1 in case of an error.
+
+   Using the PF_INET domain indicates the creation of an endpoint that
+   can use only IPv4 addresses, while PF_INET6 creates an endpoint that
+   can use both IPv6 and IPv4 addresses.
+
+3.1.2.  bind()
+
+   Applications use bind() to specify with which local address and port
+   the SCTP endpoint should associate itself.
+
+   An SCTP endpoint can be associated with multiple addresses.  To do
+   this, sctp_bindx() is introduced in Section 9.1 to help applications
+   do the job of associating multiple addresses.  But note that an
+   endpoint can only be associated with one local port.
+
+   These addresses associated with a socket are the eligible transport
+   addresses for the endpoint to send and receive data.  The endpoint
+   will also present these addresses to its peers during the association
+   initialization process; see [RFC4960].
+
+   After calling bind(), if the endpoint wishes to accept new
+   associations on the socket, it must call listen() (see
+   Section 3.1.3).
+
+   The function prototype of bind() is
+
+   int bind(int sd,
+            struct sockaddr *addr,
+            socklen_t addrlen);
+
+   and the arguments are
+
+   sd:  The socket descriptor returned by socket().
+
+   addr:  The address structure (struct sockaddr_in for an IPv4 address
+      or struct sockaddr_in6 for an IPv6 address; see [RFC3493]).
+
+   addrlen:  The size of the address structure.
+
+   bind() returns 0 on success and -1 in case of an error.
+
+   If sd is an IPv4 socket, the address passed must be an IPv4 address.
+   If the sd is an IPv6 socket, the address passed can either be an IPv4
+   or an IPv6 address.
+
+
+
+Stewart, et al.               Informational                    [Page 10]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   Applications cannot call bind() multiple times to associate multiple
+   addresses to an endpoint.  After the first call to bind(), all
+   subsequent calls will return an error.
+
+   If the IP address part of addr is specified as a wildcard (INADDR_ANY
+   for an IPv4 address, or as IN6ADDR_ANY_INIT or in6addr_any for an
+   IPv6 address), the operating system will associate the endpoint with
+   an optimal address set of the available interfaces.  If the IPv4
+   sin_port or IPv6 sin6_port is set to 0, the operating system will
+   choose an ephemeral port for the endpoint.
+
+   If bind() is not called prior to a sendmsg() call that initiates a
+   new association, the system picks an ephemeral port and will choose
+   an address set equivalent to binding with a wildcard address.  One of
+   those addresses will be the primary address for the association.
+   This automatically enables the multi-homing capability of SCTP.
+
+   The completion of this bind() process does not allow the SCTP
+   endpoint to accept inbound SCTP association requests.  Until a
+   listen() system call, described below, is performed on the socket,
+   the SCTP endpoint will promptly reject an inbound SCTP INIT request
+   with an SCTP ABORT.
+
+3.1.3.  listen()
+
+   By default, a one-to-many style socket does not accept new
+   association requests.  An application uses listen() to mark a socket
+   as being able to accept new associations.
+
+   The function prototype is
+
+   int listen(int sd,
+              int backlog);
+
+   and the arguments are
+
+   sd:  The socket descriptor of the endpoint.
+
+   backlog:  If backlog is non-zero, enable listening, else disable
+      listening.
+
+   listen() returns 0 on success and -1 in case of an error.
+
+   Note that one-to-many style socket consumers do not need to call
+   accept() to retrieve new associations.  Calling accept() on a one-to-
+   many style socket should return EOPNOTSUPP.  Rather, new associations
+   are accepted automatically, and notifications of the new associations
+   are delivered via recvmsg() with the SCTP_ASSOC_CHANGE event (if
+
+
+
+Stewart, et al.               Informational                    [Page 11]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   these notifications are enabled).  Clients will typically not call
+   listen(), so that they can be assured that only actively initiated
+   associations are possible on the socket.  Server or peer-to-peer
+   sockets, on the other hand, will always accept new associations, so a
+   well-written application using server one-to-many style sockets must
+   be prepared to handle new associations from unwanted peers.
+
+   Also note that the SCTP_ASSOC_CHANGE event provides the association
+   identifier for a new association, so if applications wish to use the
+   association identifier as a parameter to other socket calls, they
+   should ensure that the SCTP_ASSOC_CHANGE event is enabled.
+
+3.1.4.  sendmsg() and recvmsg()
+
+   An application uses the sendmsg() and recvmsg() calls to transmit
+   data to and receive data from its peer.
+
+   The function prototypes are
+
+   ssize_t sendmsg(int sd,
+                   const struct msghdr *message,
+                   int flags);
+
+   and
+
+   ssize_t recvmsg(int sd,
+                   struct msghdr *message,
+                   int flags);
+
+   using the following arguments:
+
+   sd:  The socket descriptor of the endpoint.
+
+   message:  Pointer to the msghdr structure that contains a single user
+      message and possibly some ancillary data.  See Section 5 for a
+      complete description of the data structures.
+
+   flags:  No new flags are defined for SCTP at this level.  See
+      Section 5 for SCTP-specific flags used in the msghdr structure.
+
+   sendmsg() returns the number of bytes accepted by the kernel or -1 in
+   case of an error.  recvmsg() returns the number of bytes received or
+   -1 in case of an error.
+
+
+
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 12]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   As described in Section 5, different types of ancillary data can be
+   sent and received along with user data.  When sending, the ancillary
+   data is used to specify the sent behavior, such as the SCTP stream
+   number to use.  When receiving, the ancillary data is used to
+   describe the received data, such as the SCTP stream sequence number
+   of the message.
+
+   When sending user data with sendmsg(), the msg_name field in the
+   msghdr structure will be filled with one of the transport addresses
+   of the intended receiver.  If there is no existing association
+   between the sender and the intended receiver, the sender's SCTP stack
+   will set up a new association and then send the user data (see
+   Section 7.5 for more on implicit association setup).  If sendmsg() is
+   called with no data and there is no existing association, a new one
+   will be established.  The SCTP_INIT type ancillary data can be used
+   to change some of the parameters used to set up a new association.
+   If sendmsg() is called with NULL data, and there is no existing
+   association but the SCTP_ABORT or SCTP_EOF flags are set as described
+   in Section 5.3.4, then -1 is returned and errno is set to EINVAL.
+   Sending a message using sendmsg() is atomic unless explicit end of
+   record (EOR) marking is enabled on the socket specified by sd (see
+   Section 8.1.26).
+
+   If a peer sends a SHUTDOWN, an SCTP_SHUTDOWN_EVENT notification will
+   be delivered if that notification has been enabled, and no more data
+   can be sent to that association.  Any attempt to send more data will
+   cause sendmsg() to return with an ESHUTDOWN error.  Note that the
+   socket is still open for reading at this point, so it is possible to
+   retrieve notifications.
+
+   When receiving a user message with recvmsg(), the msg_name field in
+   the msghdr structure will be populated with the source transport
+   address of the user data.  The caller of recvmsg() can use this
+   address information to determine to which association the received
+   user message belongs.  Note that if SCTP_ASSOC_CHANGE events are
+   disabled, applications must use the peer transport address provided
+   in the msg_name field by recvmsg() to perform correlation to an
+   association, since they will not have the association identifier.
+
+   If all data in a single message has been delivered, MSG_EOR will be
+   set in the msg_flags field of the msghdr structure (see Section 5.1).
+
+   If the application does not provide enough buffer space to completely
+   receive a data message, MSG_EOR will not be set in msg_flags.
+   Successive reads will consume more of the same message until the
+   entire message has been delivered, and MSG_EOR will be set.
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 13]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   If the SCTP stack is running low on buffers, it may partially deliver
+   a message.  In this case, MSG_EOR will not be set, and more calls to
+   recvmsg() will be necessary to completely consume the message.  Only
+   one message at a time can be partially delivered in any stream.  The
+   socket option SCTP_FRAGMENT_INTERLEAVE controls various aspects of
+   what interlacing of messages occurs for both the one-to-one and the
+   one-to-many style sockets.  Please consult Section 8.1.20 for further
+   details on message delivery options.
+
+3.1.5.  close()
+
+   Applications use close() to perform graceful shutdown (as described
+   in Section 10.1 of [RFC4960]) on all of the associations currently
+   represented by a one-to-many style socket.
+
+   The function prototype is
+
+   int close(int sd);
+
+   and the argument is
+
+   sd:  The socket descriptor of the associations to be closed.
+
+   0 is returned on success and -1 in case of an error.
+
+   To gracefully shut down a specific association represented by the
+   one-to-many style socket, an application should use the sendmsg()
+   call and include the SCTP_EOF flag.  A user may optionally terminate
+   an association non-gracefully by using sendmsg() with the SCTP_ABORT
+   flag set and possibly passing a user-specified abort code in the data
+   field.  Both flags SCTP_EOF and SCTP_ABORT are passed with ancillary
+   data (see Section 5.3.4) in the sendmsg() call.
+
+   If sd in the close() call is a branched-off socket representing only
+   one association, the shutdown is performed on that association only.
+
+3.1.6.  connect()
+
+   An application may use the connect() call in the one-to-many style to
+   initiate an association without sending data.
+
+   The function prototype is
+
+   int connect(int sd,
+               const struct sockaddr *nam,
+               socklen_t len);
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 14]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   and the arguments are
+
+   sd:  The socket descriptor to which a new association is added.
+
+   nam:  The address structure (struct sockaddr_in for an IPv4 address
+      or struct sockaddr_in6 for an IPv6 address; see [RFC3493]).
+
+   len:  The size of the address.
+
+   0 is returned on success and -1 in case of an error.
+
+   Multiple connect() calls can be made on the same socket to create
+   multiple associations.  This is different from the semantics of
+   connect() on a UDP socket.
+
+   Note that SCTP allows data exchange, similar to T/TCP [RFC1644] (made
+   Historic by [RFC6247]), during the association setup phase.  If an
+   application wants to do this, it cannot use the connect() call.
+   Instead, it should use sendto() or sendmsg() to initiate an
+   association.  If it uses sendto() and it wants to change the
+   initialization behavior, it needs to use the SCTP_INITMSG socket
+   option before calling sendto().  Or it can use sendmsg() with
+   SCTP_INIT type ancillary data to initiate an association without
+   calling setsockopt().  Note that the implicit setup is supported for
+   the one-to-many style sockets.
+
+   SCTP does not support half close semantics.  This means that unlike
+   T/TCP, MSG_EOF should not be set in the flags parameter when calling
+   sendto() or sendmsg() when the call is used to initiate a connection.
+   MSG_EOF is not an acceptable flag with an SCTP socket.
+
+3.2.  Non-Blocking Mode
+
+   Some SCTP applications may wish to avoid being blocked when calling a
+   socket interface function.
+
+   Once a bind() call and/or subsequent sctp_bindx() calls are complete
+   on a one-to-many style socket, an application may set the
+   non-blocking option via a fcntl() (such as O_NONBLOCK).  After
+   setting the socket to non-blocking mode, the sendmsg() function
+   returns immediately.  The success or failure of sending the data
+   message (with possible SCTP_INITMSG ancillary data) will be signaled
+   by the SCTP_ASSOC_CHANGE event with SCTP_COMM_UP or
+   SCTP_CANT_START_ASSOC.  If user data could not be sent (due to an
+   SCTP_CANT_START_ASSOC), the sender will also receive an
+   SCTP_SEND_FAILED_EVENT event.  Events can be received by the user
+   calling recvmsg().  A server (having called listen()) is also
+
+
+
+
+Stewart, et al.               Informational                    [Page 15]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   notified of an association-up event via the reception of an
+   SCTP_ASSOC_CHANGE with SCTP_COMM_UP via the calling of recvmsg() and
+   possibly the reception of the first data message.
+
+   To shut down the association gracefully, the user must call sendmsg()
+   with no data and with the SCTP_EOF flag set as described in
+   Section 5.3.4.  The function returns immediately, and completion of
+   the graceful shutdown is indicated by an SCTP_ASSOC_CHANGE
+   notification of type SCTP_SHUTDOWN_COMP (see Section 6.1.1).  Note
+   that this can also be done using the sctp_sendv() call described in
+   Section 9.12.
+
+   It is recommended that an application use caution when using select()
+   (or poll()) for writing on a one-to-many style socket, because the
+   interpretation of select() on write is implementation specific.
+   Generally, a positive return on a select() on write would only
+   indicate that one of the associations represented by the one-to-many
+   style socket is writable.  An application that writes after the
+   select() returns may still block, since the association that was
+   writable is not the destination association of the write call.
+   Likewise, select() (or poll()) for reading from a one-to-many style
+   socket will only return an indication that one of the associations
+   represented by the socket has data to be read.
+
+   An application that wishes to know that a particular association is
+   ready for reading or writing should either use the one-to-one style
+   or use the sctp_peeloff() function (see Section 9.2) to separate the
+   association of interest from the one-to-many style socket.
+
+   Note that some implementations may have an extended select call, such
+   as epoll or kqueue, that may escape this limitation and allow a
+   select on a specific association of a one-to-many style socket, but
+   this is an implementation-specific detail that a portable application
+   cannot depend on.
+
+3.3.  Special Considerations
+
+   The fact that a one-to-many style socket can provide access to many
+   SCTP associations through a single socket descriptor has important
+   implications for both application programmers and system programmers
+   implementing this API.  A key issue is how buffer space inside the
+   sockets layer is managed.  Because this implementation detail
+   directly affects how application programmers must write their code to
+   ensure correct operation and portability, this section provides some
+   guidance to both implementers and application programmers.
+
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 16]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   An important feature that SCTP shares with TCP is flow control.
+   Specifically, a sender may not send data faster than the receiver can
+   consume it.
+
+   For TCP, flow control is typically provided for in the sockets API as
+   follows.  If the reader stops reading, the sender queues messages in
+   the socket layer until the send socket buffer is completely filled.
+   This results in a "stalled connection".  Further attempts to write to
+   the socket will block or return the error EAGAIN or EWOULDBLOCK for a
+   non-blocking socket.  At some point, either the connection is closed,
+   or the receiver begins to read, again freeing space in the output
+   queue.
+
+   For one-to-one style SCTP sockets (this includes sockets descriptors
+   that were separated from a one-to-many style socket with
+   sctp_peeloff()), the behavior is identical.  For one-to-many style
+   SCTP sockets, there are multiple associations for a single socket,
+   which makes the situation more complicated.  If the implementation
+   uses a single buffer space allocation shared by all associations, a
+   single stalled association can prevent the further sending of data on
+   all associations active on a particular one-to-many style socket.
+
+   For a blocking socket, it should be clear that a single stalled
+   association can block the entire socket.  For this reason,
+   application programmers may want to use non-blocking one-to-many
+   style sockets.  The application should at least be able to send
+   messages to the non-stalled associations.
+
+   But a non-blocking socket is not sufficient if the API implementer
+   has chosen a single shared buffer allocation for the socket.  A
+   single stalled association would eventually cause the shared
+   allocation to fill, and it would become impossible to send even to
+   non-stalled associations.
+
+   The API implementer can solve this problem by providing each
+   association with its own allocation of outbound buffer space.  Each
+   association should conceptually have as much buffer space as it would
+   have if it had its own socket.  As a bonus, this simplifies the
+   implementation of sctp_peeloff().
+
+   To ensure that a given stalled association will not prevent other
+   non-stalled associations from being writable, application programmers
+   should either
+
+   o  demand that the underlying implementation dedicates independent
+      buffer space reservation to each association (as suggested
+      above), or
+
+
+
+
+Stewart, et al.               Informational                    [Page 17]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   o  verify that their application-layer protocol does not permit large
+      amounts of unread data at the receiver (this is true of some
+      request-response protocols, for example), or
+
+   o  use one-to-one style sockets for association, which may
+      potentially stall (either from the beginning, or by using
+      sctp_peeloff() before sending large amounts of data that may cause
+      a stalled condition).
+
+4.  One-to-One Style Interface
+
+   The goal of this style is to follow as closely as possible the
+   current practice of using the sockets interface for a connection-
+   oriented protocol such as TCP.  This style enables existing
+   applications using connection-oriented protocols to be ported to SCTP
+   with very little effort.
+
+   One-to-one style sockets can be connected (explicitly or implicitly)
+   at most once, similar to TCP sockets.
+
+   Note that some new SCTP features and some new SCTP socket options can
+   only be utilized through the use of sendmsg() and recvmsg() calls;
+   see Section 4.1.8.
+
+4.1.  Basic Operation
+
+   A typical one-to-one style server uses the following system call
+   sequence to prepare an SCTP endpoint for servicing requests:
+
+   o  socket()
+
+   o  bind()
+
+   o  listen()
+
+   o  accept()
+
+   The accept() call blocks until a new association is set up.  It
+   returns with a new socket descriptor.  The server then uses the new
+   socket descriptor to communicate with the client, using recv() and
+   send() calls to get requests and send back responses.
+
+   Then it calls
+
+   o  close()
+
+   to terminate the association.
+
+
+
+
+Stewart, et al.               Informational                    [Page 18]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   A typical client uses the following system call sequence to set up an
+   association with a server to request services:
+
+   o  socket()
+
+   o  connect()
+
+   After returning from the connect() call, the client uses send()/
+   sendmsg() and recv()/recvmsg() calls to send out requests and receive
+   responses from the server.
+
+   The client calls
+
+   o  close()
+
+   to terminate this association when done.
+
+4.1.1.  socket()
+
+   Applications call socket() to create a socket descriptor to represent
+   an SCTP endpoint.
+
+   The function prototype is
+
+   int socket(int domain,
+              int type,
+              int protocol);
+
+   and one uses PF_INET or PF_INET6 as the domain, SOCK_STREAM as the
+   type, and IPPROTO_SCTP as the protocol.
+
+   Here, SOCK_STREAM indicates the creation of a one-to-one style
+   socket.
+
+   Using the PF_INET domain indicates the creation of an endpoint that
+   can use only IPv4 addresses, while PF_INET6 creates an endpoint that
+   can use both IPv6 and IPv4 addresses.
+
+4.1.2.  bind()
+
+   Applications use bind() to specify with which local address and port
+   the SCTP endpoint should associate itself.
+
+   An SCTP endpoint can be associated with multiple addresses.  To do
+   this, sctp_bindx() is introduced in Section 9.1 to help applications
+   do the job of associating multiple addresses.  But note that an
+   endpoint can only be associated with one local port.
+
+
+
+
+Stewart, et al.               Informational                    [Page 19]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   These addresses associated with a socket are the eligible transport
+   addresses for the endpoint to send and receive data.  The endpoint
+   will also present these addresses to its peers during the association
+   initialization process; see [RFC4960].
+
+   The function prototype of bind() is
+
+   int bind(int sd,
+            struct sockaddr *addr,
+            socklen_t addrlen);
+
+   and the arguments are
+
+   sd:  The socket descriptor returned by socket().
+
+   addr:  The address structure (struct sockaddr_in for an IPv4 address
+      or struct sockaddr_in6 for an IPv6 address; see [RFC3493]).
+
+   addrlen:  The size of the address structure.
+
+   If sd is an IPv4 socket, the address passed must be an IPv4 address.
+   If sd is an IPv6 socket, the address passed can either be an IPv4 or
+   an IPv6 address.
+
+   Applications cannot call bind() multiple times to associate multiple
+   addresses to the endpoint.  After the first call to bind(), all
+   subsequent calls will return an error.
+
+   If the IP address part of addr is specified as a wildcard (INADDR_ANY
+   for an IPv4 address, or as IN6ADDR_ANY_INIT or in6addr_any for an
+   IPv6 address), the operating system will associate the endpoint with
+   an optimal address set of the available interfaces.  If the IPv4
+   sin_port or IPv6 sin6_port is set to 0, the operating system will
+   choose an ephemeral port for the endpoint.
+
+   If bind() is not called prior to the connect() call, the system picks
+   an ephemeral port and will choose an address set equivalent to
+   binding with a wildcard address.  One of these addresses will be the
+   primary address for the association.  This automatically enables the
+   multi-homing capability of SCTP.
+
+   The completion of this bind() process does not allow the SCTP
+   endpoint to accept inbound SCTP association requests.  Until a
+   listen() system call, described below, is performed on the socket,
+   the SCTP endpoint will promptly reject an inbound SCTP INIT request
+   with an SCTP ABORT.
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 20]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+4.1.3.  listen()
+
+   Applications use listen() to allow the SCTP endpoint to accept
+   inbound associations.
+
+   The function prototype is
+
+   int listen(int sd,
+              int backlog);
+
+   and the arguments are
+
+   sd:  The socket descriptor of the SCTP endpoint.
+
+   backlog:  Specifies the max number of outstanding associations
+      allowed in the socket's accept queue.  These are the associations
+      that have finished the four-way initiation handshake (see
+      Section 5 of [RFC4960]) and are in the ESTABLISHED state.  Note
+      that a backlog of '0' indicates that the caller no longer wishes
+      to receive new associations.
+
+   listen() returns 0 on success and -1 in case of an error.
+
+4.1.4.  accept()
+
+   Applications use the accept() call to remove an established SCTP
+   association from the accept queue of the endpoint.  A new socket
+   descriptor will be returned from accept() to represent the newly
+   formed association.
+
+   The function prototype is
+
+   int accept(int sd,
+              struct sockaddr *addr,
+              socklen_t *addrlen);
+
+   and the arguments are
+
+   sd:  The listening socket descriptor.
+
+   addr:  On return, addr (struct sockaddr_in for an IPv4 address or
+      struct sockaddr_in6 for an IPv6 address; see [RFC3493]) will
+      contain the primary address of the peer endpoint.
+
+   addrlen:  On return, addrlen will contain the size of addr.
+
+   The function returns the socket descriptor for the newly formed
+   association on success and -1 in case of an error.
+
+
+
+Stewart, et al.               Informational                    [Page 21]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+4.1.5.  connect()
+
+   Applications use connect() to initiate an association to a peer.
+
+   The function prototype is
+
+   int connect(int sd,
+               const struct sockaddr *addr,
+               socklen_t addrlen);
+
+   and the arguments are
+
+   sd:  The socket descriptor of the endpoint.
+
+   addr:  The peer's (struct sockaddr_in for an IPv4 address or struct
+      sockaddr_in6 for an IPv6 address; see [RFC3493]) address.
+
+   addrlen:  The size of the address.
+
+   connect() returns 0 on success and -1 on error.
+
+   This operation corresponds to the ASSOCIATE primitive described in
+   Section 10.1 of [RFC4960].
+
+   The number of outbound streams the new association has is stack
+   dependent.  Before connecting, applications can use the SCTP_INITMSG
+   option described in Section 8.1.3 to change the number of outbound
+   streams.
+
+   If bind() is not called prior to the connect() call, the system picks
+   an ephemeral port and will choose an address set equivalent to
+   binding with INADDR_ANY and IN6ADDR_ANY_INIT for IPv4 and IPv6
+   sockets, respectively.  One of the addresses will be the primary
+   address for the association.  This automatically enables the
+   multi-homing capability of SCTP.
+
+   Note that SCTP allows data exchange, similar to T/TCP [RFC1644] (made
+   Historic by [RFC6247]), during the association setup phase.  If an
+   application wants to do this, it cannot use the connect() call.
+   Instead, it should use sendto() or sendmsg() to initiate an
+   association.  If it uses sendto() and it wants to change the
+   initialization behavior, it needs to use the SCTP_INITMSG socket
+   option before calling sendto().  Or it can use sendmsg() with
+   SCTP_INIT type ancillary data to initiate an association without
+   calling setsockopt().  Note that the implicit setup is supported for
+   the one-to-one style sockets.
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 22]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   SCTP does not support half close semantics.  This means that unlike
+   T/TCP, MSG_EOF should not be set in the flags parameter when calling
+   sendto() or sendmsg() when the call is used to initiate a connection.
+   MSG_EOF is not an acceptable flag with an SCTP socket.
+
+4.1.6.  close()
+
+   Applications use close() to gracefully close down an association.
+
+   The function prototype is
+
+   int close(int sd);
+
+   and the argument is
+
+   sd:  The socket descriptor of the association to be closed.
+
+   close() returns 0 on success and -1 in case of an error.
+
+   After an application calls close() on a socket descriptor, no further
+   socket operations will succeed on that descriptor.
+
+4.1.7.  shutdown()
+
+   SCTP differs from TCP in that it does not have half close semantics.
+   Hence, the shutdown() call for SCTP is an approximation of the TCP
+   shutdown() call, and solves some different problems.  Full TCP
+   compatibility is not provided, so developers porting TCP applications
+   to SCTP may need to recode sections that use shutdown().  (Note that
+   it is possible to achieve the same results as half close in SCTP
+   using SCTP streams.)
+
+   The function prototype is
+
+   int shutdown(int sd,
+                int how);
+
+   and the arguments are
+
+   sd:  The socket descriptor of the association to be closed.
+
+   how:  Specifies the type of shutdown.  The values are as follows:
+
+      SHUT_RD:  Disables further receive operations.  No SCTP protocol
+         action is taken.
+
+      SHUT_WR:  Disables further send operations, and initiates the SCTP
+         shutdown sequence.
+
+
+
+Stewart, et al.               Informational                    [Page 23]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+      SHUT_RDWR:  Disables further send and receive operations, and
+         initiates the SCTP shutdown sequence.
+
+   shutdown() returns 0 on success and -1 in case of an error.
+
+   The major difference between SCTP and TCP shutdown() is that SCTP
+   SHUT_WR initiates immediate and full protocol shutdown, whereas TCP
+   SHUT_WR causes TCP to go into the half close state.  SHUT_RD behaves
+   the same for SCTP as for TCP.  The purpose of SCTP SHUT_WR is to
+   close the SCTP association while still leaving the socket descriptor
+   open.  This allows the caller to receive back any data that SCTP is
+   unable to deliver (see Section 6.1.4 for more information) and
+   receive event notifications.
+
+   To perform the ABORT operation described in Section 10.1 of
+   [RFC4960], an application can use the socket option SO_LINGER.
+   SO_LINGER is described in Section 8.1.4.
+
+4.1.8.  sendmsg() and recvmsg()
+
+   With a one-to-one style socket, the application can also use
+   sendmsg() and recvmsg() to transmit data to and receive data from its
+   peer.  The semantics is similar to those used in the one-to-many
+   style (see Section 3.1.4), with the following differences:
+
+   1.  When sending, the msg_name field in the msghdr is not used to
+       specify the intended receiver; rather, it is used to indicate a
+       preferred peer address if the sender wishes to discourage the
+       stack from sending the message to the primary address of the
+       receiver.  If the socket is connected and the transport address
+       given is not part of the current association, the data will not
+       be sent, and an SCTP_SEND_FAILED_EVENT event will be delivered to
+       the application if send failure events are enabled.
+
+   2.  Using sendmsg() on a non-connected one-to-one style socket for
+       implicit connection setup may or may not work, depending on the
+       SCTP implementation.
+
+4.1.9.  getpeername()
+
+   Applications use getpeername() to retrieve the primary socket address
+   of the peer.  This call is for TCP compatibility and is not
+   multi-homed.  It may not work with one-to-many style sockets,
+   depending on the implementation.  See Section 9.3 for a multi-homed
+   style version of the call.
+
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 24]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   The function prototype is
+
+   int getpeername(int sd,
+                   struct sockaddr *address,
+                   socklen_t *len);
+
+   and the arguments are
+
+   sd:  The socket descriptor to be queried.
+
+   address:  On return, the peer primary address is stored in this
+      buffer.  If the socket is an IPv4 socket, the address will be
+      IPv4.  If the socket is an IPv6 socket, the address will be either
+      an IPv6 or IPv4 address.
+
+   len:  The caller should set the length of address here.  On return,
+      this is set to the length of the returned address.
+
+   getpeername() returns 0 on success and -1 in case of an error.
+
+   If the actual length of the address is greater than the length of the
+   supplied sockaddr structure, the stored address will be truncated.
+
+5.  Data Structures
+
+   This section discusses important data structures that are specific to
+   SCTP and are used with sendmsg() and recvmsg() calls to control SCTP
+   endpoint operations and to access ancillary information and
+   notifications.
+
+5.1.  The msghdr and cmsghdr Structures
+
+   The msghdr structure used in the sendmsg() and recvmsg() calls, as
+   well as the ancillary data carried in the structure, is the key for
+   the application to set and get various control information from the
+   SCTP endpoint.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 25]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   The msghdr and the related cmsghdr structures are defined and
+   discussed in detail in [RFC3542].  They are defined as
+
+   struct msghdr {
+     void *msg_name;           /* ptr to socket address structure */
+     socklen_t msg_namelen;    /* size of socket address structure */
+     struct iovec *msg_iov;    /* scatter/gather array */
+     int msg_iovlen;           /* # elements in msg_iov */
+     void *msg_control;        /* ancillary data */
+     socklen_t msg_controllen; /* ancillary data buffer length */
+     int msg_flags;            /* flags on received message */
+   };
+
+   struct cmsghdr {
+     socklen_t cmsg_len; /* # bytes, including this header */
+     int cmsg_level;     /* originating protocol */
+     int cmsg_type;      /* protocol-specific type */
+                         /* followed by unsigned char cmsg_data[]; */
+   };
+
+   In the msghdr structure, the usage of msg_name has been discussed in
+   previous sections (see Sections 3.1.4 and 4.1.8).
+
+   The scatter/gather buffers, or I/O vectors (pointed to by the msg_iov
+   field) are treated by SCTP as a single user message for both
+   sendmsg() and recvmsg().
+
+   The SCTP stack uses the ancillary data (msg_control field) to
+   communicate the attributes, such as SCTP_RCVINFO, of the message
+   stored in msg_iov to the socket endpoint.  The different ancillary
+   data types are described in Section 5.3.
+
+   The msg_flags are not used when sending a message with sendmsg().
+
+   If a notification has arrived, recvmsg() will return the notification
+   in the msg_iov field and set the MSG_NOTIFICATION flag in msg_flags.
+   If the MSG_NOTIFICATION flag is not set, recvmsg() will return data.
+   See Section 6 for more information about notifications.
+
+   If all portions of a data frame or notification have been read,
+   recvmsg() will return with MSG_EOR set in msg_flags.
+
+5.2.  Ancillary Data Considerations and Semantics
+
+   Programming with ancillary socket data (msg_control) contains some
+   subtleties and pitfalls, which are discussed below.
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 26]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+5.2.1.  Multiple Items and Ordering
+
+   Multiple ancillary data items may be included in any call to
+   sendmsg() or recvmsg(); these may include multiple SCTP items,
+   non-SCTP items (such as IP-level items), or both.
+
+   The ordering of ancillary data items (either by SCTP or another
+   protocol) is not significant and is implementation dependent, so
+   applications must not depend on any ordering.
+
+   SCTP_SNDRCV/SCTP_SNDINFO/SCTP_RCVINFO type ancillary data always
+   corresponds to the data in the msghdr's msg_iov member.  There can be
+   only one such type of ancillary data for each sendmsg() or recvmsg()
+   call.
+
+5.2.2.  Accessing and Manipulating Ancillary Data
+
+   Applications can infer the presence of data or ancillary data by
+   examining the msg_iovlen and msg_controllen msghdr members,
+   respectively.
+
+   Implementations may have different padding requirements for ancillary
+   data, so portable applications should make use of the macros
+   CMSG_FIRSTHDR, CMSG_NXTHDR, CMSG_DATA, CMSG_SPACE, and CMSG_LEN.  See
+   [RFC3542] and the SCTP implementation's documentation for more
+   information.  The following is an example, from [RFC3542],
+   demonstrating the use of these macros to access ancillary data:
+
+   struct msghdr msg;
+   struct cmsghdr *cmsgptr;
+
+   /* fill in msg */
+
+   /* call recvmsg() */
+
+   for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL;
+        cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) {
+     if (cmsgptr->cmsg_len == 0) {
+        /* Error handling */
+        break;
+     }
+     if (cmsgptr->cmsg_level == ... && cmsgptr->cmsg_type == ... ) {
+       u_char  *ptr;
+
+       ptr = CMSG_DATA(cmsgptr);
+       /* process data pointed to by ptr */
+     }
+   }
+
+
+
+Stewart, et al.               Informational                    [Page 27]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+5.2.3.  Control Message Buffer Sizing
+
+   The information conveyed via SCTP_SNDRCV/SCTP_SNDINFO/SCTP_RCVINFO
+   ancillary data will often be fundamental to the correct and sane
+   operation of the sockets application.  This is particularly true for
+   one-to-many style sockets, but also for one-to-one style sockets.
+   For example, if an application needs to send and receive data on
+   different SCTP streams, SCTP_SNDRCV/SCTP_SNDINFO/SCTP_RCVINFO
+   ancillary data is indispensable.
+
+   Given that some ancillary data is critical, and that multiple
+   ancillary data items may appear in any order, applications should be
+   carefully written to always provide a large enough buffer to contain
+   all possible ancillary data that can be presented by recvmsg().  If
+   the buffer is too small, and crucial data is truncated, it may pose a
+   fatal error condition.
+
+   Thus, it is essential that applications be able to deterministically
+   calculate the maximum required buffer size to pass to recvmsg().  One
+   constraint imposed on this specification that makes this possible is
+   that all ancillary data definitions are of a fixed length.  One way
+   to calculate the maximum required buffer size might be to take the
+   sum of the sizes of all enabled ancillary data item structures, as
+   calculated by CMSG_SPACE.  For example, if we enabled
+   SCTP_SNDRCV_INFO and IPV6_RECVPKTINFO [RFC3542], we would calculate
+   and allocate the buffer size as follows:
+
+   size_t total;
+   void *buf;
+
+   total = CMSG_SPACE(sizeof(struct sctp_sndrcvinfo)) +
+           CMSG_SPACE(sizeof(struct in6_pktinfo));
+
+   buf = malloc(total);
+
+   We could then use this buffer (buf) for msg_control on each call to
+   recvmsg() and be assured that we would not lose any ancillary data to
+   truncation.
+
+5.3.  SCTP msg_control Structures
+
+   A key element of all SCTP-specific socket extensions is the use of
+   ancillary data to specify and access SCTP-specific data via the
+   msghdr structure's msg_control member used in sendmsg() and
+   recvmsg().  Fine-grained control over initialization and sending
+   parameters are handled with ancillary data.
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 28]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   Each ancillary data item is preceded by a struct cmsghdr (see
+   Section 5.1), which defines the function and purpose of the data
+   contained in the cmsg_data[] member.
+
+   By default, on either style of socket, SCTP will pass no ancillary
+   data.  Specific ancillary data items can be enabled with socket
+   options defined for SCTP; see Section 6.2.
+
+   Note that all ancillary types are of fixed length; see Section 5.2
+   for further discussion on this.  These data structures use struct
+   sockaddr_storage (defined in [RFC3493]) as a portable, fixed-length
+   address format.
+
+   Other protocols may also provide ancillary data to the socket layer
+   consumer.  These ancillary data items from other protocols may
+   intermingle with SCTP data.  For example, the IPv6 sockets API
+   definitions ([RFC3542] and [RFC3493]) define a number of ancillary
+   data items.  If a sockets API consumer enables delivery of both SCTP
+   and IPv6 ancillary data, they both may appear in the same msg_control
+   buffer in any order.  An application may thus need to handle other
+   types of ancillary data besides those passed by SCTP.
+
+   The sockets application must provide a buffer large enough to
+   accommodate all ancillary data provided via recvmsg().  If the buffer
+   is not large enough, the ancillary data will be truncated and the
+   msghdr's msg_flags will include MSG_CTRUNC.
+
+5.3.1.  SCTP Initiation Structure (SCTP_INIT)
+
+   This cmsghdr structure provides information for initializing new SCTP
+   associations with sendmsg().  The SCTP_INITMSG socket option uses
+   this same data structure.  This structure is not used for recvmsg().
+
+            +--------------+-----------+---------------------+
+            | cmsg_level   | cmsg_type | cmsg_data[]         |
+            +--------------+-----------+---------------------+
+            | IPPROTO_SCTP | SCTP_INIT | struct sctp_initmsg |
+            +--------------+-----------+---------------------+
+
+   The sctp_initmsg structure is defined below:
+
+   struct sctp_initmsg {
+     uint16_t sinit_num_ostreams;
+     uint16_t sinit_max_instreams;
+     uint16_t sinit_max_attempts;
+     uint16_t sinit_max_init_timeo;
+   };
+
+
+
+
+Stewart, et al.               Informational                    [Page 29]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   sinit_num_ostreams:  This is an integer representing the number of
+      streams to which the application wishes to be able to send.  This
+      number is confirmed in the SCTP_COMM_UP notification and must be
+      verified, since it is a negotiated number with the remote
+      endpoint.  The default value of 0 indicates the use of the
+      endpoint's default value.
+
+   sinit_max_instreams:  This value represents the maximum number of
+      inbound streams the application is prepared to support.  This
+      value is bounded by the actual implementation.  In other words,
+      the user may be able to support more streams than the operating
+      system.  In such a case, the operating-system limit overrides the
+      value requested by the user.  The default value of 0 indicates the
+      use of the endpoint's default value.
+
+   sinit_max_attempts:  This integer specifies how many attempts the
+      SCTP endpoint should make at resending the INIT.  This value
+      overrides the system SCTP 'Max.Init.Retransmits' value.  The
+      default value of 0 indicates the use of the endpoint's default
+      value.  This is normally set to the system's default
+      'Max.Init.Retransmit' value.
+
+   sinit_max_init_timeo:  This value represents the largest timeout or
+      retransmission timeout (RTO) value (in milliseconds) to use in
+      attempting an INIT.  Normally, the 'RTO.Max' is used to limit the
+      doubling of the RTO upon timeout.  For the INIT message, this
+      value may override 'RTO.Max'.  This value must not influence
+      'RTO.Max' during data transmission and is only used to bound the
+      initial setup time.  A default value of 0 indicates the use of the
+      endpoint's default value.  This is normally set to the system's
+      'RTO.Max' value (60 seconds).
+
+5.3.2.  SCTP Header Information Structure (SCTP_SNDRCV) - DEPRECATED
+
+   This cmsghdr structure specifies SCTP options for sendmsg() and
+   describes SCTP header information about a received message through
+   recvmsg().  This structure mixes the send and receive path.
+   SCTP_SNDINFO (described in Section 5.3.4) and SCTP_RCVINFO (described
+   in Section 5.3.5) split this information.  These structures should be
+   used, when possible, since SCTP_SNDRCV is deprecated.
+
+          +--------------+-------------+------------------------+
+          | cmsg_level   | cmsg_type   | cmsg_data[]            |
+          +--------------+-------------+------------------------+
+          | IPPROTO_SCTP | SCTP_SNDRCV | struct sctp_sndrcvinfo |
+          +--------------+-------------+------------------------+
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 30]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   The sctp_sndrcvinfo structure is defined below:
+
+   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;
+   };
+
+   sinfo_stream:  For recvmsg(), the SCTP stack places the message's
+      stream number in this value.  For sendmsg(), this value holds the
+      stream number to which the application wishes to send this
+      message.  If a sender specifies an invalid stream number, an error
+      indication is returned and the call fails.
+
+   sinfo_ssn:  For recvmsg(), this value contains the stream sequence
+      number that the remote endpoint placed in the DATA chunk.  For
+      fragmented messages, this is the same number for all deliveries of
+      the message (if more than one recvmsg() is needed to read the
+      message).  The sendmsg() call will ignore this parameter.
+
+   sinfo_flags:  This field may contain any of the following flags and
+      is composed of a bitwise OR of these values.
+
+      recvmsg() flags:
+
+         SCTP_UNORDERED:  This flag is present when the message was sent
+            unordered.
+
+      sendmsg() flags:
+
+         SCTP_UNORDERED:  This flag requests the unordered delivery of
+            the message.  If this flag is clear, the datagram is
+            considered an ordered send.
+
+         SCTP_ADDR_OVER:  This flag, for a one-to-many style socket,
+            requests that the SCTP stack override the primary
+            destination address with the address found with the sendto/
+            sendmsg call.
+
+
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 31]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+         SCTP_ABORT:  Setting this flag causes the specified association
+            to abort by sending an ABORT message to the peer.  The ABORT
+            chunk will contain an error cause of 'User Initiated Abort'
+            with cause code 12.  The cause-specific information of this
+            error cause is provided in msg_iov.
+
+         SCTP_EOF:  Setting this flag invokes the SCTP graceful shutdown
+            procedure on the specified association.  Graceful shutdown
+            assures that all data queued by both endpoints is
+            successfully transmitted before closing the association.
+
+         SCTP_SENDALL:  This flag, if set, will cause a one-to-many
+            style socket to send the message to all associations that
+            are currently established on this socket.  For the one-to-
+            one style socket, this flag has no effect.
+
+   sinfo_ppid:  This value in sendmsg() is an unsigned integer that is
+      passed to the remote end in each user message.  In recvmsg(), this
+      value is the same information that was passed by the upper layer
+      in the peer application.  Please note that the SCTP stack performs
+      no byte order modification of this field.  For example, if the
+      DATA chunk has to contain a given value in network byte order, the
+      SCTP user has to perform the htonl() computation.
+
+   sinfo_context:  This value is an opaque 32-bit context datum that is
+      used in the sendmsg() function.  This value is passed back to the
+      upper layer if an error occurs on the send of a message and is
+      retrieved with each undelivered message.
+
+   sinfo_timetolive:  For the sending side, this field contains the
+      message's time to live, in milliseconds.  The sending side will
+      expire the message within the specified time period if the message
+      has not been sent to the peer within this time period.  This value
+      will override any default value set using any socket option.  Also
+      note that the value of 0 is special in that it indicates no
+      timeout should occur on this message.
+
+   sinfo_tsn:  For the receiving side, this field holds a Transmission
+      Sequence Number (TSN) that was assigned to one of the SCTP DATA
+      chunks.  For the sending side, it is ignored.
+
+   sinfo_cumtsn:  This field will hold the current cumulative TSN as
+      known by the underlying SCTP layer.  Note that this field is
+      ignored when sending.
+
+
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 32]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   sinfo_assoc_id:  The association handle field, sinfo_assoc_id, holds
+      the identifier for the association announced in the SCTP_COMM_UP
+      notification.  All notifications for a given association have the
+      same identifier.  This field is ignored for one-to-one style
+      sockets.
+
+   An sctp_sndrcvinfo item always corresponds to the data in msg_iov.
+
+5.3.3.  Extended SCTP Header Information Structure (SCTP_EXTRCV) -
+        DEPRECATED
+
+   This cmsghdr structure specifies SCTP options for SCTP header
+   information about a received message via recvmsg().  Note that this
+   structure is an extended version of SCTP_SNDRCV (see Section 5.3.2)
+   and will only be received if the user has set the socket option
+   SCTP_USE_EXT_RCVINFO (see Section 8.1.22) to true in addition to any
+   event subscription needed to receive ancillary data.  Note that data
+   in the next message is not valid unless the current message is
+   completely read, i.e., unless the MSG_EOR is set; in other words, if
+   the application has more data to read from the current message, then
+   no next-message information will be available.
+
+   SCTP_NXTINFO (described in Section 5.3.6) should be used when
+   possible, since SCTP_EXTRCV is considered deprecated.
+
+          +--------------+-------------+------------------------+
+          | cmsg_level   | cmsg_type   | cmsg_data[]            |
+          +--------------+-------------+------------------------+
+          | IPPROTO_SCTP | SCTP_EXTRCV | struct sctp_extrcvinfo |
+          +--------------+-------------+------------------------+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 33]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   The sctp_extrcvinfo structure is defined below:
+
+   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_pr_value;
+     uint32_t sinfo_tsn;
+     uint32_t sinfo_cumtsn;
+     uint16_t serinfo_next_flags;
+     uint16_t serinfo_next_stream;
+     uint32_t serinfo_next_aid;
+     uint32_t serinfo_next_length;
+     uint32_t serinfo_next_ppid;
+     sctp_assoc_t sinfo_assoc_id;
+   };
+
+   sinfo_*:  Please see Section 5.3.2 for details for these fields.
+
+   serinfo_next_flags:  This bitmask will hold one or more of the
+      following values:
+
+      SCTP_NEXT_MSG_AVAIL:  This bit, when set to 1, indicates that
+         next-message information is available; i.e., next_stream,
+         next_aid, next_length, and next_ppid fields all have valid
+         values.  If this bit is set to 0, then these fields are not
+         valid and should be ignored.
+
+      SCTP_NEXT_MSG_ISCOMPLETE:  This bit, when set, indicates that the
+         next message is completely in the receive buffer.  The
+         next_length field thus contains the entire message size.  If
+         this flag is set to 0, then the next_length field only contains
+         part of the message size, since the message is still being
+         received (it is being partially delivered).
+
+      SCTP_NEXT_MSG_IS_UNORDERED:  This bit, when set, indicates that
+         the next message to be received was sent by the peer as
+         unordered.  If this bit is not set (i.e., the bit is 0) the
+         next message to be read is an ordered message in the stream
+         specified.
+
+      SCTP_NEXT_MSG_IS_NOTIFICATION:  This bit, when set, indicates that
+         the next message to be received is not a message from the peer,
+         but instead is a MSG_NOTIFICATION from the local SCTP stack.
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 34]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   serinfo_next_stream:  This value, when valid (see
+      serinfo_next_flags), contains the next stream number that will be
+      received on a subsequent call to one of the receive message
+      functions.
+
+   serinfo_next_aid:  This value, when valid (see serinfo_next_flags),
+      contains the next association identifier that will be received on
+      a subsequent call to one of the receive message functions.
+
+   serinfo_next_length:  This value, when valid (see
+      serinfo_next_flags), contains the length of the next message that
+      will be received on a subsequent call to one of the receive
+      message functions.  Note that this length may be a partial length,
+      depending on the settings of next_flags.
+
+   serinfo_next_ppid:  This value, when valid (see serinfo_next_flags),
+      contains the ppid of the next message that will be received on a
+      subsequent call to one of the receive message functions.
+
+5.3.4.  SCTP Send Information Structure (SCTP_SNDINFO)
+
+   This cmsghdr structure specifies SCTP options for sendmsg().
+
+           +--------------+--------------+---------------------+
+           | cmsg_level   | cmsg_type    | cmsg_data[]         |
+           +--------------+--------------+---------------------+
+           | IPPROTO_SCTP | SCTP_SNDINFO | struct sctp_sndinfo |
+           +--------------+--------------+---------------------+
+
+   The sctp_sndinfo structure is defined below:
+
+   struct sctp_sndinfo {
+     uint16_t snd_sid;
+     uint16_t snd_flags;
+     uint32_t snd_ppid;
+     uint32_t snd_context;
+     sctp_assoc_t snd_assoc_id;
+   };
+
+   snd_sid:  This value holds the stream number to which the application
+      wishes to send this message.  If a sender specifies an invalid
+      stream number, an error indication is returned and the call fails.
+
+
+
+
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 35]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   snd_flags:  This field may contain any of the following flags and is
+      composed of a bitwise OR of these values.
+
+      SCTP_UNORDERED:  This flag requests the unordered delivery of the
+         message.  If this flag is clear, the datagram is considered an
+         ordered send.
+
+      SCTP_ADDR_OVER:  This flag, for a one-to-many style socket,
+         requests that the SCTP stack override the primary destination
+         address with the address found with the sendto()/sendmsg call.
+
+      SCTP_ABORT:  Setting this flag causes the specified association to
+         abort by sending an ABORT message to the peer.  The ABORT chunk
+         will contain an error cause of 'User Initiated Abort' with
+         cause code 12.  The cause-specific information of this error
+         cause is provided in msg_iov.
+
+      SCTP_EOF:  Setting this flag invokes the SCTP graceful shutdown
+         procedures on the specified association.  Graceful shutdown
+         assures that all data queued by both endpoints is successfully
+         transmitted before closing the association.
+
+      SCTP_SENDALL:  This flag, if set, will cause a one-to-many style
+         socket to send the message to all associations that are
+         currently established on this socket.  For the one-to-one style
+         socket, this flag has no effect.
+
+   snd_ppid:  This value in sendmsg() is an unsigned integer that is
+      passed to the remote end in each user message.  Please note that
+      the SCTP stack performs no byte order modification of this field.
+      For example, if the DATA chunk has to contain a given value in
+      network byte order, the SCTP user has to perform the htonl()
+      computation.
+
+   snd_context:  This value is an opaque 32-bit context datum that is
+      used in the sendmsg() function.  This value is passed back to the
+      upper layer if an error occurs on the send of a message and is
+      retrieved with each undelivered message.
+
+   snd_assoc_id:  The association handle field, sinfo_assoc_id, holds
+      the identifier for the association announced in the SCTP_COMM_UP
+      notification.  All notifications for a given association have the
+      same identifier.  This field is ignored for one-to-one style
+      sockets.
+
+   An sctp_sndinfo item always corresponds to the data in msg_iov.
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 36]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+5.3.5.  SCTP Receive Information Structure (SCTP_RCVINFO)
+
+   This cmsghdr structure describes SCTP receive information about a
+   received message through recvmsg().
+
+   To enable the delivery of this information, an application must use
+   the SCTP_RECVRCVINFO socket option (see Section 8.1.29).
+
+           +--------------+--------------+---------------------+
+           | cmsg_level   | cmsg_type    | cmsg_data[]         |
+           +--------------+--------------+---------------------+
+           | IPPROTO_SCTP | SCTP_RCVINFO | struct sctp_rcvinfo |
+           +--------------+--------------+---------------------+
+
+   The sctp_rcvinfo structure is defined below:
+
+   struct sctp_rcvinfo {
+     uint16_t rcv_sid;
+     uint16_t rcv_ssn;
+     uint16_t rcv_flags;
+     uint32_t rcv_ppid;
+     uint32_t rcv_tsn;
+     uint32_t rcv_cumtsn;
+     uint32_t rcv_context;
+     sctp_assoc_t rcv_assoc_id;
+   };
+
+   rcv_sid:  The SCTP stack places the message's stream number in this
+      value.
+
+   rcv_ssn:  This value contains the stream sequence number that the
+      remote endpoint placed in the DATA chunk.  For fragmented
+      messages, this is the same number for all deliveries of the
+      message (if more than one recvmsg() is needed to read the
+      message).
+
+   rcv_flags:  This field may contain any of the following flags and is
+      composed of a bitwise OR of these values.
+
+      SCTP_UNORDERED:  This flag is present when the message was sent
+         unordered.
+
+   rcv_ppid:  This value is the same information that was passed by the
+      upper layer in the peer application.  Please note that the SCTP
+      stack performs no byte order modification of this field.  For
+      example, if the DATA chunk has to contain a given value in network
+      byte order, the SCTP user has to perform the ntohl() computation.
+
+
+
+
+Stewart, et al.               Informational                    [Page 37]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   rcv_tsn:  This field holds a TSN that was assigned to one of the SCTP
+      DATA chunks.
+
+   rcv_cumtsn:  This field will hold the current cumulative TSN as known
+      by the underlying SCTP layer.
+
+   rcv_context:  This value is an opaque 32-bit context datum that was
+      set by the user with the SCTP_CONTEXT socket option.  This value
+      is passed back to the upper layer if an error occurs on the send
+      of a message and is retrieved with each undelivered message.
+
+   rcv_assoc_id:  The association handle field, sinfo_assoc_id, holds
+      the identifier for the association announced in the SCTP_COMM_UP
+      notification.  All notifications for a given association have the
+      same identifier.  This field is ignored for one-to-one style
+      sockets.
+
+   An sctp_rcvinfo item always corresponds to the data in msg_iov.
+
+5.3.6.  SCTP Next Receive Information Structure (SCTP_NXTINFO)
+
+   This cmsghdr structure describes SCTP receive information of the next
+   message that will be delivered through recvmsg() if this information
+   is already available when delivering the current message.
+
+   To enable the delivery of this information, an application must use
+   the SCTP_RECVNXTINFO socket option (see Section 8.1.30).
+
+           +--------------+--------------+---------------------+
+           | cmsg_level   | cmsg_type    | cmsg_data[]         |
+           +--------------+--------------+---------------------+
+           | IPPROTO_SCTP | SCTP_NXTINFO | struct sctp_nxtinfo |
+           +--------------+--------------+---------------------+
+
+   The sctp_nxtinfo structure is defined below:
+
+   struct sctp_nxtinfo {
+     uint16_t nxt_sid;
+     uint16_t nxt_flags;
+     uint32_t nxt_ppid;
+     uint32_t nxt_length;
+     sctp_assoc_t nxt_assoc_id;
+   };
+
+
+
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 38]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   nxt_sid:  The SCTP stack places the next message's stream number in
+      this value.
+
+   nxt_flags:  This field may contain any of the following flags and is
+      composed of a bitwise OR of these values.
+
+      SCTP_UNORDERED:  This flag is present when the next message was
+         sent unordered.
+
+      SCTP_COMPLETE:  This flag indicates that the entire message has
+         been received and is in the socket buffer.  Note that this has
+         special implications with respect to the nxt_length field; see
+         the description for nxt_length below.
+
+      SCTP_NOTIFICATION:  This flag is present when the next message is
+         not a user message but instead is a notification.
+
+   nxt_ppid:  This value is the same information that was passed by the
+      upper layer in the peer application for the next message.  Please
+      note that the SCTP stack performs no byte order modification of
+      this field.  For example, if the DATA chunk has to contain a given
+      value in network byte order, the SCTP user has to perform the
+      ntohl() computation.
+
+   nxt_length:  This value is the length of the message currently within
+      the socket buffer.  This might NOT be the entire length of the
+      message, since a partial delivery may be in progress.  Only if the
+      flag SCTP_COMPLETE is set in the nxt_flags field does this field
+      represent the size of the entire next message.
+
+   nxt_assoc_id:  The association handle field of the next message,
+      nxt_assoc_id, holds the identifier for the association announced
+      in the SCTP_COMM_UP notification.  All notifications for a given
+      association have the same identifier.  This field is ignored for
+      one-to-one style sockets.
+
+5.3.7.  SCTP PR-SCTP Information Structure (SCTP_PRINFO)
+
+   This cmsghdr structure specifies SCTP options for sendmsg().
+
+            +--------------+-------------+--------------------+
+            | cmsg_level   | cmsg_type   | cmsg_data[]        |
+            +--------------+-------------+--------------------+
+            | IPPROTO_SCTP | SCTP_PRINFO | struct sctp_prinfo |
+            +--------------+-------------+--------------------+
+
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 39]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   The sctp_prinfo structure is defined below:
+
+   struct sctp_prinfo {
+     uint16_t pr_policy;
+     uint32_t pr_value;
+   };
+
+   pr_policy:  This specifies which Partially Reliable SCTP (PR-SCTP)
+      policy is used.  Using SCTP_PR_SCTP_NONE results in a reliable
+      transmission.  When SCTP_PR_SCTP_TTL is used, the PR-SCTP policy
+      "timed reliability" defined in [RFC3758] is used.  In this case,
+      the lifetime is provided in pr_value.
+
+   pr_value:  The meaning of this field depends on the PR-SCTP policy
+      specified by the pr_policy field.  It is ignored when
+      SCTP_PR_SCTP_NONE is specified.  In the case of SCTP_PR_SCTP_TTL,
+      the lifetime in milliseconds is specified.
+
+   An sctp_prinfo item always corresponds to the data in msg_iov.
+
+5.3.8.  SCTP AUTH Information Structure (SCTP_AUTHINFO)
+
+   This cmsghdr structure specifies SCTP options for sendmsg().
+
+          +--------------+---------------+----------------------+
+          | cmsg_level   | cmsg_type     | cmsg_data[]          |
+          +--------------+---------------+----------------------+
+          | IPPROTO_SCTP | SCTP_AUTHINFO | struct sctp_authinfo |
+          +--------------+---------------+----------------------+
+
+   The sctp_authinfo structure is defined below:
+
+   struct sctp_authinfo {
+     uint16_t auth_keynumber;
+   };
+
+   auth_keynumber:  This specifies the shared key identifier used for
+      sending the user message.
+
+   An sctp_authinfo item always corresponds to the data in msg_iov.
+   Please note that the SCTP implementation must not bundle user
+   messages that need to be authenticated using different shared key
+   identifiers.
+
+
+
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 40]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+5.3.9.  SCTP Destination IPv4 Address Structure (SCTP_DSTADDRV4)
+
+   This cmsghdr structure specifies SCTP options for sendmsg().
+
+            +--------------+----------------+----------------+
+            | cmsg_level   | cmsg_type      | cmsg_data[]    |
+            +--------------+----------------+----------------+
+            | IPPROTO_SCTP | SCTP_DSTADDRV4 | struct in_addr |
+            +--------------+----------------+----------------+
+
+   This ancillary data can be used to provide more than one destination
+   address to sendmsg().  It can be used to implement sctp_sendv() using
+   sendmsg().
+
+5.3.10.  SCTP Destination IPv6 Address Structure (SCTP_DSTADDRV6)
+
+   This cmsghdr structure specifies SCTP options for sendmsg().
+
+            +--------------+----------------+-----------------+
+            | cmsg_level   | cmsg_type      | cmsg_data[]     |
+            +--------------+----------------+-----------------+
+            | IPPROTO_SCTP | SCTP_DSTADDRV6 | struct in6_addr |
+            +--------------+----------------+-----------------+
+
+   This ancillary data can be used to provide more than one destination
+   address to sendmsg().  It can be used to implement sctp_sendv() using
+   sendmsg().
+
+6.  SCTP Events and Notifications
+
+   An SCTP application may need to understand and process events and
+   errors that happen on the SCTP stack.  These events include network
+   status changes, association startups, remote operational errors, and
+   undeliverable messages.  All of these can be essential for the
+   application.
+
+   When an SCTP application layer does a recvmsg(), the message read is
+   normally a data message from a peer endpoint.  If the application
+   wishes to have the SCTP stack deliver notifications of non-data
+   events, it sets the appropriate socket option for the notifications
+   it wants.  See Section 6.2 for these socket options.  When a
+   notification arrives, recvmsg() returns the notification in the
+   application-supplied data buffer via msg_iov, and sets
+   MSG_NOTIFICATION in msg_flags.
+
+   This section details the notification structures.  Every notification
+   structure carries some common fields that provide general
+   information.
+
+
+
+Stewart, et al.               Informational                    [Page 41]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   A recvmsg() call will return only one notification at a time.  Just
+   as when reading normal data, it may return part of a notification if
+   the msg_iov buffer is not large enough.  If a single read is not
+   sufficient, msg_flags will have MSG_EOR clear.  The user must finish
+   reading the notification before subsequent data can arrive.
+
+6.1.  SCTP Notification Structure
+
+   The notification structure is defined as the union of all
+   notification types.
+
+   union sctp_notification {
+     struct sctp_tlv {
+       uint16_t sn_type; /* Notification type. */
+       uint16_t sn_flags;
+       uint32_t sn_length;
+     } 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;
+     struct sctp_pdapi_event sn_pdapi_event;
+     struct sctp_authkey_event sn_auth_event;
+     struct sctp_sender_dry_event sn_sender_dry_event;
+     struct sctp_send_failed_event sn_send_failed_event;
+   };
+
+   sn_type:  The following list describes the SCTP notification and
+      event types for the field sn_type.
+
+      SCTP_ASSOC_CHANGE:  This tag indicates that an association has
+         either been opened or closed.  Refer to Section 6.1.1 for
+         details.
+
+      SCTP_PEER_ADDR_CHANGE:  This tag indicates that an address that is
+         part of an existing association has experienced a change of
+         state (e.g., a failure or return to service of the reachability
+         of an endpoint via a specific transport address).  Please see
+         Section 6.1.2 for data structure details.
+
+      SCTP_REMOTE_ERROR:  The attached error message is an Operation
+         Error message received from the remote peer.  It includes the
+         complete TLV sent by the remote endpoint.  See Section 6.1.3
+         for the detailed format.
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 42]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+      SCTP_SEND_FAILED_EVENT:  The attached datagram could not be sent
+         to the remote endpoint.  This structure includes the original
+         SCTP_SNDINFO that was used in sending this message; i.e., this
+         structure uses the sctp_sndinfo per Section 6.1.11.
+
+      SCTP_SHUTDOWN_EVENT:  The peer has sent a SHUTDOWN.  No further
+         data should be sent on this socket.
+
+      SCTP_ADAPTATION_INDICATION:  This notification holds the peer's
+         indicated adaptation layer.  Please see Section 6.1.6.
+
+      SCTP_PARTIAL_DELIVERY_EVENT:  This notification is used to tell a
+         receiver that the partial delivery has been aborted.  This may
+         indicate that the association is about to be aborted.  Please
+         see Section 6.1.7.
+
+      SCTP_AUTHENTICATION_EVENT:  This notification is used to tell a
+         receiver that either an error occurred on authentication, or a
+         new key was made active.  See Section 6.1.8.
+
+      SCTP_SENDER_DRY_EVENT:  This notification is used to inform the
+         application that the sender has no more user data queued for
+         transmission or retransmission.  See Section 6.1.9.
+
+   sn_flags:  These are notification-specific flags.
+
+   sn_length:  This is the length of the whole sctp_notification
+      structure, including the sn_type, sn_flags, and sn_length fields.
+
+6.1.1.  SCTP_ASSOC_CHANGE
+
+   Communication notifications inform the application that an SCTP
+   association has either begun or ended.  The identifier for a new
+   association is provided by this notification.  The notification
+   information has the following format:
+
+   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;
+     uint8_t  sac_info[];
+   };
+
+
+
+
+Stewart, et al.               Informational                    [Page 43]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   sac_type:  This field should be set to SCTP_ASSOC_CHANGE.
+
+   sac_flags:  This field is currently unused.
+
+   sac_length:  This field is the total length of the notification data,
+      including the notification header.
+
+   sac_state:  This field holds one of a number of values that
+      communicate the event that happened to the association.  These
+      values include
+
+      SCTP_COMM_UP:  A new association is now ready, and data may be
+         exchanged with this peer.  When an association has been
+         established successfully, this notification should be the
+         first one.
+
+      SCTP_COMM_LOST:  The association has failed.  The association is
+         now in the closed state.  If SEND_FAILED notifications are
+         turned on, an SCTP_COMM_LOST is accompanied by a series of
+         SCTP_SEND_FAILED_EVENT events, one for each outstanding
+         message.
+
+      SCTP_RESTART:  SCTP has detected that the peer has restarted.
+
+      SCTP_SHUTDOWN_COMP:  The association has gracefully closed.
+
+      SCTP_CANT_STR_ASSOC:  The association setup failed.  If
+         non-blocking mode is set and data was sent (on a one-to-many
+         style socket), an SCTP_CANT_STR_ASSOC is accompanied by a
+         series of SCTP_SEND_FAILED_EVENT events, one for each
+         outstanding message.
+
+   sac_error:  If the state was reached due to an error condition (e.g.,
+      SCTP_COMM_LOST), any relevant error information is available in
+      this field.  This corresponds to the protocol error codes defined
+      in [RFC4960].
+
+   sac_outbound_streams and sac_inbound_streams:  The maximum number of
+      streams allowed in each direction is available in
+      sac_outbound_streams and sac_inbound streams.
+
+   sac_assoc_id:  The sac_assoc_id field holds the identifier for the
+      association.  All notifications for a given association have the
+      same association identifier.  For a one-to-one style socket, this
+      field is ignored.
+
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 44]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   sac_info:  If sac_state is SCTP_COMM_LOST and an ABORT chunk was
+      received for this association, sac_info[] contains the complete
+      ABORT chunk as defined in Section 3.3.7 of the SCTP specification
+      [RFC4960].  If sac_state is SCTP_COMM_UP or SCTP_RESTART, sac_info
+      may contain an array of uint8_t describing the features that the
+      current association supports.  Features may include
+
+      SCTP_ASSOC_SUPPORTS_PR:  Both endpoints support the protocol
+         extension described in [RFC3758].
+
+      SCTP_ASSOC_SUPPORTS_AUTH:  Both endpoints support the protocol
+         extension described in [RFC4895].
+
+      SCTP_ASSOC_SUPPORTS_ASCONF:  Both endpoints support the protocol
+         extension described in [RFC5061].
+
+      SCTP_ASSOC_SUPPORTS_MULTIBUF:  For a one-to-many style socket, the
+         local endpoints use separate send and/or receive buffers for
+         each SCTP association.
+
+6.1.2.  SCTP_PEER_ADDR_CHANGE
+
+   When a destination address of a multi-homed peer encounters a state
+   change, a peer address change event is sent.  The notification has
+   the following format:
+
+   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;
+   }
+
+   spc_type:  This field should be set to SCTP_PEER_ADDR_CHANGE.
+
+   spc_flags:  This field is currently unused.
+
+   spc_length:  This field is the total length of the notification data,
+      including the notification header.
+
+   spc_aaddr:  The affected address field holds the remote peer's
+      address that is encountering the change of state.
+
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 45]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   spc_state:  This field holds one of a number of values that
+      communicate the event that happened to the address.  They include
+
+      SCTP_ADDR_AVAILABLE:  This address is now reachable.  This
+         notification is provided whenever an address becomes reachable.
+
+      SCTP_ADDR_UNREACHABLE:  The address specified can no longer be
+         reached.  Any data sent to this address is rerouted to an
+         alternate until this address becomes reachable.  This
+         notification is provided whenever an address becomes
+         unreachable.
+
+      SCTP_ADDR_REMOVED:  The address is no longer part of the
+         association.
+
+      SCTP_ADDR_ADDED:  The address is now part of the association.
+
+      SCTP_ADDR_MADE_PRIM:  This address has now been made the primary
+         destination address.  This notification is provided whenever an
+         address is made primary.
+
+   spc_error:  If the state was reached due to any error condition
+      (e.g., SCTP_ADDR_UNREACHABLE), any relevant error information is
+      available in this field.
+
+   spc_assoc_id:  The spc_assoc_id field holds the identifier for the
+      association.  All notifications for a given association have the
+      same association identifier.  For a one-to-one style socket, this
+      field is ignored.
+
+6.1.3.  SCTP_REMOTE_ERROR
+
+   A remote peer may send an Operation Error message to its peer.  This
+   message indicates a variety of error conditions on an association.
+   The entire ERROR chunk as it appears on the wire is included in an
+   SCTP_REMOTE_ERROR event.  Please refer to the SCTP specification
+   [RFC4960] and any extensions for a list of possible error formats.
+   An SCTP error notification has the following format:
+
+   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[];
+   };
+
+
+
+
+Stewart, et al.               Informational                    [Page 46]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   sre_type:  This field should be set to SCTP_REMOTE_ERROR.
+
+   sre_flags:  This field is currently unused.
+
+   sre_length:  This field is the total length of the notification data,
+      including the notification header and the contents of sre_data.
+
+   sre_error:  This value represents one of the Operation Error causes
+      defined in the SCTP specification [RFC4960], in network byte
+      order.
+
+   sre_assoc_id:  The sre_assoc_id field holds the identifier for the
+      association.  All notifications for a given association have the
+      same association identifier.  For a one-to-one style socket, this
+      field is ignored.
+
+   sre_data:  This contains the ERROR chunk as defined in Section 3.3.10
+      of the SCTP specification [RFC4960].
+
+6.1.4.  SCTP_SEND_FAILED - DEPRECATED
+
+   Please note that this notification is deprecated.  Use
+   SCTP_SEND_FAILED_EVENT instead.
+
+   If SCTP cannot deliver a message, it can return back the message as a
+   notification if the SCTP_SEND_FAILED event is enabled.  The
+   notification has the following format:
+
+   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[];
+   };
+
+   ssf_type:  This field should be set to SCTP_SEND_FAILED.
+
+   ssf_flags:  The flag value will take one of the following values:
+
+      SCTP_DATA_UNSENT:  This value indicates that the data was never
+         put on the wire.
+
+      SCTP_DATA_SENT:  This value indicates that the data was put on the
+         wire.  Note that this does not necessarily mean that the data
+         was (or was not) successfully delivered.
+
+
+
+Stewart, et al.               Informational                    [Page 47]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   ssf_length:  This field is the total length of the notification data,
+      including the notification header and the payload in ssf_data.
+
+   ssf_error:  This value represents the reason why the send failed, and
+      if set, will be an SCTP protocol error code as defined in
+      Section 3.3.10 of [RFC4960].
+
+   ssf_info:  This field includes the ancillary data (struct
+      sctp_sndrcvinfo) used to send the undelivered message.  Regardless
+      of whether ancillary data is used or not, the ssf_info.sinfo_flags
+      field indicates whether the complete message or only part of the
+      message is returned in ssf_data.  If only part of the message is
+      returned, it means that the part that is not present has been sent
+      successfully to the peer.
+
+      If the complete message cannot be sent, the SCTP_DATA_NOT_FRAG
+      flag is set in ssf_info.sinfo_flags.  If the first part of the
+      message is sent successfully, SCTP_DATA_LAST_FRAG is set.  This
+      means that the tail end of the message is returned in ssf_data.
+
+   ssf_assoc_id:  The ssf_assoc_id field, ssf_assoc_id, holds the
+      identifier for the association.  All notifications for a given
+      association have the same association identifier.  For a one-to-
+      one style socket, this field is ignored.
+
+   ssf_data:  The undelivered message or part of the undelivered message
+      will be present in the ssf_data field.  Note that the
+      ssf_info.sinfo_flags field as noted above should be used to
+      determine whether a complete message or just a piece of the
+      message is present.  Note that only user data is present in this
+      field; any chunk headers or SCTP common headers must be removed by
+      the SCTP stack.
+
+6.1.5.  SCTP_SHUTDOWN_EVENT
+
+   When a peer sends a SHUTDOWN, SCTP delivers this notification to
+   inform the application that it should cease sending data.
+
+       struct sctp_shutdown_event {
+           uint16_t sse_type;
+           uint16_t sse_flags;
+           uint32_t sse_length;
+           sctp_assoc_t sse_assoc_id;
+       };
+
+   sse_type:  This field should be set to SCTP_SHUTDOWN_EVENT.
+
+   sse_flags:  This field is currently unused.
+
+
+
+Stewart, et al.               Informational                    [Page 48]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   sse_length:  This field is the total length of the notification data,
+      including the notification header.  It will generally be
+      sizeof(struct sctp_shutdown_event).
+
+   sse_assoc_id:  The sse_assoc_id field holds the identifier for the
+      association.  All notifications for a given association have the
+      same association identifier.  For a one-to-one style socket, this
+      field is ignored.
+
+6.1.6.  SCTP_ADAPTATION_INDICATION
+
+   When a peer sends an Adaptation Layer Indication parameter as
+   described in [RFC5061], SCTP delivers this notification to inform the
+   application about the peer's adaptation layer indication.
+
+   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;
+   };
+
+   sai_type:  This field should be set to SCTP_ADAPTATION_INDICATION.
+
+   sai_flags:  This field is currently unused.
+
+   sai_length:  This field is the total length of the notification data,
+      including the notification header.  It will generally be
+      sizeof(struct sctp_adaptation_event).
+
+   sai_adaptation_ind:  This field holds the bit array sent by the peer
+      in the Adaptation Layer Indication parameter.
+
+   sai_assoc_id:  The sai_assoc_id field holds the identifier for the
+      association.  All notifications for a given association have the
+      same association identifier.  For a one-to-one style socket, this
+      field is ignored.
+
+6.1.7.  SCTP_PARTIAL_DELIVERY_EVENT
+
+   When a receiver is engaged in a partial delivery of a message, this
+   notification will be used to indicate various events.
+
+   struct sctp_pdapi_event {
+     uint16_t pdapi_type;
+     uint16_t pdapi_flags;
+     uint32_t pdapi_length;
+
+
+
+Stewart, et al.               Informational                    [Page 49]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+     uint32_t pdapi_indication;
+     uint32_t pdapi_stream;
+     uint32_t pdapi_seq;
+     sctp_assoc_t pdapi_assoc_id;
+   };
+
+   pdapi_type:  This field should be set to SCTP_PARTIAL_DELIVERY_EVENT.
+
+   pdapi_flags:  This field is currently unused.
+
+   pdapi_length:  This field is the total length of the notification
+      data, including the notification header.  It will generally be
+      sizeof(struct sctp_pdapi_event).
+
+   pdapi_indication:  This field holds the indication being sent to the
+      application.  Currently, there is only one defined value:
+
+      SCTP_PARTIAL_DELIVERY_ABORTED:  This indicates that the partial
+         delivery of a user message has been aborted.  This happens, for
+         example, if an association is aborted while a partial delivery
+         is going on or the user message gets abandoned using PR-SCTP
+         while the partial delivery of this message is going on.
+
+   pdapi_stream:  This field holds the stream on which the partial
+      delivery event happened.
+
+   pdapi_seq:  This field holds the stream sequence number that was
+      being partially delivered.
+
+   pdapi_assoc_id:  The pdapi_assoc_id field holds the identifier for
+      the association.  All notifications for a given association have
+      the same association identifier.  For a one-to-one style socket,
+      this field is ignored.
+
+6.1.8.  SCTP_AUTHENTICATION_EVENT
+
+   [RFC4895] defines an extension to authenticate SCTP messages.  The
+   following notification is used to report different events relating to
+   the use of this extension.
+
+   struct sctp_authkey_event {
+     uint16_t auth_type;
+     uint16_t auth_flags;
+     uint32_t auth_length;
+     uint16_t auth_keynumber;
+     uint32_t auth_indication;
+     sctp_assoc_t auth_assoc_id;
+   };
+
+
+
+Stewart, et al.               Informational                    [Page 50]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   auth_type:  This field should be set to SCTP_AUTHENTICATION_EVENT.
+
+   auth_flags:  This field is currently unused.
+
+   auth_length:  This field is the total length of the notification
+      data, including the notification header.  It will generally be
+      sizeof(struct sctp_authkey_event).
+
+   auth_keynumber:  This field holds the key number for the affected key
+      indicated in the event (depends on auth_indication).
+
+   auth_indication:  This field holds the error or indication being
+      reported.  The following values are currently defined:
+
+      SCTP_AUTH_NEW_KEY:  This report indicates that a new key has been
+         made active (used for the first time by the peer) and is now
+         the active key.  The auth_keynumber field holds the user-
+         specified key number.
+
+      SCTP_AUTH_NO_AUTH:  This report indicates that the peer does not
+         support SCTP authentication as defined in [RFC4895].
+
+      SCTP_AUTH_FREE_KEY:  This report indicates that the SCTP
+         implementation will no longer use the key identifier specified
+         in auth_keynumber.
+
+   auth_assoc_id:  The auth_assoc_id field holds the identifier for the
+      association.  All notifications for a given association have the
+      same association identifier.  For a one-to-one style socket, this
+      field is ignored.
+
+6.1.9.  SCTP_SENDER_DRY_EVENT
+
+   When the SCTP stack has no more user data to send or retransmit, this
+   notification is given to the user.  Also, at the time when a user app
+   subscribes to this event, if there is no data to be sent or
+   retransmit, the stack will immediately send up this notification.
+
+   struct sctp_sender_dry_event {
+     uint16_t sender_dry_type;
+     uint16_t sender_dry_flags;
+     uint32_t sender_dry_length;
+     sctp_assoc_t sender_dry_assoc_id;
+   };
+
+   sender_dry_type:  This field should be set to SCTP_SENDER_DRY_EVENT.
+
+   sender_dry_flags:  This field is currently unused.
+
+
+
+Stewart, et al.               Informational                    [Page 51]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   sender_dry_length:  This field is the total length of the
+      notification data, including the notification header.  It will
+      generally be sizeof(struct sctp_sender_dry_event).
+
+   sender_dry_assoc_id:  The sender_dry_assoc_id field holds the
+      identifier for the association.  All notifications for a given
+      association have the same association identifier.  For a one-to-
+      one style socket, this field is ignored.
+
+6.1.10.  SCTP_NOTIFICATIONS_STOPPED_EVENT
+
+   SCTP notifications, when subscribed to, are reliable.  They are
+   always delivered as long as there is space in the socket receive
+   buffer.  However, if an implementation experiences a notification
+   storm, it may run out of socket buffer space.  When this occurs, it
+   may wish to disable notifications.  If the implementation chooses to
+   do this, it will append a final notification
+   SCTP_NOTIFICATIONS_STOPPED_EVENT.  This notification is a union
+   sctp_notification, where only the sctp_tlv structure (see the union
+   above) is used.  It only contains this type in the sn_type field, the
+   sn_length field set to the size of an sctp_tlv structure, and the
+   sn_flags set to 0.  If an application receives this notification, it
+   will need to re-subscribe to any notifications of interest to it,
+   except for the sctp_data_io_event (note that SCTP_EVENTS is
+   deprecated).
+
+   An endpoint is automatically subscribed to this event as soon as it
+   is subscribed to any event other than data io events.
+
+6.1.11.  SCTP_SEND_FAILED_EVENT
+
+   If SCTP cannot deliver a message, it can return back the message as a
+   notification if the SCTP_SEND_FAILED_EVENT event is enabled.  The
+   notification has the following format:
+
+   struct sctp_send_failed_event {
+     uint16_t ssfe_type;
+     uint16_t ssfe_flags;
+     uint32_t ssfe_length;
+     uint32_t ssfe_error;
+     struct sctp_sndinfo ssfe_info;
+     sctp_assoc_t ssfe_assoc_id;
+     uint8_t  ssfe_data[];
+   };
+
+
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 52]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   ssfe_type:  This field should be set to SCTP_SEND_FAILED_EVENT.
+
+   ssfe_flags:  The flag value will take one of the following values:
+
+      SCTP_DATA_UNSENT:  This value indicates that the data was never
+         put on the wire.
+
+      SCTP_DATA_SENT:  This value indicates that the data was put on the
+         wire.  Note that this does not necessarily mean that the data
+         was (or was not) successfully delivered.
+
+   ssfe_length:  This field is the total length of the notification
+      data, including the notification header and the payload in
+      ssf_data.
+
+   ssfe_error:  This value represents the reason why the send failed,
+      and if set, will be an SCTP protocol error code as defined in
+      Section 3.3.10 of [RFC4960].
+
+   ssfe_info:  This field includes the ancillary data (struct
+      sctp_sndinfo) used to send the undelivered message.  Regardless of
+      whether ancillary data is used or not, the ssfe_info.sinfo_flags
+      field indicates whether the complete message or only part of the
+      message is returned in ssf_data.  If only part of the message is
+      returned, it means that the part that is not present has been sent
+      successfully to the peer.
+
+      If the complete message cannot be sent, the SCTP_DATA_NOT_FRAG
+      flag is set in ssfe_info.sinfo_flags.  If the first part of the
+      message is sent successfully, SCTP_DATA_LAST_FRAG is set.  This
+      means that the tail end of the message is returned in ssf_data.
+
+   ssfe_assoc_id:  The ssfe_assoc_id field, ssf_assoc_id, holds the
+      identifier for the association.  All notifications for a given
+      association have the same association identifier.  For a one-to-
+      one style socket, this field is ignored.
+
+   ssfe_data:  The undelivered message or part of the undelivered
+      message will be present in the ssf_data field.  Note that the
+      ssf_info.sinfo_flags field as noted above should be used to
+      determine whether a complete message or just a piece of the
+      message is present.  Note that only user data is present in this
+      field; any chunk headers or SCTP common headers must be removed by
+      the SCTP stack.
+
+
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 53]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+6.2.  Notification Interest Options
+
+6.2.1.  SCTP_EVENTS Option - DEPRECATED
+
+   Please note that this option is deprecated.  Use the SCTP_EVENT
+   option described in Section 6.2.2 instead.
+
+   To receive SCTP event notifications, an application registers its
+   interest by setting the SCTP_EVENTS socket option.  The application
+   then uses recvmsg() to retrieve notifications.  A notification is
+   stored in the data part (msg_iov) of the msghdr structure.  The
+   socket option uses the following structure:
+
+   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_sender_dry_event;
+   };
+
+   sctp_data_io_event:  Setting this flag to 1 will cause the reception
+      of SCTP_SNDRCV information on a per-message basis.  The
+      application will need to use the recvmsg() interface so that it
+      can receive the event information contained in the msg_control
+      field.  Setting the flag to 0 will disable the reception of the
+      message control information.  Note that this flag is not really a
+      notification and is stored in the ancillary data (msg_control),
+      not in the data part (msg_iov).
+
+   sctp_association_event:  Setting this flag to 1 will enable the
+      reception of association event notifications.  Setting the flag to
+      0 will disable association event notifications.
+
+   sctp_address_event:  Setting this flag to 1 will enable the reception
+      of address event notifications.  Setting the flag to 0 will
+      disable address event notifications.
+
+   sctp_send_failure_event:  Setting this flag to 1 will enable the
+      reception of send failure event notifications.  Setting the flag
+      to 0 will disable send failure event notifications.
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 54]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   sctp_peer_error_event:  Setting this flag to 1 will enable the
+      reception of peer error event notifications.  Setting the flag to
+      0 will disable peer error event notifications.
+
+   sctp_shutdown_event:  Setting this flag to 1 will enable the
+      reception of shutdown event notifications.  Setting the flag to 0
+      will disable shutdown event notifications.
+
+   sctp_partial_delivery_event:  Setting this flag to 1 will enable the
+      reception of partial delivery event notifications.  Setting the
+      flag to 0 will disable partial delivery event notifications.
+
+   sctp_adaptation_layer_event:  Setting this flag to 1 will enable the
+      reception of adaptation layer event notifications.  Setting the
+      flag to 0 will disable adaptation layer event notifications.
+
+   sctp_authentication_event:  Setting this flag to 1 will enable the
+      reception of authentication layer event notifications.  Setting
+      the flag to 0 will disable authentication layer event
+      notifications.
+
+   sctp_sender_dry_event:  Setting this flag to 1 will enable the
+      reception of sender dry event notifications.  Setting the flag to
+      0 will disable sender dry event notifications.
+
+   An example where an application would like to receive data_io_events
+   and association_events but no others would be as follows:
+
+   {
+     struct sctp_event_subscribe events;
+
+     memset(&events, 0, sizeof(events));
+
+     events.sctp_data_io_event = 1;
+     events.sctp_association_event = 1;
+
+     setsockopt(sd, IPPROTO_SCTP, SCTP_EVENTS, &events, sizeof(events));
+   }
+
+   Note that for one-to-many style SCTP sockets, the caller of recvmsg()
+   receives ancillary data and notifications for all associations bound
+   to the file descriptor.  For one-to-one style SCTP sockets, the
+   caller receives ancillary data and notifications only for the single
+   association bound to the file descriptor.
+
+   By default, both the one-to-one style and the one-to-many style
+   socket do not subscribe to any notification.
+
+
+
+
+Stewart, et al.               Informational                    [Page 55]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+6.2.2.  SCTP_EVENT Option
+
+   The SCTP_EVENTS socket option has one issue for future compatibility.
+   As new features are added, the structure (sctp_event_subscribe) must
+   be expanded.  This can cause an application binary interface (ABI)
+   issue unless an implementation has added padding at the end of the
+   structure.  To avoid this problem, SCTP_EVENTS has been deprecated
+   and a new socket option SCTP_EVENT has taken its place.  The option
+   is used with the following structure:
+
+   struct sctp_event {
+           sctp_assoc_t se_assoc_id;
+           uint16_t     se_type;
+           uint8_t      se_on;
+   };
+
+   se_assoc_id:  The se_assoc_id field is ignored for one-to-one style
+      sockets.  For one-to-many style sockets, this field can be a
+      particular association identifier or SCTP_{FUTURE|CURRENT|
+      ALL}_ASSOC.
+
+   se_type:  The se_type field can be filled with any value that would
+      show up in the respective sn_type field (in the sctp_tlv structure
+      of the notification).
+
+   se_on:  The se_on field is set to 1 to turn on an event and set to 0
+      to turn off an event.
+
+   To use this option, the user fills in this structure and then calls
+   setsockopt() to turn on or off an individual event.  The following is
+   an example use of this option:
+
+   {
+     struct sctp_event event;
+
+     memset(&event, 0, sizeof(event));
+
+     event.se_assoc_id = SCTP_FUTURE_ASSOC;
+     event.se_type = SCTP_SENDER_DRY_EVENT;
+     event.se_on = 1;
+     setsockopt(sd, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(event));
+   }
+
+   By default, both the one-to-one style and the one-to-many style
+   socket do not subscribe to any notification.
+
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 56]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+7.  Common Operations for Both Styles
+
+7.1.  send(), recv(), sendto(), and recvfrom()
+
+   Applications can use send() and sendto() to transmit data to the peer
+   of an SCTP endpoint.  recv() and recvfrom() can be used to receive
+   data from the peer.
+
+   The function prototypes are
+
+   ssize_t send(int sd,
+                const void *msg,
+                size_t len,
+                int flags);
+
+   ssize_t sendto(int sd,
+                  const void *msg,
+                  size_t len,
+                  int flags,
+                  const struct sockaddr *to,
+                  socklen_t tolen);
+
+   ssize_t recv(int sd,
+                void *buf,
+                size_t len,
+                int flags);
+
+   ssize_t recvfrom(int sd,
+                    void *buf,
+                    size_t len,
+                    int flags,
+                    struct sockaddr *from,
+                    socklen_t *fromlen);
+
+   and the arguments are
+
+   sd:  The socket descriptor of an SCTP endpoint.
+
+   msg:  The message to be sent.
+
+   len:  The size of the message or the size of the buffer.
+
+   to:  One of the peer addresses of the association to be used to send
+      the message.
+
+   tolen:  The size of the address.
+
+   buf:  The buffer to store a received message.
+
+
+
+Stewart, et al.               Informational                    [Page 57]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   from:  The buffer to store the peer address used to send the received
+      message.
+
+   fromlen:  The size of the from address.
+
+   flags:  (described below).
+
+   These calls give access to only basic SCTP protocol features.  If
+   either peer in the association uses multiple streams, or sends
+   unordered data, these calls will usually be inadequate and may
+   deliver the data in unpredictable ways.
+
+   SCTP has the concept of multiple streams in one association.  The
+   above calls do not allow the caller to specify on which stream a
+   message should be sent.  The system uses stream 0 as the default
+   stream for send() and sendto().  recv() and recvfrom() return data
+   from any stream, but the caller cannot distinguish the different
+   streams.  This may result in data seeming to arrive out of order.
+   Similarly, if a DATA chunk is sent unordered, recv() and recvfrom()
+   provide no indication.
+
+   SCTP is message based.  The msg buffer above in send() and sendto()
+   is considered to be a single message.  This means that if the caller
+   wants to send a message that is composed by several buffers, the
+   caller needs to combine them before calling send() or sendto().
+   Alternately, the caller can use sendmsg() to do that without
+   combining them.  Sending a message using send() or sendto() is atomic
+   unless explicit EOR marking is enabled on the socket specified by sd.
+   Using sendto() on a non-connected one-to-one style socket for
+   implicit connection setup may or may not work, depending on the SCTP
+   implementation.  recv() and recvfrom() cannot distinguish message
+   boundaries (i.e., there is no way to observe the MSG_EOR flag to
+   detect partial delivery).
+
+   When receiving, if the buffer supplied is not large enough to hold a
+   complete message, the receive call acts like a stream socket and
+   returns as much data as will fit in the buffer.
+
+   Note that the send() and recv() calls may not be used for a one-to-
+   many style socket.
+
+   Note that if an application calls a send() or sendto() function with
+   no user data, the SCTP implementation should reject the request with
+   an appropriate error message.  An implementation is not allowed to
+   send a DATA chunk with no user data [RFC4960].
+
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 58]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+7.2.  setsockopt() and getsockopt()
+
+   Applications use setsockopt() and getsockopt() to set or retrieve
+   socket options.  Socket options are used to change the default
+   behavior of socket calls.  They are described in Section 8.
+
+   The function prototypes are
+
+   int getsockopt(int sd,
+                  int level,
+                  int optname,
+                  void *optval,
+                  socklen_t *optlen);
+
+   and
+
+   int setsockopt(int sd,
+                  int level,
+                  int optname,
+                  const void *optval,
+                  socklen_t optlen);
+
+   and the arguments are
+
+   sd:  The socket descriptor.
+
+   level:  Set to IPPROTO_SCTP for all SCTP options.
+
+   optname:  The option name.
+
+   optval:  The buffer to store the value of the option.
+
+   optlen:  The size of the buffer (or the length of the option
+      returned).
+
+   These functions return 0 on success and -1 in case of an error.
+
+   All socket options set on a one-to-one style listening socket also
+   apply to all future accepted sockets.  For one-to-many style sockets,
+   often a socket option will pass a structure that includes an assoc_id
+   field.  This field can be filled with the association identifier of a
+   particular association and unless otherwise specified can be filled
+   with one of the following constants:
+
+   SCTP_FUTURE_ASSOC:  Specifies that only future associations created
+      after this socket option will be affected by this call.
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 59]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   SCTP_CURRENT_ASSOC:  Specifies that only currently existing
+      associations will be affected by this call, and future
+      associations will still receive the previous default value.
+
+   SCTP_ALL_ASSOC:  Specifies that all current and future associations
+      will be affected by this call.
+
+7.3.  read() and write()
+
+   Applications can use read() and write() to receive and send data from
+   and to a peer.  They have the same semantics as recv() and send(),
+   except that the flags parameter cannot be used.
+
+7.4.  getsockname()
+
+   Applications use getsockname() to retrieve the locally bound socket
+   address of the specified socket.  This is especially useful if the
+   caller let SCTP choose a local port.  This call is for single-homed
+   endpoints.  It does not work well with multi-homed endpoints.  See
+   Section 9.5 for a multi-homed version of the call.
+
+   The function prototype is
+
+   int getsockname(int sd,
+                   struct sockaddr *address,
+                   socklen_t *len);
+
+   and the arguments are
+
+   sd:  The socket descriptor to be queried.
+
+   address:  On return, one locally bound address (chosen by the SCTP
+      stack) is stored in this buffer.  If the socket is an IPv4 socket,
+      the address will be IPv4.  If the socket is an IPv6 socket, the
+      address will be either an IPv6 or IPv4 address.
+
+   len:  The caller should set the length of the address here.  On
+      return, this is set to the length of the returned address.
+
+   getsockname() returns 0 on success and -1 in case of an error.
+
+   If the actual length of the address is greater than the length of the
+   supplied sockaddr structure, the stored address will be truncated.
+
+   If the socket has not been bound to a local name, the value stored in
+   the object pointed to by address is unspecified.
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 60]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+7.5.  Implicit Association Setup
+
+   The application can begin sending and receiving data using the
+   sendmsg()/recvmsg() or sendto()/recvfrom() calls, without going
+   through any explicit association setup procedures (i.e., no connect()
+   calls required).
+
+   Whenever sendmsg() or sendto() is called and the SCTP stack at the
+   sender finds that no association exists between the sender and the
+   intended receiver (identified by the address passed either in the
+   msg_name field of the msghdr structure in the sendmsg() call or the
+   dest_addr field in the sendto() call), the SCTP stack will
+   automatically set up an association to the intended receiver.
+
+   Upon successful association setup, an SCTP_COMM_UP notification will
+   be dispatched to the socket at both the sender and receiver side.
+   This notification can be read by the recvmsg() system call (see
+   Section 3.1.4).
+
+   Note that if the SCTP stack at the sender side supports bundling, the
+   first user message may be bundled with the COOKIE ECHO message
+   [RFC4960].
+
+   When the SCTP stack sets up a new association implicitly, the
+   SCTP_INIT type ancillary data may also be passed along (see
+   Section 5.3.1 for details of the data structures) to change some
+   parameters used in setting up a new association.
+
+   If this information is not present in the sendmsg() call, or if the
+   implicit association setup is triggered by a sendto() call, the
+   default association initialization parameters will be used.  These
+   default association parameters may be set with respective
+   setsockopt() calls or be left to the system defaults.
+
+   Implicit association setup cannot be initiated by send() calls.
+
+8.  Socket Options
+
+   The following subsection describes various SCTP-level socket options
+   that are common to both styles.  SCTP associations can be
+   multi-homed.  Therefore, certain option parameters include a
+   sockaddr_storage structure to select to which peer address the option
+   should be applied.
+
+   For the one-to-many style sockets, an sctp_assoc_t (association
+   identifier) parameter is used to identify the association instance
+   that the operation affects.  So it must be set when using this style.
+
+
+
+
+Stewart, et al.               Informational                    [Page 61]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   For the one-to-one style sockets and branched-off one-to-many style
+   sockets (see Section 9.2), this association ID parameter is ignored.
+
+   Note that socket- or IP-level options are set or retrieved per
+   socket.  This means that for one-to-many style sockets, the options
+   will be applied to all associations (similar to using SCTP_ALL_ASSOC
+   as the association identifier) belonging to the socket.  For the one-
+   to-one style, these options will be applied to all peer addresses of
+   the association controlled by the socket.  Applications should be
+   careful in setting those options.
+
+   For some IP stacks, getsockopt() is read-only, so a new interface
+   will be needed when information must be passed both into and out of
+   the SCTP stack.  The syntax for sctp_opt_info() is
+
+   int sctp_opt_info(int sd,
+                     sctp_assoc_t id,
+                     int opt,
+                     void *arg,
+                     socklen_t *size);
+
+   The sctp_opt_info() call is a replacement for getsockopt() only and
+   will not set any options associated with the specified socket.  A
+   setsockopt() call must be used to set any writable option.
+
+   For one-to-many style sockets, id specifies the association to query.
+   For one-to-one style sockets, id is ignored.  For one-to-many style
+   sockets, any association identifier in the structure provided as arg
+   is ignored, and id takes precedence.
+
+   Note that SCTP_CURRENT_ASSOC and SCTP_ALL_ASSOC cannot be used with
+   sctp_opt_info() or in getsockopt() calls.  Using them will result in
+   an error (returning -1 and errno set to EINVAL).  SCTP_FUTURE_ASSOC
+   can be used to query information for future associations.
+
+   The field opt specifies which SCTP socket option to get.  It can get
+   any socket option currently supported that requests information
+   (either read/write options or read-only) such as
+
+   SCTP_RTOINFO
+
+   SCTP_ASSOCINFO
+
+   SCTP_PRIMARY_ADDR
+
+   SCTP_PEER_ADDR_PARAMS
+
+   SCTP_DEFAULT_SEND_PARAM
+
+
+
+Stewart, et al.               Informational                    [Page 62]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   SCTP_MAX_SEG
+
+   SCTP_AUTH_ACTIVE_KEY
+
+   SCTP_DELAYED_SACK
+
+   SCTP_MAX_BURST
+
+   SCTP_CONTEXT
+
+   SCTP_EVENT
+
+   SCTP_DEFAULT_SNDINFO
+
+   SCTP_DEFAULT_PRINFO
+
+   SCTP_STATUS
+
+   SCTP_GET_PEER_ADDR_INFO
+
+   SCTP_PEER_AUTH_CHUNKS
+
+   SCTP_LOCAL_AUTH_CHUNKS
+
+   The arg field is an option-specific structure buffer provided by the
+   caller.  See the rest of this section for more information on these
+   options and option-specific structures.
+
+   sctp_opt_info() returns 0 on success, or on failure returns -1 and
+   sets errno to the appropriate error code.
+
+8.1.  Read/Write Options
+
+8.1.1.  Retransmission Timeout Parameters (SCTP_RTOINFO)
+
+   The protocol parameters used to initialize and limit the
+   retransmission timeout (RTO) are tunable.  See [RFC4960] for more
+   information on how these parameters are used in RTO calculation.
+
+   The following structure is used to access and modify these
+   parameters:
+
+   struct sctp_rtoinfo {
+     sctp_assoc_t srto_assoc_id;
+     uint32_t srto_initial;
+     uint32_t srto_max;
+     uint32_t srto_min;
+   };
+
+
+
+Stewart, et al.               Informational                    [Page 63]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   srto_assoc_id:  This parameter is ignored for one-to-one style
+      sockets.  For one-to-many style sockets, the application may fill
+      in an association identifier or SCTP_FUTURE_ASSOC.  It is an error
+      to use SCTP_{CURRENT|ALL}_ASSOC in srto_assoc_id.
+
+   srto_initial:  This parameter contains the initial RTO value.
+
+   srto_max and srto_min:  These parameters contain the maximum and
+      minimum bounds for all RTOs.
+
+   All times are given in milliseconds.  A value of 0, when modifying
+   the parameters, indicates that the current value should not be
+   changed.
+
+   To access or modify these parameters, the application should call
+   getsockopt() or setsockopt(), respectively, with the option name
+   SCTP_RTOINFO.
+
+8.1.2.  Association Parameters (SCTP_ASSOCINFO)
+
+   This option is used to both examine and set various association and
+   endpoint parameters.  See [RFC4960] for more information on how these
+   parameters are used.
+
+   The following structure is used to access and modify these
+   parameters:
+
+   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;
+   };
+
+   sasoc_assoc_id:  This parameter is ignored for one-to-one style
+      sockets.  For one-to-many style sockets, the application may fill
+      in an association identifier or SCTP_FUTURE_ASSOC.  It is an error
+      to use SCTP_{CURRENT|ALL}_ASSOC in sasoc_assoc_id.
+
+   sasoc_asocmaxrxt:  This parameter contains the maximum retransmission
+      attempts to make for the association.
+
+   sasoc_number_peer_destinations:  This parameter is the number of
+      destination addresses that the peer has.
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 64]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   sasoc_peer_rwnd:  This parameter holds the current value of the
+      peer's rwnd (reported in the last selective acknowledgment (SACK))
+      minus any outstanding data (i.e., data in flight).
+
+   sasoc_local_rwnd:  This parameter holds the last reported rwnd that
+      was sent to the peer.
+
+   sasoc_cookie_life:  This parameter is the association's cookie life
+      value used when issuing cookies.
+
+   The value of sasoc_peer_rwnd is meaningless when examining endpoint
+   information (i.e., it is only valid when examining information on a
+   specific association).
+
+   All time values are given in milliseconds.  A value of 0, when
+   modifying the parameters, indicates that the current value should not
+   be changed.
+
+   The values of sasoc_asocmaxrxt and sasoc_cookie_life may be set on
+   either an endpoint or association basis.  The rwnd and destination
+   counts (sasoc_number_peer_destinations, sasoc_peer_rwnd,
+   sasoc_local_rwnd) are not settable, and any value placed in these is
+   ignored.
+
+   To access or modify these parameters, the application should call
+   getsockopt() or setsockopt(), respectively, with the option name
+   SCTP_ASSOCINFO.
+
+   The maximum number of retransmissions before an address is considered
+   unreachable is also tunable, but is address-specific, so it is
+   covered in a separate option.  If an application attempts to set the
+   value of the association's maximum retransmission parameter to more
+   than the sum of all maximum retransmission parameters, setsockopt()
+   may return an error.  The reason for this, from Section 8.2 of
+   [RFC4960], is as follows:
+
+      Note: When configuring the SCTP endpoint, the user should avoid
+      having the value of 'Association.Max.Retrans' (sasoc_maxrxt in
+      this option) larger than the summation of the 'Path.Max.Retrans'
+      (see spp_pathmaxrxt in Section 8.1.12) of all of the destination
+      addresses for the remote endpoint.  Otherwise, all of the
+      destination addresses may become inactive while the endpoint still
+      considers the peer endpoint reachable.
+
+
+
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 65]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+8.1.3.  Initialization Parameters (SCTP_INITMSG)
+
+   Applications can specify protocol parameters for the default
+   association initialization.  The structure used to access and modify
+   these parameters is defined in Section 5.3.1.  The option name
+   argument to setsockopt() and getsockopt() is SCTP_INITMSG.
+
+   Setting initialization parameters is effective only on an unconnected
+   socket (for one-to-many style sockets, only future associations are
+   affected by the change).
+
+8.1.4.  SO_LINGER
+
+   An application can use this option to perform the SCTP ABORT
+   primitive.  This option affects all associations related to the
+   socket.
+
+   The linger option structure is
+
+   struct linger {
+     int l_onoff;  /* option on/off */
+     int l_linger; /* linger time   */
+   };
+
+   To enable the option, set l_onoff to 1.  If the l_linger value is set
+   to 0, calling close() is the same as the ABORT primitive.  If the
+   value is set to a negative value, the setsockopt() call will return
+   an error.  If the value is set to a positive value linger_time, the
+   close() can be blocked for at most linger_time.  Please note that the
+   time unit is in seconds, according to POSIX, but might be different
+   on specific platforms.  If the graceful shutdown phase does not
+   finish during this period, close() will return, but the graceful
+   shutdown phase will continue in the system.
+
+   Note that this is a socket-level option, not an SCTP-level option.
+   When using this option, an application must specify a level of
+   SOL_SOCKET in the call.
+
+8.1.5.  SCTP_NODELAY
+
+   This option turns on/off any Nagle-like algorithm.  This means that
+   packets are generally sent as soon as possible, and no unnecessary
+   delays are introduced, at the cost of more packets in the network.
+   In particular, not using any Nagle-like algorithm might reduce the
+   bundling of small user messages in cases where this would require an
+   additional delay.
+
+   Turning this option on disables any Nagle-like algorithm.
+
+
+
+Stewart, et al.               Informational                    [Page 66]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   This option expects an integer boolean flag, where a non-zero value
+   turns on the option, and a zero value turns off the option.
+
+8.1.6.  SO_RCVBUF
+
+   This option sets the receive buffer size in octets.  For SCTP one-to-
+   one style sockets, this option controls the receiver window size.
+   For one-to-many style sockets, the meaning is implementation
+   dependent.  It might control the receive buffer for each association
+   bound to the socket descriptor, or it might control the receive
+   buffer for the whole socket.  This option expects an integer.
+
+   Note that this is a socket-level option, not an SCTP-level option.
+   When using this option, an application must specify a level of
+   SOL_SOCKET in the call.
+
+8.1.7.  SO_SNDBUF
+
+   This option sets the send buffer size.  For SCTP one-to-one style
+   sockets, this option controls the amount of data SCTP may have
+   waiting in internal buffers to be sent.  This option therefore bounds
+   the maximum size of data that can be sent in a single send call.  For
+   one-to-many style sockets, the effect is the same, except that it
+   applies to one or all associations (see Section 3.3) bound to the
+   socket descriptor used in the setsockopt() or getsockopt() call.  The
+   option applies to each association's window size separately.  This
+   option expects an integer.
+
+   Note that this is a socket-level option, not an SCTP-level option.
+   When using this option, an application must specify a level of
+   SOL_SOCKET in the call.
+
+8.1.8.  Automatic Close of Associations (SCTP_AUTOCLOSE)
+
+   This socket option is applicable to the one-to-many style socket
+   only.  When set, it will cause associations that are idle for more
+   than the specified number of seconds to automatically close using the
+   graceful shutdown procedure.  An idle association is defined as an
+   association that has not sent or received user data.  The special
+   value of '0' indicates that no automatic close of any association
+   should be performed; this is the default value.  This option expects
+   an integer defining the number of seconds of idle time before an
+   association is closed.
+
+
+
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 67]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   An application using this option should enable the ability to receive
+   the association change notification.  This is the only mechanism by
+   which an application is informed about the closing of an association.
+   After an association is closed, the association identifier assigned
+   to it can be reused.  An application should be aware of this to avoid
+   the possible problem of sending data to an incorrect peer endpoint.
+
+8.1.9.  Set Primary Address (SCTP_PRIMARY_ADDR)
+
+   This option requests that the local SCTP stack uses the enclosed peer
+   address as the association's primary.  The enclosed address must be
+   one of the association peer's addresses.
+
+   The following structure is used to make a set peer primary request:
+
+   struct sctp_setprim {
+     sctp_assoc_t ssp_assoc_id;
+     struct sockaddr_storage ssp_addr;
+   };
+
+   ssp_assoc_id:  This parameter is ignored for one-to-one style
+      sockets.  For one-to-many style sockets, it identifies the
+      association for this request.  Note that the special sctp_assoc_t
+      SCTP_{FUTURE|ALL|CURRENT}_ASSOC are not allowed.
+
+   ssp_addr:  This parameter is the address to set as primary.  No
+      wildcard address is allowed.
+
+8.1.10.  Set Adaptation Layer Indicator (SCTP_ADAPTATION_LAYER)
+
+   This option requests that the local endpoint set the specified
+   Adaptation Layer Indication parameter for all future INIT and
+   INIT-ACK exchanges.
+
+   The following structure is used to access and modify this parameter:
+
+   struct sctp_setadaptation {
+     uint32_t   ssb_adaptation_ind;
+   };
+
+   ssb_adaptation_ind:  The adaptation layer indicator that will be
+      included in any outgoing Adaptation Layer Indication parameter.
+
+8.1.11.  Enable/Disable Message Fragmentation (SCTP_DISABLE_FRAGMENTS)
+
+   This option is an on/off flag and is passed as an integer, where a
+   non-zero is on and a zero is off.  If enabled, no SCTP message
+   fragmentation will be performed.  The effect of enabling this option
+
+
+
+Stewart, et al.               Informational                    [Page 68]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   is that if a message being sent exceeds the current Path MTU (PMTU)
+   size, the message will not be sent and instead an error will be
+   indicated to the user.  If this option is disabled (the default),
+   then a message exceeding the size of the PMTU will be fragmented and
+   reassembled by the peer.
+
+8.1.12.  Peer Address Parameters (SCTP_PEER_ADDR_PARAMS)
+
+   Applications can enable or disable heartbeats for any peer address of
+   an association, modify an address's heartbeat interval, force a
+   heartbeat to be sent immediately, and adjust the address's maximum
+   number of retransmissions sent before an address is considered
+   unreachable.
+
+   The following structure is used to access and modify an address's
+   parameters:
+
+   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_flags;
+     uint32_t spp_ipv6_flowlabel;
+     uint8_t  spp_dscp;
+   };
+
+   spp_assoc_id:  This parameter is ignored for one-to-one style
+      sockets.  For one-to-many style sockets, the application may fill
+      in an association identifier or SCTP_FUTURE_ASSOC for this query.
+      It is an error to use SCTP_{CURRENT|ALL}_ASSOC in spp_assoc_id.
+
+   spp_address:  This specifies which address is of interest.  If a
+      wildcard address is provided, it applies to all current and future
+      paths.
+
+   spp_hbinterval:  This contains the value of the heartbeat interval,
+      in milliseconds (HB.Interval in [RFC4960]).  Note that unless the
+      spp_flags field is set to SPP_HB_ENABLE, the value of this field
+      is ignored.  Note also that a value of zero indicates that the
+      current setting should be left unchanged.  To set an actual value
+      of zero, the SPP_HB_TIME_IS_ZERO flag should be used.  Even when
+      it is set to 0, it does not mean that SCTP will continuously send
+      out heartbeats, since the actual interval also includes the
+      current RTO and jitter (see Section 8.3 of [RFC4960]).
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 69]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   spp_pathmaxrxt:  This contains the maximum number of retransmissions
+      before this address shall be considered unreachable.  Note that a
+      value of zero indicates that the current setting should be left
+      unchanged.
+
+   spp_pathmtu:  This field contains the current Path MTU of the peer
+      address.  It is the number of bytes available in an SCTP packet
+      for chunks.  Providing a value of 0 does not change the current
+      setting.  If a positive value is provided and SPP_PMTUD_DISABLE is
+      set in the spp_flags field, the given value is used as the Path
+      MTU.  If SPP_PMTUD_ENABLE is set in the spp_flags field, the
+      spp_pathmtu field is ignored.
+
+   spp_flags:  These flags are used to control various features on an
+      association.  The flag field is a bitmask that may contain zero or
+      more of the following options:
+
+      SPP_HB_ENABLE:  This field enables heartbeats on the specified
+         address.
+
+      SPP_HB_DISABLE:  This field disables heartbeats on the specified
+         address.  Note that SPP_HB_ENABLE and SPP_HB_DISABLE are
+         mutually exclusive; only one of these two should be specified.
+         Enabling both fields will yield undetermined results.
+
+      SPP_HB_DEMAND:  This field requests that a user-initiated
+         heartbeat be made immediately.  This must not be used in
+         conjunction with a wildcard address.
+
+      SPP_HB_TIME_IS_ZERO:  This field specifies that the time for
+         heartbeat delay is to be set to 0 milliseconds.
+
+      SPP_PMTUD_ENABLE:  This field will enable PMTU discovery on the
+         specified address.
+
+      SPP_PMTUD_DISABLE:  This field will disable PMTU discovery on the
+         specified address.  Note that if the address field is empty,
+         then all addresses on the association are affected.  Note also
+         that SPP_PMTUD_ENABLE and SPP_PMTUD_DISABLE are mutually
+         exclusive.  Enabling both fields will yield undetermined
+         results.
+
+      SPP_IPV6_FLOWLABEL:  Setting this flag enables the setting of the
+         IPV6 flow label value.  The value is contained in the
+         spp_ipv6_flowlabel field.
+
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 70]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+         Upon retrieval, this flag will be set to indicate that the
+         spp_ipv6_flowlabel field has a valid value returned.  If a
+         specific destination address is set (in the spp_address field),
+         then the value returned is that of the address.  If just an
+         association is specified (and no address), then the
+         association's default flow label is returned.  If neither an
+         association nor a destination is specified, then the socket's
+         default flow label is returned.  For non-IPv6 sockets, this
+         flag will be left cleared.
+
+      SPP_DSCP:  Setting this flag enables the setting of the
+         Differentiated Services Code Point (DSCP) value associated with
+         either the association or a specific address.  The value is
+         obtained in the spp_dscp field.
+
+         Upon retrieval, this flag will be set to indicate that the
+         spp_dscp field has a valid value returned.  If a specific
+         destination address is set when called (in the spp_address
+         field), then that specific destination address's DSCP value is
+         returned.  If just an association is specified, then the
+         association's default DSCP is returned.  If neither an
+         association nor a destination is specified, then the socket's
+         default DSCP is returned.
+
+   spp_ipv6_flowlabel:  This field is used in conjunction with the
+      SPP_IPV6_FLOWLABEL flag and contains the IPv6 flow label.  The 20
+      least significant bits are used for the flow label.  This setting
+      has precedence over any IPv6-layer setting.
+
+   spp_dscp:  This field is used in conjunction with the SPP_DSCP flag
+      and contains the DSCP.  The 6 most significant bits are used for
+      the DSCP.  This setting has precedence over any IPv4- or IPv6-
+      layer setting.
+
+   Please note that changing the flow label or DSCP value will affect
+   all packets sent by the SCTP stack after setting these parameters.
+   The flow label might also be set via the sin6_flowinfo field of the
+   sockaddr_in6 structure.
+
+8.1.13.  Set Default Send Parameters (SCTP_DEFAULT_SEND_PARAM) -
+         DEPRECATED
+
+   Please note that this option is deprecated.  SCTP_DEFAULT_SNDINFO
+   (Section 8.1.31) should be used instead.
+
+   Applications that wish to use the sendto() system call may wish to
+   specify a default set of parameters that would normally be supplied
+   through the inclusion of ancillary data.  This socket option allows
+
+
+
+Stewart, et al.               Informational                    [Page 71]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   such an application to set the default sctp_sndrcvinfo structure.
+   The application that wishes to use this socket option simply passes
+   the sctp_sndrcvinfo structure (defined in Section 5.3.2) to this
+   call.  The input parameters accepted by this call include
+   sinfo_stream, sinfo_flags, sinfo_ppid, sinfo_context, and
+   sinfo_timetolive.  The sinfo_flags field is composed of a bitwise OR
+   of SCTP_UNORDERED, SCTP_EOF, and SCTP_SENDALL.  The sinfo_assoc_id
+   field specifies the association to which to apply the parameters.
+   For a one-to-many style socket, any of the predefined constants are
+   also allowed in this field.  The field is ignored for one-to-one
+   style sockets.
+
+8.1.14.  Set Notification and Ancillary Events (SCTP_EVENTS) -
+         DEPRECATED
+
+   This socket option is used to specify various notifications and
+   ancillary data the user wishes to receive.  Please see Section 6.2.1
+   for a full description of this option and its usage.  Note that this
+   option is considered deprecated and is present for backward
+   compatibility.  New applications should use the SCTP_EVENT option.
+   See Section 6.2.2 for a full description of that option as well.
+
+8.1.15.  Set/Clear IPv4 Mapped Addresses (SCTP_I_WANT_MAPPED_V4_ADDR)
+
+   This socket option is a boolean flag that turns on or off the mapping
+   of IPv4 addresses.  If this option is turned on, then IPv4 addresses
+   will be mapped to IPv6 representation.  If this option is turned off,
+   then no mapping will be done of IPv4 addresses, and a user will
+   receive both PF_INET6 and PF_INET type addresses on the socket.  See
+   [RFC3542] for more details on mapped IPv6 addresses.
+
+   If this socket option is used on a socket of type PF_INET, an error
+   is returned.
+
+   By default, this option is turned off and expects an integer to be
+   passed where a non-zero value turns on the option and a zero value
+   turns off the option.
+
+8.1.16.  Get or Set the Maximum Fragmentation Size (SCTP_MAXSEG)
+
+   This option will get or set the maximum size to put in any outgoing
+   SCTP DATA chunk.  If a message is larger than this maximum size, it
+   will be fragmented by SCTP into the specified size.  Note that the
+   underlying SCTP implementation may fragment into smaller sized chunks
+   when the PMTU of the underlying association is smaller than the value
+   set by the user.  The default value for this option is '0', which
+   indicates that the user is not limiting fragmentation and only the
+   PMTU will affect SCTP's choice of DATA chunk size.  Note also that
+
+
+
+Stewart, et al.               Informational                    [Page 72]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   values set larger than the maximum size of an IP datagram will
+   effectively let SCTP control fragmentation (i.e., the same as setting
+   this option to 0).
+
+   The following structure is used to access and modify this parameter:
+
+   struct sctp_assoc_value {
+     sctp_assoc_t assoc_id;
+     uint32_t assoc_value;
+   };
+
+   assoc_id:  This parameter is ignored for one-to-one style sockets.
+      For one-to-many style sockets, this parameter indicates upon which
+      association the user is performing an action.  It is an error to
+      use SCTP_{CURRENT|ALL}_ASSOC in assoc_id.
+
+   assoc_value:  This parameter specifies the maximum size in bytes.
+
+8.1.17.  Get or Set the List of Supported HMAC Identifiers
+         (SCTP_HMAC_IDENT)
+
+   This option gets or sets the list of Hashed Message Authentication
+   Code (HMAC) algorithms that the local endpoint requires the peer
+   to use.
+
+   The following structure is used to get or set these identifiers:
+
+   struct sctp_hmacalgo {
+     uint32_t shmac_number_of_idents;
+     uint16_t shmac_idents[];
+   };
+
+   shmac_number_of_idents:  This field gives the number of elements
+      present in the array shmac_idents.
+
+   shmac_idents:  This parameter contains an array of HMAC identifiers
+      that the local endpoint is requesting the peer to use, in priority
+      order.  The following identifiers are valid:
+
+      *  SCTP_AUTH_HMAC_ID_SHA1
+
+      *  SCTP_AUTH_HMAC_ID_SHA256
+
+   Note that the list supplied must include SCTP_AUTH_HMAC_ID_SHA1 and
+   may include any of the other values in its preferred order (lowest
+   list position has the highest preference in algorithm selection).
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 73]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   Note also that the lack of SCTP_AUTH_HMAC_ID_SHA1, or the inclusion
+   of an unknown HMAC identifier (including optional identifiers unknown
+   to the implementation), will cause the set option to fail and return
+   an error.
+
+8.1.18.  Get or Set the Active Shared Key (SCTP_AUTH_ACTIVE_KEY)
+
+   This option will get or set the active shared key to be used to build
+   the association shared key.
+
+   The following structure is used to access and modify these
+   parameters:
+
+   struct sctp_authkeyid {
+     sctp_assoc_t scact_assoc_id;
+     uint16_t scact_keynumber;
+   };
+
+   scact_assoc_id:  This parameter sets the active key of the specified
+      association.  The special SCTP_{FUTURE|CURRENT|ALL}_ASSOC can be
+      used.  For one-to-one style sockets, this parameter is ignored.
+      Note, however, that this option will set the active key on the
+      association if the socket is connected; otherwise, this option
+      will set the default active key for the endpoint.
+
+   scact_keynumber:  This parameter is the shared key identifier that
+      the application is requesting to become the active shared key to
+      be used for sending authenticated chunks.  The key identifier must
+      correspond to an existing shared key.  Note that shared key
+      identifier '0' defaults to a null key.
+
+   When used with setsockopt(), the SCTP implementation must use the
+   indicated shared key identifier for all messages being given to an
+   SCTP implementation via a send call after the setsockopt() call,
+   until changed again.  Therefore, the SCTP implementation must not
+   bundle user messages that should be authenticated using different
+   shared key identifiers.
+
+   Initially, the key with key identifier 0 is the active key.
+
+8.1.19.  Get or Set Delayed SACK Timer (SCTP_DELAYED_SACK)
+
+   This option will affect the way delayed SACKs are performed.  This
+   option allows the application to get or set the delayed SACK time, in
+   milliseconds.  It also allows changing the delayed SACK frequency.
+   Changing the frequency to 1 disables the delayed SACK algorithm.
+   Note that if sack_delay or sack_freq is 0 when setting this option,
+   the current values will remain unchanged.
+
+
+
+Stewart, et al.               Informational                    [Page 74]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   The following structure is used to access and modify these
+   parameters:
+
+   struct sctp_sack_info {
+     sctp_assoc_t sack_assoc_id;
+     uint32_t sack_delay;
+     uint32_t sack_freq;
+   };
+
+   sack_assoc_id:  This parameter is ignored for one-to-one style
+      sockets.  For one-to-many style sockets, this parameter indicates
+      upon which association the user is performing an action.  The
+      special SCTP_{FUTURE|CURRENT|ALL}_ASSOC can also be used.
+
+   sack_delay:  This parameter contains the number of milliseconds the
+      user is requesting that the delayed SACK timer be set to.  Note
+      that this value is defined in [RFC4960] to be between 200 and 500
+      milliseconds.
+
+   sack_freq:  This parameter contains the number of packets that must
+      be received before a SACK is sent without waiting for the delay
+      timer to expire.  The default value is 2; setting this value to 1
+      will disable the delayed SACK algorithm.
+
+8.1.20.  Get or Set Fragmented Interleave (SCTP_FRAGMENT_INTERLEAVE)
+
+   Fragmented interleave controls how the presentation of messages
+   occurs for the message receiver.  There are three levels of fragment
+   interleave defined.  Two of the levels affect one-to-one style
+   sockets, while one-to-many style sockets are affected by all three
+   levels.
+
+   This option takes an integer value.  It can be set to a value of 0,
+   1, or 2.  Attempting to set this level to other values will return an
+   error.
+
+   Setting the three levels provides the following receiver
+   interactions:
+
+   level 0:  Prevents the interleaving of any messages.  This means that
+      when a partial delivery begins, no other messages will be received
+      except the message being partially delivered.  If another message
+      arrives on a different stream (or association) that could be
+      delivered, it will be blocked waiting for the user to read all of
+      the partially delivered message.
+
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 75]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   level 1:  Allows interleaving of messages that are from different
+      associations.  For one-to-one style sockets, level 0 and level 1
+      thus have the same meaning, since a one-to-one style socket always
+      receives messages from the same association.  Note that setting a
+      one-to-many style socket to this level may cause multiple partial
+      deliveries from different associations, but for any given
+      association, only one message will be delivered until all parts of
+      a message have been delivered.  This means that one large message,
+      being read with an association identifier of "X", will block other
+      messages from association "X" from being delivered.
+
+   level 2:  Allows complete interleaving of messages.  This level
+      requires that the sender not only carefully observe the peer
+      association identifier (or address) but also pay careful attention
+      to the stream number.  With this option enabled, a partially
+      delivered message may begin being delivered for association "X"
+      stream "Y", and the next subsequent receive may return a message
+      from association "X" stream "Z".  Note that no other messages
+      would be delivered for association "X" stream "Y" until all of
+      stream "Y"'s partially delivered message was read.  Note that this
+      option also affects one-to-one style sockets.  Also note that for
+      one-to-many style sockets, not only another stream's message from
+      the same association may be delivered upon the next receive, but
+      some other association's message may also be delivered upon the
+      next receive.
+
+   An implementation should default one-to-many style sockets to level
+   1, because otherwise, it is possible that a peer could begin sending
+   a partial message and thus block all other peers from sending data.
+   However, a setting of level 2 requires that the application not only
+   be aware of the association (via the association identifier or peer's
+   address) but also the stream number.  The stream number is not
+   present unless the user has subscribed to the sctp_data_io_event (see
+   Section 6.2), which is deprecated, or has enabled the
+   SCTP_RECVRCVINFO socket option (see Section 8.1.29).  This is also
+   why we recommend that one-to-one style sockets be defaulted to level
+   0 (level 1 for one-to-one style sockets has no effect).  Note that an
+   implementation should return an error if an application attempts to
+   set the level to 2 and has not subscribed to the sctp_data_io_event
+   event, which is deprecated, or has enabled the SCTP_RECVRCVINFO
+   socket option.
+
+   For applications that have subscribed to events, those events appear
+   in the normal socket buffer data stream.  This means that unless the
+   user has set the fragmentation interleave level to 0, notifications
+   may also be interleaved with partially delivered messages.
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 76]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+8.1.21.  Set or Get the SCTP Partial Delivery Point
+         (SCTP_PARTIAL_DELIVERY_POINT)
+
+   This option will set or get the SCTP partial delivery point.  This
+   point is the size of a message where the partial delivery API will be
+   invoked to help free up rwnd space for the peer.  Setting this to a
+   lower value will cause partial deliveries to happen more often.  This
+   option expects an integer that sets or gets the partial delivery
+   point in bytes.  Note also that the call will fail if the user
+   attempts to set this value larger than the socket receive buffer
+   size.
+
+   Note that any single message having a length smaller than or equal to
+   the SCTP partial delivery point will be delivered in a single read
+   call as long as the user-provided buffer is large enough to hold the
+   message.
+
+8.1.22.  Set or Get the Use of Extended Receive Info
+         (SCTP_USE_EXT_RCVINFO) - DEPRECATED
+
+   This option will enable or disable the use of the extended version of
+   the sctp_sndrcvinfo structure.  If this option is disabled, then the
+   normal sctp_sndrcvinfo structure is returned in all receive message
+   calls.  If this option is enabled, then the sctp_extrcvinfo structure
+   is returned in all receive message calls.  The default is off.
+
+   Note that the sctp_extrcvinfo structure is never used in any send
+   call.
+
+   This option is present for compatibility with older applications and
+   is deprecated.  Future applications should use SCTP_NXTINFO to
+   retrieve this same information via ancillary data.
+
+8.1.23.  Set or Get the Auto ASCONF Flag (SCTP_AUTO_ASCONF)
+
+   This option will enable or disable the use of the automatic
+   generation of ASCONF chunks to add and delete addresses to an
+   existing association.  Note that this option has two caveats, namely
+   a) it only affects sockets that are bound to all addresses available
+   to the SCTP stack, and b) the system administrator may have an
+   overriding control that turns the ASCONF feature off no matter what
+   setting the socket option may have.
+
+   This option expects an integer boolean flag, where a non-zero value
+   turns on the option, and a zero value turns off the option.
+
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 77]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+8.1.24.  Set or Get the Maximum Burst (SCTP_MAX_BURST)
+
+   This option will allow a user to change the maximum burst of packets
+   that can be emitted by this association.  Note that the default value
+   is 4, and some implementations may restrict this setting so that it
+   can only be lowered to positive values.
+
+   To set or get this option, the user fills in the following structure:
+
+   struct sctp_assoc_value {
+     sctp_assoc_t assoc_id;
+     uint32_t assoc_value;
+   };
+
+   assoc_id:  This parameter is ignored for one-to-one style sockets.
+      For one-to-many style sockets, this parameter indicates upon which
+      association the user is performing an action.  The special
+      SCTP_{FUTURE|CURRENT|ALL}_ASSOC can also be used.
+
+   assoc_value:  This parameter contains the maximum burst.  Setting the
+      value to 0 disables burst mitigation.
+
+8.1.25.  Set or Get the Default Context (SCTP_CONTEXT)
+
+   The context field in the sctp_sndrcvinfo structure is normally only
+   used when a failed message is retrieved holding the value that was
+   sent down on the actual send call.  This option allows the setting,
+   on an association basis, of a default context that will be received
+   on reading messages from the peer.  This is especially helpful for an
+   application when using one-to-many style sockets to keep some
+   reference to an internal state machine that is processing messages on
+   the association.  Note that the setting of this value only affects
+   received messages from the peer and does not affect the value that is
+   saved with outbound messages.
+
+   To set or get this option, the user fills in the following structure:
+
+   struct sctp_assoc_value {
+     sctp_assoc_t assoc_id;
+     uint32_t assoc_value;
+   };
+
+   assoc_id:  This parameter is ignored for one-to-one style sockets.
+      For one-to-many style sockets, this parameter indicates upon which
+      association the user is performing an action.  The special
+      SCTP_{FUTURE|CURRENT|ALL}_ASSOC can also be used.
+
+   assoc_value:  This parameter contains the context.
+
+
+
+Stewart, et al.               Informational                    [Page 78]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+8.1.26.  Enable or Disable Explicit EOR Marking (SCTP_EXPLICIT_EOR)
+
+   This boolean flag is used to enable or disable explicit end of record
+   (EOR) marking.  When this option is enabled, a user may make multiple
+   send system calls to send a record and must indicate that they are
+   finished sending a particular record by including the SCTP_EOR flag.
+   If this boolean flag is disabled, then each individual send system
+   call is considered to have an SCTP_EOR indicator set on it implicitly
+   without the user having to explicitly add this flag.  The default
+   is off.
+
+   This option expects an integer boolean flag, where a non-zero value
+   turns on the option, and a zero value turns off the option.
+
+8.1.27.  Enable SCTP Port Reusage (SCTP_REUSE_PORT)
+
+   This option only supports one-to-one style SCTP sockets.  If used on
+   a one-to-many style SCTP socket, an error is indicated.
+
+   This option expects an integer boolean flag, where a non-zero value
+   turns on the option, and a zero value turns off the option.
+
+   This socket option must not be used after calling bind() or
+   sctp_bindx() for a one-to-one style SCTP socket.  If using bind() or
+   sctp_bindx() on a socket with the SCTP_REUSE_PORT option, all other
+   SCTP sockets bound to the same port must have set the SCTP_REUSE_PORT
+   option.  Calling bind() or sctp_bindx() for a socket without having
+   set the SCTP_REUSE_PORT option will fail if there are other sockets
+   bound to the same port.  At most one socket being bound to the same
+   port may be listening.
+
+   It should be noted that the behavior of the socket-level socket
+   option to reuse ports and/or addresses for SCTP sockets is
+   unspecified.
+
+8.1.28.  Set Notification Event (SCTP_EVENT)
+
+   This socket option is used to set a specific notification option.
+   Please see Section 6.2.2 for a full description of this option and
+   its usage.
+
+8.1.29.  Enable or Disable the Delivery of SCTP_RCVINFO as Ancillary
+         Data (SCTP_RECVRCVINFO)
+
+   Setting this option specifies that SCTP_RCVINFO (defined in
+   Section 5.3.5) is returned as ancillary data by recvmsg().
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 79]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   This option expects an integer boolean flag, where a non-zero value
+   turns on the option, and a zero value turns off the option.
+
+8.1.30.  Enable or Disable the Delivery of SCTP_NXTINFO as Ancillary
+         Data (SCTP_RECVNXTINFO)
+
+   Setting this option specifies that SCTP_NXTINFO (defined in
+   Section 5.3.6) is returned as ancillary data by recvmsg().
+
+   This option expects an integer boolean flag, where a non-zero value
+   turns on the option, and a zero value turns off the option.
+
+8.1.31.  Set Default Send Parameters (SCTP_DEFAULT_SNDINFO)
+
+   Applications that wish to use the sendto() system call may wish to
+   specify a default set of parameters that would normally be supplied
+   through the inclusion of ancillary data.  This socket option allows
+   such an application to set the default sctp_sndinfo structure.  The
+   application that wishes to use this socket option simply passes the
+   sctp_sndinfo structure (defined in Section 5.3.4) to this call.  The
+   input parameters accepted by this call include snd_sid, snd_flags,
+   snd_ppid, and snd_context.  The snd_flags parameter is composed of a
+   bitwise OR of SCTP_UNORDERED, SCTP_EOF, and SCTP_SENDALL.  The
+   snd_assoc_id field specifies the association to which to apply the
+   parameters.  For a one-to-many style socket, any of the predefined
+   constants are also allowed in this field.  The field is ignored for
+   one-to-one style sockets.
+
+8.1.32.  Set Default PR-SCTP Parameters (SCTP_DEFAULT_PRINFO)
+
+   This option sets and gets the default parameters for PR-SCTP.  They
+   can be overwritten by specific information provided in send calls.
+
+   The following structure is used to access and modify these
+   parameters:
+
+   struct sctp_default_prinfo {
+     uint16_t pr_policy;
+     uint32_t pr_value;
+     sctp_assoc_t pr_assoc_id;
+   };
+
+   pr_policy:  This field is the same as that described in
+      Section 5.3.7.
+
+   pr_value:  This field is the same as that described in Section 5.3.7.
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 80]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   pr_assoc_id:  This field is ignored for one-to-one style sockets.
+      For one-to-many style sockets, pr_assoc_id can be a particular
+      association identifier or SCTP_{FUTURE|CURRENT|ALL}_ASSOC.
+
+8.2.  Read-Only Options
+
+   The options defined in this subsection are read-only.  Using this
+   option in a setsockopt() call will result in an error indicating
+   EOPNOTSUPP.
+
+8.2.1.  Association Status (SCTP_STATUS)
+
+   Applications can retrieve current status information about an
+   association, including association state, peer receiver window size,
+   number of unacknowledged DATA chunks, and number of DATA chunks
+   pending receipt.  This information is read-only.
+
+   The following structure is used to access this information:
+
+   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;
+   };
+
+   sstat_assoc_id:  This parameter is ignored for one-to-one style
+      sockets.  For one-to-many style sockets, it holds the identifier
+      for the association.  All notifications for a given association
+      have the same association identifier.  The special SCTP_{FUTURE|
+      CURRENT|ALL}_ASSOC cannot be used.
+
+   sstat_state:  This contains the association's current state, i.e.,
+      one of the following values:
+
+      *  SCTP_CLOSED
+
+      *  SCTP_BOUND
+
+      *  SCTP_LISTEN
+
+      *  SCTP_COOKIE_WAIT
+
+
+
+
+Stewart, et al.               Informational                    [Page 81]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+      *  SCTP_COOKIE_ECHOED
+
+      *  SCTP_ESTABLISHED
+
+      *  SCTP_SHUTDOWN_PENDING
+
+      *  SCTP_SHUTDOWN_SENT
+
+      *  SCTP_SHUTDOWN_RECEIVED
+
+      *  SCTP_SHUTDOWN_ACK_SENT
+
+   sstat_rwnd:  This contains the association peer's current receiver
+      window size.
+
+   sstat_unackdata:  This is the number of unacknowledged DATA chunks.
+
+   sstat_penddata:  This is the number of DATA chunks pending receipt.
+
+   sstat_instrms:  This is the number of streams that the peer will be
+      using outbound.
+
+   sstat_outstrms:  This is the number of outbound streams that the
+      endpoint is allowed to use.
+
+   sstat_fragmentation_point:  This is the size at which SCTP
+      fragmentation will occur.
+
+   sstat_primary:  This is information on the current primary peer
+      address.
+
+   To access these status values, the application calls getsockopt()
+   with the option name SCTP_STATUS.
+
+8.2.2.  Peer Address Information (SCTP_GET_PEER_ADDR_INFO)
+
+   Applications can retrieve information about a specific peer address
+   of an association, including its reachability state, congestion
+   window, and retransmission timer values.  This information is
+   read-only.
+
+   The following structure is used to access this information:
+
+   struct sctp_paddrinfo {
+     sctp_assoc_t spinfo_assoc_id;
+     struct sockaddr_storage spinfo_address;
+     int32_t  spinfo_state;
+     uint32_t spinfo_cwnd;
+
+
+
+Stewart, et al.               Informational                    [Page 82]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+     uint32_t spinfo_srtt;
+     uint32_t spinfo_rto;
+     uint32_t spinfo_mtu;
+   };
+
+   spinfo_assoc_id:  This parameter is ignored for one-to-one style
+      sockets.
+
+      For one-to-many style sockets, this field may be filled by the
+      application, and if so, this field will have priority in looking
+      up the association instead of using the address specified in
+      spinfo_address.  Note that if the address does not belong to the
+      association specified, then this call will fail.  If the
+      application does not fill in the spinfo_assoc_id, then the address
+      will be used to look up the association, and on return, this field
+      will have the valid association identifier.  In other words, this
+      call can be used to translate an address into an association
+      identifier.  Note that the predefined constants are not allowed
+      for this option.
+
+   spinfo_address:  This is filled by the application and contains the
+      peer address of interest.
+
+   spinfo_state:  This contains the peer address's state:
+
+      SCTP_UNCONFIRMED:  This is the initial state of a peer address.
+
+      SCTP_ACTIVE:  This state is entered the first time after path
+         verification.  It can also be entered if the state is
+         SCTP_INACTIVE and the path supervision detects that the peer
+         address is reachable again.
+
+      SCTP_INACTIVE:  This state is entered whenever a path failure is
+         detected.
+
+   spinfo_cwnd:  This contains the peer address's current congestion
+      window.
+
+   spinfo_srtt:  This contains the peer address's current smoothed
+      round-trip time calculation in milliseconds.
+
+   spinfo_rto:  This contains the peer address's current retransmission
+      timeout value in milliseconds.
+
+   spinfo_mtu:  This is the current Path MTU of the peer address.  It is
+      the number of bytes available in an SCTP packet for chunks.
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 83]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+8.2.3.  Get the List of Chunks the Peer Requires to Be Authenticated
+        (SCTP_PEER_AUTH_CHUNKS)
+
+   This option gets a list of chunk types (see [RFC4960]) for a
+   specified association that the peer requires to be received
+   authenticated only.
+
+   The following structure is used to access these parameters:
+
+   struct sctp_authchunks {
+     sctp_assoc_t gauth_assoc_id;
+     uint32_t gauth_number_of_chunks
+     uint8_t  gauth_chunks[];
+   };
+
+   gauth_assoc_id:  This parameter indicates for which association the
+      user is requesting the list of peer-authenticated chunks.  For
+      one-to-one style sockets, this parameter is ignored.  Note that
+      the predefined constants are not allowed with this option.
+
+   gauth_number_of_chunks:  This parameter gives the number of elements
+      in the array gauth_chunks.
+
+   gauth_chunks:  This parameter contains an array of chunk types that
+      the peer is requesting to be authenticated.  If the passed-in
+      buffer size is not large enough to hold the list of chunk types,
+      ENOBUFS is returned.
+
+8.2.4.  Get the List of Chunks the Local Endpoint Requires to Be
+        Authenticated (SCTP_LOCAL_AUTH_CHUNKS)
+
+   This option gets a list of chunk types (see [RFC4960]) for a
+   specified association that the local endpoint requires to be received
+   authenticated only.
+
+   The following structure is used to access these parameters:
+
+   struct sctp_authchunks {
+     sctp_assoc_t gauth_assoc_id;
+     uint32_t gauth_number_of_chunks;
+     uint8_t  gauth_chunks[];
+   };
+
+   gauth_assoc_id:  This parameter is ignored for one-to-one style
+      sockets.  For one-to-many style sockets, the application may fill
+      in an association identifier or SCTP_FUTURE_ASSOC.  It is an error
+      to use SCTP_{CURRENT|ALL}_ASSOC in gauth_assoc_id.
+
+
+
+
+Stewart, et al.               Informational                    [Page 84]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   gauth_number_of_chunks:  This parameter gives the number of elements
+      in the array gauth_chunks.
+
+   gauth_chunks:  This parameter contains an array of chunk types that
+      the local endpoint is requesting to be authenticated.  If the
+      passed-in buffer is not large enough to hold the list of chunk
+      types, ENOBUFS is returned.
+
+8.2.5.  Get the Current Number of Associations (SCTP_GET_ASSOC_NUMBER)
+
+   This option gets the current number of associations that are attached
+   to a one-to-many style socket.  The option value is an uint32_t.
+   Note that this number is only a snapshot.  This means that the number
+   of associations may have changed when the caller gets back the option
+   result.
+
+   For a one-to-one style socket, this socket option results in an
+   error.
+
+8.2.6.  Get the Current Identifiers of Associations
+        (SCTP_GET_ASSOC_ID_LIST)
+
+   This option gets the current list of SCTP association identifiers of
+   the SCTP associations handled by a one-to-many style socket.
+
+   The option value has the structure
+
+   struct sctp_assoc_ids {
+     uint32_t gaids_number_of_ids;
+     sctp_assoc_t gaids_assoc_id[];
+   };
+
+   The caller must provide a large enough buffer to hold all association
+   identifiers.  If the buffer is too small, an error must be returned.
+   The user can use the SCTP_GET_ASSOC_NUMBER socket option to get an
+   idea of how large the buffer has to be.  gaids_number_of_ids gives
+   the number of elements in the array gaids_assoc_id.  Note also that
+   some or all of sctp_assoc_t returned in the array may become invalid
+   by the time the caller gets back the result.
+
+   For a one-to-one style socket, this socket option results in an
+   error.
+
+8.3.  Write-Only Options
+
+   The options defined in this subsection are write-only.  Using this
+   option in a getsockopt() or sctp_opt_info() call will result in an
+   error indicating EOPNOTSUPP.
+
+
+
+Stewart, et al.               Informational                    [Page 85]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+8.3.1.  Set Peer Primary Address (SCTP_SET_PEER_PRIMARY_ADDR)
+
+   This call requests that the peer mark the enclosed address as the
+   association primary (see [RFC5061]).  The enclosed address must be
+   one of the association's locally bound addresses.
+
+   The following structure is used to make a set peer primary request:
+
+   struct sctp_setpeerprim {
+     sctp_assoc_t sspp_assoc_id;
+     struct sockaddr_storage sspp_addr;
+   };
+
+   sspp_assoc_id:  This parameter is ignored for one-to-one style
+      sockets.  For one-to-many style sockets, it identifies the
+      association for this request.  Note that the predefined constants
+      are not allowed for this option.
+
+   sspp_addr:  The address to set as primary.
+
+8.3.2.  Add a Chunk That Must Be Authenticated (SCTP_AUTH_CHUNK)
+
+   This set option adds a chunk type that the user is requesting to be
+   received only in an authenticated way.  Changes to the list of chunks
+   will only affect future associations on the socket.
+
+   The following structure is used to add a chunk:
+
+   struct sctp_authchunk {
+     uint8_t sauth_chunk;
+   };
+
+   sauth_chunk:  This parameter contains a chunk type that the user is
+      requesting to be authenticated.
+
+   The chunk types for INIT, INIT-ACK, SHUTDOWN-COMPLETE, and AUTH
+   chunks must not be used.  If they are used, an error must be
+   returned.  The usage of this option enables SCTP AUTH in cases where
+   it is not required by other means (for example, the use of dynamic
+   address reconfiguration).
+
+8.3.3.  Set a Shared Key (SCTP_AUTH_KEY)
+
+   This option will set a shared secret key that is used to build an
+   association shared key.
+
+   The following structure is used to access and modify these
+   parameters:
+
+
+
+Stewart, et al.               Informational                    [Page 86]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   struct sctp_authkey {
+     sctp_assoc_t sca_assoc_id;
+     uint16_t sca_keynumber;
+     uint16_t sca_keylength;
+     uint8_t  sca_key[];
+   };
+
+   sca_assoc_id:  This parameter indicates on what association the
+      shared key is being set.  The special SCTP_{FUTURE|CURRENT|
+      ALL}_ASSOC can be used.  For one-to-one style sockets, this
+      parameter is ignored.  Note, however, that on one-to-one style
+      sockets, this option will set a key on the association if the
+      socket is connected; otherwise, this option will set a key on the
+      endpoint.
+
+   sca_keynumber:  This parameter is the shared key identifier by which
+      the application will refer to this shared key.  If a key of the
+      specified index already exists, then this new key will replace the
+      old existing key.  Note that shared key identifier '0' defaults to
+      a null key.
+
+   sca_keylength:  This parameter is the length of the array sca_key.
+
+   sca_key:  This parameter contains an array of bytes that is to be
+      used by the endpoint (or association) as the shared secret key.
+      Note that if the length of this field is zero, a null key is set.
+
+8.3.4.  Deactivate a Shared Key (SCTP_AUTH_DEACTIVATE_KEY)
+
+   This set option indicates that the application will no longer send
+   user messages using the indicated key identifier.
+
+   struct sctp_authkeyid {
+     sctp_assoc_t scact_assoc_id;
+     uint16_t scact_keynumber;
+   };
+
+   scact_assoc_id:  This parameter indicates from which association the
+      shared key identifier is being deleted.  The special SCTP_{FUTURE|
+      CURRENT|ALL}_ASSOC can be used.  For one-to-one style sockets,
+      this parameter is ignored.  Note, however, that this option will
+      deactivate the key from the association if the socket is
+      connected; otherwise, this option will deactivate the key from the
+      endpoint.
+
+
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 87]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   scact_keynumber:  This parameter is the shared key identifier that
+      the application is requesting to be deactivated.  The key
+      identifier must correspond to an existing shared key.  Note that
+      if this parameter is zero, use of the null key identifier '0' is
+      deactivated on the endpoint and/or association.
+
+   The currently active key cannot be deactivated.
+
+8.3.5.  Delete a Shared Key (SCTP_AUTH_DELETE_KEY)
+
+   This set option will delete an SCTP association's shared secret key
+   that has been deactivated.
+
+   struct sctp_authkeyid {
+     sctp_assoc_t scact_assoc_id;
+     uint16_t scact_keynumber;
+   };
+
+   scact_assoc_id:  This parameter indicates from which association the
+      shared key identifier is being deleted.  The special SCTP_{FUTURE|
+      CURRENT|ALL}_ASSOC can be used.  For one-to-one style sockets,
+      this parameter is ignored.  Note, however, that this option will
+      delete the key from the association if the socket is connected;
+      otherwise, this option will delete the key from the endpoint.
+
+   scact_keynumber:  This parameter is the shared key identifier that
+      the application is requesting to be deleted.  The key identifier
+      must correspond to an existing shared key and must not be in use
+      for any packet being sent by the SCTP implementation.  This means,
+      in particular, that it must be deactivated first.  Note that if
+      this parameter is zero, use of the null key identifier '0' is
+      deleted from the endpoint and/or association.
+
+   Only deactivated keys that are no longer used by an association can
+   be deleted.
+
+9.  New Functions
+
+   Depending on the system, the following interface can be implemented
+   as a system call or library function.
+
+9.1.  sctp_bindx()
+
+   This function allows the user to bind a specific subset of addresses
+   or, if the SCTP extension described in [RFC5061] is supported, add or
+   delete specific addresses.
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 88]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   The function prototype is
+
+   int sctp_bindx(int sd,
+                  struct sockaddr *addrs,
+                  int addrcnt,
+                  int flags);
+
+   If sd is an IPv4 socket, the addresses passed must be IPv4 addresses.
+   If the sd is an IPv6 socket, the addresses passed can either be IPv4
+   or IPv6 addresses.
+
+   A single address may be specified as INADDR_ANY for an IPv4 address,
+   or as IN6ADDR_ANY_INIT or in6addr_any for an IPv6 address; see
+   Section 3.1.2 for this usage.
+
+   addrs is a pointer to an array of one or more socket addresses.  Each
+   address is contained in its appropriate structure.  For an IPv6
+   socket, an array of sockaddr_in6 is used.  For an IPv4 socket, an
+   array of sockaddr_in is used.  The caller specifies the number of
+   addresses in the array with addrcnt.  Note that the wildcard
+   addresses cannot be used in combination with non-wildcard addresses
+   on a socket with this function; doing so will result in an error.
+
+   On success, sctp_bindx() returns 0.  On failure, sctp_bindx() returns
+   -1 and sets errno to the appropriate error code.
+
+   For SCTP, the port given in each socket address must be the same, or
+   sctp_bindx() will fail, setting errno to EINVAL.
+
+   The flags parameter is formed from the bitwise OR of zero or more of
+   the following currently defined flags:
+
+   o  SCTP_BINDX_ADD_ADDR
+
+   o  SCTP_BINDX_REM_ADDR
+
+   SCTP_BINDX_ADD_ADDR directs SCTP to add the given addresses to the
+   socket (i.e., endpoint), and SCTP_BINDX_REM_ADDR directs SCTP to
+   remove the given addresses from the socket.  The two flags are
+   mutually exclusive; if both are given, sctp_bindx() will fail with
+   EINVAL.  A caller may not remove all addresses from a socket;
+   sctp_bindx() will reject such an attempt with EINVAL.
+
+   An application can use sctp_bindx(SCTP_BINDX_ADD_ADDR) to associate
+   additional addresses with an endpoint after calling bind().  Or, an
+   application can use sctp_bindx(SCTP_BINDX_REM_ADDR) to remove some
+   addresses with which a listening socket is associated, so that no new
+   association accepted will be associated with these addresses.  If the
+
+
+
+Stewart, et al.               Informational                    [Page 89]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   endpoint supports dynamic address reconfiguration, an
+   SCTP_BINDX_REM_ADDR or SCTP_BINDX_ADD_ADDR may cause an endpoint to
+   send the appropriate message to its peers to change the peers'
+   address lists.
+
+   Adding and removing addresses from established associations is an
+   optional functionality.  Implementations that do not support this
+   functionality should return -1 and set errno to EOPNOTSUPP.
+
+   sctp_bindx() can be called on an already bound socket or on an
+   unbound socket.  If the socket is unbound and the first port number
+   in the addrs parameter is zero, the kernel will choose a port number.
+   All port numbers after the first one being 0 must also be zero.  If
+   the first port number is not zero, the following port numbers must be
+   zero or have the same value as the first one.  For an already bound
+   socket, all port numbers provided must be the bound one or 0.
+
+   sctp_bindx() is an atomic operation.  Therefore, the binding will
+   either succeed on all addresses or fail on all addresses.  If
+   multiple addresses are provided and the sctp_bindx() call fails,
+   there is no indication of which address is responsible for the
+   failure.  The only way to identify the specific error indication is
+   to call sctp_bindx() sequentially with only one address per call.
+
+9.2.  sctp_peeloff()
+
+   After an association is established on a one-to-many style socket,
+   the application may wish to branch off the association into a
+   separate socket/file descriptor.
+
+   This is particularly desirable when, for instance, the application
+   wishes to have a number of sporadic message senders/receivers remain
+   under the original one-to-many style socket but branch off these
+   associations carrying high-volume data traffic into their own
+   separate socket descriptors.
+
+   The application uses the sctp_peeloff() call to branch off an
+   association into a separate socket.  (Note that the semantics are
+   somewhat changed from the traditional one-to-one style accept()
+   call.)  Note also that the new socket is a one-to-one style socket.
+   Thus, it will be confined to operations allowed for a one-to-one
+   style socket.
+
+   The function prototype is
+
+   int sctp_peeloff(int sd,
+                    sctp_assoc_t assoc_id);
+
+
+
+
+Stewart, et al.               Informational                    [Page 90]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   and the arguments are
+
+   sd:  The original one-to-many style socket descriptor returned from
+      the socket() system call (see Section 3.1.1).
+
+   assoc_id:  The specified identifier of the association that is to be
+      branched off to a separate file descriptor.  (Note that in a
+      traditional one-to-one style accept() call, this would be an out
+      parameter, but for the one-to-many style call, this is an in
+      parameter.)
+
+   The function returns a non-negative file descriptor representing the
+   branched-off association, or -1 if an error occurred.  The variable
+   errno is then set appropriately.
+
+9.3.  sctp_getpaddrs()
+
+   sctp_getpaddrs() returns all peer addresses in an association.
+
+   The function prototype is
+
+   int sctp_getpaddrs(int sd,
+                      sctp_assoc_t id,
+                      struct sockaddr **addrs);
+
+   On return, addrs will point to a dynamically allocated array of
+   sockaddr structures of the appropriate type for the socket type.  The
+   caller should use sctp_freepaddrs() to free the memory.  Note that
+   the in/out parameter addrs must not be NULL.
+
+   If sd is an IPv4 socket, the addresses returned will be all IPv4
+   addresses.  If sd is an IPv6 socket, the addresses returned can be a
+   mix of IPv4 or IPv6 addresses, with IPv4 addresses returned according
+   to the SCTP_I_WANT_MAPPED_V4_ADDR option setting.
+
+   For one-to-many style sockets, id specifies the association to query.
+   For one-to-one style sockets, id is ignored.
+
+   On success, sctp_getpaddrs() returns the number of peer addresses in
+   the association.  If there is no association on this socket,
+   sctp_getpaddrs() returns 0, and the value of *addrs is undefined.  If
+   an error occurs, sctp_getpaddrs() returns -1, and the value of *addrs
+   is undefined.
+
+
+
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 91]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+9.4.  sctp_freepaddrs()
+
+   sctp_freepaddrs() frees all resources allocated by sctp_getpaddrs().
+
+   The function prototype is
+
+   void sctp_freepaddrs(struct sockaddr *addrs);
+
+   and addrs is the array of peer addresses returned by
+   sctp_getpaddrs().
+
+9.5.  sctp_getladdrs()
+
+   sctp_getladdrs() returns all locally bound addresses on a socket.
+
+   The function prototype is
+
+   int sctp_getladdrs(int sd,
+                      sctp_assoc_t id,
+                      struct sockaddr **addrs);
+
+   On return, addrs will point to a dynamically allocated array of
+   sockaddr structures of the appropriate type for the socket type.  The
+   caller should use sctp_freeladdrs() to free the memory.  Note that
+   the in/out parameter addrs must not be NULL.
+
+   If sd is an IPv4 socket, the addresses returned will be all IPv4
+   addresses.  If sd is an IPv6 socket, the addresses returned can be a
+   mix of IPv4 or IPv6 addresses, with IPv4 addresses returned according
+   to the SCTP_I_WANT_MAPPED_V4_ADDR option setting.
+
+   For one-to-many style sockets, id specifies the association to query.
+   For one-to-one style sockets, id is ignored.
+
+   If the id field is set to the value '0', then the locally bound
+   addresses are returned without regard to any particular association.
+
+   On success, sctp_getladdrs() returns the number of local addresses
+   bound to the socket.  If the socket is unbound, sctp_getladdrs()
+   returns 0, and the value of *addrs is undefined.  If an error occurs,
+   sctp_getladdrs() returns -1, and the value of *addrs is undefined.
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 92]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+9.6.  sctp_freeladdrs()
+
+   sctp_freeladdrs() frees all resources allocated by sctp_getladdrs().
+
+   The function prototype is
+
+   void sctp_freeladdrs(struct sockaddr *addrs);
+
+   and addrs is the array of local addresses returned by
+   sctp_getladdrs().
+
+9.7.  sctp_sendmsg() - DEPRECATED
+
+   This function is deprecated; sctp_sendv() (see Section 9.12) should
+   be used instead.
+
+   An implementation may provide a library function (or possibly system
+   call) to assist the user with the advanced features of SCTP.
+
+   The function prototype is
+
+   ssize_t sctp_sendmsg(int sd,
+                        const void *msg,
+                        size_t len,
+                        const struct sockaddr *to,
+                        socklen_t tolen,
+                        uint32_t ppid,
+                        uint32_t flags,
+                        uint16_t stream_no,
+                        uint32_t timetolive,
+                        uint32_t context);
+
+   and the arguments are
+
+   sd:  The socket descriptor.
+
+   msg:  The message to be sent.
+
+   len:  The length of the message.
+
+   to:  The destination address of the message.
+
+   tolen:  The length of the destination address.
+
+   ppid:  The same as sinfo_ppid (see Section 5.3.2).
+
+   flags:  The same as sinfo_flags (see Section 5.3.2).
+
+
+
+
+Stewart, et al.               Informational                    [Page 93]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   stream_no:  The same as sinfo_stream (see Section 5.3.2).
+
+   timetolive:  The same as sinfo_timetolive (see Section 5.3.2).
+
+   context:  The same as sinfo_context (see Section 5.3.2).
+
+   The call returns the number of characters sent, or -1 if an error
+   occurred.  The variable errno is then set appropriately.
+
+   Sending a message using sctp_sendmsg() is atomic (unless explicit EOR
+   marking is enabled on the socket specified by sd).
+
+   Using sctp_sendmsg() on a non-connected one-to-one style socket for
+   implicit connection setup may or may not work, depending on the SCTP
+   implementation.
+
+9.8.  sctp_recvmsg() - DEPRECATED
+
+   This function is deprecated; sctp_recvv() (see Section 9.13) should
+   be used instead.
+
+   An implementation may provide a library function (or possibly system
+   call) to assist the user with the advanced features of SCTP.  Note
+   that in order for the sctp_sndrcvinfo structure to be filled in by
+   sctp_recvmsg(), the caller must enable the sctp_data_io_event with
+   the SCTP_EVENTS option.  Note that the setting of the
+   SCTP_USE_EXT_RCVINFO will affect this function as well, causing the
+   sctp_sndrcvinfo information to be extended.
+
+   The function prototype is
+
+   ssize_t sctp_recvmsg(int sd,
+                        void *msg,
+                        size_t len,
+                        struct sockaddr *from,
+                        socklen_t *fromlen
+                        struct sctp_sndrcvinfo *sinfo
+                        int *msg_flags);
+
+   and the arguments are
+
+   sd:  The socket descriptor.
+
+   msg:  The message buffer to be filled.
+
+   len:  The length of the message buffer.
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 94]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   from:  A pointer to an address to be filled with the address of the
+      sender of this message.
+
+   fromlen:  An in/out parameter describing the from length.
+
+   sinfo:  A pointer to an sctp_sndrcvinfo structure to be filled upon
+      receipt of the message.
+
+   msg_flags:  A pointer to an integer to be filled with any message
+      flags (e.g., MSG_NOTIFICATION).  Note that this field is an in-out
+      field.  Options for the receive may also be passed into the value
+      (e.g., MSG_PEEK).  On return from the call, the msg_flags value
+      will be different than what was sent in to the call.  If
+      implemented via a recvmsg() call, the msg_flags parameter should
+      only contain the value of the flags from the recvmsg() call.
+
+   The call returns the number of bytes received, or -1 if an error
+   occurred.  The variable errno is then set appropriately.
+
+9.9.  sctp_connectx()
+
+   An implementation may provide a library function (or possibly system
+   call) to assist the user with associating to an endpoint that is
+   multi-homed.  Much like sctp_bindx(), this call allows a caller to
+   specify multiple addresses at which a peer can be reached.  The way
+   the SCTP stack uses the list of addresses to set up the association
+   is implementation dependent.  This function only specifies that the
+   stack will try to make use of all of the addresses in the list when
+   needed.
+
+   Note that the list of addresses passed in is only used for setting up
+   the association.  It does not necessarily equal the set of addresses
+   the peer uses for the resulting association.  If the caller wants to
+   find out the set of peer addresses, it must use sctp_getpaddrs() to
+   retrieve them after the association has been set up.
+
+   The function prototype is
+
+   int sctp_connectx(int sd,
+                     struct sockaddr *addrs,
+                     int addrcnt,
+                     sctp_assoc_t *id);
+
+   and the arguments are
+
+   sd:  The socket descriptor.
+
+   addrs:  An array of addresses.
+
+
+
+Stewart, et al.               Informational                    [Page 95]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   addrcnt:  The number of addresses in the array.
+
+   id:  An output parameter that, if passed in as non-NULL, will return
+      the association identifier for the newly created association (if
+      successful).
+
+   The call returns 0 on success or -1 if an error occurred.  The
+   variable errno is then set appropriately.
+
+9.10.  sctp_send() - DEPRECATED
+
+   This function is deprecated; sctp_sendv() should be used instead.
+
+   An implementation may provide another alternative function or system
+   call to assist an application with the sending of data without the
+   use of the cmsghdr structures.
+
+   The function prototype is
+
+   ssize_t sctp_send(int sd,
+                     const void *msg,
+                     size_t len,
+                     const struct sctp_sndrcvinfo *sinfo,
+                     int flags);
+
+   and the arguments are
+
+   sd:  The socket descriptor.
+
+   msg:  The message to be sent.
+
+   len:  The length of the message.
+
+   sinfo:  A pointer to an sctp_sndrcvinfo structure used as described
+      in Section 5.3.2 for a sendmsg() call.
+
+   flags:  The same flags as used by the sendmsg() call flags (e.g.,
+      MSG_DONTROUTE).
+
+   The call returns the number of bytes sent, or -1 if an error
+   occurred.  The variable errno is then set appropriately.
+
+   This function call may also be used to terminate an association using
+   an association identifier by setting the sinfo.sinfo_flags to
+   SCTP_EOF and the sinfo.sinfo_assoc_id to the association that needs
+   to be terminated.  In such a case, len can be zero.
+
+
+
+
+
+Stewart, et al.               Informational                    [Page 96]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   Using sctp_send() on a non-connected one-to-one style socket for
+   implicit connection setup may or may not work, depending on the SCTP
+   implementation.
+
+   Sending a message using sctp_send() is atomic unless explicit EOR
+   marking is enabled on the socket specified by sd.
+
+9.11.  sctp_sendx() - DEPRECATED
+
+   This function is deprecated; sctp_sendv() should be used instead.
+
+   An implementation may provide another alternative function or system
+   call to assist an application with the sending of data without the
+   use of the cmsghdr structure, and to provide a list of addresses.
+   The list of addresses is provided for implicit association setup.  In
+   such a case, the list of addresses serves the same purpose as the
+   addresses given in sctp_connectx() (see Section 9.9).
+
+   The function prototype is
+
+   ssize_t sctp_sendx(int sd,
+                      const void *msg,
+                      size_t len,
+                      struct sockaddr *addrs,
+                      int addrcnt,
+                      struct sctp_sndrcvinfo *sinfo,
+                      int flags);
+
+   and the arguments are
+
+   sd:  The socket descriptor.
+
+   msg:  The message to be sent.
+
+   len:  The length of the message.
+
+   addrs:  An array of addresses.
+
+   addrcnt:  The number of addresses in the array.
+
+   sinfo:  A pointer to an sctp_sndrcvinfo structure used as described
+      in Section 5.3.2 for a sendmsg() call.
+
+   flags:  The same flags as used by the sendmsg() call flags (e.g.,
+      MSG_DONTROUTE).
+
+   The call returns the number of bytes sent, or -1 if an error
+   occurred.  The variable errno is then set appropriately.
+
+
+
+Stewart, et al.               Informational                    [Page 97]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   Note that in the case of implicit connection setup, on return from
+   this call, the sinfo_assoc_id field of the sinfo structure will
+   contain the new association identifier.
+
+   This function call may also be used to terminate an association using
+   an association identifier by setting the sinfo.sinfo_flags to
+   SCTP_EOF and the sinfo.sinfo_assoc_id to the association that needs
+   to be terminated.  In such a case, len would be zero.
+
+   Sending a message using sctp_sendx() is atomic unless explicit EOR
+   marking is enabled on the socket specified by sd.
+
+   Using sctp_sendx() on a non-connected one-to-one style socket for
+   implicit connection setup may or may not work, depending on the SCTP
+   implementation.
+
+9.12.  sctp_sendv()
+
+   The function prototype is
+
+   ssize_t sctp_sendv(int sd,
+                      const struct iovec *iov,
+                      int iovcnt,
+                      struct sockaddr *addrs,
+                      int addrcnt,
+                      void *info,
+                      socklen_t infolen,
+                      unsigned int infotype,
+                      int flags);
+
+   The function sctp_sendv() provides an extensible way for an
+   application to communicate different send attributes to the SCTP
+   stack when sending a message.  An implementation may provide
+   sctp_sendv() as a library function or a system call.
+
+   This document defines three types of attributes that can be used to
+   describe a message to be sent.  They are struct sctp_sndinfo
+   (Section 5.3.4), struct sctp_prinfo (Section 5.3.7), and struct
+   sctp_authinfo (Section 5.3.8).  The following structure,
+   sctp_sendv_spa, is defined to be used when more than one of the above
+   attributes are needed to describe a message to be sent.
+
+   struct sctp_sendv_spa {
+     uint32_t sendv_flags;
+     struct sctp_sndinfo sendv_sndinfo;
+     struct sctp_prinfo sendv_prinfo;
+     struct sctp_authinfo sendv_authinfo;
+   };
+
+
+
+Stewart, et al.               Informational                    [Page 98]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   The sendv_flags field holds a bitwise OR of SCTP_SEND_SNDINFO_VALID,
+   SCTP_SEND_PRINFO_VALID, and SCTP_SEND_AUTHINFO_VALID indicating if
+   the sendv_sndinfo/sendv_prinfo/sendv_authinfo fields contain valid
+   information.
+
+   In future, when new send attributes are needed, new structures can be
+   defined.  But those new structures do not need to be based on any of
+   the above defined structures.
+
+   The function takes the following arguments:
+
+   sd:  The socket descriptor.
+
+   iov:  The gather buffer.  The data in the buffer is treated as a
+      single user message.
+
+   iovcnt:  The number of elements in iov.
+
+   addrs:  An array of addresses to be used to set up an association or
+      a single address to be used to send the message.  NULL is passed
+      in if the caller neither wants to set up an association nor wants
+      to send the message to a specific address.
+
+   addrcnt:  The number of addresses in the addrs array.
+
+   info:  A pointer to the buffer containing the attribute associated
+      with the message to be sent.  The type is indicated by the
+      info_type parameter.
+
+   infolen:  The length of info, in bytes.
+
+   infotype:  Identifies the type of the information provided in info.
+      The current defined values are as follows:
+
+      SCTP_SENDV_NOINFO:  No information is provided.  The parameter
+         info is a NULL pointer, and infolen is 0.
+
+      SCTP_SENDV_SNDINFO:  The parameter info is pointing to a struct
+         sctp_sndinfo.
+
+      SCTP_SENDV_PRINFO:  The parameter info is pointing to a struct
+         sctp_prinfo.
+
+      SCTP_SENDV_AUTHINFO:  The parameter info is pointing to a struct
+         sctp_authinfo.
+
+      SCTP_SENDV_SPA:  The parameter info is pointing to a struct
+         sctp_sendv_spa.
+
+
+
+Stewart, et al.               Informational                    [Page 99]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   flags:  The same flags as used by the sendmsg() call flags (e.g.,
+      MSG_DONTROUTE).
+
+   The call returns the number of bytes sent, or -1 if an error
+   occurred.  The variable errno is then set appropriately.
+
+   A note on the one-to-many style socket: The struct sctp_sndinfo
+   attribute must always be used in order to specify the association on
+   which the message is to be sent.  The only case where it is not
+   needed is when this call is used to set up a new association.
+
+   The caller provides a list of addresses in the addrs parameter to set
+   up an association.  This function will behave like calling
+   sctp_connectx() (see Section 9.9), first using the list of addresses
+   and then calling sendmsg() with the given message and attributes.
+   For a one-to-many style socket, if the struct sctp_sndinfo attribute
+   is provided, the snd_assoc_id field must be 0.  When this function
+   returns, the snd_assoc_id field will contain the association
+   identifier of the newly established association.  Note that the
+   struct sctp_sndinfo attribute is not required to set up an
+   association for a one-to-many style socket.  If this attribute is not
+   provided, the caller can enable the SCTP_ASSOC_CHANGE notification
+   and use the SCTP_COMM_UP message to find out the association
+   identifier.
+
+   If the caller wants to send the message to a specific peer address
+   (hence overriding the primary address), it can provide the specific
+   address in the addrs parameter and provide a struct sctp_sndinfo
+   attribute with the field snd_flags set to SCTP_ADDR_OVER.
+
+   This function call may also be used to terminate an association.  The
+   caller provides an sctp_sndinfo attribute with the snd_flags set to
+   SCTP_EOF.  In this case, len would be zero.
+
+   Sending a message using sctp_sendv() is atomic unless explicit EOR
+   marking is enabled on the socket specified by sd.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.               Informational                   [Page 100]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+9.13.  sctp_recvv()
+
+   The function prototype is
+
+   ssize_t sctp_recvv(int sd,
+                      const struct iovec *iov,
+                      int iovlen,
+                      struct sockaddr *from,
+                      socklen_t *fromlen,
+                      void *info,
+                      socklen_t *infolen,
+                      unsigned int *infotype,
+                      int *flags);
+
+   The function sctp_recvv() provides an extensible way for the SCTP
+   stack to pass up different SCTP attributes associated with a received
+   message to an application.  An implementation may provide
+   sctp_recvv() as a library function or as a system call.
+
+   This document defines two types of attributes that can be returned by
+   this call: the attribute of the received message and the attribute of
+   the next message in the receive buffer.  The caller enables the
+   SCTP_RECVRCVINFO and SCTP_RECVNXTINFO socket options, respectively,
+   to receive these attributes.  Attributes of the received message are
+   returned in struct sctp_rcvinfo (Section 5.3.5), and attributes of
+   the next message are returned in struct sctp_nxtinfo (Section 5.3.6).
+   If both options are enabled, both attributes are returned using the
+   following structure.
+
+   struct sctp_recvv_rn {
+     struct sctp_rcvinfo recvv_rcvinfo;
+     struct sctp_nxtinfo recvv_nxtinfo;
+   };
+
+   In future, new structures can be defined to hold new types of
+   attributes.  The new structures do not need to be based on struct
+   sctp_recvv_rn or struct sctp_rcvinfo.
+
+   This function takes the following arguments:
+
+   sd:  The socket descriptor.
+
+   iov:  The scatter buffer.  Only one user message is returned in this
+      buffer.
+
+   iovlen:  The number of elements in iov.
+
+
+
+
+
+Stewart, et al.               Informational                   [Page 101]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   from:  A pointer to an address to be filled with the sender of the
+      received message's address.
+
+   fromlen:  An in/out parameter describing the from length.
+
+   info:  A pointer to the buffer to hold the attributes of the received
+      message.  The structure type of info is determined by the
+      info_type parameter.
+
+   infolen:  An in/out parameter describing the size of the info buffer.
+
+   infotype:  On return, *info_type is set to the type of the info
+      buffer.  The current defined values are as follows:
+
+      SCTP_RECVV_NOINFO:  If both SCTP_RECVRCVINFO and SCTP_RECVNXTINFO
+         options are not enabled, no attribute will be returned.  If
+         only the SCTP_RECVNXTINFO option is enabled but there is no
+         next message in the buffer, no attribute will be returned.  In
+         these cases, *info_type will be set to SCTP_RECVV_NOINFO.
+
+      SCTP_RECVV_RCVINFO:  The type of info is struct sctp_rcvinfo, and
+         the attribute relates to the received message.
+
+      SCTP_RECVV_NXTINFO:  The type of info is struct sctp_nxtinfo, and
+         the attribute relates to the next message in the receive
+         buffer.  This is the case when only the SCTP_RECVNXTINFO option
+         is enabled and there is a next message in the buffer.
+
+      SCTP_RECVV_RN:  The type of info is struct sctp_recvv_rn.  The
+         recvv_rcvinfo field is the attribute of the received message,
+         and the recvv_nxtinfo field is the attribute of the next
+         message in the buffer.  This is the case when both
+         SCTP_RECVRCVINFO and SCTP_RECVNXTINFO options are enabled and
+         there is a next message in the receive buffer.
+
+   flags:  A pointer to an integer to be filled with any message flags
+      (e.g., MSG_NOTIFICATION).  Note that this field is an in/out
+      parameter.  Options for the receive may also be passed into the
+      value (e.g., MSG_PEEK).  On return from the call, the flags value
+      will be different than what was sent in to the call.  If
+      implemented via a recvmsg() call, the flags should only contain
+      the value of the flags from the recvmsg() call when calling
+      sctp_recvv(), and on return it has the value from msg_flags.
+
+   The call returns the number of bytes received, or -1 if an error
+   occurred.  The variable errno is then set appropriately.
+
+
+
+
+
+Stewart, et al.               Informational                   [Page 102]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+10.  Security Considerations
+
+   Many TCP and UDP implementations reserve port numbers below 1024 for
+   privileged users.  If the target platform supports privileged users,
+   the SCTP implementation should restrict the ability to call bind() or
+   sctp_bindx() on these port numbers to privileged users.
+
+   Similarly, unprivileged users should not be able to set protocol
+   parameters that could result in the congestion control algorithm
+   being more aggressive than permitted on the public Internet.  These
+   parameters are as follows:
+
+   o  struct sctp_rtoinfo
+
+   If an unprivileged user inherits a one-to-many style socket with open
+   associations on a privileged port, accepting new associations might
+   be permitted, but opening new associations should not be permitted.
+   This could be relevant for the r* family (rsh, rlogin, rwho, ...) of
+   protocols.
+
+   Applications using the one-to-many style sockets and using the
+   interleave level (if 0) are subject to denial-of-service attacks, as
+   described in Section 8.1.20.
+
+   Applications needing transport layer security can use Datagram
+   Transport Layer Security/SCTP (DTLS/SCTP) as specified in [RFC6083].
+   This can be implemented using the sockets API described in this
+   document.
+
+11.  Acknowledgments
+
+   Special acknowledgment is given to Ken Fujita, Jonathan Woods,
+   Qiaobing Xie, and La Monte Yarroll, who helped extensively in the
+   early formation of this document.
+
+   The authors also wish to thank Kavitha Baratakke, Mike Bartlett,
+   Martin Becke, Jon Berger, Mark Butler, Thomas Dreibholz, Andreas
+   Fink, Scott Kimble, Jonathan Leighton, Renee Revis, Irene Ruengeler,
+   Dan Wing, and many others on the TSVWG mailing list for contributing
+   valuable comments.
+
+   A special thanks to Phillip Conrad, for his suggested text, quick and
+   constructive insights, and most of all his persistent fighting to
+   keep the interface to SCTP usable for the application programmer.
+
+
+
+
+
+
+
+Stewart, et al.               Informational                   [Page 103]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+12.  References
+
+12.1.  Normative References
+
+   [IEEE-1003.1-2008]
+              Institute of Electrical and Electronics Engineers,
+              "Information Technology - Portable Operating System
+              Interface (POSIX)", IEEE Standard 1003.1, 2008.
+
+   [RFC3493]  Gilligan, R., Thomson, S., Bound, J., McCann, J., and W.
+              Stevens, "Basic Socket Interface Extensions for IPv6",
+              RFC 3493, February 2003.
+
+   [RFC3542]  Stevens, W., Thomas, M., Nordmark, E., and T. Jinmei,
+              "Advanced Sockets Application Program Interface (API) for
+              IPv6", RFC 3542, May 2003.
+
+   [RFC3758]  Stewart, R., Ramalho, M., Xie, Q., Tuexen, M., and P.
+              Conrad, "Stream Control Transmission Protocol (SCTP)
+              Partial Reliability Extension", RFC 3758, May 2004.
+
+   [RFC4895]  Tuexen, M., Stewart, R., Lei, P., and E. Rescorla,
+              "Authenticated Chunks for the Stream Control Transmission
+              Protocol (SCTP)", RFC 4895, August 2007.
+
+   [RFC4960]  Stewart, R., Ed., "Stream Control Transmission Protocol",
+              RFC 4960, September 2007.
+
+   [RFC5061]  Stewart, R., Xie, Q., Tuexen, M., Maruyama, S., and M.
+              Kozuka, "Stream Control Transmission Protocol (SCTP)
+              Dynamic Address Reconfiguration", RFC 5061,
+              September 2007.
+
+12.2.  Informative References
+
+   [RFC0768]  Postel, J., "User Datagram Protocol", STD 6, RFC 768,
+              August 1980.
+
+   [RFC0793]  Postel, J., "Transmission Control Protocol", STD 7,
+              RFC 793, September 1981.
+
+   [RFC1644]  Braden, R., "T/TCP -- TCP Extensions for Transactions
+              Functional Specification", RFC 1644, July 1994.
+
+
+
+
+
+
+
+
+Stewart, et al.               Informational                   [Page 104]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   [RFC6083]  Tuexen, M., Seggelmann, R., and E. Rescorla, "Datagram
+              Transport Layer Security (DTLS) for Stream Control
+              Transmission Protocol (SCTP)", RFC 6083, January 2011.
+
+   [RFC6247]  Eggert, L., "Moving the Undeployed TCP Extensions RFC
+              1072, RFC 1106, RFC 1110, RFC 1145, RFC 1146, RFC 1379,
+              RFC 1644, and RFC 1693 to Historic Status", RFC 6247,
+              May 2011.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.               Informational                   [Page 105]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+Appendix A.  Example Using One-to-One Style Sockets
+
+   The following code is an implementation of a simple client that sends
+   a number of messages marked for unordered delivery to an echo server
+   making use of all outgoing streams.  The example shows how to use
+   some features of one-to-one style IPv4 SCTP sockets, including
+
+   o  Creating and connecting an SCTP socket.
+
+   o  Making a request to negotiate a number of outgoing streams.
+
+   o  Determining the negotiated number of outgoing streams.
+
+   o  Setting an adaptation layer indication.
+
+   o  Sending messages with a given payload protocol identifier on a
+      particular stream using sctp_sendv().
+
+   <CODE BEGINS>
+   /*
+
+      Copyright (c) 2011 IETF Trust and the persons identified
+      as authors of the code.  All rights reserved.
+
+      Redistribution and use in source and binary forms, with
+      or without modification, is permitted pursuant to, and subject
+      to the license terms contained in, the Simplified BSD License
+      set forth in Section 4.c of the IETF Trust's Legal Provisions
+      Relating to IETF Documents (http://trustee.ietf.org/license-info).
+
+   */
+
+   #include <sys/types.h>
+   #include <sys/socket.h>
+   #include <netinet/in.h>
+   #include <netinet/sctp.h>
+   #include <arpa/inet.h>
+   #include <string.h>
+   #include <stdio.h>
+   #include <unistd.h>
+   #include <stdlib.h>
+
+   #define PORT 9
+   #define ADDR "127.0.0.1"
+   #define SIZE_OF_MESSAGE 1000
+   #define NUMBER_OF_MESSAGES 10
+   #define PPID 1234
+
+
+
+
+Stewart, et al.               Informational                   [Page 106]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   int
+   main(void) {
+     unsigned int i;
+     int sd;
+     struct sockaddr_in addr;
+     char buffer[SIZE_OF_MESSAGE];
+     struct iovec iov;
+     struct sctp_status status;
+     struct sctp_initmsg init;
+     struct sctp_sndinfo info;
+     struct sctp_setadaptation ind;
+     socklen_t opt_len;
+
+     /* Create a one-to-one style SCTP socket. */
+     if ((sd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)) < 0) {
+       perror("socket");
+       exit(1);
+     }
+
+     /* Prepare for requesting 2048 outgoing streams. */
+     memset(&init, 0, sizeof(init));
+     init.sinit_num_ostreams = 2048;
+     if (setsockopt(sd, IPPROTO_SCTP, SCTP_INITMSG,
+                    &init, (socklen_t)sizeof(init)) < 0) {
+       perror("setsockopt");
+       exit(1);
+     }
+
+     ind.ssb_adaptation_ind  = 0x01020304;
+     if (setsockopt(sd, IPPROTO_SCTP, SCTP_ADAPTATION_LAYER,
+                    &ind, (socklen_t)sizeof(ind)) < 0) {
+       perror("setsockopt");
+       exit(1);
+     }
+
+     /* Connect to the discard server. */
+     memset(&addr, 0, sizeof(addr));
+   #ifdef HAVE_SIN_LEN
+     addr.sin_len         = sizeof(struct sockaddr_in);
+   #endif
+     addr.sin_family      = AF_INET;
+     addr.sin_port        = htons(PORT);
+     addr.sin_addr.s_addr = inet_addr(ADDR);
+
+
+
+
+
+
+
+
+Stewart, et al.               Informational                   [Page 107]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+     if (connect(sd,
+                 (const struct sockaddr *)&addr,
+                 sizeof(struct sockaddr_in)) < 0) {
+       perror("connect");
+       exit(1);
+     }
+
+     /* Get the actual number of outgoing streams. */
+     memset(&status, 0, sizeof(status));
+     opt_len = (socklen_t)sizeof(status);
+     if (getsockopt(sd, IPPROTO_SCTP, SCTP_STATUS,
+                    &status, &opt_len) < 0) {
+       perror("getsockopt");
+       exit(1);
+     }
+
+     memset(&info, 0, sizeof(info));
+     info.snd_ppid = htonl(PPID);
+     info.snd_flags = SCTP_UNORDERED;
+     memset(buffer, 'A', SIZE_OF_MESSAGE);
+     iov.iov_base = buffer;
+     iov.iov_len = SIZE_OF_MESSAGE;
+     for (i = 0; i <  NUMBER_OF_MESSAGES; i++) {
+       info.snd_sid = i % status.sstat_outstrms;
+       if (sctp_sendv(sd,
+                      (const struct iovec *)&iov, 1,
+                      NULL, 0,
+                      &info, sizeof(info), SCTP_SENDV_SNDINFO,
+                      0) < 0) {
+         perror("sctp_sendv");
+         exit(1);
+       }
+     }
+
+     if (close(sd) < 0) {
+       perror("close");
+       exit(1);
+     }
+     return(0);
+   }
+   <CODE ENDS>
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.               Informational                   [Page 108]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+Appendix B.  Example Using One-to-Many Style Sockets
+
+   The following code is a simple implementation of a discard server
+   over SCTP.  The example shows how to use some features of one-to-many
+   style IPv6 SCTP sockets, including
+
+   o  Opening and binding of a socket.
+
+   o  Enabling notifications.
+
+   o  Handling notifications.
+
+   o  Configuring the auto-close timer.
+
+   o  Using sctp_recvv() to receive messages.
+
+   Please note that this server can be used in combination with the
+   client described in Appendix A.
+
+   <CODE BEGINS>
+   /*
+
+      Copyright (c) 2011 IETF Trust and the persons identified
+      as authors of the code.  All rights reserved.
+
+      Redistribution and use in source and binary forms, with
+      or without modification, is permitted pursuant to, and subject
+      to the license terms contained in, the Simplified BSD License
+      set forth in Section 4.c of the IETF Trust's Legal Provisions
+      Relating to IETF Documents (http://trustee.ietf.org/license-info).
+
+   */
+
+   #include <sys/types.h>
+   #include <sys/socket.h>
+   #include <netinet/in.h>
+   #include <netinet/sctp.h>
+   #include <arpa/inet.h>
+   #include <string.h>
+   #include <stdio.h>
+   #include <stdlib.h>
+   #include <unistd.h>
+
+   #define BUFFER_SIZE (1<<16)
+   #define PORT 9
+   #define ADDR "0.0.0.0"
+   #define TIMEOUT 5
+
+
+
+
+Stewart, et al.               Informational                   [Page 109]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   static void
+   print_notification(void *buf)
+   {
+     struct sctp_assoc_change *sac;
+     struct sctp_paddr_change *spc;
+     struct sctp_adaptation_event *sad;
+     union sctp_notification *snp;
+     char addrbuf[INET6_ADDRSTRLEN];
+     const char *ap;
+     struct sockaddr_in *sin;
+     struct sockaddr_in6 *sin6;
+
+     snp = buf;
+
+     switch (snp->sn_header.sn_type) {
+     case SCTP_ASSOC_CHANGE:
+       sac = &snp->sn_assoc_change;
+       printf("^^^ Association change: ");
+       switch (sac->sac_state) {
+       case SCTP_COMM_UP:
+         printf("Communication up (streams (in/out)=(%u/%u)).\n",
+                sac->sac_inbound_streams, sac->sac_outbound_streams);
+         break;
+       case SCTP_COMM_LOST:
+         printf("Communication lost (error=%d).\n", sac->sac_error);
+         break;
+       case SCTP_RESTART:
+         printf("Communication restarted (streams (in/out)=(%u/%u).\n",
+                sac->sac_inbound_streams, sac->sac_outbound_streams);
+         break;
+       case SCTP_SHUTDOWN_COMP:
+         printf("Communication completed.\n");
+         break;
+       case SCTP_CANT_STR_ASSOC:
+         printf("Communication couldn't be started.\n");
+         break;
+       default:
+         printf("Unknown state: %d.\n", sac->sac_state);
+         break;
+       }
+       break;
+     case SCTP_PEER_ADDR_CHANGE:
+       spc = &snp->sn_paddr_change;
+       if (spc->spc_aaddr.ss_family == AF_INET) {
+         sin = (struct sockaddr_in *)&spc->spc_aaddr;
+         ap = inet_ntop(AF_INET, &sin->sin_addr,
+                        addrbuf, INET6_ADDRSTRLEN);
+       } else {
+
+
+
+Stewart, et al.               Informational                   [Page 110]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+         sin6 = (struct sockaddr_in6 *)&spc->spc_aaddr;
+         ap = inet_ntop(AF_INET6, &sin6->sin6_addr,
+                        addrbuf, INET6_ADDRSTRLEN);
+       }
+       printf("^^^ Peer Address change: %s ", ap);
+       switch (spc->spc_state) {
+       case SCTP_ADDR_AVAILABLE:
+         printf("is available.\n");
+         break;
+       case SCTP_ADDR_UNREACHABLE:
+         printf("is not available (error=%d).\n", spc->spc_error);
+         break;
+       case SCTP_ADDR_REMOVED:
+         printf("was removed.\n");
+         break;
+       case SCTP_ADDR_ADDED:
+         printf("was added.\n");
+         break;
+       case SCTP_ADDR_MADE_PRIM:
+         printf("is primary.\n");
+         break;
+       default:
+         printf("unknown state (%d).\n", spc->spc_state);
+         break;
+       }
+       break;
+     case SCTP_SHUTDOWN_EVENT:
+       printf("^^^ Shutdown received.\n");
+       break;
+     case SCTP_ADAPTATION_INDICATION:
+       sad = &snp->sn_adaptation_event;
+       printf("^^^ Adaptation indication 0x%08x received.\n",
+              sad->sai_adaptation_ind);
+       break;
+     default:
+       printf("^^^ Unknown event of type: %u.\n",
+              snp->sn_header.sn_type);
+       break;
+     };
+   }
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.               Informational                   [Page 111]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+   int
+   main(void) {
+     int sd, flags, timeout, on;
+     ssize_t n;
+     unsigned int i;
+     union {
+       struct sockaddr sa;
+       struct sockaddr_in sin;
+       struct sockaddr_in6 sin6;
+     } addr;
+     socklen_t fromlen, infolen;
+     struct sctp_rcvinfo info;
+     unsigned int infotype;
+     struct iovec iov;
+     char buffer[BUFFER_SIZE];
+     struct sctp_event event;
+     uint16_t event_types[] = {SCTP_ASSOC_CHANGE,
+                               SCTP_PEER_ADDR_CHANGE,
+                               SCTP_SHUTDOWN_EVENT,
+                               SCTP_ADAPTATION_INDICATION};
+
+     /* Create a one-to-many style SCTP socket. */
+     if ((sd = socket(AF_INET6, SOCK_SEQPACKET, IPPROTO_SCTP)) < 0) {
+       perror("socket");
+       exit(1);
+     }
+
+     /* Enable the events of interest. */
+     memset(&event, 0, sizeof(event));
+     event.se_assoc_id = SCTP_FUTURE_ASSOC;
+     event.se_on = 1;
+     for (i = 0; i < sizeof(event_types)/sizeof(uint16_t); i++) {
+       event.se_type = event_types[i];
+       if (setsockopt(sd, IPPROTO_SCTP, SCTP_EVENT,
+                      &event, sizeof(event)) < 0) {
+         perror("setsockopt");
+         exit(1);
+       }
+     }
+
+     /* Configure auto-close timer. */
+     timeout = TIMEOUT;
+     if (setsockopt(sd, IPPROTO_SCTP, SCTP_AUTOCLOSE,
+                    &timeout, sizeof(timeout)) < 0) {
+       perror("setsockopt SCTP_AUTOCLOSE");
+       exit(1);
+     }
+
+
+
+
+Stewart, et al.               Informational                   [Page 112]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+     /* Enable delivery of SCTP_RCVINFO. */
+     on = 1;
+     if (setsockopt(sd, IPPROTO_SCTP, SCTP_RECVRCVINFO,
+                    &on, sizeof(on)) < 0) {
+       perror("setsockopt SCTP_RECVRCVINFO");
+       exit(1);
+     }
+
+     /* Bind the socket to all local addresses. */
+     memset(&addr, 0, sizeof(addr));
+   #ifdef HAVE_SIN6_LEN
+     addr.sin6.sin6_len         = sizeof(addr.sin6);
+   #endif
+     addr.sin6.sin6_family      = AF_INET6;
+     addr.sin6.sin6_port        = htons(PORT);
+     addr.sin6.sin6_addr        = in6addr_any;
+     if (bind(sd, &addr.sa, sizeof(addr.sin6)) < 0) {
+       perror("bind");
+       exit(1);
+     }
+     /* Enable accepting associations. */
+     if (listen(sd, 1) < 0) {
+       perror("listen");
+       exit(1);
+     }
+
+     for (;;) {
+       flags = 0;
+       memset(&addr, 0, sizeof(addr));
+       fromlen = (socklen_t)sizeof(addr);
+       memset(&info, 0, sizeof(info));
+       infolen = (socklen_t)sizeof(info);
+       infotype = 0;
+       iov.iov_base = buffer;
+       iov.iov_len = BUFFER_SIZE;
+
+       n = sctp_recvv(sd, &iov, 1,
+                      &addr.sa, &fromlen,
+                      &info, &infolen, &infotype,
+                      &flags);
+
+       if (flags & MSG_NOTIFICATION) {
+         print_notification(iov.iov_base);
+       } else {
+         char addrbuf[INET6_ADDRSTRLEN];
+         const char *ap;
+         in_port_t port;
+
+
+
+
+Stewart, et al.               Informational                   [Page 113]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+         if (addr.sa.sa_family == AF_INET) {
+                ap = inet_ntop(AF_INET, &addr.sin.sin_addr,
+                               addrbuf, INET6_ADDRSTRLEN);
+                port = ntohs(addr.sin.sin_port);
+         } else {
+                ap = inet_ntop(AF_INET6, &addr.sin6.sin6_addr,
+                               addrbuf, INET6_ADDRSTRLEN);
+                port = ntohs(addr.sin6.sin6_port);
+         }
+         printf("Message received from %s:%u: len=%d",
+                ap, port, (int)n);
+         switch (infotype) {
+         case SCTP_RECVV_RCVINFO:
+           printf(", sid=%u", info.rcv_sid);
+           if (info.rcv_flags & SCTP_UNORDERED) {
+             printf(", unordered");
+           } else {
+             printf(", ssn=%u", info.rcv_ssn);
+           }
+           printf(", tsn=%u", info.rcv_tsn);
+           printf(", ppid=%u.\n", ntohl(info.rcv_ppid));
+           break;
+         case SCTP_RECVV_NOINFO:
+         case SCTP_RECVV_NXTINFO:
+         case SCTP_RECVV_RN:
+           printf(".\n");
+           break;
+         default:
+           printf(" unknown infotype.\n");
+         }
+       }
+     }
+
+     if (close(sd) < 0) {
+       perror("close");
+       exit(1);
+     }
+
+     return (0);
+   }
+   <CODE ENDS>
+
+
+
+
+
+
+
+
+
+
+Stewart, et al.               Informational                   [Page 114]
+
+RFC 6458                    SCTP Sockets API               December 2011
+
+
+Authors' Addresses
+
+   Randall R. Stewart
+   Adara Networks
+   Chapin, SC  29036
+   USA
+
+   EMail: randall@lakerest.net
+
+
+   Michael Tuexen
+   Muenster University of Applied Sciences
+   Stegerwaldstr. 39
+   48565 Steinfurt
+   Germany
+
+   EMail: tuexen@fh-muenster.de
+
+
+   Kacheong Poon
+   Oracle Corporation
+
+   EMail: ka-cheong.poon@oracle.com
+
+
+   Peter Lei
+   Cisco Systems, Inc.
+   9501 Technology Blvd.
+   West Office Center
+   Rosemont, IL  60018
+   USA
+
+   EMail: peterlei@cisco.com
+
+
+   Vladislav Yasevich
+   HP
+   110 Spitrook Rd.
+   Nashua, NH  03062
+   USA
+
+   EMail: vladislav.yasevich@hp.com
+
+
+
+
+
+
+
+
+
+Stewart, et al.               Informational                   [Page 115]
+
diff --git a/doc/states.txt b/doc/states.txt
new file mode 100644
index 0000000..de05f1f
--- /dev/null
+++ b/doc/states.txt
@@ -0,0 +1,105 @@
+#!enscript -G -r -f Courier7 -o states.ps -
+Version 0.11.  Best viewed on a 176 column terminal or printed with the above command.
+
+This table shows actions in response to all possible messages in all
+possible states for SCTP.  It is based on RFC2960.
+
+Arguments to the state functions:
+(asoc, {(skb, verificationTag, singleton) || (primitive_args) || nil} )
+- asoc is the association in question, NULL for CLOSED
+- The second arg is a coproduct depending on the event
+-- for a chunk we have:
+--- skb is the inbound chunk
+--- verificationTag is from the SCTP header
+--- singleton is true if the chunk is alone in its packet
+-- for a primitive we have
+--- primitive_args is a union which captures the args to all primitives
+-- for other events the second argument is undefined.
+
+Return values of the state functions:
+(asoc, NewState, timers, responsePacket, ULPNotice, error, unique)
+- asoc is the association in question, NB: might be a CLOSED asoc
+- NewState is the next state the machine should move to
+- timers is new timer values, NULL if not needed
+- responsePacket is an outbound packet to send, NULL if not needed
+- ULPNotice is any response or notification we need to send to the ULP
+- error is an error code, NULL if there was no error
+- unique is a boolean that tells us if the chunk has to be alone in its packet.  undef if the event was not a chunk.
+
+Most of the state functions should be self-explainatory.  Here are some which might not be clear:
+violation - Can not happen -- the other guy is violating the protocol.
+other_stupid - The other implementation is doing a legal thing which
+	is a BAD IDEA.
+lucky - We did something legal but stupid and got away with it :-).
+bug - We did something impossible.
+
+* in the left column means that this is "normal sender" flow.
++ in the left column means that this is "normal receiver" flow.
+% marks chunks which may NOT be bundled. See 3.0 and 6.10.
+! marks special security considerations
+Count the >'s to calculate state transitions.
+0 - Fixed in Version 11.
+1 - If we see more INIT ACK's than we sent INIT's, we may be under hijack attack
+2 - 3.3.10.10 is a special case of 5.2.4 for SHUTDOWN-ACK-SENT.
+3 - 6.0 says that OUTBOUND data should only be generated in ESTABLISHED, SHUTDOWN-PENDING, and SHUTDOWN-RECEIVED.
+4 - Contradiction fixed in v11.
+5 - implementation specific (safe to leave unspecified)
+6 - 
+7 - This is not explicit but is a logical consequence of other requirements.
+8 - If his HEARTBEAT beats his cookie you'll send an ABORT.
+9 - There is a finite probability that this orderly shutdown will turn into an ABORT.
+
+
+                       | CLOSED        |  COOKIE-WAIT    | COOKIE-ECHOED   | ESTABLISHED      | SHUTDOWN-PENDING   | SHUTDOWN-SENT   | SHUTDOWN-RECEIVED  | SHUTDOWN-ACK-SENT 
+-----------------------|---------------|-----------------|-----------------|------------------|--------------------|-----------------|--------------------|-------------------
+Chunks                 |               |                 |                 |                  |                    |                 |                    |                   
+-----------------------|---------------|-----------------|-----------------|------------------|--------------------|-----------------|--------------------|-------------------
+ABORT                  | pdiscard(8.4.2)| do_9_1_abort  <|do_9_1_abort   <<| do_9_1_abort  <<<| do_9_1_abort   >>>>| do_9_1_abort >>>| do_9_1_abort     >>| do_9_1_abort     >
+INIT                  %|*do_5_1B_init  | do_5_2_1_siminit| do_5_2_1_siminit| do_5_2_2_dupinit | do_5_2_2_dupinit   | do_5_2_2_dupinit| do_5_2_2_dupinit   | do_9_2_reshut     
+INIT ACK              %| discard(5.2.3)|*do_5_1C_ack    >| discard(5.2.3) 1| discard(5.2.3)  1| discard(5.2.3)    1| discard(5.2.3) 1| discard(5.2.3)    1| discard(5.2.3)   1
+COOKIE ECHO            |*do_5_1D_ce >>>| do_5_2_4_dupcook| do_5_2_4_dupcook| do_5_2_4_dupcook | do_5_2_4_dupcook   | do_5_2_4_dupcook| do_5_2_4_dupcook   | do_5_2_4_dupcook 2
+COOKIE ACK             | discard      4| discard(5.2.5)  |*do_5_1E_ca     >| discard(5.2.5)   | discard(5.2.5)     | discard(5.2.5)  | discard(5.2.5)     | discard(5.2.5)    
+SHUTDOWN               | tabort_8_4_8  | discard(9.2)   0| discard(9.2)   0|+do_9_2_shut   >>>| discard(0.2)      0| do_9_2_shutack>>| discard(0.2)      0| discard(0.2)     0
+SHUTDOWN ACK           | do_8_4_5_shut | do_8_4_5_shut   | discard        0| violation       7| violation         7|*do_9_2_final >>>| violation         7| do_9_2_final     >
+SHUTDOWN COMPLETE     %| discard(8.4.6)| discard(8.5.1c) | discard(8.5.1c) | discard(8.5.1c)  | discard(8.5.1c)    | discard(8.5.1c) | discard(8.5.1c)    |+4(C)             >
+DATA                   | tabort_8_4_8  | discard(6.0)    | discard(6.0)    |*eat_data_6_2     | eat_data_6_2       | eat_data_fast4-4| discard(6.0)       | discard(6.0)     
+SACK                   | tabort_8_4_8  | discard(6.0)    | eat_sack_6_2_1  |*eat_sack_6_2_1   | eat_sack_6_2_1     | discard(6.0)    | eat_sack_6_2_1     | discard(6.0)     
+HEARTBEAT              | tabort_8_4_8  | violation      7| other_stupid   8|*beat_8_3         | beat_8_3           | beat_8_3        | beat_8_3           | other_stupid     9
+HEARTBEAT ACK          | tabort_8_4_8  | violation      7| lucky          7|*backbeat_8_3     | backbeat_8_3       | backbeat_8_3    | backbeat_8_3       | backbeat_8_3
+ERROR_stale            | discard      4| discard(5.2.6)  | do_5_2_6_stale  | discard(5.2.6)   | discard(5.2.6)     | discard(5.2.6)  | discard(5.2.6)     | discard(5.2.6)    
+ERROR                  | tabort_8_4_8  | ?               | ?               | ?                | ?                  | ?               | ?                  | ?                 
+ECNE                   | bug?          | bug?            | do_ecne         | do_ecne          | do_ecne            | do_ecne         | do_ecne            | violation
+CWR                    | discard       | discard         | discard         | do_ecn_cwr       | do_ecn_cwr         | do_ecn_cwr      | discard            | bug?
+-----------------------|---------------|-----------------|-----------------|------------------|--------------------|-----------------|--------------------|-------------------
+Timeouts               |               |                 |                 |                  |                    |                 |                    |                   
+-----------------------|---------------|-----------------|-----------------|------------------|--------------------|-----------------|--------------------|-------------------
+T1-COOKIE TO           | bug           | bug             | do_4_3_reecho   | bug              | bug                | bug             | bug                | bug               
+T1-INIT TO             | bug           | do_4_2_reinit   | bug             | bug              | bug                | bug             | bug                | bug               
+T2-SHUTDOWN TO         | bug           | bug             | bug             | bug              | bug                | do_9_2_reshut   | bug                | do_9_2_reshutack  
+T3-RTX TO              | bug           | bug             | do_6_3_3_retx   | do_6_3_3_retx    | do_6_3_3_retx      | bug	     | do_6_3_3_retx      | bug
+HEARTBEAT TO           | bug           | bug		 | bug		   | do_8_3_hb_err    | do_8_3_hb_err      | heartoff	    5| do_8_3_hb_err      | heartoff         5
+SACK TO		       | bug	       | bug		 | bug		   | do_6_2_sack      | do_6_2_sack	   | do_6_2_sack     | bug		  | bug
+-----------------------|---------------|-----------------|-----------------|------------------|--------------------|-----------------|--------------------|-------------------
+Other Events           |               |                 |                 |                  |                    |                 |                    |                   
+-----------------------|---------------|-----------------|-----------------|------------------|--------------------|-----------------|--------------------|-------------------
+NO PENDING TSN         | ignore        | ignore          | ignore          | ignore           |*do_9_2_start_shut >| ignore          |+do_9_2_shutack 4-6>| ignore            
+ICMP UNREACHFRAG       | adjust_mtu    | adjust_mtu      | adjust_mtu      | adjust_mtu       | adjust_mtu         | adjust_mtu      | adjust_mtu         | adjust_mtu        
+-----------------------|---------------|-----------------|-----------------|------------------|--------------------|-----------------|--------------------|-------------------
+Primitives             |               |                 |                 |                  |                    |                 |                    |                   
+-----------------------|---------------|-----------------|-----------------|------------------|--------------------|-----------------|--------------------|-------------------
+PRM_INITIALIZE         |               | error           | error           | error            | error              | error           | error              | error             
+PRM_ASSOCIATE          | do_PRM_ASOC  >| error           | error           | error            | error              | error           | error              | error             
+PRM_SHUTDOWN           | error         | mark_shutdown  5| mark_shutdown  5|*do_9_2_PRM_SHUT >| discard           5| discard        5| discard(9.2)       | discard         5
+PRM_ABORT              | error         | do_PRM_ABORT   <| do_PRM_ABORT  <<| do_PRM_ABORT  <<<| do_PRM_ABORT   >>>>| do_PRM_ABORT >>>| do_PRM_ABORT     >>| do_PRM_ABORT    >
+PRM_SEND               | error         | do_PRM_SENDQ6.0 | do_PRM_SENDQ6.0 | do_PRM_SEND      | error(9.2)         | error(9.2)      | error(9.2, 4-5)    | error(9.2, 4-7)
+PRM_SETPRIMARY         | error         | error           | do_PRM_SETPRI   | do_PRM_SETPRI    | do_PRM_SETPRI      | do_PRM_SETPRI   | do_PRM_SETPRI      | do_PRM_SETPRI     
+PRM_RECEIVE            | error         | error           |                 | do_PRM_RCV       | do_PRM_RCV         | do_PRM_RCV      | do_PRM_RCV?        | do_PRM_RCV?       
+PRM_STATUS             | error         | get_PRM_STATUS  | get_PRM_STATUS  | get_PRM_STATUS   | get_PRM_STATUS     | get_PRM_STATUS  | get_PRM_STATUS     | get_PRM_STATUS    
+PRM_CHANGEHEARTBEAT    | error         | do_PRM_CH_HB    | do_PRM_CH_HB    | do_PRM_CH_HB     | do_PRM_CH_HB       | do_PRM_CH_HB    | do_PRM_CH_HB       | do_PRM_CH_HB      
+PRM_REQUESTHEARTBEAT   | error         | do_PRM_HB       | do_PRM_HB       | do_PRM_HB        | do_PRM_HB          | do_PRM_HB       | do_PRM_HB          | do_PRM_HB         
+PRM_GETSRTTREPORT      | error         | get_PRM_SRTT    | get_PRM_SRTT    | get_PRM_SRTT     | get_PRM_SRTT       | get_PRM_SRTT    | get_PRM_SRTT       | get_PRM_SRTT      
+PRM_SETFAILURETHRESHOLD| error         | error           | do_PRM_FTHRESH  | do_PRM_FTHRESH   | do_PRM_FTHRESH     | do_PRM_FTHRESH  | do_PRM_FTHRESH     | do_PRM_FTHRESH    
+PRM_SETPROTOPARAMETERS | error         | do_PRM_SETPARM  | do_PRM_SETPARM  | do_PRM_SETPARM   | do_PRM_SETPARM     | do_PRM_SETPARM  | do_PRM_SETPARM     | do_PRM_SETPARM    
+PRM_RECEIVE_UNSENT     | error         | ?               | ?               | ?                | ?                  | ?               | ?                  | ?                 
+PRM_RECEIVE_UNACKED    | error         | ?               | ?               | ?                | ?                  | ?               | ?                  | ?                 
+PRM_DESTROY            | error         | do_PRM_DIEDIE   | do_PRM_DIEDIE   | do_PRM_DIEDIE    | do_PRM_DIEDIE      | do_PRM_DIEDIE   | do_PRM_DIEDIE      | do_PRM_DIEDIE     
diff --git a/doc/style_guide.txt b/doc/style_guide.txt
new file mode 100644
index 0000000..d5b3bb2
--- /dev/null
+++ b/doc/style_guide.txt
@@ -0,0 +1,195 @@
+This is the style guide for the LKSCTP Project.
+<http://www.sf.net/projects/lksctp/>
+
+1.0 Introduction
+
+Use the Linux kernel coding style as the base,
+linux/Documentation/CodingStyle.
+
+This is intended as the IETF kernel reference code for RFC2960 and the
+SCTP API.  As such, readability is paramount.  We attempt to follow
+the names from RFC2960 as closely as practical given the constrains of
+C and the Linux kernel naming conventions.
+
+Here are the approximate naming rules we use.  Those marked
+[obsolescent] will go away once we purge the last vestiges of them.
+
+1) [obsolescent] If a name appears in RFC 2960 or the API draft we try
+   to use it as closely as permitted by C syntax without ADDING "_".
+   This usually means names of the form "xyzAbc".  E.g. "Duplicate TSN"
+   from RFC2960 became "DuplicateTSN", but "a_rwnd" is unaltered.
+
+New names should use this revised rule 1:
+
+   If a name appears in RFC 2960 or the API draft we try to use it as
+   closely as permitted by C syntax without using upper case letters.
+   This usually means names of the form "xyz_abc".  E.g. "Duplicate
+   TSN" from RFC2960 became "duplicate_tsn", but "a_rwnd" is
+   unaltered.  Remember the acronyms still need to be upper case in
+   comments.
+
+2) [obsolescent] If a name refers to a struct which appears on the wire we use
+the form "struct xyzAbc".  This is historically because we inherited most
+of these from the user space implementation.  E.g. "struct sctpHeader".
+
+3) There is no rule 3.
+
+4) All functions start with "sctp_".  Uh, yeah, well, uh...
+
+5) Constants have the form "XYZ_ABC" per K&R.
+
+6) [obsolecent] If "XYZ" is an acronym it SHOULD be capitalized as in
+   "XYZ_abc" or "XYZabc" unless overridden by rule 2 or rule 4. E.g.
+   "struct SCTP_association".
+
+New names should use this revised rule 6:
+
+   Names with anronyms SHOULD map them to lower case, E.g.
+   "struct sctp_association".
+
+7) All remaining names SHOULD use the form "xyz_abc".  E.g. "int too_big".
+
+8) Deviations from these rules are bugs and need to be fixed.
+
+
+2.0 Architectural and Procedural Standards
+
+The core metaphors are the state machine (sctp_do_sm(), related
+functions) and the smart pipe (inqueue, outqueue, ULPqueue, packet).
+
+The state machine breaks down into a pure functional core,
+sctp_sm_statefuns.c, with no side effects, and an explicit set of side
+effects, sctp_sm_sideeffects.c.  
+
+Every function, typedef, enum, and struct needs a descriptive comment.
+
+3.0 /* Comments */
+
+Except as noted below, make all comments full sentences.
+
+Proper behaviour is to spell-cheque your comments.  Those colourful
+American spellings will not be rejected.
+
+Start all sentences with a capital letter.  Do not begin sentences
+with symbols which must be all lower case.  Sentences end with a
+period, question mark, or exclamation point.  Punctuation at the end
+of a sentence has two trailing spaces or a trailing newline.
+
+Comments should confine themselves to expressing the INTENT of the code.
+
+If comments do not agree with the code, then we have a BUG.
+
+Passive voice should be avoided.
+
+Every function, typedef, enum, and struct needs a descriptive
+comment.
+
+/* All comments are C comments, */ 
+// not C++ comments.
+
+/* Multiline comments should
+ * look like this.
+ */
+
+Every #endif should include a comment describing the matching #if.
+E.g.
+
+#if 0
+#endif /* 0 */
+
+A struct sk_buff_head needs a comment describing the REAL type of its
+elements.
+
+To disable a section of code use
+#if 0
+#endif /* 0 */
+rather than /* */.  The if/endif pair safely interoperates with
+existing comments.
+
+4.0 Appearance & Pretty printing
+
+Put a space after every keyword.
+
+Here is an example function:
+
+retval_t my_fun(int foo, struct SCTP_struct *bar)
+{
+	statement;
+}
+
+Every switch statement should have a default clause.  If the default
+can never happen, default should crash or otherwise report failure.
+
+A loop with no body looks like this:
+
+        while (test()) {
+	      /* Do nothing. */
+	}
+
+If a compound condition or arithemetic expression extends beyond the
+79 character limit, put the operators at the end of the line.  E.g.
+
+	if ((NULL == map->tsn_map) ||
+	    (NULL == map->overflow_map) ||
+	    (map->len == 0)) {
+...
+
+
+The if/else style must follow that of K&R style, for example:
+
+	if (foo) {
+...
+	} else {
+...
+	}	   
+
+Unrequired whitespace should be removed from the end of lines and end of
+file.   Hardtabs should be used where possible.  
+
+
+5.0 Compiler and Behavior issues
+
+When comparing a constant to a variable, put the constant on the
+left.  The compiler will tell you if you ommited a '='.  E.g.
+
+	if (MY_CONSTANT == var) {
+        	whatever();
+	}
+
+Please eliminate all compiler warnings.  "Compilation errors are, in a
+way, unit test failures of their own.  They tell us that the
+implementation does not match the specification." -- check.sf.net tutorial
+
+Please make forward declarations for all functions in the appropriate
+header files.  This helps us detect interface changes.
+
+Whenever practical, allocate a large block of memory OUTSIDE a loop
+and then populate it inside the loop, rather than allocating many
+small blocks inside the loop.
+
+Do not use #ifdef TEST_FRAME unless absolutely necessary.  In
+particular, if you simply call kernel functions which are not defined
+in the test frame, please add them to the test frame.  The only case
+we know of which is difficult to handle is static inline functions.
+
+We require using this style of initialization:
+
+struct in_ifaddr eth2_ifa =
+      {.ifa_next = NULL, .ifa_dev =  NULL, .ifa_local = 0, .ifa_address = 0};
+
+Keyword initializations are less susceptible to bugs due to changes in
+the underlying structures.
+
+
+6.0 Version changes
+
+The lksctp-tools  packages uses the "M.m.p" versioning  model for both
+the package itself & the provided shared libraries:
+
+- (M)-ajor revision change means  both source & binary incompatibility
+  (user source code change might be required)
+
+- (m)-inor revision change means source compatibility, while ABI might
+  not be preserved (rebuild is required)
+
+- (p)-atchlevel change means that both API & ABI are preserved.
diff --git a/doc/template.c b/doc/template.c
new file mode 100644
index 0000000..a42afec
--- /dev/null
+++ b/doc/template.c
@@ -0,0 +1,47 @@
+/* SCTP kernel Implementation
+ * Copyright (c) 1999-2000 Cisco, Inc.
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ * Copyright (c) 2001 International Business Machines, Corp.
+ * Copyright (c) 2001 Intel Corp.
+ * Copyright (c) 2001 Nokia, Inc.
+ * Copyright (c) 2001 La Monte H.P. Yarroll
+ * 
+ * This file is part of the SCTP kernel Implementation
+ * 
+ * $Header: /home/CVS/tsp/SCTP/sctp-tools/doc/template.c,v 1.1.1.1 2002/08/06 22:31:05 inaky Exp $
+ * 
+ * These functions frob the sctp nagle structure.
+ * 
+ * The SCTP implementation is free software; 
+ * you can redistribute it and/or modify it under the terms of 
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ * 
+ * The SCTP implementation is distributed in the hope that it 
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.  
+ * 
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ * 
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Written or modified by: 
+ *    La Monte H.P. Yarroll <piggy@acm.org>
+ * 
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ */
+static char *cvs_id __attribute__ ((unused)) = "$Id: template.c,v 1.1.1.1 2002/08/06 22:31:05 inaky Exp $";
+
+#include <net/sctp/sctp.h>
diff --git a/doc/what_we_were_doing.txt b/doc/what_we_were_doing.txt
new file mode 100644
index 0000000..6a2834a
--- /dev/null
+++ b/doc/what_we_were_doing.txt
@@ -0,0 +1,981 @@
+What were we doing when we stopped?
+funtest1.c
+	test_sendto()
+		Wed Sep 27 12:48:34 CDT 2000
+		We are about to write sctp_do_prm_asoc().
+		
+		Thu Sep 28 15:58:27 CDT 2000
+		DONE
+
+	test_run_network()
+		Thu Sep 28 21:37:51 CDT 2000
+		We are testing.  The first chunk we see in outqueue
+		has a chunkID of 0 (DATA), not 1 (INIT).  It also has
+		a length of 0.  It looks like a dummy chunk.
+
+		Next thing will be struct SCTP_inqueue.  We WILL
+		produce an automated test for that structure!
+
+		Fri Sep 29 19:41:21 CDT 2000
+		We fixed the bug mentioned above.
+		We have created a unit test for SCTP_inqueue.
+		Next, we should implement SCTP_inqueue.
+
+		Mon Oct  2 11:03:10 CDT 2000
+
+		Mon Oct  2 18:07:14 CDT 2000
+		Finishing up on test_inqueue.  Currently giving 
+		bad results for the chunk header for the second 
+		chunk popped.  Also need to clean up validate_queue's 
+		type-casting to make the warning go away.
+
+		Wed Oct  4 10:51:55 CDT 2000
+		We have fixed the warning.  Still working on the 2nd chunk.
+
+		Wed Oct  4 14:06:21 CDT 2000
+		We passed our first automated unit test!!!
+		sctp_bundle_out() needs writing.
+		
+		Wed Oct  4 16:36:10 CDT 2000
+		writing sctp_bundle_out()
+			writing ip_queue_xmit()
+			trying to find out how to call sctp_v4_rcv()
+			Thu Oct  5 18:40:49 CDT 2000
+			We believe that ip_queue_xmit() is "written".
+		We think sctp_bundle_out() is written.
+		We are stepping through test_run_network(),sctp_v4_rcv()
+		We have made it out to ep_put(), near the end of 
+		sctp_v4_rcv().
+		bh_[un]lock_ep(), ep_put() need writing.
+		We plan to continue through sctp_v4_rcv().
+		GOAL: return from test_run_network() by COB Friday
+
+		Fri Oct  6 18:29:01 CDT 2000
+		Gee!  We are calling ourselves forever!  We need to
+		break this cycle by implementing bottom half/top
+		half...  Welcome to the kernel!
+
+		On the upside, we made it back up into do_5_1B_init().
+		Fix the BUG BUG BUG at the end of ip_queue_xmit().
+
+		Mon Oct  9 12:17:59 CDT 2000
+		We believe test_run_network() is written--we have
+		completed on full loop.
+		
+		Here is what we expect in the next three iterations:
+Next loop:
+	ep2: send the INIT_ACK
+	ep1->asoc: process the INIT_ACK, enter COOKIE_ECHOED, queue COOKIE_ECHO
+ueber-next loop:
+	ep1->asoc: send the COOKIE_ECHO, send the DATA
+	ep2->asoc: process COOKIE_ECHO, make asoc in ESTABLISHED, queue COOKIE_ACK
+		process DATA, queue SACK
+ueber^2-next loop:
+	ep2->asoc: send COOKIE_ACK, SACK
+	ep1->asoc: process COOKIE_ACK, enter ESTABLISHED, process SACK,
+		free DATA
+
+		Mon Oct  9 18:53:44 CDT 2000
+		The test for SCTP_outqueue now fails!  Yay!
+		Mon Oct  9 20:41:36 CDT 2000
+		The test for SCTP_outqueue now passes!  Yay!
+		
+		Goal for tomorrow:  Return from test_run_network().
+		Continue through the loop...
+
+		The DATA packet is ending up in the endpoint queue, not the
+		assoication queue.
+		Tue Oct 10 15:26:54 CDT 2000
+		Fixed.  This is correct behaviour, but now we look for
+		the association AGAIN.
+
+	The TSN is not getting set.  This should happen in the
+	SCTP_outqueue.
+	Tue Oct 10 15:55:27 CDT 2000
+	Added a test to test_outqueue for TSN fix.
+	Yay, test_outqueue fails!
+	
+	Added a test to test_inqueue for the end-of-packet
+	callback feature.
+	Tue Oct 10 17:32:53 CDT 2000
+	Passing test...  We are now using the feature in sideeffects.c.
+	Are we getting a SACK now?
+	Tue Oct 10 18:58:25 CDT 2000
+	Yes!  We ARE getting a SACK!  Yahoo!
+
+	Plan for tomorrow:  sctp_recvmsg(), sctp_send_up().  This is
+		probably a new data struture...
+
+	Wed Oct 11 14:21:32 CDT 2000
+	Yes, it is several... 7?  Sigh.
+	Yay!  test_ULPqueue fails!
+
+	Wed Oct 11 16:56:06 CDT 2000
+	DANGER, WILL ROBINSON!  NOT ALL UNIT TEST PASS!  But the day
+	is over and piggy needs to leave...
+	WRITE sctp_ULPqueue.c:sctp_ULP_chunk2event()
+
+	Thu Oct 12 12:08:23 CDT 2000
+	Put SCTP and IP headers on the test chunk.  Make sure that
+	skb->data, however, points at the actual payload.
+	
+	Thu Oct 12 15:40:00 CDT 2000
+	test_ULPqueue passes!  Yahoo!
+	Back to funtest1...
+
+	options for things that changed which might corrupt the
+		MD5digest: 
+		do_gettimeofday() replaced get_time()
+		tv_add() replaced net_profile_add()
+		get_random_bytes() replaced net_random()
+	I switched to MD5 and the problem disappeared.  This is very
+	bad.  The problem is that the SLA1 code is overruning the
+	stack and creaming its parent's variables.  Specifically,
+	context->howManyInBlock is getting above 64 (the size of the
+	block).  This causes "leftToFill" to become negative at line
+	195 and then things really fall apart.  This looks like a bug
+	to me, but it worked before... 
+
+	Fri Oct 13 10:14:37 CDT 2000
+	Goal for today:  Get through ueber^2-next loop.
+
+	Don't forget to look for that COOKIE ACK...
+
+	Fri Oct 13 16:52:11 CDT 2000
+	We have delivered a data packet all the way to the user from
+	the other user!  We do not seem to have either a COOKIE_ACK OR
+	a SACK.  Such is life...  More to do...  We do not deliver the
+	COMUP event either...
+
+	We sort of deliver the COMMUNICATION_UP message.  What a WASTE.
+
+	We REALLY need to get back to COOKIE_ACK/SACK.  By early next
+	week we MUST be all the way to SHUTDOWN_ACK.
+
+	Mon Oct 16 12:19:18 CDT 2000
+	We DID see that COOKIE_ACK/SACK.  We have received three
+	packets.  Check to make sure we got the second SACK.
+
+	Goal for today:  Generate a SHUTDOWN.  This means a new event
+	type for the state machine:  OTHER.
+	
+	Mon Oct 16 15:11:16 CDT 2000
+	We have finished sctp_close().
+
+	Mon Oct 16 20:52:42 CDT 2000
+	We got a SHUTDOWN processed.
+
+	The NO PENDING TSN event needs to be scheduled so that it
+	happens AFTER all the side effects for the PRIOR event.
+
+	Refactor the SACK processing OUT of sctp_outqueue.c--use the
+	empty handler.  REMEMBER TO WRITE THE TEST FIRST!
+	
+	Once all that works, continue on to generating SHUTDOWN ACK.
+
+	Goal for tomorrow: pass empty handler test, get back to the
+	point in the functional test where we are ready to generate
+	SHUTDOWN ACK.
+
+	Stretch goal for tomorrow:  Get to the end of the functional test.
+
+	Tue Oct 17 11:39:00 CDT 2000
+	We added sctp_delayed_side_effects() where we can execute side
+	effects which MUST happen after all other side effects are
+	processed.
+
+	The test for the empty queue feature now fails!
+
+	Tue Oct 17 11:54:51 CDT 2000
+	The test for the empty queue feature now passes!
+	
+	We have decided to put this off until post-Bakeoff:
+		Refactor the SACK processing OUT of
+		sctp_outqueue.c--use the empty handler.  REMEMBER TO
+		WRITE THE TEST FIRST!
+	P.S. We DO use the empty handler now, but SACK processing is
+	still partially embedded in outqueue.
+
+
+	DONE: sctp_do_9_2_final() should generate an event to send to the
+	ULP...
+	DONE: We need to deal with the possibility of an association
+	unlinking in the middle of an SK_FOR.
+	If there are undelivered notifications in association, delay
+	its freedom.
+
+	Tue Oct 17 18:17:07 CDT 2000
+	We completed the full protocol negotiation in funtest1.c!
+	Yahoo!
+	DONE: All that remains is to keep the association around
+	long enough to deliver the final notification.
+	DONE: Also, sctp_do_4_C needs to generate a ULP event too...
+	The three major tools... No, four...
+
+	Goal for tomorrow: 
+	1) Running functional test by lunch time.
+	2) Make the kernel link.
+	
+	Wed Oct 18 10:42:40 CDT 2000
+	We now set the destination address correctly.  (We think...)
+	
+	Wed Oct 18 12:42:05 CDT 2000
+	The unit tests run again.  Setting destination addresses broke
+	a couple of them...
+
+	Wed Oct 18 14:45:26 CDT 2000
+	Yeehaw!  The functional test passes!
+
+	Wed Oct 18 15:23:26 CDT 2000
+	The kernel links!
+
+	Tasks:
+	Write a kernel functional test.  Make it fail.
+	Write sctp_sendmsg().
+	Register all the SCTP structs in the right places...
+	Move funtest1.c:test_run_network functionality into the
+	kernel.
+
+	Wed Oct 18 16:44:30 CDT 2000
+	funtest2 now fails!  Yay!  It features cool error messages...
+
+	goals for tomorrow:
+	DONE: 1) Write sctp_sendmsg().
+	DONE: 2) Register all the SCTP structs in the right places...
+
+	Thu Oct 19 12:09:43 CDT 2000
+	We have a first draft of sctp_sendmsg().
+	DONE: Write lower level functions for sctp_sendmsg().
+	DONE: Fix the retval misuses in sctp_recvmsg().
+	DONE: Check all of sctp_socket.c for user space memory references.
+
+	Thu Oct 19 18:10:27 CDT 2000
+	FIXED: We are failing to generate SACKS.  It appears that pop_inqueue
+	is deciding that eop is not happening for data chunks.
+
+	Thu Oct 19 21:32:36 CDT 2000
+	It appears that at least the three key structures (sctp_prot,
+	sctp_protocol, and inet_seqpacket_ops) are properly
+	registered.
+
+	We also sort of fixed a problem with queue_xmit--it needs to
+	be transport specific.  We still do not set it properly in the
+	transport structure, but as a hack, we steal it from the ep.
+
+	goals for Friday:
+	1) Move funtest1.c:test_run_network functionality into the
+	 kernel.
+	2) Have a real kernel panic!
+	3) Move the repository onto one of the laptops...
+
+
+	Fri Oct 20 18:23:43 CDT 2000
+	test_inqueue now fails after changing handler handling
+	(i.e. item 1 above)!
+
+	Fri Oct 20 18:39:30 CDT 2000
+	test_inqueue now passes! (as do test_outqueue & test_ULPqueue)
+	funtest1, anyone?
+
+	We refactored to get rid of sctp_sm_delayed_sideeffects().
+	This led to outqueue empty processing getting a LOT cleaner.
+	This also forced us to fix the empty test in test_outqueue and
+	feed it a REAL(ish) SACK.  This led us in turn to a VERY
+	subtle TSN bug.  XP RULES!  YOW YOW YOW!!!!
+
+	Fri Oct 20 23:28:57 CDT 2000
+	We passed the functional test and all the unit tests.  We
+	think we have something we MIGHT be able to link into a kernel
+	and test...
+
+	3) Move the repository onto one of the laptops...
+
+	Goal for Monday:
+	2) Have a real kernel panic!
+
+
+	Tue Oct 24 16:10:44 CDT 2000
+	Still no kernel panic, but we have some things which seem to work!  Yowza!
+
+	Specifically, sctp_socket(), and sctp_bind() appear to work.  We get an
+	-EFAULT when we call sctp_sendmsg().  In sctp_recvmsg() we had a hang.
+	
+	Tue Oct 24 16:57:05 CDT 2000
+	unit tests pass (again)!  Yahoo!
+	
+	Wed Oct 25 10:57:59 CDT 2000
+	funtest3 rewritten to use getopt and support addresses other
+		than the loopback.
+	Wed Oct 25 11:47:18 CDT 2000
+	funtest3 --listen fails!
+		
+
+	Thu Oct 26 00:18:43 GMT-6 2000
+	Why are we getting EINVAL? 
+	- We are certain that the address going to bind is in kernel space.
+	- Add the endpoint port--we wish to differentiate the two
+	  possible failures. 
+
+	Wed Oct 25 16:38:56 CDT 2000
+	We are setting the peer's port to network byte order in one or
+	both of the following: sctp_create_asoc(), sctp_add_transport().
+	We are trying to make funtest1 pass again...
+
+	We are trying to not panic in funtest3 --listen.
+
+	Thu Oct 26 14:23:08 CDT 2000
+	Created the macro DEBUG_PRINT() and a matching unit test
+	(foolishly put in funtest1.c...).  It failed!  It passes!
+
+	By the end of the day we completed a full INIT-DATA-SHUTDOWN
+	sequence with the user space refimpl!  We listened and the
+	usref initiated.
+
+	Fri Oct 27 08:46:41 CDT 2000
+	Goal for today:  Do the equivalent of funtest2 with funtest3
+	(interoperate both directions with the usref).
+
+	Fri Oct 27 10:13:39 CDT 2000
+	funtest3 --send fails!
+
+Tue Jan 16 01:54:34 CST 2001
+        We have two bugs:
+	1) Line 277 in sctp_endpointola.c.
+	2) We need to handle non-existent ep properly, almost
+        everywhere.
+	We need to add a blow-away-the-endpoint test to one of the
+        functional tests.
+
+Wed Jan 17 02:19:18 CST 2001
+	We fixed bug 1, and now cherish bug 2 wholeheartedly.
+
+	We don't (?) need a blow-away-ep test, but we eventually need
+	to work on the out-of-the-blue-packet story.
+
+	We now pass funtest1 and funtest1b (Yeah!).
+
+	Next up: funtest3 with back to back associating, and (dare we
+	hope?) funtest2. (Note: _No_ _work_ will be done to fix
+	funtest2 until after the Developers' Release.)
+
+Tue Jan 30 16:00:26 CST 2001
+    We have a simple-minded merge of our SCTP changes into 2.4.1.
+    This merely resolved the conflicts--tag 'linux-2_4_1+sctp' will
+    NOT compile.  We need to do all the data structure changes.
+
+
+Tue Feb 27 20:07:52 CST 2001
+
+In the middle of getting funtest1 to work (again), test_print_message
+prints a bad type for a message.  May be a related CORE_DUMP in there
+somewhere too...
+
+Fri Mar  2 20:50:22 CST 2001
+
+We believe that sctp_flush_outqueue is pretty-much ready except for
+starting the timers.  We need to stop the timers in 
+need to generate the timeouts (
+
+6.3.2 R2 tells us to turn off T3-rtx when we get acks for all data on
+    an address...
+
+We REALLY want a per-transport transmitted queue.  What we want to do
+is a outqueue-private component of the transport data structure.
+
+DONE: PLAN FOR MONDAY:  Make a release w/o lost_data packet.
+PLAN FOR Wednesday after next:  Release including lost data packet and
+whatever else we jam in...
+
+DONE: Write a unit test for bundling.
+Pass the unit test for bundling.
+Make the transmitted queues transport based because we need a per
+transport timer which gets turned off when there is nothing in flight.
+Make ft_frame_lostpacket pass.
+
+Tue Mar 13 19:44:27 CST 2001
+We are working on getting test_outqueue to work again, this time with
+bundling.  The code compiles, but still dumps core.  It looks like a
+bug in the test frame (q->asoc is NULL).
+
+Wed Mar 14 14:07:51 CST 2001
+The unit tests (including the bundling mods for test_outqueue) pass.
+The mods were to comment out sock_hold in the set_owner..., since it
+kept landing us in the real kernel code (asm/atomic.h).  We thought
+this was due to string.h, but that gets called in somewhere magically
+too.
+
+Final mod was an if around the last sctp_transmit_packet for when the
+payload size isn't > 0. I (KK) added a catcher for payload_size < 0.
+
+Now on to making the transmitted queues transport based.(?)
+
+Wed Mar 14 16:26:59 CST 2001
+Have added transmitted (not private) to SCTP_transport and initted in
+sctp_add_transport().  Next would be sctp_flush_outqueue().
+
+Thu Mar 15 19:15:24 CST 2001
+Whew.  We added transport-transmitted to sctp_empty_outqueue(),
+sctp_flush_outqueue() and sack_outqueue().  We also took the
+check-transmitted-queue logic out of sctp_sack_outqueue() and added
+sctp_check_transmitted(). 
+
+We also isolated a wacky SK_FOR behavior that had us stumped for a
+while.  If you pass a local variable to SK_FOR as the_list, it has
+trouble ending the for loop since the local variable is on the stack
+(for the calling function), but the end iteration for the for"ing"
+(the real the_list) would be whereever it was before being copied into
+the local variable.
+
+Anyhow, the unit tests pass (although we haven't committed yet.)
+
+Fri Mar 16 19:19:01 CST 2001
+We fixed a padding problem with the bundling code (and its attendant
+problems with the ULPqueue/recvmsg code).  The unit tests and all
+ft_frame tests (except lostpacket, naturally) pass!  Have not run
+ft_kernel_basic yet.  Despite this, I'm committing, since La Monte and
+I(KK) will be at the IETF next week.  I also need to remember to put
+Perry's name in the code he's worked on.
+
+
+Mon Mar 19 17:31:37 CST 2001
+We were creating a new kind of smart pipe, the SCTP_packet.  Stuff
+packets in the top until they transmit.
+
+Tue Mar 27 11:26:26 CST 2001
+Write the unit test for SCTP_packet.
+
+Fri Apr  6 01:18:32 CDT 2001
+We THINK we have a full implementation of the sockets protocol table.
+We will have a go at integrating af[6]_inet.c into our test frame so
+we can write tests for it...
+
+Tue Apr 10 11:39:13 CDT 2001
+Finish SCTP_packet today.
+
+Tue Apr 10 21:39:25 CDT 2001
+Yeah, right.
+
+OK, we're in the middle of transforming transmitted_queue and
+sacked_queue into struct list_head's so that we can avoid copying
+chunks when putting them in packets.
+
+What remains:
+DONE: Make test_outqueue compile.
+UNDONE: Make test_outqueue fail.
+DONE: Finish transforming SCTP_outqueue to the new interfaces.
+DONE: Make test_outqueue pass.
+
+DONE: Make test_packet compile.
+DONE: Make test_packet fail.
+DONE: Write SCTP_packet (sctp_output.c).
+DONE: Make test_packet pass.
+
+DOING: Get on with lost packet.
+
+Wed Apr 11 16:38:52 CDT 2001
+Yay!  We have test_outqueue passing...
+
+Thu Apr 12 10:23:01 CDT 2001
+Goal for today:  Make test_packet compile and fail.
+Do an intermediate commit.
+
+Thu Apr 12 16:56:53 CDT 2001
+We hit our goal for the day!
+We've just finished the horrible table in sctp_append_chunk().
+We need to write sctp_transmit_packet().
+
+Mon Apr 16 10:39:27 CDT 2001
+DONE: Goal for the day:  Get all unit tests to pass (test_packet being the
+current red-headed-stepchild.)
+
+Mon Apr 16 15:36:42 CDT 2001
+Yay!  We've hit today's goal!
+
+Mon Apr 16 17:22:44 CDT 2001
+Milestone: all ft_frame passes except lostpacket (Almost out of the
+refactoring quagmire...).
+
+Mon Apr 16 19:12:37 CDT 2001
+Milestone: ft_frame_lostpacket now fails (after being rewritten a bit).
+
+SKIPPED: Fix up the statefun retval to communicate timer updates properly.
+DONE: Start the rtx timer.
+DONE: Make sure the rtx timer set/clear events are generated by the
+      appropriate state functions.
+DONE: Create the rtx timeout state function.
+Update the side effects to:
+       SKIPPED: Process rtx timer updates.
+       DONE: Move chunks from transmitted to retransmit.
+       DONE: Call flush with rtx_timeout set.
+
+Plan for tomorrow:
+DONE: Create the timeout event.
+DONE: Make ft_frame_lostpacket pass.
+DONE: Run ft_kernel_basic, make it pass.
+DONE: Run sctp_darn tests. (They failed, though...)
+
+Tue Apr 17 17:27:15 CDT 2001
+ft_frame_lostpacket passes!  Yeeha!
+
+Tue Apr 17 19:01:22 CDT 2001
+ft_kernel_basic passes--insignificant changes needed for compilation.
+
+Wed Apr 18 14:58:30 CDT 2001
+DONE: Write ft_frame_evenpackets.
+DONE: Have it compile and fail.
+DONE: Write sack timer support code.
+DONE: Have it compile and succeed.
+
+Wed Apr 18 16:36:17 CDT 2001
+We did a small refactoring where we changed most instances of
+struct timeval into jiffies.  We can't do this for every struct timeval
+since sk->stamp is a struct timeval and we use this to check cookie
+lifetimes.   C'est la vie.  So geht es in Leben.
+
+ft_frame_evenpackets fails!  Yeeha!
+All unit tests pass!
+
+Thu Apr 19 10:34:04 CDT 2001
+Goal for morning: ft_frame_evenpackets passes.
+To make it pass, the sack timer should be:
+DONE:  - initialized
+DONE:  - started
+DONE:  - stopped
+DONE:  - event (expiration)
+DONE:  - state function
+
+DONE:  - sctp_do_timerWork       
+   
+Thu Apr 19 13:17:08 CDT 2001
+We've written the sack timer code and it compiles, but the ft still
+fails.
+
+Thu Apr 19 15:39:58 CDT 2001
+ft_frame_evenpackets passes!  Yay!
+
+What we need to do for multihoming:
+DONE: Extend test frame for multilink.
+Write ft_frame_lostlink.
+Make ft_frame_lostlink compile.
+Make ft_frame_lostlink fail.
+Write multi-homing support:
+- Add counter events to OTHER table
+- Stroke error counts (8.2)
+DONE: - Write sctp_bindx() (API 8.1)
+- Clear error counter when RTX timer is stopped. (8.2)
+- Do failover state function (8.2, 6.4.1)
+- Do failover side effects
+- Change sctp_transmit_packet() to modify the socket for the chosen
+  destination address.
+- Change transport selection to skip inactive destinations (bakeoff 3.6)
+Make ft_frame_lostlink pass.
+
+Thu Apr 19 23:01:11 CDT 2001
+We need to refactor the whole INIT/INIT ACK/COOKIE ECHO startup
+sequence to make the INIT header processing more symmetric.  In
+particular, we are going to put the whole INIT chunk (with all
+parameters) into the cookie and simplify the cookie as much as
+possible.  This allows both sides to take a skeletal association and
+an INIT packet and build a full association.
+
+Check whether the initial destination address needs to be
+automagically added to the list of IP addresses for the association.
+
+Fri Apr 20 17:28:42 CDT 2001
+We're in the middle of the aforementioned refactoring.  We are working
+our way through the function do_5_1B_init().  Credo that
+sctp_make_temp_asoc() is now properly rewritten.  Next to rewrite is
+sctp_make_init_ack().
+
+tar up THIS directory heirarchy
+copy to both laptops
+check out the most recent CVS'd stuff on both laptops
+
+
+Sat Apr 21 18:31:28 CDT 2001
+I'm in the middle of sctp_unpack_cookie().  Make sure that everything
+lines up properly...  I THINK the static parts of the INIT are still
+unaccounted for.  Maybe.  Maybe not...  No, I think those are part of
+asoc->c, in which case, they are properly handled.
+
+Check that we do all three passes through the variable-length
+parameters: INIT, INIT ACK, COOKIE ECHO (INIT is in the cookie).
+
+Sun Apr 22 01:46:21 CDT 2001
+See the FIX ME in sctp_unpack_cookie();
+
+Tue Apr 24 16:43:30 CEST 2001
+sctp_make_cookie_echo() in sctp_side_effects() returns a malformed chunk.
+
+Thu Apr 26 10:44:15 CEST 2001
+We have a buildable kernel and we pass all unit and functional tests
+except ft_frame_lostlink.  ft_kernel_basic remains untested.  The plan
+for today is to get some interop test run with Sun and perhaps some
+others...
+
+Thu Apr 26 18:36:54 CEST 2001
+We have a deadly INIT packet from Sun.  We are trying to make a test
+frame from the deadly packet.
+
+Added WORD_ROUND() to sctp_addto_chunk() to support correct parameter
+bounding...
+
+Added some infrastructure to support replacing arbitrary packets in a
+transaction.  This doesn't work yet and isn't quite as flexible as we
+really want.
+
+Fri Apr 27 11:34:22 CEST 2001
+Start the SSN at 0, not 1.
+Increment the SSN.
+
+Tue May  1 16:11:17 CDT 2001
+These are the changes that piggy made on the airplane from Nice:
+
+DONE: Do duplicate checking in sctp_bind_endpoint().
+
+DONE: Add struct bare_ip_sctp_packet.
+
+DONE: Modify CHUNK_TYPE() so that it can work even if an IP header is present.
+
+DONE: Fix the calls to CHUNK_TYPE().  The first call is on an IP packet with
+    a header.
+
+Wed May  9 15:39:23 CDT 2001
+
+Implement Jon Grimm's suggestion about sctp_init().  
+
+DONE: 1.  Take the sctp_proto_initted check out of sctp_get_protocol(). 
+
+DONE: 2.  Call module_init(sctp_init) at the end of sctp_protocol.c
+          (Less random, but more thoughtful, placement.)
+
+DONE: 3.  Modify the frame tests to call sctp_init() directly.
+DONE: 4.  Test the simulated daylights out of it.
+UNDONE: 5.  Test the living daylights out of it.
+
+
+Wed May  9 16:41:47 CDT 2001
+DONE: Include <sys/sctp.h> from sctpConstants.h.
+DONE: Go through sctpConstants.h looking for stuff needed by the user and
+   moving it to sys/sctp.h.
+DONE: Go through sctpEvent.h looking for stuff needed by the user and
+   moving it to sys/sctp.h.
+DONE: Test the simulated daylights out of it.
+DONE: Test the living daylights out of it.
+
+Thu May 10 11:55:57 CDT 2001
+We moved kernel/include/sys/sctp.h to linux/include/linux/sctp.h.  The
+kernel does NOT have an include/sys/ directory, and
+include/linux/tcp.h has sortof similar semantics...
+
+Move linux/include/linux/sctp.h to kernel/include/net/sctp/sctp_user.h
+and copy THAT to kernel/usr_include/netinet/sctp.h.
+
+Thu May 10 16:34:35 CDT 2001
+Here are all the horrible places we need to put "132":
+DONE: /usr/include/linux/socket.h
+DONE: /usr/include/linux/in.h
+DONE: /usr/include/netinet/in.h
+These are all in kernel/usr_include and kernel/Makefile has been
+modified appropriately.
+
+DONE:Tomorrow:  Describe the hijack attack in detail in an email message to
+                Randy and Qiaobing.
+
+Fri May 11 15:43:46 CDT 2001
+Next possible tricks are to work up tests for the SACK processing/RTX
+work, the spicy INIT, or ft_frame_lostlink.
+
+We will extend ft_frame_lostpacket to include multiple lost packets
+and we will have it check reordering.
+
+Wed May 16 14:50:29 CDT 2001
+First pass priority list: Develop tests for these bugs encountered at
+the 3rd bakeoff.  (For Wednesday, go for the low hanging fruit.)
+
+BUG:    We ignore ABORT.
+TRACE:  compaq3_paddedinitackOK.tcp 
+TEST:   ft_frame_abort
+
+BUG:    We will send extra data before we get a COOKIE ACK...
+TRACE:  datakinectics_2 
+        We really lucked out and this implementation ran fine...
+TEST:   <ft_frame_delayed_cookie_ack, this involves adding a packet
+        delay queue to the network simulation>
+
+BUG:	We have an INIT that causes an oops.
+TRACE:  sun (lost trace)
+TEST:   ft_frame_init_bomb
+
+BUG:   This INIT ACK causes an oops.
+TRACE: telesoft2_lostsendings.tcp, telesoft3_spicyinitack.tcp
+TEST:  <new test: modified ft_frame_init_bomb>
+
+BUG:   We don't gap ACK.
+BUG:   We retransmitted a TSN which they had gap ack'd.
+TRACE: datakinectics_3, ulticom_3
+TEST:  <extend ft_frame_lostpackets to add tests for gap acking>
+
+BUG:   We produce MANY SACK's in a row.  Bleah.  This isn't officially
+       a bug.  Is it legal for us to look ahead in our input buffer?
+       Well, Stevens thinks that this is correct behaviour.  We should
+       NOT look ahead in our input buffer.
+TRACE: adax2_goodsend.tcp
+TEST:  no test needed
+
+BUG:   We did not bundle retransmissions.
+TRACE: adax2_goodsend.tcp
+TEST:  <modify ft_frame_lost_packets, catch the retransmissions and
+       inspect them on the wire (in Internet[]).>
+
+Mon May 21 15:56:47 CDT 2001
+Today and Tuesday are SCTP days. (Like Crazy Days, only more SCTP and
+less street fair.) 
+
+Write the ABORT test.
+
+Tue May 22 18:49:51 CDT 2001
+Once again, we are changing the end-of-packet handling to solve some
+nasty problem.  There are two issues here:
+FIXED: - sctp_tq_sideeffects is global and very dangerous (i.e. wrong)
+FIXED: - sctp_gen_sack can be called on an aborted association--it
+       still has a pointer to the free'd memory...
+
+Solution:
+We are marking the last chunk in a packet as the final chunk.
+DONE: - Add the eop flag to SCTP_chunk.
+DONE: - Set the eop flag for the final chunk (sctp_pop_inqueue()).
+DONE: - Initialize the eop flag when we create a new chunk (sctp_chunkify()).
+DONE: - Add gensack to the retval structure.
+DONE: - Modify the data state function to set retval->gensack if eop is set.
+
+DONE: - Set up gensack side effect.
+DONE: - Fix up the prototype for sctp_gen_sack().
+
+DONE: - Create asoc->sack_needed.
+DONE: - Dispose of asoc->peer.dataSeen
+DONE: - Dispose of asoc->counters[SctpCounterAckState]
+DONE: - Dispose of chunk->counted
+
+DONE? - Dispose of sctp_tq_sideeffects and friends.
+DONE: -- call sctp_other_no_pending_TSN() from sctp_side_effects().
+DONE: -- eliminate handlers.empty, etc...
+
+Wed May 23 14:43:44 CDT 2001
+Pass the rest of the ABORT test.  This means we want to GENERATE
+aborts.  This is the function tabort_8_4_8.
+
+Since we need to generate ABORTs in the CLOSED state, we want to have
+a way to send them without having to build a temporary association.
+
+We will  generate a packet for this purpose
+and will call sctp_transmit_packet() on it at the appropriate time.
+
+DONE: - extract relevant data from chunk and endpoint.
+DONE: - change sctp_init_packet to not require the association.
+- build packet
+DONE: - build transport
+DONE: -- refactor sctp_add_transport() to create a sctp_make_transport().
+DONE: --- Add fields for storing af_specific in proto.
+DONE: --- Initialize the af_specific parts of proto.
+DONE: --- Add a mechanism for fetching af_specific from proto.
+DONE: - add retval->packet
+DONE: - add retval->packet handling to SCTP_DISPOSITION_DISCARD.
+DONE: - add prototype for sctp_get_af_specific()
+DONE: - add prototype for sctp_make_transport()
+DONE: - fix call to t_new()
+
+DONE: - Update the state tables to call tabort.
+
+Tue May 29 11:53:18 CDT 2001
+We are applying Jon Grimm's patch.
+DONE: - Edit patch
+DONE: - Apply patch
+DONE: - Add Jon's contact info
+DONE: - unit_test
+DONE: - frametest
+
+Add Xingang Guo's patch.
+DONE: - Edit patch
+DONE: - Apply patch
+DONE: - Check the lock coverage paths
+
+Main changes from patch:
+-- sctp_{lock|release}_sock()
+-- moved locking in sctp_sendmsg() to right before looking up association
+-- checking return values of copy_{to|from}_user
+-- goto out_unlock for EVERY setting of err in sctp_sendmsg()
+-- sctp_setsockopt() had returns with locked socket.
+
+DONE: - Update copyright and credits
+DONE: - is emsg->msg_flags properly initialized somewhere?
+      -- Yes, but it might not conform to the API draft...
+DONE: - unit_test
+DONE: - frametest
+
+DONE: - kerneltest
+
+DONE: - Make new release
+DONE: - publish release to Source Forge.
+DONE: - Send note to list detailing changes to Xingang's patch...
+
+Thu Jun 14 17:41:04 CDT 2001
+A plan for patch application.  We have 5 patches:
+
+jgrimm_delayed_ia_01_Jun.patch (subsumed by next one)
+jgrimm_tsn_lt_04_Jun.patch (subsumed by next one)
+EDITED: jgrimm_ecn_06_Jun.patch
+
+DONE: We still want to edit Jon's patch to deal with the ecn_allowed vs.
+      ecn_capable issue.
+
+Mon Jun 18 12:07:32 CDT 2001
+DONE: xingang_patch.debug.v011
+xingang_patch.INIT_ACK.v011
+
+Wed Jun 20 18:06:20 CDT 2001
+Fix Daisy's bug:  Null pointer check needed for chunks
+
+sctp_make_chunk() may return a NULL pointer, therefore, 
+every place that sctp_make_chunk() is called needs to 
+verify the return value to prevent from using any NULL 
+pointer down the road. Right now, in 2_4_1-0_1_1, all 
+of these routines, such as sctp_make_init(), 
+sctp_make_data_empty(), sctp_make_sack(), etc, uses the 
+return value from sctp_make_chunk() assuming that it is 
+non-NULL.
+
+Here are functions which are propigating the NULL bug:
+sctp_make_init
+
+Wed Aug  1 13:25:18 CDT 2001
+DONE: Apply Jon's patch
+DONE: Remove definitions of *Unified*
+DONE: Add comments on deviation from CWR rules.
+DONE: Make myNextTSN an atomic_t.
+DONE: Create sctp_config_packet(vTag, ecn_handler), and (*packet->config)()
+Move last_cwr_tsn adjustment into sctp_handle_congestion().
+Move CWR generation into the state function?
+
+Fri Aug 17 18:38:29 CDT 2001
+We're going through sctp_ipv6.0_1_2.patch.  We've read everything but
+the tests.
+
+Mon Aug 20 15:37:47 CDT 2001
+We're about to plunge back into the ipv6 patch, mostly after the SCTP
+Business meeting at 4pm, hopefully after we commit the latest changes
+(the ones to the style guide and to sctp_v4_rcv().)
+
+Thu Aug 23 13:45:53 CDT 2001
+We cleared all outstanding integration (bug fixes, cmd_seq_t,
+ChunkDesc overallocation...).  We also refactored the retval timers to
+be sctp_cmd_seq_t's.  Now the trick is to get a test to fail because
+of the sctp_gen_sack() timer issue.
+
+Fri Aug 24 18:51:20 CDT 2001 
+
+Well, we got the test (ft_frame_sack) to fail.  Not quite where we
+wanted...but we have a pretty cool test to make up for it.  Where we
+*do* fail is by sending one too many SACKs (for the test, Piggy).  We
+send a SACK for every odd numbered packet without considering SACK
+timeouts.  This is legal, but inelegant and screwy.
+
+On Monday, we're going to check and see how much torture this will be
+to refactor.  Then we'll probably do it anyway, code-starved as we
+are.
+
+Mon Aug 27 18:04:01 CDT 2001
+OK, we are now passing ft_frame_sack, but ft_frame_ecn_basic fails.
+The problem is that we need to do ECN processing BEFORE we generate
+the SACK, but we are now generating the SACK in the side effects
+interpreter, which runs BEFORE the rest of all that stuff.  The fix is
+to convert ECN processing to use retval->commands.
+
+Tue Aug 28 17:50:27 CDT 2001
+Notes on ft_frame_lostpackets (mysterious dup TSNs):
+??? Shouldn't we be sacking 98d? 
+AAA No, because c and d are in the same packet
+??? How many times do we start the SACK timer per packet? Should this be
+conditional on end_of_packet?
+AAA I think once per packet, since we're running a small danger of ST
+expiration before all data is processed.  Might as well wait.  We do now.
+
+NNN In the non-sequential case, our sack doesn't gap ack (that's one),
+also, we sack on the reception of the middle data in that test, and
+then (presumably) stop the sack timer so the "forward time until sack"
+there does nothing.
+
+NNN When the rtx timer expires, we naturally deliver all 3 things in
+queue, and the middle one (a dup TSN) kills the test.
+
+So: a) we should gap ack, and b) dup TSNs shouldn't kill the test.
+
+SACK hunt:
+doTSNupdate looks ok.
+In sctp_gen_sack(), we would (I think) have sent f because it's an
+alternate data packet, but we also send it because it's a gap--
+(AP(max_tsn_seen) is above the AP(CTSNAckP)).
+AHA!  sctp_make_sack() evades the whole topic of gap acking!
+That'll do it...
+
+Wed Aug 29 10:41:31 CDT 2001
+Upgraded ft_frame_lostpackets to see a gap-ack-unconditional sack.
+
+??? How can we fail the test when we don't gap ack without failing on
+dup TSNs?
+
+Wed Aug 29 15:15:29 CDT 2001
+We've now created a stub for duplicate reporting--a duplicate TSN is
+no longer an error.
+
+We're going to eliminate our duplicate detection test and see if we
+now could pass ft_frame_lostpackets...  Yep!  The new test is
+meaningful!
+
+Our new goal is to make the revised ft_frame_lostpackets pass by
+implementing gap acks.  But first...
+
+Change to using Jon's new data structure!
+Integrate sctp_tsnmap_t.
+Implement gap acks.
+
+Wed Aug 29 16:34:55 CDT 2001
+We are going through lksctp-2_4_1-0_1_13.tsnmap.patch2 preparing
+comments and massaging the patch.  We need to finish this and apply
+the patch.
+
+Thu Aug 30 18:00:54 CDT 2001
+We applied Jon's patches and refactored the TSN map code to use them.
+
+Tomorrow,  Gap Acks!
+
+Fri Aug 31 14:44:37 CDT 2001
+DONE: Add a descriptive comment for sctp_check_transmitted().
+DONE: Remove the comment at sctp_outqueue.c:636.
+
+Fri Aug 31 15:59:34 CDT 2001
+OK, frametest and unit_test both pass completely.
+Unfortunately, we seem to have fixed ft_frame_biggap.  Since we did
+NOT implement fast retran, we were not expecting this.  We want this
+test to fail again.
+
+There are two possibilities:
+1) The test is wrong--it does not truely generate the big gap condition.
+2) We introduced a bug which masks the big gap bug.
+3) We really did fix the bug.
+
+It was possibility 3.  Oops.  We did not implement fast retran, but we
+DID make big gap a command rather than an error.
+
+Tue Sep  4 11:09:20 CDT 2001
+
+We successfully transferred 10M of data from the user space
+implementation to a live lksctp.  Throughput was pretty raw--about
+25k/sec on a 100Mbit link with a PII-400, and 100 byte chunks.  The
+fact that we do not advertise a growing rwnd hurts us a lot--we'd be
+about 1.8X faster if we did.  That's still not extraordinarily
+fast--we really want to try this with the printk()s removed.
+
+Mon Sep 10 17:49:29 CDT 2001
+A little integration makes the world go round.  (patch.inaddr_any.04)
+
diff --git a/libsctp.pc.in b/libsctp.pc.in
new file mode 100644
index 0000000..b1eafaf
--- /dev/null
+++ b/libsctp.pc.in
@@ -0,0 +1,10 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: sctp
+Description: User-level SCTP API library
+Version: @VERSION@
+Libs: -L${libdir} -lsctp
+Cflags: -I${includedir}
diff --git a/lksctp-tools.spec.in b/lksctp-tools.spec.in
new file mode 100644
index 0000000..8c2ce1b
--- /dev/null
+++ b/lksctp-tools.spec.in
@@ -0,0 +1,192 @@
+# -*- rpm-spec -*-
+# 
+# lksctp-tools.spec.in --- RPM'ed lksctp-tools
+# Author          : Francois-Xavier Kowalski
+# Created On      : Sat Jan 10 14:53:53 2004
+# Last Modified By: Vlad Yasevich
+# Last Modified On: Tue Jan 08 10:56 EDT 2013
+# 
+#   (c) Copyright Hewlett-Packard Company 2004
+#   (C) Copyright IBM Corp. 2004
+# 
+#   This program is free software; you can redistribute it and/or
+#   modify it under the terms of the GNU General Public
+#   License v2 as published by the Free Software Foundation; only
+#   version 2 of the License is valid for this software, unless
+#   explicitly otherwise stated.
+# 
+#   This software is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+#   General Public License for more details.
+# 
+#   You should have received a copy of the GNU General Public
+#   License v2 along with this program; if not, write to the
+#   Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+#   MA 02139, USA.
+
+%define lksctp_version @VERSION@
+
+# older lksctp-tools file name did not conform to RPM file naming
+# conventions
+
+%define pack_version %{lksctp_version}
+%define file_version %{lksctp_version}
+
+Summary: User-space access to Linux Kernel SCTP
+Name: @PACKAGE@
+Version: %{pack_version}
+Release: 1
+License: LGPL
+Group: System Environment/Libraries
+URL: http://lksctp.sourceforge.net
+Source0: %{name}-%{file_version}.tar.gz
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
+BuildRequires: gcc
+#BuildRequires: tetex, tetex-latex, tetex-xdvi, tetex-dvips
+#BuildRequires: ghostscript, enscript
+BuildRequires: libtool, automake, autoconf
+
+%description
+This is the lksctp-tools package for Linux Kernel SCTP Reference
+Implementation.
+
+This package is intended to supplement the Linux Kernel SCTP Reference
+Implementation now available in the Linux kernel source tree in
+versions 2.5.36 and following.  For more information on LKSCTP see the
+package documentation README file, section titled "LKSCTP - Linux
+Kernel SCTP."
+
+This package contains the base run-time library & command-line tools.
+
+%package devel
+Summary: Development kit for lksctp-tools
+Group: Development/Libraries
+Requires: %{name} = %{version}
+Requires: glibc-devel
+
+%description devel
+Development kit for lksctp-tools
+
+- Man pages
+- Header files
+- Static libraries
+- Symlinks to dynamic libraries
+- Tutorial source code
+
+%package doc
+Summary: Documents pertaining to SCTP
+Group: System Environment/Libraries
+Requires: %{name} = %{version}
+
+%description doc
+Documents pertaining to LKSCTP & SCTP in general
+- IETF RFC's & Internet Drafts
+
+%prep
+%setup -q -n %{name}-%{file_version}
+
+%build
+%configure --enable-shared --enable-static
+make
+
+%install
+rm -rf $RPM_BUILD_ROOT
+make install DESTDIR="$RPM_BUILD_ROOT"
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%post
+/sbin/ldconfig
+
+%postun
+/sbin/ldconfig
+
+%files
+%defattr(-,root,root,-)
+%doc AUTHORS COPYING ChangeLog COPYING.lib
+%{_bindir}/*
+%{_libdir}/libsctp.so.*
+%{_libdir}/@PACKAGE@/*
+
+%files devel
+%defattr(-,root,root,-)
+%{_includedir}
+%{_libdir}/libsctp.so
+%{_libdir}/libsctp.a
+%{_libdir}/libsctp.la
+%{_datadir}/@PACKAGE@/*
+%{_mandir}/*
+
+%files doc
+%defattr(-,root,root,-)
+%doc doc/*.txt
+
+%changelog
+* Mon May 09 2016 Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> 1.0.17-1
+- 1.0.17 Release
+
+* Tue Feb 18 2014 Daniel Borkmann <dborkman@redhat.com> 1.0.16-1
+- 1.0.16 Release
+
+* Sun May 12 2013 Daniel Borkmann <dborkman@redhat.com> 1.0.15-1
+- 1.0.15 Release
+
+* Wed Apr 05 2013 Daniel Borkmann <dborkman@redhat.com> 1.0.14-1
+- 1.0.14 Release
+
+* Wed Jan 23 2013 Daniel Borkmann <dborkman@redhat.com> 1.0.13-1
+- 1.0.13 Release
+
+* Tue Jan 08 2013 Vlad Yasevich <vyasevich@gmail.com> 1.0.12-1
+- 1.0.12 Release
+
+* Wed Oct 21 2009 Vlad Yasevich <vladislav.yasevich@hp.com> 1.0.11-1
+- 1.0.11 Release
+
+* Fri Mar 27 2009 Vlad Yasevich <vladislav.yasevich@hp.com> 1.0.10-1
+- 1.0.10 Release
+
+* Sun Jun 13 2008 Vlad Yasevich <vladislav.yasevich@hp.com> 1.0.9-1
+- 1.0.9 Release
+
+* Fri Feb 01 2008 Vlad Yasevich <vladislav.yasevich@hp.com> 1.0.8-1
+- 1.0.8 Release
+
+* Fri Jun 29 2007 Vlad Yasevich <vladislav.yasevich@hp.com> 1.0.7-1
+- 1.0.7 Release
+
+* Fri Feb 3 2006 Sridhar Samudrala <sri@us.ibm.com> 1.0.6-1
+- 1.0.6 Release
+
+* Tue Jan 3 2006 Sridhar Samudrala <sri@us.ibm.com> 1.0.5-1
+- 1.0.5 Release
+ 
+* Fri Oct 28 2005 Sridhar Samudrala <sri@us.ibm.com> 1.0.4-1
+- 1.0.4 Release
+ 
+* Thu Sep 1 2005 Sridhar Samudrala <sri@us.ibm.com> 1.0.3-1
+- 1.0.3 Release
+ 
+* Thu Dec 30 2004 Sridhar Samudrala <sri@us.ibm.com> 1.0.2-1
+- 1.0.2 Release
+ 
+* Tue May 11 2004 Sridhar Samudrala <sri@us.ibm.com> 1.0.1-1
+- 1.0.1 Release
+ 
+* Thu Feb 26 2004 Sridhar Samudrala <sri@us.ibm.com> 1.0.0-1
+- 1.0.0 Release
+ 
+* Fri Feb  6 2004 Francois-Xavier Kowalski <francois-xavier.kowalski@hp.com> 0.9.0-1
+- package only .txt doc files
+
+* Wed Feb  4 2004 Francois-Xavier Kowalski <francois-xavier.kowalski@hp.com> 0.7.5-1
+- badly placed & undelivered files
+- simplified delivery list
+
+* Tue Jan 27 2004 Francois-Xavier Kowalski <francois-xavier.kowalski@hp.com> 0.7.5-1
+- Integrate comment from project team
+
+* Sat Jan 10 2004 Francois-Xavier Kowalski <francois-xavier.kowalski@hp.com> 2.6.0_test7_0.7.4-1
+- Creation
diff --git a/m4/.gitignore b/m4/.gitignore
new file mode 100644
index 0000000..1ff72df
--- /dev/null
+++ b/m4/.gitignore
@@ -0,0 +1,2 @@
+*.m4
+!sctp.m4
diff --git a/m4/sctp.m4 b/m4/sctp.m4
new file mode 100644
index 0000000..6593517
--- /dev/null
+++ b/m4/sctp.m4
@@ -0,0 +1,63 @@
+# Handy references:
+# https://www.gnu.org/software/autoconf/manual/autoconf.html#Generic-Structures
+# AC_CHECK_MEMBER (aggregate.member, [action-if-found], [action-if-not-found], [includes = 'AC_INCLUDES_DEFAULT'])
+# https://www.gnu.org/software/autoconf/manual/autoconf.html#Generic-Types
+# AC_CHECK_TYPE (type, [action-if-found], [action-if-not-found], [includes = 'AC_INCLUDES_DEFAULT'])
+
+# Macros to assist on probing kernel features
+#   Probes if a type is defined
+AC_DEFUN([LKSCTP_CHECK_TYPE], [{
+AC_CHECK_TYPE([$1],
+	AC_DEFINE([$2], 1,
+		  [Define if $1 is present.])
+	AM_CONDITIONAL([$2], [true]),
+	AM_CONDITIONAL([$2], [false]),
+	[AC_INCLUDES_DEFAULT
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+#ifdef HAVE_LINUX_SCTP_H
+# include <linux/sctp.h>
+#endif
+])}])
+
+#   Probes if a struct has a given member
+AC_DEFUN([LKSCTP_CHECK_MEMBER], [{
+AC_CHECK_MEMBER([$1],
+	AC_DEFINE([$2], 1,
+		  [Define if $1 is present.])
+	AM_CONDITIONAL([$2], [true]),
+	AM_CONDITIONAL([$2], [false]),
+	[AC_INCLUDES_DEFAULT
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+#ifdef HAVE_LINUX_SCTP_H
+# include <linux/sctp.h>
+#endif
+])}])
+
+#   Probes if a declaration is present
+AC_DEFUN([LKSCTP_CHECK_DECL], [{
+AC_CHECK_DECL([$1],
+	AC_DEFINE([$2], 1,
+		  [Define if $1 is present.])
+	AM_CONDITIONAL([$2], [true]),
+	AM_CONDITIONAL([$2], [false]),
+	[AC_INCLUDES_DEFAULT
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+#ifdef HAVE_LINUX_SCTP_H
+# include <linux/sctp.h>
+#endif
+])}])
diff --git a/man/Makefile.am b/man/Makefile.am
new file mode 100644
index 0000000..eabfe6f
--- /dev/null
+++ b/man/Makefile.am
@@ -0,0 +1,12 @@
+# -*- Makefile -*-
+#
+include $(top_srcdir)/Makefile.vars
+include $(top_srcdir)/Makefile.rules
+
+man7_MANS = sctp.7
+
+man3_MANS = sctp_bindx.3 sctp_getladdrs.3 sctp_getpaddrs.3 sctp_opt_info.3 \
+	sctp_peeloff.3 sctp_recvmsg.3 sctp_sendmsg.3 sctp_connectx.3 \
+	sctp_send.3 sctp_sendv.3 sctp_recvv.3
+
+EXTRA_DIST += $(man3_MANS) $(man7_MANS)
diff --git a/man/sctp.7 b/man/sctp.7
new file mode 100644
index 0000000..2238a7f
--- /dev/null
+++ b/man/sctp.7
@@ -0,0 +1,352 @@
+.\" (C) Copyright Sridhar Samudrala IBM Corp. 2004, 2005.
+.\"
+.\" Permission is granted to distribute possibly modified copies
+.\" of this manual provided the header is included verbatim,
+.\" and in case of nontrivial modification author and date
+.\" of the modification is added to the header.
+.\"
+.TH SCTP  7 2005-10-25 "Linux Man Page" "Linux Programmer's Manual" 
+.SH NAME
+sctp \- SCTP protocol.
+.SH SYNOPSIS
+.nf
+.B #include <sys/socket.h>
+.B #include <netinet/in.h>
+.B #include <netinet/sctp.h>
+.sp
+.B sctp_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP); 
+.B sctp_socket = socket(PF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+.fi
+.SH DESCRIPTION
+This is an implementation of the SCTP protocol as defined in RFC2960 and
+RFC3309. It is a message oriented, reliable transport protocol with direct
+support for multihoming that runs on top of 
+.BR ip (7),
+and supports both v4 and v6 versions.
+.PP
+Like TCP, SCTP provides reliable, connection oriented data delivery with 
+congestion control. Unlike TCP, SCTP also provides message boundary 
+preservation, ordered and unordered message delivery, multi-streaming and
+multi-homing. Detection of data corruption, loss of data and duplication of
+data is achieved by using checksums and sequence numbers. A selective 
+retransmission mechanism is applied to correct loss or corruption of data.
+.PP
+This implementation supports a mapping of SCTP into sockets API as defined
+in the draft-ietf-tsvwg-sctpsocket-10.txt(Sockets API extensions for SCTP).
+Two styles of interfaces are supported.
+.PP
+A 
+.B one-to-many
+style interface with 1 to MANY relationship between socket and associations 
+where the outbound association setup is implicit. The syntax of a one-to-many
+style socket() call is
+.PP
+.B     sd = socket(PF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); 
+.PP
+A typical server in this style uses the following socket calls in sequence
+to prepare an endpoint for servicing requests.
+.PP
+     1. socket()
+     2. bind()
+     3. listen()
+     4. recvmsg()
+     5. sendmsg()
+     6. close()
+.PP
+A typical client uses the following calls in sequence to setup an association
+with a server to request services.
+.PP
+     1. socket()
+     2. sendmsg()
+     3. recvmsg()
+     4. close()
+.PP
+A
+.B one-to-one style
+interface with a 1 to 1 relationship between socket and
+association which enables existing TCP applications to be ported to SCTP with
+very little effort. The syntax of a one-to-one style socket() call is
+.PP
+.B     sd = socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP); 
+.PP
+A typical server in one-to-one style uses the following
+system call sequence to prepare an SCTP endpoint for servicing requests:
+.PP
+     1. socket()
+     2. bind()
+     3. listen()
+     4. accept()
+.PP
+The accept() call blocks until a new association is set up. It returns with a
+new socket descriptor. The server then uses the new socket descriptor to
+communicate with the client, using recv() and send() calls to get requests and
+send back responses. Then it calls
+.PP
+     5. close()
+.PP
+to terminate the association. A typical client uses the following system call
+sequence to setup an association with a server to request services:
+.PP
+     1. socket()
+     2. connect()
+.PP
+After returning from connect(), the client uses send() and recv() calls to
+send out requests and receive responses from the server. The client calls
+.PP
+     3. close()
+.PP
+to terminate this association when done.
+.SH "ADDRESS FORMATS"
+SCTP is built on top of IP (see 
+.BR ip (7)).
+The address formats defined by
+.BR ip (7)
+apply to SCTP.  SCTP only supports point-to-point communication; broadcasting
+and multicasting are not supported.
+.SH SYSCTLS
+These variables can be accessed by the 
+.B /proc/sys/net/sctp/* 
+files or with the 
+.BR sysctl (2)
+interface.  In addition, most IP sysctls also apply to SCTP. See
+.BR ip (7). 
+.TP
+Please check kernel documentation for this, at Documentation/networking/ip-sysctl.txt.
+.SH "STATISTICS"
+These variables can be accessed by the 
+.B /proc/net/sctp/* 
+files. 
+.TP
+.B assocs
+Displays the following information about the active associations.
+assoc ptr, sock ptr, socket style, sock state, association state, hash bucket,
+association id, bytes in transmit queue, bytes in receive queue, user id, 
+inode, local port, remote port, local addresses and remote addresses.
+.TP
+.B eps
+Displays the following information about the active endpoints.
+endpoint ptr, sock ptr, socket style, sock state, hash bucket, local port,
+user id, inode and local addresses.  
+.TP
+.B snmp
+Displays the following statistics related to SCTP states, packets and chunks. 
+.TP
+.TP
+.B SctpCurrEstab
+The number of associations for which the current state is either ESTABLISHED,
+SHUTDOWN-RECEIVED or SHUTDOWN-PENDING.
+.TP
+.B SctpActiveEstabs
+The number of times that associations have made a direct transition to the
+ESTABLISHED state from the COOKIE-ECHOED state. The upper layer initiated the
+association attempt.
+.TP
+.B SctpPassiveEstabs
+The number of times that associations have made a direct transition to the
+ESTABLISHED state from the CLOSED state. The remote endpoint initiated the
+association attempt.
+.TP
+.B SctpAborteds
+The number of times that associations have made a direct transition to the
+CLOSED state from any state using the primitive 'ABORT'. Ungraceful
+termination of the association.
+.TP
+.B SctpShutdowns
+The number of times that associations have made a direct transition to the
+CLOSED state from either the SHUTDOWN-SENT state or the SHUTDOWN-ACK-SENT
+state. Graceful termination of the association.
+.TP
+.B SctpOutOfBlues
+The number of out of the blue packets received by the host. An out of the blue
+packet is an SCTP packet correctly formed, including the proper checksum, but
+for which the receiver was unable to identify an appropriate association.
+.TP
+.B SctpChecksumErrors
+The number of SCTP packets received with an invalid checksum.
+.TP
+.B SctpOutCtrlChunks
+The number of SCTP control chunks sent (retransmissions are not included).
+Control chunks are those chunks different from DATA.
+.TP
+.B SctpOutOrderChunks
+The number of SCTP ordered data chunks sent (retransmissions are not included).
+.TP
+.B SctpOutUnorderChunks
+The number of SCTP unordered chunks(data chunks in which the U bit is set
+to 1) sent (retransmissions are not included).
+.TP
+.B SctpInCtrlChunks
+The number of SCTP control chunks received (no duplicate chunks included).
+.TP
+.B SctpInOrderChunks
+The number of SCTP ordered data chunks received (no duplicate chunks included).
+.TP
+.B SctpInUnorderChunks
+The number of SCTP unordered chunks(data chunks in which the U bit is set
+to 1) received (no duplicate chunks included).
+.TP
+.B SctpFragUsrMsgs
+The number of user messages that have to be fragmented because of the MTU.
+.TP
+.B SctpReasmUsrMsgs
+The number of user messages reassembled, after conversion into DATA chunks.
+.TP
+.B SctpOutSCTPPacks
+The number of SCTP packets sent. Retransmitted DATA chunks are included.
+.TP
+.B SctpInSCTPPacks
+The number of SCTP packets received. Duplicates are included.
+.SH "SOCKET OPTIONS"
+To set or get a SCTP socket option, call
+.BR getsockopt (2)
+to read or
+.BR setsockopt (2)
+to write the option with the option level argument set to 
+.BR SOL_SCTP.
+.TP
+.BR SCTP_RTOINFO.
+This option is used to get or set the protocol parameters used to
+initialize and bound retransmission timout(RTO). The structure sctp_rtoinfo
+defined in /usr/include/netinet/sctp.h is used to access and modify these
+parameters.
+.TP
+.B SCTP_ASSOCINFO
+This option is used to both examine and set various association and endpoint
+parameters. The sturcture sctp_assocparams defined in
+/usr/include/netinet/sctp.h is used to access and modify these parameters.
+.TP
+.B SCTP_INITMSG
+This option is used to get or set the protocol parameters for the default
+association initialization. The structure sctp_initmsg defined in
+/usr/include/netinet/sctp.h is used to access and modify these parameters. 
+
+Setting initialization parameters is effective only on an unconnected
+socket (for one-to-many style sockets only future associations are
+effected by the change). With one-to-one style sockets, this option
+is inherited by sockets derived from a listener socket.
+.TP
+.B SCTP_NODELAY
+Turn on/off any Nagle-like algorithm. This means that packets are generally
+sent as soon as possible and no unnecessary delays are introduced, at the cost 
+of more packets in the network.  Expects an integer boolean flag.
+.TP
+.B SCTP_AUTOCLOSE
+This socket option is applicable to the one-to-many style socket
+only. When set it will cause associations that are idle for more than
+the specified number of seconds to automatically close. An
+association being idle is defined an association that has NOT sent or
+received user data. The special value of 0 indicates that no
+automatic close of any associations should be performed. The option
+expects an integer defining the number of seconds of idle time before
+an association is closed.
+.TP
+.B SCTP_SET_PEER_PRIMARY_ADDR
+Requests that the peer mark the enclosed address as the association
+primary. The enclosed address must be one of the association's
+locally bound addresses. The structure sctp_setpeerprim defined in
+/usr/include/netinet/sctp.h is used to make a set peer primary request.
+.TP
+.B SCTP_PRIMARY_ADDR
+Requests that the local SCTP stack use the enclosed peer address as
+the association primary. The enclosed address must be one of the
+association peer's addresses. The structure sctp_prim defined in
+/usr/include/netinet/sctp.h is used to make a get/set primary request.
+.TP
+.B SCTP_DISABLE_FRAGMENTS
+This option is a on/off flag and is passed an integer where a non-zero is on 
+and a zero is off. If enabled no SCTP message fragmentation will be performed.
+Instead if a message being sent exceeds the current PMTU size, the message will 
+NOT be sent and an error will be indicated to the user.
+.TP
+.B SCTP_PEER_ADDR_PARAMS
+Using this option, applications can enable or disable heartbeats for any peer
+address of an association, modify an address's heartbeat interval, force a
+heartbeat to be sent immediately, and adjust the address's maximum number of
+retransmissions sent before an address is considered unreachable. The structure 
+sctp_paddrparams defined in /usr/include/netinet/sctp.h is used to
+access and modify an address's parameters.
+.TP
+.B SCTP_DEFAULT_SEND_PARAM
+Applications that wish to use the sendto() system call may wish to specify
+a default set of parameters that would normally be supplied through the
+inclusion of ancillary data. This socket option allows such an application to
+set the default sctp_sndrcvinfo structure. The application that wishes to use
+this socket option simply passes in to this call the sctp_sndrcvinfo structure
+defined in /usr/include/netinet/sctp.h. The input parameters accepted by this
+call include sinfo_stream, sinfo_flags, sinfo_ppid, sinfo_context,
+sinfo_timetolive. The user must set the sinfo_assoc_id field to identify the
+ association to affect if the caller is using the one-to-many style.
+.TP
+.B SCTP_EVENTS
+This socket option is used to specify various notifications and ancillary data
+the user wishes to receive. The structure sctp_event_subscribe defined in
+/usr/include/netinet/sctp.h is used to access or modify the events of interest
+to the user.
+.TP
+.B SCTP_I_WANT_MAPPED_V4_ADDR
+This socket option is a boolean flag which turns on or off mapped V4
+addresses. If this option is turned on and the socket is type PF_INET6,
+then IPv4 addresses will be mapped to V6 representation. If this option is
+turned off, then no mapping will be done of V4 addresses and a user will
+receive both PF_INET6 and PF_INET type addresses on the socket.
+
+By default this option is turned on and expects an integer to be passed where
+non-zero turns on the option and zero turns off the option.
+.TP
+.B SCTP_MAXSEG
+This socket option specifies the maximum size to put in any outgoing
+SCTP DATA chunk. If a message is larger than this size it will be
+fragmented by SCTP into the specified size. Note that the underlying
+SCTP implementation may fragment into smaller sized chunks when the
+PMTU of the underlying association is smaller than the value set by
+the user. The option expects an integer.
+
+The default value for this option is 0 which indicates the user is
+NOT limiting fragmentation and only the PMTU will effect SCTP's
+choice of DATA chunk size.
+.TP
+.B SCTP_STATUS
+Applications can retrieve current status information about an association,
+including association state, peer receiver window size, number of unacked
+data chunks, and number of data chunks pending receipt.  This information is
+read-only.  The structure sctp_status defined in /usr/include/netinet/sctp.h
+is used to access this information.
+.TP
+.B SCTP_GET_PEER_ADDR_INFO
+Applications can retrieve information about a specific peer address
+of an association, including its reachability state, congestion window,
+and retransmission timer values.  This information is read-only. The structure
+sctp_paddr_info defined in /usr/include/netinet/sctp.h is used to access this
+information.
+.TP
+.B SCTP_GET_ASSOC_STATS
+Applications can retrieve current statistics about an association, including
+SACKs sent and received, SCTP packets sent and received. The complete list can
+be found in /usr/include/netinet/sctp.h in struct sctp_assoc_stats.
+.SH AUTHORS
+Sridhar Samudrala <sri@us.ibm.com>
+.SH "SEE ALSO"
+.BR socket (7),
+.BR socket (2),
+.BR ip (7),
+.BR bind (2), 
+.BR listen (2),
+.BR accept (2),
+.BR connect (2),
+.BR sendmsg (2),
+.BR recvmsg (2),
+.BR sysctl (2),
+.BR getsockopt (2),
+.BR sctp_bindx (3),
+.BR sctp_connectx (3),
+.BR sctp_sendmsg (3),
+.BR sctp_sendv (3),
+.BR sctp_send (3),
+.BR sctp_recvmsg (3),
+.BR sctp_recvv (3),
+.BR sctp_peeloff (3),
+.BR sctp_getladdrs (3),
+.BR sctp_getpaddrs (3),
+.BR sctp_opt_info (3).
+.sp
+RFC2960, RFC3309 for the SCTP specification.
diff --git a/man/sctp_bindx.3 b/man/sctp_bindx.3
new file mode 100644
index 0000000..e1b151b
--- /dev/null
+++ b/man/sctp_bindx.3
@@ -0,0 +1,94 @@
+.\" (C) Copyright Sridhar Samudrala IBM Corp. 2004, 2005.
+.\"
+.\" Permission is granted to distribute possibly modified copies
+.\" of this manual provided the header is included verbatim,
+.\" and in case of nontrivial modification author and date
+.\" of the modification is added to the header.
+.\"
+.TH SCTP_BINDX 3 2005-10-25 "Linux 2.6" "Linux Programmer's Manual"
+.SH NAME
+sctp_bindx \- Add or remove bind addresses on a socket.
+.SH SYNOPSIS
+.nf
+.B #include <sys/types.h>
+.B #include <sys/socket.h>
+.B #include <netinet/sctp.h>
+.sp
+.BI "int sctp_bindx(int " sd ", struct sockaddr * " addrs ", int " addrcnt ,
+.BI "               int " flags );
+.fi
+.SH DESCRIPTION
+.BR sctp_bindx
+adds or removes a set of bind addresses passed in the array
+.I addrs
+to/from the socket
+.I sd.
+.I addrcnt
+is the number of addresses in the array and the
+.I flags
+paramater indicates if the addresses need to be added or removed.
+.PP
+If
+.I sd
+is an IPv4 socket, the addresses passed must be IPv4 addresses. If
+.I sd
+is an IPv6 socket, the addresses passed can be either IPv4 or IPv6
+addresses.
+.PP
+.I addrs
+is a pointer to an array of one or more socket addresses. Each address is
+contained in its appropriate structure(i.e. struct sockaddr_in or struct
+sockaddr_in6). The family of the address type must be used to distinguish
+the address length. The caller specifies the number of addresses in the
+array with
+.I addrcnt. 
+.PP
+The
+.I flags
+parameter can be either
+.B SCTP_BINDX_ADD_ADDR
+or
+.B SCTP_BINDX_REM_ADDR.
+An application can use
+.B SCTP_BINDX_ADD_ADDR
+to associate additional addresses with an endpoint after calling
+.BR bind(2). 
+.B SCTP_BINDX_REM_ADDR
+directs SCTP to remove the given addresses from the association.
+A caller may not remove all addresses from an association. It will
+fail with
+.B EINVAL.
+.SH "RETURN VALUE"
+On success, 0 is returned. On failure, \-1 is returned, and
+.I errno
+is set appropriately.
+.SH ERRORS
+.TP
+.B EBADF
+.I sd
+is not a valid descriptor.
+.TP
+.B ENOTSOCK
+.I sd
+is a descriptor for a file, not a socket.
+.TP
+.B EFAULT
+Error while copying in or out from the user address space.
+.TP
+.B EINVAL
+Invalid port or address or trying to remove all addresses from an association.
+.TP
+.B EACCES
+The address is protected, and the user is not the super-user.
+.SH "SEE ALSO"
+.BR sctp (7)
+.BR sctp_sendmsg (3),
+.BR sctp_sendv (3),
+.BR sctp_send (3),
+.BR sctp_recvmsg (3),
+.BR sctp_recvv (3),
+.BR sctp_peeloff (3),
+.BR sctp_getpaddrs (3),
+.BR sctp_getladdrs (3),
+.BR sctp_opt_info (3),
+.BR sctp_connectx (3)
diff --git a/man/sctp_connectx.3 b/man/sctp_connectx.3
new file mode 100644
index 0000000..c75454c
--- /dev/null
+++ b/man/sctp_connectx.3
@@ -0,0 +1,144 @@
+.\" (C) Copyright Frank Filz IBM Corp. 2005.
+.\"
+.\" Permission is granted to distribute possibly modified copies
+.\" of this manual provided the header is included verbatim,
+.\" and in case of nontrivial modification author and date
+.\" of the modification is added to the header.
+.\"
+.TH SCTP_CONNECTX 3 2005-10-25 "Linux 2.6" "Linux Programmer's Manual"
+.SH NAME
+sctp_connectx \- initiate a connection on an SCTP socket using multiple
+destination addresses.
+.SH SYNOPSIS
+.nf
+.B #include <sys/types.h>
+.B #include <sys/socket.h>
+.B #include <netinet/sctp.h>
+.sp
+.BI "int sctp_connectx(int " sd ", struct sockaddr * " addrs ", int " addrcnt,
+.BI "                  sctp_assoc_t  * "id );
+.fi
+.SH DESCRIPTION
+.BR sctp_connectx
+initiates a connection to a set of addresses passed in the array
+.I addrs
+to/from the socket
+.I sd.
+.I addrcnt
+is the number of addresses in the array.
+.PP
+If
+.I sd
+is an IPv4 socket, the addresses passed must be IPv4 addresses. If
+.I sd
+is an IPv6 socket, the addresses passed can be either IPv4 or IPv6
+addresses.
+.PP
+.I addrs
+is a pointer to an array of one or more socket addresses. Each address is
+contained in its appropriate structure(i.e. struct sockaddr_in or struct
+sockaddr_in6). The family of the address type must be used to distinguish
+the address length. The caller specifies the number of addresses in the
+array with
+.I addrcnt. 
+.PP
+.I id
+is a pointer to the association id and, if provided, will be set to the
+identifier of the newly created association.
+.SH "RETURN VALUE"
+On success, 0 is returned. On failure, \-1 is returned, and
+.I errno
+is set appropriately.
+.SH ERRORS
+.TP
+.B EBADF
+.I sd
+is not a valid descriptor.
+.TP
+.B ENOTSOCK
+.I sd
+is a descriptor for a file, not a socket.
+.TP
+.B EFAULT
+Error while copying in or out from the user address space.
+.TP
+.B EINVAL
+Invalid port or address.
+.TP
+.B EACCES
+The address is protected, and the user is not the super-user.
+.TP
+.B EISCONN
+The socket is already connected.
+.TP
+.B ECONNREFUSED
+No one listening on the remote address.
+.TP
+.B ETIMEDOUT
+Timeout while attempting connection. The server may be too 
+busy to accept new connections. Note that for IP sockets the timeout may
+be very long when syncookies are enabled on the server.
+.TP
+.B ENETUNREACH
+Network is unreachable.
+.TP
+.B EADDRINUSE
+Local address is already in use.
+.TP
+.B EINPROGRESS
+The socket is non-blocking and the connection cannot be completed
+immediately.  It is possible to
+.BR select (2)
+or 
+.BR poll (2) 
+for completion by selecting the socket for writing. After 
+.B select
+indicates writability, use
+.BR getsockopt (2)
+to read the 
+.B SO_ERROR
+option at level 
+.B SOL_SOCKET
+to determine whether 
+.B connect
+completed successfully 
+.RB ( SO_ERROR
+is zero) or unsuccessfully 
+.RB ( SO_ERROR
+is one of the usual error codes listed here, 
+explaining the reason for the failure).
+.TP
+.B EALREADY
+The socket is non-blocking and a previous connection attempt has not yet
+been completed.
+.TP
+.B EAGAIN
+No more free local ports or insufficient entries in the routing cache. For
+.B PF_INET
+see the 
+.B net.ipv4.ip_local_port_range
+sysctl in 
+.BR ip (7) 
+on how to increase the number of local ports.
+.TP
+.B EAFNOSUPPORT
+The passed address didn't have the correct address family in its 
+.I sa_family
+field.
+.TP
+.B EACCES, EPERM
+The user tried to connect to a broadcast address without having the socket 
+broadcast flag enabled or the connection request failed because of a local
+firewall rule.
+.SH "SEE ALSO"
+.BR sctp (7)
+.BR sctp_bindx (3),
+.BR sctp_sendmsg (3),
+.BR sctp_sendv (3),
+.BR sctp_send (3),
+.BR sctp_recvmsg (3),
+.BR sctp_recvv (3),
+.BR sctp_peeloff (3),
+.BR sctp_getpaddrs (3),
+.BR sctp_getladdrs (3),
+.BR sctp_opt_info (3),
diff --git a/man/sctp_getladdrs.3 b/man/sctp_getladdrs.3
new file mode 100644
index 0000000..c5aad14
--- /dev/null
+++ b/man/sctp_getladdrs.3
@@ -0,0 +1,78 @@
+.\" (C) Copyright Sridhar Samudrala IBM Corp. 2004, 2005.
+.\"
+.\" Permission is granted to distribute possibly modified copies
+.\" of this manual provided the header is included verbatim,
+.\" and in case of nontrivial modification author and date
+.\" of the modification is added to the header.
+.\"
+.TH SCTP_GETLADDRS 3 2005-10-25 "Linux 2.6" "Linux Programmer's Manual"
+.SH NAME
+sctp_getladdrs \- Returns all locally bound addresses on a socket. 
+.SH SYNOPSIS
+.nf
+.B #include <sys/types.h>
+.B #include <sys/socket.h>
+.B #include <netinet/sctp.h>
+.sp
+.BI "int sctp_getladdrs(int " sd ", sctp_assoc_t " assoc_id ,
+.BI "                   struct sockaddr **" addrs );
+.sp
+.BI "void sctp_freeladdrs(struct sockaddr *" addrs );
+.fi
+.SH DESCRIPTION
+.BR sctp_getladdrs
+returns all locally bound addresses on a socket. On return,
+.I addrs
+will point to a dynamically allocated packed array of
+.B sockaddr
+structures of the appropriate type for each local address. The caller
+should use 
+.BR sctp_freeladdrs
+to free the memory. Note that the in/out parameter
+.I addrs
+must not be NULL.
+.PP
+If
+.I sd
+is an IPv4 socket, the addresses returned will be all IPv4 addresses. If
+.I sd
+is an IPv6 socket, the addresses returned can be a mix of IPv4 or IPv6
+addresses.
+.PP
+For one-to-many style sockets,
+.I id
+specifies the association to query. For one-to-one style sockets,
+.I id
+is ignored.
+.PP
+If the
+.I id
+field is set to 0, then the locally bound addresses are returned 
+without regard to any particular association. 
+.PP
+.BR sctp_freeladdrs
+frees all the resources allocated by
+.BR sctp_getladdrs
+.SH "RETURN VALUE"
+On success,
+.BR sctp_getladdrs
+returns the number of local addresses bound to the socket. If the socket
+is unbound, 0 is returned and the value of 
+.I *addrs
+is undefined. On error,
+.BR sctp_getladdrs
+returns -1 and the value of
+.I *addrs
+is undefined.
+.SH "SEE ALSO"
+.BR sctp (7)
+.BR sctp_bindx (3),
+.BR sctp_connectx (3),
+.BR sctp_sendmsg (3),
+.BR sctp_sendv (3),
+.BR sctp_send (3),
+.BR sctp_recvmsg (3),
+.BR sctp_recvv (3),
+.BR sctp_peeloff (3),
+.BR sctp_getpaddrs (3),
+.BR sctp_opt_info (3),
diff --git a/man/sctp_getpaddrs.3 b/man/sctp_getpaddrs.3
new file mode 100644
index 0000000..9167dfc
--- /dev/null
+++ b/man/sctp_getpaddrs.3
@@ -0,0 +1,72 @@
+.\" (C) Copyright Sridhar Samudrala IBM Corp. 2004, 2005.
+.\"
+.\" Permission is granted to distribute possibly modified copies
+.\" of this manual provided the header is included verbatim,
+.\" and in case of nontrivial modification author and date
+.\" of the modification is added to the header.
+.\"
+.TH SCTP_GETPADDRS 3 2005-10-25 "Linux 2.6" "Linux Programmer's Manual"
+.SH NAME
+sctp_getpaddrs \- Returns all peer addresses in an association. 
+.SH SYNOPSIS
+.nf
+.B #include <sys/types.h>
+.B #include <sys/socket.h>
+.B #include <netinet/sctp.h>
+.sp
+.BI "int sctp_getpaddrs(int " sd ", sctp_assoc_t " assoc_id ,
+.BI "                   struct sockaddr **" addrs );
+.sp
+.BI "void sctp_freepaddrs(struct sockaddr *" addrs );
+.fi
+.SH DESCRIPTION
+.BR sctp_getpaddrs
+returns all peer addresses in an association. On return,
+.I addrs
+will point to a dynamically allocated packed array of
+.B sockaddr
+structures of the appropriate type for each address. The caller should use 
+.BR sctp_freepaddrs
+to free the memory. Note that the in/out parameter
+.I addrs
+must not be NULL.
+.PP
+If
+.I sd
+is an IPv4 socket, the addresses returned will be all IPv4 addresses. If
+.I sd
+is an IPv6 socket, the addresses returned can be a mix of IPv4 or IPv6
+addresses.
+.PP
+For one-to-many style sockets,
+.I id
+specifies the association to query. For one-to-one style sockets,
+.I id
+is ignored.
+.PP
+.BR sctp_freepaddrs
+frees all the resources allocated by
+.BR sctp_getpaddrs. 
+.SH "RETURN VALUE"
+On success,
+.BR sctp_getpaddrs
+returns the number of peer addresses in the association. If there is no
+association on this socket, 0 is returned and the value of 
+.I *addrs
+is undefined. On error,
+.BR sctp_getpaddrs
+returns -1 and the value of
+.I *addrs
+is undefined.
+.SH "SEE ALSO"
+.BR sctp (7)
+.BR sctp_bindx (3),
+.BR sctp_connectx (3),
+.BR sctp_sendmsg (3),
+.BR sctp_sendv (3),
+.BR sctp_send (3),
+.BR sctp_recvmsg (3),
+.BR sctp_recvv (3),
+.BR sctp_peeloff (3),
+.BR sctp_getladdrs (3),
+.BR sctp_opt_info (3),
diff --git a/man/sctp_opt_info.3 b/man/sctp_opt_info.3
new file mode 100644
index 0000000..9d63c9c
--- /dev/null
+++ b/man/sctp_opt_info.3
@@ -0,0 +1,56 @@
+.\" (C) Copyright Sridhar Samudrala IBM Corp. 2004, 2005.
+.\"
+.\" Permission is granted to distribute possibly modified copies
+.\" of this manual provided the header is included verbatim,
+.\" and in case of nontrivial modification author and date
+.\" of the modification is added to the header.
+.\"
+.TH SCTP_OPT_INFO 3 2004-01-30 "Linux 2.6" "Linux Programmer's Manual"
+.SH NAME
+sctp_optinfo \- Get options on a SCTP socket. 
+.SH SYNOPSIS
+.nf
+.B #include <sys/types.h>
+.B #include <sys/socket.h>
+.B #include <netinet/sctp.h>
+.sp
+.BI "int sctp_opt_info(int " sd ", sctp_assoc_t " id ", int " opt ,
+.BI "                  void * " arg ", socklen_t * " size);
+.fi
+.SH DESCRIPTION
+.BR sctp_opt_info
+is a wrapper library function that can be used to get SCTP level options on
+a socket.
+.I sd
+is the socket descriptor for which the option is requested. For one-to-many
+style sockets,
+.I id
+specifies the association to query. For one-to-one style sockets,
+.I id
+is ignored.
+.I opt
+specifes the SCTP socket option to get.
+.I arg
+is an option-specific structure buffer provided by the caller. 
+.I size
+is a value-result parameter, initially containing the size of the buffer
+pointed to by
+.I arg
+and modifed on return to indicate the actual size of the value returned.
+.SH "RETURN VALUE"
+On success,
+.BR sctp_opt_info
+returns 0 and on failure -1 is returned with errno set to the appropriate
+error code.
+.SH "SEE ALSO"
+.BR sctp (7)
+.BR sctp_bindx (3),
+.BR sctp_connectx (3),
+.BR sctp_sendmsg (3),
+.BR sctp_sendv (3),
+.BR sctp_send (3),
+.BR sctp_recvmsg (3),
+.BR sctp_recvv (3),
+.BR sctp_peeloff (3),
+.BR sctp_getpaddrs (3),
+.BR sctp_getladdrs (3),
diff --git a/man/sctp_peeloff.3 b/man/sctp_peeloff.3
new file mode 100644
index 0000000..7e66317
--- /dev/null
+++ b/man/sctp_peeloff.3
@@ -0,0 +1,74 @@
+.\" (C) Copyright Sridhar Samudrala IBM Corp. 2004, 2005.
+.\"
+.\" Permission is granted to distribute possibly modified copies
+.\" of this manual provided the header is included verbatim,
+.\" and in case of nontrivial modification author and date
+.\" of the modification is added to the header.
+.\"
+.TH SCTP_PEELOFF 3 2005-10-25 "Linux 2.6" "Linux Programmer's Manual"
+.SH NAME
+sctp_peeloff \- Branch off an association into a separate socket. 
+.SH SYNOPSIS
+.nf
+.B #include <sys/types.h>
+.B #include <sys/socket.h>
+.B #include <netinet/sctp.h>
+.sp
+.BI "int sctp_peeloff(int " sd ", sctp_assoc_t " assoc_id );
+.BI "int sctp_peeloff_flags(int " sd ", sctp_assoc_t " assoc_id ", unsigned " flags );
+.fi
+.SH DESCRIPTION
+.B sctp_peeloff
+branches off an existing association
+.I assoc_id
+on a one-to-many style socket
+.I sd
+into a separate socket. The new socket is a one-to-one style socket.
+.PP
+This is particularly desirable when, for instance, the application wishes to
+have a number of sporadic message senders/receivers remain under the original
+one-to-many style socket, but branch off those assocations carrying high volume
+data traffic into their own separate socket descriptors.
+
+.B sctp_peeloff_flags
+is a variant of sctp_peeloff, in which flags describing the behavior of
+the newly peeled off socket can be specified.  Currently the supported flags
+are:
+.TP
+.B SOCK_NONBLOCK
+Specifies that the new socket should not block on io operations.
+.TP
+.B SOCK_CLOEXEC
+Specifies that the new socket should be closed when the owning process calls
+exec.
+.SH "RETURN VALUE"
+On success, the new socket descriptor representing the branched-off asociation is returned.
+On error, \-1 is returned, and
+.I errno
+is set appropriately.
+.SH ERRORS
+.TP
+.B EBADF
+.I sd
+is not a valid descriptor.
+.TP
+.B EINVAL
+The assoc id passed is invalid or if the socket is a one-to-one style socket.
+.TP
+.B ENOTSOCK
+Argument is a descriptor for a file, not a socket.
+.SH NOTES
+.TP
+sctp_peeloff_flags is a linux specific variant of sctp_peeloff.  While it will compile on other systems, its use will result in an error return.  Portable code should use sctp_peeloff.
+.SH "SEE ALSO"
+.BR sctp (7)
+.BR sctp_bindx (3),
+.BR sctp_connectx (3),
+.BR sctp_sendmsg (3),
+.BR sctp_sendv (3),
+.BR sctp_send (3),
+.BR sctp_recvmsg (3),
+.BR sctp_recvv (3),
+.BR sctp_getpaddrs (3),
+.BR sctp_getladdrs (3),
+.BR sctp_opt_info (3),
diff --git a/man/sctp_recvmsg.3 b/man/sctp_recvmsg.3
new file mode 100644
index 0000000..7854aec
--- /dev/null
+++ b/man/sctp_recvmsg.3
@@ -0,0 +1,71 @@
+.\" (C) Copyright Sridhar Samudrala IBM Corp. 2004, 2005.
+.\"
+.\" Permission is granted to distribute possibly modified copies
+.\" of this manual provided the header is included verbatim,
+.\" and in case of nontrivial modification author and date
+.\" of the modification is added to the header.
+.\"
+.TH SCTP_RECVMSG 3 2005-10-25 "Linux 2.6" "Linux Programmer's Manual"
+.SH NAME
+sctp_recvmsg \- Receive a message from a SCTP socket. 
+.SH SYNOPSIS
+.nf
+.B #include <sys/types.h>
+.B #include <sys/socket.h>
+.B #include <netinet/sctp.h>
+.sp
+.BI "int sctp_recvmsg(int " sd ", void * " msg ", size_t " len ,
+.BI "                 struct sockaddr * " from ", socklen_t * " fromlen , 
+.BI "                 struct sctp_sndrcvinfo * " sinfo ", int * " msg_flags);
+.fi
+.SH DESCRIPTION
+.BR sctp_recvmsg
+is a wrapper library function that can be used to receive a message from
+a socket while using the advanced features of SCTP. 
+.I sd
+is the socket descriptor on which the message pointed to by
+.I msg
+of length
+.I len
+is received.
+.PP
+If
+.I from
+is not NULL, the source address of the message is filled in. The argument
+.I fromlen
+is a value-result parameter. initialized to the size of the buffer associated
+with 
+.I from ,
+and modified on return to indicate the actual size of the address stored.
+.PP
+.I sinfo
+is a pointer to a sctp_sndrcvinfo structure to be filled upon receipt of the
+message.
+.I msg_flags
+is a pointer to a integer that is filled with any message flags like
+.B MSG_NOTIFICATION or
+.B MSG_EOR. 
+The value of 
+.I msg_flags 
+pointer should be initialized to 0 to avoid unexpected behavior;
+.I msg_flags
+is also used as an input 
+.I flags 
+argument to 
+.I recvmsg
+function.
+.SH "RETURN VALUE"
+On success,
+.BR sctp_recvmsg
+returns the number of bytes received or -1 if an error occurred.
+.SH "SEE ALSO"
+.BR sctp (7)
+.BR sctp_bindx (3),
+.BR sctp_connectx (3),
+.BR sctp_sendmsg (3),
+.BR sctp_sendv (3),
+.BR sctp_send (3),
+.BR sctp_peeloff (3),
+.BR sctp_getpaddrs (3),
+.BR sctp_getladdrs (3),
+.BR sctp_opt_info (3)
diff --git a/man/sctp_recvv.3 b/man/sctp_recvv.3
new file mode 100644
index 0000000..a41cb33
--- /dev/null
+++ b/man/sctp_recvv.3
@@ -0,0 +1,99 @@
+.\" (C) Copyright Xin Long REDHAT Corp. 2018.
+.\"
+.\" Permission is granted to distribute possibly modified copies
+.\" of this manual provided the header is included verbatim,
+.\" and in case of nontrivial modification author and date
+.\" of the modification is added to the header.
+.\"
+.TH SCTP_RECVV 3 2018-04-29 "Linux 4.16 "Linux Programmer's Manual"
+.SH NAME
+sctp_recvv \- Receive a message from a SCTP socket with an extensible way.
+.SH SYNOPSIS
+.nf
+.B #include <sys/types.h>
+.B #include <sys/socket.h>
+.B #include <netinet/sctp.h>
+.sp
+.BI "int sctp_recvv(int " sd ", const struct iovec * " iov ", int " iovlen ,
+.BI "               struct sockaddr * " from ", socklen_t * " fromlen ", void * " info ,
+.BI "               socklen_t * " infolen ", unsigned int * " infotype ", int * " flags );
+.fi
+.SH DESCRIPTION
+.BR sctp_recvv
+provides an extensible way for the SCTP stack to pass up different SCTP
+attributes associated with a received message to an application.
+There are two types of attributes that can be returned by this call: the
+attribute of the received message and the attribute of the next message
+in the receive buffer.  The caller enables the SCTP_RECVRCVINFO and
+SCTP_RECVNXTINFO socket options, respectively, to receive these attributes.
+Attributes of the received message are returned in struct sctp_rcvinfo,
+and attributes of the next message are returned in struct sctp_nxtinfo.
+If both options are enabled, both attributes are returned using the
+following structure.
+
+   struct sctp_recvv_rn {
+     struct sctp_rcvinfo recvv_rcvinfo;
+     struct sctp_nxtinfo recvv_nxtinfo;
+   };
+
+.I sd
+is the socket descriptor.
+.I iov
+is the scatter buffer, and only one user message is returned in this buffer.
+.I iovlen
+is the number of elements in iov.
+.I from
+is a pointer to a buffer to be filled with the sender of the received message's
+address.
+.I fromlen
+is an in/out parameter describing the from length.
+.I info
+is a pointer to the buffer to hold the attributes of the received message, the
+structure type of info is determined by the info_type parameter.
+.I infolen
+is an in/out parameter describing the size of the info buffer.
+On return,
+.I infotype
+is set to the type of the info buffer, and the current defined
+values are as follows:
+.TP
+.B SCTP_RECVV_NOINFO
+If neither SCTP_RECVRCVINFO nor SCTP_RECVNXTINFO options are enabled, no
+attribute will be returned.  If only the SCTP_RECVNXTINFO option is enabled
+but there is no next message in the buffer, no attribute will be returned.
+In these cases, *info_type will be set to SCTP_RECVV_NOINFO.
+.TP
+.B SCTP_RECVV_RCVINFO
+The type of info is struct sctp_rcvinfo, and the attribute relates to the
+received message.
+.TP
+.B SCTP_RECVV_NXTINFO
+The type of info is struct sctp_nxtinfo, and the attribute relates to the
+next message in the receive buffer.  This is the case when only the
+SCTP_RECVNXTINFO option is enabled and there is a next message in the buffer.
+.TP
+.B SCTP_RECVV_RN
+The type of info is struct sctp_recvv_rn.  The recvv_rcvinfo field is the
+attribute of the received message, and the recvv_nxtinfo field is the attribute
+of the next message in the buffer.  This is the case when both SCTP_RECVRCVINFO
+and SCTP_RECVNXTINFO options are enabled and there is a next message in the
+receive buffer.
+.PP
+.I flags
+is pointer to an integer to be filled with any message flags (e.g.,
+MSG_NOTIFICATION).
+.SH "RETURN VALUE"
+On success,
+.BR sctp_recvv
+returns the number of bytes received or -1 if an error occurred.
+.SH "SEE ALSO"
+.BR sctp (7)
+.BR sctp_bindx (3),
+.BR sctp_connectx (3),
+.BR sctp_sendmsg (3),
+.BR sctp_sendv (3),
+.BR sctp_send (3),
+.BR sctp_peeloff (3),
+.BR sctp_getpaddrs (3),
+.BR sctp_getladdrs (3),
+.BR sctp_opt_info (3)
diff --git a/man/sctp_send.3 b/man/sctp_send.3
new file mode 100644
index 0000000..ba66ecd
--- /dev/null
+++ b/man/sctp_send.3
@@ -0,0 +1,50 @@
+.\" (C) Copyright Sridhar Samudrala IBM Corp. 2005.
+.\"
+.\" Permission is granted to distribute possibly modified copies
+.\" of this manual provided the header is included verbatim,
+.\" and in case of nontrivial modification author and date
+.\" of the modification is added to the header.
+.\"
+.TH SCTP_SEND 3 2005-10-25 "Linux 2.6" "Linux Programmer's Manual"
+.SH NAME
+sctp_send \- Send a message from a SCTP socket. 
+.SH SYNOPSIS
+.nf
+.B #include <sys/types.h>
+.B #include <sys/socket.h>
+.B #include <netinet/sctp.h>
+.sp
+.BI "int sctp_send(int " sd ", const void * " msg ", size_t " len ,
+.BI "                 const struct sctp_sndrcvinfo *" sinfo ",
+.BI "                 uint32_t " flags );
+.fi
+.SH DESCRIPTION
+.BR sctp_send
+is a wrapper library function that can be used to send a message from a socket
+without the use of the CMSG header structures.
+.I sd
+is the socket descriptor from which the message pointed to by
+.I msg
+of length
+.I len
+is sent.
+.I sinfo
+is a pointer to a sctp_sndrcvinfo structure.  
+.I flags
+parameter is composed of a bitwise OR of the flags that can be be passed as
+the 3rd argument of a standard sendmsg() call.
+.SH "RETURN VALUE"
+On success,
+.BR sctp_sendmsg
+returns the number of bytes sent or -1 if an error occurred.
+.SH "SEE ALSO"
+.BR sctp (7)
+.BR sctp_bindx (3),
+.BR sctp_recvmsg (3),
+.BR sctp_recvv (3),
+.BR sctp_peeloff (3),
+.BR sctp_getpaddrs (3),
+.BR sctp_getladdrs (3),
+.BR sctp_opt_info (3),
+.BR sctp_sendmsg (3),
+.BR sctp_sendv (3)
diff --git a/man/sctp_sendmsg.3 b/man/sctp_sendmsg.3
new file mode 100644
index 0000000..51828fb
--- /dev/null
+++ b/man/sctp_sendmsg.3
@@ -0,0 +1,86 @@
+.\" (C) Copyright Sridhar Samudrala IBM Corp. 2004, 2005.
+.\"
+.\" Permission is granted to distribute possibly modified copies
+.\" of this manual provided the header is included verbatim,
+.\" and in case of nontrivial modification author and date
+.\" of the modification is added to the header.
+.\"
+.TH SCTP_SENDMSG 3 2004-10-25 "Linux 2.6" "Linux Programmer's Manual"
+.SH NAME
+sctp_sendmsg \- Send a message from a SCTP socket. 
+.SH SYNOPSIS
+.nf
+.B #include <sys/types.h>
+.B #include <sys/socket.h>
+.B #include <netinet/sctp.h>
+.sp
+.BI "int sctp_sendmsg(int " sd ", const void * " msg ", size_t " len ,
+.BI "                 struct sockaddr *" to ", socklen_t " tolen , 
+.BI "                 uint32_t " ppid ", uint32_t " flags ,
+.BI "                 uint16_t " stream_no ", uint32_t " timetolive ,
+.BI "                 uint32_t " context );
+.fi
+.SH DESCRIPTION
+.BR sctp_sendmsg
+is a wrapper library function that can be used to send a message from a socket
+while using the advanced features of SCTP. 
+.I sd
+is the socket descriptor from which the message pointed to by
+.I msg
+of length
+.I len
+is sent.
+.I to
+is the destination address of the message and
+.I tolen
+is the length of the destination address.
+.I stream_no
+identifies the stream number that the application wishes to send this message to.
+.I flags
+parameter is composed of a bitwise OR of the following values.
+.TP
+.B SCTP_UNORDERED
+This flags requests the un-ordered delivery of the message.
+.TP
+.B SCTP_ADDR_OVER
+This flag, in the one-to-many style, requests the SCTP stack to override the
+primary destination address with address specified in
+.I to.
+.TP
+.B SCTP_ABORT
+Setting this flag causes the specified association to abort by sending an ABORT
+message to the peer(one-to-many style only). The ABORT chunk will contain an
+error cause 'User Initiated Abort' with cause code 12. The cause specific
+information of this error cause is provided in
+.I msg.
+.TP
+.B SCTP_EOF
+Setting this flag invokes the SCTP graceful shutdown procedure on the specific
+association(one-to-many style only).
+.PP
+.I timetolive
+specifies the time duration in milliseconds. The sending side will expire the
+message if the message has not been sent to the peer within this time period.
+A value of 0 indicates that no timeout should occur on this message. 
+.I ppid
+is an opaque unsigned value that is passed to the remote end along with the
+message.
+.I context
+is a 32 bit opaque value that is passed back to the upper layer along with the
+undelivered message if an error occurs on the send of the message.
+.SH "RETURN VALUE"
+On success,
+.BR sctp_sendmsg
+returns the number of bytes sent or -1 if an error occurred.
+.SH "SEE ALSO"
+.BR sctp (7)
+.BR sctp_bindx (3),
+.BR sctp_connectx (3),
+.BR sctp_sendv (3),
+.BR sctp_send (3),
+.BR sctp_recvmsg (3),
+.BR sctp_recvv (3),
+.BR sctp_peeloff (3),
+.BR sctp_getpaddrs (3),
+.BR sctp_getladdrs (3),
+.BR sctp_opt_info (3),
diff --git a/man/sctp_sendv.3 b/man/sctp_sendv.3
new file mode 100644
index 0000000..03a2e44
--- /dev/null
+++ b/man/sctp_sendv.3
@@ -0,0 +1,97 @@
+.\" (C) Copyright Xin Long REDHAT Corp. 2018.
+.\"
+.\" Permission is granted to distribute possibly modified copies
+.\" of this manual provided the header is included verbatim,
+.\" and in case of nontrivial modification author and date
+.\" of the modification is added to the header.
+.\"
+.TH SCTP_SENDV 3 2018-04-29 "Linux 4.16 "Linux Programmer's Manual"
+.SH NAME
+sctp_sendv \- Send messages from a SCTP socket with an extensible way.
+.SH SYNOPSIS
+.nf
+.B #include <sys/types.h>
+.B #include <sys/socket.h>
+.B #include <netinet/sctp.h>
+.sp
+.BI "int sctp_sendv(int " sd ", const struct iovec * " iov ", int " iovcnt ,
+.BI "               struct sockaddr *" addrs ", int " addrcnt ", void * " info ,
+.BI "               socklen_t " infolen ", unsigned int " infotype ", int " flags );
+.fi
+.SH DESCRIPTION
+.BR sctp_sendv
+provides an extensible way for an application to communicate different send
+attributes to the SCTP stack when sending a message. There are three types
+of attributes that can be used to describe a message to be sent. They are
+struct sctp_sndinfo, struct sctp_prinfo, and struct sctp_authinfo. The
+following structure, sctp_sendv_spa, is defined to be used when more than
+one of the above attributes are needed to describe a message to be sent.
+
+   struct sctp_sendv_spa {
+     uint32_t sendv_flags;
+     struct sctp_sndinfo sendv_sndinfo;
+     struct sctp_prinfo sendv_prinfo;
+     struct sctp_authinfo sendv_authinfo;
+   };
+
+The sendv_flags field holds a bitwise OR of SCTP_SEND_SNDINFO_VALID,
+SCTP_SEND_PRINFO_VALID, and SCTP_SEND_AUTHINFO_VALID indicating if
+the sendv_sndinfo/sendv_prinfo/sendv_authinfo fields contain valid
+information.
+
+.I sd
+is the socket descriptor.
+.I iov
+is the gather buffer,  the data in the buffer is treated as a single
+user message.
+.I iovcnt
+is the number of elements in iov.
+.I addrs
+is an array of addresses to be used to set up an association or
+a single address to be used to send the message, and  NULL is passed
+in if the caller neither wants to set up an association nor wants
+to send the message to a specific address.
+.I addrcnt
+is the number of addresses in the addrs array.
+.I info
+is a pointer to the buffer containing the attribute associated with the
+message to be sent,  and the type is indicated by the info_type parameter.
+.I infolen
+is the length of info, in bytes.
+.I infotype
+identifies the type of the information provided in info ,and the current
+defined values are as follows:
+.TP
+.B SCTP_SENDV_NOINFO
+No information is provided.  The parameter info is a NULL pointer, and
+infolen is 0.
+.TP
+.B SCTP_SENDV_SNDINFO
+The parameter info is pointing to a struct sctp_sndinfo.
+.TP
+.B SCTP_SENDV_PRINFO
+The parameter info is pointing to a struct sctp_prinfo.
+.TP
+.B SCTP_SENDV_AUTHINFO
+The parameter info is pointing to a struct sctp_authinfo.
+.TP
+.B SCTP_SENDV_SPA
+The parameter info is pointing to a struct sctp_sendv_spa.
+.PP
+.I flags
+The same flags as used by the sendmsg() call flags (e.g., MSG_DONTROUTE).
+.SH "RETURN VALUE"
+On success,
+.BR sctp_sendv
+returns the number of bytes sent or -1 if an error occurred.
+.SH "SEE ALSO"
+.BR sctp (7)
+.BR sctp_bindx (3),
+.BR sctp_connectx (3),
+.BR sctp_send (3),
+.BR sctp_recvmsg (3),
+.BR sctp_recvv (3),
+.BR sctp_peeloff (3),
+.BR sctp_getpaddrs (3),
+.BR sctp_getladdrs (3),
+.BR sctp_opt_info (3),
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..c5b8fa6
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,8 @@
+include $(top_srcdir)/Makefile.vars
+include $(top_srcdir)/Makefile.rules
+
+SUBDIRS = apps include lib testlib withsctp
+
+if BUILD_TESTS
+SUBDIRS += func_tests
+endif
diff --git a/src/apps/.gitignore b/src/apps/.gitignore
new file mode 100644
index 0000000..a7ba019
--- /dev/null
+++ b/src/apps/.gitignore
@@ -0,0 +1,10 @@
+bindx_test
+myftp
+nagle_rcv
+nagle_snd
+peel_client
+peel_server
+sctp_darn
+sctp_status
+sctp_test
+sctp_xconnect
diff --git a/src/apps/Makefile.am b/src/apps/Makefile.am
new file mode 100644
index 0000000..7e32306
--- /dev/null
+++ b/src/apps/Makefile.am
@@ -0,0 +1,42 @@
+# Include these two in all the Makefile.am's!!!
+include $(top_srcdir)/Makefile.vars
+include $(top_srcdir)/Makefile.rules
+include $(top_srcdir)/Makefile.dirs
+
+# General compilation flags
+AM_CPPFLAGS = -I. -I$(top_builddir)/src/include -I$(top_srcdir)/src/testlib \
+              -g -O2 -fno-strict-aliasing -Wall -Wstrict-prototypes \
+              -Wimplicit-function-declaration
+
+AM_LDFLAGS = 
+
+LDADD = $(top_builddir)/src/testlib/libsctputil.la \
+	$(top_builddir)/src/lib/libsctp.la
+
+# programs to be installed with the distriubution
+bin_PROGRAMS = sctp_darn sctp_test sctp_status
+
+# Test programs and libraries to build
+noinst_PROGRAMS = bindx_test nagle_snd nagle_rcv myftp sctp_xconnect \
+	peel_server peel_client sctp_test sctp_status
+
+$(top_builddir)/src/lib/libsctp.la:
+	$(MAKE) -C $(top_builddir)/src/lib libsctp.la
+
+$(top_builddir)/src/testlib/libsctputil.la:
+	$(MAKE) -C $(top_builddir)/src/testlib libsctputil.la
+
+# Specifying the sources
+bindx_test_SOURCES = bindx_test.c
+sctp_darn_SOURCES = sctp_darn.c sctp_darn.h
+sctp_test_SOURCES = sctp_test.c
+sctp_status_SOURCES = sctp_status.c
+nagle_rcv_SOURCES = nagle_rcv.c 
+nagle_snd_SOURCES = nagle_snd.c 
+myftp_SOURCES = myftp.c
+sctp_xconnect_SOURCES = sctp_xconnect.c
+peel_server_SOURCES = peel_server.c
+peel_client_SOURCES = peel_client.c
+
+# Tutorials
+pkgdoc_DATA = sctp_darn.c sctp_darn.h sctp_test.c sctp_status.c
diff --git a/src/apps/bindx_test.c b/src/apps/bindx_test.c
new file mode 100644
index 0000000..ff3de86
--- /dev/null
+++ b/src/apps/bindx_test.c
@@ -0,0 +1,134 @@
+  /* -*-c-*-
+  **
+  ** sctp-tools: Another bindx test.
+  ** 
+  ** $Id: bindx_test.c,v 1.1.1.1 2002/08/06 22:31:05 inaky Exp $
+  **
+  ** Distributed under the terms of the GPL v2.0 as described in
+  ** $top_srcdir/COPYING. 
+  **
+  ** (C) Copyright IBM Corp. 2003
+  ** (C) 2002 Intel Corporation
+  **    Iñaky Pérez-González <inaky.perez-gonzalez@intel.com>:
+  **    Sridhar Samudrala <sri@us.ibm.com>
+  */
+
+#define _GNU_SOURCE /* GNU extensions */
+
+#include <stdlib.h>     /* malloc() */
+#include <arpa/inet.h>  /* inet_pton() */
+#include <errno.h>
+#include <sys/socket.h> /* socket() */
+#include <stdio.h>      /* fprintf */
+#include <netinet/in.h> /* sockaddr_in */
+#include <unistd.h>     /* close() */
+#include <string.h>     /* strchr() */
+#include <netinet/sctp.h>   /* bindx() */
+
+  /* Global stuff */
+
+#ifndef IPPROTO_SCTP 
+#define IPPROTO_SCTP 132
+#endif
+
+  /*! Main function: initialize, setup, run the main loop
+  **
+  **
+  */
+
+int main (int argc, char **argv)
+{
+	void *addr_buf, *buf_ptr;
+	void *addr_buf_size = 0;
+	size_t addrs, cnt;
+	int sd, result, port;
+	int domain = PF_INET6;
+
+	if (argc < 3) {
+		fprintf(stderr,
+			"Usage: bindx_test PORT IPADDR1 [IPADDR2 [...]]\n");
+		return 1;
+	}
+  
+	port = atoi(argv[1]);
+	printf("bindx_test: INFO: Port is %d\n", port);
+
+	/* Allocate the maximum space for the specified no. of  addresses.
+	 * Assume all of them are v6 addresses.
+	 */
+	addr_buf = malloc((argc -2) * sizeof(struct sockaddr_in6));
+	if (addr_buf == NULL) {
+		perror("bindx_test: ERROR: addr buf allocation failed");
+		return 1;
+	}
+  
+	/* Get the addresses from the cmd line */
+	addrs = 0;  /* healthy address iterator [and total counter] */
+	cnt = 2;    /* argument iterator */
+	buf_ptr = addr_buf;
+	while (cnt < argc) {
+		printf("bindx_test: INFO: Arg %zu: %s", cnt, argv[cnt]);
+		fflush(stderr);
+		if (strchr(argv[cnt], ':')) {
+			struct sockaddr_in6 *sa6; 
+
+			sa6 = (struct sockaddr_in6 *)buf_ptr;
+			printf(" IPv6 address number %zu", addrs);
+			sa6->sin6_family = AF_INET6;
+			sa6->sin6_port = port;
+			if (inet_pton(AF_INET6, argv[cnt], &sa6->sin6_addr)) {
+				addrs++;
+				addr_buf_size += sizeof(struct sockaddr_in6);
+				buf_ptr += sizeof(struct sockaddr_in6);
+			} else
+				printf(" error");
+		} else if (strchr(argv[cnt], '.')) {
+			struct sockaddr_in *sa; 
+
+			domain = PF_INET;
+			sa = (struct sockaddr_in *)buf_ptr;
+			printf (" IPv4 address number %zu", addrs);
+			sa->sin_family = AF_INET;
+			sa->sin_port = port;
+			if (inet_pton (AF_INET, argv[cnt], &sa->sin_addr)) {
+				addrs++;
+				addr_buf_size += sizeof(struct sockaddr_in);
+				buf_ptr += sizeof(struct sockaddr_in);
+			} else
+				printf (" error");
+		} else
+			printf (" Unknown");
+		putchar ('\n');
+		cnt++;
+	}
+
+	printf ("bindx_test: INFO: Got %zu addrs\n", addrs);
+  
+	/* Create the socket */
+	sd = socket(domain, SOCK_SEQPACKET, IPPROTO_SCTP);
+	if (sd == -1) {
+		perror("bindx_test: ERROR: Cannot open socket");
+		return 1;
+	}
+
+	/* add all */
+	result = sctp_bindx(sd, (struct sockaddr *)addr_buf, addrs,
+			    SCTP_BINDX_ADD_ADDR);
+	if (result == -1)
+		perror("bindx_test: ERROR: bindx addition error");
+	else {
+		printf("bindx_test: OK: bindx address addition\n");
+
+		/* remove all but the last */
+		result = sctp_bindx(sd, (struct sockaddr *)addr_buf, addrs-1,
+				     SCTP_BINDX_REM_ADDR);
+		if (result == -1)
+			perror("bindx_test: ERROR: bindx address removal");
+		else
+			printf("bindx_test: OK: bindx address removal\n");
+	}
+  
+	close(sd);
+	free(addr_buf);
+	return result;
+}
diff --git a/src/apps/myftp.c b/src/apps/myftp.c
new file mode 100644
index 0000000..64fa3f2
--- /dev/null
+++ b/src/apps/myftp.c
@@ -0,0 +1,413 @@
+/* myftp - simple file transfer over sctp testing tool. 
+ * Copyright (c) 2002 Intel Corp.
+ * 
+ * This file is part of the LKSCTP kernel Implementation.  This
+ * is a submission by Xingang Guo from the Intel Corporation while 
+ * participating on the LKSCTP project.  
+ * 
+ * The SCTP implementation is free software; 
+ * you can redistribute it and/or modify it under the terms of 
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ * 
+ * The SCTP implementation is distributed in the hope that it 
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.  
+ * 
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <sctp-developers-list@cig.mot.com>
+ * 
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Written or modified by: 
+ *    Xingang Guo           <xingang.guo@intel.com>
+ *    Jon Grimm             <jgrimm@us.ibm.com> 
+ * 
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define _GNU_SOURCE
+#include <getopt.h>
+#include <netdb.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h> /* for sockaddr_in */
+#include <errno.h>
+#include <netinet/sctp.h>
+
+#define BUFSIZE 1024
+static char buffer[BUFSIZE];
+#define DUMP_CORE {  char *diediedie = 0; *diediedie = 0; }
+
+typedef enum { COMMAND_NONE, COMMAND_RECV, COMMAND_SEND } command_t;
+
+/* These are the global options.  */
+#define MAX_NUM_HOST	5
+static char *local_host[MAX_NUM_HOST];
+static int num_local_host = 0;
+static int local_port = 4444;
+
+static int buffer_size = BUFSIZE;
+static char *remote_host = NULL;
+static int remote_port = 4444;
+static command_t command = COMMAND_NONE;
+static char *filename = NULL;
+static int interactive = 0;
+static unsigned long delay = 0;	     
+static int verbose = 0;
+
+static void
+usage(char *argv0)
+{
+	fprintf(stderr, "Usage: %s [options]\n",argv0);
+	fprintf(stderr, "Options:\n");
+	fprintf(stderr, "\t--local, -H <hostname>     Specify local interface\n");
+	fprintf(stderr, "\t--local-port, -P <port>    Specify local port (default 4444)\n");
+	fprintf(stderr, "\t--remote, -h <hostname>    Specify interface on remote host\n");
+	fprintf(stderr, "\t--remote-port, -p <port>   Specify remote port (default 4444)\n");
+	fprintf(stderr, "\t--listen, -l               Work in receiving mode\n");
+	fprintf(stderr, "\t--send, -s                 Work in sending mode\n");
+	fprintf(stderr, "\t--file, -f <filename>      File to read or write,\n");
+	fprintf(stderr, "\t--buffer, -b <size>        Buffer size. (default 1024 bytes)\n");
+	fprintf(stderr, "\t                           by default use standard input/output.\n");
+	fprintf(stderr, "\t--quick, -q                Send packets continueously,\n");
+	fprintf(stderr, "\t                           do not wait for <ENTER> key. Default wait.\n");
+	fprintf(stderr, "\t--delay, -d <usec>         Delay between consecutive sends (see --quick)\n");
+	fprintf(stderr, "\t--verbose, -v              In verbose mode, display the progress.\n");
+	fprintf(stderr, "\n\t--help,                    Print this message.\n\n");
+} /* usage() */
+
+static int parse_arguments(int argc, char *argv[])
+{
+	int option_index = 0;
+	int c;
+	static struct option long_options[] = {
+		{"local",	1, 0, 1},
+		{"local-port",	1, 0, 2},
+		{"remote",	1, 0, 3},
+		{"remote-port",	1, 0, 4},
+		{"file",	1, 0, 5},
+		{"delay",	1, 0, 6},
+		{"buffer",	1, 0, 7},
+		{"listen",	0, 0, 10},
+		{"send",	0, 0, 11},
+		{"quick",	0, 0, 12},
+		{"verbose",	0, 0, 13},
+		{"help",	0, 0, 99},
+		{0,		0, 0, 0}
+	};
+
+	/* Parse the arguments.  */
+	while (1) {
+		c = getopt_long(argc, argv, "H:P:h:p:f:d:b:qlsv",long_options,&option_index);
+		if (c == -1) break;
+
+		switch (c) {
+		case 0:
+			printf ("option %s", long_options[option_index].name);
+			if (optarg) printf (" with arg %s", optarg);
+			printf ("\n");
+			break;
+		case 1:		/* local host */
+		case 'H':
+			local_host[num_local_host++] = optarg;
+			break;
+		case 2:		/* local port */
+		case 'P':
+			local_port = atoi(optarg);
+			break;
+		case 3:		/* remote host */
+		case 'h':
+			remote_host = optarg;
+			break;
+		case 4:		/* remote port */
+		case 'p':
+			remote_port = atoi(optarg);
+			break;
+		case 5:
+		case 'f':
+			filename = optarg;
+			break;
+
+		case 6:
+		case 'd':
+			delay = strtoul(optarg,NULL,10);
+			printf("delay is %ld usec\n",delay);
+			break;
+
+		case 7:
+		case 'b':
+			buffer_size = atoi(optarg);
+			if ( buffer_size > BUFSIZE ) {
+				buffer_size = BUFSIZE;
+				fprintf(stderr,"Warning, buffer size too large, set to %d\n",buffer_size);
+			}
+			break;
+
+		case 12:
+		case 'q':	interactive = 0; break;
+
+		case 13:
+		case 'v':	verbose = 1; break;
+			/* COMMANDS */
+		case 10:	/* listen */
+		case 'l':
+			if (command) {
+				fprintf(stderr, "%s: pick ONE of listen or send\n", argv[0]);
+				return 1;
+			}
+			else command = COMMAND_RECV;
+			break;
+
+		case 11:	/* send */
+		case 's':
+			if (command) {
+				fprintf(stderr, "%s: pick ONE of listen or send\n", argv[0]);
+				return 2;
+			} else command = COMMAND_SEND;
+			break;
+
+		case '?':
+		case 99:
+			usage(argv[0]);
+			return 3;
+			break;
+
+		default:
+			printf ("%s: unrecognized option 0%c\n", argv[0], c);
+			usage(argv[0]);
+			return 4;
+		}
+	}
+
+	if (optind < argc) {
+		fprintf(stderr, "%s: non-option arguments are illegal: ", argv[0]);
+		while (optind < argc) fprintf(stderr, "%s ", argv[optind++]);
+		fprintf(stderr, "\n");
+		usage(argv[0]);
+		return 5;
+	}
+
+
+	if (0 == num_local_host) {
+		fprintf(stderr, "%s: You MUST provide a local host.\n", argv[0]);
+		usage(argv[0]);
+		return 6;
+	}
+
+	if ( filename == NULL && command == COMMAND_SEND)
+		fprintf(stderr,"%s: Use standard input to send\n",argv[0]);
+
+	if ( filename == NULL && command == COMMAND_RECV )
+		fprintf(stderr,"%s: Use standard output to write\n",argv[0]);
+
+	return 0;
+} /* parse_arguments() */
+
+static void
+emsg(char *prog,char *s)
+{
+	if ( prog != NULL ) fprintf(stderr,"%s: ",prog);
+	perror(s);
+	fflush(stdout);
+	//DUMP_CORE;
+
+	exit(-1);
+}
+
+static int build_endpoint(char *argv0)
+{
+	int retval,i;
+
+	/* Create the local endpoint.  */
+	if ( (retval = socket(PF_INET, SOCK_SEQPACKET, IPPROTO_SCTP)) < 0 ) {
+		emsg(argv0,"socket");
+		exit(retval);
+	}
+
+	for ( i = 0;i < num_local_host;i++ ) {
+		struct hostent *hst;
+		struct sockaddr_in laddr;
+
+		memset(&laddr, 0, sizeof(laddr));
+		/* Get the transport address for the local host name.  */
+		fprintf(stderr,"Hostname %d is %s\n",i+1,local_host[i]);
+		if ( (hst = gethostbyname(local_host[i])) == NULL ) {
+			fprintf(stderr, "%s: bad hostname: %s\n", argv0, local_host[i]);
+			exit(1);
+		}
+		memcpy(&laddr.sin_addr, hst->h_addr_list[0],sizeof(laddr.sin_addr));
+		laddr.sin_port = htons(local_port);
+		laddr.sin_family = AF_INET;
+
+		/* Bind this socket to the test port.  */
+		if ( bind(retval, (struct sockaddr *)&laddr, sizeof(laddr)) ) {
+			emsg(argv0,"bind");
+			exit(-1);
+		}
+	}
+
+	fprintf(stderr,"Endpoint built.\n");
+
+	return retval;
+} /* build_endpoint() */
+
+/* Convenience structure to determine space needed for cmsg. */
+typedef union {
+	struct sctp_initmsg init;
+	struct sctp_sndrcvinfo sndrcvinfo;
+} _sctp_cmsg_data_t;
+
+
+/* Listen on the socket, printing out anything that arrives.  */
+static void
+command_recv(char *argv0, int sk)
+{
+	struct msghdr inmessage;
+	char incmsg[CMSG_SPACE(sizeof(_sctp_cmsg_data_t))];
+	struct iovec iov;
+	int ret;
+	int fd;
+	int ct;
+
+	if (listen(sk, 1) == -1)
+		emsg(argv0, "listen");
+	/* Initialize inmessage with enough space for DATA... */
+	memset(&inmessage, 0, sizeof(inmessage));
+	iov.iov_base = buffer;
+	iov.iov_len = buffer_size;
+	inmessage.msg_iov = &iov;
+	inmessage.msg_iovlen = 1;
+	/* or a control message.  */
+	inmessage.msg_control = incmsg;
+	inmessage.msg_controllen = sizeof(incmsg);
+
+	/* creat a file */
+	if ( filename == NULL ) fd = 1;
+	else if ( (fd = open(filename,O_WRONLY|O_CREAT|O_TRUNC,S_IREAD|S_IWRITE)) == -1 )
+		emsg(argv0,"open");
+
+	fprintf(stderr,"%s Receiving...\n", argv0);
+	/* Get the messages sent */
+	ct = 0;
+	while ( (ret = recvmsg(sk, &inmessage, MSG_WAITALL)) >= 0 ) {
+		if ( verbose )
+			fprintf(stderr,"%s-%d received %d bytes\n",
+				argv0, ++ct, ret);
+		if ( !(inmessage.msg_flags & MSG_NOTIFICATION) ) {
+			//printf("%s write %d bytes\n",argv0,ret);
+			if ( write(fd,buffer,ret) != ret ) emsg(argv0,"write");
+		} else {
+			union sctp_notification *sn;
+			sn = (union sctp_notification *)iov.iov_base;
+			if ((sn->sn_header.sn_type == SCTP_ASSOC_CHANGE) &&
+			    (sn->sn_assoc_change.sac_state 
+			     == SCTP_SHUTDOWN_COMP))
+				break;
+		}
+			
+	}
+
+	if ( ret < 0 ) emsg(argv0,"recvmsg");
+
+	close(fd);
+	close(sk);
+} /* command_recv() */
+
+/* Read lines from stdin and send them to the socket.  */
+static void
+command_send(char *argv0, int sk)
+{
+	struct msghdr outmsg;
+	struct iovec iov;
+	struct hostent *hst;
+	struct sockaddr_in remote_addr;
+	int fd;
+	int msglen;
+	int ct;
+
+	/* Set up the destination.  */
+	hst = gethostbyname(remote_host);
+	if (hst == NULL || hst->h_length < 1) {
+		fprintf(stderr, "%s: bad hostname: %s\n", argv0, remote_host);
+		exit(1);
+	}
+	memcpy(&remote_addr.sin_addr, hst->h_addr_list[0], sizeof(remote_addr.sin_addr));
+	remote_addr.sin_port = htons(remote_port);
+	remote_addr.sin_family = AF_INET;
+
+	/* Initialize the message struct we use to pass messages to
+	 * the remote socket.
+	 */
+	iov.iov_base = buffer;
+	iov.iov_len = buffer_size;
+	outmsg.msg_iov = &iov;
+	outmsg.msg_iovlen = 1;
+	outmsg.msg_control = NULL;
+	outmsg.msg_controllen = 0;
+	outmsg.msg_name = &remote_addr;
+	outmsg.msg_namelen = sizeof(remote_addr);
+
+	/* open the file */
+	if ( filename == NULL ) fd = 0;
+	else if ( (fd = open(filename,O_RDONLY)) == -1 ) emsg(argv0,"open");
+
+	fprintf(stderr,"%s ready to send...\n", argv0);
+	ct = 0;
+	while ( (msglen = read(fd,buffer,buffer_size)) > 0 ) {
+		/* Send to our neighbor.  */
+		iov.iov_len = msglen;
+		if ( sendmsg(sk, &outmsg, 0) != msglen ) emsg(argv0,"sendmsg");
+		if ( verbose ) fprintf(stderr,"%s-%d send %d bytes\n",argv0,++ct,msglen);
+		if ( interactive && fd != 1 ) 
+			getchar();
+			// no flow control? no problem, make it slow
+		else if ( delay > 0 ) 
+			usleep(delay);
+	}
+
+	close(fd);
+	close(sk);
+} /* command_send() */
+
+int main(int argc, char *argv[])
+{
+	int ret;
+
+	if (( ret = parse_arguments(argc, argv) )) return ret;
+
+	switch(command) {
+	case COMMAND_NONE:
+		fprintf(stderr, "%s: Please specify a command.\n", argv[0]);
+		break;
+	case COMMAND_RECV:
+		command_recv(argv[0],build_endpoint(argv[0]));
+		break;
+	case COMMAND_SEND:
+		command_send(argv[0],build_endpoint(argv[0]));
+		break;
+	default:
+		fprintf(stderr, "%s: illegal command %d\n", argv[0], command);
+	} /* switch(command) */
+
+	return 0;
+}
diff --git a/src/apps/nagle_rcv.c b/src/apps/nagle_rcv.c
new file mode 100644
index 0000000..18e0945
--- /dev/null
+++ b/src/apps/nagle_rcv.c
@@ -0,0 +1,243 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2002, 2003
+ * Copyright (c) 1999-2000 Cisco, Inc.
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ * Copyright (c) 2001 Intel Corp.
+ * Copyright (c) 2001 Nokia, Inc.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ *    Ardelle Fan <ardelle.fan@intel.com>
+ *    Sridhar Samudrala <sri@us.ibm.com>
+ */
+
+/* This is a receiver for the performance test to verify Nagle's algorithm. 
+ * It creates a socket, binds to a address specified as a parameter and
+ * goes into a receive loop waiting for 1,000,000 packets. Then it calculates
+ * the packet receive rate, i.e. packets/second.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+#include <getopt.h>
+#include <netdb.h>
+#include <time.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 1;
+int TST_CNT = 0;
+
+void
+usage(char *progname)
+{
+	fprintf(stderr, "Usage: %s -H hostname [-P port]\n", progname);
+	fprintf(stderr, " -H, --local\t\t local hostname,\n");
+	fprintf(stderr, " -P, --local-port\t local port,\n");
+}
+
+int
+main(int argc, char *argv[])
+{
+	int sk, i;
+	struct addrinfo *hst_res;
+	sockaddr_storage_t host;
+	sockaddr_storage_t msgname;
+	struct iovec iov;
+	struct msghdr inmessage;
+	char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+	int error, pf_class;
+	char *big_buffer;
+	char *local_host = NULL;
+	int local_port = SCTP_TESTPORT_1; 
+	char port_buffer[10];
+	int option_index = 0;
+	time_t from, to;
+	int bytes_received = 0; 
+	int c;
+	static struct option long_options[] = {
+		{"local",	1, 0, 1},
+		{"local-port",	1, 0, 2},
+		{0,		0, 0, 0}
+	};
+
+	/* Rather than fflush() throughout the code, set stdout to 
+	 * be unbuffered. 
+	 */
+	setvbuf(stdout, NULL, _IONBF, 0); 
+
+	/* Parse the arguments.  */
+	while (1) {
+		c = getopt_long (argc, argv, "H:P:",
+				 long_options, &option_index);
+		if (c == -1)
+			break;
+
+		switch (c) {
+		case 0:
+			printf("option %s", long_options[option_index].name);
+			if (optarg) {
+				printf(" with arg %s", optarg);
+			}
+			printf("\n");
+			break;
+		case 1:		/* local host */
+		case 'H':
+			local_host = optarg;
+			break;
+		case 2:		/* local port */
+		case 'P':
+			local_port = atoi(optarg);
+			break;
+		case '?':
+			usage(argv[0]);
+			exit(0);
+
+		default:
+			printf ("%s: unrecognized option 0%c\n", argv[0], c);
+			usage(argv[0]);
+			exit(1);
+		}
+	}
+
+	if (optind < argc)
+	{
+		fprintf(stderr, "%s: non-option arguments are illegal: ",
+			argv[0]);
+		while (optind < argc)
+			fprintf(stderr, "%s ", argv[optind++]);
+		fprintf (stderr, "\n");
+		usage(argv[0]);
+		exit(1);
+	}
+
+	if (!local_host) {
+		fprintf(stderr, "%s: : option -H, --local is required\n",
+			argv[0]);
+		usage(argv[0]);
+		exit(1);
+	}
+
+	/* Set some basic values which depend on the address family. */
+	if (!strcmp(local_host, "0"))
+		local_host = "0.0.0.0";
+
+	snprintf(port_buffer, 10, "%d", local_port);
+	error = getaddrinfo(local_host, port_buffer, NULL, &hst_res);
+	if (error) {
+		fprintf(stderr, "%s: getaddrinfo failed: %s\n", argv[0], local_host);
+		exit(1);
+	}
+
+	pf_class = hst_res->ai_family;
+	switch (pf_class) {
+	case AF_INET:
+	case AF_INET6:
+		memcpy(&host.sa, hst_res->ai_addr, hst_res->ai_addrlen);
+		break;
+	default:
+		fprintf(stderr, "Invalid address type.\n");
+		exit(1);
+		break;
+	}
+
+	freeaddrinfo(hst_res);
+
+	/* Create the endpoint which will talk to nagle_snd.  */
+	sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+
+	/* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+	test_enable_assoc_change(sk);
+
+	/* Bind the sockets to the test port.  */
+	test_bind(sk, &host.sa, sizeof(host));
+
+	/* Mark sk as being able to accept new associations.  */
+	test_listen(sk, 1);
+
+	printf("Listening on port:%d\n", local_port);
+
+	/* Initialize inmessage for receives. */
+	memset(&inmessage, 0, sizeof(inmessage));
+	big_buffer = test_malloc(REALLY_BIG);
+	iov.iov_base = big_buffer;
+	iov.iov_len = REALLY_BIG;
+	inmessage.msg_iov = &iov;
+	inmessage.msg_iovlen = 1;
+	inmessage.msg_control = incmsg;
+	inmessage.msg_controllen = sizeof(incmsg);
+	inmessage.msg_name = &msgname;
+	inmessage.msg_namelen = sizeof(msgname);
+	memset(&msgname, 0, sizeof(msgname));
+
+	/* Get the communication up message on sk.  */
+	error = test_recvmsg(sk, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage, error,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);	
+
+	printf("Established connection with "); 
+	if (AF_INET == msgname.sa.sa_family)
+		printf("%d.%d.%d.%d(%d)\n", NIPQUAD(msgname.v4.sin_addr),
+		       ntohs(msgname.v4.sin_port));
+	if (AF_INET6 == msgname.sa.sa_family)
+		printf("%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x(%d)\n",
+		       NIP6(msgname.v6.sin6_addr), ntohs(msgname.v6.sin6_port));
+
+	time(&from);
+	for (i=0; i<1000000; i++) {
+		inmessage.msg_controllen = sizeof(incmsg);
+		inmessage.msg_namelen = sizeof(msgname);
+		error = test_recvmsg(sk, &inmessage, MSG_WAITALL);
+		if (inmessage.msg_flags & MSG_NOTIFICATION)
+			break;
+		printf("Received %d bytes of data\n", error);
+		bytes_received += error;
+	}
+	time(&to);
+
+	printf("\t%d messages(%d bytes) successfully received in %ld "
+	       "seconds.\n", i, bytes_received, to - from);
+	printf("The receive rate is %ld bytes/second\n",
+	       bytes_received/(to - from));
+
+	/* Shut down the link.	*/
+	error = 0;
+	close(sk);
+
+	return 0;
+}
diff --git a/src/apps/nagle_snd.c b/src/apps/nagle_snd.c
new file mode 100644
index 0000000..bc960cc
--- /dev/null
+++ b/src/apps/nagle_snd.c
@@ -0,0 +1,359 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2002, 2003
+ * Copyright (c) 1999-2000 Cisco, Inc.
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ * Copyright (c) 2001 Intel Corp.
+ * Copyright (c) 2001 Nokia, Inc.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ *    Ardelle Fan <ardelle.fan@intel.com>
+ *    Sridhar Samudrala <sri@us.ibm.com>
+ */
+
+/* This is a receiver for the performance test to verify Nagle's algorithm. 
+ * It creates a socket, binds to a address specified as a parameter and
+ * sends 1,000,000 packets to a specified target.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+#include <getopt.h>
+#include <netdb.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 1;
+int TST_CNT = 0;
+
+void
+usage(char *argv0)
+{
+	fprintf(stderr, "Usage: %s -H localhost [-P localport] "
+		"-h remotehost [-p remoteport]\n"
+		"\t\t[-S msgsize] [-I interval] -N\n"
+		" -H, --local\t\tspecify one of the local addresses,\n"
+		" -P, --local-port\tspecify the port number for local addresses,\n"
+		" -h, --remote\t\tspecify one of the remote addresses,\n"
+		" -p, --remote-port\tspecify the port number for remote addresses,\n"
+		" -S, --size\t\tspecify the size(byte) of the sending message,\n"
+		" -I, --interval\t\tspecify the interval(second) that sending messages at,\n"
+		" -N, --nodelay\t\tspecify whether the SCTP allows Nagle's algorithm\n",
+		argv0);
+}
+
+int
+main(int argc, char *argv[])
+{
+	int sk, i;
+	struct addrinfo *hst_res, *tgt_res;
+	sockaddr_storage_t host, target;
+	sockaddr_storage_t msgname;
+	struct iovec iov;
+	struct msghdr inmessage;
+	struct msghdr outmessage;
+	char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+	char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+	struct cmsghdr *cmsg;
+	struct sctp_sndrcvinfo *sinfo;
+	struct iovec out_iov;
+	char *message;
+	int error, pf_class;
+	sctp_assoc_t associd;
+	uint32_t ppid;
+	uint32_t stream;
+	char *remote_host = NULL;
+	int remote_port = SCTP_TESTPORT_1;
+	char *local_host = NULL;
+	int local_port = SCTP_TESTPORT_2;
+	int size = 1;
+	int interval = 0;
+	int nodelay = 0;
+	int option_index = 0;
+	char *big_buffer;
+	char port_buffer[10];
+	int c;
+	static struct option long_options[] = {
+		{"local",	 1, 0, 1},
+		{"local-port",	 1, 0, 2},
+		{"remote",	 1, 0, 3},
+		{"remote-port",  1, 0, 4},
+		{"size",	 1, 0, 5},
+		{"interval",	 1, 0, 6},
+		{"nodelay",	 0, 0, 10},
+		{0,		 0, 0, 0}
+	};
+
+	/* Rather than fflush() throughout the code, set stdout to 
+	 * be unbuffered. 
+	 */
+	setvbuf(stdout, NULL, _IONBF, 0); 
+
+	/* Parse the arguments.  */
+	while (1) {
+		c = getopt_long (argc, argv, "H:P:h:p:S:I:N",
+				 long_options, &option_index);
+		if (c == -1)
+			break;
+
+		switch (c) {
+		case 0:
+			printf("option %s", long_options[option_index].name);
+			if (optarg) {
+				printf(" with arg %s", optarg);
+			}
+			printf("\n");
+			break;
+		case 1:		/* local host */
+		case 'H':
+			local_host = optarg;
+			break;
+		case 2:		/* local port */
+		case 'P':
+			local_port = atoi(optarg);
+			break;
+		case 3:		/* remote host */
+		case 'h':
+			remote_host = optarg;
+			break;
+		case 4:		/* remote port */
+		case 'p':
+			remote_port = atoi(optarg);
+			break;
+		case 5:		/* size */
+		case 'S':
+			size = atoi(optarg);
+			break;
+		case 6:		/* interval */
+		case 'I':
+			interval = atoi(optarg);
+			break;
+		case 10:	 /* nodelay */
+		case 'N':
+			nodelay = 1;
+			break;
+		case '?':
+			usage(argv[0]);
+			exit(0);
+
+		default:
+			printf ("%s: unrecognized option 0%c\n",
+				argv[0], c);
+			usage(argv[0]);
+			exit(1);
+		}
+	}
+
+	if (optind < argc)
+	{
+		fprintf(stderr, "%s: non-option arguments are illegal: ",
+			argv[0]);
+		while (optind < argc)
+			fprintf(stderr, "%s ", argv[optind++]);
+		fprintf (stderr, "\n");
+		usage(argv[0]);
+		exit(1);
+	}
+
+	if (!local_host || !remote_host) {
+		fprintf(stderr, "%s: : option --local and --remote are required\n",
+			argv[0]);
+		usage(argv[0]);
+		exit(1);
+	}
+
+	/* Set some basic values which depend on the address family. */
+	if (!strcmp(local_host, "0"))
+		local_host = "0.0.0.0";
+
+	snprintf(port_buffer, 10, "%d", local_port);
+	error = getaddrinfo(local_host, port_buffer, NULL, &hst_res);
+	if (error) {
+		fprintf(stderr, "%s: getaddrinfo failed: %s\n", argv[0], local_host);
+		exit(1);
+	}
+
+	snprintf(port_buffer, 10, "%d", remote_port);
+	error = getaddrinfo(remote_host, port_buffer, NULL, &tgt_res);
+	if (error) {
+		fprintf(stderr, "%s: getaddrinfo failed: %s\n", argv[0], remote_host);
+		exit(1);
+	}
+
+	if ( hst_res->ai_family != tgt_res->ai_family) {
+		fprintf(stderr, "local and reomte hosts should be the " 
+			"same address family\n");
+		exit(1);
+	}
+
+	pf_class = hst_res->ai_family;
+	switch (pf_class) {
+	case AF_INET:
+	case AF_INET6:
+		memcpy(&host.sa, hst_res->ai_addr, hst_res->ai_addrlen);
+		memcpy(&target.sa, tgt_res->ai_addr, tgt_res->ai_addrlen);
+		break;
+	default:
+		fprintf(stderr, "Invalid address type.\n");
+		exit(1);
+		break;
+	}
+
+	freeaddrinfo(hst_res);
+	freeaddrinfo(tgt_res);
+
+	sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+
+	/* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+	test_enable_assoc_change(sk);
+
+	test_setsockopt(sk, SCTP_NODELAY, &nodelay, sizeof(int));
+
+	/* Bind the sockets to the test port.  */
+	test_bind(sk, &host.sa, sizeof(host));
+
+	/* Mark sk as being able to accept new associations.  */
+	test_listen(sk, 1);
+
+	/* Build up a msghdr structure we can use for all sending.  */
+	outmessage.msg_name = &target;
+	outmessage.msg_namelen = sizeof(target);
+	outmessage.msg_iov = &out_iov;
+	outmessage.msg_iovlen = 1;
+	outmessage.msg_control = outcmsg;
+	outmessage.msg_controllen = sizeof(outcmsg);
+	outmessage.msg_flags = 0;
+	cmsg = CMSG_FIRSTHDR(&outmessage);
+	cmsg->cmsg_level = IPPROTO_SCTP;
+	cmsg->cmsg_type = SCTP_SNDRCV;
+	cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+	outmessage.msg_controllen = cmsg->cmsg_len;
+	sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+	memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+	ppid = rand(); /* Choose an arbitrary value. */
+	stream = 1; 
+	sinfo->sinfo_ppid = ppid;
+	sinfo->sinfo_stream = stream;
+
+	message = test_malloc((size + 1) * sizeof(u_int8_t));
+
+	for(i=0; i + 10 < size; i+= 10)
+		memcpy(message+i, "1234567890", 10);
+	strncpy(message+i, "1234567890", size-i);
+	*(message+size) = 0;
+
+	outmessage.msg_iov->iov_base = message;
+	outmessage.msg_iov->iov_len = size + 1;
+
+	printf("Initiating connection with %s:%d...\n", remote_host,
+	       remote_port);
+
+	/* Send the first message.  This will create the association.  */
+	test_sendmsg(sk, &outmessage, 0, size+1);
+
+	memset(&inmessage, 0, sizeof(inmessage));
+	big_buffer = test_malloc(REALLY_BIG);
+	iov.iov_base = big_buffer;
+	iov.iov_len = REALLY_BIG;
+	inmessage.msg_iov = &iov;
+	inmessage.msg_iovlen = 1;
+	inmessage.msg_control = incmsg;
+	inmessage.msg_controllen = sizeof(incmsg);
+	inmessage.msg_name = &msgname;
+	inmessage.msg_namelen = sizeof(msgname);
+	memset(&msgname, 0, sizeof(msgname));
+
+	/* Get the communication up message on sk.  */
+	error = test_recvmsg(sk, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage, error,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);	
+	associd = ((struct sctp_assoc_change *)iov.iov_base)->sac_assoc_id;
+
+	printf("Established connection with ");	
+	if (AF_INET == msgname.sa.sa_family)
+		printf("%d.%d.%d.%d(%d)\n", NIPQUAD(msgname.v4.sin_addr),
+		       ntohs(msgname.v4.sin_port));
+	if (AF_INET6 == msgname.sa.sa_family)
+		printf("%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x(%d)\n",
+		       NIP6(msgname.v6.sin6_addr), ntohs(msgname.v6.sin6_port));
+
+	printf("Sending data to receiver...\n");
+
+	for (i=1; i<1000000; i++) {
+
+		if (interval)
+			sleep(interval);
+
+		outmessage.msg_name = &target;
+		outmessage.msg_namelen = sizeof(target);
+		outmessage.msg_iov = &out_iov;
+		outmessage.msg_iovlen = 1;
+		outmessage.msg_controllen = sizeof(outcmsg);
+		outmessage.msg_flags = 0;
+
+		cmsg = CMSG_FIRSTHDR(&outmessage);
+		cmsg->cmsg_level = IPPROTO_SCTP;
+		cmsg->cmsg_type = SCTP_SNDRCV;
+		cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+		outmessage.msg_controllen = cmsg->cmsg_len;
+		sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+		memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+
+		ppid++;
+
+		sinfo->sinfo_ppid = ppid;
+		sinfo->sinfo_stream = stream;
+		sinfo->sinfo_assoc_id = associd;
+
+		outmessage.msg_iov->iov_base = message;
+		outmessage.msg_iov->iov_len = size + 1;
+
+		test_sendmsg(sk, &outmessage, 0, size+1);
+	}
+
+	printf("\n\n\t\tComplete all the data sendings to receiver...\n\n\n");
+
+	error = 0;
+	close(sk);
+
+	free(message);
+
+	/* Indicate successful completion.  */
+	return 0;
+
+}
diff --git a/src/apps/peel_client.c b/src/apps/peel_client.c
new file mode 100644
index 0000000..5c195d3
--- /dev/null
+++ b/src/apps/peel_client.c
@@ -0,0 +1,672 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2003
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * In addition:
+ *
+ * Copyright (c) 2003 Cisco
+ *
+ * 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.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ *    Randall Stewart   <rrs@cisco.com>
+ *    Sridhar Samudrala <sri@us.ibm.com>
+ */
+
+#include <ctype.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+
+#include <stdarg.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <arpa/inet.h>
+#include <time.h>
+#include <string.h>
+#include <errno.h>
+#include <poll.h>
+#include <sys/uio.h>
+#include <netdb.h>
+
+#include <netinet/sctp.h>
+#ifdef __NetBSD__
+#include <sys/inttypes.h>
+#endif
+
+#define SCTP_CRC32C_POLY 0x1EDC6F41
+#define SCTP_CRC32C(c,d) (c=(c>>8)^sctp_crc_c[(c^(d))&0xFF])
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/* Copyright 2001, D. Otis.  Use this program, code or tables    */
+/* extracted from it, as desired without restriction.            */
+/*                                                               */
+/* 32 Bit Reflected CRC table generation for SCTP.               */
+/* To accommodate serial byte data being shifted out least       */
+/* significant bit first, the table's 32 bit words are reflected */
+/* which flips both byte and bit MS and LS positions.  The CRC   */
+/* is calculated MS bits first from the perspective of the serial*/
+/* stream.  The x^32 term is implied and the x^0 term may also   */
+/* be shown as +1.  The polynomial code used is 0x1EDC6F41.      */
+/* Castagnoli93                                                  */
+/* x^32+x^28+x^27+x^26+x^25+x^23+x^22+x^20+x^19+x^18+x^14+x^13+  */
+/* x^11+x^10+x^9+x^8+x^6+x^0                                     */
+/* Guy Castagnoli Stefan Braeuer and Martin Herrman              */
+/* "Optimization of Cyclic Redundancy-Check Codes                */
+/* with 24 and 32 Parity Bits",                                  */
+/* IEEE Transactions on Communications, Vol.41, No.6, June 1993  */
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+static unsigned char buffer1[4100];
+static unsigned char buffer2[4100];
+static unsigned char buffer3[4100];
+static unsigned char buffer4[4100];
+static struct sockaddr_in bindto,got,to;
+static socklen_t len;
+
+unsigned long  sctp_crc_c[256] = {
+	0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,
+	0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
+	0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,
+	0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,
+	0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
+	0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,
+	0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L,
+	0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,
+	0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL,
+	0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
+	0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L,
+	0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,
+	0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L,
+	0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,
+	0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
+	0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,
+	0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L,
+	0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
+	0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L,
+	0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
+	0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L,
+	0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,
+	0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L,
+	0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,
+	0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
+	0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,
+	0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L,
+	0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,
+	0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L,
+	0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
+	0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L,
+	0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,
+	0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL,
+	0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,
+	0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
+	0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
+	0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L,
+	0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,
+	0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL,
+	0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
+	0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L,
+	0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,
+	0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL,
+	0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,
+	0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
+	0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,
+	0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L,
+	0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,
+	0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L,
+	0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
+	0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL,
+	0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,
+	0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL,
+	0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
+	0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
+	0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,
+	0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL,
+	0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,
+	0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L,
+	0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
+	0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L,
+	0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,
+	0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL,
+	0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L,
+};
+
+u_int32_t
+update_crc32(u_int32_t crc32,
+	     unsigned char *buffer,
+	     unsigned int length)
+{
+	int i;
+	for (i = 0; i < length; i++) {
+		SCTP_CRC32C(crc32, buffer[i]);
+	}
+	return (crc32);
+}
+
+u_int32_t
+sctp_csum_finalize(u_int32_t crc32)
+{
+	u_int32_t result;
+#if BYTE_ORDER == BIG_ENDIAN
+	u_int8_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;
+	result = ((byte0 << 24) |
+		  (byte1 << 16) |
+		  (byte2 << 8) |
+		  byte3);
+	crc32 = htonl(result);
+#else
+	/*
+	 * For INTEL platforms the result comes out in network order.
+	 * No htonl is required or the swap above. So we optimize out
+	 * both the htonl and the manual swap above.
+	 */
+	crc32 = result;
+#endif
+	return (crc32);
+}
+
+static u_int32_t at = 468700;
+
+void
+prepare_buffers(void)
+{
+        /* Prepare buffers */
+	u_int32_t temp,*p;
+	int i;
+
+	p = (u_int32_t *)buffer1;
+	for(i=0;i<(sizeof(buffer1)/4);i++){
+		*p = at;
+		at++;
+		p++;
+	}
+	/* backup over the last int */
+	p--;
+	*p = 0;
+	temp = 0xffffffff;
+	temp = update_crc32(temp,buffer1,(sizeof(buffer1)-4));
+	*p = sctp_csum_finalize(temp);
+
+	p = (u_int32_t *)buffer2;
+	for(i=0;i<(sizeof(buffer2)/4);i++){
+		*p = at;
+		at++;
+		p++;
+	}
+	p--;
+	*p = 0;
+	temp = 0xffffffff;
+	temp = update_crc32(temp,buffer2,(sizeof(buffer2)-4));
+	*p = sctp_csum_finalize(temp);
+
+	p = (u_int32_t *)buffer3;
+	for(i=0;i<(sizeof(buffer3)/4);i++){
+		*p = at;
+		at++;
+		p++;
+	}
+	p--;
+	*p = 0;
+	temp = 0xffffffff;
+	temp = update_crc32(temp,buffer3,(sizeof(buffer3)-4));
+	*p = sctp_csum_finalize(temp);
+
+	p = (u_int32_t *)buffer4;
+	for(i=0;i<(sizeof(buffer4)/4);i++){
+		*p = at;
+		at++;
+		p++;
+	}
+	p--;
+	*p = 0;
+	temp = 0xffffffff;
+	temp = update_crc32(temp,buffer4,(sizeof(buffer4)-4));
+	*p = sctp_csum_finalize(temp);
+}
+
+static int
+my_handle_notification(int fd,char *notify_buf) {
+	union sctp_notification *snp;
+	struct sctp_assoc_change *sac;
+	struct sctp_paddr_change *spc;
+	struct sctp_remote_error *sre;
+	struct sctp_send_failed *ssf;
+	struct sctp_shutdown_event *sse;
+	int asocDown;
+	char *str;
+	char buf[256];
+	struct sockaddr_in *sin;
+	struct sockaddr_in6 *sin6;
+
+	asocDown = 0;
+	snp = (union sctp_notification *)notify_buf;
+	switch(snp->sn_header.sn_type) {
+	case SCTP_ASSOC_CHANGE:
+		sac = &snp->sn_assoc_change;
+		switch(sac->sac_state) {
+
+		case SCTP_COMM_UP:
+			str = "COMMUNICATION UP";
+			break;
+		case SCTP_COMM_LOST:
+			str = "COMMUNICATION LOST";
+			asocDown = 1;
+			break;
+		case SCTP_RESTART:
+		        str = "RESTART";
+			break;
+		case SCTP_SHUTDOWN_COMP:
+			str = "SHUTDOWN COMPLETE";
+			asocDown = 1;
+			break;
+		case SCTP_CANT_STR_ASSOC:
+			str = "CANT START ASSOC";
+			printf("EXIT:SCTP_ASSOC_CHANGE: %s, assoc=%xh\n", str,
+			       (uint32_t)sac->sac_assoc_id);
+			exit(0);
+			break;
+		default:
+			str = "UNKNOWN";
+		} /* end switch(sac->sac_state) */
+		printf("SCTP_ASSOC_CHANGE: %s, assoc=%xh\n", str,
+		       (uint32_t)sac->sac_assoc_id);
+		break;
+	case SCTP_PEER_ADDR_CHANGE:
+		spc = &snp->sn_paddr_change;
+		switch(spc->spc_state) {
+		case SCTP_ADDR_AVAILABLE:
+			str = "ADDRESS AVAILABLE";
+			break;
+		case SCTP_ADDR_UNREACHABLE:
+			str = "ADDRESS UNAVAILABLE";
+			break;
+		case SCTP_ADDR_REMOVED:
+			str = "ADDRESS REMOVED";
+			break;
+		case SCTP_ADDR_ADDED:
+			str = "ADDRESS ADDED";
+			break;
+		case SCTP_ADDR_MADE_PRIM:
+			str = "ADDRESS MADE PRIMARY";
+			break;
+		default:
+			str = "UNKNOWN";
+		} /* end switch */
+		sin6 = (struct sockaddr_in6 *)&spc->spc_aaddr;
+		if (sin6->sin6_family == AF_INET6) {
+			inet_ntop(AF_INET6, (char*)&sin6->sin6_addr, buf, sizeof(buf));
+		} else {
+			sin = (struct sockaddr_in *)&spc->spc_aaddr;
+			inet_ntop(AF_INET, (char*)&sin->sin_addr, buf, sizeof(buf));
+		}
+		printf("SCTP_PEER_ADDR_CHANGE: %s, addr=%s, assoc=%xh\n", str,
+		       buf, (uint32_t)spc->spc_assoc_id);
+		break;
+	case SCTP_REMOTE_ERROR:
+		sre = &snp->sn_remote_error;
+		printf("SCTP_REMOTE_ERROR: assoc=%xh\n",
+		       (uint32_t)sre->sre_assoc_id);
+		break;
+	case SCTP_SEND_FAILED:
+		ssf = &snp->sn_send_failed;
+		printf("SCTP_SEND_FAILED: assoc=%xh\n",
+		       (uint32_t)ssf->ssf_assoc_id);
+		break;
+	case SCTP_ADAPTATION_INDICATION:
+	  {
+	    struct sctp_adaptation_event *ae;
+	    ae = &snp->sn_adaptation_event;
+	    printf("\nSCTP_adaptation_indication bits:0x%x\n",
+		   (u_int)ae->sai_adaptation_ind);
+	  }
+	  break;
+	case SCTP_PARTIAL_DELIVERY_EVENT:
+	  {
+	    struct sctp_pdapi_event *pdapi;
+	    pdapi = &snp->sn_pdapi_event;
+	    printf("SCTP_PD-API event:%u\n",
+		   pdapi->pdapi_indication);
+	    if(pdapi->pdapi_indication == 0){
+		    printf("PDI- Aborted\n");
+	    }
+	  }
+	  break;
+
+	case SCTP_SHUTDOWN_EVENT:
+                sse = &snp->sn_shutdown_event;
+		printf("SCTP_SHUTDOWN_EVENT: assoc=%xh\n",
+		       (uint32_t)sse->sse_assoc_id);
+		break;
+	default:
+		printf("Unknown notification event type=%xh\n", 
+		       snp->sn_header.sn_type);
+	} /* end switch(snp->sn_type) */
+	if(asocDown){
+		printf("Bring association back up\n");
+		len = sizeof(to);
+		if(connect(fd,(struct sockaddr *)&to,len) == -1){
+			printf("Sorry connect fails %d\n",errno);
+		}
+		return(1);
+	}
+	return(0);
+}
+
+
+	
+int
+my_sctpReadInput(int fd)
+{
+	/* receive some number of datagrams and
+	 * act on them.
+	 */
+	int sz;
+	struct msghdr msg;
+	struct iovec iov[2];
+	unsigned char from[200];
+	char readBuffer[65535];
+	char controlVector[65535];
+  
+	iov[0].iov_base = readBuffer;
+	iov[0].iov_len = sizeof(readBuffer);
+	iov[1].iov_base = NULL;
+	iov[1].iov_len = 0;
+	msg.msg_name = (caddr_t)from;
+	msg.msg_namelen = sizeof(from);
+	msg.msg_iov = iov;
+	msg.msg_iovlen = 1;
+	msg.msg_control = (caddr_t)controlVector;
+	msg.msg_controllen = sizeof(controlVector);
+	msg.msg_flags = 0;
+	errno = 0;
+	sz = recvmsg(fd,&msg,0);
+	if(sz <= 0){
+		printf("Read returns %d errno:%d control len is %zu msgflg:%x\n",
+		       sz,errno,
+		       msg.msg_controllen,msg.msg_flags);
+	}
+	if (msg.msg_flags & MSG_NOTIFICATION) {
+		return(my_handle_notification(fd,readBuffer));
+	}else{
+		printf("Huh, I got data?.. ignored (%d bytes)\n",sz);
+		return(0);
+	}
+}
+
+
+int
+clear_fds(int fd,int fd1)
+{
+	int felldown;
+	int max,notdone;
+	fd_set readfds,writefds,exceptfds;
+	struct timeval tv;
+	memset(&tv,0,sizeof(tv));
+	FD_ZERO(&readfds);
+	FD_ZERO(&writefds);
+	FD_ZERO(&exceptfds);
+	felldown = 0;
+	FD_SET(fd,&readfds);
+	FD_SET(fd1,&readfds);
+	if(fd > fd1){
+		max = fd + 1;
+	}else{
+		max = fd1 + 1;
+	}
+	notdone = 1;
+	while(notdone){
+		if (select(max, &readfds, &writefds, &exceptfds, &tv) == -1)
+			break;
+		notdone = 0;
+		if(FD_ISSET(fd,&readfds)){
+			notdone++;
+			printf("clearing fd:%d\n",fd);
+			felldown += my_sctpReadInput(fd);
+			notdone = 1;
+		}
+		if(FD_ISSET(fd1,&readfds)){
+			notdone++;
+			printf("clearing fd1:%d\n",fd1);
+			felldown += my_sctpReadInput(fd1);
+		}
+	}
+	return(felldown);
+}
+
+void
+process_out_data(int fd,int fd1)
+{
+	int notdone,x,ret;
+	while(1){
+		/* Prepare the buffers */
+		prepare_buffers();
+		/* send out the 4 buffers */
+		ret = sendto(fd,buffer1,sizeof(buffer1),0,
+			     (struct sockaddr *)&to,sizeof(to));
+		if(ret < sizeof(buffer1)){
+			printf("Gak1, error:%d ret:%d\n",errno,ret);
+		}
+
+		ret = sendto(fd1,buffer2,sizeof(buffer1),0,
+			     (struct sockaddr *)&to,sizeof(to));
+		if(ret < sizeof(buffer2)){
+			printf("Gak2, error:%d ret:%d\n",errno,ret);
+		}
+
+
+		ret = sendto(fd,buffer3,sizeof(buffer1),0,
+			     (struct sockaddr *)&to,sizeof(to));
+		if(ret < sizeof(buffer3)){
+			printf("Gak3, error:%d ret:%d\n",errno,ret);
+		}
+
+
+		ret = sendto(fd1,buffer4,sizeof(buffer1),0,
+			     (struct sockaddr *)&to,sizeof(to));
+		if(ret < sizeof(buffer4)){
+			printf("Gak4, error:%d ret:%d\n",errno,ret);
+		}
+
+		/*  now wait until we get a assoc failing */
+		notdone = 1;
+		while(notdone){
+			x = clear_fds(fd,fd1);
+			if(x){
+				notdone = 0;
+			}
+			sleep(1);
+		}
+	}
+}
+
+int
+main(int argc, char **argv)
+{
+	int i,fd,fd1;
+	char *addr=NULL;
+	uint16_t port=0;
+	int protocol_touse = IPPROTO_SCTP;
+	struct sctp_event_subscribe event = {0};
+
+	while((i= getopt(argc,argv,"p:h:")) != EOF){
+		switch(i){
+		case 'h':
+			addr = optarg;
+			break;
+		case 'p':
+			port = (uint16_t)strtol(optarg,NULL,0);
+			break;
+		};
+	}
+	memset(&to,0,sizeof(to));
+	if((addr == NULL) || (port == 0)){
+		printf("Usage: %s -h addr -p port\n", argv[0]);
+		return(-1);
+	}
+	if(inet_pton(AF_INET, addr, (void *) &to.sin_addr)){
+		//to.sin_len = sizeof(to);
+		to.sin_family = AF_INET;
+		printf("port selected is %d\n",port);
+		printf("addr %x\n",(u_int)ntohl(to.sin_addr.s_addr));
+		to.sin_port = htons(port);
+	}else{
+		printf("Can't translate the address\n");
+		return(-1);
+	}
+	/**********************socket 1 *******************/
+      	fd = socket(AF_INET, SOCK_SEQPACKET, protocol_touse);
+	if(fd == -1){
+		printf("can't open socket:%d\n",errno);
+		return(-1);
+	}
+	memset(&bindto,0,sizeof(bindto));
+	//len = bindto.sin_len = sizeof(bindto);
+	len = sizeof(bindto);
+	bindto.sin_family = AF_INET;
+	bindto.sin_port = 0;
+	if(bind(fd,(struct sockaddr *)&bindto, len) < 0){
+		printf("can't bind a socket:%d\n",errno);
+		close(fd);
+		return(-1);
+	}
+	if(getsockname(fd,(struct sockaddr *)&got,&len) < 0){
+		printf("get sockname failed err:%d\n",errno);
+		close(fd);
+		return(-1);
+	}	
+	printf("fd uses port %d\n",ntohs(got.sin_port));
+
+	/**********************socket 2 *******************/
+      	fd1 = socket(AF_INET, SOCK_SEQPACKET, protocol_touse);
+	if(fd1 == -1){
+		printf("can't open socket:%d\n",errno);
+		close(fd);
+		return(-1);
+	}
+	memset(&bindto,0,sizeof(bindto));
+	//len = bindto.sin_len = sizeof(bindto);
+	len = sizeof(bindto);
+	bindto.sin_family = AF_INET;
+	bindto.sin_port = 0;
+	if(bind(fd1,(struct sockaddr *)&bindto, len) < 0){
+		printf("can't bind a socket:%d\n",errno);
+		close(fd);
+		close(fd1);
+		return(-1);
+	}
+	if(getsockname(fd1,(struct sockaddr *)&got,&len) < 0){
+		printf("get sockname failed err:%d\n",errno);
+		close(fd);
+		close(fd1);
+		return(-1);
+	}	
+	printf("fd1 uses port %d\n",ntohs(got.sin_port));
+
+	/* enable all event notifications */
+	event.sctp_data_io_event = 1;
+	event.sctp_association_event = 1;
+	event.sctp_address_event = 1;
+	event.sctp_send_failure_event = 1;
+	event.sctp_peer_error_event = 1;
+	event.sctp_shutdown_event = 1;
+	event.sctp_partial_delivery_event = 1;
+	event.sctp_adaptation_layer_event = 1;
+	if (setsockopt(fd, IPPROTO_SCTP, 
+		       SCTP_EVENTS, &event, 
+		       sizeof(event)) != 0) {
+		printf("Gak, can't set events errno:%d\n",errno);
+		exit(0);
+	}
+	if (setsockopt(fd1, IPPROTO_SCTP, 
+		       SCTP_EVENTS, &event, 
+		       sizeof(event)) != 0) {
+		printf("Gak, can't set events errno:%d\n",errno);
+		exit(0);
+	}
+
+	if(connect(fd,(struct sockaddr *)&to,len) == -1){
+		printf("Sorry connect fails %d\n",errno);
+		close(fd);
+		return(-1);
+	}
+	if(connect(fd1,(struct sockaddr *)&to,len) == -1){
+		printf("Sorry connect fails %d\n",errno);
+		close(fd);
+		return(-1);
+	}
+	printf("Connected\n");
+	clear_fds(fd,fd1);
+	process_out_data(fd,fd1);
+
+	return(0);
+}
+
diff --git a/src/apps/peel_server.c b/src/apps/peel_server.c
new file mode 100644
index 0000000..24a1ef8
--- /dev/null
+++ b/src/apps/peel_server.c
@@ -0,0 +1,667 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2003
+ * Copyright (c) 2003 Cisco
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * In addition:
+ *
+ * Copyright (c) 2003 Cisco
+ *
+ * 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.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ *    Randall Stewart   <rrs@cisco.com>
+ *    Sridhar Samudrala <sri@us.ibm.com>
+ */
+
+#include <ctype.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+
+#include <stdarg.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <arpa/inet.h>
+#include <time.h>
+#include <string.h>
+#include <errno.h>
+#include <poll.h>
+#include <sys/uio.h>
+#include <netdb.h>
+
+#include <netinet/sctp.h>
+#ifdef __NetBSD__
+#include <sys/inttypes.h>
+#endif
+
+#define SCTP_CRC32C_POLY 0x1EDC6F41
+#define SCTP_CRC32C(c,d) (c=(c>>8)^sctp_crc_c[(c^(d))&0xFF])
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/* Copyright 2001, D. Otis.  Use this program, code or tables    */
+/* extracted from it, as desired without restriction.            */
+/*                                                               */
+/* 32 Bit Reflected CRC table generation for SCTP.               */
+/* To accommodate serial byte data being shifted out least       */
+/* significant bit first, the table's 32 bit words are reflected */
+/* which flips both byte and bit MS and LS positions.  The CRC   */
+/* is calculated MS bits first from the perspective of the serial*/
+/* stream.  The x^32 term is implied and the x^0 term may also   */
+/* be shown as +1.  The polynomial code used is 0x1EDC6F41.      */
+/* Castagnoli93                                                  */
+/* x^32+x^28+x^27+x^26+x^25+x^23+x^22+x^20+x^19+x^18+x^14+x^13+  */
+/* x^11+x^10+x^9+x^8+x^6+x^0                                     */
+/* Guy Castagnoli Stefan Braeuer and Martin Herrman              */
+/* "Optimization of Cyclic Redundancy-Check Codes                */
+/* with 24 and 32 Parity Bits",                                  */
+/* IEEE Transactions on Communications, Vol.41, No.6, June 1993  */
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+static unsigned char buffer1[4100];
+static unsigned char buffer2[4100];
+static unsigned char buffer3[4100];
+static unsigned char buffer4[4100];
+static struct sockaddr_in bindto,got;
+static socklen_t len;
+
+unsigned long  sctp_crc_c[256] = {
+	0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,
+	0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
+	0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,
+	0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,
+	0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
+	0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,
+	0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L,
+	0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,
+	0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL,
+	0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
+	0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L,
+	0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,
+	0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L,
+	0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,
+	0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
+	0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,
+	0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L,
+	0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
+	0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L,
+	0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
+	0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L,
+	0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,
+	0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L,
+	0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,
+	0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
+	0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,
+	0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L,
+	0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,
+	0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L,
+	0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
+	0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L,
+	0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,
+	0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL,
+	0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,
+	0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
+	0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
+	0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L,
+	0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,
+	0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL,
+	0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
+	0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L,
+	0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,
+	0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL,
+	0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,
+	0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
+	0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,
+	0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L,
+	0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,
+	0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L,
+	0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
+	0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL,
+	0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,
+	0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL,
+	0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
+	0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
+	0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,
+	0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL,
+	0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,
+	0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L,
+	0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
+	0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L,
+	0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,
+	0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL,
+	0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L,
+};
+
+u_int32_t
+update_crc32(u_int32_t crc32,
+	     unsigned char *buffer,
+	     unsigned int length)
+{
+	int i;
+	for (i = 0; i < length; i++) {
+		SCTP_CRC32C(crc32, buffer[i]);
+	}
+	return (crc32);
+}
+
+u_int32_t
+sctp_csum_finalize(u_int32_t crc32)
+{
+	u_int32_t result;
+#if BYTE_ORDER == BIG_ENDIAN
+	u_int8_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;
+	result = ((byte0 << 24) |
+		  (byte1 << 16) |
+		  (byte2 << 8) |
+		  byte3);
+	crc32 = htonl(result);
+#else
+	/*
+	 * For INTEL platforms the result comes out in network order.
+	 * No htonl is required or the swap above. So we optimize out
+	 * both the htonl and the manual swap above.
+	 */
+	crc32 = result;
+#endif
+	return (crc32);
+}
+
+int
+check_buffers(void)
+{
+        /* Prepare buffers */
+	u_int32_t temp,*csum;
+	int ret=0;
+	temp = 0xffffffff;
+	temp = update_crc32(temp,buffer1,(sizeof(buffer1)-4));
+	temp = sctp_csum_finalize(temp);
+	csum = (u_int32_t *)(buffer1+(sizeof(buffer1)-4));
+	if(*csum != temp){
+		printf("Buffer1: Found csum:%x calculated:%x\n",
+		       *csum,temp);
+		ret++;
+	}
+	temp = 0xffffffff;
+	temp = update_crc32(temp,buffer2,(sizeof(buffer2)-4));
+	temp = sctp_csum_finalize(temp);
+	csum = (u_int32_t *)(buffer2+(sizeof(buffer2)-4));
+	if(*csum != temp){
+		printf("Buffer2: Found csum:%x calculated:%x\n",
+		       *csum,temp);
+		ret++;
+	}
+
+	temp = 0xffffffff;
+	temp = update_crc32(temp,buffer3,(sizeof(buffer3)-4));
+	temp = sctp_csum_finalize(temp);
+	csum = (u_int32_t *)(buffer3+(sizeof(buffer3)-4));
+	if(*csum != temp){
+		printf("Buffer3: Found csum:%x calculated:%x\n",
+		       *csum,temp);
+		ret++;
+	}
+
+	temp = 0xffffffff;
+	temp = update_crc32(temp,buffer4,(sizeof(buffer4)-4));
+	temp = sctp_csum_finalize(temp);
+	csum = (u_int32_t *)(buffer4+(sizeof(buffer4)-4));
+	if(*csum != temp){
+		printf("Buffer4: Found csum:%x calculated:%x\n",
+		       *csum,temp);
+		ret++;
+	}
+	return(ret);
+}
+
+static int
+my_handle_notification(int fd,char *notify_buf) {
+	union sctp_notification *snp;
+	struct sctp_assoc_change *sac;
+	struct sctp_paddr_change *spc;
+	struct sctp_remote_error *sre;
+	struct sctp_send_failed *ssf;
+	struct sctp_shutdown_event *sse;
+	int asocUp;
+	char *str;
+	char buf[256];
+	struct sockaddr_in *sin;
+	struct sockaddr_in6 *sin6;
+
+	snp = (union sctp_notification *)notify_buf;
+	asocUp = 0;
+	switch(snp->sn_header.sn_type) {
+	case SCTP_ASSOC_CHANGE:
+		sac = &snp->sn_assoc_change;
+		switch(sac->sac_state) {
+
+		case SCTP_COMM_UP:
+			str = "COMMUNICATION UP";
+			asocUp++;
+			break;
+		case SCTP_COMM_LOST:
+			str = "COMMUNICATION LOST";
+			break;
+		case SCTP_RESTART:
+		        str = "RESTART";
+			asocUp++;
+			break;
+		case SCTP_SHUTDOWN_COMP:
+			str = "SHUTDOWN COMPLETE";
+			break;
+		case SCTP_CANT_STR_ASSOC:
+			str = "CANT START ASSOC";
+			printf("EXIT:SCTP_ASSOC_CHANGE: %s, assoc=%xh\n", str,
+			       (uint32_t)sac->sac_assoc_id);
+			exit(0);
+			break;
+		default:
+			str = "UNKNOWN";
+		} /* end switch(sac->sac_state) */
+		printf("SCTP_ASSOC_CHANGE: %s, assoc=%xh\n", str,
+		       (uint32_t)sac->sac_assoc_id);
+		break;
+	case SCTP_PEER_ADDR_CHANGE:
+		spc = &snp->sn_paddr_change;
+		switch(spc->spc_state) {
+		case SCTP_ADDR_AVAILABLE:
+			str = "ADDRESS AVAILABLE";
+			break;
+		case SCTP_ADDR_UNREACHABLE:
+			str = "ADDRESS UNAVAILABLE";
+			break;
+		case SCTP_ADDR_REMOVED:
+			str = "ADDRESS REMOVED";
+			break;
+		case SCTP_ADDR_ADDED:
+			str = "ADDRESS ADDED";
+			break;
+		case SCTP_ADDR_MADE_PRIM:
+			str = "ADDRESS MADE PRIMARY";
+			break;
+		default:
+			str = "UNKNOWN";
+		} /* end switch */
+		sin6 = (struct sockaddr_in6 *)&spc->spc_aaddr;
+		if (sin6->sin6_family == AF_INET6) {
+			inet_ntop(AF_INET6, (char*)&sin6->sin6_addr, buf, sizeof(buf));
+		} else {
+			sin = (struct sockaddr_in *)&spc->spc_aaddr;
+			inet_ntop(AF_INET, (char*)&sin->sin_addr, buf, sizeof(buf));
+		}
+		printf("SCTP_PEER_ADDR_CHANGE: %s, addr=%s, assoc=%xh\n", str,
+		       buf, (uint32_t)spc->spc_assoc_id);
+		break;
+	case SCTP_REMOTE_ERROR:
+		sre = &snp->sn_remote_error;
+		printf("SCTP_REMOTE_ERROR: assoc=%xh\n",
+		       (uint32_t)sre->sre_assoc_id);
+		break;
+	case SCTP_SEND_FAILED:
+		ssf = &snp->sn_send_failed;
+		printf("SCTP_SEND_FAILED: assoc=%xh\n",
+		       (uint32_t)ssf->ssf_assoc_id);
+		break;
+	case SCTP_ADAPTATION_INDICATION:
+	  {
+	    struct sctp_adaptation_event *ae;
+	    ae = &snp->sn_adaptation_event;
+	    printf("\nSCTP_adaptation_indication bits:0x%x\n",
+		   (u_int)ae->sai_adaptation_ind);
+	  }
+	  break;
+	case SCTP_PARTIAL_DELIVERY_EVENT:
+	  {
+	    struct sctp_pdapi_event *pdapi;
+	    pdapi = &snp->sn_pdapi_event;
+	    printf("SCTP_PD-API event:%u\n",
+		   pdapi->pdapi_indication);
+	    if(pdapi->pdapi_indication == 0){
+		    printf("PDI- Aborted\n");
+	    }
+	  }
+	  break;
+
+	case SCTP_SHUTDOWN_EVENT:
+                sse = &snp->sn_shutdown_event;
+		printf("SCTP_SHUTDOWN_EVENT: assoc=%xh\n",
+		       (uint32_t)sse->sse_assoc_id);
+		break;
+	default:
+		printf("Unknown notification event type=%xh\n", 
+		       snp->sn_header.sn_type);
+	} /* end switch(snp->sn_type) */
+	return(asocUp);
+}
+
+
+static char readBuffer[65535];	
+static int sz=0;
+static char controlVector[65535];
+static struct msghdr msg;
+int
+my_sctpReadInput(int fd,int maxread)
+{
+	/* receive some number of datagrams and
+	 * act on them.
+	 */
+	struct iovec iov[2];
+	unsigned char from[200];
+
+	memset(&msg,0,sizeof(msg));
+	memset(controlVector,0,sizeof(controlVector));
+	memset(readBuffer,0,sizeof(readBuffer));
+
+	iov[0].iov_base = readBuffer;
+	iov[0].iov_len = maxread;
+	iov[1].iov_base = NULL;
+	iov[1].iov_len = 0;
+	msg.msg_name = (caddr_t)from;
+	msg.msg_namelen = sizeof(from);
+	msg.msg_iov = iov;
+	msg.msg_iovlen = 1;
+	msg.msg_control = (caddr_t)controlVector;
+	msg.msg_controllen = sizeof(controlVector);
+	errno = 0;
+	sz = recvmsg(fd,&msg,0);
+	printf("Read fd:%d returns %d errno:%d control len is %zu msgflg:%x\n",
+	       fd,
+	       sz,errno,
+	       msg.msg_controllen,
+	       msg.msg_flags);
+
+	if (msg.msg_flags & MSG_NOTIFICATION) {
+		printf("Got a notification\n");
+		return(my_handle_notification(fd,readBuffer));
+	}else{
+		printf("Got data\n");
+		return(-1);
+	}
+}
+
+
+int
+poll_fd(int fd)
+{
+	int cameup;
+	int max;
+	fd_set readfds,writefds,exceptfds;
+	struct timeval tv;
+
+	memset(&tv,0,sizeof(tv));
+	FD_ZERO(&readfds);
+	FD_ZERO(&writefds);
+	FD_ZERO(&exceptfds);
+	cameup = 0;
+	max = fd + 1;
+
+	printf("poll_fd\n");
+	FD_SET(fd,&readfds);
+
+	if (select(max, &readfds, &writefds, &exceptfds, NULL) == -1)
+		return(cameup);
+	if(FD_ISSET(fd,&readfds)){
+		printf("Read please\n");
+		cameup += my_sctpReadInput(fd,4100);
+	}
+
+	return(cameup);
+}
+
+static sctp_assoc_t
+dig_out_asocid(void)
+{
+	struct sctp_sndrcvinfo *s_info;
+	struct cmsghdr *cmsg;
+	s_info = NULL;
+	if(msg.msg_controllen){
+		/* parse through and see if we find
+		 * the sctp_sndrcvinfo
+		 */
+		cmsg = (struct cmsghdr *)controlVector;
+		while(cmsg){
+			if(cmsg->cmsg_level == IPPROTO_SCTP){
+				if(cmsg->cmsg_type == SCTP_SNDRCV){
+					/* Got it */
+					s_info = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+					break;
+				}
+			}
+			cmsg = CMSG_NXTHDR(&msg,cmsg);
+		}
+	}else{
+		printf("No CMSG?\n");
+		exit(0);
+	}
+	if(s_info == NULL){
+		printf("No sinfo?\n");
+		exit(0);
+	}
+	return(s_info->sinfo_assoc_id);
+}
+
+
+void
+process(int fd,int magic)
+{
+	int fd1,num_asoc,ret,i;
+	sctp_assoc_t asoc;
+	struct timespec ts;
+	num_asoc = 0;
+	i = 1;
+	ts.tv_sec = 0;
+	ts.tv_nsec = 10000;
+
+	while(i < 4099){
+		printf("pass %d\n",i);
+		while(num_asoc < 2){
+			ret = poll_fd(fd);
+			if(ret >0 ){
+				num_asoc += ret;
+			}else if(ret == 0){
+				sleep(1);
+			}else if(ret < 0){
+				printf("Got data? %d\n",sz);
+				sleep(1);
+			}
+			printf("asoc count is %d\n",num_asoc);
+		}
+	again:
+		printf("Reading for %d bytes from fd:%d\n",
+		       i,fd);
+		my_sctpReadInput(fd,i);
+		if(sz == i){
+			memcpy(buffer1,readBuffer,i);
+		}else{
+			printf("Huh I am messed up read %d wanted %d\n",
+			       sz,i);
+			goto again;
+		}
+		if(msg.msg_flags & MSG_EOR){
+			printf("Huh got EOR on paritial read?\n");
+			exit(0);
+		}
+		asoc = dig_out_asocid();
+		nanosleep(&ts,NULL);
+
+		fd1 = sctp_peeloff(fd,asoc);
+		if(fd1 == -1){
+			printf("peeloff failed %d/err:%d\n",
+			       fd1,errno);
+			exit(0);
+		}
+		my_sctpReadInput(fd1,(4100-i));
+		if(sz > 0){
+			memcpy(&buffer1[i],readBuffer,sz);
+			printf("Copied %d bytes\n",sz);
+		}else{
+			printf("Huh only read %d\n",sz);
+		}
+		if(magic >= i){
+			printf("magic engaged\n");
+			my_sctpReadInput(fd,i);
+		}else{
+			my_sctpReadInput(fd,4100);
+		}
+		if(sz > 0){
+			memcpy(buffer2,readBuffer,sz);
+			printf("copied %d bytes\n",sz);
+		}else{
+			printf("Huh only read %d\n",sz);
+		}
+		my_sctpReadInput(fd1,4100);
+		if(sz > 0){
+			memcpy(buffer3,readBuffer,sz);
+			printf("copied %d bytes\n",sz);
+		}else{
+			printf("Huh only read %d\n",sz);
+		}
+		my_sctpReadInput(fd,4100);
+		if(sz > 0){
+			memcpy(buffer4,readBuffer,sz);
+			printf("copied %d bytes\n",sz);
+		}else{
+			printf("Huh only read %d\n",sz);
+		}
+		if(check_buffers()){
+			exit(0);
+		}
+		close(fd1);
+		i++;
+		num_asoc--;
+	}
+}
+
+int
+main(int argc, char **argv)
+{
+	int i,fd;
+	uint16_t myport=0;
+	int magic=0;
+	struct sctp_event_subscribe event = {0};
+	while((i= getopt(argc,argv,"m:M:")) != EOF){
+		switch(i){
+		case 'm':
+			myport = (uint16_t)strtol(optarg,NULL,0);
+			break;
+		case 'M':
+			magic = strtol(optarg,NULL,0);
+			break;
+		};
+	}
+	/**********************socket 1 *******************/
+      	fd = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+	if(fd == -1){
+		printf("can't open socket:%d\n",errno);
+		return(-1);
+	}
+	memset(&bindto,0,sizeof(bindto));
+	//len = bindto.sin_len = sizeof(bindto);
+	len = sizeof(bindto);
+	bindto.sin_family = AF_INET;
+	printf("bind port %d\n",myport);
+	bindto.sin_port = htons(myport);
+	if(bind(fd,(struct sockaddr *)&bindto, len) < 0){
+		printf("can't bind a socket:%d\n",errno);
+		close(fd);
+		return(-1);
+	}
+	if(getsockname(fd,(struct sockaddr *)&got,&len) < 0){
+		printf("get sockname failed err:%d\n",errno);
+		close(fd);
+		return(-1);
+	}	
+	printf("fd uses port %d\n",ntohs(got.sin_port));
+	if (listen(fd, 100) == -1) {
+		printf("listen err: %d\n", errno);
+		close(fd);
+		return(-1);
+	}
+	/* enable all event notifications */
+	event.sctp_data_io_event = 1;
+	event.sctp_association_event = 1;
+	event.sctp_address_event = 1;
+	event.sctp_send_failure_event = 1;
+	event.sctp_peer_error_event = 1;
+	event.sctp_shutdown_event = 1;
+	event.sctp_partial_delivery_event = 1;
+	event.sctp_adaptation_layer_event = 1;
+	if (setsockopt(fd, IPPROTO_SCTP, 
+		       SCTP_EVENTS, &event, 
+		       sizeof(event)) != 0) {
+		printf("Gak, can't set events errno:%d\n",errno);
+		exit(0);
+	}
+	printf("to process\n");
+	process(fd,magic);
+	return(0);
+}
+
diff --git a/src/apps/sctp_darn.c b/src/apps/sctp_darn.c
new file mode 100644
index 0000000..bcfb822
--- /dev/null
+++ b/src/apps/sctp_darn.c
@@ -0,0 +1,2414 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2001, 2003
+ * Copyright (c) 1999 Cisco
+ * Copyright (c) 1999, 2000, 2001 Motorola
+ * Copyright (c) 2001 Nokia
+ * Copyright (c) 2001 La Monte H.P. Yarroll
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ *    La Monte H.P. Yarroll <piggy@acm.org>
+ *    Karl Knutson <karl@athena.chicago.il.us>
+ *    Hui Huang <hui.huang@nokia.com>
+ *    Daisy Chang <daisyc@us.ibm.com>
+ *    Sridhar Samudrala <sri@us.ibm.com>
+ */
+
+/* This is a userspace test application for the SCTP kernel 
+ * implementation state machine.  It is vaguely inspired by Stevens'
+ * program "sock".
+ *
+ * It has the limited ability to send messages and to listen for messages
+ * sent via SCTP.
+ */
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <stdlib.h>
+//#define _GNU_SOURCE
+#include <getopt.h>
+#include <netdb.h>
+#include <inttypes.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <sys/param.h>
+#include <sys/poll.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <net/if.h>
+#include <netinet/sctp.h>
+#include <unistd.h>
+#include <string.h>
+#include <signal.h>
+#include "sctp_darn.h"
+
+char *TCID = __FILE__;
+int TST_TOTAL = 1;
+int TST_CNT = 0;
+
+#define GEN_DATA_FIRST	0x21
+#define GEN_DATA_LAST	0x7e
+
+/* Display an IPv4 address in readable format.  */
+#define NIPQUAD(addr) \
+        ((unsigned char *)&addr)[0], \
+        ((unsigned char *)&addr)[1], \
+        ((unsigned char *)&addr)[2], \
+        ((unsigned char *)&addr)[3]
+
+/* Display an IPv6 address in readable format.  */
+#define NIP6(addr) \
+        ntohs((addr).s6_addr16[0]), \
+        ntohs((addr).s6_addr16[1]), \
+        ntohs((addr).s6_addr16[2]), \
+        ntohs((addr).s6_addr16[3]), \
+        ntohs((addr).s6_addr16[4]), \
+        ntohs((addr).s6_addr16[5]), \
+        ntohs((addr).s6_addr16[6]), \
+        ntohs((addr).s6_addr16[7])
+
+/* These are the global options.  */
+char *local_host = NULL;
+int local_port = 0;
+char *remote_host = NULL;
+int remote_port = 0;
+command_t command = COMMAND_NONE;
+struct sockaddr *bindx_add_addrs = NULL;
+int bindx_add_count = 0;
+struct sockaddr *bindx_rem_addrs = NULL;
+int bindx_rem_count = 0;
+struct sockaddr *connectx_addrs = NULL;
+int connectx_count = 0;
+int interactive_mode = 0;
+int poll_skn = 0;
+int nonblocking = 0;
+int opt_space = 0;
+char gen_data = GEN_DATA_FIRST;
+char *inter_outbuf = NULL;
+int inter_outlen = 0;
+int inter_sk = 0;
+int poll_snd_size = 0;
+int use_poll = 0;
+int socket_type = SOCK_SEQPACKET;
+sctp_assoc_t associd = 0;
+int echo = 0;
+char *interface = "eth0";
+int if_index = 0;
+sockaddr_storage_t remote_addr;
+sa_family_t ra_family;	/* What family is remote_addr? */
+int ra_len = 0;		/* How long is remote_addr? */
+void *ra_raw;		/* This is the addr part of remote_addr. */
+int new_connection = 1;
+
+enum inter_cmd_num {
+	INTER_SND = 0,
+	INTER_RCV,
+	INTER_SNDBUF,
+	INTER_RCVBUF,
+	INTER_BINDX_ADD,
+	INTER_BINDX_REM,
+	INTER_SET_PRIM,
+	INTER_SET_PEER_PRIM,
+	INTER_SHUTDOWN,
+	INTER_ABORT,
+	INTER_NODELAY,
+	INTER_MAXSEG,
+	INTER_HEARTBEAT,
+	INTER_GET_STATS
+};
+
+enum shutdown_type {
+	SHUTDOWN_ABORT = 0,
+	SHUTDOWN_SHUTDOWN
+};
+
+struct inter_entry {
+	char *cmd;
+	int cmd_num;
+};
+
+struct inter_entry inter_commands[] = {
+	{"snd", INTER_SND},
+	{"rcv",	INTER_RCV},
+	{"sndbuf", INTER_SNDBUF},
+	{"rcvbuf", INTER_RCVBUF},
+	{"bindx-add", INTER_BINDX_ADD},
+	{"bindx-rem", INTER_BINDX_REM},
+	{"primary", INTER_SET_PRIM},
+	{"peer_primary", INTER_SET_PEER_PRIM},
+	{"shutdown", INTER_SHUTDOWN},
+	{"abort", INTER_ABORT},
+	{"nodelay", INTER_NODELAY},
+	{"maxseg", INTER_MAXSEG},
+	{"heartbeat", INTER_HEARTBEAT},
+	{"stats", INTER_GET_STATS},
+	{NULL, -1},
+};
+
+#define POLL_SK_MAX 	256	/* The max number of sockets to select/poll. */
+int poll_sks[POLL_SK_MAX];		/* The array for using select(). */
+struct pollfd poll_fds[POLL_SK_MAX];	/* The array for using poll().  */
+#define POLL_SND_SIZE	16384	/* Default message size in the poll mode. */
+
+
+struct sockaddr *append_addr(const char *parm, struct sockaddr *addrs,
+			     int *ret_count) ;
+int build_endpoint(char *argv0, int portnum);
+static int parse_inter_commands(char *, char *, int);
+static void snd_func(char *);
+static void sndbuf_func(char *, int, int, int);
+static void rcvbuf_func(char *, int, int, int);
+static struct sockaddr *get_bindx_addr(char *, int *);
+static int bindx_func(char *, int, struct sockaddr *, int, int, int);
+static int connectx_func(char *, int, struct sockaddr *, int);
+static void  primary_func(char *, int, char *, int);
+static void  peer_primary_func(char *, int, char *, int);
+static void  spp_hb_demand_func(char *, int, char *, int);
+static int nodelay_func(char *, int, int val, int set);
+static int maxseg_func(char *, int, int val, int set);
+static int shutdown_func(char *argv0, int *skp, int shutdown_type);
+static int get_assocstats_func(int, sctp_assoc_t);
+static int test_sk_for_assoc(int sk, sctp_assoc_t assoc_id);
+static char * gen_message(int);
+static sctp_assoc_t test_recv_assoc_change(int);
+static sctp_assoc_t test_verify_assoc_change(struct msghdr *);
+void print_addr_buf(void * laddrs, int n_laddrs);
+int print_sockaddr(struct sockaddr *sa_addr);
+
+int
+main(int argc, char *argv[]) {
+	int sk = -1;
+	int error = 0;
+	int i;
+
+	signal(SIGPIPE, SIG_IGN);
+
+	parse_arguments(argc, argv);
+
+	switch(command) {
+	case COMMAND_NONE:
+		fprintf(stderr, "%s: Please specify a command.\n",
+			argv[0]);
+		exit(1);
+		break;
+	case COMMAND_LISTEN:
+		sk = build_endpoint(argv[0], local_port);
+		error = command_listen(argv[0], sk);
+		break;
+	case COMMAND_SEND:
+		sk = build_endpoint(argv[0], local_port);
+		error = command_send(argv[0], &sk);
+		break;
+	case COMMAND_POLL:
+		if (use_poll) {
+			for (i = 0; i < poll_skn; i++) {
+				poll_fds[i].fd = build_endpoint(argv[0],
+					local_port + i);
+			}
+		} else {
+			for (i = 0; i < poll_skn; i++) {
+				poll_sks[i] = build_endpoint(argv[0],
+					local_port + i);
+			}
+		}
+		error = command_poll(argv[0]);
+		break;
+	default:
+		fprintf(stderr, "%s: illegal command %d\n",
+			argv[0], command);
+		exit(1);
+	}
+
+	/* Shut down the link.  */
+	if (COMMAND_POLL != command) {
+		close(sk);
+	} else {
+		/* Shutdown all links.  */
+		if (use_poll) {
+			for (i = 0; i < poll_skn; i++) {
+				close(poll_fds[i].fd);
+			}
+		} else {
+			for (i = 0; i < poll_skn; i++) {
+				close(poll_sks[i]);
+			}
+		}
+	}
+
+	exit(error);
+}
+
+/********************************************************************
+ * 2nd Level Abstractions
+ ********************************************************************/
+
+void
+parse_arguments(int argc, char *argv[]) {
+	int option_index = 0;
+	int c;
+	struct sockaddr *tmp_addrs = NULL;
+
+	static struct option long_options[] = {
+		{"local",	1, 0, 1},
+		{"local-port",	1, 0, 2},
+		{"remote",	1, 0, 3},
+		{"remote-port",	1, 0, 4},
+		{"listen",	0, 0, 10},
+		{"send",	0, 0, 11},
+		{"bindx-add",	1, 0, 15},
+		{"bindx-rem",	1, 0, 16},
+		{"use-poll",	0, 0, 20},
+		{"echo",        0, 0, 'e'},
+		{"interface",   optional_argument, 0, 5,},
+		{"connectx",    1, 0, 17},
+		{0,		0, 0, 0}
+	};
+
+	/* Parse the arguments.  */
+	while (1) {
+		c = getopt_long (argc, argv, "B:H:IP:b:h:i:p:lm:nstz:ec:",
+				 long_options, &option_index);
+		if (c == -1)
+			break;
+
+		switch (c) {
+		case 0:
+			printf("option %s", long_options[option_index].name);
+			if (optarg) {
+				printf(" with arg %s", optarg);
+			}
+			printf("\n");
+			break;
+		case 1:		/* local host */
+		case 'H':
+			local_host = optarg;
+			break;
+		case 2:		/* local port */
+		case 'P':
+			local_port = atoi(optarg);
+			break;
+		case 3:		/* remote host */
+		case 'h':
+			remote_host = optarg;
+			break;
+		case 4:		/* remote port */
+		case 'p':
+			remote_port = atoi(optarg);
+			break;
+		case 5:  /* interface for sin6_scope_id */
+			if (optarg)
+				interface = optarg;
+			if_index = if_nametoindex(interface);
+			if (!if_index) {
+				printf("Interface %s unknown\n", interface);
+				exit(1);
+			}
+			break;
+			/* COMMANDS */
+		case 10:	/* listen */
+		case 'l':
+			if (command) {
+				fprintf(stderr,
+					"%s: pick ONE of listen or send\n",
+					argv[0]);
+				exit(1);
+			} else {
+				command = COMMAND_LISTEN;
+			}
+			break;
+
+		case 11:	/* send */
+		case 's':
+			if (command) {
+				fprintf(stderr,
+					"%s: pick ONE of listen or send\n",
+					argv[0]);
+				exit(1);
+			} else {
+				command = COMMAND_SEND;
+			}
+			break;
+
+		case 15:		/* bindx_add */
+		case 'B':
+			tmp_addrs =
+				append_addr(optarg, bindx_add_addrs,
+					    &bindx_add_count);
+			if (NULL == tmp_addrs) {
+				/* We have no memory, so keep fprintf()
+				 * from trying to allocate more.
+				 */
+				fprintf(stderr, "No memory to add ");
+				fprintf(stderr, "%s\n", optarg);
+				exit(2);
+			}
+			bindx_add_addrs = tmp_addrs;
+
+			break;
+
+		case 16:		/* bindx_rem */
+		case 'b':
+			tmp_addrs =
+				append_addr(optarg, bindx_rem_addrs,
+					    &bindx_rem_count);
+			if (NULL == tmp_addrs) {
+				/* We have no memory, so keep fprintf()
+				 * from trying to allocate more.
+				 */
+				fprintf(stderr, "No memory to add ");
+				fprintf(stderr, "%s\n", optarg);
+				exit(2);
+			}
+			bindx_rem_addrs = tmp_addrs;
+			break;
+		case 17:		/* connectx */
+		case 'c':
+			tmp_addrs =
+				append_addr(optarg, connectx_addrs,
+					    &connectx_count);
+			if (NULL == tmp_addrs) {
+				/* We have no memory, so keep fprintf()
+				 * from trying to allocate more.
+				 */
+				fprintf(stderr, "No memory to add ");
+				fprintf(stderr, "%s\n", optarg);
+				exit(2);
+			}
+			connectx_addrs = tmp_addrs;
+			break;
+		case 20:		/* use-poll */
+			use_poll = 1;
+			break;
+		case 'I':
+			interactive_mode = 1;
+			break;
+		case 'i':
+			command = COMMAND_POLL;
+			poll_skn = atoi(optarg);
+			if (poll_skn <= 0 || poll_skn > POLL_SK_MAX) {
+				fprintf(stderr, "Too many sockets for ");
+				fprintf(stderr, "for polling\n");
+				exit(2);
+			}
+			break;
+		case 'm':
+			opt_space = atoi(optarg);
+			break;
+		case 'n':
+			nonblocking = 1;
+			break;
+		case 't':
+			socket_type = SOCK_STREAM;
+			break;
+		case 'z':
+			poll_snd_size = atoi(optarg);
+			if (poll_snd_size <= 0) {
+				fprintf(stderr, "Bad message size.\n");
+				exit(2);
+			}
+			break;
+		case 'e':
+			echo = 1;
+			break;
+		case '?':
+			usage(argv[0]);
+			exit(1);
+
+		default:
+			printf ("%s: unrecognized option 0%c\n",
+				argv[0], c);
+			usage(argv[0]);
+			exit(1);
+		}
+	}
+
+	if (optind < argc)
+	{
+		fprintf(stderr, "%s: non-option arguments are illegal: ",
+			argv[0]);
+		while (optind < argc)
+			fprintf(stderr, "%s ", argv[optind++]);
+		fprintf (stderr, "\n");
+		usage(argv[0]);
+		exit(1);
+	}
+
+
+	if (NULL == local_host) {
+		fprintf(stderr, "%s: You MUST provide a local host.\n",
+			argv[0]);
+		usage(argv[0]);
+		exit(1);
+	}
+
+	if (command == COMMAND_SEND && NULL == remote_host
+	    && connectx_count == 0) {
+		fprintf(stderr, "%s: You MUST provide a remote host for sending.\n",
+			argv[0]);
+		usage(argv[0]);
+		exit(1);
+	}
+
+	if (remote_host != NULL && connectx_count != 0) {
+		fprintf(stderr, "%s: You can not provide both -h and -c options.\n",
+			argv[0]);
+		usage(argv[0]);
+		exit(1);
+	}
+} /* parse_arguments() */
+
+/* Set up the local endpoint.  */
+int
+build_endpoint(char *argv0, int portnum)
+{
+	int retval;
+	struct hostent *hst;
+	sockaddr_storage_t local_addr;
+	sa_family_t la_family;	/* What family is local_addr? */
+	int la_len;		/* How long is local_addr? */
+	void *la_raw;		/* This is the addr part of local_addr. */
+	int error;
+	struct sctp_event_subscribe subscribe;
+
+	/* Get the transport address for the local host name.  */
+	hst = gethostbyname(local_host);
+	if (hst == NULL) {
+		hst = gethostbyname2(local_host, AF_INET6);
+	}
+
+	if (hst == NULL || hst->h_length < 1) {
+		fprintf(stderr, "%s: bad hostname: %s\n", argv0, local_host);
+		exit(1);
+	}
+
+	la_family = hst->h_addrtype;
+	switch (la_family) {
+	case AF_INET:
+		la_len = sizeof(local_addr.v4);
+		la_raw = &local_addr.v4.sin_addr;
+		local_addr.v4.sin_port = htons(portnum);
+		local_addr.v4.sin_family = AF_INET;
+		break;
+	case AF_INET6:
+		la_len = sizeof(local_addr.v6);
+		la_raw = &local_addr.v6.sin6_addr;
+		local_addr.v6.sin6_port = htons(portnum);
+		local_addr.v6.sin6_family = AF_INET6;
+		local_addr.v6.sin6_scope_id = if_index;
+		break;
+	default:
+		fprintf(stderr, "Invalid address type.\n");
+		exit(1);
+		break;
+	}
+	memcpy(la_raw, hst->h_addr_list[0], hst->h_length);
+
+	/* Create the local endpoint.  */
+	retval = socket(la_family, socket_type, IPPROTO_SCTP);
+	if (retval < 0) {
+		fprintf(stderr, "%s: failed to create socket:  %s.\n",
+			argv0, strerror(errno));
+		exit(1);
+	}
+
+	if (SOCK_SEQPACKET == socket_type) {
+		memset(&subscribe, 0, sizeof(subscribe));
+		subscribe.sctp_data_io_event = 1;
+		subscribe.sctp_association_event = 1;
+		error = setsockopt(retval, SOL_SCTP, SCTP_EVENTS,
+				   (char *)&subscribe, sizeof(subscribe));
+		if (error) {
+			fprintf(stderr, "SCTP_EVENTS: error: %d\n", error);
+			exit(1);
+		}
+	}
+
+	/* Bind this socket to the test port.  */
+	error = bind(retval, &local_addr.sa, la_len);
+	if (error != 0) {
+		fprintf(stderr, "%s: can not bind to %s:%d: %s.\n",
+			argv0, local_host, portnum,
+			strerror(errno));
+		exit(1);
+	}
+
+	/* Do we need to do bindx() to add any additional addresses? */
+	if (bindx_add_addrs) {
+		if (0 != bindx_func(argv0, retval, bindx_add_addrs,
+			bindx_add_count, SCTP_BINDX_ADD_ADDR, portnum)) {
+			fprintf(stderr, "bindx_func (add) failed.\n");
+			exit(1);
+		}
+	} /* if (bindx_add_addrs) */
+
+	/* Do we need to do bindx() to remove any bound addresses? */
+	if (bindx_rem_addrs) {
+		if (0 != bindx_func(argv0, retval, bindx_rem_addrs,
+			bindx_rem_count, SCTP_BINDX_REM_ADDR, portnum)) {
+			fprintf(stderr, "bindx_func (remove) failed.\n");
+			exit(1);
+		}
+	} /* if (bindx_rem_addrs) */
+
+	/* Do we want to run in the non-blocking mode? */
+	if (nonblocking) {
+		error = fcntl(retval, F_SETFL, O_NONBLOCK);
+		if (error != 0) {
+			fprintf(stderr, "%s: error fcntl: %s.\n",
+				argv0, strerror(errno));
+			exit(1);
+		}
+	}
+
+	if (opt_space) {
+		sndbuf_func(argv0, retval, opt_space, 1);
+		rcvbuf_func(argv0, retval, opt_space, 1);
+	}
+
+	return retval;
+
+} /* build_endpoint() */
+
+/* Convenience structure to determine space needed for cmsg. */
+typedef union {
+	struct sctp_initmsg init;
+	struct sctp_sndrcvinfo sndrcvinfo;
+} _sctp_cmsg_data_t;
+
+
+/* Listen on the socket, printing out anything that arrives.  */
+int
+command_listen(char *argv0, int sk)
+{
+	char incmsg[CMSG_SPACE(sizeof(_sctp_cmsg_data_t))];
+	struct iovec iov;
+	struct msghdr inmessage;
+	sockaddr_storage_t msgname;
+	char message[REALLY_BIG];
+	int done = 0;
+	int error;
+	int c;
+	int recvsk = 0;
+
+ 	/* Mark sk as being able to accept new associations */
+	error = listen(sk, 5);
+	if (error != 0) {
+		printf("\n\n\t\tlisten Failure:  %s.\n\n\n",
+		       strerror(errno));
+		exit(1);
+	}
+
+	if (nonblocking) {
+		if (!interactive_mode) {
+			printf("Use -I for interactive mode with");
+		       printf("	-n nonblocking\n");
+		       exit(1);
+		 }
+	}
+
+	/* Initialize the global value for interactive mode functions.  */
+	if (interactive_mode) {
+		inter_sk = sk;
+	}
+
+	/* Initialize inmessage with enough space for DATA... */
+	memset(&inmessage, 0, sizeof(inmessage));
+	if ((iov.iov_base = malloc(REALLY_BIG)) == NULL) {
+		printf("%s: Can't allocate memory.\n", argv0);
+		exit(1);
+	}
+	iov.iov_len = REALLY_BIG;
+	inmessage.msg_iov = &iov;
+	inmessage.msg_iovlen = 1;
+	/* or a control message.  */
+	inmessage.msg_control = incmsg;
+	inmessage.msg_controllen = sizeof(incmsg);
+	inmessage.msg_name = &msgname;
+	inmessage.msg_namelen = sizeof(msgname);
+
+	printf("%s listening...\n", argv0);
+	/* Get the messages sent */
+	done = 0;
+	while (!done) {
+		if (interactive_mode) {
+			/* Read from the user.  */
+			if (remote_host) {
+				printf("%s:%d-%s:%d Interactive mode> ",
+					local_host, local_port, remote_host,
+					remote_port);
+			} else {
+				printf("%s:%d-", local_host, local_port);
+				if (associd) {
+					print_sockaddr(&remote_addr.sa);
+				} else {
+					printf("?:%d", remote_port);
+				}
+				printf(" Interactive mode> ");
+			}
+			fflush(stdout);
+			if (NULL == fgets(message, REALLY_BIG, stdin)) {
+				done = 1;
+				continue;
+			}
+
+			if (0 <= (c = parse_inter_commands(argv0, message,
+				0))) {
+				if (INTER_RCV != c) {
+					continue;
+				}
+			} else {
+				continue;
+			}
+		}
+
+		if (socket_type == SOCK_STREAM) {
+			socklen_t len = 0;
+
+			if (!recvsk) {
+				if ((recvsk = accept(sk, NULL, &len)) < 0) {
+					fprintf(stderr, "%s: error: %s.\n",
+						argv0, strerror(errno));
+					exit(1);
+				}
+			}
+
+		} else {
+			recvsk = sk;
+		}
+
+		error = recvmsg(recvsk, &inmessage, MSG_WAITALL);
+		if (error < 0) {
+			if (nonblocking && (EAGAIN == errno)) {
+				error = 0;
+				continue;
+			}
+
+			if (socket_type == SOCK_STREAM) {
+				if (ENOTCONN != errno)
+					break;
+				printf("No association is present now!!\n");
+				close(recvsk);
+				recvsk = 0;
+				continue;
+			}
+			break;
+		}
+
+		/* Update the associd when a notification is received on a
+		 * UDP-style socket.
+		 */
+		if (inmessage.msg_flags & MSG_NOTIFICATION)
+			associd = test_verify_assoc_change(&inmessage);
+
+		if (echo) {
+			if( !(MSG_NOTIFICATION & inmessage.msg_flags)) {
+				if (sendto(recvsk, inmessage.msg_iov->iov_base,
+					   error, 0,
+					   (struct sockaddr *)&msgname,
+					   sizeof(msgname)) == -1) {
+					fprintf(stderr, "%s: error: %s.\n",
+						argv0, strerror(errno));
+					exit(1);
+				}
+			}
+		}
+
+		test_print_message(sk, &inmessage, error);
+
+		inmessage.msg_control = incmsg;
+		inmessage.msg_controllen = sizeof(incmsg);
+		inmessage.msg_name = &msgname;
+		inmessage.msg_namelen = sizeof(msgname);
+		iov.iov_len = REALLY_BIG;
+
+		/* Verify that the association is no longer present.  */
+		if (0 != test_sk_for_assoc(recvsk, associd)) {
+			printf("No association is present now!!\n");
+			if (socket_type == SOCK_STREAM) {
+				close(recvsk);
+				recvsk = 0;
+			}
+		}
+	}
+
+	if (error < 0) {
+		fprintf(stderr, "%s: error: %s.\n",
+			argv0, strerror(errno));
+		exit(1);
+	}
+
+	return error;
+
+} /* command_listen() */
+
+/* Read lines from stdin and send them to the socket.  */
+int
+command_send(char *argv0, int *skp)
+{
+	struct msghdr outmsg;
+	struct iovec iov;
+	int done = 0;
+	char message[REALLY_BIG];
+	struct hostent *hst;
+	int c;
+	struct sockaddr *addrs;
+	int msglen;
+	int error = 0;
+	int sk = *skp;
+
+	/* Set up the destination.  */
+	if (remote_host != NULL) {
+		hst = gethostbyname(remote_host);
+		if (hst == NULL) {
+			hst = gethostbyname2(remote_host, AF_INET6);
+		}
+
+		if (hst == NULL || hst->h_length < 1) {
+			fprintf(stderr, "%s: bad hostname: %s\n",
+				argv0, remote_host);
+			exit(1);
+		}
+
+		ra_family = hst->h_addrtype;
+		switch (ra_family) {
+		case AF_INET:
+			ra_len = sizeof(remote_addr.v4);
+			ra_raw = &remote_addr.v4.sin_addr;
+			remote_addr.v4.sin_port = htons(remote_port);
+			remote_addr.v4.sin_family = AF_INET;
+			break;
+		case AF_INET6:
+			ra_len = sizeof(remote_addr.v6);
+			ra_raw = &remote_addr.v6.sin6_addr;
+			remote_addr.v6.sin6_port = htons(remote_port);
+			remote_addr.v6.sin6_family = AF_INET6;
+			remote_addr.v6.sin6_scope_id = if_index;
+			break;
+		default:
+			fprintf(stderr, "Invalid address type.\n");
+			exit(1);
+			break;
+		}
+		memcpy(ra_raw, hst->h_addr_list[0], hst->h_length);
+	}
+
+	/* Initialize the global value for interactive mode functions.  */
+	if (interactive_mode) {
+		inter_sk = sk;
+	}
+
+	printf("%s ready to send...\n", argv0);
+	while (!done) {
+		/* Read from the user.  */
+		if (remote_host) {
+			if (interactive_mode) {
+				printf("%s:%d-%s:%d Interactive mode> ",
+					local_host, local_port, remote_host,
+					remote_port);
+			} else {
+				printf("%s:%d-%s:%d> ",
+				       local_host, local_port,
+				       remote_host, remote_port);
+			}
+		} else {
+			printf("%s:%d-", local_host, local_port);
+			if (associd) {
+				print_sockaddr(&remote_addr.sa);
+			} else {
+				printf("XXXXXX:%d", remote_port);
+			}
+			if (interactive_mode) {
+				printf(" Interactive mode> ");
+			} else {
+				printf("> ");
+			}
+		}
+		fflush(stdout);
+		if (NULL == fgets(message, REALLY_BIG, stdin)) {
+			done = 1;
+			continue;
+		}
+
+		if (interactive_mode) {
+			/* This is the send only agent.  */
+			if (0 <= (c = parse_inter_commands(argv0, message,
+				1))) {
+				if (INTER_SND == c) {
+					iov.iov_base = inter_outbuf;
+					msglen = inter_outlen;
+					iov.iov_len = msglen;
+
+				} else {
+					continue;
+				}
+
+			} else {
+				continue;
+			}
+		} else {
+			/* Send to our neighbor.  */
+			msglen = strlen(message) + 1;
+			iov.iov_len = msglen;
+		}
+
+		/* For a UDP-style socket, verify if an existing association
+		 * has gone. If so, receive the pending SCTP_ASSOC_CHANGE
+		 * notification.
+		 */
+		if ((SOCK_SEQPACKET == socket_type) && associd &&
+		    (0 != test_sk_for_assoc(sk, associd))) {
+			associd = test_recv_assoc_change(sk);
+			printf("Old association gone, Starting a new one!\n");
+			new_connection = 1;
+		}
+
+		if (new_connection && connectx_count != 0) {
+			/* Do a sctp_connectx() to establish a connection. */
+			error = connectx_func(argv0, sk, connectx_addrs,
+					      connectx_count);
+			if (0 != error) {
+				if (error == -2) {
+					printf("Connection refused\n");
+					if (SOCK_SEQPACKET == socket_type) {
+						associd = test_recv_assoc_change(sk);
+					}
+					continue;
+				}
+				fprintf(stderr, "connectx failed.\n");
+				exit(1);
+			}
+			if (SOCK_SEQPACKET == socket_type) {
+				associd = test_recv_assoc_change(sk);
+			} else {
+				associd = 1;
+			}
+			int rc = sctp_getpaddrs(sk, associd, &addrs);
+			if (0 >= rc) {
+				if (rc == 0) {
+					fprintf(stderr, "sctp_getpaddrs failed, no peers.\n");
+				} else {
+					fprintf(stderr, "sctp_getpaddrs failed %s(%d).\n", strerror(errno), errno);
+				}
+				exit(1);
+			}
+			printf("New connection, peer addresses\n");
+			print_addr_buf(addrs, rc);
+			ra_family = addrs[0].sa_family;
+			switch (ra_family) {
+			case AF_INET:
+				ra_len = sizeof(remote_addr.v4);
+				break;
+			case AF_INET6:
+				ra_len = sizeof(remote_addr.v6);
+				break;
+			default:
+				fprintf(stderr, "Invalid address type.\n");
+				exit(1);
+			}
+			memcpy(&remote_addr, &addrs[0], ra_len);
+			sctp_freepaddrs(addrs);
+			new_connection = 0;
+		}
+
+		do {
+			if (SOCK_SEQPACKET == socket_type ||
+			    (connectx_count == 0 && new_connection)) {
+				/* Initialize the message struct we use to pass
+				 * messages to the remote socket.
+				 */
+				if (!interactive_mode) {
+					iov.iov_base = message;
+					iov.iov_len = msglen;
+				}
+				outmsg.msg_iov = &iov;
+				outmsg.msg_iovlen = 1;
+				outmsg.msg_control = NULL;
+				outmsg.msg_controllen = 0;
+				outmsg.msg_name = &remote_addr;
+				outmsg.msg_namelen = ra_len;
+				outmsg.msg_flags = 0;
+
+				error = sendmsg(sk, &outmsg, 0);
+			} else {
+				error = send(sk, message, msglen, 0);
+				if (error == -1 && errno == EPIPE) {
+					error = close(sk);
+					if (error != 0) {
+						fprintf(stderr, "close failed %s\n", strerror(errno));
+						exit(1);
+					}
+					*skp = sk = build_endpoint(argv0, local_port);
+					break;
+				}
+			}
+
+			if (error != msglen) {
+				fprintf(stderr, "%s: error: %s.\n",
+					argv0, strerror(errno));
+				if (nonblocking && EAGAIN == errno) {
+					if (interactive_mode) {
+						break;
+					}
+					continue;
+				}
+				exit(1);
+			} else {
+				break;
+			}
+		} while (error != msglen);
+
+		/* If this is the first message sent over a UDP-style socket,
+		 * get the associd from the SCTP_ASSOC_CHANGE notification.
+		 */
+		if ((SOCK_SEQPACKET == socket_type) && (0 == associd))
+			associd = test_recv_assoc_change(sk);
+
+		/* Verify there is no association.  */
+		if (0 != test_sk_for_assoc(sk, associd)) {
+			printf("No association is present now!!\n");
+			new_connection = 1;
+		} else {
+			if (new_connection) {
+				int rc = sctp_getpaddrs(sk, associd, &addrs);
+				if (0 >= rc) {
+					if (rc == 0) {
+						fprintf(stderr, "sctp_getpaddrs failed, no peers.\n");
+					} else {
+						fprintf(stderr, "sctp_getpaddrs failed %s(%d).\n", strerror(errno), errno);
+					}
+					exit(1);
+				}
+				printf("New connection, peer addresses\n");
+				print_addr_buf(addrs, rc);
+				sctp_freepaddrs(addrs);
+				new_connection = 0;
+			}
+		}
+
+		/* Clean up.  */
+		if (interactive_mode) {
+			free(inter_outbuf);
+			inter_outbuf = NULL;
+		}
+	} /* while(!done) */
+
+	return error;
+
+} /* command_send() */
+
+/* Listen on the array of sockets, printing out anything that arrives.  */
+int
+command_poll(char *argv0)
+{
+	char incmsg[CMSG_SPACE(sizeof(_sctp_cmsg_data_t))];
+	struct iovec iov;
+	struct msghdr inmessage;
+	int done = 0;
+	int error = 0;
+	int max_fd, i, ret;
+	int size;
+	fd_set *ibitsp = NULL;
+	fd_set *obitsp = NULL;
+	fd_set *xbitsp = NULL;
+
+	struct msghdr outmsg;
+	struct hostent *hst;
+	int msglen;
+	int temp_fd, temp_set;
+
+
+
+	/* If a remote host is specified, initialize the destination. */
+	if (remote_host) {
+		/* Set up the destination.  */
+		hst = gethostbyname(remote_host);
+		if (hst == NULL) {
+			hst = gethostbyname2(remote_host, AF_INET6);
+		}
+
+		if (hst == NULL || hst->h_length < 1) {
+			fprintf(stderr, "%s: bad hostname: %s\n",
+				argv0, remote_host);
+			exit(1);
+		}
+
+		ra_family = hst->h_addrtype;
+		switch (ra_family) {
+		case AF_INET:
+			ra_len = sizeof(remote_addr.v4);
+			ra_raw = &remote_addr.v4.sin_addr;
+			remote_addr.v4.sin_port = htons(remote_port);
+			remote_addr.v4.sin_family = AF_INET;
+			break;
+		case AF_INET6:
+			ra_len = sizeof(remote_addr.v6);
+			ra_raw = &remote_addr.v6.sin6_addr;
+			remote_addr.v6.sin6_port = htons(remote_port);
+			remote_addr.v6.sin6_family = AF_INET6;
+			remote_addr.v6.sin6_scope_id = if_index;
+			break;
+		default:
+			fprintf(stderr, "Invalid address type.\n");
+			exit(1);
+			break;
+		}
+		memcpy(ra_raw, hst->h_addr_list[0], hst->h_length);
+
+		/* Initialize the message struct we use to pass messages to
+	 	 * the remote socket.
+	 	 */
+		outmsg.msg_iov = &iov;
+		outmsg.msg_iovlen = 1;
+		outmsg.msg_control = NULL;
+		outmsg.msg_controllen = 0;
+		outmsg.msg_name = &remote_addr;
+		outmsg.msg_namelen = ra_len;
+		outmsg.msg_flags = 0;
+	}
+
+
+	max_fd = -1;
+
+	/* Set all of the sockets to be ready for listening. */
+	if (use_poll) {
+		for (i = 0; i < poll_skn; i++) {
+			error = listen(poll_fds[i].fd, 1);
+			if (error != 0) {
+				printf("%s: Listen failed on socket number ",
+					argv0);
+				printf("%d: %s.\n", i, strerror(errno));
+				exit(1);
+			}
+		}
+		printf("%s listening...\n", argv0);
+	} else {
+		for (i = 0; i < poll_skn; i++) {
+			error = listen(poll_sks[i], 1);
+			if (error != 0) {
+				printf("%s: Listen failed on socket number ",
+					argv0);
+				printf("%d: %s.\n", i, strerror(errno));
+				exit(1);
+			}
+			if (poll_sks[i] > max_fd) {
+				max_fd = poll_sks[i];
+			}
+		}
+		printf("%s listening...\n", argv0);
+
+		size = howmany(max_fd + 1, NFDBITS) * sizeof(fd_mask);
+		if ((ibitsp = (fd_set *)malloc(size)) == NULL) {
+			printf("%s: Can't allocate memory.\n", argv0);
+			exit(1);
+		}
+		if ((obitsp = (fd_set *)malloc(size)) == NULL) {
+			printf("%s: Can't allocate memory.\n", argv0);
+			exit(1);
+		}
+		if ((xbitsp = (fd_set *)malloc(size)) == NULL) {
+			printf("%s: Can't allocate memory.\n", argv0);
+			exit(1);
+		}
+		memset(ibitsp, 0, size);
+		memset(obitsp, 0, size);
+		memset(xbitsp, 0, size);
+	}
+
+
+	/* Initialize inmessage with enough space for DATA... */
+	memset(&inmessage, 0, sizeof(inmessage));
+	if ((iov.iov_base = malloc(REALLY_BIG)) == NULL) {
+		printf("%s: Can't allocate memory.\n", argv0);
+		exit(1);
+	}
+	iov.iov_len = REALLY_BIG;
+	inmessage.msg_iov = &iov;
+	inmessage.msg_iovlen = 1;
+	/* or a control message.  */
+	inmessage.msg_control = incmsg;
+	inmessage.msg_controllen = sizeof(incmsg);
+
+
+	done = 0;
+	/* Set the default send message size.  */
+	if (!poll_snd_size) {
+		poll_snd_size = POLL_SND_SIZE;
+	}
+
+	while (!done) {
+
+		if (use_poll) {
+			for (i = 0; i < poll_skn; i++) {
+				poll_fds[i].events = POLLIN;
+			}
+			if (remote_host) {
+				/* Poll output on the first socket.  */
+				poll_fds[0].events |= POLLOUT;
+			}
+
+			if ((ret = poll(poll_fds, poll_skn, -1))) {
+				if (ret == -1) {
+					break;
+				}
+			}
+		} else {
+			for (i = 0; i < poll_skn; i++) {
+				FD_SET(poll_sks[i], ibitsp);
+				FD_SET(poll_sks[i], xbitsp);
+			}
+			if (remote_host) {
+				/* Only select output on the first socket.  */
+				FD_SET(poll_sks[0], obitsp);
+			}
+
+
+			if ((ret = select(max_fd + 1, ibitsp, obitsp, xbitsp,
+				(struct timeval *)0)) < 0) {
+				if (ret == -1) {
+					break;
+				}
+			}
+
+		}
+
+		if (remote_host) {
+			if (use_poll) {
+				temp_set = poll_fds[0].revents & POLLOUT;
+				temp_fd = poll_fds[0].fd;
+			} else {
+				temp_set = FD_ISSET(poll_sks[0], obitsp);
+				temp_fd = poll_sks[0];
+			}
+
+			if (temp_set) {
+				inter_outbuf = gen_message(poll_snd_size);
+				if (!inter_outbuf) {
+					fprintf(stderr,
+					"Cannot allocate out message.\n");
+					exit(1);
+				}
+				iov.iov_base = inter_outbuf;
+				msglen = poll_snd_size;
+				iov.iov_len = msglen;
+
+				error = sendmsg(temp_fd, &outmsg, 0);
+				fprintf(stderr,
+					"sent a message, msglen = %d\n",
+					msglen);
+
+				if (error != msglen) {
+					fprintf(stderr, "%s: error: %s.\n",
+						argv0, strerror(errno));
+					if ((!nonblocking) ||
+					    (EAGAIN != errno)) {
+						exit(1);
+					}
+				}
+
+				/* Clean up.  */
+				free(inter_outbuf);
+				inter_outbuf = NULL;
+			}
+
+		} /* while(!done) */
+
+		for (i = 0; !done && (i < poll_skn); i++) {
+			if (use_poll) {
+				temp_set = poll_fds[i].revents & POLLIN;
+				temp_fd = poll_fds[i].fd;
+			} else {
+				temp_set = FD_ISSET(poll_sks[i], ibitsp);
+				temp_fd = poll_sks[i];
+			}
+			if (temp_set) {
+				error = recvmsg(temp_fd, &inmessage,
+					MSG_WAITALL);
+				if (error < 0) {
+					if ((EAGAIN == errno)) {
+						error = 0;
+						continue;
+					}
+					else {
+						fprintf(stderr,
+							"%s: error: %s.\n",
+							argv0,
+							strerror(errno));
+						exit(1);
+					}
+				}
+				test_print_message(temp_fd, &inmessage, error);
+				inmessage.msg_control = incmsg;
+				inmessage.msg_controllen = sizeof(incmsg);
+				iov.iov_len = REALLY_BIG;
+			}
+
+			/* Update the associd when a notification is received
+			 * on a UDP-style socket.
+			 */
+			if (inmessage.msg_flags & MSG_NOTIFICATION)
+				associd = test_verify_assoc_change(&inmessage);
+
+			/* Verify there is no association. */
+			if (0 != test_sk_for_assoc(poll_sks[i], associd)) {
+				printf("No association is present in sk "
+				       "No.%d now!!\n",i);
+			}
+		}
+
+	}
+
+	if (!use_poll) {
+		free(ibitsp);
+		free(obitsp);
+		free(xbitsp);
+	}
+
+	return error;
+
+} /* command_poll() */
+
+/********************************************************************
+ * 3rd Level Abstractions
+ ********************************************************************/
+
+#define FPS(arg) fprintf(stderr, arg)
+
+void
+usage(char *argv0)
+{
+	/*
+	 * The bindx options, --bindx-add and --bindx-rem, are added to
+	 *
+	 * 1. provide first testcases for the new bindx system call
+	 *
+	 * 2. continue to grow sctp_darn with more functions and
+	 * features so it will be equivalent to the "sock" tool for
+	 * TCP as for SCTP.
+	 *
+	 * FIXME -
+	 *
+	 * It is not very effective to use these two options in the
+	 * current command line mode of sctp_darn. For example, the
+	 * --bindx-rem option can only be used in conjunction with the
+	 * --bindx-add simply to test the function in the kernel
+	 * path. Ideally, bindx needs to be tested by a tool which
+	 * provides an interactive mode for users to change parameters
+	 * and configuration dynamically with existing endpoints and
+	 * associations.
+	 */
+	fprintf(stderr, "Usage: %s -H <localhost> -P <localport> "
+		"[-h <remotehost>] [-p <remoteport>] -l|s\n"
+		" -H, --local\t\tspecify one of the local addresses,\n"
+		" -P, --local-port\tspecify the port number for local addresses,\n"
+		" -h, --remote\t\tspecify the peer address,\n"
+		" -p, --remote-port\tspecify the port number for the peer address,\n"
+		" -l, --listen\t\tprint messages received from the peer,\n"
+		" -s, --send\t\tsend messages to the peer,\n"
+		" -B, --bindx-add"
+		"\tadd the specified address(es) as additional bind\n"
+		"\t\t\taddresses to the local socket. Multiple addresses can\n"
+		"\t\t\tbe specified by using this argument multiple times.\n"
+		"\t\t\tFor example, '-B 10.0.0.1 -B 20.0.0.2'.\n"
+		" -b, --bindx-rem"
+		"\tremove the specified address(es) from the bind\n"
+		"\t\t\taddresses of the local socket. Multiple addresses can\n"
+		"\t\t\tbe specified by using this argument multiple times.\n"
+		"\t\t\tFor example, '-b 10.0.0.1 -b 20.0.0.2'.\n"
+		" -c, --connectx"
+		"\t\tuse the specified address(es) for connection to the\n"
+		"\t\t\tpeer socket. Multiple addresses can be specified by\n"
+		"\t\t\tusing this argument multiple times.\n"
+		"\t\t\tFor example, '-c 10.0.0.1 -c 20.0.0.2'.\n"
+		"\t\t\tThis option is incompatible with the -h option.\n"
+		" -I\t\t\tuse the interactive mode.\n"
+		" -i\t\t\tsetup the specified number of endpoints by using the\n"
+		"\t\t\tspecified local host (-H) and local port (-P). The port\n"
+        	"\t\t\tnumber will be incremented by one for each additional\n"
+        	"\t\t\tendpoint.  All of these endpoints will be listening.\n"
+		"\t\t\tIf a remote host (-h) and a remote port are also\n"
+		"\t\t\tspecified, the first endpoint will start sending fixed\n"
+		"\t\t\tsized messages to the remote host.\n"
+		" -m\t\t\tspecify the sockopt sndbuf/rcvbuf size.\n"
+		" -n\t\t\tset the socket(s) to be in the non-blocking mode.\n"
+		"\t\t\tcollect messages from stdin and deliver them to the\n"
+		"\t\t\tpeer,\n"
+		"--use-poll\t\tuse system call poll() for polling among the\n"
+		"\t\t\tnumber of endpoints specified by the -i option. Without\n"
+		"\t\t\tthis option, select() would be used as default.\n"
+		" -t\t\t\tuse SOCK_STREAM tcp-style sockets.\n"
+		" -z\t\t\tspecify the message size to be sent.  The default\n"
+		"\t\t\tmessage size generated would be 16K.\n"
+		" --interface=\"ifname\"\tselect interface for sin6_scope_id.\n",
+		argv0);
+}
+
+
+/* This function checks messages to see if they are of type 'event'
+ * and if they are well-formed.
+ */
+int
+user_test_check_message(struct msghdr *msg,
+                        int controllen,
+                        sctp_cmsg_t event)
+{
+
+
+	if (msg->msg_controllen != controllen) {
+		fprintf(stderr,
+			"Got control structure of length %zu, not %d\n",
+			msg->msg_controllen, controllen);
+		exit(1);
+	}
+	if (controllen > 0 && event != CMSG_FIRSTHDR(msg)->cmsg_type) {
+		fprintf(stderr, "Wrong kind of event: %d, not %d\n",
+			CMSG_FIRSTHDR(msg)->cmsg_type, event);
+		exit(1);
+	}
+
+	return 1;
+
+} /* user_test_check_message() */
+
+/* Add another address represented as the string 'parm' to the list
+ * addrs.  The argument count is the number of addrs on input and is
+ * adjusted for output.
+ */
+struct sockaddr *
+append_addr(const char *parm, struct sockaddr *addrs, int *ret_count)
+{
+	struct sockaddr *new_addrs = NULL;
+	void *aptr;
+	struct sockaddr *sa_addr;
+	struct sockaddr_in *b4ap;
+	struct sockaddr_in6 *b6ap;
+	struct hostent *hst4 = NULL;
+	struct hostent *hst6 = NULL;
+	int i4 = 0;
+	int i6 = 0;
+	int j;
+	int orig_count = *ret_count;
+	int count = orig_count;
+
+
+	if (!parm)
+		return NULL;
+	/* Get the entries for this host.  */
+	hst4 = gethostbyname(parm);
+	hst6 = gethostbyname2(parm, AF_INET6);
+
+	if ((NULL == hst4 || hst4->h_length < 1)
+	    && (NULL == hst6 || hst6->h_length < 1)) {
+		fprintf(stderr, "bad hostname: %s\n", parm);
+		goto finally;
+	}
+
+
+	/* Figure out the number of addresses.  */
+	if (NULL != hst4) {
+		for (i4 = 0; NULL != hst4->h_addr_list[i4]; ++i4) {
+			count++;
+		}
+	}
+	if (NULL != hst6) {
+		for (i6 = 0; NULL != hst6->h_addr_list[i6]; ++i6) {
+			count++;
+		}
+	}
+
+	/* Expand memory for the new addresses.  Assume all the addresses 
+	 * are v6 addresses.
+	 */
+	new_addrs = (struct sockaddr *)
+		realloc(addrs, sizeof(struct sockaddr_in6) * count);
+
+	if (NULL == new_addrs) {
+		count = *ret_count;
+		goto finally;
+	}
+
+	/* Skip the existing addresses. */
+	aptr = new_addrs; 
+	for (j = 0; j < orig_count; j++) {
+		sa_addr = (struct sockaddr *)aptr;
+		switch(sa_addr->sa_family) {
+		case AF_INET:
+			aptr += sizeof(struct sockaddr_in);
+			break;
+		case AF_INET6:
+			aptr += sizeof(struct sockaddr_in6);
+			break;
+		default:
+			count = orig_count;
+			goto finally;
+		}
+	}	
+					
+	/* Put the new addresses away.  */
+	if (NULL != hst4) {
+		for (j = 0; j < i4; ++j) {
+			b4ap = (struct sockaddr_in *)aptr;
+			memset(b4ap, 0x00, sizeof(*b4ap));
+			b4ap->sin_family = AF_INET;
+			b4ap->sin_port = htons(local_port);
+			bcopy(hst4->h_addr_list[j], &b4ap->sin_addr,
+			      hst4->h_length);
+
+			aptr += sizeof(struct sockaddr_in);
+		} /* for (loop through the new v4 addresses) */
+	}
+
+	if (NULL != hst6) {
+		for (j = 0; j < i6; ++j) {
+			b6ap = (struct sockaddr_in6 *)aptr;
+			memset(b6ap, 0x00, sizeof(*b6ap));
+			b6ap->sin6_family = AF_INET6;
+			b6ap->sin6_port =  htons(local_port);
+			b6ap->sin6_scope_id = if_index;
+			bcopy(hst6->h_addr_list[j], &b6ap->sin6_addr,
+			      hst6->h_length);
+
+			aptr += sizeof(struct sockaddr_in6);
+		} /* for (loop through the new v6 addresses) */
+	}
+
+ finally:
+
+	*ret_count = count;
+
+	return new_addrs;
+
+} /* append_addr() */
+
+static int
+parse_inter_commands(char *argv0, char *input, int snd_only)
+{
+	int i;
+	char *p;
+	int len;
+	int set = 0;
+	int val;
+	struct sockaddr *tmp_addrs = NULL;
+
+
+	p = input;
+	if (*p == '?' || *p == '\n') {
+		printf("Interactive commands:\n");
+		printf("snd=<int>        - Do a sendmsg with the specified");
+		printf(" length.\n");
+		printf("rcv=<int>        - Do a recvmsg.");
+		printf("The length is ignored for now.\n");
+		printf("bindx-add=<addr> - Add a local address");
+		printf(" with bindx. \n");
+		printf("bindx-rem=<addr> - Remove a local address");
+		printf(" with bindx. \n");
+		printf("rcvbuf=<int>     - Get/Set receive buffer size\n");
+		printf("sndbuf=<int>     - Get/Set send buffer size.\n");
+		printf("primary=<addr>   - Get/Set association's primary\n");
+		printf("peer_primary=addr- Set association's peer_primary\n");
+		printf("heartbeat=<addr> - Request a user initiated heartbeat\n");
+		printf("maxseg=<int>     - Get/Set Maximum fragment size.\n");
+		printf("nodelay=<0|1>    - Get/Set NODELAY option.\n");
+		printf("shutdown         - Shutdown the association.\n");
+		printf("abort            - Abort the association.\n");
+		printf("stats            - Print GET_ASSOC_STATS (if available in kernel).\n");
+		printf("?                - Help. Display this message.\n");
+		return -1;
+	}
+
+	for (i = 0; i < REALLY_BIG; i++) {
+		if (('=' == *p) ||
+		    ('?' == *p) ||
+		    ('\n' == *p)) {
+			if ('=' == *p) {
+				set = 1;
+			}
+			*p++ = '\0';
+			break;
+		}
+		p++;
+	}
+	if (i >= REALLY_BIG) {
+		printf("Invalid input.\n");
+		return -1;
+	}
+
+	i = 0;
+	while (NULL != inter_commands[i].cmd) {
+		if (!strcmp(input, inter_commands[i].cmd)) {
+			switch (i) {
+			case INTER_SND:
+				if (snd_only) {
+					if (*p < '0' || *p > '9') {
+						goto err_input;
+					}
+					snd_func(p);
+				} else {
+					goto err_input;
+				}
+				break;
+			case INTER_RCV:
+				if (snd_only) {
+					goto err_input;
+				}
+				break;
+			case INTER_SNDBUF:
+				if (set) {
+					if (*p < '0' || *p > '9') {
+						goto err_input;
+					}
+				}
+				len = (set) ? atoi(p) : 0;
+				sndbuf_func(argv0, inter_sk, len, set);
+				break;
+			case INTER_RCVBUF:
+				if (set) {
+					if (*p < '0' || *p > '9') {
+						goto err_input;
+					}
+				}
+				len = (set) ? atoi(p) : 0;
+				rcvbuf_func(argv0, inter_sk, len, set);
+				break;
+			case INTER_BINDX_ADD:
+				tmp_addrs = get_bindx_addr(p, &len);
+				bindx_func(argv0, inter_sk, tmp_addrs, len,
+					SCTP_BINDX_ADD_ADDR, local_port);
+				free(tmp_addrs);
+				break;
+			case INTER_BINDX_REM:
+				tmp_addrs = get_bindx_addr(p, &len);
+				bindx_func(argv0, inter_sk, tmp_addrs, len,
+					SCTP_BINDX_REM_ADDR, local_port);
+				free(tmp_addrs);
+				break;
+			case INTER_SET_PRIM:
+				primary_func(argv0, inter_sk, p, set);
+				break;
+			case INTER_SET_PEER_PRIM:
+				peer_primary_func(argv0, inter_sk, p, set);
+				break;
+			case INTER_HEARTBEAT:
+				spp_hb_demand_func(argv0, inter_sk, p, set);
+				break;
+			case INTER_SHUTDOWN:
+				shutdown_func(argv0, &inter_sk, SHUTDOWN_SHUTDOWN);
+				break;
+			case INTER_ABORT:
+				shutdown_func(argv0, &inter_sk, SHUTDOWN_ABORT);
+				break;
+			case INTER_NODELAY:
+				if (set) {
+					if (*p < '0' || *p > '9') {
+						goto err_input;
+					}
+				}
+				val = (set) ? atoi(p) : 0;
+				nodelay_func(argv0, inter_sk, val, set);
+				break;
+			case INTER_MAXSEG:
+				if (set) {
+					if (*p < '0' || *p > '9') {
+						goto err_input;
+					}
+				}
+				val = (set) ? atoi(p) : 0;
+				maxseg_func(argv0, inter_sk, val, set);
+				break;
+			case INTER_GET_STATS:
+				get_assocstats_func(inter_sk, associd);
+				break;
+			default:
+				goto err_input;
+				break;
+			}
+
+			return i;
+		}
+		i++;
+	}
+
+err_input:
+	printf("Invalid input.\n");
+	return -1;
+
+} /* parse_inter_commands() */
+
+static char *
+gen_message(int len)
+{
+
+	char *buf;
+	char *p;
+	int i;
+
+	buf = malloc(len);
+
+	if (NULL != buf) {
+		for (i = 0, p = buf; i < len; i++, p++) {
+			if (gen_data > GEN_DATA_LAST) {
+				gen_data = GEN_DATA_FIRST;
+			}
+			*p = gen_data++;
+		}
+	}
+
+	return(buf);
+
+} /* gen_message() */
+
+static void
+snd_func(char *input)
+{
+
+	int len;
+
+	len = atoi(input);
+	if (!(inter_outbuf = gen_message(len))) {
+		fprintf(stderr, "Cannot allocate out message.\n");
+		exit(1);
+	}
+	inter_outlen = len;
+
+} /* snd_func() */
+
+static void
+sndbuf_func(char *argv0, int sk, int len, int set)
+{
+	int error;
+	socklen_t optlen;
+
+	if (set) {
+		error = setsockopt(sk, SOL_SOCKET, SO_SNDBUF,
+			(char *)&len, sizeof(len));
+	} else {
+		optlen = sizeof(len);
+		error = getsockopt(sk, SOL_SOCKET, SO_SNDBUF,
+			(char *)&len, &optlen);
+	}
+	if (error != 0) {
+		fprintf(stderr, "%s: Error setting/getting sndbuf: %s.\n",
+			argv0, strerror(errno));
+		exit(1);
+	}
+
+	if (!set) {
+		printf("sndbuf is %d.\n", len);
+	}
+
+} /* sndbuf_func() */
+
+static void
+rcvbuf_func(char *argv0, int sk, int len, int set)
+{
+	int error;
+	socklen_t optlen;
+
+	if (set) {
+		error = setsockopt(sk, SOL_SOCKET, SO_RCVBUF,
+			(char *)&len, sizeof(len));
+	} else {
+		optlen = sizeof(len);
+		error = getsockopt(sk, SOL_SOCKET, SO_RCVBUF,
+			(char *)&len, &optlen);
+	}
+	if (error != 0) {
+		fprintf(stderr, "%s: Error setting/getting rcvbuf: %s.\n",
+			argv0, strerror(errno));
+		exit(1);
+	}
+
+	if (!set) {
+		printf("rcvbuf is %d.\n", len);
+	}
+
+} /* rcvbuf_func() */
+
+
+static struct sockaddr *
+get_bindx_addr(char *in, int *count)
+{
+
+	struct sockaddr *tmp_addrs = NULL;
+	char *p = in;
+
+	/* Set the buffer for address parsing.  */
+	while ('\n' != *p) {
+		p++;
+	}
+	*p = '\0';
+
+	*count = 0;
+
+	tmp_addrs = append_addr(in, tmp_addrs, count);
+	if (NULL == tmp_addrs) {
+		/* We have no memory, so keep fprintf()
+		 * from trying to allocate more.
+		 */
+		fprintf(stderr, "No memory to add ");
+		fprintf(stderr, "%s\n", in);
+		exit(2);
+	}
+	return tmp_addrs;
+
+} /* get_bindx_addr() */
+
+static int
+bindx_func(char *argv0, int sk, struct sockaddr *addrs, int count, int flag, int portnum)
+{
+
+	int error;
+	int i;
+	struct sockaddr *sa_addr;
+	void *aptr;
+
+
+	if (0 == portnum) {
+		fprintf(stderr, "%s: A non-0 local port number is ", argv0);
+		fprintf(stderr, "required for bindx to work!\n");
+		return -1 ;
+	}
+
+	/* Set the port in every address.  */
+	aptr = addrs;
+	for (i = 0; i < count; i++) {
+		sa_addr = (struct sockaddr *)aptr;
+
+		switch(sa_addr->sa_family) {
+		case AF_INET:
+			((struct sockaddr_in *)sa_addr)->sin_port =
+				htons(portnum);
+			aptr += sizeof(struct sockaddr_in);
+			break;
+		case AF_INET6:
+			((struct sockaddr_in6 *)sa_addr)->sin6_port =
+				htons(portnum);
+			aptr += sizeof(struct sockaddr_in6);
+			break;
+		default:
+			fprintf(stderr, "Invalid address family\n");
+			return -1;
+		}
+	}
+
+	error = sctp_bindx(sk, addrs, count, flag);
+
+	if (error != 0) {
+		if (flag == SCTP_BINDX_ADD_ADDR) {
+			fprintf(stderr, "%s: error adding addrs: %s.\n",
+				argv0, strerror(errno));
+			return -1;
+		} else {
+			fprintf(stderr, "%s: error removing addrs: %s.\n",
+				argv0, strerror(errno));
+			return -1;
+		}
+	}
+
+	return 0;
+
+} /* bindx_func() */
+
+static int
+connectx_func(char *argv0, int sk, struct sockaddr *addrs, int count)
+{
+
+	int error;
+	int i;
+	struct sockaddr *sa_addr;
+	void *aptr;
+
+
+	if (0 == remote_port) {
+		fprintf(stderr, "%s: A non-0 remote port number is ", argv0);
+		fprintf(stderr, "required for connectx to work!\n");
+		return -1 ;
+	}
+
+	/* Set the port in every address.  */
+	aptr = addrs;
+	for (i = 0; i < count; i++) {
+		sa_addr = (struct sockaddr *)aptr;
+
+		switch(sa_addr->sa_family) {
+		case AF_INET:
+			((struct sockaddr_in *)sa_addr)->sin_port =
+				htons(remote_port);
+			aptr += sizeof(struct sockaddr_in);
+			break;
+		case AF_INET6:
+			((struct sockaddr_in6 *)sa_addr)->sin6_port =
+				htons(remote_port);
+			aptr += sizeof(struct sockaddr_in6);
+			break;
+		default:
+			fprintf(stderr, "Invalid address family\n");
+			return -1;
+		}
+	}
+
+	error = sctp_connectx(sk, addrs, count, NULL);
+
+	if (error != 0) {
+		if (errno == ECONNREFUSED)
+			return -2;
+		fprintf(stderr, "%s: error connecting to addrs: %s.\n",
+			argv0, strerror(errno));
+		return -1;
+	}
+
+	return 0;
+
+} /* connectx_func() */
+
+static void
+primary_func(char *argv0, int sk, char *cp, int set)
+{
+	struct sctp_prim prim;
+	struct sockaddr_in *in_addr;
+	struct sockaddr_in6 *in6_addr;
+	struct sockaddr *saddr;
+	socklen_t prim_len;
+	int ret;
+	char *p = cp;
+	char addr_buf[INET6_ADDRSTRLEN];
+	const char *ap = NULL;
+
+	prim_len = sizeof(struct sctp_prim);
+	if (!set) {
+		prim.ssp_assoc_id = associd;
+		ret = getsockopt(sk, IPPROTO_SCTP, SCTP_PRIMARY_ADDR,
+				   &prim, &prim_len); 
+		if (ret < 0)
+			goto err;
+	
+		saddr = (struct sockaddr *)&prim.ssp_addr;	
+		if (AF_INET == saddr->sa_family) {
+			in_addr = (struct sockaddr_in *)&prim.ssp_addr;
+			ap = inet_ntop(AF_INET, &in_addr->sin_addr, addr_buf,
+				       INET6_ADDRSTRLEN);
+		} else if (AF_INET6 == saddr->sa_family) {
+			in6_addr = (struct sockaddr_in6 *)&prim.ssp_addr;
+			ap = inet_ntop(AF_INET6, &in6_addr->sin6_addr, addr_buf,
+				       INET6_ADDRSTRLEN);
+		}
+		if (!ap)
+			goto err;
+		printf("%s\n", ap);
+		return;
+	}
+
+	/* Set the buffer for address parsing.  */
+	while ('\n' != *p)
+		p++;
+	*p = '\0';
+
+	prim.ssp_assoc_id = associd;	
+	if (strchr(cp, '.')) {
+		in_addr = (struct sockaddr_in *)&prim.ssp_addr;
+		in_addr->sin_port = htons(remote_port);
+		in_addr->sin_family = AF_INET;
+		ret = inet_pton (AF_INET, cp, &in_addr->sin_addr);
+		if (ret <= 0)
+			goto err;		
+	} else if (strchr(cp, ':')) {
+		in6_addr = (struct sockaddr_in6 *)&prim.ssp_addr;
+		in6_addr->sin6_port = htons(remote_port);
+		in6_addr->sin6_family = AF_INET6;
+		ret = inet_pton(AF_INET6, cp, &in6_addr->sin6_addr);
+		if (ret <= 0)
+			goto err;		
+	} else
+		goto err;
+
+	ret = setsockopt(sk, IPPROTO_SCTP, SCTP_PRIMARY_ADDR,
+			    &prim, sizeof(struct sctp_prim)); 
+	if (ret < 0)
+		goto err;
+
+	return;
+err:
+	if (!errno)
+		errno = EINVAL;
+	fprintf(stderr, "%s: error %s primary: %s.\n", argv0,
+	        (set)?"setting":"getting", strerror(errno));
+}
+
+static void
+peer_primary_func(char *argv0, int sk, char *cp, int set)
+{
+	struct sctp_setpeerprim setpeerprim;
+	struct sockaddr_in *in_addr;
+	struct sockaddr_in6 *in6_addr;
+	int ret;
+	char *p = cp;
+
+	if (!set) {
+		goto err;
+	}
+
+	/* Set the buffer for address parsing.  */
+	while ('\n' != *p)
+		p++;
+	*p = '\0';
+
+	setpeerprim.sspp_assoc_id = associd;	
+	if (strchr(cp, '.')) {
+		in_addr = (struct sockaddr_in *)&setpeerprim.sspp_addr;
+		in_addr->sin_port = htons(local_port);
+		in_addr->sin_family = AF_INET;
+		ret = inet_pton (AF_INET, cp, &in_addr->sin_addr);
+		if (ret <= 0)
+			goto err;		
+	} else if (strchr(cp, ':')) {
+		in6_addr = (struct sockaddr_in6 *)&setpeerprim.sspp_addr;
+		in6_addr->sin6_port = htons(local_port);
+		in6_addr->sin6_family = AF_INET6;
+		ret = inet_pton(AF_INET6, cp, &in6_addr->sin6_addr);
+		if (ret <= 0)
+			goto err;		
+	} else
+		goto err;
+
+	ret = setsockopt(sk, IPPROTO_SCTP, SCTP_SET_PEER_PRIMARY_ADDR,
+			    &setpeerprim, sizeof(struct sctp_setpeerprim)); 
+	if (ret < 0)
+		goto err;
+
+	return;
+err:
+	if (!errno)
+		errno = EINVAL;
+	fprintf(stderr, "%s: error %s peer_primary: %s.\n", argv0,
+	        (set)?"setting":"getting", strerror(errno));
+}
+
+static void
+spp_hb_demand_func(char *argv0, int sk, char *cp, int set)
+{
+	struct sctp_paddrparams params;
+	struct sockaddr_in *in_addr;
+	struct sockaddr_in6 *in6_addr;
+	int ret;
+	char *p = cp;
+
+	memset(&params, 0, sizeof(struct sctp_paddrparams));
+	params.spp_assoc_id = associd;
+	params.spp_flags = SPP_HB_DEMAND;
+
+	if (set) {
+		/* Set the buffer for address parsing.  */
+		while ('\n' != *p)
+			p++;
+		*p = '\0';
+
+		if (strchr(cp, '.')) {
+			in_addr = (struct sockaddr_in *)&params.spp_address;
+			in_addr->sin_port = htons(remote_port);
+			in_addr->sin_family = AF_INET;
+			ret = inet_pton(AF_INET, cp, &in_addr->sin_addr);
+			if (ret <= 0)
+				goto err;
+		} else if (strchr(cp, ':')) {
+			in6_addr = (struct sockaddr_in6 *)&params.spp_address;
+			in6_addr->sin6_port = htons(remote_port);
+			in6_addr->sin6_family = AF_INET6;
+			ret = inet_pton(AF_INET6, cp, &in6_addr->sin6_addr);
+			if (ret <= 0)
+				goto err;
+		} else
+			goto err;
+	}
+
+	ret = setsockopt(sk, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS,
+			    &params, sizeof(struct sctp_paddrparams));
+	if (ret < 0)
+		goto err;
+
+	return;
+err:
+	if (!errno)
+		errno = EINVAL;
+	fprintf(stderr, "%s: error %s peer_addr_params: %s.\n", argv0,
+	        (set)?"setting":"getting", strerror(errno));
+}
+
+static int
+nodelay_func(char *argv0, int sk, int val, int set)
+{
+	socklen_t optlen;
+	int error;
+
+	if (set) {
+		error = setsockopt(sk, SOL_SCTP, SCTP_NODELAY,
+			(char *)&val, sizeof(val));
+	} else {
+		optlen = sizeof(val);
+		error = getsockopt(sk, SOL_SCTP, SCTP_NODELAY,
+			(char *)&val, &optlen);
+	}
+	if (error != 0) {
+		fprintf(stderr, "%s: Error setting/getting nodelay: %s.\n",
+			argv0, strerror(errno));
+		exit(1);
+	}
+
+	if (!set) {
+		printf("nodelay is %d.\n", val);
+	}
+
+	return error;
+}
+
+static int
+maxseg_func(char *argv0, int sk, int val, int set)
+{
+	socklen_t optlen;
+	int error;
+
+	if (set) {
+		error = setsockopt(sk, SOL_SCTP, SCTP_MAXSEG,
+			(char *)&val, sizeof(val));
+	} else {
+		optlen = sizeof(val);
+		error = getsockopt(sk, SOL_SCTP, SCTP_MAXSEG,
+			(char *)&val, &optlen);
+	}
+	if (error != 0) {
+		fprintf(stderr, "%s: Error setting/getting maxseg: %s.\n",
+			argv0, strerror(errno));
+		exit(1);
+	}
+
+	if (!set) {
+		printf("maxseg is %d.\n", val);
+	}
+
+	return error;
+}
+
+static int
+shutdown_func(char *argv0, int *skp, int shutdown_type)
+{
+	struct msghdr outmessage;
+	char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+	struct cmsghdr *cmsg;
+        int error=0, bytes_sent;
+	struct sctp_sndrcvinfo *sinfo;
+	struct hostent *hst;
+	char *sd_type;
+	int sk = *skp;
+
+	if (shutdown_type == SHUTDOWN_ABORT)
+		sd_type = "ABORT";
+	else
+		sd_type = "SHUTDOWN";
+
+	/* Verify that the association is present. */
+	error = test_sk_for_assoc(sk, associd);
+	if (error != 0) {
+		printf("The association isn't present yet! Cannot %s!\n", sd_type);
+		return -1;
+	}
+
+	if (socket_type == SOCK_SEQPACKET) {
+		/* Set up the destination.  */
+		if (remote_host) {
+			hst = gethostbyname(remote_host);
+			if (hst == NULL) {
+				hst = gethostbyname2(remote_host, AF_INET6);
+			}
+
+			if (hst == NULL || hst->h_length < 1) {
+				fprintf(stderr, "%s: bad hostname: %s\n",
+					argv0, remote_host);
+				exit(1);
+			}
+
+			ra_family = hst->h_addrtype;
+			switch (ra_family) {
+			case AF_INET:
+				ra_len = sizeof(remote_addr.v4);
+				ra_raw = &remote_addr.v4.sin_addr;
+				remote_addr.v4.sin_port = htons(remote_port);
+				remote_addr.v4.sin_family = AF_INET;
+				break;
+			case AF_INET6:
+				ra_len = sizeof(remote_addr.v6);
+				ra_raw = &remote_addr.v6.sin6_addr;
+				remote_addr.v6.sin6_port = htons(remote_port);
+				remote_addr.v6.sin6_family = AF_INET6;
+				break;
+			default:
+				fprintf(stderr, "Invalid address type.\n");
+				exit(1);
+				break;
+			}
+			memcpy(ra_raw, hst->h_addr_list[0], hst->h_length);
+		}
+
+		/* Initialize the message struct we use to pass messages to
+		 * the remote socket.
+		 */
+		outmessage.msg_name = &remote_addr;
+		outmessage.msg_namelen = ra_len;
+
+		outmessage.msg_iov = NULL;
+		outmessage.msg_iovlen = 0;
+		outmessage.msg_control = outcmsg;
+		outmessage.msg_controllen = sizeof(outcmsg);
+		outmessage.msg_flags = 0;
+
+		cmsg = CMSG_FIRSTHDR(&outmessage);
+		cmsg->cmsg_level = IPPROTO_SCTP;
+		cmsg->cmsg_type = SCTP_SNDRCV;
+		cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+		outmessage.msg_controllen = cmsg->cmsg_len;
+		sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+		memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+		if (shutdown_type == SHUTDOWN_ABORT)
+			sinfo->sinfo_flags |= SCTP_ABORT;
+		else
+			sinfo->sinfo_flags |= SCTP_EOF;
+
+		sinfo->sinfo_assoc_id = associd;
+	
+		bytes_sent = sendmsg(sk, &outmessage, 0);
+		if (bytes_sent != 0) {
+			printf("Failure:  %s.\n", strerror(errno));
+			return -1;
+		}
+
+		/* Receive the COMM_LOST or SHUTDOWN_COMP event. */
+		test_recv_assoc_change(sk);
+	} else {
+		if (shutdown_type == SHUTDOWN_ABORT) {
+			struct  linger {
+				int  l_onoff; 
+				int  l_linger;
+			} data = {1, 0};
+			error = setsockopt(sk, SOL_SOCKET, SO_LINGER,
+					   (char *)&data, sizeof(data));
+			if (error != 0) {
+				printf("setsockopt failed %s\n", strerror(errno));
+				exit(1);
+			}
+		}
+		error = close(sk);
+		if (error != 0) {
+			printf("close failed %s\n", strerror(errno));
+			exit(1);
+		}
+		*skp = sk = build_endpoint(argv0, local_port);
+	}
+
+	/* Verify that the association is no longer present.  */
+	error = test_sk_for_assoc(sk, associd);
+	if (error != 0) {
+		printf("Successfully %s the original association\n", sd_type);
+		associd = 0;
+		new_connection = 1;
+	} else {
+		printf("%s failed\n", sd_type);
+		exit(1);
+	}
+
+	return 0;
+}
+
+static int
+get_assocstats_func(int sk, sctp_assoc_t assoc_id)
+{
+	int error = 0;
+	struct sctp_assoc_stats stats;
+	socklen_t len;
+
+	if (assoc_id == 0) {
+		printf("No association present yet\n");
+		return -1;
+	}
+
+	memset(&stats, 0, sizeof(struct sctp_assoc_stats));
+	stats.sas_assoc_id = assoc_id;
+	len = sizeof(struct sctp_assoc_stats);
+	error = getsockopt(sk, SOL_SCTP, SCTP_GET_ASSOC_STATS,
+			(char *)&stats, &len);
+	if (error != 0) {
+		printf("get_assoc_stats() failed %s\n", strerror(errno));
+		return error;
+	}
+
+	printf("Retransmitted Chunks: %" PRIu64 "\n", (uint64_t) stats.sas_rtxchunks);
+	printf("Gap Acknowledgements Received: %" PRIu64 "\n", (uint64_t) stats.sas_gapcnt);
+	printf("TSN received > next expected: %" PRIu64 "\n", (uint64_t) stats.sas_outofseqtsns);
+	printf("SACKs sent: %" PRIu64 "\n", (uint64_t) stats.sas_osacks);
+	printf("SACKs received: %" PRIu64 "\n", (uint64_t) stats.sas_isacks);
+	printf("Control chunks sent: %" PRIu64 "\n", (uint64_t) stats.sas_octrlchunks);
+	printf("Control chunks received: %" PRIu64 "\n", (uint64_t) stats.sas_ictrlchunks);
+	printf("Ordered data chunks sent: %" PRIu64 "\n", (uint64_t) stats.sas_oodchunks);
+	printf("Ordered data chunks received: %" PRIu64 "\n", (uint64_t) stats.sas_iodchunks);
+	printf("Unordered data chunks sent: %" PRIu64 "\n", (uint64_t) stats.sas_ouodchunks);
+	printf("Unordered data chunks received: %" PRIu64 "\n", (uint64_t) stats.sas_iuodchunks);
+	printf("Dups received (ordered+unordered): %" PRIu64 "\n", (uint64_t) stats.sas_idupchunks);
+	printf("Packets sent: %" PRIu64 "\n", (uint64_t) stats.sas_opackets);
+	printf("Packets received: %" PRIu64 "\n", (uint64_t) stats.sas_ipackets);
+	printf("Maximum Observed RTO this period: %" PRIu64 " - Transport: ", (uint64_t) stats.sas_maxrto);
+	print_sockaddr((struct sockaddr *)&stats.sas_obs_rto_ipaddr);
+	printf("\n");
+
+	return 0;
+}
+
+static int
+test_sk_for_assoc(int sk, sctp_assoc_t assoc_id)
+{
+	int error = 0;
+	struct sctp_status status;
+	socklen_t status_len;
+
+	memset(&status, 0, sizeof(status));
+	if (assoc_id)
+		status.sstat_assoc_id = assoc_id;
+	status_len = sizeof(struct sctp_status);
+	error = getsockopt(sk, SOL_SCTP, SCTP_STATUS,
+               		(char *)&status, &status_len);
+	return error;
+}
+
+/* Receive a notification and return the corresponding associd if the event is
+ * SCTP_COMM_UP. Return 0 for any other event.
+ */
+static sctp_assoc_t
+test_recv_assoc_change(int sk)
+{
+	struct msghdr inmessage;
+	struct iovec iov;
+	char incmsg[CMSG_SPACE(sizeof(_sctp_cmsg_data_t))];
+	int error;
+
+	/* Initialize inmessage with enough space for DATA... */
+	memset(&inmessage, 0, sizeof(inmessage));
+	if ((iov.iov_base = malloc(REALLY_BIG)) == NULL) {
+		printf("%s: Can't allocate memory.\n", __FUNCTION__);
+		exit(1);
+	}
+	iov.iov_len = REALLY_BIG;
+	inmessage.msg_iov = &iov;
+	inmessage.msg_iovlen = 1;
+	/* or a control message.  */
+	inmessage.msg_control = incmsg;
+	inmessage.msg_controllen = sizeof(incmsg);
+
+	error = recvmsg(sk, &inmessage, MSG_WAITALL);
+	if (error < 0) {
+		printf("%s: recvmsg: %s\n", __FUNCTION__, strerror(errno));
+		exit(1);
+	}
+
+	return test_verify_assoc_change(&inmessage);
+}
+
+/* Verify a notification and return the corresponding associd if the event is
+ * SCTP_COMM_UP. Return 0 for any other event.
+ */
+static sctp_assoc_t
+test_verify_assoc_change(struct msghdr *msg)
+{
+	union sctp_notification *sn;
+
+	if (!(msg->msg_flags & MSG_NOTIFICATION)) {
+		fprintf(stderr, "%s: Received data when notification is expected\n",
+		       __FUNCTION__);
+		exit(1);
+	}
+
+	sn = (union sctp_notification *)msg->msg_iov->iov_base;
+	if (SCTP_ASSOC_CHANGE != sn->sn_header.sn_type) {
+		fprintf(stderr, "%s: Received unexpected notification: %d",
+			__FUNCTION__, sn->sn_header.sn_type);
+		exit(1);
+	}
+
+	switch(sn->sn_assoc_change.sac_state)
+	{
+	case SCTP_COMM_UP:
+		printf("Received SCTP_COMM_UP\n");
+		break;
+	case SCTP_COMM_LOST:
+		printf("Received SCTP_COMM_LOST\n");
+		break;
+	case SCTP_RESTART:
+		printf("Received SCTP_RESTART\n");
+		break;
+	case SCTP_SHUTDOWN_COMP:
+		printf("Received SCTP_SHUTDOWN_COMP\n");
+		break;
+	case SCTP_CANT_STR_ASSOC:
+		printf("Received SCTP_CANT_STR_ASSOC\n");
+		break;
+	}
+
+	if (SCTP_COMM_UP == sn->sn_assoc_change.sac_state)
+		return sn->sn_assoc_change.sac_assoc_id;
+	else
+		return 0;
+}
+
+void print_addr_buf(void * laddrs, int n_laddrs)
+{
+	void *addr_buf = laddrs;
+	int i;
+
+	for (i = 0; i < n_laddrs; i++) {
+		addr_buf += print_sockaddr((struct sockaddr *)addr_buf);
+		printf("\n");
+	}
+}
+
+int print_sockaddr(struct sockaddr *sa_addr)
+{
+	struct sockaddr_in *in_addr;
+	struct sockaddr_in6 *in6_addr;
+
+	if (AF_INET == sa_addr->sa_family) {
+		in_addr = (struct sockaddr_in *)sa_addr;
+		printf("%d.%d.%d.%d:%d",
+		       NIPQUAD(in_addr->sin_addr),
+		       ntohs(in_addr->sin_port));
+		return sizeof(struct sockaddr_in);
+	} else {
+		in6_addr = (struct sockaddr_in6 *)sa_addr;
+		printf("%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x:%d",
+		       NIP6(in6_addr->sin6_addr),
+		       ntohs(in6_addr->sin6_port));
+		return sizeof(struct sockaddr_in6);
+	}
+}
diff --git a/src/apps/sctp_darn.h b/src/apps/sctp_darn.h
new file mode 100644
index 0000000..e2c1ef1
--- /dev/null
+++ b/src/apps/sctp_darn.h
@@ -0,0 +1,29 @@
+#ifndef __sctp_darn_h__
+#define __sctp_darn_h__
+
+#define REALLY_BIG 65536
+#define SCTP_TESTPORT_1 1
+#define SCTP_TESTPORT_2 2
+
+void parse_arguments(int argc, char *argv[]);
+void usage(char *argv0);
+int command_listen(char *arg0, int sk);
+int command_send(char *arg0,   int *skp);
+int command_poll(char *arg0);
+int test_print_message(int sk, struct msghdr *, size_t msg_len);
+
+typedef enum {
+	COMMAND_NONE = 0,
+	COMMAND_LISTEN,
+	COMMAND_SEND,
+	COMMAND_POLL,
+} command_t;
+
+typedef union {
+	struct sockaddr_storage ss;
+        struct sockaddr_in v4;
+        struct sockaddr_in6 v6;
+        struct sockaddr sa;
+} sockaddr_storage_t;
+
+#endif /* __sctp_darn_h__ */
diff --git a/src/apps/sctp_status.c b/src/apps/sctp_status.c
new file mode 100644
index 0000000..8563cbe6
--- /dev/null
+++ b/src/apps/sctp_status.c
@@ -0,0 +1,945 @@
+/* SCTP kernel reference Implementation
+ * (C) Copyright Fujitsu Ltd. 2008, 2009
+ *
+ * The SCTP reference implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP reference implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ *    Wei Yongjun <yjwei@cn.fujitsu.com>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+#include <netinet/sctp.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <errno.h>
+#include <netdb.h>
+#include <string.h>
+
+#define DEFAULT_SEC	0
+#define DEFAULT_USEC	5000
+
+#define REALLY_BIG 65536
+
+#define SERVER 		0
+#define CLIENT 		1
+#define NOT_DEFINED	666
+
+#define DEBUG_NONE	0
+#define DEBUG_MIN	1
+#define DEBUG_MAX	2
+
+#define ORDER_PATTERN_UNORDERED   0
+#define ORDER_PATTERN_ORDERED     1
+#define ORDER_PATTERN_ALTERNATE   2
+#define ORDER_PATTERN_RANDOM      3
+
+#define STREAM_PATTERN_SEQUENTIAL 0
+#define STREAM_PATTERN_RANDOM     1
+
+#define MAX_BIND_RETRYS 10
+#define BIG_REPEAT	1000000
+#define REPEAT 		10
+
+#define DEFAULT_MAX_WINDOW 32768
+#define DEFAULT_MIN_WINDOW 1500
+
+#define MSG_CNT		10
+
+#define DEBUG_PRINT(level, print_this...)	\
+{						\
+	if (debug_level >= level) { 		\
+		fprintf(stdout, print_this); 	\
+		fflush(stdout); 		\
+	}					\
+} /* DEBUG_PRINT */
+
+char *local_host = NULL;
+int local_port = 0;
+char *remote_host = NULL;
+int remote_port = 0;
+struct sockaddr_storage s_rem, s_loc;
+int r_len, l_len;
+int size_arg = 0;
+int debug_level = DEBUG_NONE;
+int order_pattern = ORDER_PATTERN_UNORDERED;
+int order_state = 0;
+int stream_pattern = STREAM_PATTERN_SEQUENTIAL;
+int stream_state = 0;
+int repeat = REPEAT;
+int repeat_count = 0;
+int max_msgsize = DEFAULT_MAX_WINDOW;
+int msg_cnt = MSG_CNT;
+int drain = 0;
+int max_stream = 0;
+int gsk = -1;
+int period = 1;
+char *statusfile = NULL;
+
+void printstatus(int sk);
+void sighandler(int signo);
+void settimerhandle(void);
+void usage(char *argv0);
+void start_test(int role);
+
+unsigned char msg[] = "012345678901234567890123456789012345678901234567890";
+
+/* Convenience structure to determine space needed for cmsg. */
+typedef union {
+	struct sctp_initmsg init;
+	struct sctp_sndrcvinfo sndrcvinfo;
+} _sctp_cmsg_data_t;
+
+int main(int argc, char *argv[]) {
+	int c, role = NOT_DEFINED;
+	char *interface = NULL;
+	struct sockaddr_in *t_addr;
+	struct sockaddr_in6 *t_addr6;
+
+	/* Parse the arguments.  */
+	while ((c = getopt(argc, argv, ":H:L:P:h:p:c:d:lm:sx:X:o:M:Di:I:f:")) >= 0 ) {
+		switch (c) {
+		case 'H':
+			local_host = optarg;
+			break;
+		case 'P':
+			local_port = atoi(optarg);
+			break;
+		case 'h':
+			remote_host = optarg;
+			break;
+		case 'p':
+			remote_port = atoi(optarg);
+			break;
+		case 'l':
+			if (role != NOT_DEFINED) {
+				printf("%s: only -s or -l\n", argv[0]);
+				usage(argv[0]);
+				exit(1);
+			}
+			role = SERVER;
+			break;
+		case 's':
+			if (role != NOT_DEFINED) {
+				printf("%s: only -s or -l\n", argv[0]);
+				usage(argv[0]);
+				exit(1);
+			}
+			role = CLIENT;
+			break;
+		case 'D':
+			drain = 1;
+			break;
+		case 'd':
+			debug_level = atoi(optarg);
+			if (debug_level < DEBUG_NONE
+			    || debug_level > DEBUG_MAX) {
+				usage(argv[0]);
+				exit(1);
+			}
+			break;
+		case 'I':
+			period = atoi(optarg);
+			if (period < 0) {
+				usage(argv[0]);
+				exit(1);
+			}
+			break;
+		case 'x':
+			repeat = atoi(optarg);
+			if (!repeat) {
+				repeat = BIG_REPEAT;
+			}
+			break;
+		case 'X':
+			msg_cnt = atoi(optarg);
+			if ((msg_cnt <= 0) || (msg_cnt > MSG_CNT)) {
+				usage(argv[0]);
+				exit(1);
+			}
+			break;
+		case 'c':
+			size_arg = atoi(optarg);
+			if (size_arg < 0) {
+				usage(argv[0]);
+				exit(1);
+			}
+
+			break;
+		case 'o':
+			order_pattern = atoi(optarg);
+			if (order_pattern <  ORDER_PATTERN_UNORDERED
+			    || order_pattern  > ORDER_PATTERN_RANDOM ) {
+				usage(argv[0]);
+				exit(1);
+			}
+			break;
+		case 'M':
+			max_stream = atoi(optarg);
+			if (max_stream <  0
+			    || max_stream >= (1<<16)) {
+				usage(argv[0]);
+				exit(1);
+			}
+			break;
+		case 'm':
+			max_msgsize = atoi(optarg);
+			break;
+		case 'i':
+			interface = optarg;
+			break;
+		case 'f':
+			statusfile = optarg;
+			break;
+		case '?':
+		default:
+			usage(argv[0]);
+			exit(0);
+		}
+	} /* while() */
+
+	if (NOT_DEFINED == role) {
+		usage(argv[0]);
+		exit(1);
+	}
+
+	if (SERVER == role && NULL == local_host && remote_host != NULL) {
+		fprintf(stderr, "%s: Server needs local address, "
+			 "not remote address\n", argv[0]);
+		usage(argv[0]);
+		exit(1);
+	}
+	if (CLIENT == role && NULL == remote_host) {
+		fprintf(stderr, "%s: Client needs at least remote address "
+			 "& port\n", argv[0]);
+		usage(argv[0]);
+		exit(1);
+	}
+
+	if (optind < argc) {
+		fprintf(stderr, "%s: non-option arguments are illegal: ", argv[0]);
+		while (optind < argc)
+			fprintf(stderr, "%s ", argv[optind++]);
+		fprintf (stderr, "\n");
+		usage(argv[0]);
+		exit(1);
+	}
+
+	if (remote_host != NULL && remote_port != 0) {
+		struct addrinfo *res;
+		int error;
+		char *host_s, *serv_s;
+
+		if ((host_s = malloc(NI_MAXHOST)) == NULL) {
+			fprintf(stderr, "\n*** host_s malloc failed!!! ***\n");
+			exit(1);
+		}
+		if ((serv_s = malloc(NI_MAXSERV)) == NULL) {
+			fprintf(stderr, "\n*** serv_s malloc failed!!! ***\n");
+			exit(1);
+		}
+
+		error = getaddrinfo(remote_host, 0, NULL, &res);
+		if (error) {
+			printf("%s.\n", gai_strerror(error));
+			usage(argv[0]);
+			exit(1);
+		}
+
+		switch (res->ai_family) {
+			case AF_INET:
+				t_addr = (struct sockaddr_in *)&s_rem;
+
+				memcpy(t_addr, res->ai_addr,
+				       res->ai_addrlen);
+				t_addr->sin_family = res->ai_family;
+				t_addr->sin_port = htons(remote_port);
+
+				r_len = res->ai_addrlen;
+#ifdef __FreeBSD__
+				t_addr->sin_len = r_len;
+#endif
+				break;
+			case AF_INET6:
+				t_addr6 = (struct sockaddr_in6 *)&s_rem;
+
+				memcpy(t_addr6, res->ai_addr,
+				       res->ai_addrlen);
+				t_addr6->sin6_family = res->ai_family;
+				t_addr6->sin6_port = htons(remote_port);
+				if (interface)
+					t_addr6->sin6_scope_id = if_nametoindex(interface);
+
+				r_len = res->ai_addrlen;
+
+#ifdef __FreeBSD__
+				t_addr6->sin6_len = r_len;
+#endif
+				break;
+		}
+
+		getnameinfo((struct sockaddr *)&s_rem, r_len, host_s,
+			    NI_MAXHOST, serv_s, NI_MAXSERV, NI_NUMERICHOST);
+
+		DEBUG_PRINT(DEBUG_MAX, "remote:addr=%s, port=%s, family=%d\n",
+			    host_s, serv_s, res->ai_family);
+
+		freeaddrinfo(res);
+        }
+
+	if (local_host != NULL) {
+		struct addrinfo *res;
+		int error;
+		char *host_s, *serv_s;
+		struct sockaddr_in *t_addr;
+		struct sockaddr_in6 *t_addr6;
+
+		if ((host_s = malloc(NI_MAXHOST)) == NULL) {
+			fprintf(stderr, "\n*** host_s malloc failed!!! ***\n");
+			exit(1);
+		}
+		if ((serv_s = malloc(NI_MAXSERV)) == NULL) {
+			fprintf(stderr, "\n*** serv_s malloc failed!!! ***\n");
+			exit(1);
+		}
+
+		if (strcmp(local_host, "0") == 0)
+			local_host = "0.0.0.0";
+
+		error = getaddrinfo(local_host, 0, NULL, &res);
+		if (error) {
+			printf("%s.\n", gai_strerror(error));
+			usage(argv[0]);
+			exit(1);
+		}
+
+		switch (res->ai_family) {
+			case AF_INET:
+				t_addr = (struct sockaddr_in *)&s_loc;
+
+				memcpy(t_addr, res->ai_addr,
+				       res->ai_addrlen);
+				t_addr->sin_family = res->ai_family;
+				t_addr->sin_port = htons(local_port);
+
+				l_len = res->ai_addrlen;
+#ifdef __FreeBSD__
+				t_addr->sin_len = l_len;
+#endif
+				break;
+			case AF_INET6:
+				t_addr6 = (struct sockaddr_in6 *)&s_loc;
+
+				memcpy(t_addr6, res->ai_addr,
+				       res->ai_addrlen);
+				t_addr6->sin6_family = res->ai_family;
+				t_addr6->sin6_port = htons(local_port);
+				if (interface)
+					t_addr6->sin6_scope_id = if_nametoindex(interface);
+
+				l_len = res->ai_addrlen;
+
+#ifdef __FreeBSD__
+				t_addr6->sin6_len = l_len;
+#endif
+				break;
+		}
+
+		error = getnameinfo((struct sockaddr *)&s_loc, l_len, host_s,
+			    NI_MAXHOST, serv_s, NI_MAXSERV, NI_NUMERICHOST);
+
+		if (error)
+			printf("%s..\n", gai_strerror(error));
+
+		DEBUG_PRINT(DEBUG_MAX, "local:addr=%s, port=%s, family=%d\n",
+			    host_s, serv_s, res->ai_family);
+
+		freeaddrinfo(res);
+        }
+
+	/* Let the testing begin. */
+	start_test(role);
+
+	return 0;
+}
+
+int bind_r(int sk, struct sockaddr_storage *saddr) {
+	int error = 0, i = 0;
+	char *host_s, *serv_s;
+
+	if ((host_s = malloc(NI_MAXHOST)) == NULL) {
+		fprintf(stderr, "\n\t\t*** host_s malloc failed!!! ***\n");
+		exit(1);
+	}
+	if ((serv_s = malloc(NI_MAXSERV)) == NULL) {
+		fprintf(stderr, "\n\t\t*** serv_s malloc failed!!! ***\n");
+		exit(1);
+	}
+
+	do {
+		if (i > 0) sleep(1); /* sleep a while before new try... */
+
+		error = getnameinfo((struct sockaddr *)saddr, l_len, host_s,
+				    NI_MAXHOST, serv_s, NI_MAXSERV,
+				    NI_NUMERICHOST);
+
+		if (error)
+			printf("%s\n", gai_strerror(error));
+
+		DEBUG_PRINT(DEBUG_MIN,
+			"\tbind(sk=%d, [a:%s,p:%s])  --  attempt %d/%d\n",
+			sk, host_s, serv_s, i+1, MAX_BIND_RETRYS);
+
+		error = bind(sk, (struct sockaddr *)saddr, l_len);
+
+		if (error != 0) {
+			if( errno != EADDRINUSE ) {
+				fprintf(stderr, "\n\n\t\t***bind: can "
+					"not bind to %s:%s: %s ****\n",
+					host_s, serv_s, strerror(errno));
+				exit(1);
+			}
+		}
+		i++;
+		if (i >= MAX_BIND_RETRYS) {
+			fprintf(stderr, "Maximum bind() attempts. "
+				"Die now...\n\n");
+			exit(1);
+		}
+	} while (error < 0 && i < MAX_BIND_RETRYS);
+
+	return 0;
+} /* bind_r() */
+
+int listen_r(int sk, int listen_count) {
+	int error = 0;
+
+	DEBUG_PRINT(DEBUG_MIN, "\tlisten(sk=%d,backlog=%d)\n",
+		sk, listen_count);
+
+	/* Mark sk as being able to accept new associations */
+	error = listen(sk, 1);
+	if (error != 0) {
+		fprintf(stderr, "\n\n\t\t*** listen:  %s ***\n\n\n", strerror(errno));
+		exit(1);
+	}
+
+	return 0;
+} /* listen_r() */
+
+int accept_r(int sk){
+	socklen_t len = 0;
+
+	DEBUG_PRINT(DEBUG_MIN, "\taccept(sk=%d)\n", sk);
+
+	gsk = accept(sk, NULL, &len);
+	if (gsk < 0) {
+		fprintf(stderr, "\n\n\t\t*** accept:  %s ***\n\n\n", strerror(errno));
+		exit(1);
+	}
+
+	return 0;
+} /* accept_r() */
+
+int connect_r(int sk, const struct sockaddr *serv_addr, socklen_t addrlen) {
+	int error = 0;
+
+	DEBUG_PRINT(DEBUG_MIN, "\tconnect(sk=%d)\n", sk);
+
+	/* Mark sk as being able to accept new associations */
+	error = connect(sk, serv_addr, addrlen);
+	if (error != 0) {
+		fprintf(stderr, "\n\n\t\t*** connect:  %s ***\n\n\n",
+			strerror(errno));
+		exit(1);
+	}
+
+	gsk = sk;
+
+	return 0;
+} /* connect_r() */
+
+int close_r(int sk) {
+	int error = 0;
+
+	DEBUG_PRINT(DEBUG_MIN, "\tclose(sk=%d)\n",sk);
+
+	error = close(sk);
+	if (error != 0) {
+		fprintf(stderr, "\n\n\t\t*** close: %s ***\n\n",
+			strerror(errno));
+		exit(1);
+	}
+	fflush(stdout);
+	return 0;
+} /* close_r() */
+
+int receive_r(int sk)
+{
+	int error = 0;
+	char incmsg[CMSG_SPACE(sizeof(_sctp_cmsg_data_t))];
+	struct iovec iov;
+	struct msghdr inmessage;
+
+	/* Initialize inmessage with enough space for DATA... */
+	memset(&inmessage, 0, sizeof(inmessage));
+	if ((iov.iov_base = malloc(REALLY_BIG)) == NULL) {
+		fprintf(stderr, "\n\t\t*** malloc not enough memory!!! ***\n");
+		exit(1);
+	}
+	iov.iov_len = REALLY_BIG;
+	inmessage.msg_iov = &iov;
+	inmessage.msg_iovlen = 1;
+	/* or a control message.  */
+	inmessage.msg_control = incmsg;
+	inmessage.msg_controllen = sizeof(incmsg);
+
+	/* Get the messages sent */
+	while (1) {
+		DEBUG_PRINT(DEBUG_MIN, "\trecvmsg(sk=%d) ", sk);
+
+		error = recvmsg(sk, &inmessage, MSG_WAITALL);
+		if (error < 0 && errno != EAGAIN) {
+			fprintf(stderr, "\n\t\t*** recvmsg: %s ***\n\n",
+					strerror(errno));
+			fflush(stdout);
+			close(sk);
+			free(iov.iov_base);
+			exit(1);
+		} else if (error == 0) {
+			printf("\n\t\trecvmsg() returned 0 !!!!\n");
+			fflush(stdout);
+		}
+
+		if(MSG_NOTIFICATION & inmessage.msg_flags)
+			continue; /* got a notification... */
+
+		inmessage.msg_control = incmsg;
+		inmessage.msg_controllen = sizeof(incmsg);
+		iov.iov_len = REALLY_BIG;
+		break;
+	}
+
+	free(iov.iov_base);
+	return 0;
+} /* receive_r () */
+
+void server(int sk) {
+	int i;
+
+	if (max_msgsize > DEFAULT_MAX_WINDOW) {
+		if (setsockopt(sk, IPPROTO_SCTP, SO_RCVBUF, &max_msgsize,
+			       sizeof(max_msgsize)) < 0) {
+			perror("setsockopt(SO_RCVBUF)");
+			exit(1);
+		}
+	}
+
+	for (i = 0; i < msg_cnt; i++) {
+		receive_r(sk);
+		DEBUG_PRINT(DEBUG_MIN, "count %d\n", i+1);
+	}
+} /* server() */
+
+void * build_msg(int len) {
+	int i = len - 1;
+	int n;
+	char *msg_buf, *p;
+
+	msg_buf = malloc(len);
+	if (NULL == msg_buf) {
+		fprintf(stderr, "\n\t\t*** malloc not enough memory!!! ***\n");
+		exit(1);
+	}
+	p = msg_buf;
+
+	do {
+		n = ((i > 50)?50:i);
+		memcpy(p, msg, ((i > 50)?50:i));
+		p += n;
+		i -= n;
+	} while (i > 0);
+
+	msg_buf[len-1] = '\0';
+
+	return(msg_buf);
+
+} /* build_msg() */
+
+int send_r(int sk, int stream, int order, int send_size, int assoc_i) {
+	int error = 0;
+	struct msghdr outmsg;
+	struct iovec iov;
+	char *message = NULL;
+	int msglen = 0;
+	char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+	struct cmsghdr *cmsg;
+	struct sctp_sndrcvinfo *sinfo;
+
+	if (send_size > 0) {
+		message = build_msg(send_size);
+		msglen = strlen(message) + 1;
+		iov.iov_base = message;
+		iov.iov_len = msglen;
+	} else {
+			exit(1);
+	}
+
+	outmsg.msg_name = &s_rem;
+	outmsg.msg_namelen = sizeof(struct sockaddr_storage);
+	outmsg.msg_iov = &iov;
+	outmsg.msg_iovlen = 1;
+	outmsg.msg_control = outcmsg;
+	outmsg.msg_controllen = sizeof(outcmsg);
+	outmsg.msg_flags = 0;
+
+	cmsg = CMSG_FIRSTHDR(&outmsg);
+	cmsg->cmsg_level = IPPROTO_SCTP;
+	cmsg->cmsg_type = SCTP_SNDRCV;
+	cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+
+	outmsg.msg_controllen = cmsg->cmsg_len;
+	sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+	memset(sinfo, 0, sizeof(struct sctp_sndrcvinfo));
+	sinfo->sinfo_ppid = rand();
+	sinfo->sinfo_stream = stream;
+	sinfo->sinfo_flags = 0;
+	if (!order)
+		sinfo->sinfo_flags = SCTP_UNORDERED;
+
+	DEBUG_PRINT(DEBUG_MIN, "\tsendmsg(sk=%d, assoc=%d) %4d bytes.\n",
+		    sk, assoc_i, send_size);
+	DEBUG_PRINT(DEBUG_MAX, "\t  SNDRCV");
+	if (DEBUG_MAX == debug_level) {
+		printf("(stream=%u ", 	sinfo->sinfo_stream);
+		printf("flags=0x%x ",	sinfo->sinfo_flags);
+		printf("ppid=%u)\n",	sinfo->sinfo_ppid);
+	}
+
+	/* Send to our neighbor.  */
+	error = sendmsg(sk, &outmsg, MSG_WAITALL);
+	if (error != msglen) {
+		fprintf(stderr, "\n\t\t*** sendmsg: %s ***\n\n",
+			strerror(errno));
+		fflush(stdout);
+		exit(1);
+	}
+
+	if (send_size > 0) free(message);
+	return 0;
+} /* send_r() */
+
+int next_order(int state, int pattern)
+{
+	switch (pattern){
+	case ORDER_PATTERN_UNORDERED:
+		state = 0;
+		break;
+	case ORDER_PATTERN_ORDERED:
+		state = 1;
+		break;
+	case ORDER_PATTERN_ALTERNATE:
+		state = state ? 0 : 1;
+		break;
+	case ORDER_PATTERN_RANDOM:
+		state = rand() % 2;
+		break;
+	}
+
+	return state;
+}
+
+int next_stream(int state, int pattern)
+{
+	switch (pattern){
+	case STREAM_PATTERN_RANDOM:
+		state = rand() % max_stream;
+		break;
+	case STREAM_PATTERN_SEQUENTIAL:
+		state = state + 1;
+		if (state >= max_stream)
+			state = 0;
+		break;
+	}
+
+	return state;
+}
+
+int next_msg_size(int msg_cnt)
+{
+	int msg_size;
+
+	if (size_arg) {
+		msg_size = size_arg;
+	} else {
+		msg_size = (rand() % max_msgsize) + 1;
+	}
+
+	return msg_size;
+
+} /* next_msg_size() */
+
+void client(int sk) {
+	int msg_size;
+	int i;
+
+	for (i = 0; i < msg_cnt; i++) {
+		msg_size = next_msg_size(i);
+		order_state = next_order(order_state, order_pattern);
+		stream_state = next_stream(stream_state, stream_pattern);
+
+		if (send_r(sk, stream_state, order_state, msg_size, 0) < 0) {
+			close(sk);
+			break;
+		}
+
+		/* The sender is echoing so do discard the echoed data. */
+		if (drain && ((i + 1) % period == 0)) {
+			receive_r(sk);
+		}
+	}
+} /* client() */
+
+void start_test(int role) {
+	int sk, pid, ret;
+	int i = 0;
+
+	DEBUG_PRINT(DEBUG_NONE, "\nStarting tests...\n");
+
+	repeat_count = repeat;
+
+	DEBUG_PRINT(DEBUG_MIN, "\tsocket(SOCK_STREAM, IPPROTO_SCTP)");
+
+	if ((sk = socket(s_loc.ss_family, SOCK_STREAM, IPPROTO_SCTP)) < 0 ) {
+		fprintf(stderr, "\n\n\t\t*** socket: failed to create"
+			" socket:  %s ***\n", strerror(errno));
+		exit(1);
+	}
+	DEBUG_PRINT(DEBUG_MIN, "  ->  sk=%d\n", sk);
+
+	bind_r(sk, &s_loc);
+
+	if (role == SERVER) {
+		listen_r(sk, 1);
+		accept_r(sk);
+	} else {
+		if (max_stream > 0) {
+			struct sctp_initmsg initmsg;
+
+			memset(&initmsg, 0, sizeof(initmsg));
+			initmsg.sinit_num_ostreams = max_stream;
+			initmsg.sinit_max_instreams = max_stream;
+			initmsg.sinit_max_attempts = 3;
+
+			ret = setsockopt(sk, IPPROTO_SCTP, SCTP_INITMSG,
+					 &initmsg, sizeof(initmsg));
+			if (ret < 0) {
+				perror("setsockopt(SCTP_INITMSG)");
+				exit(0);
+			}
+		}
+
+		connect_r(sk, (struct sockaddr *)&s_rem, r_len);
+	}
+
+	if ((pid = fork()) == 0) {
+		settimerhandle();
+		printstatus(gsk);
+		while(1);
+	} else {
+		if (!debug_level) {
+			printf("     ");
+		}
+
+		for(i = 0; i < repeat_count; i++) {
+
+			if (role == SERVER) {
+				DEBUG_PRINT(DEBUG_NONE, "Server: Receiving packets.(%d/%d)\n",
+					i+1, repeat_count);
+				server(gsk);
+			} else {
+				DEBUG_PRINT(DEBUG_NONE, "Client: Sending packets.(%d/%d)\n",
+					i+1, repeat_count);
+				client(sk);
+			}
+
+			fflush(stdout);
+		}
+
+		if (role == SERVER) close_r(gsk);
+		close_r(sk);
+	}
+} /* start_test() */
+
+void settimerhandle(void) {
+	struct sigaction act;
+	struct itimerval interval;
+
+	act.sa_handler = sighandler;
+	act.sa_flags = 0;
+	sigemptyset(&act.sa_mask);
+	sigaction(SIGPROF, &act, NULL);
+
+	interval.it_value.tv_sec = DEFAULT_SEC;
+	interval.it_value.tv_usec = DEFAULT_USEC;
+	interval.it_interval = interval.it_value;
+
+	setitimer(ITIMER_PROF, &interval, NULL);
+}
+
+void usage(char *argv0) {
+	fprintf(stderr, "\nusage:\n");
+	fprintf(stderr, "  server:\n");
+	fprintf(stderr, "  %8s -H local-addr -P local-port -l [-d level] [-x]\n"
+			"\t      [-L num-ports] [-S num-ports]\n"
+			"\t      [-a assoc-pattern]\n"
+			"\t      [-i interface]\n"
+			"\t      [-f status-file]\n",
+		argv0);
+	fprintf(stderr, "\n");
+	fprintf(stderr, "  client:\n");
+	fprintf(stderr, "  %8s -H local-addr -P local-port -h remote-addr\n"
+		"\t      -p remote-port -s [-c case ] [-d level]\n"
+		"\t      [-x repeat] [-o order-pattern] ream-pattern]\n"
+		"\t      [-M max-stream]\n"
+		"\t      [-m max-msgsize]\n"
+		"\t      [-L num-ports] [-S num-ports]\n"
+		"\t      [-i interface]\n"
+		"\t      [-f status-file]\n",
+		argv0);
+	fprintf(stderr, "\n");
+	fprintf(stderr, "\t-c value = Packets of specifed size.\n");
+	fprintf(stderr, "\t-m msgsize(1500-65515, default value 32768)\n");
+	fprintf(stderr, "\t-x number of repeats\n");
+	fprintf(stderr, "\t-X number of messages\n");
+	fprintf(stderr, "\t-o order-pattern\n");
+	fprintf(stderr, "\t   0 = all unordered(default) \n");
+	fprintf(stderr, "\t   1 = all ordered \n");
+	fprintf(stderr, "\t   2 = alternating \n");
+	fprintf(stderr, "\t   3 = random\n");
+	fprintf(stderr, "\t-M max-stream (default value 0)\n");
+	fprintf(stderr, "\t-D drain. If in client mode do a read following send.\n");
+	fprintf(stderr, "\t-I receive after <n> times of send, default value 1.\n");
+	fprintf(stderr, "\n");
+	fflush(stderr);
+
+} /* usage() */
+
+void sighandler(int signo) {
+	DEBUG_PRINT(DEBUG_MAX, "timeout sig\n");
+	printstatus(gsk);
+}
+
+char* get_sstat_state(int state) {
+	switch(state) {
+	case SCTP_EMPTY:
+		return "EMPTY";
+	case SCTP_CLOSED:
+		return "CLOSED";
+	case SCTP_COOKIE_WAIT:
+		return "COOKIE_WAIT";
+	case SCTP_COOKIE_ECHOED:
+		return "COOKIE_ECHOED";
+	case SCTP_ESTABLISHED:
+		return "ESTABLISHED";
+	case SCTP_SHUTDOWN_PENDING:
+		return "SHUTDOWN_PENDING";
+	case SCTP_SHUTDOWN_SENT:
+		return "SHUTDOWN_SENT";
+	case SCTP_SHUTDOWN_RECEIVED:
+		return "SHUTDOWN_RECEIVED";
+	case SCTP_SHUTDOWN_ACK_SENT:
+		return "SHUTDOWN_ACK_SENT";
+	default:
+		return "UNKNOW";
+	}
+}
+
+void printstatus(int sk) {
+	static int cwnd = 0;
+	static int count = 0;
+	struct sctp_status status;
+	socklen_t optlen;
+	FILE * fp;
+	const char *state_to_str[] = {
+		[SCTP_INACTIVE]		=	"INACTIVE",
+		[SCTP_PF]		=	"PF",
+		[SCTP_ACTIVE]		=	"ACTIVE",
+		[SCTP_UNCONFIRMED]	=	"UNCONFIRMED",
+	};
+
+	optlen = sizeof(struct sctp_status);
+	if(getsockopt(sk, IPPROTO_SCTP, SCTP_STATUS, &status, &optlen) < 0) {
+		fprintf(stderr, "Error getting status: %s.\n", strerror(errno));
+		exit(1);
+	}
+
+	if (statusfile != NULL) {
+		if (count == 0)
+			unlink(statusfile);
+
+		if((fp = fopen(statusfile, "a+")) == NULL) {
+			perror("fopen");
+			exit(1);
+		}
+	} else
+		fp = stdout;
+
+	if (count == 0)
+		fprintf(fp, "NO. ASSOC-ID STATE             RWND     UNACKDATA PENDDATA INSTRMS OUTSTRMS "
+				"FRAG-POINT SPINFO-STATE SPINFO-CWDN SPINFO-SRTT SPINFO-RTO SPINFO-MTU\n");
+
+	if (cwnd != status.sstat_primary.spinfo_cwnd) {
+		count++;
+
+		fprintf(fp, "%-3d %-8d %-17s %-8d %-9d %-8d %-7d %-8d %-10d %-12s %-11d %-11d %-10d %d\n", count,
+				status.sstat_assoc_id, get_sstat_state(status.sstat_state),
+				status.sstat_rwnd, status.sstat_unackdata, status.sstat_penddata,
+				status.sstat_instrms, status.sstat_outstrms, status.sstat_fragmentation_point,
+				state_to_str[status.sstat_primary.spinfo_state],
+				status.sstat_primary.spinfo_cwnd, status.sstat_primary.spinfo_srtt,
+				status.sstat_primary.spinfo_rto, status.sstat_primary.spinfo_mtu);
+	}
+
+	cwnd = status.sstat_primary.spinfo_cwnd;
+
+	fflush(fp);
+
+	if (fp != stdout)
+		fclose(fp);
+
+	if (status.sstat_primary.spinfo_state != SCTP_ACTIVE) {
+		close_r(sk);
+		exit(1);
+	}
+}
diff --git a/src/apps/sctp_test.c b/src/apps/sctp_test.c
new file mode 100644
index 0000000..cd7654b
--- /dev/null
+++ b/src/apps/sctp_test.c
@@ -0,0 +1,1852 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2001, 2003
+ * Copyright (c) 1999 Cisco
+ * Copyright (c) 1999, 2000, 2001 Motorola
+ * Copyright (c) 2001-2002 Nokia
+ * Copyright (c) 2001 La Monte H.P. Yarroll
+ *
+ * This is a userspace test application for the SCTP kernel 
+ * implementation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ^^^^^^^^^^^^^^^^^^^^^^^^
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Written or modified by:
+ *   Hui Huang         <hui.huang@nokia.com>
+ *   Sridhar Samudrala <samudrala@us.ibm.com>
+ *   Jon Grimm         <jgrimm@us.ibm.com>
+ *   Daisy Chang       <daisyc@us.ibm.com>
+ *   Ryan Layer	       <rmlayer@us.ibm.com>
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <string.h>
+#include <arpa/inet.h>
+#include <sys/wait.h>
+#include <sys/param.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <net/if.h>
+
+#include <sys/resource.h>
+
+
+#define REALLY_BIG 65536
+
+#define SERVER 		0
+#define CLIENT 		1
+#define MIXED 		2
+#define NOT_DEFINED	666
+
+#define REPEAT 		10
+#define BIG_REPEAT	1000000
+#define MAX_BIND_RETRYS 10
+#define BODYSIZE	10
+#define MSG_CNT		10	/* If this is changed the msg_sizes array
+				   needs to be modified accordingly.  */
+
+#define DEFAULT_MAX_WINDOW 32768
+#define DEFAULT_MIN_WINDOW 1500
+
+#define DEBUG_NONE	0
+#define DEBUG_MIN	1
+#define DEBUG_MAX	2
+
+#define STREAM_PATTERN_SEQUENTIAL 0
+#define STREAM_PATTERN_RANDOM     1
+
+#define ORDER_PATTERN_UNORDERED   0
+#define ORDER_PATTERN_ORDERED     1
+#define ORDER_PATTERN_ALTERNATE   2
+#define ORDER_PATTERN_RANDOM      3
+
+#define ASSOC_PATTERN_SEQUENTIAL 0
+#define ASSOC_PATTERN_RANDOM     1
+
+#define NCASES 6
+#define MAX_POLL_SKS 256
+
+#define DEBUG_PRINT(level, print_this...)	\
+{						\
+	if (debug_level >= level) { 		\
+		fprintf(stdout, print_this); 	\
+		fflush(stdout); 		\
+	}					\
+} /* DEBUG_PRINT */
+
+/* Convenience structure to determine space needed for cmsg. */
+typedef union {
+        struct sctp_initmsg init;
+        struct sctp_sndrcvinfo sndrcvinfo;
+} _sctp_cmsg_data_t;
+
+#ifdef __FreeBSD__
+typedef union {
+        int                    raw;
+        struct sctp_initmsg     init;
+        struct sctp_sndrcvinfo  sndrcv;
+} sctp_cmsg_data_t;
+#endif
+
+#define CMSG_SPACE_INITMSG (CMSG_SPACE(sizeof(struct sctp_initmsg)))
+#define CMSG_SPACE_SNDRCV (CMSG_SPACE(sizeof(struct sctp_sndrcvinfo)))
+
+typedef struct {
+	int rem_port;
+        int order_state;
+        int stream_state;
+	int msg_cnt;
+	int msg_sent;
+	int cycle;
+} _assoc_state;
+
+typedef struct {
+        int sk;
+        int assoc_i;
+	_assoc_state *assoc_state;
+} _poll_sks;
+
+char *local_host = NULL;
+int local_port = 0;
+char *remote_host = NULL;
+int remote_port = 0;
+/* struct sockaddr_in s_rem, s_loc; */
+struct sockaddr_storage s_rem, s_loc;
+int r_len, l_len;
+int test_case = 0;
+int size_arg = 0;
+int xflag = 0;
+int debug_level = DEBUG_MAX;
+int do_exit = 1;
+int stream_pattern = STREAM_PATTERN_SEQUENTIAL;
+int stream_state = 0;
+int order_pattern = ORDER_PATTERN_UNORDERED;
+int order_state = 0;
+int max_stream = 0;
+int seed = 0;
+int max_msgsize = DEFAULT_MAX_WINDOW;
+int timetolive = 0;
+int assoc_pattern = ASSOC_PATTERN_SEQUENTIAL;
+int socket_type = SOCK_SEQPACKET;
+int repeat_count = 0;
+int listeners = 0;
+int tosend = 0;
+_poll_sks poll_sks[MAX_POLL_SKS];
+int repeat = REPEAT;
+int msg_cnt = MSG_CNT;
+int drain = 0;
+int role = NOT_DEFINED;
+struct sockaddr *bindx_add_addrs = NULL;
+int bindx_add_count = 0;
+struct sockaddr *connectx_addrs = NULL;
+int connectx_count = 0;
+int if_index = 0;
+
+unsigned char msg[] = "012345678901234567890123456789012345678901234567890";
+
+static int msg_sizes[NCASES][MSG_CNT] =
+	{{1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
+	 {1452, 2904, 4356, 1452, 2904, 4356, 1452, 2904, 4356, 1452},
+	 {1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453},
+	 {1, 1453, 32768, 1, 1453, 32768, 1, 1453, 32768, 1},
+	 {1, 1000, 2000, 3000, 5000, 10000, 15000, 20000, 25000, 32768},
+	 {32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768},
+	};
+
+static const char *sac_state_tbl[] = {
+	"COMMUNICATION_UP",
+	"COMMUNICATION_LOST",
+	"RESTART",
+	"SHUTDOWN_COMPLETE",
+	"CANT_START_ASSOCICATION"
+};
+
+void usage(char *argv0)
+{
+	fprintf(stderr, "\nusage:\n");
+	fprintf(stderr, "  server:\n");
+	fprintf(stderr, "  %8s -H local-addr -P local-port -l [-d level] [-x]\n"
+			"\t      [-L num-ports] [-S num-ports]\n"
+			"\t      [-a assoc-pattern]\n"
+			"\t      [-i interface]\n",
+		argv0);
+	fprintf(stderr, "\n");
+	fprintf(stderr, "  client:\n");
+	fprintf(stderr, "  %8s -H local-addr -P local-port -h remote-addr\n"
+		"\t      -p remote-port -s [-c case ] [-d level]\n"
+		"\t      [-x repeat] [-o order-pattern] [-t stream-pattern]\n"
+		"\t      [-M max-stream] [-r rand-seed]\n"
+		"\t      [-m max-msgsize]\n"
+		"\t      [-L num-ports] [-S num-ports]\n"
+		"\t      [-a assoc-pattern]\n"
+		"\t      [-i interface]\n",
+		argv0);
+	fprintf(stderr, "\n");
+	fprintf(stderr, "\t-a assoc_pattern in the mixed mode\n");
+	fprintf(stderr, "\t   0 = sequential ascending(default)\n");
+	fprintf(stderr, "\t   1 = random\n");
+	fprintf(stderr, "\t-d debug\n");
+	fprintf(stderr, "\t   0 = none\n");
+	fprintf(stderr, "\t   1 = min(default)\n");
+	fprintf(stderr, "\t   2 = max\n");
+	fprintf(stderr, "\t-c testcase\n");
+	fprintf(stderr, "\t   0 = 1 byte packets.\n");
+	fprintf(stderr, "\t   1 = Sequence of multiples of 1452 byte packets.\n");
+	fprintf(stderr, "\t       (1452 is fragmentation point for an i/f with ");
+	fprintf(stderr, "1500 as mtu.)\n");
+	fprintf(stderr, "\t   2 = 1453 byte packets.\n");
+	fprintf(stderr, "\t       (min. size at which fragmentation occurs\n");
+	fprintf(stderr, "\t        for an i/f with 1500 as mtu.)\n");
+	fprintf(stderr, "\t   3 = Sequence of 1, 1453, 32768 byte packets.\n");
+	fprintf(stderr, "\t   4 = Sequence of following size packets.\n");
+	fprintf(stderr, "\t       (1, 1000, 2000, 3000, 5000, 10000,");
+	fprintf(stderr, "15000, 20000, 25000, 32768)\n");
+	fprintf(stderr, "\t   5 = 32768 byte packets.\n");
+	fprintf(stderr, "\t       (default max receive window size.)\n");
+	fprintf(stderr, "\t   6 = random size packets.\n");
+	fprintf(stderr, "\t   -ve value = Packets of specifed size.\n");
+	fprintf(stderr, "\t-m max msgsize for option -c 6 (1500-65515, default value 32768)\n");
+	fprintf(stderr, "\t-x number of repeats\n");
+	fprintf(stderr, "\t-o order-pattern\n");
+	fprintf(stderr, "\t   0 = all unordered(default) \n");
+	fprintf(stderr, "\t   1 = all ordered \n");
+	fprintf(stderr, "\t   2 = alternating \n");
+        fprintf(stderr, "\t   3 = random\n");
+	fprintf(stderr, "\t-t stream-pattern\n");
+	fprintf(stderr, "\t   0 = sequential ascending(default)\n");
+	fprintf(stderr, "\t   1 = random\n");
+	fprintf(stderr, "\t-M max-stream (default value 0)\n");
+	fprintf(stderr, "\t-r seed (default 0, use time())\n");
+	fprintf(stderr, "\t-L num-ports (default value 0). Run the mixed mode\n");
+	fprintf(stderr, "\t-S num-ports (default value 0). Run the mixed mode\n");
+	fprintf(stderr, "\t-D drain. If in client mode do a read following send.\n");
+	fprintf(stderr, "\t-T use SOCK_STREAM tcp-style sockets.\n");
+	fprintf(stderr, "\t-B add the specified address(es) as additional bind\n");
+	fprintf(stderr, "\t   addresses of the local socket. Multiple addresses can\n");
+	fprintf(stderr, "\t   be specified by using this argument multiple times.\n");
+	fprintf(stderr, "\t   For example, '-B 10.0.0.1 -B 20.0.0.2'.\n");
+	fprintf(stderr, "\t   In case of IPv6 linklocal address, interface name can be set in following way \n");
+	fprintf(stderr, "\t   For example, '-B fe80::f8c3:b77f:698e:4506%%eth2'.\n");
+	fprintf(stderr, "\t-C use the specified address(es) for connection to the\n");
+	fprintf(stderr, "\t   peer socket. Multiple addresses can be specified by\n");
+	fprintf(stderr, "\t   using this argument multiple times.\n");
+	fprintf(stderr, "\t   For example, '-C 10.0.0.1 -C 20.0.0.2'.\n");
+	fprintf(stderr, "\t   This option is incompatible with the -h option.\n");
+	fprintf(stderr, "\t-O time to live (default value 0)\n");
+	fprintf(stderr, "\n");
+	fflush(stderr);
+
+} /* usage() */
+
+void *
+build_msg(int len)
+{
+	int i = len - 1;
+	int n;
+	char *msg_buf, *p;
+
+	msg_buf = malloc(len);
+	if (NULL == msg_buf) {
+		fprintf(stderr, "\n\t\t*** malloc not enough memory!!! ***\n");
+		exit(1);
+	}
+	p = msg_buf;
+
+	do {
+		n = ((i > 50)?50:i);
+		memcpy(p, msg, ((i > 50)?50:i));
+		p += n;
+		i -= n;
+	} while (i > 0);
+
+	msg_buf[len-1] = '\0';
+
+	return(msg_buf);
+
+} /* build_msg() */
+
+static int
+print_cmsg(int type, sctp_cmsg_data_t *data)
+{
+        switch(type) {
+        case SCTP_INIT:
+		DEBUG_PRINT(DEBUG_MAX, "\tINIT\n");
+		if (DEBUG_MAX == debug_level) {
+			printf("\t\tsinit_num_ostreams=%d ",
+			       data->init.sinit_num_ostreams);
+                	printf("sinit_max_instreams=%d ",
+			       data->init.sinit_max_instreams);
+	                printf("sinit_max_attempts=%d ",
+			       data->init.sinit_max_attempts);
+        	        printf("sinit_max_init_timeo=%d\n",
+			       data->init.sinit_max_init_timeo);
+		}
+		break;
+        case SCTP_SNDRCV:
+		DEBUG_PRINT(DEBUG_MAX, "\t  SNDRCV");
+		if (DEBUG_MAX == debug_level) {
+        	        printf("(stream=%u ", 	data->sndrcv.sinfo_stream);
+                	printf("ssn=%u ", 	data->sndrcv.sinfo_ssn);
+			printf("tsn=%u ", 	data->sndrcv.sinfo_tsn);
+	                printf("flags=0x%x ",	data->sndrcv.sinfo_flags);
+        	        printf("ppid=%u\n",	data->sndrcv.sinfo_ppid);
+			printf("cumtsn=%u\n",   data->sndrcv.sinfo_cumtsn);
+                }
+		break;
+         default:
+		DEBUG_PRINT(DEBUG_MIN, "\tUnknown type: %d\n", type);
+                break;
+        }
+	fflush(stdout);
+        return 0;
+
+} /* print_cmsg() */
+
+/* This function prints the message. */
+static int
+print_message(const int sk, struct msghdr *msg, size_t msg_len) {
+	struct cmsghdr *scmsg;
+	sctp_cmsg_data_t *data;
+        int i;
+
+        if (!(MSG_NOTIFICATION & msg->msg_flags)) {
+                int index = 0;
+
+		DEBUG_PRINT(DEBUG_MIN, "Data %zu bytes.", msg_len);
+		DEBUG_PRINT(DEBUG_MAX, " First %zu bytes: ",
+				    (msg_len < BODYSIZE)?msg_len:BODYSIZE);
+                /* Make sure that everything is printable and that we
+                 * are NUL terminated...
+                 */
+		while ( msg_len > 0 ) {
+			char *text, tmptext[BODYSIZE];
+			int len;
+
+			memset(tmptext, 0x0, BODYSIZE);
+
+			text = msg->msg_iov[index].iov_base;
+			len = msg->msg_iov[index].iov_len;
+
+			if (msg_len == 1 && text[0] == 0) {
+				DEBUG_PRINT(DEBUG_MIN, "<empty> text[0]=%d",
+					    text[0]);
+				break;
+			}
+
+			if ( len > msg_len ) {
+				/* text[(len = msg_len) - 1] = '\0'; */
+				text[(len = msg_len)] = '\0';
+			}
+
+			if ( (msg_len -= len) > 0 ) { index++; }
+
+			for (i = 0; i < len - 1; ++i) {
+				if (!isprint(text[i])) text[i] = '.';
+			}
+
+ 			strncpy(tmptext, text, BODYSIZE);
+ 			tmptext[BODYSIZE-1] = '\0';
+
+			DEBUG_PRINT(DEBUG_MAX, "%s", tmptext);
+                }
+
+                DEBUG_PRINT(DEBUG_MIN, "\n");
+                fflush(stdout);
+        }  else { /* if(we have notification) */
+		struct sctp_assoc_change *sac;
+		struct sctp_send_failed *ssf;
+		struct sctp_paddr_change *spc;
+		struct sctp_remote_error *sre;
+		union sctp_notification *snp;
+		char addrbuf[INET6_ADDRSTRLEN];
+		const char *ap;
+		struct sockaddr_in *sin;
+		struct sockaddr_in6 *sin6;
+		int index = 0;
+
+		snp = (union sctp_notification *)msg->msg_iov[index].iov_base;
+
+		DEBUG_PRINT(DEBUG_MIN, "Notification:");
+        	
+		switch (snp->sn_header.sn_type) {
+			case SCTP_ASSOC_CHANGE:
+				sac = &snp->sn_assoc_change;
+				DEBUG_PRINT(DEBUG_MIN,
+					    " SCTP_ASSOC_CHANGE(%s)\n",
+					    sac_state_tbl[sac->sac_state]);
+				DEBUG_PRINT(DEBUG_MAX,
+					    "\t\t(assoc_change: state=%hu, "
+					    "error=%hu, instr=%hu "
+					    "outstr=%hu)\n",
+					    sac->sac_state, sac->sac_error,
+					    sac->sac_inbound_streams,
+					    sac->sac_outbound_streams);
+				break;
+			case SCTP_PEER_ADDR_CHANGE:
+				spc = &snp->sn_paddr_change;
+				DEBUG_PRINT(DEBUG_MIN,
+					    " SCTP_PEER_ADDR_CHANGE\n");
+				if (spc->spc_aaddr.ss_family == AF_INET) {
+					sin = (struct sockaddr_in *)
+					       &spc->spc_aaddr;
+					ap = inet_ntop(AF_INET, &sin->sin_addr,
+						       addrbuf,
+						       INET6_ADDRSTRLEN);
+				} else {
+					sin6 = (struct sockaddr_in6 *)
+						&spc->spc_aaddr;
+					ap = inet_ntop(AF_INET6,
+						       &sin6->sin6_addr,
+						       addrbuf,
+						       INET6_ADDRSTRLEN);
+				}
+				DEBUG_PRINT(DEBUG_MAX,
+					    "\t\t(peer_addr_change: %s "
+					    "state=%d, error=%d)\n",
+					    ap, spc->spc_state,
+					    spc->spc_error);
+				break;
+			case SCTP_SEND_FAILED:
+				ssf = &snp->sn_send_failed;
+				DEBUG_PRINT(DEBUG_MIN,
+					    " SCTP_SEND_FAILED\n");
+				DEBUG_PRINT(DEBUG_MAX,
+					    "\t\t(sendfailed: len=%hu "
+					    "err=%d)\n",
+					    ssf->ssf_length, ssf->ssf_error);
+				break;
+			case SCTP_REMOTE_ERROR:
+				sre = &snp->sn_remote_error;
+				DEBUG_PRINT(DEBUG_MIN,
+					    " SCTP_REMOTE_ERROR\n");
+				DEBUG_PRINT(DEBUG_MAX,
+					    "\t\t(remote_error: err=%hu)\n",
+					     ntohs(sre->sre_error));
+				break;
+			case SCTP_SHUTDOWN_EVENT:
+				DEBUG_PRINT(DEBUG_MIN,
+					    " SCTP_SHUTDOWN_EVENT\n");
+				break;
+			default:
+				DEBUG_PRINT(DEBUG_MIN,
+					    " Unknown type: %hu\n",
+					    snp->sn_header.sn_type);
+				break;
+		}
+
+		fflush(stdout);
+		return 1;
+
+        } /* notification received */
+
+        for (scmsg = CMSG_FIRSTHDR(msg);
+             scmsg != NULL;
+             scmsg = CMSG_NXTHDR(msg, scmsg)) {
+
+		data = (sctp_cmsg_data_t *)CMSG_DATA(scmsg);
+		if (debug_level) print_cmsg(scmsg->cmsg_type, data);
+	}
+
+
+	fflush(stdout);
+        return 0;
+
+} /* print_message() */
+
+struct sockaddr *
+append_addr(const char *parm, struct sockaddr *addrs, int *ret_count)
+{
+	struct sockaddr *new_addrs = NULL;
+	void *aptr;
+	struct sockaddr *sa_addr;
+	struct sockaddr_in *b4ap;
+	struct sockaddr_in6 *b6ap;
+	struct hostent *hst4 = NULL;
+	struct hostent *hst6 = NULL;
+	int i4 = 0;
+	int i6 = 0;
+	int j;
+	int orig_count = *ret_count;
+	int count = orig_count;
+	char *ipaddr = strdup(parm);
+	char *ifname;
+	int ifindex = 0;
+
+	/* check the interface. */
+	ifname = strchr(ipaddr,'%');
+	if (ifname) {
+		*ifname=0;
+		ifname++;
+		ifindex = if_nametoindex(ifname);
+		if (!ifindex) {
+			fprintf(stderr, "bad interface name: %s\n", ifname);
+			goto finally;
+		}
+	}
+
+	/* Get the entries for this host.  */
+	hst4 = gethostbyname(ipaddr);
+	hst6 = gethostbyname2(ipaddr, AF_INET6);
+
+	if ((NULL == hst4 || hst4->h_length < 1)
+	    && (NULL == hst6 || hst6->h_length < 1)) {
+		fprintf(stderr, "bad hostname: %s\n", ipaddr);
+		goto finally;
+	}
+
+	/* Figure out the number of addresses.  */
+	if (NULL != hst4) {
+		for (i4 = 0; NULL != hst4->h_addr_list[i4]; ++i4) {
+			count++;
+		}
+	}
+	if (NULL != hst6) {
+		for (i6 = 0; NULL != hst6->h_addr_list[i6]; ++i6) {
+			count++;
+		}
+	}
+
+	/* Expand memory for the new addresses.  Assume all the addresses
+	 * are v6 addresses.
+	 */
+	new_addrs = (struct sockaddr *)
+		realloc(addrs, sizeof(struct sockaddr_in6) * count);
+
+	if (NULL == new_addrs) {
+		count = *ret_count;
+		goto finally;
+	}
+
+	/* Skip the existing addresses. */
+	aptr = new_addrs;
+	for (j = 0; j < orig_count; j++) {
+		sa_addr = (struct sockaddr *)aptr;
+		switch(sa_addr->sa_family) {
+		case AF_INET:
+			aptr += sizeof(struct sockaddr_in);
+			break;
+		case AF_INET6:
+			aptr += sizeof(struct sockaddr_in6);
+			break;
+		default:
+			count = orig_count;
+			goto finally;
+		}
+	}
+
+	/* Put the new addresses away.  */
+	if (NULL != hst4) {
+		for (j = 0; j < i4; ++j) {
+			b4ap = (struct sockaddr_in *)aptr;
+			memset(b4ap, 0x00, sizeof(*b4ap));
+			b4ap->sin_family = AF_INET;
+			b4ap->sin_port = htons(local_port);
+			bcopy(hst4->h_addr_list[j], &b4ap->sin_addr,
+			      hst4->h_length);
+
+			aptr += sizeof(struct sockaddr_in);
+		} /* for (loop through the new v4 addresses) */
+	}
+
+	if (NULL != hst6) {
+		for (j = 0; j < i6; ++j) {
+			b6ap = (struct sockaddr_in6 *)aptr;
+			memset(b6ap, 0x00, sizeof(*b6ap));
+			b6ap->sin6_family = AF_INET6;
+			b6ap->sin6_port =  htons(local_port);
+			b6ap->sin6_scope_id = if_index;
+			bcopy(hst6->h_addr_list[j], &b6ap->sin6_addr,
+			      hst6->h_length);
+			if (!ifindex) {
+				b6ap->sin6_scope_id = ifindex;
+			}
+
+			aptr += sizeof(struct sockaddr_in6);
+		} /* for (loop through the new v6 addresses) */
+	}
+
+ finally:
+	free(ipaddr);
+	*ret_count = count;
+
+	return new_addrs;
+
+} /* append_addr() */
+
+int socket_r(void)
+{
+	struct sctp_event_subscribe subscribe;
+	int sk, error;
+
+	DEBUG_PRINT(DEBUG_MIN, "\tsocket(%s, IPPROTO_SCTP)",
+		(socket_type == SOCK_SEQPACKET) ? "SOCK_SEQPACKET" : "SOCK_STREAM");
+
+	if ((sk = socket(s_loc.ss_family, socket_type, IPPROTO_SCTP)) < 0 ) {
+		if (do_exit) {
+			fprintf(stderr, "\n\n\t\t*** socket: failed to create"
+				" socket:  %s ***\n",
+        	       	        strerror(errno));
+			exit(1);
+		} else {
+			return -1;
+		}
+	}
+	DEBUG_PRINT(DEBUG_MIN, "  ->  sk=%d\n", sk);
+
+	memset(&subscribe, 0, sizeof(subscribe));
+	subscribe.sctp_data_io_event = 1;
+	subscribe.sctp_association_event = 1;
+	error = setsockopt(sk, SOL_SCTP, SCTP_EVENTS, (char *)&subscribe,
+			   sizeof(subscribe));
+	if (error) {
+		fprintf(stderr, "SCTP_EVENTS: error: %d\n", error);
+		exit(1);
+	}
+        if (max_stream > 0) {
+        	struct sctp_initmsg initmsg;
+        	memset(&initmsg, 0, sizeof(struct sctp_initmsg));
+        	initmsg.sinit_num_ostreams = max_stream;
+        	error = setsockopt(sk, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, sizeof(struct sctp_initmsg));
+        	if (error) {
+        		fprintf(stderr, "SCTP_INITMSG: error: %d\n", error);
+        		exit(1);
+        	}
+        }
+	return sk;
+
+} /* socket_r() */
+
+int bind_r(int sk, struct sockaddr_storage *saddr)
+{
+        int error = 0, i = 0;
+	char *host_s, *serv_s;
+
+	if ((host_s = malloc(NI_MAXHOST)) == NULL) {
+		fprintf(stderr, "\n\t\t*** host_s malloc failed!!! ***\n");
+		exit(1);
+	}
+	if ((serv_s = malloc(NI_MAXSERV)) == NULL) {
+		fprintf(stderr, "\n\t\t*** serv_s malloc failed!!! ***\n");
+		exit(1);
+	}
+
+	do {
+		if (i > 0) sleep(1); /* sleep a while before new try... */
+
+		error = getnameinfo((struct sockaddr *)saddr, l_len, host_s,
+				    NI_MAXHOST, serv_s, NI_MAXSERV,
+				    NI_NUMERICHOST);
+
+		if (error)
+			printf("%s\n", gai_strerror(error));
+
+       		DEBUG_PRINT(DEBUG_MIN,
+			    "\tbind(sk=%d, [a:%s,p:%s])  --  attempt %d/%d\n",
+       			    sk, host_s, serv_s, i+1, MAX_BIND_RETRYS);
+
+       		error = bind(sk, (struct sockaddr *)saddr, l_len);
+
+	        if (error != 0) {
+	        	if( errno != EADDRINUSE ) {
+	        		if (do_exit) {
+	        		        fprintf(stderr, "\n\n\t\t***bind: can "
+						"not bind to %s:%s: %s ****\n",
+						host_s, serv_s,
+						strerror(errno));
+					exit(1);
+				} else {
+					return -1;
+				}
+			}
+		}
+		i++;
+		if (i >= MAX_BIND_RETRYS) {
+			fprintf(stderr, "Maximum bind() attempts. "
+				"Die now...\n\n");
+			exit(1);
+		}
+        } while (error < 0 && i < MAX_BIND_RETRYS);
+
+	free(host_s);
+	free(serv_s);
+	return 0;
+
+} /* bind_r() */
+
+int
+bindx_r(int sk, struct sockaddr *addrs, int count, int flag)
+{
+	int error;
+	int i;
+	struct sockaddr *sa_addr;
+	void *aptr;
+
+	/* Set the port in every address.  */
+	aptr = addrs;
+	for (i = 0; i < count; i++) {
+		sa_addr = (struct sockaddr *)aptr;
+
+		switch(sa_addr->sa_family) {
+		case AF_INET:
+			((struct sockaddr_in *)sa_addr)->sin_port =
+				htons(local_port);
+			aptr += sizeof(struct sockaddr_in);
+			break;
+		case AF_INET6:
+			((struct sockaddr_in6 *)sa_addr)->sin6_port =
+				htons(local_port);
+			aptr += sizeof(struct sockaddr_in6);
+			break;
+		default:
+			fprintf(stderr, "Invalid address family\n");
+			exit(1);
+		}
+	}
+
+	error = sctp_bindx(sk, addrs, count, flag);
+	if (error != 0) {
+		fprintf(stderr, "\n\n\t\t***bindx_r: error adding addrs:"
+			" %s. ***\n", strerror(errno));
+		exit(1);
+	}
+
+	return 0;
+
+} /* bindx_r() */
+
+int listen_r(int sk, int listen_count)
+{
+	int error = 0;
+	
+        DEBUG_PRINT(DEBUG_MIN, "\tlisten(sk=%d,backlog=%d)\n",
+		    sk, listen_count);
+
+ 	/* Mark sk as being able to accept new associations */
+        error = listen(sk, listen_count);
+        if (error != 0) {
+        	if (do_exit) {
+                	fprintf(stderr, "\n\n\t\t*** listen:  %s ***\n\n\n",
+                       		strerror(errno));
+			exit(1);
+		}
+		else return -1;
+        }
+        return 0;
+
+} /* listen_r() */
+
+int accept_r(int sk){
+	socklen_t len = 0;
+	int subsk;
+
+	DEBUG_PRINT(DEBUG_MIN, "\taccept(sk=%d)\n", sk);
+
+	subsk = accept(sk, NULL, &len);
+	if (subsk < 0) {
+		fprintf(stderr, "\n\n\t\t*** accept:  %s ***\n\n\n", strerror(errno));
+		exit(1);
+	}
+
+	return subsk;
+} /* accept_r() */
+
+int connect_r(int sk, const struct sockaddr *serv_addr, socklen_t addrlen)
+{
+	int error = 0;
+
+	DEBUG_PRINT(DEBUG_MIN, "\tconnect(sk=%d)\n", sk);
+
+	/* Mark sk as being able to accept new associations */
+	error = connect(sk, serv_addr, addrlen);
+	if (error != 0) {
+		if (do_exit) {
+			fprintf(stderr, "\n\n\t\t*** connect:  %s ***\n\n\n",
+				strerror(errno));
+			exit(1);
+		}
+		else return -1;
+	}
+	return 0;
+
+} /* connect_r() */
+
+int connectx_r(int sk, struct sockaddr *addrs, int count)
+{
+	int error;
+	int i;
+	struct sockaddr *sa_addr;
+	void *aptr;
+
+	/* Set the port in every address.  */
+	aptr = addrs;
+	for (i = 0; i < count; i++) {
+		sa_addr = (struct sockaddr *)aptr;
+
+		switch(sa_addr->sa_family) {
+		case AF_INET:
+			((struct sockaddr_in *)sa_addr)->sin_port =
+				htons(remote_port);
+			aptr += sizeof(struct sockaddr_in);
+			break;
+		case AF_INET6:
+			((struct sockaddr_in6 *)sa_addr)->sin6_port =
+				htons(remote_port);
+			aptr += sizeof(struct sockaddr_in6);
+			break;
+		default:
+			fprintf(stderr, "Invalid address family\n");
+			exit(1);
+		}
+	}
+
+	error = sctp_connectx(sk, addrs, count, NULL);
+	if (error != 0) {
+		fprintf(stderr, "\n\n\t\t*** connectx_r: error connecting"
+			" to addrs: %s ***\n", strerror(errno));
+		exit(1);
+	}
+
+	return 0;
+
+} /* connectx_r() */
+
+int receive_r(int sk, int once)
+{
+	int recvsk = sk, i = 0, error = 0;
+        char incmsg[CMSG_SPACE(sizeof(_sctp_cmsg_data_t))];
+        struct iovec iov;
+        struct msghdr inmessage;
+
+        /* Initialize inmessage with enough space for DATA... */
+        memset(&inmessage, 0, sizeof(inmessage));
+        if ((iov.iov_base = malloc(REALLY_BIG)) == NULL) {
+		fprintf(stderr, "\n\t\t*** malloc not enough memory!!! ***\n");
+		exit(1);
+	}
+	iov.iov_len = REALLY_BIG;
+	inmessage.msg_iov = &iov;
+	inmessage.msg_iovlen = 1;
+	/* or a control message.  */
+	inmessage.msg_control = incmsg;
+	inmessage.msg_controllen = sizeof(incmsg);
+
+	/* Get the messages sent */
+	while (1) {
+
+		if (recvsk == sk && socket_type == SOCK_STREAM &&
+		    role == SERVER)
+			recvsk = accept_r(sk);
+
+		DEBUG_PRINT(DEBUG_MIN, "\trecvmsg(sk=%d) ", sk);
+
+		error = recvmsg(recvsk, &inmessage, MSG_WAITALL);
+		if (error < 0 && errno != EAGAIN) {
+			if (errno == ENOTCONN && socket_type == SOCK_STREAM &&
+			    role == SERVER) {
+				printf("No association is present now!!\n");
+				close(recvsk);
+				recvsk = sk;
+				continue;
+			}
+
+			fprintf(stderr, "\n\t\t*** recvmsg: %s ***\n\n",
+					strerror(errno));
+			fflush(stdout);
+			if (do_exit) exit(1);
+			else goto error_out;
+		}
+		else if (error == 0) {
+			if (socket_type == SOCK_STREAM && role == SERVER) {
+				printf("No association is present now!!\n");
+				close(recvsk);
+				recvsk = sk;
+				continue;
+			}
+			printf("\n\t\trecvmsg() returned 0 !!!!\n");
+			fflush(stdout);
+		}
+
+		if (print_message(recvsk, &inmessage, error) > 0)
+			continue; /* got a notification... */
+
+		inmessage.msg_control = incmsg;
+		inmessage.msg_controllen = sizeof(incmsg);
+		iov.iov_len = REALLY_BIG;
+		i++;
+		if (once)
+			break;
+	}
+
+	if (recvsk != sk)
+		close(recvsk);
+
+	free(iov.iov_base);
+	return 0;
+error_out:
+	close(sk);
+	free(iov.iov_base);
+	return -1;
+
+} /* receive_r () */
+
+int next_order(int state, int pattern)
+{
+	switch (pattern){
+	case ORDER_PATTERN_UNORDERED:
+		state = 0;
+		break;
+	case ORDER_PATTERN_ORDERED:
+		state = 1;
+		break;
+	case ORDER_PATTERN_ALTERNATE:
+		state = state ? 0 : 1;
+		break;
+	case ORDER_PATTERN_RANDOM:
+		state = rand() % 2;
+		break;
+	}
+
+	return state;
+}
+
+int next_stream(int state, int pattern)
+{
+	switch (pattern){
+	case STREAM_PATTERN_RANDOM:
+		state = rand() % (max_stream == 0 ? 1 : max_stream);
+		break;
+	case STREAM_PATTERN_SEQUENTIAL:
+		state = state + 1;
+		if (state >= max_stream)
+			state = 0;
+		break;
+	}
+
+	return state;
+}
+
+int next_msg_size(int msg_cnt)
+{
+	int msg_size;
+
+	if (size_arg) {
+		msg_size = size_arg;
+	} else if (test_case < NCASES) {
+		msg_size = msg_sizes[test_case][msg_cnt];
+	} else {
+		msg_size = (rand() % max_msgsize) + 1;
+	}
+
+	return msg_size;
+
+} /* next_msg_size() */
+
+int next_assoc(int i, int state, int pattern)
+{
+	int j;
+	int found = 0;
+	_assoc_state *as;
+
+
+	switch (pattern){
+	case ASSOC_PATTERN_RANDOM:
+		state = rand() % tosend;
+		break;
+	case ASSOC_PATTERN_SEQUENTIAL:
+		state = state + 1;
+		if (state >= tosend)
+			state = 0;
+		break;
+	}
+
+	as = poll_sks[i].assoc_state;
+	j = state;
+	do {
+		if (as[j].msg_sent < repeat_count) {
+			found = 1;
+			break;
+		}
+		if (++j >= tosend) {
+			j = 0;
+		}
+	} while (j != state);
+
+	if (found) {
+		return j;
+	} else {
+		return -1;
+	}
+	
+} /* next_assoc() */
+
+int send_r(int sk, int stream, int order, int send_size, int assoc_i)
+{
+	int error = 0;
+	struct msghdr outmsg;
+	struct iovec iov;
+	char *message = NULL;
+	int msglen = 0;
+	char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+	struct cmsghdr *cmsg;
+	struct sctp_sndrcvinfo *sinfo;
+
+	if (send_size > 0) {
+		message = build_msg(send_size);
+		msglen = strlen(message) + 1;
+		iov.iov_base = message;
+		iov.iov_len = msglen;
+	}
+	else {
+		if (do_exit) {
+			exit(1);
+		} else {
+			goto error_out;
+		}
+	}
+
+	outmsg.msg_name = &s_rem;
+       	outmsg.msg_namelen = sizeof(struct sockaddr_storage);
+	outmsg.msg_iov = &iov;
+	outmsg.msg_iovlen = 1;
+	outmsg.msg_control = outcmsg;
+	outmsg.msg_controllen = sizeof(outcmsg);
+	outmsg.msg_flags = 0;
+
+	cmsg = CMSG_FIRSTHDR(&outmsg);
+	cmsg->cmsg_level = IPPROTO_SCTP;
+	cmsg->cmsg_type = SCTP_SNDRCV;
+	cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+
+	outmsg.msg_controllen = cmsg->cmsg_len;
+	sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+	memset(sinfo, 0, sizeof(struct sctp_sndrcvinfo));
+	sinfo->sinfo_ppid = rand();
+	sinfo->sinfo_stream = stream;
+	sinfo->sinfo_flags = 0;
+	if (!order)
+		sinfo->sinfo_flags = SCTP_UNORDERED;
+	if (timetolive)
+		sinfo->sinfo_timetolive = timetolive;
+
+	DEBUG_PRINT(DEBUG_MIN, "\tsendmsg(sk=%d, assoc=%d) %4d bytes.\n",
+		    sk, assoc_i, send_size);
+	DEBUG_PRINT(DEBUG_MAX, "\t  SNDRCV");
+	if (DEBUG_MAX == debug_level) {
+        	printf("(stream=%u ", 	sinfo->sinfo_stream);
+		printf("flags=0x%x ",	sinfo->sinfo_flags);
+		printf("ppid=%u\n",	sinfo->sinfo_ppid);
+	}
+
+	/* Send to our neighbor.  */
+	error = sendmsg(sk, &outmsg, MSG_WAITALL);
+	if (error != msglen) {
+		fprintf(stderr, "\n\t\t*** sendmsg: %s ***\n\n",
+			strerror(errno));
+		fflush(stdout);
+	
+		if (do_exit) {
+			exit(1);
+		} else {
+			if (!drain)
+				goto error_out;
+		}
+	}
+
+	if (send_size > 0) free(message);
+	return 0;
+error_out:
+	if (send_size > 0) free(message);
+	return -1;
+
+} /* send_r() */
+
+int close_r(int sk)
+{
+	int error = 0;
+	
+	DEBUG_PRINT(DEBUG_MIN, "\tclose(sk=%d)\n",sk);
+
+	error = close(sk);
+	if (error != 0) {
+		if (do_exit) {
+			fprintf(stderr, "\n\n\t\t*** close: %s ***\n\n",
+				strerror(errno));
+			exit(1);
+		} else {
+			return -1;
+		}
+	}
+	fflush(stdout);
+	return 0;
+
+} /* close_r() */
+
+void
+server(int sk)
+{
+	if (max_msgsize > DEFAULT_MAX_WINDOW) {
+		if (setsockopt(sk, SOL_SOCKET, SO_RCVBUF, &max_msgsize,
+			       sizeof(max_msgsize)) < 0) {
+			perror("setsockopt(SO_RCVBUF)");
+			exit(1);
+		} 	
+	}
+
+	receive_r(sk, 0);
+
+} /* server() */
+
+void
+client(int sk)
+{
+	int msg_size;
+	int i;
+
+	for (i = 0; i < msg_cnt; i++) {
+
+		msg_size = next_msg_size(i);
+		order_state = next_order(order_state, order_pattern);
+		stream_state = next_stream(stream_state, stream_pattern);
+
+		if (send_r(sk, stream_state, order_state, msg_size, 0) < 0)
+			break;
+		/* The sender is echoing so do discard the echoed data. */
+		if (drain) {
+			receive_r(sk, 1);
+		}
+	}
+} /* client() */
+
+void
+mixed_mode_test(void)
+{
+	int error, i, j, max_fd, sks, size;
+	int assoc_i, n_msg_size, n_order, n_stream;
+	int done = 0;
+	fd_set *ibitsp = NULL, *obitsp = NULL, *xbitsp = NULL;
+        char incmsg[CMSG_SPACE(sizeof(_sctp_cmsg_data_t))];
+        struct iovec iov;
+        struct msghdr inmessage;
+	_assoc_state *as;
+
+	
+	/* Set up the listeners.  If listeners is 0, set up one socket for
+	 * transmitting only.
+	 */
+	iov.iov_base = NULL;
+	max_fd = -1;
+	sks = (0 == listeners) ? 1 : listeners;
+	memset(poll_sks, 0, sks * sizeof(_poll_sks));
+
+	for (i = 0; i < sks; i++) {
+		poll_sks[i].sk = socket_r();
+
+		if (s_loc.ss_family == AF_INET6)
+			( (struct sockaddr_in6 *)&s_loc)->sin6_port =
+				htons(local_port + i);
+		else
+			( (struct sockaddr_in *)&s_loc)->sin_port =
+				htons(local_port + i);
+
+		bind_r(poll_sks[i].sk, &s_loc);
+		if (listeners) {
+			listen_r(poll_sks[i].sk, 100);
+		}
+		if (max_msgsize > DEFAULT_MAX_WINDOW) {
+			if (setsockopt(poll_sks[i].sk, SOL_SOCKET, SO_RCVBUF,
+				&max_msgsize, sizeof(max_msgsize)) < 0) {
+				perror("setsockopt(SO_RCVBUF)");
+				exit(1);
+			}
+		} 	
+
+		if (tosend) {
+			if ((poll_sks[i].assoc_state = (_assoc_state *)malloc(
+				sizeof(_assoc_state) * tosend)) == NULL) {
+				printf("Can't allocate memory.\n");
+				goto clean_up;
+			}
+			memset(poll_sks[i].assoc_state, 0,
+				sizeof(_assoc_state) * tosend);
+		}
+
+		if (poll_sks[i].sk > max_fd) {
+			max_fd = poll_sks[i].sk;
+		}
+	}
+
+	size = howmany(max_fd + 1, NFDBITS) * sizeof(fd_mask);
+	if ((ibitsp = (fd_set *)malloc(size)) == NULL) {
+		printf("Can't allocate memory.\n");
+		goto clean_up;
+	}
+	if ((obitsp = (fd_set *)malloc(size)) == NULL) {
+		printf("Can't allocate memory.\n");
+		goto clean_up;
+	}
+	if ((xbitsp = (fd_set *)malloc(size)) == NULL) {
+		printf("Can't allocate memory.\n");
+		goto clean_up;
+	}
+
+	memset(ibitsp, 0, size);
+	memset(obitsp, 0, size);
+	memset(xbitsp, 0, size);
+
+
+        /* Initialize inmessage with enough space for DATA... */
+        memset(&inmessage, 0, sizeof(inmessage));
+        if ((iov.iov_base = malloc(REALLY_BIG)) == NULL) {
+		fprintf(stderr, "\n\t\t*** malloc not enough memory!!! ***\n");
+		goto clean_up;
+	}
+	iov.iov_len = REALLY_BIG;
+	inmessage.msg_iov = &iov;
+	inmessage.msg_iovlen = 1;
+	/* or a control message.  */
+	inmessage.msg_control = incmsg;
+	inmessage.msg_controllen = sizeof(incmsg);
+
+	/* Set up the remote port number per association for output.  */
+	for (i = 0; i < sks; i++) {
+		as = poll_sks[i].assoc_state;
+		for (j = 0; j < tosend; j++) {
+			as[j].rem_port = remote_port + j;
+		}
+	}
+
+	while (!done) {
+
+		for (i = 0; i < sks; i++) {
+			FD_SET(poll_sks[i].sk, ibitsp);
+			FD_SET(poll_sks[i].sk, obitsp);
+			FD_SET(poll_sks[i].sk, xbitsp);
+		}
+		if ((error = select(max_fd + 1, ibitsp, obitsp, xbitsp,
+			(struct timeval *)0)) < 0) {
+			fprintf(stderr, "\n\t\t*** select() failed ");
+			fprintf(stderr, "with error: %s\n\n",
+				strerror(errno));
+			fflush(stdout);
+			goto clean_up;
+		}
+		
+		for (i = 0; i < sks; i++) {
+			/* Is there anything to read from the socket?  */
+			if (listeners && FD_ISSET(poll_sks[i].sk, ibitsp)) {
+
+				FD_CLR(poll_sks[i].sk, ibitsp);
+				error = recvmsg(poll_sks[i].sk, &inmessage,
+					MSG_WAITALL);
+				if (error < 0) {
+					fprintf(stderr,
+						"\n\t\t*** recvmsg: %s ***\n\n",
+						strerror(errno));
+					fflush(stdout);
+					goto clean_up;
+				}
+				else if (error == 0) {
+					printf("\n\t\trecvmsg() returned ");
+				       	printf("0 !!!!\n");
+					fflush(stdout);
+				}
+
+				print_message(poll_sks[i].sk, &inmessage,
+					error);
+
+				inmessage.msg_control = incmsg;
+				inmessage.msg_controllen = sizeof(incmsg);
+				iov.iov_len = REALLY_BIG;
+			}
+			
+			/* Is this socket writeable?  */
+			if (tosend && FD_ISSET(poll_sks[i].sk, obitsp)) {
+
+				FD_CLR(poll_sks[i].sk, obitsp);
+
+				/* Pick an association.  */
+				assoc_i = next_assoc(i, poll_sks[i].assoc_i,
+						assoc_pattern);
+				if (assoc_i < 0) {
+					/* No work to do on any associations.
+					 * We are probably done. */
+					if (!listeners) {
+						done = 1;
+					}
+					continue;
+				}
+				poll_sks[i].assoc_i = assoc_i;
+
+				as = poll_sks[i].assoc_state;
+				n_msg_size = next_msg_size(as[assoc_i].msg_cnt);
+				n_order = as[assoc_i].order_state =
+					next_order(as[assoc_i].order_state,
+					order_pattern);
+				n_stream = as[assoc_i].stream_state =
+					next_stream(as[assoc_i].stream_state,
+					stream_pattern);
+
+				/* Set the destination port.  */
+				if (s_rem.ss_family == AF_INET6)
+					( (struct sockaddr_in6 *)&s_rem)->
+						sin6_port =
+						htons(as[assoc_i].rem_port);
+				else
+					( (struct sockaddr_in *)&s_rem)->
+						sin_port =
+						htons(as[assoc_i].rem_port);
+
+				/* Send a message thru the association.  */
+				if (send_r(poll_sks[i].sk, n_stream, n_order,
+					n_msg_size, assoc_i) < 0) {
+					/* Don't increment counter if there
+					 * is a problem of sending.
+					 */
+					continue;
+				}
+
+				/* Increment counters. */
+				if (++as[assoc_i].msg_cnt >= MSG_CNT) {
+					as[assoc_i].msg_cnt = 0;
+				}
+				if (++as[assoc_i].msg_sent >=
+					repeat_count) {
+					fprintf(stderr, "Association #%d in ",
+						assoc_i);
+					fprintf(stderr, "sk=%d has ",
+						poll_sks[i].sk);
+					fprintf(stderr, "completed %d msg as ",
+						as[assoc_i].msg_sent);
+					fprintf(stderr, "cycle %d.\n",
+						++as[assoc_i].cycle);
+
+					/* In the mixed mode, -x not only
+					 * specify the longer repeat cycle,
+					 * but it also mean to run the test
+					 * forever.
+					 */
+					if (xflag) {
+						as[assoc_i].msg_sent = 0;
+					}
+
+				}
+
+			}
+		}
+	}
+
+clean_up:
+	for (i = 0; i < sks; i++) {
+		close(poll_sks[i].sk);
+		if (poll_sks[i].assoc_state) {
+			free(poll_sks[i].assoc_state);
+		}
+	}
+
+	if (ibitsp) free(ibitsp);
+	if (obitsp) free(obitsp);
+	if (xbitsp) free(xbitsp);
+
+	if (iov.iov_base) free(iov.iov_base);
+
+} /* mixed_mode_test() */
+
+void start_test(int role)
+{
+	int sk;
+	int i = 0;
+	
+	DEBUG_PRINT(DEBUG_NONE, "\nStarting tests...\n");
+
+	repeat_count = repeat;
+
+
+	if (MIXED == role) {
+		repeat_count = repeat_count * msg_cnt;  /* Repeat per assoc. */
+		mixed_mode_test();
+		return;
+	}
+
+	sk = socket_r();
+	if (sk < 0) {
+		DEBUG_PRINT(DEBUG_NONE, "\nSocket create err %d\n", errno);
+		return;
+	}
+
+	if (bind_r(sk, &s_loc) == -1) {
+		DEBUG_PRINT(DEBUG_NONE, "\nSocket bind err %d\n", errno);
+		return;
+	}
+
+	/* Do we need to do bindx() to add any additional addresses? */
+	if (bindx_add_addrs)
+		bindx_r(sk, bindx_add_addrs, bindx_add_count,
+			   SCTP_BINDX_ADD_ADDR);
+
+	if (role == SERVER) {
+		listen_r(sk, 100);
+	} else {
+		if (socket_type == SOCK_STREAM && connectx_count == 0)
+			connect_r(sk, (struct sockaddr *)&s_rem, r_len);
+
+		if (connectx_count != 0)
+			connectx_r(sk, connectx_addrs, connectx_count);
+	}
+
+	if (!debug_level) {
+		printf("     ");
+	}
+
+	for(i = 0; i < repeat_count; i++) {
+		
+		if (role == SERVER) {
+			DEBUG_PRINT(DEBUG_NONE,
+				    "Server: Receiving packets.\n");
+			server(sk);
+		} else {
+			DEBUG_PRINT(DEBUG_NONE,
+				    "Client: Sending packets.(%d/%d)\n",
+		    		    i+1, repeat_count);
+			client(sk);
+		}
+
+		fflush(stdout);
+	}
+
+	close_r(sk);
+
+} /* start_test() */
+
+int
+main(int argc, char *argv[])
+{
+	int c;
+	char *interface = NULL;
+	struct sockaddr_in *t_addr;
+	struct sockaddr_in6 *t_addr6;
+	struct sockaddr *tmp_addrs = NULL;
+	
+        /* Parse the arguments.  */
+        while ((c = getopt(argc, argv, ":H:L:P:S:a:h:p:c:d:lm:sx:X:o:t:M:r:w:Di:TB:C:O:")) >= 0 ) {
+
+                switch (c) {
+		case 'H':
+			local_host = optarg;
+			break;
+		case 'L':
+			role = MIXED;
+			listeners = atoi(optarg);
+			if (listeners > MAX_POLL_SKS) {
+				usage(argv[0]);
+				exit(1);
+			}
+			break;
+		case 'P':
+			local_port = atoi(optarg);
+			break;
+		case 'S':
+			role = MIXED;
+			tosend = atoi(optarg);
+			if (tosend > MAX_POLL_SKS) {
+				usage(argv[0]);
+				exit(1);
+			}
+			break;
+		case 'a':
+			assoc_pattern = atoi(optarg);
+			if (assoc_pattern <  ASSOC_PATTERN_SEQUENTIAL
+			    || assoc_pattern > ASSOC_PATTERN_RANDOM ) {
+				usage(argv[0]);
+				exit(1);
+			}
+			break;
+		case 'h':
+			remote_host = optarg;
+			break;
+		case 'D':
+			drain = 1;
+			do_exit = 0;
+			break;
+		case 'p':
+			remote_port = atoi(optarg);
+			break;
+		case 's':
+			if (role != NOT_DEFINED) {
+				printf("%s: only -s or -l\n", argv[0]);
+				usage(argv[0]);
+				exit(1);
+			}
+			role = CLIENT;
+			break;
+		case 'l':
+			if (role != NOT_DEFINED) {
+				printf("%s: only -s or -l\n", argv[0]);
+				usage(argv[0]);
+				exit(1);
+			}
+			role = SERVER;
+			break;
+		case 'd':
+			debug_level = atoi(optarg);
+			if (debug_level < DEBUG_NONE
+			    || debug_level > DEBUG_MAX) {
+				usage(argv[0]);
+				exit(1);
+			}
+			break;
+		case 'x':
+			repeat = atoi(optarg);
+			if (!repeat) {
+				xflag = 1;
+				repeat = BIG_REPEAT;
+			}
+			break;
+		case 'X':
+			msg_cnt = atoi(optarg);
+			if ((msg_cnt <= 0) || (msg_cnt > MSG_CNT)) {
+				usage(argv[0]);
+				exit(1);
+			}
+			break;
+		case 'c':
+			test_case = atoi(optarg);
+			if (test_case > NCASES) {
+				usage(argv[0]);
+				exit(1);
+			}
+			if (test_case < 0) {
+				size_arg = -test_case;
+			}
+			
+			break;
+		case 'o':
+			order_pattern = atoi(optarg);
+			if (order_pattern <  ORDER_PATTERN_UNORDERED
+			    || order_pattern  > ORDER_PATTERN_RANDOM ) {
+				usage(argv[0]);
+				exit(1);
+			}
+			break;
+		case 'O':
+			timetolive = atoi(optarg);
+			if (timetolive < 0) {
+				usage(argv[0]);
+				exit(1);
+			}
+			break;
+		case 't':
+			stream_pattern = atoi(optarg);
+			if (stream_pattern <  STREAM_PATTERN_SEQUENTIAL
+			    || stream_pattern > STREAM_PATTERN_RANDOM ) {
+				usage(argv[0]);
+				exit(1);
+			}
+			break;
+		case 'M':
+			max_stream = atoi(optarg);
+			if (max_stream <  0
+			    || max_stream >= (1<<16)) {
+				usage(argv[0]);
+				exit(1);
+			}
+			break;
+		case 'r':
+			seed = atoi(optarg);
+			break;
+		case 'm':
+			max_msgsize = atoi(optarg);
+#if 0
+			if ((max_msgsize < DEFAULT_MIN_WINDOW) ||
+			    (max_msgsize > 65515)) {
+				usage(argv[0]);
+				exit(1);
+			}
+#endif
+			break;
+		case 'i':
+			interface = optarg;
+			if_index = if_nametoindex(interface);
+			if (!if_index) {
+				printf("Interface %s unknown\n", interface);
+				exit(1);
+			}
+			break;
+		case 'T':
+			socket_type = SOCK_STREAM;
+			break;
+		case 'B':
+			tmp_addrs = append_addr(optarg, bindx_add_addrs,
+						&bindx_add_count);
+			if (NULL == tmp_addrs) {
+				fprintf(stderr, "No memory to add ");
+				fprintf(stderr, "%s\n", optarg);
+				exit(1);
+			}
+			bindx_add_addrs = tmp_addrs;
+			break;
+		case 'C':
+			tmp_addrs = append_addr(optarg, connectx_addrs,
+						&connectx_count);
+			if (NULL == tmp_addrs) {
+				fprintf(stderr, "No memory to add ");
+				fprintf(stderr, "%s\n", optarg);
+				exit(1);
+			}
+			connectx_addrs = tmp_addrs;
+			break;
+		case '?':
+		default:
+			usage(argv[0]);
+			exit(0);
+		}
+	} /* while() */
+
+	if (NOT_DEFINED == role) {
+		usage(argv[0]);
+		exit(1);
+	}
+
+
+	if (SERVER == role && NULL == local_host && remote_host != NULL) {
+		fprintf (stderr, "%s: Server needs local address, "
+			 "not remote address\n", argv[0]);
+		usage(argv[0]);
+		exit(1);
+	}
+	if (CLIENT == role && NULL == remote_host && connectx_count == 0) {
+		fprintf (stderr, "%s: Client needs at least remote address "
+			 "& port\n", argv[0]);
+		usage(argv[0]);
+		exit(1);
+	}
+	if (MIXED == role) {
+		if (listeners && NULL == local_host) {
+			fprintf (stderr, "%s: Servers need local address\n",
+				argv[0]);
+			usage(argv[0]);
+			exit(1);
+		}
+		if (tosend && NULL == remote_host) {
+			fprintf (stderr, "%s: Clients need remote address ",
+				argv[0]);
+			fprintf (stderr, "& port\n");
+			usage(argv[0]);
+			exit(1);
+		}
+	}
+
+	if (optind < argc) {
+                fprintf(stderr, "%s: non-option arguments are illegal: ",
+                        argv[0]);
+                while (optind < argc)
+                        fprintf(stderr, "%s ", argv[optind++]);
+                fprintf (stderr, "\n");
+                usage(argv[0]);
+                exit(1);
+	}
+
+	if (remote_host != NULL && connectx_count != 0) {
+		fprintf(stderr, "%s: You can not provide both -h and -C options.\n",
+			argv[0]);
+		usage(argv[0]);
+		exit(1);
+	}
+
+	if (remote_host != NULL && remote_port != 0) {
+		struct addrinfo *res;
+		int error;
+		char *host_s, *serv_s;
+
+		if ((host_s = malloc(NI_MAXHOST)) == NULL) {
+			fprintf(stderr, "\n*** host_s malloc failed!!! ***\n");
+			exit(1);
+		}
+		if ((serv_s = malloc(NI_MAXSERV)) == NULL) {
+			fprintf(stderr, "\n*** serv_s malloc failed!!! ***\n");
+			exit(1);
+		}
+
+		error = getaddrinfo(remote_host, 0, NULL, &res);
+		if (error) {
+			printf("%s.\n", gai_strerror(error));
+			usage(argv[0]);
+			exit(1);
+		}
+
+		switch (res->ai_family) {
+			case AF_INET:
+				t_addr = (struct sockaddr_in *)&s_rem;
+
+				memcpy(t_addr, res->ai_addr,
+				       res->ai_addrlen);
+				t_addr->sin_family = res->ai_family;
+				t_addr->sin_port = htons(remote_port);
+
+				r_len = res->ai_addrlen;
+
+#ifdef __FreeBSD__
+				t_addr->sin_len = r_len;
+#endif
+				break;
+			case AF_INET6:
+
+				t_addr6 = (struct sockaddr_in6 *)&s_rem;
+				
+				memcpy(t_addr6, res->ai_addr,
+				       res->ai_addrlen);
+				t_addr6->sin6_family = res->ai_family;
+				t_addr6->sin6_port = htons(remote_port);
+				if (interface)
+					t_addr6->sin6_scope_id =
+						if_nametoindex(interface);
+
+				r_len = res->ai_addrlen;
+
+#ifdef __FreeBSD__
+				t_addr6->sin6_len = r_len;
+#endif
+				break;
+		}
+
+		getnameinfo((struct sockaddr *)&s_rem, r_len, host_s,
+			    NI_MAXHOST, serv_s, NI_MAXSERV, NI_NUMERICHOST);
+			
+		DEBUG_PRINT(DEBUG_MAX, "remote:addr=%s, port=%s, family=%d\n",
+			    host_s, serv_s, res->ai_family);
+
+		freeaddrinfo(res);
+        }
+
+	if (connectx_count != 0) {
+		switch (connectx_addrs->sa_family) {
+		case AF_INET:
+			t_addr = (struct sockaddr_in *)&s_rem;
+			r_len = sizeof(struct sockaddr_in);
+			memcpy(t_addr, connectx_addrs, r_len);
+			t_addr->sin_port = htons(remote_port);
+			break;
+		case AF_INET6:
+			t_addr6 = (struct sockaddr_in6 *)&s_rem;
+			r_len = sizeof(struct sockaddr_in6);
+			memcpy(t_addr6, connectx_addrs, r_len);
+			t_addr6->sin6_port = htons(remote_port);
+			break;
+		}
+	}
+
+	if (local_host != NULL) {
+		struct addrinfo *res;
+		int error;
+		char *host_s, *serv_s;
+		struct sockaddr_in *t_addr;
+		struct sockaddr_in6 *t_addr6;
+
+		if ((host_s = malloc(NI_MAXHOST)) == NULL) {
+			fprintf(stderr, "\n*** host_s malloc failed!!! ***\n");
+			exit(1);
+		}
+		if ((serv_s = malloc(NI_MAXSERV)) == NULL) {
+			fprintf(stderr, "\n*** serv_s malloc failed!!! ***\n");
+			exit(1);
+		}
+
+		if (strcmp(local_host, "0") == 0)
+			local_host = "0.0.0.0";
+
+		error = getaddrinfo(local_host, 0, NULL, &res);
+		if (error) {
+			printf("%s.\n", gai_strerror(error));
+			usage(argv[0]);
+			exit(1);
+		}
+
+		switch (res->ai_family) {
+			case AF_INET:
+				t_addr = (struct sockaddr_in *)&s_loc;
+				memcpy(t_addr, res->ai_addr,
+				       res->ai_addrlen);
+				t_addr->sin_family = res->ai_family;
+				t_addr->sin_port = htons(local_port);
+
+				l_len = res->ai_addrlen;
+
+#ifdef __FreeBSD__
+				t_addr->sin_len = l_len;
+#endif
+				break;
+			case AF_INET6:
+				t_addr6 = (struct sockaddr_in6 *)&s_loc;
+
+				memcpy(t_addr6, res->ai_addr,
+				       res->ai_addrlen);
+				t_addr6->sin6_family = res->ai_family;
+				t_addr6->sin6_port = htons(local_port);
+				if (interface)
+					t_addr6->sin6_scope_id =
+						if_nametoindex(interface);
+
+				l_len = res->ai_addrlen;
+
+#ifdef __FreeBSD__
+				t_addr6->sin6_len = l_len;
+#endif
+				break;
+		}
+
+		error = getnameinfo((struct sockaddr *)&s_loc, l_len, host_s,
+			    NI_MAXHOST, serv_s, NI_MAXSERV, NI_NUMERICHOST);
+
+		if (error)
+			printf("%s..\n", gai_strerror(error));
+
+		DEBUG_PRINT(DEBUG_MAX, "local:addr=%s, port=%s, family=%d\n",
+			    host_s, serv_s, res->ai_family);
+
+		freeaddrinfo(res);
+        }
+
+
+	/* A half-hearted attempt to seed rand() */
+	if (seed == 0 ) {
+		seed = time(0);
+		DEBUG_PRINT(DEBUG_NONE, "seed = %d\n", seed);	
+	}
+	
+	srand(seed);
+
+	/* Let the testing begin. */
+	start_test(role);
+
+	return 0;
+
+} /*  main() */
diff --git a/src/apps/sctp_xconnect.c b/src/apps/sctp_xconnect.c
new file mode 100644
index 0000000..6759c0e
--- /dev/null
+++ b/src/apps/sctp_xconnect.c
@@ -0,0 +1,579 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2003
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ *    Ryan Layer		<rmlayer@us.ibm.com>
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+#include <netdb.h>
+#include <getopt.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 1;
+int TST_CNT = 0;
+
+#define MAXHOSTNAME 64
+
+#define MAXCLIENTNUM 10000
+
+#define TRUE 1
+
+#define SERVER 1
+#define CLIENT 0
+#define NOT_DEFINED -1
+
+int mode = NOT_DEFINED;
+
+int	assoc_num,
+	remote_port,
+	local_port;
+int active = 0;
+
+char *local_host = NULL;
+char *remote_host = NULL;
+sockaddr_storage_t client_loop,
+		server_loop;
+struct hostent *hst;
+char big_buffer[REALLY_BIG];
+
+void usage(char *argv0);
+void parse_arguments(int argc, char*argv[]);
+void data_received(struct msghdr *inmessage, int len, int stream,
+                        int server_socket);
+int event_received(struct msghdr *inmessage, int assoc_num);
+void process_ready_sockets(int client_socket[], int assoc_num, fd_set *rfds);
+void server_mode(void);
+void client_mode(void);
+
+/* Print the syntax/usage */
+void usage(char *argv0)
+{
+	printf("usage: %s -H localhost -P localport -l|c [-h remotehost]\n"
+	       "\t\t[-p remoteport] [-a] [-n <cnt>]\n" 
+	       " -H\t\tspecify a local address.\n"
+	       " -P\t\tspecify the local port number to be used\n"
+	       " -l\t\trun in server mode.\n"
+	       " -c\t\trun in client mode.\n"
+	       " -h\t\tspecify the peer address.\n"
+	       " -p\t\tspecify the port number for the peer address.\n"
+	       " -a\t\tactively generate traffic with the server.\n"
+	       " -n\t\tspecify the number of associations to create.\n",
+	       argv0);
+}
+
+/* Parse command line options */
+void parse_arguments(int argc, char*argv[]) {
+	int c;
+
+	while ((c = getopt(argc, argv, ":H:P:ach:ln:p:")) >= 0) {
+		switch (c) {
+			case 'H':
+				local_host = optarg;
+				break;
+			case 'P':
+				local_port = atoi(optarg);
+				break;
+			case 'c':
+			    if (mode == NOT_DEFINED)
+					mode = CLIENT;
+				else {
+					usage(argv[0]);
+					exit(0);
+				}
+				break;
+			case 'a':
+				active = 1;
+				break;
+			case 'h':
+				remote_host = optarg;
+				break;
+			case 'l':
+			    if (mode == NOT_DEFINED)
+					mode = SERVER;
+				else {
+					usage(argv[0]);
+					exit(0);
+				}
+				break;
+			case 'n':
+				assoc_num = atoi(optarg);
+				break;
+			case 'p':
+				remote_port = atoi(optarg);
+				break;
+			default:
+				usage(argv[0]);
+				exit(0);
+		}
+	} /* while() */
+
+	if (mode == CLIENT) {
+		if (assoc_num) {
+			if (assoc_num > MAXCLIENTNUM) {
+				printf("The number of associations indicated "
+					"is greater than the");
+				printf("max number of associations "
+					"allowed(%d).", MAXCLIENTNUM);
+				usage(argv[0]);
+				exit(0);
+			}
+		} else
+			assoc_num = 1;
+
+		if (remote_host && remote_port) {
+			hst = gethostbyname(remote_host);
+
+			memcpy(&server_loop.v4.sin_addr, hst->h_addr_list[0],
+				   sizeof(server_loop.v4.sin_addr));
+
+			server_loop.v4.sin_family = AF_INET;
+server_loop.v4.sin_port = htons(remote_port);
+		} else {
+			printf("Remote host and remote port must be defined "
+				"in client mode\n");
+			usage(argv[0]);
+			exit(0);
+		}
+
+		if (local_host) {
+			hst = gethostbyname(local_host);
+
+			memcpy(&client_loop.v4.sin_addr, hst->h_addr_list[0],
+				   sizeof(client_loop.v4.sin_addr));
+		} else
+			client_loop.v4.sin_addr.s_addr = INADDR_ANY;
+
+		if (local_port)
+			client_loop.v4.sin_port = htons(local_port);
+		else
+			client_loop.v4.sin_port = 0;
+
+		client_loop.v4.sin_family = AF_INET;
+	} else if (mode == SERVER) {
+		if (active) {
+			printf("This option if for client use only");
+			usage(argv[0]);
+			exit(0);
+		}
+
+		if (remote_host || remote_port) {
+			printf("Remote values not needed in server mode.\n");
+			usage(argv[0]);
+			exit(0);
+		}
+
+		if (local_host) {
+			hst = gethostbyname(local_host);
+
+			memcpy(&server_loop.v4.sin_addr, hst->h_addr_list[0],
+				   sizeof(server_loop.v4.sin_addr));
+		} else
+			server_loop.v4.sin_addr.s_addr = INADDR_ANY;
+
+		if (local_port)
+			server_loop.v4.sin_port = htons(local_port);
+		else {
+			printf("Specify a local port in server mode.\n");
+			usage(argv[0]);
+			exit(0);
+		}
+
+		server_loop.v4.sin_family = AF_INET;
+	} else {
+		printf("Must assisgn a client or server mode.\n");
+		usage(argv[0]);
+		exit(0);
+	}
+} /* parse_arguments() */
+
+/* Handle data received */
+void data_received(struct msghdr *inmessage, int len, int stream, int socket) {
+
+	int ppid, error;
+	char *ping = "PING";
+
+	if (mode == SERVER) {
+		ppid = rand();
+
+		error = sctp_sendmsg(socket,
+				inmessage->msg_iov->iov_base,
+				len,
+				(struct sockaddr *)inmessage->msg_name,
+				inmessage->msg_namelen,
+				ppid,
+				0,
+				stream,
+				0, 0);
+
+		if (error < 0) {
+			printf("Send Failure: %s.\n", strerror(errno));
+			DUMP_CORE;
+		}
+	} else {
+		ppid = rand();
+
+		printf("Data Received by socket #: %d.\n", socket);
+		printf("\tMessage = %s\n",
+			(char *)inmessage->msg_iov->iov_base);
+
+		if (active) {
+			error = sctp_sendmsg(socket, ping, strlen(ping) + 1,
+					     (struct sockaddr *)&server_loop,
+					     sizeof(server_loop), ppid, 0,
+					     stream, 0, 0);
+			if (error < 0) {
+				printf("Send Failure: %s.\n",
+				       strerror(errno));
+				DUMP_CORE;
+			}
+		}
+	}
+}
+
+/* This will print what type of SCTP_ASSOC_CHANGE state that was received */
+void print_sctp_sac_state(struct msghdr *msg) {
+
+	char *data;
+	union sctp_notification *sn;
+
+	if (msg->msg_flags & MSG_NOTIFICATION) {
+		data = (char *)msg->msg_iov[0].iov_base;
+
+		sn = (union sctp_notification *)data;
+
+		switch (sn->sn_assoc_change.sac_state) {
+				case SCTP_COMM_UP:
+						printf("SCTP_COMM_UP\n");
+						break;
+				case SCTP_COMM_LOST:
+						printf("SCTP_COMM_LOST\n");
+						break;
+				case SCTP_RESTART:
+						printf("SCTP_RESTART");
+						break;
+				case SCTP_SHUTDOWN_COMP:
+						printf("SCTP_SHUTDOWN_COMP\n");
+						break;
+				case SCTP_CANT_STR_ASSOC:
+						printf("SCTP_CANT_STR_ASSOC\n");
+						break;
+				default:
+						break;
+		}
+	}
+} /* void print_sctp_sac_state() */
+
+/* Tests what type of MSG_NOTIFICATION has been received.
+* For now this fucntion only works with SCTP_ASSOC_CHANGE 
+* types, but can be easily expanded.
+*
+* Will return...
+* -1 if the msg_flags is not MSG_NOTIFICATION
+*  0 if the MSG_NOTIFICATION type differs from the type
+*       passed into the additional variable
+*  1 if the MSG_NOTIFICATION type matches the type
+*       passed into the additional variable
+*/
+int test_check_notification_type(struct msghdr *msg,
+	uint16_t sn_type,
+	uint32_t additional) {
+
+	char *data;
+	union sctp_notification *sn;
+
+	if (!(msg->msg_flags & MSG_NOTIFICATION)) {
+		return -1;
+	} else {
+
+		/* Fixup for testframe. */
+		data = (char *)msg->msg_iov[0].iov_base;
+
+		sn = (union sctp_notification *)data;
+
+		if (sn->sn_header.sn_type != sn_type)
+			return 0;
+		else if (sn->sn_header.sn_type == SCTP_ASSOC_CHANGE)
+			if (sn->sn_assoc_change.sac_state == additional)
+				return 1;
+		return 0;
+	}
+}
+
+/* Determine the type of event and make correct adjustments to the
+* association count
+*/
+int event_received(struct msghdr *inmessage, int assoc_num) {
+
+	int error;
+
+	printf("Event Received\n");
+
+	print_sctp_sac_state(inmessage);
+
+	if (mode == SERVER) {
+		/* Test type of Event */
+		error = test_check_notification_type(inmessage,
+						SCTP_ASSOC_CHANGE,
+						SCTP_COMM_UP);
+		if (error > 0) {
+			assoc_num++;
+			printf("Assosiation Established: count = %d.\n",
+				assoc_num);
+		} else {
+			error = test_check_notification_type(inmessage,
+							SCTP_ASSOC_CHANGE,
+							SCTP_SHUTDOWN_COMP);
+
+			if (error > 0) {
+				assoc_num--;
+				printf("Assosiation Shutdown: count = %d.\n",
+					assoc_num);
+			}
+		}
+	}
+	return assoc_num;
+}
+
+void server_mode() {
+	sockaddr_storage_t msgname;
+	int server_socket,
+		error,
+		stream;
+	int assoc_num =0;
+	struct msghdr inmessage;
+	struct iovec iov;
+	char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+
+
+	printf("Running in Server Mode...\n");
+
+	memset(&inmessage, 0, sizeof(inmessage));
+	iov.iov_base = big_buffer;
+	iov.iov_len = REALLY_BIG;
+	inmessage.msg_iov = &iov;
+	inmessage.msg_iovlen =1;
+	inmessage.msg_control = incmsg;
+	inmessage.msg_controllen = sizeof(incmsg);
+	inmessage.msg_name = &msgname;
+	inmessage.msg_namelen = sizeof (msgname);
+
+	stream = 1;
+
+	server_socket = socket(PF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+	if (server_socket < 0) {
+		printf("Socket Failure:  %s.\n", strerror(errno));
+		DUMP_CORE;
+	}
+
+	error = bind(server_socket, &server_loop.sa, sizeof(server_loop));
+	if (error != 0 ) {
+		printf("Bind Failure: %s.\n", strerror(errno));
+		DUMP_CORE;
+	}
+
+	error = listen(server_socket, 1);
+	if (error != 0) {
+		printf("Listen Failure: %s.\n", strerror(errno));
+		DUMP_CORE;
+	}
+	while (TRUE) {
+		error = recvmsg(server_socket, &inmessage, MSG_WAITALL);
+		if (error < 0) {
+			printf("Receive Failure: %s\n",
+			strerror(errno));
+		} else {
+		if (inmessage.msg_flags & MSG_NOTIFICATION)
+			assoc_num = event_received(&inmessage, assoc_num);
+		else
+			data_received(&inmessage, error, stream, server_socket);
+		}
+	}
+}
+
+void client_mode() {
+
+	int i, error, stream, max_socket = 0;
+	uint32_t ppid = 0;
+	int client_socket[assoc_num];
+	char *message = "Awake";
+	fd_set rfds;
+	struct timeval tv;
+
+        stream = 1;
+
+	printf("Running in Client Mode...\n");
+
+        /* Create the sockets */
+	for (i = 0; i < assoc_num; i++) {
+		client_socket[i] = socket(PF_INET, SOCK_SEQPACKET,
+					IPPROTO_SCTP);
+		if (client_socket[i] < 0 ){
+			printf("Socket Failure: %s.\n", strerror(errno));
+			DUMP_CORE;
+		}
+
+		if (local_port) {
+			error = bind(client_socket[i], &client_loop.sa,
+				sizeof(client_loop));
+			if (error < 0) {
+				printf("Bind Failure: %s\n", strerror(errno));
+				DUMP_CORE;
+			}
+		}
+
+		printf("Create Socket #: %d\n", client_socket[i]);
+
+		/* Connect to server and send initial message */
+		error = connect(client_socket[i], &server_loop.sa,
+						    sizeof(server_loop));
+		if (error < 0){
+			printf("Connect Failure: %s.\n", strerror(errno));
+			DUMP_CORE;
+		}
+
+		max_socket = client_socket[i];
+
+                ppid++;
+
+		/* Send initial message */
+		error = sctp_sendmsg(client_socket[i],
+				message,
+				strlen(message) + 1,
+				(struct sockaddr *)&server_loop,
+				sizeof(server_loop),
+				ppid,
+				0,
+				stream,
+				0, 0);
+		if (error < 0 ) {
+			printf("Send Failure: %s.\n", strerror(errno));
+			DUMP_CORE;
+		}
+	}
+
+	while (TRUE){
+
+		/* Clear the set for select() */
+		FD_ZERO(&rfds);
+
+		/* Set time out values for select() */
+		tv.tv_sec = 5;
+		tv.tv_usec = 0;
+
+		/* Add the sockets select() will examine */
+		for (i = 0; i < assoc_num; i++) {
+			FD_SET(client_socket[i], &rfds);
+		}
+
+		/* Wait until there is data to be read from one of the
+		 * sockets, or until the timer expires
+		 */
+		error = select(max_socket + 1, &rfds, NULL, NULL, &tv);
+
+		if (error < 0) {
+			printf("Select Failure: %s.\n", strerror(errno));
+			DUMP_CORE;
+		} else if (error) {
+			/* Loop through the array of sockets to find the ones
+			 *that have information to be read
+			 */
+			process_ready_sockets(client_socket, assoc_num, &rfds);
+		}
+	}
+}
+
+void process_ready_sockets(int client_socket[], int assoc_num, fd_set *rfds) {
+
+        int i, stream, error;
+	struct msghdr inmessage;
+	struct iovec iov;
+	char incmsg[CMSG_SPACE(sizeof (sctp_cmsg_data_t))];
+	sockaddr_storage_t msgname;
+
+        /* Setup inmessage to be able to receive in incomming message */
+	memset(&inmessage, 0, sizeof (inmessage));
+	iov.iov_base = big_buffer;
+	iov.iov_len = REALLY_BIG;
+	inmessage.msg_iov = &iov;
+	inmessage.msg_iovlen =1;
+	inmessage.msg_control = incmsg;
+	inmessage.msg_controllen = sizeof (incmsg);
+	inmessage.msg_name = &msgname;
+	inmessage.msg_namelen = sizeof (msgname);
+
+	stream = 1;
+
+	for( i = 0; i < assoc_num; i++) {
+		if (FD_ISSET(client_socket[i], rfds)) {
+				error = recvmsg(client_socket[i], &inmessage,
+						MSG_WAITALL);
+				if (error < 0)
+						printf("Receive Failure: %s\n",
+							strerror(errno));
+				else {
+		/* Test to find the type of message that was read(event/data) */
+					if (inmessage.msg_flags &
+						MSG_NOTIFICATION)
+						 event_received(&inmessage,
+								0);
+
+					else
+						data_received(&inmessage, error,
+							stream,
+							client_socket[i]);
+			}
+		}
+	}
+}
+
+int main(int argc, char *argv[]) {
+
+	parse_arguments(argc, argv);
+
+	if (mode == SERVER) {
+		server_mode();
+	} else if (mode == CLIENT){
+		client_mode();
+	}
+	exit(1);
+}
+
diff --git a/src/func_tests/.gitignore b/src/func_tests/.gitignore
new file mode 100644
index 0000000..720db65
--- /dev/null
+++ b/src/func_tests/.gitignore
@@ -0,0 +1,41 @@
+test_1_to_1_accept_close
+test_1_to_1_addrs
+test_1_to_1_connect
+test_1_to_1_connectx
+test_1_to_1_events
+test_1_to_1_initmsg_connect
+test_1_to_1_nonblock
+test_1_to_1_recvfrom
+test_1_to_1_recvmsg
+test_1_to_1_rtoinfo
+test_1_to_1_send
+test_1_to_1_sendmsg
+test_1_to_1_sendto
+test_1_to_1_shutdown
+test_1_to_1_socket_bind_listen
+test_1_to_1_sockopt
+test_1_to_1_threads
+test_assoc_abort
+test_assoc_shutdown
+test_autoclose
+test_basic
+test_basic_v6
+test_connect
+test_connectx
+test_fragments
+test_fragments_v6
+test_getname
+test_getname_v6
+test_inaddr_any
+test_inaddr_any_v6
+test_peeloff
+test_peeloff_v6
+test_recvmsg
+test_sctp_sendrecvmsg
+test_sctp_sendrecvmsg_v6
+test_sockopt
+test_sockopt_v6
+test_tcp_style
+test_tcp_style_v6
+test_timetolive
+test_timetolive_v6
diff --git a/src/func_tests/Makefile.am b/src/func_tests/Makefile.am
new file mode 100644
index 0000000..e5bf454
--- /dev/null
+++ b/src/func_tests/Makefile.am
@@ -0,0 +1,179 @@
+# Include these two in all the Makefile.am's!!!
+include $(top_srcdir)/Makefile.vars
+include $(top_srcdir)/Makefile.rules
+include $(top_srcdir)/Makefile.dirs
+
+# General compilation flags
+AM_CPPFLAGS = -I. -I$(top_builddir)/src/include -I$(top_srcdir)/src/testlib \
+              -g -O2 -fno-strict-aliasing -Wall -Wstrict-prototypes \
+              -Wimplicit-function-declaration
+
+AM_LDFLAGS = -lpthread
+
+LDADD = $(top_builddir)/src/testlib/libsctputil.la \
+	$(top_builddir)/src/lib/libsctp.la
+
+V6FLAGS = -DCONFIG_IPV6=1 -DTEST_V6=1 ${DEFS} ${INCLUDES} ${CFLAGS}
+
+# Test programs and libraries to build
+PASSING_KERN_TESTS = \
+	test_assoc_abort \
+	test_assoc_shutdown \
+	test_autoclose \
+	test_basic \
+	test_fragments \
+	test_inaddr_any \
+	test_peeloff \
+	test_sockopt \
+	test_connect \
+	test_connectx \
+	test_recvmsg \
+	test_timetolive \
+	test_sctp_sendrecvmsg \
+	test_getname \
+	test_tcp_style\
+	test_1_to_1_socket_bind_listen \
+	test_1_to_1_accept_close \
+	test_1_to_1_connect \
+	test_1_to_1_connectx \
+	test_1_to_1_send \
+	test_1_to_1_sendto \
+	test_1_to_1_sendmsg \
+	test_1_to_1_recvfrom \
+	test_1_to_1_recvmsg \
+	test_1_to_1_shutdown \
+	test_1_to_1_sockopt \
+	test_1_to_1_addrs \
+	test_1_to_1_nonblock \
+	test_1_to_1_rtoinfo \
+	test_1_to_1_events \
+	test_1_to_1_threads \
+	test_1_to_1_initmsg_connect
+
+PASSING_V6_KERN_TESTS = \
+	test_basic_v6 \
+	test_sockopt_v6 \
+	test_fragments_v6 \
+	test_inaddr_any_v6 \
+	test_peeloff_v6 \
+	test_timetolive_v6 \
+	test_sctp_sendrecvmsg_v6 \
+	test_getname_v6 \
+	test_tcp_style_v6
+
+if HAVE_SCTP_SENDV
+PASSING_KERN_TESTS += \
+	test_sctp_sendvrecvv
+PASSING_V6_KERN_TESTS += \
+	test_sctp_sendvrecvv_v6
+endif
+
+noinst_PROGRAMS = ${PASSING_KERN_TESTS} ${PASSING_V6_KERN_TESTS}
+
+$(top_builddir)/src/lib/libsctp.la:
+	$(MAKE) -C $(top_builddir)/src/lib libsctp.la
+
+$(top_builddir)/src/testlib/libsctputil.la:
+	$(MAKE) -C $(top_builddir)/src/testlib libsctputil.la
+
+# These are tests for live kernels which pass.
+v4test: ${PASSING_KERN_TESTS}
+	@for a in $^;				\
+	do 					\
+		echo "./$$a";			\
+		if ./$$a;			\
+		then				\
+			echo "$$a passes";	\
+			echo "";		\
+		else				\
+			echo "$$a fails";	\
+			exit 1;			\
+		fi;				\
+		sleep 1;			\
+	done
+	@echo "Hoody hoo!"
+
+# These are tests for live kernels which pass.
+v6test: ${PASSING_V6_KERN_TESTS}
+	@for a in $^;				\
+	do 					\
+		echo "./$$a";			\
+		if ./$$a;			\
+		then				\
+			echo "$$a passes";	\
+			echo "";		\
+		else				\
+			echo "$$a fails";	\
+			exit 1;			\
+		fi;				\
+		sleep 1;			\
+	done
+	@echo "Hoody hoo!"
+
+# Specifying the sources
+test_assoc_abort_SOURCES = test_assoc_abort.c 
+test_assoc_shutdown_SOURCES = test_assoc_shutdown.c 
+test_autoclose_SOURCES = test_autoclose.c 
+test_basic_SOURCES = test_basic.c 
+test_fragments_SOURCES = test_fragments.c 
+test_inaddr_any_SOURCES = test_inaddr_any.c 
+test_peeloff_SOURCES = test_peeloff.c 
+test_sockopt_SOURCES = test_sockopt.c 
+test_connect_SOURCES = test_connect.c 
+test_connectx_SOURCES = test_connectx.c 
+test_recvmsg_SOURCES = test_recvmsg.c 
+test_timetolive_SOURCES = test_timetolive.c
+test_sctp_sendrecvmsg_SOURCES = test_sctp_sendrecvmsg.c
+test_sctp_sendvrecvv_SOURCES = test_sctp_sendvrecvv.c
+test_getname_SOURCES = test_getname.c 
+test_tcp_style_SOURCES = test_tcp_style.c 
+
+test_1_to_1_socket_bind_listen_SOURCES = test_1_to_1_socket_bind_listen.c
+test_1_to_1_accept_close_SOURCES = test_1_to_1_accept_close.c
+test_1_to_1_connect_SOURCES = test_1_to_1_connect.c
+test_1_to_1_connectx_SOURCES = test_1_to_1_connectx.c
+test_1_to_1_send_SOURCES = test_1_to_1_send.c
+test_1_to_1_sendto_SOURCES = test_1_to_1_sendto.c
+test_1_to_1_sendmsg_SOURCES = test_1_to_1_sendmsg.c
+test_1_to_1_recvfrom_SOURCES = test_1_to_1_recvfrom.c
+test_1_to_1_recvmsg_SOURCES = test_1_to_1_recvmsg.c
+test_1_to_1_shutdown_SOURCES = test_1_to_1_shutdown.c
+test_1_to_1_sockopt_SOURCES = test_1_to_1_sockopt.c
+test_1_to_1_addrs_SOURCES = test_1_to_1_addrs.c
+test_1_to_1_nonblock_SOURCES = test_1_to_1_nonblock.c
+test_1_to_1_rtoinfo_SOURCES = test_1_to_1_rtoinfo.c
+test_1_to_1_events_SOURCES = test_1_to_1_events.c
+test_1_to_1_threads_SOURCES = test_1_to_1_threads.c
+test_1_to_1_initmsg_connect_SOURCES = test_1_to_1_initmsg_connect.c
+
+#
+# Specifying objects rules for "v6test"
+#
+test_basic_v6_SOURCES = test_basic.c
+test_basic_v6_CFLAGS = ${V6FLAGS}
+
+test_sockopt_v6_SOURCES = test_sockopt.c
+test_sockopt_v6_CFLAGS = ${V6FLAGS}
+
+test_fragments_v6_SOURCES = test_fragments.c
+test_fragments_v6_CFLAGS = ${V6FLAGS}
+
+test_inaddr_any_v6_SOURCES = test_inaddr_any.c
+test_inaddr_any_v6_CFLAGS = ${V6FLAGS}
+
+test_peeloff_v6_SOURCES = test_peeloff.c
+test_peeloff_v6_CFLAGS = ${V6FLAGS}
+
+test_timetolive_v6_SOURCES = test_timetolive.c
+test_timetolive_v6_CFLAGS = ${V6FLAGS}
+
+test_sctp_sendrecvmsg_v6_SOURCES = test_sctp_sendrecvmsg.c
+test_sctp_sendvrecvv_v6_SOURCES = test_sctp_sendvrecvv.c
+test_sctp_sendrecvmsg_v6_CFLAGS = ${V6FLAGS}
+test_sctp_sendvrecvv_v6_CFLAGS = ${V6FLAGS}
+
+test_getname_v6_SOURCES = test_getname.c
+test_getname_v6_CFLAGS = ${V6FLAGS}
+
+test_tcp_style_v6_SOURCES = test_tcp_style.c
+test_tcp_style_v6_CFLAGS = ${V6FLAGS}
diff --git a/src/func_tests/test_1_to_1_accept_close.c b/src/func_tests/test_1_to_1_accept_close.c
new file mode 100644
index 0000000..64162f8
--- /dev/null
+++ b/src/func_tests/test_1_to_1_accept_close.c
@@ -0,0 +1,246 @@
+/* SCTP kernel Implementation
+ * Copyright (c) 2003 Hewlett-Packard Development Company, L.P
+ * (C) Copyright IBM Corp. 2004
+ *
+ * This file has test cases to test the accept () and close () call for 
+ * 1-1 style sockets
+ *
+ * accept () Tests:
+ * ---------------
+ * TEST1: Bad socket descriptor
+ * TEST2: Invalid socket
+ * TEST3: Invalid address
+ * TEST4: On a non-listening socket
+ * TEST5: On a established socket
+ * TEST6: On a CLOSED association
+ * TEST7: Extracting the association on the listening socket
+ *
+ * close () Tests:
+ * --------------
+ * TEST8: Bad socket descriptor
+ * TEST9: valid socket descriptor
+ * TEST10: Closed socket descriptor
+ * 
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>         /* for sockaddr_in */
+#include <arpa/inet.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sys/uio.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 10;
+int TST_CNT = 0;
+
+#define SK_MAX  10
+
+int
+main(int argc, char *argv[])
+{
+        socklen_t len;
+	int i;
+	int sk,lstn_sk,clnt_sk[SK_MAX],acpt_sk,pf_class;
+	int new_sk[SK_MAX],clnt2_sk[SK_MAX];
+	int error;
+	int fd, err_no = 0;
+	char filename[21];
+
+        struct sockaddr_in conn_addr,lstn_addr,acpt_addr;
+
+	/* Rather than fflush() throughout the code, set stdout to
+         * be unbuffered.
+         */
+        setvbuf(stdout, NULL, _IONBF, 0);
+        setvbuf(stderr, NULL, _IONBF, 0);
+
+        pf_class = PF_INET;
+
+        sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+	for (i=0 ; i < SK_MAX ; i++)
+		new_sk[i] = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+	/* Creating a regular socket */
+	for (i = 0 ; i < SK_MAX ; i++)
+		clnt_sk[i] = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+	for (i = 0 ; i < SK_MAX ; i++)
+		clnt2_sk[i] = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+	/* Creating a listen socket */
+        lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+	conn_addr.sin_family = AF_INET;
+        conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+        conn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+	lstn_addr.sin_family = AF_INET;
+        lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+        lstn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+	/* Binding the listen socket */
+	test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr));
+
+	/* Listening many sockets as we are calling too many connect here */
+	test_listen(lstn_sk, SK_MAX );
+
+	/* connect() is called just to make sure accept() doesn't block the
+	 * program
+	 */
+	i = 0;
+	len = sizeof(struct sockaddr_in);
+	test_connect(clnt_sk[i++], (struct sockaddr *) &conn_addr, len);
+
+	/* accept() TEST1: Bad socket descriptor EBADF, Expected error */
+        error = accept(-1, (struct sockaddr *) &acpt_addr, &len);
+        if (error != -1 || errno != EBADF)
+		tst_brkm(TBROK, tst_exit, "accept with a bad socket descriptor"
+                         "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "accept() with a bad socket descriptor - EBADF");
+
+        /*accept() TEST2: Invalid socket ENOTSOCK, Expected error*/
+	strcpy(filename, "/tmp/sctptest.XXXXXX");
+	fd = mkstemp(filename);
+	if (fd == -1)
+		tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
+				filename, strerror(errno));
+	error = accept(fd, (struct sockaddr *) &acpt_addr, &len);
+	if (error == -1)
+		err_no = errno;
+	close(fd);
+	unlink(filename);
+	if (error != -1 || err_no != ENOTSOCK)
+		tst_brkm(TBROK, tst_exit, "accept with invalid socket"
+                         "error:%d, errno:%d", error, err_no);
+
+	tst_resm(TPASS, "accept() with invalid socket - ENOTSOCK");
+
+        /*accept() TEST3: Invalid address EFAULT, Expected error*/
+        error = accept(lstn_sk, (struct sockaddr *) -1, &len);
+        if (error != -1 || errno != EFAULT)
+		tst_brkm(TBROK, tst_exit, "accept with invalid address"
+                         "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "accept() with invalid address - EFAULT");
+
+	test_connect(clnt_sk[i++], (struct sockaddr *) &conn_addr, len);
+
+        /*accept() TEST4: on a non-listening socket EINVAL, Expected error*/
+        error = accept(sk, (struct sockaddr *) &acpt_addr, &len);
+        if (error != -1 || errno != EINVAL)
+		tst_brkm(TBROK, tst_exit, "accept on a non-listening socket"
+                         "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "accept() on a non-listening socket - EINVAL");
+	
+	test_connect(clnt_sk[i++], (struct sockaddr *) &conn_addr, len);
+
+	/*Calling accept to establish the connection*/
+	acpt_sk = test_accept(lstn_sk, (struct sockaddr *) &acpt_addr, &len);
+
+	/* accept() TEST5: On a established socket EINVAL or EACCES when
+	 * SELinux set to enforcing, Expected error. */
+	error = accept(acpt_sk, (struct sockaddr *) &acpt_addr, &len);
+	if (error != -1 || (errno != EINVAL && errno != EACCES)) {
+		tst_brkm(TBROK, tst_exit, "accept on an established socket"
+			"error:%d, errno:%d", error, errno);
+	}
+
+	tst_resm(TPASS, "accept() on an established socket - %d", errno);
+
+	/*Closing the previously established association*/
+	close(acpt_sk);
+
+	test_connect(clnt_sk[i], (struct sockaddr *) &conn_addr, len);
+
+	/*accept() TEST6: On the CLOSED association should succeed*/
+	acpt_sk = accept(lstn_sk, (struct sockaddr *) &acpt_addr, &len);
+        if (acpt_sk < 0)
+		tst_brkm(TBROK, tst_exit, "accept a closed association"
+                         "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "accept() a closed association - SUCCESS");
+
+	close(acpt_sk);
+
+	/*accept() TEST7: Extracting the association on the listening socket
+	as new socket, new socket socket descriptor should return*/
+	for (i = 0 ; i < (SK_MAX - 1); i++)
+		test_connect(clnt2_sk[i], (struct sockaddr *) &conn_addr, len);
+
+	for (i = 0 ; i < (SK_MAX - 1); i++)
+		new_sk[i] = test_accept(lstn_sk, (struct sockaddr *)&acpt_addr,
+					&len);
+
+	tst_resm(TPASS, "accept() on a listening socket - SUCCESS");
+
+	
+        /*close() TEST8: Bad socket descriptor, EBADF Expected error*/
+	error = close(-1);
+	if (error != -1 || errno != EBADF)
+		tst_brkm(TBROK, tst_exit, "close with a bad socket descriptor "
+                         "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "close() with a bad socket descriptor - EBADF");
+
+	/*close() TEST9: valid socket descriptor should succeed*/
+	error = close(sk);
+	if (error < 0)
+		tst_brkm(TBROK, tst_exit, "close with a valid socket descriptor"
+                         " error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "close() with a valid socket descriptor - SUCCESS");
+
+	/*close() TEST10: closed socket descriptor, EBADF Expected error*/
+        error = close(sk);
+        if (error != -1 || errno != EBADF)
+		tst_brkm(TBROK, tst_exit, "close with a closed socket "
+			 "descriptor error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "close() with a closed socket descriptor - EBADF");
+	
+	for (i = 0 ; i < SK_MAX ; i++) {
+		close(clnt_sk[i]);
+		close(new_sk[i]);
+		close(clnt2_sk[i]);
+	}
+
+	return 0;
+}
diff --git a/src/func_tests/test_1_to_1_addrs.c b/src/func_tests/test_1_to_1_addrs.c
new file mode 100644
index 0000000..5d56918
--- /dev/null
+++ b/src/func_tests/test_1_to_1_addrs.c
@@ -0,0 +1,289 @@
+/* SCTP kernel Implementation
+ * Copyright (c) 2003 Hewlett-Packard Development Company, L.P
+ * (C) Copyright IBM Corp. 2004
+ *
+ * This file has test cases to test the sctp_getladdrs (), sctp_freealddrs (),
+ * sctp_getpaddrs (), sctp_freeapaddrs () for 1-1 style sockets
+ *
+ * sctp_getladdrs () Tests:
+ * -----------------------
+ * TEST1: Bad socket descriptor
+ * TEST2: Invalid socket
+ * TEST3: Socket of different protocol
+ * TEST4: Getting the local addresses
+ *
+ * sctp_freealddrs () Tests:
+ * ------------------------
+ * TEST5: Freeing the local address
+ *
+ * sctp_getpaddrs () Tests:
+ * -----------------------
+ * TEST6: Bad socket descriptor
+ * TEST7: Invalid socket
+ * TEST8: Socket of different protocol
+ * TEST9: Getting the peers addresses
+ *
+ * sctp_freeapddrs () Tests:
+ * ------------------------
+ * TEST10: Freeing the peer's address
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>         /* for sockaddr_in */
+#include <arpa/inet.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sys/uio.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 10;
+int TST_CNT = 0;
+
+int
+main(int argc, char *argv[])
+{
+        int error;
+	socklen_t len;
+	int lstn_sk,clnt_sk,acpt_sk,pf_class,sk1;
+	struct msghdr outmessage;
+        struct msghdr inmessage;
+        char *message = "hello, world!\n";
+        struct iovec iov_rcv;
+        struct sctp_sndrcvinfo *sinfo;
+        int msg_count;
+        char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+        struct cmsghdr *cmsg;
+        struct iovec out_iov;
+        char * buffer_rcv;
+	char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+	struct sockaddr *laddrs, *paddrs;
+	int fd, err_no = 0;
+	char filename[21];
+
+        struct sockaddr_in conn_addr,lstn_addr,acpt_addr;
+	struct sockaddr_in *addr;
+
+	/* Rather than fflush() throughout the code, set stdout to
+         * be unbuffered.
+         */
+        setvbuf(stdout, NULL, _IONBF, 0);
+        setvbuf(stderr, NULL, _IONBF, 0);
+
+        pf_class = PF_INET;
+
+	/*Creating a regular socket*/
+	clnt_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+	/*Creating a listen socket*/
+        lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+	conn_addr.sin_family = AF_INET;
+        conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+        conn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+	lstn_addr.sin_family = AF_INET;
+        lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+        lstn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+	/*Binding the listen socket*/
+	test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr));
+
+	/*Listening many sockets as we are calling too many connect here*/
+	test_listen(lstn_sk, 1);
+
+	len = sizeof(struct sockaddr_in);
+	
+	test_connect(clnt_sk, (struct sockaddr *) &conn_addr, len);
+
+	acpt_sk = test_accept(lstn_sk, (struct sockaddr *) &acpt_addr, &len);
+
+	memset(&inmessage, 0, sizeof(inmessage));
+        buffer_rcv = malloc(REALLY_BIG);
+
+        iov_rcv.iov_base = buffer_rcv;
+        iov_rcv.iov_len = REALLY_BIG;
+        inmessage.msg_iov = &iov_rcv;
+        inmessage.msg_iovlen = 1;
+        inmessage.msg_control = incmsg;
+        inmessage.msg_controllen = sizeof(incmsg);
+
+        msg_count = strlen(message) + 1;
+
+	memset(&outmessage, 0, sizeof(outmessage));
+        outmessage.msg_name = &lstn_addr;
+        outmessage.msg_namelen = sizeof(lstn_addr);
+        outmessage.msg_iov = &out_iov;
+        outmessage.msg_iovlen = 1;
+        outmessage.msg_control = outcmsg;
+        outmessage.msg_controllen = sizeof(outcmsg);
+        outmessage.msg_flags = 0;
+
+        cmsg = CMSG_FIRSTHDR(&outmessage);
+        cmsg->cmsg_level = IPPROTO_SCTP;
+        cmsg->cmsg_type = SCTP_SNDRCV;
+        cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+        outmessage.msg_controllen = cmsg->cmsg_len;
+        sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+        memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+
+        outmessage.msg_iov->iov_base = message;
+        outmessage.msg_iov->iov_len = msg_count;
+
+	test_sendmsg(clnt_sk, &outmessage, MSG_NOSIGNAL, msg_count);
+
+	test_recvmsg(acpt_sk, &inmessage, MSG_NOSIGNAL);
+
+	/*sctp_getladdrs() TEST1: Bad socket descriptor, EBADF Expected error*/
+	error = sctp_getladdrs(-1, 0, &laddrs);
+	if (error != -1 || errno != EBADF)
+		tst_brkm(TBROK, tst_exit, "sctp_getladdrs with a bad socket "
+			 "descriptor error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "sctp_getladdrs() with a bad socket descriptor - "
+		 "EBADF");
+
+	/*sctp_getladdrs() TEST2: Invalid socket, ENOTSOCK Expected error*/
+	strcpy(filename, "/tmp/sctptest.XXXXXX");
+	fd = mkstemp(filename);
+	if (fd == -1)
+		tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
+				filename, strerror(errno));
+	error = sctp_getladdrs(fd, 0, &laddrs);
+	if (error == -1)
+		err_no = errno;
+	close(fd);
+	unlink(filename);
+	if (error != -1 || err_no != ENOTSOCK)
+		tst_brkm(TBROK, tst_exit, "sctp_getladdrs with invalid socket "
+			 "error:%d, errno:%d", error, err_no);
+
+	tst_resm(TPASS, "sctp_getladdrs() with invalid socket - ENOTSOCK");
+
+	/*sctp_getladdrs() TEST3: socket of different protocol
+	EOPNOTSUPP Expected error*/
+        sk1 = socket(pf_class, SOCK_STREAM, IPPROTO_IP);
+	error = sctp_getladdrs(sk1, 0, &laddrs);
+	if (error != -1 || errno != EOPNOTSUPP)
+		tst_brkm(TBROK, tst_exit, "sctp_getladdrs with socket of "
+			 "different protocol error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "sctp_getladdrs() with socket of different protocol - "
+		 "EOPNOTSUPP");
+
+	/*sctp_getladdrs() TEST4: Getting the local addresses*/
+	error = sctp_getladdrs(lstn_sk, 0, &laddrs);
+	if (error < 0)
+		tst_brkm(TBROK, tst_exit, "sctp_getladdrs with valid socket "
+			 "error:%d, errno:%d", error, errno);
+
+	addr = (struct sockaddr_in *)laddrs;
+	if (addr->sin_port != lstn_addr.sin_port || 
+	    addr->sin_family != lstn_addr.sin_family || 
+	    addr->sin_addr.s_addr != lstn_addr.sin_addr.s_addr)
+		tst_brkm(TBROK, tst_exit, "sctp_getladdrs comparision failed");
+
+	tst_resm(TPASS, "sctp_getladdrs() - SUCCESS");
+
+	/*sctp_freealddrs() TEST5: freeing the local address*/
+	if ((sctp_freeladdrs(laddrs)) < 0)
+		tst_brkm(TBROK, tst_exit, "sctp_freeladdrs "
+			 "error:%d, errno:%d", error, errno);
+		
+	tst_resm(TPASS, "sctp_freeladdrs() - SUCCESS");
+
+	/*sctp_getpaddrs() TEST6: Bad socket descriptor, EBADF Expected error*/
+	error = sctp_getpaddrs(-1, 0, &paddrs);
+	if (error != -1 || errno != EBADF)
+		tst_brkm(TBROK, tst_exit, "sctp_getpaddrs with a bad socket "
+			 "descriptor error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "sctp_getpaddrs() with a bad socket descriptor - "
+		 "EBADF");
+
+	/*sctp_getpaddrs() TEST7: Invalid socket, ENOTSOCK Expected error*/
+	strcpy(filename, "/tmp/sctptest.XXXXXX");
+	fd = mkstemp(filename);
+	if (fd == -1)
+		tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
+				filename, strerror(errno));
+	error = sctp_getpaddrs(fd, 0, &paddrs);
+	if (error == -1)
+		err_no = errno;
+	close(fd);
+	unlink(filename);
+	if (error != -1 || err_no != ENOTSOCK)
+		tst_brkm(TBROK, tst_exit, "sctp_getpaddrs with invalid socket "
+			 "error:%d, errno:%d", error, err_no);
+
+	tst_resm(TPASS, "sctp_getpaddrs() with invalid socket - ENOTSOCK");
+	
+	/*sctp_getpaddrs() TEST8: socket of different protocol
+	EOPNOTSUPP Expected error*/
+	error = sctp_getpaddrs(sk1, 0, &laddrs);
+	if (error != -1 || errno != EOPNOTSUPP)
+		tst_brkm(TBROK, tst_exit, "sctp_getpaddrs with socket of "
+			 "different protocol error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "sctp_getpaddrs() with socket of different protocol - "
+		 "EOPNOTSUPP");
+	
+	/*sctp_getpaddrs() TEST9: Getting the peer addresses*/
+	error = sctp_getpaddrs(acpt_sk, 0, &paddrs);
+	if (error < 0)
+		tst_brkm(TBROK, tst_exit, "sctp_getpaddrs with valid socket "
+			 "error:%d, errno:%d", error, errno);
+	
+	addr = (struct sockaddr_in *)paddrs;
+	if (addr->sin_port != acpt_addr.sin_port ||
+            addr->sin_family != acpt_addr.sin_family || 
+            addr->sin_addr.s_addr != acpt_addr.sin_addr.s_addr)
+		tst_brkm(TBROK, tst_exit, "sctp_getpaddrs comparision failed");
+
+	tst_resm(TPASS, "sctp_getpaddrs() - SUCCESS");
+
+	/*sctp_freeapddrs() TEST10: freeing the peer address*/
+	if ((sctp_freepaddrs(paddrs)) < 0)
+		tst_brkm(TBROK, tst_exit, "sctp_freepaddrs "
+			 "error:%d, errno:%d", error, errno);
+		
+	tst_resm(TPASS, "sctp_freepaddrs() - SUCCESS");
+
+	close(clnt_sk);
+
+	return 0;
+}
diff --git a/src/func_tests/test_1_to_1_connect.c b/src/func_tests/test_1_to_1_connect.c
new file mode 100644
index 0000000..3ebc599
--- /dev/null
+++ b/src/func_tests/test_1_to_1_connect.c
@@ -0,0 +1,234 @@
+/* SCTP kernel Implementation
+ * Copyright (c) 2003 Hewlett-Packard Development Company, L.P
+ * (C) Copyright IBM Corp. 2004
+ *
+ * This file has test cases to test the connect () call for 1-1 style sockets
+ *
+ * TEST1: Bad socket descriptor
+ * TEST2: Invalid socket
+ * TEST3: Invalid address
+ * TEST4: Invalid address length
+ * TEST5: Invalid address family
+ * TEST6: Valid blocking connect
+ * TEST7: Connect when accept queue is full
+ * TEST8: On a listening socket
+ * TEST9: On established socket
+ * TEST10: Connect to re-establish a closed association. 
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <linux/socket.h>
+#include <netinet/in.h>         /* for sockaddr_in */
+#include <arpa/inet.h>
+#include <errno.h>
+#include <sys/uio.h>
+#include <netinet/sctp.h>
+#include "sctputil.h"
+
+char *TCID = __FILE__;
+int TST_TOTAL = 10;
+int TST_CNT = 0;
+
+#define SK_MAX 10
+
+int
+main(int argc, char *argv[])
+{
+        int error,i;
+	socklen_t len;
+	int sk,lstn_sk,clnt_sk[SK_MAX],acpt_sk[SK_MAX],pf_class;
+	int sk1,clnt2_sk;
+	int fd, err_no = 0;
+	char filename[21];
+
+        struct sockaddr_in conn_addr,lstn_addr,acpt_addr;
+
+	/* Rather than fflush() throughout the code, set stdout to
+         * be unbuffered.
+         */
+        setvbuf(stdout, NULL, _IONBF, 0);
+        setvbuf(stderr, NULL, _IONBF, 0);
+
+        pf_class = PF_INET;
+
+        sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+        sk1 = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+	/*Creating a listen socket*/
+        lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+	/*Creating a regular socket*/
+	for (i = 0 ; i < SK_MAX ; i++)
+		clnt_sk[i] = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+	clnt2_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+	conn_addr.sin_family = AF_INET;
+        conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+        conn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+	lstn_addr.sin_family = AF_INET;
+        lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+        lstn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+	/*Binding the listen socket*/
+	test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr));
+
+	/*Listening the socket*/
+	test_listen(lstn_sk, SK_MAX-1);
+
+
+	/*connect () TEST1: Bad socket descriptor, EBADF Expected error*/
+	len = sizeof(struct sockaddr_in);
+	error = connect(-1, (const struct sockaddr *) &conn_addr, len);
+	if (error != -1 || errno != EBADF)
+		tst_brkm(TBROK, tst_exit, "connect with bad socket "
+			 "descriptor error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "connect() with bad socket descriptor - EBADF");
+	
+	/*connect () TEST2: Invalid socket, ENOTSOCK Expected error*/
+	strcpy(filename, "/tmp/sctptest.XXXXXX");
+	fd = mkstemp(filename);
+	if (fd == -1)
+		tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
+				filename, strerror(errno));
+	error = connect(fd, (const struct sockaddr *) &conn_addr, len);
+	if (error == -1)
+		err_no = errno;
+	close(fd);
+	unlink(filename);
+	if (error != -1 || err_no != ENOTSOCK)
+		tst_brkm(TBROK, tst_exit, "connect with invalid socket "
+                         "error:%d, errno:%d", error, err_no);
+
+	tst_resm(TPASS, "connect() with invalid socket - ENOTSOCK");
+
+	/*connect () TEST3: Invalid address, EFAULT Expected error*/
+	error = connect(sk, (const struct sockaddr *) -1, len);
+	if (error != -1 || errno != EFAULT)
+		tst_brkm(TBROK, tst_exit, "connect with invalid address "
+                         "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "connect() with invalid address - EFAULT");
+
+	/*connect () TEST4: Invalid address length, EINVAL Expected error*/
+	error = connect(sk, (const struct sockaddr *) &conn_addr, (len - 3));
+	if (error != -1 || errno != EINVAL)
+		tst_brkm(TBROK, tst_exit, "connect with invalid address length "
+                         "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "connect() with invalid address length - EINVAL");
+
+	/*connect () TEST5: Invalid address family, EINVAL Expect error*/
+	conn_addr.sin_family = 9090; /*Assigning invalid address family*/
+        error = connect(sk, (const struct sockaddr *) &conn_addr, len);
+        if (error != -1 || errno != EINVAL)
+		tst_brkm(TBROK, tst_exit, "connect with invalid address family "
+                         "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "connect() with invalid address family - EINVAL");
+
+	conn_addr.sin_family = AF_INET;
+
+	/*connect () TEST6: Blocking connect, should pass*/
+	/*All the be below blocking connect should pass as socket will be 
+	listening SK_MAX clients*/
+	for (i = 0 ; i < SK_MAX ; i++) {
+		error = connect(clnt_sk[i], (const struct sockaddr *)&conn_addr,
+			      len);
+		if (error < 0)
+			tst_brkm(TBROK, tst_exit, "valid blocking connect "
+				 "error:%d, errno:%d", error, errno);
+	}
+
+	tst_resm(TPASS, "valid blocking connect() - SUCCESS");
+
+	/*connect () TEST7: connect when accept queue is full, ECONNREFUSED
+	Expect error*/
+	/*Now that accept queue is full, the below connect should fail*/
+	error = connect(clnt2_sk, (const struct sockaddr *) &conn_addr, len);
+	if (error != -1 || errno != ECONNREFUSED)
+		tst_brkm(TBROK, tst_exit, "connect when accept queue is full "
+                         "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "connect() when accept queue is full - ECONNREFUSED");
+	
+	/*Calling a accept first to estblish the pending connections*/
+	for (i=0 ; i < SK_MAX ; i++)
+		acpt_sk[i] = test_accept(lstn_sk,
+					 (struct sockaddr *) &acpt_addr, &len);
+
+	/*connect () TEST8: from a listening socket, EISCONN Expect error*/
+	error = connect(lstn_sk, (const struct sockaddr *) &lstn_addr, len);
+	if (error != -1 || errno != EISCONN)
+		tst_brkm(TBROK, tst_exit, "connect on a listening socket "
+                         "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "connect() on a listening socket - EISCONN");
+
+	/*connect() TEST9: On established socket, EISCONN Expect error*/
+	i=0;
+	error = connect(acpt_sk[i], (const struct sockaddr *) &lstn_addr, len);
+        if (error != -1 || errno != EISCONN)
+		tst_brkm(TBROK, tst_exit, "connect on an established socket "
+                         "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "connect() on an established socket - EISCONN");
+
+	for (i = 0 ; i < 4 ; i++) {
+		close(clnt_sk[i]);
+		close(acpt_sk[i]);
+	} 
+
+	/* connect() TEST10: Re-establish an association that is closed.
+	 * should succeed.
+	 */
+	error = connect(sk1, (const struct sockaddr *)&conn_addr, len);
+	if (error < 0)
+		tst_brkm(TBROK, tst_exit, "Re-establish an association that "
+				 "is closed error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "connect() to re-establish a closed association - "
+		 "SUCCESS");
+
+	close(sk);
+	close(sk1);
+	close(lstn_sk);
+
+	return 0;
+}
diff --git a/src/func_tests/test_1_to_1_connectx.c b/src/func_tests/test_1_to_1_connectx.c
new file mode 100644
index 0000000..3cb18b3
--- /dev/null
+++ b/src/func_tests/test_1_to_1_connectx.c
@@ -0,0 +1,226 @@
+/* SCTP kernel Implementation
+ * Copyright (c) 2003 Hewlett-Packard Development Company, L.P
+ * (C) Copyright IBM Corp. 2004
+ *
+ * This file has test cases to test the sctp_connectx () call for 1-1 style sockets
+ *
+ * TEST1: Bad socket descriptor
+ * TEST2: Invalid socket
+ * TEST3: Invalid address
+ * TEST4: Invalid address length
+ * TEST5: Invalid address family
+ * TEST6: Valid blocking sctp_connectx
+ * TEST7: Connect when accept queue is full
+ * TEST8: On a listening socket
+ * TEST9: On established socket
+ * TEST10: Connect to re-establish a closed association. 
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <linux/socket.h>
+#include <netinet/in.h>         /* for sockaddr_in */
+#include <arpa/inet.h>
+#include <errno.h>
+#include <sys/uio.h>
+#include <netinet/sctp.h>
+#include "sctputil.h"
+
+char *TCID = __FILE__;
+int TST_TOTAL = 10;
+int TST_CNT = 0;
+
+#define SK_MAX 10
+
+int
+main(int argc, char *argv[])
+{
+	int error,i;
+	socklen_t len;
+	int sk,lstn_sk,clnt_sk[SK_MAX],acpt_sk[SK_MAX],pf_class;
+	int sk1,clnt2_sk;
+
+	struct sockaddr_in conn_addr,lstn_addr,acpt_addr;
+	struct sockaddr *tmp_addr;
+
+	/* Rather than fflush() throughout the code, set stdout to
+	 * be unbuffered.
+	 */
+	setvbuf(stdout, NULL, _IONBF, 0);
+	setvbuf(stderr, NULL, _IONBF, 0);
+
+	pf_class = PF_INET;
+
+	sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+	sk1 = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+	/*Creating a listen socket*/
+	lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+	/*Creating a regular socket*/
+	for (i = 0 ; i < SK_MAX ; i++)
+		clnt_sk[i] = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+	clnt2_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+	conn_addr.sin_family = AF_INET;
+	conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+	conn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+	lstn_addr.sin_family = AF_INET;
+	lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+	lstn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+	/*Binding the listen socket*/
+	test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr));
+
+	/*Listening the socket*/
+	test_listen(lstn_sk, SK_MAX-1);
+
+
+	/*sctp_connectx () TEST1: Bad socket descriptor, EBADF Expected error*/
+	len = sizeof(struct sockaddr_in);
+	error = sctp_connectx(-1, (struct sockaddr *) &conn_addr, 1, NULL);
+	if (error != -1 || errno != EBADF)
+		tst_brkm(TBROK, tst_exit, "sctp_connectx with bad socket "
+			 "descriptor error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "sctp_connectx() with bad socket descriptor - EBADF");
+	
+	/*sctp_connectx () TEST2: Invalid socket, ENOTSOCK Expected error*/
+	error = sctp_connectx(0, (struct sockaddr *) &conn_addr, 1, NULL);
+	if (error != -1 || errno != ENOTSOCK)
+		tst_brkm(TBROK, tst_exit, "sctp_connectx with invalid socket "
+	                 "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "sctp_connectx() with invalid socket - ENOTSOCK");
+
+	/*sctp_connectx () TEST3: Invalid address, EINVAL Expected error*/
+	tmp_addr = (struct sockaddr *) malloc(sizeof(struct sockaddr) - 1);
+	tmp_addr->sa_family = AF_INET;
+	error = sctp_connectx(sk, tmp_addr, 1, NULL);
+	if (error != -1 || errno != EINVAL)
+		tst_brkm(TBROK, tst_exit, "sctp_connectx with invalid address "
+	                 "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "sctp_connectx() with invalid address - EINVAL");
+
+	/*sctp_connectx () TEST4: Invalid address length, EINVAL Expected error*/
+	error = sctp_connectx(sk, (struct sockaddr *) &conn_addr, 0, NULL);
+	if (error != -1 || errno != EINVAL)
+		tst_brkm(TBROK, tst_exit, "sctp_connectx with invalid address length "
+	                 "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "sctp_connectx() with invalid address length - EINVAL");
+
+	/*sctp_connectx () TEST5: Invalid address family, EINVAL Expect error*/
+	conn_addr.sin_family = 9090; /*Assigning invalid address family*/
+	error = sctp_connectx(sk, (struct sockaddr *) &conn_addr, 1, NULL);
+	if (error != -1 || errno != EINVAL)
+		tst_brkm(TBROK, tst_exit, "sctp_connectx with invalid address family "
+	                 "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "sctp_connectx() with invalid address family - EINVAL");
+
+	conn_addr.sin_family = AF_INET;
+
+	/*sctp_connectx () TEST6: Blocking sctp_connectx, should pass*/
+	/*All the be below blocking sctp_connectx should pass as socket will be 
+	listening SK_MAX clients*/
+	for (i = 0 ; i < SK_MAX ; i++) {
+		error = sctp_connectx(clnt_sk[i], (struct sockaddr *)&conn_addr,
+			      1, NULL);
+		if (error < 0)
+			tst_brkm(TBROK, tst_exit, "valid blocking sctp_connectx "
+				 "error:%d, errno:%d", error, errno);
+	}
+
+	tst_resm(TPASS, "valid blocking sctp_connectx() - SUCCESS");
+
+	/*sctp_connectx () TEST7: sctp_connectx when accept queue is full, ECONNREFUSED
+	Expect error*/
+	/*Now that accept queue is full, the below sctp_connectx should fail*/
+	error = sctp_connectx(clnt2_sk, (struct sockaddr *) &conn_addr, 1, NULL);
+	if (error != -1 || errno != ECONNREFUSED)
+		tst_brkm(TBROK, tst_exit, "sctp_connectx when accept queue is full "
+	                 "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "sctp_connectx() when accept queue is full - ECONNREFUSED");
+	
+	/*Calling a accept first to estblish the pending sctp_connectxions*/
+	for (i=0 ; i < SK_MAX ; i++)
+		acpt_sk[i] = test_accept(lstn_sk,
+					 (struct sockaddr *) &acpt_addr, &len);
+
+	/*sctp_connectx () TEST8: from a listening socket, EISCONN Expect error*/
+	error = sctp_connectx(lstn_sk, (struct sockaddr *) &lstn_addr, 1, NULL);
+	if (error != -1 || errno != EISCONN)
+		tst_brkm(TBROK, tst_exit, "sctp_connectx on a listening socket "
+	                 "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "sctp_connectx() on a listening socket - EISCONN");
+
+	/*sctp_connectx() TEST9: On established socket, EISCONN Expect error*/
+	i=0;
+	error = sctp_connectx(acpt_sk[i], (struct sockaddr *) &lstn_addr, 1, NULL);
+	if (error != -1 || errno != EISCONN)
+		tst_brkm(TBROK, tst_exit, "sctp_connectx on an established socket "
+	                 "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "sctp_connectx() on an established socket - EISCONN");
+
+	for (i = 0 ; i < 4 ; i++) {
+		close(clnt_sk[i]);
+		close(acpt_sk[i]);
+	} 
+
+	/* sctp_connectx() TEST10: Re-establish an association that is closed.
+	 * should succeed.
+	 */
+	error = sctp_connectx(sk1, (struct sockaddr *)&conn_addr, 1, NULL);
+	if (error < 0)
+		tst_brkm(TBROK, tst_exit, "Re-establish an association that "
+				 "is closed error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "sctp_connectx() to re-establish a closed association - "
+		 "SUCCESS");
+
+	close(sk);
+	close(sk1);
+	close(lstn_sk);
+
+	return 0;
+}
diff --git a/src/func_tests/test_1_to_1_events.c b/src/func_tests/test_1_to_1_events.c
new file mode 100644
index 0000000..f758d6f
--- /dev/null
+++ b/src/func_tests/test_1_to_1_events.c
@@ -0,0 +1,205 @@
+/* SCTP kernel Implementation
+ * Copyright (c) 2003 Hewlett-Packard Development Company, L.P
+ * (C) Copyright IBM Corp. 2004
+ *
+ * This test tests the events for 1-1 style sockets.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ */
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>         /* needed by linux/sctp.h */
+#include <sys/uio.h>
+#include <netinet/in.h>         /* for sockaddr_in */
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+#include <string.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 4;
+int TST_CNT = 0;
+
+int
+main(int argc, char *argv[])
+{
+	int svr_sk, clt_sk,acpt_sk;
+	struct sockaddr_in svr_loop, clt_loop,acpt_loop;
+	struct iovec iov, out_iov;
+	struct msghdr inmessage, outmessage;
+	char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+	char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+	int error;
+	socklen_t len;
+	char *big_buffer;
+	struct sctp_event_subscribe event;
+	struct cmsghdr *cmsg;
+	struct sctp_sndrcvinfo *sinfo;
+	char *message = "hello, world!\n";
+	uint32_t ppid;
+	uint32_t stream;
+
+        /* Rather than fflush() throughout the code, set stdout to 
+	 * be unbuffered.  
+	 */ 
+	setvbuf(stdout, NULL, _IONBF, 0); 
+
+	/* Initialize the server and client addresses. */ 
+	svr_loop.sin_family = AF_INET;
+	svr_loop.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+	svr_loop.sin_port = htons(SCTP_TESTPORT_1);
+
+	clt_loop.sin_family = AF_INET;
+	clt_loop.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+	clt_loop.sin_port = htons(SCTP_TESTPORT_1);
+
+	/* Create and bind the server socket.  */
+        svr_sk = test_socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP);
+	test_bind(svr_sk, (struct sockaddr *) &svr_loop, sizeof(svr_loop));
+
+	/* Mark server socket as being able to accept new associations.  */
+	test_listen(svr_sk, 3);
+
+	/* Create the client socket.  */
+	clt_sk = test_socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP);
+
+	memset(&event, 0, sizeof(event));
+	event.sctp_data_io_event = 1;
+	event.sctp_association_event = 1;
+	event.sctp_shutdown_event = 1;
+#ifdef HAVE_SCTP_AUTH_NO_AUTH
+	event.sctp_authentication_event = 1;
+#endif
+	len = sizeof(struct sctp_event_subscribe);
+	test_setsockopt(svr_sk, SCTP_EVENTS, &event, len);
+	test_setsockopt(clt_sk, SCTP_EVENTS, &event, len);
+
+	len = sizeof(struct sockaddr_in);
+	test_connect(clt_sk, (struct sockaddr *) &clt_loop, len);
+	
+	acpt_sk = test_accept(svr_sk, (struct sockaddr *) &acpt_loop, &len);
+
+	/* Build up a msghdr structure we can use for all sending.  */
+	memset(&outmessage, 0, sizeof(outmessage));	
+	outmessage.msg_name = &svr_loop;
+	outmessage.msg_namelen = sizeof(svr_loop);
+	outmessage.msg_iov = &out_iov;
+	outmessage.msg_iovlen = 1;
+	outmessage.msg_control = outcmsg;
+	outmessage.msg_controllen = sizeof(outcmsg);
+	outmessage.msg_flags = 0;
+
+	cmsg = CMSG_FIRSTHDR(&outmessage);
+	cmsg->cmsg_level = IPPROTO_SCTP;
+	cmsg->cmsg_type = SCTP_SNDRCV;
+	cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+	outmessage.msg_controllen = cmsg->cmsg_len;
+	sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+	memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+	ppid = rand(); /* Choose an arbitrary value. */
+	stream = 1;
+
+	sinfo->sinfo_ppid = ppid;
+	sinfo->sinfo_stream = stream;
+
+	outmessage.msg_iov->iov_base = message;
+	outmessage.msg_iov->iov_len = (strlen(message) + 1);
+
+	/* Send . This will create the association*/
+	test_sendmsg(clt_sk, &outmessage, 0, strlen(message)+1);
+
+        memset(&inmessage, 0, sizeof(inmessage));
+	/* NOW initialize inmessage with enough space for DATA... */
+	big_buffer = malloc(REALLY_BIG);
+	if (!big_buffer) { DUMP_CORE; }
+
+	/* Let's do a test to do a recvmsg when we are not listening and
+	 * when we have no associations.
+	 */
+	iov.iov_base = big_buffer;
+	iov.iov_len = REALLY_BIG;
+	inmessage.msg_iov = &iov;
+	inmessage.msg_iovlen = 1;
+	inmessage.msg_control = incmsg;
+	inmessage.msg_controllen = sizeof(incmsg);
+
+	error = test_recvmsg(clt_sk, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage,
+                                    error,
+                                    sizeof(struct sctp_assoc_change),
+                                    SCTP_ASSOC_CHANGE,
+                                    SCTP_COMM_UP);
+	
+	tst_resm(TPASS, "COMM_UP notification on client socket - SUCCESS");
+
+	error = test_recvmsg(acpt_sk, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage,
+                                    error,
+                                    sizeof(struct sctp_assoc_change),
+                                    SCTP_ASSOC_CHANGE,
+                                    SCTP_COMM_UP);
+	
+	tst_resm(TPASS, "COMM_UP notification on server socket - SUCCESS");
+
+#ifdef HAVE_SCTP_AUTH_NO_AUTH
+	error = test_recvmsg(acpt_sk, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage,
+				    error,
+				    sizeof(struct sctp_authkey_event),
+				    SCTP_AUTHENTICATION_EVENT,
+				    SCTP_AUTH_NO_AUTH);
+
+	tst_resm(TPASS, "AUTH_NO_AUTH notification on server socket - SUCCESS");
+#endif
+
+	inmessage.msg_control = incmsg;
+	inmessage.msg_controllen = sizeof(incmsg);
+	error = test_recvmsg(acpt_sk, &inmessage, MSG_WAITALL);
+        test_check_msg_data(&inmessage, error, strlen(message) + 1,
+                            MSG_EOR, stream, ppid);
+
+	tst_resm(TPASS, "Data message on server socket - SUCCESS");
+
+	close(clt_sk);
+	error = test_recvmsg(acpt_sk, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage,
+                                    error,
+                                    sizeof(struct sctp_shutdown_event),
+                                    SCTP_SHUTDOWN_EVENT,
+                                    0);
+
+	tst_resm(TPASS, "SHUTDOWN notification on accepted socket - SUCCESS");
+	close(svr_sk);
+	close(acpt_sk);
+
+	return 0;
+}
diff --git a/src/func_tests/test_1_to_1_initmsg_connect.c b/src/func_tests/test_1_to_1_initmsg_connect.c
new file mode 100644
index 0000000..8efb4f5
--- /dev/null
+++ b/src/func_tests/test_1_to_1_initmsg_connect.c
@@ -0,0 +1,120 @@
+/* SCTP kernel Implementation
+ * Copyright (c) 2003 Hewlett-Packard Development Company, L.P
+ * (C) Copyright IBM Corp. 2004
+ *
+ * When init timeout is set to zero, a connect () crashed the system. This case
+ * tests the fix for the same.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ */
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>         /* for sockaddr_in */
+#include <arpa/inet.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sys/uio.h>
+#include <sctputil.h> 
+
+char *TCID = __FILE__;
+int TST_TOTAL = 1;
+int TST_CNT = 0;
+
+int 
+main (int argc, char **argv)
+{
+	int sk1, sk2, sk3, pf_class;
+	socklen_t len;
+	struct sockaddr_in lstn_addr, acpt_addr;
+	struct sockaddr_in conn_addr;
+	char * buffer_rcv;
+	struct sctp_initmsg sinmsg;
+	char *message = "Hello World!\n";
+
+	/* Rather than fflush() throughout the code, set stdout to
+	 * be unbuffered.
+	 */
+	setvbuf(stdout, NULL, _IONBF, 0);
+	setvbuf(stderr, NULL, _IONBF, 0);
+
+	/* Opening the socket*/
+	
+	pf_class = PF_INET;
+
+	sk1 = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+	sk3 = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+        conn_addr.sin_family = AF_INET;
+        conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+        conn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+        lstn_addr.sin_family = AF_INET;
+        lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+        lstn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+	test_bind(sk3, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr));
+
+	len = sizeof(struct sctp_initmsg);
+	sinmsg.sinit_num_ostreams = 65535;
+	sinmsg.sinit_max_instreams = 10;
+	sinmsg.sinit_max_attempts = 1;
+	sinmsg.sinit_max_init_timeo = 0;
+	test_setsockopt(sk1, SCTP_INITMSG, &sinmsg, len);
+	sinmsg.sinit_num_ostreams = 10;
+	sinmsg.sinit_max_instreams = 65535;
+	test_setsockopt(sk3, SCTP_INITMSG, &sinmsg, len);
+
+	test_listen(sk3, 1);
+
+	len = sizeof(struct sockaddr_in);
+	test_connect(sk1, (struct sockaddr *) &conn_addr, len);
+
+	sk2 = test_accept(sk3, (struct sockaddr *) &acpt_addr, &len);
+
+	test_sctp_sendmsg(sk1, message, strlen(message) + 1,
+			  (struct sockaddr *)&conn_addr, len,
+			  0, 0, 65534, 0, 0);
+
+	buffer_rcv = malloc(100);
+	test_recv(sk2, buffer_rcv, (strlen(message) + 1), MSG_NOSIGNAL);
+
+	tst_resm(TPASS, "connect() with init timeout set to 0 - SUCCESS");
+
+	close (sk1);
+	close (sk2);
+	close (sk3);
+	
+        return 0;
+}
diff --git a/src/func_tests/test_1_to_1_nonblock.c b/src/func_tests/test_1_to_1_nonblock.c
new file mode 100644
index 0000000..1179fb1
--- /dev/null
+++ b/src/func_tests/test_1_to_1_nonblock.c
@@ -0,0 +1,209 @@
+/* SCTP kernel Implementation
+ * Copyright (c) 2003 Hewlett-Packard Development Company, L.P
+ * (C) Copyright IBM Corp. 2004
+ *
+ * This file has test cases to test the Non-Blocking mode of connect(),
+ * accept() and recvmsg() calls.
+ *
+ * TEST1: Non blocking accept return EAGAIN if connect is not called 
+ * TEST2: Non blocking connect should return EINPROGRESS
+ * TEST3: accept() passes when connect called in Non-blocking mode
+ * TEST4: Non blocking recvmsg should return EAGAIN
+ * TEST5: recvmsg() should succeed if data present to receive in non blocking
+ *	  mode
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>         /* for sockaddr_in */
+#include <arpa/inet.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sys/uio.h>
+#include <linux/socket.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 5;
+int TST_CNT = 0;
+
+int
+main(int argc, char *argv[])
+{
+        int error,msg_count;
+	socklen_t len;
+	int sk,pf_class,lstn_sk,acpt_sk,flag,cflag,sflag;
+	struct msghdr outmessage;
+	struct msghdr inmessage;
+        char *message = "hello, world!\n";
+        struct iovec iov_rcv;
+	struct sctp_sndrcvinfo *sinfo;
+	char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+	struct cmsghdr *cmsg;
+        struct iovec out_iov;
+	char * buffer_rcv;
+	char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+	
+        struct sockaddr_in conn_addr,lstn_addr,svr_addr;
+
+	/* Rather than fflush() throughout the code, set stdout to
+         * be unbufferd
+         */
+        setvbuf(stdout, NULL, _IONBF, 0);
+        setvbuf(stderr, NULL, _IONBF, 0);
+
+        pf_class = PF_INET;
+
+        sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+        lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+	conn_addr.sin_family = AF_INET;
+        conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+        conn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+	lstn_addr.sin_family = AF_INET;
+        lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+        lstn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+	/*Binding the listen socket*/
+        test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr));
+
+        /*Listening the socket*/
+        test_listen(lstn_sk, 10);
+
+	len = sizeof(struct sockaddr_in);
+	flag = MSG_NOSIGNAL;
+	
+	/*Setting server socket non-blocking*/
+	sflag = fcntl(lstn_sk, F_GETFL, 0);
+	if (sflag < 0)
+		tst_brkm(TBROK, tst_exit, "fcnt F_GETFL failed "
+                         "sflag:%d, errno:%d", sflag, errno);
+
+	error = fcntl(lstn_sk, F_SETFL, sflag | O_NONBLOCK);
+	if (error < 0)
+		tst_brkm(TBROK, tst_exit, "fcnt F_SETFL failed "
+                         "error:%d, errno:%d", error, errno);
+
+	/* TEST1: accept should return EAGAIN instead blocking. */
+	error = accept(lstn_sk, (struct sockaddr *)&svr_addr, &len);
+	if (error != -1 || errno != EAGAIN)
+		tst_brkm(TBROK, tst_exit, "non-blocking accept "
+                         "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "non-blocking accept() - EAGAIN");
+
+	/* TEST2: Non Block connect should return EINPROGRESS */
+	/*Set client socket as non-blocking*/
+	cflag = fcntl(sk, F_GETFL, 0);
+	if (cflag < 0)
+		tst_brkm(TBROK, tst_exit, "fcnt F_GETFL failed "
+                         "cflag:%d, errno:%d", cflag, errno);
+
+	error = fcntl(sk, F_SETFL, sflag | O_NONBLOCK);
+	if (error < 0)
+		tst_brkm(TBROK, tst_exit, "fcnt F_SETFL failed "
+                         "error:%d, errno:%d", error, errno);
+
+	error = connect(sk, (const struct sockaddr *) &conn_addr, len);
+	if (error != -1 || errno != EINPROGRESS)
+		tst_brkm(TBROK, tst_exit, "non-blocking connect "
+                         "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "non-blocking connect() - EINPROGRESS");
+
+	/* TEST3: Now that connect() called, accept will succeed */
+	acpt_sk = accept(lstn_sk, (struct sockaddr *)&svr_addr, &len);
+	if (acpt_sk < 0)
+		tst_brkm(TBROK, tst_exit, "accept after a non-blocking connect "
+                         "error:%d, errno:%d", error, errno);
+	
+	tst_resm(TPASS, "accept() after a non-blocking connect - SUCCESS");
+
+	memset(&outmessage, 0, sizeof(outmessage));
+        outmessage.msg_name = &svr_addr;
+        outmessage.msg_namelen = sizeof(svr_addr);
+        outmessage.msg_iov = &out_iov;
+        outmessage.msg_iovlen = 1;
+        outmessage.msg_control = outcmsg;
+        outmessage.msg_controllen = sizeof(outcmsg);
+        outmessage.msg_flags = 0;
+
+	cmsg = CMSG_FIRSTHDR(&outmessage);
+        cmsg->cmsg_level = IPPROTO_SCTP;
+        cmsg->cmsg_type = SCTP_SNDRCV;
+        cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+        outmessage.msg_controllen = cmsg->cmsg_len;
+	sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+        memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+
+        outmessage.msg_iov->iov_base = message;
+        outmessage.msg_iov->iov_len = strlen(message) + 1;
+
+	memset(&inmessage, 0, sizeof(inmessage));
+        buffer_rcv = malloc(REALLY_BIG);
+
+        iov_rcv.iov_base = buffer_rcv;
+        iov_rcv.iov_len = REALLY_BIG;
+        inmessage.msg_iov = &iov_rcv;
+        inmessage.msg_iovlen = 1;
+        inmessage.msg_control = incmsg;
+        inmessage.msg_controllen = sizeof(incmsg);
+
+	msg_count = strlen(message) + 1;
+
+	/* TEST4: recvmsg() should return EAGAIN instead blocking */
+	error = recvmsg(sk, &inmessage, MSG_WAITALL);
+	if ( error != -1 || errno != EAGAIN)
+		tst_brkm(TBROK, tst_exit, "non-blocking recvmsg "
+                         "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "non-blocking recvmsg() - EAGAIN");
+
+	test_sendmsg(acpt_sk, &outmessage, flag, msg_count);
+
+	/* TEST5: recvmsg() should succeed now as data is available. */
+	error = test_recvmsg(sk, &inmessage, flag);
+        test_check_msg_data(&inmessage, error, msg_count, MSG_EOR, 0, 0);
+
+	tst_resm(TPASS, "non-blocking recvmsg() when data is available - "
+		 "SUCCESS");
+
+	close(lstn_sk);
+	close(acpt_sk);
+	return 0;
+}
diff --git a/src/func_tests/test_1_to_1_recvfrom.c b/src/func_tests/test_1_to_1_recvfrom.c
new file mode 100644
index 0000000..0ede562
--- /dev/null
+++ b/src/func_tests/test_1_to_1_recvfrom.c
@@ -0,0 +1,205 @@
+/* SCTP kernel Implementation
+ * Copyright (c) 2003 Hewlett-Packard Development Company, L.P
+ * (C) Copyright IBM Corp. 2004
+ *
+ * This file has test cases to test the recvfrom () call for 1-1 style sockets
+ *
+ * TEST1: Bad socket descriptor
+ * TEST2: Invalid socket
+ * TEST3: Invalid message pointer
+ * TEST4: On a listening socket
+ * TEST5: Reading on a socket that received SHUTDOWN
+ * TEST6: Reading the pending message on socket that received SHUTDOWN
+ * TEST7: No more message and association is shutdown
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>         /* for sockaddr_in */
+#include <arpa/inet.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sys/uio.h>
+#include <linux/socket.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 7;
+int TST_CNT = 0;
+
+int
+main(int argc, char *argv[])
+{
+        int msg_count;
+	socklen_t len;
+	int sk,pf_class,lstn_sk,acpt_sk, flag;
+        char *message = "hello, world!\n";
+	char *message_rcv;
+        int count;
+	int fd, err_no = 0;
+	char filename[21];
+
+        struct sockaddr_in conn_addr,lstn_addr,svr_addr;
+
+	/* Rather than fflush() throughout the code, set stdout to
+         * be unbuffered.
+         */
+        setvbuf(stdout, NULL, _IONBF, 0);
+        setvbuf(stderr, NULL, _IONBF, 0);
+
+	message_rcv = malloc(512);
+
+        pf_class = PF_INET;
+
+        sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+        lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+	conn_addr.sin_family = AF_INET;
+        conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+        conn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+	lstn_addr.sin_family = AF_INET;
+        lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+        lstn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+	/*Binding the listen socket*/
+        test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr));
+
+        /*Listening the socket*/
+        test_listen(lstn_sk, 10);
+
+	len = sizeof(struct sockaddr_in);
+	
+	test_connect(sk, (struct sockaddr *) &conn_addr, len);
+
+	acpt_sk = test_accept(lstn_sk, (struct sockaddr *)&svr_addr, &len);
+	
+	msg_count = (strlen(message) + 1);
+
+	flag = MSG_NOSIGNAL;
+	/*Sending the message*/
+	count = test_send(sk, message, msg_count, flag);
+
+	/*recvfrom () TEST1: Bad socket descriptor, EBADF Expected error*/
+	count = recvfrom(-1, message_rcv, msg_count, flag,
+			 (struct sockaddr *)&svr_addr, &len);
+	if (count != -1 || errno != EBADF)
+		tst_brkm(TBROK, tst_exit, "recvfrom with a bad socket "
+			 "descriptor count:%d, errno:%d", count, errno);
+
+	tst_resm(TPASS, "recvfrom() with a bad socket descriptor - EBADF");
+
+	/*recvfrom () TEST2: Invalid socket , ENOTSOCK Expected error*/
+	strcpy(filename, "/tmp/sctptest.XXXXXX");
+	fd = mkstemp(filename);
+	if (fd == -1)
+		tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
+				filename, strerror(errno));
+	count = recvfrom(fd, message_rcv, msg_count, flag,
+			 (struct sockaddr *)&svr_addr, &len);
+	if (count == -1)
+		err_no = errno;
+	close(fd);
+	unlink(filename);
+	if (count != -1 || err_no != ENOTSOCK)
+		tst_brkm(TBROK, tst_exit, "recvfrom with invalid socket "
+			 "count:%d, errno:%d", count, err_no);
+
+	tst_resm(TPASS, "recvfrom() with invalid socket - ENOTSOCK");
+
+	/*recvfrom () TEST3: Invalid message pointer EFAULT, Expected error*/
+	count = recvfrom(acpt_sk, (char *)-1, msg_count, flag,
+			 (struct sockaddr *)&svr_addr, &len);
+	if (count != -1 || errno != EFAULT)
+		tst_brkm(TBROK, tst_exit, "recvfrom with invalid message "
+			 "pointer count:%d, errno:%d", count, errno);
+
+	tst_resm(TPASS, "recvfrom() with invalid message ptr - EFAULT");
+
+	/*TEST4: recvfrom on listening socket,ENOTCONN Expected error*/
+	count = recvfrom(lstn_sk, message_rcv, msg_count, flag,
+			 (struct sockaddr *)&svr_addr, &len);
+	if (count != -1 || errno != ENOTCONN)
+		tst_brkm(TBROK, tst_exit, "recvfrom on listening socket "
+			 "count:%d, errno:%d", count, errno);
+
+	tst_resm(TPASS, "recvfrom() on listening socket - ENOTCONN");
+
+	count = test_send(acpt_sk, message, msg_count, flag);
+
+	test_shutdown(sk, SHUT_WR);
+
+	/*recvfrom () TEST5:reading on a socket that received SHUTDOWN*/
+	count = recvfrom(acpt_sk, message_rcv, msg_count, flag,
+			 (struct sockaddr *)&svr_addr, &len);
+	if (count < 0)
+		tst_brkm(TBROK, tst_exit, "recvfrom on a socket that has "
+			 "received shutdown count:%d, errno:%d", count, errno);
+
+	tst_resm(TPASS, "recvfrom() on a socket that has received shutdown - "
+		 "EOF");
+
+	/*recvfrom () TEST6:reading the pending message on socket that sent 
+	SHUTDOWN*/
+	count = recvfrom(sk, message_rcv, msg_count, flag,
+			 (struct sockaddr *)&svr_addr, &len);
+	if (count < 0)
+		tst_brkm(TBROK, tst_exit, "recvfrom on a socket with pending "
+			 "message that has sent shutdown count:%d, errno:%d",
+			 count, errno);
+
+	tst_resm(TPASS, "recvfrom() on a socket with pending message that has "
+		 "sent shutdown - SUCCESS");
+
+	/*recvfrom () TEST7: No more message and association is shutdown,
+	ENOTCONN Expected error*/
+	count = recvfrom(sk, message_rcv, msg_count, flag,
+			 (struct sockaddr *)&svr_addr, &len);
+	if (count != -1 || errno != ENOTCONN)
+		tst_brkm(TBROK, tst_exit, "recvfrom on a socket with no "
+			 "pending messages and has sent shutdown count:%d, "
+			 "errno:%d", count, errno);
+
+	tst_resm(TPASS, "recvfrom() on a socket with no pending messages and "
+		 " has sent shutdown - ENOTCONN");
+
+	close(sk);
+	close(lstn_sk);
+	close(acpt_sk);
+	return 0;
+	
+}
diff --git a/src/func_tests/test_1_to_1_recvmsg.c b/src/func_tests/test_1_to_1_recvmsg.c
new file mode 100644
index 0000000..5f06bb6
--- /dev/null
+++ b/src/func_tests/test_1_to_1_recvmsg.c
@@ -0,0 +1,216 @@
+/* SCTP kernel Implementation
+ * Copyright (c) 2003 Hewlett-Packard Development Company, L.P
+ * (C) Copyright IBM Corp. 2004
+ *
+ * This file has test cases to test the recvmsg() call for 1-1 style sockets
+ *
+ * TEST1: Bad socket descriptor
+ * TEST2: Invalid socket
+ * TEST3: Invalid iovec pointer
+ * TEST4: Invalid msghdr pointer
+ * TEST5: On a listening socket
+ * TEST6: Reading on a socket that received SHUTDOWN
+ * TEST7: Reading the pending message socket that received SHUTDOWN
+ * TEST8: No more message and association is shutdown
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>         /* for sockaddr_in */
+#include <arpa/inet.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sys/uio.h>
+#include <linux/socket.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 8;
+int TST_CNT = 0;
+
+int
+main(int argc, char *argv[])
+{
+        socklen_t len;
+	int sk,pf_class,lstn_sk,acpt_sk;
+	int flag = 0;
+	int fd, err_no = 0;
+	char filename[21];
+	struct msghdr inmessage;
+        char *message = "hello, world!\n";
+	struct iovec iov_rcv;
+        int count;
+	char * buffer_rcv;
+        char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+	char *message1 = "hello, world!\n";
+
+        struct sockaddr_in conn_addr,lstn_addr,svr_addr;
+
+	/* Rather than fflush() throughout the code, set stdout to
+         * be unbuffered.
+         */
+        setvbuf(stdout, NULL, _IONBF, 0);
+        setvbuf(stderr, NULL, _IONBF, 0);
+
+        pf_class = PF_INET;
+
+        sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+        lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+	conn_addr.sin_family = AF_INET;
+        conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+        conn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+	lstn_addr.sin_family = AF_INET;
+        lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+        lstn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+	/*Binding the listen socket*/
+        test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr));
+
+        /*Listening the socket*/
+        test_listen(lstn_sk, 10);
+
+	len = sizeof(struct sockaddr_in);
+	
+	test_connect(sk, (struct sockaddr *) &conn_addr, len);
+
+	acpt_sk = test_accept(lstn_sk, (struct sockaddr *)&svr_addr, &len);
+
+	memset(&inmessage, 0, sizeof(inmessage));
+        buffer_rcv = malloc(REALLY_BIG);
+
+        iov_rcv.iov_base = buffer_rcv;
+        iov_rcv.iov_len = REALLY_BIG;
+        inmessage.msg_iov = &iov_rcv;
+        inmessage.msg_iovlen = 1;
+        inmessage.msg_control = incmsg;
+        inmessage.msg_controllen = sizeof(incmsg);
+
+	/*recvmsg () TEST1: Bad socket descriptor, EBADF Expected error*/
+	count = recvmsg(-1, &inmessage, flag);
+	if (count != -1 || errno != EBADF)
+		tst_brkm(TBROK, tst_exit, "recvmsg with a bad socket "
+			 "descriptor count:%d, errno:%d", count, errno);
+
+	tst_resm(TPASS, "recvmsg() with a bad socket descriptor - EBADF");
+
+	/*recvmsg () TEST2: Invalid socket , ENOTSOCK Expected error*/
+	strcpy(filename, "/tmp/sctptest.XXXXXX");
+	fd = mkstemp(filename);
+	if (fd == -1)
+		tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
+				filename, strerror(errno));
+	count = recvmsg(fd, &inmessage, flag);
+	if (count == -1)
+		err_no = errno;
+	close(fd);
+	unlink(filename);
+	if (count != -1 || err_no != ENOTSOCK)
+		tst_brkm(TBROK, tst_exit, "recvmsg with invalid socket "
+			 "count:%d, errno:%d", count, err_no);
+
+	tst_resm(TPASS, "recvmsg() with invalid socket - ENOTSOCK");
+
+	/*recvmsg () TEST3: Invalid iovec pointer EFAULT, Expected error*/
+	inmessage.msg_iov = (struct iovec *)-1;
+	count = recvmsg(acpt_sk, &inmessage, flag);
+	if (count != -1 || errno != EFAULT)
+		tst_brkm(TBROK, tst_exit, "recvmsg with invalid iovec "
+			 "pointer count:%d, errno:%d", count, errno);
+
+	tst_resm(TPASS, "recvmsg() with invalid iovec ptr - EFAULT");
+	
+	inmessage.msg_iov = &iov_rcv;
+
+	/*recvmsg () TEST4: Invalid msghdr pointer EFAULT, Expected error*/
+	count = recvmsg(acpt_sk, (struct msghdr *)-1, flag);
+	if (count != -1 || errno != EFAULT)
+		tst_brkm(TBROK, tst_exit, "recvmsg with invalid msghdr "
+			 "pointer count:%d, errno:%d", count, errno);
+
+	tst_resm(TPASS, "recvmsg() with invalid msghdr ptr - EFAULT");
+
+	/*recvmsg () TEST5:recvmsg on listening socket,ENOTCONN Expected error*/
+	count = recvmsg(lstn_sk, &inmessage, flag);
+	if (count != -1 || errno != ENOTCONN)
+		tst_brkm(TBROK, tst_exit, "recvmsg on listening socket "
+			 "count:%d, errno:%d", count, errno);
+
+	tst_resm(TPASS, "recvmsg() on listening socket - ENOTCONN");
+
+	count = test_send(acpt_sk, message1, strlen(message), 0);
+
+	test_shutdown(sk, SHUT_WR);
+
+	flag = MSG_NOSIGNAL;
+	/*recvmsg () TEST6:reading on a socket that received SHUTDOWN*/
+	count = recvmsg(acpt_sk, &inmessage, flag);
+	if (count < 0)
+		tst_brkm(TBROK, tst_exit, "recvmsg on a socket that has "
+			 "received shutdown count:%d, errno:%d", count, errno);
+
+	tst_resm(TPASS, "recvmsg() on a socket that has received shutdown - "
+		 "EOF");
+
+	/*recvmsg () TEST7:reading the pending message socket that sent 
+	SHUTDOWN*/
+	count = recvmsg(sk, &inmessage, flag);
+	if (count < 0)
+		tst_brkm(TBROK, tst_exit, "recvmsg on a socket with pending "
+			 "message that has sent shutdown count:%d, errno:%d",
+			 count, errno);
+
+	tst_resm(TPASS, "recvmsg() on a socket with pending message that has "
+		 "sent shutdown - SUCCESS");
+
+	/*recvmsg () TEST8: No more message and association is shutdown,
+	ENOTCONN Expected error*/
+	count = recvmsg(sk, &inmessage, flag);
+	if (count != -1 || errno != ENOTCONN)
+		tst_brkm(TBROK, tst_exit, "recvmsg on a socket with no "
+			 "pending messages and has sent shutdown count:%d, "
+			 "errno:%d", count, errno);
+
+	tst_resm(TPASS, "recvmsg() on a socket with no pending messages and "
+		 " has sent shutdown - ENOTCONN");
+
+	close(sk);
+	close(lstn_sk);
+	close(acpt_sk);
+	return 0;
+}
diff --git a/src/func_tests/test_1_to_1_rtoinfo.c b/src/func_tests/test_1_to_1_rtoinfo.c
new file mode 100644
index 0000000..1651df1
--- /dev/null
+++ b/src/func_tests/test_1_to_1_rtoinfo.c
@@ -0,0 +1,115 @@
+/* SCTP kernel Implementation
+ * Copyright (c) 2003 Hewlett-Packard Development Company, L.P
+ * (C) Copyright IBM Corp. 2004
+ *
+ * This file has test cases to test the getsockopt () and sectsockopt () with
+ * SCTP_RTOINFO option on 1-1 style socket
+ *
+ * This program first gets the default values using getsockopt(). It also sets
+ * the value using setsockopt() and gets the set value using getsockopt().
+ * A comparison between set values and get values are performed.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <linux/socket.h>
+#include <linux/in.h>         /* for sockaddr_in */
+#include <linux/in6.h>         /* for sockaddr_in6 */
+#include <errno.h>
+#include <sys/uio.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 3;
+int TST_CNT = 0;
+
+int 
+main(void) 
+{
+	
+	int sd, ret;
+	socklen_t len;
+	struct sctp_rtoinfo srtoinfo; /*setting the variables*/
+	struct sctp_rtoinfo grtoinfo; /*Getting the variables*/
+
+	sd = test_socket (PF_INET, SOCK_STREAM, IPPROTO_SCTP);
+
+	len = sizeof(struct sctp_rtoinfo);
+	
+	/*TEST1 Getting the default values using getsockopt()*/
+	ret = getsockopt(sd, IPPROTO_SCTP, SCTP_RTOINFO, &grtoinfo, &len);
+	if (ret < 0)
+		tst_brkm(TBROK, tst_exit, "getsockopt SCTP_RTOINFO "
+			 "ret:%d, errno:%d", ret, errno);
+
+	tst_resm(TPASS, "getsockopt() SCTP_RTOINFO - SUCCESS");
+
+	/*Assigning the values to RTO initial and max and min bounds*/
+	srtoinfo.srto_initial=60;
+	srtoinfo.srto_max=100;
+	srtoinfo.srto_min=40;
+	srtoinfo.srto_assoc_id = 0;
+
+	/*TEST2 Setting the values using setsockopt()*/
+	ret = setsockopt(sd, IPPROTO_SCTP, SCTP_RTOINFO, &srtoinfo, 
+		sizeof(struct sctp_rtoinfo));
+	if (ret < 0)
+		tst_brkm(TBROK, tst_exit, "setsockopt SCTP_RTOINFO "
+			 "ret:%d, errno:%d", ret, errno);
+
+	tst_resm(TPASS, "setsockopt() SCTP_RTOINFO - SUCCESS");
+
+	/*Getting the values which are set using setsockopt()*/
+	ret = getsockopt(sd, IPPROTO_SCTP, SCTP_RTOINFO, &grtoinfo, &len);
+	if (ret < 0)
+		tst_brkm(TBROK, tst_exit, "getsockopt SCTP_RTOINFO "
+			 "ret:%d, errno:%d", ret, errno);
+
+	/* TEST3 Compare the get values with the set values. */ 
+	if (srtoinfo.srto_initial != grtoinfo.srto_initial &&
+            srtoinfo.srto_max != grtoinfo.srto_max &&
+            srtoinfo.srto_min != grtoinfo.srto_min)
+		tst_brkm(TBROK, tst_exit, "setsockopt/getsockopt SCTP_RTOINFO "
+			 "compare failed");
+
+	tst_resm(TPASS, "setsockopt()/getsockopt SCTP_RTOINFO compare - "
+		 "SUCCESS");
+
+	close(sd);
+
+	return 0;
+}
diff --git a/src/func_tests/test_1_to_1_send.c b/src/func_tests/test_1_to_1_send.c
new file mode 100644
index 0000000..8d9516c
--- /dev/null
+++ b/src/func_tests/test_1_to_1_send.c
@@ -0,0 +1,241 @@
+/* SCTP kernel Implementation
+ * Copyright (c) 2003 Hewlett-Packard Development Company, L.P
+ * (C) Copyright IBM Corp. 2004
+ *
+ * This file has test cases to test the send() call for 1-1 style sockets
+ *
+ * TEST1: Bad socket descriptor
+ * TEST2: Invalid socket
+ * TEST3: On a listening socket
+ * TEST4: On a closed association
+ * TEST5: Invalid message address
+ * TEST6: send from client to server 
+ * TEST7: send from server to client 
+ * TEST8: sending partial data from a buffer
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>         /* for sockaddr_in */
+#include <arpa/inet.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sys/uio.h>
+#include <linux/socket.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 8;
+int TST_CNT = 0;
+
+int
+main(int argc, char *argv[])
+{
+        socklen_t len,len_snd;
+	int msg_count;
+	int sk,sk1,pf_class,lstn_sk,acpt_sk,acpt1_sk, flag, count;
+        char *message = "hello, world!\n";
+        char *message_rcv;
+	int fd, err_no = 0;
+	char filename[21];
+
+        struct sockaddr_in conn_addr,lstn_addr,svr_addr;
+
+	/* Rather than fflush() throughout the code, set stdout to
+         * be unbuffered.
+         */
+        setvbuf(stdout, NULL, _IONBF, 0);
+        setvbuf(stderr, NULL, _IONBF, 0);
+
+        pf_class = PF_INET;
+
+        sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+        sk1 = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+        lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+	conn_addr.sin_family = AF_INET;
+        conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+        conn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+	lstn_addr.sin_family = AF_INET;
+        lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+        lstn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+	/*Binding the listen socket*/
+        test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr));
+
+        /*Listening the socket*/
+        test_listen(lstn_sk, 10);
+
+	len = sizeof(struct sockaddr_in);
+	
+	test_connect(sk, (struct sockaddr *) &conn_addr, len);
+
+	acpt_sk = test_accept(lstn_sk, (struct sockaddr *)&svr_addr, &len);
+
+	len_snd = (strlen(message) + 1);
+
+	flag = MSG_NOSIGNAL;
+	/*send () TEST1: Bad socket descriptor, EBADF Expected error*/
+	count = send(-1, message, len_snd, flag);
+	if (count != -1 || errno != EBADF)
+		tst_brkm(TBROK, tst_exit, "send with a bad socket "
+			 "descriptor count:%d, errno:%d", count, errno);
+
+	tst_resm(TPASS, "send() with a bad socket descriptor - EBADF");
+	
+	/*send () TEST2: Invalid socket, ENOTSOCK Expected error*/
+	strcpy(filename, "/tmp/sctptest.XXXXXX");
+	fd = mkstemp(filename);
+	if (fd == -1)
+		tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
+				filename, strerror(errno));
+	count = send(fd, message, len_snd, flag);
+	if (count == -1)
+		err_no = errno;
+	close(fd);
+	unlink(filename);
+	if (count != -1 || err_no != ENOTSOCK)
+		tst_brkm(TBROK, tst_exit, "send with invalid socket "
+			 "count:%d, errno:%d", count, err_no);
+
+	tst_resm(TPASS, "send() with invalid socket - ENOTSOCK");
+
+	/*send () TEST3: send on listening socket, EPIPE Expected error*/
+	count = send(lstn_sk, message, len_snd, flag);
+	if (count != -1 || errno != EPIPE)
+		tst_brkm(TBROK, tst_exit, "send on a listening socket "
+			 "count:%d, errno:%d", count, errno);
+
+	tst_resm(TPASS, "send() on a listening socket - EPIPE");
+#if 0
+	/*send () TEST4: Invalid message address, EFAULT Expected error*/
+       /* FIXME this test should pass. Don't catch why...  */
+	count = send(sk, (char *)0x1, len_snd, flag);
+	if (count != -1 || errno != EFAULT)
+		tst_brkm(TBROK, tst_exit, "send with invalid message "
+			 "pointer count:%d, errno:%d", count, errno);
+
+	tst_resm(TPASS, "send() with invalid message ptr - EFAULT");
+#endif
+
+	test_connect(sk1, (struct sockaddr *) &lstn_addr, len);
+		 
+	count = test_send(sk1, message, len_snd, flag);
+
+	close(sk1);
+
+	acpt1_sk = test_accept(lstn_sk, (struct sockaddr *)&conn_addr, &len);
+
+	/*send () TEST5: send on closed association, EPIPE Expected error*/
+	count = send(acpt1_sk, message, len_snd, flag);
+	if (count != -1 || errno != EPIPE)
+		tst_brkm(TBROK, tst_exit, "send on a closed association "
+			 "count:%d, errno:%d", count, errno);
+
+	tst_resm(TPASS, "send() on a closed association - EPIPE");
+
+	close(acpt1_sk);
+	close(sk);
+	close(lstn_sk);
+	close(acpt_sk);
+
+        sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+        lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+	message_rcv = malloc(512);
+
+	/*Binding the listen socket*/
+        test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr));
+
+        /*Listening the socket*/
+        test_listen(lstn_sk, 10);
+
+	conn_addr.sin_family = AF_INET;
+        conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+        conn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+	len = sizeof(struct sockaddr_in);
+
+	test_connect(sk, (struct sockaddr *) &conn_addr, len);
+
+	acpt_sk = test_accept(lstn_sk, (struct sockaddr *)&svr_addr, &len);
+	
+	msg_count = strlen(message) + 1;
+
+	/*send() TEST6: Sending data from client socket to server socket*/
+	count = send(sk, message, msg_count, flag);
+	if (count != msg_count)
+		tst_brkm(TBROK, tst_exit, "send from client to server "
+                         "count:%d, errno:%d", count, errno);
+
+	tst_resm(TPASS, "send() from client to server - SUCCESS");
+
+	test_recv(acpt_sk, message_rcv, msg_count, flag);
+
+	strncpy(message_rcv,"\0",512);
+
+	/*send() TEST7: Sending data from accept socket to client socket*/
+	count = send(acpt_sk, message, msg_count, flag);
+	if (count != msg_count)
+		tst_brkm(TBROK, tst_exit, "send from accept socket to client "
+                         "count:%d, errno:%d", count, errno);
+
+	tst_resm(TPASS, "send() from accept socket to client - SUCCESS");
+
+	test_recv(sk, message_rcv, msg_count, flag);
+
+	/*send() TEST8: Sending less number of data from the buffer*/
+	/*Sending only 5 bytes so that only hello is received*/
+	test_send(sk, message, 5 , flag);
+	test_recv(acpt_sk, message_rcv, 5, flag);
+	
+	tst_resm(TPASS, "send() partial data from a buffer - SUCCESS");
+
+	/* TEST9: sctp_send with no sinfo */
+	test_sctp_send(sk, message, strlen(message) + 1 , NULL, flag);
+	test_recv(acpt_sk, message_rcv, strlen(message) + 1, flag);
+	tst_resm(TPASS, "sctp_send() with no sinfo - SUCCESS");
+
+	close(sk1);
+	close(lstn_sk);
+	close(acpt_sk);
+
+	return 0;
+}
diff --git a/src/func_tests/test_1_to_1_sendmsg.c b/src/func_tests/test_1_to_1_sendmsg.c
new file mode 100644
index 0000000..13c920d
--- /dev/null
+++ b/src/func_tests/test_1_to_1_sendmsg.c
@@ -0,0 +1,377 @@
+/* SCTP kernel Implementation
+ * Copyright (c) 2003 Hewlett-Packard Development Company, L.P
+ * (C) Copyright IBM Corp. 2004
+ *
+ * This file has test cases to test the sendmsg() call for 1-1 style sockets
+ *
+ * TEST1: Bad socket descriptor
+ * TEST2: Invalid socket
+ * TEST3: On a listening socket
+ * TEST4: Invalid iovec pointer
+ * TEST5: Invalid iovec length
+ * TEST6: Invalid msghdr pointer
+ * TEST7: Invalid sinfo flags
+ * TEST8: SCTP_EOF flag set
+ * TEST9: SCTP_ABORT flag set
+ * TEST10: On a closed association
+ *
+ * TEST11: Sending data from server socket to client socket
+ * TEST12: Sending data from client socket to server socket
+ * TEST13: Sending data from unconnected client to server 
+ * TEST14: Sending a message on SHUT_RD socket
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>         /* for sockaddr_in */
+#include <arpa/inet.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sys/uio.h>
+#include <linux/socket.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 14;
+int TST_CNT = 0;
+
+int
+main(int argc, char *argv[])
+{
+        socklen_t len;
+	int msg_count;
+	int sk,sk1,pf_class,lstn_sk,acpt_sk,acpt1_sk, flag;
+	struct msghdr outmessage;
+        char *message = "hello, world!\n";
+	struct sctp_sndrcvinfo *sinfo;
+        int count;
+	char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+	struct cmsghdr *cmsg;
+        struct iovec out_iov;
+	struct msghdr inmessage;
+	char * buffer_rcv;
+        struct sockaddr_in conn_addr,lstn_addr,svr_addr;
+        struct iovec iov_rcv;
+	char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+	int fd, err_no = 0;
+	char filename[21];
+
+	/* Rather than fflush() throughout the code, set stdout to
+         * be unbuffered.
+         */
+        setvbuf(stdout, NULL, _IONBF, 0);
+        setvbuf(stderr, NULL, _IONBF, 0);
+
+        pf_class = PF_INET;
+
+        sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+        sk1 = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+        lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+	conn_addr.sin_family = AF_INET;
+        conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+        conn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+	lstn_addr.sin_family = AF_INET;
+        lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+        lstn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+	/*Binding the listen socket*/
+        test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr));
+
+        /*Listening the socket*/
+        test_listen(lstn_sk, 10);
+
+	len = sizeof(struct sockaddr_in);
+	
+	test_connect(sk, (struct sockaddr *) &conn_addr, len);
+
+	acpt_sk = test_accept(lstn_sk, (struct sockaddr *)&svr_addr, &len);
+
+	memset(&outmessage, 0, sizeof(outmessage));
+        outmessage.msg_name = &conn_addr;
+        outmessage.msg_namelen = sizeof(conn_addr);
+        outmessage.msg_iov = &out_iov;
+        outmessage.msg_iovlen = 1;
+        outmessage.msg_control = outcmsg;
+        outmessage.msg_controllen = sizeof(outcmsg);
+        outmessage.msg_flags = 0;
+
+	cmsg = CMSG_FIRSTHDR(&outmessage);
+        cmsg->cmsg_level = IPPROTO_SCTP;
+        cmsg->cmsg_type = SCTP_SNDRCV;
+        cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+        outmessage.msg_controllen = cmsg->cmsg_len;
+	sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+        memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+
+        outmessage.msg_iov->iov_base = message;
+        outmessage.msg_iov->iov_len = strlen(message) + 1;
+
+	flag = MSG_NOSIGNAL;
+	/*sendmsg () TEST1: Bad socket descriptor, EBADF Expected error*/
+	count = sendmsg(-1, &outmessage, flag);
+	if (count != -1 || errno != EBADF)
+		tst_brkm(TBROK, tst_exit, "sendmsg with a bad socket "
+			 "descriptor count:%d, errno:%d", count, errno);
+
+	tst_resm(TPASS, "sendmsg() with a bad socket descriptor - EBADF");
+	
+	/*sendmsg () TEST2: Invalid socket, ENOTSOCK Expected error*/
+	strcpy(filename, "/tmp/sctptest.XXXXXX");
+	fd = mkstemp(filename);
+	if (fd == -1)
+		tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
+				filename, strerror(errno));
+	count = sendmsg(fd, &outmessage, flag);
+	if (count == -1)
+		err_no = errno;
+	close(fd);
+	unlink(filename);
+	if (count != -1 || err_no != ENOTSOCK)
+		tst_brkm(TBROK, tst_exit, "sendmsg with invalid socket "
+			 "count:%d, errno:%d", count, err_no);
+
+	tst_resm(TPASS, "sendmsg() with invalid socket - ENOTSOCK");
+
+	/*sendmsg () TEST3: sendmsg on listening socket, EPIPE Expected error*/
+	count = sendmsg(lstn_sk, &outmessage, flag);
+	if (count != -1 || errno != EPIPE)
+		tst_brkm(TBROK, tst_exit, "sendmsg on a listening socket "
+			 "count:%d, errno:%d", count, errno);
+
+	tst_resm(TPASS, "sendmsg() on a listening socket - EPIPE");
+
+	/*sendmsg () TEST4: Invalid iovec pointer EFAULT, Expected error*/
+	outmessage.msg_iov = (struct iovec *)-1;
+	count = sendmsg(sk, &outmessage, flag);
+	if (count != -1 || errno != EFAULT)
+		tst_brkm(TBROK, tst_exit, "sendmsg with invalid iovec "
+			 "pointer count:%d, errno:%d", count, errno);
+
+	tst_resm(TPASS, "sendmsg() with invalid iovec ptr - EFAULT");
+	
+	outmessage.msg_iov = &out_iov;
+
+	/*sendmsg () TEST5: Invalid iovec count EINVAL, Expected error*/
+        outmessage.msg_iovlen = 0;
+	count = sendmsg(sk, &outmessage, flag);
+	if (count != -1 || errno != EINVAL)
+		tst_brkm(TBROK, tst_exit, "sendmsg with invalid iovec "
+			 "length count:%d, errno:%d", count, errno);
+
+	tst_resm(TPASS, "sendmsg() with invalid iovec length - EINVAL");
+
+	outmessage.msg_iovlen = 1;
+	
+	/*sendmsg () TEST6: Invalid msghdr pointer EFAULT, Expected error*/
+	count = sendmsg(sk, (struct msghdr *)-1, flag);
+	if (count != -1 || errno != EFAULT)
+		tst_brkm(TBROK, tst_exit, "sendmsg with invalid msghdr "
+			 "pointer count:%d, errno:%d", count, errno);
+
+	tst_resm(TPASS, "sendmsg() with invalid msghdr ptr - EFAULT");
+
+	/*sendmsg () TEST7: Invalid sinfo flag EINVAL, Expected error*/
+	sinfo->sinfo_flags = 999;
+	count = sendmsg(sk, &outmessage, -1);
+	if (count != -1 || errno != EINVAL)
+		tst_brkm(TBROK, tst_exit, "sendmsg with invalid sinfo "
+			 "flags count:%d, errno:%d", count, errno);
+
+	tst_resm(TPASS, "sendmsg() with invalid sinfo flags - EINVAL");
+
+	/*sendmsg () TEST8: SCTP_EOF flag EINVAL, Expected error*/
+	sinfo->sinfo_flags = SCTP_EOF;
+	count = sendmsg(sk, &outmessage, flag);
+	if (count != -1 || errno != EINVAL)
+		tst_brkm(TBROK, tst_exit, "sendmsg with SCTP_EOF flag "
+			 "count:%d, errno:%d", count, errno);
+
+	tst_resm(TPASS, "sendmsg() with SCTP_EOF flag - EINVAL");
+
+	/*sendmsg () TEST9: SCTP_ABORT flag EINVAL, Expected error*/
+	sinfo->sinfo_flags = SCTP_ABORT;
+	count = sendmsg(sk, &outmessage, flag);
+	if (count != -1 || errno != EINVAL)
+		tst_brkm(TBROK, tst_exit, "sendmsg with SCTP_ABORT flag "
+			 "count:%d, errno:%d", count, errno);
+
+	tst_resm(TPASS, "sendmsg() with SCTP_ABORT flag - EINVAL");
+
+	sinfo->sinfo_flags = 0; 
+	
+	test_connect(sk1, (struct sockaddr *) &lstn_addr, len);
+		 
+	test_sendmsg(sk1, &outmessage, flag, strlen(message)+1);
+
+	close(sk1);
+	acpt1_sk = test_accept(lstn_sk, (struct sockaddr *)&conn_addr, &len);
+
+	/*sendmsg () TEST10:sendmsg on closed association, EPIPE Expected error*/
+	count = sendmsg(acpt1_sk, &outmessage, flag);
+	if (count != -1 || errno != EPIPE)
+		tst_brkm(TBROK, tst_exit, "sendmsg on a closed association "
+			 "count:%d, errno:%d", count, errno);
+
+	tst_resm(TPASS, "sendmsg() on a closed association - EPIPE");
+
+	close(acpt1_sk);
+	close(sk);
+	close(lstn_sk);
+	close(acpt_sk);
+
+        sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+        lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+	conn_addr.sin_family = AF_INET;
+        conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+        conn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+	lstn_addr.sin_family = AF_INET;
+        lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+        lstn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+	/*Binding the listen socket*/
+        test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr));
+
+        /*Listening the socket*/
+        test_listen(lstn_sk, 10);
+
+	len = sizeof(struct sockaddr_in);
+	flag = MSG_NOSIGNAL;
+	
+	test_connect(sk, (struct sockaddr *) &conn_addr, len);
+
+	acpt_sk = test_accept(lstn_sk, (struct sockaddr *)&svr_addr, &len);
+
+	memset(&outmessage, 0, sizeof(outmessage));
+        outmessage.msg_name = &svr_addr;
+        outmessage.msg_namelen = sizeof(svr_addr);
+        outmessage.msg_iov = &out_iov;
+        outmessage.msg_iovlen = 1;
+        outmessage.msg_control = outcmsg;
+        outmessage.msg_controllen = sizeof(outcmsg);
+        outmessage.msg_flags = 0;
+
+	cmsg = CMSG_FIRSTHDR(&outmessage);
+        cmsg->cmsg_level = IPPROTO_SCTP;
+        cmsg->cmsg_type = SCTP_SNDRCV;
+        cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+        outmessage.msg_controllen = cmsg->cmsg_len;
+	sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+        memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+
+        outmessage.msg_iov->iov_base = message;
+        outmessage.msg_iov->iov_len = strlen(message) + 1;
+
+	memset(&inmessage, 0, sizeof(inmessage));
+        buffer_rcv = malloc(REALLY_BIG);
+
+        iov_rcv.iov_base = buffer_rcv;
+        iov_rcv.iov_len = REALLY_BIG;
+        inmessage.msg_iov = &iov_rcv;
+        inmessage.msg_iovlen = 1;
+        inmessage.msg_control = incmsg;
+        inmessage.msg_controllen = sizeof(incmsg);
+
+	msg_count = strlen(message) + 1;
+
+	/*sendmsg() TEST11: Sending data from server socket to client socket*/
+	count = sendmsg(acpt_sk, &outmessage, flag);
+	if (count != msg_count)
+		tst_brkm(TBROK, tst_exit, "sendmsg from accept socket to "
+			 "client count:%d, errno:%d", count, errno);
+
+	tst_resm(TPASS, "sendmsg() from accept socket to client - SUCCESS");
+
+	count = test_recvmsg(sk, &inmessage, flag);
+        test_check_msg_data(&inmessage, count, msg_count, MSG_EOR, 0, 0);
+
+        outmessage.msg_name = &conn_addr;
+        outmessage.msg_namelen = sizeof(conn_addr);
+	/*sendmsg() TEST12: Sending data from client socket to server socket*/
+	count = sendmsg(sk, &outmessage, flag);
+	if (count != msg_count)
+		tst_brkm(TBROK, tst_exit, "sendmsg from client to server "
+                         "count:%d, errno:%d", count, errno);
+
+	tst_resm(TPASS, "sendmsg() from client to server - SUCCESS");
+
+	count = test_recvmsg(acpt_sk, &inmessage, flag);
+        test_check_msg_data(&inmessage, count, msg_count, MSG_EOR, 0, 0);
+
+        outmessage.msg_name = &conn_addr;
+        outmessage.msg_namelen = sizeof(conn_addr);
+	close(sk);
+	close(acpt_sk);
+	sk1 = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+	/*sendmsg() TEST13: Sending data from unconnected client socket to 
+	server socket*/
+	count = sendmsg(sk1, &outmessage, flag);
+	if (count != msg_count)
+		tst_brkm(TBROK, tst_exit, "sendmsg from unconnected client to "
+			 "server count:%d, errno:%d", count, errno);
+
+	tst_resm(TPASS, "sendmsg() from unconnected clt to server - SUCCESS");
+
+	acpt_sk = test_accept(lstn_sk, (struct sockaddr *)&svr_addr, &len);
+
+	count = test_recvmsg(acpt_sk, &inmessage, flag);
+        test_check_msg_data(&inmessage, count, msg_count, MSG_EOR, 0, 0);
+
+	test_shutdown(sk1, SHUT_RD);
+
+	/*sendmsg() TEST14: Sending a message on SHUT_RD socket*/
+	count = sendmsg(sk1, &outmessage, flag);
+	if (count != msg_count)
+		tst_brkm(TBROK, tst_exit, "sendmsg on a SHUT_RD socket "
+                         "count:%d, errno:%d", count, errno);
+
+	tst_resm(TPASS, "sendmsg() on a SHUT_RD socket - SUCCESS");
+
+	count = test_recvmsg(acpt_sk, &inmessage, flag);
+        test_check_msg_data(&inmessage, count, msg_count, MSG_EOR, 0, 0);
+
+	close(sk1);
+	close(lstn_sk);
+	close(acpt_sk);
+	return 0;
+}
diff --git a/src/func_tests/test_1_to_1_sendto.c b/src/func_tests/test_1_to_1_sendto.c
new file mode 100644
index 0000000..56b102a
--- /dev/null
+++ b/src/func_tests/test_1_to_1_sendto.c
@@ -0,0 +1,164 @@
+/* SCTP kernel Implementation
+ * Copyright (c) 2003 Hewlett-Packard Development Company, L.P
+ * (C) Copyright IBM Corp. 2004
+ *
+ * This file has test cases to test the sendto () call 
+ * for 1-1 style sockets
+ *
+ * TEST1: Sending data from client socket to server socket
+ * TEST2: Sending data from accept (server) socket to client socket
+ * TEST3: Sending data from unconnected client socket to server
+ * TEST4: sending partial data from a buffer
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>         /* for sockaddr_in */
+#include <arpa/inet.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sys/uio.h>
+#include <linux/socket.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 4;
+int TST_CNT = 0;
+
+int
+main(int argc, char *argv[])
+{
+        int msg_count;
+	socklen_t len;
+	int sk,sk1,pf_class,lstn_sk,acpt_sk,flag;
+        char *message = "hello, world!\n";
+        char *message_rcv;
+        int count;
+	
+        struct sockaddr_in conn_addr,lstn_addr,svr_addr;
+
+	/* Rather than fflush() throughout the code, set stdout to
+         * be unbufferd
+         */
+        setvbuf(stdout, NULL, _IONBF, 0);
+        setvbuf(stderr, NULL, _IONBF, 0);
+
+        pf_class = PF_INET;
+
+        sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+        lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+	message_rcv = malloc(512);
+	conn_addr.sin_family = AF_INET;
+        conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+        conn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+	lstn_addr.sin_family = AF_INET;
+        lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+        lstn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+	/*Binding the listen socket*/
+        test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr));
+
+        /*Listening the socket*/
+        test_listen(lstn_sk, 10);
+
+	len = sizeof(struct sockaddr_in);
+	flag = MSG_NOSIGNAL;
+	
+	test_connect(sk, (struct sockaddr *) &conn_addr, len);
+
+	acpt_sk = test_accept(lstn_sk, (struct sockaddr *)&svr_addr, &len);
+
+	msg_count = strlen(message) + 1;
+
+	/*sendto() TEST1: Sending data from client socket to server socket*/
+	count = sendto(sk, message, msg_count, flag,
+		       (const struct sockaddr *) &conn_addr, len);
+	if (count != msg_count)
+		tst_brkm(TBROK, tst_exit, "sendto from client to server "
+                         "count:%d, errno:%d", count, errno);
+
+	tst_resm(TPASS, "sendto() from client to server - SUCCESS");
+
+	test_recv(acpt_sk, message_rcv, msg_count, flag);
+
+	strncpy(message_rcv,"\0",512);
+
+	/*sendto() TEST2: Sending data from accept socket to client socket*/
+	count = sendto(acpt_sk, message, msg_count, flag,
+		       (const struct sockaddr *) &svr_addr, len);
+	if (count != msg_count)
+		tst_brkm(TBROK, tst_exit, "sendto from accept socket to client "
+                         "count:%d, errno:%d", count, errno);
+
+	tst_resm(TPASS, "sendto() from accept socket to client - SUCCESS");
+
+	test_recv(sk, message_rcv, msg_count, flag);
+
+        close(sk);
+        close(acpt_sk);
+
+        sk1 = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+	/*sendto() TEST3: Sending data from unconnected client socket to
+        server socket*/
+        count = sendto(sk1, message, msg_count, flag,
+		       (const struct sockaddr *) &conn_addr, len);
+        if (count != msg_count)
+		tst_brkm(TBROK, tst_exit, "sendto from unconnected client to "
+			 "server count:%d, errno:%d", count, errno);
+
+	tst_resm(TPASS, "sendto() from unconnected client to server - SUCCESS");
+
+        acpt_sk = test_accept(lstn_sk, (struct sockaddr *)&svr_addr, &len);
+
+        test_recv(acpt_sk, message_rcv, msg_count, flag);
+
+	/*send() TEST4: Sending less number of data from the buffer*/
+	/*Sending only 5 bytes so that only hello is received*/
+	test_sendto(sk1, message, 5, flag, (const struct sockaddr *)&conn_addr,
+		    len);
+	test_recv(acpt_sk, message_rcv, 5, flag);
+	
+	tst_resm(TPASS, "sendto() partial data from a buffer - SUCCESS");
+
+	close(sk1);
+	close(lstn_sk);
+	close(acpt_sk);
+	return 0;
+	
+}
diff --git a/src/func_tests/test_1_to_1_shutdown.c b/src/func_tests/test_1_to_1_shutdown.c
new file mode 100644
index 0000000..26c5b15
--- /dev/null
+++ b/src/func_tests/test_1_to_1_shutdown.c
@@ -0,0 +1,228 @@
+/* SCTP kernel Implementation
+ * Copyright (c) 2003 Hewlett-Packard Development Company, L.P
+ * (C) Copyright IBM Corp. 2004
+ *
+ * This file has test cases to test the shutdown() call for 1-1 style sockets
+ *
+ * TEST1: Bad socket descriptor
+ * TEST2: Invalid socket
+ * TEST3: shutdown with SHUT_WR flag to disable new send
+ * TEST4: shutdown with SHUT_RD flag to disable new receive
+ * TEST5: shutdown with SHUT_RDWR flag to disable new receive/send
+ * TEST6: Unconnected socket
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release
+ *
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <linux/socket.h>
+#include <netinet/sctp.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 6;
+int TST_CNT = 0;
+
+#define MAX_CLIENTS 10
+
+int
+main(int argc, char *argv[])
+{
+	int clnt_sk[MAX_CLIENTS], acpt_sk[MAX_CLIENTS],sk;
+	int lstn_sk;
+	struct sockaddr_in lstn_addr, acpt_addr;
+	socklen_t addrlen;
+	int error, i;
+        char *message = "hello, world!\n";
+	char msgbuf[100];
+	int pf_class;
+	int fd, err_no = 0;
+	char filename[21];
+
+        /* Rather than fflush() throughout the code, set stdout to 
+	 * be unbuffered.  
+	 */ 
+	setvbuf(stdout, NULL, _IONBF, 0); 
+	setvbuf(stderr, NULL, _IONBF, 0); 
+
+	/* Initialize the server and client addresses. */ 
+	pf_class = PF_INET;
+
+	lstn_addr.sin_family = AF_INET;
+	lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+	lstn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+        sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+        lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+	test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr));
+
+	test_listen(lstn_sk, MAX_CLIENTS);
+
+	for (i = 0; i < MAX_CLIENTS; i++) {
+		clnt_sk[i] = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+		test_connect(clnt_sk[i], (struct sockaddr *)&lstn_addr,
+			     sizeof(lstn_addr));
+	}
+
+	for (i = 0; i < MAX_CLIENTS; i++) {
+		addrlen = sizeof(acpt_addr);
+		acpt_sk[i] = test_accept(lstn_sk, (struct sockaddr *)&acpt_addr,
+					 &addrlen); 
+	}
+
+	/*shutdown() TEST1: Bad socket descriptor, EBADF Expected error*/
+	error = shutdown(-1, SHUT_WR);
+	if (error != -1 || errno != EBADF)
+		tst_brkm(TBROK, tst_exit, "shutdown with a bad socket "
+			 "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "shutdown() with a bad socket descriptor - EBADF");
+
+	/*shutdown() TEST2: Invalid socket, ENOTSOCK Expected error*/
+	strcpy(filename, "/tmp/sctptest.XXXXXX");
+	fd = mkstemp(filename);
+	if (fd == -1)
+		tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
+				filename, strerror(errno));
+	error = shutdown(fd, SHUT_WR);
+	if (error == -1)
+		err_no = errno;
+	close(fd);
+	unlink(filename);
+	if (error != -1 || err_no != ENOTSOCK)
+		tst_brkm(TBROK, tst_exit, "shutdown with an invalid socket "
+			 "error:%d, errno:%d", error, err_no);
+
+	tst_resm(TPASS, "shutdown() with an invalid socket - ENOTSOCK");
+
+	errno = 0;
+	/*Do a send first before doing shutdown*/
+	test_send(acpt_sk[0], message, strlen(message), 0);
+
+	/*shutdown() TEST3: shutdown with SHUT_WR flag to disable new send*/
+	error = shutdown(clnt_sk[0], SHUT_WR);
+	if (error < 0)
+		tst_brkm(TBROK, tst_exit, "shutdown with SHUT_WR flag "
+			 "error:%d, errno:%d", error, errno);
+
+	/* Reading on a socket that has received SHUTDOWN should return 0 
+	 * indicating EOF.
+	 */
+	error = recv(acpt_sk[0], msgbuf, 100, 0);
+	if ((error != 0) || (errno != 0))
+		tst_brkm(TBROK, tst_exit, "recv on a SHUTDOWN received socket "
+			 "error:%d, errno:%d", error, errno);
+
+	/* Read the pending message on clnt_sk[0] that was received before
+	 * SHUTDOWN call.
+	 */  
+	test_recv(clnt_sk[0], msgbuf, 100, 0);
+
+	/* No more messages and the association is SHUTDOWN, should fail. */
+	error = recv(clnt_sk[0], msgbuf, 100, 0);
+	if ((error != -1) || (errno != ENOTCONN))
+		tst_brkm(TBROK, tst_exit, "recv on a SHUT_WR socket with no "
+			 "messages error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "shutdown() with SHUT_WR flag - SUCCESS");
+
+	errno = 0;
+
+	/*shutdown() TEST4: shutdown with SHUT_RD flag to disable new receive*/
+	test_shutdown(clnt_sk[1], SHUT_RD);
+
+	error = recv(clnt_sk[1], msgbuf, 100, 0);
+	if ((error != 0) || (errno != 0))
+		tst_brkm(TBROK, tst_exit, "recv on a SHUT_RD socket "
+			 "error:%d, errno:%d", error, errno);
+
+	/* Sending a message on SHUT_RD socket. */
+	error = test_send(clnt_sk[1], message, strlen(message), 0);
+	if (error < 0)
+		tst_brkm(TBROK, tst_exit, "send on a SHUT_RD socket "
+			 "error:%d, errno:%d", error, errno);
+
+	/* Receive the message sent on SHUT_RD socket. */
+	test_recv(acpt_sk[1], msgbuf, 100, 0);
+
+	/* Send a message to the SHUT_RD socket. */
+	test_send(acpt_sk[1], message, strlen(message), 0);
+
+	/* We should not receive the message as the socket is SHUT_RD */ 
+	error = recv(clnt_sk[1], msgbuf, 100, 0);
+	if ((error != 0) || (errno != 0))
+		tst_brkm(TBROK, tst_exit, "recv on a SHUT_RD socket "
+			 "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "shutdown() with SHUT_RD flag - SUCCESS");
+
+	/*shutdown() TEST5: shutdown with SHUT_RDWR flag to disable new 
+	receive/send*/
+        test_shutdown(clnt_sk[2], SHUT_RDWR);
+
+	error = recv(acpt_sk[2], msgbuf, 100, 0);
+	if ((error != 0) || (errno != 0))
+		tst_brkm(TBROK, tst_exit, "recv on a SHUTDOWN received socket "
+			 "error:%d, errno:%d", error, errno);
+
+	error = recv(clnt_sk[2], msgbuf, 100, 0);
+	if ((error != 0) || (errno != 0))
+		tst_brkm(TBROK, tst_exit, "recv on a SHUT_RDWR socket "
+			 "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "shutdown() with SHUT_RDWR flag - SUCCESS");
+
+	/*shutdown() TEST6: Unconnected socket, ENOTCONN Expected error*/
+	error = shutdown(sk, SHUT_RD);
+	if ((error != -1) || (errno != ENOTCONN))
+		tst_brkm(TBROK, tst_exit, "shutdown on an unconnected socket "
+			 "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "shutdown() on an unconnected socket - SUCCESS");
+
+	for (i = 0; i < MAX_CLIENTS; i++)
+		close(clnt_sk[i]);
+	for (i = 0; i < MAX_CLIENTS; i++)
+		close(acpt_sk[i]);
+
+
+	close(lstn_sk);
+	close(sk);
+
+	return 0;
+}
diff --git a/src/func_tests/test_1_to_1_socket_bind_listen.c b/src/func_tests/test_1_to_1_socket_bind_listen.c
new file mode 100644
index 0000000..06c6847
--- /dev/null
+++ b/src/func_tests/test_1_to_1_socket_bind_listen.c
@@ -0,0 +1,288 @@
+/* SCTP kernel Implementation
+ * Copyright (c) 2003 Hewlett-Packard Development Company, L.P
+ * (C) Copyright IBM Corp. 2004
+ *
+ * This file has test cases to test the socket (), bind () and listen () for
+ * 1-1 style sockets
+ *
+ * socket () Tests:
+ * ---------------
+ * TEST1: Invalid domain
+ * TEST2: Invalid type
+ * TEST3: Opening a TCP style socket
+ *
+ * bind () Tests:
+ * -------------
+ * TEST4: Invalid address
+ * TEST5: Invalid address length
+ * TEST6: Invalid socket descriptor
+ * TEST7: Invalid host name
+ * TEST8: On a socket that is already bound
+ * TEST9: On reserved ports
+ * TEST10: INADDR_ANY address and non-zero port
+ * TEST11: INADDR_ANY address and zero port
+ * TEST12: Local address and zero port
+ * 
+ * listen () Tests:
+ * ---------------
+ * TEST13: Bad socket descriptor
+ * TEST14: Invalid socket
+ * TEST15: Listening a bound socket
+ * 
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>         /* for sockaddr_in */
+#include <arpa/inet.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sys/uio.h>
+#include <sctputil.h>
+
+#define SCTP_RESERVED_PORT 7
+#define SCTP_INV_LOOPBACK "172.31.43.112"
+
+char *TCID = __FILE__;
+int TST_TOTAL = 15;
+int TST_CNT = 0;
+
+int
+main(int argc, char *argv[])
+{
+        int sk,pf_class;
+	int error = 0;
+	int uid;
+	int fd, err_no = 0;
+	char filename[21];
+
+        struct sockaddr_in bind_addr;
+
+	/* Rather than fflush() throughout the code, set stdout to
+         * be unbuffered.
+         */
+        setvbuf(stdout, NULL, _IONBF, 0);
+        setvbuf(stderr, NULL, _IONBF, 0);
+
+        pf_class = PF_INET;
+
+        /* socket() TEST1: Invalid domain, EAFNOSUPPORT Expected error */
+        sk = socket(-1, SOCK_STREAM, IPPROTO_SCTP);
+        if (sk != -1 || errno != EAFNOSUPPORT)
+		tst_brkm(TBROK, tst_exit, "socket() with invalid domain "
+                         "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "socket() with invalid domain - EAFNOSUPPORT");
+
+	/*socket() TEST2 : Invalid type, EINVAL Expected error*/
+        sk = socket(pf_class, -1, IPPROTO_SCTP);
+        if (sk != -1 || errno != EINVAL)
+		tst_brkm(TBROK, tst_exit, "socket() with invalid type "
+                         "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "socket() with invalid type - EINVAL");
+
+	/*socket() TEST3: opening a socket*/
+        sk = socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+        if (sk < 0)
+		tst_brkm(TBROK, tst_exit, "valid socket() call "
+                         "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "socket() - SUCCESS");
+
+	/*bind() TEST4: Invalid structure, EFAULT Expected error */
+        error = bind(sk, (struct sockaddr *)-1, sizeof(struct sockaddr_in));
+        if (error != -1 || errno != EFAULT)
+		tst_brkm(TBROK, tst_exit, "bind() with invalid address ptr "
+                         "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "bind() with invalid address ptr - EFAULT");
+
+	/*bind() TEST5: Invalid address length, EINVAL Expect error*/
+	bind_addr.sin_family = AF_INET;
+        bind_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+        bind_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+	error = bind(sk, (struct sockaddr *) &bind_addr, sizeof(bind_addr)-2);
+        if (error != -1 || errno != EINVAL)
+		tst_brkm(TBROK, tst_exit, "bind() with invalid address length "
+                         "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "bind() with invalid address length - EINVAL");
+
+	/*bind() TEST6: Invalid socket descriptor, ENOTSOCK Expect Error*/
+	strcpy(filename, "/tmp/sctptest.XXXXXX");
+	fd = mkstemp(filename);
+	if (fd == -1)
+		tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
+				filename, strerror(errno));
+	error = bind(fd, (struct sockaddr *) &bind_addr, sizeof(bind_addr));
+	if (error == -1)
+		err_no = errno;
+	close(fd);
+	unlink(filename);
+	if (error != -1 || err_no != ENOTSOCK)
+		tst_brkm(TBROK, tst_exit, "bind() with invalid socket "
+			 "descriptor error:%d, errno:%d", error, err_no);
+
+	tst_resm(TPASS, "bind() with invalid socket descriptor - ENOTSOCK");
+
+	/*bind() TEST7: Invalid host name, EADDRNOTAVAIL Expect Error*/
+	/*Assigning invalid host name*/
+	bind_addr.sin_addr.s_addr = inet_addr(SCTP_INV_LOOPBACK);
+	error = bind(sk, (struct sockaddr *) &bind_addr, sizeof(bind_addr));
+        if (error != -1 || errno != EADDRNOTAVAIL)
+		tst_brkm(TBROK, tst_exit, "bind() with invalid local "
+			 "address error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "bind() with invalid local address - EADDRNOTAVAIL");
+
+	/*bind() TEST8: Bind on a socket that has already called bind
+	EINAVL, Expected error*/
+	bind_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+	/*Calling bind first time, it should pass*/
+	test_bind(sk, (struct sockaddr *) &bind_addr, sizeof(bind_addr));
+
+	error = bind(sk, (struct sockaddr *) &bind_addr, sizeof(bind_addr));
+	if (error != -1 || errno != EINVAL)
+		tst_brkm(TBROK, tst_exit, "bind() on an already bound socket "
+			 "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "bind() on an already bound socket - EINVAL");
+
+	/*Closing the socket which succeed in bind() */
+	close(sk);
+
+	/*Opening the socket again for further test*/
+	sk = socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+	/*bind() TEST9: Bind on reserved ports EACCES, Expected error*/
+	/*Assigning a reserved port*/
+	uid = getuid();
+	if (uid != 0) {
+		bind_addr.sin_port = htons(SCTP_RESERVED_PORT);	
+		error = bind(sk, (struct sockaddr *) &bind_addr,
+			     sizeof(bind_addr));
+		if (error != -1 || errno != EACCES)
+			tst_brkm(TBROK, tst_exit, "bind() on reserverd port "
+			 "error:%d, errno:%d", error, errno);
+
+		tst_resm(TPASS, "bind() on reserved port - EACCESS");
+	}
+
+	/*bind() TEST10: INADDR_ANY address and non-zero port, bind() should 
+	succeed*/
+	bind_addr.sin_addr.s_addr = INADDR_ANY;
+        bind_addr.sin_port = htons(SCTP_TESTPORT_1);
+	error = bind(sk, (struct sockaddr *) &bind_addr,sizeof(bind_addr));
+	if ( error < 0 )
+		tst_brkm(TBROK, tst_exit, "bind() with INADDR_ANY address and "
+			 "non-zero port error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "bind() with INADDR_ANY address and non-zero port - "
+		 "SUCCESS");
+	
+	/*Closing the socket which succeed in bind() */
+	close(sk);
+
+	/*Opening the socket again for further test*/
+	sk = socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+	/*bind() TEST11: INADDR_ANY address and zero port, bind() should 
+	succeed*/
+        bind_addr.sin_port = 0;
+	error = bind(sk, (struct sockaddr *) &bind_addr,sizeof(bind_addr));
+	if ( error < 0 )
+		tst_brkm(TBROK, tst_exit, "bind() with INADDR_ANY address and "
+			 "zero port error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "bind() with INADDR_ANY address and zero port - "
+		 "SUCCESS");
+
+	/*Closing the socket which succeed in bind() */
+	close(sk);
+
+	/*Opening the socket again for further test*/
+	sk = socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+	/*bind() TEST12: local address and zero port, bind() should 
+	succeed*/
+        bind_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+        bind_addr.sin_port = 0;
+	error = bind(sk, (struct sockaddr *) &bind_addr,sizeof(bind_addr));
+	if ( error < 0 )
+		tst_brkm(TBROK, tst_exit, "bind() with local address and "
+			 "zero port error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "bind() with local address and zero port - "
+		 "SUCCESS");
+
+	/*listen() TEST13: Bad socket descriptor EBADF, Expected error*/
+	error = listen(-1, 3);
+	if (error != -1 || errno != EBADF)
+		tst_brkm(TBROK, tst_exit, "listen() with bad socket descriptor "
+			 "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "listen() with bad socket descriptor - EBADF");
+
+	/*listen() TEST14: Invalid socket ENOTSOCK, Expected error*/
+	strcpy(filename, "/tmp/sctptest.XXXXXX");
+	fd = mkstemp(filename);
+	if (fd == -1)
+		tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
+				filename, strerror(errno));
+	error = listen(fd, 3);
+	if (error == -1)
+		err_no = errno;
+	close(fd);
+	unlink(filename);
+	if (error != -1 || err_no != ENOTSOCK)
+		tst_brkm(TBROK, tst_exit, "listen() with invalid socket "
+			 "error:%d, errno:%d", error, err_no);
+
+	tst_resm(TPASS, "listen() with invalid socket - ENOTSOCK");
+
+	/*listen() TEST15:listen on a bound socket, should succeed*/
+	error = listen(sk, 3);
+	if ( error < 0 )
+		tst_brkm(TBROK, tst_exit, "listen() on a bound socket "
+			 "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "listen() on a bound socket - SUCCESS");
+
+	close(sk);
+	
+	return 0;
+}
diff --git a/src/func_tests/test_1_to_1_sockopt.c b/src/func_tests/test_1_to_1_sockopt.c
new file mode 100644
index 0000000..49f4eaf
--- /dev/null
+++ b/src/func_tests/test_1_to_1_sockopt.c
@@ -0,0 +1,434 @@
+/* SCTP kernel Implementation
+ * Copyright (c) 2003 Hewlett-Packard Development Company, L.P
+ * (C) Copyright IBM Corp. 2004
+ *
+ * This file has test cases to test negative scenarios for getsockopt ()
+ * setsockopt () call for 1-1 style sockets
+ *
+ * setsockopt () Tests:
+ * -------------------
+ * TEST1: setsockopt: Bad socket descriptor
+ * TEST2: setsockopt: Invalid socket
+ * TEST3: setsockopt: Invalid level
+ * TEST4: setsockopt: Invalid option buffer
+ * TEST5: setsockopt: Invalid option name
+ * TEST6: getsockopt: Bad socket descriptor
+ * TEST7: getsockopt: Invalid socket
+ * TEST8: getsockopt: Invalid option buffer
+ * TEST9: getsockopt: Invalid option name
+ *
+ * TEST10: getsockopt: SCTP_INITMSG
+ * TEST11: setsockopt: SCTP_INITMSG
+ * TEST12: setsockopt: SO_LINGER
+ * TEST13: getsockopt: SO_LINGER
+ * TEST14: getsockopt: SO_RCVBUF
+ * TEST15: getsockopt: SCTP_STATUS
+ * TEST16: setsockopt: SO_RCVBUF
+ * TEST17: setsockopt: SO_SNDBUF
+ * TEST18: getsockopt: SO_SNDBUF
+ * TEST19: getsockopt: SCTP_PRIMARY_ADDR
+ * TEST20: setsockopt: SCTP_PRIMARY_ADDR
+ * TEST21: getsockopt: SCTP_ASSOCINFO
+ * TEST22: setsockopt: SCTP_ASSOCINFO
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ * 
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ */ 
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sys/uio.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 22;
+int TST_CNT = 0;
+
+int
+main(void)
+{
+	int error;
+	socklen_t len;
+	int sk, sk1, sk2, acpt_sk, pf_class;
+	struct sctp_rtoinfo grtinfo;
+	struct sockaddr_in lstn_addr, conn_addr;
+	struct sctp_initmsg ginmsg; /*get the value for SCTP_INITMSG*/
+	struct sctp_initmsg sinmsg; /*set the value for SCTP_INITMSG*/
+	struct linger slinger; /*SO_LINGER structure*/
+	struct linger glinger; /*SO_LINGER structure*/
+	struct sockaddr_in addr;
+	struct sockaddr_in *gaddr;
+	struct sctp_status gstatus; /*SCTP_STATUS option*/
+	int rcvbuf_val_get, rcvbuf_val_set; /*get and set var for SO_RCVBUF*/
+	int sndbuf_val_get, sndbuf_val_set;/*get and set var for SO_SNDBUF*/
+	struct sctp_prim gprimaddr;/*SCTP_PRIMARY_ADDR get*/
+	struct sctp_prim sprimaddr;/*SCTP_PRIMARY_ADDR set*/
+	struct sctp_assocparams sassocparams;  /* SCTP_ASSOCPARAMS set */
+	struct sctp_assocparams gassocparams;  /* SCTP_ASSOCPARAMS get */
+	int fd, err_no = 0;
+	char filename[21];
+
+	/* Rather than fflush() throughout the code, set stdout to
+         * be unbuffered.
+         */
+        setvbuf(stdout, NULL, _IONBF, 0);
+        setvbuf(stderr, NULL, _IONBF, 0);
+
+	pf_class = PF_INET;
+
+	sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+	/*setsockopt() TEST1: Bad socket descriptor EBADF, Expected error*/
+        error = setsockopt(-1, IPPROTO_SCTP, 0, 0, 0);
+	if (error != -1 || errno != EBADF)
+		tst_brkm(TBROK, tst_exit, "setsockopt with a bad socket "
+			 "descriptor error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "setsockopt() with a bad socket descriptor - EBADF");
+
+	/*setsockopt() TEST2: Invalid socket ENOTSOCK, Expected error*/
+	strcpy(filename, "/tmp/sctptest.XXXXXX");
+	fd = mkstemp(filename);
+	if (fd == -1)
+		tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
+				filename, strerror(errno));
+	error = setsockopt(fd, IPPROTO_SCTP, 0, 0, 0);
+	if (error == -1)
+		err_no = errno;
+	close(fd);
+	unlink(filename);
+	if (error != -1 || err_no != ENOTSOCK)
+		tst_brkm(TBROK, tst_exit, "setsockopt with an invalid socket "
+			 "error:%d, errno:%d", error, err_no);
+
+	tst_resm(TPASS, "setsockopt() with an invalid socket - ENOTSOCK");
+
+	/*setsockopt() TEST3: Invalid level ENOPROTOOPT, Expected error*/
+        error = setsockopt(sk, -1, SCTP_RTOINFO, 0, 0);
+	if (error != -1 || errno != ENOPROTOOPT)
+		tst_brkm(TBROK, tst_exit, "setsockopt with invalid level "
+			 "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "setsockopt() with an invalid level - ENOPROTOOPT");
+
+	/*setsockopt() TEST4: Invalid option buffer EFAULT, Expected error*/
+        error = setsockopt(sk, IPPROTO_SCTP, SCTP_RTOINFO, 
+		(const struct sctp_rtoinfo *)-1, sizeof(struct sctp_rtoinfo));
+	if (error != -1 || errno != EFAULT)
+		tst_brkm(TBROK, tst_exit, "setsockopt with invalid option "
+			 "buffer error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "setsockopt() with invalid option buffer - EFAULT");
+
+	/*setsockopt() TEST5: Invalid option Name EOPNOTSUPP, Expected error*/
+        error = setsockopt(sk, IPPROTO_SCTP, SCTP_AUTOCLOSE, 0, 0);
+	if (error != -1 || errno != EOPNOTSUPP)
+		tst_brkm(TBROK, tst_exit, "setsockopt with invalid option "
+			 "name error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "setsockopt() with invalid option name - EOPNOTSUPP");
+
+	/*getsockopt() TEST6: Bad socket descriptor EBADF, Expected error*/
+        error = getsockopt(-1, IPPROTO_SCTP, 0, 0, 0);
+	if (error != -1 || errno != EBADF)
+		tst_brkm(TBROK, tst_exit, "getsockopt with a bad socket "
+			 "descriptor error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "getsockopt() with a bad socket descriptor - EBADF");
+
+	/*getsockopt() TEST7: Invalid socket ENOTSOCK, Expected error*/
+	strcpy(filename, "/tmp/sctptest.XXXXXX");
+	fd = mkstemp(filename);
+	if (fd == -1)
+		tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
+				filename, strerror(errno));
+	error = getsockopt(fd, IPPROTO_SCTP, 0, 0, 0);
+	if (error == -1)
+		err_no = errno;
+	close(fd);
+	unlink(filename);
+	if (error != -1 || err_no != ENOTSOCK)
+		tst_brkm(TBROK, tst_exit, "getsockopt with an invalid socket "
+			 "error:%d, errno:%d", error, err_no);
+
+	tst_resm(TPASS, "getsockopt() with an invalid socket - ENOTSOCK");
+#if 0
+	/*getsockopt() TEST3: Invalid level ENOPROTOOPT, Expected error*/
+	/*I have commented this test case because it is returning EOPNOTSUPP.
+	When I checked the code there also it is returning EOPNOTSUPP. As this
+	is not specific to TCP style, I do not want to do the code change*/
+	
+        error = getsockopt(sk, -1, SCTP_RTOINFO, 0, 0);
+	if (error != -1 || errno != ENOPROTOOPT)
+		tst_brkm(TBROK, tst_exit, "getsockopt with invalid level "
+			 "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "getsockopt() with an invalid level - ENOPROTOOPT");
+#endif
+	len = sizeof(struct sctp_rtoinfo);
+
+	/*getsockopt() TEST8: Invalid option buffer EFAULT, Expected error*/
+        error = getsockopt(sk, IPPROTO_SCTP, SCTP_RTOINFO, 
+			   (struct sctp_rtoinfo *)-1, &len);
+	if (error != -1 || errno != EFAULT)
+		tst_brkm(TBROK, tst_exit, "getsockopt with invalid option "
+			 "buffer error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "getsockopt() with invalid option buffer - EFAULT");
+
+	/*getsockopt() TEST9: Invalid option Name EOPNOTSUPP, Expected error*/
+        error = getsockopt(sk, IPPROTO_SCTP, SCTP_AUTOCLOSE, &grtinfo, &len);
+	if (error != -1 || errno != EOPNOTSUPP)
+		tst_brkm(TBROK, tst_exit, "getsockopt with invalid option "
+			 "name error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "getsockopt() with invalid option name - EOPNOTSUPP");
+
+	close(sk);
+
+	sk1 = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+	sk2 = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+	lstn_addr.sin_family = AF_INET;
+        lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+        lstn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+	conn_addr.sin_family = AF_INET;
+        conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+        conn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+        len = sizeof(struct sctp_initmsg);
+
+	/* TEST10: Test cases for getsockopt SCTP_INITMSG */
+	test_getsockopt(sk1, SCTP_INITMSG, &ginmsg, &len);
+
+	tst_resm(TPASS, "getsockopt() SCTP_INITMSG - SUCCESS");
+
+	sinmsg.sinit_num_ostreams = 5;
+        sinmsg.sinit_max_instreams = 5;
+        sinmsg.sinit_max_attempts = 3;
+        sinmsg.sinit_max_init_timeo = 30;
+	/* TEST11: Test case for setsockopt SCTP_INITMSG */
+	test_setsockopt(sk1, SCTP_INITMSG, &sinmsg, sizeof(sinmsg));
+
+	test_getsockopt(sk1, SCTP_INITMSG, &ginmsg, &len);
+
+	if (sinmsg.sinit_num_ostreams != ginmsg.sinit_num_ostreams &&
+	    sinmsg.sinit_max_instreams != ginmsg.sinit_max_instreams &&
+	    sinmsg.sinit_max_attempts != ginmsg.sinit_max_attempts &&
+	    sinmsg.sinit_max_init_timeo != ginmsg.sinit_max_init_timeo)
+		tst_brkm(TBROK, tst_exit, "setsockopt/getsockopt SCTP_INITMSG "
+			 "compare failed");
+
+	tst_resm(TPASS, "setsockopt() SCTP_INITMSG - SUCCESS");
+
+	/*Now get the values on different endpoint*/
+	test_getsockopt(sk2, SCTP_INITMSG, &ginmsg, &len);
+
+	/*Comparison should not succeed here*/
+	if (sinmsg.sinit_num_ostreams == ginmsg.sinit_num_ostreams &&
+	    sinmsg.sinit_max_instreams == ginmsg.sinit_max_instreams &&
+	    sinmsg.sinit_max_attempts == ginmsg.sinit_max_attempts &&
+	    sinmsg.sinit_max_init_timeo == ginmsg.sinit_max_init_timeo)
+		tst_brkm(TBROK, tst_exit, "setsockopt/getsockopt SCTP_INITMSG "
+			 "unexpected compare success");
+
+	/* SO_LINGER Test with l_onff = 0 and l_linger = 0 */
+	slinger.l_onoff = 0;
+	slinger.l_linger = 0;
+	test_bind(sk1, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr));
+	test_listen(sk1, 10 );
+	len = sizeof(struct sockaddr_in);
+	test_connect(sk2, (struct sockaddr *) &conn_addr, len);
+
+	acpt_sk = test_accept(sk1, (struct sockaddr *)&addr, &len);
+
+        len = sizeof(struct linger);
+	/* TEST12: Test case for setsockopt SO_LINGER */
+	error = setsockopt(sk2, SOL_SOCKET, SO_LINGER, &slinger, len);
+	if (error < 0)
+		tst_brkm(TBROK, tst_exit, "setsockopt SO_LINGER "
+                         "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "setsockopt() SO_LINGER - SUCCESS");
+
+	/* TEST13: Test case for getsockopt SO_LINGER */
+	error = getsockopt(sk2, SOL_SOCKET, SO_LINGER, &glinger, &len);
+	if (error < 0)
+		tst_brkm(TBROK, tst_exit, "getsockopt SO_LINGER "
+                         "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "getsockopt() SO_LINGER - SUCCESS");
+
+	if (slinger.l_onoff != glinger.l_onoff || 
+	    slinger.l_linger != glinger.l_linger)
+		tst_brkm(TBROK, tst_exit, "setsockopt/getsockopt SO_LINGER "
+			 "compare failed");
+	
+	/*First gets the default SO_RCVBUF value and comapres with the
+	value obtained from SCTP_STATUS*/
+	len = sizeof(int);
+	/* TEST14: Test case for getsockopt SO_RCVBUF */
+	error = getsockopt(sk2, SOL_SOCKET, SO_RCVBUF, &rcvbuf_val_get, &len);
+	if (error < 0)
+		tst_brkm(TBROK, tst_exit, "getsockopt SO_RCVBUF "
+                         "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "getsockopt() SO_RCVBUF - SUCCESS");
+
+	len = sizeof(struct sctp_status);
+	/* TEST15: Test case for getsockopt SCTP_STATUS */
+	error = getsockopt(sk2, IPPROTO_SCTP, SCTP_STATUS, &gstatus, &len);
+	if (error < 0)
+		tst_brkm(TBROK, tst_exit, "getsockopt SCTP_STATUS "
+                         "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "getsockopt() SCTP_STATUS - SUCCESS");
+
+	/* Reducing the SO_RCVBUF value using setsockopt() */
+	/* Upstream has changed the MIN_RCVBUF (2048 + sizeof(struct sk_buff)) */
+	len = sizeof(int);
+	rcvbuf_val_set = 2048;
+	/* TEST16: Test case for setsockopt SO_RCVBUF */
+	error = setsockopt(sk2, SOL_SOCKET, SO_RCVBUF, &rcvbuf_val_set, len);
+	if (error < 0)
+		tst_brkm(TBROK, tst_exit, "setsockopt SO_RCVBUF "
+                         "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "setsockopt() SO_RCVBUF - SUCCESS");
+
+	error = getsockopt(sk2, SOL_SOCKET, SO_RCVBUF, &rcvbuf_val_get, &len);
+	if (error < 0)
+		tst_brkm(TBROK, tst_exit, "getsockopt SO_RCVBUF "
+                         "error:%d, errno:%d", error, errno);
+
+	if ((2 * rcvbuf_val_set) != rcvbuf_val_get)
+		tst_brkm(TBROK, tst_exit, "Comparison failed:Set value and "
+			 "got value differs Set Value=%d Get Value=%d",
+			 (2*rcvbuf_val_set), rcvbuf_val_get);
+
+	sndbuf_val_set = 2304;
+	/* TEST17: Test case for setsockopt SO_SNDBUF */
+	error = setsockopt(sk2, SOL_SOCKET, SO_SNDBUF, &sndbuf_val_set, len);
+	if (error < 0)
+		tst_brkm(TBROK, tst_exit, "setsockopt SO_SNDBUF "
+                         "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "setsockopt() SO_SNDBUF - SUCCESS");
+
+	/* TEST18: Test case for getsockopt SO_SNDBUF */
+	error = getsockopt(sk2, SOL_SOCKET, SO_SNDBUF, &sndbuf_val_get, &len);
+	if (error < 0)
+		tst_brkm(TBROK, tst_exit, "getsockopt SO_SNDBUF "
+                         "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "getsockopt() SO_SNDBUF - SUCCESS");
+
+	if ((2 * sndbuf_val_set) != sndbuf_val_get)
+		tst_brkm(TBROK, tst_exit, "Comparison failed:Set value and "
+			 "got value differs Set Value=%d Get Value=%d\n",
+			 (2*sndbuf_val_set), sndbuf_val_get);
+
+            
+	/* Getting the primary address using SCTP_PRIMARY_ADDR */
+        len = sizeof(struct sctp_prim);
+	/* TEST19: Test case for getsockopt SCTP_PRIMARY_ADDR */
+	error = getsockopt(sk2,IPPROTO_SCTP, SCTP_PRIMARY_ADDR, &gprimaddr,
+			   &len);
+	if (error < 0)
+		tst_brkm(TBROK, tst_exit, "getsockopt SCTP_PRIMARY_ADDR "
+                         "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "getsockopt() SCTP_PRIMARY_ADDR - SUCCESS");
+
+	gaddr = (struct sockaddr_in *) &gprimaddr.ssp_addr;
+	if(htons(gaddr->sin_port) != lstn_addr.sin_port &&
+	   gaddr->sin_family != lstn_addr.sin_family &&
+	   gaddr->sin_addr.s_addr != lstn_addr.sin_addr.s_addr)
+		tst_brkm(TBROK, tst_exit, "getsockopt SCTP_PRIMARY_ADDR value "
+			 "mismatch");
+
+	memcpy(&sprimaddr, &gprimaddr, sizeof(struct sctp_prim));
+
+	/* TEST20: Test case for setsockopt SCTP_PRIMARY_ADDR */
+	error = setsockopt(sk2,IPPROTO_SCTP, SCTP_PRIMARY_ADDR, &sprimaddr,
+			   len);
+	if (error < 0)
+		tst_brkm(TBROK, tst_exit, "setsockopt SCTP_PRIMARY_ADDR "
+                         "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "setsockopt() SCTP_PRIMARY_ADDR - SUCCESS");
+
+	/* TEST21: Test case for getsockopt SCTP_PRIMARY_ADDR */
+	/* Getting the association info using SCTP_ASSOCINFO */
+        len = sizeof(struct sctp_assocparams);
+	error = getsockopt(sk2, IPPROTO_SCTP, SCTP_ASSOCINFO, &gassocparams,
+			   &len);
+	if (error < 0)
+		tst_brkm(TBROK, tst_exit, "getsockopt SCTP_ASSOCINFO "
+                         "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "getsockopt() SCTP_ASSOCINFO - SUCCESS");
+
+	/* TEST21: Test case for setsockopt SCTP_ASSOCINFO */
+	memcpy(&sassocparams, &gassocparams, sizeof(struct sctp_assocparams));
+	sassocparams.sasoc_asocmaxrxt += 5;
+	sassocparams.sasoc_cookie_life += 10;
+
+	error = setsockopt(sk2, IPPROTO_SCTP, SCTP_ASSOCINFO, &sassocparams,
+			   len);
+	if (error < 0)
+		tst_brkm(TBROK, tst_exit, "setsockopt SCTP_ASSOCINFO "
+                         "error:%d, errno:%d", error, errno);
+
+	error = getsockopt(sk2, IPPROTO_SCTP, SCTP_ASSOCINFO, &gassocparams,
+			   &len);
+	if (error < 0)
+		tst_brkm(TBROK, tst_exit, "getsockopt SCTP_ASSOCINFO "
+                         "error:%d, errno:%d", error, errno);
+
+	if (sassocparams.sasoc_asocmaxrxt != gassocparams.sasoc_asocmaxrxt ||
+	    sassocparams.sasoc_cookie_life != gassocparams.sasoc_cookie_life)
+		tst_brkm(TBROK, tst_exit, "getsockopt SCTP_ASSOCINFO value "
+			 "mismatch");
+	tst_resm(TPASS, "setsockopt() SCTP_ASSOCINFO - SUCCESS");
+
+	close(sk2);
+	close(sk1);
+	close(acpt_sk);
+
+	return 0;
+}
diff --git a/src/func_tests/test_1_to_1_threads.c b/src/func_tests/test_1_to_1_threads.c
new file mode 100644
index 0000000..e2a7eee
--- /dev/null
+++ b/src/func_tests/test_1_to_1_threads.c
@@ -0,0 +1,196 @@
+/* SCTP kernel Implementation
+ * Copyright (c) 2003 Hewlett-Packard Development Company, L.P
+ * (C) Copyright IBM Corp. 2004
+ *
+ * This file does send and receive for 500 threads on a unique association for
+ * THREAD_SND_RCV_LOOPS = 10 many times. To change the number of threads 
+ * change the THREADS valuen and loop change the THREAD_SND_RCV_LOOPS.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release
+ *
+ */
+#include <pthread.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>         /* for sockaddr_in */
+#include <arpa/inet.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sys/uio.h>
+#include <linux/socket.h>
+#include <sctputil.h>
+
+#define THREADS 10    /* FIXME should be 500 instead of 10 */
+#define THREAD_SND_RCV_LOOPS 10
+
+char *TCID = __FILE__;
+int TST_TOTAL = 1;
+int TST_CNT = 0;
+
+int client_sk;
+int server_sk;
+int acpt_sk;
+struct sockaddr_in  conn_addr;
+char *message = "hello, world!\n";
+
+void 
+t_recv(void) {
+	int cnt;
+	struct msghdr inmessage;
+	struct iovec iov;
+        char incmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+        char * buffer;
+
+	memset(&inmessage, 0, sizeof(inmessage));
+        buffer = malloc(100);
+
+        iov.iov_base = buffer;
+        iov.iov_len = 100;
+        inmessage.msg_iov = &iov;
+        inmessage.msg_iovlen = 1;
+        inmessage.msg_control = incmsg;
+        inmessage.msg_controllen = sizeof(incmsg);
+
+	cnt = test_recvmsg(acpt_sk,&inmessage, MSG_WAITALL);
+        test_check_msg_data(&inmessage, cnt, strlen(message) + 1, MSG_EOR,
+			    0, 0);
+}
+
+void
+t_send(void) {
+        struct msghdr outmessage;
+        struct sctp_sndrcvinfo *sinfo;
+        struct cmsghdr *cmsg;
+        struct iovec out_iov;
+        char outcmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+
+        memset(&outmessage, 0, sizeof(outmessage));
+        outmessage.msg_name = &conn_addr;
+        outmessage.msg_namelen = sizeof(conn_addr);
+        outmessage.msg_iov = &out_iov;
+        outmessage.msg_iovlen = 1;
+        outmessage.msg_control = outcmsg;
+        outmessage.msg_controllen = sizeof(outcmsg);
+        outmessage.msg_flags = 0;
+
+        cmsg = CMSG_FIRSTHDR(&outmessage);
+	cmsg->cmsg_level = IPPROTO_SCTP;
+        cmsg->cmsg_type = SCTP_SNDRCV;
+        cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+        outmessage.msg_controllen = cmsg->cmsg_len;
+
+        sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+        memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+        outmessage.msg_iov->iov_base = message;
+        outmessage.msg_iov->iov_len = (strlen(message) + 1);
+
+        test_sendmsg(client_sk, &outmessage, 0, strlen(message)+1);
+}
+
+void *relay(void *arg)
+{
+	int id = *(int *) arg;
+
+	if (id == 0) {
+		t_send();
+	} else {
+		t_recv();
+		t_send();
+	}
+
+	pthread_exit(NULL);
+}
+
+int 
+main(void) 
+{
+
+	int      cnt,i;
+	int      pth[THREADS];
+	pthread_t       thread[THREADS];
+	int  status;
+	int  exit_status;
+	void *      result;
+	pthread_attr_t attr;
+	struct sockaddr_in lstn_addr;
+	socklen_t len = sizeof(struct sockaddr_in);
+	struct sockaddr_in svr_addr;
+
+	pthread_attr_init(&attr);
+	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+	
+	server_sk = test_socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP);
+	client_sk = test_socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP);
+
+	lstn_addr.sin_family = AF_INET;
+        lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+	lstn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+	conn_addr.sin_family = AF_INET;
+        conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+	conn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+	test_bind(server_sk, (struct sockaddr *)&lstn_addr,
+		 sizeof(struct sockaddr_in));
+
+	test_listen(server_sk,10);
+
+	test_connect(client_sk,(struct sockaddr *)&conn_addr,len);
+
+	acpt_sk = test_accept(server_sk, (struct sockaddr *)&svr_addr, &len);
+
+	for ( i = 0; i < THREAD_SND_RCV_LOOPS; i++ ) {
+		for (cnt = 0; cnt < THREADS; cnt++) {
+			pth[cnt] = cnt;
+			status = pthread_create(&thread[cnt], &attr, relay, &pth[cnt]);
+			if (status)
+				tst_brkm(TBROK, tst_exit, "pthread_create "
+                         		 "failed status:%d, errno:%d", status,
+					 errno);
+		}
+
+		pthread_attr_destroy(&attr);
+		for (cnt = 0; cnt < THREADS ; cnt++) {
+			exit_status = pthread_join (thread[cnt], &result);
+			if (exit_status == -1)
+				tst_brkm(TBROK, tst_exit, "pthread_join "
+                         		 "Thread #%d exited with status:%d",
+					 cnt, exit_status);
+		}
+	}
+
+	tst_resm(TPASS, "send and receive data across multiple threads - "
+		 "SUCCESS");
+
+	return 0;
+}
diff --git a/src/func_tests/test_assoc_abort.c b/src/func_tests/test_assoc_abort.c
new file mode 100644
index 0000000..f8019c7
--- /dev/null
+++ b/src/func_tests/test_assoc_abort.c
@@ -0,0 +1,243 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2001, 2003
+ * Copyright (c) 1999-2000 Cisco, Inc.
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ * Copyright (c) 2001 Intel Corp.
+ * Copyright (c) 2001 Nokia, Inc.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ *    Ardelle Fan <ardelle.fan@intle.com>
+ *    Sridhar Samudrala <sri@us.ibm.com>
+ */
+
+/* This is a functional test to verify the ungraceful abort of an
+ * association.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 1;
+int TST_CNT = 0;
+
+#define MAX_CLIENTS 10
+
+int
+main(int argc, char *argv[])
+{
+	int svr_sk, clt_sk[MAX_CLIENTS];
+	sockaddr_storage_t svr_loop, clt_loop[MAX_CLIENTS];
+	sctp_assoc_t svr_associd[MAX_CLIENTS];
+	struct iovec iov;
+	struct msghdr inmessage;
+	struct msghdr outmessage;
+	char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+	char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+	struct cmsghdr *cmsg;
+	struct sctp_sndrcvinfo *sinfo;
+        struct iovec out_iov;
+        int error;
+	uint32_t ppid;
+	uint32_t stream;
+	struct sctp_assoc_change *sac;
+	char *big_buffer;
+	int i;
+        char *message = "hello, world!\n";
+	struct sctp_status status;
+	socklen_t status_len;
+
+        /* Rather than fflush() throughout the code, set stdout to 
+	 * be unbuffered.  
+	 */ 
+	setvbuf(stdout, NULL, _IONBF, 0); 
+
+	/* Create and bind the server socket.  */
+        svr_sk = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+	svr_loop.v4.sin_family = AF_INET;
+	svr_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+	svr_loop.v4.sin_port = htons(SCTP_TESTPORT_1);
+	test_bind(svr_sk, &svr_loop.sa, sizeof(svr_loop));
+
+	/* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+	test_enable_assoc_change(svr_sk);
+
+	/* Mark server socket as being able to accept new associations.  */
+	test_listen(svr_sk, 1);
+
+	/* Create and bind all the client sockets.  */
+	for (i = 0; i < MAX_CLIENTS; i++) {
+		clt_sk[i] = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+
+		clt_loop[i].v4.sin_family = AF_INET;
+		clt_loop[i].v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+		clt_loop[i].v4.sin_port = htons(SCTP_TESTPORT_2 + i);
+		test_bind(clt_sk[i], &clt_loop[i].sa, sizeof(clt_loop[i]));
+
+		test_enable_assoc_change(clt_sk[i]);
+	}
+
+	/* Build up a msghdr structure we can use for all sending.  */
+	outmessage.msg_name = &svr_loop;
+	outmessage.msg_namelen = sizeof(svr_loop);
+	outmessage.msg_iov = &out_iov;
+	outmessage.msg_iovlen = 1;
+	outmessage.msg_control = outcmsg;
+	outmessage.msg_controllen = sizeof(outcmsg);
+	outmessage.msg_flags = 0;
+	cmsg = CMSG_FIRSTHDR(&outmessage);
+	cmsg->cmsg_level = IPPROTO_SCTP;
+	cmsg->cmsg_type = SCTP_SNDRCV;
+	cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+	outmessage.msg_controllen = cmsg->cmsg_len;
+	sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+	memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+	ppid = rand(); /* Choose an arbitrary value. */
+	stream = 1; 
+	sinfo->sinfo_ppid = ppid;
+	sinfo->sinfo_stream = stream;
+	out_iov.iov_base = message;
+	out_iov.iov_len = strlen(message) + 1;
+	
+        /* Send the first message from all the clients to the server.  This 
+	 * will create the associations.  
+	 */
+	for (i = 0; i < MAX_CLIENTS; i++)
+		test_sendmsg(clt_sk[i], &outmessage, 0, strlen(message) + 1);
+        
+	/* Initialize inmessage for all receives. */
+	big_buffer = test_malloc(REALLY_BIG);
+        memset(&inmessage, 0, sizeof(inmessage));	
+	iov.iov_base = big_buffer;
+	iov.iov_len = REALLY_BIG;
+	inmessage.msg_iov = &iov;
+	inmessage.msg_iovlen = 1;
+	inmessage.msg_control = incmsg;
+
+	/* Get the communication up message on all client sockets.  */
+	for (i = 0; i < MAX_CLIENTS; i++) {
+		inmessage.msg_controllen = sizeof(incmsg);
+		error = test_recvmsg(clt_sk[i], &inmessage, MSG_WAITALL);
+		test_check_msg_notification(&inmessage, error,
+					    sizeof(struct sctp_assoc_change),
+					    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);	
+	}
+
+	/* Get the communication up message and the data message on the
+	 * server sockets for all the clients.  
+	 */
+	for (i = 0; i < MAX_CLIENTS; i++) {
+		inmessage.msg_controllen = sizeof(incmsg);
+		error = test_recvmsg(svr_sk, &inmessage, MSG_WAITALL);
+		test_check_msg_notification(&inmessage, error,
+					    sizeof(struct sctp_assoc_change),
+					    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);	
+
+		inmessage.msg_controllen = sizeof(incmsg);
+		error = test_recvmsg(svr_sk, &inmessage, MSG_WAITALL);
+		test_check_msg_data(&inmessage, error, strlen(message) + 1, 
+				    MSG_EOR, stream, ppid);
+		sac = (struct sctp_assoc_change *)iov.iov_base;
+		svr_associd[i] = sac->sac_assoc_id;
+	}
+
+	outmessage.msg_name = NULL;
+	outmessage.msg_namelen = 0;
+	outmessage.msg_iov = NULL;
+	outmessage.msg_iovlen = 0;
+	outmessage.msg_control = outcmsg;
+	outmessage.msg_controllen = sizeof(outcmsg);
+	outmessage.msg_flags = 0;
+	cmsg = CMSG_FIRSTHDR(&outmessage);
+	cmsg->cmsg_level = IPPROTO_SCTP;
+	cmsg->cmsg_type = SCTP_SNDRCV;
+	cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+	outmessage.msg_controllen = cmsg->cmsg_len;
+	sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+	memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+	sinfo->sinfo_flags |= SCTP_ABORT;
+
+	/* Shutdown all the associations of the server socket in a loop.  */
+	for (i = 0; i < MAX_CLIENTS; i++) {
+		sinfo->sinfo_assoc_id = svr_associd[i];
+
+		/* Verify that the association is present. */
+		memset(&status, 0, sizeof(struct sctp_status));
+		status.sstat_assoc_id = sinfo->sinfo_assoc_id;
+		status_len = sizeof(struct sctp_status);
+		error = getsockopt(svr_sk, SOL_SCTP, SCTP_STATUS,
+				   &status, &status_len);
+		if (error)
+			tst_brkm(TBROK, tst_exit,
+				 "getsockopt(SCTP_STATUS): %s",
+				 strerror(errno));
+
+		/* Call sendmsg() to abort the association.  */
+		test_sendmsg(svr_sk, &outmessage, 0, 0);
+
+		/* Verify that the association is no longer present.  */
+		memset(&status, 0, sizeof(struct sctp_status));
+		status.sstat_assoc_id = sinfo->sinfo_assoc_id;
+		status_len = sizeof(struct sctp_status);
+		error = getsockopt(svr_sk, SOL_SCTP, SCTP_STATUS, 
+				   &status, &status_len);
+		if ((error != -1) && (errno != EINVAL))
+			tst_brkm(TBROK, tst_exit,
+				 "getsockopt(SCTP_STATUS) "
+				 "error:%d errno:%d", error, errno);
+	}
+
+	close(svr_sk);
+
+        /* Get the COMM_LOST notification. */
+	for (i = 0; i < MAX_CLIENTS; i++) {
+		inmessage.msg_controllen = sizeof(incmsg);
+		error = test_recvmsg(clt_sk[i], &inmessage, MSG_WAITALL);
+		test_check_msg_notification(&inmessage, error,
+					    sizeof(struct sctp_assoc_change)+4,
+					    SCTP_ASSOC_CHANGE, SCTP_COMM_LOST);	
+
+		close(clt_sk[i]);
+	}
+
+	tst_resm(TPASS, "ABORT an association using SCTP_ABORT"); 
+
+        /* Indicate successful completion.  */
+        return 0;
+}
diff --git a/src/func_tests/test_assoc_shutdown.c b/src/func_tests/test_assoc_shutdown.c
new file mode 100644
index 0000000..a007117
--- /dev/null
+++ b/src/func_tests/test_assoc_shutdown.c
@@ -0,0 +1,245 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2001, 2003
+ * Copyright (c) 1999-2000 Cisco, Inc.
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ * Copyright (c) 2001 Intel Corp.
+ * Copyright (c) 2001 Nokia, Inc.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ *    Sridhar Samudrala <sri@us.ibm.com>
+ */
+
+/* This is a functional test to verify the graceful shutdown of an
+ * association.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 1;
+int TST_CNT = 0;
+
+#define MAX_CLIENTS 10
+
+int
+main(int argc, char *argv[])
+{
+	int svr_sk, clt_sk[MAX_CLIENTS];
+	sctp_assoc_t svr_associd[MAX_CLIENTS];
+	sockaddr_storage_t svr_loop, clt_loop[MAX_CLIENTS];
+	struct iovec iov;
+	struct msghdr inmessage;
+	struct msghdr outmessage;
+	char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+	char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+	struct cmsghdr *cmsg;
+	struct sctp_sndrcvinfo *sinfo;
+        struct iovec out_iov;
+        int error;
+	uint32_t ppid;
+	uint32_t stream;
+	struct sctp_assoc_change *sac;
+	char *big_buffer;
+	int i;
+        char *message = "hello, world!\n";
+	struct sctp_status status;
+	socklen_t status_len;
+
+        /* Rather than fflush() throughout the code, set stdout to 
+	 * be unbuffered.  
+	 */ 
+	setvbuf(stdout, NULL, _IONBF, 0); 
+
+	/* Create and bind the server socket.  */
+        svr_sk = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+
+	svr_loop.v4.sin_family = AF_INET;
+	svr_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+	svr_loop.v4.sin_port = htons(SCTP_TESTPORT_1);
+	test_bind(svr_sk, &svr_loop.sa, sizeof(svr_loop));
+
+	/* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+	test_enable_assoc_change(svr_sk);
+
+	/* Mark server socket as being able to accept new associations.  */
+	test_listen(svr_sk, 1);
+
+	/* Create and bind all the client sockets.  */
+	for (i = 0; i < MAX_CLIENTS; i++) {
+		clt_sk[i] = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+
+		clt_loop[i].v4.sin_family = AF_INET;
+		clt_loop[i].v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+		clt_loop[i].v4.sin_port = htons(SCTP_TESTPORT_2 + i);
+		test_bind(clt_sk[i], &clt_loop[i].sa, sizeof(clt_loop[i]));
+
+		test_enable_assoc_change(clt_sk[i]);
+	}
+
+	/* Build up a msghdr structure we can use for all sending.  */
+	outmessage.msg_name = &svr_loop;
+	outmessage.msg_namelen = sizeof(svr_loop);
+	outmessage.msg_iov = &out_iov;
+	outmessage.msg_iovlen = 1;
+	outmessage.msg_control = outcmsg;
+	outmessage.msg_controllen = sizeof(outcmsg);
+	outmessage.msg_flags = 0;
+	cmsg = CMSG_FIRSTHDR(&outmessage);
+	cmsg->cmsg_level = IPPROTO_SCTP;
+	cmsg->cmsg_type = SCTP_SNDRCV;
+	cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+	outmessage.msg_controllen = cmsg->cmsg_len;
+	sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+	memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+	ppid = rand(); /* Choose an arbitrary value. */
+	stream = 1; 
+	sinfo->sinfo_ppid = ppid;
+	sinfo->sinfo_stream = stream;
+	out_iov.iov_base = message;
+	out_iov.iov_len = strlen(message) + 1;
+	
+        /* Send the first message from all the clients to the server.  This 
+	 * will create the associations.  
+	 */
+	for (i = 0; i < MAX_CLIENTS; i++)
+		test_sendmsg(clt_sk[i], &outmessage, 0, strlen(message)+1);
+        
+	/* Initialize inmessage for all receives. */
+	big_buffer = test_malloc(REALLY_BIG);
+        memset(&inmessage, 0, sizeof(inmessage));	
+	iov.iov_base = big_buffer;
+	iov.iov_len = REALLY_BIG;
+	inmessage.msg_iov = &iov;
+	inmessage.msg_iovlen = 1;
+	inmessage.msg_control = incmsg;
+
+	/* Get the communication up message on all client sockets.  */
+	for (i = 0; i < MAX_CLIENTS; i++) {
+		inmessage.msg_controllen = sizeof(incmsg);
+		error = test_recvmsg(clt_sk[i], &inmessage, MSG_WAITALL);
+		test_check_msg_notification(&inmessage, error,
+					    sizeof(struct sctp_assoc_change),
+					    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);	
+	}
+
+	/* Get the communication up message and the data message on the
+	 * server sockets for all the clients.  
+	 */
+	for (i = 0; i < MAX_CLIENTS; i++) {
+		inmessage.msg_controllen = sizeof(incmsg);
+		error = test_recvmsg(svr_sk, &inmessage, MSG_WAITALL);
+		test_check_msg_notification(&inmessage, error,
+					    sizeof(struct sctp_assoc_change),
+					    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);		
+
+		inmessage.msg_controllen = sizeof(incmsg);
+		error = test_recvmsg(svr_sk, &inmessage, MSG_WAITALL);
+		test_check_msg_data(&inmessage, error, strlen(message)+1,
+				    MSG_EOR, stream, ppid);
+		sac = (struct sctp_assoc_change *)iov.iov_base;
+		svr_associd[i] = sac->sac_assoc_id;
+	}
+
+	/* Build up a msghdr structure we can use for all sending.  */
+	outmessage.msg_name = NULL;
+	outmessage.msg_namelen = 0;
+	outmessage.msg_iov = NULL;
+	outmessage.msg_iovlen = 0;
+	outmessage.msg_control = outcmsg;
+	outmessage.msg_controllen = sizeof(outcmsg);
+	outmessage.msg_flags = 0;
+	cmsg = CMSG_FIRSTHDR(&outmessage);
+	cmsg->cmsg_level = IPPROTO_SCTP;
+	cmsg->cmsg_type = SCTP_SNDRCV;
+	cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+	outmessage.msg_controllen = cmsg->cmsg_len;
+	sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+	memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+	sinfo->sinfo_flags |= SCTP_EOF;
+
+	/* Shutdown all the associations of the server socket in a loop.  */
+	for (i = 0; i < MAX_CLIENTS; i++) {
+		sinfo->sinfo_assoc_id = svr_associd[i];
+
+		/* Verify that the association is present. */
+		memset(&status, 0, sizeof(struct sctp_status));
+		status.sstat_assoc_id = sinfo->sinfo_assoc_id;
+		status_len = sizeof(struct sctp_status);
+		error = getsockopt(svr_sk, SOL_SCTP, SCTP_STATUS,
+				   &status, &status_len);
+		if (error)
+			tst_brkm(TBROK, tst_exit,
+				 "getsockopt(SCTP_STATUS): %s",
+				 strerror(errno));
+
+		/* Call sendmsg() to shutdown the association.  */
+		test_sendmsg(svr_sk, &outmessage, 0, 0);
+
+		/* Verify that the association is no longer present.  */
+		memset(&status, 0, sizeof(struct sctp_status));
+		status.sstat_assoc_id = sinfo->sinfo_assoc_id;
+		status_len = sizeof(struct sctp_status);
+		error = getsockopt(svr_sk, SOL_SCTP, SCTP_STATUS, 
+				   &status, &status_len);
+		if ((error != -1) && (errno != EINVAL))
+			tst_brkm(TBROK, tst_exit,
+				 "getsockopt(SCTP_STATUS) "
+				 "error:%d errno:%d", error, errno);
+	}
+
+	close(svr_sk);
+
+        /* Get the shutdown complete notification. */
+	for (i = 0; i < MAX_CLIENTS; i++) {
+		inmessage.msg_controllen = sizeof(incmsg);
+		error = test_recvmsg(clt_sk[i], &inmessage, MSG_WAITALL);
+		test_check_msg_notification(&inmessage, error,
+					    sizeof(struct sctp_assoc_change),
+					    SCTP_ASSOC_CHANGE,
+					    SCTP_SHUTDOWN_COMP);
+
+		close(clt_sk[i]);
+	}
+
+	tst_resm(TPASS, "Graceful shutdown of associations using SCTP_EOF"); 
+
+        /* Indicate successful completion.  */
+        return 0;
+}
diff --git a/src/func_tests/test_autoclose.c b/src/func_tests/test_autoclose.c
new file mode 100644
index 0000000..e65fac0
--- /dev/null
+++ b/src/func_tests/test_autoclose.c
@@ -0,0 +1,167 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2001, 2003
+ * Copyright (c) 1999-2000 Cisco, Inc.
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ * Copyright (c) 2001 Intel Corp.
+ * Copyright (c) 2001 Nokia, Inc.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ * Sridhar Samudrala <sri@us.ibm.com>
+ */
+
+/* This is a Functional Test to verify autoclose functionality and the
+ * socket option SCTP_AUTOCLOSE that can be used to specify the duration in
+ * which an idle association is automatically closed. 
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 1;
+int TST_CNT = 0;
+
+int
+main(int argc, char *argv[])
+{
+	int sk1, sk2;
+	sockaddr_storage_t loop1, loop2;
+	struct msghdr inmessage, outmessage;
+	struct iovec iov, out_iov;
+	int error;
+	char *big_buffer;
+	char *message = "hello, world!\n";
+	uint32_t autoclose;
+
+	/* Rather than fflush() throughout the code, set stdout to 
+	 * be unbuffered. 
+	 */
+	setvbuf(stdout, NULL, _IONBF, 0); 
+
+	loop1.v4.sin_family = AF_INET;
+	loop1.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+	loop1.v4.sin_port = htons(SCTP_TESTPORT_1);
+
+	loop2.v4.sin_family = AF_INET;
+	loop2.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+	loop2.v4.sin_port = htons(SCTP_TESTPORT_2);
+
+	/* Create the two endpoints which will talk to each other.  */
+	sk1 = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+	sk2 = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+
+	/* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+	test_enable_assoc_change(sk1);
+	test_enable_assoc_change(sk2);
+
+	/* Bind these sockets to the test ports.  */
+	test_bind(sk1, &loop1.sa, sizeof(loop1));
+	test_bind(sk2, &loop2.sa, sizeof(loop2));
+
+	/* Mark sk2 as being able to accept new associations.  */
+	test_listen(sk2, 1);
+
+	/* Set the autoclose duration for the associations created on sk1 
+	 * and sk2 to be 5 seconds.  
+	 */ 
+	autoclose = 5;
+	test_setsockopt(sk1, SCTP_AUTOCLOSE, &autoclose, sizeof(autoclose));
+	test_setsockopt(sk2, SCTP_AUTOCLOSE, &autoclose, sizeof(autoclose));
+
+	/* Send the first message.  This will create the association.  */
+	memset(&outmessage, 0, sizeof(outmessage));	
+	outmessage.msg_name = &loop2;
+	outmessage.msg_namelen = sizeof(loop2);
+	outmessage.msg_iov = &out_iov;
+	outmessage.msg_iovlen = 1;
+	outmessage.msg_iov->iov_base = message;
+	outmessage.msg_iov->iov_len = strlen(message) + 1;
+
+	test_sendmsg(sk1, &outmessage, 0, strlen(message)+1);
+
+	/* Initialize inmessage for all receives. */
+	big_buffer = test_malloc(REALLY_BIG);
+        memset(&inmessage, 0, sizeof(inmessage));	
+	iov.iov_base = big_buffer;
+	iov.iov_len = REALLY_BIG;
+	inmessage.msg_iov = &iov;
+	inmessage.msg_iovlen = 1;
+	inmessage.msg_control = NULL;
+
+	/* Get the communication up message on sk2.  */
+	error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage, error,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);	
+
+	/* Get the communication up message on sk1.  */
+	error = test_recvmsg(sk1, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage, error,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);	
+
+	/* Get the first message which was sent.  */
+	error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+	test_check_msg_data(&inmessage, error, strlen(message) + 1,
+			    MSG_EOR|MSG_CTRUNC, 0, 0);
+
+	tst_resm(TINFO, "Waiting for the associations to close automatically "
+		 "in 5 secs");
+
+	/* Get the shutdown complete notification from sk1. */
+	error = test_recvmsg(sk1, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage, error,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_SHUTDOWN_COMP);	
+				
+	/* Get the shutdown complete notification from sk2. */
+	error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage, error,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_SHUTDOWN_COMP);	
+
+	tst_resm(TPASS, "Autoclose of associations");
+
+	/* Shut down the link.  */
+	close(sk1);
+	close(sk2);
+
+	/* Indicate successful completion.  */
+	return 0;
+}
diff --git a/src/func_tests/test_basic.c b/src/func_tests/test_basic.c
new file mode 100644
index 0000000..92288b2
--- /dev/null
+++ b/src/func_tests/test_basic.c
@@ -0,0 +1,455 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2001, 2003
+ * Copyright (c) 1999-2000 Cisco, Inc.
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ * Copyright (c) 2001 Intel Corp.
+ * Copyright (c) 2001 Nokia, Inc.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ *    La Monte H.P. Yarroll <piggy@acm.org>
+ *    Karl Knutson <karl@athena.chicago.il.us>
+ *    Hui Huang <hui.huang@nokia.com>
+ *    Jon Grimm <jgrimm@us.ibm.com>
+ *    Sridhar Samudrala <samudrala@us.ibm.com>
+ */
+
+/* This is a basic functional test for the SCTP kernel
+ * implementation state machine.
+ */ 
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 15;
+int TST_CNT = 0;
+
+int main(void)
+{
+        int sk1, sk2;
+        sockaddr_storage_t loop1;
+        sockaddr_storage_t loop2;
+	sockaddr_storage_t msgname;
+        struct iovec iov;
+        struct msghdr inmessage;
+	struct msghdr outmessage;
+	char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+	char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+	struct cmsghdr *cmsg;
+	struct sctp_sndrcvinfo *sinfo;
+        struct iovec out_iov;
+        char *message = "hello, world!\n";
+        char *telephone = "Watson, come here!  I need you!\n";
+        char *telephone_resp = "I already brought your coffee...\n";
+        int error, bytes_sent;
+	int pf_class;
+	uint32_t ppid;
+	uint32_t stream;
+	sctp_assoc_t associd1, associd2;
+	struct sctp_assoc_change *sac;
+	char *big_buffer;
+	struct sockaddr *laddrs, *paddrs;
+	int n_laddrs, n_paddrs, i;
+	struct sockaddr *sa_addr;
+	struct sockaddr_in *in_addr;
+	struct sockaddr_in6 *in6_addr;
+	void *addr_buf;
+
+        /* Rather than fflush() throughout the code, set stdout to 
+	 * be unbuffered. 
+	 */
+	setvbuf(stdout, NULL, _IONBF, 0); 
+
+	/* Set some basic values which depend on the address family. */
+#if TEST_V6
+	pf_class = PF_INET6;
+
+        loop1.v6.sin6_family = AF_INET6;
+        loop1.v6.sin6_addr = (struct in6_addr)SCTP_IN6ADDR_ANY_INIT;
+        loop1.v6.sin6_port = htons(SCTP_TESTPORT_1);
+
+        loop2.v6.sin6_family = AF_INET6;
+        loop2.v6.sin6_addr = in6addr_loopback;
+        loop2.v6.sin6_port = htons(SCTP_TESTPORT_2);
+#else
+	pf_class = PF_INET;
+
+        loop1.v4.sin_family = AF_INET;
+        loop1.v4.sin_addr.s_addr = INADDR_ANY;
+        loop1.v4.sin_port = htons(SCTP_TESTPORT_1);
+
+        loop2.v4.sin_family = AF_INET;
+        loop2.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+        loop2.v4.sin_port = htons(SCTP_TESTPORT_2);
+#endif /* TEST_V6 */
+
+        /* Create the two endpoints which will talk to each other.  */
+        sk1 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+        sk2 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+
+	tst_resm(TPASS, "socket");
+
+        /* Bind these sockets to the test ports.  */
+        test_bind(sk1, &loop1.sa, sizeof(loop1));
+        test_bind(sk2, &loop2.sa, sizeof(loop2));
+
+	tst_resm(TPASS, "bind");
+
+	/* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+	test_enable_assoc_change(sk1);
+	test_enable_assoc_change(sk2);
+
+        /* Initialize inmessage for all receives. */
+	big_buffer = test_malloc(REALLY_BIG);
+	memset(&inmessage, 0, sizeof(inmessage));	
+        iov.iov_base = big_buffer;
+        iov.iov_len = REALLY_BIG;
+        inmessage.msg_iov = &iov;
+        inmessage.msg_iovlen = 1;
+        inmessage.msg_control = incmsg;
+	inmessage.msg_name = &msgname;
+
+        /* Try to read on socket 2.  This should fail since we are
+	 * neither listening, nor established. 
+	 */
+        inmessage.msg_controllen = sizeof(incmsg);
+        error = recvmsg(sk2, &inmessage, MSG_WAITALL);
+        if (error > 0)
+                tst_brkm(TBROK, tst_exit, "recvmsg on a socket neither"
+			 "listening nor established error: %d", error);
+
+	tst_resm(TPASS, "recvmsg on a socket neither listening nor "
+		 "established");
+
+       /* Mark sk2 as being able to accept new associations.  */
+	error = test_listen(sk2, 1);
+        
+	tst_resm(TPASS, "listen");
+
+        /* Send the first message.  This will create the association.  */
+        outmessage.msg_name = &loop2;
+        outmessage.msg_namelen = sizeof(loop2);
+        outmessage.msg_iov = &out_iov;
+        outmessage.msg_iovlen = 1;
+        outmessage.msg_control = outcmsg;
+        outmessage.msg_controllen = sizeof(outcmsg);
+        outmessage.msg_flags = 0;
+	cmsg = CMSG_FIRSTHDR(&outmessage);
+	cmsg->cmsg_level = IPPROTO_SCTP;
+	cmsg->cmsg_type = SCTP_SNDRCV;
+	cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+	outmessage.msg_controllen = cmsg->cmsg_len;
+	sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+	memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+	ppid = rand(); /* Choose an arbitrary value. */
+	stream = 1; 
+	sinfo->sinfo_ppid = ppid;
+	sinfo->sinfo_stream = stream;
+        outmessage.msg_iov->iov_base = message;
+        outmessage.msg_iov->iov_len = strlen(message) + 1;
+        test_sendmsg(sk1, &outmessage, 0, strlen(message)+1);
+        
+	tst_resm(TPASS, "sendmsg with a valid msg_name");
+
+        /* Get the communication up message on sk2.  */
+        inmessage.msg_controllen = sizeof(incmsg);
+	inmessage.msg_namelen = sizeof(msgname);
+        error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage, error,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);	
+#if TEST_V6
+
+	if (inmessage.msg_namelen != sizeof(struct sockaddr_in6)) {
+		DUMP_CORE;
+	}
+	if (msgname.v6.sin6_port != htons(SCTP_TESTPORT_1)) {
+		DUMP_CORE;
+	}
+
+	if (msgname.v6.sin6_family != AF_INET6) {
+		DUMP_CORE;
+	}
+
+	if (memcmp(&msgname.v6.sin6_addr, &in6addr_loopback, 
+		   sizeof(msgname.v6.sin6_addr))) {
+		DUMP_CORE;
+	}
+#else 
+	if (inmessage.msg_namelen != sizeof(struct sockaddr_in)) {
+		DUMP_CORE;
+	}
+	if (msgname.v4.sin_port != htons(SCTP_TESTPORT_1)) {
+		DUMP_CORE;
+	}
+
+	if (msgname.v4.sin_family != AF_INET) {
+		DUMP_CORE;
+	}
+	if (msgname.v4.sin_addr.s_addr != SCTP_IP_LOOPBACK) {
+		DUMP_CORE;
+	}
+#endif
+	sac = (struct sctp_assoc_change *)iov.iov_base;
+	associd2 = sac->sac_assoc_id;
+
+        /* Get the communication up message on sk1.  */
+	iov.iov_base = big_buffer;
+        iov.iov_len = REALLY_BIG;
+        inmessage.msg_control = incmsg;
+        inmessage.msg_controllen = sizeof(incmsg);
+        error = test_recvmsg(sk1, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage, error, 
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);	
+	sac = (struct sctp_assoc_change *)iov.iov_base;
+	associd1 = sac->sac_assoc_id;
+
+	tst_resm(TPASS, "recvmsg COMM_UP notifications");
+
+        /* Get the first message which was sent.  */
+        inmessage.msg_controllen = sizeof(incmsg);
+	inmessage.msg_namelen = sizeof(msgname);
+	memset(&msgname, 0, sizeof(msgname));
+        error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+        test_check_msg_data(&inmessage, error, strlen(message) + 1,
+			    MSG_EOR, stream, ppid);
+#if TEST_V6
+
+	if (inmessage.msg_namelen != sizeof(struct sockaddr_in6)) {
+		DUMP_CORE;
+	}
+	if (msgname.v6.sin6_port != htons(SCTP_TESTPORT_1)) {
+		DUMP_CORE;
+	}
+
+	if (msgname.v6.sin6_family != AF_INET6) {
+		DUMP_CORE;
+	}
+
+	if (memcmp(&msgname.v6.sin6_addr, &in6addr_loopback, 
+		   sizeof(msgname.v6.sin6_addr))) {
+		DUMP_CORE;
+	}
+#else 
+	if (inmessage.msg_namelen != sizeof(struct sockaddr_in)) {
+		DUMP_CORE;
+	}
+	if (msgname.v4.sin_port != htons(SCTP_TESTPORT_1)) {
+		DUMP_CORE;
+	}
+	if (msgname.v4.sin_family != AF_INET) {
+		DUMP_CORE;
+	}
+	if (msgname.v4.sin_addr.s_addr != SCTP_IP_LOOPBACK) {
+		DUMP_CORE;
+	}
+#endif
+
+	/* Try to send a message with NULL msg_name and associd, should fail */
+        outmessage.msg_controllen = sizeof(outcmsg);
+        outmessage.msg_flags = 0;
+	cmsg = CMSG_FIRSTHDR(&outmessage);
+	cmsg->cmsg_level = IPPROTO_SCTP;
+	cmsg->cmsg_type = SCTP_SNDRCV;
+	cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+	outmessage.msg_controllen = cmsg->cmsg_len;
+	sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+	memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+	ppid++;
+	stream++;
+	sinfo->sinfo_ppid = ppid;
+	sinfo->sinfo_stream = stream;
+	outmessage.msg_iov->iov_base = telephone;
+        outmessage.msg_iov->iov_len = strlen(telephone) + 1;
+	outmessage.msg_name = NULL;
+	outmessage.msg_namelen = 0;
+	bytes_sent = sendmsg(sk1, &outmessage, MSG_NOSIGNAL);
+	if ((bytes_sent > 0) || (EPIPE != errno))
+		tst_brkm(TBROK, tst_exit, "sendmsg with NULL associd and "
+			 "NULL msg_name error:%d errno:%d", error, errno);
+
+	tst_resm(TPASS, "sendmsg with NULL associd and NULL msg_name");
+
+	/* Fill in a incorrect assoc_id, which should cause an error. */
+	sinfo->sinfo_assoc_id = associd2;
+	bytes_sent = sendmsg(sk1, &outmessage, MSG_NOSIGNAL);
+	if ((bytes_sent > 0) || (EPIPE != errno))
+		tst_brkm(TBROK, tst_exit, "sendmsg with incorrect associd "
+			 "error:%d errno:%d", error, errno);
+
+	tst_resm(TPASS, "sendmsg with incorrect associd");
+
+	/* Fill in a correct assoc_id and get back to the normal testing. */
+	sinfo->sinfo_assoc_id = associd1;
+        /* Send two more messages, to cause a second SACK.  */
+	test_sendmsg(sk1, &outmessage, 0, strlen(telephone)+1);
+
+	outmessage.msg_name = &loop2;
+	outmessage.msg_namelen = sizeof(loop2);
+	outmessage.msg_iov->iov_base = telephone_resp;
+        outmessage.msg_iov->iov_len = strlen(telephone_resp) + 1;
+	test_sendmsg(sk1, &outmessage, 0, strlen(telephone_resp)+1);
+
+	tst_resm(TPASS, "sendmsg with valid associd");
+
+        /* Get those two messages.  */
+	inmessage.msg_controllen = sizeof(incmsg);
+        error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+        test_check_msg_data(&inmessage, error, strlen(telephone) + 1,
+			    MSG_EOR, stream, ppid);
+
+	inmessage.msg_controllen = sizeof(incmsg);
+        error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+        test_check_msg_data(&inmessage, error, strlen(telephone_resp) + 1,
+			    MSG_EOR, stream, ppid);
+       
+	tst_resm(TPASS, "recvmsg");
+
+	n_laddrs = sctp_getladdrs(sk1, associd1, &laddrs); 
+	if (n_laddrs <= 0)
+                tst_brkm(TBROK, tst_exit, "sctp_getladdrs: %s",
+			 strerror(errno));
+
+	tst_resm(TPASS, "sctp_getladdrs");
+
+	addr_buf = (void *)laddrs;
+	for (i = 0; i < n_laddrs; i++) {
+		sa_addr = (struct sockaddr *)addr_buf;
+		if (AF_INET == sa_addr->sa_family) {
+			in_addr = (struct sockaddr_in *)sa_addr;
+			tst_resm(TINFO, "LOCAL ADDR %d.%d.%d.%d PORT %d",
+				 NIPQUAD(in_addr->sin_addr),
+				 ntohs(in_addr->sin_port));
+			addr_buf += sizeof(struct sockaddr_in);
+		} else {
+			in6_addr = (struct sockaddr_in6 *)sa_addr;
+			tst_resm(TINFO,
+		 "LOCAL ADDR %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x PORT %d",
+			       NIP6(in6_addr->sin6_addr),
+			       ntohs(in6_addr->sin6_port));
+			addr_buf += sizeof(struct sockaddr_in6);
+		}
+	}
+
+	sctp_freeladdrs(laddrs);
+
+	tst_resm(TPASS, "sctp_freeladdrs");
+
+	n_paddrs = sctp_getpaddrs(sk1, associd1, &paddrs); 
+	if (n_paddrs <= 0)
+                tst_brkm(TBROK, tst_exit, "sctp_getpaddrs: %s",
+			 strerror(errno));
+
+	tst_resm(TPASS, "sctp_getpaddrs");
+
+	addr_buf = (void *)paddrs;
+	for (i = 0; i < n_paddrs; i++) {
+		sa_addr = (struct sockaddr *)addr_buf;
+		if (AF_INET == sa_addr->sa_family) {
+			in_addr = (struct sockaddr_in *)sa_addr;
+			tst_resm(TINFO, "PEER ADDR %d.%d.%d.%d PORT %d",
+				 NIPQUAD(in_addr->sin_addr),
+				 ntohs(in_addr->sin_port));
+			addr_buf += sizeof(struct sockaddr_in);
+		} else {
+			in6_addr = (struct sockaddr_in6 *)sa_addr;
+			tst_resm(TINFO,
+		 "PEER ADDR %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x PORT %d",
+			       NIP6(in6_addr->sin6_addr),
+			       ntohs(in6_addr->sin6_port));
+			addr_buf += sizeof(struct sockaddr_in6);
+		}
+	}
+
+	sctp_freepaddrs(paddrs);
+
+	tst_resm(TPASS, "sctp_freepaddrs");
+
+        /* Shut down the link.  */
+        close(sk1);
+
+        /* Get the shutdown complete notification. */
+	inmessage.msg_controllen = sizeof(incmsg);
+	inmessage.msg_namelen = sizeof(msgname);
+	memset(&msgname, 0, sizeof(msgname));
+        error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage, error,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_SHUTDOWN_COMP);	
+#if TEST_V6
+
+	if (inmessage.msg_namelen != sizeof(struct sockaddr_in6)) {
+		DUMP_CORE;
+	}
+	if (msgname.v6.sin6_port != htons(SCTP_TESTPORT_1)) {
+		DUMP_CORE;
+	}
+
+	if (msgname.v6.sin6_family != AF_INET6) {
+		DUMP_CORE;
+	}
+
+	if (memcmp(&msgname.v6.sin6_addr, &in6addr_loopback, 
+		   sizeof(msgname.v6.sin6_addr))) {
+		DUMP_CORE;
+	}
+#else 
+	if (inmessage.msg_namelen != sizeof(struct sockaddr_in)) {
+		DUMP_CORE;
+	}
+	if (msgname.v4.sin_port != htons(SCTP_TESTPORT_1)) {
+		DUMP_CORE;
+	}
+
+	if (msgname.v4.sin_family != AF_INET) {
+		DUMP_CORE;
+	}
+	if (msgname.v4.sin_addr.s_addr != SCTP_IP_LOOPBACK) {
+		DUMP_CORE;
+	}
+#endif
+				
+	tst_resm(TPASS, "recvmsg SHUTDOWN_COMP notification");
+
+        close(sk2);
+
+        /* Indicate successful completion.  */
+       	return 0; 
+}
diff --git a/src/func_tests/test_connect.c b/src/func_tests/test_connect.c
new file mode 100644
index 0000000..333c283
--- /dev/null
+++ b/src/func_tests/test_connect.c
@@ -0,0 +1,219 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2002, 2003
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ *    Sridhar Samudrala		<sri@us.ibm.com>
+ */
+
+/* This is a kernel test to verify the one-to-many style connect() in blocking
+ * and non-blocking modes.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 5;
+int TST_CNT = 0;
+
+int
+main(int argc, char *argv[])
+{
+	int svr_sk, clt_sk1, clt_sk2, peeloff_sk;
+	sctp_assoc_t svr_associd1;
+	sockaddr_storage_t svr_loop, clt_loop1, clt_loop2, clt_loop3;
+	struct sctp_assoc_change *sac;
+	struct iovec iov;
+	struct msghdr inmessage;
+	int error;
+	char *big_buffer;
+	int flags;
+
+        /* Rather than fflush() throughout the code, set stdout to 
+	 * be unbuffered.  
+	 */ 
+	setvbuf(stdout, NULL, _IONBF, 0); 
+
+	/* Initialize the server and client addresses. */ 
+	svr_loop.v4.sin_family = AF_INET;
+	svr_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+	svr_loop.v4.sin_port = htons(SCTP_TESTPORT_1);
+	clt_loop1.v4.sin_family = AF_INET;
+	clt_loop1.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+	clt_loop1.v4.sin_port = htons(SCTP_TESTPORT_2);
+	clt_loop2.v4.sin_family = AF_INET;
+	clt_loop2.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+	clt_loop2.v4.sin_port = htons(SCTP_TESTPORT_2+1);
+	clt_loop3.v4.sin_family = AF_INET;
+	clt_loop3.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+	clt_loop3.v4.sin_port = htons(SCTP_TESTPORT_2+2);
+
+	/* Create and bind the server socket.  */
+        svr_sk = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+	test_bind(svr_sk, &svr_loop.sa, sizeof(svr_loop));
+
+	/* Mark server socket as being able to accept new associations.  */
+	test_listen(svr_sk, 1);
+
+	/* Create and bind the client sockets.  */
+	clt_sk1 = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+	test_bind(clt_sk1, &clt_loop1.sa, sizeof(clt_loop1));
+	clt_sk2 = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+	test_bind(clt_sk2, &clt_loop2.sa, sizeof(clt_loop2));
+
+	/* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+	test_enable_assoc_change(svr_sk);
+	test_enable_assoc_change(clt_sk1);
+	test_enable_assoc_change(clt_sk2);
+
+	/* Set clt_sk1 as non-blocking. */
+	flags = fcntl(clt_sk1, F_GETFL, 0);
+	if (flags < 0)
+		tst_brkm(TBROK, tst_exit, "fcntl F_GETFL: %s", strerror(errno));
+	if (fcntl(clt_sk1, F_SETFL, flags | O_NONBLOCK) < 0)
+		tst_brkm(TBROK, tst_exit, "fcntl F_SETFL: %s", strerror(errno));
+
+	/* Do a non-blocking connect from clt_sk1 to svr_sk */      
+	error = connect(clt_sk1, &svr_loop.sa, sizeof(svr_loop));
+	/* Non-blocking connect should return immediately with EINPROGRESS. */
+	if ((error != -1) || (EINPROGRESS != errno))
+		tst_brkm(TBROK, tst_exit, "non-blocking connect error: %d"
+			 "errno:%d", error, errno);
+
+	tst_resm(TPASS, "non-blocking connect");
+
+	/* Doing a connect on a socket to create an association that is
+	 * is already established should return EISCONN.
+	 */
+	error = connect(clt_sk1, &svr_loop.sa, sizeof(svr_loop));
+	if ((error != -1) || (EISCONN != errno))
+		tst_brkm(TBROK, tst_exit, "connect on a socket to create an "
+			 "assoc that is already established error:%d errno:%d",
+			 error, errno);
+
+	tst_resm(TPASS, "connect on a socket to create an assoc that is "
+		 "already established");
+
+	/* Initialize inmessage for all receives. */
+        memset(&inmessage, 0, sizeof(inmessage));
+	big_buffer = test_malloc(REALLY_BIG);
+	iov.iov_base = big_buffer;
+	iov.iov_len = REALLY_BIG;
+	inmessage.msg_iov = &iov;
+	inmessage.msg_iovlen = 1;
+	inmessage.msg_control = NULL;
+
+	/* Get COMM_UP on clt_sk1 */
+	error = test_recvmsg(clt_sk1, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage, error,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+#if 0
+	sac = (struct sctp_assoc_change *)iov.iov_base;
+	clt_associd1 = sac->sac_assoc_id;
+#endif
+
+	/* Get COMM_UP on svr_sk */
+	error = test_recvmsg(svr_sk, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage, error,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+	sac = (struct sctp_assoc_change *)iov.iov_base;
+	svr_associd1 = sac->sac_assoc_id;
+
+	/* Do a blocking connect from clt_sk2 to svr_sk. 
+	 * Blocking connect should block until the association is established
+	 * and return success.
+	 */
+	test_connect(clt_sk2, &svr_loop.sa, sizeof(svr_loop));
+
+	/* Get COMM_UP on clt_sk2 */
+	error = test_recvmsg(clt_sk2, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage, error,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+#if 0
+	sac = (struct sctp_assoc_change *)iov.iov_base;
+	clt_associd2 = sac->sac_assoc_id;
+#endif
+
+	/* Get COMM_UP on svr_sk */
+	error = test_recvmsg(svr_sk, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage, error,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+#if 0
+	sac = (struct sctp_assoc_change *)iov.iov_base;
+	svr_associd2 = sac->sac_assoc_id;
+#endif
+
+	tst_resm(TPASS, "blocking connect");
+
+	peeloff_sk = test_sctp_peeloff(svr_sk, svr_associd1); 
+
+	/* Doing a connect on a peeled off socket should fail. */
+	error = connect(peeloff_sk, &clt_loop3.sa, sizeof(clt_loop3));
+	if ((error != -1) || (EISCONN != errno))
+		tst_brkm(TBROK, tst_exit, "connect on a peeled off socket "
+			 "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "connect on a peeled off socket");
+
+	/* Trying to create an association on a socket that matches an 
+	 * existing peeled-off association should fail.
+	 */
+	error = connect(svr_sk, &clt_loop1.sa, sizeof(clt_loop1));
+	if ((error != -1) || (EADDRNOTAVAIL != errno))
+		tst_brkm(TBROK, tst_exit, "connect to create an assoc that "
+			 "matches a peeled off assoc error:%d errno:%d",
+			 error, errno);
+
+	tst_resm(TPASS, "connect to create an assoc that matches a peeled off "
+		 "assoc");
+
+	close(svr_sk);
+	close(clt_sk1);
+	close(clt_sk2);
+	close(peeloff_sk);
+
+        /* Indicate successful completion.  */
+       	return 0; 
+}
diff --git a/src/func_tests/test_connectx.c b/src/func_tests/test_connectx.c
new file mode 100644
index 0000000..2477241
--- /dev/null
+++ b/src/func_tests/test_connectx.c
@@ -0,0 +1,270 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2002, 2003
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ *    Sridhar Samudrala		<sri@us.ibm.com>
+ */
+
+/* This is a kernel test to verify the one-to-many style sctp_connectx()
+ * in blocking and non-blocking modes.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 9;
+int TST_CNT = 0;
+
+#define NUMADDR 6
+#define SCTP_IP_LOOPBACK_I(I)  htonl(0x7f000001 + I)
+
+#define NIPQUAD(addr) \
+	((unsigned char *)&addr)[0], \
+	((unsigned char *)&addr)[1], \
+	((unsigned char *)&addr)[2], \
+	((unsigned char *)&addr)[3]
+
+int
+main(int argc, char *argv[])
+{
+	int svr_sk, clt_sk1, clt_sk2, peeloff_sk;
+	sctp_assoc_t associd, svr_associd1, svr_associd2, clt_associd1, clt_associd2;
+	struct iovec iov;
+	struct msghdr inmessage;
+	int error, i;
+	struct sctp_assoc_change *sac;
+	char *big_buffer;
+	int flags;
+	struct sockaddr_in svr_loop[NUMADDR];
+	struct sockaddr_in svr_try[NUMADDR];
+	struct sockaddr_in clt_loop1[NUMADDR];
+	struct sockaddr_in clt_loop2[NUMADDR];
+	struct sockaddr_in clt_loop3[NUMADDR];
+	sockaddr_storage_t svr_test[NUMADDR], clt_test1[NUMADDR], clt_test2[NUMADDR];
+
+	/* Rather than fflush() throughout the code, set stdout to 
+	 * be unbuffered.  
+	 */ 
+	setvbuf(stdout, NULL, _IONBF, 0); 
+
+	for (i = 0; i < NUMADDR; i++) {
+		/* Initialize the server and client addresses. */ 
+		svr_loop[i].sin_family = AF_INET;
+		svr_loop[i].sin_addr.s_addr = SCTP_IP_LOOPBACK_I(i);
+		svr_loop[i].sin_port = htons(SCTP_TESTPORT_1);
+		svr_test[i].v4.sin_family = AF_INET;
+		svr_test[i].v4.sin_addr.s_addr = SCTP_IP_LOOPBACK_I(i);
+		svr_test[i].v4.sin_port = htons(SCTP_TESTPORT_1);
+		svr_try[i].sin_family = AF_INET;
+		if (i < (NUMADDR-1)) {
+			svr_try[i].sin_addr.s_addr = SCTP_IP_LOOPBACK_I(i);
+		} else {
+			/* Make last address invalid. */
+			svr_try[i].sin_addr.s_addr = SCTP_IP_LOOPBACK_I(i + 0x400);
+		}
+		svr_try[i].sin_port = htons(SCTP_TESTPORT_1);
+		clt_loop1[i].sin_family = AF_INET;
+		clt_loop1[i].sin_addr.s_addr = SCTP_IP_LOOPBACK_I(i + 0x100);
+		clt_loop1[i].sin_port = htons(SCTP_TESTPORT_2);
+		clt_test1[i].v4.sin_family = AF_INET;
+		clt_test1[i].v4.sin_addr.s_addr = SCTP_IP_LOOPBACK_I(i + 0x100);
+		clt_test1[i].v4.sin_port = htons(SCTP_TESTPORT_2);
+		clt_loop2[i].sin_family = AF_INET;
+		clt_loop2[i].sin_addr.s_addr = SCTP_IP_LOOPBACK_I(i + 0x200);
+		clt_loop2[i].sin_port = htons(SCTP_TESTPORT_2+1);
+		clt_test2[i].v4.sin_family = AF_INET;
+		clt_test2[i].v4.sin_addr.s_addr = SCTP_IP_LOOPBACK_I(i + 0x200);
+		clt_test2[i].v4.sin_port = htons(SCTP_TESTPORT_2+1);
+		clt_loop3[i].sin_family = AF_INET;
+		clt_loop3[i].sin_addr.s_addr = SCTP_IP_LOOPBACK_I(i + 0x300);
+		clt_loop3[i].sin_port = htons(SCTP_TESTPORT_2+2);
+	}
+
+	/* Create and bind the server socket.  */
+	svr_sk = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+	test_bind(svr_sk, (struct sockaddr *)&svr_loop[0], sizeof(svr_loop[0]));
+	test_bindx_add(svr_sk, (struct sockaddr *)&svr_loop[1], NUMADDR-1);
+
+	/* Mark server socket as being able to accept new associations.  */
+	test_listen(svr_sk, 1);
+
+	/* Create and bind the client sockets.  */
+	clt_sk1 = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+	test_bind(clt_sk1, (struct sockaddr *)&clt_loop1[0], sizeof(clt_loop1));
+	test_bindx_add(clt_sk1, (struct sockaddr *)&clt_loop1[1], NUMADDR-1);
+	clt_sk2 = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+	test_bind(clt_sk2, (struct sockaddr *)&clt_loop2[0], sizeof(clt_loop2));
+	test_bindx_add(clt_sk2, (struct sockaddr *)&clt_loop2[1], NUMADDR-1);
+
+	/* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+	test_enable_assoc_change(svr_sk);
+	test_enable_assoc_change(clt_sk1);
+	test_enable_assoc_change(clt_sk2);
+
+	/* Set clt_sk1 as non-blocking. */
+	flags = fcntl(clt_sk1, F_GETFL, 0);
+	if (flags < 0)
+		tst_brkm(TBROK, tst_exit, "fcntl F_GETFL: %s", strerror(errno));
+	if (fcntl(clt_sk1, F_SETFL, flags | O_NONBLOCK) < 0)
+		tst_brkm(TBROK, tst_exit, "fcntl F_SETFL: %s", strerror(errno));
+
+	/* Do a non-blocking connectx from clt_sk1 to svr_sk */      
+	error = sctp_connectx(clt_sk1, (struct sockaddr *)svr_try, NUMADDR,
+			      &associd);
+	/* Non-blocking connectx should return immediately with EINPROGRESS. */
+	if ((error != -1) || (EINPROGRESS != errno))
+		tst_brkm(TBROK, tst_exit, "non-blocking connectx error: %d"
+			 "errno:%d", error, errno);
+
+	tst_resm(TPASS, "non-blocking connectx");
+
+	/* Doing a connectx on a socket to create an association that is
+	 * is already established should return EISCONN.
+	 */
+	error = sctp_connectx(clt_sk1, (struct sockaddr *)svr_try, NUMADDR,
+			      NULL);
+	if ((error != -1) || (EISCONN != errno))
+		tst_brkm(TBROK, tst_exit, "connectx on a socket to create an "
+			 "assoc that is already established error:%d errno:%d",
+			 error, errno);
+
+	tst_resm(TPASS, "connectx on a socket to create an assoc that is "
+		 "already established");
+
+	/* Initialize inmessage for all receives. */
+	memset(&inmessage, 0, sizeof(inmessage));
+	big_buffer = test_malloc(REALLY_BIG);
+	iov.iov_base = big_buffer;
+	iov.iov_len = REALLY_BIG;
+	inmessage.msg_iov = &iov;
+	inmessage.msg_iovlen = 1;
+	inmessage.msg_control = NULL;
+
+	/* Get COMM_UP on clt_sk1 */
+	error = test_recvmsg(clt_sk1, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage, error,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);	
+	sac = (struct sctp_assoc_change *)iov.iov_base;
+	clt_associd1 = sac->sac_assoc_id;
+
+	if (associd) {
+		if (associd != clt_associd1)
+			tst_brkm(TBROK, tst_exit, "Association id mismatch: "
+			 "connectx returned %d, notification returned:%d",
+			 associd, clt_associd1);
+		tst_resm(TPASS, "Association id match between sctp_connectx()"
+				" and notification.");
+	}
+
+	/* Get COMM_UP on svr_sk */
+	error = test_recvmsg(svr_sk, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage, error,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);	
+	sac = (struct sctp_assoc_change *)iov.iov_base;
+	svr_associd1 = sac->sac_assoc_id;
+
+	/* Do a blocking connectx from clt_sk2 to svr_sk. 
+	 * Blocking connectx should block until the association is established
+	 * and return success.
+	 */
+	test_connectx(clt_sk2, (struct sockaddr *)svr_try, NUMADDR);
+
+	/* Get COMM_UP on clt_sk2 */
+	error = test_recvmsg(clt_sk2, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage, error,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);	
+	sac = (struct sctp_assoc_change *)iov.iov_base;
+	clt_associd2 = sac->sac_assoc_id;
+
+	/* Get COMM_UP on svr_sk */
+	error = test_recvmsg(svr_sk, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage, error,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);	
+	sac = (struct sctp_assoc_change *)iov.iov_base;
+	svr_associd2 = sac->sac_assoc_id;
+
+	tst_resm(TPASS, "blocking connectx");
+
+	peeloff_sk = test_sctp_peeloff(svr_sk, svr_associd1); 
+
+	/* Doing a connectx on a peeled off socket should fail. */
+	error = sctp_connectx(peeloff_sk, (struct sockaddr *)clt_loop3, NUMADDR,
+			      NULL);
+	if ((error != -1) || (EISCONN != errno))
+		tst_brkm(TBROK, tst_exit, "connectx on a peeled off socket "
+			 "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "connectx on a peeled off socket");
+
+	/* Trying to create an association on a socket that matches an 
+	 * existing peeled-off association should fail.
+	 */
+	error = sctp_connectx(svr_sk, (struct sockaddr *)clt_loop1, NUMADDR,
+			      NULL);
+	if ((error != -1) || (EADDRNOTAVAIL != errno))
+		tst_brkm(TBROK, tst_exit, "connectx to create an assoc that "
+			 "matches a peeled off assoc error:%d errno:%d",
+			 error, errno);
+
+	tst_resm(TPASS, "connectx to create an assoc that matches a peeled off "
+		 "assoc");
+
+	test_peer_addr(peeloff_sk, svr_associd1, clt_test1, NUMADDR);
+	tst_resm(TPASS, "server association 1 peers ok");
+	test_peer_addr(svr_sk, svr_associd2, clt_test2, NUMADDR);
+	tst_resm(TPASS, "server association 2 peers ok");
+	test_peer_addr(clt_sk1, clt_associd1, svr_test, NUMADDR);
+	tst_resm(TPASS, "client association 1 peers ok");
+	test_peer_addr(clt_sk2, clt_associd2, svr_test, NUMADDR);
+	tst_resm(TPASS, "client association 2 peers ok");
+	close(svr_sk);
+	close(clt_sk1);
+	close(clt_sk2);
+	close(peeloff_sk);
+
+	/* Indicate successful completion.  */
+	return 0; 
+}
diff --git a/src/func_tests/test_fragments.c b/src/func_tests/test_fragments.c
new file mode 100644
index 0000000..7feb2b2
--- /dev/null
+++ b/src/func_tests/test_fragments.c
@@ -0,0 +1,297 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2001, 2003
+ * Copyright (c) 1999-2000 Cisco, Inc.
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ * Copyright (c) 2001 Intel Corp.
+ * Copyright (c) 2001 Nokia, Inc.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ *    La Monte H.P. Yarroll <piggy@acm.org>
+ *    Karl Knutson <karl@athena.chicago.il.us>
+ *    Hui Huang <hui.huang@nokia.com>
+ *    Jon Grimm <jgrimm@us.ibm.com>
+ *    Sridhar Samudrala <sri@us.ibm.com>
+ */
+
+/* This is a functional test to verify the data fragmentation, reassembly 
+ * support and SCTP_DISABLE_FRAGMENTS socket option. 
+ * The following tests are done in sequence.
+ * - Verify SCTP_DISABLE_FRAGMENTS socket option by doing a setsockopt()
+ *   followed by a getsockopt().
+ * - Verify that a message size exceeding the association fragmentation
+ *   point cannot be sent when fragmentation is disabled.
+ * - Send and receive a set of messages that are bigger than the path mtu. 
+ *   The different message sizes to be tested are specified in the array 
+ *   msg_sizes[]. 
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 4;
+int TST_CNT = 0;
+
+int msg_sizes[] = {1353, 2000, 5000, 10000, 20000, 32768};
+
+int
+main(int argc, char *argv[])
+{
+        int sk1, sk2;
+        sockaddr_storage_t loop1;
+        sockaddr_storage_t loop2;
+        struct iovec iov;
+        struct msghdr inmessage;
+	struct msghdr outmessage;
+	char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+	char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+	struct cmsghdr *cmsg;
+	struct sctp_sndrcvinfo *sinfo;
+        struct iovec out_iov;
+        int error, bytes_sent;
+	int pf_class;
+	uint32_t ppid;
+	uint32_t stream;
+	char *big_buffer;
+	int msg_len, msg_cnt, i;
+	void *msg_buf;
+	int disable_frag;
+	socklen_t optlen;
+
+        /* Rather than fflush() throughout the code, set stdout to 
+	 * be unbuffered. 
+	 */
+	setvbuf(stdout, NULL, _IONBF, 0); 
+
+	/* Set some basic values which depend on the address family. */
+#if TEST_V6
+	pf_class = PF_INET6;
+
+        loop1.v6.sin6_family = AF_INET6;
+        loop1.v6.sin6_addr = in6addr_loopback;
+        loop1.v6.sin6_port = htons(SCTP_TESTPORT_1);
+
+        loop2.v6.sin6_family = AF_INET6;
+        loop2.v6.sin6_addr = in6addr_loopback;
+        loop2.v6.sin6_port = htons(SCTP_TESTPORT_2);
+#else
+	pf_class = PF_INET;
+
+        loop1.v4.sin_family = AF_INET;
+        loop1.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+        loop1.v4.sin_port = htons(SCTP_TESTPORT_1);
+
+        loop2.v4.sin_family = AF_INET;
+        loop2.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+        loop2.v4.sin_port = htons(SCTP_TESTPORT_2);
+#endif /* TEST_V6 */
+
+        /* Create the two endpoints which will talk to each other.  */
+        sk1 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+        sk2 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+
+	/* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+	test_enable_assoc_change(sk1);
+	test_enable_assoc_change(sk2);
+
+        /* Bind these sockets to the test ports.  */
+        test_bind(sk1, &loop1.sa, sizeof(loop1));
+        test_bind(sk2, &loop2.sa, sizeof(loop2));
+
+       /* Mark sk2 as being able to accept new associations.  */
+	test_listen(sk2, 1);
+
+        /* Send the first message.  This will create the association.  */
+        outmessage.msg_name = &loop2;
+        outmessage.msg_namelen = sizeof(loop2);
+        outmessage.msg_iov = &out_iov;
+        outmessage.msg_iovlen = 1;
+        outmessage.msg_control = outcmsg;
+        outmessage.msg_controllen = sizeof(outcmsg);
+        outmessage.msg_flags = 0;
+	cmsg = CMSG_FIRSTHDR(&outmessage);
+	cmsg->cmsg_level = IPPROTO_SCTP;
+	cmsg->cmsg_type = SCTP_SNDRCV;
+	cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+	outmessage.msg_controllen = cmsg->cmsg_len;
+	sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+	memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+	ppid = rand(); /* Choose an arbitrary value. */
+	stream = 1; 
+	sinfo->sinfo_ppid = ppid;
+	sinfo->sinfo_stream = stream;
+	msg_len = 10;	
+	msg_buf = test_build_msg(10);
+        outmessage.msg_iov->iov_base = msg_buf;
+        outmessage.msg_iov->iov_len = msg_len;
+        test_sendmsg(sk1, &outmessage, 0, msg_len);
+        
+
+	/* Initialize inmessage for all receives. */
+	big_buffer = test_malloc(REALLY_BIG);
+        memset(&inmessage, 0, sizeof(inmessage));	
+        iov.iov_base = big_buffer;
+        iov.iov_len = REALLY_BIG;
+        inmessage.msg_iov = &iov;
+        inmessage.msg_iovlen = 1;
+        inmessage.msg_control = incmsg;
+
+        /* Get the communication up message on sk2.  */
+        inmessage.msg_controllen = sizeof(incmsg);
+        error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage, error,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+#if 0
+	sac = (struct sctp_assoc_change *)iov.iov_base;
+	associd2 = sac->sac_assoc_id;
+#endif
+        /* Get the communication up message on sk1.  */
+        inmessage.msg_controllen = sizeof(incmsg);
+        error = test_recvmsg(sk1, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage, error,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);	
+#if 0
+	sac = (struct sctp_assoc_change *)iov.iov_base;
+	associd1 = sac->sac_assoc_id;
+#endif
+        /* Get the first message which was sent.  */
+        inmessage.msg_controllen = sizeof(incmsg);
+        error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+        test_check_msg_data(&inmessage, error, msg_len, MSG_EOR, stream, ppid);
+
+	free(msg_buf);
+
+	/* Disable fragmentation. */
+	disable_frag = 1;
+	test_setsockopt(sk1, SCTP_DISABLE_FRAGMENTS, &disable_frag,
+			sizeof(disable_frag));
+
+	tst_resm(TPASS, "setsockopt(SCTP_DISABLE_FRAGMENTS)");
+
+	/* Do a getsockopt() and verify that fragmentation is disabled. */ 
+	disable_frag = 0;
+	optlen = sizeof(disable_frag);
+	error = test_getsockopt(sk1, SCTP_DISABLE_FRAGMENTS, &disable_frag,
+				&optlen);
+	if ((error != 0) && (disable_frag != 1))
+		tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DISABLE_FRAGMENTS) "
+			 "error:%d errno:%d disable_frag:%d",
+			 error, errno, disable_frag);
+
+	tst_resm(TPASS, "getsockopt(SCTP_DISABLE_FRAGMENTS)");
+
+	/* Try to send a messsage that exceeds association fragmentation point
+	 * and verify that it fails.
+	 */
+	msg_len = 100000;
+	msg_buf = test_build_msg(msg_len);
+	outmessage.msg_iov->iov_base = msg_buf;
+	outmessage.msg_iov->iov_len = msg_len;
+	error = sendmsg(sk1, &outmessage, 0);
+	if ((error != -1) || (errno != EMSGSIZE))
+       		tst_brkm(TBROK, tst_exit, "Send a message that exceeds "
+			 "assoc frag point error:%d errno:%d", error, errno);
+
+	tst_resm(TPASS, "Send a message that exceeds assoc frag point");
+
+	/* Enable Fragmentation. */
+	disable_frag = 0;
+	test_setsockopt(sk1, SCTP_DISABLE_FRAGMENTS, &disable_frag,
+			sizeof(disable_frag));
+
+	msg_cnt = sizeof(msg_sizes) / sizeof(int);
+
+	/* Send and receive the messages of different sizes specified in the
+	 * msg_sizes array in a loop.
+	 */
+	for (i = 0; i < msg_cnt; i++) {
+
+		msg_len = msg_sizes[i];
+		msg_buf = test_build_msg(msg_len);
+        	outmessage.msg_iov->iov_base = msg_buf;
+        	outmessage.msg_iov->iov_len = msg_len;
+        	bytes_sent = test_sendmsg(sk1, &outmessage, 0, msg_len);
+		
+		tst_resm(TINFO, "Sent %d byte message", bytes_sent);
+
+        	inmessage.msg_controllen = sizeof(incmsg);
+        	error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+		/* Handle Partial Reads. */ 
+		if (inmessage.msg_flags & MSG_EOR) {
+	        	test_check_msg_data(&inmessage, error, bytes_sent,
+					    MSG_EOR, stream, ppid);
+			tst_resm(TINFO, "Received %d byte message", error);
+		} else {
+			int remain;
+
+	        	test_check_msg_data(&inmessage, error, error, 0,
+					    stream, ppid);
+			tst_resm(TINFO, "Received %d byte message", error);
+
+			/* Read the remaining message. */
+			inmessage.msg_controllen = sizeof(incmsg);
+			remain = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+	        	test_check_msg_data(&inmessage, remain,
+					    bytes_sent - error,
+					    MSG_EOR, stream, ppid);
+			tst_resm(TINFO, "Received %d byte message", error);
+		}
+
+		free(msg_buf);
+	}
+
+	tst_resm(TPASS, "Send/Receive fragmented messages");
+
+        /* Shut down the link.  */
+        close(sk1);
+
+        /* Get the shutdown complete notification. */
+	inmessage.msg_controllen = sizeof(incmsg);
+        error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage, error,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_SHUTDOWN_COMP);
+				
+        close(sk2);
+
+        /* Indicate successful completion.  */
+       	return 0; 
+}
diff --git a/src/func_tests/test_getname.c b/src/func_tests/test_getname.c
new file mode 100644
index 0000000..5fc4b3c
--- /dev/null
+++ b/src/func_tests/test_getname.c
@@ -0,0 +1,278 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2004
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ *    Sridhar Samudrala		<sri@us.ibm.com>
+ */
+
+/* This is a kernel test to verify getsockname() and getpeername() interfaces
+ * for single-homed one-to-one style sockets.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 13;
+int TST_CNT = 0;
+
+#define MAX_CLIENTS 10
+
+int
+main(int argc, char *argv[])
+{
+	int clt_sk, svr_sk, accept_sk;
+	sockaddr_storage_t svr_loop, accept_loop;
+	sockaddr_storage_t svr_local_addr, svr_peer_addr;
+	sockaddr_storage_t clt_local_addr, clt_peer_addr;
+	socklen_t len;
+	int error;
+	int pf_class;
+	int fd, err_no = 0;
+	char filename[21];
+
+        /* Rather than fflush() throughout the code, set stdout to 
+	 * be unbuffered.  
+	 */ 
+	setvbuf(stdout, NULL, _IONBF, 0); 
+
+	/* Initialize the server and client addresses. */ 
+#if TEST_V6
+	pf_class = PF_INET6;
+        svr_loop.v6.sin6_family = AF_INET6;
+        svr_loop.v6.sin6_addr = (struct in6_addr)SCTP_IN6ADDR_ANY_INIT;
+        svr_loop.v6.sin6_port = htons(SCTP_TESTPORT_1);
+#else
+	pf_class = PF_INET;
+	svr_loop.v4.sin_family = AF_INET;
+	svr_loop.v4.sin_addr.s_addr = INADDR_ANY;
+	svr_loop.v4.sin_port = htons(SCTP_TESTPORT_1);
+#endif
+
+	/* Create and bind the listening server socket.  */
+        svr_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+	test_bind(svr_sk, &svr_loop.sa, sizeof(svr_loop));
+
+	memset(&svr_local_addr, 0x00, sizeof(svr_local_addr));
+	len = sizeof(svr_local_addr);
+	/* Verify that getsockname() on an unconnected socket works fine. */
+	error = getsockname(svr_sk, (struct sockaddr *)&svr_local_addr, &len);
+	if (0 != error)
+		tst_brkm(TBROK, tst_exit, "getsockname: %s", strerror(errno));
+
+	tst_resm(TPASS, "getsockname on an unconnected socket");
+
+	memset(&svr_peer_addr, 0x00, sizeof(svr_peer_addr));
+	len = sizeof(svr_peer_addr);
+	/* Verify that getpeername() on an unconnected socket fails. */
+	error = getpeername(svr_sk, (struct sockaddr *)&svr_peer_addr, &len);
+	if ((-1 != error) || (ENOTCONN != errno))
+		tst_brkm(TBROK, tst_exit, "getpeername on an unconnected "
+			 "socket error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "getpeername on an unconnected socket");
+
+	/* Mark svr_sk as being able to accept new associations.  */
+	test_listen(svr_sk, 5);
+
+	/* Create the client socket.  */
+	clt_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+	
+	/* Do a blocking connect from clt_sk to svr_sk */      
+#if TEST_V6
+	svr_loop.v6.sin6_addr = in6addr_loopback;
+#else
+	svr_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+#endif
+	test_connect(clt_sk, &svr_loop.sa, sizeof(svr_loop));
+
+	memset(&clt_local_addr, 0x00, sizeof(clt_local_addr));
+	len = sizeof(clt_local_addr);
+	/* Get the client's local address. */
+	error = getsockname(clt_sk, (struct sockaddr *)&clt_local_addr, &len);
+	if (0 != error)
+		tst_brkm(TBROK, tst_exit, "getsockname on a connected client "
+			 "socket: %s", strerror(errno));
+
+	tst_resm(TPASS, "getsockname on a connected client socket");
+
+	memset(&clt_peer_addr, 0x00, sizeof(clt_peer_addr));
+	len = sizeof(clt_peer_addr);
+	/* Get the client's peer address. */
+	error = getpeername(clt_sk, (struct sockaddr *)&clt_peer_addr, &len);
+	if (0 != error)
+		tst_brkm(TBROK, tst_exit, "getpeername on a connected client "
+			 "socket: %s", strerror(errno));
+
+	tst_resm(TPASS, "getpeername on a connected client socket");
+
+	/* Extract the association on the listening socket as a new socket. */
+	len = sizeof(accept_loop);
+	accept_sk = test_accept(svr_sk, &accept_loop.sa, &len); 
+
+	memset(&svr_local_addr, 0x00, sizeof(svr_local_addr));
+	len = sizeof(svr_local_addr);
+	/* Get the server's local address. */
+	error = getsockname(accept_sk, (struct sockaddr *)&svr_local_addr,
+				&len);
+	if (0 != error)
+		tst_brkm(TBROK, tst_exit, "getsockname on a connected server "
+			 "socket: %s", strerror(errno));
+
+	tst_resm(TPASS, "getsockname on a connected server socket");
+
+	memset(&svr_peer_addr, 0x00, sizeof(svr_peer_addr));
+	len = sizeof(svr_peer_addr);
+	/* Get the server's peer address. */
+	error = getpeername(accept_sk, (struct sockaddr *)&svr_peer_addr,
+				&len);
+	if (0 != error)
+		tst_brkm(TBROK, tst_exit, "getpeername on a connected server "
+			 "socket: %s", strerror(errno));
+
+	tst_resm(TPASS, "getpeername on a connected server socket");
+
+	if (svr_local_addr.v4.sin_port != clt_peer_addr.v4.sin_port)
+		tst_brkm(TBROK, tst_exit, "Server's local port(%d) doesn't "
+			 "match Client's peer port(%d)\n",
+			 svr_local_addr.v4.sin_port, clt_peer_addr.v4.sin_port);
+
+	if (svr_peer_addr.v4.sin_port != clt_local_addr.v4.sin_port)
+		tst_brkm(TBROK, tst_exit, "Server's peer port(%d) doesn't "
+			 "match Client's local port(%d)\n",
+			 svr_peer_addr.v4.sin_port, clt_local_addr.v4.sin_port);
+#if TEST_V6
+	if (memcmp(&svr_local_addr, &clt_peer_addr, len) != 0)
+		tst_brkm(TBROK, tst_exit, "Server's local address and client's "
+			 "peer addresses do not match\n");
+
+	if (memcmp(&svr_peer_addr, &clt_local_addr, len) != 0)
+		tst_brkm(TBROK, tst_exit, "Server's peer address and client's "
+			 "local addresses do not match\n");
+#else
+	if (svr_local_addr.v4.sin_addr.s_addr !=
+		 		clt_peer_addr.v4.sin_addr.s_addr)
+		tst_brkm(TBROK, tst_exit, "Server's local address and client's "
+			 "peer addresses do not match\n");
+	if (svr_peer_addr.v4.sin_addr.s_addr !=
+		 		clt_local_addr.v4.sin_addr.s_addr)
+		tst_brkm(TBROK, tst_exit, "Server's peer address and client's "
+			 "local addresses do not match\n");
+#endif
+	tst_resm(TPASS, "getsockname/getpeername server/client match");
+
+	memset(&clt_local_addr, 0x00, sizeof(clt_local_addr));
+	len = sizeof(clt_local_addr);
+	/*getsockname():  Bad socket descriptor, EBADF expected error*/
+	error = getsockname(-1, (struct sockaddr *)&clt_local_addr, &len);
+	if (error != -1 || errno != EBADF)
+		tst_brkm(TBROK, tst_exit, "getsockname on a bad socket "
+			 "descriptor. error:%d errno:%d", error, errno);
+
+	tst_resm(TPASS, "getsockname on a bad socket descriptor - EBADF");
+
+	/*getsockname(): Invalid socket, ENOTSOCK expected error*/
+	strcpy(filename, "/tmp/sctptest.XXXXXX");
+	fd = mkstemp(filename);
+	if (fd == -1)
+		tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
+				filename, strerror(errno));
+	error = getsockname(fd, (struct sockaddr *)&clt_local_addr, &len);
+	if (error == -1)
+		err_no = errno;
+	close(fd);
+	unlink(filename);
+	if (error != -1 || err_no != ENOTSOCK)
+		tst_brkm(TBROK, tst_exit, "getsockname on an invalid socket "
+			 "error:%d errno:%d", error, err_no);
+
+	tst_resm(TPASS, "getsockname on an invalid socket - ENOTSOCK");
+
+	/*getsockname(): Invalid structure, EFAULT expected error*/
+	error = getsockname(clt_sk, (struct sockaddr *)-1, &len);
+	if (error != -1 || errno != EFAULT)
+		tst_brkm(TBROK, tst_exit, "getsockname with invalid buffer "
+			 "error:%d errno:%d", error, errno);
+
+	tst_resm(TPASS, "getsockname with invalid buffer - EFAULT");
+ 
+	memset(&clt_peer_addr, 0x00, sizeof(clt_peer_addr));
+	len = sizeof(clt_peer_addr);
+	/*getpeername():  Bad socket descriptor, EBADF expected error*/
+	error = getpeername(-1, (struct sockaddr *)&clt_local_addr, &len);
+	if (error != -1 || errno != EBADF)
+		tst_brkm(TBROK, tst_exit, "getpeername on a bad socket "
+			 "descriptor. error:%d errno:%d", error, errno);
+
+	tst_resm(TPASS, "getpeername on a bad socket descriptor - EBADF");
+
+	/*getpeername(): Invalid socket, ENOTSOCK expected error*/
+	strcpy(filename, "/tmp/sctptest.XXXXXX");
+	fd = mkstemp(filename);
+	if (fd == -1)
+		tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
+				filename, strerror(errno));
+	error = getpeername(fd, (struct sockaddr *)&clt_local_addr, &len);
+	if (error == -1)
+		err_no = errno;
+	close(fd);
+	unlink(filename);
+	if (error != -1 || err_no != ENOTSOCK)
+		tst_brkm(TBROK, tst_exit, "getpeername on an invalid socket "
+			 "error:%d errno:%d", error, err_no);
+
+	tst_resm(TPASS, "getpeername on an invalid socket - ENOTSOCK");
+
+	/*getpeername(): Invalid structure, EFAULT expected error*/
+	error = getpeername(clt_sk, (struct sockaddr *)-1, &len);
+	if (error != -1 || errno != EFAULT)
+		tst_brkm(TBROK, tst_exit, "getpeername with invalid buffer "
+			 "error:%d errno:%d", error, errno);
+
+	tst_resm(TPASS, "getpeername with invalid buffer - EFAULT");
+ 
+	close(clt_sk);
+	close(svr_sk);
+	close(accept_sk);
+
+        /* Indicate successful completion.  */
+	return 0;
+}
diff --git a/src/func_tests/test_inaddr_any.c b/src/func_tests/test_inaddr_any.c
new file mode 100644
index 0000000..722a702
--- /dev/null
+++ b/src/func_tests/test_inaddr_any.c
@@ -0,0 +1,251 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2002, 2003
+ * Copyright (c) 1999-2000 Cisco, Inc.
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ * Copyright (c) 2001 Intel Corp.
+ * Copyright (c) 2001 Nokia, Inc.
+ * Copyright (c) 2001 La Monte H.P. Yarroll
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ *    La Monte H.P. Yarroll <piggy@acm.org>
+ *    Karl Knutson <karl@athena.chicago.il.us>
+ *    Jon Grimm <jgrimm@us.ibm.com>
+ *    Sridhar Samudrala <sri@us.ibm.com>
+ *    Daisy Chang <daisyc@us.ibm.com>
+ */
+
+/* This is a functional test to verify binding a socket with INADDRY_ANY
+ * address and send messages.
+ */ 
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 2;
+int TST_CNT = 0;
+
+int
+main(void)
+{
+        int sk1, sk2;
+        sockaddr_storage_t loop;
+        sockaddr_storage_t anyaddr;
+        struct msghdr outmessage;
+	char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+	char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+	struct cmsghdr *cmsg;
+	struct sctp_sndrcvinfo *sinfo;
+        struct iovec out_iov;
+        struct iovec iov;
+        struct msghdr inmessage;
+        char *message = "hello, world!\n";
+        char *telephone = "Watson, come here!  I need you!\n";
+        char *telephone_resp = "I already brought your coffee...\n";
+        int error;
+	int pf_class;
+	uint32_t ppid;
+	uint32_t stream;
+	socklen_t namelen;
+
+        /* Rather than fflush() throughout the code, set stdout to 
+	 * be unbuffered. 
+	 */
+	setvbuf(stdout, NULL, _IONBF, 0); 
+
+	/* Set some basic values which depend on the address family. */
+#if TEST_V6
+	pf_class = PF_INET6;
+
+        loop.v6.sin6_family = AF_INET6;
+        loop.v6.sin6_addr = (struct in6_addr)SCTP_IN6ADDR_LOOPBACK_INIT;
+        loop.v6.sin6_port = 0;
+
+        anyaddr.v6.sin6_family = AF_INET6;
+        anyaddr.v6.sin6_addr = (struct in6_addr)SCTP_IN6ADDR_ANY_INIT;
+        anyaddr.v6.sin6_port = 0;
+#else
+	pf_class = PF_INET;
+
+        loop.v4.sin_family = AF_INET;
+        loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+        loop.v4.sin_port = 0;
+
+        anyaddr.v4.sin_family = AF_INET;
+        anyaddr.v4.sin_addr.s_addr = INADDR_ANY;
+        anyaddr.v4.sin_port = 0;
+#endif /* TEST_V6 */
+
+        /* Create the two endpoints which will talk to each other.  */
+        sk1 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+        sk2 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+
+	/* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+	test_enable_assoc_change(sk1);
+	test_enable_assoc_change(sk2);
+
+        /* Bind these sockets to the test ports.  */
+        test_bind(sk1, &loop.sa, sizeof(loop));
+        test_bind(sk2, &anyaddr.sa, sizeof(anyaddr));
+
+	tst_resm(TPASS, "bind INADDR_ANY address");
+
+ 	/* Mark sk2 as being able to accept new associations */
+	test_listen(sk2, 1);
+
+	/* Now use getsockaname() to retrieve the ephmeral ports. */
+	namelen = sizeof(loop);
+	error = getsockname(sk1, &loop.sa, &namelen);
+	if (error != 0)
+		tst_brkm(TBROK, tst_exit, "getsockname: %s", strerror(errno));
+
+	namelen = sizeof(anyaddr);
+	error = getsockname(sk2, &anyaddr.sa, &namelen);
+	if (error != 0)
+		tst_brkm(TBROK, tst_exit, "getsockname: %s", strerror(errno));
+        
+#if TEST_V6
+	loop.v6.sin6_port = anyaddr.v6.sin6_port;
+#else
+        loop.v4.sin_port = anyaddr.v4.sin_port;
+#endif
+
+        /* Send the first message.  This will create the association.  */
+        outmessage.msg_name = &loop;
+        outmessage.msg_namelen = sizeof(loop);
+        outmessage.msg_iov = &out_iov;
+        outmessage.msg_iovlen = 1;
+        outmessage.msg_control = outcmsg;
+        outmessage.msg_controllen = sizeof(outcmsg);
+        outmessage.msg_flags = 0;
+	cmsg = CMSG_FIRSTHDR(&outmessage);
+	cmsg->cmsg_level = IPPROTO_SCTP;
+	cmsg->cmsg_type = SCTP_SNDRCV;
+	cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+	outmessage.msg_controllen = cmsg->cmsg_len;
+	sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+	memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+	ppid = rand(); /* Choose an arbitrary value. */
+	stream = 1; 
+	sinfo->sinfo_ppid = ppid;
+	sinfo->sinfo_stream = stream;
+        outmessage.msg_iov->iov_base = message;
+        outmessage.msg_iov->iov_len = strlen(message) + 1;
+        test_sendmsg(sk1, &outmessage, 0, strlen(message)+1);
+
+	/* Initialize inmessage for all receives. */
+        memset(&inmessage, 0, sizeof(inmessage));
+        iov.iov_base = test_malloc(REALLY_BIG);
+        iov.iov_len = REALLY_BIG;
+        inmessage.msg_iov = &iov;
+        inmessage.msg_iovlen = 1;
+        inmessage.msg_control = incmsg;
+
+        /* Get the communication up message on sk2.  */
+        inmessage.msg_controllen = sizeof(incmsg);
+        error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage, error,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);	
+
+        /* Get the communication up message on sk1.  */
+        inmessage.msg_controllen = sizeof(incmsg);
+        error = test_recvmsg(sk1, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage, error,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);	
+
+        /* Get the first message which was sent.  */
+        inmessage.msg_controllen = sizeof(incmsg);
+        error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+        test_check_msg_data(&inmessage, error, strlen(message) + 1, 
+			    MSG_EOR, stream, ppid);
+
+       /* Send 2 messages.  */
+        outmessage.msg_name = &loop;
+        outmessage.msg_namelen = sizeof(loop);
+        outmessage.msg_controllen = sizeof(outcmsg);
+        outmessage.msg_flags = 0;
+	cmsg = CMSG_FIRSTHDR(&outmessage);
+	cmsg->cmsg_level = IPPROTO_SCTP;
+	cmsg->cmsg_type = SCTP_SNDRCV;
+	cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+	outmessage.msg_controllen = cmsg->cmsg_len;
+	sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+	memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+	ppid++;
+	stream++;
+	sinfo->sinfo_ppid = ppid;
+	sinfo->sinfo_stream = stream;
+	outmessage.msg_iov->iov_base = telephone;
+        outmessage.msg_iov->iov_len = strlen(telephone) + 1;
+	test_sendmsg(sk1, &outmessage, 0, strlen(telephone)+1);
+
+	outmessage.msg_iov->iov_base = telephone_resp;
+        outmessage.msg_iov->iov_len = strlen(telephone_resp) + 1;
+	test_sendmsg(sk1, &outmessage, 0, strlen(telephone_resp)+1);
+        
+        /* Get those two messages.  */
+	inmessage.msg_controllen = sizeof(incmsg);
+        error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+        test_check_msg_data(&inmessage, error, strlen(telephone) + 1, 
+			    MSG_EOR, stream, ppid);
+
+	inmessage.msg_controllen = sizeof(incmsg);
+        error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+        test_check_msg_data(&inmessage, error, strlen(telephone_resp) + 1, 
+			    MSG_EOR, stream, ppid);
+        
+        /* Shut down the link.  */
+        close(sk1);
+
+        /* Get the shutdown complete notification. */
+	inmessage.msg_controllen = sizeof(incmsg);
+        error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage, error,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_SHUTDOWN_COMP);
+
+        close(sk2);
+
+	tst_resm(TPASS, "send msgs from a socket with INADDR_ANY bind address");
+
+        /* Indicate successful completion.  */
+        return 0;
+}
diff --git a/src/func_tests/test_peeloff.c b/src/func_tests/test_peeloff.c
new file mode 100644
index 0000000..8fb7a00
--- /dev/null
+++ b/src/func_tests/test_peeloff.c
@@ -0,0 +1,299 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2001, 2003
+ * Copyright (c) 1999-2000 Cisco, Inc.
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ * Copyright (c) 2001 Intel Corp.
+ * Copyright (c) 2001 Nokia, Inc.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ *    Sridhar Samudrala <sri@us.ibm.com>
+ */
+
+/* This is a Functional test to verify the new SCTP interface sctp_peeloff() 
+ * that can be used to branch off an association into a separate socket. 
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 6;
+int TST_CNT = 0;
+
+#define MAX_CLIENTS 10
+
+int
+main(int argc, char *argv[])
+{
+	int svr_sk, clt_sk[MAX_CLIENTS], peeloff_sk[MAX_CLIENTS];
+	sctp_assoc_t svr_associd[MAX_CLIENTS];
+	sockaddr_storage_t svr_loop, clt_loop[MAX_CLIENTS];
+	struct iovec iov;
+	struct msghdr inmessage;
+	struct msghdr outmessage;
+	char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+	char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+	struct cmsghdr *cmsg;
+	struct sctp_sndrcvinfo *sinfo;
+	struct iovec out_iov;
+	int error;
+	uint32_t ppid;
+	uint32_t stream;
+	struct sctp_assoc_change *sac;
+	char *big_buffer;
+	int i;
+        char *message = "hello, world!\n";
+	int pf_class;
+
+        /* Rather than fflush() throughout the code, set stdout to 
+	 * be unbuffered.  
+	 */ 
+	setvbuf(stdout, NULL, _IONBF, 0); 
+
+#if TEST_V6
+	pf_class = PF_INET6;
+        svr_loop.v6.sin6_family = AF_INET6;
+        svr_loop.v6.sin6_addr = in6addr_loopback;
+        svr_loop.v6.sin6_port = htons(SCTP_TESTPORT_1);
+#else
+	pf_class = PF_INET;
+	svr_loop.v4.sin_family = AF_INET;
+	svr_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+	svr_loop.v4.sin_port = htons(SCTP_TESTPORT_1);
+#endif
+
+	/* Create and bind the server socket.  */
+        svr_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+	test_bind(svr_sk, &svr_loop.sa, sizeof(svr_loop));
+
+	/* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+	test_enable_assoc_change(svr_sk);
+
+	/* Mark server socket as being able to accept new associations.  */
+	test_listen(svr_sk, 1);
+
+	/* Create and bind all the client sockets.  */
+	for (i = 0; i < MAX_CLIENTS; i++) {
+		clt_sk[i] = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+#if TEST_V6
+        	clt_loop[i].v6.sin6_family = AF_INET6;
+        	clt_loop[i].v6.sin6_addr = in6addr_loopback;
+        	clt_loop[i].v6.sin6_port = htons(SCTP_TESTPORT_2 + i);
+#else
+		clt_loop[i].v4.sin_family = AF_INET;
+		clt_loop[i].v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+		clt_loop[i].v4.sin_port = htons(SCTP_TESTPORT_2 + i);
+#endif
+		test_bind(clt_sk[i], &clt_loop[i].sa, sizeof(clt_loop[i]));
+
+		test_enable_assoc_change(clt_sk[i]);
+	}
+
+        /* Send the first message from all the clients to the server.  This 
+	 * will create the associations.  
+	 */
+	outmessage.msg_name = &svr_loop;
+	outmessage.msg_namelen = sizeof(svr_loop);
+	outmessage.msg_iov = &out_iov;
+	outmessage.msg_iovlen = 1;
+	outmessage.msg_control = outcmsg;
+	outmessage.msg_controllen = sizeof(outcmsg);
+	outmessage.msg_flags = 0;
+	cmsg = CMSG_FIRSTHDR(&outmessage);
+	cmsg->cmsg_level = IPPROTO_SCTP;
+	cmsg->cmsg_type = SCTP_SNDRCV;
+	cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+	outmessage.msg_controllen = cmsg->cmsg_len;
+	sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+	memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+	ppid = rand(); /* Choose an arbitrary value. */
+	stream = 1; 
+	sinfo->sinfo_ppid = ppid;
+	sinfo->sinfo_stream = stream;
+	outmessage.msg_iov->iov_base = message;
+	outmessage.msg_iov->iov_len = strlen(message) + 1;
+	for (i = 0; i < MAX_CLIENTS; i++)
+		test_sendmsg(clt_sk[i], &outmessage, 0,
+					  strlen(message)+1);
+       
+	/* Initialize inmessage for all receives. */ 
+	big_buffer = test_malloc(REALLY_BIG);
+	memset(&inmessage, 0, sizeof(inmessage));	
+	iov.iov_base = big_buffer;
+	iov.iov_len = REALLY_BIG;
+	inmessage.msg_iov = &iov;
+	inmessage.msg_iovlen = 1;
+	inmessage.msg_control = incmsg;
+
+	/* Get the communication up message on all client sockets.  */
+	for (i = 0; i < MAX_CLIENTS; i++) {
+		inmessage.msg_controllen = sizeof(incmsg);
+		error = test_recvmsg(clt_sk[i], &inmessage, MSG_WAITALL);
+		test_check_msg_notification(&inmessage, error,
+					    sizeof(struct sctp_assoc_change),
+					    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+#if 0
+		sac = (struct sctp_assoc_change *)iov.iov_base;
+		clt_associd[i] = sac->sac_assoc_id;
+#endif
+	}
+
+	/* Get the communication up message and the data message on the
+	 * server sockets for all the clients.  
+	 */
+	for (i = 0; i < MAX_CLIENTS; i++) {
+		inmessage.msg_controllen = sizeof(incmsg);
+		error = test_recvmsg(svr_sk, &inmessage, MSG_WAITALL);
+		test_check_msg_notification(&inmessage, error,
+					    sizeof(struct sctp_assoc_change),
+					    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);	
+		sac = (struct sctp_assoc_change *)iov.iov_base;
+		svr_associd[i] = sac->sac_assoc_id;
+
+		inmessage.msg_controllen = sizeof(incmsg);
+		error = test_recvmsg(svr_sk, &inmessage, MSG_WAITALL);
+		test_check_msg_data(&inmessage, error, strlen(message) + 1,
+				    MSG_EOR, stream, ppid);
+	}
+
+	/* Branch off all the associations on the server socket to separate
+	 * individual sockets.
+	 */ 
+	for (i = 0; i < MAX_CLIENTS; i++)
+		peeloff_sk[i] = test_sctp_peeloff(svr_sk, svr_associd[i]); 
+
+	tst_resm(TPASS, "sctp_peeloff");
+
+	errno = 0;
+	/* Verify that a peeled off socket is not allowed to do a listen().  */
+	error = listen(peeloff_sk[0], 1);
+	if (error != -1)
+		tst_brkm(TBROK, tst_exit, "listen on a peeled off socket "
+			 "error: %d, errno: %d", error, errno); 
+
+	tst_resm(TPASS, "listen on a peeled off socket");
+
+	errno = 0;
+	/* Verify that an association cannot be branched off an already
+	 * peeled-off socket.
+	 */
+	if ((-1 != sctp_peeloff(peeloff_sk[0], svr_associd[0])) ||
+	    (EINVAL != errno))
+		tst_brkm(TBROK, tst_exit, "sctp_peeloff on a peeled off "
+			 "socket error:%d, errno:%d",
+			 error, errno);
+
+	tst_resm(TPASS, "sctp_peeloff on a peeled off socket");
+
+	/* Send a message from all the client sockets to the server socket. */
+	for (i = 0; i < MAX_CLIENTS; i++)
+		test_sendmsg(clt_sk[i], &outmessage, 0, strlen(message)+1);
+
+	/* Receive the sent messages on the peeled off server sockets.  */    
+	for (i = 0; i < MAX_CLIENTS; i++) {
+		inmessage.msg_controllen = sizeof(incmsg);
+		error = test_recvmsg(peeloff_sk[i], &inmessage, MSG_WAITALL);
+		test_check_msg_data(&inmessage, error, strlen(message) + 1,
+				    MSG_EOR, stream, ppid);
+	}
+
+	tst_resm(TPASS, "Receive msgs on peeled off sockets");
+
+	/* Send a message from all the peeled off server sockets to the client 
+	 * sockets. 
+	 */
+	for (i = 0; i < MAX_CLIENTS; i++) {
+		outmessage.msg_name = &clt_loop[i];
+		outmessage.msg_namelen = sizeof(clt_loop[i]);
+		test_sendmsg(peeloff_sk[i], &outmessage, 0, strlen(message)+1);
+	}
+
+	/* Receive the messages sent from the peeled of server sockets on 
+	 * the client sockets.
+	 */
+	for (i = 0; i < MAX_CLIENTS; i++) {
+		inmessage.msg_controllen = sizeof(incmsg);
+		error = test_recvmsg(clt_sk[i], &inmessage, MSG_WAITALL);
+		test_check_msg_data(&inmessage, error, strlen(message) + 1,
+				    MSG_EOR, stream, ppid);
+	}
+
+	tst_resm(TPASS, "Send msgs on peeled off sockets");
+
+	errno = 0;
+	/* Verify that a peeled-off socket cannot initialize a new 
+	 * association by trying to send a message to a client that is not
+	 * associated with the peeled-off socket.
+	 * The message is sent to the client that is associated with the
+	 * socket.
+	 */ 
+	outmessage.msg_name = &clt_loop[1];
+	outmessage.msg_namelen = sizeof(clt_loop[1]);
+	test_sendmsg(peeloff_sk[0], &outmessage, 0, strlen(message)+1);
+
+	inmessage.msg_controllen = sizeof(incmsg);
+	error = test_recvmsg(clt_sk[0], &inmessage, MSG_WAITALL);
+	test_check_msg_data(&inmessage, error, strlen(message) + 1,
+			    MSG_EOR, stream, ppid);
+
+	tst_resm(TPASS, "peeled off socket cannot initialize a new assoc");
+
+	close(svr_sk);
+
+	/* Close all the peeled off server sockets.  */
+	for (i = 0; i < MAX_CLIENTS; i++)
+		close(peeloff_sk[i]);
+
+	/* Get the shutdown complete notification from all the client 
+	 * sockets.  
+	 */
+	for (i = 0; i < MAX_CLIENTS; i++) {
+		inmessage.msg_controllen = sizeof(incmsg);
+		error = test_recvmsg(clt_sk[i], &inmessage, MSG_WAITALL);
+		test_check_msg_notification(&inmessage, error,
+					    sizeof(struct sctp_assoc_change),
+					    SCTP_ASSOC_CHANGE,
+					    SCTP_SHUTDOWN_COMP);	
+
+		close(clt_sk[i]);
+	}
+
+        /* Indicate successful completion.  */
+       	return 0; 
+}
diff --git a/src/func_tests/test_recvmsg.c b/src/func_tests/test_recvmsg.c
new file mode 100644
index 0000000..b16cceb
--- /dev/null
+++ b/src/func_tests/test_recvmsg.c
@@ -0,0 +1,160 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2002, 2003
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ *
+ * This file is part of the SCTP kernel Implementation
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Written or modified by:
+ *    Sridhar Samudrala		<sri@us.ibm.com>
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ */
+
+/* This is a kernel test to verify
+ * 1. MSG_EOR flag is set correctly when a single message is read using multiple
+ *    recvmsg() calls. 
+ * 2. MSG_PEEK support. 
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 2;
+int TST_CNT = 0;
+
+int
+main(int argc, char *argv[])
+{
+	int svr_sk, clt_sk;
+	struct sockaddr_in svr_loop, clt_loop;
+	struct iovec iov, out_iov;
+	struct msghdr inmessage, outmessage;
+	char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+	int error, msglen, i;
+	char *big_buffer;
+	void *msg_buf;
+
+        /* Rather than fflush() throughout the code, set stdout to 
+	 * be unbuffered.  
+	 */ 
+	setvbuf(stdout, NULL, _IONBF, 0); 
+
+	/* Initialize the server and client addresses. */ 
+	svr_loop.sin_family = AF_INET;
+	svr_loop.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+	svr_loop.sin_port = htons(SCTP_TESTPORT_1);
+	clt_loop.sin_family = AF_INET;
+	clt_loop.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+	clt_loop.sin_port = htons(SCTP_TESTPORT_2);
+
+	/* Create and bind the server socket.  */
+        svr_sk = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+	test_bind(svr_sk, (struct sockaddr *)&svr_loop, sizeof(svr_loop));
+
+	/* Mark server socket as being able to accept new associations.  */
+	test_listen(svr_sk, 1);
+
+	/* Create and bind the client sockets.  */
+	clt_sk = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+	test_bind(clt_sk, (struct sockaddr *)&clt_loop, sizeof(clt_loop));
+
+	/* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+	test_enable_assoc_change(svr_sk);
+	test_enable_assoc_change(clt_sk);
+
+	/* Send a message. This will create the association.  */
+	memset(&outmessage, 0, sizeof(outmessage));	
+	outmessage.msg_name = &svr_loop;
+	outmessage.msg_namelen = sizeof(svr_loop);
+	outmessage.msg_iov = &out_iov;
+	outmessage.msg_iovlen = 1;
+	msg_buf = test_build_msg(30000);
+	outmessage.msg_iov->iov_base = msg_buf;
+	outmessage.msg_iov->iov_len = 30000;
+	test_sendmsg(clt_sk, &outmessage, 0, 30000);
+
+	/* Initialize inmessage for all receives. */
+	big_buffer = test_malloc(REALLY_BIG);
+        memset(&inmessage, 0, sizeof(inmessage));
+	iov.iov_base = big_buffer;
+	iov.iov_len = 2000;
+	inmessage.msg_iov = &iov;
+	inmessage.msg_iovlen = 1;
+	inmessage.msg_control = incmsg;
+
+	/* Receive COMM_UP on clt_sk. */
+	inmessage.msg_controllen = sizeof(incmsg);
+	error = test_recvmsg(clt_sk, &inmessage, 0);
+	test_check_msg_notification(&inmessage, error,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);	
+
+	/* Receive COMM_UP on svr_sk. */
+	inmessage.msg_controllen = sizeof(incmsg);
+	error = test_recvmsg(svr_sk, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage, error,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);	
+
+	/* Read the 30000 byte message using multiple recvmsg() calls in a
+	 * loop with 2000 bytes per read. 
+	 */
+	for (i = 0, msglen = 30000; i < 15; i++, msglen-=2000) {
+		iov.iov_len = REALLY_BIG;
+		inmessage.msg_controllen = sizeof(incmsg);
+		error = test_recvmsg(svr_sk, &inmessage, MSG_PEEK);
+		test_check_msg_data(&inmessage, error, msglen,
+				    MSG_EOR, 0, 0);
+
+		iov.iov_len = 2000;
+		inmessage.msg_controllen = sizeof(incmsg);
+		error = test_recvmsg(svr_sk, &inmessage, MSG_WAITALL);
+		test_check_msg_data(&inmessage, error, 2000,
+				    ((i==14)?MSG_EOR:0), 0, 0);
+	}
+
+	tst_resm(TPASS, "recvmsg with MSG_PEEK flag");
+	tst_resm(TPASS, "MSG_EOR in msg_flags set correctly");
+
+	close(svr_sk);
+	close(clt_sk);
+
+        /* Indicate successful completion.  */
+        return 0;
+}
diff --git a/src/func_tests/test_sctp_sendrecvmsg.c b/src/func_tests/test_sctp_sendrecvmsg.c
new file mode 100644
index 0000000..ceccd5a
--- /dev/null
+++ b/src/func_tests/test_sctp_sendrecvmsg.c
@@ -0,0 +1,370 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2003
+ * Copyright (c) 2003 Intel Corp.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ * To compile the v6 version, set the symbol TEST_V6 to 1.
+ *
+ * Written or modified by:
+ *    Ardelle Fan		<ardelle.fan@intel.com>
+ *    Sridhar Samudrala	 	<sri@us.ibm.com>
+ */
+
+/* This is a basic functional test for the SCTP new library APIs
+ * sctp_sendmsg() and sctp_recvmsg(). test_timetolive.c is rewritten using
+ * these new APIs. 
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 10;
+int TST_CNT = 0;
+
+/* RCVBUF value, and indirectly RWND*2 */
+#define SMALL_RCVBUF 3000
+#define SMALL_MAXSEG 500
+/* This is extra data length to ensure rwnd closes */
+#define RWND_SLOP    100
+static char *fillmsg = NULL;
+static char *ttlmsg = "This should time out!\n";
+static char *nottlmsg = "This should NOT time out!\n";
+static char ttlfrag[SMALL_MAXSEG*3] = {0};
+static char *message = "Hello world\n";
+
+int main(int argc, char *argv[])
+{
+	int sk1, sk2;
+	sockaddr_storage_t loop1;
+	sockaddr_storage_t loop2;
+	sockaddr_storage_t msgname;
+	int error;
+	int pf_class;
+	uint32_t ppid;
+	uint32_t stream;
+	struct sctp_event_subscribe subscribe;
+	char *big_buffer;
+	int offset, msg_flags;
+	socklen_t msgname_len;
+	size_t buflen;
+	struct sctp_send_failed *ssf;
+	struct sctp_sndrcvinfo sinfo;
+	struct sctp_sndrcvinfo snd_sinfo;
+	sctp_assoc_t associd1;
+	socklen_t len, oldlen;
+	struct sctp_status gstatus;
+
+	/* Rather than fflush() throughout the code, set stdout to
+	 * be unbuffered.
+	 */
+	setvbuf(stdout, NULL, _IONBF, 0);
+
+	/* Set some basic values which depend on the address family. */
+#if TEST_V6
+	pf_class = PF_INET6;
+
+	loop1.v6.sin6_family = AF_INET6;
+	loop1.v6.sin6_addr = in6addr_loopback;
+	loop1.v6.sin6_port = htons(SCTP_TESTPORT_1);
+
+	loop2.v6.sin6_family = AF_INET6;
+	loop2.v6.sin6_addr = in6addr_loopback;
+	loop2.v6.sin6_port = htons(SCTP_TESTPORT_2);
+#else
+	pf_class = PF_INET;
+
+	loop1.v4.sin_family = AF_INET;
+	loop1.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+	loop1.v4.sin_port = htons(SCTP_TESTPORT_1);
+
+	loop2.v4.sin_family = AF_INET;
+	loop2.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+	loop2.v4.sin_port = htons(SCTP_TESTPORT_2);
+#endif /* TEST_V6 */
+
+	/* Create the two endpoints which will talk to each other.  */
+	sk1 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+        sk2 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+
+	/* Set the MAXSEG to something smallish. */
+	{
+		int val = SMALL_MAXSEG;
+		test_setsockopt(sk1, SCTP_MAXSEG, &val, sizeof(val));
+	}
+
+	memset(&subscribe, 0, sizeof(subscribe));
+	subscribe.sctp_data_io_event = 1;
+	subscribe.sctp_association_event = 1;
+	subscribe.sctp_send_failure_event = 1;
+	test_setsockopt(sk1, SCTP_EVENTS, &subscribe, sizeof(subscribe));
+	test_setsockopt(sk2, SCTP_EVENTS, &subscribe, sizeof(subscribe));
+
+        /* Bind these sockets to the test ports.  */
+        test_bind(sk1, &loop1.sa, sizeof(loop1));
+        test_bind(sk2, &loop2.sa, sizeof(loop2));
+
+	/*
+	 * Set the RWND small so we can fill it up easily.
+	 */
+	len = sizeof(int);
+	error = getsockopt(sk2, SOL_SOCKET, SO_RCVBUF, &oldlen, &len);
+       
+	if (error)
+		tst_brkm(TBROK, tst_exit, "can't get rcvbuf size: %s",
+			 strerror(errno));
+
+	len = SMALL_RCVBUF; /* Really becomes 2xlen when set. */
+
+	error = setsockopt(sk2, SOL_SOCKET, SO_RCVBUF, &len, sizeof(len));
+	if (error)
+		tst_brkm(TBROK, tst_exit, "setsockopt(SO_RCVBUF): %s",
+			 strerror(errno));
+
+       /* Mark sk2 as being able to accept new associations.  */
+	test_listen(sk2, 1);
+
+	/* Send the first message.  This will create the association.  */
+	ppid = rand();
+	stream = 1;
+	test_sctp_sendmsg(sk1, message, strlen(message) + 1,
+			  (struct sockaddr *)&loop2, sizeof(loop2),
+			  ppid, 0, stream, 0, 0);
+
+	tst_resm(TPASS, "sctp_sendmsg");
+
+	/* Get the communication up message on sk2.  */
+	buflen = REALLY_BIG;
+	big_buffer = test_malloc(buflen);
+	msgname_len = sizeof(msgname);
+	msg_flags = 0;
+	error = test_sctp_recvmsg(sk2, big_buffer, buflen,
+				  (struct sockaddr *)&msgname, &msgname_len,
+				  &sinfo, &msg_flags);
+#if 0
+	associd2 = ((struct sctp_assoc_change *)big_buffer)->sac_assoc_id;
+#endif
+	test_check_buf_notification(big_buffer, error, msg_flags,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+
+
+	/* Get the communication up message on sk1.  */
+	buflen = REALLY_BIG;
+	msgname_len = sizeof(msgname);
+	msg_flags = 0;
+	error = test_sctp_recvmsg(sk1, big_buffer, buflen,
+				  (struct sockaddr *)&msgname, &msgname_len,
+				  &sinfo, &msg_flags); 
+	associd1 = ((struct sctp_assoc_change *)big_buffer)->sac_assoc_id;
+	test_check_buf_notification(big_buffer, error, msg_flags,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+
+	tst_resm(TPASS, "sctp_recvmsg SCTP_COMM_UP notification");
+
+	/* Get the first message which was sent.  */
+	buflen = REALLY_BIG;
+	msgname_len = sizeof(msgname);
+	msg_flags = 0;
+	error = test_sctp_recvmsg(sk2, big_buffer, buflen,
+				  (struct sockaddr *)&msgname, &msgname_len,
+				  &sinfo, &msg_flags); 
+	test_check_buf_data(big_buffer, error, msg_flags, &sinfo,
+			    strlen(message) + 1, MSG_EOR, stream, ppid); 
+
+	tst_resm(TPASS, "sctp_recvmsg data");
+
+	/* Figure out how big to make our fillmsg */
+	len = sizeof(struct sctp_status);
+	memset(&gstatus,0,sizeof(struct sctp_status));
+	gstatus.sstat_assoc_id = associd1;
+	error = getsockopt(sk1, IPPROTO_SCTP, SCTP_STATUS, &gstatus, &len);
+
+	if (error)
+		tst_brkm(TBROK, tst_exit, "can't get rwnd size: %s",
+			strerror(errno));
+	tst_resm(TINFO, "creating a fillmsg of size %d",
+		gstatus.sstat_rwnd+RWND_SLOP);
+        fillmsg = malloc(gstatus.sstat_rwnd+RWND_SLOP);
+
+	/* Send a fillmsg */
+	memset(fillmsg, 'X', gstatus.sstat_rwnd+RWND_SLOP);
+	fillmsg[gstatus.sstat_rwnd+RWND_SLOP-1] = '\0';
+	ppid++;
+	stream++;
+	test_sctp_sendmsg(sk1, fillmsg, gstatus.sstat_rwnd+RWND_SLOP, 
+			  (struct sockaddr *)&loop2, sizeof(loop2),
+			  ppid, 0, stream, 0, 0);
+
+	/* Now send a message that will timeout. */
+	test_sctp_sendmsg(sk1, ttlmsg, strlen(ttlmsg) + 1,
+			  (struct sockaddr *)&loop2, sizeof(loop2),
+			  ppid, 0, stream, 2000, 0);
+
+	tst_resm(TPASS, "sctp_sendmsg with ttl");
+
+	/* Next send a message that won't time out. */
+	test_sctp_sendmsg(sk1, nottlmsg, strlen(nottlmsg) + 1,
+			  (struct sockaddr *)&loop2, sizeof(loop2),
+			  ppid, 0, stream, 0, 0);
+
+	tst_resm(TPASS, "sctp_sendmsg with zero ttl");
+
+	/* And finally a fragmented message that will time out. */
+	memset(ttlfrag, 48, sizeof(ttlfrag)); /* 48 is the ascii of '0' */
+	ttlfrag[sizeof(ttlfrag)-1] = '\0';
+	test_sctp_sendmsg(sk1, ttlfrag, sizeof(ttlfrag),
+			  (struct sockaddr *)&loop2, sizeof(loop2),
+			  ppid, 0, stream, 2000, 0);
+
+	tst_resm(TPASS, "sctp_sendmsg fragmented msg with ttl");
+
+	/* Sleep waiting for the message to time out. */
+	tst_resm(TINFO, "**  SLEEPING for 3 seconds **");
+	sleep(3);
+
+	/* Get the fillmsg. */
+	do {
+		buflen = REALLY_BIG;
+		msgname_len = sizeof(msgname);
+		msg_flags = 0;
+		test_sctp_recvmsg(sk2, big_buffer, buflen,
+			  (struct sockaddr *)&msgname, &msgname_len,
+			  &sinfo, &msg_flags); 
+	} while (!(msg_flags & MSG_EOR));
+
+	/* Get the message that did NOT time out. */
+	buflen = REALLY_BIG;
+	msgname_len = sizeof(msgname);
+	msg_flags = 0;
+	error = test_sctp_recvmsg(sk2, big_buffer, buflen,
+			  (struct sockaddr *)&msgname, &msgname_len,
+			  &sinfo, &msg_flags); 
+	test_check_buf_data(big_buffer, error, msg_flags, &sinfo,
+			    strlen(nottlmsg) + 1, MSG_EOR, stream, ppid); 
+	if (0 != strncmp(big_buffer, nottlmsg, strlen(nottlmsg)))
+		tst_brkm(TBROK, tst_exit, "sctp_recvmsg: Wrong Message !!!");
+
+	tst_resm(TPASS, "sctp_recvmsg msg with zero ttl");
+
+	/* Get the SEND_FAILED notification for the message that DID
+	 * time out.
+	 */
+	buflen = REALLY_BIG;
+	msgname_len = sizeof(msgname);
+	msg_flags = 0;
+	error = test_sctp_recvmsg(sk1, big_buffer, buflen,
+			  (struct sockaddr *)&msgname, &msgname_len,
+			  &sinfo, &msg_flags); 
+	test_check_buf_notification(big_buffer, error, msg_flags,
+				    sizeof(struct sctp_send_failed) +
+							strlen(ttlmsg) + 1,
+				    SCTP_SEND_FAILED, 0);
+	ssf = (struct sctp_send_failed *)big_buffer;
+	if (0 != strncmp(ttlmsg, (char *)ssf->ssf_data, strlen(ttlmsg) + 1))
+		tst_brkm(TBROK, tst_exit, "SEND_FAILED data mismatch");
+
+	tst_resm(TPASS, "sctp_recvmsg SEND_FAILED for message with ttl");
+
+	offset = 0;
+
+	/* Get the SEND_FAILED notifications for the fragmented message that 
+	 * timed out.
+	 */
+	do {
+		buflen = REALLY_BIG;
+		msgname_len = sizeof(msgname);
+		msg_flags = 0;
+		error = test_sctp_recvmsg(sk1, big_buffer, buflen,
+			  (struct sockaddr *)&msgname, &msgname_len,
+			  &sinfo, &msg_flags); 
+		test_check_buf_notification(big_buffer, error, msg_flags,
+					    sizeof(struct sctp_send_failed) +
+							          SMALL_MAXSEG,
+					    SCTP_SEND_FAILED, 0);
+		ssf = (struct sctp_send_failed *)big_buffer;
+		if (0 != strncmp(&ttlfrag[offset], (char *)ssf->ssf_data,
+				 SMALL_MAXSEG))
+			tst_brkm(TBROK, tst_exit, "SEND_FAILED data mismatch");
+		offset += SMALL_MAXSEG;
+	} while (!(ssf->ssf_info.sinfo_flags & 0x01)); /* LAST FRAG */
+
+	tst_resm(TPASS, "sctp_recvmsg SEND_FAILED for fragmented message with "
+		 "ttl");
+
+	snd_sinfo.sinfo_ppid = rand();
+	snd_sinfo.sinfo_flags = 0; 
+	snd_sinfo.sinfo_stream = 2; 
+	snd_sinfo.sinfo_timetolive = 0; 
+	snd_sinfo.sinfo_assoc_id = associd1; 
+	test_sctp_send(sk1, message, strlen(message) + 1, &snd_sinfo,
+		       MSG_NOSIGNAL);
+
+	buflen = REALLY_BIG;
+	msgname_len = sizeof(msgname);
+	msg_flags = 0;
+	error = test_sctp_recvmsg(sk2, big_buffer, buflen,
+				  (struct sockaddr *)&msgname, &msgname_len,
+				  &sinfo, &msg_flags); 
+	test_check_buf_data(big_buffer, error, msg_flags, &sinfo,
+			    strlen(message) + 1, MSG_EOR, snd_sinfo.sinfo_stream,
+			    snd_sinfo.sinfo_ppid); 
+
+	tst_resm(TPASS, "sctp_send");
+
+	/* Shut down the link.  */
+	close(sk1);
+
+	/* Get the shutdown complete notification. */
+	buflen = REALLY_BIG;
+	msgname_len = sizeof(msgname);
+	msg_flags = 0;
+	error = test_sctp_recvmsg(sk2, big_buffer, buflen,
+		  (struct sockaddr *)&msgname, &msgname_len,
+		  &sinfo, &msg_flags); 
+	test_check_buf_notification(big_buffer, error, msg_flags,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_SHUTDOWN_COMP);
+
+	close(sk2);
+
+	/* Indicate successful completion.  */
+	return 0;	
+}
diff --git a/src/func_tests/test_sctp_sendvrecvv.c b/src/func_tests/test_sctp_sendvrecvv.c
new file mode 100644
index 0000000..4991e79
--- /dev/null
+++ b/src/func_tests/test_sctp_sendvrecvv.c
@@ -0,0 +1,270 @@
+/* SCTP kernel Implementation
+ * (C) Copyright REDHAT Corp. 2018
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ * To compile the v6 version, set the symbol TEST_V6 to 1.
+ *
+ * Written or modified by:
+ *    Xin Long		<lucien.xin@gmail.com>
+ */
+
+/* This is a basic functional test for the SCTP new library APIs
+ * sctp_sendv() and sctp_recvv().
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 10;
+int TST_CNT;
+
+/* RCVBUF value, and indirectly RWND*2 */
+#define SMALL_RCVBUF 3000
+#define SMALL_MAXSEG 500
+/* This is extra data length to ensure rwnd closes */
+#define RWND_SLOP    100
+static char *message = "Hello world\n";
+
+int main(int argc, char *argv[])
+{
+	sockaddr_storage_t loop1, loop2, msgname;
+	int sk1, sk2, error, buflen, i, addrcnt;
+	socklen_t msgname_len, rn_len;
+	struct sctp_authinfo authinfo;
+	struct sctp_sndinfo sndinfo;
+	struct sockaddr *addr_list;
+	struct sctp_sendv_spa spa;
+	uint32_t infotype, stream;
+	struct iovec iov, iovx[3];
+	struct sctp_prinfo prinfo;
+	struct sctp_recvv_rn rn;
+	int pf_class, msg_flags;
+	socklen_t val = 1;
+	char addr_str[64];
+
+	/* Set some basic values which depend on the address family. */
+#if TEST_V6
+	struct sockaddr_in6 *v6addrs;
+
+	pf_class = PF_INET6;
+
+	loop1.v6.sin6_family = AF_INET6;
+	loop1.v6.sin6_addr = in6addr_loopback;
+	loop1.v6.sin6_port = htons(SCTP_TESTPORT_1);
+
+	loop2.v6.sin6_family = AF_INET6;
+	loop2.v6.sin6_addr = in6addr_loopback;
+	loop2.v6.sin6_port = htons(SCTP_TESTPORT_2);
+
+	addrcnt = 5;
+	v6addrs = test_malloc(sizeof(*v6addrs) * addrcnt);
+	v6addrs[0].sin6_family = PF_INET6;
+	v6addrs[0].sin6_addr = in6addr_loopback;
+	v6addrs[0].sin6_port = htons(SCTP_TESTPORT_2);
+	for (i = 1; i < addrcnt; i++) {
+		sprintf(addr_str, "2020::%d", i);
+		v6addrs[i].sin6_family = PF_INET6;
+		inet_pton(PF_INET6, addr_str, &v6addrs[i].sin6_addr);
+	}
+	addr_list = (struct sockaddr *)v6addrs;
+#else
+	struct sockaddr_in *v4addrs;
+
+	pf_class = PF_INET;
+
+	loop1.v4.sin_family = AF_INET;
+	loop1.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+	loop1.v4.sin_port = htons(SCTP_TESTPORT_1);
+
+	loop2.v4.sin_family = AF_INET;
+	loop2.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+	loop2.v4.sin_port = htons(SCTP_TESTPORT_2);
+
+	addrcnt = 5;
+	v4addrs = test_malloc(sizeof(*v4addrs) * addrcnt);
+	v4addrs[0].sin_family = PF_INET;
+	v4addrs[0].sin_addr.s_addr = SCTP_IP_LOOPBACK;
+	v4addrs[0].sin_port = htons(SCTP_TESTPORT_2);
+	for (i = 1; i < addrcnt; i++) {
+		sprintf(addr_str, "172.16.1.%d", i);
+		v4addrs[i].sin_family = PF_INET;
+		v4addrs[i].sin_addr.s_addr = inet_addr(addr_str);
+	}
+	addr_list = (struct sockaddr *)v4addrs;
+#endif /* TEST_V6 */
+
+	setvbuf(stdout, NULL, _IONBF, 0);
+
+	/* Create the two endpoints which will talk to each other.  */
+	sk1 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+	sk2 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+
+	/* Bind these sockets to the test ports.  */
+	test_bind(sk1, &loop1.sa, sizeof(loop1));
+	test_bind(sk2, &loop2.sa, sizeof(loop2));
+
+	/* Mark sk2 as being able to accept new associations.  */
+	test_listen(sk2, 1);
+
+
+	/* Testing for sctp_sendv */
+	iov.iov_base = message;
+	iov.iov_len = strlen(message) + 1;
+	test_sctp_sendv(sk1, &iov, 1, addr_list, addrcnt, NULL, 0, 0, 0);
+	tst_resm(TPASS, "sctp_sendv addr info");
+
+	stream = 1;
+	memset(&sndinfo, 0, sizeof(sndinfo));
+	sndinfo.snd_flags = SCTP_UNORDERED;
+	sndinfo.snd_sid = stream;
+	test_sctp_sendv(sk1, &iov, 1, addr_list, addrcnt, &sndinfo,
+			sizeof(sndinfo), SCTP_SENDV_SNDINFO, 0);
+	tst_resm(TPASS, "sctp_sendv sndinfo with stream %d", stream);
+
+	iovx[0].iov_base = message;
+	iovx[0].iov_len = strlen(message) + 1;
+	iovx[1].iov_base = message;
+	iovx[1].iov_len = strlen(message) + 1;
+	iovx[2].iov_base = message;
+	iovx[2].iov_len = strlen(message) + 1;
+
+	stream = 2;
+	sndinfo.snd_sid = stream;
+	test_sctp_sendv(sk1, iovx, 3, addr_list, addrcnt, &sndinfo,
+			sizeof(sndinfo), SCTP_SENDV_SNDINFO, 0);
+	tst_resm(TPASS, "sctp_sendv sndinfo with stream %d", stream);
+
+	prinfo.pr_policy = SCTP_PR_SCTP_RTX;
+	prinfo.pr_value = 10;
+	test_sctp_sendv(sk1, iovx, 3, addr_list, addrcnt, &prinfo,
+			sizeof(prinfo), SCTP_SENDV_PRINFO, 0);
+	tst_resm(TPASS, "sctp_sendv prinfo");
+
+	authinfo.auth_keynumber = 0;
+	test_sctp_sendv(sk1, iovx, 3, addr_list, addrcnt, &authinfo,
+			sizeof(authinfo), SCTP_SENDV_AUTHINFO, 0);
+	tst_resm(TPASS, "sctp_sendv authinfo");
+
+
+	spa.sendv_sndinfo = sndinfo;
+	spa.sendv_prinfo = prinfo;
+	spa.sendv_authinfo = authinfo;
+
+	stream = 3;
+	spa.sendv_sndinfo.snd_sid = stream;
+	spa.sendv_flags = SCTP_SEND_SNDINFO_VALID | SCTP_SEND_PRINFO_VALID;
+	test_sctp_sendv(sk1, iovx, 3, addr_list, addrcnt, &spa,
+			sizeof(spa), SCTP_SENDV_SPA, 0);
+	tst_resm(TPASS, "sctp_sendv spa with stream %d", stream);
+
+	stream = 4;
+	spa.sendv_sndinfo.snd_sid = stream;
+	spa.sendv_flags = SCTP_SEND_SNDINFO_VALID | SCTP_SEND_PRINFO_VALID |
+			  SCTP_SEND_AUTHINFO_VALID;
+	test_sctp_sendv(sk1, iovx, 3, addr_list, addrcnt, &spa,
+			sizeof(spa), SCTP_SENDV_SPA, 0);
+	tst_resm(TPASS, "sctp_sendv spa with stream %d", stream);
+
+	/* Testing for sctp_recvv */
+	buflen = REALLY_BIG;
+	msgname_len = sizeof(msgname);
+	msg_flags = 0;
+	iov.iov_base = test_malloc(buflen);
+	iov.iov_len = buflen;
+	rn_len = sizeof(rn);
+
+	error = test_sctp_recvv(sk2, &iov, 1, (struct sockaddr *)&msgname,
+				&msgname_len, &rn, &rn_len, &infotype,
+				&msg_flags);
+	if (infotype != SCTP_RECVV_NOINFO)
+		tst_brkm(TBROK, tst_exit, "sctp_recvv infotype %d != %d",
+			 infotype, SCTP_RECVV_NOINFO);
+	tst_resm(TPASS, "sctp_recvv SCTP_RECVV_NOINFO");
+
+	error = setsockopt(sk2, SOL_SCTP, SCTP_RECVRCVINFO,
+			   &val, sizeof(val));
+	if (error)
+		tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_RECVRCVINFO): %s",
+			 strerror(errno));
+
+	error = test_sctp_recvv(sk2, &iov, 1, (struct sockaddr *)&msgname,
+				&msgname_len, &rn, &rn_len, &infotype,
+				&msg_flags);
+	if (infotype != SCTP_RECVV_RCVINFO ||
+	    rn.recvv_rcvinfo.rcv_sid != 1)
+		tst_brkm(TBROK, tst_exit, "sctp_recvv infotype %d != %d",
+			 infotype, SCTP_RECVV_NOINFO);
+	tst_resm(TPASS, "sctp_recvv SCTP_RECVV_RCVINFO");
+
+	error = setsockopt(sk2, SOL_SCTP, SCTP_RECVNXTINFO,
+			   &val, sizeof(val));
+	if (error)
+		tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_RECVNXTINFO): %s",
+			 strerror(errno));
+
+	rn_len = 1;
+	error = test_sctp_recvv(sk2, &iov, 1, (struct sockaddr *)&msgname,
+				&msgname_len, &rn, &rn_len, &infotype,
+				&msg_flags);
+	if (infotype != SCTP_RECVV_NOINFO)
+		tst_brkm(TBROK, tst_exit, "sctp_recvv infotype %d != %d",
+			 infotype, SCTP_RECVV_NOINFO);
+	tst_resm(TPASS, "sctp_recvv SCTP_RECVV_NOINFO due to small size");
+
+	rn_len = sizeof(struct sctp_nxtinfo);
+	error = test_sctp_recvv(sk2, &iov, 1, (struct sockaddr *)&msgname,
+				&msgname_len, &rn, &rn_len, &infotype,
+				&msg_flags);
+	if (infotype != SCTP_RECVV_NXTINFO)
+		tst_brkm(TBROK, tst_exit, "sctp_recvv infotype %d != %d",
+			 infotype, SCTP_RECVV_NXTINFO);
+	tst_resm(TPASS, "sctp_recvv SCTP_RECVV_NXTINFO due to small size");
+
+	rn_len = sizeof(rn);
+	error = test_sctp_recvv(sk2, &iov, 1, (struct sockaddr *)&msgname,
+				&msgname_len, &rn, &rn_len, &infotype,
+				&msg_flags);
+	if (infotype != SCTP_RECVV_RN ||
+	    rn.recvv_rcvinfo.rcv_sid != 0 || rn.recvv_nxtinfo.nxt_sid != 3)
+		tst_brkm(TBROK, tst_exit, "sctp_recvv infotype %d != %d",
+			 infotype, SCTP_RECVV_RN);
+	tst_resm(TPASS, "sctp_recvv SCTP_RECVV_RN");
+
+	close(sk1);
+	close(sk2);
+
+	return 0;
+}
diff --git a/src/func_tests/test_sockopt.c b/src/func_tests/test_sockopt.c
new file mode 100644
index 0000000..2bd1097
--- /dev/null
+++ b/src/func_tests/test_sockopt.c
@@ -0,0 +1,1147 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2001, 2004
+ * Copyright (c) 1999-2000 Cisco, Inc.
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ * Copyright (c) 2001 Intel Corp.
+ * Copyright (c) 2001 Nokia, Inc.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ *    La Monte H.P. Yarroll <piggy@acm.org>
+ *    Karl Knutson <karl@athena.chicago.il.us>
+ *    Hui Huang <hui.huang@nokia.com>
+ *    Jon Grimm <jgrimm@us.ibm.com>
+ *    Sridhar Samudrala <samudrala@us.ibm.com>
+ */
+
+/* This is a functional test to verify the various SCTP level socket
+ * options that can be used to get information about existing SCTP
+ * associations and to configure certain parameters.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <errno.h>
+#include <netinet/in.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 29;
+int TST_CNT = 0;
+
+int
+main(void)
+{
+	int udp_svr_sk, udp_clt_sk, tcp_svr_sk, tcp_clt_sk;
+	int accept_sk, peeloff_sk;
+        sockaddr_storage_t udp_svr_loop, udp_clt_loop;
+        sockaddr_storage_t tcp_svr_loop, tcp_clt_loop;
+        struct iovec iov;
+        struct msghdr inmessage;
+	struct msghdr outmessage;
+	char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+	char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+	struct cmsghdr *cmsg;
+	struct sctp_sndrcvinfo *sinfo;
+        struct iovec out_iov;
+        char *message = "hello, world!\n";
+        int error;
+	int pf_class;
+	uint32_t ppid;
+	uint32_t stream;
+	sctp_assoc_t udp_svr_associd, udp_clt_associd;
+	struct sctp_assoc_change *sac;
+	char *big_buffer;
+	struct sctp_event_subscribe subscribe;
+	struct sctp_initmsg initmsg;
+	struct sctp_paddrparams paddrparams;
+	struct sctp_sndrcvinfo set_udp_sk_dflt_param, get_udp_sk_dflt_param; 
+	struct sctp_sndrcvinfo set_tcp_sk_dflt_param, get_tcp_sk_dflt_param; 
+	struct sctp_sndrcvinfo set_udp_assoc_dflt_param;
+	struct sctp_sndrcvinfo get_udp_assoc_dflt_param; 
+	struct sctp_sndrcvinfo set_tcp_assoc_dflt_param;
+	struct sctp_sndrcvinfo get_tcp_assoc_dflt_param; 
+	struct sctp_sndrcvinfo get_peeloff_assoc_dflt_param; 
+	struct sctp_sndrcvinfo get_accept_assoc_dflt_param; 
+	struct sctp_paddrinfo pinfo;
+	int dflt_pathmaxrxt;
+	socklen_t optlen, addrlen;
+	struct sctp_status status;
+	struct sctp_assoc_value value;
+
+        /* Rather than fflush() throughout the code, set stdout to
+	 * be unbuffered.
+	 */
+	setvbuf(stdout, NULL, _IONBF, 0);
+
+	/* Set some basic values which depend on the address family. */
+#if TEST_V6
+	pf_class = PF_INET6;
+
+        udp_svr_loop.v6.sin6_family = AF_INET6;
+        udp_svr_loop.v6.sin6_addr = in6addr_loopback;
+        udp_svr_loop.v6.sin6_port = htons(SCTP_TESTPORT_1);
+
+        udp_clt_loop.v6.sin6_family = AF_INET6;
+        udp_clt_loop.v6.sin6_addr = in6addr_loopback;
+        udp_clt_loop.v6.sin6_port = htons(SCTP_TESTPORT_1+1);
+
+        tcp_svr_loop.v6.sin6_family = AF_INET6;
+        tcp_svr_loop.v6.sin6_addr = in6addr_loopback;
+        tcp_svr_loop.v6.sin6_port = htons(SCTP_TESTPORT_1+2);
+
+        tcp_clt_loop.v6.sin6_family = AF_INET6;
+        tcp_clt_loop.v6.sin6_addr = in6addr_loopback;
+        tcp_clt_loop.v6.sin6_port = htons(SCTP_TESTPORT_1+3);
+#else
+	pf_class = PF_INET;
+
+        udp_svr_loop.v4.sin_family = AF_INET;
+        udp_svr_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+        udp_svr_loop.v4.sin_port = htons(SCTP_TESTPORT_1);
+
+        udp_clt_loop.v4.sin_family = AF_INET;
+        udp_clt_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+        udp_clt_loop.v4.sin_port = htons(SCTP_TESTPORT_1+1);
+
+        tcp_svr_loop.v4.sin_family = AF_INET;
+        tcp_svr_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+        tcp_svr_loop.v4.sin_port = htons(SCTP_TESTPORT_1+2);
+
+        tcp_clt_loop.v4.sin_family = AF_INET;
+        tcp_clt_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+        tcp_clt_loop.v4.sin_port = htons(SCTP_TESTPORT_2+3);
+#endif /* TEST_V6 */
+
+        /* Create the two endpoints which will talk to each other.  */
+        udp_svr_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+        udp_clt_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+
+	/* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+	test_enable_assoc_change(udp_svr_sk);
+	test_enable_assoc_change(udp_clt_sk);
+
+        /* Bind these sockets to the test ports.  */
+        test_bind(udp_svr_sk, &udp_svr_loop.sa, sizeof(udp_svr_loop));
+        test_bind(udp_clt_sk, &udp_clt_loop.sa, sizeof(udp_clt_loop));
+
+       /* Mark udp_svr_sk as being able to accept new associations.  */
+	test_listen(udp_svr_sk, 1);
+
+	/* TEST #1: SCTP_STATUS socket option. */
+	/* Make sure that SCTP_STATUS getsockopt on a socket with no
+	 * association fails.
+	 */
+	optlen = sizeof(struct sctp_status);
+	memset(&status, 0, optlen);
+	error = getsockopt(udp_svr_sk, SOL_SCTP, SCTP_STATUS, &status,
+			   &optlen);
+	if ((error != -1) && (errno != EINVAL))
+		tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_STATUS) on a "
+			 "socket with no assoc error:%d errno:%d",
+			 error, errno);
+
+	tst_resm(TPASS, "getsockopt(SCTP_STATUS) on a socket with no assoc");
+
+        /* Send the first message.  This will create the association.  */
+        outmessage.msg_name = &udp_svr_loop;
+        outmessage.msg_namelen = sizeof(udp_svr_loop);
+        outmessage.msg_iov = &out_iov;
+        outmessage.msg_iovlen = 1;
+        outmessage.msg_control = outcmsg;
+        outmessage.msg_controllen = sizeof(outcmsg);
+        outmessage.msg_flags = 0;
+	cmsg = CMSG_FIRSTHDR(&outmessage);
+	cmsg->cmsg_level = IPPROTO_SCTP;
+	cmsg->cmsg_type = SCTP_SNDRCV;
+	cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+	outmessage.msg_controllen = cmsg->cmsg_len;
+	sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+	memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+	ppid = rand(); /* Choose an arbitrary value. */
+	stream = 1;
+	sinfo->sinfo_ppid = ppid;
+	sinfo->sinfo_stream = stream;
+        outmessage.msg_iov->iov_base = message;
+        outmessage.msg_iov->iov_len = strlen(message) + 1;
+        test_sendmsg(udp_clt_sk, &outmessage, 0, strlen(message)+1);
+
+	/* Initialize inmessage for all receives. */
+	big_buffer = test_malloc(REALLY_BIG);
+        memset(&inmessage, 0, sizeof(inmessage));
+        iov.iov_base = big_buffer;
+        iov.iov_len = REALLY_BIG;
+        inmessage.msg_iov = &iov;
+        inmessage.msg_iovlen = 1;
+        inmessage.msg_control = incmsg;
+
+        /* Get the communication up message on udp_svr_sk.  */
+        inmessage.msg_controllen = sizeof(incmsg);
+        error = test_recvmsg(udp_svr_sk, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage, error,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);	
+	sac = (struct sctp_assoc_change *)iov.iov_base;
+	udp_svr_associd = sac->sac_assoc_id;
+
+        /* Get the communication up message on udp_clt_sk.  */
+        inmessage.msg_controllen = sizeof(incmsg);
+        error = test_recvmsg(udp_clt_sk, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage, error,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);	
+	sac = (struct sctp_assoc_change *)iov.iov_base;
+	udp_clt_associd = sac->sac_assoc_id;
+
+        /* Get the first message which was sent.  */
+        inmessage.msg_controllen = sizeof(incmsg);
+        error = test_recvmsg(udp_svr_sk, &inmessage, MSG_WAITALL);
+        test_check_msg_data(&inmessage, error, strlen(message) + 1,
+			    MSG_EOR, stream, ppid);
+
+	/* Get SCTP_STATUS for udp_clt_sk's given association. */
+	optlen = sizeof(struct sctp_status);
+	memset(&status, 0, optlen);
+	status.sstat_assoc_id = udp_clt_associd;
+	test_getsockopt(udp_clt_sk, SCTP_STATUS, &status, &optlen);
+
+	tst_resm(TPASS, "getsockopt(SCTP_STATUS)");
+
+	/* Make sure that SCTP_STATUS getsockopt with invalid associd fails. */
+	optlen = sizeof(struct sctp_status);
+	memset(&status, 0, optlen);
+	status.sstat_assoc_id = udp_svr_associd;
+	error = getsockopt(udp_clt_sk, SOL_SCTP, SCTP_STATUS, &status,
+			   &optlen); 
+	if ((error != -1) && (errno != EINVAL))
+        	tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_STATUS) with "
+			 "associd error: %d errno:%d", error, errno);
+
+	tst_resm(TPASS, "getsockopt(SCTP_STATUS) with invalid associd");
+
+	/* Make sure that SCTP_STATUS getsockopt with NULL associd fails. */
+	optlen = sizeof(struct sctp_status);
+	memset(&status, 0, optlen);
+	status.sstat_assoc_id = 0;
+	error = getsockopt(udp_svr_sk, SOL_SCTP, SCTP_STATUS, &status,
+			   &optlen);
+	if ((error != -1) && (errno != EINVAL))
+        	tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_STATUS) with "
+			 "NULL associd error: %d errno:%d", error, errno);
+
+	tst_resm(TPASS, "getsockopt(SCTP_STATUS) with NULL associd");
+
+        /* Shut down the link.  */
+        close(udp_clt_sk);
+
+        /* Get the shutdown complete notification. */
+	inmessage.msg_controllen = sizeof(incmsg);
+        error = test_recvmsg(udp_svr_sk, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage, error,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_SHUTDOWN_COMP);	
+				
+	error = 0;
+        close(udp_svr_sk);
+
+	/* TEST #2: SCTP_EVENTS socket option and SCTP_SHUTDOWN_EVENT
+	 * notification.
+	 */
+        /* Create the two endpoints which will talk to each other.  */
+	udp_svr_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+	udp_clt_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+
+	/* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+	test_enable_assoc_change(udp_svr_sk);
+	test_enable_assoc_change(udp_clt_sk);
+
+	/* Bind these sockets to the test ports.  */
+	test_bind(udp_svr_sk, &udp_svr_loop.sa, sizeof(udp_svr_loop));
+	test_bind(udp_clt_sk, &udp_clt_loop.sa, sizeof(udp_clt_loop));
+
+	/* Mark udp_svr_sk as being able to accept new associations.  */
+	test_listen(udp_svr_sk, 1);
+
+	/* Get the default events that are enabled on udp_svr_sk. */
+	optlen = sizeof(subscribe);
+	test_getsockopt(udp_svr_sk, SCTP_EVENTS, &subscribe, &optlen);
+
+	/* Get the default events that are enabled on udp_clt_sk. */
+	optlen = sizeof(subscribe);
+	test_getsockopt(udp_clt_sk, SCTP_EVENTS, &subscribe, &optlen);
+
+	tst_resm(TPASS, "getsockopt(SCTP_EVENTS)");
+
+	/* Disable all the events on udp_svr_sk and udp_clt_sk. */
+	memset(&subscribe, 0, sizeof(struct sctp_event_subscribe));
+	test_setsockopt(udp_svr_sk, SCTP_EVENTS, &subscribe,
+			sizeof(subscribe));
+	test_setsockopt(udp_clt_sk, SCTP_EVENTS, &subscribe,
+			sizeof(subscribe));
+
+	tst_resm(TPASS, "setsockopt(SCTP_EVENTS)");
+
+	/* Get the updated list of enabled events on udp_svr_sk and
+	 * udp_clt_sk.
+	 */
+	optlen = sizeof(subscribe);
+	test_getsockopt(udp_svr_sk, SCTP_EVENTS, &subscribe, &optlen);
+	optlen = sizeof(subscribe);
+	test_getsockopt(udp_clt_sk, SCTP_EVENTS, &subscribe, &optlen);
+
+	/* Send a message.  This will create the association.  */
+	outmessage.msg_iov->iov_base = message;
+	outmessage.msg_iov->iov_len = strlen(message) + 1;
+	test_sendmsg(udp_clt_sk, &outmessage, 0, strlen(message)+1);
+
+	/* Get the message which was sent.  */
+	inmessage.msg_controllen = sizeof(incmsg);
+	error = test_recvmsg(udp_svr_sk, &inmessage, MSG_WAITALL);
+        test_check_msg_data(&inmessage, error, strlen(message) + 1,
+			    MSG_EOR, 0, 0);
+	/* Verify that we received the msg without any ancillary data. */
+	if (inmessage.msg_controllen != 0)
+		tst_brkm(TBROK, tst_exit, "Receive unexpected ancillary"
+			 "data");
+
+	/* Enable SCTP_SHUTDOWN_EVENTs on udp_svr_sk. */
+	memset(&subscribe, 0, sizeof(struct sctp_event_subscribe));
+	subscribe.sctp_shutdown_event = 1;
+	test_setsockopt(udp_svr_sk, SCTP_EVENTS, &subscribe,
+			sizeof(subscribe));
+
+	error = 0;
+        /* Shut down the link.  */
+        close(udp_clt_sk);
+
+	/* Get the SHUTDOWN_EVENT notification on udp_svr_sk. */
+	inmessage.msg_controllen = sizeof(incmsg);
+	error = test_recvmsg(udp_svr_sk, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage, error,
+				    sizeof(struct sctp_shutdown_event),
+				    SCTP_SHUTDOWN_EVENT, 0);	
+
+	tst_resm(TPASS, "setsockopt(SCTP_EVENTS) - SCTP_SHUTDOWN_EVENT");
+ 
+        close(udp_svr_sk);
+
+	/* TEST #3: whether sctp_opt_info equals */
+        /* Create the two endpoints which will talk to each other.  */
+	udp_svr_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+	udp_clt_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+
+	/* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+	test_enable_assoc_change(udp_svr_sk);
+	test_enable_assoc_change(udp_clt_sk);
+
+	/* Bind these sockets to the test ports.  */
+	test_bind(udp_svr_sk, &udp_svr_loop.sa, sizeof(udp_svr_loop));
+	test_bind(udp_clt_sk, &udp_clt_loop.sa, sizeof(udp_clt_loop));
+
+	/* Mark udp_svr_sk as being able to accept new associations.  */
+	test_listen(udp_svr_sk, 1);
+
+        /* Send the first message.  This will create the association.  */
+        outmessage.msg_name = &udp_svr_loop;
+        outmessage.msg_namelen = sizeof(udp_svr_loop);
+        outmessage.msg_iov = &out_iov;
+        outmessage.msg_iovlen = 1;
+        outmessage.msg_control = outcmsg;
+        outmessage.msg_controllen = sizeof(outcmsg);
+        outmessage.msg_flags = 0;
+	cmsg = CMSG_FIRSTHDR(&outmessage);
+	cmsg->cmsg_level = IPPROTO_SCTP;
+	cmsg->cmsg_type = SCTP_SNDRCV;
+	cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+	outmessage.msg_controllen = cmsg->cmsg_len;
+	sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+	memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+	ppid = rand(); /* Choose an arbitrary value. */
+	stream = 1;
+	sinfo->sinfo_ppid = ppid;
+	sinfo->sinfo_stream = stream;
+        outmessage.msg_iov->iov_base = message;
+        outmessage.msg_iov->iov_len = strlen(message) + 1;
+        test_sendmsg(udp_clt_sk, &outmessage, 0, strlen(message)+1);
+	
+        /* Get the communication up message on udp_clt_sk.  */
+        inmessage.msg_controllen = sizeof(incmsg);
+        error = test_recvmsg(udp_clt_sk, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage, error,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);	
+	sac = (struct sctp_assoc_change *)iov.iov_base;
+	udp_clt_associd = sac->sac_assoc_id;
+
+	/* Compare the SCTP_STATUS result between sctp_opt_info and 
+	 * getsockopt
+	 */
+	{
+		struct sctp_status status1, status2;
+
+		memset(&status1, 0, sizeof(status1));
+		memset(&status2, 0, sizeof(status2));
+		optlen = sizeof(struct sctp_status);
+
+		/* Test SCTP_STATUS for udp_clt_sk's given association. */	
+		error = sctp_opt_info(udp_clt_sk,udp_clt_associd,SCTP_STATUS,
+				(char *)&status1, &optlen);
+		if (error != 0)
+	                tst_brkm(TBROK, tst_exit,
+				 "sctp_opt_info(SCTP_STATUS): %s", 
+				 strerror(errno));
+
+		status2.sstat_assoc_id = udp_clt_associd;
+		error = getsockopt(udp_clt_sk, IPPROTO_SCTP, SCTP_STATUS,
+                		(char *)&status2, &optlen);
+		if (error != 0)
+	                tst_brkm(TBROK, tst_exit,
+				 "getsockopt(SCTP_STATUS): %s", 
+				 strerror(errno));
+		if (strncmp((char *)&status1, (char *)&status2, optlen))
+	                tst_brkm(TBROK, tst_exit, "sctp_opt_info(SCTP_STAUS)"
+			       "doesn't match getsockopt(SCTP_STATUS)");
+
+                tst_resm(TPASS, "sctp_opt_info(SCTP_STATUS)");
+	}
+	error = 0;
+        /* Shut down the link.  */
+        close(udp_svr_sk);
+        close(udp_clt_sk);
+
+	/* TEST #4: SCTP_INITMSG socket option. */
+        /* Create a socket.  */
+	udp_svr_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+
+	/* Bind this socket to the test port.  */
+	test_bind(udp_svr_sk, &udp_svr_loop.sa, sizeof(udp_svr_loop));
+
+	/* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+	test_enable_assoc_change(udp_svr_sk);
+
+	/* Get the default parameters for association initialization. */
+	optlen = sizeof(initmsg);
+	test_getsockopt(udp_svr_sk, SCTP_INITMSG, &initmsg, &optlen);
+
+	tst_resm(TPASS, "getsockopt(SCTP_INITMSG)");
+
+	/* Change the parameters for association initialization. */
+	initmsg.sinit_num_ostreams = 5;
+	initmsg.sinit_max_instreams = 5;
+	initmsg.sinit_max_attempts = 3;
+	initmsg.sinit_max_init_timeo = 30;
+	test_setsockopt(udp_svr_sk, SCTP_INITMSG, &initmsg, sizeof(initmsg));
+
+	tst_resm(TPASS, "setsockopt(SCTP_INITMSG)");
+
+	/* Get the updated parameters for association initialization. */
+	optlen = sizeof(initmsg);
+	test_getsockopt(udp_svr_sk, SCTP_INITMSG, &initmsg, &optlen);
+	
+	close(udp_svr_sk);
+
+	/* TEST #5: SCTP_PEER_ADDR_PARAMS socket option. */
+        /* Create a socket.  */
+	udp_svr_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+
+	/* Get the default parameters for this endpoint */
+	optlen = sizeof(paddrparams);
+	memset(&paddrparams, 0, sizeof(paddrparams));
+	paddrparams.spp_address.ss_family = AF_INET;
+	test_getsockopt(udp_svr_sk, SCTP_PEER_ADDR_PARAMS, &paddrparams,
+								&optlen);
+
+	dflt_pathmaxrxt = paddrparams.spp_pathmaxrxt;
+	tst_resm(TPASS, "getsockopt(SCTP_PEER_ADDR_PARAMS)");
+
+	/* Change the default parameters for this endpoint (socket) */
+	paddrparams.spp_hbinterval = 1000;
+	paddrparams.spp_pathmaxrxt = dflt_pathmaxrxt+1;
+	paddrparams.spp_sackdelay = 100;
+	test_setsockopt(udp_svr_sk, SCTP_PEER_ADDR_PARAMS, &paddrparams,
+							sizeof(paddrparams));
+
+	paddrparams.spp_pathmaxrxt = 0;
+
+	/* Get the updated default parameters for this endpoint. */
+	optlen = sizeof(paddrparams);
+	test_getsockopt(udp_svr_sk, SCTP_PEER_ADDR_PARAMS, &paddrparams,
+								&optlen);
+	if (paddrparams.spp_pathmaxrxt != dflt_pathmaxrxt+1)
+		tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+			 "mismatch");
+
+	value.assoc_id = 0;
+	optlen = sizeof(value);
+	test_getsockopt(udp_svr_sk, SCTP_DELAYED_ACK_TIME, &value,
+								&optlen);
+	if (value.assoc_value != 100)
+		tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DELAYED_ACK_TIME) "
+			 "mismatch");
+
+	value.assoc_id    = 0;
+	value.assoc_value = 250;
+	test_setsockopt(udp_svr_sk, SCTP_DELAYED_ACK_TIME, &value,
+							sizeof(value));
+	optlen = sizeof(paddrparams);
+	test_getsockopt(udp_svr_sk, SCTP_PEER_ADDR_PARAMS, &paddrparams,
+								&optlen);
+	if (paddrparams.spp_sackdelay != 250)
+		tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_DELAYED_ACK_TIME) "
+			 "mismatch");
+
+	tst_resm(TPASS, "setsockopt(SCTP_DELAYED_ACK_TIME)");
+
+
+	/* Ensure that prior defaults are preserved for a new endpoint */
+	udp_clt_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+	optlen = sizeof(paddrparams);
+	memset(&paddrparams, 0, sizeof(paddrparams));
+	paddrparams.spp_address.ss_family = AF_INET;
+	test_getsockopt(udp_clt_sk, SCTP_PEER_ADDR_PARAMS, &paddrparams,
+								&optlen);
+	if (paddrparams.spp_pathmaxrxt != dflt_pathmaxrxt)
+		tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_PEER_ADDR_PARAMS) "
+			 "mismatch");
+
+	
+	tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS)");
+
+       	/* Invalid assoc id */
+	paddrparams.spp_assoc_id = 1234;
+        error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_PEER_ADDR_PARAMS,
+			   &paddrparams,
+			   sizeof(paddrparams));
+	if ((-1 != error) || (EINVAL != errno))
+		tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+			 "invalid associd error:%d, errno:%d\n",
+			 error, errno);
+
+	tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+		 "- one-to-many style invalid associd");
+
+	test_bind(udp_svr_sk, &udp_svr_loop.sa, sizeof(udp_svr_loop));
+	test_bind(udp_clt_sk, &udp_clt_loop.sa, sizeof(udp_clt_loop));
+
+	test_listen(udp_svr_sk, 5);
+
+	test_enable_assoc_change(udp_svr_sk);
+	test_enable_assoc_change(udp_clt_sk);
+
+	/* Do a connect on a UDP-style socket and establish an association. */
+	test_connect(udp_clt_sk, &udp_svr_loop.sa, sizeof(udp_svr_loop));
+
+	/* Receive the COMM_UP notifications and get the associd's */
+	inmessage.msg_controllen = sizeof(incmsg);
+	error = test_recvmsg(udp_svr_sk, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage, error,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);	
+	sac = (struct sctp_assoc_change *)iov.iov_base;
+
+	paddrparams.spp_assoc_id = sac->sac_assoc_id;
+	memcpy(&paddrparams.spp_address, &udp_clt_loop, sizeof(udp_clt_loop));
+	paddrparams.spp_hbinterval = 1000;
+	paddrparams.spp_pathmaxrxt = dflt_pathmaxrxt+1;
+	test_setsockopt(udp_svr_sk, SCTP_PEER_ADDR_PARAMS, &paddrparams,
+							sizeof(paddrparams));
+	tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) - "
+		 "one-to-many style valid associd valid address");
+
+	paddrparams.spp_assoc_id = sac->sac_assoc_id;
+	memcpy(&paddrparams.spp_address, &udp_svr_loop, sizeof(udp_svr_loop));
+	paddrparams.spp_hbinterval = 1000;
+	paddrparams.spp_pathmaxrxt = dflt_pathmaxrxt+1;
+	
+        error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_PEER_ADDR_PARAMS,
+			   &paddrparams,
+			   sizeof(paddrparams));
+	if ((-1 != error) || (EINVAL != errno))
+		tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+			 "invalid transport error:%d, errno:%d\n",
+			 error, errno);
+
+	tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+		 "- one-to-many style invalid transport");
+
+	paddrparams.spp_assoc_id = sac->sac_assoc_id;
+	memcpy(&paddrparams.spp_address, &udp_clt_loop, sizeof(udp_clt_loop));
+	paddrparams.spp_hbinterval = 1000;
+	paddrparams.spp_pathmaxrxt = dflt_pathmaxrxt+1;
+
+        error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_PEER_ADDR_PARAMS,
+			   &paddrparams,
+			   sizeof(paddrparams) - 1);
+	if ((-1 != error) || (EINVAL != errno))
+		tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+			 "invalid parameter length error:%d, errno:%d\n",
+			 error, errno);
+
+	tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+		 "- one-to-many style invalid parameter length");
+
+        error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_DELAYED_ACK_TIME,
+			   &value,
+			   sizeof(value) - 1);
+	if ((-1 != error) || (EINVAL != errno))
+		tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_DELAYED_ACK_TIME) "
+			 "invalid parameter length error:%d, errno:%d\n",
+			 error, errno);
+
+	tst_resm(TPASS, "setsockopt(SCTP_DELAYED_ACK_TIME) "
+		 "- one-to-many style invalid parameter length");
+
+	memset(&paddrparams, 0, sizeof(paddrparams));
+	paddrparams.spp_assoc_id = sac->sac_assoc_id;
+	memcpy(&paddrparams.spp_address, &udp_clt_loop, sizeof(udp_clt_loop));
+	paddrparams.spp_sackdelay = 501;
+
+        error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_PEER_ADDR_PARAMS,
+			   &paddrparams,
+			   sizeof(paddrparams));
+	if ((-1 != error) || (EINVAL != errno))
+		tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+			 "invalid sack delay error:%d, errno:%d\n",
+			 error, errno);
+
+	tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+		 "- one-to-many style invalid sack delay");
+
+	value.assoc_id    = sac->sac_assoc_id;
+	value.assoc_value = 501;
+
+        error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_DELAYED_ACK_TIME,
+			   &value,
+			   sizeof(value));
+	if ((-1 != error) || (EINVAL != errno))
+		tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_DELAYED_ACK_TIME) "
+			 "invalid sack delay error:%d, errno:%d\n",
+			 error, errno);
+
+	tst_resm(TPASS, "setsockopt(SCTP_DELAYED_ACK_TIME) "
+		 "- one-to-many style invalid sack delay");
+
+	memset(&paddrparams, 0, sizeof(paddrparams));
+	paddrparams.spp_assoc_id = sac->sac_assoc_id;
+	memcpy(&paddrparams.spp_address, &udp_clt_loop, sizeof(udp_clt_loop));
+	paddrparams.spp_pathmtu = 511;
+
+        error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_PEER_ADDR_PARAMS,
+			   &paddrparams,
+			   sizeof(paddrparams));
+	if ((-1 != error) || (EINVAL != errno))
+		tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+			 "invalid path MTU error:%d, errno:%d\n",
+			 error, errno);
+
+	tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+		 "- one-to-many style invalid path MTU");
+
+	memset(&paddrparams, 0, sizeof(paddrparams));
+	paddrparams.spp_assoc_id = sac->sac_assoc_id;
+	memcpy(&paddrparams.spp_address, &udp_clt_loop, sizeof(udp_clt_loop));
+	paddrparams.spp_flags = SPP_HB_ENABLE | SPP_HB_DISABLE;
+
+        error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_PEER_ADDR_PARAMS,
+			   &paddrparams,
+			   sizeof(paddrparams));
+	if ((-1 != error) || (EINVAL != errno))
+		tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+			 "invalid hb enable flags error:%d, errno:%d\n",
+			 error, errno);
+
+	tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+		 "- one-to-many style invalid hb enable flags");
+
+	memset(&paddrparams, 0, sizeof(paddrparams));
+	paddrparams.spp_assoc_id = sac->sac_assoc_id;
+	memcpy(&paddrparams.spp_address, &udp_clt_loop, sizeof(udp_clt_loop));
+	paddrparams.spp_flags = SPP_PMTUD_ENABLE | SPP_PMTUD_DISABLE;
+
+        error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_PEER_ADDR_PARAMS,
+			   &paddrparams,
+			   sizeof(paddrparams));
+	if ((-1 != error) || (EINVAL != errno))
+		tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+			 "invalid PMTU discovery enable flags error:%d, errno:%d\n",
+			 error, errno);
+
+	tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+		 "- one-to-many style invalid PMTU discovery enable flags");
+
+	memset(&paddrparams, 0, sizeof(paddrparams));
+	paddrparams.spp_assoc_id = sac->sac_assoc_id;
+	memcpy(&paddrparams.spp_address, &udp_clt_loop, sizeof(udp_clt_loop));
+	paddrparams.spp_flags = SPP_SACKDELAY_ENABLE | SPP_SACKDELAY_DISABLE;
+
+        error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_PEER_ADDR_PARAMS,
+			   &paddrparams,
+			   sizeof(paddrparams));
+	if ((-1 != error) || (EINVAL != errno))
+		tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+			 "invalid sack delay enable flags error:%d, errno:%d\n",
+			 error, errno);
+
+	tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+		 "- one-to-many style invalid sack delay enable flags");
+
+	memset(&paddrparams, 0, sizeof(paddrparams));
+	paddrparams.spp_flags = SPP_HB_DEMAND;
+
+        error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_PEER_ADDR_PARAMS,
+			   &paddrparams,
+			   sizeof(paddrparams));
+	if ((-1 != error) || (EINVAL != errno))
+		tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+			 "invalid hb demand error:%d, errno:%d\n",
+			 error, errno);
+
+	tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+		 "- one-to-many style invalid hb demand");
+
+	close(udp_svr_sk);
+	close(udp_clt_sk);
+
+
+	/* TEST #6: SCTP_DEFAULT_SEND_PARAM socket option. */
+	/* Create and bind 2 UDP-style sockets(udp_svr_sk, udp_clt_sk) and
+	 * 2 TCP-style sockets. (tcp_svr_sk, tcp_clt_sk)
+	 */
+	udp_svr_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+	udp_clt_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+	tcp_svr_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+	tcp_clt_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+	/* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+	test_enable_assoc_change(udp_svr_sk);
+	test_enable_assoc_change(udp_clt_sk);
+	test_enable_assoc_change(tcp_svr_sk);
+	test_enable_assoc_change(tcp_clt_sk);
+
+	test_bind(udp_svr_sk, &udp_svr_loop.sa, sizeof(udp_svr_loop));
+	test_bind(udp_clt_sk, &udp_clt_loop.sa, sizeof(udp_clt_loop));
+	test_bind(tcp_svr_sk, &tcp_svr_loop.sa, sizeof(tcp_svr_loop));
+	test_bind(tcp_clt_sk, &tcp_clt_loop.sa, sizeof(tcp_clt_loop));
+
+	/* Mark udp_svr_sk and tcp_svr_sk as being able to accept new
+	 * associations.
+	 */
+	test_listen(udp_svr_sk, 5);
+	test_listen(tcp_svr_sk, 5);
+
+	/* Set default send parameters on the unconnected UDP-style sockets. */
+	memset(&set_udp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
+	set_udp_sk_dflt_param.sinfo_ppid = 1000;
+	test_setsockopt(udp_svr_sk, SCTP_DEFAULT_SEND_PARAM,
+			&set_udp_sk_dflt_param, sizeof(set_udp_sk_dflt_param));
+	memset(&set_udp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
+	set_udp_sk_dflt_param.sinfo_ppid = 1000;
+	test_setsockopt(udp_clt_sk, SCTP_DEFAULT_SEND_PARAM,
+			&set_udp_sk_dflt_param, sizeof(set_udp_sk_dflt_param));
+
+	tst_resm(TPASS, "setsockopt(SCTP_DEFAULT_SEND_PARAM) - "
+		 "one-to-many style socket");
+
+	/* Get default send parameters on the unconnected UDP-style socket. */
+	memset(&get_udp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
+	optlen = sizeof(get_udp_sk_dflt_param);
+	test_getsockopt(udp_svr_sk, SCTP_DEFAULT_SEND_PARAM,
+			&get_udp_sk_dflt_param, &optlen);
+
+	/* Verify that the get param matches set param. */
+	if (set_udp_sk_dflt_param.sinfo_ppid !=
+			get_udp_sk_dflt_param.sinfo_ppid)
+		tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) "
+			 "mismatch.");
+
+	/* Get default send parameters on the unconnected UDP-style socket. */
+	memset(&get_udp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
+	optlen = sizeof(get_udp_sk_dflt_param);
+	test_getsockopt(udp_clt_sk, SCTP_DEFAULT_SEND_PARAM,
+		       &get_udp_sk_dflt_param, &optlen);
+
+	/* Verify that the get param matches set param. */
+	if (set_udp_sk_dflt_param.sinfo_ppid !=
+			get_udp_sk_dflt_param.sinfo_ppid)
+		tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) "
+			 "mismatch.");
+
+	tst_resm(TPASS, "getsockopt(SCTP_DEFAULT_SEND_PARAM) - "
+		 "one-to-many style socket");
+
+	/* Verify that trying to set send params with an invalid assoc id
+	 * on an UDP-style socket fails.
+	 */
+	memset(&set_udp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
+	set_udp_sk_dflt_param.sinfo_ppid = 1000;
+       	/* Invalid assoc id */
+	set_udp_sk_dflt_param.sinfo_assoc_id = 1234;
+        error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_DEFAULT_SEND_PARAM,
+			   &set_udp_sk_dflt_param,
+			   sizeof(set_udp_sk_dflt_param));
+	if ((-1 != error) || (EINVAL != errno))
+		tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_DEFAULT_SEND_PARAM) "
+			 "invalid associd error:%d, errno:%d\n",
+			 error, errno);
+
+	tst_resm(TPASS, "setsockopt(SCTP_DEFAULT_SEND_PARAM) "
+		 "- one-to-many style invalid associd");
+
+	/* Do a connect on a UDP-style socket and establish an association. */
+	test_connect(udp_clt_sk, &udp_svr_loop.sa, sizeof(udp_svr_loop));
+
+	/* Receive the COMM_UP notifications and get the associd's */
+	inmessage.msg_controllen = sizeof(incmsg);
+	error = test_recvmsg(udp_svr_sk, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage, error,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);	
+	sac = (struct sctp_assoc_change *)iov.iov_base;
+	udp_svr_associd = sac->sac_assoc_id;
+
+	inmessage.msg_controllen = sizeof(incmsg);
+	error = test_recvmsg(udp_clt_sk, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage, error,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);	
+	sac = (struct sctp_assoc_change *)iov.iov_base;
+	udp_clt_associd = sac->sac_assoc_id;
+
+	/* Verify that trying to set send params with an assoc id not 
+	 * belonging to the socket on an UDP-style socket fails.
+	 */
+	memset(&set_udp_assoc_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
+	set_udp_assoc_dflt_param.sinfo_ppid = 3000;
+	set_udp_assoc_dflt_param.sinfo_assoc_id = udp_clt_associd;
+	error = setsockopt(udp_svr_sk, SOL_SCTP, SCTP_DEFAULT_SEND_PARAM,
+			   &set_udp_assoc_dflt_param,
+			   sizeof(set_udp_assoc_dflt_param));
+	if ((-1 != error) || (EINVAL != errno))
+		tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_DEFAULT_SEND_PARAM) "
+			 "associd belonging to another socket "
+			 "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "setsockopt(SCTP_DEFAULT_SEND_PARAM) - "
+		 "one-to-many style associd belonging to another socket");
+
+	/* Set default send parameters of an association on the listening 
+	 * UDP-style socket with a valid associd.
+	 */ 
+	memset(&set_udp_assoc_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
+	set_udp_assoc_dflt_param.sinfo_ppid = 3000;
+	set_udp_assoc_dflt_param.sinfo_assoc_id = udp_svr_associd;
+	test_setsockopt(udp_svr_sk, SCTP_DEFAULT_SEND_PARAM,
+			&set_udp_assoc_dflt_param,
+			sizeof(set_udp_assoc_dflt_param));
+
+	tst_resm(TPASS, "setsockopt(SCTP_DEFAULT_SEND_PARAM) - "
+		 "one-to-many style valid associd");
+
+	/* Get default send parameters of an association on the listening 
+	 * UDP-style socket with a valid associd.
+	 */ 
+	memset(&get_udp_assoc_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
+	get_udp_assoc_dflt_param.sinfo_assoc_id = udp_svr_associd ;
+	optlen = sizeof(get_udp_assoc_dflt_param);
+	test_getsockopt(udp_svr_sk, SCTP_DEFAULT_SEND_PARAM,
+			&get_udp_assoc_dflt_param, &optlen);
+
+	/* Verify that the get param matches the set param. */
+	if (get_udp_assoc_dflt_param.sinfo_ppid !=
+			set_udp_assoc_dflt_param.sinfo_ppid)
+		tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) "
+			 "mismatch.");
+
+	tst_resm(TPASS, "getsockopt(SCTP_DEFAULT_SEND_PARAM) - "
+		 "one-to-many style valid associd");
+
+	/* Get default send parameters of an association on the connected 
+	 * UDP-style socket with zero associd. This should return the
+	 * socket wide default parameters.
+	 */ 
+	memset(&get_udp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
+	get_udp_sk_dflt_param.sinfo_assoc_id = 0 ;
+	optlen = sizeof(get_udp_sk_dflt_param);
+	test_getsockopt(udp_clt_sk, SCTP_DEFAULT_SEND_PARAM,
+			&get_udp_sk_dflt_param, &optlen);
+
+	/* Verify that the get param matches the socket-wide set param. */
+	if (get_udp_sk_dflt_param.sinfo_ppid !=
+			set_udp_sk_dflt_param.sinfo_ppid)
+		tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) "
+			 "mismatch.");
+
+	tst_resm(TPASS, "getsockopt(SCTP_DEFAULT_SEND_PARAM) - "
+		 "one-to-many style zero associd");
+
+	peeloff_sk = test_sctp_peeloff(udp_svr_sk, udp_svr_associd); 
+
+	/* Get default send parameters of an association on the peeled off 
+	 * UDP-style socket. This should return the association's default
+	 * parameters.
+	 */ 
+	memset(&get_peeloff_assoc_dflt_param, 0,
+	       sizeof(struct sctp_sndrcvinfo));
+	get_peeloff_assoc_dflt_param.sinfo_assoc_id = 0 ;
+	optlen = sizeof(get_peeloff_assoc_dflt_param);
+	test_getsockopt(peeloff_sk, SCTP_DEFAULT_SEND_PARAM,
+			&get_peeloff_assoc_dflt_param, &optlen);
+
+	/* Verify that the get param matches the association's set param. */
+	if (get_peeloff_assoc_dflt_param.sinfo_ppid !=
+			set_udp_assoc_dflt_param.sinfo_ppid)
+		tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) "
+			 "mismatch.");
+
+	tst_resm(TPASS, "getsockopt(SCTP_DEFAULT_SEND_PARAM) - "
+		 "one-to-many style peeled off socket");
+
+	/* Set default send parameters on the unconnected TCP-style sockets. */
+	memset(&set_tcp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
+	set_tcp_sk_dflt_param.sinfo_ppid = 2000;
+	/* Invalid assoc id, ignored on a TCP-style socket. */
+	set_tcp_sk_dflt_param.sinfo_assoc_id = 1234;
+	test_setsockopt(tcp_svr_sk, SCTP_DEFAULT_SEND_PARAM,
+			&set_tcp_sk_dflt_param,
+			sizeof(set_tcp_sk_dflt_param));
+
+	/* Set default send parameters on the unconnected TCP-style sockets. */
+	memset(&set_tcp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
+	set_tcp_sk_dflt_param.sinfo_ppid = 2000;
+	/* Invalid assoc id, ignored on a TCP-style socket. */
+	set_tcp_sk_dflt_param.sinfo_assoc_id = 1234;
+	test_setsockopt(tcp_clt_sk, SCTP_DEFAULT_SEND_PARAM,
+			&set_tcp_sk_dflt_param,
+			sizeof(set_tcp_sk_dflt_param));
+
+	tst_resm(TPASS, "setsockopt(SCTP_DEFAULT_SEND_PARAM) - "
+		 "one-to-one style socket");
+
+	/* Get default send parameters on the unconnected TCP-style socket. */
+	memset(&get_tcp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
+	optlen = sizeof(get_tcp_sk_dflt_param);
+	test_getsockopt(tcp_svr_sk, SCTP_DEFAULT_SEND_PARAM,
+			&get_tcp_sk_dflt_param, &optlen);
+
+	/* Verify that the get param matches set param. */
+	if (set_tcp_sk_dflt_param.sinfo_ppid !=
+			get_tcp_sk_dflt_param.sinfo_ppid)
+		tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) "
+			 "mismatch.");
+
+	/* Get default send parameters on the unconnected TCP-style socket. */
+	memset(&get_tcp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
+	optlen = sizeof(get_tcp_sk_dflt_param);
+	test_getsockopt(tcp_clt_sk, SCTP_DEFAULT_SEND_PARAM,
+			&get_tcp_sk_dflt_param, &optlen);
+
+	/* Verify that the get param matches set param. */
+	if (set_tcp_sk_dflt_param.sinfo_ppid !=
+			get_tcp_sk_dflt_param.sinfo_ppid)
+		tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) "
+			 "mismatch.");
+
+	tst_resm(TPASS, "getsockopt(SCTP_DEFAULT_SEND_PARAM) - "
+		 "one-to-one style socket");
+
+	/* Do a connect on a TCP-style socket and establish an association. */
+	test_connect(tcp_clt_sk, &tcp_svr_loop.sa, sizeof(tcp_svr_loop));
+
+	/* Set default send parameters of an association on the connected 
+	 * TCP-style socket.
+	 */ 
+	memset(&set_tcp_assoc_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
+	set_tcp_assoc_dflt_param.sinfo_ppid = 4000;
+	set_tcp_assoc_dflt_param.sinfo_assoc_id = 0;
+	test_setsockopt(tcp_clt_sk, SCTP_DEFAULT_SEND_PARAM,
+			&set_tcp_assoc_dflt_param,
+			sizeof(set_tcp_assoc_dflt_param));
+
+	tst_resm(TPASS, "setsockopt(SCTP_DEFAULT_SEND_PARAM) - "
+		 "one-to-one style assoc");
+
+	/* Get default send parameters of an association on the connected 
+	 * TCP-style socket.
+	 */ 
+	memset(&get_tcp_assoc_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
+	optlen = sizeof(get_tcp_assoc_dflt_param);
+	test_getsockopt(tcp_clt_sk, SCTP_DEFAULT_SEND_PARAM,
+			&get_tcp_assoc_dflt_param, &optlen);
+
+	if (set_tcp_assoc_dflt_param.sinfo_ppid !=
+			get_tcp_assoc_dflt_param.sinfo_ppid)
+		tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) "
+			 "mismatch.");
+
+	/* Get default send parameters on the connected TCP-style socket.  */ 
+	memset(&get_tcp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
+	optlen = sizeof(get_tcp_sk_dflt_param);
+	test_getsockopt(tcp_clt_sk, SCTP_DEFAULT_SEND_PARAM,
+			&get_tcp_sk_dflt_param, &optlen);
+
+	/* Verify that the get parameters returned matches the set param
+	 * set for the association, not the socket-wide param.
+	 */ 
+	if ((get_tcp_sk_dflt_param.sinfo_ppid ==
+			set_tcp_sk_dflt_param.sinfo_ppid) ||
+	    (get_tcp_sk_dflt_param.sinfo_ppid !=
+	    		set_tcp_assoc_dflt_param.sinfo_ppid))
+		tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) "
+			 "mismatch.");
+
+	/* Get default send parameters on the listening TCP-style socket.  */ 
+	memset(&get_tcp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
+	optlen = sizeof(get_tcp_sk_dflt_param);
+	test_getsockopt(tcp_svr_sk, SCTP_DEFAULT_SEND_PARAM,
+			&get_tcp_sk_dflt_param, &optlen);
+
+	/* Verify that the get parameters returned matches the socket-wide 
+	 * set param.
+	 */
+	if (get_tcp_sk_dflt_param.sinfo_ppid !=
+			set_tcp_sk_dflt_param.sinfo_ppid)
+		tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) "
+			 "mismatch.");
+
+	tst_resm(TPASS, "getsockopt(SCTP_DEFAULT_SEND_PARAM) - "
+		 "one-to-one style assoc");
+
+	accept_sk = test_accept(tcp_svr_sk, NULL, &addrlen); 
+
+	/* Get default send parameters of an association on the accepted 
+	 * TCP-style socket.
+	 */ 
+	memset(&get_accept_assoc_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
+	optlen = sizeof(get_accept_assoc_dflt_param);
+	test_getsockopt(accept_sk, SCTP_DEFAULT_SEND_PARAM,
+			&get_accept_assoc_dflt_param, &optlen);
+
+	error = 0;
+
+	/* Verify that the get parameters returned matches the socket-wide 
+	 * set param.
+	 */
+	if (get_tcp_sk_dflt_param.sinfo_ppid !=
+			set_tcp_sk_dflt_param.sinfo_ppid)
+		tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) "
+			 "mismatch.");
+
+	tst_resm(TPASS, "getsockopt(SCTP_DEFAULT_SEND_PARAM) - "
+		 "one-to-one style accepted socket");
+
+	/* TEST #7: SCTP_GET_PEER_ADDR_INFO socket option. */
+	/* Try 0 associd and 0 addr */
+	memset(&pinfo, 0, sizeof(pinfo));
+	optlen = sizeof(pinfo);
+	error = getsockopt(udp_clt_sk, SOL_SCTP, SCTP_GET_PEER_ADDR_INFO,
+			   &pinfo, &optlen);			   
+	if ((-1 != error) || (EINVAL != errno))
+		tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_GET_PEER_ADDR_INFO) "
+			 "null associd, null addr error:%d, errno:%d\n",
+			error, errno);
+
+	tst_resm(TPASS, "getsockopt(SCTP_GET_PEER_ADDR_INFO) - "
+		 "null associd and null addr");
+
+	/* Try valid associd, but 0 addr */
+	memset(&pinfo, 0, sizeof(pinfo));
+	optlen = sizeof(pinfo);
+	pinfo.spinfo_assoc_id = udp_clt_associd;
+	error = getsockopt(udp_clt_sk, SOL_SCTP, SCTP_GET_PEER_ADDR_INFO,
+			   &pinfo, &optlen);			   
+	if ((-1 != error) || (EINVAL != errno))
+		tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_GET_PEER_ADDR_INFO) "
+			 "valid associd, null addr error:%d, errno:%d\n",
+			error, errno);
+
+	tst_resm(TPASS, "getsockopt(SCTP_GET_PEER_ADDR_INFO) - "
+		 "valid associd and null addr");
+
+	/* Try valid associd, invalid addr */
+	memset(&pinfo, 0, sizeof(pinfo));
+	optlen = sizeof(pinfo);
+	pinfo.spinfo_assoc_id = udp_clt_associd;
+	memcpy(&pinfo.spinfo_address, &udp_clt_loop, sizeof(udp_clt_loop));
+	error = getsockopt(udp_clt_sk, SOL_SCTP, SCTP_GET_PEER_ADDR_INFO,
+			   &pinfo, &optlen);			   
+	if ((-1 != error) || (EINVAL != errno))
+		tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_GET_PEER_ADDR_INFO) "
+			 "valid associd, invalid addr error:%d, errno:%d\n",
+			error, errno);
+
+	tst_resm(TPASS, "getsockopt(SCTP_GET_PEER_ADDR_INFO) - "
+		 "valid associd and invalid addr");
+
+	/* Try valid associd, valid addr */
+	memset(&pinfo, 0, sizeof(pinfo));
+	optlen = sizeof(pinfo);
+	pinfo.spinfo_assoc_id = udp_clt_associd;
+	memcpy(&pinfo.spinfo_address, &udp_svr_loop, sizeof(udp_svr_loop));
+	test_getsockopt(udp_clt_sk, SCTP_GET_PEER_ADDR_INFO, &pinfo, &optlen);			   
+
+	tst_resm(TPASS, "getsockopt(SCTP_GET_PEER_ADDR_INFO) - "
+		 "valid associd and valid addr");
+
+	/* Try valid addr, peeled off socket */
+	memset(&pinfo, 0, sizeof(pinfo));
+	optlen = sizeof(pinfo);
+	pinfo.spinfo_assoc_id = 0;
+	memcpy(&pinfo.spinfo_address, &udp_clt_loop, sizeof(udp_clt_loop));
+	test_getsockopt(peeloff_sk, SCTP_GET_PEER_ADDR_INFO, &pinfo, &optlen);			   
+
+	tst_resm(TPASS, "getsockopt(SCTP_GET_PEER_ADDR_INFO) - "
+		 "valid associd and valid addr peeled off socket");
+
+	/* Try valid addr, TCP-style accept socket */
+	memset(&pinfo, 0, sizeof(pinfo));
+	optlen = sizeof(pinfo);
+	pinfo.spinfo_assoc_id = 0;
+	memcpy(&pinfo.spinfo_address, &tcp_clt_loop, sizeof(tcp_clt_loop));
+	error = test_getsockopt(accept_sk, SCTP_GET_PEER_ADDR_INFO, &pinfo,
+				&optlen);			   
+
+	tst_resm(TPASS, "getsockopt(SCTP_GET_PEER_ADDR_INFO) - "
+		 "valid associd and valid addr accepted socket");
+
+	close(udp_svr_sk);
+	close(udp_clt_sk);
+	close(tcp_svr_sk);
+	close(tcp_clt_sk);
+	close(accept_sk);
+	close(peeloff_sk);
+
+        /* Indicate successful completion.  */
+        return 0;
+}
diff --git a/src/func_tests/test_tcp_style.c b/src/func_tests/test_tcp_style.c
new file mode 100644
index 0000000..f4f835a
--- /dev/null
+++ b/src/func_tests/test_tcp_style.c
@@ -0,0 +1,463 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2003
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ *
+ * This file is part of the SCTP kernel Implementation
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ *    Sridhar Samudrala		<sri@us.ibm.com>
+ */
+
+/* This is a kernel test to verify the TCP-style socket interfaces. */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <sys/poll.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 22;
+int TST_CNT = 0;
+
+#define MAX_CLIENTS 10
+
+int
+main(int argc, char *argv[])
+{
+	int clt_sk[MAX_CLIENTS], accept_sk[MAX_CLIENTS];
+	int listen_sk, clt2_sk, accept2_sk;
+	sockaddr_storage_t clt_loop[MAX_CLIENTS];
+	sockaddr_storage_t svr_loop, accept_loop, clt2_loop;
+	socklen_t addrlen;
+	int error, i;
+        char *message = "hello, world!\n";
+	char msgbuf[100];
+	int pf_class;
+	struct pollfd poll_fd;
+	fd_set set;
+	struct msghdr outmessage;
+	char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+	struct iovec out_iov;
+	struct cmsghdr *cmsg;
+	struct sctp_sndrcvinfo *sinfo;
+	struct msghdr inmessage;
+	char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+	char *big_buffer;
+	struct iovec iov;
+
+        /* Rather than fflush() throughout the code, set stdout to 
+	 * be unbuffered.  
+	 */ 
+	setvbuf(stdout, NULL, _IONBF, 0); 
+
+	/* Initialize the server and client addresses. */ 
+#if TEST_V6
+	pf_class = PF_INET6;
+        svr_loop.v6.sin6_family = AF_INET6;
+        svr_loop.v6.sin6_addr = in6addr_loopback;
+        svr_loop.v6.sin6_port = htons(SCTP_TESTPORT_1);
+	for (i = 0; i < MAX_CLIENTS; i++) {
+        	clt_loop[i].v6.sin6_family = AF_INET6;
+        	clt_loop[i].v6.sin6_addr = in6addr_loopback;
+        	clt_loop[i].v6.sin6_port = htons(SCTP_TESTPORT_2 + i);
+	}
+        clt2_loop.v6.sin6_family = AF_INET6;
+        clt2_loop.v6.sin6_addr = in6addr_loopback;
+        clt2_loop.v6.sin6_port = htons(SCTP_TESTPORT_2 + i);
+#else
+	pf_class = PF_INET;
+	svr_loop.v4.sin_family = AF_INET;
+	svr_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+	svr_loop.v4.sin_port = htons(SCTP_TESTPORT_1);
+	for (i = 0; i < MAX_CLIENTS; i++) {
+		clt_loop[i].v4.sin_family = AF_INET;
+		clt_loop[i].v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+		clt_loop[i].v4.sin_port = htons(SCTP_TESTPORT_2 + i);
+	}
+	clt2_loop.v4.sin_family = AF_INET;
+	clt2_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+	clt2_loop.v4.sin_port = htons(SCTP_TESTPORT_2 + i);
+#endif
+
+	/* Create and bind the listening server socket.  */
+        listen_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+	test_bind(listen_sk, &svr_loop.sa, sizeof(svr_loop));
+
+	/* Mark listen_sk as being able to accept new associations.  */
+	test_listen(listen_sk, MAX_CLIENTS-1);
+
+	/* Create and bind the client sockets.  */
+	for (i = 0; i < MAX_CLIENTS; i++) {
+		clt_sk[i] = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+		test_bind(clt_sk[i], &clt_loop[i].sa, sizeof(clt_loop[i]));
+	}
+	clt2_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+	test_bind(clt2_sk, &clt2_loop.sa, sizeof(clt2_loop));
+
+	addrlen = sizeof(accept_loop);
+	/* Try to do accept on a non-listening socket. It should fail. */
+	error = accept(clt_sk[0], &accept_loop.sa, &addrlen);
+	if ((-1 != error) && (EINVAL != errno))
+		tst_brkm(TBROK, tst_exit, "accept on non-listening socket "
+			 "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "accept on non-listening socket");
+
+	/* Try to do a connect from a listening socket. It should fail. */
+	error = connect(listen_sk, (struct sockaddr *)&clt_loop[0],
+			sizeof(clt_loop[0]));
+	if ((-1 != error) && (EISCONN != errno))
+		tst_brkm(TBROK, tst_exit, "connect to non-listening socket "
+			 "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "connect to non-listening socket");
+
+	/* Do a blocking connect from clt_sk's to listen_sk */      
+	for (i = 0; i < MAX_CLIENTS; i++)
+		test_connect(clt_sk[i], &svr_loop.sa, sizeof(svr_loop));
+
+	tst_resm(TPASS, "connect to listening socket");
+
+	/* Verify that no more connect's can be done after the acceptq
+	 * backlog has reached the max value.
+	 */
+	error = connect(clt2_sk, &svr_loop.sa, sizeof(svr_loop));
+	if ((-1 != error) && (ECONNREFUSED != errno))
+		tst_brkm(TBROK, tst_exit, "connect after max backlog "
+			 "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "connect after max backlog");
+
+	/* Extract the associations on the listening socket as new sockets. */
+	for (i = 0; i < MAX_CLIENTS; i++) {
+		poll_fd.fd = listen_sk;
+		poll_fd.events = POLLIN;
+		poll_fd.revents = 0;
+		error = poll(&poll_fd, 1, -1);
+		if ((1 != error) && (1 != poll_fd.revents))
+			tst_brkm(TBROK, tst_exit, "Unexpected return value "
+				 "with poll, error:%d errno:%d, revents:%d",
+				 error, errno, poll_fd.revents);
+
+		addrlen = sizeof(accept_loop);
+		accept_sk[i] = test_accept(listen_sk, &accept_loop.sa,
+					   &addrlen); 
+	}
+
+	tst_resm(TPASS, "accept from listening socket");
+
+	/* Try to do a connect on an established socket. It should fail. */
+	error = connect(accept_sk[0], &clt_loop[0].sa, sizeof(clt_loop[0]));
+	if ((-1 != error) || (EISCONN != errno))
+		tst_brkm(TBROK, tst_exit, "connect on an established socket "
+			 "error:%d errno:%d", error, errno);
+
+	tst_resm(TPASS, "connect on an established socket");
+
+	/* Try to do accept on an established socket. It should fail. */
+	error = accept(accept_sk[0], &accept_loop.sa, &addrlen);
+	if ((-1 != error) && (EINVAL != errno))
+		tst_brkm(TBROK, tst_exit, "accept on an established socket "
+			 "error:%d errno:%d", error, errno);
+
+	error = accept(clt_sk[0], &accept_loop.sa, &addrlen);
+	if ((-1 != error) && (EINVAL != errno))
+		tst_brkm(TBROK, tst_exit, "accept on an established socket "
+			 "failure: error:%d errno:%d", error, errno);
+
+	tst_resm(TPASS, "accept on an established socket");
+
+	/* Send and receive a message from the client sockets to the accepted
+	 * sockets.
+	 */
+	for (i = 0; i < MAX_CLIENTS; i++) {
+		test_send(clt_sk[i], message, strlen(message), 0);
+		test_recv(accept_sk[i], msgbuf, 100, 0);
+	}
+
+	tst_resm(TPASS, "client sockets -> accepted sockets");
+
+	/* Send and receive a message from the accepted sockets to the client
+	 * sockets.
+	 */
+	for (i = 0; i < MAX_CLIENTS; i++) {
+		test_send(accept_sk[i], message, strlen(message), 0);
+		test_recv(clt_sk[i], msgbuf, 100, 0);
+	}
+
+	tst_resm(TPASS, "accepted sockets -> client sockets");
+
+	/* Sending a message on a listening socket should fail. */
+	error = send(listen_sk, message, strlen(message), MSG_NOSIGNAL);
+	if ((-1 != error) || (EPIPE != errno))
+		tst_brkm(TBROK, tst_exit, "send on a listening socket "
+			 "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "send on a listening socket");
+
+	/* Trying to receive a message on a listening socket should fail. */
+	error = recv(listen_sk, msgbuf, 100, 0);
+	if ((-1 != error) || (ENOTCONN != errno))
+		tst_brkm(TBROK, tst_exit, "recv on a listening socket "
+			 "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "recv on a listening socket");
+
+	/* TESTCASES for shutdown() */
+	errno = 0;
+	test_send(accept_sk[0], message, strlen(message), 0);
+
+	/* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+	test_enable_assoc_change(clt_sk[0]);
+
+	/* Do a SHUT_WR on clt_sk[0] to disable any new sends. */
+	test_shutdown(clt_sk[0], SHUT_WR);
+
+	/* Reading on a socket that has received SHUTDOWN should return 0 
+	 * indicating EOF.
+	 */
+	error = recv(accept_sk[0], msgbuf, 100, 0);
+	if ((0 != error) || (0 != errno))
+		tst_brkm(TBROK, tst_exit, "recv on a SHUTDOWN received socket "
+			 "error:%d errno:%d", error, errno);
+
+	tst_resm(TPASS, "recv on a SHUTDOWN received socket");
+
+	/* Read the pending message on clt_sk[0] that was received before
+	 * SHUTDOWN call.
+	 */  
+	test_recv(clt_sk[0], msgbuf, 100, 0);
+
+	/* Initialize inmessage for all receives. */
+	big_buffer = test_malloc(REALLY_BIG);
+	memset(&inmessage, 0, sizeof(inmessage));	
+	iov.iov_base = big_buffer;
+	iov.iov_len = REALLY_BIG;
+	inmessage.msg_iov = &iov;
+	inmessage.msg_iovlen = 1;
+	inmessage.msg_control = incmsg;
+	inmessage.msg_controllen = sizeof(incmsg);
+
+	/* Receive the SHUTDOWN_COMP notification as they are enabled. */
+	error = test_recvmsg(clt_sk[0], &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage, error,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_SHUTDOWN_COMP);
+
+	tst_resm(TPASS, "recv SHUTDOWN_COMP notification on a SHUT_WR socket");
+
+	/* No more messages and the association is SHUTDOWN, should fail. */
+	error = recv(clt_sk[0], msgbuf, 100, 0);
+	if ((-1 != error) || (ENOTCONN != errno))
+		tst_brkm(TBROK, tst_exit, "recv on a SHUTDOWN sent socket "
+			 "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "recv on a SHUTDOWN sent socket");
+
+	errno = 0;
+
+	/* Do a SHUT_RD on clt_sk[1] to disable any new receives. */
+	test_shutdown(clt_sk[1], SHUT_RD);
+
+	error = recv(clt_sk[1], msgbuf, 100, 0);
+	if ((0 != error) || (0 != errno))
+		tst_brkm(TBROK, tst_exit, "recv on a SHUT_RD socket "
+			 "error:%d, errno:%d", error, errno);
+
+	/* Sending a message on SHUT_RD socket. */
+	test_send(clt_sk[1], message, strlen(message), 0);
+
+	/* Receive the message sent on SHUT_RD socket. */
+	test_recv(accept_sk[1], msgbuf, 100, 0);
+
+	/* Send a message to the SHUT_RD socket. */
+	test_send(accept_sk[1], message, strlen(message), 0);
+
+	/* We should not receive the message as the socket is SHUT_RD */ 
+	error = recv(clt_sk[1], msgbuf, 100, 0);
+	if ((0 != error) || (0 != errno))
+		tst_brkm(TBROK, tst_exit, "recv on a SHUT_RD socket "
+			 "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "recv on a SHUT_RD socket");
+
+	/* Do a SHUT_RDWR on clt_sk[2] to disable any new sends/receives. */
+	test_shutdown(clt_sk[2], SHUT_RDWR);
+
+	error = recv(accept_sk[2], msgbuf, 100, 0);
+	if ((0 != error) || (0 != errno))
+		tst_brkm(TBROK, tst_exit, "recv on a SHUT_RDWR socket "
+			 "error:%d, errno:%d", error, errno);
+
+	error = recv(clt_sk[2], msgbuf, 100, 0);
+	if ((0 != error) || (0 != errno))
+		tst_brkm(TBROK, tst_exit, "recv on a SHUT_RDWR socket "
+			 "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "recv on a SHUT_RDWR socket");
+
+	error = 0;
+
+	for (i = 0; i < MAX_CLIENTS; i++)
+		close(clt_sk[i]);
+	for (i = 0; i < MAX_CLIENTS; i++)
+		close(accept_sk[i]);
+
+	/* Test case to verify accept of a CLOSED association. */
+	/* Do a connect, send and a close to ESTABLISH and CLOSE an
+	 * association on the listening socket.
+	 */
+	test_connect(clt2_sk, &svr_loop.sa, sizeof(svr_loop));
+
+	test_send(clt2_sk, message, strlen(message), 0);
+
+	close(clt2_sk);
+
+	FD_ZERO(&set);
+	FD_SET(listen_sk, &set);
+
+	error = select(listen_sk + 1, &set, NULL, NULL, NULL);
+	if (1 != error)
+		tst_brkm(TBROK, tst_exit, "select error:%d, "
+			 "errno: %d", error, errno);
+
+	/* Now accept the CLOSED association waiting on the listening 
+	 * socket.
+	 */  
+	accept2_sk = test_accept(listen_sk, &accept_loop.sa, &addrlen); 
+
+	/* Receive the message sent before doing a close. */
+	test_recv(accept2_sk, msgbuf, 100, 0);
+
+	/* Receive EOF indication as there are no more messages and the
+	 * socket is SHUTDOWN.
+	 */
+	error = recv(accept2_sk, msgbuf, 100, 0);
+	if ((0 != error) || (0 != errno))
+		tst_brkm(TBROK, tst_exit, "Unexpected error return on "
+			 "recv(error:%d, errno:%d)", error, errno);
+
+	tst_resm(TPASS, "accept of a CLOSED association");
+
+	/* Trying to send a message over the CLOSED association should
+	 * generate EPIPE.
+	 */
+	error = send(accept2_sk, message, strlen(message), MSG_NOSIGNAL);
+	if ((-1 != error) || (EPIPE != errno))
+		tst_brkm(TBROK, tst_exit, "send to a CLOSED association "
+			 "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "send to a CLOSED association");
+
+	error = 0;
+	close(accept2_sk);
+
+	/* Verify that auto-connect can be done on a TCP-style socket using
+	 * sendto/sendmsg.
+	 */
+	clt2_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+	test_bind(clt2_sk, &clt2_loop.sa, sizeof(clt2_loop));
+
+	/* Do a sendto() without a connect() */
+	test_sendto(clt2_sk, message, strlen(message), 0, &svr_loop.sa,
+		    sizeof(svr_loop));
+
+	accept2_sk = test_accept(listen_sk, &accept_loop.sa, &addrlen); 
+
+	test_recv(accept2_sk, msgbuf, 100, 0);
+
+	tst_resm(TPASS, "auto-connect using sendto");
+
+	outmessage.msg_name = &svr_loop;
+	outmessage.msg_namelen = sizeof(svr_loop);
+	outmessage.msg_iov = NULL;
+	outmessage.msg_iovlen = 0;
+	outmessage.msg_control = outcmsg;
+	outmessage.msg_controllen = sizeof(outcmsg);
+	outmessage.msg_flags = 0;
+
+	cmsg = CMSG_FIRSTHDR(&outmessage);
+	cmsg->cmsg_level = IPPROTO_SCTP;
+	cmsg->cmsg_type = SCTP_SNDRCV;
+	cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+	outmessage.msg_controllen = cmsg->cmsg_len;
+	sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+	memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+
+	/* Verify that SCTP_EOF cannot be used to shutdown an association
+	 * on a TCP-style socket.
+	 */
+	sinfo->sinfo_flags |= SCTP_EOF;
+	error = sendmsg(clt2_sk, &outmessage, 0);
+	if ((-1 != error) || (EINVAL != errno))
+		tst_brkm(TBROK, tst_exit, "sendmsg with SCTP_EOF flag "
+			 "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "sendmsg with SCTP_EOF flag");
+
+	/* Verify that SCTP_ABORT cannot be used to abort an association
+	 * on a TCP-style socket.
+	 */
+	sinfo->sinfo_flags |= SCTP_ABORT;
+	error = sendmsg(clt2_sk, &outmessage, 0);
+	if ((-1 != error) || (EINVAL != errno))
+		tst_brkm(TBROK, tst_exit, "sendmsg with SCTP_ABORT flag "
+			 "error:%d, errno:%d", error, errno);
+
+	tst_resm(TPASS, "sendmsg with SCTP_ABORT flag");
+
+	/* Verify that a normal message can be sent using sendmsg. */
+	outmessage.msg_iov = &out_iov;
+	outmessage.msg_iovlen = 1;
+	out_iov.iov_base = message;
+	out_iov.iov_len = strlen(message) + 1;
+	sinfo->sinfo_flags = 0;
+	test_sendmsg(clt2_sk, &outmessage, 0, strlen(message)+1);
+
+	test_recv(accept2_sk, msgbuf, 100, 0);
+	
+	tst_resm(TPASS, "sendmsg with no flags");
+
+	close(clt2_sk);
+	close(accept2_sk);
+	close(listen_sk);
+
+        /* Indicate successful completion.  */
+	return 0;
+}
diff --git a/src/func_tests/test_timetolive.c b/src/func_tests/test_timetolive.c
new file mode 100644
index 0000000..58d76f0
--- /dev/null
+++ b/src/func_tests/test_timetolive.c
@@ -0,0 +1,395 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2001, 2003
+ * Copyright (c) 1999-2000 Cisco, Inc.
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ * Copyright (c) 2001 Intel Corp.
+ * Copyright (c) 2001 Nokia, Inc.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ *    Jon Grimm		 <jgrimm@us.ibm.com>
+ *    Sridhar Samudrala  <sri@us.ibm.com>
+ */
+
+/*
+ * This is a basic functional test for the SCTP kernel 
+ * implementation of sndrcvinfo.sinfo_timetolive.
+ *
+ * 1) Create two sockets, the listening socket sets its RECVBUF small
+ * 2) Create a connection.  Send enough data to the non-reading listener
+ * to fill the RCVBUF.
+ * 5) Set sinfo_timetolive on a message and send.
+ * 6) Disable sinfo_timetolive on a message and send.
+ * 7) Wait sinfo_timetolive.
+ * 8) Read out all the data at the receiver.
+ * 9) Make sure timed out message did not make it.
+ * 10) Make sure that the message with no timeout makes it to the receiver.
+ *
+ * Also test with SEND_FAILED notifications.  Also, use a fragmented
+ * message so as to also exercise the SEND_FAILED of fragmentation
+ * code.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 6;
+int TST_CNT = 0;
+
+/* This is the size of our RCVBUF */
+#define SMALL_RCVBUF 3000
+
+/* MAX segment size */
+#define SMALL_MAXSEG 500
+
+/* RWND_SLOP is the extra data that fills up the rwnd */
+#define RWND_SLOP 100
+static char *fillmsg = NULL;
+static char *ttlmsg = "This should time out!\n";
+static char *nottlmsg = "This should NOT time out!\n";
+static char ttlfrag[SMALL_MAXSEG*3] = {0};
+static char *message = "Hello world\n";
+
+int main(int argc, char *argv[])
+{
+        int sk1, sk2;
+        sockaddr_storage_t loop1;
+        sockaddr_storage_t loop2;
+        struct iovec iov;
+        struct msghdr inmessage;
+	struct msghdr outmessage;
+	char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+	char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+	struct cmsghdr *cmsg;
+	struct sctp_sndrcvinfo *sinfo;
+        struct iovec out_iov;
+        int error;
+	int pf_class;
+	uint32_t ppid;
+	uint32_t stream;
+	sctp_assoc_t associd1;
+	struct sctp_assoc_change *sac;
+	struct sctp_event_subscribe subscribe;
+	char *big_buffer;
+	int offset;
+	struct sctp_send_failed *ssf;
+	socklen_t len; /* Really becomes 2xlen when set. */
+	int orig_len; 
+	struct sctp_status gstatus;
+
+        /* Rather than fflush() throughout the code, set stdout to
+	 * be unbuffered.
+	 */
+	setvbuf(stdout, NULL, _IONBF, 0);
+
+	/* Set some basic values which depend on the address family. */
+#if TEST_V6
+	pf_class = PF_INET6;
+
+        loop1.v6.sin6_family = AF_INET6;
+        loop1.v6.sin6_addr = in6addr_loopback;
+        loop1.v6.sin6_port = htons(SCTP_TESTPORT_1);
+
+        loop2.v6.sin6_family = AF_INET6;
+        loop2.v6.sin6_addr = in6addr_loopback;
+        loop2.v6.sin6_port = htons(SCTP_TESTPORT_2);
+#else
+	pf_class = PF_INET;
+
+        loop1.v4.sin_family = AF_INET;
+        loop1.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+        loop1.v4.sin_port = htons(SCTP_TESTPORT_1);
+
+        loop2.v4.sin_family = AF_INET;
+        loop2.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+        loop2.v4.sin_port = htons(SCTP_TESTPORT_2);
+#endif /* TEST_V6 */
+
+        /* Create the two endpoints which will talk to each other.  */
+        sk1 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+        sk2 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+
+	len = sizeof(int);
+	error = getsockopt(sk2, SOL_SOCKET, SO_RCVBUF, &orig_len,
+			   &len);
+	if (error)
+		tst_brkm(TBROK, tst_exit, "can't get rcvbuf size: %s",
+			strerror(errno));
+	/* Set the MAXSEG to something smallish. */
+	{
+		int val = SMALL_MAXSEG;
+		test_setsockopt(sk1, SCTP_MAXSEG, &val, sizeof(val));
+	}
+
+	memset(&subscribe, 0, sizeof(subscribe));
+	subscribe.sctp_data_io_event = 1;
+	subscribe.sctp_association_event = 1;
+	subscribe.sctp_send_failure_event = 1;
+	test_setsockopt(sk1, SCTP_EVENTS, &subscribe, sizeof(subscribe));
+	test_setsockopt(sk2, SCTP_EVENTS, &subscribe, sizeof(subscribe));
+
+        /* Bind these sockets to the test ports.  */
+        test_bind(sk1, &loop1.sa, sizeof(loop1));
+        test_bind(sk2, &loop2.sa, sizeof(loop2));
+
+	/*
+	 * This code sets the associations RWND very small so we can
+	 * fill it.  It does this by manipulating the rcvbuf as follows:
+	 * 1) Reduce the rcvbuf size on the socket
+	 * 2) create an association so that we advertise rcvbuf/2 as
+	 *    our initial rwnd
+	 */
+	len = SMALL_RCVBUF;
+	error = setsockopt(sk2, SOL_SOCKET, SO_RCVBUF, &len,
+			   sizeof(len));
+	if (error)
+		tst_brkm(TBROK, tst_exit, "setsockopt(SO_RCVBUF): %s",
+			 strerror(errno));
+
+       /* Mark sk2 as being able to accept new associations.  */
+	test_listen(sk2, 1);
+
+        /* Send the first message.  This will create the association.  */
+        outmessage.msg_name = &loop2;
+        outmessage.msg_namelen = sizeof(loop2);
+        outmessage.msg_iov = &out_iov;
+        outmessage.msg_iovlen = 1;
+        outmessage.msg_control = outcmsg;
+        outmessage.msg_controllen = sizeof(outcmsg);
+        outmessage.msg_flags = 0;
+	cmsg = CMSG_FIRSTHDR(&outmessage);
+	cmsg->cmsg_level = IPPROTO_SCTP;
+	cmsg->cmsg_type = SCTP_SNDRCV;
+	cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+	outmessage.msg_controllen = cmsg->cmsg_len;
+	sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+	memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+	ppid = rand(); /* Choose an arbitrary value. */
+	stream = 1;
+	sinfo->sinfo_ppid = ppid;
+	sinfo->sinfo_stream = stream;
+        outmessage.msg_iov->iov_base = message;
+        outmessage.msg_iov->iov_len = strlen(message) + 1;
+        test_sendmsg(sk1, &outmessage, 0, strlen(message)+1);
+
+	/* Initialize inmessage for all receives. */
+	big_buffer = test_malloc(REALLY_BIG);
+        memset(&inmessage, 0, sizeof(inmessage));
+        iov.iov_base = big_buffer;
+        iov.iov_len = REALLY_BIG;
+        inmessage.msg_iov = &iov;
+        inmessage.msg_iovlen = 1;
+        inmessage.msg_control = incmsg;
+
+        /* Get the communication up message on sk2.  */
+        inmessage.msg_controllen = sizeof(incmsg);
+        error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage, error,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+#if 0
+	sac = (struct sctp_assoc_change *)iov.iov_base;
+	associd2 = sac->sac_assoc_id;
+#endif
+
+        /* Get the communication up message on sk1.  */
+        inmessage.msg_controllen = sizeof(incmsg);
+        error = test_recvmsg(sk1, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage, error,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+	sac = (struct sctp_assoc_change *)iov.iov_base;
+	associd1 = sac->sac_assoc_id;
+
+        /* Get the first data message which was sent.  */
+        inmessage.msg_controllen = sizeof(incmsg);
+        error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+        test_check_msg_data(&inmessage, error, strlen(message) + 1,
+			    MSG_EOR, stream, ppid);
+
+	/* Figure out how big to make our fillmsg */
+	len = sizeof(struct sctp_status);
+	memset(&gstatus,0,sizeof(struct sctp_status));
+	gstatus.sstat_assoc_id = associd1;
+	error = getsockopt(sk1, IPPROTO_SCTP, SCTP_STATUS, &gstatus, &len);
+	
+	if (error)
+		tst_brkm(TBROK, tst_exit, "can't get rwnd size: %s",
+			strerror(errno));
+	tst_resm(TINFO, "Creating fillmsg of size %d",
+		 gstatus.sstat_rwnd+RWND_SLOP);
+	fillmsg = malloc(gstatus.sstat_rwnd+RWND_SLOP);	
+
+	/* Send a fillmsg */
+        outmessage.msg_controllen = sizeof(outcmsg);
+        outmessage.msg_flags = 0;
+	cmsg = CMSG_FIRSTHDR(&outmessage);
+	cmsg->cmsg_level = IPPROTO_SCTP;
+	cmsg->cmsg_type = SCTP_SNDRCV;
+	cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+	outmessage.msg_controllen = cmsg->cmsg_len;
+	sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+	memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+	ppid++;
+	stream++;
+	sinfo->sinfo_ppid = ppid;
+	sinfo->sinfo_stream = stream;
+	memset(fillmsg, 'X', gstatus.sstat_rwnd+RWND_SLOP);
+	fillmsg[gstatus.sstat_rwnd+RWND_SLOP-1] = '\0';
+	outmessage.msg_iov->iov_base = fillmsg;
+	outmessage.msg_iov->iov_len = gstatus.sstat_rwnd+RWND_SLOP;
+	outmessage.msg_name = NULL;
+	outmessage.msg_namelen = 0;
+	sinfo->sinfo_assoc_id = associd1;
+	sinfo->sinfo_timetolive = 0;
+	test_sendmsg(sk1, &outmessage, MSG_NOSIGNAL,
+			 gstatus.sstat_rwnd+RWND_SLOP);
+
+	/* Now send the message with timeout. */
+	sinfo->sinfo_ppid = ppid;
+	sinfo->sinfo_stream = stream;
+	outmessage.msg_iov->iov_base = ttlmsg;
+        outmessage.msg_iov->iov_len = strlen(ttlmsg) + 1;
+	outmessage.msg_name = NULL;
+	outmessage.msg_namelen = 0;
+	sinfo->sinfo_assoc_id = associd1;
+	sinfo->sinfo_timetolive = 2000;
+	test_sendmsg(sk1, &outmessage, MSG_NOSIGNAL, strlen(ttlmsg) + 1);
+
+	tst_resm(TPASS, "Send a message with timeout");
+
+	/* Next send a message with no timeout. */
+	sinfo->sinfo_ppid = ppid;
+	sinfo->sinfo_stream = stream;
+	outmessage.msg_iov->iov_base = nottlmsg;
+        outmessage.msg_iov->iov_len = strlen(nottlmsg) + 1;
+	outmessage.msg_name = NULL;
+	outmessage.msg_namelen = 0;
+	sinfo->sinfo_assoc_id = associd1;
+	sinfo->sinfo_timetolive = 0;
+	test_sendmsg(sk1, &outmessage, MSG_NOSIGNAL, strlen(nottlmsg)+1);
+
+	tst_resm(TPASS, "Send a message with no timeout");
+
+	/* And finally a fragmented message that will time out. */
+	sinfo->sinfo_ppid = ppid;
+	sinfo->sinfo_stream = stream;
+	memset(ttlfrag, 48, sizeof(ttlfrag)); /* 48 is the ascii of '0' */
+	ttlfrag[sizeof(ttlfrag)-1] = '\0';
+	outmessage.msg_iov->iov_base = ttlfrag;
+        outmessage.msg_iov->iov_len = sizeof(ttlfrag);
+	outmessage.msg_name = NULL;
+	outmessage.msg_namelen = 0;
+	sinfo->sinfo_assoc_id = associd1;
+	sinfo->sinfo_timetolive = 2000;
+	test_sendmsg(sk1, &outmessage, MSG_NOSIGNAL, sizeof(ttlfrag));
+
+	tst_resm(TPASS, "Send a fragmented message with timeout");
+
+	/* Sleep waiting for the message to time out. */
+	tst_resm(TINFO, " **  SLEEPING for 3 seconds **");
+	sleep(3);
+
+	/* Read the fillmsg snuck in between the ttl'd messages. */
+	do {
+		inmessage.msg_controllen = sizeof(incmsg);
+		error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+	} while (!(inmessage.msg_flags & MSG_EOR));
+
+	/* Now get the message that did NOT time out. */
+	inmessage.msg_controllen = sizeof(incmsg);
+	error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+	test_check_msg_data(&inmessage, error, strlen(nottlmsg) + 1,
+			    MSG_EOR, stream, ppid);
+	if (0 != strncmp(iov.iov_base, nottlmsg, strlen(nottlmsg)+1))
+		tst_brkm(TBROK, tst_exit, "Received Wrong Message !!!");
+
+	tst_resm(TPASS, "Receive message with no timeout");
+
+	/* Get the SEND_FAILED notification for the message that DID
+	 * time out.
+	 */
+	inmessage.msg_controllen = sizeof(incmsg);
+	error = test_recvmsg(sk1, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage, error,
+				    sizeof(struct sctp_send_failed) +
+							strlen(ttlmsg) + 1,
+				    SCTP_SEND_FAILED, 0);
+	ssf = (struct sctp_send_failed *)iov.iov_base;
+	if (0 != strncmp(ttlmsg, (char *)ssf->ssf_data, strlen(ttlmsg) + 1))
+		tst_brkm(TBROK, tst_exit, "SEND_FAILED data mismatch");
+
+	tst_resm(TPASS, "Receive SEND_FAILED for message with timeout");
+
+	/* Get the SEND_FAILED notification for the fragmented message that
+	 * DID time out.
+	 */
+	offset = 0;
+	do {
+		inmessage.msg_controllen = sizeof(incmsg);
+		error = test_recvmsg(sk1, &inmessage, MSG_WAITALL);
+		test_check_msg_notification(&inmessage, error,
+					    sizeof(struct sctp_send_failed) +
+								  SMALL_MAXSEG,
+					    SCTP_SEND_FAILED, 0);
+		ssf = (struct sctp_send_failed *)iov.iov_base;
+		if (0 != strncmp(&ttlfrag[offset], (char *)ssf->ssf_data,
+				 SMALL_MAXSEG))
+			tst_brkm(TBROK, tst_exit, "SEND_FAILED data mismatch");
+		offset += SMALL_MAXSEG;
+	} while (!(ssf->ssf_info.sinfo_flags & 0x01)); /* LAST_FRAG */
+
+	tst_resm(TPASS, "Receive SEND_FAILED for fragmented message with "
+		 "timeout");
+
+        /* Shut down the link.  */
+        close(sk1);
+
+        /* Get the shutdown complete notification. */
+	inmessage.msg_controllen = sizeof(incmsg);
+        error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+	test_check_msg_notification(&inmessage, error,
+				    sizeof(struct sctp_assoc_change),
+				    SCTP_ASSOC_CHANGE, SCTP_SHUTDOWN_COMP);
+
+        close(sk2);
+
+        /* Indicate successful completion.  */
+        return 0;
+}
diff --git a/src/include/Makefile.am b/src/include/Makefile.am
new file mode 100644
index 0000000..38abaec
--- /dev/null
+++ b/src/include/Makefile.am
@@ -0,0 +1,5 @@
+
+include $(top_srcdir)/Makefile.vars
+include $(top_srcdir)/Makefile.rules
+
+SUBDIRS = netinet
diff --git a/src/include/netinet/Makefile.am b/src/include/netinet/Makefile.am
new file mode 100644
index 0000000..965db8c
--- /dev/null
+++ b/src/include/netinet/Makefile.am
@@ -0,0 +1,14 @@
+
+include $(top_srcdir)/Makefile.vars
+include $(top_srcdir)/Makefile.rules
+
+libcnetinetdir = $(includedir)/netinet
+
+
+## FIXME: Your stuff here
+
+# Supposing this is part of the development package, header for our
+# API.
+include_HEADERS =
+
+libcnetinet_HEADERS = sctp.h
diff --git a/src/include/netinet/sctp.h.in b/src/include/netinet/sctp.h.in
new file mode 100644
index 0000000..2009f1c
--- /dev/null
+++ b/src/include/netinet/sctp.h.in
@@ -0,0 +1,188 @@
+/* SCTP kernel Implementation: User API extensions.
+ *
+ * sctp.h
+ *
+ * Distributed under the terms of the LGPL v2.1 as described in
+ *    http://www.gnu.org/copyleft/lesser.txt
+ *
+ * This file is part of the user library that offers support for the
+ * Linux Kernel SCTP Implementation. The main purpose of this
+ * code is to provide the SCTP Socket API mappings for user
+ * application to interface with SCTP in kernel.
+ *
+ * This header represents the structures and constants needed to support
+ * the SCTP Extension to the Sockets API.
+ *
+ * (C) Copyright IBM Corp. 2001, 2004
+ * Copyright (c) 1999-2000 Cisco, Inc.
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ *
+ * Written or modified by:
+ *    La Monte H.P. Yarroll    <piggy@acm.org>
+ *    R. Stewart               <randall@sctp.chicago.il.us>
+ *    K. Morneau               <kmorneau@cisco.com>
+ *    Q. Xie                   <qxie1@email.mot.com>
+ *    Karl Knutson             <karl@athena.chicago.il.us>
+ *    Jon Grimm                <jgrimm@austin.ibm.com>
+ *    Daisy Chang              <daisyc@us.ibm.com>
+ *    Inaky Perez-Gonzalez     <inaky.gonzalez@intel.com>
+ *    Sridhar Samudrala        <sri@us.ibm.com>
+ *    Vlad Yasevich		<vladislav.yasevich@hp.com>
+ */
+
+#ifndef __linux_sctp_h__
+#define __linux_sctp_h__
+
+#include <stdint.h>
+#include <linux/types.h>
+#include <sys/socket.h>
+#include <linux/sctp.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Socket option layer for SCTP */
+#ifndef SOL_SCTP
+#define SOL_SCTP	132
+#endif
+
+#ifndef IPPROTO_SCTP
+#define IPPROTO_SCTP    132
+#endif
+
+/* 9. Preprocessor constants */
+#define HAVE_SCTP
+#define HAVE_KERNEL_SCTP
+#define HAVE_SCTP_MULTIBUF
+#define HAVE_SCTP_NOCONNECT
+#define HAVE_SCTP_PRSCTP
+#define HAVE_SCTP_ADDIP
+#define HAVE_SCTP_CANSET_PRIMARY
+
+#undef HAVE_SCTP_STREAM_RESET_EVENT
+#undef HAVE_SCTP_STREAM_RECONFIG
+#undef HAVE_SCTP_PEELOFF_FLAGS
+#undef HAVE_SCTP_PDAPI_EVENT_PDAPI_STREAM
+#undef HAVE_SCTP_PDAPI_EVENT_PDAPI_SEQ
+#undef HAVE_SCTP_SENDV
+#undef HAVE_SCTP_AUTH_NO_AUTH
+#undef HAVE_SCTP_SPP_IPV6_FLOWLABEL
+#undef HAVE_SCTP_SPP_DSCP
+
+int sctp_bindx(int sd, struct sockaddr *addrs, int addrcnt, int flags);
+
+int sctp_connectx(int sd, struct sockaddr *addrs, int addrcnt,
+		  sctp_assoc_t *id);
+
+int sctp_peeloff(int sd, sctp_assoc_t assoc_id);
+int sctp_peeloff_flags(int sd, sctp_assoc_t assoc_id, unsigned flags);
+
+/* Prototype for the library function sctp_opt_info defined in
+ * API 7. Socket Options.
+ */
+int sctp_opt_info(int sd, sctp_assoc_t id, int opt, void *arg, socklen_t *size);
+
+/* Get all peer address on a socket.  This is a new SCTP API
+ * described in the section 8.3 of the Sockets API Extensions for SCTP.
+ * This is implemented using the getsockopt() interface.
+ */
+int sctp_getpaddrs(int sd, sctp_assoc_t id, struct sockaddr **addrs);
+
+/* Frees all resources allocated by sctp_getpaddrs().  This is a new SCTP API
+ * described in the section 8.4 of the Sockets API Extensions for SCTP.
+ */
+int sctp_freepaddrs(struct sockaddr *addrs);
+
+/* Get all locally bound address on a socket.  This is a new SCTP API
+ * described in the section 8.5 of the Sockets API Extensions for SCTP.
+ * This is implemented using the getsockopt() interface.
+ */
+int sctp_getladdrs(int sd, sctp_assoc_t id, struct sockaddr **addrs);
+
+/* Frees all resources allocated by sctp_getladdrs().  This is a new SCTP API
+ * described in the section 8.6 of the Sockets API Extensions for SCTP.
+ */
+int sctp_freeladdrs(struct sockaddr *addrs);
+
+/* This library function assists the user with the advanced features
+ * of SCTP.  This is a new SCTP API described in the section 8.7 of the
+ * Sockets API Extensions for SCTP. This is implemented using the
+ * sendmsg() interface.
+ */
+int sctp_sendmsg(int s, const void *msg, size_t len, struct sockaddr *to,
+		 socklen_t tolen, uint32_t ppid, uint32_t flags,
+		 uint16_t stream_no, uint32_t timetolive, uint32_t context);
+
+/* This library function assist the user with sending a message without
+ * dealing directly with the CMSG header.
+ */
+int sctp_send(int s, const void *msg, size_t len,
+              const struct sctp_sndrcvinfo *sinfo, int flags);
+
+/* This library function assists the user with the advanced features
+ * of SCTP.  This is a new SCTP API described in the section 8.8 of the
+ * Sockets API Extensions for SCTP. This is implemented using the
+ * recvmsg() interface.
+ */
+int sctp_recvmsg(int s, void *msg, size_t len, struct sockaddr *from,
+		 socklen_t *fromlen, struct sctp_sndrcvinfo *sinfo,
+		 int *msg_flags);
+
+/* Return the address length for an address family. */
+int sctp_getaddrlen(sa_family_t family);
+
+
+#ifdef HAVE_SCTP_SENDV
+/* sendv infotype */
+enum {
+	SCTP_SENDV_NOINFO,
+	SCTP_SENDV_SNDINFO,
+	SCTP_SENDV_PRINFO,
+	SCTP_SENDV_AUTHINFO,
+	SCTP_SENDV_SPA
+};
+
+/* sendv_flags */
+#define SCTP_SEND_SNDINFO_VALID		0x1
+#define SCTP_SEND_PRINFO_VALID		0x2
+#define SCTP_SEND_AUTHINFO_VALID	0x4
+#endif
+
+struct sctp_sendv_spa {
+	uint32_t sendv_flags;
+	struct sctp_sndinfo sendv_sndinfo;
+#ifdef HAVE_SCTP_SENDV
+	struct sctp_prinfo sendv_prinfo;
+	struct sctp_authinfo sendv_authinfo;
+#endif
+};
+
+#ifdef HAVE_SCTP_SENDV
+int sctp_sendv(int s, const struct iovec *iov, int iovcnt,
+	       struct sockaddr *addrs, int addrcnt, void *info,
+	       socklen_t infolen, unsigned int infotype, int flags);
+
+/* recvv infotype */
+enum {
+	SCTP_RECVV_NOINFO,
+	SCTP_RECVV_RCVINFO,
+	SCTP_RECVV_NXTINFO,
+	SCTP_RECVV_RN
+};
+
+struct sctp_recvv_rn {
+	struct sctp_rcvinfo recvv_rcvinfo;
+	struct sctp_nxtinfo recvv_nxtinfo;
+};
+
+int sctp_recvv(int s, const struct iovec *iov, int iovlen,
+	       struct sockaddr *from, socklen_t *fromlen, void *info,
+	       socklen_t *infolen, unsigned int *infotype, int *flags);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __linux_sctp_h__ */
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
new file mode 100644
index 0000000..1296caa
--- /dev/null
+++ b/src/lib/Makefile.am
@@ -0,0 +1,15 @@
+# Include these two in all the Makefile.am's!!!
+include $(top_srcdir)/Makefile.vars
+include $(top_srcdir)/Makefile.rules
+include $(top_srcdir)/Makefile.dirs
+
+# General compilation flags
+AM_CPPFLAGS = -I$(top_builddir)/src/include
+
+lib_LTLIBRARIES = libsctp.la
+
+libsctp_la_SOURCES = bindx.c connectx.c peeloff.c opt_info.c \
+		addrs.c sendmsg.c recvmsg.c Versions.map
+libsctp_la_LDFLAGS = -version-info \
+		@LIBSCTP_CURRENT@:@LIBSCTP_REVISION@:@LIBSCTP_AGE@ \
+		-Wl,--version-script=$(srcdir)/Versions.map
diff --git a/src/lib/Versions.map b/src/lib/Versions.map
new file mode 100644
index 0000000..7faad5d
--- /dev/null
+++ b/src/lib/Versions.map
@@ -0,0 +1,28 @@
+VERS_1 {
+	global:
+		sctp_getpaddrs;
+		sctp_freepaddrs;
+		sctp_getladdrs;
+		sctp_freeladdrs;
+		sctp_getaddrlen;
+		sctp_bindx;
+		sctp_connectx;
+		sctp_opt_info;
+		sctp_peeloff;
+		sctp_recvmsg;
+		sctp_recvv;
+		sctp_sendmsg;
+		sctp_sendv;
+		sctp_send;
+
+	local:
+		*;
+};
+
+VERS_2 {
+	global:	sctp_connectx;
+} VERS_1;
+
+VERS_3 {
+	global:	sctp_connectx;
+} VERS_2;
diff --git a/src/lib/addrs.c b/src/lib/addrs.c
new file mode 100644
index 0000000..65f5222
--- /dev/null
+++ b/src/lib/addrs.c
@@ -0,0 +1,155 @@
+/* SCTP kernel Implementation: User API extensions.
+ *
+ * addrs.c
+ *
+ * Distributed under the terms of the LGPL v2.1 as described in
+ *    http://www.gnu.org/copyleft/lesser.txt 
+ *
+ * This file is part of the user library that offers support for the
+ * SCTP kernel Implementation. The main purpose of this
+ * code is to provide the SCTP Socket API mappings for user
+ * application to interface with the SCTP in kernel.
+ *
+ * This implementation is based on the Socket API Extensions for SCTP
+ * defined in <draft-ietf-tsvwg-sctpsocket-10.txt.
+ *
+ * (C) Copyright IBM Corp. 2003
+ * Copyright (c) 2001-2002 Intel Corp.
+ *
+ * Written or modified by:
+ *  Ardelle Fan     <ardelle.fan@intel.com>
+ *  Sridhar Samudrala <sri@us.ibm.com>
+ *  Ivan Skytte Jørgensen <isj-sctp@i1.dk>
+ */
+
+#include <malloc.h>
+#include <netinet/in.h>
+#include <netinet/sctp.h>
+#include <string.h>
+#include <errno.h>
+
+/* 
+ * Common getsockopt() layer 
+ * If the NEW getsockopt() API fails this function will fall back to using
+ * the old API
+ */
+static int
+sctp_getaddrs(int sd, sctp_assoc_t id, int optname_new,
+	      struct sockaddr **addrs)
+{
+	int cnt, err;
+	socklen_t len;
+	size_t bufsize = 4096; /*enough for most cases*/
+
+	struct sctp_getaddrs *getaddrs = (struct sctp_getaddrs*)malloc(bufsize);
+	if(!getaddrs)
+		return -1;
+	
+	for(;;) {
+		char *new_buf;
+
+		len = bufsize;
+		getaddrs->assoc_id = id;
+		err = getsockopt(sd, SOL_SCTP, optname_new, getaddrs, &len);
+		if (err == 0) {
+			/*got it*/
+			break;
+		}
+		if (errno != ENOMEM ) {
+			/*unknown error*/
+			free(getaddrs);
+			return -1;
+		}
+		/*expand buffer*/
+		if (bufsize > 128*1024) {
+			/*this is getting ridiculous*/
+			free(getaddrs);
+			errno = ENOBUFS;
+			return -1;
+		}
+		new_buf = realloc(getaddrs, bufsize+4096);
+		if (!new_buf) {
+			free(getaddrs);
+			return -1;
+		}
+		bufsize += 4096;
+		getaddrs = (struct sctp_getaddrs*)new_buf;
+	}
+
+	/* we skip traversing the list, allocating a new buffer etc. and enjoy
+	 * a simple hack*/
+	cnt = getaddrs->addr_num;
+	memmove(getaddrs, getaddrs + 1, len);
+	*addrs = (struct sockaddr*)getaddrs;
+
+	return cnt;
+} /* sctp_getaddrs() */
+
+/* Get all peer address on a socket.  This is a new SCTP API
+ * described in the section 8.3 of the Sockets API Extensions for SCTP.
+ * This is implemented using the getsockopt() interface.
+ */
+int
+sctp_getpaddrs(int sd, sctp_assoc_t id, struct sockaddr **addrs)
+{
+	return sctp_getaddrs(sd, id,
+			     SCTP_GET_PEER_ADDRS,
+			     addrs);
+} /* sctp_getpaddrs() */
+
+/* Frees all resources allocated by sctp_getpaddrs().  This is a new SCTP API
+ * described in the section 8.4 of the Sockets API Extensions for SCTP.
+ */
+int
+sctp_freepaddrs(struct sockaddr *addrs)
+{
+	free(addrs);
+	return 0;
+
+} /* sctp_freepaddrs() */
+
+/* Get all locally bound address on a socket.  This is a new SCTP API
+ * described in the section 8.5 of the Sockets API Extensions for SCTP.
+ * This is implemented using the getsockopt() interface.
+ */
+int
+sctp_getladdrs(int sd, sctp_assoc_t id, struct sockaddr **addrs)
+{
+	return sctp_getaddrs(sd, id,
+			     SCTP_GET_LOCAL_ADDRS,
+			     addrs);
+} /* sctp_getladdrs() */
+
+/* Frees all resources allocated by sctp_getladdrs().  This is a new SCTP API
+ * described in the section 8.6 of the Sockets API Extensions for SCTP.
+ */
+int
+sctp_freeladdrs(struct sockaddr *addrs)
+{
+	free(addrs);
+	return 0;
+
+} /* sctp_freeladdrs() */
+
+int
+sctp_getaddrlen(sa_family_t family)
+{
+	/* We could call into the kernel to see what it thinks the size should
+	 * be, but hardcoding the address families here is: (a) faster,
+	 * (b) easier, and (c) probably good enough for forseeable future.
+	 */
+	switch(family) {
+	case AF_INET:
+		return sizeof(struct sockaddr_in);
+	case AF_INET6:
+		return sizeof(struct sockaddr_in6);
+	default:
+		/* Currently there is no defined error handling in
+		 * draft-ietf-tsvwg-sctpsocket-13.txt.
+		 * -1 might cause the application to overwrite buffer
+		 * or misinterpret data. 0 is more likely to cause
+		 * an endless loop.
+		 */
+		return 0;
+	}
+}
diff --git a/src/lib/bindx.c b/src/lib/bindx.c
new file mode 100644
index 0000000..5f44874
--- /dev/null
+++ b/src/lib/bindx.c
@@ -0,0 +1,78 @@
+/* SCTP kernel Implementation: User API extensions.
+ *
+ * bindx.c
+ *
+ * Distributed under the terms of the LGPL v2.1 as described in
+ *    http://www.gnu.org/copyleft/lesser.txt 
+ *
+ * This file is part of the user library that offers support for the
+ * SCTP kernel Implementation. The main purpose of this
+ * code is to provide the SCTP Socket API mappings for user
+ * application to interface with the SCTP in kernel.
+ *
+ * This implementation is based on the Socket API Extensions for SCTP
+ * defined in <draft-ietf-tsvwg-sctpsocket-10.txt.
+ *
+ * (C) Copyright IBM Corp. 2001, 2003
+ * Copyright (c) 2002 Intel Corporation.
+ *
+ * Written or modified by:
+ *   La Monte H.P. Yarroll <piggy@acm.org>
+ *   Daisy Chang           <daisyc@us.ibm.com>
+ *   Inaky Perez-Gonzalez  <inaky.gonzalez@intel.com>
+ *   Sridhar Samudrala     <sri@us.ibm.com>
+ */
+
+#include <sys/socket.h>   /* struct sockaddr_storage, setsockopt() */
+#include <netinet/in.h>
+#include <netinet/sctp.h> /* SCTP_SOCKOPT_BINDX_* */
+#include <errno.h>
+
+/* Support the sctp_bindx() interface.
+ *
+ * See Sockets API Extensions for SCTP. Section 8.1.
+ *
+ * Instead of implementing through a socket call in sys_socketcall(),
+ * tunnel the request through setsockopt().
+ */
+int
+sctp_bindx(int fd, struct sockaddr *addrs, int addrcnt, int flags)
+{
+	int setsock_option = 0;
+	const char *addrbuf;
+	struct sockaddr *sa_addr;
+	socklen_t addrs_size = 0;
+	int i;
+
+	switch (flags) {
+	case SCTP_BINDX_ADD_ADDR:
+		setsock_option = SCTP_SOCKOPT_BINDX_ADD;
+		break;
+	case SCTP_BINDX_REM_ADDR:
+		setsock_option = SCTP_SOCKOPT_BINDX_REM;
+		break;
+	default:
+		errno = EINVAL;
+		return -1;
+	}
+
+	addrbuf = (char*)addrs;
+	for (i = 0; i < addrcnt; i++) {
+		sa_addr = (struct sockaddr *)addrbuf;
+		switch (sa_addr->sa_family) {
+		case AF_INET:
+			addrs_size += sizeof(struct sockaddr_in);
+			addrbuf += sizeof(struct sockaddr_in);
+			break;
+		case AF_INET6:
+			addrs_size += sizeof(struct sockaddr_in6);
+			addrbuf += sizeof(struct sockaddr_in6);
+			break;
+		default:
+			errno = EINVAL;
+			return -1;
+		}
+	}
+			
+	return setsockopt(fd, SOL_SCTP, setsock_option, addrs, addrs_size);
+}
diff --git a/src/lib/connectx.c b/src/lib/connectx.c
new file mode 100644
index 0000000..5f4552b
--- /dev/null
+++ b/src/lib/connectx.c
@@ -0,0 +1,190 @@
+/* SCTP kernel Implementation: User API extensions.
+ *
+ * connectx.c
+ *
+ * Distributed under the terms of the LGPL v2.1 as described in
+ * http://www.gnu.org/copyleft/lesser.txt.
+ *
+ * This file is part of the user library that offers support for the
+ * SCTP kernel Implementation. The main purpose of this
+ * code is to provide the SCTP Socket API mappings for user
+ * application to interface with the SCTP in kernel.
+ *
+ * This implementation is based on the Socket API Extensions for SCTP
+ * defined in <draft-ietf-tsvwg-sctpsocket-10.txt.
+ *
+ * (C) Copyright IBM Corp. 2001, 2005
+ *
+ * Written or modified by:
+ *   Frank Filz     <ffilz@us.ibm.com>
+ */
+
+#include <sys/socket.h>   /* struct sockaddr_storage, setsockopt() */
+#include <netinet/in.h>
+#include <netinet/sctp.h> /* SCTP_SOCKOPT_CONNECTX_* */
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+
+/* Support the sctp_connectx() interface.
+ *
+ * See Sockets API Extensions for SCTP. Section 8.1.
+ *
+ * Instead of implementing through a socket call in sys_socketcall(),
+ * tunnel the request through setsockopt().
+ */
+static int __connectx_addrsize(const struct sockaddr *addrs,
+				const int addrcnt)
+{
+	const char *addrbuf;
+	const struct sockaddr *sa_addr;
+	int addrs_size = 0;
+	int i;
+
+	addrbuf = (char *)addrs;
+	for (i = 0; i < addrcnt; i++) {
+		sa_addr = (const struct sockaddr *)addrbuf;
+		switch (sa_addr->sa_family) {
+		case AF_INET:
+			addrs_size += sizeof(struct sockaddr_in);
+			addrbuf += sizeof(struct sockaddr_in);
+			break;
+		case AF_INET6:
+			addrs_size += sizeof(struct sockaddr_in6);
+			addrbuf += sizeof(struct sockaddr_in6);
+			break;
+		default:
+			errno = EINVAL;
+			return -1;
+		}
+	}
+
+	return addrs_size;
+}
+			
+
+int __sctp_connectx(int fd, struct sockaddr *addrs, int addrcnt)
+{
+	int addrs_size = __connectx_addrsize(addrs, addrcnt);
+
+	if (addrs_size < 0)
+		return addrs_size;
+
+	return setsockopt(fd, SOL_SCTP, SCTP_SOCKOPT_CONNECTX_OLD, addrs,
+			    addrs_size);
+}
+
+extern int sctp_connectx_orig (int)
+	__attribute ((alias ("__sctp_connectx")));
+
+
+static int __connectx(int fd, struct sockaddr *addrs, socklen_t addrs_size,
+			sctp_assoc_t *id)
+{
+	int status;
+
+	if (id)
+		*id = 0;
+
+	status = setsockopt(fd, SOL_SCTP, SCTP_SOCKOPT_CONNECTX, addrs,
+			    addrs_size);
+
+	/* Normalize status and set association id */
+	if (status > 0) {
+		if (id)
+			*id = status;
+		return 0;
+	}
+
+	/* The error is something other then "Option not supported" */
+	if (status < 0 && errno != ENOPROTOOPT)
+		return status;
+
+	/* At this point, if the application wanted the id, we can't
+	 * really provide it, so we can return ENOPROTOOPT.
+	 */
+	if (id) {
+		errno = ENOPROTOOPT;
+		return -1;
+	}
+
+	/* Finally, try the old API */
+	return setsockopt(fd, SOL_SCTP, SCTP_SOCKOPT_CONNECTX_OLD,
+			  addrs, addrs_size);
+}
+
+int sctp_connectx2(int fd, struct sockaddr *addrs, int addrcnt,
+		      sctp_assoc_t *id)
+{
+	int addrs_size = __connectx_addrsize(addrs, addrcnt);
+
+	if (addrs_size < 0)
+		return addrs_size;
+
+	return __connectx(fd, addrs, addrs_size, id);
+}
+
+int sctp_connectx3(int fd, struct sockaddr *addrs, int addrcnt,
+		      sctp_assoc_t *id)
+{
+	int addrs_size = __connectx_addrsize(addrs, addrcnt);
+	int status;
+	struct sctp_getaddrs_old param;
+	socklen_t opt_len = sizeof(param);
+
+	if (addrs_size < 0)
+		return addrs_size;
+
+	/* First try the new socket api
+	 * Because the id is returned in the option buffer we have prepend
+	 * 32bit to it for the returned association id
+	 */
+	param.assoc_id = 0;
+	param.addr_num = addrs_size;
+	param.addrs = addrs;
+	status = getsockopt(fd, SOL_SCTP, SCTP_SOCKOPT_CONNECTX3,
+		            &param, &opt_len);
+	if (status == 0 || errno == EINPROGRESS) {
+		/* Succeeded immediately, or initiated on non-blocking
+		 * socket.
+		 */
+		if (id)
+			*id = param.assoc_id;
+	}
+
+	if (errno != ENOPROTOOPT) {
+		/* No point in trying the fallbacks*/
+		return status;
+	}
+
+	/* The first incarnation of updated connectx api didn't work for
+	 * non-blocking sockets.  So if the application wants the association
+	 * id and the socket is non-blocking, we can't really do anything.
+	 */
+	if (id) {
+		/* Program wants the association-id returned. We can only do
+		 * that if the socket is blocking */
+		status = fcntl(fd, F_GETFL);
+		if (status < 0)
+			return status;
+
+		if (status & O_NONBLOCK) {
+			/* Socket is non-blocking. Fail */
+			errno = ENOPROTOOPT;
+			return -1;
+		}
+	}
+
+	return __connectx(fd, addrs, addrs_size, id);
+}
+
+#define __SYMPFX(pfx, sym) #pfx sym
+#define _SYMPFX(pfx, sym) __SYMPFX(pfx, sym)
+#define SYMPFX(sym) _SYMPFX(__USER_LABEL_PREFIX__, #sym)
+#define SYMVER(name, name2) __asm__(".symver " SYMPFX(name) "," SYMPFX(name2))
+
+SYMVER(__sctp_connectx, sctp_connectx@);
+SYMVER(sctp_connectx_orig, sctp_connectx@VERS_1);
+SYMVER(sctp_connectx2, sctp_connectx@VERS_2);
+SYMVER(sctp_connectx3, sctp_connectx@@VERS_3);
diff --git a/src/lib/opt_info.c b/src/lib/opt_info.c
new file mode 100644
index 0000000..21c8307
--- /dev/null
+++ b/src/lib/opt_info.c
@@ -0,0 +1,62 @@
+/* SCTP kernel Implementation: User API extensions.
+ *
+ * opt_info.c
+ *
+ * Distributed under the terms of the LGPL v2.1 as described in
+ *    http://www.gnu.org/copyleft/lesser.txt 
+ *
+ * This file is part of the user library that offers support for the
+ * SCTP kernel Implementation. The main purpose of this
+ * code if to provide the SCTP Socket API mappings for user
+ * application to interface with the SCTP in kernel.
+ *
+ * This implementation is based on the Socket API Extensions for SCTP
+ * defined in <draft-ietf-tsvwg-sctpsocket-10.txt.
+ *
+ * (C) Copyright IBM Corp. 2003
+ * Copyright (c) 2002 Intel Corporation.
+ *
+ * Written or modified by:
+ *   Ardelle Fan <ardelle.fan@intel.com>
+ */
+
+#include <sys/socket.h>   /* struct sockaddr_storage, setsockopt() */
+#include <netinet/sctp.h> /* SCTP_SOCKOPT_BINDX_* */
+#include <errno.h>
+
+/* Support the sctp_opt_info() interface.
+ *
+ * See Sockets API Extensions for SCTP. Section 7.
+ *
+ * Pass sctp option information pass both in to and out of the SCTP stack.
+ * This is a new SCTP API described in the section 7 of the Sockets API
+ * Extensions for SCTP. This is implemented using the getsockopt() interface.
+ */
+int
+sctp_opt_info(int sd, sctp_assoc_t id, int opt, void *arg, socklen_t *size)
+{
+	switch (opt) {
+	case SCTP_RTOINFO:
+	case SCTP_ASSOCINFO:
+	case SCTP_INITMSG:
+	case SCTP_NODELAY:
+	case SCTP_AUTOCLOSE:
+	case SCTP_PRIMARY_ADDR:
+	case SCTP_DISABLE_FRAGMENTS:
+	case SCTP_PEER_ADDR_PARAMS:
+	case SCTP_DEFAULT_SEND_PARAM:
+	case SCTP_EVENTS:
+	case SCTP_I_WANT_MAPPED_V4_ADDR:
+	case SCTP_MAXSEG:
+	case SCTP_STATUS:
+	case SCTP_GET_PEER_ADDR_INFO:
+	case SCTP_AUTH_ACTIVE_KEY:
+	case SCTP_PEER_AUTH_CHUNKS:
+	case SCTP_LOCAL_AUTH_CHUNKS:
+		*(sctp_assoc_t *)arg = id;
+		return getsockopt(sd, IPPROTO_SCTP, opt, arg, size);
+	default:
+		return ENOTSUP;
+	}
+
+} /* sctp_opt_info() */
diff --git a/src/lib/peeloff.c b/src/lib/peeloff.c
new file mode 100644
index 0000000..a4e1ed9
--- /dev/null
+++ b/src/lib/peeloff.c
@@ -0,0 +1,72 @@
+/* SCTP kernel Implementation: User API extensions.
+ *
+ * peeloff.c
+ *
+ * Distributed under the terms of the LGPL v2.1 as described in
+ *    http://www.gnu.org/copyleft/lesser.txt 
+ *
+ * This file is part of the user library that offers support for the
+ * SCTP kernel Implementation. The main purpose of this
+ * code is to provide the SCTP Socket API mappings for user
+ * application to interface with the SCTP in kernel.
+ *
+ * This implementation is based on the Socket API Extensions for SCTP
+ * defined in <draft-ietf-tsvwg-sctpsocket-10.txt.
+ *
+ * (C) Copyright IBM Corp. 2001, 2003
+ * 
+ * Written or modified by: 
+ *  Sridhar Samudrala     <sri@us.ibm.com>
+ */
+
+#include <sys/socket.h>   /* struct sockaddr_storage, setsockopt() */
+#include <netinet/sctp.h> /* SCTP_SOCKOPT_BINDX_* */
+#include <errno.h>
+
+#ifdef HAVE_SCTP_PEELOFF_FLAGS
+int
+sctp_peeloff_flags(int fd, sctp_assoc_t associd, unsigned flags)
+{
+	socklen_t peeloff_size = sizeof(sctp_peeloff_flags_arg_t);
+	sctp_peeloff_flags_arg_t peeloff;
+	int err;
+
+	if (!flags)
+		return sctp_peeloff(fd, associd);
+
+	peeloff.p_arg.associd = associd;
+	peeloff.p_arg.sd = 0;
+	peeloff.flags = flags;
+
+	err = getsockopt(fd, SOL_SCTP, SCTP_SOCKOPT_PEELOFF_FLAGS, &peeloff,
+			 &peeloff_size);
+
+	if (err < 0)
+		return err;
+
+	return peeloff.p_arg.sd;
+}
+#endif
+
+/* Branch off an association into a seperate socket.  This is a new SCTP API
+ * described in the section 8.2 of the Sockets API Extensions for SCTP. 
+ * This is implemented using the getsockopt() interface.
+ */
+int
+sctp_peeloff(int fd, sctp_assoc_t associd)
+{
+	socklen_t peeloff_size = sizeof(sctp_peeloff_arg_t);
+	sctp_peeloff_arg_t peeloff;
+	int err;
+
+	peeloff.associd = associd;
+	peeloff.sd = 0;
+
+	err = getsockopt(fd, SOL_SCTP, SCTP_SOCKOPT_PEELOFF, &peeloff,
+			 &peeloff_size);
+
+	if (err < 0)
+		return err;
+
+	return peeloff.sd;
+}
diff --git a/src/lib/recvmsg.c b/src/lib/recvmsg.c
new file mode 100644
index 0000000..88fe061
--- /dev/null
+++ b/src/lib/recvmsg.c
@@ -0,0 +1,191 @@
+/* SCTP kernel Implementation: User API extensions.
+ *
+ * sctp_recvmsg.c
+ *
+ * Distributed under the terms of the LGPL v2.1 as described in
+ *    http://www.gnu.org/copyleft/lesser.txt 
+ *
+ * This file is part of the user library that offers support for the
+ * SCTP kernel Implementation. The main purpose of this
+ * code is to provide the SCTP Socket API mappings for user
+ * application to interface with the SCTP in kernel.
+ *
+ * This implementation is based on the Socket API Extensions for SCTP
+ * defined in <draft-ietf-tsvwg-sctpsocket-10.txt>
+ *
+ * Copyright (c) 2003 International Business Machines, Corp.
+ *
+ * Written or modified by:
+ *  Ryan Layer	<rmlayer@us.ibm.com>
+ *
+ * An implementation may provide a library function (or possibly system
+ * call) to assist the user with the advanced features of SCTP. Note
+ * that in order for the sctp_sndrcvinfo structure to be filled in by
+ * sctp_recvmsg() the caller must enable the sctp_data_io_events with
+ * the SCTP_EVENTS option.
+ * 
+ * sctp_recvmsg(). Its syntax is,
+ * 
+ * int sctp_recvmsg(int s,
+ *		    void *msg,
+ *		    size_t len,
+ *		    struct sockaddr *from,
+ *		    socklen_t *fromlen,
+ *		    struct sctp_sndrcvinfo *sinfo,
+ *		    int *msg_flags)
+ * 
+ * 
+ * s          - is the socket descriptor
+ * msg        - is a message buffer to be filled.
+ * len        - is the length of the message buffer.
+ * from       - is a pointer to a address to be filled with
+ *		the sender of this messages address.
+ * fromlen    - is the from length.
+ * sinfo      - A pointer to a sctp_sndrcvinfo structure
+ *		to be filled upon receipt of the message.
+ * msg_flags  - A pointer to a integer to be filled with
+ *		any message flags (e.g. MSG_NOTIFICATION).
+ */
+
+#include <string.h>
+#include <errno.h>
+#include <sys/socket.h>   /* struct sockaddr_storage, setsockopt() */
+#include <netinet/sctp.h>
+
+int sctp_recvmsg(int s, void *msg, size_t len, struct sockaddr *from,
+		 socklen_t *fromlen, struct sctp_sndrcvinfo *sinfo,
+		 int *msg_flags)
+{
+	int error;
+	struct iovec iov;
+	struct msghdr inmsg;
+	char incmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+	struct cmsghdr *cmsg = NULL;
+
+	memset(&inmsg, 0, sizeof (inmsg));
+
+	iov.iov_base = msg;
+	iov.iov_len = len;
+
+	inmsg.msg_name = from;
+	inmsg.msg_namelen = fromlen ? *fromlen : 0;
+	inmsg.msg_iov = &iov;
+	inmsg.msg_iovlen = 1;
+	inmsg.msg_control = incmsg;
+	inmsg.msg_controllen = sizeof(incmsg);
+
+	error = recvmsg(s, &inmsg, msg_flags ? *msg_flags : 0);
+	if (error < 0)
+		return error;
+
+	if (fromlen)
+		*fromlen = inmsg.msg_namelen;
+	if (msg_flags)
+		*msg_flags = inmsg.msg_flags;
+
+	if (!sinfo)
+		return error;
+
+	for (cmsg = CMSG_FIRSTHDR(&inmsg); cmsg != NULL;
+				 cmsg = CMSG_NXTHDR(&inmsg, cmsg)){
+		if ((IPPROTO_SCTP == cmsg->cmsg_level) &&
+		    (SCTP_SNDRCV == cmsg->cmsg_type))
+			break;
+	}
+
+        /* Copy sinfo. */
+	if (cmsg)
+		memcpy(sinfo, CMSG_DATA(cmsg), sizeof(struct sctp_sndrcvinfo));
+
+	return (error);
+}
+
+#ifdef HAVE_SCTP_SENDV
+int sctp_recvv(int s, const struct iovec *iov, int iovlen,
+	       struct sockaddr *from, socklen_t *fromlen, void *info,
+	       socklen_t *infolen, unsigned int *infotype, int *flags)
+{
+	char incmsg[CMSG_SPACE(sizeof(struct sctp_rcvinfo) +
+			       sizeof(struct sctp_nxtinfo))];
+	int error, len, _infolen;
+	struct cmsghdr *cmsg;
+	struct msghdr inmsg;
+
+	memset(&inmsg, 0, sizeof(inmsg));
+
+	/* set from and iov */
+	inmsg.msg_name = from;
+	inmsg.msg_namelen = fromlen ? *fromlen : 0;
+	inmsg.msg_iov = (struct iovec *)iov;
+	inmsg.msg_iovlen = iovlen;
+	inmsg.msg_control = incmsg;
+	inmsg.msg_controllen = sizeof(incmsg);
+
+	error = recvmsg(s, &inmsg, flags ? *flags : 0);
+	if (error < 0)
+		return error;
+
+	/* set fromlen, frags */
+	if (fromlen)
+		*fromlen = inmsg.msg_namelen;
+
+	if (flags)
+		*flags = inmsg.msg_flags;
+
+	if (!info || !infotype || !infolen)
+		return error;
+
+	*infotype = SCTP_RECVV_NOINFO;
+	_infolen = *infolen;
+
+	/* set info and infotype */
+	for (cmsg = CMSG_FIRSTHDR(&inmsg); cmsg != NULL;
+				cmsg = CMSG_NXTHDR(&inmsg, cmsg)) {
+		if (cmsg->cmsg_level != IPPROTO_SCTP)
+			continue;
+
+		if (cmsg->cmsg_type == SCTP_RCVINFO) {
+			len = sizeof(struct sctp_rcvinfo);
+			if (*infotype == SCTP_RECVV_NOINFO) {
+				if (_infolen < len)
+					break;
+				memcpy(info, CMSG_DATA(cmsg), len);
+				*infotype = SCTP_RECVV_RCVINFO;
+				*infolen = len;
+			} else if (*infotype == SCTP_RECVV_NXTINFO) {
+				if (_infolen < len +
+					       sizeof(struct sctp_nxtinfo))
+					break;
+				memcpy(info + len, info,
+				       sizeof(struct sctp_nxtinfo));
+				memcpy(info, CMSG_DATA(cmsg), len);
+				*infotype = SCTP_RECVV_RN;
+				*infolen = len + sizeof(struct sctp_nxtinfo);
+			} else {
+				break;
+			}
+		} else if (cmsg->cmsg_type == SCTP_NXTINFO) {
+			len = sizeof(struct sctp_nxtinfo);
+			if (*infotype == SCTP_RECVV_NOINFO) {
+				if (_infolen < len)
+					break;
+				memcpy(info, CMSG_DATA(cmsg), len);
+				*infotype = SCTP_RECVV_NXTINFO;
+				*infolen = len;
+			} else if (*infotype == SCTP_RECVV_RCVINFO) {
+				if (_infolen < len +
+					       sizeof(struct sctp_rcvinfo))
+					break;
+				memcpy(info + sizeof(struct sctp_rcvinfo),
+				       CMSG_DATA(cmsg), len);
+				*infotype = SCTP_RECVV_RN;
+				*infolen = len + sizeof(struct sctp_rcvinfo);
+			} else {
+				break;
+			}
+		}
+	}
+
+	return error;
+}
+#endif
diff --git a/src/lib/sendmsg.c b/src/lib/sendmsg.c
new file mode 100644
index 0000000..4c90b07
--- /dev/null
+++ b/src/lib/sendmsg.c
@@ -0,0 +1,239 @@
+/* SCTP kernel Implementation: User API extensions.
+ *
+ * sendmsg.c
+ *
+ * Distributed under the terms of the LGPL v2.1 as described in
+ *    http://www.gnu.org/copyleft/lesser.txt 
+ *
+ * This file is part of the user library that offers support for the
+ * SCTP kernel Implementation. The main purpose of this
+ * code is to provide the SCTP Socket API mappings for user
+ * application to interface with the SCTP in kernel.
+ *
+ * This implementation is based on the Socket API Extensions for SCTP
+ * defined in <draft-ietf-tsvwg-sctpsocket-10.txt>
+ *
+ * Copyright (c) 2003 Intel Corp.
+ *
+ * Written or modified by:
+ *  Ardelle Fan     <ardelle.fan@intel.com>
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <netinet/in.h>
+#include <sys/socket.h>   /* struct sockaddr_storage, setsockopt() */
+#include <netinet/sctp.h>
+
+/* This library function assists the user with the advanced features
+ * of SCTP.  This is a new SCTP API described in the section 8.7 of the
+ * Sockets API Extensions for SCTP. This is implemented using the
+ * sendmsg() interface.
+ */
+int
+sctp_sendmsg(int s, const void *msg, size_t len, struct sockaddr *to,
+	     socklen_t tolen, uint32_t ppid, uint32_t flags,
+	     uint16_t stream_no, uint32_t timetolive, uint32_t context)
+{
+	struct msghdr outmsg;
+	struct iovec iov;
+	char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+	struct cmsghdr *cmsg;
+	struct sctp_sndrcvinfo *sinfo;
+
+	outmsg.msg_name = to;
+	outmsg.msg_namelen = tolen;
+	outmsg.msg_iov = &iov;
+	iov.iov_base = (void *)msg;
+	iov.iov_len = len;
+	outmsg.msg_iovlen = 1;
+
+	outmsg.msg_control = outcmsg;
+	outmsg.msg_controllen = sizeof(outcmsg);
+	outmsg.msg_flags = 0;
+
+	cmsg = CMSG_FIRSTHDR(&outmsg);
+	cmsg->cmsg_level = IPPROTO_SCTP;
+	cmsg->cmsg_type = SCTP_SNDRCV;
+	cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+
+	outmsg.msg_controllen = cmsg->cmsg_len;
+	sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+	memset(sinfo, 0, sizeof(struct sctp_sndrcvinfo));
+	sinfo->sinfo_ppid = ppid;
+	sinfo->sinfo_flags = flags;
+	sinfo->sinfo_stream = stream_no;
+	sinfo->sinfo_timetolive = timetolive;
+	sinfo->sinfo_context = context;
+
+	return sendmsg(s, &outmsg, 0);
+}
+
+/* This library function assist the user with sending a message without
+ * dealing directly with the CMSG header.
+ */
+int
+sctp_send(int s, const void *msg, size_t len,
+          const struct sctp_sndrcvinfo *sinfo, int flags)
+{
+	struct msghdr outmsg;
+	struct iovec iov;
+	char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+
+	outmsg.msg_name = NULL;
+	outmsg.msg_namelen = 0;
+	outmsg.msg_iov = &iov;
+	iov.iov_base = (void *)msg;
+	iov.iov_len = len;
+	outmsg.msg_iovlen = 1;
+	outmsg.msg_control = NULL;
+	outmsg.msg_controllen = 0;
+
+	if (sinfo) {	
+		struct cmsghdr *cmsg;
+
+		outmsg.msg_control = outcmsg;
+		outmsg.msg_controllen = sizeof(outcmsg);
+		outmsg.msg_flags = 0;
+
+		cmsg = CMSG_FIRSTHDR(&outmsg);
+		cmsg->cmsg_level = IPPROTO_SCTP;
+		cmsg->cmsg_type = SCTP_SNDRCV;
+		cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+
+		outmsg.msg_controllen = cmsg->cmsg_len;
+		memcpy(CMSG_DATA(cmsg), sinfo, sizeof(struct sctp_sndrcvinfo));
+	}
+
+	return sendmsg(s, &outmsg, flags);
+}
+
+#ifdef HAVE_SCTP_SENDV
+static struct cmsghdr *sctp_sendv_store_cmsg(struct cmsghdr *cmsg, int *cmsglen,
+					     int type, int len, void *data)
+{
+	cmsg->cmsg_level = IPPROTO_SCTP;
+	cmsg->cmsg_type = type;
+	cmsg->cmsg_len = CMSG_LEN(len);
+	memcpy(CMSG_DATA(cmsg), data, len);
+
+	*cmsglen += CMSG_SPACE(len);
+
+	return (struct cmsghdr *)((char *)cmsg + CMSG_SPACE(len));
+}
+
+int sctp_sendv(int s, const struct iovec *iov, int iovcnt,
+	       struct sockaddr *addrs, int addrcnt, void *info,
+	       socklen_t infolen, unsigned int infotype, int flags)
+{
+	char _cmsg[CMSG_SPACE(sizeof(struct sctp_sendv_spa))];
+	struct cmsghdr *cmsg = (struct cmsghdr *)_cmsg;
+	struct sockaddr *addr;
+	struct msghdr outmsg;
+	int len, cmsglen = 0;
+	int err, type, i;
+	char *addrbuf;
+
+	/* set msg_iov, msg_iovlen, msg_flags */
+	memset(&outmsg, 0x00, sizeof(outmsg));
+	outmsg.msg_iov = (struct iovec *)iov;
+	outmsg.msg_iovlen = iovcnt;
+	outmsg.msg_flags = flags;
+
+	/* set msg_name and msg_namelen */
+	if (addrs && addrcnt) {
+		outmsg.msg_name = addrs;
+		if (addrs->sa_family == AF_INET)
+			outmsg.msg_namelen = sizeof(struct sockaddr_in);
+		else if (addrs->sa_family == AF_INET6)
+			outmsg.msg_namelen = sizeof(struct sockaddr_in6);
+		else
+			return -EINVAL;
+		addrcnt -= 1;
+		addrbuf = (char *)addrs;
+		addrs = (struct sockaddr *)(addrbuf + outmsg.msg_namelen);
+	}
+
+	/* alloc memory only when it's multi-address */
+	if (addrcnt) {
+		len = CMSG_SPACE(sizeof(struct sockaddr_in6)) * addrcnt;
+		cmsg = malloc(sizeof(_cmsg) + len);
+		if (!cmsg)
+			return -ENOMEM;
+	}
+
+	outmsg.msg_control = cmsg;
+
+	/* add cmsg info for addr info */
+	for (i = 0, addrbuf = (char *)addrs; i < addrcnt; i++) {
+		void *ainfo;
+
+		addr = (struct sockaddr *)addrbuf;
+		if (addr->sa_family == AF_INET) {
+			struct sockaddr_in *a = (struct sockaddr_in *)addrbuf;
+
+			len = sizeof(struct in_addr);
+			type = SCTP_DSTADDRV4;
+			ainfo = &a->sin_addr;
+			addrbuf += sizeof(*a);
+		} else if (addr->sa_family == AF_INET6) {
+			struct sockaddr_in6 *a = (struct sockaddr_in6 *)addrbuf;
+
+			len = sizeof(struct in6_addr);
+			type = SCTP_DSTADDRV6;
+			ainfo = &a->sin6_addr;
+			addrbuf += sizeof(*a);
+		} else {
+			free(outmsg.msg_control);
+			return -EINVAL;
+		}
+
+		cmsg = sctp_sendv_store_cmsg(cmsg, &cmsglen, type, len, ainfo);
+	}
+	/* add cmsg info for addr info for snd/pr/auth info */
+	if (infotype == SCTP_SENDV_SPA) {
+		struct sctp_sendv_spa *spa = info;
+
+		if (spa->sendv_flags & SCTP_SEND_SNDINFO_VALID) {
+			type = SCTP_SNDINFO;
+			len = sizeof(struct sctp_sndinfo);
+			cmsg = sctp_sendv_store_cmsg(cmsg, &cmsglen, type, len,
+						     &spa->sendv_sndinfo);
+		}
+		if (spa->sendv_flags & SCTP_SEND_PRINFO_VALID) {
+			type = SCTP_PRINFO;
+			len = sizeof(struct sctp_prinfo);
+			cmsg = sctp_sendv_store_cmsg(cmsg, &cmsglen, type, len,
+						     &spa->sendv_prinfo);
+		}
+		if (spa->sendv_flags & SCTP_SEND_AUTHINFO_VALID) {
+			type = SCTP_AUTHINFO;
+			len = sizeof(struct sctp_authinfo);
+			sctp_sendv_store_cmsg(cmsg, &cmsglen, type, len,
+					      &spa->sendv_authinfo);
+		}
+	} else if (infotype == SCTP_SENDV_SNDINFO) {
+		type = SCTP_SNDINFO;
+		len = sizeof(struct sctp_sndinfo);
+		sctp_sendv_store_cmsg(cmsg, &cmsglen, type, len, info);
+	} else if (infotype == SCTP_SENDV_PRINFO) {
+		type = SCTP_PRINFO;
+		len = sizeof(struct sctp_prinfo);
+		sctp_sendv_store_cmsg(cmsg, &cmsglen, type, len, info);
+	} else if (infotype == SCTP_SENDV_AUTHINFO) {
+		type = SCTP_AUTHINFO;
+		len = sizeof(struct sctp_authinfo);
+		sctp_sendv_store_cmsg(cmsg, &cmsglen, type, len, info);
+	}
+
+	outmsg.msg_controllen = cmsglen;
+
+	err = sendmsg(s, &outmsg, 0);
+
+	if (outmsg.msg_control != _cmsg)
+		free(outmsg.msg_control);
+
+	return err;
+}
+#endif
diff --git a/src/testlib/Makefile.am b/src/testlib/Makefile.am
new file mode 100644
index 0000000..b949611
--- /dev/null
+++ b/src/testlib/Makefile.am
@@ -0,0 +1,12 @@
+# Include these two in all the Makefile.am's!!!
+include $(top_srcdir)/Makefile.vars
+include $(top_srcdir)/Makefile.rules
+
+include $(top_srcdir)/Makefile.dirs
+
+# General compilation flags
+AM_CPPFLAGS = -I$(top_builddir)/src/include
+
+noinst_LTLIBRARIES = libsctputil.la
+libsctputil_la_SOURCES = sctputil.c sctputil.h
+libsctputil_la_LDFLAGS =
diff --git a/src/testlib/sctputil.c b/src/testlib/sctputil.c
new file mode 100644
index 0000000..24f305a
--- /dev/null
+++ b/src/testlib/sctputil.c
@@ -0,0 +1,417 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2001, 2003
+ * Copyright (C) 1999 Cisco
+ * Copyright (C) 1999-2000 Motorola
+ # Copyright (C) 2001 Nokia
+ * Copyright (C) 2001 La Monte H.P. Yarroll
+ * 
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ *    La Monte H.P. Yarroll <piggy@acm.org>
+ *    Narasimha Budihal <narsi@refcode.org>
+ *    Karl Knutson <karl@athena.chicago.il.us>
+ *    Jon Grimm <jgrimm@us.ibm.com>
+ *    Daisy Chang <daisyc@us.ibm.com>
+ *    Sridhar Samudrala <sri@us.ibm.com>
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h> 
+#include <errno.h>
+#include <malloc.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+
+/* This function prints the cmsg data. */
+void
+test_print_cmsg(sctp_cmsg_t type, sctp_cmsg_data_t *data)
+{
+	switch(type) {
+	case SCTP_INIT:
+		printf("INIT\n");
+		printf("   sinit_num_ostreams %d\n",
+		       data->init.sinit_num_ostreams);
+		printf("   sinit_max_instreams %d\n",
+		       data->init.sinit_max_instreams);
+		printf("   sinit_max_attempts %d\n",
+		       data->init.sinit_max_attempts);
+		printf("   sinit_max_init_timeo %d\n",
+		       data->init.sinit_max_init_timeo);
+		
+		break;
+	case SCTP_SNDRCV:
+		printf("SNDRCV\n");
+		printf("   sinfo_stream %u\n",	data->sndrcv.sinfo_stream);
+		printf("   sinfo_ssn %u\n",	data->sndrcv.sinfo_ssn);
+		printf("   sinfo_flags 0x%x\n",	data->sndrcv.sinfo_flags);
+		printf("   sinfo_ppid %u\n",	data->sndrcv.sinfo_ppid);
+		printf("   sinfo_context %x\n",	data->sndrcv.sinfo_context);
+		printf("   sinfo_tsn     %u\n",    data->sndrcv.sinfo_tsn);
+		printf("   sinfo_cumtsn  %u\n",    data->sndrcv.sinfo_cumtsn);
+		printf("   sinfo_assoc_id  %u\n", data->sndrcv.sinfo_assoc_id);
+		
+		break;
+		
+	default:
+		printf("UNKNOWN CMSG: %d\n", type);
+		break;
+	}
+}
+
+/* This function prints the message. */
+void
+test_print_message(int sk, struct msghdr *msg, size_t msg_len) 
+{
+	sctp_cmsg_data_t *data;
+	struct cmsghdr *cmsg;
+	int i;
+	int done = 0;
+	char save;
+	union sctp_notification *sn;
+
+	for (cmsg = CMSG_FIRSTHDR(msg);
+	     cmsg != NULL;
+	     cmsg = CMSG_NXTHDR(msg, cmsg)) {
+		     data = (sctp_cmsg_data_t *)CMSG_DATA(cmsg);
+		     test_print_cmsg(cmsg->cmsg_type, data);
+	}
+
+	if (!(MSG_NOTIFICATION & msg->msg_flags)) {
+		int index = 0;
+		/* Make sure that everything is printable and that we
+		 * are NUL terminated...
+		 */
+		printf("DATA(%lu):  ", msg_len);
+		while ( msg_len > 0 ) {
+			char *text;
+			int len;
+
+			text = msg->msg_iov[index].iov_base;
+			len = msg->msg_iov[index].iov_len;
+
+                        save = text[msg_len-1];
+			if ( len > msg_len ) {
+                                text[(len = msg_len) - 1] = '\0';
+                        }
+
+			if ( (msg_len -= len) > 0 ) { index++; }
+
+			for (i = 0; i < len - 1; ++i) {
+                                if (!isprint(text[i])) text[i] = '.';
+                        }
+		
+			printf("%s", text);
+			text[msg_len-1] = save;
+
+			if ( (done = !strcmp(text, "exit")) ) { break; }
+		}
+	} else {
+		printf("NOTIFICATION: ");
+		sn = (union sctp_notification *)msg->msg_iov[0].iov_base;
+		switch (sn->sn_header.sn_type) {
+		case SCTP_ASSOC_CHANGE:
+			switch (sn->sn_assoc_change.sac_state) {
+			case SCTP_COMM_UP:
+				printf("ASSOC_CHANGE - COMM_UP");
+				break;
+			case SCTP_COMM_LOST:
+				printf("ASSOC_CHANGE - COMM_LOST");
+				break;
+			case SCTP_RESTART:
+				printf("ASSOC_CHANGE - RESTART");
+				break;
+			case SCTP_SHUTDOWN_COMP:
+				printf("ASSOC_CHANGE - SHUTDOWN_COMP");
+				break;
+			case SCTP_CANT_STR_ASSOC:
+				printf("ASSOC_CHANGE - CANT_STR_ASSOC");
+				break;
+			default:
+				printf("ASSOC_CHANGE - UNEXPECTED(%d)",
+				       sn->sn_assoc_change.sac_state);
+				break;
+			}
+			break;
+		default:
+			printf("%d", sn->sn_header.sn_type);
+			break;
+		}
+	}
+
+	printf("\n");
+}
+
+/* Check if a buf/msg_flags matches a notification, its type, and possibly an
+ * additional field in the corresponding notification structure.
+ */
+void 
+test_check_buf_notification(void *buf, int datalen, int msg_flags,
+			    int expected_datalen, uint16_t expected_sn_type,
+			    uint32_t expected_additional)
+{
+	union sctp_notification *sn;
+	
+	if (!(msg_flags & MSG_NOTIFICATION))
+		tst_brkm(TBROK, tst_exit, "Got a datamsg, expecting "
+			 "notification");
+	
+	if (expected_datalen <= 0)
+		return;
+
+	if (datalen != expected_datalen)
+		tst_brkm(TBROK, tst_exit, "Got a notification of unexpected "
+			 "length:%d, expected length:%d", datalen,
+			 expected_datalen);
+		
+	sn = (union sctp_notification *)buf;
+	if (sn->sn_header.sn_type != expected_sn_type)
+		tst_brkm(TBROK, tst_exit, "Unexpected notification:%d"
+			 "expected:%d", sn->sn_header.sn_type,
+			  expected_sn_type);
+	
+	switch(sn->sn_header.sn_type){
+	case SCTP_ASSOC_CHANGE:
+		if (sn->sn_assoc_change.sac_state != expected_additional)
+			tst_brkm(TBROK, tst_exit, "Unexpected sac_state:%d "
+				 "expected:%d", sn->sn_assoc_change.sac_state,
+				  expected_additional);
+		break;
+	default:
+		break;
+	}
+}
+
+/* Check if a message matches a notification, its type, and possibly an
+ * additional field in the corresponding notification structure.
+ */
+void 
+test_check_msg_notification(struct msghdr *msg, int datalen,
+			    int expected_datalen, uint16_t expected_sn_type,
+			    uint32_t expected_additional)
+{
+	test_check_buf_notification(msg->msg_iov[0].iov_base, datalen,
+				    msg->msg_flags, expected_datalen,
+				    expected_sn_type, expected_additional);
+}
+
+/* Check if a buf/msg_flags/sinfo corresponds to data, its length, msg_flags,
+ * stream and ppid.
+ */
+void
+test_check_buf_data(void *buf, int datalen, int msg_flags,
+		    struct sctp_sndrcvinfo *sinfo, int expected_datalen,
+		    int expected_msg_flags, uint16_t expected_stream,
+		    uint32_t expected_ppid)
+{
+	if (msg_flags & MSG_NOTIFICATION)
+		tst_brkm(TBROK, tst_exit, "Got a notification, expecting a"
+			 "datamsg");
+
+	if (expected_datalen <= 0)
+		return;
+
+	if (datalen != expected_datalen)
+		tst_brkm(TBROK, tst_exit, "Got a datamsg of unexpected "
+			 "length:%d, expected length:%d", datalen,
+			 expected_datalen);
+
+	if ((msg_flags & ~0x80000000) != expected_msg_flags)
+		tst_brkm(TBROK, tst_exit, "Unexpected msg_flags:0x%x "
+			 "expecting:0x%x", msg_flags, expected_msg_flags);
+
+	if ((0 == expected_stream) && (0 == expected_ppid))
+		return; 
+
+	if (!sinfo)
+		tst_brkm(TBROK, tst_exit, "Null sinfo, but expected "
+			 "stream:%d expected ppid:%d", expected_stream,
+			 expected_ppid);
+
+	if (sinfo->sinfo_stream != expected_stream)
+		tst_brkm(TBROK, tst_exit, "stream mismatch: expected:%x "
+			 "got:%x", expected_stream, sinfo->sinfo_stream);
+	if (sinfo->sinfo_ppid != expected_ppid)
+		tst_brkm(TBROK, tst_exit, "ppid mismatch: expected:%x "
+			 "got:%x\n", expected_ppid, sinfo->sinfo_ppid);
+}
+
+/* Check if a message corresponds to data, its length, msg_flags, stream and
+ * ppid.
+ */
+void
+test_check_msg_data(struct msghdr *msg, int datalen, int expected_datalen,
+		    int expected_msg_flags, uint16_t expected_stream,
+		    uint32_t expected_ppid)
+{
+	struct cmsghdr *cmsg = NULL;
+	struct sctp_sndrcvinfo *sinfo = NULL;
+
+	/* Receive auxiliary data in msgh. */
+	for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL;
+				 cmsg = CMSG_NXTHDR(msg, cmsg)){
+		if (IPPROTO_SCTP == cmsg->cmsg_level &&
+		    SCTP_SNDRCV == cmsg->cmsg_type)
+			break;
+	} /* for( all cmsgs) */
+
+	if ((!cmsg) ||
+	    (cmsg->cmsg_len < CMSG_LEN(sizeof(struct sctp_sndrcvinfo))))
+		sinfo = NULL;
+	else
+		sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+
+	test_check_buf_data(msg->msg_iov[0].iov_base, datalen, msg->msg_flags,
+			    sinfo, expected_datalen, expected_msg_flags,
+			    expected_stream, expected_ppid);
+
+}
+
+
+/* Allocate a buffer of requested len and fill in with data. */
+void *
+test_build_msg(int len)
+{
+	int i = len - 1;
+	int n;
+	unsigned char msg[] = 
+		"012345678901234567890123456789012345678901234567890";
+	char *msg_buf, *p;
+
+	msg_buf = (char *)malloc(len);
+	if (!msg_buf)
+		tst_brkm(TBROK, tst_exit, "malloc failed");
+
+	p = msg_buf;
+
+	do {
+		n = ((i > 50)?50:i);
+		memcpy(p, msg, ((i > 50)?50:i));
+		p += n;
+		i -= n;
+	} while (i > 0); 
+
+	msg_buf[len-1] = '\0'; 
+
+	return(msg_buf);
+}
+
+/* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+void test_enable_assoc_change(int fd)
+{
+	struct sctp_event_subscribe subscribe;
+
+	memset(&subscribe, 0, sizeof(subscribe));
+	subscribe.sctp_data_io_event = 1;
+	subscribe.sctp_association_event = 1;
+	test_setsockopt(fd, SCTP_EVENTS, (char *)&subscribe,
+		        sizeof(subscribe));
+}
+
+static int cmp_addr(sockaddr_storage_t *addr1, sockaddr_storage_t *addr2)
+{
+	if (addr1->sa.sa_family != addr2->sa.sa_family)
+		return 0;
+	switch (addr1->sa.sa_family) {
+	case AF_INET6:
+		if (addr1->v6.sin6_port != addr2->v6.sin6_port)
+			return -1;
+		return memcmp(&addr1->v6.sin6_addr, &addr2->v6.sin6_addr,
+			      sizeof(addr1->v6.sin6_addr));
+	case AF_INET:
+		if (addr1->v4.sin_port != addr2->v4.sin_port)
+			return 0;
+		return memcmp(&addr1->v4.sin_addr, &addr2->v4.sin_addr,
+			      sizeof(addr1->v4.sin_addr));
+	default:
+		tst_brkm(TBROK, tst_exit, "invalid address type %d",
+			 addr1->sa.sa_family);
+		return -1;
+	}
+}
+
+/* Test peer addresses for association. */
+int test_peer_addr(int sk, sctp_assoc_t asoc, sockaddr_storage_t *peers, int count)
+{
+	struct sockaddr *addrs;
+	int error, i, j;
+	struct sockaddr *sa_addr;
+	socklen_t addrs_size = 0;
+	void *addrbuf;
+	char *found = (char *) malloc(count);
+	memset(found, 0, count);
+
+	error = sctp_getpaddrs(sk, asoc, &addrs);
+	if (-1 == error) {
+		tst_brkm(TBROK, tst_exit, "sctp_getpaddrs: %s", strerror(errno));
+		return error;
+	}
+	if (error != count) {
+		sctp_freepaddrs(addrs);
+		tst_brkm(TBROK, tst_exit, "peer count %d mismatch, expected %d",
+			 error, count);
+	}
+	addrbuf = addrs;
+	for (i = 0; i < count; i++) {
+		sa_addr = (struct sockaddr *)addrbuf;
+		switch (sa_addr->sa_family) {
+		case AF_INET:
+			addrs_size += sizeof(struct sockaddr_in);
+			addrbuf += sizeof(struct sockaddr_in);
+			break;
+		case AF_INET6:
+			addrs_size += sizeof(struct sockaddr_in6);
+			addrbuf += sizeof(struct sockaddr_in6);
+			break;
+		default:
+			errno = EINVAL;
+			sctp_freepaddrs(addrs);
+			tst_brkm(TBROK, tst_exit, "sctp_getpaddrs: %s", strerror(errno));
+			return -1;
+		}
+		for (j = 0; j < count; j++) {
+			if (cmp_addr((sockaddr_storage_t *)sa_addr,
+				     &peers[j]) == 0) {
+				found[j] = 1;
+			}
+		}
+	}
+	for (j = 0; j < count; j++) {
+		if (found[j] == 0) {
+			tst_brkm(TBROK, tst_exit, "peer address %d not found", j);
+		}
+	}
+	sctp_freepaddrs(addrs);
+	free(found);
+	return 0;
+}
diff --git a/src/testlib/sctputil.h b/src/testlib/sctputil.h
new file mode 100644
index 0000000..9dbabd4
--- /dev/null
+++ b/src/testlib/sctputil.h
@@ -0,0 +1,358 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2001, 2003
+ * Copyright (c) 1999-2000 Cisco, Inc.
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ * Copyright (c) 2001 Intel Corp.
+ * Copyright (c) 2001 Nokia, Inc.
+ * Copyright (c) 2001 La Monte H.P. Yarroll
+ * 
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ *    La Monte H.P. Yarroll <piggy@acm.org>
+ *    Karl Knutson <karl@athena.chicago.il.us>
+ *    Randall Stewart <randall@stewart.chicago.il.us>
+ *    Ken Morneau <kmorneau@cisco.com>
+ *    Qiaobing Xie <qxie1@motorola.com>
+ *    Daisy Chang <daisyc@us.ibm.com>
+ *    Jon Grimm <jgrimm@us.ibm.com>
+ *    Sridhar Samudrala <samudrala@us.ibm.com>
+ *    Hui Huang <hui.huang@nokia.com>
+ */
+
+#ifndef __sctputil_h__
+#define __sctputil_h__
+
+#ifdef LTP
+#include <test.h>
+#include <usctest.h>
+#endif
+
+#include <string.h>
+
+typedef union {
+	struct sockaddr_in v4;	
+	struct sockaddr_in6 v6;
+	struct sockaddr sa;	
+} sockaddr_storage_t;
+
+
+#define REALLY_BIG 65536
+
+/* Literal defines.  */
+#ifdef PROT_SOCK
+#define SCTP_TESTPORT_1 PROT_SOCK
+#else
+#define SCTP_TESTPORT_1 1024 
+#endif
+#define SCTP_TESTPORT_2 (SCTP_TESTPORT_1+1)
+
+#define SCTP_IP_BCAST  	htonl(0xffffffff)
+#define SCTP_IP_LOOPBACK  htonl(0x7f000001)
+
+/* These are stolen from <netinet/in.h>.  */
+#define SCTP_IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }
+#define SCTP_IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }
+
+/* Display an IPv4 address in readable format.  */
+#define NIPQUAD(addr) \
+        ((unsigned char *)&addr)[0], \
+        ((unsigned char *)&addr)[1], \
+        ((unsigned char *)&addr)[2], \
+        ((unsigned char *)&addr)[3]
+
+/* Display an IPv6 address in readable format.  */
+#define NIP6(addr) \
+        ntohs((addr).s6_addr16[0]), \
+        ntohs((addr).s6_addr16[1]), \
+        ntohs((addr).s6_addr16[2]), \
+        ntohs((addr).s6_addr16[3]), \
+        ntohs((addr).s6_addr16[4]), \
+        ntohs((addr).s6_addr16[5]), \
+        ntohs((addr).s6_addr16[6]), \
+        ntohs((addr).s6_addr16[7])
+
+#define DUMP_CORE { 					 \
+	char *diediedie = 0;				 \
+	printf("DUMP_CORE %s: %d\n", __FILE__, __LINE__);\
+	*diediedie = 0;					 \
+}
+
+#ifndef LTP
+enum {
+	TPASS,
+	TINFO,
+};
+
+extern char *TCID;
+extern int TST_TOTAL;
+extern int TST_CNT;
+
+#define tst_brkm(a1, a2, whatever...) \
+	{ \
+		printf("%s %2d BROK : ", TCID, ++TST_CNT); \
+		printf(whatever); \
+		printf("\n"); \
+		DUMP_CORE \
+	}
+#define tst_resm(a1, whatever...) \
+	{ \
+		printf("%s %2d %s : ", TCID, \
+			 (a1 == TPASS)?++TST_CNT:0, \
+			 (a1 == TPASS)?"PASS":"INFO"); \
+		printf(whatever); \
+		printf("\n"); \
+	}
+#endif
+
+static inline int test_socket(int domain, int type, int protocol)
+{
+	int sk = socket(domain, type, protocol);
+        if (-1 == sk)
+                tst_brkm(TBROK, tst_exit, "socket: %s", strerror(errno));
+	return sk;
+}
+
+static inline int test_bind(int sk, struct sockaddr *addr, socklen_t addrlen)
+{
+	int error = bind(sk, addr, addrlen);
+        if (-1 == error)
+                tst_brkm(TBROK, tst_exit, "bind: %s", strerror(errno));
+	return error;
+}
+
+static inline int test_bindx_add(int sk, struct sockaddr *addr, int count)
+{
+	int error = sctp_bindx(sk, addr, count, SCTP_BINDX_ADD_ADDR);
+        if (-1 == error)
+                tst_brkm(TBROK, tst_exit, "bindx (add): %s", strerror(errno));
+	return error;
+}
+
+static inline int test_listen(int sk, int backlog)
+{
+	int error = listen(sk, backlog);
+        if (-1 == error)
+                tst_brkm(TBROK, tst_exit, "listen: %s", strerror(errno));
+	return error;
+}
+
+static inline int test_connect(int sk, struct sockaddr *addr, socklen_t addrlen)
+{
+	int error = connect(sk, addr, addrlen);
+        if (-1 == error)
+                tst_brkm(TBROK, tst_exit, "connect: %s", strerror(errno));
+	return error;
+}
+
+static inline int test_connectx(int sk, struct sockaddr *addr, int count)
+{
+	int error = sctp_connectx(sk, addr, count, NULL);
+        if (-1 == error)
+                tst_brkm(TBROK, tst_exit, "connectx: %s", strerror(errno));
+	return error;
+}
+
+static inline int test_accept(int sk, struct sockaddr *addr, socklen_t *addrlen)
+{
+	int error = accept(sk, addr, addrlen);
+        if (-1 == error)
+                tst_brkm(TBROK, tst_exit, "accept: %s", strerror(errno));
+	return error;
+}
+
+static inline int test_send(int sk, const void *msg, size_t len, int flags)
+{
+	int error = send(sk, msg, len, flags);
+        if (len != error)
+                tst_brkm(TBROK, tst_exit, "send: error:%d errno:%d",
+			 error, errno);
+	return error;
+}
+
+static inline int test_sendto(int sk, const void *msg, size_t len, int flags,
+			      const struct sockaddr *to, socklen_t tolen)
+{
+	int error = sendto(sk, msg, len, flags, to, tolen);
+        if (len != error)
+                tst_brkm(TBROK, tst_exit, "sendto: error:%d errno:%d",
+			 error, errno);
+	return error;
+}
+
+static inline int test_sendmsg(int sk, const struct msghdr *msg, int flags,
+			       int msglen)
+{
+	int error = sendmsg(sk, msg, flags);
+        if (msglen != error)
+                tst_brkm(TBROK, tst_exit, "sendmsg: error:%d errno:%d",
+			 error, errno);
+	return error;
+}
+
+static inline int test_recv(int sk, void *buf, size_t len, int flags)
+{
+	int error = recv(sk, buf, len, flags);
+        if (-1 == error)
+                tst_brkm(TBROK, tst_exit, "recv: %s", strerror(errno));
+	return error;
+}
+
+static inline int test_recvmsg(int sk, struct msghdr *msg, int flags)
+{
+	int error = recvmsg(sk, msg, flags);
+        if (-1 == error)
+                tst_brkm(TBROK, tst_exit, "recvmsg: %s", strerror(errno));
+	return error;
+}
+
+static inline int test_shutdown(int sk, int how)
+{
+	int error = shutdown(sk, how);
+        if (-1 == error)
+                tst_brkm(TBROK, tst_exit, "shutdown: %s", strerror(errno));
+	return error;
+}
+
+static inline int test_getsockopt(int sk, int optname, void *optval,
+				  socklen_t *optlen)
+{
+	int error = getsockopt(sk, SOL_SCTP, optname, optval, optlen);
+	if (error)
+		tst_brkm(TBROK, tst_exit, "getsockopt(%d): %s", optname,
+			 strerror(errno));
+	return error;
+}
+
+static inline int test_setsockopt(int sk, int optname, const void *optval,
+				  socklen_t optlen)
+{
+	int error = setsockopt(sk, SOL_SCTP, optname, optval, optlen);
+	if (error)
+		tst_brkm(TBROK, tst_exit, "setsockopt(%d): %s", optname,
+			 strerror(errno));
+	return error;
+}
+
+static inline int test_sctp_peeloff(int sk, sctp_assoc_t assoc_id)
+{
+	int error = sctp_peeloff(sk, assoc_id);
+        if (-1 == error)
+                tst_brkm(TBROK, tst_exit, "sctp_peeloff: %s", strerror(errno));
+	return error;
+}
+
+static inline int test_sctp_sendmsg(int s, const void *msg, size_t len,
+				    struct sockaddr *to, socklen_t tolen,
+				    uint32_t ppid, uint32_t flags,
+				    uint16_t stream_no, uint32_t timetolive,
+				    uint32_t context)
+{
+	int error = sctp_sendmsg(s, msg, len, to, tolen, ppid, flags, stream_no,
+	  		         timetolive, context);
+	if (len != error)
+		tst_brkm(TBROK, tst_exit, "sctp_sendmsg: error:%d errno:%d",
+			 error, errno);
+	return error;			
+}
+
+static inline int test_sctp_send(int s, const void *msg, size_t len,
+				 const struct sctp_sndrcvinfo *sinfo, 
+				 int flags)
+{
+	int error = sctp_send(s, msg, len, sinfo, flags);
+	if (len != error)
+		tst_brkm(TBROK, tst_exit, "sctp_send: error:%d errno:%d",
+			 error, errno);
+	return error;			
+}
+
+#ifdef HAVE_SCTP_SENDV
+static inline int test_sctp_sendv(int s, const struct iovec *iov, int iovcnt,
+				  struct sockaddr *addrs, int addrcnt,
+				  void *info, socklen_t infolen,
+				  unsigned int infotype, int flags)
+{
+	int error = sctp_sendv(s, iov, iovcnt, addrs, addrcnt, info, infolen,
+			       infotype, flags);
+	int i, tlen = 0;
+
+	for (i = 0; i < iovcnt; i++)
+		tlen += iov->iov_len;
+
+	if (tlen != error)
+		tst_brkm(TBROK, tst_exit, "sctp_sendv: error:%d errno:%d",
+			 error, errno);
+	return error;
+}
+#endif
+
+static inline int test_sctp_recvmsg(int sk, void *msg, size_t len,
+				    struct sockaddr *from, socklen_t *fromlen,
+				    struct sctp_sndrcvinfo *sinfo,
+				    int *msg_flags)
+{
+	int error = sctp_recvmsg(sk, msg, len, from, fromlen, sinfo, msg_flags);
+	if (-1 == error)
+		tst_brkm(TBROK, tst_exit, "sctp_recvmsg: %s", strerror(errno));
+	return error;			
+}
+
+#ifdef HAVE_SCTP_SENDV
+static inline int test_sctp_recvv(int s, const struct iovec *iov, int iovlen,
+				  struct sockaddr *from, socklen_t *fromlen,
+				  void *info, socklen_t *infolen,
+				  unsigned int *infotype, int *flags)
+{
+	int error = sctp_recvv(s, iov, iovlen, from, fromlen, info, infolen,
+			       infotype, flags);
+	if (-1 == error)
+		tst_brkm(TBROK, tst_exit, "sctp_recvmsg: %s", strerror(errno));
+	return error;
+}
+#endif
+
+static inline void *test_malloc(size_t size)
+{
+	void *buf = malloc(size);
+        if (NULL == buf)
+                tst_brkm(TBROK, tst_exit, "malloc failed");
+	return buf;
+}
+
+void test_check_msg_notification(struct msghdr *, int, int, uint16_t, uint32_t);
+void test_check_buf_notification(void *, int, int, int, uint16_t, uint32_t);
+void test_check_msg_data(struct msghdr *, int, int, int, uint16_t, uint32_t);
+void test_check_buf_data(void *, int, int, struct sctp_sndrcvinfo *, int, int,
+			 uint16_t, uint32_t);
+void *test_build_msg(int);
+void test_enable_assoc_change(int);
+void test_print_message(int sk, struct msghdr *msg, size_t msg_len);
+int test_peer_addr(int sk, sctp_assoc_t asoc, sockaddr_storage_t *peers, int count);
+
+#endif /* __sctputil_h__ */
diff --git a/src/withsctp/.gitignore b/src/withsctp/.gitignore
new file mode 100644
index 0000000..498e578
--- /dev/null
+++ b/src/withsctp/.gitignore
@@ -0,0 +1,2 @@
+checksctp
+withsctp
diff --git a/src/withsctp/Makefile.am b/src/withsctp/Makefile.am
new file mode 100644
index 0000000..3157588
--- /dev/null
+++ b/src/withsctp/Makefile.am
@@ -0,0 +1,28 @@
+# -*- Makefile -*-
+#
+# The author (La Monte H.P. Yarroll) disclaims copyright on this file.
+#
+
+include $(top_srcdir)/Makefile.vars
+include $(top_srcdir)/Makefile.dirs
+include $(top_srcdir)/Makefile.rules
+
+bin_PROGRAMS = checksctp
+bin_SCRIPTS = withsctp
+
+AM_CPPFLAGS=-I$(top_builddir)/src/include
+pkglib_LTLIBRARIES = libwithsctp.la
+libwithsctp_la_SOURCES = sctp_load_libs.c sctp_socket.c sctp_bind.c \
+	sctp_sockopt.c sctp_socket.h
+libwithsctp_la_LDFLAGS = -version-info \
+	@LIBWITHSCTP_CURRENT@:@LIBWITHSCTP_REVISION@:@LIBWITHSCTP_AGE@ -ldl
+
+pkgdoc_DATA = sctp_load_libs.c sctp_socket.c sctp_bind.c \
+	sctp_sockopt.c sctp_socket.h checksctp.c
+
+withsctp: withsctp.in
+	$(edit) $< >$@
+
+EXTRA_DIST += withsctp.in
+
+CLEANFILES += withsctp
diff --git a/src/withsctp/README b/src/withsctp/README
new file mode 100644
index 0000000..c7d8b97
--- /dev/null
+++ b/src/withsctp/README
@@ -0,0 +1,15 @@
+This is a package to let you use SCTP with your existing TCP-based binaries.
+
+usage:
+
+$ withsctp xinetd	# Start xinetd stream services on SCTP.
+$ withsctp telnet localhost	# Make a telnet over SCTP/IP connection.
+
+To install, edit the top of Makefile to set your install path(s) and then
+
+$ make all
+# make install
+
+This package originally written by La Monte H.P. Yarroll <piggy@acm.org>.
+To submit fixes or bug reports see lksctp.sourceforget.net.
+You can try the author or lksctp-developers@lists.sourceforget.net for support.
diff --git a/src/withsctp/checksctp.c b/src/withsctp/checksctp.c
new file mode 100644
index 0000000..bda9c1d
--- /dev/null
+++ b/src/withsctp/checksctp.c
@@ -0,0 +1,58 @@
+/* Does this host have SCTP?
+ *
+ * Copyright 2003 La Monte HP Yarroll <piggy@acm.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer. 
+ *    2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with
+ * the distribution.
+ *    3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+/* IPPROTO_SCTP SHOULD be defined in
+ * /usr/include/linux/in.h but probably isn't.
+ * It is an enum element, not a #define, so we can't easily check.
+ */
+#define SHOULD_IPPROTO_SCTP 132
+
+int main(void)
+{
+    int fd;
+
+    fd = socket(PF_INET, SOCK_STREAM, SHOULD_IPPROTO_SCTP);
+
+    if (fd <= 0) {
+	perror("checksctp");
+	exit(1);
+    } else {
+	fprintf(stderr, "SCTP supported\n");
+    }
+
+    close(fd);
+    return 0;
+}
diff --git a/src/withsctp/notes.txt b/src/withsctp/notes.txt
new file mode 100644
index 0000000..ef532ec
--- /dev/null
+++ b/src/withsctp/notes.txt
@@ -0,0 +1,6 @@
+Fri Dec 26 16:20:36 EST 2003
+
+It would be nice for withsctp to provide more facilities.
+
+Perhaps we could capture the bind call and allow substitution such as the
+arguments to sctp_darn.
diff --git a/src/withsctp/sctp_bind.c b/src/withsctp/sctp_bind.c
new file mode 100644
index 0000000..e744273
--- /dev/null
+++ b/src/withsctp/sctp_bind.c
@@ -0,0 +1,58 @@
+/* Wrap bind() to force the protocol for STREAM connections to SCTP.
+ * 
+ * Thanks to Midgard Security Services for
+ * http://www.securiteam.com/tools/3D5PTR5QAE.html
+ * from whence I cribbed the code to find the old bind().
+ * 
+ * gcc sctp_socket.c sctp_bind.c -o sctp_socket.so -ldl -shared -O2 -s
+ * export LD_PRELOAD=./sctp_socket.so
+ * 
+ * Copyright 2003 La Monte HP Yarroll <piggy@acm.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer. 
+ *    2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with
+ * the distribution.
+ *    3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 <string.h> /* for strncmp() */
+#include <stdio.h>
+#include "sctp_socket.h"
+
+/* IPPROTO_SCTP SHOULD be defined in
+ * /usr/include/linux/in.h but probably isn't.
+ * It is an enum element, not a #define, so we can't easily check.
+ */
+#define SHOULD_IPPROTO_SCTP 132
+
+int
+bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen)
+{
+    _sctp_load_libs();
+
+    /* STUB.  The intent is to allow us to substitute an elaborate call to
+     * bindx() for the initial call to bind().  TBD.
+     */
+
+    return (real_bind)(sockfd, my_addr, addrlen);
+}
diff --git a/src/withsctp/sctp_load_libs.c b/src/withsctp/sctp_load_libs.c
new file mode 100644
index 0000000..d6a521f
--- /dev/null
+++ b/src/withsctp/sctp_load_libs.c
@@ -0,0 +1,67 @@
+/* Load the real underlying functions for withsctp and related scripts.
+ *
+ * Copyright 2003 La Monte HP Yarroll <piggy@acm.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer. 
+ *    2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with
+ * the distribution.
+ *    3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include "sctp_socket.h"
+
+int (*real_bind)(int  sockfd, const struct sockaddr *my_addr, socklen_t addrlen);
+int (*real_socket)(int domain, int type, int protocol);
+int (*real_setsockopt)(int s, int level, int optname, const void *optval,
+		       socklen_t optlen);	
+static void *lib_handle = NULL;
+
+void
+_sctp_load_libs(void)
+{
+    if (NULL != lib_handle) return; /* Only init once.  */
+
+    if (!(lib_handle = dlopen("libc.so", RTLD_LAZY))) {
+	if (!(lib_handle = dlopen("libc.so.6", RTLD_LAZY))) {
+	    fprintf(stderr, "error loading libc!\n");
+	    exit (1);
+	}
+    }
+    
+    if (!(real_socket = dlsym(lib_handle, "socket"))) {
+	fprintf(stderr, "socket() not found in libc!\n");
+	exit (1);
+    }
+
+    if (!(real_bind = dlsym(lib_handle, "bind"))) {
+	fprintf(stderr, "bind() not found in libc!\n");
+	exit (1);
+    }
+
+    if (!(real_setsockopt = dlsym(lib_handle, "setsockopt"))) {
+	fprintf(stderr, "setsockopt() not found in libc!\n");
+	exit (1);
+    }
+}
diff --git a/src/withsctp/sctp_socket.c b/src/withsctp/sctp_socket.c
new file mode 100644
index 0000000..37d73af
--- /dev/null
+++ b/src/withsctp/sctp_socket.c
@@ -0,0 +1,59 @@
+/* Wrap socket() to force the protocol to SCTP for STREAM connections.
+ * 
+ * Thanks to Midgard Security Services for
+ * http://www.securiteam.com/tools/3D5PTR5QAE.html
+ * from whence I cribbed the code to find the old socket().
+ * 
+ * gcc sctp_socket.c -o sctp_socket.so -ldl -shared -O2 -s
+ * export LD_PRELOAD=./sctp_socket.so
+ * 
+ * Copyright 2003 La Monte HP Yarroll <piggy@acm.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer. 
+ *    2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with
+ * the distribution.
+ *    3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 <string.h> /* for strncmp() */
+#include <stdio.h>
+#include "sctp_socket.h"
+
+/* IPPROTO_SCTP SHOULD be defined in
+ * /usr/include/linux/in.h but probably isn't.
+ * It is an enum element, not a #define, so we can't easily check.
+ */
+#define SHOULD_IPPROTO_SCTP 132
+
+int 
+socket(int domain, int type, int protocol)
+{
+    _sctp_load_libs();
+
+    if (((PF_INET == domain) || (PF_INET6 == domain))
+	&& (SOCK_STREAM == type)) {
+	protocol = SHOULD_IPPROTO_SCTP;
+    }
+
+    return (real_socket)(domain, type, protocol);
+}
diff --git a/src/withsctp/sctp_socket.h b/src/withsctp/sctp_socket.h
new file mode 100644
index 0000000..44c8226
--- /dev/null
+++ b/src/withsctp/sctp_socket.h
@@ -0,0 +1,69 @@
+/* Preprocessor definitions for withsctp and supporting scripts.
+ *
+ * Copyright 2003 La Monte HP Yarroll <piggy@acm.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer. 
+ *    2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with
+ * the distribution.
+ *    3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. 
+ * Copyright 2003 La Monte HP Yarroll <piggy@acm.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer. 
+ *    2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with
+ * the distribution.
+ *    3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 <dlfcn.h> /* for dlopen() and company */
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/sctp.h>
+#include <netinet/tcp.h>
+
+extern int (*real_bind)(int  sockfd, const struct sockaddr *my_addr, socklen_t addrlen);
+extern int (*real_socket)(int domain, int type, int protocol);
+extern int (*real_setsockopt)(int s, int level, int optname, const void *optval,
+			      socklen_t optlen);
+extern void _sctp_load_libs(void);
diff --git a/src/withsctp/sctp_sockopt.c b/src/withsctp/sctp_sockopt.c
new file mode 100644
index 0000000..01b8308
--- /dev/null
+++ b/src/withsctp/sctp_sockopt.c
@@ -0,0 +1,56 @@
+/* Wrap socket() to force the protocol to SCTP for STREAM connections.
+ * 
+ * Thanks to Midgard Security Services for
+ * http://www.securiteam.com/tools/3D5PTR5QAE.html
+ * from whence I cribbed the code to find the old socket().
+ * 
+ * Copyright 2003 La Monte HP Yarroll <piggy@acm.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer. 
+ *    2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with
+ * the distribution.
+ *    3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 <string.h> /* for strncmp() */
+#include <stdio.h>
+#include "sctp_socket.h"
+
+/* IPPROTO_SCTP SHOULD be defined in
+ * /usr/include/linux/in.h but probably isn't.
+ * It is an enum element, not a #define, so we can't easily check.
+ */
+#define SHOULD_IPPROTO_SCTP 132
+
+int 
+setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen)
+{
+    _sctp_load_libs();
+
+    if ((IPPROTO_TCP == level) && (TCP_NODELAY == optname)) {
+	level = SHOULD_IPPROTO_SCTP;
+	optname = SCTP_NODELAY;
+    }
+
+    return (real_setsockopt)(s, level, optname, optval, optlen);
+}
diff --git a/src/withsctp/withsctp.in b/src/withsctp/withsctp.in
new file mode 100644
index 0000000..ef4f7bb
--- /dev/null
+++ b/src/withsctp/withsctp.in
@@ -0,0 +1,13 @@
+#!/bin/sh
+# -*- sh -*-
+LIBDIR=@libdir@/@PACKAGE@
+BINDIR=@bindir@
+LIBVER=@LIBWITHSCTP_CURRENT@.@LIBWITHSCTP_AGE@.@LIBWITHSCTP_REVISION@
+export LD_PRELOAD=${LIBDIR}/libwithsctp.so.${LIBVER}
+if ! ${BINDIR}/checksctp 2> /dev/null
+then
+    ${BINDIR}/checksctp;
+    exit 1;
+fi
+
+exec "$@"
diff --git a/stamp-h.in b/stamp-h.in
new file mode 100644
index 0000000..9788f70
--- /dev/null
+++ b/stamp-h.in
@@ -0,0 +1 @@
+timestamp