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