about summary refs log tree commit diff
path: root/src/layer3.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/layer3.rs')
-rw-r--r--src/layer3.rs65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/layer3.rs b/src/layer3.rs
new file mode 100644
index 0000000..7521c0d
--- /dev/null
+++ b/src/layer3.rs
@@ -0,0 +1,65 @@
+pub struct Tcp<'p> {
+	src: u16,
+	dst: u16,
+	payload: &'p [u8],
+}
+
+impl<'p> Tcp<'p> {
+	pub fn new(buffer: &'p [u8]) -> Self {
+		let src = u16::from_be_bytes([buffer[0], buffer[1]]);
+		let dst = u16::from_be_bytes([buffer[2], buffer[3]]);
+		let data_offset = (buffer[12].to_be() & 0b1111_0000) >> 4;
+		// Offset is number of 32-bit words
+		let true_offset = data_offset as usize * 4;
+
+		Self {
+			src,
+			dst,
+			payload: &buffer[true_offset..],
+		}
+	}
+
+	pub fn source_port(&self) -> u16 {
+		self.src
+	}
+
+	pub fn destination_port(&self) -> u16 {
+		self.dst
+	}
+
+	pub fn payload(&self) -> &[u8] {
+		self.payload
+	}
+}
+
+pub struct Udp<'p> {
+	src: u16,
+	dst: u16,
+	payload: &'p [u8],
+}
+
+impl<'p> Udp<'p> {
+	pub fn new(buffer: &'p [u8]) -> Self {
+		let src = u16::from_be_bytes([buffer[0], buffer[1]]);
+		let dst = u16::from_be_bytes([buffer[2], buffer[3]]);
+		let _len = u16::from_be_bytes([buffer[4], buffer[5]]);
+
+		Self {
+			src,
+			dst,
+			payload: &buffer[8..],
+		}
+	}
+
+	pub fn source_port(&self) -> u16 {
+		self.src
+	}
+
+	pub fn destination_port(&self) -> u16 {
+		self.dst
+	}
+
+	pub fn payload(&self) -> &[u8] {
+		self.payload
+	}
+}