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

📄 netcat.c

📁 一个nc的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Netcat 1.00 951010

   A damn useful little "backend" utility begun 950915 or thereabouts,
   as *Hobbit*'s first real stab at some sockets programming.  Something that
   should have and indeed may have existed ten years ago, but never became a
   standard Unix utility.  IMHO, "nc" could take its place right next to cat,
   cp, rm, mv, dd, ls, and all those other cryptic and Unix-like things.

   Read the README for the whole story, doc, applications, etc.

   Layout:
	conditional includes:
	includes:
	handy defines:
	globals:
	malloced globals:
	cmd-flag globals:
	support routines:
	main:

  todo:
	more of the portability swamp, and an updated generic.h
	frontend progs to generate various packets, raw or otherwise...
	char-mode [cbreak, fcntl-unbuffered, etc...]
	connect-to-all-A-records hack
  bluesky:
	RAW mode!
	backend progs to grab a pty and look like a real telnetd?!

  Modified by jojo@farm9.com, 19-Sept-2000 -- added twofish encrypted pipe,
    uses hardcoded key generated by "metallica"
  Bill Weiss -- added "-k" option (actually added -P, but I changed it because
    Linux version already had the option as "-k")
*/

#include "generic.h"		/* same as with L5, skey, etc */
#include "farm9crypt.h"

/* conditional includes -- a very messy section: */
/* #undef _POSIX_SOURCE		/* might need this for something? */
#define HAVE_BIND		/* XXX -- for now, see below... */
#define HAVE_HELP		/* undefine if you dont want the help text */
/* #define ANAL			/* if you want case-sensitive DNS matching */
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#else
#include <malloc.h>		/* xxx: or does it live in sys/ ?? */
#endif

/* have to do this *before* including types.h. xxx: Linux still has it wrong */
#ifdef FD_SETSIZE		/* should be in types.h, butcha never know. */
#undef FD_SETSIZE		/* if we ever need more than 16 active */
#endif				/* fd's, something is horribly wrong! */
#ifdef WIN32
#define FD_SETSIZE 64		/* WIN32 does this as an array not a bitfield and it likes 64 */
#else
#define FD_SETSIZE 16		/* <-- this'll give us a long anyways, wtf */
#endif
#include <sys/types.h>		/* *now* do it.  Sigh, this is broken */


#ifdef WIN32
#undef HAVE_RANDOM
#undef IP_OPTIONS
#undef SO_REUSEPORT
#include <windows.h>
#endif


#ifdef HAVE_RANDOM
#define SRAND srandom
#define RAND random
#else
#define SRAND srand
#define RAND rand
#endif /* HAVE_RANDOM */

/* xxx: these are rsh leftovers, move to new generic.h */
/* will we even need any nonblocking shit?  Doubt it. */
/* get FIONBIO from sys/filio.h, so what if it is a compatibility feature */
/* #include <sys/filio.h> */
/*
#include <sys/ioctl.h>
#include <sys/file.h>
*/

/* includes: */

#ifdef WIN32
#include "getopt.h"
#define sleep			_sleep
#define strcasecmp		strcmpi
#define EADDRINUSE		WSAEADDRINUSE
#define ETIMEDOUT		WSAETIMEDOUT
#define ECONNREFUSED	WSAECONNREFUSED
#endif

#ifndef WIN32
#include <sys/time.h>		/* timeval, time_t */
#else
#include <time.h>
#endif

#include <setjmp.h>		/* jmp_buf et al */

#ifndef WIN32
#include <sys/socket.h>		/* basics, SO_ and AF_ defs, sockaddr, ... */
#include <netinet/in.h>		/* sockaddr_in, htons, in_addr */
#include <netinet/in_systm.h>	/* misc crud that netinet/ip.h references */
#include <netinet/ip.h>		/* IPOPT_LSRR, header stuff */
#include <netdb.h>		/* hostent, gethostby*, getservby* */
#include <arpa/inet.h>		/* inet_ntoa */
#else
#include <fcntl.h>
#include <io.h>
#include <conio.h>
#include <winsock.h>
#endif

#include <stdio.h>
#include <string.h>		/* strcpy, strchr, yadda yadda */
#include <errno.h>
#include <signal.h>

/* handy stuff: */
#define SA struct sockaddr	/* socket overgeneralization braindeath */
#define SAI struct sockaddr_in	/* ... whoever came up with this model */
#define IA struct in_addr	/* ... should be taken out and shot, */
				/* ... not that TLI is any better.  sigh.. */
#define SLEAZE_PORT 31337	/* for UDP-scan RTT trick, change if ya want */
#define USHORT unsigned short	/* use these for options an' stuff */
#define BIGSIZ 8192		/* big buffers */
#define SMALLSIZ 256		/* small buffers, hostnames, etc */

#ifndef INADDR_NONE
#define INADDR_NONE 0xffffffff
#endif
#ifdef MAXHOSTNAMELEN
#undef MAXHOSTNAMELEN		/* might be too small on aix, so fix it */
#endif
#define MAXHOSTNAMELEN 256
struct host_poop {
  char name[MAXHOSTNAMELEN];	/* dns name */
  char addrs[8][24];		/* ascii-format IP addresses */
  struct in_addr iaddrs[8];	/* real addresses: in_addr.s_addr: ulong */
};
#define HINF struct host_poop
struct port_poop {
  char name [64];		/* name in /etc/services */
  char anum [8];		/* ascii-format number */
  USHORT num;			/* real host-order number */
};
#define PINF struct port_poop

/* globals: */
jmp_buf jbuf;			/* timer crud */
int jval = 0;			/* timer crud */
int netfd = -1;
int ofd = 0;			/* hexdump output fd */
static char unknown[] = "(UNKNOWN)";
static char p_tcp[] = "tcp";	/* for getservby* */
static char p_udp[] = "udp";

#ifndef WIN32
#ifdef HAVE_BIND
extern int h_errno;
#endif
#endif
int gatesidx = 0;		/* LSRR hop count */
int gatesptr = 4;		/* initial LSRR pointer, settable */
USHORT Single = 1;		/* zero if scanning */
unsigned int insaved = 0;	/* stdin-buffer size for multi-mode */
unsigned int wrote_out = 0;	/* total stdout bytes */
unsigned int wrote_net = 0;	/* total net bytes */
static char wrote_txt[] = " sent %d, rcvd %d";
static char hexnibs[20] = "0123456789abcdef  ";

/* will malloc up the following globals: */
struct timeval * timer1 = NULL;
struct timeval * timer2 = NULL;
SAI * lclend = NULL;		/* sockaddr_in structs */
SAI * remend = NULL;
HINF ** gates = NULL;		/* LSRR hop hostpoop */
char * optbuf = NULL;		/* LSRR or sockopts */
char * bigbuf_in;		/* data buffers */
char * bigbuf_net;
fd_set * ding1;			/* for select loop */
fd_set * ding2;
PINF * portpoop = NULL;		/* for getportpoop / getservby* */
unsigned char * stage = NULL;	/* hexdump line buffer */

#ifdef WIN32
  char * setsockopt_c;
int nnetfd;
#endif

/* global cmd flags: */
USHORT o_alla = 0;
unsigned int o_interval = 0;
USHORT o_listen = 0;
USHORT o_nflag = 0;
USHORT o_wfile = 0;
USHORT o_random = 0;
USHORT o_udpmode = 0;
USHORT o_verbose = 0;
unsigned int o_wait = 0;
USHORT o_zero = 0;

/* Debug macro: squirt whatever to stderr and sleep a bit so we can see it go
   by.  need to call like Debug ((stuff)) [with no ; ] so macro args match!
   Beware: writes to stdOUT... */
#ifdef DEBUG
#define Debug(x) printf x; printf ("\n"); fflush (stdout); sleep (1);
#else
#define Debug(x)	/* nil... */
#endif

/* support routines -- the bulk of this thing.  Placed in such an order that
   we don't have to forward-declare anything: */

int helpme(); /* oop */

#ifdef WIN32

/* res_init
   winsock needs to be initialized. Might as well do it as the res_init
   call for Win32 */

void res_init()
{
WORD wVersionRequested; 
WSADATA wsaData; 
int err; 
wVersionRequested = MAKEWORD(1, 1); 
 
err = WSAStartup(wVersionRequested, &wsaData); 
 
if (err != 0) 
    /* Tell the user that we couldn't find a useable */ 
    /* winsock.dll.     */ 
    return; 
 
/* Confirm that the Windows Sockets DLL supports 1.1.*/ 
/* Note that if the DLL supports versions greater */ 
/* than 1.1 in addition to 1.1, it will still return */ 
/* 1.1 in wVersion since that is the version we */ 
/* requested. */ 
 
if ( LOBYTE( wsaData.wVersion ) != 1 || 
        HIBYTE( wsaData.wVersion ) != 1 ) { 
    /* Tell the user that we couldn't find a useable */ 
    /* winsock.dll. */ 
    WSACleanup(); 
    return; 
    }
 
}




/* winsockstr
   Windows Sockets cannot report errors through perror() so we need to define
   our own error strings to print. Someday all the string should be prettied up.
   Prettied the errors I usually get */
char * winsockstr(error)
int error;
{
	switch (error)
	{
	case WSAEINTR          : return("INTR          ");
	case WSAEBADF          : return("BADF          ");
	case WSAEACCES         : return("ACCES         ");
	case WSAEFAULT         : return("FAULT         ");
	case WSAEINVAL         : return("INVAL         ");
	case WSAEMFILE         : return("MFILE         ");
	case WSAEWOULDBLOCK    : return("WOULDBLOCK    ");
	case WSAEINPROGRESS    : return("INPROGRESS    ");
	case WSAEALREADY       : return("ALREADY       ");
	case WSAENOTSOCK       : return("NOTSOCK       ");
	case WSAEDESTADDRREQ   : return("DESTADDRREQ   ");
	case WSAEMSGSIZE       : return("MSGSIZE       ");
	case WSAEPROTOTYPE     : return("PROTOTYPE     ");
	case WSAENOPROTOOPT    : return("NOPROTOOPT    ");
	case WSAEPROTONOSUPPORT: return("PROTONOSUPPORT");
	case WSAESOCKTNOSUPPORT: return("SOCKTNOSUPPORT");
	case WSAEOPNOTSUPP     : return("OPNOTSUPP     ");
	case WSAEPFNOSUPPORT   : return("PFNOSUPPORT   ");
	case WSAEAFNOSUPPORT   : return("AFNOSUPPORT   ");
	case WSAEADDRINUSE     : return("ADDRINUSE     ");
	case WSAEADDRNOTAVAIL  : return("ADDRNOTAVAIL  ");
	case WSAENETDOWN       : return("NETDOWN       ");
	case WSAENETUNREACH    : return("NETUNREACH    ");
	case WSAENETRESET      : return("NETRESET      ");
	case WSAECONNABORTED   : return("CONNABORTED   ");
	case WSAECONNRESET     : return("CONNRESET     ");
	case WSAENOBUFS        : return("NOBUFS        ");
	case WSAEISCONN        : return("ISCONN        ");
	case WSAENOTCONN       : return("NOTCONN       ");
	case WSAESHUTDOWN      : return("SHUTDOWN      ");
	case WSAETOOMANYREFS   : return("TOOMANYREFS   ");
	case WSAETIMEDOUT      : return("TIMEDOUT      ");
	case WSAECONNREFUSED   : return("connection refused");
	case WSAELOOP          : return("LOOP          ");
	case WSAENAMETOOLONG   : return("NAMETOOLONG   ");
	case WSAEHOSTDOWN      : return("HOSTDOWN      ");
	case WSAEHOSTUNREACH   : return("HOSTUNREACH   ");
	case WSAENOTEMPTY      : return("NOTEMPTY      ");
	case WSAEPROCLIM       : return("PROCLIM       ");
	case WSAEUSERS         : return("USERS         ");
	case WSAEDQUOT         : return("DQUOT         ");
	case WSAESTALE         : return("STALE         ");
	case WSAEREMOTE        : return("REMOTE        ");
	case WSAEDISCON        : return("DISCON        ");
	case WSASYSNOTREADY    : return("SYSNOTREADY    ");
	case WSAVERNOTSUPPORTED: return("VERNOTSUPPORTED");
	case WSANOTINITIALISED : return("NOTINITIALISED ");
	case WSAHOST_NOT_FOUND : return("HOST_NOT_FOUND ");
	case WSATRY_AGAIN      : return("TRY_AGAIN      ");
	case WSANO_RECOVERY    : return("NO_RECOVERY    ");
	case WSANO_DATA        : return("NO_DATA        ");
	default : return("unknown socket error");
	}
}
#endif





/* holler :
   fake varargs -- need to do this way because we wind up calling through
   more levels of indirection than vanilla varargs can handle, and not all
   machines have vfprintf/vsyslog/whatever!  6 params oughta be enough. */
void holler (str, p1, p2, p3, p4, p5, p6)
  char * str;
  char * p1, * p2, * p3, * p4, * p5, * p6;
{
  if (o_verbose) {
    fprintf (stderr, str, p1, p2, p3, p4, p5, p6);
#ifdef WIN32
	if (h_errno)
		fprintf (stderr, ": %s\n",winsockstr(h_errno));
#else
    if (errno) {		/* this gives funny-looking messages, but */
      perror (" ");		/* it's more portable than sys_errlist[]... */
    }				/* xxx: do something better.  */
#endif
	else
      fprintf (stderr, "\n");
    fflush (stderr);
  }
} /* holler */

/* bail :
   error-exit handler, callable from anywhere */
void bail (str, p1, p2, p3, p4, p5, p6)
  char * str;
  char * p1, * p2, * p3, * p4, * p5, * p6;
{
  o_verbose = 1;
  holler (str, p1, p2, p3, p4, p5, p6);
#ifdef WIN32
  closesocket (netfd);
#else
  close (netfd);
#endif
  sleep (1);
  exit (1);
} /* bail */

/* catch :
   no-brainer interrupt handler */
void catch ()
{
  errno = 0;
   if (o_verbose > 1)		/* normally we don't care */
    bail (wrote_txt, wrote_net, wrote_out);

  bail (" punt!");
}

/* timeout and other signal handling cruft */
void tmtravel ()
{
#ifdef NTFIXTHIS
  signal (SIGALRM, SIG_IGN);
  alarm (0);
#endif
  if (jval == 0)
    bail ("spurious timer interrupt!");
  longjmp (jbuf, jval);

⌨️ 快捷键说明

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