Frame numbers are unsigned.
[obnox/wireshark/wip.git] / packet-wtp.c
index 007c29db0c48a29ad02713d95e2ff0130e27eec3..692d076a25509461d65afecccc9b21e600166bef 100644 (file)
@@ -2,7 +2,7 @@
  *
  * Routines to dissect WTP component of WAP traffic.
  *
- * $Id: packet-wtp.c,v 1.42 2002/12/19 11:22:38 sahlberg Exp $
+ * $Id: packet-wtp.c,v 1.48 2003/05/24 16:54:42 gerald Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -213,6 +213,7 @@ static const fragment_items wtp_frag_items = {
     &hf_wtp_fragment_multiple_tails,
     &hf_wtp_fragment_too_long_fragment,
     &hf_wtp_fragment_error,
+    NULL,
     "fragments"
 };
 
@@ -307,7 +308,7 @@ wtp_handle_tpi(proto_tree *tree, tvbuff_t *tvb)
 static void
 dissect_wtp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 {
-    char       szInfo[50];
+    static GString *szInfo = NULL;
     int                offCur          = 0; /* current offset from start of WTP data */
 
     unsigned char  b0;
@@ -326,7 +327,6 @@ dissect_wtp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 
     char               pdut;
     char               clsTransaction  = ' ';
-    int                        cchInfo;
     int                        numMissing = 0;         /* Number of missing packets in a negative ack */
     int                        i;
     tvbuff_t           *wsp_tvb = NULL;
@@ -334,6 +334,9 @@ dissect_wtp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
     guint8             psn = 0;                /* Packet sequence number*/
     guint16            TID = 0;                /* Transaction-Id       */
 
+    if (szInfo == NULL)
+       szInfo = g_string_sized_new(32);
+
     b0 = tvb_get_guint8 (tvb, offCur + 0);
     /* Discover Concatenated PDUs */
     if (b0 == 0) {
@@ -357,13 +360,13 @@ dissect_wtp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                c_pdulen = b0;
            }
            if (tree) {
-               proto_tree_add_item(wtp_tree, hf_wtp_header_sub_pdu_size,
-                                   tvb, offCur, c_fieldlen, bo_big_endian);
+               proto_tree_add_uint(wtp_tree, hf_wtp_header_sub_pdu_size,
+                                   tvb, offCur, c_fieldlen, c_pdulen);
            }
            if (i > 1 && check_col(pinfo->cinfo, COL_INFO)) {
                col_append_str(pinfo->cinfo, COL_INFO, ", ");
            }
-           wsp_tvb = tvb_new_subset(tvb, offCur + c_fieldlen, -1, c_pdulen);
+           wsp_tvb = tvb_new_subset(tvb, offCur + c_fieldlen, c_pdulen, c_pdulen);
            dissect_wtp_common(wsp_tvb, pinfo, wtp_tree);
            offCur += c_fieldlen + c_pdulen;
            i++;
@@ -375,7 +378,7 @@ dissect_wtp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
     pdut = pdu_type(b0);
 
     /* Develop the string to put in the Info column */
-    cchInfo = snprintf(szInfo, sizeof( szInfo ), "WTP %s",
+    g_string_sprintf(szInfo, "WTP %s",
                    val_to_str(pdut, vals_pdu_type, "Unknown PDU type 0x%x"));
 
     switch (pdut) {
@@ -384,8 +387,7 @@ dissect_wtp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
            TID = tvb_get_ntohs(tvb, offCur + 1);
            psn = 0;
            clsTransaction = transaction_class(tvb_get_guint8(tvb, offCur + 3));
-           snprintf(szInfo + cchInfo, sizeof(szInfo) - cchInfo,
-                    " Class %d", clsTransaction);
+           g_string_sprintfa(szInfo, " Class %d", clsTransaction);
            cbHeader = 4;
            break;
 
@@ -422,7 +424,7 @@ dissect_wtp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
            break;
     };
     if (fRID) {
-       strcat( szInfo, " R" );
+       g_string_append( szInfo, " R" );
     };
     if (fCon) {                                /* Scan variable part (TPI's),  */
                                        /* determine length of it       */
@@ -451,9 +453,9 @@ dissect_wtp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        ((tvb_length_remaining(tvb, offCur + cbHeader + vHeader) <= 0) ||
         (pdut == ACK) || (pdut==NEGATIVE_ACK) || (pdut==ABORT)) ) {
 #ifdef DEBUG
-       fprintf(stderr, "dissect_wtp: (6) About to set info_col header to %s\n", szInfo);
+       fprintf(stderr, "dissect_wtp: (6) About to set info_col header to %s\n", szInfo->str);
 #endif
-       col_append_str(pinfo->cinfo, COL_INFO, szInfo);
+       col_append_str(pinfo->cinfo, COL_INFO, szInfo->str);
     };
     /* In the interest of speed, if "tree" is NULL, don't do any work not
        necessary to generate protocol tree items. */
@@ -555,7 +557,7 @@ dissect_wtp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                /* Iterate through missing packets */
                for (i = 0; i < numMissing; i++)
                {
-                   proto_tree_add_item(wtp_tree, hf_wtp_header_sequence_number, tvb, offCur + i, 1, bo_little_endian);
+                   proto_tree_add_item(wtp_tree, hf_wtp_header_sequence_number, tvb, offCur + 4 + i, 1, bo_little_endian);
                }
                break;
 
@@ -595,15 +597,16 @@ dissect_wtp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
      * Any remaining data ought to be WSP data (if not WTP ACK, NACK
      * or ABORT pdu), so hand off (defragmented) to the WSP dissector
      */
-    if ((tvb_length_remaining(tvb, offCur + cbHeader + vHeader) > 0) &&
+    if ((tvb_reported_length_remaining(tvb, offCur + cbHeader + vHeader) > 0) &&
        ! ((pdut==ACK) || (pdut==NEGATIVE_ACK) || (pdut==ABORT)))
     {
        int     dataOffset = offCur + cbHeader + vHeader;
-       guint32 dataLen = tvb_length_remaining(tvb, offCur + cbHeader + vHeader);
+       gint    dataLen = tvb_reported_length_remaining(tvb, dataOffset);
        gboolean save_fragmented;
 
-       if ((pdut == SEGMENTED_INVOKE) || (pdut == SEGMENTED_RESULT) ||
-           (((pdut == INVOKE) || (pdut == RESULT)) && (!fTTR)))
+       if (((pdut == SEGMENTED_INVOKE) || (pdut == SEGMENTED_RESULT) ||
+           (((pdut == INVOKE) || (pdut == RESULT)) && (!fTTR))) &&
+           tvb_bytes_exist(tvb, dataOffset, dataLen))
        {                                       /* 1st part of segment  */
            save_fragmented = pinfo->fragmented;
            pinfo->fragmented = TRUE;
@@ -628,13 +631,17 @@ dissect_wtp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
            else
            {
                if (check_col(pinfo->cinfo, COL_INFO))          /* Won't call WSP so display */
-                   col_append_str(pinfo->cinfo, COL_INFO, szInfo);
+                   col_append_str(pinfo->cinfo, COL_INFO, szInfo->str);
            }
            pinfo->fragmented = save_fragmented;
        }
-       else                    /* Normal packet, call next dissector   */
+       else
        {
-           wsp_tvb = tvb_new_subset(tvb, dataOffset, -1, dataLen);
+           /*
+            * Normal packet, or not all the fragment data is available;
+            * call next dissector.
+            */
+           wsp_tvb = tvb_new_subset(tvb, dataOffset, -1, -1);
            call_dissector(wsp_handle, wsp_tvb, pinfo, tree);
        }
     }
@@ -685,8 +692,8 @@ proto_register_wtp(void)
        { &hf_wtp_header_sub_pdu_size,
            {   "Sub PDU size",
                "wtp.sub_pdu_size",
-               FT_BYTES, BASE_HEX, NULL, 0x0,
-               "Size of Sub-PDU", HFILL
+               FT_UINT16, BASE_DEC, NULL, 0x0,
+               "Size of Sub-PDU (bytes)", HFILL
            }
        },
        { &hf_wtp_header_flag_continue,