pub fn build_ecs_option(client_ip: IpAddr, prefix_v4: u8, prefix_v6: u8) -> Vec<u8> {
    let mut option_data = Vec::new();

    match client_ip {
        IpAddr::V4(addr) => {
            // Family
            option_data.extend_from_slice(&FAMILY_IPV4.to_be_bytes());
            // Source prefix length
            option_data.push(prefix_v4);
            // Scope prefix length (0 = let resolver decide)
            option_data.push(0);
            // Address bytes (only send prefix bytes)
            let octets = addr.octets();
            let bytes_to_send = prefix_v4.div_ceil(8) as usize;
            option_data.extend_from_slice(&octets[..bytes_to_send.min(4)]);
        }
        IpAddr::V6(addr) => {
            // Family
            option_data.extend_from_slice(&FAMILY_IPV6.to_be_bytes());
            // Source prefix length
            option_data.push(prefix_v6);
            // Scope prefix length (0 = let resolver decide)
            option_data.push(0);
            // Address bytes (only send prefix bytes)
            let octets = addr.octets();
            let bytes_to_send = prefix_v6.div_ceil(8) as usize;
            option_data.extend_from_slice(&octets[..bytes_to_send.min(16)]);
        }
    }

    option_data
}
Build EDNS Client Subnet option data
src/libdoh/src/edns_ecs.rs