2 * Routines for OSPF packet disassembly
3 * (c) Copyright Hannes R. Boehm <hannes@boehm.org>
7 * Added support for OSPF restart signaling:
8 * draft-nguyen-ospf-lls-05.txt
9 * draft-nguyen-ospf-oob-resync-05.txt
10 * draft-nguyen-ospf-restart-05.txt
11 * - (c) 2005 Michael Rozhavsky <mrozhavsky@fortinet.com>
13 * At this time, this module is able to analyze OSPF
14 * packets as specified in RFC2328. MOSPF (RFC1584) and other
15 * OSPF Extensions which introduce new Packet types
16 * (e.g the External Atributes LSA) are not supported.
17 * Furthermore RFC2740 (OSPFv3 - OSPF for IPv6) is now supported
18 * - (c) 2001 Palle Lyckegaard <palle[AT]lyckegaard.dk>
20 * Added support to E-NNI routing (OIF2003.259.02)
21 * - (c) 2004 Roberto Morro <roberto.morro[AT]tilab.com>
23 * TOS - support is not fully implemented
25 * Wireshark - Network traffic analyzer
26 * By Gerald Combs <gerald@wireshark.org>
27 * Copyright 1998 Gerald Combs
29 * This program is free software; you can redistribute it and/or
30 * modify it under the terms of the GNU General Public License
31 * as published by the Free Software Foundation; either version 2
32 * of the License, or (at your option) any later version.
34 * This program is distributed in the hope that it will be useful,
35 * but WITHOUT ANY WARRANTY; without even the implied warranty of
36 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37 * GNU General Public License for more details.
39 * You should have received a copy of the GNU General Public License
40 * along with this program; if not, write to the Free Software
41 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
52 #include <epan/packet.h>
53 #include <epan/ipproto.h>
54 #include <epan/in_cksum.h>
55 #include <epan/emem.h>
56 #include "packet-rsvp.h"
58 #define OSPF_VERSION_2 2
59 #define OSPF_VERSION_3 3
60 #define OSPF_VERSION_2_HEADER_LENGTH 24
61 #define OSPF_VERSION_3_HEADER_LENGTH 16
65 #define OSPF_DB_DESC 2
70 static const value_string pt_vals[] = {
71 {OSPF_HELLO, "Hello Packet" },
72 {OSPF_DB_DESC, "DB Descr." },
73 {OSPF_LS_REQ, "LS Request" },
74 {OSPF_LS_UPD, "LS Update" },
75 {OSPF_LS_ACK, "LS Acknowledge" },
79 #define OSPF_AUTH_NONE 0
80 #define OSPF_AUTH_SIMPLE 1
81 #define OSPF_AUTH_CRYPT 2
83 static const value_string auth_vals[] = {
84 {OSPF_AUTH_NONE, "Null" },
85 {OSPF_AUTH_SIMPLE, "Simple password" },
86 {OSPF_AUTH_CRYPT, "Cryptographic" },
90 #define OSPF_V2_OPTIONS_E 0x02
91 #define OSPF_V2_OPTIONS_MC 0x04
92 #define OSPF_V2_OPTIONS_NP 0x08
93 #define OSPF_V2_OPTIONS_L 0x10
94 #define OSPF_V2_OPTIONS_DC 0x20
95 #define OSPF_V2_OPTIONS_O 0x40
96 #define OSPF_V2_OPTIONS_DN 0x80
97 #define OSPF_V3_OPTIONS_V6 0x01
98 #define OSPF_V3_OPTIONS_E 0x02
99 #define OSPF_V3_OPTIONS_MC 0x04
100 #define OSPF_V3_OPTIONS_N 0x08
101 #define OSPF_V3_OPTIONS_R 0x10
102 #define OSPF_V3_OPTIONS_DC 0x20
104 #define OSPF_LLS_EXT_OPTIONS_LR 0x00000001
105 #define OSPF_LLS_EXT_OPTIONS_RS 0x00000002
107 #define OSPF_DBD_FLAG_MS 1
108 #define OSPF_DBD_FLAG_M 2
109 #define OSPF_DBD_FLAG_I 4
110 #define OSPF_DBD_FLAG_R 8
112 #define OSPF_LS_REQ_LENGTH 12
114 #define OSPF_LSTYPE_ROUTER 1
115 #define OSPF_LSTYPE_NETWORK 2
116 #define OSPF_LSTYPE_SUMMERY 3
117 #define OSPF_LSTYPE_ASBR 4
118 #define OSPF_LSTYPE_ASEXT 5
119 #define OSPF_LSTYPE_GRPMEMBER 6
120 #define OSPF_LSTYPE_ASEXT7 7
121 #define OSPF_LSTYPE_EXTATTR 8
122 #define OSPF_V3_LSTYPE_ROUTER 0x2001
123 #define OSPF_V3_LSTYPE_NETWORK 0x2002
124 #define OSPF_V3_LSTYPE_INTER_AREA_PREFIX 0x2003
125 #define OSPF_V3_LSTYPE_INTER_AREA_ROUTER 0x2004
126 #define OSPF_V3_LSTYPE_AS_EXTERNAL 0x4005
127 #define OSPF_V3_LSTYPE_GROUP_MEMBERSHIP 0x2006
128 #define OSPF_V3_LSTYPE_TYPE_7 0x2007
129 #define OSPF_V3_LSTYPE_LINK 0x0008
130 #define OSPF_V3_LSTYPE_INTRA_AREA_PREFIX 0x2009
132 /* Opaque LSA types */
133 #define OSPF_LSTYPE_OP_LINKLOCAL 9
134 #define OSPF_LSTYPE_OP_AREALOCAL 10
135 #define OSPF_LSTYPE_OP_ASWIDE 11
137 #define OSPF_LINK_PTP 1
138 #define OSPF_LINK_TRANSIT 2
139 #define OSPF_LINK_STUB 3
140 #define OSPF_LINK_VIRTUAL 4
142 #define OSPF_V3_LINK_PTP 1
143 #define OSPF_V3_LINK_TRANSIT 2
144 #define OSPF_V3_LINK_RESERVED 3
145 #define OSPF_V3_LINK_VIRTUAL 4
147 #define OSPF_LSA_HEADER_LENGTH 20
149 /* Known opaque LSAs */
150 #define OSPF_LSA_MPLS_TE 1
153 static const value_string ls_type_vals[] = {
154 {OSPF_LSTYPE_ROUTER, "Router-LSA" },
155 {OSPF_LSTYPE_NETWORK, "Network-LSA" },
156 {OSPF_LSTYPE_SUMMERY, "Summary-LSA (IP network)" },
157 {OSPF_LSTYPE_ASBR, "Summary-LSA (ASBR)" },
158 {OSPF_LSTYPE_ASEXT, "AS-External-LSA (ASBR)" },
159 {OSPF_LSTYPE_GRPMEMBER, "Group Membership LSA" },
160 {OSPF_LSTYPE_ASEXT7, "NSSA AS-External-LSA" },
161 {OSPF_LSTYPE_EXTATTR, "External Attributes LSA" },
162 {OSPF_LSTYPE_OP_LINKLOCAL, "Opaque LSA, Link-local scope" },
163 {OSPF_LSTYPE_OP_AREALOCAL, "Opaque LSA, Area-local scope" },
168 static const value_string ls_opaque_type_vals[] = {
169 {OSPF_LSA_MPLS_TE, "Traffic Engineering LSA" },
170 {2, "Sycamore Optical Topology Descriptions" },
175 static const value_string v3_ls_type_vals[] = {
176 {OSPF_V3_LSTYPE_ROUTER, "Router-LSA" },
177 {OSPF_V3_LSTYPE_NETWORK, "Network-LSA" },
178 {OSPF_V3_LSTYPE_INTER_AREA_PREFIX, "Inter-Area-Prefix-LSA" },
179 {OSPF_V3_LSTYPE_INTER_AREA_ROUTER, "Inter-Area-Router-LSA" },
180 {OSPF_V3_LSTYPE_AS_EXTERNAL, "AS-External-LSA" },
181 {OSPF_V3_LSTYPE_GROUP_MEMBERSHIP, "Group-Membership-LSA" },
182 {OSPF_V3_LSTYPE_TYPE_7, "Type-LSA" },
183 {OSPF_V3_LSTYPE_LINK, "Link-LSA" },
184 {OSPF_V3_LSTYPE_INTRA_AREA_PREFIX, "Intra-Area-Prefix-LSA" },
189 static const value_string lls_tlv_type_vals[] = {
190 {1, "Extended options TLV" },
191 {2, "Crypo Authentication TLV" },
195 static const value_string mpls_link_stlv_ltype_str[] = {
196 {1, "Point-to-point"},
201 #define OSPF_V2_ROUTER_LSA_FLAG_B 0x01
202 #define OSPF_V2_ROUTER_LSA_FLAG_E 0x02
203 #define OSPF_V2_ROUTER_LSA_FLAG_V 0x04
204 #define OSPF_V3_ROUTER_LSA_FLAG_B 0x01
205 #define OSPF_V3_ROUTER_LSA_FLAG_E 0x02
206 #define OSPF_V3_ROUTER_LSA_FLAG_V 0x04
207 #define OSPF_V3_ROUTER_LSA_FLAG_W 0x08
209 #define OSPF_V3_PREFIX_OPTION_NU 0x01
210 #define OSPF_V3_PREFIX_OPTION_LA 0x02
211 #define OSPF_V3_PREFIX_OPTION_MC 0x04
212 #define OSPF_V3_PREFIX_OPTION_P 0x08
214 #define OSPF_V3_AS_EXTERNAL_FLAG_T 0x01
215 #define OSPF_V3_AS_EXTERNAL_FLAG_F 0x02
216 #define OSPF_V3_AS_EXTERNAL_FLAG_E 0x04
219 static int proto_ospf = -1;
221 static gint ett_ospf = -1;
222 static gint ett_ospf_hdr = -1;
223 static gint ett_ospf_hello = -1;
224 static gint ett_ospf_desc = -1;
225 static gint ett_ospf_lsr = -1;
226 static gint ett_ospf_lsa = -1;
227 static gint ett_ospf_lsa_router_link = -1;
228 static gint ett_ospf_lsa_upd = -1;
229 static gint ett_ospf_v2_options = -1;
230 static gint ett_ospf_v3_options = -1;
231 static gint ett_ospf_dbd = -1;
232 static gint ett_ospf_lls_data_block = -1;
233 static gint ett_ospf_lls_tlv = -1;
234 static gint ett_ospf_lls_ext_options = -1;
235 static gint ett_ospf_v2_router_lsa_flags = -1;
236 static gint ett_ospf_v3_router_lsa_flags = -1;
237 static gint ett_ospf_v3_as_external_flags = -1;
238 static gint ett_ospf_v3_prefix_options = -1;
240 /* Trees for opaque LSAs */
241 static gint ett_ospf_lsa_mpls = -1;
242 static gint ett_ospf_lsa_mpls_router = -1;
243 static gint ett_ospf_lsa_mpls_link = -1;
244 static gint ett_ospf_lsa_mpls_link_stlv = -1;
245 static gint ett_ospf_lsa_mpls_link_stlv_admingrp = -1;
246 static gint ett_ospf_lsa_oif_tna = -1;
247 static gint ett_ospf_lsa_oif_tna_stlv = -1;
251 static const true_false_string tfs_v2_options_dc = {
252 "Demand Circuits are supported",
253 "Demand circuits are NOT supported"
255 static const true_false_string tfs_v2_options_l = {
256 "The packet contains LLS data block",
257 "The packet does NOT contain LLS data block"
259 static const true_false_string tfs_v2_options_np = {
261 "Nssa is NOT supported"
263 static const true_false_string tfs_v2_options_mc = {
265 "NOT multicast capable"
267 static const true_false_string tfs_v2_options_e = {
268 "ExternalRoutingCapability",
269 "NO ExternalRoutingCapability"
271 static const true_false_string tfs_v2_options_o = {
275 static const true_false_string tfs_v2_options_dn = {
279 static const true_false_string tfs_v3_options_v6 = {
283 static const true_false_string tfs_v3_options_e = {
287 static const true_false_string tfs_v3_options_mc = {
291 static const true_false_string tfs_v3_options_n = {
295 static const true_false_string tfs_v3_options_r = {
299 static const true_false_string tfs_v3_options_dc = {
303 static const true_false_string tfs_dbd_i = {
305 "Init bit is NOT set"
307 static const true_false_string tfs_dbd_m = {
309 "More bit is NOT set"
311 static const true_false_string tfs_dbd_ms = {
312 "Master/Slave bit is SET",
313 "Master/Slave bit is NOT set"
315 static const true_false_string tfs_dbd_r = {
316 "OOBResync bit is SET",
317 "OOBResync bit is NOT set"
319 static const true_false_string tfs_lls_ext_options_lr = {
320 "LSDB Resynchrinization (LR-bit) is SET",
321 "LSDB Resynchrinization (LR-bit) is NOT set"
323 static const true_false_string tfs_lls_ext_options_rs = {
324 "Restart Signal (RS-bit) is SET",
325 "Restart Signal (RS-bit) is NOT set"
327 static const true_false_string tfs_v2_router_lsa_flags_b = {
328 "Area border router",
329 "NO Area border router"
331 static const true_false_string tfs_v2_router_lsa_flags_e = {
332 "AS boundary router",
333 "NO AS boundary router"
335 static const true_false_string tfs_v2_router_lsa_flags_v = {
336 "Virtual link endpoint",
337 "NO Virtual link endpoint"
339 static const true_false_string tfs_v3_router_lsa_flags_b = {
340 "Area border router",
341 "NO Area border router"
343 static const true_false_string tfs_v3_router_lsa_flags_e = {
344 "AS boundary router",
345 "NO AS boundary router"
347 static const true_false_string tfs_v3_router_lsa_flags_v = {
348 "Virtual link endpoint",
349 "NO Virtual link endpoint"
351 static const true_false_string tfs_v3_router_lsa_flags_w = {
352 "Wild-card multicast receiver",
353 "NO Wild-card multicast receiver"
355 static const true_false_string tfs_v3_as_external_flags_t = {
356 "External Route Tag is included",
357 "External Route Tag is NOT included"
359 static const true_false_string tfs_v3_as_external_flags_f = {
360 "Forwarding Address is included",
361 "Forwarding Address is NOT included"
363 static const true_false_string tfs_v3_as_external_flags_e = {
364 "Type 2 external metric",
365 "Type 1 external metric"
367 static const true_false_string tfs_v3_prefix_options_nu = {
368 "NoUnicast capability bit is SET",
369 "NoUnicast capability bit is NOT set"
371 static const true_false_string tfs_v3_prefix_options_la = {
372 "LocalAddress capability bit is SET",
373 "LocalAddress capability bit is NOT set"
375 static const true_false_string tfs_v3_prefix_options_mc = {
376 "Multicast capability bit is SET",
377 "Multicast capability bit is NOT set"
379 static const true_false_string tfs_v3_prefix_options_p = {
380 "Propagate bit is SET",
381 "Propagate bit is NOT set"
384 /*-----------------------------------------------------------------------
386 *-----------------------------------------------------------------------*/
388 /* The OSPF filtering keys */
401 OSPFF_LS_OPAQUE_TYPE,
403 OSPFF_LS_MPLS_TE_INSTANCE,
419 OSPFF_LS_MPLS_ROUTERID,
421 OSPFF_LS_MPLS_LINKTYPE,
422 OSPFF_LS_MPLS_LINKID,
423 OSPFF_LS_MPLS_LOCAL_ADDR,
424 OSPFF_LS_MPLS_REMOTE_ADDR,
425 OSPFF_LS_MPLS_LOCAL_IFID,
426 OSPFF_LS_MPLS_REMOTE_IFID,
427 OSPFF_LS_MPLS_LINKCOLOR,
449 OSPFF_LLS_EXT_OPTIONS,
450 OSPFF_LLS_EXT_OPTIONS_LR,
451 OSPFF_LLS_EXT_OPTIONS_RS,
452 OSPFF_V2_ROUTER_LSA_FLAG,
453 OSPFF_V2_ROUTER_LSA_FLAG_B,
454 OSPFF_V2_ROUTER_LSA_FLAG_E,
455 OSPFF_V2_ROUTER_LSA_FLAG_V,
456 OSPFF_V3_ROUTER_LSA_FLAG,
457 OSPFF_V3_ROUTER_LSA_FLAG_B,
458 OSPFF_V3_ROUTER_LSA_FLAG_E,
459 OSPFF_V3_ROUTER_LSA_FLAG_V,
460 OSPFF_V3_ROUTER_LSA_FLAG_W,
461 OSPFF_V3_AS_EXTERNAL_FLAG,
462 OSPFF_V3_AS_EXTERNAL_FLAG_T,
463 OSPFF_V3_AS_EXTERNAL_FLAG_F,
464 OSPFF_V3_AS_EXTERNAL_FLAG_E,
465 OSPFF_V3_PREFIX_OPTION,
466 OSPFF_V3_PREFIX_OPTION_NU,
467 OSPFF_V3_PREFIX_OPTION_LA,
468 OSPFF_V3_PREFIX_OPTION_MC,
469 OSPFF_V3_PREFIX_OPTION_P,
474 static int ospf_filter[OSPFF_MAX];
476 static hf_register_info ospff_info[] = {
478 /* Message type number */
479 {&ospf_filter[OSPFF_MSG_TYPE],
480 { "Message Type", "ospf.msg", FT_UINT8, BASE_DEC, VALS(pt_vals), 0x0,
484 {&ospf_filter[OSPFF_MSG_HELLO],
485 { "Hello", "ospf.msg.hello", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
487 {&ospf_filter[OSPFF_MSG_DB_DESC],
488 { "Database Description", "ospf.msg.dbdesc", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
490 {&ospf_filter[OSPFF_MSG_LS_REQ],
491 { "Link State Adv Request", "ospf.msg.lsreq", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
493 {&ospf_filter[OSPFF_MSG_LS_UPD],
494 { "Link State Adv Update", "ospf.msg.lsupdate", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
496 {&ospf_filter[OSPFF_MSG_LS_ACK],
497 { "Link State Adv Acknowledgement", "ospf.msg.lsack", FT_BOOLEAN,
498 BASE_NONE, NULL, 0x0, "", HFILL }},
503 {&ospf_filter[OSPFF_LS_TYPE],
504 { "Link-State Advertisement Type", "ospf.lsa", FT_UINT8, BASE_DEC,
505 VALS(ls_type_vals), 0x0, "", HFILL }},
506 {&ospf_filter[OSPFF_LS_OPAQUE_TYPE],
507 { "Link State ID Opaque Type", "ospf.lsid_opaque_type", FT_UINT8, BASE_DEC,
508 VALS(ls_opaque_type_vals), 0x0, "", HFILL }},
510 {&ospf_filter[OSPFF_LS_MPLS_TE_INSTANCE],
511 { "Link State ID TE-LSA Instance", "ospf.lsid_te_lsa.instance", FT_UINT16, BASE_DEC,
512 NULL, 0x0, "", HFILL }},
514 {&ospf_filter[OSPFF_LS_ROUTER],
515 { "Router LSA", "ospf.lsa.router", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
517 {&ospf_filter[OSPFF_LS_NETWORK],
518 { "Network LSA", "ospf.lsa.network", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
520 {&ospf_filter[OSPFF_LS_SUMMARY],
521 { "Summary LSA (IP Network)", "ospf.lsa.summary", FT_BOOLEAN, BASE_NONE,
522 NULL, 0x0, "", HFILL }},
523 {&ospf_filter[OSPFF_LS_ASBR],
524 { "Summary LSA (ASBR)", "ospf.lsa.asbr", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
526 {&ospf_filter[OSPFF_LS_ASEXT],
527 { "AS-External LSA (ASBR)", "ospf.lsa.asext", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
529 {&ospf_filter[OSPFF_LS_GRPMEMBER],
530 { "Group Membership LSA", "ospf.lsa.member", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
532 {&ospf_filter[OSPFF_LS_ASEXT7],
533 { "NSSA AS-External LSA", "ospf.lsa.nssa", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
535 {&ospf_filter[OSPFF_LS_EXTATTR],
536 { "External Attributes LSA", "ospf.lsa.attr", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
538 {&ospf_filter[OSPFF_LS_OPAQUE],
539 { "Opaque LSA", "ospf.lsa.opaque", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
542 /* Other interesting OSPF values */
544 {&ospf_filter[OSPFF_SRC_ROUTER],
545 { "Source OSPF Router", "ospf.srcrouter", FT_IPv4, BASE_NONE, NULL, 0x0,
548 {&ospf_filter[OSPFF_ADV_ROUTER],
549 { "Advertising Router", "ospf.advrouter", FT_IPv4, BASE_NONE, NULL, 0x0,
552 {&ospf_filter[OSPFF_LS_MPLS],
553 { "MPLS Traffic Engineering LSA", "ospf.lsa.mpls", FT_BOOLEAN,
554 BASE_NONE, NULL, 0x0, "", HFILL }},
556 {&ospf_filter[OSPFF_LS_MPLS_ROUTERID],
557 { "MPLS/TE Router ID", "ospf.mpls.routerid", FT_IPv4, BASE_NONE, NULL, 0x0,
560 {&ospf_filter[OSPFF_LS_MPLS_LINKTYPE],
561 { "MPLS/TE Link Type", "ospf.mpls.linktype", FT_UINT8, BASE_DEC, VALS(mpls_link_stlv_ltype_str), 0x0,
562 "MPLS/TE Link Type", HFILL }},
563 {&ospf_filter[OSPFF_LS_MPLS_LINKID],
564 { "MPLS/TE Link ID", "ospf.mpls.linkid", FT_IPv4, BASE_NONE, NULL, 0x0,
566 {&ospf_filter[OSPFF_LS_MPLS_LOCAL_ADDR],
567 { "MPLS/TE Local Interface Address", "ospf.mpls.local_addr", FT_IPv4,
568 BASE_NONE, NULL, 0x0, "", HFILL }},
569 {&ospf_filter[OSPFF_LS_MPLS_REMOTE_ADDR],
570 { "MPLS/TE Remote Interface Address", "ospf.mpls.remote_addr", FT_IPv4,
571 BASE_NONE, NULL, 0x0, "", HFILL }},
572 {&ospf_filter[OSPFF_LS_MPLS_LOCAL_IFID],
573 { "MPLS/TE Local Interface Index", "ospf.mpls.local_id", FT_UINT32,
574 BASE_DEC, NULL, 0x0, "", HFILL }},
575 {&ospf_filter[OSPFF_LS_MPLS_REMOTE_IFID],
576 { "MPLS/TE Remote Interface Index", "ospf.mpls.remote_id", FT_UINT32,
577 BASE_DEC, NULL, 0x0, "", HFILL }},
578 {&ospf_filter[OSPFF_LS_MPLS_LINKCOLOR],
579 { "MPLS/TE Link Resource Class/Color", "ospf.mpls.linkcolor", FT_UINT32,
580 BASE_HEX, NULL, 0x0, "MPLS/TE Link Resource Class/Color", HFILL }},
582 {&ospf_filter[OSPFF_V2_OPTIONS],
583 { "Options", "ospf.v2.options", FT_UINT8, BASE_HEX,
584 NULL, 0x0, "", HFILL }},
585 {&ospf_filter[OSPFF_V2_OPTIONS_E],
586 { "E", "ospf.v2.options.e", FT_BOOLEAN, 8,
587 TFS(&tfs_v2_options_e), OSPF_V2_OPTIONS_E, "", HFILL }},
588 {&ospf_filter[OSPFF_V2_OPTIONS_MC],
589 { "MC", "ospf.v2.options.mc", FT_BOOLEAN, 8,
590 TFS(&tfs_v2_options_mc), OSPF_V2_OPTIONS_MC, "", HFILL }},
591 {&ospf_filter[OSPFF_V2_OPTIONS_NP],
592 { "NP", "ospf.v2.options.np", FT_BOOLEAN, 8,
593 TFS(&tfs_v2_options_np), OSPF_V2_OPTIONS_NP, "", HFILL }},
594 {&ospf_filter[OSPFF_V2_OPTIONS_L],
595 { "L", "ospf.v2.options.l", FT_BOOLEAN, 8,
596 TFS(&tfs_v2_options_l), OSPF_V2_OPTIONS_L, "", HFILL }},
597 {&ospf_filter[OSPFF_V2_OPTIONS_DC],
598 { "DC", "ospf.v2.options.dc", FT_BOOLEAN, 8,
599 TFS(&tfs_v2_options_dc), OSPF_V2_OPTIONS_DC, "", HFILL }},
600 {&ospf_filter[OSPFF_V2_OPTIONS_O],
601 { "O", "ospf.v2.options.o", FT_BOOLEAN, 8,
602 TFS(&tfs_v2_options_o), OSPF_V2_OPTIONS_O, "", HFILL }},
603 {&ospf_filter[OSPFF_V2_OPTIONS_DN],
604 { "DN", "ospf.v2.options.dn", FT_BOOLEAN, 8,
605 TFS(&tfs_v2_options_dn), OSPF_V2_OPTIONS_DN, "", HFILL }},
606 {&ospf_filter[OSPFF_V3_OPTIONS],
607 { "Options", "ospf.v3.options", FT_UINT24, BASE_HEX,
608 NULL, 0x0, "", HFILL }},
609 {&ospf_filter[OSPFF_V3_OPTIONS_V6],
610 { "V6", "ospf.v3.options.v6", FT_BOOLEAN, 24,
611 TFS(&tfs_v3_options_v6), OSPF_V3_OPTIONS_V6, "", HFILL }},
612 {&ospf_filter[OSPFF_V3_OPTIONS_E],
613 { "E", "ospf.v3.options.e", FT_BOOLEAN, 24,
614 TFS(&tfs_v3_options_e), OSPF_V3_OPTIONS_E, "", HFILL }},
615 {&ospf_filter[OSPFF_V3_OPTIONS_MC],
616 { "MC", "ospf.v3.options.mc", FT_BOOLEAN, 24,
617 TFS(&tfs_v3_options_mc), OSPF_V3_OPTIONS_MC, "", HFILL }},
618 {&ospf_filter[OSPFF_V3_OPTIONS_N],
619 { "N", "ospf.v3.options.n", FT_BOOLEAN, 24,
620 TFS(&tfs_v3_options_n), OSPF_V3_OPTIONS_N, "", HFILL }},
621 {&ospf_filter[OSPFF_V3_OPTIONS_R],
622 { "R", "ospf.v3.options.r", FT_BOOLEAN, 24,
623 TFS(&tfs_v3_options_r), OSPF_V3_OPTIONS_R, "", HFILL }},
624 {&ospf_filter[OSPFF_V3_OPTIONS_DC],
625 { "DC", "ospf.v3.options.dc", FT_BOOLEAN, 24,
626 TFS(&tfs_v3_options_dc), OSPF_V3_OPTIONS_DC, "", HFILL }},
627 {&ospf_filter[OSPFF_DBD],
628 { "DB Description", "ospf.dbd", FT_UINT8, BASE_HEX,
629 NULL, 0x0, "", HFILL }},
630 {&ospf_filter[OSPFF_DBD_R],
631 { "R", "ospf.dbd.r", FT_BOOLEAN, 8,
632 TFS(&tfs_dbd_r), OSPF_DBD_FLAG_R, "", HFILL }},
633 {&ospf_filter[OSPFF_DBD_I],
634 { "I", "ospf.dbd.i", FT_BOOLEAN, 8,
635 TFS(&tfs_dbd_i), OSPF_DBD_FLAG_I, "", HFILL }},
636 {&ospf_filter[OSPFF_DBD_M],
637 { "M", "ospf.dbd.m", FT_BOOLEAN, 8,
638 TFS(&tfs_dbd_m), OSPF_DBD_FLAG_M, "", HFILL }},
639 {&ospf_filter[OSPFF_DBD_MS],
640 { "MS", "ospf.dbd.ms", FT_BOOLEAN, 8,
641 TFS(&tfs_dbd_ms), OSPF_DBD_FLAG_MS, "", HFILL }},
642 {&ospf_filter[OSPFF_LLS_EXT_OPTIONS],
643 { "Options", "ospf.lls.ext.options", FT_UINT32, BASE_HEX,
644 NULL, 0x0, "", HFILL }},
645 {&ospf_filter[OSPFF_LLS_EXT_OPTIONS_LR],
646 { "LR", "ospf.lls.ext.options.lr", FT_BOOLEAN, 32,
647 TFS(&tfs_lls_ext_options_lr), OSPF_LLS_EXT_OPTIONS_LR, "", HFILL }},
648 {&ospf_filter[OSPFF_LLS_EXT_OPTIONS_RS],
649 { "RS", "ospf.lls.ext.options.rs", FT_BOOLEAN, 32,
650 TFS(&tfs_lls_ext_options_rs), OSPF_LLS_EXT_OPTIONS_RS, "", HFILL }},
651 {&ospf_filter[OSPFF_V2_ROUTER_LSA_FLAG],
652 { "Flags", "ospf.v2.router.lsa.flags", FT_UINT8, BASE_HEX,
653 NULL, 0x0, "", HFILL }},
654 {&ospf_filter[OSPFF_V2_ROUTER_LSA_FLAG_B],
655 { "B", "ospf.v2.router.lsa.flags.b", FT_BOOLEAN, 8,
656 TFS(&tfs_v2_router_lsa_flags_b), OSPF_V2_ROUTER_LSA_FLAG_B, "", HFILL }},
657 {&ospf_filter[OSPFF_V2_ROUTER_LSA_FLAG_E],
658 { "E", "ospf.v2.router.lsa.flags.e", FT_BOOLEAN, 8,
659 TFS(&tfs_v2_router_lsa_flags_e), OSPF_V2_ROUTER_LSA_FLAG_E, "", HFILL }},
660 {&ospf_filter[OSPFF_V2_ROUTER_LSA_FLAG_V],
661 { "V", "ospf.v2.router.lsa.flags.v", FT_BOOLEAN, 8,
662 TFS(&tfs_v2_router_lsa_flags_v), OSPF_V2_ROUTER_LSA_FLAG_V, "", HFILL }},
663 {&ospf_filter[OSPFF_V3_ROUTER_LSA_FLAG],
664 { "Flags", "ospf.v3.router.lsa.flags", FT_UINT8, BASE_HEX,
665 NULL, 0x0, "", HFILL }},
666 {&ospf_filter[OSPFF_V3_ROUTER_LSA_FLAG_B],
667 { "B", "ospf.v3.router.lsa.flags.b", FT_BOOLEAN, 8,
668 TFS(&tfs_v3_router_lsa_flags_b), OSPF_V3_ROUTER_LSA_FLAG_B, "", HFILL }},
669 {&ospf_filter[OSPFF_V3_ROUTER_LSA_FLAG_E],
670 { "E", "ospf.v3.router.lsa.flags.e", FT_BOOLEAN, 8,
671 TFS(&tfs_v3_router_lsa_flags_e), OSPF_V3_ROUTER_LSA_FLAG_E, "", HFILL }},
672 {&ospf_filter[OSPFF_V3_ROUTER_LSA_FLAG_V],
673 { "V", "ospf.v3.router.lsa.flags.v", FT_BOOLEAN, 8,
674 TFS(&tfs_v3_router_lsa_flags_v), OSPF_V3_ROUTER_LSA_FLAG_V, "", HFILL }},
675 {&ospf_filter[OSPFF_V3_ROUTER_LSA_FLAG_W],
676 { "W", "ospf.v3.router.lsa.flags.w", FT_BOOLEAN, 8,
677 TFS(&tfs_v3_router_lsa_flags_w), OSPF_V3_ROUTER_LSA_FLAG_W, "", HFILL }},
678 {&ospf_filter[OSPFF_V3_AS_EXTERNAL_FLAG],
679 { "Flags", "ospf.v3.as.external.flags", FT_UINT8, BASE_HEX,
680 NULL, 0x0, "", HFILL }},
681 {&ospf_filter[OSPFF_V3_AS_EXTERNAL_FLAG_T],
682 { "T", "ospf.v3.as.external.flags.t", FT_BOOLEAN, 8,
683 TFS(&tfs_v3_as_external_flags_t), OSPF_V3_AS_EXTERNAL_FLAG_T, "", HFILL }},
684 {&ospf_filter[OSPFF_V3_AS_EXTERNAL_FLAG_F],
685 { "F", "ospf.v3.as.external.flags.f", FT_BOOLEAN, 8,
686 TFS(&tfs_v3_as_external_flags_f), OSPF_V3_AS_EXTERNAL_FLAG_F, "", HFILL }},
687 {&ospf_filter[OSPFF_V3_AS_EXTERNAL_FLAG_E],
688 { "E", "ospf.v3.as.external.flags.e", FT_BOOLEAN, 8,
689 TFS(&tfs_v3_as_external_flags_e), OSPF_V3_AS_EXTERNAL_FLAG_E, "", HFILL }},
690 {&ospf_filter[OSPFF_V3_PREFIX_OPTION],
691 { "PrefixOptions", "ospf.v3.prefix.options", FT_UINT8, BASE_HEX,
692 NULL, 0x0, "", HFILL }},
693 {&ospf_filter[OSPFF_V3_PREFIX_OPTION_NU],
694 { "NU", "ospf.v3.prefix.options.nu", FT_BOOLEAN, 8,
695 TFS(&tfs_v3_prefix_options_nu), OSPF_V3_PREFIX_OPTION_NU, "", HFILL }},
696 {&ospf_filter[OSPFF_V3_PREFIX_OPTION_LA],
697 { "LA", "ospf.v3.prefix.options.la", FT_BOOLEAN, 8,
698 TFS(&tfs_v3_prefix_options_la), OSPF_V3_PREFIX_OPTION_LA, "", HFILL }},
699 {&ospf_filter[OSPFF_V3_PREFIX_OPTION_MC],
700 { "MC", "ospf.v3.prefix.options.mc", FT_BOOLEAN, 8,
701 TFS(&tfs_v3_prefix_options_mc), OSPF_V3_PREFIX_OPTION_MC, "", HFILL }},
702 {&ospf_filter[OSPFF_V3_PREFIX_OPTION_P],
703 { "P", "ospf.v3.prefix.options.p", FT_BOOLEAN, 8,
704 TFS(&tfs_v3_prefix_options_p), OSPF_V3_PREFIX_OPTION_P, "", HFILL }},
707 static guint8 ospf_msg_type_to_filter (guint8 msg_type)
709 if (msg_type >= OSPF_HELLO &&
710 msg_type <= OSPF_LS_ACK)
711 return msg_type + OSPFF_MSG_MIN;
715 static guint8 ospf_ls_type_to_filter (guint8 ls_type)
717 if (ls_type >= OSPF_LSTYPE_ROUTER &&
718 ls_type <= OSPF_LSTYPE_EXTATTR)
719 return OSPFF_LS_MIN + ls_type;
720 else if (ls_type >= OSPF_LSTYPE_OP_LINKLOCAL &&
721 ls_type <= OSPF_LSTYPE_OP_ASWIDE)
722 return OSPFF_LS_OPAQUE;
727 typedef struct _bitfield_info {
734 static int bf_dbd[] = {
740 static int bf_lls_ext_options[] = {
741 OSPFF_LLS_EXT_OPTIONS_RS,
742 OSPFF_LLS_EXT_OPTIONS_LR
744 static int bf_v2_router_lsa_flags[] = {
745 OSPFF_V2_ROUTER_LSA_FLAG_V,
746 OSPFF_V2_ROUTER_LSA_FLAG_E,
747 OSPFF_V2_ROUTER_LSA_FLAG_B
749 static int bf_v3_router_lsa_flags[] = {
750 OSPFF_V3_ROUTER_LSA_FLAG_W,
751 OSPFF_V3_ROUTER_LSA_FLAG_V,
752 OSPFF_V3_ROUTER_LSA_FLAG_E,
753 OSPFF_V3_ROUTER_LSA_FLAG_B
755 static int bf_v3_as_external_flags[] = {
756 OSPFF_V3_AS_EXTERNAL_FLAG_E,
757 OSPFF_V3_AS_EXTERNAL_FLAG_F,
758 OSPFF_V3_AS_EXTERNAL_FLAG_T
760 static int bf_v2_options[] = {
769 static int bf_v3_options[] = {
777 static int bf_v3_prefix_options[] = {
778 OSPFF_V3_PREFIX_OPTION_P,
779 OSPFF_V3_PREFIX_OPTION_MC,
780 OSPFF_V3_PREFIX_OPTION_LA,
781 OSPFF_V3_PREFIX_OPTION_NU
784 static bitfield_info bfinfo_dbd = {
785 OSPFF_DBD, &ett_ospf_dbd,
786 bf_dbd, array_length(bf_dbd)
788 static bitfield_info bfinfo_lls_ext_options = {
789 OSPFF_LLS_EXT_OPTIONS, &ett_ospf_lls_ext_options,
790 bf_lls_ext_options, array_length(bf_lls_ext_options)
792 static bitfield_info bfinfo_v2_router_lsa_flags = {
793 OSPFF_V2_ROUTER_LSA_FLAG, &ett_ospf_v2_router_lsa_flags,
794 bf_v2_router_lsa_flags, array_length(bf_v2_router_lsa_flags)
796 static bitfield_info bfinfo_v3_router_lsa_flags = {
797 OSPFF_V3_ROUTER_LSA_FLAG, &ett_ospf_v3_router_lsa_flags,
798 bf_v3_router_lsa_flags, array_length(bf_v3_router_lsa_flags)
800 static bitfield_info bfinfo_v3_as_external_flags = {
801 OSPFF_V3_AS_EXTERNAL_FLAG, &ett_ospf_v3_as_external_flags,
802 bf_v3_as_external_flags, array_length(bf_v3_as_external_flags)
804 static bitfield_info bfinfo_v2_options = {
805 OSPFF_V2_OPTIONS, &ett_ospf_v2_options,
806 bf_v2_options, array_length(bf_v2_options)
808 static bitfield_info bfinfo_v3_options = {
809 OSPFF_V3_OPTIONS, &ett_ospf_v3_options,
810 bf_v3_options, array_length(bf_v3_options)
812 static bitfield_info bfinfo_v3_prefix_options = {
813 OSPFF_V3_PREFIX_OPTION, &ett_ospf_v3_prefix_options,
814 bf_v3_prefix_options, array_length(bf_v3_prefix_options)
817 #define MAX_OPTIONS_LEN 128
819 dissect_ospf_bitfield (proto_tree *parent_tree, tvbuff_t *tvb, int offset,
820 bitfield_info *bfinfo)
822 proto_item *item = NULL;
823 proto_tree *tree = NULL;
828 header_field_info *hfinfo;
830 size_t returned_length;
832 hfindex = ospf_filter[bfinfo->hfindex];
833 hfinfo = proto_registrar_get_nth(hfindex);
834 switch (hfinfo->type) {
836 flags = tvb_get_guint8(tvb, offset);
840 flags = tvb_get_ntohs(tvb, offset);
844 flags = tvb_get_ntoh24(tvb, offset);
848 flags = tvb_get_ntohl(tvb, offset);
856 item = proto_tree_add_uint(parent_tree, hfindex, tvb, offset, length, flags);
857 tree = proto_item_add_subtree(item, *bfinfo->ett);
859 str = ep_alloc(MAX_OPTIONS_LEN);
861 for (i = 0, pos = 0; i < bfinfo->num; i++) {
862 index = ospf_filter[bfinfo->index[i]];
863 hfinfo = proto_registrar_get_nth(index);
864 if (flags & hfinfo->bitmask) {
865 returned_length = g_snprintf(&str[pos], MAX_OPTIONS_LEN-pos, "%s%s",
868 pos += MIN(returned_length, MAX_OPTIONS_LEN-pos);
870 proto_tree_add_boolean(tree, index, tvb, offset, length, flags);
872 proto_item_append_text(item, " (%s)", str);
876 static dissector_handle_t data_handle;
878 static void dissect_ospf_hello(tvbuff_t*, int, proto_tree*, guint8, guint16);
879 static void dissect_ospf_db_desc(tvbuff_t*, int, proto_tree*, guint8, guint16);
880 static void dissect_ospf_ls_req(tvbuff_t*, int, proto_tree*, guint8, guint16);
881 static void dissect_ospf_ls_upd(tvbuff_t*, int, proto_tree*, guint8, guint16);
882 static void dissect_ospf_ls_ack(tvbuff_t*, int, proto_tree*, guint8, guint16);
883 static void dissect_ospf_lls_data_block(tvbuff_t*, int, proto_tree*, guint8);
885 /* dissect_ospf_v[23]lsa returns the offset of the next LSA
886 * if disassemble_body is set to FALSE (e.g. in LSA ACK
887 * packets), the offset is set to the offset of the next
890 static int dissect_ospf_v2_lsa(tvbuff_t*, int, proto_tree*, gboolean disassemble_body);
891 static int dissect_ospf_v3_lsa(tvbuff_t*, int, proto_tree*, gboolean disassemble_body);
893 static void dissect_ospf_v3_address_prefix(tvbuff_t *, int, int, proto_tree *);
896 ospf_has_lls_block(tvbuff_t *tvb, int offset, guint8 packet_type)
900 /* LLS block can be found only in HELLO and DBDESC packets */
901 switch (packet_type) {
903 flags = tvb_get_guint8 (tvb, offset + 6);
904 return flags & OSPF_V2_OPTIONS_L;
906 flags = tvb_get_guint8 (tvb, offset + 2);
907 return flags & OSPF_V2_OPTIONS_L;
914 dissect_ospf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
916 proto_tree *ospf_tree = NULL;
918 proto_tree *ospf_header_tree;
925 guint16 cksum, computed_cksum;
926 guint length, reported_length;
930 unsigned int ospf_header_length;
936 if (check_col(pinfo->cinfo, COL_PROTOCOL))
937 col_set_str(pinfo->cinfo, COL_PROTOCOL, "OSPF");
938 if (check_col(pinfo->cinfo, COL_INFO))
939 col_clear(pinfo->cinfo, COL_INFO);
941 version = tvb_get_guint8(tvb, 0);
944 ospf_header_length = OSPF_VERSION_2_HEADER_LENGTH;
947 ospf_header_length = OSPF_VERSION_3_HEADER_LENGTH;
950 ospf_header_length = 14;
954 packet_type = tvb_get_guint8(tvb, 1);
955 if (check_col(pinfo->cinfo, COL_INFO)) {
956 col_add_str(pinfo->cinfo, COL_INFO,
957 val_to_str(packet_type, pt_vals, "Unknown (%u)"));
961 ospflen = tvb_get_ntohs(tvb, 2);
963 ti = proto_tree_add_item(tree, proto_ospf, tvb, 0, -1, FALSE);
964 ospf_tree = proto_item_add_subtree(ti, ett_ospf);
966 ti = proto_tree_add_text(ospf_tree, tvb, 0, ospf_header_length,
968 ospf_header_tree = proto_item_add_subtree(ti, ett_ospf_hdr);
970 proto_tree_add_text(ospf_header_tree, tvb, 0, 1, "OSPF Version: %u",
972 proto_tree_add_item(ospf_header_tree, ospf_filter[OSPFF_MSG_TYPE],
974 proto_tree_add_item_hidden(ospf_header_tree,
975 ospf_filter[ospf_msg_type_to_filter(packet_type)],
977 proto_tree_add_text(ospf_header_tree, tvb, 2, 2, "Packet Length: %u",
979 proto_tree_add_item(ospf_header_tree, ospf_filter[OSPFF_SRC_ROUTER],
981 areaid=tvb_get_ntohl(tvb,8);
982 proto_tree_add_text(ospf_header_tree, tvb, 8, 4, "Area ID: %s%s",
983 ip_to_str(tvb_get_ptr(tvb, 8, 4)), areaid == 0 ? " (Backbone)" : "");
986 * Quit at this point if it's an unknown OSPF version.
995 cksum = tvb_get_ntohs(tvb, 12);
997 /* No checksum supplied in the packet. */
998 proto_tree_add_text(ospf_header_tree, tvb, 12, 2,
999 "Packet Checksum: 0x%04x (none)", cksum);
1001 proto_tree_add_text(ospf_header_tree, tvb, 12, 2,
1002 "Packet Checksum: 0x%04x", cksum);
1004 proto_tree_add_text(ospf_tree, tvb, 14, -1,
1005 "Unknown OSPF version %u", version);
1009 cksum = tvb_get_ntohs(tvb, 12);
1010 length = tvb_length(tvb);
1011 /* XXX - include only the length from the OSPF header? */
1012 reported_length = tvb_reported_length(tvb);
1014 /* No checksum supplied in the packet. */
1015 proto_tree_add_text(ospf_header_tree, tvb, 12, 2,
1016 "Packet Checksum: 0x%04x (none)", cksum);
1017 } else if (!pinfo->fragmented && length >= reported_length
1018 && length >= ospf_header_length) {
1019 /* The packet isn't part of a fragmented datagram and isn't
1020 truncated, so we can checksum it. */
1024 case OSPF_VERSION_2:
1025 /* Header, not including the authentication data (the OSPFv2
1026 checksum excludes the 64-bit authentication field). */
1027 cksum_vec[0].ptr = tvb_get_ptr(tvb, 0, 16);
1028 cksum_vec[0].len = 16;
1029 if (length > ospf_header_length) {
1030 /* Rest of the packet, again not including the
1031 authentication data. */
1032 reported_length -= ospf_header_length;
1033 cksum_vec[1].ptr = tvb_get_ptr(tvb, ospf_header_length, reported_length);
1034 cksum_vec[1].len = reported_length;
1037 /* There's nothing but a header. */
1042 case OSPF_VERSION_3:
1043 /* IPv6-style checksum, covering the entire OSPF packet
1044 and a prepended IPv6 pseudo-header. */
1046 /* Set up the fields of the pseudo-header. */
1047 cksum_vec[0].ptr = pinfo->src.data;
1048 cksum_vec[0].len = pinfo->src.len;
1049 cksum_vec[1].ptr = pinfo->dst.data;
1050 cksum_vec[1].len = pinfo->dst.len;
1051 cksum_vec[2].ptr = (const guint8 *)&phdr;
1052 phdr[0] = g_htonl(ospflen);
1053 phdr[1] = g_htonl(IP_PROTO_OSPF);
1054 cksum_vec[2].len = 8;
1056 cksum_vec[3].ptr = tvb_get_ptr(tvb, 0, reported_length);
1057 cksum_vec[3].len = reported_length;
1062 DISSECTOR_ASSERT_NOT_REACHED();
1066 computed_cksum = in_cksum(cksum_vec, cksum_vec_len);
1067 if (computed_cksum == 0) {
1068 proto_tree_add_text(ospf_header_tree, tvb, 12, 2,
1069 "Packet Checksum: 0x%04x [correct]", cksum);
1071 proto_tree_add_text(ospf_header_tree, tvb, 12, 2,
1072 "Packet Checksum: 0x%04x [incorrect, should be 0x%04x]",
1073 cksum, in_cksum_shouldbe(cksum, computed_cksum));
1076 proto_tree_add_text(ospf_header_tree, tvb, 12, 2,
1077 "Packet Checksum: 0x%04x", cksum);
1083 case OSPF_VERSION_2:
1084 /* Authentication is only valid for OSPFv2 */
1085 auth_type = tvb_get_ntohs(tvb, 14);
1086 proto_tree_add_text(ospf_header_tree, tvb, 14, 2, "Auth Type: %s",
1087 val_to_str(auth_type, auth_vals, "Unknown (%u)"));
1088 switch (auth_type) {
1090 case OSPF_AUTH_NONE:
1091 proto_tree_add_text(ospf_header_tree, tvb, 16, 8, "Auth Data (none)");
1094 case OSPF_AUTH_SIMPLE:
1095 tvb_get_nstringz0(tvb, 16, 8+1, auth_data);
1096 proto_tree_add_text(ospf_header_tree, tvb, 16, 8, "Auth Data: %s", auth_data);
1099 case OSPF_AUTH_CRYPT:
1100 proto_tree_add_text(ospf_header_tree, tvb, 18, 1, "Auth Key ID: %u",
1101 tvb_get_guint8(tvb, 18));
1102 crypto_len = tvb_get_guint8(tvb, 19);
1103 proto_tree_add_text(ospf_header_tree, tvb, 19, 1, "Auth Data Length: %u",
1105 proto_tree_add_text(ospf_header_tree, tvb, 20, 4, "Auth Crypto Sequence Number: 0x%x",
1106 tvb_get_ntohl(tvb, 20));
1108 /* Show the message digest that was appended to the end of the
1109 OSPF message - but only if it's present (we don't want
1110 to get an exception before we've tried dissecting OSPF
1112 if (tvb_bytes_exist(tvb, ospflen, crypto_len)) {
1113 proto_tree_add_text(ospf_header_tree, tvb, ospflen, crypto_len,
1115 tvb_bytes_to_str(tvb, ospflen, crypto_len));
1120 proto_tree_add_text(ospf_header_tree, tvb, 16, 8, "Auth Data (unknown)");
1125 case OSPF_VERSION_3:
1126 /* Instance ID and "reserved" is OSPFv3-only */
1127 instance_ID = tvb_get_guint8(tvb, 14);
1128 proto_tree_add_text(ospf_header_tree, tvb, 14, 1, "Instance ID: %u",
1130 reserved = tvb_get_guint8(tvb, 15);
1131 proto_tree_add_text(ospf_header_tree, tvb, 15, 1, (reserved == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),
1136 switch (packet_type){
1139 dissect_ospf_hello(tvb, ospf_header_length, ospf_tree, version,
1140 ospflen - ospf_header_length);
1144 dissect_ospf_db_desc(tvb, ospf_header_length, ospf_tree, version,
1145 ospflen - ospf_header_length);
1149 dissect_ospf_ls_req(tvb, ospf_header_length, ospf_tree, version,
1150 ospflen - ospf_header_length);
1154 dissect_ospf_ls_upd(tvb, ospf_header_length, ospf_tree, version,
1155 ospflen - ospf_header_length);
1159 dissect_ospf_ls_ack(tvb, ospf_header_length, ospf_tree, version,
1160 ospflen - ospf_header_length);
1164 call_dissector(data_handle,
1165 tvb_new_subset(tvb, ospf_header_length, -1, -1), pinfo, tree);
1169 /* take care of the LLS data block */
1170 if (ospf_has_lls_block(tvb, ospf_header_length, packet_type))
1171 dissect_ospf_lls_data_block(tvb, ospflen + crypto_len, ospf_tree,
1177 dissect_ospf_lls_tlv(tvbuff_t *tvb, int offset, proto_tree *tree)
1180 proto_tree *ospf_lls_tlv_tree;
1184 type = tvb_get_ntohs(tvb, offset);
1185 length = tvb_get_ntohs(tvb, offset + 2);
1187 ti = proto_tree_add_text(tree, tvb, offset, length + 4,
1188 val_to_str(type, lls_tlv_type_vals, "Unknown TLV"));
1189 ospf_lls_tlv_tree = proto_item_add_subtree(ti, ett_ospf_lls_tlv);
1191 proto_tree_add_text(ospf_lls_tlv_tree, tvb, offset, 2,
1193 proto_tree_add_text(ospf_lls_tlv_tree, tvb, offset + 2, 2,
1194 "Length: %d", length);
1198 dissect_ospf_bitfield(ospf_lls_tlv_tree, tvb, offset + 4, &bfinfo_lls_ext_options);
1201 proto_tree_add_text(ospf_lls_tlv_tree, tvb, offset + 4, 4,
1202 "Sequence number 0x%08x",
1203 tvb_get_ntohl(tvb, offset + 4));
1204 proto_tree_add_text(ospf_lls_tlv_tree, tvb, offset + 8, length - 4,
1206 tvb_bytes_to_str(tvb, offset + 8, length - 4));
1210 return offset + length + 4;
1214 dissect_ospf_lls_data_block(tvbuff_t *tvb, int offset, proto_tree *tree,
1217 proto_tree *ospf_lls_data_block_tree;
1219 guint16 ospf_lls_len;
1220 int orig_offset = offset;
1222 ospf_lls_len = tvb_get_ntohs(tvb, offset + 2);
1223 ti = proto_tree_add_text(tree, tvb, offset, -1, "OSPF LLS Data Block");
1224 ospf_lls_data_block_tree = proto_item_add_subtree(ti,
1225 ett_ospf_lls_data_block);
1227 if (version != OSPF_VERSION_2)
1230 /* TODO: verify checksum */
1231 proto_tree_add_text(ospf_lls_data_block_tree, tvb, offset, 2,
1232 "Checksum: 0x%04x", tvb_get_ntohs(tvb, offset));
1233 proto_tree_add_text(ospf_lls_data_block_tree, tvb, offset + 2, 2,
1234 "LLS Data Length: %d bytes", ospf_lls_len * 4);
1237 while (orig_offset + ospf_lls_len * 4 > offset)
1238 offset = dissect_ospf_lls_tlv (tvb, offset, ospf_lls_data_block_tree);
1242 dissect_ospf_hello(tvbuff_t *tvb, int offset, proto_tree *tree, guint8 version,
1245 proto_tree *ospf_hello_tree;
1247 int orig_offset = offset;
1249 ti = proto_tree_add_text(tree, tvb, offset, length, "OSPF Hello Packet");
1250 ospf_hello_tree = proto_item_add_subtree(ti, ett_ospf_hello);
1253 case OSPF_VERSION_2:
1254 proto_tree_add_text(ospf_hello_tree, tvb, offset, 4, "Network Mask: %s",
1255 ip_to_str(tvb_get_ptr(tvb, offset, 4)));
1256 proto_tree_add_text(ospf_hello_tree, tvb, offset + 4, 2,
1257 "Hello Interval: %u seconds",
1258 tvb_get_ntohs(tvb, offset + 4));
1260 dissect_ospf_bitfield(ospf_hello_tree, tvb, offset + 6, &bfinfo_v2_options);
1261 proto_tree_add_text(ospf_hello_tree, tvb, offset + 7, 1, "Router Priority: %u",
1262 tvb_get_guint8(tvb, offset + 7));
1263 proto_tree_add_text(ospf_hello_tree, tvb, offset + 8, 4, "Router Dead Interval: %u seconds",
1264 tvb_get_ntohl(tvb, offset + 8));
1265 proto_tree_add_text(ospf_hello_tree, tvb, offset + 12, 4, "Designated Router: %s",
1266 ip_to_str(tvb_get_ptr(tvb, offset + 12, 4)));
1267 proto_tree_add_text(ospf_hello_tree, tvb, offset + 16, 4, "Backup Designated Router: %s",
1268 ip_to_str(tvb_get_ptr(tvb, offset + 16, 4)));
1271 while (orig_offset + length > offset) {
1272 proto_tree_add_text(ospf_hello_tree, tvb, offset, 4,
1273 "Active Neighbor: %s",
1274 ip_to_str(tvb_get_ptr(tvb, offset, 4)));
1278 case OSPF_VERSION_3:
1279 proto_tree_add_text(ospf_hello_tree, tvb, offset + 0, 4, "Interface ID: %u",
1280 tvb_get_ntohl(tvb, offset + 0));
1281 proto_tree_add_text(ospf_hello_tree, tvb, offset + 4, 1, "Router Priority: %u",
1282 tvb_get_guint8(tvb, offset + 4));
1283 dissect_ospf_bitfield(ospf_hello_tree, tvb, offset + 5, &bfinfo_v3_options);
1284 proto_tree_add_text(ospf_hello_tree, tvb, offset + 8, 2,
1285 "Hello Interval: %u seconds",
1286 tvb_get_ntohs(tvb, offset + 8));
1287 proto_tree_add_text(ospf_hello_tree, tvb, offset + 10, 2, "Router Dead Interval: %u seconds",
1288 tvb_get_ntohs(tvb, offset + 10));
1289 proto_tree_add_text(ospf_hello_tree, tvb, offset + 12, 4, "Designated Router: %s",
1290 ip_to_str(tvb_get_ptr(tvb, offset + 12, 4)));
1291 proto_tree_add_text(ospf_hello_tree, tvb, offset + 16, 4, "Backup Designated Router: %s",
1292 ip_to_str(tvb_get_ptr(tvb, offset + 16, 4)));
1294 while (orig_offset + length > offset) {
1295 proto_tree_add_text(ospf_hello_tree, tvb, offset, 4,
1296 "Active Neighbor: %s",
1297 ip_to_str(tvb_get_ptr(tvb, offset, 4)));
1306 dissect_ospf_db_desc(tvbuff_t *tvb, int offset, proto_tree *tree,
1307 guint8 version, guint16 length)
1309 proto_tree *ospf_db_desc_tree=NULL;
1312 int orig_offset = offset;
1315 ti = proto_tree_add_text(tree, tvb, offset, length, "OSPF DB Description");
1316 ospf_db_desc_tree = proto_item_add_subtree(ti, ett_ospf_desc);
1320 case OSPF_VERSION_2:
1321 proto_tree_add_text(ospf_db_desc_tree, tvb, offset, 2, "Interface MTU: %u",
1322 tvb_get_ntohs(tvb, offset));
1324 dissect_ospf_bitfield(ospf_db_desc_tree, tvb, offset + 2, &bfinfo_v2_options);
1325 dissect_ospf_bitfield(ospf_db_desc_tree, tvb, offset + 3, &bfinfo_dbd);
1327 proto_tree_add_text(ospf_db_desc_tree, tvb, offset + 4, 4, "DD Sequence: %u",
1328 tvb_get_ntohl(tvb, offset + 4));
1333 case OSPF_VERSION_3:
1335 reserved = tvb_get_guint8(tvb, offset);
1336 proto_tree_add_text(ospf_db_desc_tree, tvb, offset, 1, (reserved == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),
1339 dissect_ospf_bitfield(ospf_db_desc_tree, tvb, offset + 1, &bfinfo_v3_options);
1341 proto_tree_add_text(ospf_db_desc_tree, tvb, offset + 4, 2, "Interface MTU: %u",
1342 tvb_get_ntohs(tvb, offset+4));
1344 reserved = tvb_get_guint8(tvb, offset + 6);
1345 proto_tree_add_text(ospf_db_desc_tree, tvb, offset + 6, 1, (reserved == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),
1348 dissect_ospf_bitfield(ospf_db_desc_tree, tvb, offset + 7, &bfinfo_dbd);
1350 proto_tree_add_text(ospf_db_desc_tree, tvb, offset + 8, 4, "DD Sequence: %u",
1351 tvb_get_ntohl(tvb, offset + 8));
1358 /* LS Headers will be processed here */
1359 /* skip to the end of DB-Desc header */
1360 while (orig_offset + length > offset) {
1361 if ( version == OSPF_VERSION_2)
1362 offset = dissect_ospf_v2_lsa(tvb, offset, tree, FALSE);
1364 if ( version == OSPF_VERSION_3)
1365 offset = dissect_ospf_v3_lsa(tvb, offset, tree, FALSE);
1371 dissect_ospf_ls_req(tvbuff_t *tvb, int offset, proto_tree *tree, guint8 version,
1374 proto_tree *ospf_lsr_tree;
1378 int orig_offset = offset;
1380 /* zero or more LS requests may be within a LS Request */
1381 /* we place every request for a LSA in a single subtree */
1382 while (orig_offset + length > offset) {
1383 ti = proto_tree_add_text(tree, tvb, offset, OSPF_LS_REQ_LENGTH,
1384 "Link State Request");
1385 ospf_lsr_tree = proto_item_add_subtree(ti, ett_ospf_lsr);
1387 switch ( version ) {
1389 case OSPF_VERSION_2:
1390 ls_type = tvb_get_ntohl(tvb, offset);
1391 proto_tree_add_item(ospf_lsr_tree, ospf_filter[OSPFF_LS_TYPE],
1392 tvb, offset, 4, FALSE);
1394 case OSPF_VERSION_3:
1395 reserved = tvb_get_ntohs(tvb, offset);
1396 proto_tree_add_text(ospf_lsr_tree, tvb, offset, 2,
1397 (reserved == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"), reserved);
1398 ls_type = tvb_get_ntohs(tvb, offset+2);
1399 proto_tree_add_text(ospf_lsr_tree, tvb, offset+2, 2, "LS Type: %s (0x%04x)",
1400 val_to_str(ls_type, v3_ls_type_vals, "Unknown"),
1406 proto_tree_add_text(ospf_lsr_tree, tvb, offset + 4, 4, "Link State ID: %s",
1407 ip_to_str(tvb_get_ptr(tvb, offset + 4, 4)));
1408 proto_tree_add_item(ospf_lsr_tree, ospf_filter[OSPFF_ADV_ROUTER],
1409 tvb, offset + 8, 4, FALSE);
1416 dissect_ospf_ls_upd(tvbuff_t *tvb, int offset, proto_tree *tree, guint8 version,
1419 proto_tree *ospf_lsa_upd_tree=NULL;
1422 guint32 lsa_counter;
1424 ti = proto_tree_add_text(tree, tvb, offset, length, "LS Update Packet");
1425 ospf_lsa_upd_tree = proto_item_add_subtree(ti, ett_ospf_lsa_upd);
1427 lsa_nr = tvb_get_ntohl(tvb, offset);
1428 proto_tree_add_text(ospf_lsa_upd_tree, tvb, offset, 4, "Number of LSAs: %u",
1430 /* skip to the beginning of the first LSA */
1431 offset += 4; /* the LS Upd Packet contains only a 32 bit #LSAs field */
1434 while (lsa_counter < lsa_nr) {
1435 if ( version == OSPF_VERSION_2)
1436 offset = dissect_ospf_v2_lsa(tvb, offset, ospf_lsa_upd_tree, TRUE);
1438 if ( version == OSPF_VERSION_3)
1439 offset = dissect_ospf_v3_lsa(tvb, offset, ospf_lsa_upd_tree, TRUE);
1445 dissect_ospf_ls_ack(tvbuff_t *tvb, int offset, proto_tree *tree, guint8 version,
1448 int orig_offset = offset;
1449 /* the body of a LS Ack packet simply contains zero or more LSA Headers */
1450 while (orig_offset + length > offset) {
1451 if ( version == OSPF_VERSION_2)
1452 offset = dissect_ospf_v2_lsa(tvb, offset, tree, FALSE);
1454 if ( version == OSPF_VERSION_3)
1455 offset = dissect_ospf_v3_lsa(tvb, offset, tree, FALSE);
1460 * Returns if an LSA is opaque, i.e. requires special treatment
1463 is_opaque(int lsa_type)
1465 return (lsa_type >= OSPF_LSTYPE_OP_LINKLOCAL &&
1466 lsa_type <= OSPF_LSTYPE_OP_ASWIDE);
1469 /* MPLS/TE TLV types */
1470 #define MPLS_TLV_ROUTER 1
1471 #define MPLS_TLV_LINK 2
1472 #define OIF_TLV_TNA 32768
1474 /* MPLS/TE Link STLV types */
1479 MPLS_LINK_REMOTE_IF,
1480 MPLS_LINK_TE_METRIC,
1482 MPLS_LINK_MAX_RES_BW,
1485 MPLS_LINK_LOCAL_REMOTE_ID = 11,
1486 MPLS_LINK_PROTECTION = 14,
1487 MPLS_LINK_IF_SWITCHING_DESC,
1488 MPLS_LINK_SHARED_RISK_GROUP
1493 OIF_LOCAL_NODE_ID = 32773,
1495 OIF_SONET_SDH_SWITCHING_CAPABILITY,
1496 OIF_TNA_IPv4_ADDRESS,
1498 OIF_TNA_IPv6_ADDRESS,
1499 OIF_TNA_NSAP_ADDRESS
1502 static const value_string mpls_link_stlv_str[] = {
1503 {MPLS_LINK_TYPE, "Link Type"},
1504 {MPLS_LINK_ID, "Link ID"},
1505 {MPLS_LINK_LOCAL_IF, "Local Interface IP Address"},
1506 {MPLS_LINK_REMOTE_IF, "Remote Interface IP Address"},
1507 {MPLS_LINK_TE_METRIC, "Traffic Engineering Metric"},
1508 {MPLS_LINK_MAX_BW, "Maximum Bandwidth"},
1509 {MPLS_LINK_MAX_RES_BW, "Maximum Reservable Bandwidth"},
1510 {MPLS_LINK_UNRES_BW, "Unreserved Bandwidth"},
1511 {MPLS_LINK_COLOR, "Resource Class/Color"},
1512 {MPLS_LINK_LOCAL_REMOTE_ID, "Link Local/Remote Identifier"},
1513 {MPLS_LINK_PROTECTION, "Link Protection Type"},
1514 {MPLS_LINK_IF_SWITCHING_DESC, "Interface Switching Capability Descriptor"},
1515 {MPLS_LINK_SHARED_RISK_GROUP, "Shared Risk Link Group"},
1516 {OIF_LOCAL_NODE_ID, "Local Node ID"},
1517 {OIF_REMOTE_NODE_ID, "Remote Node ID"},
1518 {OIF_SONET_SDH_SWITCHING_CAPABILITY, "Sonet/SDH Interface Switching Capability"},
1522 static const value_string oif_stlv_str[] = {
1523 {OIF_TNA_IPv4_ADDRESS, "TNA address"},
1524 {OIF_NODE_ID, "Node ID"},
1525 {OIF_TNA_IPv6_ADDRESS, "TNA address"},
1526 {OIF_TNA_NSAP_ADDRESS, "TNA address"},
1531 * Dissect MPLS/TE opaque LSA
1534 dissect_ospf_lsa_mpls(tvbuff_t *tvb, int offset, proto_tree *tree,
1538 proto_tree *mpls_tree;
1539 proto_tree *tlv_tree;
1540 proto_tree *stlv_tree;
1541 proto_tree *stlv_admingrp_tree = NULL;
1547 int stlv_type, stlv_len, stlv_offset;
1548 const char *stlv_name;
1549 guint32 stlv_admingrp, mask;
1553 ti = proto_tree_add_text(tree, tvb, offset, length,
1554 "MPLS Traffic Engineering LSA");
1555 proto_tree_add_item_hidden(tree, ospf_filter[OSPFF_LS_MPLS],
1556 tvb, offset, 2, FALSE);
1557 mpls_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls);
1559 while (length != 0) {
1560 tlv_type = tvb_get_ntohs(tvb, offset);
1561 tlv_length = tvb_get_ntohs(tvb, offset + 2);
1562 tlv_end_offset = offset + tlv_length + 4;
1566 case MPLS_TLV_ROUTER:
1567 ti = proto_tree_add_text(mpls_tree, tvb, offset, tlv_length+4,
1568 "Router Address: %s",
1569 ip_to_str(tvb_get_ptr(tvb, offset+4, 4)));
1570 tlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_router);
1571 proto_tree_add_text(tlv_tree, tvb, offset, 2, "TLV Type: 1 - Router Address");
1572 proto_tree_add_text(tlv_tree, tvb, offset+2, 2, "TLV Length: %u",
1574 proto_tree_add_item(tlv_tree, ospf_filter[OSPFF_LS_MPLS_ROUTERID],
1575 tvb, offset+4, 4, FALSE);
1579 ti = proto_tree_add_text(mpls_tree, tvb, offset, tlv_length+4,
1580 "Link Information");
1581 tlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link);
1582 proto_tree_add_text(tlv_tree, tvb, offset, 2, "TLV Type: 2 - Link Information");
1583 proto_tree_add_text(tlv_tree, tvb, offset+2, 2, "TLV Length: %u",
1585 stlv_offset = offset + 4;
1587 /* Walk down the sub-TLVs for link information */
1588 while (stlv_offset < tlv_end_offset) {
1589 stlv_type = tvb_get_ntohs(tvb, stlv_offset);
1590 stlv_len = tvb_get_ntohs(tvb, stlv_offset + 2);
1591 stlv_name = val_to_str(stlv_type, mpls_link_stlv_str, "Unknown sub-TLV");
1592 switch (stlv_type) {
1594 case MPLS_LINK_TYPE:
1595 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1596 "%s: %u - %s", stlv_name,
1597 tvb_get_guint8(tvb, stlv_offset + 4),
1598 val_to_str(tvb_get_guint8(tvb, stlv_offset + 4),
1599 mpls_link_stlv_ltype_str, "Unknown Link Type"));
1600 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1601 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1602 "TLV Type: %u: %s", stlv_type, stlv_name);
1603 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1605 proto_tree_add_item(stlv_tree, ospf_filter[OSPFF_LS_MPLS_LINKTYPE],
1606 tvb, stlv_offset+4, 1,FALSE);
1610 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1611 "%s: %s", stlv_name,
1612 ip_to_str(tvb_get_ptr(tvb, stlv_offset + 4, 4)));
1613 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1614 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1615 "TLV Type: %u: %s", stlv_type, stlv_name);
1616 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1618 proto_tree_add_item(stlv_tree, ospf_filter[OSPFF_LS_MPLS_LINKID],
1619 tvb, stlv_offset+4, 4, FALSE);
1622 case MPLS_LINK_LOCAL_IF:
1623 case MPLS_LINK_REMOTE_IF:
1624 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1626 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1627 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1628 "TLV Type: %u: %s", stlv_type, stlv_name);
1629 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1631 /* The Local/Remote Interface IP Address sub-TLV is TLV type 3/4, and is 4N
1632 octets in length, where N is the number of neighbor addresses. */
1633 for (i=0; i < stlv_len; i+=4)
1634 proto_tree_add_item(stlv_tree,
1635 stlv_type==MPLS_LINK_LOCAL_IF ?
1636 ospf_filter[OSPFF_LS_MPLS_LOCAL_ADDR] :
1637 ospf_filter[OSPFF_LS_MPLS_REMOTE_ADDR],
1638 tvb, stlv_offset+4+i, 4, FALSE);
1641 case MPLS_LINK_TE_METRIC:
1642 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1643 "%s: %u", stlv_name,
1644 tvb_get_ntohl(tvb, stlv_offset + 4));
1645 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1646 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1647 "TLV Type: %u: %s", stlv_type, stlv_name);
1648 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1650 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 4, "%s: %u", stlv_name,
1651 tvb_get_ntohl(tvb, stlv_offset + 4));
1654 case MPLS_LINK_COLOR:
1655 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1656 "%s: 0x%08x", stlv_name,
1657 tvb_get_ntohl(tvb, stlv_offset + 4));
1658 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1659 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1660 "TLV Type: %u: %s", stlv_type, stlv_name);
1661 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1663 stlv_admingrp = tvb_get_ntohl(tvb, stlv_offset + 4);
1665 ti = proto_tree_add_item(stlv_tree, ospf_filter[OSPFF_LS_MPLS_LINKCOLOR],
1666 tvb, stlv_offset+4, 4, FALSE);
1667 stlv_admingrp_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv_admingrp);
1668 if (stlv_admingrp_tree == NULL)
1670 for (i = 0 ; i < 32 ; i++) {
1671 if ((stlv_admingrp & mask) != 0) {
1672 proto_tree_add_text(stlv_admingrp_tree, tvb, stlv_offset+4,
1679 case MPLS_LINK_MAX_BW:
1680 case MPLS_LINK_MAX_RES_BW:
1681 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1682 "%s: %.10g bytes/s (%.0f bits/s)", stlv_name,
1683 tvb_get_ntohieee_float(tvb, stlv_offset + 4),
1684 tvb_get_ntohieee_float(tvb, stlv_offset + 4) * 8.0);
1685 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1686 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1687 "TLV Type: %u: %s", stlv_type, stlv_name);
1688 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1690 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 4, "%s: %.10g bytes/s (%.0f bits/s)", stlv_name,
1691 tvb_get_ntohieee_float(tvb, stlv_offset + 4),
1692 tvb_get_ntohieee_float(tvb, stlv_offset + 4) * 8.0);
1695 case MPLS_LINK_UNRES_BW:
1696 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1698 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1699 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1700 "TLV Type: %u: %s", stlv_type, stlv_name);
1701 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1703 for (i = 0; i < 8; i++) {
1704 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4+(i*4), 4,
1705 "Pri %d: %.10g bytes/s (%.0f bits/s)", i,
1706 tvb_get_ntohieee_float(tvb, stlv_offset + 4 + i*4),
1707 tvb_get_ntohieee_float(tvb, stlv_offset + 4 + i*4) * 8.0);
1711 case MPLS_LINK_LOCAL_REMOTE_ID:
1712 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1713 "%s: %d (0x%x) - %d (0x%x)", stlv_name,
1714 tvb_get_ntohl(tvb, stlv_offset + 4),
1715 tvb_get_ntohl(tvb, stlv_offset + 4),
1716 tvb_get_ntohl(tvb, stlv_offset + 8),
1717 tvb_get_ntohl(tvb, stlv_offset + 8));
1718 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1720 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1721 "TLV Type: %u: %s", stlv_type, stlv_name);
1722 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1724 proto_tree_add_item(stlv_tree,
1725 ospf_filter[OSPFF_LS_MPLS_LOCAL_IFID],
1726 tvb, stlv_offset+4, 4, FALSE);
1727 proto_tree_add_item(stlv_tree,
1728 ospf_filter[OSPFF_LS_MPLS_REMOTE_IFID],
1729 tvb, stlv_offset+8, 4, FALSE);
1732 case MPLS_LINK_IF_SWITCHING_DESC:
1733 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1735 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1736 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1737 "TLV Type: %u: %s", stlv_type, stlv_name);
1738 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1740 switch_cap = tvb_get_guint8 (tvb, stlv_offset+4);
1741 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 1, "Switching Type: %s",
1742 val_to_str(tvb_get_guint8(tvb,stlv_offset+4),
1743 gmpls_switching_type_str, "Unknown (%d)"));
1744 proto_tree_add_text(stlv_tree, tvb, stlv_offset+5, 1, "Encoding: %s",
1745 val_to_str(tvb_get_guint8(tvb,stlv_offset+5),
1746 gmpls_lsp_enc_str, "Unknown (%d)"));
1747 for (i = 0; i < 8; i++) {
1748 proto_tree_add_text(stlv_tree, tvb, stlv_offset+8+(i*4), 4,
1749 "Pri %d: %.10g bytes/s (%.0f bits/s)", i,
1750 tvb_get_ntohieee_float(tvb, stlv_offset + 8 + i*4),
1751 tvb_get_ntohieee_float(tvb, stlv_offset + 8 + i*4) * 8.0);
1753 if (switch_cap >=1 && switch_cap <=4) { /* PSC-1 .. PSC-4 */
1754 proto_tree_add_text(stlv_tree, tvb, stlv_offset+40, 4,
1755 "Minimum LSP bandwidth: %.10g bytes/s (%.0f bits/s)",
1756 tvb_get_ntohieee_float(tvb, stlv_offset + 40),
1757 tvb_get_ntohieee_float(tvb, stlv_offset + 40) * 8.0);
1758 proto_tree_add_text(stlv_tree, tvb, stlv_offset+44, 2,
1759 "Interface MTU: %d", tvb_get_ntohs(tvb, stlv_offset+44));
1762 if (switch_cap == 100) { /* TDM */
1763 proto_tree_add_text(stlv_tree, tvb, stlv_offset+40, 4,
1764 "Minimum LSP bandwidth: %.10g bytes/s (%.0f bits/s)",
1765 tvb_get_ntohieee_float(tvb, stlv_offset + 40),
1766 tvb_get_ntohieee_float(tvb, stlv_offset + 40) * 8.0);
1767 proto_tree_add_text(stlv_tree, tvb, stlv_offset+44, 2,
1769 tvb_get_guint8(tvb, stlv_offset+44) ?
1770 "Arbitrary" : "Standard");
1773 case MPLS_LINK_PROTECTION:
1774 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1776 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1777 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1778 "TLV Type: %u: %s", stlv_type, stlv_name);
1779 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1781 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 1, "Protection Capability: %s (0x%x)",
1782 val_to_str(tvb_get_guint8(tvb,stlv_offset+4), gmpls_protection_cap_str, "Unknown (%d)"),tvb_get_guint8(tvb,stlv_offset+4));
1785 case MPLS_LINK_SHARED_RISK_GROUP:
1786 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1788 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1789 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1790 "TLV Type: %u: %s", stlv_type, stlv_name);
1791 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1793 for (i=0; i < stlv_len; i+=4)
1794 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4+i, 4, "Shared Risk Link Group: %u",
1795 tvb_get_ntohl(tvb,stlv_offset+4+i));
1798 case OIF_LOCAL_NODE_ID:
1799 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1800 "%s: %s", stlv_name,
1801 ip_to_str(tvb_get_ptr(tvb, stlv_offset + 4, 4)));
1802 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1803 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1804 "TLV Type: %u: %s", stlv_type, stlv_name);
1805 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1807 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 4, "Local Node ID: %s",
1808 ip_to_str(tvb_get_ptr(tvb, stlv_offset + 4, 4)));
1811 case OIF_REMOTE_NODE_ID:
1812 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1813 "%s: %s", stlv_name,
1814 ip_to_str(tvb_get_ptr(tvb, stlv_offset + 4, 4)));
1815 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1816 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1817 "TLV Type: %u: %s", stlv_type, stlv_name);
1818 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1820 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 4, "Remote Node ID: %s",
1821 ip_to_str(tvb_get_ptr(tvb, stlv_offset + 4, 4)));
1824 case OIF_SONET_SDH_SWITCHING_CAPABILITY:
1825 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4, "%s", stlv_name);
1826 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1827 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1828 "TLV Type: %u: %s", stlv_type, stlv_name);
1829 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1831 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 1, "Switching Cap: %s",
1832 val_to_str(tvb_get_guint8 (tvb, stlv_offset+4),
1833 gmpls_switching_type_str, "Unknown (%d)"));
1834 proto_tree_add_text(stlv_tree, tvb, stlv_offset+5, 1, "Encoding: %s",
1835 val_to_str(tvb_get_guint8(tvb,stlv_offset+5),
1836 gmpls_lsp_enc_str, "Unknown (%d)"));
1837 for (i = 0; i < (stlv_len - 4) / 4; i++) {
1838 proto_tree_add_text(stlv_tree, tvb, stlv_offset+8+(i*4), 4,
1839 "%s: %d free timeslots",
1840 val_to_str(tvb_get_guint8(tvb, stlv_offset+8+(i*4)),
1841 gmpls_sonet_signal_type_str,
1842 "Unknown Signal Type (%d)"),
1843 tvb_get_ntoh24(tvb, stlv_offset + 9 + i*4));
1848 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1849 "Unknown Link sub-TLV: %u", stlv_type);
1850 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1851 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1852 "TLV Type: %u: %s", stlv_type, stlv_name);
1853 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1855 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, stlv_len,
1859 stlv_offset += ((stlv_len+4+3)/4)*4;
1864 ti = proto_tree_add_text(mpls_tree, tvb, offset, tlv_length+4,
1866 tlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_oif_tna);
1867 proto_tree_add_text(tlv_tree, tvb, offset, 2, "TLV Type: 32768 - TNA Information");
1868 proto_tree_add_text(tlv_tree, tvb, offset+2, 2, "TLV Length: %u",
1870 stlv_offset = offset + 4;
1872 /* Walk down the sub-TLVs for TNA information */
1873 while (stlv_offset < tlv_end_offset) {
1874 stlv_type = tvb_get_ntohs(tvb, stlv_offset);
1875 stlv_len = tvb_get_ntohs(tvb, stlv_offset + 2);
1876 stlv_name = val_to_str(stlv_type, oif_stlv_str, "Unknown sub-TLV");
1877 switch (stlv_type) {
1880 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1881 "%s: %s", stlv_name,
1882 ip_to_str(tvb_get_ptr(tvb, stlv_offset + 4, 4)));
1883 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_oif_tna_stlv);
1884 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1885 "TLV Type: %u: %s", stlv_type, stlv_name);
1886 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1888 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 4, "%s: %s", stlv_name,
1889 ip_to_str(tvb_get_ptr(tvb, stlv_offset + 4, 4)));
1892 case OIF_TNA_IPv4_ADDRESS:
1893 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1894 "%s (IPv4): %s", stlv_name,
1895 ip_to_str(tvb_get_ptr(tvb, stlv_offset + 8, 4)));
1896 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_oif_tna_stlv);
1897 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1898 "TLV Type: %u: %s (IPv4)", stlv_type, stlv_name);
1899 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u", stlv_len);
1900 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 1, "Addr Length: %u",
1901 tvb_get_guint8 (tvb, stlv_offset+4));
1902 proto_tree_add_text(stlv_tree, tvb, stlv_offset+8, stlv_len - 4, "TNA Addr: %s",
1903 ip_to_str(tvb_get_ptr(tvb, stlv_offset + 8, 4)));
1906 case OIF_TNA_IPv6_ADDRESS:
1907 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1908 "%s (IPv6): %s", stlv_name,
1909 ip6_to_str((const struct e_in6_addr *)
1910 tvb_get_ptr(tvb, stlv_offset + 8, 16)));
1911 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_oif_tna_stlv);
1912 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1913 "TLV Type: %u: %s (IPv6)", stlv_type, stlv_name);
1914 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u", stlv_len);
1915 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 1, "Addr Length: %u",
1916 tvb_get_guint8 (tvb, stlv_offset+4));
1917 proto_tree_add_text(stlv_tree, tvb, stlv_offset+8, stlv_len - 4, "TNA Addr: %s",
1918 ip6_to_str((const struct e_in6_addr *)
1919 tvb_get_ptr(tvb, stlv_offset + 8, 16)));
1922 case OIF_TNA_NSAP_ADDRESS:
1923 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1924 "%s (NSAP): %s", stlv_name,
1925 tvb_bytes_to_str (tvb, stlv_offset + 8, stlv_len - 4));
1926 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_oif_tna_stlv);
1927 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1928 "TLV Type: %u: %s (NSAP)", stlv_type, stlv_name);
1929 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u", stlv_len);
1930 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 1, "Addr Length: %u",
1931 tvb_get_guint8 (tvb, stlv_offset+4));
1932 proto_tree_add_text(stlv_tree, tvb, stlv_offset+8, stlv_len - 4, "TNA Addr: %s",
1933 tvb_bytes_to_str(tvb, stlv_offset+8, stlv_len - 4));
1937 proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1938 "Unknown Link sub-TLV: %u", stlv_type);
1941 stlv_offset += ((stlv_len+4+3)/4)*4;
1945 ti = proto_tree_add_text(mpls_tree, tvb, offset, tlv_length+4,
1946 "Unknown LSA: %u", tlv_type);
1947 tlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link);
1948 proto_tree_add_text(tlv_tree, tvb, offset, 2, "TLV Type: %u - Unknown",
1950 proto_tree_add_text(tlv_tree, tvb, offset+2, 2, "TLV Length: %u",
1952 proto_tree_add_text(tlv_tree, tvb, offset+4, tlv_length, "TLV Data");
1956 offset += tlv_length + 4;
1957 length -= tlv_length + 4;
1962 * Dissect opaque LSAs
1965 dissect_ospf_lsa_opaque(tvbuff_t *tvb, int offset, proto_tree *tree,
1966 guint8 ls_id_type, guint32 length)
1968 switch (ls_id_type) {
1970 case OSPF_LSA_MPLS_TE:
1971 dissect_ospf_lsa_mpls(tvb, offset, tree, length);
1975 proto_tree_add_text(tree, tvb, offset, length,
1976 "Unknown LSA Type %u", ls_id_type);
1978 } /* switch on opaque LSA id */
1982 dissect_ospf_v2_lsa(tvbuff_t *tvb, int offset, proto_tree *tree,
1983 gboolean disassemble_body)
1985 proto_tree *ospf_lsa_tree;
1996 guint16 link_counter;
1998 const char *link_type_str;
1999 const char *link_type_short_str;
2000 const char *link_id;
2002 /* AS-external LSA */
2008 ls_type = tvb_get_guint8(tvb, offset + 3);
2009 ls_length = tvb_get_ntohs(tvb, offset + 18);
2010 end_offset = offset + ls_length;
2012 if (disassemble_body) {
2013 ti = proto_tree_add_text(tree, tvb, offset, ls_length,
2015 val_to_str(ls_type, ls_type_vals, "Unknown (%d)"));
2017 ti = proto_tree_add_text(tree, tvb, offset, OSPF_LSA_HEADER_LENGTH,
2020 ospf_lsa_tree = proto_item_add_subtree(ti, ett_ospf_lsa);
2022 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 2, "LS Age: %u seconds",
2023 tvb_get_ntohs(tvb, offset));
2024 dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset + 2, &bfinfo_v2_options);
2025 proto_tree_add_item(ospf_lsa_tree, ospf_filter[OSPFF_LS_TYPE], tvb,
2026 offset + 3, 1, FALSE);
2027 proto_tree_add_item_hidden(ospf_lsa_tree,
2028 ospf_filter[ospf_ls_type_to_filter(ls_type)], tvb,
2029 offset + 3, 1, FALSE);
2031 if (is_opaque(ls_type)) {
2032 ls_id_type = tvb_get_guint8(tvb, offset + 4);
2033 proto_tree_add_uint(ospf_lsa_tree, ospf_filter[OSPFF_LS_OPAQUE_TYPE],
2034 tvb, offset + 4, 1, ls_id_type);
2036 switch (ls_id_type) {
2038 case OSPF_LSA_MPLS_TE:
2039 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 5, 1, "Link State ID TE-LSA Reserved: %u",
2040 tvb_get_guint8(tvb, offset + 5));
2041 proto_tree_add_item(ospf_lsa_tree, ospf_filter[OSPFF_LS_MPLS_TE_INSTANCE],
2042 tvb, offset + 6, 2, FALSE);
2046 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 5, 3, "Link State ID Opaque ID: %u",
2047 tvb_get_ntoh24(tvb, offset + 5));
2052 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 4, 4, "Link State ID: %s",
2053 ip_to_str(tvb_get_ptr(tvb, offset + 4, 4)));
2056 proto_tree_add_item(ospf_lsa_tree, ospf_filter[OSPFF_ADV_ROUTER],
2057 tvb, offset + 8, 4, FALSE);
2058 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 12, 4, "LS Sequence Number: 0x%08x",
2059 tvb_get_ntohl(tvb, offset + 12));
2060 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 16, 2, "LS Checksum: %04x",
2061 tvb_get_ntohs(tvb, offset + 16));
2063 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 18, 2, "Length: %u",
2066 /* skip past the LSA header to the body */
2067 offset += OSPF_LSA_HEADER_LENGTH;
2068 if (ls_length <= OSPF_LSA_HEADER_LENGTH)
2069 return offset; /* no data, or bogus length */
2070 ls_length -= OSPF_LSA_HEADER_LENGTH;
2072 if (!disassemble_body)
2077 case OSPF_LSTYPE_ROUTER:
2078 /* flags field in an router-lsa */
2079 dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset, &bfinfo_v2_router_lsa_flags);
2081 nr_links = tvb_get_ntohs(tvb, offset + 2);
2082 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 2, 2, "Number of Links: %u",
2085 /* nr_links links follow
2086 * maybe we should put each of the links into its own subtree ???
2088 for (link_counter = 1; link_counter <= nr_links; link_counter++) {
2089 proto_tree *ospf_lsa_router_link_tree;
2090 proto_item *ti_local;
2093 /* check the Link Type and ID */
2094 link_type = tvb_get_guint8(tvb, offset + 8);
2095 switch (link_type) {
2098 link_type_str="Point-to-point connection to another router";
2099 link_type_short_str="PTP";
2100 link_id="Neighboring router's Router ID";
2103 case OSPF_LINK_TRANSIT:
2104 link_type_str="Connection to a transit network";
2105 link_type_short_str="Transit";
2106 link_id="IP address of Designated Router";
2109 case OSPF_LINK_STUB:
2110 link_type_str="Connection to a stub network";
2111 link_type_short_str="Stub";
2112 link_id="IP network/subnet number";
2115 case OSPF_LINK_VIRTUAL:
2116 link_type_str="Virtual link";
2117 link_type_short_str="Virtual";
2118 link_id="Neighboring router's Router ID";
2122 link_type_str="Unknown link type";
2123 link_type_short_str="Unknown";
2124 link_id="Unknown link ID";
2128 nr_tos = tvb_get_guint8(tvb, offset + 9);
2131 ti_local = proto_tree_add_text(ospf_lsa_tree, tvb, offset, 12 + 4 * nr_tos,
2132 "Type: %-8s ID: %-15s Data: %-15s Metric: %d",
2133 link_type_short_str,
2134 ip_to_str(tvb_get_ptr(tvb, offset, 4)),
2135 ip_to_str(tvb_get_ptr(tvb, offset + 4, 4)),
2136 tvb_get_ntohs(tvb, offset + 10));
2138 ospf_lsa_router_link_tree = proto_item_add_subtree(ti_local, ett_ospf_lsa_router_link);
2140 proto_tree_add_text(ospf_lsa_router_link_tree, tvb, offset, 4, "%s: %s", link_id,
2141 ip_to_str(tvb_get_ptr(tvb, offset, 4)));
2143 /* link_data should be specified in detail (e.g. network mask) (depends on link type)*/
2144 proto_tree_add_text(ospf_lsa_router_link_tree, tvb, offset + 4, 4, "Link Data: %s",
2145 ip_to_str(tvb_get_ptr(tvb, offset + 4, 4)));
2147 proto_tree_add_text(ospf_lsa_router_link_tree, tvb, offset + 8, 1, "Link Type: %u - %s",
2148 link_type, link_type_str);
2149 proto_tree_add_text(ospf_lsa_router_link_tree, tvb, offset + 9, 1, "Number of TOS metrics: %u",
2151 proto_tree_add_text(ospf_lsa_router_link_tree, tvb, offset + 10, 2, "TOS 0 metric: %u",
2152 tvb_get_ntohs(tvb, offset + 10));
2156 /* nr_tos metrics may follow each link
2157 * ATTENTION: TOS metrics are not tested (I don't have TOS
2159 * please send me a mail if it is/isn't working
2161 for (tos_counter = 1; tos_counter <= nr_tos; tos_counter++) {
2162 proto_tree_add_text(ospf_lsa_router_link_tree, tvb, offset, 4, "TOS: %u, Metric: %u",
2163 tvb_get_guint8(tvb, offset),
2164 tvb_get_ntohs(tvb, offset + 2));
2170 case OSPF_LSTYPE_NETWORK:
2171 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "Netmask: %s",
2172 ip_to_str(tvb_get_ptr(tvb, offset, 4)));
2175 while (offset < end_offset) {
2176 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "Attached Router: %s",
2177 ip_to_str(tvb_get_ptr(tvb, offset, 4)));
2182 case OSPF_LSTYPE_SUMMERY:
2183 /* Type 3 and 4 LSAs have the same format */
2184 case OSPF_LSTYPE_ASBR:
2185 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "Netmask: %s",
2186 ip_to_str(tvb_get_ptr(tvb, offset, 4)));
2189 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "Metric: %u",
2190 tvb_get_ntoh24(tvb, offset + 1));
2193 /* TOS-specific information, if any */
2194 while (offset < end_offset) {
2195 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "TOS: %u, Metric: %u",
2196 tvb_get_guint8(tvb, offset),
2197 tvb_get_ntoh24(tvb, offset + 1));
2202 case OSPF_LSTYPE_ASEXT:
2203 case OSPF_LSTYPE_ASEXT7:
2204 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "Netmask: %s",
2205 ip_to_str(tvb_get_ptr(tvb, offset, 4)));
2208 options = tvb_get_guint8(tvb, offset);
2209 if (options & 0x80) { /* check wether or not E bit is set */
2210 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1,
2211 "External Type: Type 2 (metric is larger than any other link state path)");
2213 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1,
2214 "External Type: Type 1 (metric is specified in the same units as interface cost)");
2216 /* the metric field of a AS-external LAS is specified in 3 bytes */
2217 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 1, 3, "Metric: %u",
2218 tvb_get_ntoh24(tvb, offset + 1));
2221 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "Forwarding Address: %s",
2222 ip_to_str(tvb_get_ptr(tvb, offset, 4)));
2225 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "External Route Tag: %u",
2226 tvb_get_ntohl(tvb, offset));
2229 /* TOS-specific information, if any */
2230 while (offset < end_offset) {
2231 options = tvb_get_guint8(tvb, offset);
2232 if (options & 0x80) { /* check wether or not E bit is set */
2233 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1,
2234 "External Type: Type 2 (metric is larger than any other link state path)");
2236 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1,
2237 "External Type: Type 1 (metric is specified in the same units as interface cost)");
2239 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "TOS: %u, Metric: %u",
2241 tvb_get_ntoh24(tvb, offset + 1));
2244 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "Forwarding Address: %s",
2245 ip_to_str(tvb_get_ptr(tvb, offset, 4)));
2248 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "External Route Tag: %u",
2249 tvb_get_ntohl(tvb, offset));
2254 case OSPF_LSTYPE_OP_LINKLOCAL:
2255 case OSPF_LSTYPE_OP_AREALOCAL:
2256 case OSPF_LSTYPE_OP_ASWIDE:
2258 * RFC 2370 opaque LSAs.
2260 dissect_ospf_lsa_opaque(tvb, offset, ospf_lsa_tree, ls_id_type,
2262 offset += ls_length;
2266 /* unknown LSA type */
2267 proto_tree_add_text(ospf_lsa_tree, tvb, offset, ls_length,
2268 "Unknown LSA Type");
2269 offset += ls_length;
2272 /* return the offset of the next LSA */
2277 dissect_ospf_v3_lsa(tvbuff_t *tvb, int offset, proto_tree *tree,
2278 gboolean disassemble_body)
2280 proto_tree *ospf_lsa_tree;
2290 const char *link_type_str;
2293 guint8 router_priority;
2294 guint32 number_prefixes;
2295 guint8 prefix_length;
2298 guint16 referenced_ls_type;
2301 guint32 external_route_tag;
2304 ls_type = tvb_get_ntohs(tvb, offset + 2);
2305 ls_length = tvb_get_ntohs(tvb, offset + 18);
2306 end_offset = offset + ls_length;
2308 if (disassemble_body) {
2309 ti = proto_tree_add_text(tree, tvb, offset, ls_length,
2310 "%s (Type: 0x%04x)", val_to_str(ls_type, v3_ls_type_vals,"Unknown"), ls_type);
2312 ti = proto_tree_add_text(tree, tvb, offset, OSPF_LSA_HEADER_LENGTH,
2315 ospf_lsa_tree = proto_item_add_subtree(ti, ett_ospf_lsa);
2317 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 2, "LS Age: %u seconds",
2318 tvb_get_ntohs(tvb, offset));
2320 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 2, 2, "LSA Type: 0x%04x (%s)",
2321 ls_type, val_to_str(ls_type, v3_ls_type_vals,"Unkown"));
2323 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 4, 4, "Link State ID: %s",
2324 ip_to_str(tvb_get_ptr(tvb, offset + 4, 4)));
2326 proto_tree_add_item(ospf_lsa_tree, ospf_filter[OSPFF_ADV_ROUTER],
2327 tvb, offset + 8, 4, FALSE);
2328 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 12, 4, "LS Sequence Number: 0x%08x",
2329 tvb_get_ntohl(tvb, offset + 12));
2330 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 16, 2, "LS Checksum: %04x",
2331 tvb_get_ntohs(tvb, offset + 16));
2333 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 18, 2, "Length: %u",
2336 /* skip past the LSA header to the body */
2337 offset += OSPF_LSA_HEADER_LENGTH;
2338 ls_length -= OSPF_LSA_HEADER_LENGTH;
2340 if (!disassemble_body)
2346 case OSPF_V3_LSTYPE_ROUTER:
2347 /* flags field in an router-lsa */
2348 dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset, &bfinfo_v3_router_lsa_flags);
2350 /* options field in an router-lsa */
2351 dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset + 1, &bfinfo_v3_options);
2353 /* skip the router-lsa flags and options */
2358 proto_tree_add_text(ospf_lsa_tree, tvb, offset, ls_length,
2359 "Router Interfaces:");
2361 /* scan all router-lsa router interfaces */
2362 /* maybe we should put each of the links into its own subtree ??? */
2363 while (ls_length > 0 ) {
2365 /* check the type */
2366 link_type = tvb_get_guint8(tvb, offset);
2367 switch (link_type) {
2369 case OSPF_V3_LINK_PTP:
2370 link_type_str="Point-to-point connection to another router";
2373 case OSPF_V3_LINK_TRANSIT:
2374 link_type_str="Connection to a transit network";
2377 case OSPF_V3_LINK_RESERVED:
2378 link_type_str="Connection to a stub network";
2381 case OSPF_V3_LINK_VIRTUAL:
2382 link_type_str="Virtual link";
2386 link_type_str="Unknown link type";
2390 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1, "Type: %u (%s)", link_type,link_type_str);
2392 /* reserved field */
2393 reserved = tvb_get_guint8(tvb, offset+1);
2394 proto_tree_add_text(ospf_lsa_tree, tvb, offset+1, 1,
2395 (reserved == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),reserved);
2398 metric=tvb_get_ntohs(tvb, offset+2);
2399 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 2, 2,"Metric: %u",metric);
2402 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 4, 4, "Interface ID: %u",
2403 tvb_get_ntohl(tvb, offset + 4));
2405 /* Neighbor Interface ID */
2406 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 8, 4, "Neighbor Interface ID: %u",
2407 tvb_get_ntohl(tvb, offset + 8));
2409 /* Neighbor Router ID */
2410 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 12, 4, "Neighbor Router ID: %s",
2411 ip_to_str(tvb_get_ptr(tvb, offset + 12, 4)));
2413 /* skip to the (possible) next entry */
2420 case OSPF_V3_LSTYPE_NETWORK:
2422 /* reserved field */
2423 reserved = tvb_get_guint8(tvb, offset);
2424 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1,
2425 (reserved == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),reserved);
2427 /* options field in an network-lsa */
2428 dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset + 1, &bfinfo_v3_options);
2433 while (ls_length > 0 ) {
2434 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "Attached Router: %s",
2435 ip_to_str(tvb_get_ptr(tvb, offset, 4)));
2442 case OSPF_V3_LSTYPE_INTER_AREA_PREFIX:
2444 /* reserved field */
2445 reserved = tvb_get_guint8(tvb, offset);
2446 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1,
2447 (reserved == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),reserved);
2450 metric=tvb_get_ntoh24(tvb, offset+1);
2451 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 1, 3,"Metric: %u",metric);
2454 prefix_length=tvb_get_guint8(tvb, offset+4);
2455 proto_tree_add_text(ospf_lsa_tree, tvb, offset+4, 1, "PrefixLength: %u",prefix_length);
2457 /* prefix options */
2458 dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset+5, &bfinfo_v3_prefix_options);
2460 /* 16 bits reserved */
2461 reserved16=tvb_get_ntohs(tvb, offset+6);
2462 proto_tree_add_text(ospf_lsa_tree, tvb, offset+6, 2,
2463 (reserved16 == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),reserved16);
2467 /* address_prefix */
2468 dissect_ospf_v3_address_prefix(tvb, offset, prefix_length, ospf_lsa_tree);
2470 offset+=(prefix_length+31)/32*4;
2475 case OSPF_V3_LSTYPE_INTER_AREA_ROUTER:
2477 /* reserved field */
2478 reserved = tvb_get_guint8(tvb, offset);
2479 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1,
2480 (reserved == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),reserved);
2482 /* options field in an inter-area-router-lsa */
2483 dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset + 1, &bfinfo_v3_options);
2485 /* reserved field */
2486 reserved = tvb_get_guint8(tvb, offset+4);
2487 proto_tree_add_text(ospf_lsa_tree, tvb, offset+4, 1,
2488 (reserved == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),reserved);
2491 metric=tvb_get_ntoh24(tvb, offset+5);
2492 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 5, 3,"Metric: %u",metric);
2494 /* Destination Router ID */
2495 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 8, 4, "Destination Router ID: %s",
2496 ip_to_str(tvb_get_ptr(tvb, offset + 8, 4)));
2502 case OSPF_V3_LSTYPE_TYPE_7:
2503 case OSPF_V3_LSTYPE_AS_EXTERNAL:
2506 dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset, &bfinfo_v3_as_external_flags);
2507 flags=tvb_get_guint8(tvb, offset);
2509 /* 24 bits metric */
2510 metric=tvb_get_ntoh24(tvb, offset+1);
2511 proto_tree_add_text(ospf_lsa_tree, tvb, offset+1, 3,
2512 "Metric: %u", metric);
2515 prefix_length=tvb_get_guint8(tvb, offset+4);
2516 proto_tree_add_text(ospf_lsa_tree, tvb, offset+4, 1, "PrefixLength: %u",prefix_length);
2518 /* prefix options */
2519 dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset+5, &bfinfo_v3_prefix_options);
2521 /* referenced LS type */
2522 referenced_ls_type=tvb_get_ntohs(tvb, offset+6);
2523 proto_tree_add_text(ospf_lsa_tree, tvb, offset+6, 2,"Referenced LS type 0x%04x (%s)",
2524 referenced_ls_type, val_to_str(referenced_ls_type, v3_ls_type_vals, "Unknown"));
2528 /* address_prefix */
2529 dissect_ospf_v3_address_prefix(tvb, offset, prefix_length, ospf_lsa_tree);
2531 offset+=(prefix_length+31)/32*4;
2533 /* Forwarding Address (optional - only if F-flag is on) */
2534 if ( (offset < end_offset) && (flags & OSPF_V3_AS_EXTERNAL_FLAG_F) ) {
2535 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 16,"Forwarding Address: %s",
2536 ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset, 16)));
2541 /* External Route Tag (optional - only if T-flag is on) */
2542 if ( (offset < end_offset) && (flags & OSPF_V3_AS_EXTERNAL_FLAG_T) ) {
2543 external_route_tag=tvb_get_ntohl(tvb, offset);
2544 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4,"External Route Tag: %u",
2545 external_route_tag);
2550 /* Referenced Link State ID (optional - only if Referenced LS type is non-zero */
2551 if ( (offset < end_offset) && (referenced_ls_type != 0) ) {
2552 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "Referenced Link State ID: %s",
2553 ip_to_str(tvb_get_ptr(tvb, offset, 4)));
2559 case OSPF_V3_LSTYPE_LINK:
2561 /* router priority */
2562 router_priority=tvb_get_guint8(tvb, offset);
2563 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1, "Router Priority: %u", router_priority);
2565 /* options field in an link-lsa */
2566 dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset + 1, &bfinfo_v3_options);
2568 /* Link-local Interface Address */
2569 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 4, 16, "Link-local Interface Address: %s",
2570 ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset + 4, 16)));
2572 /* Number prefixes */
2573 number_prefixes=tvb_get_ntohl(tvb, offset + 20);
2574 proto_tree_add_text(ospf_lsa_tree, tvb, offset+20, 4, "# prefixes: %d",number_prefixes);
2578 while (number_prefixes > 0) {
2581 prefix_length=tvb_get_guint8(tvb, offset);
2582 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1, "PrefixLength: %u",prefix_length);
2584 /* prefix options */
2585 dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset+1, &bfinfo_v3_prefix_options);
2587 /* 16 bits reserved */
2588 reserved16=tvb_get_ntohs(tvb, offset+2);
2589 proto_tree_add_text(ospf_lsa_tree, tvb, offset+2, 2,
2590 (reserved16 == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),reserved16);
2594 /* address_prefix */
2595 dissect_ospf_v3_address_prefix(tvb, offset, prefix_length, ospf_lsa_tree);
2597 offset+=(prefix_length+31)/32*4;
2604 case OSPF_V3_LSTYPE_INTRA_AREA_PREFIX:
2607 number_prefixes=tvb_get_ntohs(tvb, offset);
2608 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 2,"# prefixes: %u",number_prefixes);
2610 /* referenced LS type */
2611 referenced_ls_type=tvb_get_ntohs(tvb, offset+2);
2612 proto_tree_add_text(ospf_lsa_tree, tvb, offset+2, 2,"Referenced LS type 0x%04x (%s)",
2613 referenced_ls_type, val_to_str(referenced_ls_type, v3_ls_type_vals, "Unknown"));
2615 /* Referenced Link State ID */
2616 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 4, 4, "Referenced Link State ID: %s",
2617 ip_to_str(tvb_get_ptr(tvb, offset + 4, 4)));
2619 /* Referenced Advertising Router */
2620 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 8, 4, "Referenced Advertising Router: %s",
2621 ip_to_str(tvb_get_ptr(tvb, offset + 8, 4)));
2625 while (number_prefixes > 0) {
2628 prefix_length=tvb_get_guint8(tvb, offset);
2629 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1, "PrefixLength: %u",prefix_length);
2631 /* prefix options */
2632 dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset+1, &bfinfo_v3_prefix_options);
2634 /* 16 bits metric */
2635 metric=tvb_get_ntohs(tvb, offset+2);
2636 proto_tree_add_text(ospf_lsa_tree, tvb, offset+2, 2,
2637 "Metric: %u", metric);
2641 /* address_prefix */
2642 dissect_ospf_v3_address_prefix(tvb, offset, prefix_length, ospf_lsa_tree);
2644 offset+=(prefix_length+31)/32*4;
2651 /* unknown LSA type */
2652 proto_tree_add_text(ospf_lsa_tree, tvb, offset, ls_length,
2653 "Unknown LSA Type 0x%04x",ls_type);
2654 offset += ls_length;
2657 /* return the offset of the next LSA */
2661 static void dissect_ospf_v3_address_prefix(tvbuff_t *tvb, int offset, int prefix_length, proto_tree *tree)
2664 int bytes_to_process;
2665 struct e_in6_addr prefix;
2667 bytes_to_process=((prefix_length+31)/32)*4;
2669 if (prefix_length > 128) {
2670 proto_tree_add_text(tree, tvb, offset, bytes_to_process,
2671 "Address Prefix: length is invalid (%d, should be <= 128)",
2676 memset(prefix.bytes, 0, sizeof prefix.bytes);
2677 if (bytes_to_process != 0) {
2678 tvb_memcpy(tvb, prefix.bytes, offset, bytes_to_process);
2679 if (prefix_length % 8) {
2680 prefix.bytes[bytes_to_process - 1] &=
2681 ((0xff00 >> (prefix_length % 8)) & 0xff);
2684 proto_tree_add_text(tree, tvb, offset, bytes_to_process,
2685 "Address Prefix: %s", ip6_to_str(&prefix));
2691 proto_register_ospf(void)
2693 static gint *ett[] = {
2700 &ett_ospf_lsa_router_link,
2703 &ett_ospf_lsa_mpls_router,
2704 &ett_ospf_lsa_mpls_link,
2705 &ett_ospf_lsa_mpls_link_stlv,
2706 &ett_ospf_lsa_mpls_link_stlv_admingrp,
2707 &ett_ospf_lsa_oif_tna,
2708 &ett_ospf_lsa_oif_tna_stlv,
2709 &ett_ospf_v2_options,
2710 &ett_ospf_v3_options,
2712 &ett_ospf_lls_data_block,
2714 &ett_ospf_lls_ext_options,
2715 &ett_ospf_v2_router_lsa_flags,
2716 &ett_ospf_v3_router_lsa_flags,
2717 &ett_ospf_v3_as_external_flags,
2718 &ett_ospf_v3_prefix_options
2721 proto_ospf = proto_register_protocol("Open Shortest Path First",
2723 proto_register_field_array(proto_ospf, ospff_info, array_length(ospff_info));
2724 proto_register_subtree_array(ett, array_length(ett));
2728 proto_reg_handoff_ospf(void)
2730 dissector_handle_t ospf_handle;
2732 ospf_handle = create_dissector_handle(dissect_ospf, proto_ospf);
2733 dissector_add("ip.proto", IP_PROTO_OSPF, ospf_handle);
2734 data_handle = find_dissector("data");