aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWill Dillon <william@housedillon.com>2025-11-05 21:23:17 +0000
committerWill Dillon <william@housedillon.com>2025-11-05 21:23:17 +0000
commit7b79979ea4ba2968fad469174c3d9138e8a4a688 (patch)
tree189c9a6af24e3c5b3e42c629310015df40eff015
downloadmeshcore-rs-7b79979ea4ba2968fad469174c3d9138e8a4a688.tar.gz
meshcore-rs-7b79979ea4ba2968fad469174c3d9138e8a4a688.zip
Initial commit
-rw-r--r--.gitignore1
-rw-r--r--Cargo.lock424
-rw-r--r--Cargo.toml11
-rw-r--r--src/crypto.rs58
-rw-r--r--src/lib.rs3
-rw-r--r--src/packet.rs259
6 files changed, 756 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ea8c4bf
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/target
diff --git a/Cargo.lock b/Cargo.lock
new file mode 100644
index 0000000..fc8cc6c
--- /dev/null
+++ b/Cargo.lock
@@ -0,0 +1,424 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "base64ct"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba"
+
+[[package]]
+name = "block-buffer"
+version = "0.10.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
+name = "bytes"
+version = "1.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
+
+[[package]]
+name = "const-oid"
+version = "0.9.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
+
+[[package]]
+name = "cpufeatures"
+version = "0.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "crypto-common"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
+dependencies = [
+ "generic-array",
+ "typenum",
+]
+
+[[package]]
+name = "curve25519-dalek"
+version = "4.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be"
+dependencies = [
+ "cfg-if",
+ "cpufeatures",
+ "curve25519-dalek-derive",
+ "digest",
+ "fiat-crypto",
+ "group",
+ "rand_core",
+ "rustc_version",
+ "subtle",
+ "zeroize",
+]
+
+[[package]]
+name = "curve25519-dalek-derive"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "der"
+version = "0.7.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb"
+dependencies = [
+ "const-oid",
+ "zeroize",
+]
+
+[[package]]
+name = "digest"
+version = "0.10.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
+dependencies = [
+ "block-buffer",
+ "crypto-common",
+]
+
+[[package]]
+name = "ed25519"
+version = "2.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53"
+dependencies = [
+ "pkcs8",
+ "signature",
+]
+
+[[package]]
+name = "ed25519-dalek"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9"
+dependencies = [
+ "curve25519-dalek",
+ "ed25519",
+ "serde",
+ "sha2",
+ "subtle",
+ "zeroize",
+]
+
+[[package]]
+name = "ff"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393"
+dependencies = [
+ "rand_core",
+ "subtle",
+]
+
+[[package]]
+name = "fiat-crypto"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d"
+
+[[package]]
+name = "futures-core"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
+
+[[package]]
+name = "futures-sink"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
+
+[[package]]
+name = "generic-array"
+version = "0.14.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2"
+dependencies = [
+ "typenum",
+ "version_check",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi",
+]
+
+[[package]]
+name = "group"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63"
+dependencies = [
+ "ff",
+ "rand_core",
+ "subtle",
+]
+
+[[package]]
+name = "hex"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
+
+[[package]]
+name = "libc"
+version = "0.2.177"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976"
+
+[[package]]
+name = "meshcore"
+version = "0.1.0"
+dependencies = [
+ "curve25519-dalek",
+ "ed25519-dalek",
+ "hex",
+ "tokio-util",
+ "x25519-dalek",
+]
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
+
+[[package]]
+name = "pkcs8"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7"
+dependencies = [
+ "der",
+ "spki",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.103"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.41"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
+dependencies = [
+ "getrandom",
+]
+
+[[package]]
+name = "rustc_version"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
+dependencies = [
+ "semver",
+]
+
+[[package]]
+name = "semver"
+version = "1.0.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
+
+[[package]]
+name = "serde"
+version = "1.0.228"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
+dependencies = [
+ "serde_core",
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_core"
+version = "1.0.228"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.228"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "sha2"
+version = "0.10.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
+dependencies = [
+ "cfg-if",
+ "cpufeatures",
+ "digest",
+]
+
+[[package]]
+name = "signature"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
+dependencies = [
+ "rand_core",
+]
+
+[[package]]
+name = "spki"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d"
+dependencies = [
+ "base64ct",
+ "der",
+]
+
+[[package]]
+name = "subtle"
+version = "2.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
+
+[[package]]
+name = "syn"
+version = "2.0.108"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da58917d35242480a05c2897064da0a80589a2a0476c9a3f2fdc83b53502e917"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "tokio"
+version = "1.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408"
+dependencies = [
+ "pin-project-lite",
+]
+
+[[package]]
+name = "tokio-util"
+version = "0.7.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594"
+dependencies = [
+ "bytes",
+ "futures-core",
+ "futures-sink",
+ "pin-project-lite",
+ "tokio",
+]
+
+[[package]]
+name = "typenum"
+version = "1.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
+
+[[package]]
+name = "version_check"
+version = "0.9.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
+
+[[package]]
+name = "wasi"
+version = "0.11.1+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
+
+[[package]]
+name = "x25519-dalek"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277"
+dependencies = [
+ "curve25519-dalek",
+ "rand_core",
+ "serde",
+ "zeroize",
+]
+
+[[package]]
+name = "zeroize"
+version = "1.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0"
+dependencies = [
+ "zeroize_derive",
+]
+
+[[package]]
+name = "zeroize_derive"
+version = "1.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..4deb83a
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,11 @@
+[package]
+name = "meshcore"
+version = "0.1.0"
+edition = "2024"
+
+[dependencies]
+ed25519-dalek = { version = "2.2.0", features = ["hazmat", "pkcs8"] }
+curve25519-dalek = { version = "4.1.3", features = ["group"] }
+x25519-dalek = { version = "*", features = ["static_secrets"] }
+hex = "0.4"
+tokio-util = "*" \ No newline at end of file
diff --git a/src/crypto.rs b/src/crypto.rs
new file mode 100644
index 0000000..adcd4d8
--- /dev/null
+++ b/src/crypto.rs
@@ -0,0 +1,58 @@
+use std::{collections::HashMap, str::FromStr};
+
+use ed25519_dalek::hazmat::ExpandedSecretKey;
+use curve25519_dalek::{constants, edwards::CompressedEdwardsY};
+use tokio_util::bytes::Bytes;
+use x25519_dalek::StaticSecret;
+
+use hex::decode;
+
+pub struct PrivateKey(ExpandedSecretKey);
+pub struct PublicKey(CompressedEdwardsY);
+pub struct SharedSecret([u8; 32]);
+
+impl FromStr for PrivateKey {
+ type Err = hex::FromHexError;
+
+ fn from_str(hex_str: &str) -> Result<Self, Self::Err> {
+ let hex = decode(hex_str)?;
+
+ if let Ok(bytes) = TryInto::<[u8; 64]>::try_into(hex) {
+ let exp_sec_key = ExpandedSecretKey::from_bytes(&bytes);
+
+ Ok(PrivateKey(exp_sec_key))
+ } else {
+ Err(hex::FromHexError::InvalidStringLength)
+ }
+ }
+}
+
+impl From<PrivateKey> for PublicKey {
+ fn from(key: PrivateKey) -> Self {
+ PublicKey((key.0.scalar * constants::ED25519_BASEPOINT_POINT).compress())
+ }
+}
+
+impl PrivateKey {
+ pub fn create_secret(&self, other: &PublicKey) -> SharedSecret {
+ let private = StaticSecret::from(*self.0.scalar.as_bytes());
+ SharedSecret(private.diffie_hellman(&other.0.to_bytes().into()).to_bytes())
+ }
+}
+
+impl SharedSecret {
+ pub fn mac_then_decrypt(&self, mac: [u8; 2], data: Bytes) -> Option<Bytes> {
+ None
+ }
+
+ pub fn encrypt_then_mac(&self, data: Bytes) -> Option<([u8; 2], Bytes)> {
+ None
+ }
+}
+
+pub struct Keychain {
+ pub private_keys: Vec<PrivateKey>,
+ pub public_keys: Vec<PublicKey>,
+
+ // secrets: HashMap<String, Ha>
+} \ No newline at end of file
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..817b464
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,3 @@
+pub mod crypto;
+pub mod packet;
+
diff --git a/src/packet.rs b/src/packet.rs
new file mode 100644
index 0000000..d44aa66
--- /dev/null
+++ b/src/packet.rs
@@ -0,0 +1,259 @@
+use std::str::FromStr;
+
+use hex::decode;
+use tokio_util::bytes::{Buf, Bytes};
+
+use crate::{crypto::SharedSecret, packet};
+
+#[derive(PartialEq, Debug)]
+struct Packet {
+ route_type: RouteType,
+ version: PayloadVersion,
+ path: Vec<u16>,
+ transport: [u16; 2],
+ raw_content: Bytes,
+ content: PacketContent,
+ incomplete: bool
+}
+
+#[derive(PartialEq, Debug)]
+enum RouteType {
+ TransportFlood,
+ Flood,
+ Direct,
+ TransportDirect,
+ Invalid,
+}
+
+impl From<u8> for RouteType {
+ fn from(value: u8) -> Self {
+ match value & 0x03 {
+ 0x00 => RouteType::TransportFlood,
+ 0x01 => RouteType::Flood,
+ 0x02 => RouteType::Direct,
+ 0x03 => RouteType::TransportDirect,
+ _ => RouteType::Invalid
+ }
+ }
+}
+
+#[derive(PartialEq, Debug)]
+enum PayloadVersion {
+ VersionOne,
+ VersionTwo,
+ VersionThree,
+ VersionFour,
+ Invalid,
+}
+
+impl From<u8> for PayloadVersion {
+ fn from(value: u8) -> Self {
+ let value = (value & 0xC0) >> 6;
+ assert!(value < 4, "Programming error in masking and bitshifting");
+
+ match value {
+ 0x00 => PayloadVersion::VersionOne,
+ 0x01 => PayloadVersion::VersionTwo,
+ 0x02 => PayloadVersion::VersionThree,
+ 0x03 => PayloadVersion::VersionFour,
+ _ => PayloadVersion::Invalid
+ }
+ }
+}
+
+#[derive(PartialEq, Debug)]
+enum PacketContent {
+ Request(Request),
+ Response(Response),
+ Text(Text),
+ Ack(Ack),
+ Advert(Advert),
+ GroupText(GroupText),
+ GroupData(GroupData),
+ AnonReq(AnonReq),
+ Path(Path),
+ Trace(Trace),
+ Multipart(MultiPart),
+ Raw(Raw),
+
+ Invalid,
+}
+
+#[derive(PartialEq, Debug)]
+struct Request {}
+
+#[derive(PartialEq, Debug)]
+struct Response {}
+
+#[derive(PartialEq, Debug)]
+struct Text {}
+
+#[derive(PartialEq, Debug)]
+struct Ack {}
+
+#[derive(PartialEq, Debug)]
+struct Advert {}
+
+#[derive(PartialEq, Debug)]
+struct GroupText {}
+
+#[derive(PartialEq, Debug)]
+struct GroupData {}
+
+#[derive(PartialEq, Debug)]
+struct AnonReq {}
+
+#[derive(PartialEq, Debug)]
+struct Path {}
+
+#[derive(PartialEq, Debug)]
+struct Trace {}
+
+#[derive(PartialEq, Debug)]
+struct MultiPart {}
+
+#[derive(PartialEq, Debug)]
+struct Raw {}
+
+impl FromStr for Packet {
+ type Err = hex::FromHexError;
+
+ fn from_str(hex_str: &str) -> Result<Self, Self::Err> {
+ let hex = decode(hex_str)?;
+ Ok(Packet::from(Bytes::copy_from_slice(&hex)))
+ }
+}
+
+impl From<Bytes> for Packet {
+ fn from(bytes: Bytes) -> Self {
+ let mut bytes = bytes;
+
+ // This is the packet we'll build as we begin to parse
+ let mut packet = Packet::default();
+
+ if bytes.len() == 0 {
+ return packet
+ }
+
+ let header = bytes.split_to(0).get_u8();
+
+ // Parse the header byte
+ packet.route_type = RouteType::from(header);
+ packet.version = PayloadVersion::from(header);
+
+ // Get the transport if it's provided
+ packet.transport = match packet.route_type {
+ RouteType::TransportFlood | RouteType::TransportDirect => {
+ // The packet isn't long enough to contain the transport
+ if bytes.len() < 4 { return packet; }
+
+ [bytes.split_to(2).get_u16(), bytes.split_to(2).get_u16()]
+ },
+ _ => {
+ [0, 0]
+ }
+ };
+
+ // Get the route
+ if bytes.len() == 0 { return packet; }
+ let path_length = bytes.split_to(1).get_u8() as usize;
+
+ packet.path = match packet.version {
+ PayloadVersion::VersionOne => {
+ // The packet isn't long enough for the indicated route
+ if bytes.len() < path_length { return packet; }
+
+ let route: Vec<u16> = bytes
+ .split_to(path_length)
+ .into_iter()
+ .map(|x| x as u16)
+ .collect();
+ route
+ },
+ PayloadVersion::VersionTwo => {
+ // The packet isn't long enough for the indicated route
+ if bytes.len() < path_length as usize * 2 { return packet; }
+
+ let route: Vec<u16> = bytes
+ .split_to(path_length * 2)
+ .chunks(2)
+ .map(|c| Bytes::copy_from_slice(c).get_u16())
+ .collect();
+
+ route
+ },
+ _ => {
+ return packet;
+ }
+ };
+
+ // Get the rest of the payload and subscript the parsing to the other structs
+ packet.raw_content = bytes;
+
+ // Mark the packet as complete and valid
+ packet.incomplete = false;
+
+ packet
+ }
+}
+
+impl Packet {
+ pub fn attempt_decrypt(&mut self, secret: SharedSecret) -> bool {
+ false
+ }
+
+}
+
+impl Default for Packet {
+ fn default() -> Self {
+ Packet {
+ route_type: RouteType::Invalid,
+ version: PayloadVersion::Invalid,
+ path: vec![],
+ transport: [0, 0],
+ raw_content: Bytes::new(),
+ content: PacketContent::Invalid,
+ incomplete: true
+ }
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn header_route_type() {
+ // The route type is the lowest-order two bits
+ assert!(RouteType::TransportFlood == RouteType::from(0x00));
+ assert!(RouteType::TransportFlood == RouteType::from(0xFC));
+ assert!(RouteType::Flood == RouteType::from(0x01));
+ assert!(RouteType::Flood == RouteType::from(0xFD));
+ assert!(RouteType::Direct == RouteType::from(0x02));
+ assert!(RouteType::Direct == RouteType::from(0xFE));
+ assert!(RouteType::TransportDirect == RouteType::from(0x03));
+ assert!(RouteType::TransportDirect == RouteType::from(0xFF));
+ }
+
+ #[test]
+ fn header_version() {
+ assert!(PayloadVersion::VersionOne == PayloadVersion::from(0x00));
+ assert!(PayloadVersion::VersionOne == PayloadVersion::from(0x3F));
+ assert!(PayloadVersion::VersionTwo == PayloadVersion::from(0x40));
+ assert!(PayloadVersion::VersionTwo == PayloadVersion::from(0x7F));
+ assert!(PayloadVersion::VersionThree == PayloadVersion::from(0x80));
+ assert!(PayloadVersion::VersionThree == PayloadVersion::from(0xBF));
+ assert!(PayloadVersion::VersionFour == PayloadVersion::from(0xC0));
+ assert!(PayloadVersion::VersionFour == PayloadVersion::from(0xFF));
+ }
+
+ #[test]
+ fn packet() {
+ // Check the hex decode errors
+ assert!(Err(hex::FromHexError::InvalidHexCharacter { c: 's', index: 0 }) == Packet::from_str("s0"));
+ assert!(Err(hex::FromHexError::OddLength) == Packet::from_str("0"));
+
+ // Check errors related to packet length issues
+ assert!(Packet::default() == Packet::from_str("").unwrap())
+ }
+} \ No newline at end of file