mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-07-07 21:38:50 +00:00
Implement IPV6_RECVPKTINFO socket option
Implements the IPV6_RECVPKTINFO socket option for receiving ancillary data about an IPv6 packet. Also fixes an issue where the interface index was not being copied and updates IP_PKTINFO flag to use netconn flags macros. Based on work from https://savannah.nongnu.org/patch/?9554 Co-authored-by: Christina Schoenrogge <christina.schoenrogge@garmin.com> Co-authored-by: Joseph Huang <joseph.huang@garmin.com> Co-authored-by: Chee Bin Hoh <hohcheebin@gmail.com> Co-authored-by: hanhui <hanhui03@163.com>
This commit is contained in:
parent
4dd7e9f816
commit
70a730df64
|
@ -1214,6 +1214,23 @@ lwip_recvfrom_udp_raw(struct lwip_sock *sock, int flags, struct msghdr *msg, u16
|
|||
}
|
||||
#endif /* LWIP_IPV4 */
|
||||
}
|
||||
#if LWIP_IPV6
|
||||
else if (IP_IS_V6(&buf->toaddr)) {
|
||||
if (msg->msg_controllen >= CMSG_SPACE(sizeof(struct in6_pktinfo))) {
|
||||
struct cmsghdr *chdr = CMSG_FIRSTHDR(msg); /* This will always return a header!! */
|
||||
struct in6_pktinfo *pkti = (struct in6_pktinfo *)CMSG_DATA(chdr);
|
||||
chdr->cmsg_level = IPPROTO_IPV6;
|
||||
chdr->cmsg_type = IPV6_PKTINFO;
|
||||
chdr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
|
||||
pkti->ipi6_ifindex = buf->p->if_idx;
|
||||
inet6_addr_from_ip6addr(&pkti->ipi6_addr, ip_2_ip6(netbuf_destaddr(buf)));
|
||||
msg->msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo));
|
||||
wrote_msg = 1;
|
||||
} else {
|
||||
msg->msg_flags |= MSG_CTRUNC;
|
||||
}
|
||||
}
|
||||
#endif /* LWIP_IPV6 */
|
||||
}
|
||||
#endif /* LWIP_NETBUF_RECVINFO */
|
||||
|
||||
|
@ -3676,6 +3693,18 @@ lwip_setsockopt_impl(int s, int level, int optname, const void *optval, socklen_
|
|||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IPV6, IPV6_V6ONLY, ..) -> %d\n",
|
||||
s, (netconn_get_ipv6only(sock->conn) ? 1 : 0)));
|
||||
break;
|
||||
#if LWIP_NETBUF_RECVINFO
|
||||
case IPV6_RECVPKTINFO:
|
||||
LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, int, NETCONN_UDP);
|
||||
if (*(const int *)optval) {
|
||||
netconn_set_flags(sock->conn, NETCONN_FLAG_PKTINFO);
|
||||
} else {
|
||||
netconn_clear_flags(sock->conn, NETCONN_FLAG_PKTINFO);
|
||||
}
|
||||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IPV6, IPV6_RECVPKTINFO, ..) -> %d\n",
|
||||
s, *(const int *)optval));
|
||||
break;
|
||||
#endif /* LWIP_NETBUF_RECVINFO */
|
||||
#if LWIP_MULTICAST_TX_OPTIONS && LWIP_UDP
|
||||
case IPV6_MULTICAST_IF:
|
||||
LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, int, NETCONN_UDP);
|
||||
|
|
|
@ -1343,6 +1343,7 @@ pbuf_clone(pbuf_layer layer, pbuf_type type, struct pbuf *p)
|
|||
return NULL;
|
||||
}
|
||||
err = pbuf_copy(q, p);
|
||||
q->if_idx = p->if_idx;
|
||||
LWIP_UNUSED_ARG(err); /* in case of LWIP_NOASSERT */
|
||||
LWIP_ASSERT("pbuf_copy failed", err == ERR_OK);
|
||||
return q;
|
||||
|
|
|
@ -299,6 +299,8 @@ struct linger {
|
|||
#define IPV6_CHECKSUM 7 /* RFC3542: calculate and insert the ICMPv6 checksum for raw sockets. */
|
||||
#define IPV6_UNICAST_HOPS 16 /* RFC3493: hop limit in outgoing unicast IPv6 packets */
|
||||
#define IPV6_V6ONLY 27 /* RFC3493: boolean control to restrict AF_INET6 sockets to IPv6 communications only. */
|
||||
#define IPV6_RECVPKTINFO 49 /* RFC3542: receive ancillary data for packet */
|
||||
#define IPV6_PKTINFO 50 /* RFC3542: ancillary data for a packet */
|
||||
#endif /* LWIP_IPV6 */
|
||||
|
||||
#if LWIP_UDP && LWIP_UDPLITE
|
||||
|
@ -343,6 +345,13 @@ struct in_pktinfo {
|
|||
};
|
||||
#endif /* LWIP_IPV4 */
|
||||
|
||||
#if LWIP_IPV6
|
||||
struct in6_pktinfo {
|
||||
struct in6_addr ipi6_addr;
|
||||
int ipi6_ifindex;
|
||||
};
|
||||
#endif /* LWIP_IPV6 */
|
||||
|
||||
#if LWIP_IPV6_MLD
|
||||
/*
|
||||
* Options and types related to IPv6 multicast membership
|
||||
|
|
Loading…
Reference in New Issue
Block a user