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