From 02e2644d519ef674a79b38c6ffb97dafe1f9a85a Mon Sep 17 00:00:00 2001 From: Evan Pratten Date: Sun, 16 Jul 2023 21:29:45 -0400 Subject: [PATCH] functional TCP --- src/nat/xlat/tcp.rs | 55 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 9 deletions(-) diff --git a/src/nat/xlat/tcp.rs b/src/nat/xlat/tcp.rs index af723ef..f3d39cb 100644 --- a/src/nat/xlat/tcp.rs +++ b/src/nat/xlat/tcp.rs @@ -4,7 +4,8 @@ use pnet_packet::{ ip::IpNextHeaderProtocols, ipv4::{self, Ipv4Packet, MutableIpv4Packet}, ipv6::{Ipv6Packet, MutableIpv6Packet}, - Packet, tcp::TcpPacket, + tcp::{self, MutableTcpPacket, TcpPacket}, + Packet, }; use crate::nat::packet::IpPacket; @@ -24,20 +25,43 @@ pub async fn proxy_tcp_packet<'a>( // Parse the original packet's payload to extract UDP data let tcp_packet = TcpPacket::new(original_packet.get_payload()) .ok_or_else(|| TcpProxyError::PacketTooShort(original_packet.get_payload().len()))?; + log::debug!( + "Incoming TCP packet ports: {} -> {}", + tcp_packet.get_source(), + tcp_packet.get_destination() + ); + log::debug!( + "Incoming TCP packet payload len: {}", + tcp_packet.payload().len() + ); // Construct a new output packet match (&original_packet, new_source, new_destination) { // Translate IPv4(UDP) to IPv6(UDP) (IpPacket::V4(_), IpAddr::V6(new_source), IpAddr::V6(new_destination)) => { + // Construct translated TCP packet + let mut translated_tcp_packet = + MutableTcpPacket::owned(tcp_packet.packet().to_vec()).unwrap(); + + // Rewrite the checksum + translated_tcp_packet.set_checksum(0); + translated_tcp_packet.set_checksum(tcp::ipv6_checksum( + &translated_tcp_packet.to_immutable(), + &new_source, + &new_destination, + )); + + // Construct translated IP packet to wrap TCP packet let mut output = - MutableIpv6Packet::owned(vec![0u8; 40 + tcp_packet.packet().len()]).unwrap(); + MutableIpv6Packet::owned(vec![0u8; 40 + translated_tcp_packet.packet().len()]) + .unwrap(); output.set_version(6); output.set_source(new_source); output.set_destination(new_destination); output.set_hop_limit(original_packet.get_ttl()); - output.set_next_header(IpNextHeaderProtocols::Udp); - output.set_payload_length(tcp_packet.packet().len() as u16); - output.set_payload(tcp_packet.packet()); + output.set_next_header(IpNextHeaderProtocols::Tcp); + output.set_payload_length(translated_tcp_packet.packet().len() as u16); + output.set_payload(translated_tcp_packet.packet()); Ok(IpPacket::V6( Ipv6Packet::owned(output.to_immutable().packet().to_vec()).unwrap(), )) @@ -45,16 +69,29 @@ pub async fn proxy_tcp_packet<'a>( // Translate IPv6(UDP) to IPv4(UDP) (IpPacket::V6(_), IpAddr::V4(new_source), IpAddr::V4(new_destination)) => { + // Construct translated TCP packet + let mut translated_tcp_packet = + MutableTcpPacket::owned(tcp_packet.packet().to_vec()).unwrap(); + + // Rewrite the checksum + translated_tcp_packet.set_checksum(0); + translated_tcp_packet.set_checksum(tcp::ipv4_checksum( + &translated_tcp_packet.to_immutable(), + &new_source, + &new_destination, + )); + + // Construct translated IP packet to wrap TCP packet let mut output = - MutableIpv4Packet::owned(vec![0u8; 20 + tcp_packet.packet().len()]).unwrap(); + MutableIpv4Packet::owned(vec![0u8; 20 + translated_tcp_packet.packet().len()]).unwrap(); output.set_version(4); output.set_source(new_source); output.set_destination(new_destination); output.set_ttl(original_packet.get_ttl()); - output.set_next_level_protocol(IpNextHeaderProtocols::Udp); + output.set_next_level_protocol(IpNextHeaderProtocols::Tcp); output.set_header_length(5); - output.set_total_length(20 + tcp_packet.packet().len() as u16); - output.set_payload(tcp_packet.packet()); + output.set_total_length(20 + translated_tcp_packet.packet().len() as u16); + output.set_payload(translated_tcp_packet.packet()); output.set_checksum(0); output.set_checksum(ipv4::checksum(&output.to_immutable())); Ok(IpPacket::V4(