Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 25 May 2016 22:16:11 +0000 (UTC)
From:      Michael Tuexen <tuexen@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r300699 - head/sys/netinet
Message-ID:  <201605252216.u4PMGBrb014918@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: tuexen
Date: Wed May 25 22:16:11 2016
New Revision: 300699
URL: https://svnweb.freebsd.org/changeset/base/300699

Log:
  When sending in ICMP response to an SCTP packet,
  * include the SCTP common header, if possible
  * include the first 8 bytes of the INIT chunk, if possible
  This provides the necesary information for the receiver of the ICMP
  packet to process it.
  
  MFC after:	1 week

Modified:
  head/sys/netinet/ip_icmp.c

Modified: head/sys/netinet/ip_icmp.c
==============================================================================
--- head/sys/netinet/ip_icmp.c	Wed May 25 20:56:30 2016	(r300698)
+++ head/sys/netinet/ip_icmp.c	Wed May 25 22:16:11 2016	(r300699)
@@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$");
 #include <netinet/ip_icmp.h>
 #include <netinet/ip_var.h>
 #include <netinet/ip_options.h>
+#include <netinet/sctp.h>
 #include <netinet/tcp.h>
 #include <netinet/tcp_var.h>
 #include <netinet/tcpip.h>
@@ -249,6 +250,34 @@ icmp_error(struct mbuf *n, int type, int
 			goto freeit;
 		icmpelen = max(tcphlen, min(V_icmp_quotelen,
 		    ntohs(oip->ip_len) - oiphlen));
+	} else if (oip->ip_p == IPPROTO_SCTP) {
+		struct sctphdr *sh;
+		struct sctp_chunkhdr *ch;
+
+		if (ntohs(oip->ip_len) < oiphlen + sizeof(struct sctphdr))
+			goto stdreply;
+		if (oiphlen + sizeof(struct sctphdr) > n->m_len &&
+		    n->m_next == NULL)
+			goto stdreply;
+		if (n->m_len < oiphlen + sizeof(struct sctphdr) &&
+		    (n = m_pullup(n, oiphlen + sizeof(struct sctphdr))) == NULL)
+			goto freeit;
+		icmpelen = max(sizeof(struct sctphdr),
+		    min(V_icmp_quotelen, ntohs(oip->ip_len) - oiphlen));
+		sh = (struct sctphdr *)((caddr_t)oip + oiphlen);
+		if (ntohl(sh->v_tag) == 0 &&
+		    ntohs(oip->ip_len) >= oiphlen + sizeof(struct sctphdr) + 8 &&
+		    (n->m_len >= oiphlen + sizeof(struct sctphdr) + 8 ||
+		     n->m_next != NULL)) {
+			if (n->m_len < oiphlen + sizeof(struct sctphdr) + 8 &&
+			    (n = m_pullup(n, oiphlen + sizeof(struct sctphdr) + 8)) == NULL)
+				goto freeit;
+			ch = (struct sctp_chunkhdr *)(sh + 1);
+			if (ch->chunk_type == SCTP_INITIATION) {
+				icmpelen = max(sizeof(struct sctphdr) + 8,
+				    min(V_icmp_quotelen, ntohs(oip->ip_len) - oiphlen));
+			}
+		}
 	} else
 stdreply:	icmpelen = max(8, min(V_icmp_quotelen, ntohs(oip->ip_len) - oiphlen));
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201605252216.u4PMGBrb014918>