1 /*
2  * Copyright (C) 2015 Benjamin Fry <benjaminfry@me.com>
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 //! null record type, generally not used except as an internal tool for representing null data
18 
19 use crate::error::*;
20 use crate::serialize::binary::*;
21 
22 /// [RFC 1035, DOMAIN NAMES - IMPLEMENTATION AND SPECIFICATION, November 1987](https://tools.ietf.org/html/rfc1035)
23 ///
24 /// ```text
25 /// 3.3.10. NULL RDATA format (EXPERIMENTAL)
26 ///
27 ///     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
28 ///     /                  <anything>                   /
29 ///     /                                               /
30 ///     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
31 ///
32 /// Anything at all may be in the RDATA field so long as it is 65535 octets
33 /// or less.
34 ///
35 /// NULL records cause no additional section processing.  NULL RRs are not
36 /// allowed in master files.  NULLs are used as placeholders in some
37 /// experimental extensions of the DNS.
38 /// ```
39 #[derive(Default, Debug, PartialEq, Eq, Hash, Clone)]
40 pub struct NULL {
41     anything: Option<Vec<u8>>,
42 }
43 
44 impl NULL {
45     /// Construct a new NULL RData
new() -> NULL46     pub fn new() -> NULL {
47         Default::default()
48     }
49 
50     /// Constructs a new NULL RData with the associated data
with(anything: Vec<u8>) -> NULL51     pub fn with(anything: Vec<u8>) -> NULL {
52         NULL {
53             anything: Some(anything),
54         }
55     }
56 
57     /// Returns the buffer stored in the NULL
anything(&self) -> Option<&[u8]>58     pub fn anything(&self) -> Option<&[u8]> {
59         self.anything.as_ref().map(|bytes| &bytes[..])
60     }
61 }
62 
63 /// Read the RData from the given Decoder
read(decoder: &mut BinDecoder, rdata_length: Restrict<u16>) -> ProtoResult<NULL>64 pub fn read(decoder: &mut BinDecoder, rdata_length: Restrict<u16>) -> ProtoResult<NULL> {
65     let rdata_length = rdata_length.map(|u| u as usize).unverified(/*any u16 is valid*/);
66     if rdata_length > 0 {
67         let anything = decoder.read_vec(rdata_length)?.unverified(/*any byte array is good*/);
68         Ok(NULL::with(anything))
69     } else {
70         Ok(NULL::new())
71     }
72 }
73 
74 /// Write the RData from the given Decoder
emit(encoder: &mut BinEncoder, nil: &NULL) -> ProtoResult<()>75 pub fn emit(encoder: &mut BinEncoder, nil: &NULL) -> ProtoResult<()> {
76     if let Some(anything) = nil.anything() {
77         for b in anything.iter() {
78             encoder.emit(*b)?;
79         }
80     }
81 
82     Ok(())
83 }
84 
85 #[cfg(test)]
86 mod tests {
87     #![allow(clippy::dbg_macro, clippy::print_stdout)]
88 
89     use super::*;
90 
91     #[test]
test()92     pub fn test() {
93         let rdata = NULL::with(vec![0, 1, 2, 3, 4, 5, 6, 7]);
94 
95         let mut bytes = Vec::new();
96         let mut encoder: BinEncoder = BinEncoder::new(&mut bytes);
97         assert!(emit(&mut encoder, &rdata).is_ok());
98         let bytes = encoder.into_bytes();
99 
100         println!("bytes: {:?}", bytes);
101 
102         let mut decoder: BinDecoder = BinDecoder::new(bytes);
103         let restrict = Restrict::new(bytes.len() as u16);
104         let read_rdata = read(&mut decoder, restrict).expect("Decoding error");
105         assert_eq!(rdata, read_rdata);
106     }
107 }
108