diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/inc/ikev1payloads.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/inc/ikev1payloads.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,713 @@ +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKEv1 payload handling. +* +*/ + +#ifndef IKEV1PAYLOADS_H +#define IKEV1PAYLOADS_H + +#include +#include "ikemsgheader.h" +#include "ikev1isakmpct.h" + +// +// GENERIC PAYLOAD HEADER +// +class TPayloadISAKMP + { +public: + TPayloadISAKMP() {u.iData32[0] = 0; } + inline TUint8 GetPayload() const; + inline void SetPayload(TUint8 aPayload); + inline TUint16 GetLength() const; + inline void SetLength(TUint16 aLength); + inline TUint8 GetReserved() const; + inline void SetReserved(TUint8 aVal); + inline const TUint8 *SpecificData() const + { return (TUint8 *)((char *)this + sizeof(*this)); } //returns a * to the specific data of this payload + inline const TUint SpecificDataLen() const + { return (GetLength() - sizeof(*this)); } //returns a * to the specific data of this payload + inline const TPayloadISAKMP *Next() const + { return (TPayloadISAKMP *)((char *)this + GetLength()); } + +private: + union + { + TUint32 iData32[1]; + TUint16 iData16[2]; + TUint8 iData8[4]; + } u; + }; +inline TUint8 TPayloadISAKMP::GetPayload() const { return u.iData8[0]; } +inline void TPayloadISAKMP::SetPayload(TUint8 aPayload) { u.iData8[0] = aPayload; } +inline TUint16 TPayloadISAKMP::GetLength() const { return (TUint16)GET16(&u.iData8[2]); } +inline void TPayloadISAKMP::SetLength(TUint16 aLength) { PUT16(&u.iData8[2], aLength); } +inline TUint8 TPayloadISAKMP::GetReserved() const { return u.iData8[1]; } +inline void TPayloadISAKMP::SetReserved(TUint8 aVal) { u.iData8[1] = aVal; } + +// +// SA PAYLOAD +// + + +class TProposalISAKMP; + +//Plus Variable field (Labeled Domain Identifier) from IPSEC DOI (included in length if present) +//use TSAPayloadISAKMP to decodify its values; + +class TSAPayloadISAKMP +{ + public: + inline TSAPayloadISAKMP() {iReserved=0;} + + public: + inline TUint16 GetLength() const { return (TUint16)GET16(&iLength); } + inline void SetLength(TUint16 aLength) { PUT16(iLength, aLength); } + inline TUint16 GetReserved() const { return iReserved; } //No need to swap because always 0 + inline const TSAPayloadISAKMP *Next() const //next payload + { return (TSAPayloadISAKMP *)((TUint8 *)this + GetLength()); } + inline const TUint32 *Data() const + { return (TUint32 *)(this + sizeof(*this)); } //returns the address of the data field + + private: + TUint16 iLength; + TUint16 iReserved; +}; +//followed by a variable size field of the length indicated + +class TSAISAKMP : public TPayloadISAKMP +{ +public: + inline TUint32 Size() const { return sizeof(TSAISAKMP); } //sizeof OK because aligned + inline TUint32 GetDOI() const { return GET32(&iDOI); } + inline void SetDOI(TUint32 aDOI) { PUT32(&iDOI, aDOI); } + inline TUint32 GetSIT() const { return GET32(&iSIT); } + inline void SetSIT(TUint32 aSIT) { PUT32(&iSIT, aSIT); } + inline TUint GetSITLength() const + { + if ( GetDOI() == IPSEC_DOI) //IPSEC DOI has SPI of size 4 octets + return 4; + return 0; + } + inline TBool HasLDId() const + { + TUint32 sit=(IPSEC_SIT_SECRECY | IPSEC_SIT_INTEGRITY); + if ((GetDOI()==IPSEC_DOI) && (GetSIT() & sit)) + return ETrue; //DOI and (SECRECY or INTEGRITY) supported + + return EFalse; + } + static inline TSAISAKMP *Ptr(const TPayloadISAKMP *aPayload) + { return (TSAISAKMP *)aPayload; } + inline TUint32 *Data() const + { return (TUint32 *)(this + sizeof(*this)); } //returns the address of the data field following the header + TPayloadISAKMP* Payload() const + { + TUint size= sizeof(*this); //fixed size + if (!HasLDId()) + return (TPayloadISAKMP *) ((TUint8*)this + size); + size += 4; //Labeled Domain Identifier payload size + TUint32 *d=Data(); + TSAPayloadISAKMP *p = (TSAPayloadISAKMP *)++d; + TInt32 res; + + for (TInt i=0; i < 4; i++) + { + if (i % 2==0) //Fields 1 and 3 in bytes + Math::Int(res, p->GetLength() / 4); + else //Fields 2, 4 in bits + Math::Int(res, p->GetLength() / 32); + + size += res+1; + } + + return (TPayloadISAKMP *) ((TUint8 *)this + size); + } + + TUint32 iDOI; + TUint32 iSIT; +}; + +class TTransformISAKMP; +class TProposalISAKMP : public TPayloadISAKMP + { +public: + inline TUint32 Size() const { return sizeof(TProposalISAKMP); }//sizeof OK because aligned + inline TUint8 GetNum() const { return iNum; }; + inline void SetNum(TUint8 aPayload) { iNum = aPayload; }; + inline TUint8 GetProtocol() const { return iProtocol; }; + inline void SetProtocol(TUint8 aPayload) { iProtocol = aPayload; }; + inline TUint8 GetSPISize() const { return iSPISize; }; + inline void SetSPISize(TUint8 aPayload) { iSPISize = aPayload; }; + inline TUint8 GetNumTrans() const { return iNumTrans; }; + inline void SetNumTrans(TUint8 aPayload) { iNumTrans = aPayload; }; + //inline TUint32 GetSPI() const { return iSPI; }; + //inline void SetSPI(TUint32 aSPI) { iSPI = aSPI; }; + static inline TProposalISAKMP *Ptr(const TPayloadISAKMP *aPayload) + { return (TProposalISAKMP *)aPayload; } + inline const TPayloadISAKMP* Payload() const //next payload (transform) + { return (TPayloadISAKMP*)((TUint8*)this + sizeof(*this) + GetSPISize()); } + inline const TUint8 *SPI() {return (const TUint8 *)((TUint8*)this + sizeof(*this));} //* to the SPI + //void String(TDes &aStr) const; + +//private: + TUint8 iNum; //Proposal Number + TUint8 iProtocol; //Protocol ID for the current negotiation PROTO_ISAKMP, PROTO_IPSEC_AH, PROTO_IPSEC_ESP, ... + TUint8 iSPISize; //size in octets. For ISAKMP should be from 0 to 16. If >0 SPI ignored + TUint8 iNumTrans; //Num of transformations + //TUint32 iSPI; //Variable size (depends on protocol). No Padding. + }; + + +class TDataISAKMP; +class TTransformISAKMP : public TPayloadISAKMP + { +public: + inline TTransformISAKMP() {iReserved=0;} +public: + inline TUint32 Size() const { return sizeof(TTransformISAKMP); } //sizeof OK because aligned + inline TUint8 GetNum() const { return iNum; }; + inline void SetNum(TUint8 aPayload) { iNum = aPayload; }; + inline TUint8 GetID() const { return iID; }; + inline void SetID(TUint8 aPayload) { iID = aPayload; }; + inline TUint16 GetReserved() const { return (TUint16)GET16(&iReserved); }; + static inline TTransformISAKMP *Ptr(const TPayloadISAKMP *aPayload) + { return (TTransformISAKMP *)aPayload; } + inline TDataISAKMP *SAAttrib() const {return (TDataISAKMP *)((TUint8*)this + sizeof(*this)); } //* to SA attributes + //void String(TDes &aStr) const; + +//private: + //TPayloadISAKMP iHdr; //Generic part + TUint8 iNum; //Transform Number + TUint8 iID; //Transform ID for the current negotiation AH, ESP, OSPF, TLS, ... + TUint16 iReserved; //always set to 0 +}; + + + +class TKeyISAKMP : public TPayloadISAKMP +{ +public: + static inline TKeyISAKMP *Ptr(const TPayloadISAKMP *aPayload) + { return (TKeyISAKMP *)aPayload; } + //void String(TDes &aStr) const; + inline TUint8 *KeyData() const {return ((TUint8*)this + sizeof(*this)); } //* to keyData + +}; + + +//would require a few modifications for DOI != IPSECDOI +class TIdentISAKMP : public TPayloadISAKMP +{ +public: + inline TUint8 GetIDType() const { return iIDType; } + inline void SetIDType(TUint8 aIDType) { iIDType=aIDType; } + //IPSEC DOI Specific routines + inline TUint8 GetProtocol() const { return iProtocolID; } + inline void SetProtocol(TUint8 aProtocolID) { iProtocolID = aProtocolID; }; + inline TUint16 GetPort() const { return (TUint16)GET16(&iPort); } + inline void SetPort(TUint16 aPort) { PUT16(&iPort, aPort); } + // + static inline TIdentISAKMP *Ptr(const TPayloadISAKMP *aPayload) + { return (TIdentISAKMP *)aPayload; } + //TBool String(TDes &aStr,TUint aLength) const; + inline TUint8 *IDData() const {return ((TUint8*)this + sizeof(*this)); } //* to identity data + inline TUint16 IDDataLen() const {return (TUint16)(GetLength() - sizeof(*this)); } //Length of the payload data +public: + TUint8 iIDType; + //IPSEC DOI Specific fields + TUint8 iProtocolID; + TUint16 iPort; + +}; + + + +//Used for certificate +//WARNING:Do not use sizeof this class, better Size because size of returns aligned size and not the real. +class TCertificateISAKMP: public TPayloadISAKMP +{ +public: + inline TUint8 GetEncoding() const { return iEncoding; } + inline void SetEncoding(TUint8 aEncoding) { iEncoding = aEncoding; } + static inline TUint16 Size() {return (sizeof(TPayloadISAKMP) + sizeof(TUint8));} //TUint8 is iEncoding + inline TUint16 CertDataLen() const {return (TUint16)(GetLength()-Size()); } //* to certificate data + inline TUint8 *CertData() const {return ((TUint8*)this + Size()); } + //+1 for iEncoding.Cannot use sizeof(*this) because is not aligned and returns 8 instead of 5 + + static inline TCertificateISAKMP *Ptr(const TPayloadISAKMP *aPayload) + { return (TCertificateISAKMP *)aPayload; } + + TUint8 iEncoding; // Certificate Encoding + +}; + + + +//Used for certificate Request payloads +class TCertificateReqISAKMP : public TPayloadISAKMP +{ +public: + inline TUint8 GetEncoding() const { return iEncoding; } + inline void SetEncoding(TUint8 aEncoding) { iEncoding= aEncoding; } + static inline TUint16 Size() {return (sizeof(TPayloadISAKMP) + sizeof(TUint8));} //TUint8 is iEncoding + static inline TCertificateReqISAKMP *Ptr(const TPayloadISAKMP *aPayload) + { return (TCertificateReqISAKMP *)aPayload; } + inline TUint16 CertReqDataLen() const {return (TUint16)(GetLength() - Size()); } //* to certificate data + inline TUint8 *CertReqData() const {return ((TUint8*)this + Size()); } + + TUint8 iEncoding; // Certificate Encoding + +}; + +class THashISAKMP : public TPayloadISAKMP +{ +public: + static inline THashISAKMP *Ptr(const TPayloadISAKMP *aPayload) + { return (THashISAKMP *)aPayload; } + inline TUint8 *Data() const {return ((TUint8*)this + sizeof(*this)); } //pointer to hash data + inline TUint16 DataLen() const {return (TUint16)(GetLength() - sizeof(*this)); } //pointer to hash data + //TBool String(TDes &aStr,TUint aLength) const; +}; + + +class TSignatureISAKMP : public TPayloadISAKMP +{ +public: + static inline TSignatureISAKMP *Ptr(const TPayloadISAKMP *aPayload) + { return (TSignatureISAKMP *)aPayload; } + inline TUint16 GetDataLength() const //Length of the data part in bytes + { return (TUint16)(GetLength() - sizeof(*this));} + inline TUint8 *SigData() const {return ((TUint8*)this + sizeof(*this)); } //pointer to signature data + +}; + +class TNonceISAKMP : public TPayloadISAKMP +{ +public: + static inline TNonceISAKMP *Ptr(const TPayloadISAKMP *aPayload) + { return (TNonceISAKMP *)aPayload; } + + inline TUint8 *NonceData() const {return ((TUint8*)this + sizeof(*this)); } //* to Nonce Data + inline TUint16 NonceDataLen() const {return (TUint16)(GetLength() - sizeof(*this)); } //* to Nonce Data +}; + + + +class TNotificationISAKMP : public TPayloadISAKMP +{ +public: + inline TUint32 GetDOI() const { return GET32(&iDOI); }; + inline void SetDOI(TUint32 aDOI) { PUT32(&iDOI, aDOI); }; + inline TUint8 GetProtocol() const { return iProtocol; }; + inline void SetProtocol(TUint8 aPayload) { iProtocol = aPayload; }; + inline TUint8 GetSPISize() const { return iSPISize; }; + inline void SetSPISize(TUint8 aPayload) { iSPISize = aPayload; }; + inline TUint16 GetMsgType() const { return (TUint16)GET16(&iMsgType); }; + inline void SetMsgType(TUint16 aMsgType) { PUT16(&iMsgType, aMsgType); }; + inline TUint8 *GetSPI() const { return ((TUint8*)this + sizeof(*this)); }; //returns the SPI Data + inline TUint8 *GetNotifData() const { return ((TUint8*)this + sizeof(*this) + iSPISize); }; //returns the Notification Data + inline TUint16 GetNotifDataSize() const { return (TUint16)(GetLength() - (sizeof(*this) + iSPISize)); };//returns the Notification Data Length + + static inline TNotificationISAKMP *Ptr(const TPayloadISAKMP *aPayload) + { return (TNotificationISAKMP *)aPayload; } + + TUint32 iDOI; //Domain Of Interpretation + TUint8 iProtocol; //Protocol ID for the current notification + TUint8 iSPISize; //size in octets. For ISAKMP should be from 0 to 16. If >0 SPI ignored + TUint16 iMsgType; //Notify msg type. See constants. + //Plus the variable fields SPI and Notification Data (both included in length) +private: + inline void MsgTypeToStr(TDes &aBuf, TUint16 aMsgType) const + { +#ifdef _DEBUG + switch (aMsgType) + { + //NOTIFY MESSAGES - ERROR TYPES + case INVALID_PAYLOAD_TYPE: + aBuf = _L("INVALID_PAYLOAD_TYPE"); + break; + case DOI_NOT_SUPPORTED: + aBuf = _L("DOI_NOT_SUPPORTED"); + break; + case SITUATION_NOT_SUPPORTED: + aBuf = _L("SITUATION_NOT_SUPPORTED"); + break; + case INVALID_COOKIE: + aBuf = _L("INVALID_COOKIE"); + break; + case INVALID_MAJOR_VERSION: + aBuf = _L("INVALID_MAJOR_VERSION"); + break; + case INVALID_MINOR_VERSION: + aBuf = _L("INVALID_MINOR_VERSION"); + break; + case INVALID_EXCHANGE_TYPE: + aBuf = _L("INVALID_EXCHANGE_TYPE"); + break; + case INVALID_FLAGS: + aBuf = _L("INVALID_FLAGS"); + break; + case INVALID_MESSAGE_ID: + aBuf = _L("INVALID_MESSAGE_ID"); + break; + case INVALID_PROTOCOL_ID: + aBuf = _L("INVALID_PROTOCOL_ID"); + break; + case INVALID_SPI: + aBuf = _L("INVALID_SPI"); + break; + case INVALID_TRANSFORM_ID: + aBuf = _L("INVALID_SPI"); + break; + case ATTRIBUTES_NOT_SUPPORTED: + aBuf = _L("ATTRIBUTES_NOT_SUPPORTED"); + break; + case NO_PROPOSAL_CHOSEN: + aBuf = _L("NO_PROPOSAL_CHOSEN"); + break; + case BAD_PROPOSAL_SYNTAX: + aBuf = _L("BAD_PROPOSAL_CHOSEN"); + break; + case PAYLOAD_MALFORMED: + aBuf = _L("PAYLOAD_MALFORMED"); + break; + case INVALID_KEY_INFORMATION: + aBuf = _L("INVALID_KEY_INFORMATION"); + break; + case INVALID_ID_INFORMATION: + aBuf = _L("INVALID_ID_INFORMATION"); + break; + case INVALID_CERT_ENCODING: + aBuf = _L("INVALID_CERT_ENCODING"); + break; + case INVALID_CERTIFICATE: + aBuf = _L("INVALID_CERTIFICATE"); + break; + case CERT_TYPE_UNSUPPORTED: + aBuf = _L("CERT_TYPE_UNSUPPORTED"); + break; + case INVALID_CERT_AUTHORITY: + aBuf = _L("INVALID_CERT_AUTHORITY"); + break; + case INVALID_HASH_INFORMATION: + aBuf = _L("INVALID_HASH_INFORMATION"); + break; + case AUTHENTICATION_FAILED: + aBuf = _L("AUTHENTICATION_FAILED"); + break; + case INVALID_SIGNATURE: + aBuf = _L("INVALID_SIGNATURE"); + break; + case ADDRESS_NOTIFICATION: + aBuf = _L("ADDRESS_NOTIFICATION"); + break; + case NOTIFY_SA_LIFETIME: + aBuf = _L("NOTIFY_SA_LIFETIME"); + break; + case CERTIFICATE_UNAVAILABLE: + aBuf = _L("CERTIFICATE_UNAVAILABLE"); + break; + case UNSUPPORTED_EXCHANGE_TYPE: + aBuf = _L("UNSUPPORTED_EXCHANGE_TYPE"); + break; + case UNEQUAL_PAYLOAD_LENGTHS: + aBuf = _L("UNEQUAL_PAYLOAD_LENGTHS"); + break; + case CONNECTED: + aBuf = _L("CONNECTED"); + break; + default: + if ((aMsgType>30) && (aMsgType < 8192)) + aBuf.Format(_L("ERROR RESERVED Future Use (%d)"),aMsgType); + else if ((aMsgType>8191) && (aMsgType < 16384)) + aBuf.Format(_L("ERROR Private Use (%d)"),aMsgType); + else if (((aMsgType>16384) && (aMsgType < 24576)) || ((aMsgType>40959) && (aMsgType < 65536))) + aBuf.Format(_L("STATUS RESERVED Future Use (%d)"),aMsgType); + else if ((aMsgType>24575) && (aMsgType < 32768)) + aBuf.Format(_L("STATUS DOI Specific (%d)"),aMsgType); + else if ((aMsgType>32767) && (aMsgType < 40959)) + aBuf.Format(_L("STATUS Private Use (%d)"),aMsgType); + else + aBuf.Format(_L("UNKNOWN ERROR (%d)"),aMsgType); + } +#else + (void)aBuf; + (void)aMsgType; +#endif + } + + inline void ProtocolToStr(TDes& aBuf, TUint16 aProtocol) const + { +#ifdef _DEBUG + + switch (aProtocol) + { + //Protocol number for IPSEC DOI (=1) + case PROTO_ISAKMP: + aBuf = _L("PROTO_ISAKMP"); + break; + case PROTO_IPSEC_AH: + aBuf = _L("PROTO_IPSEC_AH"); + break; + case PROTO_IPSEC_ESP: + aBuf = _L("PROTO_IPSEC_ESP"); + break; + case PROTO_IPCOMP: + aBuf = _L("PROTO_IPCOMP"); + break; + default: + aBuf.Format(_L("Unknown (%d) "),aProtocol); + } +#else + (void)aBuf; + (void)aProtocol; +#endif + } + + +}; + +class TDeleteISAKMP : public TPayloadISAKMP +{ +public: + inline TUint32 DOI() const { return GET32(&iDOI); }; + inline void SetDOI(TUint32 aDOI) { PUT32(&iDOI, aDOI); }; + inline TUint8 Protocol() const { return iProtocol; }; + inline void SetProtocol(TUint8 aPayload) { iProtocol = aPayload; }; + inline TUint8 SPISize() const { return iSPISize; }; + inline void SetSPISize(TUint8 aPayload) { iSPISize = aPayload; }; + inline TUint16 NumSPI() const { return (TUint16)GET16(&iNumSPI); }; + inline void SetNumSPI(TUint16 aNumSPI) { PUT16(&iNumSPI, aNumSPI); }; + + static inline TDeleteISAKMP *Ptr(const TPayloadISAKMP *aPayload) + { return (TDeleteISAKMP *)aPayload; } + inline TUint8 *SPIList() const {return ((TUint8*)this + sizeof(*this)); } //* to Vendor ID Data + inline TUint8 *SPI(TUint i) const {return ((TUint8*)this + sizeof(*this) + i * SPISize()); } //i-th SPI + inline void String(TDes &aStr) const + { +#ifdef _DEBUG + aStr.Append(_L(" Delete payload ")); + aStr.AppendFormat(_L(" DOI= %u"), DOI()); + aStr.AppendFormat(_L(" Prot=%u "), Protocol()); + aStr.AppendFormat(_L(" SPIsize= %u"), SPISize()); + aStr.AppendFormat(_L(" #SPI=%u "), NumSPI()); + //2 variable size fields + + //TUint8 *p=((TUint8 *)Payload()); + TUint8 *p; + for (TInt i=0; i < NumSPI(); i++) + { + aStr.AppendFormat(_L(" #SPI(%d)="),i); + p=SPI(i); + for (TUint j=0 ; j < SPISize() ; j++) + { + if (j%4==0) + aStr.AppendFormat(_L(" ")); + aStr.AppendFormat(_L("%02.2x"), p[j]); //not sure SPI + } + } +#else + (void)aStr; +#endif + } + + TUint32 iDOI; //Domain Of Interpretation + TUint8 iProtocol; //Protocol ID for the current notification + TUint8 iSPISize; //size in octets. For ISAKMP should be from 0 to 16. If >0 SPI ignored + TUint16 iNumSPI; //# of SPIs to be deleted + //Plus iNumSPI variable fields SPI +}; + + +class TVendorISAKMP : public TPayloadISAKMP +{ +public: + static inline TVendorISAKMP *Ptr(const TPayloadISAKMP *aPayload) + { return (TVendorISAKMP *)aPayload; } + inline TUint8 *VIDData() const {return ((TUint8*)this + sizeof(*this)); } //* to Vendor ID Data + +}; + +class TCHREISAKMP : public TPayloadISAKMP +{ +public: + static inline TCHREISAKMP *Ptr(const TPayloadISAKMP *aPayload) + { return (TCHREISAKMP *)aPayload; } + inline TUint16 GetLAMtype() const { return (TUint16)GET16(&iLAMType); } + inline void SetLAMtype(TUint16 aLength) { PUT16(&iLAMType, aLength); } + inline TUint16 GetCHREReserved() const { return iReserved; } + inline void SetCHREReserved() { iReserved = 0; } + inline TDataISAKMP *CHREAttrib() const {return (TDataISAKMP *)((TUint8*)this + sizeof(*this)); } //* to CHRE attributes + //void String(TDes &aStr) const; + TUint16 iLAMType; //LAM type + TUint16 iReserved; //reserved must be zero +}; + +class TINTNETISAKMP : public TPayloadISAKMP +{ +public: + static inline TINTNETISAKMP *Ptr(const TPayloadISAKMP *aPayload) + { return (TINTNETISAKMP *)aPayload; } + inline TDataISAKMP *INTNETAttrib() const {return (TDataISAKMP *)((TUint8*)this + sizeof(*this)); } //* to INTNET attributes + //void String(TDes &aStr) const; +}; + +class TNATDISAKMP : public TPayloadISAKMP +{ +public: + static inline TNATDISAKMP *Ptr(const TPayloadISAKMP *aPayload) + { return (TNATDISAKMP *)aPayload; } + inline TUint8 *HashData() const {return ((TUint8*)this + sizeof(*this)); } //* to NAT D hash data + inline TUint32 HashLth() const {return (GetLength() - sizeof(*this)); }; +}; + + +class TNATOaISAKMP : public TPayloadISAKMP +{ +public: + inline TUint8 GetIDType() const { return iIDType; } + inline void SetIDType(TUint8 aIDType) { iIDType=aIDType; } + inline void SetReservedFields() { iReserved8=0; PUT16(iReserved16, 0); } + // + static inline TNATOaISAKMP *Ptr(const TPayloadISAKMP *aPayload) + { return (TNATOaISAKMP *)aPayload; } + + inline TUint8 *OAData() const {return ((TUint8*)this + sizeof(*this)); } //* to identity data + inline TUint16 OADDataLen() const {return (TUint16)(GetLength() - sizeof(*this)); } //Length of the payload data +public: + TUint8 iIDType; + //IPSEC DOI Specific fields + TUint8 iReserved8; + TUint16 iReserved16; + +}; + +class TAttributeISAKMP : public TPayloadISAKMP +{ +public: + inline TUint8 CfgMsgType() const { return iCfgMsgType; } + inline void SetCfgMsgType(TUint8 aMsgType) { iCfgMsgType=aMsgType; } + inline void SetReservedField() { iReserved8=0;} + inline TUint16 Identifier() const { return (TUint16)GET16(&iIdentifier);} + inline void SetIdentifier(TUint16 aIdentifier) { PUT16(&iIdentifier, aIdentifier); } + // + static inline TAttributeISAKMP *Ptr(const TPayloadISAKMP *aPayload) + { return (TAttributeISAKMP *)aPayload; } + inline TDataISAKMP *AttrData() const {return (TDataISAKMP *)((TUint8*)this + sizeof(*this)); } //* to attribute data + inline TInt AttrDataLen() const {return (TInt)(GetLength() - sizeof(*this)); } //Length of the payload data +public: + TUint8 iCfgMsgType; + TUint8 iReserved8; + TUint16 iIdentifier; + +}; + + +// +// DATA ATTRIBUTES +// +class TDataISAKMP + { +public: + TDataISAKMP(){u.iData32[0] = 0;} + inline TBool IsBasic() const {return ((u.iData8[0] & 0x80) != 0);} //return if basic attrib or variable + inline void SetBasic(TBool aIsBasic) + { + if (aIsBasic) + u.iData8[0] |= 0x80; + else u.iData8[0] &= 0x7F; + } + inline TUint16 Type() const { return (TUint16)(GET16(&u.iData16[0]) & (TUint16)0x7FFF);} + inline void SetType(TUint16 aType) + { + u.iData8[1] = (TUint8)(aType & 0x00ff); + u.iData8[0] &= 0x80; + u.iData8[0] |= ((TUint8)(aType >> 8)) & 0x7F; + } + inline TUint16 Length() const + { + if (!IsBasic()) + return (TUint16)GET16(&u.iData16[1]); + return 0; //No length needed + } + inline void SetLength(TUint16 aLength) { if (!IsBasic()) PUT16(&u.iData16[1], aLength); } + inline TUint16 Value() const + { + if (IsBasic()) + return (TUint16)GET16(&u.iData16[1]); + return 0; + } + inline void SetValue(TUint16 aValue) { if (IsBasic()) PUT16(&u.iData16[1], aValue);} + inline TUint8 *VarValue() const + { + if (!IsBasic()) + return ((TUint8*)this + sizeof(*this)); + return NULL; + } + inline TUint Size() { return (sizeof(*this) + Length());} //return attr header full size + inline TDataISAKMP *Next() {return (TDataISAKMP *)((TUint8*)this + sizeof(*this) + Length());} //next attribute +public: + union + { + TUint32 iData32[1]; + TUint16 iData16[2]; + TUint8 iData8[4]; + } u; + }; +//Plus Length() bytes if variable attrib; + +// +// TLastIKEMsg +// This class is used to detect possible IKE message retransmission from peer. +// The following information is stored to object data in consturctor: +// -- IKE message length (octets iData8[0], iData8[1] and iData8[2]) +// -- Next payload code (iData8[3]) +// -- IP checksum over entire IKE message (iData32[1]) +// +class TLastIKEMsg + { +public: + inline TLastIKEMsg() { u.iData32[0] = 0; u.iData32[1] = 0;} + inline TLastIKEMsg(const ThdrISAKMP& aHdr) + { + u.iData32[0] = aHdr.GetLength(); + TUint16 *End = (TUint16*)((TUint8*)&aHdr + (u.iData32[0] & 0xfffffffe)); + TUint16 *Ptr = (TUint16*)&aHdr; + u.iData8[3] = aHdr.GetPayload(); // MUST NOT be stored before length value ! + TUint32 sum = 0; + while ( Ptr < End ) sum += *Ptr++; + u.iData32[1] = sum; + } + inline TBool IsUninitialized() + { + if (u.iData32[0] == 0 && u.iData32[1] == 0) + return ETrue; + return EFalse; + } + inline void Store(TLastIKEMsg& aRef) + { aRef.u.iData32[0] = u.iData32[0]; aRef.u.iData32[1] = u.iData32[1]; } + inline TBool IsReTransmit(TLastIKEMsg& aRef) + { return ((u.iData32[0] == aRef.u.iData32[0]) && (u.iData32[1] == aRef.u.iData32[1]));} +private: + union + { + TUint32 iData32[2]; + TUint8 iData8[8]; + } u; + }; + + +#endif // IKEV1PAYLOADS_H