2 * Routines for decoding isis hello packets and their CLVs
4 * $Id: packet-isis-hello.c,v 1.2 2000/01/24 03:33:33 guy Exp $
5 * Stuart Stanley <stuarts@mxmail.net>
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@zing.org>
9 * Copyright 1998 Gerald Combs
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.
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.
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.
33 #ifdef HAVE_SYS_TYPES_H
34 # include <sys/types.h>
41 #include "packet-isis.h"
42 #include "packet-isis-clv.h"
43 #include "packet-isis-hello.h"
46 static int proto_isis_hello = -1;
47 static int hf_isis_hello_circuit_reserved = -1;
48 static int hf_isis_hello_source_id = -1;
49 static int hf_isis_hello_holding_timer = -1;
50 static int hf_isis_hello_pdu_length = -1;
51 static int hf_isis_hello_priority_reserved = -1;
52 static int hf_isis_hello_lan_id = -1;
53 static int hf_isis_hello_local_circuit_id = -1;
54 static int hf_isis_hello_clv_ipv4_int_addr = -1;
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;
65 static const value_string isis_hello_circuit_type_vals[] = {
66 { ISIS_HELLO_TYPE_RESERVED, "Reserved 0 (discard PDU)"},
67 { ISIS_HELLO_TYPE_LEVEL_1, "Level 1 only"},
68 { ISIS_HELLO_TYPE_LEVEL_2, "Level 2 only"},
69 { ISIS_HELLO_TYPE_LEVEL_12, "Level 1 and 2"},
73 * Predclare dissectors for use in clv dissection.
75 static void dissect_hello_area_address_clv(const u_char *pd, int offset,
76 guint length, frame_data *fd, proto_tree *tree);
77 static void dissect_hello_is_neighbors_clv(const u_char *pd, int offset,
78 guint length, frame_data *fd, proto_tree *tree);
79 static void dissect_hello_padding_clv(const u_char *pd, int offset,
80 guint length, frame_data *fd, proto_tree *tree);
81 static void dissect_hello_nlpid_clv(const u_char *pd, int offset,
82 guint length, frame_data *fd, proto_tree *tree);
83 static void dissect_hello_ip_int_addr_clv(const u_char *pd, int offset,
84 guint length, frame_data *fd, proto_tree *tree);
85 static void dissect_hello_auth_clv(const u_char *pd, int offset,
86 guint length, frame_data *fd, proto_tree *tree);
88 static const isis_clv_handle_t clv_l1_hello_opts[] = {
90 ISIS_CLV_L1H_AREA_ADDRESS,
92 &ett_isis_hello_clv_area_addr,
93 dissect_hello_area_address_clv
96 ISIS_CLV_L1H_IS_NEIGHBORS,
98 &ett_isis_hello_clv_is_neighbors,
99 dissect_hello_is_neighbors_clv
102 ISIS_CLV_L1H_PADDING,
104 &ett_isis_hello_clv_padding,
105 dissect_hello_padding_clv
110 &ett_isis_hello_clv_nlpid,
111 dissect_hello_nlpid_clv
114 ISIS_CLV_L1H_IP_INTERFACE_ADDR,
115 "IP Interface address(es)",
116 &ett_isis_hello_clv_ipv4_int_addr,
117 dissect_hello_ip_int_addr_clv
120 ISIS_CLV_L1H_AUTHENTICATION_NS,
121 "Authentication(non spec)",
122 &ett_isis_hello_clv_auth,
123 dissect_hello_auth_clv
126 ISIS_CLV_L1H_AUTHENTICATION,
128 &ett_isis_hello_clv_auth,
129 dissect_hello_auth_clv
139 static const isis_clv_handle_t clv_l2_hello_opts[] = {
141 ISIS_CLV_L2H_AREA_ADDRESS,
143 &ett_isis_hello_clv_area_addr,
144 dissect_hello_area_address_clv
147 ISIS_CLV_L2H_IS_NEIGHBORS,
149 &ett_isis_hello_clv_is_neighbors,
150 dissect_hello_is_neighbors_clv
153 ISIS_CLV_L2H_PADDING,
155 &ett_isis_hello_clv_padding,
156 dissect_hello_padding_clv
161 &ett_isis_hello_clv_nlpid,
162 dissect_hello_nlpid_clv
165 ISIS_CLV_L2H_IP_INTERFACE_ADDR,
166 "IP Interface address(es)",
167 &ett_isis_hello_clv_ipv4_int_addr,
168 dissect_hello_ip_int_addr_clv
171 ISIS_CLV_L2H_AUTHENTICATION_NS,
172 "Authentication(non spec)",
173 &ett_isis_hello_clv_auth,
174 dissect_hello_auth_clv
177 ISIS_CLV_L2H_AUTHENTICATION,
179 &ett_isis_hello_clv_auth,
180 dissect_hello_auth_clv
190 static const isis_clv_handle_t clv_ptp_hello_opts[] = {
192 ISIS_CLV_PTP_AREA_ADDRESS,
194 &ett_isis_hello_clv_area_addr,
195 dissect_hello_area_address_clv
198 ISIS_CLV_PTP_PADDING,
200 &ett_isis_hello_clv_padding,
201 dissect_hello_padding_clv
206 &ett_isis_hello_clv_nlpid,
207 dissect_hello_nlpid_clv
210 ISIS_CLV_PTP_IP_INTERFACE_ADDR,
211 "IP Interface address(es)",
212 &ett_isis_hello_clv_ipv4_int_addr,
213 dissect_hello_ip_int_addr_clv
216 ISIS_CLV_PTP_AUTHENTICATION_NS,
217 "Authentication(non spec)",
218 &ett_isis_hello_clv_auth,
219 dissect_hello_auth_clv
222 ISIS_CLV_PTP_AUTHENTICATION,
224 &ett_isis_hello_clv_auth,
225 dissect_hello_auth_clv
236 * Name: dissect_hello_nlpid_clv()
239 * Decode for a hello packets NLPID clv. Calls into the
243 * u_char * : packet data
244 * int : current offset into packet data
245 * guint : length of this clv
246 * frame_data * : frame data
247 * proto_tree * : proto tree to build on (may be null)
250 * void, will modify proto_tree if not null.
253 dissect_hello_nlpid_clv(const u_char *pd, int offset,
254 guint length, frame_data *fd, proto_tree *tree) {
255 isis_dissect_nlpid_clv(pd, offset, length, fd, tree );
259 * Name: dissect_hello_ip_int_addr_clv()
262 * Decode for a hello packets ip interface addr clv. Calls into the
266 * u_char * : packet data
267 * int : current offset into packet data
268 * guint : length of this clv
269 * frame_data * : frame data
270 * proto_tree * : proto tree to build on (may be null)
273 * void, will modify proto_tree if not null.
276 dissect_hello_ip_int_addr_clv(const u_char *pd, int offset,
277 guint length, frame_data *fd, proto_tree *tree) {
278 isis_dissect_ip_int_clv(pd, offset, length, fd, tree,
279 hf_isis_hello_clv_ipv4_int_addr );
283 * Name: dissect_hello_auth_clv()
286 * Decode for a hello packets authenticaion clv. Calls into the
287 * clv common one. An auth inside a hello packet is a perlink
291 * u_char * : packet data
292 * int : current offset into packet data
293 * guint : length of this clv
294 * frame_data * : frame data
295 * proto_tree * : proto tree to build on (may be null)
298 * void, will modify proto_tree if not null.
301 dissect_hello_auth_clv(const u_char *pd, int offset,
302 guint length, frame_data *fd, proto_tree *tree) {
303 isis_dissect_authentication_clv(pd, offset, length, fd, tree,
304 "Per Link authentication" );
308 * Name: dissect_hello_area_address_clv()
311 * Decode for a hello packets area address clv. Calls into the
315 * u_char * : packet data
316 * int : current offset into packet data
317 * guint : length of this clv
318 * frame_data * : frame data
319 * proto_tree * : proto tree to build on (may be null)
322 * void, will modify proto_tree if not null.
325 dissect_hello_area_address_clv(const u_char *pd, int offset,
326 guint length, frame_data *fd, proto_tree *tree) {
327 isis_dissect_area_address_clv(pd, offset, length, fd, tree );
331 * Name: isis_dissect_is_neighbors_clv()
334 * Take apart a IS neighbor packet. A neighbor is n 6 byte packets.
335 * (they tend to be an 802.3 MAC address, but its not required).
338 * u_char * : packet data
339 * int : offset into packet data where we are.
340 * guint : length of clv we are decoding
341 * frame_data * : frame data (complete frame)
342 * proto_tree * : protocol display tree to fill out. May be NULL
343 * gint : tree id to use for proto tree.
346 * void, but we will add to proto tree if !NULL.
349 dissect_hello_is_neighbors_clv(const u_char *pd, int offset,
350 guint length, frame_data *fd, proto_tree *tree ) {
351 while ( length > 0 ) {
353 isis_dissect_unknown(offset, length, tree, fd,
354 "short is neighbor (%d vs 6)", length );
358 * Lets turn the area address into "standard" 0000.0000.etc
362 proto_tree_add_text ( tree, offset, 6,
363 "IS Neighbor: %02x%02x.%02x%02x.%02x%02x",
364 pd[offset], pd[offset+1], pd[offset+2],
365 pd[offset+3], pd[offset+3], pd[offset+4] );
374 * Name: dissect_hello_padding_clv()
377 * Decode for a hello packet's padding clv. Padding does nothing,
381 * u_char * : packet data
382 * int : current offset into packet data
383 * guint : length of this clv
384 * frame_data * : frame data
385 * proto_tree * : proto tree to build on (may be null)
391 dissect_hello_padding_clv(const u_char *pd, int offset, guint length,
392 frame_data *fd, proto_tree *tree) {
393 /* nothing to do here! */
397 * Name: isis_dissect_isis_hello()
400 * This procedure rips apart the various types of ISIS hellos. L1H and
401 * L2H's are identicle for the most part, while the PTP hello has
405 * int : hello type, alla packet-isis.h ISIS_TYPE_* values
406 * int : header length of packet.
407 * u_char * : packet data
408 * int offset : our offset into packet data.
409 * frame_data * : frame data
410 * proto_tree * : protocol display tree to add to. May be NULL.
413 * void, will modify proto_tree if not NULL.
416 isis_dissect_isis_hello(int hello_type, int header_length,
417 const u_char *pd, int offset, frame_data *fd, proto_tree *tree){
420 proto_tree *hello_tree = NULL;
424 if (hello_type == ISIS_TYPE_PTP_HELLO) {
425 hlen = sizeof(*ihp) - 6; /* make length correct */
430 if (!BYTES_ARE_IN_FRAME(offset, hlen)) {
431 isis_dissect_unknown(offset, hlen, tree, fd,
432 "not enough capture data for header (%d vs %d)",
437 ihp = (isis_hello_t *) &pd[offset];
440 ti = proto_tree_add_item(tree, proto_isis_hello,
441 offset, END_OF_FRAME, NULL);
442 hello_tree = proto_item_add_subtree(ti, ett_isis_hello);
443 proto_tree_add_item_format(hello_tree,
444 hf_isis_hello_circuit_reserved,
445 offset, 1, ihp->isis_hello_circuit_reserved,
446 "Circuit type: %s, reserved(0x%02x == 0)",
447 val_to_str(ihp->isis_hello_circuit,
448 isis_hello_circuit_type_vals,
450 ihp->isis_hello_creserved
453 proto_tree_add_item_format(hello_tree, hf_isis_hello_lan_id,
454 offset + 1, 6, ihp->isis_hello_source_id,
455 "Lan ID: %02x%02x.%02x%02x.%02x%02x",
456 ihp->isis_hello_lan_id[0],
457 ihp->isis_hello_lan_id[1],
458 ihp->isis_hello_lan_id[2],
459 ihp->isis_hello_lan_id[3],
460 ihp->isis_hello_lan_id[4],
461 ihp->isis_hello_lan_id[5]);
462 proto_tree_add_item(hello_tree, hf_isis_hello_holding_timer,
463 offset + 7, 2,pntohs(&ihp->isis_hello_holding_timer[0]));
464 proto_tree_add_item(hello_tree, hf_isis_hello_pdu_length,
465 offset + 9, 2,pntohs(&ihp->isis_hello_pdu_length[0]));
466 proto_tree_add_item_format(hello_tree,
467 hf_isis_hello_priority_reserved,
468 offset + 11, 1, ihp->isis_hello_priority_reserved,
469 "Priority: %d, reserved(0x%02x == 0)",
470 ihp->isis_hello_priority,
471 ihp->isis_hello_preserved );
472 if (hello_type == ISIS_TYPE_PTP_HELLO) {
473 proto_tree_add_item_format(hello_tree,
474 hf_isis_hello_local_circuit_id,
475 offset + 12, 1, ihp->isis_hello_lan_id[0] );
477 proto_tree_add_item_format(hello_tree,
478 hf_isis_hello_lan_id, offset + 12, 7,
479 ihp->isis_hello_lan_id,
480 "Lan ID: %02x%02x.%02x%02x.%02x%02x-%02d",
481 ihp->isis_hello_lan_id[0],
482 ihp->isis_hello_lan_id[1],
483 ihp->isis_hello_lan_id[2],
484 ihp->isis_hello_lan_id[3],
485 ihp->isis_hello_lan_id[4],
486 ihp->isis_hello_lan_id[5],
487 ihp->isis_hello_lan_id[6]);
492 len = pntohs(&ihp->isis_hello_pdu_length[0]);
493 len -= header_length;
495 isis_dissect_unknown(offset, header_length, tree, fd,
496 "packet header length %d went beyond packet",
501 * Now, we need to decode our CLVs. We need to pass in
502 * our list of valid ones!
504 if (hello_type == ISIS_TYPE_L1_HELLO){
505 isis_dissect_clvs ( clv_l1_hello_opts, len, pd, offset, fd,
506 hello_tree, ett_isis_hello_clv_unknown );
507 } else if (hello_type == ISIS_TYPE_L2_HELLO) {
508 isis_dissect_clvs ( clv_l2_hello_opts, len, pd, offset, fd,
509 hello_tree, ett_isis_hello_clv_unknown );
511 isis_dissect_clvs ( clv_ptp_hello_opts, len, pd, offset, fd,
512 hello_tree, ett_isis_hello_clv_unknown );
517 * Name: proto_register_isis_hello()
520 * Register our protocol sub-sets with protocol manager.
521 * NOTE: this procedure is autolinked by the makefile process that
531 proto_register_isis_hello(void) {
532 static hf_register_info hf[] = {
533 { &hf_isis_hello_circuit_reserved,
534 { "Circuit type", "", FT_UINT8, BASE_HEX, NULL,
537 { &hf_isis_hello_source_id,
538 { "Source ID", "isis_hello.source_id", FT_ETHER,
539 BASE_HEX, NULL, 0x0, "" }},
541 { &hf_isis_hello_holding_timer,
542 { "Holding timer", "isis_hello.holding_timer",
543 FT_UINT16, BASE_DEC, NULL, 0x0, "" }},
545 { &hf_isis_hello_pdu_length,
546 { "PDU length", "isis_hello.pdu_length", FT_UINT16,
547 BASE_DEC, NULL, 0x0, "" }},
549 { &hf_isis_hello_priority_reserved,
550 { "Priority", "",FT_UINT8, BASE_DEC, NULL,
551 ISIS_HELLO_P_RESERVED_MASK, "" }},
553 { &hf_isis_hello_lan_id,
554 { "LAN ID", "", FT_STRING, BASE_DEC, NULL, 0x0, "" }},
556 { &hf_isis_hello_local_circuit_id,
557 { "Local circuit ID", "isis_hello.local_circuit_id", FT_UINT8,
558 BASE_DEC, NULL, 0x0, "" }},
560 { &hf_isis_hello_clv_ipv4_int_addr,
561 { "IPv4 interface address", "", FT_IPv4,
562 BASE_NONE, NULL, 0x0, "" }},
565 static gint *ett[] = {
567 &ett_isis_hello_clv_area_addr,
568 &ett_isis_hello_clv_is_neighbors,
569 &ett_isis_hello_clv_padding,
570 &ett_isis_hello_clv_unknown,
571 &ett_isis_hello_clv_nlpid,
572 &ett_isis_hello_clv_auth,
573 &ett_isis_hello_clv_ipv4_int_addr,
576 proto_isis_hello = proto_register_protocol("ISIS hello", "ISIS-hello");
577 proto_register_field_array(proto_isis_hello, hf, array_length(hf));
578 proto_register_subtree_array(ett, array_length(ett));