xref: /webrtc/mdns/src/message/header.rs (revision 97921129)
1 use super::*;
2 
3 // Header is a representation of a DNS message header.
4 #[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
5 pub struct Header {
6     pub id: u16,
7     pub response: bool,
8     pub op_code: OpCode,
9     pub authoritative: bool,
10     pub truncated: bool,
11     pub recursion_desired: bool,
12     pub recursion_available: bool,
13     pub rcode: RCode,
14 }
15 
16 impl fmt::Display for Header {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result17     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18         write!(
19             f,
20             "dnsmessage.Header{{id: {}, response: {}, op_code: {}, authoritative: {}, truncated: {}, recursion_desired: {}, recursion_available: {}, rcode: {} }}",
21             self.id,
22             self.response,
23             self.op_code,
24             self.authoritative,
25             self.truncated,
26             self.recursion_desired,
27             self.recursion_available,
28             self.rcode
29         )
30     }
31 }
32 
33 impl Header {
pack(&self) -> (u16, u16)34     pub fn pack(&self) -> (u16, u16) {
35         let id = self.id;
36         let mut bits = self.op_code << 11 | self.rcode as u16;
37         if self.recursion_available {
38             bits |= HEADER_BIT_RA
39         }
40         if self.recursion_desired {
41             bits |= HEADER_BIT_RD
42         }
43         if self.truncated {
44             bits |= HEADER_BIT_TC
45         }
46         if self.authoritative {
47             bits |= HEADER_BIT_AA
48         }
49         if self.response {
50             bits |= HEADER_BIT_QR
51         }
52 
53         (id, bits)
54     }
55 }
56 
57 #[derive(Default, Copy, Clone, PartialOrd, PartialEq, Eq)]
58 pub enum Section {
59     #[default]
60     NotStarted = 0,
61     Header = 1,
62     Questions = 2,
63     Answers = 3,
64     Authorities = 4,
65     Additionals = 5,
66     Done = 6,
67 }
68 
69 impl From<u8> for Section {
from(v: u8) -> Self70     fn from(v: u8) -> Self {
71         match v {
72             0 => Section::NotStarted,
73             1 => Section::Header,
74             2 => Section::Questions,
75             3 => Section::Answers,
76             4 => Section::Authorities,
77             5 => Section::Additionals,
78             _ => Section::Done,
79         }
80     }
81 }
82 
83 impl fmt::Display for Section {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result84     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
85         let s = match *self {
86             Section::NotStarted => "NotStarted",
87             Section::Header => "Header",
88             Section::Questions => "question",
89             Section::Answers => "answer",
90             Section::Authorities => "authority",
91             Section::Additionals => "additional",
92             Section::Done => "Done",
93         };
94         write!(f, "{s}")
95     }
96 }
97 
98 // header is the wire format for a DNS message header.
99 #[derive(Default)]
100 pub struct HeaderInternal {
101     pub id: u16,
102     pub bits: u16,
103     pub questions: u16,
104     pub answers: u16,
105     pub authorities: u16,
106     pub additionals: u16,
107 }
108 
109 impl HeaderInternal {
count(&self, sec: Section) -> u16110     pub(crate) fn count(&self, sec: Section) -> u16 {
111         match sec {
112             Section::Questions => self.questions,
113             Section::Answers => self.answers,
114             Section::Authorities => self.authorities,
115             Section::Additionals => self.additionals,
116             _ => 0,
117         }
118     }
119 
120     // pack appends the wire format of the header to msg.
pack(&self, mut msg: Vec<u8>) -> Vec<u8>121     pub(crate) fn pack(&self, mut msg: Vec<u8>) -> Vec<u8> {
122         msg = pack_uint16(msg, self.id);
123         msg = pack_uint16(msg, self.bits);
124         msg = pack_uint16(msg, self.questions);
125         msg = pack_uint16(msg, self.answers);
126         msg = pack_uint16(msg, self.authorities);
127         msg = pack_uint16(msg, self.additionals);
128         msg
129     }
130 
unpack(&mut self, msg: &[u8], off: usize) -> Result<usize>131     pub(crate) fn unpack(&mut self, msg: &[u8], off: usize) -> Result<usize> {
132         let (id, off) = unpack_uint16(msg, off)?;
133         self.id = id;
134 
135         let (bits, off) = unpack_uint16(msg, off)?;
136         self.bits = bits;
137 
138         let (questions, off) = unpack_uint16(msg, off)?;
139         self.questions = questions;
140 
141         let (answers, off) = unpack_uint16(msg, off)?;
142         self.answers = answers;
143 
144         let (authorities, off) = unpack_uint16(msg, off)?;
145         self.authorities = authorities;
146 
147         let (additionals, off) = unpack_uint16(msg, off)?;
148         self.additionals = additionals;
149 
150         Ok(off)
151     }
152 
header(&self) -> Header153     pub(crate) fn header(&self) -> Header {
154         Header {
155             id: self.id,
156             response: (self.bits & HEADER_BIT_QR) != 0,
157             op_code: ((self.bits >> 11) & 0xF) as OpCode,
158             authoritative: (self.bits & HEADER_BIT_AA) != 0,
159             truncated: (self.bits & HEADER_BIT_TC) != 0,
160             recursion_desired: (self.bits & HEADER_BIT_RD) != 0,
161             recursion_available: (self.bits & HEADER_BIT_RA) != 0,
162             rcode: RCode::from((self.bits & 0xF) as u8),
163         }
164     }
165 }
166