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