From Joerg Mayer: explicitly fill in all members of a
[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.16 2001/06/18 02:17:47 guy Exp $
5  * Stuart Stanley <stuarts@mxmail.net>
6  *
7  * Ethereal - Network traffic analyzer
8  * By Gerald Combs <gerald@zing.org>
9  * Copyright 1998 Gerald Combs
10  *
11  * 
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  * 
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  * 
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25  *
26  *
27  */
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32
33 #ifdef HAVE_SYS_TYPES_H
34 # include <sys/types.h>
35 #endif
36
37 #include <stdio.h>
38 #include <string.h>
39 #include <glib.h>
40 #include "packet.h"
41 #include "packet-osi.h"
42 #include "packet-isis.h"
43 #include "packet-isis-clv.h"
44 #include "packet-isis-hello.h"
45
46 /* hello packets */
47 static int proto_isis_hello                  = -1;
48 static int hf_isis_hello_circuit_reserved    = -1;
49 static int hf_isis_hello_source_id           = -1;
50 static int hf_isis_hello_holding_timer       = -1;
51 static int hf_isis_hello_pdu_length          = -1;
52 static int hf_isis_hello_priority_reserved   = -1;
53 static int hf_isis_hello_lan_id              = -1;
54 static int hf_isis_hello_local_circuit_id    = -1;
55 static int hf_isis_hello_clv_ipv4_int_addr   = -1;
56 static int hf_isis_hello_clv_ipv6_int_addr   = -1;
57
58 static gint ett_isis_hello                   = -1;
59 static gint ett_isis_hello_clv_area_addr     = -1;
60 static gint ett_isis_hello_clv_is_neighbors  = -1;
61 static gint ett_isis_hello_clv_padding       = -1;
62 static gint ett_isis_hello_clv_unknown       = -1;
63 static gint ett_isis_hello_clv_nlpid         = -1;
64 static gint ett_isis_hello_clv_auth          = -1;
65 static gint ett_isis_hello_clv_ipv4_int_addr = -1;
66 static gint ett_isis_hello_clv_ipv6_int_addr = -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_area_address_clv(const u_char *pd, int offset, 
79                 guint length, int id_length, frame_data *fd, proto_tree *tree);
80 static void dissect_hello_is_neighbors_clv(const u_char *pd, int offset, 
81                 guint length, int id_length, frame_data *fd, proto_tree *tree);
82 static void dissect_hello_padding_clv(const u_char *pd, int offset, 
83                 guint length, int id_length, frame_data *fd, proto_tree *tree);
84 static void dissect_hello_nlpid_clv(const u_char *pd, int offset, 
85                 guint length, int id_length, frame_data *fd, proto_tree *tree);
86 static void dissect_hello_ip_int_addr_clv(const u_char *pd, int offset, 
87                 guint length, int id_length, frame_data *fd, proto_tree *tree);
88 static void dissect_hello_ipv6_int_addr_clv(const u_char *pd, int offset, 
89                 guint length, int id_length, frame_data *fd, proto_tree *tree);
90 static void dissect_hello_auth_clv(const u_char *pd, int offset, 
91                 guint length, int id_length, frame_data *fd, proto_tree *tree);
92
93 static const isis_clv_handle_t clv_l1_hello_opts[] = {
94         {
95                 ISIS_CLV_L1H_AREA_ADDRESS,
96                 "Area address(es)",
97                 &ett_isis_hello_clv_area_addr,
98                 dissect_hello_area_address_clv
99         },
100         {
101                 ISIS_CLV_L1H_IS_NEIGHBORS,
102                 "IS Neighbor(s)",
103                 &ett_isis_hello_clv_is_neighbors,
104                 dissect_hello_is_neighbors_clv
105         },
106         {
107                 ISIS_CLV_L1H_PADDING,
108                 "Padding",
109                 &ett_isis_hello_clv_padding,
110                 dissect_hello_padding_clv
111         },
112         {
113                 ISIS_CLV_L1H_NLPID,
114                 "Protocols Supported",
115                 &ett_isis_hello_clv_nlpid,
116                 dissect_hello_nlpid_clv
117         },
118         {
119                 ISIS_CLV_L1H_IP_INTERFACE_ADDR,
120                 "IP Interface address(es)",
121                 &ett_isis_hello_clv_ipv4_int_addr,
122                 dissect_hello_ip_int_addr_clv
123         },
124         {
125                 ISIS_CLV_L1H_IPv6_INTERFACE_ADDR,
126                 "IPv6 Interface address(es)",
127                 &ett_isis_hello_clv_ipv6_int_addr,
128                 dissect_hello_ipv6_int_addr_clv
129         },
130         {
131                 ISIS_CLV_L1H_AUTHENTICATION_NS,
132                 "Authentication(non spec)",
133                 &ett_isis_hello_clv_auth,
134                 dissect_hello_auth_clv
135         },
136         {
137                 ISIS_CLV_L1H_AUTHENTICATION,
138                 "Authentication",
139                 &ett_isis_hello_clv_auth,
140                 dissect_hello_auth_clv
141         },
142         {
143                 0,
144                 "",
145                 NULL,
146                 NULL
147         }
148 };
149
150 static const isis_clv_handle_t clv_l2_hello_opts[] = {
151         {
152                 ISIS_CLV_L2H_AREA_ADDRESS,
153                 "Area address(es)",
154                 &ett_isis_hello_clv_area_addr,
155                 dissect_hello_area_address_clv
156         },
157         {
158                 ISIS_CLV_L2H_IS_NEIGHBORS,
159                 "IS Neighbor(s)",
160                 &ett_isis_hello_clv_is_neighbors,
161                 dissect_hello_is_neighbors_clv
162         },
163         {
164                 ISIS_CLV_L2H_PADDING,
165                 "Padding",
166                 &ett_isis_hello_clv_padding,
167                 dissect_hello_padding_clv
168         },
169         {
170                 ISIS_CLV_L2H_NLPID,
171                 "Protocols Supported",
172                 &ett_isis_hello_clv_nlpid,
173                 dissect_hello_nlpid_clv
174         },
175         {
176                 ISIS_CLV_L2H_IP_INTERFACE_ADDR,
177                 "IP Interface address(es)",
178                 &ett_isis_hello_clv_ipv4_int_addr,
179                 dissect_hello_ip_int_addr_clv
180         },
181         {
182                 ISIS_CLV_L2H_IPv6_INTERFACE_ADDR,
183                 "IPv6 Interface address(es)",
184                 &ett_isis_hello_clv_ipv6_int_addr,
185                 dissect_hello_ipv6_int_addr_clv
186         },
187         {
188                 ISIS_CLV_L2H_AUTHENTICATION_NS,
189                 "Authentication(non spec)",
190                 &ett_isis_hello_clv_auth,
191                 dissect_hello_auth_clv
192         },
193         {
194                 ISIS_CLV_L2H_AUTHENTICATION,
195                 "Authentication",
196                 &ett_isis_hello_clv_auth,
197                 dissect_hello_auth_clv
198         },
199         {
200                 0,
201                 "",
202                 NULL,
203                 NULL
204         }
205 };
206
207 static const isis_clv_handle_t clv_ptp_hello_opts[] = {
208         {
209                 ISIS_CLV_PTP_AREA_ADDRESS,
210                 "Area address(es)",
211                 &ett_isis_hello_clv_area_addr,
212                 dissect_hello_area_address_clv
213         },
214         {
215                 ISIS_CLV_PTP_PADDING,
216                 "Padding",
217                 &ett_isis_hello_clv_padding,
218                 dissect_hello_padding_clv
219         },
220         {
221                 ISIS_CLV_PTP_NLPID,
222                 "Protocols Supported",
223                 &ett_isis_hello_clv_nlpid,
224                 dissect_hello_nlpid_clv
225         },
226         {
227                 ISIS_CLV_PTP_IP_INTERFACE_ADDR,
228                 "IP Interface address(es)",
229                 &ett_isis_hello_clv_ipv4_int_addr,
230                 dissect_hello_ip_int_addr_clv
231         },
232         {
233                 ISIS_CLV_PTP_IPv6_INTERFACE_ADDR,
234                 "IPv6 Interface address(es)",
235                 &ett_isis_hello_clv_ipv6_int_addr,
236                 dissect_hello_ipv6_int_addr_clv
237         },
238         {
239                 ISIS_CLV_PTP_AUTHENTICATION_NS,
240                 "Authentication(non spec)",
241                 &ett_isis_hello_clv_auth,
242                 dissect_hello_auth_clv
243         },
244         {
245                 ISIS_CLV_PTP_AUTHENTICATION,
246                 "Authentication",
247                 &ett_isis_hello_clv_auth,
248                 dissect_hello_auth_clv
249         },
250         {
251                 0,
252                 "",
253                 NULL,
254                 NULL
255         }
256 };
257
258 /*
259  * Name: dissect_hello_nlpid_clv()
260  *
261  * Description:
262  *      Decode for a hello packets NLPID clv.  Calls into the
263  *      clv common one.
264  *
265  * Input:
266  *      u_char * : packet data
267  *      int : current offset into packet data
268  *      guint : length of this clv
269  *      int : length of IDs in packet.
270  *      frame_data * : frame data
271  *      proto_tree * : proto tree to build on (may be null)
272  *
273  * Output:
274  *      void, will modify proto_tree if not null.
275  */
276 static void 
277 dissect_hello_nlpid_clv(const u_char *pd, int offset, 
278                 guint length, int id_length, frame_data *fd, proto_tree *tree) {
279         isis_dissect_nlpid_clv(pd, offset, length, fd, tree );
280 }
281
282 /*
283  * Name: dissect_hello_ip_int_addr_clv()
284  *
285  * Description:
286  *      Decode for a hello packets ip interface addr clv.  Calls into the
287  *      clv common one.
288  *
289  * Input:
290  *      u_char * : packet data
291  *      int : current offset into packet data
292  *      guint : length of this clv
293  *      int : length of IDs in packet.
294  *      frame_data * : frame data
295  *      proto_tree * : proto tree to build on (may be null)
296  *
297  * Output:
298  *      void, will modify proto_tree if not null.
299  */
300 static void 
301 dissect_hello_ip_int_addr_clv(const u_char *pd, int offset, 
302                 guint length, int id_length, frame_data *fd, proto_tree *tree) {
303         isis_dissect_ip_int_clv(pd, offset, length, fd, tree, 
304                 hf_isis_hello_clv_ipv4_int_addr );
305 }
306
307 /*
308  * Name: dissect_hello_ipv6_int_addr_clv()
309  *
310  * Description:
311  *      Decode for a hello packets ipv6 interface addr clv.  Calls into the
312  *      clv common one.
313  *
314  * Input:
315  *      u_char * : packet data
316  *      int : current offset into packet data
317  *      guint : length of this clv
318  *      int : length of IDs in packet.
319  *      frame_data * : frame data
320  *      proto_tree * : proto tree to build on (may be null)
321  *
322  * Output:
323  *      void, will modify proto_tree if not null.
324  */
325 static void 
326 dissect_hello_ipv6_int_addr_clv(const u_char *pd, int offset, 
327                 guint length, int id_length, frame_data *fd, proto_tree *tree) {
328         isis_dissect_ipv6_int_clv(pd, offset, length, fd, tree, 
329                 hf_isis_hello_clv_ipv6_int_addr );
330 }
331
332 /*
333  * Name: dissect_hello_auth_clv()
334  *
335  * Description:
336  *      Decode for a hello packets authenticaion clv.  Calls into the
337  *      clv common one.  An auth inside a hello packet is a perlink
338  *      password.
339  *
340  * Input:
341  *      u_char * : packet data
342  *      int : current offset into packet data
343  *      guint : length of this clv
344  *      int : length of IDs in packet.
345  *      frame_data * : frame data
346  *      proto_tree * : proto tree to build on (may be null)
347  *
348  * Output:
349  *      void, will modify proto_tree if not null.
350  */
351 static void 
352 dissect_hello_auth_clv(const u_char *pd, int offset, 
353                 guint length, int id_length, frame_data *fd, proto_tree *tree) {
354         isis_dissect_authentication_clv(pd, offset, length, fd, tree, 
355                 "authentication" );
356 }
357
358 /*
359  * Name: dissect_hello_area_address_clv()
360  *
361  * Description:
362  *      Decode for a hello packets area address clv.  Calls into the
363  *      clv common one.
364  *
365  * Input:
366  *      u_char * : packet data
367  *      int : current offset into packet data
368  *      guint : length of this clv
369  *      int : length of IDs in packet.
370  *      frame_data * : frame data
371  *      proto_tree * : proto tree to build on (may be null)
372  *
373  * Output:
374  *      void, will modify proto_tree if not null.
375  */
376 static void 
377 dissect_hello_area_address_clv(const u_char *pd, int offset, 
378                 guint length, int id_length, frame_data *fd, proto_tree *tree) {
379         isis_dissect_area_address_clv(pd, offset, length, fd, tree );
380 }
381
382 /*
383  * Name: isis_dissect_is_neighbors_clv()
384  * 
385  * Description:
386  *      Take apart a IS neighbor packet.  A neighbor is n 6 byte packets.
387  *      (they tend to be an 802.3 MAC address, but its not required).
388  *
389  * Input:
390  *      u_char * : packet data
391  *      int : offset into packet data where we are.
392  *      guint : length of clv we are decoding
393  *      int : length of IDs in packet.
394  *      frame_data * : frame data (complete frame)
395  *      proto_tree * : protocol display tree to fill out.  May be NULL
396  *      gint : tree id to use for proto tree.
397  * 
398  * Output:
399  *      void, but we will add to proto tree if !NULL.
400  */
401 void 
402 dissect_hello_is_neighbors_clv(const u_char *pd, int offset, 
403                 guint length, int id_length, frame_data *fd, proto_tree *tree ) {
404         while ( length > 0 ) {
405                 if (length<6) {
406                         isis_dissect_unknown(offset, length, tree, fd, 
407                                 "short is neighbor (%d vs 6)", length );
408                         return;
409                 }
410                 /* 
411                  * Lets turn the area address into "standard" 0000.0000.etc
412                  * format string.  
413                  */
414                 if ( tree ) {
415                         proto_tree_add_text ( tree, NullTVB, offset, 6, 
416                                 "IS Neighbor: %s", print_system_id( pd + offset, 6 ) ); 
417                 }
418                 offset += 6;
419                 length -= 6;
420         }
421 }
422
423
424 /*
425  * Name: dissect_hello_padding_clv()
426  *
427  * Description:
428  *      Decode for a hello packet's padding clv.  Padding does nothing,
429  *      so we just return.
430  *
431  * Input:
432  *      u_char * : packet data
433  *      int : current offset into packet data
434  *      guint : length of this clv
435  *      int : length of IDs in packet.
436  *      frame_data * : frame data
437  *      proto_tree * : proto tree to build on (may be null)
438  *
439  * Output:
440  *      void
441  */
442 static void 
443 dissect_hello_padding_clv(const u_char *pd, int offset, guint length, 
444                 int id_length, frame_data *fd, proto_tree *tree) {
445         /* nothing to do here! */
446 }
447
448 /*
449  * Name: isis_dissect_isis_hello()
450  * 
451  * Description:
452  *      This procedure rips apart the various types of ISIS hellos.  L1H and
453  *      L2H's are identical for the most part, while the PTP hello has
454  *      a shorter header.
455  *
456  * Input:
457  *      int : hello type, a la packet-isis.h ISIS_TYPE_* values
458  *      int : header length of packet.
459  *      int : length of IDs in packet.
460  *      u_char * : packet data
461  *      int offset : our offset into packet data.
462  *      frame_data * : frame data
463  *      proto_tree * : protocol display tree to add to.  May be NULL.
464  *
465  * Output:
466  *      void, will modify proto_tree if not NULL.
467  */     
468 void 
469 isis_dissect_isis_hello(int hello_type, int header_length, int id_length,
470                 const u_char *pd, int offset, frame_data *fd, proto_tree *tree){
471         proto_item      *ti;
472         proto_tree      *hello_tree = NULL;
473         int             len;
474         int             hlen;
475         guint16         pdu_length;
476
477         OLD_CHECK_DISPLAY_AS_DATA(proto_isis_hello, pd, offset, fd, tree);
478
479         if (hello_type == ISIS_TYPE_PTP_HELLO) {
480                 hlen = 1+id_length+2+2+1;
481         } else {
482                 hlen = 1+id_length+2+2+1+id_length+1;
483         }
484
485         if (!BYTES_ARE_IN_FRAME(offset, hlen)) {
486                 isis_dissect_unknown(offset, hlen, tree, fd,
487                         "not enough capture data for header (%d vs %d)",
488                         hlen, END_OF_FRAME);
489                 return;
490         }
491
492         if (tree) {
493                 ti = proto_tree_add_item(tree, proto_isis_hello, NullTVB,
494                         offset, END_OF_FRAME, FALSE);
495                 hello_tree = proto_item_add_subtree(ti, ett_isis_hello);
496                 proto_tree_add_uint_format(hello_tree,
497                         hf_isis_hello_circuit_reserved,
498                         NullTVB, offset, 1, pd[offset],
499                         "Circuit type              : %s, reserved(0x%02x == 0)",
500                                 val_to_str(pd[offset]&ISIS_HELLO_CTYPE_MASK,
501                                         isis_hello_circuit_type_vals,
502                                         "Unknown (0x%x)"),
503                                 pd[offset]&ISIS_HELLO_CT_RESERVED_MASK
504                         );
505         }
506         offset += 1;
507
508         if (tree) {
509                 proto_tree_add_bytes_format(hello_tree, hf_isis_hello_source_id, NullTVB,
510                                     offset, id_length, &pd[offset],
511                                     "SystemID{ Sender of PDU } : %s", 
512                      print_system_id( pd + offset, id_length ) );
513         }
514         offset += id_length;
515
516         if (tree) {
517                 proto_tree_add_uint(hello_tree, hf_isis_hello_holding_timer, NullTVB,
518                                     offset, 2, pntohs(&pd[offset]));
519         }
520         offset += 2;
521
522         pdu_length = pntohs(&pd[offset]);
523         if (tree) {
524                 proto_tree_add_uint(hello_tree, hf_isis_hello_pdu_length, NullTVB,
525                                     offset, 2, pdu_length);
526         }
527         offset += 2;
528
529         if (hello_type == ISIS_TYPE_PTP_HELLO) {
530                 if (tree) {
531                         proto_tree_add_uint(hello_tree, hf_isis_hello_local_circuit_id, NullTVB,
532                                          offset, 1, pd[offset] );
533                 }
534                 offset += 1;
535         } else { 
536
537                 if (tree) {
538                         proto_tree_add_uint_format(hello_tree, hf_isis_hello_priority_reserved, NullTVB,
539                                     offset, 1, pd[offset],
540                                     "Priority                  : %d, reserved(0x%02x == 0)",
541                                         pd[offset]&ISIS_HELLO_PRIORITY_MASK,
542                                         pd[offset]&ISIS_HELLO_P_RESERVED_MASK );
543                 }
544                 offset += 1;
545
546                 if (tree) {
547                         proto_tree_add_bytes_format(hello_tree, hf_isis_hello_lan_id, NullTVB, 
548                                      offset, id_length + 1, &pd[offset],
549                                          "SystemID{ Designated IS } : %s",
550                                               print_system_id( pd + offset, id_length + 1 ) );
551                 }
552                 offset += id_length + 1;
553         }
554
555         len = pdu_length;
556         len -= header_length;
557         if (len < 0) {
558                 isis_dissect_unknown(offset, header_length, tree, fd, 
559                         "packet header length %d went beyond packet", 
560                         header_length );
561                 return;
562         }
563         /*
564          * Now, we need to decode our CLVs.  We need to pass in
565          * our list of valid ones!
566          */
567         if (hello_type == ISIS_TYPE_L1_HELLO){
568                 isis_dissect_clvs ( clv_l1_hello_opts, len, id_length, pd,
569                         offset, fd, hello_tree, ett_isis_hello_clv_unknown );
570         } else if (hello_type == ISIS_TYPE_L2_HELLO) {
571                 isis_dissect_clvs ( clv_l2_hello_opts, len, id_length, pd,
572                         offset, fd, hello_tree, ett_isis_hello_clv_unknown );
573         } else {
574                 isis_dissect_clvs ( clv_ptp_hello_opts, len, id_length, pd,
575                         offset, fd, hello_tree, ett_isis_hello_clv_unknown );
576         }
577 }
578
579 /*
580  * Name: proto_register_isis_hello()
581  *
582  * Description:
583  *      Register our protocol sub-sets with protocol manager.
584  *      NOTE: this procedure is autolinked by the makefile process that
585  *              builds register.c
586  *
587  * Input: 
588  *      void
589  *
590  * Output:
591  *      void
592  */
593 void
594 proto_register_isis_hello(void) {
595         static hf_register_info hf[] = {
596                 { &hf_isis_hello_circuit_reserved,
597                 { "Circuit type              ", "isis_hello.circuite_type",
598                         FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL }},
599
600                 { &hf_isis_hello_source_id,
601                 { "SystemID{ Sender of PDU } ", "isis_hello.source_id",
602                         FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
603
604                 { &hf_isis_hello_holding_timer,
605                 { "Holding timer             ", "isis_hello.holding_timer", 
606                         FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
607
608                 { &hf_isis_hello_pdu_length,
609                 { "PDU length                ", "isis_hello.pdu_length",
610                         FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
611
612                 { &hf_isis_hello_priority_reserved,
613                  { "Priority                 ", "isis_hello.priority",
614                         FT_UINT8, BASE_DEC, NULL, ISIS_HELLO_P_RESERVED_MASK, "", HFILL }},
615
616                 { &hf_isis_hello_lan_id,
617                 { "SystemID{ Designated IS } ", "isis_hello.lan_id",
618                         FT_BYTES, BASE_DEC, NULL, 0x0, "", HFILL }},
619
620                 { &hf_isis_hello_local_circuit_id,
621                 { "Local circuit ID          ", "isis_hello.local_circuit_id",
622                         FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }},
623
624                 { &hf_isis_hello_clv_ipv4_int_addr,
625                 { "IPv4 interface address    ", "isis_hello.clv_ipv4_int_addr",
626                         FT_IPv4, BASE_NONE, NULL, 0x0, "", HFILL }},
627
628                 { &hf_isis_hello_clv_ipv6_int_addr,
629                 { "IPv6 interface address    ", "isis_hello.clv_ipv6_int_addr",
630                         FT_IPv6, BASE_NONE, NULL, 0x0, "", HFILL }},
631
632         };
633         static gint *ett[] = {
634                 &ett_isis_hello,
635                 &ett_isis_hello_clv_area_addr,
636                 &ett_isis_hello_clv_is_neighbors,
637                 &ett_isis_hello_clv_padding,
638                 &ett_isis_hello_clv_unknown,
639                 &ett_isis_hello_clv_nlpid,
640                 &ett_isis_hello_clv_auth,
641                 &ett_isis_hello_clv_ipv4_int_addr,
642                 &ett_isis_hello_clv_ipv6_int_addr
643         };
644
645         proto_isis_hello = proto_register_protocol("ISIS HELLO",
646             "ISIS HELLO", "isis_hello");
647         proto_register_field_array(proto_isis_hello, hf, array_length(hf));
648         proto_register_subtree_array(ett, array_length(ett));
649 }