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

📄 proxy.c

📁 代码在ti的c67系列单片机上实现了完整的TCPIP协议栈
💻 C
📖 第 1 页 / 共 2 页
字号:
//--------------------------------------------------------------------
// 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 + -