📄 nat_icmp_datagram.c
字号:
/* nat_icmp_datagram.c *//* Copyright 2000-2003 Wind River Systems, Inc. *//* @format.tab-size 4, @format.use-tabs true, @format.new-line lf *//*modification history--------------------01g,16may03,myz Reworked SPR#87054 fix01f,13may03,myz fixed wrong port number problem in functions: handle_icmp _embedded_tcp(udp)_translation_global_rx_datagram_nats.01e,23apr03,zhu updated copyright01d,21apr03,myz replaced swap(_long) with the ntohs(l) and htons(l) macros.01c,10apr03,zhu allow icmp protocol type in icmp host unreachable message datagram01b,10apr03,zhu cleaned up SPR#87054 fix01a,28mar03,zhu SPR#87054 fix: send ICMP host unreachable message back to local host100901 tk Changes due to parameter addition in match_spoofed_port_with_udp_entry.072601 tk Fix call to match_ports_with_udp_entry to use match_ports_with_udp_entry_inbound and match_ports_with_udp_entry_outbound instead. Also fix call to match_ports_with_tcp_entry to use match_ports_with_tcp_entry_inbound and match_ports_with_tcp_entry_outbound instead.050701 tk Update handle_icmp_translation_global_rx_datagram_nats to check for embedded ICMP frame (for time-exceeded message). Add a new function handle_icmp_embedded_icmp_translation_global_rx_datagram_nats to process embedded ICMP translation (e.g. ICMP time-exceeded message).042101 tk Fix bugs in basic NAT ICMP translations for both global port and local port in functions handle_icmp_translation_global_rx_datagram_natg() and handle_icmp_translation_local_rx_datagram_natg () respectively. The bugs can cause page fault, wrong address translation in embedded IP, and checksum errors.*/#include "nat.h"/************************************************************************/static enum TEST handle_icmp_translation_global_rx_datagram_nats (ICMP_PACKET *sptr_icmp_packet);static enum TEST handle_icmp_translation_global_rx_datagram_natg (ICMP_PACKET *sptr_icmp_packet);static enum TEST handle_icmp_translation_local_rx_datagram_nats (ICMP_PACKET *sptr_icmp_packet);static enum TEST handle_icmp_translation_local_rx_datagram_natg (ICMP_PACKET *sptr_icmp_packet);static enum TEST handle_icmp_embedded_tcp_translation_global_rx_datagram_nats (ICMP_PACKET *sptr_icmp_packet);static enum TEST handle_icmp_embedded_udp_translation_global_rx_datagram_nats (ICMP_PACKET *sptr_icmp_packet);static enum TEST handle_icmp_embedded_tcp_translation_local_rx_datagram_nats (ICMP_PACKET *sptr_icmp_packet);static enum TEST handle_icmp_embedded_udp_translation_local_rx_datagram_nats (ICMP_PACKET *sptr_icmp_packet);static enum TEST handle_icmp_embedded_icmp_translation_global_rx_datagram_nats (ICMP_PACKET *sptr_icmp_packet);/************************************************************************/enum TEST handle_icmp_translation_global_rx_datagram (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_datagram_nats ( sptr_icmp_packet); if (pass_or_fail == FAIL) { /* Try IP translation, in case it use Basic NAT static entries */ pass_or_fail = handle_icmp_translation_global_rx_datagram_natg( sptr_icmp_packet); } } else { pass_or_fail = handle_icmp_translation_global_rx_datagram_natg ( sptr_icmp_packet); } return (pass_or_fail); }/***************************************************************************/enum TEST handle_icmp_translation_local_rx_datagram (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_datagram_nats ( sptr_icmp_packet); if (pass_or_fail == FAIL) { /* Try IP translation, in case it use Basic NAT static entries */ pass_or_fail = handle_icmp_translation_local_rx_datagram_natg( sptr_icmp_packet); } } else { pass_or_fail = handle_icmp_translation_local_rx_datagram_natg ( sptr_icmp_packet); } return (pass_or_fail); }/**********************************************************************************************Description: Handle packet received from global port in Basic NAT**********************************************************************************************/static enum TEST handle_icmp_translation_global_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; USHORT checksum; nested_ip_packet.header = sptr_icmp_packet->header.option.unreachable_message.ip_data; nat_printf (NAT_PRINTF_TRACE, "ICMP: 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; sptr_ip_translation_entry = match_sa_with_global_address ( ntohl (unchanged_data.ip_data.addresses.source_address), &nat.natg.ip_translation_list); if (sptr_ip_translation_entry == NULL) { nat_printf (NAT_PRINTF_TRACE, "ICMP received global: Can't match embedded source IP in ICMP datagram.\n"); return (FAIL); } changed_data.ip_data.addresses.source_address = htonl (sptr_ip_translation_entry->sa_local_address); changed_data.ip_data.addresses.destination_address = nested_ip_packet.header.destination_address; changed_data.ip_data.ip_checksum = nested_ip_packet.header.header_checksum; /* adjust checksum in embedded IP header */ checksum_fixup ((BYTE *) &changed_data.ip_data.ip_checksum, (BYTE *) &unchanged_data.ip_data.addresses.source_address, (USHORT) sizeof (IP_ADDRESS), (BYTE *) &changed_data.ip_data.addresses.source_address, (USHORT )sizeof (IP_ADDRESS)); nested_ip_packet.header.source_address = changed_data.ip_data.addresses.source_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.source_address, sizeof (ULONG), (BYTE *) &nested_ip_packet.header.source_address, sizeof (ULONG)); checksum = changed_data.icmp_checksum; /* save for printing debug msg */ /* adjust ICMP header checksum, then with change in embedded IP header 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 global: translate IP header of ICMP packet\n"); /* this function also adjusts IP header's checksum */ if (handle_ip_translation_global_rx_natg ((IP_PACKET *) sptr_icmp_packet) == NULL) { return (FAIL); } return (PASS); }/**********************************************************************************************Description: Handle ICMP packet received from global port in NAPT. The ICMP datagram may be of destination unreachable message or time-exceeded message.**********************************************************************************************/static enum TEST handle_icmp_translation_global_rx_datagram_nats (ICMP_PACKET *sptr_icmp_packet){ if (sptr_icmp_packet->header.type == ICMP_DESTINATION_UNREACHABLE_TYPE) { switch (sptr_icmp_packet->header.option.unreachable_message.ip_data.protocol) { case TCP_PROTOCOL: if (handle_icmp_embedded_tcp_translation_global_rx_datagram_nats (sptr_icmp_packet) == FAIL) { return (FAIL); } break; case UDP_PROTOCOL: if (handle_icmp_embedded_udp_translation_global_rx_datagram_nats (sptr_icmp_packet) == FAIL) { return (FAIL); } break; case ICMP_PROTOCOL: if (handle_icmp_embedded_icmp_translation_global_rx_datagram_nats (sptr_icmp_packet) == FAIL) { return (FAIL); } break; default: nat_printf(NAT_PRINTF_ERROR, "Global port: Unrecognized protocol in ICMP unreachable message datagram.\n"); return (FAIL); } } else if (sptr_icmp_packet->header.type == ICMP_TIME_EXCEEDED_TYPE) { switch (sptr_icmp_packet->header.option.time_exceeded_message.ip_data.protocol) { case ICMP_PROTOCOL: if (handle_icmp_embedded_icmp_translation_global_rx_datagram_nats (sptr_icmp_packet) == FAIL) { return (FAIL); } break; default: nat_printf (NAT_PRINTF_ERROR, "Global port: Unrecognized protocol in ICMP time-exceeded datagram.\n"); return (FAIL); } } return (PASS); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -