naptr.rs 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. use log::*;
  2. use crate::strings::{Labels, ReadLabels};
  3. use crate::wire::*;
  4. /// A **NAPTR** _(naming authority pointer)_ record,
  5. #[derive(PartialEq, Debug)]
  6. pub struct NAPTR {
  7. /// The order in which NAPTR records must be processed.
  8. pub order: u16,
  9. /// The DDDS priority.
  10. pub preference: u16,
  11. /// A set of characters that control the rewriting and interpretation of
  12. /// the other fields.
  13. pub flags: String,
  14. /// The service parameters applicable to this delegation path.
  15. pub service: String,
  16. /// A regular expression that gets applied to a string in order to
  17. /// construct the next domain name to look up using the DDDS algorithm.
  18. pub regex: String,
  19. /// The replacement domain name as part of the DDDS algorithm.
  20. pub replacement: Labels,
  21. }
  22. impl Wire for NAPTR {
  23. const NAME: &'static str = "MX";
  24. const RR_TYPE: u16 = 35;
  25. #[cfg_attr(all(test, feature = "with_mutagen"), ::mutagen::mutate)]
  26. fn read(stated_length: u16, c: &mut Cursor<&[u8]>) -> Result<Self, WireError> {
  27. let order = c.read_u16::<BigEndian>()?;
  28. trace!("Parsed order -> {:?}", order);
  29. let preference = c.read_u16::<BigEndian>()?;
  30. trace!("Parsed preference -> {:?}", preference);
  31. let flags_length = c.read_u8()?;
  32. trace!("Parsed flags length -> {:?}", flags_length);
  33. let mut flags_buffer = Vec::with_capacity(flags_length.into());
  34. for _ in 0 .. flags_length {
  35. flags_buffer.push(c.read_u8()?);
  36. }
  37. let flags = String::from_utf8_lossy(&flags_buffer).to_string();
  38. trace!("Parsed flags -> {:?}", flags);
  39. let service_length = c.read_u8()?;
  40. trace!("Parsed service length -> {:?}", service_length);
  41. let mut service_buffer = Vec::with_capacity(service_length.into());
  42. for _ in 0 .. service_length {
  43. service_buffer.push(c.read_u8()?);
  44. }
  45. let service = String::from_utf8_lossy(&service_buffer).to_string();
  46. trace!("Parsed service -> {:?}", service);
  47. let regex_length = c.read_u8()?;
  48. trace!("Parsed regex length -> {:?}", regex_length);
  49. let mut regex_buffer = Vec::with_capacity(regex_length.into());
  50. for _ in 0 .. regex_length {
  51. regex_buffer.push(c.read_u8()?);
  52. }
  53. let regex = String::from_utf8_lossy(&regex_buffer).to_string();
  54. trace!("Parsed regex -> {:?}", regex);
  55. let (replacement, replacement_length) = c.read_labels()?;
  56. trace!("Parsed replacement -> {:?}", replacement);
  57. let length_after_labels = 2 + 2 +
  58. 1 + u16::from(flags_length) + 1 + u16::from(service_length) +
  59. 1 + u16::from(regex_length) + replacement_length;
  60. if stated_length == length_after_labels {
  61. Ok(Self { order, preference, flags, service, regex, replacement })
  62. }
  63. else {
  64. Err(WireError::WrongLabelLength { stated_length, length_after_labels })
  65. }
  66. }
  67. }