1 /* 2 * Copyright (c) 1998-2007 The TCPDUMP project 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that: (1) source code 6 * distributions retain the above copyright notice and this paragraph 7 * in its entirety, and (2) distributions including binary code include 8 * the above copyright notice and this paragraph in its entirety in 9 * the documentation or other materials provided with the distribution. 10 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND 11 * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT 12 * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 13 * FOR A PARTICULAR PURPOSE. 14 * 15 * Original code by Hannes Gredler (hannes@gredler.at) 16 */ 17 18 #include <sys/cdefs.h> 19 #ifndef lint 20 __RCSID("$NetBSD: print-rsvp.c,v 1.11 2019/10/01 16:06:16 christos Exp $"); 21 #endif 22 23 /* \summary: Resource ReSerVation Protocol (RSVP) printer */ 24 25 #ifdef HAVE_CONFIG_H 26 #include "config.h" 27 #endif 28 29 #include <netdissect-stdinc.h> 30 31 #include "netdissect.h" 32 #include "extract.h" 33 #include "addrtoname.h" 34 #include "ethertype.h" 35 #include "gmpls.h" 36 #include "af.h" 37 #include "signature.h" 38 39 static const char tstr[] = " [|rsvp]"; 40 41 /* 42 * RFC 2205 common header 43 * 44 * 0 1 2 3 45 * +-------------+-------------+-------------+-------------+ 46 * | Vers | Flags| Msg Type | RSVP Checksum | 47 * +-------------+-------------+-------------+-------------+ 48 * | Send_TTL | (Reserved) | RSVP Length | 49 * +-------------+-------------+-------------+-------------+ 50 * 51 */ 52 53 struct rsvp_common_header { 54 uint8_t version_flags; 55 uint8_t msg_type; 56 uint8_t checksum[2]; 57 uint8_t ttl; 58 uint8_t reserved; 59 uint8_t length[2]; 60 }; 61 62 /* 63 * RFC2205 object header 64 * 65 * 66 * 0 1 2 3 67 * +-------------+-------------+-------------+-------------+ 68 * | Length (bytes) | Class-Num | C-Type | 69 * +-------------+-------------+-------------+-------------+ 70 * | | 71 * // (Object contents) // 72 * | | 73 * +-------------+-------------+-------------+-------------+ 74 */ 75 76 struct rsvp_object_header { 77 uint8_t length[2]; 78 uint8_t class_num; 79 uint8_t ctype; 80 }; 81 82 #define RSVP_VERSION 1 83 #define RSVP_EXTRACT_VERSION(x) (((x)&0xf0)>>4) 84 #define RSVP_EXTRACT_FLAGS(x) ((x)&0x0f) 85 86 #define RSVP_MSGTYPE_PATH 1 87 #define RSVP_MSGTYPE_RESV 2 88 #define RSVP_MSGTYPE_PATHERR 3 89 #define RSVP_MSGTYPE_RESVERR 4 90 #define RSVP_MSGTYPE_PATHTEAR 5 91 #define RSVP_MSGTYPE_RESVTEAR 6 92 #define RSVP_MSGTYPE_RESVCONF 7 93 #define RSVP_MSGTYPE_BUNDLE 12 94 #define RSVP_MSGTYPE_ACK 13 95 #define RSVP_MSGTYPE_HELLO_OLD 14 /* ancient Hellos */ 96 #define RSVP_MSGTYPE_SREFRESH 15 97 #define RSVP_MSGTYPE_HELLO 20 98 99 static const struct tok rsvp_msg_type_values[] = { 100 { RSVP_MSGTYPE_PATH, "Path" }, 101 { RSVP_MSGTYPE_RESV, "Resv" }, 102 { RSVP_MSGTYPE_PATHERR, "PathErr" }, 103 { RSVP_MSGTYPE_RESVERR, "ResvErr" }, 104 { RSVP_MSGTYPE_PATHTEAR, "PathTear" }, 105 { RSVP_MSGTYPE_RESVTEAR, "ResvTear" }, 106 { RSVP_MSGTYPE_RESVCONF, "ResvConf" }, 107 { RSVP_MSGTYPE_BUNDLE, "Bundle" }, 108 { RSVP_MSGTYPE_ACK, "Acknowledgement" }, 109 { RSVP_MSGTYPE_HELLO_OLD, "Hello (Old)" }, 110 { RSVP_MSGTYPE_SREFRESH, "Refresh" }, 111 { RSVP_MSGTYPE_HELLO, "Hello" }, 112 { 0, NULL} 113 }; 114 115 static const struct tok rsvp_header_flag_values[] = { 116 { 0x01, "Refresh reduction capable" }, /* rfc2961 */ 117 { 0, NULL} 118 }; 119 120 #define RSVP_OBJ_SESSION 1 /* rfc2205 */ 121 #define RSVP_OBJ_RSVP_HOP 3 /* rfc2205, rfc3473 */ 122 #define RSVP_OBJ_INTEGRITY 4 /* rfc2747 */ 123 #define RSVP_OBJ_TIME_VALUES 5 /* rfc2205 */ 124 #define RSVP_OBJ_ERROR_SPEC 6 125 #define RSVP_OBJ_SCOPE 7 126 #define RSVP_OBJ_STYLE 8 /* rfc2205 */ 127 #define RSVP_OBJ_FLOWSPEC 9 /* rfc2215 */ 128 #define RSVP_OBJ_FILTERSPEC 10 /* rfc2215 */ 129 #define RSVP_OBJ_SENDER_TEMPLATE 11 130 #define RSVP_OBJ_SENDER_TSPEC 12 /* rfc2215 */ 131 #define RSVP_OBJ_ADSPEC 13 /* rfc2215 */ 132 #define RSVP_OBJ_POLICY_DATA 14 133 #define RSVP_OBJ_CONFIRM 15 /* rfc2205 */ 134 #define RSVP_OBJ_LABEL 16 /* rfc3209 */ 135 #define RSVP_OBJ_LABEL_REQ 19 /* rfc3209 */ 136 #define RSVP_OBJ_ERO 20 /* rfc3209 */ 137 #define RSVP_OBJ_RRO 21 /* rfc3209 */ 138 #define RSVP_OBJ_HELLO 22 /* rfc3209 */ 139 #define RSVP_OBJ_MESSAGE_ID 23 /* rfc2961 */ 140 #define RSVP_OBJ_MESSAGE_ID_ACK 24 /* rfc2961 */ 141 #define RSVP_OBJ_MESSAGE_ID_LIST 25 /* rfc2961 */ 142 #define RSVP_OBJ_RECOVERY_LABEL 34 /* rfc3473 */ 143 #define RSVP_OBJ_UPSTREAM_LABEL 35 /* rfc3473 */ 144 #define RSVP_OBJ_LABEL_SET 36 /* rfc3473 */ 145 #define RSVP_OBJ_PROTECTION 37 /* rfc3473 */ 146 #define RSVP_OBJ_S2L 50 /* rfc4875 */ 147 #define RSVP_OBJ_DETOUR 63 /* draft-ietf-mpls-rsvp-lsp-fastreroute-07 */ 148 #define RSVP_OBJ_CLASSTYPE 66 /* rfc4124 */ 149 #define RSVP_OBJ_CLASSTYPE_OLD 125 /* draft-ietf-tewg-diff-te-proto-07 */ 150 #define RSVP_OBJ_SUGGESTED_LABEL 129 /* rfc3473 */ 151 #define RSVP_OBJ_ACCEPT_LABEL_SET 130 /* rfc3473 */ 152 #define RSVP_OBJ_RESTART_CAPABILITY 131 /* rfc3473 */ 153 #define RSVP_OBJ_NOTIFY_REQ 195 /* rfc3473 */ 154 #define RSVP_OBJ_ADMIN_STATUS 196 /* rfc3473 */ 155 #define RSVP_OBJ_PROPERTIES 204 /* juniper proprietary */ 156 #define RSVP_OBJ_FASTREROUTE 205 /* draft-ietf-mpls-rsvp-lsp-fastreroute-07 */ 157 #define RSVP_OBJ_SESSION_ATTRIBUTE 207 /* rfc3209 */ 158 #define RSVP_OBJ_GENERALIZED_UNI 229 /* OIF RSVP extensions UNI 1.0 Signaling, Rel. 2 */ 159 #define RSVP_OBJ_CALL_ID 230 /* rfc3474 */ 160 #define RSVP_OBJ_CALL_OPS 236 /* rfc3474 */ 161 162 static const struct tok rsvp_obj_values[] = { 163 { RSVP_OBJ_SESSION, "Session" }, 164 { RSVP_OBJ_RSVP_HOP, "RSVP Hop" }, 165 { RSVP_OBJ_INTEGRITY, "Integrity" }, 166 { RSVP_OBJ_TIME_VALUES, "Time Values" }, 167 { RSVP_OBJ_ERROR_SPEC, "Error Spec" }, 168 { RSVP_OBJ_SCOPE, "Scope" }, 169 { RSVP_OBJ_STYLE, "Style" }, 170 { RSVP_OBJ_FLOWSPEC, "Flowspec" }, 171 { RSVP_OBJ_FILTERSPEC, "FilterSpec" }, 172 { RSVP_OBJ_SENDER_TEMPLATE, "Sender Template" }, 173 { RSVP_OBJ_SENDER_TSPEC, "Sender TSpec" }, 174 { RSVP_OBJ_ADSPEC, "Adspec" }, 175 { RSVP_OBJ_POLICY_DATA, "Policy Data" }, 176 { RSVP_OBJ_CONFIRM, "Confirm" }, 177 { RSVP_OBJ_LABEL, "Label" }, 178 { RSVP_OBJ_LABEL_REQ, "Label Request" }, 179 { RSVP_OBJ_ERO, "ERO" }, 180 { RSVP_OBJ_RRO, "RRO" }, 181 { RSVP_OBJ_HELLO, "Hello" }, 182 { RSVP_OBJ_MESSAGE_ID, "Message ID" }, 183 { RSVP_OBJ_MESSAGE_ID_ACK, "Message ID Ack" }, 184 { RSVP_OBJ_MESSAGE_ID_LIST, "Message ID List" }, 185 { RSVP_OBJ_RECOVERY_LABEL, "Recovery Label" }, 186 { RSVP_OBJ_UPSTREAM_LABEL, "Upstream Label" }, 187 { RSVP_OBJ_LABEL_SET, "Label Set" }, 188 { RSVP_OBJ_ACCEPT_LABEL_SET, "Acceptable Label Set" }, 189 { RSVP_OBJ_DETOUR, "Detour" }, 190 { RSVP_OBJ_CLASSTYPE, "Class Type" }, 191 { RSVP_OBJ_CLASSTYPE_OLD, "Class Type (old)" }, 192 { RSVP_OBJ_SUGGESTED_LABEL, "Suggested Label" }, 193 { RSVP_OBJ_PROPERTIES, "Properties" }, 194 { RSVP_OBJ_FASTREROUTE, "Fast Re-Route" }, 195 { RSVP_OBJ_SESSION_ATTRIBUTE, "Session Attribute" }, 196 { RSVP_OBJ_GENERALIZED_UNI, "Generalized UNI" }, 197 { RSVP_OBJ_CALL_ID, "Call-ID" }, 198 { RSVP_OBJ_CALL_OPS, "Call Capability" }, 199 { RSVP_OBJ_RESTART_CAPABILITY, "Restart Capability" }, 200 { RSVP_OBJ_NOTIFY_REQ, "Notify Request" }, 201 { RSVP_OBJ_PROTECTION, "Protection" }, 202 { RSVP_OBJ_ADMIN_STATUS, "Administrative Status" }, 203 { RSVP_OBJ_S2L, "Sub-LSP to LSP" }, 204 { 0, NULL} 205 }; 206 207 #define RSVP_CTYPE_IPV4 1 208 #define RSVP_CTYPE_IPV6 2 209 #define RSVP_CTYPE_TUNNEL_IPV4 7 210 #define RSVP_CTYPE_TUNNEL_IPV6 8 211 #define RSVP_CTYPE_UNI_IPV4 11 /* OIF RSVP extensions UNI 1.0 Signaling Rel. 2 */ 212 #define RSVP_CTYPE_1 1 213 #define RSVP_CTYPE_2 2 214 #define RSVP_CTYPE_3 3 215 #define RSVP_CTYPE_4 4 216 #define RSVP_CTYPE_12 12 217 #define RSVP_CTYPE_13 13 218 #define RSVP_CTYPE_14 14 219 220 /* 221 * the ctypes are not globally unique so for 222 * translating it to strings we build a table based 223 * on objects offsetted by the ctype 224 */ 225 226 static const struct tok rsvp_ctype_values[] = { 227 { 256*RSVP_OBJ_RSVP_HOP+RSVP_CTYPE_IPV4, "IPv4" }, 228 { 256*RSVP_OBJ_RSVP_HOP+RSVP_CTYPE_IPV6, "IPv6" }, 229 { 256*RSVP_OBJ_RSVP_HOP+RSVP_CTYPE_3, "IPv4 plus opt. TLVs" }, 230 { 256*RSVP_OBJ_RSVP_HOP+RSVP_CTYPE_4, "IPv6 plus opt. TLVs" }, 231 { 256*RSVP_OBJ_NOTIFY_REQ+RSVP_CTYPE_IPV4, "IPv4" }, 232 { 256*RSVP_OBJ_NOTIFY_REQ+RSVP_CTYPE_IPV6, "IPv6" }, 233 { 256*RSVP_OBJ_CONFIRM+RSVP_CTYPE_IPV4, "IPv4" }, 234 { 256*RSVP_OBJ_CONFIRM+RSVP_CTYPE_IPV6, "IPv6" }, 235 { 256*RSVP_OBJ_TIME_VALUES+RSVP_CTYPE_1, "1" }, 236 { 256*RSVP_OBJ_FLOWSPEC+RSVP_CTYPE_1, "obsolete" }, 237 { 256*RSVP_OBJ_FLOWSPEC+RSVP_CTYPE_2, "IntServ" }, 238 { 256*RSVP_OBJ_SENDER_TSPEC+RSVP_CTYPE_2, "IntServ" }, 239 { 256*RSVP_OBJ_ADSPEC+RSVP_CTYPE_2, "IntServ" }, 240 { 256*RSVP_OBJ_FILTERSPEC+RSVP_CTYPE_IPV4, "IPv4" }, 241 { 256*RSVP_OBJ_FILTERSPEC+RSVP_CTYPE_IPV6, "IPv6" }, 242 { 256*RSVP_OBJ_FILTERSPEC+RSVP_CTYPE_3, "IPv6 Flow-label" }, 243 { 256*RSVP_OBJ_FILTERSPEC+RSVP_CTYPE_TUNNEL_IPV4, "Tunnel IPv4" }, 244 { 256*RSVP_OBJ_FILTERSPEC+RSVP_CTYPE_12, "IPv4 P2MP LSP Tunnel" }, 245 { 256*RSVP_OBJ_FILTERSPEC+RSVP_CTYPE_13, "IPv6 P2MP LSP Tunnel" }, 246 { 256*RSVP_OBJ_SESSION+RSVP_CTYPE_IPV4, "IPv4" }, 247 { 256*RSVP_OBJ_SESSION+RSVP_CTYPE_IPV6, "IPv6" }, 248 { 256*RSVP_OBJ_SESSION+RSVP_CTYPE_TUNNEL_IPV4, "Tunnel IPv4" }, 249 { 256*RSVP_OBJ_SESSION+RSVP_CTYPE_UNI_IPV4, "UNI IPv4" }, 250 { 256*RSVP_OBJ_SESSION+RSVP_CTYPE_13, "IPv4 P2MP LSP Tunnel" }, 251 { 256*RSVP_OBJ_SESSION+RSVP_CTYPE_14, "IPv6 P2MP LSP Tunnel" }, 252 { 256*RSVP_OBJ_SENDER_TEMPLATE+RSVP_CTYPE_IPV4, "IPv4" }, 253 { 256*RSVP_OBJ_SENDER_TEMPLATE+RSVP_CTYPE_IPV6, "IPv6" }, 254 { 256*RSVP_OBJ_SENDER_TEMPLATE+RSVP_CTYPE_TUNNEL_IPV4, "Tunnel IPv4" }, 255 { 256*RSVP_OBJ_SENDER_TEMPLATE+RSVP_CTYPE_12, "IPv4 P2MP LSP Tunnel" }, 256 { 256*RSVP_OBJ_SENDER_TEMPLATE+RSVP_CTYPE_13, "IPv6 P2MP LSP Tunnel" }, 257 { 256*RSVP_OBJ_MESSAGE_ID+RSVP_CTYPE_1, "1" }, 258 { 256*RSVP_OBJ_MESSAGE_ID_ACK+RSVP_CTYPE_1, "Message id ack" }, 259 { 256*RSVP_OBJ_MESSAGE_ID_ACK+RSVP_CTYPE_2, "Message id nack" }, 260 { 256*RSVP_OBJ_MESSAGE_ID_LIST+RSVP_CTYPE_1, "1" }, 261 { 256*RSVP_OBJ_STYLE+RSVP_CTYPE_1, "1" }, 262 { 256*RSVP_OBJ_HELLO+RSVP_CTYPE_1, "Hello Request" }, 263 { 256*RSVP_OBJ_HELLO+RSVP_CTYPE_2, "Hello Ack" }, 264 { 256*RSVP_OBJ_LABEL_REQ+RSVP_CTYPE_1, "without label range" }, 265 { 256*RSVP_OBJ_LABEL_REQ+RSVP_CTYPE_2, "with ATM label range" }, 266 { 256*RSVP_OBJ_LABEL_REQ+RSVP_CTYPE_3, "with FR label range" }, 267 { 256*RSVP_OBJ_LABEL_REQ+RSVP_CTYPE_4, "Generalized Label" }, 268 { 256*RSVP_OBJ_LABEL+RSVP_CTYPE_1, "Label" }, 269 { 256*RSVP_OBJ_LABEL+RSVP_CTYPE_2, "Generalized Label" }, 270 { 256*RSVP_OBJ_LABEL+RSVP_CTYPE_3, "Waveband Switching" }, 271 { 256*RSVP_OBJ_SUGGESTED_LABEL+RSVP_CTYPE_1, "Label" }, 272 { 256*RSVP_OBJ_SUGGESTED_LABEL+RSVP_CTYPE_2, "Generalized Label" }, 273 { 256*RSVP_OBJ_SUGGESTED_LABEL+RSVP_CTYPE_3, "Waveband Switching" }, 274 { 256*RSVP_OBJ_UPSTREAM_LABEL+RSVP_CTYPE_1, "Label" }, 275 { 256*RSVP_OBJ_UPSTREAM_LABEL+RSVP_CTYPE_2, "Generalized Label" }, 276 { 256*RSVP_OBJ_UPSTREAM_LABEL+RSVP_CTYPE_3, "Waveband Switching" }, 277 { 256*RSVP_OBJ_RECOVERY_LABEL+RSVP_CTYPE_1, "Label" }, 278 { 256*RSVP_OBJ_RECOVERY_LABEL+RSVP_CTYPE_2, "Generalized Label" }, 279 { 256*RSVP_OBJ_RECOVERY_LABEL+RSVP_CTYPE_3, "Waveband Switching" }, 280 { 256*RSVP_OBJ_ERO+RSVP_CTYPE_IPV4, "IPv4" }, 281 { 256*RSVP_OBJ_RRO+RSVP_CTYPE_IPV4, "IPv4" }, 282 { 256*RSVP_OBJ_ERROR_SPEC+RSVP_CTYPE_IPV4, "IPv4" }, 283 { 256*RSVP_OBJ_ERROR_SPEC+RSVP_CTYPE_IPV6, "IPv6" }, 284 { 256*RSVP_OBJ_ERROR_SPEC+RSVP_CTYPE_3, "IPv4 plus opt. TLVs" }, 285 { 256*RSVP_OBJ_ERROR_SPEC+RSVP_CTYPE_4, "IPv6 plus opt. TLVs" }, 286 { 256*RSVP_OBJ_RESTART_CAPABILITY+RSVP_CTYPE_1, "IPv4" }, 287 { 256*RSVP_OBJ_SESSION_ATTRIBUTE+RSVP_CTYPE_TUNNEL_IPV4, "Tunnel IPv4" }, 288 { 256*RSVP_OBJ_FASTREROUTE+RSVP_CTYPE_TUNNEL_IPV4, "Tunnel IPv4" }, /* old style*/ 289 { 256*RSVP_OBJ_FASTREROUTE+RSVP_CTYPE_1, "1" }, /* new style */ 290 { 256*RSVP_OBJ_DETOUR+RSVP_CTYPE_TUNNEL_IPV4, "Tunnel IPv4" }, 291 { 256*RSVP_OBJ_PROPERTIES+RSVP_CTYPE_1, "1" }, 292 { 256*RSVP_OBJ_ADMIN_STATUS+RSVP_CTYPE_1, "1" }, 293 { 256*RSVP_OBJ_CLASSTYPE+RSVP_CTYPE_1, "1" }, 294 { 256*RSVP_OBJ_CLASSTYPE_OLD+RSVP_CTYPE_1, "1" }, 295 { 256*RSVP_OBJ_LABEL_SET+RSVP_CTYPE_1, "1" }, 296 { 256*RSVP_OBJ_GENERALIZED_UNI+RSVP_CTYPE_1, "1" }, 297 { 256*RSVP_OBJ_S2L+RSVP_CTYPE_IPV4, "IPv4 sub-LSP" }, 298 { 256*RSVP_OBJ_S2L+RSVP_CTYPE_IPV6, "IPv6 sub-LSP" }, 299 { 0, NULL} 300 }; 301 302 struct rsvp_obj_integrity_t { 303 uint8_t flags; 304 uint8_t res; 305 uint8_t key_id[6]; 306 uint8_t sequence[8]; 307 uint8_t digest[16]; 308 }; 309 310 static const struct tok rsvp_obj_integrity_flag_values[] = { 311 { 0x80, "Handshake" }, 312 { 0, NULL} 313 }; 314 315 struct rsvp_obj_frr_t { 316 uint8_t setup_prio; 317 uint8_t hold_prio; 318 uint8_t hop_limit; 319 uint8_t flags; 320 uint8_t bandwidth[4]; 321 uint8_t include_any[4]; 322 uint8_t exclude_any[4]; 323 uint8_t include_all[4]; 324 }; 325 326 327 #define RSVP_OBJ_XRO_MASK_SUBOBJ(x) ((x)&0x7f) 328 #define RSVP_OBJ_XRO_MASK_LOOSE(x) ((x)&0x80) 329 330 #define RSVP_OBJ_XRO_RES 0 331 #define RSVP_OBJ_XRO_IPV4 1 332 #define RSVP_OBJ_XRO_IPV6 2 333 #define RSVP_OBJ_XRO_LABEL 3 334 #define RSVP_OBJ_XRO_ASN 32 335 #define RSVP_OBJ_XRO_MPLS 64 336 337 static const struct tok rsvp_obj_xro_values[] = { 338 { RSVP_OBJ_XRO_RES, "Reserved" }, 339 { RSVP_OBJ_XRO_IPV4, "IPv4 prefix" }, 340 { RSVP_OBJ_XRO_IPV6, "IPv6 prefix" }, 341 { RSVP_OBJ_XRO_LABEL, "Label" }, 342 { RSVP_OBJ_XRO_ASN, "Autonomous system number" }, 343 { RSVP_OBJ_XRO_MPLS, "MPLS label switched path termination" }, 344 { 0, NULL} 345 }; 346 347 /* draft-ietf-mpls-rsvp-lsp-fastreroute-07.txt */ 348 static const struct tok rsvp_obj_rro_flag_values[] = { 349 { 0x01, "Local protection available" }, 350 { 0x02, "Local protection in use" }, 351 { 0x04, "Bandwidth protection" }, 352 { 0x08, "Node protection" }, 353 { 0, NULL} 354 }; 355 356 /* RFC3209 */ 357 static const struct tok rsvp_obj_rro_label_flag_values[] = { 358 { 0x01, "Global" }, 359 { 0, NULL} 360 }; 361 362 static const struct tok rsvp_resstyle_values[] = { 363 { 17, "Wildcard Filter" }, 364 { 10, "Fixed Filter" }, 365 { 18, "Shared Explicit" }, 366 { 0, NULL} 367 }; 368 369 #define RSVP_OBJ_INTSERV_GUARANTEED_SERV 2 370 #define RSVP_OBJ_INTSERV_CONTROLLED_LOAD 5 371 372 static const struct tok rsvp_intserv_service_type_values[] = { 373 { 1, "Default/Global Information" }, 374 { RSVP_OBJ_INTSERV_GUARANTEED_SERV, "Guaranteed Service" }, 375 { RSVP_OBJ_INTSERV_CONTROLLED_LOAD, "Controlled Load" }, 376 { 0, NULL} 377 }; 378 379 static const struct tok rsvp_intserv_parameter_id_values[] = { 380 { 4, "IS hop cnt" }, 381 { 6, "Path b/w estimate" }, 382 { 8, "Minimum path latency" }, 383 { 10, "Composed MTU" }, 384 { 127, "Token Bucket TSpec" }, 385 { 130, "Guaranteed Service RSpec" }, 386 { 133, "End-to-end composed value for C" }, 387 { 134, "End-to-end composed value for D" }, 388 { 135, "Since-last-reshaping point composed C" }, 389 { 136, "Since-last-reshaping point composed D" }, 390 { 0, NULL} 391 }; 392 393 static const struct tok rsvp_session_attribute_flag_values[] = { 394 { 0x01, "Local Protection" }, 395 { 0x02, "Label Recording" }, 396 { 0x04, "SE Style" }, 397 { 0x08, "Bandwidth protection" }, /* RFC4090 */ 398 { 0x10, "Node protection" }, /* RFC4090 */ 399 { 0, NULL} 400 }; 401 402 static const struct tok rsvp_obj_prop_tlv_values[] = { 403 { 0x01, "Cos" }, 404 { 0x02, "Metric 1" }, 405 { 0x04, "Metric 2" }, 406 { 0x08, "CCC Status" }, 407 { 0x10, "Path Type" }, 408 { 0, NULL} 409 }; 410 411 #define RSVP_OBJ_ERROR_SPEC_CODE_ROUTING 24 412 #define RSVP_OBJ_ERROR_SPEC_CODE_NOTIFY 25 413 #define RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE 28 414 #define RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE_OLD 125 415 416 static const struct tok rsvp_obj_error_code_values[] = { 417 { RSVP_OBJ_ERROR_SPEC_CODE_ROUTING, "Routing Problem" }, 418 { RSVP_OBJ_ERROR_SPEC_CODE_NOTIFY, "Notify Error" }, 419 { RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE, "Diffserv TE Error" }, 420 { RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE_OLD, "Diffserv TE Error (Old)" }, 421 { 0, NULL} 422 }; 423 424 static const struct tok rsvp_obj_error_code_routing_values[] = { 425 { 1, "Bad EXPLICIT_ROUTE object" }, 426 { 2, "Bad strict node" }, 427 { 3, "Bad loose node" }, 428 { 4, "Bad initial subobject" }, 429 { 5, "No route available toward destination" }, 430 { 6, "Unacceptable label value" }, 431 { 7, "RRO indicated routing loops" }, 432 { 8, "non-RSVP-capable router in the path" }, 433 { 9, "MPLS label allocation failure" }, 434 { 10, "Unsupported L3PID" }, 435 { 0, NULL} 436 }; 437 438 static const struct tok rsvp_obj_error_code_diffserv_te_values[] = { 439 { 1, "Unexpected CT object" }, 440 { 2, "Unsupported CT" }, 441 { 3, "Invalid CT value" }, 442 { 4, "CT/setup priority do not form a configured TE-Class" }, 443 { 5, "CT/holding priority do not form a configured TE-Class" }, 444 { 6, "CT/setup priority and CT/holding priority do not form a configured TE-Class" }, 445 { 7, "Inconsistency between signaled PSC and signaled CT" }, 446 { 8, "Inconsistency between signaled PHBs and signaled CT" }, 447 { 0, NULL} 448 }; 449 450 /* rfc3473 / rfc 3471 */ 451 static const struct tok rsvp_obj_admin_status_flag_values[] = { 452 { 0x80000000, "Reflect" }, 453 { 0x00000004, "Testing" }, 454 { 0x00000002, "Admin-down" }, 455 { 0x00000001, "Delete-in-progress" }, 456 { 0, NULL} 457 }; 458 459 /* label set actions - rfc3471 */ 460 #define LABEL_SET_INCLUSIVE_LIST 0 461 #define LABEL_SET_EXCLUSIVE_LIST 1 462 #define LABEL_SET_INCLUSIVE_RANGE 2 463 #define LABEL_SET_EXCLUSIVE_RANGE 3 464 465 static const struct tok rsvp_obj_label_set_action_values[] = { 466 { LABEL_SET_INCLUSIVE_LIST, "Inclusive list" }, 467 { LABEL_SET_EXCLUSIVE_LIST, "Exclusive list" }, 468 { LABEL_SET_INCLUSIVE_RANGE, "Inclusive range" }, 469 { LABEL_SET_EXCLUSIVE_RANGE, "Exclusive range" }, 470 { 0, NULL} 471 }; 472 473 /* OIF RSVP extensions UNI 1.0 Signaling, release 2 */ 474 #define RSVP_GEN_UNI_SUBOBJ_SOURCE_TNA_ADDRESS 1 475 #define RSVP_GEN_UNI_SUBOBJ_DESTINATION_TNA_ADDRESS 2 476 #define RSVP_GEN_UNI_SUBOBJ_DIVERSITY 3 477 #define RSVP_GEN_UNI_SUBOBJ_EGRESS_LABEL 4 478 #define RSVP_GEN_UNI_SUBOBJ_SERVICE_LEVEL 5 479 480 static const struct tok rsvp_obj_generalized_uni_values[] = { 481 { RSVP_GEN_UNI_SUBOBJ_SOURCE_TNA_ADDRESS, "Source TNA address" }, 482 { RSVP_GEN_UNI_SUBOBJ_DESTINATION_TNA_ADDRESS, "Destination TNA address" }, 483 { RSVP_GEN_UNI_SUBOBJ_DIVERSITY, "Diversity" }, 484 { RSVP_GEN_UNI_SUBOBJ_EGRESS_LABEL, "Egress label" }, 485 { RSVP_GEN_UNI_SUBOBJ_SERVICE_LEVEL, "Service level" }, 486 { 0, NULL} 487 }; 488 489 /* 490 * this is a dissector for all the intserv defined 491 * specs as defined per rfc2215 492 * it is called from various rsvp objects; 493 * returns the amount of bytes being processed 494 */ 495 static int 496 rsvp_intserv_print(netdissect_options *ndo, 497 const u_char *tptr, u_short obj_tlen) 498 { 499 int parameter_id,parameter_length; 500 union { 501 float f; 502 uint32_t i; 503 } bw; 504 505 if (obj_tlen < 4) 506 return 0; 507 ND_TCHECK_8BITS(tptr); 508 parameter_id = *(tptr); 509 ND_TCHECK2(*(tptr + 2), 2); 510 parameter_length = EXTRACT_16BITS(tptr+2)<<2; /* convert wordcount to bytecount */ 511 512 ND_PRINT((ndo, "\n\t Parameter ID: %s (%u), length: %u, Flags: [0x%02x]", 513 tok2str(rsvp_intserv_parameter_id_values,"unknown",parameter_id), 514 parameter_id, 515 parameter_length, 516 *(tptr + 1))); 517 518 if (obj_tlen < parameter_length+4) 519 return 0; 520 switch(parameter_id) { /* parameter_id */ 521 522 case 4: 523 /* 524 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 525 * | 4 (e) | (f) | 1 (g) | 526 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 527 * | IS hop cnt (32-bit unsigned integer) | 528 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 529 */ 530 if (parameter_length == 4) { 531 ND_TCHECK2(*(tptr + 4), 4); 532 ND_PRINT((ndo, "\n\t\tIS hop count: %u", EXTRACT_32BITS(tptr + 4))); 533 } 534 break; 535 536 case 6: 537 /* 538 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 539 * | 6 (h) | (i) | 1 (j) | 540 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 541 * | Path b/w estimate (32-bit IEEE floating point number) | 542 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 543 */ 544 if (parameter_length == 4) { 545 ND_TCHECK2(*(tptr + 4), 4); 546 bw.i = EXTRACT_32BITS(tptr+4); 547 ND_PRINT((ndo, "\n\t\tPath b/w estimate: %.10g Mbps", bw.f / 125000)); 548 } 549 break; 550 551 case 8: 552 /* 553 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 554 * | 8 (k) | (l) | 1 (m) | 555 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 556 * | Minimum path latency (32-bit integer) | 557 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 558 */ 559 if (parameter_length == 4) { 560 ND_TCHECK2(*(tptr + 4), 4); 561 ND_PRINT((ndo, "\n\t\tMinimum path latency: ")); 562 if (EXTRACT_32BITS(tptr+4) == 0xffffffff) 563 ND_PRINT((ndo, "don't care")); 564 else 565 ND_PRINT((ndo, "%u", EXTRACT_32BITS(tptr + 4))); 566 } 567 break; 568 569 case 10: 570 571 /* 572 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 573 * | 10 (n) | (o) | 1 (p) | 574 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 575 * | Composed MTU (32-bit unsigned integer) | 576 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 577 */ 578 if (parameter_length == 4) { 579 ND_TCHECK2(*(tptr + 4), 4); 580 ND_PRINT((ndo, "\n\t\tComposed MTU: %u bytes", EXTRACT_32BITS(tptr + 4))); 581 } 582 break; 583 case 127: 584 /* 585 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 586 * | 127 (e) | 0 (f) | 5 (g) | 587 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 588 * | Token Bucket Rate [r] (32-bit IEEE floating point number) | 589 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 590 * | Token Bucket Size [b] (32-bit IEEE floating point number) | 591 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 592 * | Peak Data Rate [p] (32-bit IEEE floating point number) | 593 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 594 * | Minimum Policed Unit [m] (32-bit integer) | 595 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 596 * | Maximum Packet Size [M] (32-bit integer) | 597 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 598 */ 599 600 if (parameter_length == 20) { 601 ND_TCHECK2(*(tptr + 4), 20); 602 bw.i = EXTRACT_32BITS(tptr+4); 603 ND_PRINT((ndo, "\n\t\tToken Bucket Rate: %.10g Mbps", bw.f / 125000)); 604 bw.i = EXTRACT_32BITS(tptr+8); 605 ND_PRINT((ndo, "\n\t\tToken Bucket Size: %.10g bytes", bw.f)); 606 bw.i = EXTRACT_32BITS(tptr+12); 607 ND_PRINT((ndo, "\n\t\tPeak Data Rate: %.10g Mbps", bw.f / 125000)); 608 ND_PRINT((ndo, "\n\t\tMinimum Policed Unit: %u bytes", EXTRACT_32BITS(tptr + 16))); 609 ND_PRINT((ndo, "\n\t\tMaximum Packet Size: %u bytes", EXTRACT_32BITS(tptr + 20))); 610 } 611 break; 612 613 case 130: 614 /* 615 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 616 * | 130 (h) | 0 (i) | 2 (j) | 617 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 618 * | Rate [R] (32-bit IEEE floating point number) | 619 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 620 * | Slack Term [S] (32-bit integer) | 621 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 622 */ 623 624 if (parameter_length == 8) { 625 ND_TCHECK2(*(tptr + 4), 8); 626 bw.i = EXTRACT_32BITS(tptr+4); 627 ND_PRINT((ndo, "\n\t\tRate: %.10g Mbps", bw.f / 125000)); 628 ND_PRINT((ndo, "\n\t\tSlack Term: %u", EXTRACT_32BITS(tptr + 8))); 629 } 630 break; 631 632 case 133: 633 case 134: 634 case 135: 635 case 136: 636 if (parameter_length == 4) { 637 ND_TCHECK2(*(tptr + 4), 4); 638 ND_PRINT((ndo, "\n\t\tValue: %u", EXTRACT_32BITS(tptr + 4))); 639 } 640 break; 641 642 default: 643 if (ndo->ndo_vflag <= 1) 644 print_unknown_data(ndo, tptr + 4, "\n\t\t", parameter_length); 645 } 646 return (parameter_length+4); /* header length 4 bytes */ 647 648 trunc: 649 ND_PRINT((ndo, "%s", tstr)); 650 return 0; 651 } 652 653 /* 654 * Clear checksum prior to signature verification. 655 */ 656 static void 657 rsvp_clear_checksum(void *header) 658 { 659 struct rsvp_common_header *rsvp_com_header = (struct rsvp_common_header *) header; 660 661 rsvp_com_header->checksum[0] = 0; 662 rsvp_com_header->checksum[1] = 0; 663 } 664 665 static int 666 rsvp_obj_print(netdissect_options *ndo, 667 const u_char *pptr, u_int plen, const u_char *tptr, 668 const char *ident, u_int tlen, 669 const struct rsvp_common_header *rsvp_com_header) 670 { 671 const struct rsvp_object_header *rsvp_obj_header; 672 const u_char *obj_tptr; 673 union { 674 const struct rsvp_obj_integrity_t *rsvp_obj_integrity; 675 const struct rsvp_obj_frr_t *rsvp_obj_frr; 676 } obj_ptr; 677 678 u_short rsvp_obj_len,rsvp_obj_ctype,obj_tlen,intserv_serv_tlen; 679 int hexdump,processed,padbytes,error_code,error_value,i,sigcheck; 680 union { 681 float f; 682 uint32_t i; 683 } bw; 684 uint8_t namelen; 685 686 u_int action, subchannel; 687 688 while(tlen>=sizeof(struct rsvp_object_header)) { 689 /* did we capture enough for fully decoding the object header ? */ 690 ND_TCHECK2(*tptr, sizeof(struct rsvp_object_header)); 691 692 rsvp_obj_header = (const struct rsvp_object_header *)tptr; 693 rsvp_obj_len=EXTRACT_16BITS(rsvp_obj_header->length); 694 rsvp_obj_ctype=rsvp_obj_header->ctype; 695 696 if(rsvp_obj_len % 4) { 697 ND_PRINT((ndo, "%sERROR: object header size %u not a multiple of 4", ident, rsvp_obj_len)); 698 return -1; 699 } 700 if(rsvp_obj_len < sizeof(struct rsvp_object_header)) { 701 ND_PRINT((ndo, "%sERROR: object header too short %u < %lu", ident, rsvp_obj_len, 702 (unsigned long)sizeof(const struct rsvp_object_header))); 703 return -1; 704 } 705 706 ND_PRINT((ndo, "%s%s Object (%u) Flags: [%s", 707 ident, 708 tok2str(rsvp_obj_values, 709 "Unknown", 710 rsvp_obj_header->class_num), 711 rsvp_obj_header->class_num, 712 ((rsvp_obj_header->class_num) & 0x80) ? "ignore" : "reject")); 713 714 if (rsvp_obj_header->class_num > 128) 715 ND_PRINT((ndo, " %s", 716 ((rsvp_obj_header->class_num) & 0x40) ? "and forward" : "silently")); 717 718 ND_PRINT((ndo, " if unknown], Class-Type: %s (%u), length: %u", 719 tok2str(rsvp_ctype_values, 720 "Unknown", 721 ((rsvp_obj_header->class_num)<<8)+rsvp_obj_ctype), 722 rsvp_obj_ctype, 723 rsvp_obj_len)); 724 725 if(tlen < rsvp_obj_len) { 726 ND_PRINT((ndo, "%sERROR: object goes past end of objects TLV", ident)); 727 return -1; 728 } 729 730 obj_tptr=tptr+sizeof(struct rsvp_object_header); 731 obj_tlen=rsvp_obj_len-sizeof(struct rsvp_object_header); 732 733 /* did we capture enough for fully decoding the object ? */ 734 if (!ND_TTEST2(*tptr, rsvp_obj_len)) 735 return -1; 736 hexdump=FALSE; 737 738 switch(rsvp_obj_header->class_num) { 739 case RSVP_OBJ_SESSION: 740 switch(rsvp_obj_ctype) { 741 case RSVP_CTYPE_IPV4: 742 if (obj_tlen < 8) 743 return -1; 744 ND_PRINT((ndo, "%s IPv4 DestAddress: %s, Protocol ID: 0x%02x", 745 ident, 746 ipaddr_string(ndo, obj_tptr), 747 *(obj_tptr + sizeof(struct in_addr)))); 748 ND_PRINT((ndo, "%s Flags: [0x%02x], DestPort %u", 749 ident, 750 *(obj_tptr+5), 751 EXTRACT_16BITS(obj_tptr + 6))); 752 obj_tlen-=8; 753 obj_tptr+=8; 754 break; 755 case RSVP_CTYPE_IPV6: 756 if (obj_tlen < 20) 757 return -1; 758 ND_PRINT((ndo, "%s IPv6 DestAddress: %s, Protocol ID: 0x%02x", 759 ident, 760 ip6addr_string(ndo, obj_tptr), 761 *(obj_tptr + sizeof(struct in6_addr)))); 762 ND_PRINT((ndo, "%s Flags: [0x%02x], DestPort %u", 763 ident, 764 *(obj_tptr+sizeof(struct in6_addr)+1), 765 EXTRACT_16BITS(obj_tptr + sizeof(struct in6_addr) + 2))); 766 obj_tlen-=20; 767 obj_tptr+=20; 768 break; 769 770 case RSVP_CTYPE_TUNNEL_IPV6: 771 if (obj_tlen < 36) 772 return -1; 773 ND_PRINT((ndo, "%s IPv6 Tunnel EndPoint: %s, Tunnel ID: 0x%04x, Extended Tunnel ID: %s", 774 ident, 775 ip6addr_string(ndo, obj_tptr), 776 EXTRACT_16BITS(obj_tptr+18), 777 ip6addr_string(ndo, obj_tptr + 20))); 778 obj_tlen-=36; 779 obj_tptr+=36; 780 break; 781 782 case RSVP_CTYPE_14: /* IPv6 p2mp LSP Tunnel */ 783 if (obj_tlen < 26) 784 return -1; 785 ND_PRINT((ndo, "%s IPv6 P2MP LSP ID: 0x%08x, Tunnel ID: 0x%04x, Extended Tunnel ID: %s", 786 ident, 787 EXTRACT_32BITS(obj_tptr), 788 EXTRACT_16BITS(obj_tptr+6), 789 ip6addr_string(ndo, obj_tptr + 8))); 790 obj_tlen-=26; 791 obj_tptr+=26; 792 break; 793 case RSVP_CTYPE_13: /* IPv4 p2mp LSP Tunnel */ 794 if (obj_tlen < 12) 795 return -1; 796 ND_PRINT((ndo, "%s IPv4 P2MP LSP ID: %s, Tunnel ID: 0x%04x, Extended Tunnel ID: %s", 797 ident, 798 ipaddr_string(ndo, obj_tptr), 799 EXTRACT_16BITS(obj_tptr+6), 800 ipaddr_string(ndo, obj_tptr + 8))); 801 obj_tlen-=12; 802 obj_tptr+=12; 803 break; 804 case RSVP_CTYPE_TUNNEL_IPV4: 805 case RSVP_CTYPE_UNI_IPV4: 806 if (obj_tlen < 12) 807 return -1; 808 ND_PRINT((ndo, "%s IPv4 Tunnel EndPoint: %s, Tunnel ID: 0x%04x, Extended Tunnel ID: %s", 809 ident, 810 ipaddr_string(ndo, obj_tptr), 811 EXTRACT_16BITS(obj_tptr+6), 812 ipaddr_string(ndo, obj_tptr + 8))); 813 obj_tlen-=12; 814 obj_tptr+=12; 815 break; 816 default: 817 hexdump=TRUE; 818 } 819 break; 820 821 case RSVP_OBJ_CONFIRM: 822 switch(rsvp_obj_ctype) { 823 case RSVP_CTYPE_IPV4: 824 if (obj_tlen < sizeof(struct in_addr)) 825 return -1; 826 ND_PRINT((ndo, "%s IPv4 Receiver Address: %s", 827 ident, 828 ipaddr_string(ndo, obj_tptr))); 829 obj_tlen-=sizeof(struct in_addr); 830 obj_tptr+=sizeof(struct in_addr); 831 break; 832 case RSVP_CTYPE_IPV6: 833 if (obj_tlen < sizeof(struct in6_addr)) 834 return -1; 835 ND_PRINT((ndo, "%s IPv6 Receiver Address: %s", 836 ident, 837 ip6addr_string(ndo, obj_tptr))); 838 obj_tlen-=sizeof(struct in6_addr); 839 obj_tptr+=sizeof(struct in6_addr); 840 break; 841 default: 842 hexdump=TRUE; 843 } 844 break; 845 846 case RSVP_OBJ_NOTIFY_REQ: 847 switch(rsvp_obj_ctype) { 848 case RSVP_CTYPE_IPV4: 849 if (obj_tlen < sizeof(struct in_addr)) 850 return -1; 851 ND_PRINT((ndo, "%s IPv4 Notify Node Address: %s", 852 ident, 853 ipaddr_string(ndo, obj_tptr))); 854 obj_tlen-=sizeof(struct in_addr); 855 obj_tptr+=sizeof(struct in_addr); 856 break; 857 case RSVP_CTYPE_IPV6: 858 if (obj_tlen < sizeof(struct in6_addr)) 859 return-1; 860 ND_PRINT((ndo, "%s IPv6 Notify Node Address: %s", 861 ident, 862 ip6addr_string(ndo, obj_tptr))); 863 obj_tlen-=sizeof(struct in6_addr); 864 obj_tptr+=sizeof(struct in6_addr); 865 break; 866 default: 867 hexdump=TRUE; 868 } 869 break; 870 871 case RSVP_OBJ_SUGGESTED_LABEL: /* fall through */ 872 case RSVP_OBJ_UPSTREAM_LABEL: /* fall through */ 873 case RSVP_OBJ_RECOVERY_LABEL: /* fall through */ 874 case RSVP_OBJ_LABEL: 875 switch(rsvp_obj_ctype) { 876 case RSVP_CTYPE_1: 877 while(obj_tlen >= 4 ) { 878 ND_PRINT((ndo, "%s Label: %u", ident, EXTRACT_32BITS(obj_tptr))); 879 obj_tlen-=4; 880 obj_tptr+=4; 881 } 882 break; 883 case RSVP_CTYPE_2: 884 if (obj_tlen < 4) 885 return-1; 886 ND_PRINT((ndo, "%s Generalized Label: %u", 887 ident, 888 EXTRACT_32BITS(obj_tptr))); 889 obj_tlen-=4; 890 obj_tptr+=4; 891 break; 892 case RSVP_CTYPE_3: 893 if (obj_tlen < 12) 894 return-1; 895 ND_PRINT((ndo, "%s Waveband ID: %u%s Start Label: %u, Stop Label: %u", 896 ident, 897 EXTRACT_32BITS(obj_tptr), 898 ident, 899 EXTRACT_32BITS(obj_tptr+4), 900 EXTRACT_32BITS(obj_tptr + 8))); 901 obj_tlen-=12; 902 obj_tptr+=12; 903 break; 904 default: 905 hexdump=TRUE; 906 } 907 break; 908 909 case RSVP_OBJ_STYLE: 910 switch(rsvp_obj_ctype) { 911 case RSVP_CTYPE_1: 912 if (obj_tlen < 4) 913 return-1; 914 ND_PRINT((ndo, "%s Reservation Style: %s, Flags: [0x%02x]", 915 ident, 916 tok2str(rsvp_resstyle_values, 917 "Unknown", 918 EXTRACT_24BITS(obj_tptr+1)), 919 *(obj_tptr))); 920 obj_tlen-=4; 921 obj_tptr+=4; 922 break; 923 default: 924 hexdump=TRUE; 925 } 926 break; 927 928 case RSVP_OBJ_SENDER_TEMPLATE: 929 switch(rsvp_obj_ctype) { 930 case RSVP_CTYPE_IPV4: 931 if (obj_tlen < 8) 932 return-1; 933 ND_PRINT((ndo, "%s Source Address: %s, Source Port: %u", 934 ident, 935 ipaddr_string(ndo, obj_tptr), 936 EXTRACT_16BITS(obj_tptr + 6))); 937 obj_tlen-=8; 938 obj_tptr+=8; 939 break; 940 case RSVP_CTYPE_IPV6: 941 if (obj_tlen < 20) 942 return-1; 943 ND_PRINT((ndo, "%s Source Address: %s, Source Port: %u", 944 ident, 945 ip6addr_string(ndo, obj_tptr), 946 EXTRACT_16BITS(obj_tptr + 18))); 947 obj_tlen-=20; 948 obj_tptr+=20; 949 break; 950 case RSVP_CTYPE_13: /* IPv6 p2mp LSP tunnel */ 951 if (obj_tlen < 40) 952 return-1; 953 ND_PRINT((ndo, "%s IPv6 Tunnel Sender Address: %s, LSP ID: 0x%04x" 954 "%s Sub-Group Originator ID: %s, Sub-Group ID: 0x%04x", 955 ident, 956 ip6addr_string(ndo, obj_tptr), 957 EXTRACT_16BITS(obj_tptr+18), 958 ident, 959 ip6addr_string(ndo, obj_tptr+20), 960 EXTRACT_16BITS(obj_tptr + 38))); 961 obj_tlen-=40; 962 obj_tptr+=40; 963 break; 964 case RSVP_CTYPE_TUNNEL_IPV4: 965 if (obj_tlen < 8) 966 return-1; 967 ND_PRINT((ndo, "%s IPv4 Tunnel Sender Address: %s, LSP-ID: 0x%04x", 968 ident, 969 ipaddr_string(ndo, obj_tptr), 970 EXTRACT_16BITS(obj_tptr + 6))); 971 obj_tlen-=8; 972 obj_tptr+=8; 973 break; 974 case RSVP_CTYPE_12: /* IPv4 p2mp LSP tunnel */ 975 if (obj_tlen < 16) 976 return-1; 977 ND_PRINT((ndo, "%s IPv4 Tunnel Sender Address: %s, LSP ID: 0x%04x" 978 "%s Sub-Group Originator ID: %s, Sub-Group ID: 0x%04x", 979 ident, 980 ipaddr_string(ndo, obj_tptr), 981 EXTRACT_16BITS(obj_tptr+6), 982 ident, 983 ipaddr_string(ndo, obj_tptr+8), 984 EXTRACT_16BITS(obj_tptr + 12))); 985 obj_tlen-=16; 986 obj_tptr+=16; 987 break; 988 default: 989 hexdump=TRUE; 990 } 991 break; 992 993 case RSVP_OBJ_LABEL_REQ: 994 switch(rsvp_obj_ctype) { 995 case RSVP_CTYPE_1: 996 while(obj_tlen >= 4 ) { 997 ND_PRINT((ndo, "%s L3 Protocol ID: %s", 998 ident, 999 tok2str(ethertype_values, 1000 "Unknown Protocol (0x%04x)", 1001 EXTRACT_16BITS(obj_tptr + 2)))); 1002 obj_tlen-=4; 1003 obj_tptr+=4; 1004 } 1005 break; 1006 case RSVP_CTYPE_2: 1007 if (obj_tlen < 12) 1008 return-1; 1009 ND_PRINT((ndo, "%s L3 Protocol ID: %s", 1010 ident, 1011 tok2str(ethertype_values, 1012 "Unknown Protocol (0x%04x)", 1013 EXTRACT_16BITS(obj_tptr + 2)))); 1014 ND_PRINT((ndo, ",%s merge capability",((*(obj_tptr + 4)) & 0x80) ? "no" : "" )); 1015 ND_PRINT((ndo, "%s Minimum VPI/VCI: %u/%u", 1016 ident, 1017 (EXTRACT_16BITS(obj_tptr+4))&0xfff, 1018 (EXTRACT_16BITS(obj_tptr + 6)) & 0xfff)); 1019 ND_PRINT((ndo, "%s Maximum VPI/VCI: %u/%u", 1020 ident, 1021 (EXTRACT_16BITS(obj_tptr+8))&0xfff, 1022 (EXTRACT_16BITS(obj_tptr + 10)) & 0xfff)); 1023 obj_tlen-=12; 1024 obj_tptr+=12; 1025 break; 1026 case RSVP_CTYPE_3: 1027 if (obj_tlen < 12) 1028 return-1; 1029 ND_PRINT((ndo, "%s L3 Protocol ID: %s", 1030 ident, 1031 tok2str(ethertype_values, 1032 "Unknown Protocol (0x%04x)", 1033 EXTRACT_16BITS(obj_tptr + 2)))); 1034 ND_PRINT((ndo, "%s Minimum/Maximum DLCI: %u/%u, %s%s bit DLCI", 1035 ident, 1036 (EXTRACT_32BITS(obj_tptr+4))&0x7fffff, 1037 (EXTRACT_32BITS(obj_tptr+8))&0x7fffff, 1038 (((EXTRACT_16BITS(obj_tptr+4)>>7)&3) == 0 ) ? "10" : "", 1039 (((EXTRACT_16BITS(obj_tptr + 4) >> 7) & 3) == 2 ) ? "23" : "")); 1040 obj_tlen-=12; 1041 obj_tptr+=12; 1042 break; 1043 case RSVP_CTYPE_4: 1044 if (obj_tlen < 4) 1045 return-1; 1046 ND_PRINT((ndo, "%s LSP Encoding Type: %s (%u)", 1047 ident, 1048 tok2str(gmpls_encoding_values, 1049 "Unknown", 1050 *obj_tptr), 1051 *obj_tptr)); 1052 ND_PRINT((ndo, "%s Switching Type: %s (%u), Payload ID: %s (0x%04x)", 1053 ident, 1054 tok2str(gmpls_switch_cap_values, 1055 "Unknown", 1056 *(obj_tptr+1)), 1057 *(obj_tptr+1), 1058 tok2str(gmpls_payload_values, 1059 "Unknown", 1060 EXTRACT_16BITS(obj_tptr+2)), 1061 EXTRACT_16BITS(obj_tptr + 2))); 1062 obj_tlen-=4; 1063 obj_tptr+=4; 1064 break; 1065 default: 1066 hexdump=TRUE; 1067 } 1068 break; 1069 1070 case RSVP_OBJ_RRO: 1071 case RSVP_OBJ_ERO: 1072 switch(rsvp_obj_ctype) { 1073 case RSVP_CTYPE_IPV4: 1074 while(obj_tlen >= 4 ) { 1075 u_char length; 1076 1077 ND_TCHECK2(*obj_tptr, 4); 1078 length = *(obj_tptr + 1); 1079 ND_PRINT((ndo, "%s Subobject Type: %s, length %u", 1080 ident, 1081 tok2str(rsvp_obj_xro_values, 1082 "Unknown %u", 1083 RSVP_OBJ_XRO_MASK_SUBOBJ(*obj_tptr)), 1084 length)); 1085 1086 if (length == 0) { /* prevent infinite loops */ 1087 ND_PRINT((ndo, "%s ERROR: zero length ERO subtype", ident)); 1088 break; 1089 } 1090 1091 switch(RSVP_OBJ_XRO_MASK_SUBOBJ(*obj_tptr)) { 1092 u_char prefix_length; 1093 1094 case RSVP_OBJ_XRO_IPV4: 1095 if (length != 8) { 1096 ND_PRINT((ndo, " ERROR: length != 8")); 1097 goto invalid; 1098 } 1099 ND_TCHECK2(*obj_tptr, 8); 1100 prefix_length = *(obj_tptr+6); 1101 if (prefix_length != 32) { 1102 ND_PRINT((ndo, " ERROR: Prefix length %u != 32", 1103 prefix_length)); 1104 goto invalid; 1105 } 1106 ND_PRINT((ndo, ", %s, %s/%u, Flags: [%s]", 1107 RSVP_OBJ_XRO_MASK_LOOSE(*obj_tptr) ? "Loose" : "Strict", 1108 ipaddr_string(ndo, obj_tptr+2), 1109 *(obj_tptr+6), 1110 bittok2str(rsvp_obj_rro_flag_values, 1111 "none", 1112 *(obj_tptr + 7)))); /* rfc3209 says that this field is rsvd. */ 1113 break; 1114 case RSVP_OBJ_XRO_LABEL: 1115 if (length != 8) { 1116 ND_PRINT((ndo, " ERROR: length != 8")); 1117 goto invalid; 1118 } 1119 ND_TCHECK2(*obj_tptr, 8); 1120 ND_PRINT((ndo, ", Flags: [%s] (%#x), Class-Type: %s (%u), %u", 1121 bittok2str(rsvp_obj_rro_label_flag_values, 1122 "none", 1123 *(obj_tptr+2)), 1124 *(obj_tptr+2), 1125 tok2str(rsvp_ctype_values, 1126 "Unknown", 1127 *(obj_tptr+3) + 256*RSVP_OBJ_RRO), 1128 *(obj_tptr+3), 1129 EXTRACT_32BITS(obj_tptr + 4))); 1130 } 1131 obj_tlen-=*(obj_tptr+1); 1132 obj_tptr+=*(obj_tptr+1); 1133 } 1134 break; 1135 default: 1136 hexdump=TRUE; 1137 } 1138 break; 1139 1140 case RSVP_OBJ_HELLO: 1141 switch(rsvp_obj_ctype) { 1142 case RSVP_CTYPE_1: 1143 case RSVP_CTYPE_2: 1144 if (obj_tlen < 8) 1145 return-1; 1146 ND_PRINT((ndo, "%s Source Instance: 0x%08x, Destination Instance: 0x%08x", 1147 ident, 1148 EXTRACT_32BITS(obj_tptr), 1149 EXTRACT_32BITS(obj_tptr + 4))); 1150 obj_tlen-=8; 1151 obj_tptr+=8; 1152 break; 1153 default: 1154 hexdump=TRUE; 1155 } 1156 break; 1157 1158 case RSVP_OBJ_RESTART_CAPABILITY: 1159 switch(rsvp_obj_ctype) { 1160 case RSVP_CTYPE_1: 1161 if (obj_tlen < 8) 1162 return-1; 1163 ND_PRINT((ndo, "%s Restart Time: %ums, Recovery Time: %ums", 1164 ident, 1165 EXTRACT_32BITS(obj_tptr), 1166 EXTRACT_32BITS(obj_tptr + 4))); 1167 obj_tlen-=8; 1168 obj_tptr+=8; 1169 break; 1170 default: 1171 hexdump=TRUE; 1172 } 1173 break; 1174 1175 case RSVP_OBJ_SESSION_ATTRIBUTE: 1176 switch(rsvp_obj_ctype) { 1177 case RSVP_CTYPE_TUNNEL_IPV4: 1178 if (obj_tlen < 4) 1179 return-1; 1180 namelen = *(obj_tptr+3); 1181 if (obj_tlen < 4+namelen) 1182 return-1; 1183 ND_PRINT((ndo, "%s Session Name: ", ident)); 1184 for (i = 0; i < namelen; i++) 1185 safeputchar(ndo, *(obj_tptr + 4 + i)); 1186 ND_PRINT((ndo, "%s Setup Priority: %u, Holding Priority: %u, Flags: [%s] (%#x)", 1187 ident, 1188 (int)*obj_tptr, 1189 (int)*(obj_tptr+1), 1190 bittok2str(rsvp_session_attribute_flag_values, 1191 "none", 1192 *(obj_tptr+2)), 1193 *(obj_tptr + 2))); 1194 obj_tlen-=4+*(obj_tptr+3); 1195 obj_tptr+=4+*(obj_tptr+3); 1196 break; 1197 default: 1198 hexdump=TRUE; 1199 } 1200 break; 1201 1202 case RSVP_OBJ_GENERALIZED_UNI: 1203 switch(rsvp_obj_ctype) { 1204 int subobj_type,af,subobj_len,total_subobj_len; 1205 1206 case RSVP_CTYPE_1: 1207 1208 if (obj_tlen < 4) 1209 return-1; 1210 1211 /* read variable length subobjects */ 1212 total_subobj_len = obj_tlen; 1213 while(total_subobj_len > 0) { 1214 /* If RFC 3476 Section 3.1 defined that a sub-object of the 1215 * GENERALIZED_UNI RSVP object must have the Length field as 1216 * a multiple of 4, instead of the check below it would be 1217 * better to test total_subobj_len only once before the loop. 1218 * So long as it does not define it and this while loop does 1219 * not implement such a requirement, let's accept that within 1220 * each iteration subobj_len may happen to be a multiple of 1 1221 * and test it and total_subobj_len respectively. 1222 */ 1223 if (total_subobj_len < 4) 1224 goto invalid; 1225 subobj_len = EXTRACT_16BITS(obj_tptr); 1226 subobj_type = (EXTRACT_16BITS(obj_tptr+2))>>8; 1227 af = (EXTRACT_16BITS(obj_tptr+2))&0x00FF; 1228 1229 ND_PRINT((ndo, "%s Subobject Type: %s (%u), AF: %s (%u), length: %u", 1230 ident, 1231 tok2str(rsvp_obj_generalized_uni_values, "Unknown", subobj_type), 1232 subobj_type, 1233 tok2str(af_values, "Unknown", af), af, 1234 subobj_len)); 1235 1236 /* In addition to what is explained above, the same spec does not 1237 * explicitly say that the same Length field includes the 4-octet 1238 * sub-object header, but as long as this while loop implements it 1239 * as it does include, let's keep the check below consistent with 1240 * the rest of the code. 1241 */ 1242 if(subobj_len < 4 || subobj_len > total_subobj_len) 1243 goto invalid; 1244 1245 switch(subobj_type) { 1246 case RSVP_GEN_UNI_SUBOBJ_SOURCE_TNA_ADDRESS: 1247 case RSVP_GEN_UNI_SUBOBJ_DESTINATION_TNA_ADDRESS: 1248 1249 switch(af) { 1250 case AFNUM_INET: 1251 if (subobj_len < 8) 1252 return -1; 1253 ND_PRINT((ndo, "%s UNI IPv4 TNA address: %s", 1254 ident, ipaddr_string(ndo, obj_tptr + 4))); 1255 break; 1256 case AFNUM_INET6: 1257 if (subobj_len < 20) 1258 return -1; 1259 ND_PRINT((ndo, "%s UNI IPv6 TNA address: %s", 1260 ident, ip6addr_string(ndo, obj_tptr + 4))); 1261 break; 1262 case AFNUM_NSAP: 1263 if (subobj_len) { 1264 /* unless we have a TLV parser lets just hexdump */ 1265 hexdump=TRUE; 1266 } 1267 break; 1268 } 1269 break; 1270 1271 case RSVP_GEN_UNI_SUBOBJ_DIVERSITY: 1272 if (subobj_len) { 1273 /* unless we have a TLV parser lets just hexdump */ 1274 hexdump=TRUE; 1275 } 1276 break; 1277 1278 case RSVP_GEN_UNI_SUBOBJ_EGRESS_LABEL: 1279 if (subobj_len < 16) { 1280 return -1; 1281 } 1282 1283 ND_PRINT((ndo, "%s U-bit: %x, Label type: %u, Logical port id: %u, Label: %u", 1284 ident, 1285 ((EXTRACT_32BITS(obj_tptr+4))>>31), 1286 ((EXTRACT_32BITS(obj_tptr+4))&0xFF), 1287 EXTRACT_32BITS(obj_tptr+8), 1288 EXTRACT_32BITS(obj_tptr + 12))); 1289 break; 1290 1291 case RSVP_GEN_UNI_SUBOBJ_SERVICE_LEVEL: 1292 if (subobj_len < 8) { 1293 return -1; 1294 } 1295 1296 ND_PRINT((ndo, "%s Service level: %u", 1297 ident, (EXTRACT_32BITS(obj_tptr + 4)) >> 24)); 1298 break; 1299 1300 default: 1301 hexdump=TRUE; 1302 break; 1303 } 1304 total_subobj_len-=subobj_len; 1305 obj_tptr+=subobj_len; 1306 obj_tlen+=subobj_len; 1307 } 1308 1309 if (total_subobj_len) { 1310 /* unless we have a TLV parser lets just hexdump */ 1311 hexdump=TRUE; 1312 } 1313 break; 1314 1315 default: 1316 hexdump=TRUE; 1317 } 1318 break; 1319 1320 case RSVP_OBJ_RSVP_HOP: 1321 switch(rsvp_obj_ctype) { 1322 case RSVP_CTYPE_3: /* fall through - FIXME add TLV parser */ 1323 case RSVP_CTYPE_IPV4: 1324 if (obj_tlen < 8) 1325 return-1; 1326 ND_PRINT((ndo, "%s Previous/Next Interface: %s, Logical Interface Handle: 0x%08x", 1327 ident, 1328 ipaddr_string(ndo, obj_tptr), 1329 EXTRACT_32BITS(obj_tptr + 4))); 1330 obj_tlen-=8; 1331 obj_tptr+=8; 1332 if (obj_tlen) 1333 hexdump=TRUE; /* unless we have a TLV parser lets just hexdump */ 1334 break; 1335 case RSVP_CTYPE_4: /* fall through - FIXME add TLV parser */ 1336 case RSVP_CTYPE_IPV6: 1337 if (obj_tlen < 20) 1338 return-1; 1339 ND_PRINT((ndo, "%s Previous/Next Interface: %s, Logical Interface Handle: 0x%08x", 1340 ident, 1341 ip6addr_string(ndo, obj_tptr), 1342 EXTRACT_32BITS(obj_tptr + 16))); 1343 obj_tlen-=20; 1344 obj_tptr+=20; 1345 hexdump=TRUE; /* unless we have a TLV parser lets just hexdump */ 1346 break; 1347 default: 1348 hexdump=TRUE; 1349 } 1350 break; 1351 1352 case RSVP_OBJ_TIME_VALUES: 1353 switch(rsvp_obj_ctype) { 1354 case RSVP_CTYPE_1: 1355 if (obj_tlen < 4) 1356 return-1; 1357 ND_PRINT((ndo, "%s Refresh Period: %ums", 1358 ident, 1359 EXTRACT_32BITS(obj_tptr))); 1360 obj_tlen-=4; 1361 obj_tptr+=4; 1362 break; 1363 default: 1364 hexdump=TRUE; 1365 } 1366 break; 1367 1368 /* those three objects do share the same semantics */ 1369 case RSVP_OBJ_SENDER_TSPEC: 1370 case RSVP_OBJ_ADSPEC: 1371 case RSVP_OBJ_FLOWSPEC: 1372 switch(rsvp_obj_ctype) { 1373 case RSVP_CTYPE_2: 1374 if (obj_tlen < 4) 1375 return-1; 1376 ND_PRINT((ndo, "%s Msg-Version: %u, length: %u", 1377 ident, 1378 (*obj_tptr & 0xf0) >> 4, 1379 EXTRACT_16BITS(obj_tptr + 2) << 2)); 1380 obj_tptr+=4; /* get to the start of the service header */ 1381 obj_tlen-=4; 1382 1383 while (obj_tlen >= 4) { 1384 intserv_serv_tlen=EXTRACT_16BITS(obj_tptr+2)<<2; 1385 ND_PRINT((ndo, "%s Service Type: %s (%u), break bit %s set, Service length: %u", 1386 ident, 1387 tok2str(rsvp_intserv_service_type_values,"unknown",*(obj_tptr)), 1388 *(obj_tptr), 1389 (*(obj_tptr+1)&0x80) ? "" : "not", 1390 intserv_serv_tlen)); 1391 1392 obj_tptr+=4; /* get to the start of the parameter list */ 1393 obj_tlen-=4; 1394 1395 while (intserv_serv_tlen>=4) { 1396 processed = rsvp_intserv_print(ndo, obj_tptr, obj_tlen); 1397 if (processed == 0) 1398 break; 1399 obj_tlen-=processed; 1400 intserv_serv_tlen-=processed; 1401 obj_tptr+=processed; 1402 } 1403 } 1404 break; 1405 default: 1406 hexdump=TRUE; 1407 } 1408 break; 1409 1410 case RSVP_OBJ_FILTERSPEC: 1411 switch(rsvp_obj_ctype) { 1412 case RSVP_CTYPE_IPV4: 1413 if (obj_tlen < 8) 1414 return-1; 1415 ND_PRINT((ndo, "%s Source Address: %s, Source Port: %u", 1416 ident, 1417 ipaddr_string(ndo, obj_tptr), 1418 EXTRACT_16BITS(obj_tptr + 6))); 1419 obj_tlen-=8; 1420 obj_tptr+=8; 1421 break; 1422 case RSVP_CTYPE_IPV6: 1423 if (obj_tlen < 20) 1424 return-1; 1425 ND_PRINT((ndo, "%s Source Address: %s, Source Port: %u", 1426 ident, 1427 ip6addr_string(ndo, obj_tptr), 1428 EXTRACT_16BITS(obj_tptr + 18))); 1429 obj_tlen-=20; 1430 obj_tptr+=20; 1431 break; 1432 case RSVP_CTYPE_3: 1433 if (obj_tlen < 20) 1434 return-1; 1435 ND_PRINT((ndo, "%s Source Address: %s, Flow Label: %u", 1436 ident, 1437 ip6addr_string(ndo, obj_tptr), 1438 EXTRACT_24BITS(obj_tptr + 17))); 1439 obj_tlen-=20; 1440 obj_tptr+=20; 1441 break; 1442 case RSVP_CTYPE_TUNNEL_IPV6: 1443 if (obj_tlen < 20) 1444 return-1; 1445 ND_PRINT((ndo, "%s Source Address: %s, LSP-ID: 0x%04x", 1446 ident, 1447 ipaddr_string(ndo, obj_tptr), 1448 EXTRACT_16BITS(obj_tptr + 18))); 1449 obj_tlen-=20; 1450 obj_tptr+=20; 1451 break; 1452 case RSVP_CTYPE_13: /* IPv6 p2mp LSP tunnel */ 1453 if (obj_tlen < 40) 1454 return-1; 1455 ND_PRINT((ndo, "%s IPv6 Tunnel Sender Address: %s, LSP ID: 0x%04x" 1456 "%s Sub-Group Originator ID: %s, Sub-Group ID: 0x%04x", 1457 ident, 1458 ip6addr_string(ndo, obj_tptr), 1459 EXTRACT_16BITS(obj_tptr+18), 1460 ident, 1461 ip6addr_string(ndo, obj_tptr+20), 1462 EXTRACT_16BITS(obj_tptr + 38))); 1463 obj_tlen-=40; 1464 obj_tptr+=40; 1465 break; 1466 case RSVP_CTYPE_TUNNEL_IPV4: 1467 if (obj_tlen < 8) 1468 return-1; 1469 ND_PRINT((ndo, "%s Source Address: %s, LSP-ID: 0x%04x", 1470 ident, 1471 ipaddr_string(ndo, obj_tptr), 1472 EXTRACT_16BITS(obj_tptr + 6))); 1473 obj_tlen-=8; 1474 obj_tptr+=8; 1475 break; 1476 case RSVP_CTYPE_12: /* IPv4 p2mp LSP tunnel */ 1477 if (obj_tlen < 16) 1478 return-1; 1479 ND_PRINT((ndo, "%s IPv4 Tunnel Sender Address: %s, LSP ID: 0x%04x" 1480 "%s Sub-Group Originator ID: %s, Sub-Group ID: 0x%04x", 1481 ident, 1482 ipaddr_string(ndo, obj_tptr), 1483 EXTRACT_16BITS(obj_tptr+6), 1484 ident, 1485 ipaddr_string(ndo, obj_tptr+8), 1486 EXTRACT_16BITS(obj_tptr + 12))); 1487 obj_tlen-=16; 1488 obj_tptr+=16; 1489 break; 1490 default: 1491 hexdump=TRUE; 1492 } 1493 break; 1494 1495 case RSVP_OBJ_FASTREROUTE: 1496 /* the differences between c-type 1 and 7 are minor */ 1497 obj_ptr.rsvp_obj_frr = (const struct rsvp_obj_frr_t *)obj_tptr; 1498 1499 switch(rsvp_obj_ctype) { 1500 case RSVP_CTYPE_1: /* new style */ 1501 if (obj_tlen < sizeof(struct rsvp_obj_frr_t)) 1502 return-1; 1503 bw.i = EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->bandwidth); 1504 ND_PRINT((ndo, "%s Setup Priority: %u, Holding Priority: %u, Hop-limit: %u, Bandwidth: %.10g Mbps", 1505 ident, 1506 (int)obj_ptr.rsvp_obj_frr->setup_prio, 1507 (int)obj_ptr.rsvp_obj_frr->hold_prio, 1508 (int)obj_ptr.rsvp_obj_frr->hop_limit, 1509 bw.f * 8 / 1000000)); 1510 ND_PRINT((ndo, "%s Include-any: 0x%08x, Exclude-any: 0x%08x, Include-all: 0x%08x", 1511 ident, 1512 EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->include_any), 1513 EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->exclude_any), 1514 EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->include_all))); 1515 obj_tlen-=sizeof(struct rsvp_obj_frr_t); 1516 obj_tptr+=sizeof(struct rsvp_obj_frr_t); 1517 break; 1518 1519 case RSVP_CTYPE_TUNNEL_IPV4: /* old style */ 1520 if (obj_tlen < 16) 1521 return-1; 1522 bw.i = EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->bandwidth); 1523 ND_PRINT((ndo, "%s Setup Priority: %u, Holding Priority: %u, Hop-limit: %u, Bandwidth: %.10g Mbps", 1524 ident, 1525 (int)obj_ptr.rsvp_obj_frr->setup_prio, 1526 (int)obj_ptr.rsvp_obj_frr->hold_prio, 1527 (int)obj_ptr.rsvp_obj_frr->hop_limit, 1528 bw.f * 8 / 1000000)); 1529 ND_PRINT((ndo, "%s Include Colors: 0x%08x, Exclude Colors: 0x%08x", 1530 ident, 1531 EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->include_any), 1532 EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->exclude_any))); 1533 obj_tlen-=16; 1534 obj_tptr+=16; 1535 break; 1536 1537 default: 1538 hexdump=TRUE; 1539 } 1540 break; 1541 1542 case RSVP_OBJ_DETOUR: 1543 switch(rsvp_obj_ctype) { 1544 case RSVP_CTYPE_TUNNEL_IPV4: 1545 while(obj_tlen >= 8) { 1546 ND_PRINT((ndo, "%s PLR-ID: %s, Avoid-Node-ID: %s", 1547 ident, 1548 ipaddr_string(ndo, obj_tptr), 1549 ipaddr_string(ndo, obj_tptr + 4))); 1550 obj_tlen-=8; 1551 obj_tptr+=8; 1552 } 1553 break; 1554 default: 1555 hexdump=TRUE; 1556 } 1557 break; 1558 1559 case RSVP_OBJ_CLASSTYPE: 1560 case RSVP_OBJ_CLASSTYPE_OLD: /* fall through */ 1561 switch(rsvp_obj_ctype) { 1562 case RSVP_CTYPE_1: 1563 ND_TCHECK_32BITS(obj_tptr); 1564 ND_PRINT((ndo, "%s CT: %u", 1565 ident, 1566 EXTRACT_32BITS(obj_tptr) & 0x7)); 1567 obj_tlen-=4; 1568 obj_tptr+=4; 1569 break; 1570 default: 1571 hexdump=TRUE; 1572 } 1573 break; 1574 1575 case RSVP_OBJ_ERROR_SPEC: 1576 switch(rsvp_obj_ctype) { 1577 case RSVP_CTYPE_3: /* fall through - FIXME add TLV parser */ 1578 case RSVP_CTYPE_IPV4: 1579 if (obj_tlen < 8) 1580 return-1; 1581 error_code=*(obj_tptr+5); 1582 error_value=EXTRACT_16BITS(obj_tptr+6); 1583 ND_PRINT((ndo, "%s Error Node Address: %s, Flags: [0x%02x]%s Error Code: %s (%u)", 1584 ident, 1585 ipaddr_string(ndo, obj_tptr), 1586 *(obj_tptr+4), 1587 ident, 1588 tok2str(rsvp_obj_error_code_values,"unknown",error_code), 1589 error_code)); 1590 switch (error_code) { 1591 case RSVP_OBJ_ERROR_SPEC_CODE_ROUTING: 1592 ND_PRINT((ndo, ", Error Value: %s (%u)", 1593 tok2str(rsvp_obj_error_code_routing_values,"unknown",error_value), 1594 error_value)); 1595 break; 1596 case RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE: /* fall through */ 1597 case RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE_OLD: 1598 ND_PRINT((ndo, ", Error Value: %s (%u)", 1599 tok2str(rsvp_obj_error_code_diffserv_te_values,"unknown",error_value), 1600 error_value)); 1601 break; 1602 default: 1603 ND_PRINT((ndo, ", Unknown Error Value (%u)", error_value)); 1604 break; 1605 } 1606 obj_tlen-=8; 1607 obj_tptr+=8; 1608 break; 1609 case RSVP_CTYPE_4: /* fall through - FIXME add TLV parser */ 1610 case RSVP_CTYPE_IPV6: 1611 if (obj_tlen < 20) 1612 return-1; 1613 error_code=*(obj_tptr+17); 1614 error_value=EXTRACT_16BITS(obj_tptr+18); 1615 ND_PRINT((ndo, "%s Error Node Address: %s, Flags: [0x%02x]%s Error Code: %s (%u)", 1616 ident, 1617 ip6addr_string(ndo, obj_tptr), 1618 *(obj_tptr+16), 1619 ident, 1620 tok2str(rsvp_obj_error_code_values,"unknown",error_code), 1621 error_code)); 1622 1623 switch (error_code) { 1624 case RSVP_OBJ_ERROR_SPEC_CODE_ROUTING: 1625 ND_PRINT((ndo, ", Error Value: %s (%u)", 1626 tok2str(rsvp_obj_error_code_routing_values,"unknown",error_value), 1627 error_value)); 1628 break; 1629 default: 1630 break; 1631 } 1632 obj_tlen-=20; 1633 obj_tptr+=20; 1634 break; 1635 default: 1636 hexdump=TRUE; 1637 } 1638 break; 1639 1640 case RSVP_OBJ_PROPERTIES: 1641 switch(rsvp_obj_ctype) { 1642 case RSVP_CTYPE_1: 1643 if (obj_tlen < 4) 1644 return-1; 1645 padbytes = EXTRACT_16BITS(obj_tptr+2); 1646 ND_PRINT((ndo, "%s TLV count: %u, padding bytes: %u", 1647 ident, 1648 EXTRACT_16BITS(obj_tptr), 1649 padbytes)); 1650 obj_tlen-=4; 1651 obj_tptr+=4; 1652 /* loop through as long there is anything longer than the TLV header (2) */ 1653 while(obj_tlen >= 2 + padbytes) { 1654 ND_PRINT((ndo, "%s %s TLV (0x%02x), length: %u", /* length includes header */ 1655 ident, 1656 tok2str(rsvp_obj_prop_tlv_values,"unknown",*obj_tptr), 1657 *obj_tptr, 1658 *(obj_tptr + 1))); 1659 if (obj_tlen < *(obj_tptr+1)) 1660 return-1; 1661 if (*(obj_tptr+1) < 2) 1662 return -1; 1663 print_unknown_data(ndo, obj_tptr + 2, "\n\t\t", *(obj_tptr + 1) - 2); 1664 obj_tlen-=*(obj_tptr+1); 1665 obj_tptr+=*(obj_tptr+1); 1666 } 1667 break; 1668 default: 1669 hexdump=TRUE; 1670 } 1671 break; 1672 1673 case RSVP_OBJ_MESSAGE_ID: /* fall through */ 1674 case RSVP_OBJ_MESSAGE_ID_ACK: /* fall through */ 1675 case RSVP_OBJ_MESSAGE_ID_LIST: 1676 switch(rsvp_obj_ctype) { 1677 case RSVP_CTYPE_1: 1678 case RSVP_CTYPE_2: 1679 if (obj_tlen < 8) 1680 return-1; 1681 ND_PRINT((ndo, "%s Flags [0x%02x], epoch: %u", 1682 ident, 1683 *obj_tptr, 1684 EXTRACT_24BITS(obj_tptr + 1))); 1685 obj_tlen-=4; 1686 obj_tptr+=4; 1687 /* loop through as long there are no messages left */ 1688 while(obj_tlen >= 4) { 1689 ND_PRINT((ndo, "%s Message-ID 0x%08x (%u)", 1690 ident, 1691 EXTRACT_32BITS(obj_tptr), 1692 EXTRACT_32BITS(obj_tptr))); 1693 obj_tlen-=4; 1694 obj_tptr+=4; 1695 } 1696 break; 1697 default: 1698 hexdump=TRUE; 1699 } 1700 break; 1701 1702 case RSVP_OBJ_INTEGRITY: 1703 switch(rsvp_obj_ctype) { 1704 case RSVP_CTYPE_1: 1705 if (obj_tlen < sizeof(struct rsvp_obj_integrity_t)) 1706 return-1; 1707 obj_ptr.rsvp_obj_integrity = (const struct rsvp_obj_integrity_t *)obj_tptr; 1708 ND_PRINT((ndo, "%s Key-ID 0x%04x%08x, Sequence 0x%08x%08x, Flags [%s]", 1709 ident, 1710 EXTRACT_16BITS(obj_ptr.rsvp_obj_integrity->key_id), 1711 EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->key_id+2), 1712 EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->sequence), 1713 EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->sequence+4), 1714 bittok2str(rsvp_obj_integrity_flag_values, 1715 "none", 1716 obj_ptr.rsvp_obj_integrity->flags))); 1717 ND_PRINT((ndo, "%s MD5-sum 0x%08x%08x%08x%08x ", 1718 ident, 1719 EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest), 1720 EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest+4), 1721 EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest+8), 1722 EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest + 12))); 1723 1724 sigcheck = signature_verify(ndo, pptr, plen, 1725 obj_ptr.rsvp_obj_integrity->digest, 1726 rsvp_clear_checksum, 1727 rsvp_com_header); 1728 ND_PRINT((ndo, " (%s)", tok2str(signature_check_values, "Unknown", sigcheck))); 1729 1730 obj_tlen+=sizeof(struct rsvp_obj_integrity_t); 1731 obj_tptr+=sizeof(struct rsvp_obj_integrity_t); 1732 break; 1733 default: 1734 hexdump=TRUE; 1735 } 1736 break; 1737 1738 case RSVP_OBJ_ADMIN_STATUS: 1739 switch(rsvp_obj_ctype) { 1740 case RSVP_CTYPE_1: 1741 if (obj_tlen < 4) 1742 return-1; 1743 ND_PRINT((ndo, "%s Flags [%s]", ident, 1744 bittok2str(rsvp_obj_admin_status_flag_values, "none", 1745 EXTRACT_32BITS(obj_tptr)))); 1746 obj_tlen-=4; 1747 obj_tptr+=4; 1748 break; 1749 default: 1750 hexdump=TRUE; 1751 } 1752 break; 1753 1754 case RSVP_OBJ_LABEL_SET: 1755 switch(rsvp_obj_ctype) { 1756 case RSVP_CTYPE_1: 1757 if (obj_tlen < 4) 1758 return-1; 1759 action = (EXTRACT_16BITS(obj_tptr)>>8); 1760 1761 ND_PRINT((ndo, "%s Action: %s (%u), Label type: %u", ident, 1762 tok2str(rsvp_obj_label_set_action_values, "Unknown", action), 1763 action, ((EXTRACT_32BITS(obj_tptr) & 0x7F)))); 1764 1765 switch (action) { 1766 case LABEL_SET_INCLUSIVE_RANGE: 1767 case LABEL_SET_EXCLUSIVE_RANGE: /* fall through */ 1768 1769 /* only a couple of subchannels are expected */ 1770 if (obj_tlen < 12) 1771 return -1; 1772 ND_PRINT((ndo, "%s Start range: %u, End range: %u", ident, 1773 EXTRACT_32BITS(obj_tptr+4), 1774 EXTRACT_32BITS(obj_tptr + 8))); 1775 obj_tlen-=12; 1776 obj_tptr+=12; 1777 break; 1778 1779 default: 1780 obj_tlen-=4; 1781 obj_tptr+=4; 1782 subchannel = 1; 1783 while(obj_tlen >= 4 ) { 1784 ND_PRINT((ndo, "%s Subchannel #%u: %u", ident, subchannel, 1785 EXTRACT_32BITS(obj_tptr))); 1786 obj_tptr+=4; 1787 obj_tlen-=4; 1788 subchannel++; 1789 } 1790 break; 1791 } 1792 break; 1793 default: 1794 hexdump=TRUE; 1795 } 1796 1797 case RSVP_OBJ_S2L: 1798 switch (rsvp_obj_ctype) { 1799 case RSVP_CTYPE_IPV4: 1800 if (obj_tlen < 4) 1801 return-1; 1802 ND_PRINT((ndo, "%s Sub-LSP destination address: %s", 1803 ident, ipaddr_string(ndo, obj_tptr))); 1804 1805 obj_tlen-=4; 1806 obj_tptr+=4; 1807 break; 1808 case RSVP_CTYPE_IPV6: 1809 if (obj_tlen < 16) 1810 return-1; 1811 ND_PRINT((ndo, "%s Sub-LSP destination address: %s", 1812 ident, ip6addr_string(ndo, obj_tptr))); 1813 1814 obj_tlen-=16; 1815 obj_tptr+=16; 1816 break; 1817 default: 1818 hexdump=TRUE; 1819 } 1820 1821 /* 1822 * FIXME those are the defined objects that lack a decoder 1823 * you are welcome to contribute code ;-) 1824 */ 1825 1826 case RSVP_OBJ_SCOPE: 1827 case RSVP_OBJ_POLICY_DATA: 1828 case RSVP_OBJ_ACCEPT_LABEL_SET: 1829 case RSVP_OBJ_PROTECTION: 1830 default: 1831 if (ndo->ndo_vflag <= 1) 1832 print_unknown_data(ndo, obj_tptr, "\n\t ", obj_tlen); /* FIXME indentation */ 1833 break; 1834 } 1835 /* do we also want to see a hex dump ? */ 1836 if (ndo->ndo_vflag > 1 || hexdump == TRUE) 1837 print_unknown_data(ndo, tptr + sizeof(struct rsvp_object_header), "\n\t ", /* FIXME indentation */ 1838 rsvp_obj_len - sizeof(struct rsvp_object_header)); 1839 1840 tptr+=rsvp_obj_len; 1841 tlen-=rsvp_obj_len; 1842 } 1843 return 0; 1844 invalid: 1845 ND_PRINT((ndo, "%s", istr)); 1846 return -1; 1847 trunc: 1848 ND_PRINT((ndo, "\n\t\t")); 1849 ND_PRINT((ndo, "%s", tstr)); 1850 return -1; 1851 } 1852 1853 void 1854 rsvp_print(netdissect_options *ndo, 1855 register const u_char *pptr, register u_int len) 1856 { 1857 const struct rsvp_common_header *rsvp_com_header; 1858 const u_char *tptr; 1859 u_short plen, tlen; 1860 1861 tptr=pptr; 1862 1863 rsvp_com_header = (const struct rsvp_common_header *)pptr; 1864 ND_TCHECK(*rsvp_com_header); 1865 1866 /* 1867 * Sanity checking of the header. 1868 */ 1869 if (RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags) != RSVP_VERSION) { 1870 ND_PRINT((ndo, "ERROR: RSVP version %u packet not supported", 1871 RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags))); 1872 return; 1873 } 1874 1875 /* in non-verbose mode just lets print the basic Message Type*/ 1876 if (ndo->ndo_vflag < 1) { 1877 ND_PRINT((ndo, "RSVPv%u %s Message, length: %u", 1878 RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags), 1879 tok2str(rsvp_msg_type_values, "unknown (%u)",rsvp_com_header->msg_type), 1880 len)); 1881 return; 1882 } 1883 1884 /* ok they seem to want to know everything - lets fully decode it */ 1885 1886 plen = tlen = EXTRACT_16BITS(rsvp_com_header->length); 1887 1888 ND_PRINT((ndo, "\n\tRSVPv%u %s Message (%u), Flags: [%s], length: %u, ttl: %u, checksum: 0x%04x", 1889 RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags), 1890 tok2str(rsvp_msg_type_values, "unknown, type: %u",rsvp_com_header->msg_type), 1891 rsvp_com_header->msg_type, 1892 bittok2str(rsvp_header_flag_values,"none",RSVP_EXTRACT_FLAGS(rsvp_com_header->version_flags)), 1893 tlen, 1894 rsvp_com_header->ttl, 1895 EXTRACT_16BITS(rsvp_com_header->checksum))); 1896 1897 if (tlen < sizeof(const struct rsvp_common_header)) { 1898 ND_PRINT((ndo, "ERROR: common header too short %u < %lu", tlen, 1899 (unsigned long)sizeof(const struct rsvp_common_header))); 1900 return; 1901 } 1902 1903 tptr+=sizeof(const struct rsvp_common_header); 1904 tlen-=sizeof(const struct rsvp_common_header); 1905 1906 switch(rsvp_com_header->msg_type) { 1907 1908 case RSVP_MSGTYPE_BUNDLE: 1909 /* 1910 * Process each submessage in the bundle message. 1911 * Bundle messages may not contain bundle submessages, so we don't 1912 * need to handle bundle submessages specially. 1913 */ 1914 while(tlen > 0) { 1915 const u_char *subpptr=tptr, *subtptr; 1916 u_short subplen, subtlen; 1917 1918 subtptr=subpptr; 1919 1920 rsvp_com_header = (const struct rsvp_common_header *)subpptr; 1921 ND_TCHECK(*rsvp_com_header); 1922 1923 /* 1924 * Sanity checking of the header. 1925 */ 1926 if (RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags) != RSVP_VERSION) { 1927 ND_PRINT((ndo, "ERROR: RSVP version %u packet not supported", 1928 RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags))); 1929 return; 1930 } 1931 1932 subplen = subtlen = EXTRACT_16BITS(rsvp_com_header->length); 1933 1934 ND_PRINT((ndo, "\n\t RSVPv%u %s Message (%u), Flags: [%s], length: %u, ttl: %u, checksum: 0x%04x", 1935 RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags), 1936 tok2str(rsvp_msg_type_values, "unknown, type: %u",rsvp_com_header->msg_type), 1937 rsvp_com_header->msg_type, 1938 bittok2str(rsvp_header_flag_values,"none",RSVP_EXTRACT_FLAGS(rsvp_com_header->version_flags)), 1939 subtlen, 1940 rsvp_com_header->ttl, 1941 EXTRACT_16BITS(rsvp_com_header->checksum))); 1942 1943 if (subtlen < sizeof(const struct rsvp_common_header)) { 1944 ND_PRINT((ndo, "ERROR: common header too short %u < %lu", subtlen, 1945 (unsigned long)sizeof(const struct rsvp_common_header))); 1946 return; 1947 } 1948 1949 if (tlen < subtlen) { 1950 ND_PRINT((ndo, "ERROR: common header too large %u > %u", subtlen, 1951 tlen)); 1952 return; 1953 } 1954 1955 subtptr+=sizeof(const struct rsvp_common_header); 1956 subtlen-=sizeof(const struct rsvp_common_header); 1957 1958 /* 1959 * Print all objects in the submessage. 1960 */ 1961 if (rsvp_obj_print(ndo, subpptr, subplen, subtptr, "\n\t ", subtlen, rsvp_com_header) == -1) 1962 return; 1963 1964 tptr+=subtlen+sizeof(const struct rsvp_common_header); 1965 tlen-=subtlen+sizeof(const struct rsvp_common_header); 1966 } 1967 1968 break; 1969 1970 case RSVP_MSGTYPE_PATH: 1971 case RSVP_MSGTYPE_RESV: 1972 case RSVP_MSGTYPE_PATHERR: 1973 case RSVP_MSGTYPE_RESVERR: 1974 case RSVP_MSGTYPE_PATHTEAR: 1975 case RSVP_MSGTYPE_RESVTEAR: 1976 case RSVP_MSGTYPE_RESVCONF: 1977 case RSVP_MSGTYPE_HELLO_OLD: 1978 case RSVP_MSGTYPE_HELLO: 1979 case RSVP_MSGTYPE_ACK: 1980 case RSVP_MSGTYPE_SREFRESH: 1981 /* 1982 * Print all objects in the message. 1983 */ 1984 if (rsvp_obj_print(ndo, pptr, plen, tptr, "\n\t ", tlen, rsvp_com_header) == -1) 1985 return; 1986 break; 1987 1988 default: 1989 print_unknown_data(ndo, tptr, "\n\t ", tlen); 1990 break; 1991 } 1992 1993 return; 1994 trunc: 1995 ND_PRINT((ndo, "\n\t\t")); 1996 ND_PRINT((ndo, "%s", tstr)); 1997 } 1998