Committing ZeroConf for 10.1 to the FCL.
/*
* Copyright (c) 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:
*
*/
#include "cdnspacket.h"
CDnsPacket::CDnsPacket(const TDes8& aPacketPtr): iPtr(aPacketPtr.Ptr()),iDataLength(aPacketPtr.Size()),
iMaxLength(aPacketPtr.MaxSize())
{
}
CDnsPacket* CDnsPacket::NewL(const TDes8& aPacketPtr)
{
CDnsPacket* self = new (ELeave) CDnsPacket( aPacketPtr );
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(self);
return self;
}
CDnsPacket::~CDnsPacket()
{
}
void CDnsPacket::ConstructL()
{
iIndex = 0;
}
TUint8 CDnsPacket::GetCharL()
{
__OOB(iIndex,iDataLength)
TUint8 val = *(iPtr+iIndex);
iIndex += sizeof(TUint8);
return val;
}
TUint16 CDnsPacket::GetInt16L()
{
__OOB(iIndex,iDataLength)
TUint16 val = BigEndian::Get16(iPtr+iIndex);
iIndex += sizeof(TUint16);
return val;
}
TUint32 CDnsPacket::GetInt32L()
{
__OOB(iIndex,iDataLength)
TUint32 val = BigEndian::Get32(iPtr+iIndex);
iIndex += sizeof(TUint32);
return val;
}
const TDnsHeader& CDnsPacket::GetHeaderL()
{
iHeader.SetId(GetInt16L());
iHeader.SetFlags(GetInt16L());
iHeader.SetQueryCount(GetInt16L());
iHeader.SetAnswerCount(GetInt16L());
iHeader.SetAuthorityNSCount(GetInt16L());
iHeader.SetAdditionalRCount(GetInt16L());
return iHeader;
}
void CDnsPacket::GetDomainNameL(TDes8& aName)
{
TInt labelLen = GetCharL();
RBuf8 label;
TInt isStartingWithPointer = labelLen & KPointerBit;
if(isStartingWithPointer)
{
TUint16 pointerOffset = labelLen & KPointerOffsetBit;
__OOB(pointerOffset,iDataLength)
pointerOffset = (pointerOffset << 8) + GetCharL();
GetDomainNameAtIndexL(aName, pointerOffset);
}
else
{
while(labelLen)
{
TInt isPointer = labelLen & KPointerBit;
if(isPointer)
{
TUint16 pointerOffset = labelLen & KPointerOffsetBit;
__OOB(pointerOffset,iDataLength)
pointerOffset = (pointerOffset << 8) + GetCharL();
label.CreateL(KMaxDNSNameLength);
GetStringAtIndexL(label,pointerOffset);
}
else
{
label.CreateL(labelLen);
GetStringL(label,labelLen);
}
aName.Append(label);
if(aName[aName.Size()-1]!='.')
aName.Append(KDot);
label.Close();
if(isPointer )
{
break;
}
else
{
labelLen = GetCharL();
}
}
}
}
void CDnsPacket::GetRdDomainNameL(TDes8& aDomainName,TUint aLength)
{
TInt labelLen = GetCharL();
aLength--;
RBuf8 label;
TInt isStartingWithPointer = labelLen & KPointerBit;
while(aLength)
{
TInt isPointer = labelLen & KPointerBit;
if(isPointer)
{
TUint16 pointerOffset = labelLen & KPointerOffsetBit;
__OOB(pointerOffset,iDataLength)
pointerOffset = (pointerOffset << 8) + GetCharL();
aLength--;
label.CreateL(KMaxLabelLength);
if(isStartingWithPointer )
{
GetDomainNameAtIndexL(aDomainName, pointerOffset);
}
else
{
GetDomainNameAtIndexL(label, pointerOffset);
//GetStringAtIndexL(label, pointerOffset);
}
}
else
{
label.CreateL(labelLen);
GetStringL(label,labelLen);
aLength-=labelLen;
}
aDomainName.Append(label);
label.Close();
if(isStartingWithPointer)
{
break;
}
else
{
if(aLength )
{
labelLen = GetCharL();
aLength--;
if(aDomainName[aDomainName.Size()-1]!='.')
aDomainName.Append(KDot);
}
}
}
}
void CDnsPacket::GetStringL(TDes8& aString, TUint16 aLength)
{
__OOB(iIndex,iDataLength)
aString.Copy(iPtr+iIndex,aLength);
iIndex+= aLength;
}
void CDnsPacket::GetDomainNameAtIndexL(TDes8& aDomainName, TUint aOffset)
{
__OOB(aOffset,iDataLength)
TUint8 labelLen = *(iPtr + aOffset);
RBuf8 label;
TInt isPointer;
TUint16 pointerOffset;
TInt isStartingWithPointer = labelLen & KPointerBit;
TUint8 ptrPos;
if(isStartingWithPointer)
{
pointerOffset = labelLen & KPointerOffsetBit;
__OOB(aOffset,iDataLength)
aOffset++;
ptrPos = *(iPtr + aOffset);
pointerOffset = (pointerOffset << 8) + ptrPos;
GetDomainNameAtIndexL(aDomainName, pointerOffset);
}
else
{
while(labelLen)
{
label.CreateL(KMaxLabelLength);
GetStringAtIndexL(label, aOffset);
aDomainName.Append(label);
if(aDomainName[aDomainName.Size()-1]!='.')
aDomainName.Append(KDot);
__OOB(aOffset,iDataLength)
aOffset++; // increment by one byte for length field
aOffset += labelLen;
label.Close();
labelLen = *(iPtr + aOffset);
isPointer = labelLen & KPointerBit;
if(isPointer)
{
pointerOffset = labelLen & KPointerOffsetBit;
__OOB(aOffset,iDataLength)
aOffset++;
ptrPos = *(iPtr + aOffset);
pointerOffset = (pointerOffset << 8) + ptrPos;
label.CreateL(KMaxLabelLength);
GetStringAtIndexL(label, pointerOffset);
aDomainName.Append(label);
if(aDomainName[aDomainName.Size()-1]!='.')
aDomainName.Append(KDot);
label.Close();
break;
}
}
}
}
void CDnsPacket::GetStringAtIndexL(TDes8& aLabel, TUint aOffset)
{
__OOB(aOffset,iDataLength)
TUint8 labelLen = *(iPtr + aOffset);
if(labelLen & KPointerBit) // recursive pointers
{
TUint16 pointerOffset = labelLen & KPointerOffsetBit;
pointerOffset = (pointerOffset << 8) + GetCharL();
GetStringAtIndexL(aLabel, pointerOffset);
}
else
{
aLabel.Copy(iPtr+aOffset+1, labelLen);
}
}