mirror of
https://github.com/smoltcp-rs/smoltcp.git
synced 2025-10-01 23:01:11 +00:00
add addr resolv with context
This commit is contained in:
parent
fc69cdbe3c
commit
d2e8e993fe
@ -43,6 +43,7 @@ fuzz_target!(|fuzz: SixlowpanPacketFuzzer| {
|
|||||||
&frame,
|
&frame,
|
||||||
fuzz.ll_src_addr.map(Into::into),
|
fuzz.ll_src_addr.map(Into::into),
|
||||||
fuzz.ll_dst_addr.map(Into::into),
|
fuzz.ll_dst_addr.map(Into::into),
|
||||||
|
&[],
|
||||||
) {
|
) {
|
||||||
let mut buffer = vec![0; iphc_repr.buffer_len()];
|
let mut buffer = vec![0; iphc_repr.buffer_len()];
|
||||||
let mut iphc_frame = SixlowpanIphcPacket::new_unchecked(&mut buffer[..]);
|
let mut iphc_frame = SixlowpanIphcPacket::new_unchecked(&mut buffer[..]);
|
||||||
|
@ -247,6 +247,8 @@ pub struct InterfaceInner<'a> {
|
|||||||
pan_id: Option<Ieee802154Pan>,
|
pan_id: Option<Ieee802154Pan>,
|
||||||
#[cfg(feature = "proto-ipv4-fragmentation")]
|
#[cfg(feature = "proto-ipv4-fragmentation")]
|
||||||
ipv4_id: u16,
|
ipv4_id: u16,
|
||||||
|
#[cfg(feature = "proto-sixlowpan")]
|
||||||
|
sixlowpan_address_context: &'a [SixlowpanAddressContext<'a>],
|
||||||
#[cfg(feature = "proto-sixlowpan-fragmentation")]
|
#[cfg(feature = "proto-sixlowpan-fragmentation")]
|
||||||
tag: u16,
|
tag: u16,
|
||||||
ip_addrs: ManagedSlice<'a, IpCidr>,
|
ip_addrs: ManagedSlice<'a, IpCidr>,
|
||||||
@ -289,6 +291,9 @@ pub struct InterfaceBuilder<'a> {
|
|||||||
sixlowpan_reassembly_buffer_timeout: Duration,
|
sixlowpan_reassembly_buffer_timeout: Duration,
|
||||||
#[cfg(feature = "proto-sixlowpan-fragmentation")]
|
#[cfg(feature = "proto-sixlowpan-fragmentation")]
|
||||||
sixlowpan_out_buffer: ManagedSlice<'a, u8>,
|
sixlowpan_out_buffer: ManagedSlice<'a, u8>,
|
||||||
|
|
||||||
|
#[cfg(feature = "proto-sixlowpan")]
|
||||||
|
sixlowpan_address_context: &'a [SixlowpanAddressContext<'a>],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> InterfaceBuilder<'a> {
|
impl<'a> InterfaceBuilder<'a> {
|
||||||
@ -362,6 +367,9 @@ let iface = builder.finalize(&mut device);
|
|||||||
sixlowpan_reassembly_buffer_timeout: Duration::from_secs(60),
|
sixlowpan_reassembly_buffer_timeout: Duration::from_secs(60),
|
||||||
#[cfg(feature = "proto-sixlowpan-fragmentation")]
|
#[cfg(feature = "proto-sixlowpan-fragmentation")]
|
||||||
sixlowpan_out_buffer: ManagedSlice::Borrowed(&mut [][..]),
|
sixlowpan_out_buffer: ManagedSlice::Borrowed(&mut [][..]),
|
||||||
|
|
||||||
|
#[cfg(feature = "proto-sixlowpan")]
|
||||||
|
sixlowpan_address_context: &[],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -473,12 +481,14 @@ let iface = builder.finalize(&mut device);
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the IPv4 reassembly buffer the interface will use.
|
||||||
#[cfg(feature = "proto-ipv4-fragmentation")]
|
#[cfg(feature = "proto-ipv4-fragmentation")]
|
||||||
pub fn ipv4_reassembly_buffer(mut self, storage: PacketAssemblerSet<'a, Ipv4FragKey>) -> Self {
|
pub fn ipv4_reassembly_buffer(mut self, storage: PacketAssemblerSet<'a, Ipv4FragKey>) -> Self {
|
||||||
self.ipv4_fragments = storage;
|
self.ipv4_fragments = storage;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the IPv4 fragments buffer the interface will use.
|
||||||
#[cfg(feature = "proto-ipv4-fragmentation")]
|
#[cfg(feature = "proto-ipv4-fragmentation")]
|
||||||
pub fn ipv4_fragmentation_buffer<T>(mut self, storage: T) -> Self
|
pub fn ipv4_fragmentation_buffer<T>(mut self, storage: T) -> Self
|
||||||
where
|
where
|
||||||
@ -488,6 +498,17 @@ let iface = builder.finalize(&mut device);
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the address contexts the interface will use.
|
||||||
|
#[cfg(feature = "proto-sixlowpan")]
|
||||||
|
pub fn sixlowpan_address_context(
|
||||||
|
mut self,
|
||||||
|
sixlowpan_address_context: &'a [SixlowpanAddressContext<'a>],
|
||||||
|
) -> Self {
|
||||||
|
self.sixlowpan_address_context = sixlowpan_address_context;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the 6LoWPAN reassembly buffer the interface will use.
|
||||||
#[cfg(feature = "proto-sixlowpan-fragmentation")]
|
#[cfg(feature = "proto-sixlowpan-fragmentation")]
|
||||||
pub fn sixlowpan_reassembly_buffer(
|
pub fn sixlowpan_reassembly_buffer(
|
||||||
mut self,
|
mut self,
|
||||||
@ -497,6 +518,7 @@ let iface = builder.finalize(&mut device);
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the timeout value the 6LoWPAN reassembly buffer will use.
|
||||||
#[cfg(feature = "proto-sixlowpan-fragmentation")]
|
#[cfg(feature = "proto-sixlowpan-fragmentation")]
|
||||||
pub fn sixlowpan_reassembly_buffer_timeout(mut self, timeout: Duration) -> Self {
|
pub fn sixlowpan_reassembly_buffer_timeout(mut self, timeout: Duration) -> Self {
|
||||||
if timeout > Duration::from_secs(60) {
|
if timeout > Duration::from_secs(60) {
|
||||||
@ -506,6 +528,7 @@ let iface = builder.finalize(&mut device);
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the 6LoWPAN fragments buffer the interface will use.
|
||||||
#[cfg(feature = "proto-sixlowpan-fragmentation")]
|
#[cfg(feature = "proto-sixlowpan-fragmentation")]
|
||||||
pub fn sixlowpan_fragmentation_buffer<T>(mut self, storage: T) -> Self
|
pub fn sixlowpan_fragmentation_buffer<T>(mut self, storage: T) -> Self
|
||||||
where
|
where
|
||||||
@ -651,6 +674,8 @@ let iface = builder.finalize(&mut device);
|
|||||||
tag,
|
tag,
|
||||||
#[cfg(feature = "proto-ipv4-fragmentation")]
|
#[cfg(feature = "proto-ipv4-fragmentation")]
|
||||||
ipv4_id,
|
ipv4_id,
|
||||||
|
#[cfg(feature = "proto-sixlowpan")]
|
||||||
|
sixlowpan_address_context: &[],
|
||||||
rand,
|
rand,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -1534,6 +1559,9 @@ impl<'a> InterfaceInner<'a> {
|
|||||||
#[cfg(feature = "proto-sixlowpan-fragmentation")]
|
#[cfg(feature = "proto-sixlowpan-fragmentation")]
|
||||||
tag: 1,
|
tag: 1,
|
||||||
|
|
||||||
|
#[cfg(feature = "proto-sixlowpan")]
|
||||||
|
sixlowpan_address_context: &[],
|
||||||
|
|
||||||
#[cfg(feature = "proto-ipv4-fragmentation")]
|
#[cfg(feature = "proto-ipv4-fragmentation")]
|
||||||
ipv4_id: 1,
|
ipv4_id: 1,
|
||||||
|
|
||||||
@ -1804,6 +1832,7 @@ impl<'a> InterfaceInner<'a> {
|
|||||||
&iphc,
|
&iphc,
|
||||||
ieee802154_repr.src_addr,
|
ieee802154_repr.src_addr,
|
||||||
ieee802154_repr.dst_addr,
|
ieee802154_repr.dst_addr,
|
||||||
|
self.sixlowpan_address_context
|
||||||
));
|
));
|
||||||
|
|
||||||
// The uncompressed header size always starts with 40, since this is the size
|
// The uncompressed header size always starts with 40, since this is the size
|
||||||
@ -1888,6 +1917,7 @@ impl<'a> InterfaceInner<'a> {
|
|||||||
&iphc_packet,
|
&iphc_packet,
|
||||||
ieee802154_repr.src_addr,
|
ieee802154_repr.src_addr,
|
||||||
ieee802154_repr.dst_addr,
|
ieee802154_repr.dst_addr,
|
||||||
|
self.sixlowpan_address_context,
|
||||||
));
|
));
|
||||||
|
|
||||||
let payload = iphc_packet.payload();
|
let payload = iphc_packet.payload();
|
||||||
|
@ -151,7 +151,7 @@ pub use self::sixlowpan::{
|
|||||||
NhcPacket as SixlowpanNhcPacket, UdpNhcPacket as SixlowpanUdpNhcPacket,
|
NhcPacket as SixlowpanNhcPacket, UdpNhcPacket as SixlowpanUdpNhcPacket,
|
||||||
UdpNhcRepr as SixlowpanUdpNhcRepr,
|
UdpNhcRepr as SixlowpanUdpNhcRepr,
|
||||||
},
|
},
|
||||||
NextHeader as SixlowpanNextHeader, SixlowpanPacket,
|
AddressContext as SixlowpanAddressContext, NextHeader as SixlowpanNextHeader, SixlowpanPacket,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "medium-ieee802154")]
|
#[cfg(feature = "medium-ieee802154")]
|
||||||
|
@ -2,11 +2,25 @@
|
|||||||
//! IEEE802.154-based networks.
|
//! IEEE802.154-based networks.
|
||||||
//!
|
//!
|
||||||
//! [RFC 6282]: https://datatracker.ietf.org/doc/html/rfc6282
|
//! [RFC 6282]: https://datatracker.ietf.org/doc/html/rfc6282
|
||||||
|
use core::ops::Deref;
|
||||||
|
|
||||||
use super::{Error, Result};
|
use super::{Error, Result};
|
||||||
use crate::wire::ieee802154::Address as LlAddress;
|
use crate::wire::ieee802154::Address as LlAddress;
|
||||||
use crate::wire::ipv6;
|
use crate::wire::ipv6;
|
||||||
use crate::wire::IpProtocol;
|
use crate::wire::IpProtocol;
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||||
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
|
pub struct AddressContext<'a>(pub &'a [u8]);
|
||||||
|
|
||||||
|
impl<'a> Deref for AddressContext<'a> {
|
||||||
|
type Target = [u8];
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The representation of an unresolved address. 6LoWPAN compression of IPv6 addresses can be with
|
/// The representation of an unresolved address. 6LoWPAN compression of IPv6 addresses can be with
|
||||||
/// and without context information. The decompression with context information is not yet
|
/// and without context information. The decompression with context information is not yet
|
||||||
/// implemented.
|
/// implemented.
|
||||||
@ -14,7 +28,7 @@ use crate::wire::IpProtocol;
|
|||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
pub enum UnresolvedAddress<'a> {
|
pub enum UnresolvedAddress<'a> {
|
||||||
WithoutContext(AddressMode<'a>),
|
WithoutContext(AddressMode<'a>),
|
||||||
WithContext(AddressMode<'a>),
|
WithContext((usize, AddressMode<'a>)),
|
||||||
Reserved,
|
Reserved,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,8 +65,30 @@ const LINK_LOCAL_PREFIX: [u8; 2] = [0xfe, 0x80];
|
|||||||
const EUI64_MIDDLE_VALUE: [u8; 2] = [0xff, 0xfe];
|
const EUI64_MIDDLE_VALUE: [u8; 2] = [0xff, 0xfe];
|
||||||
|
|
||||||
impl<'a> UnresolvedAddress<'a> {
|
impl<'a> UnresolvedAddress<'a> {
|
||||||
pub fn resolve(self, ll_address: Option<LlAddress>) -> Result<ipv6::Address> {
|
pub fn resolve(
|
||||||
|
self,
|
||||||
|
ll_address: Option<LlAddress>,
|
||||||
|
addr_context: &[AddressContext<'_>],
|
||||||
|
) -> Result<ipv6::Address> {
|
||||||
let mut bytes = [0; 16];
|
let mut bytes = [0; 16];
|
||||||
|
|
||||||
|
let copy_context = |index: usize, bytes: &mut [u8]| -> Result<()> {
|
||||||
|
if index >= addr_context.len() {
|
||||||
|
return Err(Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
let context = addr_context[index];
|
||||||
|
let len = context.len();
|
||||||
|
|
||||||
|
if len > 8 {
|
||||||
|
return Err(Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes[..len].copy_from_slice(&context);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
};
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
UnresolvedAddress::WithoutContext(mode) => match mode {
|
UnresolvedAddress::WithoutContext(mode) => match mode {
|
||||||
AddressMode::FullInline(addr) => Ok(ipv6::Address::from_bytes(addr)),
|
AddressMode::FullInline(addr) => Ok(ipv6::Address::from_bytes(addr)),
|
||||||
@ -104,8 +140,35 @@ impl<'a> UnresolvedAddress<'a> {
|
|||||||
_ => Err(Error),
|
_ => Err(Error),
|
||||||
},
|
},
|
||||||
UnresolvedAddress::WithContext(mode) => match mode {
|
UnresolvedAddress::WithContext(mode) => match mode {
|
||||||
AddressMode::Unspecified => Ok(ipv6::Address::UNSPECIFIED),
|
(_, AddressMode::Unspecified) => Ok(ipv6::Address::UNSPECIFIED),
|
||||||
AddressMode::NotSupported => Err(Error),
|
(index, AddressMode::InLine64bits(inline)) => {
|
||||||
|
copy_context(index, &mut bytes[..])?;
|
||||||
|
bytes[16 - inline.len()..].copy_from_slice(inline);
|
||||||
|
Ok(ipv6::Address::from_bytes(&bytes[..]))
|
||||||
|
}
|
||||||
|
(index, AddressMode::InLine16bits(inline)) => {
|
||||||
|
copy_context(index, &mut bytes[..])?;
|
||||||
|
bytes[16 - inline.len()..].copy_from_slice(inline);
|
||||||
|
Ok(ipv6::Address::from_bytes(&bytes[..]))
|
||||||
|
}
|
||||||
|
(index, AddressMode::FullyElided) => {
|
||||||
|
match ll_address {
|
||||||
|
Some(LlAddress::Short(ll)) => {
|
||||||
|
bytes[11..13].copy_from_slice(&EUI64_MIDDLE_VALUE[..]);
|
||||||
|
bytes[14..].copy_from_slice(&ll);
|
||||||
|
}
|
||||||
|
Some(addr @ LlAddress::Extended(_)) => match addr.as_eui_64() {
|
||||||
|
Some(addr) => bytes[8..].copy_from_slice(&addr),
|
||||||
|
None => return Err(Error),
|
||||||
|
},
|
||||||
|
Some(LlAddress::Absent) => return Err(Error),
|
||||||
|
None => return Err(Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
copy_context(index, &mut bytes[..])?;
|
||||||
|
|
||||||
|
Ok(ipv6::Address::from_bytes(&bytes[..]))
|
||||||
|
}
|
||||||
_ => Err(Error),
|
_ => Err(Error),
|
||||||
},
|
},
|
||||||
UnresolvedAddress::Reserved => Err(Error),
|
UnresolvedAddress::Reserved => Err(Error),
|
||||||
@ -421,7 +484,10 @@ pub mod iphc {
|
|||||||
//!
|
//!
|
||||||
//! [RFC 6282 § 3.1]: https://datatracker.ietf.org/doc/html/rfc6282#section-3.1
|
//! [RFC 6282 § 3.1]: https://datatracker.ietf.org/doc/html/rfc6282#section-3.1
|
||||||
|
|
||||||
use super::{AddressMode, Error, NextHeader, Result, UnresolvedAddress, DISPATCH_IPHC_HEADER};
|
use super::{
|
||||||
|
AddressContext, AddressMode, Error, NextHeader, Result, UnresolvedAddress,
|
||||||
|
DISPATCH_IPHC_HEADER,
|
||||||
|
};
|
||||||
use crate::wire::{ieee802154::Address as LlAddress, ipv6, IpProtocol};
|
use crate::wire::{ieee802154::Address as LlAddress, ipv6, IpProtocol};
|
||||||
use byteorder::{ByteOrder, NetworkEndian};
|
use byteorder::{ByteOrder, NetworkEndian};
|
||||||
|
|
||||||
@ -573,7 +639,7 @@ pub mod iphc {
|
|||||||
pub fn src_context_id(&self) -> Option<u8> {
|
pub fn src_context_id(&self) -> Option<u8> {
|
||||||
if self.cid_field() == 1 {
|
if self.cid_field() == 1 {
|
||||||
let data = self.buffer.as_ref();
|
let data = self.buffer.as_ref();
|
||||||
Some(data[1] >> 4)
|
Some(data[2] >> 4)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -583,7 +649,7 @@ pub mod iphc {
|
|||||||
pub fn dst_context_id(&self) -> Option<u8> {
|
pub fn dst_context_id(&self) -> Option<u8> {
|
||||||
if self.cid_field() == 1 {
|
if self.cid_field() == 1 {
|
||||||
let data = self.buffer.as_ref();
|
let data = self.buffer.as_ref();
|
||||||
Some(data[1] & 0x0f)
|
Some(data[2] & 0x0f)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -640,30 +706,52 @@ pub mod iphc {
|
|||||||
+ self.next_header_size()
|
+ self.next_header_size()
|
||||||
+ self.hop_limit_size()) as usize;
|
+ self.hop_limit_size()) as usize;
|
||||||
|
|
||||||
|
let data = self.buffer.as_ref();
|
||||||
match (self.sac_field(), self.sam_field()) {
|
match (self.sac_field(), self.sam_field()) {
|
||||||
(0, 0b00) => {
|
(0, 0b00) => Ok(UnresolvedAddress::WithoutContext(AddressMode::FullInline(
|
||||||
let data = self.buffer.as_ref();
|
&data[start..][..16],
|
||||||
Ok(UnresolvedAddress::WithoutContext(AddressMode::FullInline(
|
))),
|
||||||
&data[start..][..16],
|
(0, 0b01) => Ok(UnresolvedAddress::WithoutContext(
|
||||||
)))
|
AddressMode::InLine64bits(&data[start..][..8]),
|
||||||
}
|
)),
|
||||||
(0, 0b01) => {
|
(0, 0b10) => Ok(UnresolvedAddress::WithoutContext(
|
||||||
let data = self.buffer.as_ref();
|
AddressMode::InLine16bits(&data[start..][..2]),
|
||||||
Ok(UnresolvedAddress::WithoutContext(
|
)),
|
||||||
AddressMode::InLine64bits(&data[start..][..8]),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
(0, 0b10) => {
|
|
||||||
let data = self.buffer.as_ref();
|
|
||||||
Ok(UnresolvedAddress::WithoutContext(
|
|
||||||
AddressMode::InLine16bits(&data[start..][..2]),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
(0, 0b11) => Ok(UnresolvedAddress::WithoutContext(AddressMode::FullyElided)),
|
(0, 0b11) => Ok(UnresolvedAddress::WithoutContext(AddressMode::FullyElided)),
|
||||||
(1, 0b00) => Ok(UnresolvedAddress::WithContext(AddressMode::Unspecified)),
|
(1, 0b00) => Ok(UnresolvedAddress::WithContext((
|
||||||
(1, 0b01) => Ok(UnresolvedAddress::WithContext(AddressMode::NotSupported)),
|
0,
|
||||||
(1, 0b10) => Ok(UnresolvedAddress::WithContext(AddressMode::NotSupported)),
|
AddressMode::Unspecified,
|
||||||
(1, 0b11) => Ok(UnresolvedAddress::WithContext(AddressMode::NotSupported)),
|
))),
|
||||||
|
(1, 0b01) => {
|
||||||
|
if let Some(id) = self.src_context_id() {
|
||||||
|
Ok(UnresolvedAddress::WithContext((
|
||||||
|
id as usize,
|
||||||
|
AddressMode::InLine64bits(&data[start..][..8]),
|
||||||
|
)))
|
||||||
|
} else {
|
||||||
|
Err(Error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(1, 0b10) => {
|
||||||
|
if let Some(id) = self.src_context_id() {
|
||||||
|
Ok(UnresolvedAddress::WithContext((
|
||||||
|
id as usize,
|
||||||
|
AddressMode::InLine16bits(&data[start..][..2]),
|
||||||
|
)))
|
||||||
|
} else {
|
||||||
|
Err(Error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(1, 0b11) => {
|
||||||
|
if let Some(id) = self.src_context_id() {
|
||||||
|
Ok(UnresolvedAddress::WithContext((
|
||||||
|
id as usize,
|
||||||
|
AddressMode::FullyElided,
|
||||||
|
)))
|
||||||
|
} else {
|
||||||
|
Err(Error)
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => Err(Error),
|
_ => Err(Error),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -676,55 +764,65 @@ pub mod iphc {
|
|||||||
+ self.hop_limit_size()
|
+ self.hop_limit_size()
|
||||||
+ self.src_address_size()) as usize;
|
+ self.src_address_size()) as usize;
|
||||||
|
|
||||||
|
let data = self.buffer.as_ref();
|
||||||
match (self.m_field(), self.dac_field(), self.dam_field()) {
|
match (self.m_field(), self.dac_field(), self.dam_field()) {
|
||||||
(0, 0, 0b00) => {
|
(0, 0, 0b00) => Ok(UnresolvedAddress::WithoutContext(AddressMode::FullInline(
|
||||||
let data = self.buffer.as_ref();
|
&data[start..][..16],
|
||||||
Ok(UnresolvedAddress::WithoutContext(AddressMode::FullInline(
|
))),
|
||||||
&data[start..][..16],
|
(0, 0, 0b01) => Ok(UnresolvedAddress::WithoutContext(
|
||||||
)))
|
AddressMode::InLine64bits(&data[start..][..8]),
|
||||||
}
|
)),
|
||||||
(0, 0, 0b01) => {
|
(0, 0, 0b10) => Ok(UnresolvedAddress::WithoutContext(
|
||||||
let data = self.buffer.as_ref();
|
AddressMode::InLine16bits(&data[start..][..2]),
|
||||||
Ok(UnresolvedAddress::WithoutContext(
|
)),
|
||||||
AddressMode::InLine64bits(&data[start..][..8]),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
(0, 0, 0b10) => {
|
|
||||||
let data = self.buffer.as_ref();
|
|
||||||
Ok(UnresolvedAddress::WithoutContext(
|
|
||||||
AddressMode::InLine16bits(&data[start..][..2]),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
(0, 0, 0b11) => Ok(UnresolvedAddress::WithoutContext(AddressMode::FullyElided)),
|
(0, 0, 0b11) => Ok(UnresolvedAddress::WithoutContext(AddressMode::FullyElided)),
|
||||||
(0, 1, 0b00) => Ok(UnresolvedAddress::Reserved),
|
(0, 1, 0b00) => Ok(UnresolvedAddress::Reserved),
|
||||||
(0, 1, 0b01) => Ok(UnresolvedAddress::WithContext(AddressMode::NotSupported)),
|
(0, 1, 0b01) => {
|
||||||
(0, 1, 0b10) => Ok(UnresolvedAddress::WithContext(AddressMode::NotSupported)),
|
if let Some(id) = self.dst_context_id() {
|
||||||
(0, 1, 0b11) => Ok(UnresolvedAddress::WithContext(AddressMode::NotSupported)),
|
Ok(UnresolvedAddress::WithContext((
|
||||||
(1, 0, 0b00) => {
|
id as usize,
|
||||||
let data = self.buffer.as_ref();
|
AddressMode::InLine64bits(&data[start..][..8]),
|
||||||
Ok(UnresolvedAddress::WithoutContext(AddressMode::FullInline(
|
)))
|
||||||
&data[start..][..16],
|
} else {
|
||||||
)))
|
Err(Error)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
(1, 0, 0b01) => {
|
(0, 1, 0b10) => {
|
||||||
let data = self.buffer.as_ref();
|
if let Some(id) = self.dst_context_id() {
|
||||||
Ok(UnresolvedAddress::WithoutContext(
|
Ok(UnresolvedAddress::WithContext((
|
||||||
AddressMode::Multicast48bits(&data[start..][..6]),
|
id as usize,
|
||||||
))
|
AddressMode::InLine16bits(&data[start..][..2]),
|
||||||
|
)))
|
||||||
|
} else {
|
||||||
|
Err(Error)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
(1, 0, 0b10) => {
|
(0, 1, 0b11) => {
|
||||||
let data = self.buffer.as_ref();
|
if let Some(id) = self.dst_context_id() {
|
||||||
Ok(UnresolvedAddress::WithoutContext(
|
Ok(UnresolvedAddress::WithContext((
|
||||||
AddressMode::Multicast32bits(&data[start..][..4]),
|
id as usize,
|
||||||
))
|
AddressMode::FullyElided,
|
||||||
|
)))
|
||||||
|
} else {
|
||||||
|
Err(Error)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
(1, 0, 0b11) => {
|
(1, 0, 0b00) => Ok(UnresolvedAddress::WithoutContext(AddressMode::FullInline(
|
||||||
let data = self.buffer.as_ref();
|
&data[start..][..16],
|
||||||
Ok(UnresolvedAddress::WithoutContext(
|
))),
|
||||||
AddressMode::Multicast8bits(&data[start..][..1]),
|
(1, 0, 0b01) => Ok(UnresolvedAddress::WithoutContext(
|
||||||
))
|
AddressMode::Multicast48bits(&data[start..][..6]),
|
||||||
}
|
)),
|
||||||
(1, 1, 0b00) => Ok(UnresolvedAddress::WithContext(AddressMode::NotSupported)),
|
(1, 0, 0b10) => Ok(UnresolvedAddress::WithoutContext(
|
||||||
|
AddressMode::Multicast32bits(&data[start..][..4]),
|
||||||
|
)),
|
||||||
|
(1, 0, 0b11) => Ok(UnresolvedAddress::WithoutContext(
|
||||||
|
AddressMode::Multicast8bits(&data[start..][..1]),
|
||||||
|
)),
|
||||||
|
(1, 1, 0b00) => Ok(UnresolvedAddress::WithContext((
|
||||||
|
0,
|
||||||
|
AddressMode::NotSupported,
|
||||||
|
))),
|
||||||
(1, 1, 0b01 | 0b10 | 0b11) => Ok(UnresolvedAddress::Reserved),
|
(1, 1, 0b01 | 0b10 | 0b11) => Ok(UnresolvedAddress::Reserved),
|
||||||
_ => Err(Error),
|
_ => Err(Error),
|
||||||
}
|
}
|
||||||
@ -1086,6 +1184,7 @@ pub mod iphc {
|
|||||||
packet: &Packet<&T>,
|
packet: &Packet<&T>,
|
||||||
ll_src_addr: Option<LlAddress>,
|
ll_src_addr: Option<LlAddress>,
|
||||||
ll_dst_addr: Option<LlAddress>,
|
ll_dst_addr: Option<LlAddress>,
|
||||||
|
addr_context: &[AddressContext<'_>],
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
// Ensure basic accessors will work.
|
// Ensure basic accessors will work.
|
||||||
packet.check_len()?;
|
packet.check_len()?;
|
||||||
@ -1095,8 +1194,8 @@ pub mod iphc {
|
|||||||
return Err(Error);
|
return Err(Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
let src_addr = packet.src_addr()?.resolve(ll_src_addr)?;
|
let src_addr = packet.src_addr()?.resolve(ll_src_addr, addr_context)?;
|
||||||
let dst_addr = packet.dst_addr()?.resolve(ll_dst_addr)?;
|
let dst_addr = packet.dst_addr()?.resolve(ll_dst_addr, addr_context)?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
src_addr,
|
src_addr,
|
||||||
@ -1293,11 +1392,17 @@ pub mod iphc {
|
|||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
packet.src_addr(),
|
packet.src_addr(),
|
||||||
Ok(UnresolvedAddress::WithContext(AddressMode::NotSupported))
|
Ok(UnresolvedAddress::WithContext((
|
||||||
|
0,
|
||||||
|
AddressMode::FullyElided
|
||||||
|
)))
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
packet.dst_addr(),
|
packet.dst_addr(),
|
||||||
Ok(UnresolvedAddress::WithContext(AddressMode::NotSupported))
|
Ok(UnresolvedAddress::WithContext((
|
||||||
|
0,
|
||||||
|
AddressMode::FullyElided
|
||||||
|
)))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2205,8 +2310,13 @@ mod test {
|
|||||||
unreachable!()
|
unreachable!()
|
||||||
};
|
};
|
||||||
|
|
||||||
let iphc_repr =
|
let iphc_repr = iphc::Repr::parse(
|
||||||
iphc::Repr::parse(&iphc, ieee802154_repr.src_addr, ieee802154_repr.dst_addr).unwrap();
|
&iphc,
|
||||||
|
ieee802154_repr.src_addr,
|
||||||
|
ieee802154_repr.dst_addr,
|
||||||
|
&[],
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
iphc_repr.dst_addr,
|
iphc_repr.dst_addr,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user