webrtc_mdns/message/
header.rs

1use super::*;
2
3// Header is a representation of a DNS message header.
4#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
5pub 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
16impl fmt::Display for Header {
17    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
33impl Header {
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)]
58pub 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
69impl From<u8> for Section {
70    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
83impl fmt::Display for Section {
84    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)]
100pub 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
109impl HeaderInternal {
110    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.
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
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
153    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}