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