default_net/
mac.rs

1use core::str::FromStr;
2use std::error;
3use std::fmt;
4
5#[cfg(feature = "serde")]
6use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
7
8/// Structure of MAC address
9#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, Default, Debug)]
10pub struct MacAddr(pub u8, pub u8, pub u8, pub u8, pub u8, pub u8);
11
12impl MacAddr {
13    /// Construct a new `MacAddr` instance.
14    pub fn new(a: u8, b: u8, c: u8, d: u8, e: u8, f: u8) -> MacAddr {
15        MacAddr(a, b, c, d, e, f)
16    }
17    /// Construct a new MacAddr instance from the given octets
18    pub fn from_octets(octets: [u8; 6]) -> MacAddr {
19        MacAddr(
20            octets[0], octets[1], octets[2], octets[3], octets[4], octets[5],
21        )
22    }
23    /// Returns an array of MAC address octets
24    pub fn octets(&self) -> [u8; 6] {
25        [self.0, self.1, self.2, self.3, self.4, self.5]
26    }
27    /// Return a formatted string of MAC address
28    pub fn address(&self) -> String {
29        format!(
30            "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
31            self.0, self.1, self.2, self.3, self.4, self.5
32        )
33    }
34    /// Construct an all-zero MacAddr instance
35    pub fn zero() -> MacAddr {
36        MacAddr(0, 0, 0, 0, 0, 0)
37    }
38    /// Construct a broadcast `MacAddr` instance.
39    pub fn broadcast() -> MacAddr {
40        MacAddr(0xff, 0xff, 0xff, 0xff, 0xff, 0xff)
41    }
42    /// Construct a new MacAddr instance from a colon-separated string of hex format
43    pub fn from_hex_format(hex_mac_addr: &str) -> MacAddr {
44        if hex_mac_addr.len() != 17 {
45            return MacAddr(0, 0, 0, 0, 0, 0);
46        }
47        let fields: Vec<&str> = hex_mac_addr.split(":").collect();
48        let o1: u8 = u8::from_str_radix(&fields[0], 0x10).unwrap_or(0);
49        let o2: u8 = u8::from_str_radix(&fields[1], 0x10).unwrap_or(0);
50        let o3: u8 = u8::from_str_radix(&fields[2], 0x10).unwrap_or(0);
51        let o4: u8 = u8::from_str_radix(&fields[3], 0x10).unwrap_or(0);
52        let o5: u8 = u8::from_str_radix(&fields[4], 0x10).unwrap_or(0);
53        let o6: u8 = u8::from_str_radix(&fields[5], 0x10).unwrap_or(0);
54        MacAddr(o1, o2, o3, o4, o5, o6)
55    }
56}
57
58impl std::fmt::Display for MacAddr {
59    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
60        let _ = write!(
61            f,
62            "{:<02x}:{:<02x}:{:<02x}:{:<02x}:{:<02x}:{:<02x}",
63            self.0, self.1, self.2, self.3, self.4, self.5
64        );
65        Ok(())
66    }
67}
68
69#[cfg(feature = "serde")]
70impl Serialize for MacAddr {
71    /// Serializes the MAC address.
72    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
73        if serializer.is_human_readable() {
74            serializer.collect_str(self)
75        } else {
76            serializer.serialize_bytes(&[self.0, self.1, self.2, self.3, self.4, self.5])
77        }
78    }
79}
80
81#[cfg(feature = "serde")]
82impl<'de> Deserialize<'de> for MacAddr {
83    /// Deserializes the MAC address.
84    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
85        struct MacAddrVisitor;
86        impl<'de> de::Visitor<'de> for MacAddrVisitor {
87            type Value = MacAddr;
88
89            fn visit_str<E: de::Error>(self, value: &str) -> Result<MacAddr, E> {
90                value.parse().map_err(|err| E::custom(err))
91            }
92
93            fn visit_bytes<E: de::Error>(self, v: &[u8]) -> Result<MacAddr, E> {
94                if v.len() == 6 {
95                    Ok(MacAddr::new(v[0], v[1], v[2], v[3], v[4], v[5]))
96                } else {
97                    Err(E::invalid_length(v.len(), &self))
98                }
99            }
100
101            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
102                write!(
103                    formatter,
104                    "either a string representation of a MAC address or 6-element byte array"
105                )
106            }
107        }
108
109        // Decide what hint to provide to the deserializer based on if it is human readable or not
110        if deserializer.is_human_readable() {
111            deserializer.deserialize_str(MacAddrVisitor)
112        } else {
113            deserializer.deserialize_bytes(MacAddrVisitor)
114        }
115    }
116}
117
118/// Represents an error which occurred whilst parsing a MAC address
119#[derive(Copy, Debug, PartialEq, Eq, Clone)]
120pub enum ParseMacAddrError {
121    /// The MAC address has too many components, eg. 00:11:22:33:44:55:66
122    TooManyComponents,
123    /// The MAC address has too few components, eg. 00:11
124    TooFewComponents,
125    /// One of the components contains an invalid value, eg. 00:GG:22:33:44:55
126    InvalidComponent,
127}
128
129impl error::Error for ParseMacAddrError {}
130
131impl ParseMacAddrError {
132    fn description(&self) -> &str {
133        match *self {
134            ParseMacAddrError::TooManyComponents => "Too many components in a MAC address string",
135            ParseMacAddrError::TooFewComponents => "Too few components in a MAC address string",
136            ParseMacAddrError::InvalidComponent => "Invalid component in a MAC address string",
137        }
138    }
139}
140
141impl fmt::Display for ParseMacAddrError {
142    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
143        write!(f, "{}", self.description())
144    }
145}
146
147impl FromStr for MacAddr {
148    type Err = ParseMacAddrError;
149    fn from_str(s: &str) -> Result<MacAddr, ParseMacAddrError> {
150        let mut parts = [0u8; 6];
151        let splits = s.split(':');
152        let mut i = 0;
153        for split in splits {
154            if i == 6 {
155                return Err(ParseMacAddrError::TooManyComponents);
156            }
157            match u8::from_str_radix(split, 16) {
158                Ok(b) if split.len() != 0 => parts[i] = b,
159                _ => return Err(ParseMacAddrError::InvalidComponent),
160            }
161            i += 1;
162        }
163
164        if i == 6 {
165            Ok(MacAddr(
166                parts[0], parts[1], parts[2], parts[3], parts[4], parts[5],
167            ))
168        } else {
169            Err(ParseMacAddrError::TooFewComponents)
170        }
171    }
172}