Imported Upstream version 878.70.2
[platform/upstream/mdnsresponder.git] / mDNSMacOSX / BonjourTop / source / bjIPAddr.cpp
1 //
2 //  bjIPAddr.cpp
3 //  TestTB
4 //
5 //  Created by Terrin Eager on 1/19/13.
6 //
7 //
8
9 #include <netinet/in.h>
10 #include <arpa/inet.h>
11
12 #include "bjIPAddr.h"
13 #include "bjstring.h"
14
15
16 //   static
17 sockaddr_storage BJIPAddr::emptySockAddrStorage;
18
19
20
21 BJIPAddr::BJIPAddr()
22 {
23     memset(&emptySockAddrStorage,0,sizeof(emptySockAddrStorage));
24     Empty();
25 }
26
27 BJIPAddr::BJIPAddr(const BJIPAddr& src)
28 {
29     memcpy(&sockAddrStorage,&src.sockAddrStorage,sizeof(sockAddrStorage));
30     IPv4SubNet = src.IPv4SubNet;
31 }
32 void BJIPAddr::Empty()
33 {
34     memset(&sockAddrStorage,0,sizeof(sockAddrStorage));
35     IPv4SubNet = 0;
36
37 }
38
39 bool BJIPAddr::IsBonjourMulticast()
40 {
41     bool bResult = false;
42
43     struct in_addr  BonjourMulicastAddrIPv4= {0xFB0000E0};
44
45     struct in6_addr BonjourMulicastAddrIPv6 = {{{ 0xFF,0x02,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xFB }}};
46
47
48     if (sockAddrStorage.ss_family == AF_INET)
49     {
50         struct sockaddr_in* pAddrIn = (sockaddr_in*) &sockAddrStorage;
51         return (pAddrIn->sin_addr.s_addr == BonjourMulicastAddrIPv4.s_addr);
52     }
53
54     if (sockAddrStorage.ss_family == AF_INET6)
55     {
56         struct sockaddr_in6* pAddrIn = (sockaddr_in6*) &sockAddrStorage;
57         return (memcmp(&pAddrIn->sin6_addr,&BonjourMulicastAddrIPv6,sizeof(in6_addr)) == 0);
58     }
59
60
61     return bResult;
62
63 }
64
65 bool BJIPAddr::IsSameSubNet(BJIPAddr* pCheckAddr)
66 {
67
68     if (IPv4SubNet == 0)
69         return true;
70
71     if (!pCheckAddr->IsIPv4())
72         return true;
73
74     in_addr_t Mask = 0xFFFFFFFF;
75
76     Mask = Mask << (32-IPv4SubNet);
77
78     endian_swap(Mask);
79
80     struct sockaddr_in* pMyAddrIn = (sockaddr_in*) &sockAddrStorage;
81     in_addr_t myNetworkAddress = pMyAddrIn->sin_addr.s_addr & Mask;
82
83     struct sockaddr_in* pCheckAddrIn = (sockaddr_in*) pCheckAddr->GetRawValue();
84     in_addr_t CheckNetworkAddress = pCheckAddrIn->sin_addr.s_addr & Mask;
85
86
87     return (myNetworkAddress == CheckNetworkAddress);
88 }
89
90
91 bool BJIPAddr::IsIPv4()
92 {
93     return (sockAddrStorage.ss_family == AF_INET);
94 }
95
96 bool BJIPAddr::IsIPv6()
97 {
98     return (sockAddrStorage.ss_family == AF_INET6);
99 }
100
101 bool BJIPAddr::IsIPv6LinkLocal()
102 {
103      struct sockaddr_in6* pAddrIn = (sockaddr_in6*) &sockAddrStorage;
104     return (pAddrIn->sin6_addr.__u6_addr.__u6_addr8[0] == 0xfe &&
105             pAddrIn->sin6_addr.__u6_addr.__u6_addr8[1] == 0x80);
106 }
107 bool BJIPAddr::IsEmpty()
108 {
109     return (memcmp(&sockAddrStorage,&emptySockAddrStorage,sizeof(sockAddrStorage)) == 0);
110 }
111
112 bool BJIPAddr::IsEmptySubnet()
113 {
114     return (IPv4SubNet == 0);
115 }
116
117 void BJIPAddr::Setv6(const char* pIPaddr)
118 {
119     memset(&sockAddrStorage,0,sizeof(sockAddrStorage));
120     struct sockaddr_in6* pAddrIn = (sockaddr_in6*) &sockAddrStorage;
121
122     if (inet_pton(AF_INET6, pIPaddr, &pAddrIn->sin6_addr) && memcmp(&sockAddrStorage,&emptySockAddrStorage,sizeof(sockAddrStorage)) == 0)
123             pAddrIn->sin6_family = AF_INET6;
124 }
125
126 void BJIPAddr::Set(const char* pIPaddr)
127 {
128     memset(&sockAddrStorage,0,sizeof(sockAddrStorage));
129
130     if (pIPaddr == NULL || strlen(pIPaddr) == 0)
131         return;
132
133     BJString sIPAddr;
134     BJString sMask;
135
136     const char* pSeperator = strstr(pIPaddr,"/");
137     if (pSeperator)
138     {
139         sIPAddr.Set(pIPaddr, (BJ_UINT32)(pSeperator - pIPaddr));
140         sMask.Set(pSeperator+1);
141     }
142     else
143     {
144         sIPAddr.Set(pIPaddr);
145     }
146
147     struct sockaddr_in* pAddrIn = (sockaddr_in*) &sockAddrStorage;
148     pAddrIn->sin_family = AF_INET;
149     pAddrIn->sin_addr.s_addr = inet_addr(sIPAddr.GetBuffer());
150
151     IPv4SubNet = sMask.GetUINT32();
152
153 }
154 void BJIPAddr::Setv4Raw(BJ_UINT8* ipi4_addr)
155 {
156
157     memset(&sockAddrStorage,0,sizeof(sockAddrStorage));
158     struct sockaddr_in* pAddrIn = (sockaddr_in*) &sockAddrStorage;
159     pAddrIn->sin_family = AF_INET;
160     memcpy(&pAddrIn->sin_addr, ipi4_addr, sizeof(pAddrIn->sin_addr));
161
162 }
163 void BJIPAddr::Setv6Raw(BJ_UINT8* ipi6_addr)
164 {
165
166     memset(&sockAddrStorage,0,sizeof(sockAddrStorage));
167     struct sockaddr_in6* pAddrIn = (sockaddr_in6*) &sockAddrStorage;
168
169     pAddrIn->sin6_family = AF_INET6;
170     memcpy(&pAddrIn->sin6_addr, ipi6_addr, sizeof(pAddrIn->sin6_addr));
171 }
172
173 void BJIPAddr::Set(struct in6_addr* ipi6_addr)
174 {
175
176     memset(&sockAddrStorage,0,sizeof(sockAddrStorage));
177     struct sockaddr_in6* pAddrIn = (sockaddr_in6*) &sockAddrStorage;
178
179     pAddrIn->sin6_family = AF_INET6;
180     memcpy(&pAddrIn->sin6_addr, ipi6_addr, sizeof(pAddrIn->sin6_addr));
181 }
182
183 void BJIPAddr::Set(struct in_addr* ip_addr)
184 {
185
186     memset(&sockAddrStorage,0,sizeof(sockAddrStorage));
187     struct sockaddr_in* pAddrIn = (sockaddr_in*) &sockAddrStorage;
188     pAddrIn->sin_family = AF_INET;
189     pAddrIn->sin_addr = *ip_addr;
190 }
191
192 void BJIPAddr::Set(struct sockaddr_storage* pStorage)
193 {
194     memcpy(&sockAddrStorage,pStorage,sizeof(sockAddrStorage));
195 }
196
197 sockaddr_storage* BJIPAddr::GetRawValue()
198 {
199     return &sockAddrStorage;
200 }
201
202 struct in6_addr* BJIPAddr::Getin6_addr()
203 {
204     struct sockaddr_in6* pAddrIn = (sockaddr_in6*) &sockAddrStorage;
205     return &pAddrIn->sin6_addr;
206 }
207
208 BJ_UINT16 BJIPAddr::GetPortNumber()
209 {
210     BJ_UINT16 port = 0;
211     if (sockAddrStorage.ss_family == AF_INET)
212     {
213         struct sockaddr_in* pAddrIn = (struct sockaddr_in*)&sockAddrStorage;
214         port = ntohs(pAddrIn->sin_port);
215     }
216     else if (sockAddrStorage.ss_family == AF_INET6)
217     {
218         struct sockaddr_in6* pAddrIn = (struct sockaddr_in6*)&sockAddrStorage;
219         port = ntohs(pAddrIn->sin6_port);
220     }
221     return port;
222 }
223
224 BJ_COMPARE BJIPAddr::Compare(BJIPAddr* pIPAddr)
225 {
226     if (sockAddrStorage.ss_family > pIPAddr->sockAddrStorage.ss_family)
227         return BJ_GT;
228     if (sockAddrStorage.ss_family < pIPAddr->sockAddrStorage.ss_family)
229         return BJ_LT;
230
231     if (sockAddrStorage.ss_family == AF_INET)
232     {
233         struct sockaddr_in* pMyAddrIn = (sockaddr_in*) &sockAddrStorage;
234         struct sockaddr_in* pAddrIn = (sockaddr_in*) &pIPAddr->sockAddrStorage;
235         if (pMyAddrIn->sin_addr.s_addr > pAddrIn->sin_addr.s_addr)
236             return BJ_GT;
237         if (pMyAddrIn->sin_addr.s_addr < pAddrIn->sin_addr.s_addr)
238             return BJ_LT;
239         return BJ_EQUAL;
240
241     }
242     else
243     {
244         struct sockaddr_in6* pMyAddrIn = (sockaddr_in6*) &sockAddrStorage;
245         struct sockaddr_in6* pAddrIn = (sockaddr_in6*) &pIPAddr->sockAddrStorage;
246
247         int result = memcmp(&pMyAddrIn->sin6_addr, &pAddrIn->sin6_addr, sizeof(sockaddr_in6));
248
249         if (result > 0)
250             return BJ_GT;
251         if (result < 0)
252             return BJ_LT;
253         return BJ_EQUAL;
254     }
255
256
257 }
258
259 /*
260
261  take the mac address: for example 52:74:f2:b1:a8:7f
262  throw ff:fe in the middle: 52:74:f2:ff:fe:b1:a8:7f
263  reformat to IPv6 notation 5274:f2ff:feb1:a87f
264  convert the first octet from hexadecimal to binary: 52 -> 01010010
265  invert the bit at position 6 (counting from 0): 01010010 -> 01010000
266  convert octet back to hexadecimal: 01010000 -> 50
267  replace first octet with newly calculated one: 5074:f2ff:feb1:a87f
268  prepend the link-local prefix: fe80::5074:f2ff:feb1:a87f
269  */
270
271 void BJIPAddr::CreateLinkLocalIPv6(BJ_UINT8* pmac)
272 {
273     memset(&sockAddrStorage,0,sizeof(sockAddrStorage));
274     struct sockaddr_in6* pAddrIn = (sockaddr_in6*) &sockAddrStorage;
275
276     pAddrIn->sin6_family = AF_INET6;
277
278     pAddrIn->sin6_addr.__u6_addr.__u6_addr8[0] = 0xfe;
279     pAddrIn->sin6_addr.__u6_addr.__u6_addr8[1] = 0x80;
280
281     pAddrIn->sin6_addr.__u6_addr.__u6_addr8[8] = *pmac;
282     pAddrIn->sin6_addr.__u6_addr.__u6_addr8[8] ^= 1 << 1; // invert 6 bit
283     pAddrIn->sin6_addr.__u6_addr.__u6_addr8[9] = *(pmac+1);
284     pAddrIn->sin6_addr.__u6_addr.__u6_addr8[10] = *(pmac+2);
285
286     pAddrIn->sin6_addr.__u6_addr.__u6_addr8[11] = 0xff;
287     pAddrIn->sin6_addr.__u6_addr.__u6_addr8[12] = 0xfe;
288
289
290     pAddrIn->sin6_addr.__u6_addr.__u6_addr8[13] = *(pmac+3);
291     pAddrIn->sin6_addr.__u6_addr.__u6_addr8[14] = *(pmac+4);
292     pAddrIn->sin6_addr.__u6_addr.__u6_addr8[15] = *(pmac+5);
293
294
295 }
296
297 char* BJIPAddr::GetString()
298 {
299     memset(stringbuffer,0,sizeof(stringbuffer));
300     if (IsIPv6())
301     {
302         struct sockaddr_in6* pAddrIn = (sockaddr_in6*) &sockAddrStorage;
303         inet_ntop(AF_INET6, &pAddrIn->sin6_addr, stringbuffer, sizeof(stringbuffer));
304     }
305     else
306     {
307         struct sockaddr_in* pAddrIn = (sockaddr_in*) &sockAddrStorage;
308         inet_ntop(AF_INET, &pAddrIn->sin_addr, stringbuffer, sizeof(stringbuffer));
309     }
310     return stringbuffer;
311 }
312