From 2694486309b1839b151dfa936b8f725c65954c68 Mon Sep 17 00:00:00 2001 From: Knut Andre Tidemann Date: Wed, 11 Jan 2017 12:11:20 +0100 Subject: [PATCH] lwip: fix broken default ICMPv6 handling of checksums. ICMPv6 should always have checksum generated for it as per RFC 3542 chapter 3.1. (cherry picked from commit 5e9df2c6988f8e00185e793205f371fe817714e9) --- src/api/api_msg.c | 8 ++++++++ src/api/sockets.c | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/src/api/api_msg.c b/src/api/api_msg.c index 4927ee50..b45d23f8 100644 --- a/src/api/api_msg.c +++ b/src/api/api_msg.c @@ -53,6 +53,7 @@ #include "lwip/dns.h" #include "lwip/mld6.h" #include "lwip/priv/tcpip_priv.h" +#include "lwip/sockets.h" #include @@ -562,6 +563,13 @@ pcb_new(struct api_msg *msg) case NETCONN_RAW: msg->conn->pcb.raw = raw_new_ip_type(iptype, msg->msg.n.proto); if (msg->conn->pcb.raw != NULL) { +#if LWIP_IPV6 + /* ICMPv6 packets should always have checksum calculated by the stack as per RFC 3542 chapter 3.1 */ + if (NETCONNTYPE_ISIPV6(msg->conn->type) && msg->conn->pcb.raw->protocol == IPPROTO_ICMPV6) { + msg->conn->pcb.raw->chksum_reqd = 1; + msg->conn->pcb.raw->chksum_offset = 2; + } +#endif /* LWIP_IPV6 */ raw_recv(msg->conn->pcb.raw, recv_raw, msg->conn); } break; diff --git a/src/api/sockets.c b/src/api/sockets.c index 24b3b5fa..0d0a1fa1 100644 --- a/src/api/sockets.c +++ b/src/api/sockets.c @@ -2574,6 +2574,12 @@ lwip_setsockopt_impl(int s, int level, int optname, const void *optval, socklen_ switch (optname) { #if LWIP_IPV6 && LWIP_RAW case IPV6_CHECKSUM: + /* It should not be possible to disable the checksum generation with ICMPv6 + * as per RFC 3542 chapter 3.1 */ + if(sock->conn->pcb.raw->protocol == IPPROTO_ICMPV6) { + return EINVAL; + } + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, int, NETCONN_RAW); if (*(const int *)optval < 0) { sock->conn->pcb.raw->chksum_reqd = 0;