Skip to content

Commit

Permalink
0.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Stargateur committed Mar 13, 2024
0 parents commit 7424e65
Show file tree
Hide file tree
Showing 14 changed files with 2,750 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
target/
Cargo.lock
.DS_Store
.vscode
49 changes: 49 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
[package]
name = "binator_network"
authors = ["Stargateur"]
version = "0.0.0"
description = "binator network"
license = "Zlib"
repository = "https://github.com/binator/network"
readme = "readme.md"
keywords = ["parsing", "combinator", "network"]
categories = ["parsing"]
edition = "2021"

include = [
"readme.md",
"license.md",
"Cargo.toml",
"rustfmt.toml",
"src/**/*.rs",
]

[dependencies]
binator_core = "0.0.2"
binator_utils = "0.0.0"
binator_base = "0.0.0"
binator_context = "0.0.0"
binator_number = "0.0.0"
serde = { version = "1.0", optional = true, features = ["derive"] }
const_format = { version = "0.2", features = ["const_generics"] }
paste = "1"

[dependencies.tracing]
version = "0.1"
optional = true

[dev-dependencies]
pretty_assertions = "1"
derive-new = "0.5"
derive_more = "0.99"

binator_core = { version = "0.0.2", features = ["tracing"]}
binator_utils = { version = "0.0.0", features = ["tracing"]}
binator_base = { version = "0.0.0", features = ["tracing"]}
binator_context = { version = "0.0.0", features = ["tracing"]}
binator_number = { version = "0.0.0", features = ["tracing"]}

tracing = "0.1"
tracing-subscriber = {version = "0.3", features = ["env-filter", "fmt"]}
env_logger = "0.9"
test-log = { version = "0.2.10", features = ["trace"] }
11 changes: 11 additions & 0 deletions license.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[zlib License](https://choosealicense.com/licenses/zlib/)

(C) 2022-2024 Stargateur

This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.

Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
1 change: 1 addition & 0 deletions readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Part of this work have been inspired by [pktparse](https://crates.io/crates/pktparse) that is the nom version. It was used to test binator but still provide some basic network parsing.
18 changes: 18 additions & 0 deletions rustfmt.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
condense_wildcard_suffixes = true
fn_params_layout = "Compressed"
format_code_in_doc_comments = true
format_macro_matchers = true
format_strings = true
hex_literal_case = "Upper"
imports_layout = "Vertical"
merge_derives = false
imports_granularity = "Crate"
newline_style = "Unix"
normalize_comments = true
reorder_impl_items = true
group_imports = "StdExternalCrate"
tab_spaces = 2
use_field_init_shorthand = true
version = "Two"
use_try_shorthand = true
wrap_comments = true
155 changes: 155 additions & 0 deletions src/ether_type.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
use binator_base::octet;
use binator_core::{
Contexting,
CoreAtom,
Parse,
Parsed,
Streaming,
};
use binator_utils::{
Utils,
UtilsAtom,
};

use crate::struct_variants;

struct_variants! {
EtherType, ether_type, u16:
/// 802.3 Min data length
LANMIN => 0x002E,
/// 802.3 Max data length
LANMAX => 0x05DC,
/// Internet Protocol version 4 (IPv4)
IPV4 => 0x0800,
/// Address Resolution Protocol (ARP)
ARP => 0x0806,
/// Wake-on-LAN
WOL => 0x0842,
/// IETF TRILL Protocol
TRILL => 0x22F3,
/// DECnet Phase IV
DECNET => 0x6003,
/// Reverse Address Resolution Protocol
RARP => 0x8035,
/// AppleTalk (Ethertalk)
APPLE_TALK => 0x809B,
/// AppleTalk Address Resolution Protocol (AARP)
AARP => 0x80F3,
/// VLAN-tagged frame (IEEE 802.1Q) and Shortest Path Bridging IEEE 802.1aq
VLAN => 0x8100,
/// IPX
IPX => 0x8137,
/// QNX Qnet
QNET => 0x8204,
/// Internet Protocol Version 6 (IPv6)
IPV6 => 0x86DD,
/// Ethernet flow control
FLOW_CONTROL => 0x8808,
/// CobraNet
COBRA_NET => 0x8819,
/// MPLS unicast
MPLS_UNI => 0x8847,
/// MPLS multicast
MPLS_MUTLI => 0x8848,
/// PPPoE Discovery Stage
PPPOE_DISCOVERY => 0x8863,
/// PPPoE Session Stage
PPPOE_SESSION => 0x8864,
/// HomePlug 1.0 MME
HOME_PLUG => 0x887B,
/// EAP over LAN (IEEE 802.1X)
EAPOL => 0x888E,
/// PROFINET Protocol
PROFINET => 0x8892,
/// HyperSCSI (SCSI over Ethernet)
HYPER_SCSI => 0x889A,
/// ATA over Ethernet
ATAOE => 0x88A2,
/// EtherCAT Protocol
ETHER_CAT => 0x88A4,
/// Provider Bridging (IEEE 802.1ad) & Shortest Path Bridging IEEE 802.1aq
QINQ => 0x88A8,
/// Ethernet Powerlink
POWER_LINK => 0x88AB,
/// GOOSE (Generic Object Oriented Substation event)
GOOSE => 0x88B8,
/// GSE (Generic Substation Events) Management Services
GSE => 0x88B9,
/// Link Layer Discovery Protocol (LLDP)
LLDP => 0x88CC,
/// SERCOS III
SERCOS => 0x88CD,
/// HomePlug AV MME
HOME_PLUG_AV => 0x88E1,
/// Media Redundancy Protocol (IEC62439-2)
MRP => 0x88E3,
/// MAC security (IEEE 802.1AE)
MAC_SEC => 0x88E5,
/// Provider Backbone Bridges (PBB) (IEEE 802.1ah)
PBB => 0x88E7,
/// Precision Time Protocol (PTP) over Ethernet (IEEE 1588)
PTP => 0x88F7,
/// Parallel Redundancy Protocol (PRP)
PRP => 0x88FB,
/// IEEE 802.1ag Connectivity Fault Management (CFM) Protocol / ITU-T Recommendation Y.1731 (OAM)
CFM => 0x8902,
/// Fibre Channel over Ethernet (FCoE)
FCOE => 0x8906,
/// FCoE Initialization Protocol
FCOEI => 0x8914,
/// RDMA over Converged Ethernet (RoCE)
ROCE => 0x8915,
/// TTEthernet Protocol Control Frame (TTE)
TTE => 0x891D,
/// High-availability Seamless Redundancy (HSR)
HSR => 0x892F,
/// Ethernet Configuration Testing Protocol
CTP => 0x9000,
/// VLAN-tagged (IEEE 802.1Q) frame with double tagging
VLAN_DOUBLE => 0x9100,
/// Veritas Low Latency Transport (LLT)
LLT => 0xCAFE,
}

pub(crate) fn ether_type<Stream, Context>(stream: Stream) -> Parsed<EtherType, Stream, Context>
where
Stream: Clone + Eq,
Stream: Streaming,
Context: Contexting<CoreAtom<Stream>>,
Context: Contexting<UtilsAtom<Stream>>,
Stream::Item: Into<u8>,
{
octet
.fill()
.map(u16::from_be_bytes)
.map(EtherType::new)
.parse(stream)
}

#[cfg(test)]
mod tests {
use binator_context::Ignore;
use binator_core::Parsed;

use super::EtherType;

#[test]
fn ether_type() {
let tests = [
([0x08, 0x00], EtherType::IPV4),
([0x08, 0x06], EtherType::ARP),
([0x86, 0xDD], EtherType::IPV6),
([0x81, 0x00], EtherType::VLAN),
];

for (stream, expected) in tests {
assert_eq!(
super::ether_type::<_, Ignore>(&stream[..]),
Parsed::Success {
token: expected,
stream: &[][..],
}
);
}
}
}
143 changes: 143 additions & 0 deletions src/ethernet.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
//! Handles parsing of Ethernet headers
use binator_base::octet;
use binator_core::{
Contexting,
CoreAtom,
Parse,
Parsed,
Streaming,
Success,
};
use binator_utils::{
Utils,
UtilsAtom,
};

use crate::ether_type::{
ether_type,
EtherType,
};

/// EthernetFrame
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct EthernetFrame {
/// MAC destination
pub destination: [u8; 6],
/// MAC source
pub source: [u8; 6],
/// EtherType used
pub ether_type: EtherType,
/// TCI
pub tci: Option<u16>,
}

/// Parser that return a ethernet frame on success
/// <https://en.wikipedia.org/wiki/Ethernet_frame>
pub fn ethernet_frame<Stream, Context>(stream: Stream) -> Parsed<EthernetFrame, Stream, Context>
where
Stream: Clone,
Stream: Eq,
Stream: Streaming,
Stream::Item: Into<u8>,
Context: Contexting<CoreAtom<Stream>>,
Context: Contexting<UtilsAtom<Stream>>,
Context: Contexting<UtilsAtom<Stream>>,
{
let Success {
token: destination,
stream,
} = octet.fill().parse(stream)?;
let Success {
token: source,
stream,
} = octet.fill().parse(stream)?;
let Success {
token: (ether_type, tci),
stream,
} = ether_type
.and_then(|tmp_ether_type| {
move |stream: Stream| {
if tmp_ether_type == EtherType::VLAN {
let Success { token: tci, stream } =
octet.fill().map(u16::from_be_bytes).parse(stream)?;
let Success {
token: ether_type,
stream,
} = ether_type.parse(stream)?;

Parsed::Success {
token: (ether_type, Some(tci)),
stream,
}
} else {
Parsed::Success {
token: (tmp_ether_type, None),
stream,
}
}
}
})
.parse(stream)?;

Parsed::Success {
token: EthernetFrame {
destination,
source,
ether_type,
tci,
},
stream,
}
}

#[cfg(test)]
mod tests {
use binator_context::Ignore;
use binator_core::Parsed;

use super::{
EtherType,
EthernetFrame,
};

#[test]
fn ethernet_frame() {
let tests = [
(
&[
0x00, 0x23, 0x54, 0x07, 0x93, 0x6C, 0x00, 0x1B, 0x21, 0x0F, 0x91, 0x9B, 0x08, 0x00,
][..],
EthernetFrame {
destination: [0x00, 0x23, 0x54, 0x07, 0x93, 0x6C],
source: [0x00, 0x1B, 0x21, 0x0F, 0x91, 0x9B],
ether_type: EtherType::IPV4,
tci: None,
},
),
(
&[
0x00, 0x23, 0x54, 0x07, 0x93, 0x6C, 0x00, 0x1B, 0x21, 0x0F, 0x91, 0x9B, 0x81, 0x00, 0x04,
0xD2, 0x08, 0x00,
][..],
EthernetFrame {
destination: [0x00, 0x23, 0x54, 0x07, 0x93, 0x6C],
source: [0x00, 0x1B, 0x21, 0x0F, 0x91, 0x9B],
ether_type: EtherType::IPV4,
tci: Some(1234),
},
),
];

for (stream, expected) in tests {
assert_eq!(
super::ethernet_frame::<_, Ignore>(stream),
Parsed::Success {
token: expected,
stream: b"".as_slice(),
}
);
}
}
}
Loading

0 comments on commit 7424e65

Please sign in to comment.