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