1 1.1 christos /* 2 1.1 christos * Redistribution and use in source and binary forms, with or without 3 1.1 christos * modification, are permitted provided that: (1) source code 4 1.1 christos * distributions retain the above copyright notice and this paragraph 5 1.1 christos * in its entirety, and (2) distributions including binary code include 6 1.1 christos * the above copyright notice and this paragraph in its entirety in 7 1.1 christos * the documentation or other materials provided with the distribution. 8 1.1 christos * THIS SOFTWARE IS PROVIDED ``AS IS'' AND 9 1.1 christos * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT 10 1.1 christos * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 11 1.1 christos * FOR A PARTICULAR PURPOSE. 12 1.1 christos * 13 1.9 christos * Original code by Hannes Gredler (hannes (at) gredler.at) 14 1.1 christos */ 15 1.1 christos 16 1.2 christos #include <sys/cdefs.h> 17 1.1 christos #ifndef lint 18 1.12 christos __RCSID("$NetBSD: print-lspping.c,v 1.12 2026/03/19 00:05:13 christos Exp $"); 19 1.1 christos #endif 20 1.1 christos 21 1.8 spz /* \summary: MPLS LSP PING printer */ 22 1.8 spz 23 1.10 christos /* specification: RFC 4379 */ 24 1.10 christos 25 1.10 christos #include <config.h> 26 1.1 christos 27 1.10 christos #include "netdissect-stdinc.h" 28 1.1 christos 29 1.10 christos #define ND_LONGJMP_FROM_TCHECK 30 1.7 christos #include "netdissect.h" 31 1.1 christos #include "extract.h" 32 1.1 christos #include "addrtoname.h" 33 1.10 christos #include "ntp.h" 34 1.1 christos 35 1.1 christos #include "l2vpn.h" 36 1.1 christos #include "oui.h" 37 1.1 christos 38 1.8 spz 39 1.1 christos /* 40 1.1 christos * LSPPING common header 41 1.1 christos * 42 1.1 christos * 0 1 2 3 43 1.1 christos * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 44 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 45 1.1 christos * | Version Number | Must Be Zero | 46 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 47 1.1 christos * | Message Type | Reply mode | Return Code | Return Subcode| 48 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 49 1.1 christos * | Sender's Handle | 50 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 51 1.1 christos * | Sequence Number | 52 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 53 1.1 christos * | TimeStamp Sent (seconds) | 54 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 55 1.1 christos * | TimeStamp Sent (microseconds) | 56 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 57 1.1 christos * | TimeStamp Received (seconds) | 58 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 59 1.1 christos * | TimeStamp Received (microseconds) | 60 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 61 1.1 christos * | TLVs ... | 62 1.1 christos * . . 63 1.1 christos * . . 64 1.1 christos * . . 65 1.1 christos */ 66 1.1 christos 67 1.1 christos struct lspping_common_header { 68 1.10 christos nd_uint16_t version; 69 1.10 christos nd_uint16_t global_flags; 70 1.10 christos nd_uint8_t msg_type; 71 1.10 christos nd_uint8_t reply_mode; 72 1.10 christos nd_uint8_t return_code; 73 1.10 christos nd_uint8_t return_subcode; 74 1.10 christos nd_uint32_t sender_handle; 75 1.10 christos nd_uint32_t seq_number; 76 1.10 christos struct l_fixedpt ts_sent; 77 1.10 christos struct l_fixedpt ts_rcvd; 78 1.1 christos }; 79 1.1 christos 80 1.1 christos #define LSPPING_VERSION 1 81 1.1 christos 82 1.1 christos static const struct tok lspping_msg_type_values[] = { 83 1.1 christos { 1, "MPLS Echo Request"}, 84 1.1 christos { 2, "MPLS Echo Reply"}, 85 1.1 christos { 0, NULL} 86 1.1 christos }; 87 1.1 christos 88 1.1 christos static const struct tok lspping_reply_mode_values[] = { 89 1.1 christos { 1, "Do not reply"}, 90 1.1 christos { 2, "Reply via an IPv4/IPv6 UDP packet"}, 91 1.1 christos { 3, "Reply via an IPv4/IPv6 UDP packet with Router Alert"}, 92 1.1 christos { 4, "Reply via application level control channel"}, 93 1.1 christos { 0, NULL} 94 1.1 christos }; 95 1.1 christos 96 1.1 christos static const struct tok lspping_return_code_values[] = { 97 1.1 christos { 0, "No return code or return code contained in the Error Code TLV"}, 98 1.1 christos { 1, "Malformed echo request received"}, 99 1.1 christos { 2, "One or more of the TLVs was not understood"}, 100 1.1 christos { 3, "Replying router is an egress for the FEC at stack depth"}, 101 1.1 christos { 4, "Replying router has no mapping for the FEC at stack depth"}, 102 1.1 christos { 5, "Reserved"}, 103 1.1 christos { 6, "Reserved"}, 104 1.1 christos { 7, "Reserved"}, 105 1.1 christos { 8, "Label switched at stack-depth"}, 106 1.1 christos { 9, "Label switched but no MPLS forwarding at stack-depth"}, 107 1.1 christos { 10, "Mapping for this FEC is not the given label at stack depth"}, 108 1.1 christos { 11, "No label entry at stack-depth"}, 109 1.1 christos { 12, "Protocol not associated with interface at FEC stack depth"}, 110 1.8 spz { 13, "Premature termination of ping due to label stack shrinking to a single label"}, 111 1.9 christos { 0, NULL}, 112 1.1 christos }; 113 1.1 christos 114 1.1 christos 115 1.5 christos /* 116 1.1 christos * LSPPING TLV header 117 1.1 christos * 0 1 2 3 118 1.1 christos * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 119 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 120 1.1 christos * | Type | Length | 121 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 122 1.1 christos * | Value | 123 1.1 christos * . . 124 1.1 christos * . . 125 1.1 christos * . . 126 1.1 christos * | | 127 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 128 1.1 christos */ 129 1.1 christos 130 1.1 christos struct lspping_tlv_header { 131 1.10 christos nd_uint16_t type; 132 1.10 christos nd_uint16_t length; 133 1.1 christos }; 134 1.1 christos 135 1.1 christos #define LSPPING_TLV_TARGET_FEC_STACK 1 136 1.1 christos #define LSPPING_TLV_DOWNSTREAM_MAPPING 2 137 1.1 christos #define LSPPING_TLV_PAD 3 138 1.8 spz /* not assigned 4 */ 139 1.1 christos #define LSPPING_TLV_VENDOR_ENTERPRISE 5 140 1.1 christos #define LSPPING_TLV_VENDOR_ENTERPRISE_LEN 4 141 1.8 spz /* not assigned 6 */ 142 1.1 christos #define LSPPING_TLV_INTERFACE_LABEL_STACK 7 143 1.8 spz /* not assigned 8 */ 144 1.1 christos #define LSPPING_TLV_ERROR_CODE 9 145 1.1 christos #define LSPPING_TLV_REPLY_TOS_BYTE 10 146 1.1 christos #define LSPPING_TLV_BFD_DISCRIMINATOR 15 /* draft-ietf-bfd-mpls-02 */ 147 1.1 christos #define LSPPING_TLV_BFD_DISCRIMINATOR_LEN 4 148 1.1 christos #define LSPPING_TLV_VENDOR_PRIVATE 0xfc00 149 1.1 christos 150 1.1 christos static const struct tok lspping_tlv_values[] = { 151 1.1 christos { LSPPING_TLV_TARGET_FEC_STACK, "Target FEC Stack" }, 152 1.1 christos { LSPPING_TLV_DOWNSTREAM_MAPPING, "Downstream Mapping" }, 153 1.1 christos { LSPPING_TLV_PAD, "Pad" }, 154 1.1 christos { LSPPING_TLV_ERROR_CODE, "Error Code" }, 155 1.1 christos { LSPPING_TLV_VENDOR_ENTERPRISE, "Vendor Enterprise Code" }, 156 1.1 christos { LSPPING_TLV_INTERFACE_LABEL_STACK, "Interface Label Stack" }, 157 1.1 christos { LSPPING_TLV_REPLY_TOS_BYTE, "Reply TOS Byte" }, 158 1.1 christos { LSPPING_TLV_BFD_DISCRIMINATOR, "BFD Discriminator" }, 159 1.1 christos { LSPPING_TLV_VENDOR_PRIVATE, "Vendor Private Code" }, 160 1.1 christos { 0, NULL} 161 1.1 christos }; 162 1.1 christos 163 1.8 spz #define LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4 1 164 1.8 spz #define LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6 2 165 1.8 spz #define LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4 3 166 1.8 spz #define LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6 4 167 1.8 spz /* not assigned 5 */ 168 1.8 spz #define LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4 6 169 1.8 spz #define LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6 7 170 1.8 spz #define LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT 8 171 1.8 spz #define LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW_OLD 9 172 1.8 spz #define LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW 10 173 1.8 spz #define LSPPING_TLV_TARGETFEC_SUBTLV_FEC_129_PW 11 174 1.8 spz #define LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4 12 175 1.8 spz #define LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6 13 176 1.8 spz #define LSPPING_TLV_TARGETFEC_SUBTLV_GENERIC_IPV4 14 177 1.8 spz #define LSPPING_TLV_TARGETFEC_SUBTLV_GENERIC_IPV6 15 178 1.8 spz #define LSPPING_TLV_TARGETFEC_SUBTLV_NIL_FEC 16 179 1.1 christos 180 1.1 christos static const struct tok lspping_tlvtargetfec_subtlv_values[] = { 181 1.1 christos { LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4, "LDP IPv4 prefix"}, 182 1.1 christos { LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6, "LDP IPv6 prefix"}, 183 1.1 christos { LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4, "RSVP IPv4 Session Query"}, 184 1.1 christos { LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6, "RSVP IPv6 Session Query"}, 185 1.1 christos { 5, "Reserved"}, 186 1.1 christos { LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4, "VPN IPv4 prefix"}, 187 1.1 christos { LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6, "VPN IPv6 prefix"}, 188 1.1 christos { LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT, "L2 VPN endpoint"}, 189 1.8 spz { LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW_OLD, "FEC 128 pseudowire (old)"}, 190 1.8 spz { LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW, "FEC 128 pseudowire"}, 191 1.1 christos { LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4, "BGP labeled IPv4 prefix"}, 192 1.1 christos { LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6, "BGP labeled IPv6 prefix"}, 193 1.1 christos { 0, NULL} 194 1.1 christos }; 195 1.1 christos 196 1.1 christos /* 197 1.1 christos * 0 1 2 3 198 1.1 christos * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 199 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 200 1.1 christos * | IPv4 prefix | 201 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 202 1.1 christos * | Prefix Length | Must Be Zero | 203 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 204 1.1 christos */ 205 1.1 christos struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t { 206 1.10 christos nd_ipv4 prefix; 207 1.10 christos nd_uint8_t prefix_len; 208 1.1 christos }; 209 1.1 christos 210 1.1 christos /* 211 1.1 christos * 0 1 2 3 212 1.1 christos * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 213 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 214 1.1 christos * | IPv6 prefix | 215 1.1 christos * | (16 octets) | 216 1.1 christos * | | 217 1.1 christos * | | 218 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 219 1.1 christos * | Prefix Length | Must Be Zero | 220 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 221 1.1 christos */ 222 1.1 christos struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t { 223 1.10 christos nd_ipv6 prefix; 224 1.10 christos nd_uint8_t prefix_len; 225 1.1 christos }; 226 1.1 christos 227 1.1 christos /* 228 1.1 christos * 0 1 2 3 229 1.1 christos * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 230 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 231 1.1 christos * | IPv4 tunnel end point address | 232 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 233 1.1 christos * | Must Be Zero | Tunnel ID | 234 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 235 1.1 christos * | Extended Tunnel ID | 236 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 237 1.1 christos * | IPv4 tunnel sender address | 238 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 239 1.1 christos * | Must Be Zero | LSP ID | 240 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 241 1.1 christos */ 242 1.1 christos struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t { 243 1.10 christos nd_ipv4 tunnel_endpoint; 244 1.10 christos nd_byte res[2]; 245 1.10 christos nd_uint16_t tunnel_id; 246 1.10 christos nd_ipv4 extended_tunnel_id; 247 1.10 christos nd_ipv4 tunnel_sender; 248 1.10 christos nd_byte res2[2]; 249 1.10 christos nd_uint16_t lsp_id; 250 1.1 christos }; 251 1.1 christos 252 1.1 christos /* 253 1.1 christos * 0 1 2 3 254 1.1 christos * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 255 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 256 1.1 christos * | IPv6 tunnel end point address | 257 1.1 christos * | | 258 1.1 christos * | | 259 1.1 christos * | | 260 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 261 1.1 christos * | Must Be Zero | Tunnel ID | 262 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 263 1.1 christos * | Extended Tunnel ID | 264 1.1 christos * | | 265 1.1 christos * | | 266 1.1 christos * | | 267 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 268 1.1 christos * | IPv6 tunnel sender address | 269 1.1 christos * | | 270 1.1 christos * | | 271 1.1 christos * | | 272 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 273 1.1 christos * | Must Be Zero | LSP ID | 274 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 275 1.1 christos */ 276 1.1 christos struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t { 277 1.10 christos nd_ipv6 tunnel_endpoint; 278 1.10 christos nd_byte res[2]; 279 1.10 christos nd_uint16_t tunnel_id; 280 1.10 christos nd_ipv6 extended_tunnel_id; 281 1.10 christos nd_ipv6 tunnel_sender; 282 1.10 christos nd_byte res2[2]; 283 1.10 christos nd_uint16_t lsp_id; 284 1.1 christos }; 285 1.1 christos 286 1.1 christos /* 287 1.1 christos * 0 1 2 3 288 1.1 christos * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 289 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 290 1.1 christos * | Route Distinguisher | 291 1.1 christos * | (8 octets) | 292 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 293 1.1 christos * | IPv4 prefix | 294 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 295 1.1 christos * | Prefix Length | Must Be Zero | 296 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 297 1.1 christos */ 298 1.1 christos struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t { 299 1.10 christos nd_byte rd[8]; 300 1.10 christos nd_ipv4 prefix; 301 1.10 christos nd_uint8_t prefix_len; 302 1.1 christos }; 303 1.1 christos 304 1.1 christos /* 305 1.1 christos * 0 1 2 3 306 1.1 christos * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 307 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 308 1.1 christos * | Route Distinguisher | 309 1.1 christos * | (8 octets) | 310 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 311 1.1 christos * | IPv6 prefix | 312 1.1 christos * | (16 octets) | 313 1.1 christos * | | 314 1.1 christos * | | 315 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 316 1.1 christos * | Prefix Length | Must Be Zero | 317 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 318 1.1 christos */ 319 1.1 christos struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t { 320 1.10 christos nd_byte rd[8]; 321 1.10 christos nd_ipv6 prefix; 322 1.10 christos nd_uint8_t prefix_len; 323 1.1 christos }; 324 1.1 christos 325 1.1 christos /* 326 1.1 christos * 0 1 2 3 327 1.1 christos * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 328 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 329 1.1 christos * | Route Distinguisher | 330 1.1 christos * | (8 octets) | 331 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 332 1.8 spz * | Sender's VE ID | Receiver's VE ID | 333 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 334 1.1 christos * | Encapsulation Type | Must Be Zero | 335 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 336 1.1 christos * 0 1 2 3 337 1.1 christos */ 338 1.1 christos struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t { 339 1.10 christos nd_byte rd[8]; 340 1.10 christos nd_uint16_t sender_ve_id; 341 1.10 christos nd_uint16_t receiver_ve_id; 342 1.10 christos nd_uint16_t encapsulation; 343 1.1 christos }; 344 1.1 christos 345 1.1 christos /* 346 1.1 christos * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 347 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 348 1.1 christos * | Remote PE Address | 349 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 350 1.8 spz * | PW ID | 351 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 352 1.8 spz * | PW Type | Must Be Zero | 353 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 354 1.1 christos */ 355 1.8 spz struct lspping_tlv_targetfec_subtlv_fec_128_pw_old { 356 1.10 christos nd_ipv4 remote_pe_address; 357 1.10 christos nd_uint32_t pw_id; 358 1.10 christos nd_uint16_t pw_type; 359 1.1 christos }; 360 1.1 christos 361 1.1 christos /* 362 1.1 christos * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 363 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 364 1.1 christos * | Sender's PE Address | 365 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 366 1.1 christos * | Remote PE Address | 367 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 368 1.8 spz * | PW ID | 369 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 370 1.8 spz * | PW Type | Must Be Zero | 371 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 372 1.1 christos */ 373 1.8 spz struct lspping_tlv_targetfec_subtlv_fec_128_pw { 374 1.10 christos nd_ipv4 sender_pe_address; 375 1.10 christos nd_ipv4 remote_pe_address; 376 1.10 christos nd_uint32_t pw_id; 377 1.10 christos nd_uint16_t pw_type; 378 1.8 spz }; 379 1.8 spz 380 1.8 spz /* 381 1.8 spz * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 382 1.8 spz * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 383 1.8 spz * | IPv4 prefix | 384 1.8 spz * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 385 1.8 spz * | Prefix Length | Must Be Zero | 386 1.8 spz * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 387 1.8 spz */ 388 1.8 spz struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t { 389 1.10 christos nd_ipv4 prefix; 390 1.10 christos nd_uint8_t prefix_len; 391 1.8 spz }; 392 1.8 spz 393 1.8 spz /* 394 1.8 spz * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 395 1.8 spz * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 396 1.8 spz * | IPv6 prefix | 397 1.8 spz * | (16 octets) | 398 1.8 spz * | | 399 1.8 spz * | | 400 1.8 spz * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 401 1.8 spz * | Prefix Length | Must Be Zero | 402 1.8 spz * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 403 1.8 spz */ 404 1.8 spz struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t { 405 1.10 christos nd_ipv6 prefix; 406 1.10 christos nd_uint8_t prefix_len; 407 1.1 christos }; 408 1.1 christos 409 1.1 christos /* 410 1.1 christos * 0 1 2 3 411 1.1 christos * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 412 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 413 1.1 christos * | MTU | Address Type | Resvd (SBZ) | 414 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 415 1.1 christos * | Downstream IP Address (4 or 16 octets) | 416 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 417 1.1 christos * | Downstream Interface Address (4 or 16 octets) | 418 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 419 1.8 spz * | Multipath Type| Depth Limit | Multipath Length | 420 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 421 1.1 christos * . . 422 1.1 christos * . (Multipath Information) . 423 1.1 christos * . . 424 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 425 1.1 christos * | Downstream Label | Protocol | 426 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 427 1.1 christos * . . 428 1.1 christos * . . 429 1.1 christos * . . 430 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 431 1.1 christos * | Downstream Label | Protocol | 432 1.1 christos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 433 1.1 christos */ 434 1.8 spz /* Enough to get the address type */ 435 1.8 spz struct lspping_tlv_downstream_map_t { 436 1.10 christos nd_uint16_t mtu; 437 1.10 christos nd_uint8_t address_type; 438 1.10 christos nd_uint8_t ds_flags; 439 1.8 spz }; 440 1.8 spz 441 1.1 christos struct lspping_tlv_downstream_map_ipv4_t { 442 1.10 christos nd_uint16_t mtu; 443 1.10 christos nd_uint8_t address_type; 444 1.10 christos nd_uint8_t ds_flags; 445 1.10 christos nd_ipv4 downstream_ip; 446 1.10 christos nd_ipv4 downstream_interface; 447 1.8 spz }; 448 1.8 spz 449 1.8 spz struct lspping_tlv_downstream_map_ipv4_unmb_t { 450 1.10 christos nd_uint16_t mtu; 451 1.10 christos nd_uint8_t address_type; 452 1.10 christos nd_uint8_t ds_flags; 453 1.10 christos nd_ipv4 downstream_ip; 454 1.10 christos nd_uint32_t downstream_interface; 455 1.1 christos }; 456 1.1 christos 457 1.1 christos struct lspping_tlv_downstream_map_ipv6_t { 458 1.10 christos nd_uint16_t mtu; 459 1.10 christos nd_uint8_t address_type; 460 1.10 christos nd_uint8_t ds_flags; 461 1.10 christos nd_ipv6 downstream_ip; 462 1.10 christos nd_ipv6 downstream_interface; 463 1.1 christos }; 464 1.1 christos 465 1.8 spz struct lspping_tlv_downstream_map_ipv6_unmb_t { 466 1.10 christos nd_uint16_t mtu; 467 1.10 christos nd_uint8_t address_type; 468 1.10 christos nd_uint8_t ds_flags; 469 1.10 christos nd_ipv6 downstream_ip; 470 1.10 christos nd_uint32_t downstream_interface; 471 1.8 spz }; 472 1.8 spz 473 1.1 christos struct lspping_tlv_downstream_map_info_t { 474 1.10 christos nd_uint8_t multipath_type; 475 1.10 christos nd_uint8_t depth_limit; 476 1.10 christos nd_uint16_t multipath_length; 477 1.1 christos }; 478 1.1 christos 479 1.8 spz #define LSPPING_AFI_IPV4 1 480 1.8 spz #define LSPPING_AFI_IPV4_UNMB 2 481 1.8 spz #define LSPPING_AFI_IPV6 3 482 1.8 spz #define LSPPING_AFI_IPV6_UNMB 4 483 1.1 christos 484 1.1 christos static const struct tok lspping_tlv_downstream_addr_values[] = { 485 1.8 spz { LSPPING_AFI_IPV4, "IPv4"}, 486 1.8 spz { LSPPING_AFI_IPV4_UNMB, "Unnumbered IPv4"}, 487 1.8 spz { LSPPING_AFI_IPV6, "IPv6"}, 488 1.8 spz { LSPPING_AFI_IPV6_UNMB, "IPv6"}, 489 1.1 christos { 0, NULL} 490 1.1 christos }; 491 1.1 christos 492 1.1 christos void 493 1.5 christos lspping_print(netdissect_options *ndo, 494 1.10 christos const u_char *pptr, u_int len) 495 1.6 christos { 496 1.1 christos const struct lspping_common_header *lspping_com_header; 497 1.1 christos const struct lspping_tlv_header *lspping_tlv_header; 498 1.1 christos const struct lspping_tlv_header *lspping_subtlv_header; 499 1.1 christos const u_char *tptr,*tlv_tptr,*subtlv_tptr; 500 1.10 christos u_int return_code, return_subcode; 501 1.8 spz u_int tlen,lspping_tlv_len,lspping_tlv_type,tlv_tlen; 502 1.1 christos int tlv_hexdump,subtlv_hexdump; 503 1.8 spz u_int lspping_subtlv_len,lspping_subtlv_type; 504 1.10 christos uint32_t int_part, fraction; 505 1.10 christos u_int address_type; 506 1.1 christos 507 1.1 christos union { 508 1.8 spz const struct lspping_tlv_downstream_map_t *lspping_tlv_downstream_map; 509 1.1 christos const struct lspping_tlv_downstream_map_ipv4_t *lspping_tlv_downstream_map_ipv4; 510 1.8 spz const struct lspping_tlv_downstream_map_ipv4_unmb_t *lspping_tlv_downstream_map_ipv4_unmb; 511 1.1 christos const struct lspping_tlv_downstream_map_ipv6_t *lspping_tlv_downstream_map_ipv6; 512 1.8 spz const struct lspping_tlv_downstream_map_ipv6_unmb_t *lspping_tlv_downstream_map_ipv6_unmb; 513 1.1 christos const struct lspping_tlv_downstream_map_info_t *lspping_tlv_downstream_map_info; 514 1.1 christos } tlv_ptr; 515 1.1 christos 516 1.1 christos union { 517 1.1 christos const struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t *lspping_tlv_targetfec_subtlv_ldp_ipv4; 518 1.1 christos const struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t *lspping_tlv_targetfec_subtlv_ldp_ipv6; 519 1.1 christos const struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t *lspping_tlv_targetfec_subtlv_rsvp_ipv4; 520 1.1 christos const struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t *lspping_tlv_targetfec_subtlv_rsvp_ipv6; 521 1.1 christos const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t *lspping_tlv_targetfec_subtlv_l3vpn_ipv4; 522 1.1 christos const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t *lspping_tlv_targetfec_subtlv_l3vpn_ipv6; 523 1.1 christos const struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t *lspping_tlv_targetfec_subtlv_l2vpn_endpt; 524 1.8 spz const struct lspping_tlv_targetfec_subtlv_fec_128_pw_old *lspping_tlv_targetfec_subtlv_l2vpn_vcid_old; 525 1.8 spz const struct lspping_tlv_targetfec_subtlv_fec_128_pw *lspping_tlv_targetfec_subtlv_l2vpn_vcid; 526 1.1 christos const struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t *lspping_tlv_targetfec_subtlv_bgp_ipv4; 527 1.1 christos const struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t *lspping_tlv_targetfec_subtlv_bgp_ipv6; 528 1.1 christos } subtlv_ptr; 529 1.1 christos 530 1.10 christos ndo->ndo_protocol = "lspping"; 531 1.1 christos tptr=pptr; 532 1.1 christos lspping_com_header = (const struct lspping_common_header *)pptr; 533 1.10 christos if (len < sizeof(struct lspping_common_header)) 534 1.8 spz goto tooshort; 535 1.10 christos ND_TCHECK_SIZE(lspping_com_header); 536 1.1 christos 537 1.1 christos /* 538 1.1 christos * Sanity checking of the header. 539 1.1 christos */ 540 1.10 christos if (GET_BE_U_2(lspping_com_header->version) != LSPPING_VERSION) { 541 1.10 christos ND_PRINT("LSP-PING version %u packet not supported", 542 1.10 christos GET_BE_U_2(lspping_com_header->version)); 543 1.1 christos return; 544 1.1 christos } 545 1.1 christos 546 1.1 christos /* in non-verbose mode just lets print the basic Message Type*/ 547 1.5 christos if (ndo->ndo_vflag < 1) { 548 1.10 christos ND_PRINT("LSP-PINGv%u, %s, seq %u, length: %u", 549 1.10 christos GET_BE_U_2(lspping_com_header->version), 550 1.10 christos tok2str(lspping_msg_type_values, "unknown (%u)",GET_U_1(lspping_com_header->msg_type)), 551 1.10 christos GET_BE_U_4(lspping_com_header->seq_number), 552 1.10 christos len); 553 1.1 christos return; 554 1.1 christos } 555 1.1 christos 556 1.1 christos /* ok they seem to want to know everything - lets fully decode it */ 557 1.1 christos 558 1.1 christos tlen=len; 559 1.1 christos 560 1.10 christos ND_PRINT("\n\tLSP-PINGv%u, msg-type: %s (%u), length: %u\n\t reply-mode: %s (%u)", 561 1.10 christos GET_BE_U_2(lspping_com_header->version), 562 1.10 christos tok2str(lspping_msg_type_values, "unknown",GET_U_1(lspping_com_header->msg_type)), 563 1.10 christos GET_U_1(lspping_com_header->msg_type), 564 1.1 christos len, 565 1.10 christos tok2str(lspping_reply_mode_values, "unknown",GET_U_1(lspping_com_header->reply_mode)), 566 1.10 christos GET_U_1(lspping_com_header->reply_mode)); 567 1.1 christos 568 1.1 christos /* 569 1.1 christos * the following return codes require that the subcode is attached 570 1.1 christos * at the end of the translated token output 571 1.1 christos */ 572 1.10 christos return_code = GET_U_1(lspping_com_header->return_code); 573 1.10 christos return_subcode = GET_U_1(lspping_com_header->return_subcode); 574 1.10 christos if (return_code == 3 || 575 1.10 christos return_code == 4 || 576 1.10 christos return_code == 8 || 577 1.10 christos return_code == 10 || 578 1.10 christos return_code == 11 || 579 1.10 christos return_code == 12 ) 580 1.10 christos ND_PRINT("\n\t Return Code: %s %u (%u)\n\t Return Subcode: (%u)", 581 1.10 christos tok2str(lspping_return_code_values, "unknown",return_code), 582 1.10 christos return_subcode, 583 1.10 christos return_code, 584 1.10 christos return_subcode); 585 1.1 christos else 586 1.10 christos ND_PRINT("\n\t Return Code: %s (%u)\n\t Return Subcode: (%u)", 587 1.10 christos tok2str(lspping_return_code_values, "unknown",return_code), 588 1.10 christos return_code, 589 1.10 christos return_subcode); 590 1.10 christos 591 1.10 christos ND_PRINT("\n\t Sender Handle: 0x%08x, Sequence: %u", 592 1.10 christos GET_BE_U_4(lspping_com_header->sender_handle), 593 1.10 christos GET_BE_U_4(lspping_com_header->seq_number)); 594 1.10 christos 595 1.12 christos ND_PRINT("\n\t TimeStamp Sent: "); 596 1.10 christos p_ntp_time(ndo, &lspping_com_header->ts_sent); 597 1.10 christos 598 1.10 christos int_part=GET_BE_U_4(lspping_com_header->ts_rcvd.int_part); 599 1.10 christos fraction=GET_BE_U_4(lspping_com_header->ts_rcvd.fraction); 600 1.12 christos ND_PRINT("\n\t TimeStamp Received: "); 601 1.10 christos if (! (int_part == 0 && fraction == 0)) 602 1.10 christos p_ntp_time(ndo, &lspping_com_header->ts_rcvd); 603 1.1 christos else 604 1.10 christos ND_PRINT("no timestamp"); 605 1.1 christos 606 1.10 christos tptr+=sizeof(struct lspping_common_header); 607 1.10 christos tlen-=sizeof(struct lspping_common_header); 608 1.1 christos 609 1.8 spz while (tlen != 0) { 610 1.8 spz /* Does the TLV go past the end of the packet? */ 611 1.8 spz if (tlen < sizeof(struct lspping_tlv_header)) 612 1.8 spz goto tooshort; 613 1.1 christos 614 1.1 christos lspping_tlv_header = (const struct lspping_tlv_header *)tptr; 615 1.10 christos lspping_tlv_type=GET_BE_U_2(lspping_tlv_header->type); 616 1.10 christos lspping_tlv_len=GET_BE_U_2(lspping_tlv_header->length); 617 1.1 christos 618 1.10 christos ND_PRINT("\n\t %s TLV (%u), length: %u", 619 1.1 christos tok2str(lspping_tlv_values, 620 1.1 christos "Unknown", 621 1.1 christos lspping_tlv_type), 622 1.1 christos lspping_tlv_type, 623 1.10 christos lspping_tlv_len); 624 1.1 christos 625 1.8 spz /* some little sanity checking */ 626 1.8 spz if (lspping_tlv_len == 0) { 627 1.8 spz tptr+=sizeof(struct lspping_tlv_header); 628 1.8 spz tlen-=sizeof(struct lspping_tlv_header); 629 1.8 spz continue; /* no value to dissect */ 630 1.8 spz } 631 1.8 spz 632 1.1 christos tlv_tptr=tptr+sizeof(struct lspping_tlv_header); 633 1.1 christos tlv_tlen=lspping_tlv_len; /* header not included -> no adjustment */ 634 1.1 christos 635 1.8 spz /* Does the TLV go past the end of the packet? */ 636 1.8 spz if (tlen < lspping_tlv_len+sizeof(struct lspping_tlv_header)) 637 1.8 spz goto tooshort; 638 1.1 christos /* did we capture enough for fully decoding the tlv ? */ 639 1.10 christos ND_TCHECK_LEN(tlv_tptr, lspping_tlv_len); 640 1.1 christos tlv_hexdump=FALSE; 641 1.1 christos 642 1.1 christos switch(lspping_tlv_type) { 643 1.1 christos case LSPPING_TLV_TARGET_FEC_STACK: 644 1.8 spz while (tlv_tlen != 0) { 645 1.8 spz /* Does the subTLV header go past the end of the TLV? */ 646 1.8 spz if (tlv_tlen < sizeof(struct lspping_tlv_header)) { 647 1.10 christos ND_PRINT("\n\t TLV is too short"); 648 1.8 spz tlv_hexdump = TRUE; 649 1.8 spz goto tlv_tooshort; 650 1.8 spz } 651 1.1 christos subtlv_hexdump=FALSE; 652 1.1 christos 653 1.1 christos lspping_subtlv_header = (const struct lspping_tlv_header *)tlv_tptr; 654 1.10 christos lspping_subtlv_type=GET_BE_U_2(lspping_subtlv_header->type); 655 1.10 christos lspping_subtlv_len=GET_BE_U_2(lspping_subtlv_header->length); 656 1.1 christos subtlv_tptr=tlv_tptr+sizeof(struct lspping_tlv_header); 657 1.5 christos 658 1.8 spz /* Does the subTLV go past the end of the TLV? */ 659 1.8 spz if (tlv_tlen < lspping_subtlv_len+sizeof(struct lspping_tlv_header)) { 660 1.10 christos ND_PRINT("\n\t TLV is too short"); 661 1.8 spz tlv_hexdump = TRUE; 662 1.8 spz goto tlv_tooshort; 663 1.8 spz } 664 1.8 spz 665 1.8 spz /* Did we capture enough for fully decoding the subTLV? */ 666 1.10 christos ND_TCHECK_LEN(subtlv_tptr, lspping_subtlv_len); 667 1.1 christos 668 1.10 christos ND_PRINT("\n\t %s subTLV (%u), length: %u", 669 1.1 christos tok2str(lspping_tlvtargetfec_subtlv_values, 670 1.1 christos "Unknown", 671 1.1 christos lspping_subtlv_type), 672 1.1 christos lspping_subtlv_type, 673 1.10 christos lspping_subtlv_len); 674 1.1 christos 675 1.1 christos switch(lspping_subtlv_type) { 676 1.1 christos 677 1.1 christos case LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4: 678 1.8 spz /* Is the subTLV length correct? */ 679 1.8 spz if (lspping_subtlv_len != 5) { 680 1.10 christos ND_PRINT("\n\t invalid subTLV length, should be 5"); 681 1.8 spz subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ 682 1.8 spz } else { 683 1.10 christos subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4 = 684 1.8 spz (const struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t *)subtlv_tptr; 685 1.10 christos ND_PRINT("\n\t %s/%u", 686 1.10 christos GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4->prefix), 687 1.10 christos GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4->prefix_len)); 688 1.8 spz } 689 1.1 christos break; 690 1.1 christos 691 1.1 christos case LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6: 692 1.8 spz /* Is the subTLV length correct? */ 693 1.8 spz if (lspping_subtlv_len != 17) { 694 1.10 christos ND_PRINT("\n\t invalid subTLV length, should be 17"); 695 1.8 spz subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ 696 1.8 spz } else { 697 1.10 christos subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6 = 698 1.8 spz (const struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t *)subtlv_tptr; 699 1.10 christos ND_PRINT("\n\t %s/%u", 700 1.10 christos GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6->prefix), 701 1.10 christos GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6->prefix_len)); 702 1.8 spz } 703 1.1 christos break; 704 1.1 christos 705 1.1 christos case LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4: 706 1.8 spz /* Is the subTLV length correct? */ 707 1.8 spz if (lspping_subtlv_len != 5) { 708 1.10 christos ND_PRINT("\n\t invalid subTLV length, should be 5"); 709 1.8 spz subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ 710 1.8 spz } else { 711 1.10 christos subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4 = 712 1.8 spz (const struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t *)subtlv_tptr; 713 1.10 christos ND_PRINT("\n\t %s/%u", 714 1.10 christos GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4->prefix), 715 1.10 christos GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4->prefix_len)); 716 1.8 spz } 717 1.1 christos break; 718 1.1 christos 719 1.1 christos case LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6: 720 1.8 spz /* Is the subTLV length correct? */ 721 1.8 spz if (lspping_subtlv_len != 17) { 722 1.10 christos ND_PRINT("\n\t invalid subTLV length, should be 17"); 723 1.8 spz subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ 724 1.8 spz } else { 725 1.10 christos subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6 = 726 1.8 spz (const struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t *)subtlv_tptr; 727 1.10 christos ND_PRINT("\n\t %s/%u", 728 1.10 christos GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6->prefix), 729 1.10 christos GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6->prefix_len)); 730 1.8 spz } 731 1.1 christos break; 732 1.1 christos 733 1.1 christos case LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4: 734 1.8 spz /* Is the subTLV length correct? */ 735 1.8 spz if (lspping_subtlv_len != 20) { 736 1.10 christos ND_PRINT("\n\t invalid subTLV length, should be 20"); 737 1.8 spz subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ 738 1.8 spz } else { 739 1.10 christos subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4 = 740 1.8 spz (const struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t *)subtlv_tptr; 741 1.10 christos ND_PRINT("\n\t tunnel end-point %s, tunnel sender %s, lsp-id 0x%04x" 742 1.8 spz "\n\t tunnel-id 0x%04x, extended tunnel-id %s", 743 1.10 christos GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_endpoint), 744 1.10 christos GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_sender), 745 1.10 christos GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->lsp_id), 746 1.10 christos GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_id), 747 1.10 christos GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->extended_tunnel_id)); 748 1.8 spz } 749 1.1 christos break; 750 1.1 christos 751 1.1 christos case LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6: 752 1.8 spz /* Is the subTLV length correct? */ 753 1.8 spz if (lspping_subtlv_len != 56) { 754 1.10 christos ND_PRINT("\n\t invalid subTLV length, should be 56"); 755 1.8 spz subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ 756 1.8 spz } else { 757 1.10 christos subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6 = 758 1.8 spz (const struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t *)subtlv_tptr; 759 1.10 christos ND_PRINT("\n\t tunnel end-point %s, tunnel sender %s, lsp-id 0x%04x" 760 1.8 spz "\n\t tunnel-id 0x%04x, extended tunnel-id %s", 761 1.10 christos GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_endpoint), 762 1.10 christos GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_sender), 763 1.10 christos GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->lsp_id), 764 1.10 christos GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_id), 765 1.10 christos GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->extended_tunnel_id)); 766 1.8 spz } 767 1.1 christos break; 768 1.1 christos 769 1.1 christos case LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4: 770 1.8 spz /* Is the subTLV length correct? */ 771 1.8 spz if (lspping_subtlv_len != 13) { 772 1.10 christos ND_PRINT("\n\t invalid subTLV length, should be 13"); 773 1.8 spz subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ 774 1.8 spz } else { 775 1.10 christos subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4 = 776 1.8 spz (const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t *)subtlv_tptr; 777 1.10 christos ND_PRINT("\n\t RD: %s, %s/%u", 778 1.8 spz bgp_vpn_rd_print(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->rd), 779 1.10 christos GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->prefix), 780 1.10 christos GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->prefix_len)); 781 1.8 spz } 782 1.1 christos break; 783 1.1 christos 784 1.1 christos case LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6: 785 1.8 spz /* Is the subTLV length correct? */ 786 1.8 spz if (lspping_subtlv_len != 25) { 787 1.10 christos ND_PRINT("\n\t invalid subTLV length, should be 25"); 788 1.8 spz subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ 789 1.8 spz } else { 790 1.10 christos subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6 = 791 1.8 spz (const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t *)subtlv_tptr; 792 1.10 christos ND_PRINT("\n\t RD: %s, %s/%u", 793 1.8 spz bgp_vpn_rd_print(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->rd), 794 1.10 christos GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->prefix), 795 1.10 christos GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->prefix_len)); 796 1.8 spz } 797 1.1 christos break; 798 1.1 christos 799 1.1 christos case LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT: 800 1.8 spz /* Is the subTLV length correct? */ 801 1.8 spz if (lspping_subtlv_len != 14) { 802 1.10 christos ND_PRINT("\n\t invalid subTLV length, should be 14"); 803 1.8 spz subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ 804 1.8 spz } else { 805 1.10 christos subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt = 806 1.8 spz (const struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t *)subtlv_tptr; 807 1.10 christos ND_PRINT("\n\t RD: %s, Sender VE ID: %u, Receiver VE ID: %u" 808 1.8 spz "\n\t Encapsulation Type: %s (%u)", 809 1.8 spz bgp_vpn_rd_print(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->rd), 810 1.10 christos GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->sender_ve_id), 811 1.10 christos GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->receiver_ve_id), 812 1.8 spz tok2str(mpls_pw_types_values, 813 1.8 spz "unknown", 814 1.10 christos GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->encapsulation)), 815 1.10 christos GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->encapsulation)); 816 1.8 spz } 817 1.1 christos break; 818 1.1 christos 819 1.1 christos /* the old L2VPN VCID subTLV does not have support for the sender field */ 820 1.8 spz case LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW_OLD: 821 1.8 spz /* Is the subTLV length correct? */ 822 1.8 spz if (lspping_subtlv_len != 10) { 823 1.10 christos ND_PRINT("\n\t invalid subTLV length, should be 10"); 824 1.8 spz subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ 825 1.8 spz } else { 826 1.10 christos subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old = 827 1.8 spz (const struct lspping_tlv_targetfec_subtlv_fec_128_pw_old *)subtlv_tptr; 828 1.10 christos ND_PRINT("\n\t Remote PE: %s" 829 1.8 spz "\n\t PW ID: 0x%08x, PW Type: %s (%u)", 830 1.10 christos GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->remote_pe_address), 831 1.10 christos GET_BE_U_4(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->pw_id), 832 1.8 spz tok2str(mpls_pw_types_values, 833 1.8 spz "unknown", 834 1.10 christos GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->pw_type)), 835 1.10 christos GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->pw_type)); 836 1.8 spz } 837 1.1 christos break; 838 1.1 christos 839 1.8 spz case LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW: 840 1.8 spz /* Is the subTLV length correct? */ 841 1.8 spz if (lspping_subtlv_len != 14) { 842 1.10 christos ND_PRINT("\n\t invalid subTLV length, should be 14"); 843 1.8 spz subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ 844 1.8 spz } else { 845 1.10 christos subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid = 846 1.8 spz (const struct lspping_tlv_targetfec_subtlv_fec_128_pw *)subtlv_tptr; 847 1.10 christos ND_PRINT("\n\t Sender PE: %s, Remote PE: %s" 848 1.8 spz "\n\t PW ID: 0x%08x, PW Type: %s (%u)", 849 1.10 christos GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->sender_pe_address), 850 1.10 christos GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->remote_pe_address), 851 1.10 christos GET_BE_U_4(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->pw_id), 852 1.8 spz tok2str(mpls_pw_types_values, 853 1.8 spz "unknown", 854 1.10 christos GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->pw_type)), 855 1.10 christos GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->pw_type)); 856 1.8 spz } 857 1.1 christos break; 858 1.1 christos 859 1.1 christos default: 860 1.1 christos subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ 861 1.1 christos break; 862 1.1 christos } 863 1.1 christos /* do we want to see an additionally subtlv hexdump ? */ 864 1.5 christos if (ndo->ndo_vflag > 1 || subtlv_hexdump==TRUE) 865 1.10 christos print_unknown_data(ndo, tlv_tptr+sizeof(struct lspping_tlv_header), 866 1.1 christos "\n\t ", 867 1.1 christos lspping_subtlv_len); 868 1.1 christos 869 1.8 spz /* All subTLVs are aligned to four octet boundary */ 870 1.8 spz if (lspping_subtlv_len % 4) { 871 1.8 spz lspping_subtlv_len += 4 - (lspping_subtlv_len % 4); 872 1.8 spz /* Does the subTLV, including padding, go past the end of the TLV? */ 873 1.8 spz if (tlv_tlen < lspping_subtlv_len+sizeof(struct lspping_tlv_header)) { 874 1.10 christos ND_PRINT("\n\t\t TLV is too short"); 875 1.8 spz return; 876 1.8 spz } 877 1.8 spz } 878 1.1 christos tlv_tptr+=lspping_subtlv_len; 879 1.1 christos tlv_tlen-=lspping_subtlv_len+sizeof(struct lspping_tlv_header); 880 1.1 christos } 881 1.1 christos break; 882 1.1 christos 883 1.1 christos case LSPPING_TLV_DOWNSTREAM_MAPPING: 884 1.8 spz /* Does the header go past the end of the TLV? */ 885 1.8 spz if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_t)) { 886 1.10 christos ND_PRINT("\n\t TLV is too short"); 887 1.8 spz tlv_hexdump = TRUE; 888 1.8 spz goto tlv_tooshort; 889 1.8 spz } 890 1.8 spz /* Did we capture enough to get the address family? */ 891 1.10 christos ND_TCHECK_LEN(tlv_tptr, 892 1.10 christos sizeof(struct lspping_tlv_downstream_map_t)); 893 1.8 spz 894 1.10 christos tlv_ptr.lspping_tlv_downstream_map= 895 1.8 spz (const struct lspping_tlv_downstream_map_t *)tlv_tptr; 896 1.8 spz 897 1.1 christos /* that strange thing with the downstream map TLV is that until now 898 1.8 spz * we do not know if its IPv4 or IPv6 or is unnumbered; after 899 1.8 spz * we find the address-type, we recast the tlv_tptr and move on. */ 900 1.1 christos 901 1.10 christos address_type = GET_U_1(tlv_ptr.lspping_tlv_downstream_map->address_type); 902 1.10 christos ND_PRINT("\n\t MTU: %u, Address-Type: %s (%u)", 903 1.10 christos GET_BE_U_2(tlv_ptr.lspping_tlv_downstream_map->mtu), 904 1.1 christos tok2str(lspping_tlv_downstream_addr_values, 905 1.1 christos "unknown", 906 1.10 christos address_type), 907 1.10 christos address_type); 908 1.1 christos 909 1.10 christos switch(address_type) { 910 1.1 christos 911 1.1 christos case LSPPING_AFI_IPV4: 912 1.8 spz /* Does the data go past the end of the TLV? */ 913 1.8 spz if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv4_t)) { 914 1.10 christos ND_PRINT("\n\t TLV is too short"); 915 1.8 spz tlv_hexdump = TRUE; 916 1.8 spz goto tlv_tooshort; 917 1.8 spz } 918 1.8 spz /* Did we capture enough for this part of the TLV? */ 919 1.10 christos ND_TCHECK_LEN(tlv_tptr, 920 1.10 christos sizeof(struct lspping_tlv_downstream_map_ipv4_t)); 921 1.8 spz 922 1.10 christos tlv_ptr.lspping_tlv_downstream_map_ipv4= 923 1.8 spz (const struct lspping_tlv_downstream_map_ipv4_t *)tlv_tptr; 924 1.10 christos ND_PRINT("\n\t Downstream IP: %s" 925 1.1 christos "\n\t Downstream Interface IP: %s", 926 1.10 christos GET_IPADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_ip), 927 1.10 christos GET_IPADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_interface)); 928 1.1 christos tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv4_t); 929 1.1 christos tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv4_t); 930 1.1 christos break; 931 1.8 spz case LSPPING_AFI_IPV4_UNMB: 932 1.8 spz /* Does the data go past the end of the TLV? */ 933 1.8 spz if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t)) { 934 1.10 christos ND_PRINT("\n\t TLV is too short"); 935 1.8 spz tlv_hexdump = TRUE; 936 1.8 spz goto tlv_tooshort; 937 1.8 spz } 938 1.8 spz /* Did we capture enough for this part of the TLV? */ 939 1.10 christos ND_TCHECK_LEN(tlv_tptr, 940 1.10 christos sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t)); 941 1.8 spz 942 1.10 christos tlv_ptr.lspping_tlv_downstream_map_ipv4_unmb= 943 1.8 spz (const struct lspping_tlv_downstream_map_ipv4_unmb_t *)tlv_tptr; 944 1.10 christos ND_PRINT("\n\t Downstream IP: %s" 945 1.8 spz "\n\t Downstream Interface Index: 0x%08x", 946 1.10 christos GET_IPADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv4_unmb->downstream_ip), 947 1.10 christos GET_BE_U_4(tlv_ptr.lspping_tlv_downstream_map_ipv4_unmb->downstream_interface)); 948 1.8 spz tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t); 949 1.8 spz tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t); 950 1.8 spz break; 951 1.8 spz case LSPPING_AFI_IPV6: 952 1.8 spz /* Does the data go past the end of the TLV? */ 953 1.8 spz if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv6_t)) { 954 1.10 christos ND_PRINT("\n\t TLV is too short"); 955 1.8 spz tlv_hexdump = TRUE; 956 1.8 spz goto tlv_tooshort; 957 1.8 spz } 958 1.8 spz /* Did we capture enough for this part of the TLV? */ 959 1.10 christos ND_TCHECK_LEN(tlv_tptr, 960 1.10 christos sizeof(struct lspping_tlv_downstream_map_ipv6_t)); 961 1.8 spz 962 1.10 christos tlv_ptr.lspping_tlv_downstream_map_ipv6= 963 1.8 spz (const struct lspping_tlv_downstream_map_ipv6_t *)tlv_tptr; 964 1.10 christos ND_PRINT("\n\t Downstream IP: %s" 965 1.1 christos "\n\t Downstream Interface IP: %s", 966 1.10 christos GET_IP6ADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv6->downstream_ip), 967 1.10 christos GET_IP6ADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv6->downstream_interface)); 968 1.1 christos tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv6_t); 969 1.1 christos tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv6_t); 970 1.1 christos break; 971 1.8 spz case LSPPING_AFI_IPV6_UNMB: 972 1.8 spz /* Does the data go past the end of the TLV? */ 973 1.8 spz if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t)) { 974 1.10 christos ND_PRINT("\n\t TLV is too short"); 975 1.8 spz tlv_hexdump = TRUE; 976 1.8 spz goto tlv_tooshort; 977 1.8 spz } 978 1.8 spz /* Did we capture enough for this part of the TLV? */ 979 1.10 christos ND_TCHECK_LEN(tlv_tptr, 980 1.10 christos sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t)); 981 1.8 spz 982 1.10 christos tlv_ptr.lspping_tlv_downstream_map_ipv6_unmb= 983 1.8 spz (const struct lspping_tlv_downstream_map_ipv6_unmb_t *)tlv_tptr; 984 1.10 christos ND_PRINT("\n\t Downstream IP: %s" 985 1.1 christos "\n\t Downstream Interface Index: 0x%08x", 986 1.10 christos GET_IP6ADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv6_unmb->downstream_ip), 987 1.10 christos GET_BE_U_4(tlv_ptr.lspping_tlv_downstream_map_ipv6_unmb->downstream_interface)); 988 1.8 spz tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t); 989 1.8 spz tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t); 990 1.1 christos break; 991 1.1 christos 992 1.1 christos default: 993 1.1 christos /* should not happen ! - no error message - tok2str() has barked already */ 994 1.1 christos break; 995 1.1 christos } 996 1.1 christos 997 1.8 spz /* Does the data go past the end of the TLV? */ 998 1.8 spz if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_info_t)) { 999 1.10 christos ND_PRINT("\n\t TLV is too short"); 1000 1.8 spz tlv_hexdump = TRUE; 1001 1.8 spz goto tlv_tooshort; 1002 1.8 spz } 1003 1.8 spz /* Did we capture enough for this part of the TLV? */ 1004 1.10 christos ND_TCHECK_LEN(tlv_tptr, 1005 1.10 christos sizeof(struct lspping_tlv_downstream_map_info_t)); 1006 1.8 spz 1007 1.10 christos tlv_ptr.lspping_tlv_downstream_map_info= 1008 1.1 christos (const struct lspping_tlv_downstream_map_info_t *)tlv_tptr; 1009 1.5 christos 1010 1.1 christos /* FIXME add hash-key type, depth limit, multipath processing */ 1011 1.1 christos 1012 1.1 christos /* FIXME print downstream labels */ 1013 1.1 christos 1014 1.1 christos tlv_hexdump=TRUE; /* dump the TLV until code complete */ 1015 1.1 christos 1016 1.1 christos break; 1017 1.1 christos 1018 1.1 christos case LSPPING_TLV_BFD_DISCRIMINATOR: 1019 1.8 spz if (tlv_tlen < LSPPING_TLV_BFD_DISCRIMINATOR_LEN) { 1020 1.10 christos ND_PRINT("\n\t TLV is too short"); 1021 1.8 spz tlv_hexdump = TRUE; 1022 1.8 spz goto tlv_tooshort; 1023 1.8 spz } else { 1024 1.10 christos ND_PRINT("\n\t BFD Discriminator 0x%08x", GET_BE_U_4(tlv_tptr)); 1025 1.8 spz } 1026 1.1 christos break; 1027 1.1 christos 1028 1.1 christos case LSPPING_TLV_VENDOR_ENTERPRISE: 1029 1.1 christos { 1030 1.5 christos uint32_t vendor_id; 1031 1.1 christos 1032 1.8 spz if (tlv_tlen < LSPPING_TLV_VENDOR_ENTERPRISE_LEN) { 1033 1.10 christos ND_PRINT("\n\t TLV is too short"); 1034 1.8 spz tlv_hexdump = TRUE; 1035 1.8 spz goto tlv_tooshort; 1036 1.8 spz } else { 1037 1.10 christos vendor_id = GET_BE_U_4(tlv_tptr); 1038 1.10 christos ND_PRINT("\n\t Vendor: %s (0x%04x)", 1039 1.8 spz tok2str(smi_values, "Unknown", vendor_id), 1040 1.10 christos vendor_id); 1041 1.8 spz } 1042 1.1 christos } 1043 1.1 christos break; 1044 1.1 christos 1045 1.1 christos /* 1046 1.1 christos * FIXME those are the defined TLVs that lack a decoder 1047 1.1 christos * you are welcome to contribute code ;-) 1048 1.1 christos */ 1049 1.1 christos case LSPPING_TLV_PAD: 1050 1.1 christos case LSPPING_TLV_ERROR_CODE: 1051 1.1 christos case LSPPING_TLV_VENDOR_PRIVATE: 1052 1.5 christos 1053 1.1 christos default: 1054 1.5 christos if (ndo->ndo_vflag <= 1) 1055 1.5 christos print_unknown_data(ndo, tlv_tptr, "\n\t ", tlv_tlen); 1056 1.1 christos break; 1057 1.1 christos } 1058 1.1 christos /* do we want to see an additionally tlv hexdump ? */ 1059 1.8 spz tlv_tooshort: 1060 1.5 christos if (ndo->ndo_vflag > 1 || tlv_hexdump==TRUE) 1061 1.5 christos print_unknown_data(ndo, tptr+sizeof(struct lspping_tlv_header), "\n\t ", 1062 1.1 christos lspping_tlv_len); 1063 1.1 christos 1064 1.1 christos 1065 1.1 christos /* All TLVs are aligned to four octet boundary */ 1066 1.1 christos if (lspping_tlv_len % 4) { 1067 1.1 christos lspping_tlv_len += (4 - lspping_tlv_len % 4); 1068 1.8 spz /* Does the TLV, including padding, go past the end of the packet? */ 1069 1.8 spz if (tlen < lspping_tlv_len+sizeof(struct lspping_tlv_header)) 1070 1.8 spz goto tooshort; 1071 1.1 christos } 1072 1.1 christos 1073 1.1 christos tptr+=lspping_tlv_len+sizeof(struct lspping_tlv_header); 1074 1.1 christos tlen-=lspping_tlv_len+sizeof(struct lspping_tlv_header); 1075 1.1 christos } 1076 1.1 christos return; 1077 1.8 spz tooshort: 1078 1.10 christos ND_PRINT("\n\t\t packet is too short"); 1079 1.1 christos } 1080