Add in the SliMP3 data protocol dissector.
[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.24 2001/12/26 21:37:21 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 "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
69 static const value_string isis_hello_circuit_type_vals[] = {
70         { ISIS_HELLO_TYPE_RESERVED,     "Reserved 0 (discard PDU)"},
71         { ISIS_HELLO_TYPE_LEVEL_1,      "Level 1 only"},
72         { ISIS_HELLO_TYPE_LEVEL_2,      "Level 2 only"},
73         { ISIS_HELLO_TYPE_LEVEL_12,     "Level 1 and 2"},
74         { 0,            NULL} };
75
76 /* 
77  * Predclare dissectors for use in clv dissection.
78  */
79 static void dissect_hello_padding_clv(tvbuff_t *tvb, 
80                 packet_info *pinfo, proto_tree *tree, int offset, 
81                 int id_length, int length);
82 static void dissect_hello_is_neighbors_clv(tvbuff_t *tvb, 
83                 packet_info *pinfo, proto_tree *tree, int offset, 
84                 int id_length, int length);
85 static void dissect_hello_ptp_adj_clv(tvbuff_t *tvb, 
86                 packet_info *pinfo, proto_tree *tree, int offset, 
87                 int id_length, int length);
88 static void dissect_hello_area_address_clv(tvbuff_t *tvb, 
89                 packet_info *pinfo, proto_tree *tree, int offset, 
90                 int id_length, int length);
91 static void dissect_hello_auth_clv(tvbuff_t *tvb, 
92                 packet_info *pinfo, proto_tree *tree, int offset, 
93                 int id_length, int length);
94 static void dissect_hello_ipv6_int_addr_clv(tvbuff_t *tvb, 
95                 packet_info *pinfo, proto_tree *tree, int offset, 
96                 int id_length, int length);
97 static void dissect_hello_ip_int_addr_clv(tvbuff_t *tvb, 
98                 packet_info *pinfo, proto_tree *tree, int offset, 
99                 int id_length, int length);
100 static void dissect_hello_mt_clv(tvbuff_t *tvb, 
101                 packet_info *pinfo, proto_tree *tree, int offset, 
102                 int id_length, int length);
103 static void dissect_hello_nlpid_clv(tvbuff_t *tvb, 
104                 packet_info *pinfo, proto_tree *tree, int offset, 
105                 int id_length, int length);
106
107
108 static const isis_clv_handle_t clv_l1_hello_opts[] = {
109         {
110                 ISIS_CLV_L1H_AREA_ADDRESS,
111                 "Area address(es)",
112                 &ett_isis_hello_clv_area_addr,
113                 dissect_hello_area_address_clv
114         },
115         {
116                 ISIS_CLV_L1H_IS_NEIGHBORS,
117                 "IS Neighbor(s)",
118                 &ett_isis_hello_clv_is_neighbors,
119                 dissect_hello_is_neighbors_clv
120         },
121         {
122                 ISIS_CLV_L1H_PADDING,
123                 "Padding",
124                 &ett_isis_hello_clv_padding,
125                 dissect_hello_padding_clv
126         },
127         {
128                 ISIS_CLV_L1H_NLPID,
129                 "Protocols Supported",
130                 &ett_isis_hello_clv_nlpid,
131                 dissect_hello_nlpid_clv
132         },
133         {
134                 ISIS_CLV_L1H_IP_INTERFACE_ADDR,
135                 "IP Interface address(es)",
136                 &ett_isis_hello_clv_ipv4_int_addr,
137                 dissect_hello_ip_int_addr_clv
138         },
139         {
140                 ISIS_CLV_L1H_IPv6_INTERFACE_ADDR,
141                 "IPv6 Interface address(es)",
142                 &ett_isis_hello_clv_ipv6_int_addr,
143                 dissect_hello_ipv6_int_addr_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_AUTHENTICATION,
216                 "Authentication",
217                 &ett_isis_hello_clv_auth,
218                 dissect_hello_auth_clv
219         },
220         {
221                 ISIS_CLV_L2H_MT,
222                 "Multi Topology",
223                 &ett_isis_hello_clv_mt,
224                 dissect_hello_mt_clv
225         },
226         {
227                 0,
228                 "",
229                 NULL,
230                 NULL
231         }
232 };
233
234 static const isis_clv_handle_t clv_ptp_hello_opts[] = {
235         {
236                 ISIS_CLV_PTP_AREA_ADDRESS,
237                 "Area address(es)",
238                 &ett_isis_hello_clv_area_addr,
239                 dissect_hello_area_address_clv
240         },
241         {
242                 ISIS_CLV_PTP_PADDING,
243                 "Padding",
244                 &ett_isis_hello_clv_padding,
245                 dissect_hello_padding_clv
246         },
247         {
248                 ISIS_CLV_PTP_NLPID,
249                 "Protocols Supported",
250                 &ett_isis_hello_clv_nlpid,
251                 dissect_hello_nlpid_clv
252         },
253         {
254                 ISIS_CLV_PTP_IP_INTERFACE_ADDR,
255                 "IP Interface address(es)",
256                 &ett_isis_hello_clv_ipv4_int_addr,
257                 dissect_hello_ip_int_addr_clv
258         },
259         {
260                 ISIS_CLV_PTP_IPv6_INTERFACE_ADDR,
261                 "IPv6 Interface address(es)",
262                 &ett_isis_hello_clv_ipv6_int_addr,
263                 dissect_hello_ipv6_int_addr_clv
264         },
265         {
266                 ISIS_CLV_PTP_AUTHENTICATION_NS,
267                 "Authentication(non spec)",
268                 &ett_isis_hello_clv_auth,
269                 dissect_hello_auth_clv
270         },
271         {
272                 ISIS_CLV_PTP_AUTHENTICATION,
273                 "Authentication",
274                 &ett_isis_hello_clv_auth,
275                 dissect_hello_auth_clv
276         },
277         {
278                 ISIS_CLV_PTP_ADJ,
279                 "Point-to-point Adjacency State",
280                 &ett_isis_hello_clv_ptp_adj,
281                 dissect_hello_ptp_adj_clv
282         },
283         {
284                 ISIS_CLV_PTP_MT,
285                 "Multi Topology",
286                 &ett_isis_hello_clv_mt,
287                 dissect_hello_mt_clv
288         },
289         {
290                 0,
291                 "",
292                 NULL,
293                 NULL
294         }
295 };
296
297 /*
298  * Name: dissect_hello_nlpid_clv()
299  *
300  * Description:
301  *      Decode for a hello packets NLPID clv.  Calls into the
302  *      clv common one.
303  *
304  * Input:
305  *      tvbuff_t * : tvbuffer for packet data
306  *      packet_info * : info for current packet
307  *      proto_tree * : proto tree to build on (may be null)
308  *      int : current offset into packet data
309  *      int : length of IDs in packet.
310  *      int : length of this clv
311  *
312  * Output:
313  *      void, will modify proto_tree if not null.
314  */
315 static void 
316 dissect_hello_nlpid_clv(tvbuff_t *tvb, 
317         packet_info *pinfo, proto_tree *tree, int offset, 
318         int id_length, int length)
319 {
320         isis_dissect_nlpid_clv(tvb, pinfo, tree, offset, length);
321 }
322
323 /*
324  * Name: dissect_hello_mt_clv()
325  *
326  * Description:
327  *      Decode for a hello packets Multi Topology clv.  Calls into the
328  *      clv common one.
329  *
330  * Input:
331  *      tvbuff_t * : tvbuffer for packet data
332  *      packet_info * : info for current packet
333  *      proto_tree * : proto tree to build on (may be null)
334  *      int : current offset into packet data
335  *      int : length of IDs in packet.
336  *      int : length of this clv
337  *
338  * Output:
339  *      void, will modify proto_tree if not null.
340  */
341
342 static void 
343 dissect_hello_mt_clv(tvbuff_t *tvb, 
344         packet_info *pinfo, proto_tree *tree, int offset, 
345         int id_length, int length)
346 {
347         isis_dissect_mt_clv(tvb, pinfo, tree, offset, length,
348                 hf_isis_hello_clv_mt );
349 }
350
351 /*
352  * Name: dissect_hello_ip_int_addr_clv()
353  *
354  * Description:
355  *      Decode for a hello packets ip interface addr clv.  Calls into the
356  *      clv common one.
357  *
358  * Input:
359  *      tvbuff_t * : tvbuffer for packet data
360  *      packet_info * : info for current packet
361  *      proto_tree * : proto tree to build on (may be null)
362  *      int : current offset into packet data
363  *      int : length of IDs in packet.
364  *      int : length of this clv
365  *
366  * Output:
367  *      void, will modify proto_tree if not null.
368  */
369 static void 
370 dissect_hello_ip_int_addr_clv(tvbuff_t *tvb, 
371         packet_info *pinfo, proto_tree *tree, int offset, 
372         int id_length, int length)
373 {
374         isis_dissect_ip_int_clv(tvb, pinfo, tree, offset, length,
375                 hf_isis_hello_clv_ipv4_int_addr );
376 }
377
378 /*
379  * Name: dissect_hello_ipv6_int_addr_clv()
380  *
381  * Description:
382  *      Decode for a hello packets ipv6 interface addr clv.  Calls into the
383  *      clv common one.
384  *
385  * Input:
386  *      tvbuff_t * : tvbuffer for packet data
387  *      packet_info * : info for current packet
388  *      proto_tree * : proto tree to build on (may be null)
389  *      int : current offset into packet data
390  *      int : length of IDs in packet.
391  *      int : length of this clv
392  *
393  * Output:
394  *      void, will modify proto_tree if not null.
395  */
396 static void 
397 dissect_hello_ipv6_int_addr_clv(tvbuff_t *tvb, 
398         packet_info *pinfo, proto_tree *tree, int offset, 
399         int id_length, int length)
400 {
401         isis_dissect_ipv6_int_clv(tvb, pinfo, tree, offset, length,
402                 hf_isis_hello_clv_ipv6_int_addr );
403 }
404
405 /*
406  * Name: dissect_hello_auth_clv()
407  *
408  * Description:
409  *      Decode for a hello packets authenticaion clv.  Calls into the
410  *      clv common one.  An auth inside a hello packet is a perlink
411  *      password.
412  *
413  * Input:
414  *      tvbuff_t * : tvbuffer for packet data
415  *      packet_info * : info for current packet
416  *      proto_tree * : proto tree to build on (may be null)
417  *      int : current offset into packet data
418  *      int : length of IDs in packet.
419  *      int : length of this clv
420  *
421  * Output:
422  *      void, will modify proto_tree if not null.
423  */
424 static void 
425 dissect_hello_auth_clv(tvbuff_t *tvb, 
426         packet_info *pinfo, proto_tree *tree, int offset, 
427         int id_length, int length)
428 {
429         isis_dissect_authentication_clv(tvb, pinfo, tree, offset,
430                 length, "authentication" );
431 }
432
433 /*
434  * Name: dissect_hello_area_address_clv()
435  *
436  * Description:
437  *      Decode for a hello packets area address clv.  Calls into the
438  *      clv common one.
439  *
440  * Input:
441  *      tvbuff_t * : tvbuffer for packet data
442  *      packet_info * : info for current packet
443  *      proto_tree * : proto tree to build on (may be null)
444  *      int : current offset into packet data
445  *      int : length of IDs in packet.
446  *      int : length of this clv
447  *
448  * Output:
449  *      void, will modify proto_tree if not null.
450  */
451 static void 
452 dissect_hello_area_address_clv(tvbuff_t *tvb, 
453         packet_info *pinfo, proto_tree *tree, int offset, 
454         int id_length, int length)
455 {
456         isis_dissect_area_address_clv(tvb, pinfo, tree, offset, length);
457 }
458
459
460
461 static void 
462 dissect_hello_ptp_adj_clv(tvbuff_t *tvb, 
463                 packet_info *pinfo, proto_tree *tree, int offset, 
464                 int id_length, int length)
465 {
466         char adj_state[20];
467
468         switch(tvb_get_guint8(tvb, offset)) {
469           case 0:
470             strcpy(adj_state,"Up");
471             break;
472           case 1:
473             strcpy(adj_state,"Initializing");
474             break;
475           case 2:
476             strcpy(adj_state,"Down");
477             break;
478           default:
479             strcpy(adj_state,"<illegal value !!!>");
480             }
481
482         switch(length) {
483           case 1:
484             proto_tree_add_text ( tree, tvb, offset, 1,
485                                   "Adjacency State: %s", adj_state );
486             break;
487           case 5:
488             proto_tree_add_text ( tree, tvb, offset, 1,        
489                                   "Adjacency State: %s", adj_state ); 
490             proto_tree_add_text ( tree, tvb, offset+1, 4,        
491                                   "Extended Local circuit ID: 0x%08x", tvb_get_ntohl(tvb, offset+1) ); 
492             break;
493           case 11:
494             proto_tree_add_text ( tree, tvb, offset, 1,
495                                   "Adjacency State: %s", adj_state );
496             proto_tree_add_text ( tree, tvb, offset+1, 4,
497                                   "Extended Local circuit ID: 0x%08x", tvb_get_ntohl(tvb, offset+1) );
498             proto_tree_add_text ( tree, tvb, offset+5, 6,
499                                   "Neighbor SystemID: %s", print_system_id( tvb_get_ptr(tvb, offset+5, 6), 6 ) );
500             break;
501           case 15:
502             proto_tree_add_text ( tree, tvb, offset, 1,
503                                   "Adjacency State: %s", adj_state );
504             proto_tree_add_text ( tree, tvb, offset+1, 4,
505                                   "Extended Local circuit ID: 0x%08x", tvb_get_ntohl(tvb, offset+1) );
506             proto_tree_add_text ( tree, tvb, offset+5, 6,
507                                   "Neighbor SystemID: %s", print_system_id( tvb_get_ptr(tvb, offset+5, 6), 6 ) );  
508             proto_tree_add_text ( tree, tvb, offset+11, 4,
509                                   "Neighbor Extended Local circuit ID: 0x%08x", tvb_get_ntohl(tvb, offset+11) );
510             break;
511           default:
512             isis_dissect_unknown(tvb, pinfo, tree, offset,
513                                  "malformed TLV (%d vs 1,5,11,15)", length );
514             return;
515         }
516 }
517
518 /*
519  * Name: isis_dissect_is_neighbors_clv()
520  * 
521  * Description:
522  *      Take apart a IS neighbor packet.  A neighbor is n 6 byte packets.
523  *      (they tend to be an 802.3 MAC address, but its not required).
524  *
525  * Input:
526  *      tvbuff_t * : tvbuffer for packet data
527  *      packet_info * : info for current packet
528  *      proto_tree * : protocol display tree to fill out.  May be NULL
529  *      int : offset into packet data where we are.
530  *      int : length of IDs in packet.
531  *      int : length of clv we are decoding
532  * 
533  * Output:
534  *      void, but we will add to proto tree if !NULL.
535  */
536 static void 
537 dissect_hello_is_neighbors_clv(tvbuff_t *tvb, packet_info *pinfo,
538                 proto_tree *tree, int offset, int id_length, int length)
539 {
540         while ( length > 0 ) {
541                 if (length<6) {
542                         isis_dissect_unknown(tvb, pinfo, tree, offset,
543                                 "short is neighbor (%d vs 6)", length );
544                         return;
545                 }
546                 /* 
547                  * Lets turn the area address into "standard" 0000.0000.etc
548                  * format string.  
549                  */
550                 if ( tree ) {
551                         proto_tree_add_text ( tree, tvb, offset, 6, 
552                                 "IS Neighbor: %s", get_ether_name( tvb_get_ptr(tvb, offset, 6)) );
553                 }
554                 offset += 6;
555                 length -= 6;
556         }
557 }
558
559 /*
560  * Name: dissect_hello_padding_clv()
561  *
562  * Description:
563  *      Decode for a hello packet's padding clv.  Padding does nothing,
564  *      so we just return.
565  *
566  * Input:
567  *      tvbuff_t * : tvbuffer for packet data
568  *      packet_info * : info for current packet
569  *      proto_tree * : proto tree to build on (may be null)
570  *      int : current offset into packet data
571  *      int : length of IDs in packet.
572  *      int : length of this clv
573  *
574  * Output:
575  *      void
576  */
577 static void 
578 dissect_hello_padding_clv(tvbuff_t *tvb, packet_info *pinfo,
579         proto_tree *tree, int offset, int id_length, int length)
580 {
581         /* nothing to do here! */
582 }
583
584
585 /*
586  * Name: isis_dissect_isis_hello()
587  * 
588  * Description:
589  *      This procedure rips apart the various types of ISIS hellos.  L1H and
590  *      L2H's are identical for the most part, while the PTP hello has
591  *      a shorter header.
592  *
593  * Input:
594  *      tvbuff_t * : tvbuffer for packet data
595  *      packet_info * : info for current packet
596  *      proto_tree * : protocol display tree to add to.  May be NULL.
597  *      int offset : our offset into packet data.
598  *      int : hello type, a la packet-isis.h ISIS_TYPE_* values
599  *      int : header length of packet.
600  *      int : length of IDs in packet.
601  *
602  * Output:
603  *      void, will modify proto_tree if not NULL.
604  */     
605 void 
606 isis_dissect_isis_hello(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
607         int offset, int hello_type, int header_length, int id_length)
608 {
609         proto_item      *ti;
610         proto_tree      *hello_tree = NULL;
611         int             len;
612         guint8          octet;
613         const guint8    *source_id;
614         guint16         pdu_length;
615         const guint8    *lan_id;
616
617         if (tree) {
618                 ti = proto_tree_add_text(tree, tvb, offset,
619                     tvb_length_remaining(tvb, offset), "ISIS HELLO");
620                 hello_tree = proto_item_add_subtree(ti, ett_isis_hello);
621                 octet = tvb_get_guint8(tvb, offset);
622                 proto_tree_add_uint_format(hello_tree,
623                         hf_isis_hello_circuit_reserved,
624                         tvb, offset, 1, octet,
625                         "Circuit type              : %s, reserved(0x%02x == 0)",
626                                 val_to_str(octet&ISIS_HELLO_CTYPE_MASK,
627                                         isis_hello_circuit_type_vals,
628                                         "Unknown (0x%x)"),
629                                 octet&ISIS_HELLO_CT_RESERVED_MASK
630                         );
631         }
632         offset += 1;
633
634         if (tree) {
635                 source_id = tvb_get_ptr(tvb, offset, id_length);
636                 proto_tree_add_bytes_format(hello_tree, hf_isis_hello_source_id, tvb,
637                                     offset, id_length, source_id,
638                                     "SystemID{ Sender of PDU } : %s", 
639                                     print_system_id( source_id, id_length ) );
640         }
641         offset += id_length;
642
643         if (tree) {
644                 proto_tree_add_item(hello_tree, hf_isis_hello_holding_timer, tvb,
645                                     offset, 2, FALSE);
646         }
647         offset += 2;
648
649         pdu_length = tvb_get_ntohs(tvb, offset);
650         if (tree) {
651                 proto_tree_add_uint(hello_tree, hf_isis_hello_pdu_length, tvb,
652                                     offset, 2, pdu_length);
653         }
654         offset += 2;
655
656         if (hello_type == ISIS_TYPE_PTP_HELLO) {
657                 if (tree) {
658                         proto_tree_add_item(hello_tree, hf_isis_hello_local_circuit_id, tvb,
659                                          offset, 1, FALSE );
660                 }
661                 offset += 1;
662         } else { 
663
664                 if (tree) {
665                         octet = tvb_get_guint8(tvb, offset);
666                         proto_tree_add_uint_format(hello_tree, hf_isis_hello_priority_reserved, tvb,
667                                     offset, 1, octet,
668                                     "Priority                  : %d, reserved(0x%02x == 0)",
669                                         octet&ISIS_HELLO_PRIORITY_MASK,
670                                         octet&ISIS_HELLO_P_RESERVED_MASK );
671                 }
672                 offset += 1;
673
674                 if (tree) {
675                         lan_id = tvb_get_ptr(tvb, offset, id_length+1);
676                         proto_tree_add_bytes_format(hello_tree, hf_isis_hello_lan_id, tvb, 
677                                      offset, id_length + 1, lan_id,
678                                          "SystemID{ Designated IS } : %s",
679                                               print_system_id( lan_id, id_length + 1 ) );
680                 }
681                 offset += id_length + 1;
682         }
683
684         len = pdu_length;
685         len -= header_length;
686         if (len < 0) {
687                 isis_dissect_unknown(tvb, pinfo, tree, offset,
688                         "Packet header length %d went beyond packet", 
689                         header_length );
690                 return;
691         }
692         /*
693          * Now, we need to decode our CLVs.  We need to pass in
694          * our list of valid ones!
695          */
696         if (hello_type == ISIS_TYPE_L1_HELLO){
697                 isis_dissect_clvs(tvb, pinfo, hello_tree, offset,
698                         clv_l1_hello_opts, len, id_length,
699                         ett_isis_hello_clv_unknown);
700         } else if (hello_type == ISIS_TYPE_L2_HELLO) {
701                 isis_dissect_clvs(tvb, pinfo, hello_tree, offset,
702                         clv_l2_hello_opts, len, id_length,
703                         ett_isis_hello_clv_unknown);
704         } else {
705                 isis_dissect_clvs(tvb, pinfo, hello_tree, offset,
706                         clv_ptp_hello_opts, len, id_length,
707                         ett_isis_hello_clv_unknown);
708         }
709 }
710
711 /*
712  * Name: isis_register_hello()
713  *
714  * Description:
715  *      Register our protocol sub-sets with protocol manager.
716  *
717  * Input: 
718  *      int : protocol index for the ISIS protocol
719  *
720  * Output:
721  *      void
722  */
723 void
724 isis_register_hello(int proto_isis) {
725         static hf_register_info hf[] = {
726                 { &hf_isis_hello_circuit_reserved,
727                 { "Circuit type              ", "isis.hello.circuit_type",
728                         FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL }},
729
730                 { &hf_isis_hello_source_id,
731                 { "SystemID{ Sender of PDU } ", "isis.hello.source_id",
732                         FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
733
734                 { &hf_isis_hello_holding_timer,
735                 { "Holding timer             ", "isis.hello.holding_timer", 
736                         FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
737
738                 { &hf_isis_hello_pdu_length,
739                 { "PDU length                ", "isis.hello.pdu_length",
740                         FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
741
742                 { &hf_isis_hello_priority_reserved,
743                  { "Priority                 ", "isis.hello.priority",
744                         FT_UINT8, BASE_DEC, NULL, ISIS_HELLO_P_RESERVED_MASK, "", HFILL }},
745
746                 { &hf_isis_hello_lan_id,
747                 { "SystemID{ Designated IS } ", "isis.hello.lan_id",
748                         FT_BYTES, BASE_DEC, NULL, 0x0, "", HFILL }},
749
750                 { &hf_isis_hello_local_circuit_id,
751                 { "Local circuit ID          ", "isis.hello.local_circuit_id",
752                         FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }},
753
754                 { &hf_isis_hello_clv_ipv4_int_addr,
755                 { "IPv4 interface address    ", "isis.hello.clv_ipv4_int_addr",
756                         FT_IPv4, BASE_NONE, NULL, 0x0, "", HFILL }},
757
758                 { &hf_isis_hello_clv_ipv6_int_addr,
759                 { "IPv6 interface address    ", "isis.hello.clv_ipv6_int_addr",
760                         FT_IPv6, BASE_NONE, NULL, 0x0, "", HFILL }},
761
762                 { &hf_isis_hello_clv_ptp_adj,
763                 { "Point-to-point Adjacency  ", "isis.hello.clv_ptp_adj",
764                         FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }},
765
766         };
767         static gint *ett[] = {
768                 &ett_isis_hello,
769                 &ett_isis_hello_clv_area_addr,
770                 &ett_isis_hello_clv_is_neighbors,
771                 &ett_isis_hello_clv_padding,
772                 &ett_isis_hello_clv_unknown,
773                 &ett_isis_hello_clv_nlpid,
774                 &ett_isis_hello_clv_auth,
775                 &ett_isis_hello_clv_ipv4_int_addr,
776                 &ett_isis_hello_clv_ipv6_int_addr,
777                 &ett_isis_hello_clv_ptp_adj,
778                 &ett_isis_hello_clv_mt
779         };
780
781         proto_register_field_array(proto_isis, hf, array_length(hf));
782         proto_register_subtree_array(ett, array_length(ett));
783 }