+ case RSVP_OBJ_GENERALIZED_UNI:
+ switch(rsvp_obj_ctype) {
+ u_int subobj_type,af,subobj_len,total_subobj_len;
+
+ case RSVP_CTYPE_1:
+
+ if (obj_tlen < 4)
+ goto obj_tooshort;
+
+ /* read variable length subobjects */
+ total_subobj_len = obj_tlen;
+ while(total_subobj_len > 0) {
+ /* If RFC 3476 Section 3.1 defined that a sub-object of the
+ * GENERALIZED_UNI RSVP object must have the Length field as
+ * a multiple of 4, instead of the check below it would be
+ * better to test total_subobj_len only once before the loop.
+ * So long as it does not define it and this while loop does
+ * not implement such a requirement, let's accept that within
+ * each iteration subobj_len may happen to be a multiple of 1
+ * and test it and total_subobj_len respectively.
+ */
+ if (total_subobj_len < 4)
+ goto invalid;
+ subobj_len = GET_BE_U_2(obj_tptr);
+ subobj_type = (GET_BE_U_2(obj_tptr + 2))>>8;
+ af = (GET_BE_U_2(obj_tptr + 2))&0x00FF;
+
+ ND_PRINT("%s Subobject Type: %s (%u), AF: %s (%u), length: %u",
+ indent,
+ tok2str(rsvp_obj_generalized_uni_values, "Unknown", subobj_type),
+ subobj_type,
+ tok2str(af_values, "Unknown", af), af,
+ subobj_len);
+
+ /* In addition to what is explained above, the same spec does not
+ * explicitly say that the same Length field includes the 4-octet
+ * sub-object header, but as long as this while loop implements it
+ * as it does include, let's keep the check below consistent with
+ * the rest of the code.
+ *
+ * XXX - RFC 3476 Section 3.1 says "The contents of these
+ * sub-objects are described in [8]", where [8] is
+ * UNI 1.0 Signaling Specification, The Optical
+ * Internetworking Forum. The URL they give for that
+ * document is
+ *
+ * http://www.oiforum.com/public/UNI_1.0_ia.html
+ *
+ * but that doesn't work; the new URL appears to be
+ *
+ * https://web.archive.org/web/20160401194747/http://www.oiforum.com/public/documents/OIF-UNI-01.0.pdf
+ *
+ * and *that* document, in section 12.5.2.3
+ * "GENERALIZED_UNI Object (Class-Num=11bbbbbb (TBA))",
+ * says nothing about the length field in general, but
+ * some of the examples it gives in subsections have
+ * length field values that clearly includes the length
+ * of the sub-object header as well as the length of the
+ * value.
+ */
+ if(subobj_len < 4 || subobj_len > total_subobj_len ||
+ obj_tlen < subobj_len)
+ goto invalid;
+
+ switch(subobj_type) {
+ case RSVP_GEN_UNI_SUBOBJ_SOURCE_TNA_ADDRESS:
+ case RSVP_GEN_UNI_SUBOBJ_DESTINATION_TNA_ADDRESS:
+
+ switch(af) {
+ case AFNUM_INET:
+ if (subobj_len < 8)
+ goto subobj_tooshort;
+ ND_PRINT("%s UNI IPv4 TNA address: %s",
+ indent, GET_IPADDR_STRING(obj_tptr + 4));
+ break;
+ case AFNUM_INET6:
+ if (subobj_len < 20)
+ goto subobj_tooshort;
+ ND_PRINT("%s UNI IPv6 TNA address: %s",
+ indent, GET_IP6ADDR_STRING(obj_tptr + 4));
+ break;
+ case AFNUM_NSAP:
+ if (subobj_len) {
+ /* unless we have a TLV parser lets just hexdump */
+ hexdump=TRUE;
+ }
+ break;
+ }
+ break;
+
+ case RSVP_GEN_UNI_SUBOBJ_DIVERSITY:
+ if (subobj_len > 4) {
+ /* unless we have a TLV parser lets just hexdump */
+ hexdump=TRUE;
+ }
+ break;
+
+ case RSVP_GEN_UNI_SUBOBJ_EGRESS_LABEL:
+ if (subobj_len < 16) {
+ goto subobj_tooshort;
+ }
+
+ ND_PRINT("%s U-bit: %x, Label type: %u, Logical port id: %u, Label: %u",
+ indent,
+ ((GET_BE_U_4(obj_tptr + 4))>>31),
+ ((GET_BE_U_4(obj_tptr + 4))&0xFF),
+ GET_BE_U_4(obj_tptr + 8),
+ GET_BE_U_4(obj_tptr + 12));
+ break;
+
+ case RSVP_GEN_UNI_SUBOBJ_SERVICE_LEVEL:
+ if (subobj_len < 8) {
+ goto subobj_tooshort;
+ }
+
+ ND_PRINT("%s Service level: %u",
+ indent, (GET_BE_U_4(obj_tptr + 4)) >> 24);
+ break;
+
+ default:
+ hexdump=TRUE;
+ break;
+ }
+ total_subobj_len-=subobj_len;
+ obj_tptr+=subobj_len;
+ obj_tlen+=subobj_len;
+ }