CLNP: use a dissect-as dissector table for the OSI security option.

Add a decode-as dissector table, and use its entry to dissect the
payload of an CLNP (or ES-IS) security option.

This allows the user to specify that it should be dissected as used in
ICAO's ATN specification without requiring so much entanglement between
the CLNP dissector, the OSI options dissector, and the code to dissect
the ATN security option.

(It would also allw other OSI profiles to provide their own such
dissector, e.g. GOSIP if anybody still cares, or TUBA in case it was
ever even used on a network.)
This commit is contained in:
Guy Harris 2024-04-03 12:01:11 -07:00
parent a85952e2ce
commit 82bc36ba53
4 changed files with 272 additions and 198 deletions

View File

@ -80,6 +80,7 @@ set(CLEAN_ASN1_DISSECTOR_SRC
${CMAKE_CURRENT_SOURCE_DIR}/packet-atn-ulcs.c
${CMAKE_CURRENT_SOURCE_DIR}/packet-atn-cm.c
${CMAKE_CURRENT_SOURCE_DIR}/packet-atn-cpdlc.c
${CMAKE_CURRENT_SOURCE_DIR}/packet-atn-sl.c
${CMAKE_CURRENT_SOURCE_DIR}/packet-c1222.c
${CMAKE_CURRENT_SOURCE_DIR}/packet-camel.c
${CMAKE_CURRENT_SOURCE_DIR}/packet-cbrs-oids.c

View File

@ -0,0 +1,238 @@
/* packet-atn-sl.c
* Routines for ISO/OSI network protocol packet disassembly
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "config.h"
#include <epan/packet.h>
void proto_register_atn_sl(void);
void proto_reg_handoff_atn_sl(void);
/* protocols and fields */
static int proto_atn_sl;
static gint ett_atn_sl;
static int hf_atn_sl_tt;
static int hf_atn_sl_sc;
/* ATN traffic types (ICAO doc 9705 Edition3 SV5 5.6.2.2.6.7.3) */
#define ATN_TT_ATSC_NO_PREFERENCE 0x01
#define ATN_TT_ATSC_CLASS_A 0x10
#define ATN_TT_ATSC_CLASS_B 0x11
#define ATN_TT_ATSC_CLASS_C 0x12
#define ATN_TT_ATSC_CLASS_D 0x13
#define ATN_TT_ATSC_CLASS_E 0x14
#define ATN_TT_ATSC_CLASS_F 0x15
#define ATN_TT_ATSC_CLASS_G 0x16
#define ATN_TT_ATSC_CLASS_H 0x17
#define ATN_TT_AOC_NO_PREFERENCE 0x21
#define ATN_TT_AOC_G 0x22
#define ATN_TT_AOC_V 0x23
#define ATN_TT_AOC_S 0x24
#define ATN_TT_AOC_H 0x25
#define ATN_TT_AOC_M 0x26
#define ATN_TT_AOC_G_V 0x27
#define ATN_TT_AOC_G_V_S 0x28
#define ATN_TT_AOC_G_V_H_S 0x29
#define ATN_TT_ADM_NO_PREFERENCE 0x30
#define ATN_TT_SYS_MGMT_NO_PREFERENCE 0x60
/* ATN security classification (ICAO doc 9705 Edition3 SV5 5.6.2.2.6.8.3) */
#define ATN_SC_UNCLASSIFIED 0x01
#define ATN_SC_RESTRICTED 0x02
#define ATN_SC_CONFIDENTIAL 0x03
#define ATN_SC_SECRET 0x04
#define ATN_SC_TOP_SECRET 0x05
/* ATN security label records */
#define OSI_OPT_SECURITY_ATN_SR 0xc0
#define OSI_OPT_SECURITY_ATN_TT 0x0f
#define OSI_OPT_SECURITY_ATN_SC 0x03
#define OSI_OPT_SECURITY_ATN_SR_LEN 6
#define OSI_OPT_SECURITY_ATN_TT_LEN 1
#define OSI_OPT_SECURITY_ATN_SC_LEN 1
#define OSI_OPT_SECURITY_ATN_SI_MAX_LEN 8
static const guchar atn_security_registration_val[] = {
0x06, 0x04, 0x2b, 0x1b, 0x00, 0x00
}; /* =iso(1).org(3).ICAO(27).ATN(0).TrafficType(0)*/
#if 0
static const value_string osi_opt_sec_atn_sr_vals[] = {
{OSI_OPT_SECURITY_ATN_SR, "ATN Security Label"},
{0, NULL}
};
#endif
static const value_string osi_opt_sec_atn_si_vals[] = {
{OSI_OPT_SECURITY_ATN_TT, "Traffic Type and Routing"},
{OSI_OPT_SECURITY_ATN_SC, "Security classification"},
{0, NULL}
};
static const value_string osi_opt_sec_atn_tt_vals[] = {
{ATN_TT_ATSC_NO_PREFERENCE, "ATSC No preference"},
{ATN_TT_ATSC_CLASS_A, "ATSC Class A"},
{ATN_TT_ATSC_CLASS_B, "ATSC Class B"},
{ATN_TT_ATSC_CLASS_C, "ATSC Class C"},
{ATN_TT_ATSC_CLASS_D, "ATSC Class D"},
{ATN_TT_ATSC_CLASS_E, "ATSC Class E"},
{ATN_TT_ATSC_CLASS_F, "ATSC Class F"},
{ATN_TT_ATSC_CLASS_G, "ATSC Class G"},
{ATN_TT_ATSC_CLASS_H, "ATSC Class H"},
{ATN_TT_AOC_NO_PREFERENCE, "AOC No preference"},
{ATN_TT_AOC_G, "AOC Gatelink only"},
{ATN_TT_AOC_V, "AOC VHF only"},
{ATN_TT_AOC_S, "AOC Satellite only"},
{ATN_TT_AOC_H, "AOC HF only"},
{ATN_TT_AOC_M, "AOC Mode S only"},
{ATN_TT_AOC_G_V, "AOC Gatelink first, then VHF"},
{ATN_TT_AOC_G_V_S, "AOC Gatelink first, then VHF, then Satellite"},
{ATN_TT_AOC_G_V_H_S, "AOC Gatelink first, then VHF, then HF, then Satellite"},
{ATN_TT_ADM_NO_PREFERENCE, "ATN Administrative No preference"},
{ATN_TT_SYS_MGMT_NO_PREFERENCE, "ATN Systems Management No preference"},
{0, NULL}
};
static const value_string osi_opt_sec_atn_sc_vals[] = {
{ATN_SC_UNCLASSIFIED, "unclassified"},
{ATN_SC_RESTRICTED, "restricted"},
{ATN_SC_CONFIDENTIAL, "confidential"},
{ATN_SC_SECRET, "secret"},
{ATN_SC_TOP_SECRET, "top secret"},
{0, NULL}
};
/* dissect ATN security label used for policy based interdomain routing.*/
/* For details see ICAO doc 9705 Edition 3 SV5 5.6.2.2.2.2 */
static int
dissect_atn_sl(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
void* data _U_)
{
proto_item *ti;
proto_tree *atn_sl_tree;
guint offset = 0;
guchar len = 0;
guint8 tag_name = 0;
guint security_info_end = 0;
ti = proto_tree_add_item(tree, proto_atn_sl, tvb, offset, -1, ENC_NA);
atn_sl_tree = proto_item_add_subtree(ti, ett_atn_sl);
/* check Security Registration Length */
len = tvb_get_guint8(tvb, offset);
if ( OSI_OPT_SECURITY_ATN_SR_LEN != len )
return tvb_captured_length(tvb);
offset++;
/* check Security Registration ID */
if ( tvb_memeql(tvb, offset, atn_security_registration_val, OSI_OPT_SECURITY_ATN_SR_LEN) )
return tvb_captured_length(tvb);
offset += OSI_OPT_SECURITY_ATN_SR_LEN;
/* Security Information length */
len = tvb_get_guint8(tvb, offset);
if ( OSI_OPT_SECURITY_ATN_SI_MAX_LEN < len )
return tvb_captured_length(tvb);
offset++;
security_info_end = offset + len;
while ( offset < security_info_end ) {
/* check tag name length*/
len = tvb_get_guint8(tvb, offset); /* check tag name length*/
if ( len != 1 )
return tvb_captured_length(tvb);
offset++;
tag_name = tvb_get_guint8(tvb, offset);
offset++;
switch(tag_name) {
case OSI_OPT_SECURITY_ATN_TT:
/* check tag set length*/
len = tvb_get_guint8(tvb, offset);
if ( len != OSI_OPT_SECURITY_ATN_TT_LEN )
return tvb_captured_length(tvb);
offset++;
proto_tree_add_uint_format(atn_sl_tree, hf_atn_sl_tt, tvb, offset, 1,
tvb_get_guint8(tvb, offset), "%s: %s",
val_to_str(OSI_OPT_SECURITY_ATN_TT, osi_opt_sec_atn_si_vals, "Unknown (0x%x)"),
val_to_str(tvb_get_guint8(tvb, offset ), osi_opt_sec_atn_tt_vals, "Unknown (0x%x)"));
offset += len;
break;
case OSI_OPT_SECURITY_ATN_SC:
/* check tag set length*/
len = tvb_get_guint8(tvb, offset);
if ( len != OSI_OPT_SECURITY_ATN_SC_LEN )
return tvb_captured_length(tvb);
offset++;
proto_tree_add_uint_format(atn_sl_tree, hf_atn_sl_sc, tvb, offset, 1,
tvb_get_guint8(tvb, offset), "%s: %s",
val_to_str(OSI_OPT_SECURITY_ATN_SC, osi_opt_sec_atn_si_vals, "Unknown (0x%x)"),
val_to_str(tvb_get_guint8(tvb, offset ), osi_opt_sec_atn_sc_vals, "Unknown (0x%x)"));
offset += len;
break;
default:
return tvb_captured_length(tvb);
}
}
return tvb_captured_length(tvb);
}
void
proto_register_atn_sl(void)
{
static hf_register_info hf[] = {
{ &hf_atn_sl_tt,
{ "ATN traffic type", "atn_sl.tt", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_atn_sl_sc,
{ "ATN security classification", "atn_sl.sc", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
};
static gint *ett[] = {
&ett_atn_sl,
};
proto_atn_sl = proto_register_protocol("ATN Security Label", "ATN SL", "atn_sl");
proto_register_field_array(proto_atn_sl, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
}
void
proto_reg_handoff_atn_sl(void)
{
dissector_handle_t atn_sl_handle;
atn_sl_handle = create_dissector_handle(dissect_atn_sl, proto_atn_sl);
dissector_add_for_decode_as("osi.opt_security", atn_sl_handle);
}
/*
* Editor modelines - https://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 2
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* vi: set shiftwidth=2 tabstop=8 expandtab:
* :indentSize=4:tabSize=8:noTabs=true:
*/

View File

@ -53,8 +53,6 @@ static int hf_clnp_dest_length;
static int hf_clnp_dest;
static int hf_clnp_src_length;
static int hf_clnp_src;
int hf_clnp_atntt; /* as referenced in packet-osi-options.c */
int hf_clnp_atnsc; /* as referenced in packet-osi-options.c */
static int hf_clnp_segments;
static int hf_clnp_segment;
static int hf_clnp_segment_overlap;
@ -185,7 +183,6 @@ static reassembly_table clnp_reassembly_table;
static guint tp_nsap_selector = NSEL_TP;
static bool always_decode_transport = false;
static bool clnp_reassemble = true;
bool clnp_decode_atn_options = false;
/* function definitions */
@ -627,12 +624,6 @@ proto_register_clnp(void)
{ &hf_clnp_src,
{ "SA", "clnp.ssap", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_clnp_atntt,
{ "ATN traffic type", "clnp.atn.tt", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_clnp_atnsc,
{ "ATN security classification", "clnp.atn.sc", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_clnp_segment_overlap,
{ "Segment overlap", "clnp.segment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
"Segment overlaps with other segments", HFILL }},
@ -715,10 +706,8 @@ proto_register_clnp(void)
"Reassemble segmented CLNP datagrams",
"Whether segmented CLNP datagrams should be reassembled",
&clnp_reassemble);
prefs_register_bool_preference(clnp_module, "decode_atn_options",
"Decode ATN security label",
"Whether ATN security label should be decoded",
&clnp_decode_atn_options);
/* XXX - catch this and tweak the decode_as settings? */
prefs_register_obsolete_preference(clnp_module, "decode_atn_options");
}
void

View File

@ -18,49 +18,10 @@
#include <epan/packet.h>
#include <epan/expert.h>
#include <epan/decode_as.h>
#include "packet-osi.h"
#include "packet-osi-options.h"
/* ATN traffic types (ICAO doc 9705 Edition3 SV5 5.6.2.2.6.7.3) */
#define ATN_TT_ATSC_NO_PREFERENCE 0x01
#define ATN_TT_ATSC_CLASS_A 0x10
#define ATN_TT_ATSC_CLASS_B 0x11
#define ATN_TT_ATSC_CLASS_C 0x12
#define ATN_TT_ATSC_CLASS_D 0x13
#define ATN_TT_ATSC_CLASS_E 0x14
#define ATN_TT_ATSC_CLASS_F 0x15
#define ATN_TT_ATSC_CLASS_G 0x16
#define ATN_TT_ATSC_CLASS_H 0x17
#define ATN_TT_AOC_NO_PREFERENCE 0x21
#define ATN_TT_AOC_G 0x22
#define ATN_TT_AOC_V 0x23
#define ATN_TT_AOC_S 0x24
#define ATN_TT_AOC_H 0x25
#define ATN_TT_AOC_M 0x26
#define ATN_TT_AOC_G_V 0x27
#define ATN_TT_AOC_G_V_S 0x28
#define ATN_TT_AOC_G_V_H_S 0x29
#define ATN_TT_ADM_NO_PREFERENCE 0x30
#define ATN_TT_SYS_MGMT_NO_PREFERENCE 0x60
/* ATN security classification (ICAO doc 9705 Edition3 SV5 5.6.2.2.6.8.3) */
#define ATN_SC_UNCLASSIFIED 0x01
#define ATN_SC_RESTRICTED 0x02
#define ATN_SC_CONFIDENTIAL 0x03
#define ATN_SC_SECRET 0x04
#define ATN_SC_TOP_SECRET 0x05
/* ATN security label records */
#define OSI_OPT_SECURITY_ATN_SR 0xc0
#define OSI_OPT_SECURITY_ATN_TT 0x0f
#define OSI_OPT_SECURITY_ATN_SC 0x03
#define OSI_OPT_SECURITY_ATN_SR_LEN 6
#define OSI_OPT_SECURITY_ATN_TT_LEN 1
#define OSI_OPT_SECURITY_ATN_SC_LEN 1
#define OSI_OPT_SECURITY_ATN_SI_MAX_LEN 8
#define OSI_OPT_SECURITY 0xc5
#define OSI_OPT_QOS_MAINTANANCE 0xc3
#define OSI_OPT_PRIORITY 0xcd
@ -105,10 +66,6 @@
#define OSI_OPT_RFD_MASK 0xf0
#define OSI_OPT_RFD_SUB_MASK 0x0f
extern bool clnp_decode_atn_options; /* as defined in packet-clnp.c */
extern int hf_clnp_atntt; /* as defined in packet-clnp.c */
extern int hf_clnp_atnsc; /* as defined in packet-clnp.c */
/* Generated from convert_proto_tree_add_text.pl */
static int hf_osi_options_address_mask;
static int hf_osi_options_transit_delay_vs_cost;
@ -144,54 +101,6 @@ static gint ett_osi_redirect;
static expert_field ei_osi_options_none;
static expert_field ei_osi_options_rfd_error_class;
static const guchar atn_security_registration_val[] = {
0x06, 0x04, 0x2b, 0x1b, 0x00, 0x00
}; /* =iso(1).org(3).ICAO(27).ATN(0).TrafficType(0)*/
static const value_string osi_opt_sec_atn_sr_vals[] = {
{OSI_OPT_SECURITY_ATN_SR, "ATN Security Label"},
{0, NULL}
};
static const value_string osi_opt_sec_atn_si_vals[] = {
{OSI_OPT_SECURITY_ATN_TT, "Traffic Type and Routing"},
{OSI_OPT_SECURITY_ATN_SC, "Security classification"},
{0, NULL}
};
static const value_string osi_opt_sec_atn_tt_vals[] = {
{ATN_TT_ATSC_NO_PREFERENCE, "ATSC No preference"},
{ATN_TT_ATSC_CLASS_A, "ATSC Class A"},
{ATN_TT_ATSC_CLASS_B, "ATSC Class B"},
{ATN_TT_ATSC_CLASS_C, "ATSC Class C"},
{ATN_TT_ATSC_CLASS_D, "ATSC Class D"},
{ATN_TT_ATSC_CLASS_E, "ATSC Class E"},
{ATN_TT_ATSC_CLASS_F, "ATSC Class F"},
{ATN_TT_ATSC_CLASS_G, "ATSC Class G"},
{ATN_TT_ATSC_CLASS_H, "ATSC Class H"},
{ATN_TT_AOC_NO_PREFERENCE, "AOC No preference"},
{ATN_TT_AOC_G, "AOC Gatelink only"},
{ATN_TT_AOC_V, "AOC VHF only"},
{ATN_TT_AOC_S, "AOC Satellite only"},
{ATN_TT_AOC_H, "AOC HF only"},
{ATN_TT_AOC_M, "AOC Mode S only"},
{ATN_TT_AOC_G_V, "AOC Gatelink first, then VHF"},
{ATN_TT_AOC_G_V_S, "AOC Gatelink first, then VHF, then Satellite"},
{ATN_TT_AOC_G_V_H_S, "AOC Gatelink first, then VHF, then HF, then Satellite"},
{ATN_TT_ADM_NO_PREFERENCE, "ATN Administrative No preference"},
{ATN_TT_SYS_MGMT_NO_PREFERENCE, "ATN Systems Management No preference"},
{0, NULL}
};
static const value_string osi_opt_sec_atn_sc_vals[] = {
{ATN_SC_UNCLASSIFIED, "unclassified"},
{ATN_SC_RESTRICTED, "restricted"},
{ATN_SC_CONFIDENTIAL, "confidential"},
{ATN_SC_SECRET, "secret"},
{ATN_SC_TOP_SECRET, "top secret"},
{0, NULL}
};
static const value_string osi_opt_sec_vals[] = {
{OSI_OPT_SEC_RESERVED, "Reserved"},
{OSI_OPT_SEC_SRC_ADR_SPEC, "Source Address Specific"},
@ -263,6 +172,7 @@ static const value_string osi_opt_rfd_reassembly[] = {
{0x00, "Reassembly interference"},
{0, NULL} };
static dissector_table_t subdissector_decode_as_opt_security_table;
static void
dissect_option_qos(const guint8 qos, proto_tree *tree, tvbuff_t *tvb, int offset)
@ -384,91 +294,6 @@ dissect_option_rfd(const guchar error, const guchar field, int offset,
proto_tree_add_uint(tree, hf_osi_options_rfd_field, tvb, offset + field, 1, field);
}
/* dissect ATN security label used for policy based interdomain routing.*/
/* For details see ICAO doc 9705 Edition 3 SV5 5.6.2.2.2.2 */
static void
dissect_option_atn_security_label(const guchar sub_type, guchar length,
tvbuff_t *tvb, guint offset,
proto_tree *tree)
{
proto_tree *atn_sl_tree;
guchar len = 0;
guint8 tag_name = 0;
guint security_info_end = 0;
/* check for ATN security label */
if ( OSI_OPT_SECURITY_ATN_SR != sub_type )
return;
/* check Security Registration Length */
len = tvb_get_guint8(tvb, ++offset);
if ( OSI_OPT_SECURITY_ATN_SR_LEN != len )
return;
/* check Security Registration ID */
if ( tvb_memeql(tvb, ++offset , atn_security_registration_val, OSI_OPT_SECURITY_ATN_SR_LEN) )
return;
atn_sl_tree = proto_tree_add_subtree(tree, tvb, offset, length, ett_osi_qos, NULL,
val_to_str(sub_type, osi_opt_sec_atn_sr_vals, "Unknown (0x%x)"));
offset += OSI_OPT_SECURITY_ATN_SR_LEN;
/* Security Information length */
len = tvb_get_guint8(tvb, offset);
if ( OSI_OPT_SECURITY_ATN_SI_MAX_LEN < len )
return;
offset++;
security_info_end = offset + len;
while ( offset < security_info_end ) {
/* check tag name length*/
len = tvb_get_guint8(tvb, offset); /* check tag name length*/
if ( len != 1 )
return;
offset++;
tag_name = tvb_get_guint8(tvb, offset);
offset++;
switch(tag_name) {
case OSI_OPT_SECURITY_ATN_TT:
/* check tag set length*/
len = tvb_get_guint8(tvb, offset);
if ( len != OSI_OPT_SECURITY_ATN_TT_LEN )
return;
offset++;
proto_tree_add_uint_format(atn_sl_tree, hf_clnp_atntt, tvb, offset, 1,
tvb_get_guint8(tvb, offset), "%s: %s",
val_to_str(OSI_OPT_SECURITY_ATN_TT, osi_opt_sec_atn_si_vals, "Unknown (0x%x)"),
val_to_str(tvb_get_guint8(tvb, offset ), osi_opt_sec_atn_tt_vals, "Unknown (0x%x)"));
offset += len;
break;
case OSI_OPT_SECURITY_ATN_SC:
/* check tag set length*/
len = tvb_get_guint8(tvb, offset);
if ( len != OSI_OPT_SECURITY_ATN_SC_LEN )
return;
offset++;
proto_tree_add_uint_format(atn_sl_tree, hf_clnp_atnsc, tvb, offset, 1,
tvb_get_guint8(tvb, offset), "%s: %s",
val_to_str(OSI_OPT_SECURITY_ATN_SC, osi_opt_sec_atn_si_vals, "Unknown (0x%x)"),
val_to_str(tvb_get_guint8(tvb, offset ), osi_opt_sec_atn_sc_vals, "Unknown (0x%x)"));
offset += len;
break;
default:
return;
}
}
}
/* ############################## Dissection Functions ###################### */
/*
@ -496,6 +321,8 @@ dissect_osi_options(guchar opt_len, tvbuff_t *tvb, int offset, proto_tree *tree,
guchar parm_len = 0;
guchar parm_type = 0;
guint8 octet;
uint32_t sec_type;
tvbuff_t *next_tvb;
osi_option_tree = proto_tree_add_subtree(tree, tvb, offset, opt_len,
ett_osi_options, &ti, "### Option Section ###");
@ -515,13 +342,30 @@ dissect_osi_options(guchar opt_len, tvbuff_t *tvb, int offset, proto_tree *tree,
break;
case OSI_OPT_SECURITY:
octet = tvb_get_guint8(tvb, offset);
if ( clnp_decode_atn_options ) {
dissect_option_atn_security_label(octet,parm_len,tvb, offset,
osi_option_tree);
} else {
ti = proto_tree_add_item(osi_option_tree, hf_osi_options_security_type, tvb, offset, 1, ENC_BIG_ENDIAN);
proto_item_set_len(ti, parm_len);
/*
* This is unspecified by ISO 8473, and the interpretation
* of the value of the security option appears to be
* specified by various profiles, such as GOSIP, TUBA, and
* ATN.
*
* Thus, we use a payload dissector, so the user can
* specify which dissector to use.
*/
proto_tree_add_item_ret_uint(osi_option_tree, hf_osi_options_security_type, tvb, offset, 1, ENC_BIG_ENDIAN, &sec_type);
/* XXX */
switch ( sec_type ) {
case OSI_OPT_SEC_RESERVED:
case OSI_OPT_SEC_SRC_ADR_SPEC:
case OSI_OPT_SEC_DST_ADR_SPEC:
default:
break;
case OSI_OPT_SEC_GLOBAL_UNIQUE:
next_tvb = tvb_new_subset_length(tvb, offset + 1, parm_len - 1);
dissector_try_payload(subdissector_decode_as_opt_security_table,
next_tvb, pinfo, osi_option_tree);
break;
}
break;
@ -640,6 +484,9 @@ proto_register_osi_options(void) {
proto_register_subtree_array(ett, array_length(ett));
expert_osi_options = expert_register_protocol(proto_osi);
expert_register_field_array(expert_osi_options, ei, array_length(ei));
subdissector_decode_as_opt_security_table = register_decode_as_next_proto(proto_osi,
"osi.opt_security", "OSI Security Option", NULL);
}
/*
@ -654,4 +501,3 @@ proto_register_osi_options(void) {
* vi: set shiftwidth=2 tabstop=8 expandtab:
* :indentSize=2:tabSize=8:noTabs=true:
*/