capsules_extra/net/
util.rs

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.
4
5//! Utility functions used in the 6LoWPAN implementation
6
7/// 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 {
14    let full_bytes = (prefix_len / 8) as usize;
15    let remaining_bits = prefix_len % 8;
16    let bytes = full_bytes + usize::from(remaining_bits != 0);
17
18    if bytes > prefix.len() {
19        return false;
20    }
21
22    // The bits between the prefix's end and the next byte boundary must be 0
23    if remaining_bits != 0 {
24        let last_byte_mask = 0xff >> remaining_bits;
25        if prefix[full_bytes] & last_byte_mask != 0 {
26            return false;
27        }
28    }
29
30    // Ensure that the remaining bytes are also 0
31    prefix[bytes..].iter().all(|&b| b == 0)
32}
33
34/// 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 {
37    let full_bytes = (prefix_len / 8) as usize;
38    let remaining_bits = prefix_len % 8;
39    let bytes = full_bytes + usize::from(remaining_bits != 0);
40
41    if bytes > buf1.len() || bytes > buf2.len() {
42        return false;
43    }
44
45    // Ensure that the prefix bits in the last byte match
46    if remaining_bits != 0 {
47        let last_byte_mask = 0xff << (8 - remaining_bits);
48        if (buf1[full_bytes] ^ buf2[full_bytes]) & last_byte_mask != 0 {
49            return false;
50        }
51    }
52
53    // Ensure that the prefix bytes before that match
54    buf1[..full_bytes].iter().eq(buf2[..full_bytes].iter())
55}
56
57// 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}
61
62// 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}
66
67pub 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}