📄 proxy.c
字号:
//--------------------------------------------------------------------
// ProxyRx
//
// Called to modify a proxy RX packet
//--------------------------------------------------------------------
void ProxyRx( NATINFO *pni, HANDLE hPkt, IPHDR *pIpHdr )
{
ModeCurrent = NAT_MODE_RX;
// Save the current packet and header
hPktCurrent = hPkt;
pIpHdrCurrent = pIpHdr;
// Assume we don't rechecksum the entire packet
ChecksumCurrent = 1;
Altered = 0;
// Get the current proxy entry
ppeCurrent = (PROXYENTRY *)pni->hProxyEntry;
// Call user callback
if( ppeCurrent->pfnRxCb )
if( !ppeCurrent->pfnRxCb( pni, pIpHdr ) )
{
PktFree( hPktCurrent );
return;
}
// At this point, the globals variables hold information about what
// could actually be a new packet (if the size changed). Thus, we
// can't do anything more here
ProxyComplete();
}
//--------------------------------------------------------------------
// ProxyComplete
//
// This function is called once a all packet modifications are
// complete. When using TCP, the TCP sequences are adjusted.
// Plus the packet checksums may need to be recalculated.
//--------------------------------------------------------------------
static void ProxyComplete()
{
uint IPHdrLen;
UINT16 Length;
// Get the length of the IP header
IPHdrLen = (pIpHdrCurrent->VerLen & 0xf) * 4;
// Get the length of the payload
Length = HNC16(pIpHdrCurrent->TotalLen);
Length -= IPHdrLen;
Length = HNC16(Length);
// Do the easy case first: UDP
if( pIpHdrCurrent->Protocol == IPPROTO_UDP )
{
UDPHDR *pUdpHdr;
// Get UDP packet header
pUdpHdr = (UDPHDR *)(((UINT8 *)pIpHdrCurrent) + IPHdrLen);
// If the UDP checksum is invalid, redo it
if( !ChecksumCurrent )
{
// Checksum Header
upseudo.dwIPSrc = RdNet32( &pIpHdrCurrent->dwIPSrc );
upseudo.dwIPDst = RdNet32( &pIpHdrCurrent->dwIPDst );
upseudo.Null = 0;
upseudo.Protocol = 17;
upseudo.Length = Length;
UdpChecksum( pUdpHdr );
}
}
// Else we're TCP
else
{
TCPHDR *pTcpHdr;
UINT32 Seq,Ack,NewSeq,NewAck;
int offack,offseq;
// Get TCP packet header
pTcpHdr = (TCPHDR *)(((UINT8 *)pIpHdrCurrent) + IPHdrLen);
// Get Seq and Ack
Seq = RdNet32( &pTcpHdr->dwSeq );
NewSeq = HNC32(Seq);
Ack = RdNet32( &pTcpHdr->dwAck );
NewAck = HNC32(Ack);
// Adjust sequencing
if( ModeCurrent == NAT_MODE_TX )
{
if( SEQ_LEQ( NewSeq, ppeCurrent->TxSeqThresh ) )
offseq = ppeCurrent->TxOffset1;
else
offseq = ppeCurrent->TxOffset2;
if( SEQ_LEQ( NewAck, ppeCurrent->RxSeqThresh ) )
offack = ppeCurrent->RxOffset1;
else
offack = ppeCurrent->RxOffset2;
}
else
{
if( SEQ_LEQ( NewAck, ppeCurrent->TxSeqThresh ) )
offack = ppeCurrent->TxOffset1;
else
offack = ppeCurrent->TxOffset2;
if( SEQ_LEQ( NewSeq, ppeCurrent->RxSeqThresh ) )
offseq = ppeCurrent->RxOffset1;
else
offseq = ppeCurrent->RxOffset2;
}
// If the sequence numbers have changed, replace them
if( offseq != 0 || offack != 0 )
{
// Replace the SEQ and ACK values
NewSeq = (UINT32)((INT32)NewSeq+(INT32)offseq);
NewSeq = HNC32(NewSeq);
NewAck = (UINT32)((INT32)NewAck-(INT32)offack);
NewAck = HNC32(NewAck);
WrNet32( &pTcpHdr->dwSeq, NewSeq );
WrNet32( &pTcpHdr->dwAck, NewAck );
ChecksumCurrent = 0;
}
// If the TCP checksum is invalid, redo it
if( !ChecksumCurrent )
{
// Checksum Header
tpseudo.dwIPSrc = RdNet32( &pIpHdrCurrent->dwIPSrc );
tpseudo.dwIPDst = RdNet32( &pIpHdrCurrent->dwIPDst );
tpseudo.Null = 0;
tpseudo.Protocol = 6;
tpseudo.Length = Length;
TcpChecksum( pTcpHdr );
}
}
// Send packet
IPTxPacket( hPktCurrent, FLG_IPTX_FORWARDING );
}
//--------------------------------------------------------------------
// ProxyPacketMod
//
// This function is called by the USER to modify a packet
//--------------------------------------------------------------------
IPHDR *ProxyPacketMod( uint Offset, uint OldSize, uint NewSize, UINT8 *pData )
{
// First, adjust the packet
// If the size is the same, its easy
if( NewSize == OldSize )
{
if( OldSize )
mmCopy( ((UINT8 *)pIpHdrCurrent)+Offset, pData, OldSize );
}
// If the size changes, we'll copy the entire fragment
else
{
HANDLE hFragO,hFragN;
UINT8 *pbO,*pbN;
UINT16 Length;
uint BufferLen,NewBuffer;
uint ValidLen,NewValid;
uint Off;
// Get the old frag
hFragO = PktGetFrag( hPktCurrent );
pbO = FragGetBufParams( hFragO, &BufferLen, &ValidLen, &Off );
// Alloc the new frag
NewBuffer = BufferLen + NewSize - OldSize;
NewValid = ValidLen + NewSize - OldSize;
hFragN = FragNewAlloc( FRAG_POOL_PACKET, NewBuffer, 0, NewValid, Off );
if( !hFragN )
return( pIpHdrCurrent );
pbN = FragGetBufParams( hFragN, 0, 0, 0 );
// Copy OldData, NewData, and rest of OldData
if( Offset )
mmCopy( pbN+Off, pbO+Off, Offset );
if( NewSize )
mmCopy( pbN+Off+Offset, pData, NewSize );
if( NewValid-Offset-NewSize )
mmCopy( pbN+Off+Offset+NewSize, pbO+Off+Offset+OldSize,
NewValid-Offset-NewSize);
// Add the new frag to the packet
PktSetFrag( hPktCurrent, hFragN );
FragFree( hFragO );
// Set the new IpHdr Ptr and Length
Length = HNC16(pIpHdrCurrent->TotalLen);
pIpHdrCurrent = (IPHDR *)(pbN+Off);
Length = Length + (UINT16)NewSize - (UINT16)OldSize;
pIpHdrCurrent->TotalLen = HNC16(Length);
// If TCP, adjust sequencing info
if( pIpHdrCurrent->Protocol == IPPROTO_TCP )
{
UINT16 IPHdrLen;
TCPHDR *pTcpHdr;
IPHdrLen = (pIpHdrCurrent->VerLen & 0xf) * 4;
pTcpHdr = (TCPHDR *)(((UINT8 *)pIpHdrCurrent) + IPHdrLen);
// Get the offset into the TCP payload
Off = pTcpHdr->HdrLen >> 2;
Off += IPHdrLen;
// See if alteration was in TCP payload
if( Offset >= Off )
{
UINT32 Seq;
// Start offset from start of TCP payload
Off = Offset - Off;
// Get the sequenct
Seq = RdNet32( &pTcpHdr->dwSeq );
Seq = HNC32(Seq);
Seq += (UINT32)Off;
if( ModeCurrent == NAT_MODE_TX )
{
// Track the first alteration in this packet
if( !Altered )
{
// If this packet preceeds an old alteration,
// then we resync the offset in hopes it will be OK
if( SEQ_LEQ( Seq, ppeCurrent->TxSeqThresh ) )
ppeCurrent->TxOffset2 = ppeCurrent->TxOffset1;
else
ppeCurrent->TxOffset1 = ppeCurrent->TxOffset2;
ppeCurrent->TxSeqThresh = Seq;
}
ppeCurrent->TxOffset2 += (NewSize - OldSize);
}
else
{
// Track the first alteration in this packet
if( !Altered )
{
// If this packet preceeds an old alteration,
// then we resync the offset in hopes it will be OK
if( SEQ_LEQ( Seq, ppeCurrent->RxSeqThresh ) )
ppeCurrent->RxOffset2 = ppeCurrent->RxOffset1;
else
ppeCurrent->RxOffset1 = ppeCurrent->RxOffset2;
ppeCurrent->RxSeqThresh = Seq;
}
ppeCurrent->RxOffset2 += (NewSize - OldSize);
}
Altered = 1;
}
}
}
ChecksumCurrent = 0;
return( pIpHdrCurrent );
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -