📄 nat_icmp_datagram.c
字号:
UDP_PACKET sptr_udp_packet;
sptr_udp_packet = *(UDP_PACKET *) &sptr_icmp_packet->header.option.unreachable_message.ip_data;
sptr_icmp_embedded_header = (NAT_ICMP_EMBEDDED_HEADER *) &sptr_icmp_packet->header.option.unreachable_message.ip_data;
semTake(natentrylock, WAIT_FOREVER);
sptr_udp_translation_entry = match_ports_with_udp_entry_inbound (&sptr_udp_packet);
semGive(natentrylock);
/* Did we find a UDP translation entry? */
if (sptr_udp_translation_entry == NULL)
{
/* no way to determine who to send the ICMP message to*/
return FAIL;
}
address = htonl (sptr_udp_translation_entry->local_address);
if (sptr_udp_translation_entry->spoofed_local_port != 0x0000)
{
local_port_number = htons (sptr_udp_translation_entry->local_port);
checksum = sptr_udp_packet.header.checksum ;
checksum_fixup ((BYTE *) &checksum,
(BYTE *) &sptr_udp_packet.header.source_port, sizeof (USHORT),
(BYTE *) &local_port_number, sizeof (USHORT));
sptr_udp_packet.header.source_port = local_port_number;
sptr_udp_packet.header.checksum = checksum;
}
checksum = sptr_udp_packet.ip_header.header_checksum;
checksum_fixup ((BYTE *) &checksum,
(BYTE *) &sptr_udp_packet.ip_header.source_address, sizeof (IP_ADDRESS),
(BYTE *) &address, sizeof (IP_ADDRESS));
sptr_udp_packet.ip_header.source_address = address;
sptr_udp_packet.ip_header.header_checksum = checksum;
checksum = sptr_icmp_packet->header.checksum;
checksum_fixup ((BYTE *) &checksum,
(BYTE *) &sptr_icmp_packet->header.option.unreachable_message.ip_data, sizeof (NAT_ICMP_EMBEDDED_HEADER),
(BYTE *) &sptr_udp_packet, sizeof (NAT_ICMP_EMBEDDED_HEADER));
*sptr_icmp_embedded_header = *(NAT_ICMP_EMBEDDED_HEADER *) &sptr_udp_packet;
sptr_icmp_packet->header.checksum = checksum;
checksum = sptr_icmp_packet->ip_header.header_checksum;
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;
return (PASS);
}
/***************************************************************************/
static enum TEST handle_icmp_embedded_icmp_translation_global_rx_datagram_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;
ICMP_PACKET *sptr_icmp_embedded_packet=NULL;
sptr_icmp_embedded_packet = (ICMP_PACKET *) ((ULONG) &sptr_icmp_packet->header.option.time_exceeded_message.ip_data);
spoofed_icmp_identifier = ntohs (sptr_icmp_embedded_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)))
{
break;
}
}
semGive(natentrylock);
if (sptr_icmp_translation_entry == NULL)
{
/*sptr_icmp_translation_entry = &nat.nats.icmp_default_entry;*/
return FAIL;
}
if (sptr_icmp_translation_entry->local_port!= 0x0000)
{
icmp_identifier = htons (sptr_icmp_translation_entry->local_port);
checksum = sptr_icmp_embedded_packet->header.checksum;
checksum_fixup ((BYTE *) &checksum,
(BYTE *) &sptr_icmp_embedded_packet->header.option.echo_message.identifier, sizeof (USHORT),
(BYTE *) &icmp_identifier, sizeof (USHORT));
sptr_icmp_embedded_packet->header.option.echo_message.identifier = icmp_identifier;
sptr_icmp_embedded_packet->header.checksum = checksum;
address = htonl (sptr_icmp_translation_entry->local_address);
checksum = sptr_icmp_embedded_packet->ip_header.header_checksum;
checksum_fixup ((BYTE *) &checksum,
(BYTE *) &sptr_icmp_embedded_packet->ip_header.source_address, sizeof (IP_ADDRESS),
(BYTE *) &address, sizeof (IP_ADDRESS));
sptr_icmp_embedded_packet->ip_header.source_address = address;
sptr_icmp_embedded_packet->ip_header.header_checksum = checksum;
}
else if (sptr_icmp_translation_entry->local_address == 0)
{
return (PASS);
}
address = htonl (sptr_icmp_translation_entry->local_address);
checksum = sptr_icmp_packet->ip_header.header_checksum;
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;
return (PASS);
}
/***************************************************************************/
static enum TEST handle_icmp_embedded_tcp_translation_local_rx_datagram_nats (ICMP_PACKET *sptr_icmp_packet)
{
IP_ADDRESS address;
NAT_CURRENCY_TRANSLATION_ENTRY *sptr_tcp_translation_entry=NULL;
NAT_ICMP_EMBEDDED_HEADER *sptr_icmp_embedded_header=NULL;
USHORT checksum;
USHORT local_spoofed_port_number;
TCP_PACKET sptr_tcp_packet;
sptr_tcp_packet = *(TCP_PACKET *) &sptr_icmp_packet->header.option.unreachable_message.ip_data;
sptr_icmp_embedded_header = (NAT_ICMP_EMBEDDED_HEADER *) &sptr_icmp_packet->header.option.unreachable_message.ip_data;
semTake(natentrylock, WAIT_FOREVER);
sptr_tcp_translation_entry = find_entry (sptr_tcp_packet.ip_header.destination_address,sptr_tcp_packet.ip_header.source_address,sptr_tcp_packet.tcp_header.destination_port,sptr_tcp_packet.tcp_header.source_port);
semGive(natentrylock);
if (sptr_tcp_translation_entry == NULL)
{
/* no way to determine who to send the ICMP message to*/
return (FAIL);
}
address = htonl (nat.global_address);
local_spoofed_port_number = htons (sptr_tcp_translation_entry->spoofed_local_port);
tcp_sequence_number_fixup_local_rx (&sptr_tcp_packet.tcp_header, sptr_tcp_translation_entry);
checksum = sptr_tcp_packet.tcp_header.checksum;
checksum_fixup ((BYTE *) &checksum,
(BYTE *) &sptr_tcp_packet.tcp_header.destination_port, sizeof (USHORT),
(BYTE *) &local_spoofed_port_number, sizeof (USHORT));
sptr_tcp_packet.tcp_header.destination_port = local_spoofed_port_number;
sptr_tcp_packet.tcp_header.checksum = checksum;
checksum = sptr_tcp_packet.ip_header.header_checksum;
checksum_fixup ((BYTE *) &checksum,
(BYTE *) &sptr_tcp_packet.ip_header.destination_address, sizeof (IP_ADDRESS),
(BYTE *) &address, sizeof (IP_ADDRESS));
sptr_tcp_packet.ip_header.destination_address = address;
sptr_tcp_packet.ip_header.header_checksum = checksum;
checksum = sptr_icmp_packet->header.checksum;
checksum_fixup ((BYTE *) &checksum,
(BYTE *) &sptr_icmp_packet->header.option.unreachable_message.ip_data, sizeof (NAT_ICMP_EMBEDDED_HEADER),
(BYTE *) &sptr_tcp_packet, sizeof (NAT_ICMP_EMBEDDED_HEADER));
*sptr_icmp_embedded_header = *(NAT_ICMP_EMBEDDED_HEADER *) &sptr_tcp_packet;
sptr_icmp_packet->header.checksum = checksum;
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;
return (PASS);
}
/***************************************************************************/
static enum TEST handle_icmp_embedded_udp_translation_local_rx_datagram_nats (ICMP_PACKET *sptr_icmp_packet)
{
NAT_ICMP_EMBEDDED_HEADER *sptr_icmp_embedded_header=NULL;
NAT_CURRENCY_TRANSLATION_ENTRY *sptr_udp_translation_entry=NULL;
IP_ADDRESS address;
USHORT checksum;
USHORT local_spoofed_port_number;
UDP_PACKET sptr_udp_packet;
sptr_udp_packet = *(UDP_PACKET *) &sptr_icmp_packet->header.option.unreachable_message.ip_data;
sptr_icmp_embedded_header = (NAT_ICMP_EMBEDDED_HEADER *) &sptr_icmp_packet->header.option.unreachable_message.ip_data;
semTake(natentrylock, WAIT_FOREVER);
sptr_udp_translation_entry = find_entry (sptr_udp_packet.ip_header.destination_address,sptr_udp_packet.ip_header.source_address,sptr_udp_packet.header.destination_port,sptr_udp_packet.header.source_port);
semGive(natentrylock);
if (sptr_udp_translation_entry == NULL)
{
/* no way to determine who to send the ICMP message to*/
return (FAIL);
}
address = htonl (nat.global_address);
local_spoofed_port_number = htons (sptr_udp_translation_entry->spoofed_local_port);
checksum = sptr_udp_packet.header.checksum;
checksum_fixup ((BYTE *) &checksum,
(BYTE *) &sptr_udp_packet.header.destination_port, sizeof (USHORT),
(BYTE *) &local_spoofed_port_number, sizeof (USHORT));
sptr_udp_packet.header.destination_port = local_spoofed_port_number;
sptr_udp_packet.header.checksum = checksum;
checksum = sptr_udp_packet.ip_header.header_checksum;
checksum_fixup ((BYTE *) &checksum,
(BYTE *) &sptr_udp_packet.ip_header.destination_address, sizeof (IP_ADDRESS),
(BYTE *) &address, sizeof (IP_ADDRESS));
sptr_udp_packet.ip_header.destination_address = address;
sptr_udp_packet.ip_header.header_checksum = checksum;
checksum = sptr_icmp_packet->header.checksum;
checksum_fixup ((BYTE *) &checksum,
(BYTE *) &sptr_icmp_packet->header.option.unreachable_message.ip_data, sizeof (NAT_ICMP_EMBEDDED_HEADER),
(BYTE *) &sptr_udp_packet, sizeof (NAT_ICMP_EMBEDDED_HEADER));
*sptr_icmp_embedded_header = *(NAT_ICMP_EMBEDDED_HEADER *) &sptr_udp_packet;
sptr_icmp_packet->header.checksum = checksum;
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;
return (PASS);
}
/**********************************************************************************************
Description:
Handle packet received from local port in Basic NAT
**********************************************************************************************/
static enum TEST handle_icmp_translation_local_rx_datagram_natg (ICMP_PACKET *sptr_icmp_packet)
{
ICMP_DATA changed_data;
ICMP_DATA unchanged_data;
IP_PACKET nested_ip_packet;
IP_TRANSLATION_ENTRY *sptr_ip_translation_entry;
nested_ip_packet.header = sptr_icmp_packet->header.option.unreachable_message.ip_data;
nat_printf (NAT_PRINTF_TRACE, "ICMP received local: translate embedded IP header\n");
unchanged_data.ip_data.addresses.source_address = nested_ip_packet.header.source_address;
unchanged_data.ip_data.addresses.destination_address = nested_ip_packet.header.destination_address;
unchanged_data.ip_data.ip_checksum = nested_ip_packet.header.header_checksum;
changed_data.ip_data.addresses.source_address = nested_ip_packet.header.source_address;
sptr_ip_translation_entry = match_sa_with_local_address (
ntohl (unchanged_data.ip_data.addresses.destination_address),
&nat.natg.ip_translation_list);
if (sptr_ip_translation_entry == NULL)
{
nat_printf (NAT_PRINTF_TRACE,
"ICMP received local: Can't match embedded destination IP address in ICMP datagram.\n");
return (FAIL);
}
changed_data.ip_data.addresses.destination_address = htonl (sptr_ip_translation_entry->sa_global_address);
changed_data.ip_data.ip_checksum = nested_ip_packet.header.header_checksum;
/* adjust embedded IP checksum */
checksum_fixup ((BYTE *) &changed_data.ip_data.ip_checksum,
(BYTE *) &unchanged_data.ip_data.addresses.destination_address, (USHORT) sizeof (IP_ADDRESS),
(BYTE *) &changed_data.ip_data.addresses.destination_address, (USHORT )sizeof (IP_ADDRESS));
nested_ip_packet.header.destination_address = changed_data.ip_data.addresses.destination_address;
nested_ip_packet.header.header_checksum = changed_data.ip_data.ip_checksum;
changed_data.icmp_checksum = sptr_icmp_packet->header.checksum;
/* adjust ICMP header checksum, first with change in embedded IP address */
checksum_fixup ((BYTE *) &changed_data.icmp_checksum,
(BYTE *) &sptr_icmp_packet->header.option.unreachable_message.ip_data.destination_address,
sizeof (ULONG),
(BYTE *) &nested_ip_packet.header.destination_address,
sizeof (ULONG));
sptr_icmp_packet->header.option.unreachable_message.ip_data.destination_address =
changed_data.ip_data.addresses.destination_address;
/* adjust ICMP header checksum, then with change in embedded IP checksum */
checksum_fixup ((BYTE *) &changed_data.icmp_checksum,
(BYTE *) &sptr_icmp_packet->header.option.unreachable_message.ip_data.header_checksum,
sizeof (USHORT),
(BYTE *) &nested_ip_packet.header.header_checksum,
sizeof (USHORT));
sptr_icmp_packet->header.option.unreachable_message.ip_data.source_address =
changed_data.ip_data.addresses.source_address;
sptr_icmp_packet->header.option.unreachable_message.ip_data.destination_address =
changed_data.ip_data.addresses.destination_address;
sptr_icmp_packet->header.option.unreachable_message.ip_data.header_checksum =
changed_data.ip_data.ip_checksum;
sptr_icmp_packet->header.checksum = changed_data.icmp_checksum;
nat_printf (NAT_PRINTF_TRACE, "ICMP received local: translate IP header of ICMP packet\n");
/* this function also adjusts IP header's checksum */
if (handle_ip_translation_local_rx_natg ((IP_PACKET *) sptr_icmp_packet) == NULL)
{
return (FAIL);
}
return (PASS);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -