📄 nat_tcp.c
字号:
{
return (FAIL);
}
}
/* the following recalculates the checksum multiple times, it should be written
a bit better */
if((sptr_tcp_packet->tcp_header.flags.reset_flag)||
(sptr_tcp_packet->tcp_header.flags.finished_flag))
{
sptr_tcp_translation_entry->nat_aging_state = NAT_FIN_STATE;
}
else if(sptr_tcp_translation_entry->nat_aging_state == NAT_SYNCH_STATE)
{
sptr_tcp_translation_entry->nat_aging_state = NAT_ESTABLISHED_STATE;
}
if(sptr_tcp_translation_entry->nat_aging_state == NAT_SYNCH_STATE)
sptr_tcp_translation_entry->currenty_translation_entry_timer = NAT_TCP_CONNECTING_TIMER;
else if(sptr_tcp_translation_entry->nat_aging_state == NAT_ESTABLISHED_STATE)
sptr_tcp_translation_entry->currenty_translation_entry_timer = NAT_TCP_CONNECTED_TIMER;
else if(sptr_tcp_translation_entry->nat_aging_state ==NAT_FIN_STATE)
sptr_tcp_translation_entry->currenty_translation_entry_timer = NAT_TCP_CLOSING_TIMER;
else
sptr_tcp_translation_entry->currenty_translation_entry_timer = NAT_TCP_CONNECTED_TIMER;
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;
}
if ((sptr_tcp_packet->tcp_header.flags.synchronize_flag == TRUE)&&
(sptr_tcp_packet->tcp_header.header_length_byte.header_length>5))
{
if(sptr_tcp_packet->options_or_data.tcp_options.kind==0x02)
{
mss=htons(sptr_tcp_packet->options_or_data.tcp_options.maximum_segment_size);
if(mss>NAT_FORPPPOE_MSS)
{
mss=htons(NAT_FORPPPOE_MSS);
checksum = sptr_tcp_packet->tcp_header.checksum;
checksum_fixup ((BYTE *) &checksum,
(BYTE *) &sptr_tcp_packet->options_or_data.tcp_options.maximum_segment_size, sizeof (USHORT),
(BYTE *) &mss, sizeof (USHORT));
sptr_tcp_packet->options_or_data.tcp_options.maximum_segment_size=mss;
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(_func_packetsend!=NULL) /*PPPOE is running*/
{
if(sptr_tcp_packet->tcp_header.flags.synchronize_flag == TRUE)
{
USHORT pppoeTcpMss=htons(1452);
checksum = sptr_tcp_packet->tcp_header.checksum;
checksum_fixup((BYTE *)&checksum,(BYTE *) &sptr_tcp_packet->options_or_data.tcp_options.maximum_segment_size,
sizeof(USHORT),(BYTE *) &pppoeTcpMss,sizeof(USHORT));
sptr_tcp_packet->options_or_data.tcp_options.maximum_segment_size=pppoeTcpMss;
sptr_tcp_packet->tcp_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);
}
}
/*
printf("handle_tcp_translation_local_rx_nats call over!\n");
printf("s_ip=%lu\n",sptr_tcp_packet->ip_header.source_address);
printf("d_ip=%lu\n",sptr_tcp_packet->ip_header.destination_address);
printf("s_port=%d\n",sptr_tcp_packet->tcp_header.source_port);
printf("d_port=%d\n",sptr_tcp_packet->tcp_header.destination_port);
*/
semGive(natentrylock);
natStats.tcp_pkts_l2i++;
natStats.tcp_bytes_l2i += ntohs(sptr_tcp_packet->ip_header.total_length);
return (PASS);
}
/************************************************************************/
NAT_CURRENCY_TRANSLATION_ENTRY *new_tcp_translation_entry (
IP_ADDRESS local_address, USHORT local_port,
IP_ADDRESS remote_address, USHORT remote_port,
bool static_entry)
{
NAT_CURRENCY_TRANSLATION_ENTRY *sptr_tcp_translation_entry=NULL;
unsigned long out_porthash;
struct portcheck *temp=portchecktable;
/* Take the semaphore before doing anything */
semTake (spoofingPortLock, WAIT_FOREVER);
for(;temp!=NULL;temp=temp->next)
{
if((temp->port==remote_port)&&(temp->protocol==TCP_PROTOCOL))
{
temp->checkcount++;
semGive (spoofingPortLock);
return NULL;
}
}
if( natEntryFree != NULL)
{
sptr_tcp_translation_entry= natEntryFree;
natEntryFree=natEntryFree->next_entrys_link;
}
else
{
sptr_tcp_translation_entry=natCheck_Free_Entrys();
}
if (sptr_tcp_translation_entry == NULL)
{
semGive (spoofingPortLock);
return (NULL);
}
if (find_nat_port_spoofing_number (ntohl (local_address),ntohs (local_port)) == FAIL)
{
semGive (spoofingPortLock);
return (NULL);
}
sptr_tcp_translation_entry->local_state = NAT_INITIAL_STATE;
sptr_tcp_translation_entry->global_state = NAT_INITIAL_STATE;
sptr_tcp_translation_entry->nat_aging_state = NAT_SYNCH_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->currenty_translation_entry_timer=nat.tcp_connecting_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;
*/
if(static_entry==-1)
{
sptr_tcp_translation_entry->spoofed_local_port = remote_port;
sptr_tcp_translation_entry->static_entry = FALSE;
sptr_tcp_translation_entry->remote_port = 0;
}
else
{
sptr_tcp_translation_entry->spoofed_local_port = nat.current_port_spoofing_number;
sptr_tcp_translation_entry->static_entry = static_entry;
sptr_tcp_translation_entry->remote_port = ntohs (remote_port);
}
sptr_tcp_translation_entry->local_port = ntohs (local_port);
sptr_tcp_translation_entry->local_address = ntohl (local_address);
sptr_tcp_translation_entry->remote_address = remote_address;
out_porthash=sptr_tcp_translation_entry->spoofed_local_port&(UPPER_EPHEMERAL_PORT_VALUE-1);
sptr_tcp_translation_entry->next_entrys_link=out_port_map[out_porthash].next_entrys_link;
out_port_map[out_porthash].next_entrys_link=sptr_tcp_translation_entry;
natMark_in_map(sptr_tcp_translation_entry);
natStats.tcpCons++;
semGive (spoofingPortLock);
/*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,
NAT_CURRENCY_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,
NAT_CURRENCY_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 + -