📄 netcat.c
字号:
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( ¤t );
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 + -