netcat with SCTP support

From: Martin Kulas <coolaz_at_web.de>
Date: Mon, 9 Apr 2007 23:45:04 +0200
Hello!

I am running -CURRENT and I am happy to have SCTP support.  I wrote a patch
for netcat so I can experiment with SCTP.  The patch opens a SCTP socket
in one-to-one style. 
But there is a problem I could not solve: If I open an SCTP listening socket 
with netcat and connect to it with netcat, data transfer works correctly.  When I
kill the client process, the server process does not react on the
SHUTDOWN-chunk sent to it: poll() does not notify the process that the
association has been closed.  Using TCP poll() works correctly.
Does anyone know how to solve this problem?

Thanks in advance,
Martin

<patch>
--- netcat.c.orig	Fri Mar 30 21:58:02 2007
+++ netcat.c	Mon Apr  9 16:59:21 2007
_at__at_ -44,6 +44,7 _at__at_
 #ifdef IPSEC
 #include <netinet6/ipsec.h>
 #endif
+#include <netinet/sctp.h>
 #include <netinet/tcp.h>
 #include <netinet/ip.h>
 #include <arpa/telnet.h>
_at__at_ -71,6 +72,7 _at__at_
 
 /* Command Line Options */
 int	Eflag;					/* Use IPsec ESP */
+int	cflag;					/* Use SCTP */
 int	dflag;					/* detached, no stdin */
 unsigned int iflag;				/* Interval Flag */
 int	jflag;					/* use jumbo frames if we can */
_at__at_ -138,8 +140,11 _at__at_
 	sv = NULL;
 
 	while ((ch = getopt(argc, argv,
-	    "46e:DEdhi:jklnoP:p:rSs:tT:Uuvw:X:x:z")) != -1) {
+	    "c46e:DEdhi:jklnoP:p:rSs:tT:Uuvw:X:x:z")) != -1) {
 		switch (ch) {
+		case 'c':
+			cflag = 1;
+			break;
 		case '4':
 			family = AF_INET;
 			break;
_at__at_ -257,6 +262,8 _at__at_
 	if (argv[0] && !argv[1] && family == AF_UNIX) {
 		if (uflag)
 			errx(1, "cannot use -u and -U");
+		if (cflag)
+			errx(1, "cannot use -c and -U");
 		host = argv[0];
 		uport = NULL;
 	} else if (argv[0] && !argv[1]) {
_at__at_ -283,13 +290,23 _at__at_
 	if (family != AF_UNIX) {
 		memset(&hints, 0, sizeof(struct addrinfo));
 		hints.ai_family = family;
-		hints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM;
-		hints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP;
+		if (cflag) {
+		    hints.ai_socktype = SOCK_STREAM;
+		    // XXX IPPROTO_SCTP not supported form getaddrinfo
+		} else {
+		    hints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM;
+		    hints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP;
+		}
 		if (nflag)
 			hints.ai_flags |= AI_NUMERICHOST;
 	}
 
+	if ( cflag && uflag )
+	    errx(1, "cannot use -c and -u");
+
 	if (xflag) {
+		if (cflag)
+			errx(1, "no proxy support for SCTP mode");
 		if (uflag)
 			errx(1, "no proxy support for UDP mode");
 
_at__at_ -418,7 +435,7 _at__at_
 				}
 
 				printf("Connection to %s %s port [%s/%s] succeeded!\n",
-				    host, portlist[i], uflag ? "udp" : "tcp",
+				    host, portlist[i], uflag ? "udp" : (cflag ? "sctp" : "tcp"),
 				    sv ? sv->s_name : "*");
 			}
 			if (!zflag)
_at__at_ -515,9 +532,15 _at__at_
 
 	res0 = res;
 	do {
-		if ((s = socket(res0->ai_family, res0->ai_socktype,
-		    res0->ai_protocol)) < 0)
-			continue;
+		if (cflag) {
+			if ((s = socket(res0->ai_family, res0->ai_socktype,
+			    IPPROTO_SCTP)) < 0)
+				continue;
+		} else {
+			if ((s = socket(res0->ai_family, res0->ai_socktype,
+			    res0->ai_protocol)) < 0)
+				continue;
+		}
 #ifdef IPSEC
 		if (ipsec_policy[0] != NULL)
 			add_ipsec_policy(s, ipsec_policy[0]);
_at__at_ -532,7 +555,8 _at__at_
 			memset(&ahints, 0, sizeof(struct addrinfo));
 			ahints.ai_family = res0->ai_family;
 			ahints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM;
-			ahints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP;
+			if (!cflag)
+			    ahints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP;
 			ahints.ai_flags = AI_PASSIVE;
 			if ((error = getaddrinfo(sflag, pflag, &ahints, &ares)))
 				errx(1, "getaddrinfo: %s", gai_strerror(error));
_at__at_ -549,7 +573,7 _at__at_
 			break;
 		else if (vflag)
 			warn("connect to %s port %s (%s) failed", host, port,
-			    uflag ? "udp" : "tcp");
+			    uflag ? "udp" : (cflag ? "sctp" : "tcp") );
 
 		close(s);
 		s = -1;
_at__at_ -587,10 +611,15 _at__at_
 
 	res0 = res;
 	do {
-		if ((s = socket(res0->ai_family, res0->ai_socktype,
-		    res0->ai_protocol)) < 0)
-			continue;
-
+		if (cflag) {
+		    if ((s = socket(res0->ai_family, res0->ai_socktype,
+			IPPROTO_SCTP)) < 0)
+			    continue;
+		} else {
+		    if ((s = socket(res0->ai_family, res0->ai_socktype,
+			res0->ai_protocol)) < 0)
+			    continue;
+		}
 		ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x));
 		if (ret == -1)
 			err(1, NULL);
</patch>
-- 
PGP Key: http://www.stud.uni-hamburg.de/~kulas/mkulas_pubkey.asc

Received on Mon Apr 09 2007 - 20:15:49 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:08 UTC