reSIProcate/rutil  9694
GenericIPAddress.hxx
Go to the documentation of this file.
00001 #if !defined(RESIP_GENERIC_IP_ADDRESS_HXX)
00002 #define RESIP_GENERIC_IP_ADDRESS_HXX
00003 
00004 #ifndef WIN32
00005 #include <netinet/in.h>
00006 #else
00007 #include <winsock2.h>
00008 #include <Ws2tcpip.h>
00009 #endif
00010 
00011 #include "rutil/Socket.hxx"
00012 #include "rutil/compat.hxx"
00013 
00014 
00015 namespace resip
00016 {
00022 struct GenericIPAddress
00023 {
00024    public:   
00025       GenericIPAddress()
00026       {
00027       }
00028       
00029       GenericIPAddress(const sockaddr& addr) : address(addr) 
00030       {
00031       }
00032 
00033       GenericIPAddress(const sockaddr_in& v4) : v4Address(v4)
00034       {
00035       }
00036 
00037 #ifdef IPPROTO_IPV6
00038       GenericIPAddress(const sockaddr_in6& v6) : v6Address(v6)
00039       {
00040       }
00041 #endif
00042       
00043       size_t length() const
00044       {
00045          if (address.sa_family == AF_INET) // v4
00046          {
00047             return sizeof(sockaddr_in);
00048          }
00049 #ifdef IPPROTO_IPV6
00050          else  if (address.sa_family == AF_INET6) // v6
00051          {
00052             return sizeof(sockaddr_in6);
00053          }
00054 #endif
00055          assert(0);
00056          return 0;
00057       }
00058       
00059       bool isVersion4() const
00060       {
00061          return address.sa_family == AF_INET;
00062       }
00063 
00064       bool isVersion6() const 
00065       { 
00066 #ifdef IPPROTO_IPV6
00067          if (address.sa_family == AF_INET6) return true; 
00068 #endif
00069          return false;
00070       }
00071 
00072       union
00073       {
00074             sockaddr address;
00075             sockaddr_in v4Address;
00076 #ifdef IPPROTO_IPV6
00077             sockaddr_in6 v6Address;
00078 #endif
00079             char pad[28]; // this make union same size if v6 is in or out
00080       };
00081 
00082       bool operator==(const GenericIPAddress& addr) const
00083       {
00084          if (address.sa_family == addr.address.sa_family)
00085          {
00086             if (address.sa_family == AF_INET) // v4
00087             {
00088                return (v4Address.sin_port == addr.v4Address.sin_port &&
00089                      memcmp(&v4Address.sin_addr, &addr.v4Address.sin_addr, sizeof(in_addr)) == 0);
00090             }
00091             else // v6
00092             {
00093 #ifdef IPPROTO_IPV6
00094                return (v6Address.sin6_port == addr.v6Address.sin6_port &&
00095                      memcmp(&v6Address.sin6_addr, &addr.v6Address.sin6_addr, sizeof(in6_addr)) == 0);
00096 #else
00097                assert(0);
00098                          return false;
00099 #endif
00100             }
00101          }
00102          return false;
00103       }
00104 
00105       bool operator<(const GenericIPAddress& addr) const
00106       {
00107     
00108          if (address.sa_family == AF_INET && addr.address.sa_family == AF_INET)
00109          {
00110             int c=memcmp(&v4Address.sin_addr,
00111                         &addr.v4Address.sin_addr,
00112                         sizeof(in_addr));
00113 
00114             if (c < 0)
00115             {
00116                return true;
00117             }
00118             else if (c > 0)
00119             {
00120                return false;
00121             }
00122             else if (v4Address.sin_port < addr.v4Address.sin_port)
00123             {
00124                return true;
00125             }
00126             else
00127             {
00128                return false;
00129             }
00130          }
00131 #ifdef IPPROTO_IPV6
00132          else if (address.sa_family == AF_INET6 &&
00133                   addr.address.sa_family == AF_INET6)
00134          {
00135             int c = memcmp(&v6Address.sin6_addr,
00136                            &addr.v6Address.sin6_addr,
00137                            sizeof(in6_addr));
00138             if (c < 0)
00139             {
00140                return true;
00141             }
00142             else if (c > 0)
00143             {
00144                return false;
00145             }
00146             else if (v6Address.sin6_port < addr.v6Address.sin6_port)
00147             {
00148                return true;
00149             }
00150             else
00151             {
00152                return false;
00153             }
00154          }
00155          else if (address.sa_family == AF_INET6 &&
00156                   addr.address.sa_family == AF_INET)
00157          {
00158             return true;
00159          }
00160          else if (address.sa_family == AF_INET &&
00161                   addr.address.sa_family == AF_INET6)
00162          {
00163             return false;
00164          }
00165 #endif
00166          else
00167          {
00168             //assert(0);
00169             return false;
00170          }
00171       }
00172 
00173 };
00174 
00175 }
00176 
00177 
00178 #endif
00179 
00180 /* ====================================================================
00181  * The Vovida Software License, Version 1.0 
00182  * 
00183  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
00184  * 
00185  * Redistribution and use in source and binary forms, with or without
00186  * modification, are permitted provided that the following conditions
00187  * are met:
00188  * 
00189  * 1. Redistributions of source code must retain the above copyright
00190  *    notice, this list of conditions and the following disclaimer.
00191  * 
00192  * 2. Redistributions in binary form must reproduce the above copyright
00193  *    notice, this list of conditions and the following disclaimer in
00194  *    the documentation and/or other materials provided with the
00195  *    distribution.
00196  * 
00197  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
00198  *    and "Vovida Open Communication Application Library (VOCAL)" must
00199  *    not be used to endorse or promote products derived from this
00200  *    software without prior written permission. For written
00201  *    permission, please contact vocal@vovida.org.
00202  *
00203  * 4. Products derived from this software may not be called "VOCAL", nor
00204  *    may "VOCAL" appear in their name, without prior written
00205  *    permission of Vovida Networks, Inc.
00206  * 
00207  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
00208  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00209  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
00210  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
00211  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
00212  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
00213  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00214  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00215  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00216  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00217  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00218  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00219  * DAMAGE.
00220  * 
00221  * ====================================================================
00222  * 
00223  * This software consists of voluntary contributions made by Vovida
00224  * Networks, Inc. and many individuals on behalf of Vovida Networks,
00225  * Inc.  For more information on Vovida Networks, Inc., please see
00226  * <http://www.vovida.org/>.
00227  *
00228  */