Selaa lähdekoodia

Support EUI64 records

Benjamin Sago 4 vuotta sitten
vanhempi
commit
a002db81fb
6 muutettua tiedostoa jossa 128 lisäystä ja 1 poistoa
  1. 1 1
      dns/src/record/eui48.rs
  2. 109 0
      dns/src/record/eui64.rs
  3. 6 0
      dns/src/record/mod.rs
  4. 2 0
      src/colours.rs
  5. 9 0
      src/output.rs
  6. 1 0
      src/table.rs

+ 1 - 1
dns/src/record/eui48.rs

@@ -22,7 +22,7 @@ impl Wire for EUI48 {
 
     #[cfg_attr(feature = "with_mutagen", ::mutagen::mutate)]
     fn read(stated_length: u16, c: &mut Cursor<&[u8]>) -> Result<Self, WireError> {
-        if stated_length !=  6 {
+        if stated_length != 6 {
             warn!("Length is incorrect (record length {:?}, but should be six)", stated_length);
             let mandated_length = MandatedLength::Exactly(6);
             return Err(WireError::WrongRecordLength { stated_length, mandated_length });

+ 109 - 0
dns/src/record/eui64.rs

@@ -0,0 +1,109 @@
+use log::*;
+
+use crate::wire::*;
+
+/// A **EUI64** record, which holds an eight-octet (64-bit) Extended Unique
+/// Identifier.
+///
+/// # References
+///
+/// - [RFC 7043](https://tools.ietf.org/html/rfc7043) — Resource Records for
+///   EUI-48 and EUI-64 Addresses in the DNS (October 2013)
+#[derive(PartialEq, Debug, Copy, Clone)]
+pub struct EUI64 {
+
+    /// The eight octets that make up the identifier.
+    pub octets: [u8; 8],
+}
+
+impl Wire for EUI64 {
+    const NAME: &'static str = "EUI64";
+    const RR_TYPE: u16 = 109;
+
+    #[cfg_attr(feature = "with_mutagen", ::mutagen::mutate)]
+    fn read(stated_length: u16, c: &mut Cursor<&[u8]>) -> Result<Self, WireError> {
+        if stated_length != 8 {
+            warn!("Length is incorrect (record length {:?}, but should be eight)", stated_length);
+            let mandated_length = MandatedLength::Exactly(8);
+            return Err(WireError::WrongRecordLength { stated_length, mandated_length });
+        }
+
+        let mut octets = [0_u8; 8];
+        c.read_exact(&mut octets)?;
+
+        Ok(Self { octets })
+    }
+}
+
+
+impl EUI64 {
+
+    /// Returns this EUI as hexadecimal numbers, separated by dashes.
+    pub fn formatted_address(&self) -> String {
+        format!("{:02x}-{:02x}-{:02x}-{:02x}-{:02x}-{:02x}-{:02x}-{:02x}",
+                self.octets[0], self.octets[1], self.octets[2], self.octets[3],
+                self.octets[4], self.octets[5], self.octets[6], self.octets[7])
+    }
+}
+
+
+#[cfg(test)]
+mod test {
+    use super::*;
+    use pretty_assertions::assert_eq;
+
+    #[test]
+    fn parses() {
+        let buf = &[
+            0x00, 0x7F, 0x23, 0x12, 0x34, 0x56, 0x78, 0x90,  // identifier
+        ];
+
+        assert_eq!(EUI64::read(buf.len() as _, &mut Cursor::new(buf)).unwrap(),
+                   EUI64 { octets: [ 0x00, 0x7F, 0x23, 0x12, 0x34, 0x56, 0x78, 0x90 ] });
+    }
+
+    #[test]
+    fn record_too_short() {
+        let buf = &[
+            0x00, 0x7F, 0x23,  // a mere OUI
+        ];
+
+        assert_eq!(EUI64::read(buf.len() as _, &mut Cursor::new(buf)),
+                   Err(WireError::WrongRecordLength { stated_length: 3, mandated_length: MandatedLength::Exactly(8) }));
+    }
+
+    #[test]
+    fn record_too_long() {
+        let buf = &[
+            0x00, 0x7F, 0x23, 0x12, 0x34, 0x56, 0x78, 0x90,  // identifier
+            0x01,  // an unexpected extra byte
+        ];
+
+        assert_eq!(EUI64::read(buf.len() as _, &mut Cursor::new(buf)),
+                   Err(WireError::WrongRecordLength { stated_length: 9, mandated_length: MandatedLength::Exactly(8) }));
+    }
+
+    #[test]
+    fn record_empty() {
+        assert_eq!(EUI64::read(0, &mut Cursor::new(&[])),
+                   Err(WireError::WrongRecordLength { stated_length: 0, mandated_length: MandatedLength::Exactly(8) }));
+    }
+
+    #[test]
+    fn buffer_ends_abruptly() {
+        let buf = &[
+            0x00, 0x7F, 0x23,  // a mere OUI
+        ];
+
+        assert_eq!(EUI64::read(8, &mut Cursor::new(buf)),
+                   Err(WireError::IO));
+    }
+
+    #[test]
+    fn hex_rep() {
+        let record = EUI64 { octets: [ 0x00, 0x7F, 0x23, 0x12, 0x34, 0x56, 0x78, 0x90 ] };
+
+        assert_eq!(record.formatted_address(),
+                   "00-7f-23-12-34-56-78-90");
+    }
+}

+ 6 - 0
dns/src/record/mod.rs

@@ -16,6 +16,9 @@ pub use self::cname::CNAME;
 mod eui48;
 pub use self::eui48::EUI48;
 
+mod eui64;
+pub use self::eui64::EUI64;
+
 mod hinfo;
 pub use self::hinfo::HINFO;
 
@@ -82,6 +85,9 @@ pub enum Record {
     /// An **EUI48** record.
     EUI48(EUI48),
 
+    /// An **EUI64** record.
+    EUI64(EUI64),
+
     /// A **HINFO** record.
     HINFO(HINFO),
 

+ 2 - 0
src/colours.rs

@@ -18,6 +18,7 @@ pub struct Colours {
     pub caa: Style,
     pub cname: Style,
     pub eui48: Style,
+    pub eui64: Style,
     pub hinfo: Style,
     pub loc: Style,
     pub mx: Style,
@@ -52,6 +53,7 @@ impl Colours {
             caa: Red.normal(),
             cname: Yellow.normal(),
             eui48: Yellow.normal(),
+            eui64: Yellow.bold(),
             hinfo: Yellow.normal(),
             loc: Yellow.normal(),
             mx: Cyan.normal(),

+ 9 - 0
src/output.rs

@@ -197,6 +197,9 @@ impl TextFormat {
             Record::EUI48(ref eui48) => {
                 format!("{:?}", eui48.formatted_address())
             }
+            Record::EUI64(ref eui64) => {
+                format!("{:?}", eui64.formatted_address())
+            }
             Record::HINFO(ref hinfo) => {
                 format!("{:?} {:?}", hinfo.cpu, hinfo.os)
             }
@@ -399,6 +402,12 @@ fn json_record(record: &Record) -> JsonValue {
                 "identifier": eui48.formatted_address(),
             })
         }
+        Record::EUI64(eui64) => {
+            json!({
+                "type": "EUI64",
+                "identifier": eui64.formatted_address(),
+            })
+        }
         Record::HINFO(hinfo) => {
             json!({
                 "type": "HINFO",

+ 1 - 0
src/table.rs

@@ -119,6 +119,7 @@ impl Table {
             Record::CAA(_)         => self.colours.caa.paint("CAA"),
             Record::CNAME(_)       => self.colours.cname.paint("CNAME"),
             Record::EUI48(_)       => self.colours.eui48.paint("EUI48"),
+            Record::EUI64(_)       => self.colours.eui64.paint("EUI64"),
             Record::HINFO(_)       => self.colours.hinfo.paint("HINFO"),
             Record::LOC(_)         => self.colours.loc.paint("LOC"),
             Record::MX(_)          => self.colours.mx.paint("MX"),