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