vpnengine/ikev2lib/src/ikev2trafficselector.cpp
changeset 0 33413c0669b9
equal deleted inserted replaced
-1:000000000000 0:33413c0669b9
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 #include "ikev2trafficselector.h"
       
    19 #include "ikev2const.h"
       
    20 #include "ikev2payloads.h"
       
    21 
       
    22 TIkeV2TrafficSelector* TIkeV2TrafficSelector::NewL(const TDesC8& aIkeV2TrafficSector)
       
    23     {    
       
    24     static const TUint16 KIpv4SelectorLength = 16;
       
    25     static const TUint16 KIpv6SelectorLength = 48;
       
    26 
       
    27     if (aIkeV2TrafficSector.Length() != KIpv4SelectorLength &&
       
    28         aIkeV2TrafficSector.Length() != KIpv6SelectorLength)
       
    29         {
       
    30         User::Leave(KErrArgument);
       
    31         }
       
    32         
       
    33     
       
    34     const TTrafficSelector* selector = 
       
    35             reinterpret_cast<const TTrafficSelector*>(aIkeV2TrafficSector.Ptr());
       
    36         
       
    37 
       
    38     TInetAddr startAddr;
       
    39     TInetAddr endAddr;
       
    40     
       
    41     const TUint8* addresses = selector->Addresses();
       
    42     if ( selector->Type() ==  TS_IPV4_ADDR_RANGE )
       
    43         {
       
    44         if (aIkeV2TrafficSector.Length() != KIpv4SelectorLength)
       
    45             {
       
    46             User::Leave(KErrArgument);
       
    47             }        
       
    48         TUint32 startA = *(reinterpret_cast<const TUint32*>(addresses));
       
    49         TUint32 endA = *(reinterpret_cast<const TUint32*>(addresses + 4));
       
    50         
       
    51         BigEndian::Put32(reinterpret_cast<TUint8*>(&startA), startA);
       
    52         BigEndian::Put32(reinterpret_cast<TUint8*>(&endA), endA);
       
    53         
       
    54         startAddr.SetAddress(startA);              
       
    55         endAddr.SetAddress(endA);
       
    56         
       
    57         }
       
    58     else
       
    59         {
       
    60         if (aIkeV2TrafficSector.Length() != KIpv6SelectorLength ||
       
    61             selector->Type() !=  TS_IPV6_ADDR_RANGE)
       
    62             {
       
    63             User::Leave(KErrArgument);
       
    64             }
       
    65         TIp6Addr startA;
       
    66         TIp6Addr endA;
       
    67         
       
    68         Mem::Copy(startA.u.iAddr8, addresses, 16);
       
    69         Mem::Copy(endA.u.iAddr8, addresses+16, 16);
       
    70 
       
    71         startAddr.SetAddress(startA);              
       
    72         endAddr.SetAddress(endA);        
       
    73         }
       
    74 
       
    75     TUint16 startPort = selector->StartPort();
       
    76     BigEndian::Put16(reinterpret_cast<TUint8*>(&startPort), startPort);
       
    77     startAddr.SetPort(startPort);
       
    78     
       
    79     TUint16 endPort = selector->EndPort();
       
    80     BigEndian::Put16(reinterpret_cast<TUint8*>(&endPort), endPort);
       
    81     endAddr.SetPort(endPort);
       
    82     
       
    83     return new (ELeave) TIkeV2TrafficSelector(startAddr, endAddr, selector->Protocol());       
       
    84     }
       
    85 
       
    86 
       
    87 TIkeV2TrafficSelector::TIkeV2TrafficSelector(TInetAddr aStartingAddress, TInetAddr aEndingAddress, TUint8 aProtocolId)
       
    88 :iStartingAddress(aStartingAddress), iEndingAddress(aEndingAddress), iProtocolId(aProtocolId)
       
    89     {
       
    90     __ASSERT_DEBUG(iStartingAddress.Family() == iEndingAddress.Family() &&
       
    91                    iStartingAddress.IsV4Compat() == iEndingAddress.IsV4Compat() &&
       
    92                    iStartingAddress.IsV4Mapped() == iEndingAddress.IsV4Mapped(), User::Invariant());
       
    93     
       
    94     iMask = CalcuateMask();
       
    95     }
       
    96 
       
    97 
       
    98 TIkeV2TrafficSelector::TIkeV2TrafficSelector(const TIkeV2TrafficSelector& aTrafficSelector)
       
    99     {
       
   100     iStartingAddress = aTrafficSelector.iStartingAddress;
       
   101     iEndingAddress = aTrafficSelector.iEndingAddress;
       
   102     
       
   103     iProtocolId = aTrafficSelector.iProtocolId;
       
   104     
       
   105     __ASSERT_DEBUG(iStartingAddress.Family() == iEndingAddress.Family() &&
       
   106                    iStartingAddress.IsV4Compat() == iEndingAddress.IsV4Compat() &&
       
   107                    iStartingAddress.IsV4Mapped() == iEndingAddress.IsV4Mapped(), User::Invariant());
       
   108     iMask = CalcuateMask();    
       
   109     }
       
   110 
       
   111 
       
   112 TInetAddr TIkeV2TrafficSelector::StartingAddress() const
       
   113     {
       
   114     return iStartingAddress;
       
   115     }   
       
   116 
       
   117 
       
   118 TInetAddr TIkeV2TrafficSelector::EndingAddress() const
       
   119     {
       
   120     return iEndingAddress;
       
   121     }
       
   122     
       
   123 TInetAddr TIkeV2TrafficSelector::Mask() const
       
   124     {
       
   125     return iMask;
       
   126     }
       
   127 
       
   128 TUint8 TIkeV2TrafficSelector::ProtocolId() const
       
   129     {
       
   130     return iProtocolId;
       
   131     }
       
   132 
       
   133 TUint8 TIkeV2TrafficSelector::Type() const
       
   134     {
       
   135     __ASSERT_DEBUG(iStartingAddress.Family() == iEndingAddress.Family() &&
       
   136                    iStartingAddress.IsV4Compat() == iEndingAddress.IsV4Compat() &&
       
   137                    iStartingAddress.IsV4Mapped() == iEndingAddress.IsV4Mapped(), User::Invariant());
       
   138     
       
   139     if (iStartingAddress.Family() == KAfInet ||
       
   140         iStartingAddress.IsV4Compat() ||
       
   141         iStartingAddress.IsV4Mapped())
       
   142         {
       
   143         return TS_IPV4_ADDR_RANGE;
       
   144         }
       
   145     else
       
   146         {
       
   147         return TS_IPV6_ADDR_RANGE;
       
   148         }
       
   149     }
       
   150 
       
   151 
       
   152 HBufC8* TIkeV2TrafficSelector::IdFromTsL() const
       
   153     {
       
   154     TInetAddr idAddr = iStartingAddress;
       
   155     idAddr.SetPort(0);
       
   156     TInt prefix = 0;
       
   157     if (Type() == TS_IPV4_ADDR_RANGE)
       
   158         {
       
   159         TUint32 startIp = iStartingAddress.Address();
       
   160         TUint32 endIp   = iEndingAddress.Address();
       
   161         TUint32 mask = ~(endIp ^ startIp);
       
   162         TUint32 m = 1;           
       
   163         while ( prefix < 32 )
       
   164         {
       
   165             if ( mask & ( m << prefix) )
       
   166                break;
       
   167             prefix ++;
       
   168         }
       
   169         prefix = 32 - prefix;
       
   170         idAddr = TInetAddr(startIp);        
       
   171         }
       
   172     else
       
   173         {        
       
   174         prefix = 128;  // NOT IMPLEMENTED YET
       
   175         }
       
   176 
       
   177     HBufC* idString = HBufC::NewLC(512);
       
   178     TPtr idStringPtr = idString->Des();
       
   179     idAddr.Output(idStringPtr);
       
   180     idStringPtr.AppendFormat(_L("/%d"), prefix);
       
   181     
       
   182     HBufC8* idString8 = HBufC8::NewL(idString->Length());
       
   183     TPtr8 idString8Ptr = idString8->Des();
       
   184     idString8Ptr.Copy(*idString);
       
   185     CleanupStack::PopAndDestroy(idString);
       
   186     
       
   187     return idString8;
       
   188     }
       
   189 
       
   190 TInetAddr TIkeV2TrafficSelector::CalcuateMask() const
       
   191     {
       
   192     TInetAddr mask;
       
   193     if ( Type() ==  TS_IPV4_ADDR_RANGE )
       
   194         {
       
   195         TUint32 A = iStartingAddress.Address();
       
   196         TUint32 M = iEndingAddress.Address();
       
   197         TUint32 X = 0x80000000;
       
   198         TUint32 Y = 0;
       
   199         M = ~(A ^ M); //Gets the bits that are 1 in both addresses
       
   200         for ( TInt i = 0; i < 32; ++i )     
       
   201         {
       
   202             if ( (M & X) == 0 )
       
   203             {
       
   204                M &= Y;
       
   205                break;
       
   206             }
       
   207             Y |= X;         
       
   208             X  = (X >> 1);
       
   209         }
       
   210         mask.SetAddress(M);     
       
   211         }
       
   212     else
       
   213         {
       
   214         TIp6Addr startAddr = iStartingAddress.Ip6Address();
       
   215         TIp6Addr endAddr = iEndingAddress.Ip6Address();
       
   216         TIp6Addr m; 
       
   217         Mem::FillZ(m.u.iAddr8, 16);
       
   218         
       
   219         TUint8   c = 0xff;
       
   220         for ( TInt i = 0; i < 16; ++i )
       
   221             {
       
   222             if ( c == 0xff )
       
   223                 c = (TUint8)(~(startAddr.u.iAddr8[i] ^ endAddr.u.iAddr8[i])); // Convert range to mask
       
   224             if ( (c != 0) && (c != 0xff) )
       
   225                 {
       
   226                 TUint8 z = 0x80;
       
   227                 TUint8 w = 0;               
       
   228                 for ( TInt j = 0; j < 8; ++j )       
       
   229                     {
       
   230                     if ( (c & z) == 0 )
       
   231                         {
       
   232                         c &= w;
       
   233                         break;
       
   234                         }
       
   235                     w |= z;                 
       
   236                     z  = (TUint8)(z >> 1);
       
   237                     }            
       
   238                 m.u.iAddr8[i]  = c;
       
   239                 c = 0;   
       
   240                 }
       
   241             else
       
   242                 {                            
       
   243                 m.u.iAddr8[i]  = c;
       
   244                 }       
       
   245             }
       
   246         mask.SetAddress(m);
       
   247         }
       
   248     return mask;
       
   249     }
       
   250 
       
   251 bool TIkeV2TrafficSelector::operator>(const TIkeV2TrafficSelector& aOtherSelector) const
       
   252     {
       
   253     if (Type() != aOtherSelector.Type())
       
   254          {
       
   255          //types do not match.
       
   256          return false;
       
   257          }        
       
   258 
       
   259     if (operator==(aOtherSelector))
       
   260         {
       
   261         //selectors are equal
       
   262         return false;
       
   263         }   
       
   264 
       
   265     return operator>=(aOtherSelector);
       
   266     }
       
   267 
       
   268 
       
   269 bool TIkeV2TrafficSelector::operator<(const TIkeV2TrafficSelector& aOtherSelector) const
       
   270     {
       
   271     if (operator==(aOtherSelector))
       
   272         {
       
   273         //selectors are equal
       
   274         return false;
       
   275         }   
       
   276     
       
   277     //The operator
       
   278     return operator<=(aOtherSelector); 
       
   279     }
       
   280 
       
   281 bool TIkeV2TrafficSelector::operator!=(const TIkeV2TrafficSelector& aOtherSelector) const
       
   282     {
       
   283     return !operator==(aOtherSelector);
       
   284     }
       
   285 
       
   286 bool TIkeV2TrafficSelector::operator==(const TIkeV2TrafficSelector& aOtherSelector) const
       
   287     {
       
   288     return (iStartingAddress == aOtherSelector.iStartingAddress &&
       
   289             iEndingAddress == aOtherSelector.iEndingAddress);
       
   290     }
       
   291 
       
   292 bool TIkeV2TrafficSelector::operator>=(const TIkeV2TrafficSelector& aOtherSelector) const
       
   293     {
       
   294     if (Type() != aOtherSelector.Type())
       
   295          {
       
   296          //types do not match.
       
   297          return false;
       
   298          }        
       
   299     
       
   300     if (operator==(aOtherSelector))
       
   301         {
       
   302         //selectors are equal
       
   303         return true;
       
   304         }
       
   305 
       
   306     return !operator<(aOtherSelector);
       
   307     }
       
   308 
       
   309 bool TIkeV2TrafficSelector::operator<=(const TIkeV2TrafficSelector& aOtherSelector) const
       
   310     {
       
   311     if (Type() != aOtherSelector.Type())
       
   312          {
       
   313          //types do not match.
       
   314          return false;
       
   315          }        
       
   316     
       
   317     if (operator==(aOtherSelector))
       
   318         {
       
   319         //selectors are equal
       
   320         return true;
       
   321         }
       
   322     
       
   323     if (iStartingAddress.Port() < aOtherSelector.iStartingAddress.Port() ||
       
   324         iEndingAddress.Port() > aOtherSelector.iEndingAddress.Port())
       
   325         {
       
   326         //Port range of this is bigger
       
   327         return false;
       
   328         }
       
   329 
       
   330     if (Type() == TS_IPV4_ADDR_RANGE)
       
   331          {        
       
   332          if (iStartingAddress.Address() >= aOtherSelector.iStartingAddress.Address() &&
       
   333              iEndingAddress.Address() <= aOtherSelector.iEndingAddress.Address())
       
   334              {
       
   335              return true;
       
   336              }
       
   337          else
       
   338              {
       
   339              return false;
       
   340              }
       
   341          }
       
   342      else
       
   343          {
       
   344          __ASSERT_DEBUG(Type() == TS_IPV6_ADDR_RANGE, User::Invariant());
       
   345          
       
   346          const TIp6Addr& thisStart = iStartingAddress.Ip6Address();
       
   347          const TIp6Addr& thisEnd = iEndingAddress.Ip6Address();
       
   348                            
       
   349          const TIp6Addr& otherStart = aOtherSelector.iStartingAddress.Ip6Address();
       
   350          const TIp6Addr& otherEnd = aOtherSelector.iEndingAddress.Ip6Address();
       
   351          
       
   352          TInt i;
       
   353          for (i = 0; i < 4; i++)
       
   354              {
       
   355              if (thisStart.u.iAddr32[i] > otherStart.u.iAddr32[i])
       
   356                  {
       
   357                  //this start address is bigger 
       
   358                  break;
       
   359                  }
       
   360              else if (thisStart.u.iAddr32[i] < otherStart.u.iAddr32[i])
       
   361                  {
       
   362                  //this start address is smaller.
       
   363                  return false; 
       
   364                  }             
       
   365              }
       
   366          
       
   367          for (i = 0; i < 4; i++)
       
   368              {
       
   369              if (thisEnd.u.iAddr32[i] < otherEnd.u.iAddr32[i])
       
   370                  {
       
   371                  //this end address is smaller 
       
   372                  break;
       
   373                  }
       
   374              else if (thisEnd.u.iAddr32[i] > otherEnd.u.iAddr32[i])
       
   375                  {
       
   376                  //this end address is bigger
       
   377                  return false; 
       
   378                  }             
       
   379              }         
       
   380          return true;
       
   381          }            
       
   382     }
       
   383 
       
   384