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