diff --git a/makefiles/pseudomodules.inc.mk b/makefiles/pseudomodules.inc.mk index 602281a02eed..1c5ea3dab46a 100644 --- a/makefiles/pseudomodules.inc.mk +++ b/makefiles/pseudomodules.inc.mk @@ -513,6 +513,7 @@ PSEUDOMODULES += sock_async PSEUDOMODULES += sock_aux_local PSEUDOMODULES += sock_aux_rssi PSEUDOMODULES += sock_aux_timestamp +PSEUDOMODULES += sock_aux_ttl PSEUDOMODULES += sock_dtls PSEUDOMODULES += sock_ip PSEUDOMODULES += sock_tcp diff --git a/sys/include/net/sock.h b/sys/include/net/sock.h index 4acf9f36a267..6636abe4cf54 100644 --- a/sys/include/net/sock.h +++ b/sys/include/net/sock.h @@ -319,6 +319,21 @@ enum { * @ref sock_dtls_aux_tx_t::local. */ SOCK_AUX_SET_LOCAL = (1LU << 3), + /** + * @brief Flag to request the TTL value of received frame + * + * @note Select module `sock_aux_ttl` and a compatible network stack to + * use this + * + * Set this flag in the auxiliary data structure prior to the call of + * @ref sock_udp_recv_aux / @ref sock_ip_recv_aux / etc. to request the + * TTL value of a received frame. This flag will be cleared if the + * time to live was stored, otherwise it remains set. + * + * Depending on the family of the socket, the TTL value will be stored in + * @ref sock_udp_aux_rx_t::ttl or @ref sock_dtls_aux_rx_t::ttl. + */ + SOCK_AUX_GET_TTL = (1LU << 4), }; /** diff --git a/sys/include/net/sock/udp.h b/sys/include/net/sock/udp.h index 69fad737f765..7ed8ed1234ae 100644 --- a/sys/include/net/sock/udp.h +++ b/sys/include/net/sock/udp.h @@ -332,6 +332,14 @@ typedef struct { */ int16_t rssi; #endif /* MODULE_SOCK_AUX_RSSI */ +#if defined(MODULE_SOCK_AUX_TTL) || defined(DOXYGEN) + /** + * @brief TTL value of the received frame + * + * @see SOCK_AUX_GET_TTL + */ + uint8_t ttl; +#endif /* MODULE_SOCK_AUX_TTL */ sock_aux_flags_t flags; /**< Flags used request information */ } sock_udp_aux_rx_t; diff --git a/sys/net/gnrc/sock/udp/gnrc_sock_udp.c b/sys/net/gnrc/sock/udp/gnrc_sock_udp.c index 465df3c3271d..dfffcef6e1a3 100644 --- a/sys/net/gnrc/sock/udp/gnrc_sock_udp.c +++ b/sys/net/gnrc/sock/udp/gnrc_sock_udp.c @@ -305,6 +305,16 @@ ssize_t sock_udp_recv_buf_aux(sock_udp_t *sock, void **data, void **buf_ctx, if ((aux != NULL) && (_aux.flags & GNRC_SOCK_RECV_AUX_FLAG_RSSI)) { aux->flags &= ~SOCK_AUX_GET_RSSI; } +#endif +#if IS_USED(MODULE_SOCK_AUX_TTL) + if ((aux != NULL) && (aux->flags & SOCK_AUX_GET_TTL)) { + gnrc_pktsnip_t *ip = gnrc_pktsnip_search_type(pkt, GNRC_NETTYPE_IPV6); + if (ip) { + ipv6_hdr_t *ip_hdr = ip->data; + aux->ttl = ip_hdr->hl; + aux->flags &= ~SOCK_AUX_GET_TTL; + } + } #endif *data = pkt->data; *buf_ctx = pkt; diff --git a/tests/net/gnrc_sock_udp/Makefile b/tests/net/gnrc_sock_udp/Makefile index 0af901c04994..421326bd9747 100644 --- a/tests/net/gnrc_sock_udp/Makefile +++ b/tests/net/gnrc_sock_udp/Makefile @@ -3,6 +3,7 @@ include ../Makefile.net_common AUX_LOCAL ?= 1 AUX_TIMESTAMP ?= 1 AUX_RSSI ?= 1 +AUX_TTL ?= 1 ifeq (1, $(AUX_LOCAL)) USEMODULE += sock_aux_local @@ -16,6 +17,10 @@ ifeq (1, $(AUX_RSSI)) USEMODULE += sock_aux_rssi endif +ifeq (1, $(AUX_TTL)) + USEMODULE += sock_aux_ttl +endif + USEMODULE += gnrc_sock_check_reuse USEMODULE += sock_udp USEMODULE += gnrc_ipv6 diff --git a/tests/net/gnrc_sock_udp/main.c b/tests/net/gnrc_sock_udp/main.c index 48a349a7fb1c..bddfc6033675 100644 --- a/tests/net/gnrc_sock_udp/main.c +++ b/tests/net/gnrc_sock_udp/main.c @@ -451,7 +451,7 @@ static void test_sock_udp_recv__aux(void) static const inject_aux_t inject_aux = { .timestamp = 1337, .rssi = -11 }; sock_udp_ep_t result; sock_udp_aux_rx_t aux = { - .flags = SOCK_AUX_GET_LOCAL | SOCK_AUX_GET_TIMESTAMP | SOCK_AUX_GET_RSSI + .flags = SOCK_AUX_GET_LOCAL | SOCK_AUX_GET_TIMESTAMP | SOCK_AUX_GET_RSSI | SOCK_AUX_GET_TTL }; expect(0 == sock_udp_create(&_sock, &local, NULL, SOCK_FLAGS_REUSE_EP)); @@ -483,6 +483,12 @@ static void test_sock_udp_recv__aux(void) expect(inject_aux.rssi == aux.rssi); #else expect(aux.flags & SOCK_AUX_GET_RSSI); +#endif +#if IS_USED(MODULE_SOCK_AUX_TTL) + expect(!(aux.flags & SOCK_AUX_GET_TTL)); + expect(64 == aux.ttl); +#else + expect(aux.flags & SOCK_AUX_GET_TTL); #endif expect(_check_net()); }