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