📄 nat_icmp_datagram.c
字号:
/**********************************************************************************************Description: Handle ICMP packet received from local port in NAPT. Only needs to handle destination unreachable message. There is no reason that NAT should receive time-exceeded message from local port.**********************************************************************************************/static enum TEST handle_icmp_translation_local_rx_datagram_nats (ICMP_PACKET *sptr_icmp_packet){ switch (sptr_icmp_packet->header.option.unreachable_message.ip_data.protocol) { case TCP_PROTOCOL: if (handle_icmp_embedded_tcp_translation_local_rx_datagram_nats (sptr_icmp_packet) == FAIL) { return (FAIL); } break; case UDP_PROTOCOL: if (handle_icmp_embedded_udp_translation_local_rx_datagram_nats (sptr_icmp_packet) == FAIL) { return (FAIL); } break; default: nat_printf (NAT_PRINTF_ERROR, "Local port: Unrecognized protocol in ICMP unreachable message datagram.\n"); return (FAIL); } return (PASS);}/***************************************************************************/static enum TEST handle_icmp_embedded_tcp_translation_global_rx_datagram_nats (ICMP_PACKET *sptr_icmp_packet){ NAT_IP_TCP_HEADER nested_tcp_header; NAT_ICMP_EMBEDDED_HEADER *sptr_icmp_embedded_header; TCP_TRANSLATION_ENTRY *sptr_tcp_translation_entry; IP_ADDRESS address; USHORT local_port_number; USHORT checksum; nested_tcp_header = *(NAT_IP_TCP_HEADER *)&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; sptr_tcp_translation_entry = match_spoofed_port_with_tcp_entry (ntohs (nested_tcp_header.tcp_header.source_port), &nat.nats.tcp_translation_list, FALSE); if (sptr_tcp_translation_entry == NULL) { sptr_tcp_translation_entry = match_ports_with_tcp_entry_inbound ( ntohs (nested_tcp_header.tcp_header.destination_port), ntohs (nested_tcp_header.tcp_header.source_port), ntohl (nested_tcp_header.ip_header.destination_address), &nat.nats.tcp_translation_list); } /* Did we find a TCP translation entry? */ if (sptr_tcp_translation_entry == NULL) { /* no way to determine who to send the ICMP message to*/ return FAIL; } /* TCP translation entry found */ address = htonl (sptr_tcp_translation_entry->local_address); local_port_number = htons (sptr_tcp_translation_entry->local_port); tcp_sequence_number_fixup_global_rx (&nested_tcp_header.tcp_header, sptr_tcp_translation_entry); if (local_port_number != 0x0000) { checksum = nested_tcp_header.tcp_header.checksum; checksum_fixup ((BYTE *) &checksum, (BYTE *) &nested_tcp_header.tcp_header.source_port, sizeof (USHORT), (BYTE *) &local_port_number, sizeof (USHORT)); nested_tcp_header.tcp_header.source_port = local_port_number; nested_tcp_header.tcp_header.checksum = checksum; } checksum = nested_tcp_header.ip_header.header_checksum; checksum_fixup ((BYTE *) &checksum, (BYTE *) &nested_tcp_header.ip_header.source_address, sizeof (IP_ADDRESS), (BYTE *) &address, sizeof (IP_ADDRESS)); nested_tcp_header.ip_header.source_address = address; nested_tcp_header.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 *) &nested_tcp_header, sizeof (NAT_ICMP_EMBEDDED_HEADER)); *sptr_icmp_embedded_header = *(NAT_ICMP_EMBEDDED_HEADER *) &nested_tcp_header; 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_udp_translation_global_rx_datagram_nats (ICMP_PACKET *sptr_icmp_packet){ NAT_IP_UDP_HEADER nested_udp_header; NAT_ICMP_EMBEDDED_HEADER *sptr_icmp_embedded_header; UDP_TRANSLATION_ENTRY *sptr_udp_translation_entry; IP_ADDRESS address; USHORT checksum; USHORT local_port_number; nested_udp_header = *(NAT_IP_UDP_HEADER *) &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; sptr_udp_translation_entry = match_spoofed_port_with_udp_entry (ntohs (nested_udp_header.udp_header.source_port), &nat.nats.udp_translation_list, FALSE); if (sptr_udp_translation_entry == NULL) { sptr_udp_translation_entry = match_ports_with_udp_entry_inbound ( ntohs (nested_udp_header.udp_header.destination_port), ntohs (nested_udp_header.udp_header.source_port), ntohl (nested_udp_header.ip_header.destination_address), &nat.nats.udp_translation_list); } /* 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 = nested_udp_header.udp_header.checksum ; checksum_fixup ((BYTE *) &checksum, (BYTE *) &nested_udp_header.udp_header.source_port, sizeof (USHORT), (BYTE *) &local_port_number, sizeof (USHORT)); nested_udp_header.udp_header.source_port = local_port_number; nested_udp_header.udp_header.checksum = checksum; } checksum = nested_udp_header.ip_header.header_checksum; checksum_fixup ((BYTE *) &checksum, (BYTE *) &nested_udp_header.ip_header.source_address, sizeof (IP_ADDRESS), (BYTE *) &address, sizeof (IP_ADDRESS)); nested_udp_header.ip_header.source_address = address; nested_udp_header.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 *) &nested_udp_header, sizeof (NAT_ICMP_EMBEDDED_HEADER)); *sptr_icmp_embedded_header = *(NAT_ICMP_EMBEDDED_HEADER *) &nested_udp_header; 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){ ICMP_TRANSLATION_ENTRY *sptr_icmp_translation_entry; USHORT icmp_identifier; USHORT spoofed_icmp_identifier; IP_ADDRESS address; USHORT checksum; ICMP_PACKET *sptr_icmp_embedded_packet; 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); sptr_icmp_translation_entry = match_spoofed_identifier_with_icmp_entry (spoofed_icmp_identifier, &nat.nats.icmp_translation_list); if (sptr_icmp_translation_entry == NULL) { sptr_icmp_translation_entry = &nat.nats.icmp_default_entry; } if (sptr_icmp_translation_entry->icmp_identifier != 0x0000) { icmp_identifier = htons (sptr_icmp_translation_entry->icmp_identifier); 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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -