File dccp-support.patch of Package netcat-openbsd
From: Aron Xu <aron@debian.org>
Date: Mon, 13 Feb 2012 15:56:51 +0800
Subject: New flag '-Z' for DCCP support
---
nc.1 | 4 ++-
netcat.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
2 files changed, 76 insertions(+), 13 deletions(-)
diff --git a/nc.1 b/nc.1
index fbcc098..da37f06 100644
--- 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 unambiguously by enclosing
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
diff --git a/netcat.c b/netcat.c
index dd893ac..1c50615 100644
--- 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 */
@@ -225,6 +226,7 @@ ssize_t drainbuf(int, unsigned char *, size_t *, int);
ssize_t fillbuf(int, unsigned char *, size_t *);
#endif
+char *proto_name(int, int);
static int connect_with_timeout(int, const struct sockaddr *, socklen_t, int);
static void quit(int sig);
@@ -261,7 +263,7 @@ main(int argc, char *argv[])
#ifdef HAVE_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) {
@@ -378,6 +380,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':
#ifdef RT_TABLEID_MAX
rtableid = (int)strtonum(optarg, 0,
@@ -482,6 +491,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)
@@ -583,8 +596,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;
}
@@ -592,7 +617,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");
@@ -838,9 +866,11 @@ main(int argc, char *argv[])
continue;
}
}
- if (print_info == 1)
+ if (print_info == 1) {
+ char *proto = proto_name(uflag, dccpflag);
connection_info(host, portlist[i],
- uflag ? "udp" : "tcp", ipaddr);
+ proto, ipaddr);
+ }
}
if (Fflag)
fdpass(s);
@@ -1054,6 +1084,21 @@ 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
@@ -1085,8 +1130,20 @@ remote_connect(const char *host, const char *port, struct addrinfo hints,
#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));
@@ -1116,16 +1173,18 @@ remote_connect(const char *host, const char *port, struct addrinfo hints,
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");
}
@@ -1742,7 +1801,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");
@@ -2155,6 +2215,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);
@@ -2164,7 +2225,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"