Skip to content

Commit

Permalink
clean arp
Browse files Browse the repository at this point in the history
  • Loading branch information
tiannian committed Oct 18, 2022
1 parent 5f329ba commit 1cdc633
Show file tree
Hide file tree
Showing 15 changed files with 482 additions and 296 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ MAC Layer support these packet type:

- [X] EthernetII
- [X] IEEE802.3
- [ ] VLAN (802.3q)
- [ ] QinQ (802.3q)
- [X] VLAN (802.3q)
- [X] QinQ (802.3q)

### Network Layer

Expand Down
2 changes: 2 additions & 0 deletions pkt/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ pub enum Error {
Illegal,
Malformed,
Unrecognized,
WrongLengthForEthernetAddress,
WrongLengthForIpv4Address,
}

/// Result for packet.
Expand Down
5 changes: 1 addition & 4 deletions pkt/src/ip/arp/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
mod types;

pub use types::{Hardware, Operation};
pub use types::*;

mod packet;
pub use packet::Packet;

mod repr;
pub use repr::Repr;
105 changes: 78 additions & 27 deletions pkt/src/ip/arp/packet.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use super::Repr;
use super::{Hardware, Operation};
use crate::error::*;
use crate::mac::Protocol;
use super::{consts, Operation, HardwareAddress, ProtocolAddress};
use crate::{error::*, mac, ip::ipv4::Address};
use byteorder::{ByteOrder, NetworkEndian};
use core::fmt::{self, Display};

Expand All @@ -12,8 +10,13 @@ pub struct Packet<T: AsRef<[u8]>> {

impl<T: AsRef<[u8]>> Display for Packet<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let repr = Repr::parse(self).unwrap();
f.write_fmt(format_args!("{}", repr))
f.write_str("Arp Packet:")?;
f.write_fmt(format_args!(
"{:?} to {:?}, Op: {:?}",
self.source_hardware_address(),
self.target_hardware_address(),
self.operation()
))
}
}

Expand Down Expand Up @@ -70,28 +73,84 @@ impl<T: AsRef<[u8]>> Packet<T> {
}
}

/// Return the hardware type field.
pub fn hardware_type(&self) -> Hardware {
/// Return the source hardware address.
pub fn source_hardware_address(&self) -> Result<HardwareAddress> {
let data = self.buffer.as_ref();
let raw = NetworkEndian::read_u16(&data[field::HTYPE]);
Hardware::from(raw)

if raw == consts::HARDWARE_ETHERNET {
if self.hardware_len() == consts::HARDWARE_ETHERNET_LENGTH {
let raw_addr = self.source_hardware_addr();
let addr = mac::Address::from(raw_addr);
Ok(HardwareAddress::Ethernet(addr))
} else {
Err(Error::WrongLengthForEthernetAddress)
}
} else {
Ok(HardwareAddress::from(raw))
}
}

/// Return the target hardware address.
pub fn target_hardware_address(&self) -> Result<HardwareAddress> {
let data = self.buffer.as_ref();
let raw = NetworkEndian::read_u16(&data[field::HTYPE]);

if raw == consts::HARDWARE_ETHERNET {
if self.hardware_len() == consts::HARDWARE_ETHERNET_LENGTH {
let raw_addr = self.target_hardware_addr();
let addr = mac::Address::from(raw_addr);
Ok(HardwareAddress::Ethernet(addr))
} else {
Err(Error::WrongLengthForEthernetAddress)
}
} else {
Ok(HardwareAddress::from(raw))
}
}

/// Return the protocol type field.
pub fn protocol_type(&self) -> Protocol {
pub fn source_protocol_address(&self) -> Result<ProtocolAddress> {
let data = self.buffer.as_ref();
let raw = NetworkEndian::read_u16(&data[field::PTYPE]);
Protocol::from(raw)
if raw == consts::HARDWARE_ETHERNET {
if self.hardware_len() == consts::HARDWARE_ETHERNET_LENGTH {
let raw_addr = self.source_protocol_addr();
let addr = Address::from(raw_addr);
Ok(ProtocolAddress::IPv4(addr))
} else {
Err(Error::WrongLengthForIpv4Address)
}
} else {
Ok(ProtocolAddress::from(raw))
}
}

/// Return the target protocol address.
pub fn target_protocol_address(&self) -> Result<ProtocolAddress> {
let data = self.buffer.as_ref();
let raw = NetworkEndian::read_u16(&data[field::PTYPE]);
if raw == consts::HARDWARE_ETHERNET {
if self.hardware_len() == consts::HARDWARE_ETHERNET_LENGTH {
let raw_addr = self.target_protocol_addr();
let addr = Address::from(raw_addr);
Ok(ProtocolAddress::IPv4(addr))
} else {
Err(Error::WrongLengthForIpv4Address)
}
} else {
Ok(ProtocolAddress::from(raw))
}
}

/// Return the hardware length field.
pub fn hardware_len(&self) -> u8 {
fn hardware_len(&self) -> u8 {
let data = self.buffer.as_ref();
data[field::HLEN]
}

/// Return the protocol length field.
pub fn protocol_len(&self) -> u8 {
fn protocol_len(&self) -> u8 {
let data = self.buffer.as_ref();
data[field::PLEN]
}
Expand All @@ -103,44 +162,36 @@ impl<T: AsRef<[u8]>> Packet<T> {
Operation::from(raw)
}

/// Return the source hardware address field.
pub fn source_hardware_addr(&self) -> &[u8] {
fn source_hardware_addr(&self) -> &[u8] {
let data = self.buffer.as_ref();
&data[field::source_hardware_address(self.hardware_len(), self.protocol_len())]
}

/// Return the source protocol address field.
pub fn source_protocol_addr(&self) -> &[u8] {
fn source_protocol_addr(&self) -> &[u8] {
let data = self.buffer.as_ref();
&data[field::source_protocol_address(self.hardware_len(), self.protocol_len())]
}

/// Return the target hardware address field.
pub fn target_hardware_addr(&self) -> &[u8] {
fn target_hardware_addr(&self) -> &[u8] {
let data = self.buffer.as_ref();
&data[field::target_hardware_address(self.hardware_len(), self.protocol_len())]
}

/// Return the target protocol address field.
pub fn target_protocol_addr(&self) -> &[u8] {
fn target_protocol_addr(&self) -> &[u8] {
let data = self.buffer.as_ref();
&data[field::target_protocol_address(self.hardware_len(), self.protocol_len())]
}

pub fn into_inner(self) -> T {
self.buffer
}
}

impl<T: AsRef<[u8]> + AsMut<[u8]>> Packet<T> {
/// Set the hardware type field.
pub fn set_hardware_type(&mut self, value: Hardware) {
pub fn set_hardware(&mut self, value: HardwareAddress) {
let data = self.buffer.as_mut();
NetworkEndian::write_u16(&mut data[field::HTYPE], value.into())
}

/// Set the protocol type field.
pub fn set_protocol_type(&mut self, value: Protocol) {
pub fn set_protocol(&mut self, value: ProtocolAddress) {
let data = self.buffer.as_mut();
NetworkEndian::write_u16(&mut data[field::PTYPE], value.into())
}
Expand Down
84 changes: 0 additions & 84 deletions pkt/src/ip/arp/repr.rs

This file was deleted.

72 changes: 59 additions & 13 deletions pkt/src/ip/arp/types.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,35 @@
use crate::{mac, ip::ipv4::Address};

pub mod consts {
pub const HARDWARE_ETHERNET: u16 = 1;

pub const HARDWARE_ETHERNET_LENGTH: u8 = 6;

pub const OPERATION_REQUEST: u16 = 1;
pub const OPERATION_REPLAY: u16 = 2;

pub const PROTOCOL_IPV4: u16 = 0x0800;
}

#[derive(Debug, PartialEq, Eq, Clone)]
pub enum Hardware {
Ethernet,
pub enum HardwareAddress {
Ethernet(mac::Address),
Unknown(u16),
}

impl From<u16> for Hardware {
impl From<u16> for HardwareAddress {
fn from(v: u16) -> Self {
match v {
1 => Hardware::Ethernet,
_ => Hardware::Unknown(v),
_ => Self::Unknown(v),
}
}
}

impl From<Hardware> for u16 {
fn from(v: Hardware) -> u16 {
impl From<HardwareAddress> for u16 {
fn from(v: HardwareAddress) -> u16 {
match v {
Hardware::Ethernet => 1,
Hardware::Unknown(a) => a,
HardwareAddress::Ethernet(_) => consts::HARDWARE_ETHERNET,
HardwareAddress::Unknown(a) => a,
}
}
}
Expand All @@ -32,8 +44,8 @@ pub enum Operation {
impl From<u16> for Operation {
fn from(v: u16) -> Self {
match v {
1 => Operation::Request,
2 => Operation::Reply,
consts::OPERATION_REQUEST => Operation::Request,
consts::OPERATION_REPLAY => Operation::Reply,
_ => Operation::Unknown(v),
}
}
Expand All @@ -42,9 +54,43 @@ impl From<u16> for Operation {
impl From<Operation> for u16 {
fn from(v: Operation) -> u16 {
match v {
Operation::Request => 1,
Operation::Reply => 2,
Operation::Request => consts::OPERATION_REQUEST,
Operation::Reply => consts::OPERATION_REPLAY,
Operation::Unknown(a) => a,
}
}
}

/// Ethernet payload type.
#[derive(Debug, Clone)]
pub enum ProtocolAddress {
IPv4(Address),

Unknown(u16),
}

impl From<u16> for ProtocolAddress {
fn from(ty: u16) -> Self {
match ty {
_ => Self::Unknown(ty),
}
}
}

impl From<ProtocolAddress> for u16 {
fn from(e: ProtocolAddress) -> u16 {
match e {
ProtocolAddress::IPv4(_) => consts::PROTOCOL_IPV4,
ProtocolAddress::Unknown(v) => v,
}
}
}

impl From<&ProtocolAddress> for u16 {
fn from(e: &ProtocolAddress) -> u16 {
match e {
ProtocolAddress::IPv4(_) => consts::PROTOCOL_IPV4,
ProtocolAddress::Unknown(v) => *v,
}
}
}
2 changes: 1 addition & 1 deletion pkt/src/ip/ipv4/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ impl Display for Address {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let inner = self.0;
f.write_fmt(format_args!(
"{}:{}:{}:{}",
"{}.{}.{}.{}",
inner[0], inner[1], inner[2], inner[3]
))
}
Expand Down
Loading

0 comments on commit 1cdc633

Please sign in to comment.