2 * Common CLV decode routines.
5 * Stuart Stanley <stuarts@mxmail.net>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30 #include <epan/packet.h>
31 #include "packet-osi.h"
32 #include "packet-isis.h"
33 #include "packet-isis-clv.h"
34 #include <epan/nlpid.h>
37 * Name: isis_dissect_area_address_clv()
40 * Take an area address CLV and display it pieces. An area address
41 * CLV is n, x byte hex strings.
44 * tvbuff_t * : tvbuffer for packet data
45 * proto_tree * : protocol display tree to fill out. May be NULL
46 * int : offset into packet data where we are.
47 * int : length of clv we are decoding
50 * void, but we will add to proto tree if !NULL.
53 isis_dissect_area_address_clv(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
,
58 while ( length
> 0 ) {
59 arealen
= tvb_get_guint8(tvb
, offset
);
62 isis_dissect_unknown(tvb
, tree
, offset
,
63 "short address (no length for payload)");
66 if ( arealen
> length
) {
67 isis_dissect_unknown(tvb
, tree
, offset
,
68 "short address, packet says %d, we have %d left",
77 * Throw an exception rather than putting in a
80 tvb_ensure_bytes_exist ( tvb
, offset
, arealen
+ 1 );
82 ti
= proto_tree_add_text ( tree
, tvb
, offset
, arealen
+ 1,
83 "Area address (%d): ", arealen
);
86 * Lets turn the area address into "standard"
87 * xx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx format string.
88 * this is a private routine as the print_nsap_net in
89 * epan/osi_utils.c is incomplete and we need only
90 * a subset - actually some nice placing of dots ....
92 for (area_idx
= 0; area_idx
< arealen
; area_idx
++) {
93 proto_item_append_text(ti
, "%02x",
94 tvb_get_guint8(tvb
, offset
+area_idx
+1));
95 if (((area_idx
& 1) == 0) &&
96 (area_idx
+ 1 < arealen
)) {
97 proto_item_append_text(ti
, ".");
101 offset
+= arealen
+ 1;
102 length
-= arealen
; /* length already adjusted for len fld*/
108 * Name: isis_dissect_authentication_clv()
111 * Take apart the CLV that hold authentication information. This
112 * is currently 1 octet auth type.
113 * the two defined authentication types
114 * are 1 for a clear text password and
115 * 54 for a HMAC-MD5 digest
118 * tvbuff_t * : tvbuffer for packet data
119 * proto_tree * : protocol display tree to fill out. May be NULL
120 * int : offset into packet data where we are.
121 * int : length of clv we are decoding
124 * void, but we will add to proto tree if !NULL.
127 isis_dissect_authentication_clv(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
,
131 int auth_unsupported
;
138 pw_type
= tvb_get_guint8(tvb
, offset
);
141 auth_unsupported
= FALSE
;
145 ti
= proto_tree_add_text ( tree
, tvb
, offset
- 1, length
+ 1,
146 "clear text (1), password (length %d) = ", length
);
148 proto_item_append_text(ti
, "%s",
149 tvb_format_text(tvb
, offset
, length
));
151 proto_item_append_text(ti
, "no clear-text password found!!!");
155 ti
= proto_tree_add_text ( tree
, tvb
, offset
- 1, length
+ 1,
156 "hmac-md5 (54), password (length %d) = ", length
);
158 if ( length
== 16 ) {
159 proto_item_append_text(ti
, "0x%02x", tvb_get_guint8(tvb
, offset
));
163 proto_item_append_text(ti
, "%02x", tvb_get_guint8(tvb
, offset
));
168 proto_item_append_text(ti
,
169 "illegal hmac-md5 digest format (must be 16 bytes)");
173 proto_tree_add_text ( tree
, tvb
, offset
- 1, length
+ 1,
174 "type 0x%02x (0x%02x): ", pw_type
, length
);
175 auth_unsupported
=TRUE
;
179 if ( auth_unsupported
) {
180 isis_dissect_unknown(tvb
, tree
, offset
,
181 "Unknown authentication type" );
186 * Name: isis_ip_authentication_clv()
189 * dump the IP authentication information found in TLV 133
190 * the CLV is standardized in rf1195, however all major
191 * implementations use TLV #10
193 * tvbuff_t * : tvbuffer for packet data
194 * proto_tree * : protocol display tree to fill out. May be NULL
195 * int : offset into packet data where we are.
196 * int : length of clv we are decoding
199 * void, but we will add to proto tree if !NULL.
204 isis_dissect_ip_authentication_clv(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
,
207 if ( !tree
) return; /* nothing to do! */
210 proto_tree_add_text ( tree
, tvb
, offset
, length
,
211 "IP Authentication: %.*s", length
,
212 tvb_get_string(wmem_packet_scope(), tvb
, offset
, length
) );
218 * Name: isis_dissect_hostname_clv()
221 * dump the hostname information found in TLV 137
222 * pls note that the hostname is not null terminated
225 * tvbuff_t * : tvbuffer for packet data
226 * proto_tree * : protocol display tree to fill out. May be NULL
227 * int : offset into packet data where we are.
228 * int : length of clv we are decoding
229 * int : tree id to use for proto tree.
232 * void, but we will add to proto tree if !NULL.
237 isis_dissect_hostname_clv(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
,
238 int length
, int tree_id
)
240 if ( !tree
) return; /* nothing to do! */
243 proto_tree_add_text ( tree
, tvb
, offset
, length
,
244 "Hostname: --none--" );
246 const char* value
= tvb_get_string(wmem_packet_scope(), tvb
, offset
, length
);
247 proto_tree_add_string_format ( tree
, tree_id
,
249 value
, "Hostname: %.*s", length
, value
);
257 isis_dissect_mt_clv(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
, int length
,
264 /* length can only be a multiple of 2, otherwise there is
265 something broken -> so decode down until length is 1 */
267 /* fetch two bytes */
268 mt_block
=tvb_get_ntohs(tvb
, offset
);
270 /* mask out the lower 12 bits */
271 switch(mt_block
&0x0fff) {
273 mt_desc
="IPv4 unicast";
276 mt_desc
="In-Band Management";
279 mt_desc
="IPv6 unicast";
285 mt_desc
="Development, Experimental or Proprietary";
288 mt_desc
="Reserved for IETF Consensus";
291 proto_tree_add_uint_format ( tree
, tree_id
, tvb
, offset
, 2,
293 "%s Topology (0x%03x), %ssubTLVs present%s",
296 (mt_block
&0x8000) ? "" : "no ",
297 (mt_block
&0x4000) ? ", ATT bit set" : "" );
299 proto_tree_add_text ( tree
, tvb
, offset
, 1,
310 * Name: isis_dissect_ip_int_clv()
313 * Take apart the CLV that lists all the IP interfaces. The
314 * meaning of which is slightly different for the different base packet
315 * types, but the display is not different. What we have is n ip
316 * addresses, plain and simple.
319 * tvbuff_t * : tvbuffer for packet data
320 * proto_tree * : protocol display tree to fill out. May be NULL
321 * int : offset into packet data where we are.
322 * int : length of clv we are decoding
323 * int : tree id to use for proto tree.
326 * void, but we will add to proto tree if !NULL.
329 isis_dissect_ip_int_clv(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
,
330 int length
, int tree_id
)
336 while ( length
> 0 ) {
338 isis_dissect_unknown(tvb
, tree
, offset
,
339 "Short IP interface address (%d vs 4)",length
);
344 proto_tree_add_item(tree
, tree_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
352 * Name: isis_dissect_ipv6_int_clv()
355 * Take apart the CLV that lists all the IPv6 interfaces. The
356 * meaning of which is slightly different for the different base packet
357 * types, but the display is not different. What we have is n ip
358 * addresses, plain and simple.
361 * tvbuff_t * : tvbuffer for packet data
362 * proto_tree * : protocol display tree to fill out. May be NULL
363 * int : offset into packet data where we are.
364 * int : length of clv we are decoding
365 * int : tree id to use for proto tree.
368 * void, but we will add to proto tree if !NULL.
371 isis_dissect_ipv6_int_clv(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
,
372 int length
, int tree_id
)
380 while ( length
> 0 ) {
382 isis_dissect_unknown(tvb
, tree
, offset
,
383 "Short IPv6 interface address (%d vs 16)",length
);
386 tvb_memcpy(tvb
, addr
, offset
, sizeof(addr
));
388 proto_tree_add_ipv6(tree
, tree_id
, tvb
, offset
, 16, addr
);
397 * Name: isis_dissect_te_router_id_clv()
400 * Display the Traffic Engineering Router ID TLV #134.
401 * This TLV is like the IP Interface TLV, except that
402 * only _one_ IP address is present
405 * tvbuff_t * : tvbuffer for packet data
406 * proto_tree * : protocol display tree to fill out. May be NULL
407 * int : offset into packet data where we are.
408 * int : length of clv we are decoding
409 * int : tree id to use for proto tree.
412 * void, but we will add to proto tree if !NULL.
415 isis_dissect_te_router_id_clv(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
,
416 int length
, int tree_id
)
423 isis_dissect_unknown(tvb
, tree
, offset
,
424 "malformed Traffic Engineering Router ID (%d vs 4)",length
);
428 proto_tree_add_item(tree
, tree_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
433 * Name: isis_dissect_nlpid_clv()
436 * Take apart a NLPID packet and display it. The NLPID (for intergrated
437 * ISIS, contains n network layer protocol IDs that the box supports.
438 * We max out at 256 entries.
441 * tvbuff_t * : tvbuffer for packet data
442 * proto_tree * : protocol display tree to fill out. May be NULL
443 * int : offset into packet data where we are.
444 * int : length of clv we are decoding
447 * void, but we will add to proto tree if !NULL.
450 #define TRUNCATED_TEXT " [truncated]"
452 isis_dissect_nlpid_clv(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
, int length
)
457 if ( !tree
) return; /* nothing to do! */
460 * Throw an exception rather than putting in a
463 tvb_ensure_bytes_exist ( tvb
, offset
, length
);
466 proto_tree_add_text (tree
, tvb
, offset
, length
,
467 "NLPID(s): --none--");
470 ti
= proto_tree_add_text (tree
, tvb
, offset
, length
,
472 while (length
-- > 0 ) {
474 proto_item_append_text(ti
, ", ");
476 proto_item_append_text(ti
, "%s (0x%02x)",
477 /* NLPID_IEEE_8021AQ conflicts with NLPID_SNDCF.
478 * In this context, we want the former.
480 (tvb_get_guint8(tvb
, offset
) == NLPID_IEEE_8021AQ
481 ? "IEEE 802.1aq (SPB)"
482 : val_to_str_const(tvb_get_guint8(tvb
, offset
), nlpid_vals
,
484 tvb_get_guint8(tvb
, offset
));
492 * Name: isis_dissect_clvs()
495 * Dispatch routine to shred all the CLVs in a packet. We just
496 * walk through the clv entries in the packet. For each one, we
497 * search the passed in valid clv's for this protocol (opts) for
498 * a matching code. If found, we add to the display tree and
499 * then call the dissector. If it is not, we just post an
500 * "unknown" clv entry using the passed in unknown clv tree id.
503 * tvbuff_t * : tvbuffer for packet data
504 * proto_tree * : protocol display tree to fill out. May be NULL
505 * int : offset into packet data where we are.
506 * isis_clv_handle_t * : NULL dissector terminated array of codes
507 * and handlers (along with tree text and tree id's).
508 * int : length of CLV area.
509 * int : length of IDs in packet.
510 * int : unknown clv tree id
513 * void, but we will add to proto tree if !NULL.
516 isis_dissect_clvs(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
,
517 const isis_clv_handle_t
*opts
, int len
, int id_length
,
518 int unknown_tree_id _U_
)
524 proto_tree
*clv_tree
;
527 code
= tvb_get_guint8(tvb
, offset
);
533 length
= tvb_get_guint8(tvb
, offset
);
539 if ( len
< length
) {
540 isis_dissect_unknown(tvb
, tree
, offset
,
541 "Short CLV header (%d vs %d)",
546 while ((opts
[q
].dissect
!= NULL
)&&( opts
[q
].optcode
!= code
)){
549 if ( opts
[q
].dissect
) {
551 /* adjust by 2 for code/len octets */
552 ti
= proto_tree_add_text(tree
, tvb
, offset
- 2,
553 length
+ 2, "%s (%u)",
554 opts
[q
].tree_text
, length
);
555 clv_tree
= proto_item_add_subtree(ti
,
560 opts
[q
].dissect(tvb
, clv_tree
, offset
,
563 #if 0 /* XXX: Left as commented out in case info about "unknown code" is ever to be displayed under a sub-tree */
565 ti
= proto_tree_add_text(tree
, tvb
, offset
- 2,
566 length
+ 2, "Unknown code %u (%u)",
568 clv_tree
= proto_item_add_subtree(ti
,
575 proto_tree_add_text(tree
, tvb
, offset
- 2,
576 length
+ 2, "Unknown code %u (%u)",