分析netcat程序代码

/*=================NetCat代码分析==================*/
//作者:常涛
//语言:C
//去除非Win32代码和和一些其他非Win32的预编译代码
//全功能的nc
/*=================================================*/


#include "generic.h"               /* 此头文件定义了所有的宏代码 */
#define HAVE_BIND                   /* XXX -- for now, see below... */
#define GAPING_SECURITY_HOLE             //控制-e参数的功能
#define TELNET                           //控制-t参数的功能
#define HAVE_BIND
/*==============ifdef...else...endif=========*/
#include <stdlib.h>
/*=============================================*/
#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! */
/*==============================================*/

#define FD_SETSIZE 64  /* WIN32 does this as an array not a bitfield and it likes 64 */

/*=====================================================*/
#include <sys/types.h>  /* *now* do it.  Sigh, this is broken */

/*=========================取消以前定义的宏定义================*/

#undef HAVE_RANDOM       //取消以前定义的宏定义
#undef IP_OPTIONS
#undef SO_REUSEPORT
#include <windows.h>

/*==========================================================*/
#ifdef HAVE_RANDOM
#define SRAND srandom
#define RAND random
#else
#define SRAND srand
#define RAND rand
#endif /* HAVE_RANDOM */
/*========================================================*/
#include "getopt.h"
#define sleep   _sleep
#define strcasecmp  strcmpi
#define EADDRINUSE  WSAEADDRINUSE
#define ETIMEDOUT  WSAETIMEDOUT
#define ECONNREFUSED WSAECONNREFUSED
/*===========================================================*/
#include <time.h>
/*==========================================================*/
#include <setjmp.h>  /* jmp_buf et al */
#include <fcntl.h>
#include <io.h>
#include <conio.h>
#include <winsock.h>
/*===============================================================*/
#include <stdio.h>
#include <string.h>                /* strcpy, strchr, yadda yadda */
#include <errno.h>
#include <signal.h>
#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, */
#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              /* 防止最大主机名称长度不够,重新定义其大小 */
#endif

#define MAXHOSTNAMELEN 256              //将最大主机名长度设为256

/*===================端口信息=======数据结构====主机信息==========================*/

struct host_poop {
  char name[MAXHOSTNAMELEN];          /* DNS */
  char addrs[8][24];               /* ASCII形式的IP地址 */
  struct in_addr iaddrs[8];              /* 真实的IP地址: in_addr.s_addr: ulong */
};

#define HINF struct host_poop            //宏定义主机信息变量 HINF host information

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            //宏定义端口信息变量 PINF: port information

/*================================数据结构完=================================*/

/* globals: */

/*=================================定义变量===全局变量==============================*/

jmp_buf jbuf;                                                         /* timer crud */
int jval = 0;                                                          /* timer crud */
int netfd = -1;
int ofd = 0;                                                          /* hexdump output fd */
static char unknown[] = "(无法获得)";
static char p_tcp[] = "tcp";                                                /* 指定NetCat工作的传输层协议-TCP* */
static char p_udp[] = "udp";                                                   /* 指定NetCat工作的传输层协议-UDP* */

int gatesidx = 0;                                                         /* 指定网络跳数 */
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 输出文件名 */

  char * setsockopt_c;
  int nnetfd;

USHORT o_alla = 0;
unsigned int o_interval = 0;
USHORT o_listen = 0;
/*===主程序参数的标记为,默认为0,所以不执行,如果有参数自动加1,最后影响整个程序执行========*/
USHORT o_nflag = 0;
USHORT o_wfile = 0;
USHORT o_random = 0;
USHORT o_udpmode = 0;
USHORT o_verbose = 0;                //#define USHORT unsigned short
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 */

/*========================初始化WinSock============================*/
/* 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)
    return; 
if ( LOBYTE( wsaData.wVersion ) != 1 ||
        HIBYTE( wsaData.wVersion ) != 1 ) {
    WSACleanup();
    return;
    }
 
}

/*========================= winsockstr(error)===错误信息===============================*/
/* 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("拒绝连接");
 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("未找到主机 ");
 case WSATRY_AGAIN         : return("TRY_AGAIN      ");
 case WSANO_RECOVERY       : return("NO_RECOVERY    ");
 case WSANO_DATA           : return("NO_DATA        ");
 default : return("!!未知的socket错误!!");
 }
}

/*========================如果是WIN32初始化WinSock==结束==========================*/

 

/*=================================输出函数holler===============================*/
/* 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);

 if (h_errno)  //#define h_errno         WSAGetLastError()
  fprintf (stderr, ": %s/n",winsockstr(h_errno));
                  //此处也可以添加一些其他功能 
 else
      fprintf (stderr, "/n");
    fflush (stderr);
  }
} /* holler */
/*=================================输出函数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;                                             //USHORT o_verbose = 0;
  holler (str, p1, p2, p3, p4, p5, p6);

  closesocket (netfd);                                       //int netfd = -1;int PASCAL FAR closesocket (SOCKET s);

  sleep (1);
  exit (1);
} /* bail */

/*=================================输出函数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!");
}

/*================================================

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值