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

📄 nat_rx.c

📁 vxworks下ppp的实现源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* nat_rx.c *//* Copyright 2000-2003 Wind River Systems, Inc. *//* @format.tab-size 4, @format.use-tabs true, @format.new-line lf *//*modification history--------------------01j,18jul03,vks  changes for Virtual Stack01i,16jun03,myz  Replace old fragment translation APIs with new ones.01h,09may03,myz  reworked SPR6969801g,02may03,vks  corrected header for natIpOutputFilterHook, removed #ifdef 0                 code from it01f,01may03,zhu  renamed SPR69698_PATCH to NAT_OUTPUT_FILTER01e,28apr03,myz  fixed problem introduced in 01c version.01d,28apr03,myz  removed org_src_addr, use the value in org_ip_header.01c,25apr03,myz  Modified nat_rx function to improve the performance.01b,21apr03,myz  replaced swap(_long) with the ntohs(l) and htons(l) macros.01a,15apr03,zhu  replaced function call with direct access, fixed a bug in ALG                 fragments092402  vvv replaced rw_container lists with linked lists to improve performance092302  vvv used direct copy instead of memcpy to copy IP header to improve             performance101901  tk  Fix data type to avoid warning in T3 compiler.101601	tk  Add a case for ICMP protocol in nat_get_src_transport().092801	tk  Fix SPR69698: Added a special hook to handle icmp error generated             by IP stack. This hook was not included in the NAT 1.1 FCS.071301	tk  Add code to call the agent callback function for no-NAT translation.051501	tk  Fix SPR67123: Global FTP client can't connect to local server when             client issues PASV command.  Add new function             nat_get_src_transport() to check source port.042101	tk  Fix ICMP redirect packet handling.  Should be ignored by NAT             per RFC1631.*//* ANSI headers */#include <string.h>/* RouterWare headers */ #include "nat.h"#include "net/mbuf.h"#include "netBufLib.h"#ifdef VIRTUAL_STACK#include "netinet/vsLib.h"#endif /* VIRTUAL_STACK *//* Local defines */#define IF_DEV_NAME_LEN  16/********************************************************************************************Static functions and variables********************************************************************************************/static enum TEST nat_handle_translation_for_global_rx (IP_PACKET*,	enum NAT_PACKET_TYPES nat_packet_type);static enum TEST nat_handle_translation_for_local_rx (M_BLK*,	enum NAT_PACKET_TYPES nat_packet_type);LOCAL void natTranslatedIpPacketConvert (M_BLK_ID, struct ifnet *,int);/********************************************************************************************Function declarations********************************************************************************************/extern NAT_AGENT_INFO *nat_find_agent(	NAT_CLASS	*nat_p,	u_short		protocol,	u_long		remote_port,	u_long		local_port	);#ifndef VIRTUAL_STACKextern VOIDFUNCPTR      _icmpErrorHook;#endif /* VIRTUAL_STACK */LOCAL  VOIDFUNCPTR      stdIcmpErrorHook = NULL;void natIcmpErrorHook (struct mbuf *, int, int, ULONG, struct ifnet *);/*******************************************************************************************/enum TEST nat_rx (USHORT port_number, M_BLK* pMblk)    {    enum NAT_PORT_TYPE nat_port_type;    ULONG_ENUM (NAT_PACKET_TYPES) nat_packet_type;    enum NAT_FILTER nat_filter_result;    NAT_AGENT_INFO* agent_info;    enum TEST return_code;    u_long	org_dst_addr;    u_long  org_src_addr;    char addr_str[32];    IP_PACKET *sptr_ip_packet;    NAT_DIRECTION	direction;    UINT16 srcTransport, dstTransport;    void * pFragEntry;    sptr_ip_packet = (IP_PACKET*) pMblk->mBlkHdr.mData;    /* possible unaligned access if the offset value is not set properly in     * the ethernet END driver     */    org_dst_addr = sptr_ip_packet->header.destination_address;    org_src_addr = sptr_ip_packet->header.source_address;    nat_port_type = nat.port[port_number].type;  /* local or global port */    /* do filter first (translate or not translate), so packets do not need     * to be translated, such as local traffic, can get out this function ASAP.      */    nat_filter_result = nat_filter_rx (ntohl(org_dst_addr), port_number,                                 nat_port_type);    if (nat_filter_result == NAT_DONT_TRANSLATE)        {        return (PASS);        }    else if (nat_filter_result == NAT_FILTER)        {        return (FAIL);        }    /* Now check ICMP redirect msg, Per RFC1631: NAT doesn't handle it */    nat_packet_type = nat_packet_discriminator (sptr_ip_packet);    if (nat_packet_type == NAT_ICMP_REDIRECT)        {        return (PASS);        }    /* Handle fragmented IP datagram */    pFragEntry = NULL;    if ( (sptr_ip_packet->header.fragment & IP_FRAGMENT_OFFSET_MASK) == 0)        {        if (sptr_ip_packet->header.fragment & IP_FRAGMENT_FLAG_MORE_FRAGMENTS)            {            /* first fragment, create fragment translation entry */            pFragEntry = (void *)natFragTranEntryGet (nat_port_type,                                           sptr_ip_packet);            if (pFragEntry == NULL)                return (FAIL);            }        }    else    /* subsequent fragment */        {        return_code = natFragAddrTranslate (nat_port_type, sptr_ip_packet);        return (return_code);        }    if (nat_port_type == NAT_GLOBAL_PORT)        {        direction = NAT_INBOUND;        }    else	/* local port */        {        direction = NAT_OUTBOUND;        }    /* Do not translate OSPF or outbound RIP packets */	    if ((nat_packet_type == NAT_OSPF) 	|| ((nat_packet_type == NAT_RIP) && (direction == NAT_OUTBOUND)))        {        return (PASS);        }    /********************************************/    /* Search for installed ALG for this packet */    /********************************************/    if (sptr_ip_packet->header.protocol == IPPROTO_TCP)         {        srcTransport = ntohs( ((TCP_PACKET*)                               sptr_ip_packet)->tcp_header.source_port );        dstTransport = ntohs( ((TCP_PACKET*)                               sptr_ip_packet)->tcp_header.destination_port );        }    else if(sptr_ip_packet->header.protocol == IPPROTO_UDP)         {        srcTransport = ntohs( ((UDP_PACKET*)                               sptr_ip_packet)->header.source_port );        dstTransport = ntohs( ((UDP_PACKET*)                               sptr_ip_packet)->header.destination_port );        }    else        {        srcTransport = 0;        dstTransport = 0;        }    agent_info = nat_find_agent(&nat, sptr_ip_packet->header.protocol,                                 dstTransport, srcTransport);    nat.agent_info = agent_info;	    /* ALG packet translations - PRE NAT */    if (agent_info != NULL && agent_info->flags & NAT_FLAG_PRE_XLAT        && agent_info->packet_callback != NULL)        {        nat_printf (NAT_PRINTF_TRACE,                     "nat_rx: calling agent (%s) packet callback (pre-NAT)\n",                    agent_info->name);        if (agent_info->packet_callback((u_long)&nat, agent_info->id,                         0, /* session_id */                        direction, sptr_ip_packet)==FALSE)            {            nat_printf(NAT_PRINTF_TRACE,                        "nat_rx: agent (%s) packet callback returned FALSE\n",                       agent_info->name);            return(FAIL);            }        }    /* NAT Built-in translations (TCP/UDP/ICMP) if no matching registered      * agent or the registered agent processes only the payload      */    if (agent_info == NULL || (agent_info->flags & NAT_FLAG_NO_XLAT)==0)         {        switch (nat_port_type)            {            case NAT_GLOBAL_PORT:                return_code = nat_handle_translation_for_global_rx (                                    sptr_ip_packet, nat_packet_type);				                if (return_code == FAIL)                    return (FAIL);                if (pFragEntry != NULL)		    {                    return_code = natFragTranAddrSave(NAT_GLOBAL_PORT,                                   pFragEntry,                                   sptr_ip_packet->header.destination_address);                    if (return_code == FAIL)                        return (FAIL);                    }                break;            case NAT_LOCAL_PORT:		return_code = nat_handle_translation_for_local_rx (pMblk,                                  nat_packet_type);                if (return_code == FAIL)                    return (FAIL);				                if (pFragEntry != NULL)                    {                    return_code = natFragTranAddrSave(NAT_LOCAL_PORT,pFragEntry,                                   sptr_ip_packet->header.source_address);                    if (return_code == FAIL)                        return (FAIL);                    }                break;            default:		nat_printf (NAT_PRINTF_ERROR,                             "nat_rx: Unknown port type %d for port number %d\n",                             nat_port_type, port_number);				                return (FAIL);            }        }    /* ALG packet translations - POST NAT */    if (agent_info != NULL && agent_info->flags & NAT_FLAG_POST_XLAT        && agent_info->packet_callback != NULL)        {        nat_printf (NAT_PRINTF_TRACE,                     "nat_rx: calling agent (%s) packet callback (post-NAT)\n",                    agent_info->name);        if (agent_info->packet_callback((u_long)&nat, agent_info->id, 0,            direction, sptr_ip_packet)==FALSE)            {            nat_printf(NAT_PRINTF_TRACE,                        "nat_rx: agent (%s) packet callback returned FALSE\n",                        agent_info->name);            return(FALSE);            }        }    /* ALG translates entire packet */    if (agent_info != NULL && agent_info->flags & NAT_FLAG_NO_XLAT        && agent_info->packet_callback != NULL)        {	nat_printf (NAT_PRINTF_TRACE,                     "nat_rx: calling agent (%s) packet callback (no-NAT)\n",                    agent_info->name);        if (agent_info->packet_callback((u_long)&nat, agent_info->id, 0,                            direction, sptr_ip_packet)==FALSE)            {            nat_printf(NAT_PRINTF_TRACE,                        "nat_rx: agent (%s) packet callback returned FALSE\n",                       agent_info->name);            return(FALSE);            }        /* If this is first fragment of larger packet, store the modified          * address.          */        if (pFragEntry != NULL) /* insert the new source address here */            {            if (nat_port_type == NAT_GLOBAL_PORT)                return_code = natFragTranAddrSave(NAT_GLOBAL_PORT,pFragEntry,                                    sptr_ip_packet->header.destination_address);            else                return_code = natFragTranAddrSave(NAT_LOCAL_PORT,pFragEntry,                                    sptr_ip_packet->header.source_address);            if (return_code == FAIL)                return (FAIL);            }        }    if (nat.printing_enabled == true || nat.logging_enabled == true)         {        struct in_addr iaddr;        iaddr.s_addr = org_src_addr;        inet_ntoa_b(iaddr,addr_str);        nat_printf (NAT_PRINTF_DATA,                     "nat_rx: original IP hdr source address: %s\n",                     addr_str);        iaddr.s_addr = sptr_ip_packet->header.source_address;        inet_ntoa_b(iaddr,addr_str);        nat_printf (NAT_PRINTF_DATA,                     "nat_rx: translated IP hdr source address: %s\n",                     addr_str);        iaddr.s_addr = org_dst_addr;        inet_ntoa_b(iaddr,addr_str);        nat_printf (NAT_PRINTF_DATA,                     "nat_rx: original IP hdr destination address: %s\n",                     addr_str);         iaddr.s_addr = sptr_ip_packet->header.destination_address;        inet_ntoa_b(iaddr,addr_str);        nat_printf (NAT_PRINTF_DATA,                     "nat_rx: translated IP hdr destination address: %s\n",                     addr_str);        }    return (PASS);       }/********************************************************************************************	This function handles translation of inbound packets (i.e. received from global port).********************************************************************************************/static enum TEST nat_handle_translation_for_global_rx (IP_PACKET* p_packet, 	enum NAT_PACKET_TYPES nat_packet_type){	enum TEST return_code;		switch (nat_packet_type)		{		case NAT_TCP:			return_code = handle_tcp_translation_global_rx ((TCP_PACKET*)p_packet);			break;		case NAT_ICMP_DATAGRAM:			return_code = handle_icmp_translation_global_rx_datagram ((ICMP_PACKET*)p_packet);			break;		case NAT_ICMP_TRANSACTION:

⌨️ 快捷键说明

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