Home | History | Annotate | Download | only in nc
      1 /* $OpenBSD: netcat.c,v 1.89 2007/02/20 14:11:17 jmc Exp $ */
      2 /*
      3  * Copyright (c) 2001 Eric Jackson <ericj (at) monkey.org>
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  *
      9  * 1. Redistributions of source code must retain the above copyright
     10  *   notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *   notice, this list of conditions and the following disclaimer in the
     13  *   documentation and/or other materials provided with the distribution.
     14  * 3. The name of the author may not be used to endorse or promote products
     15  *   derived from this software without specific prior written permission.
     16  *
     17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 /*
     30  * Re-written nc(1) for OpenBSD. Original implementation by
     31  * *Hobbit* <hobbit (at) avian.org>.
     32  */
     33 
     34 /*
     35  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     36  * Use is subject to license terms.
     37  */
     38 
     39 /*
     40  * Portions Copyright 2008 Erik Trauschke
     41  */
     42 
     43 #include <sys/types.h>
     44 #include <sys/socket.h>
     45 #include <sys/time.h>
     46 #include <sys/un.h>
     47 
     48 #include <netinet/in.h>
     49 #include <netinet/in_systm.h>
     50 #include <netinet/tcp.h>
     51 #include <netinet/ip.h>
     52 #include <arpa/telnet.h>
     53 
     54 #include <err.h>
     55 #include <errno.h>
     56 #include <netdb.h>
     57 #include <poll.h>
     58 #include <stdarg.h>
     59 #include <stdio.h>
     60 #include <stdlib.h>
     61 #include <string.h>
     62 #include <unistd.h>
     63 #include <fcntl.h>
     64 #include <limits.h>
     65 #include <signal.h>
     66 
     67 #include "atomicio.h"
     68 #include "strtonum.h"
     69 
     70 #ifndef	SUN_LEN
     71 #define	SUN_LEN(su) \
     72 	(sizeof (*(su)) - sizeof ((su)->sun_path) + strlen((su)->sun_path))
     73 #endif
     74 
     75 #define	PORT_MIN	1
     76 #define	PORT_MAX	65535
     77 #define	PORT_MAX_LEN	6
     78 #define	PLIST_SZ	32	/* initial capacity of the portlist */
     79 
     80 /* Command Line Options */
     81 int	dflag;		/* detached, no stdin */
     82 unsigned int iflag;	/* Interval Flag */
     83 int	kflag;		/* More than one connect */
     84 int	lflag;		/* Bind to local port */
     85 int	nflag;		/* Don't do name lookup */
     86 char	*Pflag;		/* Proxy username */
     87 char	*pflag;		/* Localport flag */
     88 int	rflag;		/* Random ports flag */
     89 char	*sflag;		/* Source Address */
     90 int	tflag;		/* Telnet Emulation */
     91 int	uflag;		/* UDP - Default to TCP */
     92 int	vflag;		/* Verbosity */
     93 int	xflag;		/* Socks proxy */
     94 int	Xflag;		/* indicator of Socks version set */
     95 int	zflag;		/* Port Scan Flag */
     96 int	Dflag;		/* sodebug */
     97 int	Tflag = -1;	/* IP Type of Service */
     98 
     99 int	timeout = -1;
    100 int	family = AF_UNSPEC;
    101 
    102 /*
    103  * portlist structure
    104  * Used to store a list of ports given by the user and maintaining
    105  * information about the number of ports stored.
    106  */
    107 struct {
    108 	uint16_t *list; /* list containing the ports */
    109 	uint_t listsize;   /* capacity of the list (number of entries) */
    110 	uint_t numports;   /* number of ports in the list */
    111 } ports;
    112 
    113 void	atelnet(int, unsigned char *, unsigned int);
    114 void	build_ports(char *);
    115 void	help(void);
    116 int	local_listen(char *, char *, struct addrinfo);
    117 void	readwrite(int);
    118 int	remote_connect(const char *, const char *, struct addrinfo);
    119 int	socks_connect(const char *, const char *,
    120 	    const char *, const char *, struct addrinfo, int, const char *);
    121 int	udptest(int);
    122 int	unix_connect(char *);
    123 int	unix_listen(char *);
    124 void	set_common_sockopts(int);
    125 int	parse_iptos(char *);
    126 void	usage(int);
    127 char	*print_addr(char *, size_t, struct sockaddr *, int, int);
    128 
    129 int
    130 main(int argc, char *argv[])
    131 {
    132 	int ch, s, ret, socksv;
    133 	char *host, *uport, *proxy;
    134 	struct addrinfo hints;
    135 	struct servent *sv;
    136 	socklen_t len;
    137 	struct sockaddr_storage cliaddr;
    138 	const char *errstr, *proxyhost = "", *proxyport = NULL;
    139 	struct addrinfo proxyhints;
    140 	char port[PORT_MAX_LEN];
    141 
    142 	ret = 1;
    143 	s = -1;
    144 	socksv = 5;
    145 	host = NULL;
    146 	uport = NULL;
    147 	sv = NULL;
    148 
    149 	while ((ch = getopt(argc, argv,
    150 	    "46Ddhi:klnP:p:rs:T:tUuvw:X:x:z")) != -1) {
    151 		switch (ch) {
    152 		case '4':
    153 			family = AF_INET;
    154 			break;
    155 		case '6':
    156 			family = AF_INET6;
    157 			break;
    158 		case 'U':
    159 			family = AF_UNIX;
    160 			break;
    161 		case 'X':
    162 			Xflag = 1;
    163 			if (strcasecmp(optarg, "connect") == 0)
    164 				socksv = -1; /* HTTP proxy CONNECT */
    165 			else if (strcmp(optarg, "4") == 0)
    166 				socksv = 4; /* SOCKS v.4 */
    167 			else if (strcmp(optarg, "5") == 0)
    168 				socksv = 5; /* SOCKS v.5 */
    169 			else
    170 				errx(1, "unsupported proxy protocol");
    171 			break;
    172 		case 'd':
    173 			dflag = 1;
    174 			break;
    175 		case 'h':
    176 			help();
    177 			break;
    178 		case 'i':
    179 			iflag = strtonum(optarg, 0, UINT_MAX, &errstr);
    180 			if (errstr)
    181 				errx(1, "interval %s: %s", errstr, optarg);
    182 			break;
    183 		case 'k':
    184 			kflag = 1;
    185 			break;
    186 		case 'l':
    187 			lflag = 1;
    188 			break;
    189 		case 'n':
    190 			nflag = 1;
    191 			break;
    192 		case 'P':
    193 			Pflag = optarg;
    194 			break;
    195 		case 'p':
    196 			pflag = optarg;
    197 			break;
    198 		case 'r':
    199 			rflag = 1;
    200 			break;
    201 		case 's':
    202 			sflag = optarg;
    203 			break;
    204 		case 't':
    205 			tflag = 1;
    206 			break;
    207 		case 'u':
    208 			uflag = 1;
    209 			break;
    210 		case 'v':
    211 			vflag = 1;
    212 			break;
    213 		case 'w':
    214 			timeout = strtonum(optarg, 0, INT_MAX / 1000, &errstr);
    215 			if (errstr)
    216 				errx(1, "timeout %s: %s", errstr, optarg);
    217 			timeout *= 1000;
    218 			break;
    219 		case 'x':
    220 			xflag = 1;
    221 			if ((proxy = strdup(optarg)) == NULL)
    222 				err(1, NULL);
    223 			break;
    224 		case 'z':
    225 			zflag = 1;
    226 			break;
    227 		case 'D':
    228 			Dflag = 1;
    229 			break;
    230 		case 'T':
    231 			Tflag = parse_iptos(optarg);
    232 			break;
    233 		default:
    234 			usage(1);
    235 		}
    236 	}
    237 	argc -= optind;
    238 	argv += optind;
    239 
    240 	/* Cruft to make sure options are clean, and used properly. */
    241 	if (argv[0] && !argv[1] && family == AF_UNIX) {
    242 		if (uflag)
    243 			errx(1, "cannot use -u and -U");
    244 		host = argv[0];
    245 		uport = NULL;
    246 	} else if (argv[0] && !argv[1]) {
    247 		if (!lflag)
    248 			usage(1);
    249 		uport = argv[0];
    250 		host = NULL;
    251 	} else if (argv[0] && argv[1]) {
    252 		if (family == AF_UNIX)
    253 			usage(1);
    254 		host = argv[0];
    255 		uport = argv[1];
    256 	} else {
    257 		if (!(lflag && pflag))
    258 			usage(1);
    259 	}
    260 
    261 	if (argc > 2)
    262 		usage(1);
    263 
    264 	if (lflag && sflag)
    265 		errx(1, "cannot use -s and -l");
    266 	if (lflag && rflag)
    267 		errx(1, "cannot use -r and -l");
    268 	if (lflag && (timeout >= 0))
    269 		warnx("-w has no effect with -l");
    270 	if (lflag && pflag) {
    271 		if (uport)
    272 			usage(1);
    273 		uport = pflag;
    274 	}
    275 	if (lflag && zflag)
    276 		errx(1, "cannot use -z and -l");
    277 	if (!lflag && kflag)
    278 		errx(1, "must use -l with -k");
    279 	if (lflag && (Pflag || xflag || Xflag))
    280 		errx(1, "cannot use -l with -P, -X or -x");
    281 
    282 	/* Initialize addrinfo structure. */
    283 	if (family != AF_UNIX) {
    284 		(void) memset(&hints, 0, sizeof (struct addrinfo));
    285 		hints.ai_family = family;
    286 		hints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM;
    287 		hints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP;
    288 		if (nflag)
    289 			hints.ai_flags |= AI_NUMERICHOST;
    290 	}
    291 
    292 	if (xflag) {
    293 		if (uflag)
    294 			errx(1, "no proxy support for UDP mode");
    295 
    296 		if (lflag)
    297 			errx(1, "no proxy support for listen");
    298 
    299 		if (family == AF_UNIX)
    300 			errx(1, "no proxy support for unix sockets");
    301 
    302 		if (family == AF_INET6)
    303 			errx(1, "no proxy support for IPv6");
    304 
    305 		if (sflag)
    306 			errx(1, "no proxy support for local source address");
    307 
    308 		if ((proxyhost = strtok(proxy, ":")) == NULL)
    309 			errx(1, "missing port specification");
    310 		proxyport = strtok(NULL, ":");
    311 
    312 		(void) memset(&proxyhints, 0, sizeof (struct addrinfo));
    313 		proxyhints.ai_family = family;
    314 		proxyhints.ai_socktype = SOCK_STREAM;
    315 		proxyhints.ai_protocol = IPPROTO_TCP;
    316 		if (nflag)
    317 			proxyhints.ai_flags |= AI_NUMERICHOST;
    318 	}
    319 
    320 	if (lflag) {
    321 		int connfd;
    322 		ret = 0;
    323 
    324 		if (family == AF_UNIX) {
    325 			if (host == NULL)
    326 				usage(1);
    327 			s = unix_listen(host);
    328 		}
    329 
    330 		/* Allow only one connection at a time, but stay alive. */
    331 		for (;;) {
    332 			if (family != AF_UNIX) {
    333 				/* check if uport is valid */
    334 				if (strtonum(uport, PORT_MIN, PORT_MAX,
    335 				    &errstr) == 0)
    336 					errx(1, "port number %s: %s",
    337 					    uport, errstr);
    338 				s = local_listen(host, uport, hints);
    339 			}
    340 			if (s < 0)
    341 				err(1, NULL);
    342 			/*
    343 			 * For UDP, we will use recvfrom() initially
    344 			 * to wait for a caller, then use the regular
    345 			 * functions to talk to the caller.
    346 			 */
    347 			if (uflag) {
    348 				int rv, plen;
    349 				char buf[8192];
    350 				struct sockaddr_storage z;
    351 
    352 				len = sizeof (z);
    353 				plen = 1024;
    354 				rv = recvfrom(s, buf, plen, MSG_PEEK,
    355 				    (struct sockaddr *)&z, &len);
    356 				if (rv < 0)
    357 					err(1, "recvfrom");
    358 
    359 				rv = connect(s, (struct sockaddr *)&z, len);
    360 				if (rv < 0)
    361 					err(1, "connect");
    362 
    363 				connfd = s;
    364 			} else {
    365 				len = sizeof (cliaddr);
    366 				connfd = accept(s, (struct sockaddr *)&cliaddr,
    367 				    &len);
    368 				if ((connfd != -1) && vflag) {
    369 					char ntop[NI_MAXHOST + NI_MAXSERV];
    370 					(void) fprintf(stderr,
    371 					    "Received connection from %s\n",
    372 					    print_addr(ntop, sizeof (ntop),
    373 					    (struct sockaddr *)&cliaddr, len,
    374 					    nflag ? NI_NUMERICHOST : 0));
    375 				}
    376 			}
    377 
    378 			readwrite(connfd);
    379 			(void) close(connfd);
    380 			if (family != AF_UNIX)
    381 				(void) close(s);
    382 
    383 			if (!kflag)
    384 				break;
    385 		}
    386 	} else if (family == AF_UNIX) {
    387 		ret = 0;
    388 
    389 		if ((s = unix_connect(host)) > 0 && !zflag) {
    390 			readwrite(s);
    391 			(void) close(s);
    392 		} else
    393 			ret = 1;
    394 
    395 		exit(ret);
    396 
    397 	} else {	/* AF_INET or AF_INET6 */
    398 		int i;
    399 
    400 		/* Construct the portlist. */
    401 		build_ports(uport);
    402 
    403 		/* Cycle through portlist, connecting to each port. */
    404 		for (i = 0; i < ports.numports; i++) {
    405 			(void) snprintf(port, sizeof (port), "%u",
    406 			    ports.list[i]);
    407 
    408 			if (s != -1)
    409 				(void) close(s);
    410 
    411 			if (xflag)
    412 				s = socks_connect(host, port,
    413 				    proxyhost, proxyport, proxyhints, socksv,
    414 				    Pflag);
    415 			else
    416 				s = remote_connect(host, port, hints);
    417 
    418 			if (s < 0)
    419 				continue;
    420 
    421 			ret = 0;
    422 			if (vflag || zflag) {
    423 				/* For UDP, make sure we are connected. */
    424 				if (uflag) {
    425 					if (udptest(s) == -1) {
    426 						ret = 1;
    427 						continue;
    428 					}
    429 				}
    430 
    431 				/* Don't look up port if -n. */
    432 				if (nflag)
    433 					sv = NULL;
    434 				else {
    435 					sv = getservbyport(
    436 					    ntohs(ports.list[i]),
    437 					    uflag ? "udp" : "tcp");
    438 				}
    439 
    440 				(void) fprintf(stderr, "Connection to %s %s "
    441 				    "port [%s/%s] succeeded!\n",
    442 				    host, port, uflag ? "udp" : "tcp",
    443 				    sv ? sv->s_name : "*");
    444 			}
    445 			if (!zflag)
    446 				readwrite(s);
    447 		}
    448 		free(ports.list);
    449 	}
    450 
    451 	if (s != -1)
    452 		(void) close(s);
    453 
    454 	return (ret);
    455 }
    456 
    457 /*
    458  * print IP address and (optionally) a port
    459  */
    460 char *
    461 print_addr(char *ntop, size_t ntlen, struct sockaddr *addr, int len, int flags)
    462 {
    463 	char port[NI_MAXSERV];
    464 	int e;
    465 
    466 	/* print port always as number */
    467 	if ((e = getnameinfo(addr, len, ntop, ntlen,
    468 	    port, sizeof (port), flags|NI_NUMERICSERV)) != 0) {
    469 		return ((char *)gai_strerror(e));
    470 	}
    471 
    472 	(void) snprintf(ntop, ntlen, "%s port %s", ntop, port);
    473 
    474 	return (ntop);
    475 }
    476 
    477 /*
    478  * unix_connect()
    479  * Returns a socket connected to a local unix socket. Returns -1 on failure.
    480  */
    481 int
    482 unix_connect(char *path)
    483 {
    484 	struct sockaddr_un sunaddr;
    485 	int s;
    486 
    487 	if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
    488 		return (-1);
    489 
    490 	(void) memset(&sunaddr, 0, sizeof (struct sockaddr_un));
    491 	sunaddr.sun_family = AF_UNIX;
    492 
    493 	if (strlcpy(sunaddr.sun_path, path, sizeof (sunaddr.sun_path)) >=
    494 	    sizeof (sunaddr.sun_path)) {
    495 		(void) close(s);
    496 		errno = ENAMETOOLONG;
    497 		return (-1);
    498 	}
    499 	if (connect(s, (struct sockaddr *)&sunaddr, SUN_LEN(&sunaddr)) < 0) {
    500 		(void) close(s);
    501 		return (-1);
    502 	}
    503 	return (s);
    504 }
    505 
    506 /*
    507  * unix_listen()
    508  * Create a unix domain socket, and listen on it.
    509  */
    510 int
    511 unix_listen(char *path)
    512 {
    513 	struct sockaddr_un sunaddr;
    514 	int s;
    515 
    516 	/* Create unix domain socket. */
    517 	if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
    518 		return (-1);
    519 
    520 	(void) memset(&sunaddr, 0, sizeof (struct sockaddr_un));
    521 	sunaddr.sun_family = AF_UNIX;
    522 
    523 	if (strlcpy(sunaddr.sun_path, path, sizeof (sunaddr.sun_path)) >=
    524 	    sizeof (sunaddr.sun_path)) {
    525 		(void) close(s);
    526 		errno = ENAMETOOLONG;
    527 		return (-1);
    528 	}
    529 
    530 	if (bind(s, (struct sockaddr *)&sunaddr, SUN_LEN(&sunaddr)) < 0) {
    531 		(void) close(s);
    532 		return (-1);
    533 	}
    534 
    535 	if (listen(s, 5) < 0) {
    536 		(void) close(s);
    537 		return (-1);
    538 	}
    539 	return (s);
    540 }
    541 
    542 /*
    543  * remote_connect()
    544  * Returns a socket connected to a remote host. Properly binds to a local
    545  * port or source address if needed. Returns -1 on failure.
    546  */
    547 int
    548 remote_connect(const char *host, const char *port, struct addrinfo hints)
    549 {
    550 	struct addrinfo *res, *res0;
    551 	int s, error;
    552 
    553 	if ((error = getaddrinfo(host, port, &hints, &res)))
    554 		errx(1, "getaddrinfo: %s", gai_strerror(error));
    555 
    556 	res0 = res;
    557 	do {
    558 		if ((s = socket(res0->ai_family, res0->ai_socktype,
    559 		    res0->ai_protocol)) < 0) {
    560 			warn("failed to create socket");
    561 			continue;
    562 		}
    563 
    564 		/* Bind to a local port or source address if specified. */
    565 		if (sflag || pflag) {
    566 			struct addrinfo ahints, *ares;
    567 
    568 			(void) memset(&ahints, 0, sizeof (struct addrinfo));
    569 			ahints.ai_family = res0->ai_family;
    570 			ahints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM;
    571 			ahints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP;
    572 			ahints.ai_flags = AI_PASSIVE;
    573 			if ((error = getaddrinfo(sflag, pflag, &ahints, &ares)))
    574 				errx(1, "getaddrinfo: %s", gai_strerror(error));
    575 
    576 			if (bind(s, (struct sockaddr *)ares->ai_addr,
    577 			    ares->ai_addrlen) < 0)
    578 				errx(1, "bind failed: %s", strerror(errno));
    579 			freeaddrinfo(ares);
    580 
    581 			if (vflag && !lflag) {
    582 				if (sflag != NULL)
    583 					(void) fprintf(stderr,
    584 					    "Using source address: %s\n",
    585 					    sflag);
    586 				if (pflag != NULL)
    587 					(void) fprintf(stderr,
    588 					    "Using source port: %s\n", pflag);
    589 			}
    590 		}
    591 
    592 		set_common_sockopts(s);
    593 
    594 		if (connect(s, res0->ai_addr, res0->ai_addrlen) == 0)
    595 			break;
    596 		else if (vflag) {
    597 			char ntop[NI_MAXHOST + NI_MAXSERV];
    598 			warn("connect to %s [host %s] (%s) failed",
    599 			    print_addr(ntop, sizeof (ntop),
    600 			    res0->ai_addr, res0->ai_addrlen, NI_NUMERICHOST),
    601 			    host, uflag ? "udp" : "tcp");
    602 		}
    603 
    604 		(void) close(s);
    605 		s = -1;
    606 	} while ((res0 = res0->ai_next) != NULL);
    607 
    608 	freeaddrinfo(res);
    609 
    610 	return (s);
    611 }
    612 
    613 /*
    614  * local_listen()
    615  * Returns a socket listening on a local port, binds to specified source
    616  * address. Returns -1 on failure.
    617  */
    618 int
    619 local_listen(char *host, char *port, struct addrinfo hints)
    620 {
    621 	struct addrinfo *res, *res0;
    622 	int s, ret, x = 1;
    623 	int error;
    624 
    625 	/* Allow nodename to be null. */
    626 	hints.ai_flags |= AI_PASSIVE;
    627 
    628 	if ((error = getaddrinfo(host, port, &hints, &res)))
    629 		errx(1, "getaddrinfo: %s", gai_strerror(error));
    630 
    631 	res0 = res;
    632 	do {
    633 		if ((s = socket(res0->ai_family, res0->ai_socktype,
    634 		    res0->ai_protocol)) < 0) {
    635 			warn("failed to create socket");
    636 			continue;
    637 		}
    638 
    639 		ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &x, sizeof (x));
    640 		if (ret == -1)
    641 			err(1, NULL);
    642 
    643 		set_common_sockopts(s);
    644 
    645 		if (bind(s, (struct sockaddr *)res0->ai_addr,
    646 		    res0->ai_addrlen) == 0)
    647 			break;
    648 
    649 		(void) close(s);
    650 		s = -1;
    651 	} while ((res0 = res0->ai_next) != NULL);
    652 
    653 	if (!uflag && s != -1) {
    654 		if (listen(s, 1) < 0)
    655 			err(1, "listen");
    656 	}
    657 
    658 	freeaddrinfo(res);
    659 
    660 	return (s);
    661 }
    662 
    663 /*
    664  * readwrite()
    665  * Loop that polls on the network file descriptor and stdin.
    666  */
    667 void
    668 readwrite(int nfd)
    669 {
    670 	struct pollfd pfd[2];
    671 	unsigned char buf[8192];
    672 	int n, wfd = fileno(stdin);
    673 	int lfd = fileno(stdout);
    674 	int plen;
    675 
    676 	plen = 1024;
    677 
    678 	/* Setup Network FD */
    679 	pfd[0].fd = nfd;
    680 	pfd[0].events = POLLIN;
    681 
    682 	/* Set up STDIN FD. */
    683 	pfd[1].fd = wfd;
    684 	pfd[1].events = POLLIN;
    685 
    686 	while (pfd[0].fd != -1) {
    687 		if (iflag)
    688 			(void) sleep(iflag);
    689 
    690 		if ((n = poll(pfd, 2 - dflag, timeout)) < 0) {
    691 			(void) close(nfd);
    692 			err(1, "Polling Error");
    693 		}
    694 
    695 		if (n == 0)
    696 			return;
    697 
    698 		if (pfd[0].revents & (POLLIN|POLLHUP)) {
    699 			if ((n = read(nfd, buf, plen)) < 0)
    700 				return;
    701 			else if (n == 0) {
    702 				(void) shutdown(nfd, SHUT_RD);
    703 				pfd[0].fd = -1;
    704 				pfd[0].events = 0;
    705 			} else {
    706 				if (tflag)
    707 					atelnet(nfd, buf, n);
    708 				if (atomicio(vwrite, lfd, buf, n) != n)
    709 					return;
    710 			}
    711 		}
    712 
    713 		/*
    714 		 * handle the case of disconnected pipe: after pipe
    715 		 * is closed (indicated by POLLHUP) there may still
    716 		 * be some data lingering (POLLIN). After we read
    717 		 * the data, only POLLHUP remains, read() returns 0
    718 		 * and we are finished.
    719 		 */
    720 		if (!dflag && (pfd[1].revents & (POLLIN|POLLHUP))) {
    721 			if ((n = read(wfd, buf, plen)) < 0)
    722 				return;
    723 			else if (n == 0) {
    724 				(void) shutdown(nfd, SHUT_WR);
    725 				pfd[1].fd = -1;
    726 				pfd[1].events = 0;
    727 			} else {
    728 				if (atomicio(vwrite, nfd, buf, n) != n)
    729 					return;
    730 			}
    731 		}
    732 	}
    733 }
    734 
    735 /* Deal with RFC 854 WILL/WONT DO/DONT negotiation. */
    736 void
    737 atelnet(int nfd, unsigned char *buf, unsigned int size)
    738 {
    739 	unsigned char *p, *end;
    740 	unsigned char obuf[4];
    741 
    742 	end = buf + size;
    743 	obuf[0] = '\0';
    744 
    745 	for (p = buf; p < end; p++) {
    746 		if (*p != IAC)
    747 			break;
    748 
    749 		obuf[0] = IAC;
    750 		obuf[1] = 0;
    751 		p++;
    752 		/* refuse all options */
    753 		if ((*p == WILL) || (*p == WONT))
    754 			obuf[1] = DONT;
    755 		if ((*p == DO) || (*p == DONT))
    756 			obuf[1] = WONT;
    757 		if (obuf[1]) {
    758 			p++;
    759 			obuf[2] = *p;
    760 			obuf[3] = '\0';
    761 			if (atomicio(vwrite, nfd, obuf, 3) != 3)
    762 				warn("Write Error!");
    763 			obuf[0] = '\0';
    764 		}
    765 	}
    766 }
    767 
    768 /*
    769  * build_ports()
    770  * Build an array of ports in ports.list[], listing each port
    771  * that we should try to connect to.
    772  */
    773 void
    774 build_ports(char *p)
    775 {
    776 	const char *errstr;
    777 	const char *token;
    778 	char *n;
    779 	int lo, hi, cp;
    780 	int i;
    781 
    782 	/* Set up initial portlist. */
    783 	ports.list = malloc(PLIST_SZ * sizeof (uint16_t));
    784 	if (ports.list == NULL)
    785 		err(1, NULL);
    786 	ports.listsize = PLIST_SZ;
    787 	ports.numports = 0;
    788 
    789 	/* Cycle through list of given ports sep. by "," */
    790 	while ((token = strsep(&p, ",")) != NULL) {
    791 		if (*token == '\0')
    792 			errx(1, "Invalid port/portlist format: "
    793 			    "zero length port");
    794 
    795 		/* check if it is a range */
    796 		if ((n = strchr(token, '-')) != NULL)
    797 			*n++ = '\0';
    798 
    799 		lo = strtonum(token, PORT_MIN, PORT_MAX, &errstr);
    800 		if (errstr)
    801 			errx(1, "port number %s: %s", errstr, token);
    802 
    803 		if (n == NULL) {
    804 			hi = lo;
    805 		} else {
    806 			hi = strtonum(n, PORT_MIN, PORT_MAX, &errstr);
    807 			if (errstr)
    808 				errx(1, "port number %s: %s", errstr, n);
    809 			if (lo > hi) {
    810 				cp = hi;
    811 				hi = lo;
    812 				lo = cp;
    813 			}
    814 		}
    815 
    816 		/*
    817 		 * Grow the portlist if needed.
    818 		 * We double the size and add size of current range
    819 		 * to make sure we don't have to resize that often.
    820 		 */
    821 		if (hi - lo + ports.numports + 1 >= ports.listsize) {
    822 			ports.listsize = ports.listsize * 2 + hi - lo;
    823 			ports.list = realloc(ports.list,
    824 			    ports.listsize * sizeof (uint16_t));
    825 			if (ports.list == NULL)
    826 				err(1, NULL);
    827 		}
    828 
    829 		/* Load ports sequentially. */
    830 		for (i = lo; i <= hi; i++)
    831 			ports.list[ports.numports++] = i;
    832 	}
    833 
    834 	/* Randomly swap ports. */
    835 	if (rflag) {
    836 		int y;
    837 		uint16_t u;
    838 
    839 		if (ports.numports < 2) {
    840 			warnx("can not swap %d port randomly",
    841 			    ports.numports);
    842 			return;
    843 		}
    844 		srandom(time(NULL));
    845 		for (i = 0; i < ports.numports; i++) {
    846 			y = random() % (ports.numports - 1);
    847 			u = ports.list[i];
    848 			ports.list[i] = ports.list[y];
    849 			ports.list[y] = u;
    850 		}
    851 	}
    852 }
    853 
    854 /*
    855  * udptest()
    856  * Do a few writes to see if the UDP port is there.
    857  * XXX - Better way of doing this? Doesn't work for IPv6.
    858  * Also fails after around 100 ports checked.
    859  */
    860 int
    861 udptest(int s)
    862 {
    863 	int i, ret;
    864 
    865 	for (i = 0; i <= 3; i++) {
    866 		if (write(s, "X", 1) == 1)
    867 			ret = 1;
    868 		else
    869 			ret = -1;
    870 	}
    871 	return (ret);
    872 }
    873 
    874 void
    875 set_common_sockopts(int s)
    876 {
    877 	int x = 1;
    878 
    879 	if (Dflag) {
    880 		if (setsockopt(s, SOL_SOCKET, SO_DEBUG, &x, sizeof (x)) == -1)
    881 			err(1, NULL);
    882 	}
    883 	if (Tflag != -1) {
    884 		if (setsockopt(s, IPPROTO_IP, IP_TOS, &Tflag,
    885 		    sizeof (Tflag)) == -1)
    886 			err(1, "set IP ToS");
    887 	}
    888 }
    889 
    890 int
    891 parse_iptos(char *s)
    892 {
    893 	int tos = -1;
    894 
    895 	if (strcmp(s, "lowdelay") == 0)
    896 		return (IPTOS_LOWDELAY);
    897 	if (strcmp(s, "throughput") == 0)
    898 		return (IPTOS_THROUGHPUT);
    899 	if (strcmp(s, "reliability") == 0)
    900 		return (IPTOS_RELIABILITY);
    901 
    902 	if (sscanf(s, "0x%x", (unsigned int *) &tos) != 1 ||
    903 	    tos < 0 || tos > 0xff)
    904 		errx(1, "invalid IP Type of Service");
    905 	return (tos);
    906 }
    907 
    908 void
    909 help(void)
    910 {
    911 	usage(0);
    912 	(void) fprintf(stderr, "\tCommand Summary:\n\
    913 	\t-4		Use IPv4\n\
    914 	\t-6		Use IPv6\n\
    915 	\t-D		Enable the debug socket option\n\
    916 	\t-d		Detach from stdin\n\
    917 	\t-h		This help text\n\
    918 	\t-i secs\t	Delay interval for lines sent, ports scanned\n\
    919 	\t-k		Keep inbound sockets open for multiple connects\n\
    920 	\t-l		Listen mode, for inbound connects\n\
    921 	\t-n		Suppress name/port resolutions\n\
    922 	\t-P proxyuser\tUsername for proxy authentication\n\
    923 	\t-p port\t	Specify local port or listen port\n\
    924 	\t-r		Randomize remote ports\n\
    925 	\t-s addr\t	Local source address\n\
    926 	\t-T ToS\t	Set IP Type of Service\n\
    927 	\t-t		Answer TELNET negotiation\n\
    928 	\t-U		Use UNIX domain socket\n\
    929 	\t-u		UDP mode\n\
    930 	\t-v		Verbose\n\
    931 	\t-w secs\t	Timeout for connects and final net reads\n\
    932 	\t-X proto	Proxy protocol: \"4\", \"5\" (SOCKS) or \"connect\"\n\
    933 	\t-x addr[:port]\tSpecify proxy address and port\n\
    934 	\t-z		Zero-I/O mode [used for scanning]\n\
    935 	Port numbers can be individuals, ranges (lo-hi; inclusive) and\n\
    936 	combinations of both separated by comma (e.g. 10,22-25,80)\n");
    937 	exit(1);
    938 }
    939 
    940 void
    941 usage(int ret)
    942 {
    943 	(void) fprintf(stderr,
    944 	    "usage: nc [-46DdhklnrtUuvz] [-i interval] [-P proxy_username]"
    945 	    " [-p port]\n");
    946 	(void) fprintf(stderr,
    947 	    "\t  [-s source_ip_address] [-T ToS] [-w timeout]"
    948 	    " [-X proxy_protocol]\n");
    949 	(void) fprintf(stderr,
    950 	    "\t  [-x proxy_address[:port]] [hostname]"
    951 	    " [port[s]]\n");
    952 	if (ret)
    953 		exit(1);
    954 }
    955