- error_code, encapsulated_pdu_length));
-
- tptr += sizeof(*pdu);
- tlen -= sizeof(*pdu);
-
- /*
- * Recurse if there is an encapsulated PDU.
- */
- if (encapsulated_pdu_length &&
- (encapsulated_pdu_length <= tlen)) {
- ND_PRINT((ndo, "%s-----encapsulated PDU-----", indent_string(indent+4)));
- rpki_rtr_pdu_print(ndo, tptr, indent+2);
+ error_code, encapsulated_pdu_length);
+
+ if (encapsulated_pdu_length) {
+ /* Section 5.10 of RFC 6810 says:
+ * "An Error Report PDU MUST NOT be sent for an Error Report PDU."
+ *
+ * However, as far as the protocol encoding goes Error Report PDUs can
+ * happen to be nested in each other, however many times, in which case
+ * the decoder should still print such semantically incorrect PDUs.
+ *
+ * That said, "the Erroneous PDU field MAY be truncated" (ibid), thus
+ * to keep things simple this implementation decodes only the two
+ * outermost layers of PDUs and makes bounds checks in the outer and
+ * the inner PDU independently.
+ */
+ if (pdu_len < tlen + encapsulated_pdu_length)
+ goto invalid;
+ if (! recurse) {
+ ND_TCHECK_LEN(tptr, tlen + encapsulated_pdu_length);
+ }
+ else {
+ ND_PRINT("%s-----encapsulated PDU-----", indent_string(indent+4));
+ rpki_rtr_pdu_print(ndo, tptr + tlen,
+ encapsulated_pdu_length, 0, indent + 2);
+ }
+ tlen += encapsulated_pdu_length;