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