diff -c 2.1.0/api_msg.c new/api_msg.c *** 2.1.0/api_msg.c 2018-07-02 23:26:20.000000000 +0800 --- new/api_msg.c 2018-11-12 23:30:08.306280900 +0800 *************** *** 189,194 **** --- 189,199 ---- ip_addr_copy(buf->addr, *ip_current_src_addr()); buf->port = pcb->protocol; + #if LWIP_NETBUF_RECVINFO + buf->flags = NETBUF_FLAG_DESTADDR; + ip_addr_set(&buf->toaddr, ip_current_dest_addr()); + #endif /* LWIP_NETBUF_RECVINFO */ + len = q->tot_len; if (sys_mbox_trypost(&conn->recvmbox, buf) != ERR_OK) { netbuf_delete(buf); diff -c 2.1.0/pbuf.c new/pbuf.c *** 2.1.0/pbuf.c 2018-07-20 03:41:43.000000000 +0800 --- new/pbuf.c 2018-11-15 22:01:50.462442600 +0800 *************** *** 1312,1317 **** --- 1312,1318 ---- return NULL; } err = pbuf_copy(q, p); + q->if_idx = p->if_idx; /* should copy if_idx info too */ LWIP_UNUSED_ARG(err); /* in case of LWIP_NOASSERT */ LWIP_ASSERT("pbuf_copy failed", err == ERR_OK); return q; diff -c 2.1.0/sockets.c new/sockets.c *** 2.1.0/sockets.c 2018-07-13 02:52:41.000000000 +0800 --- new/sockets.c 2018-11-15 21:41:21.448598100 +0800 *************** *** 1176,1181 **** --- 1176,1198 ---- } #endif /* LWIP_IPV4 */ } + else if (IP_IS_V6(&buf->toaddr)) { + #if LWIP_IPV6 + 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 */ *************** *** 3620,3626 **** struct netif *netif; ip6_addr_t multi_addr; const struct ipv6_mreq *imr = (const struct ipv6_mreq *)optval; ! LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, struct ipv6_mreq, NETCONN_UDP); inet6_addr_to_ip6addr(&multi_addr, &imr->ipv6mr_multiaddr); LWIP_ASSERT("Invalid netif index", imr->ipv6mr_interface <= 0xFFu); netif = netif_get_by_index((u8_t)imr->ipv6mr_interface); --- 3637,3643 ---- struct netif *netif; ip6_addr_t multi_addr; const struct ipv6_mreq *imr = (const struct ipv6_mreq *)optval; ! LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, struct ipv6_mreq, NETCONN_RAW); inet6_addr_to_ip6addr(&multi_addr, &imr->ipv6mr_multiaddr); LWIP_ASSERT("Invalid netif index", imr->ipv6mr_interface <= 0xFFu); netif = netif_get_by_index((u8_t)imr->ipv6mr_interface); diff -c 2.1.0/sockets.h new/sockets.h *** 2.1.0/sockets.h 2018-09-13 04:06:18.000000000 +0800 --- new/sockets.h 2018-11-12 23:16:45.304766100 +0800 *************** *** 289,294 **** --- 289,295 ---- */ #define IPV6_CHECKSUM 7 /* RFC3542: calculate and insert the ICMPv6 checksum for raw sockets. */ #define IPV6_V6ONLY 27 /* RFC3493: boolean control to restrict AF_INET6 sockets to IPv6 communications only. */ + #define IPV6_PKTINFO 49 #endif /* LWIP_IPV6 */ #if LWIP_UDP && LWIP_UDPLITE *************** *** 329,334 **** --- 330,344 ---- }; #endif /* LWIP_IPV4 */ + + #if LWIP_IPV6 + struct in6_pktinfo { + unsigned int ipi6_ifindex; /* Interface index */ + struct in6_addr ipi6_addr; /* Destination (from header) address */ + }; + #endif /* LWIP_IPV6 */ + + #if LWIP_IPV6_MLD /* * Options and types related to IPv6 multicast membership