epoc32/include/in_pkt.h
branchSymbian2
changeset 2 2fe1408b6811
child 4 837f303aceeb
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/epoc32/include/in_pkt.h	Tue Mar 16 16:12:26 2010 +0000
     1.3 @@ -0,0 +1,713 @@
     1.4 +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of the License "Symbian Foundation License v1.0" to Symbian Foundation members and "Symbian Foundation End User License Agreement v1.0" to non-members
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.symbianfoundation.org/legal/licencesv10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +// in_pkt.h - packet handling routines
    1.18 +// Generic packet handling utility for mapping packet handling to the RMBufChain.
    1.19 +//
    1.20 +
    1.21 +
    1.22 +
    1.23 +/**
    1.24 + @file in_pkt.h
    1.25 + @publishedAll
    1.26 + @released
    1.27 +*/
    1.28 +
    1.29 +#ifndef __IN_PKT_H__
    1.30 +#define __IN_PKT_H__
    1.31 +
    1.32 +#include <nifmbuf.h>
    1.33 +#include "ip6_hdr.h"	// ..should eventually be <inet/ip6_hdr.h>? -- msa
    1.34 +#include "ip4_hdr.h"
    1.35 +
    1.36 +#define TPACKETHEAD_FRAGMENT	1	///< Enable iFragment in TPacketHead
    1.37 +
    1.38 +/**
    1.39 + TScopeType is only provided so that "magic" constants can be
    1.40 + avoided in the source code. However, the max value cannot be changed
    1.41 + to anything from 0xF. The scope type is assumed to be 4 bits long
    1.42 + in many occasions.
    1.43 +
    1.44 + The value of the scope type is directly bound the the IPv6 Scope
    1.45 + level - 1. This can be done, as IPv6 Scope level 0 is not legal
    1.46 + (or usable) in any context within the stack.
    1.47 + This allows our non-standard network scope (= 0x10) to
    1.48 + be coded internally in 4 bits (as 0xF).
    1.49 +
    1.50 + @publishedAll
    1.51 + @released
    1.52 + @since v7.0s
    1.53 +*/
    1.54 +enum TScopeType
    1.55 +	{
    1.56 +	EScopeType_IF	= 0x0,	///< (= #KIp6AddrScopeNodeLocal - 1), id is interface index
    1.57 +	EScopeType_IAP	= 0x1,	///< (= #KIp6AddrScopeLinkLocal - 1). id is IAP number
    1.58 +	EScopeType_GLOBAL = 0xD,///< (= #KIp6AddrScopeGlobal - 1). id is global scope id
    1.59 +	//
    1.60 +	// no symbols defined for types 2..14 (they are also valid)
    1.61 +	//
    1.62 +	EScopeType_NET	= 0xF	///< (= #KIp6AddrScopeNetwork - 1), id is network number (must be the last entry)
    1.63 +	};
    1.64 +
    1.65 +//
    1.66 +//	TIpHeader
    1.67 +//	*********
    1.68 +class TIpHeader
    1.69 +	/**
    1.70 +	A simple help class that uses a union to merge handling of either an IPv4 or 
    1.71 +	an IPv6 header. 
    1.72 +	@since v7.0
    1.73 +	@publishedAll
    1.74 +	@released
    1.75 +	*/
    1.76 +	{
    1.77 +public:
    1.78 +	/**
    1.79 +	Gets the minimum header length.
    1.80 +
    1.81 +	IPv6 header is longer than minimum IPv4 header, thus
    1.82 +	returned value is for IPv4. This function only defined
    1.83 +	because it is required when this class is used as template
    1.84 +	parameter in TInet6Packet.
    1.85 +	
    1.86 +	@return Minimum IPv4 header length
    1.87 +	*/
    1.88 +	inline static TInt MinHeaderLength() {return TInet6HeaderIP4::MinHeaderLength(); }
    1.89 +	/**
    1.90 +	Gets the maximum header length.
    1.91 +
    1.92 +	IPv6 header always shorter than maximum IPv4 header, thus
    1.93 +	returned value is for IPv4. This function is only defined
    1.94 +	because "header mapping" classes are expected to have it.
    1.95 +	
    1.96 +	@return Maximum IPv4 header length
    1.97 +	*/
    1.98 +	inline static TInt MaxHeaderLength() {return TInet6HeaderIP4::MaxHeaderLength(); }
    1.99 +
   1.100 +	union
   1.101 +		{
   1.102 +		TInet6HeaderIP4 ip4;
   1.103 +		TInet6HeaderIP ip6;
   1.104 +		};
   1.105 +	};
   1.106 +
   1.107 +
   1.108 +//	RMBufPacketPeek
   1.109 +//	***************
   1.110 +class RMBufPacketPeek : public RMBufChain
   1.111 +	/**
   1.112 +	Extends RMBufChain to add functions to read packet data as a descriptor 
   1.113 +	and as an IP header.
   1.114 +
   1.115 +	The RMBufChain is assumed to contain the raw packet, without
   1.116 +	the info block prepended (e.g. if this class is used for RMBufPacketBase
   1.117 +	derived handle, it must be in "unpacked" state).
   1.118 +	
   1.119 +	@since v7.0
   1.120 +	@publishedAll
   1.121 +	@released
   1.122 +	*/
   1.123 +	{
   1.124 +public:
   1.125 +	IMPORT_C TPtr8 Access(TInt aSize, TUint aOffset = 0);
   1.126 +	IMPORT_C TIpHeader *GetIpHeader();
   1.127 +	};
   1.128 +
   1.129 +//	TPacketHead
   1.130 +//	***********
   1.131 +class TPacketHead
   1.132 +	/**
   1.133 +	Storage for some precomputed information for an outbound packet flow.
   1.134 +
   1.135 +	The outbound TPacketHead is part of the flow context (CFlowContext).
   1.136 +
   1.137 +	The CFlowContext::Connect initializes the content from the parameters
   1.138 +	of the flow (TFlowInfo) and runs the connection process.. The connection
   1.139 +	process (MIp6Hook::OpenL and MFlowHook::ReadyL phases) completes the
   1.140 +	information. After this, as long as the flow is connected, the content
   1.141 +	is mostly frozen and <b>must not be modified by anyone</b>.
   1.142 + 
   1.143 +    When there is a need to change any flow information, the changes must
   1.144 +	be done to the flow parameters (and not to TPacketHead). The change of
   1.145 +	flow parameters also sets the CFlowContext::iChanged flag, and this
   1.146 +	eventually causes a new CFlowContext::Connect, which re-initializes
   1.147 +	the TPacketHead with the new information.
   1.148 +
   1.149 +	For each field in the TPacketHead, the hook writer must follow the
   1.150 +	basic rule (only for fields that it intends to change):
   1.151 +
   1.152 +	- if some field is changed in MIp6Hook::OpenL, then the previous
   1.153 +	value should be restored in the MFlowHook::ReadyL.
   1.154 +	- an exeception: the hook must omit the restore, if the
   1.155 +	previous value was unspecified value (for example, the source
   1.156 +	address).
   1.157 +	- the content of #iPacket (and #iOffset) are special: they cannot
   1.158 +	be modified in the MIp6Hook::OpenL phase. A hook can
   1.159 +	modify them only in the MFlowHook::ReadyL phase. And, if the hook
   1.160 +	is adding an IP header for tunneling, it must save the current content
   1.161 +	of these fields in the ReadyL function, and then clear out the fields
   1.162 +	(it must make the iPacket empty and zero iOffset). The hook must add
   1.163 +	the saved iPacket content below the added tunnel header in
   1.164 +	MFlowHook::ApplyL .
   1.165 +
   1.166 +	@since v7.0
   1.167 +	@publishedAll
   1.168 +	@released
   1.169 +	*/
   1.170 +	{
   1.171 +public:
   1.172 +	IMPORT_C TBool ExtHdrGet(TInt aType, TInt& aOfs, TInt& aLen);
   1.173 +	IMPORT_C TBool ExtHdrGetOrPrependL(TInt aType, TInt& aOfs, TInt& aLen);
   1.174 +	IMPORT_C TBool ExtHdrGetOrAppendL(TInt aType, TInt& aOfs, TInt& aLen);
   1.175 +	IMPORT_C void AddDestinationOptionL(const TPtrC8& aOption, TUint8 aAlign=0, TUint8 aModulo=4);
   1.176 +	IMPORT_C void AddDestinationOptionL(const TUint8* aOption, TUint8 aLen, TUint8 aAlign=0, TUint8 aModulo=4);
   1.177 +
   1.178 +public:
   1.179 +	/**
   1.180 +	"Virtual" IP header. The IPv6 header stucture is used, but the same
   1.181 +	format is <b>also</b> used for the IPv4 destinations (Version() == 4,
   1.182 +	even though the header format is still IPv6!)
   1.183 +	
   1.184 +	This header is initialized in the beginning of the OpenL phase
   1.185 +	as follows:
   1.186 +	@li	Version = 0
   1.187 +	@li	Traffic Class, copied from the flow iOptions.iTrafficClass
   1.188 +	@li	Flow Label = 0
   1.189 +	@li	Payload Length = 0 (dummy field, not used)
   1.190 +	@li	Next Header, copied from the flow iProtocol
   1.191 +	@li	Hop Limit, copied from the flow iOptions.iHopLimit
   1.192 +	@li	Src Address, copied from the flow Local Address (usually unspecified)
   1.193 +	@li	Dst Address, copied from the flow Remote Address
   1.194 +	
   1.195 +	At beginning of the ReadyL phase (= at end of OpenL), the destination
   1.196 +	address (and iDstId) are used to find a route on the interface. Depending
   1.197 +	on whether this address is IPv4 (mapped) or IPv6, the Version field is set
   1.198 +	accordingly to either 4 or 6.
   1.199 +
   1.200 +	After succesfull completion of the ReadyL, this used for *each* packet
   1.201 +	which needs an IP header to be generated on send. The Version() determines
   1.202 +	whether IPv4 or IPv6 frame is to be generated (this is the initial
   1.203 +	header in the packet, *before* running outbound ApplyL hooks):
   1.204 +	
   1.205 +	@verbatim
   1.206 +	                   IPv6            IPv4
   1.207 +	   Version         == 6            ==4
   1.208 +	   Traffic Class   used as is      used as TOS
   1.209 +	   Flow Label      used as is      ignored
   1.210 +	   Payload Length  ignored         ignored
   1.211 +	   Next Header     used as is      used as Protocol
   1.212 +	   Hop Limit       used as is      used as TTL
   1.213 +	   Src Address     used as is      used as IPv4 mapped
   1.214 +	   Dst Address     used as is      used as IPv4 mapped
   1.215 +	@endverbatim
   1.216 +	*/
   1.217 +	TInet6HeaderIP ip6;
   1.218 +	/**
   1.219 +	Contains the scope id associated with the destination address
   1.220 +	which is stored in #ip6 Dst Address. This id and address must
   1.221 +	always be considered as a unit. Logically, any change changes
   1.222 +	both values.
   1.223 +
   1.224 +	iDstId is initialized from the flow context TFlowInfo::iRemote.Scope() at
   1.225 +	beginning of the flow connect phase. If application does not define
   1.226 +	this scope id, then the system will attempt to choose a default value
   1.227 +	at beginning of the connect phase. If the default cannot be determined,
   1.228 +	the flow is put into pending state (and no connect happens).
   1.229 +
   1.230 +	@par MIp6Hook::OpenL
   1.231 +	On entry to the OpenL, the iDstId is always non-zero and destination
   1.232 +	address is specified. If a hook changes the destination address in
   1.233 +	OpenL method, it must provide the correct id value
   1.234 +	which goes with the new destination. If it cannot do this, it
   1.235 +	must either abort the connect by leaving with an error state, or it
   1.236 +	can leave with PENDING (> 0) status to signal there is no route
   1.237 +	for the new destination.
   1.238 +	If the stack cannot find suitable interface for the destination, then
   1.239 +	it aborts the connect phase, and the flow is placed into holding state.
   1.240 +
   1.241 +	@note
   1.242 +		Only a tunneling hook can safely change the destination
   1.243 +		address (a use of routing header can also be a kind of
   1.244 +		tunneling).
   1.245 +	
   1.246 +	@par MFlowHook::ReadyL
   1.247 +	If the hook changed the destination address (or id) in the OpenL,
   1.248 +	the ReadyL must restore the original values back.
   1.249 +
   1.250 +	*/
   1.251 +	TUint32 iDstId;
   1.252 +	/**
   1.253 +	Contains the scope id associated with the source address
   1.254 +	which is stored in #ip6 Src address. This is defined when the source
   1.255 +	address is defined, and otherwise undefined.
   1.256 +
   1.257 +	iSrcId is initialized from TFlowInfo::iLocal.Scope() at beginning of the
   1.258 +	flow connect phase. If application defines the source address,
   1.259 +	but does not specify this scope id, then the system chooses
   1.260 +	the id based on the interface defined by the source address.
   1.261 +	If scope and address are both specified, they must match the
   1.262 +	selected interface.
   1.263 +
   1.264 +	@par MIp6Hook::OpenL
   1.265 +	On entry to the OpenL, the iSrcId (and source address) may be
   1.266 +	undefined (#iSourceSet = 0). If defined (iSourceSet = 1), then
   1.267 +	both address and iSrcId are defined (iSrcId != 0). A hook may
   1.268 +	force a reselection of the source just by zeroing the
   1.269 +	iSourceSet.
   1.270 +
   1.271 +	@par MFlowHook::ReadyL
   1.272 +	If the hook changed the source address (or id) in the OpenL,
   1.273 +	the ReadyL must restore the original values back, but only
   1.274 +	if the original value was defined (#iSourceSet = 1 in OpenL).
   1.275 +	*/
   1.276 +	TUint32 iSrcId;
   1.277 +	/**
   1.278 +	The source address has been set.
   1.279 +
   1.280 +	This bit indicates whether the value stored in #ip6 src field
   1.281 +	and #iSrcId is to be used as a source address as is.
   1.282 +
   1.283 +	Initialized from TFlowInfo::iLocalSet, which tells whether user
   1.284 +	specified tbe source address or not (e.g used RSocket Bind method).
   1.285 +	The stack checks the value after each MIp6Hook::OpenL call, and
   1.286 +	if the flag is set, the source in ip6 is used as is. If the flag
   1.287 +	is zero, then the stack performs the normal source address selection
   1.288 +	based on the current destination address (#iSrcId and destination
   1.289 +	address).
   1.290 +
   1.291 +	@par MIp6Hook::OpenL
   1.292 +	On entry, this flag is always set and source address is defined.
   1.293 +	A hook may clear this flag, if it wants the
   1.294 +	stack choose the source address based on current destination.
   1.295 +	The clearing operation is normally needed only by a tunneling
   1.296 +	hook.
   1.297 +
   1.298 +	@note
   1.299 +		If the hook specifies the source address, it must be either
   1.300 +		a valid source address for the interface or unspecified
   1.301 +		address.
   1.302 +
   1.303 +	@par MFlowHook::ReadyL
   1.304 +	Upon entry to the ReadyL, the source address is always fully
   1.305 +	known (the hook can assume that #iSrcId and the #ip6 source
   1.306 +	addresses are valid).
   1.307 +	If the source address was set before the OpenL, then this
   1.308 +	must restore the original value (along with the #iSrcId
   1.309 +	and source address).
   1.310 +	*/
   1.311 +	TUint iSourceSet:1;
   1.312 +#ifdef TPACKETHEAD_FRAGMENT
   1.313 +	/**
   1.314 +	The fragment processing alredy done.
   1.315 +	
   1.316 +	This bit is meaningful only in OpenL phase. If already set,
   1.317 +	then some ealier hook has requested that the packet must
   1.318 +	be fragmented to fit the mtu.
   1.319 +	
   1.320 +	A tunneling hook can set this bit in OpenL, if it needs
   1.321 +	the fragmenting to happen before the ApplyL is called (e.g.
   1.322 +	the fragments are tunneled instead of fragmenting the
   1.323 +	tunneling).
   1.324 +	
   1.325 +	This bit can only be set or left as is. It cannot be cleared
   1.326 +	once set.
   1.327 +	*/
   1.328 +	TUint iFragment:1;
   1.329 +#endif
   1.330 +	/**
   1.331 +	Selector info, the upper layer protocol.
   1.332 +
   1.333 +	iProtocol has the same value as ip6.NextHeader() when iPacket is empty,
   1.334 +	and otherwise it is the same as NextHeader() of the last extension
   1.335 +	header in the iPacket.
   1.336 +
   1.337 +	The values of the other selector fields: #iIcmpType, #iIcmpCode
   1.338 +	#iSrcPort and #iDstPort depend on iProtocol. Whenever iProtocol
   1.339 +	is changed, the other fields must be updated accordingly.
   1.340 +
   1.341 +	@par MIp6Hook::OpenL
   1.342 +	Because iPacket cannot be modified during the OpenL phase, the
   1.343 +	content of this field and the Next Header (protocol) field in
   1.344 +	the #ip6 pseudoheader must always be the same. This field should
   1.345 +	be considered as <b>read-only</b>, unless the hook intends to
   1.346 +	apply IP-in-IP tunneling, in which case the hook <b>must</b>
   1.347 +	change the value to the appropriate tunneling protocol
   1.348 +	(#KProtocolInet6Ipip or #KProtocolInetIpip).
   1.349 +
   1.350 +    @par MFlowHook::ReadyL
   1.351 +	Only a tunneling hook needs to restore the value here to match
   1.352 +	the original upper layer protocol. See #iPacket for
   1.353 +	more detailed information.
   1.354 +	*/
   1.355 +	TUint8 iProtocol;
   1.356 +	/**
   1.357 +	Selector field whose value depends on #iProtocol. 
   1.358 + 
   1.359 +	If this field does not have meaning with the protocol,
   1.360 +	the field content should be set to ZERO.
   1.361 +	*/
   1.362 +	TUint8 iIcmpType;
   1.363 +	/**
   1.364 +	Selector field whose value depends on #iProtocol. 
   1.365 + 
   1.366 +	If this field does not have meaning with the protocol,
   1.367 +	the field content should be set to ZERO.
   1.368 +	*/
   1.369 +	TUint8 iIcmpCode;
   1.370 +	/**
   1.371 +	Selector field whose value depends on #iProtocol. 
   1.372 + 
   1.373 +	If this field does not have meaning with the protocol,
   1.374 +	the field content should be set to ZERO.
   1.375 +	*/
   1.376 +	TUint16 iSrcPort;
   1.377 +	/**
   1.378 +	Selector field whose value depends on #iProtocol. 
   1.379 + 
   1.380 +	If this field does not have meaning with the protocol,
   1.381 +	the field content should be set to ZERO.
   1.382 +	*/
   1.383 +	TUint16 iDstPort;
   1.384 +	/**
   1.385 +	The amount of pre-computed IPv6 extension headers in iPacket which
   1.386 +	are copied to the beginning of each outgoing packet
   1.387 +
   1.388 +	If iOffset > 0, then #iPacket includes that much of extension
   1.389 +	headers that are copied in front of each packet.
   1.390 +	*/
   1.391 +	TInt iOffset;
   1.392 +	/**
   1.393 +	Pre-computed extension headers for all packets in this flow.
   1.394 +	
   1.395 +	These can only be added in the ReadyL phase. If any of the
   1.396 +	ReadyL's adds extension headers into this, it must take care
   1.397 +	of maintaining the correct Next Header in the virtual IP header
   1.398 +	(and the original upper layer protocol must be placed in the
   1.399 +	next header of the last extension header added.
   1.400 +	
   1.401 +	Stack copies the content of this to each outgoing packet, just below
   1.402 +	the IP header, before running the ApplyL functions of the outbound
   1.403 +	flow hooks.
   1.404 +
   1.405 +	@par MIp6Hook::OpenL
   1.406 +	The iPacket <b>must not</b> be modified during the OpenL phase.
   1.407 +
   1.408 +	@par MFlowHook::ReadyL
   1.409 +	A non-tunneling hook may add extension headers into the current
   1.410 +	iPacket. A tunneling hook has more complex requirements:
   1.411 +	it must save the current iPacket and #iOffset and initialize
   1.412 +	iOffset = 0, and iPacket as empty.
   1.413 +
   1.414 +    @par MFlowHook::ApplyL
   1.415 +	When a tunneling hook adds the tunneling IP header, it
   1.416 +	must also copy the saved iPacket below the added IP header.
   1.417 +	*/
   1.418 +	RMBufPacketPeek iPacket;
   1.419 +	/**
   1.420 +	The received packet which caused an ICMP error reply to be sent.
   1.421 +
   1.422 +	This is only used for ICMP error repply flows, and should be
   1.423 +	ignored by others -- mainly for IPSEC hook. The packet, if
   1.424 +	present, is in unpacked state.
   1.425 +	*/
   1.426 +	RMBufPacketBase iIcmp;
   1.427 +	/**
   1.428 +	The current destination interface.
   1.429 +
   1.430 + 	This is ONLY used during connect/OpenL phase.
   1.431 +
   1.432 +	The value is maintained by the stack, and is intended as
   1.433 +	read-only information for the hooks that have a use for
   1.434 +	it (for example, IPSEC implementing VPN specific policies).
   1.435 +
   1.436 +	A hook must not modify this value (the stack will recompute
   1.437 +	the value after each OpenL, based on the possibly changed
   1.438 +	address parameters in the TPacketHead)
   1.439 +
   1.440 +	@par MIp6Hook::OpenL
   1.441 +	<b>read-only</b>
   1.442 +	@par MFlowHook::ReadyL
   1.443 +	<b>read-only</b>
   1.444 +	*/
   1.445 + 	TUint32 iInterfaceIndex;
   1.446 +	};
   1.447 +
   1.448 +class TInet6PacketBase
   1.449 +	/**
   1.450 +	* Thin base class for the TInet6Packet.
   1.451 +	*/
   1.452 +	{
   1.453 +public:
   1.454 +	enum TAlign
   1.455 +		{
   1.456 +		EAlign1 = 0,	///< Align to byte (no align requirement)
   1.457 +		EAlign2 = 1,	///< Align to 2 byte unit (even address)
   1.458 +		EAlign4 = 3,	///< Align to 4 byte unit
   1.459 +		EAlign8 = 7		///< Align to 8 byte unit
   1.460 +		};
   1.461 +
   1.462 +	/**
   1.463 +	Constructor.
   1.464 +
   1.465 +	@param aAlign	The align requirement.
   1.466 +	*/
   1.467 +	TInet6PacketBase(TAlign aAlign) : iLength(0), iAlign(aAlign) {}
   1.468 +
   1.469 +	/**
   1.470 +	Length of the mapped region.
   1.471 +
   1.472 +	The real mapped length as computed by the Access function.
   1.473 +	If access returned non-NULL, the following is always TRUE:
   1.474 +
   1.475 +	@li	aMin <= iLength
   1.476 +	*/
   1.477 +	TInt iLength;
   1.478 +
   1.479 +	IMPORT_C TUint8 *Access(RMBufChain &aPacket, TInt aOffset, TInt aSize, TInt aMin);
   1.480 +
   1.481 +	inline void SetAlign(TAlign aAlign)
   1.482 +		/**
   1.483 +		* Changes the align requirement.
   1.484 +		*
   1.485 +		* @param aAlign The new align requirement.
   1.486 +		*/
   1.487 +		{
   1.488 +		iAlign = aAlign;
   1.489 +		}
   1.490 +protected:
   1.491 +	/**
   1.492 +	The align requirement.
   1.493 +	*/
   1.494 +	TAlign iAlign;
   1.495 +	};
   1.496 +
   1.497 +// TInet6Packet template
   1.498 +// *********************
   1.499 +template <class T>
   1.500 +class TInet6Packet : public TInet6PacketBase
   1.501 +	/**
   1.502 +	Encapsulates an IPv6 packet header as a section of an RMBufChain.
   1.503 +
   1.504 +	The T template parameter should represent a packet header type. It should 
   1.505 +	support static functions MaxHeaderLength() and MinHeaderLength() that return 
   1.506 +	TInt values for maximum and minimum header lengths respectively.
   1.507 +
   1.508 +	@publishedAll
   1.509 +	@released
   1.510 +	@since v7.0
   1.511 +	*/
   1.512 +	{
   1.513 +public:
   1.514 +	TInet6Packet(TAlign aAlign = EAlign4) : TInet6PacketBase(aAlign), iHdr(NULL)
   1.515 +		/**
   1.516 +		Default constructor.
   1.517 +
   1.518 +		Construct an empty mapping. To be usable, the Set() function
   1.519 +		must be used.
   1.520 +		*/
   1.521 +		{}
   1.522 +	TInet6Packet(RMBufChain &aPacket) : TInet6PacketBase(EAlign4)
   1.523 +		/**
   1.524 +		Constructor specifying a RMBufChain object.
   1.525 +
   1.526 +		Verify and arrange it so that a class T can be mapped
   1.527 +		to a contiguous octets from the beginning of the RMBufChain
   1.528 +		content, and set iHdr to point this area.
   1.529 +
   1.530 +		If this is not possible, iHdr is initialized to NULL.
   1.531 +
   1.532 +		@param	aPacket
   1.533 +			Packet containing the header T at offset = 0
   1.534 +		*/
   1.535 +		{
   1.536 +		iHdr = (T *)Access(aPacket, 0, T::MaxHeaderLength(), T::MinHeaderLength());
   1.537 +		}
   1.538 +
   1.539 +	TInet6Packet(RMBufChain &aPacket, TInt aOffset, TAlign aAlign = EAlign4) : TInet6PacketBase(aAlign)
   1.540 +		/**
   1.541 +		Constructor specifying a RMBufChain object and an offset.
   1.542 +
   1.543 +		Verify and arrange it so that a class T can be mapped
   1.544 +		to a contiguous octets starting at specified offset of
   1.545 +		the RMBufChain content, and set iHdr to point this area.
   1.546 +
   1.547 +		If this is not possible, iHdr is initialized to NULL.
   1.548 +
   1.549 +		@param aPacket
   1.550 +			Packet containing the header T at aOffset
   1.551 +		@param aOffset
   1.552 +			Offset of the header to be mapped.
   1.553 +		@param aAlign
   1.554 +			The alignement requirement.
   1.555 +		*/
   1.556 +		{
   1.557 +		iHdr = (T *)Access(aPacket, aOffset, T::MaxHeaderLength(), T::MinHeaderLength());
   1.558 +		}
   1.559 +
   1.560 +	void Set(RMBufChain &aPacket, TInt aOffset, TInt aSize)
   1.561 +		/**
   1.562 +		Sets the packet header from a specified RMBufChain object.
   1.563 +
   1.564 +		Verify and arrange it so that a aSize octets can be mapped
   1.565 +		to a contiguous octets starting at specified offset of
   1.566 +		the RMBufChain content, and set iHdr to point this area.
   1.567 +
   1.568 +		If this is not possible, iHdr is initialized to NULL.
   1.569 +
   1.570 +		Note that this differs from the contructors: the required
   1.571 +		size is a parameter, and not determined by the T::MinHeaderLength().
   1.572 +		However, the "T* iHdr" is set to point the start of the requested
   1.573 +		area. It's a responsibility of the user of this method to know
   1.574 +		whether using this pointer is safe with the specified size parameter.
   1.575 +
   1.576 +		@param	aPacket
   1.577 +			Packet containing the header T at aOffset
   1.578 +		@param	aOffset
   1.579 +			Offset (position) of the header to be mapped
   1.580 +		@param	aSize
   1.581 +			Length of required contiguous memory
   1.582 +		*/
   1.583 +		{
   1.584 +		iHdr = (T *)Access(aPacket, aOffset, aSize, aSize);
   1.585 +		}
   1.586 +
   1.587 +	inline T& operator()()
   1.588 +		{
   1.589 +		return *iHdr;
   1.590 +		}
   1.591 +	/**
   1.592 +	The pointer to the mapped region (if non-NULL). If NULL,
   1.593 +	then there is no mapping, and iLength == 0.
   1.594 +	*/
   1.595 +	T *iHdr;
   1.596 +	};
   1.597 +
   1.598 +
   1.599 +//	TPacketPoker
   1.600 +//	************
   1.601 +class TPacketPoker
   1.602 +	/**
   1.603 +	Provides a utility for linear scanning of a chain of RMBuf objects (an RMBufChain).
   1.604 +
   1.605 +	An object of this type maintains a current point in the RMBufChain. This point 
   1.606 +	can only move forward, and a leave occurs if the point advances beyond the 
   1.607 +	end of the chain.
   1.608 +
   1.609 +	Any pointers and aligns arranged before the current point, remain valid: for 
   1.610 +	example, you can save a reference and advance the pointer, and the reference 
   1.611 +	remains usable.
   1.612 + 
   1.613 +	If instead you need to go to a single specified offset, then use
   1.614 +	RMBufChain::Goto() or RMBufPacketPeek::Access().
   1.615 +
   1.616 +	@post
   1.617 +	A Generic implementation assert: 
   1.618 +	after construct, iTail == 0 iff iCurrent == 0 (all scanned), or
   1.619 +	in other words: as long as there are bytes after current point,
   1.620 +	iTail will be non-zero (and More() returns ETrue).
   1.621 +	All methods maintain this invariant or leave, if impossible.
   1.622 +
   1.623 +	Some other utility methods, not directly related to scanning, are also included. 
   1.624 +	@since v7.0
   1.625 +	@publishedAll
   1.626 +	@released
   1.627 +	*/
   1.628 +	{
   1.629 +public:
   1.630 +	IMPORT_C TPacketPoker(RMBufChain &aChain);
   1.631 +
   1.632 +	inline void SkipL(TInt aSize)
   1.633 +		/**
   1.634 +		Moves the current point forward a specified number of bytes.
   1.635 +
   1.636 +		@param aSize Number of bytes to move forward
   1.637 +		@leave KErrEof
   1.638 +			if the request cannot be satisfied.
   1.639 +		*/
   1.640 +		{ if (aSize < iTail) { iTail -= aSize; iOffset += aSize; } else OverL(aSize); }
   1.641 +
   1.642 +	inline TUint8 *Ptr() const
   1.643 +		/**
   1.644 +		Raw pointer to the current point (can be invalid, if iTail = 0).
   1.645 +	
   1.646 +		@note Internal "unsafe" method
   1.647 +		*/
   1.648 +		{return iCurrent->Ptr() + iOffset; }
   1.649 +
   1.650 +	inline TUint8 *ReferenceL(TInt aSize = 1)
   1.651 +		/**
   1.652 +		Gets a pointer to the current point, such that
   1.653 +		at least the specified minimum number of bytes can be read.
   1.654 +
   1.655 +		@param aSize
   1.656 +			Specified minimum number of bytes to be read through
   1.657 +			the returned pointer.
   1.658 +		@return Raw data pointer
   1.659 +		@leave KErrEof
   1.660 +			if the request cannot be satisfied.
   1.661 +		*/
   1.662 +		{ if (iTail >= aSize) return Ptr(); else return AdjustL(aSize); }
   1.663 +
   1.664 +	inline TUint8 *ReferenceAndSkipL(TInt aSize)
   1.665 +		/**
   1.666 +		Gets a pointer to the current point, such that at least the
   1.667 +		specified minimum number of bytes can be read,
   1.668 +		and moves the point the specified number of bytes forward.
   1.669 +
   1.670 +		@param aSize
   1.671 +			Specified minimum number of bytes to be read through the returned 
   1.672 +			pointer, and the number of bytes to move forward
   1.673 +		@return
   1.674 +			Raw data pointer
   1.675 +		@leave KErrEof
   1.676 +			if the request cannot be satisfied.
   1.677 +		*/
   1.678 +		{ TUint8 *x = ReferenceL(aSize); SkipL(aSize); return x; }
   1.679 +
   1.680 +	inline TInt Remainder() const
   1.681 +		/**
   1.682 +		Gets the length of the contiguous space after the current point.	
   1.683 +
   1.684 +		@return Length after the current point
   1.685 +		*/
   1.686 +		{ return iTail; }
   1.687 +
   1.688 +	inline TBool AtBegin() const
   1.689 +		/**
   1.690 +		Tests whether the current point is at the beginning of an RMBuf.
   1.691 +
   1.692 +		@return ETrue if current point is at the beginning
   1.693 +		*/
   1.694 +		{ return iOffset == 0; }
   1.695 +
   1.696 +	inline TBool More() const
   1.697 +		/**
   1.698 +		Tests whether there is more data to scan.
   1.699 +
   1.700 +		@return ETrue if there is more data to scan
   1.701 +		*/
   1.702 +		{ return iTail > 0; }
   1.703 +
   1.704 +	IMPORT_C static TBool IsExtensionHeader(TInt aProtocolId);
   1.705 +private:
   1.706 +	IMPORT_C void OverL(TInt aSize);
   1.707 +	IMPORT_C TUint8 *AdjustL(TInt aSize);
   1.708 +	/** The RMBuf of the current point. */
   1.709 +	RMBuf *iCurrent;
   1.710 +	/** The offset of the current point in the RMBuf. */
   1.711 +	TInt iOffset;
   1.712 +	/** Remaining bytes starting from the current point in the RMBuf. */
   1.713 +	TInt iTail;
   1.714 +	};
   1.715 +
   1.716 +#endif