一个嗅探 window 系统TCP/IP 数据包的 Raw Socket class
来源:互联网 发布:java实现杨辉三角 编辑:程序博客网 时间:2024/06/11 01:05
网络嗅探器 sniffer 很多,不过自己做的有很多好处。window2000, XP 支持 raw socket,可以用 raw socket 构造一些特殊用途的工具.
#include <windows.h>
#include "winsock2.h"
#include "IPHeader.h"
class CRawSocket
{
SOCKET m_InSocket;
SOCKET m_OutSocket;
DWORD m_LocalIPAddress;
WORD m_LocalPort;
DWORD m_RemoteIPAddress;
WORD m_RemotePort;
int m_SendProtocal;
public:
CRawSocket();
virtual ~CRawSocket();
void FinalIPHeader(char* pIpAndDataBuffer, int length);
void ConstructIPHeader(IPHEADER* pIpHeader, int dataLength);
void FinalTCPHeader(char* pTcpAndDataBuffer, int length);
void ConstructTCPHeader(TCPHEADER* pTcpHeader);
bool SendRawData(char* buffer, int length);
bool Receive(char* buffer, int bufferSize, int& receivedLength);
bool CreateSendSocket(LPCTSTR protocal);
bool CreateReceiveSocket(int port=-1);
DWORD GetLocalIPAddress();
void SetLocalPort(int port);
void SetRemote(DWORD remoteIP, int remotePort);
protected:
unsigned short CalculateChecksum(char* buffer1, int len1, char* buffer2, int len2);
};
CPP 文件,在thread 中使用 Receive 函数,可以获取网络中的数据包。SendRawData 是发送一个自己构造数据包,仅仅是发送,不管 ack 应答,也不管 remote IP and port。其余几个函数用于构造 Raw TCP/IP data.
#include "stdafx.h"
#include "RawSocket.h"
#include <ws2tcpip.h>
#include "IPHeader.h"
#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
#define RCVALL_OFF 0
#define RCVALL_ON 1
#define RCVALL_SOCKETLEVELONLY 2
CRawSocket::CRawSocket()
{
WSADATA wsaData;
char szHostName[128];
m_InSocket = INVALID_SOCKET;
m_OutSocket = INVALID_SOCKET;
if (::WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
CString s;
s.Format("Error socket()= %ld", ::GetLastError());
::AfxMessageBox(s);
}
::gethostname(szHostName, sizeof(szHostName));
HOSTENT* pHostEnt = ::gethostbyname(szHostName);
if (pHostEnt != NULL)
m_LocalIPAddress = *((DWORD*) pHostEnt->h_addr_list[0]);
else
m_LocalIPAddress = 0;
}
CRawSocket::~CRawSocket()
{
::WSACleanup();
}
void CRawSocket::SetRemote(DWORD remoteIP, int remotePort)
{
m_RemoteIPAddress = remoteIP;
m_RemotePort = ::htons(remotePort);
}
void CRawSocket::SetLocalPort(int port)
{
m_LocalPort = ::htons(port);
}
DWORD CRawSocket::GetLocalIPAddress() { return m_LocalIPAddress; }
bool CRawSocket::CreateReceiveSocket(int port)
{
CString s;
m_InSocket = ::WSASocket(AF_INET, SOCK_RAW, IPPROTO_IP, NULL, 0, WSA_FLAG_OVERLAPPED);
if (m_InSocket == INVALID_SOCKET) {
s.Format("Error socket()= %ld", ::WSAGetLastError());
::AfxMessageBox(s);
::closesocket(m_InSocket);
return false;
}
int rcvTimeout = 5000;
if (::setsockopt(m_InSocket, SOL_SOCKET, SO_RCVTIMEO,
(const char*) &rcvTimeout, sizeof(rcvTimeout))
== SOCKET_ERROR)
{
s.Format("Error WSA IO Ctrl= %ld", ::WSAGetLastError());
::AfxMessageBox(s);
::closesocket(m_InSocket);
return false;
}
SOCKADDR_IN sa;
sa.sin_family = AF_INET;
sa.sin_port = port < 0 ? m_LocalPort : (::htons(port));
sa.sin_addr.S_un.S_addr = m_LocalIPAddress;
if (::bind(m_InSocket, (PSOCKADDR) &sa, sizeof(sa)) == SOCKET_ERROR) {
s.Format("Error bind()= %ld", ::WSAGetLastError());
::AfxMessageBox(s);
::closesocket(m_InSocket);
return false;
}
DWORD dwBufferLen[10];
DWORD dwBufferInLen = 1;
DWORD dwBytesReturned = 0;
if (::WSAIoctl( m_InSocket, SIO_RCVALL,
&dwBufferInLen, sizeof(dwBufferInLen),
&dwBufferLen, sizeof(dwBufferLen),
&dwBytesReturned, NULL, NULL)
== SOCKET_ERROR)
{
s.Format("Error WSAIoctl()= %ld", ::WSAGetLastError());
::AfxMessageBox(s);
::closesocket(m_InSocket);
return false;
}
return true;
}
bool CRawSocket::CreateSendSocket(LPCTSTR protocal)
{
CString s(protocal);
if (s == "TCP")
m_SendProtocal = IPPROTO_TCP;
else if (s == "UDP")
m_SendProtocal = IPPROTO_UDP;
else if (s == "ICMP")
m_SendProtocal = IPPROTO_ICMP;
else
m_SendProtocal = IPPROTO_IP;
m_OutSocket = ::WSASocket(AF_INET, SOCK_RAW, m_SendProtocal, NULL, 0, WSA_FLAG_OVERLAPPED);
if (m_OutSocket == INVALID_SOCKET) {
s.Format("Error socket()= %ld", ::WSAGetLastError());
::AfxMessageBox(s);
::closesocket(m_OutSocket);
return false;
}
BOOL flag = TRUE;
if (::setsockopt(m_OutSocket, IPPROTO_IP, IP_HDRINCL, (char*)&flag, sizeof(flag)) == SOCKET_ERROR) {
s.Format("Error setsockopt()= %ld", ::WSAGetLastError());
::AfxMessageBox(s);
::closesocket(m_OutSocket);
return false;
}
int nTimeOver=1000;
if (::setsockopt(m_OutSocket, SOL_SOCKET, SO_SNDTIMEO, (char*)&nTimeOver, sizeof(nTimeOver))==SOCKET_ERROR)
{
s.Format("Error setsockopt()= %ld", ::WSAGetLastError());
::AfxMessageBox(s);
::closesocket(m_OutSocket);
return false;
}
return true;
}
bool CRawSocket::Receive(char* buffer, int bufferSize, int& receivedLength)
{
if (m_OutSocket == m_InSocket) return false;
receivedLength = ::recv(m_InSocket, buffer, bufferSize, 0);
return receivedLength != SOCKET_ERROR;
}
bool CRawSocket::SendRawData(char *buffer, int length)
{
if (m_OutSocket == INVALID_SOCKET) return false;
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = m_RemoteIPAddress;
sin.sin_port = m_RemotePort;
if (::sendto(m_OutSocket,
buffer,
length, 0,
(struct sockaddr*) &sin,
sizeof(struct sockaddr_in)
) == SOCKET_ERROR)
{
CString s;
s.Format("Error sendto()= %ld", ::WSAGetLastError());
::AfxMessageBox(s);
return false;
}
return true;
}
unsigned short CRawSocket::CalculateChecksum(char *buffer1, int len1, char *buffer2, int len2)
{
ASSERT((len1 & 1) == 0);
unsigned long checksum=0;
unsigned short* buffer;
buffer = (unsigned short*) buffer1;
for (int i=0; i<int(len1/sizeof(unsigned short)); i++)
checksum += buffer[i];
buffer = (unsigned short*) buffer2;
for (int i=0; i<int(len2/sizeof(unsigned short)); i++)
checksum += buffer[i];
if ((len2 & 0x1) != 0)
checksum += (unsigned char) buffer2[len2-1];
checksum = (checksum >> 16) + (checksum & 0xffff);
checksum += (checksum >>16);
return (unsigned short)(~checksum);
}
void CRawSocket::ConstructTCPHeader(TCPHEADER *pTcpHeader)
{
pTcpHeader->destPort = m_RemotePort;
pTcpHeader->sourcePort = m_LocalPort;
pTcpHeader->sequence = ::htons(::rand());
pTcpHeader->acknowledge = 0;
pTcpHeader->lengthres = ((sizeof(TCPHEADER)/4 )<< 4);
pTcpHeader->flags = 2;
pTcpHeader->window_size = ::htons(512);
pTcpHeader->urp = 0;
}
void CRawSocket::FinalTCPHeader(char *pTcpAndDataBuffer, int length)
{
ASSERT(length >= sizeof(TCPHEADER));
struct PSDHEADER{
unsigned long saddr;
unsigned long daddr;
char mbz;
char ptcl;
unsigned short tcpl;
} psdHeader;
TCPHEADER* pTcpHeader = (TCPHEADER*) pTcpAndDataBuffer;
char* pDataBuffer = pTcpAndDataBuffer + sizeof(TCPHEADER);
int dataLen = length - sizeof(TCPHEADER);
psdHeader.saddr = m_LocalIPAddress;
psdHeader.daddr = m_RemoteIPAddress;
psdHeader.mbz = 0;
psdHeader.ptcl = IPPROTO_TCP;
psdHeader.tcpl = ::htons(length);
pTcpHeader->checksum = CalculateChecksum((char*) &psdHeader, sizeof(psdHeader), pTcpAndDataBuffer, length);
}
void CRawSocket::ConstructIPHeader(IPHEADER *pIpHeader, int dataLength)
{
pIpHeader->version_length = (4<<4 | sizeof(IPHEADER)/sizeof(unsigned long));
pIpHeader->type_of_service = 0;
pIpHeader->total_length = ::htons(dataLength);
pIpHeader->id = ::htons(::rand());
pIpHeader->offset = 0;
pIpHeader->ttl = 128;
pIpHeader->protocol = m_SendProtocal;
pIpHeader->checksum = 0;
pIpHeader->sourceIP = m_LocalIPAddress;
pIpHeader->destIP = m_RemoteIPAddress;
}
void CRawSocket::FinalIPHeader(char *pIpAndDataBuffer, int length)
{
ASSERT(length > sizeof(IPHEADER));
IPHEADER* pIpHeader = (IPHEADER*) pIpAndDataBuffer;
char* pDataBuffer = pIpAndDataBuffer + sizeof(IPHEADER);
int dataLen = length - sizeof(IPHEADER);
pIpHeader->checksum = CalculateChecksum(pIpAndDataBuffer, sizeof(IPHEADER), pDataBuffer, dataLen);
pIpHeader->checksum = CalculateChecksum(pIpAndDataBuffer, sizeof(IPHEADER), pDataBuffer, 0);
}
- 一个嗅探 window 系统TCP/IP 数据包的 Raw Socket class
- raw socket编写自定义Ip数据包
- Python Raw Socket使用示例(发送TCP SYN数据包)
- Python Raw Socket使用示例(发送TCP SYN数据包)
- tcp、ip的 数据包格式
- TCP/IP数据包的认识
- Socket中接受tcp数据包,怎么让他receive的时候,就接一个数据包?
- TCP/Socket学习---TCP/IP协议栈与数据包封装
- Advanced TCP/IP - THE RAW SOCKET PROGRAM EXAMPLES
- Socket编程-TCP/IP数据包格式详解-包括数据链路层的头部
- 关于TCP/IP数据包的小认识
- TCP/IP各层的数据包长度
- Socket网络通信理论基础搜集(TCP/IP协议栈与数据包封装+TCP与UDP的区别)
- Socket网络通信理论基础搜集(TCP/IP协议栈与数据包封装+TCP与UDP的区别)
- Socket网络通信理论基础搜集(TCP/IP协议栈与数据包封装+TCP与UDP的区别)
- C# TCP/IP数据包
- TCP/IP 网络 数据包
- TCP/IP 网络数据包
- 趣味日语幽默笑话
- 你用右脑多,还是左脑多?
- debian安装nvidia显卡驱动
- 谷歌公布内部数据语言 速度比XML快100倍
- Firefox 3.0 扩展--很实用
- 一个嗅探 window 系统TCP/IP 数据包的 Raw Socket class
- C程序(1)
- apache request
- 在.NET 3.5 平台上使用LINQ to SQL创建三层/多层Web应用系统 (Part 5)
- Python的匿名函数——lambda
- 注册时控制按钮上的时间显示
- ToolTip的动态生成
- C小试牛刀
- oracle企业管理器的心得