--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/networksecurity/ipsec/ipsec6/src/pfkeymsg.cpp Tue Jan 26 15:23:49 2010 +0200
@@ -0,0 +1,1028 @@
+// 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:
+// pfkeymsg.cpp - IPv6/IPv4 IPSEC PFKEY message handling utilities
+//
+
+#include <networking/pfkeyv2.h>
+#include "pfkeymsg.h"
+#include "pfkeyext.h" // PFKEY API General extension
+#include "ipseclog.h"
+#include "sadb.h"
+
+
+T_sadb_msg::T_sadb_msg(TUint8 aMsgType, TUint8 aSaType, TUint32 aSeq)
+ {
+ sadb_msg_version = PF_KEY_V2;
+ sadb_msg_type = aMsgType;
+ sadb_msg_errno = 0;
+ sadb_msg_satype = aSaType;
+ sadb_msg_len = ((sizeof(*this) + 7) / 8),
+ sadb_msg_reserved = 0;
+ sadb_msg_seq = aSeq;
+ sadb_msg_pid = 0;
+ }
+
+
+T_sadb_sa::T_sadb_sa(TUint32 aSPI, TUint8 aWindow, TUint8 aState, TUint8 aAalg, TUint8 aEalg, TUint32 aFlags)
+ {
+ sadb_sa_len = (sizeof(*this) + 7) / 8;
+ sadb_sa_exttype = SADB_EXT_SA;
+ sadb_sa_spi = aSPI;
+ sadb_sa_replay = aWindow;
+ sadb_sa_state = aState;
+ sadb_sa_auth = aAalg;
+ sadb_sa_encrypt = aEalg;
+ sadb_sa_flags = aFlags;
+ }
+
+
+// Construct sadb_lifetime for the CURRENT
+T_sadb_lifetime::T_sadb_lifetime(const TLifetime &aLt)
+ {
+ sadb_lifetime_len = (sizeof(*this) + 7) / 8;
+ sadb_lifetime_exttype = SADB_EXT_LIFETIME_CURRENT;
+ sadb_lifetime_allocations = aLt.iAllocations;
+ sadb_lifetime_bytes = aLt.iBytes;
+
+ // Convert time stamps
+ TTimeIntervalSeconds seconds;
+ TTime time_now;
+ time_now.UniversalTime();
+
+ // Lifetime doesn't fit the 32bit int? Do I need to consider
+ // probes to Alpha Centauri?
+ if (time_now.SecondsFrom(aLt.iAddtime, seconds))
+ sadb_lifetime_addtime = 0;
+ else
+ sadb_lifetime_addtime = seconds.Int();
+
+ // If iCurrent.iUsetime still NullTime, then usetime
+ // has not yet defined, return 0 (aSa.iUsed == 0)
+ if (aLt.iUsetime == Time::NullTTime() || time_now.SecondsFrom(aLt.iUsetime, seconds))
+ sadb_lifetime_usetime = 0;
+ else
+ sadb_lifetime_usetime = seconds.Int();
+ }
+
+// Construct sadb_lifetime for HARD and SOFT, relative to CURRENT (aRef)
+T_sadb_lifetime::T_sadb_lifetime(TUint8 aType, const TLifetime &aLt, const TLifetime &aRef)
+ {
+ sadb_lifetime_len = (sizeof(*this) + 7) / 8;
+ sadb_lifetime_exttype = aType;
+ sadb_lifetime_allocations = aLt.iAllocations;
+ sadb_lifetime_bytes = aLt.iBytes;
+
+ // An implementation decision: if the expiration time
+ // is so far in the future that the result in seconds
+ // does not fit into 32 bit integer, then report it as
+ // being infinite. (0?)
+ TTimeIntervalSeconds seconds;
+
+ if (aLt.iAddtime == Time::MaxTTime() || aLt.iAddtime.SecondsFrom(aRef.iAddtime, seconds))
+ sadb_lifetime_addtime = 0;
+ else
+ sadb_lifetime_addtime = seconds.Int();
+
+ // If the reference iUsetime is NULL, then usetime is not
+ // yet frozen, just return the value as is.
+ if (aRef.iUsetime == Time::NullTTime())
+ sadb_lifetime_usetime = aLt.iUsetime.Int64();
+ else if (aLt.iUsetime == Time::MaxTTime() || aLt.iUsetime.SecondsFrom(aRef.iUsetime, seconds))
+ sadb_lifetime_usetime = 0;
+ else
+ sadb_lifetime_usetime = seconds.Int();
+ }
+
+T_sadb_address::T_sadb_address(TUint8 aType, TUint8 aProto, TUint8 aPrefix)
+ {
+ sadb_address_len = (sizeof(*this) + sizeof(TInetAddr) + 7) / 8;
+ sadb_address_exttype = aType;
+ sadb_address_proto = aProto;
+ sadb_address_prefixlen = aPrefix;
+ sadb_address_reserved = 0;
+ }
+
+T_sadb_key::T_sadb_key(TUint8 aType, TInt aKeyBytes, TInt aKeyBits)
+ {
+ sadb_key_len = (uint16_t)((sizeof(*this) + aKeyBytes + 7) / 8);
+ sadb_key_exttype = aType;
+ sadb_key_bits = (uint16_t)(aKeyBits < 0 ? aKeyBytes * 8 : aKeyBits);
+ sadb_key_reserved = 0;
+ }
+
+T_sadb_supported::T_sadb_supported(TUint8 aType, TInt aNum)
+ {
+ sadb_supported_len = (uint16_t)((sizeof(*this) + sizeof(sadb_alg) * aNum + 7) / 8);
+ sadb_supported_exttype = aType;
+ sadb_supported_reserved = 0;
+ }
+
+T_sadb_ident::T_sadb_ident(TUint8 aType, TInt aLength)
+ {
+ sadb_ident_len = (uint16_t)((sizeof(*this) + aLength + 1 + 7) / 8);
+ sadb_ident_exttype = aType;
+ sadb_ident_reserved = 0;
+ sadb_ident_type = 0;
+ sadb_ident_id = 0;
+ }
+
+T_sadb_sens::T_sadb_sens()
+ {
+ sadb_sens_len = (uint16_t)((sizeof(*this) + 7) / 8);
+ sadb_sens_exttype = SADB_EXT_SENSITIVITY;
+ sadb_sens_dpd = 0;
+ sadb_sens_sens_level = 0;
+ sadb_sens_sens_len = 0;
+ sadb_sens_integ_level = 0;
+ sadb_sens_integ_len = 0;
+ sadb_sens_reserved = 0;
+ }
+
+T_sadb_prop::T_sadb_prop(TUint8 aReplay, TInt aNum)
+ {
+ sadb_prop_len = (uint16_t)((sizeof(*this) + aNum * sizeof(struct sadb_comb) + 7) / 8);
+ sadb_prop_exttype = SADB_EXT_PROPOSAL;
+ sadb_prop_replay = aReplay;
+ //sadb_prop_reserved[0..3] = 0;
+ }
+
+
+T_sadb_ts::T_sadb_ts(TInt aNum)
+ {
+ sadb_x_ts_len = (uint16_t)((sizeof(*this) + aNum * sizeof(T_sadb_selector) + 7) / 8);
+ sadb_x_ts_exttype = SADB_X_EXT_TS;
+ sadb_x_ts_numsel = aNum;
+ }
+
+
+TInt TPfkeyBase::ByteStream(RMBufChain &aPacket, TInt aTotal) const
+ {
+ if (iMsg)
+ {
+ struct sadb_msg base = *iMsg;
+ base.sadb_msg_len = (TUint16)(aTotal / 8);
+ aPacket.CopyIn(TPtrC8((TUint8 *)&base, sizeof(base)), 0);
+ return Length();
+ }
+ else
+ return 0;
+ }
+
+TInt TPfkeyAssociation::ByteStream(RMBufChain &aPacket, TInt aOffset) const
+ {
+ if (iExt)
+ {
+ aPacket.CopyIn(TPtrC8((TUint8 *)iExt, sizeof(*iExt)), aOffset);
+ aOffset += Length();
+ }
+ return aOffset;
+ }
+
+TInt TPfkeyLifetime::ByteStream(RMBufChain &aPacket, TInt aOffset) const
+ {
+ if (iExt)
+ {
+ aPacket.CopyIn(TPtrC8((TUint8 *)iExt, sizeof(*iExt)), aOffset);
+ aOffset += Length();
+ }
+ return aOffset;
+ }
+
+TInt TPfkeyTs::ByteStream(RMBufChain &aPacket, TInt aOffset) const
+ {
+ if (iExt && iTS)
+ {
+ aPacket.CopyIn(TPtrC8((TUint8 *)iExt, sizeof(*iExt)), aOffset);
+ aOffset += sizeof(*iExt);
+ for (TInt i = 0; i < iExt->sadb_x_ts_numsel; ++i)
+ {
+ T_sadb_selector sel;
+ const RTrafficSelector &ts = (*iTS)[i];
+ sel.sadb_x_selector_proto = ts.iProtocol;
+ sel.iSrc.SetAddress(ts.iSrc());
+ sel.iSrc.SetPort(ts.iPortSrc);
+ sel.iSrc.SetScope(ts.iSrc().iScope);
+ sel.iDst.SetAddress(ts.iDst());
+ sel.iDst.SetPort(ts.iPortDst);
+ sel.iDst.SetScope(ts.iDst().iScope);
+ // Setup next sel.
+ aPacket.CopyIn(TPtrC8((TUint8 *)&sel, sizeof(sel)), aOffset);
+ aOffset += sizeof(sel);
+ }
+ }
+ return aOffset;
+ }
+
+TInt TPfkeyAddress::ByteStream(RMBufChain &aPacket, TInt aOffset) const
+ {
+ if (iExt)
+ {
+ TInetAddr addr(iPort);
+ addr.SetAddress(iAddr());
+ addr.SetScope(iAddr().iScope);
+ if (iAddr().iScope == 0 && addr.IsV4Mapped())
+ addr.SetAddress(addr.Address());
+ aPacket.CopyIn(TPtrC8((TUint8 *)iExt, sizeof(*iExt)), aOffset);
+ aPacket.CopyIn(TPtrC8((TUint8 *)&addr, sizeof(addr)), aOffset + sizeof(*iExt));
+ aOffset += Length();
+ }
+ return aOffset;
+ }
+
+TInt TPfkeyAddress::LoadFromStream(const TInt aLength, const TUint8 *aPtr, REndPoints &aEp)
+ {
+ if (iExt)
+ return KErrGeneral;
+ if (aLength != sizeof(struct sadb_address) + sizeof(TInetAddr))
+ return KErrGeneral;
+ iExt = (struct sadb_address *)aPtr;
+
+ const TInetAddr &addr = *(TInetAddr *)(aPtr + sizeof(struct sadb_address));
+ TIpAddress tmp(addr);
+ const TInt err = iAddr.Open(aEp, tmp);
+ iPort = (TUint16)addr.Port();
+ return err;
+ }
+
+
+
+TInt TPfkeyIdentity::ByteStream(RMBufChain &aPacket, TInt aOffset) const
+ {
+ if (iExt)
+ {
+ aPacket.CopyIn(TPtrC8((TUint8 *)iExt, sizeof(*iExt)), aOffset);
+ aPacket.CopyIn(iData, aOffset + sizeof(*iExt));
+ aPacket.CopyIn(KZeroByte, aOffset + sizeof(*iExt) + iData.Length()); // Patch in the NUL terminator.
+ aOffset += Length();
+ }
+ return aOffset;
+ }
+
+TInt TPfkeyIdentity::LoadFromStream(const TInt aLength, const TUint8 *aPtr)
+ {
+ if (iExt)
+ return KErrGeneral;
+ iExt = (struct sadb_ident *)aPtr;
+ TInt len = aLength - sizeof(struct sadb_ident);
+ if (len < 0)
+ return KErrGeneral;
+ iData.Set(aPtr + sizeof(struct sadb_ident), len);
+
+ // strip off the trailing zero byte, if present.
+ len = iData.Locate(0);
+ if (len >= 0)
+ iData.Set(iData.Ptr(), len);
+ return KErrNone;
+ }
+
+TInt TPfkeyKey::ByteStream(RMBufChain &aPacket, TInt aOffset) const
+ {
+ if (iExt)
+ {
+ aPacket.CopyIn(TPtrC8((TUint8 *)iExt, sizeof(*iExt)), aOffset);
+ aPacket.CopyIn(iData, aOffset + sizeof(*iExt));
+ aOffset += Length();
+ }
+ return aOffset;
+ }
+
+TInt TPfkeySensitivity::ByteStream(RMBufChain &aPacket, TInt aOffset) const
+ {
+ if (iExt)
+ {
+ aPacket.CopyIn(TPtrC8((TUint8 *)iExt, sizeof(*iExt)), aOffset);
+ aPacket.CopyIn(iSensBitmap, aOffset + sizeof(*iExt));
+ aPacket.CopyIn(iIntegBitmap, aOffset + sizeof(*iExt) + iSensBitmap.Length());
+ aOffset += Length();
+ }
+ return aOffset;
+ }
+
+TInt TPfkeyProposal::ByteStream(RMBufChain &aPacket, TInt aOffset) const
+ {
+ if (iExt)
+ {
+ aPacket.CopyIn(TPtrC8((TUint8 *)iExt, sizeof(*iExt)), aOffset);
+ aPacket.CopyIn(TPtrC8((TUint8 *)iComb, sizeof(*iComb) * iNumComb),
+ aOffset + sizeof(*iExt));
+ aOffset += Length();
+ }
+ return aOffset;
+ }
+
+TInt TPfkeySupported::ByteStream(RMBufChain &aPacket, TInt aOffset) const
+ {
+ if (iExt)
+ {
+ aPacket.CopyIn(TPtrC8((TUint8 *)iExt, sizeof(*iExt)), aOffset);
+ aPacket.CopyIn(TPtrC8((TUint8 *)iAlg, sizeof(*iAlg) * iNumAlg),
+ aOffset + sizeof(*iExt));
+ aOffset += Length();
+ }
+ return aOffset;
+ }
+
+void TPfkeySupported::Init(struct sadb_supported *aExt, TInt aNumAlg, struct sadb_alg *aAlg)
+ {
+ iExt = aExt;
+ iAlg = aAlg;
+ iNumAlg = aNumAlg;
+ }
+
+TInt TPfkeySpirange::ByteStream(RMBufChain &aPacket, TInt aOffset) const
+ {
+ if (iExt)
+ {
+ aPacket.CopyIn(TPtrC8((TUint8 *)iExt, sizeof(*iExt)), aOffset);
+ aOffset += Length();
+ }
+ return aOffset;
+ }
+
+TInt TPfkeyAddress::BindToEndPoint(TPfkeyIdentity &aName, REndPoints &aEp)
+ {
+ TInt err = KErrNone;
+ if (aName.iExt)
+ {
+ HBufC *buf = HBufC::New(aName.iData.Length());
+ if (buf == NULL)
+ return KErrNoMemory;
+ buf->Des().Copy(aName.iData);
+ // Do not override existing address, if iAddr does not specify a new address.
+ TIpAddress tmp;
+ // Need to save previous address, as Open below may release
+ // the temporary TIpAddr referenced by iAddr().
+ tmp = iAddr();
+ err = iAddr.Open(aEp, *buf, tmp, tmp.IsNone());
+ delete buf;
+ }
+ return err;
+ }
+
+// TPfkeyMessage
+//
+// Construct TPfkeyMesage from a PF_KEY v2 byte stream (aMsg)
+TPfkeyMessage::TPfkeyMessage(const TDesC8& aMsg, REndPoints &aEp)
+ {
+ const TUint8 *p = aMsg.Ptr();
+ TInt length = aMsg.Length();
+
+ iError = KErrArgument;
+ if (length < (TInt)sizeof(sadb_msg))
+ return; // EMSGSIZE (impossible message size)
+
+ // Base Message Header
+ iBase.iMsg = (struct sadb_msg *)p;
+ if (iBase.iMsg->sadb_msg_version != PF_KEY_V2)
+ return; // EINVAL
+ // SADB_ACQUIRE response can have sadb_msg_errno set to non-zero value
+ if (iBase.iMsg->sadb_msg_errno && (iBase.iMsg->sadb_msg_type != SADB_ACQUIRE))
+ return; // EINVAL (should be set zero by sender)
+ if (iBase.iMsg->sadb_msg_len * 8 != length)
+ return; // EMSGSIZE (incorrect message length)
+ // SADB_ACQUIRE response can have sadb_msg_reserved set to non-zero value
+ if (iBase.iMsg->sadb_msg_reserved && (iBase.iMsg->sadb_msg_type != SADB_ACQUIRE))
+ return; // EINVAL (unused parts must be zeroed)
+ p += sizeof(struct sadb_msg);
+ length -= sizeof(struct sadb_msg);
+
+ // Extension headers
+ // Some general rules:
+ // - only one instance of an extension type is valid
+ while (length > 0)
+ {
+ struct sadb_ext *ext = (struct sadb_ext *)p;
+ int ext_len = ext->sadb_ext_len;
+ int data_len, data_len2;
+
+ if (ext_len < 1)
+ return; // EINVAL (bad message format)
+ ext_len *= 8;
+ if (ext_len > length)
+ return; // EINVAL
+ switch (ext->sadb_ext_type)
+ {
+ case SADB_EXT_RESERVED:
+ return; // EINVAL (bad mesage format)
+
+ case SADB_EXT_SA:
+ if (iSa.iExt)
+ return; // EINVAL
+ iSa.iExt = (struct sadb_sa *)p;
+ break;
+
+ case SADB_EXT_LIFETIME_CURRENT:
+ if (iCurrent.iExt)
+ return; // EINVAL;
+ iCurrent.iExt = (struct sadb_lifetime *)p;
+ break;
+
+ case SADB_EXT_LIFETIME_HARD:
+ if (iHard.iExt)
+ return;
+ iHard.iExt = (struct sadb_lifetime *)p;
+ break;
+
+ case SADB_EXT_LIFETIME_SOFT:
+ if (iSoft.iExt)
+ return;
+ iSoft.iExt = (struct sadb_lifetime *)p;
+ break;
+
+ case SADB_EXT_ADDRESS_SRC:
+ if (iSrcAddr.LoadFromStream(ext_len, p, aEp) != KErrNone)
+ return;
+ break;
+
+ case SADB_EXT_ADDRESS_DST:
+ if (iDstAddr.LoadFromStream(ext_len, p, aEp) != KErrNone)
+ return;
+ break;
+
+ case SADB_EXT_ADDRESS_PROXY:
+ if (iProxyAddr.LoadFromStream(ext_len, p, aEp) != KErrNone)
+ return;
+ break;
+
+ case SADB_EXT_KEY_AUTH:
+ if (iAuthKey.iExt)
+ return;
+ iAuthKey.iExt = (struct sadb_key *)p;
+ data_len = (iAuthKey.iExt->sadb_key_bits + 7) / 8;
+ if (data_len == 0 || data_len + (int)sizeof(struct sadb_key) > ext_len)
+ return;
+ iAuthKey.iData.Set(p + sizeof(struct sadb_key), data_len);
+ break;
+
+ case SADB_EXT_KEY_ENCRYPT:
+ if (iEncryptKey.iExt)
+ return;
+ iEncryptKey.iExt = (struct sadb_key *)p;
+ data_len = (iEncryptKey.iExt->sadb_key_bits + 7) / 8;
+ if (data_len == 0 || data_len + (int)sizeof(struct sadb_key) > ext_len)
+ return;
+ iEncryptKey.iData.Set(p + sizeof(struct sadb_key), data_len);
+ break;
+
+ case SADB_EXT_IDENTITY_SRC:
+ if (iSrcIdent.LoadFromStream(ext_len, p) != KErrNone)
+ return;
+ break;
+
+ case SADB_EXT_IDENTITY_DST:
+ if (iDstIdent.LoadFromStream(ext_len, p) != KErrNone)
+ return;
+ break;
+
+ case SADB_EXT_SENSITIVITY:
+ if (iSensitivity.iExt)
+ return;
+ iSensitivity.iExt = (struct sadb_sens *)p;
+ data_len = iSensitivity.iExt->sadb_sens_sens_len * 8;
+ iSensitivity.iSensBitmap.Set(p + sizeof(struct sadb_sens), data_len);
+ data_len2 = iSensitivity.iExt->sadb_sens_integ_len * 8;
+ iSensitivity.iSensBitmap.Set(p + (sizeof(struct sadb_sens) + data_len),
+ data_len2);
+ if (data_len + data_len2 + (int)sizeof(struct sadb_sens) > ext_len)
+ return;
+ break;
+
+ case SADB_EXT_PROPOSAL:
+ if (iProposal.iExt)
+ return;
+ iProposal.iExt = (struct sadb_prop *)p;
+ iProposal.iNumComb = (ext_len - sizeof(struct sadb_prop)) / sizeof(struct sadb_comb);
+ iProposal.iComb = (struct sadb_comb *)(p + sizeof(struct sadb_prop));
+ break;
+
+ case SADB_EXT_SUPPORTED_AUTH:
+ if (iAuthAlgs.iExt)
+ return;
+ iAuthAlgs.iExt = (struct sadb_supported *)p;
+ iAuthAlgs.iNumAlg = (ext_len - sizeof(struct sadb_supported)) / sizeof(struct sadb_alg);
+ iAuthAlgs.iAlg = (struct sadb_alg *)(p + sizeof(struct sadb_supported));
+ break;
+
+ case SADB_EXT_SUPPORTED_ENCRYPT:
+ if (iEncryptAlgs.iExt)
+ return;
+ iEncryptAlgs.iExt = (struct sadb_supported *)p;
+ iEncryptAlgs.iNumAlg = (ext_len - sizeof(struct sadb_supported)) / sizeof(struct sadb_alg);
+ iEncryptAlgs.iAlg = (struct sadb_alg *)(p + sizeof(struct sadb_supported));
+ break;
+
+ case SADB_EXT_SPIRANGE:
+ if (iSpirange.iExt)
+ return;
+ iSpirange.iExt = (struct sadb_spirange *)p;
+ break;
+
+ /**---------------------------------------------------------------
+ *
+ * PFKEY API general private extension.
+ *
+ *----------------------------------------------------------------*/
+ case SADB_PRIV_GENERIC_EXT:
+ if (iPrivateExtension.iExt)
+ return;
+ iPrivateExtension.iExt = (struct sadb_gen_ext *)p;
+ data_len = (ext_len - sizeof(struct sadb_gen_ext));
+ if (data_len > ext_len)
+ return;
+ iPrivateExtension.iData.Set(p + sizeof(struct sadb_gen_ext), data_len);
+ break;
+
+ // End Point Extensions
+ case SADB_X_EXT_ENDPOINT_SRC:
+ if (iSrcEndpoint.LoadFromStream(ext_len, p) != KErrNone)
+ return;
+ break;
+ case SADB_X_EXT_ENDPOINT_DST:
+ if (iDstEndpoint.LoadFromStream(ext_len, p) != KErrNone)
+ return;
+ break;
+
+ case SADB_X_EXT_TS:
+ if (iTs.iExt)
+ return;
+ iTs.iExt = (struct sadb_x_ts *)p;
+ break;
+
+ default:
+ // Unknown extensions must be ignored, not an error!
+ break;
+ }
+ p += ext_len;
+ length -= ext_len;
+ }
+ if (length != 0)
+ return;
+
+ // Do the "End Point Hack"
+ if ((iError = iSrcAddr.BindToEndPoint(iSrcEndpoint, aEp)) == KErrNone)
+ iError = iDstAddr.BindToEndPoint(iDstEndpoint, aEp);
+ }
+
+TUint16 TPfkeyMessage::Length64() const
+ {
+ // Always make sure that all possible fields in PFKEY are included!
+ return (TUint16)(
+ (iBase.Length() +
+ iSa.Length() +
+ iCurrent.Length() +
+ iHard.Length() +
+ iSoft.Length() +
+ iSrcAddr.Length() +
+ iDstAddr.Length() +
+ iProxyAddr.Length() +
+ iAuthKey.Length() +
+ iEncryptKey.Length() +
+ iSrcIdent.Length() +
+ iDstIdent.Length() +
+ iSrcEndpoint.Length() +
+ iDstEndpoint.Length() +
+ iSensitivity.Length() +
+ iProposal.Length() +
+ iAuthAlgs.Length() +
+ iEncryptAlgs.Length() +
+ iTs.Length() +
+ iSpirange.Length()) / 8);
+ }
+
+void TPfkeyMessage::ByteStreamL(RMBufChain &aPacket) const
+ {
+ TInt totlen = Length64() * 8;
+
+ // This code basicly assumes the RMBuf is empty before!!
+ // (Any possible previous content is lost)
+ //
+// aPacket.TrimEnd(0); // does not like empty buffer!!
+ aPacket.AppendL(totlen);
+
+
+ TInt offset = iBase.ByteStream(aPacket, totlen);
+
+ // Always make sure that all possible extension fields in PFKEY are included!
+
+ offset = iSa.ByteStream(aPacket, offset);
+ offset = iCurrent.ByteStream(aPacket, offset);
+ offset = iHard.ByteStream(aPacket, offset);
+ offset = iSoft.ByteStream(aPacket, offset);
+ offset = iSrcAddr.ByteStream(aPacket, offset);
+ offset = iDstAddr.ByteStream(aPacket, offset);
+ offset = iProxyAddr.ByteStream(aPacket, offset);
+ offset = iAuthKey.ByteStream(aPacket, offset);
+ offset = iEncryptKey.ByteStream(aPacket, offset);
+ offset = iSrcIdent.ByteStream(aPacket, offset);
+ offset = iDstIdent.ByteStream(aPacket, offset);
+ offset = iSrcEndpoint.ByteStream(aPacket, offset);
+ offset = iDstEndpoint.ByteStream(aPacket, offset);
+ offset = iSensitivity.ByteStream(aPacket, offset);
+ offset = iProposal.ByteStream(aPacket, offset);
+ offset = iAuthAlgs.ByteStream(aPacket, offset);
+ offset = iEncryptAlgs.ByteStream(aPacket, offset);
+ offset = iSpirange.ByteStream(aPacket, offset);
+ offset = iTs.ByteStream(aPacket, offset);
+ }
+
+#ifdef _LOG
+
+// Convert the message type into string literal
+static const TDesC &LogMessageType(TInt aType)
+ {
+ _LIT(Kgetspi, "getspi");
+ _LIT(Kupdate, "update");
+ _LIT(Kadd, "add");
+ _LIT(Kdelete, "delete");
+ _LIT(Kget, "get");
+ _LIT(Kacquire, "acquire");
+ _LIT(Kregister, "register");
+ _LIT(Kexpire, "expire");
+ _LIT(Kflush, "flush");
+ _LIT(Kdump, "dump");
+ _LIT(Kunknown, "unknown");
+ switch (aType)
+ {
+ case SADB_GETSPI: return Kgetspi;
+ case SADB_UPDATE: return Kupdate;
+ case SADB_ADD: return Kadd;
+ case SADB_DELETE: return Kdelete;
+ case SADB_GET: return Kget;
+ case SADB_ACQUIRE: return Kacquire;
+ case SADB_REGISTER: return Kregister;
+ case SADB_EXPIRE: return Kexpire;
+ case SADB_FLUSH: return Kflush;
+ case SADB_DUMP: return Kdump;
+ default: break;
+ }
+ Log::Printf(_L("\t\t*invalid PFKEY message type %d*"), aType);
+ return Kunknown;
+ }
+
+// Convert association (SADB_SATYPE_*) into string literal
+static const TDesC &LogAssociationType(TInt aType)
+ {
+ _LIT(Kah, " ah");
+ _LIT(Kesp, " esp");
+ _LIT(Kinvalid, " invalid");
+
+ switch (aType)
+ {
+ case SADB_SATYPE_UNSPEC: return KNullDesC;
+ case SADB_SATYPE_AH: return Kah;
+ case SADB_SATYPE_ESP: return Kesp;
+ default: break;
+ }
+ Log::Printf(_L("\t\t*invalid PFKEY SA type %d*"), aType);
+ return Kinvalid;
+ }
+
+// Convert Association state (SADB_SASTATE_*) into string literal
+static const TDesC &LogAssociationState(TInt aState)
+ {
+ _LIT(Klarval, " larval");
+ _LIT(Kdying, " dying");
+ _LIT(Kdead, " dead");
+ _LIT(Kinvalid, " invalid");
+
+ switch (aState)
+ {
+ case SADB_SASTATE_LARVAL: return Klarval;
+ case SADB_SASTATE_MATURE: return KNullDesC; // The default state
+ case SADB_SASTATE_DYING: return Kdying;
+ case SADB_SASTATE_DEAD: return Kdead;
+ default: break;
+ }
+ Log::Printf(_L("\t\t*invalid PFKEY state %d*"), aState);
+ return Kinvalid;
+ }
+
+// Convert authentication algorithm (SADB_AALG_*) into string literal
+static const TDesC &LogAuthAlg(TInt aAlg, const CAlgorithmList *aAlgorithms)
+ {
+ _LIT(Kunknown, "auth_alg unknown");
+ _LIT(Knone, "auth none");
+
+ if (!aAlg)
+ return Knone;
+
+ if (aAlgorithms)
+ {
+ const TAlgorithmMap *map = aAlgorithms->Lookup(EAlgorithmClass_Digest, aAlg);
+ if (map)
+ return map->iAlgorithm;
+#ifdef SYMBIAN_IPSEC_VOIP_SUPPORT
+ map = aAlgorithms->Lookup(EAlgorithmClass_Mac, aAlg);
+ return map->iAlgorithm;
+#endif
+ }
+ Log::Printf(_L("\t\t*unknown PFKEY auth_alg %d*"), aAlg);
+ return Kunknown;
+ }
+
+// Convert encryption algorithm (SADB_EALG_*) into string literal
+static const TDesC &LogEncrAlg(TInt aAlg, const CAlgorithmList *aAlgorithms)
+ {
+ _LIT(Kunknown, "encr_alg unknown");
+ _LIT(Knull, "null");
+ _LIT(Knone, "encr none");
+
+ if (!aAlg)
+ return Knone;
+
+ if (aAlgorithms)
+ {
+ const TAlgorithmMap *map = aAlgorithms->Lookup(EAlgorithmClass_Cipher, aAlg);
+ if (map)
+ {
+ if (map->iAlgorithm.Length() == 0)
+ return Knull();
+ return map->iAlgorithm;
+ }
+ }
+ Log::Printf(_L("\t\t*unknown PFKEY encr_alg %d*"), aAlg);
+ return Kunknown;
+ }
+
+// Conditional return either "" or aStr
+static const TDesC &LogTest(TInt aCondition, const TDesC &aStr)
+ {
+ return aCondition ? aStr : KNullDesC;
+ }
+
+static void LogTestAppend(TDes &aBuf, const TDesC &aLabel, TInt aValue)
+ {
+ if (aValue)
+ {
+ aBuf.AppendFormat(_L("%S %d"), &aLabel, aValue);
+ }
+ }
+
+
+// Convert identity type (SADB_IDENTTYP_*) into string literal
+static const TDesC8 &LogIdentityType(TInt aType)
+ {
+ _LIT8(Kprefix, "prefix");
+ _LIT8(Kfqdn, "fqdn");
+ _LIT8(Kuserfqdn, "user_fqdn");
+ _LIT8(Kinvalid, "invalid");
+
+ switch (aType)
+ {
+ case SADB_IDENTTYPE_RESERVED: return KNullDesC8; // Used by EndPoint
+ case SADB_IDENTTYPE_PREFIX: return Kprefix;
+ case SADB_IDENTTYPE_FQDN: return Kfqdn;
+ case SADB_IDENTTYPE_USERFQDN: return Kuserfqdn;
+ default: break;
+ }
+ Log::Printf(_L("\t\t*invalid PFKEY identity type %d*"), aType);
+ return Kinvalid;
+ }
+
+void TPfkeyMessage::LogPrint(const TDesC &aLabel, const CAlgorithmList *aAlgorithms) const
+ {
+ iBase.LogPrint(aLabel);
+ iSa.LogPrint(_L("\t"), aAlgorithms);
+ iCurrent.LogPrint(_L("\tcurrent"));
+ iHard.LogPrint(_L("\thard"));
+ iSoft.LogPrint(_L("\tsoft"));
+ iSrcAddr.LogPrint(_L("\tsrc"));
+ iDstAddr.LogPrint(_L("\tdst"));
+ iProxyAddr.LogPrint(_L("\tproxy"));
+ iAuthKey.LogPrint(_L("\tauthkey"));
+ iEncryptKey.LogPrint(_L("\tencrkey"));
+ iSrcIdent.LogPrint(_L8("\tsrcid"));
+ iDstIdent.LogPrint(_L8("\tdstid"));
+ iSrcEndpoint.LogPrint(_L8("\tsrcep"));
+ iDstEndpoint.LogPrint(_L8("\tdstep"));
+ iSensitivity.LogPrint(_L("\tsensitivity"));
+ iTs.LogPrint(_L("\tts"));
+ iProposal.LogPrint(_L("\tproposal"), aAlgorithms);
+ iAuthAlgs.LogPrint(_L("\t"), aAlgorithms);
+ iEncryptAlgs.LogPrint(_L("\t"), aAlgorithms);
+ iSpirange.LogPrint(_L("\tspirange"));
+ Log::Printf(_L("\tmsg length=%d"), (TInt)8*Length64());
+ }
+
+void TPfkeyBase::LogPrint(const TDesC &aLabel) const
+ {
+ if (iMsg)
+ {
+ TBuf<20> errbuf;
+ // High order bits of the error code are in sadb_msg_reserved!
+ const TInt error = (iMsg->sadb_msg_reserved << 8) | iMsg->sadb_msg_errno;
+ if (error)
+ {
+ errbuf.Format(_L(" error %d"), -error);
+ }
+ Log::Printf(_L("%S\t%S%S seq %d pid %d%S"),
+ &aLabel,
+ &LogMessageType(iMsg->sadb_msg_type),
+ &LogAssociationType(iMsg->sadb_msg_satype),
+ (TInt)iMsg->sadb_msg_seq,
+ (TInt)iMsg->sadb_msg_pid,
+ &errbuf);
+ }
+ }
+
+void TPfkeyAssociation::LogPrint(const TDesC &aLabel, const CAlgorithmList *aAlgorithms) const
+ {
+ _LIT(Kpfs, " pfs");
+ _LIT(Ktunnel, " tunnel");
+ _LIT(Knatt, " nat-t");
+ _LIT(Kaddr, " int-addr");
+ _LIT(Kesn, " esn");
+
+ if (iExt)
+ {
+ const TInt flags = iExt->sadb_sa_flags;
+ TBuf<20> replay;
+ if (iExt->sadb_sa_replay)
+ {
+ replay.Format(_L(" replay %d"), (TInt)iExt->sadb_sa_replay);
+ }
+ Log::Printf(_L("%Sspi %d%S%S %S(%d) %S(%d)%S%S%S%S%S"),
+ &aLabel,
+ (TInt)ByteOrder::Swap32(iExt->sadb_sa_spi), // kinky definition in PFKEYv2 (network order used)
+ &replay,
+ &LogAssociationState(iExt->sadb_sa_state),
+ &LogAuthAlg(iExt->sadb_sa_auth, aAlgorithms), iExt->sadb_sa_auth,
+ &LogEncrAlg(iExt->sadb_sa_encrypt, aAlgorithms), iExt->sadb_sa_encrypt,
+ &LogTest(flags & SADB_SAFLAGS_PFS, Kpfs),
+ &LogTest(flags & SADB_SAFLAGS_TUNNEL, Ktunnel),
+ &LogTest(flags & SADB_SAFLAGS_NAT_T, Knatt),
+ &LogTest(flags & SADB_SAFLAGS_INT_ADDR, Kaddr),
+ &LogTest(flags & SABD_SAFLAGS_ESN, Kesn));
+ }
+ }
+
+void TPfkeyLifetime::LogPrint(const TDesC &aLabel) const
+ {
+ if (iExt)
+ {
+ TBuf<200> buf;
+ if (iExt->sadb_lifetime_allocations)
+ buf.AppendFormat(_L("%S_allocations %d"), &aLabel, (TInt)iExt->sadb_lifetime_allocations);
+ if (iExt->sadb_lifetime_bytes)
+ buf.AppendFormat(_L("%S_bytes %d"), &aLabel, (TInt)iExt->sadb_lifetime_bytes);
+ if (iExt->sadb_lifetime_addtime)
+ buf.AppendFormat(_L("%S_addtime %d"), &aLabel, (TInt)iExt->sadb_lifetime_addtime);
+ if (iExt->sadb_lifetime_usetime)
+ buf.AppendFormat(_L("%S_usetime %d"), &aLabel, (TInt)iExt->sadb_lifetime_usetime);
+ if (buf.Length())
+ Log::Printf(_L("%S"), &buf);
+ }
+ }
+
+void TPfkeyKey::LogPrint(const TDesC &aLabel) const
+ {
+ if (iExt)
+ {
+ Log::Printf(_L("%S bitlength %d"),
+ &aLabel,
+ (TInt)iExt->sadb_key_bits);
+ }
+ }
+
+void TPfkeyAddress::LogPrint(const TDesC &aLabel) const
+ {
+ if (iExt)
+ {
+ TBuf<70> tmp;
+ TBuf<100> name;
+ name.Copy(iAddr.Name());
+ TInetAddr addr(iAddr(), iPort);
+ addr.SetScope(iAddr().iScope);
+ addr.OutputWithScope(tmp);
+ Log::Printf(_L("%S %S#%d %S"),
+ &aLabel,
+ &tmp,
+ (TInt)iPort,
+ &name
+ );
+ }
+ }
+
+void TPfkeyIdentity::LogPrint(const TDesC8 &aLabel) const
+ {
+ if (iExt)
+ {
+ Log::Printf(_L8("%S %S %S"),
+ &aLabel,
+ &LogIdentityType(iExt->sadb_ident_type),
+ &iData);
+ }
+ }
+
+void TPfkeySensitivity::LogPrint(const TDesC &aLabel) const
+ {
+ if (iExt)
+ {
+ Log::Printf(_L("%S"),
+ &aLabel);
+ }
+ }
+
+void TPfkeyProposal::LogPrint(const TDesC &aLabel, const CAlgorithmList *aAlgorithms) const
+ {
+ if (iComb)
+ {
+ for (TInt i = 0; i < iNumComb; ++i)
+ {
+ TBuf<200> buf;
+ if (iComb[i].sadb_comb_auth)
+ {
+ buf.AppendFormat(_L(" auth min %d max %d"),
+ (TInt)iComb[i].sadb_comb_auth_minbits,
+ (TInt)iComb[i].sadb_comb_auth_maxbits);
+ }
+ if (iComb[i].sadb_comb_encrypt)
+ {
+ buf.AppendFormat(_L(" encr min %d max %d"),
+ (TInt)iComb[i].sadb_comb_encrypt_minbits,
+ (TInt)iComb[i].sadb_comb_encrypt_maxbits);
+ }
+ LogTestAppend(buf, _L(" soft_allocations"), iComb[i].sadb_comb_soft_allocations);
+ LogTestAppend(buf, _L(" hard_allocations"), iComb[i].sadb_comb_hard_allocations);
+ LogTestAppend(buf, _L(" soft_bytes"), iComb[i].sadb_comb_soft_bytes);
+ LogTestAppend(buf, _L(" hard_bytes"), iComb[i].sadb_comb_hard_bytes);
+ LogTestAppend(buf, _L(" soft_addtime"), iComb[i].sadb_comb_soft_addtime);
+ LogTestAppend(buf, _L(" hard_addtime"), iComb[i].sadb_comb_hard_addtime);
+ LogTestAppend(buf, _L(" soft_usetime"), iComb[i].sadb_comb_soft_usetime);
+ LogTestAppend(buf, _L(" hard_usetime"), iComb[i].sadb_comb_hard_usetime);
+
+ Log::Printf(_L("%S[%d] %S(%d) %S(%d)%S"),
+ &aLabel, i,
+ &LogAuthAlg(iComb[i].sadb_comb_auth, aAlgorithms), iComb[i].sadb_comb_auth,
+ &LogEncrAlg(iComb[i].sadb_comb_encrypt, aAlgorithms), iComb[i].sadb_comb_encrypt,
+ &buf
+ );
+ }
+ }
+ }
+
+void TPfkeySupported::LogPrint(const TDesC &aLabel, const CAlgorithmList *aAlgorithms) const
+ {
+ if (iAlg)
+ {
+ const TBool auth = iExt->sadb_supported_exttype == SADB_EXT_SUPPORTED_AUTH;
+ for (TInt i = 0; i < iNumAlg; ++i)
+ {
+ Log::Printf(_L("%S %S(%d) ivlen %d minbits %d maxbits %d"),
+ &aLabel,
+ auth ? &LogAuthAlg(iAlg[i].sadb_alg_id, aAlgorithms) : &LogEncrAlg(iAlg[i].sadb_alg_id, aAlgorithms),
+ iAlg[i].sadb_alg_id,
+ iAlg[i].sadb_alg_ivlen,
+ iAlg[i].sadb_alg_minbits,
+ iAlg[i].sadb_alg_maxbits);
+ }
+ }
+ }
+
+void TPfkeySpirange::LogPrint(const TDesC &aLabel) const
+ {
+ if (iExt)
+ {
+ Log::Printf(_L("%S min %d max %d"),
+ &aLabel,
+ (TInt)iExt->sadb_spirange_min,
+ (TInt)iExt->sadb_spirange_max);
+ }
+ }
+
+void TPfkeyTs::LogPrint(const TDesC &aLabel) const
+ {
+ if (iExt && iTS)
+ {
+ for (TInt i = 0; i < iTS->Count(); ++i)
+ {
+ TInetAddr addr;
+ TBuf<50> src;
+ TBuf<50> dst;
+ const RTrafficSelector &ts = (*iTS)[i];
+ addr.SetAddress(ts.iSrc());
+ addr.SetScope(ts.iSrc().iScope);
+ addr.OutputWithScope(src);
+ addr.SetAddress(ts.iDst());
+ addr.SetScope(ts.iDst().iScope);
+ addr.OutputWithScope(dst);
+ Log::Printf(_L("%S[%d] proto=%d src=%S#%d dst=%S#%d"),
+ &aLabel, i,
+ (TInt)ts.iProtocol,
+ &src, (TInt)ts.iPortSrc,
+ &dst, (TInt)ts.iPortDst);
+ }
+ }
+ }
+#endif