?? nat_icmp_transaction.c
字號:
/* nat_icmp_transaction.c */
/* Copyright 2000-2003 Wind River Systems, Inc. */
/* @format.tab-size 4, @format.use-tabs true, @format.new-line lf */
/*
modification history
--------------------
01b,24apr03,zhu updated copyright
01a,21apr03,myz replaced swap(_long) with the ntohs(l) and htons(l) macros,
replaced RWOS list functions with ones in dllLib.c.
040803 vks updated Copyright info
040303 vks replacing table_malloc with calloc
050701 tk Fix problem with ICMP time-exceeded message. The ICMP time-exceeded message
is handled as a datagram and is therefore moved to nat_icmp_datagram.c.
Add comment in the code.
*/
#include "nat.h"
#include "nat_api.h"
/************************************************************************/
enum TEST handle_icmp_translation_global_rx_transaction_nats (ICMP_PACKET *sptr_icmp_packet);
static enum TEST handle_icmp_translation_global_rx_transaction_natg (ICMP_PACKET *sptr_icmp_packet);
static enum TEST handle_icmp_translation_local_rx_transaction_nats (ICMP_PACKET *sptr_icmp_packet);
static enum TEST handle_icmp_translation_local_rx_transaction_natg (ICMP_PACKET *sptr_icmp_packet);
/******************************************add by zbb********************************************/
static NAT_CURRENCY_TRANSLATION_ENTRY *new_icmp_translation_entry (ICMP_PACKET *sptr_icmp_packet);
static NAT_CURRENCY_TRANSLATION_ENTRY *find_icmp_entry (ICMP_PACKET *sptr_icmp_packet);
extern unsigned long c_icmp_translation_entry;
/************************************************************************/
enum TEST handle_icmp_translation_global_rx_transaction (ICMP_PACKET *sptr_icmp_packet)
{
enum TEST pass_or_fail;
if (nat.single_global_address_enabled == TRUE)
{
pass_or_fail = handle_icmp_translation_global_rx_transaction_nats (sptr_icmp_packet);
}
else
{
pass_or_fail = handle_icmp_translation_global_rx_transaction_natg (sptr_icmp_packet);
}
return (pass_or_fail);
}
/***************************************************************************/
enum TEST handle_icmp_translation_local_rx_transaction (ICMP_PACKET *sptr_icmp_packet)
{
enum TEST pass_or_fail;
if (nat.single_global_address_enabled == TRUE)
{
pass_or_fail = handle_icmp_translation_local_rx_transaction_nats (sptr_icmp_packet);
}
else
{
pass_or_fail = handle_icmp_translation_local_rx_transaction_natg (sptr_icmp_packet);
}
return (pass_or_fail);
}
/*********************************************************************************************
Description:
This function handles translation of ICMP transactions received from global NAPT port.
If a match of the ICMP identifier is not found, it goes to the default ICMP address if
configured in natcfg.c and perform the translation and checksum adjustment. If the
ICMP address is not configured, it passes the ICMP packet to the higher layer.
**********************************************************************************************/
enum TEST handle_icmp_translation_global_rx_transaction_nats (ICMP_PACKET *sptr_icmp_packet)
{
NAT_CURRENCY_TRANSLATION_ENTRY *sptr_icmp_translation_entry=NULL;
USHORT icmp_identifier;
USHORT spoofed_icmp_identifier;
IP_ADDRESS address;
USHORT checksum;
spoofed_icmp_identifier = ntohs (sptr_icmp_packet->header.option.echo_message.identifier);
spoofed_icmp_identifier=spoofed_icmp_identifier&(UPPER_EPHEMERAL_PORT_VALUE-1);
semTake(natentrylock,WAIT_FOREVER);
sptr_icmp_translation_entry=out_port_map[spoofed_icmp_identifier].next_entrys_link;
for(;sptr_icmp_translation_entry!=NULL;sptr_icmp_translation_entry=sptr_icmp_translation_entry->next_entrys_link)
{
if (sptr_icmp_translation_entry->remote_address== ntohl(sptr_icmp_packet->ip_header.source_address)
&&(sptr_icmp_translation_entry->spoofed_local_port== ntohs(sptr_icmp_packet->header.option.echo_message.identifier))
&&(sptr_icmp_translation_entry->protocol_type==sptr_icmp_packet->ip_header.protocol))
{
break;
}
}
if(sptr_icmp_translation_entry==NULL)
{
semGive(natentrylock);
return (FAIL);
}
if (sptr_icmp_translation_entry->local_port!= 0x0000)
{
icmp_identifier = htons (sptr_icmp_translation_entry->local_port);
checksum = sptr_icmp_packet->header.checksum;
checksum_fixup ((BYTE *) &checksum,
(BYTE *) &sptr_icmp_packet->header.option.echo_message.identifier, sizeof (USHORT),
(BYTE *) &icmp_identifier, sizeof (USHORT));
sptr_icmp_packet->header.option.echo_message.identifier = icmp_identifier;
sptr_icmp_packet->header.checksum = checksum;
}
else
{
semGive(natentrylock);
return (PASS);
}
address = htonl (sptr_icmp_translation_entry->local_address);
checksum = sptr_icmp_packet->ip_header.header_checksum;
if(sptr_icmp_translation_entry->nat_aging_state == NAT_SYNCH_STATE)
sptr_icmp_translation_entry->nat_aging_state = NAT_ESTABLISHED_STATE;
checksum_fixup ((BYTE *) &checksum,
(BYTE *) &sptr_icmp_packet->ip_header.destination_address, sizeof (IP_ADDRESS),
(BYTE *) &address, sizeof (IP_ADDRESS));
sptr_icmp_packet->ip_header.destination_address = address;
sptr_icmp_packet->ip_header.header_checksum = checksum;
sptr_icmp_translation_entry->currenty_translation_entry_timer=nat.icmp_translation_entry_timer;
semGive(natentrylock);
natStats.icmp_pkts_i2l++;
natStats.icmp_bytes_i2l += ntohs(sptr_icmp_packet->ip_header.total_length);
return (PASS);
}
/***************************************************************************/
static enum TEST handle_icmp_translation_global_rx_transaction_natg (ICMP_PACKET *sptr_icmp_packet)
{
if (sptr_icmp_packet->ip_header.destination_address == nat.global_address)
{
return (PASS);
}
if (handle_ip_translation_global_rx_natg ((IP_PACKET *) sptr_icmp_packet) == NULL)
{
return (FAIL);
}
return (PASS);
}
/***************************************************************************/
static enum TEST handle_icmp_translation_local_rx_transaction_natg (ICMP_PACKET *sptr_icmp_packet)
{
if (handle_ip_translation_local_rx_natg ((IP_PACKET *) sptr_icmp_packet) == NULL)
{
return (FAIL);
}
return (PASS);
}
/***************************************************************************/
static NAT_CURRENCY_TRANSLATION_ENTRY *find_icmp_entry (ICMP_PACKET *sptr_icmp_packet)
{
unsigned long hash;
NAT_CURRENCY_TRANSLATION_ENTRY *sptr_icmp_translation_entry=NULL;
hash=natHash_get(sptr_icmp_packet->ip_header.source_address,sptr_icmp_packet->ip_header.destination_address,sptr_icmp_packet->header.option.echo_message.identifier);
for(sptr_icmp_translation_entry=in_map_hash[hash].inmap;sptr_icmp_translation_entry != NULL;sptr_icmp_translation_entry=sptr_icmp_translation_entry->next_inmap_entrys_link)
{
if (sptr_icmp_translation_entry->local_address == ntohl(sptr_icmp_packet->ip_header.source_address)
&&(sptr_icmp_translation_entry->local_port == ntohs(sptr_icmp_packet->header.option.echo_message.identifier)))
{
return (sptr_icmp_translation_entry);
}
}
return (NULL);
}
/***************************************************************************/
static enum TEST handle_icmp_translation_local_rx_transaction_nats (ICMP_PACKET *sptr_icmp_packet)
{
NAT_CURRENCY_TRANSLATION_ENTRY *sptr_icmp_translation_entry=NULL;
USHORT checksum;
IP_ADDRESS address;
USHORT spoofed_icmp_identifier;
/*printf("enter icmp function !start find icmp entry!\n");*/
semTake(natentrylock,WAIT_FOREVER);
sptr_icmp_translation_entry = find_icmp_entry (sptr_icmp_packet);
if (!sptr_icmp_translation_entry)
{
sptr_icmp_translation_entry = new_icmp_translation_entry (sptr_icmp_packet);
}
if (!sptr_icmp_translation_entry)
{
semGive(natentrylock);
return (FAIL);
}
if (sptr_icmp_translation_entry->spoofed_local_port != 0x0000)
{
spoofed_icmp_identifier = htons (sptr_icmp_translation_entry->spoofed_local_port);
checksum = sptr_icmp_packet->header.checksum;
checksum_fixup ((BYTE *) &checksum,
(BYTE *) &sptr_icmp_packet->header.option.echo_message.identifier, sizeof (USHORT),
(BYTE *) &spoofed_icmp_identifier, sizeof (USHORT));
sptr_icmp_packet->header.checksum = checksum;
sptr_icmp_packet->header.option.echo_message.identifier = spoofed_icmp_identifier;
}
address = htonl (nat.global_address);
checksum = sptr_icmp_packet->ip_header.header_checksum;
checksum_fixup ((BYTE *) &checksum,
(BYTE *) &sptr_icmp_packet->ip_header.source_address, sizeof (IP_ADDRESS),
(BYTE *) &address, sizeof (IP_ADDRESS));
sptr_icmp_packet->ip_header.source_address = address;
sptr_icmp_packet->ip_header.header_checksum = checksum;
/*********************************add by zbb******************************************/
sptr_icmp_translation_entry->currenty_translation_entry_timer=nat.icmp_translation_entry_timer;
semGive(natentrylock);
natStats.icmp_pkts_l2i++;
natStats.icmp_bytes_l2i += ntohs(sptr_icmp_packet->ip_header.total_length);
/************************************************************************************/
return (PASS);
}
/*********************************add by zbb******************************************/
static NAT_CURRENCY_TRANSLATION_ENTRY *new_icmp_translation_entry (ICMP_PACKET *sptr_icmp_packet)
{
NAT_CURRENCY_TRANSLATION_ENTRY *sptr_icmp_translation_entry=NULL;
unsigned long out_porthash;
semTake (spoofingPortLock, WAIT_FOREVER);
if( natEntryFree != NULL)
{
sptr_icmp_translation_entry= natEntryFree;
natEntryFree=natEntryFree->next_entrys_link;
}
else
{
sptr_icmp_translation_entry=natCheck_Free_Entrys();
}
if (sptr_icmp_translation_entry == NULL)
{
semGive(spoofingPortLock);
return (NULL);
}
if(find_nat_port_spoofing_number(ntohl (sptr_icmp_packet->ip_header.source_address),
ntohs (sptr_icmp_packet->header.option.timestamp_message.identifier))==FAIL)
{
semGive(spoofingPortLock);
return (NULL);
}
sptr_icmp_translation_entry->local_state = NAT_INITIAL_STATE;
sptr_icmp_translation_entry->nat_aging_state = NAT_SYNCH_STATE;
sptr_icmp_translation_entry->local_sequence_delta_list.sptr_forward_link = NULL;
sptr_icmp_translation_entry->local_sequence_delta_list.sptr_backward_link = NULL;
sptr_icmp_translation_entry->global_sequence_delta_list.sptr_forward_link = NULL;
sptr_icmp_translation_entry->global_sequence_delta_list.sptr_backward_link = NULL;
/*
sptr_icmp_translation_entry->global_sequence_number = 0x00000000L;
sptr_icmp_translation_entry->local_sequence_number = 0x00000000L;
*/
sptr_icmp_translation_entry->protocol_type=sptr_icmp_packet->ip_header.protocol;
sptr_icmp_translation_entry->local_port = ntohs (sptr_icmp_packet->header.option.timestamp_message.identifier);
sptr_icmp_translation_entry->spoofed_local_port = nat.current_port_spoofing_number;
sptr_icmp_translation_entry->local_address = ntohl (sptr_icmp_packet->ip_header.source_address);
sptr_icmp_translation_entry->currenty_translation_entry_timer = nat.icmp_translation_entry_timer;
sptr_icmp_translation_entry->remote_address=ntohl(sptr_icmp_packet->ip_header.destination_address);
out_porthash=nat.current_port_spoofing_number&(UPPER_EPHEMERAL_PORT_VALUE-1);
sptr_icmp_translation_entry->next_entrys_link=out_port_map[out_porthash].next_entrys_link;
out_port_map[out_porthash].next_entrys_link=sptr_icmp_translation_entry;
natMark_in_map(sptr_icmp_translation_entry);
natStats.icmpCons++;
semGive(spoofingPortLock);
return (sptr_icmp_translation_entry);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -