dnsparse/
name.rs

1use core::fmt;
2use core::str;
3
4use crate::Error;
5
6/// A DNS name.
7#[derive(Debug, Clone)]
8pub struct Name<'a> {
9  pub(crate) buf: &'a [u8],
10  pub(crate) start: usize,
11}
12
13impl<'a> Name<'a> {
14  #[cfg(test)]
15  pub(crate) fn from_bytes(bytes: &'a [u8]) -> Self {
16    Self { buf: bytes, start: 0 }
17  }
18
19  pub(crate) fn create_pointer(&self, sub_name: &Name<'_>) -> Option<[u8; 2]> {
20    let mut labels = self.labels();
21
22    loop {
23      let i = labels.buf_i;
24
25      if labels.next().is_some() {
26        if self.equal_from(i, sub_name) {
27          let [ptr_1, ptr_2] = (i as u16).to_be_bytes();
28          return Some([ptr_1 | PTR_MASK, ptr_2]);
29        }
30
31        continue;
32      }
33
34      break;
35    }
36
37    None
38  }
39
40  fn equal_from(&self, i: usize, sub_name: &Name<'_>) -> bool {
41    let mut this = Labels { buf: self.buf, buf_i: i };
42    let mut other = sub_name.labels();
43
44    loop {
45      match (this.next(), other.next()) {
46        (Some(t), Some(o)) => if !t.as_str().eq_ignore_ascii_case(o.as_str()) {
47          break;
48        },
49        (None, None) => return true,
50        _ => break,
51      }
52    }
53
54    false
55  }
56
57  pub(crate) fn read(buf: &'a [u8], i: &'_ mut usize) -> Result<Self, Error> {
58    let mut j = *i;
59    let mut maximum = *i;
60    let mut ptr = None;
61
62    let mut len: u8 = 0;
63
64    loop {
65      match LabelType::read(buf, ptr.as_mut().unwrap_or(&mut j))? {
66        LabelType::Pointer(p) => {
67          let p = p as usize;
68
69          // Pointers can only point to previous occurences.
70          if p >= maximum {
71            return Err(Error::Pointer)
72          }
73
74          maximum = p;
75          ptr = Some(p);
76        },
77        LabelType::Part(part_len) => {
78          if part_len == 0 {
79            let name = Name {
80              buf,
81              start: *i,
82            };
83
84            *i = j;
85            return Ok(name)
86          }
87
88          // Stop if maximum name length of 255 bytes is reached.
89          if let Some(l) = len.checked_add(part_len) {
90            len = l;
91          } else {
92            return Err(Error::NameTooLong)
93          };
94        },
95      }
96    }
97  }
98
99  pub(crate) fn split(&self) -> (Label<'a>, Option<Name<'a>>) {
100    let mut labels = self.labels();
101
102    let label = labels.next().unwrap();
103    let name = labels.next().map(|l| Name { buf: l.buf, start: l.buf_i });
104
105    (label, name)
106  }
107
108  pub(crate) fn labels(&self) -> Labels<'a> {
109    Labels {
110      buf: self.buf,
111      buf_i: self.start,
112    }
113  }
114}
115
116impl fmt::Display for Name<'_> {
117  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
118    let mut print_dot = false;
119
120    for label in self.labels() {
121      if print_dot {
122        '.'.fmt(f)?;
123      }
124
125      label.as_str().fmt(f)?;
126
127      print_dot = true;
128    }
129
130    Ok(())
131  }
132}
133
134impl PartialEq<str> for Name<'_> {
135  fn eq(&self, other: &str) -> bool {
136    let mut other_i = 0;
137
138    let other = other.as_bytes();
139
140    for label in self.labels() {
141      if other_i != 0 {
142        if other.get(other_i) != Some(&b'.') {
143          return false
144        } else {
145          other_i += 1;
146        }
147      }
148
149      if let Some(substring) = other.get(other_i..(other_i + label.len())) {
150        if !label.as_bytes().eq_ignore_ascii_case(substring) {
151          return false
152        }
153      } else {
154        return false
155      }
156
157      other_i += label.len();
158    }
159
160    other_i == other.len()
161  }
162}
163
164#[derive(Debug, Clone)]
165pub(crate) struct Labels<'a> {
166  buf: &'a [u8],
167  buf_i: usize,
168}
169
170impl<'a> Iterator for Labels<'a> {
171  type Item = Label<'a>;
172
173  fn next(&mut self) -> Option<Self::Item> {
174    loop {
175      match LabelType::read(self.buf, &mut self.buf_i).ok()? {
176        LabelType::Pointer(ptr) => {
177          self.buf_i = ptr as usize;
178          continue;
179        },
180        LabelType::Part(len) => {
181          if len == 0 {
182            return None
183          }
184
185          let label = Label {
186            buf: self.buf,
187            buf_i: self.buf_i - len as usize - 1,
188          };
189
190          return Some(label)
191        },
192      }
193    }
194  }
195}
196
197#[derive(Debug)]
198pub(crate) struct Label<'a> {
199  pub(crate) buf: &'a [u8],
200  pub(crate) buf_i: usize,
201}
202
203impl<'a> Label<'a> {
204  #[inline]
205  pub fn as_bytes(&self) -> &[u8] {
206    &self.buf[(self.buf_i + 1)..(self.buf_i + 1 + self.len())]
207  }
208
209  #[inline]
210  pub fn as_str(&self) -> &str {
211    unsafe { str::from_utf8_unchecked(self.as_bytes()) }
212  }
213
214  #[inline]
215  pub fn len(&self) -> usize {
216    self.buf[self.buf_i] as usize
217  }
218}
219
220#[derive(Debug)]
221pub(crate) enum LabelType {
222  Pointer(u16),
223  Part(u8),
224}
225
226const PTR_MASK: u8 = 0b11000000;
227const LEN_MASK: u8 = !PTR_MASK;
228
229impl LabelType {
230  /// Return whether a label was read and whether it was a pointer or a normal name part.
231  pub(crate) fn read(buf: &[u8], i: &mut usize) -> Result<Self, Error> {
232    if let Some(&ptr_or_len) = buf.get(*i) {
233      // Check for pointer:
234      // https://tools.ietf.org/rfc/rfc1035#section-4.1.4
235      if ptr_or_len & PTR_MASK == PTR_MASK {
236        if let Some(&ptr) = buf.get(*i + 1) {
237          *i += 1 + 1;
238          return Ok(Self::Pointer(u16::from_be_bytes([ptr_or_len & LEN_MASK, ptr])))
239        }
240      } else {
241        let len = ptr_or_len & LEN_MASK;
242
243        let j = *i + 1 + len as usize;
244        if j <= buf.len() {
245          *i = j;
246          return Ok(Self::Part(len))
247        }
248      }
249    }
250
251    Err(Error::MessageTooShort)
252  }
253}
254
255#[cfg(test)]
256mod tests {
257  use super::*;
258
259  #[test]
260  fn test_name_create_pointer() {
261    let name = Name::from_bytes(&[1, b'a', 1, b'b', 1, b'c', 0]);
262    let name_uppercase = Name::from_bytes(&[1, b'A', 1, b'B', 1, b'C', 0]);
263    let sub_name = Name::from_bytes(&[1, b'b', 1, b'c', 0]);
264    let sub_sub_name = Name::from_bytes(&[1, b'c', 0]);
265
266    assert_eq!(name.create_pointer(&name), Some([0b11000000, 0]));
267    assert_eq!(name_uppercase.create_pointer(&name), Some([0b11000000, 0]));
268    assert_eq!(name.create_pointer(&name_uppercase), Some([0b11000000, 0]));
269    assert_eq!(name.create_pointer(&sub_name), Some([0b11000000, 2]));
270    assert_eq!(sub_name.create_pointer(&name), None);
271    assert_eq!(sub_name.create_pointer(&sub_sub_name), Some([0b11000000, 2]));
272    assert_eq!(name.create_pointer(&sub_sub_name), Some([0b11000000, 4]));
273    assert_eq!(sub_sub_name.create_pointer(&name), None);
274    assert_eq!(sub_sub_name.create_pointer(&sub_name), None);
275  }
276}