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 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 * 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 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 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 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 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 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 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 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 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 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 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 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 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