netcat.c revision 264911
1/* $OpenBSD: netcat.c,v 1.117 2013/10/26 21:33:29 sthen 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: stable/10/contrib/netcat/netcat.c 264911 2014-04-25 04:49: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/sysctl.h>
40#include <sys/time.h>
41#include <sys/uio.h>
42#include <sys/un.h>
43
44#include <netinet/in.h>
45#include <netinet/in_systm.h>
46#ifdef IPSEC
47#include <netipsec/ipsec.h>
48#endif
49#include <netinet/tcp.h>
50#include <netinet/ip.h>
51#include <arpa/telnet.h>
52
53#include <err.h>
54#include <errno.h>
55#include <getopt.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 "atomicio.h"
66
67#ifndef SUN_LEN
68#define SUN_LEN(su) \
69	(sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
70#endif
71
72#define PORT_MAX	65535
73#define PORT_MAX_LEN	6
74#define UNIX_DG_TMP_SOCKET_SIZE	19
75
76/* Command Line Options */
77int	dflag;					/* detached, no stdin */
78int	Fflag;					/* fdpass sock to stdout */
79unsigned int iflag;				/* Interval Flag */
80int	kflag;					/* More than one connect */
81int	lflag;					/* Bind to local port */
82int	Nflag;					/* shutdown() network socket */
83int	nflag;					/* Don't do name look up */
84int	FreeBSD_Oflag;				/* Do not use TCP options */
85char   *Pflag;					/* Proxy username */
86char   *pflag;					/* Localport flag */
87int	rflag;					/* Random ports flag */
88char   *sflag;					/* Source Address */
89int	tflag;					/* Telnet Emulation */
90int	uflag;					/* UDP - Default to TCP */
91int	vflag;					/* Verbosity */
92int	xflag;					/* Socks proxy */
93int	zflag;					/* Port Scan Flag */
94int	Dflag;					/* sodebug */
95int	Iflag;					/* TCP receive buffer size */
96int	Oflag;					/* TCP send buffer size */
97int	Sflag;					/* TCP MD5 signature option */
98int	Tflag = -1;				/* IP Type of Service */
99int	rtableid = -1;
100
101int timeout = -1;
102int family = AF_UNSPEC;
103char *portlist[PORT_MAX+1];
104char *unix_dg_tmp_socket;
105
106void	atelnet(int, unsigned char *, unsigned int);
107void	build_ports(char *);
108void	help(void);
109int	local_listen(char *, char *, struct addrinfo);
110void	readwrite(int);
111void	fdpass(int nfd) __attribute__((noreturn));
112int	remote_connect(const char *, const char *, struct addrinfo);
113int	timeout_connect(int, const struct sockaddr *, socklen_t);
114int	socks_connect(const char *, const char *, struct addrinfo,
115	    const char *, const char *, struct addrinfo, int, const char *);
116int	udptest(int);
117int	unix_bind(char *);
118int	unix_connect(char *);
119int	unix_listen(char *);
120void	set_common_sockopts(int);
121int	map_tos(char *, int *);
122void	report_connect(const struct sockaddr *, socklen_t);
123void	usage(int);
124
125#ifdef IPSEC
126void	add_ipsec_policy(int, char *);
127
128char	*ipsec_policy[2];
129#endif
130
131int
132main(int argc, char *argv[])
133{
134	int ch, s, ret, socksv, ipsec_count;
135	int numfibs;
136	size_t intsize = sizeof(int);
137	char *host, *uport;
138	struct addrinfo hints;
139	struct servent *sv;
140	socklen_t len;
141	struct sockaddr_storage cliaddr;
142	char *proxy;
143	const char *errstr, *proxyhost = "", *proxyport = NULL;
144	struct addrinfo proxyhints;
145	char unix_dg_tmp_socket_buf[UNIX_DG_TMP_SOCKET_SIZE];
146	struct option longopts[] = {
147		{ "no-tcpopt",	no_argument,	&FreeBSD_Oflag,	1 },
148		{ NULL,		0,		NULL,		0 }
149	};
150
151	ret = 1;
152	ipsec_count = 0;
153	s = 0;
154	socksv = 5;
155	host = NULL;
156	uport = NULL;
157	sv = NULL;
158#if 0
159	rtableid = getrtable();
160#endif
161
162	while ((ch = getopt_long(argc, argv,
163	    "46DdEe:FhI:i:klNnoO:P:p:rSs:tT:UuV:vw:X:x:z",
164	    longopts, NULL)) != -1) {
165		switch (ch) {
166		case '4':
167			family = AF_INET;
168			break;
169		case '6':
170			family = AF_INET6;
171			break;
172		case 'U':
173			family = AF_UNIX;
174			break;
175		case 'X':
176			if (strcasecmp(optarg, "connect") == 0)
177				socksv = -1; /* HTTP proxy CONNECT */
178			else if (strcmp(optarg, "4") == 0)
179				socksv = 4; /* SOCKS v.4 */
180			else if (strcmp(optarg, "5") == 0)
181				socksv = 5; /* SOCKS v.5 */
182			else
183				errx(1, "unsupported proxy protocol");
184			break;
185		case 'd':
186			dflag = 1;
187			break;
188		case 'e':
189#ifdef IPSEC
190			ipsec_policy[ipsec_count++ % 2] = optarg;
191#else
192			errx(1, "IPsec support unavailable.");
193#endif
194			break;
195		case 'E':
196#ifdef IPSEC
197			ipsec_policy[0] = "in  ipsec esp/transport//require";
198			ipsec_policy[1] = "out ipsec esp/transport//require";
199#else
200			errx(1, "IPsec support unavailable.");
201#endif
202			break;
203		case 'F':
204			Fflag = 1;
205			break;
206		case 'h':
207			help();
208			break;
209		case 'i':
210			iflag = strtonum(optarg, 0, UINT_MAX, &errstr);
211			if (errstr)
212				errx(1, "interval %s: %s", errstr, optarg);
213			break;
214		case 'k':
215			kflag = 1;
216			break;
217		case 'l':
218			lflag = 1;
219			break;
220		case 'N':
221			Nflag = 1;
222			break;
223		case 'n':
224			nflag = 1;
225			break;
226		case 'o':
227			fprintf(stderr, "option -o is deprecated.\n");
228			break;
229		case 'P':
230			Pflag = optarg;
231			break;
232		case 'p':
233			pflag = optarg;
234			break;
235		case 'r':
236			rflag = 1;
237			break;
238		case 's':
239			sflag = optarg;
240			break;
241		case 't':
242			tflag = 1;
243			break;
244		case 'u':
245			uflag = 1;
246			break;
247		case 'V':
248			if (sysctlbyname("net.fibs", &numfibs, &intsize, NULL, 0) == -1)
249				errx(1, "Multiple FIBS not supported");
250			rtableid = (int)strtonum(optarg, 0,
251			    numfibs - 1, &errstr);
252			if (errstr)
253				errx(1, "rtable %s: %s", errstr, optarg);
254			break;
255		case 'v':
256			vflag = 1;
257			break;
258		case 'w':
259			timeout = strtonum(optarg, 0, INT_MAX / 1000, &errstr);
260			if (errstr)
261				errx(1, "timeout %s: %s", errstr, optarg);
262			timeout *= 1000;
263			break;
264		case 'x':
265			xflag = 1;
266			if ((proxy = strdup(optarg)) == NULL)
267				err(1, NULL);
268			break;
269		case 'z':
270			zflag = 1;
271			break;
272		case 'D':
273			Dflag = 1;
274			break;
275		case 'I':
276			Iflag = strtonum(optarg, 1, 65536 << 14, &errstr);
277			if (errstr != NULL)
278				errx(1, "TCP receive window %s: %s",
279				    errstr, optarg);
280			break;
281		case 'O':
282			Oflag = strtonum(optarg, 1, 65536 << 14, &errstr);
283			if (errstr != NULL) {
284			    if (strcmp(errstr, "invalid") != 0)
285				errx(1, "TCP send window %s: %s",
286				    errstr, optarg);
287			}
288			break;
289		case 'S':
290			Sflag = 1;
291			break;
292		case 'T':
293			errstr = NULL;
294			errno = 0;
295			if (map_tos(optarg, &Tflag))
296				break;
297			if (strlen(optarg) > 1 && optarg[0] == '0' &&
298			    optarg[1] == 'x')
299				Tflag = (int)strtol(optarg, NULL, 16);
300			else
301				Tflag = (int)strtonum(optarg, 0, 255,
302				    &errstr);
303			if (Tflag < 0 || Tflag > 255 || errstr || errno)
304				errx(1, "illegal tos value %s", optarg);
305			break;
306		default:
307			usage(1);
308		}
309	}
310	argc -= optind;
311	argv += optind;
312
313	/* Cruft to make sure options are clean, and used properly. */
314	if (argv[0] && !argv[1] && family == AF_UNIX) {
315		host = argv[0];
316		uport = NULL;
317	} else if (argv[0] && !argv[1]) {
318		if  (!lflag)
319			usage(1);
320		uport = argv[0];
321		host = NULL;
322	} else if (argv[0] && argv[1]) {
323		host = argv[0];
324		uport = argv[1];
325	} else
326		usage(1);
327
328	if (lflag && sflag)
329		errx(1, "cannot use -s and -l");
330	if (lflag && pflag)
331		errx(1, "cannot use -p and -l");
332	if (lflag && zflag)
333		errx(1, "cannot use -z and -l");
334	if (!lflag && kflag)
335		errx(1, "must use -l with -k");
336
337	/* Get name of temporary socket for unix datagram client */
338	if ((family == AF_UNIX) && uflag && !lflag) {
339		if (sflag) {
340			unix_dg_tmp_socket = sflag;
341		} else {
342			strlcpy(unix_dg_tmp_socket_buf, "/tmp/nc.XXXXXXXXXX",
343				UNIX_DG_TMP_SOCKET_SIZE);
344			if (mktemp(unix_dg_tmp_socket_buf) == NULL)
345				err(1, "mktemp");
346			unix_dg_tmp_socket = unix_dg_tmp_socket_buf;
347		}
348	}
349
350	/* Initialize addrinfo structure. */
351	if (family != AF_UNIX) {
352		memset(&hints, 0, sizeof(struct addrinfo));
353		hints.ai_family = family;
354		hints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM;
355		hints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP;
356		if (nflag)
357			hints.ai_flags |= AI_NUMERICHOST;
358	}
359
360	if (xflag) {
361		if (uflag)
362			errx(1, "no proxy support for UDP mode");
363
364		if (lflag)
365			errx(1, "no proxy support for listen");
366
367		if (family == AF_UNIX)
368			errx(1, "no proxy support for unix sockets");
369
370		/* XXX IPv6 transport to proxy would probably work */
371		if (family == AF_INET6)
372			errx(1, "no proxy support for IPv6");
373
374		if (sflag)
375			errx(1, "no proxy support for local source address");
376
377		proxyhost = strsep(&proxy, ":");
378		proxyport = proxy;
379
380		memset(&proxyhints, 0, sizeof(struct addrinfo));
381		proxyhints.ai_family = family;
382		proxyhints.ai_socktype = SOCK_STREAM;
383		proxyhints.ai_protocol = IPPROTO_TCP;
384		if (nflag)
385			proxyhints.ai_flags |= AI_NUMERICHOST;
386	}
387
388	if (lflag) {
389		int connfd;
390		ret = 0;
391
392		if (family == AF_UNIX) {
393			if (uflag)
394				s = unix_bind(host);
395			else
396				s = unix_listen(host);
397		}
398
399		/* Allow only one connection at a time, but stay alive. */
400		for (;;) {
401			if (family != AF_UNIX)
402				s = local_listen(host, uport, hints);
403			if (s < 0)
404				err(1, NULL);
405			/*
406			 * For UDP and -k, don't connect the socket, let it
407			 * receive datagrams from multiple socket pairs.
408			 */
409			if (uflag && kflag)
410				readwrite(s);
411			/*
412			 * For UDP and not -k, we will use recvfrom() initially
413			 * to wait for a caller, then use the regular functions
414			 * to talk to the caller.
415			 */
416			else if (uflag && !kflag) {
417				int rv, plen;
418				char buf[16384];
419				struct sockaddr_storage z;
420
421				len = sizeof(z);
422				plen = 2048;
423				rv = recvfrom(s, buf, plen, MSG_PEEK,
424				    (struct sockaddr *)&z, &len);
425				if (rv < 0)
426					err(1, "recvfrom");
427
428				rv = connect(s, (struct sockaddr *)&z, len);
429				if (rv < 0)
430					err(1, "connect");
431
432				if (vflag)
433					report_connect((struct sockaddr *)&z, len);
434
435				readwrite(s);
436			} else {
437				len = sizeof(cliaddr);
438				connfd = accept(s, (struct sockaddr *)&cliaddr,
439				    &len);
440				if (connfd == -1) {
441					/* For now, all errnos are fatal */
442   					err(1, "accept");
443				}
444				if (vflag)
445					report_connect((struct sockaddr *)&cliaddr, len);
446
447				readwrite(connfd);
448				close(connfd);
449			}
450
451			if (family != AF_UNIX)
452				close(s);
453			else if (uflag) {
454				if (connect(s, NULL, 0) < 0)
455					err(1, "connect");
456			}
457
458			if (!kflag)
459				break;
460		}
461	} else if (family == AF_UNIX) {
462		ret = 0;
463
464		if ((s = unix_connect(host)) > 0 && !zflag) {
465			readwrite(s);
466			close(s);
467		} else
468			ret = 1;
469
470		if (uflag)
471			unlink(unix_dg_tmp_socket);
472		exit(ret);
473
474	} else {
475		int i = 0;
476
477		/* Construct the portlist[] array. */
478		build_ports(uport);
479
480		/* Cycle through portlist, connecting to each port. */
481		for (i = 0; portlist[i] != NULL; i++) {
482			if (s)
483				close(s);
484
485			if (xflag)
486				s = socks_connect(host, portlist[i], hints,
487				    proxyhost, proxyport, proxyhints, socksv,
488				    Pflag);
489			else
490				s = remote_connect(host, portlist[i], hints);
491
492			if (s < 0)
493				continue;
494
495			ret = 0;
496			if (vflag || zflag) {
497				/* For UDP, make sure we are connected. */
498				if (uflag) {
499					if (udptest(s) == -1) {
500						ret = 1;
501						continue;
502					}
503				}
504
505				/* Don't look up port if -n. */
506				if (nflag)
507					sv = NULL;
508				else {
509					sv = getservbyport(
510					    ntohs(atoi(portlist[i])),
511					    uflag ? "udp" : "tcp");
512				}
513
514				fprintf(stderr,
515				    "Connection to %s %s port [%s/%s] "
516				    "succeeded!\n", host, portlist[i],
517				    uflag ? "udp" : "tcp",
518				    sv ? sv->s_name : "*");
519			}
520			if (Fflag)
521				fdpass(s);
522			else if (!zflag)
523				readwrite(s);
524		}
525	}
526
527	if (s)
528		close(s);
529
530	exit(ret);
531}
532
533/*
534 * unix_bind()
535 * Returns a unix socket bound to the given path
536 */
537int
538unix_bind(char *path)
539{
540	struct sockaddr_un sun;
541	int s;
542
543	/* Create unix domain socket. */
544	if ((s = socket(AF_UNIX, uflag ? SOCK_DGRAM : SOCK_STREAM,
545	     0)) < 0)
546		return (-1);
547
548	memset(&sun, 0, sizeof(struct sockaddr_un));
549	sun.sun_family = AF_UNIX;
550
551	if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >=
552	    sizeof(sun.sun_path)) {
553		close(s);
554		errno = ENAMETOOLONG;
555		return (-1);
556	}
557
558	if (bind(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) {
559		close(s);
560		return (-1);
561	}
562	return (s);
563}
564
565/*
566 * unix_connect()
567 * Returns a socket connected to a local unix socket. Returns -1 on failure.
568 */
569int
570unix_connect(char *path)
571{
572	struct sockaddr_un sun;
573	int s;
574
575	if (uflag) {
576		if ((s = unix_bind(unix_dg_tmp_socket)) < 0)
577			return (-1);
578	} else {
579		if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
580			return (-1);
581	}
582	(void)fcntl(s, F_SETFD, FD_CLOEXEC);
583
584	memset(&sun, 0, sizeof(struct sockaddr_un));
585	sun.sun_family = AF_UNIX;
586
587	if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >=
588	    sizeof(sun.sun_path)) {
589		close(s);
590		errno = ENAMETOOLONG;
591		return (-1);
592	}
593	if (connect(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) {
594		close(s);
595		return (-1);
596	}
597	return (s);
598
599}
600
601/*
602 * unix_listen()
603 * Create a unix domain socket, and listen on it.
604 */
605int
606unix_listen(char *path)
607{
608	int s;
609	if ((s = unix_bind(path)) < 0)
610		return (-1);
611
612	if (listen(s, 5) < 0) {
613		close(s);
614		return (-1);
615	}
616	return (s);
617}
618
619/*
620 * remote_connect()
621 * Returns a socket connected to a remote host. Properly binds to a local
622 * port or source address if needed. Returns -1 on failure.
623 */
624int
625remote_connect(const char *host, const char *port, struct addrinfo hints)
626{
627	struct addrinfo *res, *res0;
628	int s, error, on = 1;
629
630	if ((error = getaddrinfo(host, port, &hints, &res)))
631		errx(1, "getaddrinfo: %s", gai_strerror(error));
632
633	res0 = res;
634	do {
635		if ((s = socket(res0->ai_family, res0->ai_socktype,
636		    res0->ai_protocol)) < 0)
637			continue;
638#ifdef IPSEC
639		if (ipsec_policy[0] != NULL)
640			add_ipsec_policy(s, ipsec_policy[0]);
641		if (ipsec_policy[1] != NULL)
642			add_ipsec_policy(s, ipsec_policy[1]);
643#endif
644
645		if (rtableid >= 0 && (setsockopt(s, SOL_SOCKET, SO_SETFIB,
646		    &rtableid, sizeof(rtableid)) == -1))
647			err(1, "setsockopt SO_SETFIB");
648
649		/* Bind to a local port or source address if specified. */
650		if (sflag || pflag) {
651			struct addrinfo ahints, *ares;
652
653			/* try IP_BINDANY, but don't insist */
654			setsockopt(s, IPPROTO_IP, IP_BINDANY, &on, sizeof(on));
655			memset(&ahints, 0, sizeof(struct addrinfo));
656			ahints.ai_family = res0->ai_family;
657			ahints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM;
658			ahints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP;
659			ahints.ai_flags = AI_PASSIVE;
660			if ((error = getaddrinfo(sflag, pflag, &ahints, &ares)))
661				errx(1, "getaddrinfo: %s", gai_strerror(error));
662
663			if (bind(s, (struct sockaddr *)ares->ai_addr,
664			    ares->ai_addrlen) < 0)
665				errx(1, "bind failed: %s", strerror(errno));
666			freeaddrinfo(ares);
667		}
668
669		set_common_sockopts(s);
670
671		if (timeout_connect(s, res0->ai_addr, res0->ai_addrlen) == 0)
672			break;
673		else if (vflag)
674			warn("connect to %s port %s (%s) failed", host, port,
675			    uflag ? "udp" : "tcp");
676
677		close(s);
678		s = -1;
679	} while ((res0 = res0->ai_next) != NULL);
680
681	freeaddrinfo(res);
682
683	return (s);
684}
685
686int
687timeout_connect(int s, const struct sockaddr *name, socklen_t namelen)
688{
689	struct pollfd pfd;
690	socklen_t optlen;
691	int flags, optval;
692	int ret;
693
694	if (timeout != -1) {
695		flags = fcntl(s, F_GETFL, 0);
696		if (fcntl(s, F_SETFL, flags | O_NONBLOCK) == -1)
697			err(1, "set non-blocking mode");
698	}
699
700	if ((ret = connect(s, name, namelen)) != 0 && errno == EINPROGRESS) {
701		pfd.fd = s;
702		pfd.events = POLLOUT;
703		if ((ret = poll(&pfd, 1, timeout)) == 1) {
704			optlen = sizeof(optval);
705			if ((ret = getsockopt(s, SOL_SOCKET, SO_ERROR,
706			    &optval, &optlen)) == 0) {
707				errno = optval;
708				ret = optval == 0 ? 0 : -1;
709			}
710		} else if (ret == 0) {
711			errno = ETIMEDOUT;
712			ret = -1;
713		} else
714			err(1, "poll failed");
715	}
716
717	if (timeout != -1 && fcntl(s, F_SETFL, flags) == -1)
718		err(1, "restoring flags");
719
720	return (ret);
721}
722
723/*
724 * local_listen()
725 * Returns a socket listening on a local port, binds to specified source
726 * address. Returns -1 on failure.
727 */
728int
729local_listen(char *host, char *port, struct addrinfo hints)
730{
731	struct addrinfo *res, *res0;
732	int s, ret, x = 1;
733	int error;
734
735	/* Allow nodename to be null. */
736	hints.ai_flags |= AI_PASSIVE;
737
738	/*
739	 * In the case of binding to a wildcard address
740	 * default to binding to an ipv4 address.
741	 */
742	if (host == NULL && hints.ai_family == AF_UNSPEC)
743		hints.ai_family = AF_INET;
744
745	if ((error = getaddrinfo(host, port, &hints, &res)))
746		errx(1, "getaddrinfo: %s", gai_strerror(error));
747
748	res0 = res;
749	do {
750		if ((s = socket(res0->ai_family, res0->ai_socktype,
751		    res0->ai_protocol)) < 0)
752			continue;
753
754		if (rtableid >= 0 && (setsockopt(s, IPPROTO_IP, SO_SETFIB,
755		    &rtableid, sizeof(rtableid)) == -1))
756			err(1, "setsockopt SO_SETFIB");
757
758		ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x));
759		if (ret == -1)
760			err(1, NULL);
761#ifdef IPSEC
762		if (ipsec_policy[0] != NULL)
763			add_ipsec_policy(s, ipsec_policy[0]);
764		if (ipsec_policy[1] != NULL)
765			add_ipsec_policy(s, ipsec_policy[1]);
766#endif
767		if (FreeBSD_Oflag) {
768			if (setsockopt(s, IPPROTO_TCP, TCP_NOOPT,
769			    &FreeBSD_Oflag, sizeof(FreeBSD_Oflag)) == -1)
770				err(1, "disable TCP options");
771		}
772
773		if (bind(s, (struct sockaddr *)res0->ai_addr,
774		    res0->ai_addrlen) == 0)
775			break;
776
777		close(s);
778		s = -1;
779	} while ((res0 = res0->ai_next) != NULL);
780
781	if (!uflag && s != -1) {
782		if (listen(s, 1) < 0)
783			err(1, "listen");
784	}
785
786	freeaddrinfo(res);
787
788	return (s);
789}
790
791/*
792 * readwrite()
793 * Loop that polls on the network file descriptor and stdin.
794 */
795void
796readwrite(int nfd)
797{
798	struct pollfd pfd[2];
799	unsigned char buf[16384];
800	int n, wfd = fileno(stdin);
801	int lfd = fileno(stdout);
802	int plen;
803
804	plen = 2048;
805
806	/* Setup Network FD */
807	pfd[0].fd = nfd;
808	pfd[0].events = POLLIN;
809
810	/* Set up STDIN FD. */
811	pfd[1].fd = wfd;
812	pfd[1].events = POLLIN;
813
814	while (pfd[0].fd != -1) {
815		if (iflag)
816			sleep(iflag);
817
818		if ((n = poll(pfd, 2 - dflag, timeout)) < 0) {
819			close(nfd);
820			err(1, "Polling Error");
821		}
822
823		if (n == 0)
824			return;
825
826		if (pfd[0].revents & POLLIN) {
827			if ((n = read(nfd, buf, plen)) < 0)
828				return;
829			else if (n == 0) {
830				shutdown(nfd, SHUT_RD);
831				pfd[0].fd = -1;
832				pfd[0].events = 0;
833			} else {
834				if (tflag)
835					atelnet(nfd, buf, n);
836				if (atomicio(vwrite, lfd, buf, n) != n)
837					return;
838			}
839		}
840
841		if (!dflag && pfd[1].revents & POLLIN) {
842			if ((n = read(wfd, buf, plen)) < 0)
843				return;
844			else if (n == 0) {
845				if (Nflag)
846					shutdown(nfd, SHUT_WR);
847				pfd[1].fd = -1;
848				pfd[1].events = 0;
849			} else {
850				if (atomicio(vwrite, nfd, buf, n) != n)
851					return;
852			}
853		}
854	}
855}
856
857/*
858 * fdpass()
859 * Pass the connected file descriptor to stdout and exit.
860 */
861void
862fdpass(int nfd)
863{
864	struct msghdr mh;
865	union {
866		struct cmsghdr hdr;
867		char buf[CMSG_SPACE(sizeof(int))];
868	} cmsgbuf;
869	struct cmsghdr *cmsg;
870	struct iovec iov;
871	char c = '\0';
872	ssize_t r;
873	struct pollfd pfd;
874
875	/* Avoid obvious stupidity */
876	if (isatty(STDOUT_FILENO))
877		errx(1, "Cannot pass file descriptor to tty");
878
879	bzero(&mh, sizeof(mh));
880	bzero(&cmsgbuf, sizeof(cmsgbuf));
881	bzero(&iov, sizeof(iov));
882	bzero(&pfd, sizeof(pfd));
883
884	mh.msg_control = (caddr_t)&cmsgbuf.buf;
885	mh.msg_controllen = sizeof(cmsgbuf.buf);
886	cmsg = CMSG_FIRSTHDR(&mh);
887	cmsg->cmsg_len = CMSG_LEN(sizeof(int));
888	cmsg->cmsg_level = SOL_SOCKET;
889	cmsg->cmsg_type = SCM_RIGHTS;
890	*(int *)CMSG_DATA(cmsg) = nfd;
891
892	iov.iov_base = &c;
893	iov.iov_len = 1;
894	mh.msg_iov = &iov;
895	mh.msg_iovlen = 1;
896
897	bzero(&pfd, sizeof(pfd));
898	pfd.fd = STDOUT_FILENO;
899	for (;;) {
900		r = sendmsg(STDOUT_FILENO, &mh, 0);
901		if (r == -1) {
902			if (errno == EAGAIN || errno == EINTR) {
903				pfd.events = POLLOUT;
904				if (poll(&pfd, 1, -1) == -1)
905					err(1, "poll");
906				continue;
907			}
908			err(1, "sendmsg");
909		} else if (r == -1)
910			errx(1, "sendmsg: unexpected return value %zd", r);
911		else
912			break;
913	}
914	exit(0);
915}
916
917/* Deal with RFC 854 WILL/WONT DO/DONT negotiation. */
918void
919atelnet(int nfd, unsigned char *buf, unsigned int size)
920{
921	unsigned char *p, *end;
922	unsigned char obuf[4];
923
924	if (size < 3)
925		return;
926	end = buf + size - 2;
927
928	for (p = buf; p < end; p++) {
929		if (*p != IAC)
930			continue;
931
932		obuf[0] = IAC;
933		p++;
934		if ((*p == WILL) || (*p == WONT))
935			obuf[1] = DONT;
936		else if ((*p == DO) || (*p == DONT))
937			obuf[1] = WONT;
938		else
939			continue;
940
941		p++;
942		obuf[2] = *p;
943		if (atomicio(vwrite, nfd, obuf, 3) != 3)
944			warn("Write Error!");
945	}
946}
947
948/*
949 * build_ports()
950 * Build an array of ports in portlist[], listing each port
951 * that we should try to connect to.
952 */
953void
954build_ports(char *p)
955{
956	const char *errstr;
957	char *n;
958	int hi, lo, cp;
959	int x = 0;
960
961	if ((n = strchr(p, '-')) != NULL) {
962		*n = '\0';
963		n++;
964
965		/* Make sure the ports are in order: lowest->highest. */
966		hi = strtonum(n, 1, PORT_MAX, &errstr);
967		if (errstr)
968			errx(1, "port number %s: %s", errstr, n);
969		lo = strtonum(p, 1, PORT_MAX, &errstr);
970		if (errstr)
971			errx(1, "port number %s: %s", errstr, p);
972
973		if (lo > hi) {
974			cp = hi;
975			hi = lo;
976			lo = cp;
977		}
978
979		/* Load ports sequentially. */
980		for (cp = lo; cp <= hi; cp++) {
981			portlist[x] = calloc(1, PORT_MAX_LEN);
982			if (portlist[x] == NULL)
983				err(1, NULL);
984			snprintf(portlist[x], PORT_MAX_LEN, "%d", cp);
985			x++;
986		}
987
988		/* Randomly swap ports. */
989		if (rflag) {
990			int y;
991			char *c;
992
993			for (x = 0; x <= (hi - lo); x++) {
994				y = (arc4random() & 0xFFFF) % (hi - lo);
995				c = portlist[x];
996				portlist[x] = portlist[y];
997				portlist[y] = c;
998			}
999		}
1000	} else {
1001		hi = strtonum(p, 1, PORT_MAX, &errstr);
1002		if (errstr)
1003			errx(1, "port number %s: %s", errstr, p);
1004		portlist[0] = strdup(p);
1005		if (portlist[0] == NULL)
1006			err(1, NULL);
1007	}
1008}
1009
1010/*
1011 * udptest()
1012 * Do a few writes to see if the UDP port is there.
1013 * Fails once PF state table is full.
1014 */
1015int
1016udptest(int s)
1017{
1018	int i, ret;
1019
1020	for (i = 0; i <= 3; i++) {
1021		if (write(s, "X", 1) == 1)
1022			ret = 1;
1023		else
1024			ret = -1;
1025	}
1026	return (ret);
1027}
1028
1029void
1030set_common_sockopts(int s)
1031{
1032	int x = 1;
1033
1034	if (Sflag) {
1035		if (setsockopt(s, IPPROTO_TCP, TCP_MD5SIG,
1036			&x, sizeof(x)) == -1)
1037			err(1, NULL);
1038	}
1039	if (Dflag) {
1040		if (setsockopt(s, SOL_SOCKET, SO_DEBUG,
1041			&x, sizeof(x)) == -1)
1042			err(1, NULL);
1043	}
1044	if (Tflag != -1) {
1045		if (setsockopt(s, IPPROTO_IP, IP_TOS,
1046		    &Tflag, sizeof(Tflag)) == -1)
1047			err(1, "set IP ToS");
1048	}
1049	if (Iflag) {
1050		if (setsockopt(s, SOL_SOCKET, SO_RCVBUF,
1051		    &Iflag, sizeof(Iflag)) == -1)
1052			err(1, "set TCP receive buffer size");
1053	}
1054	if (Oflag) {
1055		if (setsockopt(s, SOL_SOCKET, SO_SNDBUF,
1056		    &Oflag, sizeof(Oflag)) == -1)
1057			err(1, "set TCP send buffer size");
1058	}
1059	if (FreeBSD_Oflag) {
1060		if (setsockopt(s, IPPROTO_TCP, TCP_NOOPT,
1061		    &FreeBSD_Oflag, sizeof(FreeBSD_Oflag)) == -1)
1062			err(1, "disable TCP options");
1063	}
1064}
1065
1066int
1067map_tos(char *s, int *val)
1068{
1069	/* DiffServ Codepoints and other TOS mappings */
1070	const struct toskeywords {
1071		const char	*keyword;
1072		int		 val;
1073	} *t, toskeywords[] = {
1074		{ "af11",		IPTOS_DSCP_AF11 },
1075		{ "af12",		IPTOS_DSCP_AF12 },
1076		{ "af13",		IPTOS_DSCP_AF13 },
1077		{ "af21",		IPTOS_DSCP_AF21 },
1078		{ "af22",		IPTOS_DSCP_AF22 },
1079		{ "af23",		IPTOS_DSCP_AF23 },
1080		{ "af31",		IPTOS_DSCP_AF31 },
1081		{ "af32",		IPTOS_DSCP_AF32 },
1082		{ "af33",		IPTOS_DSCP_AF33 },
1083		{ "af41",		IPTOS_DSCP_AF41 },
1084		{ "af42",		IPTOS_DSCP_AF42 },
1085		{ "af43",		IPTOS_DSCP_AF43 },
1086		{ "critical",		IPTOS_PREC_CRITIC_ECP },
1087		{ "cs0",		IPTOS_DSCP_CS0 },
1088		{ "cs1",		IPTOS_DSCP_CS1 },
1089		{ "cs2",		IPTOS_DSCP_CS2 },
1090		{ "cs3",		IPTOS_DSCP_CS3 },
1091		{ "cs4",		IPTOS_DSCP_CS4 },
1092		{ "cs5",		IPTOS_DSCP_CS5 },
1093		{ "cs6",		IPTOS_DSCP_CS6 },
1094		{ "cs7",		IPTOS_DSCP_CS7 },
1095		{ "ef",			IPTOS_DSCP_EF },
1096		{ "inetcontrol",	IPTOS_PREC_INTERNETCONTROL },
1097		{ "lowdelay",		IPTOS_LOWDELAY },
1098		{ "netcontrol",		IPTOS_PREC_NETCONTROL },
1099		{ "reliability",	IPTOS_RELIABILITY },
1100		{ "throughput",		IPTOS_THROUGHPUT },
1101		{ NULL, 		-1 },
1102	};
1103
1104	for (t = toskeywords; t->keyword != NULL; t++) {
1105		if (strcmp(s, t->keyword) == 0) {
1106			*val = t->val;
1107			return (1);
1108		}
1109	}
1110
1111	return (0);
1112}
1113
1114void
1115report_connect(const struct sockaddr *sa, socklen_t salen)
1116{
1117	char remote_host[NI_MAXHOST];
1118	char remote_port[NI_MAXSERV];
1119	int herr;
1120	int flags = NI_NUMERICSERV;
1121
1122	if (nflag)
1123		flags |= NI_NUMERICHOST;
1124
1125	if ((herr = getnameinfo(sa, salen,
1126	    remote_host, sizeof(remote_host),
1127	    remote_port, sizeof(remote_port),
1128	    flags)) != 0) {
1129		if (herr == EAI_SYSTEM)
1130			err(1, "getnameinfo");
1131		else
1132			errx(1, "getnameinfo: %s", gai_strerror(herr));
1133	}
1134
1135	fprintf(stderr,
1136	    "Connection from %s %s "
1137	    "received!\n", remote_host, remote_port);
1138}
1139
1140void
1141help(void)
1142{
1143	usage(0);
1144	fprintf(stderr, "\tCommand Summary:\n\
1145	\t-4		Use IPv4\n\
1146	\t-6		Use IPv6\n\
1147	\t-D		Enable the debug socket option\n\
1148	\t-d		Detach from stdin\n");
1149#ifdef IPSEC
1150	fprintf(stderr, "\
1151	\t-E		Use IPsec ESP\n\
1152	\t-e policy	Use specified IPsec policy\n");
1153#endif
1154	fprintf(stderr, "\
1155	\t-F		Pass socket fd\n\
1156	\t-h		This help text\n\
1157	\t-I length	TCP receive buffer length\n\
1158	\t-i secs\t	Delay interval for lines sent, ports scanned\n\
1159	\t-k		Keep inbound sockets open for multiple connects\n\
1160	\t-l		Listen mode, for inbound connects\n\
1161	\t-N		Shutdown the network socket after EOF on stdin\n\
1162	\t-n		Suppress name/port resolutions\n\
1163	\t--no-tcpopt	Disable TCP options\n\
1164	\t-O length	TCP send buffer length\n\
1165	\t-P proxyuser\tUsername for proxy authentication\n\
1166	\t-p port\t	Specify local port for remote connects\n\
1167	\t-r		Randomize remote ports\n\
1168	\t-S		Enable the TCP MD5 signature option\n\
1169	\t-s addr\t	Local source address\n\
1170	\t-T toskeyword\tSet IP Type of Service\n\
1171	\t-t		Answer TELNET negotiation\n\
1172	\t-U		Use UNIX domain socket\n\
1173	\t-u		UDP mode\n\
1174	\t-V rtable	Specify alternate routing table\n\
1175	\t-v		Verbose\n\
1176	\t-w secs\t	Timeout for connects and final net reads\n\
1177	\t-X proto	Proxy protocol: \"4\", \"5\" (SOCKS) or \"connect\"\n\
1178	\t-x addr[:port]\tSpecify proxy address and port\n\
1179	\t-z		Zero-I/O mode [used for scanning]\n\
1180	Port numbers can be individual or ranges: lo-hi [inclusive]\n");
1181#ifdef IPSEC
1182	fprintf(stderr, "See ipsec_set_policy(3) for -e argument format\n");
1183#endif
1184	exit(1);
1185}
1186
1187#ifdef IPSEC
1188void
1189add_ipsec_policy(int s, char *policy)
1190{
1191	char *raw;
1192	int e;
1193
1194	raw = ipsec_set_policy(policy, strlen(policy));
1195	if (raw == NULL)
1196		errx(1, "ipsec_set_policy `%s': %s", policy,
1197		     ipsec_strerror());
1198	e = setsockopt(s, IPPROTO_IP, IP_IPSEC_POLICY, raw,
1199			ipsec_get_policylen(raw));
1200	if (e < 0)
1201		err(1, "ipsec policy cannot be configured");
1202	free(raw);
1203	if (vflag)
1204		fprintf(stderr, "ipsec policy configured: `%s'\n", policy);
1205	return;
1206}
1207#endif /* IPSEC */
1208
1209void
1210usage(int ret)
1211{
1212	fprintf(stderr,
1213#ifdef IPSEC
1214	    "usage: nc [-46DdEFhklNnrStUuvz] [-e policy] [-I length] [-i interval] [-O length]\n"
1215#else
1216	    "usage: nc [-46DdFhklNnrStUuvz] [-I length] [-i interval] [-O length]\n"
1217#endif
1218	    "\t  [-P proxy_username] [-p source_port] [-s source] [-T ToS]\n"
1219	    "\t  [-V rtable] [-w timeout] [-X proxy_protocol]\n"
1220	    "\t  [-x proxy_address[:port]] [destination] [port]\n");
1221	if (ret)
1222		exit(1);
1223}
1224