+ case LSPPING_TLV_DOWNSTREAM_MAPPING:
+ /* Does the header go past the end of the TLV? */
+ if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_t)) {
+ ND_PRINT("\n\t TLV is too short");
+ tlv_hexdump = TRUE;
+ goto tlv_tooshort;
+ }
+ /* Did we capture enough to get the address family? */
+ ND_TCHECK_LEN(tlv_tptr,
+ sizeof(struct lspping_tlv_downstream_map_t));
+
+ tlv_ptr.lspping_tlv_downstream_map=
+ (const struct lspping_tlv_downstream_map_t *)tlv_tptr;
+
+ /* that strange thing with the downstream map TLV is that until now
+ * we do not know if its IPv4 or IPv6 or is unnumbered; after
+ * we find the address-type, we recast the tlv_tptr and move on. */
+
+ address_type = GET_U_1(tlv_ptr.lspping_tlv_downstream_map->address_type);
+ ND_PRINT("\n\t MTU: %u, Address-Type: %s (%u)",
+ GET_BE_U_2(tlv_ptr.lspping_tlv_downstream_map->mtu),
+ tok2str(lspping_tlv_downstream_addr_values,
+ "unknown",
+ address_type),
+ address_type);
+
+ switch(address_type) {
+
+ case LSPPING_AFI_IPV4:
+ /* Does the data go past the end of the TLV? */
+ if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv4_t)) {
+ ND_PRINT("\n\t TLV is too short");
+ tlv_hexdump = TRUE;
+ goto tlv_tooshort;
+ }
+ /* Did we capture enough for this part of the TLV? */
+ ND_TCHECK_LEN(tlv_tptr,
+ sizeof(struct lspping_tlv_downstream_map_ipv4_t));
+
+ tlv_ptr.lspping_tlv_downstream_map_ipv4=
+ (const struct lspping_tlv_downstream_map_ipv4_t *)tlv_tptr;
+ ND_PRINT("\n\t Downstream IP: %s"
+ "\n\t Downstream Interface IP: %s",
+ GET_IPADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_ip),
+ GET_IPADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_interface));
+ tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv4_t);
+ tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv4_t);
+ break;
+ case LSPPING_AFI_IPV4_UNMB:
+ /* Does the data go past the end of the TLV? */
+ if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t)) {
+ ND_PRINT("\n\t TLV is too short");
+ tlv_hexdump = TRUE;
+ goto tlv_tooshort;
+ }
+ /* Did we capture enough for this part of the TLV? */
+ ND_TCHECK_LEN(tlv_tptr,
+ sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t));
+
+ tlv_ptr.lspping_tlv_downstream_map_ipv4_unmb=
+ (const struct lspping_tlv_downstream_map_ipv4_unmb_t *)tlv_tptr;
+ ND_PRINT("\n\t Downstream IP: %s"
+ "\n\t Downstream Interface Index: 0x%08x",
+ GET_IPADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv4_unmb->downstream_ip),
+ GET_BE_U_4(tlv_ptr.lspping_tlv_downstream_map_ipv4_unmb->downstream_interface));
+ tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t);
+ tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t);
+ break;
+ case LSPPING_AFI_IPV6:
+ /* Does the data go past the end of the TLV? */
+ if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv6_t)) {
+ ND_PRINT("\n\t TLV is too short");
+ tlv_hexdump = TRUE;
+ goto tlv_tooshort;
+ }
+ /* Did we capture enough for this part of the TLV? */
+ ND_TCHECK_LEN(tlv_tptr,
+ sizeof(struct lspping_tlv_downstream_map_ipv6_t));
+
+ tlv_ptr.lspping_tlv_downstream_map_ipv6=
+ (const struct lspping_tlv_downstream_map_ipv6_t *)tlv_tptr;
+ ND_PRINT("\n\t Downstream IP: %s"
+ "\n\t Downstream Interface IP: %s",
+ GET_IP6ADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv6->downstream_ip),
+ GET_IP6ADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv6->downstream_interface));
+ tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv6_t);
+ tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv6_t);
+ break;
+ case LSPPING_AFI_IPV6_UNMB:
+ /* Does the data go past the end of the TLV? */
+ if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t)) {
+ ND_PRINT("\n\t TLV is too short");
+ tlv_hexdump = TRUE;
+ goto tlv_tooshort;
+ }
+ /* Did we capture enough for this part of the TLV? */
+ ND_TCHECK_LEN(tlv_tptr,
+ sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t));
+
+ tlv_ptr.lspping_tlv_downstream_map_ipv6_unmb=
+ (const struct lspping_tlv_downstream_map_ipv6_unmb_t *)tlv_tptr;
+ ND_PRINT("\n\t Downstream IP: %s"
+ "\n\t Downstream Interface Index: 0x%08x",
+ GET_IP6ADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv6_unmb->downstream_ip),
+ GET_BE_U_4(tlv_ptr.lspping_tlv_downstream_map_ipv6_unmb->downstream_interface));
+ tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t);
+ tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t);
+ break;
+
+ default:
+ /* should not happen ! - no error message - tok2str() has barked already */
+ break;
+ }
+
+ /* Does the data go past the end of the TLV? */
+ if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_info_t)) {
+ ND_PRINT("\n\t TLV is too short");
+ tlv_hexdump = TRUE;
+ goto tlv_tooshort;
+ }
+ /* Did we capture enough for this part of the TLV? */
+ ND_TCHECK_LEN(tlv_tptr,
+ sizeof(struct lspping_tlv_downstream_map_info_t));
+
+ tlv_ptr.lspping_tlv_downstream_map_info=
+ (const struct lspping_tlv_downstream_map_info_t *)tlv_tptr;
+
+ /* FIXME add hash-key type, depth limit, multipath processing */
+
+ /* FIXME print downstream labels */
+
+ tlv_hexdump=TRUE; /* dump the TLV until code complete */
+
+ break;
+
+ case LSPPING_TLV_BFD_DISCRIMINATOR:
+ if (tlv_tlen < LSPPING_TLV_BFD_DISCRIMINATOR_LEN) {
+ ND_PRINT("\n\t TLV is too short");
+ tlv_hexdump = TRUE;
+ goto tlv_tooshort;
+ } else {
+ ND_PRINT("\n\t BFD Discriminator 0x%08x", GET_BE_U_4(tlv_tptr));
+ }
+ break;
+
+ case LSPPING_TLV_VENDOR_ENTERPRISE:
+ {
+ uint32_t vendor_id;
+
+ if (tlv_tlen < LSPPING_TLV_VENDOR_ENTERPRISE_LEN) {
+ ND_PRINT("\n\t TLV is too short");
+ tlv_hexdump = TRUE;
+ goto tlv_tooshort;
+ } else {
+ vendor_id = GET_BE_U_4(tlv_tptr);
+ ND_PRINT("\n\t Vendor: %s (0x%04x)",
+ tok2str(smi_values, "Unknown", vendor_id),
+ vendor_id);
+ }
+ }
+ break;
+