2 * Routines for decoding isis complete & partial SNP and their payload
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
33 #include <epan/packet.h>
34 #include "packet-osi.h"
35 #include "packet-isis.h"
36 #include "packet-isis-clv.h"
37 #include "packet-isis-lsp.h"
38 #include "packet-isis-snp.h"
41 static int hf_isis_csnp_pdu_length = -1;
42 static gint ett_isis_csnp = -1;
43 static gint ett_isis_csnp_clv_lsp_entries = -1;
44 static gint ett_isis_csnp_lsp_entry = -1;
45 static gint ett_isis_csnp_clv_authentication = -1;
46 static gint ett_isis_csnp_clv_ip_authentication = -1;
47 static gint ett_isis_csnp_clv_checksum = -1;
48 static gint ett_isis_csnp_clv_unknown = -1;
51 static int hf_isis_psnp_pdu_length = -1;
52 static gint ett_isis_psnp = -1;
53 static gint ett_isis_psnp_clv_lsp_entries = -1;
54 static gint ett_isis_psnp_lsp_entry = -1;
55 static gint ett_isis_psnp_clv_authentication = -1;
56 static gint ett_isis_psnp_clv_ip_authentication = -1;
57 static gint ett_isis_psnp_clv_checksum = -1;
58 static gint ett_isis_psnp_clv_unknown = -1;
60 static void dissect_snp_authentication_clv(tvbuff_t *tvb,
61 proto_tree *tree, int offset, int id_length, int length);
62 static void dissect_snp_ip_authentication_clv(tvbuff_t *tvb,
63 proto_tree *tree, int offset, int id_length, int length);
64 static void dissect_snp_checksum_clv(tvbuff_t *tvb,
65 proto_tree *tree, int offset, int id_length, int length);
66 static void dissect_snp_lsp_entries_clv(tvbuff_t *tvb,
67 proto_tree *tree, int offset, int id_length, int length);
69 static const isis_clv_handle_t clv_l1_csnp_opts[] = {
73 &ett_isis_csnp_clv_lsp_entries,
74 dissect_snp_lsp_entries_clv
77 ISIS_CLV_AUTHENTICATION,
79 &ett_isis_csnp_clv_authentication,
80 dissect_snp_authentication_clv
83 ISIS_CLV_IP_AUTHENTICATION,
85 &ett_isis_csnp_clv_ip_authentication,
86 dissect_snp_ip_authentication_clv
91 &ett_isis_csnp_clv_checksum,
92 dissect_snp_checksum_clv
99 static const isis_clv_handle_t clv_l2_csnp_opts[] = {
101 ISIS_CLV_LSP_ENTRIES,
103 &ett_isis_csnp_clv_lsp_entries,
104 dissect_snp_lsp_entries_clv
107 ISIS_CLV_AUTHENTICATION,
109 &ett_isis_csnp_clv_authentication,
110 dissect_snp_authentication_clv
113 ISIS_CLV_IP_AUTHENTICATION,
115 &ett_isis_csnp_clv_ip_authentication,
116 dissect_snp_ip_authentication_clv
121 &ett_isis_csnp_clv_checksum,
122 dissect_snp_checksum_clv
129 static const isis_clv_handle_t clv_l1_psnp_opts[] = {
131 ISIS_CLV_LSP_ENTRIES,
133 &ett_isis_psnp_clv_lsp_entries,
134 dissect_snp_lsp_entries_clv
137 ISIS_CLV_AUTHENTICATION,
139 &ett_isis_psnp_clv_authentication,
140 dissect_snp_authentication_clv
143 ISIS_CLV_IP_AUTHENTICATION,
145 &ett_isis_psnp_clv_ip_authentication,
146 dissect_snp_ip_authentication_clv
151 &ett_isis_psnp_clv_checksum,
152 dissect_snp_checksum_clv
159 static const isis_clv_handle_t clv_l2_psnp_opts[] = {
161 ISIS_CLV_LSP_ENTRIES,
163 &ett_isis_psnp_clv_lsp_entries,
164 dissect_snp_lsp_entries_clv
167 ISIS_CLV_AUTHENTICATION,
169 &ett_isis_psnp_clv_authentication,
170 dissect_snp_authentication_clv
173 ISIS_CLV_IP_AUTHENTICATION,
175 &ett_isis_psnp_clv_ip_authentication,
176 dissect_snp_ip_authentication_clv
181 &ett_isis_psnp_clv_checksum,
182 dissect_snp_checksum_clv
190 * Name: dissect_snp_lsp_entries_clv()
193 * All the snp packets use a common payload format. We have up
194 * to n entries (based on length), which are made of:
195 * 2 : remaining life time
197 * 4 : sequence number
201 * tvbuff_t * : tvbuffer for packet data
202 * proto_tree * : protocol display tree to fill out. May be NULL
203 * int : offset into packet data where we are.
204 * int : length of IDs in packet.
205 * int : length of payload to decode.
208 * void, but we will add to proto tree if !NULL.
211 dissect_snp_lsp_entries_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
212 int id_length, int length)
214 proto_tree *subtree,*ti;
216 while ( length > 0 ) {
217 if ( length < 2+id_length+2+4+2 ) {
218 isis_dissect_unknown(tvb, tree, offset,
219 "Short SNP header entry (%d vs %d)", length,
224 ti = proto_tree_add_text(tree, tvb, offset, 2+id_length+2+4+2,
225 "LSP-ID: %s, Sequence: 0x%08x, Lifetime: %5us, Checksum: 0x%04x",
226 print_system_id( tvb_get_ptr(tvb, offset+2, id_length+2), id_length+2 ),
227 tvb_get_ntohl(tvb, offset+2+id_length+2),
228 tvb_get_ntohs(tvb, offset),
229 tvb_get_ntohs(tvb, offset+2+id_length+2+4));
231 subtree = proto_item_add_subtree(ti,ett_isis_csnp_lsp_entry);
233 proto_tree_add_text(subtree, tvb, offset+2, 8,
235 print_system_id( tvb_get_ptr(tvb, offset+2, id_length+2), id_length+2 ));
237 proto_tree_add_text(subtree, tvb, offset+2+id_length+2, 4,
238 "LSP Sequence Number : 0x%08x",
239 tvb_get_ntohl(tvb, offset+2+id_length+2));
241 proto_tree_add_text(subtree, tvb, offset, 2,
242 "Remaining Lifetime : %us",
243 tvb_get_ntohs(tvb, offset));
245 proto_tree_add_text(subtree, tvb, offset+2+id_length+2+4, 2,
246 "LSP checksum : 0x%04x",
247 tvb_get_ntohs(tvb, offset+2+id_length+2+4));
249 length -= 2+id_length+2+4+2;
250 offset += 2+id_length+2+4+2;
257 * Name: isis_dissect_isis_csnp()
260 * Tear apart a L1 or L2 CSNP header and then call into payload dissect
261 * to pull apart the lsp id payload.
264 * tvbuff_t * : tvbuffer for packet data
265 * proto_tree * : protocol display tree to add to. May be NULL.
266 * int offset : our offset into packet data.
267 * int : type (l1 csnp, l2 csnp)
268 * int : header length of packet.
269 * int : length of IDs in packet.
272 * void, but we will add to proto tree if !NULL.
275 isis_dissect_isis_csnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
276 int type, int header_length, int id_length)
279 proto_tree *csnp_tree = NULL;
284 ti = proto_tree_add_text(tree, tvb, offset, -1,
286 csnp_tree = proto_item_add_subtree(ti, ett_isis_csnp);
289 pdu_length = tvb_get_ntohs(tvb, offset);
291 proto_tree_add_uint(csnp_tree, hf_isis_csnp_pdu_length, tvb,
292 offset, 2, pdu_length);
297 proto_tree_add_text(csnp_tree, tvb, offset, id_length + 1,
299 print_system_id( tvb_get_ptr(tvb, offset, id_length+1), id_length+1 ) );
301 if (check_col(pinfo->cinfo, COL_INFO)) {
302 col_append_fstr(pinfo->cinfo, COL_INFO, ", Source-ID: %s",
303 print_system_id( tvb_get_ptr(tvb, offset, id_length+1), id_length+1 ) );
305 offset += id_length + 1;
308 proto_tree_add_text(csnp_tree, tvb, offset, id_length + 2,
310 print_system_id( tvb_get_ptr(tvb, offset, id_length+2), id_length+2 ) );
312 if (check_col(pinfo->cinfo, COL_INFO)) {
313 col_append_fstr(pinfo->cinfo, COL_INFO, ", Start LSP-ID: %s",
314 print_system_id( tvb_get_ptr(tvb, offset, id_length+2), id_length+2 ) );
316 offset += id_length + 2;
319 proto_tree_add_text(csnp_tree, tvb, offset, id_length + 2,
321 print_system_id( tvb_get_ptr(tvb, offset, id_length+2), id_length+2 ) );
323 if (check_col(pinfo->cinfo, COL_INFO)) {
324 col_append_fstr(pinfo->cinfo, COL_INFO, ", End LSP-ID: %s",
325 print_system_id( tvb_get_ptr(tvb, offset, id_length+2), id_length+2 ) );
327 offset += id_length + 2;
329 len = pdu_length - header_length;
333 /* Call into payload dissector */
334 if (type == ISIS_TYPE_L1_CSNP ) {
335 isis_dissect_clvs(tvb, csnp_tree, offset,
336 clv_l1_csnp_opts, len, id_length,
337 ett_isis_csnp_clv_unknown );
339 isis_dissect_clvs(tvb, csnp_tree, offset,
340 clv_l2_csnp_opts, len, id_length,
341 ett_isis_csnp_clv_unknown );
346 * Name: isis_dissect_isis_psnp()
349 * Tear apart a L1 or L2 PSNP header and then call into payload dissect
350 * to pull apart the lsp id payload.
353 * tvbuff_t * : tvbuffer for packet data
354 * proto_tree * : protocol display tree to add to. May be NULL.
355 * int : our offset into packet data
356 * int : type (l1 psnp, l2 psnp)
357 * int : header length of packet.
358 * int : length of IDs in packet.
361 * void, but we will add to proto tree if !NULL.
364 isis_dissect_isis_psnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
365 int type, int header_length, int id_length)
368 proto_tree *psnp_tree = NULL;
373 ti = proto_tree_add_text(tree, tvb, offset, -1,
375 psnp_tree = proto_item_add_subtree(ti, ett_isis_psnp);
378 pdu_length = tvb_get_ntohs(tvb, offset);
380 proto_tree_add_uint(psnp_tree, hf_isis_psnp_pdu_length, tvb,
381 offset, 2, pdu_length);
386 proto_tree_add_text(psnp_tree, tvb, offset, id_length + 1,
388 print_system_id( tvb_get_ptr(tvb, offset, id_length+1), id_length + 1 ) );
390 if (check_col(pinfo->cinfo, COL_INFO)) {
391 col_append_fstr(pinfo->cinfo, COL_INFO, ", Source-ID: %s",
392 print_system_id( tvb_get_ptr(tvb, offset, id_length+1), id_length+1 ) );
394 offset += id_length + 1;
396 len = pdu_length - header_length;
398 isis_dissect_unknown(tvb, tree, offset,
399 "packet header length %d went beyond packet",
403 /* Call into payload dissector */
404 if (type == ISIS_TYPE_L1_PSNP ) {
405 isis_dissect_clvs(tvb, psnp_tree, offset,
406 clv_l1_psnp_opts, len, id_length,
407 ett_isis_psnp_clv_unknown );
409 isis_dissect_clvs(tvb, psnp_tree, offset,
410 clv_l2_psnp_opts, len, id_length,
411 ett_isis_psnp_clv_unknown );
416 * Name: dissect_snp_authentication_clv()
419 * Decode for a snp packets authenticaion clv.
420 * Calls into the CLV common one.
423 * tvbuff_t * : tvbuffer for packet data
424 * proto_tree * : proto tree to build on (may be null)
425 * int : current offset into packet data
426 * int : length of IDs in packet.
427 * int : length of this clv
430 * void, will modify proto_tree if not null.
433 dissect_snp_authentication_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
434 int id_length _U_, int length)
436 isis_dissect_authentication_clv(tvb, tree, offset, length);
440 * Name: dissect_snp_ip_authentication_clv()
443 * Decode for a snp packets authenticaion clv.
444 * Calls into the CLV common one.
447 * tvbuff_t * : tvbuffer for packet data
448 * proto_tree * : proto tree to build on (may be null)
449 * int : current offset into packet data
450 * int : length of IDs in packet.
451 * int : length of this clv
454 * void, will modify proto_tree if not null.
457 dissect_snp_ip_authentication_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
458 int id_length _U_, int length)
460 isis_dissect_ip_authentication_clv(tvb, tree, offset, length);
464 * Name: dissect_snp_checksum_clv()
467 * dump and verify the optional checksum in TLV 12
470 * tvbuff_t * : tvbuffer for packet data
471 * proto_tree * : protocol display tree to fill out. May be NULL
472 * int : offset into packet data where we are.
473 * int : length of clv we are decoding
476 * void, but we will add to proto tree if !NULL.
480 dissect_snp_checksum_clv(tvbuff_t *tvb,
481 proto_tree *tree, int offset, int id_length _U_, int length) {
483 guint16 pdu_length,checksum, cacl_checksum=0;
487 proto_tree_add_text ( tree, tvb, offset, length,
488 "incorrect checksum length (%u), should be (2)", length );
492 checksum = tvb_get_ntohs(tvb, offset);
494 /* the check_and_get_checksum() function needs to know how big
495 * the packet is. we can either pass through the pdu-len through several layers
496 * of dissectors and wrappers or extract the PDU length field from the PDU specific header
497 * which is offseted 8 bytes (relative to the beginning of the IS-IS packet) in SNPs */
499 pdu_length = tvb_get_ntohs(tvb, 8);
501 /* unlike the LSP checksum verification which starts at an offset of 12 we start at offset 0*/
502 switch (check_and_get_checksum(tvb, 0, pdu_length, checksum, offset, &cacl_checksum))
506 proto_tree_add_text ( tree, tvb, offset, length,
507 "Checksum: 0x%04x [unused]", checksum);
510 isis_dissect_unknown(tvb, tree, offset,
511 "[packet length %d went beyond packet]",
512 tvb_length_remaining(tvb, 0));
515 proto_tree_add_text ( tree, tvb, offset, length,
516 "Checksum: 0x%04x [incorrect, should be 0x%04x]",
521 proto_tree_add_text ( tree, tvb, offset, length,
522 "Checksum: 0x%04x [correct]", checksum);
525 g_message("'check_and_get_checksum' returned an invalid value");
531 * Name: isis_register_csnp()
534 * Register our protocol sub-sets with protocol manager.
537 * int : protocol index for the ISIS protocol
543 isis_register_csnp(int proto_isis) {
544 static hf_register_info hf[] = {
545 { &hf_isis_csnp_pdu_length,
546 { "PDU length", "isis.csnp.pdu_length", FT_UINT16,
547 BASE_DEC, NULL, 0x0, "", HFILL }},
549 static gint *ett[] = {
551 &ett_isis_csnp_clv_lsp_entries,
552 &ett_isis_csnp_lsp_entry,
553 &ett_isis_csnp_clv_authentication,
554 &ett_isis_csnp_clv_ip_authentication,
555 &ett_isis_csnp_clv_checksum,
556 &ett_isis_csnp_clv_unknown,
559 proto_register_field_array(proto_isis, hf, array_length(hf));
560 proto_register_subtree_array(ett, array_length(ett));
565 * Name: isis_register_psnp()
568 * Register our protocol sub-sets with protocol manager.
571 * int : protocol index for the ISIS protocol
577 isis_register_psnp(int proto_isis) {
578 static hf_register_info hf[] = {
579 { &hf_isis_psnp_pdu_length,
580 { "PDU length", "isis.psnp.pdu_length", FT_UINT16,
581 BASE_DEC, NULL, 0x0, "", HFILL }},
583 static gint *ett[] = {
585 &ett_isis_psnp_clv_lsp_entries,
586 &ett_isis_psnp_lsp_entry,
587 &ett_isis_psnp_clv_authentication,
588 &ett_isis_psnp_clv_ip_authentication,
589 &ett_isis_psnp_clv_checksum,
590 &ett_isis_psnp_clv_unknown,
593 proto_register_field_array(proto_isis, hf, array_length(hf));
594 proto_register_subtree_array(ett, array_length(ett));