📄 nat_util.c
字号:
return (NULL);}/*****************************************************************************Function: match_sa_with_static_entryDescription:Look for matching entry in the IP static table.*****************************************************************************/STATUS match_sa_with_static_entry (IP_ADDRESS source_address){ USHORT i; for (i = 0; i < MAXIMUM_NUMBER_OF_IP_STATIC_ENTRIES; i++) { if (nat.static_entries[i].local_address == source_address) { return (OK); /* found */ } } return (ERROR); /* not found */} /********************************************************************************Description: This function creates a new IP translation entry. It is called when a match is not found in the current IP translation list.********************************************************************************/IP_TRANSLATION_ENTRY *new_ip_translation_entry ( IP_TRANSLATION_HEADER *sptr_ip_translation_list, IP_ADDRESS source_address, bool static_entry){ IP_TRANSLATION_ENTRY *sptr_ip_translation_entry; ULONG index; /* tk - for basic NAT, find the next available IP address in the global address pool */ if (nat.single_global_address_enabled == FALSE) { for (index = 0; index < nat.natg.global_address_pool_size; index++ ) { if (nat.natg.global_address_pool[index].address_in_use == FALSE) { break; } } } else /* tk - if NAPT, it means that no match was found in NAPT translation lists and static entries, and no match was found either in the IP translation list. No new IP entry should be created in NAPT, so we return NULL here */ { return (NULL); } if (index >= nat.natg.global_address_pool_size) { nat_printf (NAT_PRINTF_ERROR, "translation address table full\n"); return (NULL); } sptr_ip_translation_entry = allocate_and_initialize_ip_translation_entry ( &nat.natg.global_address_pool[index], source_address, nat.natg.global_address_pool[index].address, static_entry); dllAdd ((DL_LIST *) sptr_ip_translation_list, (DL_NODE *) sptr_ip_translation_entry); return (sptr_ip_translation_entry);}/********************************************************************************Description: This function creates a new static IP translation entry given the local and global address pair.********************************************************************************/IP_TRANSLATION_ENTRY *create_static_ip_entry ( IP_TRANSLATION_HEADER *sptr_ip_translation_list, IP_ADDRESS source_address, IP_ADDRESS global_address){ IP_TRANSLATION_ENTRY *sptr_ip_translation_entry; ULONG index; /* check if the specified global address is available */ for (index = 0; index < nat.natg.global_address_pool_size; index++ ) { if (nat.natg.global_address_pool[index].address == global_address && nat.natg.global_address_pool[index].address_in_use == FALSE) { break; } } if (index >= nat.natg.global_address_pool_size) { nat_printf (NAT_PRINTF_ERROR, "IP translation address table full\n"); return (NULL); } sptr_ip_translation_entry = allocate_and_initialize_ip_translation_entry ( &nat.natg.global_address_pool[index], source_address, nat.natg.global_address_pool[index].address, TRUE); semTake (ipListLock, WAIT_FOREVER); dllAdd ((DL_LIST *) sptr_ip_translation_list, (DL_NODE *) sptr_ip_translation_entry); semGive (ipListLock); return (sptr_ip_translation_entry);}/*********************************************************************/IP_TRANSLATION_ENTRY *allocate_and_initialize_ip_translation_entry (NAT_IP_ADDRESS_ENTRY *sptr_address_entry, IP_ADDRESS local_address, IP_ADDRESS global_address, bool static_entry){ IP_TRANSLATION_ENTRY *sptr_ip_translation_entry; struct in_addr iaddr; char asciiAddr[INET_ADDR_LEN]; sptr_ip_translation_entry = (IP_TRANSLATION_ENTRY *) calloc (1, sizeof (IP_TRANSLATION_ENTRY)); if (sptr_ip_translation_entry == NULL) { nat_printf (NAT_PRINTF_ERROR, "allocate_and_initialize_ip_translation_entry: failed calloc\n"); return (NULL); } if (sptr_address_entry != NULL) { sptr_address_entry->address_in_use = TRUE; } sptr_ip_translation_entry->sptr_local_address_use_entry = sptr_address_entry; sptr_ip_translation_entry->sa_local_address = local_address; sptr_ip_translation_entry->sa_global_address = global_address; sptr_ip_translation_entry->time_stamp = nat.ip_translation_entry_timer; sptr_ip_translation_entry->tcp_translation_list.sptr_forward_link = NULL; sptr_ip_translation_entry->tcp_translation_list.sptr_backward_link = NULL; sptr_ip_translation_entry->static_entry = static_entry; iaddr.s_addr = ntohl(global_address); inet_ntoa_b(iaddr, asciiAddr); arpAdd(asciiAddr, nat.etherAddr, 0x0c); return (sptr_ip_translation_entry); }/**********************************************************************************Function: registerStaticEntryToTranslationListDescription:This function registers the TCP or UDP static entries in the static table to NAT'sTCP or UDP translation list and bind list.**********************************************************************************/STATUS registerStaticEntryToTranslationList ( NAT_PORT_STATIC_ENTRY *staticEntry, u_short protocol){ TCP_TRANSLATION_ENTRY *tcpTranslationEntry; UDP_TRANSLATION_ENTRY *udpTranslationEntry; NAT_BIND_INFO bind_info; NAT_STATUS status; 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_INBOUND; bind_info.protocol = protocol; bind_info.static_entry = TRUE; bind_info.global_transport = staticEntry->global_port_number; bind_info.local_addr = staticEntry->local_address; bind_info.local_transport = staticEntry->local_port_number; status = natSetBind((u_long)&nat, 0, &bind_info); if(status != NAT_OK) { nat_printf (NAT_PRINTF_ERROR, "registerStaticEntryToTranslationList: natSetBind returned %d\n",status); return(ERROR); } if (protocol == IPPROTO_TCP) { tcpTranslationEntry = (TCP_TRANSLATION_ENTRY *) bind_info.nat_transport_entry; tcpTranslationEntry->spoofed_local_port = bind_info.global_transport; tcpTranslationEntry->local_address = bind_info.local_addr; tcpTranslationEntry->local_port = bind_info.local_transport; } else { udpTranslationEntry = (UDP_TRANSLATION_ENTRY *) bind_info.nat_transport_entry; udpTranslationEntry->spoofed_local_port = bind_info.global_transport; udpTranslationEntry->local_address = bind_info.local_addr; udpTranslationEntry->local_port = bind_info.local_transport; } return (OK); }/*********************************************************************//* Taken directly from RFC 1631 *//*********************************************************************/void checksum_fixup (BYTE *bptr_checksum, BYTE *bptr_old_data, USHORT old_data_length, BYTE *bptr_new_data, USHORT new_data_length){ ULONG working_checksum; ULONG old_data_word; ULONG new_data_word; working_checksum = (ULONG) ((bptr_checksum[0] * 256) + bptr_checksum[1]); working_checksum = (~working_checksum & 0x0000FFFF); while (old_data_length > 0x0000) { if (old_data_length == 0x00000001) { old_data_word = (ULONG) ((bptr_old_data[0] * 256) + bptr_old_data[1]); working_checksum = working_checksum - (old_data_word & 0x0000FF00); if ((long) working_checksum <= 0x00000000L) { --working_checksum; working_checksum = working_checksum & 0x0000FFFF; } break; } else { old_data_word = (ULONG) ((bptr_old_data[0] * 256) + bptr_old_data[1]); bptr_old_data = bptr_old_data + 2; working_checksum = working_checksum - (old_data_word & 0x0000FFFF); if ((long) working_checksum <= 0x00000000L) { --working_checksum; working_checksum = working_checksum & 0x0000FFFF; } old_data_length = (USHORT) (old_data_length - 2); } } while (new_data_length > 0x0000) { if (new_data_length == 0x00000001) { new_data_word = (ULONG) ((bptr_new_data[0] * 256) + bptr_new_data[1]); working_checksum = working_checksum + (new_data_word & 0x0000FF00); if (working_checksum & 0x00010000) { ++working_checksum; working_checksum = working_checksum & 0x0000FFFF; } break; } else { new_data_word = (ULONG) ((bptr_new_data[0] * 256) + bptr_new_data[1]); bptr_new_data = bptr_new_data + 2; working_checksum = working_checksum + (new_data_word & 0x0000FFFF); if (working_checksum & 0x00010000) { ++working_checksum; working_checksum = working_checksum & 0x0000FFFF; } new_data_length = (USHORT) (new_data_length - 2); } } working_checksum = ~working_checksum; bptr_checksum[0] = (BYTE) (working_checksum/256); bptr_checksum[1] = (BYTE) (working_checksum & 0x000000FF);}/*********************************************************************/enum TEST increment_nat_port_spoofing_number (USHORT *usptr_spoofing_number){ TCP_TRANSLATION_ENTRY *sptr_tcp_translation_entry; UDP_TRANSLATION_ENTRY *sptr_udp_translation_entry; ICMP_TRANSLATION_ENTRY *sptr_icmp_translation_entry; USHORT index; bool conflict; bool first_pass; first_pass = FALSE; for (*usptr_spoofing_number = (USHORT) (*usptr_spoofing_number + 1); ; *usptr_spoofing_number = (USHORT) (*usptr_spoofing_number +1)) { if (*usptr_spoofing_number > UPPER_EPHEMERAL_PORT_VALUE) { *usptr_spoofing_number = LOWER_EPHEMERAL_PORT_VALUE; if (first_pass == FALSE) { first_pass = TRUE; } else { return (FAIL); } } conflict = FALSE; for (index = 0x0000; (index < MAXIMUM_NUMBER_OF_TCP_STATIC_ENTRIES) && !conflict; ++index) { if (nat.tcp_static_entries[index].global_port_number == *usptr_spoofing_number) { conflict = TRUE; break; } } if (conflict == TRUE) { continue; } for (index = 0x0000; (index < MAXIMUM_NUMBER_OF_UDP_STATIC_ENTRIES) && !conflict; ++index) { if (nat.udp_static_entries[index].global_port_number == *usptr_spoofing_number) { conflict = TRUE; break; } } if (conflict == TRUE) { continue; } if (nat.single_global_address_enabled == TRUE) { for (sptr_tcp_translation_entry = (TCP_TRANSLATION_ENTRY *) DLL_FIRST ((DL_LIST *) &nat.nats.tcp_translation_list); sptr_tcp_translation_entry != NULL; sptr_tcp_translation_entry = (TCP_TRANSLATION_ENTRY *) DLL_NEXT ((DL_NODE *) sptr_tcp_translation_entry)) { if (sptr_tcp_translation_entry->spoofed_local_port == *usptr_spoofing_number) { conflict = TRUE; break; } } if (conflict == TRUE) { continue; } for (sptr_udp_translation_entry = (UDP_TRANSLATION_ENTRY *) DLL_FIRST ((DL_LIST *) &nat.nats.udp_translation_list); sptr_udp_translation_entry != NULL; sptr_udp_translation_entry = (UDP_TRANSLATION_ENTRY *) DLL_NEXT ((DL_NODE *) sptr_udp_translation_entry)) { if (sptr_udp_translation_entry->spoofed_local_port == *usptr_spoofing_number) { conflict = TRUE; break; } } if (conflict == TRUE) { continue; } for (sptr_icmp_translation_entry = (ICMP_TRANSLATION_ENTRY *) DLL_FIRST ((DL_LIST *) &nat.nats.icmp_translation_list); sptr_icmp_translation_entry != NULL; sptr_icmp_translation_entry = (ICMP_TRANSLATION_ENTRY *) DLL_NEXT ((DL_NODE *) sptr_icmp_translation_entry)) { if (sptr_icmp_translation_entry->spoofed_icmp_identifier == *usptr_spoofing_number) { conflict = TRUE; break; } } if (conflict == TRUE) { continue; } } break; } return (PASS);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -