1 /* $OpenBSD: netcat.c,v 1.39 2001/10/28 19:52:04 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 ((error = 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 close(s); 365 s = -1; 366 } while ((res0 = res0->ai_next) != NULL); 367 368 freeaddrinfo(res); 369 370 return (s); 371 } 372 373 /* 374 * local_listen() 375 * Return's a socket listening on a local port, binds to specified source 376 * address. Return's -1 on failure. 377 */ 378 int 379 local_listen(char *host, char *port, struct addrinfo hints) 380 { 381 struct addrinfo *res, *res0; 382 int s, ret, x = 1; 383 int error; 384 385 /* Allow nodename to be null */ 386 hints.ai_flags |= AI_PASSIVE; 387 388 /* 389 * In the case of binding to a wildcard address 390 * default to binding to an ipv4 address. 391 */ 392 if (host == NULL && hints.ai_family == AF_UNSPEC) 393 hints.ai_family = AF_INET; 394 395 if ((error = getaddrinfo(host, port, &hints, &res))) 396 errx(1, "%s", gai_strerror(error)); 397 398 res0 = res; 399 do { 400 if ((s = socket(res0->ai_family, res0->ai_socktype, 401 res0->ai_protocol)) == 0) 402 continue; 403 404 ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x)); 405 if (ret == -1) 406 err(1, NULL); 407 408 if (bind(s, (struct sockaddr *)res0->ai_addr, 409 res0->ai_addrlen) == 0) 410 break; 411 412 close(s); 413 s = -1; 414 } while ((res0 = res0->ai_next) != NULL); 415 416 if (!uflag) { 417 if (listen(s, 1) < 0) 418 errx(1, "%s", strerror(errno)); 419 } 420 421 freeaddrinfo(res); 422 423 return (s); 424 } 425 426 /* 427 * readwrite() 428 * Loop that polls on the network file descriptor and stdin. 429 */ 430 void 431 readwrite(int nfd) 432 { 433 struct pollfd *pfd; 434 char buf[BUFSIZ]; 435 int wfd = fileno(stdin), n, ret; 436 int lfd = fileno(stdout); 437 438 pfd = malloc(2 * sizeof(struct pollfd)); 439 440 /* Setup Network FD */ 441 pfd[0].fd = nfd; 442 pfd[0].events = POLLIN; 443 444 /* Setup STDIN FD */ 445 pfd[1].fd = wfd; 446 pfd[1].events = POLLIN; 447 448 for (;;) { 449 if (iflag) 450 sleep(iflag); 451 452 if (poll(pfd, 2, timeout) < 0) { 453 close(nfd); 454 close(wfd); 455 free(pfd); 456 errx(1, "Polling Error"); 457 } 458 459 if (pfd[0].revents & POLLIN) { 460 if ((n = read(nfd, buf, sizeof(buf))) <= 0) { 461 return; 462 } else { 463 if (tflag) 464 atelnet(nfd, buf, n); 465 if ((ret = atomicio(write, lfd, buf, n)) != n) 466 return; 467 } 468 } 469 470 if (pfd[1].revents & POLLIN) { 471 if ((n = read(wfd, buf, sizeof(buf))) <= 0) { 472 return; 473 } else 474 if((ret = atomicio(write, nfd, buf, n)) != n) 475 return; 476 } 477 } 478 } 479 /* Deal with RFC854 WILL/WONT DO/DONT negotiation */ 480 void 481 atelnet(int nfd, unsigned char *buf, unsigned int size) 482 { 483 int ret; 484 unsigned char *p, *end; 485 unsigned char obuf[4]; 486 487 end = buf + size; 488 obuf[0] = '\0'; 489 490 for (p = buf; p < end; p++) { 491 if (*p != IAC) 492 break; 493 494 obuf[0] = IAC; 495 p++; 496 if ((*p == WILL) || (*p == WONT)) { 497 obuf[1] = DONT; 498 } 499 if ((*p == DO) || (*p == DONT)) { 500 obuf[1] = WONT; 501 } 502 if (obuf) { 503 p++; 504 obuf[2] = *p; 505 obuf[3] = '\0'; 506 if ((ret = atomicio(write , nfd, obuf, 3)) != 3) 507 warnx("Write Error!"); 508 obuf[0] = '\0'; 509 } 510 } 511 } 512 513 /* 514 * build_ports() 515 * Build an array or ports in portlist[], listing each port 516 * that we should try to connect too. 517 */ 518 void 519 build_ports(char *p) 520 { 521 char *n, *endp; 522 int hi, lo, cp; 523 int x = 0; 524 525 if ((n = strchr(p, '-')) != NULL) { 526 if (lflag) 527 errx(1, "Cannot use -l with multiple ports!"); 528 529 *n = '\0'; 530 n++; 531 532 /* Make sure the ports are in order: lowest->highest */ 533 hi = (int)strtoul(n, &endp, 10); 534 if (hi <= 0 || hi > PORT_MAX || *endp != '\0') 535 errx(1, "port range not valid"); 536 lo = (int)strtoul(p, &endp, 10); 537 if (lo <= 0 || lo > PORT_MAX || *endp != '\0') 538 errx(1, "port range not valid"); 539 540 if (lo > hi) { 541 cp = hi; 542 hi = lo; 543 lo = cp; 544 } 545 546 /* Load ports sequentially */ 547 for (cp = lo; cp <= hi; cp++) { 548 portlist[x] = calloc(1, PORT_MAX); 549 sprintf(portlist[x], "%d", cp); 550 x++; 551 } 552 553 /* Randomly swap ports */ 554 if (rflag) { 555 int y; 556 char *c; 557 558 for (x = 0; x <= (hi - lo); x++) { 559 y = (arc4random() & 0xFFFF) % (hi - lo); 560 c = portlist[x]; 561 portlist[x] = portlist[y]; 562 portlist[y] = c; 563 } 564 } 565 } else { 566 hi = (int)strtoul(p, &endp, 10); 567 if (hi <= 0 || hi > PORT_MAX || *endp != '\0') 568 errx(1, "port range not valid"); 569 portlist[0] = calloc(1, PORT_MAX); 570 portlist[0] = p; 571 } 572 } 573 574 /* 575 * udptest() 576 * Do a few writes to see if the UDP port is there. 577 * XXX - Better way of doing this? Doesn't work for IPv6 578 * Also fails after around 100 ports checked. 579 */ 580 int 581 udptest(int s) 582 { 583 int i, rv, ret; 584 585 for (i=0; i <= 3; i++) { 586 if ((rv = write(s, "X", 1)) == 1) 587 ret = 1; 588 else 589 ret = -1; 590 } 591 return (ret); 592 } 593 594 void 595 help() 596 { 597 usage(0); 598 fprintf(stderr, "\tCommand Summary:\n\ 599 \t-4 Use IPv4\n\ 600 \t-6 Use IPv6\n\ 601 \t-h This help text\n\ 602 \t-i secs\t Delay interval for lines sent, ports scanned\n\ 603 \t-k Keep inbound sockets open for multiple connects\n\ 604 \t-l Listen mode, for inbound connects\n\ 605 \t-n Suppress name/port resolutions\n\ 606 \t-p port\t Specify local port for remote connects\n\ 607 \t-r Randomize remote ports\n\ 608 \t-s addr\t Local source address\n\ 609 \t-t Answer TELNET negotiation\n\ 610 \t-u UDP mode\n\ 611 \t-v Verbose\n\ 612 \t-w secs\t Timeout for connects and final net reads\n\ 613 \t-x addr[:port]\tSpecify socks5 proxy address and port\n\ 614 \t-z Zero-I/O mode [used for scanning]\n\ 615 Port numbers can be individual or ranges: lo-hi [inclusive]\n"); 616 exit(1); 617 } 618 619 void 620 usage(int ret) 621 { 622 fprintf(stderr, "usage: nc [-46hklnrtuvz] [-i interval] [-p source port]\n"); 623 fprintf(stderr, "\t [-s ip address] [-w timeout] [-x proxy address [:port]]\n"); 624 fprintf(stderr, "\t [hostname] [port[s...]]\n"); 625 if (ret) 626 exit(1); 627 } 628