forked from osmocom/wireshark
GSUP/SMS: add MO-/MT-FORWARD-SM message decoding
According to 3GPP TS 29.002, there are two services: - MAP-MO-FORWARD-SHORT-MESSAGE (see 12.2), - MAP-MT-FORWARD-SHORT-MESSAGE (see 12.9), which are used to forward MO/MT short messages. This change replicates both services as GSUP messages: - OSMO_GSUP_MSGT_MO_FORWARD_SM_*, - OSMO_GSUP_MSGT_MT_FORWARD_SM_*. For more information, please see: https://git.osmocom.org/libosmocore/commit/?id=c2628317cc3482262c80b93cbfb2cbe960772558 https://git.osmocom.org/osmo-gsm-manuals/commit/?id=f26967aad547e8f79e6726aefe9fe8a69ae2ba4b Change-Id: Ia46aabc74c00c89c4da53c2ed4b9fd2200a485a0 Reviewed-on: https://code.wireshark.org/review/30586 Petri-Dish: Anders Broman <a.broman58@gmail.com> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
parent
afc1265b63
commit
94bc8f1276
|
@ -25,6 +25,7 @@
|
|||
#include "config.h"
|
||||
|
||||
#include <epan/packet.h>
|
||||
#include <epan/expert.h>
|
||||
#include <epan/conversation.h>
|
||||
|
||||
#include "packet-e164.h"
|
||||
|
@ -87,6 +88,13 @@ enum osmo_gsup_iei {
|
|||
OSMO_GSUP_SESSION_ID_IE = 0x30,
|
||||
OSMO_GSUP_SESSION_STATE_IE = 0x31,
|
||||
OSMO_GSUP_SS_INFO_IE = 0x35,
|
||||
/* SM Service (see 3GPP TS 29.002, section 7.6.8) */
|
||||
OSMO_GSUP_SM_RP_MR_IE = 0x40,
|
||||
OSMO_GSUP_SM_RP_DA_IE = 0x41,
|
||||
OSMO_GSUP_SM_RP_OA_IE = 0x42,
|
||||
OSMO_GSUP_SM_RP_UI_IE = 0x43,
|
||||
OSMO_GSUP_SM_RP_CAUSE_IE = 0x44,
|
||||
OSMO_GSUP_SM_RP_MMS_IE = 0x45,
|
||||
};
|
||||
|
||||
/*! GSUP message type */
|
||||
|
@ -120,6 +128,14 @@ enum osmo_gsup_message_type {
|
|||
OSMO_GSUP_MSGT_PROC_SS_REQUEST = 0x20,
|
||||
OSMO_GSUP_MSGT_PROC_SS_ERROR = 0x21,
|
||||
OSMO_GSUP_MSGT_PROC_SS_RESULT = 0x22,
|
||||
|
||||
OSMO_GSUP_MSGT_MO_FORWARD_SM_REQUEST = 0x24,
|
||||
OSMO_GSUP_MSGT_MO_FORWARD_SM_ERROR = 0x25,
|
||||
OSMO_GSUP_MSGT_MO_FORWARD_SM_RESULT = 0x26,
|
||||
|
||||
OSMO_GSUP_MSGT_MT_FORWARD_SM_REQUEST = 0x28,
|
||||
OSMO_GSUP_MSGT_MT_FORWARD_SM_ERROR = 0x29,
|
||||
OSMO_GSUP_MSGT_MT_FORWARD_SM_RESULT = 0x2a,
|
||||
};
|
||||
|
||||
#define OSMO_GSUP_IS_MSGT_REQUEST(msgt) (((msgt) & 0b00000011) == 0b00)
|
||||
|
@ -143,6 +159,16 @@ enum osmo_gsup_session_state {
|
|||
OSMO_GSUP_SESSION_STATE_END = 0x03,
|
||||
};
|
||||
|
||||
/* Identity types for SM-RP-{OA|DA} */
|
||||
enum osmo_gsup_sms_sm_rp_oda_type {
|
||||
OSMO_GSUP_SMS_SM_RP_ODA_NONE = 0x00,
|
||||
OSMO_GSUP_SMS_SM_RP_ODA_IMSI = 0x01,
|
||||
OSMO_GSUP_SMS_SM_RP_ODA_MSISDN = 0x02,
|
||||
OSMO_GSUP_SMS_SM_RP_ODA_SMSC_ADDR = 0x03,
|
||||
/* Special value for noSM-RP-DA and noSM-RP-OA */
|
||||
OSMO_GSUP_SMS_SM_RP_ODA_NULL = 0xff,
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* Wireshark Dissector Implementation
|
||||
***********************************************************************/
|
||||
|
@ -174,11 +200,20 @@ static int hf_gsup_auts = -1;
|
|||
static int hf_gsup_res = -1;
|
||||
static int hf_gsup_session_id = -1;
|
||||
static int hf_gsup_session_state = -1;
|
||||
static int hf_gsup_sm_rp_mr = -1;
|
||||
static int hf_gsup_sm_rp_da_id_type = -1;
|
||||
static int hf_gsup_sm_rp_oa_id_type = -1;
|
||||
static int hf_gsup_sm_rp_cause = -1;
|
||||
static int hf_gsup_sm_rp_mms = -1;
|
||||
|
||||
static gint ett_gsup = -1;
|
||||
static gint ett_gsup_ie = -1;
|
||||
|
||||
static expert_field ei_sm_rp_da_invalid = EI_INIT;
|
||||
static expert_field ei_sm_rp_oa_invalid = EI_INIT;
|
||||
|
||||
static dissector_handle_t gsm_map_handle;
|
||||
static dissector_handle_t gsm_sms_handle;
|
||||
|
||||
static const value_string gsup_iei_types[] = {
|
||||
{ OSMO_GSUP_IMSI_IE, "IMSI" },
|
||||
|
@ -207,6 +242,12 @@ static const value_string gsup_iei_types[] = {
|
|||
{ OSMO_GSUP_SESSION_ID_IE, "Session Id" },
|
||||
{ OSMO_GSUP_SESSION_STATE_IE, "Session State" },
|
||||
{ OSMO_GSUP_SS_INFO_IE, "Supplementary Service Info"},
|
||||
{ OSMO_GSUP_SM_RP_MR_IE, "SM-RP-MR (Message Reference)" },
|
||||
{ OSMO_GSUP_SM_RP_DA_IE, "SM-RP-DA (Destination Address)" },
|
||||
{ OSMO_GSUP_SM_RP_OA_IE, "SM-RP-OA (Originating Address)" },
|
||||
{ OSMO_GSUP_SM_RP_UI_IE, "SM-RP-UI (SMS TPDU)" },
|
||||
{ OSMO_GSUP_SM_RP_CAUSE_IE, "SM-RP-Cause" },
|
||||
{ OSMO_GSUP_SM_RP_MMS_IE, "SM-RP-MMS (More Messages to Send)" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
|
@ -233,6 +274,12 @@ static const value_string gsup_msg_types[] = {
|
|||
{ OSMO_GSUP_MSGT_PROC_SS_REQUEST, "Supplementary Service Request" },
|
||||
{ OSMO_GSUP_MSGT_PROC_SS_ERROR, "Supplementary Service Error" },
|
||||
{ OSMO_GSUP_MSGT_PROC_SS_RESULT, "Supplementary Service Result" },
|
||||
{ OSMO_GSUP_MSGT_MO_FORWARD_SM_REQUEST, "MO-forwardSM Request" },
|
||||
{ OSMO_GSUP_MSGT_MO_FORWARD_SM_ERROR, "MO-forwardSM Error" },
|
||||
{ OSMO_GSUP_MSGT_MO_FORWARD_SM_RESULT, "MO-forwardSM Result" },
|
||||
{ OSMO_GSUP_MSGT_MT_FORWARD_SM_REQUEST, "MT-forwardSM Request" },
|
||||
{ OSMO_GSUP_MSGT_MT_FORWARD_SM_ERROR, "MT-forwardSM Error" },
|
||||
{ OSMO_GSUP_MSGT_MT_FORWARD_SM_RESULT, "MT-forwardSM Result" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
|
@ -256,6 +303,15 @@ static const value_string gsup_session_states[] = {
|
|||
{ 0, NULL }
|
||||
};
|
||||
|
||||
static const value_string osmo_gsup_sms_sm_rp_oda_types[] = {
|
||||
{ OSMO_GSUP_SMS_SM_RP_ODA_NONE, "NONE" },
|
||||
{ OSMO_GSUP_SMS_SM_RP_ODA_IMSI, "IMSI" },
|
||||
{ OSMO_GSUP_SMS_SM_RP_ODA_MSISDN, "MSISDN" },
|
||||
{ OSMO_GSUP_SMS_SM_RP_ODA_SMSC_ADDR, "SMSC Address" },
|
||||
{ OSMO_GSUP_SMS_SM_RP_ODA_NULL, "noSM-RP-DA or noSM-RP-OA" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
static void dissect_ss_info_ie(tvbuff_t *tvb, packet_info *pinfo, guint offset, guint len, proto_tree *tree)
|
||||
{
|
||||
guint saved_offset;
|
||||
|
@ -288,9 +344,122 @@ static void dissect_ss_info_ie(tvbuff_t *tvb, packet_info *pinfo, guint offset,
|
|||
}
|
||||
}
|
||||
|
||||
static void dissect_sm_rp_da_ie(tvbuff_t *tvb, packet_info *pinfo, guint offset,
|
||||
guint ie_len, proto_tree *tree)
|
||||
{
|
||||
proto_item *ti;
|
||||
guint8 id_type;
|
||||
|
||||
/* Identity type is mandatory */
|
||||
if (ie_len < 1) {
|
||||
expert_add_info_format(pinfo, NULL, &ei_sm_rp_da_invalid,
|
||||
"Missing mandatory SM-RP-DA ID type (IE len < 1)");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Parse ID type */
|
||||
ti = proto_tree_add_item(tree, hf_gsup_sm_rp_da_id_type, tvb, offset, 1, ENC_NA);
|
||||
id_type = tvb_get_guint8(tvb, offset);
|
||||
|
||||
switch (id_type) {
|
||||
case OSMO_GSUP_SMS_SM_RP_ODA_IMSI:
|
||||
dissect_e212_imsi(tvb, pinfo, tree,
|
||||
offset + 1, ie_len - 1, FALSE);
|
||||
break;
|
||||
case OSMO_GSUP_SMS_SM_RP_ODA_MSISDN:
|
||||
case OSMO_GSUP_SMS_SM_RP_ODA_SMSC_ADDR:
|
||||
dissect_e164_msisdn(tvb, tree,
|
||||
offset + 2, ie_len - 2, E164_ENC_BCD);
|
||||
break;
|
||||
|
||||
/* Special case for noSM-RP-DA and noSM-RP-OA */
|
||||
case OSMO_GSUP_SMS_SM_RP_ODA_NULL:
|
||||
if (ie_len > 1) {
|
||||
expert_add_info_format(pinfo, ti, &ei_sm_rp_da_invalid,
|
||||
"Unexpected ID length=%u for noSM-RP-DA", ie_len - 1);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case OSMO_GSUP_SMS_SM_RP_ODA_NONE:
|
||||
default:
|
||||
expert_add_info_format(pinfo, ti, &ei_sm_rp_da_invalid,
|
||||
"Unexpected SM-RP-DA ID (type=0x%02x)", id_type);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void dissect_sm_rp_oa_ie(tvbuff_t *tvb, packet_info *pinfo, guint offset,
|
||||
guint ie_len, proto_tree *tree)
|
||||
{
|
||||
proto_item *ti;
|
||||
guint8 id_type;
|
||||
|
||||
/* Identity type is mandatory */
|
||||
if (ie_len < 1) {
|
||||
expert_add_info_format(pinfo, NULL, &ei_sm_rp_oa_invalid,
|
||||
"Missing mandatory SM-RP-OA ID type (IE len < 1)");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Parse ID type */
|
||||
ti = proto_tree_add_item(tree, hf_gsup_sm_rp_oa_id_type, tvb, offset, 1, ENC_NA);
|
||||
id_type = tvb_get_guint8(tvb, offset);
|
||||
|
||||
switch (id_type) {
|
||||
case OSMO_GSUP_SMS_SM_RP_ODA_MSISDN:
|
||||
case OSMO_GSUP_SMS_SM_RP_ODA_SMSC_ADDR:
|
||||
dissect_e164_msisdn(tvb, tree,
|
||||
offset + 2, ie_len - 2, E164_ENC_BCD);
|
||||
break;
|
||||
|
||||
/* Special case for noSM-RP-DA and noSM-RP-OA */
|
||||
case OSMO_GSUP_SMS_SM_RP_ODA_NULL:
|
||||
if (ie_len > 1) {
|
||||
expert_add_info_format(pinfo, ti, &ei_sm_rp_oa_invalid,
|
||||
"Unexpected ID length=%u for noSM-RP-OA", ie_len - 1);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case OSMO_GSUP_SMS_SM_RP_ODA_NONE:
|
||||
default:
|
||||
expert_add_info_format(pinfo, ti, &ei_sm_rp_oa_invalid,
|
||||
"Unexpected SM-RP-OA ID (type=0x%02x)", id_type);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void dissect_sm_rp_ui_ie(tvbuff_t *tvb, packet_info *pinfo, guint offset,
|
||||
guint ie_len, proto_tree *tree, guint8 msg_type)
|
||||
{
|
||||
tvbuff_t *ss_tvb;
|
||||
|
||||
/* Choose direction: RECV for MO, SENT for MT */
|
||||
switch (msg_type) {
|
||||
case OSMO_GSUP_MSGT_MO_FORWARD_SM_REQUEST:
|
||||
case OSMO_GSUP_MSGT_MO_FORWARD_SM_ERROR:
|
||||
case OSMO_GSUP_MSGT_MO_FORWARD_SM_RESULT:
|
||||
pinfo->p2p_dir = P2P_DIR_RECV;
|
||||
break;
|
||||
case OSMO_GSUP_MSGT_MT_FORWARD_SM_REQUEST:
|
||||
case OSMO_GSUP_MSGT_MT_FORWARD_SM_ERROR:
|
||||
case OSMO_GSUP_MSGT_MT_FORWARD_SM_RESULT:
|
||||
pinfo->p2p_dir = P2P_DIR_SENT;
|
||||
break;
|
||||
default:
|
||||
/* Just to be sure */
|
||||
DISSECTOR_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
ss_tvb = tvb_new_subset_length(tvb, offset, ie_len);
|
||||
call_dissector(gsm_sms_handle, ss_tvb, pinfo, tree);
|
||||
}
|
||||
|
||||
static gint
|
||||
dissect_gsup_tlvs(tvbuff_t *tvb, int base_offs, int length, packet_info *pinfo, proto_tree *tree,
|
||||
proto_item *gsup_ti)
|
||||
proto_item *gsup_ti, guint8 msg_type)
|
||||
{
|
||||
int offset = base_offs;
|
||||
|
||||
|
@ -319,7 +488,7 @@ dissect_gsup_tlvs(tvbuff_t *tvb, int base_offs, int length, packet_info *pinfo,
|
|||
/* Nested TLVs */
|
||||
case OSMO_GSUP_AUTH_TUPLE_IE:
|
||||
case OSMO_GSUP_PDP_INFO_IE:
|
||||
dissect_gsup_tlvs(tvb, offset, len, pinfo, att_tree, gsup_ti);
|
||||
dissect_gsup_tlvs(tvb, offset, len, pinfo, att_tree, gsup_ti, msg_type);
|
||||
break;
|
||||
/* Normal IEs */
|
||||
case OSMO_GSUP_RAND_IE:
|
||||
|
@ -399,6 +568,24 @@ dissect_gsup_tlvs(tvbuff_t *tvb, int base_offs, int length, packet_info *pinfo,
|
|||
case OSMO_GSUP_SS_INFO_IE:
|
||||
dissect_ss_info_ie(tvb, pinfo, offset, len, att_tree);
|
||||
break;
|
||||
case OSMO_GSUP_SM_RP_MR_IE:
|
||||
proto_tree_add_item(att_tree, hf_gsup_sm_rp_mr, tvb, offset, len, ENC_NA);
|
||||
break;
|
||||
case OSMO_GSUP_SM_RP_DA_IE:
|
||||
dissect_sm_rp_da_ie(tvb, pinfo, offset, len, att_tree);
|
||||
break;
|
||||
case OSMO_GSUP_SM_RP_OA_IE:
|
||||
dissect_sm_rp_oa_ie(tvb, pinfo, offset, len, att_tree);
|
||||
break;
|
||||
case OSMO_GSUP_SM_RP_UI_IE:
|
||||
dissect_sm_rp_ui_ie(tvb, pinfo, offset, len, att_tree, msg_type);
|
||||
break;
|
||||
case OSMO_GSUP_SM_RP_CAUSE_IE:
|
||||
proto_tree_add_item(att_tree, hf_gsup_sm_rp_cause, tvb, offset, len, ENC_NA);
|
||||
break;
|
||||
case OSMO_GSUP_SM_RP_MMS_IE:
|
||||
proto_tree_add_item(att_tree, hf_gsup_sm_rp_mms, tvb, offset, len, ENC_NA);
|
||||
break;
|
||||
case OSMO_GSUP_HLR_NUMBER_IE:
|
||||
case OSMO_GSUP_PDP_TYPE_IE:
|
||||
case OSMO_GSUP_PDP_QOS_IE:
|
||||
|
@ -442,7 +629,7 @@ dissect_gsup(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_
|
|||
offset++;
|
||||
|
||||
dissect_gsup_tlvs(tvb, offset, tvb_reported_length_remaining(tvb, offset), pinfo,
|
||||
gsup_tree, ti);
|
||||
gsup_tree, ti, msg_type);
|
||||
}
|
||||
|
||||
return tvb_captured_length(tvb);
|
||||
|
@ -498,15 +685,39 @@ proto_register_gsup(void)
|
|||
FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } },
|
||||
{ &hf_gsup_session_state, { "Session State", "gsup.session_state",
|
||||
FT_UINT8, BASE_DEC, VALS(gsup_session_states), 0, NULL, HFILL } },
|
||||
{ &hf_gsup_sm_rp_mr, { "SM-RP-MR (Message Reference)", "gsup.sm_rp_mr",
|
||||
FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
|
||||
{ &hf_gsup_sm_rp_da_id_type, { "Address Type", "gsup.sm_rp_da.addr_type",
|
||||
FT_UINT8, BASE_DEC, VALS(osmo_gsup_sms_sm_rp_oda_types), 0, NULL, HFILL } },
|
||||
{ &hf_gsup_sm_rp_oa_id_type, { "Address Type", "gsup.sm_rp_oa.addr_type",
|
||||
FT_UINT8, BASE_DEC, VALS(osmo_gsup_sms_sm_rp_oda_types), 0, NULL, HFILL } },
|
||||
{ &hf_gsup_sm_rp_cause, { "SM-RP Cause", "gsup.sm_rp.cause",
|
||||
FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
|
||||
{ &hf_gsup_sm_rp_mms, { "More Messages to Send", "gsup.sm_rp.mms",
|
||||
FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
|
||||
};
|
||||
static gint *ett[] = {
|
||||
&ett_gsup,
|
||||
&ett_gsup_ie,
|
||||
};
|
||||
|
||||
expert_module_t *expert_gsup;
|
||||
|
||||
static ei_register_info ei[] = {
|
||||
{ &ei_sm_rp_da_invalid,
|
||||
{ "gsup.sm_rp_da.invalid", PI_PROTOCOL, PI_ERROR,
|
||||
"Malformed SM-RP-DA IE", EXPFILL } },
|
||||
{ &ei_sm_rp_oa_invalid,
|
||||
{ "gsup.sm_rp_oa.invalid", PI_PROTOCOL, PI_ERROR,
|
||||
"Malformed SM-RP-OA IE", EXPFILL } },
|
||||
};
|
||||
|
||||
proto_gsup = proto_register_protocol("Osmocom General Subscriber Update Protocol", "gsup", "gsup");
|
||||
proto_register_field_array(proto_gsup, hf, array_length(hf));
|
||||
proto_register_subtree_array(ett, array_length(ett));
|
||||
|
||||
expert_gsup = expert_register_protocol(proto_gsup);
|
||||
expert_register_field_array(expert_gsup, ei, array_length(ei));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -516,6 +727,7 @@ proto_reg_handoff_gsup(void)
|
|||
gsup_handle = create_dissector_handle(dissect_gsup, proto_gsup);
|
||||
dissector_add_uint_with_preference("ipa.osmo.protocol", IPAC_PROTO_EXT_GSUP, gsup_handle);
|
||||
gsm_map_handle = find_dissector_add_dependency("gsm_map", proto_gsup);
|
||||
gsm_sms_handle = find_dissector_add_dependency("gsm_sms", proto_gsup);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue