📄 coutward.cpp
字号:
#include "stdafx.h"
#include "PIPMasq.h"
bool getAdapterInfo(
const char* nicIPAddress, // input
char* AdapterName, // output
unsigned char* macAddr // output
);
////////////////////////// COutward /////////////////////////////////
COutward::COutward(
TableMgr* tableMgr,
PortMgr* portMgr,
ArpMgr* arpMgr,
PseudIF* pseudIF,
ThreadMgr* threadMgr,
FtpMgr* ftpMgr,
const char* lanIPAddr,
const char* wanIPAddr,
const char* subWanIPAddr,
const char* defaultWanGWAddr)
{
memset(m_message, 0, sizeof(m_message));
m_tableMgr = tableMgr;
m_portMgr = portMgr;
m_pseudIF = pseudIF;
m_arpMgr = arpMgr;
m_threadMgr = threadMgr;
m_ftpMgr = ftpMgr;
strcpy(m_lanIPAddr, lanIPAddr);
strcpy(m_wanIPAddr, wanIPAddr);
m_lanIPAddr_u32 = htonl(inet_addr(m_lanIPAddr));
m_wanIPAddr_u32 = htonl(inet_addr(m_wanIPAddr));
memset(m_lanAdapterName, 0 , sizeof(m_lanAdapterName));
if (getAdapterInfo(m_lanIPAddr, m_lanAdapterName, m_lanMacAddr))
m_lanLpAdapter = PacketOpenAdapter(m_lanAdapterName);
else
return;
// LAN Side only
PacketSetBuff(m_lanLpAdapter, RECV_BUF);
PacketSetReadTimeout(m_lanLpAdapter, 10000); // 10 seconds
//PacketSetReadTimeout(m_lanLpAdapter, 0); // Blocking mode
PacketSetHwFilter(m_lanLpAdapter,NDIS_PACKET_TYPE_DIRECTED);
// PacketSetHwFilter(m_wanLpAdapter,NDIS_PACKET_TYPE_DIRECTED);
if((m_lanLpPacket = PacketAllocatePacket())==NULL)
{
sprintf(m_message,"\nError:failed to allocate the LPPACKET structure.");
return;
}
PacketInitPacket(m_lanLpPacket,(char*)m_lanBuffer, sizeof(m_lanBuffer));
}
COutward::~COutward()
{
PacketFreePacket(m_lanLpPacket);
PacketCloseAdapter(m_lanLpAdapter);
printf(".....COutward is destructed.\n");
// Sleep(1000);
}
COutward::start()
{
while(1)
{
if(PacketReceivePacket(m_lanLpAdapter,m_lanLpPacket,TRUE) == FALSE)
{
sprintf(m_message,"Error: PacketReceivePacket failed");
return false;
}
packetDelimiter();
if (m_threadMgr->m_lifeFlag == true)
return false;
}
}
bool
COutward::packetDelimiter()
{
ULONG ulBytesReceived;
char *pChar;
char *buf;
u_int off=0;
u_int dataLen;
struct bpf_hdr *hdr;
ulBytesReceived = m_lanLpPacket->ulBytesReceived;
buf = (char *)m_lanLpPacket->Buffer;
off=0;
while(off<ulBytesReceived){
hdr=(struct bpf_hdr *)(buf+off);
off += hdr->bh_hdrlen;
pChar = (char*)(buf+off); // Top Address of thr Raw Packet
dataLen =hdr->bh_datalen;
off = Packet_WORDALIGN(off+dataLen); // For padding
analizeRawPacket(pChar, dataLen);
}
return true;
}
bool
COutward::analizeRawPacket(char* pChar, int dataLen)
{
char* _pChar = pChar;
// Step.1
// If the packet is not IP packet, stop it.
struct ethhdr *_ethhdr;
_ethhdr = (struct ethhdr *)_pChar;
if (_ethhdr->h_proto != htons(ETH_P_IP))
{
return false;
}
// Step.2
// If the destination IP address is LAN or WAN NIC IP Address, stop it.
struct iphdr *_iphdr;
_pChar += sizeof(struct ethhdr);
_iphdr = (struct iphdr *)_pChar;
if ((htonl(_iphdr->daddr) == m_lanIPAddr_u32)
||(htonl(_iphdr->daddr) == m_wanIPAddr_u32))
{
return false;
}
// Step.3
// Pick out each element of IP Packet
__u8 p_Protocol = _iphdr->protocol; // TCP or UDP or ICMP
__u32 p_srcIPAddr = _iphdr->saddr; // Source IP Address
__u32 p_destIPAddr = _iphdr->daddr; // Destination IP Address
__u16 p_srcPort;
__u16 p_destPort;
struct udphdr *_udphdr;
struct tcphdr *_tcphdr;
struct icmphdr *_icmphdr;
// Step.4
// Pick up UDP or TCP header
_pChar += sizeof(struct iphdr);
if (_iphdr->protocol == UDP)
{
_udphdr = (struct udphdr *)_pChar;
p_srcPort = _udphdr->source; // Source Port
p_destPort = _udphdr->dest; // Destination Port
}
else if (_iphdr->protocol == TCP)
{
_tcphdr = (struct tcphdr *)_pChar;
p_srcPort = _tcphdr->source; // Source Port
p_destPort = _tcphdr->dest; // Destination Port
}
else if (_iphdr->protocol == ICMP)
{
// You might feel strange about the following lines.
// Because ICMP has no concept of the port.
// I didn't want to the table entry format in tablemgr.cpp, so
// I decided to use srcPort and masqPort in order to identify
// the ping reply message.
_icmphdr = (struct icmphdr *)_pChar;
p_srcPort = _icmphdr->un.echo.id;
p_destPort = PORT_IGNORED;
}
else
{
return false;
}
// Step.5
// Refer to the Entry Table
TableEntry* pTable;
RefLevel refLevel = m_tableMgr->refEntry(
p_Protocol, // Protocol
p_srcPort, // Source Port
p_srcIPAddr, // Source IP Address
p_destPort, // Destination Port
p_destIPAddr, // Destination IP Address
&pTable // Return Table pointer
);
// Step.6
// Make new packet toward WAN
// Case L2 (Perfect Matching)
if (refLevel == L2)
{
// FTP in Active mode
if ((_iphdr->protocol == TCP) && (_tcphdr->dest == htons(FTP)))
m_ftpMgr->activeMode_out(pChar, &dataLen, pTable);
if (_iphdr->protocol == (UDP))
{
_udphdr->source = pTable->masqPort;
}
else if (_iphdr->protocol == (TCP))
{
_tcphdr->source = pTable->masqPort;
}
else if (_iphdr->protocol == ICMP)
{
_icmphdr->un.echo.id = pTable->masqPort;
}
else
{
return false;
}
_iphdr->saddr = htonl(m_pseudIF->m_pseudIPAddr_u32);
memcpy(_ethhdr->h_source, m_pseudIF->m_pseudMacAddr, ETH_ALEN);
memcpy(_ethhdr->h_dest, pTable->destMACAddr, ETH_ALEN);
}
else if (refLevel == L1)
{
// Port Number reservation
__u16 _masqPort;
if (! m_portMgr->reservPort(_iphdr->protocol, &_masqPort))
return false;
// Make new table entry
TableEntry _entry;
_entry.diff_ack = 0;
memcpy(&_entry, pTable, sizeof(TableEntry)); // full copy
_entry.expireTime = time(NULL) + EXPIRE_PERIOD;
_entry.Protocol = _iphdr->protocol;
//_entry.socket = _socket;
_entry.masqPort = _masqPort;
if (_iphdr->protocol == (UDP))
_entry.srcPort = _udphdr->source;
else if (_iphdr->protocol == (TCP))
_entry.srcPort = _tcphdr->source;
else if (_iphdr->protocol == ICMP)
_entry.srcPort = _icmphdr->un.echo.id;
else
return false;
_entry.srcIPAddr = _iphdr->saddr;
memcpy(_entry.srcMACAddr, _ethhdr->h_source, ETH_ALEN);
// Add Entry
if (m_tableMgr->addEntry(&_entry) == false)
return false;
//////
if (_iphdr->protocol == (UDP))
{
_udphdr->source = _entry.masqPort;
}
else if (_iphdr->protocol == (TCP))
{
_tcphdr->source = _entry.masqPort;
}
else if (_iphdr->protocol == ICMP)
{
_icmphdr->un.echo.id = _entry.masqPort;
}
else
{
return false;
}
//_iphdr->saddr = htonl(m_wanIPAddr_u32);
_iphdr->saddr = htonl(m_pseudIF->m_pseudIPAddr_u32);
memcpy(_ethhdr->h_source, m_pseudIF->m_pseudMacAddr, ETH_ALEN);
memcpy(_ethhdr->h_dest, _entry.destMACAddr, ETH_ALEN);
}
else if (refLevel == L0)
{
char _macAddr[ETH_ALEN];
memset(_macAddr, 0, sizeof(_macAddr));
__u32 hAddr = ntohl(_iphdr->daddr);
if (m_arpMgr->arpSendRecv(hAddr,_macAddr) == false)
return false;
// Port Number reservation
__u16 _masqPort;
if (! m_portMgr->reservPort(_iphdr->protocol, &_masqPort))
return false;
// Make new table entry
TableEntry _entry;
_entry.diff_ack = 0;
_entry.expireTime = time(NULL) + EXPIRE_PERIOD;
_entry.Protocol = _iphdr->protocol;
//_entry.socket = _socket;
_entry.masqPort = _masqPort;
if (_iphdr->protocol == (UDP))
_entry.srcPort = _udphdr->source;
else if (_iphdr->protocol == (TCP))
_entry.srcPort = _tcphdr->source;
else if (_iphdr->protocol == ICMP)
_entry.srcPort = _icmphdr->un.echo.id;
else
return false;
_entry.srcIPAddr = _iphdr->saddr;
memcpy(_entry.srcMACAddr, _ethhdr->h_source, ETH_ALEN);
if (_iphdr->protocol == (UDP))
_entry.destPort = _udphdr->dest;
else if (_iphdr->protocol == (TCP))
_entry.destPort = _tcphdr->dest;
else if (_iphdr->protocol == ICMP)
_entry.destPort = _icmphdr->un.echo.id;
else
return false;
_entry.destIPAddr = _iphdr->daddr;
memcpy(_entry.destMACAddr, _macAddr, ETH_ALEN);
// Add Entry
if (m_tableMgr->addEntry(&_entry) == false)
return false;
//////
if (_iphdr->protocol == (UDP))
{
_udphdr->source = _entry.masqPort;
}
else if (_iphdr->protocol == (TCP))
{
_tcphdr->source = _entry.masqPort;
}
else if (_iphdr->protocol == ICMP)
{
_icmphdr->un.echo.id = _entry.masqPort;
}
else
{
return false;
}
_iphdr->saddr = htonl(m_pseudIF->m_pseudIPAddr_u32);
memcpy(_ethhdr->h_source, m_pseudIF->m_pseudMacAddr, ETH_ALEN);
memcpy(_ethhdr->h_dest, _entry.destMACAddr, ETH_ALEN);
}
else
return false;
///// Checksum calculation /////
// IP checksum
_iphdr->check = 0;
_iphdr->check = in_cksum((unsigned short *)_iphdr, sizeof(struct iphdr));
if (_iphdr->protocol == (UDP))
{
int udpDataLenInPacket =
ntohs(_iphdr->tot_len) - sizeof(struct iphdr) - sizeof(struct udphdr);
_udphdr->check = 0; // Checksum should be set "0" first.
_udphdr->check =
udpchecksum(_udphdr, _iphdr, udpDataLenInPacket);
}
else if (_iphdr->protocol == (TCP))
{
int tcpDataLenInPacket =
ntohs(_iphdr->tot_len) - sizeof(struct iphdr) - sizeof(struct tcphdr);
_tcphdr->check = 0; // Checksum should be set "0" first.
_tcphdr->check =
tcpchecksum(_tcphdr, _iphdr, tcpDataLenInPacket);
}
else if (_iphdr->protocol == ICMP)
{
int icmpDataLenInPacket =
ntohs(_iphdr->tot_len) - sizeof(struct iphdr);
_icmphdr->checksum = 0; // should be 0
_icmphdr->checksum =
in_cksum((unsigned short *)_icmphdr, icmpDataLenInPacket);
}
else
{
return false;
}
///// Packet Release /////
// printf("\n\n\nAfter\n");
// DumpPacket(pChar, dataLen);
m_pseudIF->releasePacket((void *)pChar, dataLen);
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -