summaryrefslogtreecommitdiffstats
path: root/contrib/netcat/netcat.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/netcat/netcat.c')
-rw-r--r--contrib/netcat/netcat.c802
1 files changed, 802 insertions, 0 deletions
diff --git a/contrib/netcat/netcat.c b/contrib/netcat/netcat.c
new file mode 100644
index 0000000..3c610b9
--- /dev/null
+++ b/contrib/netcat/netcat.c
@@ -0,0 +1,802 @@
+/* $OpenBSD: netcat.c,v 1.76 2004/12/10 16:51:31 hshoexer Exp $ */
+/*
+ * Copyright (c) 2001 Eric Jackson <ericj@monkey.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Re-written nc(1) for OpenBSD. Original implementation by
+ * *Hobbit* <hobbit@avian.org>.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/un.h>
+
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <arpa/telnet.h>
+
+#include <err.h>
+#include <errno.h>
+#include <netdb.h>
+#include <poll.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#ifndef SUN_LEN
+#define SUN_LEN(su) \
+ (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
+#endif
+
+#define PORT_MAX 65535
+#define PORT_MAX_LEN 6
+
+/* Command Line Options */
+int dflag; /* detached, no stdin */
+int iflag; /* Interval Flag */
+int kflag; /* More than one connect */
+int lflag; /* Bind to local port */
+int nflag; /* Don't do name look up */
+char *pflag; /* Localport flag */
+int rflag; /* Random ports flag */
+char *sflag; /* Source Address */
+int tflag; /* Telnet Emulation */
+int uflag; /* UDP - Default to TCP */
+int vflag; /* Verbosity */
+int xflag; /* Socks proxy */
+int zflag; /* Port Scan Flag */
+int Dflag; /* sodebug */
+int Sflag; /* TCP MD5 signature option */
+
+int timeout = -1;
+int family = AF_UNSPEC;
+char *portlist[PORT_MAX+1];
+
+ssize_t atomicio(ssize_t (*)(int, void *, size_t), int, void *, size_t);
+void atelnet(int, unsigned char *, unsigned int);
+void build_ports(char *);
+void help(void);
+int local_listen(char *, char *, struct addrinfo);
+void readwrite(int);
+int remote_connect(char *, char *, struct addrinfo);
+int socks_connect(char *, char *, struct addrinfo, char *, char *,
+ struct addrinfo, int);
+int udptest(int);
+int unix_connect(char *);
+int unix_listen(char *);
+void usage(int);
+
+int
+main(int argc, char *argv[])
+{
+ int ch, s, ret, socksv;
+ char *host, *uport, *endp;
+ struct addrinfo hints;
+ struct servent *sv;
+ socklen_t len;
+ struct sockaddr_storage cliaddr;
+ char *proxy;
+ char *proxyhost = "", *proxyport = NULL;
+ struct addrinfo proxyhints;
+
+ ret = 1;
+ s = 0;
+ socksv = 5;
+ host = NULL;
+ uport = NULL;
+ endp = NULL;
+ sv = NULL;
+
+ while ((ch = getopt(argc, argv, "46Ddhi:klnp:rSs:tUuvw:X:x:z")) != -1) {
+ switch (ch) {
+ case '4':
+ family = AF_INET;
+ break;
+ case '6':
+ family = AF_INET6;
+ break;
+ case 'U':
+ family = AF_UNIX;
+ break;
+ case 'X':
+ if (strcasecmp(optarg, "connect") == 0)
+ socksv = -1; /* HTTP proxy CONNECT */
+ else if (strcmp(optarg, "4") == 0)
+ socksv = 4; /* SOCKS v.4 */
+ else if (strcmp(optarg, "5") == 0)
+ socksv = 5; /* SOCKS v.5 */
+ else
+ errx(1, "unsupported proxy protocol");
+ break;
+ case 'd':
+ dflag = 1;
+ break;
+ case 'h':
+ help();
+ break;
+ case 'i':
+ iflag = (int)strtoul(optarg, &endp, 10);
+ if (iflag < 0 || *endp != '\0')
+ errx(1, "interval cannot be negative");
+ break;
+ case 'k':
+ kflag = 1;
+ break;
+ case 'l':
+ lflag = 1;
+ break;
+ case 'n':
+ nflag = 1;
+ break;
+ case 'p':
+ pflag = optarg;
+ break;
+ case 'r':
+ rflag = 1;
+ break;
+ case 's':
+ sflag = optarg;
+ break;
+ case 't':
+ tflag = 1;
+ break;
+ case 'u':
+ uflag = 1;
+ break;
+ case 'v':
+ vflag = 1;
+ break;
+ case 'w':
+ timeout = (int)strtoul(optarg, &endp, 10);
+ if (timeout < 0 || *endp != '\0')
+ errx(1, "timeout cannot be negative");
+ if (timeout >= (INT_MAX / 1000))
+ errx(1, "timeout too large");
+ timeout *= 1000;
+ break;
+ case 'x':
+ xflag = 1;
+ if ((proxy = strdup(optarg)) == NULL)
+ err(1, NULL);
+ break;
+ case 'z':
+ zflag = 1;
+ break;
+ case 'D':
+ Dflag = 1;
+ break;
+ case 'S':
+ Sflag = 1;
+ break;
+ default:
+ usage(1);
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ /* 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");
+ host = argv[0];
+ uport = NULL;
+ } else if (argv[0] && !argv[1]) {
+ if (!lflag)
+ usage(1);
+ uport = argv[0];
+ host = NULL;
+ } else if (argv[0] && argv[1]) {
+ host = argv[0];
+ uport = argv[1];
+ } else
+ usage(1);
+
+ if (lflag && sflag)
+ errx(1, "cannot use -s and -l");
+ if (lflag && pflag)
+ errx(1, "cannot use -p and -l");
+ if (lflag && zflag)
+ errx(1, "cannot use -z and -l");
+ if (!lflag && kflag)
+ errx(1, "must use -l with -k");
+
+ /* Initialize addrinfo structure. */
+ 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 (nflag)
+ hints.ai_flags |= AI_NUMERICHOST;
+ }
+
+ if (xflag) {
+ if (uflag)
+ errx(1, "no proxy support for UDP mode");
+
+ if (lflag)
+ errx(1, "no proxy support for listen");
+
+ if (family == AF_UNIX)
+ errx(1, "no proxy support for unix sockets");
+
+ /* XXX IPv6 transport to proxy would probably work */
+ if (family == AF_INET6)
+ errx(1, "no proxy support for IPv6");
+
+ if (sflag)
+ errx(1, "no proxy support for local source address");
+
+ proxyhost = strsep(&proxy, ":");
+ proxyport = proxy;
+
+ memset(&proxyhints, 0, sizeof(struct addrinfo));
+ proxyhints.ai_family = family;
+ proxyhints.ai_socktype = SOCK_STREAM;
+ proxyhints.ai_protocol = IPPROTO_TCP;
+ if (nflag)
+ proxyhints.ai_flags |= AI_NUMERICHOST;
+ }
+
+ if (lflag) {
+ int connfd;
+ ret = 0;
+
+ if (family == AF_UNIX)
+ s = unix_listen(host);
+
+ /* Allow only one connection at a time, but stay alive. */
+ for (;;) {
+ if (family != AF_UNIX)
+ s = local_listen(host, uport, hints);
+ if (s < 0)
+ err(1, NULL);
+ /*
+ * For UDP, we will use recvfrom() initially
+ * to wait for a caller, then use the regular
+ * functions to talk to the caller.
+ */
+ if (uflag) {
+ int rv;
+ char buf[1024];
+ struct sockaddr_storage z;
+
+ len = sizeof(z);
+ rv = recvfrom(s, buf, sizeof(buf), MSG_PEEK,
+ (struct sockaddr *)&z, &len);
+ if (rv < 0)
+ err(1, "recvfrom");
+
+ rv = connect(s, (struct sockaddr *)&z, len);
+ if (rv < 0)
+ err(1, "connect");
+
+ connfd = s;
+ } else {
+ connfd = accept(s, (struct sockaddr *)&cliaddr,
+ &len);
+ }
+
+ readwrite(connfd);
+ close(connfd);
+ if (family != AF_UNIX)
+ close(s);
+
+ if (!kflag)
+ break;
+ }
+ } else if (family == AF_UNIX) {
+ ret = 0;
+
+ if ((s = unix_connect(host)) > 0 && !zflag) {
+ readwrite(s);
+ close(s);
+ } else
+ ret = 1;
+
+ exit(ret);
+
+ } else {
+ int i = 0;
+
+ /* Construct the portlist[] array. */
+ build_ports(uport);
+
+ /* Cycle through portlist, connecting to each port. */
+ for (i = 0; portlist[i] != NULL; i++) {
+ if (s)
+ close(s);
+
+ if (xflag)
+ s = socks_connect(host, portlist[i], hints,
+ proxyhost, proxyport, proxyhints, socksv);
+ else
+ s = remote_connect(host, portlist[i], hints);
+
+ if (s < 0)
+ continue;
+
+ ret = 0;
+ if (vflag || zflag) {
+ /* For UDP, make sure we are connected. */
+ if (uflag) {
+ if (udptest(s) == -1) {
+ ret = 1;
+ continue;
+ }
+ }
+
+ /* Don't look up port if -n. */
+ if (nflag)
+ sv = NULL;
+ else {
+ sv = getservbyport(
+ ntohs(atoi(portlist[i])),
+ uflag ? "udp" : "tcp");
+ }
+
+ printf("Connection to %s %s port [%s/%s] succeeded!\n",
+ host, portlist[i], uflag ? "udp" : "tcp",
+ sv ? sv->s_name : "*");
+ }
+ if (!zflag)
+ readwrite(s);
+ }
+ }
+
+ if (s)
+ close(s);
+
+ exit(ret);
+}
+
+/*
+ * unix_connect()
+ * Returns a socket connected to a local unix socket. Returns -1 on failure.
+ */
+int
+unix_connect(char *path)
+{
+ struct sockaddr_un sun;
+ int s;
+
+ if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
+ return (-1);
+ (void)fcntl(s, F_SETFD, 1);
+
+ memset(&sun, 0, sizeof(struct sockaddr_un));
+ sun.sun_family = AF_UNIX;
+
+ if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >=
+ sizeof(sun.sun_path)) {
+ close(s);
+ errno = ENAMETOOLONG;
+ return (-1);
+ }
+ if (connect(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) {
+ close(s);
+ return (-1);
+ }
+ return (s);
+
+}
+
+/*
+ * unix_listen()
+ * Create a unix domain socket, and listen on it.
+ */
+int
+unix_listen(char *path)
+{
+ struct sockaddr_un sun;
+ int s;
+
+ /* Create unix domain socket. */
+ if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
+ return (-1);
+
+ memset(&sun, 0, sizeof(struct sockaddr_un));
+ sun.sun_family = AF_UNIX;
+
+ if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >=
+ sizeof(sun.sun_path)) {
+ close(s);
+ errno = ENAMETOOLONG;
+ return (-1);
+ }
+
+ if (bind(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) {
+ close(s);
+ return (-1);
+ }
+
+ if (listen(s, 5) < 0) {
+ close(s);
+ return (-1);
+ }
+ return (s);
+}
+
+/*
+ * remote_connect()
+ * Returns a socket connected to a remote host. Properly binds to a local
+ * port or source address if needed. Returns -1 on failure.
+ */
+int
+remote_connect(char *host, char *port, struct addrinfo hints)
+{
+ struct addrinfo *res, *res0;
+ int s, error, x = 1;
+
+ if ((error = getaddrinfo(host, port, &hints, &res)))
+ errx(1, "getaddrinfo: %s", gai_strerror(error));
+
+ res0 = res;
+ do {
+ if ((s = socket(res0->ai_family, res0->ai_socktype,
+ res0->ai_protocol)) < 0)
+ continue;
+
+ /* Bind to a local port or source address if specified. */
+ if (sflag || pflag) {
+ struct addrinfo ahints, *ares;
+
+ if (!(sflag && pflag)) {
+ if (!sflag)
+ sflag = NULL;
+ else
+ pflag = NULL;
+ }
+
+ 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;
+ ahints.ai_flags = AI_PASSIVE;
+ if ((error = getaddrinfo(sflag, pflag, &ahints, &ares)))
+ errx(1, "getaddrinfo: %s", gai_strerror(error));
+
+ if (bind(s, (struct sockaddr *)ares->ai_addr,
+ ares->ai_addrlen) < 0)
+ errx(1, "bind failed: %s", strerror(errno));
+ freeaddrinfo(ares);
+ }
+ if (Sflag) {
+ if (setsockopt(s, IPPROTO_TCP, TCP_MD5SIG,
+ &x, sizeof(x)) == -1)
+ err(1, NULL);
+ }
+ if (Dflag) {
+ if (setsockopt(s, SOL_SOCKET, SO_DEBUG,
+ &x, sizeof(x)) == -1)
+ err(1, NULL);
+ }
+
+ if (connect(s, res0->ai_addr, res0->ai_addrlen) == 0)
+ break;
+ else if (vflag)
+ warn("connect to %s port %s (%s) failed", host, port,
+ uflag ? "udp" : "tcp");
+
+ close(s);
+ s = -1;
+ } while ((res0 = res0->ai_next) != NULL);
+
+ freeaddrinfo(res);
+
+ return (s);
+}
+
+/*
+ * local_listen()
+ * Returns a socket listening on a local port, binds to specified source
+ * address. Returns -1 on failure.
+ */
+int
+local_listen(char *host, char *port, struct addrinfo hints)
+{
+ struct addrinfo *res, *res0;
+ int s, ret, x = 1;
+ int error;
+
+ /* Allow nodename to be null. */
+ hints.ai_flags |= AI_PASSIVE;
+
+ /*
+ * In the case of binding to a wildcard address
+ * default to binding to an ipv4 address.
+ */
+ if (host == NULL && hints.ai_family == AF_UNSPEC)
+ hints.ai_family = AF_INET;
+
+ if ((error = getaddrinfo(host, port, &hints, &res)))
+ errx(1, "getaddrinfo: %s", gai_strerror(error));
+
+ res0 = res;
+ do {
+ if ((s = socket(res0->ai_family, res0->ai_socktype,
+ res0->ai_protocol)) == 0)
+ continue;
+
+ ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x));
+ if (ret == -1)
+ err(1, NULL);
+ if (Sflag) {
+ ret = setsockopt(s, IPPROTO_TCP, TCP_MD5SIG,
+ &x, sizeof(x));
+ if (ret == -1)
+ err(1, NULL);
+ }
+ if (Dflag) {
+ if (setsockopt(s, SOL_SOCKET, SO_DEBUG,
+ &x, sizeof(x)) == -1)
+ err(1, NULL);
+ }
+
+ if (bind(s, (struct sockaddr *)res0->ai_addr,
+ res0->ai_addrlen) == 0)
+ break;
+
+ close(s);
+ s = -1;
+ } while ((res0 = res0->ai_next) != NULL);
+
+ if (!uflag && s != -1) {
+ if (listen(s, 1) < 0)
+ err(1, "listen");
+ }
+
+ freeaddrinfo(res);
+
+ return (s);
+}
+
+/*
+ * readwrite()
+ * Loop that polls on the network file descriptor and stdin.
+ */
+void
+readwrite(int nfd)
+{
+ struct pollfd pfd[2];
+ unsigned char buf[BUFSIZ];
+ int wfd = fileno(stdin), n;
+ int lfd = fileno(stdout);
+
+ /* Setup Network FD */
+ pfd[0].fd = nfd;
+ pfd[0].events = POLLIN;
+
+ /* Set up STDIN FD. */
+ pfd[1].fd = wfd;
+ pfd[1].events = POLLIN;
+
+ while (pfd[0].fd != -1) {
+ if (iflag)
+ sleep(iflag);
+
+ if ((n = poll(pfd, 2 - dflag, timeout)) < 0) {
+ close(nfd);
+ err(1, "Polling Error");
+ }
+
+ if (n == 0)
+ return;
+
+ if (pfd[0].revents & POLLIN) {
+ if ((n = read(nfd, buf, sizeof(buf))) < 0)
+ return;
+ else if (n == 0) {
+ shutdown(nfd, SHUT_RD);
+ pfd[0].fd = -1;
+ pfd[0].events = 0;
+ } else {
+ if (tflag)
+ atelnet(nfd, buf, n);
+ if (atomicio((ssize_t (*)(int, void *, size_t))write,
+ lfd, buf, n) != n)
+ return;
+ }
+ }
+
+ if (!dflag && pfd[1].revents & POLLIN) {
+ if ((n = read(wfd, buf, sizeof(buf))) < 0)
+ return;
+ else if (n == 0) {
+ shutdown(nfd, SHUT_WR);
+ pfd[1].fd = -1;
+ pfd[1].events = 0;
+ } else {
+ if (atomicio((ssize_t (*)(int, void *, size_t))write,
+ nfd, buf, n) != n)
+ return;
+ }
+ }
+ }
+}
+
+/* Deal with RFC 854 WILL/WONT DO/DONT negotiation. */
+void
+atelnet(int nfd, unsigned char *buf, unsigned int size)
+{
+ unsigned char *p, *end;
+ unsigned char obuf[4];
+
+ end = buf + size;
+ obuf[0] = '\0';
+
+ for (p = buf; p < end; p++) {
+ if (*p != IAC)
+ break;
+
+ obuf[0] = IAC;
+ p++;
+ if ((*p == WILL) || (*p == WONT))
+ obuf[1] = DONT;
+ if ((*p == DO) || (*p == DONT))
+ obuf[1] = WONT;
+ if (obuf) {
+ p++;
+ obuf[2] = *p;
+ obuf[3] = '\0';
+ if (atomicio((ssize_t (*)(int, void *, size_t))write,
+ nfd, obuf, 3) != 3)
+ warnx("Write Error!");
+ obuf[0] = '\0';
+ }
+ }
+}
+
+/*
+ * build_ports()
+ * Build an array or ports in portlist[], listing each port
+ * that we should try to connect to.
+ */
+void
+build_ports(char *p)
+{
+ char *n, *endp;
+ int hi, lo, cp;
+ int x = 0;
+
+ if ((n = strchr(p, '-')) != NULL) {
+ if (lflag)
+ errx(1, "Cannot use -l with multiple ports!");
+
+ *n = '\0';
+ n++;
+
+ /* Make sure the ports are in order: lowest->highest. */
+ hi = (int)strtoul(n, &endp, 10);
+ if (hi <= 0 || hi > PORT_MAX || *endp != '\0')
+ errx(1, "port range not valid");
+ lo = (int)strtoul(p, &endp, 10);
+ if (lo <= 0 || lo > PORT_MAX || *endp != '\0')
+ errx(1, "port range not valid");
+
+ if (lo > hi) {
+ cp = hi;
+ hi = lo;
+ lo = cp;
+ }
+
+ /* Load ports sequentially. */
+ for (cp = lo; cp <= hi; cp++) {
+ portlist[x] = calloc(1, PORT_MAX_LEN);
+ if (portlist[x] == NULL)
+ err(1, NULL);
+ snprintf(portlist[x], PORT_MAX_LEN, "%d", cp);
+ x++;
+ }
+
+ /* Randomly swap ports. */
+ if (rflag) {
+ int y;
+ char *c;
+
+ for (x = 0; x <= (hi - lo); x++) {
+ y = (arc4random() & 0xFFFF) % (hi - lo);
+ c = portlist[x];
+ portlist[x] = portlist[y];
+ portlist[y] = c;
+ }
+ }
+ } else {
+ hi = (int)strtoul(p, &endp, 10);
+ if (hi <= 0 || hi > PORT_MAX || *endp != '\0')
+ errx(1, "port range not valid");
+ portlist[0] = calloc(1, PORT_MAX_LEN);
+ if (portlist[0] == NULL)
+ err(1, NULL);
+ portlist[0] = p;
+ }
+}
+
+/*
+ * udptest()
+ * Do a few writes to see if the UDP port is there.
+ * XXX - Better way of doing this? Doesn't work for IPv6.
+ * Also fails after around 100 ports checked.
+ */
+int
+udptest(int s)
+{
+ int i, ret;
+
+ for (i = 0; i <= 3; i++) {
+ if (write(s, "X", 1) == 1)
+ ret = 1;
+ else
+ ret = -1;
+ }
+ return (ret);
+}
+
+void
+help(void)
+{
+ usage(0);
+ fprintf(stderr, "\tCommand Summary:\n\
+ \t-4 Use IPv4\n\
+ \t-6 Use IPv6\n\
+ \t-D Enable the debug socket option\n\
+ \t-d Detach from stdin\n\
+ \t-h This help text\n\
+ \t-i secs\t Delay interval for lines sent, ports scanned\n\
+ \t-k Keep inbound sockets open for multiple connects\n\
+ \t-l Listen mode, for inbound connects\n\
+ \t-n Suppress name/port resolutions\n\
+ \t-p port\t Specify local port for remote connects\n\
+ \t-r Randomize remote ports\n\
+ \t-S Enable the TCP MD5 signature option\n\
+ \t-s addr\t Local source address\n\
+ \t-t Answer TELNET negotiation\n\
+ \t-U Use UNIX domain socket\n\
+ \t-u UDP mode\n\
+ \t-v Verbose\n\
+ \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 Zero-I/O mode [used for scanning]\n\
+ Port numbers can be individual or ranges: lo-hi [inclusive]\n");
+ exit(1);
+}
+
+void
+usage(int ret)
+{
+ fprintf(stderr, "usage: nc [-46DdhklnrStUuvz] [-i interval] [-p source_port]\n");
+ fprintf(stderr, "\t [-s source_ip_address] [-w timeout] [-X proxy_version]\n");
+ fprintf(stderr, "\t [-x proxy_address[:port]] [hostname] [port[s]]\n");
+ if (ret)
+ exit(1);
+}
OpenPOWER on IntegriCloud