use super::*;
const ICMP_TIMESTAMP_BODY_LEN: usize = 12;
const ICMP_ADDRESS_MASK_BODY_LEN: usize = 4;
const ICMP_ROUTER_ADVERTISEMENT_ENTRY_LEN: usize = 8;
#[derive(Debug, Clone)]
pub struct Icmpv4QuotedIp {
pub(crate) datagram: Packet,
}
#[deprecated(since = "2.1.0", note = "renamed to Icmpv4QuotedIp")]
pub type IcmpQuotedIpv4 = Icmpv4QuotedIp;
impl Icmpv4QuotedIp {
pub fn new(datagram: impl IntoPacket) -> Self {
Self {
datagram: datagram.into_packet(),
}
}
pub fn datagram(&self) -> &Packet {
&self.datagram
}
pub fn datagram_mut(&mut self) -> &mut Packet {
&mut self.datagram
}
pub fn quoted_layer<T>(&self) -> Option<&T>
where
T: Layer,
{
self.datagram.layer::<T>()
}
}
impl PartialEq for Icmpv4QuotedIp {
fn eq(&self, other: &Self) -> bool {
match (self.datagram.compile(), other.datagram.compile()) {
(Ok(left), Ok(right)) => left.as_bytes() == right.as_bytes(),
_ => false,
}
}
}
impl Layer for Icmpv4QuotedIp {
fn name(&self) -> &'static str {
"IcmpQuotedIpv4"
}
fn summary(&self) -> String {
format!("IcmpQuotedIpv4({})", self.datagram.summary())
}
fn inspection_fields(&self) -> Vec<(&'static str, String)> {
vec![
("quoted_len", self.datagram.encoded_len().to_string()),
("quoted", self.datagram.summary()),
]
}
fn encoded_len(&self) -> usize {
self.datagram.encoded_len()
}
fn compile(&self, _ctx: &LayerContext<'_>, out: &mut Vec<u8>) -> Result<()> {
self.datagram.compile_into(out)
}
impl_layer_object!(Icmpv4QuotedIp);
}
impl_layer_div!(Icmpv4QuotedIp);
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Icmpv4Timestamp {
pub(crate) originate: Field<u32>,
pub(crate) receive: Field<u32>,
pub(crate) transmit: Field<u32>,
}
#[deprecated(since = "2.1.0", note = "renamed to Icmpv4Timestamp")]
pub type IcmpTimestamp = Icmpv4Timestamp;
impl Icmpv4Timestamp {
pub fn new() -> Self {
Self {
originate: Field::defaulted(0),
receive: Field::defaulted(0),
transmit: Field::defaulted(0),
}
}
pub fn originate(mut self, originate: u32) -> Self {
self.originate.set_user(originate);
self
}
pub fn receive(mut self, receive: u32) -> Self {
self.receive.set_user(receive);
self
}
pub fn transmit(mut self, transmit: u32) -> Self {
self.transmit.set_user(transmit);
self
}
pub fn originate_value(&self) -> u32 {
value_or_copy(&self.originate, 0)
}
pub fn receive_value(&self) -> u32 {
value_or_copy(&self.receive, 0)
}
pub fn transmit_value(&self) -> u32 {
value_or_copy(&self.transmit, 0)
}
}
impl Default for Icmpv4Timestamp {
fn default() -> Self {
Self::new()
}
}
impl Layer for Icmpv4Timestamp {
fn name(&self) -> &'static str {
"IcmpTimestamp"
}
fn summary(&self) -> String {
format!(
"IcmpTimestamp(originate={}, receive={}, transmit={})",
self.originate_value(),
self.receive_value(),
self.transmit_value()
)
}
fn inspection_fields(&self) -> Vec<(&'static str, String)> {
vec![
("originate", self.originate_value().to_string()),
("receive", self.receive_value().to_string()),
("transmit", self.transmit_value().to_string()),
]
}
fn encoded_len(&self) -> usize {
ICMP_TIMESTAMP_BODY_LEN
}
fn compile(&self, _ctx: &LayerContext<'_>, out: &mut Vec<u8>) -> Result<()> {
out.extend_from_slice(&self.originate_value().to_be_bytes());
out.extend_from_slice(&self.receive_value().to_be_bytes());
out.extend_from_slice(&self.transmit_value().to_be_bytes());
Ok(())
}
impl_layer_object!(Icmpv4Timestamp);
}
impl_layer_div!(Icmpv4Timestamp);
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Icmpv4AddressMask {
pub(crate) mask: Field<Ipv4Addr>,
}
#[deprecated(since = "2.1.0", note = "renamed to Icmpv4AddressMask")]
pub type IcmpAddressMask = Icmpv4AddressMask;
impl Icmpv4AddressMask {
pub fn new() -> Self {
Self {
mask: Field::defaulted(Ipv4Addr::UNSPECIFIED),
}
}
pub fn mask(mut self, mask: Ipv4Addr) -> Self {
self.mask.set_user(mask);
self
}
pub fn mask_str(self, mask: &str) -> Result<Self> {
Ok(self.mask(parse_ipv4(mask)?))
}
pub fn mask_bits(self, mask: u32) -> Self {
self.mask(Ipv4Addr::from(mask))
}
pub fn mask_value(&self) -> Ipv4Addr {
value_or_copy(&self.mask, Ipv4Addr::UNSPECIFIED)
}
pub fn mask_octets(&self) -> [u8; 4] {
self.mask_value().octets()
}
}
impl Default for Icmpv4AddressMask {
fn default() -> Self {
Self::new()
}
}
impl Layer for Icmpv4AddressMask {
fn name(&self) -> &'static str {
"IcmpAddressMask"
}
fn summary(&self) -> String {
format!("IcmpAddressMask(mask={})", self.mask_value())
}
fn inspection_fields(&self) -> Vec<(&'static str, String)> {
vec![
("mask", self.mask_value().to_string()),
("mask_bytes", hex_bytes(&self.mask_octets())),
]
}
fn encoded_len(&self) -> usize {
ICMP_ADDRESS_MASK_BODY_LEN
}
fn compile(&self, _ctx: &LayerContext<'_>, out: &mut Vec<u8>) -> Result<()> {
out.extend_from_slice(&self.mask_octets());
Ok(())
}
impl_layer_object!(Icmpv4AddressMask);
}
impl_layer_div!(Icmpv4AddressMask);
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Icmpv4RouterAdvertisementEntry {
pub(crate) router_address: Field<Ipv4Addr>,
pub(crate) preference_level: Field<i32>,
}
#[deprecated(since = "2.1.0", note = "renamed to Icmpv4RouterAdvertisementEntry")]
pub type IcmpRouterAdvertisementEntry = Icmpv4RouterAdvertisementEntry;
impl Icmpv4RouterAdvertisementEntry {
pub fn new() -> Self {
Self {
router_address: Field::defaulted(Ipv4Addr::UNSPECIFIED),
preference_level: Field::defaulted(0),
}
}
pub fn router_address(mut self, router_address: Ipv4Addr) -> Self {
self.router_address.set_user(router_address);
self
}
pub fn router_address_str(self, router_address: &str) -> Result<Self> {
Ok(self.router_address(parse_ipv4(router_address)?))
}
pub fn preference_level(mut self, preference_level: i32) -> Self {
self.preference_level.set_user(preference_level);
self
}
pub fn router_address_value(&self) -> Ipv4Addr {
value_or_copy(&self.router_address, Ipv4Addr::UNSPECIFIED)
}
pub fn router_address_octets(&self) -> [u8; 4] {
self.router_address_value().octets()
}
pub fn preference_level_value(&self) -> i32 {
value_or_copy(&self.preference_level, 0)
}
}
impl Default for Icmpv4RouterAdvertisementEntry {
fn default() -> Self {
Self::new()
}
}
impl Layer for Icmpv4RouterAdvertisementEntry {
fn name(&self) -> &'static str {
"IcmpRouterAdvertisementEntry"
}
fn summary(&self) -> String {
format!(
"IcmpRouterAdvertisementEntry(router={}, preference={})",
self.router_address_value(),
self.preference_level_value()
)
}
fn inspection_fields(&self) -> Vec<(&'static str, String)> {
vec![
("router_address", self.router_address_value().to_string()),
(
"router_address_bytes",
hex_bytes(&self.router_address_octets()),
),
(
"preference_level",
self.preference_level_value().to_string(),
),
]
}
fn encoded_len(&self) -> usize {
ICMP_ROUTER_ADVERTISEMENT_ENTRY_LEN
}
fn compile(&self, _ctx: &LayerContext<'_>, out: &mut Vec<u8>) -> Result<()> {
out.extend_from_slice(&self.router_address_octets());
out.extend_from_slice(&self.preference_level_value().to_be_bytes());
Ok(())
}
impl_layer_object!(Icmpv4RouterAdvertisementEntry);
}
impl_layer_div!(Icmpv4RouterAdvertisementEntry);