+/*
+ * Sub-TLVs consume the "extra data" of Babel TLVs (see Section 4.3 of RFC6126),
+ * their encoding is similar to the encoding of TLVs, but the type namespace is
+ * different:
+ *
+ * o Type 0 stands for Pad1 sub-TLV with the same encoding as the Pad1 TLV.
+ * o Type 1 stands for PadN sub-TLV with the same encoding as the PadN TLV.
+ * o Type 2 stands for ChanInfo sub-TLV, which propagates diversity routing
+ * data. Its body is a variable-length sequence of 8-bit unsigned integers,
+ * each representing per-hop number of interferring radio channel for the
+ * prefix. Channel 0 is invalid and must not be used in the sub-TLV, channel
+ * 255 interferes with any other channel.
+ *
+ * Sub-TLV types 0 and 1 are valid for any TLV type, whether sub-TLV type 2 is
+ * only valid for TLV type 8 (Update). Note that within an Update TLV a missing
+ * ChanInfo sub-TLV is not the same as a ChanInfo sub-TLV with an empty body.
+ * The former would mean a lack of any claims about the interference, and the
+ * latter would state that interference is definitely absent. */
+static void
+subtlvs_print(const u_char *cp, const u_char *ep, const uint8_t tlv_type) {
+ uint8_t subtype, sublen;
+ const char *sep;
+
+ while (cp < ep) {
+ subtype = *cp++;
+ if(subtype == MESSAGE_SUB_PAD1) {
+ printf(" sub-pad1");
+ continue;
+ }
+ if(cp == ep)
+ goto corrupt;
+ sublen = *cp++;
+ if(cp + sublen > ep)
+ goto corrupt;
+
+ switch(subtype) {
+ case MESSAGE_SUB_PADN:
+ printf(" sub-padn");
+ cp += sublen;
+ break;
+ case MESSAGE_SUB_CHANINFO:
+ printf(" sub-chaninfo");
+ if (sublen == 0) {
+ printf(" empty");
+ break;
+ }
+ sep = " ";
+ while(sublen--) {
+ printf("%s%s", sep, tok2str(chaninfo_str, "%u", *cp++));
+ sep = "-";
+ }
+ if(tlv_type != MESSAGE_UPDATE)
+ printf(" (bogus)");
+ break;
+ default:
+ printf(" sub-unknown-0x%02x", subtype);
+ cp += sublen;
+ } /* switch */
+ } /* while */
+ return;
+
+ corrupt:
+ printf(" (corrupt)");
+}
+