1

Implement the rest of clat packet translation

This commit is contained in:
Evan Pratten 2023-08-02 19:59:23 -04:00
parent f1c1afed96
commit eb1da675de

View File

@ -9,9 +9,10 @@ use easy_tun::Tun;
use interproto::protocols::ip::{translate_ipv4_to_ipv6, translate_ipv6_to_ipv4}; use interproto::protocols::ip::{translate_ipv4_to_ipv6, translate_ipv6_to_ipv4};
use ipnet::Ipv6Net; use ipnet::Ipv6Net;
use nix::unistd::Uid; use nix::unistd::Uid;
use rfc6052::{embed_ipv4_addr_unchecked, extract_ipv4_addr_unchecked};
use std::{ use std::{
io::{Read, Write}, io::{Read, Write},
net::Ipv4Addr, net::{Ipv4Addr, Ipv6Addr},
}; };
mod common; mod common;
@ -61,28 +62,37 @@ pub async fn main() {
log::trace!("New packet with layer 3 protocol: {}", layer_3_proto); log::trace!("New packet with layer 3 protocol: {}", layer_3_proto);
let output = match layer_3_proto { let output = match layer_3_proto {
// IPv4 // IPv4
4 => { 4 => translate_ipv4_to_ipv6(
// Get the IPv4 source and destination addresses &buffer[..len],
let ipv4_source = unsafe {
u32::from_be_bytes([buffer[12], buffer[13], buffer[14], buffer[15]]); embed_ipv4_addr_unchecked(
let ipv4_destination = Ipv4Addr::from(u32::from_be_bytes(buffer[12..16].try_into().unwrap())),
u32::from_be_bytes([buffer[16], buffer[17], buffer[18], buffer[19]]); args.embed_prefix,
)
// Create a new IPv6 source and destination address by embedding the IPv4 addresses into the clat prefix },
let new_source = u128::from(args.embed_prefix.addr()) | (ipv4_source as u128); unsafe {
let new_destination = embed_ipv4_addr_unchecked(
u128::from(args.embed_prefix.addr()) | (ipv4_destination as u128); Ipv4Addr::from(u32::from_be_bytes(buffer[16..20].try_into().unwrap())),
args.embed_prefix,
translate_ipv4_to_ipv6(&buffer[..len], new_source.into(), new_destination.into()) )
} },
),
// IPv6 // IPv6
6 => translate_ipv6_to_ipv4( 6 => translate_ipv6_to_ipv4(
&buffer[..len], &buffer[..len],
// NOTE: The new source and destination addresses are just the last unsafe {
// 4 octets of the IPv6 source and destination addresses extract_ipv4_addr_unchecked(
Ipv4Addr::new(buffer[20], buffer[21], buffer[22], buffer[23]), Ipv6Addr::from(u128::from_be_bytes(buffer[8..24].try_into().unwrap())),
Ipv4Addr::new(buffer[36], buffer[37], buffer[38], buffer[39]), args.embed_prefix.prefix_len(),
)
},
unsafe {
extract_ipv4_addr_unchecked(
Ipv6Addr::from(u128::from_be_bytes(buffer[24..40].try_into().unwrap())),
args.embed_prefix.prefix_len(),
)
},
), ),
// Unknown // Unknown
proto => { proto => {
@ -91,5 +101,8 @@ pub async fn main() {
} }
} }
.unwrap(); .unwrap();
// Write the translated packet back to the TUN interface
tun.write(&output).unwrap();
} }
} }