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

📄 proxy.c

📁 代码在ti的c67系列单片机上实现了完整的TCPIP协议栈
💻 C
📖 第 1 页 / 共 2 页
字号:
//--------------------------------------------------------------------------
// Ip Stack
//--------------------------------------------------------------------------
// PROXY.C
//
// Network Address Translation
//
// Author: Michael A. Denio
// Copyright 1999, 2000 by Texas Instruments Inc.
//-------------------------------------------------------------------------
#include <stkmain.h>
#ifdef _INCLUDE_NAT_CODE
#include "nat.h"
#include "proxy.h"

// Head of linked lists for proxies
static PROXY *pProxy[4] = { 0, 0, 0, 0 };

static HANDLE ProxyFind( uint ProxyMode, UINT16 Port );
static void   ProxyComplete();

//
// Static "current" values. We get away with this since PROXY is
// single threaded.
//
static PROXYENTRY *ppeCurrent;
static HANDLE     hPktCurrent;
static int        ChecksumCurrent;
static IPHDR      *pIpHdrCurrent;
static uint       ModeCurrent;
static uint       Altered;

//--------------------------------------------------------------------
// ProxyNew - Create a PROXY
//
// ProxyType      - NatMode
// Protocol       - Protocol (TCP or UDP)
// Port           - TCP/UDP Port
// IPTarget       - Target IP of Local Machine (for mapping)
// pfnEnableCb    - Callback for enabling new proxy
// pfnTxCb        - Callback for Local to Foreign packet
// pfnRxCb        - Callback for Foreign to Local packet
//
//--------------------------------------------------------------------
HANDLE ProxyNew( uint NatMode, UINT8 Protocol, UINT16 Port, IPN IPTarget,
                 int (*pfnEnableCb)( NATINFO *, uint ),
                 int (*pfnTxCb)( NATINFO *, IPHDR * ),
                 int (*pfnRxCb)( NATINFO *, IPHDR * ) )
{
    PROXY    *pp;
    PROXY    **ppProxList;

    // Check for illegal arguments
    if( !Port || (NatMode > 1) )
        return(0);

    // Adjust Nat Mode by protocol
    if( Protocol == IPPROTO_UDP )
        NatMode += PROXY_OFFSET_UDP;
    else if( Protocol != IPPROTO_TCP )
        return(0);

    // Can't proxy reserved port range
    if( Port >= SOCK_RESPORT_FIRST && Port <= SOCK_RESPORT_LAST )
        return(0);

    // If a proxy already exists, delete it
    if( (pp = ProxyFind( NatMode, Port )) != 0 )
        ProxyFree( pp );

    if( !(pp = mmAlloc(sizeof(PROXY))) )
    {
        DbgPrintf(DBG_WARN,"ProxyNew: OOM");
        ExecLowResource();
        return(0);
    }

    // Initialize type
    pp->Type = HTYPE_PROXY;

    // Set information
    pp->NatMode     = NatMode;
    pp->Port        = Port;
    pp->IPTarget    = IPTarget;
    pp->pfnEnableCb = pfnEnableCb;
    pp->pfnTxCb     = pfnTxCb;
    pp->pfnRxCb     = pfnRxCb;

    // Init our forward pointer
    pp->pNext     = 0;

    // Get the list pointer
    ppProxList = &pProxy[NatMode];

    // If there's a "next" entry, point to it and point it
    // back to us
    if( *ppProxList )
    {
        pp->pNext         = *ppProxList;
        pp->pNext->ppPrev = &pp->pNext;
    }

    // Put us at head of the list
    *ppProxList = pp;
    pp->ppPrev  = ppProxList;

    return( pp );
}

//--------------------------------------------------------------------
// ProxyFree - Free a proxy entry
//--------------------------------------------------------------------
void ProxyFree( HANDLE hProxy )
{
    PROXY *pp = (PROXY *)hProxy;

#ifdef _STRONG_CHECKING
    if( pp->Type != HTYPE_PROXY )
    {
        DbgPrintf(DBG_ERROR,"ProxyFree: HTYPE %04x",pp->Type);
        return;
    }
#endif

    // Remove Entry from linked list
    *pp->ppPrev = pp->pNext;
    if( pp->pNext )
        pp->pNext->ppPrev = pp->ppPrev;

    // Zap it
    pp->Type = 0;
    mmFree( pp );
}

//--------------------------------------------------------------------
// ProxyFind - Find a proxy entry from Type and Port
//--------------------------------------------------------------------
static HANDLE ProxyFind( uint ProxyMode, UINT16 Port )
{
    PROXY *pp;

    // Quick error check
    if( ProxyMode > 3 )
        return(0);

    // Get the first entry
    pp = pProxy[ProxyMode];

    // Search
    while( pp )
    {
        if( pp->Port == Port )
            return( pp );
        pp = pp->pNext;
    }

    return(0);
}

//--------------------------------------------------------------------
// ProxyEntrySpawn - Create New Proxy Entry
//--------------------------------------------------------------------
int ProxyEntrySpawn( uint NatMode, UINT8 Protocol, UINT16 Port,
                     HANDLE *phProxyEntry, IPN *pIPLocal )
{
    PROXY *pp;
    PROXYENTRY *ppe;

    // Quick error check
    if( NatMode > 1 )
        return(0);

    // Adjust Nat Mode by protocol
    if( Protocol == IPPROTO_UDP )
        NatMode += PROXY_OFFSET_UDP;
    else if( Protocol != IPPROTO_TCP )
        return(0);

    // Get the first entry
    pp = pProxy[NatMode];

    // Search
    while( pp )
    {
        if( pp->Port == Port )
            goto Found;
        pp = pp->pNext;
    }
    return(0);

Found:
    if( !(ppe = mmAlloc(sizeof(PROXYENTRY))) )
    {
        DbgPrintf(DBG_WARN,"ProxyEntryNew: OOM");
        ExecLowResource();
        return(0);
    }

    mmZeroInit( ppe, sizeof(PROXYENTRY) );

    // Initialize type
    ppe->Type = HTYPE_PROXYENTRY;

    // Set information
    ppe->pfnEnableCb = pp->pfnEnableCb;
    ppe->pfnTxCb = pp->pfnTxCb;
    ppe->pfnRxCb = pp->pfnRxCb;

    // If the entry handle pointer is valid, return it
    if( phProxyEntry )
        *phProxyEntry = ppe;

    // If the IP pointer is valid, return the IPDst
    if( pIPLocal )
        *pIPLocal = pp->IPTarget;

    // Return success
    return( 1 );
}

//--------------------------------------------------------------------
// ProxyEnable
//
// Called to Enable or Disable a Proxy
//--------------------------------------------------------------------
int ProxyEnable( NATINFO *pni, uint Enable )
{
    // Get the current proxy entry
    ppeCurrent = (PROXYENTRY *)pni->hProxyEntry;

    // Call user callback
    if( ppeCurrent->pfnEnableCb )
        return( ppeCurrent->pfnEnableCb( pni, Enable ) );

    // If no callback we always enable
    return(1);
}

//--------------------------------------------------------------------
// ProxyTx
//
// Called to modify a proxy TX packet
//--------------------------------------------------------------------
void ProxyTx( NATINFO *pni, HANDLE hPkt, IPHDR *pIpHdr )
{
    ModeCurrent = NAT_MODE_TX;

    // 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->pfnTxCb )
        if( !ppeCurrent->pfnTxCb( 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();
}

⌨️ 快捷键说明

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