1 /* $OpenBSD: netcat.c,v 1.19 2001/01/16 20:20:48 ericj Exp $ */ 2 3 /* Netcat 1.10 RELEASE 960320 4 * 5 * A damn useful little "backend" utility begun 950915 or thereabouts, 6 * as *Hobbit*'s first real stab at some sockets programming. Something that 7 * should have and indeed may have existed ten years ago, but never became a 8 * standard Unix utility. IMHO, "nc" could take its place right next to cat, 9 * cp, rm, mv, dd, ls, and all those other cryptic and Unix-like things. 10 * 11 * Read the README for the whole story, doc, applications, etc. 12 * 13 * Layout: 14 * conditional includes: 15 * includes: 16 * handy defines: 17 * globals: 18 * malloced globals: 19 * cmd-flag globals: 20 * support routines: 21 * readwrite select loop: 22 * main: 23 * 24 * bluesky: 25 * parse ranges of IP address as well as ports, perhaps 26 * RAW mode! 27 * backend progs to grab a pty and look like a real telnetd?! 28 * backend progs to do various encryption modes??!?! 29 */ 30 31 32 #include <sys/types.h> 33 #include <sys/time.h> 34 #include <sys/select.h> 35 #include <sys/socket.h> 36 #include <netinet/in.h> 37 #include <netinet/in_systm.h> 38 #include <netinet/ip.h> 39 #include <arpa/inet.h> 40 #include <arpa/nameser.h> 41 #include <netdb.h> /* hostent, gethostby*, getservby* */ 42 #include <stdio.h> 43 #include <string.h> 44 #include <err.h> 45 #include <errno.h> 46 #include <setjmp.h> 47 #include <signal.h> 48 #include <fcntl.h> 49 #include <resolv.h> 50 #include <stdarg.h> 51 #include <stdlib.h> 52 #include <unistd.h> 53 54 #define SLEAZE_PORT 31337 /* for UDP-scan RTT trick, change if ya want */ 55 #define BIGSIZ 8192 /* big buffers */ 56 57 struct host_info { 58 char name[MAXHOSTNAMELEN]; /* DNS name */ 59 char addrs[8][24]; /* ascii-format IP addresses */ 60 struct in_addr iaddrs[8]; /* in_addr.s_addr: ulong */ 61 }; 62 63 struct port_info { 64 char name[64]; /* name in /etc/services */ 65 char anum[8]; /* ascii-format number */ 66 u_short num; /* real host-order number */ 67 }; 68 69 /* globals: */ 70 jmp_buf jbuf; /* timer jump buffer*/ 71 int jval = 0; /* timer crud */ 72 int netfd = -1; 73 int ofd = 0; /* hexdump output fd */ 74 75 int gatesidx = 0; /* LSRR hop count */ 76 int gatesptr = 4; /* initial LSRR pointer, settable */ 77 u_short Single = 1; /* zero if scanning */ 78 unsigned int insaved = 0; /* stdin-buffer size for multi-mode */ 79 unsigned int wrote_out = 0; /* total stdout bytes */ 80 unsigned int wrote_net = 0; /* total net bytes */ 81 static char hexnibs[20] = "0123456789abcdef "; 82 83 /* will malloc up the following globals: */ 84 struct timeval timer1, timer2; 85 struct sockaddr_in *lclend = NULL; /* sockaddr_in structs */ 86 struct sockaddr_in *remend = NULL; 87 struct host_info **gates = NULL; /* LSRR hop hinfo */ 88 char *optbuf = NULL; /* LSRR or sockopts */ 89 char *bigbuf_in; /* data buffers */ 90 char *bigbuf_net; 91 fd_set fds1, fds2; 92 struct port_info *pinfo = NULL; /* for getpinfo / getservby* */ 93 unsigned char *stage = NULL; /* hexdump line buffer */ 94 95 /* global cmd flags: */ 96 u_short o_alla = 0; 97 unsigned int o_interval = 0; 98 u_short o_listen = 0; 99 u_short o_nflag = 0; 100 u_short o_wfile = 0; 101 u_short o_random = 0; 102 u_short o_udpmode = 0; 103 u_short o_verbose = 0; 104 unsigned int o_wait = 0; 105 u_short o_zero = 0; 106 107 /* Function Prototype's */ 108 void help __P(()); 109 void nlog __P((int, char *, ...)); 110 void usage __P((int)); 111 112 /* 113 * support routines -- the bulk of this thing. Placed in such an order that 114 * we don't have to forward-declare anything: 115 */ 116 117 /* 118 * catch : 119 * no-brainer interrupt handler 120 */ 121 void 122 catch() 123 { 124 if (o_verbose) /* normally we don't care */ 125 nlog(1, "Sent %i Rcvd %i", wrote_net, wrote_out); 126 nlog(1, " punt!"); 127 } 128 129 /* timeout and other signal handling cruft */ 130 void 131 tmtravel() 132 { 133 signal(SIGALRM, SIG_IGN); 134 alarm(0); 135 if (jval == 0) 136 nlog(1, "spurious timer interrupt!"); 137 longjmp(jbuf, jval); 138 } 139 140 /* 141 * arm : 142 * set the timer. Zero secs arg means unarm 143 */ 144 void 145 arm(num, secs) 146 unsigned int num; 147 unsigned int secs; 148 { 149 if (secs == 0) { 150 signal(SIGALRM, SIG_IGN); 151 alarm(0); 152 jval = 0; 153 } else { 154 signal(SIGALRM, tmtravel); 155 alarm(secs); 156 jval = num; 157 } 158 } 159 160 /* 161 * findline : 162 * find the next newline in a buffer; return inclusive size of that "line", 163 * or the entire buffer size, so the caller knows how much to then write(). 164 * Not distinguishing \n vs \r\n for the nonce; it just works as is... 165 */ 166 unsigned int 167 findline(buf, siz) 168 char *buf; 169 unsigned int siz; 170 { 171 char *p; 172 int x; 173 if (!buf) /* various sanity checks... */ 174 return (0); 175 if (siz > BIGSIZ) 176 return (0); 177 x = siz; 178 for (p = buf; x > 0; x--) { 179 if (*p == '\n') { 180 x = (int) (p - buf); 181 x++; /* 'sokay if it points just past the end! */ 182 return (x); 183 } 184 p++; 185 } 186 return (siz); 187 } 188 189 /* 190 * comparehosts : 191 * cross-check the host_info we have so far against new gethostby*() info, 192 * and holler about mismatches. Perhaps gratuitous, but it can't hurt to 193 * point out when someone's DNS is fukt. Returns 1 if mismatch, in case 194 * someone else wants to do something about it. 195 */ 196 int 197 comparehosts(hinfo, hp) 198 struct host_info *hinfo; 199 struct hostent *hp; 200 { 201 if (strcasecmp(hinfo->name, hp->h_name) != 0) { 202 nlog(0, "DNS fwd/rev mismatch: %s != %s", hinfo->name, hp->h_name); 203 return (1); 204 } 205 return (0); 206 } 207 208 /* 209 * gethinfo: 210 * resolve a host 8 ways from sunday; return a new host_info struct with its 211 * info. The argument can be a name or [ascii] IP address; it will try its 212 * damndest to deal with it. "numeric" governs whether we do any DNS at all, 213 * and we also check o_verbose for what's appropriate work to do. 214 */ 215 struct host_info * 216 gethinfo(name, numeric) 217 char *name; 218 u_short numeric; 219 { 220 struct hostent *hostent; 221 struct in_addr iaddr; 222 struct host_info *hinfo = NULL; 223 int x; 224 225 if (name) 226 hinfo = (struct host_info *) calloc(1, sizeof(struct host_info)); 227 228 if (!hinfo) 229 nlog(1, "error obtaining host information"); 230 231 strlcpy(hinfo->name, "(UNKNOWN)", sizeof(hinfo->name)); 232 if (inet_aton(name, &iaddr) == 0) { 233 if (numeric) 234 nlog(1, "Can't parse %s as an IP address", name); 235 236 /* 237 * failure to look up a name is fatal, 238 * since we can't do anything with it. 239 */ 240 hostent = gethostbyname(name); 241 if (!hostent) 242 nlog(1, "%s: forward host lookup failed: ", name); 243 244 strlcpy(hinfo->name, hostent->h_name, MAXHOSTNAMELEN); 245 for (x = 0; hostent->h_addr_list[x] && (x < 8); x++) { 246 memcpy(&hinfo->iaddrs[x], hostent->h_addr_list[x], 247 sizeof(struct in_addr)); 248 strlcpy(hinfo->addrs[x], inet_ntoa(hinfo->iaddrs[x]), 249 sizeof(hinfo->addrs[0])); 250 } 251 /* Go ahead and return if we don't want to view more */ 252 if (!o_verbose) 253 return (hinfo); 254 255 /* 256 * Do inverse lookups in separate loop based on our collected 257 * forward addrs, since gethostby* tends to crap into the same 258 * buffer over and over. 259 */ 260 for (x = 0; hinfo->iaddrs[x].s_addr && (x < 8); x++) { 261 hostent = gethostbyaddr((char *) &hinfo->iaddrs[x], 262 sizeof(struct in_addr), AF_INET); 263 if ((!hostent) || (!hostent->h_name)) 264 nlog(0, "Warning: inverse host lookup failed for %s: ", 265 hinfo->addrs[x]); 266 else 267 (void) comparehosts(hinfo, hostent); 268 } 269 270 } else { /* not INADDR_NONE: numeric addresses... */ 271 memcpy(hinfo->iaddrs, &iaddr, sizeof(struct in_addr)); 272 strlcpy(hinfo->addrs[0], inet_ntoa(iaddr), sizeof(hinfo->addrs)); 273 /* If all that's wanted is numeric IP, go ahead and leave */ 274 if (numeric) 275 return (hinfo); 276 277 /* Go ahead and return if we don't want to view more */ 278 if (!o_verbose) 279 return (hinfo); 280 281 hostent = gethostbyaddr((char *) &iaddr, 282 sizeof(struct in_addr), AF_INET); 283 284 /* 285 * numeric or not, failure to look up a PTR is 286 * *not* considered fatal 287 */ 288 if (!hostent) 289 nlog(0, "%s: inverse host lookup failed: ", name); 290 else { 291 strlcpy(hinfo->name, hostent->h_name, MAXHOSTNAMELEN); 292 hostent = gethostbyname(hinfo->name); 293 if ((!hostent) || (!hostent->h_addr_list[0])) 294 nlog(0, "Warning: forward host lookup failed for %s: ", 295 hinfo->name); 296 else 297 (void) comparehosts(hinfo, hostent); 298 } 299 } 300 301 /* 302 * Whatever-all went down previously, we should now have a host_info 303 * struct with at least one IP address in it. 304 */ 305 return (hinfo); 306 } 307 308 /* 309 * getpinfo: 310 * Same general idea as gethinfo-- look up a port in /etc/services, fill 311 * in global port_info, but return the actual port *number*. Pass ONE of: 312 * pstring to resolve stuff like "23" or "exec"; 313 * pnum to reverse-resolve something that's already a number. 314 * If o_nflag is on, fill in what we can but skip the getservby??? stuff. 315 * Might as well have consistent behavior here, and it *is* faster. 316 */ 317 u_short 318 getpinfo(pstring, pnum) 319 char *pstring; 320 unsigned int pnum; 321 { 322 struct servent *servent; 323 int x; 324 int y; 325 326 pinfo->name[0] = '?';/* fast preload */ 327 pinfo->name[1] = '\0'; 328 329 /* 330 * case 1: reverse-lookup of a number; placed first since this case 331 * is much more frequent if we're scanning. 332 */ 333 if (pnum) { 334 /* Can't be both */ 335 if (pstring) 336 return (0); 337 338 x = pnum; 339 if (o_nflag) /* go faster, skip getservbyblah */ 340 goto gp_finish; 341 y = htons(x); /* gotta do this -- see Fig.1 below */ 342 servent = getservbyport(y, o_udpmode ? "udp" : "tcp"); 343 if (servent) { 344 y = ntohs(servent->s_port); 345 if (x != y) 346 nlog(0, "Warning: port-bynum mismatch, %d != %d", x, y); 347 strlcpy(pinfo->name, servent->s_name, 348 sizeof(pinfo->name)); 349 } 350 goto gp_finish; 351 } 352 /* 353 * case 2: resolve a string, but we still give preference to numbers 354 * instead of trying to resolve conflicts. None of the entries in *my* 355 * extensive /etc/services begins with a digit, so this should "always 356 * work" unless you're at 3com and have some company-internal services 357 * defined. 358 */ 359 if (pstring) { 360 /* Can't be both */ 361 if (pnum) 362 return (0); 363 364 x = atoi(pstring); 365 if (x) 366 return (getpinfo(NULL, x)); /* recurse for 367 * numeric-string-arg */ 368 if (o_nflag) 369 return (0); 370 servent = getservbyname(pstring, o_udpmode ? "udp" : "tcp"); 371 if (servent) { 372 strlcpy(pinfo->name, servent->s_name, 373 sizeof(pinfo->name)); 374 x = ntohs(servent->s_port); 375 goto gp_finish; 376 } /* if servent */ 377 } /* if pstring */ 378 return (0); /* catches any problems so far */ 379 380 gp_finish: 381 /* 382 * Fall here whether or not we have a valid servent at this point, with 383 * x containing our [host-order and therefore useful, dammit] port number. 384 */ 385 sprintf(pinfo->anum, "%d", x); /* always load any numeric 386 * specs! */ 387 pinfo->num = (x & 0xffff); /* u_short, remember... */ 388 return (pinfo->num); 389 } 390 391 /* 392 * nextport : 393 * Come up with the next port to try, be it random or whatever. "block" is 394 * a ptr to randports array, whose bytes [so far] carry these meanings: 395 * 0 ignore 396 * 1 to be tested 397 * 2 tested [which is set as we find them here] 398 * returns a u_short random port, or 0 if all the t-b-t ones are used up. 399 */ 400 u_short 401 nextport(block) 402 char *block; 403 { 404 unsigned int x; 405 unsigned int y; 406 407 y = 70000; /* high safety count for rnd-tries */ 408 while (y > 0) { 409 x = (arc4random() & 0xffff); 410 if (block[x] == 1) { /* try to find a not-done one... */ 411 block[x] = 2; 412 break; 413 } 414 x = 0; 415 y--; 416 } 417 if (x) 418 return (x); 419 420 y = 65535; /* no random one, try linear downsearch */ 421 while (y > 0) { /* if they're all used, we *must* be sure! */ 422 if (block[y] == 1) { 423 block[y] = 2; 424 break; 425 } 426 y--; 427 } 428 if (y) 429 return (y); /* at least one left */ 430 431 return (0); 432 } 433 434 /* 435 * loadports : 436 * set "to be tested" indications in BLOCK, from LO to HI. Almost too small 437 * to be a separate routine, but makes main() a little cleaner. 438 */ 439 void 440 loadports(block, lo, hi) 441 char *block; 442 u_short lo; 443 u_short hi; 444 { 445 u_short x; 446 447 if (!block) 448 nlog(1, "loadports: no block?!"); 449 if ((!lo) || (!hi)) 450 nlog(1, "loadports: bogus values %d, %d", lo, hi); 451 x = hi; 452 while (lo <= x) { 453 block[x] = 1; 454 x--; 455 } 456 } 457 458 459 /* 460 * doconnect : 461 * do all the socket stuff, and return an fd for one of 462 * an open outbound TCP connection 463 * a UDP stub-socket thingie 464 * with appropriate socket options set up if we wanted source-routing, or 465 * an unconnected TCP or UDP socket to listen on. 466 * Examines various global o_blah flags to figure out what-all to do. 467 */ 468 int 469 doconnect(rad, rp, lad, lp) 470 struct in_addr *rad; 471 u_short rp; 472 struct in_addr *lad; 473 u_short lp; 474 { 475 int nnetfd = 0; 476 int rr; 477 int x, y; 478 479 /* grab a socket; set opts */ 480 while (nnetfd == 0) { 481 if (o_udpmode) 482 nnetfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 483 else 484 nnetfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 485 if (nnetfd < 0) 486 nlog(1, "Can't get socket"); 487 } 488 489 x = 1; 490 rr = setsockopt(nnetfd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x)); 491 if (rr == -1) 492 nlog(1, NULL); 493 494 /* fill in all the right sockaddr crud */ 495 lclend->sin_family = AF_INET; 496 remend->sin_family = AF_INET; 497 498 /* if lad/lp, do appropriate binding */ 499 if (lad) 500 memcpy(&lclend->sin_addr.s_addr, lad, sizeof(struct in_addr)); 501 if (lp) 502 lclend->sin_port = htons(lp); 503 504 rr = 0; 505 if (lad || lp) { 506 x = (int) lp; 507 /* try a few times for the local bind, a la ftp-data-port... */ 508 for (y = 4; y > 0; y--) { 509 rr = bind(nnetfd, (struct sockaddr *) lclend, 510 sizeof(struct sockaddr_in)); 511 if (rr == 0) 512 break; 513 if (errno != EADDRINUSE) 514 break; 515 else { 516 nlog(0, "retrying local %s:%d", inet_ntoa(lclend->sin_addr), lp); 517 sleep(2); 518 } 519 } 520 } 521 if (rr) 522 nlog(1, "Can't grab %s:%d with bind", 523 inet_ntoa(lclend->sin_addr), lp); 524 525 if (o_listen) 526 return (nnetfd);/* thanks, that's all for today */ 527 528 memcpy(&remend->sin_addr.s_addr, rad, sizeof(struct in_addr)); 529 remend->sin_port = htons(rp); 530 531 /* wrap connect inside a timer, and hit it */ 532 arm(1, o_wait); 533 if (setjmp(jbuf) == 0) { 534 rr = connect(nnetfd, (struct sockaddr *) remend, 535 sizeof(struct sockaddr)); 536 } else { 537 rr = -1; 538 errno = ETIMEDOUT; 539 } 540 arm(0, 0); 541 if (rr == 0) 542 return (nnetfd); 543 close(nnetfd); 544 return (-1); 545 } 546 547 /* 548 * dolisten : 549 * just like doconnect, and in fact calls a hunk of doconnect, but listens for 550 * incoming and returns an open connection *from* someplace. If we were 551 * given host/port args, any connections from elsewhere are rejected. This 552 * in conjunction with local-address binding should limit things nicely. 553 */ 554 int 555 dolisten(rad, rp, lad, lp) 556 struct in_addr *rad; 557 u_short rp; 558 struct in_addr *lad; 559 u_short lp; 560 { 561 int nnetfd; 562 int rr; 563 struct host_info *whozis = NULL; 564 int x; 565 char *cp; 566 u_short z; 567 568 /* 569 * Pass everything off to doconnect, 570 * who in o_listen mode just gets a socket 571 */ 572 nnetfd = doconnect(rad, rp, lad, lp); 573 if (nnetfd <= 0) 574 return (-1); 575 if (o_udpmode) { 576 if (!lp) 577 nlog(1, "UDP listen needs -p arg"); 578 } else { 579 rr = listen(nnetfd, 1); 580 if (rr < 0) 581 nlog(1, "error listening"); 582 } 583 584 if (o_verbose) { 585 x = sizeof(struct sockaddr); 586 rr = getsockname(nnetfd, (struct sockaddr *) lclend, &x); 587 if (rr < 0) 588 nlog(0, "local getsockname failed"); 589 strcpy(bigbuf_net, "listening on ["); /* buffer reuse... */ 590 if (lclend->sin_addr.s_addr) 591 strcat(bigbuf_net, inet_ntoa(lclend->sin_addr)); 592 else 593 strcat(bigbuf_net, "any"); 594 strcat(bigbuf_net, "] ..."); 595 z = ntohs(lclend->sin_port); 596 nlog(0, "%s %d", bigbuf_net, z); 597 } /* verbose -- whew!! */ 598 /* 599 * UDP is a speeeeecial case -- we have to do I/O *and* get the 600 * calling party's particulars all at once, listen() and accept() 601 * don't apply. At least in the BSD universe, however, recvfrom/PEEK 602 * is enough to tell us something came in, and we can set things up so 603 * straight read/write actually does work after all. Yow. YMMV on 604 * strange platforms! 605 */ 606 if (o_udpmode) { 607 x = sizeof(struct sockaddr); /* retval for recvfrom */ 608 arm(2, o_wait); /* might as well timeout this, too */ 609 if (setjmp(jbuf) == 0) { /* do timeout for initial 610 * connect */ 611 rr = recvfrom(nnetfd, bigbuf_net, BIGSIZ, MSG_PEEK, 612 (struct sockaddr *)remend, &x); 613 } else 614 goto dol_tmo; 615 arm(0, 0); 616 rr = connect(nnetfd, (struct sockaddr *)remend, 617 sizeof(struct sockaddr)); 618 goto whoisit; 619 } 620 /* fall here for TCP */ 621 x = sizeof(struct sockaddr); 622 arm(2, o_wait); 623 if (setjmp(jbuf) == 0) { 624 rr = accept(nnetfd, (struct sockaddr *) remend, &x); 625 } else 626 goto dol_tmo; 627 arm(0, 0); 628 close(nnetfd); /* dump the old socket */ 629 nnetfd = rr; /* here's our new one */ 630 631 whoisit: 632 if (rr < 0) 633 goto dol_err; /* bail out if any errors so far */ 634 635 /* 636 * Find out what address the connection was *to* on 637 * our end, in case we're doing a listen-on-any on 638 * a multihomed machine. This allows one to offer 639 * different services via different alias addresses, 640 * such as the "virtual web site" hack. 641 */ 642 memset(bigbuf_net, 0, 64); 643 cp = &bigbuf_net[32]; 644 x = sizeof(struct sockaddr); 645 rr = getsockname(nnetfd, (struct sockaddr *) lclend, &x); 646 if (rr < 0) 647 nlog(0, "post-rcv getsockname failed"); 648 strcpy(cp, inet_ntoa(lclend->sin_addr)); 649 650 z = ntohs(remend->sin_port); 651 strcpy(bigbuf_net, inet_ntoa(remend->sin_addr)); 652 whozis = gethinfo(bigbuf_net, o_nflag); 653 x = 0; 654 if (rad) /* xxx: fix to go down the *list* if we have 655 * one? */ 656 if (memcmp(rad, whozis->iaddrs, sizeof(struct sockaddr))) 657 x = 1; 658 if (rp) { 659 if (z != rp) 660 x = 1; 661 } 662 if (x) { 663 nlog(1, "invalid connection to [%s] from %s [%s] %d", 664 cp, whozis->name, whozis->addrs[0], z); 665 } 666 if (o_verbose) { 667 nlog(0, "connect to [%s] from %s [%s] %d", 668 cp, whozis->name, whozis->addrs[0], z); 669 } 670 return (nnetfd); 671 672 dol_tmo: 673 errno = ETIMEDOUT; 674 dol_err: 675 close(nnetfd); 676 return (-1); 677 } 678 679 /* 680 * udptest : 681 * fire a couple of packets at a UDP target port, just to see if it's really 682 * there. On BSD kernels, ICMP host/port-unreachable errors get delivered to 683 * our socket as ECONNREFUSED write errors. On SV kernels, we lose; we'll have 684 * to collect and analyze raw ICMP ourselves a la satan's probe_udp_ports 685 * backend. Guess where one could swipe the appropriate code from... 686 * 687 * Use the time delay between writes if given, otherwise use the "tcp ping" 688 * trick for getting the RTT. [I got that idea from pluvius, and warped it.] 689 * Return either the original fd, or clean up and return -1. 690 */ 691 int 692 udptest(fd, where) 693 int fd; 694 struct in_addr *where; 695 { 696 int rr; 697 698 rr = write(fd, bigbuf_in, 1); 699 if (rr != 1) 700 nlog(0, "udptest first write failed: "); 701 if (o_wait) 702 sleep(o_wait); 703 else { 704 o_udpmode = 0; 705 o_wait = 5; 706 rr = doconnect(where, SLEAZE_PORT, 0, 0); 707 if (rr > 0) 708 close(rr); 709 o_wait = 0; 710 o_udpmode++; 711 } 712 rr = write(fd, bigbuf_in, 1); 713 if (rr == 1) 714 return (fd); 715 close(fd); 716 return (-1); 717 } 718 719 /* 720 * oprint : 721 * Hexdump bytes shoveled either way to a running logfile, in the format: 722 * D offset - - - - --- 16 bytes --- - - - - # .... ascii ..... 723 * where "which" sets the direction indicator, D: 724 * 0 -- sent to network, or ">" 725 * 1 -- rcvd and printed to stdout, or "<" 726 * and "buf" and "n" are data-block and length. If the current block generates 727 * a partial line, so be it; we *want* that lockstep indication of who sent 728 * what when. Adapted from dgaudet's original example -- but must be ripping 729 * *fast*, since we don't want to be too disk-bound. 730 */ 731 void 732 oprint(which, buf, n) 733 int which; 734 char *buf; 735 int n; 736 { 737 int bc; /* in buffer count */ 738 int obc; /* current "global" offset */ 739 int soc; /* stage write count */ 740 unsigned char *p; /* main buf ptr; m.b. unsigned here */ 741 unsigned char *op; /* out hexdump ptr */ 742 unsigned char *a; /* out asc-dump ptr */ 743 int x; 744 unsigned int y; 745 746 if (!ofd) 747 nlog(1, "oprint called with no open fd?!"); 748 if (n == 0) 749 return; 750 751 op = stage; 752 if (which) { 753 *op = '<'; 754 obc = wrote_out;/* use the globals! */ 755 } else { 756 *op = '>'; 757 obc = wrote_net; 758 } 759 op++; /* preload "direction" */ 760 *op = ' '; 761 p = (unsigned char *) buf; 762 bc = n; 763 stage[59] = '#'; /* preload separator */ 764 stage[60] = ' '; 765 766 while (bc) { /* for chunk-o-data ... */ 767 x = 16; 768 soc = 78; /* len of whole formatted line */ 769 if (bc < x) { 770 soc = soc - 16 + bc; /* fiddle for however much is 771 * left */ 772 x = (bc * 3) + 11; /* 2 digits + space per, after 773 * D & offset */ 774 op = &stage[x]; 775 x = 16 - bc; 776 while (x) { 777 *op++ = ' '; /* preload filler spaces */ 778 *op++ = ' '; 779 *op++ = ' '; 780 x--; 781 } 782 x = bc; /* re-fix current linecount */ 783 } /* if bc < x */ 784 bc -= x; /* fix wrt current line size */ 785 sprintf(&stage[2], "%8.8x ", obc); /* xxx: still slow? */ 786 obc += x; /* fix current offset */ 787 op = &stage[11];/* where hex starts */ 788 a = &stage[61]; /* where ascii starts */ 789 790 while (x) { /* for line of dump, however long ... */ 791 y = (int) (*p >> 4); /* hi half */ 792 *op = hexnibs[y]; 793 op++; 794 y = (int) (*p & 0x0f); /* lo half */ 795 *op = hexnibs[y]; 796 op++; 797 *op = ' '; 798 op++; 799 if ((*p > 31) && (*p < 127)) 800 *a = *p; /* printing */ 801 else 802 *a = '.'; /* nonprinting, loose def */ 803 a++; 804 p++; 805 x--; 806 } /* while x */ 807 *a = '\n'; /* finish the line */ 808 x = write(ofd, stage, soc); 809 if (x < 0) 810 nlog(1, "ofd write err"); 811 } 812 } 813 814 #ifdef TELNET 815 u_short o_tn = 0; /* global -t option */ 816 817 /* 818 * atelnet : 819 * Answer anything that looks like telnet negotiation with don't/won't. 820 * This doesn't modify any data buffers, update the global output count, 821 * or show up in a hexdump -- it just shits into the outgoing stream. 822 * Idea and codebase from Mudge@l0pht.com. 823 */ 824 void 825 atelnet(buf, size) 826 unsigned char *buf; /* has to be unsigned here! */ 827 unsigned int size; 828 { 829 static unsigned char obuf[4]; /* tiny thing to build responses into */ 830 int x; 831 unsigned char y; 832 unsigned char *p; 833 834 y = 0; 835 p = buf; 836 x = size; 837 while (x > 0) { 838 if (*p != 255) /* IAC? */ 839 goto notiac; 840 obuf[0] = 255; 841 p++; 842 x--; 843 if ((*p == 251) || (*p == 252)) /* WILL or WONT */ 844 y = 254;/* -> DONT */ 845 if ((*p == 253) || (*p == 254)) /* DO or DONT */ 846 y = 252;/* -> WONT */ 847 if (y) { 848 obuf[1] = y; 849 p++; 850 x--; 851 obuf[2] = *p; 852 (void) write(netfd, obuf, 3); 853 /* 854 * if one wanted to bump wrote_net or do 855 * a hexdump line, here's the place. 856 */ 857 y = 0; 858 } 859 notiac: 860 p++; 861 x--; 862 } 863 } 864 #endif /* TELNET */ 865 866 /* 867 * readwrite : 868 * handle stdin/stdout/network I/O. Bwahaha!! -- the select loop from hell. 869 * In this instance, return what might become our exit status. 870 */ 871 int 872 readwrite(fd) 873 int fd; 874 { 875 int rr; 876 char *zp; /* stdin buf ptr */ 877 char *np; /* net-in buf ptr */ 878 unsigned int rzleft; 879 unsigned int rnleft; 880 u_short netretry; /* net-read retry counter */ 881 u_short wretry; /* net-write sanity counter */ 882 u_short wfirst; /* one-shot flag to skip first net read */ 883 884 /* 885 * if you don't have all this FD_* macro hair in sys/types.h, 886 * you'll have to either find it or do your own bit-bashing: 887 * *ds1 |= (1 << fd), etc. 888 */ 889 if (fd > FD_SETSIZE) { 890 nlog(0, "Preposterous fd value %d", fd); 891 return (1); 892 } 893 FD_SET(fd, &fds1); 894 netretry = 2; 895 wfirst = 0; 896 rzleft = rnleft = 0; 897 if (insaved) { 898 rzleft = insaved; /* preload multi-mode fakeouts */ 899 zp = bigbuf_in; 900 wfirst = 1; 901 /* If not scanning, this is a one-off first */ 902 if (Single) 903 insaved = 0; 904 else { 905 FD_CLR(0, &fds1); 906 close(0); 907 } 908 } 909 if (o_interval) 910 sleep(o_interval); 911 912 while (FD_ISSET(fd, &fds1)) { /* i.e. till the *net* closes! */ 913 struct timeval *tv; 914 915 wretry = 8200; /* more than we'll ever hafta write */ 916 if (wfirst) { /* any saved stdin buffer? */ 917 wfirst = 0; /* clear flag for the duration */ 918 goto shovel; /* and go handle it first */ 919 } 920 fds2 = fds1; 921 if (timer1.tv_sec > 0 || timer1.tv_usec > 0) { 922 memcpy(&timer2, &timer1, sizeof(struct timeval)); 923 tv = &timer2; 924 } else 925 tv = NULL; 926 rr = select(getdtablesize(), &fds2, 0, 0, tv); 927 if (rr < 0) { 928 if (errno != EINTR) { 929 nlog(0, "Select Failure"); 930 close(fd); 931 return (1); 932 } 933 } 934 /* if we have a timeout AND stdin is closed AND we haven't 935 * heard anything from the net during that time, assume it's 936 * dead and close it too. */ 937 if (rr == 0) { 938 if (!FD_ISSET(0, &fds1)) 939 netretry--; /* we actually try a coupla 940 * times. */ 941 if (!netretry) { 942 if (o_verbose > 1) /* normally we don't 943 * care */ 944 nlog(0, "net timeout"); 945 close(fd); 946 return (0); /* not an error! */ 947 } 948 } /* select timeout */ 949 /* XXX: should we check the exception fds too? The read fds 950 * seem to give us the right info, and none of the examples I 951 * found bothered. */ 952 /* Ding!! Something arrived, go check all the incoming 953 * hoppers, net first */ 954 if (FD_ISSET(fd, &fds2)) { /* net: ding! */ 955 rr = read(fd, bigbuf_net, BIGSIZ); 956 if (rr <= 0) { 957 FD_CLR(fd, &fds1); /* net closed, we'll 958 * finish up... */ 959 rzleft = 0; /* can't write anymore: broken 960 * pipe */ 961 } else { 962 rnleft = rr; 963 np = bigbuf_net; 964 #ifdef TELNET 965 if (o_tn) 966 atelnet(np, rr); /* fake out telnet stuff */ 967 #endif /* TELNET */ 968 } 969 } 970 /* if we're in "slowly" mode there's probably still stuff in 971 * the stdin buffer, so don't read unless we really need MORE 972 * INPUT! MORE INPUT! */ 973 if (rzleft) 974 goto shovel; 975 976 if (FD_ISSET(0, &fds2)) { 977 rr = read(0, bigbuf_in, BIGSIZ); 978 if (rr <= 0) { 979 FD_CLR(0, &fds1); /* disable and close */ 980 close(0); 981 } else { 982 rzleft = rr; 983 zp = bigbuf_in; 984 if (!Single) { 985 insaved = rr; 986 FD_CLR(0, &fds1); 987 close(0); 988 } 989 } 990 } 991 shovel: 992 /* sanity check. Works because they're both unsigned... */ 993 if ((rzleft > 8200) || (rnleft > 8200)) { 994 rzleft = rnleft = 0; 995 } 996 /* net write retries sometimes happen on UDP connections */ 997 if (!wretry) { /* is something hung? */ 998 nlog(0, "too many output retries"); 999 return (1); 1000 } 1001 if (rnleft) { 1002 rr = write(1, np, rnleft); 1003 if (rr > 0) { 1004 if (o_wfile) 1005 oprint(1, np, rr); 1006 np += rr; 1007 rnleft -= rr; 1008 wrote_out += rr; /* global count */ 1009 } 1010 } 1011 if (rzleft) { 1012 if (o_interval) 1013 rr = findline(zp, rzleft); 1014 else 1015 rr = rzleft; 1016 rr = write(fd, zp, rr); 1017 if (rr > 0) { 1018 if (o_wfile) 1019 oprint(0, zp, rr); 1020 zp += rr; 1021 rzleft -= rr; 1022 wrote_net += rr; 1023 } 1024 } 1025 if (o_interval) { 1026 sleep(o_interval); 1027 continue; 1028 } 1029 if ((rzleft) || (rnleft)) { 1030 wretry--; 1031 goto shovel; 1032 } 1033 } 1034 1035 close(fd); 1036 return (0); 1037 } 1038 1039 /* main : 1040 now we pull it all together... */ 1041 int 1042 main(argc, argv) 1043 int argc; 1044 char **argv; 1045 { 1046 int x, ch; 1047 char *cp; 1048 struct host_info *gp; 1049 struct host_info *whereto = NULL; 1050 struct host_info *wherefrom = NULL; 1051 struct in_addr *ouraddr = NULL; 1052 struct in_addr *themaddr = NULL; 1053 u_short o_lport = 0; 1054 u_short ourport = 0; 1055 u_short loport = 0; /* for scanning stuff */ 1056 u_short hiport = 0; 1057 u_short curport = 0; 1058 char *randports = NULL; 1059 1060 res_init(); 1061 1062 lclend = (struct sockaddr_in *) calloc(1, sizeof(struct sockaddr)); 1063 remend = (struct sockaddr_in *) calloc(1, sizeof(struct sockaddr)); 1064 bigbuf_in = calloc(1, BIGSIZ); 1065 bigbuf_net = calloc(1, BIGSIZ); 1066 pinfo= (struct port_info *) calloc(1, sizeof(struct port_info)); 1067 1068 gatesptr = 4; 1069 1070 /* 1071 * We want to catch a few of these signals. 1072 * Others we disgard. 1073 */ 1074 signal(SIGINT, catch); 1075 signal(SIGQUIT, catch); 1076 signal(SIGTERM, catch); 1077 signal(SIGURG, SIG_IGN); 1078 signal(SIGPIPE, SIG_IGN); /* important! */ 1079 1080 /* 1081 * If no args given at all, get 'em from stdin, construct an argv, 1082 * and hand anything left over to readwrite(). 1083 */ 1084 if (argc == 1) { 1085 /* Loop until we get a command to try */ 1086 for (;;) { 1087 cp = argv[0]; 1088 argv = (char **) calloc(1, 128 * sizeof(char *)); 1089 argv[0] = cp; /* leave old prog name intact */ 1090 cp = calloc(1, BIGSIZ); 1091 argv[1] = cp; /* head of new arg block */ 1092 fprintf(stderr, "Cmd line: "); 1093 fflush(stderr); /* I dont care if it's unbuffered or not! */ 1094 insaved = read(0, cp, BIGSIZ-1); /* we're gonna fake fgets() 1095 * here */ 1096 cp[BIGSIZ-1] = '\0'; 1097 if (*cp != '\n' && *cp != '\t') 1098 break; 1099 } 1100 if (insaved <= 0) 1101 nlog(1, "wrong"); 1102 x = findline(cp, insaved); 1103 if (x) 1104 insaved -= x; /* remaining chunk size to be sent */ 1105 if (insaved) /* which might be zero... */ 1106 memcpy(bigbuf_in, &cp[x], insaved); 1107 cp = strchr(argv[1], '\n'); 1108 if (cp) 1109 *cp = '\0'; 1110 cp = strchr(argv[1], '\r'); /* look for ^M too */ 1111 if (cp) 1112 *cp = '\0'; 1113 1114 /* 1115 * Find and stash pointers to remaining new "args" 1116 */ 1117 cp = argv[1]; 1118 cp++; /* skip past first char */ 1119 x = 2; /* we know argv 0 and 1 already */ 1120 for (; *cp != '\0'; cp++) { 1121 if (*cp == ' ') { 1122 *cp = '\0'; /* smash all spaces */ 1123 continue; 1124 } else { 1125 if (*(cp - 1) == '\0') { 1126 argv[x] = cp; 1127 x++; 1128 } 1129 } /* if space */ 1130 } /* for cp */ 1131 argc = x; 1132 } 1133 1134 while ((ch = getopt(argc, argv, "g:G:hi:lno:p:rs:tuvw:z")) != -1) { 1135 switch (ch) { 1136 case 'G': /* srcrt gateways pointer val */ 1137 x = atoi(optarg); 1138 /* Mask of bits */ 1139 if ((x) && (x == (x & 0x1c))) 1140 gatesptr = x; 1141 else 1142 nlog(1, "invalid hop pointer %d, must be multiple of 4 <= 28", x); 1143 break; 1144 case 'g': /* srcroute hop[s] */ 1145 if (gatesidx > 8) 1146 nlog(1, "Too many -g hops!"); 1147 if (gates == NULL) 1148 gates = (struct host_info **) calloc(1, 1149 sizeof(struct host_info *) * 10); 1150 gp = gethinfo(optarg, o_nflag); 1151 if (gp) 1152 gates[gatesidx] = gp; 1153 gatesidx++; 1154 break; 1155 case 'h': 1156 help(); 1157 break; 1158 case 'i': /* line-interval time */ 1159 o_interval = atoi(optarg) & 0xffff; 1160 if (!o_interval) 1161 nlog(1, "invalid interval time %s", optarg); 1162 break; 1163 case 'l': /* listen mode */ 1164 o_listen++; 1165 break; 1166 case 'n': /* numeric-only, no DNS lookups */ 1167 o_nflag++; 1168 break; 1169 case 'o': /* hexdump log */ 1170 stage = (unsigned char *) optarg; 1171 o_wfile++; 1172 break; 1173 case 'p': /* local source port */ 1174 o_lport = getpinfo(optarg, 0); 1175 if (o_lport == 0) 1176 nlog(1, "invalid local port %s", optarg); 1177 break; 1178 case 'r': /* randomize various things */ 1179 o_random++; 1180 break; 1181 /* 1182 * Do a full lookup [since everything else goes through the same 1183 * mill], unless -n was previously specified. In fact, careful 1184 * placement of -n can be useful, so we'll still pass o_nflag 1185 * here instead of forcing numeric. 1186 */ 1187 case 's': /* local source address */ 1188 wherefrom = gethinfo(optarg, o_nflag); 1189 ouraddr = &wherefrom->iaddrs[0]; 1190 break; 1191 #ifdef TELNET 1192 case 't': /* do telnet fakeout */ 1193 o_tn++; 1194 break; 1195 #endif 1196 case 'u': /* use UDP */ 1197 o_udpmode++; 1198 break; 1199 case 'v': /* verbose */ 1200 o_verbose++; 1201 break; 1202 case 'w': /* wait time */ 1203 o_wait = atoi(optarg); 1204 if (o_wait <= 0) 1205 nlog(1, "invalid wait-time %s", optarg); 1206 timer1.tv_sec = o_wait; 1207 timer1.tv_usec = 0; 1208 break; 1209 case 'z': /* little or no data xfer */ 1210 o_zero++; 1211 break; 1212 default: 1213 usage(1); 1214 } 1215 } 1216 1217 /* other misc initialization */ 1218 FD_SET(0, &fds1); /* stdin *is* initially open */ 1219 if (o_random) { 1220 randports = calloc(1, 65536); /* big flag array for ports */ 1221 } 1222 if (o_wfile) { 1223 ofd = open(stage, O_WRONLY | O_CREAT | O_TRUNC, 0664); 1224 if (ofd <= 0) /* must be > extant 0/1/2 */ 1225 nlog(1, "%s: ", stage); 1226 stage = (unsigned char *) calloc(1, 100); 1227 } 1228 /* optind is now index of first non -x arg */ 1229 if (argv[optind]) 1230 whereto = gethinfo(argv[optind], o_nflag); 1231 if (whereto && whereto->iaddrs) 1232 themaddr = &whereto->iaddrs[0]; 1233 if (themaddr) 1234 optind++; /* skip past valid host lookup */ 1235 1236 /* 1237 * Handle listen mode here, and exit afterward. Only does one connect; 1238 * this is arguably the right thing to do. A "persistent listen-and-fork" 1239 * mode a la inetd has been thought about, but not implemented. A tiny 1240 * wrapper script can handle such things. 1241 */ 1242 if (o_listen) { 1243 curport = 0; 1244 if (argv[optind]) { 1245 curport = getpinfo(argv[optind], 0); 1246 if (curport == 0) 1247 nlog(1, "invalid port %s", argv[optind]); 1248 } 1249 netfd = dolisten(themaddr, curport, ouraddr, o_lport); 1250 if (netfd > 0) { 1251 x = readwrite(netfd); 1252 if (o_verbose) 1253 nlog(0, "Sent %i Rcvd %i", wrote_net, wrote_out); 1254 exit(x); 1255 } else 1256 nlog(1, "no connection"); 1257 } 1258 /* fall thru to outbound connects. Now we're more picky about args... */ 1259 if (!themaddr) 1260 nlog(1, "no destination"); 1261 if (argv[optind] == NULL) 1262 nlog(1, "no port[s] to connect to"); 1263 if (argv[optind + 1]) 1264 Single = 0; 1265 ourport = o_lport; 1266 1267 while (argv[optind]) { 1268 hiport = loport = 0; 1269 if (cp = strchr(argv[optind], '-')) { 1270 *cp = '\0'; 1271 cp++; 1272 hiport = getpinfo(cp, 0); 1273 if (hiport == 0) 1274 nlog(1, "invalid port %s", cp); 1275 } 1276 loport = getpinfo(argv[optind], 0); 1277 if (loport == 0) 1278 nlog(1, "invalid port %s", argv[optind]); 1279 if (hiport > loport) { 1280 Single = 0; 1281 if (o_random) { 1282 loadports(randports, loport, hiport); 1283 curport = nextport(randports); 1284 } else 1285 curport = hiport; 1286 } else 1287 curport = loport; 1288 /* 1289 * Now start connecting to these things. 1290 * curport is already preloaded. 1291 */ 1292 while (loport <= curport) { 1293 curport = getpinfo(NULL, curport); 1294 netfd = doconnect(themaddr, curport, ouraddr, ourport); 1295 if (netfd > 0) 1296 if (o_zero && o_udpmode) 1297 netfd = udptest(netfd, themaddr); 1298 if (netfd > 0) { 1299 x = errno = 0; 1300 if (o_verbose) { 1301 nlog(0, "%s [%s] %d (%s) open", 1302 whereto->name, 1303 whereto->addrs[0], curport, 1304 pinfo->name); 1305 } 1306 if (!o_zero) 1307 x = readwrite(netfd); 1308 } else { 1309 x = 1; 1310 if ((Single || (o_verbose > 1)) 1311 || (errno != ECONNREFUSED)) { 1312 nlog(0, "%s [%s] %d (%s)", 1313 whereto->name, whereto->addrs[0], 1314 curport, pinfo->name); 1315 } 1316 } 1317 close(netfd); 1318 if (o_interval) 1319 sleep(o_interval); 1320 if (o_random) 1321 curport = nextport(randports); 1322 else 1323 curport--; 1324 } 1325 optind++; 1326 } 1327 errno = 0; 1328 if (o_verbose > 1) 1329 nlog(0, "Sent %i Rcvd %i", wrote_net, wrote_out); 1330 if (Single) 1331 exit(x); 1332 exit(0); 1333 } 1334 1335 /* 1336 * nlog: 1337 * dual purpose function, does both warn() and err() 1338 * and pays attention to o_verbose. 1339 */ 1340 void 1341 nlog(doexit, fmt) 1342 int doexit; 1343 char *fmt; 1344 { 1345 va_list args; 1346 1347 if (o_verbose || doexit) { 1348 va_start(args, fmt); 1349 vfprintf(stderr, fmt, args); 1350 if (h_errno) 1351 herror(NULL); 1352 else if (errno) 1353 fprintf(stderr, "%s\n", strerror(errno)); 1354 else 1355 putc('\n', stderr); 1356 va_end(args); 1357 } 1358 1359 if (doexit) 1360 exit(1); 1361 1362 h_errno = errno = 0; 1363 } 1364 1365 void 1366 usage(doexit) 1367 int doexit; 1368 { 1369 fprintf(stderr, "netcat - [v1.10]\n"); 1370 fprintf(stderr, "nc [-lnrtuvz] [-e command] [-g intermediates]\n"); 1371 fprintf(stderr, " [-G hopcount] [-i interval] [-o filename] [-p source port]\n"); 1372 fprintf(stderr, " [-s ip address] [-w timeout] [hostname] [port[s...]]\n"); 1373 if (doexit) 1374 exit(1); 1375 } 1376 1377 void 1378 help() 1379 { 1380 usage(0); 1381 fprintf(stderr, "\tCommand Summary:\n\ 1382 \t-g gateway source-routing hop point[s], up to 8\n\ 1383 \t-G num\t source-routing pointer: 4, 8, 12, ...\n\ 1384 \t-h this help text\n\ 1385 \t-i secs\t delay interval for lines sent, ports scanned\n\ 1386 \t-l listen mode, for inbound connects\n\ 1387 \t-n numeric-only IP addresses, no DNS\n\ 1388 \t-o file\t hex dump of traffic\n\ 1389 \t-r randomize local and remote ports\n\ 1390 \t-s addr\t local source address\n"); 1391 #ifdef TELNET 1392 fprintf(stderr, "\t\t-t answer TELNET negotiation\n"); 1393 #endif 1394 fprintf(stderr, "\t\t-u UDP mode\n\ 1395 \t-v verbose [use twice to be more verbose]\n\ 1396 \t-w secs\t timeout for connects and final net reads\n\ 1397 \t-z zero-I/O mode [used for scanning]\n\ 1398 Port numbers can be individual or ranges: lo-hi [inclusive]\n"); 1399 exit(1); 1400 } 1401