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