2 * Routines for decoding isis complete & partial SNP and their payload
4 * $Id: packet-isis-snp.c,v 1.22 2003/07/09 04:25:16 guy Exp $
5 * Stuart Stanley <stuarts@mxmail.net>
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@ethereal.com>
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_lsp_entries = -1;
44 static gint ett_isis_csnp_lsp_entry = -1;
45 static gint ett_isis_csnp_authentication = -1;
46 static gint ett_isis_csnp_clv_unknown = -1;
49 static int hf_isis_psnp_pdu_length = -1;
50 static gint ett_isis_psnp = -1;
51 static gint ett_isis_psnp_lsp_entries = -1;
52 static gint ett_isis_psnp_lsp_entry = -1;
53 static gint ett_isis_psnp_authentication = -1;
54 static gint ett_isis_psnp_clv_unknown = -1;
56 static void dissect_l1_snp_authentication_clv(tvbuff_t *tvb,
57 proto_tree *tree, int offset, int id_length, int length);
58 static void dissect_l2_snp_authentication_clv(tvbuff_t *tvb,
59 proto_tree *tree, int offset, int id_length, int length);
60 static void dissect_csnp_lsp_entries(tvbuff_t *tvb,
61 proto_tree *tree, int offset, int id_length, int length);
62 static void dissect_psnp_lsp_entries(tvbuff_t *tvb,
63 proto_tree *tree, int offset, int id_length, int length);
65 static const isis_clv_handle_t clv_l1_csnp_opts[] = {
67 ISIS_CLV_L1_CSNP_LSP_ENTRIES,
69 &ett_isis_csnp_lsp_entries,
70 dissect_csnp_lsp_entries
73 ISIS_CLV_L1_CSNP_AUTHENTICATION_NS,
74 "Authentication(non spec)",
75 &ett_isis_csnp_authentication,
76 dissect_l1_snp_authentication_clv
79 ISIS_CLV_L1_CSNP_AUTHENTICATION,
81 &ett_isis_csnp_authentication,
82 dissect_l1_snp_authentication_clv
89 static const isis_clv_handle_t clv_l2_csnp_opts[] = {
91 ISIS_CLV_L2_CSNP_LSP_ENTRIES,
93 &ett_isis_csnp_lsp_entries,
94 dissect_csnp_lsp_entries
97 ISIS_CLV_L2_CSNP_AUTHENTICATION_NS,
98 "Authentication(non spec)",
99 &ett_isis_csnp_authentication,
100 dissect_l2_snp_authentication_clv
103 ISIS_CLV_L2_CSNP_AUTHENTICATION,
105 &ett_isis_csnp_authentication,
106 dissect_l2_snp_authentication_clv
113 static const isis_clv_handle_t clv_l1_psnp_opts[] = {
115 ISIS_CLV_L1_PSNP_LSP_ENTRIES,
117 &ett_isis_psnp_lsp_entries,
118 dissect_psnp_lsp_entries
121 ISIS_CLV_L1_PSNP_AUTHENTICATION_NS,
122 "Authentication(non spec)",
123 &ett_isis_psnp_authentication,
124 dissect_l1_snp_authentication_clv
127 ISIS_CLV_L1_PSNP_AUTHENTICATION,
129 &ett_isis_psnp_authentication,
130 dissect_l1_snp_authentication_clv
137 static const isis_clv_handle_t clv_l2_psnp_opts[] = {
139 ISIS_CLV_L2_PSNP_LSP_ENTRIES,
141 &ett_isis_psnp_lsp_entries,
142 dissect_psnp_lsp_entries
145 ISIS_CLV_L2_PSNP_AUTHENTICATION_NS,
146 "Authentication(non spec)",
147 &ett_isis_psnp_authentication,
148 dissect_l2_snp_authentication_clv
151 ISIS_CLV_L2_PSNP_AUTHENTICATION,
153 &ett_isis_psnp_authentication,
154 dissect_l2_snp_authentication_clv
162 * Name: dissect_snp_lsp_entries()
165 * All the snp packets use a common payload format. We have up
166 * to n entries (based on length), which are made of:
167 * 2 : remaining life time
169 * 4 : sequence number
173 * tvbuff_t * : tvbuffer for packet data
174 * proto_tree * : protocol display tree to fill out. May be NULL
175 * int : offset into packet data where we are.
176 * int : length of IDs in packet.
177 * int : length of payload to decode.
180 * void, but we will add to proto tree if !NULL.
183 dissect_csnp_lsp_entries(tvbuff_t *tvb, proto_tree *tree, int offset,
184 int id_length, int length)
186 proto_tree *subtree,*ti;
188 while ( length > 0 ) {
189 if ( length < 2+id_length+2+4+2 ) {
190 isis_dissect_unknown(tvb, tree, offset,
191 "Short CSNP header entry (%d vs %d)", length,
196 ti = proto_tree_add_text(tree, tvb, offset, 2+id_length+2+4+2,
197 "LSP-ID: %s, Sequence: 0x%08x, Lifetime: %5us, Checksum: 0x%04x",
198 print_system_id( tvb_get_ptr(tvb, offset+2, id_length+2), id_length+2 ),
199 tvb_get_ntohl(tvb, offset+2+id_length+2),
200 tvb_get_ntohs(tvb, offset),
201 tvb_get_ntohs(tvb, offset+2+id_length+2+4));
203 subtree = proto_item_add_subtree(ti,ett_isis_csnp_lsp_entry);
205 proto_tree_add_text(subtree, tvb, offset+2, 8,
207 print_system_id( tvb_get_ptr(tvb, offset+2, id_length+2), id_length+2 ));
209 proto_tree_add_text(subtree, tvb, offset+2+id_length+2, 4,
210 "LSP Sequence Number : 0x%08x",
211 tvb_get_ntohl(tvb, offset+2+id_length+2));
213 proto_tree_add_text(subtree, tvb, offset, 2,
214 "Remaining Lifetime : %us",
215 tvb_get_ntohs(tvb, offset));
217 proto_tree_add_text(subtree, tvb, offset+2+id_length+2+4, 2,
218 "LSP checksum : 0x%04x",
219 tvb_get_ntohs(tvb, offset+2+id_length+2+4));
221 length -= 2+id_length+2+4+2;
222 offset += 2+id_length+2+4+2;
228 dissect_psnp_lsp_entries(tvbuff_t *tvb, proto_tree *tree, int offset,
229 int id_length, int length)
231 proto_tree *subtree,*ti;
233 while ( length > 0 ) {
234 if ( length < 2+id_length+2+4+2 ) {
235 isis_dissect_unknown(tvb, tree, offset,
236 "Short PSNP header entry (%d vs %d)", length,
241 ti = proto_tree_add_text(tree, tvb, offset, 2+id_length+2+4+2,
242 "LSP-ID: %s, Sequence: 0x%08x, Lifetime: %5us, Checksum: 0x%04x",
243 print_system_id( tvb_get_ptr(tvb, offset+2, id_length+2), id_length+2 ),
244 tvb_get_ntohl(tvb, offset+2+id_length+2),
245 tvb_get_ntohs(tvb, offset),
246 tvb_get_ntohs(tvb, offset+2+id_length+2+4));
248 subtree = proto_item_add_subtree(ti,ett_isis_psnp_lsp_entry);
250 proto_tree_add_text(subtree, tvb, offset+2, 8,
252 print_system_id( tvb_get_ptr(tvb, offset+2, id_length+2), id_length+2 ));
254 proto_tree_add_text(subtree, tvb, offset+2+id_length+2, 4,
255 "LSP Sequence Number : 0x%08x",
256 tvb_get_ntohl(tvb, offset+2+id_length+2));
258 proto_tree_add_text(subtree, tvb, offset, 2,
259 "Remaining Lifetime : %us",
260 tvb_get_ntohs(tvb, offset));
262 proto_tree_add_text(subtree, tvb, offset+2+id_length+2+4, 2,
263 "LSP checksum : 0x%04x",
264 tvb_get_ntohs(tvb, offset+2+id_length+2+4));
266 length -= 2+id_length+2+4+2;
267 offset += 2+id_length+2+4+2;
273 * Name: isis_dissect_isis_csnp()
276 * Tear apart a L1 or L2 CSNP header and then call into payload dissect
277 * to pull apart the lsp id payload.
280 * tvbuff_t * : tvbuffer for packet data
281 * proto_tree * : protocol display tree to add to. May be NULL.
282 * int offset : our offset into packet data.
283 * int : type (l1 csnp, l2 csnp)
284 * int : header length of packet.
285 * int : length of IDs in packet.
288 * void, but we will add to proto tree if !NULL.
291 isis_dissect_isis_csnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
292 int type, int header_length, int id_length)
295 proto_tree *csnp_tree = NULL;
300 ti = proto_tree_add_text(tree, tvb, offset, -1,
302 csnp_tree = proto_item_add_subtree(ti, ett_isis_csnp);
305 pdu_length = tvb_get_ntohs(tvb, offset);
307 proto_tree_add_uint(csnp_tree, hf_isis_csnp_pdu_length, tvb,
308 offset, 2, pdu_length);
313 proto_tree_add_text(csnp_tree, tvb, offset, id_length + 1,
315 print_system_id( tvb_get_ptr(tvb, offset, id_length+1), id_length+1 ) );
317 if (check_col(pinfo->cinfo, COL_INFO)) {
318 col_append_fstr(pinfo->cinfo, COL_INFO, ", Source-ID: %s",
319 print_system_id( tvb_get_ptr(tvb, offset, id_length+1), id_length+1 ) );
321 offset += id_length + 1;
324 proto_tree_add_text(csnp_tree, tvb, offset, id_length + 2,
326 print_system_id( tvb_get_ptr(tvb, offset, id_length+2), id_length+2 ) );
328 if (check_col(pinfo->cinfo, COL_INFO)) {
329 col_append_fstr(pinfo->cinfo, COL_INFO, ", Start LSP-ID: %s",
330 print_system_id( tvb_get_ptr(tvb, offset, id_length+2), id_length+2 ) );
332 offset += id_length + 2;
335 proto_tree_add_text(csnp_tree, tvb, offset, id_length + 2,
337 print_system_id( tvb_get_ptr(tvb, offset, id_length+2), id_length+2 ) );
339 if (check_col(pinfo->cinfo, COL_INFO)) {
340 col_append_fstr(pinfo->cinfo, COL_INFO, ", End LSP-ID: %s",
341 print_system_id( tvb_get_ptr(tvb, offset, id_length+2), id_length+2 ) );
343 offset += id_length + 2;
345 len = pdu_length - header_length;
349 /* Call into payload dissector */
350 if (type == ISIS_TYPE_L1_CSNP ) {
351 isis_dissect_clvs(tvb, csnp_tree, offset,
352 clv_l1_csnp_opts, len, id_length,
353 ett_isis_csnp_clv_unknown );
355 isis_dissect_clvs(tvb, csnp_tree, offset,
356 clv_l2_csnp_opts, len, id_length,
357 ett_isis_csnp_clv_unknown );
362 * Name: isis_dissect_isis_psnp()
365 * Tear apart a L1 or L2 PSNP header and then call into payload dissect
366 * to pull apart the lsp id payload.
369 * tvbuff_t * : tvbuffer for packet data
370 * proto_tree * : protocol display tree to add to. May be NULL.
371 * int : our offset into packet data
372 * int : type (l1 psnp, l2 psnp)
373 * int : header length of packet.
374 * int : length of IDs in packet.
377 * void, but we will add to proto tree if !NULL.
380 isis_dissect_isis_psnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
381 int type, int header_length, int id_length)
384 proto_tree *psnp_tree = NULL;
389 ti = proto_tree_add_text(tree, tvb, offset, -1,
391 psnp_tree = proto_item_add_subtree(ti, ett_isis_psnp);
394 pdu_length = tvb_get_ntohs(tvb, offset);
396 proto_tree_add_uint(psnp_tree, hf_isis_psnp_pdu_length, tvb,
397 offset, 2, pdu_length);
402 proto_tree_add_text(psnp_tree, tvb, offset, id_length + 1,
404 print_system_id( tvb_get_ptr(tvb, offset, id_length+1), id_length + 1 ) );
406 if (check_col(pinfo->cinfo, COL_INFO)) {
407 col_append_fstr(pinfo->cinfo, COL_INFO, ", Source-ID: %s",
408 print_system_id( tvb_get_ptr(tvb, offset, id_length+1), id_length+1 ) );
410 offset += id_length + 1;
412 len = pdu_length - header_length;
414 isis_dissect_unknown(tvb, tree, offset,
415 "packet header length %d went beyond packet",
419 /* Call into payload dissector */
420 if (type == ISIS_TYPE_L1_PSNP ) {
421 isis_dissect_clvs(tvb, psnp_tree, offset,
422 clv_l1_psnp_opts, len, id_length,
423 ett_isis_psnp_clv_unknown );
425 isis_dissect_clvs(tvb, psnp_tree, offset,
426 clv_l2_psnp_opts, len, id_length,
427 ett_isis_psnp_clv_unknown );
432 * Name: dissect_L1_snp_authentication_clv()
435 * Decode for a lsp packets authenticaion clv. Calls into the
436 * clv common one. An auth inside a L1 SNP is a per area password
439 * tvbuff_t * : tvbuffer for packet data
440 * proto_tree * : proto tree to build on (may be null)
441 * int : current offset into packet data
442 * int : length of IDs in packet.
443 * int : length of this clv
446 * void, will modify proto_tree if not null.
449 dissect_l1_snp_authentication_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
450 int id_length _U_, int length)
452 isis_dissect_authentication_clv(tvb, tree, offset, length,
453 "Per area authentication" );
457 * Name: dissect_l2_authentication_clv()
460 * Decode for a lsp packets authenticaion clv. Calls into the
461 * clv common one. An auth inside a L2 LSP is a per domain password
464 * tvbuff_t * : tvbuffer for packet data
465 * proto_tree * : proto tree to build on (may be null)
466 * int : current offset into packet data
467 * int : length of IDs in packet.
468 * int : length of this clv
471 * void, will modify proto_tree if not null.
474 dissect_l2_snp_authentication_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
475 int id_length _U_, int length)
477 isis_dissect_authentication_clv(tvb, tree, offset, length,
478 "Per domain authentication" );
482 * Name: isis_register_csnp()
485 * Register our protocol sub-sets with protocol manager.
488 * int : protocol index for the ISIS protocol
494 isis_register_csnp(int proto_isis) {
495 static hf_register_info hf[] = {
496 { &hf_isis_csnp_pdu_length,
497 { "PDU length", "isis.csnp.pdu_length", FT_UINT16,
498 BASE_DEC, NULL, 0x0, "", HFILL }},
500 static gint *ett[] = {
502 &ett_isis_csnp_lsp_entries,
503 &ett_isis_csnp_lsp_entry,
504 &ett_isis_csnp_authentication,
505 &ett_isis_csnp_clv_unknown,
508 proto_register_field_array(proto_isis, hf, array_length(hf));
509 proto_register_subtree_array(ett, array_length(ett));
514 * Name: isis_register_psnp()
517 * Register our protocol sub-sets with protocol manager.
520 * int : protocol index for the ISIS protocol
526 isis_register_psnp(int proto_isis) {
527 static hf_register_info hf[] = {
528 { &hf_isis_psnp_pdu_length,
529 { "PDU length", "isis.psnp.pdu_length", FT_UINT16,
530 BASE_DEC, NULL, 0x0, "", HFILL }},
532 static gint *ett[] = {
534 &ett_isis_psnp_lsp_entries,
535 &ett_isis_psnp_lsp_entry,
536 &ett_isis_psnp_authentication,
537 &ett_isis_psnp_clv_unknown,
540 proto_register_field_array(proto_isis, hf, array_length(hf));
541 proto_register_subtree_array(ett, array_length(ett));