2 * Routines for decoding isis complete & partial SNP and their payload
4 * $Id: packet-isis-snp.c,v 1.3 2000/04/15 22:11:10 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-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, frame_data *fd, proto_tree *tree );
65 static void dissect_l1_snp_authentication_clv(const u_char *pd, int offset,
66 guint length, frame_data *fd, proto_tree *tree );
67 static void dissect_l2_snp_authentication_clv(const u_char *pd, int offset,
68 guint 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_payload()
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 * int : length of payload to decode.
180 * frame_data * : frame data (complete frame)
181 * proto_tree * : protocol display tree to fill out. May be NULL
184 * void, but we will add to proto tree if !NULL.
187 dissect_snp_lsp_entries(const u_char *pd, int offset, guint length,
188 frame_data *fd, proto_tree *tree ) {
191 ps = (isis_snp_t *) &pd[offset];
192 while ( length > 0 ) {
193 if ( length < sizeof(isis_psnp_t) ) {
194 isis_dissect_unknown(offset, length, tree, fd,
195 "Short SNP header entry (%d vs %d)", length,
196 sizeof(isis_psnp_t) );
200 proto_tree_add_text(tree, offset, 2, "Remaining life : %d",
201 pntohs(&ps->isis_snp_remaining_lifetime));
202 isis_lsp_decode_lsp_id( "LSP ID ", tree, offset + 2,
203 &ps->isis_snp_lsp_id );
204 proto_tree_add_text(tree, offset+10, 4,
205 "LSP Sequence Number : 0x%04x",
206 pntohl(&ps->isis_snp_sequence_number));
207 proto_tree_add_text(tree, offset+14, 2,
208 "LSP checksum : 0x%02x",
209 pntohs(&ps->isis_snp_checksum));
210 length -= sizeof ( isis_snp_t );
211 offset += sizeof ( isis_snp_t );
218 * Name: isis_dissect_isis_csnp()
221 * Tear apart a L1 or L2 CSNP header and then call into payload dissect
222 * to pull apart the lsp id payload.
225 * int : type (l1 csnp, l2 csnp)
226 * u_char * : packet data
227 * int : offset into packet data where we are.
228 * guint : length of clv we are decoding
229 * frame_data * : frame data (complete frame)
230 * proto_tree * : protocol display tree to fill out. May be NULL
233 * void, but we will add to proto tree if !NULL.
236 isis_dissect_isis_csnp(int type, int header_length, const u_char *pd,
237 int offset, frame_data *fd, proto_tree *tree){
240 proto_tree *csnp_tree = NULL;
246 if (!BYTES_ARE_IN_FRAME(offset, hlen)) {
247 isis_dissect_unknown(offset, hlen, tree, fd,
248 "not enough capture data for header (%d vs %d)",
253 ilp = (isis_csnp_t *) &pd[offset];
256 ti = proto_tree_add_item(tree, proto_isis_csnp,
257 offset, END_OF_FRAME, NULL);
258 csnp_tree = proto_item_add_subtree(ti, ett_isis_csnp);
259 proto_tree_add_item(csnp_tree, hf_isis_csnp_pdu_length,
260 offset, 2, pntohs(&ilp->isis_csnp_pdu_length));
261 proto_tree_add_text(csnp_tree, offset + 2, 7,
263 print_system_id( pd + offset + 2, 7 ) );
264 isis_lsp_decode_lsp_id( "Start LSP id ", csnp_tree, offset + 9,
265 &ilp->isis_csnp_start_lsp_id );
266 isis_lsp_decode_lsp_id( "End LSP id ", csnp_tree, offset + 17,
267 &ilp->isis_csnp_end_lsp_id );
271 len = pntohs(&ilp->isis_csnp_pdu_length);
272 len -= header_length;
276 /* Call into payload dissector */
277 if (type == ISIS_TYPE_L1_CSNP ) {
278 isis_dissect_clvs ( clv_l1_csnp_opts, len, pd, offset, fd,
279 csnp_tree, ett_isis_csnp_clv_unknown );
281 isis_dissect_clvs ( clv_l2_csnp_opts, len, pd, offset, fd,
282 csnp_tree, ett_isis_csnp_clv_unknown );
287 * Name: isis_dissect_isis_psnp()
290 * Tear apart a L1 or L2 PSNP header and then call into payload dissect
291 * to pull apart the lsp id payload.
294 * u_char * : packet data
295 * int : offset into packet data where we are.
296 * guint : length of clv we are decoding
297 * frame_data * : frame data (complete frame)
298 * proto_tree * : protocol display tree to fill out. May be NULL
301 * void, but we will add to proto tree if !NULL.
304 isis_dissect_isis_psnp(int type, int header_length, const u_char *pd,
305 int offset, frame_data *fd, proto_tree *tree){
308 proto_tree *psnp_tree = NULL;
314 if (!BYTES_ARE_IN_FRAME(offset, hlen)) {
315 isis_dissect_unknown(offset, hlen, tree, fd,
316 "not enough capture data for header (%d vs %d)",
321 ilp = (isis_psnp_t *) &pd[offset];
324 ti = proto_tree_add_item(tree, proto_isis_psnp,
325 offset, END_OF_FRAME, NULL);
326 psnp_tree = proto_item_add_subtree(ti, ett_isis_psnp);
327 proto_tree_add_item(psnp_tree, hf_isis_psnp_pdu_length,
328 offset, 2, pntohs(&ilp->isis_psnp_pdu_length));
329 proto_tree_add_text(psnp_tree, offset + 2, 7,
331 print_system_id( pd + offset + 2, 7 ) );
335 len = pntohs(&ilp->isis_psnp_pdu_length);
336 len -= header_length;
338 isis_dissect_unknown(offset, header_length, tree, fd,
339 "packet header length %d went beyond packet",
343 /* Call into payload dissector */
344 if (type == ISIS_TYPE_L1_CSNP ) {
345 isis_dissect_clvs ( clv_l1_csnp_opts, len, pd, offset, fd,
346 psnp_tree, ett_isis_psnp_clv_unknown );
348 isis_dissect_clvs ( clv_l2_csnp_opts, len, pd, offset, fd,
349 psnp_tree, ett_isis_psnp_clv_unknown );
354 * Name: dissect_L1_snp_authentication_clv()
357 * Decode for a lsp packets authenticaion clv. Calls into the
358 * clv common one. An auth inside a L1 SNP is a per area password
361 * u_char * : packet data
362 * int : current offset into packet data
363 * guint : length of this clv
364 * frame_data * : frame data
365 * proto_tree * : proto tree to build on (may be null)
368 * void, will modify proto_tree if not null.
371 dissect_l1_snp_authentication_clv(const u_char *pd, int offset,
372 guint length, frame_data *fd, proto_tree *tree) {
373 isis_dissect_authentication_clv(pd, offset, length, fd, tree,
374 "Per area authentication" );
378 * Name: dissect_l2_authentication_clv()
381 * Decode for a lsp packets authenticaion clv. Calls into the
382 * clv common one. An auth inside a L2 LSP is a per domain password
385 * u_char * : packet data
386 * int : current offset into packet data
387 * guint : length of this clv
388 * frame_data * : frame data
389 * proto_tree * : proto tree to build on (may be null)
392 * void, will modify proto_tree if not null.
395 dissect_l2_snp_authentication_clv(const u_char *pd, int offset,
396 guint length, frame_data *fd, proto_tree *tree) {
397 isis_dissect_authentication_clv(pd, offset, length, fd, tree,
398 "Per domain authentication" );
402 * Name: proto_register_isis_csnp()
405 * Register our protocol sub-sets with protocol manager.
406 * NOTE: this procedure is autolinked by the makefile process that
410 * u_char * : packet data
411 * int : offset into packet data where we are.
412 * guint : length of clv we are decoding
413 * frame_data * : frame data (complete frame)
414 * proto_tree * : protocol display tree to fill out. May be NULL
417 * void, but we will add to proto tree if !NULL.
420 proto_register_isis_csnp(void) {
421 static hf_register_info hf[] = {
422 { &hf_isis_csnp_pdu_length,
423 { "PDU length", "isis_csnp.pdu_length", FT_UINT16,
424 BASE_DEC, NULL, 0x0, "" }},
426 static gint *ett[] = {
428 &ett_isis_csnp_lsp_entries,
429 &ett_isis_csnp_authentication,
430 &ett_isis_csnp_clv_unknown,
433 proto_isis_csnp = proto_register_protocol(PROTO_STRING_CSNP, "isis_csnp");
434 proto_register_field_array(proto_isis_csnp, hf, array_length(hf));
435 proto_register_subtree_array(ett, array_length(ett));
440 * Name: proto_register_isis_psnp()
443 * Register our protocol sub-sets with protocol manager.
444 * NOTE: this procedure is autolinked by the makefile process that
448 * u_char * : packet data
449 * int : offset into packet data where we are.
450 * guint : length of clv we are decoding
451 * frame_data * : frame data (complete frame)
452 * proto_tree * : protocol display tree to fill out. May be NULL
455 * void, but we will add to proto tree if !NULL.
458 proto_register_isis_psnp(void) {
459 static hf_register_info hf[] = {
460 { &hf_isis_psnp_pdu_length,
461 { "PDU length", "isis_psnp.pdu_length", FT_UINT16,
462 BASE_DEC, NULL, 0x0, "" }},
464 static gint *ett[] = {
466 &ett_isis_psnp_lsp_entries,
467 &ett_isis_psnp_authentication,
468 &ett_isis_psnp_clv_unknown,
471 proto_isis_psnp = proto_register_protocol(PROTO_STRING_PSNP, "isis_psnp");
472 proto_register_field_array(proto_isis_psnp, hf, array_length(hf));
473 proto_register_subtree_array(ett, array_length(ett));