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