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

📄 nat_rx.c

📁 vxworks下ppp的实现源码
💻 C
📖 第 1 页 / 共 2 页
字号:
			return_code = handle_icmp_translation_global_rx_transaction ((ICMP_PACKET*)p_packet);			break;		case NAT_RIP:		case NAT_UDP:			return_code = handle_udp_translation_global_rx ((UDP_PACKET*)p_packet);			break;		case NAT_UNKNOWN_PROTOCOL:			if (nat.filter_unknown_protocols == TRUE)				{				return_code = FAIL;				}			else				{				return_code = TRUE;				}			break;		default:			return_code = FAIL;		}		return (return_code);}/********************************************************************************************	This function handles translation of outbound packets (i.e. received from local port).********************************************************************************************/static enum TEST nat_handle_translation_for_local_rx (M_BLK* pMblk,	enum NAT_PACKET_TYPES nat_packet_type){	enum TEST return_code;	/* none of the following functions currently use the port_number passed */			switch (nat_packet_type)		{		case NAT_TCP:			return_code = handle_tcp_translation_local_rx (				(TCP_PACKET *) pMblk->mBlkHdr.mData);			break;		case NAT_ICMP_DATAGRAM:			return_code = handle_icmp_translation_local_rx_datagram (				(ICMP_PACKET *) pMblk->mBlkHdr.mData);			break;		case NAT_ICMP_TRANSACTION:			return_code = handle_icmp_translation_local_rx_transaction (				(ICMP_PACKET *) pMblk->mBlkHdr.mData);			break;		case NAT_RIP:		case NAT_UDP:			return_code = handle_udp_translation_local_rx (				(UDP_PACKET *) pMblk->mBlkHdr.mData);			break;		case NAT_UNKNOWN_PROTOCOL:			if (nat.filter_unknown_protocols == TRUE)				{				return_code = FAIL;				}			else				{				return_code = TRUE;				}			break;		default:			return_code = FAIL;		}	return (return_code);}/*************************************************************************************Description:	Look for a registered agent (e.g. ALG) from the given NAT instance.*************************************************************************************/NAT_AGENT_INFO *nat_find_agent(	NAT_CLASS	*nat_p,	u_short		protocol,	u_long		remote_port,	u_long		local_port	){	NAT_AGENT_INFO	*agent_info;	        semTake(agentListLock, WAIT_FOREVER);        agent_info = (NAT_AGENT_INFO *) lstFirst(&nat.agent_list);	while (agent_info != NULL)	    {	    if (agent_info->session_tag.protocol == protocol && 		(agent_info->session_tag.transport == remote_port || 		 agent_info->session_tag.transport == local_port))		{		nat_printf (NAT_PRINTF_TRACE, 			    "Registered agent found for port %d\n", 			    agent_info->session_tag.transport);		break;		}	    agent_info = (NAT_AGENT_INFO *) lstNext((NODE*)agent_info);	    }	semGive(agentListLock);        return (agent_info);}/******************************************************************************** natIcmpErrorHookAdd - Install the NAT ICMP error handling routine**/void natIcmpErrorHookAdd (void)    {    if (_icmpErrorHook != NULL)        {        stdIcmpErrorHook = _icmpErrorHook;        _icmpErrorHook = (VOIDFUNCPTR)natIcmpErrorHook;        }    else        nat_printf (NAT_PRINTF_ERROR,                    "natIcmpErrorHookAdd Error: _icmpErrorHook is NULL\n");    }/******************************************************************************** natIcmpErrorHookRemove - Remove the NAT ICMP error handling routine**/void natIcmpErrorHookRemove (void)    {    if (stdIcmpErrorHook != NULL)        _icmpErrorHook = stdIcmpErrorHook;    }/******************************************************************************* natIcmpErrorHook - Process the ICMP error message generated by the stack** This routine handles the ICMP error message generated by the NAT device's* own IP stack on the NAT translated packets. Consider this scenario:* a TCP/UDP packet enters the NAT device via global port, is translated by NAT,* and is handed to the IP stack.  But the IP stack can't deliver the packet to * the local port because of an error condition (e.g., MTU size is too small* and the don't fragment bit is set).  The IP stack then constructs an* ICMP error message (e.g., destination unreachable) with the embedded * fragment of the offending packet. However, this fragment must be retranslated * back to its global address before sending it out to the driver. Otherwise it* will have incorrect local address. The same scenario can happen for a TCP/UDP * packet coming from a NAT device's local port. In this case, if we don't* retranslate the packet, it will possibly have the NAT device's own global * interface address as the destination address, thus will be wrongly sent to* the loopback interface.** To solve the problem, this routine will first convert the NAT translated * packet back to the original and then hand to the standard ICMP error handling* routine. This requires the standard ICMP error handle hook to be* installed with this new routine and the original one is called within* this routine.**/void natIcmpErrorHook     (    M_BLK_ID  pMblk, /* orginal IP packet */      int type,        /* ICMP type */    int code,        /* ICMP code */    ULONG dest,    struct ifnet *destifp    )    {    struct ifnet * pIf;    /* convert back the NAT translated packet to the original  */    pIf = pMblk->m_pkthdr.rcvif;    natTranslatedIpPacketConvert(pMblk,pIf,type);    /* call the standard ICMP error handling routine */    (*stdIcmpErrorHook)(pMblk,type,code,dest,destifp);    }/******************************************************************************** natTranslatedIpPacketConvert - convert back the NAT translated packet** This routine converts the NAT translated packet back to the original as if it* was not translated. When the packet pointed to by parameter pMblk arrives at* this function. It has already been translated by NAT filter. That means the* packet's destination,source addresses as well as the port numbers if it* is a TCP/UDP packet is no longer same as the ones when it came in the network* port. These elements need to be translated back. Instead of inventing a set* of reverse translation routines for the TCP,UDP or other packet headers, we* find it easy to constructs an ICMP packet with necessary fields and copy the* packet header as the payload of the ICMP packet, and then utilize existing* NAT ICMP translation routines to perfrom the conversion.** The converted packet header will be copied back to the original packet. The  * caller of this routine takes it and then call the standard ICMP error * handling routine. And a real ICMP packet will be constructed there.  ** This routine must also take consideration of the ICMP error messages generated* on the packets which are not touched by the NAT translation filter, are now* also intercepted by this new NAT ICMP error handling routine. They must not* be erroneously translated. **/LOCAL void natTranslatedIpPacketConvert    (    M_BLK_ID  pMblk,    /* original IP packet */    struct ifnet * pIf, /* network interface the packet coming from */    int type    )    {    M_BLK_ID pTmpMblk;    ICMP_PACKET * pIcmpPkt;    IP_PACKET * pIpPacket;    ULONG address;    int inx;    enum NAT_PORT_TYPE icmpPortType;    enum TEST retCode;    char ifName[IF_DEV_NAME_LEN];    /* filter out non NAT related packets */    if (nat.enabled == FALSE || pIf == NULL)        return;   /* no translation */    inx = 0;    while ((pIf->if_name[inx]) && (inx < (IF_DEV_NAME_LEN - 2)) )        ifName[inx] = pIf->if_name[inx++];            ifName[inx++] = '0' + pIf->if_unit;    ifName[inx++] = 0;    /* find this packet is coming from global or local interface or neither */    for (inx = 0; inx < sizeof(nat.port)/sizeof(nat.port[0]); inx++)        {        if ((nat.port[inx].ifunit == pIf) ||	    ((nat.port[inx].ifunit == NULL) &&  /* dynamically attached IF */	     (strcmp(nat.port[inx].ifname,ifName)==0)) )            {            /* Found the port */            break;            }        }    if (inx == sizeof(nat.port)/sizeof(nat.port[0]))        /* no port found, the packet does not come from a NAT port  */        return;  /* no translation */    /* allocate a mblk to hold the temp ICMP packet */    pTmpMblk = netTupleGet(_pNetDpool, 128,M_DONTWAIT,MT_DATA,TRUE);    if (pTmpMblk == NULL)        {        nat_printf (NAT_PRINTF_ERROR,                    "natIcmpErrorHook: Can't get a mblk\n");        return;        }    /* construct an incomplete ICMP header, good enough for the NAT ICMP     * translation     */    pIcmpPkt = (ICMP_PACKET *)(pTmpMblk->mBlkHdr.mData);    bcopy((char *)pMblk->mBlkHdr.mData,(char *)&pIcmpPkt->ip_header,	  sizeof(IP_HEADER));    pIcmpPkt->ip_header.protocol = IPPROTO_ICMP;    /* construct the ICMP error packet's destination and source addresses */    address = pIcmpPkt->ip_header.source_address;    pIcmpPkt->ip_header.source_address =pIcmpPkt->ip_header.destination_address;    pIcmpPkt->ip_header.destination_address = address;    pIcmpPkt->ip_header.total_length = htons(80);  /* fake one */     pIcmpPkt->header.checksum = 0x1122;  /* fake one */    pIcmpPkt->header.type     = type;    /* The ICMP error packet generated by this NAT deivce's IP stack on the     * packet coming from the NAT global port just looks as if a ICMP error     * packet coming from the NAT local interface and vice versa, as far as     * the NAT translation filter concerns.     */    /* so reverse the port type */    if (nat.port[inx].type == NAT_GLOBAL_PORT)	icmpPortType = NAT_LOCAL_PORT;    else	icmpPortType = NAT_GLOBAL_PORT;    /* Further checking whether this packet needs to be translated back */    if (nat_filter_rx(ntohl(pIcmpPkt->ip_header.destination_address),		      inx, icmpPortType) != NAT_TRANSLATE)        {        netMblkClFree(pTmpMblk);        return;   /* no translation */        }    /* copy the original IP and TCP headers  */    bcopy((char *)pMblk->mBlkHdr.mData,	  (char *)&pIcmpPkt->header.option.unreachable_message.ip_data,	  sizeof(IP_HEADER) + sizeof(TCP_HEADER));    /* perform the translation */    if (icmpPortType == NAT_GLOBAL_PORT)        {        retCode = nat_handle_translation_for_global_rx(                        (IP_PACKET *)(pTmpMblk->mBlkHdr.mData),                        NAT_ICMP_DATAGRAM);        }    else        {        retCode = nat_handle_translation_for_local_rx(pTmpMblk,			   NAT_ICMP_DATAGRAM);        }    if (retCode == FAIL)	{	/* again this packet is not translated by NAT, simply return */        netMblkClFree(pTmpMblk);        return;        }    /* now translation is done, copy it back to the original mblk */    bcopy((char *)&pIcmpPkt->header.option.unreachable_message.ip_data,              (char *)pMblk->mBlkHdr.mData,	      sizeof(IP_HEADER) + sizeof(TCP_HEADER));    /* the IP header checksum is most likely not correct due to the fact the      * ipintr zeroed it in the default configuration. Recalculate it.     */    pIpPacket = (IP_PACKET*) pMblk->mBlkHdr.mData;    /* The total length is already in host byte order, convert it back */    pIpPacket->header.total_length = htons(pIpPacket->header.total_length);    /* the offset is already in host byte order, convert it back */    pIpPacket->header.fragment = htons(pIpPacket->header.fragment);    /* do the checksum calculation */     pIpPacket->header.header_checksum = 0;    pIpPacket->header.header_checksum = in_cksum(pMblk,                   pIpPacket->header.version_header_length.header_length << 2);    /* the icmp_error will add IP header length to the total length field     * and assume the id field is in host byte order. So we need to set proper     * values for these two fields here before feeding to the icmp_error.     */    pIpPacket->header.total_length = ntohs(pIpPacket->header.total_length);    pIpPacket->header.total_length -=            (pIpPacket->header.version_header_length.header_length << 2);    pIpPacket->header.identifier = ntohs(pIpPacket->header.identifier);    pIpPacket->header.fragment = ntohs(pIpPacket->header.fragment);    /* free the allocated temporary mblk */    netMblkClFree(pTmpMblk);    }

⌨️ 快捷键说明

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