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