1use nom::bytes::streaming::take;
2use nom::number::complete::be_u32;
3use nom::number::streaming::be_u16;
4
5use sawp_flags::{Flag, Flags};
6
7use crate::enums::{RecordClass, RecordType};
8use crate::rdata::RDataType;
9use crate::{custom_count, ErrorFlags, IResult, Name};
10
11#[cfg(feature = "ffi")]
12use sawp_ffi::GenerateFFI;
13
14const MAX_TXT_PARSES: usize = 32767;
17const OPT_RR_START: [u8; 3] = [0, 0, 41];
19
20#[cfg_attr(feature = "ffi", derive(GenerateFFI))]
22#[cfg_attr(feature = "ffi", sawp_ffi(prefix = "sawp_dns"))]
23#[derive(Debug, PartialEq, Eq)]
24pub struct Answer {
25 pub name: Vec<u8>,
26 #[cfg_attr(feature = "ffi", sawp_ffi(copy))]
27 pub rtype: RecordType,
28 pub rtype_raw: u16,
29 #[cfg_attr(feature = "ffi", sawp_ffi(copy))]
30 pub rclass: RecordClass,
31 pub rclass_raw: u16,
32 pub ttl: u32,
33 pub data: RDataType,
34}
35
36impl Answer {
37 fn parse<'a>(
38 input: &'a [u8],
39 reference_bytes: &'a [u8],
40 ) -> IResult<'a, (Answer, Flags<ErrorFlags>)> {
41 let (input, (name, mut error_flags)) = Name::parse(reference_bytes)(input)?;
42
43 let (input, working_rtype) = be_u16(input)?;
44 let rtype = RecordType::from_raw(working_rtype);
45 if rtype == RecordType::UNKNOWN {
46 error_flags |= ErrorFlags::UnknownRtype;
47 }
48
49 let (input, working_rclass) = be_u16(input)?;
50 let rclass = RecordClass::from_raw(working_rclass);
51 if rclass == RecordClass::UNKNOWN {
52 error_flags |= ErrorFlags::UnknownRclass;
53 }
54
55 let (input, ttl) = be_u32(input)?;
56
57 let mut answer: Answer = Answer {
58 name,
59 rtype,
60 rtype_raw: working_rtype,
61 rclass,
62 rclass_raw: working_rclass,
63 ttl,
64 data: RDataType::UNKNOWN(vec![]),
65 };
66
67 let (input, data_len) = be_u16(input)?;
68 let (rem, local_data) = take(data_len)(input)?;
69
70 let (mut local_data, (mut rdata, inner_error_flags)) =
72 RDataType::parse(local_data, reference_bytes, rtype)?;
73 error_flags |= inner_error_flags;
74
75 if let RDataType::TXT(ref mut current_rdata) = rdata {
77 for _ in 0..MAX_TXT_PARSES - 1 {
78 if local_data.is_empty() {
79 break;
80 }
81 let (new_data, (rdata, inner_error_flags)) =
82 RDataType::parse(local_data, reference_bytes, rtype)?;
83 error_flags |= inner_error_flags;
84 if let RDataType::TXT(new_rdata) = rdata {
85 current_rdata.extend(new_rdata);
86 local_data = new_data;
87 } else {
88 break;
89 }
90 }
91 }
92 answer.data = rdata;
93 Ok((rem, (answer, error_flags)))
94 }
95
96 fn parse_additional<'a>(
97 input: &'a [u8],
98 reference_bytes: &'a [u8],
99 ) -> IResult<'a, (Answer, Flags<ErrorFlags>, bool)> {
100 let mut opt_rr_present = false;
101 if input.len() >= 3 && input[0..3] == OPT_RR_START[0..3] {
102 let (input, (data, inner_error_flags)) = RDataType::parse_rdata_opt(&input[3..])?;
103 opt_rr_present = true;
104 Ok((
105 input,
106 (
107 Answer {
108 name: vec![0], rtype: RecordType::OPT,
110 rtype_raw: 41,
111 rclass: RecordClass::NONE, rclass_raw: 254,
113 ttl: 0, data,
115 },
116 inner_error_flags,
117 opt_rr_present,
118 ),
119 ))
120 } else {
121 let (input, (answer, inner_error_flags)) = Answer::parse(input, reference_bytes)?;
122 Ok((input, (answer, inner_error_flags, opt_rr_present)))
123 }
124 }
125
126 pub fn parse_additionals<'a>(
127 input: &'a [u8],
128 reference_bytes: &'a [u8],
129 acnt: usize,
130 ) -> IResult<'a, (Vec<Answer>, Flags<ErrorFlags>)> {
131 let mut opt_rr_present = false;
132 let mut error_flags = ErrorFlags::none();
133 let (input, answers) = custom_count(
134 |input, reference_bytes| {
135 let (input, (answer, inner_error_flags, inner_opt_rr_present)) =
136 Answer::parse_additional(input, reference_bytes)?;
137 if inner_opt_rr_present {
138 if opt_rr_present {
139 error_flags |= ErrorFlags::ExtraOptRr;
140 } else {
141 opt_rr_present = true;
142 }
143 }
144 error_flags |= inner_error_flags;
145 Ok((input, answer))
146 },
147 acnt,
148 )(input, reference_bytes)?;
149
150 Ok((input, (answers, error_flags)))
151 }
152
153 pub fn parse_answers<'a>(
154 input: &'a [u8],
155 reference_bytes: &'a [u8],
156 acnt: usize,
157 ) -> IResult<'a, (Vec<Answer>, Flags<ErrorFlags>)> {
158 let mut error_flags = ErrorFlags::none();
159 let (input, answers) = custom_count(
160 |input, reference_bytes| {
161 let (input, (answer, inner_error_flags)) = Answer::parse(input, reference_bytes)?;
162 error_flags |= inner_error_flags;
163 Ok((input, answer))
164 },
165 acnt,
166 )(input, reference_bytes)?;
167
168 Ok((input, (answers, error_flags)))
169 }
170}