Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create v6::OROCodes (#1) #38

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
7 changes: 7 additions & 0 deletions src/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ impl<'a> Decoder<'a> {
Ok(u8::from_be_bytes(self.peek::<{ mem::size_of::<u8>() }>()?))
}

/// peek at the next u16 without advancing the internal pointer
pub fn peek_u16(&self) -> DecodeResult<u16> {
Ok(u16::from_be_bytes(
self.peek::<{ mem::size_of::<u16>() }>()?,
))
}

/// read a u8
pub fn read_u8(&mut self) -> DecodeResult<u8> {
Ok(u8::from_be_bytes(self.read::<{ mem::size_of::<u8>() }>()?))
Expand Down
90 changes: 90 additions & 0 deletions src/v6/duid.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

use crate::v4::HType;
use crate::v6::{DecodeResult, EncodeResult, Ipv6Addr};
use crate::{Decodable, Decoder, Encodable, Encoder};

/// Duid helper type
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Duid(Vec<u8>);
// TODO: define specific duid types

impl Duid {
/// new DUID link layer address with time
pub fn link_layer_time(htype: HType, time: u32, addr: Ipv6Addr) -> Self {
let mut buf = Vec::new();
let mut e = Encoder::new(&mut buf);
e.write_u16(1).unwrap(); // duid type
e.write_u16(u8::from(htype) as u16).unwrap();
e.write_u32(time).unwrap();
e.write_u128(addr.into()).unwrap();
Self(buf)
}
/// new DUID enterprise number
pub fn enterprise(enterprise: u32, id: &[u8]) -> Self {
let mut buf = Vec::new();
let mut e = Encoder::new(&mut buf);
e.write_u16(2).unwrap(); // duid type
e.write_u32(enterprise).unwrap();
e.write_slice(id).unwrap();
Self(buf)
}
/// new link layer DUID
pub fn link_layer(htype: HType, addr: Ipv6Addr) -> Self {
let mut buf = Vec::new();
let mut e = Encoder::new(&mut buf);
e.write_u16(3).unwrap(); // duid type
e.write_u16(u8::from(htype) as u16).unwrap();
e.write_u128(addr.into()).unwrap();
Self(buf)
}
/// new DUID-UUID
/// `uuid` must be 16 bytes long
pub fn uuid(uuid: &[u8]) -> Self {
assert!(uuid.len() == 16);
let mut buf = Vec::new();
let mut e = Encoder::new(&mut buf);
e.write_u16(4).unwrap(); // duid type
e.write_slice(uuid).unwrap();
Self(buf)
}
/// create a DUID of unknown type
pub fn unknown(duid: &[u8]) -> Self {
Self(duid.to_vec())
}
/// total length of contained DUID
pub fn len(&self) -> usize {
self.0.len()
}
/// is contained DUID empty
pub fn is_empty(&self) -> bool {
self.len() == 0
}
}

impl AsRef<[u8]> for Duid {
fn as_ref(&self) -> &[u8] {
&self.0
}
}

impl From<Vec<u8>> for Duid {
fn from(v: Vec<u8>) -> Self {
Self(v)
}
}

impl Decodable for Duid {
fn decode(decoder: &'_ mut Decoder<'_>) -> DecodeResult<Self> {
Ok(Duid(decoder.buffer().into()))
}
}

impl Encodable for Duid {
fn encode(&self, e: &'_ mut Encoder<'_>) -> EncodeResult<()> {
e.write_slice(&self.0)?;
Ok(())
}
}
Loading