C++做的变态Sniffer注意这是我原来做竞赛的(黑色部分)

原来这个程序是放在远程端做的控制用

/*
C实现缓冲区扫描
*/
#include "stdio.h"         
#include "winsock2.h"
#define  DINGCHI 30//设置的扫描区域(后期可加入一定模块扫描主机数然后相应改动扫描区域)
//缓冲区扫描控制
#define  LIS_SEVEN 1

//扫描
void SEVEN   (SOCKET Sock);
//处理包(按协议字段)
void doP   (unsigned char* , int);
//打印包头
void PrintIpHeader   (unsigned char* , int);
//IPV4头部
typedef struct ip_hdr
{   //IP首部第一个4字节
 unsigned char  ip_header_len:4; //低4个比特位
 unsigned char  ip_version   :4; //低4个比特位(4字节为单位)
 unsigned char  ip_tos;          
 unsigned short ip_total_length;
 //重点(标识字段两个字节)
 unsigned short ip_id;
 unsigned char  ip_frag_offset :5;      
 unsigned char  ip_more_fragment :1;
 unsigned char  ip_dont_fragment :1;
 unsigned char  ip_reserved_zero :1;
 unsigned char  ip_frag_offset1; 
 unsigned char  ip_ttl;
 //协议(后面需要根据这个字段)
 unsigned char  ip_protocol;     
 unsigned short ip_checksum; 
 //源地址和目的地址
 unsigned int   ip_srcaddr;      
 unsigned int   ip_destaddr;     
}   IPV4_HDR;
//特殊的IP选项(后期可以加入对其操作的函数)
struct ip_option{
 unsigned char   faddr;
 unsigned char   optlen;
 unsigned char   srr;
 unsigned char   rr;
 unsigned char   ts;
 unsigned char   is_setbyuser:1,is_data:1,
    is_strictroute:1,srr_is_hit:1,is_changed:1,rr_needaddr:1,ts_needtime:1,ts_needaddr:1;
 unsigned char   router_alert;
 unsigned char   __pad1;
 unsigned char   __pad2;
 unsigned char   __data[0];
};
//写入的文件(以便用于入库和查看)
FILE *logfile;
int total=0,i,j=1;
struct sockaddr_in source,dest;
//用于进制转换
char hex[2];
//Its free!
IPV4_HDR *iphdr;
//用于设置网卡工作模式(参考)
#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
//几个协议icmp\uDP\TCP\....(后期可以扩展)
//ICMP头部(暂时不需要查看)
typedef struct icmpA  
{
 BYTE A[2];
 USHORT S[3];
}   ICMPH;
ICMPH *icmpheader;
//UDP
typedef struct udpA
{
 unsigned short port[2];   //不需要查看
 unsigned short udp_length;
 unsigned short udp_checksum;   
}   UDPH;
UDPH  *udpheader;
//TCP
//其中一些字段可用用于后期的程序功能拓展
typedef struct tcp_header
{
 //端口(不要查看)
 unsigned short port[2];    
 //序列号(4字节)
 unsigned int   seq;
 //确认号
 unsigned int   ack; 
 //数据偏移 (4位) 保留 (6位) 标志 (6位)
 unsigned char  ns   :1;          //Nonce Sum Flag Added in RFC 3540.
 unsigned char  reserved_part1:3;
 unsigned char  data_offset:4; 
 //标志
 unsigned char  fin  :1;     
 unsigned char  syn  :1;     
 unsigned char  rst  :1;    
 unsigned char  psh  :1;     
 unsigned char  TCP_ackN  :1;     
 unsigned char  urg  :1;     
 unsigned char  ecn  :1;     
 unsigned char  cwr  :1;  
 //窗口、校验、紧急
 unsigned short window;  
 unsigned short checksum;
 unsigned short urgent_pointer;
}   TCPH;
TCPH *tcpheader;
//打印数据部分
void PrintDZ(unsigned char* data , int Size);
void doP(unsigned char* Buffer, int Size);
void PrintIP(unsigned char* Buffer, int Size);
void RAW();
//主模块(包括扫描和返回信息文件【可以是ACCESS数据库】)
void main()
{
 RAW();//扫描开始
 //RAW2();后期可以加入一些方法使扫描加快(多线程)
}
//几个处理模块
void ICMP(unsigned char* Buffer , int Size);
void TCP(unsigned char* Buffer, int Size);
void UDP(unsigned char* Buffer , int Size);
//扫描开始
void RAW()
{   SOCKET listenWMF;//声明scorket对象
struct in_addr addr;
//用作扫描的网卡的判定
int in=1;//默认为1(在无线环境下无线网卡列表位置在有线之前)
//主机名
char hostname[100];
//主机地址
struct hostent *local;
//WSADATA数据类型(用于套接字)
WSADATA wsa;
logfile=fopen("log.txt","w");
//第二个版本
WSAStartup(MAKEWORD(2,2), &wsa);
//扫描
listenWMF = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
//printf("创建");用于调试
//本地主机的标准主机名。(可删)
gethostname(hostname, sizeof(hostname));
//返回对应于给定主机名的包含主机名字和地址信息的hostent结构指针。
//结构的声明与gethostaddr()中一致。
local = gethostbyname(hostname);
for (i = 0; local->h_addr_list[i] != 0; ++i)
{
 memcpy(&addr, local->h_addr_list[i], sizeof(struct in_addr));
}
memset(&dest, 0, sizeof(dest));
//指向地址为起始地址的
//连续n个字节的数据复制到以destin指向地址为起始地址的空间内。
memcpy(&dest.sin_addr.s_addr,local->h_addr_list[1],sizeof(dest.sin_addr.s_addr));
dest.sin_family      = AF_INET;
dest.sin_port        = 0;
//将内网网卡与一套接口捆绑。
bind(listenWMF,(struct sockaddr *)&dest,sizeof(dest));
WSAIoctl(listenWMF, SIO_RCVALL, &j, sizeof(j), 0, 0, &in,0, 0);
SEVEN(listenWMF);
closesocket(listenWMF);
WSACleanup();
return 0;
}

void SEVEN(SOCKET listenWMF)
{
 unsigned char *Buffer = (char *)malloc(65536); //可用最大缓冲区(一个IP报文)
 int  pL,WW=DINGCHI;//这里是永久监听(也可设置定次器)
 do
 {
  pL = recvfrom(listenWMF,Buffer,65536,0,0,0);;
  doP(Buffer, pL);WW--;
 }
 while (pL > 0&&WW>0);
 free(Buffer);
 
}

void doP(unsigned char* Buffer, int Size)
{
 iphdr = (IPV4_HDR *)Buffer;
 ++total;
 PrintIP(Buffer,Size);
 //根据协议处理(可拓展)
 switch (iphdr->ip_protocol)
 {
 case 1:ICMP(Buffer,Size);break;
 case 6:TCP(Buffer,Size);break;
 case 17:UDP(Buffer,Size);break;
 }
 printf("Total : %d\r",total);
}

void PrintIP(unsigned char* Buffer, int Size)
{
 unsigned short iphdrlen;
 iphdr = (IPV4_HDR *)Buffer;
 iphdrlen = iphdr->ip_header_len*4;
 memset(&source, 0, sizeof(source));
 source.sin_addr.s_addr = iphdr->ip_srcaddr;
 memset(&dest, 0, sizeof(dest));
 dest.sin_addr.s_addr = iphdr->ip_destaddr;
 fprintf(logfile,"%d#",ntohs(iphdr->ip_id));
 fprintf(logfile,"%s#",inet_ntoa(source.sin_addr));
}
void TCP(unsigned char* Buffer, int Size)
{   //计算出数据部分的位置
 unsigned short iphdrlen;
 iphdr = (IPV4_HDR *)Buffer;
 iphdrlen = iphdr->ip_header_len*4;
 tcpheader=(TCPH*)(Buffer+iphdrlen); 
 PrintDZ(Buffer+iphdrlen+tcpheader->data_offset*4,(Size-tcpheader->data_offset*4-iphdr->ip_header_len*4)/4);
 fprintf(logfile,"\n");
}
void ICMP(unsigned char* Buffer , int Size)
{//计算出数据部分的位置
 unsigned short iphdrlen;
 iphdr = (IPV4_HDR *)Buffer;
 iphdrlen = iphdr->ip_header_len*4;
 icmpheader=(ICMPH*)(Buffer+iphdrlen); 
 PrintDZ(Buffer+iphdrlen+sizeof(ICMPH),(Size - sizeof(ICMPH) - iphdr->ip_header_len*4)/4);
 fprintf(logfile,"\n");
}
void UDP(unsigned char *Buffer,int Size)
{//计算出数据部分的位置
 unsigned short iphdrlen;
 
 iphdr = (IPV4_HDR *)Buffer;
 iphdrlen = iphdr->ip_header_len*4;
 udpheader = (UDPH*)(Buffer + iphdrlen); 
 PrintDZ(Buffer+iphdrlen+sizeof(UDPH),(Size - sizeof(UDPH) - iphdr->ip_header_len*4)/4);
 fprintf(logfile,"\n");
}

//处理二进制数据(转为16进制) 
void PrintDZ(unsigned char* data , int Size)
{
 //这样写主要是为了返回来的数据能够很好的将信息解析出来,但可读性差
 fprintf(logfile,"%02X",(unsigned int)data[0]);
 for(i=1 ; i < Size ; i++)fprintf(logfile,"%02X",(unsigned int)data[i]);

}


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值