网络嗅探器(MFC实现)

大家也许用过网络嗅探器吧,确实网络嗅探器用在了很多方面。网络嗅探器是通过把网卡设置为混杂模式来捕获网络数据包的,简单介绍网络嗅探器的实现:

 

定义IP协议结构

typedef struct _IP_HEADER
{
	BYTE	bVerAndHLen;                    //版本信息(前4位)和头长度(后4位)
	BYTE	BTypeOfService;                 //服务类型
	USHORT	nToalLength;                    //数据包长度
	USHORT	nID;                            //数据包标识
	USHORT	nReserved;                      //保留字段
	BYTE	bTTL;                           //生成时间
	BYTE	bProtocol;                      //协议类型
	USHORT	nCheckSum;                      //校验和
	UINT	nSourIP;                        //源IP
	UINT	nDestIp;                        //目的IP
} IP_HEADER, *LPIP_HEADER;

 

定义TCP协议结构

typedef struct _TCP_HEADER
{
	USHORT	nSourPort;						//源端口号
	USHORT	nDestPort;						//目的端口号
	UINT	nSeqNum;						//序列号
	UINT	nAcknowledgeNum;				//确认号
	USHORT	nHLenAndFlag;					//前4位:TCP头长度	中6位:保留	后6位:标志位
	USHORT	nWindowSize;					//窗口大小
	USHORT	nCheckSum;						//校验和
	USHORT	nrgentPointer;					//紧急数据偏移量
} TCP_HEADER, *LPTCP_HEADER;


定义UDP协议结构

typedef struct _UDP_HEADER

{

USHORT nSourPort; //源端口号

USHORT nDestPort; //目的端口号

USHORT nLength; //数据包长度

USHORT nCheckSum; //校验和

} UDP_HEADER, *LPUDP_HEADER;

 

对于IPTCPUDP结构,我只抽取6个字段,当然可以自行添加所需要的字段

typedef struct _PACK_INFO
{
	USHORT	nLength;						//数据包长度
	USHORT	nProtocol;						//协议类型
	UINT	nSourIp;						//源IP
	UINT	nDestIp;						//目的IP
	USHORT	nSourPort;						//源端口
	USHORT	nDestPort;						//目的端口
} PACK_INFO, *LPPACK_INFO;


 

点击“启动”按钮后启动一个独立的线程来捕获数据包

HANDLE hThread = ::CreateThread(NULL, 0, MonitorThread, this, 0, NULL);

 

线程的实现如下

//监视线程
DWORD WINAPI MonitorThread(LPVOID lParam)
{
	//取得窗体指针
	CSnifferDlg *pDlg = (CSnifferDlg*)lParam;

	WSADATA wsaData;
	if(WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
	{
		TCHAR szErrorMessage[200];
		ZeroMemory(szErrorMessage, sizeof(szErrorMessage));
		wsprintf(szErrorMessage, "ERROR NO:%d", GetLastError());
		AfxMessageBox(szErrorMessage);
		return 0;
	}

	//创建监听套接字  创建的是原始套接字
	SOCKET MonSock;
	MonSock = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
	if(MonSock == INVALID_SOCKET)
	{
		TCHAR szErrorMessage[200];
		ZeroMemory(szErrorMessage, sizeof(szErrorMessage));
		wsprintf(szErrorMessage, "ERROR NO:%d", GetLastError());
		AfxMessageBox(szErrorMessage);
		return 0;
	}


	//获取本地地址信息
	SOCKADDR_IN LocalAddr;
	TCHAR szLocalName[200];
	ZeroMemory(szLocalName, sizeof(szLocalName));
	gethostname(szLocalName, sizeof(szLocalName));
	hostent *pHost = gethostbyname(szLocalName);
	if(pHost != NULL)
	{
		LocalAddr.sin_family = AF_INET;
		LocalAddr.sin_port = htons(0);
		memcpy (&(LocalAddr.sin_addr.s_addr), pHost->h_addr_list[0], pHost->h_length) ;
	}
	else
	{
		return 0;
	}

	//绑定
	if(bind(MonSock, (SOCKADDR*)&LocalAddr, sizeof(SOCKADDR)) == SOCKET_ERROR)
	{
		TCHAR szErrorMessage[200];
		ZeroMemory(szErrorMessage, sizeof(szErrorMessage));
		wsprintf(szErrorMessage, "ERROR NO:%d", GetLastError());
		AfxMessageBox(szErrorMessage);
		return 0;
	}

	//设置为混杂模式 接收所有IP包
	DWORD dwValue = 1;
	if(ioctlsocket(MonSock, SIO_RCVALL, &dwValue) != 0)
	{
		TCHAR szErrorMessage[200];
		ZeroMemory(szErrorMessage, sizeof(szErrorMessage));
		wsprintf(szErrorMessage, "ERROR NO:%d", GetLastError());
		return 0;
	}


	//检测控制标志,是否继续监视
	while(pDlg->isMonitor)
	{
		PACK_INFO PackInfo;
		ZeroMemory(&PackInfo, sizeof(PackInfo));

		int nRecvSize = 0;
		TCHAR szPackBuff[1024];
		ZeroMemory(szPackBuff, sizeof(szPackBuff));
		nRecvSize = recv(MonSock, szPackBuff, sizeof(szPackBuff), 0);

		//如果接收到数据开始解析
		if(nRecvSize > 0)
		{
			//解析IP包头
			LPIP_HEADER pIpHeader = (LPIP_HEADER)szPackBuff;
			PackInfo.nLength = nRecvSize;
			PackInfo.nProtocol = (USHORT)pIpHeader->bProtocol;
			PackInfo.nSourIp = pIpHeader->nSourIP;
			PackInfo.nDestIp = pIpHeader->nDestIp;
			
			UINT nIpHeadLength = (pIpHeader->bVerAndHLen & 0x0F) * sizeof(UINT);

			//只检测TCP包和UDP包
			switch(pIpHeader->bProtocol)
			{
			case IPPROTO_TCP:
				//取得TCP数据包端口号
				LPTCP_HEADER pTcpHeader; 
				pTcpHeader = (LPTCP_HEADER)&szPackBuff[nIpHeadLength];
				PackInfo.nSourPort = pTcpHeader->nSourPort;
				PackInfo.nDestPort = pTcpHeader->nDestPort;
				pDlg->AddPackInfo(&PackInfo);
				break;

			case IPPROTO_UDP:
				//取得UDP数据包端口号
				LPUDP_HEADER pUdpHeader;
				pUdpHeader = (LPUDP_HEADER)&szPackBuff[nIpHeadLength];
				PackInfo.nSourPort = pTcpHeader->nSourPort;
				PackInfo.nDestPort = pTcpHeader->nDestPort;
				pDlg->AddPackInfo(&PackInfo);
				break;
			}
		}

		Sleep(100);
	}

	return 0;
}


 

 

 

关于嗅探器的源代码#include #include #include #include #include #pragma comment(lib,"ws2_32.lib") #define MAX_HOSTNAME_LAN 255 #define SIO_RCVALL _WSAIOW(IOC_VENDOR,1) #define MAX_ADDR_LEN 16 struct ipheader { unsigned char ip_hl:4; unsigned char ip_v:4; unsigned char ip_tos; unsigned short int ip_len; unsigned short int ip_id; unsigned short int ip_off; unsigned char ip_ttl; unsigned char ip_p; unsigned short int ip_sum; unsigned int ip_src; unsigned int ip_dst; }; typedef struct tcpheader { unsigned short int sport; unsigned short int dport; unsigned int th_seq; unsigned int th_ack; unsigned char th_x:4; unsigned char th_off:4; unsigned char Flags; unsigned short int th_win; unsigned short int th_sum; unsigned short int th_urp; }TCP_HDR; typedef struct udphdr { unsigned short sport; unsigned short dport; unsigned short len; unsigned short cksum; }UDP_HDR; void main(){ SOCKET sock; WSADATA wsd; DWORD dwBytesRet; unsigned int optval = 1; unsigned char *dataudp,*datatcp; int i,pCount=0,lentcp, lenudp; SOCKADDR_IN sa,saSource, saDest; struct hostent FAR * pHostent; char FAR name[MAX_HOSTNAME_LAN]; char szSourceIP[MAX_ADDR_LEN], szDestIP[MAX_ADDR_LEN],RecvBuf[65535] = {0}; struct udphdr *pUdpheader; struct ipheader *pIpheader; struct tcpheader *pTcpheader; WSAStartup(MAKEWORD(2,1),&wsd); if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP))==SOCKET_ERROR) exit(1); gethostname(name, MAX_HOSTNAME_LAN); pHostent = gethostbyname(name); sa.sin_family = AF_INET; sa.sin_port = htons(6000); memcpy(&sa.sin_addr.S_un.S_addr, pHostent->h_addr_list[0], pHostent->h_length); bind(sock, (SOCKADDR *)&sa, sizeof(sa)); if ((WSAGetLastError())==10013) exit(1); WSAIoctl(sock, SIO_RCVALL, &optval, sizeof(optval), NULL, 0, &dwBytesRet, NULL, NULL); pIpheader = (struct ipheader *)RecvBuf; pTcpheader = (struct tcpheader *)(RecvBuf+ sizeof(struct ipheader )); pUdpheader = (struct udphdr *) (RecvBuf+ sizeof(struct ipheader )); while (1){ memset(RecvBuf, 0, sizeof(RecvBuf)); recv(sock, RecvBuf, sizeof(RecvBuf), 0); saSource.sin_addr.s_addr = pIpheader->ip_src; strncpy(szSourceIP, inet_ntoa(saSource.sin_addr), MAX_ADDR_LEN); saDest.sin_addr.s_addr = pIpheader->ip_dst; strncpy(szDestIP, inet_ntoa(saDest.sin_addr), MAX_ADDR_LEN); lentcp =(ntohs(pIpheader->ip_len)-(sizeof(struct ipheader)+sizeof(struct tcpheader))); lenudp =(ntohs(pIpheader->ip_len)-(sizeof(struct ipheader)+sizeof(struct udphdr))); if((pIpheader->ip_p)==IPPROTO_TCP&&lentcp!=0){ printf("*******************************************\n"); pCount++; datatcp=(unsigned char *) RecvBuf+sizeof(struct ipheader)+sizeof(struct tcpheader); printf("-TCP-\n"); printf("\n%s\n",szDestIP); printf("\n%i\n",ntohs(pTcpheader->dport)); printf("datatcp address->%x\n",datatcp); printf("size of ipheader->%i\n",sizeof(struct ipheader)); printf("size of tcpheader->%i\n",sizeof(struct tcpheader)); printf("size of the hole packet->%i\n",ntohs(pIpheader->ip_len)); printf("\nchar Packet%i [%i]=\"",pCount,lentcp-1); for (i=0;i<lentcp;i++){ printf("\\x%.2x",*(datatcp+i)); if (i==0) printf("\"\n\""); } printf("\";\n\n\n"); for (i=0;i<lentcp;i++){ if( *(datatcp+i)=20) printf("%c",*(datatcp+i)); else printf("."); } printf("\n\n*******************************************\n"); } if((pIpheader->ip_p)==IPPROTO_UDP&&lentcp!=0){ pCount++; dataudp=(unsigned char *) RecvBuf+sizeof(struct ipheader)+sizeof(struct udphdr); printf("-UDP-\n"); printf("\n%s\n",szDestIP); printf("\n%d\n",ntohs(pTcpheader->dport)); printf("UDP%x\n",dataudp); printf("IP%i\n",sizeof(struct ipheader)); printf("UDP%i\n",sizeof(struct udphdr)); printf("%i\n",ntohs(pIpheader->ip_len)); printf("\nchar Packet%i [%i]=\"",pCount,lenudp-1); for (i=0;i<lenudp;i++){ printf("\\x%.2x",*(dataudp+i)); if (i==0) printf("\"\n\""); } printf("\";\n\n\n"); for (i=0;i<lenudp;i++){ if( *(dataudp+i)=20) printf("%c",*(dataudp+i)); else printf("."); } printf("\n\n*******************************************\n"); } } }
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值