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