trust_dns_proto/rr/rdata/a.rs
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//! IPv4 address record data
18//!
19//! [RFC 1035, DOMAIN NAMES - IMPLEMENTATION AND SPECIFICATION, November 1987](https://tools.ietf.org/html/rfc1035)
20//!
21//! ```text
22//! 3.4. Internet specific RRs
23//!
24//! 3.4.1. A RDATA format
25//!
26//! +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
27//! | ADDRESS |
28//! +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
29//!
30//! where:
31//!
32//! ADDRESS A 32 bit Internet address.
33//!
34//! Hosts that have multiple Internet addresses will have multiple A
35//! records.
36//!
37//! A records cause no additional section processing. The RDATA section of
38//! an A line in a Zone File is an Internet address expressed as four
39//! decimal numbers separated by dots without any embedded spaces (e.g.,
40//! "10.2.0.52" or "192.0.5.6").
41//! ```
42
43use std::net::Ipv4Addr;
44
45use crate::error::*;
46use crate::serialize::binary::*;
47
48/// Read the RData from the given Decoder
49pub fn read(decoder: &mut BinDecoder<'_>) -> ProtoResult<Ipv4Addr> {
50 Ok(Ipv4Addr::new(
51 decoder.pop()?.unverified(/*valid as any u8*/),
52 decoder.pop()?.unverified(/*valid as any u8*/),
53 decoder.pop()?.unverified(/*valid as any u8*/),
54 decoder.pop()?.unverified(/*valid as any u8*/),
55 ))
56}
57
58/// Write the RData from the given Decoder
59pub fn emit(encoder: &mut BinEncoder<'_>, address: Ipv4Addr) -> ProtoResult<()> {
60 let segments = address.octets();
61
62 encoder.emit(segments[0])?;
63 encoder.emit(segments[1])?;
64 encoder.emit(segments[2])?;
65 encoder.emit(segments[3])?;
66 Ok(())
67}
68
69#[cfg(test)]
70mod mytests {
71 use std::net::Ipv4Addr;
72 use std::str::FromStr;
73
74 use super::*;
75 use crate::serialize::binary::bin_tests::{test_emit_data_set, test_read_data_set};
76
77 fn get_data() -> Vec<(Ipv4Addr, Vec<u8>)> {
78 vec![
79 (Ipv4Addr::from_str("0.0.0.0").unwrap(), vec![0, 0, 0, 0]), // base case
80 (Ipv4Addr::from_str("1.0.0.0").unwrap(), vec![1, 0, 0, 0]),
81 (Ipv4Addr::from_str("0.1.0.0").unwrap(), vec![0, 1, 0, 0]),
82 (Ipv4Addr::from_str("0.0.1.0").unwrap(), vec![0, 0, 1, 0]),
83 (Ipv4Addr::from_str("0.0.0.1").unwrap(), vec![0, 0, 0, 1]),
84 (Ipv4Addr::from_str("127.0.0.1").unwrap(), vec![127, 0, 0, 1]),
85 (
86 Ipv4Addr::from_str("192.168.64.32").unwrap(),
87 vec![192, 168, 64, 32],
88 ),
89 ]
90 }
91
92 #[test]
93 fn test_parse() {
94 test_read_data_set(get_data(), |ref mut d| read(d));
95 }
96
97 #[test]
98 fn test_write_to() {
99 test_emit_data_set(get_data(), |ref mut e, d| emit(e, d));
100 }
101}