diff --git a/include/zephyr/net/socket.h b/include/zephyr/net/socket.h index 7d0c2c79c91..adf756c3650 100644 --- a/include/zephyr/net/socket.h +++ b/include/zephyr/net/socket.h @@ -1095,10 +1095,33 @@ struct ifreq { /** sockopt: Set or receive the Type-Of-Service value for an outgoing packet. */ #define IP_TOS 1 +/** sockopt: Pass an IP_PKTINFO ancillary message that contains a + * pktinfo structure that supplies some information about the + * incoming packet. + */ +#define IP_PKTINFO 8 + +struct in_pktinfo { + unsigned int ipi_ifindex; /* Interface index */ + struct in_addr ipi_spec_dst; /* Local address */ + struct in_addr ipi_addr; /* Header Destination address */ +}; + /* Socket options for IPPROTO_IPV6 level */ /** sockopt: Don't support IPv4 access (ignored, for compatibility) */ #define IPV6_V6ONLY 26 +/** sockopt: Pass an IPV6_RECVPKTINFO ancillary message that contains a + * in6_pktinfo structure that supplies some information about the + * incoming packet. See RFC 3542. + */ +#define IPV6_RECVPKTINFO 49 + +struct in6_pktinfo { + struct in6_addr ipi6_addr; /* src/dst IPv6 address */ + unsigned int ipi6_ifindex; /* send/recv interface index */ +}; + /** sockopt: Set or receive the traffic class value for an outgoing packet. */ #define IPV6_TCLASS 67 diff --git a/subsys/net/lib/sockets/sockets.c b/subsys/net/lib/sockets/sockets.c index 8bdd99b61c9..d1e2a69aa1d 100644 --- a/subsys/net/lib/sockets/sockets.c +++ b/subsys/net/lib/sockets/sockets.c @@ -2756,6 +2756,23 @@ int zsock_setsockopt_ctx(struct net_context *ctx, int level, int optname, return 0; } + break; + + case IP_PKTINFO: + if (IS_ENABLED(CONFIG_NET_IPV4) && + IS_ENABLED(CONFIG_NET_CONTEXT_RECV_PKTINFO)) { + ret = net_context_set_option(ctx, + NET_OPT_RECV_PKTINFO, + optval, + optlen); + if (ret < 0) { + errno = -ret; + return -1; + } + + return 0; + } + break; } @@ -2777,6 +2794,23 @@ int zsock_setsockopt_ctx(struct net_context *ctx, int level, int optname, return 0; + case IPV6_RECVPKTINFO: + if (IS_ENABLED(CONFIG_NET_IPV6) && + IS_ENABLED(CONFIG_NET_CONTEXT_RECV_PKTINFO)) { + ret = net_context_set_option(ctx, + NET_OPT_RECV_PKTINFO, + optval, + optlen); + if (ret < 0) { + errno = -ret; + return -1; + } + + return 0; + } + + break; + case IPV6_TCLASS: if (IS_ENABLED(CONFIG_NET_CONTEXT_DSCP_ECN)) { ret = net_context_set_option(ctx,