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

📄 ipin.c

📁 代码在ti的c67系列单片机上实现了完整的TCPIP协议栈
💻 C
📖 第 1 页 / 共 2 页
字号:
            if( Opt == IPOPT_RR || Opt == IPOPT_SSRR || Opt == IPOPT_LSRR )
            {
                // Get the offset
                w = pIpHdr->Options[OptIdx+2];

                // Offset less than 4 is illegal
                if( w<4 )
                {
                    // This is an ICMP error
                    // Give the whole works to ICMP
                    ips.dwBadoptions++;
                    w = IPHDR_SIZE+OptIdx+2;
                    ICMPGenPacket( pIpHdr, hIFRx, ICMP_PARAMPROB, w, 0 );
                    PktFree( hPkt );
                    return;
                }

                // Make offset Zero based (is normally 1 based)
                w--;
            }

            // Process Option
            switch( Opt )
            {
            // OPTION: NOP
            case IPOPT_NOP:
            default:
                break;

            // OPTION: Record Route
            case IPOPT_RR:
                // Ignore if there's no more room
                if( (w+4) >= OptSize )
                    break;

                // Get the IP of the outgoing IF (or local host)
                if( !(IPTmp = IPRouteIP( hIFRx, IPDst, IPSrc, Opt )) )
                {
                    // If no address found, we have an error
                    // Give the whole works to ICMP
                    ips.dwCantforward++;
                    if( IP_FORWARDING )
                        ICMPGenPacket( pIpHdr, hIFRx, ICMP_UNREACH,
                                       ICMP_UNREACH_HOST, 0 );
                    PktFree( hPkt );
                    return;
                }

                // Save IP addr in the header
                mmCopy( pIpHdr->Options+OptIdx+w, (UINT8 *)&IPTmp, 4 );

                // Bump the offset
                pIpHdr->Options[OptIdx+2] += sizeof(IPN);

                break;

            // OPTION: Source Route
            case IPOPT_LSRR:
            case IPOPT_SSRR:
                // If the packet isn't addressed to us, there's not much
                // to do.
                if( !BindFindByHost( 0, IPDst) )
                {
                    // If using SSRR or not routing, this is an error
                    if( Opt == IPOPT_SSRR || !IP_FORWARDING )
                    {
                        ips.dwCantforward++;
                        ICMPGenPacket( pIpHdr, hIFRx, ICMP_UNREACH,
                                            ICMP_UNREACH_SRCFAIL, 0 );
                        PktFree( hPkt );
                        return;
                    }
                    // Here we're using LSRR, but we can't do anything
                    break;
                }

                // Here we know the packet is for us. If we're at the
                // end of the source route, we're done

                if( w >= OptSize )
                    break;

                // Get the IP addr of the next hop
                mmCopy( (UINT8 *)&IPDst, pIpHdr->Options+OptIdx+w, 4 );

                // If we don't forward, or we can't get the next hop,
                // this is an error
                if( !IP_FORWARDING ||
                    !(IPTmp = IPRouteIP( hIFRx, IPDst, IPSrc, Opt )) )
                {
                    ips.dwCantforward++;
                    ICMPGenPacket( pIpHdr, hIFRx, ICMP_UNREACH,
                                               ICMP_UNREACH_SRCFAIL, 0 );
                    PktFree( hPkt );
                    return;
                }

                // Save outgoing IP addr in the header
                mmCopy( pIpHdr->Options+OptIdx+w, (UINT8 *)&IPTmp, 4 );

                // Patch the next hop destination
                WrNet32( &pIpHdr->dwIPDst, IPDst );

                // Bump the offset
                pIpHdr->Options[OptIdx+2] += sizeof(IPN);

                // Set Source Routing
                SrcRoute = 1;

                // The packet is now "from" us (local IF)
                // This suspends normal error checks for looping packets
                PktSetIFRx( hPkt, 0 );

                break;
            }
        }
    }

    //
    // If we have a filtered NET, then a packet from outside the
    // filtered net can not enter the filtered net
    //
    if( IP_FILTERENABLE && _IPFltMask )
    {
        // If the destination is in the protected net and the source
        // is not, drop the packet.
        if( ( IPDst & _IPFltMask ) == _IPFltAddr &&
            ( IPSrc & _IPFltMask ) != _IPFltAddr )
        {
            ips.dwFiltered++;
            PktFree( hPkt );
            return;
        }
    }

    //
    // If not source routing, see if the packet is for us.
    //
    if( !SrcRoute )
    {
        // We take the following packets:
        //     - The Dst is an all 0's BCast
        //     - The Dst is an all 1's BCast
        //     - The Dst is a Multicast Addr
        //     - The Dst is one of our host addresses
        //     - Sent directly to a non-configured IF
        if( IPDst == INADDR_ANY || IPDst == INADDR_BROADCAST ||
            IN_MULTICAST(IPDst) || BindFindByHost( 0, IPDst ) ||
                ( !(PktFlags & (FLG_PKT_MACMCAST|FLG_PKT_MACBCAST)) &&
                  hIFRx && !BindFindByIF( hIFRx ) ) )
        {
            // The packet is for us!!!

            //
            // First we must reassemble any fragmented packets
            //
            if( pIpHdr->FlagOff & ~HNC16(IP_DF) )
            {
                // Packet is fragmented
                //
                // We pass the packet to the IPReasm function, which
                // consumes the packet. When a packet is ready, it is
                // resubmitted to IpRxPacket
                //
                IPReasm( hPkt, hFrag, pIpHdr );
                return;
            }

#ifdef _INCLUDE_NAT_CODE
            if( IP_NATENABLE )
            {
                // NAT Processing for Received Packets
                NatRC = NatIpRxInput( hPkt, pIpHdr );
                if( NatRC > 0 )
                    goto forward_post_nat;
                if( NatRC < 0 )
                    return;
            }
#endif

            // Track packets we deliver to upper layers
            ips.dwDelivered++;

            // Dispatch the IP packet
            switch( pIpHdr->Protocol )
            {
            case IPPROTO_ICMP:
                ICMPInput( hPkt );
                break;
            case IPPROTO_TCP:
                TcpInput( hPkt );
                break;
            case IPPROTO_UDP:
                UdpInput( hPkt );
                break;
            case 2:             //IGMP
            default:
                ips.dwDelivered--;
                ips.dwNoproto++;
                RawInput( hPkt );
                break;
            }
            return;
        }
    }

    // If we get here, the packet is not for us
    // Verify Packet can be forwarded

    // We can not foward ...
    //    - if the packet was rx'd on a local IF AND we're not source
    //      routing (this is loop caused by a bad route configuration)
    //    - if forwarding disabled
    //    - if addressed to an experimental, multicast, or loopback IP
    //    - if mac addr received on was broadcast

    if( (!hIFRx && !SrcRoute) || !IP_FORWARDING ||
        IPDst == INADDR_ANY || IPDst == INADDR_BROADCAST ||
        IN_EXPERIMENTAL(IPDst) || IN_MULTICAST(IPDst) ||
        IN_LOOPBACK(IPDst) || (PktFlags & FLG_PKT_MACBCAST) )
    {
        ips.dwCantforwardBA++;
        PktFree( hPkt );
        return;
    }

    //
    // Forward Packet
    //

    // Process Time to Live
    w = pIpHdr->Ttl;
    if( w < 2 )
    {
        ips.dwExpired++;
        ICMPGenPacket( pIpHdr, hIFRx, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, 0 );
        PktFree( hPkt );
        return;
    }
    pIpHdr->Ttl = (UINT8)(w-1);

#ifdef _INCLUDE_NAT_CODE
    // NAT Processing for Transmitted Packets
    if( IP_NATENABLE && NatIpTxInput( hPkt, pIpHdr ) )
        return;
forward_post_nat:
#endif

    // Set the IPTx Flags
    // Send the packet
    if( SrcRoute )
        IPTxPacket( hPkt, FLG_IPTX_FORWARDING|FLG_IPTX_SRCROUTE );
     else
        IPTxPacket( hPkt, FLG_IPTX_FORWARDING );

    return;
}


⌨️ 快捷键说明

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