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