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

  1 dave.sudlik 1.2.2.2 //%2007////////////////////////////////////////////////////////////////////////
  2                     //
  3                     // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
  4                     // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
  5                     // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
  6                     // IBM Corp.; EMC Corporation, The Open Group.
  7                     // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
  8                     // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
  9                     // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 10                     // EMC Corporation; VERITAS Software Corporation; The Open Group.
 11                     // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 12                     // EMC Corporation; Symantec Corporation; The Open Group.
 13                     //
 14                     // Permission is hereby granted, free of charge, to any person obtaining a copy
 15                     // of this software and associated documentation files (the "Software"), to
 16                     // deal in the Software without restriction, including without limitation the
 17                     // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 18                     // sell copies of the Software, and to permit persons to whom the Software is
 19                     // furnished to do so, subject to the following conditions:
 20                     // 
 21                     // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 22 dave.sudlik 1.2.2.2 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 23                     // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 24                     // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 25                     // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 26                     // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 27                     // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 28                     // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 29                     //
 30                     //==============================================================================
 31                     //
 32                     //%/////////////////////////////////////////////////////////////////////////////
 33                     
 34                     #include <Pegasus/Common/HostAddress.h>
 35                     
 36                     PEGASUS_NAMESPACE_BEGIN
 37                     
 38                     #if defined (PEGASUS_OS_TYPE_WINDOWS) || !defined (PEGASUS_ENABLE_IPV6)
 39                     
 40                     /*
 41                         Address conversion utility functions.
 42                     */
 43 dave.sudlik 1.2.2.2 
 44                     /*
 45                         Converts given "src" text address (Ex: 127.0.0.1) to equivalent binary form 
 46                         and stores in "dst"  buffer (Ex 0x7f000001). Returns 1 if given ipv4 address
 47                         is valid or returns -1 if invalid. Returns value in network byte order.
 48                     */
 49                     
 50                     static int _inet_ptonv4(const char *src, void *dst)
 51                     {
 52                         Boolean isValid = true;
 53                         Uint16 octetValue[4] = {0};
 54                          // Check for valid IPV4 address.
 55                         for (Uint32 octet = 1, i = 0; octet <= 4; octet++)
 56                         {
 57                             int j = 0;
 58                             if (!(isascii(src[i]) && isdigit(src[i])))
 59                             {
 60                                 isValid = false;
 61                                 break;
 62                             }
 63                             while (isascii(src[i]) && isdigit(src[i]))
 64 dave.sudlik 1.2.2.2         {
 65                                 if (j == 3)
 66                                 {
 67                                     isValid = false;
 68                                     break;
 69                                 }
 70                                 octetValue[octet-1] = octetValue[octet-1]*10 + (src[i] - '0');
 71                                 i++;
 72                                 j++;
 73                             }
 74                             if (octetValue[octet-1] > 255)
 75                             {
 76                                 isValid = false;
 77                                 break;
 78                             }
 79                             // Check for invalid character in IP address
 80                             if ((octet != 4) && (src[i++] != '.'))
 81                             {
 82                                 isValid = false;
 83                                 break;
 84                             }
 85 dave.sudlik 1.2.2.2         // Check for the case where it's a valid host name that happens
 86                             // to have 4 (or more) leading all-numeric host segments.
 87                             if ((octet == 4) && (src[i] != ':') &&
 88                                 src[i] != char(0))
 89                             {
 90                                 isValid = false;
 91                                 break;
 92                             }
 93                         }
 94                         if (!isValid)
 95                         {
 96                             return 0;
 97                         }
 98                     
 99                         // Return the value in network byte order.
100                         Uint32 value;
101                         value = octetValue[0];
102                         value = (value << 8) + octetValue[1];
103                         value = (value << 8) + octetValue[2];
104                         value = (value << 8) + octetValue[3];
105                         value = htonl(value);
106 dave.sudlik 1.2.2.2     memcpy (dst, &value, sizeof(Uint32));
107                     
108                         return 1;
109                     }
110                     
111                     /*
112                          Converts given ipv6 text address (ex. ::1) to binary form and stroes
113                          in "dst" buffer (ex. 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1). Returns 1
114                          if src ipv6 address is valid or returns -1 if invalid. Returns value
115                          in network byte order.
116                     */
117                     static int _inet_ptonv6(const char *src, void *dst)
118                     {
119                         int ccIndex = -1;
120                         int sNumber = 0;
121                         Uint16 sValues[8] = {0};
122                         Boolean ipv4Mapped = false; 
123                     
124                         while (*src && sNumber < 8)
125                         {
126                             if (*src == ':')
127 dave.sudlik 1.2.2.2         {
128                                 if (!*++src)
129                                 {
130                                     return 0;
131                                 } 
132                                 if (*src == ':')
133                                 {
134                                     if (ccIndex != -1)
135                                     {
136                                         return 0;
137                                     }
138                                     ccIndex = sNumber;
139                                     if (!*++src)
140                                     {
141                                         break;
142                                     }   
143                                 } 
144                             } 
145                             if ((isalpha(*src) && tolower(*src) <= 'f') || isdigit(*src))
146                             {
147                                 // Check for ipv4 compatible ipv6 or ipv4 mapped ipv6 addresses
148 dave.sudlik 1.2.2.2             if(!strchr(src, ':') && strchr(src, '.'))
149                                 {
150                                     if ( _inet_ptonv4 (src, sValues + sNumber) != 1) 
151                                     {
152                                         return 0;
153                                     }  
154                                     sNumber += 2;              
155                                     ipv4Mapped = true;
156                                     break;
157                                 }
158                                 int chars = 0;            
159                                 while (*src && *src != ':')
160                                 {
161                                     if (chars++ == 4)
162                                     {
163                                         return 0;
164                                     }
165                                     if (!((isalpha(*src) && tolower(*src) <= 'f') || isdigit(*src)))
166                                     {
167                                         return 0;
168                                     }
169 dave.sudlik 1.2.2.2                 sValues[sNumber] = sValues[sNumber] * 16 +
170                                         (isdigit(*src) ? *src - '0' : (tolower(*src) - 'a' + 10));
171                                     ++src;
172                                 }
173                                 sValues[sNumber] = htons(sValues[sNumber]);
174                                 ++sNumber;
175                             }
176                             else
177                             {
178                                 return 0;
179                             }  
180                         }
181                     
182                         if ((!ipv4Mapped &&*src) || (ccIndex == -1 && sNumber < 8) || 
183                             (ccIndex != -1 && sNumber == 8) )
184                         {
185                             return 0;
186                         }
187                         memset(dst, 0, PEGASUS_IN6_ADDR_SIZE);
188                         for (int i = 0, j = 0; i < 8 ; ++i)
189                         {
190 dave.sudlik 1.2.2.2         if (ccIndex == i)
191                             {
192                                 i += 7 - sNumber;
193                             }
194                             else
195                             {
196                                 memcpy ((char*) dst + i * 2, sValues + j++ , 2);
197                             }
198                         }
199                         return 1;
200                     }
201                     
202                     /*
203                         Converts given ipv4 address in binary form to text form. Ex. 0x7f000001
204                         to 127.0.0.1.
205                     */
206                     static const char *_inet_ntopv4(const void *src, char *dst, Uint32 size)
207                     {
208                     
209                        Uint32 n;
210                     
211 dave.sudlik 1.2.2.2    memset(dst, 0, size); 
212                        memcpy(&n, src, sizeof (Uint32));   
213                        n = ntohl(n);
214                        sprintf(dst, "%u.%u.%u.%u", n >> 24 & 0xFF , 
215                            n >> 16 & 0xFF, n >> 8 & 0xFF, n & 0xFF); 
216                     
217                        return dst; 
218                     }
219                     
220                     /*  
221                         Converts given ipv6 address in binary form to text form. Ex. 
222                         0000000000000001 to ::1.
223                     */
224                     static const char *_inet_ntopv6(const void *src, char *dst, Uint32 size)
225                     {
226                     
227                         Uint16 n[8];
228                         int ccIndex = -1;
229                         int maxZeroCnt = 0;
230                         int zeroCnt = 0;
231                         int index = 0;
232 dave.sudlik 1.2.2.2 
233                         memcpy (n, src, PEGASUS_IN6_ADDR_SIZE);
234                         memset(dst, 0, size); 
235                         for (int i = 0; i < 8 ; ++i)
236                         {
237                             if (n[i])
238                             {
239                                 if (zeroCnt)
240                                 {
241                                     if (zeroCnt > maxZeroCnt)
242                                     {
243                                         ccIndex = index; 
244                                         maxZeroCnt = zeroCnt;
245                                     }
246                                     zeroCnt = index = 0;
247                                 }
248                                 n[i] = ntohs (n[i]);
249                             }
250                             else
251                             {
252                                 if(!zeroCnt++)
253 dave.sudlik 1.2.2.2             {
254                                     if (ccIndex == -1)
255                                     {
256                                         ccIndex = i;   
257                                     }
258                                     index = i;
259                                 }
260                             }
261                         }
262                         char tmp[50];  
263                         *dst = 0;
264                         zeroCnt = 0;
265                     
266                         for (int i = 0; i < 8 ; ++i)
267                         {
268                             if (i == ccIndex)
269                             {
270                                 sprintf(tmp, "::");
271                                 while ( i < 8 && !n[i])
272                                 {
273                                     ++i;
274 dave.sudlik 1.2.2.2                 ++zeroCnt;
275                                 }
276                                 --i;
277                             } 
278                             else
279                             {
280                                 Boolean mapped = false;
281                                 if (ccIndex == 0 && zeroCnt > 4)
282                                 {
283                                     // check for ipv4 mapped ipv6 and ipv4 compatible ipv6 
284                                     // addresses.
285                                     if (zeroCnt == 5 && n[i] == 0xffff)
286                                     {
287                                         strcat(dst,"ffff:"); 
288                                         mapped = true;
289                                     }
290                                     else if (zeroCnt == 6 && n[6])
291                                     {
292                                         mapped = true;
293                                     } 
294                                 }
295 dave.sudlik 1.2.2.2             if (mapped)
296                                 {
297                                     Uint32 m;
298                                     m = htons(n[7]);
299                                     m = (m << 16) + htons(n[6]);
300                                     HostAddress::convertBinaryToText(AF_INET, &m, tmp, 50);
301                                     i += 2;
302                                 }
303                                 else
304                                 {
305                                     sprintf(tmp, i < 7 && ccIndex != i + 1 ? "%x:" : "%x", n[i]);
306                                 }
307                             }
308                             strcat(dst,tmp);
309                         }
310                     
311                         return dst;
312                     }
313                     #endif  // defined (PEGASUS_OS_TYPE_WINDOWS) || !defined (PEGASUS_ENABLE_IPV6)
314                     
315                     void HostAddress::_init()
316 dave.sudlik 1.2.2.2 {
317                         _hostAddrStr = String::EMPTY;
318                         _isValid = false;
319                         _addrType = AT_INVALID;
320                     }
321                     
322                     HostAddress::HostAddress()
323                     {
324                         _init();
325                     }
326                     
327                     HostAddress::HostAddress(const String &addrStr)
328                     {
329                         _init();
330                         _hostAddrStr = addrStr;
331                         _parseAddress();
332                     }
333                     
334                     HostAddress& HostAddress::operator =(const HostAddress &rhs)
335                     {
336                         if (this != &rhs)
337 dave.sudlik 1.2.2.2     {
338                             _hostAddrStr = rhs._hostAddrStr;
339                             _isValid = rhs._isValid;
340                             _addrType = rhs._addrType;
341                         }
342                     
343                         return *this;
344                     }
345                     
346                     HostAddress::HostAddress(const HostAddress &rhs)
347                     {
348                         *this = rhs;
349                     }
350                     
351                     HostAddress::~HostAddress()
352                     {
353                     }
354                     
355                     void HostAddress::setHostAddress(const String &addrStr)
356                     {
357                         _init();
358 dave.sudlik 1.2.2.2     _hostAddrStr = addrStr;
359                         _parseAddress();
360                     }
361                     
362                     Uint32 HostAddress::getAddressType()
363                     {
364                         return _addrType;
365                     }
366                     
367                     Boolean HostAddress::isValid()
368                     {
369                         return _isValid;
370                     }
371                     
372                     String HostAddress::getHost()
373                     {
374                         return _hostAddrStr;
375                     }
376                     
377                     Boolean HostAddress::equal(int af, void *p1, void *p2)
378                     {
379 dave.sudlik 1.2.2.2     switch (af)
380                         {
381                             case AT_IPV6:
382                                  return !memcmp(p1, p2, PEGASUS_IN6_ADDR_SIZE);
383                             case AT_IPV4:
384                                  return !memcmp(p1, p2, sizeof(struct in_addr));
385                         }    
386                     
387                         return false;
388                     }
389                     
390                     void HostAddress::_parseAddress()
391                     {
392                         if (_hostAddrStr == String::EMPTY)
393                         {
394                             return;
395                         }
396                         if ((_isValid = isValidIPV6Address(_hostAddrStr)))
397                         {
398                             _addrType = AT_IPV6;
399                         }
400 dave.sudlik 1.2.2.2     else if( (_isValid = isValidIPV4Address(_hostAddrStr)))
401                         {
402                             _addrType = AT_IPV4;
403                         } 
404                         else if((_isValid = isValidHostName(_hostAddrStr)))
405                         {
406                             _addrType = AT_HOSTNAME;
407                         }
408                     }
409                     
410                     Boolean HostAddress::isValidIPV6Address (const String &ipv6Address)
411                     {
412                         int i = 0;
413                         while (ipv6Address[i])
414                         {
415                             if (!isascii(ipv6Address[i++]))
416                             {
417                                 return false;
418                             }
419                         }
420                     
421 dave.sudlik 1.2.2.2     CString addr = ipv6Address.getCString();
422                     #ifdef PEGASUS_ENABLE_IPV6
423                         struct in6_addr iaddr;
424                     #else
425                         char iaddr[PEGASUS_IN6_ADDR_SIZE];
426                     #endif
427                         return  1 == convertTextToBinary(AT_IPV6, (const char*) addr,
428                                          (void*)&iaddr);
429                     }
430                     
431                     Boolean HostAddress::isValidIPV4Address (const String &ipv4Address)
432                     {
433                         int i = 0;
434                         while (ipv4Address[i])
435                         {
436                             if (!isascii(ipv4Address[i++]))
437                             {
438                                 return false;
439                             }
440                         }
441                     
442 dave.sudlik 1.2.2.2     CString addr = ipv4Address.getCString();
443                         struct in_addr iaddr;
444                     
445                         return  1 == convertTextToBinary(AT_IPV4, (const char*) addr,
446                                          (void*)&iaddr);
447                     }
448                     
449                     Boolean HostAddress::isValidHostName (const String &hostName)
450                     {
451                         Uint32 i = 0;
452                         Boolean expectHostSegment = true;
453                         Boolean hostSegmentIsNumeric;
454                         while (expectHostSegment)
455                         {
456                             expectHostSegment = false;
457                             hostSegmentIsNumeric = true; // assume all-numeric host segment
458                             if (!(isascii(hostName[i]) &&
459                                 (isalnum(hostName[i]) || (hostName[i] == '_'))))
460                             {
461                                 return false;
462                             }
463 dave.sudlik 1.2.2.2         while (isascii(hostName[i]) &&
464                                 (isalnum(hostName[i]) || (hostName[i] == '-') ||
465                                     (hostName[i] == '_')))
466                             {
467                                 // If a non-digit is encountered, set "all-numeric"
468                                 // flag to false
469                                 if (isalpha(hostName[i]) || (hostName[i] == '-') ||
470                                     (hostName[i] == '_'))
471                                 {
472                                     hostSegmentIsNumeric = false;
473                                 }
474                                 i++;
475                             }
476                             if (hostName[i] == '.')
477                             {
478                                 i++;
479                                 expectHostSegment = true;
480                             }
481                         }
482                         // If the last Host Segment is all numeric, then return false.
483                         // RFC 1123 says "highest-level component label will be alphabetic".
484 dave.sudlik 1.2.2.2     if (hostSegmentIsNumeric || hostName[i] != char(0))
485                         {
486                             return false;
487                         }
488                     
489                         return true;
490                     }
491                     
492                     
493                     int HostAddress::convertTextToBinary(int af, const char *src, void *dst)
494                     {
495                     #if defined (PEGASUS_OS_TYPE_WINDOWS) || !defined (PEGASUS_ENABLE_IPV6)
496                         if (af == AT_IPV4)
497                         {
498                             return _inet_ptonv4(src, dst);
499                         }
500                         else if(af == AT_IPV6)
501                         {
502                             return _inet_ptonv6(src, dst);
503                         }
504                         return -1; // Unsupported address family.
505 dave.sudlik 1.2.2.2 #else
506                         return ::inet_pton(af, src, dst);
507                     #endif 
508                     }
509                     
510                     const char * HostAddress::convertBinaryToText(int af, const void *src,
511                         char *dst, Uint32 size)
512                     {
513                     #if defined (PEGASUS_OS_TYPE_WINDOWS) || !defined (PEGASUS_ENABLE_IPV6)
514                         if (af == AT_IPV6)
515                         {
516                             return _inet_ntopv6(src, dst, size);
517                         }
518                         else if (af == AT_IPV4)
519                         {
520                             return _inet_ntopv4(src, dst, size);
521                         }
522                         return 0; // Unsupported address family.
523                     #else
524                         return ::inet_ntop(af, src, dst, size);
525                     #endif 
526 dave.sudlik 1.2.2.2 }
527                     
528                     PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2