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));