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