Fix for bug 2638:
authorjake <jake@f5534014-38df-0310-8fa8-9805f1628bb7>
Tue, 7 Oct 2008 06:52:15 +0000 (06:52 +0000)
committerjake <jake@f5534014-38df-0310-8fa8-9805f1628bb7>
Tue, 7 Oct 2008 06:52:15 +0000 (06:52 +0000)
Add support for XOT PVC setup dissection.

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@26368 f5534014-38df-0310-8fa8-9805f1628bb7

epan/dissectors/packet-xot.c

index 9bf014b0fcae227554ece646d4fa8e25f3e4eeca..fd7acf2dddd98c377d2a9c4e7974f4ea6df276f2 100644 (file)
@@ -41,6 +41,7 @@
 #define TCP_PORT_XOT 1998
 #define XOT_HEADER_LENGTH 4
 #define XOT_VERSION 0
+#define XOT_PVC_SETUP 0xF5
 
 /* Some X25 macros from packet-x25.c - some adapted code as well below */
 #define X25_MIN_HEADER_LENGTH 3
 #define X25_MBIT_MOD8                  0x10
 #define X25_MBIT_MOD128                        0x01
 
+static const value_string vals_x25_type[] = {
+   { XOT_PVC_SETUP, "PVC Setup" },
+   { 0,   NULL}
+};
+
+static const value_string xot_pvc_status_vals[] = {
+   { 0x00, "Waiting to connect" },
+
+   { 0x08, "Destination disconnected" },
+   { 0x09, "PVC/TCP connection refused" },
+   { 0x0A, "PVC/TCP routing error" },
+   { 0x0B, "PVC/TCP connect timed out" },
+
+   { 0x10, "Trying to connect via TCP" },
+   { 0x11, "Awaiting PVC-SETUP reply" },
+   { 0x12, "Connected" },
+   { 0x13, "No such destination interface" },
+   { 0x14, "Destination interface is not up" },
+   { 0x15, "Non-X.25 destination interface" },
+   { 0x16, "No such destination PVC" },
+   { 0x17, "Destination PVC configuration mismatch" },
+   { 0x18, "Mismatched flow control values" },
+   { 0x19, "Can't support flow control values" },
+   { 0x1A, "PVC setup protocol error" },
+
+   { 0,   NULL}
+};
+
 static dissector_handle_t x25_handle;
 
 static gint proto_xot = -1;
@@ -57,6 +86,23 @@ static gint ett_xot = -1;
 static gint hf_xot_version = -1;
 static gint hf_xot_length = -1;
 
+static gint hf_x25_gfi = -1;
+static gint hf_x25_lcn = -1;
+static gint hf_x25_type = -1;
+
+static gint hf_xot_pvc_version = -1;
+static gint hf_xot_pvc_status = -1;
+static gint hf_xot_pvc_init_itf_name_len = -1;
+static gint hf_xot_pvc_init_lcn = -1;
+static gint hf_xot_pvc_resp_itf_name_len = -1;
+static gint hf_xot_pvc_resp_lcn = -1;
+static gint hf_xot_pvc_send_inc_window = -1;
+static gint hf_xot_pvc_send_out_window = -1;
+static gint hf_xot_pvc_send_inc_pkt_size = -1;
+static gint hf_xot_pvc_send_out_pkt_size = -1;
+static gint hf_xot_pvc_init_itf_name = -1;
+static gint hf_xot_pvc_resp_itf_name = -1;
+
 /* desegmentation of X.25 over multiple TCP */
 static gboolean xot_desegment = TRUE;
 /* desegmentation of X.25 packet sequences */
@@ -84,7 +130,7 @@ static guint get_xot_pdu_len_mult(packet_info *pinfo _U_, tvbuff_t *tvb, int off
    int offset_next = offset + XOT_HEADER_LENGTH + X25_MIN_HEADER_LENGTH;
    int tvb_len;
 
-  while (tvb_len = tvb_length_remaining(tvb, offset), tvb_len>0){
+   while (tvb_len = tvb_length_remaining(tvb, offset), tvb_len>0){
       guint16 plen = 0;
       int modulo;
       guint16 bytes0_1;
@@ -109,7 +155,7 @@ static guint get_xot_pdu_len_mult(packet_info *pinfo _U_, tvbuff_t *tvb, int off
       if (tvb_len < plen){
          return offset_next-offset_before;
       }
-      
+
       /*Some minor code copied from packet-x25.c */
       bytes0_1 = tvb_get_ntohs(tvb,  offset_x25+0);
       pkt_type = tvb_get_guint8(tvb, offset_x25+2);
@@ -136,7 +182,7 @@ static guint get_xot_pdu_len_mult(packet_info *pinfo _U_, tvbuff_t *tvb, int off
       offset = offset_next;
       offset_next += XOT_HEADER_LENGTH + X25_MIN_HEADER_LENGTH;
   }
-  
+
   /* not enough data */
   pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
   return offset_next - offset_before;
@@ -147,8 +193,9 @@ static void dissect_xot_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
   int offset = 0;
   guint16 version;
   guint16 plen;
-  proto_item *ti;
-  proto_tree *xot_tree;
+  guint8 pkt_type;
+  proto_item *ti = NULL;
+  proto_tree *xot_tree = NULL;
   tvbuff_t   *next_tvb;
 
   /*
@@ -174,8 +221,7 @@ static void dissect_xot_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
         proto_tree_add_uint(xot_tree, hf_xot_version, tvb, offset, 2, version);
         proto_tree_add_uint(xot_tree, hf_xot_length, tvb, offset + 2, 2, plen);
      }
-  
-     plen = tvb_get_ntohs(tvb, offset + 2);
+
      offset += XOT_HEADER_LENGTH;
      /*
       * Construct a tvbuff containing the amount of the payload we have
@@ -183,9 +229,54 @@ static void dissect_xot_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
       * X.25-over-TCP packet.
       */
      if (plen >= X25_MIN_HEADER_LENGTH) {
-        next_tvb = tvb_new_subset(tvb, offset,
+        pkt_type = tvb_get_guint8(tvb, offset + 2);
+        if (pkt_type == XOT_PVC_SETUP) {
+           guint init_itf_name_len, resp_itf_name_len, pkt_size;
+           gint hdr_offset = offset;
+
+           if (check_col(pinfo->cinfo, COL_INFO))
+              col_add_fstr(pinfo->cinfo, COL_INFO, "XOT PVC Setup");
+           proto_item_set_len(ti, XOT_HEADER_LENGTH + plen);
+
+           /* These fields are in overlay with packet-x25.c */
+           proto_tree_add_item(xot_tree, hf_x25_gfi, tvb, hdr_offset, 2, FALSE);
+           proto_tree_add_item(xot_tree, hf_x25_lcn, tvb, hdr_offset, 2, FALSE);
+           hdr_offset += 2;
+           proto_tree_add_item(xot_tree, hf_x25_type, tvb, hdr_offset, 1, FALSE);
+           hdr_offset += 1;
+
+           proto_tree_add_item(xot_tree, hf_xot_pvc_version, tvb, hdr_offset, 1, FALSE);
+           hdr_offset += 1;
+           proto_tree_add_item(xot_tree, hf_xot_pvc_status, tvb, hdr_offset, 1, FALSE);
+           hdr_offset += 1;
+           proto_tree_add_item(xot_tree, hf_xot_pvc_init_itf_name_len, tvb, hdr_offset, 1, FALSE);
+           init_itf_name_len = tvb_get_guint8(tvb, hdr_offset);
+           hdr_offset += 1;
+           proto_tree_add_item(xot_tree, hf_xot_pvc_init_lcn, tvb, hdr_offset, 2, FALSE);
+           hdr_offset += 2;
+           proto_tree_add_item(xot_tree, hf_xot_pvc_resp_itf_name_len, tvb, hdr_offset, 1, FALSE);
+           resp_itf_name_len = tvb_get_guint8(tvb, hdr_offset);
+           hdr_offset += 1;
+           proto_tree_add_item(xot_tree, hf_xot_pvc_resp_lcn, tvb, hdr_offset, 2, FALSE);
+           hdr_offset += 2;
+           proto_tree_add_item(xot_tree, hf_xot_pvc_send_inc_window, tvb, hdr_offset, 1, FALSE);
+           hdr_offset += 1;
+           proto_tree_add_item(xot_tree, hf_xot_pvc_send_out_window, tvb, hdr_offset, 1, FALSE);
+           hdr_offset += 1;
+           pkt_size = 1 << tvb_get_guint8(tvb, hdr_offset);
+           proto_tree_add_uint(xot_tree, hf_xot_pvc_send_inc_pkt_size, tvb, hdr_offset, 1, pkt_size);
+           hdr_offset += 1;
+           pkt_size = 1 << tvb_get_guint8(tvb, hdr_offset);
+           proto_tree_add_uint(xot_tree, hf_xot_pvc_send_out_pkt_size, tvb, hdr_offset, 1, pkt_size);
+           hdr_offset += 1;
+           proto_tree_add_item(xot_tree, hf_xot_pvc_init_itf_name, tvb, hdr_offset, init_itf_name_len, FALSE);
+           hdr_offset += init_itf_name_len;
+           proto_tree_add_item(xot_tree, hf_xot_pvc_resp_itf_name, tvb, hdr_offset, resp_itf_name_len, FALSE);
+        } else {
+           next_tvb = tvb_new_subset(tvb, offset,
                                   MIN(plen, tvb_length_remaining(tvb, offset)), plen);
-        call_dissector(x25_handle, next_tvb, pinfo, tree);
+           call_dissector(x25_handle, next_tvb, pinfo, tree);
+        }
      }
      offset += plen;
 }
@@ -206,12 +297,12 @@ static void dissect_xot_mult(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
       xot_tree = proto_item_add_subtree(ti, ett_xot);
       proto_tree_add_uint(xot_tree, hf_xot_length, tvb, offset, offset_max, len);
    }
-      
+
    while (offset <= offset_max - XOT_HEADER_LENGTH){
       int plen = get_xot_pdu_len(pinfo, tvb, offset);
       next_tvb = tvb_new_subset(tvb, offset,plen, plen);
                                 /*MIN(plen,tvb_length_remaining(tvb, offset)),plen*/
-                                
+
       dissect_xot_pdu(next_tvb, pinfo, tree);
       offset += plen;
    }
@@ -220,11 +311,11 @@ static int dissect_xot_tcp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
 {
    int tvb_len = tvb_length(tvb);
    int len = 0;
-   
+
    if (tvb_len >= 2 && tvb_get_ntohs(tvb,0) != XOT_VERSION) {
       return 0;
    }
-   
+
    if (!x25_desegment || !xot_desegment){
       tcp_dissect_pdus(tvb, pinfo, tree, xot_desegment,
                        XOT_HEADER_LENGTH,
@@ -270,12 +361,71 @@ proto_register_xot(void)
 
                { &hf_xot_length,
                        { "Length", "xot.length", FT_UINT16, BASE_DEC,
-                       NULL, 0, "Length of X.25 over TCP packet", HFILL }}
-
+                       NULL, 0, "Length of X.25 over TCP packet", HFILL }},
+               /* These fields are in overlay with packet-x25.c */
+               { &hf_x25_gfi,
+                       { "GFI", "x.25.gfi", FT_UINT16, BASE_DEC,
+                       NULL, 0xF000, "General Format Identifier", HFILL }},
+
+               { &hf_x25_lcn,
+                       { "Logical Channel", "x.25.lcn", FT_UINT16, BASE_DEC,
+                       NULL, 0x0FFF, "Logical Channel Number", HFILL }},
+
+               { &hf_x25_type,
+                       { "Packet Type", "x.25.type", FT_UINT8, BASE_HEX,
+                       VALS(vals_x25_type), 0x0, "Packet Type", HFILL }},
+
+               { &hf_xot_pvc_version,
+                       { "Version", "xot.pvc.version", FT_UINT8, BASE_HEX,
+                       NULL, 0, NULL, HFILL }},
+
+               { &hf_xot_pvc_status,
+                       { "Status", "xot.pvc.status", FT_UINT8, BASE_HEX,
+                       VALS(xot_pvc_status_vals), 0, NULL, HFILL }},
+
+               { &hf_xot_pvc_init_itf_name_len,
+                       { "Initiator interface name length", "xot.pvc.init_itf_name_len", FT_UINT8, BASE_DEC,
+                       NULL, 0, NULL, HFILL }},
+
+               { &hf_xot_pvc_init_lcn,
+                       { "Initiator LCN", "xot.pvc.init_lcn", FT_UINT8, BASE_DEC,
+                       NULL, 0, "Initiator Logical Channel Number", HFILL }},
+
+               { &hf_xot_pvc_resp_itf_name_len,
+                       { "Responder interface name length", "xot.pvc.resp_itf_name_len", FT_UINT8, BASE_DEC,
+                       NULL, 0, NULL, HFILL }},
+
+               { &hf_xot_pvc_resp_lcn,
+                       { "Responder LCN", "xot.pvc.resp_lcn", FT_UINT16, BASE_DEC,
+                       NULL, 0, "Responder Logical Channel Number", HFILL }},
+
+               { &hf_xot_pvc_send_inc_window,
+                       { "Sender incoming window", "xot.pvc.send_inc_window", FT_UINT8, BASE_DEC,
+                       NULL, 0, NULL, HFILL }},
+
+               { &hf_xot_pvc_send_out_window,
+                       { "Sender outgoing window", "xot.pvc.send_out_window", FT_UINT8, BASE_DEC,
+                       NULL, 0, NULL, HFILL }},
+
+               { &hf_xot_pvc_send_inc_pkt_size,
+                       { "Sender incoming packet size", "xot.pvc.send_inc_pkt_size", FT_UINT8, BASE_DEC,
+                       NULL, 0, NULL, HFILL }},
+
+               { &hf_xot_pvc_send_out_pkt_size,
+                       { "Sender outgoing packet size", "xot.pvc.send_out_pkt_size", FT_UINT8, BASE_DEC,
+                       NULL, 0, NULL, HFILL }},
+
+               { &hf_xot_pvc_init_itf_name,
+                       { "Initiator interface name", "xot.pvc.init_itf_name", FT_STRING, BASE_NONE,
+                       NULL, 0, NULL, HFILL }},
+
+               { &hf_xot_pvc_resp_itf_name,
+                       { "Responder interface name", "xot.pvc.resp_itf_name", FT_STRING, BASE_NONE,
+                       NULL, 0, NULL, HFILL }}
        };
 
        static gint *ett[] = {
-               &ett_xot,
+               &ett_xot
        };
        module_t *xot_module;
 
@@ -283,8 +433,8 @@ proto_register_xot(void)
        proto_register_field_array(proto_xot, hf, array_length(hf));
        proto_register_subtree_array(ett, array_length(ett));
        new_register_dissector("xot", dissect_xot_tcp_heur, proto_xot);
-       xot_module = prefs_register_protocol(proto_xot, NULL);
-        
+       xot_module = prefs_register_protocol(proto_xot, NULL);
+
        prefs_register_bool_preference(xot_module, "desegment",
            "Reassemble X.25-over-TCP messages spanning multiple TCP segments",
            "Whether the X.25-over-TCP dissector should reassemble messages spanning multiple TCP segments. "
@@ -293,7 +443,7 @@ proto_register_xot(void)
        prefs_register_bool_preference(xot_module, "x25_desegment",
            "Reassemble X.25 packets with More flag to enable safe X.25 reassembly",
            "Whether the X.25-over-TCP dissector should reassemble all X.25 packets before calling the X25 dissector. "
-            "If the TCP packets arrive out-of-order, the X.25 reassembly can otherwise fail. "
+           "If the TCP packets arrive out-of-order, the X.25 reassembly can otherwise fail. "
            "To use this option, you should also enable \"Reassemble X.25-over-TCP messages spanning multiple TCP segments\", \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings and \"Reassemble fragmented X.25 packets\" in the X.25 protocol settings.",
            &x25_desegment);