blob: 73bc5301114118ebb841cbfa0262ac8c62037a11 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
/*
* Copyright (c) 2026 HPMicro
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef LWIP_PTP_TX_TS_H
#define LWIP_PTP_TX_TS_H
#include <stdbool.h>
#include "lwip/def.h"
#include "lwip/pbuf.h"
#include "lwip/prot/ethernet.h"
#include "lwip/prot/ip.h"
#include "lwip/prot/ip4.h"
#include "lwip/prot/udp.h"
/**
* @brief True if this Ethernet frame should use ENET TX descriptor TTSE and HW timestamp
* PTPd sends messages that need precise egress time on UDP event port 319 only.
* General port 320 (Announce, Follow_Up, Delay_Resp, etc.) does not use TX HW stamp.
*/
static inline bool lwip_ptp_frame_needs_tx_hw_timestamp(const struct pbuf *p)
{
u8_t hdr[SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR + IP_HLEN + sizeof(struct udp_hdr)];
u16_t ethertype;
u16_t ip_off;
const struct ip_hdr *iph;
u16_t ip_len;
const struct udp_hdr *udph;
if (p == NULL || p->tot_len < (s16_t)(SIZEOF_ETH_HDR + IP_HLEN + UDP_HLEN)) {
return false;
}
if (pbuf_copy_partial(p, hdr, (u16_t)sizeof(hdr), 0) != (u16_t)sizeof(hdr)) {
return false;
}
ethertype = lwip_ntohs(*(u16_t *)(hdr + 12U));
ip_off = SIZEOF_ETH_HDR;
if (ethertype == ETHTYPE_VLAN) {
if (p->tot_len < (s16_t)(SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR + IP_HLEN + UDP_HLEN)) {
return false;
}
ethertype = lwip_ntohs(*(u16_t *)(hdr + (SIZEOF_ETH_HDR + 2U)));
ip_off = SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR;
}
if (ethertype != ETHTYPE_IP) {
return false;
}
iph = (const struct ip_hdr *)(hdr + ip_off);
if (IPH_HL(iph) != 5) {
return false;
}
if (IPH_PROTO(iph) != IP_PROTO_UDP) {
return false;
}
ip_len = IP_HLEN;
if ((u32_t)ip_off + (u32_t)ip_len + UDP_HLEN > sizeof(hdr)) {
return false;
}
udph = (const struct udp_hdr *)(hdr + ip_off + ip_len);
return udph->dest == PP_HTONS(319);
}
#endif /* LWIP_PTP_TX_TS_H */
|