⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spoofsocket.cpp

📁 一个可订制ip packet的程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
 *
 *
 *  Copyright (c) 2000 Barak Weichselbaum <barak@komodia.com>
 *  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *
 * Contact info:
 * Site: http://www.komodia.com
 * Email: barak@komodia.com
 */

#include "stdafx.h"
#include "SpoofSocket.h"

/////////////////////////////////////////////////////////////////////////////
// CSpoofSocket

#define CSpoofSocket_LOGNAME "CSpoofSocket"
#define CIPOptions_LOGNAME "CIPOptions"

//##ModelId=3B43E6F20183
CSpoofSocket::CSpoofSocket() : CSpoofBase()
{
	try
	{
		SetName(CSpoofSocket_LOGNAME);
		InitializeIP();
	}
	ERROR_HANDLER("CSpoofSocket")
}

//##ModelId=3B43E6F20320
CSpoofSocket::CSpoofSocket(SOCKET sok) : CSpoofBase()
{
	//Check it's a valid socket
	if (sok!=INVALID_SOCKET)
		ReportError("CSpoofSocket","Received invalid socket!");
	else
		try
		{
			SetName(CSpoofSocket_LOGNAME);
			AssignSocket(sok);
		}
		ERROR_HANDLER("CSpoofSocket")
}

//##ModelId=3B43E6F201A1
CSpoofSocket::~CSpoofSocket()
{
	try
	{
		//Delete options
		SetOptions(FALSE);

		Close();
	}
	ERROR_HANDLER("~CSpoofSocket")
}

/////////////////////////////////////////////////////////////////////////////
// CSpoofSocket member functions

//##ModelId=3B43E6F202A6
BOOL CSpoofSocket::Create(int iProtocol)
{
	try
	{
		//Here we create the raw socket
		if (m_Raw || iProtocol==IPPROTO_ICMP)
			m_SpoofSocket=socket(AF_INET,SOCK_RAW,iProtocol);//iProtocol);
		else
			if (iProtocol==IPPROTO_TCP)
				m_SpoofSocket=socket(AF_INET,SOCK_STREAM,iProtocol);
			else if (iProtocol==IPPROTO_UDP)
				m_SpoofSocket=socket(AF_INET,SOCK_DGRAM,iProtocol);

		//Check for socket validity
		if (m_SpoofSocket==INVALID_SOCKET)
		{
			//Error
			SetLastError("Create");
			return FALSE;
		}

		if (m_Raw)
		{
			//Set that the application will send the IP header
			unsigned int iTrue=1;

			if(setsockopt(m_SpoofSocket,IPPROTO_IP,IP_HDRINCL,(char*)&iTrue,sizeof(iTrue))==SOCKET_ERROR)
			{
				//Check for options error
				SetLastError("Create");
				return FALSE;
			}
		}

		return TRUE;
	}
	ERROR_HANDLER_RETURN("Create",FALSE)
}

//##ModelId=3B43E6F20288
BOOL CSpoofSocket::Send(LPCSTR lpDestinationAddress,char* buf,int bufLength,unsigned short usDestinationPort)
{
	try
	{
		//Quit if not ok
		if (!CheckSocketValid())
			return FALSE;

		//Define the target address
		sockaddr_in m_TargetAddress;
		memset(&m_TargetAddress,0,sizeof(m_TargetAddress));

		m_TargetAddress.sin_family=AF_INET;
		m_TargetAddress.sin_addr.s_addr=inet_addr(lpDestinationAddress);
		m_TargetAddress.sin_port=htons(usDestinationPort);

		//packet send status ?
		int iResult;

		//Only if allowing raw headers !!
		if (m_Raw)
		{
			//Header length
			unsigned char ucHeaderLength=IpHeaderLength;

			if (m_Options)
				ucHeaderLength+=m_IPOptions->GetBufferLength();
			
			//First construct the packet
			LPIpHeader lpHead=ConstructIPHeader(m_Protocol,IpFragFlag_DONT_FRAG,m_TTL,(unsigned short)GetCurrentProcessId(),ucHeaderLength);

			//Set the address
			SetIPHeaderAddress(lpHead,m_SourceAddress,lpDestinationAddress);

			//Now add some more options
			int iTotalLength;
			iTotalLength=ucHeaderLength+bufLength;

			//Set the header
			lpHead->TotalLength=htons(iTotalLength);

			//Need to construct a new packet
			char* newBuf=new char[iTotalLength];

			//Copy two buffers
			memcpy(newBuf,lpHead,IpHeaderLength);

			//Do we need to copy options ?
			if (m_Options)
				memcpy(newBuf+IpHeaderLength,m_IPOptions->GetBuffer(),m_IPOptions->GetBufferLength());

			//Only if not null
			if (buf)
				memcpy(newBuf+ucHeaderLength,buf,bufLength);
			
			//Calculate the checksum
			lpHead->CheckSum=CalculateChecksum((unsigned short*)newBuf,iTotalLength);

			//Alert everyone this is the final header
			FinalIPHeader(lpHead);

			//Recopy the ip
			memcpy(newBuf,lpHead,IpHeaderLength);
			
			//Send the data
			iResult=sendto(GetHandle(),(const char*)newBuf,iTotalLength,0,(sockaddr*)&m_TargetAddress,sizeof(m_TargetAddress));

			if (iResult==SOCKET_ERROR)
				SetLastError("Send - Raw");

			//Dispose of the buffer
			delete newBuf;

			//Dispose the header
			delete lpHead;
		}
		else
		{
			iResult=!SOCKET_ERROR;

			//Insert options
			//if (m_Options)
				//if (setsockopt(GetHandle(),IPPROTO_IP,IP_OPTIONS,m_IPOptions->GetBuffer(),m_IPOptions->GetBufferLength())==SOCKET_ERROR)
					//Error
					//iResult=SOCKET_ERROR;
				//else
				//	;
			//else
				//No options
				//iResult=setsockopt(GetHandle(),IPPROTO_IP,IP_OPTIONS,NULL,0);

			//Check if we had an error
			if (iResult!=SOCKET_ERROR)
				//Use regular send !!!
				iResult=sendto(GetHandle(),(const char*)buf,bufLength,0,(sockaddr*)&m_TargetAddress,sizeof(m_TargetAddress));
		}

		if (iResult==SOCKET_ERROR)
			//Set the error
			SetLastError("Send");

		return iResult!=SOCKET_ERROR;
	}
	ERROR_HANDLER_RETURN("Send",FALSE)
}

//##ModelId=3B43E6F202DB
LPIpHeader CSpoofSocket::ConstructIPHeader(unsigned char  ucProtocol,
										   unsigned short usFragmentationFlags,
										   unsigned char  ucTTL,
										   unsigned short usIdentification,
										   unsigned char  ucHeaderLength)
{
	return ConstructStaticIPHeader(ucProtocol,
								   usFragmentationFlags,
								   ucTTL,
								   usIdentification,
								   ucHeaderLength);				   
}

//##ModelId=3B43E6F203B5
void CSpoofSocket::SetIPHeaderAddress(LPIpHeader lpHead, LPCSTR lpSourceAddress, LPCSTR lpDestinationAddress)
{
	try
	{
		//We need to place the header
		
		//If source is NULL then we need to use default source
		if (!lpSourceAddress)
		{
			//We will implement it
		}
		else
			//Use sockets2
			lpHead->sourceIPAddress=inet_addr(lpSourceAddress);

		//Place destination address
		lpHead->destIPAddress=inet_addr(lpDestinationAddress);

		//Done
	}
	ERROR_HANDLER("SetIPHeaderAddress")
}

//##ModelId=3B43E6F20382
BOOL CSpoofSocket::ValidSocket()
{
	return m_SpoofSocket!=INVALID_SOCKET;
}

//##ModelId=3B43E6F20364
unsigned short CSpoofSocket::CalculateChecksum(unsigned short *usBuf, int iSize)
{
	try
	{
		unsigned long usChksum=0;

		//Calculate the checksum
		while (iSize>1)
		{
			usChksum+=*usBuf++;
			iSize-=sizeof(unsigned short);
		}

		//If we have one char left
		if (iSize)
			usChksum+=*(unsigned char*)usBuf;

		//Complete the calculations
		usChksum=(usChksum >> 16) + (usChksum & 0xffff);
		usChksum+=(usChksum >> 16);

		//Return the value (inversed)
		return (unsigned short)(~usChksum);
	}
	ERROR_HANDLER_RETURN("CalculateChecksum",0)
}


//##ModelId=3B43E6F2026A
BOOL CSpoofSocket::Bind(LPCSTR lpSourceAddress,int iPort)
{
	try
	{
		//Quit if not ok
		if (!CheckSocketValid())
			return FALSE;

		//Create the local address
		sockaddr_in soSrc;

		//Set to 0
		memset(&soSrc,0,sizeof(soSrc));
		soSrc.sin_family=AF_INET;

		if (lpSourceAddress)
			soSrc.sin_addr.s_addr=inet_addr(lpSourceAddress);
		else
			soSrc.sin_addr.s_addr=ADDR_ANY ;

		soSrc.sin_port=htons(iPort);

		//Now we need to bind it
		if (bind(GetHandle(),(sockaddr*)&soSrc,sizeof(soSrc)))
		{
			//Error
			SetLastError("Bind");
			return FALSE;
		}
		else
			//Save the address
			m_ConnectedTo=soSrc;

		//If already has a source address then don't change it
		if (!m_SourceAddress)
			m_SourceAddress=lpSourceAddress;

		return TRUE;
	}
	ERROR_HANDLER_RETURN("Bind",FALSE)
}

//##ModelId=3B43E6F20396
SOCKET CSpoofSocket::GetHandle()
{
	return m_SpoofSocket;
}

//##ModelId=3B43E6F20300
BOOL CSpoofSocket::CheckSocketValid()
{
	try
	{
		//Check if socket is invalid
		if (!ValidSocket())
		{
			ReportError("CheckSocketValid","Operation made on non existant socket!");
			return FALSE;
		}

		//OK
		return TRUE;
	}
	ERROR_HANDLER_RETURN("CheckSocketValid",FALSE)
}

//##ModelId=3B43E6F20256
BOOL CSpoofSocket::Close()
{
	try
	{
		//Close the socket
		//Quit if not ok
		if (!ValidSocket())
			return FALSE;

		//Close it
		if (closesocket(GetHandle())==SOCKET_ERROR)
		{
			//Error in closing ?
			SetLastError("Close");
			return FALSE;
		}

		//Set the socket to invalid
		m_SpoofSocket=INVALID_SOCKET;

		return TRUE;
	}
	ERROR_HANDLER_RETURN("Close",FALSE)
}


//##ModelId=3B43E6F20350
void CSpoofSocket::SetProtocol(int iProtocol)
{
	m_Protocol=iProtocol;
}

//##ModelId=3B43E6F20241
void CSpoofSocket::SetSourceAddress(LPCSTR lpSourceAddress)
{
	try
	{
		//Set the source address, in case we want to spoof it
		m_SourceAddress=lpSourceAddress;
	}
	ERROR_HANDLER("SetSourceAddress")
}

//##ModelId=3B43E6F2022D
unsigned short CSpoofSocket::CalculatePseudoChecksum(char *buf, int BufLength,LPCSTR lpDestinationAddress,int iPacketLength)
{
	try
	{
		//Calculate the checksum
		LPPseudoHeader lpPseudo;
		lpPseudo=new PseudoHeader;

		lpPseudo->DestinationAddress=inet_addr(lpDestinationAddress);
		lpPseudo->SourceAddress=inet_addr(m_SourceAddress);
		lpPseudo->Zeros=0;
		lpPseudo->PTCL=m_Protocol;
		lpPseudo->Length=htons(iPacketLength);

		//Calculate checksum of all
		int iTotalLength;
		iTotalLength=PseudoHeaderLength+BufLength;

		char* tmpBuf;
		tmpBuf=new char[iTotalLength];

		//Copy pseudo
		memcpy(tmpBuf,lpPseudo,PseudoHeaderLength);

		//Copy header
		memcpy(tmpBuf+PseudoHeaderLength,buf,BufLength);

		//Calculate the checksum
		unsigned short usChecksum;
		usChecksum=CalculateChecksum((unsigned short*)tmpBuf,iTotalLength);

		//Delete all
		delete tmpBuf;
		delete lpPseudo;

		//Return checksum
		return usChecksum;
	}
	ERROR_HANDLER_RETURN("CalculatePseudoChecksum",0)
}

//##ModelId=3B43E6F20219
void CSpoofSocket::SetTTL(unsigned char ucTTL)
{
	try
	{
		//Quit if not ok
		if (!CheckSocketValid())
			return;

		if (m_Raw)
		{
			//Set the ttl
			m_TTL=ucTTL;
		}
		else
			setsockopt(GetHandle(),IPPROTO_IP,IP_TTL,(const char*)&ucTTL,sizeof(ucTTL));
	}
	ERROR_HANDLER("SetTTL")
}

//##ModelId=3B43E6F20205
void CSpoofSocket::SetRaw(BOOL bRaw)
{
	//Do we want to create raw socket (YES!!)
	m_Raw=bRaw;
}

//##ModelId=3B43E6F201FB
void CSpoofSocket::SetOptions(BOOL bOptions)
{
	try
	{
		//Do we want options, normaly not
		m_Options=bOptions;

		if (m_IPOptions)
		{
			delete m_IPOptions;
			m_IPOptions=NULL;
		}

		if (bOptions)
			m_IPOptions=new CIPOptions;
	}
	ERROR_HANDLER("SetOptions")
}

//##ModelId=3B43E6F003DA
CIPOptions::CIPOptions()
{
	try
	{
		SetName(CIPOptions_LOGNAME);

		//Initialize our buffer
		m_Buffer=new char[IPOption_SIZE];

		//Set our buffer to nothing
		Reset();

		//Set auto pad
		m_AutoPAD=TRUE;
	}
	ERROR_HANDLER("CIPOptions")
}

//##ModelId=3B43E6F10005
CIPOptions::~CIPOptions()
{
	try
	{
		delete m_Buffer;
	}
	ERROR_HANDLER("~CIPOptions")
}

//##ModelId=3B43E6F100C3
void CIPOptions::AddOption_Nothing()
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -