use std::net::IpAddr;
pub fn ip_to_bytes(ip: IpAddr) -> [u8; 16] {
match ip {
IpAddr::V4(ipv4) => {
let mut bytes = [0u8; 16];
bytes[10..12].copy_from_slice(&[0xFF; 2]); bytes[12..16].copy_from_slice(&ipv4.octets());
bytes
}
IpAddr::V6(ipv6) => ipv6.octets(),
}
}
pub fn bytes_to_ip(bytes: [u8; 16]) -> IpAddr {
if bytes[..10].iter().all(|&b| b == 0) && bytes[10..12] == [0xFF; 2] {
let mut ipv4_bytes = [0u8; 4];
ipv4_bytes.copy_from_slice(&bytes[12..16]);
IpAddr::V4(ipv4_bytes.into())
} else {
IpAddr::V6(bytes.into())
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::net::{Ipv4Addr, Ipv6Addr};
#[test]
fn test_ipv4_conversion() {
let ipv4 = IpAddr::V4(Ipv4Addr::new(192, 168, 1, 1));
let bytes = ip_to_bytes(ipv4);
assert_eq!(bytes_to_ip(bytes), ipv4);
}
#[test]
fn test_ipv6_conversion() {
let ipv6 = IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1));
let bytes = ip_to_bytes(ipv6);
assert_eq!(bytes_to_ip(bytes), ipv6);
}
}