Note that pre-0.6 libpcap didn't handle HP-UX as well as 0.6 and later
[obnox/wireshark/wip.git] / packet-isis-hello.c
1 /* packet-isis-hello.c
2  * Routines for decoding isis hello packets and their CLVs
3  *
4  * $Id: packet-isis-hello.c,v 1.29 2002/04/07 23:39:00 guy Exp $
5  * Stuart Stanley <stuarts@mxmail.net>
6  *
7  * Ethereal - Network traffic analyzer
8  * By Gerald Combs <gerald@ethereal.com>
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 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #ifdef HAVE_SYS_TYPES_H
31 # include <sys/types.h>
32 #endif
33
34 #include <stdio.h>
35 #include <string.h>
36 #include <glib.h>
37 #include <epan/packet.h>
38 #include "packet-osi.h"
39 #include "packet-isis.h"
40 #include "packet-isis-clv.h"
41 #include "packet-isis-hello.h"
42 #include "epan/resolv.h"
43
44 /* hello packets */
45 static int hf_isis_hello_circuit_reserved    = -1;
46 static int hf_isis_hello_source_id           = -1;
47 static int hf_isis_hello_holding_timer       = -1;
48 static int hf_isis_hello_pdu_length          = -1;
49 static int hf_isis_hello_priority_reserved   = -1;
50 static int hf_isis_hello_lan_id              = -1;
51 static int hf_isis_hello_local_circuit_id    = -1;
52 static int hf_isis_hello_clv_ipv4_int_addr   = -1;
53 static int hf_isis_hello_clv_ipv6_int_addr   = -1;
54 static int hf_isis_hello_clv_ptp_adj         = -1;
55 static int hf_isis_hello_clv_mt              = -1;
56
57 static gint ett_isis_hello                   = -1;
58 static gint ett_isis_hello_clv_area_addr     = -1;
59 static gint ett_isis_hello_clv_is_neighbors  = -1;
60 static gint ett_isis_hello_clv_padding       = -1;
61 static gint ett_isis_hello_clv_unknown       = -1;
62 static gint ett_isis_hello_clv_nlpid         = -1;
63 static gint ett_isis_hello_clv_auth          = -1;
64 static gint ett_isis_hello_clv_ipv4_int_addr = -1;
65 static gint ett_isis_hello_clv_ipv6_int_addr = -1;
66 static gint ett_isis_hello_clv_ptp_adj       = -1;
67 static gint ett_isis_hello_clv_mt            = -1;
68 static gint ett_isis_hello_clv_restart       = -1;
69
70 static const value_string isis_hello_circuit_type_vals[] = {
71         { ISIS_HELLO_TYPE_RESERVED,     "Reserved 0 (discard PDU)"},
72         { ISIS_HELLO_TYPE_LEVEL_1,      "Level 1 only"},
73         { ISIS_HELLO_TYPE_LEVEL_2,      "Level 2 only"},
74         { ISIS_HELLO_TYPE_LEVEL_12,     "Level 1 and 2"},
75         { 0,            NULL} };
76
77 /* 
78  * Predclare dissectors for use in clv dissection.
79  */
80 static void dissect_hello_padding_clv(tvbuff_t *tvb, 
81                 proto_tree *tree, int offset, int id_length, int length);
82 static void dissect_hello_is_neighbors_clv(tvbuff_t *tvb, 
83                 proto_tree *tree, int offset, int id_length, int length);
84 static void dissect_hello_ptp_adj_clv(tvbuff_t *tvb, 
85                 proto_tree *tree, int offset, int id_length, int length);
86 static void dissect_hello_area_address_clv(tvbuff_t *tvb, 
87                 proto_tree *tree, int offset, int id_length, int length);
88 static void dissect_hello_auth_clv(tvbuff_t *tvb, 
89                 proto_tree *tree, int offset, int id_length, int length);
90 static void dissect_hello_ipv6_int_addr_clv(tvbuff_t *tvb, 
91                 proto_tree *tree, int offset, int id_length, int length);
92 static void dissect_hello_ip_int_addr_clv(tvbuff_t *tvb, 
93                 proto_tree *tree, int offset, int id_length, int length);
94 static void dissect_hello_mt_clv(tvbuff_t *tvb, 
95                 proto_tree *tree, int offset, int id_length, int length);
96 static void dissect_hello_nlpid_clv(tvbuff_t *tvb, 
97                 proto_tree *tree, int offset, int id_length, int length);
98 static void dissect_hello_restart_clv(tvbuff_t *tvb, 
99                 proto_tree *tree, int offset, int id_length, int length);
100
101
102 static const isis_clv_handle_t clv_l1_hello_opts[] = {
103         {
104                 ISIS_CLV_L1H_AREA_ADDRESS,
105                 "Area address(es)",
106                 &ett_isis_hello_clv_area_addr,
107                 dissect_hello_area_address_clv
108         },
109         {
110                 ISIS_CLV_L1H_IS_NEIGHBORS,
111                 "IS Neighbor(s)",
112                 &ett_isis_hello_clv_is_neighbors,
113                 dissect_hello_is_neighbors_clv
114         },
115         {
116                 ISIS_CLV_L1H_PADDING,
117                 "Padding",
118                 &ett_isis_hello_clv_padding,
119                 dissect_hello_padding_clv
120         },
121         {
122                 ISIS_CLV_L1H_NLPID,
123                 "Protocols Supported",
124                 &ett_isis_hello_clv_nlpid,
125                 dissect_hello_nlpid_clv
126         },
127         {
128                 ISIS_CLV_L1H_IP_INTERFACE_ADDR,
129                 "IP Interface address(es)",
130                 &ett_isis_hello_clv_ipv4_int_addr,
131                 dissect_hello_ip_int_addr_clv
132         },
133         {
134                 ISIS_CLV_L1H_IPv6_INTERFACE_ADDR,
135                 "IPv6 Interface address(es)",
136                 &ett_isis_hello_clv_ipv6_int_addr,
137                 dissect_hello_ipv6_int_addr_clv
138         },
139         {
140                 ISIS_CLV_L1H_RESTART,
141                 "Restart Signaling",
142                 &ett_isis_hello_clv_restart,
143                 dissect_hello_restart_clv
144         },
145         {
146                 ISIS_CLV_L1H_AUTHENTICATION_NS,
147                 "Authentication(non spec)",
148                 &ett_isis_hello_clv_auth,
149                 dissect_hello_auth_clv
150         },
151         {
152                 ISIS_CLV_L1H_AUTHENTICATION,
153                 "Authentication",
154                 &ett_isis_hello_clv_auth,
155                 dissect_hello_auth_clv
156         },
157         {
158                 ISIS_CLV_L1H_MT,
159                 "Multi Topology",
160                 &ett_isis_hello_clv_mt,
161                 dissect_hello_mt_clv
162         },
163         {
164                 0,
165                 "",
166                 NULL,
167                 NULL
168         }
169 };
170
171 static const isis_clv_handle_t clv_l2_hello_opts[] = {
172         {
173                 ISIS_CLV_L2H_AREA_ADDRESS,
174                 "Area address(es)",
175                 &ett_isis_hello_clv_area_addr,
176                 dissect_hello_area_address_clv
177         },
178         {
179                 ISIS_CLV_L2H_IS_NEIGHBORS,
180                 "IS Neighbor(s)",
181                 &ett_isis_hello_clv_is_neighbors,
182                 dissect_hello_is_neighbors_clv
183         },
184         {
185                 ISIS_CLV_L2H_PADDING,
186                 "Padding",
187                 &ett_isis_hello_clv_padding,
188                 dissect_hello_padding_clv
189         },
190         {
191                 ISIS_CLV_L2H_NLPID,
192                 "Protocols Supported",
193                 &ett_isis_hello_clv_nlpid,
194                 dissect_hello_nlpid_clv
195         },
196         {
197                 ISIS_CLV_L2H_IP_INTERFACE_ADDR,
198                 "IP Interface address(es)",
199                 &ett_isis_hello_clv_ipv4_int_addr,
200                 dissect_hello_ip_int_addr_clv
201         },
202         {
203                 ISIS_CLV_L2H_IPv6_INTERFACE_ADDR,
204                 "IPv6 Interface address(es)",
205                 &ett_isis_hello_clv_ipv6_int_addr,
206                 dissect_hello_ipv6_int_addr_clv
207         },
208         {
209                 ISIS_CLV_L2H_AUTHENTICATION_NS,
210                 "Authentication(non spec)",
211                 &ett_isis_hello_clv_auth,
212                 dissect_hello_auth_clv
213         },
214         {
215                 ISIS_CLV_L2H_RESTART,
216                 "Restart Signaling",
217                 &ett_isis_hello_clv_restart,
218                 dissect_hello_restart_clv
219         },
220         {
221                 ISIS_CLV_L2H_AUTHENTICATION,
222                 "Authentication",
223                 &ett_isis_hello_clv_auth,
224                 dissect_hello_auth_clv
225         },
226         {
227                 ISIS_CLV_L2H_MT,
228                 "Multi Topology",
229                 &ett_isis_hello_clv_mt,
230                 dissect_hello_mt_clv
231         },
232         {
233                 0,
234                 "",
235                 NULL,
236                 NULL
237         }
238 };
239
240 static const isis_clv_handle_t clv_ptp_hello_opts[] = {
241         {
242                 ISIS_CLV_PTP_AREA_ADDRESS,
243                 "Area address(es)",
244                 &ett_isis_hello_clv_area_addr,
245                 dissect_hello_area_address_clv
246         },
247         {
248                 ISIS_CLV_PTP_PADDING,
249                 "Padding",
250                 &ett_isis_hello_clv_padding,
251                 dissect_hello_padding_clv
252         },
253         {
254                 ISIS_CLV_PTP_NLPID,
255                 "Protocols Supported",
256                 &ett_isis_hello_clv_nlpid,
257                 dissect_hello_nlpid_clv
258         },
259         {
260                 ISIS_CLV_PTP_IP_INTERFACE_ADDR,
261                 "IP Interface address(es)",
262                 &ett_isis_hello_clv_ipv4_int_addr,
263                 dissect_hello_ip_int_addr_clv
264         },
265         {
266                 ISIS_CLV_PTP_IPv6_INTERFACE_ADDR,
267                 "IPv6 Interface address(es)",
268                 &ett_isis_hello_clv_ipv6_int_addr,
269                 dissect_hello_ipv6_int_addr_clv
270         },
271         {
272                 ISIS_CLV_PTP_AUTHENTICATION_NS,
273                 "Authentication(non spec)",
274                 &ett_isis_hello_clv_auth,
275                 dissect_hello_auth_clv
276         },
277         {
278                 ISIS_CLV_PTP_AUTHENTICATION,
279                 "Authentication",
280                 &ett_isis_hello_clv_auth,
281                 dissect_hello_auth_clv
282         },
283         {
284                 ISIS_CLV_PTP_RESTART,
285                 "Restart Option",
286                 &ett_isis_hello_clv_restart,
287                 dissect_hello_restart_clv
288         },
289         {
290                 ISIS_CLV_PTP_ADJ,
291                 "Point-to-point Adjacency State",
292                 &ett_isis_hello_clv_ptp_adj,
293                 dissect_hello_ptp_adj_clv
294         },
295         {
296                 ISIS_CLV_PTP_MT,
297                 "Multi Topology",
298                 &ett_isis_hello_clv_mt,
299                 dissect_hello_mt_clv
300         },
301         {
302                 0,
303                 "",
304                 NULL,
305                 NULL
306         }
307 };
308
309
310 /*
311  * Name: dissect_hello_restart_clv()
312  *
313  * Description:
314  *      Decode for a restart clv - only found in IIHs
315  *      hence no call in the common clv dissector
316  *
317  */
318
319 static void 
320 dissect_hello_restart_clv(tvbuff_t *tvb, 
321                 proto_tree *tree, int offset, int id_length, int length)
322 {
323         int restart_options;
324
325         restart_options = tvb_get_guint8(tvb, offset);
326
327         proto_tree_add_text ( tree, tvb, offset, 1,        
328                               "Restart Request bit %s, "
329                               "Restart Acknowledgement bit %s",
330                               ISIS_MASK_RESTART_RR(restart_options) ? "set" : "clear",
331                               ISIS_MASK_RESTART_RA(restart_options) ? "set" : "clear"); 
332         proto_tree_add_text ( tree, tvb, offset+1, 2,        
333                               "Remaining holding time: %us",
334                               tvb_get_ntohs(tvb, offset+1) );
335 }
336
337 /*
338  * Name: dissect_hello_nlpid_clv()
339  *
340  * Description:
341  *      Decode for a hello packets NLPID clv.  Calls into the
342  *      clv common one.
343  *
344  * Input:
345  *      tvbuff_t * : tvbuffer for packet data
346  *      proto_tree * : proto tree to build on (may be null)
347  *      int : current offset into packet data
348  *      int : length of IDs in packet.
349  *      int : length of this clv
350  *
351  * Output:
352  *      void, will modify proto_tree if not null.
353  */
354 static void 
355 dissect_hello_nlpid_clv(tvbuff_t *tvb, 
356         proto_tree *tree, int offset, int id_length, int length)
357 {
358         isis_dissect_nlpid_clv(tvb, tree, offset, length);
359 }
360
361 /*
362  * Name: dissect_hello_mt_clv()
363  *
364  * Description:
365  *      Decode for a hello packets Multi Topology clv.  Calls into the
366  *      clv common one.
367  *
368  * Input:
369  *      tvbuff_t * : tvbuffer for packet data
370  *      proto_tree * : proto tree to build on (may be null)
371  *      int : current offset into packet data
372  *      int : length of IDs in packet.
373  *      int : length of this clv
374  *
375  * Output:
376  *      void, will modify proto_tree if not null.
377  */
378
379 static void 
380 dissect_hello_mt_clv(tvbuff_t *tvb, 
381         proto_tree *tree, int offset, int id_length, int length)
382 {
383         isis_dissect_mt_clv(tvb, tree, offset, length,
384                 hf_isis_hello_clv_mt );
385 }
386
387 /*
388  * Name: dissect_hello_ip_int_addr_clv()
389  *
390  * Description:
391  *      Decode for a hello packets ip interface addr clv.  Calls into the
392  *      clv common one.
393  *
394  * Input:
395  *      tvbuff_t * : tvbuffer for packet data
396  *      proto_tree * : proto tree to build on (may be null)
397  *      int : current offset into packet data
398  *      int : length of IDs in packet.
399  *      int : length of this clv
400  *
401  * Output:
402  *      void, will modify proto_tree if not null.
403  */
404 static void 
405 dissect_hello_ip_int_addr_clv(tvbuff_t *tvb, 
406         proto_tree *tree, int offset, int id_length, int length)
407 {
408         isis_dissect_ip_int_clv(tvb, tree, offset, length,
409                 hf_isis_hello_clv_ipv4_int_addr );
410 }
411
412 /*
413  * Name: dissect_hello_ipv6_int_addr_clv()
414  *
415  * Description:
416  *      Decode for a hello packets ipv6 interface addr clv.  Calls into the
417  *      clv common one.
418  *
419  * Input:
420  *      tvbuff_t * : tvbuffer for packet data
421  *      proto_tree * : proto tree to build on (may be null)
422  *      int : current offset into packet data
423  *      int : length of IDs in packet.
424  *      int : length of this clv
425  *
426  * Output:
427  *      void, will modify proto_tree if not null.
428  */
429 static void 
430 dissect_hello_ipv6_int_addr_clv(tvbuff_t *tvb, 
431         proto_tree *tree, int offset, int id_length, int length)
432 {
433         isis_dissect_ipv6_int_clv(tvb, tree, offset, length,
434                 hf_isis_hello_clv_ipv6_int_addr );
435 }
436
437 /*
438  * Name: dissect_hello_auth_clv()
439  *
440  * Description:
441  *      Decode for a hello packets authenticaion clv.  Calls into the
442  *      clv common one.  An auth inside a hello packet is a perlink
443  *      password.
444  *
445  * Input:
446  *      tvbuff_t * : tvbuffer for packet data
447  *      proto_tree * : proto tree to build on (may be null)
448  *      int : current offset into packet data
449  *      int : length of IDs in packet.
450  *      int : length of this clv
451  *
452  * Output:
453  *      void, will modify proto_tree if not null.
454  */
455 static void 
456 dissect_hello_auth_clv(tvbuff_t *tvb, 
457         proto_tree *tree, int offset, int id_length, int length)
458 {
459         isis_dissect_authentication_clv(tvb, tree, offset,
460                 length, "authentication" );
461 }
462
463 /*
464  * Name: dissect_hello_area_address_clv()
465  *
466  * Description:
467  *      Decode for a hello packets area address clv.  Calls into the
468  *      clv common one.
469  *
470  * Input:
471  *      tvbuff_t * : tvbuffer for packet data
472  *      proto_tree * : proto tree to build on (may be null)
473  *      int : current offset into packet data
474  *      int : length of IDs in packet.
475  *      int : length of this clv
476  *
477  * Output:
478  *      void, will modify proto_tree if not null.
479  */
480 static void 
481 dissect_hello_area_address_clv(tvbuff_t *tvb, 
482         proto_tree *tree, int offset, int id_length, int length)
483 {
484         isis_dissect_area_address_clv(tvb, tree, offset, length);
485 }
486
487
488
489 static void 
490 dissect_hello_ptp_adj_clv(tvbuff_t *tvb, 
491                 proto_tree *tree, int offset, int id_length, int length)
492 {
493         char adj_state[20];
494
495         switch(tvb_get_guint8(tvb, offset)) {
496           case 0:
497             strcpy(adj_state,"Up");
498             break;
499           case 1:
500             strcpy(adj_state,"Initializing");
501             break;
502           case 2:
503             strcpy(adj_state,"Down");
504             break;
505           default:
506             strcpy(adj_state,"<illegal value !!!>");
507             }
508
509         switch(length) {
510           case 1:
511             proto_tree_add_text ( tree, tvb, offset, 1,
512                                   "Adjacency State: %s", adj_state );
513             break;
514           case 5:
515             proto_tree_add_text ( tree, tvb, offset, 1,        
516                                   "Adjacency State: %s", adj_state ); 
517             proto_tree_add_text ( tree, tvb, offset+1, 4,        
518                                   "Extended Local circuit ID: 0x%08x", tvb_get_ntohl(tvb, offset+1) ); 
519             break;
520           case 11:
521             proto_tree_add_text ( tree, tvb, offset, 1,
522                                   "Adjacency State: %s", adj_state );
523             proto_tree_add_text ( tree, tvb, offset+1, 4,
524                                   "Extended Local circuit ID: 0x%08x", tvb_get_ntohl(tvb, offset+1) );
525             proto_tree_add_text ( tree, tvb, offset+5, 6,
526                                   "Neighbor SystemID: %s", print_system_id( tvb_get_ptr(tvb, offset+5, 6), 6 ) );
527             break;
528           case 15:
529             proto_tree_add_text ( tree, tvb, offset, 1,
530                                   "Adjacency State: %s", adj_state );
531             proto_tree_add_text ( tree, tvb, offset+1, 4,
532                                   "Extended Local circuit ID: 0x%08x", tvb_get_ntohl(tvb, offset+1) );
533             proto_tree_add_text ( tree, tvb, offset+5, 6,
534                                   "Neighbor SystemID: %s", print_system_id( tvb_get_ptr(tvb, offset+5, 6), 6 ) );  
535             proto_tree_add_text ( tree, tvb, offset+11, 4,
536                                   "Neighbor Extended Local circuit ID: 0x%08x", tvb_get_ntohl(tvb, offset+11) );
537             break;
538           default:
539             isis_dissect_unknown(tvb, tree, offset,
540                                  "malformed TLV (%d vs 1,5,11,15)", length );
541             return;
542         }
543 }
544
545 /*
546  * Name: isis_dissect_is_neighbors_clv()
547  * 
548  * Description:
549  *      Take apart a IS neighbor packet.  A neighbor is n 6 byte packets.
550  *      (they tend to be an 802.3 MAC address, but its not required).
551  *
552  * Input:
553  *      tvbuff_t * : tvbuffer for packet data
554  *      proto_tree * : protocol display tree to fill out.  May be NULL
555  *      int : offset into packet data where we are.
556  *      int : length of IDs in packet.
557  *      int : length of clv we are decoding
558  * 
559  * Output:
560  *      void, but we will add to proto tree if !NULL.
561  */
562 static void 
563 dissect_hello_is_neighbors_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
564         int id_length, int length)
565 {
566         while ( length > 0 ) {
567                 if (length<6) {
568                         isis_dissect_unknown(tvb, tree, offset,
569                                 "short is neighbor (%d vs 6)", length );
570                         return;
571                 }
572                 /* 
573                  * Lets turn the area address into "standard" 0000.0000.etc
574                  * format string.  
575                  */
576                 if ( tree ) {
577                         proto_tree_add_text ( tree, tvb, offset, 6, 
578                                 "IS Neighbor: %s", get_ether_name( tvb_get_ptr(tvb, offset, 6)) );
579                 }
580                 offset += 6;
581                 length -= 6;
582         }
583 }
584
585 /*
586  * Name: dissect_hello_padding_clv()
587  *
588  * Description:
589  *      Decode for a hello packet's padding clv.  Padding does nothing,
590  *      so we just return.
591  *
592  * Input:
593  *      tvbuff_t * : tvbuffer for packet data
594  *      proto_tree * : proto tree to build on (may be null)
595  *      int : current offset into packet data
596  *      int : length of IDs in packet.
597  *      int : length of this clv
598  *
599  * Output:
600  *      void
601  */
602 static void 
603 dissect_hello_padding_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
604         int id_length, int length)
605 {
606         /* nothing to do here! */
607 }
608
609
610 /*
611  * Name: isis_dissect_isis_hello()
612  * 
613  * Description:
614  *      This procedure rips apart the various types of ISIS hellos.  L1H and
615  *      L2H's are identical for the most part, while the PTP hello has
616  *      a shorter header.
617  *
618  * Input:
619  *      tvbuff_t * : tvbuffer for packet data
620  *      proto_tree * : protocol display tree to add to.  May be NULL.
621  *      int offset : our offset into packet data.
622  *      int : hello type, a la packet-isis.h ISIS_TYPE_* values
623  *      int : header length of packet.
624  *      int : length of IDs in packet.
625  *
626  * Output:
627  *      void, will modify proto_tree if not NULL.
628  */     
629 void 
630 isis_dissect_isis_hello(tvbuff_t *tvb, proto_tree *tree, int offset,
631         int hello_type, int header_length, int id_length)
632 {
633         proto_item      *ti;
634         proto_tree      *hello_tree = NULL;
635         int             len;
636         guint8          octet;
637         const guint8    *source_id;
638         guint16         pdu_length;
639         const guint8    *lan_id;
640
641         if (tree) {
642                 ti = proto_tree_add_text(tree, tvb, offset, -1, "ISIS HELLO");
643                 hello_tree = proto_item_add_subtree(ti, ett_isis_hello);
644                 octet = tvb_get_guint8(tvb, offset);
645                 proto_tree_add_uint_format(hello_tree,
646                         hf_isis_hello_circuit_reserved,
647                         tvb, offset, 1, octet,
648                         "Circuit type              : %s, reserved(0x%02x == 0)",
649                                 val_to_str(octet&ISIS_HELLO_CTYPE_MASK,
650                                         isis_hello_circuit_type_vals,
651                                         "Unknown (0x%x)"),
652                                 octet&ISIS_HELLO_CT_RESERVED_MASK
653                         );
654         }
655         offset += 1;
656
657         if (tree) {
658                 source_id = tvb_get_ptr(tvb, offset, id_length);
659                 proto_tree_add_bytes_format(hello_tree, hf_isis_hello_source_id, tvb,
660                                     offset, id_length, source_id,
661                                     "SystemID{ Sender of PDU } : %s", 
662                                     print_system_id( source_id, id_length ) );
663         }
664         offset += id_length;
665
666         if (tree) {
667                 proto_tree_add_item(hello_tree, hf_isis_hello_holding_timer, tvb,
668                                     offset, 2, FALSE);
669         }
670         offset += 2;
671
672         pdu_length = tvb_get_ntohs(tvb, offset);
673         if (tree) {
674                 proto_tree_add_uint(hello_tree, hf_isis_hello_pdu_length, tvb,
675                                     offset, 2, pdu_length);
676         }
677         offset += 2;
678
679         if (hello_type == ISIS_TYPE_PTP_HELLO) {
680                 if (tree) {
681                         proto_tree_add_item(hello_tree, hf_isis_hello_local_circuit_id, tvb,
682                                          offset, 1, FALSE );
683                 }
684                 offset += 1;
685         } else { 
686
687                 if (tree) {
688                         octet = tvb_get_guint8(tvb, offset);
689                         proto_tree_add_uint_format(hello_tree, hf_isis_hello_priority_reserved, tvb,
690                                     offset, 1, octet,
691                                     "Priority                  : %d, reserved(0x%02x == 0)",
692                                         octet&ISIS_HELLO_PRIORITY_MASK,
693                                         octet&ISIS_HELLO_P_RESERVED_MASK );
694                 }
695                 offset += 1;
696
697                 if (tree) {
698                         lan_id = tvb_get_ptr(tvb, offset, id_length+1);
699                         proto_tree_add_bytes_format(hello_tree, hf_isis_hello_lan_id, tvb, 
700                                      offset, id_length + 1, lan_id,
701                                          "SystemID{ Designated IS } : %s",
702                                               print_system_id( lan_id, id_length + 1 ) );
703                 }
704                 offset += id_length + 1;
705         }
706
707         len = pdu_length;
708         len -= header_length;
709         if (len < 0) {
710                 isis_dissect_unknown(tvb, tree, offset,
711                         "Packet header length %d went beyond packet", 
712                         header_length );
713                 return;
714         }
715         /*
716          * Now, we need to decode our CLVs.  We need to pass in
717          * our list of valid ones!
718          */
719         if (hello_type == ISIS_TYPE_L1_HELLO){
720                 isis_dissect_clvs(tvb, hello_tree, offset,
721                         clv_l1_hello_opts, len, id_length,
722                         ett_isis_hello_clv_unknown);
723         } else if (hello_type == ISIS_TYPE_L2_HELLO) {
724                 isis_dissect_clvs(tvb, hello_tree, offset,
725                         clv_l2_hello_opts, len, id_length,
726                         ett_isis_hello_clv_unknown);
727         } else {
728                 isis_dissect_clvs(tvb, hello_tree, offset,
729                         clv_ptp_hello_opts, len, id_length,
730                         ett_isis_hello_clv_unknown);
731         }
732 }
733
734 /*
735  * Name: isis_register_hello()
736  *
737  * Description:
738  *      Register our protocol sub-sets with protocol manager.
739  *
740  * Input: 
741  *      int : protocol index for the ISIS protocol
742  *
743  * Output:
744  *      void
745  */
746 void
747 isis_register_hello(int proto_isis) {
748         static hf_register_info hf[] = {
749                 { &hf_isis_hello_circuit_reserved,
750                 { "Circuit type              ", "isis.hello.circuit_type",
751                         FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL }},
752
753                 { &hf_isis_hello_source_id,
754                 { "SystemID{ Sender of PDU } ", "isis.hello.source_id",
755                         FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
756
757                 { &hf_isis_hello_holding_timer,
758                 { "Holding timer             ", "isis.hello.holding_timer", 
759                         FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
760
761                 { &hf_isis_hello_pdu_length,
762                 { "PDU length                ", "isis.hello.pdu_length",
763                         FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
764
765                 { &hf_isis_hello_priority_reserved,
766                  { "Priority                 ", "isis.hello.priority",
767                         FT_UINT8, BASE_DEC, NULL, ISIS_HELLO_P_RESERVED_MASK, "", HFILL }},
768
769                 { &hf_isis_hello_lan_id,
770                 { "SystemID{ Designated IS } ", "isis.hello.lan_id",
771                         FT_BYTES, BASE_DEC, NULL, 0x0, "", HFILL }},
772
773                 { &hf_isis_hello_local_circuit_id,
774                 { "Local circuit ID          ", "isis.hello.local_circuit_id",
775                         FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }},
776
777                 { &hf_isis_hello_clv_ipv4_int_addr,
778                 { "IPv4 interface address    ", "isis.hello.clv_ipv4_int_addr",
779                         FT_IPv4, BASE_NONE, NULL, 0x0, "", HFILL }},
780
781                 { &hf_isis_hello_clv_ipv6_int_addr,
782                 { "IPv6 interface address    ", "isis.hello.clv_ipv6_int_addr",
783                         FT_IPv6, BASE_NONE, NULL, 0x0, "", HFILL }},
784
785                 { &hf_isis_hello_clv_ptp_adj,
786                 { "Point-to-point Adjacency  ", "isis.hello.clv_ptp_adj",
787                         FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }},
788
789                 { &hf_isis_hello_clv_mt,
790                 { "MT-ID                     ", "isis.hello.clv_mt",
791                         FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
792         };
793         static gint *ett[] = {
794                 &ett_isis_hello,
795                 &ett_isis_hello_clv_area_addr,
796                 &ett_isis_hello_clv_is_neighbors,
797                 &ett_isis_hello_clv_padding,
798                 &ett_isis_hello_clv_unknown,
799                 &ett_isis_hello_clv_nlpid,
800                 &ett_isis_hello_clv_auth,
801                 &ett_isis_hello_clv_ipv4_int_addr,
802                 &ett_isis_hello_clv_ipv6_int_addr,
803                 &ett_isis_hello_clv_ptp_adj,
804                 &ett_isis_hello_clv_mt,
805                 &ett_isis_hello_clv_restart
806         };
807
808         proto_register_field_array(proto_isis, hf, array_length(hf));
809         proto_register_subtree_array(ett, array_length(ett));
810 }