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

📄 netcat.c

📁 一个nc的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
  if (o_wait)
    sleep (o_wait);
  else {
/* use the tcp-ping trick: try connecting to a normally refused port, which
   causes us to block for the time that SYN gets there and RST gets back.
   Not completely reliable, but it *does* mostly work. */
    o_udpmode = 0;			/* so doconnect does TCP this time */
/* Set a temporary connect timeout, so packet filtration doesnt cause
   us to hang forever, and hit it */
    o_wait = 5;				/* XXX: enough to notice?? */
    rr = doconnect (where, SLEAZE_PORT, 0, 0);
    if (rr > 0)
#ifdef WIN32
	  closesocket (rr);
#else
      close (rr);			/* in case it *did* open */
#endif
    o_wait = 0;				/* reset it */
    o_udpmode++;			/* we *are* still doing UDP, right? */
  } /* if o_wait */
  errno = 0;				/* clear from sleep */
#ifdef WIN32
  rr = send (fd, bigbuf_in, 1, 0);
#else
  rr = write (fd, bigbuf_in, 1);
#endif
  if (rr == 1)				/* if write error, no UDP listener */
    return (fd);
#ifdef WIN32
  closesocket (fd);
#else
  close (fd);				/* use it or lose it! */
#endif
  return (-1);
} /* udptest */

/* oprint :
   Hexdump bytes shoveled either way to a running logfile, in the format:
D offset       -  - - - --- 16 bytes --- - - -  -     # .... ascii .....
   where "which" sets the direction indicator, D:
	0 -- sent to network, or ">"
	1 -- rcvd and printed to stdout, or "<"
   and "buf" and "n" are data-block and length.  If the current block generates
   a partial line, so be it; we *want* that lockstep indication of who sent
   what when.  Adapted from dgaudet's original example -- but must be ripping
   *fast*, since we don't want to be too disk-bound... */
void oprint (which, buf, n)
  int which;
  char * buf;
  int n;
{
  int bc;			/* in buffer count */
  int obc;			/* current "global" offset */
  int soc;			/* stage write count */
  register unsigned char * p;	/* main buf ptr; m.b. unsigned here */
  register unsigned char * op;	/* out hexdump ptr */
  register unsigned char * a;	/* out asc-dump ptr */
  register int x;
  register unsigned int y;

  if (! ofd)
    bail ("oprint called with no open fd?!");
  if (n == 0)
    return;

  op = stage;
  if (which) {
    *op = '<';
    obc = wrote_out;		/* use the globals! */
  } else {
    *op = '>';
    obc = wrote_net;
  }
  op++;				/* preload "direction" */
  *op = ' ';
  p = (unsigned char *) buf;
  bc = n;
  stage[59] = '#';		/* preload separator */
  stage[60] = ' ';

  while (bc) {			/* for chunk-o-data ... */
    x = 16;
    soc = 78;			/* len of whole formatted line */
    if (bc < x) {
      soc = soc - 16 + bc;	/* fiddle for however much is left */
      x = (bc * 3) + 11;	/* 2 digits + space per, after D & offset */
      op = &stage[x];
      x = 16 - bc;
      while (x) {
	*op++ = ' ';		/* preload filler spaces */
	*op++ = ' ';
	*op++ = ' ';
	x--;
      }
      x = bc;			/* re-fix current linecount */
    } /* if bc < x */

    bc -= x;			/* fix wrt current line size */
    sprintf (&stage[2], "%8.8x ", obc);		/* xxx: still slow? */
    obc += x;			/* fix current offset */
    op = &stage[11];		/* where hex starts */
    a = &stage[61];		/* where ascii starts */

    while (x) {			/* for line of dump, however long ... */
      y = (int)(*p >> 4);	/* hi half */
      *op = hexnibs[y];
      op++;
      y = (int)(*p & 0x0f);	/* lo half */
      *op = hexnibs[y];
      op++;
      *op = ' ';
      op++;
      if ((*p > 31) && (*p < 127))
	*a = *p;		/* printing */
      else
	*a = '.';		/* nonprinting, loose def */
      a++;
      p++;
      x--;
    } /* while x */
    *a = '\n';			/* finish the line */
    x = write (ofd, stage, soc);
    if (x < 0)
      bail ("ofd write err");
  } /* while bc */
} /* oprint */

#ifdef TELNET
USHORT o_tn = 0;		/* global -t option */

/* atelnet :
   Answer anything that looks like telnet negotiation with don't/won't.
   This doesn't modify any data buffers, update the global output count,
   or show up in a hexdump -- it just shits into the outgoing stream.
   Idea and codebase from Mudge@l0pht.com. */
void atelnet (buf, size)
  unsigned char * buf;		/* has to be unsigned here! */
  unsigned int size;
{
  static unsigned char obuf [4];  /* tiny thing to build responses into */
  register int x;
  register unsigned char y;
  register unsigned char * p;

  y = 0;
  p = buf;
  x = size;
  while (x > 0) {
    if (*p != 255)			/* IAC? */
      goto notiac;
    obuf[0] = 255;
    p++; x--;
    if ((*p == 251) || (*p == 252))	/* WILL or WONT */
      y = 254;				/* -> DONT */
    if ((*p == 253) || (*p == 254))	/* DO or DONT */
      y = 252;				/* -> WONT */
    if (y) {
      obuf[1] = y;
      p++; x--;
      obuf[2] = *p;			/* copy actual option byte */
#ifdef WIN32
	  (void) send (netfd, obuf, 3, 0);	/* one line, or the whole buffer */
#else
      (void) write (netfd, obuf, 3);
#endif
/* if one wanted to bump wrote_net or do a hexdump line, here's the place */
      y = 0;
    } /* if y */
notiac:
    p++; x--;
  } /* while x */
} /* atelnet */
#endif /* TELNET */


/* readwrite :
   handle stdin/stdout/network I/O.  Bwahaha!! -- the select loop from hell.
   In this instance, return what might become our exit status. */
int readwrite (fd)
#ifdef WIN32
  unsigned int fd;
#else
  int fd;
#endif
{
  register int rr;
  register char * zp;		/* stdin buf ptr */
  register char * np;		/* net-in buf ptr */
  unsigned int rzleft;
  unsigned int rnleft;
  USHORT netretry;		/* net-read retry counter */
  USHORT wretry;		/* net-write sanity counter */
  USHORT wfirst;		/* one-shot flag to skip first net read */

#ifdef WIN32 /* (weld) WIN32 must poll because of weak stdin handling so we need a
				short timer */
  struct timeval timer3;
  int istty;
  time_t start, current;
  int foo;

  timer3.tv_sec = 0;
  timer3.tv_usec = 1000;

  /* save the time so we can bail when we reach timeout */
  time( &start );


  /* sets stdin and stdout to binary so no crlf translation if its a tty */
  if (!_isatty( 1 ))
	_setmode( 1, _O_BINARY ); 

  if ((istty = _isatty( 0 )) == FALSE)
	_setmode( 0, _O_BINARY ); /* (weld) I think we want to do this */

#endif

/* if you don't have all this FD_* macro hair in sys/types.h, you'll have to
   either find it or do your own bit-bashing: *ding1 |= (1 << fd), etc... */
#ifndef WIN32  /* fd is not implemented as a real file handle in WIN32 */
  if (fd > FD_SETSIZE) {
    holler ("Preposterous fd value %d", fd);
    return (1);
  }
#endif
  FD_SET (fd, ding1);		/* global: the net is open */
  netretry = 2;
  wfirst = 0;
  rzleft = rnleft = 0;
  if (insaved) {
    rzleft = insaved;		/* preload multi-mode fakeouts */
    zp = bigbuf_in;

	wfirst = 1;
    if (Single)			/* if not scanning, this is a one-off first */
      insaved = 0;		/* buffer left over from argv construction, */
    else {
      FD_CLR (0, ding1);	/* OR we've already got our repeat chunk, */
      close (0);		/* so we won't need any more stdin */
    } /* Single */
  } /* insaved */
  if (o_interval)
    sleep (o_interval);		/* pause *before* sending stuff, too */
  errno = 0;			/* clear from sleep */
#ifdef WIN32
  WSASetLastError(0);
#endif

/* and now the big ol' select shoveling loop ... */
  while (FD_ISSET (fd, ding1)) {	/* i.e. till the *net* closes! */
    wretry = 8200;			/* more than we'll ever hafta write */
    if (wfirst) {			/* any saved stdin buffer? */
      wfirst = 0;			/* clear flag for the duration */
      goto shovel;			/* and go handle it first */
    }
    *ding2 = *ding1;			/* FD_COPY ain't portable... */
	
/* some systems, notably linux, crap into their select timers on return, so
   we create a expendable copy and give *that* to select.  *Fuck* me ... */
    if (timer1)
      memcpy (timer2, timer1, sizeof (struct timeval));
#ifdef WIN32 /* (weld)we must use our own small timeval to poll */
    rr = select (16, ding2, 0, 0, &timer3);	/* here it is, kiddies */
#else
    rr = select (16, ding2, 0, 0, timer2);	/* here it is, kiddies */
#endif
    if (rr < 0) {
#ifdef WIN32
		if (h_errno != WSAEINTR) {		/* might have gotten ^Zed, etc ?*/
#else
		if (errno != EINTR) {		/* might have gotten ^Zed, etc ?*/
#endif
		  foo = h_errno;
		  holler ("select fuxored");
#ifdef WIN32
		  closesocket (fd);
#else
		  close (fd);
#endif
		  return (1);
		}
    } /* select fuckup */
/* if we have a timeout AND stdin is closed AND we haven't heard anything
   from the net during that time, assume it's dead and close it too. */
#ifndef WIN32  /* (weld) need to write some code here */
    if (rr == 0) {
	if (! FD_ISSET (0, ding1))
	  netretry--;			/* we actually try a coupla times. */
	if (! netretry) {
	  if (o_verbose > 1)		/* normally we don't care */
	    holler ("net timeout");
	  close (fd);
	  return (0);			/* not an error! */
		}
    } /* select timeout */
#else
	if (rr == 0) {
		time( &current );
		if ( o_wait > 0 && (current - start) > timer1->tv_sec)	{
			if (o_verbose > 1)		/* normally we don't care */
				holler ("net timeout");
			closesocket (fd);
			FD_ZERO(ding1);
			WSASetLastError(0); 
			return (0);			/* not an error! */
		}
    } /* select timeout */
#endif
/* xxx: should we check the exception fds too?  The read fds seem to give
   us the right info, and none of the examples I found bothered. */

/* Ding!!  Something arrived, go check all the incoming hoppers, net first */
    if (FD_ISSET (fd, ding2)) {		/* net: ding! */
#ifdef WIN32
	// reset timer
	time( &start );
	rr = farm9crypt_read( fd, bigbuf_net, BIGSIZ ); //recv (fd, bigbuf_net, BIGSIZ, 0);
//	rr = recv (fd, bigbuf_net, BIGSIZ, 0);
#else
	rr = read (fd, bigbuf_net, BIGSIZ);
#endif
	if (rr <= 0) {
	  FD_CLR (fd, ding1);		/* net closed, we'll finish up... */
	  rzleft = 0;			/* can't write anymore: broken pipe */
	} else {
	  rnleft = rr;
	  np = bigbuf_net;
#ifdef TELNET
	  if (o_tn)
	    atelnet (np, rr);		/* fake out telnet stuff */
#endif /* TELNET */
	} /* if rr */
Debug (("got %d from the net, errno %d", rr, errno))
    } /* net:ding */

/* if we're in "slowly" mode there's probably still stuff in the stdin
   buffer, so don't read unless we really need MORE INPUT!  MORE INPUT! */
    if (rzleft)
	goto shovel;

/* okay, suck more stdin */
#ifndef WIN32
    if (FD_ISSET (0, ding2)) {		/* stdin: ding! */
	rr = read (0, bigbuf_in, BIGSIZ);

/* xxx: maybe make reads here smaller for UDP mode, so that the subsequent
   writes are smaller -- 1024 or something?  "oh, frag it", etc, although
   mobygrams are kinda fun and exercise the reassembler. */
	if (rr <= 0) {			/* at end, or fukt, or ... */
	  FD_CLR (0, ding1);		/* disable and close stdin */
	  close (0);
	} else {
	  rzleft = rr;
	  zp = bigbuf_in;
/* special case for multi-mode -- we'll want to send this one buffer to every
   open TCP port or every UDP attempt, so save its size and clean up stdin */
	  if (! Single) {		/* we might be scanning... */
	    insaved = rr;		/* save len */
	    FD_CLR (0, ding1);		/* disable further junk from stdin */
	    close (0);			/* really, I mean it */
	  } /* Single */
	} /* if rr/read */
    } /* stdin:ding */
#else
	if (istty) {
		/* (weld) cool, we can actually peek a tty and not have to block */
		/* needs to be cleaned up */
		if (kbhit()) {
/*			bigbuf_in[0] = getche(); */
			gets(bigbuf_in);
		  	strcat(bigbuf_in, "\n");
			rr = strlen(bigbuf_in);
			rzleft = rr;
			zp = bigbuf_in;
/* special case for multi-mode -- we'll want to send this one buffer to every
   open TCP port or every UDP attempt, so save its size and clean up stdin */
			if (! Single) {		/* we might be scanning... */
				insaved = rr;		/* save len */
				close (0);			/* really, I mean it */
			}
		}
	} else {
		/* (weld) this is gonna block until a <cr> so it kinda sucks */
		rr = read (0, bigbuf_in, BIGSIZ);
		if (rr <= 0) {			/* at end, or fukt, or ... */
			close (0);
		} else {
			rzleft = rr;
			zp = bigbuf_in;
/* special case for multi-mode -- we'll want to send this one buffer to every
   open TCP port or every UDP attempt, so save its size and clean up stdin */
			if (! Single) {		/* we might be scanning... */

⌨️ 快捷键说明

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