diff -r 000000000000 -r af10295192d8 networkingtestandutils/ipv6to4tunnel/src/6to4_tunnel.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/networkingtestandutils/ipv6to4tunnel/src/6to4_tunnel.cpp Tue Jan 26 15:23:49 2010 +0200 @@ -0,0 +1,528 @@ +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// Name : 6to4_tunnel.cpp +// Part of : 6to4 plugin / 6to4.prt +// Implements 6to4 automatic and configured tunnels, see +// RFC 3056 & RFC 2893 +// Version : 0.2 +// + + + + +// INCLUDE FILES +#include "6to4_tunnel.h" + +// EXTERNAL DATA STRUCTURES +// EXTERNAL FUNCTION PROTOTYPES +// CONSTANTS +// MACROS +// LOCAL CONSTANTS AND MACROS +// MODULE DATA STRUCTURES +// LOCAL FUNCTION PROTOTYPES +// FORWARD DECLARATIONS + +// ============================= LOCAL FUNCTIONS ============================== + +// ---------------------------------------------------------------------------- +// TInetAddress6Only +// A simple help class which overrides the Input method and +// guarantees that the result is always KAfInet6 on valid +// input. +// ---------------------------------------------------------------------------- +class TInetAddr6Only : public TInetAddr + { + public: + TInt Input(const TDesC &aBuf); + }; + +TInt TInetAddr6Only::Input(const TDesC &aBuf) + { + const TInt ret = TInetAddr::Input(aBuf); + if (ret == KErrNone && Family() == KAfInet) + ConvertToV4Mapped(); + return ret; + } + +// ============================ MEMBER FUNCTIONS ============================== + +// ---------------------------------------------------------------------------- +// CTunnel::CTunnel +// C++ default constructor can NOT contain any code, that +// might leave. +// ---------------------------------------------------------------------------- +// +CTunnel::CTunnel () + { + } + +// Destructor +CTunnel::~CTunnel () + { + delete iName; + } + +// ---------------------------------------------------------------------------- +// CTunnel::SetNameL +// Sets a name for the tunnel. +// ---------------------------------------------------------------------------- +// +void CTunnel::SetNameL (const TDesC & aName) + { + delete iName; + iName = NULL; + iName = HBufC::NewMaxL (aName.Length ()); + *iName = aName; + } + +// ---------------------------------------------------------------------------- +// TTunnelParser::TTunnelParser +// C++ default constructor can NOT contain any code, that +// might leave. +// ---------------------------------------------------------------------------- +// +TTunnelParser::TTunnelParser () : iToken(), iTokenVal(0), iTunnelQueue() + { + iTunnelQueue.SetOffset (_FOFF (CTunnel, iDLink)); + } + +// Destructor +TTunnelParser::~TTunnelParser () + { + CTunnel *tunnel = NULL; + TTunnelQueueIter iter (iTunnelQueue); + + while ((tunnel = iter++) != NULL) + { + tunnel->iDLink.Deque(); + delete tunnel; + } + } + +// ---------------------------------------------------------------------------- +// TTunnelParser::ParseL +// Parses the tunnel configuration file and creates tunnel objects accordingly. +// +// File syntax example. +// Keywords: tunnels, tunnel, endpoint_address, virtual_if_address, +// route_address, route_prefix_length, STRING, INTEGER. +// # +// # Write comments like this to the beginning of the file +// # +// +// tunnels = { +// tunnel_1, +// tunnel_2, +// tunnel_3 +// } +// +// tunnel tunnel_1 = { +// STRING endpoint_address = 192.168.0.3, +// STRING virtual_if_address = 2000:abcd::1, +// STRING route_address = 2000:abcd::, +// INTEGER route_prefix_length = 32 +// } +// +// tunnel tunnel_2 = { +// STRING endpoint_address = 192.168.0.3, +// STRING virtual_if_address = 2000:1111::1, +// STRING route_address = 2000:1111::, +// INTEGER route_prefix_length = 32 +// } +// +// tunnel tunnel_3 = { +// STRING endpoint_address = 192.168.0.5, +// STRING virtual_if_address = 2000:2222::1, +// STRING route_address = 2000:2222::, +// INTEGER route_prefix_length = 32 +// } +// ---------------------------------------------------------------------------- +// +TInt TTunnelParser::ParseL (const TDesC & aTunnelData) + { + + Assign (aTunnelData); + + // Parse the list of tunnels first and create and add them to the list. + TTokenType token; + + while ((token = NextToken()) == ETokenTypeComment) + { + // Intentionally left blank + } + if (token == ETokenTypeString) + { + if (iToken.Compare (_L ("tunnels")) != 0) + { + return KErrGeneral; + } + } + else + { + return token == ETokenTypeEof ? KErrNone : KErrGeneral; + } + + if ((token = NextToken ()) != ETokenTypeEqual) + { + return KErrGeneral; + } + + if ((token = NextToken ()) != ETokenTypeBraceLeft) + { + return KErrGeneral; + } + + do + { + token = NextToken (); + if (token == ETokenTypeBraceRight) + { + // Tunnels done + break; + } + + if (token == ETokenTypeString) + { + CTunnel *tunnel = new (ELeave) CTunnel; + + tunnel->SetNameL (iToken); + + iTunnelQueue.AddLast (*tunnel); + } + else + { + return KErrGeneral; + } + } + while ((token = NextToken ()) == ETokenTypeComma); + + if (token != ETokenTypeBraceRight) + { + return KErrGeneral; + } + + // Parse individual tunnels. Search for the list for a match and if + // found, add parameters there. + while ((token = NextToken ()) == ETokenTypeString) + { + if (iToken.Compare (_L ("tunnel")) != 0) + { + return KErrGeneral; + } + + TInetAddr6Only address; + CTunnel *tunnel = NULL; + + if ((token = NextToken ()) == ETokenTypeString) + { + TTunnelQueueIter iter (iTunnelQueue); + + while ((tunnel = iter++) != NULL) + { + if (tunnel->Name().Compare (iToken) == 0) + { + // found. + break; + } + } + if (tunnel == NULL) + { + return KErrGeneral; + } + } + else + { + return KErrGeneral; + } + + if ((token = NextToken ()) != ETokenTypeEqual) + { + return KErrGeneral; + } + + if ((token = NextToken ()) != ETokenTypeBraceLeft) + { + return KErrGeneral; + } + + if ((token = NextToken ()) == ETokenTypeString) + { + if (iToken.Compare (_L ("STRING")) != 0) + { + return KErrGeneral; + } + } + else + { + return KErrGeneral; + } + + if ((token = NextToken ()) == ETokenTypeString) + { + if (iToken.Compare (_L ("endpoint_address")) != 0) + { + return KErrGeneral; + } + } + else + { + return KErrGeneral; + } + + if ((token = NextToken ()) != ETokenTypeEqual) + { + return KErrGeneral; + } + + if ((token = NextToken ()) == ETokenTypeString) + { + // Parse endpoint address + if (address.Input (iToken) != KErrNone) + { + return KErrGeneral; + } + tunnel->EndpointAddr().SetAddress (address.Ip6Address(), address.Scope()); + } + else + { + return KErrGeneral; + } + + if ((token = NextToken ()) != ETokenTypeComma) + { + return KErrGeneral; + } + + if ((token = NextToken ()) == ETokenTypeString) + { + if (iToken.Compare (_L ("STRING")) != 0) + { + return KErrGeneral; + } + } + else + { + return KErrGeneral; + } + + if ((token = NextToken ()) == ETokenTypeString) + { + if (iToken.Compare (_L ("virtual_if_address")) != 0) + { + return KErrGeneral; + } + } + else + { + return KErrGeneral; + } + + if ((token = NextToken ()) != ETokenTypeEqual) + { + return KErrGeneral; + } + + if ((token = NextToken ()) == ETokenTypeString) + { + // Parse inner virtual address + if (address.Input (iToken) != KErrNone) + { + return KErrGeneral; + } + tunnel->VirtualIfAddr().SetAddress(address.Ip6Address(), address.Scope()); + } + else + { + return KErrGeneral; + } + + if ((token = NextToken ()) != ETokenTypeComma) + { + return KErrGeneral; + } + + if ((token = NextToken ()) == ETokenTypeString) + { + if (iToken.Compare (_L ("STRING")) != 0) + { + return KErrGeneral; + } + } + else + { + return KErrGeneral; + } + + if ((token = NextToken ()) == ETokenTypeString) + { + if (iToken.Compare (_L ("route_address")) != 0) + { + return KErrGeneral; + } + } + else + { + return KErrGeneral; + } + + if ((token = NextToken ()) != ETokenTypeEqual) + { + return KErrGeneral; + } + + if ((token = NextToken ()) == ETokenTypeString) + { + // Parse route prefix as "address" + if (address.Input (iToken) != KErrNone) + { + return KErrGeneral; + } + tunnel->RouteAddr() = address.Ip6Address(); + } + else + { + return KErrGeneral; + } + + if ((token = NextToken ()) != ETokenTypeComma) + { + return KErrGeneral; + } + + if ((token = NextToken ()) == ETokenTypeString) + { + if (iToken.Compare (_L ("INTEGER")) != 0) + { + return KErrGeneral; + } + } + else + { + return KErrGeneral; + } + + if ((token = NextToken ()) == ETokenTypeString) + { + if (iToken.Compare (_L ("route_prefix_length")) != 0) + { + return KErrGeneral; + } + } + else + { + return KErrGeneral; + } + + if ((token = NextToken ()) != ETokenTypeEqual) + { + return KErrGeneral; + } + + if (Val (iTokenVal) != KErrNone) + return KErrGeneral; + tunnel->SetRoutePrefixLength(iTokenVal); + + if ((token = NextToken ()) != ETokenTypeBraceRight) + { + return KErrGeneral; + } + } + + // Scan through the list and make sure all tunnels have been configured. + TTunnelQueueIter iter (iTunnelQueue); + CTunnel *tunnel = NULL; + + while ((tunnel = iter++) != NULL) + { + if (tunnel->EndpointAddr().IsUnspecified ()) + { + // not configured. + return KErrGeneral; + } + } + + return KErrNone; + } + +// ---------------------------------------------------------------------------- +// TTunnelParser::NextToken +// Returns the next token type in the input stream. iToken gets the value of +// the (string) token. +// ---------------------------------------------------------------------------- +// +TTunnelParser::TTokenType TTunnelParser::NextToken () + { + TChar ch; + TTokenType val; + + SkipSpaceAndMark (); + if (Eos ()) + val = ETokenTypeEof; + else + { + ch = Get (); + switch (ch) + { + case '{': + val = ETokenTypeBraceLeft; + break; + case '}': + val = ETokenTypeBraceRight; + break; + case '(': + val = ETokenTypeParLeft; + break; + case ')': + val = ETokenTypeParRight; + break; + case '=': + val = ETokenTypeEqual; + break; + case ',': + val = ETokenTypeComma; + break; + case '#': + val = ETokenTypeComment; + while (!Eos()) + { + ch = Get(); + if (ch == '\n' || ch == '\r') + break; + } + break; + default: + // Integers, ip addresses, etc. are mapped to strings. + val = ETokenTypeString; + while (!Eos ()) + { + ch = Peek (); + if (ch == '{' || ch == '}' || + ch == '(' || ch == ')' || + ch == '=' || ch == '#' || + ch == ',' || ch.IsSpace ()) + break; + Inc (); + } + } + } + + iToken.Set (MarkedToken ()); + SkipSpaceAndMark (); + + return val; + } + +// ========================== OTHER EXPORTED FUNCTIONS ======================== + +// End of File