BPv7: Add Bundle Protocol version 7 and BPSec dissectors from dtn-wireshark
This commit is contained in:
parent
35d09a7854
commit
ce0592514c
|
@ -65,6 +65,24 @@ libwireshark.so.0 libwireshark0 #MINVER#
|
|||
bluetooth_uuid_vals@Base 1.99.2
|
||||
bluetooth_uuid_vals_ext@Base 1.99.2
|
||||
bluetooth_uuids@Base 2.1.0
|
||||
bp_block_canonical_new@Base 3.5.1rc0-3265-gb0c69d7db316
|
||||
bp_block_primary_free@Base 3.5.1rc0-3265-gb0c69d7db316
|
||||
bp_block_primary_new@Base 3.5.1rc0-3265-gb0c69d7db316
|
||||
bp_bundle_free@Base 3.5.1rc0-3265-gb0c69d7db316
|
||||
bp_bundle_ident_equal@Base 3.5.1rc0-3265-gb0c69d7db316
|
||||
bp_bundle_ident_free@Base 3.5.1rc0-3265-gb0c69d7db316
|
||||
bp_bundle_ident_hash@Base 3.5.1rc0-3265-gb0c69d7db316
|
||||
bp_bundle_ident_new@Base 3.5.1rc0-3265-gb0c69d7db316
|
||||
bp_bundle_new@Base 3.5.1rc0-3265-gb0c69d7db316
|
||||
bp_creation_ts_compare@Base 3.5.1rc0-3265-gb0c69d7db316
|
||||
bp_creation_ts_free@Base 3.5.1rc0-3265-gb0c69d7db316
|
||||
bp_eid_equal@Base 3.5.1rc0-3265-gb0c69d7db316
|
||||
bp_eid_free@Base 3.5.1rc0-3265-gb0c69d7db316
|
||||
bp_eid_new@Base 3.5.1rc0-3265-gb0c69d7db316
|
||||
bpsec_id_equal@Base 3.5.1rc0-3265-gb0c69d7db316
|
||||
bpsec_id_free@Base 3.5.1rc0-3265-gb0c69d7db316
|
||||
bpsec_id_hash@Base 3.5.1rc0-3265-gb0c69d7db316
|
||||
bpsec_id_new@Base 3.5.1rc0-3265-gb0c69d7db316
|
||||
bssgp_cause_vals_ext@Base 1.9.1
|
||||
bthci_cmd_authentication_enable_values@Base 2.1.2
|
||||
bthci_cmd_encrypt_mode_vals@Base 2.1.2
|
||||
|
@ -1226,6 +1244,7 @@ libwireshark.so.0 libwireshark0 #MINVER#
|
|||
proto_tree_add_cbor_bstr@Base 3.5.1
|
||||
proto_tree_add_cbor_container@Base 3.5.1
|
||||
proto_tree_add_cbor_ctrl@Base 3.5.1
|
||||
proto_tree_add_cbor_eid@Base 3.5.1rc0-3265-gb0c69d7db316
|
||||
proto_tree_add_cbor_int64@Base 3.5.1
|
||||
proto_tree_add_cbor_tstr@Base 3.5.1
|
||||
proto_tree_add_cbor_uint64@Base 3.5.1
|
||||
|
|
|
@ -120,6 +120,8 @@ Vector Informatik Binary Log File (BLF)
|
|||
[commaize]
|
||||
--
|
||||
Bluetooth Link Manager Protocol (BT LMP)
|
||||
Bundle Protocol version 7 (BPv7)
|
||||
Bundle Protocol version 7 Security (BPSec)
|
||||
CBOR Object Signing and Encryption (COSE)
|
||||
E2 Application Protocol (E2AP)
|
||||
Event Tracing for Windows (ETW)
|
||||
|
|
|
@ -252,6 +252,7 @@ set(DISSECTOR_PUBLIC_HEADERS
|
|||
packet-adb_service.h
|
||||
packet-afp.h
|
||||
packet-alcap.h
|
||||
packet-amp.h
|
||||
packet-ansi_a.h
|
||||
packet-ansi_map.h
|
||||
packet-ansi_tcap.h
|
||||
|
@ -267,6 +268,9 @@ set(DISSECTOR_PUBLIC_HEADERS
|
|||
packet-bgp.h
|
||||
packet-bicc_mst.h
|
||||
packet-bluetooth.h
|
||||
packet-bpv6.h
|
||||
packet-bpv7.h
|
||||
packet-bpsec.h
|
||||
packet-bssap.h
|
||||
packet-bssgp.h
|
||||
packet-btatt.h
|
||||
|
@ -330,7 +334,6 @@ set(DISSECTOR_PUBLIC_HEADERS
|
|||
packet-dop.h
|
||||
packet-dsp.h
|
||||
packet-dtls.h
|
||||
packet-dtn.h
|
||||
packet-dvbci.h
|
||||
packet-e1ap.h
|
||||
packet-enip.h
|
||||
|
@ -581,6 +584,7 @@ set(DISSECTOR_PUBLIC_HEADERS
|
|||
packet-tacacs.h
|
||||
packet-tcap.h
|
||||
packet-tcp.h
|
||||
packet-tcpclv3.h
|
||||
packet-tetra.h
|
||||
packet-thrift.h
|
||||
packet-tls-utils.h
|
||||
|
@ -694,6 +698,7 @@ set(DISSECTOR_SRC
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/packet-ansi_637.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-ansi_683.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-ansi_801.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-amp.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-ansi_a.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-aodv.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-aoe.c
|
||||
|
@ -764,6 +769,9 @@ set(DISSECTOR_SRC
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/packet-brcm-tag.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-brdwlk.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-brp.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-bpv6.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-bpv7.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-bpsec.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-bssap.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-bssgp.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-bt-dht.c
|
||||
|
@ -983,7 +991,6 @@ set(DISSECTOR_SRC
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/packet-dsr.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-dtcp-ip.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-dtls.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-dtn.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-dtp.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-dtpt.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-dua.c
|
||||
|
@ -1831,6 +1838,7 @@ set(DISSECTOR_SRC
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/packet-tapa.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-tcg-cp-oids.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-tcp.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-tcpclv3.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-tcpros.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-tdmoe.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-tdmop.c
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include <epan/exceptions.h>
|
||||
#include <epan/packet.h>
|
||||
#include "packet-amp.h"
|
||||
|
||||
/* The AMP standard can be found here:
|
||||
* https://tools.ietf.org/html/draft-birrane-dtn-amp-04
|
||||
|
@ -25,8 +26,6 @@
|
|||
data-payload as AMP. Later in the future, when a dedicated field is given to
|
||||
this, this should be filled. */
|
||||
|
||||
void dissect_amp_as_subtree(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
|
||||
|
||||
/*
|
||||
*/
|
||||
static void
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/* packet-amp.h
|
||||
* Routines for Asynchronous management Protocol dissection
|
||||
* Copyright 2018, Krishnamurthy Mayya (krishnamurthymayya@gmail.com)
|
||||
* Updated to CBOR encoding: Keith Scott, 2019 (kscott@mitre.org)
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef PACKET_AMP_H
|
||||
#define PACKET_AMP_H
|
||||
|
||||
#include <ws_symbol_export.h>
|
||||
#include <epan/tvbuff.h>
|
||||
#include <epan/proto.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void dissect_amp_as_subtree(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PACKET_AMP_H */
|
||||
|
||||
/*
|
||||
* Editor modelines - https://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
* Local variables:
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* vi: set shiftwidth=4 tabstop=8 expandtab:
|
||||
* :indentSize=4:tabSize=8:noTabs=true:
|
||||
*/
|
|
@ -0,0 +1,576 @@
|
|||
/* packet-sec.c
|
||||
* Routines for Bundle Protocol Version 7 Security (BPSec) dissection
|
||||
* References:
|
||||
* BPSec: https://datatracker.ietf.org/doc/html/draft-ietf-dtn-bpsec-27
|
||||
*
|
||||
* Copyright 2019-2021, Brian Sipos <brian.sipos@gmail.com>
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
#include "packet-bpsec.h"
|
||||
#include "packet-bpv7.h"
|
||||
#include <epan/packet.h>
|
||||
#include <epan/prefs.h>
|
||||
#include <epan/proto.h>
|
||||
#include <epan/expert.h>
|
||||
#include <epan/to_str.h>
|
||||
#include <wsutil/crc16.h>
|
||||
#include <wsutil/crc32.h>
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include "epan/wscbor.h"
|
||||
|
||||
/// Glib logging "domain" name
|
||||
//static const char *LOG_DOMAIN = "bpsec";
|
||||
|
||||
/// Protocol handles
|
||||
static int proto_bpsec = -1;
|
||||
|
||||
/// Dissect opaque CBOR data
|
||||
static dissector_handle_t handle_cbor = NULL;
|
||||
/// Extension sub-dissectors
|
||||
static dissector_table_t param_dissectors = NULL;
|
||||
static dissector_table_t result_dissectors = NULL;
|
||||
|
||||
static const val64_string shavar_vals[] = {
|
||||
{5, "HMAC 256/256"},
|
||||
{6, "HMAC 384/384"},
|
||||
{7, "HMAC 512/512"},
|
||||
{0, NULL},
|
||||
};
|
||||
|
||||
static const val64_string aesvar_vals[] = {
|
||||
{1, "A128GCM"},
|
||||
{3, "A256GCM"},
|
||||
{0, NULL},
|
||||
};
|
||||
|
||||
static int hf_bib = -1;
|
||||
static int hf_bcb = -1;
|
||||
static int hf_asb_target_list = -1;
|
||||
static int hf_asb_target = -1;
|
||||
static int hf_asb_ctxid = -1;
|
||||
static int hf_asb_flags = -1;
|
||||
static int hf_asb_flags_has_params = -1;
|
||||
static int hf_asb_secsrc_nodeid = -1;
|
||||
static int hf_asb_secsrc_uri = -1;
|
||||
static int hf_asb_param_list = -1;
|
||||
static int hf_asb_param_pair = -1;
|
||||
static int hf_asb_param_id = -1;
|
||||
static int hf_asb_result_all_list = -1;
|
||||
static int hf_asb_result_tgt_list = -1;
|
||||
static int hf_asb_result_tgt_ref = -1;
|
||||
static int hf_asb_result_pair = -1;
|
||||
static int hf_asb_result_id = -1;
|
||||
|
||||
static int hf_defaultsc_shavar = -1;
|
||||
static int hf_defaultsc_wrapedkey = -1;
|
||||
static int hf_defaultsc_scope = -1;
|
||||
static int hf_defaultsc_scope_pri_block = -1;
|
||||
static int hf_defaultsc_scope_tgt_head = -1;
|
||||
static int hf_defaultsc_scope_sec_head = -1;
|
||||
static int hf_defaultsc_hmac = -1;
|
||||
static int hf_defaultsc_iv = -1;
|
||||
static int hf_defaultsc_aesvar = -1;
|
||||
static int hf_defaultsc_authtag = -1;
|
||||
|
||||
/// Field definitions
|
||||
static hf_register_info fields[] = {
|
||||
{&hf_bib, {"BPSec Block Integrity Block", "bpsec.bib", FT_PROTOCOL, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
||||
{&hf_bcb, {"BPSec Block Confidentiality Block", "bpsec.bcb", FT_PROTOCOL, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
||||
{&hf_asb_target_list, {"Security Targets, Count", "bpsec.asb.target_count", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL}},
|
||||
{&hf_asb_target, {"Target Block Number", "bpsec.asb.target", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL}},
|
||||
{&hf_asb_ctxid, {"Context ID", "bpsec.asb.ctxid", FT_INT64, BASE_DEC, NULL, 0x0, NULL, HFILL}},
|
||||
{&hf_asb_flags, {"Flags", "bpsec.asb.flags", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL}},
|
||||
{&hf_asb_flags_has_params, {"Parameters Present", "bpsec.asb.flags.has_params", FT_BOOLEAN, 8, TFS(&tfs_set_notset), BPSEC_ASB_HAS_PARAMS, NULL, HFILL}},
|
||||
{&hf_asb_secsrc_nodeid, {"Security Source", "bpsec.asb.secsrc.nodeid", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
||||
{&hf_asb_secsrc_uri, {"Security Source URI", "bpsec.asb.secsrc.uri", FT_STRING, STR_UNICODE, NULL, 0x0, NULL, HFILL}},
|
||||
{&hf_asb_param_list, {"Security Parameters, Count", "bpsec.asb.param_count", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL}},
|
||||
{&hf_asb_param_pair, {"Parameter", "bpsec.asb.param", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
||||
{&hf_asb_param_id, {"Type ID", "bpsec.asb.param.id", FT_INT64, BASE_DEC, NULL, 0x0, NULL, HFILL}},
|
||||
{&hf_asb_result_all_list, {"Security Result Targets, Count", "bpsec.asb.result_count", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL}},
|
||||
{&hf_asb_result_tgt_ref, {"Associated Target Block Number", "bpsec.asb.result_tgt_ref", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL}},
|
||||
{&hf_asb_result_tgt_list, {"Security Results, Count", "bpsec.asb.result_count", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL}},
|
||||
{&hf_asb_result_pair, {"Result", "bpsec.asb.result", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
||||
{&hf_asb_result_id, {"Type ID", "bpsec.asb.result.id", FT_INT64, BASE_DEC, NULL, 0x0, NULL, HFILL}},
|
||||
|
||||
{&hf_defaultsc_shavar, {"SHA Variant", "bpsec.defaultsc.shavar", FT_UINT64, BASE_DEC | BASE_VAL64_STRING, VALS64(shavar_vals), 0x0, NULL, HFILL}},
|
||||
{&hf_defaultsc_wrapedkey, {"Wrapped Key", "bpsec.defaultsc.wrappedkey", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
||||
{&hf_defaultsc_scope, {"BIB Scope", "bpsec.defaultsc.scope", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL}},
|
||||
{&hf_defaultsc_scope_pri_block, {"Primary Block", "bpsec.defaultsc.scope.pri_block", FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x0001, NULL, HFILL}},
|
||||
{&hf_defaultsc_scope_tgt_head, {"Target Header", "bpsec.defaultsc.scope.tgt_head", FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x0002, NULL, HFILL}},
|
||||
{&hf_defaultsc_scope_sec_head, {"Security Header", "bpsec.defaultsc.scope.sec_head", FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x0004, NULL, HFILL}},
|
||||
{&hf_defaultsc_hmac, {"Expected HMAC", "bpsec.defaultsc.hmac", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
||||
{&hf_defaultsc_iv, {"IV", "bpsec.defaultsc.iv", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
||||
{&hf_defaultsc_aesvar, {"AES Variant", "bpsec.defaultsc.aesvar", FT_UINT64, BASE_DEC | BASE_VAL64_STRING, VALS64(aesvar_vals), 0x0, NULL, HFILL}},
|
||||
{&hf_defaultsc_authtag, {"Authentication Tag", "bpsec.defaultsc.authtag", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
||||
};
|
||||
|
||||
static int *const asb_flags[] = {
|
||||
&hf_asb_flags_has_params,
|
||||
NULL
|
||||
};
|
||||
|
||||
static int *const defaultsc_scope[] = {
|
||||
&hf_defaultsc_scope_pri_block,
|
||||
&hf_defaultsc_scope_tgt_head,
|
||||
&hf_defaultsc_scope_sec_head,
|
||||
NULL
|
||||
};
|
||||
|
||||
static int ett_asb = -1;
|
||||
static int ett_asb_flags = -1;
|
||||
static int ett_tgt_list = -1;
|
||||
static int ett_param_list = -1;
|
||||
static int ett_param_pair = -1;
|
||||
static int ett_result_all_list = -1;
|
||||
static int ett_result_tgt_list = -1;
|
||||
static int ett_result_pair = -1;
|
||||
static int ett_defaultsc_scope = -1;
|
||||
/// Tree structures
|
||||
static int *ett[] = {
|
||||
&ett_asb,
|
||||
&ett_asb_flags,
|
||||
&ett_tgt_list,
|
||||
&ett_param_list,
|
||||
&ett_param_pair,
|
||||
&ett_result_all_list,
|
||||
&ett_result_tgt_list,
|
||||
&ett_result_pair,
|
||||
&ett_defaultsc_scope,
|
||||
};
|
||||
|
||||
static expert_field ei_secsrc_diff = EI_INIT;
|
||||
static expert_field ei_ctxid_zero = EI_INIT;
|
||||
static expert_field ei_ctxid_priv = EI_INIT;
|
||||
static expert_field ei_target_invalid = EI_INIT;
|
||||
static expert_field ei_value_partial_decode = EI_INIT;
|
||||
static ei_register_info expertitems[] = {
|
||||
{&ei_secsrc_diff, {"bpsec.secsrc_diff", PI_SECURITY, PI_CHAT, "BPSec Security Source different from bundle Source", EXPFILL}},
|
||||
{&ei_ctxid_zero, {"bpsec.ctxid_zero", PI_SECURITY, PI_WARN, "BPSec Security Context ID zero is reserved", EXPFILL}},
|
||||
{&ei_ctxid_priv, {"bpsec.ctxid_priv", PI_SECURITY, PI_NOTE, "BPSec Security Context ID from private/experimental block", EXPFILL}},
|
||||
{&ei_target_invalid, {"bpsec.target_invalid", PI_PROTOCOL, PI_WARN, "Target block number not present", EXPFILL}},
|
||||
{&ei_value_partial_decode, {"bpsec.value_partial_decode", PI_UNDECODED, PI_WARN, "Value data not fully dissected", EXPFILL}},
|
||||
};
|
||||
|
||||
bpsec_id_t * bpsec_id_new(wmem_allocator_t *alloc, gint64 context_id, gint64 type_id) {
|
||||
bpsec_id_t *obj;
|
||||
if (alloc) {
|
||||
obj = wmem_new(alloc, bpsec_id_t);
|
||||
}
|
||||
else {
|
||||
obj = g_new(bpsec_id_t, 1);
|
||||
}
|
||||
obj->context_id = context_id;
|
||||
obj->type_id = type_id;
|
||||
return obj;
|
||||
}
|
||||
|
||||
void bpsec_id_free(wmem_allocator_t *alloc, gpointer ptr) {
|
||||
//bpsec_id_t *obj = (bpsec_id_t *)ptr;
|
||||
wmem_free(alloc, ptr);
|
||||
}
|
||||
|
||||
gboolean bpsec_id_equal(gconstpointer a, gconstpointer b) {
|
||||
const bpsec_id_t *aobj = a;
|
||||
const bpsec_id_t *bobj = b;
|
||||
return (
|
||||
aobj && bobj
|
||||
&& (aobj->context_id == bobj->context_id)
|
||||
&& (aobj->type_id == bobj->type_id)
|
||||
);
|
||||
}
|
||||
|
||||
guint bpsec_id_hash(gconstpointer key) {
|
||||
const bpsec_id_t *obj = key;
|
||||
return (
|
||||
g_int64_hash(&(obj->context_id))
|
||||
^ g_int64_hash(&(obj->type_id))
|
||||
);
|
||||
}
|
||||
|
||||
/** Dissect an ID-value pair within a context.
|
||||
*
|
||||
* @param dissector
|
||||
* @param typeid
|
||||
* @param tvb
|
||||
* @param pinfo
|
||||
* @param tree
|
||||
*/
|
||||
static gint dissect_value(dissector_handle_t dissector, gint64 *typeid, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
|
||||
gint sublen = 0;
|
||||
if (dissector) {
|
||||
sublen = call_dissector_with_data(dissector, tvb, pinfo, tree, typeid);
|
||||
if ((sublen < 0) || ((guint)sublen < tvb_captured_length(tvb))) {
|
||||
expert_add_info(pinfo, proto_tree_get_parent(tree), &ei_value_partial_decode);
|
||||
}
|
||||
}
|
||||
if (sublen == 0) {
|
||||
sublen = call_dissector(handle_cbor, tvb, pinfo, tree);
|
||||
}
|
||||
return sublen;
|
||||
}
|
||||
|
||||
/** Dissector for abstract security block structure.
|
||||
*/
|
||||
static int dissect_block_asb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, const bp_dissector_data_t *const data, int root_hfindex) {
|
||||
proto_item *item_asb = proto_tree_add_item(tree, root_hfindex, tvb, 0, -1, ENC_NA);
|
||||
proto_tree *tree_asb = proto_item_add_subtree(item_asb, ett_asb);
|
||||
gint offset = 0;
|
||||
|
||||
wmem_array_t *targets;
|
||||
targets = wmem_array_new(wmem_packet_scope(), sizeof(guint64));
|
||||
|
||||
wscbor_chunk_t *chunk_tgt_list = wscbor_chunk_read(wmem_packet_scope(), tvb, &offset);
|
||||
wscbor_require_array(chunk_tgt_list);
|
||||
proto_item *item_tgt_list = proto_tree_add_cbor_container(tree_asb, hf_asb_target_list, pinfo, tvb, chunk_tgt_list);
|
||||
if (!wscbor_skip_if_errors(wmem_packet_scope(), tvb, &offset, chunk_tgt_list)) {
|
||||
proto_tree *tree_tgt_list = proto_item_add_subtree(item_tgt_list, ett_tgt_list);
|
||||
|
||||
wscbor_chunk_t *chunk_tgt = wscbor_chunk_read(wmem_packet_scope(), tvb, &offset);
|
||||
guint64 *tgt_blknum = wscbor_require_uint64(wmem_packet_scope(), chunk_tgt);
|
||||
proto_item *item_tgt = proto_tree_add_cbor_uint64(tree_tgt_list, hf_asb_target, pinfo, tvb, chunk_tgt, tgt_blknum);
|
||||
if (tgt_blknum) {
|
||||
wmem_array_append(targets, tgt_blknum, 1);
|
||||
|
||||
wmem_map_t *map = NULL;
|
||||
if (*tgt_blknum == 0) {
|
||||
map = (root_hfindex == hf_bib)
|
||||
? data->bundle->primary->sec.data_i
|
||||
: data->bundle->primary->sec.data_c;
|
||||
}
|
||||
else {
|
||||
bp_block_canonical_t *found = wmem_map_lookup(data->bundle->block_nums, tgt_blknum);
|
||||
if (found) {
|
||||
map = (root_hfindex == hf_bib)
|
||||
? found->sec.data_i
|
||||
: found->sec.data_c;
|
||||
}
|
||||
else {
|
||||
expert_add_info(pinfo, item_tgt, &ei_target_invalid);
|
||||
}
|
||||
}
|
||||
if (map) {
|
||||
wmem_map_insert(
|
||||
map,
|
||||
data->block->block_number,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
proto_item_set_len(item_tgt_list, offset - chunk_tgt_list->start);
|
||||
}
|
||||
|
||||
wscbor_chunk_t *chunk_ctxid = wscbor_chunk_read(wmem_packet_scope(), tvb, &offset);
|
||||
gint64 *ctxid = wscbor_require_int64(wmem_packet_scope(), chunk_ctxid);
|
||||
proto_item *item_ctxid = proto_tree_add_cbor_int64(tree_asb, hf_asb_ctxid, pinfo, tvb, chunk_ctxid, ctxid);
|
||||
if (ctxid) {
|
||||
if (*ctxid == 0) {
|
||||
expert_add_info(pinfo, item_ctxid, &ei_ctxid_zero);
|
||||
}
|
||||
else if (*ctxid < 0) {
|
||||
expert_add_info(pinfo, item_ctxid, &ei_ctxid_priv);
|
||||
}
|
||||
}
|
||||
|
||||
wscbor_chunk_t *chunk_flags = wscbor_chunk_read(wmem_packet_scope(), tvb, &offset);
|
||||
guint64 *flags = wscbor_require_uint64(wmem_packet_scope(), chunk_flags);
|
||||
proto_tree_add_cbor_bitmask(tree_asb, hf_asb_flags, ett_asb_flags, asb_flags, pinfo, tvb, chunk_flags, flags);
|
||||
|
||||
{
|
||||
bp_eid_t *secsrc = bp_eid_new(wmem_packet_scope());
|
||||
proto_item *item_secsrc = proto_tree_add_cbor_eid(tree_asb, hf_asb_secsrc_nodeid, hf_asb_secsrc_uri, pinfo, tvb, &offset, secsrc);
|
||||
if (!bp_eid_equal(data->bundle->primary->src_nodeid, secsrc)) {
|
||||
expert_add_info(pinfo, item_secsrc, &ei_secsrc_diff);
|
||||
}
|
||||
}
|
||||
|
||||
if (flags && (*flags & BPSEC_ASB_HAS_PARAMS)) {
|
||||
wscbor_chunk_t *chunk_param_list = wscbor_chunk_read(wmem_packet_scope(), tvb, &offset);
|
||||
wscbor_require_array(chunk_param_list);
|
||||
proto_item *item_param_list = proto_tree_add_cbor_container(tree_asb, hf_asb_param_list, pinfo, tvb, chunk_param_list);
|
||||
if (!wscbor_skip_if_errors(wmem_packet_scope(), tvb, &offset, chunk_param_list)) {
|
||||
proto_tree *tree_param_list = proto_item_add_subtree(item_param_list, ett_param_list);
|
||||
|
||||
// iterate all parameters
|
||||
for (guint64 param_ix = 0; param_ix < chunk_param_list->head_value; ++param_ix) {
|
||||
wscbor_chunk_t *chunk_param_pair = wscbor_chunk_read(wmem_packet_scope(), tvb, &offset);
|
||||
wscbor_require_array_size(chunk_param_pair, 2, 2);
|
||||
proto_item *item_param_pair = proto_tree_add_cbor_container(tree_param_list, hf_asb_param_pair, pinfo, tvb, chunk_param_pair);
|
||||
if (!wscbor_skip_if_errors(wmem_packet_scope(), tvb, &offset, chunk_param_pair)) {
|
||||
proto_tree *tree_param_pair = proto_item_add_subtree(item_param_pair, ett_param_pair);
|
||||
|
||||
wscbor_chunk_t *chunk_paramid = wscbor_chunk_read(wmem_packet_scope(), tvb, &offset);
|
||||
gint64 *paramid = wscbor_require_int64(wmem_packet_scope(), chunk_paramid);
|
||||
proto_tree_add_cbor_int64(tree_param_pair, hf_asb_param_id, pinfo, tvb, chunk_paramid, paramid);
|
||||
if (paramid) {
|
||||
proto_item_append_text(item_param_pair, ", ID: %" PRIi64, *paramid);
|
||||
}
|
||||
|
||||
const gint offset_value = offset;
|
||||
wscbor_skip_next_item(wmem_packet_scope(), tvb, &offset);
|
||||
tvbuff_t *tvb_value = tvb_new_subset_length(tvb, offset_value, offset - offset_value);
|
||||
|
||||
dissector_handle_t value_dissect = NULL;
|
||||
if (ctxid && paramid) {
|
||||
bpsec_id_t *key = bpsec_id_new(wmem_packet_scope(), *ctxid, *paramid);
|
||||
value_dissect = dissector_get_custom_table_handle(param_dissectors, key);
|
||||
bpsec_id_free(wmem_packet_scope(), key);
|
||||
}
|
||||
dissect_value(value_dissect, paramid, tvb_value, pinfo, tree_param_pair);
|
||||
|
||||
proto_item_set_len(item_param_pair, offset - chunk_param_pair->start);
|
||||
}
|
||||
}
|
||||
|
||||
proto_item_set_len(item_param_list, offset - chunk_param_list->start);
|
||||
}
|
||||
}
|
||||
|
||||
// array sizes should agree
|
||||
const guint tgt_size = wmem_array_get_count(targets);
|
||||
|
||||
wscbor_chunk_t *chunk_result_all_list = wscbor_chunk_read(wmem_packet_scope(), tvb, &offset);
|
||||
wscbor_require_array_size(chunk_result_all_list, tgt_size, tgt_size);
|
||||
proto_item *item_result_all_list = proto_tree_add_cbor_container(tree_asb, hf_asb_result_all_list, pinfo, tvb, chunk_result_all_list);
|
||||
if (!wscbor_skip_if_errors(wmem_packet_scope(), tvb, &offset, chunk_result_all_list)) {
|
||||
proto_tree *tree_result_all_list = proto_item_add_subtree(item_result_all_list, ett_result_all_list);
|
||||
|
||||
// iterate each target's results
|
||||
for (guint tgt_ix = 0; tgt_ix < tgt_size; ++tgt_ix) {
|
||||
wscbor_chunk_t *chunk_result_tgt_list = wscbor_chunk_read(wmem_packet_scope(), tvb, &offset);
|
||||
wscbor_require_array(chunk_result_tgt_list);
|
||||
proto_item *item_result_tgt_list = proto_tree_add_cbor_container(tree_result_all_list, hf_asb_result_tgt_list, pinfo, tvb, chunk_result_tgt_list);
|
||||
if (!wscbor_skip_if_errors(wmem_packet_scope(), tvb, &offset, chunk_result_tgt_list)) {
|
||||
proto_tree *tree_result_tgt_list = proto_item_add_subtree(item_result_tgt_list, ett_result_tgt_list);
|
||||
|
||||
// Hint at the associated target number
|
||||
if (tgt_ix < tgt_size) {
|
||||
const guint64 *tgt_blknum = wmem_array_index(targets, tgt_ix);
|
||||
proto_item *item_tgt_blknum = proto_tree_add_uint64(tree_result_tgt_list, hf_asb_result_tgt_ref, tvb, 0, 0, *tgt_blknum);
|
||||
PROTO_ITEM_SET_GENERATED(item_tgt_blknum);
|
||||
}
|
||||
|
||||
// iterate all results for this target
|
||||
for (guint64 result_ix = 0; result_ix < chunk_result_tgt_list->head_value; ++result_ix) {
|
||||
wscbor_chunk_t *chunk_result_pair = wscbor_chunk_read(wmem_packet_scope(), tvb, &offset);
|
||||
wscbor_require_array_size(chunk_result_pair, 2, 2);
|
||||
proto_item *item_result_pair = proto_tree_add_cbor_container(tree_result_tgt_list, hf_asb_result_pair, pinfo, tvb, chunk_result_pair);
|
||||
if (!wscbor_skip_if_errors(wmem_packet_scope(), tvb, &offset, chunk_result_pair)) {
|
||||
proto_tree *tree_result_pair = proto_item_add_subtree(item_result_pair, ett_result_pair);
|
||||
|
||||
wscbor_chunk_t *chunk_resultid = wscbor_chunk_read(wmem_packet_scope(), tvb, &offset);
|
||||
gint64 *resultid = wscbor_require_int64(wmem_packet_scope(), chunk_resultid);
|
||||
proto_tree_add_cbor_int64(tree_result_pair, hf_asb_result_id, pinfo, tvb, chunk_resultid, resultid);
|
||||
if (resultid) {
|
||||
proto_item_append_text(item_result_pair, ", ID: %" PRIi64, *resultid);
|
||||
}
|
||||
|
||||
const gint offset_value = offset;
|
||||
wscbor_skip_next_item(wmem_packet_scope(), tvb, &offset);
|
||||
tvbuff_t *tvb_value = tvb_new_subset_length(tvb, offset_value, offset - offset_value);
|
||||
|
||||
dissector_handle_t value_dissect = NULL;
|
||||
if (ctxid && resultid) {
|
||||
bpsec_id_t *key = bpsec_id_new(wmem_packet_scope(), *ctxid, *resultid);
|
||||
value_dissect = dissector_get_custom_table_handle(result_dissectors, key);
|
||||
bpsec_id_free(wmem_packet_scope(), key);
|
||||
}
|
||||
dissect_value(value_dissect, resultid, tvb_value, pinfo, tree_result_pair);
|
||||
|
||||
proto_item_set_len(item_result_pair, offset - chunk_result_pair->start);
|
||||
}
|
||||
}
|
||||
|
||||
proto_item_set_len(item_result_tgt_list, offset - chunk_result_tgt_list->start);
|
||||
}
|
||||
}
|
||||
|
||||
proto_item_set_len(item_result_all_list, offset - chunk_result_all_list->start);
|
||||
}
|
||||
|
||||
proto_item_set_len(item_asb, offset);
|
||||
return offset;
|
||||
}
|
||||
|
||||
/** Dissector for Bundle Integrity block.
|
||||
*/
|
||||
static int dissect_block_bib(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) {
|
||||
return dissect_block_asb(tvb, pinfo, tree, (bp_dissector_data_t *)data, hf_bib);
|
||||
}
|
||||
|
||||
/** Dissector for Bundle Confidentiality block.
|
||||
*/
|
||||
static int dissect_block_bcb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) {
|
||||
return dissect_block_asb(tvb, pinfo, tree, (bp_dissector_data_t *)data, hf_bcb);
|
||||
}
|
||||
|
||||
static int dissect_defaultsc_param_shavar(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
|
||||
gint offset = 0;
|
||||
wscbor_chunk_t *chunk = wscbor_chunk_read(wmem_packet_scope(), tvb, &offset);
|
||||
guint64 *val = wscbor_require_uint64(wmem_packet_scope(), chunk);
|
||||
proto_tree_add_cbor_uint64(tree, hf_defaultsc_shavar, pinfo, tvb, chunk, val);
|
||||
return offset;
|
||||
}
|
||||
|
||||
static int dissect_defaultsc_param_wrappedkey(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
|
||||
gint offset = 0;
|
||||
wscbor_chunk_t *chunk = wscbor_chunk_read(wmem_packet_scope(), tvb, &offset);
|
||||
wscbor_require_bstr(wmem_packet_scope(), chunk);
|
||||
proto_tree_add_cbor_bstr(tree, hf_defaultsc_wrapedkey, pinfo, tvb, chunk);
|
||||
return offset;
|
||||
}
|
||||
|
||||
static int dissect_defaultsc_param_scope(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
|
||||
gint offset = 0;
|
||||
wscbor_chunk_t *chunk = wscbor_chunk_read(wmem_packet_scope(), tvb, &offset);
|
||||
guint64 *flags = wscbor_require_uint64(wmem_packet_scope(), chunk);
|
||||
proto_tree_add_cbor_bitmask(tree, hf_defaultsc_scope, ett_defaultsc_scope, defaultsc_scope, pinfo, tvb, chunk, flags);
|
||||
return offset;
|
||||
}
|
||||
|
||||
static int dissect_defaultsc_result_hmac(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
|
||||
gint offset = 0;
|
||||
wscbor_chunk_t *chunk = wscbor_chunk_read(wmem_packet_scope(), tvb, &offset);
|
||||
wscbor_require_bstr(wmem_packet_scope(), chunk);
|
||||
proto_tree_add_cbor_bstr(tree, hf_defaultsc_hmac, pinfo, tvb, chunk);
|
||||
return offset;
|
||||
}
|
||||
|
||||
static int dissect_defaultsc_param_iv(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
|
||||
gint offset = 0;
|
||||
wscbor_chunk_t *chunk = wscbor_chunk_read(wmem_packet_scope(), tvb, &offset);
|
||||
wscbor_require_bstr(wmem_packet_scope(), chunk);
|
||||
proto_tree_add_cbor_bstr(tree, hf_defaultsc_iv, pinfo, tvb, chunk);
|
||||
return offset;
|
||||
}
|
||||
|
||||
static int dissect_defaultsc_param_aesvar(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
|
||||
gint offset = 0;
|
||||
wscbor_chunk_t *chunk = wscbor_chunk_read(wmem_packet_scope(), tvb, &offset);
|
||||
guint64 *val = wscbor_require_uint64(wmem_packet_scope(), chunk);
|
||||
proto_tree_add_cbor_uint64(tree, hf_defaultsc_aesvar, pinfo, tvb, chunk, val);
|
||||
return offset;
|
||||
}
|
||||
|
||||
static int dissect_defaultsc_result_authtag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
|
||||
gint offset = 0;
|
||||
wscbor_chunk_t *chunk = wscbor_chunk_read(wmem_packet_scope(), tvb, &offset);
|
||||
wscbor_require_bstr(wmem_packet_scope(), chunk);
|
||||
proto_tree_add_cbor_bstr(tree, hf_defaultsc_authtag, pinfo, tvb, chunk);
|
||||
return offset;
|
||||
}
|
||||
|
||||
/// Re-initialize after a configuration change
|
||||
static void reinit_bpsec(void) {
|
||||
}
|
||||
|
||||
/// Overall registration of the protocol
|
||||
void proto_register_bpsec(void) {
|
||||
proto_bpsec = proto_register_protocol(
|
||||
"DTN Bundle Protocol Security", /* name */
|
||||
"BPSec", /* short name */
|
||||
"bpsec" /* abbrev */
|
||||
);
|
||||
|
||||
proto_register_field_array(proto_bpsec, fields, array_length(fields));
|
||||
proto_register_subtree_array(ett, array_length(ett));
|
||||
expert_module_t *expert = expert_register_protocol(proto_bpsec);
|
||||
expert_register_field_array(expert, expertitems, array_length(expertitems));
|
||||
|
||||
param_dissectors = register_custom_dissector_table("bpsec.param", "BPSec Parameter", proto_bpsec, bpsec_id_hash, bpsec_id_equal);
|
||||
result_dissectors = register_custom_dissector_table("bpsec.result", "BPSec Result", proto_bpsec, bpsec_id_hash, bpsec_id_equal);
|
||||
|
||||
prefs_register_protocol(proto_bpsec, reinit_bpsec);
|
||||
}
|
||||
|
||||
void proto_reg_handoff_bpsec(void) {
|
||||
handle_cbor = find_dissector("cbor");
|
||||
|
||||
/* Packaged extensions */
|
||||
{
|
||||
guint64 *key = g_new(guint64, 1);
|
||||
*key = 11;
|
||||
dissector_handle_t hdl = create_dissector_handle(dissect_block_bib, proto_bpsec);
|
||||
dissector_add_custom_table_handle("bpv7.block_type", key, hdl);
|
||||
}
|
||||
{
|
||||
guint64 *key = g_new(guint64, 1);
|
||||
*key = 12;
|
||||
dissector_handle_t hdl = create_dissector_handle(dissect_block_bcb, proto_bpsec);
|
||||
dissector_add_custom_table_handle("bpv7.block_type", key, hdl);
|
||||
}
|
||||
|
||||
// Context 1: BIB-HMAC-SHA2
|
||||
{
|
||||
bpsec_id_t *key = g_new(bpsec_id_t, 1);
|
||||
key->context_id = 1;
|
||||
key->type_id = 1;
|
||||
dissector_handle_t hdl = create_dissector_handle(dissect_defaultsc_param_shavar, proto_bpsec);
|
||||
dissector_add_custom_table_handle("bpsec.param", key, hdl);
|
||||
}
|
||||
{
|
||||
bpsec_id_t *key = g_new(bpsec_id_t, 1);
|
||||
key->context_id = 1;
|
||||
key->type_id = 2;
|
||||
dissector_handle_t hdl = create_dissector_handle(dissect_defaultsc_param_wrappedkey, proto_bpsec);
|
||||
dissector_add_custom_table_handle("bpsec.param", key, hdl);
|
||||
}
|
||||
{
|
||||
bpsec_id_t *key = g_new(bpsec_id_t, 1);
|
||||
key->context_id = 1;
|
||||
key->type_id = 3;
|
||||
dissector_handle_t hdl = create_dissector_handle(dissect_defaultsc_param_scope, proto_bpsec);
|
||||
dissector_add_custom_table_handle("bpsec.param", key, hdl);
|
||||
}
|
||||
{
|
||||
bpsec_id_t *key = g_new(bpsec_id_t, 1);
|
||||
key->context_id = 1;
|
||||
key->type_id = 1;
|
||||
dissector_handle_t hdl = create_dissector_handle(dissect_defaultsc_result_hmac, proto_bpsec);
|
||||
dissector_add_custom_table_handle("bpsec.result", key, hdl);
|
||||
}
|
||||
// Context 2: BCB-AES-GCM
|
||||
{
|
||||
bpsec_id_t *key = g_new(bpsec_id_t, 1);
|
||||
key->context_id = 2;
|
||||
key->type_id = 1;
|
||||
dissector_handle_t hdl = create_dissector_handle(dissect_defaultsc_param_iv, proto_bpsec);
|
||||
dissector_add_custom_table_handle("bpsec.param", key, hdl);
|
||||
}
|
||||
{
|
||||
bpsec_id_t *key = g_new(bpsec_id_t, 1);
|
||||
key->context_id = 2;
|
||||
key->type_id = 2;
|
||||
dissector_handle_t hdl = create_dissector_handle(dissect_defaultsc_param_aesvar, proto_bpsec);
|
||||
dissector_add_custom_table_handle("bpsec.param", key, hdl);
|
||||
}
|
||||
{
|
||||
bpsec_id_t *key = g_new(bpsec_id_t, 1);
|
||||
key->context_id = 2;
|
||||
key->type_id = 3;
|
||||
dissector_handle_t hdl = create_dissector_handle(dissect_defaultsc_param_wrappedkey, proto_bpsec);
|
||||
dissector_add_custom_table_handle("bpsec.param", key, hdl);
|
||||
}
|
||||
{
|
||||
bpsec_id_t *key = g_new(bpsec_id_t, 1);
|
||||
key->context_id = 2;
|
||||
key->type_id = 4;
|
||||
dissector_handle_t hdl = create_dissector_handle(dissect_defaultsc_param_scope, proto_bpsec);
|
||||
dissector_add_custom_table_handle("bpsec.param", key, hdl);
|
||||
}
|
||||
{
|
||||
bpsec_id_t *key = g_new(bpsec_id_t, 1);
|
||||
key->context_id = 2;
|
||||
key->type_id = 1;
|
||||
dissector_handle_t hdl = create_dissector_handle(dissect_defaultsc_result_authtag, proto_bpsec);
|
||||
dissector_add_custom_table_handle("bpsec.result", key, hdl);
|
||||
}
|
||||
|
||||
reinit_bpsec();
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/* packet-bpv7.h
|
||||
* Definitions for Bundle Protocol Version 7 Security (BPSec) dissection
|
||||
* References:
|
||||
* BPSec: https://datatracker.ietf.org/doc/html/draft-ietf-dtn-bpsec-27
|
||||
*
|
||||
* Copyright 2019-2021, Brian Sipos <brian.sipos@gmail.com>
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
#ifndef PACKET_BPSEC_H
|
||||
#define PACKET_BPSEC_H
|
||||
|
||||
#include <ws_symbol_export.h>
|
||||
#include <epan/tvbuff.h>
|
||||
#include <epan/proto.h>
|
||||
#include <epan/expert.h>
|
||||
#include <glib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* BPSec per-context parameter types and result types are registered with the
|
||||
* dissector table "bpsec.param" and "bpsec.result" respectively.
|
||||
* Both use bpsec_id_t* table keys, to identify both the context and the type
|
||||
* code points.
|
||||
*/
|
||||
|
||||
/** Abstract Security Block Security Context Flags.
|
||||
* Section 3.6.
|
||||
*/
|
||||
typedef enum {
|
||||
/// Security Parameters present
|
||||
BPSEC_ASB_HAS_PARAMS = 0x01,
|
||||
} BpsecAsbFlag;
|
||||
|
||||
/// Parameter/Result dissector lookup
|
||||
typedef struct {
|
||||
/// Security context ID
|
||||
gint64 context_id;
|
||||
/// Parameter/Result ID
|
||||
gint64 type_id;
|
||||
} bpsec_id_t;
|
||||
|
||||
/** Construct a new ID.
|
||||
*/
|
||||
WS_DLL_PUBLIC
|
||||
bpsec_id_t * bpsec_id_new(wmem_allocator_t *alloc, gint64 context_id, gint64 type_id);
|
||||
|
||||
/** Function to match the GDestroyNotify signature.
|
||||
*/
|
||||
WS_DLL_PUBLIC
|
||||
void bpsec_id_free(wmem_allocator_t *alloc, gpointer ptr);
|
||||
|
||||
/** Function to match the GCompareFunc signature.
|
||||
*/
|
||||
WS_DLL_PUBLIC
|
||||
gboolean bpsec_id_equal(gconstpointer a, gconstpointer b);
|
||||
|
||||
/** Function to match the GHashFunc signature.
|
||||
*/
|
||||
WS_DLL_PUBLIC
|
||||
guint bpsec_id_hash(gconstpointer key);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PACKET_BPSEC_H */
|
|
@ -1,4 +1,7 @@
|
|||
/* packet-dtn.c
|
||||
/* packet-bpv6.c
|
||||
* References:
|
||||
* RFC 5050: https://tools.ietf.org/html/rfc5050
|
||||
*
|
||||
* Copyright 2006-2007 The MITRE Corporation.
|
||||
* All Rights Reserved.
|
||||
* Approved for Public Release; Distribution Unlimited.
|
||||
|
@ -41,8 +44,9 @@
|
|||
#include <epan/packet.h>
|
||||
#include <epan/reassemble.h>
|
||||
#include <epan/expert.h>
|
||||
#include "packet-dtn.h"
|
||||
#include "packet-tcp.h"
|
||||
#include <epan/wscbor.h>
|
||||
#include "packet-bpv6.h"
|
||||
#include "packet-cfdp.h"
|
||||
|
||||
static int dissect_admin_record(proto_tree *primary_tree, tvbuff_t *tvb, packet_info *pinfo,
|
||||
int offset, int payload_length, gboolean* success);
|
||||
|
@ -53,59 +57,13 @@ dissect_amp_as_subtree(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int
|
|||
static int add_sdnv_time_to_tree(proto_tree *tree, tvbuff_t *tvb, int offset, int hf_sdnv_time);
|
||||
|
||||
|
||||
/* For Reassembling TCP Convergence Layer segments */
|
||||
static reassembly_table msg_reassembly_table;
|
||||
|
||||
static const char magic[] = {'d', 't', 'n', '!'};
|
||||
|
||||
static int proto_bundle = -1;
|
||||
static int proto_tcp_conv = -1;
|
||||
static dissector_handle_t bundle_handle = NULL;
|
||||
static dissector_handle_t bpv6_handle = NULL;
|
||||
static dissector_handle_t bpv7_handle = NULL;
|
||||
|
||||
static int hf_bundle_pdu_version = -1;
|
||||
|
||||
/* TCP Convergence Header Variables */
|
||||
static int hf_tcp_convergence_pkt_type = -1;
|
||||
|
||||
/* Refuse-Bundle reason code */
|
||||
static int hf_dtn_refuse_bundle_reason_code = -1;
|
||||
|
||||
static int hf_contact_hdr_version = -1;
|
||||
static int hf_contact_hdr_flags = -1;
|
||||
static int hf_contact_hdr_keep_alive = -1;
|
||||
static int hf_contact_hdr_flags_ack_req = -1;
|
||||
static int hf_contact_hdr_flags_frag_enable = -1;
|
||||
static int hf_contact_hdr_flags_nak = -1;
|
||||
static int hf_contact_hdr_magic = -1;
|
||||
static int hf_contact_hdr_local_eid_length = -1;
|
||||
static int hf_contact_hdr_local_eid = -1;
|
||||
|
||||
/* TCP Convergence Data Header Variables */
|
||||
static int hf_tcp_convergence_data_procflags = -1;
|
||||
static int hf_tcp_convergence_data_procflags_start = -1;
|
||||
static int hf_tcp_convergence_data_procflags_end = -1;
|
||||
static int hf_tcp_convergence_data_segment_length = -1;
|
||||
|
||||
/* TCP Convergence Ack Variables */
|
||||
static int hf_tcp_convergence_ack_length = -1;
|
||||
|
||||
/* TCP Convergence Shutdown Header Variables */
|
||||
static int hf_tcp_convergence_shutdown_flags = -1;
|
||||
static int hf_tcp_convergence_shutdown_flags_reason = -1;
|
||||
static int hf_tcp_convergence_shutdown_flags_delay = -1;
|
||||
static int hf_tcp_convergence_shutdown_reason = -1;
|
||||
static int hf_tcp_convergence_shutdown_delay = -1;
|
||||
|
||||
/*TCP Convergence Layer Reassembly boilerplate*/
|
||||
static int hf_msg_fragments = -1;
|
||||
static int hf_msg_fragment = -1;
|
||||
static int hf_msg_fragment_overlap = -1;
|
||||
static int hf_msg_fragment_overlap_conflicts = -1;
|
||||
static int hf_msg_fragment_multiple_tails = -1;
|
||||
static int hf_msg_fragment_too_long_fragment = -1;
|
||||
static int hf_msg_fragment_error = -1;
|
||||
static int hf_msg_fragment_count = -1;
|
||||
static int hf_msg_reassembled_in = -1;
|
||||
static int hf_msg_reassembled_length = -1;
|
||||
|
||||
/* Primary Header Processing Flag Variables */
|
||||
static int hf_bundle_procflags = -1;
|
||||
static int hf_bundle_procflags_fragment = -1;
|
||||
|
@ -267,8 +225,6 @@ static int hf_block_ciphersuite_range_length = -1;
|
|||
|
||||
/* Tree Node Variables */
|
||||
static gint ett_bundle = -1;
|
||||
static gint ett_conv_flags = -1;
|
||||
static gint ett_shutdown_flags = -1;
|
||||
static gint ett_bundle_hdr = -1;
|
||||
static gint ett_primary_hdr = -1;
|
||||
static gint ett_proc_flags = -1;
|
||||
|
@ -279,17 +235,11 @@ static gint ett_dictionary = -1;
|
|||
static gint ett_payload_hdr = -1;
|
||||
static gint ett_payload_flags = -1;
|
||||
static gint ett_block_flags = -1;
|
||||
static gint ett_contact_hdr_flags = -1;
|
||||
static gint ett_admin_record = -1;
|
||||
static gint ett_admin_rec_status = -1;
|
||||
static gint ett_metadata_hdr = -1;
|
||||
static gint ett_sec_block_param_data = -1;
|
||||
|
||||
static gint ett_tcp_conv = -1;
|
||||
static gint ett_tcp_conv_hdr = -1;
|
||||
static gint ett_msg_fragment = -1;
|
||||
static gint ett_msg_fragments = -1;
|
||||
|
||||
static expert_field ei_bundle_payload_length = EI_INIT;
|
||||
static expert_field ei_bundle_control_flags_length = EI_INIT;
|
||||
static expert_field ei_bundle_block_control_flags = EI_INIT;
|
||||
|
@ -299,14 +249,6 @@ static expert_field ei_bundle_offset_error = EI_INIT;
|
|||
static expert_field ei_block_control_block_cteb_invalid = EI_INIT;
|
||||
static expert_field ei_block_control_block_cteb_valid = EI_INIT;
|
||||
|
||||
static expert_field ei_tcp_convergence_data_flags = EI_INIT;
|
||||
static expert_field ei_tcp_convergence_segment_length = EI_INIT;
|
||||
static expert_field ei_tcp_convergence_ack_length = EI_INIT;
|
||||
|
||||
|
||||
static dissector_handle_t bundle_handle;
|
||||
|
||||
#define BUNDLE_PORT 4556
|
||||
|
||||
typedef struct dictionary_data {
|
||||
int bundle_header_dict_length;
|
||||
|
@ -335,25 +277,6 @@ typedef struct dictionary_data {
|
|||
} dictionary_data_t;
|
||||
|
||||
|
||||
static const value_string packet_type_vals[] = {
|
||||
{((TCP_CONVERGENCE_DATA_SEGMENT>>4) & 0x0F), "Data"},
|
||||
{((TCP_CONVERGENCE_ACK_SEGMENT>>4) & 0x0F), "Ack"},
|
||||
{((TCP_CONVERGENCE_REFUSE_BUNDLE>>4) & 0x0F), "Refuse Bundle"},
|
||||
{((TCP_CONVERGENCE_KEEP_ALIVE>>4) & 0x0F), "Keep Alive"},
|
||||
{((TCP_CONVERGENCE_SHUTDOWN>>4) & 0x0F), "Shutdown"},
|
||||
{((TCP_CONVERGENCE_LENGTH>>4) & 0x0F), "Length"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
/* Refuse-Bundle Reason-Code Flags as per RFC-7242: Section-5.4 */
|
||||
static const value_string refuse_bundle_reason_code[] = {
|
||||
{TCP_REFUSE_BUNDLE_REASON_UNKNOWN, "Reason for refusal is unknown"},
|
||||
{TCP_REFUSE_BUNDLE_REASON_RX_COMPLETE, "Complete Bundle Received"},
|
||||
{TCP_REFUSE_BUNDLE_REASON_RX_EXHAUSTED, "Receiver's resources exhausted"},
|
||||
{TCP_REFUSE_BUNDLE_REASON_RX_RETRANSMIT, "Receiver expects re-transmission of bundle"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
static const value_string admin_record_type_vals[] = {
|
||||
{ADMIN_REC_TYPE_STATUS_REPORT, "Bundle Status Report"},
|
||||
{ADMIN_REC_TYPE_CUSTODY_SIGNAL, "Custody Signal"},
|
||||
|
@ -430,39 +353,6 @@ static const value_string res_params_types[] = {
|
|||
{0, NULL}
|
||||
};
|
||||
|
||||
/*
|
||||
* SDNV has a zero in high-order bit position of last byte. The high-order
|
||||
* bit of all preceding bytes is set to one. This returns the numeric value
|
||||
* in an integer and sets the value of the second argument to the number of
|
||||
* bytes used to code the SDNV. A -1 is returned if the evaluation fails
|
||||
* (value exceeds maximum for signed integer). 0 is an acceptable value.
|
||||
*/
|
||||
|
||||
#define SDNV_MASK 0x7f
|
||||
|
||||
static const fragment_items msg_frag_items = {
|
||||
/*Fragment subtrees*/
|
||||
&ett_msg_fragment,
|
||||
&ett_msg_fragments,
|
||||
/*Fragment Fields*/
|
||||
&hf_msg_fragments,
|
||||
&hf_msg_fragment,
|
||||
&hf_msg_fragment_overlap,
|
||||
&hf_msg_fragment_overlap_conflicts,
|
||||
&hf_msg_fragment_multiple_tails,
|
||||
&hf_msg_fragment_too_long_fragment,
|
||||
&hf_msg_fragment_error,
|
||||
&hf_msg_fragment_count,
|
||||
/*Reassembled in field*/
|
||||
&hf_msg_reassembled_in,
|
||||
/*Reassembled length field*/
|
||||
&hf_msg_reassembled_length,
|
||||
/* Reassembled data field */
|
||||
NULL,
|
||||
/*Tag*/
|
||||
"Message fragments"
|
||||
};
|
||||
|
||||
/*
|
||||
* Adds the result of 2 SDNVs to tree: First SDNV is seconds, next is nanoseconds.
|
||||
* Returns bytes in both SDNVs or 0 if something goes wrong.
|
||||
|
@ -1958,6 +1848,12 @@ evaluate_sdnv(tvbuff_t *tvb, int offset, int *bytecount)
|
|||
return value;
|
||||
}
|
||||
|
||||
int evaluate_sdnv_ei(tvbuff_t *tvb, int offset, int *bytecount, expert_field **error) {
|
||||
int value = evaluate_sdnv(tvb, offset, bytecount);
|
||||
*error = (value < 0) ? &ei_bundle_sdnv_length : NULL;
|
||||
return value;
|
||||
}
|
||||
|
||||
/* Special Function to evaluate 64 bit SDNVs */
|
||||
/*3rd arg is number of bytes in field (returned)*/
|
||||
gint64
|
||||
|
@ -2153,404 +2049,8 @@ evaluate_sdnv64(tvbuff_t *tvb, int offset, int *bytecount, guint64 *value)
|
|||
}
|
||||
|
||||
|
||||
static guint
|
||||
get_dtn_contact_header_len(packet_info *pinfo _U_, tvbuff_t *tvb,
|
||||
int offset, void *data _U_)
|
||||
{
|
||||
int len, bytecount;
|
||||
|
||||
/* get length from sdnv */
|
||||
len = evaluate_sdnv(tvb, offset+8, &bytecount);
|
||||
if (len < 0)
|
||||
return 0;
|
||||
|
||||
return len+bytecount+8;
|
||||
}
|
||||
|
||||
static int
|
||||
dissect_dtn_contact_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
|
||||
{
|
||||
proto_item *ti;
|
||||
proto_tree *conv_proto_tree, *conv_tree, *conv_flag_tree;
|
||||
int eid_length, sdnv_length;
|
||||
int offset = 0;
|
||||
|
||||
col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCPCL");
|
||||
col_clear(pinfo->cinfo,COL_INFO); /* Clear out stuff in the info column */
|
||||
col_add_str(pinfo->cinfo, COL_INFO, "Contact Header");
|
||||
|
||||
ti = proto_tree_add_item(tree, proto_tcp_conv, tvb, offset, -1, ENC_NA);
|
||||
conv_proto_tree = proto_item_add_subtree(ti, ett_tcp_conv);
|
||||
|
||||
conv_tree = proto_tree_add_subtree(conv_proto_tree, tvb, offset, -1, ett_tcp_conv, NULL, "Contact Header");
|
||||
|
||||
proto_tree_add_item(conv_tree, hf_contact_hdr_magic, tvb, offset, 4, ENC_NA|ENC_ASCII);
|
||||
offset += 4;
|
||||
proto_tree_add_item(conv_tree, hf_contact_hdr_version, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||
offset++;
|
||||
|
||||
/* Subtree to expand the bits in the Contact Header Flags */
|
||||
ti = proto_tree_add_item(conv_tree, hf_contact_hdr_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||
conv_flag_tree = proto_item_add_subtree(ti, ett_contact_hdr_flags);
|
||||
proto_tree_add_item(conv_flag_tree, hf_contact_hdr_flags_ack_req, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||
proto_tree_add_item(conv_flag_tree, hf_contact_hdr_flags_frag_enable, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||
proto_tree_add_item(conv_flag_tree, hf_contact_hdr_flags_nak, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||
offset++;
|
||||
|
||||
proto_tree_add_item(conv_tree, hf_contact_hdr_keep_alive, tvb, offset, 2, ENC_BIG_ENDIAN);
|
||||
offset += 2;
|
||||
|
||||
/*
|
||||
* New format Contact header has length field followed by Bundle Header.
|
||||
*/
|
||||
eid_length = evaluate_sdnv(tvb, offset, &sdnv_length);
|
||||
ti = proto_tree_add_int(tree, hf_contact_hdr_local_eid_length, tvb, offset, sdnv_length, eid_length);
|
||||
if (eid_length < 0) {
|
||||
expert_add_info(pinfo, ti, &ei_bundle_sdnv_length);
|
||||
return offset;
|
||||
}
|
||||
|
||||
proto_tree_add_item(conv_tree, hf_contact_hdr_local_eid, tvb, sdnv_length + offset, eid_length, ENC_NA|ENC_ASCII);
|
||||
return tvb_captured_length(tvb);
|
||||
}
|
||||
|
||||
static guint
|
||||
get_tcpcl_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
|
||||
{
|
||||
int len, bytecount;
|
||||
guint8 conv_hdr = tvb_get_guint8(tvb, offset);
|
||||
|
||||
switch (conv_hdr & TCP_CONVERGENCE_TYPE_MASK)
|
||||
{
|
||||
case TCP_CONVERGENCE_DATA_SEGMENT:
|
||||
/* get length from sdnv */
|
||||
len = evaluate_sdnv(tvb, offset+1, &bytecount);
|
||||
if (len < 0)
|
||||
return 0;
|
||||
|
||||
return len+bytecount+1;
|
||||
|
||||
case TCP_CONVERGENCE_ACK_SEGMENT:
|
||||
/* get length from sdnv */
|
||||
len = evaluate_sdnv(tvb, offset+1, &bytecount);
|
||||
if (len < 0)
|
||||
return 0;
|
||||
|
||||
return bytecount+1;
|
||||
|
||||
case TCP_CONVERGENCE_KEEP_ALIVE:
|
||||
case TCP_CONVERGENCE_REFUSE_BUNDLE:
|
||||
/* always 1 byte */
|
||||
return 1;
|
||||
case TCP_CONVERGENCE_SHUTDOWN:
|
||||
len = 1;
|
||||
|
||||
if (conv_hdr & TCP_CONVERGENCE_SHUTDOWN_REASON) {
|
||||
len += 1;
|
||||
}
|
||||
if (conv_hdr & TCP_CONVERGENCE_SHUTDOWN_DELAY) {
|
||||
len += 2;
|
||||
}
|
||||
|
||||
return len;
|
||||
|
||||
case TCP_CONVERGENCE_LENGTH:
|
||||
/* get length from sdnv */
|
||||
len = evaluate_sdnv(tvb, offset+1, &bytecount);
|
||||
if (len < 0)
|
||||
return 0;
|
||||
return bytecount+1;
|
||||
|
||||
}
|
||||
|
||||
/* This probably isn't a TCPCL/Bundle packet, so just stop dissection */
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
dissect_tcpcl_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
|
||||
{
|
||||
guint8 conv_hdr;
|
||||
guint8 refuse_bundle_hdr;
|
||||
int offset = 0;
|
||||
int sdnv_length, segment_length, convergence_hdr_size;
|
||||
proto_item *ci, *sub_item;
|
||||
proto_tree *conv_proto_tree, *conv_tree, *sub_tree;
|
||||
fragment_head *frag_msg;
|
||||
tvbuff_t *new_tvb;
|
||||
gboolean more_frags;
|
||||
int processed_length = 0;
|
||||
const gchar* col_text;
|
||||
gboolean bundle_in_col_info;
|
||||
|
||||
static guint32 frag_id = 0;
|
||||
static guint32 last_frame = 0;
|
||||
static int last_raw_offset = 0;
|
||||
|
||||
if (last_frame != pinfo->fd->num || tvb_raw_offset(tvb) < last_raw_offset)
|
||||
frag_id = 0;
|
||||
last_frame = pinfo->fd->num;
|
||||
last_raw_offset = tvb_raw_offset(tvb);
|
||||
|
||||
col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCPCL");
|
||||
col_clear(pinfo->cinfo,COL_INFO); /* Clear out stuff in the info column */
|
||||
|
||||
col_text = col_get_text(pinfo->cinfo, COL_INFO);
|
||||
bundle_in_col_info = (col_text && strstr(col_text, " > "));
|
||||
|
||||
ci = proto_tree_add_item(tree, proto_tcp_conv, tvb, offset, -1, ENC_NA);
|
||||
conv_proto_tree = proto_item_add_subtree(ci, ett_tcp_conv);
|
||||
|
||||
conv_tree = proto_tree_add_subtree(conv_proto_tree, tvb, 0, -1, ett_tcp_conv_hdr, NULL, "TCP Convergence Header");
|
||||
|
||||
conv_hdr = tvb_get_guint8(tvb, offset);
|
||||
proto_tree_add_item(conv_tree, hf_tcp_convergence_pkt_type, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||
col_add_str(pinfo->cinfo, COL_INFO, val_to_str_const((conv_hdr>>4)&0xF, packet_type_vals, "Unknown"));
|
||||
|
||||
switch (conv_hdr & TCP_CONVERGENCE_TYPE_MASK)
|
||||
{
|
||||
case TCP_CONVERGENCE_DATA_SEGMENT:
|
||||
sub_item = proto_tree_add_item(conv_tree, hf_tcp_convergence_data_procflags, tvb,
|
||||
offset, 1, ENC_BIG_ENDIAN);
|
||||
sub_tree = proto_item_add_subtree(sub_item, ett_conv_flags);
|
||||
proto_tree_add_item(sub_tree, hf_tcp_convergence_data_procflags_start,
|
||||
tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||
proto_tree_add_item(sub_tree, hf_tcp_convergence_data_procflags_end,
|
||||
tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||
|
||||
/* Only Start and End flags (bits 0 & 1) are valid in Data Segment */
|
||||
if ((conv_hdr & ~(TCP_CONVERGENCE_TYPE_MASK | TCP_CONVERGENCE_DATA_FLAGS)) != 0) {
|
||||
expert_add_info(pinfo, sub_item, &ei_tcp_convergence_data_flags);
|
||||
}
|
||||
|
||||
segment_length = evaluate_sdnv(tvb, 1, &sdnv_length);
|
||||
sub_item = proto_tree_add_int(conv_tree, hf_tcp_convergence_data_segment_length, tvb, 1, sdnv_length, segment_length);
|
||||
if (segment_length < 0) {
|
||||
expert_add_info(pinfo, sub_item, &ei_tcp_convergence_segment_length);
|
||||
return 1;
|
||||
}
|
||||
|
||||
convergence_hdr_size = sdnv_length + 1;
|
||||
|
||||
/*
|
||||
* 1/11/2006 - If I got here, I should have a complete convergence layer
|
||||
* "segment" beginning at frame_offset. However that might not be a
|
||||
* complete bundle. Or there might be a complete bundle plus one or more
|
||||
* additional convergence layer headers.
|
||||
*/
|
||||
|
||||
new_tvb = NULL;
|
||||
sub_tree = NULL;
|
||||
if ((conv_hdr & TCP_CONVERGENCE_DATA_END_FLAG) == TCP_CONVERGENCE_DATA_END_FLAG) {
|
||||
more_frags = FALSE;
|
||||
}
|
||||
else {
|
||||
more_frags = TRUE;
|
||||
}
|
||||
|
||||
frag_msg = fragment_add_seq_next(&msg_reassembly_table,
|
||||
tvb, offset + convergence_hdr_size,
|
||||
pinfo, frag_id, data,
|
||||
segment_length, more_frags);
|
||||
|
||||
if (!more_frags) ++frag_id;
|
||||
|
||||
processed_length = convergence_hdr_size + segment_length;
|
||||
|
||||
if (frag_msg && !more_frags) {
|
||||
|
||||
int save_fd_head_layer = frag_msg->reas_in_layer_num;
|
||||
frag_msg->reas_in_layer_num = pinfo->curr_layer_num;
|
||||
|
||||
sub_item = proto_tree_add_item(tree, proto_bundle, tvb, offset, -1, ENC_NA);
|
||||
sub_tree = proto_item_add_subtree(sub_item, ett_bundle);
|
||||
|
||||
new_tvb = process_reassembled_data(tvb, offset + convergence_hdr_size,
|
||||
pinfo, "Reassembled DTN", frag_msg,
|
||||
&msg_frag_items, NULL, sub_tree);
|
||||
|
||||
frag_msg->reas_in_layer_num = save_fd_head_layer;
|
||||
}
|
||||
|
||||
if (new_tvb) {
|
||||
if (0 == call_dissector_with_data(bundle_handle, new_tvb, pinfo, sub_tree, data)) {
|
||||
/*Couldn't parse bundle, treat as raw data */
|
||||
call_data_dissector(new_tvb, pinfo, sub_tree);
|
||||
return tvb_captured_length(tvb);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
/*
|
||||
* If there are 2 segments, the second of which is very short, this
|
||||
* gets displayed instead of the usual Source EID/Destination EID in
|
||||
* the Bundle Dissection frame. If these statements are left out entirely,
|
||||
* nothing is displayed, i.e., there seems to be no way to get the
|
||||
* Source/Destination in the 2-segment case. I'll leave it in because I
|
||||
* think it is informative in the multi-segment case although confusing in the
|
||||
* 2-segment case.
|
||||
*/
|
||||
col_add_str(pinfo->cinfo, COL_INFO, "[Bundle TCPCL Segment]");
|
||||
}
|
||||
break;
|
||||
case TCP_CONVERGENCE_ACK_SEGMENT:
|
||||
if (bundle_in_col_info) {
|
||||
if (!strstr(col_text, ", TCPL ACK")) {
|
||||
col_add_str(pinfo->cinfo, COL_INFO, ", TCPL ACK Segment(s)");
|
||||
}
|
||||
} else {
|
||||
col_set_str(pinfo->cinfo, COL_INFO, "TCPL ACK Segment(s)");
|
||||
}
|
||||
segment_length = evaluate_sdnv(tvb, offset+1, &sdnv_length);
|
||||
sub_item = proto_tree_add_int(conv_tree, hf_tcp_convergence_ack_length, tvb, offset+1, sdnv_length, segment_length);
|
||||
if (segment_length < 0) {
|
||||
expert_add_info(pinfo, sub_item, &ei_tcp_convergence_ack_length);
|
||||
processed_length = tvb_captured_length(tvb);
|
||||
} else {
|
||||
processed_length = sdnv_length + 1;
|
||||
}
|
||||
break;
|
||||
case TCP_CONVERGENCE_KEEP_ALIVE:
|
||||
if (bundle_in_col_info) {
|
||||
if (!strstr(col_text, ", TCPL KEEPALIVE")) {
|
||||
col_add_str(pinfo->cinfo, COL_INFO, ", TCPL KEEPALIVE Segment");
|
||||
}
|
||||
} else {
|
||||
col_set_str(pinfo->cinfo, COL_INFO, "TCPL KEEPALIVE Segment");
|
||||
}
|
||||
/*No valid flags in Keep Alive*/
|
||||
processed_length = 1;
|
||||
break;
|
||||
|
||||
case TCP_CONVERGENCE_SHUTDOWN:
|
||||
if (bundle_in_col_info) {
|
||||
if (!strstr(col_text, ", TCPL SHUTDOWN")) {
|
||||
col_add_str(pinfo->cinfo, COL_INFO, ", TCPL SHUTDOWN Segment");
|
||||
}
|
||||
} else {
|
||||
col_set_str(pinfo->cinfo, COL_INFO, "TCPL SHUTDOWN Segment");
|
||||
}
|
||||
/* Add tree for Shutdown Flags */
|
||||
sub_item = proto_tree_add_item(conv_tree, hf_tcp_convergence_shutdown_flags, tvb,
|
||||
offset, 1, ENC_BIG_ENDIAN);
|
||||
sub_tree = proto_item_add_subtree(sub_item, ett_shutdown_flags);
|
||||
|
||||
proto_tree_add_item(sub_tree, hf_tcp_convergence_shutdown_flags_reason,
|
||||
tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||
proto_tree_add_item(sub_tree, hf_tcp_convergence_shutdown_flags_delay,
|
||||
tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||
|
||||
offset += 1;
|
||||
if (conv_hdr & TCP_CONVERGENCE_SHUTDOWN_REASON) {
|
||||
proto_tree_add_item(conv_tree,
|
||||
hf_tcp_convergence_shutdown_reason, tvb,
|
||||
offset, 1, ENC_BIG_ENDIAN);
|
||||
offset += 1;
|
||||
}
|
||||
if (conv_hdr & TCP_CONVERGENCE_SHUTDOWN_DELAY) {
|
||||
proto_tree_add_item(conv_tree,
|
||||
hf_tcp_convergence_shutdown_delay, tvb,
|
||||
offset, 2, ENC_BIG_ENDIAN);
|
||||
}
|
||||
break;
|
||||
case TCP_CONVERGENCE_REFUSE_BUNDLE:
|
||||
if (bundle_in_col_info) {
|
||||
if (!strstr(col_text, ", TCPL REFUSE")) {
|
||||
col_add_str(pinfo->cinfo, COL_INFO, ", TCPL REFUSE_BUNDLE Segment");
|
||||
}
|
||||
} else {
|
||||
col_set_str(pinfo->cinfo, COL_INFO, "TCPL REFUSE_BUNDLE Segment");
|
||||
}
|
||||
|
||||
refuse_bundle_hdr = tvb_get_guint8(tvb, offset);
|
||||
proto_tree_add_item(conv_tree, hf_dtn_refuse_bundle_reason_code, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||
col_add_str(pinfo->cinfo, COL_INFO, val_to_str_const((refuse_bundle_hdr>>4)&0xF, refuse_bundle_reason_code, "Unknown"));
|
||||
|
||||
/*No valid flags*/
|
||||
processed_length = tvb_captured_length(tvb);
|
||||
break;
|
||||
}
|
||||
|
||||
return processed_length;
|
||||
}
|
||||
|
||||
static int
|
||||
dissect_tcpcl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
|
||||
{
|
||||
guint8 conv_hdr;
|
||||
int offset, bytecount;
|
||||
int processed_length;
|
||||
|
||||
/* Make sure we have a convergence header byte */
|
||||
if (!tvb_bytes_exist(tvb, 0, 1))
|
||||
return 0;
|
||||
|
||||
conv_hdr = tvb_get_guint8(tvb, 0);
|
||||
switch (conv_hdr & TCP_CONVERGENCE_TYPE_MASK)
|
||||
{
|
||||
case TCP_CONVERGENCE_DATA_SEGMENT:
|
||||
case TCP_CONVERGENCE_ACK_SEGMENT:
|
||||
/* ensure sdnv */
|
||||
offset = 1;
|
||||
bytecount = 1;
|
||||
|
||||
if (!tvb_bytes_exist(tvb, offset, 1)) {
|
||||
pinfo->desegment_offset = 0;
|
||||
pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (tvb_get_guint8(tvb, offset) & ~SDNV_MASK) {
|
||||
if (bytecount > (int)sizeof(int)) {
|
||||
/* invalid length field */
|
||||
return 0;
|
||||
}
|
||||
|
||||
bytecount++;
|
||||
offset++;
|
||||
|
||||
if (!tvb_bytes_exist(tvb, offset, 1)) {
|
||||
pinfo->desegment_offset = 0;
|
||||
pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TCP_CONVERGENCE_KEEP_ALIVE:
|
||||
case TCP_CONVERGENCE_REFUSE_BUNDLE:
|
||||
/* always 1 byte */
|
||||
break;
|
||||
case TCP_CONVERGENCE_SHUTDOWN:
|
||||
if ((conv_hdr &
|
||||
~(TCP_CONVERGENCE_TYPE_MASK | TCP_CONVERGENCE_SHUTDOWN_FLAGS)) != 0) {
|
||||
/* Not for us */
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (conv_hdr == (guint8)magic[0]) {
|
||||
if (!tvb_bytes_exist(tvb, 0, 4) || tvb_memeql(tvb, 0, magic, 4)) {
|
||||
/* Not for us */
|
||||
return 0;
|
||||
}
|
||||
|
||||
tcp_dissect_pdus(tvb, pinfo, tree, TRUE, 8, get_dtn_contact_header_len, dissect_dtn_contact_header, data);
|
||||
return tvb_captured_length(tvb);
|
||||
}
|
||||
|
||||
/* Not for us */
|
||||
return 0;
|
||||
};
|
||||
|
||||
processed_length = get_tcpcl_pdu_len(pinfo, tvb, 0, data);
|
||||
|
||||
tcp_dissect_pdus(tvb, pinfo, tree, TRUE, 1, get_tcpcl_pdu_len, dissect_tcpcl_pdu, data);
|
||||
|
||||
return processed_length;
|
||||
}
|
||||
|
||||
static int
|
||||
dissect_bundle(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
|
||||
dissect_bpv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
|
||||
{
|
||||
proto_item *ti, *ti_bundle_protocol;
|
||||
proto_tree *bundle_tree, *primary_tree;
|
||||
|
@ -2620,12 +2120,40 @@ dissect_bundle(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _
|
|||
return(offset);
|
||||
}
|
||||
|
||||
/// Introspect the data to choose a dissector version
|
||||
static int
|
||||
dissect_bundle(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
|
||||
{
|
||||
gint offset = 0;
|
||||
|
||||
{
|
||||
// Primary Header Version octet
|
||||
guint8 version = tvb_get_guint8(tvb, offset);
|
||||
if ((version == 4) || (version == 5) || (version == 6)) {
|
||||
return call_dissector(bpv6_handle, tvb, pinfo, tree);
|
||||
}
|
||||
}
|
||||
|
||||
wscbor_chunk_t *frame = wscbor_chunk_read(wmem_packet_scope(), tvb, &offset);
|
||||
if (frame->type_major == CBOR_TYPE_ARRAY) {
|
||||
wscbor_chunk_t *primary = wscbor_chunk_read(wmem_packet_scope(), tvb, &offset);
|
||||
if (primary->type_major == CBOR_TYPE_ARRAY) {
|
||||
wscbor_chunk_t *version = wscbor_chunk_read(wmem_packet_scope(), tvb, &offset);
|
||||
if (version->type_major == CBOR_TYPE_UINT) {
|
||||
guint64 vers_val = version->head_value;
|
||||
if (vers_val == 7) {
|
||||
return call_dissector(bpv7_handle, tvb, pinfo, tree);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void proto_reg_handoff_bundle(void);
|
||||
void proto_register_bundle(void);
|
||||
|
||||
void
|
||||
proto_register_bundle(void)
|
||||
proto_register_bpv6(void)
|
||||
{
|
||||
|
||||
static hf_register_info hf[] = {
|
||||
|
@ -2633,47 +2161,6 @@ proto_register_bundle(void)
|
|||
{"Bundle Version", "bundle.version",
|
||||
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_msg_fragments,
|
||||
{"Message Fragments", "bundle.msg.fragments",
|
||||
FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_msg_fragment,
|
||||
{"Message Fragment", "bundle.msg.fragment",
|
||||
FT_FRAMENUM, BASE_NONE, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_msg_fragment_overlap,
|
||||
{"Message fragment overlap", "bundle.msg.fragment.overlap",
|
||||
FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_msg_fragment_overlap_conflicts,
|
||||
{"Message fragment overlapping with conflicting data",
|
||||
"bundle.msg.fragment.overlap.conflicts",
|
||||
FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_msg_fragment_multiple_tails,
|
||||
{"Message has multiple tails", "bundle.msg.fragment.multiple_tails",
|
||||
FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_msg_fragment_too_long_fragment,
|
||||
{"Message fragment too long", "bundle.msg.fragment.too_long_fragment",
|
||||
FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_msg_fragment_error,
|
||||
{"Message defragmentation error", "bundle.msg.fragment.error",
|
||||
FT_FRAMENUM, BASE_NONE, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_msg_fragment_count,
|
||||
{"Message fragment count", "bundle.msg.fragment.count",
|
||||
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_msg_reassembled_in,
|
||||
{"Reassembled in", "bundle.msg.reassembled.in",
|
||||
FT_FRAMENUM, BASE_NONE, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_msg_reassembled_length,
|
||||
{"Reassembled DTN length", "bundle.msg.reassembled.length",
|
||||
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_bundle_procflags,
|
||||
{"Primary Header Processing Flags", "bundle.primary.proc.flag",
|
||||
FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
|
||||
|
@ -3192,93 +2679,6 @@ proto_register_bundle(void)
|
|||
},
|
||||
};
|
||||
|
||||
static hf_register_info hf_tcpcl[] = {
|
||||
{&hf_tcp_convergence_pkt_type,
|
||||
{"Pkt Type", "tcpcl.pkt_type",
|
||||
FT_UINT8, BASE_DEC, VALS(packet_type_vals), 0xF0, NULL, HFILL}
|
||||
},
|
||||
{&hf_dtn_refuse_bundle_reason_code,
|
||||
{"Reason-Code", "tcpcl.refuse.reason_code",
|
||||
FT_UINT8, BASE_DEC, VALS(refuse_bundle_reason_code), 0x0F, NULL, HFILL}
|
||||
},
|
||||
{&hf_tcp_convergence_data_procflags,
|
||||
{"TCP Convergence Data Flags", "tcpcl.data.proc.flag",
|
||||
FT_UINT8, BASE_HEX, NULL, TCP_CONVERGENCE_DATA_FLAGS, NULL, HFILL}
|
||||
},
|
||||
{&hf_tcp_convergence_data_procflags_start,
|
||||
{"Segment contains start of bundle", "tcpcl.data.proc.start",
|
||||
FT_BOOLEAN, 8, NULL, TCP_CONVERGENCE_DATA_START_FLAG, NULL, HFILL}
|
||||
},
|
||||
{&hf_tcp_convergence_data_procflags_end,
|
||||
{"Segment contains end of Bundle", "tcpcl.data.proc.end",
|
||||
FT_BOOLEAN, 8, NULL, TCP_CONVERGENCE_DATA_END_FLAG, NULL, HFILL}
|
||||
},
|
||||
{&hf_tcp_convergence_data_segment_length,
|
||||
{"Segment Length", "tcpcl.data.length",
|
||||
FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_tcp_convergence_shutdown_flags,
|
||||
{"TCP Convergence Shutdown Flags", "tcpcl.shutdown.flags",
|
||||
FT_UINT8, BASE_HEX, NULL, TCP_CONVERGENCE_SHUTDOWN_FLAGS, NULL, HFILL}
|
||||
},
|
||||
{&hf_tcp_convergence_shutdown_flags_reason,
|
||||
{"Shutdown includes Reason Code", "tcpcl.shutdown.reason.flag",
|
||||
FT_BOOLEAN, 8, NULL, TCP_CONVERGENCE_SHUTDOWN_REASON, NULL, HFILL}
|
||||
},
|
||||
{&hf_tcp_convergence_shutdown_flags_delay,
|
||||
{"Shutdown includes Reconnection Delay", "tcpcl.shutdown.delay.flag",
|
||||
FT_BOOLEAN, 8, NULL, TCP_CONVERGENCE_SHUTDOWN_DELAY, NULL, HFILL}
|
||||
},
|
||||
{&hf_tcp_convergence_shutdown_reason,
|
||||
{"Shutdown Reason Code", "tcpcl.shutdown.reason",
|
||||
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_tcp_convergence_shutdown_delay,
|
||||
{"Shutdown Reconnection Delay", "tcpcl.shutdown.delay",
|
||||
FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_tcp_convergence_ack_length,
|
||||
{"Ack Length", "tcpcl.ack.length",
|
||||
FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_contact_hdr_version,
|
||||
{"Version", "tcpcl.contact_hdr.version",
|
||||
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_contact_hdr_flags,
|
||||
{"Flags", "tcpcl.contact_hdr.flags",
|
||||
FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_contact_hdr_flags_ack_req,
|
||||
{"Bundle Acks Requested", "tcpcl.contact_hdr.flags.ackreq",
|
||||
FT_BOOLEAN, 8, NULL, TCP_CONV_BUNDLE_ACK_FLAG, NULL, HFILL}
|
||||
},
|
||||
{&hf_contact_hdr_flags_frag_enable,
|
||||
{"Reactive Fragmentation Enabled", "tcpcl.contact_hdr.flags.fragen",
|
||||
FT_BOOLEAN, 8, NULL, TCP_CONV_REACTIVE_FRAG_FLAG, NULL, HFILL}
|
||||
},
|
||||
{&hf_contact_hdr_flags_nak,
|
||||
{"Support Negative Acknowledgements", "tcpcl.contact_hdr.flags.nak",
|
||||
FT_BOOLEAN, 8, NULL, TCP_CONV_CONNECTOR_RCVR_FLAG, NULL, HFILL}
|
||||
},
|
||||
{&hf_contact_hdr_keep_alive,
|
||||
{"Keep Alive", "tcpcl.contact_hdr.keep_alive",
|
||||
FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_contact_hdr_magic,
|
||||
{"Magic", "tcpcl.contact_hdr.magic",
|
||||
FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_contact_hdr_local_eid,
|
||||
{"Local EID", "tcpcl.contact_hdr.local_eid",
|
||||
FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_contact_hdr_local_eid_length,
|
||||
{"Local EID Length", "tcpcl.contact_hdr.local_eid_length",
|
||||
FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
};
|
||||
|
||||
static gint *ett[] = {
|
||||
&ett_bundle,
|
||||
&ett_bundle_hdr,
|
||||
|
@ -3291,22 +2691,12 @@ proto_register_bundle(void)
|
|||
&ett_payload_hdr,
|
||||
&ett_payload_flags,
|
||||
&ett_block_flags,
|
||||
&ett_contact_hdr_flags,
|
||||
&ett_conv_flags,
|
||||
&ett_shutdown_flags,
|
||||
&ett_admin_record,
|
||||
&ett_admin_rec_status,
|
||||
&ett_metadata_hdr,
|
||||
&ett_sec_block_param_data
|
||||
};
|
||||
|
||||
static gint *ett_tcpcl[] = {
|
||||
&ett_tcp_conv,
|
||||
&ett_tcp_conv_hdr,
|
||||
&ett_msg_fragment,
|
||||
&ett_msg_fragments,
|
||||
};
|
||||
|
||||
static ei_register_info ei[] = {
|
||||
{ &ei_bundle_control_flags_length,
|
||||
{ "bundle.block.control.flags.length", PI_UNDECODED, PI_WARN, "Wrong bundle control flag length", EXPFILL }
|
||||
|
@ -3334,47 +2724,23 @@ proto_register_bundle(void)
|
|||
},
|
||||
};
|
||||
|
||||
static ei_register_info ei_tcpcl[] = {
|
||||
{ &ei_tcp_convergence_data_flags,
|
||||
{ "tcpcl.data.flags.invalid", PI_PROTOCOL, PI_WARN, "Invalid TCP CL Data Segment Flags", EXPFILL }
|
||||
},
|
||||
{ &ei_tcp_convergence_segment_length,
|
||||
{ "tcpcl.data.length.invalid", PI_PROTOCOL, PI_ERROR, "Invalid Data Length", EXPFILL }
|
||||
},
|
||||
{ &ei_tcp_convergence_ack_length,
|
||||
{ "tcpcl.ack.length.error", PI_PROTOCOL, PI_WARN, "Ack Length: Error", EXPFILL }
|
||||
},
|
||||
};
|
||||
expert_module_t *expert_bundle;
|
||||
|
||||
expert_module_t *expert_bundle, *expert_tcpcl;
|
||||
|
||||
proto_bundle = proto_register_protocol("Bundle Protocol", "Bundle", "bundle");
|
||||
proto_bundle = proto_register_protocol("Bundle Protocol", "BP", "bundle");
|
||||
bpv6_handle = register_dissector("bpv6", dissect_bpv6, proto_bundle);
|
||||
bundle_handle = register_dissector("bundle", dissect_bundle, proto_bundle);
|
||||
|
||||
proto_tcp_conv = proto_register_protocol ("DTN TCP Convergence Layer Protocol", "TCPCL", "tcpcl");
|
||||
|
||||
proto_register_field_array(proto_bundle, hf, array_length(hf));
|
||||
proto_register_subtree_array(ett, array_length(ett));
|
||||
expert_bundle = expert_register_protocol(proto_bundle);
|
||||
expert_register_field_array(expert_bundle, ei, array_length(ei));
|
||||
|
||||
proto_register_field_array(proto_tcp_conv, hf_tcpcl, array_length(hf_tcpcl));
|
||||
proto_register_subtree_array(ett_tcpcl, array_length(ett_tcpcl));
|
||||
expert_tcpcl = expert_register_protocol(proto_tcp_conv);
|
||||
expert_register_field_array(expert_tcpcl, ei_tcpcl, array_length(ei_tcpcl));
|
||||
|
||||
reassembly_table_register(&msg_reassembly_table,
|
||||
&addresses_reassembly_table_functions);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
proto_reg_handoff_bundle(void)
|
||||
proto_reg_handoff_bpv6(void)
|
||||
{
|
||||
dissector_handle_t tcpcl_handle;
|
||||
bpv7_handle = find_dissector("bpv7");
|
||||
|
||||
tcpcl_handle = create_dissector_handle(dissect_tcpcl, proto_bundle);
|
||||
dissector_add_uint_with_preference("tcp.port", BUNDLE_PORT, tcpcl_handle);
|
||||
dissector_add_uint_with_preference("udp.port", BUNDLE_PORT, bundle_handle);
|
||||
}
|
||||
|
|
@ -1,4 +1,7 @@
|
|||
/*
|
||||
/* packet-bpv6.h
|
||||
* References:
|
||||
* RFC 5050: https://tools.ietf.org/html/rfc5050
|
||||
*
|
||||
* Copyright 2006-2007 The MITRE Corporation.
|
||||
* All Rights Reserved.
|
||||
* Approved for Public Release; Distribution Unlimited.
|
||||
|
@ -15,53 +18,18 @@
|
|||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef PACKET_BPV6_H
|
||||
#define PACKET_BPV6_H
|
||||
|
||||
/* TCP Convergence Layer - Message Types */
|
||||
#define TCP_CONV_MSG_TYPE_DATA 0x01
|
||||
#define TCP_CONV_MSG_TYPE_ACK 0x02
|
||||
#define TCP_CONV_MSG_TYPE_KEEP_ALIVE 0x03
|
||||
#define TCP_CONV_MSG_TYPE_SHUTDOWN 0x04
|
||||
#include <ws_symbol_export.h>
|
||||
#include <epan/tvbuff.h>
|
||||
#include <epan/proto.h>
|
||||
|
||||
/* TCP Convergence Layer (3) - Message Types */
|
||||
#define TCP_CONVERGENCE_TYPE_MASK 0xf0
|
||||
#define TCP_CONVERGENCE_DATA_SEGMENT 0x10
|
||||
#define TCP_CONVERGENCE_ACK_SEGMENT 0x20
|
||||
#define TCP_CONVERGENCE_REFUSE_BUNDLE 0x30
|
||||
#define TCP_CONVERGENCE_KEEP_ALIVE 0x40
|
||||
#define TCP_CONVERGENCE_SHUTDOWN 0x50
|
||||
#define TCP_CONVERGENCE_LENGTH 0x60
|
||||
|
||||
/* TCP Convergence Layer - Contact Header Flags */
|
||||
#define TCP_CONV_BUNDLE_ACK_FLAG 0x01
|
||||
#define TCP_CONV_REACTIVE_FRAG_FLAG 0x02
|
||||
#define TCP_CONV_CONNECTOR_RCVR_FLAG 0x04
|
||||
|
||||
/* TCP Convergence Layer - Data Segment Flags */
|
||||
#define TCP_CONVERGENCE_DATA_FLAGS 0x03
|
||||
#define TCP_CONVERGENCE_DATA_END_FLAG 0x01
|
||||
#define TCP_CONVERGENCE_DATA_START_FLAG 0x02
|
||||
|
||||
/* TCP Convergence Layer - Shutdown Segment Flags */
|
||||
#define TCP_CONVERGENCE_SHUTDOWN_FLAGS 0x03
|
||||
#define TCP_CONVERGENCE_SHUTDOWN_REASON 0x02
|
||||
#define TCP_CONVERGENCE_SHUTDOWN_DELAY 0x01
|
||||
|
||||
/* REFUSE-BUNDLE Reason-Codes */
|
||||
#define TCP_REFUSE_BUNDLE_REASON_UNKNOWN 0x00
|
||||
#define TCP_REFUSE_BUNDLE_REASON_RX_COMPLETE 0x01
|
||||
#define TCP_REFUSE_BUNDLE_REASON_RX_EXHAUSTED 0x02
|
||||
#define TCP_REFUSE_BUNDLE_REASON_RX_RETRANSMIT 0x03
|
||||
/* 0x4-0x7 - Unassigned
|
||||
* 0x8-0xf - Reserved for future Use */
|
||||
|
||||
/*
|
||||
* TCP Convergence Layer - Minimum buffer sizes
|
||||
* For Data Packet require 5 bytes fixed plus
|
||||
* up to 4 additional for length SDV
|
||||
*/
|
||||
|
||||
#define TCP_CONV_MIN_DATA_BUFFER 9
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define BUNDLE_PORT 4556
|
||||
|
||||
#define BUNDLE_PROCFLAGS_FRAG_MASK 0x01
|
||||
#define BUNDLE_PROCFLAGS_ADMIN_MASK 0x02
|
||||
|
@ -106,12 +74,6 @@
|
|||
#define PAYLOAD_PROCFLAGS_DISCARD_FAILURE 0x04
|
||||
#define PAYLOAD_PROCFLAGS_LAST_HEADER 0x08
|
||||
|
||||
/* Header Fixed Sizes */
|
||||
#define TCP_CONV_HDR_DATA_FIXED_LENGTH 5
|
||||
#define TCP_CONV_HDR_ACK_LENGTH 9
|
||||
#define TCP_CONV_HDR_KEEP_ALIVE_LENGTH 1
|
||||
#define TCP_CONV_HDR_SHUTDOWN_LENGTH 1
|
||||
|
||||
/* Administrative Record Definitions */
|
||||
#define ADMIN_REC_TYPE_STATUS_REPORT 0x01
|
||||
#define ADMIN_REC_TYPE_CUSTODY_SIGNAL 0x02
|
||||
|
@ -150,7 +112,20 @@
|
|||
#define DTN_SCHEME_STR "dtn"
|
||||
#define IPN_SCHEME_STR "ipn"
|
||||
|
||||
/*
|
||||
* SDNV has a zero in high-order bit position of last byte. The high-order
|
||||
* bit of all preceding bytes is set to one. This returns the numeric value
|
||||
* in an integer and sets the value of the second argument to the number of
|
||||
* bytes used to code the SDNV. A -1 is returned if the evaluation fails
|
||||
* (value exceeds maximum for signed integer). 0 is an acceptable value.
|
||||
*/
|
||||
#define SDNV_MASK 0x7f
|
||||
|
||||
int evaluate_sdnv(tvbuff_t *tvb, int offset, int *bytecount);
|
||||
|
||||
/// Return an error_info index if not valid
|
||||
int evaluate_sdnv_ei(tvbuff_t *tvb, int offset, int *bytecount, expert_field **error);
|
||||
|
||||
gint64 evaluate_sdnv_64(tvbuff_t *tvb, int offset, int *bytecount);
|
||||
|
||||
|
||||
|
@ -161,10 +136,14 @@ gint64 evaluate_sdnv_64(tvbuff_t *tvb, int offset, int *bytecount);
|
|||
* result is TRUE (1) on success else FALSE (0)
|
||||
*/
|
||||
int evaluate_sdnv32(tvbuff_t *tvb, int offset, int *bytecount, guint32 *value);
|
||||
|
||||
int evaluate_sdnv64(tvbuff_t *tvb, int offset, int *bytecount, guint64 *value);
|
||||
|
||||
void
|
||||
dissect_cfdp_as_subtree(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PACKET_AMP_H */
|
||||
|
||||
/*
|
||||
* Editor modelines - https://www.wireshark.org/tools/modelines.html
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,357 @@
|
|||
/* packet-bpv7.h
|
||||
* Definitions for Bundle Protocol Version 7 dissection.
|
||||
* References:
|
||||
* BPv7: https://datatracker.ietf.org/doc/html/draft-ietf-dtn-bpbis-31
|
||||
*
|
||||
* Copyright 2019-2021, Brian Sipos <brian.sipos@gmail.com>
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
#ifndef PACKET_BPV7_H
|
||||
#define PACKET_BPV7_H
|
||||
|
||||
#include <ws_symbol_export.h>
|
||||
#include <epan/tvbuff.h>
|
||||
#include <epan/proto.h>
|
||||
#include <epan/expert.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* BPv7 block-type-specific data dissectors are registered with the
|
||||
* dissector table "bpv7.block_type" and Administrative Record dissectors
|
||||
* with the table "bpv7.admin_record_type". Both use guint64* table keys.
|
||||
*/
|
||||
|
||||
/** Bundle CRC types.
|
||||
* Section 4.1.1.
|
||||
*/
|
||||
typedef enum {
|
||||
/// no CRC is present.
|
||||
BP_CRC_NONE = 0,
|
||||
/// a standard X-25 CRC-16 is present.
|
||||
BP_CRC_16 = 1,
|
||||
/// a standard CRC32C (Castagnoli) CRC-32 is present.
|
||||
BP_CRC_32 = 2,
|
||||
} BundleCrcType;
|
||||
|
||||
/** Bundle processing control flags.
|
||||
* Section 4.1.3.
|
||||
*/
|
||||
typedef enum {
|
||||
/// bundle deletion status reports are requested.
|
||||
BP_BUNDLE_REQ_DELETION_REPORT = 0x040000,
|
||||
/// bundle delivery status reports are requested.
|
||||
BP_BUNDLE_REQ_DELIVERY_REPORT = 0x020000,
|
||||
/// bundle forwarding status reports are requested.
|
||||
BP_BUNDLE_REQ_FORWARDING_REPORT = 0x010000,
|
||||
/// bundle reception status reports are requested.
|
||||
BP_BUNDLE_REQ_RECEPTION_REPORT = 0x004000,
|
||||
/// status time is requested in all status reports.
|
||||
BP_BUNDLE_REQ_STATUS_TIME = 0x000040,
|
||||
/// user application acknowledgement is requested.
|
||||
BP_BUNDLE_USER_APP_ACK = 0x000020,
|
||||
/// bundle must not be fragmented.
|
||||
BP_BUNDLE_NO_FRAGMENT = 0x000004,
|
||||
/// payload is an administrative record.
|
||||
BP_BUNDLE_PAYLOAD_ADMIN = 0x000002,
|
||||
/// bundle is a fragment.
|
||||
BP_BUNDLE_IS_FRAGMENT = 0x000001,
|
||||
} BundleProcessingFlag;
|
||||
|
||||
/** Block processing control flags.
|
||||
* Section 4.1.4.
|
||||
*/
|
||||
typedef enum {
|
||||
/// block must be removed from bundle if it can't be processed.
|
||||
BP_BLOCK_REMOVE_IF_NO_PROCESS = 0x10,
|
||||
/// bundle must be deleted if block can't be processed.
|
||||
BP_BLOCK_DELETE_IF_NO_PROCESS = 0x04,
|
||||
/// transmission of a status report is requested if block can't be processed.
|
||||
BP_BLOCK_STATUS_IF_NO_PROCESS = 0x02,
|
||||
/// block must be replicated in every fragment.
|
||||
BP_BLOCK_REPLICATE_IN_FRAGMENT = 0x01,
|
||||
} BlockProcessingFlag;
|
||||
|
||||
/** Standard block type codes.
|
||||
* Section 4.2.3 and Section 4.3.
|
||||
*/
|
||||
typedef enum {
|
||||
BP_BLOCKTYPE_INVALID = 0,
|
||||
/// Payload (data)
|
||||
BP_BLOCKTYPE_PAYLOAD = 1,
|
||||
/// Previous Node
|
||||
BP_BLOCKTYPE_PREV_NODE = 6,
|
||||
/// Bundle Age
|
||||
BP_BLOCKTYPE_BUNDLE_AGE = 7,
|
||||
/// Hop Count
|
||||
BP_BLOCKTYPE_HOP_COUNT = 10,
|
||||
/// Block Integrity Block
|
||||
BP_BLOCKTYPE_BIB = 11,
|
||||
/// Block Confidentiality Block
|
||||
BP_BLOCKTYPE_BCB = 12,
|
||||
} BlockTypeCode;
|
||||
|
||||
/** Administrative record type codes.
|
||||
* Section 6.1.
|
||||
*/
|
||||
typedef enum {
|
||||
/// Bundle status report
|
||||
BP_ADMINTYPE_BUNDLE_STATUS = 1,
|
||||
} AdminRecordTypeCode;
|
||||
|
||||
/// DTN time with derived UTC time
|
||||
typedef struct {
|
||||
/// DTN time
|
||||
guint64 dtntime;
|
||||
/// Converted to UTC
|
||||
nstime_t utctime;
|
||||
} bp_dtn_time_t;
|
||||
|
||||
/// Creation Timestamp used to correlate bundles
|
||||
typedef struct {
|
||||
/// Absolute time
|
||||
bp_dtn_time_t abstime;
|
||||
/// Sequence number
|
||||
guint64 seqno;
|
||||
} bp_creation_ts_t;
|
||||
|
||||
/** Construct a new timestamp.
|
||||
*/
|
||||
WS_DLL_PUBLIC
|
||||
bp_creation_ts_t * bp_creation_ts_alloc(wmem_allocator_t *alloc);
|
||||
|
||||
/** Function to match the GDestroyNotify signature.
|
||||
*/
|
||||
WS_DLL_PUBLIC
|
||||
void bp_creation_ts_free(wmem_allocator_t *alloc, bp_creation_ts_t *obj);
|
||||
|
||||
/** Function to match the GCompareDataFunc signature.
|
||||
*/
|
||||
WS_DLL_PUBLIC
|
||||
gint bp_creation_ts_compare(gconstpointer a, gconstpointer b, gpointer user_data);
|
||||
|
||||
/** Endpoint ID scheme encodings.
|
||||
*/
|
||||
typedef enum {
|
||||
EID_SCHEME_DTN = 1,
|
||||
EID_SCHEME_IPN = 2,
|
||||
} EidScheme;
|
||||
|
||||
/// Metadata from a Endpoint ID
|
||||
typedef struct {
|
||||
/// Scheme ID number
|
||||
gint64 scheme;
|
||||
/// Derived URI text
|
||||
const char *uri;
|
||||
|
||||
/// Optional DTN well-known SSP
|
||||
const char *dtn_wkssp;
|
||||
/// Optional URI authority part
|
||||
// const char *node_name;
|
||||
/// Optional DTN service name
|
||||
const char *dtn_serv;
|
||||
} bp_eid_t;
|
||||
|
||||
/** Construct a new timestamp.
|
||||
*/
|
||||
WS_DLL_PUBLIC
|
||||
bp_eid_t * bp_eid_new(wmem_allocator_t *alloc);
|
||||
|
||||
/** Function to match the GDestroyNotify signature.
|
||||
*/
|
||||
WS_DLL_PUBLIC
|
||||
void bp_eid_free(wmem_allocator_t *alloc, bp_eid_t *obj);
|
||||
|
||||
/** Function to match the GCompareFunc signature.
|
||||
*/
|
||||
WS_DLL_PUBLIC
|
||||
gboolean bp_eid_equal(gconstpointer a, gconstpointer b);
|
||||
|
||||
/// Security marking metadata
|
||||
typedef struct {
|
||||
/// Block numbers marking the data as security integrity protected
|
||||
wmem_map_t *data_i;
|
||||
/// Block numbers marking the data as security-modified and not decodable
|
||||
wmem_map_t *data_c;
|
||||
} security_mark_t;
|
||||
|
||||
/// Metadata extracted from the primary block
|
||||
typedef struct {
|
||||
/// Display item for the whole block
|
||||
proto_item *item_block;
|
||||
|
||||
/// Bundle flags (assumed zero).
|
||||
/// Values are BundleProcessingFlag.
|
||||
guint64 flags;
|
||||
/// Destination EID
|
||||
bp_eid_t *dst_eid;
|
||||
/// Source NID
|
||||
bp_eid_t *src_nodeid;
|
||||
/// Report-to NID
|
||||
bp_eid_t *rep_nodeid;
|
||||
/// Creation Timestamp
|
||||
bp_creation_ts_t ts;
|
||||
/// Optional fragment start offset
|
||||
guint64 *frag_offset;
|
||||
/// Optional bundle total length
|
||||
guint64 *total_len;
|
||||
/// CRC type code (assumed zero)
|
||||
BundleCrcType crc_type;
|
||||
/// Raw bytes of CRC field
|
||||
tvbuff_t *crc_field;
|
||||
|
||||
security_mark_t sec;
|
||||
} bp_block_primary_t;
|
||||
|
||||
/** Construct a new object on the file allocator.
|
||||
*/
|
||||
WS_DLL_PUBLIC
|
||||
bp_block_primary_t * bp_block_primary_new(wmem_allocator_t *alloc);
|
||||
|
||||
/** Function to match the GDestroyNotify signature.
|
||||
*/
|
||||
WS_DLL_PUBLIC
|
||||
void bp_block_primary_free(wmem_allocator_t *alloc, bp_block_primary_t *obj);
|
||||
|
||||
typedef struct {
|
||||
/// The index of the block within the bundle.
|
||||
/// This is for internal bookkeeping, *not* the block number.
|
||||
guint64 blk_ix;
|
||||
/// Display item for the whole block
|
||||
proto_item *item_block;
|
||||
|
||||
/// Type of this block
|
||||
guint64 *type_code;
|
||||
/// Unique identifier for this block
|
||||
guint64 *block_number;
|
||||
/// All flags on this block
|
||||
guint64 flags;
|
||||
/// CRC type code (assumed zero)
|
||||
BundleCrcType crc_type;
|
||||
/// Raw bytes of CRC field
|
||||
tvbuff_t *crc_field;
|
||||
|
||||
/// Type-specific data, unencoded
|
||||
tvbuff_t *data;
|
||||
/// Type-specific data tree
|
||||
proto_tree *tree_data;
|
||||
|
||||
security_mark_t sec;
|
||||
} bp_block_canonical_t;
|
||||
|
||||
/** Construct a new object on the file allocator.
|
||||
* @param blk_ix The index of the block within the bundle.
|
||||
* The canonical index is always greater than zero.
|
||||
*/
|
||||
WS_DLL_PUBLIC
|
||||
bp_block_canonical_t * bp_block_canonical_new(wmem_allocator_t *alloc, guint64 blk_ix);
|
||||
|
||||
WS_DLL_PUBLIC
|
||||
void bp_block_canonical_delete(wmem_allocator_t *alloc, bp_block_canonical_t *obj);
|
||||
|
||||
/// Identification of an individual bundle
|
||||
typedef struct {
|
||||
/// Normalized EID URI for the Source Node ID
|
||||
const char *src;
|
||||
/// Pointer to an external Creation Timestamp
|
||||
bp_creation_ts_t *ts;
|
||||
/// Pointer to external optional fragment start offset
|
||||
guint64 *frag_offset;
|
||||
/// Pointer to external optional bundle total length
|
||||
guint64 *total_len;
|
||||
} bp_bundle_ident_t;
|
||||
|
||||
/** Construct a new object on the file allocator.
|
||||
*/
|
||||
WS_DLL_PUBLIC
|
||||
bp_bundle_ident_t * bp_bundle_ident_new(wmem_allocator_t *alloc, bp_eid_t *src, bp_creation_ts_t *ts, guint64 *off, guint64 *len);
|
||||
|
||||
WS_DLL_PUBLIC
|
||||
void bp_bundle_ident_free(wmem_allocator_t *alloc, bp_bundle_ident_t *obj);
|
||||
|
||||
/** Function to match the GCompareFunc signature.
|
||||
*/
|
||||
WS_DLL_PUBLIC
|
||||
gboolean bp_bundle_ident_equal(gconstpointer a, gconstpointer b);
|
||||
|
||||
/** Function to match the GHashFunc signature.
|
||||
*/
|
||||
WS_DLL_PUBLIC
|
||||
guint bp_bundle_ident_hash(gconstpointer key);
|
||||
|
||||
/// Metadata extracted per-bundle
|
||||
typedef struct {
|
||||
/// Index of the frame
|
||||
guint32 frame_num;
|
||||
/// Timestamp on the frame (end time if reassembled)
|
||||
nstime_t frame_time;
|
||||
/// Bundle identity derived from #primary data
|
||||
bp_bundle_ident_t *ident;
|
||||
/// Required primary block
|
||||
bp_block_primary_t *primary;
|
||||
/// Additional blocks in order (type bp_block_canonical_t)
|
||||
wmem_list_t *blocks;
|
||||
/// Map from block number (guint64) to pointer to block of that number
|
||||
/// (bp_block_canonical_t owned by #blocks)
|
||||
wmem_map_t *block_nums;
|
||||
/// Map from block type code (guint64) to sequence (wmem_list_t) of
|
||||
/// pointers to block of that type (bp_block_canonical_t owned by #blocks)
|
||||
wmem_map_t *block_types;
|
||||
} bp_bundle_t;
|
||||
|
||||
/** Construct a new object on the file allocator.
|
||||
*/
|
||||
WS_DLL_PUBLIC
|
||||
bp_bundle_t * bp_bundle_new(wmem_allocator_t *alloc);
|
||||
|
||||
/** Function to match the GDestroyNotify signature.
|
||||
*/
|
||||
WS_DLL_PUBLIC
|
||||
void bp_bundle_free(wmem_allocator_t *alloc, bp_bundle_t *obj);
|
||||
|
||||
/** Extract an Endpoint ID.
|
||||
* All EID fields are allocated with wmem_file_scope().
|
||||
*
|
||||
* @param tree The tree to write items under.
|
||||
* @param hfindex The root item field.
|
||||
* @param hfindex_uri The reassembled URI item field.
|
||||
* @param pinfo Packet info to update.
|
||||
* @param tvb Buffer to read from.
|
||||
* @param[in,out] offset Starting offset within @c tvb.
|
||||
* @param[out] eid If non-null, the EID to write to.
|
||||
* @return The new tree item.
|
||||
*/
|
||||
WS_DLL_PUBLIC
|
||||
proto_item * proto_tree_add_cbor_eid(proto_tree *tree, int hfindex, int hfindex_uri, packet_info *pinfo, tvbuff_t *tvb, gint *offset, bp_eid_t *eid);
|
||||
|
||||
/// Metadata for an entire file
|
||||
typedef struct {
|
||||
/// Map from a bundle ID (bp_bundle_ident_t) to bundle (bp_bundle_t)
|
||||
wmem_map_t *bundles;
|
||||
/// Map from subject bundle ID (bp_bundle_ident_t) to
|
||||
/// map from references (bp_bundle_ident_t) of status bundles to NULL
|
||||
/// i.e. a set
|
||||
wmem_map_t *admin_status;
|
||||
} bp_history_t;
|
||||
|
||||
/** Data supplied to each block sub-dissector.
|
||||
*/
|
||||
typedef struct {
|
||||
/// The overall bundle being decoded (so far)
|
||||
bp_bundle_t *bundle;
|
||||
/// This block being decoded
|
||||
bp_block_canonical_t *block;
|
||||
} bp_dissector_data_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PACKET_BPV7_H */
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include <epan/packet.h>
|
||||
#include <epan/expert.h>
|
||||
#include "packet-dtn.h"
|
||||
#include "packet-cfdp.h"
|
||||
|
||||
/* The CFDP standard can be found here:
|
||||
* http://public.ccsds.org/publications/archive/727x0b4.pdf
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/* packet-cfdp.c
|
||||
* Routines for CCSDS File Delivery Protocol (CFDP) dissection
|
||||
* Copyright 2013, Juan Antonio Montesinos juan.mondl@gmail.com
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* Slightly updated to allow more in-depth decoding when called
|
||||
* with the 'dissect_as_subtree' method and to leverage some
|
||||
* of the bitfield display operations: Keith Scott
|
||||
* <kscott@mitre.org>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef PACKET_CFDP_H
|
||||
#define PACKET_CFDP_H
|
||||
|
||||
#include <ws_symbol_export.h>
|
||||
#include <epan/tvbuff.h>
|
||||
#include <epan/proto.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void dissect_cfdp_as_subtree(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PACKET_CFDP_H */
|
||||
|
||||
/*
|
||||
* Editor modelines - https://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
* Local variables:
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* vi: set shiftwidth=4 tabstop=8 expandtab:
|
||||
* :indentSize=4:tabSize=8:noTabs=true:
|
||||
*/
|
|
@ -36,7 +36,7 @@
|
|||
#include <epan/expert.h>
|
||||
#include <epan/reassemble.h>
|
||||
|
||||
#include "packet-dtn.h"
|
||||
#include "packet-bpv6.h"
|
||||
|
||||
void proto_register_ltp(void);
|
||||
void proto_reg_handoff_ltp(void);
|
||||
|
|
|
@ -0,0 +1,775 @@
|
|||
/* packet-tcpclv3.c
|
||||
* References:
|
||||
* RFC 7242: https://tools.ietf.org/html/rfc7242
|
||||
*
|
||||
* Copyright 2006-2007 The MITRE Corporation.
|
||||
* All Rights Reserved.
|
||||
* Approved for Public Release; Distribution Unlimited.
|
||||
* Tracking Number 07-0090.
|
||||
*
|
||||
* The US Government will not be charged any license fee and/or royalties
|
||||
* related to this software. Neither name of The MITRE Corporation; nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*
|
||||
* Specification reference:
|
||||
* RFC 5050
|
||||
* https://tools.ietf.org/html/rfc5050
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modifications were made to this file under designation MFS-33289-1 and
|
||||
* are Copyright 2015 United States Government as represented by NASA
|
||||
* Marshall Space Flight Center. All Rights Reserved.
|
||||
*
|
||||
* Released under the GNU GPL with NASA legal approval granted 2016-06-10.
|
||||
*
|
||||
* The subject software is provided "AS IS" WITHOUT ANY WARRANTY of any kind,
|
||||
* either expressed, implied or statutory and this agreement does not,
|
||||
* in any manner, constitute an endorsement by government agency of any
|
||||
* results, designs or products resulting from use of the subject software.
|
||||
* See the Agreement for the specific language governing permissions and
|
||||
* limitations.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <epan/packet.h>
|
||||
#include <epan/reassemble.h>
|
||||
#include <epan/expert.h>
|
||||
#include "packet-tcpclv3.h"
|
||||
#include "packet-bpv6.h"
|
||||
#include "packet-tcp.h"
|
||||
|
||||
/* For Reassembling TCP Convergence Layer segments */
|
||||
static reassembly_table msg_reassembly_table;
|
||||
|
||||
static const char magic[] = {'d', 't', 'n', '!'};
|
||||
|
||||
static int proto_tcp_conv = -1;
|
||||
|
||||
/* TCP Convergence Header Variables */
|
||||
static int hf_tcp_convergence_pkt_type = -1;
|
||||
|
||||
/* Refuse-Bundle reason code */
|
||||
static int hf_dtn_refuse_bundle_reason_code = -1;
|
||||
|
||||
static int hf_contact_hdr_version = -1;
|
||||
static int hf_contact_hdr_flags = -1;
|
||||
static int hf_contact_hdr_keep_alive = -1;
|
||||
static int hf_contact_hdr_flags_ack_req = -1;
|
||||
static int hf_contact_hdr_flags_frag_enable = -1;
|
||||
static int hf_contact_hdr_flags_nak = -1;
|
||||
static int hf_contact_hdr_magic = -1;
|
||||
static int hf_contact_hdr_local_eid_length = -1;
|
||||
static int hf_contact_hdr_local_eid = -1;
|
||||
|
||||
/* TCP Convergence Data Header Variables */
|
||||
static int hf_tcp_convergence_data_procflags = -1;
|
||||
static int hf_tcp_convergence_data_procflags_start = -1;
|
||||
static int hf_tcp_convergence_data_procflags_end = -1;
|
||||
static int hf_tcp_convergence_data_segment_length = -1;
|
||||
|
||||
/* TCP Convergence Ack Variables */
|
||||
static int hf_tcp_convergence_ack_length = -1;
|
||||
|
||||
/* TCP Convergence Shutdown Header Variables */
|
||||
static int hf_tcp_convergence_shutdown_flags = -1;
|
||||
static int hf_tcp_convergence_shutdown_flags_reason = -1;
|
||||
static int hf_tcp_convergence_shutdown_flags_delay = -1;
|
||||
static int hf_tcp_convergence_shutdown_reason = -1;
|
||||
static int hf_tcp_convergence_shutdown_delay = -1;
|
||||
|
||||
/*TCP Convergence Layer Reassembly boilerplate*/
|
||||
static int hf_msg_fragments = -1;
|
||||
static int hf_msg_fragment = -1;
|
||||
static int hf_msg_fragment_overlap = -1;
|
||||
static int hf_msg_fragment_overlap_conflicts = -1;
|
||||
static int hf_msg_fragment_multiple_tails = -1;
|
||||
static int hf_msg_fragment_too_long_fragment = -1;
|
||||
static int hf_msg_fragment_error = -1;
|
||||
static int hf_msg_fragment_count = -1;
|
||||
static int hf_msg_reassembled_in = -1;
|
||||
static int hf_msg_reassembled_length = -1;
|
||||
|
||||
/* Tree Node Variables */
|
||||
static gint ett_conv_flags = -1;
|
||||
static gint ett_shutdown_flags = -1;
|
||||
static gint ett_contact_hdr_flags = -1;
|
||||
static gint ett_tcp_conv = -1;
|
||||
static gint ett_tcp_conv_hdr = -1;
|
||||
static gint ett_msg_fragment = -1;
|
||||
static gint ett_msg_fragments = -1;
|
||||
|
||||
static expert_field ei_tcp_convergence_data_flags = EI_INIT;
|
||||
static expert_field ei_tcp_convergence_segment_length = EI_INIT;
|
||||
static expert_field ei_tcp_convergence_ack_length = EI_INIT;
|
||||
|
||||
|
||||
static dissector_handle_t bundle_handle;
|
||||
|
||||
typedef struct dictionary_data {
|
||||
int bundle_header_dict_length;
|
||||
|
||||
int dest_scheme_offset;
|
||||
int dst_scheme_pos;
|
||||
int dst_scheme_len;
|
||||
int source_scheme_offset;
|
||||
int src_scheme_pos;
|
||||
int src_scheme_len;
|
||||
int report_scheme_offset;
|
||||
int rpt_scheme_pos;
|
||||
int rpt_scheme_len;
|
||||
int cust_scheme_offset;
|
||||
int cust_scheme_pos;
|
||||
int cust_scheme_len;
|
||||
int dest_ssp_offset;
|
||||
int dst_ssp_len;
|
||||
int source_ssp_offset;
|
||||
int src_ssp_len;
|
||||
int report_ssp_offset;
|
||||
int rpt_ssp_len;
|
||||
int cust_ssp_offset;
|
||||
int cust_ssp_len;
|
||||
|
||||
} dictionary_data_t;
|
||||
|
||||
|
||||
static const value_string packet_type_vals[] = {
|
||||
{((TCP_CONVERGENCE_DATA_SEGMENT>>4) & 0x0F), "Data"},
|
||||
{((TCP_CONVERGENCE_ACK_SEGMENT>>4) & 0x0F), "Ack"},
|
||||
{((TCP_CONVERGENCE_REFUSE_BUNDLE>>4) & 0x0F), "Refuse Bundle"},
|
||||
{((TCP_CONVERGENCE_KEEP_ALIVE>>4) & 0x0F), "Keep Alive"},
|
||||
{((TCP_CONVERGENCE_SHUTDOWN>>4) & 0x0F), "Shutdown"},
|
||||
{((TCP_CONVERGENCE_LENGTH>>4) & 0x0F), "Length"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
/* Refuse-Bundle Reason-Code Flags as per RFC-7242: Section-5.4 */
|
||||
static const value_string refuse_bundle_reason_code[] = {
|
||||
{TCP_REFUSE_BUNDLE_REASON_UNKNOWN, "Reason for refusal is unknown"},
|
||||
{TCP_REFUSE_BUNDLE_REASON_RX_COMPLETE, "Complete Bundle Received"},
|
||||
{TCP_REFUSE_BUNDLE_REASON_RX_EXHAUSTED, "Receiver's resources exhausted"},
|
||||
{TCP_REFUSE_BUNDLE_REASON_RX_RETRANSMIT, "Receiver expects re-transmission of bundle"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
static const fragment_items msg_frag_items = {
|
||||
/*Fragment subtrees*/
|
||||
&ett_msg_fragment,
|
||||
&ett_msg_fragments,
|
||||
/*Fragment Fields*/
|
||||
&hf_msg_fragments,
|
||||
&hf_msg_fragment,
|
||||
&hf_msg_fragment_overlap,
|
||||
&hf_msg_fragment_overlap_conflicts,
|
||||
&hf_msg_fragment_multiple_tails,
|
||||
&hf_msg_fragment_too_long_fragment,
|
||||
&hf_msg_fragment_error,
|
||||
&hf_msg_fragment_count,
|
||||
/*Reassembled in field*/
|
||||
&hf_msg_reassembled_in,
|
||||
/*Reassembled length field*/
|
||||
&hf_msg_reassembled_length,
|
||||
/* Reassembled data field */
|
||||
NULL,
|
||||
/*Tag*/
|
||||
"Message fragments"
|
||||
};
|
||||
|
||||
static guint
|
||||
get_dtn_contact_header_len(packet_info *pinfo _U_, tvbuff_t *tvb,
|
||||
int offset, void *data _U_)
|
||||
{
|
||||
int len, bytecount;
|
||||
|
||||
/* get length from sdnv */
|
||||
len = evaluate_sdnv(tvb, offset+8, &bytecount);
|
||||
if (len < 0)
|
||||
return 0;
|
||||
|
||||
return len+bytecount+8;
|
||||
}
|
||||
|
||||
static int
|
||||
dissect_dtn_contact_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
|
||||
{
|
||||
proto_item *ti;
|
||||
proto_tree *conv_proto_tree, *conv_tree, *conv_flag_tree;
|
||||
int eid_length, sdnv_length;
|
||||
int offset = 0;
|
||||
|
||||
col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCPCLv3");
|
||||
col_clear(pinfo->cinfo,COL_INFO); /* Clear out stuff in the info column */
|
||||
col_add_str(pinfo->cinfo, COL_INFO, "Contact Header");
|
||||
|
||||
ti = proto_tree_add_item(tree, proto_tcp_conv, tvb, offset, -1, ENC_NA);
|
||||
conv_proto_tree = proto_item_add_subtree(ti, ett_tcp_conv);
|
||||
|
||||
conv_tree = proto_tree_add_subtree(conv_proto_tree, tvb, offset, -1, ett_tcp_conv, NULL, "Contact Header");
|
||||
|
||||
proto_tree_add_item(conv_tree, hf_contact_hdr_magic, tvb, offset, 4, ENC_NA|ENC_ASCII);
|
||||
offset += 4;
|
||||
proto_tree_add_item(conv_tree, hf_contact_hdr_version, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||
offset++;
|
||||
|
||||
/* Subtree to expand the bits in the Contact Header Flags */
|
||||
ti = proto_tree_add_item(conv_tree, hf_contact_hdr_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||
conv_flag_tree = proto_item_add_subtree(ti, ett_contact_hdr_flags);
|
||||
proto_tree_add_item(conv_flag_tree, hf_contact_hdr_flags_ack_req, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||
proto_tree_add_item(conv_flag_tree, hf_contact_hdr_flags_frag_enable, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||
proto_tree_add_item(conv_flag_tree, hf_contact_hdr_flags_nak, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||
offset++;
|
||||
|
||||
proto_tree_add_item(conv_tree, hf_contact_hdr_keep_alive, tvb, offset, 2, ENC_BIG_ENDIAN);
|
||||
offset += 2;
|
||||
|
||||
/*
|
||||
* New format Contact header has length field followed by Bundle Header.
|
||||
*/
|
||||
expert_field *ei_bundle_sdnv_length;
|
||||
eid_length = evaluate_sdnv_ei(tvb, offset, &sdnv_length, &ei_bundle_sdnv_length);
|
||||
ti = proto_tree_add_int(tree, hf_contact_hdr_local_eid_length, tvb, offset, sdnv_length, eid_length);
|
||||
if (ei_bundle_sdnv_length) {
|
||||
expert_add_info(pinfo, ti, ei_bundle_sdnv_length);
|
||||
return offset;
|
||||
}
|
||||
|
||||
proto_tree_add_item(conv_tree, hf_contact_hdr_local_eid, tvb, sdnv_length + offset, eid_length, ENC_NA|ENC_ASCII);
|
||||
return tvb_captured_length(tvb);
|
||||
}
|
||||
|
||||
static guint
|
||||
get_tcpcl_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
|
||||
{
|
||||
int len, bytecount;
|
||||
guint8 conv_hdr = tvb_get_guint8(tvb, offset);
|
||||
|
||||
switch (conv_hdr & TCP_CONVERGENCE_TYPE_MASK)
|
||||
{
|
||||
case TCP_CONVERGENCE_DATA_SEGMENT:
|
||||
/* get length from sdnv */
|
||||
len = evaluate_sdnv(tvb, offset+1, &bytecount);
|
||||
if (len < 0)
|
||||
return 0;
|
||||
|
||||
return len+bytecount+1;
|
||||
|
||||
case TCP_CONVERGENCE_ACK_SEGMENT:
|
||||
/* get length from sdnv */
|
||||
len = evaluate_sdnv(tvb, offset+1, &bytecount);
|
||||
if (len < 0)
|
||||
return 0;
|
||||
|
||||
return bytecount+1;
|
||||
|
||||
case TCP_CONVERGENCE_KEEP_ALIVE:
|
||||
case TCP_CONVERGENCE_REFUSE_BUNDLE:
|
||||
/* always 1 byte */
|
||||
return 1;
|
||||
case TCP_CONVERGENCE_SHUTDOWN:
|
||||
len = 1;
|
||||
|
||||
if (conv_hdr & TCP_CONVERGENCE_SHUTDOWN_REASON) {
|
||||
len += 1;
|
||||
}
|
||||
if (conv_hdr & TCP_CONVERGENCE_SHUTDOWN_DELAY) {
|
||||
len += 2;
|
||||
}
|
||||
|
||||
return len;
|
||||
|
||||
case TCP_CONVERGENCE_LENGTH:
|
||||
/* get length from sdnv */
|
||||
len = evaluate_sdnv(tvb, offset+1, &bytecount);
|
||||
if (len < 0)
|
||||
return 0;
|
||||
return bytecount+1;
|
||||
|
||||
}
|
||||
|
||||
/* This probably isn't a TCPCL/Bundle packet, so just stop dissection */
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
dissect_tcpcl_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
|
||||
{
|
||||
guint8 conv_hdr;
|
||||
guint8 refuse_bundle_hdr;
|
||||
int offset = 0;
|
||||
int sdnv_length, segment_length, convergence_hdr_size;
|
||||
proto_item *ci, *sub_item;
|
||||
proto_tree *conv_proto_tree, *conv_tree, *sub_tree;
|
||||
fragment_head *frag_msg;
|
||||
tvbuff_t *new_tvb;
|
||||
gboolean more_frags;
|
||||
int processed_length = 0;
|
||||
const gchar* col_text;
|
||||
gboolean bundle_in_col_info;
|
||||
|
||||
static guint32 frag_id = 0;
|
||||
static guint32 last_frame = 0;
|
||||
static int last_raw_offset = 0;
|
||||
|
||||
if (last_frame != pinfo->fd->num || tvb_raw_offset(tvb) < last_raw_offset)
|
||||
frag_id = 0;
|
||||
last_frame = pinfo->fd->num;
|
||||
last_raw_offset = tvb_raw_offset(tvb);
|
||||
|
||||
col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCPCL");
|
||||
col_clear(pinfo->cinfo,COL_INFO); /* Clear out stuff in the info column */
|
||||
|
||||
col_text = col_get_text(pinfo->cinfo, COL_INFO);
|
||||
bundle_in_col_info = (col_text && strstr(col_text, " > "));
|
||||
|
||||
ci = proto_tree_add_item(tree, proto_tcp_conv, tvb, offset, -1, ENC_NA);
|
||||
conv_proto_tree = proto_item_add_subtree(ci, ett_tcp_conv);
|
||||
|
||||
conv_tree = proto_tree_add_subtree(conv_proto_tree, tvb, 0, -1, ett_tcp_conv_hdr, NULL, "TCP Convergence Header");
|
||||
|
||||
conv_hdr = tvb_get_guint8(tvb, offset);
|
||||
proto_tree_add_item(conv_tree, hf_tcp_convergence_pkt_type, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||
col_add_str(pinfo->cinfo, COL_INFO, val_to_str_const((conv_hdr>>4)&0xF, packet_type_vals, "Unknown"));
|
||||
|
||||
switch (conv_hdr & TCP_CONVERGENCE_TYPE_MASK)
|
||||
{
|
||||
case TCP_CONVERGENCE_DATA_SEGMENT:
|
||||
sub_item = proto_tree_add_item(conv_tree, hf_tcp_convergence_data_procflags, tvb,
|
||||
offset, 1, ENC_BIG_ENDIAN);
|
||||
sub_tree = proto_item_add_subtree(sub_item, ett_conv_flags);
|
||||
proto_tree_add_item(sub_tree, hf_tcp_convergence_data_procflags_start,
|
||||
tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||
proto_tree_add_item(sub_tree, hf_tcp_convergence_data_procflags_end,
|
||||
tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||
|
||||
/* Only Start and End flags (bits 0 & 1) are valid in Data Segment */
|
||||
if ((conv_hdr & ~(TCP_CONVERGENCE_TYPE_MASK | TCP_CONVERGENCE_DATA_FLAGS)) != 0) {
|
||||
expert_add_info(pinfo, sub_item, &ei_tcp_convergence_data_flags);
|
||||
}
|
||||
|
||||
segment_length = evaluate_sdnv(tvb, 1, &sdnv_length);
|
||||
sub_item = proto_tree_add_int(conv_tree, hf_tcp_convergence_data_segment_length, tvb, 1, sdnv_length, segment_length);
|
||||
if (segment_length < 0) {
|
||||
expert_add_info(pinfo, sub_item, &ei_tcp_convergence_segment_length);
|
||||
return 1;
|
||||
}
|
||||
|
||||
convergence_hdr_size = sdnv_length + 1;
|
||||
|
||||
/*
|
||||
* 1/11/2006 - If I got here, I should have a complete convergence layer
|
||||
* "segment" beginning at frame_offset. However that might not be a
|
||||
* complete bundle. Or there might be a complete bundle plus one or more
|
||||
* additional convergence layer headers.
|
||||
*/
|
||||
|
||||
new_tvb = NULL;
|
||||
sub_tree = NULL;
|
||||
if ((conv_hdr & TCP_CONVERGENCE_DATA_END_FLAG) == TCP_CONVERGENCE_DATA_END_FLAG) {
|
||||
more_frags = FALSE;
|
||||
}
|
||||
else {
|
||||
more_frags = TRUE;
|
||||
}
|
||||
|
||||
frag_msg = fragment_add_seq_next(&msg_reassembly_table,
|
||||
tvb, offset + convergence_hdr_size,
|
||||
pinfo, frag_id, data,
|
||||
segment_length, more_frags);
|
||||
|
||||
if (!more_frags) ++frag_id;
|
||||
|
||||
processed_length = convergence_hdr_size + segment_length;
|
||||
|
||||
if (frag_msg && !more_frags) {
|
||||
|
||||
int save_fd_head_layer = frag_msg->reas_in_layer_num;
|
||||
frag_msg->reas_in_layer_num = pinfo->curr_layer_num;
|
||||
|
||||
new_tvb = process_reassembled_data(tvb, offset + convergence_hdr_size,
|
||||
pinfo, "Reassembled DTN", frag_msg,
|
||||
&msg_frag_items, NULL,
|
||||
proto_tree_get_parent_tree(tree)
|
||||
);
|
||||
|
||||
frag_msg->reas_in_layer_num = save_fd_head_layer;
|
||||
}
|
||||
|
||||
if (new_tvb) {
|
||||
if (0 == call_dissector_with_data(bundle_handle, new_tvb, pinfo, sub_tree, data)) {
|
||||
/*Couldn't parse bundle, treat as raw data */
|
||||
call_data_dissector(new_tvb, pinfo, sub_tree);
|
||||
return tvb_captured_length(tvb);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
/*
|
||||
* If there are 2 segments, the second of which is very short, this
|
||||
* gets displayed instead of the usual Source EID/Destination EID in
|
||||
* the Bundle Dissection frame. If these statements are left out entirely,
|
||||
* nothing is displayed, i.e., there seems to be no way to get the
|
||||
* Source/Destination in the 2-segment case. I'll leave it in because I
|
||||
* think it is informative in the multi-segment case although confusing in the
|
||||
* 2-segment case.
|
||||
*/
|
||||
col_add_str(pinfo->cinfo, COL_INFO, "[Bundle TCPCL Segment]");
|
||||
}
|
||||
break;
|
||||
case TCP_CONVERGENCE_ACK_SEGMENT:
|
||||
if (bundle_in_col_info) {
|
||||
if (!strstr(col_text, ", TCPL ACK")) {
|
||||
col_add_str(pinfo->cinfo, COL_INFO, ", TCPL ACK Segment(s)");
|
||||
}
|
||||
} else {
|
||||
col_set_str(pinfo->cinfo, COL_INFO, "TCPL ACK Segment(s)");
|
||||
}
|
||||
segment_length = evaluate_sdnv(tvb, offset+1, &sdnv_length);
|
||||
sub_item = proto_tree_add_int(conv_tree, hf_tcp_convergence_ack_length, tvb, offset+1, sdnv_length, segment_length);
|
||||
if (segment_length < 0) {
|
||||
expert_add_info(pinfo, sub_item, &ei_tcp_convergence_ack_length);
|
||||
processed_length = tvb_captured_length(tvb);
|
||||
} else {
|
||||
processed_length = sdnv_length + 1;
|
||||
}
|
||||
break;
|
||||
case TCP_CONVERGENCE_KEEP_ALIVE:
|
||||
if (bundle_in_col_info) {
|
||||
if (!strstr(col_text, ", TCPL KEEPALIVE")) {
|
||||
col_add_str(pinfo->cinfo, COL_INFO, ", TCPL KEEPALIVE Segment");
|
||||
}
|
||||
} else {
|
||||
col_set_str(pinfo->cinfo, COL_INFO, "TCPL KEEPALIVE Segment");
|
||||
}
|
||||
/*No valid flags in Keep Alive*/
|
||||
processed_length = 1;
|
||||
break;
|
||||
|
||||
case TCP_CONVERGENCE_SHUTDOWN:
|
||||
if (bundle_in_col_info) {
|
||||
if (!strstr(col_text, ", TCPL SHUTDOWN")) {
|
||||
col_add_str(pinfo->cinfo, COL_INFO, ", TCPL SHUTDOWN Segment");
|
||||
}
|
||||
} else {
|
||||
col_set_str(pinfo->cinfo, COL_INFO, "TCPL SHUTDOWN Segment");
|
||||
}
|
||||
/* Add tree for Shutdown Flags */
|
||||
sub_item = proto_tree_add_item(conv_tree, hf_tcp_convergence_shutdown_flags, tvb,
|
||||
offset, 1, ENC_BIG_ENDIAN);
|
||||
sub_tree = proto_item_add_subtree(sub_item, ett_shutdown_flags);
|
||||
|
||||
proto_tree_add_item(sub_tree, hf_tcp_convergence_shutdown_flags_reason,
|
||||
tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||
proto_tree_add_item(sub_tree, hf_tcp_convergence_shutdown_flags_delay,
|
||||
tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||
|
||||
offset += 1;
|
||||
if (conv_hdr & TCP_CONVERGENCE_SHUTDOWN_REASON) {
|
||||
proto_tree_add_item(conv_tree,
|
||||
hf_tcp_convergence_shutdown_reason, tvb,
|
||||
offset, 1, ENC_BIG_ENDIAN);
|
||||
offset += 1;
|
||||
}
|
||||
if (conv_hdr & TCP_CONVERGENCE_SHUTDOWN_DELAY) {
|
||||
proto_tree_add_item(conv_tree,
|
||||
hf_tcp_convergence_shutdown_delay, tvb,
|
||||
offset, 2, ENC_BIG_ENDIAN);
|
||||
}
|
||||
break;
|
||||
case TCP_CONVERGENCE_REFUSE_BUNDLE:
|
||||
if (bundle_in_col_info) {
|
||||
if (!strstr(col_text, ", TCPL REFUSE")) {
|
||||
col_add_str(pinfo->cinfo, COL_INFO, ", TCPL REFUSE_BUNDLE Segment");
|
||||
}
|
||||
} else {
|
||||
col_set_str(pinfo->cinfo, COL_INFO, "TCPL REFUSE_BUNDLE Segment");
|
||||
}
|
||||
|
||||
refuse_bundle_hdr = tvb_get_guint8(tvb, offset);
|
||||
proto_tree_add_item(conv_tree, hf_dtn_refuse_bundle_reason_code, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||
col_add_str(pinfo->cinfo, COL_INFO, val_to_str_const((refuse_bundle_hdr>>4)&0xF, refuse_bundle_reason_code, "Unknown"));
|
||||
|
||||
/*No valid flags*/
|
||||
processed_length = tvb_captured_length(tvb);
|
||||
break;
|
||||
}
|
||||
|
||||
return processed_length;
|
||||
}
|
||||
|
||||
static int
|
||||
dissect_tcpcl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
|
||||
{
|
||||
guint8 conv_hdr;
|
||||
int offset, bytecount;
|
||||
int processed_length;
|
||||
|
||||
/* Make sure we have a convergence header byte */
|
||||
if (!tvb_bytes_exist(tvb, 0, 1))
|
||||
return 0;
|
||||
|
||||
conv_hdr = tvb_get_guint8(tvb, 0);
|
||||
switch (conv_hdr & TCP_CONVERGENCE_TYPE_MASK)
|
||||
{
|
||||
case TCP_CONVERGENCE_DATA_SEGMENT:
|
||||
case TCP_CONVERGENCE_ACK_SEGMENT:
|
||||
/* ensure sdnv */
|
||||
offset = 1;
|
||||
bytecount = 1;
|
||||
|
||||
if (!tvb_bytes_exist(tvb, offset, 1)) {
|
||||
pinfo->desegment_offset = 0;
|
||||
pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (tvb_get_guint8(tvb, offset) & ~SDNV_MASK) {
|
||||
if (bytecount > (int)sizeof(int)) {
|
||||
/* invalid length field */
|
||||
return 0;
|
||||
}
|
||||
|
||||
bytecount++;
|
||||
offset++;
|
||||
|
||||
if (!tvb_bytes_exist(tvb, offset, 1)) {
|
||||
pinfo->desegment_offset = 0;
|
||||
pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TCP_CONVERGENCE_KEEP_ALIVE:
|
||||
case TCP_CONVERGENCE_REFUSE_BUNDLE:
|
||||
/* always 1 byte */
|
||||
break;
|
||||
case TCP_CONVERGENCE_SHUTDOWN:
|
||||
if ((conv_hdr &
|
||||
~(TCP_CONVERGENCE_TYPE_MASK | TCP_CONVERGENCE_SHUTDOWN_FLAGS)) != 0) {
|
||||
/* Not for us */
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (conv_hdr == (guint8)magic[0]) {
|
||||
if (!tvb_bytes_exist(tvb, 0, 4) || tvb_memeql(tvb, 0, magic, 4)) {
|
||||
/* Not for us */
|
||||
return 0;
|
||||
}
|
||||
|
||||
tcp_dissect_pdus(tvb, pinfo, tree, TRUE, 8, get_dtn_contact_header_len, dissect_dtn_contact_header, data);
|
||||
return tvb_captured_length(tvb);
|
||||
}
|
||||
|
||||
/* Not for us */
|
||||
return 0;
|
||||
};
|
||||
|
||||
processed_length = get_tcpcl_pdu_len(pinfo, tvb, 0, data);
|
||||
|
||||
tcp_dissect_pdus(tvb, pinfo, tree, TRUE, 1, get_tcpcl_pdu_len, dissect_tcpcl_pdu, data);
|
||||
|
||||
return processed_length;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
proto_register_tcpclv3(void)
|
||||
{
|
||||
|
||||
static hf_register_info hf_tcpcl[] = {
|
||||
{&hf_tcp_convergence_pkt_type,
|
||||
{"Pkt Type", "tcpcl.pkt_type",
|
||||
FT_UINT8, BASE_DEC, VALS(packet_type_vals), 0xF0, NULL, HFILL}
|
||||
},
|
||||
{&hf_dtn_refuse_bundle_reason_code,
|
||||
{"Reason-Code", "tcpcl.refuse.reason_code",
|
||||
FT_UINT8, BASE_DEC, VALS(refuse_bundle_reason_code), 0x0F, NULL, HFILL}
|
||||
},
|
||||
{&hf_tcp_convergence_data_procflags,
|
||||
{"TCP Convergence Data Flags", "tcpcl.data.proc.flag",
|
||||
FT_UINT8, BASE_HEX, NULL, TCP_CONVERGENCE_DATA_FLAGS, NULL, HFILL}
|
||||
},
|
||||
{&hf_tcp_convergence_data_procflags_start,
|
||||
{"Segment contains start of bundle", "tcpcl.data.proc.start",
|
||||
FT_BOOLEAN, 8, NULL, TCP_CONVERGENCE_DATA_START_FLAG, NULL, HFILL}
|
||||
},
|
||||
{&hf_tcp_convergence_data_procflags_end,
|
||||
{"Segment contains end of Bundle", "tcpcl.data.proc.end",
|
||||
FT_BOOLEAN, 8, NULL, TCP_CONVERGENCE_DATA_END_FLAG, NULL, HFILL}
|
||||
},
|
||||
{&hf_tcp_convergence_data_segment_length,
|
||||
{"Segment Length", "tcpcl.data.length",
|
||||
FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_tcp_convergence_shutdown_flags,
|
||||
{"TCP Convergence Shutdown Flags", "tcpcl.shutdown.flags",
|
||||
FT_UINT8, BASE_HEX, NULL, TCP_CONVERGENCE_SHUTDOWN_FLAGS, NULL, HFILL}
|
||||
},
|
||||
{&hf_tcp_convergence_shutdown_flags_reason,
|
||||
{"Shutdown includes Reason Code", "tcpcl.shutdown.reason.flag",
|
||||
FT_BOOLEAN, 8, NULL, TCP_CONVERGENCE_SHUTDOWN_REASON, NULL, HFILL}
|
||||
},
|
||||
{&hf_tcp_convergence_shutdown_flags_delay,
|
||||
{"Shutdown includes Reconnection Delay", "tcpcl.shutdown.delay.flag",
|
||||
FT_BOOLEAN, 8, NULL, TCP_CONVERGENCE_SHUTDOWN_DELAY, NULL, HFILL}
|
||||
},
|
||||
{&hf_tcp_convergence_shutdown_reason,
|
||||
{"Shutdown Reason Code", "tcpcl.shutdown.reason",
|
||||
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_tcp_convergence_shutdown_delay,
|
||||
{"Shutdown Reconnection Delay", "tcpcl.shutdown.delay",
|
||||
FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_tcp_convergence_ack_length,
|
||||
{"Ack Length", "tcpcl.ack.length",
|
||||
FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_contact_hdr_version,
|
||||
{"Version", "tcpcl.contact_hdr.version",
|
||||
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_contact_hdr_flags,
|
||||
{"Flags", "tcpcl.contact_hdr.flags",
|
||||
FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_contact_hdr_flags_ack_req,
|
||||
{"Bundle Acks Requested", "tcpcl.contact_hdr.flags.ackreq",
|
||||
FT_BOOLEAN, 8, NULL, TCP_CONV_BUNDLE_ACK_FLAG, NULL, HFILL}
|
||||
},
|
||||
{&hf_contact_hdr_flags_frag_enable,
|
||||
{"Reactive Fragmentation Enabled", "tcpcl.contact_hdr.flags.fragen",
|
||||
FT_BOOLEAN, 8, NULL, TCP_CONV_REACTIVE_FRAG_FLAG, NULL, HFILL}
|
||||
},
|
||||
{&hf_contact_hdr_flags_nak,
|
||||
{"Support Negative Acknowledgements", "tcpcl.contact_hdr.flags.nak",
|
||||
FT_BOOLEAN, 8, NULL, TCP_CONV_CONNECTOR_RCVR_FLAG, NULL, HFILL}
|
||||
},
|
||||
{&hf_contact_hdr_keep_alive,
|
||||
{"Keep Alive", "tcpcl.contact_hdr.keep_alive",
|
||||
FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_contact_hdr_magic,
|
||||
{"Magic", "tcpcl.contact_hdr.magic",
|
||||
FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_contact_hdr_local_eid,
|
||||
{"Local EID", "tcpcl.contact_hdr.local_eid",
|
||||
FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_contact_hdr_local_eid_length,
|
||||
{"Local EID Length", "tcpcl.contact_hdr.local_eid_length",
|
||||
FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
|
||||
{&hf_msg_fragments,
|
||||
{"Message Fragments", "tcpcl.msg.fragments",
|
||||
FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_msg_fragment,
|
||||
{"Message Fragment", "tcpcl.msg.fragment",
|
||||
FT_FRAMENUM, BASE_NONE, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_msg_fragment_overlap,
|
||||
{"Message fragment overlap", "tcpcl.msg.fragment.overlap",
|
||||
FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_msg_fragment_overlap_conflicts,
|
||||
{"Message fragment overlapping with conflicting data",
|
||||
"tcpcl.msg.fragment.overlap.conflicts",
|
||||
FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_msg_fragment_multiple_tails,
|
||||
{"Message has multiple tails", "tcpcl.msg.fragment.multiple_tails",
|
||||
FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_msg_fragment_too_long_fragment,
|
||||
{"Message fragment too long", "tcpcl.msg.fragment.too_long_fragment",
|
||||
FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_msg_fragment_error,
|
||||
{"Message defragmentation error", "tcpcl.msg.fragment.error",
|
||||
FT_FRAMENUM, BASE_NONE, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_msg_fragment_count,
|
||||
{"Message fragment count", "tcpcl.msg.fragment.count",
|
||||
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_msg_reassembled_in,
|
||||
{"Reassembled in", "tcpcl.msg.reassembled.in",
|
||||
FT_FRAMENUM, BASE_NONE, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
{&hf_msg_reassembled_length,
|
||||
{"Reassembled DTN length", "tcpcl.msg.reassembled.length",
|
||||
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
|
||||
},
|
||||
};
|
||||
|
||||
static gint *ett_tcpcl[] = {
|
||||
&ett_tcp_conv,
|
||||
&ett_tcp_conv_hdr,
|
||||
&ett_conv_flags,
|
||||
&ett_contact_hdr_flags,
|
||||
&ett_shutdown_flags,
|
||||
&ett_msg_fragment,
|
||||
&ett_msg_fragments,
|
||||
};
|
||||
|
||||
static ei_register_info ei_tcpcl[] = {
|
||||
{ &ei_tcp_convergence_data_flags,
|
||||
{ "tcpcl.data.flags.invalid", PI_PROTOCOL, PI_WARN, "Invalid TCP CL Data Segment Flags", EXPFILL }
|
||||
},
|
||||
{ &ei_tcp_convergence_segment_length,
|
||||
{ "tcpcl.data.length.invalid", PI_PROTOCOL, PI_ERROR, "Invalid Data Length", EXPFILL }
|
||||
},
|
||||
{ &ei_tcp_convergence_ack_length,
|
||||
{ "tcpcl.ack.length.error", PI_PROTOCOL, PI_WARN, "Ack Length: Error", EXPFILL }
|
||||
},
|
||||
};
|
||||
|
||||
expert_module_t *expert_tcpcl;
|
||||
|
||||
proto_tcp_conv = proto_register_protocol ("DTN TCP Convergence Layer Protocol", "TCPCL", "tcpcl");
|
||||
|
||||
proto_register_field_array(proto_tcp_conv, hf_tcpcl, array_length(hf_tcpcl));
|
||||
proto_register_subtree_array(ett_tcpcl, array_length(ett_tcpcl));
|
||||
expert_tcpcl = expert_register_protocol(proto_tcp_conv);
|
||||
expert_register_field_array(expert_tcpcl, ei_tcpcl, array_length(ei_tcpcl));
|
||||
|
||||
reassembly_table_register(&msg_reassembly_table,
|
||||
&addresses_reassembly_table_functions);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
proto_reg_handoff_tcpclv3(void)
|
||||
{
|
||||
dissector_handle_t tcpcl_handle;
|
||||
|
||||
bundle_handle = find_dissector("bundle");
|
||||
|
||||
tcpcl_handle = create_dissector_handle(dissect_tcpcl, proto_tcp_conv);
|
||||
dissector_add_uint_with_preference("tcp.port", BUNDLE_PORT, tcpcl_handle);
|
||||
}
|
||||
|
||||
/*
|
||||
* Editor modelines - https://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
* Local variables:
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* vi: set shiftwidth=4 tabstop=8 expandtab:
|
||||
* :indentSize=4:tabSize=8:noTabs=true:
|
||||
*/
|
|
@ -0,0 +1,101 @@
|
|||
/* packet-tcpclv3.h
|
||||
* References:
|
||||
* RFC 7242: https://tools.ietf.org/html/rfc7242
|
||||
*
|
||||
* Copyright 2006-2007 The MITRE Corporation.
|
||||
* All Rights Reserved.
|
||||
* Approved for Public Release; Distribution Unlimited.
|
||||
* Tracking Number 07-0090.
|
||||
*
|
||||
* The US Government will not be charged any license fee and/or royalties
|
||||
* related to this software. Neither name of The MITRE Corporation; nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef PACKET_TCPCLV3_H
|
||||
#define PACKET_TCPCLV3_H
|
||||
|
||||
#include <ws_symbol_export.h>
|
||||
#include <epan/tvbuff.h>
|
||||
#include <epan/proto.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* TCP Convergence Layer - Message Types */
|
||||
#define TCP_CONV_MSG_TYPE_DATA 0x01
|
||||
#define TCP_CONV_MSG_TYPE_ACK 0x02
|
||||
#define TCP_CONV_MSG_TYPE_KEEP_ALIVE 0x03
|
||||
#define TCP_CONV_MSG_TYPE_SHUTDOWN 0x04
|
||||
|
||||
/* TCP Convergence Layer (3) - Message Types */
|
||||
#define TCP_CONVERGENCE_TYPE_MASK 0xf0
|
||||
#define TCP_CONVERGENCE_DATA_SEGMENT 0x10
|
||||
#define TCP_CONVERGENCE_ACK_SEGMENT 0x20
|
||||
#define TCP_CONVERGENCE_REFUSE_BUNDLE 0x30
|
||||
#define TCP_CONVERGENCE_KEEP_ALIVE 0x40
|
||||
#define TCP_CONVERGENCE_SHUTDOWN 0x50
|
||||
#define TCP_CONVERGENCE_LENGTH 0x60
|
||||
|
||||
/* TCP Convergence Layer - Contact Header Flags */
|
||||
#define TCP_CONV_BUNDLE_ACK_FLAG 0x01
|
||||
#define TCP_CONV_REACTIVE_FRAG_FLAG 0x02
|
||||
#define TCP_CONV_CONNECTOR_RCVR_FLAG 0x04
|
||||
|
||||
/* TCP Convergence Layer - Data Segment Flags */
|
||||
#define TCP_CONVERGENCE_DATA_FLAGS 0x03
|
||||
#define TCP_CONVERGENCE_DATA_END_FLAG 0x01
|
||||
#define TCP_CONVERGENCE_DATA_START_FLAG 0x02
|
||||
|
||||
/* TCP Convergence Layer - Shutdown Segment Flags */
|
||||
#define TCP_CONVERGENCE_SHUTDOWN_FLAGS 0x03
|
||||
#define TCP_CONVERGENCE_SHUTDOWN_REASON 0x02
|
||||
#define TCP_CONVERGENCE_SHUTDOWN_DELAY 0x01
|
||||
|
||||
/* REFUSE-BUNDLE Reason-Codes */
|
||||
#define TCP_REFUSE_BUNDLE_REASON_UNKNOWN 0x00
|
||||
#define TCP_REFUSE_BUNDLE_REASON_RX_COMPLETE 0x01
|
||||
#define TCP_REFUSE_BUNDLE_REASON_RX_EXHAUSTED 0x02
|
||||
#define TCP_REFUSE_BUNDLE_REASON_RX_RETRANSMIT 0x03
|
||||
/* 0x4-0x7 - Unassigned
|
||||
* 0x8-0xf - Reserved for future Use */
|
||||
|
||||
/*
|
||||
* TCP Convergence Layer - Minimum buffer sizes
|
||||
* For Data Packet require 5 bytes fixed plus
|
||||
* up to 4 additional for length SDV
|
||||
*/
|
||||
|
||||
#define TCP_CONV_MIN_DATA_BUFFER 9
|
||||
|
||||
/* Header Fixed Sizes */
|
||||
#define TCP_CONV_HDR_DATA_FIXED_LENGTH 5
|
||||
#define TCP_CONV_HDR_ACK_LENGTH 9
|
||||
#define TCP_CONV_HDR_KEEP_ALIVE_LENGTH 1
|
||||
#define TCP_CONV_HDR_SHUTDOWN_LENGTH 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PACKET_TCPCLV3_H */
|
||||
|
||||
/*
|
||||
* Editor modelines - https://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
* Local variables:
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* vi: set shiftwidth=4 tabstop=8 expandtab:
|
||||
* :indentSize=4:tabSize=8:noTabs=true:
|
||||
*/
|
|
@ -0,0 +1,7 @@
|
|||
[_
|
||||
[7, 11094, 1, [2, [26622, 12070]], [2, [5279, 7390]], [2, [4785, 1111]], [81089243, 993], 52532350140, 1646, 2047, h'55E4'],
|
||||
[7, 7, 175, 0, 24(h'1B000000013075CD37')],
|
||||
[10, 5, 89, 0, 24(h'820007')],
|
||||
[12, 25, 162, 0, 63(h'8101 02 01 82028219149f191cde 84 8201426869 820205 8203426869 820407 8181 8201457468657265')],
|
||||
[1, 1, 3, 0, 24(h'8201848482F41B000000018BA3F02382F41A3027AC8782F41B000000018DFAF97381F503820282185D18B9821A533D733D190119')]
|
||||
]
|
Binary file not shown.
|
@ -0,0 +1,7 @@
|
|||
[_
|
||||
[7, 11094, 1, [2, [26622, 12070]], [2, [5279, 7390]], [2, [4785, 1111]], [81089243, 993], 52532350140, 1646, 2047, h'55E4'],
|
||||
[7, 7, 175, 0, 24(h'1B000000013075CD37')],
|
||||
[10, 5, 89, 0, 24(h'820007')],
|
||||
[11, 25, 162, 0, 63(h'8101 01 01 82028219149f191cde 83 820105 8202426869 820307 8181 8201457468657265')],
|
||||
[1, 1, 3, 0, 24(h'8201848482F41B000000018BA3F02382F41A3027AC8782F41B000000018DFAF97381F503820282185D18B9821A533D733D190119')]
|
||||
]
|
Binary file not shown.
|
@ -14,6 +14,49 @@ import unittest
|
|||
import fixtures
|
||||
import sys
|
||||
|
||||
|
||||
@fixtures.mark_usefixtures('test_env')
|
||||
@fixtures.uses_fixtures
|
||||
class case_dissect_bpv7(subprocesstest.SubprocessTestCase):
|
||||
|
||||
def test_bpv7_admin_status(self, cmd_tshark, features, dirs, capture_file):
|
||||
self.assertRun((cmd_tshark,
|
||||
'-r', capture_file('dtn_udpcl_bpv7_bpsec_bib_admin.pcapng'),
|
||||
'-Tfields', '-ebpv7.status_rep.identity',
|
||||
))
|
||||
self.assertTrue(self.grepOutput(r'Source: ipn:93.185, DTN Time: 1396536125, Seq: 281'))
|
||||
|
||||
def test_bpv7_bpsec_bib(self, cmd_tshark, features, dirs, capture_file):
|
||||
self.assertRun((cmd_tshark,
|
||||
'-r', capture_file('dtn_udpcl_bpv7_bpsec_bib_admin.pcapng'),
|
||||
'-Tfields', '-ebpsec.asb.ctxid',
|
||||
))
|
||||
self.assertEqual(self.countOutput(r'1'), 1)
|
||||
|
||||
def test_bpv7_bpsec_bib_admin_type(self, cmd_tshark, features, dirs, capture_file):
|
||||
# BIB doesn't alter payload
|
||||
self.assertRun((cmd_tshark,
|
||||
'-r', capture_file('dtn_udpcl_bpv7_bpsec_bib_admin.pcapng'),
|
||||
'-Tfields', '-ebpv7.admin_rec.type_code',
|
||||
))
|
||||
self.assertEqual(self.countOutput(r'1'), 1)
|
||||
|
||||
def test_bpv7_bpsec_bcb(self, cmd_tshark, features, dirs, capture_file):
|
||||
self.assertRun((cmd_tshark,
|
||||
'-r', capture_file('dtn_udpcl_bpv7_bpsec_bcb_admin.pcapng'),
|
||||
'-Tfields', '-ebpsec.asb.ctxid',
|
||||
))
|
||||
self.assertEqual(self.countOutput(r'2'), 1)
|
||||
|
||||
def test_bpv7_bpsec_bcb_admin_type(self, cmd_tshark, features, dirs, capture_file):
|
||||
# BCB inhibits payload dissection
|
||||
self.assertRun((cmd_tshark,
|
||||
'-r', capture_file('dtn_udpcl_bpv7_bpsec_bcb_admin.pcapng'),
|
||||
'-Tfields', '-ebpv7.admin_rec.type_code',
|
||||
))
|
||||
self.assertEqual(self.countOutput(r'1'), 0)
|
||||
|
||||
|
||||
@fixtures.mark_usefixtures('test_env')
|
||||
@fixtures.uses_fixtures
|
||||
class case_dissect_cose(subprocesstest.SubprocessTestCase):
|
||||
|
|
Loading…
Reference in New Issue