epoc32/include/in_pkt.h
author William Roberts <williamr@symbian.org>
Tue, 16 Mar 2010 16:12:26 +0000
branchSymbian2
changeset 2 2fe1408b6811
child 4 837f303aceeb
permissions -rw-r--r--
Final list of Symbian^2 public API header files
williamr@2
     1
// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
williamr@2
     2
// All rights reserved.
williamr@2
     3
// This component and the accompanying materials are made available
williamr@2
     4
// 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
williamr@2
     5
// which accompanies this distribution, and is available
williamr@2
     6
// at the URL "http://www.symbianfoundation.org/legal/licencesv10.html".
williamr@2
     7
//
williamr@2
     8
// Initial Contributors:
williamr@2
     9
// Nokia Corporation - initial contribution.
williamr@2
    10
//
williamr@2
    11
// Contributors:
williamr@2
    12
//
williamr@2
    13
// Description:
williamr@2
    14
// in_pkt.h - packet handling routines
williamr@2
    15
// Generic packet handling utility for mapping packet handling to the RMBufChain.
williamr@2
    16
//
williamr@2
    17
williamr@2
    18
williamr@2
    19
williamr@2
    20
/**
williamr@2
    21
 @file in_pkt.h
williamr@2
    22
 @publishedAll
williamr@2
    23
 @released
williamr@2
    24
*/
williamr@2
    25
williamr@2
    26
#ifndef __IN_PKT_H__
williamr@2
    27
#define __IN_PKT_H__
williamr@2
    28
williamr@2
    29
#include <nifmbuf.h>
williamr@2
    30
#include "ip6_hdr.h"	// ..should eventually be <inet/ip6_hdr.h>? -- msa
williamr@2
    31
#include "ip4_hdr.h"
williamr@2
    32
williamr@2
    33
#define TPACKETHEAD_FRAGMENT	1	///< Enable iFragment in TPacketHead
williamr@2
    34
williamr@2
    35
/**
williamr@2
    36
 TScopeType is only provided so that "magic" constants can be
williamr@2
    37
 avoided in the source code. However, the max value cannot be changed
williamr@2
    38
 to anything from 0xF. The scope type is assumed to be 4 bits long
williamr@2
    39
 in many occasions.
williamr@2
    40
williamr@2
    41
 The value of the scope type is directly bound the the IPv6 Scope
williamr@2
    42
 level - 1. This can be done, as IPv6 Scope level 0 is not legal
williamr@2
    43
 (or usable) in any context within the stack.
williamr@2
    44
 This allows our non-standard network scope (= 0x10) to
williamr@2
    45
 be coded internally in 4 bits (as 0xF).
williamr@2
    46
williamr@2
    47
 @publishedAll
williamr@2
    48
 @released
williamr@2
    49
 @since v7.0s
williamr@2
    50
*/
williamr@2
    51
enum TScopeType
williamr@2
    52
	{
williamr@2
    53
	EScopeType_IF	= 0x0,	///< (= #KIp6AddrScopeNodeLocal - 1), id is interface index
williamr@2
    54
	EScopeType_IAP	= 0x1,	///< (= #KIp6AddrScopeLinkLocal - 1). id is IAP number
williamr@2
    55
	EScopeType_GLOBAL = 0xD,///< (= #KIp6AddrScopeGlobal - 1). id is global scope id
williamr@2
    56
	//
williamr@2
    57
	// no symbols defined for types 2..14 (they are also valid)
williamr@2
    58
	//
williamr@2
    59
	EScopeType_NET	= 0xF	///< (= #KIp6AddrScopeNetwork - 1), id is network number (must be the last entry)
williamr@2
    60
	};
williamr@2
    61
williamr@2
    62
//
williamr@2
    63
//	TIpHeader
williamr@2
    64
//	*********
williamr@2
    65
class TIpHeader
williamr@2
    66
	/**
williamr@2
    67
	A simple help class that uses a union to merge handling of either an IPv4 or 
williamr@2
    68
	an IPv6 header. 
williamr@2
    69
	@since v7.0
williamr@2
    70
	@publishedAll
williamr@2
    71
	@released
williamr@2
    72
	*/
williamr@2
    73
	{
williamr@2
    74
public:
williamr@2
    75
	/**
williamr@2
    76
	Gets the minimum header length.
williamr@2
    77
williamr@2
    78
	IPv6 header is longer than minimum IPv4 header, thus
williamr@2
    79
	returned value is for IPv4. This function only defined
williamr@2
    80
	because it is required when this class is used as template
williamr@2
    81
	parameter in TInet6Packet.
williamr@2
    82
	
williamr@2
    83
	@return Minimum IPv4 header length
williamr@2
    84
	*/
williamr@2
    85
	inline static TInt MinHeaderLength() {return TInet6HeaderIP4::MinHeaderLength(); }
williamr@2
    86
	/**
williamr@2
    87
	Gets the maximum header length.
williamr@2
    88
williamr@2
    89
	IPv6 header always shorter than maximum IPv4 header, thus
williamr@2
    90
	returned value is for IPv4. This function is only defined
williamr@2
    91
	because "header mapping" classes are expected to have it.
williamr@2
    92
	
williamr@2
    93
	@return Maximum IPv4 header length
williamr@2
    94
	*/
williamr@2
    95
	inline static TInt MaxHeaderLength() {return TInet6HeaderIP4::MaxHeaderLength(); }
williamr@2
    96
williamr@2
    97
	union
williamr@2
    98
		{
williamr@2
    99
		TInet6HeaderIP4 ip4;
williamr@2
   100
		TInet6HeaderIP ip6;
williamr@2
   101
		};
williamr@2
   102
	};
williamr@2
   103
williamr@2
   104
williamr@2
   105
//	RMBufPacketPeek
williamr@2
   106
//	***************
williamr@2
   107
class RMBufPacketPeek : public RMBufChain
williamr@2
   108
	/**
williamr@2
   109
	Extends RMBufChain to add functions to read packet data as a descriptor 
williamr@2
   110
	and as an IP header.
williamr@2
   111
williamr@2
   112
	The RMBufChain is assumed to contain the raw packet, without
williamr@2
   113
	the info block prepended (e.g. if this class is used for RMBufPacketBase
williamr@2
   114
	derived handle, it must be in "unpacked" state).
williamr@2
   115
	
williamr@2
   116
	@since v7.0
williamr@2
   117
	@publishedAll
williamr@2
   118
	@released
williamr@2
   119
	*/
williamr@2
   120
	{
williamr@2
   121
public:
williamr@2
   122
	IMPORT_C TPtr8 Access(TInt aSize, TUint aOffset = 0);
williamr@2
   123
	IMPORT_C TIpHeader *GetIpHeader();
williamr@2
   124
	};
williamr@2
   125
williamr@2
   126
//	TPacketHead
williamr@2
   127
//	***********
williamr@2
   128
class TPacketHead
williamr@2
   129
	/**
williamr@2
   130
	Storage for some precomputed information for an outbound packet flow.
williamr@2
   131
williamr@2
   132
	The outbound TPacketHead is part of the flow context (CFlowContext).
williamr@2
   133
williamr@2
   134
	The CFlowContext::Connect initializes the content from the parameters
williamr@2
   135
	of the flow (TFlowInfo) and runs the connection process.. The connection
williamr@2
   136
	process (MIp6Hook::OpenL and MFlowHook::ReadyL phases) completes the
williamr@2
   137
	information. After this, as long as the flow is connected, the content
williamr@2
   138
	is mostly frozen and <b>must not be modified by anyone</b>.
williamr@2
   139
 
williamr@2
   140
    When there is a need to change any flow information, the changes must
williamr@2
   141
	be done to the flow parameters (and not to TPacketHead). The change of
williamr@2
   142
	flow parameters also sets the CFlowContext::iChanged flag, and this
williamr@2
   143
	eventually causes a new CFlowContext::Connect, which re-initializes
williamr@2
   144
	the TPacketHead with the new information.
williamr@2
   145
williamr@2
   146
	For each field in the TPacketHead, the hook writer must follow the
williamr@2
   147
	basic rule (only for fields that it intends to change):
williamr@2
   148
williamr@2
   149
	- if some field is changed in MIp6Hook::OpenL, then the previous
williamr@2
   150
	value should be restored in the MFlowHook::ReadyL.
williamr@2
   151
	- an exeception: the hook must omit the restore, if the
williamr@2
   152
	previous value was unspecified value (for example, the source
williamr@2
   153
	address).
williamr@2
   154
	- the content of #iPacket (and #iOffset) are special: they cannot
williamr@2
   155
	be modified in the MIp6Hook::OpenL phase. A hook can
williamr@2
   156
	modify them only in the MFlowHook::ReadyL phase. And, if the hook
williamr@2
   157
	is adding an IP header for tunneling, it must save the current content
williamr@2
   158
	of these fields in the ReadyL function, and then clear out the fields
williamr@2
   159
	(it must make the iPacket empty and zero iOffset). The hook must add
williamr@2
   160
	the saved iPacket content below the added tunnel header in
williamr@2
   161
	MFlowHook::ApplyL .
williamr@2
   162
williamr@2
   163
	@since v7.0
williamr@2
   164
	@publishedAll
williamr@2
   165
	@released
williamr@2
   166
	*/
williamr@2
   167
	{
williamr@2
   168
public:
williamr@2
   169
	IMPORT_C TBool ExtHdrGet(TInt aType, TInt& aOfs, TInt& aLen);
williamr@2
   170
	IMPORT_C TBool ExtHdrGetOrPrependL(TInt aType, TInt& aOfs, TInt& aLen);
williamr@2
   171
	IMPORT_C TBool ExtHdrGetOrAppendL(TInt aType, TInt& aOfs, TInt& aLen);
williamr@2
   172
	IMPORT_C void AddDestinationOptionL(const TPtrC8& aOption, TUint8 aAlign=0, TUint8 aModulo=4);
williamr@2
   173
	IMPORT_C void AddDestinationOptionL(const TUint8* aOption, TUint8 aLen, TUint8 aAlign=0, TUint8 aModulo=4);
williamr@2
   174
williamr@2
   175
public:
williamr@2
   176
	/**
williamr@2
   177
	"Virtual" IP header. The IPv6 header stucture is used, but the same
williamr@2
   178
	format is <b>also</b> used for the IPv4 destinations (Version() == 4,
williamr@2
   179
	even though the header format is still IPv6!)
williamr@2
   180
	
williamr@2
   181
	This header is initialized in the beginning of the OpenL phase
williamr@2
   182
	as follows:
williamr@2
   183
	@li	Version = 0
williamr@2
   184
	@li	Traffic Class, copied from the flow iOptions.iTrafficClass
williamr@2
   185
	@li	Flow Label = 0
williamr@2
   186
	@li	Payload Length = 0 (dummy field, not used)
williamr@2
   187
	@li	Next Header, copied from the flow iProtocol
williamr@2
   188
	@li	Hop Limit, copied from the flow iOptions.iHopLimit
williamr@2
   189
	@li	Src Address, copied from the flow Local Address (usually unspecified)
williamr@2
   190
	@li	Dst Address, copied from the flow Remote Address
williamr@2
   191
	
williamr@2
   192
	At beginning of the ReadyL phase (= at end of OpenL), the destination
williamr@2
   193
	address (and iDstId) are used to find a route on the interface. Depending
williamr@2
   194
	on whether this address is IPv4 (mapped) or IPv6, the Version field is set
williamr@2
   195
	accordingly to either 4 or 6.
williamr@2
   196
williamr@2
   197
	After succesfull completion of the ReadyL, this used for *each* packet
williamr@2
   198
	which needs an IP header to be generated on send. The Version() determines
williamr@2
   199
	whether IPv4 or IPv6 frame is to be generated (this is the initial
williamr@2
   200
	header in the packet, *before* running outbound ApplyL hooks):
williamr@2
   201
	
williamr@2
   202
	@verbatim
williamr@2
   203
	                   IPv6            IPv4
williamr@2
   204
	   Version         == 6            ==4
williamr@2
   205
	   Traffic Class   used as is      used as TOS
williamr@2
   206
	   Flow Label      used as is      ignored
williamr@2
   207
	   Payload Length  ignored         ignored
williamr@2
   208
	   Next Header     used as is      used as Protocol
williamr@2
   209
	   Hop Limit       used as is      used as TTL
williamr@2
   210
	   Src Address     used as is      used as IPv4 mapped
williamr@2
   211
	   Dst Address     used as is      used as IPv4 mapped
williamr@2
   212
	@endverbatim
williamr@2
   213
	*/
williamr@2
   214
	TInet6HeaderIP ip6;
williamr@2
   215
	/**
williamr@2
   216
	Contains the scope id associated with the destination address
williamr@2
   217
	which is stored in #ip6 Dst Address. This id and address must
williamr@2
   218
	always be considered as a unit. Logically, any change changes
williamr@2
   219
	both values.
williamr@2
   220
williamr@2
   221
	iDstId is initialized from the flow context TFlowInfo::iRemote.Scope() at
williamr@2
   222
	beginning of the flow connect phase. If application does not define
williamr@2
   223
	this scope id, then the system will attempt to choose a default value
williamr@2
   224
	at beginning of the connect phase. If the default cannot be determined,
williamr@2
   225
	the flow is put into pending state (and no connect happens).
williamr@2
   226
williamr@2
   227
	@par MIp6Hook::OpenL
williamr@2
   228
	On entry to the OpenL, the iDstId is always non-zero and destination
williamr@2
   229
	address is specified. If a hook changes the destination address in
williamr@2
   230
	OpenL method, it must provide the correct id value
williamr@2
   231
	which goes with the new destination. If it cannot do this, it
williamr@2
   232
	must either abort the connect by leaving with an error state, or it
williamr@2
   233
	can leave with PENDING (> 0) status to signal there is no route
williamr@2
   234
	for the new destination.
williamr@2
   235
	If the stack cannot find suitable interface for the destination, then
williamr@2
   236
	it aborts the connect phase, and the flow is placed into holding state.
williamr@2
   237
williamr@2
   238
	@note
williamr@2
   239
		Only a tunneling hook can safely change the destination
williamr@2
   240
		address (a use of routing header can also be a kind of
williamr@2
   241
		tunneling).
williamr@2
   242
	
williamr@2
   243
	@par MFlowHook::ReadyL
williamr@2
   244
	If the hook changed the destination address (or id) in the OpenL,
williamr@2
   245
	the ReadyL must restore the original values back.
williamr@2
   246
williamr@2
   247
	*/
williamr@2
   248
	TUint32 iDstId;
williamr@2
   249
	/**
williamr@2
   250
	Contains the scope id associated with the source address
williamr@2
   251
	which is stored in #ip6 Src address. This is defined when the source
williamr@2
   252
	address is defined, and otherwise undefined.
williamr@2
   253
williamr@2
   254
	iSrcId is initialized from TFlowInfo::iLocal.Scope() at beginning of the
williamr@2
   255
	flow connect phase. If application defines the source address,
williamr@2
   256
	but does not specify this scope id, then the system chooses
williamr@2
   257
	the id based on the interface defined by the source address.
williamr@2
   258
	If scope and address are both specified, they must match the
williamr@2
   259
	selected interface.
williamr@2
   260
williamr@2
   261
	@par MIp6Hook::OpenL
williamr@2
   262
	On entry to the OpenL, the iSrcId (and source address) may be
williamr@2
   263
	undefined (#iSourceSet = 0). If defined (iSourceSet = 1), then
williamr@2
   264
	both address and iSrcId are defined (iSrcId != 0). A hook may
williamr@2
   265
	force a reselection of the source just by zeroing the
williamr@2
   266
	iSourceSet.
williamr@2
   267
williamr@2
   268
	@par MFlowHook::ReadyL
williamr@2
   269
	If the hook changed the source address (or id) in the OpenL,
williamr@2
   270
	the ReadyL must restore the original values back, but only
williamr@2
   271
	if the original value was defined (#iSourceSet = 1 in OpenL).
williamr@2
   272
	*/
williamr@2
   273
	TUint32 iSrcId;
williamr@2
   274
	/**
williamr@2
   275
	The source address has been set.
williamr@2
   276
williamr@2
   277
	This bit indicates whether the value stored in #ip6 src field
williamr@2
   278
	and #iSrcId is to be used as a source address as is.
williamr@2
   279
williamr@2
   280
	Initialized from TFlowInfo::iLocalSet, which tells whether user
williamr@2
   281
	specified tbe source address or not (e.g used RSocket Bind method).
williamr@2
   282
	The stack checks the value after each MIp6Hook::OpenL call, and
williamr@2
   283
	if the flag is set, the source in ip6 is used as is. If the flag
williamr@2
   284
	is zero, then the stack performs the normal source address selection
williamr@2
   285
	based on the current destination address (#iSrcId and destination
williamr@2
   286
	address).
williamr@2
   287
williamr@2
   288
	@par MIp6Hook::OpenL
williamr@2
   289
	On entry, this flag is always set and source address is defined.
williamr@2
   290
	A hook may clear this flag, if it wants the
williamr@2
   291
	stack choose the source address based on current destination.
williamr@2
   292
	The clearing operation is normally needed only by a tunneling
williamr@2
   293
	hook.
williamr@2
   294
williamr@2
   295
	@note
williamr@2
   296
		If the hook specifies the source address, it must be either
williamr@2
   297
		a valid source address for the interface or unspecified
williamr@2
   298
		address.
williamr@2
   299
williamr@2
   300
	@par MFlowHook::ReadyL
williamr@2
   301
	Upon entry to the ReadyL, the source address is always fully
williamr@2
   302
	known (the hook can assume that #iSrcId and the #ip6 source
williamr@2
   303
	addresses are valid).
williamr@2
   304
	If the source address was set before the OpenL, then this
williamr@2
   305
	must restore the original value (along with the #iSrcId
williamr@2
   306
	and source address).
williamr@2
   307
	*/
williamr@2
   308
	TUint iSourceSet:1;
williamr@2
   309
#ifdef TPACKETHEAD_FRAGMENT
williamr@2
   310
	/**
williamr@2
   311
	The fragment processing alredy done.
williamr@2
   312
	
williamr@2
   313
	This bit is meaningful only in OpenL phase. If already set,
williamr@2
   314
	then some ealier hook has requested that the packet must
williamr@2
   315
	be fragmented to fit the mtu.
williamr@2
   316
	
williamr@2
   317
	A tunneling hook can set this bit in OpenL, if it needs
williamr@2
   318
	the fragmenting to happen before the ApplyL is called (e.g.
williamr@2
   319
	the fragments are tunneled instead of fragmenting the
williamr@2
   320
	tunneling).
williamr@2
   321
	
williamr@2
   322
	This bit can only be set or left as is. It cannot be cleared
williamr@2
   323
	once set.
williamr@2
   324
	*/
williamr@2
   325
	TUint iFragment:1;
williamr@2
   326
#endif
williamr@2
   327
	/**
williamr@2
   328
	Selector info, the upper layer protocol.
williamr@2
   329
williamr@2
   330
	iProtocol has the same value as ip6.NextHeader() when iPacket is empty,
williamr@2
   331
	and otherwise it is the same as NextHeader() of the last extension
williamr@2
   332
	header in the iPacket.
williamr@2
   333
williamr@2
   334
	The values of the other selector fields: #iIcmpType, #iIcmpCode
williamr@2
   335
	#iSrcPort and #iDstPort depend on iProtocol. Whenever iProtocol
williamr@2
   336
	is changed, the other fields must be updated accordingly.
williamr@2
   337
williamr@2
   338
	@par MIp6Hook::OpenL
williamr@2
   339
	Because iPacket cannot be modified during the OpenL phase, the
williamr@2
   340
	content of this field and the Next Header (protocol) field in
williamr@2
   341
	the #ip6 pseudoheader must always be the same. This field should
williamr@2
   342
	be considered as <b>read-only</b>, unless the hook intends to
williamr@2
   343
	apply IP-in-IP tunneling, in which case the hook <b>must</b>
williamr@2
   344
	change the value to the appropriate tunneling protocol
williamr@2
   345
	(#KProtocolInet6Ipip or #KProtocolInetIpip).
williamr@2
   346
williamr@2
   347
    @par MFlowHook::ReadyL
williamr@2
   348
	Only a tunneling hook needs to restore the value here to match
williamr@2
   349
	the original upper layer protocol. See #iPacket for
williamr@2
   350
	more detailed information.
williamr@2
   351
	*/
williamr@2
   352
	TUint8 iProtocol;
williamr@2
   353
	/**
williamr@2
   354
	Selector field whose value depends on #iProtocol. 
williamr@2
   355
 
williamr@2
   356
	If this field does not have meaning with the protocol,
williamr@2
   357
	the field content should be set to ZERO.
williamr@2
   358
	*/
williamr@2
   359
	TUint8 iIcmpType;
williamr@2
   360
	/**
williamr@2
   361
	Selector field whose value depends on #iProtocol. 
williamr@2
   362
 
williamr@2
   363
	If this field does not have meaning with the protocol,
williamr@2
   364
	the field content should be set to ZERO.
williamr@2
   365
	*/
williamr@2
   366
	TUint8 iIcmpCode;
williamr@2
   367
	/**
williamr@2
   368
	Selector field whose value depends on #iProtocol. 
williamr@2
   369
 
williamr@2
   370
	If this field does not have meaning with the protocol,
williamr@2
   371
	the field content should be set to ZERO.
williamr@2
   372
	*/
williamr@2
   373
	TUint16 iSrcPort;
williamr@2
   374
	/**
williamr@2
   375
	Selector field whose value depends on #iProtocol. 
williamr@2
   376
 
williamr@2
   377
	If this field does not have meaning with the protocol,
williamr@2
   378
	the field content should be set to ZERO.
williamr@2
   379
	*/
williamr@2
   380
	TUint16 iDstPort;
williamr@2
   381
	/**
williamr@2
   382
	The amount of pre-computed IPv6 extension headers in iPacket which
williamr@2
   383
	are copied to the beginning of each outgoing packet
williamr@2
   384
williamr@2
   385
	If iOffset > 0, then #iPacket includes that much of extension
williamr@2
   386
	headers that are copied in front of each packet.
williamr@2
   387
	*/
williamr@2
   388
	TInt iOffset;
williamr@2
   389
	/**
williamr@2
   390
	Pre-computed extension headers for all packets in this flow.
williamr@2
   391
	
williamr@2
   392
	These can only be added in the ReadyL phase. If any of the
williamr@2
   393
	ReadyL's adds extension headers into this, it must take care
williamr@2
   394
	of maintaining the correct Next Header in the virtual IP header
williamr@2
   395
	(and the original upper layer protocol must be placed in the
williamr@2
   396
	next header of the last extension header added.
williamr@2
   397
	
williamr@2
   398
	Stack copies the content of this to each outgoing packet, just below
williamr@2
   399
	the IP header, before running the ApplyL functions of the outbound
williamr@2
   400
	flow hooks.
williamr@2
   401
williamr@2
   402
	@par MIp6Hook::OpenL
williamr@2
   403
	The iPacket <b>must not</b> be modified during the OpenL phase.
williamr@2
   404
williamr@2
   405
	@par MFlowHook::ReadyL
williamr@2
   406
	A non-tunneling hook may add extension headers into the current
williamr@2
   407
	iPacket. A tunneling hook has more complex requirements:
williamr@2
   408
	it must save the current iPacket and #iOffset and initialize
williamr@2
   409
	iOffset = 0, and iPacket as empty.
williamr@2
   410
williamr@2
   411
    @par MFlowHook::ApplyL
williamr@2
   412
	When a tunneling hook adds the tunneling IP header, it
williamr@2
   413
	must also copy the saved iPacket below the added IP header.
williamr@2
   414
	*/
williamr@2
   415
	RMBufPacketPeek iPacket;
williamr@2
   416
	/**
williamr@2
   417
	The received packet which caused an ICMP error reply to be sent.
williamr@2
   418
williamr@2
   419
	This is only used for ICMP error repply flows, and should be
williamr@2
   420
	ignored by others -- mainly for IPSEC hook. The packet, if
williamr@2
   421
	present, is in unpacked state.
williamr@2
   422
	*/
williamr@2
   423
	RMBufPacketBase iIcmp;
williamr@2
   424
	/**
williamr@2
   425
	The current destination interface.
williamr@2
   426
williamr@2
   427
 	This is ONLY used during connect/OpenL phase.
williamr@2
   428
williamr@2
   429
	The value is maintained by the stack, and is intended as
williamr@2
   430
	read-only information for the hooks that have a use for
williamr@2
   431
	it (for example, IPSEC implementing VPN specific policies).
williamr@2
   432
williamr@2
   433
	A hook must not modify this value (the stack will recompute
williamr@2
   434
	the value after each OpenL, based on the possibly changed
williamr@2
   435
	address parameters in the TPacketHead)
williamr@2
   436
williamr@2
   437
	@par MIp6Hook::OpenL
williamr@2
   438
	<b>read-only</b>
williamr@2
   439
	@par MFlowHook::ReadyL
williamr@2
   440
	<b>read-only</b>
williamr@2
   441
	*/
williamr@2
   442
 	TUint32 iInterfaceIndex;
williamr@2
   443
	};
williamr@2
   444
williamr@2
   445
class TInet6PacketBase
williamr@2
   446
	/**
williamr@2
   447
	* Thin base class for the TInet6Packet.
williamr@2
   448
	*/
williamr@2
   449
	{
williamr@2
   450
public:
williamr@2
   451
	enum TAlign
williamr@2
   452
		{
williamr@2
   453
		EAlign1 = 0,	///< Align to byte (no align requirement)
williamr@2
   454
		EAlign2 = 1,	///< Align to 2 byte unit (even address)
williamr@2
   455
		EAlign4 = 3,	///< Align to 4 byte unit
williamr@2
   456
		EAlign8 = 7		///< Align to 8 byte unit
williamr@2
   457
		};
williamr@2
   458
williamr@2
   459
	/**
williamr@2
   460
	Constructor.
williamr@2
   461
williamr@2
   462
	@param aAlign	The align requirement.
williamr@2
   463
	*/
williamr@2
   464
	TInet6PacketBase(TAlign aAlign) : iLength(0), iAlign(aAlign) {}
williamr@2
   465
williamr@2
   466
	/**
williamr@2
   467
	Length of the mapped region.
williamr@2
   468
williamr@2
   469
	The real mapped length as computed by the Access function.
williamr@2
   470
	If access returned non-NULL, the following is always TRUE:
williamr@2
   471
williamr@2
   472
	@li	aMin <= iLength
williamr@2
   473
	*/
williamr@2
   474
	TInt iLength;
williamr@2
   475
williamr@2
   476
	IMPORT_C TUint8 *Access(RMBufChain &aPacket, TInt aOffset, TInt aSize, TInt aMin);
williamr@2
   477
williamr@2
   478
	inline void SetAlign(TAlign aAlign)
williamr@2
   479
		/**
williamr@2
   480
		* Changes the align requirement.
williamr@2
   481
		*
williamr@2
   482
		* @param aAlign The new align requirement.
williamr@2
   483
		*/
williamr@2
   484
		{
williamr@2
   485
		iAlign = aAlign;
williamr@2
   486
		}
williamr@2
   487
protected:
williamr@2
   488
	/**
williamr@2
   489
	The align requirement.
williamr@2
   490
	*/
williamr@2
   491
	TAlign iAlign;
williamr@2
   492
	};
williamr@2
   493
williamr@2
   494
// TInet6Packet template
williamr@2
   495
// *********************
williamr@2
   496
template <class T>
williamr@2
   497
class TInet6Packet : public TInet6PacketBase
williamr@2
   498
	/**
williamr@2
   499
	Encapsulates an IPv6 packet header as a section of an RMBufChain.
williamr@2
   500
williamr@2
   501
	The T template parameter should represent a packet header type. It should 
williamr@2
   502
	support static functions MaxHeaderLength() and MinHeaderLength() that return 
williamr@2
   503
	TInt values for maximum and minimum header lengths respectively.
williamr@2
   504
williamr@2
   505
	@publishedAll
williamr@2
   506
	@released
williamr@2
   507
	@since v7.0
williamr@2
   508
	*/
williamr@2
   509
	{
williamr@2
   510
public:
williamr@2
   511
	TInet6Packet(TAlign aAlign = EAlign4) : TInet6PacketBase(aAlign), iHdr(NULL)
williamr@2
   512
		/**
williamr@2
   513
		Default constructor.
williamr@2
   514
williamr@2
   515
		Construct an empty mapping. To be usable, the Set() function
williamr@2
   516
		must be used.
williamr@2
   517
		*/
williamr@2
   518
		{}
williamr@2
   519
	TInet6Packet(RMBufChain &aPacket) : TInet6PacketBase(EAlign4)
williamr@2
   520
		/**
williamr@2
   521
		Constructor specifying a RMBufChain object.
williamr@2
   522
williamr@2
   523
		Verify and arrange it so that a class T can be mapped
williamr@2
   524
		to a contiguous octets from the beginning of the RMBufChain
williamr@2
   525
		content, and set iHdr to point this area.
williamr@2
   526
williamr@2
   527
		If this is not possible, iHdr is initialized to NULL.
williamr@2
   528
williamr@2
   529
		@param	aPacket
williamr@2
   530
			Packet containing the header T at offset = 0
williamr@2
   531
		*/
williamr@2
   532
		{
williamr@2
   533
		iHdr = (T *)Access(aPacket, 0, T::MaxHeaderLength(), T::MinHeaderLength());
williamr@2
   534
		}
williamr@2
   535
williamr@2
   536
	TInet6Packet(RMBufChain &aPacket, TInt aOffset, TAlign aAlign = EAlign4) : TInet6PacketBase(aAlign)
williamr@2
   537
		/**
williamr@2
   538
		Constructor specifying a RMBufChain object and an offset.
williamr@2
   539
williamr@2
   540
		Verify and arrange it so that a class T can be mapped
williamr@2
   541
		to a contiguous octets starting at specified offset of
williamr@2
   542
		the RMBufChain content, and set iHdr to point this area.
williamr@2
   543
williamr@2
   544
		If this is not possible, iHdr is initialized to NULL.
williamr@2
   545
williamr@2
   546
		@param aPacket
williamr@2
   547
			Packet containing the header T at aOffset
williamr@2
   548
		@param aOffset
williamr@2
   549
			Offset of the header to be mapped.
williamr@2
   550
		@param aAlign
williamr@2
   551
			The alignement requirement.
williamr@2
   552
		*/
williamr@2
   553
		{
williamr@2
   554
		iHdr = (T *)Access(aPacket, aOffset, T::MaxHeaderLength(), T::MinHeaderLength());
williamr@2
   555
		}
williamr@2
   556
williamr@2
   557
	void Set(RMBufChain &aPacket, TInt aOffset, TInt aSize)
williamr@2
   558
		/**
williamr@2
   559
		Sets the packet header from a specified RMBufChain object.
williamr@2
   560
williamr@2
   561
		Verify and arrange it so that a aSize octets can be mapped
williamr@2
   562
		to a contiguous octets starting at specified offset of
williamr@2
   563
		the RMBufChain content, and set iHdr to point this area.
williamr@2
   564
williamr@2
   565
		If this is not possible, iHdr is initialized to NULL.
williamr@2
   566
williamr@2
   567
		Note that this differs from the contructors: the required
williamr@2
   568
		size is a parameter, and not determined by the T::MinHeaderLength().
williamr@2
   569
		However, the "T* iHdr" is set to point the start of the requested
williamr@2
   570
		area. It's a responsibility of the user of this method to know
williamr@2
   571
		whether using this pointer is safe with the specified size parameter.
williamr@2
   572
williamr@2
   573
		@param	aPacket
williamr@2
   574
			Packet containing the header T at aOffset
williamr@2
   575
		@param	aOffset
williamr@2
   576
			Offset (position) of the header to be mapped
williamr@2
   577
		@param	aSize
williamr@2
   578
			Length of required contiguous memory
williamr@2
   579
		*/
williamr@2
   580
		{
williamr@2
   581
		iHdr = (T *)Access(aPacket, aOffset, aSize, aSize);
williamr@2
   582
		}
williamr@2
   583
williamr@2
   584
	inline T& operator()()
williamr@2
   585
		{
williamr@2
   586
		return *iHdr;
williamr@2
   587
		}
williamr@2
   588
	/**
williamr@2
   589
	The pointer to the mapped region (if non-NULL). If NULL,
williamr@2
   590
	then there is no mapping, and iLength == 0.
williamr@2
   591
	*/
williamr@2
   592
	T *iHdr;
williamr@2
   593
	};
williamr@2
   594
williamr@2
   595
williamr@2
   596
//	TPacketPoker
williamr@2
   597
//	************
williamr@2
   598
class TPacketPoker
williamr@2
   599
	/**
williamr@2
   600
	Provides a utility for linear scanning of a chain of RMBuf objects (an RMBufChain).
williamr@2
   601
williamr@2
   602
	An object of this type maintains a current point in the RMBufChain. This point 
williamr@2
   603
	can only move forward, and a leave occurs if the point advances beyond the 
williamr@2
   604
	end of the chain.
williamr@2
   605
williamr@2
   606
	Any pointers and aligns arranged before the current point, remain valid: for 
williamr@2
   607
	example, you can save a reference and advance the pointer, and the reference 
williamr@2
   608
	remains usable.
williamr@2
   609
 
williamr@2
   610
	If instead you need to go to a single specified offset, then use
williamr@2
   611
	RMBufChain::Goto() or RMBufPacketPeek::Access().
williamr@2
   612
williamr@2
   613
	@post
williamr@2
   614
	A Generic implementation assert: 
williamr@2
   615
	after construct, iTail == 0 iff iCurrent == 0 (all scanned), or
williamr@2
   616
	in other words: as long as there are bytes after current point,
williamr@2
   617
	iTail will be non-zero (and More() returns ETrue).
williamr@2
   618
	All methods maintain this invariant or leave, if impossible.
williamr@2
   619
williamr@2
   620
	Some other utility methods, not directly related to scanning, are also included. 
williamr@2
   621
	@since v7.0
williamr@2
   622
	@publishedAll
williamr@2
   623
	@released
williamr@2
   624
	*/
williamr@2
   625
	{
williamr@2
   626
public:
williamr@2
   627
	IMPORT_C TPacketPoker(RMBufChain &aChain);
williamr@2
   628
williamr@2
   629
	inline void SkipL(TInt aSize)
williamr@2
   630
		/**
williamr@2
   631
		Moves the current point forward a specified number of bytes.
williamr@2
   632
williamr@2
   633
		@param aSize Number of bytes to move forward
williamr@2
   634
		@leave KErrEof
williamr@2
   635
			if the request cannot be satisfied.
williamr@2
   636
		*/
williamr@2
   637
		{ if (aSize < iTail) { iTail -= aSize; iOffset += aSize; } else OverL(aSize); }
williamr@2
   638
williamr@2
   639
	inline TUint8 *Ptr() const
williamr@2
   640
		/**
williamr@2
   641
		Raw pointer to the current point (can be invalid, if iTail = 0).
williamr@2
   642
	
williamr@2
   643
		@note Internal "unsafe" method
williamr@2
   644
		*/
williamr@2
   645
		{return iCurrent->Ptr() + iOffset; }
williamr@2
   646
williamr@2
   647
	inline TUint8 *ReferenceL(TInt aSize = 1)
williamr@2
   648
		/**
williamr@2
   649
		Gets a pointer to the current point, such that
williamr@2
   650
		at least the specified minimum number of bytes can be read.
williamr@2
   651
williamr@2
   652
		@param aSize
williamr@2
   653
			Specified minimum number of bytes to be read through
williamr@2
   654
			the returned pointer.
williamr@2
   655
		@return Raw data pointer
williamr@2
   656
		@leave KErrEof
williamr@2
   657
			if the request cannot be satisfied.
williamr@2
   658
		*/
williamr@2
   659
		{ if (iTail >= aSize) return Ptr(); else return AdjustL(aSize); }
williamr@2
   660
williamr@2
   661
	inline TUint8 *ReferenceAndSkipL(TInt aSize)
williamr@2
   662
		/**
williamr@2
   663
		Gets a pointer to the current point, such that at least the
williamr@2
   664
		specified minimum number of bytes can be read,
williamr@2
   665
		and moves the point the specified number of bytes forward.
williamr@2
   666
williamr@2
   667
		@param aSize
williamr@2
   668
			Specified minimum number of bytes to be read through the returned 
williamr@2
   669
			pointer, and the number of bytes to move forward
williamr@2
   670
		@return
williamr@2
   671
			Raw data pointer
williamr@2
   672
		@leave KErrEof
williamr@2
   673
			if the request cannot be satisfied.
williamr@2
   674
		*/
williamr@2
   675
		{ TUint8 *x = ReferenceL(aSize); SkipL(aSize); return x; }
williamr@2
   676
williamr@2
   677
	inline TInt Remainder() const
williamr@2
   678
		/**
williamr@2
   679
		Gets the length of the contiguous space after the current point.	
williamr@2
   680
williamr@2
   681
		@return Length after the current point
williamr@2
   682
		*/
williamr@2
   683
		{ return iTail; }
williamr@2
   684
williamr@2
   685
	inline TBool AtBegin() const
williamr@2
   686
		/**
williamr@2
   687
		Tests whether the current point is at the beginning of an RMBuf.
williamr@2
   688
williamr@2
   689
		@return ETrue if current point is at the beginning
williamr@2
   690
		*/
williamr@2
   691
		{ return iOffset == 0; }
williamr@2
   692
williamr@2
   693
	inline TBool More() const
williamr@2
   694
		/**
williamr@2
   695
		Tests whether there is more data to scan.
williamr@2
   696
williamr@2
   697
		@return ETrue if there is more data to scan
williamr@2
   698
		*/
williamr@2
   699
		{ return iTail > 0; }
williamr@2
   700
williamr@2
   701
	IMPORT_C static TBool IsExtensionHeader(TInt aProtocolId);
williamr@2
   702
private:
williamr@2
   703
	IMPORT_C void OverL(TInt aSize);
williamr@2
   704
	IMPORT_C TUint8 *AdjustL(TInt aSize);
williamr@2
   705
	/** The RMBuf of the current point. */
williamr@2
   706
	RMBuf *iCurrent;
williamr@2
   707
	/** The offset of the current point in the RMBuf. */
williamr@2
   708
	TInt iOffset;
williamr@2
   709
	/** Remaining bytes starting from the current point in the RMBuf. */
williamr@2
   710
	TInt iTail;
williamr@2
   711
	};
williamr@2
   712
williamr@2
   713
#endif