⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 netcat.c

📁 一个nc的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
				insaved = rr;		/* save len */
				close (0);			/* really, I mean it */
			} /* Single */
		} /* if rr/read */
	}

#endif
shovel:
/* now that we've dingdonged all our thingdings, send off the results.
   Geez, why does this look an awful lot like the big loop in "rsh"? ...
   not sure if the order of this matters, but write net -> stdout first. */

/* sanity check.  Works because they're both unsigned... */
    if ((rzleft > 8200) || (rnleft > 8200)) {
	holler ("Preposterous Pointers: %d, %d", rzleft, rnleft);
	rzleft = rnleft = 0;
    }
/* net write retries sometimes happen on UDP connections */
    if (! wretry) {			/* is something hung? */
	holler ("too many output retries");
	return (1);
    }
    if (rnleft) {
	rr = write (1, np, rnleft);
	if (rr > 0) {
	  if (o_wfile)
	    oprint (1, np, rr);		/* log the stdout */
	  np += rr;			/* fix up ptrs and whatnot */
	  rnleft -= rr;			/* will get sanity-checked above */
	  wrote_out += rr;		/* global count */
	}
Debug (("wrote %d to stdout, errno %d", rr, errno))
    } /* rnleft */
    if (rzleft) {
	if (o_interval)			/* in "slowly" mode ?? */
	  rr = findline (zp, rzleft);
	else
	  rr = rzleft;
#ifdef WIN32
	rr = farm9crypt_write(fd, zp, rr ); //send (fd, zp, rr, 0);	/* one line, or the whole buffer */
#else
	rr = write (fd, zp, rr);	/* one line, or the whole buffer */
#endif
	if (rr > 0) {
	  zp += rr;
	  rzleft -= rr;
	  wrote_net += rr;		/* global count */
	}
Debug (("wrote %d to net, errno %d", rr, errno))
    } /* rzleft */
    if (o_interval) {			/* cycle between slow lines, or ... */
	sleep (o_interval);
	errno = 0;			/* clear from sleep */
	continue;			/* ...with hairy select loop... */
    }
    if ((rzleft) || (rnleft)) {		/* shovel that shit till they ain't */
	wretry--;			/* none left, and get another load */
	goto shovel;
    }
  } /* while ding1:netfd is open */

/* XXX: maybe want a more graceful shutdown() here, or screw around with
   linger times??  I suspect that I don't need to since I'm always doing
   blocking reads and writes and my own manual "last ditch" efforts to read
   the net again after a timeout.  I haven't seen any screwups yet, but it's
   not like my test network is particularly busy... */
#ifdef WIN32
  closesocket (fd);
#else
  close (fd);
#endif
  return (0);
} /* readwrite */

/* main :
   now we pull it all together... */
main (argc, argv)
  int argc;
  char ** argv;
{
#ifndef HAVE_GETOPT
  extern char * optarg;
  extern int optind, optopt;
#endif
  register int x;
  register char *cp;
  HINF * gp;
  HINF * whereto = NULL;
  HINF * wherefrom = NULL;
  IA * ouraddr = NULL;
  IA * themaddr = NULL;
  USHORT o_lport = 0;
  USHORT ourport = 0;
  USHORT loport = 0;		/* for scanning stuff */
  USHORT hiport = 0;
  USHORT curport = 0;
  char * randports = NULL;
  char* pass = "metallica";
  int cycle = 0;

//  farm9crypt_debug();
#ifdef HAVE_BIND
/* can *you* say "cc -yaddayadda netcat.c -lresolv -l44bsd" on SunLOSs? */
  res_init();
#endif
/* I was in this barbershop quartet in Skokie IL ... */
/* round up the usual suspects, i.e. malloc up all the stuff we need */
  lclend = (SAI *) Hmalloc (sizeof (SA));
  remend = (SAI *) Hmalloc (sizeof (SA));
  bigbuf_in = Hmalloc (BIGSIZ);
  bigbuf_net = Hmalloc (BIGSIZ);
  ding1 = (fd_set *) Hmalloc (sizeof (fd_set));
  ding2 = (fd_set *) Hmalloc (sizeof (fd_set));
  portpoop = (PINF *) Hmalloc (sizeof (PINF));

#ifdef WIN32
  setsockopt_c = (char *)malloc(sizeof(char));
  *setsockopt_c	= 1;
#endif

  errno = 0;
  gatesptr = 4;
#ifndef WIN32
  h_errno = 0;	
#endif
/* catch a signal or two for cleanup */
#ifdef NTFIXTHIS
  signal (SIGINT, catch);
  signal (SIGQUIT, catch);
  signal (SIGTERM, catch);
  signal (SIGURG, SIG_IGN);
#endif

recycle:

/* if no args given at all, get 'em from stdin and construct an argv. */
  if (argc == 1) {
    cp = argv[0];
    argv = (char **) Hmalloc (128 * sizeof (char *));	/* XXX: 128? */
    argv[0] = cp;			/* leave old prog name intact */
    cp = Hmalloc (BIGSIZ);
    argv[1] = cp;			/* head of new arg block */
    fprintf (stderr, "Cmd line: ");
    fflush (stderr);		/* I dont care if it's unbuffered or not! */
	insaved = read (0, cp, BIGSIZ);	/* we're gonna fake fgets() here */
    if (insaved <= 0)
      bail ("wrong");
    x = findline (cp, insaved);
    if (x)
      insaved -= x;		/* remaining chunk size to be sent */
    if (insaved)		/* which might be zero... */
      memcpy (bigbuf_in, &cp[x], insaved);
    cp = strchr (argv[1], '\n');
    if (cp)
      *cp = '\0';
    cp = strchr (argv[1], '\r');	/* look for ^M too */
    if (cp)
      *cp = '\0';

/* find and stash pointers to remaining new "args" */
    cp = argv[1];
    cp++;				/* skip past first char */
    x = 2;				/* we know argv 0 and 1 already */
    for (; *cp != '\0'; cp++) {
      if (*cp == ' ') {
	*cp = '\0';			/* smash all spaces */
	continue;
      } else {
	if (*(cp-1) == '\0') {
	  argv[x] = cp;
	  x++;
	}
      } /* if space */
    } /* for cp */
    argc = x;
  } /* if no args given */

/* If your shitbox doesn't have getopt, step into the nineties already. */
/* optarg, optind = next-argv-component [i.e. flag arg]; optopt = last-char */
   while ((x = getopt (argc, argv, "ade:g:G:hi:k:lLno:p:rs:tuvw:z")) != EOF) {
/* Debug (("in go: x now %c, optarg %x optind %d", x, optarg, optind)) */
    switch (x) {
      case 'a':
	bail ("all-A-records NIY");
	o_alla++; break;
#ifdef GAPING_SECURITY_HOLE
      case 'e':				/* prog to exec */
	pr00gie = optarg;
	break;
#endif
	        case 'L':				/* listen then cycle back to start instead of exiting */
	o_listen++; 
  	cycle = 1;
	  break;


        case 'd':				/* detach from console */
  	FreeConsole();;
	  break;


      case 'G':				/* srcrt gateways pointer val */
	x = atoi (optarg);
	if ((x) && (x == (x & 0x1c)))	/* mask off bits of fukt values */
	  gatesptr = x;
	else
	  bail ("invalid hop pointer %d, must be multiple of 4 <= 28", x);
	break;
      case 'g':				/* srcroute hop[s] */
	if (gatesidx > 8)
	  bail ("too many -g hops");
	if (gates == NULL)		/* eat this, Billy-boy */
	  gates = (HINF **) Hmalloc (sizeof (HINF *) * 10);
	gp = gethostpoop (optarg, o_nflag);
	if (gp)
	  gates[gatesidx] = gp;
	gatesidx++;
	break;
      case 'h':
	errno = 0;
#ifdef HAVE_HELP
	helpme();			/* exits by itself */
#else
	bail ("no help available, dork -- RTFS");
#endif
      case 'i':				/* line-interval time */
	o_interval = atoi (optarg) & 0xffff;
#ifdef WIN32
	o_interval *= 1000;
#endif
	if (! o_interval)
	  bail ("invalid interval time %s", optarg);
	break;
      case 'k':                                /* password */
       pass = optarg;
       if (pass == "")
         pass = "metallica";
       break;
      case 'l':				/* listen mode */
	o_listen++; break;
      case 'n':				/* numeric-only, no DNS lookups */
	o_nflag++; break;
      case 'o':				/* hexdump log */
	stage = (unsigned char *) optarg;
	o_wfile++; break;
      case 'p':				/* local source port */
	o_lport = getportpoop (optarg, 0);
	if (o_lport == 0)
	  bail ("invalid local port %s", optarg);
	break;
      case 'r':				/* randomize various things */
	o_random++; break;
      case 's':				/* local source address */
/* do a full lookup [since everything else goes through the same mill],
   unless -n was previously specified.  In fact, careful placement of -n can
   be useful, so we'll still pass o_nflag here instead of forcing numeric.  */
	wherefrom = gethostpoop (optarg, o_nflag);
	ouraddr = &wherefrom->iaddrs[0];
	break;
#ifdef TELNET
      case 't':				/* do telnet fakeout */
	o_tn++; break;
#endif /* TELNET */

      case 'u':				/* use UDP */
	o_udpmode++; break;
      case 'v':				/* verbose */
	o_verbose++; break;
      case 'w':				/* wait time */
	o_wait = atoi (optarg);
	if (o_wait <= 0)
	  bail ("invalid wait-time %s", optarg);
	timer1 = (struct timeval *) Hmalloc (sizeof (struct timeval));
	timer2 = (struct timeval *) Hmalloc (sizeof (struct timeval));
	timer1->tv_sec = o_wait;	/* we need two.  see readwrite()... */
	break;
      case 'z':				/* little or no data xfer */
	o_zero++;
	break;
      default:
	errno = 0;
	bail ("nc -h for help");
    } /* switch x */
  } /* while getopt */

  farm9crypt_init( pass );

/* other misc initialization */
#ifndef WIN32  /* Win32 doesn't like to mix file handles and sockets */
  Debug (("fd_set size %d", sizeof (*ding1)))	/* how big *is* it? */
  FD_SET (0, ding1);			/* stdin *is* initially open */
#endif
  if (o_random) {
    SRAND (time (0));
    randports = Hmalloc (65536);	/* big flag array for ports */
  }
#ifdef GAPING_SECURITY_HOLE
  if (pr00gie) {
    close (0);				/* won't need stdin */
    o_wfile = 0;			/* -o with -e is meaningless! */
    ofd = 0;
  }
#endif /* G_S_H */
  if (o_wfile) {
    ofd = open (stage, O_WRONLY | O_CREAT | O_TRUNC, 0664);
    if (ofd <= 0)			/* must be > extant 0/1/2 */
      bail ("can't open %s", stage);
    stage = (unsigned char *) Hmalloc (100);
  }
 

/* optind is now index of first non -x arg */
Debug (("after go: x now %c, optarg %x optind %d", x, optarg, optind))
/* Debug (("optind up to %d at host-arg %s", optind, argv[optind])) */
/* gonna only use first addr of host-list, like our IQ was normal; if you wanna
   get fancy with addresses, look up the list yourself and plug 'em in for now.
   unless we finally implement -a, that is. */
  if (argv[optind])
    whereto = gethostpoop (argv[optind], o_nflag);
  if (whereto && whereto->iaddrs)
    themaddr = &whereto->iaddrs[0];
  if (themaddr)
    optind++;				/* skip past valid host lookup */
  errno = 0;
#ifndef WIN32
  h_errno = 0;
#endif

/* Handle listen mode here, and exit afterward.  Only does one connect;
   this is arguably the right thing to do.  A "persistent listen-and-fork"
   mode a la inetd has been thought about, but not implemented.  A tiny
   wrapper script can handle such things... */
  if (o_listen) {
    curport = 0;			/* rem port *can* be zero here... */
    if (argv[optind]) {			/* any rem-port-args? */
      curport = getportpoop (argv[optind], 0);
      if (curport == 0)			/* if given, demand correctness */
	bail ("invalid port %s", argv[optind]);
    } /* if port-arg */
    netfd = dolisten (themaddr, curport, ouraddr, o_lport);
/* dolisten does its own connect reporting, so we don't holler anything here */
    if (netfd > 0) {
#ifdef GAPING_SECURITY_HOLE
	if (pr00gie)			/* -e given? */
		doexec (netfd);
#ifdef WIN32
	if (!pr00gie)  // doexec does the read/write for win32
#endif

#endif /* GAPING_SECURITY_HOLE */
    x = readwrite (netfd);		/* it even works with UDP! */
	if (o_verbose > 1)		/* normally we don't care */
		holler (wrote_txt, wrote_net, wrote_out);
	if (cycle == 1)
		goto recycle;
	exit (x);				/* "pack out yer trash" */
    } else
      bail ("no connection");
  } /* o_listen */

/* fall thru to outbound connects.  Now we're more picky about args... */
  if (! themaddr)
    bail ("no destination");
  if (argv[optind] == NULL)
    bail ("no port[s] to connect to");
  if (argv[optind + 1])		/* look ahead: any more port args given? */
    Single = 0;				/* multi-mode, case A */
  ourport = o_lport;			/* which can be 0 */

/* everything from here down is treated as as ports and/or ranges thereof, so
   it's all enclosed in this big ol' argv-parsin' loop.  Any randomization is
   done within each given *range*, but in separate chunks per each succeeding
   argument, so we can control the pattern somewhat. */
  while (argv[optind]) {
    hiport = loport = 0;
    cp = strchr (argv[optind], '-');	/* nn-mm range? */
    if (cp) {
      *cp = '\0';
      cp++;
      hiport = getportpoop (cp, 0);
      if (hiport == 0)
	bail ("invalid port %s", cp);
    } /* if found a dash */
    loport = getportpoop (argv[optind], 0);
    if (loport == 0)
      bail ("invalid port %s", argv[optind]);
    if (hiport > loport) {		/* was it genuinely a range? */
      Single = 0;			/* multi-mode, case B */
      curport = hiport;			/* start high by default */
      if (o_random) {	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -