aports/main/netcat-openbsd/0008-dccp-support.patch

263 lines
7.6 KiB
Diff

From: Aron Xu <aron@debian.org>
Date: Mon, 13 Feb 2012 15:56:51 +0800
Subject: dccp support
---
nc.1 | 4 ++-
netcat.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
2 files changed, 88 insertions(+), 18 deletions(-)
diff --git a/nc.1 b/nc.1
index 1ee6887..fe42909 100644
--- a/nc.1
+++ b/nc.1
@@ -34,7 +34,7 @@
.Sh SYNOPSIS
.Nm nc
.Bk -words
-.Op Fl 46CDdFhklNnrStUuvz
+.Op Fl 46CDdFhklNnrStUuvZz
.Op Fl I Ar length
.Op Fl i Ar interval
.Op Fl O Ar length
@@ -279,6 +279,8 @@ If
.Ar port
is not specified, the well-known port for the proxy protocol is used (1080
for SOCKS, 3128 for HTTPS).
+.It Fl Z
+DCCP mode.
.It Fl z
Specifies that
.Nm
diff --git a/netcat.c b/netcat.c
index 3240a08..f4d85af 100644
--- a/netcat.c
+++ b/netcat.c
@@ -136,6 +136,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 */
@@ -171,6 +172,7 @@ void report_connect(const struct sockaddr *, socklen_t);
void usage(int);
ssize_t drainbuf(int, unsigned char *, size_t *, int);
ssize_t fillbuf(int, unsigned char *, size_t *);
+char *proto_name(int uflag, int dccpflag);
static int connect_with_timeout(int fd, const struct sockaddr *sa,
socklen_t salen, int ctimeout);
@@ -200,7 +202,7 @@ main(int argc, char *argv[])
signal(SIGPIPE, SIG_IGN);
while ((ch = getopt(argc, argv,
- "46CDdFhI:i:klNnO:P:p:q:rSs:tT:UuV:vw:X:x:z")) != -1) {
+ "46CDdFhI:i:klNnO:P:p:q:rSs:tT:UuV:vw:X:x:Zz")) != -1) {
switch (ch) {
case '4':
family = AF_INET;
@@ -270,6 +272,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,
@@ -345,6 +354,12 @@ main(int argc, char *argv[])
/* Cruft to make sure options are clean, and used properly. */
if (argv[0] && !argv[1] && family == AF_UNIX) {
+ if (uflag)
+ errx(1, "cannot use -u and -U");
+# if defined(IPPROTO_DCCP) && defined(SOCK_DCCP)
+ if (dccpflag)
+ errx(1, "cannot use -Z and -U");
+# endif
host = argv[0];
uport = NULL;
} else if (!argv[0] && lflag) {
@@ -386,8 +401,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;
}
@@ -395,7 +422,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");
@@ -439,12 +469,12 @@ main(int argc, char *argv[])
err(1, NULL);
char* local;
- if (family == AF_INET6
+ if (family == AF_INET6 )
local = "0.0.0.0";
else if (family == AF_INET)
local = ":::";
else
- local = "unknown"
+ local = "unknown";
fprintf(stderr, "Listening on [%s] (family %d, port %d)\n",
host ?: local,
family,
@@ -549,19 +579,20 @@ 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 %s port [%s/%s] "
"succeeded!\n", host, portlist[i],
- uflag ? "udp" : "tcp",
+ proto,
sv ? sv->s_name : "*");
}
if (Fflag)
@@ -663,6 +694,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
@@ -699,8 +748,21 @@ remote_connect(const char *host, const char *port, struct addrinfo hints)
# endif
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 (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));
@@ -712,15 +774,19 @@ remote_connect(const char *host, const char *port, struct addrinfo hints)
}
set_common_sockopts(s, res0->ai_family);
+ char *proto = proto_name(uflag, dccpflag);
- if ((error = connect_with_timeout(s, res0->ai_addr, res0->ai_addrlen, timeout))== CONNECTION_SUCCESS)
+ if ((error = connect_with_timeout(s, res0->ai_addr, res0->ai_addrlen, timeout))== CONNECTION_SUCCESS) {
break;
- else if (vflag && error == CONNECTION_FAILED)
+ }
+ else if (vflag && error == CONNECTION_FAILED) {
warn("connect to %s port %s (%s) failed", host, port,
- uflag ? "udp" : "tcp");
- else if (vflag && error == CONNECTION_TIMEOUT)
+ proto);
+ }
+ else if (vflag && error == CONNECTION_TIMEOUT) {
warn("connect to %s port %s (%s) timed out", host, port,
- uflag ? "udp" : "tcp");
+ proto);
+ }
close(s);
s = -1;
@@ -1250,7 +1316,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) {
portlist[0] = calloc(1, PORT_MAX_LEN);
if (portlist[0] == NULL)
@@ -1484,6 +1551,7 @@ help(void)
\t-w secs\t 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);
@@ -1493,7 +1561,7 @@ void
usage(int ret)
{
fprintf(stderr,
- "usage: nc [-46CDdFhklNnrStUuvz] [-I length] [-i interval] [-O length]\n"
+ "usage: nc [-46CDdFhklNnrStUuvZz] [-I length] [-i interval] [-O length]\n"
"\t [-P proxy_username] [-p source_port] [-q seconds] [-s source]\n"
"\t [-T toskeyword] [-V rtable] [-w timeout] [-X proxy_protocol]\n"
"\t [-x proxy_address[:port]] [destination] [port]\n");
--