⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nat_icmp_datagram.c

📁 VXWORKS NAT 部分源代码2 有兴趣朋友可以参考下
💻 C
📖 第 1 页 / 共 2 页
字号:
	UDP_PACKET sptr_udp_packet;

	sptr_udp_packet = *(UDP_PACKET *) &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;

	semTake(natentrylock, WAIT_FOREVER);
	sptr_udp_translation_entry = match_ports_with_udp_entry_inbound (&sptr_udp_packet);
	semGive(natentrylock);

    /* 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 = sptr_udp_packet.header.checksum ;

		checksum_fixup ((BYTE *) &checksum,
		(BYTE *) &sptr_udp_packet.header.source_port, sizeof (USHORT),
		(BYTE *) &local_port_number, sizeof (USHORT));

		sptr_udp_packet.header.source_port = local_port_number;
		sptr_udp_packet.header.checksum = checksum;
	}

	checksum = sptr_udp_packet.ip_header.header_checksum;

	checksum_fixup ((BYTE *) &checksum,
	(BYTE *) &sptr_udp_packet.ip_header.source_address, sizeof (IP_ADDRESS),
	(BYTE *) &address, sizeof (IP_ADDRESS));

	sptr_udp_packet.ip_header.source_address = address;
	sptr_udp_packet.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 *) &sptr_udp_packet, sizeof (NAT_ICMP_EMBEDDED_HEADER));

	*sptr_icmp_embedded_header = *(NAT_ICMP_EMBEDDED_HEADER *) &sptr_udp_packet;
	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)
{
	NAT_CURRENCY_TRANSLATION_ENTRY *sptr_icmp_translation_entry=NULL;
	USHORT icmp_identifier;
	USHORT spoofed_icmp_identifier;
	IP_ADDRESS address;
	USHORT checksum;
	ICMP_PACKET *sptr_icmp_embedded_packet=NULL;

	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);

	
	spoofed_icmp_identifier=spoofed_icmp_identifier&(UPPER_EPHEMERAL_PORT_VALUE-1);
	
	semTake(natentrylock, WAIT_FOREVER);
	
	sptr_icmp_translation_entry=out_port_map[spoofed_icmp_identifier].next_entrys_link;
	for(;sptr_icmp_translation_entry!=NULL;sptr_icmp_translation_entry=sptr_icmp_translation_entry->next_entrys_link)
	{
		if (sptr_icmp_translation_entry->remote_address== ntohl(sptr_icmp_packet->ip_header.source_address)
			&&(sptr_icmp_translation_entry->spoofed_local_port== ntohs(sptr_icmp_packet->header.option.echo_message.identifier)))
		{
			break;
		}
	}
	
	semGive(natentrylock);
	
	if (sptr_icmp_translation_entry == NULL)
	{
		/*sptr_icmp_translation_entry = &nat.nats.icmp_default_entry;*/
		return FAIL;
	}

	if (sptr_icmp_translation_entry->local_port!= 0x0000)
	{
		icmp_identifier = htons (sptr_icmp_translation_entry->local_port);

		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)
	{
		return (PASS);
	}   

	address = htonl (sptr_icmp_translation_entry->local_address);

	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_tcp_translation_local_rx_datagram_nats (ICMP_PACKET *sptr_icmp_packet)
{

	IP_ADDRESS address;
	NAT_CURRENCY_TRANSLATION_ENTRY *sptr_tcp_translation_entry=NULL;
	NAT_ICMP_EMBEDDED_HEADER *sptr_icmp_embedded_header=NULL;
	USHORT checksum;
	USHORT local_spoofed_port_number;
	TCP_PACKET sptr_tcp_packet;

	sptr_tcp_packet = *(TCP_PACKET *) &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;

	semTake(natentrylock, WAIT_FOREVER);
	sptr_tcp_translation_entry = find_entry (sptr_tcp_packet.ip_header.destination_address,sptr_tcp_packet.ip_header.source_address,sptr_tcp_packet.tcp_header.destination_port,sptr_tcp_packet.tcp_header.source_port);
	semGive(natentrylock);
	if (sptr_tcp_translation_entry == NULL)
	{
		/* no way to determine who to send the ICMP message to*/
		return (FAIL);
	}

	address = htonl (nat.global_address);

	local_spoofed_port_number = htons (sptr_tcp_translation_entry->spoofed_local_port);

	tcp_sequence_number_fixup_local_rx (&sptr_tcp_packet.tcp_header, sptr_tcp_translation_entry);

	checksum = sptr_tcp_packet.tcp_header.checksum;

	checksum_fixup ((BYTE *) &checksum,
	(BYTE *) &sptr_tcp_packet.tcp_header.destination_port, sizeof (USHORT),
	(BYTE *) &local_spoofed_port_number, sizeof (USHORT));

	sptr_tcp_packet.tcp_header.destination_port = local_spoofed_port_number;
	sptr_tcp_packet.tcp_header.checksum = checksum;

	checksum = sptr_tcp_packet.ip_header.header_checksum;

	checksum_fixup ((BYTE *) &checksum,
	(BYTE *) &sptr_tcp_packet.ip_header.destination_address, sizeof (IP_ADDRESS),
	(BYTE *) &address, sizeof (IP_ADDRESS));

	sptr_tcp_packet.ip_header.destination_address = address;
	sptr_tcp_packet.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 *) &sptr_tcp_packet, sizeof (NAT_ICMP_EMBEDDED_HEADER));

	*sptr_icmp_embedded_header = *(NAT_ICMP_EMBEDDED_HEADER *) &sptr_tcp_packet;
	sptr_icmp_packet->header.checksum = checksum;

	checksum = sptr_icmp_packet->ip_header.header_checksum;

	checksum_fixup ((BYTE *) &checksum,
	(BYTE *) &sptr_icmp_packet->ip_header.source_address, sizeof (IP_ADDRESS),
	(BYTE *) &address, sizeof (IP_ADDRESS));

	sptr_icmp_packet->ip_header.source_address = address;
	sptr_icmp_packet->ip_header.header_checksum = checksum;

	return (PASS);
}
/***************************************************************************/
static enum TEST handle_icmp_embedded_udp_translation_local_rx_datagram_nats (ICMP_PACKET *sptr_icmp_packet)
{
	
	NAT_ICMP_EMBEDDED_HEADER *sptr_icmp_embedded_header=NULL;
	NAT_CURRENCY_TRANSLATION_ENTRY *sptr_udp_translation_entry=NULL;
	IP_ADDRESS address;
	USHORT checksum;
	USHORT local_spoofed_port_number;
	UDP_PACKET sptr_udp_packet;

	sptr_udp_packet = *(UDP_PACKET *) &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;
	semTake(natentrylock, WAIT_FOREVER);
	sptr_udp_translation_entry = find_entry (sptr_udp_packet.ip_header.destination_address,sptr_udp_packet.ip_header.source_address,sptr_udp_packet.header.destination_port,sptr_udp_packet.header.source_port);
	semGive(natentrylock);
	if (sptr_udp_translation_entry == NULL)
	{
		/* no way to determine who to send the ICMP message to*/
		return (FAIL);
	}

	address = htonl (nat.global_address);

	local_spoofed_port_number = htons (sptr_udp_translation_entry->spoofed_local_port);

	checksum = sptr_udp_packet.header.checksum;

	checksum_fixup ((BYTE *) &checksum,
	(BYTE *) &sptr_udp_packet.header.destination_port, sizeof (USHORT),
	(BYTE *) &local_spoofed_port_number, sizeof (USHORT));

	sptr_udp_packet.header.destination_port = local_spoofed_port_number;
	sptr_udp_packet.header.checksum = checksum;

	checksum = sptr_udp_packet.ip_header.header_checksum;

	checksum_fixup ((BYTE *) &checksum,
	(BYTE *) &sptr_udp_packet.ip_header.destination_address, sizeof (IP_ADDRESS),
	(BYTE *) &address, sizeof (IP_ADDRESS));

	sptr_udp_packet.ip_header.destination_address = address;
	sptr_udp_packet.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 *) &sptr_udp_packet, sizeof (NAT_ICMP_EMBEDDED_HEADER));

	*sptr_icmp_embedded_header = *(NAT_ICMP_EMBEDDED_HEADER *) &sptr_udp_packet;
	sptr_icmp_packet->header.checksum = checksum;

	checksum = sptr_icmp_packet->ip_header.header_checksum;

	checksum_fixup ((BYTE *) &checksum,
	(BYTE *) &sptr_icmp_packet->ip_header.source_address, sizeof (IP_ADDRESS),
	(BYTE *) &address, sizeof (IP_ADDRESS));

	sptr_icmp_packet->ip_header.source_address = address;
	sptr_icmp_packet->ip_header.header_checksum = checksum;
    
    return (PASS);
}

/**********************************************************************************************
Description:
    Handle packet received from local port in Basic NAT
**********************************************************************************************/
static enum TEST handle_icmp_translation_local_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;

	nested_ip_packet.header = sptr_icmp_packet->header.option.unreachable_message.ip_data;

	nat_printf (NAT_PRINTF_TRACE, "ICMP received local: 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;

	changed_data.ip_data.addresses.source_address = nested_ip_packet.header.source_address;

	sptr_ip_translation_entry = match_sa_with_local_address (
	ntohl (unchanged_data.ip_data.addresses.destination_address),
	&nat.natg.ip_translation_list);

	if (sptr_ip_translation_entry == NULL)
	{
		nat_printf (NAT_PRINTF_TRACE,
		"ICMP received local: Can't match embedded destination IP address in ICMP datagram.\n");
		return (FAIL);
	}

	changed_data.ip_data.addresses.destination_address = htonl (sptr_ip_translation_entry->sa_global_address);

	changed_data.ip_data.ip_checksum = nested_ip_packet.header.header_checksum;

	/* adjust embedded IP checksum */
	checksum_fixup ((BYTE *) &changed_data.ip_data.ip_checksum,
	(BYTE *) &unchanged_data.ip_data.addresses.destination_address, (USHORT) sizeof (IP_ADDRESS),
	(BYTE *) &changed_data.ip_data.addresses.destination_address, (USHORT )sizeof (IP_ADDRESS));

	nested_ip_packet.header.destination_address = changed_data.ip_data.addresses.destination_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.destination_address,
	sizeof (ULONG),
	(BYTE *) &nested_ip_packet.header.destination_address,
	sizeof (ULONG));

	sptr_icmp_packet->header.option.unreachable_message.ip_data.destination_address =
	changed_data.ip_data.addresses.destination_address;

	/* adjust ICMP header checksum, then with change in embedded IP 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 local: translate IP header of ICMP packet\n");

	/* this function also adjusts IP header's checksum */
	if (handle_ip_translation_local_rx_natg ((IP_PACKET *) sptr_icmp_packet) == NULL)
	{
		return (FAIL);
	}

	return (PASS);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -