mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-10-05 22:29:49 +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 */
|
#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 */
|
#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",
|
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IPV6, IPV6_V6ONLY, ..) -> %d\n",
|
||||||
s, (netconn_get_ipv6only(sock->conn) ? 1 : 0)));
|
s, (netconn_get_ipv6only(sock->conn) ? 1 : 0)));
|
||||||
break;
|
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
|
#if LWIP_MULTICAST_TX_OPTIONS && LWIP_UDP
|
||||||
case IPV6_MULTICAST_IF:
|
case IPV6_MULTICAST_IF:
|
||||||
LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, int, NETCONN_UDP);
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
err = pbuf_copy(q, p);
|
err = pbuf_copy(q, p);
|
||||||
|
q->if_idx = p->if_idx;
|
||||||
LWIP_UNUSED_ARG(err); /* in case of LWIP_NOASSERT */
|
LWIP_UNUSED_ARG(err); /* in case of LWIP_NOASSERT */
|
||||||
LWIP_ASSERT("pbuf_copy failed", err == ERR_OK);
|
LWIP_ASSERT("pbuf_copy failed", err == ERR_OK);
|
||||||
return q;
|
return q;
|
||||||
|
@ -299,6 +299,8 @@ struct linger {
|
|||||||
#define IPV6_CHECKSUM 7 /* RFC3542: calculate and insert the ICMPv6 checksum for raw sockets. */
|
#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_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_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 */
|
#endif /* LWIP_IPV6 */
|
||||||
|
|
||||||
#if LWIP_UDP && LWIP_UDPLITE
|
#if LWIP_UDP && LWIP_UDPLITE
|
||||||
@ -343,6 +345,13 @@ struct in_pktinfo {
|
|||||||
};
|
};
|
||||||
#endif /* LWIP_IPV4 */
|
#endif /* LWIP_IPV4 */
|
||||||
|
|
||||||
|
#if LWIP_IPV6
|
||||||
|
struct in6_pktinfo {
|
||||||
|
struct in6_addr ipi6_addr;
|
||||||
|
int ipi6_ifindex;
|
||||||
|
};
|
||||||
|
#endif /* LWIP_IPV6 */
|
||||||
|
|
||||||
#if LWIP_IPV6_MLD
|
#if LWIP_IPV6_MLD
|
||||||
/*
|
/*
|
||||||
* Options and types related to IPv6 multicast membership
|
* Options and types related to IPv6 multicast membership
|
||||||
|
Loading…
Reference in New Issue
Block a user