// Copyright (c) 2004-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:
// DHCPv4 Message wrapper header file
//
//
/**
@file DHCPMsg.h
*/
#ifndef __DHCPIP4MSG_H__
#define __DHCPIP4MSG_H__
#include <babitflags.h>
#include "DHCPMsg.h"
#include "DomainNameDecoder.h"
class TInetAddr;
class RSocket;
class TSockAddr;
namespace DHCPv4
{
const TUint8 KHwAddrTypeOffset = 1;
const TUint8 KHwAddrLengthOffset = 2;
const TUint8 KHopOffset = 3;
const TUint8 KLengthUptoSecs = 8;
const TUint8 KSecsElapsedLength = 2;
const TUint8 KDhcpSipEncodingOffset = 2;
const TUint8 KDhcpSipLengthOffset = 1;
const TUint8 KDhcpSipEncodingDomains = 0;
const TUint8 KDhcpSipEncodingAddresses = 1;
enum TDHCPv4MessageOpCode
/**
* TDHCPv4MessageOpCode
*
* The message op code constants for
* DHCPv4 messages. A message is either
* a request of reply. DHCP clients always
* send requests to DHCP servers that always
* send replies.
*
* @internalTechnology
*/
{
EDHCPBootRequest = 1,
EDHCPBootReply
};
enum TDHCPv4MessageType
/**
* TDHCPv4MessageType
*
* The message type constants for the DHCPv4
* message type option for inclusion in DHCPv4
* messages.
*
* @internalTechnology
*/
{
EDHCPDiscover = 0x01, // request
EDHCPOffer, // reply
EDHCPRequest, // request
EDHCPDecline, // request
EDHCPAck, // reply
EDHCPNak, // reply
EDHCPReleaseMsg, // request
EDHCPInform // request
};
enum TDHCPOptionCodes
/**
* TDHCPOptionCodes
*
* The constant values for each supported
* option type.
*
* @internalTechnology
*/
{
EDHCPPad = 0,
EDHCPSubnetMask = 1,
EDHCPRouter = 3,
#ifdef SYMBIAN_NETWORKING_DHCPSERVER
EDHCPNameServer = 5,
#endif // SYMBIAN_NETWORKING_DHCPSERVER
EDHCPDomainNameServer = 6,
EDHCPHostName = 12,
EDHCPDomainName = 15,
EDHCPBroadcastAddr = 28,
EDHCPRequestedIPAddr = 50,
EDHCPLeaseTime = 51,
EDHCPMessageType = 53,
EDHCPServerID = 54,
EDHCPParameterReqList = 55,
EDHCPMaxMsgSize = 57,
EDHCPRenewalT1 = 58,
EDHCPRebindT2 = 59,
EDHCPClientID = 61,
EDHCPDNSUpdate = 81,
EDHCPAuthentication = 90,
EDHCPSIPServers = 120,
#ifdef SYMBIAN_NETWORKING_DHCP_MSG_HEADERS
EDHCPOptionOverload = 52,
EDHCPTftpServerName = 66,
EDHCPTftpServers = 150,
#endif//SYMBIAN_NETWORKING_DHCP_MSG_HEADERS
EDHCPEnd = 255
};
#ifdef SYMBIAN_NETWORKING_DHCP_MSG_HEADERS
enum TDHCPOverloadOptions
{
EDHCPFile = 1,
EDHCPSname = 2,
EDHCPBoth = 3
};
#endif//SYMBIAN_NETWORKING_DHCP_MSG_HEADERS
template <typename LAYOUT>
class TOptionHeader : public TValue< LAYOUT >
{
public:
TOptionHeader(TInt aValueLength) :
TValue<LAYOUT>(aValueLength)
{
};
TInt GetValue(const TUint8* aPtr8) const;
void SetValue(TUint8* aPtr8, TInt aValue) const;
};
template <typename LAYOUT>
TInt TOptionHeader<LAYOUT>::GetValue(const TUint8* aPtr8) const
{
ASSERT(this->iValueLength <= 2);
return this->iValueLength == 2 ? LAYOUT::GetValue(aPtr8 + 1, this->iValueLength - 1) : 0;
}
template <typename LAYOUT>
void TOptionHeader<LAYOUT>::SetValue(TUint8* aPtr8, TInt aValue) const
{
ASSERT(this->iValueLength <= 2);
if (this->iValueLength == 2)
{
LAYOUT::SetValue(aPtr8 + 1, this->iValueLength - 1, aValue);
}
}
class COption : public CItem<TOptionHeader<TLittleEndian> >
{
public:
COption(CItemBase* aNext, TInt aValue) :
CItem<TOptionHeader<TLittleEndian> >(aNext, aValue)
{
}
};
// lengths of headers for different option codes
const TInt KEDHCPPadLength = 1;
const TInt KOptionHeaderLength = 2;
//we may want to have an derived class for options needing special attention
//(permitted value cheking)
class COptionNode : public COption
/**
* we may want to have a derived class for options needing special attention
* (permitted value cheking)
*
* @internalTechnology
*/
{
friend class COptionList;
public:
TUint8 OpCode() const
{
return iPtr8[0];
}
void SetOpCode(TUint8 aOpCode)
{
iPtr8[0] = aOpCode; //should panic if not long enough
}
#ifdef __FLOG_ACTIVE
virtual void Dump(const TDesC& aTag, const TDesC& aFile);
#endif
protected:
COptionNode(TInt aHeaderLength);
virtual ~COptionNode();
};
inline COptionNode::COptionNode(TInt aHeaderLength) :
COption(NULL, aHeaderLength)
{
}
/******DHCP extension template []->optional - the code dependent******
Code [Len] [Octets]
+-----+-----+-----+-----+-----+---
|Code | n | o0 | o1 | o2 | ...
+-----+-----+-----+-----+-----+---
*********************************************************************/
class COptionList : public CListItem
{
public:
COptionList(CItemBase* aNext);
COptionNode* AddNodeL(TInt aInitialLength, TInt aHeaderLength);
COptionNode* FindOption(TUint8 aOpCode) const;
virtual void ParseL(TPtr8& aDes8);
TInt NumberOfItemsInAddressListOption(TUint8 aOpCode) const;
TUint32 GetAddressFromAddressListOption(TUint8 aOpCode,TInt aPos) const;
TUint32 GetSubnetMask() const;
TUint32 GetRouterAddress() const;
TInt NumberOfDomainServers() const;
TUint32 GetDomainNameServer(TInt aPos) const;
TUint32 GetBroadcastAddress() const;
TUint32 GetLeaseTime() const;
TUint8 GetMessageType() const;
TUint32 GetServerId() const;
TUint32 GetRenewalTime() const;
TUint32 GetRebindTime() const;
TInt CopyHostNameL(HBufC8*& aBuf8) const;
TInt CopyDomainNameL(HBufC8*& aBuf8) const;
#ifdef SYMBIAN_NETWORKING_DHCPSERVER
TUint32 GetRequestedIPAddress() const;
#endif // SYMBIAN_NETWORKING_DHCPSERVER
#ifdef SYMBIAN_NETWORKING_DHCP_MSG_HEADERS
TUint8 GetOptionOverload() const;
#endif // SYMBIAN_NETWORKING_DHCP_MSG_HEADERS
protected:
TUint32 GetValueBigEndian(TUint8 aOpCode) const;
};
inline COptionList::COptionList(CItemBase* aNext) : CListItem(aNext, 0)
{
}
inline TUint32 COptionList::GetSubnetMask() const
{
return GetValueBigEndian(EDHCPSubnetMask);
}
inline TUint32 COptionList::GetRouterAddress() const
{
// Only look at the first item, because tcpip6 only supports 1 router
// Subsequent addresses shall be ignored.
return GetAddressFromAddressListOption(EDHCPRouter,0);
}
inline TUint32 COptionList::GetBroadcastAddress() const
{
return GetValueBigEndian(EDHCPBroadcastAddr);
}
inline TUint32 COptionList::GetLeaseTime() const
{
return GetValueBigEndian(EDHCPLeaseTime);
}
inline TUint8 COptionList::GetMessageType() const
{
return (TUint8)GetValueBigEndian(EDHCPMessageType);
}
inline TUint32 COptionList::GetServerId() const
{
return GetValueBigEndian(EDHCPServerID);
}
inline TUint32 COptionList::GetRenewalTime() const
{
return GetValueBigEndian(EDHCPRenewalT1);
}
inline TUint32 COptionList::GetRebindTime() const
{
return GetValueBigEndian(EDHCPRebindT2);
}
#ifdef SYMBIAN_NETWORKING_DHCPSERVER
inline TUint32 COptionList::GetRequestedIPAddress() const
{
return GetValueBigEndian(EDHCPRequestedIPAddr);
}
#endif // SYMBIAN_NETWORKING_DHCPSERVER
#ifdef SYMBIAN_NETWORKING_DHCP_MSG_HEADERS
inline TUint8 COptionList::GetOptionOverload() const
{
return (TUint8)GetValueBigEndian(EDHCPOptionOverload);
}
#endif //SYMBIAN_NETWORKING_DHCP_MSG_HEADERS
/**********************DHCP message header****************************
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| op (1) | htype (1) | hlen (1) | hops (1) |
+---------------+---------------+---------------+---------------+
| xid (4) |
+-------------------------------+-------------------------------+
| secs (2) | flags (2) |
+-------------------------------+-------------------------------+
| ciaddr (4) |
+---------------------------------------------------------------+
| yiaddr (4) |
+---------------------------------------------------------------+
| siaddr (4) |
+---------------------------------------------------------------+
| giaddr (4) |
+---------------------------------------------------------------+
| |
| chaddr (16) |
| |
| |
+---------------------------------------------------------------+
| |
| sname (64) |
+---------------------------------------------------------------+
| |
| file (128) |
+---------------------------------------------------------------+
| cookie (4) |
+---------------------------------------------------------------+
| |
| options (variable) |
+---------------------------------------------------------------+
**********************************************************************/
class CDHCPMessageHeaderIP4 : public CDHCPMessageHeader
/**
* This class implements the specifics for the DHCPv4 messages
*/
{
public:
CDHCPMessageHeaderIP4(HBufC8*& aMsg);
~CDHCPMessageHeaderIP4();
public:
#ifdef SYMBIAN_NETWORKING_DHCP_MSG_HEADERS
TUint32 GetSIAddr() const;//IP Address of the Next Server
TPtr8 GetSName() const; //Hostname of next available server
void FinishL(TDesC8& aClientId, const TDesC8* aOptionsPtr=NULL);
#else // SYMBIAN_NETWORKING_DHCP_MSG_HEADERS
void FinishL(TDesC8& aClientId);
#endif
void ParseL();
#ifdef SYMBIAN_NETWORKING_DHCPSERVER
void ParseClientMsgL();
void SetYIAddr(TUint32 aYiaddr); // Offered Client address
void GetCHAddr(TSockAddr& aSockAddr);
#ifdef SYMBIAN_NETWORKING_ADDRESS_PROVISION
void GetClientHwAddr(TSockAddr& aSockAddr);
#endif //SYMBIAN_NETWORKING_ADDRESS_PROVISION
TUint16 GetFlags();
#endif // SYMBIAN_NETWORKING_DHCPSERVER
COptionNode* AddOptionL(TDHCPOptionCodes aOpCode, TInt nLength);
virtual void RemoveAllOptions();
void SetHeader(TUint8 aOpCode, TUint8 aType, TUint8 aLength, TUint8 aHops);
void SetXid(TUint32 aXid); // Transaction ID
void SetSecs(TUint16 aSecs); // Seconds elapsed since clien began address aquisition
void SetFlags(TUint16 aFlag);
void SetCIAddr(TUint32 aAddr); // If IP Address
void SetCHAddr(TSockAddr& aAddr); // If Hardware Address
TUint8 GetOpCode() const;
TUint32 GetXid() const; // Transaction ID
TUint32 GetCIAddr() const; // If IP Address
TUint32 GetYIAddr() const; // "your" (If) IP address
void Close() //so as it could be put on the stack and on the cleanup stack
{
iOptions.RemoveAllNodes();
}
public:
CConstItem iXid;
CConstItem iSecs;
CConstItem iFlags;
CConstItem iCiaddr;
CConstItem iYiaddr;
CConstItem iSiaddr;
CConstItem iGiaddr;
CConstItem iChaddr;
CConstItem iSname;
CConstItem iFile;
CConstItem iCookie;
COptionList iOptions;
#ifdef SYMBIAN_NETWORKING_DHCPSERVER
TBool iDHCPServerImpl;
#endif // SYMBIAN_NETWORKING_DHCPSERVER
};
inline void CDHCPMessageHeaderIP4::RemoveAllOptions()
{
iOptions.RemoveAllNodes();
}
inline TUint8 CDHCPMessageHeaderIP4::GetOpCode() const
/**
* Retrieve Op code from message
*
* @internalTechnology
*
*/
{
return GetBodyPtr()[0];
}
inline void CDHCPMessageHeaderIP4::SetCIAddr(TUint32 aAddr)
/**
* Set If IP Address in message
*
* @internalTechnology
*
*/
{
iCiaddr.SetBigEndian(aAddr);
}
inline void CDHCPMessageHeaderIP4::SetXid(TUint32 aXid)
/**
* Set Transaction ID in message
*
* @internalTechnology
*
*/
{
iXid.SetLittleEndian(aXid);
}
#ifdef SYMBIAN_NETWORKING_DHCPSERVER
inline void CDHCPMessageHeaderIP4::SetYIAddr(TUint32 aYiaddr)
/**
* Set Transaction ID in message
*
* @internalTechnology
*
*/
{
iYiaddr.SetBigEndian(aYiaddr);
}
inline TUint32 CDHCPMessageHeaderIP4::GetCIAddr() const
/**
* Retrieve Client IP Address from message
*
* @internalTechnology
*
*/
{
return iCiaddr.GetBigEndian();
}
inline TUint16 CDHCPMessageHeaderIP4::GetFlags()
/**
* Set flags in message
*
* @internalTechnology
*
*/
{
return iFlags.GetBigEndian();
}
#endif // SYMBIAN_NETWORKING_DHCPSERVER
inline void CDHCPMessageHeaderIP4::SetSecs(TUint16 aSecs)
/**
* SSet Number of seconds since commencement of configuration process in message
*
* @internalTechnology
*
*/
{
iSecs.SetBigEndian(aSecs);
}
inline void CDHCPMessageHeaderIP4::SetFlags(TUint16 aFlag)
/**
* Set flags in message
*
* @internalTechnology
*
*/
{
iFlags.SetBigEndian(aFlag);
}
inline TUint32 CDHCPMessageHeaderIP4::GetXid() const
/**
* Retrieve Transaction ID from message
*
* @internalTechnology
*
*/
{
return iXid.GetLittleEndian();
}
inline TUint32 CDHCPMessageHeaderIP4::GetYIAddr() const
/**
* Retrieve Your IP Address from message
*
* @internalTechnology
*
*/
{
return iYiaddr.GetBigEndian();
}
#ifdef SYMBIAN_NETWORKING_DHCP_MSG_HEADERS
inline TUint32 CDHCPMessageHeaderIP4::GetSIAddr() const
/**
* Get next server IP Address in message
*
* @internalTechnology
*
*/
{
return iSiaddr.GetBigEndian();
}
inline TPtr8 CDHCPMessageHeaderIP4::GetSName() const
/**
* Get next server hostname in message
*
* @internalTechnology
*
*/
{
return iSname.GetBodyDes();
}
#endif //SYMBIAN_NETWORKING_DHCP_MSG_HEADERS
const TUint8 KDnsUpdateRCode1Offset = 0x01;
const TUint8 KDnsUpdateRCode2Offset = 0x02;
class CDnsUpdateOption : public COptionNode
{
public:
enum TDnsUpdateFlag
{
EDnsUpdateFlagN = 0x03,
EDnsUpdateFlagE = 0x02,
EDnsUpdateFlagO = 0x01,
EDnsUpdateFlagS = 0x00
};
public:
CDnsUpdateOption() : COptionNode(KOptionHeaderLength)
{
};
virtual ~CDnsUpdateOption()
{
};
TBool GetFlag(const TDnsUpdateFlag aFlag) const;
void SetFlag(const TDnsUpdateFlag aFlag);
void ClearFlag(const TDnsUpdateFlag aFlag);
TUint8 GetRCode1();
TUint8 GetRCode2();
const TDomainName& GetDomainName() const;
void SetDomainName(const TDomainName& aDomainName);
void ToStringL(RBuf8& aString) const;
private:
TBitFlags8 iFlags;
TInt8 iRCode1;
TInt8 iRCode2;
TDomainName iDomainName;
};
inline TBool CDnsUpdateOption::GetFlag(const TDnsUpdateFlag aFlag) const
{
return iFlags.IsSet(aFlag);
}
inline void CDnsUpdateOption::SetFlag(const TDnsUpdateFlag aFlag)
{
iFlags.Set(aFlag);
}
inline void CDnsUpdateOption::ClearFlag(const TDnsUpdateFlag aFlag)
{
iFlags.Clear(aFlag);
}
inline TUint8 CDnsUpdateOption::GetRCode1()
{
return iRCode1;
}
inline TUint8 CDnsUpdateOption::GetRCode2()
{
return iRCode2;
}
inline const TDomainName& CDnsUpdateOption::GetDomainName() const
{
return iDomainName;
}
inline void CDnsUpdateOption::SetDomainName(const TDomainName& aDomainName)
{
iDomainName.Copy(aDomainName);
}
}//namespace DHCPv4
#endif