📄 spoofsocket.cpp
字号:
/*
*
*
* 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 + -