2 * Routines for decoding isis complete & partial SNP and their payload
4 * $Id: packet-isis-snp.c,v 1.7 2000/08/13 14:08:22 deniel 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-osi.h"
42 #include "packet-isis.h"
43 #include "packet-isis-clv.h"
44 #include "packet-isis-lsp.h"
45 #include "packet-isis-snp.h"
48 static int proto_isis_csnp = -1;
49 static int hf_isis_csnp_pdu_length = -1;
50 static gint ett_isis_csnp = -1;
51 static gint ett_isis_csnp_lsp_entries = -1;
52 static gint ett_isis_csnp_authentication = -1;
53 static gint ett_isis_csnp_clv_unknown = -1;
56 static int proto_isis_psnp = -1;
57 static int hf_isis_psnp_pdu_length = -1;
58 static gint ett_isis_psnp = -1;
59 static gint ett_isis_psnp_lsp_entries = -1;
60 static gint ett_isis_psnp_authentication = -1;
61 static gint ett_isis_psnp_clv_unknown = -1;
63 static void dissect_snp_lsp_entries(const u_char *pd, int offset,
64 guint length, int id_length, frame_data *fd, proto_tree *tree );
65 static void dissect_l1_snp_authentication_clv(const u_char *pd, int offset,
66 guint length, int id_length, frame_data *fd, proto_tree *tree );
67 static void dissect_l2_snp_authentication_clv(const u_char *pd, int offset,
68 guint length, int id_length, frame_data *fd, proto_tree *tree );
70 static const isis_clv_handle_t clv_l1_csnp_opts[] = {
72 ISIS_CLV_L1_CSNP_LSP_ENTRIES,
74 &ett_isis_csnp_lsp_entries,
75 dissect_snp_lsp_entries
78 ISIS_CLV_L1_CSNP_AUTHENTICATION_NS,
79 "Authentication(non spec)",
80 &ett_isis_csnp_authentication,
81 dissect_l1_snp_authentication_clv
84 ISIS_CLV_L1_CSNP_AUTHENTICATION,
86 &ett_isis_csnp_authentication,
87 dissect_l1_snp_authentication_clv
94 static const isis_clv_handle_t clv_l2_csnp_opts[] = {
96 ISIS_CLV_L2_CSNP_LSP_ENTRIES,
98 &ett_isis_csnp_lsp_entries,
99 dissect_snp_lsp_entries
102 ISIS_CLV_L2_CSNP_AUTHENTICATION_NS,
103 "Authentication(non spec)",
104 &ett_isis_csnp_authentication,
105 dissect_l2_snp_authentication_clv
108 ISIS_CLV_L2_CSNP_AUTHENTICATION,
110 &ett_isis_csnp_authentication,
111 dissect_l2_snp_authentication_clv
118 static const isis_clv_handle_t clv_l1_psnp_opts[] = {
120 ISIS_CLV_L1_PSNP_LSP_ENTRIES,
122 &ett_isis_psnp_lsp_entries,
123 dissect_snp_lsp_entries
126 ISIS_CLV_L1_PSNP_AUTHENTICATION_NS,
127 "Authentication(non spec)",
128 &ett_isis_psnp_authentication,
129 dissect_l1_snp_authentication_clv
132 ISIS_CLV_L1_PSNP_AUTHENTICATION,
134 &ett_isis_psnp_authentication,
135 dissect_l1_snp_authentication_clv
142 static const isis_clv_handle_t clv_l2_psnp_opts[] = {
144 ISIS_CLV_L2_PSNP_LSP_ENTRIES,
146 &ett_isis_psnp_lsp_entries,
147 dissect_snp_lsp_entries
150 ISIS_CLV_L2_PSNP_AUTHENTICATION,
152 &ett_isis_psnp_authentication,
153 dissect_l2_snp_authentication_clv
156 ISIS_CLV_L2_PSNP_AUTHENTICATION_NS,
157 "Authentication(non spec)",
158 &ett_isis_psnp_authentication,
159 dissect_l2_snp_authentication_clv
166 * Name: dissect_snp_lsp_entries()
169 * All the snp packets use a common payload format. We have up
170 * to n entries (based on length), which are made of:
171 * 2 : remaining life time
173 * 4 : sequence number
177 * u_char * : packet data
178 * int : offset into packet data where we are.
179 * guint : length of payload to decode.
180 * int : length of IDs in packet.
181 * frame_data * : frame data (complete frame)
182 * proto_tree * : protocol display tree to fill out. May be NULL
185 * void, but we will add to proto tree if !NULL.
188 dissect_snp_lsp_entries(const u_char *pd, int offset, guint length,
189 int id_length, frame_data *fd, proto_tree *tree ) {
190 while ( length > 0 ) {
191 if ( length < 2+id_length+2+4+2 ) {
192 isis_dissect_unknown(offset, length, tree, fd,
193 "Short SNP header entry (%d vs %d)", length,
198 proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining life : %d",
199 pntohs(&pd[offset]));
203 isis_lsp_decode_lsp_id( "LSP ID ", tree, pd,
205 length -= id_length + 2;
206 offset += id_length + 2;
208 proto_tree_add_text(tree, NullTVB, offset, 4,
209 "LSP Sequence Number : 0x%04x",
210 pntohl(&pd[offset]));
214 proto_tree_add_text(tree, NullTVB, offset, 2,
215 "LSP checksum : 0x%02x",
216 pntohs(&pd[offset]));
224 * Name: isis_dissect_isis_csnp()
227 * Tear apart a L1 or L2 CSNP header and then call into payload dissect
228 * to pull apart the lsp id payload.
231 * int : type (l1 csnp, l2 csnp)
232 * int : header length of packet.
233 * int : length of IDs in packet.
234 * u_char * : packet data
235 * int offset : our offset into packet data.
236 * frame_data * : frame data
237 * proto_tree * : protocol display tree to add to. May be NULL.
240 * void, but we will add to proto tree if !NULL.
243 isis_dissect_isis_csnp(int type, int header_length, int id_length,
244 const u_char *pd, int offset, frame_data *fd, proto_tree *tree){
246 proto_tree *csnp_tree = NULL;
251 OLD_CHECK_DISPLAY_AS_DATA(proto_isis_csnp, pd, offset, fd, tree);
253 hlen = 2+id_length+1+id_length+2+id_length+2;
255 if (!BYTES_ARE_IN_FRAME(offset, hlen)) {
256 isis_dissect_unknown(offset, hlen, tree, fd,
257 "not enough capture data for header (%d vs %d)",
263 ti = proto_tree_add_item(tree, proto_isis_csnp, NullTVB,
264 offset, END_OF_FRAME, FALSE);
265 csnp_tree = proto_item_add_subtree(ti, ett_isis_csnp);
268 pdu_length = pntohs(&pd[offset]);
270 proto_tree_add_uint(csnp_tree, hf_isis_csnp_pdu_length, NullTVB,
271 offset, 2, pdu_length);
276 proto_tree_add_text(csnp_tree, NullTVB, offset, id_length + 1,
278 print_system_id( pd + offset, id_length + 1 ) );
280 offset += id_length + 1;
283 isis_lsp_decode_lsp_id( "Start LSP id ", csnp_tree, pd, offset,
286 offset += id_length + 2;
289 isis_lsp_decode_lsp_id( "End LSP id ", csnp_tree, pd, offset,
292 offset += id_length + 2;
294 len = pdu_length - header_length;
298 /* Call into payload dissector */
299 if (type == ISIS_TYPE_L1_CSNP ) {
300 isis_dissect_clvs ( clv_l1_csnp_opts, len, id_length, pd,
301 offset, fd, csnp_tree, ett_isis_csnp_clv_unknown );
303 isis_dissect_clvs ( clv_l2_csnp_opts, len, id_length, pd,
304 offset, fd, csnp_tree, ett_isis_csnp_clv_unknown );
309 * Name: isis_dissect_isis_psnp()
312 * Tear apart a L1 or L2 PSNP header and then call into payload dissect
313 * to pull apart the lsp id payload.
316 * int : type (l1 psnp, l2 psnp)
317 * int : header length of packet.
318 * int : length of IDs in packet.
319 * u_char * : packet data
320 * int offset : our offset into packet data.
321 * frame_data * : frame data
322 * proto_tree * : protocol display tree to add to. May be NULL.
325 * void, but we will add to proto tree if !NULL.
328 isis_dissect_isis_psnp(int type, int header_length, int id_length,
329 const u_char *pd, int offset, frame_data *fd, proto_tree *tree){
331 proto_tree *psnp_tree = NULL;
336 OLD_CHECK_DISPLAY_AS_DATA(proto_isis_psnp, pd, offset, fd, tree);
338 hlen = 2+id_length+1;
340 if (!BYTES_ARE_IN_FRAME(offset, hlen)) {
341 isis_dissect_unknown(offset, hlen, tree, fd,
342 "not enough capture data for header (%d vs %d)",
348 ti = proto_tree_add_item(tree, proto_isis_psnp, NullTVB,
349 offset, END_OF_FRAME, FALSE);
350 psnp_tree = proto_item_add_subtree(ti, ett_isis_psnp);
353 pdu_length = pntohs(&pd[offset]);
355 proto_tree_add_uint(psnp_tree, hf_isis_psnp_pdu_length, NullTVB,
356 offset, 2, pdu_length);
361 proto_tree_add_text(psnp_tree, NullTVB, offset, id_length + 1,
363 print_system_id( pd + offset, id_length + 1 ) );
365 offset += id_length + 1;
367 len = pdu_length - header_length;
369 isis_dissect_unknown(offset, header_length, tree, fd,
370 "packet header length %d went beyond packet",
374 /* Call into payload dissector */
375 if (type == ISIS_TYPE_L1_CSNP ) {
376 isis_dissect_clvs ( clv_l1_csnp_opts, len, id_length, pd,
377 offset, fd, psnp_tree, ett_isis_psnp_clv_unknown );
379 isis_dissect_clvs ( clv_l2_csnp_opts, len, id_length, pd,
380 offset, fd, psnp_tree, ett_isis_psnp_clv_unknown );
385 * Name: dissect_L1_snp_authentication_clv()
388 * Decode for a lsp packets authenticaion clv. Calls into the
389 * clv common one. An auth inside a L1 SNP is a per area password
392 * u_char * : packet data
393 * int : current offset into packet data
394 * guint : length of this clv
395 * int : length of IDs in packet.
396 * frame_data * : frame data
397 * proto_tree * : proto tree to build on (may be null)
400 * void, will modify proto_tree if not null.
403 dissect_l1_snp_authentication_clv(const u_char *pd, int offset,
404 guint length, int id_length, frame_data *fd, proto_tree *tree) {
405 isis_dissect_authentication_clv(pd, offset, length, fd, tree,
406 "Per area authentication" );
410 * Name: dissect_l2_authentication_clv()
413 * Decode for a lsp packets authenticaion clv. Calls into the
414 * clv common one. An auth inside a L2 LSP is a per domain password
417 * u_char * : packet data
418 * int : current offset into packet data
419 * guint : length of this clv
420 * int : length of IDs in packet.
421 * frame_data * : frame data
422 * proto_tree * : proto tree to build on (may be null)
425 * void, will modify proto_tree if not null.
428 dissect_l2_snp_authentication_clv(const u_char *pd, int offset,
429 guint length, int id_length, frame_data *fd, proto_tree *tree) {
430 isis_dissect_authentication_clv(pd, offset, length, fd, tree,
431 "Per domain authentication" );
435 * Name: proto_register_isis_csnp()
438 * Register our protocol sub-sets with protocol manager.
439 * NOTE: this procedure is autolinked by the makefile process that
443 * u_char * : packet data
444 * int : offset into packet data where we are.
445 * guint : length of clv we are decoding
446 * frame_data * : frame data (complete frame)
447 * proto_tree * : protocol display tree to fill out. May be NULL
450 * void, but we will add to proto tree if !NULL.
453 proto_register_isis_csnp(void) {
454 static hf_register_info hf[] = {
455 { &hf_isis_csnp_pdu_length,
456 { "PDU length", "isis_csnp.pdu_length", FT_UINT16,
457 BASE_DEC, NULL, 0x0, "" }},
459 static gint *ett[] = {
461 &ett_isis_csnp_lsp_entries,
462 &ett_isis_csnp_authentication,
463 &ett_isis_csnp_clv_unknown,
466 proto_isis_csnp = proto_register_protocol(PROTO_STRING_CSNP, "isis_csnp");
467 proto_register_field_array(proto_isis_csnp, hf, array_length(hf));
468 proto_register_subtree_array(ett, array_length(ett));
473 * Name: proto_register_isis_psnp()
476 * Register our protocol sub-sets with protocol manager.
477 * NOTE: this procedure is autolinked by the makefile process that
481 * u_char * : packet data
482 * int : offset into packet data where we are.
483 * guint : length of clv we are decoding
484 * frame_data * : frame data (complete frame)
485 * proto_tree * : protocol display tree to fill out. May be NULL
488 * void, but we will add to proto tree if !NULL.
491 proto_register_isis_psnp(void) {
492 static hf_register_info hf[] = {
493 { &hf_isis_psnp_pdu_length,
494 { "PDU length", "isis_psnp.pdu_length", FT_UINT16,
495 BASE_DEC, NULL, 0x0, "" }},
497 static gint *ett[] = {
499 &ett_isis_psnp_lsp_entries,
500 &ett_isis_psnp_authentication,
501 &ett_isis_psnp_clv_unknown,
504 proto_isis_psnp = proto_register_protocol(PROTO_STRING_PSNP, "isis_psnp");
505 proto_register_field_array(proto_isis_psnp, hf, array_length(hf));
506 proto_register_subtree_array(ett, array_length(ett));