summaryrefslogtreecommitdiffstats
path: root/mDNSResponder/mDNSMacOSX/BonjourTop/source/bjIPAddr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mDNSResponder/mDNSMacOSX/BonjourTop/source/bjIPAddr.cpp')
-rw-r--r--mDNSResponder/mDNSMacOSX/BonjourTop/source/bjIPAddr.cpp312
1 files changed, 312 insertions, 0 deletions
diff --git a/mDNSResponder/mDNSMacOSX/BonjourTop/source/bjIPAddr.cpp b/mDNSResponder/mDNSMacOSX/BonjourTop/source/bjIPAddr.cpp
new file mode 100644
index 00000000..188f962e
--- /dev/null
+++ b/mDNSResponder/mDNSMacOSX/BonjourTop/source/bjIPAddr.cpp
@@ -0,0 +1,312 @@
+//
+// bjIPAddr.cpp
+// TestTB
+//
+// Created by Terrin Eager on 1/19/13.
+//
+//
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include "bjIPAddr.h"
+#include "bjstring.h"
+
+
+// static
+sockaddr_storage BJIPAddr::emptySockAddrStorage;
+
+
+
+BJIPAddr::BJIPAddr()
+{
+ memset(&emptySockAddrStorage,0,sizeof(emptySockAddrStorage));
+ Empty();
+}
+
+BJIPAddr::BJIPAddr(const BJIPAddr& src)
+{
+ memcpy(&sockAddrStorage,&src.sockAddrStorage,sizeof(sockAddrStorage));
+ IPv4SubNet = src.IPv4SubNet;
+}
+void BJIPAddr::Empty()
+{
+ memset(&sockAddrStorage,0,sizeof(sockAddrStorage));
+ IPv4SubNet = 0;
+
+}
+
+bool BJIPAddr::IsBonjourMulticast()
+{
+ bool bResult = false;
+
+ struct in_addr BonjourMulicastAddrIPv4= {0xFB0000E0};
+
+ struct in6_addr BonjourMulicastAddrIPv6 = {{{ 0xFF,0x02,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xFB }}};
+
+
+ if (sockAddrStorage.ss_family == AF_INET)
+ {
+ struct sockaddr_in* pAddrIn = (sockaddr_in*) &sockAddrStorage;
+ return (pAddrIn->sin_addr.s_addr == BonjourMulicastAddrIPv4.s_addr);
+ }
+
+ if (sockAddrStorage.ss_family == AF_INET6)
+ {
+ struct sockaddr_in6* pAddrIn = (sockaddr_in6*) &sockAddrStorage;
+ return (memcmp(&pAddrIn->sin6_addr,&BonjourMulicastAddrIPv6,sizeof(in6_addr)) == 0);
+ }
+
+
+ return bResult;
+
+}
+
+bool BJIPAddr::IsSameSubNet(BJIPAddr* pCheckAddr)
+{
+
+ if (IPv4SubNet == 0)
+ return true;
+
+ if (!pCheckAddr->IsIPv4())
+ return true;
+
+ in_addr_t Mask = 0xFFFFFFFF;
+
+ Mask = Mask << (32-IPv4SubNet);
+
+ endian_swap(Mask);
+
+ struct sockaddr_in* pMyAddrIn = (sockaddr_in*) &sockAddrStorage;
+ in_addr_t myNetworkAddress = pMyAddrIn->sin_addr.s_addr & Mask;
+
+ struct sockaddr_in* pCheckAddrIn = (sockaddr_in*) pCheckAddr->GetRawValue();
+ in_addr_t CheckNetworkAddress = pCheckAddrIn->sin_addr.s_addr & Mask;
+
+
+ return (myNetworkAddress == CheckNetworkAddress);
+}
+
+
+bool BJIPAddr::IsIPv4()
+{
+ return (sockAddrStorage.ss_family == AF_INET);
+}
+
+bool BJIPAddr::IsIPv6()
+{
+ return (sockAddrStorage.ss_family == AF_INET6);
+}
+
+bool BJIPAddr::IsIPv6LinkLocal()
+{
+ struct sockaddr_in6* pAddrIn = (sockaddr_in6*) &sockAddrStorage;
+ return (pAddrIn->sin6_addr.__u6_addr.__u6_addr8[0] == 0xfe &&
+ pAddrIn->sin6_addr.__u6_addr.__u6_addr8[1] == 0x80);
+}
+bool BJIPAddr::IsEmpty()
+{
+ return (memcmp(&sockAddrStorage,&emptySockAddrStorage,sizeof(sockAddrStorage)) == 0);
+}
+
+bool BJIPAddr::IsEmptySubnet()
+{
+ return (IPv4SubNet == 0);
+}
+
+void BJIPAddr::Setv6(const char* pIPaddr)
+{
+ memset(&sockAddrStorage,0,sizeof(sockAddrStorage));
+ struct sockaddr_in6* pAddrIn = (sockaddr_in6*) &sockAddrStorage;
+
+ if (inet_pton(AF_INET6, pIPaddr, &pAddrIn->sin6_addr) && memcmp(&sockAddrStorage,&emptySockAddrStorage,sizeof(sockAddrStorage)) == 0)
+ pAddrIn->sin6_family = AF_INET6;
+}
+
+void BJIPAddr::Set(const char* pIPaddr)
+{
+ memset(&sockAddrStorage,0,sizeof(sockAddrStorage));
+
+ if (pIPaddr == NULL || strlen(pIPaddr) == 0)
+ return;
+
+ BJString sIPAddr;
+ BJString sMask;
+
+ const char* pSeperator = strstr(pIPaddr,"/");
+ if (pSeperator)
+ {
+ sIPAddr.Set(pIPaddr, (BJ_UINT32)(pSeperator - pIPaddr));
+ sMask.Set(pSeperator+1);
+ }
+ else
+ {
+ sIPAddr.Set(pIPaddr);
+ }
+
+ struct sockaddr_in* pAddrIn = (sockaddr_in*) &sockAddrStorage;
+ pAddrIn->sin_family = AF_INET;
+ pAddrIn->sin_addr.s_addr = inet_addr(sIPAddr.GetBuffer());
+
+ IPv4SubNet = sMask.GetUINT32();
+
+}
+void BJIPAddr::Setv4Raw(BJ_UINT8* ipi4_addr)
+{
+
+ memset(&sockAddrStorage,0,sizeof(sockAddrStorage));
+ struct sockaddr_in* pAddrIn = (sockaddr_in*) &sockAddrStorage;
+ pAddrIn->sin_family = AF_INET;
+ memcpy(&pAddrIn->sin_addr, ipi4_addr, sizeof(pAddrIn->sin_addr));
+
+}
+void BJIPAddr::Setv6Raw(BJ_UINT8* ipi6_addr)
+{
+
+ memset(&sockAddrStorage,0,sizeof(sockAddrStorage));
+ struct sockaddr_in6* pAddrIn = (sockaddr_in6*) &sockAddrStorage;
+
+ pAddrIn->sin6_family = AF_INET6;
+ memcpy(&pAddrIn->sin6_addr, ipi6_addr, sizeof(pAddrIn->sin6_addr));
+}
+
+void BJIPAddr::Set(struct in6_addr* ipi6_addr)
+{
+
+ memset(&sockAddrStorage,0,sizeof(sockAddrStorage));
+ struct sockaddr_in6* pAddrIn = (sockaddr_in6*) &sockAddrStorage;
+
+ pAddrIn->sin6_family = AF_INET6;
+ memcpy(&pAddrIn->sin6_addr, ipi6_addr, sizeof(pAddrIn->sin6_addr));
+}
+
+void BJIPAddr::Set(struct in_addr* ip_addr)
+{
+
+ memset(&sockAddrStorage,0,sizeof(sockAddrStorage));
+ struct sockaddr_in* pAddrIn = (sockaddr_in*) &sockAddrStorage;
+ pAddrIn->sin_family = AF_INET;
+ pAddrIn->sin_addr = *ip_addr;
+}
+
+void BJIPAddr::Set(struct sockaddr_storage* pStorage)
+{
+ memcpy(&sockAddrStorage,pStorage,sizeof(sockAddrStorage));
+}
+
+sockaddr_storage* BJIPAddr::GetRawValue()
+{
+ return &sockAddrStorage;
+}
+
+struct in6_addr* BJIPAddr::Getin6_addr()
+{
+ struct sockaddr_in6* pAddrIn = (sockaddr_in6*) &sockAddrStorage;
+ return &pAddrIn->sin6_addr;
+}
+
+BJ_UINT16 BJIPAddr::GetPortNumber()
+{
+ BJ_UINT16 port = 0;
+ if (sockAddrStorage.ss_family == AF_INET)
+ {
+ struct sockaddr_in* pAddrIn = (struct sockaddr_in*)&sockAddrStorage;
+ port = ntohs(pAddrIn->sin_port);
+ }
+ else if (sockAddrStorage.ss_family == AF_INET6)
+ {
+ struct sockaddr_in6* pAddrIn = (struct sockaddr_in6*)&sockAddrStorage;
+ port = ntohs(pAddrIn->sin6_port);
+ }
+ return port;
+}
+
+BJ_COMPARE BJIPAddr::Compare(BJIPAddr* pIPAddr)
+{
+ if (sockAddrStorage.ss_family > pIPAddr->sockAddrStorage.ss_family)
+ return BJ_GT;
+ if (sockAddrStorage.ss_family < pIPAddr->sockAddrStorage.ss_family)
+ return BJ_LT;
+
+ if (sockAddrStorage.ss_family == AF_INET)
+ {
+ struct sockaddr_in* pMyAddrIn = (sockaddr_in*) &sockAddrStorage;
+ struct sockaddr_in* pAddrIn = (sockaddr_in*) &pIPAddr->sockAddrStorage;
+ if (pMyAddrIn->sin_addr.s_addr > pAddrIn->sin_addr.s_addr)
+ return BJ_GT;
+ if (pMyAddrIn->sin_addr.s_addr < pAddrIn->sin_addr.s_addr)
+ return BJ_LT;
+ return BJ_EQUAL;
+
+ }
+ else
+ {
+ struct sockaddr_in6* pMyAddrIn = (sockaddr_in6*) &sockAddrStorage;
+ struct sockaddr_in6* pAddrIn = (sockaddr_in6*) &pIPAddr->sockAddrStorage;
+
+ int result = memcmp(&pMyAddrIn->sin6_addr, &pAddrIn->sin6_addr, sizeof(sockaddr_in6));
+
+ if (result > 0)
+ return BJ_GT;
+ if (result < 0)
+ return BJ_LT;
+ return BJ_EQUAL;
+ }
+
+
+}
+
+/*
+
+ take the mac address: for example 52:74:f2:b1:a8:7f
+ throw ff:fe in the middle: 52:74:f2:ff:fe:b1:a8:7f
+ reformat to IPv6 notation 5274:f2ff:feb1:a87f
+ convert the first octet from hexadecimal to binary: 52 -> 01010010
+ invert the bit at position 6 (counting from 0): 01010010 -> 01010000
+ convert octet back to hexadecimal: 01010000 -> 50
+ replace first octet with newly calculated one: 5074:f2ff:feb1:a87f
+ prepend the link-local prefix: fe80::5074:f2ff:feb1:a87f
+ */
+
+void BJIPAddr::CreateLinkLocalIPv6(BJ_UINT8* pmac)
+{
+ memset(&sockAddrStorage,0,sizeof(sockAddrStorage));
+ struct sockaddr_in6* pAddrIn = (sockaddr_in6*) &sockAddrStorage;
+
+ pAddrIn->sin6_family = AF_INET6;
+
+ pAddrIn->sin6_addr.__u6_addr.__u6_addr8[0] = 0xfe;
+ pAddrIn->sin6_addr.__u6_addr.__u6_addr8[1] = 0x80;
+
+ pAddrIn->sin6_addr.__u6_addr.__u6_addr8[8] = *pmac;
+ pAddrIn->sin6_addr.__u6_addr.__u6_addr8[8] ^= 1 << 1; // invert 6 bit
+ pAddrIn->sin6_addr.__u6_addr.__u6_addr8[9] = *(pmac+1);
+ pAddrIn->sin6_addr.__u6_addr.__u6_addr8[10] = *(pmac+2);
+
+ pAddrIn->sin6_addr.__u6_addr.__u6_addr8[11] = 0xff;
+ pAddrIn->sin6_addr.__u6_addr.__u6_addr8[12] = 0xfe;
+
+
+ pAddrIn->sin6_addr.__u6_addr.__u6_addr8[13] = *(pmac+3);
+ pAddrIn->sin6_addr.__u6_addr.__u6_addr8[14] = *(pmac+4);
+ pAddrIn->sin6_addr.__u6_addr.__u6_addr8[15] = *(pmac+5);
+
+
+}
+
+char* BJIPAddr::GetString()
+{
+ memset(stringbuffer,0,sizeof(stringbuffer));
+ if (IsIPv6())
+ {
+ struct sockaddr_in6* pAddrIn = (sockaddr_in6*) &sockAddrStorage;
+ inet_ntop(AF_INET6, &pAddrIn->sin6_addr, stringbuffer, sizeof(stringbuffer));
+ }
+ else
+ {
+ struct sockaddr_in* pAddrIn = (sockaddr_in*) &sockAddrStorage;
+ inet_ntop(AF_INET, &pAddrIn->sin_addr, stringbuffer, sizeof(stringbuffer));
+ }
+ return stringbuffer;
+}
+