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