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