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 /* \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 ND_TCHECK_8BITS(tptr); 503 parameter_id = *(tptr); 504 ND_TCHECK2(*(tptr + 2), 2); 505 parameter_length = EXTRACT_16BITS(tptr+2)<<2; /* convert wordcount to bytecount */ 506 507 ND_PRINT((ndo, "\n\t Parameter ID: %s (%u), length: %u, Flags: [0x%02x]", 508 tok2str(rsvp_intserv_parameter_id_values,"unknown",parameter_id), 509 parameter_id, 510 parameter_length, 511 *(tptr + 1))); 512 513 if (obj_tlen < parameter_length+4) 514 return 0; 515 switch(parameter_id) { /* parameter_id */ 516 517 case 4: 518 /* 519 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 520 * | 4 (e) | (f) | 1 (g) | 521 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 522 * | IS hop cnt (32-bit unsigned integer) | 523 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 524 */ 525 if (parameter_length == 4) { 526 ND_TCHECK2(*(tptr + 4), 4); 527 ND_PRINT((ndo, "\n\t\tIS hop count: %u", EXTRACT_32BITS(tptr + 4))); 528 } 529 break; 530 531 case 6: 532 /* 533 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 534 * | 6 (h) | (i) | 1 (j) | 535 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 536 * | Path b/w estimate (32-bit IEEE floating point number) | 537 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 538 */ 539 if (parameter_length == 4) { 540 ND_TCHECK2(*(tptr + 4), 4); 541 bw.i = EXTRACT_32BITS(tptr+4); 542 ND_PRINT((ndo, "\n\t\tPath b/w estimate: %.10g Mbps", bw.f / 125000)); 543 } 544 break; 545 546 case 8: 547 /* 548 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 549 * | 8 (k) | (l) | 1 (m) | 550 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 551 * | Minimum path latency (32-bit integer) | 552 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 553 */ 554 if (parameter_length == 4) { 555 ND_TCHECK2(*(tptr + 4), 4); 556 ND_PRINT((ndo, "\n\t\tMinimum path latency: ")); 557 if (EXTRACT_32BITS(tptr+4) == 0xffffffff) 558 ND_PRINT((ndo, "don't care")); 559 else 560 ND_PRINT((ndo, "%u", EXTRACT_32BITS(tptr + 4))); 561 } 562 break; 563 564 case 10: 565 566 /* 567 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 568 * | 10 (n) | (o) | 1 (p) | 569 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 570 * | Composed MTU (32-bit unsigned integer) | 571 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 572 */ 573 if (parameter_length == 4) { 574 ND_TCHECK2(*(tptr + 4), 4); 575 ND_PRINT((ndo, "\n\t\tComposed MTU: %u bytes", EXTRACT_32BITS(tptr + 4))); 576 } 577 break; 578 case 127: 579 /* 580 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 581 * | 127 (e) | 0 (f) | 5 (g) | 582 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 583 * | Token Bucket Rate [r] (32-bit IEEE floating point number) | 584 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 585 * | Token Bucket Size [b] (32-bit IEEE floating point number) | 586 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 587 * | Peak Data Rate [p] (32-bit IEEE floating point number) | 588 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 589 * | Minimum Policed Unit [m] (32-bit integer) | 590 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 591 * | Maximum Packet Size [M] (32-bit integer) | 592 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 593 */ 594 595 if (parameter_length == 20) { 596 ND_TCHECK2(*(tptr + 4), 20); 597 bw.i = EXTRACT_32BITS(tptr+4); 598 ND_PRINT((ndo, "\n\t\tToken Bucket Rate: %.10g Mbps", bw.f / 125000)); 599 bw.i = EXTRACT_32BITS(tptr+8); 600 ND_PRINT((ndo, "\n\t\tToken Bucket Size: %.10g bytes", bw.f)); 601 bw.i = EXTRACT_32BITS(tptr+12); 602 ND_PRINT((ndo, "\n\t\tPeak Data Rate: %.10g Mbps", bw.f / 125000)); 603 ND_PRINT((ndo, "\n\t\tMinimum Policed Unit: %u bytes", EXTRACT_32BITS(tptr + 16))); 604 ND_PRINT((ndo, "\n\t\tMaximum Packet Size: %u bytes", EXTRACT_32BITS(tptr + 20))); 605 } 606 break; 607 608 case 130: 609 /* 610 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 611 * | 130 (h) | 0 (i) | 2 (j) | 612 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 613 * | Rate [R] (32-bit IEEE floating point number) | 614 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 615 * | Slack Term [S] (32-bit integer) | 616 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 617 */ 618 619 if (parameter_length == 8) { 620 ND_TCHECK2(*(tptr + 4), 8); 621 bw.i = EXTRACT_32BITS(tptr+4); 622 ND_PRINT((ndo, "\n\t\tRate: %.10g Mbps", bw.f / 125000)); 623 ND_PRINT((ndo, "\n\t\tSlack Term: %u", EXTRACT_32BITS(tptr + 8))); 624 } 625 break; 626 627 case 133: 628 case 134: 629 case 135: 630 case 136: 631 if (parameter_length == 4) { 632 ND_TCHECK2(*(tptr + 4), 4); 633 ND_PRINT((ndo, "\n\t\tValue: %u", EXTRACT_32BITS(tptr + 4))); 634 } 635 break; 636 637 default: 638 if (ndo->ndo_vflag <= 1) 639 print_unknown_data(ndo, tptr + 4, "\n\t\t", parameter_length); 640 } 641 return (parameter_length+4); /* header length 4 bytes */ 642 643 trunc: 644 ND_PRINT((ndo, "%s", tstr)); 645 return 0; 646 } 647 648 /* 649 * Clear checksum prior to signature verification. 650 */ 651 static void 652 rsvp_clear_checksum(void *header) 653 { 654 struct rsvp_common_header *rsvp_com_header = (struct rsvp_common_header *) header; 655 656 rsvp_com_header->checksum[0] = 0; 657 rsvp_com_header->checksum[1] = 0; 658 } 659 660 static int 661 rsvp_obj_print(netdissect_options *ndo, 662 const u_char *pptr, u_int plen, const u_char *tptr, 663 const char *ident, u_int tlen, 664 const struct rsvp_common_header *rsvp_com_header) 665 { 666 const struct rsvp_object_header *rsvp_obj_header; 667 const u_char *obj_tptr; 668 union { 669 const struct rsvp_obj_integrity_t *rsvp_obj_integrity; 670 const struct rsvp_obj_frr_t *rsvp_obj_frr; 671 } obj_ptr; 672 673 u_short rsvp_obj_len,rsvp_obj_ctype,obj_tlen,intserv_serv_tlen; 674 int hexdump,processed,padbytes,error_code,error_value,i,sigcheck; 675 union { 676 float f; 677 uint32_t i; 678 } bw; 679 uint8_t namelen; 680 681 u_int action, subchannel; 682 683 while(tlen>=sizeof(struct rsvp_object_header)) { 684 /* did we capture enough for fully decoding the object header ? */ 685 ND_TCHECK2(*tptr, sizeof(struct rsvp_object_header)); 686 687 rsvp_obj_header = (const struct rsvp_object_header *)tptr; 688 rsvp_obj_len=EXTRACT_16BITS(rsvp_obj_header->length); 689 rsvp_obj_ctype=rsvp_obj_header->ctype; 690 691 if(rsvp_obj_len % 4) { 692 ND_PRINT((ndo, "%sERROR: object header size %u not a multiple of 4", ident, rsvp_obj_len)); 693 return -1; 694 } 695 if(rsvp_obj_len < sizeof(struct rsvp_object_header)) { 696 ND_PRINT((ndo, "%sERROR: object header too short %u < %lu", ident, rsvp_obj_len, 697 (unsigned long)sizeof(const struct rsvp_object_header))); 698 return -1; 699 } 700 701 ND_PRINT((ndo, "%s%s Object (%u) Flags: [%s", 702 ident, 703 tok2str(rsvp_obj_values, 704 "Unknown", 705 rsvp_obj_header->class_num), 706 rsvp_obj_header->class_num, 707 ((rsvp_obj_header->class_num) & 0x80) ? "ignore" : "reject")); 708 709 if (rsvp_obj_header->class_num > 128) 710 ND_PRINT((ndo, " %s", 711 ((rsvp_obj_header->class_num) & 0x40) ? "and forward" : "silently")); 712 713 ND_PRINT((ndo, " if unknown], Class-Type: %s (%u), length: %u", 714 tok2str(rsvp_ctype_values, 715 "Unknown", 716 ((rsvp_obj_header->class_num)<<8)+rsvp_obj_ctype), 717 rsvp_obj_ctype, 718 rsvp_obj_len)); 719 720 if(tlen < rsvp_obj_len) { 721 ND_PRINT((ndo, "%sERROR: object goes past end of objects TLV", ident)); 722 return -1; 723 } 724 725 obj_tptr=tptr+sizeof(struct rsvp_object_header); 726 obj_tlen=rsvp_obj_len-sizeof(struct rsvp_object_header); 727 728 /* did we capture enough for fully decoding the object ? */ 729 if (!ND_TTEST2(*tptr, rsvp_obj_len)) 730 return -1; 731 hexdump=FALSE; 732 733 switch(rsvp_obj_header->class_num) { 734 case RSVP_OBJ_SESSION: 735 switch(rsvp_obj_ctype) { 736 case RSVP_CTYPE_IPV4: 737 if (obj_tlen < 8) 738 return -1; 739 ND_PRINT((ndo, "%s IPv4 DestAddress: %s, Protocol ID: 0x%02x", 740 ident, 741 ipaddr_string(ndo, obj_tptr), 742 *(obj_tptr + sizeof(struct in_addr)))); 743 ND_PRINT((ndo, "%s Flags: [0x%02x], DestPort %u", 744 ident, 745 *(obj_tptr+5), 746 EXTRACT_16BITS(obj_tptr + 6))); 747 obj_tlen-=8; 748 obj_tptr+=8; 749 break; 750 case RSVP_CTYPE_IPV6: 751 if (obj_tlen < 20) 752 return -1; 753 ND_PRINT((ndo, "%s IPv6 DestAddress: %s, Protocol ID: 0x%02x", 754 ident, 755 ip6addr_string(ndo, obj_tptr), 756 *(obj_tptr + sizeof(struct in6_addr)))); 757 ND_PRINT((ndo, "%s Flags: [0x%02x], DestPort %u", 758 ident, 759 *(obj_tptr+sizeof(struct in6_addr)+1), 760 EXTRACT_16BITS(obj_tptr + sizeof(struct in6_addr) + 2))); 761 obj_tlen-=20; 762 obj_tptr+=20; 763 break; 764 765 case RSVP_CTYPE_TUNNEL_IPV6: 766 if (obj_tlen < 36) 767 return -1; 768 ND_PRINT((ndo, "%s IPv6 Tunnel EndPoint: %s, Tunnel ID: 0x%04x, Extended Tunnel ID: %s", 769 ident, 770 ip6addr_string(ndo, obj_tptr), 771 EXTRACT_16BITS(obj_tptr+18), 772 ip6addr_string(ndo, obj_tptr + 20))); 773 obj_tlen-=36; 774 obj_tptr+=36; 775 break; 776 777 case RSVP_CTYPE_14: /* IPv6 p2mp LSP Tunnel */ 778 if (obj_tlen < 26) 779 return -1; 780 ND_PRINT((ndo, "%s IPv6 P2MP LSP ID: 0x%08x, Tunnel ID: 0x%04x, Extended Tunnel ID: %s", 781 ident, 782 EXTRACT_32BITS(obj_tptr), 783 EXTRACT_16BITS(obj_tptr+6), 784 ip6addr_string(ndo, obj_tptr + 8))); 785 obj_tlen-=26; 786 obj_tptr+=26; 787 break; 788 case RSVP_CTYPE_13: /* IPv4 p2mp LSP Tunnel */ 789 if (obj_tlen < 12) 790 return -1; 791 ND_PRINT((ndo, "%s IPv4 P2MP LSP ID: %s, Tunnel ID: 0x%04x, Extended Tunnel ID: %s", 792 ident, 793 ipaddr_string(ndo, obj_tptr), 794 EXTRACT_16BITS(obj_tptr+6), 795 ipaddr_string(ndo, obj_tptr + 8))); 796 obj_tlen-=12; 797 obj_tptr+=12; 798 break; 799 case RSVP_CTYPE_TUNNEL_IPV4: 800 case RSVP_CTYPE_UNI_IPV4: 801 if (obj_tlen < 12) 802 return -1; 803 ND_PRINT((ndo, "%s IPv4 Tunnel EndPoint: %s, Tunnel ID: 0x%04x, Extended Tunnel ID: %s", 804 ident, 805 ipaddr_string(ndo, obj_tptr), 806 EXTRACT_16BITS(obj_tptr+6), 807 ipaddr_string(ndo, obj_tptr + 8))); 808 obj_tlen-=12; 809 obj_tptr+=12; 810 break; 811 default: 812 hexdump=TRUE; 813 } 814 break; 815 816 case RSVP_OBJ_CONFIRM: 817 switch(rsvp_obj_ctype) { 818 case RSVP_CTYPE_IPV4: 819 if (obj_tlen < sizeof(struct in_addr)) 820 return -1; 821 ND_PRINT((ndo, "%s IPv4 Receiver Address: %s", 822 ident, 823 ipaddr_string(ndo, obj_tptr))); 824 obj_tlen-=sizeof(struct in_addr); 825 obj_tptr+=sizeof(struct in_addr); 826 break; 827 case RSVP_CTYPE_IPV6: 828 if (obj_tlen < sizeof(struct in6_addr)) 829 return -1; 830 ND_PRINT((ndo, "%s IPv6 Receiver Address: %s", 831 ident, 832 ip6addr_string(ndo, obj_tptr))); 833 obj_tlen-=sizeof(struct in6_addr); 834 obj_tptr+=sizeof(struct in6_addr); 835 break; 836 default: 837 hexdump=TRUE; 838 } 839 break; 840 841 case RSVP_OBJ_NOTIFY_REQ: 842 switch(rsvp_obj_ctype) { 843 case RSVP_CTYPE_IPV4: 844 if (obj_tlen < sizeof(struct in_addr)) 845 return -1; 846 ND_PRINT((ndo, "%s IPv4 Notify Node Address: %s", 847 ident, 848 ipaddr_string(ndo, obj_tptr))); 849 obj_tlen-=sizeof(struct in_addr); 850 obj_tptr+=sizeof(struct in_addr); 851 break; 852 case RSVP_CTYPE_IPV6: 853 if (obj_tlen < sizeof(struct in6_addr)) 854 return-1; 855 ND_PRINT((ndo, "%s IPv6 Notify Node Address: %s", 856 ident, 857 ip6addr_string(ndo, obj_tptr))); 858 obj_tlen-=sizeof(struct in6_addr); 859 obj_tptr+=sizeof(struct in6_addr); 860 break; 861 default: 862 hexdump=TRUE; 863 } 864 break; 865 866 case RSVP_OBJ_SUGGESTED_LABEL: /* fall through */ 867 case RSVP_OBJ_UPSTREAM_LABEL: /* fall through */ 868 case RSVP_OBJ_RECOVERY_LABEL: /* fall through */ 869 case RSVP_OBJ_LABEL: 870 switch(rsvp_obj_ctype) { 871 case RSVP_CTYPE_1: 872 while(obj_tlen >= 4 ) { 873 ND_PRINT((ndo, "%s Label: %u", ident, EXTRACT_32BITS(obj_tptr))); 874 obj_tlen-=4; 875 obj_tptr+=4; 876 } 877 break; 878 case RSVP_CTYPE_2: 879 if (obj_tlen < 4) 880 return-1; 881 ND_PRINT((ndo, "%s Generalized Label: %u", 882 ident, 883 EXTRACT_32BITS(obj_tptr))); 884 obj_tlen-=4; 885 obj_tptr+=4; 886 break; 887 case RSVP_CTYPE_3: 888 if (obj_tlen < 12) 889 return-1; 890 ND_PRINT((ndo, "%s Waveband ID: %u%s Start Label: %u, Stop Label: %u", 891 ident, 892 EXTRACT_32BITS(obj_tptr), 893 ident, 894 EXTRACT_32BITS(obj_tptr+4), 895 EXTRACT_32BITS(obj_tptr + 8))); 896 obj_tlen-=12; 897 obj_tptr+=12; 898 break; 899 default: 900 hexdump=TRUE; 901 } 902 break; 903 904 case RSVP_OBJ_STYLE: 905 switch(rsvp_obj_ctype) { 906 case RSVP_CTYPE_1: 907 if (obj_tlen < 4) 908 return-1; 909 ND_PRINT((ndo, "%s Reservation Style: %s, Flags: [0x%02x]", 910 ident, 911 tok2str(rsvp_resstyle_values, 912 "Unknown", 913 EXTRACT_24BITS(obj_tptr+1)), 914 *(obj_tptr))); 915 obj_tlen-=4; 916 obj_tptr+=4; 917 break; 918 default: 919 hexdump=TRUE; 920 } 921 break; 922 923 case RSVP_OBJ_SENDER_TEMPLATE: 924 switch(rsvp_obj_ctype) { 925 case RSVP_CTYPE_IPV4: 926 if (obj_tlen < 8) 927 return-1; 928 ND_PRINT((ndo, "%s Source Address: %s, Source Port: %u", 929 ident, 930 ipaddr_string(ndo, obj_tptr), 931 EXTRACT_16BITS(obj_tptr + 6))); 932 obj_tlen-=8; 933 obj_tptr+=8; 934 break; 935 case RSVP_CTYPE_IPV6: 936 if (obj_tlen < 20) 937 return-1; 938 ND_PRINT((ndo, "%s Source Address: %s, Source Port: %u", 939 ident, 940 ip6addr_string(ndo, obj_tptr), 941 EXTRACT_16BITS(obj_tptr + 18))); 942 obj_tlen-=20; 943 obj_tptr+=20; 944 break; 945 case RSVP_CTYPE_13: /* IPv6 p2mp LSP tunnel */ 946 if (obj_tlen < 40) 947 return-1; 948 ND_PRINT((ndo, "%s IPv6 Tunnel Sender Address: %s, LSP ID: 0x%04x" 949 "%s Sub-Group Originator ID: %s, Sub-Group ID: 0x%04x", 950 ident, 951 ip6addr_string(ndo, obj_tptr), 952 EXTRACT_16BITS(obj_tptr+18), 953 ident, 954 ip6addr_string(ndo, obj_tptr+20), 955 EXTRACT_16BITS(obj_tptr + 38))); 956 obj_tlen-=40; 957 obj_tptr+=40; 958 break; 959 case RSVP_CTYPE_TUNNEL_IPV4: 960 if (obj_tlen < 8) 961 return-1; 962 ND_PRINT((ndo, "%s IPv4 Tunnel Sender Address: %s, LSP-ID: 0x%04x", 963 ident, 964 ipaddr_string(ndo, obj_tptr), 965 EXTRACT_16BITS(obj_tptr + 6))); 966 obj_tlen-=8; 967 obj_tptr+=8; 968 break; 969 case RSVP_CTYPE_12: /* IPv4 p2mp LSP tunnel */ 970 if (obj_tlen < 16) 971 return-1; 972 ND_PRINT((ndo, "%s IPv4 Tunnel Sender Address: %s, LSP ID: 0x%04x" 973 "%s Sub-Group Originator ID: %s, Sub-Group ID: 0x%04x", 974 ident, 975 ipaddr_string(ndo, obj_tptr), 976 EXTRACT_16BITS(obj_tptr+6), 977 ident, 978 ipaddr_string(ndo, obj_tptr+8), 979 EXTRACT_16BITS(obj_tptr + 12))); 980 obj_tlen-=16; 981 obj_tptr+=16; 982 break; 983 default: 984 hexdump=TRUE; 985 } 986 break; 987 988 case RSVP_OBJ_LABEL_REQ: 989 switch(rsvp_obj_ctype) { 990 case RSVP_CTYPE_1: 991 while(obj_tlen >= 4 ) { 992 ND_PRINT((ndo, "%s L3 Protocol ID: %s", 993 ident, 994 tok2str(ethertype_values, 995 "Unknown Protocol (0x%04x)", 996 EXTRACT_16BITS(obj_tptr + 2)))); 997 obj_tlen-=4; 998 obj_tptr+=4; 999 } 1000 break; 1001 case RSVP_CTYPE_2: 1002 if (obj_tlen < 12) 1003 return-1; 1004 ND_PRINT((ndo, "%s L3 Protocol ID: %s", 1005 ident, 1006 tok2str(ethertype_values, 1007 "Unknown Protocol (0x%04x)", 1008 EXTRACT_16BITS(obj_tptr + 2)))); 1009 ND_PRINT((ndo, ",%s merge capability",((*(obj_tptr + 4)) & 0x80) ? "no" : "" )); 1010 ND_PRINT((ndo, "%s Minimum VPI/VCI: %u/%u", 1011 ident, 1012 (EXTRACT_16BITS(obj_tptr+4))&0xfff, 1013 (EXTRACT_16BITS(obj_tptr + 6)) & 0xfff)); 1014 ND_PRINT((ndo, "%s Maximum VPI/VCI: %u/%u", 1015 ident, 1016 (EXTRACT_16BITS(obj_tptr+8))&0xfff, 1017 (EXTRACT_16BITS(obj_tptr + 10)) & 0xfff)); 1018 obj_tlen-=12; 1019 obj_tptr+=12; 1020 break; 1021 case RSVP_CTYPE_3: 1022 if (obj_tlen < 12) 1023 return-1; 1024 ND_PRINT((ndo, "%s L3 Protocol ID: %s", 1025 ident, 1026 tok2str(ethertype_values, 1027 "Unknown Protocol (0x%04x)", 1028 EXTRACT_16BITS(obj_tptr + 2)))); 1029 ND_PRINT((ndo, "%s Minimum/Maximum DLCI: %u/%u, %s%s bit DLCI", 1030 ident, 1031 (EXTRACT_32BITS(obj_tptr+4))&0x7fffff, 1032 (EXTRACT_32BITS(obj_tptr+8))&0x7fffff, 1033 (((EXTRACT_16BITS(obj_tptr+4)>>7)&3) == 0 ) ? "10" : "", 1034 (((EXTRACT_16BITS(obj_tptr + 4) >> 7) & 3) == 2 ) ? "23" : "")); 1035 obj_tlen-=12; 1036 obj_tptr+=12; 1037 break; 1038 case RSVP_CTYPE_4: 1039 if (obj_tlen < 4) 1040 return-1; 1041 ND_PRINT((ndo, "%s LSP Encoding Type: %s (%u)", 1042 ident, 1043 tok2str(gmpls_encoding_values, 1044 "Unknown", 1045 *obj_tptr), 1046 *obj_tptr)); 1047 ND_PRINT((ndo, "%s Switching Type: %s (%u), Payload ID: %s (0x%04x)", 1048 ident, 1049 tok2str(gmpls_switch_cap_values, 1050 "Unknown", 1051 *(obj_tptr+1)), 1052 *(obj_tptr+1), 1053 tok2str(gmpls_payload_values, 1054 "Unknown", 1055 EXTRACT_16BITS(obj_tptr+2)), 1056 EXTRACT_16BITS(obj_tptr + 2))); 1057 obj_tlen-=4; 1058 obj_tptr+=4; 1059 break; 1060 default: 1061 hexdump=TRUE; 1062 } 1063 break; 1064 1065 case RSVP_OBJ_RRO: 1066 case RSVP_OBJ_ERO: 1067 switch(rsvp_obj_ctype) { 1068 case RSVP_CTYPE_IPV4: 1069 while(obj_tlen >= 4 ) { 1070 u_char length; 1071 1072 ND_TCHECK2(*obj_tptr, 4); 1073 length = *(obj_tptr + 1); 1074 ND_PRINT((ndo, "%s Subobject Type: %s, length %u", 1075 ident, 1076 tok2str(rsvp_obj_xro_values, 1077 "Unknown %u", 1078 RSVP_OBJ_XRO_MASK_SUBOBJ(*obj_tptr)), 1079 length)); 1080 1081 if (length == 0) { /* prevent infinite loops */ 1082 ND_PRINT((ndo, "%s ERROR: zero length ERO subtype", ident)); 1083 break; 1084 } 1085 1086 switch(RSVP_OBJ_XRO_MASK_SUBOBJ(*obj_tptr)) { 1087 u_char prefix_length; 1088 1089 case RSVP_OBJ_XRO_IPV4: 1090 if (length != 8) { 1091 ND_PRINT((ndo, " ERROR: length != 8")); 1092 goto invalid; 1093 } 1094 ND_TCHECK2(*obj_tptr, 8); 1095 prefix_length = *(obj_tptr+6); 1096 if (prefix_length != 32) { 1097 ND_PRINT((ndo, " ERROR: Prefix length %u != 32", 1098 prefix_length)); 1099 goto invalid; 1100 } 1101 ND_PRINT((ndo, ", %s, %s/%u, Flags: [%s]", 1102 RSVP_OBJ_XRO_MASK_LOOSE(*obj_tptr) ? "Loose" : "Strict", 1103 ipaddr_string(ndo, obj_tptr+2), 1104 *(obj_tptr+6), 1105 bittok2str(rsvp_obj_rro_flag_values, 1106 "none", 1107 *(obj_tptr + 7)))); /* rfc3209 says that this field is rsvd. */ 1108 break; 1109 case RSVP_OBJ_XRO_LABEL: 1110 if (length != 8) { 1111 ND_PRINT((ndo, " ERROR: length != 8")); 1112 goto invalid; 1113 } 1114 ND_TCHECK2(*obj_tptr, 8); 1115 ND_PRINT((ndo, ", Flags: [%s] (%#x), Class-Type: %s (%u), %u", 1116 bittok2str(rsvp_obj_rro_label_flag_values, 1117 "none", 1118 *(obj_tptr+2)), 1119 *(obj_tptr+2), 1120 tok2str(rsvp_ctype_values, 1121 "Unknown", 1122 *(obj_tptr+3) + 256*RSVP_OBJ_RRO), 1123 *(obj_tptr+3), 1124 EXTRACT_32BITS(obj_tptr + 4))); 1125 } 1126 obj_tlen-=*(obj_tptr+1); 1127 obj_tptr+=*(obj_tptr+1); 1128 } 1129 break; 1130 default: 1131 hexdump=TRUE; 1132 } 1133 break; 1134 1135 case RSVP_OBJ_HELLO: 1136 switch(rsvp_obj_ctype) { 1137 case RSVP_CTYPE_1: 1138 case RSVP_CTYPE_2: 1139 if (obj_tlen < 8) 1140 return-1; 1141 ND_PRINT((ndo, "%s Source Instance: 0x%08x, Destination Instance: 0x%08x", 1142 ident, 1143 EXTRACT_32BITS(obj_tptr), 1144 EXTRACT_32BITS(obj_tptr + 4))); 1145 obj_tlen-=8; 1146 obj_tptr+=8; 1147 break; 1148 default: 1149 hexdump=TRUE; 1150 } 1151 break; 1152 1153 case RSVP_OBJ_RESTART_CAPABILITY: 1154 switch(rsvp_obj_ctype) { 1155 case RSVP_CTYPE_1: 1156 if (obj_tlen < 8) 1157 return-1; 1158 ND_PRINT((ndo, "%s Restart Time: %ums, Recovery Time: %ums", 1159 ident, 1160 EXTRACT_32BITS(obj_tptr), 1161 EXTRACT_32BITS(obj_tptr + 4))); 1162 obj_tlen-=8; 1163 obj_tptr+=8; 1164 break; 1165 default: 1166 hexdump=TRUE; 1167 } 1168 break; 1169 1170 case RSVP_OBJ_SESSION_ATTRIBUTE: 1171 switch(rsvp_obj_ctype) { 1172 case RSVP_CTYPE_TUNNEL_IPV4: 1173 if (obj_tlen < 4) 1174 return-1; 1175 namelen = *(obj_tptr+3); 1176 if (obj_tlen < 4+namelen) 1177 return-1; 1178 ND_PRINT((ndo, "%s Session Name: ", ident)); 1179 for (i = 0; i < namelen; i++) 1180 safeputchar(ndo, *(obj_tptr + 4 + i)); 1181 ND_PRINT((ndo, "%s Setup Priority: %u, Holding Priority: %u, Flags: [%s] (%#x)", 1182 ident, 1183 (int)*obj_tptr, 1184 (int)*(obj_tptr+1), 1185 bittok2str(rsvp_session_attribute_flag_values, 1186 "none", 1187 *(obj_tptr+2)), 1188 *(obj_tptr + 2))); 1189 obj_tlen-=4+*(obj_tptr+3); 1190 obj_tptr+=4+*(obj_tptr+3); 1191 break; 1192 default: 1193 hexdump=TRUE; 1194 } 1195 break; 1196 1197 case RSVP_OBJ_GENERALIZED_UNI: 1198 switch(rsvp_obj_ctype) { 1199 int subobj_type,af,subobj_len,total_subobj_len; 1200 1201 case RSVP_CTYPE_1: 1202 1203 if (obj_tlen < 4) 1204 return-1; 1205 1206 /* read variable length subobjects */ 1207 total_subobj_len = obj_tlen; 1208 while(total_subobj_len > 0) { 1209 /* If RFC 3476 Section 3.1 defined that a sub-object of the 1210 * GENERALIZED_UNI RSVP object must have the Length field as 1211 * a multiple of 4, instead of the check below it would be 1212 * better to test total_subobj_len only once before the loop. 1213 * So long as it does not define it and this while loop does 1214 * not implement such a requirement, let's accept that within 1215 * each iteration subobj_len may happen to be a multiple of 1 1216 * and test it and total_subobj_len respectively. 1217 */ 1218 if (total_subobj_len < 4) 1219 goto invalid; 1220 subobj_len = EXTRACT_16BITS(obj_tptr); 1221 subobj_type = (EXTRACT_16BITS(obj_tptr+2))>>8; 1222 af = (EXTRACT_16BITS(obj_tptr+2))&0x00FF; 1223 1224 ND_PRINT((ndo, "%s Subobject Type: %s (%u), AF: %s (%u), length: %u", 1225 ident, 1226 tok2str(rsvp_obj_generalized_uni_values, "Unknown", subobj_type), 1227 subobj_type, 1228 tok2str(af_values, "Unknown", af), af, 1229 subobj_len)); 1230 1231 /* In addition to what is explained above, the same spec does not 1232 * explicitly say that the same Length field includes the 4-octet 1233 * sub-object header, but as long as this while loop implements it 1234 * as it does include, let's keep the check below consistent with 1235 * the rest of the code. 1236 */ 1237 if(subobj_len < 4 || subobj_len > total_subobj_len) 1238 goto invalid; 1239 1240 switch(subobj_type) { 1241 case RSVP_GEN_UNI_SUBOBJ_SOURCE_TNA_ADDRESS: 1242 case RSVP_GEN_UNI_SUBOBJ_DESTINATION_TNA_ADDRESS: 1243 1244 switch(af) { 1245 case AFNUM_INET: 1246 if (subobj_len < 8) 1247 return -1; 1248 ND_PRINT((ndo, "%s UNI IPv4 TNA address: %s", 1249 ident, ipaddr_string(ndo, obj_tptr + 4))); 1250 break; 1251 case AFNUM_INET6: 1252 if (subobj_len < 20) 1253 return -1; 1254 ND_PRINT((ndo, "%s UNI IPv6 TNA address: %s", 1255 ident, ip6addr_string(ndo, obj_tptr + 4))); 1256 break; 1257 case AFNUM_NSAP: 1258 if (subobj_len) { 1259 /* unless we have a TLV parser lets just hexdump */ 1260 hexdump=TRUE; 1261 } 1262 break; 1263 } 1264 break; 1265 1266 case RSVP_GEN_UNI_SUBOBJ_DIVERSITY: 1267 if (subobj_len) { 1268 /* unless we have a TLV parser lets just hexdump */ 1269 hexdump=TRUE; 1270 } 1271 break; 1272 1273 case RSVP_GEN_UNI_SUBOBJ_EGRESS_LABEL: 1274 if (subobj_len < 16) { 1275 return -1; 1276 } 1277 1278 ND_PRINT((ndo, "%s U-bit: %x, Label type: %u, Logical port id: %u, Label: %u", 1279 ident, 1280 ((EXTRACT_32BITS(obj_tptr+4))>>31), 1281 ((EXTRACT_32BITS(obj_tptr+4))&0xFF), 1282 EXTRACT_32BITS(obj_tptr+8), 1283 EXTRACT_32BITS(obj_tptr + 12))); 1284 break; 1285 1286 case RSVP_GEN_UNI_SUBOBJ_SERVICE_LEVEL: 1287 if (subobj_len < 8) { 1288 return -1; 1289 } 1290 1291 ND_PRINT((ndo, "%s Service level: %u", 1292 ident, (EXTRACT_32BITS(obj_tptr + 4)) >> 24)); 1293 break; 1294 1295 default: 1296 hexdump=TRUE; 1297 break; 1298 } 1299 total_subobj_len-=subobj_len; 1300 obj_tptr+=subobj_len; 1301 obj_tlen+=subobj_len; 1302 } 1303 1304 if (total_subobj_len) { 1305 /* unless we have a TLV parser lets just hexdump */ 1306 hexdump=TRUE; 1307 } 1308 break; 1309 1310 default: 1311 hexdump=TRUE; 1312 } 1313 break; 1314 1315 case RSVP_OBJ_RSVP_HOP: 1316 switch(rsvp_obj_ctype) { 1317 case RSVP_CTYPE_3: /* fall through - FIXME add TLV parser */ 1318 case RSVP_CTYPE_IPV4: 1319 if (obj_tlen < 8) 1320 return-1; 1321 ND_PRINT((ndo, "%s Previous/Next Interface: %s, Logical Interface Handle: 0x%08x", 1322 ident, 1323 ipaddr_string(ndo, obj_tptr), 1324 EXTRACT_32BITS(obj_tptr + 4))); 1325 obj_tlen-=8; 1326 obj_tptr+=8; 1327 if (obj_tlen) 1328 hexdump=TRUE; /* unless we have a TLV parser lets just hexdump */ 1329 break; 1330 case RSVP_CTYPE_4: /* fall through - FIXME add TLV parser */ 1331 case RSVP_CTYPE_IPV6: 1332 if (obj_tlen < 20) 1333 return-1; 1334 ND_PRINT((ndo, "%s Previous/Next Interface: %s, Logical Interface Handle: 0x%08x", 1335 ident, 1336 ip6addr_string(ndo, obj_tptr), 1337 EXTRACT_32BITS(obj_tptr + 16))); 1338 obj_tlen-=20; 1339 obj_tptr+=20; 1340 hexdump=TRUE; /* unless we have a TLV parser lets just hexdump */ 1341 break; 1342 default: 1343 hexdump=TRUE; 1344 } 1345 break; 1346 1347 case RSVP_OBJ_TIME_VALUES: 1348 switch(rsvp_obj_ctype) { 1349 case RSVP_CTYPE_1: 1350 if (obj_tlen < 4) 1351 return-1; 1352 ND_PRINT((ndo, "%s Refresh Period: %ums", 1353 ident, 1354 EXTRACT_32BITS(obj_tptr))); 1355 obj_tlen-=4; 1356 obj_tptr+=4; 1357 break; 1358 default: 1359 hexdump=TRUE; 1360 } 1361 break; 1362 1363 /* those three objects do share the same semantics */ 1364 case RSVP_OBJ_SENDER_TSPEC: 1365 case RSVP_OBJ_ADSPEC: 1366 case RSVP_OBJ_FLOWSPEC: 1367 switch(rsvp_obj_ctype) { 1368 case RSVP_CTYPE_2: 1369 if (obj_tlen < 4) 1370 return-1; 1371 ND_PRINT((ndo, "%s Msg-Version: %u, length: %u", 1372 ident, 1373 (*obj_tptr & 0xf0) >> 4, 1374 EXTRACT_16BITS(obj_tptr + 2) << 2)); 1375 obj_tptr+=4; /* get to the start of the service header */ 1376 obj_tlen-=4; 1377 1378 while (obj_tlen >= 4) { 1379 intserv_serv_tlen=EXTRACT_16BITS(obj_tptr+2)<<2; 1380 ND_PRINT((ndo, "%s Service Type: %s (%u), break bit %s set, Service length: %u", 1381 ident, 1382 tok2str(rsvp_intserv_service_type_values,"unknown",*(obj_tptr)), 1383 *(obj_tptr), 1384 (*(obj_tptr+1)&0x80) ? "" : "not", 1385 intserv_serv_tlen)); 1386 1387 obj_tptr+=4; /* get to the start of the parameter list */ 1388 obj_tlen-=4; 1389 1390 while (intserv_serv_tlen>=4) { 1391 processed = rsvp_intserv_print(ndo, obj_tptr, obj_tlen); 1392 if (processed == 0) 1393 break; 1394 obj_tlen-=processed; 1395 intserv_serv_tlen-=processed; 1396 obj_tptr+=processed; 1397 } 1398 } 1399 break; 1400 default: 1401 hexdump=TRUE; 1402 } 1403 break; 1404 1405 case RSVP_OBJ_FILTERSPEC: 1406 switch(rsvp_obj_ctype) { 1407 case RSVP_CTYPE_IPV4: 1408 if (obj_tlen < 8) 1409 return-1; 1410 ND_PRINT((ndo, "%s Source Address: %s, Source Port: %u", 1411 ident, 1412 ipaddr_string(ndo, obj_tptr), 1413 EXTRACT_16BITS(obj_tptr + 6))); 1414 obj_tlen-=8; 1415 obj_tptr+=8; 1416 break; 1417 case RSVP_CTYPE_IPV6: 1418 if (obj_tlen < 20) 1419 return-1; 1420 ND_PRINT((ndo, "%s Source Address: %s, Source Port: %u", 1421 ident, 1422 ip6addr_string(ndo, obj_tptr), 1423 EXTRACT_16BITS(obj_tptr + 18))); 1424 obj_tlen-=20; 1425 obj_tptr+=20; 1426 break; 1427 case RSVP_CTYPE_3: 1428 if (obj_tlen < 20) 1429 return-1; 1430 ND_PRINT((ndo, "%s Source Address: %s, Flow Label: %u", 1431 ident, 1432 ip6addr_string(ndo, obj_tptr), 1433 EXTRACT_24BITS(obj_tptr + 17))); 1434 obj_tlen-=20; 1435 obj_tptr+=20; 1436 break; 1437 case RSVP_CTYPE_TUNNEL_IPV6: 1438 if (obj_tlen < 20) 1439 return-1; 1440 ND_PRINT((ndo, "%s Source Address: %s, LSP-ID: 0x%04x", 1441 ident, 1442 ipaddr_string(ndo, obj_tptr), 1443 EXTRACT_16BITS(obj_tptr + 18))); 1444 obj_tlen-=20; 1445 obj_tptr+=20; 1446 break; 1447 case RSVP_CTYPE_13: /* IPv6 p2mp LSP tunnel */ 1448 if (obj_tlen < 40) 1449 return-1; 1450 ND_PRINT((ndo, "%s IPv6 Tunnel Sender Address: %s, LSP ID: 0x%04x" 1451 "%s Sub-Group Originator ID: %s, Sub-Group ID: 0x%04x", 1452 ident, 1453 ip6addr_string(ndo, obj_tptr), 1454 EXTRACT_16BITS(obj_tptr+18), 1455 ident, 1456 ip6addr_string(ndo, obj_tptr+20), 1457 EXTRACT_16BITS(obj_tptr + 38))); 1458 obj_tlen-=40; 1459 obj_tptr+=40; 1460 break; 1461 case RSVP_CTYPE_TUNNEL_IPV4: 1462 if (obj_tlen < 8) 1463 return-1; 1464 ND_PRINT((ndo, "%s Source Address: %s, LSP-ID: 0x%04x", 1465 ident, 1466 ipaddr_string(ndo, obj_tptr), 1467 EXTRACT_16BITS(obj_tptr + 6))); 1468 obj_tlen-=8; 1469 obj_tptr+=8; 1470 break; 1471 case RSVP_CTYPE_12: /* IPv4 p2mp LSP tunnel */ 1472 if (obj_tlen < 16) 1473 return-1; 1474 ND_PRINT((ndo, "%s IPv4 Tunnel Sender Address: %s, LSP ID: 0x%04x" 1475 "%s Sub-Group Originator ID: %s, Sub-Group ID: 0x%04x", 1476 ident, 1477 ipaddr_string(ndo, obj_tptr), 1478 EXTRACT_16BITS(obj_tptr+6), 1479 ident, 1480 ipaddr_string(ndo, obj_tptr+8), 1481 EXTRACT_16BITS(obj_tptr + 12))); 1482 obj_tlen-=16; 1483 obj_tptr+=16; 1484 break; 1485 default: 1486 hexdump=TRUE; 1487 } 1488 break; 1489 1490 case RSVP_OBJ_FASTREROUTE: 1491 /* the differences between c-type 1 and 7 are minor */ 1492 obj_ptr.rsvp_obj_frr = (const struct rsvp_obj_frr_t *)obj_tptr; 1493 1494 switch(rsvp_obj_ctype) { 1495 case RSVP_CTYPE_1: /* new style */ 1496 if (obj_tlen < sizeof(struct rsvp_obj_frr_t)) 1497 return-1; 1498 bw.i = EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->bandwidth); 1499 ND_PRINT((ndo, "%s Setup Priority: %u, Holding Priority: %u, Hop-limit: %u, Bandwidth: %.10g Mbps", 1500 ident, 1501 (int)obj_ptr.rsvp_obj_frr->setup_prio, 1502 (int)obj_ptr.rsvp_obj_frr->hold_prio, 1503 (int)obj_ptr.rsvp_obj_frr->hop_limit, 1504 bw.f * 8 / 1000000)); 1505 ND_PRINT((ndo, "%s Include-any: 0x%08x, Exclude-any: 0x%08x, Include-all: 0x%08x", 1506 ident, 1507 EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->include_any), 1508 EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->exclude_any), 1509 EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->include_all))); 1510 obj_tlen-=sizeof(struct rsvp_obj_frr_t); 1511 obj_tptr+=sizeof(struct rsvp_obj_frr_t); 1512 break; 1513 1514 case RSVP_CTYPE_TUNNEL_IPV4: /* old style */ 1515 if (obj_tlen < 16) 1516 return-1; 1517 bw.i = EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->bandwidth); 1518 ND_PRINT((ndo, "%s Setup Priority: %u, Holding Priority: %u, Hop-limit: %u, Bandwidth: %.10g Mbps", 1519 ident, 1520 (int)obj_ptr.rsvp_obj_frr->setup_prio, 1521 (int)obj_ptr.rsvp_obj_frr->hold_prio, 1522 (int)obj_ptr.rsvp_obj_frr->hop_limit, 1523 bw.f * 8 / 1000000)); 1524 ND_PRINT((ndo, "%s Include Colors: 0x%08x, Exclude Colors: 0x%08x", 1525 ident, 1526 EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->include_any), 1527 EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->exclude_any))); 1528 obj_tlen-=16; 1529 obj_tptr+=16; 1530 break; 1531 1532 default: 1533 hexdump=TRUE; 1534 } 1535 break; 1536 1537 case RSVP_OBJ_DETOUR: 1538 switch(rsvp_obj_ctype) { 1539 case RSVP_CTYPE_TUNNEL_IPV4: 1540 while(obj_tlen >= 8) { 1541 ND_PRINT((ndo, "%s PLR-ID: %s, Avoid-Node-ID: %s", 1542 ident, 1543 ipaddr_string(ndo, obj_tptr), 1544 ipaddr_string(ndo, obj_tptr + 4))); 1545 obj_tlen-=8; 1546 obj_tptr+=8; 1547 } 1548 break; 1549 default: 1550 hexdump=TRUE; 1551 } 1552 break; 1553 1554 case RSVP_OBJ_CLASSTYPE: 1555 case RSVP_OBJ_CLASSTYPE_OLD: /* fall through */ 1556 switch(rsvp_obj_ctype) { 1557 case RSVP_CTYPE_1: 1558 ND_TCHECK_32BITS(obj_tptr); 1559 ND_PRINT((ndo, "%s CT: %u", 1560 ident, 1561 EXTRACT_32BITS(obj_tptr) & 0x7)); 1562 obj_tlen-=4; 1563 obj_tptr+=4; 1564 break; 1565 default: 1566 hexdump=TRUE; 1567 } 1568 break; 1569 1570 case RSVP_OBJ_ERROR_SPEC: 1571 switch(rsvp_obj_ctype) { 1572 case RSVP_CTYPE_3: /* fall through - FIXME add TLV parser */ 1573 case RSVP_CTYPE_IPV4: 1574 if (obj_tlen < 8) 1575 return-1; 1576 error_code=*(obj_tptr+5); 1577 error_value=EXTRACT_16BITS(obj_tptr+6); 1578 ND_PRINT((ndo, "%s Error Node Address: %s, Flags: [0x%02x]%s Error Code: %s (%u)", 1579 ident, 1580 ipaddr_string(ndo, obj_tptr), 1581 *(obj_tptr+4), 1582 ident, 1583 tok2str(rsvp_obj_error_code_values,"unknown",error_code), 1584 error_code)); 1585 switch (error_code) { 1586 case RSVP_OBJ_ERROR_SPEC_CODE_ROUTING: 1587 ND_PRINT((ndo, ", Error Value: %s (%u)", 1588 tok2str(rsvp_obj_error_code_routing_values,"unknown",error_value), 1589 error_value)); 1590 break; 1591 case RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE: /* fall through */ 1592 case RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE_OLD: 1593 ND_PRINT((ndo, ", Error Value: %s (%u)", 1594 tok2str(rsvp_obj_error_code_diffserv_te_values,"unknown",error_value), 1595 error_value)); 1596 break; 1597 default: 1598 ND_PRINT((ndo, ", Unknown Error Value (%u)", error_value)); 1599 break; 1600 } 1601 obj_tlen-=8; 1602 obj_tptr+=8; 1603 break; 1604 case RSVP_CTYPE_4: /* fall through - FIXME add TLV parser */ 1605 case RSVP_CTYPE_IPV6: 1606 if (obj_tlen < 20) 1607 return-1; 1608 error_code=*(obj_tptr+17); 1609 error_value=EXTRACT_16BITS(obj_tptr+18); 1610 ND_PRINT((ndo, "%s Error Node Address: %s, Flags: [0x%02x]%s Error Code: %s (%u)", 1611 ident, 1612 ip6addr_string(ndo, obj_tptr), 1613 *(obj_tptr+16), 1614 ident, 1615 tok2str(rsvp_obj_error_code_values,"unknown",error_code), 1616 error_code)); 1617 1618 switch (error_code) { 1619 case RSVP_OBJ_ERROR_SPEC_CODE_ROUTING: 1620 ND_PRINT((ndo, ", Error Value: %s (%u)", 1621 tok2str(rsvp_obj_error_code_routing_values,"unknown",error_value), 1622 error_value)); 1623 break; 1624 default: 1625 break; 1626 } 1627 obj_tlen-=20; 1628 obj_tptr+=20; 1629 break; 1630 default: 1631 hexdump=TRUE; 1632 } 1633 break; 1634 1635 case RSVP_OBJ_PROPERTIES: 1636 switch(rsvp_obj_ctype) { 1637 case RSVP_CTYPE_1: 1638 if (obj_tlen < 4) 1639 return-1; 1640 padbytes = EXTRACT_16BITS(obj_tptr+2); 1641 ND_PRINT((ndo, "%s TLV count: %u, padding bytes: %u", 1642 ident, 1643 EXTRACT_16BITS(obj_tptr), 1644 padbytes)); 1645 obj_tlen-=4; 1646 obj_tptr+=4; 1647 /* loop through as long there is anything longer than the TLV header (2) */ 1648 while(obj_tlen >= 2 + padbytes) { 1649 ND_PRINT((ndo, "%s %s TLV (0x%02x), length: %u", /* length includes header */ 1650 ident, 1651 tok2str(rsvp_obj_prop_tlv_values,"unknown",*obj_tptr), 1652 *obj_tptr, 1653 *(obj_tptr + 1))); 1654 if (obj_tlen < *(obj_tptr+1)) 1655 return-1; 1656 if (*(obj_tptr+1) < 2) 1657 return -1; 1658 print_unknown_data(ndo, obj_tptr + 2, "\n\t\t", *(obj_tptr + 1) - 2); 1659 obj_tlen-=*(obj_tptr+1); 1660 obj_tptr+=*(obj_tptr+1); 1661 } 1662 break; 1663 default: 1664 hexdump=TRUE; 1665 } 1666 break; 1667 1668 case RSVP_OBJ_MESSAGE_ID: /* fall through */ 1669 case RSVP_OBJ_MESSAGE_ID_ACK: /* fall through */ 1670 case RSVP_OBJ_MESSAGE_ID_LIST: 1671 switch(rsvp_obj_ctype) { 1672 case RSVP_CTYPE_1: 1673 case RSVP_CTYPE_2: 1674 if (obj_tlen < 8) 1675 return-1; 1676 ND_PRINT((ndo, "%s Flags [0x%02x], epoch: %u", 1677 ident, 1678 *obj_tptr, 1679 EXTRACT_24BITS(obj_tptr + 1))); 1680 obj_tlen-=4; 1681 obj_tptr+=4; 1682 /* loop through as long there are no messages left */ 1683 while(obj_tlen >= 4) { 1684 ND_PRINT((ndo, "%s Message-ID 0x%08x (%u)", 1685 ident, 1686 EXTRACT_32BITS(obj_tptr), 1687 EXTRACT_32BITS(obj_tptr))); 1688 obj_tlen-=4; 1689 obj_tptr+=4; 1690 } 1691 break; 1692 default: 1693 hexdump=TRUE; 1694 } 1695 break; 1696 1697 case RSVP_OBJ_INTEGRITY: 1698 switch(rsvp_obj_ctype) { 1699 case RSVP_CTYPE_1: 1700 if (obj_tlen < sizeof(struct rsvp_obj_integrity_t)) 1701 return-1; 1702 obj_ptr.rsvp_obj_integrity = (const struct rsvp_obj_integrity_t *)obj_tptr; 1703 ND_PRINT((ndo, "%s Key-ID 0x%04x%08x, Sequence 0x%08x%08x, Flags [%s]", 1704 ident, 1705 EXTRACT_16BITS(obj_ptr.rsvp_obj_integrity->key_id), 1706 EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->key_id+2), 1707 EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->sequence), 1708 EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->sequence+4), 1709 bittok2str(rsvp_obj_integrity_flag_values, 1710 "none", 1711 obj_ptr.rsvp_obj_integrity->flags))); 1712 ND_PRINT((ndo, "%s MD5-sum 0x%08x%08x%08x%08x ", 1713 ident, 1714 EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest), 1715 EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest+4), 1716 EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest+8), 1717 EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest + 12))); 1718 1719 sigcheck = signature_verify(ndo, pptr, plen, 1720 obj_ptr.rsvp_obj_integrity->digest, 1721 rsvp_clear_checksum, 1722 rsvp_com_header); 1723 ND_PRINT((ndo, " (%s)", tok2str(signature_check_values, "Unknown", sigcheck))); 1724 1725 obj_tlen+=sizeof(struct rsvp_obj_integrity_t); 1726 obj_tptr+=sizeof(struct rsvp_obj_integrity_t); 1727 break; 1728 default: 1729 hexdump=TRUE; 1730 } 1731 break; 1732 1733 case RSVP_OBJ_ADMIN_STATUS: 1734 switch(rsvp_obj_ctype) { 1735 case RSVP_CTYPE_1: 1736 if (obj_tlen < 4) 1737 return-1; 1738 ND_PRINT((ndo, "%s Flags [%s]", ident, 1739 bittok2str(rsvp_obj_admin_status_flag_values, "none", 1740 EXTRACT_32BITS(obj_tptr)))); 1741 obj_tlen-=4; 1742 obj_tptr+=4; 1743 break; 1744 default: 1745 hexdump=TRUE; 1746 } 1747 break; 1748 1749 case RSVP_OBJ_LABEL_SET: 1750 switch(rsvp_obj_ctype) { 1751 case RSVP_CTYPE_1: 1752 if (obj_tlen < 4) 1753 return-1; 1754 action = (EXTRACT_16BITS(obj_tptr)>>8); 1755 1756 ND_PRINT((ndo, "%s Action: %s (%u), Label type: %u", ident, 1757 tok2str(rsvp_obj_label_set_action_values, "Unknown", action), 1758 action, ((EXTRACT_32BITS(obj_tptr) & 0x7F)))); 1759 1760 switch (action) { 1761 case LABEL_SET_INCLUSIVE_RANGE: 1762 case LABEL_SET_EXCLUSIVE_RANGE: /* fall through */ 1763 1764 /* only a couple of subchannels are expected */ 1765 if (obj_tlen < 12) 1766 return -1; 1767 ND_PRINT((ndo, "%s Start range: %u, End range: %u", ident, 1768 EXTRACT_32BITS(obj_tptr+4), 1769 EXTRACT_32BITS(obj_tptr + 8))); 1770 obj_tlen-=12; 1771 obj_tptr+=12; 1772 break; 1773 1774 default: 1775 obj_tlen-=4; 1776 obj_tptr+=4; 1777 subchannel = 1; 1778 while(obj_tlen >= 4 ) { 1779 ND_PRINT((ndo, "%s Subchannel #%u: %u", ident, subchannel, 1780 EXTRACT_32BITS(obj_tptr))); 1781 obj_tptr+=4; 1782 obj_tlen-=4; 1783 subchannel++; 1784 } 1785 break; 1786 } 1787 break; 1788 default: 1789 hexdump=TRUE; 1790 } 1791 1792 case RSVP_OBJ_S2L: 1793 switch (rsvp_obj_ctype) { 1794 case RSVP_CTYPE_IPV4: 1795 if (obj_tlen < 4) 1796 return-1; 1797 ND_PRINT((ndo, "%s Sub-LSP destination address: %s", 1798 ident, ipaddr_string(ndo, obj_tptr))); 1799 1800 obj_tlen-=4; 1801 obj_tptr+=4; 1802 break; 1803 case RSVP_CTYPE_IPV6: 1804 if (obj_tlen < 16) 1805 return-1; 1806 ND_PRINT((ndo, "%s Sub-LSP destination address: %s", 1807 ident, ip6addr_string(ndo, obj_tptr))); 1808 1809 obj_tlen-=16; 1810 obj_tptr+=16; 1811 break; 1812 default: 1813 hexdump=TRUE; 1814 } 1815 1816 /* 1817 * FIXME those are the defined objects that lack a decoder 1818 * you are welcome to contribute code ;-) 1819 */ 1820 1821 case RSVP_OBJ_SCOPE: 1822 case RSVP_OBJ_POLICY_DATA: 1823 case RSVP_OBJ_ACCEPT_LABEL_SET: 1824 case RSVP_OBJ_PROTECTION: 1825 default: 1826 if (ndo->ndo_vflag <= 1) 1827 print_unknown_data(ndo, obj_tptr, "\n\t ", obj_tlen); /* FIXME indentation */ 1828 break; 1829 } 1830 /* do we also want to see a hex dump ? */ 1831 if (ndo->ndo_vflag > 1 || hexdump == TRUE) 1832 print_unknown_data(ndo, tptr + sizeof(struct rsvp_object_header), "\n\t ", /* FIXME indentation */ 1833 rsvp_obj_len - sizeof(struct rsvp_object_header)); 1834 1835 tptr+=rsvp_obj_len; 1836 tlen-=rsvp_obj_len; 1837 } 1838 return 0; 1839 invalid: 1840 ND_PRINT((ndo, "%s", istr)); 1841 return -1; 1842 trunc: 1843 ND_PRINT((ndo, "\n\t\t")); 1844 ND_PRINT((ndo, "%s", tstr)); 1845 return -1; 1846 } 1847 1848 void 1849 rsvp_print(netdissect_options *ndo, 1850 register const u_char *pptr, register u_int len) 1851 { 1852 const struct rsvp_common_header *rsvp_com_header; 1853 const u_char *tptr; 1854 u_short plen, tlen; 1855 1856 tptr=pptr; 1857 1858 rsvp_com_header = (const struct rsvp_common_header *)pptr; 1859 ND_TCHECK(*rsvp_com_header); 1860 1861 /* 1862 * Sanity checking of the header. 1863 */ 1864 if (RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags) != RSVP_VERSION) { 1865 ND_PRINT((ndo, "ERROR: RSVP version %u packet not supported", 1866 RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags))); 1867 return; 1868 } 1869 1870 /* in non-verbose mode just lets print the basic Message Type*/ 1871 if (ndo->ndo_vflag < 1) { 1872 ND_PRINT((ndo, "RSVPv%u %s Message, length: %u", 1873 RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags), 1874 tok2str(rsvp_msg_type_values, "unknown (%u)",rsvp_com_header->msg_type), 1875 len)); 1876 return; 1877 } 1878 1879 /* ok they seem to want to know everything - lets fully decode it */ 1880 1881 plen = tlen = EXTRACT_16BITS(rsvp_com_header->length); 1882 1883 ND_PRINT((ndo, "\n\tRSVPv%u %s Message (%u), Flags: [%s], length: %u, ttl: %u, checksum: 0x%04x", 1884 RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags), 1885 tok2str(rsvp_msg_type_values, "unknown, type: %u",rsvp_com_header->msg_type), 1886 rsvp_com_header->msg_type, 1887 bittok2str(rsvp_header_flag_values,"none",RSVP_EXTRACT_FLAGS(rsvp_com_header->version_flags)), 1888 tlen, 1889 rsvp_com_header->ttl, 1890 EXTRACT_16BITS(rsvp_com_header->checksum))); 1891 1892 if (tlen < sizeof(const struct rsvp_common_header)) { 1893 ND_PRINT((ndo, "ERROR: common header too short %u < %lu", tlen, 1894 (unsigned long)sizeof(const struct rsvp_common_header))); 1895 return; 1896 } 1897 1898 tptr+=sizeof(const struct rsvp_common_header); 1899 tlen-=sizeof(const struct rsvp_common_header); 1900 1901 switch(rsvp_com_header->msg_type) { 1902 1903 case RSVP_MSGTYPE_BUNDLE: 1904 /* 1905 * Process each submessage in the bundle message. 1906 * Bundle messages may not contain bundle submessages, so we don't 1907 * need to handle bundle submessages specially. 1908 */ 1909 while(tlen > 0) { 1910 const u_char *subpptr=tptr, *subtptr; 1911 u_short subplen, subtlen; 1912 1913 subtptr=subpptr; 1914 1915 rsvp_com_header = (const struct rsvp_common_header *)subpptr; 1916 ND_TCHECK(*rsvp_com_header); 1917 1918 /* 1919 * Sanity checking of the header. 1920 */ 1921 if (RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags) != RSVP_VERSION) { 1922 ND_PRINT((ndo, "ERROR: RSVP version %u packet not supported", 1923 RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags))); 1924 return; 1925 } 1926 1927 subplen = subtlen = EXTRACT_16BITS(rsvp_com_header->length); 1928 1929 ND_PRINT((ndo, "\n\t RSVPv%u %s Message (%u), Flags: [%s], length: %u, ttl: %u, checksum: 0x%04x", 1930 RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags), 1931 tok2str(rsvp_msg_type_values, "unknown, type: %u",rsvp_com_header->msg_type), 1932 rsvp_com_header->msg_type, 1933 bittok2str(rsvp_header_flag_values,"none",RSVP_EXTRACT_FLAGS(rsvp_com_header->version_flags)), 1934 subtlen, 1935 rsvp_com_header->ttl, 1936 EXTRACT_16BITS(rsvp_com_header->checksum))); 1937 1938 if (subtlen < sizeof(const struct rsvp_common_header)) { 1939 ND_PRINT((ndo, "ERROR: common header too short %u < %lu", subtlen, 1940 (unsigned long)sizeof(const struct rsvp_common_header))); 1941 return; 1942 } 1943 1944 if (tlen < subtlen) { 1945 ND_PRINT((ndo, "ERROR: common header too large %u > %u", subtlen, 1946 tlen)); 1947 return; 1948 } 1949 1950 subtptr+=sizeof(const struct rsvp_common_header); 1951 subtlen-=sizeof(const struct rsvp_common_header); 1952 1953 /* 1954 * Print all objects in the submessage. 1955 */ 1956 if (rsvp_obj_print(ndo, subpptr, subplen, subtptr, "\n\t ", subtlen, rsvp_com_header) == -1) 1957 return; 1958 1959 tptr+=subtlen+sizeof(const struct rsvp_common_header); 1960 tlen-=subtlen+sizeof(const struct rsvp_common_header); 1961 } 1962 1963 break; 1964 1965 case RSVP_MSGTYPE_PATH: 1966 case RSVP_MSGTYPE_RESV: 1967 case RSVP_MSGTYPE_PATHERR: 1968 case RSVP_MSGTYPE_RESVERR: 1969 case RSVP_MSGTYPE_PATHTEAR: 1970 case RSVP_MSGTYPE_RESVTEAR: 1971 case RSVP_MSGTYPE_RESVCONF: 1972 case RSVP_MSGTYPE_HELLO_OLD: 1973 case RSVP_MSGTYPE_HELLO: 1974 case RSVP_MSGTYPE_ACK: 1975 case RSVP_MSGTYPE_SREFRESH: 1976 /* 1977 * Print all objects in the message. 1978 */ 1979 if (rsvp_obj_print(ndo, pptr, plen, tptr, "\n\t ", tlen, rsvp_com_header) == -1) 1980 return; 1981 break; 1982 1983 default: 1984 print_unknown_data(ndo, tptr, "\n\t ", tlen); 1985 break; 1986 } 1987 1988 return; 1989 trunc: 1990 ND_PRINT((ndo, "\n\t\t")); 1991 ND_PRINT((ndo, "%s", tstr)); 1992 } 1993