Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
267 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// Copyright 2015-2021 Benjamin Fry <benjaminfry@me.com> | ||
// | ||
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or | ||
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or | ||
// http://opensource.org/licenses/MIT>, at your option. This file may not be | ||
// copied, modified, or distributed except according to those terms. | ||
|
||
//! HINFO record for storing host information | ||
|
||
use crate::error::*; | ||
use crate::rr::rdata::HINFO; | ||
|
||
/// Parse the RData from a set of Tokens | ||
/// | ||
/// ```text | ||
/// IN HINFO DEC-2060 TOPS20 | ||
/// IN HINFO VAX-11/780 UNIX | ||
/// ``` | ||
pub fn parse<'i, I: Iterator<Item = &'i str>>(mut tokens: I) -> ParseResult<HINFO> { | ||
let cpu = tokens | ||
.next() | ||
.ok_or_else(|| ParseError::from(ParseErrorKind::MissingToken("cpu".to_string()))) | ||
.map(ToString::to_string)?; | ||
let os = tokens | ||
.next() | ||
.ok_or_else(|| ParseError::from(ParseErrorKind::MissingToken("os".to_string()))) | ||
.map(ToString::to_string)?; | ||
Ok(HINFO::new(cpu, os)) | ||
} | ||
|
||
#[test] | ||
fn test_parsing() { | ||
// IN HINFO DEC-2060 TOPS20 | ||
|
||
assert_eq!( | ||
parse(vec!["DEC-2060", "TOPS20"].into_iter()) | ||
.expect("failed to parse NAPTR"), | ||
HINFO::new( | ||
"DEC-2060".to_string(), | ||
"TOPS20".to_string() | ||
), | ||
); | ||
} | ||
|
||
#[test] | ||
fn test_parsing_fails() { | ||
// IN HINFO DEC-2060 TOPS20 | ||
|
||
assert!(parse(vec!["DEC-2060"].into_iter()).is_err()); | ||
assert!(parse(vec![].into_iter()).is_err()); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,6 +22,7 @@ | |
pub mod a; | ||
pub mod aaaa; | ||
pub mod caa; | ||
pub mod hinfo; | ||
pub mod mx; | ||
pub mod name; | ||
pub mod naptr; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
// Copyright 2015-2021 Benjamin Fry <benjaminfry@me.com> | ||
// | ||
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or | ||
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or | ||
// http://opensource.org/licenses/MIT>, at your option. This file may not be | ||
// copied, modified, or distributed except according to those terms. | ||
|
||
//! HINFO record for storing host information | ||
|
||
use std::fmt; | ||
|
||
use crate::error::*; | ||
use crate::serialize::binary::*; | ||
|
||
/// [RFC 1035, DOMAIN NAMES - IMPLEMENTATION AND SPECIFICATION, November 1987][rfc1035] | ||
/// | ||
/// ```text | ||
/// 3.3.2. HINFO RDATA format | ||
/// | ||
/// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ||
/// / CPU / | ||
/// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ||
/// / OS / | ||
/// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ||
/// | ||
/// where: | ||
/// | ||
/// CPU A <character-string> which specifies the CPU type. | ||
/// | ||
/// OS A <character-string> which specifies the operating | ||
/// system type. | ||
/// | ||
/// Standard values for CPU and OS can be found in [RFC-1010]. | ||
/// | ||
/// HINFO records are used to acquire general information about a host. The | ||
/// main use is for protocols such as FTP that can use special procedures | ||
/// when talking between machines or operating systems of the same type. | ||
/// ``` | ||
/// | ||
/// [rfc1035]: https://tools.ietf.org/html/rfc1035 | ||
#[derive(Debug, PartialEq, Eq, Hash, Clone)] | ||
pub struct HINFO { | ||
cpu: Box<[u8]>, | ||
os: Box<[u8]>, | ||
} | ||
|
||
impl HINFO { | ||
pub fn new(cpu: String, os: String) -> HINFO { | ||
HINFO { | ||
cpu: cpu.into_bytes().into_boxed_slice(), | ||
os: os.into_bytes().into_boxed_slice(), | ||
} | ||
} | ||
|
||
pub fn from_bytes(cpu: Box<[u8]>, os: Box<[u8]>) -> HINFO { | ||
HINFO { cpu, os } | ||
} | ||
|
||
pub fn cpu(&self) -> &Box<[u8]> { | ||
&self.cpu | ||
} | ||
|
||
pub fn os(&self) -> &Box<[u8]> { | ||
&self.os | ||
} | ||
} | ||
|
||
/// Read the RData from the given Decoder | ||
pub fn read(decoder: &mut BinDecoder<'_>) -> ProtoResult<HINFO> { | ||
let cpu = decoder.read_character_data()? | ||
.unverified(/*any data should be validate in HINFO CPU usage*/) | ||
.to_vec() | ||
.into_boxed_slice(); | ||
let os = decoder.read_character_data()? | ||
.unverified(/*any data should be validate in HINFO OS usage*/) | ||
.to_vec() | ||
.into_boxed_slice(); | ||
|
||
Ok(HINFO { cpu, os }) | ||
} | ||
|
||
/// Write the RData from the given Decoder | ||
pub fn emit(encoder: &mut BinEncoder<'_>, hinfo: &HINFO) -> ProtoResult<()> { | ||
encoder.emit_character_data(&hinfo.cpu)?; | ||
encoder.emit_character_data(&hinfo.os)?; | ||
|
||
Ok(()) | ||
} | ||
|
||
/// [RFC 1033](https://tools.ietf.org/html/rfc1033), DOMAIN OPERATIONS GUIDE, November 1987 | ||
/// | ||
/// ```text | ||
/// HINFO (Host Info) | ||
/// | ||
/// <host> [<ttl>] [<class>] HINFO <hardware> <software> | ||
/// | ||
/// The HINFO record gives information about a particular host. The data | ||
/// is two strings separated by whitespace. The first string is a | ||
/// hardware description and the second is software. The hardware is | ||
/// usually a manufacturer name followed by a dash and model designation. | ||
/// The software string is usually the name of the operating system. | ||
/// | ||
/// Official HINFO types can be found in the latest Assigned Numbers RFC, | ||
/// the latest of which is RFC-1010. The Hardware type is called the | ||
/// Machine name and the Software type is called the System name. | ||
/// | ||
/// Some sample HINFO records: | ||
/// | ||
/// SRI-NIC.ARPA. HINFO DEC-2060 TOPS20 | ||
/// UCBARPA.Berkeley.EDU. HINFO VAX-11/780 UNIX | ||
/// ``` | ||
impl fmt::Display for HINFO { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { | ||
write!( | ||
f, | ||
"{cpu} {os}", | ||
cpu = &String::from_utf8_lossy(&self.cpu), | ||
os = &String::from_utf8_lossy(&self.os) | ||
)?; | ||
Ok(()) | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
#![allow(clippy::dbg_macro, clippy::print_stdout)] | ||
|
||
use super::*; | ||
|
||
#[test] | ||
pub fn test() { | ||
let rdata = HINFO::new("cpu".to_string(), "os".to_string()); | ||
|
||
let mut bytes = Vec::new(); | ||
let mut encoder: BinEncoder<'_> = BinEncoder::new(&mut bytes); | ||
assert!(emit(&mut encoder, &rdata).is_ok()); | ||
let bytes = encoder.into_bytes(); | ||
|
||
println!("bytes: {:?}", bytes); | ||
|
||
let mut decoder: BinDecoder<'_> = BinDecoder::new(bytes); | ||
let read_rdata = read(&mut decoder).expect("Decoding error"); | ||
assert_eq!(rdata, read_rdata); | ||
} | ||
|
||
#[test] | ||
fn test_binary() { | ||
let bin_data = vec![0, 1, 2, 3, 4, 5, 6, 7, 8]; | ||
let rdata = HINFO::from_bytes( | ||
b"cpu".to_vec().into_boxed_slice(), | ||
bin_data.into_boxed_slice(), | ||
); | ||
|
||
let mut bytes = Vec::new(); | ||
let mut encoder: BinEncoder<'_> = BinEncoder::new(&mut bytes); | ||
assert!(emit(&mut encoder, &rdata).is_ok()); | ||
let bytes = encoder.into_bytes(); | ||
|
||
println!("bytes: {:?}", bytes); | ||
|
||
let mut decoder: BinDecoder<'_> = BinDecoder::new(bytes); | ||
let read_rdata = read(&mut decoder).expect("Decoding error"); | ||
assert_eq!(rdata, read_rdata); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.