c++ ip数据包捕获

IpPack.h


#pragma once

#ifndef __IP_PACK_H__
#define __IP_PACK_H__

#include <wtypes.h>
#include <string>

#define MAX_IP_PACK_LEN		(USHORT)(0xFFFF)

#define IP4_PROTOCOL			4
#define IP6_PROTOCOL			6

#define IP_VER(ver_ihl)			((ver_ihl)&(0x0f))
#define IS_IP4(ver_ihl)			(IP4_PROTOCOL == IP_VER(ver_ihl))
#define IS_IP6(ver_ihl)			(IP6_PROTOCOL == IP_VER(ver_ihl))


/* 4 bytes IP address */
 typedef union _Ip4_Address
 {
	 struct
	 {
		 u_char	byte1;
		 u_char	byte2;
		 u_char	byte3;
		 u_char	byte4;
	 };

 	u_long	ul;
 
 }Ip4_Address;

 /* IPv4 header */
 typedef struct _Ip4_Header
 {
	 u_char			ver_ihl;		// Version (4 bits) + Internet header length (4 bits)
	 u_char			tos;			// Type of service 
	 u_short		tlen;			// Total length 
	 u_short		identification; // Identification
	 u_short		flags_fo;		// Flags (3 bits) + Fragment offset (13 bits)
	 u_char			ttl;			// Time to live
	 u_char			proto;			// Protocol
	 u_short		crc;			// Header checksum
	 Ip4_Address	saddr;		// Source address
	 Ip4_Address	daddr;		// Destination address
 }Ip4_Header,*PIp4_Header;

 /* UDP header*/
 typedef struct _Udp_Header
 {
	 u_short sport;			// Source port
	 u_short dport;			// Destination port
	 u_short len;			// Datagram length
	 u_short crc;			// Checksum
 }Udp_Header;

 /* TCP header*/
 typedef struct _Tcp_Header
 {
	 u_short sport;				//	Source port
	 u_short dport;				//  Destination port
	 u_int	 sequence_num;		//	Sequence Number
	 u_int	 acknowledgment;	//  Acknowledgment
	 u_char	 hdr_len;			//  header len
	 u_char  flags;				//  flags
	 u_short window_size;		//
	 u_short crc;
	 u_short urg_ptr;
 }Tcp_Header,*PTcp_Header;

 /* Dns header*/
 typedef struct _Dns_Header
 {

 }Dns_Header,*PDns_Header;

class IIpPack
{
public:
	virtual ~IIpPack(){};
	virtual VOID GetPack(PVOID pPack, int iLen) = 0;
};

class test : public IIpPack
{
public:
	virtual VOID GetPack(PVOID pPack, int iLen)
	{
		PIp4_Header p = (PIp4_Header)pPack;

		char buf[128];
		std::string str = "@@@ 协议版本:";
		sprintf_s(buf, "%d", (p->ver_ihl >> 4));
		str += buf;

		std::string src = inet_ntoa(*(in_addr*)&p->saddr);
		std::string dst = inet_ntoa(*(in_addr*)&p->daddr);

		str += " 源ip:";
		str += src;
		
		str += " 目标ip:";
		str += dst;

		OutputDebugStringA(str.c_str());
	}
};

#endif

IpPackCap.h



#pragma once

#ifndef __IP_PACK_CAPTURE_H__
#define __IP_PACK_CAPTURE_H__

#include <windows.h>
#include <ws2tcpip.h>
#include <list>
#include "IpPack.h"

enum IP_FAMILY
{
	IP_UNKNOW_FAMILY	= 0,
	IP4_FAMILY			= AF_INET,
	IP6_FAMILY			= AF_INET6,
};

typedef struct _IP_ADDRESS
{
	IP_FAMILY		Type;
	union 
	{
		ULONG	Ipv4;
		struct  in_addr InAddr;
		UCHAR	Ipv6[16];
		struct  in6_addr In6Addr;
	};

	_IP_ADDRESS()
	{
		Type = IP_UNKNOW_FAMILY;
	};

}IP_ADDRESS,*PIP_ADDRESS;

typedef struct _IP_ENPOINT
{
	IP_ADDRESS	Address;
	ULONG		Port;
	
	_IP_ENPOINT()
	{
		Port = 0;
	};

}IP_ENPOINT,*PIP_ENPOINT;

class CIpPackCap
{
public:
	CIpPackCap();
	~CIpPackCap();

	DWORD   Start(IP_ENPOINT& ipEndpoint, IIpPack* pPackDeal);
	VOID	Stop();

private:
	static DWORD WINAPI _WorkFunction(LPVOID lpParam);

private:
	BOOL		m_bStop;
	HANDLE		m_hThread;
	SOCKET		m_socket;
	PVOID		m_pPackBuf;
	ULONG		m_ulPackBufLen;
	IIpPack*	m_pPackDeal;

};

class CIpPackCapManager
{
public:
	typedef struct _IP_LISTEN
	{
		IP_ENPOINT	stListenEnpoint;
		CIpPackCap *pPackCap;
		IIpPack	   *pIpPack;

		_IP_LISTEN()
		{
			pPackCap = NULL;
			pIpPack = NULL;
		};

	}IP_LISTEN, *PIP_LISTEN;

public:
	CIpPackCapManager();
	~CIpPackCapManager();


	DWORD	Init();
	VOID	UnInit();

	DWORD   Start();
	VOID	Stop();

private:
	VOID	_Clear();

private:
	std::list<IP_LISTEN>	m_ltIpListenTable;
	BOOL					m_bInit;

};

#endif

IpPackCap.cpp


#include "stdafx.h"
#include "IpPackCap.h"
#include <winsock2.h>
#include <ws2tcpip.h>
#include <mstcpip.h>

#pragma comment(lib, "ws2_32.lib")

#define MAX_SAF_HOSTNAME_LEN		(256+1)

CIpPackCap::CIpPackCap()
{
	m_bStop			= TRUE;
	m_hThread		= NULL;
	m_socket		= INVALID_SOCKET;
	m_pPackBuf		= NULL;
	m_ulPackBufLen	= 0;
	m_pPackDeal		= NULL;
}

CIpPackCap::~CIpPackCap()
{
	Stop();
}

DWORD CIpPackCap::Start(IP_ENPOINT& ipEndpoint, IIpPack* pPackDeal)
{
	DWORD dwError = ERROR_SUCCESS;

	do 
	{
		if (NULL != m_hThread ||
			IP_UNKNOW_FAMILY == ipEndpoint.Address.Type ||
			NULL == pPackDeal)
		{
			dwError = ERROR_FUNCTION_FAILED;
			return dwError;
		}

		m_pPackBuf = ::HeapAlloc(::GetProcessHeap(), 0,
								MAX_IP_PACK_LEN);
		if (NULL == m_pPackBuf)
		{
			dwError = ERROR_NOT_ENOUGH_MEMORY;
			break;
		}
		m_ulPackBufLen = MAX_IP_PACK_LEN;

		m_socket = ::socket(
			ipEndpoint.Address.Type,
			SOCK_RAW,
			IPPROTO_IP);
		if (INVALID_SOCKET == m_socket)
		{
			dwError = ::WSAGetLastError();
			break;
		}

		int iResult;

		std::string str;
		if (IP4_FAMILY == ipEndpoint.Address.Type)
		{
			struct sockaddr_in address4;
			
			address4.sin_family = ipEndpoint.Address.Type;
			address4.sin_port = ::htons(ipEndpoint.Port);
			address4.sin_addr = ipEndpoint.Address.InAddr;
			
			str = inet_ntoa(address4.sin_addr);

			iResult = ::bind(m_socket, 
							(struct sockaddr*)&address4, 
							sizeof(struct sockaddr_in));
		}
		else
		{
			dwError = ERROR_FUNCTION_FAILED;
			break;
		}

		if (SOCKET_ERROR == iResult)
		{
			dwError = ::WSAGetLastError();
			break;
		}

		DWORD dwInBuff = RCVALL_IPLEVEL;
		DWORD dwRetLen = 0;

		iResult = ::WSAIoctl(
					m_socket,
					SIO_RCVALL,
					&dwInBuff,
					sizeof(dwInBuff),
					NULL,
					0,		
					&dwRetLen,
					NULL,
					NULL);
		if (SOCKET_ERROR == iResult)
		{
			dwError = ::WSAGetLastError();
			break;
		}

		//阻塞模式
		u_long bioarg = 0;
		iResult = ioctlsocket(m_socket, FIONBIO, &bioarg);
		if (SOCKET_ERROR == iResult)
		{
			dwError = ::WSAGetLastError();
			break;
		}

		m_bStop = FALSE;
		m_pPackDeal = pPackDeal;

		m_hThread = ::CreateThread(
					NULL, 0, _WorkFunction,
					this, 0, NULL);
		if (NULL == m_hThread)
		{
			m_bStop = TRUE;
			dwError = ::GetLastError();
			break;
		}

	} while (0);

	if (ERROR_SUCCESS != dwError)
	{
		if (INVALID_SOCKET != m_socket)
		{
			::closesocket(m_socket);
			m_socket = NULL;
		}

		if (NULL != m_pPackBuf)
		{
			::HeapFree(GetProcessHeap(), 0, m_pPackBuf);
			m_pPackBuf		= NULL;
			m_ulPackBufLen	= 0;
		}
	}

	return dwError;
}

VOID CIpPackCap::Stop()
{
	if (NULL != m_hThread)
	{
		m_bStop = TRUE;

		m_pPackDeal = NULL;
		
		if (INVALID_SOCKET != m_socket)
		{
			::closesocket(m_socket);
			m_socket = INVALID_SOCKET;
		}

		DWORD dwWaitResult = 
			::WaitForSingleObject(m_hThread, 1000);
		if (WAIT_OBJECT_0 != dwWaitResult)
		{
			::TerminateThread(m_hThread, 0);
		}

		m_hThread = NULL;

		if (NULL != m_pPackBuf)
		{
			::HeapFree(GetProcessHeap(), 0, m_pPackBuf);
			m_pPackBuf = NULL;
			m_ulPackBufLen = 0;
		}
	}
}

DWORD CIpPackCap::_WorkFunction(LPVOID lpParam)
{
	DWORD dwError = ERROR_SUCCESS;

	CIpPackCap* pThis = (CIpPackCap*)lpParam;
 
	while(FALSE == pThis->m_bStop)
	{
		if (NULL == pThis)
			break;

		int iLen = ::recv(
			pThis->m_socket, 
			(char*)pThis->m_pPackBuf,
			pThis->m_ulPackBufLen, 0);
		if (SOCKET_ERROR == iLen)
		{
			dwError = ::WSAGetLastError();
			break;
		}

		if (pThis->m_pPackDeal)
		{
			pThis->m_pPackDeal->GetPack(
				pThis->m_pPackBuf, iLen);
		}
	}

	return dwError;
}

CIpPackCapManager::CIpPackCapManager()
{
	Init();
}

CIpPackCapManager::~CIpPackCapManager()
{
	UnInit();
}

DWORD CIpPackCapManager::Init()
{
	DWORD dwError = ERROR_SUCCESS;

	BOOL  bStartup = FALSE;

	struct addrinfo *result = NULL;

	do
	{
		if (TRUE == m_bInit)
			break;

		WORD wVersionRequested;
		WSADATA wsaData;
		wVersionRequested = MAKEWORD(2, 2);

		int err = ::WSAStartup(wVersionRequested, &wsaData);
		if (0 != err)
		{
			dwError = ERROR_FUNCTION_FAILED;
			break;
		}

		bStartup = TRUE;

		if (LOBYTE(wsaData.wVersion) != 2 ||
			HIBYTE(wsaData.wVersion) != 2)
		{
			dwError = ERROR_FUNCTION_FAILED;
			break;
		}

		char hostName[MAX_SAF_HOSTNAME_LEN] = { 0 };

		int iResult =
			::gethostname(hostName, MAX_SAF_HOSTNAME_LEN);
		if (SOCKET_ERROR == iResult)
		{
			dwError = ::WSAGetLastError();
			break;
		}
	
		struct addrinfo *ptr = NULL;
		struct addrinfo hints;

		struct sockaddr_in  *sockaddr_ipv4;
		struct sockaddr_in6 *sockaddr_ipv6;

		ZeroMemory(&hints, sizeof(hints));
		hints.ai_family = AF_UNSPEC;
		hints.ai_flags = AI_PASSIVE;
		hints.ai_protocol = IPPROTO_IPV4;

		dwError = ::getaddrinfo(hostName, NULL, &hints, &result);
		if (0 != dwError)
		{
			break;
		}

		for (ptr = result; NULL != ptr; ptr = ptr->ai_next)
		{
			IP_LISTEN ip_listen;

			PVOID	pPackBuf = NULL;

			switch (ptr->ai_family)
			{
			case AF_INET:
			{
				ip_listen.stListenEnpoint.Address.Type = IP4_FAMILY;
				sockaddr_ipv4 = (struct sockaddr_in *) ptr->ai_addr;
				ip_listen.stListenEnpoint.Address.InAddr = sockaddr_ipv4->sin_addr;

				break;
			}
			default:
			{
				continue;
			}

			}

			m_ltIpListenTable.push_back(ip_listen);
		}

		if (ERROR_SUCCESS != dwError)
			break;

		m_bInit = TRUE;

	} while (0);

	if (ERROR_SUCCESS != dwError)
	{
		m_ltIpListenTable.clear();

		if(TRUE == bStartup)
			::WSACleanup();
	}

	if (NULL != result)
	{
		::freeaddrinfo(result);
	}

	return dwError;
}

VOID CIpPackCapManager::UnInit()
{
	if (TRUE == m_bInit)
	{
		Stop();

		::WSACleanup();

		m_bInit = FALSE;
	}
}

DWORD CIpPackCapManager::Start()
{
	DWORD	dwError = ERROR_SUCCESS;

	do
	{
		if (FALSE == m_bInit)
		{
			dwError = ERROR_FUNCTION_FAILED;
			break;
		}

		std::list<IP_LISTEN>::iterator it;
		it = m_ltIpListenTable.begin();
		for (; it != m_ltIpListenTable.end(); it++)
		{
			CIpPackCap *pPackCap = new CIpPackCap;
			IIpPack	   *pIpPack = new test;
			it->stListenEnpoint.Port = 0;
			dwError = pPackCap->Start(it->stListenEnpoint, pIpPack);
			
			if (ERROR_SUCCESS != dwError)
			{
				delete pPackCap;
				delete pIpPack;
				//break;
			}
			else
			{
				it->pPackCap = pPackCap;
				it->pIpPack = pIpPack;
			}
		}

	} while (0);

	if (ERROR_SUCCESS != dwError)
	{
		_Clear();
	}

	return dwError;
}

VOID CIpPackCapManager::Stop()
{
	_Clear();
}

VOID CIpPackCapManager::_Clear()
{
	std::list<IP_LISTEN>::iterator it;
	it = m_ltIpListenTable.begin();
	for (; it != m_ltIpListenTable.end(); it++)
	{
		if (NULL != it->pPackCap)
		{
			delete it->pPackCap;
			it->pPackCap = NULL;
		}
		if (NULL != it->pIpPack)
		{
			delete it->pIpPack;
			it->pIpPack = NULL;
		}
	}
}

CIpPackCapManager m_manager;

    m_manager.Init();

    m_manager.Start();

 

管理员启动,window7 及以上系统  都无法捕获数据输入ip包  所以我已经放弃治疗了  哎。。。。。。

选择winpcap玩玩咯  或者  以后自己写驱动咯 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值