1 /* $MirOS: src/usr.bin/nc/netcat.c,v 1.7 2008/11/08 23:04:29 tg Exp $ */
2 /* $OpenBSD: netcat.c,v 1.81 2005/05/28 16:57:48 marius Exp $ */
3 /*
4  * Copyright (c) 2004 Thorsten "mirabilos" Glaser <tg@mirbsd.org>
5  * Copyright (c) 2001 Eric Jackson <ericj@monkey.org>
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *   notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *   notice, this list of conditions and the following disclaimer in the
15  *   documentation and/or other materials provided with the distribution.
16  * 3. The name of the author may not be used to endorse or promote products
17  *   derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 /*
32  * Re-written nc(1) for OpenBSD. Original implementation by
33  * *Hobbit* <hobbit@avian.org>.
34  */
35 
36 #include <sys/types.h>
37 #include <sys/socket.h>
38 #include <sys/time.h>
39 #include <sys/un.h>
40 
41 #include <netinet/in.h>
42 #include <netinet/tcp.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 "atomicio.h"
56 
57 __RCSID("$MirOS: src/usr.bin/nc/netcat.c,v 1.7 2008/11/08 23:04:29 tg Exp $");
58 
59 #undef BUFSIZ
60 #define BUFSIZ 4096
61 
62 #ifndef SUN_LEN
63 #define SUN_LEN(su) \
64 	(sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
65 #endif
66 
67 #define PORT_MAX	65535
68 #define PORT_MAX_LEN	6
69 
70 /* Command Line Options */
71 int	dflag;					/* detached, no stdin */
72 int	iflag;					/* Interval Flag */
73 int	jflag;					/* use jumbo frames if we can */
74 int	kflag;					/* More than one connect */
75 int	lflag;					/* Bind to local port */
76 int	nflag;					/* Don't do name look up */
77 char   *pflag;					/* Localport flag */
78 int	rflag;					/* Random ports flag */
79 char   *sflag;					/* Source Address */
80 int	tflag;					/* Telnet Emulation */
81 int	uflag;					/* UDP - Default to TCP */
82 int	vflag;					/* Verbosity */
83 int	xflag;					/* Socks proxy */
84 int	zflag;					/* Port Scan Flag */
85 int	Dflag;					/* sodebug */
86 int	Iflag;					/* Prefix peer IP */
87 int	Sflag;					/* TCP MD5 signature option */
88 
89 int timeout = -1;
90 int family = AF_UNSPEC;
91 char *portlist[PORT_MAX+1];
92 
93 void	atelnet(int, unsigned char *, unsigned int);
94 void	build_ports(char *);
95 void	help(void);
96 int	local_listen(char *, char *, struct addrinfo);
97 void	readwrite(int);
98 int	remote_connect(const char *, const char *, struct addrinfo);
99 int	socks_connect(const char *, const char *, struct addrinfo, const char *, const char *,
100 	struct addrinfo, int);
101 int	udptest(int);
102 int	unix_connect(char *);
103 int	unix_listen(char *);
104 void    set_common_sockopts(int);
105 void	usage(int);
106 void	prepend_peer(const struct sockaddr *);
107 
108 int
main(int argc,char * argv[])109 main(int argc, char *argv[])
110 {
111 	int ch, s, ret, socksv;
112 	char *host, *uport, *endp;
113 	struct addrinfo hints;
114 	struct servent *sv;
115 	socklen_t len;
116 	struct sockaddr_storage cliaddr;
117 	char *proxy;
118 	const char *proxyhost = "", *proxyport = NULL;
119 	struct addrinfo proxyhints;
120 
121 	ret = 1;
122 	s = 0;
123 	socksv = 5;
124 	host = NULL;
125 	uport = NULL;
126 	endp = NULL;
127 	sv = NULL;
128 
129 	while ((ch = getopt(argc, argv,
130 	    "46DdhIi:jklnp:rSs:tUuvw:X:x:z")) != -1) {
131 		switch (ch) {
132 		case '4':
133 			family = AF_INET;
134 			break;
135 		case '6':
136 			family = AF_INET6;
137 			break;
138 		case 'U':
139 			family = AF_UNIX;
140 			break;
141 		case 'X':
142 			if (strcasecmp(optarg, "connect") == 0)
143 				socksv = -1; /* HTTP proxy CONNECT */
144 			else if (strcmp(optarg, "4") == 0)
145 				socksv = 4; /* SOCKS v.4 */
146 			else if (strcmp(optarg, "5") == 0)
147 				socksv = 5; /* SOCKS v.5 */
148 			else
149 				errx(1, "unsupported proxy protocol");
150 			break;
151 		case 'd':
152 			dflag = 1;
153 			break;
154 		case 'h':
155 			help();
156 			break;
157 		case 'i':
158 			iflag = (int)strtoul(optarg, &endp, 10);
159 			if (iflag < 0 || *endp != '\0')
160 				errx(1, "interval cannot be negative");
161 			break;
162 		case 'j':
163 			jflag = 1;
164 			break;
165 		case 'k':
166 			kflag = 1;
167 			break;
168 		case 'l':
169 			lflag = 1;
170 			break;
171 		case 'n':
172 			nflag = 1;
173 			break;
174 		case 'p':
175 			pflag = optarg;
176 			break;
177 		case 'r':
178 			rflag = 1;
179 			break;
180 		case 's':
181 			sflag = optarg;
182 			break;
183 		case 't':
184 			tflag = 1;
185 			break;
186 		case 'u':
187 			uflag = 1;
188 			break;
189 		case 'v':
190 			vflag = 1;
191 			break;
192 		case 'w':
193 			timeout = (int)strtoul(optarg, &endp, 10);
194 			if (timeout < 0 || *endp != '\0')
195 				errx(1, "timeout cannot be negative");
196 			if (timeout >= (INT_MAX / 1000))
197 				errx(1, "timeout too large");
198 			timeout *= 1000;
199 			break;
200 		case 'x':
201 			xflag = 1;
202 			if ((proxy = strdup(optarg)) == NULL)
203 				err(1, NULL);
204 			break;
205 		case 'z':
206 			zflag = 1;
207 			break;
208 		case 'D':
209 			Dflag = 1;
210 			break;
211 		case 'I':
212 			Iflag = 1;
213 			break;
214 		case 'S':
215 			Sflag = 1;
216 			break;
217 		default:
218 			usage(1);
219 		}
220 	}
221 	argc -= optind;
222 	argv += optind;
223 
224 	/* Cruft to make sure options are clean, and used properly. */
225 	if (argv[0] && !argv[1] && family == AF_UNIX) {
226 		if (uflag)
227 			errx(1, "cannot use -u and -U");
228 		host = argv[0];
229 		uport = NULL;
230 	} else if (argv[0] && !argv[1]) {
231 		if  (!lflag)
232 			usage(1);
233 		uport = argv[0];
234 		host = NULL;
235 	} else if (argv[0] && argv[1]) {
236 		host = argv[0];
237 		uport = argv[1];
238 	} else
239 		usage(1);
240 
241 	if (lflag && sflag)
242 		errx(1, "cannot use -s and -l");
243 	if (lflag && pflag)
244 		errx(1, "cannot use -p and -l");
245 	if (lflag && zflag)
246 		errx(1, "cannot use -z and -l");
247 	if (!lflag && kflag)
248 		errx(1, "must use -l with -k");
249 	if (Iflag && (vflag || xflag || zflag))
250 		errx(1, "cannot use -I with -vxz");
251 
252 	/* Initialize addrinfo structure. */
253 	if (family != AF_UNIX) {
254 		memset(&hints, 0, sizeof(struct addrinfo));
255 		hints.ai_family = family;
256 		hints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM;
257 		hints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP;
258 		if (nflag)
259 			hints.ai_flags |= AI_NUMERICHOST;
260 	}
261 
262 	if (xflag) {
263 		if (uflag)
264 			errx(1, "no proxy support for UDP mode");
265 
266 		if (lflag)
267 			errx(1, "no proxy support for listen");
268 
269 		if (family == AF_UNIX)
270 			errx(1, "no proxy support for unix sockets");
271 
272 		/* XXX IPv6 transport to proxy would probably work */
273 		if (family == AF_INET6)
274 			errx(1, "no proxy support for IPv6");
275 
276 		if (sflag)
277 			errx(1, "no proxy support for local source address");
278 
279 		proxyhost = strsep(&proxy, ":");
280 		proxyport = proxy;
281 
282 		memset(&proxyhints, 0, sizeof(struct addrinfo));
283 		proxyhints.ai_family = family;
284 		proxyhints.ai_socktype = SOCK_STREAM;
285 		proxyhints.ai_protocol = IPPROTO_TCP;
286 		if (nflag)
287 			proxyhints.ai_flags |= AI_NUMERICHOST;
288 	}
289 
290 	if (lflag) {
291 		int connfd;
292 		ret = 0;
293 
294 		if (family == AF_UNIX)
295 			s = unix_listen(host);
296 
297 		/* Allow only one connection at a time, but stay alive. */
298 		for (;;) {
299 			if (family != AF_UNIX)
300 				s = local_listen(host, uport, hints);
301 			if (s < 0)
302 				err(1, NULL);
303 			/*
304 			 * For UDP, we will use recvfrom() initially
305 			 * to wait for a caller, then use the regular
306 			 * functions to talk to the caller.
307 			 */
308 			len = sizeof(cliaddr);
309 			memset(&cliaddr, 0, len);
310 			if (uflag) {
311 				int rv, plen;
312 				char buf[8192];
313 
314 				plen = jflag ? 8192 : 1024;
315 				rv = recvfrom(s, buf, plen, MSG_PEEK,
316 				    (struct sockaddr *)&cliaddr, &len);
317 				if (rv < 0)
318 					err(1, "recvfrom");
319 
320 				rv = connect(s, (struct sockaddr *)&cliaddr,
321 				    len);
322 				if (rv < 0)
323 					err(1, "connect");
324 
325 				connfd = s;
326 			} else {
327 				connfd = accept(s, (struct sockaddr *)&cliaddr,
328 				    &len);
329 			}
330 			if (Iflag)
331 				prepend_peer((struct sockaddr *)&cliaddr);
332 
333 			readwrite(connfd);
334 			close(connfd);
335 			if (family != AF_UNIX)
336 				close(s);
337 
338 			if (!kflag)
339 				break;
340 		}
341 	} else if (family == AF_UNIX) {
342 		ret = 0;
343 
344 		if ((s = unix_connect(host)) > 0 && !zflag) {
345 			readwrite(s);
346 			close(s);
347 		} else
348 			ret = 1;
349 
350 		exit(ret);
351 
352 	} else {
353 		int i = 0;
354 
355 		/* Construct the portlist[] array. */
356 		build_ports(uport);
357 
358 		/* Cycle through portlist, connecting to each port. */
359 		for (i = 0; portlist[i] != NULL; i++) {
360 			if (s)
361 				close(s);
362 
363 			if (xflag)
364 				s = socks_connect(host, portlist[i], hints,
365 				    proxyhost, proxyport, proxyhints, socksv);
366 			else
367 				s = remote_connect(host, portlist[i], hints);
368 
369 			if (s < 0)
370 				continue;
371 
372 			ret = 0;
373 			if (vflag || zflag) {
374 				/* For UDP, make sure we are connected. */
375 				if (uflag) {
376 					if (udptest(s) == -1) {
377 						ret = 1;
378 						continue;
379 					}
380 				}
381 
382 				/* Don't look up port if -n. */
383 				if (nflag)
384 					sv = NULL;
385 				else {
386 					sv = getservbyport(
387 					    ntohs(atoi(portlist[i])),
388 					    uflag ? "udp" : "tcp");
389 				}
390 
391 				printf("Connection to %s %s port [%s/%s] succeeded!\n",
392 				    host, portlist[i], uflag ? "udp" : "tcp",
393 				    sv ? sv->s_name : "*");
394 			}
395 			if (!zflag)
396 				readwrite(s);
397 		}
398 	}
399 
400 	if (s)
401 		close(s);
402 
403 	exit(ret);
404 }
405 
406 /*
407  * unix_connect()
408  * Returns a socket connected to a local unix socket. Returns -1 on failure.
409  */
410 int
unix_connect(char * path)411 unix_connect(char *path)
412 {
413 	struct sockaddr_un sun;
414 	int s;
415 
416 	if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
417 		return (-1);
418 	(void)fcntl(s, F_SETFD, 1);
419 
420 	memset(&sun, 0, sizeof(struct sockaddr_un));
421 	sun.sun_family = AF_UNIX;
422 
423 	if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >=
424 	    sizeof(sun.sun_path)) {
425 		close(s);
426 		errno = ENAMETOOLONG;
427 		return (-1);
428 	}
429 	if (connect(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) {
430 		close(s);
431 		return (-1);
432 	}
433 	return (s);
434 
435 }
436 
437 /*
438  * unix_listen()
439  * Create a unix domain socket, and listen on it.
440  */
441 int
unix_listen(char * path)442 unix_listen(char *path)
443 {
444 	struct sockaddr_un sun;
445 	int s;
446 
447 	/* Create unix domain socket. */
448 	if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
449 		return (-1);
450 
451 	memset(&sun, 0, sizeof(struct sockaddr_un));
452 	sun.sun_family = AF_UNIX;
453 
454 	if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >=
455 	    sizeof(sun.sun_path)) {
456 		close(s);
457 		errno = ENAMETOOLONG;
458 		return (-1);
459 	}
460 
461 	if (bind(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) {
462 		close(s);
463 		return (-1);
464 	}
465 
466 	if (listen(s, 5) < 0) {
467 		close(s);
468 		return (-1);
469 	}
470 	return (s);
471 }
472 
473 /*
474  * remote_connect()
475  * Returns a socket connected to a remote host. Properly binds to a local
476  * port or source address if needed. Returns -1 on failure.
477  */
478 int
remote_connect(const char * host,const char * port,struct addrinfo hints)479 remote_connect(const char *host, const char *port, struct addrinfo hints)
480 {
481 	struct addrinfo *res, *res0;
482 	int s, error;
483 
484 	if ((error = getaddrinfo(host, port, &hints, &res)))
485 		errx(1, "getaddrinfo: %s", gai_strerror(error));
486 
487 	res0 = res;
488 	do {
489 		if ((s = socket(res0->ai_family, res0->ai_socktype,
490 		    res0->ai_protocol)) < 0)
491 			continue;
492 
493 		/* Bind to a local port or source address if specified. */
494 		if (sflag || pflag) {
495 			struct addrinfo ahints, *ares;
496 
497 			if (!(sflag && pflag)) {
498 				if (!sflag)
499 					sflag = NULL;
500 				else
501 					pflag = NULL;
502 			}
503 
504 			memset(&ahints, 0, sizeof(struct addrinfo));
505 			ahints.ai_family = res0->ai_family;
506 			ahints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM;
507 			ahints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP;
508 			ahints.ai_flags = AI_PASSIVE;
509 			if ((error = getaddrinfo(sflag, pflag, &ahints, &ares)))
510 				errx(1, "getaddrinfo: %s", gai_strerror(error));
511 
512 			if (bind(s, (struct sockaddr *)ares->ai_addr,
513 			    ares->ai_addrlen) < 0)
514 				errx(1, "bind failed: %s", strerror(errno));
515 			freeaddrinfo(ares);
516 		}
517 
518 		set_common_sockopts(s);
519 
520 		if (connect(s, res0->ai_addr, res0->ai_addrlen) == 0)
521 			break;
522 		else if (vflag)
523 			warn("connect to %s port %s (%s) failed", host, port,
524 			    uflag ? "udp" : "tcp");
525 
526 		close(s);
527 		s = -1;
528 	} while ((res0 = res0->ai_next) != NULL);
529 
530 	if (Iflag && res0)
531 		prepend_peer(res0->ai_addr);
532 
533 	freeaddrinfo(res);
534 
535 	return (s);
536 }
537 
538 /*
539  * local_listen()
540  * Returns a socket listening on a local port, binds to specified source
541  * address. Returns -1 on failure.
542  */
543 int
local_listen(char * host,char * port,struct addrinfo hints)544 local_listen(char *host, char *port, struct addrinfo hints)
545 {
546 	struct addrinfo *res, *res0;
547 	int s, ret, x = 1;
548 	int error;
549 
550 	/* Allow nodename to be null. */
551 	hints.ai_flags |= AI_PASSIVE;
552 
553 	/*
554 	 * In the case of binding to a wildcard address
555 	 * default to binding to an ipv4 address.
556 	 */
557 	if (host == NULL && hints.ai_family == AF_UNSPEC)
558 		hints.ai_family = AF_INET;
559 
560 	if ((error = getaddrinfo(host, port, &hints, &res)))
561 		errx(1, "getaddrinfo: %s", gai_strerror(error));
562 
563 	res0 = res;
564 	do {
565 		if ((s = socket(res0->ai_family, res0->ai_socktype,
566 		    res0->ai_protocol)) == 0)
567 			continue;
568 
569 		ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x));
570 		if (ret == -1)
571 			err(1, NULL);
572 
573 		set_common_sockopts(s);
574 
575 		if (bind(s, (struct sockaddr *)res0->ai_addr,
576 		    res0->ai_addrlen) == 0)
577 			break;
578 
579 		close(s);
580 		s = -1;
581 	} while ((res0 = res0->ai_next) != NULL);
582 
583 	if (!uflag && s != -1) {
584 		if (listen(s, 1) < 0)
585 			err(1, "listen");
586 	}
587 
588 	freeaddrinfo(res);
589 
590 	return (s);
591 }
592 
593 /*
594  * readwrite()
595  * Loop that polls on the network file descriptor and stdin.
596  */
597 void
readwrite(int nfd)598 readwrite(int nfd)
599 {
600 	struct pollfd pfd[2];
601 	unsigned char buf[8192];
602 	int n, wfd = fileno(stdin);
603 	int lfd = fileno(stdout);
604 	int plen;
605 
606 	plen = jflag ? 8192 : 1024;
607 
608 	/* Setup Network FD */
609 	pfd[0].fd = nfd;
610 	pfd[0].events = POLLIN;
611 
612 	/* Set up STDIN FD. */
613 	pfd[1].fd = wfd;
614 	pfd[1].events = POLLIN;
615 
616 	while (pfd[0].fd != -1) {
617 		if (iflag)
618 			sleep(iflag);
619 
620 		if ((n = poll(pfd, 2 - dflag, timeout)) < 0) {
621 			close(nfd);
622 			err(1, "Polling Error");
623 		}
624 
625 		if (n == 0)
626 			return;
627 
628 		if (pfd[0].revents & POLLIN) {
629 			if ((n = read(nfd, buf, plen)) < 0)
630 				return;
631 			else if (n == 0) {
632 				shutdown(nfd, SHUT_RD);
633 				pfd[0].fd = -1;
634 				pfd[0].events = 0;
635 			} else {
636 				if (tflag)
637 					atelnet(nfd, buf, n);
638 				if ((int)atomicio(vwrite, lfd, buf, n) != n)
639 					return;
640 			}
641 		}
642 
643 		if (!dflag && pfd[1].revents & POLLIN) {
644 			if ((n = read(wfd, buf, plen)) < 0)
645 				return;
646 			else if (n == 0) {
647 				shutdown(nfd, SHUT_WR);
648 				pfd[1].fd = -1;
649 				pfd[1].events = 0;
650 			} else {
651 				if ((int)atomicio(vwrite, nfd, buf, n) != n)
652 					return;
653 			}
654 		}
655 	}
656 }
657 
658 /* Deal with RFC 854 WILL/WONT DO/DONT negotiation. */
659 void
atelnet(int nfd,unsigned char * buf,unsigned int size)660 atelnet(int nfd, unsigned char *buf, unsigned int size)
661 {
662 	unsigned char *p, *end;
663 	unsigned char obuf[4];
664 
665 	end = buf + size;
666 	obuf[0] = '\0';
667 
668 	for (p = buf; p < end; p++) {
669 		if (*p != IAC)
670 			break;
671 
672 		obuf[0] = IAC;
673 		p++;
674 		if ((*p == WILL) || (*p == WONT))
675 			obuf[1] = DONT;
676 		if ((*p == DO) || (*p == DONT))
677 			obuf[1] = WONT;
678 		if (obuf) {
679 			p++;
680 			obuf[2] = *p;
681 			obuf[3] = '\0';
682 			if (atomicio(vwrite, nfd, obuf, 3) != 3)
683 				warn("Write Error!");
684 			obuf[0] = '\0';
685 		}
686 	}
687 }
688 
689 /*
690  * build_ports()
691  * Build an array or ports in portlist[], listing each port
692  * that we should try to connect to.
693  */
694 void
build_ports(char * p)695 build_ports(char *p)
696 {
697 	char *n, *endp;
698 	int hi, lo, cp;
699 	int x = 0;
700 
701 	if ((n = strchr(p, '-')) != NULL) {
702 		if (lflag)
703 			errx(1, "Cannot use -l with multiple ports!");
704 
705 		*n = '\0';
706 		n++;
707 
708 		/* Make sure the ports are in order: lowest->highest. */
709 		hi = (int)strtoul(n, &endp, 10);
710 		if (hi <= 0 || hi > PORT_MAX || *endp != '\0')
711 			errx(1, "port range not valid");
712 		lo = (int)strtoul(p, &endp, 10);
713 		if (lo <= 0 || lo > PORT_MAX || *endp != '\0')
714 			errx(1, "port range not valid");
715 
716 		if (lo > hi) {
717 			cp = hi;
718 			hi = lo;
719 			lo = cp;
720 		}
721 
722 		/* Load ports sequentially. */
723 		for (cp = lo; cp <= hi; cp++) {
724 			portlist[x] = calloc(1, PORT_MAX_LEN);
725 			if (portlist[x] == NULL)
726 				err(1, NULL);
727 			snprintf(portlist[x], PORT_MAX_LEN, "%d", cp);
728 			x++;
729 		}
730 
731 		/* Randomly swap ports. */
732 		if (rflag) {
733 			int y;
734 			char *c;
735 
736 			for (x = 0; x <= (hi - lo); x++) {
737 				y = (arc4random() & 0xFFFF) % (hi - lo);
738 				c = portlist[x];
739 				portlist[x] = portlist[y];
740 				portlist[y] = c;
741 			}
742 		}
743 	} else {
744 		hi = (int)strtoul(p, &endp, 10);
745 		if (hi <= 0 || hi > PORT_MAX || *endp != '\0')
746 			errx(1, "port range not valid");
747 		portlist[0] = calloc(1, PORT_MAX_LEN);
748 		if (portlist[0] == NULL)
749 			err(1, NULL);
750 		portlist[0] = p;
751 	}
752 }
753 
754 /*
755  * udptest()
756  * Do a few writes to see if the UDP port is there.
757  * XXX - Better way of doing this? Doesn't work for IPv6.
758  * Also fails after around 100 ports checked.
759  */
760 int
udptest(int s)761 udptest(int s)
762 {
763 	int i, ret;
764 
765 	for (i = 0; i <= 3; i++) {
766 		if (write(s, "X", 1) == 1)
767 			ret = 1;
768 		else
769 			ret = -1;
770 	}
771 	return (ret);
772 }
773 
774 void
set_common_sockopts(int s)775 set_common_sockopts(int s)
776 {
777 	int x = 1;
778 
779 	if (Sflag) {
780 		if (setsockopt(s, IPPROTO_TCP, TCP_MD5SIG,
781 			&x, sizeof(x)) == -1)
782 			err(1, NULL);
783 	}
784 	if (Dflag) {
785 		if (setsockopt(s, SOL_SOCKET, SO_DEBUG,
786 			&x, sizeof(x)) == -1)
787 			err(1, NULL);
788 	}
789 	if (jflag) {
790 		if (setsockopt(s, SOL_SOCKET, SO_JUMBO,
791 			&x, sizeof(x)) == -1)
792 			err(1, NULL);
793 	}
794 }
795 
796 void
help(void)797 help(void)
798 {
799 	usage(0);
800 	fprintf(stderr, "\tCommand Summary:\n\
801 	\t-4		Use IPv4\n\
802 	\t-6		Use IPv6\n\
803 	\t-D		Enable the debug socket option\n\
804 	\t-d		Detach from stdin\n\
805 	\t-h		This help text\n\
806 	\t-I		Prepend peer's IP and port to output\n\
807 	\t-i secs\t	Delay interval for lines sent, ports scanned\n\
808 	\t-k		Keep inbound sockets open for multiple connects\n\
809 	\t-l		Listen mode, for inbound connects\n\
810 	\t-n		Suppress name/port resolutions\n\
811 	\t-p port\t	Specify local port for remote connects\n");
812 	fprintf(stderr, "\
813 	\t-r		Randomize remote ports\n\
814 	\t-S		Enable the TCP MD5 signature option\n\
815 	\t-s addr\t	Local source address\n\
816 	\t-t		Answer TELNET negotiation\n\
817 	\t-U		Use UNIX domain socket\n\
818 	\t-u		UDP mode\n\
819 	\t-v		Verbose\n\
820 	\t-w secs\t	Timeout for connects and final net reads\n\
821 	\t-X proto	Proxy protocol: \"4\", \"5\" (SOCKS) or \"connect\"\n\
822 	\t-x addr[:port]\tSpecify proxy address and port\n\
823 	\t-z		Zero-I/O mode [used for scanning]\n\
824 	Port numbers can be individual or ranges: lo-hi [inclusive]\n");
825 	exit(1);
826 }
827 
828 void
usage(int ret)829 usage(int ret)
830 {
831 	fprintf(stderr, "usage: nc [-46DdhIklnrStUuvz] [-i interval] [-p source_port]\n");
832 	fprintf(stderr, "\t  [-s source_ip_address] [-w timeout] [-X proxy_version]\n");
833 	fprintf(stderr, "\t  [-x proxy_address[:port]] [hostname] [port[s]]\n");
834 	if (ret)
835 		exit(1);
836 }
837 
838 void
prepend_peer(const struct sockaddr * sa)839 prepend_peer(const struct sockaddr *sa)
840 {
841 	char host[NI_MAXHOST], port[NI_MAXSERV];
842 
843 	if (getnameinfo(sa, SA_LEN(sa), host, NI_MAXHOST,
844 	    port, NI_MAXSERV, NI_NUMERICHOST | NI_NUMERICSERV)) {
845 		errx(1, "could not get numeric hostname");
846 		/* NOTREACHED */
847 	}
848 
849 	printf("[%s]:%s ", host, port);
850 	fflush(stdout);
851 }
852