首页 / C++ / c++ ip数据包捕获
c++ ip数据包捕获
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c++ ip数据包捕获,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含9210字,纯文字阅读大概需要14分钟。
内容图文
![c++ ip数据包捕获](/upload/InfoBanner/zyjiaocheng/856/fac16a518e0e4dfd8db15132b110e4e7.jpg)
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玩玩咯 或者 以后自己写驱动咯 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
内容总结
以上是互联网集市为您收集整理的c++ ip数据包捕获全部内容,希望文章能够帮你解决c++ ip数据包捕获所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。