5 // Created by Terrin Eager on 1/19/13.
9 #include <netinet/in.h>
10 #include <arpa/inet.h>
17 sockaddr_storage
BJIPAddr::emptySockAddrStorage
;
23 memset(&emptySockAddrStorage
,0,sizeof(emptySockAddrStorage
));
27 BJIPAddr::BJIPAddr(const BJIPAddr
& src
)
29 memcpy(&sockAddrStorage
,&src
.sockAddrStorage
,sizeof(sockAddrStorage
));
30 IPv4SubNet
= src
.IPv4SubNet
;
32 void BJIPAddr::Empty()
34 memset(&sockAddrStorage
,0,sizeof(sockAddrStorage
));
39 bool BJIPAddr::IsBonjourMulticast()
43 struct in_addr BonjourMulicastAddrIPv4
= {0xFB0000E0};
45 struct in6_addr BonjourMulicastAddrIPv6
= {{{ 0xFF,0x02,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xFB }}};
48 if (sockAddrStorage
.ss_family
== AF_INET
)
50 struct sockaddr_in
* pAddrIn
= (sockaddr_in
*) &sockAddrStorage
;
51 return (pAddrIn
->sin_addr
.s_addr
== BonjourMulicastAddrIPv4
.s_addr
);
54 if (sockAddrStorage
.ss_family
== AF_INET6
)
56 struct sockaddr_in6
* pAddrIn
= (sockaddr_in6
*) &sockAddrStorage
;
57 return (memcmp(&pAddrIn
->sin6_addr
,&BonjourMulicastAddrIPv6
,sizeof(in6_addr
)) == 0);
65 bool BJIPAddr::IsSameSubNet(BJIPAddr
* pCheckAddr
)
71 if (!pCheckAddr
->IsIPv4())
74 in_addr_t Mask
= 0xFFFFFFFF;
76 Mask
= Mask
<< (32-IPv4SubNet
);
80 struct sockaddr_in
* pMyAddrIn
= (sockaddr_in
*) &sockAddrStorage
;
81 in_addr_t myNetworkAddress
= pMyAddrIn
->sin_addr
.s_addr
& Mask
;
83 struct sockaddr_in
* pCheckAddrIn
= (sockaddr_in
*) pCheckAddr
->GetRawValue();
84 in_addr_t CheckNetworkAddress
= pCheckAddrIn
->sin_addr
.s_addr
& Mask
;
87 return (myNetworkAddress
== CheckNetworkAddress
);
91 bool BJIPAddr::IsIPv4()
93 return (sockAddrStorage
.ss_family
== AF_INET
);
96 bool BJIPAddr::IsIPv6()
98 return (sockAddrStorage
.ss_family
== AF_INET6
);
101 bool BJIPAddr::IsIPv6LinkLocal()
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);
107 bool BJIPAddr::IsEmpty()
109 return (memcmp(&sockAddrStorage
,&emptySockAddrStorage
,sizeof(sockAddrStorage
)) == 0);
112 bool BJIPAddr::IsEmptySubnet()
114 return (IPv4SubNet
== 0);
117 void BJIPAddr::Setv6(const char* pIPaddr
)
119 memset(&sockAddrStorage
,0,sizeof(sockAddrStorage
));
120 struct sockaddr_in6
* pAddrIn
= (sockaddr_in6
*) &sockAddrStorage
;
122 if (inet_pton(AF_INET6
, pIPaddr
, &pAddrIn
->sin6_addr
) && memcmp(&sockAddrStorage
,&emptySockAddrStorage
,sizeof(sockAddrStorage
)) == 0)
123 pAddrIn
->sin6_family
= AF_INET6
;
126 void BJIPAddr::Set(const char* pIPaddr
)
128 memset(&sockAddrStorage
,0,sizeof(sockAddrStorage
));
130 if (pIPaddr
== NULL
|| strlen(pIPaddr
) == 0)
136 const char* pSeperator
= strstr(pIPaddr
,"/");
139 sIPAddr
.Set(pIPaddr
, (BJ_UINT32
)(pSeperator
- pIPaddr
));
140 sMask
.Set(pSeperator
+1);
144 sIPAddr
.Set(pIPaddr
);
147 struct sockaddr_in
* pAddrIn
= (sockaddr_in
*) &sockAddrStorage
;
148 pAddrIn
->sin_family
= AF_INET
;
149 pAddrIn
->sin_addr
.s_addr
= inet_addr(sIPAddr
.GetBuffer());
151 IPv4SubNet
= sMask
.GetUINT32();
154 void BJIPAddr::Setv4Raw(BJ_UINT8
* ipi4_addr
)
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
));
163 void BJIPAddr::Setv6Raw(BJ_UINT8
* ipi6_addr
)
166 memset(&sockAddrStorage
,0,sizeof(sockAddrStorage
));
167 struct sockaddr_in6
* pAddrIn
= (sockaddr_in6
*) &sockAddrStorage
;
169 pAddrIn
->sin6_family
= AF_INET6
;
170 memcpy(&pAddrIn
->sin6_addr
, ipi6_addr
, sizeof(pAddrIn
->sin6_addr
));
173 void BJIPAddr::Set(struct in6_addr
* ipi6_addr
)
176 memset(&sockAddrStorage
,0,sizeof(sockAddrStorage
));
177 struct sockaddr_in6
* pAddrIn
= (sockaddr_in6
*) &sockAddrStorage
;
179 pAddrIn
->sin6_family
= AF_INET6
;
180 memcpy(&pAddrIn
->sin6_addr
, ipi6_addr
, sizeof(pAddrIn
->sin6_addr
));
183 void BJIPAddr::Set(struct in_addr
* ip_addr
)
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
;
192 void BJIPAddr::Set(struct sockaddr_storage
* pStorage
)
194 memcpy(&sockAddrStorage
,pStorage
,sizeof(sockAddrStorage
));
197 sockaddr_storage
* BJIPAddr::GetRawValue()
199 return &sockAddrStorage
;
202 struct in6_addr
* BJIPAddr::Getin6_addr()
204 struct sockaddr_in6
* pAddrIn
= (sockaddr_in6
*) &sockAddrStorage
;
205 return &pAddrIn
->sin6_addr
;
208 BJ_UINT16
BJIPAddr::GetPortNumber()
211 if (sockAddrStorage
.ss_family
== AF_INET
)
213 struct sockaddr_in
* pAddrIn
= (struct sockaddr_in
*)&sockAddrStorage
;
214 port
= ntohs(pAddrIn
->sin_port
);
216 else if (sockAddrStorage
.ss_family
== AF_INET6
)
218 struct sockaddr_in6
* pAddrIn
= (struct sockaddr_in6
*)&sockAddrStorage
;
219 port
= ntohs(pAddrIn
->sin6_port
);
224 BJ_COMPARE
BJIPAddr::Compare(BJIPAddr
* pIPAddr
)
226 if (sockAddrStorage
.ss_family
> pIPAddr
->sockAddrStorage
.ss_family
)
228 if (sockAddrStorage
.ss_family
< pIPAddr
->sockAddrStorage
.ss_family
)
231 if (sockAddrStorage
.ss_family
== AF_INET
)
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
)
237 if (pMyAddrIn
->sin_addr
.s_addr
< pAddrIn
->sin_addr
.s_addr
)
244 struct sockaddr_in6
* pMyAddrIn
= (sockaddr_in6
*) &sockAddrStorage
;
245 struct sockaddr_in6
* pAddrIn
= (sockaddr_in6
*) &pIPAddr
->sockAddrStorage
;
247 int result
= memcmp(&pMyAddrIn
->sin6_addr
, &pAddrIn
->sin6_addr
, sizeof(sockaddr_in6
));
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
271 void BJIPAddr::CreateLinkLocalIPv6(BJ_UINT8
* pmac
)
273 memset(&sockAddrStorage
,0,sizeof(sockAddrStorage
));
274 struct sockaddr_in6
* pAddrIn
= (sockaddr_in6
*) &sockAddrStorage
;
276 pAddrIn
->sin6_family
= AF_INET6
;
278 pAddrIn
->sin6_addr
.__u6_addr
.__u6_addr8
[0] = 0xfe;
279 pAddrIn
->sin6_addr
.__u6_addr
.__u6_addr8
[1] = 0x80;
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);
286 pAddrIn
->sin6_addr
.__u6_addr
.__u6_addr8
[11] = 0xff;
287 pAddrIn
->sin6_addr
.__u6_addr
.__u6_addr8
[12] = 0xfe;
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);
297 char* BJIPAddr::GetString()
299 memset(stringbuffer
,0,sizeof(stringbuffer
));
302 struct sockaddr_in6
* pAddrIn
= (sockaddr_in6
*) &sockAddrStorage
;
303 inet_ntop(AF_INET6
, &pAddrIn
->sin6_addr
, stringbuffer
, sizeof(stringbuffer
));
307 struct sockaddr_in
* pAddrIn
= (sockaddr_in
*) &sockAddrStorage
;
308 inet_ntop(AF_INET
, &pAddrIn
->sin_addr
, stringbuffer
, sizeof(stringbuffer
));