GTK: Wrap static preference labels.
[metze/wireshark/wip.git] / epan / dissectors / packet-mbtcp.c
index 56296521e01a17cca2e23f331eb76375a6e2d155..4a71d352d77446d03d5130cafb42047a22a1d293 100644 (file)
@@ -174,17 +174,19 @@ static dissector_table_t   modbus_dissector_table;
 /* Globals for Modbus/TCP Preferences */
 static gboolean mbtcp_desegment = TRUE;
 static guint global_mbus_tcp_port = PORT_MBTCP; /* Port 502, by default */
+static guint global_mbus_udp_port = PORT_MBTCP; /* Port 502, by default */
 
 /* Globals for Modbus RTU over TCP Preferences */
 static gboolean mbrtu_desegment = TRUE;
-static guint global_mbus_rtu_port = PORT_MBRTU; /* 0, by default        */
+static guint global_mbus_tcp_rtu_port = PORT_MBRTU; /* 0, by default        */
+static guint global_mbus_udp_rtu_port = PORT_MBRTU; /* 0, by default        */
 static gboolean mbrtu_crc = FALSE;
 
 /* Globals for Modbus Preferences */
 static gint global_mbus_register_format = MODBUS_PREF_REGISTER_FORMAT_UINT16;
 
 static int
-classify_mbtcp_packet(packet_info *pinfo)
+classify_mbtcp_packet(packet_info *pinfo, guint port)
 {
     /* see if nature of packets can be derived from src/dst ports */
     /* if so, return as found */
@@ -193,9 +195,9 @@ classify_mbtcp_packet(packet_info *pinfo)
     /* the Modbus/TCP transaction ID for each pair of messages would allow for detection based on a new seq. number. */
     /* Otherwise, we can stick with this method; a configurable port option has been added to allow for usage of     */
     /* user ports either than the default of 502.                                                                    */
-    if (( pinfo->srcport == global_mbus_tcp_port ) && ( pinfo->destport != global_mbus_tcp_port ))
+    if (( pinfo->srcport == port ) && ( pinfo->destport != port ))
         return RESPONSE_PACKET;
-    if (( pinfo->srcport != global_mbus_tcp_port ) && ( pinfo->destport == global_mbus_tcp_port ))
+    if (( pinfo->srcport != port ) && ( pinfo->destport == port ))
         return QUERY_PACKET;
 
     /* else, cannot classify */
@@ -203,7 +205,7 @@ classify_mbtcp_packet(packet_info *pinfo)
 }
 
 static int
-classify_mbrtu_packet(packet_info *pinfo, tvbuff_t *tvb)
+classify_mbrtu_packet(packet_info *pinfo, tvbuff_t *tvb, guint port)
 {
     guint8 func, len;
 
@@ -212,9 +214,9 @@ classify_mbrtu_packet(packet_info *pinfo, tvbuff_t *tvb)
 
     /* see if nature of packets can be derived from src/dst ports */
     /* if so, return as found */
-    if (( pinfo->srcport == global_mbus_rtu_port ) && ( pinfo->destport != global_mbus_rtu_port ))
+    if (( pinfo->srcport == port ) && ( pinfo->destport != port ))
         return RESPONSE_PACKET;
-    if (( pinfo->srcport != global_mbus_rtu_port ) && ( pinfo->destport == global_mbus_rtu_port ))
+    if (( pinfo->srcport != port ) && ( pinfo->destport == port ))
         return QUERY_PACKET;
 
 
@@ -393,7 +395,7 @@ static const enum_val_t mbus_register_format[] = {
 
 /* Code to dissect Modbus/TCP packets */
 static int
-dissect_mbtcp_pdu_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int proto)
+dissect_mbtcp_pdu_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int proto, guint port)
 {
 /* Set up structures needed to add the protocol subtree and manage it */
     proto_item    *mi;
@@ -416,7 +418,7 @@ dissect_mbtcp_pdu_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
     offset = 0;
 
     /* "Request" or "Response" */
-    packet_type = classify_mbtcp_packet(pinfo);
+    packet_type = classify_mbtcp_packet(pinfo, port);
 
     switch ( packet_type ) {
         case QUERY_PACKET :
@@ -517,12 +519,12 @@ dissect_mbtcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* dat
     col_set_str(pinfo->cinfo, COL_PROTOCOL, "Modbus/TCP");
     col_clear(pinfo->cinfo, COL_INFO);
 
-    return dissect_mbtcp_pdu_common(tvb, pinfo, tree, proto_mbtcp);
+    return dissect_mbtcp_pdu_common(tvb, pinfo, tree, proto_mbtcp, global_mbus_tcp_port);
 }
 
-/* Code to dissect Modbus RTU over TCP packets */
+/* Code to dissect Modbus RTU */
 static int
-dissect_mbrtu_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
+dissect_mbrtu_pdu_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint port)
 {
 /* Set up structures needed to add the protocol subtree and manage it */
     proto_item    *mi;
@@ -547,7 +549,7 @@ dissect_mbrtu_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* dat
     offset = 0;
 
     /* "Request" or "Response" */
-    packet_type = classify_mbrtu_packet(pinfo, tvb);
+    packet_type = classify_mbrtu_packet(pinfo, tvb, port);
 
     switch ( packet_type ) {
         case QUERY_PACKET :
@@ -650,6 +652,12 @@ dissect_mbrtu_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* dat
     return tvb_captured_length(tvb);
 }
 
+/* Code to dissect Modbus RTU over TCP packets */
+static int
+dissect_mbrtu_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
+{
+    return dissect_mbrtu_pdu_common(tvb, pinfo, tree, global_mbus_tcp_rtu_port);
+}
 
 /* Return length of Modbus/TCP message */
 static guint
@@ -685,7 +693,7 @@ get_mbrtu_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb,
              the rest can be added as pcap examples are made available */
 
     /* Determine "Query" or "Response" */
-    packet_type = classify_mbrtu_packet(pinfo, tvb);
+    packet_type = classify_mbrtu_packet(pinfo, tvb, global_mbus_tcp_rtu_port);
 
     switch ( packet_type ) {
         case QUERY_PACKET :
@@ -786,7 +794,7 @@ dissect_mbudp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U
     col_set_str(pinfo->cinfo, COL_PROTOCOL, "Modbus/UDP");
     col_clear(pinfo->cinfo, COL_INFO);
 
-    return dissect_mbtcp_pdu_common(tvb, pinfo, tree, proto_mbudp);
+    return dissect_mbtcp_pdu_common(tvb, pinfo, tree, proto_mbudp, global_mbus_udp_port);
 }
 
 /* Code to dissect Modbus RTU over TCP messages */
@@ -812,7 +820,7 @@ dissect_mbrtu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
 }
 
 static int
-dissect_mbrtu_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
+dissect_mbrtu_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
 {
 
     /* Make sure there's at least enough data to determine it's a Modbus packet */
@@ -820,7 +828,7 @@ dissect_mbrtu_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *dat
     if (tvb_reported_length(tvb) < 5)
         return 0;
 
-    return dissect_mbrtu_pdu(tvb, pinfo, tree, data);
+    return dissect_mbrtu_pdu_common(tvb, pinfo, tree, global_mbus_udp_rtu_port);
 }
 
 
@@ -865,7 +873,7 @@ dissect_modbus_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint8
     }
 
     /* Build a new tvb containing just the data payload   */
-    next_tvb = tvb_new_subset(tvb, payload_start, payload_len, reported_len);
+    next_tvb = tvb_new_subset_length_caplen(tvb, payload_start, payload_len, reported_len);
 
     switch ( function_code ) {
 
@@ -1573,6 +1581,22 @@ dissect_modbus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
     return tvb_captured_length(tvb);
 }
 
+static void
+apply_mbtcp_prefs(void)
+{
+    /* Modbus/RTU uses the port preference to determine request/response */
+    global_mbus_tcp_port = prefs_get_uint_value("mbtcp", "tcp.port");
+    global_mbus_udp_port = prefs_get_uint_value("mbudp", "udp.port");
+}
+
+static void
+apply_mbrtu_prefs(void)
+{
+    /* Modbus/RTU uses the port preference to determine request/response */
+    global_mbus_tcp_rtu_port = prefs_get_uint_value("mbrtu", "tcp.port");
+    global_mbus_udp_rtu_port = prefs_get_uint_value("mbrtu", "udp.port");
+}
+
 /* Register the protocol with Wireshark */
 void
 proto_register_modbus(void)
@@ -1972,8 +1996,8 @@ proto_register_modbus(void)
     mbudp_handle = register_dissector("mbudp", dissect_mbudp, proto_mbudp);
 
     /* Registering subdissectors table */
-    modbus_data_dissector_table = register_dissector_table("modbus.data", "Modbus Data", proto_modbus, FT_STRING, BASE_NONE, DISSECTOR_TABLE_NOT_ALLOW_DUPLICATE);
-    modbus_dissector_table = register_dissector_table("mbtcp.prot_id", "Modbus/TCP protocol identifier", proto_mbtcp, FT_UINT16, BASE_DEC, DISSECTOR_TABLE_NOT_ALLOW_DUPLICATE);
+    modbus_data_dissector_table = register_dissector_table("modbus.data", "Modbus Data", proto_modbus, FT_STRING, BASE_NONE);
+    modbus_dissector_table = register_dissector_table("mbtcp.prot_id", "Modbus/TCP protocol identifier", proto_mbtcp, FT_UINT16, BASE_DEC);
 
     /* Required function calls to register the header fields and subtrees used */
     proto_register_field_array(proto_mbtcp, mbtcp_hf, array_length(mbtcp_hf));
@@ -1989,8 +2013,8 @@ proto_register_modbus(void)
 
 
     /* Register required preferences for Modbus Protocol variants */
-    mbtcp_module = prefs_register_protocol(proto_mbtcp, proto_reg_handoff_mbtcp);
-    mbrtu_module = prefs_register_protocol(proto_mbrtu, proto_reg_handoff_mbrtu);
+    mbtcp_module = prefs_register_protocol(proto_mbtcp, apply_mbtcp_prefs);
+    mbrtu_module = prefs_register_protocol(proto_mbrtu, apply_mbrtu_prefs);
     modbus_module = prefs_register_protocol(proto_modbus, NULL);
 
     /* Modbus RTU Preference - Desegment, defaults to TRUE for TCP desegmentation */
@@ -1999,12 +2023,6 @@ proto_register_modbus(void)
                                   "Whether the Modbus RTU dissector should desegment all messages spanning multiple TCP segments",
                                   &mbtcp_desegment);
 
-    /* Modbus/TCP Preference - Default TCP Port, allows for "user" port either than 502. */
-    prefs_register_uint_preference(mbtcp_module, "tcp.port", "Modbus/TCP Port",
-                       "Set the TCP port for Modbus/TCP packets (if other"
-                       " than the default of 502)",
-                       10, &global_mbus_tcp_port);
-
     /* Modbus RTU Preference - Desegment, defaults to TRUE for TCP desegmentation */
     prefs_register_bool_preference(mbrtu_module, "desegment",
                                   "Desegment all Modbus RTU packets spanning multiple TCP segments",
@@ -2017,18 +2035,13 @@ proto_register_modbus(void)
                                   "Whether to validate the CRC",
                                   &mbrtu_crc);
 
-    /* Modbus RTU Preference - Default TCP Port, defaults to zero, allows custom user port. */
-    prefs_register_uint_preference(mbrtu_module, "tcp.port", "Modbus RTU Port",
-                       "Set the TCP/UDP port for encapsulated Modbus RTU packets",
-                       10, &global_mbus_rtu_port);
-
     /* Modbus Preference - Holding/Input Register format, this allows for deeper dissection of response data */
     prefs_register_enum_preference(modbus_module, "mbus_register_format",
                                     "Holding/Input Register Format",
                                     "Register Format",
                                     &global_mbus_register_format,
                                     mbus_register_format,
-                                    TRUE);
+                                    FALSE);
 
     /* Obsolete Preferences */
     prefs_register_obsolete_preference(mbtcp_module, "mbus_register_addr_type");
@@ -2046,20 +2059,8 @@ proto_register_modbus(void)
 void
 proto_reg_handoff_mbtcp(void)
 {
-    static unsigned int mbtcp_port;
-
-    /* Make sure to use Modbus/TCP Preferences field to determine default TCP port */
-    if(mbtcp_port != 0 && mbtcp_port != global_mbus_tcp_port){
-        dissector_delete_uint("tcp.port", mbtcp_port, mbtcp_handle);
-        dissector_delete_uint("udp.port", mbtcp_port, mbudp_handle);
-    }
-
-    if(global_mbus_tcp_port != 0 && mbtcp_port != global_mbus_tcp_port) {
-        dissector_add_uint("tcp.port", global_mbus_tcp_port, mbtcp_handle);
-        dissector_add_uint("udp.port", global_mbus_tcp_port, mbudp_handle);
-    }
-
-    mbtcp_port = global_mbus_tcp_port;
+    dissector_add_uint_with_preference("tcp.port", PORT_MBTCP, mbtcp_handle);
+    dissector_add_uint_with_preference("udp.port", PORT_MBTCP, mbudp_handle);
 
     dissector_add_uint("mbtcp.prot_id", MODBUS_PROTOCOL_ID, modbus_handle);
 
@@ -2068,25 +2069,17 @@ proto_reg_handoff_mbtcp(void)
 void
 proto_reg_handoff_mbrtu(void)
 {
-    static unsigned int mbrtu_port = 0;
     dissector_handle_t mbrtu_udp_handle = create_dissector_handle(dissect_mbrtu_udp, proto_mbrtu);
 
     /* Make sure to use Modbus RTU Preferences field to determine default TCP port */
-
-    if(mbrtu_port != 0 && mbrtu_port != global_mbus_rtu_port){
-        dissector_delete_uint("tcp.port", mbrtu_port, mbrtu_handle);
-        dissector_delete_uint("udp.port", mbrtu_port, mbrtu_udp_handle);
-    }
-
-    if(global_mbus_rtu_port != 0 && mbrtu_port != global_mbus_rtu_port) {
-        dissector_add_uint("tcp.port", global_mbus_rtu_port, mbrtu_handle);
-        dissector_add_uint("udp.port", global_mbus_rtu_port, mbrtu_udp_handle);
-    }
-
-    mbrtu_port = global_mbus_rtu_port;
+    dissector_add_for_decode_as_with_preference("udp.port", mbrtu_udp_handle);
+    dissector_add_for_decode_as_with_preference("tcp.port", mbrtu_handle);
 
     dissector_add_uint("mbtcp.prot_id", MODBUS_PROTOCOL_ID, modbus_handle);
     dissector_add_for_decode_as("rtacser.data", mbrtu_handle);
+    dissector_add_for_decode_as("usb.device", mbrtu_handle);
+    dissector_add_for_decode_as("usb.product", mbrtu_handle);
+    dissector_add_for_decode_as("usb.protocol", mbrtu_handle);
 
 }