HACK: 2nd try to match RowsetProperties
[wireshark-wip.git] / epan / dissectors / packet-ospf.c
blobbec917fc046ab51fd4bc1b54ce4c8541a0bc4682
1 /* packet-ospf.c
2 * Routines for OSPF packet disassembly
3 * (c) Copyright Hannes R. Boehm <hannes@boehm.org>
5 * $Id$
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 * At this time, this module is able to analyze OSPF
27 * packets as specified in RFC2328. MOSPF (RFC1584) and other
28 * OSPF Extensions which introduce new Packet types
29 * (e.g the External Atributes LSA) are not supported.
30 * Furthermore RFC2740 (OSPFv3 - OSPF for IPv6) is now supported
31 * - (c) 2001 Palle Lyckegaard <palle[AT]lyckegaard.dk>
33 * Added support to E-NNI routing (OIF2003.259.02)
34 * - (c) 2004 Roberto Morro <roberto.morro[AT]tilab.com>
36 * Added support for OSPF restart signaling:
37 * draft-nguyen-ospf-lls-05.txt
38 * draft-nguyen-ospf-oob-resync-05.txt
39 * draft-nguyen-ospf-restart-05.txt
40 * - (c) 2005 Michael Rozhavsky <mrozhavsky@fortinet.com>
42 * Added support of MPLS Diffserv-aware TE (RFC 4124); new BC sub-TLV
43 * - (c) 2006 (FF) <francesco.fondelli[AT]gmail.com>
45 * Added support for decoding the TLVs in a grace-LSA
46 * - (c) 2007 Todd J Martin <todd.martin@acm.org>
48 * Added support for draft-ietf-ospf-manet-or-02
49 * Added support for draft-ietf-ospf-af-alt-06
50 * - (c) 2008 Cisco Systems
52 * Added support for Multi-Topology (MT) Routing (RFC4915)
53 * - (c) 2009 Stig Bjorlykke <stig@bjorlykke.org>, Thales Norway AS
55 * Added support for OSPFv2 & OSPFv3 Router Information (RI) Opaque LSA (RFC4970); RI Capabilities TLV
56 * Added support for OSPFv2 & OSPFv3 Dynamic Hostname TLV in RI Opaque LSA (RFC5642)
57 * - (c) 2011 Salil Kanitkar <sskanitk@ncsu.edu>, North Carolina State University
59 * Added support for Type Classification of Experimental and Reserved sub-TLVs (RFC3630)
60 * - (c) 2013 Kaushal Shah <kshah3@ncsu.edu>, North Carolina State University
63 #include "config.h"
65 #include <string.h>
66 #include <glib.h>
67 #include <epan/packet.h>
68 #include <epan/ipproto.h>
69 #include <epan/in_cksum.h>
70 #include <epan/wmem/wmem.h>
71 #include <epan/addr_resolv.h>
72 #include "packet-rsvp.h"
74 #define OSPF_VERSION_2 2
75 #define OSPF_VERSION_3 3
76 #define OSPF_AF_4 4
77 #define OSPF_AF_6 6
78 #define OSPF_VERSION_2_HEADER_LENGTH 24
79 #define OSPF_VERSION_3_HEADER_LENGTH 16
82 #define OSPF_HELLO 1
83 #define OSPF_DB_DESC 2
84 #define OSPF_LS_REQ 3
85 #define OSPF_LS_UPD 4
86 #define OSPF_LS_ACK 5
88 static const value_string pt_vals[] = {
89 {OSPF_HELLO, "Hello Packet" },
90 {OSPF_DB_DESC, "DB Description" },
91 {OSPF_LS_REQ, "LS Request" },
92 {OSPF_LS_UPD, "LS Update" },
93 {OSPF_LS_ACK, "LS Acknowledge" },
94 {0, NULL }
97 #define OSPF_AUTH_NONE 0
98 #define OSPF_AUTH_SIMPLE 1
99 #define OSPF_AUTH_CRYPT 2
101 static const value_string auth_vals[] = {
102 {OSPF_AUTH_NONE, "Null" },
103 {OSPF_AUTH_SIMPLE, "Simple password" },
104 {OSPF_AUTH_CRYPT, "Cryptographic" },
105 {0, NULL }
108 #define OSPF_V2_OPTIONS_MT 0x01
109 #define OSPF_V2_OPTIONS_E 0x02
110 #define OSPF_V2_OPTIONS_MC 0x04
111 #define OSPF_V2_OPTIONS_NP 0x08
112 #define OSPF_V2_OPTIONS_L 0x10
113 #define OSPF_V2_OPTIONS_DC 0x20
114 #define OSPF_V2_OPTIONS_O 0x40
115 #define OSPF_V2_OPTIONS_DN 0x80
116 #define OSPF_V3_OPTIONS_V6 0x01
117 #define OSPF_V3_OPTIONS_E 0x02
118 #define OSPF_V3_OPTIONS_MC 0x04
119 #define OSPF_V3_OPTIONS_N 0x08
120 #define OSPF_V3_OPTIONS_R 0x10
121 #define OSPF_V3_OPTIONS_DC 0x20
122 #define OSPF_V3_OPTIONS_AF 0x0100
123 #define OSPF_V3_OPTIONS_L 0x0200
124 #define OSPF_V3_OPTIONS_I 0x0400
125 #define OSPF_V3_OPTIONS_F 0x0800
127 /* Bitmask definitions for the informational capabilities bits. */
128 #define OSPF_RI_OPTIONS_GRC 0x80
129 #define OSPF_RI_OPTIONS_GRH 0x40
130 #define OSPF_RI_OPTIONS_SRS 0x20
131 #define OSPF_RI_OPTIONS_TES 0x10
132 #define OSPF_RI_OPTIONS_P2PLAN 0x08
133 #define OSPF_RI_OPTIONS_ETE 0x04
135 #define OSPF_LLS_EXT_OPTIONS_LR 0x00000001
136 #define OSPF_LLS_EXT_OPTIONS_RS 0x00000002
138 #define OSPF_V3_LLS_EXT_OPTIONS_LR 0x00000001
139 #define OSPF_V3_LLS_EXT_OPTIONS_RS 0x00000002
141 #define OSPF_V3_LLS_STATE_OPTIONS_R 0x80
142 #define OSPF_V3_LLS_STATE_OPTIONS_A 0x40
143 #define OSPF_V3_LLS_STATE_OPTIONS_N 0x20
144 #define OSPF_V3_LLS_RELAY_OPTIONS_A 0x80
145 #define OSPF_V3_LLS_RELAY_OPTIONS_N 0x40
147 #define OSPF_DBD_FLAG_MS 1
148 #define OSPF_DBD_FLAG_M 2
149 #define OSPF_DBD_FLAG_I 4
150 #define OSPF_DBD_FLAG_R 8
152 #define OSPF_LS_REQ_LENGTH 12
154 #define OSPF_LSTYPE_ROUTER 1
155 #define OSPF_LSTYPE_NETWORK 2
156 #define OSPF_LSTYPE_SUMMERY 3
157 #define OSPF_LSTYPE_ASBR 4
158 #define OSPF_LSTYPE_ASEXT 5
159 #define OSPF_LSTYPE_GRPMEMBER 6
160 #define OSPF_LSTYPE_ASEXT7 7
161 #define OSPF_LSTYPE_EXTATTR 8
162 #define OSPF_V3_LSTYPE_ROUTER 0x2001
163 #define OSPF_V3_LSTYPE_NETWORK 0x2002
164 #define OSPF_V3_LSTYPE_INTER_AREA_PREFIX 0x2003
165 #define OSPF_V3_LSTYPE_INTER_AREA_ROUTER 0x2004
166 #define OSPF_V3_LSTYPE_AS_EXTERNAL 0x4005
167 #define OSPF_V3_LSTYPE_GROUP_MEMBERSHIP 0x2006
168 #define OSPF_V3_LSTYPE_NSSA 0x2007
169 #define OSPF_V3_LSTYPE_LINK 0x0008
170 #define OSPF_V3_LSTYPE_INTRA_AREA_PREFIX 0x2009
171 #define OSPF_V3_LSTYPE_OPAQUE_RI 0x800c
173 /* Opaque LSA types */
174 #define OSPF_LSTYPE_OP_LINKLOCAL 9
175 #define OSPF_LSTYPE_OP_AREALOCAL 10
176 #define OSPF_LSTYPE_OP_ASWIDE 11
178 #define OSPF_V3_LSA_FUNCTION_CODE_ROUTER 1
179 #define OSPF_V3_LSA_FUNCTION_CODE_NETWORK 2
180 #define OSPF_V3_LSA_FUNCTION_CODE_INTER_AREA_PREFIX 3
181 #define OSPF_V3_LSA_FUNCTION_CODE_INTER_AREA_ROUTER 4
182 #define OSPF_V3_LSA_FUNCTION_CODE_AS_EXTERNAL 5
183 #define OSPF_V3_LSA_FUNCTION_CODE_GROUP_MEMBERSHIP 6
184 #define OSPF_V3_LSA_FUNCTION_CODE_NSSA 7
185 #define OSPF_V3_LSA_FUNCTION_CODE_LINK 8
186 #define OSPF_V3_LSA_FUNCTION_CODE_INTRA_AREA_PREFIX 9
187 #define OSPF_V3_LSA_FUNCTION_CODE_OPAQUE_RI 12
189 #define OSPF_LINK_PTP 1
190 #define OSPF_LINK_TRANSIT 2
191 #define OSPF_LINK_STUB 3
192 #define OSPF_LINK_VIRTUAL 4
194 #define OSPF_V3_LINK_PTP 1
195 #define OSPF_V3_LINK_TRANSIT 2
196 #define OSPF_V3_LINK_RESERVED 3
197 #define OSPF_V3_LINK_VIRTUAL 4
199 #define OSPF_LSA_HEADER_LENGTH 20
201 #define OSPF_DNA_LSA 0x8000
202 /* Known opaque LSAs */
203 #define OSPF_LSA_MPLS_TE 1
204 #define OSPF_LSA_GRACE 3
205 /* The type field "4" indicates the Opaque RI LSA with Optional Router Capabilites
206 advertized in the first TLV. (RFC4970) */
207 #define OSPF_LSA_OPAQUE_RI 4
208 #define OSPF_LSA_UNKNOWN 11
209 #define OSPF_RESTART_REASON_UNKNOWN 0
210 #define OSPF_RESTART_REASON_SWRESTART 1
211 #define OSPF_RESTART_REASON_SWRELOAD 2
212 #define OSPF_RESTART_REASON_SWITCH 3
214 static const value_string restart_reason_vals[] = {
215 {OSPF_RESTART_REASON_UNKNOWN, "Unknown" },
216 {OSPF_RESTART_REASON_SWRESTART, "Software Restart" },
217 {OSPF_RESTART_REASON_SWRELOAD, "Software Reload/Upgrade" },
218 {OSPF_RESTART_REASON_SWITCH, "Processor Switchover" },
219 {0, NULL}
222 /* grace-LSA TLV Types */
223 #define GRACE_TLV_PERIOD 1
224 #define GRACE_TLV_REASON 2
225 #define GRACE_TLV_IP 3
227 static const value_string grace_tlv_type_vals[] = {
228 {GRACE_TLV_PERIOD, "grace-LSA Grace Period"},
229 {GRACE_TLV_REASON, "grace-LSA Restart Reason"},
230 {GRACE_TLV_IP, "grace-LSA Restart IP"},
231 {0, NULL}
234 /* Opaque-LSA - Router Informational Capabilities: TLV Types*/
235 #define OPT_RI_TLV 1
236 #define DYN_HOSTNAME_TLV 7
238 #if 0
239 /* The Opaque RI LSA TLV types definitions. */
240 static const value_string ri_tlv_type_vals[] = {
241 {OPT_RI_TLV, "Optional Router Informational Capabilities TLV"},
242 {DYN_HOSTNAME_TLV, "Dynamic Hostname TLV"},
243 {0, NULL}
245 #endif
247 static const value_string ls_type_vals[] = {
248 {OSPF_LSTYPE_ROUTER, "Router-LSA" },
249 {OSPF_LSTYPE_NETWORK, "Network-LSA" },
250 {OSPF_LSTYPE_SUMMERY, "Summary-LSA (IP network)" },
251 {OSPF_LSTYPE_ASBR, "Summary-LSA (ASBR)" },
252 {OSPF_LSTYPE_ASEXT, "AS-External-LSA (ASBR)" },
253 {OSPF_LSTYPE_GRPMEMBER, "Group Membership LSA" },
254 {OSPF_LSTYPE_ASEXT7, "NSSA AS-External-LSA" },
255 {OSPF_LSTYPE_EXTATTR, "External Attributes LSA" },
256 {OSPF_LSTYPE_OP_LINKLOCAL, "Opaque LSA, Link-local scope" },
257 {OSPF_LSTYPE_OP_AREALOCAL, "Opaque LSA, Area-local scope" },
258 {0, NULL }
262 static const value_string ls_opaque_type_vals[] = {
263 {OSPF_LSA_MPLS_TE, "Traffic Engineering LSA" },
264 {2, "Sycamore Optical Topology Descriptions" },
265 {OSPF_LSA_GRACE, "grace-LSA" },
266 {OSPF_LSA_OPAQUE_RI, "Optional Router Capabilities Opaque RI LSA" },
267 {0, NULL }
270 static const value_string v3_ls_type_vals[] = {
271 {OSPF_V3_LSTYPE_ROUTER, "Router-LSA" },
272 {OSPF_V3_LSTYPE_NETWORK, "Network-LSA" },
273 {OSPF_V3_LSTYPE_INTER_AREA_PREFIX, "Inter-Area-Prefix-LSA" },
274 {OSPF_V3_LSTYPE_INTER_AREA_ROUTER, "Inter-Area-Router-LSA" },
275 {OSPF_V3_LSTYPE_AS_EXTERNAL, "AS-External-LSA" },
276 {OSPF_V3_LSTYPE_GROUP_MEMBERSHIP, "Group-Membership-LSA" },
277 {OSPF_V3_LSTYPE_NSSA, "NSSA-LSA" },
278 {OSPF_V3_LSTYPE_LINK, "Link-LSA" },
279 {OSPF_V3_LSTYPE_INTRA_AREA_PREFIX, "Intra-Area-Prefix-LSA" },
280 {OSPF_V3_LSTYPE_OPAQUE_RI, "Router Information Opaque-LSA"},
281 {0, NULL }
284 static const value_string lls_tlv_type_vals[] = {
285 {1, "Extended options TLV" },
286 {2, "Crypto Authentication TLV" },
287 {0, NULL }
290 /* OSPFv3 LLS TLV Types */
291 #define LLS_V3_EXT_OPT 1
292 #define LLS_V3_STATE_CHECK 3
293 #define LLS_V3_NBR_DROP 4
294 #define LLS_V3_RELAYS 7
295 #define LLS_V3_WILLING 8
296 #define LLS_V3_RQST_FROM 5
297 #define LLS_V3_FULL_STATE 6
299 static const value_string lls_v3_tlv_type_vals[] = {
300 {LLS_V3_EXT_OPT, "Extended Options TLV" },
301 {LLS_V3_STATE_CHECK, "State Check Sequence TLV" },
302 {LLS_V3_NBR_DROP, "Neighbor Drop TLV" },
303 {LLS_V3_RELAYS, "Active Overlapping Relays TLV" },
304 {LLS_V3_WILLING, "Willingness TLV" },
305 {LLS_V3_RQST_FROM, "Request From LTV" },
306 {LLS_V3_FULL_STATE, "Full State For TLV" },
307 {0, NULL }
310 static const value_string mpls_link_stlv_ltype_str[] = {
311 {1, "Point-to-point"},
312 {2, "Multi-access"},
313 {0, NULL}
316 /* FF: from www.iana.org/assignments/bandwidth-constraints-model-ids */
317 static const range_string mpls_link_stlv_bcmodel_rvals[] = {
318 { 0, 0, "(Russian Dolls Model - RDM)" },
319 { 1, 1, "(Maximum Allocation Model - MAM)" },
320 { 2, 2, "(Maximum Allocation with Reservation Model - MAR)" },
321 { 3, 239, "(Unassigned, Specification Required)" },
322 { 240, 255, "(Reserved, Private Use)" },
323 { 0, 0, NULL }
326 #define OSPF_V2_ROUTER_LSA_FLAG_B 0x01
327 #define OSPF_V2_ROUTER_LSA_FLAG_E 0x02
328 #define OSPF_V2_ROUTER_LSA_FLAG_V 0x04
329 #define OSPF_V2_ROUTER_LSA_FLAG_W 0x08
330 #define OSPF_V2_ROUTER_LSA_FLAG_N 0x10
331 #define OSPF_V3_ROUTER_LSA_FLAG_B 0x01
332 #define OSPF_V3_ROUTER_LSA_FLAG_E 0x02
333 #define OSPF_V3_ROUTER_LSA_FLAG_V 0x04
334 #define OSPF_V3_ROUTER_LSA_FLAG_W 0x08
336 #define OSPF_V3_PREFIX_OPTION_NU 0x01
337 #define OSPF_V3_PREFIX_OPTION_LA 0x02
338 #define OSPF_V3_PREFIX_OPTION_MC 0x04
339 #define OSPF_V3_PREFIX_OPTION_P 0x08
341 #define OSPF_V3_AS_EXTERNAL_FLAG_T 0x01
342 #define OSPF_V3_AS_EXTERNAL_FLAG_F 0x02
343 #define OSPF_V3_AS_EXTERNAL_FLAG_E 0x04
346 static int proto_ospf = -1;
348 static gint ett_ospf = -1;
349 static gint ett_ospf_hdr = -1;
350 static gint ett_ospf_hello = -1;
351 static gint ett_ospf_desc = -1;
352 static gint ett_ospf_lsr = -1;
353 static gint ett_ospf_lsa = -1;
354 static gint ett_ospf_lsa_router_link = -1;
355 static gint ett_ospf_lsa_upd = -1;
356 static gint ett_ospf_v2_options = -1;
357 static gint ett_ospf_ri_options = -1;
358 static gint ett_ospf_v3_options = -1;
359 static gint ett_ospf_dbd = -1;
360 static gint ett_ospf_lls_data_block = -1;
361 static gint ett_ospf_lls_tlv = -1;
362 static gint ett_ospf_lls_ext_options = -1;
363 static gint ett_ospf_v3_lls_ext_options_tlv = -1;
364 static gint ett_ospf_v3_lls_ext_options = -1;
365 static gint ett_ospf_v3_lls_state_tlv = -1;
366 static gint ett_ospf_v3_lls_state_scs = -1;
367 static gint ett_ospf_v3_lls_state_options = -1;
368 static gint ett_ospf_v3_lls_drop_tlv = -1;
369 static gint ett_ospf_v3_lls_relay_tlv = -1;
370 static gint ett_ospf_v3_lls_relay_added = -1;
371 static gint ett_ospf_v3_lls_relay_options = -1;
372 static gint ett_ospf_v3_lls_willingness_tlv = -1;
373 static gint ett_ospf_v3_lls_willingness = -1;
374 static gint ett_ospf_v3_lls_rf_tlv = -1;
375 static gint ett_ospf_v3_lls_fsf_tlv = -1;
376 static gint ett_ospf_v2_router_lsa_flags = -1;
377 static gint ett_ospf_v3_router_lsa_flags = -1;
378 static gint ett_ospf_v3_as_external_flags = -1;
379 static gint ett_ospf_v3_prefix_options = -1;
381 /* Trees for opaque LSAs */
382 static gint ett_ospf_lsa_mpls = -1;
383 static gint ett_ospf_lsa_mpls_router = -1;
384 static gint ett_ospf_lsa_mpls_link = -1;
385 static gint ett_ospf_lsa_mpls_link_stlv = -1;
386 static gint ett_ospf_lsa_mpls_link_stlv_admingrp = -1;
387 static gint ett_ospf_lsa_oif_tna = -1;
388 static gint ett_ospf_lsa_oif_tna_stlv = -1;
389 static gint ett_ospf_lsa_grace_tlv = -1;
390 static gint ett_ospf_lsa_opaque_ri = -1;
391 static gint ett_ospf_lsa_ri_tlv = -1;
392 static gint ett_ospf_lsa_dyn_hostname_tlv = -1;
393 static gint ett_ospf_lsa_unknown_tlv = -1;
396 static const true_false_string tfs_v2_options_dc = {
397 "Demand Circuits are supported",
398 "Demand Circuits are NOT supported"
400 static const true_false_string tfs_v2_options_l = {
401 "The packet contains LLS data block",
402 "The packet does NOT contain LLS data block"
404 static const true_false_string tfs_v2_options_np = {
405 "NSSA is supported",
406 "NSSA is NOT supported"
408 static const true_false_string tfs_v2_options_mc = {
409 "Multicast Capable",
410 "NOT Multicast Capable"
412 static const true_false_string tfs_v2_options_e = {
413 "External Routing Capability",
414 "NO External Routing Capability"
416 static const true_false_string tfs_v2_options_mt = {
417 "Multi-Topology Routing",
418 "NO Multi-Topology Routing"
420 static const true_false_string tfs_v2_options_o = {
421 "O-bit is SET",
422 "O-bit is NOT set"
424 static const true_false_string tfs_v2_options_dn = {
425 "DN-bit is SET",
426 "DN-bit is NOT set"
429 /* The Options field in the first TLV of the Opaque RI LSA with type field set to "4" for OSPFv2
430 and type field set to "12" in OSPFv3, is interpreted as advertizing optional router capabilties.
431 (RFC4970) */
432 static const true_false_string tfs_ri_options_grc = {
433 "OSPF Graceful Restart Capable",
434 "NOT OSPF Graceful Restart Capable"
436 static const true_false_string tfs_ri_options_grh = {
437 "OSPF Graceful Restart Helper",
438 "NOT OSPF Graceful Restart Helper"
440 static const true_false_string tfs_ri_options_srs = {
441 "OSPF Stub Router Support",
442 "NOT OSPF Stub Router Support"
444 static const true_false_string tfs_ri_options_tes = {
445 "OSPF Traffic Engineering Support",
446 "NOT OSPF Traffic Engineering Support"
448 static const true_false_string tfs_ri_options_p2plan = {
449 "OSPF point-to-point over LAN",
450 "NOT OSPF point-to-point over LAN"
452 static const true_false_string tfs_ri_options_ete = {
453 "OSPF Experimental TE",
454 "NOT OSPF Experimental TE"
457 static const true_false_string tfs_v3_options_v6 = {
458 "V6 is SET",
459 "V6 is NOT set"
461 static const true_false_string tfs_v3_options_e = {
462 "E is SET",
463 "E is NOT set"
465 static const true_false_string tfs_v3_options_mc = {
466 "MC is SET",
467 "MC is NOT set"
469 static const true_false_string tfs_v3_options_n = {
470 "N is SET",
471 "N is NOT set"
473 static const true_false_string tfs_v3_options_r = {
474 "R is SET",
475 "R is NOT set"
477 static const true_false_string tfs_v3_options_dc = {
478 "DC is SET",
479 "DC is NOT set"
481 static const true_false_string tfs_v3_options_af = {
482 "AF is SET",
483 "AF is NOT set"
485 static const true_false_string tfs_v3_options_l = {
486 "L is SET",
487 "L is NOT set"
489 static const true_false_string tfs_v3_options_i = {
490 "I is SET",
491 "I is NOT set"
493 static const true_false_string tfs_v3_options_f = {
494 "F is SET",
495 "F is NOT set"
497 static const true_false_string tfs_dbd_i = {
498 "Init bit is SET",
499 "Init bit is NOT set"
501 static const true_false_string tfs_dbd_m = {
502 "More bit is SET",
503 "More bit is NOT set"
505 static const true_false_string tfs_dbd_ms = {
506 "Master/Slave bit is SET",
507 "Master/Slave bit is NOT set"
509 static const true_false_string tfs_dbd_r = {
510 "OOBResync bit is SET",
511 "OOBResync bit is NOT set"
513 static const true_false_string tfs_lls_ext_options_lr = {
514 "LSDB Resynchronization (LR-bit) is SET",
515 "LSDB Resynchronization (LR-bit) is NOT set"
517 static const true_false_string tfs_lls_ext_options_rs = {
518 "Restart Signal (RS-bit) is SET",
519 "Restart Signal (RS-bit) is NOT set"
521 static const true_false_string tfs_v3_lls_ext_options_lr = {
522 "LSDB Resynchronization (LR-bit) is SET",
523 "LSDB Resynchronization (LR-bit) is NOT set"
525 static const true_false_string tfs_v3_lls_ext_options_rs = {
526 "Restart Signal (RS-bit) is SET",
527 "Restart Signal (RS-bit) is NOT set"
529 static const true_false_string tfs_v3_lls_state_options_r = {
530 "Request (R-bit) is SET",
531 "Request (R-bit) is NOT set",
533 static const true_false_string tfs_v3_lls_state_options_a = {
534 "Answer (A-bit) is SET",
535 "Answer (A-bit) is NOT set",
537 static const true_false_string tfs_v3_lls_state_options_n = {
538 "Incomplete (N-bit) is SET",
539 "Incomplete (N-bit) is NOT set",
541 static const true_false_string tfs_v3_lls_relay_options_a = {
542 "Always (A-bit) is SET",
543 "Always (A-bit) is NOT set",
545 static const true_false_string tfs_v3_lls_relay_options_n = {
546 "Never (N-bit) is SET",
547 "Never (N-bit) is NOT set",
549 static const true_false_string tfs_v2_router_lsa_flags_b = {
550 "Area border router",
551 "NO Area border router"
553 static const true_false_string tfs_v2_router_lsa_flags_e = {
554 "AS boundary router",
555 "NO AS boundary router"
557 static const true_false_string tfs_v2_router_lsa_flags_v = {
558 "Virtual link endpoint",
559 "NO Virtual link endpoint"
561 static const true_false_string tfs_v2_router_lsa_flags_w = {
562 "Wild-card multicast receiver",
563 "NO Wild-card multicast receiver"
565 static const true_false_string tfs_v2_router_lsa_flags_n = {
566 "N flag",
567 "NO N flag"
569 static const true_false_string tfs_v3_router_lsa_flags_b = {
570 "Area border router",
571 "NO Area border router"
573 static const true_false_string tfs_v3_router_lsa_flags_e = {
574 "AS boundary router",
575 "NO AS boundary router"
577 static const true_false_string tfs_v3_router_lsa_flags_v = {
578 "Virtual link endpoint",
579 "NO Virtual link endpoint"
581 static const true_false_string tfs_v3_router_lsa_flags_w = {
582 "Wild-card multicast receiver",
583 "NO Wild-card multicast receiver"
585 static const true_false_string tfs_v3_as_external_flags_t = {
586 "External Route Tag is included",
587 "External Route Tag is NOT included"
589 static const true_false_string tfs_v3_as_external_flags_f = {
590 "Forwarding Address is included",
591 "Forwarding Address is NOT included"
593 static const true_false_string tfs_v3_as_external_flags_e = {
594 "Type 2 external metric",
595 "Type 1 external metric"
597 static const true_false_string tfs_v3_prefix_options_nu = {
598 "NoUnicast capability bit is SET",
599 "NoUnicast capability bit is NOT set"
601 static const true_false_string tfs_v3_prefix_options_la = {
602 "LocalAddress capability bit is SET",
603 "LocalAddress capability bit is NOT set"
605 static const true_false_string tfs_v3_prefix_options_mc = {
606 "Multicast capability bit is SET",
607 "Multicast capability bit is NOT set"
609 static const true_false_string tfs_v3_prefix_options_p = {
610 "Propagate bit is SET",
611 "Propagate bit is NOT set"
614 /*-----------------------------------------------------------------------
615 * OSPF Filtering
616 *-----------------------------------------------------------------------*/
618 /* The OSPF filtering keys */
619 enum {
621 OSPFF_MSG_TYPE,
623 OSPFF_MSG_MIN,
624 OSPFF_MSG_HELLO,
625 OSPFF_MSG_DB_DESC,
626 OSPFF_MSG_LS_REQ,
627 OSPFF_MSG_LS_UPD,
628 OSPFF_MSG_LS_ACK,
630 OSPFF_LS_TYPE,
631 OSPFF_LS_OPAQUE_TYPE,
633 OSPFF_LS_MPLS_TE_INSTANCE,
635 OSPFF_LS_MIN,
636 OSPFF_LS_ROUTER,
637 OSPFF_LS_NETWORK,
638 OSPFF_LS_SUMMARY,
639 OSPFF_LS_ASBR,
640 OSPFF_LS_ASEXT,
641 OSPFF_LS_GRPMEMBER,
642 OSPFF_LS_ASEXT7,
643 OSPFF_LS_EXTATTR,
644 OSPFF_LS_OPAQUE,
646 OSPFF_V3_LS_TYPE,
648 OSPFF_V3_LS_MIN,
649 OSPFF_V3_LS_ROUTER,
650 OSPFF_V3_LS_NETWORK,
651 OSPFF_V3_LS_INTER_AREA_PREFIX,
652 OSPFF_V3_LS_INTER_AREA_ROUTER,
653 OSPFF_V3_LS_AS_EXTERNAL,
654 OSPFF_V3_LS_GROUP_MEMBERSHIP,
655 OSPFF_V3_LS_NSSA,
656 OSPFF_V3_LS_LINK,
657 OSPFF_V3_LS_INTRA_AREA_PREFIX,
658 OSPFF_V3_LS_OPAQUE_RI,
660 OSPFF_SRC_ROUTER,
661 OSPFF_ADV_ROUTER,
662 OSPFF_LS_MPLS,
663 OSPFF_LS_MPLS_ROUTERID,
665 OSPFF_LS_MPLS_LINKTYPE,
666 OSPFF_LS_MPLS_LINKID,
667 OSPFF_LS_MPLS_LOCAL_ADDR,
668 OSPFF_LS_MPLS_REMOTE_ADDR,
669 OSPFF_LS_MPLS_LOCAL_IFID,
670 OSPFF_LS_MPLS_REMOTE_IFID,
671 OSPFF_LS_MPLS_LINKCOLOR,
672 OSPFF_LS_MPLS_BC_MODEL_ID,
673 OSPFF_LS_OIF_LOCAL_NODE_ID,
674 OSPFF_LS_OIF_REMOTE_NODE_ID,
676 OSPFF_V2_OPTIONS,
677 OSPFF_V2_OPTIONS_MT,
678 OSPFF_V2_OPTIONS_E,
679 OSPFF_V2_OPTIONS_MC,
680 OSPFF_V2_OPTIONS_NP,
681 OSPFF_V2_OPTIONS_L,
682 OSPFF_V2_OPTIONS_DC,
683 OSPFF_V2_OPTIONS_O,
684 OSPFF_V2_OPTIONS_DN,
686 /* OSPF Filtering keys for Router Informational Capabilities Options field. */
687 OSPFF_RI_OPTIONS,
688 OSPFF_RI_OPTIONS_GRC,
689 OSPFF_RI_OPTIONS_GRH,
690 OSPFF_RI_OPTIONS_SRS,
691 OSPFF_RI_OPTIONS_TES,
692 OSPFF_RI_OPTIONS_P2PLAN,
693 OSPFF_RI_OPTIONS_ETE,
695 /* OSPF Filtering keys for Dynamic Hostname support (RFC5642) */
696 OSPFF_DYN_HOSTNAME,
697 OSPFF_OPAQUE_LSA_MBZ,
699 OSPFF_UNKNOWN_TLV_TXT,
701 OSPFF_V3_OPTIONS,
702 OSPFF_V3_OPTIONS_V6,
703 OSPFF_V3_OPTIONS_E,
704 OSPFF_V3_OPTIONS_MC,
705 OSPFF_V3_OPTIONS_N,
706 OSPFF_V3_OPTIONS_R,
707 OSPFF_V3_OPTIONS_DC,
708 OSPFF_V3_OPTIONS_AF,
709 OSPFF_V3_OPTIONS_L,
710 OSPFF_V3_OPTIONS_I,
711 OSPFF_V3_OPTIONS_F,
712 OSPFF_DBD,
713 OSPFF_DBD_R,
714 OSPFF_DBD_I,
715 OSPFF_DBD_M,
716 OSPFF_DBD_MS,
717 OSPFF_LLS_EXT_OPTIONS_TLV,
718 OSPFF_LLS_EXT_OPTIONS,
719 OSPFF_LLS_EXT_OPTIONS_LR,
720 OSPFF_LLS_EXT_OPTIONS_RS,
721 OSPFF_V3_LLS_EXT_OPTIONS_TLV,
722 OSPFF_V3_LLS_EXT_OPTIONS,
723 OSPFF_V3_LLS_EXT_OPTIONS_LR,
724 OSPFF_V3_LLS_EXT_OPTIONS_RS,
725 OSPFF_V3_LLS_STATE_TLV,
726 OSPFF_V3_LLS_STATE_SCS,
727 OSPFF_V3_LLS_STATE_OPTIONS,
728 OSPFF_V3_LLS_STATE_OPTIONS_R,
729 OSPFF_V3_LLS_STATE_OPTIONS_A,
730 OSPFF_V3_LLS_STATE_OPTIONS_N,
731 OSPFF_V3_LLS_DROP_TLV,
732 OSPFF_V3_LLS_RELAY_TLV,
733 OSPFF_V3_LLS_RELAY_ADDED,
734 OSPFF_V3_LLS_RELAY_OPTIONS,
735 OSPFF_V3_LLS_RELAY_OPTIONS_A,
736 OSPFF_V3_LLS_RELAY_OPTIONS_N,
737 OSPFF_V3_LLS_WILLINGNESS_TLV,
738 OSPFF_V3_LLS_WILLINGNESS,
739 OSPFF_V3_LLS_RF_TLV,
740 OSPFF_V3_LLS_FSF_TLV,
741 OSPFF_V2_ROUTER_LSA_FLAG,
742 OSPFF_V2_ROUTER_LSA_FLAG_B,
743 OSPFF_V2_ROUTER_LSA_FLAG_E,
744 OSPFF_V2_ROUTER_LSA_FLAG_V,
745 OSPFF_V2_ROUTER_LSA_FLAG_W,
746 OSPFF_V2_ROUTER_LSA_FLAG_N,
747 OSPFF_V3_ROUTER_LSA_FLAG,
748 OSPFF_V3_ROUTER_LSA_FLAG_B,
749 OSPFF_V3_ROUTER_LSA_FLAG_E,
750 OSPFF_V3_ROUTER_LSA_FLAG_V,
751 OSPFF_V3_ROUTER_LSA_FLAG_W,
752 OSPFF_V3_AS_EXTERNAL_FLAG,
753 OSPFF_V3_AS_EXTERNAL_FLAG_T,
754 OSPFF_V3_AS_EXTERNAL_FLAG_F,
755 OSPFF_V3_AS_EXTERNAL_FLAG_E,
756 OSPFF_V3_PREFIX_OPTION,
757 OSPFF_V3_PREFIX_OPTION_NU,
758 OSPFF_V3_PREFIX_OPTION_LA,
759 OSPFF_V3_PREFIX_OPTION_MC,
760 OSPFF_V3_PREFIX_OPTION_P,
762 OSPFF_V2_GRACE_TLV,
763 OSPFF_V2_GRACE_PERIOD,
764 OSPFF_V2_GRACE_REASON,
765 OSPFF_V2_GRACE_IP,
767 OSPFF_MAX
770 static int hf_ospf_filter[OSPFF_MAX];
772 static gint ospf_msg_type_to_filter (guint8 msg_type)
774 if (msg_type >= OSPF_HELLO &&
775 msg_type <= OSPF_LS_ACK)
776 return msg_type + OSPFF_MSG_MIN;
777 return -1;
780 static gint ospf_ls_type_to_filter (guint8 ls_type)
782 if (ls_type >= OSPF_LSTYPE_ROUTER &&
783 ls_type <= OSPF_LSTYPE_EXTATTR)
784 return OSPFF_LS_MIN + ls_type;
785 else if (ls_type >= OSPF_LSTYPE_OP_LINKLOCAL &&
786 ls_type <= OSPF_LSTYPE_OP_ASWIDE)
787 return OSPFF_LS_OPAQUE;
788 else
789 return -1;
792 static gint ospf_v3_ls_type_to_filter (guint16 ls_type)
794 guint16 function_code;
796 function_code = ls_type & 0x1fff;
797 if (function_code >= OSPF_V3_LSA_FUNCTION_CODE_ROUTER &&
798 function_code <= OSPF_V3_LSA_FUNCTION_CODE_INTRA_AREA_PREFIX)
799 return OSPFF_V3_LS_MIN + function_code;
800 else if (function_code == OSPF_V3_LSA_FUNCTION_CODE_OPAQUE_RI)
801 return OSPFF_V3_LS_OPAQUE_RI;
802 else
803 return -1;
806 typedef struct _bitfield_info {
807 int hfindex;
808 gint *ett;
809 int *idx;
810 int num;
811 } bitfield_info;
813 static int bf_dbd[] = {
814 OSPFF_DBD_R,
815 OSPFF_DBD_I,
816 OSPFF_DBD_M,
817 OSPFF_DBD_MS
819 static int bf_lls_ext_options[] = {
820 OSPFF_LLS_EXT_OPTIONS_RS,
821 OSPFF_LLS_EXT_OPTIONS_LR
823 static int bf_v3_lls_ext_options[] = {
824 OSPFF_V3_LLS_EXT_OPTIONS_LR,
825 OSPFF_V3_LLS_EXT_OPTIONS_RS
828 static int bf_v3_lls_state_options[] = {
829 OSPFF_V3_LLS_STATE_OPTIONS_R,
830 OSPFF_V3_LLS_STATE_OPTIONS_A,
831 OSPFF_V3_LLS_STATE_OPTIONS_N
833 static int bf_v3_lls_relay_options[] = {
834 OSPFF_V3_LLS_RELAY_OPTIONS_A,
835 OSPFF_V3_LLS_RELAY_OPTIONS_N
837 static int bf_v2_router_lsa_flags[] = {
838 OSPFF_V2_ROUTER_LSA_FLAG_V,
839 OSPFF_V2_ROUTER_LSA_FLAG_E,
840 OSPFF_V2_ROUTER_LSA_FLAG_B
842 static int bf_v2_router_lsa_mt_flags[] = {
843 OSPFF_V2_ROUTER_LSA_FLAG_N,
844 OSPFF_V2_ROUTER_LSA_FLAG_W,
845 OSPFF_V2_ROUTER_LSA_FLAG_V,
846 OSPFF_V2_ROUTER_LSA_FLAG_E,
847 OSPFF_V2_ROUTER_LSA_FLAG_B
849 static int bf_v3_router_lsa_flags[] = {
850 OSPFF_V3_ROUTER_LSA_FLAG_W,
851 OSPFF_V3_ROUTER_LSA_FLAG_V,
852 OSPFF_V3_ROUTER_LSA_FLAG_E,
853 OSPFF_V3_ROUTER_LSA_FLAG_B
855 static int bf_v3_as_external_flags[] = {
856 OSPFF_V3_AS_EXTERNAL_FLAG_E,
857 OSPFF_V3_AS_EXTERNAL_FLAG_F,
858 OSPFF_V3_AS_EXTERNAL_FLAG_T
860 static int bf_v2_options[] = {
861 OSPFF_V2_OPTIONS_DN,
862 OSPFF_V2_OPTIONS_O,
863 OSPFF_V2_OPTIONS_DC,
864 OSPFF_V2_OPTIONS_L,
865 OSPFF_V2_OPTIONS_NP,
866 OSPFF_V2_OPTIONS_MC,
867 OSPFF_V2_OPTIONS_E,
868 OSPFF_V2_OPTIONS_MT
870 /* Structures for handling the bitfield of the Options field of Optional Router Capabilites LSA (RFC4970). */
871 static int bf_ri_options[] = {
872 OSPFF_RI_OPTIONS_GRC,
873 OSPFF_RI_OPTIONS_GRH,
874 OSPFF_RI_OPTIONS_SRS,
875 OSPFF_RI_OPTIONS_TES,
876 OSPFF_RI_OPTIONS_P2PLAN,
877 OSPFF_RI_OPTIONS_ETE
879 static int bf_v3_options[] = {
880 OSPFF_V3_OPTIONS_F,
881 OSPFF_V3_OPTIONS_I,
882 OSPFF_V3_OPTIONS_L,
883 OSPFF_V3_OPTIONS_AF,
884 OSPFF_V3_OPTIONS_DC,
885 OSPFF_V3_OPTIONS_R,
886 OSPFF_V3_OPTIONS_N,
887 OSPFF_V3_OPTIONS_MC,
888 OSPFF_V3_OPTIONS_E,
889 OSPFF_V3_OPTIONS_V6
891 static int bf_v3_prefix_options[] = {
892 OSPFF_V3_PREFIX_OPTION_P,
893 OSPFF_V3_PREFIX_OPTION_MC,
894 OSPFF_V3_PREFIX_OPTION_LA,
895 OSPFF_V3_PREFIX_OPTION_NU
898 static bitfield_info bfinfo_dbd = {
899 OSPFF_DBD, &ett_ospf_dbd,
900 bf_dbd, array_length(bf_dbd)
902 static bitfield_info bfinfo_lls_ext_options = {
903 OSPFF_LLS_EXT_OPTIONS, &ett_ospf_lls_ext_options,
904 bf_lls_ext_options, array_length(bf_lls_ext_options)
906 static bitfield_info bfinfo_v3_lls_ext_options = {
907 OSPFF_V3_LLS_EXT_OPTIONS, &ett_ospf_v3_lls_ext_options,
908 bf_v3_lls_ext_options, array_length(bf_v3_lls_ext_options)
910 static bitfield_info bfinfo_v3_lls_state_options = {
911 OSPFF_V3_LLS_STATE_OPTIONS, &ett_ospf_v3_lls_state_options,
912 bf_v3_lls_state_options, array_length(bf_v3_lls_state_options)
914 static bitfield_info bfinfo_v3_lls_relay_options = {
915 OSPFF_V3_LLS_RELAY_OPTIONS, &ett_ospf_v3_lls_relay_options,
916 bf_v3_lls_relay_options, array_length(bf_v3_lls_relay_options)
918 static bitfield_info bfinfo_v2_router_lsa_flags = {
919 OSPFF_V2_ROUTER_LSA_FLAG, &ett_ospf_v2_router_lsa_flags,
920 bf_v2_router_lsa_flags, array_length(bf_v2_router_lsa_flags)
922 static bitfield_info bfinfo_v2_router_lsa_mt_flags = {
923 OSPFF_V2_ROUTER_LSA_FLAG, &ett_ospf_v2_router_lsa_flags,
924 bf_v2_router_lsa_mt_flags, array_length(bf_v2_router_lsa_mt_flags)
926 static bitfield_info bfinfo_v3_router_lsa_flags = {
927 OSPFF_V3_ROUTER_LSA_FLAG, &ett_ospf_v3_router_lsa_flags,
928 bf_v3_router_lsa_flags, array_length(bf_v3_router_lsa_flags)
930 static bitfield_info bfinfo_v3_as_external_flags = {
931 OSPFF_V3_AS_EXTERNAL_FLAG, &ett_ospf_v3_as_external_flags,
932 bf_v3_as_external_flags, array_length(bf_v3_as_external_flags)
934 static bitfield_info bfinfo_v2_options = {
935 OSPFF_V2_OPTIONS, &ett_ospf_v2_options,
936 bf_v2_options, array_length(bf_v2_options)
938 static bitfield_info bfinfo_v3_options = {
939 OSPFF_V3_OPTIONS, &ett_ospf_v3_options,
940 bf_v3_options, array_length(bf_v3_options)
942 static bitfield_info bfinfo_v3_prefix_options = {
943 OSPFF_V3_PREFIX_OPTION, &ett_ospf_v3_prefix_options,
944 bf_v3_prefix_options, array_length(bf_v3_prefix_options)
946 /* Structure used for dissecing the Options bitfield of the Optional Router Informational
947 Capabilities RI LSA. */
948 static bitfield_info bfinfo_ri_options = {
949 OSPFF_RI_OPTIONS, &ett_ospf_ri_options,
950 bf_ri_options, array_length(bf_ri_options)
953 #define MAX_OPTIONS_LEN 128
954 static void
955 dissect_ospf_bitfield (proto_tree *parent_tree, tvbuff_t *tvb, int offset,
956 bitfield_info *bfinfo)
958 proto_item *item = NULL;
959 proto_tree *tree = NULL;
960 guint32 flags;
961 char *str;
962 gint length, pos;
963 gint i;
964 header_field_info *hfinfo;
965 int hfindex, idx;
966 gint returned_length;
968 hfindex = hf_ospf_filter[bfinfo->hfindex];
969 hfinfo = proto_registrar_get_nth(hfindex);
970 switch (hfinfo->type) {
971 case FT_UINT8:
972 flags = tvb_get_guint8(tvb, offset);
973 length = 1;
974 break;
975 case FT_UINT16:
976 flags = tvb_get_ntohs(tvb, offset);
977 length = 2;
978 break;
979 case FT_UINT24:
980 flags = tvb_get_ntoh24(tvb, offset);
981 length = 3;
982 break;
983 case FT_UINT32:
984 flags = tvb_get_ntohl(tvb, offset);
985 length = 4;
986 break;
987 default:
988 return;
991 if (parent_tree) {
992 item = proto_tree_add_uint(parent_tree, hfindex, tvb, offset, length, flags);
993 tree = proto_item_add_subtree(item, *bfinfo->ett);
995 str = (char *)wmem_alloc(wmem_packet_scope(), MAX_OPTIONS_LEN);
996 str[0] = 0;
997 for (i = 0, pos = 0; i < bfinfo->num; i++) {
998 idx = hf_ospf_filter[bfinfo->idx[i]];
999 hfinfo = proto_registrar_get_nth(idx);
1000 if (flags & hfinfo->bitmask) {
1001 returned_length = g_snprintf(&str[pos], MAX_OPTIONS_LEN-pos, "%s%s",
1002 pos ? ", " : "",
1003 hfinfo->name);
1004 pos += MIN(returned_length, MAX_OPTIONS_LEN-pos);
1006 proto_tree_add_boolean(tree, idx, tvb, offset, length, flags);
1008 if (str[0]) {
1009 proto_item_append_text(item, " (%s)", str);
1014 static dissector_handle_t data_handle;
1016 static void dissect_ospf_hello(tvbuff_t*, int, proto_tree*, guint8, guint16);
1017 static void dissect_ospf_db_desc(tvbuff_t*, int, proto_tree*, guint8, guint16, guint8);
1018 static void dissect_ospf_ls_req(tvbuff_t*, int, proto_tree*, guint8, guint16);
1019 static void dissect_ospf_ls_upd(tvbuff_t*, int, proto_tree*, guint8, guint16, guint8);
1020 static void dissect_ospf_ls_ack(tvbuff_t*, int, proto_tree*, guint8, guint16, guint8);
1021 static void dissect_ospf_lls_data_block(tvbuff_t*, int, proto_tree*, guint8);
1023 /* dissect_ospf_v[23]lsa returns the offset of the next LSA
1024 * if disassemble_body is set to FALSE (e.g. in LSA ACK
1025 * packets), the offset is set to the offset of the next
1026 * LSA header
1028 static int dissect_ospf_v2_lsa(tvbuff_t*, int, proto_tree*, gboolean disassemble_body);
1029 static int dissect_ospf_v3_lsa(tvbuff_t*, int, proto_tree*, gboolean disassemble_body,
1030 guint8);
1032 static void dissect_ospf_v3_address_prefix(tvbuff_t *, int, int, proto_tree *, guint8);
1034 static int
1035 ospf_has_lls_block(tvbuff_t *tvb, int offset, guint8 packet_type, guint8 version)
1037 guint8 flags;
1038 guint32 v3flags;
1040 /* LLS block can be found only in HELLO and DBDESC packets */
1041 switch (packet_type) {
1042 case OSPF_HELLO:
1043 switch (version) {
1044 case OSPF_VERSION_2:
1045 flags = tvb_get_guint8 (tvb, offset + 6);
1046 return flags & OSPF_V2_OPTIONS_L;
1047 case OSPF_VERSION_3:
1048 v3flags = tvb_get_ntohl(tvb, offset + 5);
1049 v3flags = v3flags >> 8;
1050 return v3flags & OSPF_V3_OPTIONS_L;
1052 break;
1053 case OSPF_DB_DESC:
1054 switch (version) {
1055 case OSPF_VERSION_2:
1056 flags = tvb_get_guint8 (tvb, offset + 2);
1057 return flags & OSPF_V2_OPTIONS_L;
1058 case OSPF_VERSION_3:
1059 v3flags = tvb_get_ntohl(tvb, offset + 1);
1060 v3flags = v3flags >> 8;
1061 return v3flags & OSPF_V3_OPTIONS_L;
1063 break;
1066 return 0;
1069 static void
1070 dissect_ospf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1072 proto_tree *ospf_tree = NULL;
1073 proto_item *ti, *hidden_item;
1074 proto_tree *ospf_header_tree;
1075 guint8 version;
1076 guint8 packet_type;
1077 guint16 ospflen;
1078 vec_t cksum_vec[4];
1079 int cksum_vec_len;
1080 guint32 phdr[2];
1081 guint16 cksum, computed_cksum;
1082 guint length, reported_length;
1083 guint16 auth_type;
1084 char auth_data[8+1];
1085 int crypto_len = 0;
1086 unsigned int ospf_header_length;
1087 guint8 instance_ID;
1088 guint8 reserved;
1089 guint32 areaid;
1090 guint8 address_family = OSPF_AF_6;
1092 col_set_str(pinfo->cinfo, COL_PROTOCOL, "OSPF");
1093 col_clear(pinfo->cinfo, COL_INFO);
1095 version = tvb_get_guint8(tvb, 0);
1096 switch (version) {
1097 case OSPF_VERSION_2:
1098 ospf_header_length = OSPF_VERSION_2_HEADER_LENGTH;
1099 break;
1100 case OSPF_VERSION_3:
1101 ospf_header_length = OSPF_VERSION_3_HEADER_LENGTH;
1102 break;
1103 default:
1104 ospf_header_length = 14;
1105 break;
1108 packet_type = tvb_get_guint8(tvb, 1);
1109 col_add_str(pinfo->cinfo, COL_INFO,
1110 val_to_str(packet_type, pt_vals, "Unknown (%u)"));
1112 if (tree) {
1113 ospflen = tvb_get_ntohs(tvb, 2);
1115 ti = proto_tree_add_item(tree, proto_ospf, tvb, 0, -1, ENC_NA);
1116 ospf_tree = proto_item_add_subtree(ti, ett_ospf);
1118 ti = proto_tree_add_text(ospf_tree, tvb, 0, ospf_header_length,
1119 "OSPF Header");
1120 ospf_header_tree = proto_item_add_subtree(ti, ett_ospf_hdr);
1122 proto_tree_add_text(ospf_header_tree, tvb, 0, 1, "OSPF Version: %u",
1123 version);
1124 proto_tree_add_item(ospf_header_tree, hf_ospf_filter[OSPFF_MSG_TYPE],
1125 tvb, 1, 1, ENC_BIG_ENDIAN);
1127 if (ospf_msg_type_to_filter(packet_type) != -1) {
1128 hidden_item = proto_tree_add_item(ospf_header_tree,
1129 hf_ospf_filter[ospf_msg_type_to_filter(packet_type)],
1130 tvb, 1, 1, ENC_BIG_ENDIAN);
1131 PROTO_ITEM_SET_HIDDEN(hidden_item);
1133 proto_tree_add_text(ospf_header_tree, tvb, 2, 2, "Packet Length: %u",
1134 ospflen);
1135 proto_tree_add_item(ospf_header_tree, hf_ospf_filter[OSPFF_SRC_ROUTER],
1136 tvb, 4, 4, ENC_BIG_ENDIAN);
1138 areaid=tvb_get_ntohl(tvb,8);
1139 proto_tree_add_text(ospf_header_tree, tvb, 8, 4, "Area ID: %s%s",
1140 tvb_ip_to_str(tvb, 8), areaid == 0 ? " (Backbone)" : "");
1143 * Quit at this point if it's an unknown OSPF version.
1145 switch (version) {
1147 case OSPF_VERSION_2:
1148 case OSPF_VERSION_3:
1149 break;
1151 default:
1152 cksum = tvb_get_ntohs(tvb, 12);
1153 if (cksum == 0) {
1154 /* No checksum supplied in the packet. */
1155 proto_tree_add_text(ospf_header_tree, tvb, 12, 2,
1156 "Packet Checksum: 0x%04x (none)", cksum);
1157 } else {
1158 proto_tree_add_text(ospf_header_tree, tvb, 12, 2,
1159 "Packet Checksum: 0x%04x", cksum);
1161 proto_tree_add_text(ospf_tree, tvb, 14, -1,
1162 "Unknown OSPF version %u", version);
1163 return;
1166 cksum = tvb_get_ntohs(tvb, 12);
1167 length = tvb_length(tvb);
1168 /* XXX - include only the length from the OSPF header? */
1169 reported_length = tvb_reported_length(tvb);
1170 if (cksum == 0) {
1171 /* No checksum supplied in the packet. */
1172 proto_tree_add_text(ospf_header_tree, tvb, 12, 2,
1173 "Packet Checksum: 0x%04x (none)", cksum);
1174 } else if (!pinfo->fragmented && length >= reported_length
1175 && length >= ospf_header_length) {
1176 /* The packet isn't part of a fragmented datagram and isn't
1177 truncated, so we can checksum it. */
1179 switch (version) {
1181 case OSPF_VERSION_2:
1182 /* Header, not including the authentication data (the OSPFv2
1183 checksum excludes the 64-bit authentication field). */
1184 cksum_vec[0].ptr = tvb_get_ptr(tvb, 0, 16);
1185 cksum_vec[0].len = 16;
1186 if (length > ospf_header_length) {
1187 /* Rest of the packet, again not including the
1188 authentication data. */
1189 reported_length -= ospf_header_length;
1190 cksum_vec[1].ptr = tvb_get_ptr(tvb, ospf_header_length, reported_length);
1191 cksum_vec[1].len = reported_length;
1192 cksum_vec_len = 2;
1193 } else {
1194 /* There's nothing but a header. */
1195 cksum_vec_len = 1;
1197 break;
1199 case OSPF_VERSION_3:
1200 /* IPv6-style checksum, covering the entire OSPF packet
1201 and a prepended IPv6 pseudo-header. */
1203 /* Set up the fields of the pseudo-header. */
1204 cksum_vec[0].ptr = (guint8 *)pinfo->src.data;
1205 cksum_vec[0].len = pinfo->src.len;
1206 cksum_vec[1].ptr = (guint8 *)pinfo->dst.data;
1207 cksum_vec[1].len = pinfo->dst.len;
1208 cksum_vec[2].ptr = (const guint8 *)&phdr;
1209 phdr[0] = g_htonl(ospflen);
1210 phdr[1] = g_htonl(IP_PROTO_OSPF);
1211 cksum_vec[2].len = 8;
1213 cksum_vec[3].ptr = tvb_get_ptr(tvb, 0, reported_length);
1214 cksum_vec[3].len = reported_length;
1215 cksum_vec_len = 4;
1216 break;
1218 default:
1219 DISSECTOR_ASSERT_NOT_REACHED();
1220 cksum_vec_len = 0;
1221 break;
1223 computed_cksum = in_cksum(cksum_vec, cksum_vec_len);
1224 if (computed_cksum == 0) {
1225 proto_tree_add_text(ospf_header_tree, tvb, 12, 2,
1226 "Packet Checksum: 0x%04x [correct]", cksum);
1227 } else {
1228 proto_tree_add_text(ospf_header_tree, tvb, 12, 2,
1229 "Packet Checksum: 0x%04x [incorrect, should be 0x%04x]",
1230 cksum, in_cksum_shouldbe(cksum, computed_cksum));
1232 } else {
1233 proto_tree_add_text(ospf_header_tree, tvb, 12, 2,
1234 "Packet Checksum: 0x%04x", cksum);
1238 switch (version) {
1240 case OSPF_VERSION_2:
1241 /* Authentication is only valid for OSPFv2 */
1242 auth_type = tvb_get_ntohs(tvb, 14);
1243 proto_tree_add_text(ospf_header_tree, tvb, 14, 2, "Auth Type: %s",
1244 val_to_str(auth_type, auth_vals, "Unknown (%u)"));
1245 switch (auth_type) {
1247 case OSPF_AUTH_NONE:
1248 proto_tree_add_text(ospf_header_tree, tvb, 16, 8, "Auth Data (none)");
1249 break;
1251 case OSPF_AUTH_SIMPLE:
1252 tvb_get_nstringz0(tvb, 16, 8+1, auth_data);
1253 proto_tree_add_text(ospf_header_tree, tvb, 16, 8, "Auth Data: %s", auth_data);
1254 break;
1256 case OSPF_AUTH_CRYPT:
1257 proto_tree_add_text(ospf_header_tree, tvb, 18, 1, "Auth Key ID: %u",
1258 tvb_get_guint8(tvb, 18));
1259 crypto_len = tvb_get_guint8(tvb, 19);
1260 proto_tree_add_text(ospf_header_tree, tvb, 19, 1, "Auth Data Length: %u",
1261 crypto_len);
1262 proto_tree_add_text(ospf_header_tree, tvb, 20, 4, "Auth Crypto Sequence Number: 0x%x",
1263 tvb_get_ntohl(tvb, 20));
1265 /* Show the message digest that was appended to the end of the
1266 OSPF message - but only if it's present (we don't want
1267 to get an exception before we've tried dissecting OSPF
1268 message). */
1269 if (tvb_bytes_exist(tvb, ospflen, crypto_len)) {
1270 proto_tree_add_text(ospf_header_tree, tvb, ospflen, crypto_len,
1271 "Auth Data: %s",
1272 tvb_bytes_to_str(tvb, ospflen, crypto_len));
1273 proto_tree_set_appendix(ospf_header_tree, tvb, ospflen, crypto_len);
1275 break;
1277 default:
1278 proto_tree_add_text(ospf_header_tree, tvb, 16, 8, "Auth Data (unknown)");
1279 break;
1281 break;
1283 case OSPF_VERSION_3:
1284 /* Instance ID and "reserved" is OSPFv3-only */
1285 instance_ID = tvb_get_guint8(tvb, 14);
1286 ti = proto_tree_add_text(ospf_header_tree, tvb, 14, 1, "Instance ID: %u",
1287 instance_ID);
1289 if (instance_ID < 32) {
1290 proto_item_append_text(ti, " (IPv6 unicast AF)");
1291 address_family = OSPF_AF_6;
1292 } else if (instance_ID < 64) {
1293 proto_item_append_text(ti, " (IPv6 multicast AF)");
1294 address_family = OSPF_AF_6;
1295 } else if (instance_ID < 96) {
1296 proto_item_append_text(ti, " (IPv4 unicast AF)");
1297 address_family = OSPF_AF_4;
1298 } else if (instance_ID < 128) {
1299 proto_item_append_text(ti, " (IPv4 multicast AF)");
1300 address_family = OSPF_AF_4;
1301 } else {
1302 proto_item_append_text(ti, " (Reserved)");
1303 address_family = OSPF_AF_6;
1306 reserved = tvb_get_guint8(tvb, 15);
1307 proto_tree_add_text(ospf_header_tree, tvb, 15, 1,
1308 (reserved == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),
1309 reserved);
1310 break;
1312 default:
1313 DISSECTOR_ASSERT_NOT_REACHED();
1314 break;
1317 switch (packet_type){
1319 case OSPF_HELLO:
1320 dissect_ospf_hello(tvb, ospf_header_length, ospf_tree, version,
1321 (guint16)(ospflen - ospf_header_length));
1322 break;
1324 case OSPF_DB_DESC:
1325 dissect_ospf_db_desc(tvb, (int)ospf_header_length, ospf_tree, version,
1326 (guint16)(ospflen - ospf_header_length),
1327 address_family);
1328 break;
1330 case OSPF_LS_REQ:
1331 dissect_ospf_ls_req(tvb, (int)ospf_header_length, ospf_tree, version,
1332 (guint16)(ospflen - ospf_header_length));
1333 break;
1335 case OSPF_LS_UPD:
1336 dissect_ospf_ls_upd(tvb, (int)ospf_header_length, ospf_tree, version,
1337 (guint16)(ospflen - ospf_header_length),
1338 address_family);
1339 break;
1341 case OSPF_LS_ACK:
1342 dissect_ospf_ls_ack(tvb, (int)ospf_header_length, ospf_tree, version,
1343 (guint16)(ospflen - ospf_header_length),
1344 address_family);
1345 break;
1347 default:
1348 call_dissector(data_handle,
1349 tvb_new_subset_remaining(tvb, ospf_header_length), pinfo, tree);
1350 break;
1353 /* take care of the LLS data block */
1354 if (ospf_has_lls_block(tvb, ospf_header_length, packet_type, version)) {
1355 dissect_ospf_lls_data_block(tvb, ospflen + crypto_len, ospf_tree,
1356 version);
1361 static int
1362 dissect_ospfv2_lls_tlv(tvbuff_t *tvb, int offset, proto_tree *tree)
1364 proto_item *ti;
1365 proto_tree *ospf_lls_tlv_tree;
1366 guint16 type;
1367 guint16 length;
1369 type = tvb_get_ntohs(tvb, offset);
1370 length = tvb_get_ntohs(tvb, offset + 2);
1372 ti = proto_tree_add_text(tree, tvb, offset, length + 4, "%s",
1373 val_to_str_const(type, lls_tlv_type_vals, "Unknown TLV"));
1374 ospf_lls_tlv_tree = proto_item_add_subtree(ti, ett_ospf_lls_tlv);
1376 proto_tree_add_text(ospf_lls_tlv_tree, tvb, offset, 2,
1377 "Type: %d", type);
1378 proto_tree_add_text(ospf_lls_tlv_tree, tvb, offset + 2, 2,
1379 "Length: %d", length);
1381 switch(type) {
1382 case 1:
1383 dissect_ospf_bitfield(ospf_lls_tlv_tree, tvb, offset + 4, &bfinfo_lls_ext_options);
1384 break;
1385 case 2:
1386 proto_tree_add_text(ospf_lls_tlv_tree, tvb, offset + 4, 4,
1387 "Sequence number 0x%08x",
1388 tvb_get_ntohl(tvb, offset + 4));
1389 proto_tree_add_text(ospf_lls_tlv_tree, tvb, offset + 8, length - 4,
1390 "Auth Data: %s",
1391 tvb_bytes_to_str(tvb, offset + 8, length - 4));
1392 break;
1395 return offset + length + 4;
1398 static int
1399 dissect_ospfv3_lls_tlv(tvbuff_t *tvb, int offset, proto_tree *tree)
1401 proto_item *ti;
1402 proto_tree *ospf_lls_tlv_tree;
1403 guint16 type;
1404 guint16 length;
1405 guint8 relays_added;
1406 int orig_offset;
1408 type = tvb_get_ntohs(tvb, offset);
1409 length = tvb_get_ntohs(tvb, offset + 2);
1411 switch(type) {
1412 case LLS_V3_EXT_OPT:
1413 ti = proto_tree_add_item(tree, hf_ospf_filter[OSPFF_V3_LLS_EXT_OPTIONS_TLV], tvb,
1414 offset, length + 4, ENC_NA);
1415 break;
1416 case LLS_V3_STATE_CHECK:
1417 ti = proto_tree_add_item(tree, hf_ospf_filter[OSPFF_V3_LLS_STATE_TLV], tvb,
1418 offset, length + 4, ENC_NA);
1419 break;
1420 case LLS_V3_NBR_DROP:
1421 ti = proto_tree_add_item(tree, hf_ospf_filter[OSPFF_V3_LLS_DROP_TLV], tvb,
1422 offset, length + 4, ENC_NA);
1423 break;
1424 case LLS_V3_RELAYS:
1425 ti = proto_tree_add_item(tree, hf_ospf_filter[OSPFF_V3_LLS_RELAY_TLV], tvb,
1426 offset, length + 4, ENC_NA);
1427 break;
1428 case LLS_V3_WILLING:
1429 ti = proto_tree_add_item(tree, hf_ospf_filter[OSPFF_V3_LLS_WILLINGNESS_TLV], tvb,
1430 offset, length + 4, ENC_NA);
1431 break;
1432 case LLS_V3_RQST_FROM:
1433 ti = proto_tree_add_item(tree, hf_ospf_filter[OSPFF_V3_LLS_RF_TLV], tvb,
1434 offset, length + 4, ENC_NA);
1435 break;
1436 case LLS_V3_FULL_STATE:
1437 ti = proto_tree_add_item(tree, hf_ospf_filter[OSPFF_V3_LLS_FSF_TLV], tvb,
1438 offset, length + 4, ENC_NA);
1439 break;
1440 default:
1441 ti = proto_tree_add_text(tree, tvb, offset, length + 4, "%s",
1442 val_to_str_const(type, lls_v3_tlv_type_vals, "Unknown TLV"));
1445 ospf_lls_tlv_tree = proto_item_add_subtree(ti, ett_ospf_lls_tlv);
1446 proto_tree_add_text(ospf_lls_tlv_tree, tvb, offset, 2,
1447 "Type: %d", type);
1448 proto_tree_add_text(ospf_lls_tlv_tree, tvb, offset + 2, 2,
1449 "Length: %d", length);
1451 orig_offset = offset;
1453 switch (type) {
1454 case LLS_V3_EXT_OPT:
1455 proto_tree_add_text(ospf_lls_tlv_tree, tvb, offset + 4, 4,
1456 "Extended Options: 0x%08x",
1457 tvb_get_ntohl(tvb, offset + 4));
1459 dissect_ospf_bitfield(ospf_lls_tlv_tree, tvb, offset + 4, &bfinfo_v3_lls_ext_options);
1460 break;
1461 case LLS_V3_STATE_CHECK:
1462 proto_tree_add_item(ospf_lls_tlv_tree, hf_ospf_filter[OSPFF_V3_LLS_STATE_SCS],
1463 tvb, offset+4, 2, ENC_BIG_ENDIAN);
1465 dissect_ospf_bitfield(ospf_lls_tlv_tree, tvb, offset + 6,
1466 &bfinfo_v3_lls_state_options);
1467 break;
1468 case LLS_V3_NBR_DROP:
1469 offset += 4;
1470 while (orig_offset + length >= offset) {
1471 proto_tree_add_text(ospf_lls_tlv_tree, tvb, offset, 4,
1472 "Dropped Neighbor: %s",
1473 tvb_ip_to_str(tvb, offset));
1474 offset += 4;
1476 offset = orig_offset;
1477 break;
1478 case LLS_V3_RELAYS:
1479 relays_added = tvb_get_guint8(tvb, offset+4);
1480 proto_tree_add_item(ospf_lls_tlv_tree, hf_ospf_filter[OSPFF_V3_LLS_RELAY_ADDED],
1481 tvb, offset+4, 1, ENC_BIG_ENDIAN);
1482 dissect_ospf_bitfield(ospf_lls_tlv_tree, tvb, offset + 5,
1483 &bfinfo_v3_lls_relay_options);
1484 offset += 8;
1485 while (orig_offset + length >= offset) {
1486 ti = proto_tree_add_text(ospf_lls_tlv_tree, tvb, offset, 4,
1487 "Neighbor: %s",
1488 tvb_ip_to_str(tvb, offset));
1489 if (relays_added > 0) {
1490 proto_item_append_text(ti, " Added");
1491 } else {
1492 proto_item_append_text(ti, " Deleted");
1495 relays_added--;
1496 offset += 4;
1498 break;
1499 case LLS_V3_WILLING:
1500 proto_tree_add_item(ospf_lls_tlv_tree, hf_ospf_filter[OSPFF_V3_LLS_WILLINGNESS],
1501 tvb, offset+4, 1, ENC_BIG_ENDIAN);
1503 break;
1504 case LLS_V3_RQST_FROM:
1505 offset += 4;
1506 while (orig_offset + length >= offset) {
1507 proto_tree_add_text(ospf_lls_tlv_tree, tvb, offset, 4,
1508 "Request From: %s",
1509 tvb_ip_to_str(tvb, offset));
1510 offset += 4;
1512 offset = orig_offset;
1513 break;
1514 case LLS_V3_FULL_STATE:
1515 offset += 4;
1516 while (orig_offset + length >= offset) {
1517 proto_tree_add_text(ospf_lls_tlv_tree, tvb, offset, 4,
1518 "Full State For: %s",
1519 tvb_ip_to_str(tvb, offset));
1520 offset += 4;
1522 offset = orig_offset;
1523 break;
1526 return offset + length + 4;
1530 static void
1531 dissect_ospf_lls_data_block(tvbuff_t *tvb, int offset, proto_tree *tree,
1532 guint8 version)
1534 proto_tree *ospf_lls_data_block_tree;
1535 proto_item *ti;
1536 guint16 ospf_lls_len;
1537 int orig_offset = offset;
1539 ospf_lls_len = tvb_get_ntohs(tvb, offset + 2);
1540 ti = proto_tree_add_text(tree, tvb, offset, -1, "OSPF LLS Data Block");
1541 ospf_lls_data_block_tree = proto_item_add_subtree(ti,
1542 ett_ospf_lls_data_block);
1544 /* TODO: verify checksum */
1545 proto_tree_add_text(ospf_lls_data_block_tree, tvb, offset, 2,
1546 "Checksum: 0x%04x", tvb_get_ntohs(tvb, offset));
1547 proto_tree_add_text(ospf_lls_data_block_tree, tvb, offset + 2, 2,
1548 "LLS Data Length: %d bytes", ospf_lls_len * 4);
1550 offset += 4;
1551 DISSECTOR_ASSERT((version == OSPF_VERSION_2) || (version == OSPF_VERSION_3));
1552 while (orig_offset + ospf_lls_len * 4 > offset) {
1553 if (version == OSPF_VERSION_2)
1554 offset = dissect_ospfv2_lls_tlv (tvb, offset, ospf_lls_data_block_tree);
1555 else
1556 offset = dissect_ospfv3_lls_tlv (tvb, offset, ospf_lls_data_block_tree);
1560 static void
1561 dissect_ospf_hello(tvbuff_t *tvb, int offset, proto_tree *tree, guint8 version,
1562 guint16 length)
1564 proto_tree *ospf_hello_tree;
1565 proto_item *ti;
1566 int orig_offset = offset;
1568 ti = proto_tree_add_text(tree, tvb, offset, length, "OSPF Hello Packet");
1569 ospf_hello_tree = proto_item_add_subtree(ti, ett_ospf_hello);
1571 switch (version ) {
1572 case OSPF_VERSION_2:
1573 proto_tree_add_text(ospf_hello_tree, tvb, offset, 4, "Network Mask: %s",
1574 tvb_ip_to_str(tvb, offset));
1575 proto_tree_add_text(ospf_hello_tree, tvb, offset + 4, 2,
1576 "Hello Interval: %u seconds",
1577 tvb_get_ntohs(tvb, offset + 4));
1579 dissect_ospf_bitfield(ospf_hello_tree, tvb, offset + 6, &bfinfo_v2_options);
1580 proto_tree_add_text(ospf_hello_tree, tvb, offset + 7, 1, "Router Priority: %u",
1581 tvb_get_guint8(tvb, offset + 7));
1582 proto_tree_add_text(ospf_hello_tree, tvb, offset + 8, 4, "Router Dead Interval: %u seconds",
1583 tvb_get_ntohl(tvb, offset + 8));
1584 proto_tree_add_text(ospf_hello_tree, tvb, offset + 12, 4, "Designated Router: %s",
1585 tvb_ip_to_str(tvb, offset + 12));
1586 proto_tree_add_text(ospf_hello_tree, tvb, offset + 16, 4, "Backup Designated Router: %s",
1587 tvb_ip_to_str(tvb, offset + 16));
1589 offset += 20;
1590 while (orig_offset + length > offset) {
1591 proto_tree_add_text(ospf_hello_tree, tvb, offset, 4,
1592 "Active Neighbor: %s",
1593 tvb_ip_to_str(tvb, offset));
1594 offset += 4;
1596 break;
1597 case OSPF_VERSION_3:
1598 proto_tree_add_text(ospf_hello_tree, tvb, offset + 0, 4, "Interface ID: %u",
1599 tvb_get_ntohl(tvb, offset + 0));
1600 proto_tree_add_text(ospf_hello_tree, tvb, offset + 4, 1, "Router Priority: %u",
1601 tvb_get_guint8(tvb, offset + 4));
1602 dissect_ospf_bitfield(ospf_hello_tree, tvb, offset + 5, &bfinfo_v3_options);
1603 proto_tree_add_text(ospf_hello_tree, tvb, offset + 8, 2,
1604 "Hello Interval: %u seconds",
1605 tvb_get_ntohs(tvb, offset + 8));
1606 proto_tree_add_text(ospf_hello_tree, tvb, offset + 10, 2, "Router Dead Interval: %u seconds",
1607 tvb_get_ntohs(tvb, offset + 10));
1608 proto_tree_add_text(ospf_hello_tree, tvb, offset + 12, 4, "Designated Router: %s",
1609 tvb_ip_to_str(tvb, offset + 12));
1610 proto_tree_add_text(ospf_hello_tree, tvb, offset + 16, 4, "Backup Designated Router: %s",
1611 tvb_ip_to_str(tvb, offset + 16));
1612 offset += 20;
1613 while (orig_offset + length > offset) {
1614 proto_tree_add_text(ospf_hello_tree, tvb, offset, 4,
1615 "Active Neighbor: %s",
1616 tvb_ip_to_str(tvb, offset));
1617 offset += 4;
1620 break;
1624 static void
1625 dissect_ospf_db_desc(tvbuff_t *tvb, int offset, proto_tree *tree,
1626 guint8 version, guint16 length, guint8 address_family)
1628 proto_tree *ospf_db_desc_tree=NULL;
1629 proto_item *ti;
1630 guint8 reserved;
1631 int orig_offset = offset;
1633 if (tree) {
1634 ti = proto_tree_add_text(tree, tvb, offset, length, "OSPF DB Description");
1635 ospf_db_desc_tree = proto_item_add_subtree(ti, ett_ospf_desc);
1637 switch (version ) {
1639 case OSPF_VERSION_2:
1640 proto_tree_add_text(ospf_db_desc_tree, tvb, offset, 2, "Interface MTU: %u",
1641 tvb_get_ntohs(tvb, offset));
1643 dissect_ospf_bitfield(ospf_db_desc_tree, tvb, offset + 2, &bfinfo_v2_options);
1644 dissect_ospf_bitfield(ospf_db_desc_tree, tvb, offset + 3, &bfinfo_dbd);
1646 proto_tree_add_text(ospf_db_desc_tree, tvb, offset + 4, 4, "DD Sequence: %u",
1647 tvb_get_ntohl(tvb, offset + 4));
1649 offset += 8;
1650 break;
1652 case OSPF_VERSION_3:
1654 reserved = tvb_get_guint8(tvb, offset);
1655 proto_tree_add_text(ospf_db_desc_tree, tvb, offset, 1,
1656 (reserved == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),
1657 reserved);
1659 dissect_ospf_bitfield(ospf_db_desc_tree, tvb, offset + 1, &bfinfo_v3_options);
1661 proto_tree_add_text(ospf_db_desc_tree, tvb, offset + 4, 2, "Interface MTU: %u",
1662 tvb_get_ntohs(tvb, offset+4));
1664 reserved = tvb_get_guint8(tvb, offset + 6);
1665 proto_tree_add_text(ospf_db_desc_tree, tvb, offset + 6, 1,
1666 (reserved == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),
1667 reserved);
1669 dissect_ospf_bitfield(ospf_db_desc_tree, tvb, offset + 7, &bfinfo_dbd);
1671 proto_tree_add_text(ospf_db_desc_tree, tvb, offset + 8, 4, "DD Sequence: %u",
1672 tvb_get_ntohl(tvb, offset + 8));
1674 offset += 12;
1675 break;
1679 /* LS Headers will be processed here */
1680 /* skip to the end of DB-Desc header */
1681 DISSECTOR_ASSERT((version == OSPF_VERSION_2) || (version == OSPF_VERSION_3));
1682 while (orig_offset + length > offset) {
1683 if ( version == OSPF_VERSION_2)
1684 offset = dissect_ospf_v2_lsa(tvb, offset, tree, FALSE);
1685 else
1686 offset = dissect_ospf_v3_lsa(tvb, offset, tree, FALSE, address_family);
1691 static void
1692 dissect_ospf_ls_req(tvbuff_t *tvb, int offset, proto_tree *tree, guint8 version,
1693 guint16 length)
1695 proto_tree *ospf_lsr_tree;
1696 proto_item *ti;
1697 guint16 reserved;
1698 int orig_offset = offset;
1700 /* zero or more LS requests may be within a LS Request */
1701 /* we place every request for a LSA in a single subtree */
1702 while (orig_offset + length > offset) {
1703 ti = proto_tree_add_text(tree, tvb, offset, OSPF_LS_REQ_LENGTH,
1704 "Link State Request");
1705 ospf_lsr_tree = proto_item_add_subtree(ti, ett_ospf_lsr);
1707 switch ( version ) {
1709 case OSPF_VERSION_2:
1710 proto_tree_add_item(ospf_lsr_tree, hf_ospf_filter[OSPFF_LS_TYPE],
1711 tvb, offset, 4, ENC_BIG_ENDIAN);
1712 break;
1713 case OSPF_VERSION_3:
1714 reserved = tvb_get_ntohs(tvb, offset);
1715 proto_tree_add_text(ospf_lsr_tree, tvb, offset, 2,
1716 (reserved == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"), reserved);
1717 proto_tree_add_item(ospf_lsr_tree, hf_ospf_filter[OSPFF_V3_LS_TYPE],
1718 tvb, offset + 2, 2, ENC_BIG_ENDIAN);
1719 break;
1723 proto_tree_add_text(ospf_lsr_tree, tvb, offset + 4, 4, "Link State ID: %s",
1724 tvb_ip_to_str(tvb, offset + 4));
1725 proto_tree_add_item(ospf_lsr_tree, hf_ospf_filter[OSPFF_ADV_ROUTER],
1726 tvb, offset + 8, 4, ENC_BIG_ENDIAN);
1728 offset += 12;
1732 static void
1733 dissect_ospf_ls_upd(tvbuff_t *tvb, int offset, proto_tree *tree, guint8 version,
1734 guint16 length, guint8 address_family)
1736 proto_tree *ospf_lsa_upd_tree=NULL;
1737 proto_item *ti;
1738 guint32 lsa_nr;
1739 guint32 lsa_counter;
1741 ti = proto_tree_add_text(tree, tvb, offset, length, "LS Update Packet");
1742 ospf_lsa_upd_tree = proto_item_add_subtree(ti, ett_ospf_lsa_upd);
1744 lsa_nr = tvb_get_ntohl(tvb, offset);
1745 proto_tree_add_text(ospf_lsa_upd_tree, tvb, offset, 4, "Number of LSAs: %u", lsa_nr);
1746 /* skip to the beginning of the first LSA */
1747 offset += 4; /* the LS Upd Packet contains only a 32 bit #LSAs field */
1749 DISSECTOR_ASSERT((version == OSPF_VERSION_2) || (version == OSPF_VERSION_3));
1750 lsa_counter = 0;
1751 while (lsa_counter < lsa_nr) {
1752 if (version == OSPF_VERSION_2)
1753 offset = dissect_ospf_v2_lsa(tvb, offset, ospf_lsa_upd_tree, TRUE);
1754 else
1755 offset = dissect_ospf_v3_lsa(tvb, offset, ospf_lsa_upd_tree, TRUE,
1756 address_family);
1757 lsa_counter += 1;
1761 static void
1762 dissect_ospf_ls_ack(tvbuff_t *tvb, int offset, proto_tree *tree, guint8 version,
1763 guint16 length, guint8 address_family)
1765 int orig_offset = offset;
1766 DISSECTOR_ASSERT((version == OSPF_VERSION_2) || (version == OSPF_VERSION_3));
1767 /* the body of a LS Ack packet simply contains zero or more LSA Headers */
1768 while (orig_offset + length > offset) {
1769 if (version == OSPF_VERSION_2)
1770 offset = dissect_ospf_v2_lsa(tvb, offset, tree, FALSE);
1771 else
1772 offset = dissect_ospf_v3_lsa(tvb, offset, tree, FALSE, address_family);
1777 * Returns if an LSA is opaque, i.e. requires special treatment
1779 static int
1780 is_opaque(int lsa_type)
1782 return (lsa_type >= OSPF_LSTYPE_OP_LINKLOCAL &&
1783 lsa_type <= OSPF_LSTYPE_OP_ASWIDE);
1786 /* MPLS/TE TLV types */
1787 #define MPLS_TLV_ROUTER 1
1788 #define MPLS_TLV_LINK 2
1789 #define OIF_TLV_TNA 32768
1791 /* MPLS/TE Link STLV types */
1792 enum {
1793 MPLS_LINK_TYPE = 1, /* RFC 3630, OSPF-TE */
1794 MPLS_LINK_ID,
1795 MPLS_LINK_LOCAL_IF,
1796 MPLS_LINK_REMOTE_IF,
1797 MPLS_LINK_TE_METRIC,
1798 MPLS_LINK_MAX_BW,
1799 MPLS_LINK_MAX_RES_BW,
1800 MPLS_LINK_UNRES_BW,
1801 MPLS_LINK_COLOR,
1802 MPLS_LINK_LOCAL_REMOTE_ID = 11, /* RFC 4203, GMPLS */
1803 MPLS_LINK_PROTECTION = 14,
1804 MPLS_LINK_IF_SWITCHING_DESC,
1805 MPLS_LINK_SHARED_RISK_GROUP,
1806 MPLS_LINK_BANDWIDTH_CONSTRAINT = 17 /* RFC 4124, OSPF-DSTE */
1810 /* OIF TLV types */
1811 enum {
1812 OIF_LOCAL_NODE_ID = 32773,
1813 OIF_REMOTE_NODE_ID,
1814 OIF_SONET_SDH_SWITCHING_CAPABILITY,
1815 OIF_TNA_IPv4_ADDRESS,
1816 OIF_NODE_ID,
1817 OIF_TNA_IPv6_ADDRESS,
1818 OIF_TNA_NSAP_ADDRESS
1821 static const value_string mpls_link_stlv_str[] = {
1822 {MPLS_LINK_TYPE, "Link Type"},
1823 {MPLS_LINK_ID, "Link ID"},
1824 {MPLS_LINK_LOCAL_IF, "Local Interface IP Address"},
1825 {MPLS_LINK_REMOTE_IF, "Remote Interface IP Address"},
1826 {MPLS_LINK_TE_METRIC, "Traffic Engineering Metric"},
1827 {MPLS_LINK_MAX_BW, "Maximum Bandwidth"},
1828 {MPLS_LINK_MAX_RES_BW, "Maximum Reservable Bandwidth"},
1829 {MPLS_LINK_UNRES_BW, "Unreserved Bandwidth"},
1830 {MPLS_LINK_COLOR, "Resource Class/Color"},
1831 {MPLS_LINK_LOCAL_REMOTE_ID, "Link Local/Remote Identifier"},
1832 {MPLS_LINK_PROTECTION, "Link Protection Type"},
1833 {MPLS_LINK_IF_SWITCHING_DESC, "Interface Switching Capability Descriptor"},
1834 {MPLS_LINK_SHARED_RISK_GROUP, "Shared Risk Link Group"},
1835 {MPLS_LINK_BANDWIDTH_CONSTRAINT, "Bandwidth Constraints"},
1836 {OIF_LOCAL_NODE_ID, "Local Node ID"},
1837 {OIF_REMOTE_NODE_ID, "Remote Node ID"},
1838 {OIF_SONET_SDH_SWITCHING_CAPABILITY, "Sonet/SDH Interface Switching Capability"},
1839 {0, NULL},
1842 static const range_string mpls_te_tlv_rvals[] = {
1843 { 3, 32767, "(Assigned via Standards Action)"},
1844 { 32768, 32777, "(For Experimental Use)"},
1845 { 32778, 65535, "(Not to be Assigned)"},
1846 { 0, 0, NULL}
1849 static const range_string mpls_te_sub_tlv_rvals[] = {
1850 { 10, 32767, "(Assigned via Standards Action)"},
1851 { 32768, 32777, "(For Experimental Use)"},
1852 { 32778, 65535, "(Not to be Assigned)"},
1853 { 0, 0, NULL}
1856 static const value_string oif_stlv_str[] = {
1857 {OIF_TNA_IPv4_ADDRESS, "TNA address"},
1858 {OIF_NODE_ID, "Node ID"},
1859 {OIF_TNA_IPv6_ADDRESS, "TNA address"},
1860 {OIF_TNA_NSAP_ADDRESS, "TNA address"},
1861 {0, NULL},
1865 * Dissect MPLS/TE opaque LSA
1867 static void
1868 dissect_ospf_lsa_mpls(tvbuff_t *tvb, int offset, proto_tree *tree,
1869 guint32 length)
1871 proto_item *ti, *hidden_item;
1872 proto_tree *mpls_tree;
1873 proto_tree *tlv_tree;
1874 proto_tree *stlv_tree;
1875 proto_tree *stlv_admingrp_tree = NULL;
1877 int tlv_type;
1878 int tlv_length;
1879 int tlv_end_offset;
1881 int stlv_type, stlv_len, stlv_offset;
1882 const char *stlv_name;
1883 guint32 stlv_admingrp, mask;
1884 int i;
1885 guint8 switch_cap;
1887 const guint8 allzero[] = { 0x00, 0x00, 0x00 };
1888 guint num_bcs = 0;
1890 ti = proto_tree_add_text(tree, tvb, offset, length,
1891 "MPLS Traffic Engineering LSA");
1892 hidden_item = proto_tree_add_item(tree, hf_ospf_filter[OSPFF_LS_MPLS],
1893 tvb, offset, 2, ENC_BIG_ENDIAN);
1894 PROTO_ITEM_SET_HIDDEN(hidden_item);
1895 mpls_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls);
1897 while (length != 0) {
1898 tlv_type = tvb_get_ntohs(tvb, offset);
1899 tlv_length = tvb_get_ntohs(tvb, offset + 2);
1900 tlv_end_offset = offset + tlv_length + 4;
1902 switch (tlv_type) {
1904 case MPLS_TLV_ROUTER:
1905 ti = proto_tree_add_text(mpls_tree, tvb, offset, tlv_length+4,
1906 "Router Address: %s",
1907 tvb_ip_to_str(tvb, offset+4));
1908 tlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_router);
1909 proto_tree_add_text(tlv_tree, tvb, offset, 2, "TLV Type: 1 - Router Address");
1910 proto_tree_add_text(tlv_tree, tvb, offset+2, 2, "TLV Length: %u",
1911 tlv_length);
1912 proto_tree_add_item(tlv_tree, hf_ospf_filter[OSPFF_LS_MPLS_ROUTERID],
1913 tvb, offset+4, 4, ENC_BIG_ENDIAN);
1914 break;
1916 case MPLS_TLV_LINK:
1917 ti = proto_tree_add_text(mpls_tree, tvb, offset, tlv_length+4,
1918 "Link Information");
1919 tlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link);
1920 proto_tree_add_text(tlv_tree, tvb, offset, 2, "TLV Type: 2 - Link Information");
1921 proto_tree_add_text(tlv_tree, tvb, offset+2, 2, "TLV Length: %u",
1922 tlv_length);
1923 stlv_offset = offset + 4;
1925 /* Walk down the sub-TLVs for link information */
1926 while (stlv_offset < tlv_end_offset) {
1927 stlv_type = tvb_get_ntohs(tvb, stlv_offset);
1928 stlv_len = tvb_get_ntohs(tvb, stlv_offset + 2);
1929 stlv_name = val_to_str_const(stlv_type, mpls_link_stlv_str, "Unknown sub-TLV");
1930 switch (stlv_type) {
1932 case MPLS_LINK_TYPE:
1933 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1934 "%s: %u - %s", stlv_name,
1935 tvb_get_guint8(tvb, stlv_offset + 4),
1936 val_to_str_const(tvb_get_guint8(tvb, stlv_offset + 4),
1937 mpls_link_stlv_ltype_str, "Unknown Link Type"));
1938 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1939 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1940 "TLV Type: %u: %s", stlv_type, stlv_name);
1941 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1942 stlv_len);
1943 proto_tree_add_item(stlv_tree, hf_ospf_filter[OSPFF_LS_MPLS_LINKTYPE],
1944 tvb, stlv_offset+4, 1,ENC_BIG_ENDIAN);
1945 break;
1947 case MPLS_LINK_ID:
1948 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1949 "%s: %s", stlv_name,
1950 tvb_ip_to_str(tvb, stlv_offset + 4));
1951 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1952 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1953 "TLV Type: %u: %s", stlv_type, stlv_name);
1954 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1955 stlv_len);
1956 proto_tree_add_item(stlv_tree, hf_ospf_filter[OSPFF_LS_MPLS_LINKID],
1957 tvb, stlv_offset+4, 4, ENC_BIG_ENDIAN);
1958 break;
1960 case MPLS_LINK_LOCAL_IF:
1961 case MPLS_LINK_REMOTE_IF:
1962 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1963 "%s: %s", stlv_name, tvb_ip_to_str(tvb, stlv_offset + 4));
1964 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1965 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1966 "TLV Type: %u: %s", stlv_type, stlv_name);
1967 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1968 stlv_len);
1969 /* The Local/Remote Interface IP Address sub-TLV is TLV type 3/4, and is 4N
1970 octets in length, where N is the number of neighbor addresses. */
1971 for (i=0; i < stlv_len; i+=4)
1972 proto_tree_add_item(stlv_tree,
1973 stlv_type==MPLS_LINK_LOCAL_IF ?
1974 hf_ospf_filter[OSPFF_LS_MPLS_LOCAL_ADDR] :
1975 hf_ospf_filter[OSPFF_LS_MPLS_REMOTE_ADDR],
1976 tvb, stlv_offset+4+i, 4, ENC_BIG_ENDIAN);
1977 break;
1979 case MPLS_LINK_TE_METRIC:
1980 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1981 "%s: %u", stlv_name,
1982 tvb_get_ntohl(tvb, stlv_offset + 4));
1983 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1984 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1985 "TLV Type: %u: %s", stlv_type, stlv_name);
1986 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1987 stlv_len);
1988 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 4, "%s: %u", stlv_name,
1989 tvb_get_ntohl(tvb, stlv_offset + 4));
1990 break;
1992 case MPLS_LINK_COLOR:
1993 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1994 "%s: 0x%08x", stlv_name,
1995 tvb_get_ntohl(tvb, stlv_offset + 4));
1996 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1997 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1998 "TLV Type: %u: %s", stlv_type, stlv_name);
1999 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
2000 stlv_len);
2001 stlv_admingrp = tvb_get_ntohl(tvb, stlv_offset + 4);
2002 mask = 1;
2003 ti = proto_tree_add_item(stlv_tree, hf_ospf_filter[OSPFF_LS_MPLS_LINKCOLOR],
2004 tvb, stlv_offset+4, 4, ENC_BIG_ENDIAN);
2005 stlv_admingrp_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv_admingrp);
2006 if (stlv_admingrp_tree == NULL)
2007 return;
2008 for (i = 0 ; i < 32 ; i++) {
2009 if ((stlv_admingrp & mask) != 0) {
2010 proto_tree_add_text(stlv_admingrp_tree, tvb, stlv_offset+4,
2011 4, "Group %d", i);
2013 mask <<= 1;
2015 break;
2017 case MPLS_LINK_MAX_BW:
2018 case MPLS_LINK_MAX_RES_BW:
2019 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
2020 "%s: %.10g bytes/s (%.0f bits/s)", stlv_name,
2021 tvb_get_ntohieee_float(tvb, stlv_offset + 4),
2022 tvb_get_ntohieee_float(tvb, stlv_offset + 4) * 8.0);
2023 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
2024 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
2025 "TLV Type: %u: %s", stlv_type, stlv_name);
2026 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
2027 stlv_len);
2028 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 4, "%s: %.10g bytes/s (%.0f bits/s)", stlv_name,
2029 tvb_get_ntohieee_float(tvb, stlv_offset + 4),
2030 tvb_get_ntohieee_float(tvb, stlv_offset + 4) * 8.0);
2031 break;
2033 case MPLS_LINK_UNRES_BW:
2034 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
2035 "%s", stlv_name);
2036 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
2037 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
2038 "TLV Type: %u: %s", stlv_type, stlv_name);
2039 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
2040 stlv_len);
2041 for (i = 0; i < 8; i++) {
2042 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4+(i*4), 4,
2043 "Pri (or TE-Class) %d: %.10g bytes/s (%.0f bits/s)", i,
2044 tvb_get_ntohieee_float(tvb, stlv_offset + 4 + i*4),
2045 tvb_get_ntohieee_float(tvb, stlv_offset + 4 + i*4) * 8.0);
2047 break;
2049 case MPLS_LINK_BANDWIDTH_CONSTRAINT:
2051 The "Bandwidth Constraints" sub-TLV format is illustrated below:
2053 0 1 2 3
2054 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
2055 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2056 | BC Model Id | Reserved |
2057 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2058 | BC0 value |
2059 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2060 // . . . //
2061 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2062 | BCh value |
2063 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2066 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
2067 "%s", stlv_name);
2069 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
2071 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
2072 "TLV Type: %u: %s", stlv_type, stlv_name);
2074 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
2075 stlv_len);
2077 proto_tree_add_item(stlv_tree, hf_ospf_filter[OSPFF_LS_MPLS_BC_MODEL_ID],
2078 tvb, stlv_offset+4, 1, ENC_BIG_ENDIAN);
2080 /* 3 octets reserved +5, +6 and +7 (all 0x00) */
2081 if(tvb_memeql(tvb, stlv_offset+5, allzero, 3) == -1) {
2082 proto_tree_add_text(stlv_tree, tvb, stlv_offset+5, 3,
2083 "Warning: these bytes are reserved and must be 0x00");
2086 if(((stlv_len % 4)!=0)) {
2087 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, stlv_len,
2088 "Malformed Packet: Length must be N x 4 octets");
2089 break;
2092 /* stlv_len shound range from 4 to 36 bytes */
2093 num_bcs = (stlv_len - 4)/4;
2095 if(num_bcs>8) {
2096 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, stlv_len,
2097 "Malformed Packet: too many BC (%u)", num_bcs);
2098 break;
2101 if(num_bcs==0) {
2102 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, stlv_len,
2103 "Malformed Packet: Bandwidth Constraints sub-TLV with no BC?");
2104 break;
2107 for(i = 0; i < (int) num_bcs; i++) {
2108 proto_tree_add_text(stlv_tree, tvb, stlv_offset+8+(i*4), 4,
2109 "BC %d: %.10g bytes/s (%.0f bits/s)", i,
2110 tvb_get_ntohieee_float(tvb, stlv_offset + 8 + i*4),
2111 tvb_get_ntohieee_float(tvb, stlv_offset + 8 + i*4) * 8.0);
2113 break;
2115 case MPLS_LINK_LOCAL_REMOTE_ID:
2116 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
2117 "%s: %d (0x%x) - %d (0x%x)", stlv_name,
2118 tvb_get_ntohl(tvb, stlv_offset + 4),
2119 tvb_get_ntohl(tvb, stlv_offset + 4),
2120 tvb_get_ntohl(tvb, stlv_offset + 8),
2121 tvb_get_ntohl(tvb, stlv_offset + 8));
2122 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
2124 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
2125 "TLV Type: %u: %s", stlv_type, stlv_name);
2126 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
2127 stlv_len);
2128 proto_tree_add_item(stlv_tree,
2129 hf_ospf_filter[OSPFF_LS_MPLS_LOCAL_IFID],
2130 tvb, stlv_offset+4, 4, ENC_BIG_ENDIAN);
2131 proto_tree_add_item(stlv_tree,
2132 hf_ospf_filter[OSPFF_LS_MPLS_REMOTE_IFID],
2133 tvb, stlv_offset+8, 4, ENC_BIG_ENDIAN);
2134 break;
2136 case MPLS_LINK_IF_SWITCHING_DESC:
2137 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
2138 "%s", stlv_name);
2139 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
2140 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
2141 "TLV Type: %u: %s", stlv_type, stlv_name);
2142 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
2143 stlv_len);
2144 switch_cap = tvb_get_guint8 (tvb, stlv_offset+4);
2145 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 1, "Switching Type: %s",
2146 rval_to_str(tvb_get_guint8(tvb,stlv_offset+4),
2147 gmpls_switching_type_rvals, "Unknown (%d)"));
2148 proto_tree_add_text(stlv_tree, tvb, stlv_offset+5, 1, "Encoding: %s",
2149 rval_to_str(tvb_get_guint8(tvb,stlv_offset+5),
2150 gmpls_lsp_enc_rvals, "Unknown (%d)"));
2151 for (i = 0; i < 8; i++) {
2152 proto_tree_add_text(stlv_tree, tvb, stlv_offset+8+(i*4), 4,
2153 "Pri %d: %.10g bytes/s (%.0f bits/s)", i,
2154 tvb_get_ntohieee_float(tvb, stlv_offset + 8 + i*4),
2155 tvb_get_ntohieee_float(tvb, stlv_offset + 8 + i*4) * 8.0);
2157 if (switch_cap >=1 && switch_cap <=4) { /* PSC-1 .. PSC-4 */
2158 proto_tree_add_text(stlv_tree, tvb, stlv_offset+40, 4,
2159 "Minimum LSP bandwidth: %.10g bytes/s (%.0f bits/s)",
2160 tvb_get_ntohieee_float(tvb, stlv_offset + 40),
2161 tvb_get_ntohieee_float(tvb, stlv_offset + 40) * 8.0);
2162 proto_tree_add_text(stlv_tree, tvb, stlv_offset+44, 2,
2163 "Interface MTU: %d", tvb_get_ntohs(tvb, stlv_offset+44));
2166 if (switch_cap == 100) { /* TDM */
2167 proto_tree_add_text(stlv_tree, tvb, stlv_offset+40, 4,
2168 "Minimum LSP bandwidth: %.10g bytes/s (%.0f bits/s)",
2169 tvb_get_ntohieee_float(tvb, stlv_offset + 40),
2170 tvb_get_ntohieee_float(tvb, stlv_offset + 40) * 8.0);
2171 proto_tree_add_text(stlv_tree, tvb, stlv_offset+44, 2,
2172 "SONET/SDH: %s",
2173 tvb_get_guint8(tvb, stlv_offset+44) ?
2174 "Arbitrary" : "Standard");
2176 break;
2177 case MPLS_LINK_PROTECTION:
2178 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
2179 "%s", stlv_name);
2180 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
2181 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
2182 "TLV Type: %u: %s", stlv_type, stlv_name);
2183 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
2184 stlv_len);
2185 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 1, "Protection Capability: %s (0x%x)",
2186 val_to_str(tvb_get_guint8(tvb,stlv_offset+4),
2187 gmpls_protection_cap_str,
2188 "Unknown (%d)"),
2189 tvb_get_guint8(tvb,stlv_offset+4));
2190 break;
2192 case MPLS_LINK_SHARED_RISK_GROUP:
2193 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
2194 "%s", stlv_name);
2195 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
2196 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
2197 "TLV Type: %u: %s", stlv_type, stlv_name);
2198 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
2199 stlv_len);
2200 for (i=0; i < stlv_len; i+=4)
2201 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4+i, 4, "Shared Risk Link Group: %u",
2202 tvb_get_ntohl(tvb,stlv_offset+4+i));
2203 break;
2205 case OIF_LOCAL_NODE_ID:
2206 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
2207 "%s: %s", stlv_name,
2208 tvb_ip_to_str(tvb, stlv_offset + 4));
2209 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
2210 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
2211 "TLV Type: %u: %s", stlv_type, stlv_name);
2212 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
2213 stlv_len);
2214 proto_tree_add_item(stlv_tree,
2215 hf_ospf_filter[OSPFF_LS_OIF_LOCAL_NODE_ID],
2216 tvb, stlv_offset + 4, 4, ENC_BIG_ENDIAN);
2217 break;
2219 case OIF_REMOTE_NODE_ID:
2220 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
2221 "%s: %s", stlv_name,
2222 tvb_ip_to_str(tvb, stlv_offset + 4));
2223 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
2224 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
2225 "TLV Type: %u: %s", stlv_type, stlv_name);
2226 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
2227 stlv_len);
2228 proto_tree_add_item(stlv_tree,
2229 hf_ospf_filter[OSPFF_LS_OIF_REMOTE_NODE_ID],
2230 tvb, stlv_offset + 4, 4, ENC_BIG_ENDIAN);
2231 break;
2233 case OIF_SONET_SDH_SWITCHING_CAPABILITY:
2234 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4, "%s", stlv_name);
2235 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
2236 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
2237 "TLV Type: %u: %s", stlv_type, stlv_name);
2238 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
2239 stlv_len);
2240 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 1, "Switching Cap: %s",
2241 rval_to_str(tvb_get_guint8 (tvb, stlv_offset+4),
2242 gmpls_switching_type_rvals, "Unknown (%d)"));
2243 proto_tree_add_text(stlv_tree, tvb, stlv_offset+5, 1, "Encoding: %s",
2244 rval_to_str(tvb_get_guint8(tvb,stlv_offset+5),
2245 gmpls_lsp_enc_rvals, "Unknown (%d)"));
2246 for (i = 0; i < (stlv_len - 4) / 4; i++) {
2247 proto_tree_add_text(stlv_tree, tvb, stlv_offset+8+(i*4), 4,
2248 "%s: %d free timeslots",
2249 val_to_str_ext(tvb_get_guint8(tvb, stlv_offset+8+(i*4)),
2250 &gmpls_sonet_signal_type_str_ext,
2251 "Unknown Signal Type (%d)"),
2252 tvb_get_ntoh24(tvb, stlv_offset + 9 + i*4));
2255 break;
2256 default:
2257 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
2258 "Unknown Link sub-TLV: %u %s", stlv_type,
2259 rval_to_str(stlv_type, mpls_te_sub_tlv_rvals, "Unknown"));
2260 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
2261 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
2262 "TLV Type: %u: %s %s", stlv_type, stlv_name,
2263 rval_to_str(stlv_type, mpls_te_sub_tlv_rvals, "Unknown"));
2264 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
2265 stlv_len);
2266 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, stlv_len,
2267 "TLV Value");
2268 break;
2270 stlv_offset += ((stlv_len+4+3)/4)*4;
2272 break;
2274 case OIF_TLV_TNA:
2275 ti = proto_tree_add_text(mpls_tree, tvb, offset, tlv_length+4,
2276 "TNA Information");
2277 tlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_oif_tna);
2278 proto_tree_add_text(tlv_tree, tvb, offset, 2, "TLV Type: 32768 - TNA Information");
2279 proto_tree_add_text(tlv_tree, tvb, offset+2, 2, "TLV Length: %u",
2280 tlv_length);
2281 stlv_offset = offset + 4;
2283 /* Walk down the sub-TLVs for TNA information */
2284 while (stlv_offset < tlv_end_offset) {
2285 stlv_type = tvb_get_ntohs(tvb, stlv_offset);
2286 stlv_len = tvb_get_ntohs(tvb, stlv_offset + 2);
2287 stlv_name = val_to_str_const(stlv_type, oif_stlv_str, "Unknown sub-TLV");
2288 switch (stlv_type) {
2290 case OIF_NODE_ID:
2291 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
2292 "%s: %s", stlv_name,
2293 tvb_ip_to_str(tvb, stlv_offset + 4));
2294 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_oif_tna_stlv);
2295 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
2296 "TLV Type: %u: %s", stlv_type, stlv_name);
2297 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
2298 stlv_len);
2299 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 4, "%s: %s", stlv_name,
2300 tvb_ip_to_str(tvb, stlv_offset + 4));
2301 break;
2303 case OIF_TNA_IPv4_ADDRESS:
2304 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
2305 "%s (IPv4): %s", stlv_name,
2306 tvb_ip_to_str(tvb, stlv_offset + 8));
2307 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_oif_tna_stlv);
2308 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
2309 "TLV Type: %u: %s (IPv4)", stlv_type, stlv_name);
2310 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u", stlv_len);
2311 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 1, "Addr Length: %u",
2312 tvb_get_guint8 (tvb, stlv_offset+4));
2313 proto_tree_add_text(stlv_tree, tvb, stlv_offset+8, stlv_len - 4, "TNA Addr: %s",
2314 tvb_ip_to_str(tvb, stlv_offset + 8));
2315 break;
2317 case OIF_TNA_IPv6_ADDRESS:
2318 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
2319 "%s (IPv6): %s", stlv_name,
2320 tvb_ip6_to_str(tvb, stlv_offset + 8));
2321 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_oif_tna_stlv);
2322 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
2323 "TLV Type: %u: %s (IPv6)", stlv_type, stlv_name);
2324 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u", stlv_len);
2325 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 1, "Addr Length: %u",
2326 tvb_get_guint8 (tvb, stlv_offset+4));
2327 proto_tree_add_text(stlv_tree, tvb, stlv_offset+8, stlv_len - 4, "TNA Addr: %s",
2328 tvb_ip6_to_str(tvb, stlv_offset + 8));
2329 break;
2331 case OIF_TNA_NSAP_ADDRESS:
2332 ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
2333 "%s (NSAP): %s", stlv_name,
2334 tvb_bytes_to_str (tvb, stlv_offset + 8, stlv_len - 4));
2335 stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_oif_tna_stlv);
2336 proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
2337 "TLV Type: %u: %s (NSAP)", stlv_type, stlv_name);
2338 proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u", stlv_len);
2339 proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 1, "Addr Length: %u",
2340 tvb_get_guint8 (tvb, stlv_offset+4));
2341 proto_tree_add_text(stlv_tree, tvb, stlv_offset+8, stlv_len - 4, "TNA Addr: %s",
2342 tvb_bytes_to_str(tvb, stlv_offset+8, stlv_len - 4));
2343 break;
2345 default:
2346 proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
2347 "Unknown Link sub-TLV: %u", stlv_type);
2348 break;
2350 stlv_offset += ((stlv_len+4+3)/4)*4;
2352 break;
2353 default:
2354 ti = proto_tree_add_text(mpls_tree, tvb, offset, tlv_length+4,
2355 "Unknown LSA: %u %s", tlv_type,
2356 rval_to_str(tlv_type, mpls_te_tlv_rvals, "Unknown"));
2357 tlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link);
2358 proto_tree_add_text(tlv_tree, tvb, offset, 2, "TLV Type: %u - Unknown %s",
2359 tlv_type, rval_to_str(tlv_type, mpls_te_tlv_rvals, "Unknown"));
2360 proto_tree_add_text(tlv_tree, tvb, offset+2, 2, "TLV Length: %u",
2361 tlv_length);
2362 proto_tree_add_text(tlv_tree, tvb, offset+4, tlv_length, "TLV Data");
2363 break;
2366 offset += tlv_length + 4;
2367 length -= tlv_length + 4;
2372 * Dissect the TLVs within a Grace-LSA as defined by RFC 3623
2374 static void dissect_ospf_lsa_grace_tlv (tvbuff_t *tvb, int offset,
2375 proto_tree *tree, guint32 length)
2377 guint16 tlv_type;
2378 guint16 tlv_length;
2379 int tlv_length_with_pad; /* The total length of the TLV including the type
2380 and length fields and any padding */
2381 guint32 grace_period;
2382 guint8 restart_reason;
2383 guint32 restart_ip;
2384 proto_tree *tlv_tree;
2385 proto_item *tree_item;
2386 proto_item *grace_tree_item;
2388 if (!tree) { return; }
2390 while (length > 0)
2392 tlv_type = tvb_get_ntohs(tvb, offset);
2393 tlv_length = tvb_get_ntohs(tvb, offset + 2);
2394 /* The total length of the TLV including the type, length, value and
2395 * pad bytes (TLVs are padded to 4 octet alignment).
2397 tlv_length_with_pad = tlv_length + 4 + ((4 - (tlv_length % 4)) % 4);
2399 tree_item = proto_tree_add_item(tree, hf_ospf_filter[OSPFF_V2_GRACE_TLV], tvb, offset,
2400 tlv_length_with_pad, ENC_NA);
2401 tlv_tree = proto_item_add_subtree(tree_item, ett_ospf_lsa_grace_tlv);
2402 proto_tree_add_text(tlv_tree, tvb, offset, 2, "Type: %s (%u)",
2403 val_to_str_const(tlv_type, grace_tlv_type_vals, "Unknown grace-LSA TLV"), tlv_type);
2404 proto_tree_add_text(tlv_tree, tvb, offset + 2, 2, "Length: %u", tlv_length);
2406 switch (tlv_type) {
2407 case GRACE_TLV_PERIOD:
2408 grace_period = tvb_get_ntohl(tvb, offset + 4);
2409 grace_tree_item = proto_tree_add_item(tlv_tree, hf_ospf_filter[OSPFF_V2_GRACE_PERIOD], tvb,
2410 offset + 4, tlv_length, ENC_BIG_ENDIAN);
2411 proto_item_append_text(grace_tree_item, " seconds");
2412 proto_item_set_text(tree_item, "Grace Period: %u seconds", grace_period);
2413 break;
2414 case GRACE_TLV_REASON:
2415 restart_reason = tvb_get_guint8(tvb, offset + 4);
2416 proto_tree_add_item(tlv_tree, hf_ospf_filter[OSPFF_V2_GRACE_REASON], tvb, offset + 4,
2417 tlv_length, ENC_BIG_ENDIAN);
2418 proto_item_set_text(tree_item, "Restart Reason: %s (%u)",
2419 val_to_str_const(restart_reason, restart_reason_vals, "Unknown Restart Reason"),
2420 restart_reason);
2421 break;
2422 case GRACE_TLV_IP:
2423 restart_ip = tvb_get_ipv4(tvb, offset + 4);
2424 proto_tree_add_item(tlv_tree, hf_ospf_filter[OSPFF_V2_GRACE_IP], tvb, offset + 4,
2425 tlv_length, ENC_BIG_ENDIAN);
2426 proto_item_set_text(tree_item, "Restart IP: %s (%s)",
2427 get_hostname(restart_ip), ip_to_str((guint8 *)&restart_ip));
2428 break;
2429 default:
2430 proto_item_set_text(tree_item, "Unknown grace-LSA TLV");
2431 break;
2433 if (4 + tlv_length < tlv_length_with_pad) {
2434 proto_tree_add_text(tlv_tree, tvb, offset + 4 + tlv_length,
2435 tlv_length_with_pad - (4 + tlv_length), "Pad Bytes (%u)",
2436 tlv_length_with_pad - (4 + tlv_length) );
2438 offset += tlv_length_with_pad;
2439 length -= tlv_length_with_pad;
2444 * This function dissects the Optional Router capabilities LSA.
2445 * In case of OSPFv2, the Router Capabilities would be advertized via the first TLV
2446 * of an RI LSA and in the case of OSPFv3, the router capabilities would be advertized
2447 * using a special purpose type field value. (RFC 4970)
2448 * Also, the Dynamic Hostname or FQDN is advertized via a special purpose TLV type.
2449 * The below function adds the support to handle this as well. (RFC5642).
2451 static void
2452 dissect_ospf_lsa_opaque_ri(tvbuff_t *tvb, int offset, proto_tree *tree,
2453 guint32 length)
2455 proto_item *ti;
2456 proto_tree *ri_tree;
2457 proto_tree *tlv_tree;
2459 int tlv_type;
2460 int tlv_length;
2462 ti = proto_tree_add_text(tree, tvb, offset, length,
2463 "Opaque Router Information LSA");
2465 ri_tree = proto_item_add_subtree(ti, ett_ospf_lsa_opaque_ri);
2467 while (length > 0) {
2468 tlv_type = tvb_get_ntohs(tvb, offset);
2469 tlv_length = tvb_get_ntohs(tvb, offset + 2);
2471 switch(tlv_type) {
2473 case OPT_RI_TLV:
2474 ti = proto_tree_add_text(ri_tree, tvb, offset, tlv_length+4,
2475 "RI TLV");
2476 tlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_ri_tlv);
2478 proto_tree_add_text(tlv_tree, tvb, offset, 2, "TLV Type: %s (%u)",
2479 "Router Informational Capabilities TLV", tlv_type);
2481 proto_tree_add_text(tlv_tree, tvb, offset + 2, 2, "TLV Length: %u", tlv_length);
2483 dissect_ospf_bitfield(tlv_tree, tvb, offset + 4, &bfinfo_ri_options);
2484 break;
2486 case DYN_HOSTNAME_TLV:
2487 ti = proto_tree_add_text(ri_tree, tvb, offset, tlv_length+4,
2488 "Dynamic Hostname TLV");
2489 tlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_dyn_hostname_tlv);
2491 proto_tree_add_text(tlv_tree, tvb, offset, 2, "TLV Type: %s (%u)",
2492 "Dynamic Hostname TLV", tlv_type);
2494 proto_tree_add_text(tlv_tree, tvb, offset + 2, 2, "TLV Length: %u", tlv_length);
2496 proto_tree_add_item(tlv_tree, hf_ospf_filter[OSPFF_DYN_HOSTNAME], tvb, offset+4, tlv_length, ENC_ASCII|ENC_NA);
2497 break;
2499 default:
2500 ti = proto_tree_add_text(ri_tree, tvb, offset, tlv_length+4,
2501 "Unknown Opaque RI LSA TLV");
2502 tlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_unknown_tlv);
2504 proto_tree_add_text(tlv_tree, tvb, offset, 2, "TLV Type: %s (%u)",
2505 "Unknown TLV", tlv_type);
2507 proto_tree_add_text(tlv_tree, tvb, offset + 2, 2, "TLV Length: %u", tlv_length);
2509 proto_tree_add_item(tlv_tree, hf_ospf_filter[OSPFF_UNKNOWN_TLV_TXT], tvb, offset+4, tlv_length, ENC_ASCII|ENC_NA);
2510 break;
2514 offset += tlv_length + 4;
2515 length -= tlv_length + 4;
2520 * Dissect opaque LSAs
2522 static void
2523 dissect_ospf_lsa_opaque(tvbuff_t *tvb, int offset, proto_tree *tree,
2524 guint8 ls_id_type, guint32 length)
2526 switch (ls_id_type) {
2528 case OSPF_LSA_MPLS_TE:
2529 dissect_ospf_lsa_mpls(tvb, offset, tree, length);
2530 break;
2531 case OSPF_LSA_OPAQUE_RI:
2532 dissect_ospf_lsa_opaque_ri(tvb, offset, tree, length);
2533 break;
2534 case OSPF_LSA_GRACE:
2535 dissect_ospf_lsa_grace_tlv(tvb, offset, tree, length);
2536 break;
2538 default:
2539 proto_tree_add_text(tree, tvb, offset, length,
2540 "Unknown LSA Type %u", ls_id_type);
2541 break;
2542 } /* switch on opaque LSA id */
2545 static int
2546 dissect_ospf_v2_lsa(tvbuff_t *tvb, int offset, proto_tree *tree,
2547 gboolean disassemble_body)
2549 proto_tree *ospf_lsa_tree;
2550 proto_item *ti, *hidden_item;
2552 guint8 ls_type;
2553 guint16 ls_length;
2554 int end_offset;
2555 guint16 nr_links;
2556 guint16 nr_metric;
2558 /* router LSA */
2559 guint8 link_type;
2560 guint16 link_counter;
2561 guint16 metric_counter;
2562 const char *link_type_str;
2563 const char *link_type_short_str;
2564 const char *link_id;
2565 const char *metric_type_str;
2567 /* AS-external LSA */
2568 guint8 options;
2570 /* opaque LSA */
2571 guint8 ls_id_type;
2572 guint8 ls_ri_opaque_field;
2574 ls_type = tvb_get_guint8(tvb, offset + 3);
2575 ls_length = tvb_get_ntohs(tvb, offset + 18);
2576 end_offset = offset + ls_length;
2578 if (disassemble_body) {
2579 ti = proto_tree_add_text(tree, tvb, offset, ls_length,
2580 "LS Type: %s",
2581 val_to_str(ls_type, ls_type_vals, "Unknown (%d)"));
2582 } else {
2583 ti = proto_tree_add_text(tree, tvb, offset, OSPF_LSA_HEADER_LENGTH,
2584 "LSA Header");
2586 ospf_lsa_tree = proto_item_add_subtree(ti, ett_ospf_lsa);
2588 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 2, "LS Age: %u seconds",
2589 tvb_get_ntohs(tvb, offset) & ~OSPF_DNA_LSA);
2590 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 2, "Do Not Age: %s",
2591 (tvb_get_ntohs(tvb, offset) & OSPF_DNA_LSA) ? "True" : "False");
2592 options = tvb_get_guint8 (tvb, offset + 2);
2593 dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset + 2, &bfinfo_v2_options);
2594 proto_tree_add_item(ospf_lsa_tree, hf_ospf_filter[OSPFF_LS_TYPE], tvb,
2595 offset + 3, 1, ENC_BIG_ENDIAN);
2596 if (ospf_ls_type_to_filter(ls_type) != -1) {
2597 hidden_item = proto_tree_add_item(ospf_lsa_tree,
2598 hf_ospf_filter[ospf_ls_type_to_filter(ls_type)], tvb,
2599 offset + 3, 1, ENC_BIG_ENDIAN);
2600 PROTO_ITEM_SET_HIDDEN(hidden_item);
2603 if (options & OSPF_V2_OPTIONS_MT) {
2604 metric_type_str = "MT-ID";
2605 } else {
2606 metric_type_str = "TOS";
2609 if (is_opaque(ls_type)) {
2610 ls_id_type = tvb_get_guint8(tvb, offset + 4);
2611 proto_tree_add_uint(ospf_lsa_tree, hf_ospf_filter[OSPFF_LS_OPAQUE_TYPE],
2612 tvb, offset + 4, 1, ls_id_type);
2614 switch (ls_id_type) {
2616 case OSPF_LSA_MPLS_TE:
2617 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 5, 1, "Link State ID TE-LSA Reserved: %u",
2618 tvb_get_guint8(tvb, offset + 5));
2619 proto_tree_add_item(ospf_lsa_tree, hf_ospf_filter[OSPFF_LS_MPLS_TE_INSTANCE],
2620 tvb, offset + 6, 2, ENC_BIG_ENDIAN);
2621 break;
2623 case OSPF_LSA_OPAQUE_RI:
2624 ls_ri_opaque_field = tvb_get_guint8(tvb, offset + 5);
2625 if ( ls_ri_opaque_field != 0 )
2626 ls_id_type = OSPF_LSA_UNKNOWN;
2627 else
2628 proto_tree_add_item(ospf_lsa_tree, hf_ospf_filter[OSPFF_OPAQUE_LSA_MBZ],
2629 tvb, offset + 5, 3, ENC_BIG_ENDIAN);
2630 break;
2632 default:
2633 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 5, 3, "Link State ID Opaque ID: %u",
2634 tvb_get_ntoh24(tvb, offset + 5));
2635 break;
2637 } else {
2638 ls_id_type = 0;
2639 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 4, 4, "Link State ID: %s",
2640 tvb_ip_to_str(tvb, offset + 4));
2643 proto_tree_add_item(ospf_lsa_tree, hf_ospf_filter[OSPFF_ADV_ROUTER],
2644 tvb, offset + 8, 4, ENC_BIG_ENDIAN);
2645 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 12, 4, "LS Sequence Number: 0x%08x",
2646 tvb_get_ntohl(tvb, offset + 12));
2647 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 16, 2, "LS Checksum: 0x%04x",
2648 tvb_get_ntohs(tvb, offset + 16));
2650 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 18, 2, "Length: %u",
2651 ls_length);
2653 /* skip past the LSA header to the body */
2654 offset += OSPF_LSA_HEADER_LENGTH;
2655 if (ls_length <= OSPF_LSA_HEADER_LENGTH)
2656 return offset; /* no data, or bogus length */
2657 ls_length -= OSPF_LSA_HEADER_LENGTH;
2659 if (!disassemble_body)
2660 return offset;
2662 switch (ls_type){
2664 case OSPF_LSTYPE_ROUTER:
2665 /* flags field in an router-lsa */
2666 if (options & OSPF_V2_OPTIONS_MT) {
2667 dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset, &bfinfo_v2_router_lsa_mt_flags);
2668 } else {
2669 dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset, &bfinfo_v2_router_lsa_flags);
2672 nr_links = tvb_get_ntohs(tvb, offset + 2);
2673 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 2, 2, "Number of Links: %u",
2674 nr_links);
2675 offset += 4;
2676 /* nr_links links follow
2677 * maybe we should put each of the links into its own subtree ???
2679 for (link_counter = 0; link_counter < nr_links; link_counter++) {
2680 proto_tree *ospf_lsa_router_link_tree;
2681 proto_item *ti_local;
2684 /* check the Link Type and ID */
2685 link_type = tvb_get_guint8(tvb, offset + 8);
2686 switch (link_type) {
2688 case OSPF_LINK_PTP:
2689 link_type_str="Point-to-point connection to another router";
2690 link_type_short_str="PTP";
2691 link_id="Neighboring router's Router ID";
2692 break;
2694 case OSPF_LINK_TRANSIT:
2695 link_type_str="Connection to a transit network";
2696 link_type_short_str="Transit";
2697 link_id="IP address of Designated Router";
2698 break;
2700 case OSPF_LINK_STUB:
2701 link_type_str="Connection to a stub network";
2702 link_type_short_str="Stub";
2703 link_id="IP network/subnet number";
2704 break;
2706 case OSPF_LINK_VIRTUAL:
2707 link_type_str="Virtual link";
2708 link_type_short_str="Virtual";
2709 link_id="Neighboring router's Router ID";
2710 break;
2712 default:
2713 link_type_str="Unknown link type";
2714 link_type_short_str="Unknown";
2715 link_id="Unknown link ID";
2716 break;
2719 nr_metric = tvb_get_guint8(tvb, offset + 9);
2722 ti_local = proto_tree_add_text(ospf_lsa_tree, tvb, offset, 12 + 4 * nr_metric,
2723 "Type: %-8s ID: %-15s Data: %-15s Metric: %d",
2724 link_type_short_str,
2725 tvb_ip_to_str(tvb, offset),
2726 tvb_ip_to_str(tvb, offset + 4),
2727 tvb_get_ntohs(tvb, offset + 10));
2729 ospf_lsa_router_link_tree = proto_item_add_subtree(ti_local, ett_ospf_lsa_router_link);
2731 proto_tree_add_text(ospf_lsa_router_link_tree, tvb, offset, 4, "%s: %s", link_id,
2732 tvb_ip_to_str(tvb, offset));
2734 /* link_data should be specified in detail (e.g. network mask) (depends on link type)*/
2735 proto_tree_add_text(ospf_lsa_router_link_tree, tvb, offset + 4, 4, "Link Data: %s",
2736 tvb_ip_to_str(tvb, offset + 4));
2738 proto_tree_add_text(ospf_lsa_router_link_tree, tvb, offset + 8, 1, "Link Type: %u - %s",
2739 link_type, link_type_str);
2740 proto_tree_add_text(ospf_lsa_router_link_tree, tvb, offset + 9, 1, "Number of %s metrics: %u",
2741 metric_type_str, nr_metric);
2742 proto_tree_add_text(ospf_lsa_router_link_tree, tvb, offset + 10, 2, "%s 0 metric: %u",
2743 metric_type_str, tvb_get_ntohs(tvb, offset + 10));
2745 offset += 12;
2747 /* nr_metric metrics may follow each link
2748 * According to RFC4915 the TOS metrics was never deployed and was subsequently deprecated,
2749 * but decoding still present because MT-ID use the same structure.
2751 for (metric_counter = 0; metric_counter < nr_metric; metric_counter++) {
2752 proto_tree_add_text(ospf_lsa_router_link_tree, tvb, offset, 4, "%s: %u, Metric: %u",
2753 metric_type_str,
2754 tvb_get_guint8(tvb, offset),
2755 tvb_get_ntohs(tvb, offset + 2));
2756 offset += 4;
2759 break;
2761 case OSPF_LSTYPE_NETWORK:
2762 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "Netmask: %s",
2763 tvb_ip_to_str(tvb, offset));
2764 offset += 4;
2766 while (offset < end_offset) {
2767 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "Attached Router: %s",
2768 tvb_ip_to_str(tvb, offset));
2769 offset += 4;
2771 break;
2773 case OSPF_LSTYPE_SUMMERY:
2774 /* Type 3 and 4 LSAs have the same format */
2775 case OSPF_LSTYPE_ASBR:
2776 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "Netmask: %s",
2777 tvb_ip_to_str(tvb, offset));
2778 offset += 4;
2780 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "Metric: %u",
2781 tvb_get_ntoh24(tvb, offset + 1));
2782 offset += 4;
2784 /* Metric specific information, if any */
2785 while (offset < end_offset) {
2786 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "%s: %u, Metric: %u",
2787 metric_type_str,
2788 tvb_get_guint8(tvb, offset),
2789 tvb_get_ntoh24(tvb, offset + 1));
2790 offset += 4;
2792 break;
2794 case OSPF_LSTYPE_ASEXT:
2795 case OSPF_LSTYPE_ASEXT7:
2796 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "Netmask: %s",
2797 tvb_ip_to_str(tvb, offset));
2798 offset += 4;
2800 options = tvb_get_guint8(tvb, offset);
2801 if (options & 0x80) { /* check whether or not E bit is set */
2802 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1,
2803 "External Type: Type 2 (metric is larger than any other link state path)");
2804 } else {
2805 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1,
2806 "External Type: Type 1 (metric is specified in the same units as interface cost)");
2808 /* the metric field of a AS-external LAS is specified in 3 bytes */
2809 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 1, 3, "Metric: %u",
2810 tvb_get_ntoh24(tvb, offset + 1));
2811 offset += 4;
2813 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "Forwarding Address: %s",
2814 tvb_ip_to_str(tvb, offset));
2815 offset += 4;
2817 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "External Route Tag: %u",
2818 tvb_get_ntohl(tvb, offset));
2819 offset += 4;
2821 /* Metric specific information, if any */
2822 while (offset < end_offset) {
2823 options = tvb_get_guint8(tvb, offset);
2824 if (options & 0x80) { /* check whether or not E bit is set */
2825 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1,
2826 "External Type: Type 2 (metric is larger than any other link state path)");
2827 } else {
2828 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1,
2829 "External Type: Type 1 (metric is specified in the same units as interface cost)");
2831 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "%s: %u, Metric: %u",
2832 metric_type_str, options & 0x7F,
2833 tvb_get_ntoh24(tvb, offset + 1));
2834 offset += 4;
2836 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "Forwarding Address: %s",
2837 tvb_ip_to_str(tvb, offset));
2838 offset += 4;
2840 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "External Route Tag: %u",
2841 tvb_get_ntohl(tvb, offset));
2842 offset += 4;
2844 break;
2846 case OSPF_LSTYPE_OP_LINKLOCAL:
2847 case OSPF_LSTYPE_OP_AREALOCAL:
2848 case OSPF_LSTYPE_OP_ASWIDE:
2850 * RFC 2370 opaque LSAs.
2852 dissect_ospf_lsa_opaque(tvb, offset, ospf_lsa_tree, ls_id_type,
2853 ls_length);
2854 offset += ls_length;
2855 break;
2857 default:
2858 /* unknown LSA type */
2859 proto_tree_add_text(ospf_lsa_tree, tvb, offset, ls_length,
2860 "Unknown LSA Type");
2861 offset += ls_length;
2862 break;
2864 /* return the offset of the next LSA */
2865 return offset;
2868 static int
2869 dissect_ospf_v3_lsa(tvbuff_t *tvb, int offset, proto_tree *tree,
2870 gboolean disassemble_body, guint8 address_family)
2872 proto_tree *ospf_lsa_tree;
2873 proto_item *ti, *hidden_item;
2875 guint16 ls_type;
2876 guint16 ls_length;
2877 int end_offset;
2878 guint8 reserved;
2880 /* router LSA */
2881 guint8 link_type;
2882 const char *link_type_str;
2883 guint32 metric;
2885 guint8 router_priority;
2886 guint32 number_prefixes;
2887 guint8 prefix_length;
2888 guint16 reserved16;
2890 guint16 referenced_ls_type;
2892 guint8 flags;
2893 guint32 external_route_tag;
2896 ls_type = tvb_get_ntohs(tvb, offset + 2);
2897 ls_length = tvb_get_ntohs(tvb, offset + 18);
2898 end_offset = offset + ls_length;
2900 if (disassemble_body) {
2901 ti = proto_tree_add_text(tree, tvb, offset, ls_length,
2902 "%s (Type: 0x%04x)", val_to_str_const(ls_type, v3_ls_type_vals,"Unknown"), ls_type);
2903 } else {
2904 ti = proto_tree_add_text(tree, tvb, offset, OSPF_LSA_HEADER_LENGTH,
2905 "LSA Header");
2907 ospf_lsa_tree = proto_item_add_subtree(ti, ett_ospf_lsa);
2909 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 2, "LS Age: %u seconds",
2910 tvb_get_ntohs(tvb, offset) & ~OSPF_DNA_LSA);
2911 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 2, "Do Not Age: %s",
2912 (tvb_get_ntohs(tvb, offset) & OSPF_DNA_LSA) ? "True" : "False");
2914 proto_tree_add_item(ospf_lsa_tree, hf_ospf_filter[OSPFF_V3_LS_TYPE], tvb,
2915 offset + 2, 2, ENC_BIG_ENDIAN);
2916 if (ospf_v3_ls_type_to_filter(ls_type) != -1) {
2917 hidden_item = proto_tree_add_item(ospf_lsa_tree,
2918 hf_ospf_filter[ospf_v3_ls_type_to_filter(ls_type)], tvb,
2919 offset + 2, 2, ENC_BIG_ENDIAN);
2920 PROTO_ITEM_SET_HIDDEN(hidden_item);
2923 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 4, 4, "Link State ID: %s",
2924 tvb_ip_to_str(tvb, offset + 4));
2926 proto_tree_add_item(ospf_lsa_tree, hf_ospf_filter[OSPFF_ADV_ROUTER],
2927 tvb, offset + 8, 4, ENC_BIG_ENDIAN);
2928 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 12, 4, "LS Sequence Number: 0x%08x",
2929 tvb_get_ntohl(tvb, offset + 12));
2930 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 16, 2, "LS Checksum: 0x%04x",
2931 tvb_get_ntohs(tvb, offset + 16));
2933 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 18, 2, "Length: %u",
2934 ls_length);
2936 /* skip past the LSA header to the body */
2937 offset += OSPF_LSA_HEADER_LENGTH;
2938 ls_length -= OSPF_LSA_HEADER_LENGTH;
2940 if (!disassemble_body)
2941 return offset;
2943 switch (ls_type){
2946 case OSPF_V3_LSTYPE_ROUTER:
2947 /* flags field in an router-lsa */
2948 dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset, &bfinfo_v3_router_lsa_flags);
2950 /* options field in an router-lsa */
2951 dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset + 1, &bfinfo_v3_options);
2953 /* skip the router-lsa flags and options */
2954 offset+=4;
2955 ls_length-=4;
2957 if (ls_length > 0)
2958 proto_tree_add_text(ospf_lsa_tree, tvb, offset, ls_length,
2959 "Router Interfaces:");
2961 /* scan all router-lsa router interfaces */
2962 /* maybe we should put each of the links into its own subtree ??? */
2963 while (ls_length > 0 ) {
2965 /* check the type */
2966 link_type = tvb_get_guint8(tvb, offset);
2967 switch (link_type) {
2969 case OSPF_V3_LINK_PTP:
2970 link_type_str="Point-to-point connection to another router";
2971 break;
2973 case OSPF_V3_LINK_TRANSIT:
2974 link_type_str="Connection to a transit network";
2975 break;
2977 case OSPF_V3_LINK_RESERVED:
2978 link_type_str="Connection to a stub network";
2979 break;
2981 case OSPF_V3_LINK_VIRTUAL:
2982 link_type_str="Virtual link";
2983 break;
2985 default:
2986 link_type_str="Unknown link type";
2987 break;
2990 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1, "Type: %u (%s)", link_type,link_type_str);
2992 /* reserved field */
2993 reserved = tvb_get_guint8(tvb, offset+1);
2994 proto_tree_add_text(ospf_lsa_tree, tvb, offset+1, 1,
2995 (reserved == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),reserved);
2997 /* metric */
2998 metric=tvb_get_ntohs(tvb, offset+2);
2999 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 2, 2,"Metric: %u",metric);
3001 /* Interface ID */
3002 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 4, 4, "Interface ID: %u",
3003 tvb_get_ntohl(tvb, offset + 4));
3005 /* Neighbor Interface ID */
3006 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 8, 4, "Neighbor Interface ID: %u",
3007 tvb_get_ntohl(tvb, offset + 8));
3009 /* Neighbor Router ID */
3010 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 12, 4, "Neighbor Router ID: %s",
3011 tvb_ip_to_str(tvb, offset + 12));
3013 /* skip to the (possible) next entry */
3014 offset+=16;
3015 ls_length-=16;
3018 break;
3020 case OSPF_V3_LSTYPE_NETWORK:
3022 /* reserved field */
3023 reserved = tvb_get_guint8(tvb, offset);
3024 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1,
3025 (reserved == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),reserved);
3027 /* options field in an network-lsa */
3028 dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset + 1, &bfinfo_v3_options);
3030 offset += 4;
3031 ls_length-=4;
3033 while (ls_length > 0 ) {
3034 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "Attached Router: %s",
3035 tvb_ip_to_str(tvb, offset));
3036 ls_length-=4;
3037 offset += 4;
3039 break;
3042 case OSPF_V3_LSTYPE_INTER_AREA_PREFIX:
3044 /* reserved field */
3045 reserved = tvb_get_guint8(tvb, offset);
3046 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1,
3047 (reserved == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),reserved);
3049 /* metric */
3050 metric=tvb_get_ntoh24(tvb, offset+1);
3051 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 1, 3,"Metric: %u",metric);
3053 /* prefix length */
3054 prefix_length=tvb_get_guint8(tvb, offset+4);
3055 proto_tree_add_text(ospf_lsa_tree, tvb, offset+4, 1, "PrefixLength: %u",prefix_length);
3057 /* prefix options */
3058 dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset+5, &bfinfo_v3_prefix_options);
3060 /* 16 bits reserved */
3061 reserved16=tvb_get_ntohs(tvb, offset+6);
3062 proto_tree_add_text(ospf_lsa_tree, tvb, offset+6, 2,
3063 (reserved16 == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),reserved16);
3065 offset+=8;
3067 /* address_prefix */
3068 dissect_ospf_v3_address_prefix(tvb, offset, prefix_length, ospf_lsa_tree, address_family);
3070 offset+=(prefix_length+31)/32*4;
3072 break;
3075 case OSPF_V3_LSTYPE_INTER_AREA_ROUTER:
3077 /* reserved field */
3078 reserved = tvb_get_guint8(tvb, offset);
3079 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1,
3080 (reserved == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),reserved);
3082 /* options field in an inter-area-router-lsa */
3083 dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset + 1, &bfinfo_v3_options);
3085 /* reserved field */
3086 reserved = tvb_get_guint8(tvb, offset+4);
3087 proto_tree_add_text(ospf_lsa_tree, tvb, offset+4, 1,
3088 (reserved == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),reserved);
3090 /* metric */
3091 metric=tvb_get_ntoh24(tvb, offset+5);
3092 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 5, 3,"Metric: %u",metric);
3094 /* Destination Router ID */
3095 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 8, 4, "Destination Router ID: %s",
3096 tvb_ip_to_str(tvb, offset + 8));
3098 offset+=12;
3099 break;
3102 case OSPF_V3_LSTYPE_NSSA:
3103 case OSPF_V3_LSTYPE_AS_EXTERNAL:
3105 /* flags */
3106 dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset, &bfinfo_v3_as_external_flags);
3107 flags=tvb_get_guint8(tvb, offset);
3109 /* 24 bits metric */
3110 metric=tvb_get_ntoh24(tvb, offset+1);
3111 proto_tree_add_text(ospf_lsa_tree, tvb, offset+1, 3,
3112 "Metric: %u", metric);
3114 /* prefix length */
3115 prefix_length=tvb_get_guint8(tvb, offset+4);
3116 proto_tree_add_text(ospf_lsa_tree, tvb, offset+4, 1, "PrefixLength: %u",prefix_length);
3118 /* prefix options */
3119 dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset+5, &bfinfo_v3_prefix_options);
3121 /* referenced LS type */
3122 referenced_ls_type=tvb_get_ntohs(tvb, offset+6);
3123 proto_tree_add_text(ospf_lsa_tree, tvb, offset+6, 2,"Referenced LS type 0x%04x (%s)",
3124 referenced_ls_type, val_to_str_const(referenced_ls_type, v3_ls_type_vals, "Unknown"));
3126 offset+=8;
3128 /* address_prefix */
3129 dissect_ospf_v3_address_prefix(tvb, offset, prefix_length, ospf_lsa_tree, address_family);
3131 offset+=(prefix_length+31)/32*4;
3133 /* Forwarding Address (optional - only if F-flag is on) */
3134 if ( (offset < end_offset) && (flags & OSPF_V3_AS_EXTERNAL_FLAG_F) ) {
3135 if (address_family == OSPF_AF_6) {
3136 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 16,"Forwarding Address: %s",
3137 tvb_ip6_to_str(tvb, offset));
3138 } else {
3139 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 16,"Forwarding Address: %s",
3140 tvb_ip_to_str(tvb, offset));
3143 offset+=16;
3146 /* External Route Tag (optional - only if T-flag is on) */
3147 if ( (offset < end_offset) && (flags & OSPF_V3_AS_EXTERNAL_FLAG_T) ) {
3148 external_route_tag=tvb_get_ntohl(tvb, offset);
3149 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4,"External Route Tag: %u",
3150 external_route_tag);
3152 offset+=4;
3155 /* Referenced Link State ID (optional - only if Referenced LS type is non-zero */
3156 if ( (offset < end_offset) && (referenced_ls_type != 0) ) {
3157 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "Referenced Link State ID: %s",
3158 tvb_ip_to_str(tvb, offset));
3159 offset+=4;
3162 break;
3164 case OSPF_V3_LSTYPE_LINK:
3166 /* router priority */
3167 router_priority=tvb_get_guint8(tvb, offset);
3168 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1, "Router Priority: %u", router_priority);
3170 /* options field in an link-lsa */
3171 dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset + 1, &bfinfo_v3_options);
3173 /* Link-local Interface Address */
3174 if (address_family == OSPF_AF_6) {
3175 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 4, 16, "Link-local Interface Address: %s",
3176 tvb_ip6_to_str(tvb, offset + 4));
3177 } else {
3178 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 4, 16, "Link-local Interface Address: %s",
3179 tvb_ip_to_str(tvb, offset + 4));
3181 /* Number prefixes */
3182 number_prefixes=tvb_get_ntohl(tvb, offset + 20);
3183 proto_tree_add_text(ospf_lsa_tree, tvb, offset+20, 4, "# prefixes: %d",number_prefixes);
3185 offset+=24;
3187 while (number_prefixes > 0) {
3189 /* prefix length */
3190 prefix_length=tvb_get_guint8(tvb, offset);
3191 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1, "PrefixLength: %u",prefix_length);
3193 /* prefix options */
3194 dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset+1, &bfinfo_v3_prefix_options);
3196 /* 16 bits reserved */
3197 reserved16=tvb_get_ntohs(tvb, offset+2);
3198 proto_tree_add_text(ospf_lsa_tree, tvb, offset+2, 2,
3199 (reserved16 == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),reserved16);
3201 offset+=4;
3203 /* address_prefix */
3204 dissect_ospf_v3_address_prefix(tvb, offset, prefix_length, ospf_lsa_tree, address_family);
3206 offset+=(prefix_length+31)/32*4;
3208 number_prefixes--;
3211 break;
3213 case OSPF_V3_LSTYPE_INTRA_AREA_PREFIX:
3215 /* # prefixes */
3216 number_prefixes=tvb_get_ntohs(tvb, offset);
3217 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 2,"# prefixes: %u",number_prefixes);
3219 /* referenced LS type */
3220 referenced_ls_type=tvb_get_ntohs(tvb, offset+2);
3221 proto_tree_add_text(ospf_lsa_tree, tvb, offset+2, 2,"Referenced LS type 0x%04x (%s)",
3222 referenced_ls_type, val_to_str_const(referenced_ls_type, v3_ls_type_vals, "Unknown"));
3224 /* Referenced Link State ID */
3225 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 4, 4, "Referenced Link State ID: %s",
3226 tvb_ip_to_str(tvb, offset + 4));
3228 /* Referenced Advertising Router */
3229 proto_tree_add_text(ospf_lsa_tree, tvb, offset + 8, 4, "Referenced Advertising Router: %s",
3230 tvb_ip_to_str(tvb, offset + 8));
3232 offset+=12;
3234 while (number_prefixes > 0) {
3236 /* prefix length */
3237 prefix_length=tvb_get_guint8(tvb, offset);
3238 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1, "PrefixLength: %u",prefix_length);
3240 /* prefix options */
3241 dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset+1, &bfinfo_v3_prefix_options);
3243 /* 16 bits metric */
3244 metric=tvb_get_ntohs(tvb, offset+2);
3245 proto_tree_add_text(ospf_lsa_tree, tvb, offset+2, 2,
3246 "Metric: %u", metric);
3248 offset+=4;
3250 /* address_prefix */
3251 dissect_ospf_v3_address_prefix(tvb, offset, prefix_length, ospf_lsa_tree, address_family);
3253 offset+=(prefix_length+31)/32*4;
3255 number_prefixes--;
3257 break;
3259 case OSPF_V3_LSTYPE_OPAQUE_RI:
3260 dissect_ospf_lsa_opaque_ri(tvb, offset, ospf_lsa_tree, ls_length);
3261 break;
3263 default:
3264 /* unknown LSA type */
3265 proto_tree_add_text(ospf_lsa_tree, tvb, offset, ls_length,
3266 "Unknown LSA Type 0x%04x",ls_type);
3267 offset += ls_length;
3268 break;
3270 /* return the offset of the next LSA */
3271 return offset;
3274 static void dissect_ospf_v3_address_prefix(tvbuff_t *tvb, int offset, int prefix_length, proto_tree *tree,
3275 guint8 address_family)
3278 int bytes_to_process;
3279 struct e_in6_addr prefix;
3281 bytes_to_process=((prefix_length+31)/32)*4;
3283 if (prefix_length > 128) {
3284 proto_tree_add_text(tree, tvb, offset, bytes_to_process,
3285 "Address Prefix: length is invalid (%d, should be <= 128)",
3286 prefix_length);
3287 return;
3290 memset(prefix.bytes, 0, sizeof prefix.bytes);
3291 if (bytes_to_process != 0) {
3292 tvb_memcpy(tvb, prefix.bytes, offset, bytes_to_process);
3293 if (prefix_length % 8) {
3294 prefix.bytes[bytes_to_process - 1] &=
3295 ((0xff00 >> (prefix_length % 8)) & 0xff);
3298 if (address_family == OSPF_AF_6) {
3299 proto_tree_add_text(tree, tvb, offset, bytes_to_process,
3300 "Address Prefix: %s", ip6_to_str(&prefix));
3301 } else {
3302 proto_tree_add_text(tree, tvb, offset, bytes_to_process,
3303 "Address Prefix: %s", tvb_ip_to_str(tvb, offset));
3309 void
3310 proto_register_ospf(void)
3312 static hf_register_info ospff_info[] = {
3314 /* Message type number */
3315 {&hf_ospf_filter[OSPFF_MSG_TYPE],
3316 { "Message Type", "ospf.msg", FT_UINT8, BASE_DEC, VALS(pt_vals), 0x0,
3317 NULL, HFILL }},
3319 /* Message types */
3320 {&hf_ospf_filter[OSPFF_MSG_HELLO],
3321 { "Hello", "ospf.msg.hello", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3322 NULL, HFILL }},
3323 {&hf_ospf_filter[OSPFF_MSG_DB_DESC],
3324 { "Database Description", "ospf.msg.dbdesc", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3325 NULL, HFILL }},
3326 {&hf_ospf_filter[OSPFF_MSG_LS_REQ],
3327 { "Link State Adv Request", "ospf.msg.lsreq", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3328 NULL, HFILL }},
3329 {&hf_ospf_filter[OSPFF_MSG_LS_UPD],
3330 { "Link State Adv Update", "ospf.msg.lsupdate", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3331 NULL, HFILL }},
3332 {&hf_ospf_filter[OSPFF_MSG_LS_ACK],
3333 { "Link State Adv Acknowledgement", "ospf.msg.lsack", FT_BOOLEAN,
3334 BASE_NONE, NULL, 0x0, NULL, HFILL }},
3338 /* LS Types */
3339 {&hf_ospf_filter[OSPFF_LS_TYPE],
3340 { "LS Type", "ospf.lsa", FT_UINT8, BASE_DEC,
3341 VALS(ls_type_vals), 0x0, NULL, HFILL }},
3342 {&hf_ospf_filter[OSPFF_LS_OPAQUE_TYPE],
3343 { "Link State ID Opaque Type", "ospf.lsid_opaque_type", FT_UINT8, BASE_DEC,
3344 VALS(ls_opaque_type_vals), 0x0, NULL, HFILL }},
3346 {&hf_ospf_filter[OSPFF_LS_MPLS_TE_INSTANCE],
3347 { "Link State ID TE-LSA Instance", "ospf.lsid_te_lsa.instance", FT_UINT16, BASE_DEC,
3348 NULL, 0x0, NULL, HFILL }},
3350 {&hf_ospf_filter[OSPFF_LS_ROUTER],
3351 { "Router LSA", "ospf.lsa.router", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3352 NULL, HFILL }},
3353 {&hf_ospf_filter[OSPFF_LS_NETWORK],
3354 { "Network LSA", "ospf.lsa.network", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3355 NULL, HFILL }},
3356 {&hf_ospf_filter[OSPFF_LS_SUMMARY],
3357 { "Summary LSA (IP Network)", "ospf.lsa.summary", FT_BOOLEAN, BASE_NONE,
3358 NULL, 0x0, NULL, HFILL }},
3359 {&hf_ospf_filter[OSPFF_LS_ASBR],
3360 { "Summary LSA (ASBR)", "ospf.lsa.asbr", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3361 NULL, HFILL }},
3362 {&hf_ospf_filter[OSPFF_LS_ASEXT],
3363 { "AS-External LSA (ASBR)", "ospf.lsa.asext", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3364 NULL, HFILL }},
3365 {&hf_ospf_filter[OSPFF_LS_GRPMEMBER],
3366 { "Group Membership LSA", "ospf.lsa.member", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3367 NULL, HFILL }},
3368 {&hf_ospf_filter[OSPFF_LS_ASEXT7],
3369 { "NSSA AS-External LSA", "ospf.lsa.nssa", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3370 NULL, HFILL }},
3371 {&hf_ospf_filter[OSPFF_LS_EXTATTR],
3372 { "External Attributes LSA", "ospf.lsa.attr", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3373 NULL, HFILL }},
3374 {&hf_ospf_filter[OSPFF_LS_OPAQUE],
3375 { "Opaque LSA", "ospf.lsa.opaque", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3376 NULL, HFILL }},
3378 /* OSPFv3 LS Types */
3379 {&hf_ospf_filter[OSPFF_V3_LS_TYPE],
3380 { "LS Type", "ospf.v3.lsa", FT_UINT16, BASE_HEX,
3381 VALS(v3_ls_type_vals), 0x0, NULL, HFILL }},
3383 {&hf_ospf_filter[OSPFF_V3_LS_ROUTER],
3384 { "Router-LSA", "ospf.v3.lsa.router", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3385 NULL, HFILL }},
3386 {&hf_ospf_filter[OSPFF_V3_LS_NETWORK],
3387 { "Network-LSA", "ospf.v3.lsa.network", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3388 NULL, HFILL }},
3389 {&hf_ospf_filter[OSPFF_V3_LS_INTER_AREA_PREFIX],
3390 { "Inter-Area-Prefix-LSA", "ospf.v3.lsa.interprefix", FT_BOOLEAN, BASE_NONE,
3391 NULL, 0x0, NULL, HFILL }},
3392 {&hf_ospf_filter[OSPFF_V3_LS_INTER_AREA_ROUTER],
3393 { "Inter-Area-Router-LSA", "ospf.v3.lsa.interrouter", FT_BOOLEAN, BASE_NONE,
3394 NULL, 0x0, NULL, HFILL }},
3395 {&hf_ospf_filter[OSPFF_V3_LS_AS_EXTERNAL],
3396 { "AS-External-LSA", "ospf.v3.lsa.asext", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3397 NULL, HFILL }},
3398 {&hf_ospf_filter[OSPFF_V3_LS_GROUP_MEMBERSHIP],
3399 { "Group-Membership-LSA", "ospf.v3.lsa.member", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3400 NULL, HFILL }},
3401 {&hf_ospf_filter[OSPFF_V3_LS_NSSA],
3402 { "NSSA-LSA", "ospf.v3.lsa.nssa", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3403 NULL, HFILL }},
3404 {&hf_ospf_filter[OSPFF_V3_LS_LINK],
3405 { "Link-LSA", "ospf.v3.lsa.link", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3406 NULL, HFILL }},
3407 {&hf_ospf_filter[OSPFF_V3_LS_INTRA_AREA_PREFIX],
3408 { "Intra-Area-Prefix-LSA", "ospf.v3.lsa.intraprefix", FT_BOOLEAN, BASE_NONE,
3409 NULL, 0x0, NULL, HFILL }},
3410 {&hf_ospf_filter[OSPFF_V3_LS_OPAQUE_RI],
3411 { "Router Information Opaque-LSA", "ospf.v3.lsa.opaque", FT_BOOLEAN, BASE_NONE,
3412 NULL, 0x0, NULL, HFILL }},
3414 /* Other interesting OSPF values */
3415 {&hf_ospf_filter[OSPFF_SRC_ROUTER],
3416 { "Source OSPF Router", "ospf.srcrouter", FT_IPv4, BASE_NONE, NULL, 0x0,
3417 NULL, HFILL }},
3419 {&hf_ospf_filter[OSPFF_ADV_ROUTER],
3420 { "Advertising Router", "ospf.advrouter", FT_IPv4, BASE_NONE, NULL, 0x0,
3421 NULL, HFILL }},
3423 {&hf_ospf_filter[OSPFF_LS_MPLS],
3424 { "MPLS Traffic Engineering LSA", "ospf.lsa.mpls", FT_BOOLEAN,
3425 BASE_NONE, NULL, 0x0, NULL, HFILL }},
3427 {&hf_ospf_filter[OSPFF_LS_MPLS_ROUTERID],
3428 { "MPLS/TE Router ID", "ospf.mpls.routerid", FT_IPv4, BASE_NONE, NULL, 0x0,
3429 NULL, HFILL }},
3431 {&hf_ospf_filter[OSPFF_LS_MPLS_LINKTYPE],
3432 { "MPLS/TE Link Type", "ospf.mpls.linktype", FT_UINT8, BASE_DEC,
3433 VALS(mpls_link_stlv_ltype_str), 0x0, NULL, HFILL }},
3434 {&hf_ospf_filter[OSPFF_LS_MPLS_LINKID],
3435 { "MPLS/TE Link ID", "ospf.mpls.linkid", FT_IPv4, BASE_NONE, NULL, 0x0,
3436 NULL, HFILL }},
3437 {&hf_ospf_filter[OSPFF_LS_MPLS_LOCAL_ADDR],
3438 { "MPLS/TE Local Interface Address", "ospf.mpls.local_addr", FT_IPv4,
3439 BASE_NONE, NULL, 0x0, NULL, HFILL }},
3440 {&hf_ospf_filter[OSPFF_LS_MPLS_REMOTE_ADDR],
3441 { "MPLS/TE Remote Interface Address", "ospf.mpls.remote_addr", FT_IPv4,
3442 BASE_NONE, NULL, 0x0, NULL, HFILL }},
3443 {&hf_ospf_filter[OSPFF_LS_MPLS_LOCAL_IFID],
3444 { "MPLS/TE Local Interface Index", "ospf.mpls.local_id", FT_UINT32,
3445 BASE_DEC, NULL, 0x0, NULL, HFILL }},
3446 {&hf_ospf_filter[OSPFF_LS_MPLS_REMOTE_IFID],
3447 { "MPLS/TE Remote Interface Index", "ospf.mpls.remote_id", FT_UINT32,
3448 BASE_DEC, NULL, 0x0, NULL, HFILL }},
3449 {&hf_ospf_filter[OSPFF_LS_MPLS_LINKCOLOR],
3450 { "MPLS/TE Link Resource Class/Color", "ospf.mpls.linkcolor", FT_UINT32,
3451 BASE_HEX, NULL, 0x0, NULL, HFILL }},
3452 {&hf_ospf_filter[OSPFF_LS_MPLS_BC_MODEL_ID],
3453 { "MPLS/DSTE Bandwidth Constraints Model Id", "ospf.mpls.bc", FT_UINT8,
3454 BASE_RANGE_STRING | BASE_DEC, RVALS(mpls_link_stlv_bcmodel_rvals), 0x0,
3455 NULL, HFILL }},
3457 {&hf_ospf_filter[OSPFF_LS_OIF_LOCAL_NODE_ID],
3458 { "Local Node ID", "ospf.oif.local_node_id", FT_IPv4,
3459 BASE_NONE, NULL, 0x0, NULL, HFILL }},
3460 {&hf_ospf_filter[OSPFF_LS_OIF_REMOTE_NODE_ID],
3461 { "Remote Node ID", "ospf.oif.remote_node_id", FT_IPv4,
3462 BASE_NONE, NULL, 0x0, NULL, HFILL }},
3464 {&hf_ospf_filter[OSPFF_V2_OPTIONS],
3465 { "Options", "ospf.v2.options", FT_UINT8, BASE_HEX,
3466 NULL, 0x0, NULL, HFILL }},
3467 {&hf_ospf_filter[OSPFF_V2_OPTIONS_MT],
3468 { "MT", "ospf.v2.options.mt", FT_BOOLEAN, 8,
3469 TFS(&tfs_v2_options_mt), OSPF_V2_OPTIONS_MT, NULL, HFILL }},
3470 {&hf_ospf_filter[OSPFF_V2_OPTIONS_E],
3471 { "E", "ospf.v2.options.e", FT_BOOLEAN, 8,
3472 TFS(&tfs_v2_options_e), OSPF_V2_OPTIONS_E, NULL, HFILL }},
3473 {&hf_ospf_filter[OSPFF_V2_OPTIONS_MC],
3474 { "MC", "ospf.v2.options.mc", FT_BOOLEAN, 8,
3475 TFS(&tfs_v2_options_mc), OSPF_V2_OPTIONS_MC, NULL, HFILL }},
3476 {&hf_ospf_filter[OSPFF_V2_OPTIONS_NP],
3477 { "NP", "ospf.v2.options.np", FT_BOOLEAN, 8,
3478 TFS(&tfs_v2_options_np), OSPF_V2_OPTIONS_NP, NULL, HFILL }},
3479 {&hf_ospf_filter[OSPFF_V2_OPTIONS_L],
3480 { "L", "ospf.v2.options.l", FT_BOOLEAN, 8,
3481 TFS(&tfs_v2_options_l), OSPF_V2_OPTIONS_L, NULL, HFILL }},
3482 {&hf_ospf_filter[OSPFF_V2_OPTIONS_DC],
3483 { "DC", "ospf.v2.options.dc", FT_BOOLEAN, 8,
3484 TFS(&tfs_v2_options_dc), OSPF_V2_OPTIONS_DC, NULL, HFILL }},
3485 {&hf_ospf_filter[OSPFF_V2_OPTIONS_O],
3486 { "O", "ospf.v2.options.o", FT_BOOLEAN, 8,
3487 TFS(&tfs_v2_options_o), OSPF_V2_OPTIONS_O, NULL, HFILL }},
3488 {&hf_ospf_filter[OSPFF_V2_OPTIONS_DN],
3489 { "DN", "ospf.v2.options.dn", FT_BOOLEAN, 8,
3490 TFS(&tfs_v2_options_dn), OSPF_V2_OPTIONS_DN, NULL, HFILL }},
3492 {&hf_ospf_filter[OSPFF_RI_OPTIONS],
3493 { "RI Options", "ospf.ri.options", FT_UINT8, BASE_HEX,
3494 NULL, 0x0, NULL, HFILL }},
3495 {&hf_ospf_filter[OSPFF_RI_OPTIONS_GRC],
3496 { "GRC", "ospf.ri.options.grc", FT_BOOLEAN, 8,
3497 TFS(&tfs_ri_options_grc), OSPF_RI_OPTIONS_GRC, NULL, HFILL }},
3498 {&hf_ospf_filter[OSPFF_RI_OPTIONS_GRH],
3499 { "GRH", "ospf.ri.options.grh", FT_BOOLEAN, 8,
3500 TFS(&tfs_ri_options_grh), OSPF_RI_OPTIONS_GRH, NULL, HFILL }},
3501 {&hf_ospf_filter[OSPFF_RI_OPTIONS_SRS],
3502 { "SRS", "ospf.ri.options.srs", FT_BOOLEAN, 8,
3503 TFS(&tfs_ri_options_srs), OSPF_RI_OPTIONS_SRS, NULL, HFILL }},
3504 {&hf_ospf_filter[OSPFF_RI_OPTIONS_TES],
3505 { "TES", "ospf.ri.options.tes", FT_BOOLEAN, 8,
3506 TFS(&tfs_ri_options_tes), OSPF_RI_OPTIONS_TES, NULL, HFILL }},
3507 {&hf_ospf_filter[OSPFF_RI_OPTIONS_P2PLAN],
3508 { "P2PLAN", "ospf.ri.options.p2plan", FT_BOOLEAN, 8,
3509 TFS(&tfs_ri_options_p2plan), OSPF_RI_OPTIONS_P2PLAN, NULL, HFILL }},
3510 {&hf_ospf_filter[OSPFF_RI_OPTIONS_ETE],
3511 { "ETE", "ospf.ri.options.ete", FT_BOOLEAN, 8,
3512 TFS(&tfs_ri_options_ete), OSPF_RI_OPTIONS_ETE, NULL, HFILL }},
3514 /* An MBZ field for the 24-bits of type field of Opaque RI LSA */
3515 {&hf_ospf_filter[OSPFF_OPAQUE_LSA_MBZ],
3516 { "MBZ", "ospf.ri.mbz", FT_UINT16, BASE_HEX,
3517 NULL, 0x0, "OSPF Opaque RI LSA - 24 bits of Type Field Must be Zero", HFILL }},
3519 {&hf_ospf_filter[OSPFF_V3_OPTIONS],
3520 { "Options", "ospf.v3.options", FT_UINT24, BASE_HEX,
3521 NULL, 0x0, NULL, HFILL }},
3522 {&hf_ospf_filter[OSPFF_V3_OPTIONS_V6],
3523 { "V6", "ospf.v3.options.v6", FT_BOOLEAN, 24,
3524 TFS(&tfs_v3_options_v6), OSPF_V3_OPTIONS_V6, NULL, HFILL }},
3525 {&hf_ospf_filter[OSPFF_V3_OPTIONS_E],
3526 { "E", "ospf.v3.options.e", FT_BOOLEAN, 24,
3527 TFS(&tfs_v3_options_e), OSPF_V3_OPTIONS_E, NULL, HFILL }},
3528 {&hf_ospf_filter[OSPFF_V3_OPTIONS_MC],
3529 { "MC", "ospf.v3.options.mc", FT_BOOLEAN, 24,
3530 TFS(&tfs_v3_options_mc), OSPF_V3_OPTIONS_MC, NULL, HFILL }},
3531 {&hf_ospf_filter[OSPFF_V3_OPTIONS_N],
3532 { "N", "ospf.v3.options.n", FT_BOOLEAN, 24,
3533 TFS(&tfs_v3_options_n), OSPF_V3_OPTIONS_N, NULL, HFILL }},
3534 {&hf_ospf_filter[OSPFF_V3_OPTIONS_R],
3535 { "R", "ospf.v3.options.r", FT_BOOLEAN, 24,
3536 TFS(&tfs_v3_options_r), OSPF_V3_OPTIONS_R, NULL, HFILL }},
3537 {&hf_ospf_filter[OSPFF_V3_OPTIONS_DC],
3538 { "DC", "ospf.v3.options.dc", FT_BOOLEAN, 24,
3539 TFS(&tfs_v3_options_dc), OSPF_V3_OPTIONS_DC, NULL, HFILL }},
3540 {&hf_ospf_filter[OSPFF_V3_OPTIONS_AF],
3541 { "AF", "ospf.v3.options.af", FT_BOOLEAN, 24,
3542 TFS(&tfs_v3_options_af), OSPF_V3_OPTIONS_AF, NULL, HFILL }},
3543 {&hf_ospf_filter[OSPFF_V3_OPTIONS_L],
3544 { "L", "ospf.v3.options.l", FT_BOOLEAN, 24,
3545 TFS(&tfs_v3_options_l), OSPF_V3_OPTIONS_L, NULL, HFILL }},
3546 {&hf_ospf_filter[OSPFF_V3_OPTIONS_I],
3547 { "I", "ospf.v3.options.i", FT_BOOLEAN, 24,
3548 TFS(&tfs_v3_options_i), OSPF_V3_OPTIONS_I, NULL, HFILL }},
3549 {&hf_ospf_filter[OSPFF_V3_OPTIONS_F],
3550 { "F", "ospf.v3.options.f", FT_BOOLEAN, 24,
3551 TFS(&tfs_v3_options_f), OSPF_V3_OPTIONS_F, NULL, HFILL }},
3552 {&hf_ospf_filter[OSPFF_DBD],
3553 { "DB Description", "ospf.dbd", FT_UINT8, BASE_HEX,
3554 NULL, 0x0, NULL, HFILL }},
3555 {&hf_ospf_filter[OSPFF_DBD_R],
3556 { "R", "ospf.dbd.r", FT_BOOLEAN, 8,
3557 TFS(&tfs_dbd_r), OSPF_DBD_FLAG_R, NULL, HFILL }},
3558 {&hf_ospf_filter[OSPFF_DBD_I],
3559 { "I", "ospf.dbd.i", FT_BOOLEAN, 8,
3560 TFS(&tfs_dbd_i), OSPF_DBD_FLAG_I, NULL, HFILL }},
3561 {&hf_ospf_filter[OSPFF_DBD_M],
3562 { "M", "ospf.dbd.m", FT_BOOLEAN, 8,
3563 TFS(&tfs_dbd_m), OSPF_DBD_FLAG_M, NULL, HFILL }},
3564 {&hf_ospf_filter[OSPFF_DBD_MS],
3565 { "MS", "ospf.dbd.ms", FT_BOOLEAN, 8,
3566 TFS(&tfs_dbd_ms), OSPF_DBD_FLAG_MS, NULL, HFILL }},
3567 {&hf_ospf_filter[OSPFF_LLS_EXT_OPTIONS],
3568 { "Options", "ospf.lls.ext.options", FT_UINT32, BASE_HEX,
3569 NULL, 0x0, NULL, HFILL }},
3570 {&hf_ospf_filter[OSPFF_LLS_EXT_OPTIONS_LR],
3571 { "LR", "ospf.lls.ext.options.lr", FT_BOOLEAN, 32,
3572 TFS(&tfs_lls_ext_options_lr), OSPF_LLS_EXT_OPTIONS_LR, NULL, HFILL }},
3573 {&hf_ospf_filter[OSPFF_LLS_EXT_OPTIONS_RS],
3574 { "RS", "ospf.lls.ext.options.rs", FT_BOOLEAN, 32,
3575 TFS(&tfs_lls_ext_options_rs), OSPF_LLS_EXT_OPTIONS_RS, NULL, HFILL }},
3576 {&hf_ospf_filter[OSPFF_V2_ROUTER_LSA_FLAG],
3577 { "Flags", "ospf.v2.router.lsa.flags", FT_UINT8, BASE_HEX,
3578 NULL, 0x0, NULL, HFILL }},
3579 {&hf_ospf_filter[OSPFF_V2_ROUTER_LSA_FLAG_B],
3580 { "B", "ospf.v2.router.lsa.flags.b", FT_BOOLEAN, 8,
3581 TFS(&tfs_v2_router_lsa_flags_b), OSPF_V2_ROUTER_LSA_FLAG_B, NULL, HFILL }},
3582 {&hf_ospf_filter[OSPFF_V2_ROUTER_LSA_FLAG_E],
3583 { "E", "ospf.v2.router.lsa.flags.e", FT_BOOLEAN, 8,
3584 TFS(&tfs_v2_router_lsa_flags_e), OSPF_V2_ROUTER_LSA_FLAG_E, NULL, HFILL }},
3585 {&hf_ospf_filter[OSPFF_V2_ROUTER_LSA_FLAG_V],
3586 { "V", "ospf.v2.router.lsa.flags.v", FT_BOOLEAN, 8,
3587 TFS(&tfs_v2_router_lsa_flags_v), OSPF_V2_ROUTER_LSA_FLAG_V, NULL, HFILL }},
3588 {&hf_ospf_filter[OSPFF_V2_ROUTER_LSA_FLAG_W],
3589 { "W", "ospf.v2.router.lsa.flags.w", FT_BOOLEAN, 8,
3590 TFS(&tfs_v2_router_lsa_flags_w), OSPF_V2_ROUTER_LSA_FLAG_W, NULL, HFILL }},
3591 {&hf_ospf_filter[OSPFF_V2_ROUTER_LSA_FLAG_N],
3592 { "N", "ospf.v2.router.lsa.flags.n", FT_BOOLEAN, 8,
3593 TFS(&tfs_v2_router_lsa_flags_n), OSPF_V2_ROUTER_LSA_FLAG_N, NULL, HFILL }},
3594 {&hf_ospf_filter[OSPFF_V3_ROUTER_LSA_FLAG],
3595 { "Flags", "ospf.v3.router.lsa.flags", FT_UINT8, BASE_HEX,
3596 NULL, 0x0, NULL, HFILL }},
3597 {&hf_ospf_filter[OSPFF_V3_ROUTER_LSA_FLAG_B],
3598 { "B", "ospf.v3.router.lsa.flags.b", FT_BOOLEAN, 8,
3599 TFS(&tfs_v3_router_lsa_flags_b), OSPF_V3_ROUTER_LSA_FLAG_B, NULL, HFILL }},
3600 {&hf_ospf_filter[OSPFF_V3_ROUTER_LSA_FLAG_E],
3601 { "E", "ospf.v3.router.lsa.flags.e", FT_BOOLEAN, 8,
3602 TFS(&tfs_v3_router_lsa_flags_e), OSPF_V3_ROUTER_LSA_FLAG_E, NULL, HFILL }},
3603 {&hf_ospf_filter[OSPFF_V3_ROUTER_LSA_FLAG_V],
3604 { "V", "ospf.v3.router.lsa.flags.v", FT_BOOLEAN, 8,
3605 TFS(&tfs_v3_router_lsa_flags_v), OSPF_V3_ROUTER_LSA_FLAG_V, NULL, HFILL }},
3606 {&hf_ospf_filter[OSPFF_V3_ROUTER_LSA_FLAG_W],
3607 { "W", "ospf.v3.router.lsa.flags.w", FT_BOOLEAN, 8,
3608 TFS(&tfs_v3_router_lsa_flags_w), OSPF_V3_ROUTER_LSA_FLAG_W, NULL, HFILL }},
3609 {&hf_ospf_filter[OSPFF_V3_AS_EXTERNAL_FLAG],
3610 { "Flags", "ospf.v3.as.external.flags", FT_UINT8, BASE_HEX,
3611 NULL, 0x0, NULL, HFILL }},
3612 {&hf_ospf_filter[OSPFF_V3_AS_EXTERNAL_FLAG_T],
3613 { "T", "ospf.v3.as.external.flags.t", FT_BOOLEAN, 8,
3614 TFS(&tfs_v3_as_external_flags_t), OSPF_V3_AS_EXTERNAL_FLAG_T, NULL, HFILL }},
3615 {&hf_ospf_filter[OSPFF_V3_AS_EXTERNAL_FLAG_F],
3616 { "F", "ospf.v3.as.external.flags.f", FT_BOOLEAN, 8,
3617 TFS(&tfs_v3_as_external_flags_f), OSPF_V3_AS_EXTERNAL_FLAG_F, NULL, HFILL }},
3618 {&hf_ospf_filter[OSPFF_V3_AS_EXTERNAL_FLAG_E],
3619 { "E", "ospf.v3.as.external.flags.e", FT_BOOLEAN, 8,
3620 TFS(&tfs_v3_as_external_flags_e), OSPF_V3_AS_EXTERNAL_FLAG_E, NULL, HFILL }},
3621 {&hf_ospf_filter[OSPFF_V3_PREFIX_OPTION],
3622 { "PrefixOptions", "ospf.v3.prefix.options", FT_UINT8, BASE_HEX,
3623 NULL, 0x0, NULL, HFILL }},
3624 {&hf_ospf_filter[OSPFF_V3_PREFIX_OPTION_NU],
3625 { "NU", "ospf.v3.prefix.options.nu", FT_BOOLEAN, 8,
3626 TFS(&tfs_v3_prefix_options_nu), OSPF_V3_PREFIX_OPTION_NU, NULL, HFILL }},
3627 {&hf_ospf_filter[OSPFF_V3_PREFIX_OPTION_LA],
3628 { "LA", "ospf.v3.prefix.options.la", FT_BOOLEAN, 8,
3629 TFS(&tfs_v3_prefix_options_la), OSPF_V3_PREFIX_OPTION_LA, NULL, HFILL }},
3630 {&hf_ospf_filter[OSPFF_V3_PREFIX_OPTION_MC],
3631 { "MC", "ospf.v3.prefix.options.mc", FT_BOOLEAN, 8,
3632 TFS(&tfs_v3_prefix_options_mc), OSPF_V3_PREFIX_OPTION_MC, NULL, HFILL }},
3633 {&hf_ospf_filter[OSPFF_V3_PREFIX_OPTION_P],
3634 { "P", "ospf.v3.prefix.options.p", FT_BOOLEAN, 8,
3635 TFS(&tfs_v3_prefix_options_p), OSPF_V3_PREFIX_OPTION_P, NULL, HFILL }},
3637 /* Dynamic Hostname contained in the Opaque RI LSA - dynamic hostname TLV*/
3638 {&hf_ospf_filter[OSPFF_DYN_HOSTNAME],
3639 { "Dynamic Hostname", "ospf.dynhostname", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3641 /* text contained in the Unknown TLV of the Opaque RI LSA */
3642 {&hf_ospf_filter[OSPFF_UNKNOWN_TLV_TXT],
3643 { "Text in the Unknown TLV", "ospf.unknown_text", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3645 /* OSPF Restart TLVs */
3646 {&hf_ospf_filter[OSPFF_V2_GRACE_TLV],
3647 { "Grace TLV", "ospf.v2.grace", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3648 {&hf_ospf_filter[OSPFF_V2_GRACE_PERIOD],
3649 { "Grace Period", "ospf.v2.grace.period", FT_UINT32, BASE_DEC,
3650 NULL, 0x0,
3651 "The number of seconds neighbors should advertise the router as fully adjacent",
3652 HFILL }},
3653 {&hf_ospf_filter[OSPFF_V2_GRACE_REASON],
3654 { "Restart Reason", "ospf.v2.grace.reason", FT_UINT8, BASE_DEC,
3655 VALS(restart_reason_vals), 0x0, "The reason the router is restarting", HFILL }},
3656 {&hf_ospf_filter[OSPFF_V2_GRACE_IP],
3657 { "Restart IP", "ospf.v2.grace.ip", FT_IPv4, BASE_NONE,
3658 NULL, 0x0, "The IP address of the interface originating this LSA", HFILL }},
3660 /* OSPFv3 LLS TLVs */
3661 {&hf_ospf_filter[OSPFF_V3_LLS_EXT_OPTIONS_TLV],
3662 { "Extended Options TLV", "ospf.v3.lls.ext.options.tlv", FT_NONE, BASE_NONE,
3663 NULL, 0x0, NULL, HFILL }},
3664 {&hf_ospf_filter[OSPFF_V3_LLS_EXT_OPTIONS],
3665 { "Options", "ospf.v3.lls.ext.options", FT_UINT32, BASE_HEX,
3666 NULL, 0x0, NULL, HFILL }},
3667 {&hf_ospf_filter[OSPFF_V3_LLS_EXT_OPTIONS_LR],
3668 { "LR", "ospf.v3.lls.ext.options.lr", FT_BOOLEAN, 32,
3669 TFS(&tfs_v3_lls_ext_options_lr), OSPF_V3_LLS_EXT_OPTIONS_LR, NULL, HFILL }},
3670 {&hf_ospf_filter[OSPFF_V3_LLS_EXT_OPTIONS_RS],
3671 { "RS", "ospf.v3.lls.ext.options.rs", FT_BOOLEAN, 32,
3672 TFS(&tfs_v3_lls_ext_options_rs), OSPF_V3_LLS_EXT_OPTIONS_RS, NULL, HFILL }},
3673 {&hf_ospf_filter[OSPFF_V3_LLS_STATE_TLV],
3674 { "State Check Sequence TLV", "ospf.v3.lls.state.tlv", FT_NONE, BASE_NONE,
3675 NULL, 0x0, NULL, HFILL }},
3676 {&hf_ospf_filter[OSPFF_V3_LLS_STATE_SCS],
3677 { "SCS Number", "ospf.v3.lls.state.scs", FT_UINT16, BASE_DEC,
3678 NULL, 0x0, NULL, HFILL }},
3679 {&hf_ospf_filter[OSPFF_V3_LLS_STATE_OPTIONS],
3680 { "Options", "ospf.v3.lls.state.options", FT_UINT8, BASE_HEX,
3681 NULL, 0x0, NULL, HFILL }},
3682 {&hf_ospf_filter[OSPFF_V3_LLS_STATE_OPTIONS_R],
3683 { "R", "ospf.v3.lls.state.options.r", FT_BOOLEAN, 8,
3684 TFS(&tfs_v3_lls_state_options_r), OSPF_V3_LLS_STATE_OPTIONS_R, NULL, HFILL }},
3685 {&hf_ospf_filter[OSPFF_V3_LLS_STATE_OPTIONS_A],
3686 { "A", "ospf.v3.lls.state.options.a", FT_BOOLEAN, 8,
3687 TFS(&tfs_v3_lls_state_options_a), OSPF_V3_LLS_STATE_OPTIONS_A , NULL, HFILL }},
3688 {&hf_ospf_filter[OSPFF_V3_LLS_STATE_OPTIONS_N],
3689 { "N", "ospf.v3.lls.state.options.n", FT_BOOLEAN, 8,
3690 TFS(&tfs_v3_lls_state_options_n), OSPF_V3_LLS_STATE_OPTIONS_N ,NULL, HFILL }},
3691 {&hf_ospf_filter[OSPFF_V3_LLS_DROP_TLV],
3692 { "Neighbor Drop TLV", "ospf.v3.lls.drop.tlv", FT_NONE, BASE_NONE,
3693 NULL, 0x0, NULL, HFILL }},
3694 {&hf_ospf_filter[OSPFF_V3_LLS_RELAY_TLV],
3695 { "Active Overlapping Relays TLV", "ospf.v3.lls.relay.tlv", FT_NONE, BASE_NONE,
3696 NULL, 0x0, NULL, HFILL }},
3697 {&hf_ospf_filter[OSPFF_V3_LLS_RELAY_ADDED],
3698 { "Relays Added", "ospf.v3.lls.relay.added", FT_UINT8, BASE_DEC,
3699 NULL, 0x0, NULL, HFILL }},
3700 {&hf_ospf_filter[OSPFF_V3_LLS_RELAY_OPTIONS],
3701 { "Options", "ospf.v3.lls.relay.options", FT_UINT8, BASE_HEX,
3702 NULL, 0x0, NULL, HFILL }},
3703 {&hf_ospf_filter[OSPFF_V3_LLS_RELAY_OPTIONS_A],
3704 { "A", "ospf.v3.lls.relay.options.a", FT_BOOLEAN, 8,
3705 TFS(&tfs_v3_lls_relay_options_a), OSPF_V3_LLS_RELAY_OPTIONS_A , NULL, HFILL }},
3706 {&hf_ospf_filter[OSPFF_V3_LLS_RELAY_OPTIONS_N],
3707 { "N", "ospf.v3.lls.relay.options.n", FT_BOOLEAN, 8,
3708 TFS(&tfs_v3_lls_relay_options_n), OSPF_V3_LLS_RELAY_OPTIONS_N ,NULL, HFILL }},
3709 {&hf_ospf_filter[OSPFF_V3_LLS_WILLINGNESS_TLV],
3710 { "Willingness TLV", "ospf.v3.lls.willingness.tlv", FT_NONE, BASE_NONE,
3711 NULL, 0x0, NULL, HFILL }},
3712 {&hf_ospf_filter[OSPFF_V3_LLS_WILLINGNESS],
3713 { "Willingness", "ospf.v3.lls.willingness", FT_UINT8, BASE_DEC,
3714 NULL, 0x0, NULL, HFILL }},
3715 {&hf_ospf_filter[OSPFF_V3_LLS_RF_TLV],
3716 { "Request From TLV", "ospf.v3.lls.rf.tlv", FT_NONE, BASE_NONE,
3717 NULL, 0x0, NULL, HFILL }},
3718 {&hf_ospf_filter[OSPFF_V3_LLS_FSF_TLV],
3719 { "Full State For TLV", "ospf.v3.lls.fsf.tlv", FT_NONE, BASE_NONE,
3720 NULL, 0x0, NULL, HFILL }}
3723 static gint *ett[] = {
3724 &ett_ospf,
3725 &ett_ospf_hdr,
3726 &ett_ospf_hello,
3727 &ett_ospf_desc,
3728 &ett_ospf_lsr,
3729 &ett_ospf_lsa,
3730 &ett_ospf_lsa_router_link,
3731 &ett_ospf_lsa_upd,
3732 &ett_ospf_lsa_mpls,
3733 &ett_ospf_lsa_mpls_router,
3734 &ett_ospf_lsa_mpls_link,
3735 &ett_ospf_lsa_mpls_link_stlv,
3736 &ett_ospf_lsa_mpls_link_stlv_admingrp,
3737 &ett_ospf_lsa_opaque_ri,
3738 &ett_ospf_lsa_ri_tlv,
3739 &ett_ospf_lsa_dyn_hostname_tlv,
3740 &ett_ospf_lsa_unknown_tlv,
3741 &ett_ospf_lsa_oif_tna,
3742 &ett_ospf_lsa_oif_tna_stlv,
3743 &ett_ospf_lsa_grace_tlv,
3744 &ett_ospf_v2_options,
3745 &ett_ospf_ri_options,
3746 &ett_ospf_v3_options,
3747 &ett_ospf_dbd,
3748 &ett_ospf_lls_data_block,
3749 &ett_ospf_lls_tlv,
3750 &ett_ospf_lls_ext_options,
3751 &ett_ospf_v3_lls_ext_options_tlv,
3752 &ett_ospf_v3_lls_ext_options,
3753 &ett_ospf_v3_lls_state_tlv,
3754 &ett_ospf_v3_lls_state_scs,
3755 &ett_ospf_v3_lls_state_options,
3756 &ett_ospf_v3_lls_drop_tlv,
3757 &ett_ospf_v3_lls_relay_tlv,
3758 &ett_ospf_v3_lls_relay_added,
3759 &ett_ospf_v3_lls_relay_options,
3760 &ett_ospf_v3_lls_willingness_tlv,
3761 &ett_ospf_v3_lls_willingness,
3762 &ett_ospf_v3_lls_rf_tlv,
3763 &ett_ospf_v3_lls_fsf_tlv,
3764 &ett_ospf_v2_router_lsa_flags,
3765 &ett_ospf_v3_router_lsa_flags,
3766 &ett_ospf_v3_as_external_flags,
3767 &ett_ospf_v3_prefix_options
3770 proto_ospf = proto_register_protocol("Open Shortest Path First",
3771 "OSPF", "ospf");
3772 proto_register_field_array(proto_ospf, ospff_info, array_length(ospff_info));
3773 proto_register_subtree_array(ett, array_length(ett));
3776 void
3777 proto_reg_handoff_ospf(void)
3779 dissector_handle_t ospf_handle;
3781 ospf_handle = create_dissector_handle(dissect_ospf, proto_ospf);
3782 dissector_add_uint("ip.proto", IP_PROTO_OSPF, ospf_handle);
3783 data_handle = find_dissector("data");