* Technical realization of Short Message Service (SMS)
* (3GPP TS 23.040 version 5.4.0 Release 5)
*
- * $Id: packet-gsm_sms.c,v 1.7 2003/12/13 23:55:29 guy Exp $
+ * $Id: packet-gsm_sms.c,v 1.10 2004/03/05 10:06:19 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
/* PROTOTYPES/FORWARDS */
-#define RP_DATA_MS_TO_N 0x00
-#define RP_DATA_N_TO_MS 0x01
-#define RP_ACK_MS_TO_N 0x02
-#define RP_ACK_N_TO_MS 0x03
-#define RP_ERROR_MS_TO_N 0x04
-#define RP_ERROR_N_TO_MS 0x05
-
#define EXTRANEOUS_DATA_CHECK(edc_len, edc_max_len) \
if ((edc_len) > (edc_max_len)) \
{ \
return; \
}
+#define SMS_SHIFTMASK(m_val, m_bitmask, m_sval); \
+ { \
+ int _temp_val = m_val; \
+ int _temp_bm = m_bitmask; \
+ while (_temp_bm && !(_temp_bm & 0x01)) \
+ { \
+ _temp_bm = _temp_bm >> 1; \
+ _temp_val = _temp_val >> 1; \
+ } \
+ m_sval = _temp_val; \
+ }
+
+
static char *gsm_sms_proto_name = "GSM SMS TPDU (GSM 03.40)";
static char *gsm_sms_proto_name_short = "GSM SMS";
static dissector_handle_t data_handle;
static packet_info *g_pinfo;
static proto_tree *g_tree;
-static gint g_rp_type;
/*
* this is the GSM 03.40 definition with the bit 2
}
/* 9.2.3.1 */
-#define DIS_FIELD_MTI(m_tree, m_offset) \
+#define DIS_FIELD_MTI(m_tree, m_bitmask, m_offset) \
{ \
- other_decode_bitfield_value(bigbuf, oct, 0x03, 8); \
+ other_decode_bitfield_value(bigbuf, oct, m_bitmask, 8); \
proto_tree_add_text(m_tree, tvb, \
m_offset, 1, \
"%s : TP-Message-Type-Indicator", \
}
/* 9.2.3.2 */
-#define DIS_FIELD_MMS(m_tree, m_offset) \
+#define DIS_FIELD_MMS(m_tree, m_bitmask, m_offset) \
{ \
- other_decode_bitfield_value(bigbuf, oct, 0x04, 8); \
+ other_decode_bitfield_value(bigbuf, oct, m_bitmask, 8); \
proto_tree_add_text(m_tree, tvb, \
m_offset, 1, \
"%s : TP-More-Messages-to-Send: %s messages are waiting for the MS in this SC", \
bigbuf, \
- (oct & 0x04) ? "No more" : "More"); \
+ (oct & m_bitmask) ? "No more" : "More"); \
}
/* 9.2.3.3 */
-#define DIS_FIELD_VPF(m_tree, m_offset, m_form) \
+#define DIS_FIELD_VPF(m_tree, m_bitmask, m_offset, m_form) \
{ \
- *m_form = (oct & 0x18) >> 3; \
+ SMS_SHIFTMASK(oct & m_bitmask, m_bitmask, *m_form); \
switch (*m_form) \
{ \
case 0: str = "TP-VP field not present"; break; \
case 2: str = "TP-VP field present - relative format"; break; \
case 3: str = "TP-VP field present - absolute format"; break; \
} \
- other_decode_bitfield_value(bigbuf, oct, 0x18, 8); \
+ other_decode_bitfield_value(bigbuf, oct, m_bitmask, 8); \
proto_tree_add_text(m_tree, tvb, \
m_offset, 1, \
"%s : TP-Validity-Period-Format: %s", \
}
/* 9.2.3.4 */
-#define DIS_FIELD_SRI(m_tree, m_offset) \
+#define DIS_FIELD_SRI(m_tree, m_bitmask, m_offset) \
{ \
- other_decode_bitfield_value(bigbuf, oct, 0x20, 8); \
+ other_decode_bitfield_value(bigbuf, oct, m_bitmask, 8); \
proto_tree_add_text(m_tree, tvb, \
m_offset, 1, \
"%s : TP-Status-Report-Indication: A status report shall %sbe returned to the SME", \
bigbuf, \
- (oct & 0x20) ? "" : "not "); \
+ (oct & m_bitmask) ? "" : "not "); \
}
/* 9.2.3.5 */
-#define DIS_FIELD_SRR(m_tree, m_offset) \
+#define DIS_FIELD_SRR(m_tree, m_bitmask, m_offset) \
{ \
- other_decode_bitfield_value(bigbuf, oct, 0x20, 8); \
+ other_decode_bitfield_value(bigbuf, oct, m_bitmask, 8); \
proto_tree_add_text(m_tree, tvb, \
m_offset, 1, \
"%s : TP-Status-Report-Request: A status report is %srequested", \
bigbuf, \
- (oct & 0x20) ? "" : "not "); \
+ (oct & m_bitmask) ? "" : "not "); \
}
/* 9.2.3.6 */
}
/* 9.2.3.17 */
-#define DIS_FIELD_RP(m_tree, m_offset) \
+#define DIS_FIELD_RP(m_tree, m_bitmask, m_offset) \
{ \
- other_decode_bitfield_value(bigbuf, oct, 0x80, 8); \
+ other_decode_bitfield_value(bigbuf, oct, m_bitmask, 8); \
proto_tree_add_text(m_tree, tvb, \
m_offset, 1, \
"%s : TP-Reply-Path: parameter is %sset in this SMS-SUBMIT/DELIVER", \
bigbuf, \
- (oct & 0x80) ? "" : "not "); \
+ (oct & m_bitmask) ? "" : "not "); \
}
/* 9.2.3.18 */
}
/* 9.2.3.23 */
-#define DIS_FIELD_UDHI(m_tree, m_offset, m_udhi) \
+#define DIS_FIELD_UDHI(m_tree, m_bitmask, m_offset, m_udhi) \
{ \
- m_udhi = (oct & 0x40) >> 6; \
- other_decode_bitfield_value(bigbuf, oct, 0x40, 8); \
+ SMS_SHIFTMASK(oct & m_bitmask, m_bitmask, m_udhi); \
+ other_decode_bitfield_value(bigbuf, oct, m_bitmask, 8); \
proto_tree_add_text(m_tree, tvb, \
m_offset, 1, \
"%s : TP-User-Data-Header-Indicator: %s short message", \
static int
char_7bit_unpack(unsigned int offset, unsigned int in_length, unsigned int out_length,
- unsigned char *input, unsigned char *output)
+ const guint8 *input, unsigned char *output)
{
unsigned char *out_num = output; /* Current pointer to the output buffer */
- unsigned char *in_num = input; /* Current pointer to the input buffer */
+ const guint8 *in_num = input; /* Current pointer to the input buffer */
unsigned char rest = 0x00;
int bits;
static void
dis_field_ud_iei(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint8 length)
{
- void (*iei_fcn)(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint8 length) = NULL;
+ void (*iei_fcn)(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint8 length);
guint8 oct;
proto_item *item;
proto_tree *subtree = NULL;
while (length > 2)
{
+ iei_fcn = NULL;
+
oct = tvb_get_guint8(tvb, offset);
switch (oct)
}
length -= 2 + iei_len;
+ offset += iei_len;
}
}
{
out_len =
char_7bit_unpack(fill_bits, length, sizeof(bigbuf),
- (guchar*) (tvb_get_ptr(tvb, offset, length)), bigbuf);
+ tvb_get_ptr(tvb, offset, length), bigbuf);
bigbuf[out_len] = '\0';
char_ascii_decode(bigbuf, bigbuf, out_len);
+ bigbuf[udl] = '\0';
proto_tree_add_text(subtree, tvb, offset, length, "%s", bigbuf);
}
else if (eight_bit)
{
- proto_tree_add_text(subtree, tvb, offset, length, "%.*s",
- (int)length, tvb_get_ptr(tvb, offset, length));
+ proto_tree_add_text(subtree, tvb, offset, length, "%s",
+ tvb_format_text(tvb, offset, length));
}
else if (ucs2)
{
}
/* 9.2.3.25 */
-#define DIS_FIELD_RD(m_tree, m_offset) \
+#define DIS_FIELD_RD(m_tree, m_bitmask, m_offset) \
{ \
- other_decode_bitfield_value(bigbuf, oct, 0x04, 8); \
+ other_decode_bitfield_value(bigbuf, oct, m_bitmask, 8); \
proto_tree_add_text(m_tree, tvb, \
m_offset, 1, \
"%s : TP-Reject-Duplicates: Instruct SC to %s duplicates", \
bigbuf, \
- (oct & 0x04) ? \
+ (oct & m_bitmask) ? \
"reject" : \
"accept"); \
}
/* 9.2.3.26 */
-#define DIS_FIELD_SRQ(m_tree, m_offset) \
+#define DIS_FIELD_SRQ(m_tree, m_bitmask, m_offset) \
{ \
- other_decode_bitfield_value(bigbuf, oct, 0x20, 8); \
+ other_decode_bitfield_value(bigbuf, oct, m_bitmask, 8); \
proto_tree_add_text(m_tree, tvb, \
m_offset, 1, \
"%s : TP-Status-Report-Qualifier: The SMS-STATUS-REPORT is the result of %s", \
bigbuf, \
- (oct & 0x20) ? \
+ (oct & m_bitmask) ? \
"an SMS-COMMAND e.g. an Enquiry" : \
"a SMS-SUBMIT"); \
}
oct = tvb_get_guint8(tvb, offset);
- DIS_FIELD_RP(tree, offset);
+ DIS_FIELD_SRI(tree, 0x20, offset);
- DIS_FIELD_UDHI(tree, offset, udhi);
+ DIS_FIELD_UDHI(tree, 0x10, offset, udhi);
- DIS_FIELD_SRI(tree, offset);
+ DIS_FIELD_RP(tree, 0x08, offset);
- DIS_FIELD_MMS(tree, offset);
+ DIS_FIELD_MMS(tree, 0x04, offset);
- DIS_FIELD_MTI(tree, offset);
+ DIS_FIELD_MTI(tree, 0x03, offset);
offset++;
oct = tvb_get_guint8(tvb, offset);
- DIS_FIELD_UDHI(tree, offset, udhi);
+ DIS_FIELD_UDHI(tree, 0x04, offset, udhi);
- DIS_FIELD_MTI(tree, offset);
+ DIS_FIELD_MTI(tree, 0x03, offset);
if (length < 2)
{
return;
}
- switch (g_rp_type)
- {
- case RP_ERROR_MS_TO_N:
- /* FALLTHRU */
-
- case RP_ERROR_N_TO_MS:
- offset++;
- oct = tvb_get_guint8(tvb, offset);
+ /*
+ * there does not seem to be a way to determine that this
+ * deliver report is from an RP-ERROR or RP-ACK other
+ * than to look at the next octet
+ *
+ * FCS values are 0x80 and higher
+ * PI uses bit 7 as an extension indicator
+ *
+ * will assume that if bit 7 is set then this octet
+ * is an FCS otherwise PI
+ */
+ offset++;
+ oct = tvb_get_guint8(tvb, offset);
+ if (oct & 0x80)
+ {
dis_field_fcs(tvb, tree, offset, oct);
-
- if (length < 3)
- {
- proto_tree_add_text(tree,
- tvb, saved_offset, length,
- "Short Data (?)");
- return;
- }
- break;
}
offset++;
oct = tvb_get_guint8(tvb, offset);
- DIS_FIELD_RP(tree, offset);
+ DIS_FIELD_SRR(tree, 0x80, offset);
- DIS_FIELD_UDHI(tree, offset, udhi);
+ DIS_FIELD_UDHI(tree, 0x40, offset, udhi);
- DIS_FIELD_SRR(tree, offset);
+ DIS_FIELD_RP(tree, 0x20, offset);
- DIS_FIELD_VPF(tree, offset, &vp_form);
+ DIS_FIELD_VPF(tree, 0x18, offset, &vp_form);
- DIS_FIELD_RD(tree, offset);
+ DIS_FIELD_RD(tree, 0x04, offset);
- DIS_FIELD_MTI(tree, offset);
+ DIS_FIELD_MTI(tree, 0x03, offset);
offset++;
oct = tvb_get_guint8(tvb, offset);
oct = tvb_get_guint8(tvb, offset);
- DIS_FIELD_UDHI(tree, offset, udhi);
-
- DIS_FIELD_MTI(tree, offset);
+ DIS_FIELD_UDHI(tree, 0x04, offset, udhi);
- switch (g_rp_type)
- {
- case RP_ERROR_MS_TO_N:
- /* FALLTHRU */
+ DIS_FIELD_MTI(tree, 0x03, offset);
- case RP_ERROR_N_TO_MS:
- offset++;
- oct = tvb_get_guint8(tvb, offset);
+ /*
+ * there does not seem to be a way to determine that this
+ * deliver report is from an RP-ERROR or RP-ACK other
+ * than to look at the next octet
+ *
+ * FCS values are 0x80 and higher
+ * PI uses bit 7 as an extension indicator
+ *
+ * will assume that if bit 7 is set then this octet
+ * is an FCS otherwise PI
+ */
+ offset++;
+ oct = tvb_get_guint8(tvb, offset);
+ if (oct & 0x80)
+ {
dis_field_fcs(tvb, tree, offset, oct);
- break;
}
offset++;
oct = tvb_get_guint8(tvb, offset);
- DIS_FIELD_SRQ(tree, offset);
+ DIS_FIELD_SRQ(tree, 0x10, offset);
- DIS_FIELD_MMS(tree, offset);
+ DIS_FIELD_MMS(tree, 0x08, offset);
- DIS_FIELD_UDHI(tree, offset, udhi);
+ DIS_FIELD_UDHI(tree, 0x04, offset, udhi);
- DIS_FIELD_MTI(tree, offset);
+ DIS_FIELD_MTI(tree, 0x03, offset);
offset++;
oct = tvb_get_guint8(tvb, offset);
oct = tvb_get_guint8(tvb, offset);
- DIS_FIELD_SRR(tree, offset);
+ DIS_FIELD_SRR(tree, 0x08, offset);
- DIS_FIELD_UDHI(tree, offset, udhi);
+ DIS_FIELD_UDHI(tree, 0x04, offset, udhi);
- DIS_FIELD_MTI(tree, offset);
+ DIS_FIELD_MTI(tree, 0x03, offset);
offset++;
oct = tvb_get_guint8(tvb, offset);
if (tree)
{
g_tree = tree;
- g_rp_type = pinfo->match_port;
offset = 0;
gsm_sms_handle = create_dissector_handle(dissect_gsm_sms, proto_gsm_sms);
- dissector_add("gsm_a.sms_tpdu", RP_DATA_MS_TO_N, gsm_sms_handle);
- dissector_add("gsm_a.sms_tpdu", RP_DATA_N_TO_MS, gsm_sms_handle);
- dissector_add("gsm_a.sms_tpdu", RP_ACK_MS_TO_N, gsm_sms_handle);
- dissector_add("gsm_a.sms_tpdu", RP_ACK_N_TO_MS, gsm_sms_handle);
- dissector_add("gsm_a.sms_tpdu", RP_ERROR_MS_TO_N, gsm_sms_handle);
- dissector_add("gsm_a.sms_tpdu", RP_ERROR_N_TO_MS, gsm_sms_handle);
+ dissector_add("gsm_a.sms_tpdu", 0, gsm_sms_handle);
+ dissector_add("gsm_map.sms_tpdu", 0, gsm_sms_handle);
data_handle = find_dissector("data");
}