zond_engine/core/models/
mac.rs1use mac_oui::Oui;
14use std::fmt;
15use std::sync::OnceLock;
16
17#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
19pub struct MacAddr(pub [u8; 6]);
20
21impl MacAddr {
22 pub const fn new(a: u8, b: u8, c: u8, d: u8, e: u8, f: u8) -> Self {
24 Self([a, b, c, d, e, f])
25 }
26}
27
28impl From<[u8; 6]> for MacAddr {
29 fn from(octets: [u8; 6]) -> Self {
30 Self(octets)
31 }
32}
33
34impl fmt::Debug for MacAddr {
35 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36 write!(
37 f,
38 "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
39 self.0[0], self.0[1], self.0[2], self.0[3], self.0[4], self.0[5]
40 )
41 }
42}
43
44impl fmt::Display for MacAddr {
45 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46 write!(
47 f,
48 "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
49 self.0[0], self.0[1], self.0[2], self.0[3], self.0[4], self.0[5]
50 )
51 }
52}
53
54static OUI_DB: OnceLock<Oui> = OnceLock::new();
55
56fn get_oui_db() -> &'static Oui {
60 OUI_DB.get_or_init(|| Oui::default().expect("failed to load OUI database"))
61}
62
63pub fn vendor(mac: &MacAddr) -> Option<String> {
65 let db = get_oui_db();
66 let mac_str = mac.to_string();
67 match db.lookup_by_mac(&mac_str) {
68 Ok(Some(entry)) => Some(entry.company_name.clone()),
69 _ => None,
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use super::*;
76
77 #[test]
78 fn test_mac_display_and_debug() {
79 let mac = MacAddr::new(0x00, 0x1A, 0x2B, 0x3C, 0x4D, 0x5E);
80 assert_eq!(mac.to_string(), "00:1a:2b:3c:4d:5e");
81 assert_eq!(format!("{:?}", mac), "00:1a:2b:3c:4d:5e");
82 }
83
84 #[test]
85 fn test_mac_from_array() {
86 let arr = [0x11, 0x22, 0x33, 0x44, 0x55, 0x66];
87 let mac = MacAddr::from(arr);
88 assert_eq!(mac.0, arr);
89 }
90
91 #[test]
92 fn test_vendor_lookup() {
93 let mac = MacAddr::new(0x00, 0x0C, 0x29, 0xAB, 0xCD, 0xEF);
94 let vendor = vendor(&mac);
95 assert_eq!(vendor, Some("VMware, Inc".to_string()));
96 }
97
98 #[test]
99 fn test_unknown_vendor_lookup() {
100 let mac = MacAddr::new(0x02, 0x00, 0x00, 0x00, 0x00, 0x00); let vendor = vendor(&mac);
102 assert_eq!(vendor, None);
103 }
104}