forked from pool/netcat-openbsd
OBS-URL: https://build.opensuse.org/package/show/network:utilities/netcat-openbsd?expand=0&rev=29
195 lines
5.0 KiB
Diff
195 lines
5.0 KiB
Diff
From: Guilhem Moulin <guilhem@debian.org>
|
||
Date: Mon, 22 Oct 2018 04:15:52 +0200
|
||
Subject: Add ability to specify a list of destination ports
|
||
|
||
---
|
||
nc.1 | 26 +++++++++++++++++---
|
||
netcat.c | 86 +++++++++++++++++++++++++++++++++-------------------------------
|
||
2 files changed, 68 insertions(+), 44 deletions(-)
|
||
|
||
diff --git a/nc.1 b/nc.1
|
||
index 49a3d4d..80c654c 100644
|
||
--- a/nc.1
|
||
+++ b/nc.1
|
||
@@ -417,15 +417,35 @@ The
|
||
flag can be used to tell
|
||
.Nm
|
||
to report open ports,
|
||
-rather than initiate a connection.
|
||
+rather than initiate a connection. Usually it's useful to turn on verbose
|
||
+output to stderr by use this option in conjunction with
|
||
+.Fl v
|
||
+option.
|
||
+.Pp
|
||
For example:
|
||
.Bd -literal -offset indent
|
||
-$ nc -z host.example.com 20-30
|
||
+$ nc \-zv host.example.com 20-30
|
||
Connection to host.example.com 22 port [tcp/ssh] succeeded!
|
||
Connection to host.example.com 25 port [tcp/smtp] succeeded!
|
||
.Ed
|
||
.Pp
|
||
-The port range was specified to limit the search to ports 20 \- 30.
|
||
+The port range was specified to limit the search to ports 20 \- 30, and is
|
||
+scanned by increasing order (unless the
|
||
+.Fl r
|
||
+flag is set).
|
||
+.Pp
|
||
+You can also specify a list of ports to scan, for example:
|
||
+.Bd -literal -offset indent
|
||
+$ nc \-zv host.example.com http 20 22-23
|
||
+nc: connect to host.example.com 80 (tcp) failed: Connection refused
|
||
+nc: connect to host.example.com 20 (tcp) failed: Connection refused
|
||
+Connection to host.example.com port [tcp/ssh] succeeded!
|
||
+nc: connect to host.example.com 23 (tcp) failed: Connection refused
|
||
+.Ed
|
||
+.Pp
|
||
+The ports are scanned by the order you given (unless the
|
||
+.Fl r
|
||
+flag is set).
|
||
.Pp
|
||
Alternatively, it might be useful to know which server software
|
||
is running, and which versions.
|
||
diff --git a/netcat.c b/netcat.c
|
||
index 990c31b..bef27a4 100644
|
||
--- a/netcat.c
|
||
+++ b/netcat.c
|
||
@@ -191,7 +191,7 @@ int minttl = -1;
|
||
|
||
void atelnet(int, unsigned char *, unsigned int);
|
||
int strtoport(char *portstr, int udp);
|
||
-void build_ports(char *);
|
||
+void build_ports(char **);
|
||
void help(void) __attribute__((noreturn));
|
||
int local_listen(const char *, const char *, struct addrinfo);
|
||
#ifdef HAVE_TLS
|
||
@@ -241,7 +241,7 @@ int
|
||
main(int argc, char *argv[])
|
||
{
|
||
int ch, s = -1, ret, socksv;
|
||
- char *host, *uport;
|
||
+ char *host, **uport;
|
||
char ipaddr[NI_MAXHOST];
|
||
struct addrinfo hints;
|
||
socklen_t len;
|
||
@@ -521,10 +521,10 @@ main(int argc, char *argv[])
|
||
if (zflag)
|
||
errx(1, "cannot use -z and -l");
|
||
} else if (argc == 1 && lflag) {
|
||
- uport = argv[0];
|
||
+ uport = &argv[0];
|
||
} else if (argc == 2) {
|
||
host = argv[0];
|
||
- uport = argv[1];
|
||
+ uport = &argv[1];
|
||
} else
|
||
usage(1);
|
||
|
||
@@ -723,7 +723,7 @@ main(int argc, char *argv[])
|
||
else
|
||
s = unix_listen(host);
|
||
} else
|
||
- s = local_listen(host, uport, hints);
|
||
+ s = local_listen(host, *uport, hints);
|
||
if (s < 0)
|
||
err(1, NULL);
|
||
|
||
@@ -1810,57 +1810,61 @@ strtoport(char *portstr, int udp)
|
||
* that we should try to connect to.
|
||
*/
|
||
void
|
||
-build_ports(char *p)
|
||
+build_ports(char **p)
|
||
{
|
||
struct servent *sv;
|
||
char *n;
|
||
int hi, lo, cp;
|
||
int x = 0;
|
||
+ int i;
|
||
|
||
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");
|
||
- } else if (isdigit((unsigned char)*p) && (n = strchr(p, '-')) != NULL) {
|
||
- *n = '\0';
|
||
- n++;
|
||
-
|
||
- /* Make sure the ports are in order: lowest->highest. */
|
||
- hi = strtoport(n, uflag);
|
||
- lo = strtoport(p, uflag);
|
||
- if (lo > hi) {
|
||
- cp = hi;
|
||
- hi = lo;
|
||
- lo = cp;
|
||
- }
|
||
-
|
||
- /*
|
||
- * Initialize portlist with a random permutation. Based on
|
||
- * Knuth, as in ip_randomid() in sys/netinet/ip_id.c.
|
||
- */
|
||
- if (rflag) {
|
||
- for (x = 0; x <= hi - lo; x++) {
|
||
- cp = arc4random_uniform(x + 1);
|
||
- portlist[x] = portlist[cp];
|
||
- if (asprintf(&portlist[cp], "%d", x + lo) == -1)
|
||
- err(1, "asprintf");
|
||
+ for (i = 0; p[i] != NULL; i++) {
|
||
+ sv = getservbyname(p[i], proto);
|
||
+ if (sv) {
|
||
+ if (asprintf(&portlist[x], "%d", ntohs(sv->s_port)) < 0)
|
||
+ err(1, "asprintf");
|
||
+ x++;
|
||
+ } else if (isdigit((unsigned char)*p[i]) && (n = strchr(p[i], '-')) != NULL) {
|
||
+ *n = '\0';
|
||
+ n++;
|
||
+
|
||
+ /* Make sure the ports are in order: lowest->highest. */
|
||
+ hi = strtoport(n, uflag);
|
||
+ lo = strtoport(p[i], uflag);
|
||
+ if (lo > hi) {
|
||
+ cp = hi;
|
||
+ hi = lo;
|
||
+ lo = cp;
|
||
}
|
||
- } else { /* Load ports sequentially. */
|
||
+
|
||
+ /* Load ports sequentially. */
|
||
for (cp = lo; cp <= hi; cp++) {
|
||
if (asprintf(&portlist[x], "%d", cp) == -1)
|
||
err(1, "asprintf");
|
||
x++;
|
||
}
|
||
+ } else {
|
||
+ hi = strtoport(p[i], uflag);
|
||
+ if (asprintf(&portlist[x], "%d", hi) < 0)
|
||
+ err(1, "asprintf");
|
||
+ x++;
|
||
}
|
||
- } else {
|
||
- char *tmp;
|
||
+ }
|
||
|
||
- hi = strtoport(p, uflag);
|
||
- if (asprintf(&tmp, "%d", hi) != -1)
|
||
- portlist[0] = tmp;
|
||
- else
|
||
- err(1, NULL);
|
||
+ /*
|
||
+ * Initialize portlist with a random permutation using
|
||
+ * Fisher–Yates shuffle.
|
||
+ */
|
||
+ if (rflag) {
|
||
+ for (i = x-1; i > 0; i--) {
|
||
+ cp = arc4random_uniform(i+1);
|
||
+ if (cp != i) {
|
||
+ n = portlist[i];
|
||
+ portlist[i] = portlist[cp];
|
||
+ portlist[cp] = n;
|
||
+ }
|
||
+ }
|
||
}
|
||
}
|
||
|