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 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 * 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) snprintf(ntop, ntlen, "%s port %s", ntop, port); 472 473 return (ntop); 474 } 475 476 /* 477 * unix_connect() 478 * Returns a socket connected to a local unix socket. Returns -1 on failure. 479 */ 480 int 481 unix_connect(char *path) 482 { 483 struct sockaddr_un sunaddr; 484 int s; 485 486 if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) 487 return (-1); 488 489 (void) memset(&sunaddr, 0, sizeof (struct sockaddr_un)); 490 sunaddr.sun_family = AF_UNIX; 491 492 if (strlcpy(sunaddr.sun_path, path, sizeof (sunaddr.sun_path)) >= 493 sizeof (sunaddr.sun_path)) { 494 (void) close(s); 495 errno = ENAMETOOLONG; 496 return (-1); 497 } 498 if (connect(s, (struct sockaddr *)&sunaddr, SUN_LEN(&sunaddr)) < 0) { 499 (void) close(s); 500 return (-1); 501 } 502 return (s); 503 } 504 505 /* 506 * unix_listen() 507 * Create a unix domain socket, and listen on it. 508 */ 509 int 510 unix_listen(char *path) 511 { 512 struct sockaddr_un sunaddr; 513 int s; 514 515 /* Create unix domain socket. */ 516 if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) 517 return (-1); 518 519 (void) memset(&sunaddr, 0, sizeof (struct sockaddr_un)); 520 sunaddr.sun_family = AF_UNIX; 521 522 if (strlcpy(sunaddr.sun_path, path, sizeof (sunaddr.sun_path)) >= 523 sizeof (sunaddr.sun_path)) { 524 (void) close(s); 525 errno = ENAMETOOLONG; 526 return (-1); 527 } 528 529 if (bind(s, (struct sockaddr *)&sunaddr, SUN_LEN(&sunaddr)) < 0) { 530 (void) close(s); 531 return (-1); 532 } 533 534 if (listen(s, 5) < 0) { 535 (void) close(s); 536 return (-1); 537 } 538 return (s); 539 } 540 541 /* 542 * remote_connect() 543 * Returns a socket connected to a remote host. Properly binds to a local 544 * port or source address if needed. Returns -1 on failure. 545 */ 546 int 547 remote_connect(const char *host, const char *port, struct addrinfo hints) 548 { 549 struct addrinfo *res, *res0; 550 int s, error; 551 552 if ((error = getaddrinfo(host, port, &hints, &res))) 553 errx(1, "getaddrinfo: %s", gai_strerror(error)); 554 555 res0 = res; 556 do { 557 if ((s = socket(res0->ai_family, res0->ai_socktype, 558 res0->ai_protocol)) < 0) { 559 warn("failed to create socket"); 560 continue; 561 } 562 563 /* Bind to a local port or source address if specified. */ 564 if (sflag || pflag) { 565 struct addrinfo ahints, *ares; 566 567 (void) memset(&ahints, 0, sizeof (struct addrinfo)); 568 ahints.ai_family = res0->ai_family; 569 ahints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM; 570 ahints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP; 571 ahints.ai_flags = AI_PASSIVE; 572 if ((error = getaddrinfo(sflag, pflag, &ahints, &ares))) 573 errx(1, "getaddrinfo: %s", gai_strerror(error)); 574 575 if (bind(s, (struct sockaddr *)ares->ai_addr, 576 ares->ai_addrlen) < 0) 577 errx(1, "bind failed: %s", strerror(errno)); 578 freeaddrinfo(ares); 579 580 if (vflag && !lflag) { 581 if (sflag != NULL) 582 (void) fprintf(stderr, 583 "Using source address: %s\n", 584 sflag); 585 if (pflag != NULL) 586 (void) fprintf(stderr, 587 "Using source port: %s\n", pflag); 588 } 589 } 590 591 set_common_sockopts(s); 592 593 if (connect(s, res0->ai_addr, res0->ai_addrlen) == 0) 594 break; 595 else if (vflag) { 596 char ntop[NI_MAXHOST + NI_MAXSERV]; 597 warn("connect to %s [host %s] (%s) failed", 598 print_addr(ntop, sizeof (ntop), 599 res0->ai_addr, res0->ai_addrlen, NI_NUMERICHOST), 600 host, uflag ? "udp" : "tcp"); 601 } 602 603 (void) close(s); 604 s = -1; 605 } while ((res0 = res0->ai_next) != NULL); 606 607 freeaddrinfo(res); 608 609 return (s); 610 } 611 612 /* 613 * local_listen() 614 * Returns a socket listening on a local port, binds to specified source 615 * address. Returns -1 on failure. 616 */ 617 int 618 local_listen(char *host, char *port, struct addrinfo hints) 619 { 620 struct addrinfo *res, *res0; 621 int s, ret, x = 1; 622 int error; 623 624 /* Allow nodename to be null. */ 625 hints.ai_flags |= AI_PASSIVE; 626 627 if ((error = getaddrinfo(host, port, &hints, &res))) 628 errx(1, "getaddrinfo: %s", gai_strerror(error)); 629 630 res0 = res; 631 do { 632 if ((s = socket(res0->ai_family, res0->ai_socktype, 633 res0->ai_protocol)) < 0) { 634 warn("failed to create socket"); 635 continue; 636 } 637 638 ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &x, sizeof (x)); 639 if (ret == -1) 640 err(1, NULL); 641 642 set_common_sockopts(s); 643 644 if (bind(s, (struct sockaddr *)res0->ai_addr, 645 res0->ai_addrlen) == 0) 646 break; 647 648 (void) close(s); 649 s = -1; 650 } while ((res0 = res0->ai_next) != NULL); 651 652 if (!uflag && s != -1) { 653 if (listen(s, 1) < 0) 654 err(1, "listen"); 655 } 656 657 freeaddrinfo(res); 658 659 return (s); 660 } 661 662 /* 663 * readwrite() 664 * Loop that polls on the network file descriptor and stdin. 665 */ 666 void 667 readwrite(int nfd) 668 { 669 struct pollfd pfd[2]; 670 unsigned char buf[8192]; 671 int n, wfd = fileno(stdin); 672 int lfd = fileno(stdout); 673 int plen; 674 675 plen = 1024; 676 677 /* Setup Network FD */ 678 pfd[0].fd = nfd; 679 pfd[0].events = POLLIN; 680 681 /* Set up STDIN FD. */ 682 pfd[1].fd = wfd; 683 pfd[1].events = POLLIN; 684 685 while (pfd[0].fd != -1) { 686 if (iflag) 687 (void) sleep(iflag); 688 689 if ((n = poll(pfd, 2 - dflag, timeout)) < 0) { 690 (void) close(nfd); 691 err(1, "Polling Error"); 692 } 693 694 if (n == 0) 695 return; 696 697 if (pfd[0].revents & (POLLIN|POLLHUP)) { 698 if ((n = read(nfd, buf, plen)) < 0) 699 return; 700 else if (n == 0) { 701 (void) shutdown(nfd, SHUT_RD); 702 pfd[0].fd = -1; 703 pfd[0].events = 0; 704 } else { 705 if (tflag) 706 atelnet(nfd, buf, n); 707 if (atomicio(vwrite, lfd, buf, n) != n) 708 return; 709 } 710 } 711 712 /* 713 * handle the case of disconnected pipe: after pipe 714 * is closed (indicated by POLLHUP) there may still 715 * be some data lingering (POLLIN). After we read 716 * the data, only POLLHUP remains, read() returns 0 717 * and we are finished. 718 */ 719 if (!dflag && (pfd[1].revents & (POLLIN|POLLHUP))) { 720 if ((n = read(wfd, buf, plen)) < 0) 721 return; 722 else if (n == 0) { 723 (void) shutdown(nfd, SHUT_WR); 724 pfd[1].fd = -1; 725 pfd[1].events = 0; 726 } else { 727 if (atomicio(vwrite, nfd, buf, n) != n) 728 return; 729 } 730 } 731 } 732 } 733 734 /* Deal with RFC 854 WILL/WONT DO/DONT negotiation. */ 735 void 736 atelnet(int nfd, unsigned char *buf, unsigned int size) 737 { 738 unsigned char *p, *end; 739 unsigned char obuf[4]; 740 741 end = buf + size; 742 obuf[0] = '\0'; 743 744 for (p = buf; p < end; p++) { 745 if (*p != IAC) 746 break; 747 748 obuf[0] = IAC; 749 obuf[1] = 0; 750 p++; 751 /* refuse all options */ 752 if ((*p == WILL) || (*p == WONT)) 753 obuf[1] = DONT; 754 if ((*p == DO) || (*p == DONT)) 755 obuf[1] = WONT; 756 if (obuf[1]) { 757 p++; 758 obuf[2] = *p; 759 obuf[3] = '\0'; 760 if (atomicio(vwrite, nfd, obuf, 3) != 3) 761 warn("Write Error!"); 762 obuf[0] = '\0'; 763 } 764 } 765 } 766 767 /* 768 * build_ports() 769 * Build an array of ports in ports.list[], listing each port 770 * that we should try to connect to. 771 */ 772 void 773 build_ports(char *p) 774 { 775 const char *errstr; 776 const char *token; 777 char *n; 778 int lo, hi, cp; 779 int i; 780 781 /* Set up initial portlist. */ 782 ports.list = malloc(PLIST_SZ * sizeof (uint16_t)); 783 if (ports.list == NULL) 784 err(1, NULL); 785 ports.listsize = PLIST_SZ; 786 ports.numports = 0; 787 788 /* Cycle through list of given ports sep. by "," */ 789 while ((token = strsep(&p, ",")) != NULL) { 790 if (*token == '\0') 791 errx(1, "Invalid port/portlist format: " 792 "zero length port"); 793 794 /* check if it is a range */ 795 if ((n = strchr(token, '-')) != NULL) 796 *n++ = '\0'; 797 798 lo = strtonum(token, PORT_MIN, PORT_MAX, &errstr); 799 if (errstr) 800 errx(1, "port number %s: %s", errstr, token); 801 802 if (n == NULL) { 803 hi = lo; 804 } else { 805 hi = strtonum(n, PORT_MIN, PORT_MAX, &errstr); 806 if (errstr) 807 errx(1, "port number %s: %s", errstr, n); 808 if (lo > hi) { 809 cp = hi; 810 hi = lo; 811 lo = cp; 812 } 813 } 814 815 /* 816 * Grow the portlist if needed. 817 * We double the size and add size of current range 818 * to make sure we don't have to resize that often. 819 */ 820 if (hi - lo + ports.numports + 1 >= ports.listsize) { 821 ports.listsize = ports.listsize * 2 + hi - lo; 822 ports.list = realloc(ports.list, 823 ports.listsize * sizeof (uint16_t)); 824 if (ports.list == NULL) 825 err(1, NULL); 826 } 827 828 /* Load ports sequentially. */ 829 for (i = lo; i <= hi; i++) 830 ports.list[ports.numports++] = i; 831 } 832 833 /* Randomly swap ports. */ 834 if (rflag) { 835 int y; 836 uint16_t u; 837 838 if (ports.numports < 2) { 839 warnx("can not swap %d port randomly", 840 ports.numports); 841 return; 842 } 843 srandom(time(NULL)); 844 for (i = 0; i < ports.numports; i++) { 845 y = random() % (ports.numports - 1); 846 u = ports.list[i]; 847 ports.list[i] = ports.list[y]; 848 ports.list[y] = u; 849 } 850 } 851 } 852 853 /* 854 * udptest() 855 * Do a few writes to see if the UDP port is there. 856 * XXX - Better way of doing this? Doesn't work for IPv6. 857 * Also fails after around 100 ports checked. 858 */ 859 int 860 udptest(int s) 861 { 862 int i, ret; 863 864 for (i = 0; i <= 3; i++) { 865 if (write(s, "X", 1) == 1) 866 ret = 1; 867 else 868 ret = -1; 869 } 870 return (ret); 871 } 872 873 void 874 set_common_sockopts(int s) 875 { 876 int x = 1; 877 878 if (Dflag) { 879 if (setsockopt(s, SOL_SOCKET, SO_DEBUG, &x, sizeof (x)) == -1) 880 err(1, NULL); 881 } 882 if (Tflag != -1) { 883 if (setsockopt(s, IPPROTO_IP, IP_TOS, &Tflag, 884 sizeof (Tflag)) == -1) 885 err(1, "set IP ToS"); 886 } 887 } 888 889 int 890 parse_iptos(char *s) 891 { 892 int tos = -1; 893 894 if (strcmp(s, "lowdelay") == 0) 895 return (IPTOS_LOWDELAY); 896 if (strcmp(s, "throughput") == 0) 897 return (IPTOS_THROUGHPUT); 898 if (strcmp(s, "reliability") == 0) 899 return (IPTOS_RELIABILITY); 900 901 if (sscanf(s, "0x%x", (unsigned int *) &tos) != 1 || 902 tos < 0 || tos > 0xff) 903 errx(1, "invalid IP Type of Service"); 904 return (tos); 905 } 906 907 void 908 help(void) 909 { 910 usage(0); 911 (void) fprintf(stderr, "\tCommand Summary:\n\ 912 \t-4 Use IPv4\n\ 913 \t-6 Use IPv6\n\ 914 \t-D Enable the debug socket option\n\ 915 \t-d Detach from stdin\n\ 916 \t-h This help text\n\ 917 \t-i secs\t Delay interval for lines sent, ports scanned\n\ 918 \t-k Keep inbound sockets open for multiple connects\n\ 919 \t-l Listen mode, for inbound connects\n\ 920 \t-n Suppress name/port resolutions\n\ 921 \t-P proxyuser\tUsername for proxy authentication\n\ 922 \t-p port\t Specify local port or listen port\n\ 923 \t-r Randomize remote ports\n\ 924 \t-s addr\t Local source address\n\ 925 \t-T ToS\t Set IP Type of Service\n\ 926 \t-t Answer TELNET negotiation\n\ 927 \t-U Use UNIX domain socket\n\ 928 \t-u UDP mode\n\ 929 \t-v Verbose\n\ 930 \t-w secs\t Timeout for connects and final net reads\n\ 931 \t-X proto Proxy protocol: \"4\", \"5\" (SOCKS) or \"connect\"\n\ 932 \t-x addr[:port]\tSpecify proxy address and port\n\ 933 \t-z Zero-I/O mode [used for scanning]\n\ 934 Port numbers can be individuals, ranges (lo-hi; inclusive) and\n\ 935 combinations of both separated by comma (e.g. 10,22-25,80)\n"); 936 exit(1); 937 } 938 939 void 940 usage(int ret) 941 { 942 (void) fprintf(stderr, 943 "usage: nc [-46DdhklnrtUuvz] [-i interval] [-P proxy_username]" 944 " [-p port]\n"); 945 (void) fprintf(stderr, 946 "\t [-s source_ip_address] [-T ToS] [-w timeout]" 947 " [-X proxy_protocol]\n"); 948 (void) fprintf(stderr, 949 "\t [-x proxy_address[:port]] [hostname]" 950 " [port[s]]\n"); 951 if (ret) 952 exit(1); 953 } 954