CVE-2017-12985/IPv6: Check for print routines returning -1 when running past the end.

rt6_print(), ah_print(), and esp_print() return -1 if they run up
against the end of the packet while dissecting; if that happens, stop
dissecting, don't try to fetch the next header value, because 1) *it*
might be past the end of the packet and 2) we won't be using it in any
case, as we'll be exiting the loop.

Also, change mobility_print() to return -1 if it runs up against the
end of the packet, and stop dissecting if it does so.

This fixes a buffer over-read discovered by Brian 'geeknik' Carpenter.

Add tests using the capture files supplied by the reporter(s).
diff --git a/print-ip6.c b/print-ip6.c
index 0075fce..f2f56ef 100644
--- a/print-ip6.c
+++ b/print-ip6.c
@@ -280,6 +280,8 @@
 	advance = sizeof(struct ip6_hdr);
 	nh = ip6->ip6_nxt;
 	while (cp < ndo->ndo_snapend && advance > 0) {
+		if (len < (u_int)advance)
+			goto trunc;
 		cp += advance;
 		len -= advance;
 
@@ -322,10 +324,15 @@
 			 * mobility header.
 			 */
 			advance = mobility_print(ndo, cp, (const u_char *)ip6);
+			if (advance < 0)
+				return;
 			nh = *cp;
 			return;
 		case IPPROTO_ROUTING:
+			ND_TCHECK(*cp);
 			advance = rt6_print(ndo, cp, (const u_char *)ip6);
+			if (advance < 0)
+				return;
 			nh = *cp;
 			break;
 		case IPPROTO_SCTP:
@@ -345,12 +352,16 @@
 			return;
 		case IPPROTO_AH:
 			advance = ah_print(ndo, cp);
+			if (advance < 0)
+				return;
 			nh = *cp;
 			break;
 		case IPPROTO_ESP:
 		    {
 			int enh, padlen;
 			advance = esp_print(ndo, cp, len, (const u_char *)ip6, &enh, &padlen);
+			if (advance < 0)
+				return;
 			nh = enh & 0xff;
 			len -= padlen;
 			break;
diff --git a/print-mobility.c b/print-mobility.c
index c7c03ee..ca55413 100644
--- a/print-mobility.c
+++ b/print-mobility.c
@@ -332,5 +332,5 @@
 
  trunc:
 	ND_PRINT((ndo, "%s", tstr));
-	return(mhlen);
+	return(-1);
 }
diff --git a/tests/TESTLIST b/tests/TESTLIST
index c18586f..9b60df2 100644
--- a/tests/TESTLIST
+++ b/tests/TESTLIST
@@ -432,6 +432,8 @@
 otv-heapoverflow-2	otv-heapoverflow-2.pcap		otv-heapoverflow-2.out		-c10
 q933-heapoverflow-2	q933-heapoverflow-2.pcap	q933-heapoverflow-2.out
 atm-heapoverflow	atm-heapoverflow.pcap		atm-heapoverflow.out		-c1 -e
+ipv6-next-header-oobr-1	ipv6-next-header-oobr-1.pcap	ipv6-next-header-oobr-1.out
+ipv6-next-header-oobr-2	ipv6-next-header-oobr-2.pcap	ipv6-next-header-oobr-2.out
 
 # bad packets from Kamil Frankowicz
 snmp-heapoverflow-1	snmp-heapoverflow-1.pcap	snmp-heapoverflow-1.out
diff --git a/tests/ipv6-next-header-oobr-1.out b/tests/ipv6-next-header-oobr-1.out
new file mode 100644
index 0000000..74eaf72
--- /dev/null
+++ b/tests/ipv6-next-header-oobr-1.out
@@ -0,0 +1 @@
+IP6 3030:3030:3030:3030:3030:3030:3030:3030 > 3030:3030:3030:3030:3030:3030:3030:3030: HBH [|ip6]
diff --git a/tests/ipv6-next-header-oobr-1.pcap b/tests/ipv6-next-header-oobr-1.pcap
new file mode 100644
index 0000000..767350d
--- /dev/null
+++ b/tests/ipv6-next-header-oobr-1.pcap
Binary files differ
diff --git a/tests/ipv6-next-header-oobr-2.out b/tests/ipv6-next-header-oobr-2.out
new file mode 100644
index 0000000..911d2ae
--- /dev/null
+++ b/tests/ipv6-next-header-oobr-2.out
@@ -0,0 +1 @@
+IP6 3030:3030:3030:3030:3030:3030:3030:3030 > 3030:3030:3030:3030:3030:3030:3030:3030: HBH [|AH]
diff --git a/tests/ipv6-next-header-oobr-2.pcap b/tests/ipv6-next-header-oobr-2.pcap
new file mode 100644
index 0000000..1be5729
--- /dev/null
+++ b/tests/ipv6-next-header-oobr-2.pcap
Binary files differ