1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
45//! Utility functions used in the 6LoWPAN implementation
67/// Verifies that a prefix given in the form of a byte array slice is valid with
8/// respect to its length in bits (prefix_len):
9///
10/// - The byte array slice must contain enough bytes to cover the prefix length
11/// (no implicit zero-padding)
12/// - The rest of the prefix array slice is zero-padded
13pub fn verify_prefix_len(prefix: &[u8], prefix_len: u8) -> bool {
14let full_bytes = (prefix_len / 8) as usize;
15let remaining_bits = prefix_len % 8;
16let bytes = full_bytes + usize::from(remaining_bits != 0);
1718if bytes > prefix.len() {
19return false;
20 }
2122// The bits between the prefix's end and the next byte boundary must be 0
23if remaining_bits != 0 {
24let last_byte_mask = 0xff >> remaining_bits;
25if prefix[full_bytes] & last_byte_mask != 0 {
26return false;
27 }
28 }
2930// Ensure that the remaining bytes are also 0
31prefix[bytes..].iter().all(|&b| b == 0)
32}
3334/// Verifies that the prefixes of the two buffers match, where the length of the
35/// prefix is given in bits
36pub fn matches_prefix(buf1: &[u8], buf2: &[u8], prefix_len: u8) -> bool {
37let full_bytes = (prefix_len / 8) as usize;
38let remaining_bits = prefix_len % 8;
39let bytes = full_bytes + usize::from(remaining_bits != 0);
4041if bytes > buf1.len() || bytes > buf2.len() {
42return false;
43 }
4445// Ensure that the prefix bits in the last byte match
46if remaining_bits != 0 {
47let last_byte_mask = 0xff << (8 - remaining_bits);
48if (buf1[full_bytes] ^ buf2[full_bytes]) & last_byte_mask != 0 {
49return false;
50 }
51 }
5253// Ensure that the prefix bytes before that match
54buf1[..full_bytes].iter().eq(buf2[..full_bytes].iter())
55}
5657// When reading from a buffer in network order
58pub fn network_slice_to_u16(buf: &[u8]) -> u16 {
59 ((buf[0] as u16) << 8) | (buf[1] as u16)
60}
6162// When reading from a buffer in host order
63pub fn host_slice_to_u16(buf: &[u8]) -> u16 {
64 ((buf[1] as u16) << 8) | (buf[0] as u16)
65}
6667pub fn u16_to_network_slice(short: u16, slice: &mut [u8]) {
68 slice[0] = (short >> 8) as u8;
69 slice[1] = (short & 0xff) as u8;
70}