赞
踩
/*=================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!");
}
/*================================================
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。