/* packet-mbtcp.c
- * Routines for Modbus/TCP dissection
+ * Routines for Modbus/TCP and Modbus/UDP dissection
* By Riaan Swart <rswart@cs.sun.ac.za>
* Copyright 2001, Institute for Applied Computer Science
* University of Stellenbosch
*
* See
*
- * http://www.modicon.com/openmbus/
+ * http://www.modbus.org/
*
* for information on Modbus/TCP.
*
#include <epan/packet.h>
-#define DEBUG
-
-#define TCP_PORT_MBTCP 502 /* Modbus/TCP located on TCP port 502 */
+#define PORT_MBTCP 502 /* Modbus/TCP and Modbus/UDP located on port 502 */
/* Modbus protocol function codes */
#define READ_COILS 1
#define READ_WRITE_REG 23
#define READ_FIFO_QUEUE 24
#define PROGRAM_CONCEPT 40
+#define ENCAP_INTERFACE_TRANSP 43
#define FIRMWARE_REPLACE 125
#define PROGRAM_584_984_2 126
#define REPORT_LOCAL_ADDR_MB 127
{
/* see if nature of packets can be derived from src/dst ports */
/* if so, return as found */
- if ( ( 502 == pinfo->srcport && 502 != pinfo->destport ) ||
- ( 502 != pinfo->srcport && 502 == pinfo->destport ) ) {
- /* the slave is receiving queries on port 502 */
- if ( 502 == pinfo->srcport )
- return RESPONSE_PACKET;
- else if ( 502 == pinfo->destport )
- return QUERY_PACKET;
- }
+ if (( pinfo->srcport == PORT_MBTCP ) && ( pinfo->destport != PORT_MBTCP ))
+ return RESPONSE_PACKET;
+ if (( pinfo->srcport != PORT_MBTCP ) && ( pinfo->destport == PORT_MBTCP ))
+ return QUERY_PACKET;
+
/* else, cannot classify */
return CANNOT_CLASSIFY;
}
{ READ_WRITE_REG, "Read Write Register" },
{ READ_FIFO_QUEUE, "Read FIFO Queue" },
{ PROGRAM_CONCEPT, "Program (ConCept)" },
+ { ENCAP_INTERFACE_TRANSP, "Encapsulated Interface Transport" },
{ FIRMWARE_REPLACE, "Firmware replacement" },
{ PROGRAM_584_984_2, "Program (584/984)" },
{ REPORT_LOCAL_ADDR_MB, "Report local address (Modbus)" },
const char *err_str = "";
guint32 byte_cnt, group_byte_cnt, group_word_cnt;
guint32 packet_num; /* num to uniquely identify different mbtcp
- * packets in one TCP packet */
+ * packets in one packet */
guint8 exception_code;
gboolean exception_returned;
guint8 fc;
* Note that function code is only 7 bits.
*/
fc=mh.mdbs_hdr.function_code&0x7f;
- if( (fc<1)
- ||(fc>127)
- ||((fc>24)&&(fc<40))
- ||((fc>40)&&(fc<125)) ){
+ if(!match_strval(fc, function_code_vals))
return 0;
- }
/* Make entries in Protocol column on summary display */
- if (check_col(pinfo->cinfo, COL_PROTOCOL))
- col_set_str(pinfo->cinfo, COL_PROTOCOL, "Modbus/TCP");
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "Modbus/TCP");
- if (check_col(pinfo->cinfo, COL_INFO))
- col_clear(pinfo->cinfo, COL_INFO);
+ col_clear(pinfo->cinfo, COL_INFO);
/* Make entries in Info column on summary display */
packet_len, "Modbus/TCP");
mbtcp_tree = proto_item_add_subtree(mi, ett_mbtcp);
- /* Add items to protocol tree specific to Modbus/TCP Modbus/TCP */
+ /* Add items to protocol tree specific to Modbus/TCP */
proto_tree_add_uint(mbtcp_tree, hf_mbtcp_transid, tvb, offset, 2,
mh.transaction_id);
proto_tree_add_uint(mbtcp_tree, hf_mbtcp_protid, tvb, offset + 2, 2,
/* Add items to protocol tree specific to Modbus generic */
- mf = proto_tree_add_text(mbtcp_tree, tvb, offset + 6, mh.len,
+ mf = proto_tree_add_text(mbtcp_tree, tvb, offset + 7, mh.len - 1,
"Modbus");
modbus_tree = proto_item_add_subtree(mf, ett_modbus_hdr);
mi = proto_tree_add_uint(modbus_tree, hf_mbtcp_functioncode, tvb, offset + 7, 1,
{ &hf_mbtcp_transid,
{ "transaction identifier", "modbus_tcp.trans_id",
FT_UINT16, BASE_DEC, NULL, 0x0,
- "", HFILL }
+ NULL, HFILL }
},
{ &hf_mbtcp_protid,
{ "protocol identifier", "modbus_tcp.prot_id",
FT_UINT16, BASE_DEC, NULL, 0x0,
- "", HFILL }
+ NULL, HFILL }
},
{ &hf_mbtcp_len,
{ "length", "modbus_tcp.len",
FT_UINT16, BASE_DEC, NULL, 0x0,
- "", HFILL }
+ NULL, HFILL }
},
/* Modbus header fields */
{ &hf_mbtcp_unitid,
{ "unit identifier", "modbus_tcp.unit_id",
FT_UINT8, BASE_DEC, NULL, 0x0,
- "", HFILL }
+ NULL, HFILL }
},
{ &hf_mbtcp_functioncode,
{ "function code", "modbus_tcp.func_code",
FT_UINT8, BASE_DEC, VALS(function_code_vals), 0x0,
- "", HFILL }
+ NULL, HFILL }
},
{ &hf_modbus_reference,
{ "reference number", "modbus_tcp.reference_num",
FT_UINT16, BASE_DEC, NULL, 0x0,
- "", HFILL }
+ NULL, HFILL }
},
{ &hf_modbus_lreference,
{ "reference number (32 bit)", "modbus_tcp.reference_num_32",
FT_UINT32, BASE_DEC, NULL, 0x0,
- "", HFILL }
+ NULL, HFILL }
},
{ &hf_modbus_reftype,
{ "reference type", "modbus_tcp.reference_type",
FT_UINT8, BASE_DEC, NULL, 0x0,
- "", HFILL }
+ NULL, HFILL }
},
{ &hf_modbus_readref,
{ "read reference number", "modbus_tcp.read_reference_num",
FT_UINT16, BASE_DEC, NULL, 0x0,
- "", HFILL }
+ NULL, HFILL }
},
{ &hf_modbus_writeref,
{ "write reference number", "modbus_tcp.write_reference_num",
FT_UINT16, BASE_DEC, NULL, 0x0,
- "", HFILL }
+ NULL, HFILL }
},
{ &hf_modbus_wordcnt,
{ "word count", "modbus_tcp.word_cnt",
FT_UINT16, BASE_DEC, NULL, 0x0,
- "", HFILL }
+ NULL, HFILL }
},
{ &hf_modbus_readwordcnt,
{ "read word count", "modbus_tcp.read_word_cnt",
FT_UINT16, BASE_DEC, NULL, 0x0,
- "", HFILL }
+ NULL, HFILL }
},
{ &hf_modbus_writewordcnt,
{ "write word count", "modbus_tcp.write_word_cnt",
FT_UINT16, BASE_DEC, NULL, 0x0,
- "", HFILL }
+ NULL, HFILL }
},
{ &hf_modbus_bitcnt,
{ "bit count", "modbus_tcp.bit_cnt",
FT_UINT16, BASE_DEC, NULL, 0x0,
- "", HFILL }
+ NULL, HFILL }
},
{ &hf_modbus_bytecnt,
{ "byte count", "modbus_tcp.byte_cnt",
FT_UINT8, BASE_DEC, NULL, 0x0,
- "", HFILL }
+ NULL, HFILL }
},
{ &hf_modbus_lbytecnt,
{ "byte count (16-bit)", "modbus_tcp.byte_cnt_16",
FT_UINT8, BASE_DEC, NULL, 0x0,
- "", HFILL }
+ NULL, HFILL }
},
{ &hf_modbus_exceptioncode,
{ "exception code", "modbus_tcp.exception_code",
FT_UINT8, BASE_DEC, VALS(exception_code_vals), 0x0,
- "", HFILL }
+ NULL, HFILL }
},
{ &hf_modbus_andmask,
{ "AND mask", "modbus_tcp.and_mask",
FT_UINT16, BASE_HEX, NULL, 0x0,
- "", HFILL }
+ NULL, HFILL }
},
{ &hf_modbus_ormask,
{ "OR mask", "modbus_tcp.or_mask",
FT_UINT16, BASE_HEX, NULL, 0x0,
- "", HFILL }
+ NULL, HFILL }
}
};
dissector_handle_t mbtcp_handle;
mbtcp_handle = new_create_dissector_handle(dissect_mbtcp, proto_mbtcp);
- dissector_add("tcp.port", TCP_PORT_MBTCP, mbtcp_handle);
+ dissector_add("tcp.port", PORT_MBTCP, mbtcp_handle);
+ dissector_add("udp.port", PORT_MBTCP, mbtcp_handle);
}