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