Skip to content

Commit

Permalink
Implement the rest of clat packet translation
Browse files Browse the repository at this point in the history
  • Loading branch information
ewpratten committed Aug 2, 2023
1 parent f1c1afe commit eb1da67
Showing 1 changed file with 32 additions and 19 deletions.
51 changes: 32 additions & 19 deletions src/protomask-clat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ use easy_tun::Tun;
use interproto::protocols::ip::{translate_ipv4_to_ipv6, translate_ipv6_to_ipv4};
use ipnet::Ipv6Net;
use nix::unistd::Uid;
use rfc6052::{embed_ipv4_addr_unchecked, extract_ipv4_addr_unchecked};
use std::{
io::{Read, Write},
net::Ipv4Addr,
net::{Ipv4Addr, Ipv6Addr},
};

mod common;
Expand Down Expand Up @@ -61,28 +62,37 @@ pub async fn main() {
log::trace!("New packet with layer 3 protocol: {}", layer_3_proto);
let output = match layer_3_proto {
// IPv4
4 => {
// Get the IPv4 source and destination addresses
let ipv4_source =
u32::from_be_bytes([buffer[12], buffer[13], buffer[14], buffer[15]]);
let ipv4_destination =
u32::from_be_bytes([buffer[16], buffer[17], buffer[18], buffer[19]]);

// 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);
let new_destination =
u128::from(args.embed_prefix.addr()) | (ipv4_destination as u128);

translate_ipv4_to_ipv6(&buffer[..len], new_source.into(), new_destination.into())
}
4 => translate_ipv4_to_ipv6(
&buffer[..len],
unsafe {
embed_ipv4_addr_unchecked(
Ipv4Addr::from(u32::from_be_bytes(buffer[12..16].try_into().unwrap())),
args.embed_prefix,
)
},
unsafe {
embed_ipv4_addr_unchecked(
Ipv4Addr::from(u32::from_be_bytes(buffer[16..20].try_into().unwrap())),
args.embed_prefix,
)
},
),

// IPv6
6 => translate_ipv6_to_ipv4(
&buffer[..len],
// NOTE: The new source and destination addresses are just the last
// 4 octets of the IPv6 source and destination addresses
Ipv4Addr::new(buffer[20], buffer[21], buffer[22], buffer[23]),
Ipv4Addr::new(buffer[36], buffer[37], buffer[38], buffer[39]),
unsafe {
extract_ipv4_addr_unchecked(
Ipv6Addr::from(u128::from_be_bytes(buffer[8..24].try_into().unwrap())),
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
proto => {
Expand All @@ -91,5 +101,8 @@ pub async fn main() {
}
}
.unwrap();

// Write the translated packet back to the TUN interface
tun.write(&output).unwrap();

Check failure on line 106 in src/protomask-clat.rs

View workflow job for this annotation

GitHub Actions / clippy

written amount is not handled

error: written amount is not handled --> src/protomask-clat.rs:106:9 | 106 | tun.write(&output).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: use `Write::write_all` instead, or handle partial writes = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unused_io_amount = note: `#[deny(clippy::unused_io_amount)]` on by default
}
}

0 comments on commit eb1da67

Please sign in to comment.