From cbcdbe796925a51b36864eba6f4a84e0f73f3565 Mon Sep 17 00:00:00 2001 From: 0xphen Date: Mon, 6 Nov 2023 12:29:47 +0100 Subject: [PATCH] Refactor ethernet frame parser --- src/lib.rs | 129 ++++++++++++------------------ src/parsers/definitions.rs | 1 - src/parsers/errors.rs | 3 + src/parsers/ethernet_frame.rs | 142 +++++++++++++++------------------- src/parsers/ipv4.rs | 2 - src/parsers/utils.rs | 13 ++++ 6 files changed, 129 insertions(+), 161 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index bb5a55a..6a10a1c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,83 +9,55 @@ pub mod parsers; // #[test] // fn run_test() { // let frames = [ -// 60, 34, 251, 165, 184, 202, 180, 28, 48, 182, 93, 120, 8, 0, 69, 0, 5, 160, 22, 43, 64, -// 0, 95, 6, 159, 226, 118, 179, 40, 116, 192, 168, 0, 123, 118, 88, 226, 105, 230, 83, -// 76, 55, 63, 197, 136, 176, 128, 16, 16, 1, 142, 83, 0, 0, 1, 1, 8, 10, 2, 4, 83, 111, -// 145, 186, 142, 229, 206, 219, 128, 122, 192, 126, 244, 189, 126, 234, 229, 18, 100, -// 150, 104, 114, 187, 244, 222, 16, 160, 194, 133, 237, 181, 243, 122, 130, 2, 97, 210, -// 3, 117, 229, 88, 174, 176, 44, 30, 188, 160, 108, 230, 90, 222, 59, 235, 222, 149, 186, -// 129, 3, 239, 216, 88, 202, 22, 233, 110, 31, 149, 65, 61, 104, 255, 200, 211, 58, 114, -// 67, 150, 240, 124, 139, 164, 60, 3, 79, 23, 102, 111, 109, 41, 196, 176, 172, 95, 243, -// 99, 19, 112, 26, 91, 207, 0, 217, 116, 194, 136, 94, 142, 223, 101, 50, 228, 122, 52, -// 195, 8, 67, 8, 196, 236, 68, 49, 202, 185, 100, 204, 169, 52, 73, 9, 215, 36, 112, 24, -// 13, 238, 95, 156, 107, 121, 154, 219, 113, 109, 217, 19, 156, 162, 100, 252, 241, 107, -// 142, 140, 88, 122, 72, 178, 175, 236, 181, 108, 161, 112, 219, 85, 121, 254, 152, 233, -// 41, 25, 18, 146, 239, 243, 138, 10, 143, 49, 141, 83, 185, 78, 207, 76, 33, 73, 154, -// 45, 38, 40, 213, 79, 151, 238, 223, 228, 229, 44, 162, 31, 109, 211, 104, 86, 238, 246, -// 136, 6, 205, 230, 167, 209, 13, 141, 227, 10, 51, 126, 98, 107, 238, 80, 147, 239, 136, -// 79, 74, 239, 134, 204, 223, 38, 41, 21, 183, 228, 39, 58, 183, 209, 90, 138, 227, 71, -// 213, 40, 71, 135, 243, 61, 219, 1, 168, 238, 97, 210, 80, 177, 21, 157, 103, 241, 242, -// 133, 154, 111, 209, 150, 58, 27, 91, 246, 10, 235, 126, 92, 240, 83, 51, 10, 243, 56, -// 144, 212, 216, 58, 89, 36, 118, 26, 81, 45, 8, 69, 151, 246, 98, 249, 136, 224, 39, 17, -// 151, 229, 63, 229, 167, 180, 58, 238, 133, 220, 151, 216, 6, 18, 67, 106, 19, 208, 239, -// 147, 103, 15, 9, 43, 150, 138, 63, 114, 223, 39, 178, 167, 88, 108, 68, 137, 196, 7, -// 87, 67, 219, 6, 103, 89, 250, 47, 135, 80, 200, 8, 250, 86, 208, 92, 77, 23, 91, 54, -// 246, 184, 76, 97, 185, 224, 128, 94, 25, 210, 175, 183, 130, 106, 111, 177, 223, 57, -// 56, 83, 209, 66, 59, 242, 98, 138, 122, 116, 193, 193, 244, 188, 197, 10, 89, 249, 255, -// 96, 83, 134, 105, 100, 243, 102, 244, 186, 78, 101, 241, 22, 103, 222, 138, 249, 252, -// 25, 106, 170, 243, 193, 94, 209, 196, 225, 10, 55, 8, 222, 255, 126, 193, 64, 195, 250, -// 172, 222, 26, 4, 51, 133, 153, 157, 95, 74, 29, 237, 100, 11, 252, 198, 14, 144, 239, -// 178, 54, 64, 179, 148, 200, 52, 183, 155, 172, 55, 58, 106, 90, 42, 28, 134, 95, 15, -// 159, 69, 174, 0, 24, 21, 64, 41, 118, 22, 185, 172, 185, 201, 9, 149, 237, 195, 112, -// 215, 77, 178, 75, 215, 176, 122, 110, 96, 202, 184, 79, 199, 3, 130, 133, 16, 149, 147, -// 119, 24, 81, 244, 124, 107, 102, 208, 159, 138, 186, 182, 104, 213, 116, 65, 130, 209, -// 199, 234, 106, 15, 23, 203, 245, 220, 194, 228, 197, 110, 40, 82, 249, 10, 81, 199, 78, -// 73, 100, 52, 109, 144, 150, 100, 254, 55, 160, 143, 124, 223, 155, 215, 62, 175, 166, -// 226, 226, 140, 122, 126, 74, 222, 190, 66, 211, 179, 46, 116, 140, 72, 243, 66, 102, -// 141, 169, 188, 168, 78, 193, 101, 138, 156, 111, 162, 89, 229, 3, 102, 249, 1, 105, 60, -// 7, 2, 35, 78, 121, 121, 33, 4, 222, 221, 45, 238, 125, 211, 118, 8, 15, 226, 1, 180, -// 134, 42, 87, 243, 130, 175, 150, 85, 130, 6, 227, 226, 202, 140, 123, 121, 9, 253, 178, -// 31, 224, 18, 78, 87, 245, 97, 116, 10, 93, 74, 51, 125, 210, 57, 183, 150, 236, 47, 52, -// 201, 222, 252, 38, 36, 185, 66, 56, 49, 13, 5, 112, 167, 182, 165, 119, 247, 217, 225, -// 71, 90, 18, 137, 63, 179, 221, 206, 95, 130, 71, 141, 130, 63, 173, 159, 46, 109, 66, -// 179, 191, 103, 147, 126, 115, 225, 137, 149, 225, 143, 159, 225, 46, 3, 122, 227, 124, -// 47, 104, 70, 225, 149, 169, 134, 134, 172, 108, 64, 91, 176, 112, 227, 209, 69, 234, -// 67, 38, 135, 139, 225, 18, 154, 66, 219, 239, 120, 247, 160, 23, 26, 243, 99, 64, 237, -// 91, 61, 206, 153, 203, 95, 226, 97, 33, 149, 251, 200, 247, 216, 87, 211, 221, 64, 4, -// 219, 135, 154, 105, 155, 39, 178, 237, 67, 87, 188, 223, 10, 14, 201, 199, 203, 27, -// 198, 1, 67, 20, 113, 165, 8, 243, 183, 167, 190, 98, 63, 67, 40, 56, 29, 202, 91, 130, -// 82, 182, 1, 125, 226, 31, 143, 241, 19, 158, 119, 84, 150, 87, 174, 103, 14, 41, 91, -// 213, 1, 117, 194, 15, 191, 64, 156, 231, 255, 226, 65, 87, 174, 144, 63, 57, 0, 125, -// 202, 189, 114, 113, 186, 24, 144, 100, 49, 163, 142, 63, 127, 180, 39, 140, 150, 76, -// 98, 254, 243, 216, 130, 132, 71, 124, 23, 172, 230, 200, 234, 226, 127, 200, 231, 14, -// 211, 254, 103, 123, 59, 251, 216, 210, 167, 218, 24, 145, 131, 56, 209, 180, 29, 121, -// 121, 221, 247, 169, 2, 244, 80, 170, 94, 160, 59, 8, 249, 95, 8, 76, 251, 42, 42, 196, -// 45, 77, 242, 52, 14, 215, 67, 222, 125, 92, 120, 73, 167, 243, 129, 130, 10, 71, 78, -// 192, 31, 136, 24, 104, 97, 191, 104, 53, 187, 38, 79, 107, 49, 253, 213, 105, 219, 95, -// 174, 79, 41, 175, 231, 55, 170, 131, 150, 89, 39, 200, 176, 20, 159, 135, 91, 248, 25, -// 202, 253, 168, 85, 128, 144, 49, 109, 58, 247, 3, 6, 232, 25, 81, 148, 100, 104, 45, -// 153, 58, 1, 120, 2, 228, 207, 112, 78, 23, 255, 151, 245, 50, 40, 10, 202, 237, 194, -// 75, 120, 106, 157, 213, 174, 36, 43, 177, 214, 187, 227, 42, 122, 222, 13, 231, 142, -// 36, 55, 43, 100, 29, 92, 227, 65, 32, 109, 73, 196, 212, 173, 243, 95, 114, 100, 57, -// 37, 174, 181, 126, 106, 192, 93, 51, 131, 161, 229, 42, 123, 136, 222, 25, 243, 237, -// 12, 240, 39, 52, 59, 140, 84, 177, 57, 141, 93, 2, 246, 79, 140, 122, 161, 17, 84, 92, -// 190, 59, 26, 193, 253, 110, 140, 166, 174, 191, 6, 172, 43, 236, 128, 201, 93, 128, 30, -// 214, 111, 127, 190, 73, 58, 149, 37, 81, 126, 180, 80, 23, 80, 207, 241, 118, 159, 125, -// 214, 141, 123, 159, 143, 81, 102, 112, 123, 121, 147, 89, 185, 204, 30, 36, 19, 5, 65, -// 204, 223, 163, 122, 168, 171, 67, 152, 179, 222, 160, 119, 172, 241, 178, 153, 249, -// 114, 17, 46, 86, 117, 28, 158, 109, 170, 33, 194, 62, 7, 56, 169, 19, 231, 62, 24, 253, -// 25, 131, 213, 152, 197, 34, 104, 177, 31, 119, 176, 223, 81, 174, 6, 55, 131, 69, 227, -// 148, 134, 94, 43, 165, 244, 11, 81, 248, 115, 139, 191, 254, 6, 226, 191, 101, 202, 42, -// 196, 152, 2, 6, 126, 130, 196, 102, 215, 51, 226, 212, 248, 184, 28, 30, 182, 56, 53, -// 86, 163, 24, 14, 2, 63, 189, 52, 221, 112, 210, 201, 172, 172, 85, 4, 184, 139, 8, 22, -// 40, 205, 193, 95, 247, 37, 183, 38, 40, 244, 243, 64, 199, 159, 172, 93, 133, 233, 75, -// 132, 199, 217, 24, 96, 31, 126, 17, 195, 146, 57, 204, 85, 26, 253, 64, 177, 43, 112, -// 172, 174, 32, 19, 124, 68, 242, 223, 182, 108, 51, 101, 130, 134, 243, 87, 89, 31, 213, -// 89, 246, 215, 19, 195, 194, 173, 74, 132, 195, 227, 44, 84, 38, 199, 25, 55, 250, 150, -// 141, 178, 189, 97, 71, 250, 68, 207, 198, 131, 96, 8, 26, 103, 115, 26, 13, 64, 213, -// 225, 226, 190, 41, 245, 101, 225, 247, 213, 39, 129, 61, 95, 107, 80, 181, 63, 47, 58, -// 20, 1, 97, 181, 162, 120, 40, 62, 201, 3, 161, 197, 46, 166, 96, +// 60, 34, 251, 165, 184, 202, 180, 28, 48, 182, 93, 120, 8, 0, 69, 0, 3, 140, 207, 254, +// 0, 0, 41, 17, 209, 24, 103, 107, 196, 187, 192, 168, 0, 123, 202, 108, 197, 122, 3, +// 120, 194, 63, 4, 0, 0, 0, 83, 21, 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, 89, 63, 69, 21, 228, +// 55, 113, 142, 1, 118, 235, 249, 212, 105, 246, 98, 106, 141, 246, 44, 178, 207, 93, +// 153, 171, 142, 137, 232, 240, 83, 30, 196, 120, 53, 181, 24, 123, 52, 20, 199, 87, 51, +// 45, 209, 25, 60, 95, 213, 80, 9, 2, 78, 90, 55, 118, 82, 6, 203, 205, 115, 128, 153, +// 198, 184, 75, 45, 162, 171, 140, 85, 96, 104, 245, 18, 123, 100, 197, 141, 206, 215, +// 111, 176, 175, 105, 132, 16, 201, 212, 17, 83, 118, 231, 252, 160, 8, 112, 123, 39, 92, +// 44, 71, 187, 191, 0, 82, 29, 160, 220, 229, 77, 177, 87, 176, 142, 2, 168, 158, 73, 71, +// 95, 248, 239, 195, 80, 210, 115, 244, 5, 105, 33, 73, 198, 152, 139, 7, 64, 54, 221, +// 30, 167, 225, 120, 253, 34, 111, 187, 0, 163, 50, 213, 192, 126, 66, 132, 35, 193, 78, +// 106, 60, 108, 214, 112, 110, 29, 150, 160, 81, 234, 124, 200, 205, 188, 69, 54, 248, +// 209, 168, 179, 221, 83, 126, 25, 106, 46, 47, 166, 111, 110, 103, 123, 23, 0, 23, 18, +// 222, 136, 159, 50, 166, 224, 16, 180, 59, 65, 34, 254, 150, 108, 176, 226, 181, 50, +// 167, 73, 218, 87, 90, 255, 120, 23, 188, 139, 23, 85, 44, 79, 114, 169, 135, 2, 14, 3, +// 62, 63, 80, 48, 144, 15, 148, 105, 244, 186, 212, 30, 90, 145, 234, 114, 155, 159, 137, +// 166, 58, 36, 31, 95, 93, 55, 145, 103, 176, 236, 196, 7, 92, 191, 3, 206, 133, 159, +// 131, 197, 144, 98, 106, 157, 13, 2, 84, 43, 100, 249, 197, 33, 6, 196, 74, 8, 21, 134, +// 160, 47, 161, 78, 78, 54, 211, 249, 21, 93, 85, 37, 47, 242, 185, 13, 18, 75, 88, 149, +// 234, 213, 165, 254, 210, 2, 208, 209, 151, 217, 111, 197, 148, 183, 111, 47, 110, 218, +// 134, 52, 233, 44, 195, 73, 177, 214, 138, 54, 119, 152, 40, 195, 42, 144, 109, 73, 220, +// 151, 159, 72, 56, 112, 160, 90, 44, 64, 180, 146, 118, 128, 20, 92, 4, 206, 126, 68, +// 67, 211, 72, 244, 110, 68, 243, 142, 110, 38, 151, 211, 211, 60, 97, 191, 127, 8, 118, +// 132, 27, 121, 207, 62, 202, 117, 155, 187, 56, 123, 29, 209, 7, 86, 70, 7, 205, 254, +// 194, 25, 163, 114, 20, 145, 98, 86, 67, 39, 110, 175, 213, 169, 66, 112, 18, 88, 131, +// 131, 22, 186, 54, 13, 226, 141, 184, 160, 87, 74, 248, 155, 9, 160, 205, 108, 83, 176, +// 34, 101, 87, 170, 75, 249, 128, 167, 46, 242, 155, 240, 108, 222, 221, 35, 147, 230, +// 221, 74, 150, 61, 147, 138, 133, 188, 41, 30, 109, 235, 159, 25, 27, 174, 90, 150, 89, +// 163, 107, 44, 123, 226, 8, 11, 184, 172, 30, 43, 28, 216, 177, 55, 185, 198, 191, 29, +// 135, 8, 23, 239, 183, 173, 112, 130, 10, 2, 240, 55, 252, 8, 118, 148, 131, 214, 35, +// 79, 149, 52, 226, 67, 175, 155, 87, 213, 140, 207, 104, 200, 128, 68, 72, 23, 107, 23, +// 37, 180, 230, 65, 127, 244, 127, 59, 254, 27, 16, 169, 0, 198, 117, 195, 181, 92, 9, +// 65, 202, 146, 144, 182, 255, 245, 231, 216, 193, 66, 105, 47, 245, 79, 80, 32, 230, +// 229, 167, 37, 100, 93, 41, 223, 65, 13, 116, 245, 160, 7, 104, 88, 77, 105, 177, 64, +// 168, 144, 23, 237, 240, 137, 71, 183, 198, 150, 173, 130, 121, 125, 114, 201, 248, 2, +// 114, 140, 91, 71, 72, 209, 52, 41, 162, 247, 0, 147, 79, 119, 131, 92, 232, 213, 19, +// 150, 151, 190, 14, 128, 122, 96, 227, 34, 46, 94, 37, 160, 110, 12, 105, 160, 177, 170, +// 197, 76, 0, 225, 174, 198, 129, 6, 248, 11, 33, 83, 91, 212, 68, 37, 178, 175, 49, 1, +// 230, 101, 174, 226, 176, 49, 67, 217, 60, 17, 217, 100, 244, 71, 33, 39, 76, 91, 21, +// 51, 57, 243, 222, 13, 43, 169, 185, 195, 27, 179, 61, 98, 46, 92, 174, 96, 33, 27, 75, +// 92, 227, 126, 234, 124, 41, 31, 233, 187, 139, 226, 175, 60, 229, 248, 166, 40, 41, +// 254, 225, 224, 174, 153, 167, 191, 214, 67, 237, 193, 125, 46, 159, 172, 172, 226, 112, +// 197, 233, 141, 203, 109, 160, 126, 171, 56, 211, 30, 113, 167, 31, 252, 39, 108, 21, +// 128, 96, 124, 139, 18, 138, 247, 190, 124, 31, 179, 232, 252, 85, 211, 27, 175, 19, +// 242, 26, 80, 139, 22, 19, 57, 38, 76, 34, 226, 199, 59, 186, 205, 27, 245, 29, 243, +// 110, 150, 216, 28, 134, 237, 83, 73, 53, 206, 240, 146, 85, 230, 128, 122, 237, 51, +// 118, 49, 114, 123, 6, 99, 51, 82, 174, 180, 80, 82, 233, 1, 151, 236, 241, 184, 105, +// 184, 6, 36, 186, 231, 36, 204, 14, 27, 218, 4, 241, 87, 134, 186, 60, 6, 214, 253, 217, +// 186, 182, 110, 58, 117, 128, 31, 10, 89, 1, 2, 3, 4 // ]; // let packets: [u8; 1436] = [ @@ -168,7 +140,8 @@ pub mod parsers; // ]; // let ether_frame = parsers::ethernet_frame::EthernetFrame::from_bytes(&frames).unwrap(); + // let layered_data = ether_frame.parse_next_layer().unwrap(); -// println!("Packet: {:?}", layered_data); +// println!("Layered Data: {:?}", layered_data); // } // } diff --git a/src/parsers/definitions.rs b/src/parsers/definitions.rs index 32dc34d..021e2a8 100644 --- a/src/parsers/definitions.rs +++ b/src/parsers/definitions.rs @@ -1,4 +1,3 @@ -// Main module imports necessary for parsing operations. use super::{ errors::ParserError, ethernet_frame::EthernetFrame, icmp::IcmpPacket, ipv4::Ipv4Packet, ipv6::Ipv6Packet, tcp::TcpSegment, udp::UdpDatagram, diff --git a/src/parsers/errors.rs b/src/parsers/errors.rs index eb73361..80ef72c 100644 --- a/src/parsers/errors.rs +++ b/src/parsers/errors.rs @@ -53,4 +53,7 @@ pub enum ParserError { #[error("Unknown ether type type")] UnSupportedEtherType, + + #[error("Exceeded MAC range `{0}`")] + MacRangeExceeded(u128), } diff --git a/src/parsers/ethernet_frame.rs b/src/parsers/ethernet_frame.rs index e1a367d..77e794d 100644 --- a/src/parsers/ethernet_frame.rs +++ b/src/parsers/ethernet_frame.rs @@ -18,10 +18,10 @@ use super::{ constants, definitions::{DeepParser, EtherType, LayeredData}, - errors::{ErrorSource, ParserError}, + errors::ParserError, ipv4::Ipv4Packet, ipv6::Ipv6Packet, - utils::{read_arbitrary_length, read_u16, read_u32}, + utils::{read_arbitrary_length, read_u128, read_u16, read_u32}, }; use std::fmt; @@ -65,10 +65,6 @@ impl fmt::Display for MacAddress { // Constants representing various parameters and offsets within an Ethernet frame. // These are used for parsing the frame correctly. const TPID_VLAN: u32 = 33024; // [0x81, 0x00]; -const Q_TAG_OR_ETHER_TYPE_OFFSET: u64 = 12; -const BITMASK_Q_TAG: u32 = 0xFFFFFFFF; -const OFFSET_MAC_DEST: usize = 0; -const OFFSET_MAC_SRC: usize = 6; #[derive(Debug, PartialEq)] /// Represents the header of an Ethernet frame. @@ -145,79 +141,63 @@ impl EthernetFrame { if frame.len() < constants::MIN_FRAME_SIZE { return Err(ParserError::InvalidLength); } - - let mac_destination_bytes: [u8; 6] = - EthernetFrame::extract_mac_address(&frame, OFFSET_MAC_DEST)?; - - let mac_source_bytes: [u8; 6] = Self::extract_mac_address(&frame, OFFSET_MAC_SRC)?; - let mut cursor: Cursor<&[u8]> = Cursor::new(frame); - // Since we already extracted the MAC addresses, we move the cursor - // to the next index after the MAC addresses. - cursor - .seek(SeekFrom::Start(Q_TAG_OR_ETHER_TYPE_OFFSET)) - .map_err(|e| ParserError::CursorError { - string: "Options".to_string(), - source: e, - })?; - let q_tag_ether_bytes = read_u32(&mut cursor, "QTAG_&_ETHERTYPE")?; + let (mac_destination, mac_source, q_tag, ether_type) = Self::extract_header(&mut cursor)?; - let (q_tag, ether_type) = - Self::parse_vlan_tag_and_ether_type(&mut cursor, q_tag_ether_bytes)?; - - let fcs_offset = frame.len() - 4; - let data_size = fcs_offset as u64 - cursor.position(); - let data = read_arbitrary_length(&mut cursor, data_size as usize, "EtherFrame_Data")?; + let data = read_arbitrary_length( + &mut cursor, + Self::data_size(frame.len(), q_tag), + "EtherFrame_Data", + )?; Ok(EthernetFrame { header: EthernetFrameHeader { - mac_destination: MacAddress::from_bytes(mac_destination_bytes), - mac_source: MacAddress::from_bytes(mac_source_bytes), + mac_destination, + mac_source, q_tag, - ether_type: EtherType::from(ether_type), + ether_type, }, data: Box::new(LayeredData::Payload(data)), }) } - /// Parses the VLAN tag (if present) and the EtherType from a segment of network packet data. + /// Extracts the Ethernet frame header from a byte stream. /// - /// Given a cursor reference within a network packet and a 4-byte segment that potentially contains - /// VLAN tagging information (Q-tag) and EtherType, this function discerns whether a VLAN tag is - /// present and extracts the EtherType. It adjusts the cursor position based on the presence of the - /// VLAN tag. + /// This function parses the destination and source MAC addresses, optional VLAN tag (QTag), + /// and EtherType from the provided byte stream accessed via a cursor. /// - /// The function operates by examining the two higher-order bytes of `q_tag_ether_bytes` for the - /// VLAN TPID. If the TPID indicates a VLAN tag, the tag is extracted along with the EtherType. - /// If not, the cursor is adjusted, assuming the two bytes are part of the EtherType, not a VLAN tag. - /// - /// # Arguments - /// - /// * `cursor` - A mutable reference to a cursor positioned at the relevant segment - /// of a network packet data slice. - /// * `q_tag_ether_bytes` - A 32-bit value possibly containing a VLAN tag and EtherType, - /// specifically the two bytes for the potential tag and two bytes for the EtherType. + /// # Parameters + /// * `cursor`: A mutable reference to a cursor over the byte slice containing the Ethernet frame. /// /// # Returns + /// * `Ok((MacAddress, MacAddress, Option, EtherType))`: A tuple containing the destination MAC + /// address, the source MAC address, an optional VLAN tag (QTag), and the EtherType if successful. + /// * `Err(ParserError)`: An error if the header could not be parsed, which could be due to + /// insufficient data, unrecognized EtherType, or other parsing issues. /// - /// This function returns a tuple containing two elements wrapped in `Result`: - /// * `Option` - The VLAN tag present as a 32-bit value, or `None` if a VLAN tag isn't found. - /// * `u16` - The 16-bit EtherType value extracted from the packet data. - fn parse_vlan_tag_and_ether_type( + /// # Errors + /// This function will return an error if the byte slice does not contain enough data for a + /// complete Ethernet header, if the EtherType is not one of the accepted types, or if any + /// other parsing issue occurs. + fn extract_header( cursor: &mut Cursor<&[u8]>, - q_tag_ether_bytes: u32, - ) -> Result<(Option, u16), ParserError> { - let (q_tag, ether_type) = match q_tag_ether_bytes >> 16 { + ) -> Result<(MacAddress, MacAddress, Option, EtherType), ParserError> { + let bytes = read_u128(cursor, "Ethernet_Header")?; + let mac_dest = Self::extract_mac_address(((bytes >> 80) & 0xFFFFFFFFFFFF) as u64); + let mac_src = Self::extract_mac_address(((bytes >> 32) & 0xFFFFFFFFFFFF) as u64); + let leftover_bytes = (bytes & 0xFFFFFFFF) as u32; + + let (q_tag, ether_type) = match leftover_bytes >> 16 { TPID_VLAN => { - let e_t = read_u16(cursor, "Ether Type")?; - (Some(q_tag_ether_bytes & BITMASK_Q_TAG), e_t) + let ether_type = read_u16(cursor, "Ether_Type")?; + (Some(leftover_bytes), ether_type) } _ => { // QTag isn't present in the frame, hence we move the cursor // back 2 positions. cursor.set_position(cursor.position() - 2); - (None, (q_tag_ether_bytes >> 16) as u16) + (None, (leftover_bytes >> 16) as u16) } }; @@ -225,41 +205,43 @@ impl EthernetFrame { return Err(ParserError::InvalidEtherType); } - Ok((q_tag, ether_type)) + Ok((mac_dest, mac_src, q_tag, EtherType::from(ether_type))) } - /// Extracts a MAC address from the ethernet frame based on a specified offset. + /// Extracts a MAC address from a 64-bit integer. /// - /// The function attempts to retrieve a MAC address, typically used for - /// either source or destination MAC extraction, starting from the given offset. + /// The MAC address is assumed to be in the lower 48 bits of the value, + /// in big-endian order. This function reads the individual bytes that + /// make up the MAC address and returns a `MacAddress` instance. /// /// # Arguments /// - /// * `frame` - The byte slice representing the ethernet frame. - /// * `offset` - Starting index within `frame` where the MAC address is expected to begin. + /// * `value` - A `u64` value containing the MAC address in its lower 48 bits. /// /// # Returns /// - /// * `Ok` with the MAC address as a byte array if extraction is successful. - /// * `Err` with an associated `EthernetFrameError` detailing the cause of the failure. - /// - /// # Errors - /// - /// * `EthernetFrameError::InvalidMacBytes` if the frame doesn't contain - /// enough bytes from the offset to extract a MAC address. - /// * `EthernetFrameError::MacAddressExtractionError` if there's an issue - /// during the extraction process. - fn extract_mac_address(frame: &[u8], offset: usize) -> Result<[u8; 6], ParserError> { - if frame.len() < offset + 6 { - return Err(ParserError::InvalidLength); - } + /// A `MacAddress` instance created from the extracted bytes. + fn extract_mac_address(value: u64) -> MacAddress { + // The MAC address lies in the 48 LSBs. + let bytes: [u8; 6] = [ + ((value >> 40) & 0xFF) as u8, + ((value >> 32) & 0xFF) as u8, + ((value >> 24) & 0xFF) as u8, + ((value >> 16) & 0xFF) as u8, + ((value >> 8) & 0xFF) as u8, + (value & 0xFF) as u8, + ]; + + MacAddress::from_bytes(bytes) + } + + fn data_size(frame_size: usize, q_tag: Option) -> usize { + let header_size_without_q_tag = 14; // Header size (excluding the VLAN field) is 14 bytes + let vlan_tag_size = q_tag.map_or(0, |_| 4); // VLAN tag is 4 bytes if present + let fcs_size = 4; // Frame Check Sequence is 4 bytes - frame[offset..offset + 6] - .try_into() - .map_err(|e| ParserError::ExtractionError { - source: ErrorSource::TryFromSlice(e), - string: "Src/Dest MAC Address".to_string(), - }) + // Calculate payload size by subtracting the header size and FCS from the frame size + frame_size - (header_size_without_q_tag + vlan_tag_size + fcs_size) } } diff --git a/src/parsers/ipv4.rs b/src/parsers/ipv4.rs index 79e4811..7ef1606 100644 --- a/src/parsers/ipv4.rs +++ b/src/parsers/ipv4.rs @@ -127,9 +127,7 @@ impl Ipv4Packet { let type_of_service = read_u8(&mut cursor, "ToS")?; let total_length = read_u16(&mut cursor, "Total Length")?; - let identification = read_u16(&mut cursor, "Identification")?; - let flags_fragment = read_u16(&mut cursor, "Flags & Fragment")?; // Right shift the byte `flags_fragment` 13 times to get the flags diff --git a/src/parsers/utils.rs b/src/parsers/utils.rs index b2ba4af..f3e4a6c 100644 --- a/src/parsers/utils.rs +++ b/src/parsers/utils.rs @@ -89,6 +89,19 @@ pub fn read_u16(cursor: &mut Cursor<&[u8]>, field: &str) -> Result, field: &str) -> Result { + let mut buffer: [u8; 16] = Default::default(); + + cursor + .read_exact(&mut buffer) + .map_err(|e| ParserError::ExtractionError { + string: field.to_string(), + source: ErrorSource::Io(e), + })?; + + Ok(u128::from_be_bytes(buffer)) +} + pub fn read_u8(cursor: &mut Cursor<&[u8]>, field: &str) -> Result { let mut buffer: [u8; 1] = Default::default();