diff -r 000000000000 -r af10295192d8 networksecurity/ipsec/ipsec6/src/ipaddress.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/networksecurity/ipsec/ipsec6/src/ipaddress.cpp Tue Jan 26 15:23:49 2010 +0200 @@ -0,0 +1,235 @@ +// Copyright (c) 2005-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: +// ipaddress.cpp - Basic IP address class for IPSEC use +// @internalComponent for IPSEC +// + +#include "ipaddress.h" + +TInt TIpAddress::operator==(const TIpAddress &aAddr) const + /** + * Equality operator. + * + * Two TIpAddress are equal if the TIp6Addr part matches + * exactly (TIp6addr::IsEqual()), and either scope id's + * are equal or either one is zero, which acts as a wild + * card. + * + * @param aAddr The other address. + */ + { + // iScope == 0 acting as a "wildcard" is *DUBIOUS* for == operator. need to check -- msa + return IsEqual(aAddr) && (iScope == aAddr.iScope || iScope == 0 || aAddr.iScope == 0); + } + +TBool TIpAddress::operator<=(const TIpAddress &aAddr) const + /** + * Relation operator. + * + * The presense of the scope confuse the issue. The nature of the + * scope id is such, that only exact equality test makes sense. + * + * Thus, the "<=" is true if one address is less or equal to the + * other, and if scope ids are equal or either one is zero, which acts + * as a wild card. + * + * Thus, EFalse return does not mean that the other address + * is "larger", e.g. it is possible that + * @code (addr1 <= addr2 || addr2 <= addr1) + * @endcode + * is false; addresses are not comparable (because scope ids do not match). + */ + { + return + (iScope == 0 || aAddr.iScope == 0 || iScope == aAddr.iScope) && + Mem::Compare(&u.iAddr8[0], 16, &aAddr.u.iAddr8[0], 16) <= 0; + } + +TInt TIpAddress::operator!=(const TIpAddress &aAddr) const + { + return ! (*this == aAddr); + } + +TBool TIpAddress::IsEqMask(const TIpAddress &aAddr, const TIpAddress &aMask) const + /** + * Compare address under mask. + * + * Tests if + * @code (*this & aMask) == (aAddr & aMask) + * @endcode + * is true. + * + * @param aAddr The other address. + * @param aMask The mask. + * @return ETrue, if equal. + */ + { + return + ((u.iAddr32[0] ^ aAddr.u.iAddr32[0]) & aMask.u.iAddr32[0]) == 0 && + ((u.iAddr32[1] ^ aAddr.u.iAddr32[1]) & aMask.u.iAddr32[1]) == 0 && + ((u.iAddr32[2] ^ aAddr.u.iAddr32[2]) & aMask.u.iAddr32[2]) == 0 && + ((u.iAddr32[3] ^ aAddr.u.iAddr32[3]) & aMask.u.iAddr32[3]) == 0 && + ((iScope ^ aAddr.iScope) & aMask.iScope) == 0; + } + +TBool TIpAddress::IsMulticast() const + /** + * Test if address is multicast address. + * + * The base class TIp6Addr::IsMulticast() returns true only for + * real IPv6 multicast addresses. This function expands the test + * to work also for IPv4 multicast addresses, which are stored + * as IPv4 mapped format. + * + * @return True, if address is multicast (IPv4 or IPv6). + */ + { + static const union {TUint8 a[4]; TUint32 b;} v4Prefix = { {0, 0, 0xff, 0xff} }; + + // TRUE, if real IPv6 multicast + if (TIp6Addr::IsMulticast()) + return TRUE; + // + // Otherwise, return TRUE, if address is the IPv4 + // multicast address. + return + u.iAddr32[0] == 0 && + u.iAddr32[1] == 0 && + u.iAddr32[2] == v4Prefix.b && + (u.iAddr8[12] & 0xF0) == 0xE0; + } + + +TInt TIpAddress::SetAddress(const TDesC &aStr, TInt aMask) + /** + * Set address from a string + * + * Take a string as a parameter and attempt to parse this as + * an IP address. + * + * The aMask setting is needed when IP address is used + * as a bit mask. IPv4 addresses are expanded into IPv4 mapped format. + * This would not work right when address is used as a mask, and thus a + * special flag is required. + * + * @param aStr Literal IPv4 or IPv6 address + * @param aMask Non-zero, if address is to be used as a bitmask + * @return KErrNone, if address literal was valid. + */ + { + TInetAddr addr; + const TInt ret = addr.Input(aStr); + if (ret == KErrNone) + return aMask ? SetMask(addr) : SetAddress(addr); + return ret; + } + +TInt TIpAddress::SetMask(const TSockAddr &aAddr) + /** + * Set address to be used as a mask. + * + * This function is needed. when aAddr contains a IPv4 + * address. The resulting IPv4 mapped format would not + * be usable as mask bits, and the high order bits must + * also be set. + * + * @param aAddr The mask + * @return KErrNone + */ + { + const TInetAddr &addr = TInetAddr::Cast(aAddr); + + if (addr.Family() == KAfInet || addr.IsV4Mapped()) + { + // Loading IPv4 address requires some extra shuffles.. + SetAddress(addr.Address()); + // When an IPv4 address intended to be a mask is converted + // to IPv6 address, the rest of IPv6 address bits must + // be set to all ones too. + u.iAddr32[0] = ~0U; + u.iAddr32[1] = ~0U; + u.iAddr32[2] = ~0U; + } + else + (TIp6Addr &)*this = addr.Ip6Address(); + iScope = addr.Scope(); + return KErrNone; + } + +TInt TIpAddress::SetAddress(const TSockAddr &aAddr) + /** + * Set address. + * + * @param aAddr The address. + * @return KErrNone + */ + { + const TInetAddr &addr = TInetAddr::Cast(aAddr); + if (addr.Family() == KAfInet) + // Loading IPv4 address requires some extra shuffles.. + SetAddress(addr.Address()); + else + { + (TIp6Addr &)*this = addr.Ip6Address(); + } + iScope = addr.Scope(); + return KErrNone; + } + +void TIpAddress::SetAddressNone() + /** + * Set address to none. + * + * Fill with zeroes. + */ + { + (TIp6Addr &)*this = KInet6AddrNone; + iScope = 0; + } + +void TIpAddress::SetAddress(const TIp6Addr &aAddr, const TUint32 aScope) + /** + * Set address. + * + * @param aAddr The IPv6 address + * @param aScope The scope id. + */ + { + (TIp6Addr &)*this = aAddr; + iScope = aScope; + } + +void TIpAddress::SetAddress(const TUint32 aAddr) + /** + * Set address. + * + * Set address from IPv4 address. + * + * @param aAddr The IPv4 address + */ + { + u.iAddr32[0] = 0; + u.iAddr32[1] = 0; + u.iAddr8[8] = 0; + u.iAddr8[9] = 0; + u.iAddr8[10] = 0xff; + u.iAddr8[11] = 0xff; + + u.iAddr8[12] = (TUint8)(aAddr >> 24); + u.iAddr8[13] = (TUint8)(aAddr >> 16); + u.iAddr8[14] = (TUint8)(aAddr >> 8); + u.iAddr8[15] = (TUint8)aAddr; + // The scope id is not set? should clear it? + } +