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