15size_t detws_eth_build(
const uint8_t *dst,
const uint8_t *src, uint16_t ethertype,
const uint8_t *payload,
16 size_t payload_len, uint8_t *out,
size_t cap)
18 if (!dst || !src || !out || (payload_len && !payload))
20 size_t n = RawL2::ETH_HDR_LEN + payload_len;
23 memcpy(out, dst, RawL2::ETH_ALEN);
24 memcpy(out + RawL2::ETH_ALEN, src, RawL2::ETH_ALEN);
25 out[12] = (uint8_t)(ethertype >> 8);
26 out[13] = (uint8_t)ethertype;
28 memcpy(out + RawL2::ETH_HDR_LEN, payload, payload_len);
32size_t detws_eth_build_vlan(
const uint8_t *dst,
const uint8_t *src, uint8_t pcp,
bool dei, uint16_t vid,
33 uint16_t ethertype,
const uint8_t *payload,
size_t payload_len, uint8_t *out,
size_t cap)
35 if (!dst || !src || !out || (payload_len && !payload))
37 size_t n = RawL2::ETH_VLAN_HDR_LEN + payload_len;
40 memcpy(out, dst, RawL2::ETH_ALEN);
41 memcpy(out + RawL2::ETH_ALEN, src, RawL2::ETH_ALEN);
42 out[12] = (uint8_t)(RawL2::ETH_TPID_8021Q >> 8);
43 out[13] = (uint8_t)RawL2::ETH_TPID_8021Q;
44 uint16_t tci = (uint16_t)(((pcp & 0x7) << 13) | ((dei ? 1 : 0) << 12) | (vid & 0x0FFF));
45 out[14] = (uint8_t)(tci >> 8);
46 out[15] = (uint8_t)tci;
47 out[16] = (uint8_t)(ethertype >> 8);
48 out[17] = (uint8_t)ethertype;
50 memcpy(out + RawL2::ETH_VLAN_HDR_LEN, payload, payload_len);
54bool detws_eth_parse(
const uint8_t *frame,
size_t len, EthFrame *out)
56 if (!frame || !out || len < RawL2::ETH_HDR_LEN)
59 out->src = frame + RawL2::ETH_ALEN;
60 uint16_t et = (uint16_t)((frame[12] << 8) | frame[13]);
61 if (et == RawL2::ETH_TPID_8021Q)
63 if (len < RawL2::ETH_VLAN_HDR_LEN)
65 uint16_t tci = (uint16_t)((frame[14] << 8) | frame[15]);
67 out->pcp = (uint8_t)((tci >> 13) & 0x7);
68 out->vid = (uint16_t)(tci & 0x0FFF);
69 out->ethertype = (uint16_t)((frame[16] << 8) | frame[17]);
70 out->payload = frame + RawL2::ETH_VLAN_HDR_LEN;
71 out->payload_len = len - RawL2::ETH_VLAN_HDR_LEN;
79 out->payload = frame + RawL2::ETH_HDR_LEN;
80 out->payload_len = len - RawL2::ETH_HDR_LEN;
85uint32_t detws_eth_fcs(
const uint8_t *bytes,
size_t len)
88 uint32_t crc = 0xFFFFFFFFu;
89 for (
size_t i = 0; i < len; i++)
92 for (
int b = 0; b < 8; b++)
93 crc = (crc >> 1) ^ (0xEDB88320u & (uint32_t)(-(int32_t)(crc & 1)));
Raw Layer-2 Ethernet frame codec (DETWS_ENABLE_RAWL2).