Make filterable OSPF Header...
[metze/wireshark/wip.git] / epan / dissectors / packet-ospf.c
1 /* packet-ospf.c
2  * Routines for OSPF packet disassembly
3  * (c) Copyright Hannes R. Boehm <hannes@boehm.org>
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 1998 Gerald Combs
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23 /*
24  * At this time, this module is able to analyze OSPF
25  * packets as specified in RFC2328. MOSPF (RFC1584) and other
26  * OSPF Extensions which introduce new Packet types
27  * (e.g the External Atributes LSA) are not supported.
28  * Furthermore RFC2740 (OSPFv3 - OSPF for IPv6) is now supported
29  *   - (c) 2001 Palle Lyckegaard <palle[AT]lyckegaard.dk>
30  *
31  * Added support to E-NNI routing (OIF2003.259.02)
32  *   - (c) 2004 Roberto Morro <roberto.morro[AT]tilab.com>
33  *
34  * Added support for OSPF restart signaling:
35  *       draft-nguyen-ospf-lls-05.txt
36  *       draft-nguyen-ospf-oob-resync-05.txt
37  *       draft-nguyen-ospf-restart-05.txt
38  *   - (c) 2005 Michael Rozhavsky <mrozhavsky@fortinet.com>
39  *
40  * Added support of MPLS Diffserv-aware TE (RFC 4124); new BC sub-TLV
41  *   - (c) 2006 (FF) <francesco.fondelli[AT]gmail.com>
42  *
43  * Added support for decoding the TLVs in a grace-LSA
44  *   - (c) 2007 Todd J Martin <todd.martin@acm.org>
45  *
46  * Added support for draft-ietf-ospf-manet-or-02
47  * Added support for draft-ietf-ospf-af-alt-06
48  *   - (c) 2008 Cisco Systems
49  *
50  * Added support for Multi-Topology (MT) Routing (RFC4915)
51  *   - (c) 2009 Stig Bjorlykke <stig@bjorlykke.org>, Thales Norway AS
52  *
53  * Added support for OSPFv2 & OSPFv3 Router Information (RI) Opaque LSA (RFC4970); RI Capabilities TLV
54  * Added support for OSPFv2 & OSPFv3 Dynamic Hostname TLV in RI Opaque LSA (RFC5642)
55  *   - (c) 2011 Salil Kanitkar <sskanitk@ncsu.edu>, North Carolina State University
56  *
57  * Added support for Type Classification of Experimental and Reserved sub-TLVs (RFC3630)
58  *   - (c) 2013 Kaushal Shah <kshah3@ncsu.edu>, North Carolina State University
59  */
60
61 #include "config.h"
62
63 #include <string.h>
64 #include <glib.h>
65 #include <epan/packet.h>
66 #include <epan/ipproto.h>
67 #include <epan/in_cksum.h>
68 #include <epan/wmem/wmem.h>
69 #include <epan/addr_resolv.h>
70 #include "packet-rsvp.h"
71
72 void proto_register_ospf(void);
73 void proto_reg_handoff_ospf(void);
74
75 #define OSPF_VERSION_2 2
76 #define OSPF_VERSION_3 3
77 #define OSPF_AF_4 4
78 #define OSPF_AF_6 6
79 #define OSPF_VERSION_2_HEADER_LENGTH    24
80 #define OSPF_VERSION_3_HEADER_LENGTH    16
81
82
83 #define OSPF_HELLO      1
84 #define OSPF_DB_DESC    2
85 #define OSPF_LS_REQ     3
86 #define OSPF_LS_UPD     4
87 #define OSPF_LS_ACK     5
88
89 static const value_string pt_vals[] = {
90     {OSPF_HELLO,   "Hello Packet"   },
91     {OSPF_DB_DESC, "DB Description" },
92     {OSPF_LS_REQ,  "LS Request"     },
93     {OSPF_LS_UPD,  "LS Update"      },
94     {OSPF_LS_ACK,  "LS Acknowledge" },
95     {0,             NULL            }
96 };
97
98 #define OSPF_AUTH_NONE          0
99 #define OSPF_AUTH_SIMPLE        1
100 #define OSPF_AUTH_CRYPT         2
101
102 static const value_string auth_vals[] = {
103     {OSPF_AUTH_NONE,   "Null"            },
104     {OSPF_AUTH_SIMPLE, "Simple password" },
105     {OSPF_AUTH_CRYPT,  "Cryptographic"   },
106     {0,                NULL              }
107 };
108
109 #define OSPF_V2_OPTIONS_MT              0x01
110 #define OSPF_V2_OPTIONS_E               0x02
111 #define OSPF_V2_OPTIONS_MC              0x04
112 #define OSPF_V2_OPTIONS_NP              0x08
113 #define OSPF_V2_OPTIONS_L               0x10
114 #define OSPF_V2_OPTIONS_DC              0x20
115 #define OSPF_V2_OPTIONS_O               0x40
116 #define OSPF_V2_OPTIONS_DN              0x80
117 #define OSPF_V3_OPTIONS_V6              0x01
118 #define OSPF_V3_OPTIONS_E               0x02
119 #define OSPF_V3_OPTIONS_MC              0x04
120 #define OSPF_V3_OPTIONS_N               0x08
121 #define OSPF_V3_OPTIONS_R               0x10
122 #define OSPF_V3_OPTIONS_DC              0x20
123 #define OSPF_V3_OPTIONS_AF              0x0100
124 #define OSPF_V3_OPTIONS_L               0x0200
125 #define OSPF_V3_OPTIONS_AT              0x0400
126
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
134
135 #define OSPF_LLS_EXT_OPTIONS_LR         0x00000001
136 #define OSPF_LLS_EXT_OPTIONS_RS         0x00000002
137
138 #define OSPF_V3_LLS_EXT_OPTIONS_LR      0x00000001
139 #define OSPF_V3_LLS_EXT_OPTIONS_RS      0x00000002
140
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
146
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
151
152 #define OSPF_LS_REQ_LENGTH      12
153
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
172
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
177
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
188
189 #define OSPF_LINK_PTP           1
190 #define OSPF_LINK_TRANSIT       2
191 #define OSPF_LINK_STUB          3
192 #define OSPF_LINK_VIRTUAL       4
193
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
198
199 #define OSPF_LSA_HEADER_LENGTH  20
200
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
213
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}
220 };
221
222 /* grace-LSA TLV Types */
223 #define GRACE_TLV_PERIOD 1
224 #define GRACE_TLV_REASON 2
225 #define GRACE_TLV_IP 3
226
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}
232 };
233
234 /* Opaque-LSA - Router Informational Capabilities: TLV Types*/
235 #define OPT_RI_TLV       1
236 #define DYN_HOSTNAME_TLV 7
237
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}
244 };
245 #endif
246
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                           }
259
260 };
261
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                                     }
268 };
269
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                           }
282 };
283
284 static const value_string lls_tlv_type_vals[] = {
285     {1,                                   "Extended options TLV"         },
286     {2,                                   "Crypto Authentication TLV"    },
287     {0,                                   NULL                           }
288 };
289
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
298
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                            }
308 };
309
310 static const value_string mpls_link_stlv_ltype_str[] = {
311     {1, "Point-to-point"},
312     {2, "Multi-access"},
313     {0, NULL}
314 };
315
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                                                }
324 };
325
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
335
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
340
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
344
345
346 static int proto_ospf = -1;
347
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;
380
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;
394
395
396 static const true_false_string tfs_v2_options_dc = {
397     "Demand Circuits are supported",
398     "Demand Circuits are NOT supported"
399 };
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"
403 };
404 static const true_false_string tfs_v2_options_np = {
405     "NSSA is supported",
406     "NSSA is NOT supported"
407 };
408 static const true_false_string tfs_v2_options_mc = {
409     "Multicast Capable",
410     "NOT Multicast Capable"
411 };
412 static const true_false_string tfs_v2_options_e = {
413     "External Routing Capability",
414     "NO External Routing Capability"
415 };
416 static const true_false_string tfs_v2_options_mt = {
417     "Multi-Topology Routing",
418     "NO Multi-Topology Routing"
419 };
420
421 /* The Options field in the first TLV of the Opaque RI LSA with type field set to "4" for OSPFv2
422    and type field set to "12" in OSPFv3, is interpreted as advertizing optional router capabilties.
423    (RFC4970) */
424 static const true_false_string tfs_ri_options_grc = {
425     "OSPF Graceful Restart Capable",
426     "NOT OSPF Graceful Restart Capable"
427 };
428 static const true_false_string tfs_ri_options_grh = {
429     "OSPF Graceful Restart Helper",
430     "NOT OSPF Graceful Restart Helper"
431 };
432 static const true_false_string tfs_ri_options_srs = {
433     "OSPF Stub Router Support",
434     "NOT OSPF Stub Router Support"
435 };
436 static const true_false_string tfs_ri_options_tes = {
437     "OSPF Traffic Engineering Support",
438     "NOT OSPF Traffic Engineering Support"
439 };
440 static const true_false_string tfs_ri_options_p2plan = {
441     "OSPF point-to-point over LAN",
442     "NOT OSPF point-to-point over LAN"
443 };
444 static const true_false_string tfs_ri_options_ete = {
445     "OSPF Experimental TE",
446     "NOT OSPF Experimental TE"
447 };
448
449
450
451 static const true_false_string tfs_dbd_i = {
452     "Init bit is SET",
453     "Init bit is NOT set"
454 };
455 static const true_false_string tfs_dbd_m = {
456     "More bit is SET",
457     "More bit is NOT set"
458 };
459 static const true_false_string tfs_dbd_ms = {
460     "Master/Slave bit is SET",
461     "Master/Slave bit is NOT set"
462 };
463 static const true_false_string tfs_dbd_r = {
464     "OOBResync bit is SET",
465     "OOBResync bit is NOT set"
466 };
467 static const true_false_string tfs_lls_ext_options_lr = {
468     "LSDB Resynchronization (LR-bit) is SET",
469     "LSDB Resynchronization (LR-bit) is NOT set"
470 };
471 static const true_false_string tfs_lls_ext_options_rs = {
472     "Restart Signal (RS-bit) is SET",
473     "Restart Signal (RS-bit) is NOT set"
474 };
475 static const true_false_string tfs_v3_lls_ext_options_lr = {
476     "LSDB Resynchronization (LR-bit) is SET",
477     "LSDB Resynchronization (LR-bit) is NOT set"
478 };
479 static const true_false_string tfs_v3_lls_ext_options_rs = {
480     "Restart Signal (RS-bit) is SET",
481     "Restart Signal (RS-bit) is NOT set"
482 };
483 static const true_false_string tfs_v3_lls_state_options_r = {
484     "Request (R-bit) is SET",
485     "Request (R-bit) is NOT set",
486 };
487 static const true_false_string tfs_v3_lls_state_options_a = {
488     "Answer (A-bit) is SET",
489     "Answer (A-bit) is NOT set",
490 };
491 static const true_false_string tfs_v3_lls_state_options_n = {
492     "Incomplete (N-bit) is SET",
493     "Incomplete (N-bit) is NOT set",
494 };
495 static const true_false_string tfs_v3_lls_relay_options_a = {
496     "Always (A-bit) is SET",
497     "Always (A-bit) is NOT set",
498 };
499 static const true_false_string tfs_v3_lls_relay_options_n = {
500     "Never (N-bit) is SET",
501     "Never (N-bit) is NOT set",
502 };
503 static const true_false_string tfs_v2_router_lsa_flags_b = {
504     "Area border router",
505     "NO Area border router"
506 };
507 static const true_false_string tfs_v2_router_lsa_flags_e = {
508     "AS boundary router",
509     "NO AS boundary router"
510 };
511 static const true_false_string tfs_v2_router_lsa_flags_v = {
512     "Virtual link endpoint",
513     "NO Virtual link endpoint"
514 };
515 static const true_false_string tfs_v2_router_lsa_flags_w = {
516     "Wild-card multicast receiver",
517     "NO Wild-card multicast receiver"
518 };
519 static const true_false_string tfs_v2_router_lsa_flags_n = {
520     "N flag",
521     "NO N flag"
522 };
523 static const true_false_string tfs_v3_router_lsa_flags_b = {
524     "Area border router",
525     "NO Area border router"
526 };
527 static const true_false_string tfs_v3_router_lsa_flags_e = {
528     "AS boundary router",
529     "NO AS boundary router"
530 };
531 static const true_false_string tfs_v3_router_lsa_flags_v = {
532     "Virtual link endpoint",
533     "NO Virtual link endpoint"
534 };
535 static const true_false_string tfs_v3_router_lsa_flags_w = {
536     "Wild-card multicast receiver",
537     "NO Wild-card multicast receiver"
538 };
539 static const true_false_string tfs_v3_as_external_flags_t = {
540     "External Route Tag is included",
541     "External Route Tag is NOT included"
542 };
543 static const true_false_string tfs_v3_as_external_flags_f = {
544     "Forwarding Address is included",
545     "Forwarding Address is NOT included"
546 };
547 static const true_false_string tfs_v3_as_external_flags_e = {
548     "Type 2 external metric",
549     "Type 1 external metric"
550 };
551 static const true_false_string tfs_v3_prefix_options_nu = {
552     "NoUnicast capability bit is SET",
553     "NoUnicast capability bit is NOT set"
554 };
555 static const true_false_string tfs_v3_prefix_options_la = {
556     "LocalAddress capability bit is SET",
557     "LocalAddress capability bit is NOT set"
558 };
559 static const true_false_string tfs_v3_prefix_options_mc = {
560     "Multicast capability bit is SET",
561     "Multicast capability bit is NOT set"
562 };
563 static const true_false_string tfs_v3_prefix_options_p = {
564     "Propagate bit is SET",
565     "Propagate bit is NOT set"
566 };
567
568 /*-----------------------------------------------------------------------
569  * OSPF Filtering
570  *-----------------------------------------------------------------------*/
571
572 /* The OSPF filtering keys */
573 enum {
574
575     OSPFF_MSG_MIN,
576     OSPFF_MSG_HELLO,
577     OSPFF_MSG_DB_DESC,
578     OSPFF_MSG_LS_REQ,
579     OSPFF_MSG_LS_UPD,
580     OSPFF_MSG_LS_ACK,
581
582     OSPFF_LS_TYPE,
583     OSPFF_LS_OPAQUE_TYPE,
584
585     OSPFF_LS_MPLS_TE_INSTANCE,
586
587     OSPFF_LS_MIN,
588
589     OSPFF_LS_ROUTER,
590     OSPFF_LS_ROUTER_LINKTYPE,
591     OSPFF_LS_ROUTER_LINKID,
592     OSPFF_LS_ROUTER_LINKDATA,
593     OSPFF_LS_NETWORK,
594     OSPFF_LS_SUMMARY,
595     OSPFF_LS_ASBR,
596     OSPFF_LS_ASEXT,
597     OSPFF_LS_GRPMEMBER,
598     OSPFF_LS_ASEXT7,
599     OSPFF_LS_EXTATTR,
600     OSPFF_LS_OPAQUE,
601
602     OSPFF_V3_LS_TYPE,
603
604     OSPFF_V3_LS_MIN,
605     OSPFF_V3_LS_ROUTER,
606     OSPFF_V3_LS_NETWORK,
607     OSPFF_V3_LS_INTER_AREA_PREFIX,
608     OSPFF_V3_LS_INTER_AREA_ROUTER,
609     OSPFF_V3_LS_AS_EXTERNAL,
610     OSPFF_V3_LS_GROUP_MEMBERSHIP,
611     OSPFF_V3_LS_NSSA,
612     OSPFF_V3_LS_LINK,
613     OSPFF_V3_LS_INTRA_AREA_PREFIX,
614     OSPFF_V3_LS_OPAQUE_RI,
615
616     OSPFF_ADV_ROUTER,
617     OSPFF_LS_MPLS,
618     OSPFF_LS_MPLS_ROUTERID,
619
620     OSPFF_LS_MPLS_LINKTYPE,
621     OSPFF_LS_MPLS_LINKID,
622     OSPFF_LS_MPLS_LOCAL_ADDR,
623     OSPFF_LS_MPLS_REMOTE_ADDR,
624     OSPFF_LS_MPLS_LOCAL_IFID,
625     OSPFF_LS_MPLS_REMOTE_IFID,
626     OSPFF_LS_MPLS_LINKCOLOR,
627     OSPFF_LS_MPLS_BC_MODEL_ID,
628     OSPFF_LS_OIF_LOCAL_NODE_ID,
629     OSPFF_LS_OIF_REMOTE_NODE_ID,
630
631     OSPFF_V2_OPTIONS,
632     OSPFF_V2_OPTIONS_MT,
633     OSPFF_V2_OPTIONS_E,
634     OSPFF_V2_OPTIONS_MC,
635     OSPFF_V2_OPTIONS_NP,
636     OSPFF_V2_OPTIONS_L,
637     OSPFF_V2_OPTIONS_DC,
638     OSPFF_V2_OPTIONS_O,
639     OSPFF_V2_OPTIONS_DN,
640
641     /* OSPF Filtering keys for Router Informational Capabilities Options field. */
642     OSPFF_RI_OPTIONS,
643     OSPFF_RI_OPTIONS_GRC,
644     OSPFF_RI_OPTIONS_GRH,
645     OSPFF_RI_OPTIONS_SRS,
646     OSPFF_RI_OPTIONS_TES,
647     OSPFF_RI_OPTIONS_P2PLAN,
648     OSPFF_RI_OPTIONS_ETE,
649
650     /* OSPF Filtering keys for Dynamic Hostname support (RFC5642) */
651     OSPFF_DYN_HOSTNAME,
652     OSPFF_OPAQUE_LSA_MBZ,
653
654     OSPFF_UNKNOWN_TLV_TXT,
655
656     OSPFF_V3_OPTIONS,
657     OSPFF_V3_OPTIONS_V6,
658     OSPFF_V3_OPTIONS_E,
659     OSPFF_V3_OPTIONS_MC,
660     OSPFF_V3_OPTIONS_N,
661     OSPFF_V3_OPTIONS_R,
662     OSPFF_V3_OPTIONS_DC,
663     OSPFF_V3_OPTIONS_AF,
664     OSPFF_V3_OPTIONS_L,
665     OSPFF_V3_OPTIONS_AT,
666     OSPFF_DBD,
667     OSPFF_DBD_R,
668     OSPFF_DBD_I,
669     OSPFF_DBD_M,
670     OSPFF_DBD_MS,
671     OSPFF_LLS_EXT_OPTIONS_TLV,
672     OSPFF_LLS_EXT_OPTIONS,
673     OSPFF_LLS_EXT_OPTIONS_LR,
674     OSPFF_LLS_EXT_OPTIONS_RS,
675     OSPFF_V3_LLS_EXT_OPTIONS_TLV,
676     OSPFF_V3_LLS_EXT_OPTIONS,
677     OSPFF_V3_LLS_EXT_OPTIONS_LR,
678     OSPFF_V3_LLS_EXT_OPTIONS_RS,
679     OSPFF_V3_LLS_STATE_TLV,
680     OSPFF_V3_LLS_STATE_SCS,
681     OSPFF_V3_LLS_STATE_OPTIONS,
682     OSPFF_V3_LLS_STATE_OPTIONS_R,
683     OSPFF_V3_LLS_STATE_OPTIONS_A,
684     OSPFF_V3_LLS_STATE_OPTIONS_N,
685     OSPFF_V3_LLS_DROP_TLV,
686     OSPFF_V3_LLS_RELAY_TLV,
687     OSPFF_V3_LLS_RELAY_ADDED,
688     OSPFF_V3_LLS_RELAY_OPTIONS,
689     OSPFF_V3_LLS_RELAY_OPTIONS_A,
690     OSPFF_V3_LLS_RELAY_OPTIONS_N,
691     OSPFF_V3_LLS_WILLINGNESS_TLV,
692     OSPFF_V3_LLS_WILLINGNESS,
693     OSPFF_V3_LLS_RF_TLV,
694     OSPFF_V3_LLS_FSF_TLV,
695     OSPFF_V2_ROUTER_LSA_FLAG,
696     OSPFF_V2_ROUTER_LSA_FLAG_B,
697     OSPFF_V2_ROUTER_LSA_FLAG_E,
698     OSPFF_V2_ROUTER_LSA_FLAG_V,
699     OSPFF_V2_ROUTER_LSA_FLAG_W,
700     OSPFF_V2_ROUTER_LSA_FLAG_N,
701     OSPFF_V3_ROUTER_LSA_FLAG,
702     OSPFF_V3_ROUTER_LSA_FLAG_B,
703     OSPFF_V3_ROUTER_LSA_FLAG_E,
704     OSPFF_V3_ROUTER_LSA_FLAG_V,
705     OSPFF_V3_ROUTER_LSA_FLAG_W,
706     OSPFF_V3_AS_EXTERNAL_FLAG,
707     OSPFF_V3_AS_EXTERNAL_FLAG_T,
708     OSPFF_V3_AS_EXTERNAL_FLAG_F,
709     OSPFF_V3_AS_EXTERNAL_FLAG_E,
710     OSPFF_V3_PREFIX_OPTION,
711     OSPFF_V3_PREFIX_OPTION_NU,
712     OSPFF_V3_PREFIX_OPTION_LA,
713     OSPFF_V3_PREFIX_OPTION_MC,
714     OSPFF_V3_PREFIX_OPTION_P,
715
716     OSPFF_V2_GRACE_TLV,
717     OSPFF_V2_GRACE_PERIOD,
718     OSPFF_V2_GRACE_REASON,
719     OSPFF_V2_GRACE_IP,
720
721     OSPFF_MAX
722 };
723
724 static int hf_ospf_filter[OSPFF_MAX];
725 static int hf_ospf_header = -1;
726 static int hf_ospf_header_version = -1;
727 static int hf_ospf_header_msg_type = -1;
728 static int hf_ospf_header_packet_length = -1;
729 static int hf_ospf_header_src_router = -1;
730 static int hf_ospf_header_area_id = -1;
731 static int hf_ospf_header_checksum = -1;
732
733 /* Header OSPF v2 auth */
734 static int hf_ospf_header_auth_type = -1;
735 static int hf_ospf_header_auth_data_none = -1;
736 static int hf_ospf_header_auth_data_simple = -1;
737 static int hf_ospf_header_auth_crypt_key_id = -1;
738 static int hf_ospf_header_auth_crypt_data_length = -1;
739 static int hf_ospf_header_auth_crypt_seq_nbr = -1;
740 static int hf_ospf_header_auth_crypt_data = -1;
741 static int hf_ospf_header_auth_data_unknown = -1;
742
743 /* Header OSPF v3 */
744 static int hf_ospf_header_instance_id = -1;
745 static int hf_ospf_header_reserved = -1;
746
747 /* Hello */
748 static int hf_ospf_hello = -1;
749 static int hf_ospf_hello_network_mask = -1;
750 static int hf_ospf_hello_interface_id = -1;
751 static int hf_ospf_hello_hello_interval = -1;
752 static int hf_ospf_hello_router_priority = -1;
753 static int hf_ospf_hello_router_dead_interval = -1;
754 static int hf_ospf_hello_designated_router = -1;
755 static int hf_ospf_hello_backup_designated_router = -1;
756 static int hf_ospf_hello_active_neighbor = -1;
757
758 static gint ospf_msg_type_to_filter (guint8 msg_type)
759 {
760     if (msg_type >= OSPF_HELLO &&
761         msg_type <= OSPF_LS_ACK)
762         return msg_type + OSPFF_MSG_MIN;
763     return -1;
764 }
765
766 static gint ospf_ls_type_to_filter (guint8 ls_type)
767 {
768     if (ls_type >= OSPF_LSTYPE_ROUTER &&
769         ls_type <= OSPF_LSTYPE_EXTATTR)
770         return OSPFF_LS_MIN + ls_type;
771     else if (ls_type >= OSPF_LSTYPE_OP_LINKLOCAL &&
772              ls_type <= OSPF_LSTYPE_OP_ASWIDE)
773         return OSPFF_LS_OPAQUE;
774     else
775         return -1;
776 }
777
778 static gint ospf_v3_ls_type_to_filter (guint16 ls_type)
779 {
780     guint16 function_code;
781
782     function_code = ls_type & 0x1fff;
783     if (function_code >= OSPF_V3_LSA_FUNCTION_CODE_ROUTER &&
784         function_code <= OSPF_V3_LSA_FUNCTION_CODE_INTRA_AREA_PREFIX)
785         return OSPFF_V3_LS_MIN + function_code;
786     else if (function_code == OSPF_V3_LSA_FUNCTION_CODE_OPAQUE_RI)
787         return OSPFF_V3_LS_OPAQUE_RI;
788     else
789         return -1;
790 }
791
792 typedef struct _bitfield_info {
793     int         hfindex;
794     gint        *ett;
795     int         *idx;
796     int         num;
797 } bitfield_info;
798
799 static int bf_dbd[] = {
800     OSPFF_DBD_R,
801     OSPFF_DBD_I,
802     OSPFF_DBD_M,
803     OSPFF_DBD_MS
804 };
805 static int bf_lls_ext_options[] = {
806     OSPFF_LLS_EXT_OPTIONS_RS,
807     OSPFF_LLS_EXT_OPTIONS_LR
808 };
809 static int bf_v3_lls_ext_options[] = {
810     OSPFF_V3_LLS_EXT_OPTIONS_LR,
811     OSPFF_V3_LLS_EXT_OPTIONS_RS
812 };
813
814 static int bf_v3_lls_state_options[] = {
815     OSPFF_V3_LLS_STATE_OPTIONS_R,
816     OSPFF_V3_LLS_STATE_OPTIONS_A,
817     OSPFF_V3_LLS_STATE_OPTIONS_N
818 };
819 static int bf_v3_lls_relay_options[] = {
820     OSPFF_V3_LLS_RELAY_OPTIONS_A,
821     OSPFF_V3_LLS_RELAY_OPTIONS_N
822 };
823 static int bf_v2_router_lsa_flags[] = {
824     OSPFF_V2_ROUTER_LSA_FLAG_V,
825     OSPFF_V2_ROUTER_LSA_FLAG_E,
826     OSPFF_V2_ROUTER_LSA_FLAG_B
827 };
828 static int bf_v2_router_lsa_mt_flags[] = {
829     OSPFF_V2_ROUTER_LSA_FLAG_N,
830     OSPFF_V2_ROUTER_LSA_FLAG_W,
831     OSPFF_V2_ROUTER_LSA_FLAG_V,
832     OSPFF_V2_ROUTER_LSA_FLAG_E,
833     OSPFF_V2_ROUTER_LSA_FLAG_B
834 };
835 static int bf_v3_router_lsa_flags[] = {
836     OSPFF_V3_ROUTER_LSA_FLAG_W,
837     OSPFF_V3_ROUTER_LSA_FLAG_V,
838     OSPFF_V3_ROUTER_LSA_FLAG_E,
839     OSPFF_V3_ROUTER_LSA_FLAG_B
840 };
841 static int bf_v3_as_external_flags[] = {
842     OSPFF_V3_AS_EXTERNAL_FLAG_E,
843     OSPFF_V3_AS_EXTERNAL_FLAG_F,
844     OSPFF_V3_AS_EXTERNAL_FLAG_T
845 };
846 static int bf_v2_options[] = {
847     OSPFF_V2_OPTIONS_DN,
848     OSPFF_V2_OPTIONS_O,
849     OSPFF_V2_OPTIONS_DC,
850     OSPFF_V2_OPTIONS_L,
851     OSPFF_V2_OPTIONS_NP,
852     OSPFF_V2_OPTIONS_MC,
853     OSPFF_V2_OPTIONS_E,
854     OSPFF_V2_OPTIONS_MT
855 };
856 /* Structures for handling the bitfield of the Options field of Optional Router Capabilites LSA (RFC4970). */
857 static int bf_ri_options[] = {
858     OSPFF_RI_OPTIONS_GRC,
859     OSPFF_RI_OPTIONS_GRH,
860     OSPFF_RI_OPTIONS_SRS,
861     OSPFF_RI_OPTIONS_TES,
862     OSPFF_RI_OPTIONS_P2PLAN,
863     OSPFF_RI_OPTIONS_ETE
864 };
865 static int bf_v3_options[] = {
866     OSPFF_V3_OPTIONS_AT,
867     OSPFF_V3_OPTIONS_L,
868     OSPFF_V3_OPTIONS_AF,
869     OSPFF_V3_OPTIONS_DC,
870     OSPFF_V3_OPTIONS_R,
871     OSPFF_V3_OPTIONS_N,
872     OSPFF_V3_OPTIONS_MC,
873     OSPFF_V3_OPTIONS_E,
874     OSPFF_V3_OPTIONS_V6
875 };
876 static int bf_v3_prefix_options[] = {
877     OSPFF_V3_PREFIX_OPTION_P,
878     OSPFF_V3_PREFIX_OPTION_MC,
879     OSPFF_V3_PREFIX_OPTION_LA,
880     OSPFF_V3_PREFIX_OPTION_NU
881 };
882
883 static bitfield_info bfinfo_dbd = {
884     OSPFF_DBD, &ett_ospf_dbd,
885     bf_dbd, array_length(bf_dbd)
886 };
887 static bitfield_info bfinfo_lls_ext_options = {
888     OSPFF_LLS_EXT_OPTIONS, &ett_ospf_lls_ext_options,
889     bf_lls_ext_options, array_length(bf_lls_ext_options)
890 };
891 static bitfield_info bfinfo_v3_lls_ext_options = {
892     OSPFF_V3_LLS_EXT_OPTIONS, &ett_ospf_v3_lls_ext_options,
893     bf_v3_lls_ext_options, array_length(bf_v3_lls_ext_options)
894 };
895 static bitfield_info bfinfo_v3_lls_state_options = {
896     OSPFF_V3_LLS_STATE_OPTIONS, &ett_ospf_v3_lls_state_options,
897     bf_v3_lls_state_options, array_length(bf_v3_lls_state_options)
898 };
899 static bitfield_info bfinfo_v3_lls_relay_options = {
900     OSPFF_V3_LLS_RELAY_OPTIONS, &ett_ospf_v3_lls_relay_options,
901     bf_v3_lls_relay_options, array_length(bf_v3_lls_relay_options)
902 };
903 static bitfield_info bfinfo_v2_router_lsa_flags = {
904     OSPFF_V2_ROUTER_LSA_FLAG, &ett_ospf_v2_router_lsa_flags,
905     bf_v2_router_lsa_flags, array_length(bf_v2_router_lsa_flags)
906 };
907 static bitfield_info bfinfo_v2_router_lsa_mt_flags = {
908     OSPFF_V2_ROUTER_LSA_FLAG, &ett_ospf_v2_router_lsa_flags,
909     bf_v2_router_lsa_mt_flags, array_length(bf_v2_router_lsa_mt_flags)
910 };
911 static bitfield_info bfinfo_v3_router_lsa_flags = {
912     OSPFF_V3_ROUTER_LSA_FLAG, &ett_ospf_v3_router_lsa_flags,
913     bf_v3_router_lsa_flags, array_length(bf_v3_router_lsa_flags)
914 };
915 static bitfield_info bfinfo_v3_as_external_flags = {
916     OSPFF_V3_AS_EXTERNAL_FLAG, &ett_ospf_v3_as_external_flags,
917     bf_v3_as_external_flags, array_length(bf_v3_as_external_flags)
918 };
919 static bitfield_info bfinfo_v2_options = {
920     OSPFF_V2_OPTIONS, &ett_ospf_v2_options,
921     bf_v2_options, array_length(bf_v2_options)
922 };
923 static bitfield_info bfinfo_v3_options = {
924     OSPFF_V3_OPTIONS, &ett_ospf_v3_options,
925     bf_v3_options, array_length(bf_v3_options)
926 };
927 static bitfield_info bfinfo_v3_prefix_options = {
928     OSPFF_V3_PREFIX_OPTION, &ett_ospf_v3_prefix_options,
929     bf_v3_prefix_options, array_length(bf_v3_prefix_options)
930 };
931 /* Structure used for dissecing the Options bitfield of the Optional Router Informational
932    Capabilities RI LSA. */
933 static bitfield_info bfinfo_ri_options = {
934     OSPFF_RI_OPTIONS, &ett_ospf_ri_options,
935     bf_ri_options, array_length(bf_ri_options)
936 };
937
938 #define MAX_OPTIONS_LEN 128
939 static void
940 dissect_ospf_bitfield (proto_tree *parent_tree, tvbuff_t *tvb, int offset,
941                         bitfield_info *bfinfo)
942 {
943     proto_item *item = NULL;
944     proto_tree *tree = NULL;
945     guint32 flags;
946     char *str;
947     gint length, pos;
948     gint i;
949     header_field_info *hfinfo;
950     int hfindex, idx;
951     gint returned_length;
952
953     hfindex = hf_ospf_filter[bfinfo->hfindex];
954     hfinfo = proto_registrar_get_nth(hfindex);
955     switch (hfinfo->type) {
956     case FT_UINT8:
957         flags = tvb_get_guint8(tvb, offset);
958         length = 1;
959         break;
960     case FT_UINT16:
961         flags = tvb_get_ntohs(tvb, offset);
962         length = 2;
963         break;
964     case FT_UINT24:
965         flags = tvb_get_ntoh24(tvb, offset);
966         length = 3;
967         break;
968     case FT_UINT32:
969         flags = tvb_get_ntohl(tvb, offset);
970         length = 4;
971         break;
972     default:
973         return;
974     }
975
976     if (parent_tree) {
977         item = proto_tree_add_uint(parent_tree, hfindex, tvb, offset, length, flags);
978         tree = proto_item_add_subtree(item, *bfinfo->ett);
979
980         str = (char *)wmem_alloc(wmem_packet_scope(), MAX_OPTIONS_LEN);
981         str[0] = 0;
982         for (i = 0, pos = 0; i < bfinfo->num; i++) {
983             idx = hf_ospf_filter[bfinfo->idx[i]];
984             hfinfo = proto_registrar_get_nth(idx);
985             if (flags & hfinfo->bitmask) {
986                 returned_length = g_snprintf(&str[pos], MAX_OPTIONS_LEN-pos, "%s%s",
987                                   pos ? ", " : "",
988                                   hfinfo->name);
989                 pos += MIN(returned_length, MAX_OPTIONS_LEN-pos);
990             }
991             proto_tree_add_boolean(tree, idx, tvb, offset, length, flags);
992         }
993         if (str[0]) {
994             proto_item_append_text(item, " (%s)", str);
995         }
996     }
997 }
998
999 static dissector_handle_t data_handle;
1000
1001 static void dissect_ospf_hello(tvbuff_t*, int, proto_tree*, guint8, guint16);
1002 static void dissect_ospf_db_desc(tvbuff_t*, int, proto_tree*, guint8, guint16, guint8);
1003 static void dissect_ospf_ls_req(tvbuff_t*, int, proto_tree*, guint8, guint16);
1004 static void dissect_ospf_ls_upd(tvbuff_t*, int, proto_tree*, guint8, guint16, guint8);
1005 static void dissect_ospf_ls_ack(tvbuff_t*, int, proto_tree*, guint8, guint16, guint8);
1006 static void dissect_ospf_lls_data_block(tvbuff_t*, int, proto_tree*, guint8);
1007
1008 /* dissect_ospf_v[23]lsa returns the offset of the next LSA
1009  * if disassemble_body is set to FALSE (e.g. in LSA ACK
1010  * packets), the offset is set to the offset of the next
1011  * LSA header
1012  */
1013 static int dissect_ospf_v2_lsa(tvbuff_t*, int, proto_tree*, gboolean disassemble_body);
1014 static int dissect_ospf_v3_lsa(tvbuff_t*, int, proto_tree*, gboolean disassemble_body,
1015                                guint8);
1016
1017 static void dissect_ospf_v3_address_prefix(tvbuff_t *, int, int, proto_tree *, guint8);
1018
1019 static int
1020 ospf_has_lls_block(tvbuff_t *tvb, int offset, guint8 packet_type, guint8 version)
1021 {
1022     guint8 flags;
1023     guint32 v3flags;
1024
1025     /* LLS block can be found only in HELLO and DBDESC packets */
1026     switch (packet_type) {
1027     case OSPF_HELLO:
1028         switch (version) {
1029         case OSPF_VERSION_2:
1030             flags = tvb_get_guint8 (tvb, offset + 6);
1031             return flags & OSPF_V2_OPTIONS_L;
1032         case OSPF_VERSION_3:
1033             v3flags = tvb_get_ntohl(tvb, offset + 5);
1034             v3flags = v3flags >> 8;
1035             return v3flags & OSPF_V3_OPTIONS_L;
1036         }
1037         break;
1038     case OSPF_DB_DESC:
1039         switch (version) {
1040         case OSPF_VERSION_2:
1041             flags = tvb_get_guint8 (tvb, offset + 2);
1042             return flags & OSPF_V2_OPTIONS_L;
1043         case OSPF_VERSION_3:
1044             v3flags = tvb_get_ntohl(tvb, offset + 1);
1045             v3flags = v3flags >> 8;
1046             return v3flags & OSPF_V3_OPTIONS_L;
1047         }
1048         break;
1049     }
1050
1051     return 0;
1052 }
1053
1054 static void
1055 dissect_ospf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1056 {
1057     proto_tree *ospf_tree = NULL;
1058     proto_item *ti, *ti_sum, *hidden_item;
1059     proto_tree *ospf_header_tree;
1060     guint8  version;
1061     guint8  packet_type;
1062     guint16 ospflen;
1063     vec_t cksum_vec[4];
1064     int cksum_vec_len;
1065     guint32 phdr[2];
1066     guint16 cksum, computed_cksum;
1067     guint length, reported_length;
1068     guint16 auth_type;
1069     int crypto_len = 0;
1070     unsigned int ospf_header_length;
1071     guint8 instance_id;
1072     guint32 areaid;
1073     guint8  address_family = OSPF_AF_6;
1074
1075     col_set_str(pinfo->cinfo, COL_PROTOCOL, "OSPF");
1076     col_clear(pinfo->cinfo, COL_INFO);
1077
1078     version = tvb_get_guint8(tvb, 0);
1079     switch (version) {
1080     case OSPF_VERSION_2:
1081         ospf_header_length = OSPF_VERSION_2_HEADER_LENGTH;
1082         break;
1083     case OSPF_VERSION_3:
1084         ospf_header_length = OSPF_VERSION_3_HEADER_LENGTH;
1085         break;
1086     default:
1087         ospf_header_length = 14;
1088         break;
1089     }
1090
1091     packet_type = tvb_get_guint8(tvb, 1);
1092     col_add_str(pinfo->cinfo, COL_INFO,
1093                 val_to_str(packet_type, pt_vals, "Unknown (%u)"));
1094
1095     ospflen = tvb_get_ntohs(tvb, 2);
1096
1097     ti = proto_tree_add_item(tree, proto_ospf, tvb, 0, -1, ENC_NA);
1098     ospf_tree = proto_item_add_subtree(ti, ett_ospf);
1099
1100
1101     ti = proto_tree_add_item(ospf_tree, hf_ospf_header, tvb, 0, ospf_header_length, ENC_NA);
1102     ospf_header_tree = proto_item_add_subtree(ti, ett_ospf_hdr);
1103
1104     proto_tree_add_item(ospf_header_tree, hf_ospf_header_version, tvb, 0, 1, ENC_NA);
1105     proto_tree_add_item(ospf_header_tree, hf_ospf_header_msg_type, tvb, 1, 1, ENC_BIG_ENDIAN);
1106
1107     if (ospf_msg_type_to_filter(packet_type) != -1) {
1108         hidden_item = proto_tree_add_item(ospf_header_tree,
1109                                           hf_ospf_filter[ospf_msg_type_to_filter(packet_type)],
1110                                           tvb, 1, 1, ENC_BIG_ENDIAN);
1111         PROTO_ITEM_SET_HIDDEN(hidden_item);
1112     }
1113     proto_tree_add_item(ospf_header_tree, hf_ospf_header_packet_length, tvb, 2, 2, ENC_BIG_ENDIAN);
1114     proto_tree_add_item(ospf_header_tree, hf_ospf_header_src_router, tvb, 4, 4, ENC_BIG_ENDIAN);
1115
1116
1117     ti = proto_tree_add_item(ospf_header_tree, hf_ospf_header_area_id, tvb, 8, 4, ENC_BIG_ENDIAN);
1118     areaid = tvb_get_ntohl(tvb,8);
1119     if(areaid == 0){
1120         proto_item_append_text(ti, " (Backbone)");
1121     }
1122
1123     ti_sum = proto_tree_add_item(ospf_header_tree, hf_ospf_header_checksum, tvb, 12, 2, ENC_BIG_ENDIAN);
1124     cksum = tvb_get_ntohs(tvb, 12);
1125     if(cksum == 0){
1126         proto_item_append_text(ti_sum, " (None)");
1127     }
1128
1129     /* Quit at this point if it's an unknown OSPF version. */
1130     if(version != OSPF_VERSION_2 && version != OSPF_VERSION_3) {
1131         return;
1132     }
1133
1134     length = tvb_length(tvb);
1135     /* XXX - include only the length from the OSPF header? */
1136     reported_length = tvb_reported_length(tvb);
1137     if (cksum !=0 && !pinfo->fragmented && length >= reported_length
1138                && length >= ospf_header_length) {
1139         /* The packet isn't part of a fragmented datagram and isn't
1140            truncated, so we can checksum it. */
1141
1142         switch (version) {
1143
1144         case OSPF_VERSION_2:
1145             /* Header, not including the authentication data (the OSPFv2
1146                checksum excludes the 64-bit authentication field). */
1147             cksum_vec[0].ptr = tvb_get_ptr(tvb, 0, 16);
1148             cksum_vec[0].len = 16;
1149             if (length > ospf_header_length) {
1150                 /* Rest of the packet, again not including the
1151                    authentication data. */
1152                 reported_length -= ospf_header_length;
1153                 cksum_vec[1].ptr = tvb_get_ptr(tvb, ospf_header_length, reported_length);
1154                 cksum_vec[1].len = reported_length;
1155                 cksum_vec_len = 2;
1156             } else {
1157                 /* There's nothing but a header. */
1158                 cksum_vec_len = 1;
1159             }
1160             break;
1161
1162         case OSPF_VERSION_3:
1163             /* IPv6-style checksum, covering the entire OSPF packet
1164                and a prepended IPv6 pseudo-header. */
1165
1166             /* Set up the fields of the pseudo-header. */
1167             cksum_vec[0].ptr = (const guint8 *)pinfo->src.data;
1168             cksum_vec[0].len = pinfo->src.len;
1169             cksum_vec[1].ptr = (const guint8 *)pinfo->dst.data;
1170             cksum_vec[1].len = pinfo->dst.len;
1171             cksum_vec[2].ptr = (const guint8 *)&phdr;
1172             phdr[0] = g_htonl(ospflen);
1173             phdr[1] = g_htonl(IP_PROTO_OSPF);
1174             cksum_vec[2].len = 8;
1175
1176             cksum_vec[3].ptr = tvb_get_ptr(tvb, 0, reported_length);
1177             cksum_vec[3].len = reported_length;
1178             cksum_vec_len = 4;
1179             break;
1180
1181         default:
1182             DISSECTOR_ASSERT_NOT_REACHED();
1183             break;
1184         }
1185         computed_cksum = in_cksum(cksum_vec, cksum_vec_len);
1186         if (computed_cksum == 0) {
1187             proto_item_append_text(ti_sum, " [correct]");
1188         } else {
1189             proto_item_append_text(ti_sum, " [incorrect, should be 0x%04x]", in_cksum_shouldbe(cksum, computed_cksum));
1190         }
1191     }
1192
1193     switch (version) {
1194
1195     case OSPF_VERSION_2:
1196         /* Authentication is only valid for OSPFv2 */
1197         proto_tree_add_item(ospf_header_tree, hf_ospf_header_auth_type, tvb, 14, 2, ENC_NA);
1198         auth_type = tvb_get_ntohs(tvb, 14);
1199         switch (auth_type) {
1200         case OSPF_AUTH_NONE:
1201             proto_tree_add_item(ospf_header_tree, hf_ospf_header_auth_data_none, tvb, 16, 8, ENC_NA);
1202             break;
1203
1204         case OSPF_AUTH_SIMPLE:
1205             proto_tree_add_item(ospf_header_tree, hf_ospf_header_auth_data_simple, tvb, 16, 8, ENC_ASCII|ENC_NA);
1206             break;
1207
1208         case OSPF_AUTH_CRYPT:
1209             proto_tree_add_item(ospf_header_tree, hf_ospf_header_auth_crypt_key_id, tvb, 18, 1, ENC_NA);
1210
1211             proto_tree_add_item(ospf_header_tree, hf_ospf_header_auth_crypt_data_length, tvb, 19, 1, ENC_NA);
1212             crypto_len = tvb_get_guint8(tvb, 19);
1213
1214             proto_tree_add_item(ospf_header_tree, hf_ospf_header_auth_crypt_seq_nbr, tvb, 20, 4, ENC_BIG_ENDIAN);
1215                /* Show the message digest that was appended to the end of the
1216                OSPF message - but only if it's present (we don't want
1217                to get an exception before we've tried dissecting OSPF
1218                message). */
1219             if (tvb_bytes_exist(tvb, ospflen, crypto_len)) {
1220                 proto_tree_add_item(ospf_header_tree, hf_ospf_header_auth_crypt_data, tvb, ospflen, crypto_len, ENC_NA);
1221                 proto_tree_set_appendix(ospf_header_tree, tvb, ospflen, crypto_len);
1222             }
1223             break;
1224
1225         default:
1226             proto_tree_add_item(ospf_header_tree, hf_ospf_header_auth_data_unknown, tvb, 16, 8, ENC_NA);
1227             break;
1228         }
1229         break;
1230
1231     case OSPF_VERSION_3:
1232         /* Instance ID and "reserved" is OSPFv3-only */
1233         ti = proto_tree_add_item(ospf_header_tree, hf_ospf_header_instance_id, tvb, 14, 1, ENC_NA);
1234         instance_id = tvb_get_guint8(tvb, 14);
1235         /* By default set address_family to OSPF_AF_6 */
1236         address_family = OSPF_AF_6;
1237         if(instance_id > 65 && instance_id < 128) {
1238             address_family = OSPF_AF_4;
1239         }
1240
1241         ti = proto_tree_add_item(ospf_header_tree, hf_ospf_header_reserved, tvb, 15, 1, ENC_NA);
1242         if(tvb_get_guint8(tvb, 15)){
1243             proto_item_append_text(ti, " [incorrect, should be 0]");
1244         }
1245         break;
1246
1247     default:
1248         DISSECTOR_ASSERT_NOT_REACHED();
1249         break;
1250     }
1251
1252     switch (packet_type){
1253
1254     case OSPF_HELLO:
1255         dissect_ospf_hello(tvb, ospf_header_length, ospf_tree, version,
1256                            (guint16)(ospflen - ospf_header_length));
1257         break;
1258
1259     case OSPF_DB_DESC:
1260         dissect_ospf_db_desc(tvb, (int)ospf_header_length, ospf_tree, version,
1261                              (guint16)(ospflen - ospf_header_length),
1262                                  address_family);
1263         break;
1264
1265     case OSPF_LS_REQ:
1266         dissect_ospf_ls_req(tvb, (int)ospf_header_length, ospf_tree, version,
1267                             (guint16)(ospflen - ospf_header_length));
1268         break;
1269
1270     case OSPF_LS_UPD:
1271         dissect_ospf_ls_upd(tvb, (int)ospf_header_length, ospf_tree, version,
1272                             (guint16)(ospflen - ospf_header_length),
1273                             address_family);
1274         break;
1275
1276     case OSPF_LS_ACK:
1277         dissect_ospf_ls_ack(tvb, (int)ospf_header_length, ospf_tree, version,
1278                             (guint16)(ospflen - ospf_header_length),
1279                             address_family);
1280         break;
1281
1282     default:
1283         call_dissector(data_handle,
1284                        tvb_new_subset_remaining(tvb, ospf_header_length), pinfo, tree);
1285         break;
1286     }
1287
1288     /* take care of the LLS data block */
1289     if (ospf_has_lls_block(tvb, ospf_header_length, packet_type, version)) {
1290         dissect_ospf_lls_data_block(tvb, ospflen + crypto_len, ospf_tree,
1291                                     version);
1292     }
1293
1294 }
1295
1296 static int
1297 dissect_ospfv2_lls_tlv(tvbuff_t *tvb, int offset, proto_tree *tree)
1298 {
1299     proto_item *ti;
1300     proto_tree *ospf_lls_tlv_tree;
1301     guint16 type;
1302     guint16 length;
1303
1304     type = tvb_get_ntohs(tvb, offset);
1305     length = tvb_get_ntohs(tvb, offset + 2);
1306
1307     ti = proto_tree_add_text(tree, tvb, offset, length + 4, "%s",
1308                              val_to_str_const(type, lls_tlv_type_vals, "Unknown TLV"));
1309     ospf_lls_tlv_tree = proto_item_add_subtree(ti, ett_ospf_lls_tlv);
1310
1311     proto_tree_add_text(ospf_lls_tlv_tree, tvb, offset, 2,
1312                         "Type: %d", type);
1313     proto_tree_add_text(ospf_lls_tlv_tree, tvb, offset + 2, 2,
1314                         "Length: %d", length);
1315
1316     switch(type) {
1317     case 1:
1318         dissect_ospf_bitfield(ospf_lls_tlv_tree, tvb, offset + 4, &bfinfo_lls_ext_options);
1319         break;
1320     case 2:
1321         proto_tree_add_text(ospf_lls_tlv_tree, tvb, offset + 4, 4,
1322                             "Sequence number 0x%08x",
1323                             tvb_get_ntohl(tvb, offset + 4));
1324         proto_tree_add_text(ospf_lls_tlv_tree, tvb, offset + 8, length - 4,
1325                             "Auth Data: %s",
1326                             tvb_bytes_to_ep_str(tvb, offset + 8, length - 4));
1327         break;
1328     }
1329
1330     return offset + length + 4;
1331 }
1332
1333 static int
1334 dissect_ospfv3_lls_tlv(tvbuff_t *tvb, int offset, proto_tree *tree)
1335 {
1336     proto_item *ti;
1337     proto_tree *ospf_lls_tlv_tree;
1338     guint16 type;
1339     guint16 length;
1340     guint8 relays_added;
1341     int orig_offset;
1342
1343     type = tvb_get_ntohs(tvb, offset);
1344     length = tvb_get_ntohs(tvb, offset + 2);
1345
1346     switch(type) {
1347     case LLS_V3_EXT_OPT:
1348         ti = proto_tree_add_item(tree, hf_ospf_filter[OSPFF_V3_LLS_EXT_OPTIONS_TLV], tvb,
1349                                  offset, length + 4, ENC_NA);
1350        break;
1351     case LLS_V3_STATE_CHECK:
1352         ti = proto_tree_add_item(tree, hf_ospf_filter[OSPFF_V3_LLS_STATE_TLV], tvb,
1353                                  offset, length + 4, ENC_NA);
1354         break;
1355     case LLS_V3_NBR_DROP:
1356         ti = proto_tree_add_item(tree, hf_ospf_filter[OSPFF_V3_LLS_DROP_TLV], tvb,
1357                                  offset, length + 4, ENC_NA);
1358         break;
1359     case LLS_V3_RELAYS:
1360         ti = proto_tree_add_item(tree, hf_ospf_filter[OSPFF_V3_LLS_RELAY_TLV], tvb,
1361                                  offset, length + 4, ENC_NA);
1362         break;
1363     case LLS_V3_WILLING:
1364         ti = proto_tree_add_item(tree, hf_ospf_filter[OSPFF_V3_LLS_WILLINGNESS_TLV], tvb,
1365                                  offset, length + 4, ENC_NA);
1366         break;
1367     case LLS_V3_RQST_FROM:
1368          ti = proto_tree_add_item(tree, hf_ospf_filter[OSPFF_V3_LLS_RF_TLV], tvb,
1369                                   offset, length + 4, ENC_NA);
1370          break;
1371     case LLS_V3_FULL_STATE:
1372         ti = proto_tree_add_item(tree, hf_ospf_filter[OSPFF_V3_LLS_FSF_TLV], tvb,
1373                                  offset, length + 4, ENC_NA);
1374         break;
1375     default:
1376         ti = proto_tree_add_text(tree, tvb, offset, length + 4, "%s",
1377                                  val_to_str_const(type, lls_v3_tlv_type_vals, "Unknown TLV"));
1378     }
1379
1380     ospf_lls_tlv_tree = proto_item_add_subtree(ti, ett_ospf_lls_tlv);
1381     proto_tree_add_text(ospf_lls_tlv_tree, tvb, offset, 2,
1382                         "Type: %d", type);
1383     proto_tree_add_text(ospf_lls_tlv_tree, tvb, offset + 2, 2,
1384                         "Length: %d", length);
1385
1386     orig_offset = offset;
1387
1388     switch (type) {
1389     case LLS_V3_EXT_OPT:
1390         proto_tree_add_text(ospf_lls_tlv_tree, tvb, offset + 4, 4,
1391                             "Extended Options: 0x%08x",
1392                             tvb_get_ntohl(tvb, offset + 4));
1393
1394         dissect_ospf_bitfield(ospf_lls_tlv_tree, tvb, offset + 4, &bfinfo_v3_lls_ext_options);
1395         break;
1396     case LLS_V3_STATE_CHECK:
1397         proto_tree_add_item(ospf_lls_tlv_tree, hf_ospf_filter[OSPFF_V3_LLS_STATE_SCS],
1398                             tvb, offset+4, 2, ENC_BIG_ENDIAN);
1399
1400         dissect_ospf_bitfield(ospf_lls_tlv_tree, tvb, offset + 6,
1401                               &bfinfo_v3_lls_state_options);
1402         break;
1403     case LLS_V3_NBR_DROP:
1404         offset += 4;
1405         while (orig_offset + length >= offset) {
1406             proto_tree_add_text(ospf_lls_tlv_tree, tvb, offset, 4,
1407                                 "Dropped Neighbor: %s",
1408                                 tvb_ip_to_str(tvb, offset));
1409             offset += 4;
1410         }
1411         offset = orig_offset;
1412         break;
1413     case LLS_V3_RELAYS:
1414         relays_added = tvb_get_guint8(tvb, offset+4);
1415         proto_tree_add_item(ospf_lls_tlv_tree, hf_ospf_filter[OSPFF_V3_LLS_RELAY_ADDED],
1416                             tvb, offset+4, 1, ENC_BIG_ENDIAN);
1417         dissect_ospf_bitfield(ospf_lls_tlv_tree, tvb, offset + 5,
1418                               &bfinfo_v3_lls_relay_options);
1419         offset += 8;
1420         while (orig_offset + length >= offset) {
1421             ti = proto_tree_add_text(ospf_lls_tlv_tree, tvb, offset, 4,
1422                                 "Neighbor: %s",
1423                                 tvb_ip_to_str(tvb, offset));
1424             if (relays_added > 0) {
1425                 proto_item_append_text(ti, " Added");
1426             } else {
1427                 proto_item_append_text(ti, " Deleted");
1428             }
1429
1430             relays_added--;
1431             offset += 4;
1432         }
1433         break;
1434     case LLS_V3_WILLING:
1435         proto_tree_add_item(ospf_lls_tlv_tree, hf_ospf_filter[OSPFF_V3_LLS_WILLINGNESS],
1436                             tvb, offset+4, 1, ENC_BIG_ENDIAN);
1437
1438         break;
1439     case LLS_V3_RQST_FROM:
1440         offset += 4;
1441         while (orig_offset + length >= offset) {
1442             proto_tree_add_text(ospf_lls_tlv_tree, tvb, offset, 4,
1443                                 "Request From: %s",
1444                                 tvb_ip_to_str(tvb, offset));
1445             offset += 4;
1446         }
1447         offset = orig_offset;
1448         break;
1449     case LLS_V3_FULL_STATE:
1450            offset += 4;
1451         while (orig_offset + length >= offset) {
1452             proto_tree_add_text(ospf_lls_tlv_tree, tvb, offset, 4,
1453                                 "Full State For: %s",
1454                                 tvb_ip_to_str(tvb, offset));
1455             offset += 4;
1456         }
1457         offset = orig_offset;
1458         break;
1459     }
1460
1461     return offset + length + 4;
1462 }
1463
1464
1465 static void
1466 dissect_ospf_lls_data_block(tvbuff_t *tvb, int offset, proto_tree *tree,
1467                             guint8 version)
1468 {
1469     proto_tree *ospf_lls_data_block_tree;
1470     proto_item *ti;
1471     guint16 ospf_lls_len;
1472     int orig_offset = offset;
1473
1474     ospf_lls_len = tvb_get_ntohs(tvb, offset + 2);
1475     ti = proto_tree_add_text(tree, tvb, offset, -1, "OSPF LLS Data Block");
1476     ospf_lls_data_block_tree = proto_item_add_subtree(ti,
1477                                                       ett_ospf_lls_data_block);
1478
1479     /* TODO: verify checksum */
1480     proto_tree_add_text(ospf_lls_data_block_tree, tvb, offset, 2,
1481                         "Checksum: 0x%04x", tvb_get_ntohs(tvb, offset));
1482     proto_tree_add_text(ospf_lls_data_block_tree, tvb, offset + 2, 2,
1483                         "LLS Data Length: %d bytes", ospf_lls_len * 4);
1484
1485     offset += 4;
1486     DISSECTOR_ASSERT((version == OSPF_VERSION_2) || (version == OSPF_VERSION_3));
1487     while (orig_offset + ospf_lls_len * 4 > offset) {
1488         if (version == OSPF_VERSION_2)
1489             offset = dissect_ospfv2_lls_tlv (tvb, offset, ospf_lls_data_block_tree);
1490         else
1491             offset = dissect_ospfv3_lls_tlv (tvb, offset, ospf_lls_data_block_tree);
1492     }
1493 }
1494
1495 static void
1496 dissect_ospf_hello(tvbuff_t *tvb, int offset, proto_tree *tree, guint8 version,
1497                    guint16 length)
1498 {
1499     proto_tree *ospf_hello_tree;
1500     proto_item *ti;
1501     int orig_offset = offset;
1502
1503     ti = proto_tree_add_item(tree, hf_ospf_hello, tvb, offset, length, ENC_NA);
1504     ospf_hello_tree = proto_item_add_subtree(ti, ett_ospf_hello);
1505
1506     switch (version) {
1507     case OSPF_VERSION_2:
1508         proto_tree_add_item(ospf_hello_tree, hf_ospf_hello_network_mask, tvb, offset, 4, ENC_NA);
1509         proto_tree_add_item(ospf_hello_tree, hf_ospf_hello_hello_interval, tvb, offset + 4, 2, ENC_BIG_ENDIAN);
1510         dissect_ospf_bitfield(ospf_hello_tree, tvb, offset + 6, &bfinfo_v2_options);
1511         proto_tree_add_item(ospf_hello_tree, hf_ospf_hello_router_priority, tvb, offset + 7, 1, ENC_NA);
1512         proto_tree_add_item(ospf_hello_tree, hf_ospf_hello_router_dead_interval, tvb, offset + 8, 4, ENC_BIG_ENDIAN);
1513         proto_tree_add_item(ospf_hello_tree, hf_ospf_hello_designated_router, tvb, offset + 12, 4, ENC_NA);
1514         proto_tree_add_item(ospf_hello_tree, hf_ospf_hello_backup_designated_router, tvb, offset + 16, 4, ENC_NA);
1515         offset += 20;
1516
1517         while (orig_offset + length > offset) {
1518             proto_tree_add_item(ospf_hello_tree, hf_ospf_hello_active_neighbor, tvb, offset, 4, ENC_NA);
1519             offset += 4;
1520         }
1521         break;
1522     case OSPF_VERSION_3:
1523         proto_tree_add_item(ospf_hello_tree, hf_ospf_hello_interface_id, tvb, offset, 4, ENC_BIG_ENDIAN);
1524         proto_tree_add_item(ospf_hello_tree, hf_ospf_hello_router_priority, tvb, offset + 4, 1, ENC_NA);
1525         dissect_ospf_bitfield(ospf_hello_tree, tvb, offset + 5, &bfinfo_v3_options);
1526         proto_tree_add_item(ospf_hello_tree, hf_ospf_hello_hello_interval, tvb, offset + 8, 2, ENC_BIG_ENDIAN);
1527         proto_tree_add_item(ospf_hello_tree, hf_ospf_hello_router_dead_interval, tvb, offset + 10, 2, ENC_BIG_ENDIAN);
1528         proto_tree_add_item(ospf_hello_tree, hf_ospf_hello_designated_router, tvb, offset + 12, 4, ENC_NA);
1529         proto_tree_add_item(ospf_hello_tree, hf_ospf_hello_backup_designated_router, tvb, offset + 16, 4, ENC_NA);
1530         offset += 20;
1531
1532         while (orig_offset + length > offset) {
1533             proto_tree_add_item(ospf_hello_tree, hf_ospf_hello_active_neighbor, tvb, offset, 4, ENC_NA);
1534             offset += 4;
1535         }
1536         break;
1537     }
1538 }
1539
1540 static void
1541 dissect_ospf_db_desc(tvbuff_t *tvb, int offset, proto_tree *tree,
1542                      guint8 version, guint16 length, guint8 address_family)
1543 {
1544     proto_tree *ospf_db_desc_tree=NULL;
1545     proto_item *ti;
1546     guint8 reserved;
1547     int orig_offset = offset;
1548
1549     if (tree) {
1550         ti = proto_tree_add_text(tree, tvb, offset, length, "OSPF DB Description");
1551         ospf_db_desc_tree = proto_item_add_subtree(ti, ett_ospf_desc);
1552
1553         switch (version ) {
1554
1555         case OSPF_VERSION_2:
1556             proto_tree_add_text(ospf_db_desc_tree, tvb, offset, 2, "Interface MTU: %u",
1557                                 tvb_get_ntohs(tvb, offset));
1558
1559             dissect_ospf_bitfield(ospf_db_desc_tree, tvb, offset + 2, &bfinfo_v2_options);
1560             dissect_ospf_bitfield(ospf_db_desc_tree, tvb, offset + 3, &bfinfo_dbd);
1561
1562             proto_tree_add_text(ospf_db_desc_tree, tvb, offset + 4, 4, "DD Sequence: %u",
1563                                 tvb_get_ntohl(tvb, offset + 4));
1564
1565             offset += 8;
1566             break;
1567
1568         case OSPF_VERSION_3:
1569
1570             reserved = tvb_get_guint8(tvb, offset);
1571             proto_tree_add_text(ospf_db_desc_tree, tvb, offset, 1,
1572                                 (reserved == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),
1573                                 reserved);
1574
1575             dissect_ospf_bitfield(ospf_db_desc_tree, tvb, offset + 1, &bfinfo_v3_options);
1576
1577             proto_tree_add_text(ospf_db_desc_tree, tvb, offset + 4, 2, "Interface MTU: %u",
1578                                 tvb_get_ntohs(tvb, offset+4));
1579
1580             reserved = tvb_get_guint8(tvb, offset + 6);
1581             proto_tree_add_text(ospf_db_desc_tree, tvb, offset + 6, 1,
1582                                 (reserved == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),
1583                                 reserved);
1584
1585             dissect_ospf_bitfield(ospf_db_desc_tree, tvb, offset + 7, &bfinfo_dbd);
1586
1587             proto_tree_add_text(ospf_db_desc_tree, tvb, offset + 8, 4, "DD Sequence: %u",
1588                                 tvb_get_ntohl(tvb, offset + 8));
1589
1590             offset += 12;
1591             break;
1592         }
1593     }
1594
1595     /* LS Headers will be processed here */
1596     /* skip to the end of DB-Desc header */
1597     DISSECTOR_ASSERT((version == OSPF_VERSION_2) || (version == OSPF_VERSION_3));
1598     while (orig_offset + length > offset) {
1599         if ( version == OSPF_VERSION_2)
1600             offset = dissect_ospf_v2_lsa(tvb, offset, tree, FALSE);
1601         else
1602             offset = dissect_ospf_v3_lsa(tvb, offset, tree, FALSE, address_family);
1603     }
1604
1605 }
1606
1607 static void
1608 dissect_ospf_ls_req(tvbuff_t *tvb, int offset, proto_tree *tree, guint8 version,
1609                     guint16 length)
1610 {
1611     proto_tree *ospf_lsr_tree;
1612     proto_item *ti;
1613     guint16 reserved;
1614     int orig_offset = offset;
1615
1616     /* zero or more LS requests may be within a LS Request */
1617     /* we place every request for a LSA in a single subtree */
1618     while (orig_offset + length > offset) {
1619         ti = proto_tree_add_text(tree, tvb, offset, OSPF_LS_REQ_LENGTH,
1620                                  "Link State Request");
1621         ospf_lsr_tree = proto_item_add_subtree(ti, ett_ospf_lsr);
1622
1623         switch ( version ) {
1624
1625         case OSPF_VERSION_2:
1626             proto_tree_add_item(ospf_lsr_tree, hf_ospf_filter[OSPFF_LS_TYPE],
1627                                 tvb, offset, 4, ENC_BIG_ENDIAN);
1628             break;
1629         case OSPF_VERSION_3:
1630             reserved = tvb_get_ntohs(tvb, offset);
1631             proto_tree_add_text(ospf_lsr_tree, tvb, offset, 2,
1632                                 (reserved == 0 ? "Reserved: %u" :  "Reserved: %u [incorrect, should be 0]"), reserved);
1633             proto_tree_add_item(ospf_lsr_tree, hf_ospf_filter[OSPFF_V3_LS_TYPE],
1634                                 tvb, offset + 2, 2, ENC_BIG_ENDIAN);
1635             break;
1636         }
1637
1638
1639         proto_tree_add_text(ospf_lsr_tree, tvb, offset + 4, 4, "Link State ID: %s",
1640                             tvb_ip_to_str(tvb, offset + 4));
1641         proto_tree_add_item(ospf_lsr_tree, hf_ospf_filter[OSPFF_ADV_ROUTER],
1642                             tvb, offset + 8, 4, ENC_BIG_ENDIAN);
1643
1644         offset += 12;
1645     }
1646 }
1647
1648 static void
1649 dissect_ospf_ls_upd(tvbuff_t *tvb, int offset, proto_tree *tree, guint8 version,
1650                     guint16 length, guint8 address_family)
1651 {
1652     proto_tree *ospf_lsa_upd_tree=NULL;
1653     proto_item *ti;
1654     guint32 lsa_nr;
1655     guint32 lsa_counter;
1656
1657     ti = proto_tree_add_text(tree, tvb, offset, length, "LS Update Packet");
1658     ospf_lsa_upd_tree = proto_item_add_subtree(ti, ett_ospf_lsa_upd);
1659
1660     lsa_nr = tvb_get_ntohl(tvb, offset);
1661     proto_tree_add_text(ospf_lsa_upd_tree, tvb, offset, 4, "Number of LSAs: %u", lsa_nr);
1662     /* skip to the beginning of the first LSA */
1663     offset += 4; /* the LS Upd Packet contains only a 32 bit #LSAs field */
1664
1665     DISSECTOR_ASSERT((version == OSPF_VERSION_2) || (version == OSPF_VERSION_3));
1666     lsa_counter = 0;
1667     while (lsa_counter < lsa_nr) {
1668         if (version == OSPF_VERSION_2)
1669             offset = dissect_ospf_v2_lsa(tvb, offset, ospf_lsa_upd_tree, TRUE);
1670         else
1671             offset = dissect_ospf_v3_lsa(tvb, offset, ospf_lsa_upd_tree, TRUE,
1672                                          address_family);
1673         lsa_counter += 1;
1674     }
1675 }
1676
1677 static void
1678 dissect_ospf_ls_ack(tvbuff_t *tvb, int offset, proto_tree *tree, guint8 version,
1679                     guint16 length, guint8 address_family)
1680 {
1681     int orig_offset = offset;
1682     DISSECTOR_ASSERT((version == OSPF_VERSION_2) || (version == OSPF_VERSION_3));
1683     /* the body of a LS Ack packet simply contains zero or more LSA Headers */
1684     while (orig_offset + length > offset) {
1685         if (version == OSPF_VERSION_2)
1686             offset = dissect_ospf_v2_lsa(tvb, offset, tree, FALSE);
1687         else
1688             offset = dissect_ospf_v3_lsa(tvb, offset, tree, FALSE, address_family);
1689     }
1690 }
1691
1692 /*
1693  * Returns if an LSA is opaque, i.e. requires special treatment
1694  */
1695 static int
1696 is_opaque(int lsa_type)
1697 {
1698     return (lsa_type >= OSPF_LSTYPE_OP_LINKLOCAL &&
1699         lsa_type <= OSPF_LSTYPE_OP_ASWIDE);
1700 }
1701
1702 /* MPLS/TE TLV types */
1703 #define MPLS_TLV_ROUTER    1
1704 #define MPLS_TLV_LINK      2
1705 #define OIF_TLV_TNA    32768
1706
1707 /* MPLS/TE Link STLV types */
1708 enum {
1709     MPLS_LINK_TYPE       = 1,           /* RFC 3630, OSPF-TE   */
1710     MPLS_LINK_ID,
1711     MPLS_LINK_LOCAL_IF,
1712     MPLS_LINK_REMOTE_IF,
1713     MPLS_LINK_TE_METRIC,
1714     MPLS_LINK_MAX_BW,
1715     MPLS_LINK_MAX_RES_BW,
1716     MPLS_LINK_UNRES_BW,
1717     MPLS_LINK_COLOR,
1718     MPLS_LINK_LOCAL_REMOTE_ID = 11,     /* RFC 4203, GMPLS     */
1719     MPLS_LINK_PROTECTION = 14,
1720     MPLS_LINK_IF_SWITCHING_DESC,
1721     MPLS_LINK_SHARED_RISK_GROUP,
1722     MPLS_LINK_BANDWIDTH_CONSTRAINT = 17 /* RFC 4124, OSPF-DSTE */
1723 };
1724
1725
1726 /* OIF TLV types */
1727 enum {
1728     OIF_LOCAL_NODE_ID = 32773,
1729     OIF_REMOTE_NODE_ID,
1730     OIF_SONET_SDH_SWITCHING_CAPABILITY,
1731     OIF_TNA_IPv4_ADDRESS,
1732     OIF_NODE_ID,
1733     OIF_TNA_IPv6_ADDRESS,
1734     OIF_TNA_NSAP_ADDRESS
1735 };
1736
1737 static const value_string mpls_link_stlv_str[] = {
1738     {MPLS_LINK_TYPE, "Link Type"},
1739     {MPLS_LINK_ID, "Link ID"},
1740     {MPLS_LINK_LOCAL_IF, "Local Interface IP Address"},
1741     {MPLS_LINK_REMOTE_IF, "Remote Interface IP Address"},
1742     {MPLS_LINK_TE_METRIC, "Traffic Engineering Metric"},
1743     {MPLS_LINK_MAX_BW, "Maximum Bandwidth"},
1744     {MPLS_LINK_MAX_RES_BW, "Maximum Reservable Bandwidth"},
1745     {MPLS_LINK_UNRES_BW, "Unreserved Bandwidth"},
1746     {MPLS_LINK_COLOR, "Resource Class/Color"},
1747     {MPLS_LINK_LOCAL_REMOTE_ID, "Link Local/Remote Identifier"},
1748     {MPLS_LINK_PROTECTION, "Link Protection Type"},
1749     {MPLS_LINK_IF_SWITCHING_DESC, "Interface Switching Capability Descriptor"},
1750     {MPLS_LINK_SHARED_RISK_GROUP, "Shared Risk Link Group"},
1751     {MPLS_LINK_BANDWIDTH_CONSTRAINT, "Bandwidth Constraints"},
1752     {OIF_LOCAL_NODE_ID, "Local Node ID"},
1753     {OIF_REMOTE_NODE_ID, "Remote Node ID"},
1754     {OIF_SONET_SDH_SWITCHING_CAPABILITY, "Sonet/SDH Interface Switching Capability"},
1755     {0, NULL},
1756 };
1757
1758 static const range_string mpls_te_tlv_rvals[] = {
1759     { 3,     32767, "(Assigned via Standards Action)"},
1760     { 32768, 32777, "(For Experimental Use)"},
1761     { 32778, 65535, "(Not to be Assigned)"},
1762     { 0,         0, NULL}
1763 };
1764
1765 static const range_string mpls_te_sub_tlv_rvals[] = {
1766     { 10,     32767, "(Assigned via Standards Action)"},
1767     { 32768, 32777, "(For Experimental Use)"},
1768     { 32778, 65535, "(Not to be Assigned)"},
1769     { 0,         0, NULL}
1770 };
1771
1772 static const value_string oif_stlv_str[] = {
1773     {OIF_TNA_IPv4_ADDRESS, "TNA address"},
1774     {OIF_NODE_ID, "Node ID"},
1775     {OIF_TNA_IPv6_ADDRESS, "TNA address"},
1776     {OIF_TNA_NSAP_ADDRESS, "TNA address"},
1777     {0, NULL},
1778 };
1779
1780 static const range_string ospf_instance_id_rvals[] = {
1781     { 0, 32, "IPv6 unicast AF" },
1782     { 33, 64, "IPv6 multicast AF" },
1783     { 65, 96, "IPv4 unicast AF" },
1784     { 97, 128, "IPv4 multicast AF" },
1785     { 129, 255, "Reserved" },
1786     { 0, 0, NULL },
1787 };
1788
1789 /*
1790  * Dissect MPLS/TE opaque LSA
1791  */
1792 static void
1793 dissect_ospf_lsa_mpls(tvbuff_t *tvb, int offset, proto_tree *tree,
1794                       guint32 length)
1795 {
1796     proto_item *ti, *hidden_item;
1797     proto_tree *mpls_tree;
1798     proto_tree *tlv_tree;
1799     proto_tree *stlv_tree;
1800     proto_tree *stlv_admingrp_tree = NULL;
1801
1802     int tlv_type;
1803     int tlv_length;
1804     int tlv_end_offset;
1805
1806     int stlv_type, stlv_len, stlv_offset;
1807     const char *stlv_name;
1808     guint32 stlv_admingrp, mask;
1809     int i;
1810     guint8 switch_cap;
1811
1812     const guint8 allzero[] = { 0x00, 0x00, 0x00 };
1813     guint num_bcs = 0;
1814
1815     ti = proto_tree_add_text(tree, tvb, offset, length,
1816                              "MPLS Traffic Engineering LSA");
1817     hidden_item = proto_tree_add_item(tree, hf_ospf_filter[OSPFF_LS_MPLS],
1818                                       tvb, offset, 2, ENC_BIG_ENDIAN);
1819     PROTO_ITEM_SET_HIDDEN(hidden_item);
1820     mpls_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls);
1821
1822     while (length != 0) {
1823         tlv_type = tvb_get_ntohs(tvb, offset);
1824         tlv_length = tvb_get_ntohs(tvb, offset + 2);
1825         tlv_end_offset = offset + tlv_length + 4;
1826
1827         switch (tlv_type) {
1828
1829         case MPLS_TLV_ROUTER:
1830             ti = proto_tree_add_text(mpls_tree, tvb, offset, tlv_length+4,
1831                                      "Router Address: %s",
1832                                      tvb_ip_to_str(tvb, offset+4));
1833             tlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_router);
1834             proto_tree_add_text(tlv_tree, tvb, offset, 2, "TLV Type: 1 - Router Address");
1835             proto_tree_add_text(tlv_tree, tvb, offset+2, 2, "TLV Length: %u",
1836                                 tlv_length);
1837             proto_tree_add_item(tlv_tree, hf_ospf_filter[OSPFF_LS_MPLS_ROUTERID],
1838                                 tvb, offset+4, 4, ENC_BIG_ENDIAN);
1839             break;
1840
1841         case MPLS_TLV_LINK:
1842             ti = proto_tree_add_text(mpls_tree, tvb, offset, tlv_length+4,
1843                                      "Link Information");
1844             tlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link);
1845             proto_tree_add_text(tlv_tree, tvb, offset, 2, "TLV Type: 2 - Link Information");
1846             proto_tree_add_text(tlv_tree, tvb, offset+2, 2, "TLV Length: %u",
1847                                 tlv_length);
1848             stlv_offset = offset + 4;
1849
1850             /* Walk down the sub-TLVs for link information */
1851             while (stlv_offset < tlv_end_offset) {
1852                 stlv_type = tvb_get_ntohs(tvb, stlv_offset);
1853                 stlv_len = tvb_get_ntohs(tvb, stlv_offset + 2);
1854                 stlv_name = val_to_str_const(stlv_type, mpls_link_stlv_str, "Unknown sub-TLV");
1855                 switch (stlv_type) {
1856
1857                 case MPLS_LINK_TYPE:
1858                     ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1859                                              "%s: %u - %s", stlv_name,
1860                                              tvb_get_guint8(tvb, stlv_offset + 4),
1861                                              val_to_str_const(tvb_get_guint8(tvb, stlv_offset + 4),
1862                                                               mpls_link_stlv_ltype_str, "Unknown Link Type"));
1863                     stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1864                     proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1865                                         "TLV Type: %u: %s", stlv_type, stlv_name);
1866                     proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1867                                         stlv_len);
1868                     proto_tree_add_item(stlv_tree, hf_ospf_filter[OSPFF_LS_MPLS_LINKTYPE],
1869                                         tvb, stlv_offset+4, 1,ENC_BIG_ENDIAN);
1870                     break;
1871
1872                 case MPLS_LINK_ID:
1873                     ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1874                                              "%s: %s", stlv_name,
1875                                              tvb_ip_to_str(tvb, stlv_offset + 4));
1876                     stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1877                     proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1878                                         "TLV Type: %u: %s", stlv_type, stlv_name);
1879                     proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1880                                         stlv_len);
1881                     proto_tree_add_item(stlv_tree, hf_ospf_filter[OSPFF_LS_MPLS_LINKID],
1882                                         tvb, stlv_offset+4, 4, ENC_BIG_ENDIAN);
1883                     break;
1884
1885                 case MPLS_LINK_LOCAL_IF:
1886                 case MPLS_LINK_REMOTE_IF:
1887                     ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1888                                              "%s: %s", stlv_name, tvb_ip_to_str(tvb, stlv_offset + 4));
1889                     stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1890                     proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1891                                         "TLV Type: %u: %s", stlv_type, stlv_name);
1892                     proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1893                                         stlv_len);
1894                     /*   The Local/Remote Interface IP Address sub-TLV is TLV type 3/4, and is 4N
1895                          octets in length, where N is the number of neighbor addresses. */
1896                     for (i=0; i < stlv_len; i+=4)
1897                         proto_tree_add_item(stlv_tree,
1898                                             stlv_type==MPLS_LINK_LOCAL_IF ?
1899                                             hf_ospf_filter[OSPFF_LS_MPLS_LOCAL_ADDR] :
1900                                             hf_ospf_filter[OSPFF_LS_MPLS_REMOTE_ADDR],
1901                                             tvb, stlv_offset+4+i, 4, ENC_BIG_ENDIAN);
1902                     break;
1903
1904                 case MPLS_LINK_TE_METRIC:
1905                     ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1906                                              "%s: %u", stlv_name,
1907                                              tvb_get_ntohl(tvb, stlv_offset + 4));
1908                     stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1909                     proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1910                                         "TLV Type: %u: %s", stlv_type, stlv_name);
1911                     proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1912                                         stlv_len);
1913                     proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 4, "%s: %u", stlv_name,
1914                                         tvb_get_ntohl(tvb, stlv_offset + 4));
1915                     break;
1916
1917                 case MPLS_LINK_COLOR:
1918                     ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1919                                              "%s: 0x%08x", stlv_name,
1920                                              tvb_get_ntohl(tvb, stlv_offset + 4));
1921                     stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1922                     proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1923                                         "TLV Type: %u: %s", stlv_type, stlv_name);
1924                     proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1925                                         stlv_len);
1926                     stlv_admingrp = tvb_get_ntohl(tvb, stlv_offset + 4);
1927                     mask = 1;
1928                     ti = proto_tree_add_item(stlv_tree, hf_ospf_filter[OSPFF_LS_MPLS_LINKCOLOR],
1929                                              tvb, stlv_offset+4, 4, ENC_BIG_ENDIAN);
1930                     stlv_admingrp_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv_admingrp);
1931                     if (stlv_admingrp_tree == NULL)
1932                         return;
1933                     for (i = 0 ; i < 32 ; i++) {
1934                         if ((stlv_admingrp & mask) != 0) {
1935                             proto_tree_add_text(stlv_admingrp_tree, tvb, stlv_offset+4,
1936                                                 4, "Group %d", i);
1937                         }
1938                         mask <<= 1;
1939                     }
1940                     break;
1941
1942                 case MPLS_LINK_MAX_BW:
1943                 case MPLS_LINK_MAX_RES_BW:
1944                     ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1945                                              "%s: %.10g bytes/s (%.0f bits/s)", stlv_name,
1946                                              tvb_get_ntohieee_float(tvb, stlv_offset + 4),
1947                                              tvb_get_ntohieee_float(tvb, stlv_offset + 4) * 8.0);
1948                     stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1949                     proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1950                                         "TLV Type: %u: %s", stlv_type, stlv_name);
1951                     proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1952                                         stlv_len);
1953                     proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 4, "%s: %.10g bytes/s (%.0f bits/s)", stlv_name,
1954                                         tvb_get_ntohieee_float(tvb, stlv_offset + 4),
1955                                         tvb_get_ntohieee_float(tvb, stlv_offset + 4) * 8.0);
1956                     break;
1957
1958                 case MPLS_LINK_UNRES_BW:
1959                     ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1960                                              "%s", stlv_name);
1961                     stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1962                     proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1963                                         "TLV Type: %u: %s", stlv_type, stlv_name);
1964                     proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
1965                                         stlv_len);
1966                     for (i = 0; i < 8; i++) {
1967                         proto_tree_add_text(stlv_tree, tvb, stlv_offset+4+(i*4), 4,
1968                                             "Pri (or TE-Class) %d: %.10g bytes/s (%.0f bits/s)", i,
1969                                             tvb_get_ntohieee_float(tvb, stlv_offset + 4 + i*4),
1970                                             tvb_get_ntohieee_float(tvb, stlv_offset + 4 + i*4) * 8.0);
1971                     }
1972                     break;
1973
1974                 case MPLS_LINK_BANDWIDTH_CONSTRAINT:
1975                     /*
1976                       The "Bandwidth Constraints" sub-TLV format is illustrated below:
1977
1978                       0                   1                   2                   3
1979                       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
1980                       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1981                       | BC Model Id   |           Reserved                            |
1982                       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1983                       |                       BC0 value                               |
1984                       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1985                       //                       . . .                                 //
1986                       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1987                       |                       BCh value                               |
1988                       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1989                     */
1990
1991                     ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
1992                                              "%s", stlv_name);
1993
1994                     stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
1995
1996                     proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
1997                                         "TLV Type: %u: %s", stlv_type, stlv_name);
1998
1999                     proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
2000                                         stlv_len);
2001
2002                     proto_tree_add_item(stlv_tree, hf_ospf_filter[OSPFF_LS_MPLS_BC_MODEL_ID],
2003                                         tvb, stlv_offset+4, 1, ENC_BIG_ENDIAN);
2004
2005                     /* 3 octets reserved +5, +6 and +7 (all 0x00) */
2006                     if(tvb_memeql(tvb, stlv_offset+5, allzero, 3) == -1) {
2007                         proto_tree_add_text(stlv_tree, tvb, stlv_offset+5, 3,
2008                                             "Warning: these bytes are reserved and must be 0x00");
2009                     }
2010
2011                     if(((stlv_len % 4)!=0)) {
2012                         proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, stlv_len,
2013                                             "Malformed Packet: Length must be N x 4 octets");
2014                         break;
2015                     }
2016
2017                     /* stlv_len shound range from 4 to 36 bytes */
2018                     num_bcs = (stlv_len - 4)/4;
2019
2020                     if(num_bcs>8) {
2021                         proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, stlv_len,
2022                                             "Malformed Packet: too many BC (%u)", num_bcs);
2023                         break;
2024                     }
2025
2026                     if(num_bcs==0) {
2027                         proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, stlv_len,
2028                                             "Malformed Packet: Bandwidth Constraints sub-TLV with no BC?");
2029                         break;
2030                     }
2031
2032                     for(i = 0; i < (int) num_bcs; i++) {
2033                         proto_tree_add_text(stlv_tree, tvb, stlv_offset+8+(i*4), 4,
2034                                             "BC %d: %.10g bytes/s (%.0f bits/s)", i,
2035                                             tvb_get_ntohieee_float(tvb, stlv_offset + 8 + i*4),
2036                                             tvb_get_ntohieee_float(tvb, stlv_offset + 8 + i*4) * 8.0);
2037                     }
2038                     break;
2039
2040                 case MPLS_LINK_LOCAL_REMOTE_ID:
2041                     ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
2042                                              "%s: %d (0x%x) - %d (0x%x)", stlv_name,
2043                                              tvb_get_ntohl(tvb, stlv_offset + 4),
2044                                              tvb_get_ntohl(tvb, stlv_offset + 4),
2045                                              tvb_get_ntohl(tvb, stlv_offset + 8),
2046                                              tvb_get_ntohl(tvb, stlv_offset + 8));
2047                     stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
2048
2049                     proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
2050                                         "TLV Type: %u: %s", stlv_type, stlv_name);
2051                     proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
2052                                         stlv_len);
2053                     proto_tree_add_item(stlv_tree,
2054                                         hf_ospf_filter[OSPFF_LS_MPLS_LOCAL_IFID],
2055                                         tvb, stlv_offset+4, 4, ENC_BIG_ENDIAN);
2056                     proto_tree_add_item(stlv_tree,
2057                                         hf_ospf_filter[OSPFF_LS_MPLS_REMOTE_IFID],
2058                                         tvb, stlv_offset+8, 4, ENC_BIG_ENDIAN);
2059                     break;
2060
2061                 case MPLS_LINK_IF_SWITCHING_DESC:
2062                     ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
2063                                              "%s", stlv_name);
2064                     stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
2065                     proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
2066                                         "TLV Type: %u: %s", stlv_type, stlv_name);
2067                     proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
2068                                         stlv_len);
2069                     switch_cap = tvb_get_guint8 (tvb, stlv_offset+4);
2070                     proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 1, "Switching Type: %s",
2071                                         rval_to_str(tvb_get_guint8(tvb,stlv_offset+4),
2072                                                     gmpls_switching_type_rvals, "Unknown (%d)"));
2073                     proto_tree_add_text(stlv_tree, tvb, stlv_offset+5, 1, "Encoding: %s",
2074                                         rval_to_str(tvb_get_guint8(tvb,stlv_offset+5),
2075                                                     gmpls_lsp_enc_rvals, "Unknown (%d)"));
2076                     for (i = 0; i < 8; i++) {
2077                         proto_tree_add_text(stlv_tree, tvb, stlv_offset+8+(i*4), 4,
2078                                             "Pri %d: %.10g bytes/s (%.0f bits/s)", i,
2079                                             tvb_get_ntohieee_float(tvb, stlv_offset + 8 + i*4),
2080                                             tvb_get_ntohieee_float(tvb, stlv_offset + 8 + i*4) * 8.0);
2081                     }
2082                     if (switch_cap >=1 && switch_cap <=4) {           /* PSC-1 .. PSC-4 */
2083                         proto_tree_add_text(stlv_tree, tvb, stlv_offset+40, 4,
2084                                             "Minimum LSP bandwidth: %.10g bytes/s (%.0f bits/s)",
2085                                             tvb_get_ntohieee_float(tvb, stlv_offset + 40),
2086                                             tvb_get_ntohieee_float(tvb, stlv_offset + 40) * 8.0);
2087                         proto_tree_add_text(stlv_tree, tvb, stlv_offset+44, 2,
2088                                             "Interface MTU: %d", tvb_get_ntohs(tvb, stlv_offset+44));
2089                     }
2090
2091                     if (switch_cap == 100) {                         /* TDM */
2092                         proto_tree_add_text(stlv_tree, tvb, stlv_offset+40, 4,
2093                                             "Minimum LSP bandwidth: %.10g bytes/s (%.0f bits/s)",
2094                                             tvb_get_ntohieee_float(tvb, stlv_offset + 40),
2095                                             tvb_get_ntohieee_float(tvb, stlv_offset + 40) * 8.0);
2096                         proto_tree_add_text(stlv_tree, tvb, stlv_offset+44, 2,
2097                                             "SONET/SDH: %s",
2098                                             tvb_get_guint8(tvb, stlv_offset+44) ?
2099                                             "Arbitrary" : "Standard");
2100                     }
2101                     break;
2102                 case MPLS_LINK_PROTECTION:
2103                     ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
2104                                              "%s", stlv_name);
2105                     stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
2106                     proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
2107                                         "TLV Type: %u: %s", stlv_type, stlv_name);
2108                     proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
2109                                         stlv_len);
2110                     proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 1, "Protection Capability: %s (0x%x)",
2111                                         val_to_str(tvb_get_guint8(tvb,stlv_offset+4),
2112                                                    gmpls_protection_cap_str,
2113                                                    "Unknown (%d)"),
2114                                         tvb_get_guint8(tvb,stlv_offset+4));
2115                     break;
2116
2117                 case MPLS_LINK_SHARED_RISK_GROUP:
2118                     ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
2119                                              "%s", stlv_name);
2120                     stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
2121                     proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
2122                                         "TLV Type: %u: %s", stlv_type, stlv_name);
2123                     proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
2124                                         stlv_len);
2125                     for (i=0; i < stlv_len; i+=4)
2126                         proto_tree_add_text(stlv_tree, tvb, stlv_offset+4+i, 4, "Shared Risk Link Group: %u",
2127                                             tvb_get_ntohl(tvb,stlv_offset+4+i));
2128                     break;
2129
2130                 case OIF_LOCAL_NODE_ID:
2131                     ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
2132                                              "%s: %s", stlv_name,
2133                                              tvb_ip_to_str(tvb, stlv_offset + 4));
2134                     stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
2135                     proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
2136                                         "TLV Type: %u: %s", stlv_type, stlv_name);
2137                     proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
2138                                         stlv_len);
2139                     proto_tree_add_item(stlv_tree,
2140                                         hf_ospf_filter[OSPFF_LS_OIF_LOCAL_NODE_ID],
2141                                         tvb, stlv_offset + 4, 4, ENC_BIG_ENDIAN);
2142                     break;
2143
2144                 case OIF_REMOTE_NODE_ID:
2145                     ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
2146                                              "%s: %s", stlv_name,
2147                                              tvb_ip_to_str(tvb, stlv_offset + 4));
2148                     stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
2149                     proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
2150                                         "TLV Type: %u: %s", stlv_type, stlv_name);
2151                     proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
2152                                         stlv_len);
2153                     proto_tree_add_item(stlv_tree,
2154                                         hf_ospf_filter[OSPFF_LS_OIF_REMOTE_NODE_ID],
2155                                         tvb, stlv_offset + 4, 4, ENC_BIG_ENDIAN);
2156                     break;
2157
2158                 case OIF_SONET_SDH_SWITCHING_CAPABILITY:
2159                     ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4, "%s", stlv_name);
2160                     stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
2161                     proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
2162                                         "TLV Type: %u: %s", stlv_type, stlv_name);
2163                     proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
2164                                         stlv_len);
2165                     proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 1, "Switching Cap: %s",
2166                                         rval_to_str(tvb_get_guint8 (tvb, stlv_offset+4),
2167                                                     gmpls_switching_type_rvals, "Unknown (%d)"));
2168                     proto_tree_add_text(stlv_tree, tvb, stlv_offset+5, 1, "Encoding: %s",
2169                                         rval_to_str(tvb_get_guint8(tvb,stlv_offset+5),
2170                                                     gmpls_lsp_enc_rvals, "Unknown (%d)"));
2171                     for (i = 0; i < (stlv_len - 4) / 4; i++) {
2172                         proto_tree_add_text(stlv_tree, tvb, stlv_offset+8+(i*4), 4,
2173                                             "%s: %d free timeslots",
2174                                             val_to_str_ext(tvb_get_guint8(tvb, stlv_offset+8+(i*4)),
2175                                                            &gmpls_sonet_signal_type_str_ext,
2176                                                            "Unknown Signal Type (%d)"),
2177                                             tvb_get_ntoh24(tvb, stlv_offset + 9 + i*4));
2178                     }
2179
2180                     break;
2181                 default:
2182                     ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
2183                                              "Unknown Link sub-TLV: %u %s", stlv_type,
2184                                              rval_to_str(stlv_type, mpls_te_sub_tlv_rvals, "Unknown"));
2185                     stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link_stlv);
2186                     proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
2187                                         "TLV Type: %u: %s %s", stlv_type, stlv_name,
2188                                         rval_to_str(stlv_type, mpls_te_sub_tlv_rvals, "Unknown"));
2189                     proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
2190                                         stlv_len);
2191                     proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, stlv_len,
2192                                         "TLV Value");
2193                     break;
2194                 }
2195                 stlv_offset += ((stlv_len+4+3)/4)*4;
2196             }
2197             break;
2198
2199         case OIF_TLV_TNA:
2200             ti = proto_tree_add_text(mpls_tree, tvb, offset, tlv_length+4,
2201                                      "TNA Information");
2202             tlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_oif_tna);
2203             proto_tree_add_text(tlv_tree, tvb, offset, 2, "TLV Type: 32768 - TNA Information");
2204             proto_tree_add_text(tlv_tree, tvb, offset+2, 2, "TLV Length: %u",
2205                                 tlv_length);
2206             stlv_offset = offset + 4;
2207
2208             /* Walk down the sub-TLVs for TNA information */
2209             while (stlv_offset < tlv_end_offset) {
2210                 stlv_type = tvb_get_ntohs(tvb, stlv_offset);
2211                 stlv_len = tvb_get_ntohs(tvb, stlv_offset + 2);
2212                 stlv_name = val_to_str_const(stlv_type, oif_stlv_str, "Unknown sub-TLV");
2213                 switch (stlv_type) {
2214
2215                 case OIF_NODE_ID:
2216                     ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
2217                                              "%s: %s", stlv_name,
2218                                              tvb_ip_to_str(tvb, stlv_offset + 4));
2219                     stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_oif_tna_stlv);
2220                     proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
2221                                         "TLV Type: %u: %s", stlv_type, stlv_name);
2222                     proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
2223                                         stlv_len);
2224                     proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 4, "%s: %s", stlv_name,
2225                                         tvb_ip_to_str(tvb, stlv_offset + 4));
2226                     break;
2227
2228                 case OIF_TNA_IPv4_ADDRESS:
2229                     ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
2230                                              "%s (IPv4): %s", stlv_name,
2231                                              tvb_ip_to_str(tvb, stlv_offset + 8));
2232                     stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_oif_tna_stlv);
2233                     proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
2234                                         "TLV Type: %u: %s (IPv4)", stlv_type, stlv_name);
2235                     proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u", stlv_len);
2236                     proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 1, "Addr Length: %u",
2237                                         tvb_get_guint8 (tvb, stlv_offset+4));
2238                     proto_tree_add_text(stlv_tree, tvb, stlv_offset+8, stlv_len - 4, "TNA Addr: %s",
2239                                         tvb_ip_to_str(tvb, stlv_offset + 8));
2240                     break;
2241
2242                 case OIF_TNA_IPv6_ADDRESS:
2243                     ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
2244                                              "%s (IPv6): %s", stlv_name,
2245                                              tvb_ip6_to_str(tvb, stlv_offset + 8));
2246                     stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_oif_tna_stlv);
2247                     proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
2248                                         "TLV Type: %u: %s (IPv6)", stlv_type, stlv_name);
2249                     proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u", stlv_len);
2250                     proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 1, "Addr Length: %u",
2251                                         tvb_get_guint8 (tvb, stlv_offset+4));
2252                     proto_tree_add_text(stlv_tree, tvb, stlv_offset+8, stlv_len - 4, "TNA Addr: %s",
2253                                         tvb_ip6_to_str(tvb, stlv_offset + 8));
2254                     break;
2255
2256                 case OIF_TNA_NSAP_ADDRESS:
2257                     ti = proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
2258                                              "%s (NSAP): %s", stlv_name,
2259                                              tvb_bytes_to_ep_str (tvb, stlv_offset + 8, stlv_len - 4));
2260                     stlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_oif_tna_stlv);
2261                     proto_tree_add_text(stlv_tree, tvb, stlv_offset, 2,
2262                                         "TLV Type: %u: %s (NSAP)", stlv_type, stlv_name);
2263                     proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u", stlv_len);
2264                     proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 1, "Addr Length: %u",
2265                                         tvb_get_guint8 (tvb, stlv_offset+4));
2266                     proto_tree_add_text(stlv_tree, tvb, stlv_offset+8, stlv_len - 4, "TNA Addr: %s",
2267                                         tvb_bytes_to_ep_str(tvb, stlv_offset+8, stlv_len - 4));
2268                     break;
2269
2270                 default:
2271                     proto_tree_add_text(tlv_tree, tvb, stlv_offset, stlv_len+4,
2272                                         "Unknown Link sub-TLV: %u", stlv_type);
2273                     break;
2274                 }
2275                 stlv_offset += ((stlv_len+4+3)/4)*4;
2276             }
2277             break;
2278         default:
2279             ti = proto_tree_add_text(mpls_tree, tvb, offset, tlv_length+4,
2280                                      "Unknown LSA: %u %s", tlv_type,
2281                                      rval_to_str(tlv_type, mpls_te_tlv_rvals, "Unknown"));
2282             tlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_mpls_link);
2283             proto_tree_add_text(tlv_tree, tvb, offset, 2, "TLV Type: %u - Unknown %s",
2284                                 tlv_type, rval_to_str(tlv_type, mpls_te_tlv_rvals, "Unknown"));
2285             proto_tree_add_text(tlv_tree, tvb, offset+2, 2, "TLV Length: %u",
2286                                 tlv_length);
2287             proto_tree_add_text(tlv_tree, tvb, offset+4, tlv_length, "TLV Data");
2288             break;
2289         }
2290
2291         offset += tlv_length + 4;
2292         length -= tlv_length + 4;
2293     }
2294 }
2295
2296 /*
2297  * Dissect the TLVs within a Grace-LSA as defined by RFC 3623
2298  */
2299 static void dissect_ospf_lsa_grace_tlv (tvbuff_t *tvb, int offset,
2300                                         proto_tree *tree, guint32 length)
2301 {
2302     guint16 tlv_type;
2303     guint16 tlv_length;
2304     int tlv_length_with_pad; /* The total length of the TLV including the type
2305                                 and length fields and any padding */
2306     guint32 grace_period;
2307     guint8 restart_reason;
2308     guint32 restart_ip;
2309     proto_tree *tlv_tree;
2310     proto_item *tree_item;
2311     proto_item *grace_tree_item;
2312
2313     if (!tree) { return; }
2314
2315     while (length > 0)
2316     {
2317         tlv_type = tvb_get_ntohs(tvb, offset);
2318         tlv_length = tvb_get_ntohs(tvb, offset + 2);
2319         /* The total length of the TLV including the type, length, value and
2320          * pad bytes (TLVs are padded to 4 octet alignment).
2321          */
2322         tlv_length_with_pad = tlv_length + 4 + ((4 - (tlv_length % 4)) % 4);
2323
2324         tree_item = proto_tree_add_item(tree, hf_ospf_filter[OSPFF_V2_GRACE_TLV], tvb, offset,
2325                                         tlv_length_with_pad, ENC_NA);
2326         tlv_tree = proto_item_add_subtree(tree_item, ett_ospf_lsa_grace_tlv);
2327         proto_tree_add_text(tlv_tree, tvb, offset, 2, "Type: %s (%u)",
2328                             val_to_str_const(tlv_type, grace_tlv_type_vals, "Unknown grace-LSA TLV"), tlv_type);
2329         proto_tree_add_text(tlv_tree, tvb, offset + 2, 2, "Length: %u", tlv_length);
2330
2331         switch (tlv_type) {
2332         case GRACE_TLV_PERIOD:
2333             grace_period = tvb_get_ntohl(tvb, offset + 4);
2334             grace_tree_item = proto_tree_add_item(tlv_tree, hf_ospf_filter[OSPFF_V2_GRACE_PERIOD], tvb,
2335                                                   offset + 4, tlv_length, ENC_BIG_ENDIAN);
2336             proto_item_append_text(grace_tree_item, " seconds");
2337             proto_item_set_text(tree_item, "Grace Period: %u seconds", grace_period);
2338             break;
2339         case GRACE_TLV_REASON:
2340             restart_reason = tvb_get_guint8(tvb, offset + 4);
2341             proto_tree_add_item(tlv_tree, hf_ospf_filter[OSPFF_V2_GRACE_REASON], tvb, offset + 4,
2342                                 tlv_length, ENC_BIG_ENDIAN);
2343             proto_item_set_text(tree_item, "Restart Reason: %s (%u)",
2344                                 val_to_str_const(restart_reason, restart_reason_vals, "Unknown Restart Reason"),
2345                                 restart_reason);
2346             break;
2347         case GRACE_TLV_IP:
2348             restart_ip = tvb_get_ipv4(tvb, offset + 4);
2349             proto_tree_add_item(tlv_tree, hf_ospf_filter[OSPFF_V2_GRACE_IP], tvb, offset + 4,
2350                                 tlv_length, ENC_BIG_ENDIAN);
2351             proto_item_set_text(tree_item, "Restart IP: %s (%s)",
2352                                 get_hostname(restart_ip), ip_to_str((guint8 *)&restart_ip));
2353             break;
2354         default:
2355             proto_item_set_text(tree_item, "Unknown grace-LSA TLV");
2356             break;
2357         }
2358         if (4 + tlv_length < tlv_length_with_pad) {
2359             proto_tree_add_text(tlv_tree, tvb, offset + 4 + tlv_length,
2360                                 tlv_length_with_pad - (4 + tlv_length), "Pad Bytes (%u)",
2361                                 tlv_length_with_pad - (4 + tlv_length) );
2362         }
2363         offset += tlv_length_with_pad;
2364         length -= tlv_length_with_pad;
2365     }
2366 }
2367
2368 /*
2369  * This function dissects the Optional Router capabilities LSA.
2370  * In case of OSPFv2, the Router Capabilities would be advertized via the first TLV
2371  * of an RI LSA and in the case of OSPFv3, the router capabilities would be advertized
2372  * using a special purpose type field value. (RFC 4970)
2373  * Also, the Dynamic Hostname or FQDN is advertized via a special purpose TLV type.
2374  * The below function adds the support to handle this as well. (RFC5642).
2375  */
2376 static void
2377 dissect_ospf_lsa_opaque_ri(tvbuff_t *tvb, int offset, proto_tree *tree,
2378                            guint32 length)
2379 {
2380     proto_item *ti;
2381     proto_tree *ri_tree;
2382     proto_tree *tlv_tree;
2383
2384     int tlv_type;
2385     int tlv_length;
2386
2387     ti = proto_tree_add_text(tree, tvb, offset, length,
2388                              "Opaque Router Information LSA");
2389
2390     ri_tree = proto_item_add_subtree(ti, ett_ospf_lsa_opaque_ri);
2391
2392     while (length > 0) {
2393         tlv_type = tvb_get_ntohs(tvb, offset);
2394         tlv_length = tvb_get_ntohs(tvb, offset + 2);
2395
2396         switch(tlv_type) {
2397
2398         case OPT_RI_TLV:
2399            ti = proto_tree_add_text(ri_tree, tvb, offset, tlv_length+4,
2400                                     "RI TLV");
2401            tlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_ri_tlv);
2402
2403            proto_tree_add_text(tlv_tree, tvb, offset, 2, "TLV Type: %s (%u)",
2404                         "Router Informational Capabilities TLV", tlv_type);
2405
2406            proto_tree_add_text(tlv_tree, tvb, offset + 2, 2, "TLV Length: %u", tlv_length);
2407
2408            dissect_ospf_bitfield(tlv_tree, tvb, offset + 4, &bfinfo_ri_options);
2409            break;
2410
2411         case DYN_HOSTNAME_TLV:
2412            ti = proto_tree_add_text(ri_tree, tvb, offset, tlv_length+4,
2413                                     "Dynamic Hostname TLV");
2414            tlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_dyn_hostname_tlv);
2415
2416            proto_tree_add_text(tlv_tree, tvb, offset, 2, "TLV Type: %s (%u)",
2417                                "Dynamic Hostname TLV", tlv_type);
2418
2419            proto_tree_add_text(tlv_tree, tvb, offset + 2, 2, "TLV Length: %u", tlv_length);
2420
2421            proto_tree_add_item(tlv_tree, hf_ospf_filter[OSPFF_DYN_HOSTNAME], tvb, offset+4, tlv_length, ENC_ASCII|ENC_NA);
2422            break;
2423
2424         default:
2425            ti = proto_tree_add_text(ri_tree, tvb, offset, tlv_length+4,
2426                                     "Unknown Opaque RI LSA TLV");
2427            tlv_tree = proto_item_add_subtree(ti, ett_ospf_lsa_unknown_tlv);
2428
2429            proto_tree_add_text(tlv_tree, tvb, offset, 2, "TLV Type: %s (%u)",
2430                                "Unknown TLV", tlv_type);
2431
2432            proto_tree_add_text(tlv_tree, tvb, offset + 2, 2, "TLV Length: %u", tlv_length);
2433
2434            proto_tree_add_item(tlv_tree, hf_ospf_filter[OSPFF_UNKNOWN_TLV_TXT], tvb, offset+4, tlv_length, ENC_ASCII|ENC_NA);
2435            break;
2436
2437         }
2438
2439         offset += tlv_length + 4;
2440         length -= tlv_length + 4;
2441     }
2442 }
2443
2444 /*
2445  * Dissect opaque LSAs
2446  */
2447 static void
2448 dissect_ospf_lsa_opaque(tvbuff_t *tvb, int offset, proto_tree *tree,
2449                         guint8 ls_id_type, guint32 length)
2450 {
2451     switch (ls_id_type) {
2452
2453     case OSPF_LSA_MPLS_TE:
2454         dissect_ospf_lsa_mpls(tvb, offset, tree, length);
2455         break;
2456     case OSPF_LSA_OPAQUE_RI:
2457         dissect_ospf_lsa_opaque_ri(tvb, offset, tree, length);
2458         break;
2459     case OSPF_LSA_GRACE:
2460         dissect_ospf_lsa_grace_tlv(tvb, offset, tree, length);
2461         break;
2462
2463     default:
2464         proto_tree_add_text(tree, tvb, offset, length,
2465                             "Unknown LSA Type %u", ls_id_type);
2466         break;
2467     } /* switch on opaque LSA id */
2468 }
2469
2470 static int
2471 dissect_ospf_v2_lsa(tvbuff_t *tvb, int offset, proto_tree *tree,
2472                     gboolean disassemble_body)
2473 {
2474     proto_tree *ospf_lsa_tree;
2475     proto_item *ti, *hidden_item;
2476
2477     guint8               ls_type;
2478     guint16              ls_length;
2479     int                  end_offset;
2480     guint16              nr_links;
2481     guint16              nr_metric;
2482
2483     /* router LSA */
2484     guint8               link_type;
2485     guint16              link_counter;
2486     guint16              metric_counter;
2487     const char          *link_type_str;
2488     const char          *link_type_short_str;
2489     const char          *link_id;
2490     const char          *metric_type_str;
2491
2492     /* AS-external LSA */
2493     guint8               options;
2494
2495     /* opaque LSA */
2496     guint8               ls_id_type;
2497     guint8               ls_ri_opaque_field;
2498
2499     ls_type = tvb_get_guint8(tvb, offset + 3);
2500     ls_length = tvb_get_ntohs(tvb, offset + 18);
2501     end_offset = offset + ls_length;
2502
2503     if (disassemble_body) {
2504         ti = proto_tree_add_text(tree, tvb, offset, ls_length,
2505                                  "LS Type: %s",
2506                                  val_to_str(ls_type, ls_type_vals, "Unknown (%d)"));
2507     } else {
2508         ti = proto_tree_add_text(tree, tvb, offset, OSPF_LSA_HEADER_LENGTH,
2509                                  "LSA Header");
2510     }
2511     ospf_lsa_tree = proto_item_add_subtree(ti, ett_ospf_lsa);
2512
2513     proto_tree_add_text(ospf_lsa_tree, tvb, offset, 2, "LS Age: %u seconds",
2514                         tvb_get_ntohs(tvb, offset) & ~OSPF_DNA_LSA);
2515     proto_tree_add_text(ospf_lsa_tree, tvb, offset, 2, "Do Not Age: %s",
2516                         (tvb_get_ntohs(tvb, offset) & OSPF_DNA_LSA) ? "True" : "False");
2517     options = tvb_get_guint8 (tvb, offset + 2);
2518     dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset + 2, &bfinfo_v2_options);
2519     proto_tree_add_item(ospf_lsa_tree, hf_ospf_filter[OSPFF_LS_TYPE], tvb,
2520                         offset + 3, 1, ENC_BIG_ENDIAN);
2521     if (ospf_ls_type_to_filter(ls_type) != -1) {
2522         hidden_item = proto_tree_add_item(ospf_lsa_tree,
2523                                           hf_ospf_filter[ospf_ls_type_to_filter(ls_type)], tvb,
2524                                           offset + 3, 1, ENC_BIG_ENDIAN);
2525         PROTO_ITEM_SET_HIDDEN(hidden_item);
2526     }
2527
2528     if (options & OSPF_V2_OPTIONS_MT) {
2529         metric_type_str = "MT-ID";
2530     } else {
2531         metric_type_str = "TOS";
2532     }
2533
2534     if (is_opaque(ls_type)) {
2535         ls_id_type = tvb_get_guint8(tvb, offset + 4);
2536         proto_tree_add_uint(ospf_lsa_tree, hf_ospf_filter[OSPFF_LS_OPAQUE_TYPE],
2537                             tvb, offset + 4, 1, ls_id_type);
2538
2539         switch (ls_id_type) {
2540
2541         case OSPF_LSA_MPLS_TE:
2542             proto_tree_add_text(ospf_lsa_tree, tvb, offset + 5, 1, "Link State ID TE-LSA Reserved: %u",
2543                                 tvb_get_guint8(tvb, offset + 5));
2544             proto_tree_add_item(ospf_lsa_tree, hf_ospf_filter[OSPFF_LS_MPLS_TE_INSTANCE],
2545                                 tvb, offset + 6, 2, ENC_BIG_ENDIAN);
2546             break;
2547
2548         case OSPF_LSA_OPAQUE_RI:
2549            ls_ri_opaque_field = tvb_get_guint8(tvb, offset + 5);
2550            if ( ls_ri_opaque_field != 0 )
2551                 ls_id_type = OSPF_LSA_UNKNOWN;
2552            else
2553                 proto_tree_add_item(ospf_lsa_tree, hf_ospf_filter[OSPFF_OPAQUE_LSA_MBZ],
2554                                     tvb, offset + 5, 3, ENC_BIG_ENDIAN);
2555            break;
2556
2557         default:
2558             proto_tree_add_text(ospf_lsa_tree, tvb, offset + 5, 3, "Link State ID Opaque ID: %u",
2559                                 tvb_get_ntoh24(tvb, offset + 5));
2560             break;
2561         }
2562     } else {
2563         ls_id_type = 0;
2564         proto_tree_add_text(ospf_lsa_tree, tvb, offset + 4, 4, "Link State ID: %s",
2565                             tvb_ip_to_str(tvb, offset + 4));
2566     }
2567
2568     proto_tree_add_item(ospf_lsa_tree, hf_ospf_filter[OSPFF_ADV_ROUTER],
2569                         tvb, offset + 8, 4, ENC_BIG_ENDIAN);
2570     proto_tree_add_text(ospf_lsa_tree, tvb, offset + 12, 4, "LS Sequence Number: 0x%08x",
2571                         tvb_get_ntohl(tvb, offset + 12));
2572     proto_tree_add_text(ospf_lsa_tree, tvb, offset + 16, 2, "LS Checksum: 0x%04x",
2573                         tvb_get_ntohs(tvb, offset + 16));
2574
2575     proto_tree_add_text(ospf_lsa_tree, tvb, offset + 18, 2, "Length: %u",
2576                         ls_length);
2577
2578     /* skip past the LSA header to the body */
2579     offset += OSPF_LSA_HEADER_LENGTH;
2580     if (ls_length <= OSPF_LSA_HEADER_LENGTH)
2581         return offset;  /* no data, or bogus length */
2582     ls_length -= OSPF_LSA_HEADER_LENGTH;
2583
2584     if (!disassemble_body)
2585         return offset;
2586
2587     switch (ls_type){
2588
2589     case OSPF_LSTYPE_ROUTER:
2590         /* flags field in an router-lsa */
2591         if (options & OSPF_V2_OPTIONS_MT) {
2592             dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset, &bfinfo_v2_router_lsa_mt_flags);
2593         } else {
2594             dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset, &bfinfo_v2_router_lsa_flags);
2595         }
2596
2597         nr_links = tvb_get_ntohs(tvb, offset + 2);
2598         proto_tree_add_text(ospf_lsa_tree, tvb, offset + 2, 2, "Number of Links: %u",
2599                             nr_links);
2600         offset += 4;
2601         /* nr_links links follow
2602          * maybe we should put each of the links into its own subtree ???
2603          */
2604         for (link_counter = 0; link_counter < nr_links; link_counter++) {
2605             proto_tree *ospf_lsa_router_link_tree;
2606             proto_item *ti_local;
2607             proto_item *ti_item;
2608
2609
2610             /* check the Link Type and ID */
2611             link_type = tvb_get_guint8(tvb, offset + 8);
2612             switch (link_type) {
2613
2614             case OSPF_LINK_PTP:
2615                 link_type_str="Point-to-point connection to another router";
2616                 link_type_short_str="PTP";
2617                 link_id="Neighboring router's Router ID";
2618                 break;
2619
2620             case OSPF_LINK_TRANSIT:
2621                 link_type_str="Connection to a transit network";
2622                 link_type_short_str="Transit";
2623                 link_id="IP address of Designated Router";
2624                 break;
2625
2626             case OSPF_LINK_STUB:
2627                 link_type_str="Connection to a stub network";
2628                 link_type_short_str="Stub";
2629                 link_id="IP network/subnet number";
2630                 break;
2631
2632             case OSPF_LINK_VIRTUAL:
2633                 link_type_str="Virtual link";
2634                 link_type_short_str="Virtual";
2635                 link_id="Neighboring router's Router ID";
2636                 break;
2637
2638             default:
2639                 link_type_str="Unknown link type";
2640                 link_type_short_str="Unknown";
2641                 link_id="Unknown link ID";
2642                 break;
2643             }
2644
2645             nr_metric = tvb_get_guint8(tvb, offset + 9);
2646
2647
2648             ti_local = proto_tree_add_text(ospf_lsa_tree, tvb, offset, 12 + 4 * nr_metric,
2649                                            "Type: %-8s ID: %-15s Data: %-15s Metric: %d",
2650                                            link_type_short_str,
2651                                            tvb_ip_to_str(tvb, offset),
2652                                            tvb_ip_to_str(tvb, offset + 4),
2653                                            tvb_get_ntohs(tvb, offset + 10));
2654
2655             ospf_lsa_router_link_tree = proto_item_add_subtree(ti_local, ett_ospf_lsa_router_link);
2656
2657
2658             ti_item = proto_tree_add_item(ospf_lsa_router_link_tree, hf_ospf_filter[OSPFF_LS_ROUTER_LINKID],
2659                         tvb, offset, 4, ENC_BIG_ENDIAN);
2660             proto_item_append_text(ti_item, " - %s", link_id);
2661
2662             /* link_data should be specified in detail (e.g. network mask) (depends on link type)*/
2663             ti_item = proto_tree_add_item(ospf_lsa_router_link_tree, hf_ospf_filter[OSPFF_LS_ROUTER_LINKDATA],
2664                         tvb, offset +4, 4, ENC_BIG_ENDIAN);
2665
2666             ti_item = proto_tree_add_item(ospf_lsa_router_link_tree, hf_ospf_filter[OSPFF_LS_ROUTER_LINKTYPE],
2667                         tvb, offset + 8, 1, ENC_BIG_ENDIAN);
2668             proto_item_append_text(ti_item, " - %s", link_type_str);
2669
2670             proto_tree_add_text(ospf_lsa_router_link_tree, tvb, offset + 9, 1, "Number of %s metrics: %u",
2671                                 metric_type_str, nr_metric);
2672             proto_tree_add_text(ospf_lsa_router_link_tree, tvb, offset + 10, 2, "%s 0 metric: %u",
2673                                 metric_type_str, tvb_get_ntohs(tvb, offset + 10));
2674
2675             offset += 12;
2676
2677             /* nr_metric metrics may follow each link
2678              * According to RFC4915 the TOS metrics was never deployed and was subsequently deprecated,
2679              * but decoding still present because MT-ID use the same structure.
2680              */
2681             for (metric_counter = 0; metric_counter < nr_metric; metric_counter++) {
2682                 proto_tree_add_text(ospf_lsa_router_link_tree, tvb, offset, 4, "%s: %u, Metric: %u",
2683                                     metric_type_str,
2684                                     tvb_get_guint8(tvb, offset),
2685                                     tvb_get_ntohs(tvb, offset + 2));
2686                 offset += 4;
2687             }
2688         }
2689         break;
2690
2691     case OSPF_LSTYPE_NETWORK:
2692         proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "Netmask: %s",
2693                             tvb_ip_to_str(tvb, offset));
2694         offset += 4;
2695
2696         while (offset < end_offset) {
2697             proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "Attached Router: %s",
2698                                 tvb_ip_to_str(tvb, offset));
2699             offset += 4;
2700         }
2701         break;
2702
2703     case OSPF_LSTYPE_SUMMERY:
2704         /* Type 3 and 4 LSAs have the same format */
2705     case OSPF_LSTYPE_ASBR:
2706         proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "Netmask: %s",
2707                             tvb_ip_to_str(tvb, offset));
2708         offset += 4;
2709
2710         proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "Metric: %u",
2711                             tvb_get_ntoh24(tvb, offset + 1));
2712         offset += 4;
2713
2714         /* Metric specific information, if any */
2715         while (offset < end_offset) {
2716             proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "%s: %u, Metric: %u",
2717                                 metric_type_str,
2718                                 tvb_get_guint8(tvb, offset),
2719                                 tvb_get_ntoh24(tvb, offset + 1));
2720             offset += 4;
2721         }
2722         break;
2723
2724     case OSPF_LSTYPE_ASEXT:
2725     case OSPF_LSTYPE_ASEXT7:
2726         proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "Netmask: %s",
2727                             tvb_ip_to_str(tvb, offset));
2728         offset += 4;
2729
2730         options = tvb_get_guint8(tvb, offset);
2731         if (options & 0x80) { /* check whether or not E bit is set */
2732             proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1,
2733                                 "External Type: Type 2 (metric is larger than any other link state path)");
2734         } else {
2735             proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1,
2736                                 "External Type: Type 1 (metric is specified in the same units as interface cost)");
2737         }
2738         /* the metric field of a AS-external LAS is specified in 3 bytes */
2739         proto_tree_add_text(ospf_lsa_tree, tvb, offset + 1, 3, "Metric: %u",
2740                             tvb_get_ntoh24(tvb, offset + 1));
2741         offset += 4;
2742
2743         proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "Forwarding Address: %s",
2744                             tvb_ip_to_str(tvb, offset));
2745         offset += 4;
2746
2747         proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "External Route Tag: %u",
2748                             tvb_get_ntohl(tvb, offset));
2749         offset += 4;
2750
2751         /* Metric specific information, if any */
2752         while (offset < end_offset) {
2753             options = tvb_get_guint8(tvb, offset);
2754             if (options & 0x80) { /* check whether or not E bit is set */
2755                 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1,
2756                                     "External Type: Type 2 (metric is larger than any other link state path)");
2757             } else {
2758                 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1,
2759                                     "External Type: Type 1 (metric is specified in the same units as interface cost)");
2760             }
2761             proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "%s: %u, Metric: %u",
2762                                 metric_type_str, options & 0x7F,
2763                                 tvb_get_ntoh24(tvb, offset + 1));
2764             offset += 4;
2765
2766             proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "Forwarding Address: %s",
2767                                 tvb_ip_to_str(tvb, offset));
2768             offset += 4;
2769
2770             proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "External Route Tag: %u",
2771                                 tvb_get_ntohl(tvb, offset));
2772             offset += 4;
2773         }
2774         break;
2775
2776     case OSPF_LSTYPE_OP_LINKLOCAL:
2777     case OSPF_LSTYPE_OP_AREALOCAL:
2778     case OSPF_LSTYPE_OP_ASWIDE:
2779         /*
2780          * RFC 2370 opaque LSAs.
2781          */
2782         dissect_ospf_lsa_opaque(tvb, offset, ospf_lsa_tree, ls_id_type,
2783                                 ls_length);
2784         offset += ls_length;
2785         break;
2786
2787     default:
2788         /* unknown LSA type */
2789         proto_tree_add_text(ospf_lsa_tree, tvb, offset, ls_length,
2790                             "Unknown LSA Type");
2791         offset += ls_length;
2792         break;
2793     }
2794     /* return the offset of the next LSA */
2795     return offset;
2796 }
2797
2798 static int
2799 dissect_ospf_v3_lsa(tvbuff_t *tvb, int offset, proto_tree *tree,
2800                     gboolean disassemble_body, guint8 address_family)
2801 {
2802     proto_tree *ospf_lsa_tree;
2803     proto_item *ti, *hidden_item;
2804
2805     guint16              ls_type;
2806     guint16              ls_length;
2807     int                  end_offset;
2808     guint8               reserved;
2809
2810     /* router LSA */
2811     guint8               link_type;
2812     const char          *link_type_str;
2813     guint32              metric;
2814
2815     guint8               router_priority;
2816     guint32              number_prefixes;
2817     guint8               prefix_length;
2818     guint16              reserved16;
2819
2820     guint16              referenced_ls_type;
2821
2822     guint8               flags;
2823     guint32              external_route_tag;
2824
2825
2826     ls_type = tvb_get_ntohs(tvb, offset + 2);
2827     ls_length = tvb_get_ntohs(tvb, offset + 18);
2828     end_offset = offset + ls_length;
2829
2830     if (disassemble_body) {
2831         ti = proto_tree_add_text(tree, tvb, offset, ls_length,
2832                                  "%s (Type: 0x%04x)", val_to_str_const(ls_type, v3_ls_type_vals,"Unknown"), ls_type);
2833     } else {
2834         ti = proto_tree_add_text(tree, tvb, offset, OSPF_LSA_HEADER_LENGTH,
2835                                  "LSA Header");
2836     }
2837     ospf_lsa_tree = proto_item_add_subtree(ti, ett_ospf_lsa);
2838
2839     proto_tree_add_text(ospf_lsa_tree, tvb, offset, 2, "LS Age: %u seconds",
2840                         tvb_get_ntohs(tvb, offset) & ~OSPF_DNA_LSA);
2841     proto_tree_add_text(ospf_lsa_tree, tvb, offset, 2, "Do Not Age: %s",
2842                         (tvb_get_ntohs(tvb, offset) & OSPF_DNA_LSA) ? "True" : "False");
2843
2844     proto_tree_add_item(ospf_lsa_tree, hf_ospf_filter[OSPFF_V3_LS_TYPE], tvb,
2845                         offset + 2, 2, ENC_BIG_ENDIAN);
2846     if (ospf_v3_ls_type_to_filter(ls_type) != -1) {
2847         hidden_item = proto_tree_add_item(ospf_lsa_tree,
2848                                           hf_ospf_filter[ospf_v3_ls_type_to_filter(ls_type)], tvb,
2849                                           offset + 2, 2, ENC_BIG_ENDIAN);
2850         PROTO_ITEM_SET_HIDDEN(hidden_item);
2851     }
2852
2853     proto_tree_add_text(ospf_lsa_tree, tvb, offset + 4, 4, "Link State ID: %s",
2854                         tvb_ip_to_str(tvb, offset + 4));
2855
2856     proto_tree_add_item(ospf_lsa_tree, hf_ospf_filter[OSPFF_ADV_ROUTER],
2857                         tvb, offset + 8, 4, ENC_BIG_ENDIAN);
2858     proto_tree_add_text(ospf_lsa_tree, tvb, offset + 12, 4, "LS Sequence Number: 0x%08x",
2859                         tvb_get_ntohl(tvb, offset + 12));
2860     proto_tree_add_text(ospf_lsa_tree, tvb, offset + 16, 2, "LS Checksum: 0x%04x",
2861                         tvb_get_ntohs(tvb, offset + 16));
2862
2863     proto_tree_add_text(ospf_lsa_tree, tvb, offset + 18, 2, "Length: %u",
2864                         ls_length);
2865
2866     /* skip past the LSA header to the body */
2867     offset += OSPF_LSA_HEADER_LENGTH;
2868     ls_length -= OSPF_LSA_HEADER_LENGTH;
2869
2870     if (!disassemble_body)
2871         return offset;
2872
2873     switch (ls_type){
2874
2875
2876     case OSPF_V3_LSTYPE_ROUTER:
2877         /* flags field in an router-lsa */
2878         dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset, &bfinfo_v3_router_lsa_flags);
2879
2880         /* options field in an router-lsa */
2881         dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset + 1, &bfinfo_v3_options);
2882
2883         /* skip the router-lsa flags and options */
2884         offset+=4;
2885         ls_length-=4;
2886
2887         if (ls_length > 0)
2888             proto_tree_add_text(ospf_lsa_tree, tvb, offset, ls_length,
2889                                 "Router Interfaces:");
2890
2891         /* scan all router-lsa router interfaces */
2892         /* maybe we should put each of the links into its own subtree ??? */
2893         while (ls_length > 0 ) {
2894
2895             /* check the type */
2896             link_type = tvb_get_guint8(tvb, offset);
2897             switch (link_type) {
2898
2899             case OSPF_V3_LINK_PTP:
2900                 link_type_str="Point-to-point connection to another router";
2901                 break;
2902
2903             case OSPF_V3_LINK_TRANSIT:
2904                 link_type_str="Connection to a transit network";
2905                 break;
2906
2907             case OSPF_V3_LINK_RESERVED:
2908                 link_type_str="Connection to a stub network";
2909                 break;
2910
2911             case OSPF_V3_LINK_VIRTUAL:
2912                 link_type_str="Virtual link";
2913                 break;
2914
2915             default:
2916                 link_type_str="Unknown link type";
2917                 break;
2918             }
2919
2920             proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1, "Type: %u (%s)", link_type,link_type_str);
2921
2922             /* reserved field */
2923             reserved = tvb_get_guint8(tvb, offset+1);
2924             proto_tree_add_text(ospf_lsa_tree, tvb, offset+1, 1,
2925                                 (reserved == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),reserved);
2926
2927             /* metric */
2928             metric=tvb_get_ntohs(tvb, offset+2);
2929             proto_tree_add_text(ospf_lsa_tree, tvb, offset + 2, 2,"Metric: %u",metric);
2930
2931             /* Interface ID */
2932             proto_tree_add_text(ospf_lsa_tree, tvb, offset + 4, 4, "Interface ID: %u",
2933                                 tvb_get_ntohl(tvb, offset + 4));
2934
2935             /* Neighbor Interface ID */
2936             proto_tree_add_text(ospf_lsa_tree, tvb, offset + 8, 4, "Neighbor Interface ID: %u",
2937                                 tvb_get_ntohl(tvb, offset + 8));
2938
2939             /* Neighbor Router ID */
2940             proto_tree_add_text(ospf_lsa_tree, tvb, offset + 12, 4, "Neighbor Router ID: %s",
2941                                 tvb_ip_to_str(tvb, offset + 12));
2942
2943             /* skip to the (possible) next entry */
2944             offset+=16;
2945             ls_length-=16;
2946
2947         }
2948         break;
2949
2950     case OSPF_V3_LSTYPE_NETWORK:
2951
2952         /* reserved field */
2953         reserved = tvb_get_guint8(tvb, offset);
2954         proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1,
2955                             (reserved == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),reserved);
2956
2957         /* options field in an network-lsa */
2958         dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset + 1, &bfinfo_v3_options);
2959
2960         offset += 4;
2961         ls_length-=4;
2962
2963         while (ls_length > 0 ) {
2964             proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "Attached Router: %s",
2965                                 tvb_ip_to_str(tvb, offset));
2966             ls_length-=4;
2967             offset += 4;
2968         }
2969         break;
2970
2971
2972     case OSPF_V3_LSTYPE_INTER_AREA_PREFIX:
2973
2974         /* reserved field */
2975         reserved = tvb_get_guint8(tvb, offset);
2976         proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1,
2977                             (reserved == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),reserved);
2978
2979         /* metric */
2980         metric=tvb_get_ntoh24(tvb, offset+1);
2981         proto_tree_add_text(ospf_lsa_tree, tvb, offset + 1, 3,"Metric: %u",metric);
2982
2983         /* prefix length */
2984         prefix_length=tvb_get_guint8(tvb, offset+4);
2985         proto_tree_add_text(ospf_lsa_tree, tvb, offset+4, 1, "PrefixLength: %u",prefix_length);
2986
2987         /* prefix options */
2988         dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset+5, &bfinfo_v3_prefix_options);
2989
2990         /* 16 bits reserved */
2991         reserved16=tvb_get_ntohs(tvb, offset+6);
2992         proto_tree_add_text(ospf_lsa_tree, tvb, offset+6, 2,
2993                             (reserved16 == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),reserved16);
2994
2995         offset+=8;
2996
2997         /* address_prefix */
2998         dissect_ospf_v3_address_prefix(tvb, offset, prefix_length, ospf_lsa_tree, address_family);
2999
3000         offset+=(prefix_length+31)/32*4;
3001
3002         break;
3003
3004
3005     case OSPF_V3_LSTYPE_INTER_AREA_ROUTER:
3006
3007         /* reserved field */
3008         reserved = tvb_get_guint8(tvb, offset);
3009         proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1,
3010                             (reserved == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),reserved);
3011
3012         /* options field in an inter-area-router-lsa */
3013         dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset + 1, &bfinfo_v3_options);
3014
3015         /* reserved field */
3016         reserved = tvb_get_guint8(tvb, offset+4);
3017         proto_tree_add_text(ospf_lsa_tree, tvb, offset+4, 1,
3018                             (reserved == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),reserved);
3019
3020         /* metric */
3021         metric=tvb_get_ntoh24(tvb, offset+5);
3022         proto_tree_add_text(ospf_lsa_tree, tvb, offset + 5, 3,"Metric: %u",metric);
3023
3024         /* Destination Router ID */
3025         proto_tree_add_text(ospf_lsa_tree, tvb, offset + 8, 4, "Destination Router ID: %s",
3026                             tvb_ip_to_str(tvb, offset + 8));
3027
3028         offset+=12;
3029         break;
3030
3031
3032     case OSPF_V3_LSTYPE_NSSA:
3033     case OSPF_V3_LSTYPE_AS_EXTERNAL:
3034
3035         /* flags */
3036         dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset, &bfinfo_v3_as_external_flags);
3037         flags=tvb_get_guint8(tvb, offset);
3038
3039         /* 24 bits metric */
3040         metric=tvb_get_ntoh24(tvb, offset+1);
3041         proto_tree_add_text(ospf_lsa_tree, tvb, offset+1, 3,
3042                             "Metric: %u", metric);
3043
3044         /* prefix length */
3045         prefix_length=tvb_get_guint8(tvb, offset+4);
3046         proto_tree_add_text(ospf_lsa_tree, tvb, offset+4, 1, "PrefixLength: %u",prefix_length);
3047
3048         /* prefix options */
3049         dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset+5, &bfinfo_v3_prefix_options);
3050
3051         /* referenced LS type */
3052         referenced_ls_type=tvb_get_ntohs(tvb, offset+6);
3053         proto_tree_add_text(ospf_lsa_tree, tvb, offset+6, 2,"Referenced LS type 0x%04x (%s)",
3054                             referenced_ls_type, val_to_str_const(referenced_ls_type, v3_ls_type_vals, "Unknown"));
3055
3056         offset+=8;
3057
3058         /* address_prefix */
3059         dissect_ospf_v3_address_prefix(tvb, offset, prefix_length, ospf_lsa_tree, address_family);
3060
3061         offset+=(prefix_length+31)/32*4;
3062
3063         /* Forwarding Address (optional - only if F-flag is on) */
3064         if ( (offset < end_offset) && (flags & OSPF_V3_AS_EXTERNAL_FLAG_F) ) {
3065             if (address_family == OSPF_AF_6) {
3066                 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 16,"Forwarding Address: %s",
3067                                     tvb_ip6_to_str(tvb, offset));
3068             } else {
3069                 proto_tree_add_text(ospf_lsa_tree, tvb, offset, 16,"Forwarding Address: %s",
3070                                     tvb_ip_to_str(tvb, offset));
3071             }
3072
3073             offset+=16;
3074         }
3075
3076         /* External Route Tag (optional - only if T-flag is on) */
3077         if ( (offset < end_offset) && (flags & OSPF_V3_AS_EXTERNAL_FLAG_T) ) {
3078             external_route_tag=tvb_get_ntohl(tvb, offset);
3079             proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4,"External Route Tag: %u",
3080                                 external_route_tag);
3081
3082             offset+=4;
3083         }
3084
3085         /* Referenced Link State ID (optional - only if Referenced LS type is non-zero */
3086         if ( (offset < end_offset) && (referenced_ls_type != 0) ) {
3087             proto_tree_add_text(ospf_lsa_tree, tvb, offset, 4, "Referenced Link State ID: %s",
3088                                 tvb_ip_to_str(tvb, offset));
3089             offset+=4;
3090         }
3091
3092         break;
3093
3094     case OSPF_V3_LSTYPE_LINK:
3095
3096         /* router priority */
3097         router_priority=tvb_get_guint8(tvb, offset);
3098         proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1, "Router Priority: %u", router_priority);
3099
3100         /* options field in an link-lsa */
3101         dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset + 1, &bfinfo_v3_options);
3102
3103         /* Link-local Interface Address */
3104         if (address_family == OSPF_AF_6) {
3105             proto_tree_add_text(ospf_lsa_tree, tvb, offset + 4, 16, "Link-local Interface Address: %s",
3106                                 tvb_ip6_to_str(tvb, offset + 4));
3107         } else {
3108             proto_tree_add_text(ospf_lsa_tree, tvb, offset + 4, 16, "Link-local Interface Address: %s",
3109                                 tvb_ip_to_str(tvb, offset + 4));
3110         }
3111         /* Number prefixes */
3112         number_prefixes=tvb_get_ntohl(tvb, offset + 20);
3113         proto_tree_add_text(ospf_lsa_tree, tvb, offset+20, 4, "# prefixes: %d",number_prefixes);
3114
3115         offset+=24;
3116
3117         while (number_prefixes > 0) {
3118
3119             /* prefix length */
3120             prefix_length=tvb_get_guint8(tvb, offset);
3121             proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1, "PrefixLength: %u",prefix_length);
3122
3123             /* prefix options */
3124             dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset+1, &bfinfo_v3_prefix_options);
3125
3126             /* 16 bits reserved */
3127             reserved16=tvb_get_ntohs(tvb, offset+2);
3128             proto_tree_add_text(ospf_lsa_tree, tvb, offset+2, 2,
3129                                 (reserved16 == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"),reserved16);
3130
3131             offset+=4;
3132
3133             /* address_prefix */
3134             dissect_ospf_v3_address_prefix(tvb, offset, prefix_length, ospf_lsa_tree, address_family);
3135
3136             offset+=(prefix_length+31)/32*4;
3137
3138             number_prefixes--;
3139
3140         }
3141         break;
3142
3143     case OSPF_V3_LSTYPE_INTRA_AREA_PREFIX:
3144
3145         /* # prefixes */
3146         number_prefixes=tvb_get_ntohs(tvb, offset);
3147         proto_tree_add_text(ospf_lsa_tree, tvb, offset, 2,"# prefixes: %u",number_prefixes);
3148
3149         /* referenced LS type */
3150         referenced_ls_type=tvb_get_ntohs(tvb, offset+2);
3151         proto_tree_add_text(ospf_lsa_tree, tvb, offset+2, 2,"Referenced LS type 0x%04x (%s)",
3152                             referenced_ls_type, val_to_str_const(referenced_ls_type, v3_ls_type_vals, "Unknown"));
3153
3154         /* Referenced Link State ID */
3155         proto_tree_add_text(ospf_lsa_tree, tvb, offset + 4, 4, "Referenced Link State ID: %s",
3156                             tvb_ip_to_str(tvb, offset + 4));
3157
3158         /* Referenced Advertising Router */
3159         proto_tree_add_text(ospf_lsa_tree, tvb, offset + 8, 4, "Referenced Advertising Router: %s",
3160                             tvb_ip_to_str(tvb, offset + 8));
3161
3162         offset+=12;
3163
3164         while (number_prefixes > 0) {
3165
3166             /* prefix length */
3167             prefix_length=tvb_get_guint8(tvb, offset);
3168             proto_tree_add_text(ospf_lsa_tree, tvb, offset, 1, "PrefixLength: %u",prefix_length);
3169
3170             /* prefix options */
3171             dissect_ospf_bitfield(ospf_lsa_tree, tvb, offset+1, &bfinfo_v3_prefix_options);
3172
3173             /* 16 bits metric */
3174             metric=tvb_get_ntohs(tvb, offset+2);
3175             proto_tree_add_text(ospf_lsa_tree, tvb, offset+2, 2,
3176                                 "Metric: %u", metric);
3177
3178             offset+=4;
3179
3180             /* address_prefix */
3181             dissect_ospf_v3_address_prefix(tvb, offset, prefix_length, ospf_lsa_tree, address_family);
3182
3183             offset+=(prefix_length+31)/32*4;
3184
3185             number_prefixes--;
3186         }
3187         break;
3188
3189     case OSPF_V3_LSTYPE_OPAQUE_RI:
3190         dissect_ospf_lsa_opaque_ri(tvb, offset, ospf_lsa_tree, ls_length);
3191         break;
3192
3193     default:
3194         /* unknown LSA type */
3195         proto_tree_add_text(ospf_lsa_tree, tvb, offset, ls_length,
3196                             "Unknown LSA Type 0x%04x",ls_type);
3197         offset += ls_length;
3198         break;
3199     }
3200     /* return the offset of the next LSA */
3201     return offset;
3202 }
3203
3204 static void dissect_ospf_v3_address_prefix(tvbuff_t *tvb, int offset, int prefix_length, proto_tree *tree,
3205                                            guint8 address_family)
3206 {
3207
3208     int bytes_to_process;
3209     struct e_in6_addr prefix;
3210
3211     bytes_to_process=((prefix_length+31)/32)*4;
3212
3213     if (prefix_length > 128) {
3214         proto_tree_add_text(tree, tvb, offset, bytes_to_process,
3215             "Address Prefix: length is invalid (%d, should be <= 128)",
3216             prefix_length);
3217         return;
3218     }
3219
3220     memset(prefix.bytes, 0, sizeof prefix.bytes);
3221     if (bytes_to_process != 0) {
3222         tvb_memcpy(tvb, prefix.bytes, offset, bytes_to_process);
3223         if (prefix_length % 8) {
3224             prefix.bytes[bytes_to_process - 1] &=
3225                 ((0xff00 >> (prefix_length % 8)) & 0xff);
3226         }
3227     }
3228     if (address_family == OSPF_AF_6) {
3229         proto_tree_add_text(tree, tvb, offset, bytes_to_process,
3230                             "Address Prefix: %s", ip6_to_str(&prefix));
3231     } else {
3232         proto_tree_add_text(tree, tvb, offset, bytes_to_process,
3233                             "Address Prefix: %s", tvb_ip_to_str(tvb, offset));
3234     }
3235
3236 }
3237
3238
3239 void
3240 proto_register_ospf(void)
3241 {
3242     static hf_register_info ospff_info[] = {
3243
3244         {&hf_ospf_header,
3245          { "OSPF Header", "ospf.header", FT_NONE, BASE_NONE, NULL, 0x0,
3246            NULL, HFILL }},
3247         {&hf_ospf_header_version,
3248          { "Version", "ospf.version", FT_UINT8, BASE_DEC, NULL, 0x0,
3249            NULL, HFILL }},
3250         /* Message type number */
3251         {&hf_ospf_header_msg_type,
3252          { "Message Type", "ospf.msg", FT_UINT8, BASE_DEC, VALS(pt_vals), 0x0,
3253            NULL, HFILL }},
3254         {&hf_ospf_header_packet_length,
3255          { "Packet Length", "ospf.packet_length", FT_UINT16, BASE_DEC, NULL, 0x0,
3256            NULL, HFILL }},
3257         {&hf_ospf_header_src_router,
3258          { "Source OSPF Router", "ospf.srcrouter", FT_IPv4, BASE_NONE, NULL, 0x0,
3259            NULL, HFILL }},
3260         {&hf_ospf_header_area_id,
3261          { "Area ID", "ospf.area_id", FT_IPv4, BASE_NONE, NULL, 0x0,
3262            NULL, HFILL }},
3263         {&hf_ospf_header_checksum,
3264          { "Checksum", "ospf.checksum", FT_UINT16, BASE_HEX, NULL, 0x0,
3265            NULL, HFILL }},
3266         /* OSPF Header v2 (Auth) */
3267         {&hf_ospf_header_auth_type,
3268          { "Auth Type", "ospf.auth.type", FT_UINT16, BASE_DEC, VALS(auth_vals), 0x0,
3269            NULL, HFILL }},
3270         {&hf_ospf_header_auth_data_none,
3271          { "Auth Data (none)", "ospf.auth.none", FT_BYTES, BASE_NONE, NULL, 0x0,
3272            NULL, HFILL }},
3273         {&hf_ospf_header_auth_data_simple,
3274          { "Auth Data (Simple)", "ospf.auth.simple", FT_STRING, BASE_NONE, NULL, 0x0,
3275            NULL, HFILL }},
3276         {&hf_ospf_header_auth_crypt_key_id,
3277          { "Auth Crypt Key id", "ospf.auth.crypt.key_id", FT_UINT8, BASE_DEC, NULL, 0x0,
3278            NULL, HFILL }},
3279         {&hf_ospf_header_auth_crypt_data_length,
3280          { "Auth Crypt Data Length", "ospf.auth.crypt.data_length", FT_UINT8, BASE_DEC, NULL, 0x0,
3281            NULL, HFILL }},
3282         {&hf_ospf_header_auth_crypt_seq_nbr,
3283          { "Auth Crypt Sequence Number", "ospf.auth.crypt.seq_nbr", FT_UINT32, BASE_DEC, NULL, 0x0,
3284            NULL, HFILL }},
3285         {&hf_ospf_header_auth_crypt_data,
3286          { "Auth Crypt Data", "ospf.auth.crypt.data", FT_BYTES, BASE_NONE, NULL, 0x0,
3287            NULL, HFILL }},
3288         {&hf_ospf_header_auth_data_unknown,
3289          { "Auth Unknown", "ospf.auth.unknown", FT_BYTES, BASE_NONE, NULL, 0x0,
3290            NULL, HFILL }},
3291
3292         /* OSPF Header v3 */
3293         {&hf_ospf_header_instance_id,
3294          { "Instance ID", "ospf.instance_id", FT_UINT8, BASE_RANGE_STRING | BASE_DEC, RVALS(ospf_instance_id_rvals), 0x0,
3295            NULL, HFILL }},
3296         {&hf_ospf_header_reserved,
3297          { "Reserved", "ospf.reserved", FT_BYTES, BASE_NONE, NULL, 0x0,
3298            "Must be zero", HFILL }},
3299
3300         /* Message types */
3301         {&hf_ospf_filter[OSPFF_MSG_HELLO],
3302          { "Hello", "ospf.msg.hello", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3303            NULL, HFILL }},
3304         {&hf_ospf_filter[OSPFF_MSG_DB_DESC],
3305          { "Database Description", "ospf.msg.dbdesc", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3306            NULL, HFILL }},
3307         {&hf_ospf_filter[OSPFF_MSG_LS_REQ],
3308          { "Link State Adv Request", "ospf.msg.lsreq", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3309            NULL, HFILL }},
3310         {&hf_ospf_filter[OSPFF_MSG_LS_UPD],
3311          { "Link State Adv Update", "ospf.msg.lsupdate", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3312            NULL, HFILL }},
3313         {&hf_ospf_filter[OSPFF_MSG_LS_ACK],
3314          { "Link State Adv Acknowledgement", "ospf.msg.lsack", FT_BOOLEAN,
3315            BASE_NONE, NULL, 0x0, NULL, HFILL }},
3316
3317         /* Hello Packet */
3318         {&hf_ospf_hello,
3319          { "OSPF Hello Packet", "ospf.hello", FT_NONE,
3320            BASE_NONE, NULL, 0x0, NULL, HFILL }},
3321         {&hf_ospf_hello_network_mask,
3322          { "Network Mask", "ospf.hello.network_mask", FT_IPv4,
3323            BASE_NONE, NULL, 0x0, NULL, HFILL }},
3324         {&hf_ospf_hello_interface_id,
3325          { "Interface ID", "ospf.hello.interface_id", FT_UINT32,
3326            BASE_DEC, NULL, 0x0, NULL, HFILL }},
3327         {&hf_ospf_hello_hello_interval,
3328          { "Hello Interval [sec]", "ospf.hello.hello_interval", FT_UINT32,
3329            BASE_DEC, NULL, 0x0, NULL, HFILL }},
3330         {&hf_ospf_hello_router_priority,
3331          { "Router Priority", "ospf.hello.router_priority", FT_UINT8,
3332            BASE_DEC, NULL, 0x0, NULL, HFILL }},
3333         {&hf_ospf_hello_router_dead_interval,
3334          { "Router Dead Interval [sec]", "ospf.hello.router_dead_interval", FT_UINT32,
3335            BASE_DEC, NULL, 0x0, NULL, HFILL }},
3336         {&hf_ospf_hello_designated_router,
3337          { "Designated Router", "ospf.hello.designated_router", FT_IPv4,
3338            BASE_NONE, NULL, 0x0, NULL, HFILL }},
3339         {&hf_ospf_hello_backup_designated_router,
3340          { "Backup Designated Router", "ospf.hello.backup_designated_router", FT_IPv4,
3341            BASE_NONE, NULL, 0x0, NULL, HFILL }},
3342         {&hf_ospf_hello_active_neighbor,
3343          { "Active Neighbor", "ospf.hello.active_neighbor", FT_IPv4,
3344            BASE_NONE, NULL, 0x0, NULL, HFILL }},
3345
3346         /* LS Types */
3347         {&hf_ospf_filter[OSPFF_LS_TYPE],
3348          { "LS Type", "ospf.lsa", FT_UINT8, BASE_DEC,
3349            VALS(ls_type_vals), 0x0, NULL, HFILL }},
3350         {&hf_ospf_filter[OSPFF_LS_OPAQUE_TYPE],
3351          { "Link State ID Opaque Type", "ospf.lsid_opaque_type", FT_UINT8, BASE_DEC,
3352            VALS(ls_opaque_type_vals), 0x0, NULL, HFILL }},
3353
3354         {&hf_ospf_filter[OSPFF_LS_MPLS_TE_INSTANCE],
3355          { "Link State ID TE-LSA Instance", "ospf.lsid_te_lsa.instance", FT_UINT16, BASE_DEC,
3356            NULL, 0x0, NULL, HFILL }},
3357
3358         {&hf_ospf_filter[OSPFF_LS_ROUTER],
3359          { "Router LSA", "ospf.lsa.router", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3360            NULL, HFILL }},
3361         {&hf_ospf_filter[OSPFF_LS_ROUTER_LINKTYPE],
3362          { "Link Type", "ospf.lsa.router.linktype", FT_UINT8, BASE_DEC, NULL, 0x0,
3363            NULL, HFILL }},
3364         {&hf_ospf_filter[OSPFF_LS_ROUTER_LINKID],
3365          { "Link ID", "ospf.lsa.router.linkid", FT_IPv4, BASE_NONE, NULL, 0x0,
3366            NULL, HFILL }},
3367         {&hf_ospf_filter[OSPFF_LS_ROUTER_LINKDATA],
3368          { "Link Data", "ospf.lsa.router.linkdata", FT_IPv4, BASE_NONE, NULL, 0x0,
3369            NULL, HFILL }},
3370
3371         {&hf_ospf_filter[OSPFF_LS_NETWORK],
3372          { "Network LSA", "ospf.lsa.network", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3373            NULL, HFILL }},
3374         {&hf_ospf_filter[OSPFF_LS_SUMMARY],
3375          { "Summary LSA (IP Network)", "ospf.lsa.summary", FT_BOOLEAN, BASE_NONE,
3376            NULL, 0x0, NULL, HFILL }},
3377         {&hf_ospf_filter[OSPFF_LS_ASBR],
3378          { "Summary LSA (ASBR)", "ospf.lsa.asbr", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3379            NULL, HFILL }},
3380         {&hf_ospf_filter[OSPFF_LS_ASEXT],
3381          { "AS-External LSA (ASBR)", "ospf.lsa.asext", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3382            NULL, HFILL }},
3383         {&hf_ospf_filter[OSPFF_LS_GRPMEMBER],
3384          { "Group Membership LSA", "ospf.lsa.member", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3385            NULL, HFILL }},
3386         {&hf_ospf_filter[OSPFF_LS_ASEXT7],
3387          { "NSSA AS-External LSA", "ospf.lsa.nssa", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3388            NULL, HFILL }},
3389         {&hf_ospf_filter[OSPFF_LS_EXTATTR],
3390          { "External Attributes LSA", "ospf.lsa.attr", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3391            NULL, HFILL }},
3392         {&hf_ospf_filter[OSPFF_LS_OPAQUE],
3393          { "Opaque LSA", "ospf.lsa.opaque", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3394            NULL, HFILL }},
3395
3396         /* OSPFv3 LS Types */
3397         {&hf_ospf_filter[OSPFF_V3_LS_TYPE],
3398          { "LS Type", "ospf.v3.lsa", FT_UINT16, BASE_HEX,
3399            VALS(v3_ls_type_vals), 0x0, NULL, HFILL }},
3400
3401         {&hf_ospf_filter[OSPFF_V3_LS_ROUTER],
3402          { "Router-LSA", "ospf.v3.lsa.router", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3403            NULL, HFILL }},
3404         {&hf_ospf_filter[OSPFF_V3_LS_NETWORK],
3405          { "Network-LSA", "ospf.v3.lsa.network", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3406            NULL, HFILL }},
3407         {&hf_ospf_filter[OSPFF_V3_LS_INTER_AREA_PREFIX],
3408          { "Inter-Area-Prefix-LSA", "ospf.v3.lsa.interprefix", FT_BOOLEAN, BASE_NONE,
3409            NULL, 0x0, NULL, HFILL }},
3410         {&hf_ospf_filter[OSPFF_V3_LS_INTER_AREA_ROUTER],
3411          { "Inter-Area-Router-LSA", "ospf.v3.lsa.interrouter", FT_BOOLEAN, BASE_NONE,
3412            NULL, 0x0, NULL, HFILL }},
3413         {&hf_ospf_filter[OSPFF_V3_LS_AS_EXTERNAL],
3414          { "AS-External-LSA", "ospf.v3.lsa.asext", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3415            NULL, HFILL }},
3416         {&hf_ospf_filter[OSPFF_V3_LS_GROUP_MEMBERSHIP],
3417          { "Group-Membership-LSA", "ospf.v3.lsa.member", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3418            NULL, HFILL }},
3419         {&hf_ospf_filter[OSPFF_V3_LS_NSSA],
3420          { "NSSA-LSA", "ospf.v3.lsa.nssa", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3421            NULL, HFILL }},
3422         {&hf_ospf_filter[OSPFF_V3_LS_LINK],
3423          { "Link-LSA", "ospf.v3.lsa.link", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3424            NULL, HFILL }},
3425         {&hf_ospf_filter[OSPFF_V3_LS_INTRA_AREA_PREFIX],
3426          { "Intra-Area-Prefix-LSA", "ospf.v3.lsa.intraprefix", FT_BOOLEAN, BASE_NONE,
3427            NULL, 0x0, NULL, HFILL }},
3428         {&hf_ospf_filter[OSPFF_V3_LS_OPAQUE_RI],
3429          { "Router Information Opaque-LSA", "ospf.v3.lsa.opaque", FT_BOOLEAN, BASE_NONE,
3430            NULL, 0x0, NULL, HFILL }},
3431
3432         /* Other interesting OSPF values */
3433
3434         {&hf_ospf_filter[OSPFF_ADV_ROUTER],
3435          { "Advertising Router", "ospf.advrouter", FT_IPv4, BASE_NONE, NULL, 0x0,
3436            NULL, HFILL }},
3437
3438         {&hf_ospf_filter[OSPFF_LS_MPLS],
3439          { "MPLS Traffic Engineering LSA", "ospf.lsa.mpls", FT_BOOLEAN,
3440            BASE_NONE, NULL, 0x0, NULL, HFILL }},
3441
3442         {&hf_ospf_filter[OSPFF_LS_MPLS_ROUTERID],
3443          { "MPLS/TE Router ID", "ospf.mpls.routerid", FT_IPv4, BASE_NONE, NULL, 0x0,
3444            NULL, HFILL }},
3445
3446         {&hf_ospf_filter[OSPFF_LS_MPLS_LINKTYPE],
3447          { "MPLS/TE Link Type", "ospf.mpls.linktype", FT_UINT8, BASE_DEC,
3448            VALS(mpls_link_stlv_ltype_str), 0x0, NULL, HFILL }},
3449         {&hf_ospf_filter[OSPFF_LS_MPLS_LINKID],
3450          { "MPLS/TE Link ID", "ospf.mpls.linkid", FT_IPv4, BASE_NONE, NULL, 0x0,
3451            NULL, HFILL }},
3452         {&hf_ospf_filter[OSPFF_LS_MPLS_LOCAL_ADDR],
3453          { "MPLS/TE Local Interface Address", "ospf.mpls.local_addr", FT_IPv4,
3454            BASE_NONE, NULL, 0x0, NULL, HFILL }},
3455         {&hf_ospf_filter[OSPFF_LS_MPLS_REMOTE_ADDR],
3456          { "MPLS/TE Remote Interface Address", "ospf.mpls.remote_addr", FT_IPv4,
3457            BASE_NONE, NULL, 0x0, NULL, HFILL }},
3458         {&hf_ospf_filter[OSPFF_LS_MPLS_LOCAL_IFID],
3459          { "MPLS/TE Local Interface Index", "ospf.mpls.local_id", FT_UINT32,
3460            BASE_DEC, NULL, 0x0, NULL, HFILL }},
3461         {&hf_ospf_filter[OSPFF_LS_MPLS_REMOTE_IFID],
3462          { "MPLS/TE Remote Interface Index", "ospf.mpls.remote_id", FT_UINT32,
3463            BASE_DEC, NULL, 0x0, NULL, HFILL }},
3464         {&hf_ospf_filter[OSPFF_LS_MPLS_LINKCOLOR],
3465          { "MPLS/TE Link Resource Class/Color", "ospf.mpls.linkcolor", FT_UINT32,
3466            BASE_HEX, NULL, 0x0, NULL, HFILL }},
3467         {&hf_ospf_filter[OSPFF_LS_MPLS_BC_MODEL_ID],
3468          { "MPLS/DSTE Bandwidth Constraints Model Id", "ospf.mpls.bc", FT_UINT8,
3469            BASE_RANGE_STRING | BASE_DEC, RVALS(mpls_link_stlv_bcmodel_rvals), 0x0,
3470            NULL, HFILL }},
3471
3472         {&hf_ospf_filter[OSPFF_LS_OIF_LOCAL_NODE_ID],
3473          { "Local Node ID", "ospf.oif.local_node_id", FT_IPv4,
3474            BASE_NONE, NULL, 0x0, NULL, HFILL }},
3475         {&hf_ospf_filter[OSPFF_LS_OIF_REMOTE_NODE_ID],
3476          { "Remote Node ID", "ospf.oif.remote_node_id", FT_IPv4,
3477            BASE_NONE, NULL, 0x0, NULL, HFILL }},
3478
3479         {&hf_ospf_filter[OSPFF_V2_OPTIONS],
3480          { "Options", "ospf.v2.options", FT_UINT8, BASE_HEX,
3481            NULL, 0x0, NULL, HFILL }},
3482         {&hf_ospf_filter[OSPFF_V2_OPTIONS_MT],
3483          { "MT", "ospf.v2.options.mt", FT_BOOLEAN, 8,
3484            TFS(&tfs_v2_options_mt), OSPF_V2_OPTIONS_MT, NULL, HFILL }},
3485         {&hf_ospf_filter[OSPFF_V2_OPTIONS_E],
3486          { "E", "ospf.v2.options.e", FT_BOOLEAN, 8,
3487            TFS(&tfs_v2_options_e), OSPF_V2_OPTIONS_E, NULL, HFILL }},
3488         {&hf_ospf_filter[OSPFF_V2_OPTIONS_MC],
3489          { "MC", "ospf.v2.options.mc", FT_BOOLEAN, 8,
3490            TFS(&tfs_v2_options_mc), OSPF_V2_OPTIONS_MC, NULL, HFILL }},
3491         {&hf_ospf_filter[OSPFF_V2_OPTIONS_NP],
3492          { "NP", "ospf.v2.options.np", FT_BOOLEAN, 8,
3493            TFS(&tfs_v2_options_np), OSPF_V2_OPTIONS_NP, NULL, HFILL }},
3494         {&hf_ospf_filter[OSPFF_V2_OPTIONS_L],
3495          { "L", "ospf.v2.options.l", FT_BOOLEAN, 8,
3496            TFS(&tfs_v2_options_l), OSPF_V2_OPTIONS_L, NULL, HFILL }},
3497         {&hf_ospf_filter[OSPFF_V2_OPTIONS_DC],
3498          { "DC", "ospf.v2.options.dc", FT_BOOLEAN, 8,
3499            TFS(&tfs_v2_options_dc), OSPF_V2_OPTIONS_DC, NULL, HFILL }},
3500         {&hf_ospf_filter[OSPFF_V2_OPTIONS_O],
3501          { "O", "ospf.v2.options.o", FT_BOOLEAN, 8,
3502            TFS(&tfs_set_notset), OSPF_V2_OPTIONS_O, NULL, HFILL }},
3503         {&hf_ospf_filter[OSPFF_V2_OPTIONS_DN],
3504          { "DN", "ospf.v2.options.dn", FT_BOOLEAN, 8,
3505            TFS(&tfs_set_notset), OSPF_V2_OPTIONS_DN, NULL, HFILL }},
3506
3507         {&hf_ospf_filter[OSPFF_RI_OPTIONS],
3508          { "RI Options", "ospf.ri.options", FT_UINT8, BASE_HEX,
3509            NULL, 0x0, NULL, HFILL }},
3510         {&hf_ospf_filter[OSPFF_RI_OPTIONS_GRC],
3511          { "GRC", "ospf.ri.options.grc", FT_BOOLEAN, 8,
3512            TFS(&tfs_ri_options_grc), OSPF_RI_OPTIONS_GRC, NULL, HFILL }},
3513         {&hf_ospf_filter[OSPFF_RI_OPTIONS_GRH],
3514          { "GRH", "ospf.ri.options.grh", FT_BOOLEAN, 8,
3515            TFS(&tfs_ri_options_grh), OSPF_RI_OPTIONS_GRH, NULL, HFILL }},
3516         {&hf_ospf_filter[OSPFF_RI_OPTIONS_SRS],
3517          { "SRS", "ospf.ri.options.srs", FT_BOOLEAN, 8,
3518            TFS(&tfs_ri_options_srs), OSPF_RI_OPTIONS_SRS, NULL, HFILL }},
3519         {&hf_ospf_filter[OSPFF_RI_OPTIONS_TES],
3520          { "TES", "ospf.ri.options.tes", FT_BOOLEAN, 8,
3521            TFS(&tfs_ri_options_tes), OSPF_RI_OPTIONS_TES, NULL, HFILL }},
3522         {&hf_ospf_filter[OSPFF_RI_OPTIONS_P2PLAN],
3523          { "P2PLAN", "ospf.ri.options.p2plan", FT_BOOLEAN, 8,
3524            TFS(&tfs_ri_options_p2plan), OSPF_RI_OPTIONS_P2PLAN, NULL, HFILL }},
3525         {&hf_ospf_filter[OSPFF_RI_OPTIONS_ETE],
3526          { "ETE", "ospf.ri.options.ete", FT_BOOLEAN, 8,
3527            TFS(&tfs_ri_options_ete), OSPF_RI_OPTIONS_ETE, NULL, HFILL }},
3528
3529         /* An MBZ field for the 24-bits of type field of Opaque RI LSA */
3530         {&hf_ospf_filter[OSPFF_OPAQUE_LSA_MBZ],
3531          { "MBZ", "ospf.ri.mbz", FT_UINT16, BASE_HEX,
3532             NULL, 0x0, "OSPF Opaque RI LSA - 24 bits of Type Field Must be Zero", HFILL }},
3533
3534         {&hf_ospf_filter[OSPFF_V3_OPTIONS],
3535          { "Options", "ospf.v3.options", FT_UINT24, BASE_HEX,
3536            NULL, 0x0, NULL, HFILL }},
3537         {&hf_ospf_filter[OSPFF_V3_OPTIONS_V6],
3538          { "V6", "ospf.v3.options.v6", FT_BOOLEAN, 24,
3539            TFS(&tfs_set_notset), OSPF_V3_OPTIONS_V6, NULL, HFILL }},
3540         {&hf_ospf_filter[OSPFF_V3_OPTIONS_E],
3541          { "E", "ospf.v3.options.e", FT_BOOLEAN, 24,
3542            TFS(&tfs_set_notset), OSPF_V3_OPTIONS_E, NULL, HFILL }},
3543         {&hf_ospf_filter[OSPFF_V3_OPTIONS_MC],
3544          { "MC", "ospf.v3.options.mc", FT_BOOLEAN, 24,
3545            TFS(&tfs_set_notset), OSPF_V3_OPTIONS_MC, NULL, HFILL }},
3546         {&hf_ospf_filter[OSPFF_V3_OPTIONS_N],
3547          { "N", "ospf.v3.options.n", FT_BOOLEAN, 24,
3548            TFS(&tfs_set_notset), OSPF_V3_OPTIONS_N, NULL, HFILL }},
3549         {&hf_ospf_filter[OSPFF_V3_OPTIONS_R],
3550          { "R", "ospf.v3.options.r", FT_BOOLEAN, 24,
3551            TFS(&tfs_set_notset), OSPF_V3_OPTIONS_R, NULL, HFILL }},
3552         {&hf_ospf_filter[OSPFF_V3_OPTIONS_DC],
3553          { "DC", "ospf.v3.options.dc", FT_BOOLEAN, 24,
3554            TFS(&tfs_set_notset), OSPF_V3_OPTIONS_DC, NULL, HFILL }},
3555         {&hf_ospf_filter[OSPFF_V3_OPTIONS_AF],
3556          { "AF", "ospf.v3.options.af", FT_BOOLEAN, 24,
3557            TFS(&tfs_set_notset), OSPF_V3_OPTIONS_AF, NULL, HFILL }},
3558         {&hf_ospf_filter[OSPFF_V3_OPTIONS_L],
3559          { "L", "ospf.v3.options.l", FT_BOOLEAN, 24,
3560            TFS(&tfs_set_notset), OSPF_V3_OPTIONS_L, NULL, HFILL }},
3561         {&hf_ospf_filter[OSPFF_V3_OPTIONS_AT],
3562          { "AT", "ospf.v3.options.at", FT_BOOLEAN, 24,
3563            TFS(&tfs_set_notset), OSPF_V3_OPTIONS_AT, NULL, HFILL }},
3564         {&hf_ospf_filter[OSPFF_DBD],
3565          { "DB Description", "ospf.dbd", FT_UINT8, BASE_HEX,
3566            NULL, 0x0, NULL, HFILL }},
3567         {&hf_ospf_filter[OSPFF_DBD_R],
3568          { "R", "ospf.dbd.r", FT_BOOLEAN, 8,
3569            TFS(&tfs_dbd_r), OSPF_DBD_FLAG_R, NULL, HFILL }},
3570         {&hf_ospf_filter[OSPFF_DBD_I],
3571          { "I", "ospf.dbd.i", FT_BOOLEAN, 8,
3572            TFS(&tfs_dbd_i), OSPF_DBD_FLAG_I, NULL, HFILL }},
3573         {&hf_ospf_filter[OSPFF_DBD_M],
3574          { "M", "ospf.dbd.m", FT_BOOLEAN, 8,
3575            TFS(&tfs_dbd_m), OSPF_DBD_FLAG_M, NULL, HFILL }},
3576         {&hf_ospf_filter[OSPFF_DBD_MS],
3577          { "MS", "ospf.dbd.ms", FT_BOOLEAN, 8,
3578            TFS(&tfs_dbd_ms), OSPF_DBD_FLAG_MS, NULL, HFILL }},
3579         {&hf_ospf_filter[OSPFF_LLS_EXT_OPTIONS],
3580          { "Options", "ospf.lls.ext.options", FT_UINT32, BASE_HEX,
3581            NULL, 0x0, NULL, HFILL }},
3582         {&hf_ospf_filter[OSPFF_LLS_EXT_OPTIONS_LR],
3583          { "LR", "ospf.lls.ext.options.lr", FT_BOOLEAN, 32,
3584            TFS(&tfs_lls_ext_options_lr), OSPF_LLS_EXT_OPTIONS_LR, NULL, HFILL }},
3585         {&hf_ospf_filter[OSPFF_LLS_EXT_OPTIONS_RS],
3586          { "RS", "ospf.lls.ext.options.rs", FT_BOOLEAN, 32,
3587            TFS(&tfs_lls_ext_options_rs), OSPF_LLS_EXT_OPTIONS_RS, NULL, HFILL }},
3588         {&hf_ospf_filter[OSPFF_V2_ROUTER_LSA_FLAG],
3589          { "Flags", "ospf.v2.router.lsa.flags", FT_UINT8, BASE_HEX,
3590            NULL, 0x0, NULL, HFILL }},
3591         {&hf_ospf_filter[OSPFF_V2_ROUTER_LSA_FLAG_B],
3592          { "B", "ospf.v2.router.lsa.flags.b", FT_BOOLEAN, 8,
3593            TFS(&tfs_v2_router_lsa_flags_b), OSPF_V2_ROUTER_LSA_FLAG_B, NULL, HFILL }},
3594         {&hf_ospf_filter[OSPFF_V2_ROUTER_LSA_FLAG_E],
3595          { "E", "ospf.v2.router.lsa.flags.e", FT_BOOLEAN, 8,
3596            TFS(&tfs_v2_router_lsa_flags_e), OSPF_V2_ROUTER_LSA_FLAG_E, NULL, HFILL }},
3597         {&hf_ospf_filter[OSPFF_V2_ROUTER_LSA_FLAG_V],
3598          { "V", "ospf.v2.router.lsa.flags.v", FT_BOOLEAN, 8,
3599            TFS(&tfs_v2_router_lsa_flags_v), OSPF_V2_ROUTER_LSA_FLAG_V, NULL, HFILL }},
3600         {&hf_ospf_filter[OSPFF_V2_ROUTER_LSA_FLAG_W],
3601          { "W", "ospf.v2.router.lsa.flags.w", FT_BOOLEAN, 8,
3602            TFS(&tfs_v2_router_lsa_flags_w), OSPF_V2_ROUTER_LSA_FLAG_W, NULL, HFILL }},
3603         {&hf_ospf_filter[OSPFF_V2_ROUTER_LSA_FLAG_N],
3604          { "N", "ospf.v2.router.lsa.flags.n", FT_BOOLEAN, 8,
3605            TFS(&tfs_v2_router_lsa_flags_n), OSPF_V2_ROUTER_LSA_FLAG_N, NULL, HFILL }},
3606         {&hf_ospf_filter[OSPFF_V3_ROUTER_LSA_FLAG],
3607          { "Flags", "ospf.v3.router.lsa.flags", FT_UINT8, BASE_HEX,
3608            NULL, 0x0, NULL, HFILL }},
3609         {&hf_ospf_filter[OSPFF_V3_ROUTER_LSA_FLAG_B],
3610          { "B", "ospf.v3.router.lsa.flags.b", FT_BOOLEAN, 8,
3611            TFS(&tfs_v3_router_lsa_flags_b), OSPF_V3_ROUTER_LSA_FLAG_B, NULL, HFILL }},
3612         {&hf_ospf_filter[OSPFF_V3_ROUTER_LSA_FLAG_E],
3613          { "E", "ospf.v3.router.lsa.flags.e", FT_BOOLEAN, 8,
3614            TFS(&tfs_v3_router_lsa_flags_e), OSPF_V3_ROUTER_LSA_FLAG_E, NULL, HFILL }},
3615         {&hf_ospf_filter[OSPFF_V3_ROUTER_LSA_FLAG_V],
3616          { "V", "ospf.v3.router.lsa.flags.v", FT_BOOLEAN, 8,
3617            TFS(&tfs_v3_router_lsa_flags_v), OSPF_V3_ROUTER_LSA_FLAG_V, NULL, HFILL }},
3618         {&hf_ospf_filter[OSPFF_V3_ROUTER_LSA_FLAG_W],
3619          { "W", "ospf.v3.router.lsa.flags.w", FT_BOOLEAN, 8,
3620            TFS(&tfs_v3_router_lsa_flags_w), OSPF_V3_ROUTER_LSA_FLAG_W, NULL, HFILL }},
3621         {&hf_ospf_filter[OSPFF_V3_AS_EXTERNAL_FLAG],
3622          { "Flags", "ospf.v3.as.external.flags", FT_UINT8, BASE_HEX,
3623            NULL, 0x0, NULL, HFILL }},
3624         {&hf_ospf_filter[OSPFF_V3_AS_EXTERNAL_FLAG_T],
3625          { "T", "ospf.v3.as.external.flags.t", FT_BOOLEAN, 8,
3626            TFS(&tfs_v3_as_external_flags_t), OSPF_V3_AS_EXTERNAL_FLAG_T, NULL, HFILL }},
3627         {&hf_ospf_filter[OSPFF_V3_AS_EXTERNAL_FLAG_F],
3628          { "F", "ospf.v3.as.external.flags.f", FT_BOOLEAN, 8,
3629            TFS(&tfs_v3_as_external_flags_f), OSPF_V3_AS_EXTERNAL_FLAG_F, NULL, HFILL }},
3630         {&hf_ospf_filter[OSPFF_V3_AS_EXTERNAL_FLAG_E],
3631          { "E", "ospf.v3.as.external.flags.e", FT_BOOLEAN, 8,
3632            TFS(&tfs_v3_as_external_flags_e), OSPF_V3_AS_EXTERNAL_FLAG_E, NULL, HFILL }},
3633         {&hf_ospf_filter[OSPFF_V3_PREFIX_OPTION],
3634          { "PrefixOptions", "ospf.v3.prefix.options", FT_UINT8, BASE_HEX,
3635            NULL, 0x0, NULL, HFILL }},
3636         {&hf_ospf_filter[OSPFF_V3_PREFIX_OPTION_NU],
3637          { "NU", "ospf.v3.prefix.options.nu", FT_BOOLEAN, 8,
3638            TFS(&tfs_v3_prefix_options_nu), OSPF_V3_PREFIX_OPTION_NU, NULL, HFILL }},
3639         {&hf_ospf_filter[OSPFF_V3_PREFIX_OPTION_LA],
3640          { "LA", "ospf.v3.prefix.options.la", FT_BOOLEAN, 8,
3641            TFS(&tfs_v3_prefix_options_la), OSPF_V3_PREFIX_OPTION_LA, NULL, HFILL }},
3642         {&hf_ospf_filter[OSPFF_V3_PREFIX_OPTION_MC],
3643          { "MC", "ospf.v3.prefix.options.mc", FT_BOOLEAN, 8,
3644            TFS(&tfs_v3_prefix_options_mc), OSPF_V3_PREFIX_OPTION_MC, NULL, HFILL }},
3645         {&hf_ospf_filter[OSPFF_V3_PREFIX_OPTION_P],
3646          { "P", "ospf.v3.prefix.options.p", FT_BOOLEAN, 8,
3647            TFS(&tfs_v3_prefix_options_p), OSPF_V3_PREFIX_OPTION_P, NULL, HFILL }},
3648
3649         /* Dynamic Hostname contained in the Opaque RI LSA - dynamic hostname TLV*/
3650         {&hf_ospf_filter[OSPFF_DYN_HOSTNAME],
3651          { "Dynamic Hostname", "ospf.dynhostname", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3652
3653         /* text contained in the Unknown TLV of the Opaque RI LSA */
3654         {&hf_ospf_filter[OSPFF_UNKNOWN_TLV_TXT],
3655          { "Text in the Unknown TLV", "ospf.unknown_text", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3656
3657         /* OSPF Restart TLVs  */
3658         {&hf_ospf_filter[OSPFF_V2_GRACE_TLV],
3659          { "Grace TLV", "ospf.v2.grace", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3660         {&hf_ospf_filter[OSPFF_V2_GRACE_PERIOD],
3661          { "Grace Period", "ospf.v2.grace.period", FT_UINT32, BASE_DEC,
3662            NULL, 0x0,
3663            "The number of seconds neighbors should advertise the router as fully adjacent",
3664            HFILL }},
3665         {&hf_ospf_filter[OSPFF_V2_GRACE_REASON],
3666          { "Restart Reason", "ospf.v2.grace.reason", FT_UINT8, BASE_DEC,
3667            VALS(restart_reason_vals), 0x0, "The reason the router is restarting", HFILL }},
3668         {&hf_ospf_filter[OSPFF_V2_GRACE_IP],
3669          { "Restart IP", "ospf.v2.grace.ip", FT_IPv4, BASE_NONE,
3670            NULL, 0x0, "The IP address of the interface originating this LSA", HFILL }},
3671
3672         /* OSPFv3 LLS TLVs */
3673         {&hf_ospf_filter[OSPFF_V3_LLS_EXT_OPTIONS_TLV],
3674          { "Extended Options TLV", "ospf.v3.lls.ext.options.tlv", FT_NONE, BASE_NONE,
3675            NULL, 0x0, NULL, HFILL }},
3676         {&hf_ospf_filter[OSPFF_V3_LLS_EXT_OPTIONS],
3677          { "Options", "ospf.v3.lls.ext.options", FT_UINT32,  BASE_HEX,
3678            NULL, 0x0, NULL, HFILL }},
3679         {&hf_ospf_filter[OSPFF_V3_LLS_EXT_OPTIONS_LR],
3680          { "LR", "ospf.v3.lls.ext.options.lr", FT_BOOLEAN, 32,
3681            TFS(&tfs_v3_lls_ext_options_lr), OSPF_V3_LLS_EXT_OPTIONS_LR, NULL, HFILL }},
3682         {&hf_ospf_filter[OSPFF_V3_LLS_EXT_OPTIONS_RS],
3683          { "RS", "ospf.v3.lls.ext.options.rs", FT_BOOLEAN, 32,
3684            TFS(&tfs_v3_lls_ext_options_rs), OSPF_V3_LLS_EXT_OPTIONS_RS, NULL, HFILL }},
3685         {&hf_ospf_filter[OSPFF_V3_LLS_STATE_TLV],
3686          { "State Check Sequence TLV", "ospf.v3.lls.state.tlv", FT_NONE, BASE_NONE,
3687            NULL, 0x0, NULL, HFILL }},
3688         {&hf_ospf_filter[OSPFF_V3_LLS_STATE_SCS],
3689          { "SCS Number", "ospf.v3.lls.state.scs", FT_UINT16,  BASE_DEC,
3690            NULL, 0x0, NULL, HFILL }},
3691         {&hf_ospf_filter[OSPFF_V3_LLS_STATE_OPTIONS],
3692          { "Options", "ospf.v3.lls.state.options", FT_UINT8,  BASE_HEX,
3693            NULL, 0x0, NULL, HFILL }},
3694         {&hf_ospf_filter[OSPFF_V3_LLS_STATE_OPTIONS_R],
3695          { "R", "ospf.v3.lls.state.options.r", FT_BOOLEAN, 8,
3696            TFS(&tfs_v3_lls_state_options_r), OSPF_V3_LLS_STATE_OPTIONS_R, NULL, HFILL }},
3697         {&hf_ospf_filter[OSPFF_V3_LLS_STATE_OPTIONS_A],
3698          { "A", "ospf.v3.lls.state.options.a", FT_BOOLEAN, 8,
3699            TFS(&tfs_v3_lls_state_options_a), OSPF_V3_LLS_STATE_OPTIONS_A , NULL, HFILL }},
3700         {&hf_ospf_filter[OSPFF_V3_LLS_STATE_OPTIONS_N],
3701          { "N", "ospf.v3.lls.state.options.n", FT_BOOLEAN, 8,
3702            TFS(&tfs_v3_lls_state_options_n), OSPF_V3_LLS_STATE_OPTIONS_N ,NULL, HFILL }},
3703         {&hf_ospf_filter[OSPFF_V3_LLS_DROP_TLV],
3704          { "Neighbor Drop TLV", "ospf.v3.lls.drop.tlv", FT_NONE, BASE_NONE,
3705            NULL, 0x0, NULL, HFILL }},
3706         {&hf_ospf_filter[OSPFF_V3_LLS_RELAY_TLV],
3707          { "Active Overlapping Relays TLV", "ospf.v3.lls.relay.tlv", FT_NONE, BASE_NONE,
3708            NULL, 0x0, NULL, HFILL }},
3709         {&hf_ospf_filter[OSPFF_V3_LLS_RELAY_ADDED],
3710          { "Relays Added", "ospf.v3.lls.relay.added", FT_UINT8,  BASE_DEC,
3711            NULL, 0x0, NULL, HFILL }},
3712         {&hf_ospf_filter[OSPFF_V3_LLS_RELAY_OPTIONS],
3713          { "Options", "ospf.v3.lls.relay.options", FT_UINT8,  BASE_HEX,
3714            NULL, 0x0, NULL, HFILL }},
3715         {&hf_ospf_filter[OSPFF_V3_LLS_RELAY_OPTIONS_A],
3716          { "A", "ospf.v3.lls.relay.options.a", FT_BOOLEAN, 8,
3717            TFS(&tfs_v3_lls_relay_options_a), OSPF_V3_LLS_RELAY_OPTIONS_A , NULL, HFILL }},
3718         {&hf_ospf_filter[OSPFF_V3_LLS_RELAY_OPTIONS_N],
3719          { "N", "ospf.v3.lls.relay.options.n", FT_BOOLEAN, 8,
3720            TFS(&tfs_v3_lls_relay_options_n), OSPF_V3_LLS_RELAY_OPTIONS_N ,NULL, HFILL }},
3721         {&hf_ospf_filter[OSPFF_V3_LLS_WILLINGNESS_TLV],
3722          { "Willingness TLV", "ospf.v3.lls.willingness.tlv", FT_NONE, BASE_NONE,
3723            NULL, 0x0, NULL, HFILL }},
3724         {&hf_ospf_filter[OSPFF_V3_LLS_WILLINGNESS],
3725          { "Willingness", "ospf.v3.lls.willingness", FT_UINT8,  BASE_DEC,
3726            NULL, 0x0, NULL, HFILL }},
3727         {&hf_ospf_filter[OSPFF_V3_LLS_RF_TLV],
3728          { "Request From TLV", "ospf.v3.lls.rf.tlv", FT_NONE, BASE_NONE,
3729            NULL, 0x0, NULL, HFILL }},
3730         {&hf_ospf_filter[OSPFF_V3_LLS_FSF_TLV],
3731          { "Full State For TLV", "ospf.v3.lls.fsf.tlv", FT_NONE, BASE_NONE,
3732            NULL, 0x0, NULL, HFILL }}
3733     };
3734
3735     static gint *ett[] = {
3736         &ett_ospf,
3737         &ett_ospf_hdr,
3738         &ett_ospf_hello,
3739         &ett_ospf_desc,
3740         &ett_ospf_lsr,
3741         &ett_ospf_lsa,
3742         &ett_ospf_lsa_router_link,
3743         &ett_ospf_lsa_upd,
3744         &ett_ospf_lsa_mpls,
3745         &ett_ospf_lsa_mpls_router,
3746         &ett_ospf_lsa_mpls_link,
3747         &ett_ospf_lsa_mpls_link_stlv,
3748         &ett_ospf_lsa_mpls_link_stlv_admingrp,
3749         &ett_ospf_lsa_opaque_ri,
3750         &ett_ospf_lsa_ri_tlv,
3751         &ett_ospf_lsa_dyn_hostname_tlv,
3752         &ett_ospf_lsa_unknown_tlv,
3753         &ett_ospf_lsa_oif_tna,
3754         &ett_ospf_lsa_oif_tna_stlv,
3755         &ett_ospf_lsa_grace_tlv,
3756         &ett_ospf_v2_options,
3757         &ett_ospf_ri_options,
3758         &ett_ospf_v3_options,
3759         &ett_ospf_dbd,
3760         &ett_ospf_lls_data_block,
3761         &ett_ospf_lls_tlv,
3762         &ett_ospf_lls_ext_options,
3763         &ett_ospf_v3_lls_ext_options_tlv,
3764         &ett_ospf_v3_lls_ext_options,
3765         &ett_ospf_v3_lls_state_tlv,
3766         &ett_ospf_v3_lls_state_scs,
3767         &ett_ospf_v3_lls_state_options,
3768         &ett_ospf_v3_lls_drop_tlv,
3769         &ett_ospf_v3_lls_relay_tlv,
3770         &ett_ospf_v3_lls_relay_added,
3771         &ett_ospf_v3_lls_relay_options,
3772         &ett_ospf_v3_lls_willingness_tlv,
3773         &ett_ospf_v3_lls_willingness,
3774         &ett_ospf_v3_lls_rf_tlv,
3775         &ett_ospf_v3_lls_fsf_tlv,
3776         &ett_ospf_v2_router_lsa_flags,
3777         &ett_ospf_v3_router_lsa_flags,
3778         &ett_ospf_v3_as_external_flags,
3779         &ett_ospf_v3_prefix_options
3780     };
3781
3782     proto_ospf = proto_register_protocol("Open Shortest Path First",
3783                                          "OSPF", "ospf");
3784     proto_register_field_array(proto_ospf, ospff_info, array_length(ospff_info));
3785     proto_register_subtree_array(ett, array_length(ett));
3786 }
3787
3788 void
3789 proto_reg_handoff_ospf(void)
3790 {
3791     dissector_handle_t ospf_handle;
3792
3793     ospf_handle = create_dissector_handle(dissect_ospf, proto_ospf);
3794     dissector_add_uint("ip.proto", IP_PROTO_OSPF, ospf_handle);
3795     data_handle = find_dissector("data");
3796 }
3797
3798 /*
3799  * Editor modelines
3800  *
3801  * Local Variables:
3802  * c-basic-offset: 4
3803  * tab-width: 8
3804  * indent-tabs-mode: nil
3805  * End:
3806  *
3807  * ex: set shiftwidth=4 tabstop=8 expandtab:
3808  * :indentSize=4:tabSize=8:noTabs=true:
3809  */