4
0
Benjamin Sago 4 жил өмнө
parent
commit
6033453bbc

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

@@ -22,6 +22,9 @@ pub use self::loc::LOC;
 mod mx;
 pub use self::mx::MX;
 
+mod naptr;
+pub use self::naptr::NAPTR;
+
 mod ns;
 pub use self::ns::NS;
 
@@ -76,6 +79,9 @@ pub enum Record {
     /// A **MX** record.
     MX(MX),
 
+    /// A **NAPTR** record.
+    NAPTR(NAPTR),
+
     /// A **NS** record.
     NS(NS),
 

+ 91 - 0
dns/src/record/naptr.rs

@@ -0,0 +1,91 @@
+use log::*;
+
+use crate::strings::{Labels, ReadLabels};
+use crate::wire::*;
+
+
+/// A **NAPTR** _(naming authority pointer)_ record,
+#[derive(PartialEq, Debug)]
+pub struct NAPTR {
+
+    /// The order in which NAPTR records must be processed.
+    pub order: u16,
+
+    /// The DDDS priority.
+    pub preference: u16,
+
+    /// A set of characters that control the rewriting and interpretation of
+    /// the other fields.
+    pub flags: String,
+
+    /// The service parameters applicable to this delegation path.
+    pub service: String,
+
+    /// A regular expression that gets applied to a string in order to
+    /// construct the next domain name to look up using the DDDS algorithm.
+    pub regex: String,
+
+    /// The replacement domain name as part of the DDDS algorithm.
+    pub replacement: Labels,
+}
+
+impl Wire for NAPTR {
+    const NAME: &'static str = "MX";
+    const RR_TYPE: u16 = 35;
+
+    #[cfg_attr(all(test, feature = "with_mutagen"), ::mutagen::mutate)]
+    fn read(stated_length: u16, c: &mut Cursor<&[u8]>) -> Result<Self, WireError> {
+        let order = c.read_u16::<BigEndian>()?;
+        trace!("Parsed order -> {:?}", order);
+
+        let preference = c.read_u16::<BigEndian>()?;
+        trace!("Parsed preference -> {:?}", preference);
+
+        let flags_length = c.read_u8()?;
+        trace!("Parsed flags length -> {:?}", flags_length);
+
+        let mut flags_buffer = Vec::with_capacity(flags_length.into());
+        for _ in 0 .. flags_length {
+            flags_buffer.push(c.read_u8()?);
+        }
+
+        let flags = String::from_utf8_lossy(&flags_buffer).to_string();
+        trace!("Parsed flags -> {:?}", flags);
+
+        let service_length = c.read_u8()?;
+        trace!("Parsed service length -> {:?}", service_length);
+
+        let mut service_buffer = Vec::with_capacity(service_length.into());
+        for _ in 0 .. service_length {
+            service_buffer.push(c.read_u8()?);
+        }
+
+        let service = String::from_utf8_lossy(&service_buffer).to_string();
+        trace!("Parsed service -> {:?}", service);
+
+        let regex_length = c.read_u8()?;
+        trace!("Parsed regex length -> {:?}", regex_length);
+
+        let mut regex_buffer = Vec::with_capacity(regex_length.into());
+        for _ in 0 .. regex_length {
+            regex_buffer.push(c.read_u8()?);
+        }
+
+        let regex = String::from_utf8_lossy(&regex_buffer).to_string();
+        trace!("Parsed regex -> {:?}", regex);
+
+        let (replacement, replacement_length) = c.read_labels()?;
+        trace!("Parsed replacement -> {:?}", replacement);
+
+        let length_after_labels = 2 + 2 +
+            1 + u16::from(flags_length) + 1 + u16::from(service_length) +
+            1 + u16::from(regex_length) + u16::from(replacement_length);
+
+        if stated_length == length_after_labels {
+            Ok(Self { order, preference, flags, service, regex, replacement })
+        }
+        else {
+            Err(WireError::WrongLabelLength { stated_length, length_after_labels })
+        }
+    }
+}

+ 2 - 0
dns/src/wire.rs

@@ -178,6 +178,7 @@ impl Record {
         try_record!(HINFO);
         try_record!(LOC);
         try_record!(MX);
+        try_record!(NAPTR);
         try_record!(NS);
         // OPT is handled separately
         try_record!(PTR);
@@ -240,6 +241,7 @@ pub fn find_qtype_number(record_type: &str) -> Option<TypeInt> {
     try_record!(HINFO);
     try_record!(LOC);
     try_record!(MX);
+    try_record!(NAPTR);
     try_record!(NS);
     // OPT is elsewhere
     try_record!(PTR);

+ 2 - 0
src/colours.rs

@@ -21,6 +21,7 @@ pub struct Colours {
     pub loc: Style,
     pub mx: Style,
     pub ns: Style,
+    pub naptr: Style,
     pub opt: Style,
     pub ptr: Style,
     pub sshfp: Style,
@@ -50,6 +51,7 @@ impl Colours {
             hinfo: Yellow.normal(),
             loc: Yellow.normal(),
             mx: Cyan.normal(),
+            naptr: Green.normal(),
             ns: Red.normal(),
             opt: Purple.normal(),
             ptr: Red.normal(),

+ 20 - 0
src/output.rs

@@ -210,6 +210,16 @@ impl TextFormat {
             Record::MX(ref mx) => {
                 format!("{} {:?}", mx.preference, mx.exchange.to_string())
             }
+            Record::NAPTR(ref naptr) => {
+                format!("{} {} {} {:?} /{}/ {:?}",
+                    naptr.order,
+                    naptr.preference,
+                    naptr.flags,
+                    naptr.service,
+                    naptr.regex,
+                    naptr.replacement.to_string(),
+                )
+            }
             Record::NS(ref ns) => {
                 format!("{:?}", ns.nameserver.to_string())
             }
@@ -402,6 +412,16 @@ fn json_record(record: &Record) -> JsonValue {
                 "exchange": rec.exchange.to_string(),
             })
         }
+        Record::NAPTR(rec) => {
+            json!({
+                "type": "NAPTR",
+                "order": rec.order,
+                "flags": rec.flags,
+                "service": rec.service,
+                "regex": rec.service,
+                "replacement": rec.replacement.to_string(),
+            })
+        }
         Record::NS(rec) => {
             json!({
                 "type": "NS",

+ 1 - 0
src/table.rs

@@ -121,6 +121,7 @@ impl Table {
             Record::HINFO(_)  => self.colours.hinfo.paint("HINFO"),
             Record::LOC(_)    => self.colours.loc.paint("LOC"),
             Record::MX(_)     => self.colours.mx.paint("MX"),
+            Record::NAPTR(_)  => self.colours.ns.paint("NAPTR"),
             Record::NS(_)     => self.colours.ns.paint("NS"),
             Record::PTR(_)    => self.colours.ptr.paint("PTR"),
             Record::SSHFP(_)  => self.colours.sshfp.paint("SSHFP"),