networkingtestandutils/ipv6to4tunnel/src/6to4_tunnel.cpp
changeset 0 af10295192d8
--- /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