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 #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 { 0, NULL}, 108 }; 109 110 111 /* 112 * LSPPING TLV header 113 * 0 1 2 3 114 * 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 115 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 116 * | Type | Length | 117 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 118 * | Value | 119 * . . 120 * . . 121 * . . 122 * | | 123 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 124 */ 125 126 struct lspping_tlv_header { 127 uint8_t type[2]; 128 uint8_t length[2]; 129 }; 130 131 #define LSPPING_TLV_TARGET_FEC_STACK 1 132 #define LSPPING_TLV_DOWNSTREAM_MAPPING 2 133 #define LSPPING_TLV_PAD 3 134 /* not assigned 4 */ 135 #define LSPPING_TLV_VENDOR_ENTERPRISE 5 136 #define LSPPING_TLV_VENDOR_ENTERPRISE_LEN 4 137 /* not assigned 6 */ 138 #define LSPPING_TLV_INTERFACE_LABEL_STACK 7 139 /* not assigned 8 */ 140 #define LSPPING_TLV_ERROR_CODE 9 141 #define LSPPING_TLV_REPLY_TOS_BYTE 10 142 #define LSPPING_TLV_BFD_DISCRIMINATOR 15 /* draft-ietf-bfd-mpls-02 */ 143 #define LSPPING_TLV_BFD_DISCRIMINATOR_LEN 4 144 #define LSPPING_TLV_VENDOR_PRIVATE 0xfc00 145 146 static const struct tok lspping_tlv_values[] = { 147 { LSPPING_TLV_TARGET_FEC_STACK, "Target FEC Stack" }, 148 { LSPPING_TLV_DOWNSTREAM_MAPPING, "Downstream Mapping" }, 149 { LSPPING_TLV_PAD, "Pad" }, 150 { LSPPING_TLV_ERROR_CODE, "Error Code" }, 151 { LSPPING_TLV_VENDOR_ENTERPRISE, "Vendor Enterprise Code" }, 152 { LSPPING_TLV_INTERFACE_LABEL_STACK, "Interface Label Stack" }, 153 { LSPPING_TLV_REPLY_TOS_BYTE, "Reply TOS Byte" }, 154 { LSPPING_TLV_BFD_DISCRIMINATOR, "BFD Discriminator" }, 155 { LSPPING_TLV_VENDOR_PRIVATE, "Vendor Private Code" }, 156 { 0, NULL} 157 }; 158 159 #define LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4 1 160 #define LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6 2 161 #define LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4 3 162 #define LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6 4 163 /* not assigned 5 */ 164 #define LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4 6 165 #define LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6 7 166 #define LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT 8 167 #define LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW_OLD 9 168 #define LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW 10 169 #define LSPPING_TLV_TARGETFEC_SUBTLV_FEC_129_PW 11 170 #define LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4 12 171 #define LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6 13 172 #define LSPPING_TLV_TARGETFEC_SUBTLV_GENERIC_IPV4 14 173 #define LSPPING_TLV_TARGETFEC_SUBTLV_GENERIC_IPV6 15 174 #define LSPPING_TLV_TARGETFEC_SUBTLV_NIL_FEC 16 175 176 static const struct tok lspping_tlvtargetfec_subtlv_values[] = { 177 { LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4, "LDP IPv4 prefix"}, 178 { LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6, "LDP IPv6 prefix"}, 179 { LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4, "RSVP IPv4 Session Query"}, 180 { LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6, "RSVP IPv6 Session Query"}, 181 { 5, "Reserved"}, 182 { LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4, "VPN IPv4 prefix"}, 183 { LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6, "VPN IPv6 prefix"}, 184 { LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT, "L2 VPN endpoint"}, 185 { LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW_OLD, "FEC 128 pseudowire (old)"}, 186 { LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW, "FEC 128 pseudowire"}, 187 { LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4, "BGP labeled IPv4 prefix"}, 188 { LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6, "BGP labeled IPv6 prefix"}, 189 { 0, NULL} 190 }; 191 192 /* 193 * 0 1 2 3 194 * 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 195 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 196 * | IPv4 prefix | 197 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 198 * | Prefix Length | Must Be Zero | 199 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 200 */ 201 struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t { 202 uint8_t prefix [4]; 203 uint8_t prefix_len; 204 }; 205 206 /* 207 * 0 1 2 3 208 * 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 209 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 210 * | IPv6 prefix | 211 * | (16 octets) | 212 * | | 213 * | | 214 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 215 * | Prefix Length | Must Be Zero | 216 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 217 */ 218 struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t { 219 uint8_t prefix [16]; 220 uint8_t prefix_len; 221 }; 222 223 /* 224 * 0 1 2 3 225 * 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 226 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 227 * | IPv4 tunnel end point address | 228 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 229 * | Must Be Zero | Tunnel ID | 230 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 231 * | Extended Tunnel ID | 232 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 233 * | IPv4 tunnel sender address | 234 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 235 * | Must Be Zero | LSP ID | 236 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 237 */ 238 struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t { 239 uint8_t tunnel_endpoint [4]; 240 uint8_t res[2]; 241 uint8_t tunnel_id[2]; 242 uint8_t extended_tunnel_id[4]; 243 uint8_t tunnel_sender [4]; 244 uint8_t res2[2]; 245 uint8_t lsp_id [2]; 246 }; 247 248 /* 249 * 0 1 2 3 250 * 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 251 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 252 * | IPv6 tunnel end point address | 253 * | | 254 * | | 255 * | | 256 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 257 * | Must Be Zero | Tunnel ID | 258 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 259 * | Extended Tunnel ID | 260 * | | 261 * | | 262 * | | 263 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 264 * | IPv6 tunnel sender address | 265 * | | 266 * | | 267 * | | 268 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 269 * | Must Be Zero | LSP ID | 270 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 271 */ 272 struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t { 273 uint8_t tunnel_endpoint [16]; 274 uint8_t res[2]; 275 uint8_t tunnel_id[2]; 276 uint8_t extended_tunnel_id[16]; 277 uint8_t tunnel_sender [16]; 278 uint8_t res2[2]; 279 uint8_t lsp_id [2]; 280 }; 281 282 /* 283 * 0 1 2 3 284 * 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 285 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 286 * | Route Distinguisher | 287 * | (8 octets) | 288 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 289 * | IPv4 prefix | 290 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 291 * | Prefix Length | Must Be Zero | 292 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 293 */ 294 struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t { 295 uint8_t rd [8]; 296 uint8_t prefix [4]; 297 uint8_t prefix_len; 298 }; 299 300 /* 301 * 0 1 2 3 302 * 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 303 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 304 * | Route Distinguisher | 305 * | (8 octets) | 306 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 307 * | IPv6 prefix | 308 * | (16 octets) | 309 * | | 310 * | | 311 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 312 * | Prefix Length | Must Be Zero | 313 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 314 */ 315 struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t { 316 uint8_t rd [8]; 317 uint8_t prefix [16]; 318 uint8_t prefix_len; 319 }; 320 321 /* 322 * 0 1 2 3 323 * 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 324 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 325 * | Route Distinguisher | 326 * | (8 octets) | 327 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 328 * | Sender's VE ID | Receiver's VE ID | 329 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 330 * | Encapsulation Type | Must Be Zero | 331 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 332 * 0 1 2 3 333 */ 334 struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t { 335 uint8_t rd [8]; 336 uint8_t sender_ve_id [2]; 337 uint8_t receiver_ve_id [2]; 338 uint8_t encapsulation[2]; 339 }; 340 341 /* 342 * 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 343 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 344 * | Remote PE Address | 345 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 346 * | PW ID | 347 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 348 * | PW Type | Must Be Zero | 349 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 350 */ 351 struct lspping_tlv_targetfec_subtlv_fec_128_pw_old { 352 uint8_t remote_pe_address [4]; 353 uint8_t pw_id [4]; 354 uint8_t pw_type[2]; 355 }; 356 357 /* 358 * 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 359 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 360 * | Sender's PE Address | 361 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 362 * | Remote PE Address | 363 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 364 * | PW ID | 365 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 366 * | PW Type | Must Be Zero | 367 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 368 */ 369 struct lspping_tlv_targetfec_subtlv_fec_128_pw { 370 uint8_t sender_pe_address [4]; 371 uint8_t remote_pe_address [4]; 372 uint8_t pw_id [4]; 373 uint8_t pw_type[2]; 374 }; 375 376 /* 377 * 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 378 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 379 * | IPv4 prefix | 380 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 381 * | Prefix Length | Must Be Zero | 382 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 383 */ 384 struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t { 385 uint8_t prefix [4]; 386 uint8_t prefix_len; 387 }; 388 389 /* 390 * 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 391 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 392 * | IPv6 prefix | 393 * | (16 octets) | 394 * | | 395 * | | 396 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 397 * | Prefix Length | Must Be Zero | 398 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 399 */ 400 struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t { 401 uint8_t prefix [16]; 402 uint8_t prefix_len; 403 }; 404 405 /* 406 * 0 1 2 3 407 * 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 408 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 409 * | MTU | Address Type | Resvd (SBZ) | 410 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 411 * | Downstream IP Address (4 or 16 octets) | 412 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 413 * | Downstream Interface Address (4 or 16 octets) | 414 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 415 * | Multipath Type| Depth Limit | Multipath Length | 416 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 417 * . . 418 * . (Multipath Information) . 419 * . . 420 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 421 * | Downstream Label | Protocol | 422 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 423 * . . 424 * . . 425 * . . 426 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 427 * | Downstream Label | Protocol | 428 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 429 */ 430 /* Enough to get the address type */ 431 struct lspping_tlv_downstream_map_t { 432 uint8_t mtu [2]; 433 uint8_t address_type; 434 uint8_t ds_flags; 435 }; 436 437 struct lspping_tlv_downstream_map_ipv4_t { 438 uint8_t mtu [2]; 439 uint8_t address_type; 440 uint8_t ds_flags; 441 uint8_t downstream_ip[4]; 442 uint8_t downstream_interface[4]; 443 }; 444 445 struct lspping_tlv_downstream_map_ipv4_unmb_t { 446 uint8_t mtu [2]; 447 uint8_t address_type; 448 uint8_t ds_flags; 449 uint8_t downstream_ip[4]; 450 uint8_t downstream_interface[4]; 451 }; 452 453 struct lspping_tlv_downstream_map_ipv6_t { 454 uint8_t mtu [2]; 455 uint8_t address_type; 456 uint8_t ds_flags; 457 uint8_t downstream_ip[16]; 458 uint8_t downstream_interface[16]; 459 }; 460 461 struct lspping_tlv_downstream_map_ipv6_unmb_t { 462 uint8_t mtu [2]; 463 uint8_t address_type; 464 uint8_t ds_flags; 465 uint8_t downstream_ip[16]; 466 uint8_t downstream_interface[4]; 467 }; 468 469 struct lspping_tlv_downstream_map_info_t { 470 uint8_t multipath_type; 471 uint8_t depth_limit; 472 uint8_t multipath_length [2]; 473 }; 474 475 #define LSPPING_AFI_IPV4 1 476 #define LSPPING_AFI_IPV4_UNMB 2 477 #define LSPPING_AFI_IPV6 3 478 #define LSPPING_AFI_IPV6_UNMB 4 479 480 static const struct tok lspping_tlv_downstream_addr_values[] = { 481 { LSPPING_AFI_IPV4, "IPv4"}, 482 { LSPPING_AFI_IPV4_UNMB, "Unnumbered IPv4"}, 483 { LSPPING_AFI_IPV6, "IPv6"}, 484 { LSPPING_AFI_IPV6_UNMB, "IPv6"}, 485 { 0, NULL} 486 }; 487 488 void 489 lspping_print(netdissect_options *ndo, 490 register const u_char *pptr, register u_int len) 491 { 492 const struct lspping_common_header *lspping_com_header; 493 const struct lspping_tlv_header *lspping_tlv_header; 494 const struct lspping_tlv_header *lspping_subtlv_header; 495 const u_char *tptr,*tlv_tptr,*subtlv_tptr; 496 u_int tlen,lspping_tlv_len,lspping_tlv_type,tlv_tlen; 497 int tlv_hexdump,subtlv_hexdump; 498 u_int lspping_subtlv_len,lspping_subtlv_type; 499 struct timeval timestamp; 500 501 union { 502 const struct lspping_tlv_downstream_map_t *lspping_tlv_downstream_map; 503 const struct lspping_tlv_downstream_map_ipv4_t *lspping_tlv_downstream_map_ipv4; 504 const struct lspping_tlv_downstream_map_ipv4_unmb_t *lspping_tlv_downstream_map_ipv4_unmb; 505 const struct lspping_tlv_downstream_map_ipv6_t *lspping_tlv_downstream_map_ipv6; 506 const struct lspping_tlv_downstream_map_ipv6_unmb_t *lspping_tlv_downstream_map_ipv6_unmb; 507 const struct lspping_tlv_downstream_map_info_t *lspping_tlv_downstream_map_info; 508 } tlv_ptr; 509 510 union { 511 const struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t *lspping_tlv_targetfec_subtlv_ldp_ipv4; 512 const struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t *lspping_tlv_targetfec_subtlv_ldp_ipv6; 513 const struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t *lspping_tlv_targetfec_subtlv_rsvp_ipv4; 514 const struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t *lspping_tlv_targetfec_subtlv_rsvp_ipv6; 515 const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t *lspping_tlv_targetfec_subtlv_l3vpn_ipv4; 516 const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t *lspping_tlv_targetfec_subtlv_l3vpn_ipv6; 517 const struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t *lspping_tlv_targetfec_subtlv_l2vpn_endpt; 518 const struct lspping_tlv_targetfec_subtlv_fec_128_pw_old *lspping_tlv_targetfec_subtlv_l2vpn_vcid_old; 519 const struct lspping_tlv_targetfec_subtlv_fec_128_pw *lspping_tlv_targetfec_subtlv_l2vpn_vcid; 520 const struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t *lspping_tlv_targetfec_subtlv_bgp_ipv4; 521 const struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t *lspping_tlv_targetfec_subtlv_bgp_ipv6; 522 } subtlv_ptr; 523 524 tptr=pptr; 525 lspping_com_header = (const struct lspping_common_header *)pptr; 526 if (len < sizeof(const struct lspping_common_header)) 527 goto tooshort; 528 ND_TCHECK(*lspping_com_header); 529 530 /* 531 * Sanity checking of the header. 532 */ 533 if (EXTRACT_16BITS(&lspping_com_header->version[0]) != LSPPING_VERSION) { 534 ND_PRINT((ndo, "LSP-PING version %u packet not supported", 535 EXTRACT_16BITS(&lspping_com_header->version[0]))); 536 return; 537 } 538 539 /* in non-verbose mode just lets print the basic Message Type*/ 540 if (ndo->ndo_vflag < 1) { 541 ND_PRINT((ndo, "LSP-PINGv%u, %s, seq %u, length: %u", 542 EXTRACT_16BITS(&lspping_com_header->version[0]), 543 tok2str(lspping_msg_type_values, "unknown (%u)",lspping_com_header->msg_type), 544 EXTRACT_32BITS(lspping_com_header->seq_number), 545 len)); 546 return; 547 } 548 549 /* ok they seem to want to know everything - lets fully decode it */ 550 551 tlen=len; 552 553 ND_PRINT((ndo, "\n\tLSP-PINGv%u, msg-type: %s (%u), length: %u\n\t reply-mode: %s (%u)", 554 EXTRACT_16BITS(&lspping_com_header->version[0]), 555 tok2str(lspping_msg_type_values, "unknown",lspping_com_header->msg_type), 556 lspping_com_header->msg_type, 557 len, 558 tok2str(lspping_reply_mode_values, "unknown",lspping_com_header->reply_mode), 559 lspping_com_header->reply_mode)); 560 561 /* 562 * the following return codes require that the subcode is attached 563 * at the end of the translated token output 564 */ 565 if (lspping_com_header->return_code == 3 || 566 lspping_com_header->return_code == 4 || 567 lspping_com_header->return_code == 8 || 568 lspping_com_header->return_code == 10 || 569 lspping_com_header->return_code == 11 || 570 lspping_com_header->return_code == 12 ) 571 ND_PRINT((ndo, "\n\t Return Code: %s %u (%u)\n\t Return Subcode: (%u)", 572 tok2str(lspping_return_code_values, "unknown",lspping_com_header->return_code), 573 lspping_com_header->return_subcode, 574 lspping_com_header->return_code, 575 lspping_com_header->return_subcode)); 576 else 577 ND_PRINT((ndo, "\n\t Return Code: %s (%u)\n\t Return Subcode: (%u)", 578 tok2str(lspping_return_code_values, "unknown",lspping_com_header->return_code), 579 lspping_com_header->return_code, 580 lspping_com_header->return_subcode)); 581 582 ND_PRINT((ndo, "\n\t Sender Handle: 0x%08x, Sequence: %u", 583 EXTRACT_32BITS(lspping_com_header->sender_handle), 584 EXTRACT_32BITS(lspping_com_header->seq_number))); 585 586 timestamp.tv_sec=EXTRACT_32BITS(lspping_com_header->ts_sent_sec); 587 timestamp.tv_usec=EXTRACT_32BITS(lspping_com_header->ts_sent_usec); 588 ND_PRINT((ndo, "\n\t Sender Timestamp: ")); 589 ts_print(ndo, ×tamp); 590 591 timestamp.tv_sec=EXTRACT_32BITS(lspping_com_header->ts_rcvd_sec); 592 timestamp.tv_usec=EXTRACT_32BITS(lspping_com_header->ts_rcvd_usec); 593 ND_PRINT((ndo, "Receiver Timestamp: ")); 594 if ((timestamp.tv_sec != 0) && (timestamp.tv_usec != 0)) 595 ts_print(ndo, ×tamp); 596 else 597 ND_PRINT((ndo, "no timestamp")); 598 599 tptr+=sizeof(const struct lspping_common_header); 600 tlen-=sizeof(const struct lspping_common_header); 601 602 while (tlen != 0) { 603 /* Does the TLV go past the end of the packet? */ 604 if (tlen < sizeof(struct lspping_tlv_header)) 605 goto tooshort; 606 607 /* did we capture enough for fully decoding the tlv header ? */ 608 ND_TCHECK2(*tptr, sizeof(struct lspping_tlv_header)); 609 610 lspping_tlv_header = (const struct lspping_tlv_header *)tptr; 611 lspping_tlv_type=EXTRACT_16BITS(lspping_tlv_header->type); 612 lspping_tlv_len=EXTRACT_16BITS(lspping_tlv_header->length); 613 614 ND_PRINT((ndo, "\n\t %s TLV (%u), length: %u", 615 tok2str(lspping_tlv_values, 616 "Unknown", 617 lspping_tlv_type), 618 lspping_tlv_type, 619 lspping_tlv_len)); 620 621 /* some little sanity checking */ 622 if (lspping_tlv_len == 0) { 623 tptr+=sizeof(struct lspping_tlv_header); 624 tlen-=sizeof(struct lspping_tlv_header); 625 continue; /* no value to dissect */ 626 } 627 628 tlv_tptr=tptr+sizeof(struct lspping_tlv_header); 629 tlv_tlen=lspping_tlv_len; /* header not included -> no adjustment */ 630 631 /* Does the TLV go past the end of the packet? */ 632 if (tlen < lspping_tlv_len+sizeof(struct lspping_tlv_header)) 633 goto tooshort; 634 /* did we capture enough for fully decoding the tlv ? */ 635 ND_TCHECK2(*tlv_tptr, lspping_tlv_len); 636 tlv_hexdump=FALSE; 637 638 switch(lspping_tlv_type) { 639 case LSPPING_TLV_TARGET_FEC_STACK: 640 while (tlv_tlen != 0) { 641 /* Does the subTLV header go past the end of the TLV? */ 642 if (tlv_tlen < sizeof(struct lspping_tlv_header)) { 643 ND_PRINT((ndo, "\n\t TLV is too short")); 644 tlv_hexdump = TRUE; 645 goto tlv_tooshort; 646 } 647 /* did we capture enough for fully decoding the subtlv header ? */ 648 ND_TCHECK2(*tlv_tptr, sizeof(struct lspping_tlv_header)); 649 subtlv_hexdump=FALSE; 650 651 lspping_subtlv_header = (const struct lspping_tlv_header *)tlv_tptr; 652 lspping_subtlv_type=EXTRACT_16BITS(lspping_subtlv_header->type); 653 lspping_subtlv_len=EXTRACT_16BITS(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((ndo, "\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_TCHECK2(*subtlv_tptr, lspping_subtlv_len); 665 666 ND_PRINT((ndo, "\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((ndo, "\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((ndo, "\n\t %s/%u", 684 ipaddr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4->prefix), 685 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((ndo, "\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((ndo, "\n\t %s/%u", 698 ip6addr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6->prefix), 699 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((ndo, "\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((ndo, "\n\t %s/%u", 712 ipaddr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4->prefix), 713 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((ndo, "\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((ndo, "\n\t %s/%u", 726 ip6addr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6->prefix), 727 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((ndo, "\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((ndo, "\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 ipaddr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_endpoint), 742 ipaddr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_sender), 743 EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->lsp_id), 744 EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_id), 745 ipaddr_string(ndo, 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((ndo, "\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((ndo, "\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 ip6addr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_endpoint), 760 ip6addr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_sender), 761 EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->lsp_id), 762 EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_id), 763 ip6addr_string(ndo, 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((ndo, "\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((ndo, "\n\t RD: %s, %s/%u", 776 bgp_vpn_rd_print(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->rd), 777 ipaddr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->prefix), 778 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((ndo, "\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((ndo, "\n\t RD: %s, %s/%u", 791 bgp_vpn_rd_print(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->rd), 792 ip6addr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->prefix), 793 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((ndo, "\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((ndo, "\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 EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->sender_ve_id), 809 EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->receiver_ve_id), 810 tok2str(mpls_pw_types_values, 811 "unknown", 812 EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->encapsulation)), 813 EXTRACT_16BITS(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((ndo, "\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((ndo, "\n\t Remote PE: %s" \ 827 "\n\t PW ID: 0x%08x, PW Type: %s (%u)", 828 ipaddr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->remote_pe_address), 829 EXTRACT_32BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->pw_id), 830 tok2str(mpls_pw_types_values, 831 "unknown", 832 EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->pw_type)), 833 EXTRACT_16BITS(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((ndo, "\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((ndo, "\n\t Sender PE: %s, Remote PE: %s" \ 846 "\n\t PW ID: 0x%08x, PW Type: %s (%u)", 847 ipaddr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->sender_pe_address), 848 ipaddr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->remote_pe_address), 849 EXTRACT_32BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->pw_id), 850 tok2str(mpls_pw_types_values, 851 "unknown", 852 EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->pw_type)), 853 EXTRACT_16BITS(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((ndo, "\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((ndo, "\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_TCHECK2(*tlv_tptr, sizeof(struct lspping_tlv_downstream_map_t)); 890 891 tlv_ptr.lspping_tlv_downstream_map= \ 892 (const struct lspping_tlv_downstream_map_t *)tlv_tptr; 893 894 /* that strange thing with the downstream map TLV is that until now 895 * we do not know if its IPv4 or IPv6 or is unnumbered; after 896 * we find the address-type, we recast the tlv_tptr and move on. */ 897 898 ND_PRINT((ndo, "\n\t MTU: %u, Address-Type: %s (%u)", 899 EXTRACT_16BITS(tlv_ptr.lspping_tlv_downstream_map->mtu), 900 tok2str(lspping_tlv_downstream_addr_values, 901 "unknown", 902 tlv_ptr.lspping_tlv_downstream_map->address_type), 903 tlv_ptr.lspping_tlv_downstream_map->address_type)); 904 905 switch(tlv_ptr.lspping_tlv_downstream_map->address_type) { 906 907 case LSPPING_AFI_IPV4: 908 /* Does the data go past the end of the TLV? */ 909 if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv4_t)) { 910 ND_PRINT((ndo, "\n\t TLV is too short")); 911 tlv_hexdump = TRUE; 912 goto tlv_tooshort; 913 } 914 /* Did we capture enough for this part of the TLV? */ 915 ND_TCHECK2(*tlv_tptr, sizeof(struct lspping_tlv_downstream_map_ipv4_t)); 916 917 tlv_ptr.lspping_tlv_downstream_map_ipv4= \ 918 (const struct lspping_tlv_downstream_map_ipv4_t *)tlv_tptr; 919 ND_PRINT((ndo, "\n\t Downstream IP: %s" \ 920 "\n\t Downstream Interface IP: %s", 921 ipaddr_string(ndo, tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_ip), 922 ipaddr_string(ndo, tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_interface))); 923 tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv4_t); 924 tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv4_t); 925 break; 926 case LSPPING_AFI_IPV4_UNMB: 927 /* Does the data go past the end of the TLV? */ 928 if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t)) { 929 ND_PRINT((ndo, "\n\t TLV is too short")); 930 tlv_hexdump = TRUE; 931 goto tlv_tooshort; 932 } 933 /* Did we capture enough for this part of the TLV? */ 934 ND_TCHECK2(*tlv_tptr, sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t)); 935 936 tlv_ptr.lspping_tlv_downstream_map_ipv4_unmb= \ 937 (const struct lspping_tlv_downstream_map_ipv4_unmb_t *)tlv_tptr; 938 ND_PRINT((ndo, "\n\t Downstream IP: %s" \ 939 "\n\t Downstream Interface Index: 0x%08x", 940 ipaddr_string(ndo, tlv_ptr.lspping_tlv_downstream_map_ipv4_unmb->downstream_ip), 941 EXTRACT_32BITS(tlv_ptr.lspping_tlv_downstream_map_ipv4_unmb->downstream_interface))); 942 tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t); 943 tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t); 944 break; 945 case LSPPING_AFI_IPV6: 946 /* Does the data go past the end of the TLV? */ 947 if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv6_t)) { 948 ND_PRINT((ndo, "\n\t TLV is too short")); 949 tlv_hexdump = TRUE; 950 goto tlv_tooshort; 951 } 952 /* Did we capture enough for this part of the TLV? */ 953 ND_TCHECK2(*tlv_tptr, sizeof(struct lspping_tlv_downstream_map_ipv6_t)); 954 955 tlv_ptr.lspping_tlv_downstream_map_ipv6= \ 956 (const struct lspping_tlv_downstream_map_ipv6_t *)tlv_tptr; 957 ND_PRINT((ndo, "\n\t Downstream IP: %s" \ 958 "\n\t Downstream Interface IP: %s", 959 ip6addr_string(ndo, tlv_ptr.lspping_tlv_downstream_map_ipv6->downstream_ip), 960 ip6addr_string(ndo, tlv_ptr.lspping_tlv_downstream_map_ipv6->downstream_interface))); 961 tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv6_t); 962 tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv6_t); 963 break; 964 case LSPPING_AFI_IPV6_UNMB: 965 /* Does the data go past the end of the TLV? */ 966 if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t)) { 967 ND_PRINT((ndo, "\n\t TLV is too short")); 968 tlv_hexdump = TRUE; 969 goto tlv_tooshort; 970 } 971 /* Did we capture enough for this part of the TLV? */ 972 ND_TCHECK2(*tlv_tptr, sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t)); 973 974 tlv_ptr.lspping_tlv_downstream_map_ipv6_unmb= \ 975 (const struct lspping_tlv_downstream_map_ipv6_unmb_t *)tlv_tptr; 976 ND_PRINT((ndo, "\n\t Downstream IP: %s" \ 977 "\n\t Downstream Interface Index: 0x%08x", 978 ip6addr_string(ndo, tlv_ptr.lspping_tlv_downstream_map_ipv6_unmb->downstream_ip), 979 EXTRACT_32BITS(tlv_ptr.lspping_tlv_downstream_map_ipv6_unmb->downstream_interface))); 980 tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t); 981 tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t); 982 break; 983 984 default: 985 /* should not happen ! - no error message - tok2str() has barked already */ 986 break; 987 } 988 989 /* Does the data go past the end of the TLV? */ 990 if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_info_t)) { 991 ND_PRINT((ndo, "\n\t TLV is too short")); 992 tlv_hexdump = TRUE; 993 goto tlv_tooshort; 994 } 995 /* Did we capture enough for this part of the TLV? */ 996 ND_TCHECK2(*tlv_tptr, sizeof(struct lspping_tlv_downstream_map_info_t)); 997 998 tlv_ptr.lspping_tlv_downstream_map_info= \ 999 (const struct lspping_tlv_downstream_map_info_t *)tlv_tptr; 1000 1001 /* FIXME add hash-key type, depth limit, multipath processing */ 1002 1003 tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_info_t); 1004 tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_info_t); 1005 1006 /* FIXME print downstream labels */ 1007 1008 tlv_hexdump=TRUE; /* dump the TLV until code complete */ 1009 1010 break; 1011 1012 case LSPPING_TLV_BFD_DISCRIMINATOR: 1013 if (tlv_tlen < LSPPING_TLV_BFD_DISCRIMINATOR_LEN) { 1014 ND_PRINT((ndo, "\n\t TLV is too short")); 1015 tlv_hexdump = TRUE; 1016 goto tlv_tooshort; 1017 } else { 1018 ND_TCHECK2(*tptr, LSPPING_TLV_BFD_DISCRIMINATOR_LEN); 1019 ND_PRINT((ndo, "\n\t BFD Discriminator 0x%08x", EXTRACT_32BITS(tptr))); 1020 } 1021 break; 1022 1023 case LSPPING_TLV_VENDOR_ENTERPRISE: 1024 { 1025 uint32_t vendor_id; 1026 1027 if (tlv_tlen < LSPPING_TLV_VENDOR_ENTERPRISE_LEN) { 1028 ND_PRINT((ndo, "\n\t TLV is too short")); 1029 tlv_hexdump = TRUE; 1030 goto tlv_tooshort; 1031 } else { 1032 ND_TCHECK2(*tptr, LSPPING_TLV_VENDOR_ENTERPRISE_LEN); 1033 vendor_id = EXTRACT_32BITS(tlv_tptr); 1034 ND_PRINT((ndo, "\n\t Vendor: %s (0x%04x)", 1035 tok2str(smi_values, "Unknown", vendor_id), 1036 vendor_id)); 1037 } 1038 } 1039 break; 1040 1041 /* 1042 * FIXME those are the defined TLVs that lack a decoder 1043 * you are welcome to contribute code ;-) 1044 */ 1045 case LSPPING_TLV_PAD: 1046 case LSPPING_TLV_ERROR_CODE: 1047 case LSPPING_TLV_VENDOR_PRIVATE: 1048 1049 default: 1050 if (ndo->ndo_vflag <= 1) 1051 print_unknown_data(ndo, tlv_tptr, "\n\t ", tlv_tlen); 1052 break; 1053 } 1054 /* do we want to see an additionally tlv hexdump ? */ 1055 tlv_tooshort: 1056 if (ndo->ndo_vflag > 1 || tlv_hexdump==TRUE) 1057 print_unknown_data(ndo, tptr+sizeof(struct lspping_tlv_header), "\n\t ", 1058 lspping_tlv_len); 1059 1060 1061 /* All TLVs are aligned to four octet boundary */ 1062 if (lspping_tlv_len % 4) { 1063 lspping_tlv_len += (4 - lspping_tlv_len % 4); 1064 /* Does the TLV, including padding, go past the end of the packet? */ 1065 if (tlen < lspping_tlv_len+sizeof(struct lspping_tlv_header)) 1066 goto tooshort; 1067 } 1068 1069 tptr+=lspping_tlv_len+sizeof(struct lspping_tlv_header); 1070 tlen-=lspping_tlv_len+sizeof(struct lspping_tlv_header); 1071 } 1072 return; 1073 tooshort: 1074 ND_PRINT((ndo, "\n\t\t packet is too short")); 1075 return; 1076 trunc: 1077 ND_PRINT((ndo, "\n\t\t packet exceeded snapshot")); 1078 return; 1079 } 1080 /* 1081 * Local Variables: 1082 * c-style: whitesmith 1083 * c-basic-offset: 8 1084 * End: 1085 */ 1086