aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-iec104.c
diff options
context:
space:
mode:
authormorriss <morriss@f5534014-38df-0310-8fa8-9805f1628bb7>2008-09-30 16:03:18 +0000
committermorriss <morriss@f5534014-38df-0310-8fa8-9805f1628bb7>2008-09-30 16:03:18 +0000
commitbc11018828dfe9862edb2174176f2a3fa333604a (patch)
tree58489f2e06258e928969b70e7f5b52051348374e /epan/dissectors/packet-iec104.c
parent02747a50534502c1ea78fe9f6d43a1d5e56d252f (diff)
get_iec104apdu_len(): make the offset variable a guin32 instead of a guint8 so
we can deal with TVB lengths greater than 255. This fixes the infite loop reported in: https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=2914o git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@26310 f5534014-38df-0310-8fa8-9805f1628bb7
Diffstat (limited to 'epan/dissectors/packet-iec104.c')
-rw-r--r--epan/dissectors/packet-iec104.c300
1 files changed, 150 insertions, 150 deletions
diff --git a/epan/dissectors/packet-iec104.c b/epan/dissectors/packet-iec104.c
index f1ca294d30..aeab6b3883 100644
--- a/epan/dissectors/packet-iec104.c
+++ b/epan/dissectors/packet-iec104.c
@@ -1,6 +1,6 @@
/* packet-iec104.c
* Routines for IEC-60870-5-104 (iec104) Protocol disassembly
- *
+ *
*
* $Id$
*
@@ -142,56 +142,56 @@ static const value_string u_types[] = {
#define M_SP_NA_1 1 /* single-point information */
#define M_DP_NA_1 3 /* double-point information */
#define M_ST_NA_1 5 /* step position information */
-#define M_BO_NA_1 7 /* bitstring of 32 bits */
+#define M_BO_NA_1 7 /* bitstring of 32 bits */
#define M_ME_NA_1 9 /* measured value, normalized value */
-#define M_ME_NB_1 11 /* measured value, scaled value */
-#define M_ME_NC_1 13 /* measured value, short floating point number */
+#define M_ME_NB_1 11 /* measured value, scaled value */
+#define M_ME_NC_1 13 /* measured value, short floating point number */
#define M_IT_NA_1 15 /* integrated totals */
-#define M_PS_NA_1 20 /* packed single-point information with status change detection */
-#define M_ME_ND_1 21 /* measured value, normalized value without quality descriptor */
+#define M_PS_NA_1 20 /* packed single-point information with status change detection */
+#define M_ME_ND_1 21 /* measured value, normalized value without quality descriptor */
#define M_SP_TB_1 30 /* single-point information with time tag CP56Time2a */
#define M_DP_TB_1 31 /* double-point information with time tag CP56Time2a */
#define M_ST_TB_1 32 /* step position information with time tag CP56Time2a */
-#define M_BO_TB_1 33 /* bitstring of 32 bit with time tag CP56Time2a */
+#define M_BO_TB_1 33 /* bitstring of 32 bit with time tag CP56Time2a */
#define M_ME_TD_1 34 /* measured value, normalized value with time tag CP56Time2a */
-#define M_ME_TE_1 35 /* measured value, scaled value with time tag CP56Time2a */
-#define M_ME_TF_1 36 /* measured value, short floating point number with time tag CP56Time2a */
+#define M_ME_TE_1 35 /* measured value, scaled value with time tag CP56Time2a */
+#define M_ME_TF_1 36 /* measured value, short floating point number with time tag CP56Time2a */
#define M_IT_TB_1 37 /* integrated totals with time tag CP56Time2a */
-#define M_EP_TD_1 38 /* event of protection equipment with time tag CP56Time2a */
-#define M_EP_TE_1 39 /* packed start events of protection equipment with time tag CP56Time2a */
+#define M_EP_TD_1 38 /* event of protection equipment with time tag CP56Time2a */
+#define M_EP_TE_1 39 /* packed start events of protection equipment with time tag CP56Time2a */
#define M_EP_TF_1 40 /* packed output circuit information of protection equipment with time tag CP56Time2a */
-#define C_SC_NA_1 45 /* single command */
-#define C_DC_NA_1 46 /* double command */
+#define C_SC_NA_1 45 /* single command */
+#define C_DC_NA_1 46 /* double command */
#define C_RC_NA_1 47 /* regulating step command */
-#define C_SE_NA_1 48 /* set point command, normalized value */
+#define C_SE_NA_1 48 /* set point command, normalized value */
#define C_SE_NB_1 49 /* set point command, scaled value */
-#define C_SE_NC_1 50 /* set point command, short floating point number */
-#define C_BO_NA_1 51 /* bitstring of 32 bits */
+#define C_SE_NC_1 50 /* set point command, short floating point number */
+#define C_BO_NA_1 51 /* bitstring of 32 bits */
#define C_SC_TA_1 58 /* single command with time tag CP56Time2a */
#define C_DC_TA_1 59 /* double command with time tag CP56Time2a */
#define C_RC_TA_1 60 /* regulating step command with time tag CP56Time2a */
-#define C_SE_TA_1 61 /* set point command, normalized value with time tag CP56Time2a */
+#define C_SE_TA_1 61 /* set point command, normalized value with time tag CP56Time2a */
#define C_SE_TB_1 62 /* set point command, scaled value with time tag CP56Time2a */
#define C_SE_TC_1 63 /* set point command, short floating-point number with time tag CP56Time2a */
-#define C_BO_TA_1 64 /* bitstring of 32 bits with time tag CP56Time2a */
-#define M_EI_NA_1 70 /* end of initialization */
-#define C_IC_NA_1 100 /* interrogation command */
-#define C_CI_NA_1 101 /* counter interrogation command */
-#define C_RD_NA_1 102 /* read command */
-#define C_CS_NA_1 103 /* clock synchronization command */
-#define C_RP_NA_1 105 /* reset process command */
-#define C_TS_TA_1 107 /* test command with time tag CP56Time2a */
-#define P_ME_NA_1 110 /* parameter of measured value, normalized value */
-#define P_ME_NB_1 111 /* parameter of measured value, scaled value */
+#define C_BO_TA_1 64 /* bitstring of 32 bits with time tag CP56Time2a */
+#define M_EI_NA_1 70 /* end of initialization */
+#define C_IC_NA_1 100 /* interrogation command */
+#define C_CI_NA_1 101 /* counter interrogation command */
+#define C_RD_NA_1 102 /* read command */
+#define C_CS_NA_1 103 /* clock synchronization command */
+#define C_RP_NA_1 105 /* reset process command */
+#define C_TS_TA_1 107 /* test command with time tag CP56Time2a */
+#define P_ME_NA_1 110 /* parameter of measured value, normalized value */
+#define P_ME_NB_1 111 /* parameter of measured value, scaled value */
#define P_ME_NC_1 112 /* parameter of measured value, short floating-point number */
-#define P_AC_NA_1 113 /* parameter activation */
-#define F_FR_NA_1 120 /* file ready */
-#define F_SR_NA_1 121 /* section ready */
-#define F_SC_NA_1 122 /* call directory, select file, call file, call section */
-#define F_LS_NA_1 123 /* last section, last segment */
-#define F_AF_NA_1 124 /* ack file, ack section */
+#define P_AC_NA_1 113 /* parameter activation */
+#define F_FR_NA_1 120 /* file ready */
+#define F_SR_NA_1 121 /* section ready */
+#define F_SC_NA_1 122 /* call directory, select file, call file, call section */
+#define F_LS_NA_1 123 /* last section, last segment */
+#define F_AF_NA_1 124 /* ack file, ack section */
#define F_SG_NA_1 125 /* segment */
-#define F_DR_TA_1 126 /* directory */
+#define F_DR_TA_1 126 /* directory */
#define F_SC_NB_1 127 /* Query Log - Request archive file */
static const value_string asdu_types [] = {
{ M_SP_NA_1, "M_SP_NA_1" },
@@ -202,52 +202,52 @@ static const value_string asdu_types [] = {
{ M_ME_NB_1, "M_ME_NB_1" },
{ M_ME_NC_1, "M_ME_NC_1" },
{ M_IT_NA_1, "M_IT_NA_1" },
- { M_PS_NA_1, "M_PS_NA_1" },
- { M_ME_ND_1, "M_ME_ND_1" },
- { M_SP_TB_1, "M_SP_TB_1" },
- { M_DP_TB_1, "M_DP_TB_1" },
- { M_ST_TB_1, "M_ST_TB_1" },
- { M_BO_TB_1, "M_BO_TB_1" },
- { M_ME_TD_1, "M_ME_TD_1" },
- { M_ME_TE_1, "M_ME_TE_1" },
- { M_ME_TF_1, "M_ME_TF_1" },
- { M_IT_TB_1, "M_IT_TB_1" },
- { M_EP_TD_1, "M_EP_TD_1" },
- { M_EP_TE_1, "M_EP_TE_1" },
- { M_EP_TF_1, "M_EP_TF_1" },
- { C_SC_NA_1, "C_SC_NA_1" },
- { C_DC_NA_1, "C_DC_NA_1" },
- { C_RC_NA_1, "C_RC_NA_1" },
- { C_SE_NA_1, "C_SE_NA_1" },
- { C_SE_NB_1, "C_SE_NB_1" },
- { C_SE_NC_1, "C_SE_NC_1" },
- { C_BO_NA_1, "C_BO_NA_1" },
- { C_SC_TA_1, "C_SC_TA_1" },
- { C_DC_TA_1, "C_DC_TA_1" },
- { C_RC_TA_1, "C_RC_TA_1" },
- { C_SE_TA_1, "C_SE_TA_1" },
- { C_SE_TB_1, "C_SE_TB_1" },
- { C_SE_TC_1, "C_SE_TC_1" },
- { C_BO_TA_1, "C_BO_TA_1" },
- { M_EI_NA_1, "M_EI_NA_1" },
- { C_IC_NA_1, "C_IC_NA_1" },
- { C_CI_NA_1, "C_CI_NA_1" },
- { C_RD_NA_1, "C_RD_NA_1" },
- { C_CS_NA_1, "C_CS_NA_1" },
- { C_RP_NA_1, "C_RP_NA_1" },
- { C_TS_TA_1, "C_TS_TA_1" },
- { P_ME_NA_1, "P_ME_NA_1" },
- { P_ME_NB_1, "P_ME_NB_1" },
- { P_ME_NC_1, "P_ME_NC_1" },
- { P_AC_NA_1, "P_AC_NA_1" },
- { F_FR_NA_1, "F_FR_NA_1" },
- { F_SR_NA_1, "F_SR_NA_1" },
- { F_SC_NA_1, "F_SC_NA_1" },
- { F_LS_NA_1, "F_LS_NA_1" },
- { F_AF_NA_1, "F_AF_NA_1" },
- { F_SG_NA_1, "F_SG_NA_1" },
- { F_DR_TA_1, "F_DR_TA_1" },
- { F_SC_NB_1, "F_SC_NB_1" },
+ { M_PS_NA_1, "M_PS_NA_1" },
+ { M_ME_ND_1, "M_ME_ND_1" },
+ { M_SP_TB_1, "M_SP_TB_1" },
+ { M_DP_TB_1, "M_DP_TB_1" },
+ { M_ST_TB_1, "M_ST_TB_1" },
+ { M_BO_TB_1, "M_BO_TB_1" },
+ { M_ME_TD_1, "M_ME_TD_1" },
+ { M_ME_TE_1, "M_ME_TE_1" },
+ { M_ME_TF_1, "M_ME_TF_1" },
+ { M_IT_TB_1, "M_IT_TB_1" },
+ { M_EP_TD_1, "M_EP_TD_1" },
+ { M_EP_TE_1, "M_EP_TE_1" },
+ { M_EP_TF_1, "M_EP_TF_1" },
+ { C_SC_NA_1, "C_SC_NA_1" },
+ { C_DC_NA_1, "C_DC_NA_1" },
+ { C_RC_NA_1, "C_RC_NA_1" },
+ { C_SE_NA_1, "C_SE_NA_1" },
+ { C_SE_NB_1, "C_SE_NB_1" },
+ { C_SE_NC_1, "C_SE_NC_1" },
+ { C_BO_NA_1, "C_BO_NA_1" },
+ { C_SC_TA_1, "C_SC_TA_1" },
+ { C_DC_TA_1, "C_DC_TA_1" },
+ { C_RC_TA_1, "C_RC_TA_1" },
+ { C_SE_TA_1, "C_SE_TA_1" },
+ { C_SE_TB_1, "C_SE_TB_1" },
+ { C_SE_TC_1, "C_SE_TC_1" },
+ { C_BO_TA_1, "C_BO_TA_1" },
+ { M_EI_NA_1, "M_EI_NA_1" },
+ { C_IC_NA_1, "C_IC_NA_1" },
+ { C_CI_NA_1, "C_CI_NA_1" },
+ { C_RD_NA_1, "C_RD_NA_1" },
+ { C_CS_NA_1, "C_CS_NA_1" },
+ { C_RP_NA_1, "C_RP_NA_1" },
+ { C_TS_TA_1, "C_TS_TA_1" },
+ { P_ME_NA_1, "P_ME_NA_1" },
+ { P_ME_NB_1, "P_ME_NB_1" },
+ { P_ME_NC_1, "P_ME_NC_1" },
+ { P_AC_NA_1, "P_AC_NA_1" },
+ { F_FR_NA_1, "F_FR_NA_1" },
+ { F_SR_NA_1, "F_SR_NA_1" },
+ { F_SC_NA_1, "F_SC_NA_1" },
+ { F_LS_NA_1, "F_LS_NA_1" },
+ { F_AF_NA_1, "F_AF_NA_1" },
+ { F_SG_NA_1, "F_SG_NA_1" },
+ { F_DR_TA_1, "F_DR_TA_1" },
+ { F_SC_NB_1, "F_SC_NB_1" },
{ 0, NULL }
};
static const value_string asdu_lngtypes [] = {
@@ -310,45 +310,45 @@ static const value_string asdu_lngtypes [] = {
/* Cause of Transmision (CauseTx) */
-#define Per_Cyc 1
-#define Back 2
-#define Spont 3
-#define Init 4
-#define Req 5
-#define Act 6
-#define ActCon 7
-#define Deact 8
-#define DeactCon 9
-#define ActTerm 10
-#define Retrem 11
-#define Retloc 12
-#define File 13
-#define Inrogen 20
-#define Inro1 21
-#define Inro2 22
-#define Inro3 23
-#define Inro4 24
-#define Inro5 25
-#define Inro6 26
-#define Inro7 27
-#define Inro8 28
-#define Inro9 29
-#define Inro10 30
-#define Inro11 31
-#define Inro12 32
-#define Inro13 33
-#define Inro14 34
-#define Inro15 35
-#define Inro16 36
-#define Reqcogen 37
-#define Reqco1 38
-#define Reqco2 39
-#define Reqco3 40
-#define Reqco4 41
-#define UkTypeId 44
-#define UkCauseTx 45
-#define UkComAdrASDU 46
-#define UkIOA 47
+#define Per_Cyc 1
+#define Back 2
+#define Spont 3
+#define Init 4
+#define Req 5
+#define Act 6
+#define ActCon 7
+#define Deact 8
+#define DeactCon 9
+#define ActTerm 10
+#define Retrem 11
+#define Retloc 12
+#define File 13
+#define Inrogen 20
+#define Inro1 21
+#define Inro2 22
+#define Inro3 23
+#define Inro4 24
+#define Inro5 25
+#define Inro6 26
+#define Inro7 27
+#define Inro8 28
+#define Inro9 29
+#define Inro10 30
+#define Inro11 31
+#define Inro12 32
+#define Inro13 33
+#define Inro14 34
+#define Inro15 35
+#define Inro16 36
+#define Reqcogen 37
+#define Reqco1 38
+#define Reqco2 39
+#define Reqco3 40
+#define Reqco4 41
+#define UkTypeId 44
+#define UkCauseTx 45
+#define UkComAdrASDU 46
+#define UkIOA 47
static const value_string causetx_types [] = {
{ Per_Cyc ,"Per/Cyc" },
{ Back ,"Back" },
@@ -413,20 +413,20 @@ static gint ett_apci = -1;
static gint ett_asdu = -1;
-/* Find the APDU 104 (APDU=APCI+ASDU) length.
+/* Find the APDU 104 (APDU=APCI+ASDU) length.
Includes possible tvb_length-1 bytes that don't form an APDU */
static guint get_iec104apdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
{
guint8 Val;
- guint8 Off;
+ guint32 Off;
for (Off= 0; Off <= tvb_length(tvb)- 2; Off++) {
- Val = tvb_get_guint8(tvb, offset+ Off);
+ Val = tvb_get_guint8(tvb, offset+ Off);
if (Val == APCI_START) {
return (guint)(Off+ tvb_get_guint8(tvb, offset+ Off+ 1)+ 2);
}
}
-
+
return (guint)(tvb_length(tvb));
}
@@ -494,7 +494,7 @@ static void dissect_iec104asdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
/*** *** DISSECT 'Packet List' *** ***/
if (check_col(pinfo->cinfo, COL_INFO)) {
col_add_str(pinfo->cinfo, COL_INFO, res);
- col_set_fence(pinfo->cinfo, COL_INFO);
+ col_set_fence(pinfo->cinfo, COL_INFO);
}
if(!tree) return;
@@ -512,15 +512,15 @@ static void dissect_iec104asdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
/* Remember: add_uint, add_boolean, _add_text: value from last parameter.
add_item: value from tvb. */
- proto_tree_add_uint(trHead, hf_typeid, tvb, 0, 1, asduh->TypeId);
- proto_tree_add_uint(trHead, hf_numix, tvb, 1, 1, asduh->NumIx);
- proto_tree_add_uint(trHead, hf_causetx, tvb, 2, 1, asduh->TNCause & F_CAUSE);
- proto_tree_add_boolean(trHead, hf_nega, tvb, 2, 1, asduh->TNCause);
- proto_tree_add_boolean(trHead, hf_test, tvb, 2, 1, asduh->TNCause);
- proto_tree_add_uint(trHead, hf_oa, tvb, 3, 1, asduh->OA);
- proto_tree_add_uint(trHead, hf_addr, tvb, 4, 2, asduh->AddrLow+ 256* asduh->AddrHigh);
+ proto_tree_add_uint(trHead, hf_typeid, tvb, 0, 1, asduh->TypeId);
+ proto_tree_add_uint(trHead, hf_numix, tvb, 1, 1, asduh->NumIx);
+ proto_tree_add_uint(trHead, hf_causetx, tvb, 2, 1, asduh->TNCause & F_CAUSE);
+ proto_tree_add_boolean(trHead, hf_nega, tvb, 2, 1, asduh->TNCause);
+ proto_tree_add_boolean(trHead, hf_test, tvb, 2, 1, asduh->TNCause);
+ proto_tree_add_uint(trHead, hf_oa, tvb, 3, 1, asduh->OA);
+ proto_tree_add_uint(trHead, hf_addr, tvb, 4, 2, asduh->AddrLow+ 256* asduh->AddrHigh);
proto_tree_add_uint(trHead, hf_ioa, tvb, 6, 3, asduh->IOA);
- if (asduh->NumIx > 1) proto_tree_add_boolean(trHead, hf_sq, tvb, 1, 1, asduh->SQ);
+ if (asduh->NumIx > 1) proto_tree_add_boolean(trHead, hf_sq, tvb, 1, 1, asduh->SQ);
}
@@ -554,7 +554,7 @@ static void dissect_iec104apci(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
/*** *** START: Common to 'Packet List' and 'Packet Details' *** ***/
Start = 0;
for (Off= 0; Off <= TcpLen- 2; Off++) {
- Start = tvb_get_guint8(tvb, Off);
+ Start = tvb_get_guint8(tvb, Off);
if (Start == APCI_START) {
Brossa = Off;
apcih->ApduLen = tvb_get_guint8(tvb, Off+ 1);
@@ -572,7 +572,7 @@ static void dissect_iec104apci(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
case U_TYPE:
apcih->UType = (Byte1 & 0xFC); /* Don't shift */
break;
- }
+ }
}
else {
/* WireShark can crash if we process packets with length less than expected (6). We consider that everything is bad */
@@ -609,8 +609,8 @@ static void dissect_iec104apci(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
}
else {
g_snprintf(res+strlen(res), MAXS-strlen(res), "<ERR ApduLen=%u bytes> ", apcih->ApduLen);
- }
- }
+ }
+ }
g_strlcat(res, " ", MAXS); /* We add an space to separate possible APCIs/ASDUs in the same packet */
/*** *** END: Common to 'Packet List' and 'Packet Details' *** ***/
@@ -618,9 +618,9 @@ static void dissect_iec104apci(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
if (check_col(pinfo->cinfo, COL_INFO)) {
col_add_str(pinfo->cinfo, COL_INFO, res);
if(apcih->Type == I_TYPE && Brossa != TcpLen) {
- call_dissector(iec104asdu_handle, tvb_new_subset(tvb, Off+ APCI_LEN, -1, apcih->ApduLen- APCI_LEN), pinfo, tree);
+ call_dissector(iec104asdu_handle, tvb_new_subset(tvb, Off+ APCI_LEN, -1, apcih->ApduLen- APCI_LEN), pinfo, tree);
} else {
- col_set_fence(pinfo->cinfo, COL_INFO);
+ col_set_fence(pinfo->cinfo, COL_INFO);
}
}
@@ -633,7 +633,7 @@ static void dissect_iec104apci(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
/* 'Packet Details': ROOT ITEM */
proto_item_append_text(it104, ": %s", res);
- if(Brossa == TcpLen) return;
+ if(Brossa == TcpLen) return;
/* Don't call ASDU dissector if it was called before */
if(apcih->Type == I_TYPE && (!check_col(pinfo->cinfo, COL_INFO))) call_dissector(iec104asdu_handle, tvb_new_subset(tvb, Off+ APCI_LEN, -1, apcih->ApduLen- APCI_LEN), pinfo, tree);
@@ -658,7 +658,7 @@ static void dissect_iec104apci(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
static void dissect_iec104reas(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
/* 5th parameter = 6 = minimum bytes received to calculate the length. (Not 2 in order to find more APCIs in case of 'noisy' bytes between the APCIs) */
- tcp_dissect_pdus(tvb, pinfo, tree, TRUE, APCI_LEN,
+ tcp_dissect_pdus(tvb, pinfo, tree, TRUE, APCI_LEN,
get_iec104apdu_len, dissect_iec104apci);
}
@@ -689,11 +689,11 @@ static gint *ett_ap[] = {
};
proto_iec104apci = proto_register_protocol(
- "IEC 60870-5-104,Apci",
- "104apci",
- "104apci"
+ "IEC 60870-5-104,Apci",
+ "104apci",
+ "104apci"
);
-proto_register_field_array(proto_iec104apci, hf_ap, array_length(hf_ap));
+proto_register_field_array(proto_iec104apci, hf_ap, array_length(hf_ap));
proto_register_subtree_array(ett_ap, array_length(ett_ap));
}
@@ -750,11 +750,11 @@ static gint *ett_as[] = {
};
proto_iec104asdu = proto_register_protocol(
- "IEC 60870-5-104,Asdu",
- "104asdu",
- "104asdu"
+ "IEC 60870-5-104,Asdu",
+ "104asdu",
+ "104asdu"
);
-proto_register_field_array(proto_iec104asdu, hf_as, array_length(hf_as));
+proto_register_field_array(proto_iec104asdu, hf_as, array_length(hf_as));
proto_register_subtree_array(ett_as, array_length(ett_as));
}
@@ -767,8 +767,8 @@ proto_reg_handoff_iec104(void)
{
static dissector_handle_t iec104apci_handle;
- iec104apci_handle = create_dissector_handle(dissect_iec104reas, proto_iec104apci);
- iec104asdu_handle = create_dissector_handle(dissect_iec104asdu, proto_iec104asdu);
+ iec104apci_handle = create_dissector_handle(dissect_iec104reas, proto_iec104apci);
+ iec104asdu_handle = create_dissector_handle(dissect_iec104asdu, proto_iec104asdu);
dissector_add("tcp.port", iec104port, iec104apci_handle);
}