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