481 lines
23 KiB
C
481 lines
23 KiB
C
|
/****************************************************************************/
|
|||
|
/* SISCO SOFTWARE MODULE HEADER *********************************************/
|
|||
|
/****************************************************************************/
|
|||
|
/* (c) Copyright 2012 Systems Integration Specialists Company, Inc. (SISCO) */
|
|||
|
/* 6605 19 1/2 Mile Road, Sterling Heights, Michigan, 48314 USA */
|
|||
|
/* Tel: +1-586-254-0020 http://www.sisconet.com */
|
|||
|
/* */
|
|||
|
/* This Work consists of voluntary contributions made by SISCO and */
|
|||
|
/* individuals on behalf of SISCO and then contributed to the */
|
|||
|
/* community in support of furthering market acceptance of */
|
|||
|
/* IEC TR 61850-90-5. Please support the community by submitting */
|
|||
|
/* your modifications and contributions at: */
|
|||
|
/* */
|
|||
|
/* http://iec61850.ucaiug.org/90-5/default.aspx */
|
|||
|
/* */
|
|||
|
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
|
|||
|
/* not use this Work except in compliance with the License. */
|
|||
|
/* */
|
|||
|
/* You may obtain a copy of the License at */
|
|||
|
/* */
|
|||
|
/* http://www.apache.org/licenses/LICENSE-2.0 */
|
|||
|
/* */
|
|||
|
/* A copy of the License is included in the distribution of this Work */
|
|||
|
/* in the file named <20>90-5_License.txt<78>. */
|
|||
|
/* */
|
|||
|
/* Unless required by applicable law or agreed to in writing, software */
|
|||
|
/* distributed under the License is distributed on an "AS IS" BASIS, */
|
|||
|
/* WITHOUT, WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
|
|||
|
/* implied. See the License for the specific language governing */
|
|||
|
/* permissions andlimitations under the License. */
|
|||
|
/* */
|
|||
|
/* */
|
|||
|
/* MODULE NAME : iec_90_5.h */
|
|||
|
/* */
|
|||
|
/* MODULE DESCRIPTION : */
|
|||
|
/* Structures and functions declarations for 90-5. */
|
|||
|
/* */
|
|||
|
/* MODIFICATION LOG : */
|
|||
|
/* Date Who Comments */
|
|||
|
/* -------- --- ------ ------------------------------------------- */
|
|||
|
/* 08/11/12 HSF Modified header to include Apache License */
|
|||
|
/* 02/18/12 HSF Added optflds to sv initialize function */
|
|||
|
/* 12/01/11 HSF Initial revision */
|
|||
|
/****************************************************************************/
|
|||
|
#ifndef IEC_90_5_INCLUDED
|
|||
|
#define IEC_90_5_INCLUDED
|
|||
|
|
|||
|
#define SECURITY_INFO_SIZE 8 /* num bytes for Security info */
|
|||
|
|
|||
|
|
|||
|
typedef struct iec_61850_90_5_hdr_info{
|
|||
|
#define IEC_90_5_SI_TYPE_TUNNEL 0xA0
|
|||
|
#define IEC_90_5_SI_TYPE_GOOSE 0xA1
|
|||
|
#define IEC_90_5_SI_TYPE_SV 0xA2
|
|||
|
#define IEC_90_5_SI_TYPE_MNGT 0x83
|
|||
|
ST_UINT8 SessionIdentifer;
|
|||
|
/*the following is a set of security related information*/
|
|||
|
ST_UINT32 timeOfCurrentKey;
|
|||
|
ST_UINT16 timeToNextKey;
|
|||
|
#define SEC_ALG_NONE 0
|
|||
|
#define SEC_ALG_AES_128_GCM 1
|
|||
|
#define SEC_ALG_AES_256_GCM 2
|
|||
|
ST_UCHAR secAlgType;
|
|||
|
#define HMAC_ALG_None 0
|
|||
|
#define HMAC_ALG_SHA_256_80 1
|
|||
|
#define HMAC_ALG_SHA_256_128 2
|
|||
|
#define HMAC_ALG_SHA_256_256 3
|
|||
|
#define HMAC_ALG_AES_GMAC_64 4
|
|||
|
#define HMAC_ALG_AES_GMAC_128 5
|
|||
|
ST_UCHAR hmacAlg;
|
|||
|
ST_ULONG keyLen; //length of the key
|
|||
|
ST_CHAR *pKey; //pointer to the key to be used
|
|||
|
#define IEC_90_5_SIZE_OF_KEY_ID 4
|
|||
|
ST_CHAR *pKeyID; //pointer to the key reference for the key being used
|
|||
|
}IEC905_SESS_PDU_HDR_INFO;
|
|||
|
|
|||
|
typedef struct IEC905_SESS_PAYLOAD_DEF{
|
|||
|
struct IEC905_SESS_PAYLOAD_DEF *next; /*if not NULL, points to another structure. This allows for the encoding*/
|
|||
|
/*of multiple payload packets*/
|
|||
|
#define GOOSE_PAYLOAD_TYPE_TAG 0x81 /*tag for a GOOSE Payload*/
|
|||
|
#define SV_PAYLOAD_TYPE_TAG 0x82 /*tag for a sv payload*/
|
|||
|
#define TUNNEL_PAYLOAD_TYPE_TAG 0x83 /*tag for a tunnelled payload*/
|
|||
|
#define MNGT_PAYLOAD_TYPE_TAG 0x84 /*tag for mngt request/response payload*/
|
|||
|
//the payload tag, simulationBit, and AppID are common information for all payloads*/
|
|||
|
//and must be present as does the pdu_len and pdu_ptr*/
|
|||
|
ST_UINT8 payload_tag; /*tag for the payload type*/
|
|||
|
ST_BOOLEAN simulationBit; /*True indicates that packet is in simulation mode*/
|
|||
|
ST_UINT16 appID; /*ApplicationID*/
|
|||
|
ST_UINT16 pduLen; /*pointer to the length of the encoded PDU*/
|
|||
|
ST_UCHAR *pPDU; /*pointer to previously encoded goose/sv packet APDU only*/
|
|||
|
/*the following fields are for tunnelled payloads only */
|
|||
|
ST_UCHAR *dst_mac; /* DST MAC (must be 6 bytes) */
|
|||
|
ST_UINT16 tpid; /* TPID from original message */
|
|||
|
ST_UINT16 tci; /* TCI from original message*/
|
|||
|
ST_UINT16 etype_id; /* Ethertype ID from original message*/
|
|||
|
}IEC905_SESS_PAYLOAD_DEF;
|
|||
|
|
|||
|
|
|||
|
typedef struct iec_90_5_rx
|
|||
|
{
|
|||
|
IEC905_SESS_PDU_HDR_INFO *pHDR; /*pointer to allocated header information rxd */
|
|||
|
IEC905_SESS_PAYLOAD_DEF *pPayload; /*pointer to the first payload definition in the payload chain */
|
|||
|
ST_UCHAR *pRXDbuffer; /* pointer to the buffer that was received and decoded - filled in by calling application*/
|
|||
|
ST_UCHAR lenRXDBuffer; /*length of the buffer - filled in by calling application*/
|
|||
|
}IEC_90_5_RX;
|
|||
|
|
|||
|
/*function definition to call in order to encode a 90_5 PDU */
|
|||
|
/* returns a pointer to the encoded buffer that includes CLTP */
|
|||
|
extern ST_UCHAR *iec905_sess_enc (
|
|||
|
IEC905_SESS_PDU_HDR_INFO *pHDR, /*points to the header information*/
|
|||
|
IEC905_SESS_PAYLOAD_DEF *pPayload, /*points to the first in the chain of payload information (freeing of the information is reponsibility of the caller*/
|
|||
|
#define PAYLOAD_TYPE_UNKNOWN 0
|
|||
|
#define PAYLOAD_TYPE_SINGLE_GOOSE 1
|
|||
|
#define PAYLOAD_TYPE_SINGLE_SV 2
|
|||
|
#define PAYLOAD_TYPE_TUNNEL 3
|
|||
|
ST_UINT32 *pEncLen, /*pointer to where the length of the encoded buffer is to be stored. */
|
|||
|
ST_UINT32 *SPDUnum /*pointer to the SPDU number to be used. Value will be incremented if encode succeeds*/
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
|
|||
|
#define SIZEOF_IPV4_ADDRESS 4
|
|||
|
// the following is used to store keys
|
|||
|
#define SIZEOF_IPV6_ADDRESS 16
|
|||
|
//this structure is used to store the IP Address, typically destination
|
|||
|
#define IP_V4_ADDRESS_TYPE 0
|
|||
|
#define IP_DNS_NAME_TYPE 1 //this option shall not be used for key management. It is up to the application to convert a DNSName to an
|
|||
|
//actual IP Address. The define is being provided for completeness and traceability to the standard.
|
|||
|
#define IP_V6_ADDRESS_TYPE 2
|
|||
|
#define ETHERNET_MAC_ADDRESS_TYPE 3 //not for use in 90-5, for use with 62351-6
|
|||
|
#define NO_ADDRESS_TYPE 4
|
|||
|
typedef struct iec_comm_address{
|
|||
|
ST_UINT8 typeOfAddress;
|
|||
|
ST_UINT8 lenOfAddress;
|
|||
|
ST_UCHAR *pAddress;
|
|||
|
}IEC_COMM_ADDRESS;
|
|||
|
|
|||
|
IEC_COMM_ADDRESS *create_address_structure(int typeOfAddress, char *pAddress); //function used to fill in the structure and hide nasty functions
|
|||
|
void destroy_address_structure(IEC_COMM_ADDRESS *pAddress); //destroys the structure created in the create funciton
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
typedef struct iec905_key_info{
|
|||
|
struct iec905_key_info *pNext;
|
|||
|
struct iec905_key_info *pPrev;
|
|||
|
struct iec_chain_info *pChain; //pointer to the chain that it belongs in.
|
|||
|
#define SIZE_OF_KEY_ID 4
|
|||
|
unsigned char key_id[SIZE_OF_KEY_ID];
|
|||
|
#define KEY_TYPE_AES_128 0 //these are the defines used for type_of_key value, these are the allows values from 90-5
|
|||
|
#define KEY_TYPE_AES_256 1
|
|||
|
ST_UINT8 typeOfKey;
|
|||
|
ST_UINT16 keyLen;
|
|||
|
ST_UCHAR *pKey; //pointer to the actual key
|
|||
|
time_t timeOfInitialUse;
|
|||
|
time_t timeOfexpiration; //seconds of century at which time the key expires (timeof key acquisition + GDOI expiration time)
|
|||
|
#define MAX_ALLOWED_KEY_EXPIRATION_SECONDS 172800 // 48 hours * 60 minutes * 60 seconds , from 90-5
|
|||
|
ST_UINT32 elapsedTimeUntilExpiration; //seconds remaining prior to expiration (returned via GDOI)
|
|||
|
struct iec905_msg_cntrl *pUsedBy; //pointer to what makes use of the key
|
|||
|
} IEC905_KEY_INFO;
|
|||
|
|
|||
|
typedef struct iec905_statistics { //structure used for statistic tracking
|
|||
|
unsigned long int TotalTxPktCnt;
|
|||
|
unsigned long int TotalRxPktCnt;
|
|||
|
unsigned long int TotalRxMissingPktCnt;
|
|||
|
unsigned long int TotalRxPktWithBadHMAC;
|
|||
|
} IEC905_STATISTICS;
|
|||
|
|
|||
|
typedef struct iec905_msg_cntrl{
|
|||
|
struct iec905_msg_cntrl *pPrev;
|
|||
|
struct iec905_msg_cntrl *pNext;
|
|||
|
#define IEC_KEY_USAGE_TYPE_SV 0
|
|||
|
#define IEC_KEY_USAGE_TYPE_GOOSE 1
|
|||
|
#define IEC_KEY_USAGE_TYPE_TUNNEL 2
|
|||
|
#define MAX_IEC_KEY_USAGE_TYPE 2
|
|||
|
ST_UINT8 keyUsageType;
|
|||
|
IEC_COMM_ADDRESS keyAddress; //value for the destination (tx or subscription)
|
|||
|
IEC_COMM_ADDRESS srcKeyAddress; //value for the src address for IGMPV3 (subscription only)
|
|||
|
ST_UINT8 dataSetRefLen;
|
|||
|
ST_UCHAR *pDataSetRef;
|
|||
|
IEC905_KEY_INFO *pCurrentKey;
|
|||
|
IEC905_KEY_INFO *pNextKey;
|
|||
|
ST_UINT32 kdcRefNum;
|
|||
|
void *pKDCReserved;
|
|||
|
#define IEC_ALLOW_NO_HASH 0 //is the default and won't declare a tamper if PDU is received with no hash
|
|||
|
#define IEC_REQUIRE_HASH 1 //requires a HASH, if not present, then there has been a tamper
|
|||
|
int hashExpected;
|
|||
|
int requestedUpdate; //used to indicate that the user has been notified that the keys need to be updated (internal use only).
|
|||
|
unsigned long spdu_num_tx; //used to control the SPDU number on encode
|
|||
|
unsigned long last_spdu_num_rxd; //last spdu number received with valid decode
|
|||
|
IEC905_STATISTICS stats;
|
|||
|
} IEC905_MSG_CNTRL;
|
|||
|
|
|||
|
extern IEC_90_5_RX * iec905_create_dec_info( );
|
|||
|
extern int iec905_sess_dec( IEC_90_5_RX *rx_ptr, struct iec_comm_address *pDestAddress); /* pointer to a user allocated structure */
|
|||
|
extern int iec905_destroy_dec_info( IEC_90_5_RX * stuff_to_free);
|
|||
|
extern ST_UCHAR *udp_tunnel_dec (ST_UCHAR *udp_pdu_ptr, ST_INT udp_pdu_len, ST_UCHAR *dst_mac, ST_UINT16 *tci_ptr, ST_UINT *dec_len_ptr);
|
|||
|
extern ST_UCHAR *usr_encrypt_payloads( IEC905_SESS_PDU_HDR_INFO *hdr, ST_UCHAR *unencrypted_buffer, ST_UINT32 *payload_len );
|
|||
|
extern ST_BOOLEAN usr_create_HMAC( IEC905_SESS_PDU_HDR_INFO *hdr, ST_UCHAR *pData, ST_UINT32 DataLen, ST_UCHAR *pOutHash, ST_UINT32 *enc_len_ptr );
|
|||
|
extern ST_BOOLEAN usr_compare_HMAC( IEC905_SESS_PDU_HDR_INFO *hdr, ST_UCHAR *pData, ST_UINT32 DataLen, ST_UCHAR *pCmpHash);
|
|||
|
|
|||
|
|
|||
|
void iec905_init_key_storage(); //initializes the key storage for the stack
|
|||
|
IEC905_MSG_CNTRL *iec905_create_msg_cntrl_rx( ST_UINT8 usageType, IEC_COMM_ADDRESS *pAddress, IEC_COMM_ADDRESS *pSrcAddress, ST_CHAR *pDatSetRef); //used to allocate key storage and put it into the appropriate chain
|
|||
|
IEC905_MSG_CNTRL *iec905_create_msg_cntrl_tx( ST_UINT8 usageType, IEC_COMM_ADDRESS *pAddress, IEC_COMM_ADDRESS *pSrcAddress, ST_CHAR *pDatSetRef);
|
|||
|
ST_BOOLEAN iec905_destroy_msg_cntrl (IEC905_MSG_CNTRL *pKeyRoot); //used to destroy and recover allocated resources and deletes any associated keys
|
|||
|
IEC905_KEY_INFO * iec905_add_current_key( IEC905_MSG_CNTRL *pKeyRoot, ST_UINT8 typeOfAlg,ST_UINT16 key_len, ST_UCHAR *pKey, ST_UCHAR *pKeyID, ST_UINT32 time_remaining);
|
|||
|
IEC905_KEY_INFO * iec905_add_next_key( IEC905_MSG_CNTRL *pKeyRoot, ST_UINT8 typeOfAlg,ST_UINT16 key_len, ST_UCHAR *pKey, ST_UCHAR *pKeyID,ST_UINT32 time_remaining);
|
|||
|
IEC905_MSG_CNTRL *iec905_find_rxd_msg_cntrl(ST_UCHAR pduSI, IEC_COMM_ADDRESS *pDestAddress , ST_UCHAR *pKeyID);
|
|||
|
|
|||
|
|
|||
|
|
|||
|
void iec905_getStats(IEC905_STATISTICS *pRetStatistics, int resetStats);
|
|||
|
|
|||
|
|
|||
|
int iec905_manage_keys(IEC905_MSG_CNTRL *pKeyRoot);
|
|||
|
ST_BOOLEAN iec905_destroy_key (IEC905_MSG_CNTRL *pKeyRoot) ;
|
|||
|
|
|||
|
|
|||
|
//IGMP3 functions -- located in udp_rx.c
|
|||
|
IEC905_MSG_CNTRL *iec905_igmpv3_group_enroll(ST_UINT8 usageType, ST_UINT8 typeOfAddress, char *pMultiAddress, char *pSrcAddress, char *pDatSetRef, SOCKET pReceivingSocket);
|
|||
|
IEC905_MSG_CNTRL *iec905_igmpv3_group_destroy(IEC905_MSG_CNTRL *pPayload,SOCKET pReceivingSocket);
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/**************************************************/
|
|||
|
/* The following are functions found in the */
|
|||
|
/* udp_tx.c module */
|
|||
|
typedef struct ethertype_8021Q {
|
|||
|
USHORT priority; //priority specification
|
|||
|
USHORT vlanID; //vlanID Setting
|
|||
|
}ETHERTYPE_8021Q;
|
|||
|
|
|||
|
#define MAX_NUM_TC_INTERFACES_SUPPORTED 20
|
|||
|
#define MAX_PEAK_RATE 1000000 //bits per second used in Traffic FlowSpec
|
|||
|
#define MAX_TOKEN_RATE 100000 //token rate for sending TC.
|
|||
|
|
|||
|
typedef struct iecsocket_info{
|
|||
|
HANDLE FlowHandle;
|
|||
|
HANDLE FilterHandle;
|
|||
|
SOCKET SendingSocket;
|
|||
|
}IECSOCKET_TX_INFO;
|
|||
|
|
|||
|
#define MAX_KEY_SIZE_TO_GENERATE (2048/8) //2048 bits divide by 8 gives the number of bytes required.
|
|||
|
ST_UCHAR *generate_symmetric_key(int algorithmID, int size);
|
|||
|
|
|||
|
//*********************************Functions in iec90_5_udp_rx.c *************************************
|
|||
|
//udp/socket functions
|
|||
|
int iec905_ip_init(); //used to initialize the ip socket interface, MUST BE CALLED before any other socket activity
|
|||
|
#define IEC_61850_90_5_UDP_RX_PORT 102 //port specified for use by 90-5
|
|||
|
int iec905_rx_init(SOCKET *pReceivingSocket,unsigned long UDPSckBufSize); //function used to initialize the UDP RX port used for 90-5
|
|||
|
void iec905_close_socket(ReceivingSocket);
|
|||
|
|
|||
|
int iec905_tx_pdu_init();
|
|||
|
int iec905_tx_pdu_open_socket_with_priorities(IECSOCKET_TX_INFO ** pSocketInfo, char *pInterfaceName, ETHERTYPE_8021Q *p8021Q, USHORT *pIP_TOS_DSCP, IEC_COMM_ADDRESS *pDestAddress);
|
|||
|
int iec905_tx_pdu_close_socket (IECSOCKET_TX_INFO *SendingInfo);
|
|||
|
|
|||
|
|
|||
|
#define UDP_HDR_SIZE_IPV6 16 //V6 is the worst case for pseudo HDR size
|
|||
|
#define MAX_ALLOWED_UDP_PACKET_LENGTH (65535 - UDP_HDR_SIZE_IPV6) //maximum size allowed, in order to avoid Jumbo packets
|
|||
|
int iec905_tx_pdu (IECSOCKET_TX_INFO *SendingInfo, IEC_COMM_ADDRESS *pMyAddressInfo, ST_INT IPPort, ST_UCHAR *pEnc, ST_UINT encLen, IEC905_MSG_CNTRL *pTxStats);
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//***********************************************/
|
|||
|
// error code definitions */
|
|||
|
|
|||
|
typedef struct errorTracking{
|
|||
|
int inUse; //TRUE if there is a valid errorCode in the structure
|
|||
|
int errorCode; //Error that was passed into the ErrorHandler Function
|
|||
|
char * fileName; //Name of the file that called the ErrorHandler funciton. May be NULL.
|
|||
|
unsigned long lineNumber; //Number of the line, in the file, that called the ErrorHandler function.
|
|||
|
time_t timeOfError;
|
|||
|
}ERROR_TRACKING;
|
|||
|
|
|||
|
int IEC905_ErrorHandler (int errorCode, char * fileName, unsigned long int lineNumber); //function to call in case of error
|
|||
|
char *IEC905_XlatErrorCode(int errorCode); //called to translate and error code to a string
|
|||
|
ERROR_TRACKING *IEC905_GetSpecificEntry(unsigned int entryNumber); //called to retrieve other errors. The maximum number is
|
|||
|
//determined by MAX_ALLOWED_LAST_ERRORS. EntryNumber starts
|
|||
|
//numbering at zero(0). EntryNumber=0 is the same as GetLastError
|
|||
|
ERROR_TRACKING *IEC905_GetLastError(); //used to get the last error
|
|||
|
|
|||
|
#define MAX_ALLOWED_LAST_ERRORS 10 //defines the depth of errors that will be maintained
|
|||
|
|
|||
|
#define SUCCESS_IEC905 0
|
|||
|
#define FAILURE_IEC905 -1
|
|||
|
#define OK_IEC905 0
|
|||
|
#define NOK_IEC905 -1
|
|||
|
#define INVALID_INPUT_PARAMETER -2
|
|||
|
|
|||
|
#define COMM_RELATED_ERROR_OFFSET -100
|
|||
|
#define UNABLE_TO_INTIALIZE_IP_INTERFACE (COMM_RELATED_ERROR_OFFSET-0)
|
|||
|
#define IP_PORT_INCORRECT_IEC905 (COMM_RELATED_ERROR_OFFSET-1)
|
|||
|
#define UNABLE_TO_OPEN_UDP_SOCKET_IEC905 (COMM_RELATED_ERROR_OFFSET-2)
|
|||
|
#define UDP_RX_BIND_FAILED_IEC905 (COMM_RELATED_ERROR_OFFSET-3)
|
|||
|
#define ETHERNET_INTERFACE_NOT_FOUND (COMM_RELATED_ERROR_OFFSET-4)
|
|||
|
#define ETHERNET_INTERFACE_OPEN_FAILED (COMM_RELATED_ERROR_OFFSET-5)
|
|||
|
#define UNABLE_TO_CREATE_SENDING_SOCKET (COMM_RELATED_ERROR_OFFSET-6)
|
|||
|
#define UNABLE_TO_CONVERT_IP_ADDRESS (COMM_RELATED_ERROR_OFFSET-7)
|
|||
|
|
|||
|
#define SUBSCRIPTION_AND_TRAFFIC_CONTROL_OFFSET -200
|
|||
|
#define INVALID_IGMP_GROUP_ENROLL_PARAMETERS_IEC905 (SUBSCRIPTION_AND_TRAFFIC_CONTROL_OFFSET-1)
|
|||
|
#define DUPLICATE_PAYLOAD_DETECTED_IEC905 (SUBSCRIPTION_AND_TRAFFIC_CONTROL_OFFSET-2)
|
|||
|
#define IGMPV3_GROUP_MEMBERSHIP_ENROLL_FAILED_IEC905 (SUBSCRIPTION_AND_TRAFFIC_CONTROL_OFFSET-3)
|
|||
|
#define IGMPV2_GROUP_MEMBERSHIP_ENROLL_FAILED_IEC905 (SUBSCRIPTION_AND_TRAFFIC_CONTROL_OFFSET-4)
|
|||
|
#define INVALID_IGMP_GROUP_UNSUB_PARAMETER_IEC905 (SUBSCRIPTION_AND_TRAFFIC_CONTROL_OFFSET-5)
|
|||
|
#define INVALID_IGMP_GROUP_UNSUBV2_FAILURE_IEC905 (SUBSCRIPTION_AND_TRAFFIC_CONTROL_OFFSET-6)
|
|||
|
#define INVALID_IGMP_GROUP_UNSUBV3_FAILURE_IEC905 (SUBSCRIPTION_AND_TRAFFIC_CONTROL_OFFSET-7)
|
|||
|
#define WINDOWS_FLOW_OBJECT_ALLOCATON_ERROR (SUBSCRIPTION_AND_TRAFFIC_CONTROL_OFFSET-8)
|
|||
|
#define TC_REGISTRATION_ERROR (SUBSCRIPTION_AND_TRAFFIC_CONTROL_OFFSET-9)
|
|||
|
//must have administrative priviledges to access the Traffic Control API
|
|||
|
#define TC_OPEN_FAILED_CHK_ADMIN_PRIV (SUBSCRIPTION_AND_TRAFFIC_CONTROL_OFFSET-10)
|
|||
|
#define TC_INTERFACE_LISTING_FALIED (SUBSCRIPTION_AND_TRAFFIC_CONTROL_OFFSET-11)
|
|||
|
#define INTERFACE_DIFFSERV_FAILED (SUBSCRIPTION_AND_TRAFFIC_CONTROL_OFFSET-12)
|
|||
|
#define TC_FLOWADD_FAILED (SUBSCRIPTION_AND_TRAFFIC_CONTROL_OFFSET-13)
|
|||
|
#define UNABLE_TO_ADD_TCFILTER (SUBSCRIPTION_AND_TRAFFIC_CONTROL_OFFSET-14)
|
|||
|
#define UNABLE_TO_DELETE_TC_FLOW (SUBSCRIPTION_AND_TRAFFIC_CONTROL_OFFSET-15)
|
|||
|
|
|||
|
#define CRYPTO_API_ERROR_OFFSET -300
|
|||
|
#define CRYPTO_PROVIDER_OPEN_ERROR (CRYPTO_API_ERROR_OFFSET-0)
|
|||
|
#define CRYPTO_RND_NUM_GEN_ERROR (CRYPTO_API_ERROR_OFFSET-1)
|
|||
|
#define GENERAL_CRYPTO_PROBLEM (CRYPTO_API_ERROR_OFFSET-2)
|
|||
|
#define CRYPTO_BLOCK_LEN_PROBLEM (CRYPTO_API_ERROR_OFFSET-3)
|
|||
|
|
|||
|
#define ENCODE_DECODE_ERROR_OFFSET -400
|
|||
|
#define LARGER_THAN_ALLOWED_PDU (ENCODE_DECODE_ERROR_OFFSET -0)
|
|||
|
#define MEMORY_ALLOCATION_ERROR (ENCODE_DECODE_ERROR_OFFSET -1)
|
|||
|
#define DECODE_ERROR_TOO_LARGE (ENCODE_DECODE_ERROR_OFFSET -2)
|
|||
|
#define DECODE_UNKNOWN_TAG (ENCODE_DECODE_ERROR_OFFSET -3)
|
|||
|
#define DECODE_ERROR_IN_PAYLOADS (ENCODE_DECODE_ERROR_OFFSET -4)
|
|||
|
#define IEC_90_5_NO_CLTP (ENCODE_DECODE_ERROR_OFFSET -5)
|
|||
|
#define IEC_90_5_TAMPERDECTECT_HDR (ENCODE_DECODE_ERROR_OFFSET -6)
|
|||
|
#define IEC_90_5_INVALID_HDR (ENCODE_DECODE_ERROR_OFFSET -7)
|
|||
|
#define IEC_90_5_INVALID_HDR_LI (ENCODE_DECODE_ERROR_OFFSET -8)
|
|||
|
#define IEC_90_5_TAMPERDECTECT_NO_SIG (ENCODE_DECODE_ERROR_OFFSET -9)
|
|||
|
#define IEC_90_5UNEXPECTED_PDU_RXD (ENCODE_DECODE_ERROR_OFFSET -10)
|
|||
|
#define IEC_90_5_DUPLICATE_PACKET_RXD (ENCODE_DECODE_ERROR_OFFSET -11)
|
|||
|
|
|||
|
#define INTERNAL_SECURITY_ERROR_OFFSET -500
|
|||
|
#define UNABLE_TO_ADD_KEY (INTERNAL_SECURITY_ERROR_OFFSET+0)
|
|||
|
#define KEYS_NOK (INTERNAL_SECURITY_ERROR_OFFSET -1) //indicates that neither the primary nor next key are valid
|
|||
|
#define PRIME_KEY_OK_NEXT_KEY_NOK (INTERNAL_SECURITY_ERROR_OFFSET -2) //indicates that the primary key is OK, but there is no next key
|
|||
|
|
|||
|
//************* SV ENCODE and DECODE FUNCTIONS And Defines ************************
|
|||
|
|
|||
|
//The following are supported Data Types as defined in IEC 61850-9-2 ED.2
|
|||
|
|
|||
|
enum SV_DATATYPES {
|
|||
|
SV_BOOLEAN,
|
|||
|
SV_INT8,
|
|||
|
SV_INT16,
|
|||
|
SV_INT32,
|
|||
|
SV_INT64,
|
|||
|
SV_INT8U,
|
|||
|
SV_INT16U,
|
|||
|
SV_INT24U, //do not use
|
|||
|
SV_INT32U,
|
|||
|
SV_FLOAT32,
|
|||
|
SV_FLOAT64,
|
|||
|
SV_ENUMERATED,
|
|||
|
SV_CODEDENUM,
|
|||
|
SV_OCTETSTRING,
|
|||
|
SV_VISIBLESTRING,
|
|||
|
SV_UNICODESTRING,
|
|||
|
SV_OBJECTNAME,
|
|||
|
SV_OBJECTREFERENCE,
|
|||
|
SV_TIMESTAMP,
|
|||
|
SV_ENTRYTIME
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
|
|||
|
typedef struct asdu_enc_info{
|
|||
|
char * pASDU; //pointer to the beginning of the ASDU;
|
|||
|
ST_UINT16 *pSmpCntValue; //pointer to where to place the SMPCNT value
|
|||
|
ST_UCHAR *pSmpSynch; //pointer to the SMPSNYC Value
|
|||
|
char * pASDU_data; //pointer to the beginning of the ASDU data
|
|||
|
char * pASDU_TimeStamp; //pointer to the UTC timestamp;
|
|||
|
} ASDU_ENC_INFO;
|
|||
|
|
|||
|
typedef struct sv_enc_struct {
|
|||
|
ST_UINT16 length_to_send; //Actual PDU size to send
|
|||
|
unsigned char * pSVbuffer; //pointer to the allocated buffer
|
|||
|
unsigned int max_num_ASDUs_allocated;
|
|||
|
ST_UINT16 size_of_asdu;
|
|||
|
ST_UINT16 *pPDULen; //pointer to where the PDU len is located
|
|||
|
ST_UCHAR *pNumASDUVal; //pointer to where the number of ASDUs is located
|
|||
|
ST_UINT16 *pASDUSeqLen; //pointer to the sequence length for ASDUs
|
|||
|
ST_UINT16 asdu_data_size; //size in octets of the ASDU
|
|||
|
ASDU_ENC_INFO asdus[0]; //begining of the ASDU arrays, will be allocated to the max_num_ASDUs;
|
|||
|
}SV_ENC_STRUCT;
|
|||
|
|
|||
|
SV_ENC_STRUCT * initialize_sv_encode_struct (char * pMsvid, //pointer to a NULL terminated MSVID value may not be more than 127
|
|||
|
char * pDatSetRef, //pointer to a NULL terminated DataSetReference string, may not be more than 127
|
|||
|
unsigned int max_num_asdus, //maximum number of ASDUs, may not be more than 127
|
|||
|
ST_UINT32 confrev,
|
|||
|
ST_UCHAR smpSync,
|
|||
|
ST_UINT16 smpRate,
|
|||
|
ST_UINT16 *smpMod,
|
|||
|
ST_UINT16 size_of_asdu_data, //size of ASDU data in bytes
|
|||
|
#define SV_INCLUDE_REFRESH_TIME 0x80
|
|||
|
#define SV_INCLUDE_SAMPLE_SYNC 0x40 //do not used, just provided for backward compatibility with V1
|
|||
|
#define SV_INCLUDE_SAMPLE_RATE 0x20
|
|||
|
#define SV_INCLUDE_DATA_SET 0x10
|
|||
|
#define SV_INCLUDE_SECURITY 0x08 //ignored, not used
|
|||
|
#define SV_INCLUDE_UTC_TIME 0x04 //added by 90-5
|
|||
|
|
|||
|
ST_UINT8 sv_optflds
|
|||
|
);
|
|||
|
int sv_enc_update_lengths( SV_ENC_STRUCT *pCntrlStruc, //pointer the the control structure for the buffer
|
|||
|
unsigned int num_asdus_to_use //number of the actual ASDUs that will be used
|
|||
|
);
|
|||
|
int destroy_sv_encode_struct (SV_ENC_STRUCT * pDestroy);
|
|||
|
int sv_data_helper_prim(unsigned int dataType, int initial_data_offset, int *ret_len);
|
|||
|
int sv_data_helper_calculate_samples_size_prim (unsigned int dataType, int initial_data_offset, int *ret_len, int *total_calc_len);
|
|||
|
|
|||
|
|
|||
|
typedef struct asn1Info{
|
|||
|
ST_UINT16 len;
|
|||
|
unsigned char *pValue;
|
|||
|
}SV_ASDUINFO;
|
|||
|
|
|||
|
typedef struct asdu_dec_info{
|
|||
|
SV_ASDUINFO msvID;
|
|||
|
SV_ASDUINFO datSetRef;
|
|||
|
SV_ASDUINFO smpCnt;
|
|||
|
SV_ASDUINFO confRev;
|
|||
|
SV_ASDUINFO refrTm;
|
|||
|
SV_ASDUINFO smpSynch;
|
|||
|
SV_ASDUINFO smpRate;
|
|||
|
SV_ASDUINFO samples;
|
|||
|
SV_ASDUINFO smpMod;
|
|||
|
SV_ASDUINFO utcTimeStamp;
|
|||
|
} ASDU_DEC_INFO;
|
|||
|
|
|||
|
typedef struct sv_dec_struct {
|
|||
|
unsigned int num_ASDUs;
|
|||
|
ASDU_DEC_INFO asdus[0]; //begining of the ASDU arrays, will be allocated to the max_num_ASDUs;
|
|||
|
}SV_DEC_STRUCT;
|
|||
|
|
|||
|
SV_DEC_STRUCT * sv_decode (unsigned char * pSVPdu, //pointer to the SVPDU to be decoded
|
|||
|
ST_UINT16 SVPDULen //length of the PDU to be decoded
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
/**************** functions used to interact with the KDC ****************/
|
|||
|
|
|||
|
typedef struct kdc_credentials{ // a placeholder for what needs to be done eventually. Anticipate certificate information, but that may change.
|
|||
|
char * certificate_info;
|
|||
|
}KDC_CREDENTIALS;
|
|||
|
|
|||
|
typedef struct kdc_ref{
|
|||
|
void *pReserved; //reserved for internal use
|
|||
|
ST_UINT32 refNum; //alternat reference number
|
|||
|
char *pUserRef; //pointer to the user reference for the KDC Pair
|
|||
|
}KDC_REF;
|
|||
|
|
|||
|
|
|||
|
int iec905_destroy_kdc_credential(KDC_CREDENTIALS *pCredential); //destroys and frees a created KDC Credential structure
|
|||
|
int iec905_init_kdc_interface(KDC_CREDENTIALS *pLocalCredential, int maxNumOfKDCPairs); //function is called in order to initialize what needs to be initialized for the KDC interface
|
|||
|
|
|||
|
KDC_REF *iec905_create_KDC_pair(char *userRef,
|
|||
|
IEC_COMM_ADDRESS *pPrimary, //addressing information for the primary KDC
|
|||
|
KDC_CREDENTIALS *pPrimaryCredentials, //pointer to the primary KDCs credentials that need to be used in phase 1 of GDOI
|
|||
|
IEC_COMM_ADDRESS *pSecondary, //addressing information for the secondary KDC
|
|||
|
KDC_CREDENTIALS *pSecondaryCredentials //pointer to the secondary KDCs credentials that need to be used in phase 1 of GDOI
|
|||
|
);
|
|||
|
int iec905_destroy_KDC_pair(ST_UINT32 refNum);
|
|||
|
int iec905_kdc_bind (IEC905_MSG_CNTRL *pMsgCntrl, KDC_REF *pKDCRef);
|
|||
|
int iec905_get_kdc_tx_keys(IEC905_MSG_CNTRL * pMsgCntrl);
|
|||
|
int iec905_get_kdc_rx_keys(IEC905_MSG_CNTRL * pMsgCntrl);
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//***********************************************************************
|
|||
|
// REQUIRED FUNCTIONS TO BE SUPPLIED BY THE USER
|
|||
|
void usr_notify_of_key_updated_needed(IEC905_MSG_CNTRL *pCntrl); //called if keys need to be updated by the KDC
|
|||
|
void usr_notify_of_error(int errorCode,char *fileName,unsigned long int lineNumber);
|
|||
|
#endif /* !IEC_90_5_INCLUDED */
|