Skip to content

Commit a5d99b2

Browse files
committed
- CS101 Slave: reject commands with broadcast CA when not allowed for command type (LIB8705-130)
1 parent 9e3feeb commit a5d99b2

1 file changed

Lines changed: 62 additions & 10 deletions

File tree

lib60870-C/src/iec60870/cs101/cs101_slave.c

Lines changed: 62 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -617,14 +617,37 @@ CS101_Slave_setDelayAcquisitionHandler(CS101_Slave self, CS101_DelayAcquisitionH
617617
}
618618

619619
static void
620-
responseCOTUnknown(CS101_ASDU asdu, IMasterConnection self)
620+
responseNegative(CS101_ASDU asdu, IMasterConnection self, CS101_CauseOfTransmission cot)
621621
{
622-
DEBUG_PRINT(" with unknown COT\n");
623-
CS101_ASDU_setCOT(asdu, CS101_COT_UNKNOWN_COT);
622+
CS101_ASDU_setCOT(asdu, cot);
624623
CS101_ASDU_setNegative(asdu, true);
625624
sendASDU(self, asdu);
626625
}
627626

627+
static void
628+
responseCOTUnknown(CS101_ASDU asdu, IMasterConnection self)
629+
{
630+
DEBUG_PRINT("CS101 SLAVE: with unknown COT\n");
631+
responseNegative(asdu, self, CS101_COT_UNKNOWN_COT);
632+
}
633+
634+
static bool
635+
isBroadcastCA(CS101_Slave self, int ca)
636+
{
637+
if (self->alParameters.sizeOfCA == 2)
638+
{
639+
if (ca == 65535)
640+
return true;
641+
}
642+
else if (self->alParameters.sizeOfCA == 1)
643+
{
644+
if (ca == 255)
645+
return true;
646+
}
647+
648+
return false;
649+
}
650+
628651
/*
629652
* Handle received ASDUs
630653
*
@@ -635,6 +658,8 @@ handleASDU(CS101_Slave self, CS101_ASDU asdu)
635658
{
636659
bool messageHandled = false;
637660

661+
int ca = CS101_ASDU_getCA(asdu);
662+
638663
/* call plugins */
639664
if (self->plugins)
640665
{
@@ -665,7 +690,7 @@ handleASDU(CS101_Slave self, CS101_ASDU asdu)
665690
{
666691
case C_IC_NA_1: /* 100 - interrogation command */
667692

668-
DEBUG_PRINT("Rcvd interrogation command C_IC_NA_1\n");
693+
DEBUG_PRINT("CS101_SLAVE: Rcvd interrogation command C_IC_NA_1\n");
669694

670695
if ((cot == CS101_COT_ACTIVATION) || (cot == CS101_COT_DEACTIVATION))
671696
{
@@ -695,7 +720,7 @@ handleASDU(CS101_Slave self, CS101_ASDU asdu)
695720

696721
case C_CI_NA_1: /* 101 - counter interrogation command */
697722

698-
DEBUG_PRINT("Rcvd counter interrogation command C_CI_NA_1\n");
723+
DEBUG_PRINT("CS101_SLAVE: Rcvd counter interrogation command C_CI_NA_1\n");
699724

700725
if ((cot == CS101_COT_ACTIVATION) || (cot == CS101_COT_DEACTIVATION))
701726
{
@@ -727,7 +752,16 @@ handleASDU(CS101_Slave self, CS101_ASDU asdu)
727752

728753
case C_RD_NA_1: /* 102 - read command */
729754

730-
DEBUG_PRINT("Rcvd read command C_RD_NA_1\n");
755+
DEBUG_PRINT("CS101_SLAVE: Rcvd read command C_RD_NA_1\n");
756+
757+
if (isBroadcastCA(self, ca) == true)
758+
{
759+
DEBUG_PRINT("CS101_SLAVE: command with broadcast CA not allowed\n");
760+
761+
responseNegative(asdu, &(self->iMasterConnection), CS101_COT_UNKNOWN_CA);
762+
763+
return;
764+
}
731765

732766
if (cot == CS101_COT_REQUEST)
733767
{
@@ -756,7 +790,7 @@ handleASDU(CS101_Slave self, CS101_ASDU asdu)
756790

757791
case C_CS_NA_1: /* 103 - Clock synchronization command */
758792

759-
DEBUG_PRINT("Rcvd clock sync command C_CS_NA_1\n");
793+
DEBUG_PRINT("CS101_SLAVE: Rcvd clock sync command C_CS_NA_1\n");
760794

761795
if (cot == CS101_COT_ACTIVATION)
762796
{
@@ -794,7 +828,16 @@ handleASDU(CS101_Slave self, CS101_ASDU asdu)
794828

795829
case C_TS_NA_1: /* 104 - test command */
796830

797-
DEBUG_PRINT("Rcvd test command C_TS_NA_1\n");
831+
DEBUG_PRINT("CS101_SLAVE: Rcvd test command C_TS_NA_1\n");
832+
833+
if (isBroadcastCA(self, ca) == true)
834+
{
835+
DEBUG_PRINT("CS101_SLAVE: command with broadcast CA not allowed\n");
836+
837+
responseNegative(asdu, &(self->iMasterConnection), CS101_COT_UNKNOWN_CA);
838+
839+
return;
840+
}
798841

799842
{
800843
union uInformationObject _io;
@@ -837,7 +880,7 @@ handleASDU(CS101_Slave self, CS101_ASDU asdu)
837880

838881
case C_RP_NA_1: /* 105 - Reset process command */
839882

840-
DEBUG_PRINT("Rcvd reset process command C_RP_NA_1\n");
883+
DEBUG_PRINT("CS101_SLAVE: Rcvd reset process command C_RP_NA_1\n");
841884

842885
if (cot == CS101_COT_ACTIVATION)
843886
{
@@ -867,7 +910,16 @@ handleASDU(CS101_Slave self, CS101_ASDU asdu)
867910

868911
case C_CD_NA_1: /* 106 - Delay acquisition command */
869912

870-
DEBUG_PRINT("Rcvd delay acquisition command C_CD_NA_1\n");
913+
DEBUG_PRINT("CS101_SLAVE: Rcvd delay acquisition command C_CD_NA_1\n");
914+
915+
if (isBroadcastCA(self, ca) == true)
916+
{
917+
DEBUG_PRINT("CS101_SLAVE: command with broadcast CA not allowed\n");
918+
919+
responseNegative(asdu, &(self->iMasterConnection), CS101_COT_UNKNOWN_CA);
920+
921+
return;
922+
}
871923

872924
if ((cot == CS101_COT_ACTIVATION) || (cot == CS101_COT_SPONTANEOUS))
873925
{

0 commit comments

Comments
 (0)