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

📄 ipin.c

📁 代码在ti的c67系列单片机上实现了完整的TCPIP协议栈
💻 C
📖 第 1 页 / 共 2 页
字号:
//--------------------------------------------------------------------------
// Ip Stack
//--------------------------------------------------------------------------
// IPIN.C
//
// Routines related to IP Receive
//
//
// Author: Michael A. Denio
// Copyright 1999 by Texas Instruments Inc.
//-------------------------------------------------------------------------
#include <stkmain.h>
#include "ip.h"

static IPN _IPFltAddr = 0;
static IPN _IPFltMask = 0;

//--------------------------------------------------------------------
// IPFilterSet() - Set IP Filtered Net
//
// The stack has the ability to protect one network (which can be
// a combination of multiple networks). The IP address and mask is
// set by this function. The feature is enabled via a configuration
// entry.
//--------------------------------------------------------------------
void IPFilterSet( IPN IPAddr, IPN IPMask )
{
    _IPFltAddr = IPAddr & IPMask;
    _IPFltMask = IPMask;
}

//--------------------------------------------------------------------
// IPRouteIP() - Find Route's Outgoing IP
//
// Return the IP address of the outgoing IF for a packet routed
// to the IP address supplied in IPDst. The Source IP is provided
// in the event that the Dest IP does not contain any relevant
// information (e.g.: broadcast or multicast).
//--------------------------------------------------------------------
static IPN IPRouteIP( HANDLE hIF, IPN IPDst, IPN IPSrc, uint Opt )
{
    HANDLE hRt;
    IPN    IPOut;

    // This function will potentially have to examine routes, but
    // we'll try the easy cases first.

    // Anything sent via a local IF (NULL) can be looked up by IPDst
    // We know this since it is the only way a NULL IF packet could
    // have got this far.
    if( !hIF )
    {
        // Try and verify the local IP host address. Otherwise,
        // we'll just use the IPDst. Note that we punt if we
        // don't verify the IP. We don't use IPSrc because we know
        // the packet came from another local IF. Therefore, the
        // IPSrc doesn't reperesent the IP subnet of the outgoing
        // interface.
        if( !(IPOut = BindIFNet2IPHost( hIF, IPDst )) )
            return( IPDst );
        return( IPOut );
    }

    // 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

    // Do BCast and Multicast First
    if( IPDst == INADDR_ANY || IPDst == INADDR_BROADCAST ||
        IN_MULTICAST(IPDst) )
    {
        // The packet is ours, but we don't have a sub-net to lookup
        // our IF's IP address. First, we'll try and find one based
        // in the IPNet of the source

        if( !(IPOut = BindIFNet2IPHost( hIF, IPSrc )) )
        {
            // Oops, now we're not sure of the true dest - we'll
            // simply return anything we find on hIF
            IPOut = BindIF2IPHost( hIF );
        }
        return( IPOut );
    }

    // See if this packet is addressed directly to us
    if( BindFindByHost( 0, IPDst ) )
        return( IPDst );

    // This is a routed packet (not for us). If forwarding is off,
    // there is no reason to go on.
    if( !IP_FORWARDING )
        return( 0 );

    // Now find the next hop for this packet. Search for a route
    // WITHOUT cloning. All we need from the route is the outgoing
    // IF / IP.
    if( !(hRt = IPGetRoute( FLG_RTF_REPORT, IPDst, Opt )) )
        return(0);

    // We have a viable route for the packet. Now, get the IP host
    // address of the outgoing IF on the IP subnet of the next hop.

    // We can look up the IP of the outgoing IF directly.
    IPOut = BindIFNet2IPHost( RtGetIF(hRt), RtGetIPAddr(hRt) );
    RtDeRef( hRt );

    // Note: Sometimes IPOut will be NULL!
    // IPOut == NULL is an odd case. What happens is
    // that we have a route for a host for which we don't
    // have a network! This can only be caused by an illegal
    // host, or by a misconfiguration. Since we have no
    // outgoing IP for this IF/Host, we're forced to
    // return NULL.
    return( IPOut );
}

//--------------------------------------------------------------------
// IPRxPacket( HANDLE hPkt )
//
// Processes message containing a newly received IP packet
//--------------------------------------------------------------------
void IPRxPacket( HANDLE hPkt )
{
    HANDLE   hFrag,hIFRx;
    uint     w,Offset,Valid,IPHdrLen,SrcRoute;
    uint     PktFlags;
    UINT8    *pb;
    IPHDR    *pIpHdr;
    IPN      IPDst,IPSrc,IPTmp;
#ifdef _INCLUDE_NAT_CODE
    int      NatRC;
#endif

    // If not executing, then no frame gets through
    if( !_IPExecuting )
    {
        PktFree( hPkt );
        return;
    }

    // Get the frag for this packet
    if( !(hFrag = PktGetFrag( hPkt )) )
    {
        DbgPrintf(DBG_ERROR,"IPRxPacket: No frag");
        PktFree( hPkt );
        return;
    }

    // Get the the receiving interface
    hIFRx = PktGetIFRx( hPkt );

    // Get the buffer parameters
    pb = FragGetBufParams( hFrag, 0, &Valid, &Offset );

    // We don't ever use the LLC
    PktFlags = PktGetFlags( hPkt );
    if( PktFlags & FLG_PKT_LLC_VALID )
    {
        // Get offset to our data
        w = PktGetSizeLLC( hPkt );
        Offset += w;
        Valid  -= w;

        // Patch the LLC out of the packet
        FragSetBufParams( hFrag, Valid, Offset );
        PktSetFlagsClear( hPkt, FLG_PKT_LLC_VALID );
    }

    // Assign a IP header pointer
    pIpHdr = (IPHDR *)(pb + Offset);

    // Bump Rx Count
    ips.dwTotal++;

    // We only handle IP version 4
    if( (pIpHdr->VerLen & 0xf0) != 0x40 )
    {
        ips.dwBadvers++;
        PktFree( hPkt );
        return;
    }

    // Make sure size is in range and not bigger than the packet length
    if( (IPHdrLen = ((pIpHdr->VerLen & 0xf)*4) ) < IPHDR_SIZE ||
                     IPHdrLen > Valid )
    {
        ips.dwBadhlen++;
        PktFree( hPkt );
        return;
    }

    // Make sure total length is reasonable, and not bigger than the
    // packet length
    w = (uint)pIpHdr->TotalLen;
    if( HNC16(w) > Valid )
    {
        ips.dwBadlen++;
        PktFree( hPkt );
        return;
    }

    // Record the length for others
    PktSetSizeNet( hPkt, IPHdrLen );
    PktSetFlagsSet( hPkt, FLG_PKT_IP_VALID );

    // Verify the IP header checksum
    w = (uint)pIpHdr->Checksum;
    IPChecksum( pIpHdr );
    if( w != (uint)pIpHdr->Checksum )
    {
        ips.dwBadsum++;
        PktFree( hPkt );
        return;
    }

    // Record the Destination and Source IP
    IPDst = RdNet32( &pIpHdr->dwIPDst );
    IPSrc = RdNet32( &pIpHdr->dwIPSrc );

    // Initially assume no source routing
    SrcRoute = 0;

    //
    // Process any IP Options
    //
    if( IPHdrLen > IPHDR_SIZE )
    {
        uint    OptIdx,OptBytes,OptSize;
        UINT8   Opt;

        // Byte count of options
        OptBytes = IPHdrLen - IPHDR_SIZE;

        // Process option bytes
        for( OptIdx = 0; OptIdx < OptBytes; OptIdx += OptSize )
        {
            Opt = pIpHdr->Options[OptIdx];

            // Validate Option and Get Size
            if( Opt == IPOPT_EOL )
                break;
            else if( Opt == IPOPT_NOP )
                OptSize = 1;
            else
            {
                OptSize = pIpHdr->Options[OptIdx+1];
                if( OptSize <= 0 || OptSize > OptBytes )
                {
                    // This is an ICMP error
                    // Give the whole works to ICMP
                    ips.dwBadoptions++;
                    w = IPHDR_SIZE + OptIdx + 1;
                    ICMPGenPacket( pIpHdr, hIFRx, ICMP_PARAMPROB, w, 0 );
                    PktFree( hPkt );
                    return;
                }
            }

            // Check for legal opiton offset on RECORD ROUTE variants

⌨️ 快捷键说明

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