(file) Return to HostAddress.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

Diff for /pegasus/src/Pegasus/Common/HostAddress.cpp between version 1.1.2.1 and 1.6.8.1

version 1.1.2.1, 2007/06/08 10:43:20 version 1.6.8.1, 2013/06/03 22:35:12
Line 1 
Line 1 
 //%2007////////////////////////////////////////////////////////////////////////  //%LICENSE////////////////////////////////////////////////////////////////
 // //
 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development  // Licensed to The Open Group (TOG) under one or more contributor license
 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.  // agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;  // this work for additional information regarding copyright ownership.
 // IBM Corp.; EMC Corporation, The Open Group.  // Each contributor licenses this file to you under the OpenPegasus Open
 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;  // Source License; you may not use this file except in compliance with the
 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.  // License.
 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;  
 // EMC Corporation; VERITAS Software Corporation; The Open Group.  
 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;  
 // EMC Corporation; Symantec Corporation; The Open Group.  
 // //
 // Permission is hereby granted, free of charge, to any person obtaining a copy  // Permission is hereby granted, free of charge, to any person obtaining a
 // of this software and associated documentation files (the "Software"), to  // copy of this software and associated documentation files (the "Software"),
 // deal in the Software without restriction, including without limitation the  // to deal in the Software without restriction, including without limitation
 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or  // the rights to use, copy, modify, merge, publish, distribute, sublicense,
 // sell copies of the Software, and to permit persons to whom the Software is  // and/or sell copies of the Software, and to permit persons to whom the
 // furnished to do so, subject to the following conditions:  // Software is furnished to do so, subject to the following conditions:
 // //
 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN  // The above copyright notice and this permission notice shall be included
 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED  // in all copies or substantial portions of the Software.
 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT  
 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR  
 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT  
 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN  
 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION  
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  
 // //
 //==============================================================================  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   //
   //////////////////////////////////////////////////////////////////////////
 // //
 //%///////////////////////////////////////////////////////////////////////////// //%/////////////////////////////////////////////////////////////////////////////
  
 #include <string.h>  
 #include <stdlib.h>  
 #include <ctype.h>  
 #include <Pegasus/Common/String.h>  
 #include <Pegasus/Common/HostAddress.h> #include <Pegasus/Common/HostAddress.h>
 #include <Pegasus/Common/PegasusAssert.h>  #include <Pegasus/Common/Tracer.h>
  
 PEGASUS_NAMESPACE_BEGIN PEGASUS_NAMESPACE_BEGIN
  
 #if defined (PEGASUS_OS_TYPE_WINDOWS) || defined (PEGASUS_DISABLE_IPV6)  #if defined (PEGASUS_OS_TYPE_WINDOWS) || !defined (PEGASUS_ENABLE_IPV6)
  
 /* /*
     Address conversion utility functions.     Address conversion utility functions.
Line 113 
Line 107 
     return 1;     return 1;
 } }
  
 #ifndef PEGASUS_DISABLE_IPV6  
 /* /*
      Converts given ipv6 text address (ex. ::1) to binary form and stroes       Converts given ipv6 text address (ex. ::1) to binary form and stores
      in "dst" buffer (ex. 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1). Returns 1      in "dst" buffer (ex. 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1). Returns 1
      if src ipv6 address is valid or returns -1 if invalid. Returns value      if src ipv6 address is valid or returns -1 if invalid. Returns value
      in network byte order.      in network byte order.
Line 190 
Line 183 
     {     {
         return 0;         return 0;
     }     }
       memset(dst, 0, PEGASUS_IN6_ADDR_SIZE);
     memset(dst, 0, sizeof(struct in6_addr));  
   
     for (int i = 0, j = 0; i < 8 ; ++i)     for (int i = 0, j = 0; i < 8 ; ++i)
     {     {
         if (ccIndex == i)         if (ccIndex == i)
Line 206 
Line 197 
     }     }
     return 1;     return 1;
 } }
 #endif  
  
 /* /*
     Converts given ipv4 address in binary form to text form. Ex. 0x7f000001     Converts given ipv4 address in binary form to text form. Ex. 0x7f000001
Line 226 
Line 216 
    return dst;    return dst;
 } }
  
 #ifndef PEGASUS_DISABLE_IPV6  
 /* /*
     Converts given ipv6 address in binary form to text form. Ex.     Converts given ipv6 address in binary form to text form. Ex.
     0000000000000001 to ::1.     0000000000000001 to ::1.
Line 240 
Line 229 
     int zeroCnt = 0;     int zeroCnt = 0;
     int index = 0;     int index = 0;
  
     memcpy (n, src, sizeof (struct in6_addr));      memcpy (n, src, PEGASUS_IN6_ADDR_SIZE);
     memset(dst, 0, size);     memset(dst, 0, size);
     for (int i = 0; i < 8 ; ++i)     for (int i = 0; i < 8 ; ++i)
     {     {
Line 320 
Line 309 
  
     return dst;     return dst;
 } }
 #endif  #endif  // defined (PEGASUS_OS_TYPE_WINDOWS) || !defined (PEGASUS_ENABLE_IPV6)
 #endif  // defined (PEGASUS_OS_TYPE_WINDOWS) || defined (PEGASUS_DISABLE_IPV6)  
  
 void HostAddress::_init()  HostAddress::HostAddress():
 {      _hostAddrStr(),
     _hostAddress = String::EMPTY;      _addrType(AT_INVALID),
     _hostAddrStr = String::EMPTY;      _isValid(false),
     _portNumber = PORT_UNSPECIFIED;      _isAddrLinkLocal(false),
     _isValid = false;      _scopeID(0)
     _addrType = AT_INVALID;  
 }  
  
 HostAddress::HostAddress()  
 { {
     _init();  
 }  
   
 HostAddress::HostAddress(const String &addrStr)  
 {  
     _init();  
     _hostAddrStr = addrStr;  
     _parseAddress();  
 } }
  
 HostAddress& HostAddress::operator =(const HostAddress &rhs) HostAddress& HostAddress::operator =(const HostAddress &rhs)
 { {
     if (this != &rhs)     if (this != &rhs)
     {     {
         _hostAddress = rhs._hostAddress;  
         _hostAddrStr = rhs._hostAddrStr;         _hostAddrStr = rhs._hostAddrStr;
         _portNumber = rhs._portNumber;  
         _isValid = rhs._isValid;         _isValid = rhs._isValid;
         _addrType = rhs._addrType;         _addrType = rhs._addrType;
           _scopeID = rhs._scopeID;
           _isAddrLinkLocal = rhs._isAddrLinkLocal;
     }     }
  
     return *this;     return *this;
Line 367 
Line 344 
 { {
 } }
  
 void HostAddress::setHostAddress(const String &addrStr)  Boolean HostAddress::setHostAddress(const String &addrStr)
   {
   
       if (addrStr.size() != 0)
 { {
     _init();  
           if (isValidIPV4Address(addrStr))
           {
               _isValid = true;
               _addrType = AT_IPV4;
     _hostAddrStr = addrStr;     _hostAddrStr = addrStr;
     _parseAddress();              _scopeID = 0;
               _isAddrLinkLocal = false;
               return _isValid;
 } }
  
 Uint32 HostAddress::getPort()          if (isValidHostName(addrStr))
 { {
     return _portNumber;              _isValid = true;
               _addrType = AT_HOSTNAME;
               _hostAddrStr = addrStr;
               _scopeID = 0;
               _isAddrLinkLocal = false;
               return _isValid;
 } }
  
 String HostAddress::getPortString()          if (_checkIPv6AndLinkLocal( addrStr ))
 { {
     char portStr[10];              _isValid = true;
     sprintf(portStr, "%u", _portNumber);              _addrType = AT_IPV6;
     return String(portStr);              return _isValid;
 } }
  
 Uint32 HostAddress::getAddressType()      } // if addrStr == 0 or no valid address specified.
 {  
     return _addrType;      _hostAddrStr.clear();
       _isValid = false;
       _addrType = AT_INVALID;
       _scopeID = 0;
       _isAddrLinkLocal = false;
       return _isValid;
 } }
  
 Boolean HostAddress::isValid()  Uint32 HostAddress::getAddressType() const
 { {
     return _isValid;      return _addrType;
 } }
  
 String HostAddress::getHost()  Boolean HostAddress::isValid() const
 { {
     return _hostAddress;      return _isValid;
 } }
  
 Boolean HostAddress::isPortSpecified()  String HostAddress::getHost() const
 { {
     return _portNumber != PORT_UNSPECIFIED && _portNumber != PORT_INVALID;      return _hostAddrStr;
 } }
  
 Boolean HostAddress::equal(int af, void *p1, void *p2) Boolean HostAddress::equal(int af, void *p1, void *p2)
 { {
     switch (af)     switch (af)
     {     {
 #ifndef PEGASUS_DISABLE_IPV6          case AT_IPV6:
         case AF_INET6:               return !memcmp(p1, p2, PEGASUS_IN6_ADDR_SIZE);
              return !memcmp(p1, p2, sizeof(struct in6_addr));          case AT_IPV4:
 #endif  
         case AF_INET:  
              return !memcmp(p1, p2, sizeof(struct in_addr));              return !memcmp(p1, p2, sizeof(struct in_addr));
     }     }
  
     return false;     return false;
 } }
  
 void HostAddress::_parseAddress()  Boolean HostAddress::_checkIPv6AndLinkLocal( const String &ip6add2check)
 {  
     if (_hostAddrStr == String::EMPTY)  
     {     {
         _isValid = false;         _isValid = false;
         return;      _isAddrLinkLocal = false;
     }      _scopeID = 0;
  
     Uint32 i = 0;      String iptmp = ip6add2check;
 #ifndef PEGASUS_DISABLE_IPV6      String tmp = iptmp.subString(0, 4);
     if (_hostAddrStr[0] == '[')      // If the IP address starts with "fe80" it is a link-local address
     {      if(String::equalNoCase(tmp, "fe80"))
         i = 1;      {
         while (_hostAddrStr[i] && _hostAddrStr[i] != ']')          Uint32 idx = iptmp.find('%');
         {          if(idx != PEG_NOT_FOUND)
             ++i;          {
         }  #if defined PEGASUS_OS_TYPE_WINDOWS
         if (_hostAddrStr[i] == ']')              // On Windows the zone ID/inteface index for link-local is an
         {              // integer value starting with 1.
             _hostAddress = _hostAddrStr.subString (1, i - 1);              _scopeID = atoi(
             if( !(_isValid = isValidIPV6Address(_hostAddress)))                      (const char *)(iptmp.subString(idx+1).getCString()));
             {  #else
                 return;              // if_nametoindex() retruns 0 when zone ID was not valid/found.
             }              _scopeID = if_nametoindex(
             _addrType = AT_IPV6;                      (const char *)(iptmp.subString(idx+1).getCString()));
             ++i;  
         }  
         else  
         {  
             _hostAddress = _hostAddrStr;  
             return;  
         }  
     }  
     else  
 #endif #endif
     if (!_isValid)              // The scope ID should not be 0, even RFC4007 specifies 0 as the
     {              // default interface. But
         while (_hostAddrStr[i] && _hostAddrStr[i] != ':')              if (0 == _scopeID)
         {              {
             ++i;                  PEG_TRACE((TRC_HTTP,Tracer::LEVEL1,
                       "The zone index of IPv6 link-local address %s is invalid.",
                       (const char*)ip6add2check.getCString()));
                   return false;
         }         }
         _hostAddress = _hostAddrStr.subString(0, i);              // Remove the zone id before checkeing for a valid IPv6 address.
         if( !(_isValid = isValidIPV4Address(_hostAddress)))              iptmp.remove(idx);
         {              _isAddrLinkLocal = true;
             // Not a valid IPV4 address, check for valid hostName  
             if(!(_isValid = isValidHostName(_hostAddress)))  
             {  
                 return;  
             }  
             _addrType = AT_HOSTNAME;  
         }         }
         else         else
         {         {
             _addrType = AT_IPV4;              PEG_TRACE((TRC_HTTP,Tracer::LEVEL1,
                   "The IPv6 link-local address %s has no zone index specified.",
                   (const char*)ip6add2check.getCString()));
               return false;
         }         }
     }     }
     // Check for Port number.  
     Uint32 port = 0;      if (isValidIPV6Address(iptmp))
     if (_hostAddrStr[i] == ':')  
     {  
         ++i;  
         while (isascii(_hostAddrStr[i]) && isdigit(_hostAddrStr[i]))  
         {  
             port = port * 10 + ( _hostAddrStr[i] - '0' );  
             if (port > MAX_PORT_NUMBER)  
             {             {
                 _portNumber = PORT_INVALID;          _hostAddrStr = iptmp;
                 _isValid = false;          _isValid = true;
                 return;          return true;
             }             }
             ++i;      PEG_TRACE((TRC_HTTP,Tracer::LEVEL1,
           "Invalid IPv6 address %s specified.",
           (const char*)ip6add2check.getCString()));
       return false;
         }         }
  
         if (_hostAddrStr[i-1] != ':' && _hostAddrStr[i] == char(0))  Uint32 HostAddress::getScopeID() const
         {         {
             _portNumber = port;      return _scopeID;
         }         }
         else  
   Boolean HostAddress::isHostAddLinkLocal() const
         {         {
             _portNumber = PORT_INVALID;      return _isAddrLinkLocal;
             _isValid = false;  
         }  
     }  
 } }
  
 #ifndef PEGASUS_DISABLE_IPV6  
 Boolean HostAddress::isValidIPV6Address (const String &ipv6Address) Boolean HostAddress::isValidIPV6Address (const String &ipv6Address)
 { {
     CString addr = ipv6Address.getCString();      const Uint16* p = (const Uint16*)ipv6Address.getChar16Data();
     struct in6_addr iaddr;      int numColons = 0;
   
       while (*p)
       {
           if (*p > 127)
               return false;
   
           if (*p == ':')
               numColons++;
  
     return  1 == convertTextToBinary(AF_INET6, (const char*) addr,          p++;
                     (void*)&iaddr);  
 } }
   
       // No need to check whether IPV6 if no colons found.
   
       if (numColons == 0)
           return false;
   
       CString addr = ipv6Address.getCString();
   #ifdef PEGASUS_ENABLE_IPV6
       struct in6_addr iaddr;
   #else
       char iaddr[PEGASUS_IN6_ADDR_SIZE];
 #endif #endif
       return  convertTextToBinary(AT_IPV6, (const char*)addr, (void*)&iaddr) == 1;
   }
  
 Boolean HostAddress::isValidIPV4Address (const String &ipv4Address) Boolean HostAddress::isValidIPV4Address (const String &ipv4Address)
 { {
     CString addr = ipv4Address.getCString();      const Uint16* src = (const Uint16*)ipv4Address.getChar16Data();
     struct in_addr iaddr;      Uint16 octetValue[4] = {0};
   
       for (Uint32 octet = 1, i = 0; octet <= 4; octet++)
       {
           int j = 0;
   
           if (!(isascii(src[i]) && isdigit(src[i])))
               return false;
   
           while (isascii(src[i]) && isdigit(src[i]))
           {
               if (j == 3)
                   return false;
   
               octetValue[octet-1] = octetValue[octet-1] * 10 + (src[i] - '0');
               i++;
               j++;
           }
   
           if (octetValue[octet-1] > 255)
               return false;
   
           if ((octet != 4) && (src[i++] != '.'))
               return false;
  
     return  1 == convertTextToBinary(AF_INET, (const char*) addr,          if ((octet == 4) && (src[i] != ':') && src[i] != char(0))
                      (void*)&iaddr);              return false;
       }
       return true;
 } }
  
 Boolean HostAddress::isValidHostName (const String &hostName)  Boolean HostAddress::isValidHostName (const String &hostName_)
 { {
       const Uint16* hostName = (const Uint16*)hostName_.getChar16Data();
   
     Uint32 i = 0;     Uint32 i = 0;
     Boolean expectHostSegment = true;     Boolean expectHostSegment = true;
     Boolean hostSegmentIsNumeric;     Boolean hostSegmentIsNumeric;
Line 572 
Line 595 
  
 int HostAddress::convertTextToBinary(int af, const char *src, void *dst) int HostAddress::convertTextToBinary(int af, const char *src, void *dst)
 { {
 #ifdef PEGASUS_DISABLE_IPV6  #if defined (PEGASUS_OS_TYPE_WINDOWS) || !defined (PEGASUS_ENABLE_IPV6)
     if (af == AF_INET)      if (af == AT_IPV4)
     {     {
         return _inet_ptonv4(src, dst);         return _inet_ptonv4(src, dst);
     }     }
     return -1;      else if(af == AT_IPV6)
 #else  
 #ifdef PEGASUS_OS_TYPE_UNIX  
     return ::inet_pton(af, src, dst);  
 #else  
     if (af == AF_INET)  
     {  
         return _inet_ptonv4(src, dst);  
     }  
     else if(af == AF_INET6)  
     {     {
         return _inet_ptonv6(src, dst);         return _inet_ptonv6(src, dst);
     }     }
     else  
     {  
         return -1; // Unsupported address family.         return -1; // Unsupported address family.
     }  #else
 #endif // PEGASUS_OS_TYPE_UNIX      return ::inet_pton(af, src, dst);
 #endif // PEGASUS_DISABLE_IPV6  #endif
 } }
  
 const char * HostAddress::convertBinaryToText(int af, const void *src, const char * HostAddress::convertBinaryToText(int af, const void *src,
     char *dst, Uint32 size)     char *dst, Uint32 size)
 { {
 #ifdef PEGASUS_DISABLE_IPV6  #if defined (PEGASUS_OS_TYPE_WINDOWS) || !defined (PEGASUS_ENABLE_IPV6)
     if (af == AF_INET)      if (af == AT_IPV6)
     {     {
         return _inet_ntopv4(src, dst, size);          return _inet_ntopv6(src, dst, size);
     }     }
     return 0;      else if (af == AT_IPV4)
 #else  
 #ifdef PEGASUS_OS_TYPE_UNIX  
     return ::inet_ntop(af, src, dst, size);  
 #else  
     if (af == AF_INET)  
     {     {
         return _inet_ntopv4(src, dst, size);         return _inet_ntopv4(src, dst, size);
     }     }
     else if (af == AF_INET6)  
     {  
         return _inet_ntopv6(src, dst, size);  
     }  
     else  
     {  
         return 0; // Unsupported address family.         return 0; // Unsupported address family.
     }  #else
 #endif // PEGASUS_OS_TYPE_UNIX      return ::inet_ntop(af, src, dst, size);
 #endif // PEGASUS_DISABLE_IPV6  #endif
 } }
  
 PEGASUS_NAMESPACE_END PEGASUS_NAMESPACE_END


Legend:
Removed from v.1.1.2.1  
changed lines
  Added in v.1.6.8.1

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2