Coverage Report

Created: 2024-04-23 06:04

/src/resiprocate/rutil/GenericIPAddress.hxx
Line
Count
Source (jump to first uncovered line)
1
#if !defined(RESIP_GENERIC_IP_ADDRESS_HXX)
2
#define RESIP_GENERIC_IP_ADDRESS_HXX
3
4
#ifndef WIN32
5
#include <netinet/in.h>
6
#else
7
#include <winsock2.h>
8
#include <Ws2tcpip.h>
9
#endif
10
11
#include "rutil/Socket.hxx"
12
#include "rutil/compat.hxx"
13
14
15
namespace resip
16
{
17
/** 
18
   @brief Represents an IP-address and port (V4 or V6).
19
20
   @note This class is misnamed - it is really an IP address and port 
21
*/
22
struct GenericIPAddress
23
{
24
   public:   
25
      GenericIPAddress()
26
0
      {
27
0
      }
28
      
29
      GenericIPAddress(const sockaddr& addr) : address(addr) 
30
0
      {
31
0
#ifdef IPPROTO_IPV6
32
0
         if (addr.sa_family == AF_INET6)
33
0
         {
34
0
            v6Address = reinterpret_cast<const sockaddr_in6&>(addr);
35
0
         }
36
0
         else
37
0
#endif
38
0
         {
39
0
            v4Address = reinterpret_cast<const sockaddr_in&>(addr);
40
0
         }
41
0
      }
42
43
      GenericIPAddress(const sockaddr_in& v4) : v4Address(v4)
44
0
      {
45
0
      }
46
47
#ifdef IPPROTO_IPV6
48
      GenericIPAddress(const sockaddr_in6& v6) : v6Address(v6)
49
0
      {
50
0
      }
51
#endif
52
      
53
      size_t length() const
54
0
      {
55
0
         if (address.sa_family == AF_INET) // v4
56
0
         {
57
0
            return sizeof(sockaddr_in);
58
0
         }
59
0
#ifdef IPPROTO_IPV6
60
0
         else  if (address.sa_family == AF_INET6) // v6
61
0
         {
62
0
            return sizeof(sockaddr_in6);
63
0
         }
64
0
#endif
65
0
         resip_assert(0);
66
0
         return 0;
67
0
      }
68
      
69
      bool isVersion4() const
70
0
      {
71
0
         return address.sa_family == AF_INET;
72
0
      }
73
74
      bool isVersion6() const 
75
0
      { 
76
0
#ifdef IPPROTO_IPV6
77
0
         if (address.sa_family == AF_INET6) return true; 
78
0
#endif
79
0
         return false;
80
0
      }
81
82
      union
83
      {
84
            sockaddr address;
85
            sockaddr_in v4Address;
86
#ifdef IPPROTO_IPV6
87
            sockaddr_in6 v6Address;
88
#endif
89
            char pad[28]; // this make union same size if v6 is in or out
90
      };
91
92
      bool operator==(const GenericIPAddress& addr) const
93
0
      {
94
0
         if (address.sa_family == addr.address.sa_family)
95
0
         {
96
0
            if (address.sa_family == AF_INET) // v4
97
0
            {
98
0
               return (v4Address.sin_port == addr.v4Address.sin_port &&
99
0
                     memcmp(&v4Address.sin_addr, &addr.v4Address.sin_addr, sizeof(in_addr)) == 0);
100
0
            }
101
0
            else // v6
102
0
            {
103
0
#ifdef IPPROTO_IPV6
104
0
               return (v6Address.sin6_port == addr.v6Address.sin6_port &&
105
0
                     memcmp(&v6Address.sin6_addr, &addr.v6Address.sin6_addr, sizeof(in6_addr)) == 0);
106
0
#else
107
0
               resip_assert(0);
108
0
             return false;
109
0
#endif
110
0
            }
111
0
         }
112
0
         return false;
113
0
      }
114
115
      bool operator<(const GenericIPAddress& addr) const
116
0
      {
117
0
    
118
0
         if (address.sa_family == AF_INET && addr.address.sa_family == AF_INET)
119
0
         {
120
0
            int c=memcmp(&v4Address.sin_addr,
121
0
                        &addr.v4Address.sin_addr,
122
0
                        sizeof(in_addr));
123
0
124
0
            if (c < 0)
125
0
            {
126
0
               return true;
127
0
            }
128
0
            else if (c > 0)
129
0
            {
130
0
               return false;
131
0
            }
132
0
            else if (v4Address.sin_port < addr.v4Address.sin_port)
133
0
            {
134
0
               return true;
135
0
            }
136
0
            else
137
0
            {
138
0
               return false;
139
0
            }
140
0
         }
141
0
#ifdef IPPROTO_IPV6
142
0
         else if (address.sa_family == AF_INET6 &&
143
0
                  addr.address.sa_family == AF_INET6)
144
0
         {
145
0
            int c = memcmp(&v6Address.sin6_addr,
146
0
                           &addr.v6Address.sin6_addr,
147
0
                           sizeof(in6_addr));
148
0
            if (c < 0)
149
0
            {
150
0
               return true;
151
0
            }
152
0
            else if (c > 0)
153
0
            {
154
0
               return false;
155
0
            }
156
0
            else if (v6Address.sin6_port < addr.v6Address.sin6_port)
157
0
            {
158
0
               return true;
159
0
            }
160
0
            else
161
0
            {
162
0
               return false;
163
0
            }
164
0
         }
165
0
         else if (address.sa_family == AF_INET6 &&
166
0
                  addr.address.sa_family == AF_INET)
167
0
         {
168
0
            return true;
169
0
         }
170
0
         else if (address.sa_family == AF_INET &&
171
0
                  addr.address.sa_family == AF_INET6)
172
0
         {
173
0
            return false;
174
0
         }
175
0
#endif
176
0
         else
177
0
         {
178
0
            //assert(0);
179
0
            return false;
180
0
         }
181
0
      }
182
183
      friend EncodeStream& operator<<(EncodeStream& strm, const GenericIPAddress& addr);
184
185
};
186
187
EncodeStream&
188
operator<<(EncodeStream& ostrm, const GenericIPAddress& addr);
189
190
}
191
192
193
#endif
194
195
/* ====================================================================
196
 * The Vovida Software License, Version 1.0 
197
 * 
198
 * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
199
 * 
200
 * Redistribution and use in source and binary forms, with or without
201
 * modification, are permitted provided that the following conditions
202
 * are met:
203
 * 
204
 * 1. Redistributions of source code must retain the above copyright
205
 *    notice, this list of conditions and the following disclaimer.
206
 * 
207
 * 2. Redistributions in binary form must reproduce the above copyright
208
 *    notice, this list of conditions and the following disclaimer in
209
 *    the documentation and/or other materials provided with the
210
 *    distribution.
211
 * 
212
 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
213
 *    and "Vovida Open Communication Application Library (VOCAL)" must
214
 *    not be used to endorse or promote products derived from this
215
 *    software without prior written permission. For written
216
 *    permission, please contact vocal@vovida.org.
217
 *
218
 * 4. Products derived from this software may not be called "VOCAL", nor
219
 *    may "VOCAL" appear in their name, without prior written
220
 *    permission of Vovida Networks, Inc.
221
 * 
222
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
223
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
224
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
225
 * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
226
 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
227
 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
228
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
229
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
230
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
231
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
232
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
233
 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
234
 * DAMAGE.
235
 * 
236
 * ====================================================================
237
 * 
238
 * This software consists of voluntary contributions made by Vovida
239
 * Networks, Inc. and many individuals on behalf of Vovida Networks,
240
 * Inc.  For more information on Vovida Networks, Inc., please see
241
 * <http://www.vovida.org/>.
242
 *
243
 */