class CProtocolPosthook : public CIp6Hook |
Base class for the hooks between IP and NIF.
This is the base class for hooks that live between the IP and NIF layer (post-processing and pre-processing hooks). However, this is also suitable for the base class of any hook. The class provides automatic "network service detection", and supports both binding to and binding from IP6.
The implementations of CProtocolPosthook::BindL and CProtocolPosthook::Unbind handle the "chaining" feature of the post processing hooks. The stack uses a sequence of BindL and Unbind calls when inserting or removing a protocol.
U ---> IP6 F ---> NIF ..Send.. \ / \ ....P -> \ | H1 --> H2 --> ... --> T ...Send...Send...SendThe MNetworkService::Send passes the packet (P) to the CProtocolBase::Send of the first post processing hook (H1). It is the responsibility of H1 to pass the packet to the next post-processing hook (H2). The stack maintains an internal chain terminator (T), which will pass the packet to the NIF using the flow context (F) attached to the packet. The Send does the packet forwarding to the next linked hook automaticly.
The information block associated with the packet is defined by RMBufSendPacket , which always includes a reference to the flow context (F). If a hook before the terminator (T) does not pass the packet forward in chain, then it must also take care of releasing the flow context (RMBufSendInfo::iFlow.Close()).
The flow context is the only way for the terminator (T) to know the target NIF. If the packet has not flow context, the terminator drops the packet. The flow context is detached from the packet before it is passed to the NIF.
NIF --> IP6 IP6 ---> U ..Process..\ | \ ......P -> | \ src=NIF | H1 --> H2 --> .. --> T ..Process..Process..ProcessThe MNetworkService::Process passes the incoming packet to the CProtocolBase::Process of the first pre-processing hook (H1). It is the responsibility of the H1 to pass the packet to the next pre-processing hook (H2). The stack maintains an internal terminator (T), which will pass the packet upwards in the protocol stack. The CProtocolPosthook::Process does the packet forwarding to the next linked hook automaticly.
In the Process chain, the source (CProtocolBase *) is actually a pointer to the NIF object (CNifIfBase). Upon arriving to the terminator (T), the source must still be a valid and known to stack as a NIF (successfully introduced as documented in nif_binding at some earlier point). Otherwise packet is not accepted. The information block is defined by the RMBufPktInfo class. The information block "changes into" RMBufRecvInfo after the terminator (T).
CProtocolPosthook can also be used as a generic base for any hook. Then the following protocol ids for the BindL will become reserved:
MIp6Hook::BindPostHook() (for outbound posthook chaining)
MIp6Hook::BindPreHook() (for inbound posthook chaining)
KProtocolInet6Ip (for the network intance)
KProtocolInetIp (for network instance, deprecated)
BindToL implementation handles KProtocolInet6Ip and KProtocolInetIp targets. This does not do automatic CProtcolBase::BindL to the target (see DoBindToL). The hook binds, if needed, should be done in the NetworkAttachedL function.
Public Member Functions | |
---|---|
TInt | ApplyL(RMBufHookPacket &, RMBufRecvInfo &) |
IMPORT_C void | BindL(CProtocolBase *, TUint) |
IMPORT_C void | BindToL(CProtocolBase *) |
void | NetworkAttachedL() |
void | NetworkDetached() |
MNetworkService * | NetworkService() |
IMPORT_C void | Process(RMBufChain &, CProtocolBase *) |
IMPORT_C TInt | Send(RMBufChain &, CProtocolBase *) |
IMPORT_C void | Unbind(CProtocolBase *, TUint) |
Protected Member Functions | |
---|---|
~CProtocolPosthook() | |
IMPORT_C TInt | DoBindToL(CProtocolBase *) |
Private Attributes | |
---|---|
TUint | iBindToNet |
CProtocolBase * | iInboundHook |
MNetworkService * | iNetwork |
CProtocolBase * | iPostHook |
IMPORT_C | ~CProtocolPosthook | ( | ) | [protected, virtual] |
Destructor
If this object is still attached to the network layer, the attachement and all bindings to the network layer from this protocol object are cancelled.
TInt | ApplyL | ( | RMBufHookPacket & | , |
RMBufRecvInfo & | ||||
) | [inline, virtual] |
If the only hook binding is post or pre-preprocessing, the ApplyL is never called.
RMBufHookPacket & | |
RMBufRecvInfo & |
IMPORT_C void | BindL | ( | CProtocolBase * | aProtocol, |
TUint | aId | |||
) | [virtual] |
Handles network layer binds.
This function handles the network layer detection and posthook chaining binds. The processing is based on the following "well known" id values:
MIp6Hook::BindPostHook() (for outbound posthook chaining)
MIp6Hook::BindPreHook() (for inbound posthook chaining)
KProtocolInet6Ip (aProtocol must be network instance)
KProtocolInetIp (aProtocol must be network instance, deprecated)
If the aId does not match any of the above, the BindL is silently ignored (just return happens). This is quite OK, there is no need to generate an error in such case.
[yourposthook] filename= yourposthook.prt index= 1 bindfrom= ip6
This protocol can be loaded even if network is not. If the protocol provides a SAP functionality, an application can open a socket to this protocol without the network layer being started.
CProtocolBase *iAnother; CProtocolDerivedHook::BindL(CProtocolBase *aProtocol, TUint aId) { if (aId == your_special_binding_protocol) { // handle your bind iAnother = aProtocol; } // The default should always be called, CProtocolPosthook::BindL(aProtocol, aId); }
CProtocolBase * aProtocol | The protocol binding to this. |
TUint aId | The bind id. |
IMPORT_C void | BindToL | ( | CProtocolBase * | aProtocol | ) | [virtual] |
The default implementation.
This implemenation only handles the network bind and leaves with KErrNotSupported if the protocol is not the network instance.
CProtocolDerivedHook::BindToL(CProtocolBase *aProtocol) { const TInt id = DoBindToL(aProtocol); if (id == (TInt)your_special_protocol) { // if (iBindTo) iBindTo->Close(); iBindTo = aProtocol; iBindTo->Open(); // Destructor must issue Close, if iBindTo is non-NULL } else if (id != KErrNone) User::Leave(KErrNotSupported); }
CProtocolBase * aProtocol |
IMPORT_C TInt | DoBindToL | ( | CProtocolBase * | aProtocol | ) | [protected] |
Handle network layer bindto.
Performs the BindToL processing for the network detection. This network layer detection is only used in a configuration, where the "bindto" list of this protocol includes the network layer (ip6). In this configuration, the network layer stays installed whenever this protocol is loaded.
Network can be loaded without this protocol being loaded.
The protocol id is TUint. However, this method is defined to return TInt The function should be considered to return TUint and any non-zero value means that the protocol was not the network. [returning TInt instead of TUint is a mistake].
CProtocolBase * aProtocol | The protocol to bind to. |
void | NetworkAttachedL | ( | ) | [pure virtual] |
Network layer has been attached.
// request inbound packets to my Process() NetworkService()->BindL(this, MIp6Hook::BindPreHook()); // request outbound packets to my Send(). NetworkService()->BindL(this, MIp6Hook::BindPostHook()); ... // stop getting inbound packets to my Process() NetworkService()->Unbind(this, MIp6Hook::BindPreHook()); // stop getting outbound packets to my Send() NetworkService()->Unbind(this, MIp6Hook::BindPostHook()); // ..or, to rip off all my hooks NetworkService()->Unbind(this);
void | NetworkDetached | ( | ) | [inline, virtual] |
Network layer is being detached.
This function is called when the hook is losing the connection to the network instance (the network instance has issued Unbind request, because it is shutting down).
Derived class does not need to implement this, unless it caches network layer dependent data internally. Otherwise, it must implement the function and cleanup all such data.
During the call NetworkService returns the service instance that is going away. However, it should not be used for any binding or unbinding. the detach process does the unbindings automaticly.
The desctuctor can be called while network is attached. CProtocolPosthook destructor will unbind this object automaticly from the network (cancel all binds), and then detaches withouth calling NetworkDetached. Thus, the destructor of the derived class must do the cleanup of cached data, but it does not need to worry about the binds to the network.
MNetworkService * | NetworkService | ( | ) | const [inline] |
Gets the network service.
This returns the network service, if any is currently attached. The network is attached after NetworkAttachedL call until the next NetworkDetached or destruction. Otherwise, network is not attached and return is always NULL.
IMPORT_C void | Process | ( | RMBufChain & | aPacket, |
CProtocolBase * | aSrc | |||
) | [virtual] |
Process incoming packet.
TInt CProtocolDerivedHook::Process(RMBufChain &aPacket, CProtocolBase *aSrc) { // Do own packet processing. RMBufPktInfo *info = RMBufPacketBase::PeekInfoInChain(aPacket); ... if (packet_is_dropped) aPacket.Free(); else CProtocolPosthook::Process(aPacket, aSrc); }Hook will receive and pass forward inbound packets only if it has bound as pre-processing hook:
NetworkService()->BindL(this, MIp6Hook::BindPreHook());
For inbound packets, the aSrc is the NIF object (derived from CNifIfBase and not from CProtocolBase.).
The implementation SHOULD NOT change the aSrc. But, if it does change the source, the new source must also be a NIF pointer, and that NIF must also be known to the TCP/IP stack.
RMBufChain & aPacket | The inbound packet |
CProtocolBase * aSrc | The originating NIF |
IMPORT_C TInt | Send | ( | RMBufChain & | aPacket, |
CProtocolBase * | aSrc | |||
) | [virtual] |
Send packet to the next protocol.
TInt CProtocolDerivedHook::Send(RMBufChain &aPacket, CProtocolBase *aSrc) { ... // Do own packet processing if (packet_is_dropped) { RMBufSendInfo *info = RMBufSendPacket::PeekInfoInChain(aPacket); if (info) info->iFlow.Close(); aPacket.Free(); return 1; } else return CProtocolPosthook::Send(aPacket, aSrc); }Hook will receive and pass forward the outbound packets only if it has a binding to the network layer as a post-processinghook:
NetworkService()->BindL(this, MIp6Hook::BindPostHook());
The network layer currently sends packets with aSrc == NULL. This may change in future (the network instance is used instead).
Hook will receive outbound packets from the network layer only if it binds as post-processing hook.
RMBufChain & aPacket | The outbound packet. |
CProtocolBase * aSrc | The originating protocol (or NULL). |
IMPORT_C void | Unbind | ( | CProtocolBase * | aProtocol, |
TUint | aId | |||
) | [virtual] |
Handles network layer unbinds.
This function handles the network layer unbind and posthook chaining unbinds. The processing is based on the following "well known" bind id values:
MIp6Hook::BindPostHook() (for outbound posthook chaining)
MIp6Hook::BindPreHook() (for inbound posthook chaining)
KProtocolInet6Ip (for the network intance)
KProtocolInetIp (for network instance, deprecated)
0 (unbind all)
If the aId does not match any of the above, the Unbind is silently ignored (just return happens). This is quite OK, there is no need to generate an error in such case.
CProtocolDerivedHook::Unbind(CProtocolBase *aProtocol, TUint aId) { if (iAnother == aProtocol && (aId == 0 || aId == your_special_binding_protocol)) { // handle your unbind iAnotherProtocol = NULL; } // The default should always be called, CProtocolPosthook::Unbind(aProtocol, aId); }
CProtocolBase * aProtocol | The protocol unbinding from this. |
TUint aId | The bind id. |
TUint | iBindToNet | [private] |
The network attachment type. This base class supports both "bind" and "bindto" attachments to the network layer.
if == 1, bindto= ip6 is in the "hook" ESK file. iNetwork has been set by CProtocolPosthook::DoBindToL.
if == 0, bindto= hook is in the [ip6] section of the TCPIP6.ESK. iNetwork has been set by the CProtocolPosthook::BindL.
The value is significant only if iNetwork is non-NULL.
CProtocolBase * | iInboundHook | [private] |
Inbound posthook chain. The next protocol in list. The CProtocolPosthook::BindL and CProtocolPosthook::Unbind implementions maintain this chain based on the calls coming from the network layer. The id reference in the chaining calls is MIp6Hook::BindPreHook().
MNetworkService * | iNetwork | [private] |
The attached network layer (IP layer). The CProtocolPosthook::DoBindToL, CProtocolPosthook::BindL and CProtocolPosthook::Unbind implementations maintain this pointer.
CProtocolBase * | iPostHook | [private] |
Outbound posthook chain. The next protocol in list. The CProtocolPosthook::BindL and CProtocolPosthook::Unbind implementions maintain this chain based on the calls coming from the network layer. The id reference in the chaining calls is MIp6Hook::BindPostHook().
Copyright ©2010 Nokia Corporation and/or its subsidiary(-ies).
All rights
reserved. Unless otherwise stated, these materials are provided under the terms of the Eclipse Public License
v1.0.