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