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