File dccp-support.patch of Package netcat-openbsd

From: Aron Xu <aron@debian.org>
Date: Mon, 13 Feb 2012 15:56:51 +0800
Subject: dccp support

---
 nc.1     |    4 ++
 netcat.c |   88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
 2 files changed, 79 insertions(+), 13 deletions(-)

--- a/nc.1
+++ b/nc.1
@@ -33,7 +33,7 @@
 .Nd arbitrary TCP and UDP connections and listens
 .Sh SYNOPSIS
 .Nm nc
-.Op Fl 46CDdFhklNnrStUuvz
+.Op Fl 46CDdFhklNnrStUuvZz
 .Op Fl I Ar length
 .Op Fl i Ar interval
 .Op Fl M Ar ttl
@@ -288,6 +288,8 @@ An IPv6 address can be specified unambig
 in square brackets.
 A proxy cannot be used with any of the options
 .Fl lsuU .
+.It Fl Z
+DCCP mode.
 .It Fl z
 Only scan for listening daemons, without sending any data to them.
 Cannot be used together with
--- a/netcat.c
+++ b/netcat.c
@@ -146,6 +146,7 @@ int	rflag;					/* Random ports flag */
 char   *sflag;					/* Source Address */
 int	tflag;					/* Telnet Emulation */
 int	uflag;					/* UDP - Default to TCP */
+int	dccpflag;				/* DCCP - Default to TCP */
 int	vflag;					/* Verbosity */
 int	xflag;					/* Socks proxy */
 int	zflag;					/* Port Scan Flag */
@@ -224,6 +225,7 @@ ssize_t drainbuf(int, unsigned char *, s
 ssize_t fillbuf(int, unsigned char *, size_t *);
 # endif
 
+char *proto_name(int uflag, int dccpflag);
 static int connect_with_timeout(int fd, const struct sockaddr *sa,
         socklen_t salen, int ctimeout);
 
@@ -264,7 +266,7 @@ main(int argc, char *argv[])
 # if defined(TLS)
 	    "46C:cDde:FH:hI:i:K:klM:m:NnO:o:P:p:q:R:rSs:T:tUuV:vW:w:X:x:Z:z"))
 # else
-	    "46CDdFhI:i:klM:m:NnO:P:p:q:rSs:T:tUuV:vW:w:X:x:z"))
+	    "46CDdFhI:i:klM:m:NnO:P:p:q:rSs:T:tUuV:vW:w:X:x:Zz"))
 # endif
 	    != -1) {
 		switch (ch) {
@@ -381,6 +383,13 @@ main(int argc, char *argv[])
 		case 'u':
 			uflag = 1;
 			break;
+		case 'Z':
+# if defined(IPPROTO_DCCP) && defined(SOCK_DCCP)
+			dccpflag = 1;
+# else
+			errx(1, "no DCCP support available");
+# endif
+			break;
 		case 'V':
 # if defined(RT_TABLEID_MAX)
 			rtableid = (int)strtonum(optarg, 0,
@@ -485,6 +494,10 @@ main(int argc, char *argv[])
 
 	/* Cruft to make sure options are clean, and used properly. */
 	if (argc == 1 && family == AF_UNIX) {
+# if defined(IPPROTO_DCCP) && defined(SOCK_DCCP)
+		if (dccpflag)
+			errx(1, "cannot use -Z and -U");
+# endif
 		host = argv[0];
 	} else if (argc == 0 && lflag) {
 		if (sflag)
@@ -586,8 +599,20 @@ main(int argc, char *argv[])
 	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 (uflag) {
+		    hints.ai_socktype = SOCK_DGRAM;
+		    hints.ai_protocol = IPPROTO_UDP;
+		}
+# if defined(IPPROTO_DCCP) && defined(SOCK_DCCP)
+		else if (dccpflag) {
+		    hints.ai_socktype = SOCK_DCCP;
+		    hints.ai_protocol = IPPROTO_DCCP;
+		}
+# endif
+		else {
+		    hints.ai_socktype = SOCK_STREAM;
+		    hints.ai_protocol = IPPROTO_TCP;
+		}
 		if (nflag)
 			hints.ai_flags |= AI_NUMERICHOST;
 	}
@@ -595,7 +620,10 @@ main(int argc, char *argv[])
 	if (xflag) {
 		if (uflag)
 			errx(1, "no proxy support for UDP mode");
-
+# if defined(IPPROTO_DCCP) && defined(SOCK_DCCP)
+		if (dccpflag)
+			errx(1, "no proxy support for DCCP mode");
+# endif
 		if (lflag)
 			errx(1, "no proxy support for listen");
 
@@ -844,13 +872,14 @@ main(int argc, char *argv[])
 					}
 				}
 
+				char *proto = proto_name(uflag, dccpflag);
 				/* Don't look up port if -n. */
 				if (nflag)
 					sv = NULL;
 				else {
 					sv = getservbyport(
 					    ntohs(atoi(portlist[i])),
-					    uflag ? "udp" : "tcp");
+					    proto);
 				}
 
 				fprintf(stderr, "Connection to %s", host);
@@ -864,7 +893,7 @@ main(int argc, char *argv[])
 					fprintf(stderr, " (%s)", ipaddr);
 
 				fprintf(stderr, " %s port [%s/%s] succeeded!\n",
-				    portlist[i], uflag ? "udp" : "tcp",
+				    portlist[i], proto,
 				    sv ? sv->s_name : "*");
 			}
 			if (Fflag)
@@ -1080,6 +1109,24 @@ unix_listen(char *path)
 	return s;
 }
 
+char *proto_name(int uflag, int dccpflag) {
+
+    char *proto = NULL;
+    if (uflag) {
+	proto = "udp";
+    }
+# if defined(IPPROTO_DCCP) && defined(SOCK_DCCP)
+    else if (dccpflag) {
+	proto = "dccp";
+    }
+# endif
+    else {
+	proto = "tcp";
+    }
+
+    return proto;
+}
+
 /*
  * remote_connect()
  * Returns a socket connected to a remote host. Properly binds to a local
@@ -1111,8 +1158,21 @@ remote_connect(const char *host, const c
 # endif
 			memset(&ahints, 0, sizeof(struct addrinfo));
 			ahints.ai_family = res->ai_family;
-			ahints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM;
-			ahints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP;
+			if (uflag) {
+			    ahints.ai_socktype = SOCK_DGRAM;
+			    ahints.ai_protocol = IPPROTO_UDP;
+
+			}
+# if defined(IPPROTO_DCCP) && defined(SOCK_DCCP)
+			else if (dccpflag) {
+			    hints.ai_socktype = SOCK_DCCP;
+			    hints.ai_protocol = IPPROTO_DCCP;
+			}
+# endif
+			else {
+		    	    ahints.ai_socktype = SOCK_STREAM;
+			    ahints.ai_protocol = IPPROTO_TCP;
+			}
 			ahints.ai_flags = AI_PASSIVE;
 			if ((error = getaddrinfo(sflag, pflag, &ahints, &ares)))
 				errx(1, "getaddrinfo: %s", gai_strerror(error));
@@ -1142,16 +1202,18 @@ remote_connect(const char *host, const c
 		    timeout)) == CONNECTION_SUCCESS)
 			break;
 
+		char *proto = proto_name(uflag, dccpflag);
+
 		if (vflag) {
 			/* only print IP if there is something to report */
 			if (nflag || ipaddr == NULL ||
 			    (strncmp(host, ipaddr, NI_MAXHOST) == 0))
 				warn("connect to %s port %s (%s) %s", host,
-				    port, uflag ? "udp" : "tcp",
+				    port, proto,
 				    error == CONNECTION_TIMEOUT ? "timed out" : "failed");
 			else
 				warn("connect to %s (%s) port %s (%s) %s",
-				    host, ipaddr, port, uflag ? "udp" : "tcp",
+				    host, ipaddr, port, proto,
 				    error == CONNECTION_TIMEOUT ? "timed out" : "failed");
 		}
 
@@ -1764,7 +1826,8 @@ build_ports(char *p)
 	int hi, lo, cp;
 	int x = 0;
 
-	sv = getservbyname(p, uflag ? "udp" : "tcp");
+	char *proto = proto_name(uflag, dccpflag);
+	sv = getservbyname(p, proto);
 	if (sv) {
 		if (asprintf(&portlist[0], "%d", ntohs(sv->s_port)) < 0)
 			err(1, "asprintf");
@@ -2147,6 +2210,7 @@ help(void)
 	\t-w timeout	Timeout for connects and final net reads\n\
 	\t-X proto	Proxy protocol: \"4\", \"5\" (SOCKS) or \"connect\"\n\
 	\t-x addr[:port]\tSpecify proxy address and port\n\
+	\t-Z		DCCP mode\n\
 	\t-z		Zero-I/O mode [used for scanning]\n\
 	Port numbers can be individual or ranges: lo-hi [inclusive]\n");
 	exit(0);
@@ -2156,7 +2220,7 @@ void
 usage(int ret)
 {
 	fprintf(stderr,
-	    "usage: nc [-46CDdFhklNnrStUuvz] [-I length] [-i interval] [-M ttl]\n"
+	    "usage: nc [-46CDdFhklNnrStUuvZz] [-I length] [-i interval] [-M ttl]\n"
 	    "\t  [-m minttl] [-O length] [-P proxy_username] [-p source_port]\n"
 	    "\t  [-q seconds] [-s sourceaddr] [-T keyword] [-V rtable] [-W recvlimit]\n"
 	    "\t  [-w timeout] [-X proxy_protocol] [-x proxy_address[:port]]\n"
openSUSE Build Service is sponsored by