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