packet/ip/v6/
packet.rs

1//            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
2//                    Version 2, December 2004
3//
4// Copyleft (ↄ) meh. <meh@schizofreni.co> | http://meh.schizofreni.co
5//
6// Everyone is permitted to copy and distribute verbatim or modified
7// copies of this license document, and changing it is allowed as long
8// as the name is changed.
9//
10//            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
11//   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
12//
13//  0. You just DO WHAT THE FUCK YOU WANT TO.
14
15use std::fmt;
16use crate::error::*;
17use crate::packet::{Packet as P, PacketMut as PM, AsPacket, AsPacketMut};
18
19/// IPv6 packet parser.
20#[derive(Clone)]
21pub struct Packet<B> {
22	buffer: B,
23}
24
25sized!(Packet,
26	header {
27		min:  0,
28		max:  0,
29		size: 0,
30	}
31
32	payload {
33		min:  0,
34		max:  0,
35		size: 0,
36	});
37
38impl<B: AsRef<[u8]>> fmt::Debug for Packet<B> {
39	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40		f.debug_struct("ip::v6::Packet")
41			.finish()
42	}
43}
44
45impl<B: AsRef<[u8]>> Packet<B> {
46	/// Create an IPv6 packet without checking the buffer.
47	pub fn unchecked(buffer: B) -> Packet<B> {
48		Packet { buffer }
49	}
50
51	/// Parse an IPv6 packet without checking the payload.
52	pub fn no_payload(buffer: B) -> Result<Packet<B>> {
53		use crate::size::header::Min;
54
55		let packet = Packet::unchecked(buffer);
56
57		if packet.buffer.as_ref().len() < Self::min() {
58			Err(Error::SmallBuffer)?
59		}
60
61		if packet.buffer.as_ref()[0] >> 4 != 6 {
62			Err(Error::InvalidPacket)?
63		}
64
65		Ok(packet)
66	}
67
68	/// Parse an IPv6 packet, checking the buffer contents are correct.
69	pub fn new(buffer: B) -> Result<Packet<B>> {
70		Packet::no_payload(buffer)
71	}
72}
73
74impl<B: AsRef<[u8]>> Packet<B> {
75	/// Convert the packet to its owned version.
76	///
77	/// # Notes
78	///
79	/// It would be nice if `ToOwned` could be implemented, but `Packet` already
80	/// implements `Clone` and the impl would conflict.
81	pub fn to_owned(&self) -> Packet<Vec<u8>> {
82		Packet::unchecked(self.buffer.as_ref().to_vec())
83	}
84}
85
86impl<B: AsRef<[u8]>> AsRef<[u8]> for Packet<B> {
87	fn as_ref(&self) -> &[u8] {
88		&[]
89	}
90}
91
92impl<B: AsRef<[u8]> + AsMut<[u8]>> AsMut<[u8]> for Packet<B> {
93	fn as_mut(&mut self) -> &mut [u8] {
94		&mut []
95	}
96}
97
98impl<'a, B: AsRef<[u8]>> AsPacket<'a, Packet<&'a [u8]>> for B {
99	fn as_packet(&self) -> Result<Packet<&[u8]>> {
100		Packet::new(self.as_ref())
101	}
102}
103
104impl<'a, B: AsRef<[u8]> + AsMut<[u8]>> AsPacketMut<'a, Packet<&'a mut [u8]>> for B {
105	fn as_packet_mut(&mut self) -> Result<Packet<&mut [u8]>> {
106		Packet::new(self.as_mut())
107	}
108}
109
110impl<B: AsRef<[u8]>> P for Packet<B> {
111	fn split(&self) -> (&[u8], &[u8]) {
112		(&[], &[])
113	}
114}
115
116impl<B: AsRef<[u8]> + AsMut<[u8]>> PM for Packet<B> {
117	fn split_mut(&mut self) -> (&mut [u8], &mut [u8]) {
118		(&mut [], &mut [])
119	}
120}