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