diff --git a/hal/inc/hal_socket.h b/hal/inc/hal_socket.h index e52defb5..414a1a7e 100644 --- a/hal/inc/hal_socket.h +++ b/hal/inc/hal_socket.h @@ -151,8 +151,19 @@ UdpSocket_bind(UdpSocket self, const char* address, int port); PAL_API bool UdpSocket_sendTo(UdpSocket self, const char* address, int port, uint8_t* msg, int msgSize); +/** + * \brief Receive data from UDP socket (store data and (optionally) the IP address of the sender + * + * \param self UDP socket instance + * \param address (optional) buffer to store the IP address as string + * \param maxAddrSize (optional) size of the provided buffer to store the IP address + * \param msg buffer to store the UDP message data + * \param msgSize the maximum size of the message to receive + * + * \return number of received bytes or -1 in case of an error + */ PAL_API int -UdpSocket_receiveFrom(UdpSocket self, char** address, int maxAddrSize, uint8_t* msg, int msgSize); +UdpSocket_receiveFrom(UdpSocket self, char* address, int maxAddrSize, uint8_t* msg, int msgSize); PAL_API void diff --git a/hal/socket/linux/socket_linux.c b/hal/socket/linux/socket_linux.c index dc9bbaeb..3d4e32b8 100644 --- a/hal/socket/linux/socket_linux.c +++ b/hal/socket/linux/socket_linux.c @@ -755,14 +755,40 @@ UdpSocket_sendTo(UdpSocket self, const char* address, int port, uint8_t* msg, in int UdpSocket_receiveFrom(UdpSocket self, char** address, int maxAddrSize, uint8_t* msg, int msgSize) { - struct sockaddr_in remoteAddress; + struct sockaddr_storage remoteAddress; - int result = recvfrom(self->fd, msg, msgSize, MSG_DONTWAIT, NULL, NULL); + int result = recvfrom(self->fd, msg, msgSize, MSG_DONTWAIT, (struct sockaddr*)&remoteAddress, sizeof(struct sockaddr_storage)); if (result == -1) { if (DEBUG_SOCKET) printf("SOCKET: failed to receive UDP message (errno=%i)\n", errno); } + if (address) { + bool isIPv6; + char addrString[INET6_ADDRSTRLEN + 7]; + int port; + + if (remoteAddress.ss_family == AF_INET) { + struct sockaddr_in* ipv4Addr = (struct sockaddr_in*) &remoteAddress; + port = ntohs(ipv4Addr->sin_port); + inet_ntop(AF_INET, &(ipv4Addr->sin_addr), addrString, INET_ADDRSTRLEN); + isIPv6 = false; + } + else if (remoteAddress.ss_family == AF_INET6) { + struct sockaddr_in6* ipv6Addr = (struct sockaddr_in6*) &remoteAddress; + port = ntohs(ipv6Addr->sin6_port); + inet_ntop(AF_INET6, &(ipv6Addr->sin6_addr), addrString, INET6_ADDRSTRLEN); + isIPv6 = true; + } + else + return NULL ; + + if (isIPv6) + snprintf(*address, maxAddrSize, "[%s]:%i", addrString, port); + else + snprintf(*address, maxAddrSize, "%s:%i", addrString, port); + } + return result; } diff --git a/hal/time/unix/time.c b/hal/time/unix/time.c index 6565da33..5c1bffe7 100644 --- a/hal/time/unix/time.c +++ b/hal/time/unix/time.c @@ -1,7 +1,7 @@ /* * time.c * - * Copyright 2013, 2014 Michael Zillgith + * Copyright 2013-2021 Michael Zillgith * * This file is part of libIEC61850. *