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
69 #ifndef SUN_LEN
70 #define SUN_LEN(su) \
71 (sizeof (*(su)) - sizeof ((su)->sun_path) + strlen((su)->sun_path))
72 #endif
73
74 #define PORT_MIN 1
75 #define PORT_MAX 65535
76 #define PORT_MAX_LEN 6
77 #define PLIST_SZ 32 /* initial capacity of the portlist */
78
79 /* Command Line Options */
80 int dflag; /* detached, no stdin */
81 unsigned int iflag; /* Interval Flag */
82 int kflag; /* More than one connect */
83 int lflag; /* Bind to local port */
84 int nflag; /* Don't do name lookup */
85 char *Pflag; /* Proxy username */
86 char *pflag; /* Localport flag */
87 int rflag; /* Random ports flag */
88 char *sflag; /* Source Address */
89 int tflag; /* Telnet Emulation */
90 int uflag; /* UDP - Default to TCP */
91 int vflag; /* Verbosity */
92 int xflag; /* Socks proxy */
93 int Xflag; /* indicator of Socks version set */
94 int zflag; /* Port Scan Flag */
95 int Dflag; /* sodebug */
96 int Tflag = -1; /* IP Type of Service */
97
98 int timeout = -1;
99 int family = AF_UNSPEC;
100
101 /*
102 * portlist structure
103 * Used to store a list of ports given by the user and maintaining
104 * information about the number of ports stored.
105 */
106 struct {
107 uint16_t *list; /* list containing the ports */
108 uint_t listsize; /* capacity of the list (number of entries) */
109 uint_t numports; /* number of ports in the list */
110 } ports;
111
112 void atelnet(int, unsigned char *, unsigned int);
113 void build_ports(char *);
114 void help(void);
115 int local_listen(char *, char *, struct addrinfo);
116 void readwrite(int);
117 int remote_connect(const char *, const char *, struct addrinfo);
118 int socks_connect(const char *, const char *,
119 const char *, const char *, struct addrinfo, int, const char *);
120 int udptest(int);
121 int unix_connect(char *);
122 int unix_listen(char *);
123 void set_common_sockopts(int);
124 int parse_iptos(char *);
125 void usage(int);
126 char *print_addr(char *, size_t, struct sockaddr *, int, int);
127
128 int
main(int argc,char * argv[])129 main(int argc, char *argv[])
130 {
131 int ch, s, ret, socksv;
132 char *host, *uport, *proxy;
133 struct addrinfo hints;
134 struct servent *sv;
135 socklen_t len;
136 struct sockaddr_storage cliaddr;
137 const char *errstr, *proxyhost = "", *proxyport = NULL;
138 struct addrinfo proxyhints;
139 char port[PORT_MAX_LEN];
140
141 ret = 1;
142 s = -1;
143 socksv = 5;
144 host = NULL;
145 uport = NULL;
146 sv = NULL;
147
148 while ((ch = getopt(argc, argv,
149 "46Ddhi:klnP:p:rs:T:tUuvw:X:x:z")) != -1) {
150 switch (ch) {
151 case '4':
152 family = AF_INET;
153 break;
154 case '6':
155 family = AF_INET6;
156 break;
157 case 'U':
158 family = AF_UNIX;
159 break;
160 case 'X':
161 Xflag = 1;
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 'h':
175 help();
176 break;
177 case 'i':
178 iflag = strtonum(optarg, 0, UINT_MAX, &errstr);
179 if (errstr)
180 errx(1, "interval %s: %s", errstr, optarg);
181 break;
182 case 'k':
183 kflag = 1;
184 break;
185 case 'l':
186 lflag = 1;
187 break;
188 case 'n':
189 nflag = 1;
190 break;
191 case 'P':
192 Pflag = optarg;
193 break;
194 case 'p':
195 pflag = optarg;
196 break;
197 case 'r':
198 rflag = 1;
199 break;
200 case 's':
201 sflag = optarg;
202 break;
203 case 't':
204 tflag = 1;
205 break;
206 case 'u':
207 uflag = 1;
208 break;
209 case 'v':
210 vflag = 1;
211 break;
212 case 'w':
213 timeout = strtonum(optarg, 0, INT_MAX / 1000, &errstr);
214 if (errstr)
215 errx(1, "timeout %s: %s", errstr, optarg);
216 timeout *= 1000;
217 break;
218 case 'x':
219 xflag = 1;
220 if ((proxy = strdup(optarg)) == NULL)
221 err(1, NULL);
222 break;
223 case 'z':
224 zflag = 1;
225 break;
226 case 'D':
227 Dflag = 1;
228 break;
229 case 'T':
230 Tflag = parse_iptos(optarg);
231 break;
232 default:
233 usage(1);
234 }
235 }
236 argc -= optind;
237 argv += optind;
238
239 /* Cruft to make sure options are clean, and used properly. */
240 if (argv[0] && !argv[1] && family == AF_UNIX) {
241 if (uflag)
242 errx(1, "cannot use -u and -U");
243 host = argv[0];
244 uport = NULL;
245 } else if (argv[0] && !argv[1]) {
246 if (!lflag)
247 usage(1);
248 uport = argv[0];
249 host = NULL;
250 } else if (argv[0] && argv[1]) {
251 if (family == AF_UNIX)
252 usage(1);
253 host = argv[0];
254 uport = argv[1];
255 } else {
256 if (!(lflag && pflag))
257 usage(1);
258 }
259
260 if (argc > 2)
261 usage(1);
262
263 if (lflag && sflag)
264 errx(1, "cannot use -s and -l");
265 if (lflag && rflag)
266 errx(1, "cannot use -r and -l");
267 if (lflag && (timeout >= 0))
268 warnx("-w has no effect with -l");
269 if (lflag && pflag) {
270 if (uport)
271 usage(1);
272 uport = pflag;
273 }
274 if (lflag && zflag)
275 errx(1, "cannot use -z and -l");
276 if (!lflag && kflag)
277 errx(1, "must use -l with -k");
278 if (lflag && (Pflag || xflag || Xflag))
279 errx(1, "cannot use -l with -P, -X or -x");
280
281 /* Initialize addrinfo structure. */
282 if (family != AF_UNIX) {
283 (void) memset(&hints, 0, sizeof (struct addrinfo));
284 hints.ai_family = family;
285 hints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM;
286 hints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP;
287 if (nflag)
288 hints.ai_flags |= AI_NUMERICHOST;
289 }
290
291 if (xflag) {
292 if (uflag)
293 errx(1, "no proxy support for UDP mode");
294
295 if (lflag)
296 errx(1, "no proxy support for listen");
297
298 if (family == AF_UNIX)
299 errx(1, "no proxy support for unix sockets");
300
301 if (family == AF_INET6)
302 errx(1, "no proxy support for IPv6");
303
304 if (sflag)
305 errx(1, "no proxy support for local source address");
306
307 if ((proxyhost = strtok(proxy, ":")) == NULL)
308 errx(1, "missing port specification");
309 proxyport = strtok(NULL, ":");
310
311 (void) memset(&proxyhints, 0, sizeof (struct addrinfo));
312 proxyhints.ai_family = family;
313 proxyhints.ai_socktype = SOCK_STREAM;
314 proxyhints.ai_protocol = IPPROTO_TCP;
315 if (nflag)
316 proxyhints.ai_flags |= AI_NUMERICHOST;
317 }
318
319 if (lflag) {
320 int connfd;
321 ret = 0;
322
323 if (family == AF_UNIX) {
324 if (host == NULL)
325 usage(1);
326 s = unix_listen(host);
327 }
328
329 /* Allow only one connection at a time, but stay alive. */
330 for (;;) {
331 if (family != AF_UNIX) {
332 /* check if uport is valid */
333 if (strtonum(uport, PORT_MIN, PORT_MAX,
334 &errstr) == 0)
335 errx(1, "port number %s: %s",
336 uport, errstr);
337 s = local_listen(host, uport, hints);
338 }
339 if (s < 0)
340 err(1, NULL);
341 /*
342 * For UDP, we will use recvfrom() initially
343 * to wait for a caller, then use the regular
344 * functions to talk to the caller.
345 */
346 if (uflag) {
347 int rv, plen;
348 char buf[8192];
349 struct sockaddr_storage z;
350
351 len = sizeof (z);
352 plen = 1024;
353 rv = recvfrom(s, buf, plen, MSG_PEEK,
354 (struct sockaddr *)&z, &len);
355 if (rv < 0)
356 err(1, "recvfrom");
357
358 rv = connect(s, (struct sockaddr *)&z, len);
359 if (rv < 0)
360 err(1, "connect");
361
362 connfd = s;
363 } else {
364 len = sizeof (cliaddr);
365 connfd = accept(s, (struct sockaddr *)&cliaddr,
366 &len);
367 if ((connfd != -1) && vflag) {
368 char ntop[NI_MAXHOST + NI_MAXSERV];
369 (void) fprintf(stderr,
370 "Received connection from %s\n",
371 print_addr(ntop, sizeof (ntop),
372 (struct sockaddr *)&cliaddr, len,
373 nflag ? NI_NUMERICHOST : 0));
374 }
375 }
376
377 readwrite(connfd);
378 (void) close(connfd);
379 if (family != AF_UNIX)
380 (void) close(s);
381
382 if (!kflag)
383 break;
384 }
385 } else if (family == AF_UNIX) {
386 ret = 0;
387
388 if ((s = unix_connect(host)) > 0 && !zflag) {
389 readwrite(s);
390 (void) close(s);
391 } else
392 ret = 1;
393
394 exit(ret);
395
396 } else { /* AF_INET or AF_INET6 */
397 int i;
398
399 /* Construct the portlist. */
400 build_ports(uport);
401
402 /* Cycle through portlist, connecting to each port. */
403 for (i = 0; i < ports.numports; i++) {
404 (void) snprintf(port, sizeof (port), "%u",
405 ports.list[i]);
406
407 if (s != -1)
408 (void) close(s);
409
410 if (xflag)
411 s = socks_connect(host, port,
412 proxyhost, proxyport, proxyhints, socksv,
413 Pflag);
414 else
415 s = remote_connect(host, port, hints);
416
417 if (s < 0)
418 continue;
419
420 ret = 0;
421 if (vflag || zflag) {
422 /* For UDP, make sure we are connected. */
423 if (uflag) {
424 if (udptest(s) == -1) {
425 ret = 1;
426 continue;
427 }
428 }
429
430 /* Don't look up port if -n. */
431 if (nflag)
432 sv = NULL;
433 else {
434 sv = getservbyport(
435 ntohs(ports.list[i]),
436 uflag ? "udp" : "tcp");
437 }
438
439 (void) fprintf(stderr, "Connection to %s %s "
440 "port [%s/%s] succeeded!\n",
441 host, port, uflag ? "udp" : "tcp",
442 sv ? sv->s_name : "*");
443 }
444 if (!zflag)
445 readwrite(s);
446 }
447 free(ports.list);
448 }
449
450 if (s != -1)
451 (void) close(s);
452
453 return (ret);
454 }
455
456 /*
457 * print IP address and (optionally) a port
458 */
459 char *
print_addr(char * ntop,size_t ntlen,struct sockaddr * addr,int len,int flags)460 print_addr(char *ntop, size_t ntlen, struct sockaddr *addr, int len, int flags)
461 {
462 char port[NI_MAXSERV];
463 int e;
464
465 /* print port always as number */
466 if ((e = getnameinfo(addr, len, ntop, ntlen,
467 port, sizeof (port), flags|NI_NUMERICSERV)) != 0) {
468 return ((char *)gai_strerror(e));
469 }
470
471 (void) strlcat(ntop, " port ", ntlen);
472 (void) strlcat(ntop, port, ntlen);
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