#[derive(Debug, Clone, Copy)]
pub enum TsiFeatures {
None,
HijackInet,
HijackUnix,
HijackAll,
}
impl TsiFeatures {
pub fn as_raw(self) -> u32 {
match self {
Self::None => 0,
Self::HijackInet => 1 << 0,
Self::HijackUnix => 1 << 1,
Self::HijackAll => (1 << 0) | (1 << 1),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn tsi_features_none_is_zero() {
assert_eq!(TsiFeatures::None.as_raw(), 0);
}
#[test]
fn tsi_features_hijack_inet_is_bit_0() {
assert_eq!(TsiFeatures::HijackInet.as_raw(), 1);
}
#[test]
fn tsi_features_hijack_unix_is_bit_1() {
assert_eq!(TsiFeatures::HijackUnix.as_raw(), 2);
}
#[test]
fn tsi_features_hijack_all_combines_both_bits() {
let raw = TsiFeatures::HijackAll.as_raw();
assert_eq!(raw, 3);
assert_eq!(
raw,
TsiFeatures::HijackInet.as_raw() | TsiFeatures::HijackUnix.as_raw()
);
}
#[test]
fn tsi_features_variants_are_distinct() {
let values: Vec<u32> = [
TsiFeatures::None,
TsiFeatures::HijackInet,
TsiFeatures::HijackUnix,
TsiFeatures::HijackAll,
]
.iter()
.map(|f| f.as_raw())
.collect();
for i in 0..values.len() {
for j in (i + 1)..values.len() {
assert_ne!(values[i], values[j], "variants {i} and {j} must differ");
}
}
}
}
pub mod network_features {
pub const NET_FEATURE_CSUM: u32 = 1 << 0; pub const NET_FEATURE_GUEST_CSUM: u32 = 1 << 1; pub const NET_FEATURE_GUEST_TSO4: u32 = 1 << 7; pub const NET_FEATURE_GUEST_UFO: u32 = 1 << 10; pub const NET_FEATURE_HOST_TSO4: u32 = 1 << 11; pub const NET_FEATURE_HOST_UFO: u32 = 1 << 14;
pub const NET_FLAG_VFKIT: u32 = 1 << 0;
}