Clean up old files
This commit is contained in:
parent
94fdf28012
commit
deaa9e87c5
@ -1,121 +0,0 @@
|
|||||||
// use futures::stream::TryStreamExt;
|
|
||||||
// use ipnet::{Ipv4Net, Ipv6Net};
|
|
||||||
// use tun_tap::{Iface, Mode};
|
|
||||||
|
|
||||||
// #[derive(Debug, thiserror::Error)]
|
|
||||||
// pub enum InterfaceError {
|
|
||||||
// #[error(transparent)]
|
|
||||||
// IoError(#[from] std::io::Error),
|
|
||||||
// #[error(transparent)]
|
|
||||||
// NetlinkError(#[from] rtnetlink::Error),
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Wrapper around a TUN interface that automatically configures itself
|
|
||||||
// #[derive(Debug)]
|
|
||||||
// pub struct Nat64Interface {
|
|
||||||
// /// Underlying TUN interface
|
|
||||||
// interface: Iface,
|
|
||||||
// /// Interface MTU
|
|
||||||
// mtu: usize,
|
|
||||||
// }
|
|
||||||
|
|
||||||
// impl Nat64Interface {
|
|
||||||
// /// Create a new NAT64 interface
|
|
||||||
// pub async fn new(v6_prefix: Ipv6Net, v4_pool: &Vec<Ipv4Net>) -> Result<Self, InterfaceError> {
|
|
||||||
// // Bring up an rtnetlink connection
|
|
||||||
// let (rt_connection, rt_handle, _) = rtnetlink::new_connection()?;
|
|
||||||
// tokio::spawn(rt_connection);
|
|
||||||
|
|
||||||
// // Set up the TUN interface
|
|
||||||
// let interface = Iface::without_packet_info("nat64i%d", Mode::Tun)?;
|
|
||||||
|
|
||||||
// // Get access to the new interface through rtnetlink
|
|
||||||
// let interface_link = rt_handle
|
|
||||||
// .link()
|
|
||||||
// .get()
|
|
||||||
// .match_name(interface.name().to_owned())
|
|
||||||
// .execute()
|
|
||||||
// .try_next()
|
|
||||||
// .await?
|
|
||||||
// .expect("Interface not found even though it was just created");
|
|
||||||
|
|
||||||
// // Bring up the interface
|
|
||||||
// rt_handle
|
|
||||||
// .link()
|
|
||||||
// .set(interface_link.header.index)
|
|
||||||
// .up()
|
|
||||||
// .execute()
|
|
||||||
// .await?;
|
|
||||||
// log::info!("Created interface: {}", interface.name());
|
|
||||||
|
|
||||||
// // Add the v6 prefix as a route
|
|
||||||
// rt_handle
|
|
||||||
// .route()
|
|
||||||
// .add()
|
|
||||||
// .v6()
|
|
||||||
// .destination_prefix(v6_prefix.addr(), v6_prefix.prefix_len())
|
|
||||||
// .output_interface(interface_link.header.index)
|
|
||||||
// .execute()
|
|
||||||
// .await
|
|
||||||
// .map_err(|error| {
|
|
||||||
// log::error!("Failed to add route for {}: {}", v6_prefix, error);
|
|
||||||
// error
|
|
||||||
// })?;
|
|
||||||
// log::info!("Added route: {} via {}", v6_prefix, interface.name());
|
|
||||||
|
|
||||||
// // Add every prefix in the v4 pool as a route
|
|
||||||
// for prefix in v4_pool {
|
|
||||||
// rt_handle
|
|
||||||
// .route()
|
|
||||||
// .add()
|
|
||||||
// .v4()
|
|
||||||
// .destination_prefix(prefix.addr(), prefix.prefix_len())
|
|
||||||
// .output_interface(interface_link.header.index)
|
|
||||||
// .execute()
|
|
||||||
// .await
|
|
||||||
// .map_err(|error| {
|
|
||||||
// log::error!("Failed to add route for {}: {}", prefix, error);
|
|
||||||
// error
|
|
||||||
// })?;
|
|
||||||
// log::info!("Added route: {} via {}", prefix, interface.name());
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Read the interface MTU
|
|
||||||
// let mtu: usize =
|
|
||||||
// std::fs::read_to_string(format!("/sys/class/net/{}/mtu", interface.name()))
|
|
||||||
// .expect("Failed to read interface MTU")
|
|
||||||
// .strip_suffix("\n")
|
|
||||||
// .unwrap()
|
|
||||||
// .parse()
|
|
||||||
// .unwrap();
|
|
||||||
|
|
||||||
// Ok(Self { interface, mtu })
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Get the interface mode
|
|
||||||
// #[allow(dead_code)]
|
|
||||||
// pub fn mode(&self) -> Mode {
|
|
||||||
// self.interface.mode()
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Get the interface nam
|
|
||||||
// #[allow(dead_code)]
|
|
||||||
// pub fn name(&self) -> &str {
|
|
||||||
// self.interface.name()
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Get the interface MTU
|
|
||||||
// pub fn mtu(&self) -> usize {
|
|
||||||
// self.mtu
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Receive a packet from the interface
|
|
||||||
// pub fn recv(&self, buf: &mut [u8]) -> Result<usize, std::io::Error> {
|
|
||||||
// self.interface.recv(buf)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Send a packet to the interface
|
|
||||||
// pub fn send(&self, buf: &[u8]) -> Result<usize, std::io::Error> {
|
|
||||||
// self.interface.send(buf)
|
|
||||||
// }
|
|
||||||
// }
|
|
@ -1,163 +0,0 @@
|
|||||||
// /// Quickly convert a byte slice into an ICMP packet
|
|
||||||
// #[macro_export]
|
|
||||||
// macro_rules! into_icmp {
|
|
||||||
// ($bytes:expr) => {
|
|
||||||
// pnet_packet::icmp::IcmpPacket::owned($bytes).ok_or_else(|| {
|
|
||||||
// crate::nat::xlat::PacketTranslationError::InputPacketTooShort($bytes.len())
|
|
||||||
// })
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Quickly convert a byte slice into an ICMPv6 packet
|
|
||||||
// #[macro_export]
|
|
||||||
// macro_rules! into_icmpv6 {
|
|
||||||
// ($bytes:expr) => {
|
|
||||||
// pnet_packet::icmpv6::Icmpv6Packet::owned($bytes).ok_or_else(|| {
|
|
||||||
// crate::nat::xlat::PacketTranslationError::InputPacketTooShort($bytes.len())
|
|
||||||
// })
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Quickly convert a byte slice into a UDP packet
|
|
||||||
// #[macro_export]
|
|
||||||
// macro_rules! into_udp {
|
|
||||||
// ($bytes:expr) => {
|
|
||||||
// pnet_packet::udp::UdpPacket::owned($bytes).ok_or_else(|| {
|
|
||||||
// crate::nat::xlat::PacketTranslationError::InputPacketTooShort($bytes.len())
|
|
||||||
// })
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Quickly convert a byte slice into a TCP packet
|
|
||||||
// #[macro_export]
|
|
||||||
// macro_rules! into_tcp {
|
|
||||||
// ($bytes:expr) => {
|
|
||||||
// pnet_packet::tcp::TcpPacket::owned($bytes).ok_or_else(|| {
|
|
||||||
// crate::nat::xlat::PacketTranslationError::InputPacketTooShort($bytes.len())
|
|
||||||
// })
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Quickly construct an IPv6 packet with the given parameters
|
|
||||||
// #[macro_export]
|
|
||||||
// macro_rules! ipv6_packet {
|
|
||||||
// ($source:expr, $destination:expr, $next_header:expr, $hop_limit:expr, $payload:expr) => {
|
|
||||||
// ipv6_packet!(
|
|
||||||
// $source,
|
|
||||||
// $destination,
|
|
||||||
// 0,
|
|
||||||
// 0,
|
|
||||||
// $next_header,
|
|
||||||
// $hop_limit,
|
|
||||||
// $payload
|
|
||||||
// )
|
|
||||||
// };
|
|
||||||
|
|
||||||
// ($source:expr, $destination:expr, $traffic_class:expr, $flow_label:expr, $next_header:expr, $hop_limit:expr, $payload:expr) => {{
|
|
||||||
// let mut output =
|
|
||||||
// pnet_packet::ipv6::MutableIpv6Packet::owned(vec![0u8; 40 + $payload.len()]).unwrap();
|
|
||||||
// output.set_version(6);
|
|
||||||
// output.set_traffic_class($traffic_class);
|
|
||||||
// output.set_flow_label($flow_label);
|
|
||||||
// output.set_next_header($next_header);
|
|
||||||
// output.set_hop_limit($hop_limit);
|
|
||||||
// output.set_source($source);
|
|
||||||
// output.set_destination($destination);
|
|
||||||
// output.set_payload_length($payload.len() as u16);
|
|
||||||
// output.set_payload($payload);
|
|
||||||
// pnet_packet::ipv6::Ipv6Packet::owned(output.to_immutable().packet().to_vec()).unwrap()
|
|
||||||
// }};
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Quickly construct an IPv4 packet with the given parameters
|
|
||||||
// #[macro_export]
|
|
||||||
// macro_rules! ipv4_packet {
|
|
||||||
// ($source:expr, $destination:expr, $next_level_protocol:expr, $ttl:expr, $payload:expr) => {
|
|
||||||
// ipv4_packet!(
|
|
||||||
// $source,
|
|
||||||
// $destination,
|
|
||||||
// 0,
|
|
||||||
// 0,
|
|
||||||
// 0,
|
|
||||||
// 0,
|
|
||||||
// 0,
|
|
||||||
// $ttl,
|
|
||||||
// $next_level_protocol,
|
|
||||||
// // &[],
|
|
||||||
// $payload
|
|
||||||
// )
|
|
||||||
// };
|
|
||||||
|
|
||||||
// // NOTE: Temporarily disabled options, since we aren't using them
|
|
||||||
// // ($source:expr, $destination:expr, $dscp:expr, $ecn:expr, $identification:expr, $flags:expr, $fragment_offset:expr, $ttl:expr, $next_level_protocol:expr, $options:expr, $payload:expr) => {{
|
|
||||||
// ($source:expr, $destination:expr, $dscp:expr, $ecn:expr, $identification:expr, $flags:expr, $fragment_offset:expr, $ttl:expr, $next_level_protocol:expr, $payload:expr) => {{
|
|
||||||
// // let total_option_length = $options
|
|
||||||
// // .iter()
|
|
||||||
// // .map(|o: pnet_packet::ipv4::Ipv4Option| pnet_packet::Packet::payload(o).len())
|
|
||||||
// // .sum::<usize>();
|
|
||||||
// let total_option_length: usize = 0;
|
|
||||||
// let mut output = pnet_packet::ipv4::MutableIpv4Packet::owned(vec![
|
|
||||||
// 0u8;
|
|
||||||
// 20 + total_option_length
|
|
||||||
// + $payload.len()
|
|
||||||
// ])
|
|
||||||
// .unwrap();
|
|
||||||
// output.set_version(4);
|
|
||||||
// output.set_header_length(((20 + total_option_length) / (32 / 8)) as u8); // Dynamic header length :(
|
|
||||||
// output.set_dscp($dscp);
|
|
||||||
// output.set_ecn($ecn);
|
|
||||||
// output.set_total_length((20 + total_option_length + $payload.len()) as u16);
|
|
||||||
// output.set_identification($identification);
|
|
||||||
// output.set_flags($flags);
|
|
||||||
// output.set_fragment_offset($fragment_offset);
|
|
||||||
// output.set_ttl($ttl);
|
|
||||||
// output.set_next_level_protocol($next_level_protocol);
|
|
||||||
// output.set_source($source);
|
|
||||||
// output.set_destination($destination);
|
|
||||||
// // output.set_options($options);
|
|
||||||
// output.set_payload($payload);
|
|
||||||
// output.set_checksum(0);
|
|
||||||
// output.set_checksum(pnet_packet::ipv4::checksum(&output.to_immutable()));
|
|
||||||
// pnet_packet::ipv4::Ipv4Packet::owned(output.to_immutable().packet().to_vec()).unwrap()
|
|
||||||
// }};
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Quickly construct an ICMPv6 packet with the given parameters
|
|
||||||
// #[macro_export]
|
|
||||||
// macro_rules! icmpv6_packet {
|
|
||||||
// ($source:expr, $destination:expr, $message_type:expr, $code:expr) => {
|
|
||||||
// icmpv6_packet!($source, $destination, $message_type, $code, &[0u8; 0])
|
|
||||||
// };
|
|
||||||
// ($source:expr, $destination:expr, $message_type:expr, $code:expr, $payload:expr) => {{
|
|
||||||
// let mut output =
|
|
||||||
// pnet_packet::icmpv6::MutableIcmpv6Packet::owned(vec![0u8; 4 + $payload.len()]).unwrap();
|
|
||||||
// output.set_icmpv6_type($message_type);
|
|
||||||
// output.set_icmpv6_code($code);
|
|
||||||
// output.set_payload($payload);
|
|
||||||
// output.set_checksum(0);
|
|
||||||
// output.set_checksum(pnet_packet::icmpv6::checksum(
|
|
||||||
// &output.to_immutable(),
|
|
||||||
// &$source,
|
|
||||||
// &$destination,
|
|
||||||
// ));
|
|
||||||
// pnet_packet::icmpv6::Icmpv6Packet::owned(output.to_immutable().packet().to_vec()).unwrap()
|
|
||||||
// }};
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Quickly construct an ICMP packet with the given parameters
|
|
||||||
// #[macro_export]
|
|
||||||
// macro_rules! icmp_packet {
|
|
||||||
// ($message_type:expr, $code:expr) => {
|
|
||||||
// icmp_packet!($message_type, $code, &[0u8; 0])
|
|
||||||
// };
|
|
||||||
// ($message_type:expr, $code:expr, $payload:expr) => {{
|
|
||||||
// let mut output =
|
|
||||||
// pnet_packet::icmp::MutableIcmpPacket::owned(vec![0u8; 4 + $payload.len()]).unwrap();
|
|
||||||
// output.set_icmp_type($message_type);
|
|
||||||
// output.set_icmp_code($code);
|
|
||||||
// output.set_payload($payload);
|
|
||||||
// output.set_checksum(0);
|
|
||||||
// output.set_checksum(pnet_packet::icmp::checksum(&output.to_immutable()));
|
|
||||||
// pnet_packet::icmp::IcmpPacket::owned(output.to_immutable().packet().to_vec()).unwrap()
|
|
||||||
// }};
|
|
||||||
// }
|
|
@ -15,12 +15,8 @@ use std::{
|
|||||||
};
|
};
|
||||||
use tokio::sync::{broadcast, mpsc};
|
use tokio::sync::{broadcast, mpsc};
|
||||||
|
|
||||||
mod interface;
|
|
||||||
mod macros;
|
|
||||||
// mod packet;
|
|
||||||
mod table;
|
mod table;
|
||||||
mod utils;
|
mod utils;
|
||||||
mod xlat;
|
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
pub enum Nat64Error {
|
pub enum Nat64Error {
|
||||||
|
@ -1,159 +0,0 @@
|
|||||||
// //! A generic internet protocol packet type
|
|
||||||
|
|
||||||
// use std::net::IpAddr;
|
|
||||||
|
|
||||||
// use pnet_packet::{ip::IpNextHeaderProtocol, ipv4::Ipv4Packet, ipv6::Ipv6Packet, Packet};
|
|
||||||
|
|
||||||
// #[derive(Debug, thiserror::Error)]
|
|
||||||
// pub enum PacketError {
|
|
||||||
// #[error("Packed too small (len: {0})")]
|
|
||||||
// PacketTooSmall(usize),
|
|
||||||
// #[error("Unknown Internet Protocol version: {0}")]
|
|
||||||
// UnknownVersion(u8),
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// A protocol-agnostic packet type
|
|
||||||
// #[derive(Debug)]
|
|
||||||
// pub enum IpPacket<'a> {
|
|
||||||
// /// IPv4 packet
|
|
||||||
// V4(Ipv4Packet<'a>),
|
|
||||||
// /// IPv6 packet
|
|
||||||
// V6(Ipv6Packet<'a>),
|
|
||||||
// }
|
|
||||||
|
|
||||||
// impl IpPacket<'_> {
|
|
||||||
// /// Creates a new packet from a byte slice
|
|
||||||
// pub fn new<'a>(bytes: &'a [u8]) -> Result<IpPacket<'a>, PacketError> {
|
|
||||||
// // Parse the packet. If there is an error, cast None to the error type
|
|
||||||
// match bytes[0] >> 4 {
|
|
||||||
// 4 => Ok(IpPacket::V4(
|
|
||||||
// Ipv4Packet::new(bytes).ok_or_else(|| PacketError::PacketTooSmall(bytes.len()))?,
|
|
||||||
// )),
|
|
||||||
// 6 => Ok(IpPacket::V6(
|
|
||||||
// Ipv6Packet::new(bytes).ok_or_else(|| PacketError::PacketTooSmall(bytes.len()))?,
|
|
||||||
// )),
|
|
||||||
// n => Err(PacketError::UnknownVersion(n)),
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Returns the source address
|
|
||||||
// pub fn get_source(&self) -> IpAddr {
|
|
||||||
// match self {
|
|
||||||
// IpPacket::V4(packet) => IpAddr::V4(packet.get_source()),
|
|
||||||
// IpPacket::V6(packet) => IpAddr::V6(packet.get_source()),
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Returns the destination address
|
|
||||||
// pub fn get_destination(&self) -> IpAddr {
|
|
||||||
// match self {
|
|
||||||
// IpPacket::V4(packet) => IpAddr::V4(packet.get_destination()),
|
|
||||||
// IpPacket::V6(packet) => IpAddr::V6(packet.get_destination()),
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Returns the packet header
|
|
||||||
// #[allow(dead_code)]
|
|
||||||
// pub fn get_header(&self) -> &[u8] {
|
|
||||||
// match self {
|
|
||||||
// IpPacket::V4(packet) => packet.packet()[..20].as_ref(),
|
|
||||||
// IpPacket::V6(packet) => packet.packet()[..40].as_ref(),
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Returns the packet payload
|
|
||||||
// #[allow(dead_code)]
|
|
||||||
// pub fn get_payload(&self) -> &[u8] {
|
|
||||||
// match self {
|
|
||||||
// IpPacket::V4(packet) => packet.payload(),
|
|
||||||
// IpPacket::V6(packet) => packet.payload(),
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Converts the packet to a byte vector
|
|
||||||
// pub fn to_bytes(&self) -> Vec<u8> {
|
|
||||||
// match self {
|
|
||||||
// IpPacket::V4(packet) => packet.packet().to_vec(),
|
|
||||||
// IpPacket::V6(packet) => packet.packet().to_vec(),
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Returns the packet length
|
|
||||||
// #[allow(dead_code)]
|
|
||||||
// pub fn len(&self) -> usize {
|
|
||||||
// match self {
|
|
||||||
// IpPacket::V4(packet) => packet.packet().len(),
|
|
||||||
// IpPacket::V6(packet) => packet.packet().len(),
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Get the next header
|
|
||||||
// pub fn get_next_header(&self) -> IpNextHeaderProtocol {
|
|
||||||
// match self {
|
|
||||||
// IpPacket::V4(packet) => packet.get_next_level_protocol(),
|
|
||||||
// IpPacket::V6(packet) => packet.get_next_header(),
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Get the TTL
|
|
||||||
// #[allow(dead_code)]
|
|
||||||
// pub fn get_ttl(&self) -> u8 {
|
|
||||||
// match self {
|
|
||||||
// IpPacket::V4(packet) => packet.get_ttl(),
|
|
||||||
// IpPacket::V6(packet) => packet.get_hop_limit(),
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// #[cfg(test)]
|
|
||||||
// mod tests {
|
|
||||||
// use pnet_packet::{ipv4::MutableIpv4Packet, ipv6::MutableIpv6Packet};
|
|
||||||
|
|
||||||
// use super::*;
|
|
||||||
|
|
||||||
// #[test]
|
|
||||||
// fn test_ipv4_packet() {
|
|
||||||
// // Build packet to test
|
|
||||||
// let mut packet = MutableIpv4Packet::owned(vec![0; 20]).unwrap();
|
|
||||||
// packet.set_version(4);
|
|
||||||
// packet.set_source("192.0.2.1".parse().unwrap());
|
|
||||||
// packet.set_destination("192.0.2.2".parse().unwrap());
|
|
||||||
|
|
||||||
// // Parse
|
|
||||||
// let header = packet.packet()[..20].to_vec();
|
|
||||||
// let packet = IpPacket::new(packet.packet()).unwrap();
|
|
||||||
// assert_eq!(
|
|
||||||
// packet.get_source(),
|
|
||||||
// IpAddr::V4("192.0.2.1".parse().unwrap())
|
|
||||||
// );
|
|
||||||
// assert_eq!(
|
|
||||||
// packet.get_destination(),
|
|
||||||
// IpAddr::V4("192.0.2.2".parse().unwrap())
|
|
||||||
// );
|
|
||||||
// assert_eq!(packet.get_header(), header);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// #[test]
|
|
||||||
// fn test_ipv6_packet() {
|
|
||||||
// // Build packet to test
|
|
||||||
// let mut packet = MutableIpv6Packet::owned(vec![0; 40]).unwrap();
|
|
||||||
// packet.set_version(6);
|
|
||||||
// packet.set_source("2001:db8::c0a8:1".parse().unwrap());
|
|
||||||
// packet.set_destination("2001:db8::c0a8:2".parse().unwrap());
|
|
||||||
|
|
||||||
// // Parse
|
|
||||||
// let header = packet.packet()[..40].to_vec();
|
|
||||||
// let packet = IpPacket::new(packet.packet()).unwrap();
|
|
||||||
|
|
||||||
// // Test
|
|
||||||
// assert_eq!(
|
|
||||||
// packet.get_source(),
|
|
||||||
// IpAddr::V6("2001:db8::c0a8:1".parse().unwrap())
|
|
||||||
// );
|
|
||||||
// assert_eq!(
|
|
||||||
// packet.get_destination(),
|
|
||||||
// IpAddr::V6("2001:db8::c0a8:2".parse().unwrap())
|
|
||||||
// );
|
|
||||||
// assert_eq!(packet.get_header(), header);
|
|
||||||
// }
|
|
||||||
// }
|
|
@ -1,314 +0,0 @@
|
|||||||
use std::net::{Ipv4Addr, Ipv6Addr};
|
|
||||||
|
|
||||||
use pnet_packet::{
|
|
||||||
icmp::{
|
|
||||||
self, destination_unreachable, IcmpCode, IcmpPacket, IcmpType, IcmpTypes, MutableIcmpPacket,
|
|
||||||
},
|
|
||||||
icmpv6::{self, Icmpv6Code, Icmpv6Packet, Icmpv6Type, Icmpv6Types, MutableIcmpv6Packet},
|
|
||||||
ip::IpNextHeaderProtocols,
|
|
||||||
ipv4::Ipv4Packet,
|
|
||||||
ipv6::Ipv6Packet,
|
|
||||||
Packet,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{icmp_packet, icmpv6_packet, ipv4_packet, ipv6_packet};
|
|
||||||
|
|
||||||
use super::PacketTranslationError;
|
|
||||||
|
|
||||||
// /// Best effort translation from an ICMP type and code to an ICMPv6 type and code
|
|
||||||
// fn translate_type_and_code_4_to_6(
|
|
||||||
// icmp_type: IcmpType,
|
|
||||||
// icmp_code: IcmpCode,
|
|
||||||
// ) -> Option<(Icmpv6Type, Icmpv6Code)> {
|
|
||||||
// match (icmp_type, icmp_code) {
|
|
||||||
// // Echo Request
|
|
||||||
// (IcmpTypes::EchoRequest, _) => Some((Icmpv6Types::EchoRequest, Icmpv6Code(0))),
|
|
||||||
|
|
||||||
// // Echo Reply
|
|
||||||
// (IcmpTypes::EchoReply, _) => Some((Icmpv6Types::EchoReply, Icmpv6Code(0))),
|
|
||||||
|
|
||||||
// // Packet Too Big
|
|
||||||
// (
|
|
||||||
// IcmpTypes::DestinationUnreachable,
|
|
||||||
// destination_unreachable::IcmpCodes::FragmentationRequiredAndDFFlagSet,
|
|
||||||
// ) => Some((Icmpv6Types::PacketTooBig, Icmpv6Code(0))),
|
|
||||||
|
|
||||||
// // Destination Unreachable
|
|
||||||
// (IcmpTypes::DestinationUnreachable, icmp_code) => Some((
|
|
||||||
// Icmpv6Types::DestinationUnreachable,
|
|
||||||
// #[cfg_attr(rustfmt, rustfmt_skip)]
|
|
||||||
// Icmpv6Code(match icmp_code {
|
|
||||||
// destination_unreachable::IcmpCodes::DestinationHostUnreachable => 3,
|
|
||||||
// destination_unreachable::IcmpCodes::DestinationProtocolUnreachable => 4,
|
|
||||||
// destination_unreachable::IcmpCodes::DestinationPortUnreachable => 4,
|
|
||||||
// destination_unreachable::IcmpCodes::SourceRouteFailed => 5,
|
|
||||||
// destination_unreachable::IcmpCodes::SourceHostIsolated => 2,
|
|
||||||
// destination_unreachable::IcmpCodes::NetworkAdministrativelyProhibited => 1,
|
|
||||||
// destination_unreachable::IcmpCodes::HostAdministrativelyProhibited => 1,
|
|
||||||
// destination_unreachable::IcmpCodes::CommunicationAdministrativelyProhibited => 1,
|
|
||||||
|
|
||||||
// // Default to No Route to Destination
|
|
||||||
// _ => 0,
|
|
||||||
// }),
|
|
||||||
// )),
|
|
||||||
|
|
||||||
// // Time Exceeded
|
|
||||||
// (IcmpTypes::TimeExceeded, icmp_code) => {
|
|
||||||
// Some((Icmpv6Types::TimeExceeded, Icmpv6Code(icmp_code.0)))
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Default unsupported
|
|
||||||
// _ => {
|
|
||||||
// log::warn!(
|
|
||||||
// "Unsupported ICMP code and type: {:?}, {:?}",
|
|
||||||
// icmp_type,
|
|
||||||
// icmp_code
|
|
||||||
// );
|
|
||||||
// None
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Best effort translation from an ICMPv6 type and code to an ICMP type and code
|
|
||||||
// fn translate_type_and_code_6_to_4(
|
|
||||||
// icmp_type: Icmpv6Type,
|
|
||||||
// icmp_code: Icmpv6Code,
|
|
||||||
// ) -> Option<(IcmpType, IcmpCode)> {
|
|
||||||
// match (icmp_type, icmp_code) {
|
|
||||||
// // Echo Request
|
|
||||||
// (Icmpv6Types::EchoRequest, _) => Some((IcmpTypes::EchoRequest, IcmpCode(0))),
|
|
||||||
|
|
||||||
// // Echo Reply
|
|
||||||
// (Icmpv6Types::EchoReply, _) => Some((IcmpTypes::EchoReply, IcmpCode(0))),
|
|
||||||
|
|
||||||
// // Packet Too Big
|
|
||||||
// (Icmpv6Types::PacketTooBig, _) => Some((
|
|
||||||
// IcmpTypes::DestinationUnreachable,
|
|
||||||
// destination_unreachable::IcmpCodes::FragmentationRequiredAndDFFlagSet,
|
|
||||||
// )),
|
|
||||||
|
|
||||||
// // Destination Unreachable
|
|
||||||
// (Icmpv6Types::DestinationUnreachable, icmp_code) => Some((
|
|
||||||
// IcmpTypes::DestinationUnreachable,
|
|
||||||
// #[cfg_attr(rustfmt, rustfmt_skip)]
|
|
||||||
// match icmp_code.0 {
|
|
||||||
// 1 => destination_unreachable::IcmpCodes::CommunicationAdministrativelyProhibited,
|
|
||||||
// 2 => destination_unreachable::IcmpCodes::SourceHostIsolated,
|
|
||||||
// 3 => destination_unreachable::IcmpCodes::DestinationHostUnreachable,
|
|
||||||
// 4 => destination_unreachable::IcmpCodes::DestinationPortUnreachable,
|
|
||||||
// 5 => destination_unreachable::IcmpCodes::SourceRouteFailed,
|
|
||||||
// _ => destination_unreachable::IcmpCodes::DestinationNetworkUnreachable,
|
|
||||||
// },
|
|
||||||
// )),
|
|
||||||
|
|
||||||
// // Time Exceeded
|
|
||||||
// (Icmpv6Types::TimeExceeded, icmp_code) => {
|
|
||||||
// Some((IcmpTypes::TimeExceeded, IcmpCode(icmp_code.0)))
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Default unsupported
|
|
||||||
// _ => {
|
|
||||||
// log::warn!(
|
|
||||||
// "Unsupported ICMPv6 code and type: {:?}, {:?}",
|
|
||||||
// icmp_type,
|
|
||||||
// icmp_code
|
|
||||||
// );
|
|
||||||
// None
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
/// Translate an ICMP packet into an ICMPv6 packet
|
|
||||||
pub fn translate_icmp_4_to_6(
|
|
||||||
icmp_packet: IcmpPacket,
|
|
||||||
new_source: Ipv6Addr,
|
|
||||||
new_dest: Ipv6Addr,
|
|
||||||
) -> Result<Option<Icmpv6Packet>, PacketTranslationError> {
|
|
||||||
// Translate the type and code
|
|
||||||
if let Some((icmpv6_type, icmpv6_code)) =
|
|
||||||
translate_type_and_code_4_to_6(icmp_packet.get_icmp_type(), icmp_packet.get_icmp_code())
|
|
||||||
{
|
|
||||||
// "Time Exceeded" requires an additional payload be embedded in the packet
|
|
||||||
// This payload looks like: 4bytes + IPv6(data)
|
|
||||||
let mut output_payload = icmp_packet.payload().to_vec();
|
|
||||||
if icmpv6_type == Icmpv6Types::TimeExceeded {
|
|
||||||
// Get access to the original payload
|
|
||||||
let original_payload =
|
|
||||||
Ipv4Packet::new(&icmp_packet.payload()[4..]).ok_or_else(|| {
|
|
||||||
PacketTranslationError::EmbeddedPacketTooShort(icmp_packet.payload().len() - 4)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
// Copy the original payload's payload to a buffer
|
|
||||||
let mut original_payload_inner = vec![0u8; original_payload.payload().len()];
|
|
||||||
original_payload_inner.copy_from_slice(original_payload.payload());
|
|
||||||
|
|
||||||
// if the original payload's next header is ICMP, we need to translated the inner payload's ICMP type
|
|
||||||
if original_payload.get_next_level_protocol() == IpNextHeaderProtocols::Icmp {
|
|
||||||
log::debug!("Time Exceeded packet contains another ICMP packet.. Translating");
|
|
||||||
if let Some((icmpv6_type, icmpv6_code)) = translate_type_and_code_4_to_6(
|
|
||||||
IcmpType(original_payload_inner[0]),
|
|
||||||
IcmpCode(original_payload_inner[1]),
|
|
||||||
) {
|
|
||||||
let inner_icmpv6 = icmpv6_packet!(
|
|
||||||
new_source,
|
|
||||||
new_dest,
|
|
||||||
icmpv6_type,
|
|
||||||
icmpv6_code,
|
|
||||||
&original_payload_inner[4..]
|
|
||||||
);
|
|
||||||
original_payload_inner = inner_icmpv6.packet().to_vec();
|
|
||||||
log::debug!(
|
|
||||||
"Translated inner ICMPv6 packet: {:?}",
|
|
||||||
original_payload_inner
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build a new IPv6 packet out of the embedded IPv4 packet's data
|
|
||||||
let new_payload_packet = ipv6_packet!(
|
|
||||||
new_source,
|
|
||||||
new_dest,
|
|
||||||
match original_payload.get_next_level_protocol() {
|
|
||||||
IpNextHeaderProtocols::Icmp => IpNextHeaderProtocols::Icmpv6,
|
|
||||||
proto => proto,
|
|
||||||
},
|
|
||||||
original_payload.get_ttl(),
|
|
||||||
&original_payload_inner
|
|
||||||
);
|
|
||||||
|
|
||||||
// Set the payload
|
|
||||||
output_payload = vec![0u8; 4 + new_payload_packet.packet().len()];
|
|
||||||
output_payload[4..].copy_from_slice(new_payload_packet.packet());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a new ICMPv6 packet for the translated values to be stored in
|
|
||||||
let mut output = MutableIcmpv6Packet::owned(vec![
|
|
||||||
0u8;
|
|
||||||
Icmpv6Packet::minimum_packet_size()
|
|
||||||
+ output_payload.len()
|
|
||||||
])
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// Set the type and code
|
|
||||||
output.set_icmpv6_type(icmpv6_type);
|
|
||||||
output.set_icmpv6_code(icmpv6_code);
|
|
||||||
|
|
||||||
// Set the payload
|
|
||||||
log::debug!("Setting ICMPv6 payload: {:?}", output_payload);
|
|
||||||
output.set_payload(&output_payload);
|
|
||||||
|
|
||||||
// Calculate the checksum
|
|
||||||
output.set_checksum(0);
|
|
||||||
output.set_checksum(icmpv6::checksum(
|
|
||||||
&output.to_immutable(),
|
|
||||||
&new_source,
|
|
||||||
&new_dest,
|
|
||||||
));
|
|
||||||
|
|
||||||
// Return the translated packet
|
|
||||||
return Ok(Some(
|
|
||||||
Icmpv6Packet::owned(output.to_immutable().packet().to_vec()).unwrap(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(None)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Translate an ICMPv6 packet into an ICMP packet
|
|
||||||
pub fn translate_icmp_6_to_4(
|
|
||||||
icmpv6_packet: Icmpv6Packet,
|
|
||||||
new_source: Ipv4Addr,
|
|
||||||
new_dest: Ipv4Addr,
|
|
||||||
) -> Result<Option<IcmpPacket>, PacketTranslationError> {
|
|
||||||
// If the incoming packet is a "Parameter Problem", log it
|
|
||||||
if icmpv6_packet.get_icmpv6_type() == Icmpv6Types::ParameterProblem {
|
|
||||||
log::warn!(
|
|
||||||
"ICMPv6 Parameter Problem: {:?}",
|
|
||||||
match icmpv6_packet.get_icmpv6_code().0 {
|
|
||||||
0 => "Erroneous header field encountered",
|
|
||||||
1 => "Unrecognized Next Header type encountered",
|
|
||||||
2 => "Unrecognized IPv6 option encountered",
|
|
||||||
_ => "Unknown",
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Translate the type and code
|
|
||||||
if let Some((icmp_type, icmp_code)) = translate_type_and_code_6_to_4(
|
|
||||||
icmpv6_packet.get_icmpv6_type(),
|
|
||||||
icmpv6_packet.get_icmpv6_code(),
|
|
||||||
) {
|
|
||||||
// "Time Exceeded" requires an additional payload be embedded in the packet
|
|
||||||
// This payload looks like: 4bytes + IPv6(8bytes)
|
|
||||||
let mut output_payload = icmpv6_packet.payload().to_vec();
|
|
||||||
if icmp_type == IcmpTypes::TimeExceeded {
|
|
||||||
// Get access to the original payload
|
|
||||||
let original_payload =
|
|
||||||
Ipv6Packet::new(&icmpv6_packet.payload()[4..]).ok_or_else(|| {
|
|
||||||
PacketTranslationError::EmbeddedPacketTooShort(
|
|
||||||
icmpv6_packet.payload().len() - 4,
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
// Copy the original payload's payload to a buffer
|
|
||||||
let mut original_payload_inner = vec![0u8; original_payload.payload().len()];
|
|
||||||
original_payload_inner.copy_from_slice(original_payload.payload());
|
|
||||||
|
|
||||||
// if the original payload's next header is ICMPv6, we need to translated the inner payload's ICMPv6 type
|
|
||||||
if original_payload.get_next_header() == IpNextHeaderProtocols::Icmpv6 {
|
|
||||||
log::debug!("Time Exceeded packet contains another ICMPv6 packet.. Translating");
|
|
||||||
if let Some((icmp_type, icmp_code)) = translate_type_and_code_6_to_4(
|
|
||||||
Icmpv6Type(original_payload_inner[0]),
|
|
||||||
Icmpv6Code(original_payload_inner[1]),
|
|
||||||
) {
|
|
||||||
let inner_icmp =
|
|
||||||
icmp_packet!(icmp_type, icmp_code, &original_payload_inner[8..]);
|
|
||||||
original_payload_inner = inner_icmp.packet().to_vec();
|
|
||||||
log::debug!("Translated inner ICMP packet: {:?}", original_payload_inner);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build a new IPv6 packet out of the embedded IPv4 packet's data
|
|
||||||
let new_payload_packet = ipv4_packet!(
|
|
||||||
new_source,
|
|
||||||
new_dest,
|
|
||||||
match original_payload.get_next_header() {
|
|
||||||
IpNextHeaderProtocols::Icmpv6 => IpNextHeaderProtocols::Icmp,
|
|
||||||
proto => proto,
|
|
||||||
},
|
|
||||||
original_payload.get_hop_limit(),
|
|
||||||
&original_payload_inner[..std::cmp::min(8, original_payload_inner.len())]
|
|
||||||
);
|
|
||||||
|
|
||||||
// Set the payload
|
|
||||||
output_payload = vec![0u8; 4 + new_payload_packet.packet().len()];
|
|
||||||
output_payload[4..].copy_from_slice(new_payload_packet.packet());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a new ICMP packet for the translated values to be stored in
|
|
||||||
let mut output = MutableIcmpPacket::owned(vec![
|
|
||||||
0u8;
|
|
||||||
IcmpPacket::minimum_packet_size()
|
|
||||||
+ output_payload.len()
|
|
||||||
])
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// Set the type and code
|
|
||||||
output.set_icmp_type(icmp_type);
|
|
||||||
output.set_icmp_code(icmp_code);
|
|
||||||
|
|
||||||
// Calculate the checksum
|
|
||||||
output.set_checksum(0);
|
|
||||||
output.set_checksum(icmp::checksum(&output.to_immutable()));
|
|
||||||
|
|
||||||
// Set the payload
|
|
||||||
output.set_payload(&output_payload);
|
|
||||||
|
|
||||||
// Return the translated packet
|
|
||||||
return Ok(Some(
|
|
||||||
IcmpPacket::owned(output.to_immutable().packet().to_vec()).unwrap(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(None)
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
// //! Packet type translation functionality
|
|
||||||
|
|
||||||
// mod icmp;
|
|
||||||
// mod tcp;
|
|
||||||
// mod udp;
|
|
||||||
|
|
||||||
// pub use icmp::{translate_icmp_4_to_6, translate_icmp_6_to_4};
|
|
||||||
// // pub use tcp::{translate_tcp_4_to_6, translate_tcp_6_to_4};
|
|
||||||
// // pub use udp::{translate_udp_4_to_6, translate_udp_6_to_4};
|
|
||||||
|
|
||||||
// #[derive(Debug, thiserror::Error)]
|
|
||||||
// pub enum PacketTranslationError {
|
|
||||||
// #[error("Input packet too short. Got {0} bytes")]
|
|
||||||
// InputPacketTooShort(usize),
|
|
||||||
// #[error("Embedded packet too short. Got {0} bytes")]
|
|
||||||
// EmbeddedPacketTooShort(usize),
|
|
||||||
// }
|
|
@ -1,52 +0,0 @@
|
|||||||
// use std::net::{Ipv4Addr, Ipv6Addr};
|
|
||||||
|
|
||||||
// use pnet_packet::{
|
|
||||||
// tcp::{self, MutableTcpPacket, TcpPacket},
|
|
||||||
// Packet,
|
|
||||||
// };
|
|
||||||
|
|
||||||
// use super::PacketTranslationError;
|
|
||||||
|
|
||||||
// /// Translate an IPv4 TCP packet into an IPv6 TCP packet (aka: recalculate checksum)
|
|
||||||
// pub fn translate_tcp_4_to_6(
|
|
||||||
// ipv4_tcp: TcpPacket,
|
|
||||||
// new_source: Ipv6Addr,
|
|
||||||
// new_dest: Ipv6Addr,
|
|
||||||
// ) -> Result<TcpPacket, PacketTranslationError> {
|
|
||||||
// // Create a mutable clone of the IPv4 TCP packet, so it can be adapted for use in IPv6
|
|
||||||
// let mut ipv6_tcp = MutableTcpPacket::owned(ipv4_tcp.packet().to_vec())
|
|
||||||
// .ok_or_else(|| PacketTranslationError::InputPacketTooShort(ipv4_tcp.packet().len()))?;
|
|
||||||
|
|
||||||
// // Rewrite the checksum for use in an IPv6 packet
|
|
||||||
// ipv6_tcp.set_checksum(0);
|
|
||||||
// ipv6_tcp.set_checksum(tcp::ipv6_checksum(
|
|
||||||
// &ipv4_tcp.to_immutable(),
|
|
||||||
// &new_source,
|
|
||||||
// &new_dest,
|
|
||||||
// ));
|
|
||||||
|
|
||||||
// // Return the translated packet
|
|
||||||
// Ok(TcpPacket::owned(ipv6_tcp.packet().to_vec()).unwrap())
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Translate an IPv6 TCP packet into an IPv4 TCP packet (aka: recalculate checksum)
|
|
||||||
// pub fn translate_tcp_6_to_4(
|
|
||||||
// ipv6_tcp: TcpPacket,
|
|
||||||
// new_source: Ipv4Addr,
|
|
||||||
// new_dest: Ipv4Addr,
|
|
||||||
// ) -> Result<TcpPacket, PacketTranslationError> {
|
|
||||||
// // Create a mutable clone of the IPv6 TCP packet, so it can be adapted for use in IPv4
|
|
||||||
// let mut ipv4_tcp = MutableTcpPacket::owned(ipv6_tcp.packet().to_vec())
|
|
||||||
// .ok_or_else(|| PacketTranslationError::InputPacketTooShort(ipv6_tcp.packet().len()))?;
|
|
||||||
|
|
||||||
// // Rewrite the checksum for use in an IPv4 packet
|
|
||||||
// ipv4_tcp.set_checksum(0);
|
|
||||||
// ipv4_tcp.set_checksum(tcp::ipv4_checksum(
|
|
||||||
// &ipv6_tcp.to_immutable(),
|
|
||||||
// &new_source,
|
|
||||||
// &new_dest,
|
|
||||||
// ));
|
|
||||||
|
|
||||||
// // Return the translated packet
|
|
||||||
// Ok(TcpPacket::owned(ipv4_tcp.packet().to_vec()).unwrap())
|
|
||||||
// }
|
|
@ -1,117 +0,0 @@
|
|||||||
// use super::PacketTranslationError;
|
|
||||||
// use pnet_packet::{
|
|
||||||
// udp::{self, MutableUdpPacket, UdpPacket},
|
|
||||||
// Packet,
|
|
||||||
// };
|
|
||||||
// use std::net::{Ipv4Addr, Ipv6Addr};
|
|
||||||
|
|
||||||
// /// Translate an IPv4 UDP packet into an IPv6 UDP packet (aka: recalculate checksum)
|
|
||||||
// pub fn translate_udp_4_to_6(
|
|
||||||
// ipv4_udp: UdpPacket,
|
|
||||||
// new_source: Ipv6Addr,
|
|
||||||
// new_dest: Ipv6Addr,
|
|
||||||
// ) -> Result<UdpPacket, PacketTranslationError> {
|
|
||||||
// // Create a mutable clone of the IPv4 UDP packet, so it can be adapted for use in IPv6
|
|
||||||
// let mut ipv6_udp = MutableUdpPacket::owned(ipv4_udp.packet().to_vec())
|
|
||||||
// .ok_or_else(|| PacketTranslationError::InputPacketTooShort(ipv4_udp.packet().len()))?;
|
|
||||||
|
|
||||||
// // Rewrite the checksum for use in an IPv6 packet
|
|
||||||
// ipv6_udp.set_checksum(0);
|
|
||||||
// ipv6_udp.set_checksum(udp::ipv6_checksum(
|
|
||||||
// &ipv4_udp.to_immutable(),
|
|
||||||
// &new_source,
|
|
||||||
// &new_dest,
|
|
||||||
// ));
|
|
||||||
|
|
||||||
// // Return the translated packet
|
|
||||||
// Ok(UdpPacket::owned(ipv6_udp.packet().to_vec()).unwrap())
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Translate an IPv6 UDP packet into an IPv4 UDP packet (aka: recalculate checksum)
|
|
||||||
// pub fn translate_udp_6_to_4(
|
|
||||||
// ipv6_udp: UdpPacket,
|
|
||||||
// new_source: Ipv4Addr,
|
|
||||||
// new_dest: Ipv4Addr,
|
|
||||||
// ) -> Result<UdpPacket, PacketTranslationError> {
|
|
||||||
// // Create a mutable clone of the IPv6 UDP packet, so it can be adapted for use in IPv4
|
|
||||||
// let mut ipv4_udp = MutableUdpPacket::owned(ipv6_udp.packet().to_vec())
|
|
||||||
// .ok_or_else(|| PacketTranslationError::InputPacketTooShort(ipv6_udp.packet().len()))?;
|
|
||||||
|
|
||||||
// // Rewrite the checksum for use in an IPv4 packet
|
|
||||||
// ipv4_udp.set_checksum(0);
|
|
||||||
// ipv4_udp.set_checksum(udp::ipv4_checksum(
|
|
||||||
// &ipv6_udp.to_immutable(),
|
|
||||||
// &new_source,
|
|
||||||
// &new_dest,
|
|
||||||
// ));
|
|
||||||
|
|
||||||
// // Return the translated packet
|
|
||||||
// Ok(UdpPacket::owned(ipv4_udp.packet().to_vec()).unwrap())
|
|
||||||
// }
|
|
||||||
|
|
||||||
// #[cfg(test)]
|
|
||||||
// mod tests {
|
|
||||||
// use crate::into_udp;
|
|
||||||
|
|
||||||
// use super::*;
|
|
||||||
|
|
||||||
// #[test]
|
|
||||||
// fn test_udp_4_to_6() {
|
|
||||||
// // Build an example UDP packet
|
|
||||||
// let input = into_udp!(vec![
|
|
||||||
// 0, 255, // Source port
|
|
||||||
// 0, 128, // Destination port
|
|
||||||
// 0, 4, // Length
|
|
||||||
// 0, 0, // Checksum (doesn't matter)
|
|
||||||
// 1, 2, 3, 4 // Data
|
|
||||||
// ])
|
|
||||||
// .unwrap();
|
|
||||||
|
|
||||||
// // Translate to IPv6
|
|
||||||
// let output = translate_udp_4_to_6(
|
|
||||||
// input,
|
|
||||||
// "2001:db8::1".parse().unwrap(),
|
|
||||||
// "2001:db8::2".parse().unwrap(),
|
|
||||||
// );
|
|
||||||
|
|
||||||
// // Check the output
|
|
||||||
// assert!(output.is_ok());
|
|
||||||
// let output = output.unwrap();
|
|
||||||
|
|
||||||
// // Check the output's contents
|
|
||||||
// assert_eq!(output.get_source(), 255);
|
|
||||||
// assert_eq!(output.get_destination(), 128);
|
|
||||||
// assert_eq!(output.get_length(), 4);
|
|
||||||
// assert_eq!(output.payload(), &[1, 2, 3, 4]);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// #[test]
|
|
||||||
// fn test_udp_6_to_4() {
|
|
||||||
// // Build an example UDP packet
|
|
||||||
// let input = into_udp!(vec![
|
|
||||||
// 0, 255, // Source port
|
|
||||||
// 0, 128, // Destination port
|
|
||||||
// 0, 4, // Length
|
|
||||||
// 0, 0, // Checksum (doesn't matter)
|
|
||||||
// 1, 2, 3, 4 // Data
|
|
||||||
// ])
|
|
||||||
// .unwrap();
|
|
||||||
|
|
||||||
// // Translate to IPv4
|
|
||||||
// let output = translate_udp_6_to_4(
|
|
||||||
// input,
|
|
||||||
// "192.0.2.1".parse().unwrap(),
|
|
||||||
// "192.0.2.2".parse().unwrap(),
|
|
||||||
// );
|
|
||||||
|
|
||||||
// // Check the output
|
|
||||||
// assert!(output.is_ok());
|
|
||||||
// let output = output.unwrap();
|
|
||||||
|
|
||||||
// // Check the output's contents
|
|
||||||
// assert_eq!(output.get_source(), 255);
|
|
||||||
// assert_eq!(output.get_destination(), 128);
|
|
||||||
// assert_eq!(output.get_length(), 4);
|
|
||||||
// assert_eq!(output.payload(), &[1, 2, 3, 4]);
|
|
||||||
// }
|
|
||||||
// }
|
|
Loading…
x
Reference in New Issue
Block a user