1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227
|
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"
|