From: morriss Date: Tue, 30 Sep 2008 16:03:18 +0000 (+0000) Subject: get_iec104apdu_len(): make the offset variable a guin32 instead of a guint8 so X-Git-Url: http://git.samba.org/samba.git/?p=obnox%2Fwireshark%2Fwip.git;a=commitdiff_plain;h=bc11018828dfe9862edb2174176f2a3fa333604a 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 --- 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), " ", 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); }