netcat.c (67756B)
1 // for license see license.txt 2 3 /* Netcat 1.00 951010 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 main: 22 23 todo: 24 more of the portability swamp, and an updated generic.h 25 frontend progs to generate various packets, raw or otherwise... 26 char-mode [cbreak, fcntl-unbuffered, etc...] 27 connect-to-all-A-records hack 28 bluesky: 29 RAW mode! 30 backend progs to grab a pty and look like a real telnetd?! 31 */ 32 33 #include "generic.h" /* same as with L5, skey, etc */ 34 35 #ifdef WIN32 36 #pragma comment (lib, "ws2_32") /* winsock support */ 37 #endif 38 39 /* conditional includes -- a very messy section: */ 40 /* #undef _POSIX_SOURCE /* might need this for something? */ 41 #define HAVE_BIND /* XXX -- for now, see below... */ 42 #define HAVE_HELP /* undefine if you dont want the help text */ 43 /* #define ANAL /* if you want case-sensitive DNS matching */ 44 #ifdef HAVE_STDLIB_H 45 #include <stdlib.h> 46 #else 47 #include <malloc.h> /* xxx: or does it live in sys/ ?? */ 48 #endif 49 50 /* have to do this *before* including types.h. xxx: Linux still has it wrong */ 51 #ifdef FD_SETSIZE /* should be in types.h, butcha never know. */ 52 #undef FD_SETSIZE /* if we ever need more than 16 active */ 53 #endif /* fd's, something is horribly wrong! */ 54 #ifdef WIN32 55 #define FD_SETSIZE 64 /* WIN32 does this as an array not a bitfield and it likes 64 */ 56 #else 57 #define FD_SETSIZE 16 /* <-- this'll give us a long anyways, wtf */ 58 #endif 59 #include <sys/types.h> /* *now* do it. Sigh, this is broken */ 60 61 62 #ifdef WIN32 63 #undef HAVE_RANDOM 64 #undef IP_OPTIONS 65 #undef SO_REUSEPORT 66 #include <windows.h> 67 #endif 68 69 70 #ifdef HAVE_RANDOM 71 #define SRAND srandom 72 #define RAND random 73 #else 74 #define SRAND srand 75 #define RAND rand 76 #endif /* HAVE_RANDOM */ 77 78 /* xxx: these are rsh leftovers, move to new generic.h */ 79 /* will we even need any nonblocking shit? Doubt it. */ 80 /* get FIONBIO from sys/filio.h, so what if it is a compatibility feature */ 81 /* #include <sys/filio.h> */ 82 /* 83 #include <sys/ioctl.h> 84 #include <sys/file.h> 85 */ 86 87 /* includes: */ 88 89 #ifdef WIN32 90 #include "getopt.h" 91 #define sleep _sleep 92 #define strcasecmp strcmpi 93 #define EADDRINUSE WSAEADDRINUSE 94 #define ETIMEDOUT WSAETIMEDOUT 95 #define ECONNREFUSED WSAECONNREFUSED 96 #endif 97 98 #ifndef WIN32 99 #include <sys/time.h> /* timeval, time_t */ 100 #else 101 #include <time.h> 102 #endif 103 104 #include <setjmp.h> /* jmp_buf et al */ 105 106 #ifndef WIN32 107 #include <sys/socket.h> /* basics, SO_ and AF_ defs, sockaddr, ... */ 108 #include <netinet/in.h> /* sockaddr_in, htons, in_addr */ 109 #include <netinet/in_systm.h> /* misc crud that netinet/ip.h references */ 110 #include <netinet/ip.h> /* IPOPT_LSRR, header stuff */ 111 #include <netdb.h> /* hostent, gethostby*, getservby* */ 112 #include <arpa/inet.h> /* inet_ntoa */ 113 #else 114 #include <fcntl.h> 115 #include <io.h> 116 #include <conio.h> 117 //#include <winsock2.h> 118 #endif 119 120 #include <stdio.h> 121 #include <string.h> /* strcpy, strchr, yadda yadda */ 122 #include <errno.h> 123 #include <signal.h> 124 125 /* handy stuff: */ 126 #define SA struct sockaddr /* socket overgeneralization braindeath */ 127 #define SAI struct sockaddr_in /* ... whoever came up with this model */ 128 #define IA struct in_addr /* ... should be taken out and shot, */ 129 /* ... not that TLI is any better. sigh.. */ 130 #define SLEAZE_PORT 31337 /* for UDP-scan RTT trick, change if ya want */ 131 #define USHORT unsigned short /* use these for options an' stuff */ 132 #define BIGSIZ 8192 /* big buffers */ 133 #define SMALLSIZ 256 /* small buffers, hostnames, etc */ 134 135 #ifndef INADDR_NONE 136 #define INADDR_NONE 0xffffffff 137 #endif 138 #ifdef MAXHOSTNAMELEN 139 #undef MAXHOSTNAMELEN /* might be too small on aix, so fix it */ 140 #endif 141 #define MAXHOSTNAMELEN 256 142 struct host_poop { 143 char name[MAXHOSTNAMELEN]; /* dns name */ 144 char addrs[8][24]; /* ascii-format IP addresses */ 145 struct in_addr iaddrs[8]; /* real addresses: in_addr.s_addr: ulong */ 146 }; 147 #define HINF struct host_poop 148 struct port_poop { 149 char name [64]; /* name in /etc/services */ 150 char anum [8]; /* ascii-format number */ 151 USHORT num; /* real host-order number */ 152 }; 153 #define PINF struct port_poop 154 155 /* globals: */ 156 jmp_buf jbuf; /* timer crud */ 157 int jval = 0; /* timer crud */ 158 int netfd = -1; 159 int ofd = 0; /* hexdump output fd */ 160 static char unknown[] = "(UNKNOWN)"; 161 static char p_tcp[] = "tcp"; /* for getservby* */ 162 static char p_udp[] = "udp"; 163 164 #ifndef WIN32 165 #ifdef HAVE_BIND 166 extern int h_errno; 167 #endif 168 #endif 169 int gatesidx = 0; /* LSRR hop count */ 170 int gatesptr = 4; /* initial LSRR pointer, settable */ 171 USHORT Single = 1; /* zero if scanning */ 172 unsigned int insaved = 0; /* stdin-buffer size for multi-mode */ 173 unsigned int wrote_out = 0; /* total stdout bytes */ 174 unsigned int wrote_net = 0; /* total net bytes */ 175 static char wrote_txt[] = " sent %d, rcvd %d"; 176 static char hexnibs[20] = "0123456789abcdef "; 177 178 /* will malloc up the following globals: */ 179 struct timeval * timer1 = NULL; 180 struct timeval * timer2 = NULL; 181 SAI * lclend = NULL; /* sockaddr_in structs */ 182 SAI * remend = NULL; 183 HINF ** gates = NULL; /* LSRR hop hostpoop */ 184 char * optbuf = NULL; /* LSRR or sockopts */ 185 char * bigbuf_in; /* data buffers */ 186 char * bigbuf_net; 187 fd_set * ding1; /* for select loop */ 188 fd_set * ding2; 189 PINF * portpoop = NULL; /* for getportpoop / getservby* */ 190 unsigned char * stage = NULL; /* hexdump line buffer */ 191 192 #ifdef WIN32 193 char * setsockopt_c; 194 int nnetfd; 195 #endif 196 197 /* global cmd flags: */ 198 USHORT o_alla = 0; 199 unsigned int o_interval = 0; 200 USHORT o_listen = 0; 201 USHORT o_nflag = 0; 202 USHORT o_wfile = 0; 203 USHORT o_random = 0; 204 USHORT o_udpmode = 0; 205 USHORT o_verbose = 0; 206 unsigned int o_wait = 0; 207 USHORT o_zero = 0; 208 USHORT o_crlf = 0; 209 210 /* Debug macro: squirt whatever to stderr and sleep a bit so we can see it go 211 by. need to call like Debug ((stuff)) [with no ; ] so macro args match! 212 Beware: writes to stdOUT... */ 213 #ifdef DEBUG 214 #define Debug(x) printf x; printf ("\n"); fflush (stdout); sleep (1); 215 #else 216 #define Debug(x) /* nil... */ 217 #endif 218 219 /* support routines -- the bulk of this thing. Placed in such an order that 220 we don't have to forward-declare anything: */ 221 222 int helpme(); /* oop */ 223 224 #ifdef WIN32 225 226 /* res_init 227 winsock needs to be initialized. Might as well do it as the res_init 228 call for Win32 */ 229 230 void res_init() 231 { 232 WORD wVersionRequested; 233 WSADATA wsaData; 234 int err; 235 wVersionRequested = MAKEWORD(1, 1); 236 237 err = WSAStartup(wVersionRequested, &wsaData); 238 239 if (err != 0) 240 /* Tell the user that we couldn't find a useable */ 241 /* winsock.dll. */ 242 return; 243 244 /* Confirm that the Windows Sockets DLL supports 1.1.*/ 245 /* Note that if the DLL supports versions greater */ 246 /* than 1.1 in addition to 1.1, it will still return */ 247 /* 1.1 in wVersion since that is the version we */ 248 /* requested. */ 249 250 if ( LOBYTE( wsaData.wVersion ) != 1 || 251 HIBYTE( wsaData.wVersion ) != 1 ) { 252 /* Tell the user that we couldn't find a useable */ 253 /* winsock.dll. */ 254 WSACleanup(); 255 return; 256 } 257 258 } 259 260 261 262 263 /* winsockstr 264 Windows Sockets cannot report errors through perror() so we need to define 265 our own error strings to print. Someday all the string should be prettied up. 266 Prettied the errors I usually get */ 267 char * winsockstr(error) 268 int error; 269 { 270 switch (error) 271 { 272 case WSAEINTR : return("INTR "); 273 case WSAEBADF : return("BADF "); 274 case WSAEACCES : return("ACCES "); 275 case WSAEFAULT : return("FAULT "); 276 case WSAEINVAL : return("INVAL "); 277 case WSAEMFILE : return("MFILE "); 278 case WSAEWOULDBLOCK : return("WOULDBLOCK "); 279 case WSAEINPROGRESS : return("INPROGRESS "); 280 case WSAEALREADY : return("ALREADY "); 281 case WSAENOTSOCK : return("NOTSOCK "); 282 case WSAEDESTADDRREQ : return("DESTADDRREQ "); 283 case WSAEMSGSIZE : return("MSGSIZE "); 284 case WSAEPROTOTYPE : return("PROTOTYPE "); 285 case WSAENOPROTOOPT : return("NOPROTOOPT "); 286 case WSAEPROTONOSUPPORT: return("PROTONOSUPPORT"); 287 case WSAESOCKTNOSUPPORT: return("SOCKTNOSUPPORT"); 288 case WSAEOPNOTSUPP : return("OPNOTSUPP "); 289 case WSAEPFNOSUPPORT : return("PFNOSUPPORT "); 290 case WSAEAFNOSUPPORT : return("AFNOSUPPORT "); 291 case WSAEADDRINUSE : return("ADDRINUSE "); 292 case WSAEADDRNOTAVAIL : return("ADDRNOTAVAIL "); 293 case WSAENETDOWN : return("NETDOWN "); 294 case WSAENETUNREACH : return("NETUNREACH "); 295 case WSAENETRESET : return("NETRESET "); 296 case WSAECONNABORTED : return("CONNABORTED "); 297 case WSAECONNRESET : return("CONNRESET "); 298 case WSAENOBUFS : return("NOBUFS "); 299 case WSAEISCONN : return("ISCONN "); 300 case WSAENOTCONN : return("NOTCONN "); 301 case WSAESHUTDOWN : return("SHUTDOWN "); 302 case WSAETOOMANYREFS : return("TOOMANYREFS "); 303 case WSAETIMEDOUT : return("TIMEDOUT "); 304 case WSAECONNREFUSED : return("connection refused"); 305 case WSAELOOP : return("LOOP "); 306 case WSAENAMETOOLONG : return("NAMETOOLONG "); 307 case WSAEHOSTDOWN : return("HOSTDOWN "); 308 case WSAEHOSTUNREACH : return("HOSTUNREACH "); 309 case WSAENOTEMPTY : return("NOTEMPTY "); 310 case WSAEPROCLIM : return("PROCLIM "); 311 case WSAEUSERS : return("USERS "); 312 case WSAEDQUOT : return("DQUOT "); 313 case WSAESTALE : return("STALE "); 314 case WSAEREMOTE : return("REMOTE "); 315 case WSAEDISCON : return("DISCON "); 316 case WSASYSNOTREADY : return("SYSNOTREADY "); 317 case WSAVERNOTSUPPORTED: return("VERNOTSUPPORTED"); 318 case WSANOTINITIALISED : return("NOTINITIALISED "); 319 case WSAHOST_NOT_FOUND : return("HOST_NOT_FOUND "); 320 case WSATRY_AGAIN : return("TRY_AGAIN "); 321 case WSANO_RECOVERY : return("NO_RECOVERY "); 322 case WSANO_DATA : return("NO_DATA "); 323 default : return("unknown socket error"); 324 } 325 } 326 #endif 327 328 329 330 331 332 /* holler : 333 fake varargs -- need to do this way because we wind up calling through 334 more levels of indirection than vanilla varargs can handle, and not all 335 machines have vfprintf/vsyslog/whatever! 6 params oughta be enough. */ 336 void holler (str, p1, p2, p3, p4, p5, p6) 337 char * str; 338 char * p1, * p2, * p3, * p4, * p5, * p6; 339 { 340 if (o_verbose) { 341 fprintf (stderr, str, p1, p2, p3, p4, p5, p6); 342 #ifdef WIN32 343 if (h_errno) 344 fprintf (stderr, ": %s\n",winsockstr(h_errno)); 345 #else 346 if (errno) { /* this gives funny-looking messages, but */ 347 perror (" "); /* it's more portable than sys_errlist[]... */ 348 } /* xxx: do something better. */ 349 #endif 350 else 351 fprintf (stderr, "\n"); 352 fflush (stderr); 353 } 354 } /* holler */ 355 356 /* bail : 357 error-exit handler, callable from anywhere */ 358 void bail (str, p1, p2, p3, p4, p5, p6) 359 char * str; 360 char * p1, * p2, * p3, * p4, * p5, * p6; 361 { 362 o_verbose = 1; 363 holler (str, p1, p2, p3, p4, p5, p6); 364 #ifdef WIN32 365 shutdown(netfd, 0x02); /* Kirby */ 366 closesocket (netfd); 367 #else 368 close (netfd); 369 #endif 370 sleep (1); 371 exit (1); 372 } /* bail */ 373 374 /* catch : 375 no-brainer interrupt handler */ 376 void catch () 377 { 378 errno = 0; 379 if (o_verbose > 1) /* normally we don't care */ 380 bail (wrote_txt, wrote_net, wrote_out); 381 382 bail (" punt!"); 383 } 384 385 /* timeout and other signal handling cruft */ 386 void tmtravel () 387 { 388 #ifdef NTFIXTHIS 389 signal (SIGALRM, SIG_IGN); 390 alarm (0); 391 #endif 392 if (jval == 0) 393 bail ("spurious timer interrupt!"); 394 longjmp (jbuf, jval); 395 } 396 397 398 399 UINT theTimer; 400 401 /* arm : 402 set the timer. Zero secs arg means unarm */ 403 void arm (num, secs) 404 unsigned int num; 405 unsigned int secs; 406 { 407 408 #ifdef WIN32 409 HANDLE stdhnd; 410 stdhnd = GetStdHandle(STD_OUTPUT_HANDLE); 411 #ifdef DEBUG 412 if (stdhnd != INVALID_HANDLE_VALUE) 413 printf("handle is %ld\n", stdhnd); 414 else 415 printf("failed to get stdhndl\n"); 416 #endif 417 #else 418 if (secs == 0) { /* reset */ 419 signal (SIGALRM, SIG_IGN); 420 alarm (0); 421 jval = 0; 422 } else { /* set */ 423 signal (SIGALRM, tmtravel); 424 alarm (secs); 425 jval = num; 426 } /* if secs */ 427 #endif /* WIN32 */ 428 } /* arm */ 429 430 /* Hmalloc : 431 malloc up what I want, rounded up to *4, and pre-zeroed. Either succeeds 432 or bails out on its own, so that callers don't have to worry about it. */ 433 char * Hmalloc (size) 434 unsigned int size; 435 { 436 unsigned int s = (size + 4) & 0xfffffffc; /* 4GB?! */ 437 char * p = malloc (s); 438 if (p != NULL) 439 memset (p, 0, s); 440 else 441 bail ("Hmalloc %d failed", s); 442 return (p); 443 } /* Hmalloc */ 444 445 /* findline : 446 find the next newline in a buffer; return inclusive size of that "line", 447 or the entire buffer size, so the caller knows how much to then write(). 448 Not distinguishing \n vs \r\n for the nonce; it just works as is... */ 449 unsigned int findline (buf, siz) 450 char * buf; 451 unsigned int siz; 452 { 453 register char * p; 454 register int x; 455 if (! buf) /* various sanity checks... */ 456 return (0); 457 if (siz > BIGSIZ) 458 return (0); 459 x = siz; 460 for (p = buf; x > 0; x--) { 461 if (*p == '\n') { 462 x = (int) (p - buf); 463 x++; /* 'sokay if it points just past the end! */ 464 Debug (("findline returning %d", x)) 465 return (x); 466 } 467 p++; 468 } /* for */ 469 Debug (("findline returning whole thing: %d", siz)) 470 return (siz); 471 } /* findline */ 472 473 /* comparehosts : 474 cross-check the host_poop we have so far against new gethostby*() info, 475 and holler about mismatches. Perhaps gratuitous, but it can't hurt to 476 point out when someone's DNS is fukt. Returns 1 if mismatch, in case 477 someone else wants to do something about it. */ 478 int comparehosts (poop, hp) 479 HINF * poop; 480 struct hostent * hp; 481 { 482 errno = 0; 483 #ifndef WIN32 484 h_errno = 0; 485 #endif 486 /* The DNS spec is officially case-insensitive, but for those times when you 487 *really* wanna see any and all discrepancies, by all means define this. */ 488 #ifdef ANAL 489 if (strcmp (poop->name, hp->h_name) != 0) { /* case-sensitive */ 490 #else 491 if (strcasecmp (poop->name, hp->h_name) != 0) { /* normal */ 492 #endif 493 holler ("DNS fwd/rev mismatch: %s != %s", poop->name, hp->h_name); 494 return (1); 495 } 496 return (0); 497 /* ... do we need to do anything over and above that?? */ 498 } /* comparehosts */ 499 500 /* gethostpoop : 501 resolve a host 8 ways from sunday; return a new host_poop struct with its 502 info. The argument can be a name or [ascii] IP address; it will try its 503 damndest to deal with it. "numeric" governs whether we do any DNS at all, 504 and we also check o_verbose for what's appropriate work to do. */ 505 HINF * gethostpoop (name, numeric) 506 char * name; 507 USHORT numeric; 508 { 509 struct hostent * hostent; 510 struct in_addr iaddr; 511 register HINF * poop = NULL; 512 register int x; 513 514 /* I really want to strangle the twit who dreamed up all these sockaddr and 515 hostent abstractions, and then forced them all to be incompatible with 516 each other so you *HAVE* to do all this ridiculous casting back and forth. 517 If that wasn't bad enough, all the doc insists on referring to local ports 518 and addresses as "names", which makes NO sense down at the bare metal. 519 520 What an absolutely horrid paradigm, and to think of all the people who 521 have been wasting significant amounts of time fighting with this stupid 522 deliberate obfuscation over the last 10 years... then again, I like 523 languages wherein a pointer is a pointer, what you put there is your own 524 business, the compiler stays out of your face, and sheep are nervous. 525 Maybe that's why my C code reads like assembler half the time... */ 526 527 /* If we want to see all the DNS stuff, do the following hair -- 528 if inet_addr, do reverse and forward with any warnings; otherwise try 529 to do forward and reverse with any warnings. In other words, as long 530 as we're here, do a complete DNS check on these clowns. Yes, it slows 531 things down a bit for a first run, but once it's cached, who cares? */ 532 533 errno = 0; 534 #ifndef WIN32 535 h_errno = 0; 536 #endif 537 if (name) 538 poop = (HINF *) Hmalloc (sizeof (HINF)); 539 if (! poop) 540 bail ("gethostpoop fuxored"); 541 strcpy (poop->name, unknown); /* preload it */ 542 /* see wzv:workarounds.c for dg/ux return-a-struct inet_addr lossage */ 543 iaddr.s_addr = inet_addr (name); 544 545 if (iaddr.s_addr == INADDR_NONE) { /* here's the great split: names... */ 546 if (numeric) 547 bail ("Can't parse %s as an IP address", name); 548 hostent = gethostbyname (name); 549 if (! hostent) 550 /* failure to look up a name is fatal, since we can't do anything with it */ 551 /* XXX: h_errno only if BIND? look up how telnet deals with this */ 552 bail ("%s: forward host lookup failed: h_errno %d", name, h_errno); 553 strncpy (poop->name, hostent->h_name, sizeof (poop->name)); 554 for (x = 0; hostent->h_addr_list[x] && (x < 8); x++) { 555 memcpy (&poop->iaddrs[x], hostent->h_addr_list[x], sizeof (IA)); 556 strncpy (poop->addrs[x], inet_ntoa (poop->iaddrs[x]), 557 sizeof (poop->addrs[0])); 558 } /* for x -> addrs, part A */ 559 if (! o_verbose) /* if we didn't want to see the */ 560 return (poop); /* inverse stuff, we're done. */ 561 /* do inverse lookups in separate loop based on our collected forward addrs, 562 since gethostby* tends to crap into the same buffer over and over */ 563 for (x = 0; poop->iaddrs[x].s_addr && (x < 8); x++) { 564 hostent = gethostbyaddr ((char *)&poop->iaddrs[x], 565 sizeof (IA), AF_INET); 566 if ((! hostent) || (! hostent-> h_name)) 567 holler ("Warning: inverse host lookup failed for %s: h_errno %d", 568 poop->addrs[x], h_errno); 569 else 570 (void) comparehosts (poop, hostent); 571 } /* for x -> addrs, part B */ 572 573 } else { /* not INADDR_NONE: numeric addresses... */ 574 memcpy (poop->iaddrs, &iaddr, sizeof (IA)); 575 strncpy (poop->addrs[0], inet_ntoa (iaddr), sizeof (poop->addrs)); 576 if (numeric) /* if numeric-only, we're done */ 577 return (poop); 578 if (! o_verbose) /* likewise if we don't want */ 579 return (poop); /* the full DNS hair */ 580 hostent = gethostbyaddr ((char *) &iaddr, sizeof (IA), AF_INET); 581 /* numeric or not, failure to look up a PTR is *not* considered fatal */ 582 if (! hostent) 583 holler ("%s: inverse host lookup failed: h_errno %d", name, h_errno); 584 else { 585 strncpy (poop->name, hostent->h_name, MAXHOSTNAMELEN - 2); 586 hostent = gethostbyname (poop->name); 587 if ((! hostent) || (! hostent->h_addr_list[0])) 588 holler ("Warning: forward host lookup failed for %s: h_errno %d", 589 poop->name, h_errno); 590 else 591 (void) comparehosts (poop, hostent); 592 } /* if hostent */ 593 } /* INADDR_NONE Great Split */ 594 595 /* whatever-all went down previously, we should now have a host_poop struct 596 with at least one IP address in it. */ 597 #ifndef WIN32 598 h_errno = 0; 599 #endif 600 return (poop); 601 } /* gethostpoop */ 602 603 /* getportpoop : 604 Same general idea as gethostpoop -- look up a port in /etc/services, fill 605 in global port_poop, but return the actual port *number*. Pass ONE of: 606 pstring to resolve stuff like "23" or "exec"; 607 pnum to reverse-resolve something that's already a number. 608 If o_nflag is on, fill in what we can but skip the getservby??? stuff. 609 Might as well have consistent behavior here... */ 610 USHORT getportpoop (pstring, pnum) 611 char * pstring; 612 unsigned int pnum; 613 { 614 struct servent * servent; 615 #ifndef WIN32 616 register int x; 617 register int y; 618 #else 619 u_short x; 620 u_short y; 621 #endif 622 char * whichp = p_tcp; 623 if (o_udpmode) 624 whichp = p_udp; 625 portpoop->name[0] = '?'; /* fast preload */ 626 portpoop->name[1] = '\0'; 627 628 /* case 1: reverse-lookup of a number; placed first since this case is much 629 more frequent if we're scanning */ 630 if (pnum) { 631 if (pstring) /* one or the other, pleeze */ 632 return (0); 633 x = pnum; 634 if (o_nflag) /* go faster, skip getservbyblah */ 635 goto gp_finish; 636 y = htons (x); /* gotta do this -- see Fig.1 below */ 637 servent = getservbyport (y, whichp); 638 if (servent) { 639 y = ntohs (servent->s_port); 640 if (x != y) /* "never happen" */ 641 holler ("Warning: port-bynum mismatch, %d != %d", x, y); 642 strncpy (portpoop->name, servent->s_name, sizeof (portpoop->name)); 643 } /* if servent */ 644 goto gp_finish; 645 } /* if pnum */ 646 647 /* case 2: resolve a string, but we still give preference to numbers instead 648 of trying to resolve conflicts. None of the entries in *my* extensive 649 /etc/services begins with a digit, so this should "always work" unless 650 you're at 3com and have some company-internal services defined... */ 651 if (pstring) { 652 if (pnum) /* one or the other, pleeze */ 653 return (0); 654 x = atoi (pstring); 655 if (x) 656 return (getportpoop (NULL, x)); /* recurse for numeric-string-arg */ 657 if (o_nflag) /* can't use names! */ 658 return (0); 659 servent = getservbyname (pstring, whichp); 660 if (servent) { 661 strncpy (portpoop->name, servent->s_name, sizeof (portpoop->name)); 662 x = ntohs (servent->s_port); 663 goto gp_finish; 664 } /* if servent */ 665 } /* if pstring */ 666 667 return (0); /* catches any problems so far */ 668 669 /* Obligatory netdb.h-inspired rant: servent.s_port is supposed to be an int. 670 Despite this, we still have to treat it as a short when copying it around. 671 Not only that, but we have to convert it *back* into net order for 672 getservbyport to work. Manpages generally aren't clear on all this, but 673 there are plenty of examples in which it is just quietly done. More BSD 674 lossage... since everything getserv* ever deals with is local to our own 675 host, why bother with all this network-order/host-order crap at all?! 676 That should be saved for when we want to actually plug the port[s] into 677 some real network calls -- and guess what, we have to *re*-convert at that 678 point as well. Fuckheads. */ 679 680 gp_finish: 681 /* Fall here whether or not we have a valid servent at this point, with 682 x containing our [host-order and therefore useful, dammit] port number */ 683 sprintf (portpoop->anum, "%d", x); /* always load any numeric specs! */ 684 portpoop->num = (x & 0xffff); /* ushort, remember... */ 685 return (portpoop->num); 686 } /* getportpoop */ 687 688 /* nextport : 689 Come up with the next port to try, be it random or whatever. "block" is 690 a ptr to randports array, whose bytes [so far] carry these meanings: 691 0 ignore 692 1 to be tested 693 2 tested [which is set as we find them here] 694 returns a USHORT random port, or 0 if all the t-b-t ones are used up. */ 695 USHORT nextport (block) 696 char * block; 697 { 698 register unsigned int x; 699 register unsigned int y; 700 701 y = 70000; /* high safety count for rnd-tries */ 702 while (y > 0) { 703 x = (RAND() & 0xffff); 704 if (block[x] == 1) { /* try to find a not-done one... */ 705 block[x] = 2; 706 break; 707 } 708 x = 0; /* bummer. */ 709 y--; 710 } /* while y */ 711 if (x) 712 return (x); 713 714 y = 65535; /* no random one, try linear downsearch */ 715 while (y > 0) { /* if they're all used, we *must* be sure! */ 716 if (block[y] == 1) { 717 block[y] = 2; 718 break; 719 } 720 y--; 721 } /* while y */ 722 if (y) 723 return (y); /* at least one left */ 724 725 return (0); /* no more left! */ 726 } /* nextport */ 727 728 /* loadports : 729 set "to be tested" indications in BLOCK, from LO to HI. Almost too small 730 to be a separate routine, but makes main() a little cleaner... */ 731 void loadports (block, lo, hi) 732 char * block; 733 USHORT lo; 734 USHORT hi; 735 { 736 USHORT x; 737 738 if (! block) 739 bail ("loadports: no block?!"); 740 if ((! lo) || (! hi)) 741 bail ("loadports: bogus values %d, %d", lo, hi); 742 x = hi; 743 while (lo <= x) { 744 block[x] = 1; 745 x--; 746 } 747 } /* loadports */ 748 749 #ifdef GAPING_SECURITY_HOLE 750 char * pr00gie = NULL; /* global ptr to -e arg */ 751 #ifdef WIN32 752 BOOL doexec(SOCKET ClientSocket); // this is in doexec.c 753 #else 754 755 /* doexec : 756 fiddle all the file descriptors around, and hand off to another prog. Sort 757 of like a one-off "poor man's inetd". This is the only section of code 758 that would be security-critical, which is why it's ifdefed out by default. 759 Use at your own hairy risk; if you leave shells lying around behind open 760 listening ports you deserve to lose!! */ 761 doexec (fd) 762 int fd; 763 { 764 register char * p; 765 766 dup2 (fd, 0); /* the precise order of fiddlage */ 767 #ifdef WIN32 768 shutdown(fd, SD_BOTH); /* Kirby */ 769 closesocket (fd); 770 #else 771 close (fd); /* is apparently crucial; this is */ 772 #endif 773 dup2 (0, 1); /* swiped directly out of "inetd". */ 774 dup2 (0, 2); 775 p = strrchr (pr00gie, '/'); /* shorter argv[0] */ 776 if (p) 777 p++; 778 else 779 p = pr00gie; 780 Debug (("gonna exec %s as %s...", pr00gie, p)) 781 execl (pr00gie, p, NULL); 782 bail ("exec %s failed", pr00gie); /* this gets sent out. Hmm... */ 783 } /* doexec */ 784 #endif 785 #endif /* GAPING_SECURITY_HOLE */ 786 787 /* doconnect : 788 do all the socket stuff, and return an fd for one of 789 an open outbound TCP connection 790 a UDP stub-socket thingie 791 with appropriate socket options set up if we wanted source-routing, or 792 an unconnected TCP or UDP socket to listen on. 793 Examines various global o_blah flags to figure out what-all to do. */ 794 int doconnect (rad, rp, lad, lp) 795 IA * rad; 796 USHORT rp; 797 IA * lad; 798 USHORT lp; 799 { 800 #ifndef WIN32 801 register int nnetfd; 802 #endif 803 register int rr; 804 int x, y; 805 806 errno = 0; 807 #ifdef WIN32 808 WSASetLastError(0); 809 #endif 810 /* grab a socket; set opts */ 811 if (o_udpmode) 812 nnetfd = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); 813 else 814 nnetfd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); 815 if (nnetfd < 0) 816 bail ("Can't get socket"); 817 if (nnetfd == 0) /* might *be* zero if stdin was closed! */ 818 nnetfd = dup (nnetfd); /* so fix it. Leave the old 0 hanging. */ 819 #ifdef WIN32 820 rr = setsockopt (nnetfd, SOL_SOCKET, SO_REUSEADDR, (const char FAR *)setsockopt_c, sizeof (setsockopt_c)); 821 #else 822 x = 1; 823 rr = setsockopt (nnetfd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof (x)); 824 #endif 825 if (rr == -1) 826 holler ("nnetfd reuseaddr failed"); /* ??? */ 827 #ifdef SO_REUSEPORT /* doesnt exist everywhere... */ 828 #ifdef WIN32 829 rr = setsockopt (nnetfd, SOL_SOCKET, SO_REUSEPORT, &c, sizeof (c)); 830 #else 831 rr = setsockopt (nnetfd, SOL_SOCKET, SO_REUSEPORT, &x, sizeof (x)); 832 #endif 833 if (rr == -1) 834 holler ("nnetfd reuseport failed"); /* ??? */ 835 #endif 836 837 /* fill in all the right sockaddr crud */ 838 lclend->sin_family = AF_INET; 839 remend->sin_family = AF_INET; 840 841 /* if lad/lp, do appropriate binding */ 842 if (lad) 843 memcpy (&lclend->sin_addr.s_addr, lad, sizeof (IA)); 844 if (lp) 845 lclend->sin_port = htons (lp); 846 rr = 0; 847 if (lad || lp) { 848 x = (int) lp; 849 /* try a few times for the local bind, a la ftp-data-port... */ 850 for (y = 4; y > 0; y--) { 851 rr = bind (nnetfd, (SA *)lclend, sizeof (SA)); 852 if (rr == 0) 853 break; 854 if (errno != EADDRINUSE) 855 break; 856 else { 857 holler ("retrying local %s:%d", inet_ntoa (lclend->sin_addr), lp); 858 sleep (1); 859 errno = 0; /* clear from sleep */ 860 } /* if EADDRINUSE */ 861 } /* for y counter */ 862 } /* if lad or lp */ 863 if (rr) 864 bail ("Can't grab %s:%d with bind", 865 inet_ntoa(lclend->sin_addr), lp); 866 867 if (o_listen) 868 return (nnetfd); /* thanks, that's all for today */ 869 870 memcpy (&remend->sin_addr.s_addr, rad, sizeof (IA)); 871 remend->sin_port = htons (rp); 872 873 /* rough format of LSRR option and explanation of weirdness. 874 -Option comes after IP-hdr dest addr in packet, padded to *4, and ihl > 5. 875 -IHL is multiples of 4, i.e. real len = ip_hl << 2. 876 - type 131 1 ; 0x83: copied, option class 0, number 3 877 - len 1 ; of *whole* option! 878 - pointer 1 ; nxt-hop-addr; 1-relative, not 0-relative 879 - addrlist... var ; 4 bytes per hop-addr 880 - pad-to-32 var ; ones, i.e. "NOP" 881 - 882 -If we want to route A -> B via hops C and D, we must add C, D, *and* B to the 883 -options list. Why? Because when we hand the kernel A -> B with list C, D, B 884 -the "send shuffle" inside the kernel changes it into A -> C with list D, B and 885 -the outbound packet gets sent to C. If B wasn't also in the hops list, the 886 -final destination would have been lost at this point. 887 - 888 -When C gets the packet, it changes it to A -> D with list C', B where C' is 889 -the interface address that C used to forward the packet. This "records" the 890 -route hop from B's point of view, i.e. which address points "toward" B. This 891 -is to make B better able to return the packets. The pointer gets bumped by 4, 892 -so that D does the right thing instead of trying to forward back to C. 893 - 894 -When B finally gets the packet, it sees that the pointer is at the end of the 895 -LSRR list and is thus "completed". B will then try to use the packet instead 896 -of forwarding it, i.e. deliver it up to some application. 897 - 898 -Note that by moving the pointer yourself, you could send the traffic directly 899 -to B but have it return via your preconstructed source-route. Playing with 900 -this and watching "tcpdump -v" is the best way to understand what's going on. 901 - 902 -Only works for TCP in BSD-flavor kernels. UDP is a loss; udp_input calls 903 -stripoptions() early on, and the code to save the srcrt is notdef'ed. 904 -Linux is also still a loss at 1.3.x it looks like; the lsrr code is { }... 905 -*/ 906 907 908 /* if any -g arguments were given, set up source-routing. We hit this after 909 the gates are all looked up and ready to rock, any -G pointer is set, 910 and gatesidx is now the *number* of hops */ 911 if (gatesidx) { /* if we wanted any srcrt hops ... */ 912 /* don't even bother compiling if we can't do IP options here! */ 913 /* #ifdef IP_OPTIONS */ 914 #ifndef WIN32 915 if (! optbuf) { /* and don't already *have* a srcrt set */ 916 char * opp; /* then do all this setup hair */ 917 optbuf = Hmalloc (48); 918 opp = optbuf; 919 *opp++ = IPOPT_LSRR; /* option */ 920 *opp++ = (char) 921 (((gatesidx + 1) * sizeof (IA)) + 3) & 0xff; /* length */ 922 *opp++ = gatesptr; /* pointer */ 923 /* opp now points at first hop addr -- insert the intermediate gateways */ 924 for ( x = 0; x < gatesidx; x++) { 925 memcpy (opp, gates[x]->iaddrs, sizeof (IA)); 926 opp += sizeof (IA); 927 } 928 /* and tack the final destination on the end [needed!] */ 929 memcpy (opp, rad, sizeof (IA)); 930 opp += sizeof (IA); 931 *opp = IPOPT_NOP; /* alignment filler */ 932 } /* if empty optbuf */ 933 /* calculate length of whole option mess, which is (3 + [hops] + [final] + 1), 934 and apply it [have to do this every time through, of course] */ 935 x = ((gatesidx + 1) * sizeof (IA)) + 4; 936 rr = setsockopt (nnetfd, IPPROTO_IP, IP_OPTIONS, optbuf, x); 937 if (rr == -1) 938 bail ("srcrt setsockopt fuxored"); 939 #else /* IP_OPTIONS */ 940 holler ("Warning: source routing unavailable on this machine, ignoring"); 941 #endif /* IP_OPTIONS*/ 942 } /* if gatesidx */ 943 944 /* wrap connect inside a timer, and hit it */ 945 arm (1, o_wait); 946 if (setjmp (jbuf) == 0) { 947 rr = connect (nnetfd, (SA *)remend, sizeof (SA)); 948 } else { /* setjmp: connect failed... */ 949 rr = -1; 950 #ifdef WIN32 951 WSASetLastError(WSAETIMEDOUT); /* fake it */ 952 #else 953 errno = ETIMEDOUT; /* fake it */ 954 #endif 955 } 956 arm (0, 0); 957 if (rr == 0) 958 return (nnetfd); 959 #ifdef WIN32 960 errno = h_errno; 961 shutdown(nnetfd, 0x02); /* Kirby */ 962 closesocket (nnetfd); 963 WSASetLastError(errno); /* don't want to lose connect error */ 964 #else 965 close (nnetfd); /* clean up junked socket FD!! */ 966 #endif 967 return (-1); 968 } /* doconnect */ 969 970 /* dolisten : 971 just like doconnect, and in fact calls a hunk of doconnect, but listens for 972 incoming and returns an open connection *from* someplace. If we were 973 given host/port args, any connections from elsewhere are rejected. This 974 in conjunction with local-address binding should limit things nicely... */ 975 int dolisten (rad, rp, lad, lp) 976 IA * rad; 977 USHORT rp; 978 IA * lad; 979 USHORT lp; 980 { 981 register int nnetfd; 982 register int rr; 983 HINF * whozis = NULL; 984 int x; 985 char * cp; 986 USHORT z; 987 errno = 0; 988 989 /* Pass everything off to doconnect, who in o_listen mode just gets a socket */ 990 nnetfd = doconnect (rad, rp, lad, lp); 991 if (nnetfd <= 0) 992 return (-1); 993 if (o_udpmode) { /* apparently UDP can listen ON */ 994 if (! lp) /* "port 0", but that's not useful */ 995 bail ("UDP listen needs -p arg"); 996 } else { 997 rr = listen (nnetfd, 1); /* gotta listen() before we can get */ 998 if (rr < 0) /* our local random port. sheesh. */ 999 bail ("local listen fuxored"); 1000 } 1001 1002 /* I can't believe I have to do all this to get my own goddamn bound address 1003 and port number. It should just get filled in during bind() or something. 1004 All this is only useful if we didn't say -p for listening, since if we 1005 said -p we *know* what port we're listening on. At any rate we won't bother 1006 with it all unless we wanted to see it, although listening quietly on a 1007 random unknown port is probably not very useful without "netstat". */ 1008 if (o_verbose) { 1009 x = sizeof (SA); /* how 'bout getsockNUM instead, pinheads?! */ 1010 rr = getsockname (nnetfd, (SA *) lclend, &x); 1011 if (rr < 0) 1012 holler ("local getsockname failed"); 1013 strcpy (bigbuf_net, "listening on ["); /* buffer reuse... */ 1014 if (lclend->sin_addr.s_addr) 1015 strcat (bigbuf_net, inet_ntoa (lclend->sin_addr)); 1016 else 1017 strcat (bigbuf_net, "any"); 1018 strcat (bigbuf_net, "] %d ..."); 1019 z = ntohs (lclend->sin_port); 1020 holler (bigbuf_net, z); 1021 } /* verbose -- whew!! */ 1022 1023 /* UDP is a speeeeecial case -- we have to do I/O *and* get the calling 1024 party's particulars all at once, listen() and accept() don't apply. 1025 At least in the BSD universe, however, recvfrom/PEEK is enough to tell 1026 us something came in, and we can set things up so straight read/write 1027 actually does work after all. Yow. YMMV on strange platforms! */ 1028 if (o_udpmode) { 1029 x = sizeof (SA); /* retval for recvfrom */ 1030 arm (2, o_wait); /* might as well timeout this, too */ 1031 if (setjmp (jbuf) == 0) { /* do timeout for initial connect */ 1032 rr = recvfrom /* and here we block... */ 1033 (nnetfd, bigbuf_net, BIGSIZ, MSG_PEEK, (SA *) remend, &x); 1034 Debug (("dolisten/recvfrom ding, rr = %d, netbuf %s ", rr, bigbuf_net)) 1035 } else 1036 goto dol_tmo; /* timeout */ 1037 arm (0, 0); 1038 /* I'm not completely clear on how this works -- BSD seems to make UDP 1039 just magically work in a connect()ed context, but we'll undoubtedly run 1040 into systems this deal doesn't work on. For now, we apparently have to 1041 issue a connect() on our just-tickled socket so we can write() back. 1042 Again, why the fuck doesn't it just get filled in and taken care of?! 1043 This hack is anything but optimal. Basically, if you want your listener 1044 to also be able to send data back, you need this connect() line, which 1045 also has the side effect that now anything from a different source or even a 1046 different port on the other end won't show up and will cause ICMP errors. 1047 I guess that's what they meant by "connect". 1048 Let's try to remember what the "U" is *really* for, eh? 1049 */ 1050 rr = connect (nnetfd, (SA *)remend, sizeof (SA)); 1051 goto whoisit; 1052 } /* o_udpmode */ 1053 1054 /* fall here for TCP */ 1055 x = sizeof (SA); /* retval for accept */ 1056 arm (2, o_wait); /* wrap this in a timer, too; 0 = forever */ 1057 if (setjmp (jbuf) == 0) { 1058 rr = accept (nnetfd, (SA *)remend, &x); 1059 } else 1060 goto dol_tmo; /* timeout */ 1061 arm (0, 0); 1062 #ifdef WIN32 1063 shutdown(nnetfd, 0x02); /* Kirby */ 1064 closesocket (nnetfd); 1065 #else 1066 close (nnetfd); /* dump the old socket */ 1067 #endif 1068 nnetfd = rr; /* here's our new one */ 1069 1070 whoisit: 1071 if (rr < 0) 1072 goto dol_err; /* bail out if any errors so far */ 1073 1074 /* Various things that follow temporarily trash bigbuf_net, which might contain 1075 a copy of any recvfrom()ed packet, but we'll read() another copy later. */ 1076 1077 /* If we can, look for any IP options. Useful for testing the receiving end of 1078 such things, and is a good exercise in dealing with it. We do this before 1079 the connect message, to ensure that the connect msg is uniformly the LAST 1080 thing to emerge after all the intervening crud. Doesn't work for UDP on 1081 any machines I've tested, but feel free to surprise me. */ 1082 /* #ifdef IP_OPTIONS */ 1083 #ifndef WIN32 1084 if (! o_verbose) /* if we wont see it, we dont care */ 1085 goto dol_noop; 1086 optbuf = Hmalloc (40); 1087 x = 40; 1088 rr = getsockopt (nnetfd, IPPROTO_IP, IP_OPTIONS, optbuf, &x); 1089 if (rr < 0) 1090 holler ("getsockopt failed"); 1091 Debug (("ipoptions ret len %d", x)) 1092 if (x) { /* we've got options, lessee em... */ 1093 unsigned char * q = (unsigned char *) optbuf; 1094 char * p = bigbuf_net; /* local variables, yuk! */ 1095 char * pp = &bigbuf_net[128]; /* get random space farther out... */ 1096 memset (bigbuf_net, 0, 256); /* clear it all first */ 1097 while (x > 0) { 1098 sprintf (pp, "%2.2x ", *q); /* clumsy, but works: turn into hex */ 1099 strcat (p, pp); /* and build the final string */ 1100 q++; p++; 1101 x--; 1102 } 1103 holler ("IP options: %s", bigbuf_net); 1104 } /* if x, i.e. any options */ 1105 dol_noop: 1106 #endif /* IP_OPTIONS */ 1107 1108 /* find out what address the connection was *to* on our end, in case we're 1109 doing a listen-on-any on a multihomed machine. This allows one to 1110 offer different services via different alias addresses, such as the 1111 "virtual web site" hack. */ 1112 memset (bigbuf_net, 0, 64); 1113 cp = &bigbuf_net[32]; 1114 x = sizeof (SA); 1115 rr = getsockname (nnetfd, (SA *) lclend, &x); 1116 if (rr < 0) 1117 holler ("post-rcv getsockname failed"); 1118 strcpy (cp, inet_ntoa (lclend->sin_addr)); 1119 1120 1121 /* now check out who it is. We don't care about mismatched DNS names here, 1122 but any ADDR and PORT we specified had better fucking well match the caller. 1123 Converting from addr to inet_ntoa and back again is a bit of a kludge, but 1124 gethostpoop wants a string and there's much gnarlier code out there already, 1125 so I don't feel bad. 1126 The *real* question is why BFD sockets wasn't designed to allow listens for 1127 connections *from* specific hosts/ports, instead of requiring the caller to 1128 accept the connection and then reject undesireable ones by closing. */ 1129 z = ntohs (remend->sin_port); 1130 strcpy (bigbuf_net, inet_ntoa (remend->sin_addr)); 1131 whozis = gethostpoop (bigbuf_net, o_nflag); 1132 errno = 0; 1133 x = 0; /* use as a flag... */ 1134 if (rad) 1135 if (memcmp (rad, whozis->iaddrs, sizeof (SA))) 1136 x = 1; 1137 if (rp) 1138 if (z != rp) 1139 x = 1; 1140 if (x) /* guilty! */ 1141 bail ("invalid connection to [%s] from %s [%s] %d", 1142 cp, whozis->name, whozis->addrs[0], z); 1143 holler ("connect to [%s] from %s [%s] %d", /* oh, you're okay.. */ 1144 cp, whozis->name, whozis->addrs[0], z); 1145 1146 return (nnetfd); /* open! */ 1147 1148 dol_tmo: 1149 errno = ETIMEDOUT; /* fake it */ 1150 dol_err: 1151 #ifdef WIN32 1152 shutdown(nnetfd, 0x02); /* Kirby */ 1153 closesocket (nnetfd); 1154 #else 1155 close (nnetfd); 1156 #endif 1157 return (-1); 1158 } /* dolisten */ 1159 1160 /* udptest : 1161 fire a couple of packets at a UDP target port, just to see if it's really 1162 there. On BSD kernels, ICMP host/port-unreachable errors get delivered to 1163 our socket as ECONNREFUSED write errors. On SV kernels, we lose; we'll have 1164 to collect and analyze raw ICMP ourselves a la satan's probe_udp_ports 1165 backend. Guess where could swipe the appropriate code from... 1166 1167 Use the time delay between writes if given, otherwise use the "tcp ping" 1168 trick for getting the RTT. [I got that idea from pluvius, and warped it.] 1169 Return either the original fd, or clean up and return -1. */ 1170 udptest (fd, where) 1171 int fd; 1172 IA * where; 1173 { 1174 register int rr; 1175 1176 #ifdef WIN32 1177 rr = send (fd, bigbuf_in, 1, 0); 1178 #else 1179 rr = write (fd, bigbuf_in, 1); 1180 #endif 1181 if (rr != 1) 1182 holler ("udptest first write failed?! errno %d", errno); 1183 if (o_wait) 1184 sleep (o_wait); 1185 else { 1186 /* use the tcp-ping trick: try connecting to a normally refused port, which 1187 causes us to block for the time that SYN gets there and RST gets back. 1188 Not completely reliable, but it *does* mostly work. */ 1189 o_udpmode = 0; /* so doconnect does TCP this time */ 1190 /* Set a temporary connect timeout, so packet filtration doesnt cause 1191 us to hang forever, and hit it */ 1192 o_wait = 5; /* XXX: enough to notice?? */ 1193 rr = doconnect (where, SLEAZE_PORT, 0, 0); 1194 if (rr > 0) 1195 #ifdef WIN32 1196 shutdown(fd, 0x02); /* Kirby */ 1197 closesocket (rr); 1198 #else 1199 close (rr); /* in case it *did* open */ 1200 #endif 1201 o_wait = 0; /* reset it */ 1202 o_udpmode++; /* we *are* still doing UDP, right? */ 1203 } /* if o_wait */ 1204 errno = 0; /* clear from sleep */ 1205 #ifdef WIN32 1206 rr = send (fd, bigbuf_in, 1, 0); 1207 #else 1208 rr = write (fd, bigbuf_in, 1); 1209 #endif 1210 if (rr == 1) /* if write error, no UDP listener */ 1211 return (fd); 1212 #ifdef WIN32 1213 shutdown(fd, 0x02); /* Kirby */ 1214 closesocket (fd); 1215 #else 1216 close (fd); /* use it or lose it! */ 1217 #endif 1218 return (-1); 1219 } /* udptest */ 1220 1221 /* oprint : 1222 Hexdump bytes shoveled either way to a running logfile, in the format: 1223 D offset - - - - --- 16 bytes --- - - - - # .... ascii ..... 1224 where "which" sets the direction indicator, D: 1225 0 -- sent to network, or ">" 1226 1 -- rcvd and printed to stdout, or "<" 1227 and "buf" and "n" are data-block and length. If the current block generates 1228 a partial line, so be it; we *want* that lockstep indication of who sent 1229 what when. Adapted from dgaudet's original example -- but must be ripping 1230 *fast*, since we don't want to be too disk-bound... */ 1231 void oprint (which, buf, n) 1232 int which; 1233 char * buf; 1234 int n; 1235 { 1236 int bc; /* in buffer count */ 1237 int obc; /* current "global" offset */ 1238 int soc; /* stage write count */ 1239 register unsigned char * p; /* main buf ptr; m.b. unsigned here */ 1240 register unsigned char * op; /* out hexdump ptr */ 1241 register unsigned char * a; /* out asc-dump ptr */ 1242 register int x; 1243 register unsigned int y; 1244 1245 if (! ofd) 1246 bail ("oprint called with no open fd?!"); 1247 if (n == 0) 1248 return; 1249 1250 op = stage; 1251 if (which) { 1252 *op = '<'; 1253 obc = wrote_out; /* use the globals! */ 1254 } else { 1255 *op = '>'; 1256 obc = wrote_net; 1257 } 1258 op++; /* preload "direction" */ 1259 *op = ' '; 1260 p = (unsigned char *) buf; 1261 bc = n; 1262 stage[59] = '#'; /* preload separator */ 1263 stage[60] = ' '; 1264 1265 while (bc) { /* for chunk-o-data ... */ 1266 x = 16; 1267 soc = 78; /* len of whole formatted line */ 1268 if (bc < x) { 1269 soc = soc - 16 + bc; /* fiddle for however much is left */ 1270 x = (bc * 3) + 11; /* 2 digits + space per, after D & offset */ 1271 op = &stage[x]; 1272 x = 16 - bc; 1273 while (x) { 1274 *op++ = ' '; /* preload filler spaces */ 1275 *op++ = ' '; 1276 *op++ = ' '; 1277 x--; 1278 } 1279 x = bc; /* re-fix current linecount */ 1280 } /* if bc < x */ 1281 1282 bc -= x; /* fix wrt current line size */ 1283 sprintf (&stage[2], "%8.8x ", obc); /* xxx: still slow? */ 1284 obc += x; /* fix current offset */ 1285 op = &stage[11]; /* where hex starts */ 1286 a = &stage[61]; /* where ascii starts */ 1287 1288 while (x) { /* for line of dump, however long ... */ 1289 y = (int)(*p >> 4); /* hi half */ 1290 *op = hexnibs[y]; 1291 op++; 1292 y = (int)(*p & 0x0f); /* lo half */ 1293 *op = hexnibs[y]; 1294 op++; 1295 *op = ' '; 1296 op++; 1297 if ((*p > 31) && (*p < 127)) 1298 *a = *p; /* printing */ 1299 else 1300 *a = '.'; /* nonprinting, loose def */ 1301 a++; 1302 p++; 1303 x--; 1304 } /* while x */ 1305 *a = '\n'; /* finish the line */ 1306 x = write (ofd, stage, soc); 1307 if (x < 0) 1308 bail ("ofd write err"); 1309 } /* while bc */ 1310 } /* oprint */ 1311 1312 #ifdef TELNET 1313 USHORT o_tn = 0; /* global -t option */ 1314 1315 /* atelnet : 1316 Answer anything that looks like telnet negotiation with don't/won't. 1317 This doesn't modify any data buffers, update the global output count, 1318 or show up in a hexdump -- it just shits into the outgoing stream. 1319 Idea and codebase from Mudge@l0pht.com. */ 1320 void atelnet (buf, size) 1321 unsigned char * buf; /* has to be unsigned here! */ 1322 unsigned int size; 1323 { 1324 static unsigned char obuf [4]; /* tiny thing to build responses into */ 1325 register int x; 1326 register unsigned char y; 1327 register unsigned char * p; 1328 1329 y = 0; 1330 p = buf; 1331 x = size; 1332 while (x > 0) { 1333 if (*p != 255) /* IAC? */ 1334 goto notiac; 1335 obuf[0] = 255; 1336 p++; x--; 1337 if ((*p == 251) || (*p == 252)) /* WILL or WONT */ 1338 y = 254; /* -> DONT */ 1339 if ((*p == 253) || (*p == 254)) /* DO or DONT */ 1340 y = 252; /* -> WONT */ 1341 if (y) { 1342 obuf[1] = y; 1343 p++; x--; 1344 obuf[2] = *p; /* copy actual option byte */ 1345 #ifdef WIN32 1346 (void) send (netfd, obuf, 3, 0); /* one line, or the whole buffer */ 1347 #else 1348 (void) write (netfd, obuf, 3); 1349 #endif 1350 /* if one wanted to bump wrote_net or do a hexdump line, here's the place */ 1351 y = 0; 1352 } /* if y */ 1353 notiac: 1354 p++; x--; 1355 } /* while x */ 1356 } /* atelnet */ 1357 #endif /* TELNET */ 1358 1359 1360 /* readwrite : 1361 handle stdin/stdout/network I/O. Bwahaha!! -- the select loop from hell. 1362 In this instance, return what might become our exit status. */ 1363 int readwrite (fd) 1364 #ifdef WIN32 1365 unsigned int fd; 1366 #else 1367 int fd; 1368 #endif 1369 { 1370 register int rr; 1371 register char * zp; /* stdin buf ptr */ 1372 register char * np; /* net-in buf ptr */ 1373 unsigned int rzleft; 1374 unsigned int rnleft; 1375 USHORT netretry; /* net-read retry counter */ 1376 USHORT wretry; /* net-write sanity counter */ 1377 USHORT wfirst; /* one-shot flag to skip first net read */ 1378 1379 #ifdef WIN32 /* (weld) WIN32 must poll because of weak stdin handling so we need a 1380 short timer */ 1381 struct timeval timer3; 1382 int istty; 1383 time_t start, current; 1384 int foo; 1385 1386 timer3.tv_sec = 0; 1387 timer3.tv_usec = 1000; 1388 1389 /* save the time so we can bail when we reach timeout */ 1390 time( &start ); 1391 1392 1393 /* sets stdin and stdout to binary so no crlf translation if its a tty */ 1394 if (!_isatty( 1 )) 1395 _setmode( 1, _O_BINARY ); 1396 1397 if ((istty = _isatty( 0 )) == FALSE) 1398 _setmode( 0, _O_BINARY ); /* (weld) I think we want to do this */ 1399 1400 #endif 1401 1402 /* if you don't have all this FD_* macro hair in sys/types.h, you'll have to 1403 either find it or do your own bit-bashing: *ding1 |= (1 << fd), etc... */ 1404 #ifndef WIN32 /* fd is not implemented as a real file handle in WIN32 */ 1405 if (fd > FD_SETSIZE) { 1406 holler ("Preposterous fd value %d", fd); 1407 return (1); 1408 } 1409 #endif 1410 FD_SET (fd, ding1); /* global: the net is open */ 1411 netretry = 2; 1412 wfirst = 0; 1413 rzleft = rnleft = 0; 1414 if (insaved) { 1415 rzleft = insaved; /* preload multi-mode fakeouts */ 1416 zp = bigbuf_in; 1417 1418 wfirst = 1; 1419 if (Single) /* if not scanning, this is a one-off first */ 1420 insaved = 0; /* buffer left over from argv construction, */ 1421 else { 1422 FD_CLR (0, ding1); /* OR we've already got our repeat chunk, */ 1423 close (0); /* so we won't need any more stdin */ 1424 } /* Single */ 1425 } /* insaved */ 1426 1427 if (o_interval) 1428 sleep (o_interval); /* pause *before* sending stuff, too */ 1429 errno = 0; /* clear from sleep */ 1430 #ifdef WIN32 1431 WSASetLastError(0); 1432 #endif 1433 1434 /* and now the big ol' select shoveling loop ... */ 1435 while (FD_ISSET (fd, ding1)) { /* i.e. till the *net* closes! */ 1436 wretry = 8200; /* more than we'll ever hafta write */ 1437 if (wfirst) { /* any saved stdin buffer? */ 1438 wfirst = 0; /* clear flag for the duration */ 1439 goto shovel; /* and go handle it first */ 1440 } 1441 *ding2 = *ding1; /* FD_COPY ain't portable... */ 1442 1443 /* some systems, notably linux, crap into their select timers on return, so 1444 we create a expendable copy and give *that* to select. *Fuck* me ... */ 1445 if (timer1) 1446 memcpy (timer2, timer1, sizeof (struct timeval)); 1447 #ifdef WIN32 /* (weld)we must use our own small timeval to poll */ 1448 rr = select (16, ding2, 0, 0, &timer3); /* here it is, kiddies */ 1449 #else 1450 rr = select (16, ding2, 0, 0, timer2); /* here it is, kiddies */ 1451 #endif 1452 if (rr < 0) { 1453 #ifdef WIN32 1454 if (h_errno != WSAEINTR) { /* might have gotten ^Zed, etc ?*/ 1455 #else 1456 if (errno != EINTR) { /* might have gotten ^Zed, etc ?*/ 1457 #endif 1458 foo = h_errno; 1459 holler ("select fuxored"); 1460 #ifdef WIN32 1461 shutdown(fd, 0x02); /* Kirby */ 1462 closesocket (fd); 1463 #else 1464 close (fd); 1465 #endif 1466 return (1); 1467 } 1468 } /* select fuckup */ 1469 /* if we have a timeout AND stdin is closed AND we haven't heard anything 1470 from the net during that time, assume it's dead and close it too. */ 1471 #ifndef WIN32 /* (weld) need to write some code here */ 1472 if (rr == 0) { 1473 if (! FD_ISSET (0, ding1)) 1474 netretry--; /* we actually try a coupla times. */ 1475 if (! netretry) { 1476 if (o_verbose > 1) /* normally we don't care */ 1477 holler ("net timeout"); 1478 close (fd); 1479 return (0); /* not an error! */ 1480 } 1481 } /* select timeout */ 1482 #else 1483 if (rr == 0) { 1484 time( ¤t ); 1485 if ( o_wait > 0 && (current - start) > timer1->tv_sec) { 1486 if (o_verbose > 1) /* normally we don't care */ 1487 holler ("net timeout"); 1488 shutdown(fd, 0x02); /* Kirby */ 1489 closesocket (fd); 1490 FD_ZERO(ding1); 1491 WSASetLastError(0); 1492 return (0); /* not an error! */ 1493 } 1494 } /* select timeout */ 1495 #endif 1496 /* xxx: should we check the exception fds too? The read fds seem to give 1497 us the right info, and none of the examples I found bothered. */ 1498 1499 /* Ding!! Something arrived, go check all the incoming hoppers, net first */ 1500 if (FD_ISSET (fd, ding2)) { /* net: ding! */ 1501 #ifdef WIN32 1502 // reset timer 1503 time( &start ); 1504 1505 rr = recv (fd, bigbuf_net, BIGSIZ, 0); 1506 #else 1507 rr = read (fd, bigbuf_net, BIGSIZ); 1508 #endif 1509 if (rr <= 0) { 1510 FD_CLR (fd, ding1); /* net closed, we'll finish up... */ 1511 rzleft = 0; /* can't write anymore: broken pipe */ 1512 } else { 1513 rnleft = rr; 1514 np = bigbuf_net; 1515 #ifdef TELNET 1516 if (o_tn) 1517 atelnet (np, rr); /* fake out telnet stuff */ 1518 #endif /* TELNET */ 1519 } /* if rr */ 1520 Debug (("got %d from the net, errno %d", rr, errno)) 1521 } /* net:ding */ 1522 1523 /* if we're in "slowly" mode there's probably still stuff in the stdin 1524 buffer, so don't read unless we really need MORE INPUT! MORE INPUT! */ 1525 if (rzleft) 1526 goto shovel; 1527 1528 /* okay, suck more stdin */ 1529 #ifndef WIN32 1530 if (FD_ISSET (0, ding2)) { /* stdin: ding! */ 1531 rr = read (0, bigbuf_in, BIGSIZ); 1532 1533 /* xxx: maybe make reads here smaller for UDP mode, so that the subsequent 1534 writes are smaller -- 1024 or something? "oh, frag it", etc, although 1535 mobygrams are kinda fun and exercise the reassembler. */ 1536 if (rr <= 0) { /* at end, or fukt, or ... */ 1537 FD_CLR (0, ding1); /* disable and close stdin */ 1538 close (0); 1539 } else { 1540 rzleft = rr; 1541 zp = bigbuf_in; 1542 /* special case for multi-mode -- we'll want to send this one buffer to every 1543 open TCP port or every UDP attempt, so save its size and clean up stdin */ 1544 if (! Single) { /* we might be scanning... */ 1545 insaved = rr; /* save len */ 1546 FD_CLR (0, ding1); /* disable further junk from stdin */ 1547 close (0); /* really, I mean it */ 1548 } /* Single */ 1549 } /* if rr/read */ 1550 } /* stdin:ding */ 1551 #else 1552 if (istty) { 1553 /* (weld) cool, we can actually peek a tty and not have to block */ 1554 /* needs to be cleaned up */ 1555 if (kbhit()) { 1556 /* bigbuf_in[0] = getche(); */ 1557 gets(bigbuf_in); 1558 if (o_crlf) 1559 strcat(bigbuf_in, "\x0d"); 1560 strcat(bigbuf_in, "\x0a"); 1561 rr = strlen(bigbuf_in); 1562 rzleft = rr; 1563 zp = bigbuf_in; 1564 /* special case for multi-mode -- we'll want to send this one buffer to every 1565 open TCP port or every UDP attempt, so save its size and clean up stdin */ 1566 if (! Single) { /* we might be scanning... */ 1567 insaved = rr; /* save len */ 1568 close (0); /* really, I mean it */ 1569 } 1570 } 1571 } else { 1572 /* (weld) this is gonna block until a <cr> so it kinda sucks */ 1573 rr = read (0, bigbuf_in, BIGSIZ); 1574 if (rr <= 0) { /* at end, or fukt, or ... */ 1575 close (0); 1576 } else { 1577 rzleft = rr; 1578 zp = bigbuf_in; 1579 /* special case for multi-mode -- we'll want to send this one buffer to every 1580 open TCP port or every UDP attempt, so save its size and clean up stdin */ 1581 if (! Single) { /* we might be scanning... */ 1582 insaved = rr; /* save len */ 1583 close (0); /* really, I mean it */ 1584 } /* Single */ 1585 } /* if rr/read */ 1586 } 1587 1588 #endif 1589 shovel: 1590 /* now that we've dingdonged all our thingdings, send off the results. 1591 Geez, why does this look an awful lot like the big loop in "rsh"? ... 1592 not sure if the order of this matters, but write net -> stdout first. */ 1593 1594 /* sanity check. Works because they're both unsigned... */ 1595 if ((rzleft > 8200) || (rnleft > 8200)) { 1596 holler ("Preposterous Pointers: %d, %d", rzleft, rnleft); 1597 rzleft = rnleft = 0; 1598 } 1599 /* net write retries sometimes happen on UDP connections */ 1600 if (! wretry) { /* is something hung? */ 1601 holler ("too many output retries"); 1602 return (1); 1603 } 1604 if (rnleft) { 1605 rr = write (1, np, rnleft); 1606 fflush(stdin); 1607 if (rr > 0) { 1608 if (o_wfile) 1609 oprint (1, np, rr); /* log the stdout */ 1610 np += rr; /* fix up ptrs and whatnot */ 1611 rnleft -= rr; /* will get sanity-checked above */ 1612 wrote_out += rr; /* global count */ 1613 } 1614 Debug (("wrote %d to stdout, errno %d", rr, errno)) 1615 } /* rnleft */ 1616 if (rzleft) { 1617 if (o_interval) /* in "slowly" mode ?? */ 1618 rr = findline (zp, rzleft); 1619 else 1620 rr = rzleft; 1621 #ifdef WIN32 1622 rr = send (fd, zp, rr, 0); /* one line, or the whole buffer */ 1623 #else 1624 rr = write (fd, zp, rr); /* one line, or the whole buffer */ 1625 #endif 1626 if (rr > 0) { 1627 zp += rr; 1628 rzleft -= rr; 1629 wrote_net += rr; /* global count */ 1630 } 1631 Debug (("wrote %d to net, errno %d", rr, errno)) 1632 } /* rzleft */ 1633 if (o_interval) { /* cycle between slow lines, or ... */ 1634 sleep (o_interval); 1635 errno = 0; /* clear from sleep */ 1636 continue; /* ...with hairy select loop... */ 1637 } 1638 if ((rzleft) || (rnleft)) { /* shovel that shit till they ain't */ 1639 wretry--; /* none left, and get another load */ 1640 goto shovel; 1641 } 1642 } /* while ding1:netfd is open */ 1643 1644 /* XXX: maybe want a more graceful shutdown() here, or screw around with 1645 linger times?? I suspect that I don't need to since I'm always doing 1646 blocking reads and writes and my own manual "last ditch" efforts to read 1647 the net again after a timeout. I haven't seen any screwups yet, but it's 1648 not like my test network is particularly busy... */ 1649 #ifdef WIN32 1650 shutdown(fd, 0x02); /* Kirby */ 1651 closesocket (fd); 1652 #else 1653 close (fd); 1654 #endif 1655 return (0); 1656 } /* readwrite */ 1657 1658 /* main : 1659 now we pull it all together... */ 1660 main (argc, argv) 1661 int argc; 1662 char ** argv; 1663 { 1664 #ifndef HAVE_GETOPT 1665 extern char * optarg; 1666 extern int optind, optopt; 1667 #endif 1668 register int x; 1669 register char *cp; 1670 HINF * gp; 1671 HINF * whereto = NULL; 1672 HINF * wherefrom = NULL; 1673 IA * ouraddr = NULL; 1674 IA * themaddr = NULL; 1675 USHORT o_lport = 0; 1676 USHORT ourport = 0; 1677 USHORT loport = 0; /* for scanning stuff */ 1678 USHORT hiport = 0; 1679 USHORT curport = 0; 1680 char * randports = NULL; 1681 int cycle = 0; 1682 1683 #ifdef HAVE_BIND 1684 /* can *you* say "cc -yaddayadda netcat.c -lresolv -l44bsd" on SunLOSs? */ 1685 res_init(); 1686 #endif 1687 /* I was in this barbershop quartet in Skokie IL ... */ 1688 /* round up the usual suspects, i.e. malloc up all the stuff we need */ 1689 lclend = (SAI *) Hmalloc (sizeof (SA)); 1690 remend = (SAI *) Hmalloc (sizeof (SA)); 1691 bigbuf_in = Hmalloc (BIGSIZ); 1692 bigbuf_net = Hmalloc (BIGSIZ); 1693 ding1 = (fd_set *) Hmalloc (sizeof (fd_set)); 1694 ding2 = (fd_set *) Hmalloc (sizeof (fd_set)); 1695 portpoop = (PINF *) Hmalloc (sizeof (PINF)); 1696 1697 #ifdef WIN32 1698 setsockopt_c = (char *)malloc(sizeof(char)); 1699 *setsockopt_c = 1; 1700 #endif 1701 1702 errno = 0; 1703 gatesptr = 4; 1704 #ifndef WIN32 1705 h_errno = 0; 1706 #endif 1707 /* catch a signal or two for cleanup */ 1708 #ifdef NTFIXTHIS 1709 signal (SIGINT, catch); 1710 signal (SIGQUIT, catch); 1711 signal (SIGTERM, catch); 1712 signal (SIGURG, SIG_IGN); 1713 #endif 1714 1715 recycle: 1716 1717 /* if no args given at all, get 'em from stdin and construct an argv. */ 1718 if (argc == 1) { 1719 cp = argv[0]; 1720 argv = (char **) Hmalloc (128 * sizeof (char *)); /* XXX: 128? */ 1721 argv[0] = cp; /* leave old prog name intact */ 1722 cp = Hmalloc (BIGSIZ); 1723 argv[1] = cp; /* head of new arg block */ 1724 fprintf (stderr, "Cmd line: "); 1725 fflush (stderr); /* I dont care if it's unbuffered or not! */ 1726 insaved = read (0, cp, BIGSIZ); /* we're gonna fake fgets() here */ 1727 if (insaved <= 0) 1728 bail ("wrong"); 1729 x = findline (cp, insaved); 1730 if (x) 1731 insaved -= x; /* remaining chunk size to be sent */ 1732 if (insaved) /* which might be zero... */ 1733 memcpy (bigbuf_in, &cp[x], insaved); 1734 cp = strchr (argv[1], '\n'); 1735 if (cp) 1736 *cp = '\0'; 1737 cp = strchr (argv[1], '\r'); /* look for ^M too */ 1738 if (cp) 1739 *cp = '\0'; 1740 1741 /* find and stash pointers to remaining new "args" */ 1742 cp = argv[1]; 1743 cp++; /* skip past first char */ 1744 x = 2; /* we know argv 0 and 1 already */ 1745 for (; *cp != '\0'; cp++) { 1746 if (*cp == ' ') { 1747 *cp = '\0'; /* smash all spaces */ 1748 continue; 1749 } else { 1750 if (*(cp-1) == '\0') { 1751 argv[x] = cp; 1752 x++; 1753 } 1754 } /* if space */ 1755 } /* for cp */ 1756 argc = x; 1757 } /* if no args given */ 1758 1759 /* If your shitbox doesn't have getopt, step into the nineties already. */ 1760 /* optarg, optind = next-argv-component [i.e. flag arg]; optopt = last-char */ 1761 while ((x = getopt (argc, argv, "ade:g:G:hi:lLno:p:rs:tcuvw:z")) != EOF) { 1762 /* Debug (("in go: x now %c, optarg %x optind %d", x, optarg, optind)) */ 1763 switch (x) { 1764 case 'a': 1765 bail ("all-A-records NIY"); 1766 o_alla++; break; 1767 #ifdef GAPING_SECURITY_HOLE 1768 case 'e': /* prog to exec */ 1769 pr00gie = optarg; 1770 break; 1771 #endif 1772 case 'L': /* listen then cycle back to start instead of exiting */ 1773 o_listen++; 1774 cycle = 1; 1775 break; 1776 1777 1778 case 'd': /* detach from console */ 1779 FreeConsole();; 1780 break; 1781 1782 1783 case 'G': /* srcrt gateways pointer val */ 1784 x = atoi (optarg); 1785 if ((x) && (x == (x & 0x1c))) /* mask off bits of fukt values */ 1786 gatesptr = x; 1787 else 1788 bail ("invalid hop pointer %d, must be multiple of 4 <= 28", x); 1789 break; 1790 case 'g': /* srcroute hop[s] */ 1791 if (gatesidx > 8) 1792 bail ("too many -g hops"); 1793 if (gates == NULL) /* eat this, Billy-boy */ 1794 gates = (HINF **) Hmalloc (sizeof (HINF *) * 10); 1795 gp = gethostpoop (optarg, o_nflag); 1796 if (gp) 1797 gates[gatesidx] = gp; 1798 gatesidx++; 1799 break; 1800 case 'h': 1801 errno = 0; 1802 #ifdef HAVE_HELP 1803 helpme(); /* exits by itself */ 1804 #else 1805 bail ("no help available, dork -- RTFS"); 1806 #endif 1807 case 'i': /* line-interval time */ 1808 o_interval = atoi (optarg) & 0xffff; 1809 #ifdef WIN32 1810 o_interval *= 1000; 1811 #endif 1812 if (! o_interval) 1813 bail ("invalid interval time %s", optarg); 1814 break; 1815 case 'l': /* listen mode */ 1816 o_listen++; break; 1817 case 'n': /* numeric-only, no DNS lookups */ 1818 o_nflag++; break; 1819 case 'o': /* hexdump log */ 1820 stage = (unsigned char *) optarg; 1821 o_wfile++; break; 1822 case 'p': /* local source port */ 1823 o_lport = getportpoop (optarg, 0); 1824 if (o_lport == 0) 1825 bail ("invalid local port %s", optarg); 1826 break; 1827 case 'r': /* randomize various things */ 1828 o_random++; break; 1829 case 's': /* local source address */ 1830 /* do a full lookup [since everything else goes through the same mill], 1831 unless -n was previously specified. In fact, careful placement of -n can 1832 be useful, so we'll still pass o_nflag here instead of forcing numeric. */ 1833 wherefrom = gethostpoop (optarg, o_nflag); 1834 ouraddr = &wherefrom->iaddrs[0]; 1835 break; 1836 #ifdef TELNET 1837 case 't': /* do telnet fakeout */ 1838 o_tn++; break; 1839 #endif /* TELNET */ 1840 1841 case 'c': /* do telnet fakeout */ 1842 o_crlf++; break; 1843 case 'u': /* use UDP */ 1844 o_udpmode++; break; 1845 case 'v': /* verbose */ 1846 o_verbose++; break; 1847 case 'w': /* wait time */ 1848 o_wait = atoi (optarg); 1849 if (o_wait <= 0) 1850 bail ("invalid wait-time %s", optarg); 1851 timer1 = (struct timeval *) Hmalloc (sizeof (struct timeval)); 1852 timer2 = (struct timeval *) Hmalloc (sizeof (struct timeval)); 1853 timer1->tv_sec = o_wait; /* we need two. see readwrite()... */ 1854 break; 1855 case 'z': /* little or no data xfer */ 1856 o_zero++; 1857 break; 1858 default: 1859 errno = 0; 1860 bail ("nc -h for help"); 1861 } /* switch x */ 1862 } /* while getopt */ 1863 1864 /* other misc initialization */ 1865 #ifndef WIN32 /* Win32 doesn't like to mix file handles and sockets */ 1866 Debug (("fd_set size %d", sizeof (*ding1))) /* how big *is* it? */ 1867 FD_SET (0, ding1); /* stdin *is* initially open */ 1868 #endif 1869 if (o_random) { 1870 SRAND (time (0)); 1871 randports = Hmalloc (65536); /* big flag array for ports */ 1872 } 1873 #ifdef GAPING_SECURITY_HOLE 1874 if (pr00gie) { 1875 close (0); /* won't need stdin */ 1876 o_wfile = 0; /* -o with -e is meaningless! */ 1877 ofd = 0; 1878 } 1879 #endif /* G_S_H */ 1880 if (o_wfile) { 1881 ofd = open (stage, O_WRONLY | O_CREAT | O_TRUNC, 0664); 1882 if (ofd <= 0) /* must be > extant 0/1/2 */ 1883 bail ("can't open %s", stage); 1884 stage = (unsigned char *) Hmalloc (100); 1885 } 1886 1887 1888 /* optind is now index of first non -x arg */ 1889 Debug (("after go: x now %c, optarg %x optind %d", x, optarg, optind)) 1890 /* Debug (("optind up to %d at host-arg %s", optind, argv[optind])) */ 1891 /* gonna only use first addr of host-list, like our IQ was normal; if you wanna 1892 get fancy with addresses, look up the list yourself and plug 'em in for now. 1893 unless we finally implement -a, that is. */ 1894 if (argv[optind]) 1895 whereto = gethostpoop (argv[optind], o_nflag); 1896 if (whereto && whereto->iaddrs) 1897 themaddr = &whereto->iaddrs[0]; 1898 if (themaddr) 1899 optind++; /* skip past valid host lookup */ 1900 errno = 0; 1901 #ifndef WIN32 1902 h_errno = 0; 1903 #endif 1904 1905 /* Handle listen mode here, and exit afterward. Only does one connect; 1906 this is arguably the right thing to do. A "persistent listen-and-fork" 1907 mode a la inetd has been thought about, but not implemented. A tiny 1908 wrapper script can handle such things... */ 1909 if (o_listen) { 1910 curport = 0; /* rem port *can* be zero here... */ 1911 if (argv[optind]) { /* any rem-port-args? */ 1912 curport = getportpoop (argv[optind], 0); 1913 if (curport == 0) /* if given, demand correctness */ 1914 bail ("invalid port %s", argv[optind]); 1915 } /* if port-arg */ 1916 netfd = dolisten (themaddr, curport, ouraddr, o_lport); 1917 /* dolisten does its own connect reporting, so we don't holler anything here */ 1918 if (netfd > 0) { 1919 #ifdef GAPING_SECURITY_HOLE 1920 if (pr00gie) /* -e given? */ 1921 doexec (netfd); 1922 #ifdef WIN32 1923 if (!pr00gie) // doexec does the read/write for win32 1924 #endif 1925 1926 #endif /* GAPING_SECURITY_HOLE */ 1927 x = readwrite (netfd); /* it even works with UDP! */ 1928 if (o_verbose > 1) /* normally we don't care */ 1929 holler (wrote_txt, wrote_net, wrote_out); 1930 if (cycle == 1) 1931 goto recycle; 1932 exit (x); /* "pack out yer trash" */ 1933 } else 1934 bail ("no connection"); 1935 } /* o_listen */ 1936 1937 /* fall thru to outbound connects. Now we're more picky about args... */ 1938 if (! themaddr) 1939 bail ("no destination"); 1940 if (argv[optind] == NULL) 1941 bail ("no port[s] to connect to"); 1942 if (argv[optind + 1]) /* look ahead: any more port args given? */ 1943 Single = 0; /* multi-mode, case A */ 1944 ourport = o_lport; /* which can be 0 */ 1945 1946 /* everything from here down is treated as as ports and/or ranges thereof, so 1947 it's all enclosed in this big ol' argv-parsin' loop. Any randomization is 1948 done within each given *range*, but in separate chunks per each succeeding 1949 argument, so we can control the pattern somewhat. */ 1950 while (argv[optind]) { 1951 hiport = loport = 0; 1952 cp = strchr (argv[optind], '-'); /* nn-mm range? */ 1953 if (cp) { 1954 *cp = '\0'; 1955 cp++; 1956 hiport = getportpoop (cp, 0); 1957 if (hiport == 0) 1958 bail ("invalid port %s", cp); 1959 } /* if found a dash */ 1960 loport = getportpoop (argv[optind], 0); 1961 if (loport == 0) 1962 bail ("invalid port %s", argv[optind]); 1963 if (hiport > loport) { /* was it genuinely a range? */ 1964 Single = 0; /* multi-mode, case B */ 1965 curport = hiport; /* start high by default */ 1966 if (o_random) { /* maybe populate the random array */ 1967 loadports (randports, loport, hiport); 1968 curport = nextport (randports); 1969 } 1970 } else /* not a range, including args like "25-25" */ 1971 curport = loport; 1972 Debug (("Single %d, curport %d", Single, curport)) 1973 1974 /* Now start connecting to these things. curport is already preloaded. */ 1975 while (loport <= curport) { 1976 if ((! o_lport) && (o_random)) { /* -p overrides random local-port */ 1977 ourport = (RAND() & 0xffff); /* random local-bind -- well above */ 1978 if (ourport < 8192) /* resv and any likely listeners??? */ 1979 ourport += 8192; /* xxx: may still conflict; use -s? */ 1980 } 1981 curport = getportpoop (NULL, curport); 1982 netfd = doconnect (themaddr, curport, ouraddr, ourport); 1983 Debug (("netfd %d from port %d to port %d", netfd, ourport, curport)) 1984 if (netfd > 0) 1985 if (o_zero && o_udpmode) /* if UDP scanning... */ 1986 netfd = udptest (netfd, themaddr); 1987 if (netfd > 0) { /* Yow, are we OPEN YET?! */ 1988 x = 0; /* pre-exit status */ 1989 holler ("%s [%s] %d (%s) open", 1990 whereto->name, whereto->addrs[0], curport, portpoop->name); 1991 #ifdef GAPING_SECURITY_HOLE 1992 if (pr00gie) /* exec is valid for outbound, too */ 1993 doexec (netfd); 1994 #endif /* GAPING_SECURITY_HOLE */ 1995 if (! o_zero) 1996 #ifdef WIN32 1997 #ifdef GAPING_SECURITY_HOLE 1998 if (!pr00gie) // doexec does the read/write for win32 1999 #endif 2000 #endif 2001 x = readwrite (netfd); /* go shovel shit */ 2002 } else { /* no netfd... */ 2003 x = 1; /* preload exit status for later */ 2004 /* if we're scanning at a "one -v" verbosity level, don't print refusals. 2005 Give it another -v if you want to see everything. */ 2006 #ifdef WIN32 2007 if ((Single || (o_verbose > 1)) || (h_errno != WSAECONNREFUSED)) 2008 #else 2009 if ((Single || (o_verbose > 1)) || (errno != ECONNREFUSED)) 2010 #endif 2011 holler ("%s [%s] %d (%s)", 2012 whereto->name, whereto->addrs[0], curport, portpoop->name); 2013 } /* if netfd */ 2014 #ifdef WIN32 2015 shutdown(netfd, 0x02); /* Kirby */ 2016 closesocket (netfd); /* just in case we didn't already */ 2017 #else 2018 close (netfd); /* just in case we didn't already */ 2019 #endif 2020 if (o_interval) 2021 sleep (o_interval); /* if -i, delay between ports too */ 2022 if (o_random) 2023 curport = nextport (randports); 2024 else 2025 curport--; /* just decrement... */ 2026 } /* while curport within current range */ 2027 optind++; 2028 } /* while remaining port-args -- end of big argv-ports loop*/ 2029 2030 errno = 0; 2031 if (o_verbose > 1) /* normally we don't care */ 2032 holler ("sent %d, rcvd %d", wrote_net, wrote_out); 2033 2034 #ifdef WIN32 2035 WSACleanup(); 2036 #endif 2037 2038 if (cycle == 1) 2039 goto recycle; 2040 2041 if (Single) 2042 exit (x); /* give us status on one connection */ 2043 exit (0); /* otherwise, we're just done */ 2044 return(0); 2045 } /* main */ 2046 2047 #ifdef HAVE_HELP /* unless we wanna be *really* cryptic */ 2048 /* helpme : 2049 the obvious */ 2050 int helpme() 2051 { 2052 o_verbose = 1; 2053 holler ("[v1.12 NT http://eternallybored.org/misc/netcat/]\n\ 2054 connect to somewhere: nc [-options] hostname port[s] [ports] ... \n\ 2055 listen for inbound: nc -l -p port [options] [hostname] [port]\n\ 2056 options:"); 2057 holler ("\ 2058 -d detach from console, background mode\n"); 2059 2060 #ifdef GAPING_SECURITY_HOLE /* needs to be separate holler() */ 2061 holler ("\ 2062 -e prog inbound program to exec [dangerous!!]"); 2063 #endif 2064 holler ("\ 2065 -g gateway source-routing hop point[s], up to 8\n\ 2066 -G num source-routing pointer: 4, 8, 12, ...\n\ 2067 -h this cruft\n\ 2068 -i secs delay interval for lines sent, ports scanned\n\ 2069 -l listen mode, for inbound connects\n\ 2070 -L listen harder, re-listen on socket close\n\ 2071 -n numeric-only IP addresses, no DNS\n\ 2072 -o file hex dump of traffic\n\ 2073 -p port local port number\n\ 2074 -r randomize local and remote ports\n\ 2075 -s addr local source address"); 2076 #ifdef TELNET 2077 holler ("\ 2078 -t answer TELNET negotiation"); 2079 #endif 2080 holler ("\ 2081 -c send CRLF instead of just LF\n\ 2082 -u UDP mode\n\ 2083 -v verbose [use twice to be more verbose]\n\ 2084 -w secs timeout for connects and final net reads\n\ 2085 -z zero-I/O mode [used for scanning]"); 2086 bail ("port numbers can be individual or ranges: m-n [inclusive]"); 2087 return(0); 2088 } /* helpme */ 2089 #endif /* HAVE_HELP */ 2090 2091 2092 2093 2094 /* None genuine without this seal! _H*/