03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk/* $OpenBSD: netcat.c,v 1.89 2007/02/20 14:11:17 jmc Exp $ */
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * Copyright (c) 2001 Eric Jackson <ericj@monkey.org>
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * Redistribution and use in source and binary forms, with or without
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * modification, are permitted provided that the following conditions
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * are met:
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * 1. Redistributions of source code must retain the above copyright
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * notice, this list of conditions and the following disclaimer.
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * 2. Redistributions in binary form must reproduce the above copyright
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * notice, this list of conditions and the following disclaimer in the
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * documentation and/or other materials provided with the distribution.
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * 3. The name of the author may not be used to endorse or promote products
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * derived from this software without specific prior written permission.
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * Re-written nc(1) for OpenBSD. Original implementation by
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * *Hobbit* <hobbit@avian.org>.
f8c3982ab1838a24e4b671d13329f52bbbebc2a7vk * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
f8c3982ab1838a24e4b671d13329f52bbbebc2a7vk * Use is subject to license terms.
2eef1f2b3c0d57d3f401f917b9f38f01456fd554Erik Trauschke * Portions Copyright 2008 Erik Trauschke
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk (sizeof (*(su)) - sizeof ((su)->sun_path) + strlen((su)->sun_path))
2eef1f2b3c0d57d3f401f917b9f38f01456fd554Erik Trauschke#define PLIST_SZ 32 /* initial capacity of the portlist */
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk/* Command Line Options */
2eef1f2b3c0d57d3f401f917b9f38f01456fd554Erik Trauschke * portlist structure
2eef1f2b3c0d57d3f401f917b9f38f01456fd554Erik Trauschke * Used to store a list of ports given by the user and maintaining
2eef1f2b3c0d57d3f401f917b9f38f01456fd554Erik Trauschke * information about the number of ports stored.
2eef1f2b3c0d57d3f401f917b9f38f01456fd554Erik Trauschke uint16_t *list; /* list containing the ports */
2eef1f2b3c0d57d3f401f917b9f38f01456fd554Erik Trauschke uint_t listsize; /* capacity of the list (number of entries) */
2eef1f2b3c0d57d3f401f917b9f38f01456fd554Erik Trauschke uint_t numports; /* number of ports in the list */
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vkvoid atelnet(int, unsigned char *, unsigned int);
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vkvoid build_ports(char *);
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vkvoid help(void);
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vkint remote_connect(const char *, const char *, struct addrinfo);
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vkint socks_connect(const char *, const char *,
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk const char *, const char *, struct addrinfo, int, const char *);
f8c3982ab1838a24e4b671d13329f52bbbebc2a7vkchar *print_addr(char *, size_t, struct sockaddr *, int, int);
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk switch (ch) {
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk /* Cruft to make sure options are clean, and used properly. */
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk /* Initialize addrinfo structure. */
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk /* Allow only one connection at a time, but stay alive. */
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk for (;;) {
2eef1f2b3c0d57d3f401f917b9f38f01456fd554Erik Trauschke /* check if uport is valid */
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk if (s < 0)
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * For UDP, we will use recvfrom() initially
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * to wait for a caller, then use the regular
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * functions to talk to the caller.
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk len = sizeof (z);
f8c3982ab1838a24e4b671d13329f52bbbebc2a7vk "Received connection from %s\n",
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk (void) close(s);
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk (void) close(s);
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk } else { /* AF_INET or AF_INET6 */
2eef1f2b3c0d57d3f401f917b9f38f01456fd554Erik Trauschke /* Construct the portlist. */
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk /* Cycle through portlist, connecting to each port. */
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk (void) close(s);
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk if (s < 0)
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk /* For UDP, make sure we are connected. */
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk /* Don't look up port if -n. */
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk "port [%s/%s] succeeded!\n",
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk (void) close(s);
f8c3982ab1838a24e4b671d13329f52bbbebc2a7vk * print IP address and (optionally) a port
f8c3982ab1838a24e4b671d13329f52bbbebc2a7vkprint_addr(char *ntop, size_t ntlen, struct sockaddr *addr, int len, int flags)
f8c3982ab1838a24e4b671d13329f52bbbebc2a7vk /* print port always as number */
f8c3982ab1838a24e4b671d13329f52bbbebc2a7vk return ((char *)gai_strerror(e));
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * unix_connect()
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * Returns a socket connected to a local unix socket. Returns -1 on failure.
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk return (-1);
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk if (strlcpy(sunaddr.sun_path, path, sizeof (sunaddr.sun_path)) >=
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk (void) close(s);
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk return (-1);
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk if (connect(s, (struct sockaddr *)&sunaddr, SUN_LEN(&sunaddr)) < 0) {
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk (void) close(s);
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk return (-1);
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk return (s);
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * unix_listen()
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * Create a unix domain socket, and listen on it.
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk /* Create unix domain socket. */
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk return (-1);
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk if (strlcpy(sunaddr.sun_path, path, sizeof (sunaddr.sun_path)) >=
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk (void) close(s);
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk return (-1);
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk if (bind(s, (struct sockaddr *)&sunaddr, SUN_LEN(&sunaddr)) < 0) {
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk (void) close(s);
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk return (-1);
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk (void) close(s);
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk return (-1);
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk return (s);
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * remote_connect()
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * Returns a socket connected to a remote host. Properly binds to a local
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * port or source address if needed. Returns -1 on failure.
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vkremote_connect(const char *host, const char *port, struct addrinfo hints)
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk /* Bind to a local port or source address if specified. */
f8c3982ab1838a24e4b671d13329f52bbbebc2a7vk "Using source address: %s\n",
f8c3982ab1838a24e4b671d13329f52bbbebc2a7vk else if (vflag) {
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk (void) close(s);
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk return (s);
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * local_listen()
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * Returns a socket listening on a local port, binds to specified source
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * address. Returns -1 on failure.
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vklocal_listen(char *host, char *port, struct addrinfo hints)
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk /* Allow nodename to be null. */
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &x, sizeof (x));
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk (void) close(s);
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk return (s);
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * readwrite()
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * Loop that polls on the network file descriptor and stdin.
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk /* Setup Network FD */
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk /* Set up STDIN FD. */
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk if (n == 0)
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk else if (n == 0) {
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * handle the case of disconnected pipe: after pipe
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * is closed (indicated by POLLHUP) there may still
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * be some data lingering (POLLIN). After we read
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * the data, only POLLHUP remains, read() returns 0
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * and we are finished.
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk else if (n == 0) {
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk if (*p != IAC)
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk /* refuse all options */
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * build_ports()
2eef1f2b3c0d57d3f401f917b9f38f01456fd554Erik Trauschke * Build an array of ports in ports.list[], listing each port
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * that we should try to connect to.
2eef1f2b3c0d57d3f401f917b9f38f01456fd554Erik Trauschke /* Set up initial portlist. */
2eef1f2b3c0d57d3f401f917b9f38f01456fd554Erik Trauschke ports.list = malloc(PLIST_SZ * sizeof (uint16_t));
2eef1f2b3c0d57d3f401f917b9f38f01456fd554Erik Trauschke /* Cycle through list of given ports sep. by "," */
2eef1f2b3c0d57d3f401f917b9f38f01456fd554Erik Trauschke "zero length port");
2eef1f2b3c0d57d3f401f917b9f38f01456fd554Erik Trauschke /* check if it is a range */
2eef1f2b3c0d57d3f401f917b9f38f01456fd554Erik Trauschke lo = strtonum(token, PORT_MIN, PORT_MAX, &errstr);
2eef1f2b3c0d57d3f401f917b9f38f01456fd554Erik Trauschke errx(1, "port number %s: %s", errstr, token);
2eef1f2b3c0d57d3f401f917b9f38f01456fd554Erik Trauschke hi = strtonum(n, PORT_MIN, PORT_MAX, &errstr);
2eef1f2b3c0d57d3f401f917b9f38f01456fd554Erik Trauschke * Grow the portlist if needed.
2eef1f2b3c0d57d3f401f917b9f38f01456fd554Erik Trauschke * We double the size and add size of current range
2eef1f2b3c0d57d3f401f917b9f38f01456fd554Erik Trauschke * to make sure we don't have to resize that often.
2eef1f2b3c0d57d3f401f917b9f38f01456fd554Erik Trauschke if (hi - lo + ports.numports + 1 >= ports.listsize) {
2eef1f2b3c0d57d3f401f917b9f38f01456fd554Erik Trauschke ports.listsize = ports.listsize * 2 + hi - lo;
2eef1f2b3c0d57d3f401f917b9f38f01456fd554Erik Trauschke /* Load ports sequentially. */
2eef1f2b3c0d57d3f401f917b9f38f01456fd554Erik Trauschke /* Randomly swap ports. */
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * udptest()
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * Do a few writes to see if the UDP port is there.
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * XXX - Better way of doing this? Doesn't work for IPv6.
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * Also fails after around 100 ports checked.
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk for (i = 0; i <= 3; i++) {
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk int x = 1;
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk if (setsockopt(s, SOL_SOCKET, SO_DEBUG, &x, sizeof (x)) == -1)
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk \t-4 Use IPv4\n\
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk \t-6 Use IPv6\n\
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk \t-D Enable the debug socket option\n\
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk \t-d Detach from stdin\n\
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk \t-h This help text\n\
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk \t-i secs\t Delay interval for lines sent, ports scanned\n\
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk \t-k Keep inbound sockets open for multiple connects\n\
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk \t-l Listen mode, for inbound connects\n\
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk \t-n Suppress name/port resolutions\n\
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk \t-P proxyuser\tUsername for proxy authentication\n\
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk \t-p port\t Specify local port or listen port\n\
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk \t-r Randomize remote ports\n\
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk \t-s addr\t Local source address\n\
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk \t-T ToS\t Set IP Type of Service\n\
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk \t-t Answer TELNET negotiation\n\
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk \t-U Use UNIX domain socket\n\
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk \t-u UDP mode\n\
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk \t-v Verbose\n\
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk \t-w secs\t Timeout for connects and final net reads\n\
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk \t-X proto Proxy protocol: \"4\", \"5\" (SOCKS) or \"connect\"\n\
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk \t-x addr[:port]\tSpecify proxy address and port\n\
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk \t-z Zero-I/O mode [used for scanning]\n\
2eef1f2b3c0d57d3f401f917b9f38f01456fd554Erik Trauschke Port numbers can be individuals, ranges (lo-hi; inclusive) and\n\
2eef1f2b3c0d57d3f401f917b9f38f01456fd554Erik Trauschke combinations of both separated by comma (e.g. 10,22-25,80)\n");
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk "usage: nc [-46DdhklnrtUuvz] [-i interval] [-P proxy_username]"
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk " [-p port]\n");
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk "\t [-s source_ip_address] [-T ToS] [-w timeout]"
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk " [-X proxy_protocol]\n");
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk "\t [-x proxy_address[:port]] [hostname]"
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk " [port[s]]\n");