📄 nat_tcp.c
字号:
if (sptr_tcp_translation_entry == NULL) { /* look for source address match in ip static table. If found, process as basic NAT. */ if (match_sa_with_static_entry ( ntohl (sptr_tcp_packet->ip_header.source_address)) == OK) { if (handle_tcp_translation_local_rx_natg (sptr_tcp_packet) == PASS) { return (PASS); } else { return (FAIL); } } /* from here on, process normally in NAPT mode */ if (sptr_tcp_packet->tcp_header.flags.synchronize_flag == TRUE) { memset(&bind_info,0,sizeof(bind_info)); bind_info.agent_id = 0; /* agent is NAT */ bind_info.type = NAT_BIND_NAPT; bind_info.direction = NAT_OUTBOUND; bind_info.protocol = IPPROTO_TCP; bind_info.static_entry = FALSE; /* source and destination transport addresses must be in host format */ bind_info.local_addr = ntohl(sptr_tcp_packet->ip_header.source_address); bind_info.local_transport = ntohs(sptr_tcp_packet->tcp_header.source_port); bind_info.remote_addr = ntohl(sptr_tcp_packet->ip_header.destination_address); bind_info.remote_transport = ntohs(sptr_tcp_packet->tcp_header.destination_port); status = natSetBind((u_long)&nat, 0, &bind_info); if(status != NAT_OK) { nat_printf (NAT_PRINTF_ERROR, "handle_tcp_translation_local_rx_nats: natSetBind returned %d\n",status); return(FAIL); } sptr_tcp_translation_entry = (TCP_TRANSLATION_ENTRY *) bind_info.nat_transport_entry; } else { return (FAIL); } } /* the following recalculates the checksum multiple times, it should be written a bit better */ tcp_sequence_number_fixup_local_rx (&sptr_tcp_packet->tcp_header, sptr_tcp_translation_entry); if (ntohl(sptr_tcp_packet->tcp_header.sequence_number) >= ntohl(sptr_tcp_translation_entry->local_sequence_number)) { do_state_transition = TRUE; } else if(sptr_tcp_packet->tcp_header.flags.reset_flag == TRUE) { do_state_transition = TRUE; } else { do_state_transition = FALSE; } sptr_tcp_translation_entry->local_sequence_number = sptr_tcp_packet->tcp_header.sequence_number; if (sptr_tcp_translation_entry->spoofed_local_port != 0x0000) { local_spoofed_port_number = htons (sptr_tcp_translation_entry->spoofed_local_port); checksum = sptr_tcp_packet->tcp_header.checksum; checksum_fixup ((BYTE *) &checksum, (BYTE *) &sptr_tcp_packet->tcp_header.source_port, sizeof (USHORT), (BYTE *) &local_spoofed_port_number, sizeof (USHORT)); sptr_tcp_packet->tcp_header.source_port = local_spoofed_port_number; sptr_tcp_packet->tcp_header.checksum = checksum; } address = htonl (nat.global_address); checksum_fixup ((BYTE *) &sptr_tcp_packet->tcp_header.checksum, (BYTE *) &sptr_tcp_packet->ip_header.source_address, sizeof (IP_ADDRESS), (BYTE *) &address, sizeof (IP_ADDRESS)); checksum = sptr_tcp_packet->ip_header.header_checksum; checksum_fixup ((BYTE *) &checksum, (BYTE *) &sptr_tcp_packet->ip_header.source_address, sizeof (IP_ADDRESS), (BYTE *) &address, sizeof (IP_ADDRESS)); sptr_tcp_packet->ip_header.source_address = address; sptr_tcp_packet->ip_header.header_checksum = checksum; if (do_state_transition == TRUE) { if (sptr_tcp_packet->tcp_header.flags.acknowledgment_flag == TRUE) { tcp_state_transistion_local_rx (NAT_ACK, sptr_tcp_translation_entry); } if (sptr_tcp_packet->tcp_header.flags.synchronize_flag == TRUE) { tcp_state_transistion_local_rx (NAT_SYNCH, sptr_tcp_translation_entry); } if (sptr_tcp_packet->tcp_header.flags.finished_flag == TRUE) { tcp_state_transistion_local_rx (NAT_FIN, sptr_tcp_translation_entry); } if (sptr_tcp_packet->tcp_header.flags.reset_flag == TRUE) { tcp_state_transistion_local_rx (NAT_RESET, sptr_tcp_translation_entry); } if ((sptr_tcp_packet->tcp_header.flags.acknowledgment_flag == FALSE) && (sptr_tcp_packet->tcp_header.flags.synchronize_flag == FALSE) && (sptr_tcp_packet->tcp_header.flags.reset_flag == FALSE) && (sptr_tcp_packet->tcp_header.flags.finished_flag == FALSE)) { tcp_state_transistion_local_rx (NAT_ESTABLISHED, sptr_tcp_translation_entry); } } return (PASS);}/************************************************************************/TCP_TRANSLATION_ENTRY *new_tcp_translation_entry ( TCP_TRANSLATION_HEADER *sptr_tcp_translation_list, IP_ADDRESS local_address, USHORT local_port, IP_ADDRESS remote_address, USHORT remote_port, bool static_entry){ TCP_TRANSLATION_ENTRY *sptr_tcp_translation_entry; nat_printf (NAT_PRINTF_DATA, "new_tcp_translation_entry: " "local_addr/port=%08lx:%hu remote_addr/port=%08lx:%hu\n" ,local_address, local_port ,remote_address, remote_port); /* Take the semaphore before doing anything */ semTake (spoofingPortLock, WAIT_FOREVER); if (increment_nat_port_spoofing_number (&nat.current_port_spoofing_number) == FAIL) { nat_printf (NAT_PRINTF_ERROR, "new_tcp_translation_entry: failed to increment port spoofing number\n"); semGive (spoofingPortLock); return (NULL); } semGive (spoofingPortLock); sptr_tcp_translation_entry = (TCP_TRANSLATION_ENTRY *) calloc (1, sizeof (TCP_TRANSLATION_ENTRY)); if (sptr_tcp_translation_entry == NULL) { nat_printf (NAT_PRINTF_ERROR, "new_tcp_translation_entry: failed calloc\n"); return (NULL); } sptr_tcp_translation_entry->local_state = NAT_INITIAL_STATE; sptr_tcp_translation_entry->global_state = NAT_INITIAL_STATE; sptr_tcp_translation_entry->local_connection_timer = nat.tcp_disconnected_timer; sptr_tcp_translation_entry->global_connection_timer = nat.tcp_disconnected_timer; sptr_tcp_translation_entry->local_sequence_delta_list.sptr_forward_link = NULL; sptr_tcp_translation_entry->local_sequence_delta_list.sptr_backward_link = NULL; sptr_tcp_translation_entry->global_sequence_delta_list.sptr_forward_link = NULL; sptr_tcp_translation_entry->global_sequence_delta_list.sptr_backward_link = NULL; sptr_tcp_translation_entry->global_sequence_number = 0x00000000L; sptr_tcp_translation_entry->local_sequence_number = 0x00000000L; sptr_tcp_translation_entry->spoofed_local_port = nat.current_port_spoofing_number; sptr_tcp_translation_entry->local_port = ntohs (local_port); sptr_tcp_translation_entry->remote_port = ntohs (remote_port); sptr_tcp_translation_entry->local_address = ntohl (local_address); sptr_tcp_translation_entry->remote_address = remote_address; sptr_tcp_translation_entry->static_entry = static_entry; dllAdd ((DL_LIST *) sptr_tcp_translation_list, (DL_NODE *) sptr_tcp_translation_entry); return (sptr_tcp_translation_entry); }/************************************************************************/void tcp_sequence_number_fixup_global_rx (TCP_HEADER *sptr_tcp_header, TCP_TRANSLATION_ENTRY *sptr_tcp_translation_entry){ enum NAT_TCP_DELTA_SIGN delta_sign; nat_printf (NAT_PRINTF_TRACE, "tcp_sequence_number_fixup for inbound packet\n"); delta_sign = DELTA_NEGATIVE; do_tcp_sequence_number_fixup (delta_sign, &sptr_tcp_header->acknowledgment_number, &sptr_tcp_header->checksum, &sptr_tcp_translation_entry->local_sequence_delta_list); delta_sign = DELTA_POSITIVE; do_tcp_sequence_number_fixup (delta_sign, &sptr_tcp_header->sequence_number, &sptr_tcp_header->checksum, &sptr_tcp_translation_entry->global_sequence_delta_list);}/************************************************************************/void tcp_sequence_number_fixup_local_rx (TCP_HEADER *sptr_tcp_header, TCP_TRANSLATION_ENTRY *sptr_tcp_translation_entry){ enum NAT_TCP_DELTA_SIGN delta_sign; nat_printf (NAT_PRINTF_TRACE, "tcp_sequence_number_fixup for outbound packet\n"); delta_sign = DELTA_NEGATIVE; do_tcp_sequence_number_fixup (delta_sign, &sptr_tcp_header->acknowledgment_number, &sptr_tcp_header->checksum, &sptr_tcp_translation_entry->global_sequence_delta_list); delta_sign = DELTA_POSITIVE; do_tcp_sequence_number_fixup (delta_sign, &sptr_tcp_header->sequence_number, &sptr_tcp_header->checksum, &sptr_tcp_translation_entry->local_sequence_delta_list);}/************************************************************************/static void do_tcp_sequence_number_fixup (enum NAT_TCP_DELTA_SIGN delta_sign, ULONG *ulptr_packet_sequence_number, USHORT *usptr_checksum, SEQUENCE_HEADER *sptr_sequence_list){ ULONG working_sequence_number; ULONG test_sequence_number; ULONG packet_sequence_number; SEQUENCE_ENTRY *sptr_sequence_entry; long result; packet_sequence_number = ntohl (*ulptr_packet_sequence_number); for (sptr_sequence_entry = (SEQUENCE_ENTRY *) DLL_FIRST ((DL_LIST *) sptr_sequence_list); sptr_sequence_entry != NULL; sptr_sequence_entry = (SEQUENCE_ENTRY *) DLL_NEXT ((DL_NODE *) sptr_sequence_entry)) { if (delta_sign != DELTA_POSITIVE) { test_sequence_number = (ULONG) (packet_sequence_number + (sptr_sequence_entry->sequence_number_base_adjust * delta_sign)); } else { test_sequence_number = (ULONG) (packet_sequence_number - 1); } result = test_sequence_number - sptr_sequence_entry->sequence_number_base; if (result >= 0x00000000L) { working_sequence_number = (ULONG) (packet_sequence_number + ((sptr_sequence_entry->sequence_number_delta * delta_sign) + (sptr_sequence_entry->sequence_number_base_adjust * delta_sign))); nat_printf (NAT_PRINTF_DATA, "original TCP sequence number %d, original checksum 0x%x\n", packet_sequence_number, ntohs (*usptr_checksum)); working_sequence_number = ntohl (working_sequence_number); checksum_fixup ((BYTE *) usptr_checksum, (BYTE *) ulptr_packet_sequence_number, sizeof (ULONG), (BYTE *) &working_sequence_number, sizeof (ULONG)); nat_printf (NAT_PRINTF_DATA, "new TCP sequence number %d, new checksum 0x%x\n", ntohl (working_sequence_number), ntohs (*usptr_checksum)); *ulptr_packet_sequence_number = working_sequence_number; break; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -