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