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 * Ethereal - Network traffic analyzer
26 * By Gerald Combs <gerald@ethereal.com>
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;
827 header_field_info *hfinfo;
830 hfindex = ospf_filter[bfinfo->hfindex];
831 hfinfo = proto_registrar_get_nth(hfindex);
832 switch (hfinfo->type) {
834 flags = tvb_get_guint8(tvb, offset);
838 flags = tvb_get_ntohs(tvb, offset);
842 flags = tvb_get_ntoh24(tvb, offset);
846 flags = tvb_get_ntohl(tvb, offset);
854 item = proto_tree_add_uint(parent_tree, hfindex, tvb, offset, length, flags);
855 tree = proto_item_add_subtree(item, *bfinfo->ett);
857 str = ep_alloc(MAX_OPTIONS_LEN);
859 for (i = 0, pos = 0; i < bfinfo->num; i++) {
860 index = ospf_filter[bfinfo->index[i]];
861 hfinfo = proto_registrar_get_nth(index);
862 if (flags & hfinfo->bitmask) {
863 pos += g_snprintf(str+pos, MAX_OPTIONS_LEN-pos, "%s%s",
867 proto_tree_add_boolean(tree, index, tvb, offset, length, flags);
869 proto_item_append_text(item, " (%s)", str);
873 static dissector_handle_t data_handle;
875 static void dissect_ospf_hello(tvbuff_t*, int, proto_tree*, guint8, guint16);
876 static void dissect_ospf_db_desc(tvbuff_t*, int, proto_tree*, guint8, guint16);
877 static void dissect_ospf_ls_req(tvbuff_t*, int, proto_tree*, guint8, guint16);
878 static void dissect_ospf_ls_upd(tvbuff_t*, int, proto_tree*, guint8, guint16);
879 static void dissect_ospf_ls_ack(tvbuff_t*, int, proto_tree*, guint8, guint16);
880 static void dissect_ospf_lls_data_block(tvbuff_t*, int, proto_tree*, guint8);
882 /* dissect_ospf_v[23]lsa returns the offset of the next LSA
883 * if disassemble_body is set to FALSE (e.g. in LSA ACK
884 * packets), the offset is set to the offset of the next
887 static int dissect_ospf_v2_lsa(tvbuff_t*, int, proto_tree*, gboolean disassemble_body);
888 static int dissect_ospf_v3_lsa(tvbuff_t*, int, proto_tree*, gboolean disassemble_body);
890 static void dissect_ospf_v3_address_prefix(tvbuff_t *, int, int, proto_tree *);
893 ospf_has_lls_block(tvbuff_t *tvb, int offset, guint8 packet_type)
897 /* LLS block can be found only in HELLO and DBDESC packets */
898 switch (packet_type) {
900 flags = tvb_get_guint8 (tvb, offset + 6);
901 return flags & OSPF_V2_OPTIONS_L;
903 flags = tvb_get_guint8 (tvb, offset + 2);
904 return flags & OSPF_V2_OPTIONS_L;
911 dissect_ospf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
913 proto_tree *ospf_tree = NULL;
915 proto_tree *ospf_header_tree;
922 guint16 cksum, computed_cksum;
923 guint length, reported_length;
927 unsigned int ospf_header_length;
933 if (check_col(pinfo->cinfo, COL_PROTOCOL))
934 col_set_str(pinfo->cinfo, COL_PROTOCOL, "OSPF");
935 if (check_col(pinfo->cinfo, COL_INFO))
936 col_clear(pinfo->cinfo, COL_INFO);
938 version = tvb_get_guint8(tvb, 0);
941 ospf_header_length = OSPF_VERSION_2_HEADER_LENGTH;
944 ospf_header_length = OSPF_VERSION_3_HEADER_LENGTH;
947 ospf_header_length = 14;
951 packet_type = tvb_get_guint8(tvb, 1);
952 if (check_col(pinfo->cinfo, COL_INFO)) {
953 col_add_str(pinfo->cinfo, COL_INFO,
954 val_to_str(packet_type, pt_vals, "Unknown (%u)"));
958 ospflen = tvb_get_ntohs(tvb, 2);
960 ti = proto_tree_add_item(tree, proto_ospf, tvb, 0, -1, FALSE);
961 ospf_tree = proto_item_add_subtree(ti, ett_ospf);
963 ti = proto_tree_add_text(ospf_tree, tvb, 0, ospf_header_length,
965 ospf_header_tree = proto_item_add_subtree(ti, ett_ospf_hdr);
967 proto_tree_add_text(ospf_header_tree, tvb, 0, 1, "OSPF Version: %u",
969 proto_tree_add_item(ospf_header_tree, ospf_filter[OSPFF_MSG_TYPE],
971 proto_tree_add_item_hidden(ospf_header_tree,
972 ospf_filter[ospf_msg_type_to_filter(packet_type)],
974 proto_tree_add_text(ospf_header_tree, tvb, 2, 2, "Packet Length: %u",
976 proto_tree_add_item(ospf_header_tree, ospf_filter[OSPFF_SRC_ROUTER],
978 areaid=tvb_get_ntohl(tvb,8);
979 proto_tree_add_text(ospf_header_tree, tvb, 8, 4, "Area ID: %s%s",
980 ip_to_str(tvb_get_ptr(tvb, 8, 4)), areaid == 0 ? " (Backbone)" : "");
983 * Quit at this point if it's an unknown OSPF version.
992 cksum = tvb_get_ntohs(tvb, 12);
994 /* No checksum supplied in the packet. */
995 proto_tree_add_text(ospf_header_tree, tvb, 12, 2,
996 "Packet Checksum: 0x%04x (none)", cksum);
998 proto_tree_add_text(ospf_header_tree, tvb, 12, 2,
999 "Packet Checksum: 0x%04x", cksum);
1001 proto_tree_add_text(ospf_tree, tvb, 14, -1,
1002 "Unknown OSPF version %u", version);
1006 cksum = tvb_get_ntohs(tvb, 12);
1007 length = tvb_length(tvb);
1008 /* XXX - include only the length from the OSPF header? */
1009 reported_length = tvb_reported_length(tvb);
1011 /* No checksum supplied in the packet. */
1012 proto_tree_add_text(ospf_header_tree, tvb, 12, 2,
1013 "Packet Checksum: 0x%04x (none)", cksum);
1014 } else if (!pinfo->fragmented && length >= reported_length
1015 && length >= ospf_header_length) {
1016 /* The packet isn't part of a fragmented datagram and isn't
1017 truncated, so we can checksum it. */
1021 case OSPF_VERSION_2:
1022 /* Header, not including the authentication data (the OSPFv2
1023 checksum excludes the 64-bit authentication field). */
1024 cksum_vec[0].ptr = tvb_get_ptr(tvb, 0, 16);
1025 cksum_vec[0].len = 16;
1026 if (length > ospf_header_length) {
1027 /* Rest of the packet, again not including the
1028 authentication data. */
1029 reported_length -= ospf_header_length;
1030 cksum_vec[1].ptr = tvb_get_ptr(tvb, ospf_header_length, reported_length);
1031 cksum_vec[1].len = reported_length;
1034 /* There's nothing but a header. */
1039 case OSPF_VERSION_3:
1040 /* IPv6-style checksum, covering the entire OSPF packet
1041 and a prepended IPv6 pseudo-header. */
1043 /* Set up the fields of the pseudo-header. */
1044 cksum_vec[0].ptr = pinfo->src.data;
1045 cksum_vec[0].len = pinfo->src.len;
1046 cksum_vec[1].ptr = pinfo->dst.data;
1047 cksum_vec[1].len = pinfo->dst.len;
1048 cksum_vec[2].ptr = (const guint8 *)&phdr;
1049 phdr[0] = g_htonl(ospflen);
1050 phdr[1] = g_htonl(IP_PROTO_OSPF);
1051 cksum_vec[2].len = 8;
1053 cksum_vec[3].ptr = tvb_get_ptr(tvb, 0, reported_length);
1054 cksum_vec[3].len = reported_length;
1059 DISSECTOR_ASSERT_NOT_REACHED();
1063 computed_cksum = in_cksum(cksum_vec, cksum_vec_len);
1064 if (computed_cksum == 0) {
1065 proto_tree_add_text(ospf_header_tree, tvb, 12, 2,
1066 "Packet Checksum: 0x%04x [correct]", cksum);
1068 proto_tree_add_text(ospf_header_tree, tvb, 12, 2,
1069 "Packet Checksum: 0x%04x [incorrect, should be 0x%04x]",
1070 cksum, in_cksum_shouldbe(cksum, computed_cksum));
1073 proto_tree_add_text(ospf_header_tree, tvb, 12, 2,
1074 "Packet Checksum: 0x%04x", cksum);
1080 case OSPF_VERSION_2:
1081 /* Authentication is only valid for OSPFv2 */
1082 auth_type = tvb_get_ntohs(tvb, 14);
1083 proto_tree_add_text(ospf_header_tree, tvb, 14, 2, "Auth Type: %s",
1084 val_to_str(auth_type, auth_vals, "Unknown (%u)"));
1085 switch (auth_type) {
1087 case OSPF_AUTH_NONE:
1088 proto_tree_add_text(ospf_header_tree, tvb, 16, 8, "Auth Data (none)");
1091 case OSPF_AUTH_SIMPLE:
1092 tvb_get_nstringz0(tvb, 16, 8+1, auth_data);
1093 proto_tree_add_text(ospf_header_tree, tvb, 16, 8, "Auth Data: %s", auth_data);
1096 case OSPF_AUTH_CRYPT:
1097 proto_tree_add_text(ospf_header_tree, tvb, 18, 1, "Auth Key ID: %u",
1098 tvb_get_guint8(tvb, 18));
1099 crypto_len = tvb_get_guint8(tvb, 19);
1100 proto_tree_add_text(ospf_header_tree, tvb, 19, 1, "Auth Data Length: %u",
1102 proto_tree_add_text(ospf_header_tree, tvb, 20, 4, "Auth Crypto Sequence Number: 0x%x",
1103 tvb_get_ntohl(tvb, 20));
1105 /* Show the message digest that was appended to the end of the
1106 OSPF message - but only if it's present (we don't want
1107 to get an exception before we've tried dissecting OSPF
1109 if (tvb_bytes_exist(tvb, ospflen, crypto_len)) {
1110 proto_tree_add_text(ospf_header_tree, tvb, ospflen, crypto_len,
1112 tvb_bytes_to_str(tvb, ospflen, crypto_len));
1117 proto_tree_add_text(ospf_header_tree, tvb, 16, 8, "Auth Data (unknown)");
1122 case OSPF_VERSION_3:
1123 /* Instance ID and "reserved" is OSPFv3-only */
1124 instance_ID = tvb_get_guint8(tvb, 14);
1125 proto_tree_add_text(ospf_header_tree, tvb, 14, 1, "Instance ID: %u",
1127 reserved = tvb_get_guint8(tvb, 15);
1128 proto_tree_add_text(ospf_header_tree, tvb, 15, 1, (reserved == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),
1133 switch (packet_type){
1136 dissect_ospf_hello(tvb, ospf_header_length, ospf_tree, version,
1137 ospflen - ospf_header_length);
1141 dissect_ospf_db_desc(tvb, ospf_header_length, ospf_tree, version,
1142 ospflen - ospf_header_length);
1146 dissect_ospf_ls_req(tvb, ospf_header_length, ospf_tree, version,
1147 ospflen - ospf_header_length);
1151 dissect_ospf_ls_upd(tvb, ospf_header_length, ospf_tree, version,
1152 ospflen - ospf_header_length);
1156 dissect_ospf_ls_ack(tvb, ospf_header_length, ospf_tree, version,
1157 ospflen - ospf_header_length);
1161 call_dissector(data_handle,
1162 tvb_new_subset(tvb, ospf_header_length, -1, -1), pinfo, tree);
1166 /* take care of the LLS data block */
1167 if (ospf_has_lls_block(tvb, ospf_header_length, packet_type))
1168 dissect_ospf_lls_data_block(tvb, ospflen + crypto_len, ospf_tree,
1174 dissect_ospf_lls_tlv(tvbuff_t *tvb, int offset, proto_tree *tree)
1177 proto_tree *ospf_lls_tlv_tree;
1181 type = tvb_get_ntohs(tvb, offset);
1182 length = tvb_get_ntohs(tvb, offset + 2);
1184 ti = proto_tree_add_text(tree, tvb, offset, length + 4,
1185 val_to_str(type, lls_tlv_type_vals, "Unknown TLV"));
1186 ospf_lls_tlv_tree = proto_item_add_subtree(ti, ett_ospf_lls_tlv);
1188 proto_tree_add_text(ospf_lls_tlv_tree, tvb, offset, 2,
1190 proto_tree_add_text(ospf_lls_tlv_tree, tvb, offset + 2, 2,
1191 "Length: %d", length);
1195 dissect_ospf_bitfield(ospf_lls_tlv_tree, tvb, offset + 4, &bfinfo_lls_ext_options);
1198 proto_tree_add_text(ospf_lls_tlv_tree, tvb, offset + 4, 4,
1199 "Sequence number 0x%08x",
1200 tvb_get_ntohl(tvb, offset + 4));
1201 proto_tree_add_text(ospf_lls_tlv_tree, tvb, offset + 8, length - 4,
1203 tvb_bytes_to_str(tvb, offset + 8, length - 4));
1207 return offset + length + 4;
1211 dissect_ospf_lls_data_block(tvbuff_t *tvb, int offset, proto_tree *tree,
1214 proto_tree *ospf_lls_data_block_tree;
1216 guint16 ospf_lls_len;
1217 int orig_offset = offset;
1219 ospf_lls_len = tvb_get_ntohs(tvb, offset + 2);
1220 ti = proto_tree_add_text(tree, tvb, offset, -1, "OSPF LLS Data Block");
1221 ospf_lls_data_block_tree = proto_item_add_subtree(ti,
1222 ett_ospf_lls_data_block);
1224 if (version != OSPF_VERSION_2)
1227 /* TODO: verify checksum */
1228 proto_tree_add_text(ospf_lls_data_block_tree, tvb, offset, 2,
1229 "Checksum: 0x%04x", tvb_get_ntohs(tvb, offset));
1230 proto_tree_add_text(ospf_lls_data_block_tree, tvb, offset + 2, 2,
1231 "LLS Data Length: %d bytes", ospf_lls_len * 4);
1234 while (orig_offset + ospf_lls_len * 4 > offset)
1235 offset = dissect_ospf_lls_tlv (tvb, offset, ospf_lls_data_block_tree);
1239 dissect_ospf_hello(tvbuff_t *tvb, int offset, proto_tree *tree, guint8 version,
1242 proto_tree *ospf_hello_tree;
1244 int orig_offset = offset;
1246 ti = proto_tree_add_text(tree, tvb, offset, length, "OSPF Hello Packet");
1247 ospf_hello_tree = proto_item_add_subtree(ti, ett_ospf_hello);
1250 case OSPF_VERSION_2:
1251 proto_tree_add_text(ospf_hello_tree, tvb, offset, 4, "Network Mask: %s",
1252 ip_to_str(tvb_get_ptr(tvb, offset, 4)));
1253 proto_tree_add_text(ospf_hello_tree, tvb, offset + 4, 2,
1254 "Hello Interval: %u seconds",
1255 tvb_get_ntohs(tvb, offset + 4));
1257 dissect_ospf_bitfield(ospf_hello_tree, tvb, offset + 6, &bfinfo_v2_options);
1258 proto_tree_add_text(ospf_hello_tree, tvb, offset + 7, 1, "Router Priority: %u",
1259 tvb_get_guint8(tvb, offset + 7));
1260 proto_tree_add_text(ospf_hello_tree, tvb, offset + 8, 4, "Router Dead Interval: %u seconds",
1261 tvb_get_ntohl(tvb, offset + 8));
1262 proto_tree_add_text(ospf_hello_tree, tvb, offset + 12, 4, "Designated Router: %s",
1263 ip_to_str(tvb_get_ptr(tvb, offset + 12, 4)));
1264 proto_tree_add_text(ospf_hello_tree, tvb, offset + 16, 4, "Backup Designated Router: %s",
1265 ip_to_str(tvb_get_ptr(tvb, offset + 16, 4)));
1268 while (orig_offset + length > offset) {
1269 proto_tree_add_text(ospf_hello_tree, tvb, offset, 4,
1270 "Active Neighbor: %s",
1271 ip_to_str(tvb_get_ptr(tvb, offset, 4)));
1275 case OSPF_VERSION_3:
1276 proto_tree_add_text(ospf_hello_tree, tvb, offset + 0, 4, "Interface ID: %u",
1277 tvb_get_ntohl(tvb, offset + 0));
1278 proto_tree_add_text(ospf_hello_tree, tvb, offset + 4, 1, "Router Priority: %u",
1279 tvb_get_guint8(tvb, offset + 4));
1280 dissect_ospf_bitfield(ospf_hello_tree, tvb, offset + 5, &bfinfo_v3_options);
1281 proto_tree_add_text(ospf_hello_tree, tvb, offset + 8, 2,
1282 "Hello Interval: %u seconds",
1283 tvb_get_ntohs(tvb, offset + 8));
1284 proto_tree_add_text(ospf_hello_tree, tvb, offset + 10, 2, "Router Dead Interval: %u seconds",
1285 tvb_get_ntohs(tvb, offset + 10));
1286 proto_tree_add_text(ospf_hello_tree, tvb, offset + 12, 4, "Designated Router: %s",
1287 ip_to_str(tvb_get_ptr(tvb, offset + 12, 4)));
1288 proto_tree_add_text(ospf_hello_tree, tvb, offset + 16, 4, "Backup Designated Router: %s",
1289 ip_to_str(tvb_get_ptr(tvb, offset + 16, 4)));
1291 while (orig_offset + length > offset) {
1292 proto_tree_add_text(ospf_hello_tree, tvb, offset, 4,
1293 "Active Neighbor: %s",
1294 ip_to_str(tvb_get_ptr(tvb, offset, 4)));
1303 dissect_ospf_db_desc(tvbuff_t *tvb, int offset, proto_tree *tree,
1304 guint8 version, guint16 length)
1306 proto_tree *ospf_db_desc_tree=NULL;
1309 int orig_offset = offset;
1312 ti = proto_tree_add_text(tree, tvb, offset, length, "OSPF DB Description");
1313 ospf_db_desc_tree = proto_item_add_subtree(ti, ett_ospf_desc);
1317 case OSPF_VERSION_2:
1318 proto_tree_add_text(ospf_db_desc_tree, tvb, offset, 2, "Interface MTU: %u",
1319 tvb_get_ntohs(tvb, offset));
1321 dissect_ospf_bitfield(ospf_db_desc_tree, tvb, offset + 2, &bfinfo_v2_options);
1322 dissect_ospf_bitfield(ospf_db_desc_tree, tvb, offset + 3, &bfinfo_dbd);
1324 proto_tree_add_text(ospf_db_desc_tree, tvb, offset + 4, 4, "DD Sequence: %u",
1325 tvb_get_ntohl(tvb, offset + 4));
1330 case OSPF_VERSION_3:
1332 reserved = tvb_get_guint8(tvb, offset);
1333 proto_tree_add_text(ospf_db_desc_tree, tvb, offset, 1, (reserved == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),
1336 dissect_ospf_bitfield(ospf_db_desc_tree, tvb, offset + 1, &bfinfo_v3_options);
1338 proto_tree_add_text(ospf_db_desc_tree, tvb, offset + 4, 2, "Interface MTU: %u",
1339 tvb_get_ntohs(tvb, offset+4));
1341 reserved = tvb_get_guint8(tvb, offset + 6);
1342 proto_tree_add_text(ospf_db_desc_tree, tvb, offset + 6, 1, (reserved == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),
1345 dissect_ospf_bitfield(ospf_db_desc_tree, tvb, offset + 7, &bfinfo_dbd);
1347 proto_tree_add_text(ospf_db_desc_tree, tvb, offset + 8, 4, "DD Sequence: %u",
1348 tvb_get_ntohl(tvb, offset + 8));
1355 /* LS Headers will be processed here */
1356 /* skip to the end of DB-Desc header */
1357 while (orig_offset + length > offset) {
1358 if ( version == OSPF_VERSION_2)
1359 offset = dissect_ospf_v2_lsa(tvb, offset, tree, FALSE);
1361 if ( version == OSPF_VERSION_3)
1362 offset = dissect_ospf_v3_lsa(tvb, offset, tree, FALSE);
1368 dissect_ospf_ls_req(tvbuff_t *tvb, int offset, proto_tree *tree, guint8 version,
1371 proto_tree *ospf_lsr_tree;
1375 int orig_offset = offset;
1377 /* zero or more LS requests may be within a LS Request */
1378 /* we place every request for a LSA in a single subtree */
1379 while (orig_offset + length > offset) {
1380 ti = proto_tree_add_text(tree, tvb, offset, OSPF_LS_REQ_LENGTH,
1381 "Link State Request");
1382 ospf_lsr_tree = proto_item_add_subtree(ti, ett_ospf_lsr);
1384 switch ( version ) {
1386 case OSPF_VERSION_2:
1387 ls_type = tvb_get_ntohl(tvb, offset);
1388 proto_tree_add_item(ospf_lsr_tree, ospf_filter[OSPFF_LS_TYPE],
1389 tvb, offset, 4, FALSE);
1391 case OSPF_VERSION_3:
1392 reserved = tvb_get_ntohs(tvb, offset);
1393 proto_tree_add_text(ospf_lsr_tree, tvb, offset, 2,
1394 (reserved == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"), reserved);
1395 ls_type = tvb_get_ntohs(tvb, offset+2);
1396 proto_tree_add_text(ospf_lsr_tree, tvb, offset+2, 2, "LS Type: %s (0x%04x)",
1397 val_to_str(ls_type, v3_ls_type_vals, "Unknown"),
1403 proto_tree_add_text(ospf_lsr_tree, tvb, offset + 4, 4, "Link State ID: %s",
1404 ip_to_str(tvb_get_ptr(tvb, offset + 4, 4)));
1405 proto_tree_add_item(ospf_lsr_tree, ospf_filter[OSPFF_ADV_ROUTER],
1406 tvb, offset + 8, 4, FALSE);
1413 dissect_ospf_ls_upd(tvbuff_t *tvb, int offset, proto_tree *tree, guint8 version,
1416 proto_tree *ospf_lsa_upd_tree=NULL;
1419 guint32 lsa_counter;
1421 ti = proto_tree_add_text(tree, tvb, offset, length, "LS Update Packet");
1422 ospf_lsa_upd_tree = proto_item_add_subtree(ti, ett_ospf_lsa_upd);
1424 lsa_nr = tvb_get_ntohl(tvb, offset);
1425 proto_tree_add_text(ospf_lsa_upd_tree, tvb, offset, 4, "Number of LSAs: %u",
1427 /* skip to the beginning of the first LSA */
1428 offset += 4; /* the LS Upd Packet contains only a 32 bit #LSAs field */
1431 while (lsa_counter < lsa_nr) {
1432 if ( version == OSPF_VERSION_2)
1433 offset = dissect_ospf_v2_lsa(tvb, offset, ospf_lsa_upd_tree, TRUE);
1435 if ( version == OSPF_VERSION_3)
1436 offset = dissect_ospf_v3_lsa(tvb, offset, ospf_lsa_upd_tree, TRUE);
1442 dissect_ospf_ls_ack(tvbuff_t *tvb, int offset, proto_tree *tree, guint8 version,
1445 int orig_offset = offset;
1446 /* the body of a LS Ack packet simply contains zero or more LSA Headers */
1447 while (orig_offset + length > offset) {
1448 if ( version == OSPF_VERSION_2)
1449 offset = dissect_ospf_v2_lsa(tvb, offset, tree, FALSE);
1451 if ( version == OSPF_VERSION_3)
1452 offset = dissect_ospf_v3_lsa(tvb, offset, tree, FALSE);
1457 * Returns if an LSA is opaque, i.e. requires special treatment
1460 is_opaque(int lsa_type)
1462 return (lsa_type >= OSPF_LSTYPE_OP_LINKLOCAL &&
1463 lsa_type <= OSPF_LSTYPE_OP_ASWIDE);
1466 /* MPLS/TE TLV types */
1467 #define MPLS_TLV_ROUTER 1
1468 #define MPLS_TLV_LINK 2
1469 #define OIF_TLV_TNA 32768
1471 /* MPLS/TE Link STLV types */
1476 MPLS_LINK_REMOTE_IF,
1477 MPLS_LINK_TE_METRIC,
1479 MPLS_LINK_MAX_RES_BW,
1482 MPLS_LINK_LOCAL_REMOTE_ID = 11,
1483 MPLS_LINK_PROTECTION = 14,
1484 MPLS_LINK_IF_SWITCHING_DESC,
1485 MPLS_LINK_SHARED_RISK_GROUP
1490 OIF_LOCAL_NODE_ID = 32773,
1492 OIF_SONET_SDH_SWITCHING_CAPABILITY,
1493 OIF_TNA_IPv4_ADDRESS,
1495 OIF_TNA_IPv6_ADDRESS,
1496 OIF_TNA_NSAP_ADDRESS
1499 static const value_string mpls_link_stlv_str[] = {
1500 {MPLS_LINK_TYPE, "Link Type"},
1501 {MPLS_LINK_ID, "Link ID"},
1502 {MPLS_LINK_LOCAL_IF, "Local Interface IP Address"},
1503 {MPLS_LINK_REMOTE_IF, "Remote Interface IP Address"},
1504 {MPLS_LINK_TE_METRIC, "Traffic Engineering Metric"},
1505 {MPLS_LINK_MAX_BW, "Maximum Bandwidth"},
1506 {MPLS_LINK_MAX_RES_BW, "Maximum Reservable Bandwidth"},
1507 {MPLS_LINK_UNRES_BW, "Unreserved Bandwidth"},
1508 {MPLS_LINK_COLOR, "Resource Class/Color"},
1509 {MPLS_LINK_LOCAL_REMOTE_ID, "Link Local/Remote Identifier"},
1510 {MPLS_LINK_PROTECTION, "Link Protection Type"},
1511 {MPLS_LINK_IF_SWITCHING_DESC, "Interface Switching Capability Descriptor"},
1512 {MPLS_LINK_SHARED_RISK_GROUP, "Shared Risk Link Group"},
1513 {OIF_LOCAL_NODE_ID, "Local Node ID"},
1514 {OIF_REMOTE_NODE_ID, "Remote Node ID"},
1515 {OIF_SONET_SDH_SWITCHING_CAPABILITY, "Sonet/SDH Interface Switching Capability"},
1519 static const value_string oif_stlv_str[] = {
1520 {OIF_TNA_IPv4_ADDRESS, "TNA address"},
1521 {OIF_NODE_ID, "Node ID"},
1522 {OIF_TNA_IPv6_ADDRESS, "TNA address"},
1523 {OIF_TNA_NSAP_ADDRESS, "TNA address"},
1528 * Dissect MPLS/TE opaque LSA
1531 dissect_ospf_lsa_mpls(tvbuff_t *tvb, int offset, proto_tree *tree,
1535 proto_tree *mpls_tree;
1536 proto_tree *tlv_tree;
1537 proto_tree *stlv_tree;
1538 proto_tree *stlv_admingrp_tree = NULL;
1544 int stlv_type, stlv_len, stlv_offset;
1545 const char *stlv_name;
1546 guint32 stlv_admingrp, mask;
1550 ti = proto_tree_add_text(tree, tvb, offset, length,
1551 "MPLS Traffic Engineering LSA");
1552 proto_tree_add_item_hidden(tree, ospf_filter[OSPFF_LS_MPLS],
1553 tvb, offset, 2, FALSE);
1554 mpls_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls);
1556 while (length != 0) {
1557 tlv_type = tvb_get_ntohs(tvb, offset);
1558 tlv_length = tvb_get_ntohs(tvb, offset + 2);
1559 tlv_end_offset = offset + tlv_length + 4;
1563 case MPLS_TLV_ROUTER:
1564 ti = proto_tree_add_text(mpls_tree, tvb, offset, tlv_length+4,
1565 "Router Address: %s",
1566 ip_to_str(tvb_get_ptr(tvb, offset+4, 4)));
1567 tlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_router);
1568 proto_tree_add_text(tlv_tree, tvb, offset, 2, "TLV Type: 1 - Router Address");
1569 proto_tree_add_text(tlv_tree, tvb, offset+2, 2, "TLV Length: %u",
1571 proto_tree_add_item(tlv_tree, ospf_filter[OSPFF_LS_MPLS_ROUTERID],
1572 tvb, offset+4, 4, FALSE);
1576 ti = proto_tree_add_text(mpls_tree, tvb, offset, tlv_length+4,
1577 "Link Information");
1578 tlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link);
1579 proto_tree_add_text(tlv_tree, tvb, offset, 2, "TLV Type: 2 - Link Information");
1580 proto_tree_add_text(tlv_tree, tvb, offset+2, 2, "TLV Length: %u",
1582 stlv_offset = offset + 4;
1584 /* Walk down the sub-TLVs for link information */
1585 while (stlv_offset < tlv_end_offset) {
1586 stlv_type = tvb_get_ntohs(tvb, stlv_offset);
1587 stlv_len = tvb_get_ntohs(tvb, stlv_offset + 2);
1588 stlv_name = val_to_str(stlv_type, mpls_link_stlv_str, "Unknown sub-TLV");
1589 switch (stlv_type) {
1591 case MPLS_LINK_TYPE:
1592 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1593 "%s: %u - %s", stlv_name,
1594 tvb_get_guint8(tvb, stlv_offset + 4),
1595 val_to_str(tvb_get_guint8(tvb, stlv_offset + 4),
1596 mpls_link_stlv_ltype_str, "Unknown Link Type"));
1597 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1598 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1599 "TLV Type: %u: %s", stlv_type, stlv_name);
1600 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1602 proto_tree_add_item(stlv_tree, ospf_filter[OSPFF_LS_MPLS_LINKTYPE],
1603 tvb, stlv_offset+4, 1,FALSE);
1607 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1608 "%s: %s", stlv_name,
1609 ip_to_str(tvb_get_ptr(tvb, stlv_offset + 4, 4)));
1610 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1611 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1612 "TLV Type: %u: %s", stlv_type, stlv_name);
1613 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1615 proto_tree_add_item(stlv_tree, ospf_filter[OSPFF_LS_MPLS_LINKID],
1616 tvb, stlv_offset+4, 4, FALSE);
1619 case MPLS_LINK_LOCAL_IF:
1620 case MPLS_LINK_REMOTE_IF:
1621 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1623 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1624 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1625 "TLV Type: %u: %s", stlv_type, stlv_name);
1626 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1628 /* The Local/Remote Interface IP Address sub-TLV is TLV type 3/4, and is 4N
1629 octets in length, where N is the number of neighbor addresses. */
1630 for (i=0; i < stlv_len; i+=4)
1631 proto_tree_add_item(stlv_tree,
1632 stlv_type==MPLS_LINK_LOCAL_IF ?
1633 ospf_filter[OSPFF_LS_MPLS_LOCAL_ADDR] :
1634 ospf_filter[OSPFF_LS_MPLS_REMOTE_ADDR],
1635 tvb, stlv_offset+4+i, 4, FALSE);
1638 case MPLS_LINK_TE_METRIC:
1639 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1640 "%s: %u", stlv_name,
1641 tvb_get_ntohl(tvb, stlv_offset + 4));
1642 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1643 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1644 "TLV Type: %u: %s", stlv_type, stlv_name);
1645 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1647 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 4, "%s: %u", stlv_name,
1648 tvb_get_ntohl(tvb, stlv_offset + 4));
1651 case MPLS_LINK_COLOR:
1652 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1653 "%s: 0x%08x", stlv_name,
1654 tvb_get_ntohl(tvb, stlv_offset + 4));
1655 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1656 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1657 "TLV Type: %u: %s", stlv_type, stlv_name);
1658 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1660 stlv_admingrp = tvb_get_ntohl(tvb, stlv_offset + 4);
1662 ti = proto_tree_add_item(stlv_tree, ospf_filter[OSPFF_LS_MPLS_LINKCOLOR],
1663 tvb, stlv_offset+4, 4, FALSE);
1664 stlv_admingrp_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv_admingrp);
1665 if (stlv_admingrp_tree == NULL)
1667 for (i = 0 ; i < 32 ; i++) {
1668 if ((stlv_admingrp & mask) != 0) {
1669 proto_tree_add_text(stlv_admingrp_tree, tvb, stlv_offset+4,
1676 case MPLS_LINK_MAX_BW:
1677 case MPLS_LINK_MAX_RES_BW:
1678 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1679 "%s: %.10g bytes/s (%.0f bits/s)", stlv_name,
1680 tvb_get_ntohieee_float(tvb, stlv_offset + 4),
1681 tvb_get_ntohieee_float(tvb, stlv_offset + 4) * 8.0);
1682 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1683 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1684 "TLV Type: %u: %s", stlv_type, stlv_name);
1685 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1687 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 4, "%s: %.10g bytes/s (%.0f bits/s)", stlv_name,
1688 tvb_get_ntohieee_float(tvb, stlv_offset + 4),
1689 tvb_get_ntohieee_float(tvb, stlv_offset + 4) * 8.0);
1692 case MPLS_LINK_UNRES_BW:
1693 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1695 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1696 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1697 "TLV Type: %u: %s", stlv_type, stlv_name);
1698 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1700 for (i = 0; i < 8; i++) {
1701 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4+(i*4), 4,
1702 "Pri %d: %.10g bytes/s (%.0f bits/s)", i,
1703 tvb_get_ntohieee_float(tvb, stlv_offset + 4 + i*4),
1704 tvb_get_ntohieee_float(tvb, stlv_offset + 4 + i*4) * 8.0);
1708 case MPLS_LINK_LOCAL_REMOTE_ID:
1709 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1710 "%s: %d (0x%x) - %d (0x%x)", stlv_name,
1711 tvb_get_ntohl(tvb, stlv_offset + 4),
1712 tvb_get_ntohl(tvb, stlv_offset + 4),
1713 tvb_get_ntohl(tvb, stlv_offset + 8),
1714 tvb_get_ntohl(tvb, stlv_offset + 8));
1715 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1717 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1718 "TLV Type: %u: %s", stlv_type, stlv_name);
1719 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1721 proto_tree_add_item(stlv_tree,
1722 ospf_filter[OSPFF_LS_MPLS_LOCAL_IFID],
1723 tvb, stlv_offset+4, 4, FALSE);
1724 proto_tree_add_item(stlv_tree,
1725 ospf_filter[OSPFF_LS_MPLS_REMOTE_IFID],
1726 tvb, stlv_offset+8, 4, FALSE);
1729 case MPLS_LINK_IF_SWITCHING_DESC:
1730 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1732 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1733 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1734 "TLV Type: %u: %s", stlv_type, stlv_name);
1735 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1737 switch_cap = tvb_get_guint8 (tvb, stlv_offset+4);
1738 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 1, "Switching Type: %s",
1739 val_to_str(tvb_get_guint8(tvb,stlv_offset+4),
1740 gmpls_switching_type_str, "Unknown (%d)"));
1741 proto_tree_add_text(stlv_tree, tvb, stlv_offset+5, 1, "Encoding: %s",
1742 val_to_str(tvb_get_guint8(tvb,stlv_offset+5),
1743 gmpls_lsp_enc_str, "Unknown (%d)"));
1744 for (i = 0; i < 8; i++) {
1745 proto_tree_add_text(stlv_tree, tvb, stlv_offset+8+(i*4), 4,
1746 "Pri %d: %.10g bytes/s (%.0f bits/s)", i,
1747 tvb_get_ntohieee_float(tvb, stlv_offset + 8 + i*4),
1748 tvb_get_ntohieee_float(tvb, stlv_offset + 8 + i*4) * 8.0);
1750 if (switch_cap >=1 && switch_cap <=4) { /* PSC-1 .. PSC-4 */
1751 proto_tree_add_text(stlv_tree, tvb, stlv_offset+40, 4,
1752 "Minimum LSP bandwidth: %.10g bytes/s (%.0f bits/s)",
1753 tvb_get_ntohieee_float(tvb, stlv_offset + 40),
1754 tvb_get_ntohieee_float(tvb, stlv_offset + 40) * 8.0);
1755 proto_tree_add_text(stlv_tree, tvb, stlv_offset+44, 2,
1756 "Interface MTU: %d", tvb_get_ntohs(tvb, stlv_offset+44));
1759 if (switch_cap == 100) { /* TDM */
1760 proto_tree_add_text(stlv_tree, tvb, stlv_offset+40, 4,
1761 "Minimum LSP bandwidth: %.10g bytes/s (%.0f bits/s)",
1762 tvb_get_ntohieee_float(tvb, stlv_offset + 40),
1763 tvb_get_ntohieee_float(tvb, stlv_offset + 40) * 8.0);
1764 proto_tree_add_text(stlv_tree, tvb, stlv_offset+44, 2,
1766 tvb_get_guint8(tvb, stlv_offset+44) ?
1767 "Arbitrary" : "Standard");
1770 case MPLS_LINK_PROTECTION:
1771 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1773 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1774 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1775 "TLV Type: %u: %s", stlv_type, stlv_name);
1776 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1778 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 1, "Protection Capability: %s (0x%x)",
1779 val_to_str(tvb_get_guint8(tvb,stlv_offset+4), gmpls_protection_cap_str, "Unknown (%d)"),tvb_get_guint8(tvb,stlv_offset+4));
1782 case MPLS_LINK_SHARED_RISK_GROUP:
1783 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1785 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1786 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1787 "TLV Type: %u: %s", stlv_type, stlv_name);
1788 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1790 for (i=0; i < stlv_len; i+=4)
1791 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4+i, 4, "Shared Risk Link Group: %u",
1792 tvb_get_ntohl(tvb,stlv_offset+4+i));
1795 case OIF_LOCAL_NODE_ID:
1796 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1797 "%s: %s", stlv_name,
1798 ip_to_str(tvb_get_ptr(tvb, stlv_offset + 4, 4)));
1799 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1800 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1801 "TLV Type: %u: %s", stlv_type, stlv_name);
1802 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1804 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 4, "Local Node ID: %s",
1805 ip_to_str(tvb_get_ptr(tvb, stlv_offset + 4, 4)));
1808 case OIF_REMOTE_NODE_ID:
1809 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1810 "%s: %s", stlv_name,
1811 ip_to_str(tvb_get_ptr(tvb, stlv_offset + 4, 4)));
1812 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1813 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1814 "TLV Type: %u: %s", stlv_type, stlv_name);
1815 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1817 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 4, "Remote Node ID: %s",
1818 ip_to_str(tvb_get_ptr(tvb, stlv_offset + 4, 4)));
1821 case OIF_SONET_SDH_SWITCHING_CAPABILITY:
1822 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4, "%s", stlv_name);
1823 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1824 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1825 "TLV Type: %u: %s", stlv_type, stlv_name);
1826 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1828 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 1, "Switching Cap: %s",
1829 val_to_str(tvb_get_guint8 (tvb, stlv_offset+4),
1830 gmpls_switching_type_str, "Unknown (%d)"));
1831 proto_tree_add_text(stlv_tree, tvb, stlv_offset+5, 1, "Encoding: %s",
1832 val_to_str(tvb_get_guint8(tvb,stlv_offset+5),
1833 gmpls_lsp_enc_str, "Unknown (%d)"));
1834 for (i = 0; i < (stlv_len - 4) / 4; i++) {
1835 proto_tree_add_text(stlv_tree, tvb, stlv_offset+8+(i*4), 4,
1836 "%s: %d free timeslots",
1837 val_to_str(tvb_get_guint8(tvb, stlv_offset+8+(i*4)),
1838 gmpls_sonet_signal_type_str,
1839 "Unknown Signal Type (%d)"),
1840 tvb_get_ntoh24(tvb, stlv_offset + 9 + i*4));
1845 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1846 "Unknown Link sub-TLV: %u", stlv_type);
1847 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1848 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1849 "TLV Type: %u: %s", stlv_type, stlv_name);
1850 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1852 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, stlv_len,
1856 stlv_offset += ((stlv_len+4+3)/4)*4;
1861 ti = proto_tree_add_text(mpls_tree, tvb, offset, tlv_length+4,
1863 tlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_oif_tna);
1864 proto_tree_add_text(tlv_tree, tvb, offset, 2, "TLV Type: 32768 - TNA Information");
1865 proto_tree_add_text(tlv_tree, tvb, offset+2, 2, "TLV Length: %u",
1867 stlv_offset = offset + 4;
1869 /* Walk down the sub-TLVs for TNA information */
1870 while (stlv_offset < tlv_end_offset) {
1871 stlv_type = tvb_get_ntohs(tvb, stlv_offset);
1872 stlv_len = tvb_get_ntohs(tvb, stlv_offset + 2);
1873 stlv_name = val_to_str(stlv_type, oif_stlv_str, "Unknown sub-TLV");
1874 switch (stlv_type) {
1877 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1878 "%s: %s", stlv_name,
1879 ip_to_str(tvb_get_ptr(tvb, stlv_offset + 4, 4)));
1880 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_oif_tna_stlv);
1881 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1882 "TLV Type: %u: %s", stlv_type, stlv_name);
1883 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1885 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 4, "%s: %s", stlv_name,
1886 ip_to_str(tvb_get_ptr(tvb, stlv_offset + 4, 4)));
1889 case OIF_TNA_IPv4_ADDRESS:
1890 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1891 "%s (IPv4): %s", stlv_name,
1892 ip_to_str(tvb_get_ptr(tvb, stlv_offset + 8, 4)));
1893 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_oif_tna_stlv);
1894 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1895 "TLV Type: %u: %s (IPv4)", stlv_type, stlv_name);
1896 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u", stlv_len);
1897 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 1, "Addr Length: %u",
1898 tvb_get_guint8 (tvb, stlv_offset+4));
1899 proto_tree_add_text(stlv_tree, tvb, stlv_offset+8, stlv_len - 4, "TNA Addr: %s",
1900 ip_to_str(tvb_get_ptr(tvb, stlv_offset + 8, 4)));
1903 case OIF_TNA_IPv6_ADDRESS:
1904 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1905 "%s (IPv6): %s", stlv_name,
1906 ip6_to_str((const struct e_in6_addr *)
1907 tvb_get_ptr(tvb, stlv_offset + 8, 16)));
1908 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_oif_tna_stlv);
1909 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1910 "TLV Type: %u: %s (IPv6)", stlv_type, stlv_name);
1911 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u", stlv_len);
1912 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 1, "Addr Length: %u",
1913 tvb_get_guint8 (tvb, stlv_offset+4));
1914 proto_tree_add_text(stlv_tree, tvb, stlv_offset+8, stlv_len - 4, "TNA Addr: %s",
1915 ip6_to_str((const struct e_in6_addr *)
1916 tvb_get_ptr(tvb, stlv_offset + 8, 16)));
1919 case OIF_TNA_NSAP_ADDRESS:
1920 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1921 "%s (NSAP): %s", stlv_name,
1922 tvb_bytes_to_str (tvb, stlv_offset + 8, stlv_len - 4));
1923 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_oif_tna_stlv);
1924 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1925 "TLV Type: %u: %s (NSAP)", stlv_type, stlv_name);
1926 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u", stlv_len);
1927 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 1, "Addr Length: %u",
1928 tvb_get_guint8 (tvb, stlv_offset+4));
1929 proto_tree_add_text(stlv_tree, tvb, stlv_offset+8, stlv_len - 4, "TNA Addr: %s",
1930 tvb_bytes_to_str(tvb, stlv_offset+8, stlv_len - 4));
1934 proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1935 "Unknown Link sub-TLV: %u", stlv_type);
1938 stlv_offset += ((stlv_len+4+3)/4)*4;
1942 ti = proto_tree_add_text(mpls_tree, tvb, offset, tlv_length+4,
1943 "Unknown LSA: %u", tlv_type);
1944 tlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link);
1945 proto_tree_add_text(tlv_tree, tvb, offset, 2, "TLV Type: %u - Unknown",
1947 proto_tree_add_text(tlv_tree, tvb, offset+2, 2, "TLV Length: %u",
1949 proto_tree_add_text(tlv_tree, tvb, offset+4, tlv_length, "TLV Data");
1953 offset += tlv_length + 4;
1954 length -= tlv_length + 4;
1959 * Dissect opaque LSAs
1962 dissect_ospf_lsa_opaque(tvbuff_t *tvb, int offset, proto_tree *tree,
1963 guint8 ls_id_type, guint32 length)
1965 switch (ls_id_type) {
1967 case OSPF_LSA_MPLS_TE:
1968 dissect_ospf_lsa_mpls(tvb, offset, tree, length);
1972 proto_tree_add_text(tree, tvb, offset, length,
1973 "Unknown LSA Type %u", ls_id_type);
1975 } /* switch on opaque LSA id */
1979 dissect_ospf_v2_lsa(tvbuff_t *tvb, int offset, proto_tree *tree,
1980 gboolean disassemble_body)
1982 proto_tree *ospf_lsa_tree;
1993 guint16 link_counter;
1995 const char *link_type_str;
1996 const char *link_type_short_str;
1997 const char *link_id;
1999 /* AS-external LSA */
2005 ls_type = tvb_get_guint8(tvb, offset + 3);
2006 ls_length = tvb_get_ntohs(tvb, offset + 18);
2007 end_offset = offset + ls_length;
2009 if (disassemble_body) {
2010 ti = proto_tree_add_text(tree, tvb, offset, ls_length,
2012 val_to_str(ls_type, ls_type_vals, "Unknown (%d)"));
2014 ti = proto_tree_add_text(tree, tvb, offset, OSPF_LSA_HEADER_LENGTH,
2017 ospf_lsa_tree = proto_item_add_subtree(ti, ett_ospf_lsa);
2019 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 2, "LS Age: %u seconds",
2020 tvb_get_ntohs(tvb, offset));
2021 dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset + 2, &bfinfo_v2_options);
2022 proto_tree_add_item(ospf_lsa_tree, ospf_filter[OSPFF_LS_TYPE], tvb,
2023 offset + 3, 1, FALSE);
2024 proto_tree_add_item_hidden(ospf_lsa_tree,
2025 ospf_filter[ospf_ls_type_to_filter(ls_type)], tvb,
2026 offset + 3, 1, FALSE);
2028 if (is_opaque(ls_type)) {
2029 ls_id_type = tvb_get_guint8(tvb, offset + 4);
2030 proto_tree_add_uint(ospf_lsa_tree, ospf_filter[OSPFF_LS_OPAQUE_TYPE],
2031 tvb, offset + 4, 1, ls_id_type);
2033 switch (ls_id_type) {
2035 case OSPF_LSA_MPLS_TE:
2036 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 5, 1, "Link State ID TE-LSA Reserved: %u",
2037 tvb_get_guint8(tvb, offset + 5));
2038 proto_tree_add_item(ospf_lsa_tree, ospf_filter[OSPFF_LS_MPLS_TE_INSTANCE],
2039 tvb, offset + 6, 2, FALSE);
2043 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 5, 3, "Link State ID Opaque ID: %u",
2044 tvb_get_ntoh24(tvb, offset + 5));
2049 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 4, 4, "Link State ID: %s",
2050 ip_to_str(tvb_get_ptr(tvb, offset + 4, 4)));
2053 proto_tree_add_item(ospf_lsa_tree, ospf_filter[OSPFF_ADV_ROUTER],
2054 tvb, offset + 8, 4, FALSE);
2055 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 12, 4, "LS Sequence Number: 0x%08x",
2056 tvb_get_ntohl(tvb, offset + 12));
2057 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 16, 2, "LS Checksum: %04x",
2058 tvb_get_ntohs(tvb, offset + 16));
2060 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 18, 2, "Length: %u",
2063 /* skip past the LSA header to the body */
2064 offset += OSPF_LSA_HEADER_LENGTH;
2065 if (ls_length <= OSPF_LSA_HEADER_LENGTH)
2066 return offset; /* no data, or bogus length */
2067 ls_length -= OSPF_LSA_HEADER_LENGTH;
2069 if (!disassemble_body)
2074 case OSPF_LSTYPE_ROUTER:
2075 /* flags field in an router-lsa */
2076 dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset, &bfinfo_v2_router_lsa_flags);
2078 nr_links = tvb_get_ntohs(tvb, offset + 2);
2079 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 2, 2, "Number of Links: %u",
2082 /* nr_links links follow
2083 * maybe we should put each of the links into its own subtree ???
2085 for (link_counter = 1; link_counter <= nr_links; link_counter++) {
2086 proto_tree *ospf_lsa_router_link_tree;
2087 proto_item *ti_local;
2090 /* check the Link Type and ID */
2091 link_type = tvb_get_guint8(tvb, offset + 8);
2092 switch (link_type) {
2095 link_type_str="Point-to-point connection to another router";
2096 link_type_short_str="PTP";
2097 link_id="Neighboring router's Router ID";
2100 case OSPF_LINK_TRANSIT:
2101 link_type_str="Connection to a transit network";
2102 link_type_short_str="Transit";
2103 link_id="IP address of Designated Router";
2106 case OSPF_LINK_STUB:
2107 link_type_str="Connection to a stub network";
2108 link_type_short_str="Stub";
2109 link_id="IP network/subnet number";
2112 case OSPF_LINK_VIRTUAL:
2113 link_type_str="Virtual link";
2114 link_type_short_str="Virtual";
2115 link_id="Neighboring router's Router ID";
2119 link_type_str="Unknown link type";
2120 link_type_short_str="Unknown";
2121 link_id="Unknown link ID";
2125 nr_tos = tvb_get_guint8(tvb, offset + 9);
2128 ti_local = proto_tree_add_text(ospf_lsa_tree, tvb, offset, 12 + 4 * nr_tos,
2129 "Type: %-8s ID: %-15s Data: %-15s Metric: %d",
2130 link_type_short_str,
2131 ip_to_str(tvb_get_ptr(tvb, offset, 4)),
2132 ip_to_str(tvb_get_ptr(tvb, offset + 4, 4)),
2133 tvb_get_ntohs(tvb, offset + 10));
2135 ospf_lsa_router_link_tree = proto_item_add_subtree(ti_local, ett_ospf_lsa_router_link);
2137 proto_tree_add_text(ospf_lsa_router_link_tree, tvb, offset, 4, "%s: %s", link_id,
2138 ip_to_str(tvb_get_ptr(tvb, offset, 4)));
2140 /* link_data should be specified in detail (e.g. network mask) (depends on link type)*/
2141 proto_tree_add_text(ospf_lsa_router_link_tree, tvb, offset + 4, 4, "Link Data: %s",
2142 ip_to_str(tvb_get_ptr(tvb, offset + 4, 4)));
2144 proto_tree_add_text(ospf_lsa_router_link_tree, tvb, offset + 8, 1, "Link Type: %u - %s",
2145 link_type, link_type_str);
2146 proto_tree_add_text(ospf_lsa_router_link_tree, tvb, offset + 9, 1, "Number of TOS metrics: %u",
2148 proto_tree_add_text(ospf_lsa_router_link_tree, tvb, offset + 10, 2, "TOS 0 metric: %u",
2149 tvb_get_ntohs(tvb, offset + 10));
2153 /* nr_tos metrics may follow each link
2154 * ATTENTION: TOS metrics are not tested (I don't have TOS
2156 * please send me a mail if it is/isn't working
2158 for (tos_counter = 1; tos_counter <= nr_tos; tos_counter++) {
2159 proto_tree_add_text(ospf_lsa_router_link_tree, tvb, offset, 4, "TOS: %u, Metric: %u",
2160 tvb_get_guint8(tvb, offset),
2161 tvb_get_ntohs(tvb, offset + 2));
2167 case OSPF_LSTYPE_NETWORK:
2168 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "Netmask: %s",
2169 ip_to_str(tvb_get_ptr(tvb, offset, 4)));
2172 while (offset < end_offset) {
2173 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "Attached Router: %s",
2174 ip_to_str(tvb_get_ptr(tvb, offset, 4)));
2179 case OSPF_LSTYPE_SUMMERY:
2180 /* Type 3 and 4 LSAs have the same format */
2181 case OSPF_LSTYPE_ASBR:
2182 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "Netmask: %s",
2183 ip_to_str(tvb_get_ptr(tvb, offset, 4)));
2186 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "Metric: %u",
2187 tvb_get_ntoh24(tvb, offset + 1));
2190 /* TOS-specific information, if any */
2191 while (offset < end_offset) {
2192 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "TOS: %u, Metric: %u",
2193 tvb_get_guint8(tvb, offset),
2194 tvb_get_ntoh24(tvb, offset + 1));
2199 case OSPF_LSTYPE_ASEXT:
2200 case OSPF_LSTYPE_ASEXT7:
2201 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "Netmask: %s",
2202 ip_to_str(tvb_get_ptr(tvb, offset, 4)));
2205 options = tvb_get_guint8(tvb, offset);
2206 if (options & 0x80) { /* check wether or not E bit is set */
2207 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1,
2208 "External Type: Type 2 (metric is larger than any other link state path)");
2210 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1,
2211 "External Type: Type 1 (metric is specified in the same units as interface cost)");
2213 /* the metric field of a AS-external LAS is specified in 3 bytes */
2214 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 1, 3, "Metric: %u",
2215 tvb_get_ntoh24(tvb, offset + 1));
2218 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "Forwarding Address: %s",
2219 ip_to_str(tvb_get_ptr(tvb, offset, 4)));
2222 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "External Route Tag: %u",
2223 tvb_get_ntohl(tvb, offset));
2226 /* TOS-specific information, if any */
2227 while (offset < end_offset) {
2228 options = tvb_get_guint8(tvb, offset);
2229 if (options & 0x80) { /* check wether or not E bit is set */
2230 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1,
2231 "External Type: Type 2 (metric is larger than any other link state path)");
2233 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1,
2234 "External Type: Type 1 (metric is specified in the same units as interface cost)");
2236 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "TOS: %u, Metric: %u",
2238 tvb_get_ntoh24(tvb, offset + 1));
2241 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "Forwarding Address: %s",
2242 ip_to_str(tvb_get_ptr(tvb, offset, 4)));
2245 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "External Route Tag: %u",
2246 tvb_get_ntohl(tvb, offset));
2251 case OSPF_LSTYPE_OP_LINKLOCAL:
2252 case OSPF_LSTYPE_OP_AREALOCAL:
2253 case OSPF_LSTYPE_OP_ASWIDE:
2255 * RFC 2370 opaque LSAs.
2257 dissect_ospf_lsa_opaque(tvb, offset, ospf_lsa_tree, ls_id_type,
2259 offset += ls_length;
2263 /* unknown LSA type */
2264 proto_tree_add_text(ospf_lsa_tree, tvb, offset, ls_length,
2265 "Unknown LSA Type");
2266 offset += ls_length;
2269 /* return the offset of the next LSA */
2274 dissect_ospf_v3_lsa(tvbuff_t *tvb, int offset, proto_tree *tree,
2275 gboolean disassemble_body)
2277 proto_tree *ospf_lsa_tree;
2287 const char *link_type_str;
2290 guint8 router_priority;
2291 guint32 number_prefixes;
2292 guint8 prefix_length;
2295 guint16 referenced_ls_type;
2298 guint32 external_route_tag;
2301 ls_type = tvb_get_ntohs(tvb, offset + 2);
2302 ls_length = tvb_get_ntohs(tvb, offset + 18);
2303 end_offset = offset + ls_length;
2305 if (disassemble_body) {
2306 ti = proto_tree_add_text(tree, tvb, offset, ls_length,
2307 "%s (Type: 0x%04x)", val_to_str(ls_type, v3_ls_type_vals,"Unknown"), ls_type);
2309 ti = proto_tree_add_text(tree, tvb, offset, OSPF_LSA_HEADER_LENGTH,
2312 ospf_lsa_tree = proto_item_add_subtree(ti, ett_ospf_lsa);
2314 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 2, "LS Age: %u seconds",
2315 tvb_get_ntohs(tvb, offset));
2317 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 2, 2, "LSA Type: 0x%04x (%s)",
2318 ls_type, val_to_str(ls_type, v3_ls_type_vals,"Unkown"));
2320 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 4, 4, "Link State ID: %s",
2321 ip_to_str(tvb_get_ptr(tvb, offset + 4, 4)));
2323 proto_tree_add_item(ospf_lsa_tree, ospf_filter[OSPFF_ADV_ROUTER],
2324 tvb, offset + 8, 4, FALSE);
2325 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 12, 4, "LS Sequence Number: 0x%08x",
2326 tvb_get_ntohl(tvb, offset + 12));
2327 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 16, 2, "LS Checksum: %04x",
2328 tvb_get_ntohs(tvb, offset + 16));
2330 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 18, 2, "Length: %u",
2333 /* skip past the LSA header to the body */
2334 offset += OSPF_LSA_HEADER_LENGTH;
2335 ls_length -= OSPF_LSA_HEADER_LENGTH;
2337 if (!disassemble_body)
2343 case OSPF_V3_LSTYPE_ROUTER:
2344 /* flags field in an router-lsa */
2345 dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset, &bfinfo_v3_router_lsa_flags);
2347 /* options field in an router-lsa */
2348 dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset + 1, &bfinfo_v3_options);
2350 /* skip the router-lsa flags and options */
2355 proto_tree_add_text(ospf_lsa_tree, tvb, offset, ls_length,
2356 "Router Interfaces:");
2358 /* scan all router-lsa router interfaces */
2359 /* maybe we should put each of the links into its own subtree ??? */
2360 while (ls_length > 0 ) {
2362 /* check the type */
2363 link_type = tvb_get_guint8(tvb, offset);
2364 switch (link_type) {
2366 case OSPF_V3_LINK_PTP:
2367 link_type_str="Point-to-point connection to another router";
2370 case OSPF_V3_LINK_TRANSIT:
2371 link_type_str="Connection to a transit network";
2374 case OSPF_V3_LINK_RESERVED:
2375 link_type_str="Connection to a stub network";
2378 case OSPF_V3_LINK_VIRTUAL:
2379 link_type_str="Virtual link";
2383 link_type_str="Unknown link type";
2387 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1, "Type: %u (%s)", link_type,link_type_str);
2389 /* reserved field */
2390 reserved = tvb_get_guint8(tvb, offset+1);
2391 proto_tree_add_text(ospf_lsa_tree, tvb, offset+1, 1,
2392 (reserved == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),reserved);
2395 metric=tvb_get_ntohs(tvb, offset+2);
2396 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 2, 2,"Metric: %u",metric);
2399 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 4, 4, "Interface ID: %u",
2400 tvb_get_ntohl(tvb, offset + 4));
2402 /* Neighbor Interface ID */
2403 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 8, 4, "Neighbor Interface ID: %u",
2404 tvb_get_ntohl(tvb, offset + 8));
2406 /* Neighbor Router ID */
2407 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 12, 4, "Neighbor Router ID: %s",
2408 ip_to_str(tvb_get_ptr(tvb, offset + 12, 4)));
2410 /* skip to the (possible) next entry */
2417 case OSPF_V3_LSTYPE_NETWORK:
2419 /* reserved field */
2420 reserved = tvb_get_guint8(tvb, offset);
2421 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1,
2422 (reserved == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),reserved);
2424 /* options field in an network-lsa */
2425 dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset + 1, &bfinfo_v3_options);
2430 while (ls_length > 0 ) {
2431 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "Attached Router: %s",
2432 ip_to_str(tvb_get_ptr(tvb, offset, 4)));
2439 case OSPF_V3_LSTYPE_INTER_AREA_PREFIX:
2441 /* reserved field */
2442 reserved = tvb_get_guint8(tvb, offset);
2443 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1,
2444 (reserved == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),reserved);
2447 metric=tvb_get_ntoh24(tvb, offset+1);
2448 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 1, 3,"Metric: %u",metric);
2451 prefix_length=tvb_get_guint8(tvb, offset+4);
2452 proto_tree_add_text(ospf_lsa_tree, tvb, offset+4, 1, "PrefixLength: %u",prefix_length);
2454 /* prefix options */
2455 dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset+5, &bfinfo_v3_prefix_options);
2457 /* 16 bits reserved */
2458 reserved16=tvb_get_ntohs(tvb, offset+6);
2459 proto_tree_add_text(ospf_lsa_tree, tvb, offset+6, 2,
2460 (reserved16 == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),reserved16);
2464 /* address_prefix */
2465 dissect_ospf_v3_address_prefix(tvb, offset, prefix_length, ospf_lsa_tree);
2467 offset+=(prefix_length+31)/32*4;
2472 case OSPF_V3_LSTYPE_INTER_AREA_ROUTER:
2474 /* reserved field */
2475 reserved = tvb_get_guint8(tvb, offset);
2476 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1,
2477 (reserved == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),reserved);
2479 /* options field in an inter-area-router-lsa */
2480 dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset + 1, &bfinfo_v3_options);
2482 /* reserved field */
2483 reserved = tvb_get_guint8(tvb, offset+4);
2484 proto_tree_add_text(ospf_lsa_tree, tvb, offset+4, 1,
2485 (reserved == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),reserved);
2488 metric=tvb_get_ntoh24(tvb, offset+5);
2489 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 5, 3,"Metric: %u",metric);
2491 /* Destination Router ID */
2492 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 8, 4, "Destination Router ID: %s",
2493 ip_to_str(tvb_get_ptr(tvb, offset + 8, 4)));
2499 case OSPF_V3_LSTYPE_TYPE_7:
2500 case OSPF_V3_LSTYPE_AS_EXTERNAL:
2503 dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset, &bfinfo_v3_as_external_flags);
2504 flags=tvb_get_guint8(tvb, offset);
2506 /* 24 bits metric */
2507 metric=tvb_get_ntoh24(tvb, offset+1);
2508 proto_tree_add_text(ospf_lsa_tree, tvb, offset+1, 3,
2509 "Metric: %u", metric);
2512 prefix_length=tvb_get_guint8(tvb, offset+4);
2513 proto_tree_add_text(ospf_lsa_tree, tvb, offset+4, 1, "PrefixLength: %u",prefix_length);
2515 /* prefix options */
2516 dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset+5, &bfinfo_v3_prefix_options);
2518 /* referenced LS type */
2519 referenced_ls_type=tvb_get_ntohs(tvb, offset+6);
2520 proto_tree_add_text(ospf_lsa_tree, tvb, offset+6, 2,"Referenced LS type 0x%04x (%s)",
2521 referenced_ls_type, val_to_str(referenced_ls_type, v3_ls_type_vals, "Unknown"));
2525 /* address_prefix */
2526 dissect_ospf_v3_address_prefix(tvb, offset, prefix_length, ospf_lsa_tree);
2528 offset+=(prefix_length+31)/32*4;
2530 /* Forwarding Address (optional - only if F-flag is on) */
2531 if ( (offset < end_offset) && (flags & OSPF_V3_AS_EXTERNAL_FLAG_F) ) {
2532 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 16,"Forwarding Address: %s",
2533 ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset, 16)));
2538 /* External Route Tag (optional - only if T-flag is on) */
2539 if ( (offset < end_offset) && (flags & OSPF_V3_AS_EXTERNAL_FLAG_T) ) {
2540 external_route_tag=tvb_get_ntohl(tvb, offset);
2541 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4,"External Route Tag: %u",
2542 external_route_tag);
2547 /* Referenced Link State ID (optional - only if Referenced LS type is non-zero */
2548 if ( (offset < end_offset) && (referenced_ls_type != 0) ) {
2549 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "Referenced Link State ID: %s",
2550 ip_to_str(tvb_get_ptr(tvb, offset, 4)));
2556 case OSPF_V3_LSTYPE_LINK:
2558 /* router priority */
2559 router_priority=tvb_get_guint8(tvb, offset);
2560 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1, "Router Priority: %u", router_priority);
2562 /* options field in an link-lsa */
2563 dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset + 1, &bfinfo_v3_options);
2565 /* Link-local Interface Address */
2566 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 4, 16, "Link-local Interface Address: %s",
2567 ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset + 4, 16)));
2569 /* Number prefixes */
2570 number_prefixes=tvb_get_ntohl(tvb, offset + 20);
2571 proto_tree_add_text(ospf_lsa_tree, tvb, offset+20, 4, "# prefixes: %d",number_prefixes);
2575 while (number_prefixes > 0) {
2578 prefix_length=tvb_get_guint8(tvb, offset);
2579 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1, "PrefixLength: %u",prefix_length);
2581 /* prefix options */
2582 dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset+1, &bfinfo_v3_prefix_options);
2584 /* 16 bits reserved */
2585 reserved16=tvb_get_ntohs(tvb, offset+2);
2586 proto_tree_add_text(ospf_lsa_tree, tvb, offset+2, 2,
2587 (reserved16 == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),reserved16);
2591 /* address_prefix */
2592 dissect_ospf_v3_address_prefix(tvb, offset, prefix_length, ospf_lsa_tree);
2594 offset+=(prefix_length+31)/32*4;
2601 case OSPF_V3_LSTYPE_INTRA_AREA_PREFIX:
2604 number_prefixes=tvb_get_ntohs(tvb, offset);
2605 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 2,"# prefixes: %u",number_prefixes);
2607 /* referenced LS type */
2608 referenced_ls_type=tvb_get_ntohs(tvb, offset+2);
2609 proto_tree_add_text(ospf_lsa_tree, tvb, offset+2, 2,"Referenced LS type 0x%04x (%s)",
2610 referenced_ls_type, val_to_str(referenced_ls_type, v3_ls_type_vals, "Unknown"));
2612 /* Referenced Link State ID */
2613 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 4, 4, "Referenced Link State ID: %s",
2614 ip_to_str(tvb_get_ptr(tvb, offset + 4, 4)));
2616 /* Referenced Advertising Router */
2617 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 8, 4, "Referenced Advertising Router: %s",
2618 ip_to_str(tvb_get_ptr(tvb, offset + 8, 4)));
2622 while (number_prefixes > 0) {
2625 prefix_length=tvb_get_guint8(tvb, offset);
2626 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1, "PrefixLength: %u",prefix_length);
2628 /* prefix options */
2629 dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset+1, &bfinfo_v3_prefix_options);
2631 /* 16 bits metric */
2632 metric=tvb_get_ntohs(tvb, offset+2);
2633 proto_tree_add_text(ospf_lsa_tree, tvb, offset+2, 2,
2634 "Metric: %u", metric);
2638 /* address_prefix */
2639 dissect_ospf_v3_address_prefix(tvb, offset, prefix_length, ospf_lsa_tree);
2641 offset+=(prefix_length+31)/32*4;
2648 /* unknown LSA type */
2649 proto_tree_add_text(ospf_lsa_tree, tvb, offset, ls_length,
2650 "Unknown LSA Type 0x%04x",ls_type);
2651 offset += ls_length;
2654 /* return the offset of the next LSA */
2658 static void dissect_ospf_v3_address_prefix(tvbuff_t *tvb, int offset, int prefix_length, proto_tree *tree)
2661 int bytes_to_process;
2662 struct e_in6_addr prefix;
2664 bytes_to_process=((prefix_length+31)/32)*4;
2666 if (prefix_length > 128) {
2667 proto_tree_add_text(tree, tvb, offset, bytes_to_process,
2668 "Address Prefix: length is invalid (%d, should be <= 128)",
2673 memset(prefix.bytes, 0, sizeof prefix.bytes);
2674 if (bytes_to_process != 0) {
2675 tvb_memcpy(tvb, prefix.bytes, offset, bytes_to_process);
2676 if (prefix_length % 8) {
2677 prefix.bytes[bytes_to_process - 1] &=
2678 ((0xff00 >> (prefix_length % 8)) & 0xff);
2681 proto_tree_add_text(tree, tvb, offset, bytes_to_process,
2682 "Address Prefix: %s", ip6_to_str(&prefix));
2688 proto_register_ospf(void)
2690 static gint *ett[] = {
2697 &ett_ospf_lsa_router_link,
2700 &ett_ospf_lsa_mpls_router,
2701 &ett_ospf_lsa_mpls_link,
2702 &ett_ospf_lsa_mpls_link_stlv,
2703 &ett_ospf_lsa_mpls_link_stlv_admingrp,
2704 &ett_ospf_lsa_oif_tna,
2705 &ett_ospf_lsa_oif_tna_stlv,
2706 &ett_ospf_v2_options,
2707 &ett_ospf_v3_options,
2709 &ett_ospf_lls_data_block,
2711 &ett_ospf_lls_ext_options,
2712 &ett_ospf_v2_router_lsa_flags,
2713 &ett_ospf_v3_router_lsa_flags,
2714 &ett_ospf_v3_as_external_flags,
2715 &ett_ospf_v3_prefix_options
2718 proto_ospf = proto_register_protocol("Open Shortest Path First",
2720 proto_register_field_array(proto_ospf, ospff_info, array_length(ospff_info));
2721 proto_register_subtree_array(ett, array_length(ett));
2725 proto_reg_handoff_ospf(void)
2727 dissector_handle_t ospf_handle;
2729 ospf_handle = create_dissector_handle(dissect_ospf, proto_ospf);
2730 dissector_add("ip.proto", IP_PROTO_OSPF, ospf_handle);
2731 data_handle = find_dissector("data");