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