forked from osmocom/wireshark
From guettler:
ATN decoding fixes for CLNP and COTP dissectors (configurable by option). ATN decoding fixes for CLNP and COTP dissectors (configurable by option). ATN specifics may be selected/deseleted per CLNP/COTP dissector configuration (as requested). CLNP dissector 1) configurable decoding of "ATN security label" COTP dissector 1) configurable decoding of ATN TPDU's 2) checksum calculation (none,OSI,ATN 16-bit, ATN 32-bit) 3) VP decoding for DR TPDU's https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5622 svn path=/trunk/; revision=46043
This commit is contained in:
parent
22d1aa1f6c
commit
c6cf5703f5
|
@ -38,6 +38,12 @@
|
|||
#include <epan/nlpid.h>
|
||||
#include <epan/ipproto.h>
|
||||
|
||||
/* pseudo-trailer for ATN extended checksums on TP4 layer*/
|
||||
/* the checksum is calculated from the TPDU as well als */
|
||||
/* dst NSAP length, dst NSAP, src NSAP length and src NSAP as encoded in CLNP PDU*/
|
||||
guint clnp_pt_len ;
|
||||
guint8 clnp_pt_buffer[42];
|
||||
|
||||
/* protocols and fields */
|
||||
|
||||
static int proto_clnp = -1;
|
||||
|
@ -62,6 +68,8 @@ static int hf_clnp_dest_length = -1;
|
|||
static int hf_clnp_dest = -1;
|
||||
static int hf_clnp_src_length = -1;
|
||||
static int hf_clnp_src = -1;
|
||||
int hf_clnp_atntt = -1; /* as referenced in packet-osi-options.c */
|
||||
int hf_clnp_atnsc = -1; /* as referenced in packet-osi-options.c */
|
||||
static int hf_clnp_segments = -1;
|
||||
static int hf_clnp_segment = -1;
|
||||
static int hf_clnp_segment_overlap = -1;
|
||||
|
@ -185,6 +193,7 @@ static GHashTable *clnp_reassembled_table = NULL;
|
|||
static guint tp_nsap_selector = NSEL_TP;
|
||||
static gboolean always_decode_transport = FALSE;
|
||||
static gboolean clnp_reassemble = TRUE;
|
||||
gboolean clnp_decode_atn_options = FALSE;
|
||||
|
||||
/* function definitions */
|
||||
|
||||
|
@ -250,7 +259,7 @@ dissect_clnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
/* fixed part decoding */
|
||||
cnf_hdr_len = tvb_get_guint8(tvb, P_CLNP_HDR_LEN);
|
||||
opt_len = cnf_hdr_len;
|
||||
|
||||
|
||||
if (tree) {
|
||||
ti = proto_tree_add_item(tree, proto_clnp, tvb, 0, cnf_hdr_len, ENC_NA);
|
||||
clnp_tree = proto_item_add_subtree(ti, ett_clnp);
|
||||
|
@ -342,7 +351,7 @@ dissect_clnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
cnf_cksum);
|
||||
break;
|
||||
}
|
||||
opt_len -= 9; /* Fixed part of Hesder */
|
||||
opt_len -= 9; /* Fixed part of Header */
|
||||
} /* tree */
|
||||
|
||||
/* address part */
|
||||
|
@ -354,6 +363,10 @@ dissect_clnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
src_len = tvb_get_guint8(tvb, offset + dst_len + 1);
|
||||
src_addr = tvb_get_ptr(tvb, offset + dst_len + 2, src_len);
|
||||
|
||||
/* store src & dst address parts for ATN extended checksum calculation in ositp.c */
|
||||
clnp_pt_len = dst_len + src_len + 2;
|
||||
tvb_memcpy(tvb, &clnp_pt_buffer, offset, sizeof(clnp_pt_buffer));
|
||||
|
||||
if (tree) {
|
||||
proto_tree_add_uint(clnp_tree, hf_clnp_dest_length, tvb, offset, 1,
|
||||
dst_len);
|
||||
|
@ -595,7 +608,13 @@ proto_register_clnp(void)
|
|||
{ &hf_clnp_src,
|
||||
{ "SA", "clnp.ssap", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
|
||||
|
||||
{ &hf_clnp_segment_overlap,
|
||||
{ &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 }},
|
||||
|
||||
|
@ -665,6 +684,14 @@ 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);
|
||||
|
||||
/* init src & dst address parts for ATN extended checksum calculation in ositp.c */
|
||||
memset(clnp_pt_buffer, 0, sizeof(clnp_pt_buffer));
|
||||
clnp_pt_len = 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -41,6 +41,46 @@
|
|||
#include "packet-esis.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 0x50
|
||||
|
||||
/* 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
|
||||
|
@ -85,13 +125,56 @@
|
|||
#define OSI_OPT_RFD_MASK 0xf0
|
||||
#define OSI_OPT_RFD_SUB_MASK 0x0f
|
||||
|
||||
|
||||
|
||||
extern gboolean 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 */
|
||||
|
||||
static gint ott_osi_options = -1;
|
||||
static gint ott_osi_qos = -1;
|
||||
static gint ott_osi_route = -1;
|
||||
static gint ott_osi_redirect = -1;
|
||||
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"},
|
||||
|
@ -337,6 +420,108 @@ dissect_option_rfd( const guchar error, const guchar field, int offset,
|
|||
}
|
||||
}
|
||||
|
||||
/* 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_item *ti;
|
||||
proto_tree *atn_sl_tree = NULL;
|
||||
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; } /* FALLTHROUGH */
|
||||
|
||||
/* check Security Registration Length */
|
||||
len = tvb_get_guint8(tvb, ++offset);
|
||||
if( OSI_OPT_SECURITY_ATN_SR_LEN != len ){
|
||||
return; } /* FALLTHROUGH */
|
||||
|
||||
/* check Security Registration ID */
|
||||
if (tvb_memeql(tvb, ++offset , atn_security_registration_val, OSI_OPT_SECURITY_ATN_SR_LEN )){
|
||||
return; } /* FALLTHROUGH */
|
||||
|
||||
ti = proto_tree_add_text( tree, tvb, offset, length,
|
||||
"%s",
|
||||
val_to_str( sub_type, osi_opt_sec_atn_sr_vals, "Unknown (0x%x)"));
|
||||
|
||||
atn_sl_tree = proto_item_add_subtree( ti, ott_osi_qos );
|
||||
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){
|
||||
/* FALLTHROUGH */
|
||||
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; } /* FALLTHROUGH */
|
||||
|
||||
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; } /* FALLTHROUGH */
|
||||
|
||||
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 ){
|
||||
/* FALLTHROUGH */
|
||||
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:
|
||||
/* FALLTHROUGH */
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* ############################## Dissection Functions ###################### */
|
||||
|
||||
/*
|
||||
|
@ -391,10 +576,16 @@ dissect_osi_options( guchar opt_len, tvbuff_t *tvb,
|
|||
break;
|
||||
case OSI_OPT_SECURITY:
|
||||
octet = tvb_get_guint8(tvb, offset);
|
||||
proto_tree_add_text( osi_option_tree, tvb, offset, parm_len,
|
||||
if ( clnp_decode_atn_options ){
|
||||
dissect_option_atn_security_label(octet,parm_len,tvb, offset, osi_option_tree );
|
||||
}else {
|
||||
proto_tree_add_text( osi_option_tree, tvb, offset, parm_len,
|
||||
"Security type: %s",
|
||||
val_to_str( octet&OSI_OPT_SEC_MASK,
|
||||
osi_opt_sec_vals, "Unknown (0x%x)") );
|
||||
osi_opt_sec_vals, "Unknown (0x%x)") );
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
case OSI_OPT_PRIORITY:
|
||||
octet = tvb_get_guint8(tvb, offset);
|
||||
|
|
|
@ -194,6 +194,155 @@ check_and_get_checksum( tvbuff_t *tvb, int offset, guint len, guint checksum, in
|
|||
return( CKSUM_OK );
|
||||
}
|
||||
|
||||
/* 4 octet ATN extended checksum: ICAO doc 9705 Ed3 Volume V section 5.5.4.6.4 */
|
||||
/* It is calculated over TP4 userdata (all checksums set to zero ) and a pseudo tailer */
|
||||
/* of length SRC-NSAP, SRC-NSAP, length DST-NSAP, DST-NSAP and ATN extended checksum. */
|
||||
/* In case of a CR TPDU, the value of the ISO 8073 16-bit fletcher checksum parameter shall */
|
||||
/* be set to zero. */
|
||||
gboolean check_atn_ec_32(
|
||||
tvbuff_t *tvb, guint tdpu_len,
|
||||
guint offset_ec_32_val, /* offset ATN extended checksum value, calculated at last as part of pseudo trailer */
|
||||
guint offset_iso8073_val, /* offset ISO 8073 fletcher checksum, CR only*/
|
||||
guint clnp_pt_len, /* length of NSAP part of pseudo trailer */
|
||||
guint8 * clnp_pt_buffer){ /* NSAP part of pseudo trailer */
|
||||
|
||||
guint i = 0;
|
||||
guint32 c0 = 0;
|
||||
guint32 c1 = 0;
|
||||
guint32 c2 = 0;
|
||||
guint32 c3 = 0;
|
||||
guint32 sum = 0;
|
||||
|
||||
/* sum accross complete TDPU */
|
||||
for ( i =0; i< tdpu_len; i++){
|
||||
|
||||
c0 += tvb_get_guint8(tvb, i) ;
|
||||
|
||||
if( ( i >= offset_ec_32_val ) && /* ignore 32 bit ATN extended checksum value */
|
||||
( i < ( offset_ec_32_val + 4 ) ) ){
|
||||
c0 -= tvb_get_guint8(tvb, i); }
|
||||
|
||||
if( ( offset_iso8073_val ) && /* ignore 16 bit ISO 8073 checksum, if present*/
|
||||
( i >= offset_iso8073_val ) &&
|
||||
( i < ( offset_iso8073_val + 2 ) ) ){
|
||||
c0 -= tvb_get_guint8(tvb, i); }
|
||||
|
||||
if ( c0 >= 0x000000FF )
|
||||
c0 -= 0x00000FF;
|
||||
c1 += c0;
|
||||
if ( c1 >= 0x000000FF )
|
||||
c1 -= 0x000000FF;
|
||||
c2 += c1;
|
||||
if ( c2 >= 0x000000FF )
|
||||
c2 -= 0x000000FF;
|
||||
c3 += c2;
|
||||
if ( c3 >= 0x000000FF )
|
||||
c3 -= 0x000000FF;
|
||||
|
||||
}
|
||||
/* add NSAP part of pseudo trailer */
|
||||
for ( i =0; i< clnp_pt_len; i++){
|
||||
c0 += clnp_pt_buffer[i];
|
||||
if ( c0 >= 0x000000FF )
|
||||
c0 -= 0x000000FF;
|
||||
c1 += c0;
|
||||
if ( c1 >= 0x000000FF )
|
||||
c1 -= 0x000000FF;
|
||||
c2 += c1;
|
||||
if ( c2 >= 0x000000FF )
|
||||
c2 -= 0x000000FF;
|
||||
c3 += c2;
|
||||
if ( c3 >= 0x000000FF )
|
||||
c3 -= 0x000000FF;
|
||||
}
|
||||
/* add with extended checksum as last part of the pseudo trailer */
|
||||
for ( i = offset_ec_32_val; i< (offset_ec_32_val+4); i++){
|
||||
c0 += tvb_get_guint8(tvb, i) ;
|
||||
|
||||
if ( c0 >= 0x000000FF )
|
||||
c0 -= 0x00000FF;
|
||||
c1 += c0;
|
||||
if ( c1 >= 0x000000FF )
|
||||
c1 -= 0x000000FF;
|
||||
c2 += c1;
|
||||
if ( c2 >= 0x000000FF )
|
||||
c2 -= 0x000000FF;
|
||||
c3 += c2;
|
||||
if ( c3 >= 0x000000FF )
|
||||
c3 -= 0x000000FF;
|
||||
}
|
||||
|
||||
sum = (c3 << 24) + (c2 << 16 ) + (c1 << 8) + c0 ;
|
||||
|
||||
if(!sum)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* 2 octet ATN extended checksum: ICAO doc 9705 Ed3 Volume V section 5.5.4.6.4 */
|
||||
/* It is calculated over TP4 userdata (all checksums set to zero ) and a pseudo tailer */
|
||||
/* of length SRC-NSAP, SRC-NSAP, length DST-NSAP, DST-NSAP and ATN extended checksum. */
|
||||
/* In case of a CR TPDU, the value of the ISO 8073 16-bit fletcher checksum parameter shall */
|
||||
/* be set to zero. */
|
||||
/* this routine is currently *untested* because of the unavailability of samples.*/
|
||||
gboolean check_atn_ec_16(
|
||||
tvbuff_t *tvb,
|
||||
guint tdpu_len,
|
||||
guint offset_ec_16_val, /* offset ATN extended checksum value, calculated at last as part of pseudo trailer */
|
||||
guint offset_iso8073_val, /* offset ISO 8073 fletcher checksum, CR only*/
|
||||
guint clnp_pt_len, /* length of NSAP part of pseudo trailer */
|
||||
guint8 * clnp_pt_buffer ){ /* NSAP part of pseudo trailer */
|
||||
|
||||
guint i = 0;
|
||||
guint16 c0 = 0;
|
||||
guint16 c1 = 0;
|
||||
guint16 sum = 0;
|
||||
|
||||
/* sum accross complete TDPU */
|
||||
for ( i =0; i< tdpu_len; i++){
|
||||
|
||||
c0 += tvb_get_guint8(tvb, i);
|
||||
|
||||
if( (i >= offset_ec_16_val) && /* ignore 16 bit extended checksum */
|
||||
(i < (offset_ec_16_val + 2) ) ) {
|
||||
c0 -= tvb_get_guint8(tvb, i) ; }
|
||||
|
||||
if( (i >= offset_iso8073_val) && /* ignore 16 bit ISO 8073 checksum, if present*/
|
||||
(i < (offset_iso8073_val + 2) ) ) {
|
||||
c0 -= tvb_get_guint8(tvb, i) ; }
|
||||
|
||||
if ( c0 >= 0x00FF )
|
||||
c0 -= 0x00FF;
|
||||
c1 += c0;
|
||||
if ( c1 >= 0x00FF )
|
||||
c1 -= 0x00FF;
|
||||
|
||||
}
|
||||
/* sum with NSAP part of the pseudo trailer */
|
||||
for ( i =0; i< clnp_pt_len; i++){
|
||||
c0 += clnp_pt_buffer[i] ;
|
||||
c1 += c0;
|
||||
}
|
||||
|
||||
/* add extended checksum as last part of the pseudo trailer */
|
||||
for ( i = offset_ec_16_val; i< (offset_ec_16_val+2); i++){
|
||||
c0 += tvb_get_guint8(tvb, i) ;
|
||||
|
||||
if ( c0 >= 0x00FF )
|
||||
c0 -= 0x00FF;
|
||||
c1 += c0;
|
||||
if ( c1 >= 0x00FF )
|
||||
c1 -= 0x00FF;
|
||||
}
|
||||
|
||||
sum = (c1 << 8) + c0 ;
|
||||
|
||||
if(!sum)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* main entry point */
|
||||
|
@ -350,5 +499,6 @@ proto_register_osi(void)
|
|||
"Whether segmented TPKT datagrams should be reassembled",
|
||||
&tpkt_desegment);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -87,5 +87,7 @@ typedef enum {
|
|||
|
||||
extern cksum_status_t calc_checksum(tvbuff_t *, int, guint, guint);
|
||||
extern cksum_status_t check_and_get_checksum( tvbuff_t *, int, guint, guint, int, guint16*);
|
||||
extern gboolean check_atn_ec_32(tvbuff_t *tvb, guint tdpu_len, guint offset_ec_32_val, guint offset_iso8073_val, guint clnp_pt_len, guint8 * clnp_pt_buffer);
|
||||
extern gboolean check_atn_ec_16( tvbuff_t *tvb, guint tdpu_len, guint offset_ec_16_val, guint offset_iso8073_val, guint clnp_pt_len, guint8 * clnp_pt_buffer );
|
||||
|
||||
#endif /* _PACKET_OSI_H */
|
||||
|
|
|
@ -198,6 +198,18 @@ static const value_string class_option_vals[] = {
|
|||
number of octets? */
|
||||
#define is_LI_NORMAL_AK(p) ( ( p & 0x01 ) == 0 )
|
||||
|
||||
/* modified TPDU length indicators due to ATN extended checksum */
|
||||
#define LI_ATN_NORMAL_DT_WITH_CHECKSUM 10 /* ATN 4 octet extended checksum adds 2 octets */
|
||||
#define LI_ATN_EXTENDED_DT_WITH_CHECKSUM 13 /* ATN 4 octet extended checksum adds 2 octets */
|
||||
#define LI_ATN_NORMAL_EA_WITH_CHECKSUM 10 /* ATN 4 octet extended checksum adds 2 octets */
|
||||
#define LI_ATN_EXTENDED_EA_WITH_CHECKSUM 13 /* ATN 4 octet extended checksum adds 2 octets */
|
||||
#define LI_ATN_NORMAL_RJ 6 /* ATN 4 octet extended checksum adds 2 octets */
|
||||
#define LI_ATN_EXTENDED_RJ 11 /* ATN 4 octet extended checksum adds 2 octets */
|
||||
#define LI_ATN_MAX_DC 11 /* ATN 4 octet extended checksum adds 2 octets */
|
||||
#define LI_ATN_MAX_AK 30 /* ATN 4 octet extended checksum adds 2 octets */
|
||||
#define LI_ATN_MAX_EA 13 /* ATN 4 octet extended checksum adds 2 octets */
|
||||
#define LI_ATN_MAX_ER 10 /* ATN 4 octet extended checksum adds 2 octets */
|
||||
|
||||
/* variant part */
|
||||
|
||||
#define VP_ACK_TIME 0x85
|
||||
|
@ -219,7 +231,23 @@ static const value_string class_option_vals[] = {
|
|||
#define VP_PREF_MAX_TPDU_SIZE 0xF0
|
||||
#define VP_INACTIVITY_TIMER 0xF2
|
||||
|
||||
/* ATN */
|
||||
/* Parameter codes with bits 7 and 8 are explicitly not */
|
||||
/* assigned by ISO/IEC 8073, nor is their use precluded. */
|
||||
/* Parameter codes for ATN defined in ICAO doc 9507 Ed3 SV 5 section 5.5.2.4.3.1 */
|
||||
#define VP_ATN_EC_32 0x08 /* 4 octet ATN Extended Transport Checksum parameter */
|
||||
#define VP_ATN_EC_16 0x09 /* 2 octet ATN Extended Transport Checksum parameter */
|
||||
/* ATN end */
|
||||
|
||||
/* pseudo-trailer for ATN extended checksums on TP4 layer*/
|
||||
/* the checksum is calculated from the TPDU as well als */
|
||||
/* dst NSAP length, dst NSAP, src NSAP length and src NSAP as encoded in CLNP PDU*/
|
||||
extern guint clnp_pt_len; /* length of dst-len + dst-nsap + src-len + src-nsap */
|
||||
extern guint8 clnp_pt_buffer[42]; /* buffer containing CLNP pseudoheader */
|
||||
|
||||
static const value_string tp_vpart_type_vals[] = {
|
||||
{ VP_ATN_EC_16, "ATN extended checksum - 16 bit" },
|
||||
{ VP_ATN_EC_32, "ATN extended checksum - 32 bit" },
|
||||
{ VP_ACK_TIME, "ack time" },
|
||||
{ VP_RES_ERROR, "res error" },
|
||||
{ VP_PRIORITY, "priority" },
|
||||
|
@ -237,9 +265,16 @@ static const value_string tp_vpart_type_vals[] = {
|
|||
{ VP_OPT_SEL, "options" },
|
||||
{ VP_PROTO_CLASS, "proto class" },
|
||||
{ VP_PREF_MAX_TPDU_SIZE, "preferred max TPDU size" },
|
||||
{ VP_INACTIVITY_TIMER, "inactivity timer" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
static const value_string tp_vpart_checksum_vals[] = {
|
||||
{ FALSE, "incorrect" },
|
||||
{ TRUE, "correct" }
|
||||
};
|
||||
|
||||
|
||||
static int hf_cotp_vp_src_tsap = -1;
|
||||
static int hf_cotp_vp_dst_tsap = -1;
|
||||
static int hf_cotp_vp_src_tsap_bytes = -1;
|
||||
|
@ -272,6 +307,8 @@ static gboolean cotp_last_fragment = FALSE;
|
|||
/* options */
|
||||
static gboolean cotp_reassemble = TRUE;
|
||||
static gint32 tsap_display = TSAP_DISPLAY_AUTO;
|
||||
static gboolean cotp_decode_atn = TRUE;
|
||||
|
||||
|
||||
const enum_val_t tsap_display_options[] = {
|
||||
{"auto", "As strings if printable", TSAP_DISPLAY_AUTO},
|
||||
|
@ -285,6 +322,7 @@ const enum_val_t tsap_display_options[] = {
|
|||
|
||||
#define MAX_TSAP_LEN 32
|
||||
|
||||
|
||||
static void cotp_frame_end(void)
|
||||
{
|
||||
if (!cotp_last_fragment) {
|
||||
|
@ -352,9 +390,18 @@ static gboolean ositp_decode_var_part(tvbuff_t *tvb, int offset,
|
|||
guint8 c1;
|
||||
guint16 s, s1,s2,s3,s4;
|
||||
guint32 t1, t2, t3, t4;
|
||||
guint32 offset_iso8073_checksum = 0;
|
||||
gint32 i = 0;
|
||||
guint16 tdpu_length = 0;
|
||||
guint8 tmp_code = 0;
|
||||
guint tmp_len = 0;
|
||||
guint checksum_ok = 0;
|
||||
guint32 pref_max_tpdu_size;
|
||||
proto_item *hidden_item;
|
||||
|
||||
/* TDPU length needed for ATN checksum calculations */
|
||||
tdpu_length = offset + vp_length + tvb_length_remaining(tvb, offset + vp_length);
|
||||
|
||||
while (vp_length != 0) {
|
||||
code = tvb_get_guint8(tvb, offset);
|
||||
proto_tree_add_text(tree, tvb, offset, 1,
|
||||
|
@ -373,6 +420,58 @@ static gboolean ositp_decode_var_part(tvbuff_t *tvb, int offset,
|
|||
vp_length -= 1;
|
||||
|
||||
switch (code) {
|
||||
case VP_ATN_EC_16 : /* ATN */
|
||||
if (cotp_decode_atn) {
|
||||
/* if an alternate OSI checksum is present in the currently unprocessed VP section to the checksum algorithm has to know */
|
||||
/* this may be the case for backward compatible CR TDPU */
|
||||
if(!offset_iso8073_checksum){
|
||||
/* search following parameters in VP part for ISO checksum */
|
||||
for( i = ( offset + length ); i < vp_length; ){
|
||||
tmp_code = tvb_get_guint8(tvb, i++);
|
||||
tmp_len = tvb_get_guint8(tvb, i++);
|
||||
if (tmp_code == VP_CHECKSUM ){
|
||||
offset_iso8073_checksum = i; /* save ISO 8073 checksum offset for ATN extended checksum calculation */
|
||||
break;
|
||||
}
|
||||
i += tmp_len; }
|
||||
}
|
||||
checksum_ok = check_atn_ec_16(tvb, tdpu_length, offset, offset_iso8073_checksum, clnp_pt_len, (guint8 *) &clnp_pt_buffer);
|
||||
proto_tree_add_text(tree, tvb, offset, length,
|
||||
"ATN extended checksum : 0x%04x (%s)",
|
||||
tvb_get_ntohs(tvb, offset),
|
||||
val_to_str(checksum_ok, tp_vpart_checksum_vals, "?"));
|
||||
}else {
|
||||
proto_tree_add_text(tree, tvb, offset, length,"Parameter value: <not shown>");
|
||||
}
|
||||
offset += length;
|
||||
vp_length -= length;
|
||||
break;
|
||||
|
||||
case VP_ATN_EC_32 : /* ATN */
|
||||
if (cotp_decode_atn) {
|
||||
/* if an alternate OSI checksum is present in the currently unprocessed VP section the checksum algorithm has to know */
|
||||
/* this may be the case for backward compatible CR TDPU */
|
||||
if(!offset_iso8073_checksum){
|
||||
/* search following parameters in VP part for ISO checksum */
|
||||
for( i = ( offset + length ); i < vp_length; ){
|
||||
tmp_code = tvb_get_guint8(tvb, i++);
|
||||
tmp_len = tvb_get_guint8(tvb, i++);
|
||||
if (tmp_code == VP_CHECKSUM ){
|
||||
offset_iso8073_checksum = i; /* save ISO 8073 checksum offset for ATN extended checksum calculation */
|
||||
break;}
|
||||
i += tmp_len; }
|
||||
}
|
||||
checksum_ok = check_atn_ec_32(tvb, tdpu_length, offset, offset_iso8073_checksum, clnp_pt_len, (guint8 *) &clnp_pt_buffer);
|
||||
proto_tree_add_text(tree, tvb, offset, length,
|
||||
"ATN extended checksum : 0x%08x (%s)",
|
||||
tvb_get_ntohl(tvb, offset),
|
||||
val_to_str(checksum_ok, tp_vpart_checksum_vals, "?"));
|
||||
}else {
|
||||
proto_tree_add_text(tree, tvb, offset, length,"Parameter value: <not shown>");
|
||||
}
|
||||
offset += length;
|
||||
vp_length -= length;
|
||||
break;
|
||||
|
||||
case VP_ACK_TIME:
|
||||
s = tvb_get_ntohs(tvb, offset);
|
||||
|
@ -585,8 +684,10 @@ static gboolean ositp_decode_var_part(tvbuff_t *tvb, int offset,
|
|||
break;
|
||||
|
||||
case VP_CHECKSUM:
|
||||
offset_iso8073_checksum = offset; /* save ISO 8073 checksum offset for ATN extended checksum calculation */
|
||||
checksum_ok = calc_checksum(tvb, 0, tdpu_length, tvb_get_ntohs(tvb, offset));
|
||||
proto_tree_add_text(tree, tvb, offset, length,
|
||||
"Checksum: 0x%04x", tvb_get_ntohs(tvb, offset));
|
||||
"Checksum: 0x%04x (%s)", tvb_get_ntohs(tvb, offset),val_to_str( (checksum_ok == CKSUM_OK) ? TRUE : FALSE , tp_vpart_checksum_vals, "?"));
|
||||
offset += length;
|
||||
vp_length -= length;
|
||||
break;
|
||||
|
@ -697,10 +798,11 @@ static int ositp_decode_DR(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu,
|
|||
guint16 dst_ref, src_ref;
|
||||
guchar reason;
|
||||
const char *str;
|
||||
|
||||
|
||||
/* ATN TPDU's tend to be larger than normal OSI, so nothing to do with respect to LI checks */
|
||||
if (li < LI_MIN_DR)
|
||||
return -1;
|
||||
|
||||
|
||||
dst_ref = tvb_get_ntohs(tvb, offset + P_DST_REF);
|
||||
|
||||
src_ref = tvb_get_ntohs(tvb, offset + P_SRC_REF);
|
||||
|
@ -753,6 +855,11 @@ static int ositp_decode_DR(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu,
|
|||
"Cause: %s", str);
|
||||
}
|
||||
|
||||
/* decode VP */
|
||||
if (tree) {
|
||||
ositp_decode_var_part(tvb, offset + P_REASON_IN_DR + 1, li - P_REASON_IN_DR , 4, cotp_tree);
|
||||
}
|
||||
|
||||
offset += li + 1;
|
||||
|
||||
expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_CHAT,
|
||||
|
@ -785,79 +892,185 @@ static int ositp_decode_DT(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu,
|
|||
fragment_data *fd_head;
|
||||
conversation_t *conv;
|
||||
|
||||
/* VP_CHECKSUM is the only parameter allowed in the variable part.
|
||||
(This means we may misdissect this if the packet is bad and
|
||||
contains other parameters.) */
|
||||
switch (li) {
|
||||
/* note: in the ATN the user is up to chose between 3 different checksums: */
|
||||
/* standard OSI, 2 or 4 octet extended checksum. */
|
||||
/* The differences for DT are that the TDPU headers may be enlarged by 2 octets */
|
||||
/* and that checksum related option codes and option lengths are different. */
|
||||
/* to not mess up the original OSI dissector LI checking was implemented separately. */
|
||||
if (!cotp_decode_atn) { /* non ATN, plain OSI*/
|
||||
|
||||
case LI_NORMAL_DT_WITH_CHECKSUM :
|
||||
if (tvb_get_guint8(tvb, offset + P_VAR_PART_NDT) != VP_CHECKSUM)
|
||||
return -1;
|
||||
/* FALLTHROUGH */
|
||||
/* VP_CHECKSUM is the only parameter allowed in the variable part.
|
||||
(This means we may misdissect this if the packet is bad and
|
||||
contains other parameters.) */
|
||||
switch (li) {
|
||||
|
||||
case LI_NORMAL_DT_WITHOUT_CHECKSUM :
|
||||
tpdu_nr = tvb_get_guint8(tvb, offset + P_TPDU_NR_234);
|
||||
if ( tpdu_nr & 0x80 )
|
||||
tpdu_nr = tpdu_nr & 0x7F;
|
||||
else
|
||||
fragment = TRUE;
|
||||
is_extended = FALSE;
|
||||
is_class_234 = TRUE;
|
||||
dst_ref = tvb_get_ntohs(tvb, offset + P_DST_REF);
|
||||
break;
|
||||
case LI_NORMAL_DT_WITH_CHECKSUM :
|
||||
if (tvb_get_guint8(tvb, offset + P_VAR_PART_NDT) != VP_CHECKSUM)
|
||||
return -1;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case LI_EXTENDED_DT_WITH_CHECKSUM :
|
||||
if (tvb_get_guint8(tvb, offset + P_VAR_PART_EDT) != VP_CHECKSUM)
|
||||
return -1;
|
||||
/* FALLTHROUGH */
|
||||
case LI_NORMAL_DT_WITHOUT_CHECKSUM :
|
||||
tpdu_nr = tvb_get_guint8(tvb, offset + P_TPDU_NR_234);
|
||||
if ( tpdu_nr & 0x80 )
|
||||
tpdu_nr = tpdu_nr & 0x7F;
|
||||
else
|
||||
fragment = TRUE;
|
||||
is_extended = FALSE;
|
||||
is_class_234 = TRUE;
|
||||
dst_ref = tvb_get_ntohs(tvb, offset + P_DST_REF);
|
||||
break;
|
||||
|
||||
case LI_EXTENDED_DT_WITHOUT_CHECKSUM :
|
||||
tpdu_nr = tvb_get_ntohl(tvb, offset + P_TPDU_NR_234);
|
||||
if ( tpdu_nr & 0x80000000 )
|
||||
tpdu_nr = tpdu_nr & 0x7FFFFFFF;
|
||||
else
|
||||
fragment = TRUE;
|
||||
is_extended = TRUE;
|
||||
is_class_234 = TRUE;
|
||||
dst_ref = tvb_get_ntohs(tvb, offset + P_DST_REF);
|
||||
break;
|
||||
case LI_EXTENDED_DT_WITH_CHECKSUM :
|
||||
if (tvb_get_guint8(tvb, offset + P_VAR_PART_EDT) != VP_CHECKSUM)
|
||||
return -1;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case LI_NORMAL_DT_CLASS_01 :
|
||||
tpdu_nr = tvb_get_guint8(tvb, offset + P_TPDU_NR_0_1);
|
||||
if ( tpdu_nr & 0x80 )
|
||||
tpdu_nr = tpdu_nr & 0x7F;
|
||||
else
|
||||
fragment = TRUE;
|
||||
is_extended = FALSE;
|
||||
is_class_234 = FALSE;
|
||||
prev_dst_ref = p_get_proto_data (pinfo->fd, proto_clnp);
|
||||
if (!prev_dst_ref) {
|
||||
/* First COTP in frame - save previous dst_ref as offset */
|
||||
prev_dst_ref = se_alloc (sizeof (guint32));
|
||||
*prev_dst_ref = cotp_dst_ref;
|
||||
p_add_proto_data (pinfo->fd, proto_clnp, prev_dst_ref);
|
||||
} else if (cotp_frame_reset) {
|
||||
cotp_dst_ref = *prev_dst_ref;
|
||||
}
|
||||
cotp_frame_reset = FALSE;
|
||||
cotp_last_fragment = fragment;
|
||||
dst_ref = cotp_dst_ref;
|
||||
conv = find_conversation (pinfo->fd->num, &pinfo->src, &pinfo->dst,
|
||||
pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
|
||||
if (conv) {
|
||||
/* Found a conversation, also use index for the generated dst_ref */
|
||||
dst_ref += (conv->index << 16);
|
||||
}
|
||||
if (!fragment) {
|
||||
cotp_dst_ref++;
|
||||
register_frame_end_routine(pinfo, cotp_frame_end);
|
||||
}
|
||||
break;
|
||||
case LI_EXTENDED_DT_WITHOUT_CHECKSUM :
|
||||
tpdu_nr = tvb_get_ntohl(tvb, offset + P_TPDU_NR_234);
|
||||
if ( tpdu_nr & 0x80000000 )
|
||||
tpdu_nr = tpdu_nr & 0x7FFFFFFF;
|
||||
else
|
||||
fragment = TRUE;
|
||||
is_extended = TRUE;
|
||||
is_class_234 = TRUE;
|
||||
dst_ref = tvb_get_ntohs(tvb, offset + P_DST_REF);
|
||||
break;
|
||||
|
||||
default : /* bad TPDU */
|
||||
return -1;
|
||||
}
|
||||
case LI_NORMAL_DT_CLASS_01 :
|
||||
tpdu_nr = tvb_get_guint8(tvb, offset + P_TPDU_NR_0_1);
|
||||
if ( tpdu_nr & 0x80 )
|
||||
tpdu_nr = tpdu_nr & 0x7F;
|
||||
else
|
||||
fragment = TRUE;
|
||||
is_extended = FALSE;
|
||||
is_class_234 = FALSE;
|
||||
prev_dst_ref = p_get_proto_data (pinfo->fd, proto_clnp);
|
||||
if (!prev_dst_ref) {
|
||||
/* First COTP in frame - save previous dst_ref as offset */
|
||||
prev_dst_ref = se_alloc (sizeof (guint32));
|
||||
*prev_dst_ref = cotp_dst_ref;
|
||||
p_add_proto_data (pinfo->fd, proto_clnp, prev_dst_ref);
|
||||
} else if (cotp_frame_reset) {
|
||||
cotp_dst_ref = *prev_dst_ref;
|
||||
}
|
||||
cotp_frame_reset = FALSE;
|
||||
cotp_last_fragment = fragment;
|
||||
dst_ref = cotp_dst_ref;
|
||||
conv = find_conversation (pinfo->fd->num, &pinfo->src, &pinfo->dst,
|
||||
pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
|
||||
if (conv) {
|
||||
/* Found a conversation, also use index for the generated dst_ref */
|
||||
dst_ref += (conv->index << 16);
|
||||
}
|
||||
if (!fragment) {
|
||||
cotp_dst_ref++;
|
||||
register_frame_end_routine(pinfo, cotp_frame_end);
|
||||
}
|
||||
break;
|
||||
|
||||
default : /* bad TPDU */
|
||||
return -1;
|
||||
} /* li */
|
||||
} else {
|
||||
/* check ATN class4 TDPU's here */
|
||||
|
||||
/* check packet length indicators of DaTa(DT) TDPU */
|
||||
/* note: use of checksum depends on the selected RER */
|
||||
/* (high:non-use medium:16-bit OSI/16-bit ext.ATN low:32-bit ext. ATN) */
|
||||
/* note: sole use of TP4 class in the ATN */
|
||||
/* note: normal/extended TDPU numbering is negociable */
|
||||
switch (li) {
|
||||
|
||||
case LI_NORMAL_DT_WITHOUT_CHECKSUM :
|
||||
tpdu_nr = tvb_get_guint8(tvb, offset + P_TPDU_NR_234);
|
||||
if ( tpdu_nr & 0x80 )
|
||||
tpdu_nr = tpdu_nr & 0x7F;
|
||||
else
|
||||
fragment = TRUE;
|
||||
is_extended = FALSE;
|
||||
is_class_234 = TRUE;
|
||||
dst_ref = tvb_get_ntohs(tvb, offset + P_DST_REF);
|
||||
break;
|
||||
|
||||
/* normal DT with 2 octets of OSI or of ATN Extended Checksum */
|
||||
case LI_NORMAL_DT_WITH_CHECKSUM :
|
||||
if ( tvb_get_guint8(tvb, offset + P_VAR_PART_NDT) != VP_CHECKSUM &&
|
||||
tvb_get_guint8(tvb, offset + P_VAR_PART_NDT) != VP_ATN_EC_16 )
|
||||
return -1; /* FALLTHROUGH */
|
||||
tpdu_nr = tvb_get_guint8(tvb, offset + P_TPDU_NR_234);
|
||||
if ( tpdu_nr & 0x80 )
|
||||
tpdu_nr = tpdu_nr & 0x7F;
|
||||
else
|
||||
fragment = TRUE;
|
||||
is_extended = FALSE;
|
||||
is_class_234 = TRUE;
|
||||
dst_ref = tvb_get_ntohs(tvb, offset + P_DST_REF);
|
||||
break;
|
||||
|
||||
/* normal DT with ATN Extended Checksum (4 octets)*/
|
||||
case LI_ATN_NORMAL_DT_WITH_CHECKSUM :
|
||||
if ( tvb_get_guint8(tvb, offset + P_VAR_PART_NDT) != VP_ATN_EC_32 )
|
||||
return -1; /* FALLTHROUGH */
|
||||
|
||||
tpdu_nr = tvb_get_guint8(tvb, offset + P_TPDU_NR_234);
|
||||
|
||||
if ( tpdu_nr & 0x80 )
|
||||
tpdu_nr = tpdu_nr & 0x7F;
|
||||
else
|
||||
fragment = TRUE;
|
||||
is_extended = FALSE;
|
||||
is_class_234 = TRUE;
|
||||
dst_ref = tvb_get_ntohs(tvb, offset + P_DST_REF);
|
||||
break;
|
||||
|
||||
case LI_EXTENDED_DT_WITHOUT_CHECKSUM :
|
||||
tpdu_nr = tvb_get_ntohl(tvb, offset + P_TPDU_NR_234);
|
||||
if ( tpdu_nr & 0x80000000 )
|
||||
tpdu_nr = tpdu_nr & 0x7FFFFFFF;
|
||||
else
|
||||
fragment = TRUE;
|
||||
is_extended = TRUE;
|
||||
is_class_234 = TRUE;
|
||||
dst_ref = tvb_get_ntohs(tvb, offset + P_DST_REF);
|
||||
break;
|
||||
|
||||
/* extended DT with 2 octets of OSI or of ATN Extended Checksum */
|
||||
case LI_EXTENDED_DT_WITH_CHECKSUM :
|
||||
if ( tvb_get_guint8(tvb, offset + P_VAR_PART_EDT) != VP_CHECKSUM &&
|
||||
tvb_get_guint8(tvb, offset + P_VAR_PART_EDT) != VP_ATN_EC_16 )
|
||||
return -1; /* FALLTHROUGH */
|
||||
/* FALLTHROUGH */
|
||||
|
||||
tpdu_nr = tvb_get_ntohl(tvb, offset + P_TPDU_NR_234);
|
||||
if ( tpdu_nr & 0x80000000 )
|
||||
tpdu_nr = tpdu_nr & 0x7FFFFFFF;
|
||||
else
|
||||
fragment = TRUE;
|
||||
is_extended = TRUE;
|
||||
is_class_234 = TRUE;
|
||||
dst_ref = tvb_get_ntohs(tvb, offset + P_DST_REF);
|
||||
break;
|
||||
|
||||
/* extended DT with 4 octets ATN Extended Checksum */
|
||||
case LI_ATN_EXTENDED_DT_WITH_CHECKSUM:
|
||||
if ( tvb_get_guint8(tvb, offset + P_VAR_PART_EDT) != VP_ATN_EC_32 )
|
||||
return -1; /* FALLTHROUGH */
|
||||
|
||||
tpdu_nr = tvb_get_ntohl(tvb, offset + P_TPDU_NR_234);
|
||||
if ( tpdu_nr & 0x80000000 )
|
||||
tpdu_nr = tpdu_nr & 0x7FFFFFFF;
|
||||
else
|
||||
fragment = TRUE;
|
||||
is_extended = TRUE;
|
||||
is_class_234 = TRUE;
|
||||
dst_ref = tvb_get_ntohs(tvb, offset + P_DST_REF);
|
||||
break;
|
||||
|
||||
default : /* bad TPDU */
|
||||
return -1;
|
||||
} /* li */
|
||||
} /* cotp_decode_atn */
|
||||
|
||||
pinfo->clnp_dstref = dst_ref;
|
||||
|
||||
pinfo->fragmented = fragment;
|
||||
|
@ -1011,45 +1224,138 @@ static int ositp_decode_ED(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu,
|
|||
guint tpdu_nr;
|
||||
tvbuff_t *next_tvb;
|
||||
|
||||
/* ED TPDUs are never fragmented */
|
||||
/* note: in the ATN the user is up to chose between 3 different checksums: */
|
||||
/* standard OSI, 2 or 4 octet extended checksum. */
|
||||
/* The differences for ED (as for DT) are that the TDPU headers may be enlarged by 2 octets */
|
||||
/* and that checksum related option codes and option lengths are different. */
|
||||
/* to not mess up the original OSI dissector LI checking was implemented separately. */
|
||||
/* note: this could not be tested, because no sample was avail for expedited data */
|
||||
if (!cotp_decode_atn) { /* non ATN, plain OSI*/
|
||||
/* ED TPDUs are never fragmented */
|
||||
|
||||
/* VP_CHECKSUM is the only parameter allowed in the variable part.
|
||||
(This means we may misdissect this if the packet is bad and
|
||||
contains other parameters.) */
|
||||
switch (li) {
|
||||
/* VP_CHECKSUM is the only parameter allowed in the variable part.
|
||||
(This means we may misdissect this if the packet is bad and
|
||||
contains other parameters.) */
|
||||
switch (li) {
|
||||
|
||||
case LI_NORMAL_DT_WITH_CHECKSUM :
|
||||
if (tvb_get_guint8(tvb, offset + P_VAR_PART_NDT) != VP_CHECKSUM)
|
||||
return -1;
|
||||
/* FALLTHROUGH */
|
||||
case LI_NORMAL_DT_WITH_CHECKSUM :
|
||||
if (tvb_get_guint8(tvb, offset + P_VAR_PART_NDT) != VP_CHECKSUM)
|
||||
return -1;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case LI_NORMAL_DT_WITHOUT_CHECKSUM :
|
||||
tpdu_nr = tvb_get_guint8(tvb, offset + P_TPDU_NR_234);
|
||||
if ( tpdu_nr & 0x80 )
|
||||
tpdu_nr = tpdu_nr & 0x7F;
|
||||
else
|
||||
return -1;
|
||||
is_extended = FALSE;
|
||||
break;
|
||||
case LI_NORMAL_DT_WITHOUT_CHECKSUM :
|
||||
tpdu_nr = tvb_get_guint8(tvb, offset + P_TPDU_NR_234);
|
||||
if ( tpdu_nr & 0x80 )
|
||||
tpdu_nr = tpdu_nr & 0x7F;
|
||||
else
|
||||
return -1;
|
||||
is_extended = FALSE;
|
||||
break;
|
||||
|
||||
case LI_EXTENDED_DT_WITH_CHECKSUM :
|
||||
if (tvb_get_guint8(tvb, offset + P_VAR_PART_EDT) != VP_CHECKSUM)
|
||||
return -1;
|
||||
/* FALLTHROUGH */
|
||||
case LI_EXTENDED_DT_WITH_CHECKSUM :
|
||||
if (tvb_get_guint8(tvb, offset + P_VAR_PART_EDT) != VP_CHECKSUM)
|
||||
return -1;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case LI_EXTENDED_DT_WITHOUT_CHECKSUM :
|
||||
tpdu_nr = tvb_get_ntohl(tvb, offset + P_TPDU_NR_234);
|
||||
if ( tpdu_nr & 0x80000000 )
|
||||
tpdu_nr = tpdu_nr & 0x7FFFFFFF;
|
||||
else
|
||||
return -1;
|
||||
is_extended = TRUE;
|
||||
break;
|
||||
case LI_EXTENDED_DT_WITHOUT_CHECKSUM :
|
||||
tpdu_nr = tvb_get_ntohl(tvb, offset + P_TPDU_NR_234);
|
||||
if ( tpdu_nr & 0x80000000 )
|
||||
tpdu_nr = tpdu_nr & 0x7FFFFFFF;
|
||||
else
|
||||
return -1;
|
||||
is_extended = TRUE;
|
||||
break;
|
||||
|
||||
default : /* bad TPDU */
|
||||
return -1;
|
||||
} /* li */
|
||||
default : /* bad TPDU */
|
||||
return -1;
|
||||
} /* li */
|
||||
}else {
|
||||
|
||||
/* check packet length indicators of ATN Expedited Data (ED) TDPU */
|
||||
/* note: use of checksum depends on the selected RER */
|
||||
/* (high:non-use medium:16-bit OSI/16-bit ext.ATN low:32-bit ext. ATN) */
|
||||
/* note: sole use of TP4 class in the ATN */
|
||||
/* note: normal/extended TDPU numbering is negociable */
|
||||
switch (li) {
|
||||
case LI_NORMAL_DT_WITHOUT_CHECKSUM :
|
||||
tpdu_nr = tvb_get_guint8(tvb, offset + P_TPDU_NR_234);
|
||||
if ( tpdu_nr & 0x80 )
|
||||
tpdu_nr = tpdu_nr & 0x7F;
|
||||
else
|
||||
return -1;
|
||||
is_extended = FALSE;
|
||||
break;
|
||||
|
||||
case LI_NORMAL_DT_WITH_CHECKSUM :
|
||||
if ((tvb_get_guint8(tvb, offset + P_VAR_PART_NDT) != VP_CHECKSUM) &&
|
||||
(tvb_get_guint8(tvb, offset + P_VAR_PART_NDT) != VP_ATN_EC_16))
|
||||
return -1;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
tpdu_nr = tvb_get_guint8(tvb, offset + P_TPDU_NR_234);
|
||||
if ( tpdu_nr & 0x80 )
|
||||
tpdu_nr = tpdu_nr & 0x7F;
|
||||
else
|
||||
return -1;
|
||||
is_extended = FALSE;
|
||||
break;
|
||||
|
||||
case LI_ATN_NORMAL_DT_WITH_CHECKSUM :
|
||||
if ( tvb_get_guint8(tvb, offset + P_VAR_PART_NDT) != VP_ATN_EC_32 )
|
||||
return -1;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
tpdu_nr = tvb_get_guint8(tvb, offset + P_TPDU_NR_234);
|
||||
if ( tpdu_nr & 0x80 )
|
||||
tpdu_nr = tpdu_nr & 0x7F;
|
||||
else
|
||||
return -1;
|
||||
is_extended = FALSE;
|
||||
break;
|
||||
|
||||
case LI_EXTENDED_DT_WITHOUT_CHECKSUM :
|
||||
tpdu_nr = tvb_get_ntohl(tvb, offset + P_TPDU_NR_234);
|
||||
if ( tpdu_nr & 0x80000000 )
|
||||
tpdu_nr = tpdu_nr & 0x7FFFFFFF;
|
||||
else
|
||||
return -1;
|
||||
is_extended = TRUE;
|
||||
break;
|
||||
|
||||
case LI_EXTENDED_DT_WITH_CHECKSUM :
|
||||
if ( ( tvb_get_guint8(tvb, offset + P_VAR_PART_EDT) != VP_CHECKSUM ) &&
|
||||
( tvb_get_guint8(tvb, offset + P_VAR_PART_EDT) != VP_ATN_EC_16) )
|
||||
return -1;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
tpdu_nr = tvb_get_ntohl(tvb, offset + P_TPDU_NR_234);
|
||||
if ( tpdu_nr & 0x80000000 )
|
||||
tpdu_nr = tpdu_nr & 0x7FFFFFFF;
|
||||
else
|
||||
return -1;
|
||||
is_extended = TRUE;
|
||||
break;
|
||||
|
||||
case LI_ATN_EXTENDED_DT_WITH_CHECKSUM :
|
||||
if (tvb_get_guint8(tvb, offset + P_VAR_PART_EDT) != VP_ATN_EC_32)
|
||||
return -1;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
tpdu_nr = tvb_get_ntohl(tvb, offset + P_TPDU_NR_234);
|
||||
if ( tpdu_nr & 0x80000000 )
|
||||
tpdu_nr = tpdu_nr & 0x7FFFFFFF;
|
||||
else
|
||||
return -1;
|
||||
is_extended = TRUE;
|
||||
break;
|
||||
|
||||
default : /* bad TPDU */
|
||||
return -1;
|
||||
} /* li */
|
||||
|
||||
} /* cotp_decode_atn */
|
||||
|
||||
|
||||
dst_ref = tvb_get_ntohs(tvb, offset + P_DST_REF);
|
||||
pinfo->clnp_dstref = dst_ref;
|
||||
|
||||
|
@ -1115,18 +1421,43 @@ static int ositp_decode_RJ(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu,
|
|||
guint tpdu_nr;
|
||||
gushort credit = 0;
|
||||
|
||||
switch(li) {
|
||||
case LI_NORMAL_RJ :
|
||||
tpdu_nr = tvb_get_guint8(tvb, offset + P_TPDU_NR_234);
|
||||
break;
|
||||
case LI_EXTENDED_RJ :
|
||||
tpdu_nr = tvb_get_ntohl(tvb, offset + P_TPDU_NR_234);
|
||||
credit = tvb_get_ntohs(tvb, offset + P_CDT_IN_RJ);
|
||||
break;
|
||||
default :
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* note: in the ATN the user is up to chose between 3 different checksums: */
|
||||
/* standard OSI, 2 or 4 octet extended checksum. */
|
||||
/* The difference for RJ is that the TDPU header may be enlarged by 2 octets */
|
||||
/* for checksum parameters are not going to be checked here */
|
||||
if (!cotp_decode_atn) { /* non ATN, plain OSI*/
|
||||
switch(li) {
|
||||
case LI_NORMAL_RJ :
|
||||
tpdu_nr = tvb_get_guint8(tvb, offset + P_TPDU_NR_234);
|
||||
break;
|
||||
case LI_EXTENDED_RJ :
|
||||
tpdu_nr = tvb_get_ntohl(tvb, offset + P_TPDU_NR_234);
|
||||
credit = tvb_get_ntohs(tvb, offset + P_CDT_IN_RJ);
|
||||
break;
|
||||
default :
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
switch(li) {
|
||||
/* normal with 2 octets of OSI or ATN checksum */
|
||||
case LI_NORMAL_RJ :
|
||||
/* with 4 octets of ATN checksum */
|
||||
case LI_ATN_NORMAL_RJ :
|
||||
tpdu_nr = tvb_get_guint8(tvb, offset + P_TPDU_NR_234);
|
||||
break;
|
||||
/* extended with 2 octets of OSI or ATN checksum */
|
||||
case LI_EXTENDED_RJ :
|
||||
/* with 4 octets of ATN checksum */
|
||||
case LI_ATN_EXTENDED_RJ :
|
||||
tpdu_nr = tvb_get_ntohl(tvb, offset + P_TPDU_NR_234);
|
||||
credit = tvb_get_ntohs(tvb, offset + P_CDT_IN_RJ);
|
||||
break;
|
||||
default :
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dst_ref = tvb_get_ntohs(tvb, offset + P_DST_REF);
|
||||
pinfo->clnp_dstref = dst_ref;
|
||||
|
||||
|
@ -1168,7 +1499,10 @@ static int ositp_decode_CC(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu,
|
|||
gboolean uses_inactive_subset,
|
||||
gboolean *subdissector_found)
|
||||
{
|
||||
|
||||
/* note: in the ATN the user is up to chose between 3 different checksums: */
|
||||
/* standard OSI, 2 or 4 octet extended checksum. */
|
||||
/* Nothing has to be done here, for all ATN specifics are handled in VP. */
|
||||
|
||||
/* CC & CR decoding in the same function */
|
||||
|
||||
proto_tree *cotp_tree = NULL;
|
||||
|
@ -1264,9 +1598,15 @@ static int ositp_decode_DC(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu,
|
|||
proto_item *item = NULL;
|
||||
guint16 dst_ref, src_ref;
|
||||
|
||||
if (li > LI_MAX_DC)
|
||||
return -1;
|
||||
|
||||
/* ATN may use checksums different from OSI */
|
||||
/* which may result in different TPDU header length. */
|
||||
if ( !cotp_decode_atn) {
|
||||
if (li > LI_MAX_DC)
|
||||
return -1; }
|
||||
else {
|
||||
if (li > LI_ATN_MAX_DC)
|
||||
return -1; }
|
||||
|
||||
dst_ref = tvb_get_ntohs(tvb, offset + P_DST_REF);
|
||||
src_ref = tvb_get_ntohs(tvb, offset + P_SRC_REF);
|
||||
pinfo->clnp_dstref = dst_ref;
|
||||
|
@ -1321,9 +1661,15 @@ static int ositp_decode_AK(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu,
|
|||
guint tpdu_nr;
|
||||
gushort cdt_in_ak;
|
||||
|
||||
if (li > LI_MAX_AK)
|
||||
return -1;
|
||||
if (!cotp_decode_atn ){
|
||||
if (li > LI_MAX_AK)
|
||||
return -1;}
|
||||
else {
|
||||
if (li > LI_ATN_MAX_AK)
|
||||
return -1; }
|
||||
|
||||
/* is_LI_NORMAL_AK() works for normal ATN AK's, */
|
||||
/* for the TPDU header size may be enlarged by 2 octets */
|
||||
if (is_LI_NORMAL_AK(li)) {
|
||||
|
||||
dst_ref = tvb_get_ntohs(tvb, offset + P_DST_REF);
|
||||
|
@ -1426,41 +1772,134 @@ static int ositp_decode_EA(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu,
|
|||
gboolean is_extended;
|
||||
guint16 dst_ref;
|
||||
guint tpdu_nr;
|
||||
|
||||
/* Due to different checksums in the ATN the TDPU header sizes */
|
||||
/* as well as the checksum parameters may be different than plain OSI EA.*/
|
||||
/* because these are heavily checked for EA these checks had to be re-implemented. */
|
||||
/* note: this could not be tested, because no sample was avail for expedited data */
|
||||
if(!cotp_decode_atn) {
|
||||
|
||||
if (li > LI_MAX_EA)
|
||||
return -1;
|
||||
if (li > LI_MAX_EA)
|
||||
return -1;
|
||||
|
||||
/* VP_CHECKSUM is the only parameter allowed in the variable part.
|
||||
/* VP_CHECKSUM is the only parameter allowed in the variable part.
|
||||
(This means we may misdissect this if the packet is bad and
|
||||
contains other parameters.) */
|
||||
switch (li) {
|
||||
switch (li) {
|
||||
|
||||
case LI_NORMAL_EA_WITH_CHECKSUM :
|
||||
if (tvb_get_guint8(tvb, offset + P_VAR_PART_NDT) != VP_CHECKSUM ||
|
||||
tvb_get_guint8(tvb, offset + P_VAR_PART_NDT + 1) != 2)
|
||||
return -1;
|
||||
/* FALLTHROUGH */
|
||||
case LI_NORMAL_EA_WITH_CHECKSUM :
|
||||
if (tvb_get_guint8(tvb, offset + P_VAR_PART_NDT) != VP_CHECKSUM ||
|
||||
tvb_get_guint8(tvb, offset + P_VAR_PART_NDT + 1) != 2)
|
||||
return -1;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case LI_NORMAL_EA_WITHOUT_CHECKSUM :
|
||||
tpdu_nr = tvb_get_guint8(tvb, offset + P_TPDU_NR_234);
|
||||
is_extended = FALSE;
|
||||
break;
|
||||
case LI_NORMAL_EA_WITHOUT_CHECKSUM :
|
||||
tpdu_nr = tvb_get_guint8(tvb, offset + P_TPDU_NR_234);
|
||||
is_extended = FALSE;
|
||||
break;
|
||||
|
||||
case LI_EXTENDED_EA_WITH_CHECKSUM :
|
||||
if (tvb_get_guint8(tvb, offset + P_VAR_PART_EDT) != VP_CHECKSUM ||
|
||||
tvb_get_guint8(tvb, offset + P_VAR_PART_EDT + 1) != 2)
|
||||
return -1;
|
||||
/* FALLTHROUGH */
|
||||
case LI_EXTENDED_EA_WITH_CHECKSUM :
|
||||
if (tvb_get_guint8(tvb, offset + P_VAR_PART_EDT) != VP_CHECKSUM ||
|
||||
tvb_get_guint8(tvb, offset + P_VAR_PART_EDT + 1) != 2)
|
||||
return -1;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case LI_EXTENDED_EA_WITHOUT_CHECKSUM :
|
||||
tpdu_nr = tvb_get_ntohl(tvb, offset + P_TPDU_NR_234);
|
||||
is_extended = TRUE;
|
||||
break;
|
||||
case LI_EXTENDED_EA_WITHOUT_CHECKSUM :
|
||||
tpdu_nr = tvb_get_ntohl(tvb, offset + P_TPDU_NR_234);
|
||||
is_extended = TRUE;
|
||||
break;
|
||||
|
||||
default : /* bad TPDU */
|
||||
return -1;
|
||||
} /* li */
|
||||
default : /* bad TPDU */
|
||||
return -1;
|
||||
} /* li */
|
||||
}else { /* cotp_decode_atn */
|
||||
|
||||
/* check for ATN length: TDPU may be 2 octets longer due to checksum */
|
||||
if (li > LI_ATN_MAX_EA)
|
||||
return -1;
|
||||
|
||||
switch (li) {
|
||||
/* extended TDPU numbering EA with no checksum */
|
||||
case LI_NORMAL_EA_WITHOUT_CHECKSUM :
|
||||
tpdu_nr = tvb_get_guint8(tvb, offset + P_TPDU_NR_234);
|
||||
is_extended = FALSE;
|
||||
break;
|
||||
|
||||
/* normal TDPU numbering EA with 2 octets of OSI or ATN extended checksum */
|
||||
case LI_NORMAL_EA_WITH_CHECKSUM :
|
||||
/* check checksum parameter (in VP) parameter code octet */
|
||||
if ((tvb_get_guint8(tvb, offset + P_VAR_PART_NDT) != VP_CHECKSUM) &&
|
||||
(tvb_get_guint8(tvb, offset + P_VAR_PART_NDT) != VP_ATN_EC_16 ))
|
||||
return -1;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
/* check checksum parameter (in VP) length octet */
|
||||
if (tvb_get_guint8(tvb, offset + P_VAR_PART_NDT +1 ) != 2)
|
||||
return -1;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
tpdu_nr = tvb_get_guint8(tvb, offset + P_TPDU_NR_234);
|
||||
is_extended = FALSE;
|
||||
break;
|
||||
/* normal TDPU numbering EA with 4 octets of ATN extended checksum */
|
||||
case LI_ATN_NORMAL_EA_WITH_CHECKSUM :
|
||||
/* check checksum parameter (in VP) parameter code octet */
|
||||
if (tvb_get_guint8(tvb, offset + P_VAR_PART_NDT) != VP_ATN_EC_32 )
|
||||
return -1;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
/* check checksum parameter (in VP) length octet */
|
||||
if (tvb_get_guint8(tvb, offset + P_VAR_PART_NDT +1 ) != 4)
|
||||
return -1;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
tpdu_nr = tvb_get_guint8(tvb, offset + P_TPDU_NR_234);
|
||||
is_extended = FALSE;
|
||||
break;
|
||||
/* extended TDPU numbering EA with no checksum */
|
||||
case LI_EXTENDED_EA_WITHOUT_CHECKSUM :
|
||||
tpdu_nr = tvb_get_ntohl(tvb, offset + P_TPDU_NR_234);
|
||||
is_extended = TRUE;
|
||||
break;
|
||||
|
||||
/* extended TDPU numbering EA with 2 octets of OSI or ATN extended checksum */
|
||||
case LI_EXTENDED_EA_WITH_CHECKSUM :
|
||||
/* check checksum parameter (in VP) parameter code octet */
|
||||
if ( (tvb_get_guint8(tvb, offset + P_VAR_PART_EDT) != VP_CHECKSUM ) &&
|
||||
(tvb_get_guint8(tvb, offset + P_VAR_PART_EDT) != VP_ATN_EC_16))
|
||||
return -1;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
/* check checksum parameter (in VP) length octet */
|
||||
if (tvb_get_guint8(tvb, offset + P_VAR_PART_EDT +1 ) != 2 )
|
||||
return -1;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
tpdu_nr = tvb_get_ntohl(tvb, offset + P_TPDU_NR_234);
|
||||
is_extended = TRUE;
|
||||
break;
|
||||
|
||||
/* extended EA with 4 octets ATN extended checksum */
|
||||
case LI_ATN_EXTENDED_EA_WITH_CHECKSUM :
|
||||
/* check checksum parameter (in VP) parameter code octet */
|
||||
if ( tvb_get_guint8(tvb, offset + P_VAR_PART_EDT) != VP_ATN_EC_32 )
|
||||
return -1;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
/* check checksum parameter (in VP) length octet */
|
||||
if ( tvb_get_guint8(tvb, offset + P_VAR_PART_EDT +1 ) != 2 )
|
||||
return -1;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
tpdu_nr = tvb_get_ntohl(tvb, offset + P_TPDU_NR_234);
|
||||
is_extended = TRUE;
|
||||
break;
|
||||
|
||||
default : /* bad TPDU */
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
dst_ref = tvb_get_ntohs(tvb, offset + P_DST_REF);
|
||||
pinfo->clnp_dstref = dst_ref;
|
||||
|
||||
|
@ -1518,8 +1957,14 @@ static int ositp_decode_ER(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu,
|
|||
const char *str;
|
||||
guint16 dst_ref;
|
||||
|
||||
if (li > LI_MAX_ER)
|
||||
return -1;
|
||||
/* ATN: except for modified LI checking nothing to be done here */
|
||||
if(!cotp_decode_atn) {
|
||||
if (li > LI_MAX_ER)
|
||||
return -1;
|
||||
}else {
|
||||
if (li > LI_ATN_MAX_ER)
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch(tvb_get_guint8(tvb, offset + P_REJECT_ER)) {
|
||||
case 0 :
|
||||
|
@ -1826,7 +2271,7 @@ void proto_register_cotp(void)
|
|||
{ &hf_cotp_vp_dst_tsap_bytes,
|
||||
{ "Destination TSAP", "cotp.dst-tsap-bytes", FT_BYTES, BASE_NONE, NULL, 0x0,
|
||||
"Called TSAP (bytes representation)", HFILL }},
|
||||
|
||||
|
||||
};
|
||||
static gint *ett[] = {
|
||||
&ett_cotp,
|
||||
|
@ -1854,12 +2299,19 @@ void proto_register_cotp(void)
|
|||
tsap_display_options,
|
||||
FALSE);
|
||||
|
||||
prefs_register_bool_preference(cotp_module, "decode_atn",
|
||||
"Decode ATN TPDUs",
|
||||
"Whether to decode OSI TDPUs with ATN (Aereonautical Telecommunications Network) extensions."
|
||||
" To use this option, you must also enable \"Always try to decode NSDU as transport PDUs\" in the CLNP protocol settings.",
|
||||
&cotp_decode_atn);
|
||||
|
||||
|
||||
/* subdissector code in inactive subset */
|
||||
register_heur_dissector_list("cotp_is", &cotp_is_heur_subdissector_list);
|
||||
|
||||
/* other COTP/ISO 8473 subdissectors */
|
||||
register_heur_dissector_list("cotp", &cotp_heur_subdissector_list);
|
||||
|
||||
|
||||
/* XXX - what about CLTP and proto_cltp? */
|
||||
new_register_dissector("ositp", dissect_ositp, proto_cotp);
|
||||
new_register_dissector("ositp_inactive", dissect_ositp_inactive, proto_cotp);
|
||||
|
|
Loading…
Reference in New Issue