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