various string related changes, mainly replace sprintf/snprintf by g_snprintf
[obnox/wireshark/wip.git] / packet-gsm_sms.c
index 4f0bdef75c3a5f29353aa5c96d002f6b04d2ee8c..c28e932401ed2d39d1a78c304f8ecd6a79af27c0 100644 (file)
@@ -11,7 +11,7 @@
  *   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";
 
@@ -110,7 +116,6 @@ static char bigbuf[1024];
 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
@@ -153,9 +158,9 @@ my_match_strval(guint32 val, const value_string *vs, gint *idx)
 }
 
 /* 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", \
@@ -163,20 +168,20 @@ my_match_strval(guint32 val, const value_string *vs, gint *idx)
 }
 
 /* 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; \
@@ -184,7 +189,7 @@ my_match_strval(guint32 val, const value_string *vs, gint *idx)
     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", \
@@ -193,25 +198,25 @@ my_match_strval(guint32 val, const value_string *vs, gint *idx)
 }
 
 /* 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 */
@@ -1226,14 +1231,14 @@ dis_field_st(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint8 oct)
 }
 
 /* 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 */
@@ -1367,10 +1372,10 @@ dis_field_fcs(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint8 oct)
 }
 
 /* 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", \
@@ -1389,10 +1394,10 @@ dis_field_fcs(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint8 oct)
 
 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;
 
@@ -1616,7 +1621,7 @@ dis_iei_apa_16bit(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint8 length
 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;
@@ -1626,6 +1631,8 @@ dis_field_ud_iei(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint8 length)
 
     while (length > 2)
     {
+       iei_fcn = NULL;
+
        oct = tvb_get_guint8(tvb, offset);
 
        switch (oct)
@@ -1736,6 +1743,7 @@ dis_field_ud_iei(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint8 length)
        }
 
        length -= 2 + iei_len;
+       offset += iei_len;
     }
 }
 
@@ -1821,16 +1829,17 @@ dis_field_ud(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint32 length, gb
        {
            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)
        {
@@ -1842,27 +1851,27 @@ dis_field_ud(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint32 length, gb
 }
 
 /* 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"); \
 }
@@ -1940,15 +1949,15 @@ dis_msg_deliver(tvbuff_t *tvb, proto_tree *tree, guint32 offset)
 
     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++;
 
@@ -2005,9 +2014,9 @@ dis_msg_deliver_report(tvbuff_t *tvb, proto_tree *tree, guint32 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)
     {
@@ -2017,25 +2026,23 @@ dis_msg_deliver_report(tvbuff_t *tvb, proto_tree *tree, guint32 offset)
        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++;
@@ -2126,17 +2133,17 @@ dis_msg_submit(tvbuff_t *tvb, proto_tree *tree, guint32 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);
@@ -2198,21 +2205,27 @@ dis_msg_submit_report(tvbuff_t *tvb, proto_tree *tree, guint32 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++;
@@ -2290,13 +2303,13 @@ dis_msg_status_report(tvbuff_t *tvb, proto_tree *tree, guint32 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);
@@ -2399,11 +2412,11 @@ dis_msg_command(tvbuff_t *tvb, proto_tree *tree, guint32 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);
@@ -2487,7 +2500,6 @@ dissect_gsm_sms(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
     if (tree)
     {
        g_tree = tree;
-       g_rp_type = pinfo->match_port;
 
        offset = 0;
 
@@ -2606,12 +2618,8 @@ proto_reg_handoff_gsm_sms(void)
 
     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");
 }