📄 sniffer.cpp
字号:
// Sniffer.cpp: implementation of the CSniffer class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Sniffer.h"
#include <winsock2.h>
#include <WS2TCPIP.H>
#include <MSTcpIP.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CSniffer::CSniffer()
{
WSADATA wsaData;
if(WSAStartup(0x202, &wsaData) == 0)
{
m_bWSAStartup = TRUE;
}
else
{
m_bWSAStartup = FALSE;
}
//初始化临界区对象
InitializeCriticalSection(&m_ls);
memset(m_szProto, 0, 16);
memset(m_strAddr, 0, 64);
memset(m_szDestPort, 0, 16);
memset(m_szSourcePort, 0, 16);
memset(m_szTTL, 0, 16);
memset(m_szDestIP, 0, 16);
memset(m_szSourceIP, 0, 16);
memset(m_szProtocol, 0, 16);
m_bIsRun = FALSE;
m_IsAllPort = false;
m_IsAllIp = TRUE;
m_IsAllProto = TRUE;
}
CSniffer::~CSniffer()
{
//销毁临界区对象
DeleteCriticalSection(&m_ls);
DelListBuf();
}
BOOL CSniffer::SnifferInit(LPSTR lpStrAddr, UINT uPort)
{
DWORD dwThreadID;
strcpy(m_strAddr, lpStrAddr);
m_uPort = uPort;
m_HostIp = GetIp(); //得到本机IP
//开始监听
if(!CreateSock()) //建立
{
//"WinSock设置失败
return false;
}
else
{
m_bIsRun = TRUE;
m_hThread = CreateThread( NULL, NULL, RecvIpPro, (PVOID)this, NULL, &dwThreadID);
}
return true;
}
void CSniffer::StopSniffer()
{
m_bIsRun = FALSE;
if(m_hThread)
{
TerminateThread(m_hThread, 0);
CloseHandle(m_hThread);
}
if(m_RawSock)
closesocket(m_RawSock);
}
//建立原始套接字
BOOL CSniffer::CreateSock()
{
char name[56] = {0};
hostent *pHostent;
int port = 8310; //监听端口
int err;
SOCKADDR_IN sockaddr;
m_RawSock = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
if(m_RawSock == INVALID_SOCKET)
{
return WSAGetLastError(); //socket创建失败
}
err= ::gethostname(name, 56);
if(err==SOCKET_ERROR)
{
return WSAGetLastError(); //取本机用户名失败
}
pHostent = gethostbyname (name);
sockaddr.sin_family = AF_INET;
sockaddr.sin_port = htons(port);
memcpy(&sockaddr.sin_addr.s_addr, pHostent->h_addr_list[0],
pHostent->h_length);
//free(pHostent);
err = bind(m_RawSock,(SOCKADDR *)&sockaddr, sizeof(sockaddr));//绑定
if(err == SOCKET_ERROR)
{
return WSAGetLastError(); //取本机用户名失败
}
BOOL bOptval = TRUE;
//设置套节字选项
setsockopt(m_RawSock, SOL_SOCKET,SO_REUSEADDR, (char*)&bOptval, sizeof(bOptval));
err = setsockopt(m_RawSock, IPPROTO_IP,IP_HDRINCL, (char*)&bOptval, //IP_HDRINCL该选项使之能操作IP头
sizeof(bOptval));
if(err == SOCKET_ERROR)
{
return WSAGetLastError(); //设置套节字选项失败
}
//把网卡置于混杂模式。获取IO操作的相关信息
DWORD dwBufferLen[10] ;
DWORD dwBufferInLen = 1 ;
DWORD dwBytesReturned = 0 ;
err=WSAIoctl (
m_RawSock,
SIO_RCVALL, //设置SOCK_RAW为SIO_RCVALL,以便接收所有的IP包
&dwBufferInLen,
sizeof(dwBufferInLen),
&dwBufferLen,
sizeof(dwBufferLen),
&dwBytesReturned,
NULL,
NULL
);//最后两参数设置非阻塞
if(err == SOCKET_ERROR)
{
return WSAGetLastError(); //设置套节字选项失败
}
return true;
}
//在线程中不断接受IP包
DWORD CALLBACK CSniffer::RecvIpPro(LPVOID lpParam)
{
int err = 0;
int recvLen;
CSniffer* pSniffer = (CSniffer*)lpParam;
char *recvBuf = new char[MAX_PACK_LEN];
while(pSniffer->m_bIsRun)
{
memset(recvBuf, 0, MAX_PACK_LEN);
recvLen = recv(pSniffer->m_RawSock,recvBuf, MAX_PACK_LEN, 0);//接受数据
if(err==SOCKET_ERROR)
{
if(WSAGetLastError() == WSAEWOULDBLOCK) //如果错误为阻塞那么将继续接受
continue;
break;
}
//处理已经接受到的IP包
EnterCriticalSection(&pSniffer->m_ls);
pSniffer->SplitIpPack(recvBuf, recvLen); //分解IP包
//pSniffer->ShowIpInfo(recvBuf,recvLen); //分析并处理IP数据包
LeaveCriticalSection(&pSniffer->m_ls);
}
return 0;
}
//分解IP包
void CSniffer::SplitIpPack(char *pData, int len)
{
IP_HEADER* pIpHead;
memset(m_szDestPort, 0, 16);
memset(m_szSourcePort, 0, 16);
memset(m_szTTL, 0, 16);
memset(m_szDestIP, 0, 16);
memset(m_szSourceIP, 0, 16);
memset(m_szProtocol, 0, 16);
pIpHead = (IP_HEADER*)pData; //转为IP头结构
SOCKADDR_IN saSource, saDest; //中间变量分别为源IP地址结构和目标IP地址结构
//得到包中协议
int iProtocol;
iProtocol = pIpHead->proto;
//得到协议字符形式表示m_szProtocol
strncpy(m_szProtocol,CheckProtocol(iProtocol), MAX_PROTO_TEXT_LEN);
//得到源IP
saSource.sin_addr.s_addr = pIpHead->sourceIP;
strncpy(m_szSourceIP, inet_ntoa(saSource.sin_addr), MAX_ADDR_LEN);
//得到目标IP
saDest.sin_addr.s_addr=pIpHead->destIP;
strncpy(m_szDestIP, inet_ntoa(saDest.sin_addr), MAX_ADDR_LEN);
//得到TTL
int ttl;
ttl=pIpHead->ttl;
wsprintf(m_szTTL, "%d", ttl);
//得到头长度
int ihLen = sizeof(unsigned long)*(pIpHead->h_lenver & 0xf);
m_ihLen = ihLen;
unsigned short srcPort = 0, destPort = 0;
switch(iProtocol)
{
case IPPROTO_TCP:
{
TCP_HEADER* pTcpHead;
pTcpHead = (TCP_HEADER*)(pData+ihLen);
srcPort = ntohs(pTcpHead->th_sport);
destPort = ntohs(pTcpHead->th_dport);
wsprintf(m_szSourcePort, "%d", srcPort);
wsprintf(m_szDestPort, "%d", destPort);
int nLen = ihLen + sizeof(TCP_HEADER);
//基于TCP/IP协议之上的协议的解析
TCPProtocolParse(pData + nLen, len - nLen);
}
break;
case IPPROTO_UDP:
UDP_HEADER* pUdpHead;
pUdpHead = (UDP_HEADER*)(pData+ihLen);
srcPort = ntohs(pUdpHead->uh_sport);
destPort = ntohs(pUdpHead->uh_dport);
wsprintf(m_szSourcePort, "%d", srcPort);
wsprintf(m_szDestPort, "%d",destPort);
break;
case IPPROTO_ICMP:
ICMP_HEADER* pIcmpHead;
pIcmpHead=(ICMP_HEADER*)(pData + ihLen);
wsprintf(m_szSourcePort, "%s", "");
wsprintf(m_szDestPort, "%s", "");
break;
default:
wsprintf(m_szSourcePort, "%s", "");
wsprintf(m_szDestPort, "%s", "");
}
}
//将IP记录存放到链表中
void CSniffer::ShowIpInfo(char *pData, int len)
{
if(len<0)
return;
char szSourceIP[32] = {0};
char szDestIP[32] = {0};
char szSourcePort[16] = {0}; //截取到的源端口
char szDestPort[16] = {0}; //截取到的目标端口
char szSourceIPt[32] = {0}; //截取到源IP
char szDestIPt[32] = {0}; //截取到目标IP
char szWprot[5] = {0}; //取得输入端口
char szIP[32] = {0}; //取得输入IP
char szProto[16] = {0}; //取得输入协议
if(strcmp(m_HostIp, m_szSourceIP) == 0)
{
strcat(szSourceIP, "(本机)");
strcat(szSourceIP, m_szSourceIP);
}
else
strncpy(szSourceIP, m_szSourceIP, 16);
if(strcmp(m_HostIp, m_szDestIP) == 0)
{
strcat(szDestIP, "(本机)");
strcat(szDestIP, m_szDestIP);
}
else
strncpy(szDestIP, m_szDestIP, 16);
strncpy(szSourcePort, m_szSourcePort, 5);
strncpy(szDestPort, m_szDestPort, 5);
strncpy(szDestIPt, m_szSourceIP, 32);
strncpy(szSourceIPt, m_szDestIP, 32);
strncpy(szProto, m_szProtocol, 16);
wsprintf(szWprot, "%d", m_uPort);
//取得输入IP
strcpy(szIP, m_strAddr);
BOOL bProt = m_IsAllPort | (strcmp(szSourcePort, szWprot) == 0) |
(strcmp(szDestPort, szWprot) == 0); //判断端口规则
BOOL bIp = m_IsAllIp | (strcmp(szSourceIPt, szIP) == 0) |
(strcmp(szDestIPt, szIP) == 0); //判断IP规则
BOOL bProto = m_IsAllProto | (strcmp(szProto, m_szProto) == 0); //判断协议规则
if(bProt && bIp && bProto)
{
char sNowTime[18] = {0};
GetNowTime(sNowTime);
char str[512] = {0};
wsprintf(str, "[%s] %s:%s->%s:%s 包大小(头/总)%d/%d %s", m_szProtocol, szSourceIP,
m_szSourcePort, szDestIP, m_szDestPort,
m_ihLen, len, sNowTime);
int nCount = m_strIPInfoList.size();
if (nCount >= 1000)
m_strIPInfoList.clear();
//放入链表
string strData(str);
m_strIPInfoList.push_back(strData);
//绑定数据
IPDATA *pIpData = new IPDATA();
pIpData->len = len;
pIpData->buf = new char[len];
memcpy(pIpData->buf, pData, len);
m_strIPDataList.push_back((DWORD)pIpData);
}
}
//清除和ListBox绑定的数据和列表
void CSniffer::DelListBuf()
{
}
//格式化显示IP包
void CSniffer::ShowIpData(char *pData, int len)
{
}
//协议分析统一在此处理
void CSniffer::TCPProtocolParse(char *pData, int nLen)
{
for(int i=0; i<nLen; i++)
{
if(pData[i] == 0)
pData[i] = '\n';
}
UINT nPort = GetPort();
m_HttpParse.Perform(pData, nLen, nPort, m_szSourceIP, "",
m_szSourcePort, m_szDestIP, "", m_szDestPort);
}
void CSniffer::ConfigProtocolParsePack(vector<DWORD> &Parse_List)
{
int nTelnetLen = Parse_List.size();
int nLen = sizeof(TELNET_IAC_PACK) * nTelnetLen;
char *config = new char[nLen];
for (int i = 0; i < nTelnetLen; i++)
{
DWORD Node = Parse_List.at(i);
if (Node != 0)
{
TELNET_IAC_PACK* pNode = (TELNET_IAC_PACK*)Node;
memset(config, 0, nLen + 1);
wsprintf(config,
"[时间]%s\r\n[源IP]%s\r\n[目的IP]%s\r\n[源MAC]%s\r\n[目的MAC]%s\r\n[命令]\r\n%s\r\n[数据域]\r\n%s%\r\n",
pNode->date,
pNode->src_ip,
pNode->des_ip,
pNode->src_mac,
pNode->des_mac,
pNode->cmd,
pNode->data);
}
}
//存放到文件中去
char path[1024] ={0};
//GetCurrentDirectory(1024, path);
//strcat(path, "\\网络抓包日志(Telent).log");
strcpy(path, "c:\\网络抓包日志(Telent).log");
nLen = strlen(config);
WriteLogFile(config, nLen, path);
}
//////////////////////////////////////////////////////////////////////////
//将协议int转为字符串
char* CSniffer::CheckProtocol(int iProtocol)
{
for(int i=0; i < MAX_PROTO_NUM; i++)
{
if(ProtoMap[i].ProtoNum == iProtocol)
{
return ProtoMap[i].ProtoText;
}
}
return "";
}
//得到本机IP
char* CSniffer::GetIp()
{
WORD wVersionRequested;
WSADATA wsaData;
char name[255];
char *ip;
PHOSTENT hostinfo;
wVersionRequested = MAKEWORD( 2, 0 );
if ( WSAStartup( wVersionRequested, &wsaData ) == 0 )
{
if( gethostname ( name, sizeof(name)) == 0)
{
if((hostinfo = gethostbyname(name)) != NULL)
{
ip = inet_ntoa (*(struct in_addr *)*hostinfo->h_addr_list);
}
}
WSACleanup();
}
return ip;
}
//得到当前时间,格式:%Y-%m-%d %H:%M:%S
void CSniffer::GetNowTime(char *pCurTime)
{
_SYSTEMTIME Curtime;
GetSystemTime(&Curtime);
wsprintf(pCurTime, "%4d-%2d-%2d %2d:%2d:%2d",
Curtime.wYear,
Curtime.wMonth,
Curtime.wDay,
Curtime.wHour,
Curtime.wMinute,
Curtime.wSecond);
}
//写入日志文件
bool CSniffer::WriteLogFile(char *strInfo, int nBuffer, char *strFileName)
{
if (lstrlen(strInfo)<1)
return FALSE;
int nLen = sizeof(strInfo);
FILE *lpfile;
lpfile = fopen(strFileName, "aw+");
//fseek(lpfile, 0, SEEK_END);
char *temp = new char[nBuffer];
memset(temp, 0, nBuffer);
strcpy(temp, strInfo);
strcat(temp, "\r\n");
fwrite(temp, nBuffer, 1, lpfile);
fclose(lpfile);
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -