This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new e0816ff050 in.h: add SOL_IPV6 protocol-level socket option
IPV6_RECVHOPLIMIT
e0816ff050 is described below
commit e0816ff050f62817f2d0f13c39943f912383a443
Author: zhanghongyu <[email protected]>
AuthorDate: Fri Apr 14 18:11:12 2023 +0800
in.h: add SOL_IPV6 protocol-level socket option IPV6_RECVHOPLIMIT
added IPV6_RECVHOPLIMIT support so that fd of SOCK_RAW ICMPV6 can obtain ttl
information, some network related tools use this feature.
Signed-off-by: zhanghongyu <[email protected]>
---
include/netinet/in.h | 2 ++
net/icmpv6/icmpv6.h | 2 +-
net/icmpv6/icmpv6_input.c | 6 ++++-
net/icmpv6/icmpv6_recvmsg.c | 55 ++++++++++++++++++++++++++++++++-------------
net/inet/ipv6_setsockopt.c | 1 +
5 files changed, 49 insertions(+), 17 deletions(-)
diff --git a/include/netinet/in.h b/include/netinet/in.h
index 867095fcfa..3affebaa9b 100644
--- a/include/netinet/in.h
+++ b/include/netinet/in.h
@@ -132,6 +132,8 @@
* the incoming packet */
#define IPV6_TCLASS (__SO_PROTOCOL + 10) /* Access the Traffic Class
* field */
+#define IPV6_RECVHOPLIMIT (__SO_PROTOCOL + 11) /* Access the hop limit
field */
+#define IPV6_HOPLIMIT (__SO_PROTOCOL + 12) /* Hop limit */
/* Values used with SIOCSIFMCFILTER and SIOCGIFMCFILTER ioctl's */
diff --git a/net/icmpv6/icmpv6.h b/net/icmpv6/icmpv6.h
index 259a873bce..d930ca00d0 100644
--- a/net/icmpv6/icmpv6.h
+++ b/net/icmpv6/icmpv6.h
@@ -651,7 +651,7 @@ ssize_t icmpv6_sendmsg(FAR struct socket *psock, FAR struct
msghdr *msg,
* Description:
* Implements the socket recvfrom interface for the case of the AF_INET
* data gram socket with the IPPROTO_ICMP6 protocol. icmpv6_recvmsg()
- * receives ICMPv6 ECHO replies for the a socket.
+ * receives ICMPv6 message for the a socket.
*
* If msg_name is not NULL, and the underlying protocol provides the source
* address, this source address is filled in. The argument 'msg_namelen' is
diff --git a/net/icmpv6/icmpv6_input.c b/net/icmpv6/icmpv6_input.c
index 16378a7bdf..ec53103986 100644
--- a/net/icmpv6/icmpv6_input.c
+++ b/net/icmpv6/icmpv6_input.c
@@ -111,6 +111,7 @@ static uint16_t icmpv6_datahandler(FAR struct net_driver_s
*dev,
FAR struct ipv6_hdr_s *ipv6;
struct sockaddr_in6 inaddr;
FAR struct iob_s *iob;
+ unsigned int offset;
uint16_t buflen;
int ret;
@@ -132,8 +133,11 @@ static uint16_t icmpv6_datahandler(FAR struct net_driver_s
*dev,
*/
memcpy(iob->io_data, &inaddr, sizeof(struct sockaddr_in6));
+ offset = sizeof(struct sockaddr_in6);
- iob_reserve(iob, sizeof(struct sockaddr_in6));
+ iob->io_data[offset++] = ipv6->ttl;
+
+ iob_reserve(iob, offset);
/* Copy the ICMPv6 message into the I/O buffer chain (without waiting) */
diff --git a/net/icmpv6/icmpv6_recvmsg.c b/net/icmpv6/icmpv6_recvmsg.c
index ffffd2a23a..56e02bd3aa 100644
--- a/net/icmpv6/icmpv6_recvmsg.c
+++ b/net/icmpv6/icmpv6_recvmsg.c
@@ -36,6 +36,7 @@
#include "devif/devif.h"
#include "socket/socket.h"
#include "icmpv6/icmpv6.h"
+#include "utils/utils.h"
#ifdef CONFIG_NET_ICMPv6_SOCKET
@@ -60,6 +61,7 @@ struct icmpv6_recvfrom_s
* from */
FAR uint8_t *recv_buf; /* Location to return the response */
uint16_t recv_buflen; /* Size of the response */
+ FAR struct msghdr *msg; /* Input message header */
int16_t recv_result; /* >=0: receive size on success;
* <0: negated errno on fail */
};
@@ -73,8 +75,8 @@ struct icmpv6_recvfrom_s
*
* Description:
* This function is called with the network locked to perform the actual
- * ECHO request and/or ECHO reply actions when polled by the lower, device
- * interfacing layer.
+ * ICMPv6 message actions when polled by the lower, device interfacing
+ * layer.
*
* Input Parameters:
* dev The structure of the network driver that generated the
@@ -113,15 +115,18 @@ static uint16_t recvfrom_eventhandler(FAR struct
net_driver_s *dev,
psock = pstate->recv_sock;
DEBUGASSERT(psock != NULL && psock->s_conn != NULL);
- /* Check if we have just received a ICMPv6 ECHO reply. */
+ /* Check if we have just received a ICMPv6 message. */
if ((flags & ICMPv6_NEWDATA) != 0) /* No incoming data */
{
+#ifdef CONFIG_NET_SOCKOPTS
+ FAR struct icmpv6_conn_s *conn = psock->s_conn;
+#endif
unsigned int recvsize;
- ninfo("Received ICMPv6 reply\n");
+ ninfo("Received ICMPv6 message\n");
- /* What should we do if the received reply is larger that the
+ /* What should we do if the received message is larger that the
* buffer that the caller of sendto provided? Truncate? Error
* out?
*/
@@ -132,7 +137,7 @@ static uint16_t recvfrom_eventhandler(FAR struct
net_driver_s *dev,
recvsize = pstate->recv_buflen;
}
- /* Copy the ICMPv6 ECHO reply to the user provided buffer
+ /* Copy the ICMPv6 message to the user provided buffer
* REVISIT: What if there are IPv6 extension headers present?
*/
@@ -150,7 +155,17 @@ static uint16_t recvfrom_eventhandler(FAR struct
net_driver_s *dev,
/* Indicate that the data has been consumed */
- flags &= ~ICMPv6_NEWDATA;
+ flags &= ~ICMPv6_NEWDATA;
+#ifdef CONFIG_NET_SOCKOPTS
+ if (_SO_GETOPT(conn->sconn.s_options, IPV6_RECVHOPLIMIT))
+ {
+ int hoplimit = ipv6->ttl;
+
+ cmsg_append(pstate->msg, SOL_IPV6, IPV6_HOPLIMIT,
+ &hoplimit, sizeof(hoplimit));
+ }
+#endif
+
dev->d_len = 0;
goto end_wait;
}
@@ -196,9 +211,8 @@ end_wait:
****************************************************************************/
static inline ssize_t icmpv6_readahead(FAR struct icmpv6_conn_s *conn,
- FAR void *buf, size_t buflen,
- FAR struct sockaddr_in6 *from,
- FAR socklen_t *fromlen)
+ FAR void *buf, size_t buflen,
+ FAR struct msghdr *msg)
{
FAR struct iob_s *iob;
ssize_t ret = -ENODATA;
@@ -213,10 +227,21 @@ static inline ssize_t icmpv6_readahead(FAR struct
icmpv6_conn_s *conn,
/* Then get address */
- if (from != NULL)
+ if (msg->msg_name != NULL)
{
- memcpy(from, iob->io_data, sizeof(struct sockaddr_in6));
+ memcpy(msg->msg_name, iob->io_data, sizeof(struct sockaddr_in6));
+ }
+
+#ifdef CONFIG_NET_SOCKOPTS
+ if (_SO_GETOPT(conn->sconn.s_options, IPV6_RECVHOPLIMIT))
+ {
+ int hoplimit;
+
+ hoplimit = iob->io_data[sizeof(struct sockaddr_in6)];
+ cmsg_append(msg, SOL_IPV6, IPV6_HOPLIMIT,
+ &hoplimit, sizeof(hoplimit));
}
+#endif
/* Copy to user */
@@ -248,7 +273,7 @@ static inline ssize_t icmpv6_readahead(FAR struct
icmpv6_conn_s *conn,
* Description:
* Implements the socket recvfrom interface for the case of the AF_INET
* data gram socket with the IPPROTO_ICMP6 protocol. icmpv6_recvmsg()
- * receives ICMPv6 ECHO replies for the a socket.
+ * receives ICMPv6 message for the a socket.
*
* If msg_name is not NULL, and the underlying protocol provides the source
* address, this source address is filled in. The argument 'msg_namelen' is
@@ -325,8 +350,7 @@ ssize_t icmpv6_recvmsg(FAR struct socket *psock, FAR struct
msghdr *msg,
if (!IOB_QEMPTY(&conn->readahead))
{
- ret = icmpv6_readahead(conn, buf, len,
- (FAR struct sockaddr_in6 *)from, fromlen);
+ ret = icmpv6_readahead(conn, buf, len, msg);
}
else if (_SS_ISNONBLOCK(conn->sconn.s_flags) ||
(flags & MSG_DONTWAIT) != 0)
@@ -346,6 +370,7 @@ ssize_t icmpv6_recvmsg(FAR struct socket *psock, FAR struct
msghdr *msg,
state.recv_result = -ENOMEM; /* Assume allocation failure */
state.recv_buf = buf; /* Location to return the response */
state.recv_buflen = len; /* Size of the response */
+ state.msg = msg; /* Input message header */
/* Set up the callback */
diff --git a/net/inet/ipv6_setsockopt.c b/net/inet/ipv6_setsockopt.c
index 0dc425f9ec..69692a6da1 100644
--- a/net/inet/ipv6_setsockopt.c
+++ b/net/inet/ipv6_setsockopt.c
@@ -128,6 +128,7 @@ int ipv6_setsockopt(FAR struct socket *psock, int option,
break;
case IPV6_RECVPKTINFO:
+ case IPV6_RECVHOPLIMIT:
{
FAR struct socket_conn_s *conn;
int enable;