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