williamr@2: // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). williamr@2: // All rights reserved. williamr@2: // This component and the accompanying materials are made available williamr@4: // under the terms of "Eclipse Public License v1.0" williamr@2: // which accompanies this distribution, and is available williamr@4: // at the URL "http://www.eclipse.org/legal/epl-v10.html". williamr@2: // williamr@2: // Initial Contributors: williamr@2: // Nokia Corporation - initial contribution. williamr@2: // williamr@2: // Contributors: williamr@2: // williamr@2: // Description: williamr@2: // in6_if.h - control API between the stack and IPv6 interfaces williamr@2: // Specifies the IPv6 extensions for CNifIfBase::Control() API williamr@2: // defined in the standard EPOC header file in_iface.h. williamr@2: // williamr@2: williamr@2: williamr@2: williamr@2: /** williamr@2: @file in6_if.h williamr@2: @publishedAll williamr@2: @released williamr@2: */ williamr@2: williamr@2: #ifndef __IN6_IF_H__ williamr@2: #define __IN6_IF_H__ williamr@2: williamr@2: #include williamr@4: #include williamr@2: williamr@2: // CNifIfBase::Control(aLevel, aName, aOption, ..) williamr@2: // aLevel is KSOLInterface defined in in_iface.h in standard EPOC williamr@2: williamr@2: // IPv6 specific aName constants and aOption structures williamr@2: williamr@2: /** williamr@2: * Option to get the current network interface driver operation parameters to williamr@2: * the passed TSoIfInfo6 structure. williamr@2: * @since v7.0 williamr@2: * @publishedAll williamr@2: * @released williamr@2: */ williamr@2: const TUint KSoIfInfo6 = 0x202; williamr@2: williamr@2: williamr@2: /** williamr@2: * Incoming RMBufPktInfo iFlag value for a loopback packet. williamr@2: * williamr@2: * The stack sets this flag for a packet, which is looped williamr@2: * back by a call to IP layer Process function. A NIF should williamr@2: * never set this flag. williamr@2: * williamr@2: * This flag is effective only when capabilities are enabled. williamr@2: * A packet with this flag set can be delivered to sockets williamr@2: * that do not posses NetworkServices cabability. williamr@2: */ williamr@2: const TUint KIpLoopbackPacket = 0x1; williamr@2: /** williamr@2: * Incoming and outgoing RMBufPktInfo iFlag value for broadcast packet. williamr@2: * williamr@2: * The packet uses link layer broadcast. The stack sets this bit for williamr@2: * outgoing packets that are not unicast (e.g. multicast and broadcast williamr@2: * destinations). A NIF can set this flag for incoming packet, if it williamr@2: * was sent to a link layer broadcast address. The presence of this williamr@2: * flag suppresses some error replies from the stack. williamr@2: */ williamr@2: const TUint KIpBroadcastOnLink = 0x2; williamr@2: williamr@2: williamr@2: /** williamr@2: * A TSoIfInfo::iFeatures flag to indicate that the interface requires Neighbour williamr@2: * Discovery. williamr@2: * williamr@2: * @note williamr@2: * For IPv4 this enables ARP for the interface. The NIF must williamr@2: * pass received ARP packets to the stack, and accept ARP williamr@2: * packets for sending from the stack. williamr@2: * @since v7.0 williamr@2: * @publishedAll williamr@2: * @released williamr@2: */ williamr@2: const TUint KIfNeedsND = 0x00000100; williamr@2: williamr@4: const TUint KMaxInterfaceName=32; williamr@4: williamr@4: /** williamr@4: * Holds the name of a network interface. williamr@4: * williamr@4: * This is used in TSoIfInfo. williamr@4: * williamr@4: */ williamr@4: typedef TBuf TInterfaceName; williamr@4: williamr@4: class TSoIfInfo williamr@4: // Socket option structure for KSoIfInfo williamr@4: /** williamr@4: * Current network interface operation parameters. williamr@4: * williamr@4: * It is returned by RSocket::GetOpt(), when that function is called with anOptionLevel williamr@4: * set to KSOLInterface and anOptionName set to KSoIfInfo. williamr@4: * williamr@4: */ williamr@4: { williamr@4: public: williamr@4: /** Feature flags. Possible values are defined in in_iface.h. */ williamr@4: TUint iFeatures; // Feature flags williamr@4: /** Maximum transmission unit. */ williamr@4: TInt iMtu; // Max frame size williamr@4: /** An approximation of the interface speed in Kbps. */ williamr@4: TInt iSpeedMetric; // Indication of performance, approx to Kbps williamr@4: /** Interface protocol name, ipcp::\. */ williamr@4: TInterfaceName iName; williamr@4: }; williamr@4: williamr@4: williamr@2: class TSoIfInfo6 : public TSoIfInfo // aOption when aName == KSoIfInfo williamr@2: /** williamr@2: * Extends the TSoIfInfo for the receive MTU. williamr@2: * williamr@2: * The IPv6 capable interfaces must support this control option. The usage williamr@2: * template in the stack is: williamr@2: @code williamr@2: CNifIfBase *iNif; williamr@2: ... williamr@2: TPckgBuf ifProp; williamr@2: TInt err = iNif->Control(KSOLInterface, KSoIfInfo6, ifProp); williamr@2: @endcode williamr@2: * For the IPv4 interfaces, only the plain TSoIfInfo is used. williamr@2: @code williamr@2: CNifIfBase *iNif; williamr@2: ... williamr@2: TPckgBuf ifProp; williamr@2: TInt err = iNif->Control(KSOLInterface, KSoIfInfo, ifProp); williamr@2: @endcode williamr@2: * @since v7.0 williamr@2: * @publishedAll williamr@2: * @released williamr@2: */ williamr@2: { williamr@2: public: williamr@2: /** Maximum transmission unit for receiving. */ williamr@2: TInt iRMtu; williamr@2: }; williamr@2: williamr@4: class TSoIfConfigBase williamr@4: /** williamr@4: * Base class for TSoInetIfConfig, which simply identifies the protocol family williamr@4: * using the interface. williamr@4: * williamr@4: * @internalComponent williamr@4: */ williamr@4: { williamr@4: public: williamr@4: /** The protocol family, e.g. KAfInet. */ williamr@4: TUint iFamily; williamr@4: }; williamr@4: williamr@2: class TSoInet6IfConfig : public TSoIfConfigBase williamr@2: /** williamr@2: * IPv6 interface configuration. williamr@2: * williamr@2: * This is the option when stack queries the interface configuration williamr@2: * information using williamr@2: @code williamr@2: TPckgBuf cfg; williamr@2: cfg().iFamily = KAfInet6; // Query about IPv6 capability williamr@2: TInt res = iNif->Control(KSOLInterface, KSoIfConfig, cfg); williamr@2: @endcode williamr@2: * The KErrNone return signifies that this NIF supports IPv6 on the williamr@2: * link layer. Note, similarly, the IPv4 support is detected by the williamr@2: * stack using: williamr@2: @code williamr@2: TPckgBuf cfg; williamr@2: cfg().iFamily = KAfInet; // Query about IPv4 capability. williamr@2: TInt res = iNif->Control(KSOLInterface, KSoIfConfig, cfg); williamr@2: @endcode williamr@2: * The same NIF can support both IPv4 and IPv6. williamr@2: * williamr@2: * @since v7.0 williamr@2: * @publishedAll williamr@2: * @released williamr@2: */ williamr@2: { williamr@2: public: williamr@2: /** williamr@2: * The local interface id. williamr@2: * williamr@2: * If the address family is not KAFUnspec, then this defines the id portion of williamr@2: * the IPv6 addresses for this host. The id portion is used in constructing the williamr@2: * link-local address (fe80::id) and combined with any other prefixes, which williamr@2: * are configured for this interface (prefix::id). Prefixes are configured via williamr@2: * Router Advertisement prefix option (TInet6OptionICMP_Prefix) with the A flag williamr@2: * set, or using interface control socket options (see TSoInet6InterfaceInfo). williamr@2: * williamr@2: * The length of the id is determined by the TSockAddr::GetUserLen. The normal williamr@2: * value is 8 (e.g. the standard id is always 64 bits). Other id lengths are williamr@2: * possibly activated by future RFC's for some special address formats. williamr@2: * williamr@2: * If the address family is KAFUnspec, then id is not configured (and for the williamr@2: * IPv6 interface to be functional, address(es), including the link-local address, williamr@2: * must be configured by some other means). williamr@2: */ williamr@2: TSockAddr iLocalId; williamr@2: /** williamr@2: * The remote interface id (or KAFUnspec, if not applicaple). williamr@2: * williamr@2: * If the address family is not KAFUnspec, then this defines the id portion of williamr@2: * another host on the link. The stack constructs a link-local address williamr@2: * (fe80::remote-id) and installs a host route for it. williamr@2: * williamr@2: * This might be useful for PPP links, if other end is not acting as a router. williamr@2: * If the other end is a router, it's address will become automaticly known, williamr@2: * when it sends the Router Advertisement. williamr@2: */ williamr@2: TSockAddr iRemoteId; williamr@2: /** williamr@2: * Unused highest significant bits in interface id (usually 0). williamr@2: * williamr@2: * This is reserved for future use, in case there is a need for id length williamr@2: * that is not multiple of 8. williamr@2: */ williamr@2: TUint idPaddingBits; williamr@2: /** 1st DNS address (or Unspecified address, if none) */ williamr@2: TInetAddr iNameSer1; williamr@2: /** 2nd DNS address (or Unspecified address, if none) */ williamr@2: TInetAddr iNameSer2; williamr@2: }; williamr@2: williamr@2: /** williamr@2: williamr@2: @page nif_interface The interface between a NIF and the TCP/IP stack. williamr@2: williamr@2: The network interfaces (NIF's) are registered with the stack using the williamr@2: MNifIfUser::IfUserNewInterfaceL function. Stack has an internal object that williamr@2: represents the interface and the given CNifIfBase object is attached to this. williamr@2: williamr@2: The stack communicates with the NIF using the public API defined by the CNifIfBase. williamr@2: The NIF sees the stack as an instance of CProtocolBase and can use a subset of williamr@2: public functions to communcite with the stack. williamr@2: williamr@2: The following CNifBase functions are used by the stack: williamr@2: williamr@2: - CNifIfBase::Open, (binding stack and NIF) williamr@2: - CNifIfBase::Close, (binding stack and NIF) williamr@2: - CNifIfBase::BindL, (binding stack and NIF) williamr@2: - CNifIfBase::Control, (for the configuration information) williamr@2: - CNifIfBase::Info, (retrieve the interface name) williamr@2: - CNifIfBase::Send, (send outbound packets to NIF) williamr@2: - CNifIfBase::Notify, (NIFMAN about packet activity) williamr@2: williamr@2: The following CProtocolBase functions are available for NIFs: williamr@2: williamr@2: - CProtocolBase::StartSending, (notify stack that NIF is ready) williamr@2: - CProtocolBase::Error, (notify stack about NIF error) williamr@2: - CProtocolBase::Process, (feed inbound packets to stack) williamr@2: williamr@2: The network interface is removed from the stack either by directly deleting it, or williamr@2: by NIFMAN using MNifIfUser::IfUserInterfaceDown. williamr@2: williamr@2: A pointer to the MNifIfUser object can be obtained from the network williamr@2: layer protocol. williamr@2: @code williamr@2: MNetworkService *iNetwork; williamr@2: TPckgBuf ifUser; williamr@2: TInt err = iNetwork->Protocol()->GetOption(KNifOptLevel, KNifOptGetNifIfUser, ifUser); williamr@2: @endcode williamr@2: williamr@2: williamr@2: @section nif_binding Binding the NIF and TCP/IP together williamr@2: williamr@2: MNifIfUser::IfUserNewInterfaceL introduces a new network interface (NIF) to the stack. williamr@2: The introduction consists of the following steps: williamr@2: williamr@2: -# retrieve interface info into TNifIfInfo by CNifIfBase::Info function. Stack uses williamr@2: only the interface name (iName) from this. The name cannot be an empty string. williamr@2: -# using the name, the stack searches for a matching internal interface object. If williamr@2: it does not exist, it is created. If there was an existing interface with the same williamr@2: name, the stack will disconnect that first. williamr@2: -# the stack gives itself to the new NIF by calling CNifIfBase::BindL. williamr@2: -# stack does not send any packets to the interface until the NIF has called williamr@2: CProtocolBase::StartSending at least once. williamr@2: -# stack executes the interface configuration when the first CProtocolBase::StartSending arrives williamr@2: after MNifIfUser::IfUserNewInterfaceL. The configuration uses the CNifIfBase::Control function williamr@2: with different options to retrieve additional information from the NIF. williamr@2: williamr@2: MNifIfUser::IfUserInterfaceDown disconnects the NIF from the stack. There is one williamr@2: exception: if the MNifIfUser::IfUserInterfaceDown aResult parameter has a special williamr@2: value #KErrLinkConfigChanged, then the internal interface state is only reset to the williamr@2: exact same state as if interface was just introduced by the williamr@2: MNifIfUser::IfUserNewInterfaceL, and a reconfiguration occurs when the NIF calls williamr@2: StartSending. williamr@2: williamr@2: @section nif_control_api The Control API williamr@2: williamr@2: The stack requires the NIF to implement a minimal set of #KSOLInterface level williamr@2: options via it's CNifIfBase::Control API. williamr@2: williamr@2: - at least one of the information options williamr@2: - TSoIfInfo6 with #KSoIfInfo6 (for IPv6) williamr@2: - TSoIfInfo with #KSoIfInfo (for IPv4) williamr@2: . williamr@2: - at least one of the configuration options williamr@2: - TSoInet6IfConfig (iFamily=#KAfInet6) with #KSoIfConfig williamr@2: - TSoInetIfConfig (iFamily=#KAfInet) with #KSoIfConfig williamr@2: . williamr@2: - TSoIfHardwareAddr with #KSoIfHardwareAddr if the link williamr@2: uses hardware addresses (only used #KIfNeedsND is also set.). The returned williamr@2: address is used in the neighbor discovery (ICMPv6 ND or ARP for IPv4), and williamr@2: in sending packets to NIF, the address family is used to indicate that the williamr@2: stack has chosen the destination link layer address (based on the neighbor williamr@2: cache). williamr@2: - TSoIfConnectionInfo with #KSoIfGetConnectionInfo (for IAP and NET numbers). williamr@2: If this is not supported, the stack will assign unique numbers for the williamr@2: IAP and NET. The scope vector (zone identifiers) is contructed as follows: williamr@2: -# [0] The unique interface index (node local scope id) williamr@2: -# [1] IAP number (link scope id) williamr@2: -# [2] IAP number (subnet scope id) williamr@2: -# [3] NET number williamr@2: -# [4] NET number (site local scope id) williamr@2: -# [5] NET number williamr@2: -# [6] NET number williamr@2: -# [7] NET number (organization scope id) williamr@2: -# [8] NET number williamr@2: -# [9] NET number williamr@2: -# [10] NET number williamr@2: -# [11] NET number williamr@2: -# [12] NET number williamr@2: -# [13] NET number (IPv6 global scope) williamr@2: -# [14] NET number williamr@2: -# [15] NET number (highest, NET id, IPv4 global) williamr@2: williamr@2: @note williamr@2: To build complete ARP packets in the stack, stack needs to know the hardware williamr@2: type value to be used in the packet (see TInet6HeaderArp). This 16 bit value williamr@2: is assumed to be in the Port() field of the returned hardware address williamr@2: (#KSoIfHardwareAddr). An IPv4 NIF that leaves the ARP to the stack, williamr@2: must provide this value (or sniff and fix the outgoing ARP packets). williamr@2: williamr@2: @section nif_inbound_packets Inbound packets from the NIF to stack. williamr@2: williamr@2: The NIF feeds the inbound packets to the stack through the CProtocolBase::Process williamr@2: function (see also MNetworkService::Process). The information block associated williamr@2: with the packet is RMBufPktInfo and the fields must have been set as follows: williamr@2: williamr@2: - RMBufPktInfo::iSrcAddr, the link layer source address (using the same williamr@2: address family as returned with the hardware address control option). If williamr@2: the link does not use addresses, then #KAFUnspec should be used. williamr@2: - RMBufPktInfo::iDstAddr, the link layer destination address (using the same williamr@2: address family as returned with the hardware address control option). If williamr@2: the link does not use addresses, then #KAFUnspec should be used. williamr@2: - RMBufPktInfo::iProtocol, the type of the packet: williamr@2: - #KProtocolInetIp, IPv4 packet williamr@2: - #KProtocolInet6Ip, IPv6 packet williamr@2: - #KProtocolArp, ARP packet williamr@2: . williamr@2: - RMBufPktInfo::iLength, the length of the packet in octets williamr@2: - RMBufPktInfo::iFlags, should be set to zero (reserved for future use). williamr@2: williamr@2: @note williamr@2: The stack is relaxed about the checking of iProtocol field, and anything williamr@2: else except #KProtocolArp is assumed to be an IP packet. This is potentially williamr@2: to changed in future, and NIFs should set the protocol field correctly. williamr@2: @note williamr@2: The link layer addresses in iSrcAddr and iDstAddr are informative. The williamr@2: values do not affect the processing of the packet within stack. They are williamr@2: made available for the inbound post hooks (CProtocolPosthook). williamr@2: williamr@2: @section nif_outbound_packets Outbound packets from the stack to NIF williamr@2: williamr@2: The stack feeds the outbound packets to the NIF through the CNifIfBase::Send williamr@2: function. The information block associated with the packet follows RMBufPktInfo williamr@2: and the fields need to be interpreted as follows: williamr@2: williamr@2: - RMBufPktInfo::iSrcAddr, undefined (must be ignored by the NIF). williamr@2: The NIF must choose the link layer source address. williamr@2: - RMBufPktInfo::iDstAddr, three variants, if link layer addresses are used williamr@2: - hardware address, using the same address family as NIF returned williamr@2: in harware address control option (TSoIfHardwareAddr ). williamr@2: The packet must be sent to this link layer destination. williamr@2: - #KAfInet, the address is IPv4 multicast address. and the NIF must williamr@2: select a suitable link layer broadcast address as a destination. williamr@2: - #KAfInet6, the address is IPv6 multicast address, and the NIF msut williamr@2: select a suitable link layer broadcast address as a destination. williamr@2: . williamr@2: If the NIF does not use link layer addresses, then iDstAddr is also williamr@2: undefined (must be ingnored byt the NIF). The link is a point-to-point williamr@2: interface. williamr@2: - RMBufPktInfo::iProtocol, defines the type of packet williamr@2: - #KProtocolInetIp, IPv4 packet williamr@2: - #KProtocolInet6Ip, IPv6 packet williamr@2: - #KProtocolArp, ARP packet williamr@2: . williamr@2: - RMBufPktInfo::iLength, the length of the packet in octets. williamr@2: - RMBufPktInfo::iFlags, undefined (must be igrnored by the NIF). williamr@2: williamr@2: The stack interprets the return value from the CNifIfBase::Send as follows: williamr@2: williamr@2: - return 1; the NIF is ready to receive more packets. williamr@2: - return 0; the NIF is blocked and cannot receive any more packets. The stack williamr@2: does not send anything to the NIF until it calls CProtocolBase::StartSending. williamr@2: - return < 0; unspecified, but currently, the error is passed on to williamr@2: all flows attached to this interface. The stack will continue sending williamr@2: packets to the interface (no StartSending is required). williamr@2: - return > 1; unspecified, but currently treated same as return 1. williamr@2: williamr@2: */ williamr@2: williamr@2: #endif