Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 9 Apr 2007 23:45:04 +0200
From:      Martin Kulas <coolaz@web.de>
To:        freebsd-current@freebsd.org
Subject:   netcat with SCTP support
Message-ID:  <20070409214504.GA1780@thunderbird.tld>

next in thread | raw e-mail | index | archive | help

--DocE+STaALJfprDB
Content-Type: text/plain; charset=iso-8859-1
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

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.=20
But there is a problem I could not solve: If I open an SCTP listening socke=
t=20
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
@@ -44,6 +44,7 @@
 #ifdef IPSEC
 #include <netinet6/ipsec.h>
 #endif
+#include <netinet/sctp.h>
 #include <netinet/tcp.h>
 #include <netinet/ip.h>
 #include <arpa/telnet.h>
@@ -71,6 +72,7 @@
=20
 /* 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 */
@@ -138,8 +140,11 @@
 	sv =3D NULL;
=20
 	while ((ch =3D getopt(argc, argv,
-	    "46e:DEdhi:jklnoP:p:rSs:tT:Uuvw:X:x:z")) !=3D -1) {
+	    "c46e:DEdhi:jklnoP:p:rSs:tT:Uuvw:X:x:z")) !=3D -1) {
 		switch (ch) {
+		case 'c':
+			cflag =3D 1;
+			break;
 		case '4':
 			family =3D AF_INET;
 			break;
@@ -257,6 +262,8 @@
 	if (argv[0] && !argv[1] && family =3D=3D AF_UNIX) {
 		if (uflag)
 			errx(1, "cannot use -u and -U");
+		if (cflag)
+			errx(1, "cannot use -c and -U");
 		host =3D argv[0];
 		uport =3D NULL;
 	} else if (argv[0] && !argv[1]) {
@@ -283,13 +290,23 @@
 	if (family !=3D AF_UNIX) {
 		memset(&hints, 0, sizeof(struct addrinfo));
 		hints.ai_family =3D family;
-		hints.ai_socktype =3D uflag ? SOCK_DGRAM : SOCK_STREAM;
-		hints.ai_protocol =3D uflag ? IPPROTO_UDP : IPPROTO_TCP;
+		if (cflag) {
+		    hints.ai_socktype =3D SOCK_STREAM;
+		    // XXX IPPROTO_SCTP not supported form getaddrinfo
+		} else {
+		    hints.ai_socktype =3D uflag ? SOCK_DGRAM : SOCK_STREAM;
+		    hints.ai_protocol =3D uflag ? IPPROTO_UDP : IPPROTO_TCP;
+		}
 		if (nflag)
 			hints.ai_flags |=3D AI_NUMERICHOST;
 	}
=20
+	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");
=20
@@ -418,7 +435,7 @@
 				}
=20
 				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)
@@ -515,9 +532,15 @@
=20
 	res0 =3D res;
 	do {
-		if ((s =3D socket(res0->ai_family, res0->ai_socktype,
-		    res0->ai_protocol)) < 0)
-			continue;
+		if (cflag) {
+			if ((s =3D socket(res0->ai_family, res0->ai_socktype,
+			    IPPROTO_SCTP)) < 0)
+				continue;
+		} else {
+			if ((s =3D socket(res0->ai_family, res0->ai_socktype,
+			    res0->ai_protocol)) < 0)
+				continue;
+		}
 #ifdef IPSEC
 		if (ipsec_policy[0] !=3D NULL)
 			add_ipsec_policy(s, ipsec_policy[0]);
@@ -532,7 +555,8 @@
 			memset(&ahints, 0, sizeof(struct addrinfo));
 			ahints.ai_family =3D res0->ai_family;
 			ahints.ai_socktype =3D uflag ? SOCK_DGRAM : SOCK_STREAM;
-			ahints.ai_protocol =3D uflag ? IPPROTO_UDP : IPPROTO_TCP;
+			if (!cflag)
+			    ahints.ai_protocol =3D uflag ? IPPROTO_UDP : IPPROTO_TCP;
 			ahints.ai_flags =3D AI_PASSIVE;
 			if ((error =3D getaddrinfo(sflag, pflag, &ahints, &ares)))
 				errx(1, "getaddrinfo: %s", gai_strerror(error));
@@ -549,7 +573,7 @@
 			break;
 		else if (vflag)
 			warn("connect to %s port %s (%s) failed", host, port,
-			    uflag ? "udp" : "tcp");
+			    uflag ? "udp" : (cflag ? "sctp" : "tcp") );
=20
 		close(s);
 		s =3D -1;
@@ -587,10 +611,15 @@
=20
 	res0 =3D res;
 	do {
-		if ((s =3D socket(res0->ai_family, res0->ai_socktype,
-		    res0->ai_protocol)) < 0)
-			continue;
-
+		if (cflag) {
+		    if ((s =3D socket(res0->ai_family, res0->ai_socktype,
+			IPPROTO_SCTP)) < 0)
+			    continue;
+		} else {
+		    if ((s =3D socket(res0->ai_family, res0->ai_socktype,
+			res0->ai_protocol)) < 0)
+			    continue;
+		}
 		ret =3D setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x));
 		if (ret =3D=3D -1)
 			err(1, NULL);
</patch>
--=20
PGP Key: http://www.stud.uni-hamburg.de/~kulas/mkulas_pubkey.asc

--DocE+STaALJfprDB
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (FreeBSD)

iD8DBQFGGrPfu1jKg1agQ1oRAnRxAKCar+RgaK3RBM87hbEfy3/OtBF1vgCgs+Jy
rCHJjOW9TRzACKhwslFdAak=
=CwkG
-----END PGP SIGNATURE-----

--DocE+STaALJfprDB--




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20070409214504.GA1780>