networkprotocols/iphook/inhook6/include/ip6_hook.h
changeset 0 af10295192d8
equal deleted inserted replaced
-1:000000000000 0:af10295192d8
       
     1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // ip6_hook.h - hook interface for IPv6 extension header handlers
       
    15 // This module defines the interface between the main IPv6 protocol
       
    16 // handler (ip6.cpp) and header handlers. A hook need only the basic
       
    17 // IPv6 header definitions (ip6_hdr.h), it does not need to be aware
       
    18 // of IPv6 protocol specific classes: it should not include ip6.h!
       
    19 // This describes a pure interface, there is no respective
       
    20 // implementation module (ip6_hook.cpp does not exist).
       
    21 //
       
    22 
       
    23 
       
    24 
       
    25 /**
       
    26  @file ip6_hook.h
       
    27  @publishedPartner
       
    28  @released
       
    29 */
       
    30 
       
    31 #ifndef __IP6_HOOK_H__
       
    32 #define __IP6_HOOK_H__
       
    33 
       
    34 #include <es_prot.h>
       
    35 #include <nifmbuf.h>	// The interface uses RMBuf with Info
       
    36 #include "inet6err.h"
       
    37 #include "flow.h"
       
    38 #include "ip6_iprt.h"	// ..for CProtocolBaseUnbind class.
       
    39 #include "apibase.h"
       
    40 
       
    41 /** @name IP v6 constants 
       
    42 * @since v7.0
       
    43 */
       
    44 //@{
       
    45 
       
    46 /**
       
    47 * A reference constant used to compute protocol ID values for the CProtocolBase::BindL() 
       
    48 * method of the IP protocol.
       
    49 */
       
    50 const TInt KIp6Hook_ANY = 256;
       
    51 
       
    52 /**
       
    53 * A special return value from MIp6Hook::ApplyL().
       
    54 *
       
    55 * This signals that the hook didn't handle the extension header,
       
    56 * which will be passed to the next registered hook
       
    57 */
       
    58 const TInt KIp6Hook_PASS = 0;
       
    59 
       
    60 /**
       
    61 * A special return value from MIp6Hook::ApplyL().
       
    62 * 
       
    63 * This signals that the hook processed the extension header and
       
    64 * that the main loop should restart a new hook processing using
       
    65 * the function's aInfo.iProtocol field.
       
    66 */
       
    67 const TInt KIp6Hook_DONE = 1;
       
    68 
       
    69 /**
       
    70 * A flag that must be <b>cleared</b> by MIp6Hook::ApplyL() processing
       
    71 * in the aInfo.iFlags parameter, if the hook changes the destination or
       
    72 * source address in the aInfo.
       
    73 * 
       
    74 * It causes address and forwarding checks to be run by the main loop.
       
    75 * 
       
    76 * Note that this requires the hook to also signal that the extension
       
    77 * header has been processed by returning KIp6Hook_DONE. 
       
    78 */
       
    79 const TUint KIpAddressVerified	= 0x080000;
       
    80 //
       
    81 //	*NOTE*	This flag is added as a stopgap solution for
       
    82 //			the IPSEC problem, which results if decrypted packet
       
    83 //			is echoed pack due to some error condition (like
       
    84 //			Port Unreachable). It may be removed when a final
       
    85 //			solution for the problem is found (and if no other
       
    86 //			uses exist). -- msa
       
    87 /**
       
    88 * Prevent sending of this packet as ICMP error report.
       
    89 *
       
    90 * A flag that if set causes an unconditional drop of a packet,
       
    91 * if the packet is passed to the ICMP send functionality in
       
    92 * the IP layer. (see MNetworkService::Icmp4Send or
       
    93 * MNetworkService::Icmp6Send
       
    94 */
       
    95 const TUint KIpNeverIcmpError	= 0x100000;
       
    96 // *NOTE*
       
    97 //	Reuse the same bit as KIpAddressVerified. This
       
    98 //	is ok, because verified bit is used only for incoming
       
    99 //	packets, and the keep up is used only for outgoing packets.
       
   100 //
       
   101 /**
       
   102 * KIpKeepInterfaceUp is an internal flag which set or reset
       
   103 * depending on the state of the KSoKeepInterfaceUp option.
       
   104 */
       
   105 const TUint KIpKeepInterfaceUp	= 0x080000;
       
   106 
       
   107 /**
       
   108 * If this bit is set in RMBufPktInfo flags, the ECN ECT bits in
       
   109 * IP packet should be zeroed.
       
   110 */
       
   111 const TUint KIpNoEcnEct			= 0x200000;
       
   112 //@}
       
   113 
       
   114 //
       
   115 //	RMBufRecvInfo
       
   116 //	*************
       
   117 class RMBufRecvInfo : public RMBufPktInfo
       
   118 /**
       
   119 * Information for incoming packets.
       
   120 * 
       
   121 * This extends the packet information class to record progress of
       
   122 * processing the received IPv4 or IPv6 packet.
       
   123 *
       
   124 * The RMBufChain contains a full IPv6 (or IPv4) packet
       
   125 * starting from the beginning. The position of the current
       
   126 * (upper layer or extension header) is indicated by the
       
   127 * #iOffset field.
       
   128 *
       
   129 * @li #iProtocol
       
   130 *	is always the internet protocol number 	corresponding
       
   131 *	to the header incidated by iOffset.
       
   132 *	
       
   133 * @li #iLength
       
   134 *	is the length of the FULL packet, starting from the
       
   135 *	IP header. The upper layer length (that includes
       
   136 *	the uppler layer header) is always: (iLength - iOffset) >= 0.
       
   137 *	Note that this can be ZERO!
       
   138 *
       
   139 * @li #iIcmp == 0, for normal packet
       
   140 *
       
   141 * @li #iIcmp =! 0, for ICMP error report
       
   142 *
       
   143 * The source and destination address are loaded from the ip
       
   144 * header associated with the indicated upper layer header. In
       
   145 * case of ICMP error report, the addresses are loaded from the
       
   146 * packet *inside* the ICMP report.
       
   147 *
       
   148 * The addresses are always in IPv6 format. If the packet
       
   149 * was IPv4 packet, the addresses are presented in IPv4 mapped format.
       
   150 *
       
   151 * @warning
       
   152 *	The fact that address is IPv4 mapped DOES NOT mean that
       
   153 *	the packet is IPv4. It could as well be an IPv6
       
   154 *	packet with mapped addresses!
       
   155 *
       
   156 * @warning
       
   157 *	RMBufRecvInfo is assuming that it fits
       
   158 *	into the single RMBuf block.
       
   159 *
       
   160 * @publishedPartner
       
   161 * @released
       
   162 * @since v7.0
       
   163 */
       
   164 	{
       
   165 public:
       
   166 	TInt CheckL(TInt aLength) const
       
   167 	/**
       
   168 	* Tests that the specified length field does not exceed the
       
   169 	* remaining space in the buffer.
       
   170 	*
       
   171 	* Verify that there is enough data after in the packet
       
   172 	* after the #iOffset octets. This simply tests whether
       
   173 	* (aLength > #iLength - #iOffset), and leaves
       
   174 	* with #KErrInet6ShortPacket, if true.
       
   175 	*
       
   176 	* @param aLength				Length to test.
       
   177 	* @return aLength				(for convenience)
       
   178 	* @leave KErrInet6ShortPacket	Insufficient space.
       
   179 	*/
       
   180 		{
       
   181 		if (aLength > iLength - iOffset)
       
   182 			User::Leave(KErrInet6ShortPacket);
       
   183 		return aLength;
       
   184 		}
       
   185 	/** Index of the logical source network interface. */
       
   186   	TUint32 iInterfaceIndex;
       
   187 	/** Index of the physical original network interface. */
       
   188  	TUint32 iOriginalIndex;
       
   189 	//
       
   190 	// IP Information
       
   191 	//
       
   192 	/**
       
   193 	* An offset that indicates the beginning of the current header
       
   194 	* being processed.
       
   195 	* 
       
   196 	* Inbound hooks must update this if they consume a header
       
   197 	* within the packet.
       
   198 	* 	
       
   199 	* It initially points to the first header after the IP header.
       
   200 	* Offset to the header being processed.
       
   201 	*/
       
   202 	TInt iOffset;
       
   203 	/**
       
   204 	* Offset to the related IP header.
       
   205 	* 
       
   206 	* This is usually zero, but is non-zero for ICMP error reports, and could be 
       
   207 	* non-zero for tunneled packets.
       
   208 	*/
       
   209 	TUint16 iOffsetIp;
       
   210 	/** Offset of the previous Next Header field.
       
   211 	* 
       
   212 	* If a hook consumes an extension header and advances #iOffset to the
       
   213 	* next header, it must also set this to point to the Next Header
       
   214 	* field of the former header.
       
   215 	*
       
   216 	* This is initialized to refer the next header field of the IP header.
       
   217 	*
       
   218 	* This can be used by header handlers which remove the
       
   219 	* header from the packet. For example, IPSEC does this for AH and
       
   220 	* ESP headers. IPSEC must be able to correct the protocol/next header
       
   221 	* field of the previous header.
       
   222 	*/
       
   223 	TUint16 iPrevNextHdr;
       
   224 	/**
       
   225 	* IP Version (4 or 6) of the related IP header.
       
   226 	*/
       
   227 	TUint8 iVersion;
       
   228 	/**
       
   229 	* ICMP packet flag.
       
   230 	* 	
       
   231 	* This determines the interpretation of the information fields:
       
   232 	* iType, iCode, and iParameter.
       
   233 	*
       
   234 	* @li
       
   235 	*	iIcmp == 0,	The buffer contains normal upper layer packet,
       
   236 	*	the header starting from the indicated iOffset.
       
   237 	*	The values of the iType, iCode and iParameter are undefined..
       
   238 	*
       
   239 	* @li
       
   240 	*	iIcmp != 0,	The buffer contains an ICMP error report for
       
   241 	*	the upper layer protocol, the returned upper layer header
       
   242 	*	starting from the indicated iOffset. The #iOffsetIp indicates
       
   243 	*	the start of the problem packet.
       
   244 	*
       
   245 	* Valid values are: 0, #KProtocolInetIcmp, or #KProtocolInet6Icmp.
       
   246 	*/
       
   247 	TUint8 iIcmp;
       
   248 	/**
       
   249 	* ICMP Type (0..255).
       
   250 	* 
       
   251 	* This applies to both ICMPv4 and ICMPv6.
       
   252 	*
       
   253 	* (only defined if the field iIcmp != 0)
       
   254 	*/
       
   255 	TUint8 iType;
       
   256 	/**
       
   257 	* ICMP Code (0..255).
       
   258 	* 
       
   259 	* This applies to both ICMPv4 and ICMPv6.
       
   260 	*
       
   261 	* (only defined if the field iIcmp != 0)
       
   262 	*/
       
   263 	TUint8 iCode;
       
   264 	/**
       
   265 	* The last 32 bits from the ICMP header.
       
   266 	*
       
   267 	* (only defined if the field iIcmp != 0)
       
   268 	*/
       
   269 	TUint32 iParameter;
       
   270 	};
       
   271 
       
   272 typedef class RMBufInfoPacketBase<RMBufRecvInfo> RMBufRecvPacket;
       
   273 
       
   274 
       
   275 class MPacketContext : public MInetBase
       
   276 /**
       
   277 * Provides a packet context as a number of (key, value) pairs.
       
   278 *
       
   279 * The rules for construction of the key are:
       
   280 * @li
       
   281 *	The low eight bits of the key contain always the protocol number
       
   282 *	(extension header) being implemented by the hook.
       
   283 * @li
       
   284 *	If the protocol is destination option or hop-by-hop option,
       
   285 *	the implemented option types are communicated to the default
       
   286 *	handler by adding a non-zero value to the packet context with
       
   287 *	a key computed as "(option-type << 8) | protocol".
       
   288 *
       
   289 * @publishedPartner
       
   290 * @released
       
   291 * @since v7.0
       
   292 */
       
   293 	{
       
   294 public:
       
   295 	/**
       
   296 	* Sets a (key,value) pair.
       
   297 	* 
       
   298 	* If a setting already exists for the key, the value is just replaced.
       
   299 	*
       
   300 	* @param aId	Key
       
   301 	* @param aValue	Value associated with the key
       
   302 	* @return
       
   303 	* @li	KErrNone, if value stored successfully.
       
   304 	* @li	KErrNoMemory, if there was no room for the new value
       
   305 	*/
       
   306 	virtual TInt SetHookValue(const TUint32 aId, const TUint32 aValue) = 0;
       
   307 	/**
       
   308 	* Gets the value associated with the specified key.
       
   309 	*
       
   310 	* Return the current value associated with aId. If aId does not
       
   311 	* exist, ZERO is returned [=> there is no way to differentiate
       
   312 	* between non-existing value and a value that is explicitly set
       
   313 	* to zero. Implementation may interpret setting value to ZERO
       
   314 	* as request to delete the association, if it exists].
       
   315 	*
       
   316 	* @param aId	Key
       
   317 	* @return	The value, or 0 if no value was found for the key..
       
   318 	*/
       
   319 	virtual TUint32 HookValue(const TUint32 aId) const = 0;
       
   320 	};
       
   321 
       
   322 class RMBufHookPacket : public RMBufRecvPacket
       
   323 /**
       
   324 * Extends the received packet buffer class for hook processing.
       
   325 * 
       
   326 * The extension provides a packet context (MPacketContext) for
       
   327 * the duration of the hook processing. 
       
   328 * 
       
   329 * This extension has been created to solve the following problem:
       
   330 *
       
   331 *	-#	The default option header handlers need to return ICMP
       
   332 *		error message on some unimplemented options,
       
   333 *	-#	The basic design idea of the stack is that functionality
       
   334 *		can be dynamically added. Thus, if a dynamically loaded
       
   335 *		module adds support for some new option type, the default
       
   336 *		handler should not report error for such options.
       
   337 *
       
   338 * The rules of the context use are:
       
   339 *
       
   340 *	-#	While the incoming packet is processed with hooks, the IP
       
   341 *		layer maintains a packet specific context, which can store
       
   342 *		values (32 bits) associated with a key (32 bits).
       
   343 *	-#	The low 8 bits of the key is defined to be the protocol number
       
   344 *		of the header, and interpretation of the rest of the key bits
       
   345 *		is up to protocol/header specific definitions.
       
   346 *	-#	For destination and hop by hop headers, to solve the problem,
       
   347 *		the additional specification is used: the default handlers will
       
   348 *		look a value from packet context with the following key:
       
   349 *			- (optiontype << 8) | (protocol)
       
   350 *			.
       
   351 *		and if the returned value is non-ZERO, the default handler
       
   352 *		will assume someone implemented the option in question and
       
   353 *		does not generate an error.
       
   354 *
       
   355 * @note
       
   356 *	The packet context is only available during "hook processing".
       
   357 *	It is not available for upper layer prototocols!
       
   358 *
       
   359 * @publishedPartner
       
   360 * @released
       
   361 * @since v7.0
       
   362 */
       
   363 	{
       
   364 public:
       
   365 	/**
       
   366 	* Constructor
       
   367 	* @param aContext Packet context
       
   368     */
       
   369 	inline RMBufHookPacket(MPacketContext *const aContext) : iContext(aContext) {}
       
   370 	inline TInt SetHookValue(const TUint32 aId, const TUint32 aValue)
       
   371 	/**
       
   372 	* Sets a (key,value) pair.
       
   373 	* 
       
   374 	* If a setting already exists for the key, the value is just replaced.
       
   375 	*
       
   376 	* @param aId Key
       
   377 	* @param aValue  Value associated with the key
       
   378 	* @return  KErrNone, if the value was stored,
       
   379 	* @return  KErrNoMemory, if there was no room to store the value
       
   380 	*/
       
   381 		{ return iContext->SetHookValue(aId, aValue); }
       
   382 	
       
   383 	inline TInt HookValue(const TUint32 aId) const
       
   384 	/**
       
   385 	* Gets the value associated with the specified key. 
       
   386 	* 
       
   387 	* @param aId	Key
       
   388 	* @return		The value, or 0 if no value was found for the key 
       
   389 	*
       
   390 	* Note: There is no way to distinquish between 'no stored value'
       
   391 	* and 'stored value = 0'.
       
   392 	*/
       
   393 		{ return iContext->HookValue(aId); }
       
   394 private:
       
   395 	// The packet context handler. This is always defined while the
       
   396 	// packet is being processed by the hooks.
       
   397 	MPacketContext *const iContext;
       
   398 	};
       
   399 
       
   400 //
       
   401 //	MIp6Hook
       
   402 //
       
   403 class MIp6Hook : public MInetBase
       
   404 /** Abstract IP hook interface.
       
   405 * 
       
   406 * A protocol which binds to the stack as a hook
       
   407 * must implement this interface.
       
   408 *
       
   409 * @warning
       
   410 *	Even though this is a mixin class, all protocol hooks
       
   411 *	<b>MUST</b> be derived from CIp6Hook, which includes MIp6Hook.
       
   412 *	The stack assumes that all hooks use CIp6Hook derived
       
   413 *	classes. This is only for hooks, an upper layer protocol
       
   414 *	can be anything derived from CProtocolBase. However, the
       
   415 *	recommended base class for the upper layer is CProtocolInet6Binder.
       
   416 *	The recommended generic base class for any hook is CProtocolPosthook,
       
   417 *	which inherits from CIp6Hook.
       
   418 *
       
   419 * An IPv6 packet can have several layers of extension headers
       
   420 * to be peeled off, before the actual transport layer is reached.
       
   421 * This process must be done by the installed hooks following this
       
   422 * API. The stack includes default hooks for the obligatory extension
       
   423 * headers (destination, hop-by-hop and routing headers). A hook which
       
   424 * implements an extension header for the protocol number N, attaches
       
   425 * itself to the stack by calling
       
   426 @code
       
   427 	NetworkService()->BindL(this, BindHookFor(N));
       
   428 @endcode
       
   429 * and starts receiving a call to the ApplyL() function for
       
   430 * each protocol header N. It is possible that one packet contains
       
   431 * multiple instances of the header N, and ApplyL is called
       
   432 * for each of them. If multiple hooks register for the same
       
   433 * protocol, they are called sequentially until any of them
       
   434 * handles the header or rejects the packet.
       
   435 *
       
   436 * A hook can also register to be called just before the packet
       
   437 * is going to be passed to the upper layer by calling:
       
   438 @code
       
   439 	NetworkService()->BindL(this, BindHookAll());
       
   440 @endcode
       
   441 * Any number of hooks can register this way and the ApplyL()
       
   442 * is called sequentially until any of them rejects the packet.
       
   443 * If all of them pass the packet, the packet goes to the
       
   444 * upper layer protocol.
       
   445 *
       
   446 * A hook can also process outgoing packets. This type of hook
       
   447 * should implement OpenL(), SetFlowOption() and GetFlowOption().
       
   448 * The outbound processing is totally different from the inbound
       
   449 * processing, and is based on the flow architecture and MFlowHook.
       
   450 * Registerning for outbound flow processing is
       
   451 @code
       
   452 	NetworkService()->BindL(this, BindFlowHook());
       
   453 @endcode
       
   454 * If a hook is interested in packets which the stack would
       
   455 * forward, if forwarding is enabled, there is a binding code
       
   456 * for that too:
       
   457 @code
       
   458 	NetworkService()->BindL(this, BindForwardHook());
       
   459 @endcode
       
   460 * The ApplyL() of the forwarding hook is called for each received
       
   461 * packet, which does not have a destination address of this node
       
   462 * (either unicast or multicast group).
       
   463 *
       
   464 * Finally, a hook can be a post processing hook, which sees raw
       
   465 * packets as they come from the network interfaces (inbound) or are
       
   466 * going out to the interface (outbound).
       
   467 * The base class for a post processing hook should be CProtocolPosthook.
       
   468 * The registering for post processing hook is:
       
   469 @code
       
   470 	NetworkService()->BindL(this, BindPostHook()); // for outbound
       
   471 	NetworkService()->BindL(this, BindPreHook());  // for inbound.
       
   472 @endcode
       
   473 *
       
   474 * All hooks can monitor which interfaces are attached to the stack.
       
   475 * This requires implementing InterfaceAttached() and InterfaceDetached(). 
       
   476 *
       
   477 * @publishedPartner
       
   478 * @released
       
   479 * @since v7.0
       
   480 *
       
   481 * @dontinclude mip6hook.cpp
       
   482 * Example using a hook class
       
   483 * @skip class CHookExample
       
   484 * @until //-
       
   485 * and registering hooks with the stack to handle extension header
       
   486 * in all incoming and outgoing packets:
       
   487 * @skip ::NetworkAttachedL
       
   488 * @until //-
       
   489 */
       
   490 	{
       
   491 public:
       
   492 	inline static TUint BindHookFor(TUint8 aProtocol)
       
   493 		/**
       
   494 		* Gets the ID value for binding as an inbound hook for the
       
   495 		* specified protocol.
       
   496 		* 
       
   497 		* @param aProtocol Protocol number (0..255) for which to get ID
       
   498 		* @return 		   The ID value
       
   499 		*/
       
   500 		{ return KIp6Hook_ANY + aProtocol; }
       
   501 	inline static TUint BindHookAll()
       
   502 		/**
       
   503 		* Gets the ID value for binding as an inbound hook for all protocols.	
       
   504 		* 
       
   505 		* @return	The ID value
       
   506 		*/
       
   507 		{ return 2*KIp6Hook_ANY; }
       
   508 	inline static TUint BindFlowHook(TUint8 aPriority = 1)
       
   509 		/**
       
   510 		* Gets the ID value for binding as an outbound flow hook
       
   511 		* with the specified priority.
       
   512 		* 
       
   513 		* The priority determines the calling order for OpenL() sequence.
       
   514 		* 
       
   515 		* @param aPriority Priority value (allowed range [1..255])
       
   516 		* @return 		   The ID value
       
   517 		*/
       
   518 		{ return 2*KIp6Hook_ANY + Max(Min(KIp6Hook_ANY-1, aPriority), 1); }
       
   519 	inline static TUint BindPostHook()
       
   520 		/**
       
   521 		* Gets the ID value for binding as an outbound packet
       
   522 		* post-processor (below the IP layer).
       
   523 		*
       
   524 		* See CProtocolPosthook.
       
   525 		* 
       
   526 		* @return	The ID value
       
   527 		*/
       
   528 		{ return 3*KIp6Hook_ANY; }
       
   529 	inline static TUint BindPreHook()
       
   530 		/**
       
   531 	 	* Gets the ID value for binding as an inbound packet
       
   532 		* pre-processor (below IP layer)
       
   533 		* 
       
   534 		* See CProtocolPosthook.
       
   535 		* 
       
   536 		* @return	The ID value
       
   537 		*/
       
   538 		{ return BindPostHook()+1; }
       
   539 	inline static TUint BindForwardHook()
       
   540 		/**
       
   541 	 	* Gets the ID value for binding as a forwarding hook
       
   542 		* 
       
   543 		* @return	The ID value
       
   544 		*/
       
   545 		{ return BindPreHook()+1; }
       
   546 	/**
       
   547 	* Processing of incoming packet.
       
   548 	*
       
   549 	* Depending on the how the hook binds to the stack, the stack calls
       
   550 	* this function from different places during the inbound packet
       
   551 	* processing path:
       
   552 	*
       
   553 	* @li
       
   554 	*	to implement new (or just to monitor occurrence of) header, do a bind
       
   555 	*	with BindHookFor(protocol) and the stack calls this function whenever
       
   556 	*	a header of the protocol is encountered within the packet (some headers
       
   557 	*	can appear more than once per packet). The RMBufRecvPacket::iProtocol
       
   558 	*	contains the protocol.
       
   559 	* @li
       
   560 	*	to watch all packets for upper layer protocols, do a bind with
       
   561 	*	BindHookAll() and the stack calls this function for every packet
       
   562 	*	about to be passed on to the upper layer protocol (identified
       
   563 	*	by RMBufRecvPacket::iProtocol).
       
   564 	* @li
       
   565 	*	to watch all packets which stack would forward (or drop if forwarding
       
   566 	*	is disabled), do a bind with BindForwardHook(), and the stack calls
       
   567 	*	this function whenever a packet would be forwarded.
       
   568 	*
       
   569 	* The same hook can request all of the above callbacks. However, then
       
   570 	* the function may have some difficulties in determining the type
       
   571 	* of call from the packet and associated information.
       
   572 	*
       
   573 	* In addition to normal packet parsing (RMBufRecvInfo::iIcmp == 0),
       
   574 	* the ApplyL is also called when processing a returned packet within
       
   575 	* the ICMP error message (RMBufRecvInfo::iIcmp != 0).
       
   576 	*
       
   577 	* The function receives the packet and information about the state of
       
   578 	* its processing.
       
   579 	*
       
   580 	* The hook has three choices of returns as follows:
       
   581 	* 
       
   582 	* @li < 0:
       
   583 	*	The hook dropped or passed the packet elsewhere.
       
   584 	*	The main loop goes to the next packet
       
   585 	* 
       
   586 	* @li #KIp6Hook_PASS (= 0):
       
   587 	*	The hook has completed, and the header is still in the packet, 
       
   588 	*	and has possibly been modified. The main loop continues processing
       
   589 	*	this header with the next hook or protocol
       
   590 	* 
       
   591 	* @li #KIp6Hook_DONE (= 1):
       
   592 	*	The hook has completed, the header has been handled. The 
       
   593 	*	hook is responsible for updating the iOffset and other fields
       
   594 	*	to skip over the processed header.
       
   595 	*	The main loop will restart to process the new protocol.
       
   596 	* 
       
   597 	* In the case of a ICMPv6 Parameter Problem message, the value of the
       
   598 	* aInfo.iParameter is an offset to the problematic value relative to
       
   599 	* the start of the original packet. To check whether the parameter
       
   600 	* problem applies to the current header, the code must test whether
       
   601 	* the offset falls between 
       
   602 @verbatim
       
   603 	0 <= (iParameter + aInfo.iOffsetIp - aInfo.iOffset) < header_length
       
   604 @endverbatim
       
   605 	*
       
   606 	* @param aPacket
       
   607 	*	The received packet. On return, the packet as modified by the hook.
       
   608 	* @param aInfo
       
   609 	*	The packet information. On return, the information as modified by
       
   610 	*	the hook.
       
   611 	* @return
       
   612 	*	Return code, as described above. 
       
   613 	* @leave error
       
   614 	*	The packet is dropped and buffers are released.
       
   615 	*
       
   616 	* Example: @ref doc_example_1
       
   617 	* @dontinclude mip6hook.cpp
       
   618 	* @skip class TExtensionHeader
       
   619 	* @until //-
       
   620 	* Only this hoook knows how to handle it. The stack needs the help of this
       
   621 	* hook for normal packets, and also for processing the returned packet
       
   622 	* inside the ICMP error reports.
       
   623 	* @skip ::ApplyL
       
   624 	* @until //-
       
   625 	*/
       
   626 	virtual TInt ApplyL(RMBufHookPacket &aPacket, RMBufRecvInfo &aInfo) = 0;
       
   627 
       
   628 	/**
       
   629 	* Opening a hook for a flow.
       
   630 	*
       
   631 	* The OpenL is called once at flow opening phase, if the hook has
       
   632 	* registered a flow hook using BindFlowHook() id.
       
   633 	* OpenL must decide whether the flow needs any processing by this hook.
       
   634 	* If yes, it must return with a non-NULL pointer to an instance of
       
   635 	* MFlowHook. The returned handler is attached to the flow until it
       
   636 	* closes,  which event is informed to the hook by the MFlowHook::Close
       
   637 	* method.
       
   638 	*
       
   639 	* @param aHead
       
   640 	*	Contains the address information of the flow.
       
   641 	*	A hook can update this information in the Open phase, if required.
       
   642 	* @param aFlow The flow for which the hook is being activated
       
   643 	* @return
       
   644 	*	MFlowHook pointer (!= NULL), if the hook attaches to the flow using this handler.
       
   645 	*	Returning NULL means that the hook has no interest on this flow.
       
   646 	*
       
   647 	* @leave error (< 0).
       
   648 	*	The flow setup is aborted and the indicated error is passed to
       
   649 	*	the application.
       
   650 	* @leave EFlow_PENDING
       
   651 	*	(leave with anything > 0). The flow setup is aborted and flow
       
   652 	*	is treated as if no route for the destination was available
       
   653 	*	(flow is put into pending state).
       
   654 	*	This may activate additional interface setups.
       
   655 	*
       
   656 	* @note
       
   657 	*	This function has a default implmentation, which returns NULL.
       
   658 	*
       
   659 	* Example: @ref doc_example_1
       
   660 	* Attach to every outbound flow:
       
   661 	* @dontinclude mip6hook.cpp
       
   662 	* @skip ::OpenL
       
   663 	* @until //-
       
   664 	*
       
   665 	* But, then we need to suply the MFlowHook methods as well.
       
   666 	* @skip ::ReadyL
       
   667 	* @until //-
       
   668 	*
       
   669 	* and 
       
   670 	*
       
   671 	* @skip ::ApplyL
       
   672 	* @until //-
       
   673 	*/
       
   674 	virtual MFlowHook *OpenL(TPacketHead &aHead, CFlowContext *aFlow)
       
   675 		{
       
   676 		(void)aHead; (void)aFlow;	// silence compiler warnings
       
   677 		return NULL;
       
   678 		}
       
   679 	/**
       
   680 	* Implements additional flow options in the hook.
       
   681 	*
       
   682 	* When a hook registers for outbound packets, it will also get these calls whenever
       
   683 	* the upper layer uses the GetOption to a flow.
       
   684 	*
       
   685 	* @note
       
   686 	*	 This function has a default implementation, which returns KErrNotSupported.
       
   687 	* @note
       
   688 	*	The flow does not need to be open when this call occurs. If hook implements
       
   689 	*	any options, it should use the CFlowContext::RetrieveOption for the current
       
   690 	*	value of the option.
       
   691 	*
       
   692 	* @param aLevel		The option level code
       
   693 	* @param aName		The option name code
       
   694 	* @retval aOption   The option value (if KErrNone)
       
   695 	* @param aFlow		The flow
       
   696 	* @return error code (KErrNotSupported) or KErrNone
       
   697 	*
       
   698 	* Example: @ref doc_example_1
       
   699 	* The current example port and protocol number can be read by a socket option
       
   700 	* by any application code. Assuming socket is an opened RSocket (for example,
       
   701 	* an UDP socket), then
       
   702 	*
       
   703 	* @code
       
   704 	TPckgBuf<TUint> opt;
       
   705 	RSocket socket;
       
   706 	if (socket.GetOpt(KSoHookExample_PROTOCOL, KSolHookExample, opt) == KErrNone)
       
   707 		{
       
   708 		...
       
   709 		protocol = opt();
       
   710 		...
       
   711 		}
       
   712 	@endcode
       
   713 	*
       
   714 	* enters the GetFlowOption function in the example hook:
       
   715 	* @dontinclude mip6hook.cpp
       
   716 	* @skip ::GetFlowOption
       
   717 	* @until //-
       
   718 	*/
       
   719 	virtual TInt GetFlowOption(TUint aLevel, TUint aName, TDes8 &aOption, const CFlowContext &aFlow) const
       
   720 		{
       
   721 		(void)aLevel; (void)aName; (void)aOption; (void)aFlow;	// silence compiler warnings
       
   722 		return KErrNotSupported;
       
   723 		}
       
   724 	/**
       
   725 	* Implements additional flow options in the hook.
       
   726 	*
       
   727 	* When a hook registers for outbound packets, it will also get these calls whenever
       
   728 	* the upper layer uses the SetOption to a flow.
       
   729 	*
       
   730 	* @note
       
   731 	*	 This function has a default implementation, which returns KErrNotSupported.
       
   732 	* @note
       
   733 	*	The flow does not need to be open when this call occurs. The hook should not store
       
   734 	*	the pointer of the flow. Instead, it should use the CFlowContext::StoreOption to
       
   735 	*	remember the option values.
       
   736 	*
       
   737 	* @param aLevel		The option level code
       
   738 	* @param aName		The option name code
       
   739 	* @param aOption	The option value
       
   740 	* @param aFlow		The flow
       
   741 	* @return error code (KErrNotSupported) or KErrNone
       
   742 	*
       
   743 	* Example: @ref doc_example_1
       
   744 	* The example port and protocol number can be changed by a socket option.
       
   745 	* Assuming socket is an opened RSocket (for example, an UDP socket), then
       
   746 	* @code
       
   747 	TPckgBuf<TUint> opt;
       
   748 	RSocket socket;
       
   749 	opt() = 18;
       
   750 	if (socket.SetOpt(KSoHookExample_PROTOCOL, KSolHookExample, opt) == KErrNone)
       
   751 		{
       
   752 		// Succesfully changed the protocol number!
       
   753 		}
       
   754 	@endcode
       
   755 	*
       
   756 	* enters the SetFlowOption function in the example hook:
       
   757 	* @dontinclude mip6hook.cpp
       
   758 	* @skip ::SetFlowOption
       
   759 	* @until //-
       
   760 	*/
       
   761 	virtual TInt SetFlowOption(TUint aLevel, TUint aName, const TDesC8 &aOption, CFlowContext &aFlow)
       
   762 		{
       
   763 		(void)aLevel; (void)aName; (void)aOption; (void)aFlow;	// silence compiler warnings
       
   764 		return KErrNotSupported;
       
   765 		}
       
   766 	/**
       
   767 	* Monitoring attached interfaces.
       
   768 	*
       
   769 	* A hook can monitor what interfaces are attached
       
   770 	* to the stack by overriding the MIp6Hook::InterfaceAttached and
       
   771 	* MIp6Hook::InterfaceDetached.
       
   772 	*
       
   773 	* The InterfaceAttached is called just after the CNifIfBase
       
   774 	* pointer has  been stored into the internal interface
       
   775 	* instance and CNifIfBase::Open() has been called.
       
   776 	*
       
   777     * @note
       
   778 	*	It is possible to receive InteraceDetached
       
   779 	*	without a matching InterfaceAttached, because interfaces can
       
   780 	*	be up before the hook is active.
       
   781 	*
       
   782 	* @param aName   The name of the interface within the stack
       
   783 	* @param aIf	 The interface
       
   784 	*/
       
   785 	virtual void InterfaceAttached(const TDesC &aName, CNifIfBase *aIf) {(void)aName; (void)aIf;}
       
   786 	/**
       
   787 	* Monitoring attached interfaces.
       
   788 	*
       
   789 	* A hook can monitor what interfaces are attached
       
   790 	* to the stack by overriding the MIp6Hook::InterfaceAttached and
       
   791 	* MIp6Hook::InterfaceDetached.
       
   792 	*
       
   793 	* The InterfaceDetached is called just before the CNifIfBase
       
   794 	* pointer is  going to be removed from the internal interface
       
   795 	* instance and before calling the CNifIfBase::Close().
       
   796 	*
       
   797     * @note
       
   798 	*	It is possible to receive InteraceDetached
       
   799 	*	without a matching InterfaceAttached, because interfaces can
       
   800 	*	be up before the hook is active.
       
   801 	*
       
   802 	* @param aName   The name of the interface within the stack
       
   803 	* @param aIf	 The interface
       
   804 	*/
       
   805 	virtual void InterfaceDetached(const TDesC & aName, CNifIfBase *aIf) {(void)aName; (void)aIf;}
       
   806 	};
       
   807 
       
   808 
       
   809 
       
   810 class CIp6Hook: public CProtocolBaseUnbind, public MIp6Hook
       
   811 /**
       
   812 * The base class of all hook protocols.
       
   813 *
       
   814 * See MIp6Hook and CProtocolBaseUnbind.
       
   815 *
       
   816 * @publishedPartner
       
   817 * @released
       
   818 * @since v7.0
       
   819 */
       
   820 	{
       
   821 public:
       
   822 	/**
       
   823 	* Processes an incoming packet.
       
   824 	* 
       
   825 	* @see MIp6Hook::ApplyL().
       
   826 	* @param aPacket 	Packet to process
       
   827 	* @param aInfo 		Packet information
       
   828 	* @return 			System-wide error code
       
   829 	*/
       
   830 	virtual TInt ApplyL(RMBufHookPacket &aPacket, RMBufRecvInfo &aInfo) = 0;
       
   831 
       
   832 public:
       
   833 	//
       
   834 	// Silence compiler
       
   835 	//
       
   836 	/**
       
   837      * dummy
       
   838      */
       
   839 	void Identify(struct TServerProtocolDesc *) const {}	// should put something here!!
       
   840 	/**
       
   841      * The inbound hooks don't need this really
       
   842      */
       
   843 	void Unbind(CProtocolBase *, TUint) {}		// The inbound hooks don't need this really.
       
   844 	};
       
   845 
       
   846 #endif