Skip to content

Commit

Permalink
added new OPT codes
Browse files Browse the repository at this point in the history
  • Loading branch information
dandyvica committed Nov 30, 2024
1 parent 2a61e98 commit 31ce220
Show file tree
Hide file tree
Showing 30 changed files with 426 additions and 240 deletions.
11 changes: 10 additions & 1 deletion src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::path::PathBuf;
use std::str::FromStr;
use std::time::Duration;

use clap::{error, Arg, ArgAction, Command};
use clap::{Arg, ArgAction, Command};
use http::*;
use log::{debug, trace};
use regex::Regex;
Expand Down Expand Up @@ -451,6 +451,14 @@ Caveat: all options starting with a dash (-) should be placed after optional [TY
.value_parser(clap::value_parser!(u16))
.help_heading("EDNS options")
)
.arg(
Arg::new("zoneversion")
.long("zoneversion")
.long_help("Sets the EDNS ZONEVERSION option in the OPT record.")
.long_help("Sets the EDNS NSID option in the OPT record.")
.action(ArgAction::SetTrue)
.help_heading("EDNS options")
)
//───────────────────────────────────────────────────────────────────────────────────
// Display options
//───────────────────────────────────────────────────────────────────────────────────
Expand Down Expand Up @@ -809,6 +817,7 @@ Caveat: all options starting with a dash (-) should be placed after optional [TY
options.edns.no_opt = matches.get_flag("no-opt");
options.edns.dnssec = matches.get_flag("dnssec");
options.edns.nsid = matches.get_flag("nsid");
options.edns.zoneversion = matches.get_flag("zoneversion");
options.edns.padding = matches.get_one::<u16>("padding").copied();

options.edns.dau = matches.get_many::<u8>("dau").map(|v| v.copied().collect::<Vec<u8>>());
Expand Down
35 changes: 22 additions & 13 deletions src/cli_options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ use log::trace;

use crate::args::CliOptions;
use crate::dns::rfc::domain::ROOT;
use crate::dns::rfc::opt::zoneversion::ZONEVERSION;
use crate::dns::rfc::{
domain::{DomainName, ROOT_DOMAIN},
opt::{
dau_dhu_n3u::{EdnsKeyTag, DAU, DHU, N3U},
//dau_dhu_n3u::{EdnsKeyTag, DAU, DHU, N3U},
nsid::NSID,
//opt_rr::OPT,
padding::Padding,
Expand Down Expand Up @@ -63,6 +64,9 @@ pub struct EdnsOptions {
// add NSID option if true
pub nsid: bool,

// add ZONEVERSION option if true
pub zoneversion: bool,

// padding if the form of +padding=20
pub padding: Option<u16>,

Expand Down Expand Up @@ -145,21 +149,26 @@ impl FromOptions<u16> for OPT {
opt.add_option(Padding::new(len));
}

// DAU, DHU & N3U
if let Some(list) = &edns.dau {
opt.add_option(DAU::from(list.as_slice()));
}
if let Some(list) = &edns.dhu {
opt.add_option(DHU::from(list.as_slice()));
}
if let Some(list) = &edns.n3u {
opt.add_option(N3U::from(list.as_slice()));
// ZONEVERSION
if edns.zoneversion {
opt.add_option(ZONEVERSION::default());
}

// DAU, DHU & N3U
// if let Some(list) = &edns.dau {
// opt.add_option(DAU::from(list.as_slice()));
// }
// if let Some(list) = &edns.dhu {
// opt.add_option(DHU::from(list.as_slice()));
// }
// if let Some(list) = &edns.n3u {
// opt.add_option(N3U::from(list.as_slice()));
// }

// edns-key-tag
if let Some(list) = &edns.keytag {
opt.add_option(EdnsKeyTag::from(list.as_slice()));
}
// if let Some(list) = &edns.keytag {
// opt.add_option(EdnsKeyTag::from(list.as_slice()));
// }

Some(opt)
}
Expand Down
9 changes: 7 additions & 2 deletions src/dns/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,24 @@ impl Buffer {
// }

// some RRs need to convert the raw data into b16 or b64 hexa strings
pub fn to_b64(&self) -> String {
pub fn to_base64(&self) -> String {
general_purpose::STANDARD.encode(self.as_ref())
}

// some RRs need to convert the raw data into b16 or b64 hexa strings
pub fn to_b16(&self) -> String {
pub fn to_base16(&self) -> String {
base16::encode_upper(&self.as_ref())
}

// useful for JSON output
pub fn to_hex(&self) -> String {
format!("{:?}", self)
}

// fancier display
pub fn display(&self) -> String {
format!("0x{:?} \"{}\"", self, self)
}
}

impl Deref for Buffer {
Expand Down
4 changes: 2 additions & 2 deletions src/dns/rfc/cert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ impl fmt::Display for CERT {
self.certificate_type,
self.key_tag,
self.algorithm,
self.certificate.to_b64()
self.certificate.to_base64()
)
}
}
Expand All @@ -77,7 +77,7 @@ impl Serialize for CERT {
seq.serialize_entry("flags", &self.certificate_type.to_string())?;
seq.serialize_entry("key_tag", &self.key_tag)?;
seq.serialize_entry("algorithm", &self.algorithm)?;
seq.serialize_entry("certificate", &self.certificate.to_b64())?;
seq.serialize_entry("certificate", &self.certificate.to_base64())?;
seq.end()
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/dns/rfc/dhcid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ new_rd_length!(DHCID);

impl fmt::Display for DHCID {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.data.to_b64())
write!(f, "{}", self.data.to_base64())
}
}

Expand All @@ -33,7 +33,7 @@ impl Serialize for DHCID {
where
S: Serializer,
{
serializer.serialize_str(&self.data.to_b64())
serializer.serialize_str(&self.data.to_base64())
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/dns/rfc/dnskey.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ impl fmt::Display for DNSKEY {
self.flags,
self.protocol,
self.algorithm,
self.key.to_b64()
self.key.to_base64()
)
}
}
Expand All @@ -97,7 +97,7 @@ impl Serialize for DNSKEY {
seq.serialize_entry("flags", &self.flags)?;
seq.serialize_entry("protocol", &self.protocol)?;
seq.serialize_entry("algorithm", &self.algorithm.to_string())?;
seq.serialize_entry("key", &self.key.to_b64())?;
seq.serialize_entry("key", &self.key.to_base64())?;
seq.end()
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/dns/rfc/ds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ impl Serialize for DS {
seq.serialize_entry("key_tag", &self.key_tag)?;
seq.serialize_entry("algorithm", &self.algorithm.to_string())?;
seq.serialize_entry("digest_type", &self.digest_type)?;
seq.serialize_entry("digest", &self.digest.to_b64())?;
seq.serialize_entry("digest", &self.digest.to_base64())?;
seq.end()
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/dns/rfc/hip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ impl fmt::Display for HIP {
f,
"{} {} {}",
self.pk_algorithm,
self.hit.to_b16(),
self.public_key.to_b64()
self.hit.to_base16(),
self.public_key.to_base64()
)
}
}
Expand All @@ -74,8 +74,8 @@ impl Serialize for HIP {
{
let mut seq = serializer.serialize_map(Some(3))?;
seq.serialize_entry("pk_algorithm", &self.pk_algorithm)?;
seq.serialize_entry("hit", &self.hit.to_b16())?;
seq.serialize_entry("public_key", &self.public_key.to_b64())?;
seq.serialize_entry("hit", &self.hit.to_base16())?;
seq.serialize_entry("public_key", &self.public_key.to_base64())?;
seq.end()
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/dns/rfc/ipseckey.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ impl fmt::Display for IPSECKEY {
self.gateway_type,
self.algorithm,
self.gateway,
self.public_key.to_b64()
self.public_key.to_base64()
)
}
}
Expand All @@ -100,7 +100,7 @@ impl Serialize for IPSECKEY {
seq.serialize_entry("gateway_type", &self.gateway_type)?;
seq.serialize_entry("algorithm", &self.algorithm)?;
seq.serialize_entry("gateway", &self.gateway.to_string())?;
seq.serialize_entry("public_key", &self.public_key.to_b64())?;
seq.serialize_entry("public_key", &self.public_key.to_base64())?;
seq.end()
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/dns/rfc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ pub mod query;
pub mod rdata;
pub mod response;
pub mod rp;
pub mod rrset;
pub mod rrlist;
pub mod rrsig;
pub mod soa;
pub mod srv;
Expand Down
2 changes: 1 addition & 1 deletion src/dns/rfc/nsec3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use serde::Serialize;

use crate::{
dns::buffer::{serialize_buffer, Buffer},
error::{Dns, Error},
// error::{Dns, Error},
new_rd_length,
};

Expand Down
4 changes: 2 additions & 2 deletions src/dns/rfc/openpgpkey.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ new_rd_length!(OPENPGPKEY);

impl fmt::Display for OPENPGPKEY {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.key.to_b64())
write!(f, "{}", self.key.to_base64())
}
}

Expand All @@ -35,7 +35,7 @@ impl Serialize for OPENPGPKEY {
where
S: Serializer,
{
serializer.serialize_str(&self.key.to_b64())
serializer.serialize_str(&self.key.to_base64())
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/dns/rfc/opt/cookie.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use type2network_derive::ToNetwork;

use serde::Serialize;

// Cookie: https://www.rfc-editor.org/rfc/rfc5001.html
// Cookie: https://www.rfc-editor.org/rfc/rfc7873
#[derive(Debug, Default, ToNetwork, Serialize)]
pub struct COOKIE {
client_cookie: Vec<u8>,
Expand Down
4 changes: 2 additions & 2 deletions src/dns/rfc/opt/dau_dhu_n3u.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use serde::Serialize;
use crate::{opt_code, opt_data};

use super::{
opt_rr::{OptionCode, OptOptionData},
OptionData,
opt_rr::{OptionData, OptionCode},
OptionDataValue,
};

// useful macro to auto define DAU, DHU & N3U which are the same
Expand Down
50 changes: 47 additions & 3 deletions src/dns/rfc/opt/extended.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,57 @@
use type2network::{FromNetworkOrder, ToNetworkOrder};
use type2network_derive::{FromNetwork, ToNetwork};
use std::fmt;

use type2network::ToNetworkOrder;
use type2network_derive::ToNetwork;

use serde::Serialize;

use crate::dns::buffer::Buffer;

// https://www.rfc-editor.org/rfc/rfc7871
#[derive(Debug, Default, ToNetwork, FromNetwork, Serialize)]
#[derive(Debug, Default, ToNetwork, Serialize)]
pub struct Extended {
pub(super) info_code: u16,
pub(super) extra_text: Buffer,
}

impl From<(u16, Buffer)> for Extended {
fn from(x: (u16, Buffer)) -> Self {
Self {
info_code: x.0,
extra_text: x.1,
}
}
}

impl fmt::Display for Extended {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.info_code {
1 => write!(f, "Other"),
2 => write!(f, "Unsupported DNSKEY Algorithm"),
3 => write!(f, "Unsupported DS Digest Type"),
4 => write!(f, "Stale Answer"),
5 => write!(f, "Forged Answer"),
6 => write!(f, "DNSSEC Indeterminate"),
7 => write!(f, "DNSSEC Bogus"),
8 => write!(f, "Signature Expired"),
9 => write!(f, "Signature Not Yet Valid"),
10 => write!(f, "DNSKEY Missing"),
11 => write!(f, "RRSIGs Missing"),
12 => write!(f, "No Zone Key Bit Set"),
13 => write!(f, "NSEC Missing"),
14 => write!(f, "Cached Error"),
15 => write!(f, "Not Ready"),
16 => write!(f, "Blocked"),
17 => write!(f, "Censored"),
18 => write!(f, "Filtered"),
19 => write!(f, "Prohibited"),
20 => write!(f, "Stale NXDOMAIN Answer"),
21 => write!(f, "Not Authoritative"),
22 => write!(f, "Not Supported"),
23 => write!(f, "No Reachable Authority"),
24 => write!(f, "Network Error"),
25 => write!(f, "Invalid Data"),
_ => write!(f, "extended code {} not yet assigned", self.info_code),
}
}
}
22 changes: 14 additions & 8 deletions src/dns/rfc/opt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,19 @@
// 65001-65534 Reserved for Local/Experimental Use [RFC6891]
// 65535 Reserved for future expansion [RFC6891]

use self::opt_rr::{OptionCode, OptOptionData};
use self::opt_rr::{OptionCode, OptionData};

pub mod client_subnet;
pub mod cookie;
pub mod dau_dhu_n3u;
//pub mod dau_dhu_n3u;
pub mod extended;
pub mod nsid;
pub mod opt_rr;
pub mod padding;
pub mod report_chanel;
pub mod zoneversion;

pub trait OptionData {
pub trait OptionDataValue {
// return the option code for the option data
fn code(&self) -> OptionCode;

Expand All @@ -36,13 +38,12 @@ pub trait OptionData {
}

// return the option data enum arm
fn data(self) -> OptOptionData;
fn data(self) -> Option<OptionData>;
}

// macro helpers to define code() et data() easily
#[macro_export]
macro_rules! opt_code {
// to deserialize "simple" structs (like A)
($opt:ident) => {
fn code(&self) -> OptionCode {
OptionCode::$opt
Expand All @@ -52,10 +53,15 @@ macro_rules! opt_code {

#[macro_export]
macro_rules! opt_data {
// to deserialize "simple" structs (like A)
($opt:ident) => {
fn data(self) -> OptOptionData {
OptOptionData::$opt(self)
fn data(self) -> Option<OptionData> {
Some(OptionData::$opt(self))
}
};

() => {
fn data(self) -> Option<OptionData> {
None
}
};
}
Loading

0 comments on commit 31ce220

Please sign in to comment.