xref: /webrtc/mdns/src/message/resource/opt.rs (revision ffe74184)
1 use super::*;
2 use crate::error::Result;
3 use crate::error::*;
4 use crate::message::packer::*;
5 
6 // An OPTResource is an OPT pseudo Resource record.
7 //
8 // The pseudo resource record is part of the extension mechanisms for DNS
9 // as defined in RFC 6891.
10 #[derive(Default, Debug, Clone, PartialEq, Eq)]
11 pub struct OptResource {
12     pub options: Vec<DnsOption>,
13 }
14 
15 // An Option represents a DNS message option within OPTResource.
16 //
17 // The message option is part of the extension mechanisms for DNS as
18 // defined in RFC 6891.
19 #[derive(Default, Debug, Clone, PartialEq, Eq)]
20 pub struct DnsOption {
21     pub code: u16, // option code
22     pub data: Vec<u8>,
23 }
24 
25 impl fmt::Display for DnsOption {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result26     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27         write!(
28             f,
29             "dnsmessage.Option{{Code: {}, Data: {:?}}}",
30             self.code, self.data
31         )
32     }
33 }
34 
35 impl fmt::Display for OptResource {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result36     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37         let s: Vec<String> = self.options.iter().map(|o| o.to_string()).collect();
38         write!(f, "dnsmessage.OPTResource{{options: {}}}", s.join(","))
39     }
40 }
41 
42 impl ResourceBody for OptResource {
real_type(&self) -> DnsType43     fn real_type(&self) -> DnsType {
44         DnsType::Opt
45     }
46 
pack( &self, mut msg: Vec<u8>, _compression: &mut Option<HashMap<String, usize>>, _compression_off: usize, ) -> Result<Vec<u8>>47     fn pack(
48         &self,
49         mut msg: Vec<u8>,
50         _compression: &mut Option<HashMap<String, usize>>,
51         _compression_off: usize,
52     ) -> Result<Vec<u8>> {
53         for opt in &self.options {
54             msg = pack_uint16(msg, opt.code);
55             msg = pack_uint16(msg, opt.data.len() as u16);
56             msg = pack_bytes(msg, &opt.data);
57         }
58         Ok(msg)
59     }
60 
unpack(&mut self, msg: &[u8], mut off: usize, length: usize) -> Result<usize>61     fn unpack(&mut self, msg: &[u8], mut off: usize, length: usize) -> Result<usize> {
62         let mut opts = vec![];
63         let old_off = off;
64         while off < old_off + length {
65             let (code, new_off) = unpack_uint16(msg, off)?;
66             off = new_off;
67 
68             let (l, new_off) = unpack_uint16(msg, off)?;
69             off = new_off;
70 
71             let mut opt = DnsOption {
72                 code,
73                 data: vec![0; l as usize],
74             };
75             if off + l as usize > msg.len() {
76                 return Err(Error::ErrCalcLen);
77             }
78             opt.data.copy_from_slice(&msg[off..off + l as usize]);
79             off += l as usize;
80             opts.push(opt);
81         }
82         self.options = opts;
83         Ok(off)
84     }
85 }
86