2 * Common CLV decode routines.
4 * $Id: packet-isis-clv.c,v 1.8 2000/08/11 13:35:17 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 #ifdef NEED_SNPRINTF_H
42 # include "snprintf.h"
46 #include "packet-osi.h"
47 #include "packet-isis.h"
48 #include "packet-isis-clv.h"
52 * Name: isis_dissect_area_address_clv()
55 * Take an area address CLV and display it pieces. An area address
56 * CLV is n, x byte hex strings.
59 * u_char * : packet data
60 * int : offset into packet data where we are.
61 * guint : length of clv we are decoding
62 * frame_data * : frame data (complete frame)
63 * proto_tree * : protocol display tree to fill out. May be NULL
66 * void, but we will add to proto tree if !NULL.
69 isis_dissect_area_address_clv(const u_char *pd, int offset,
70 guint length, frame_data *fd, proto_tree *tree ) {
74 while ( length > 0 ) {
78 isis_dissect_unknown( offset, length, tree, fd,
79 "short address (no length for payload)");
82 if ( mylen > length) {
83 isis_dissect_unknown(offset, length, tree, fd,
84 "short address, packet say %d, we have %d left",
90 * Lets turn the area address into "standard" 0000.0000.etc
93 /* sbuf = isis_address_to_string ( pd, offset + 1, mylen );*/
94 sbuf = print_nsap_net( pd + offset + 1, mylen );
97 proto_tree_add_text ( tree, NullTVB, offset, mylen + 1,
98 "Area address (%d): %s", mylen, sbuf );
101 length -= mylen; /* length already adjusted for len fld*/
107 * Name: isis_dissect_authentication_clv()
110 * Take apart the CLV that hold authentication information. This
111 * is currently 1 octet auth type (which must be 1) and then
112 * the clear text password.
114 * An ISIS password has different meaning depending where it
115 * is found. Thus we support a passed in prefix string to
119 * u_char * : packet data
120 * int : offset into packet data where we are.
121 * guint : length of clv we are decoding
122 * frame_data * : frame data (complete frame)
123 * proto_tree * : protocol display tree to fill out. May be NULL
124 * char * : Password meaning
127 * void, but we will add to proto tree if !NULL.
130 isis_dissect_authentication_clv(const u_char *pd, int offset, guint length,
131 frame_data *fd, proto_tree *tree, char *meaning) {
133 char sbuf[300]; /* 255 + header info area */
141 pw_type = pd[offset++];
143 use_cleartext = FALSE;
146 s += sprintf ( s, "type 1, clear text" );
147 use_cleartext = TRUE;
150 s += sprintf ( s, "type 0x%02x, (must be 1)", pw_type );
154 s += sprintf ( s, " (0x%02x): ", length );
156 if ( use_cleartext ) {
158 strncpy(s, &pd[offset], length);
162 strcat(s, "<<no password found!!!>>" );
164 /* NOTE, s no longer valid */
166 proto_tree_add_text ( tree, NullTVB, offset - 1, length + 1,
167 "%s %s", meaning, sbuf );
168 if ( !use_cleartext ) {
170 isis_dissect_unknown(offset, length, tree, fd,
171 "Unknown autheticion type" );
176 * Name: isis_dissect_ip_int_clv()
179 * Take apart the CLV that lists all the IP interfaces. The
180 * meaning of which is slightly different for the different base packet
181 * types, but the display is not different. What we have is n ip
182 * addresses, plain and simple.
185 * u_char * : packet data
186 * int : offset into packet data where we are.
187 * guint : length of clv we are decoding
188 * frame_data * : frame data (complete frame)
189 * proto_tree * : protocol display tree to fill out. May be NULL
190 * gint : tree id to use for proto tree.
193 * void, but we will add to proto tree if !NULL.
196 isis_dissect_ip_int_clv(const u_char *pd, int offset,
197 guint length, frame_data *fd, proto_tree *tree, gint tree_id ) {
203 while ( length > 0 ) {
205 isis_dissect_unknown(offset, length, tree, fd,
206 "Short ip interface address (%d vs 4)",length );
209 memcpy(&addr, &pd[offset], sizeof(addr));
211 proto_tree_add_ipv4(tree, tree_id, NullTVB, offset, 4, addr);
219 * Name: isis_dissect_nlpid_clv()
222 * Take apart a NLPID packet and display it. The NLPID (for intergrated
223 * ISIS, contains n network layer protocol IDs that the box supports.
224 * Our display buffer we use is upto 255 entries, 6 bytes per (0x00, )
225 * plus 1 for zero termination. We just just 256*6 for simplicity.
228 * u_char * : packet data
229 * int : offset into packet data where we are.
230 * guint : length of clv we are decoding
231 * frame_data * : frame data (complete frame)
232 * proto_tree * : protocol display tree to fill out. May be NULL
235 * void, but we will add to proto tree if !NULL.
238 isis_dissect_nlpid_clv(const u_char *pd, int offset,
239 guint length, frame_data *fd, proto_tree *tree ) {
243 int old_offset = offset;
245 if ( !tree ) return; /* nothing to do! */
247 while ( length-- > 0 ) {
249 s += sprintf ( s, ", " );
251 s += sprintf ( s, "0x%02x", pd[offset++] );
254 sprintf ( sbuf, "--none--" );
257 proto_tree_add_text ( tree, NullTVB, old_offset, hlen,
262 * Name: isis_dissect_clvs()
265 * Dispatch routine to shred all the CLVs in a packet. We just
266 * walk through the clv entries in the packet. For each one, we
267 * search the passed in valid clv's for this protocol (opts) for
268 * a matching code. If found, we add to the display tree and
269 * then call the dissector. If it is not, we just post an
270 * "unknown" clv entrie using the passed in unknown clv tree id.
273 * isis_clv_handle_t * : NULL dissector terminated array of codes
274 * and handlers (along with tree text and tree id's).
275 * int : length of CLV area.
276 * u_char * : packet data
277 * int : offset into packet data where we are.
278 * guint : length of clv we are decoding
279 * frame_data * : frame data (complete frame)
280 * proto_tree * : protocol display tree to fill out. May be NULL
281 * gint : unknown clv tree id
284 * void, but we will add to proto tree if !NULL.
287 isis_dissect_clvs(const isis_clv_handle_t *opts, int len, int id_length,
288 const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
289 gint unknown_tree_id ) {
294 proto_tree *clv_tree;
300 length = pd[offset++];
301 adj = (sizeof(code) + sizeof(length) + length);
303 if ( len < 0 || !BYTES_ARE_IN_FRAME(offset, length) ) {
304 isis_dissect_unknown(offset, adj, tree, fd,
305 "Short CLV header (%d vs %d)",
310 while ((opts[q].dissect != NULL )&&( opts[q].optcode != code )){
313 if ( opts[q].dissect ) {
315 /* adjust by 2 for code/len octets */
316 snprintf ( sbuf, sizeof(sbuf), "%s (%d)",
317 opts[q].tree_text, length );
318 ti = proto_tree_add_text(tree, NullTVB, offset - 2,
320 clv_tree = proto_item_add_subtree(ti,
325 opts[q].dissect(pd, offset, length, id_length, fd,
329 snprintf ( sbuf, sizeof(sbuf),
330 "Unknown code (%d:%d)", code, length );
331 ti = proto_tree_add_text(tree, NullTVB, offset - 2,
333 clv_tree = proto_item_add_subtree(ti,