diff options
| author | mzgrebnak <[email protected]> | 2026-05-29 16:34:38 +0200 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-05-29 10:34:38 -0400 |
| commit | 09ce97f8f9019724407917c197c2a0c0e859bf2d (patch) | |
| tree | 3f0683ac14105149cf0759ea1fa133ed9675cd34 /addons | |
| parent | 53070b69eed6af6840b0a890fe749e73e3f280f2 (diff) | |
Added BSD recvfromto support (#376)
* recvfromto support
* nx_bsd_inet_aton, disabling other format than four numbers separated by dots. Otherwise used in nx_bsd_inet_pton
It accepts unallowed format of IP address.
* bsd: address PR review feedback
- Fix build failure: add missing nx_bsd_recvfromto() prototype to
nxd_bsd.h near the other receive prototypes. The nx_bsd_recvfromto
macro maps to recvfromto, but without a prior declaration the
compiler emits -Werror=missing-declarations.
- Revert inet_aton() change: restore the 1-part, 2-part and 3-part
abbreviated IPv4 address formats (a.b.c and a.b). The PR removed
them, breaking existing tests that rely on these forms.
- Add IPv6 destination address support in recvfromto(): when the
receiving BSD socket is AF_INET6, extract the destination IPv6
address from the IPv6 packet header and populate a sockaddr_in6
in toAddr, mirroring the existing IPv4 path.
- Add regression test netx_bsd_recvfromto_test covering:
* recvfromto() populates fromAddr (sender) and toAddr (destination)
with correct address/port values for IPv4 UDP
* recvfromto() with NULL toAddr/toAddrLen works like recvfrom()
* inet_aton() still accepts abbreviated a.b and a.b.c forms
Register test in regression/CMakeLists.txt.
---------
Co-authored-by: Frédéric Desbiens <[email protected]>
Co-authored-by: Copilot <[email protected]>
Diffstat (limited to 'addons')
| -rw-r--r-- | addons/BSD/nxd_bsd.c | 72 | ||||
| -rw-r--r-- | addons/BSD/nxd_bsd.h | 2 |
2 files changed, 69 insertions, 5 deletions
diff --git a/addons/BSD/nxd_bsd.c b/addons/BSD/nxd_bsd.c index 10a2dee5..b69edf57 100644 --- a/addons/BSD/nxd_bsd.c +++ b/addons/BSD/nxd_bsd.c @@ -164,7 +164,8 @@ static VOID _nxd_bsd_ipv4_packet_send(NX_PACKET *packet_ptr); static INT nx_bsd_send_internal(INT sockID, const CHAR *msg, INT msgLength, INT flags, NXD_ADDRESS *dst_address, USHORT dst_port, UINT local_interface_index); static INT nx_bsd_recv_internal(INT sockID, struct nx_bsd_iovec *iov, size_t iovlen, INT flags, - struct nx_bsd_sockaddr *fromAddr, INT *fromAddrLen); + struct nx_bsd_sockaddr *fromAddr, INT *fromAddrLen, + struct nx_bsd_sockaddr *toAddr, INT *toAddrLen); #ifdef FEATURE_NX_IPV6 static VOID _nxd_bsd_ipv6_packet_send(NX_PACKET *packet_ptr, ULONG *src_addr, ULONG *dest_addr); #endif /* FEATURE_NX_IPV6 */ @@ -3931,7 +3932,7 @@ struct nx_bsd_iovec iov; iov.iov_len = (size_t)bufferLength; /* Call the recv_internal() function. */ - return nx_bsd_recv_internal(sockID, &iov, 1, flags, NX_NULL, NX_NULL); + return nx_bsd_recv_internal(sockID, &iov, 1, flags, NX_NULL, NX_NULL, NX_NULL, NX_NULL); } @@ -3986,7 +3987,21 @@ struct nx_bsd_iovec iov; iov.iov_len = (size_t)bufferLength; /* Call the recv_internal() function. */ - return nx_bsd_recv_internal(sockID, &iov, 1, flags, fromAddr, fromAddrLen); + return nx_bsd_recv_internal(sockID, &iov, 1, flags, fromAddr, fromAddrLen, NX_NULL, NX_NULL); +} + + +INT nx_bsd_recvfromto(INT sockID, CHAR *rcvBuffer, INT bufferLength, INT flags, + struct nx_bsd_sockaddr *fromAddr, INT *fromAddrLen, + struct nx_bsd_sockaddr *toAddr, INT *toAddrLen) +{ +struct nx_bsd_iovec iov; + + iov.iov_base = rcvBuffer; + iov.iov_len = (size_t)bufferLength; + + /* Call the recv_internal() function. */ + return nx_bsd_recv_internal(sockID, &iov, 1, flags, fromAddr, fromAddrLen, toAddr, toAddrLen); } /**************************************************************************/ @@ -4035,7 +4050,7 @@ INT fromAddrLen = 0; fromAddrLen = (INT)(msg -> msg_namelen); } - return(nx_bsd_recv_internal(sockID, msg -> msg_iov, msg -> msg_iovlen, flags, (struct nx_bsd_sockaddr *)(msg -> msg_name), &fromAddrLen)); + return(nx_bsd_recv_internal(sockID, msg -> msg_iov, msg -> msg_iovlen, flags, (struct nx_bsd_sockaddr *)(msg -> msg_name), &fromAddrLen, NX_NULL, NX_NULL)); } /**************************************************************************/ @@ -4102,7 +4117,9 @@ INT fromAddrLen = 0; /* recvfrom */ /* */ /**************************************************************************/ -static INT nx_bsd_recv_internal(INT sockID, struct nx_bsd_iovec *iov, size_t iovlen, INT flags, struct nx_bsd_sockaddr *fromAddr, INT *fromAddrLen) +static INT nx_bsd_recv_internal(INT sockID, struct nx_bsd_iovec *iov, size_t iovlen, INT flags, + struct nx_bsd_sockaddr *fromAddr, INT *fromAddrLen, + struct nx_bsd_sockaddr *toAddr, INT *toAddrLen) { UINT status; NX_PACKET *packet_ptr; @@ -4388,6 +4405,51 @@ struct nx_bsd_sockaddr_in6 /* Get the sender and port from the UDP packet. */ nxd_udp_source_extract(packet_ptr, &bsd_socket_ptr -> nx_bsd_socket_source_ip_address, (UINT *)&bsd_socket_ptr -> nx_bsd_socket_source_port); + + if(toAddr && (*toAddrLen != 0)) + { +#ifndef NX_DISABLE_IPV4 + if(bsd_socket_ptr -> nx_bsd_socket_family == AF_INET) + { + ULONG nx_ip_header_destination_ip = ((NX_IPV4_HEADER *)packet_ptr -> nx_packet_ip_header) -> nx_ip_header_destination_ip; + ULONG *prepend_ptr = (ULONG *)packet_ptr -> nx_packet_prepend_ptr; + USHORT dst_port = (USHORT)(*(prepend_ptr - 2U) & 0xFFFFU); + struct nx_bsd_sockaddr_in destination_address; + + destination_address.sin_family = AF_INET; + destination_address.sin_addr.s_addr = ntohl(nx_ip_header_destination_ip); + destination_address.sin_port = ntohs(dst_port); + + if(*toAddrLen > (INT)sizeof(struct nx_bsd_sockaddr_in)) + { + *toAddrLen = (INT)sizeof(struct nx_bsd_sockaddr_in); + } + memcpy(toAddr, &destination_address, (UINT)(*toAddrLen)); + } +#endif /* NX_DISABLE_IPV4 */ +#ifdef FEATURE_NX_IPV6 + if(bsd_socket_ptr -> nx_bsd_socket_family == AF_INET6) + { + NX_IPV6_HEADER *ipv6_header = (NX_IPV6_HEADER *)packet_ptr -> nx_packet_ip_header; + ULONG *prepend_ptr = (ULONG *)packet_ptr -> nx_packet_prepend_ptr; + USHORT dst_port = (USHORT)(*(prepend_ptr - 2U) & 0xFFFFU); + struct nx_bsd_sockaddr_in6 destination_address6; + + destination_address6.sin6_family = AF_INET6; + destination_address6.sin6_addr._S6_un._S6_u32[0] = ntohl(ipv6_header -> nx_ip_header_destination_ip[0]); + destination_address6.sin6_addr._S6_un._S6_u32[1] = ntohl(ipv6_header -> nx_ip_header_destination_ip[1]); + destination_address6.sin6_addr._S6_un._S6_u32[2] = ntohl(ipv6_header -> nx_ip_header_destination_ip[2]); + destination_address6.sin6_addr._S6_un._S6_u32[3] = ntohl(ipv6_header -> nx_ip_header_destination_ip[3]); + destination_address6.sin6_port = ntohs(dst_port); + + if(*toAddrLen > (INT)sizeof(struct nx_bsd_sockaddr_in6)) + { + *toAddrLen = (INT)sizeof(struct nx_bsd_sockaddr_in6); + } + memcpy(toAddr, &destination_address6, (UINT)(*toAddrLen)); + } +#endif /* FEATURE_NX_IPV6 */ + } } #if defined(NX_BSD_RAW_SUPPORT) || defined(NX_BSD_RAW_PPPOE_SUPPORT) diff --git a/addons/BSD/nxd_bsd.h b/addons/BSD/nxd_bsd.h index 15d1c1ac..5223efd0 100644 --- a/addons/BSD/nxd_bsd.h +++ b/addons/BSD/nxd_bsd.h @@ -238,6 +238,7 @@ extern "C" { #define nx_bsd_inet_ntop inet_ntop #define nx_bsd_listen listen #define nx_bsd_recvfrom recvfrom +#define nx_bsd_recvfromto recvfromto #define nx_bsd_recv recv #define nx_bsd_recvmsg recvmsg #define nx_bsd_sendto sendto @@ -1014,6 +1015,7 @@ VOID nx_bsd_raw_receive_notify(NX_IP *ip_ptr, UINT bsd_socket_index); #endif UINT nx_bsd_socket_set_inherited_settings(UINT master_sock_id, UINT secondary_sock_id); INT nx_bsd_recvfrom(INT sockID, CHAR *buffer, INT buffersize, INT flags,struct nx_bsd_sockaddr *fromAddr, INT *fromAddrLen); +INT nx_bsd_recvfromto(INT sockID, CHAR *rcvBuffer, INT bufferLength, INT flags, struct nx_bsd_sockaddr *fromAddr, INT *fromAddrLen, struct nx_bsd_sockaddr *toAddr, INT *toAddrLen); INT nx_bsd_recv(INT sockID, VOID *rcvBuffer, INT bufferLength, INT flags); INT nx_bsd_recvmsg(INT sockID, struct nx_bsd_msghdr *msg, INT flags); INT nx_bsd_sendto(INT sockID, CHAR *msg, INT msgLength, INT flags, struct nx_bsd_sockaddr *destAddr, INT destAddrLen); |
