diff --git a/extras/JuceDemo/Source/ApplicationStartup.cpp b/extras/JuceDemo/Source/ApplicationStartup.cpp index 2240c2dddd..e3db4e10da 100644 --- a/extras/JuceDemo/Source/ApplicationStartup.cpp +++ b/extras/JuceDemo/Source/ApplicationStartup.cpp @@ -126,6 +126,7 @@ private: << "CPU has 3DNOW: " << (SystemStats::has3DNow() ? "yes" : "no") << newLine << "Found network card MAC addresses: " << getMacAddressList() << newLine + << "Found IP addresses: " << getIPAddressList() << newLine << "Current working directory: " << File::getCurrentWorkingDirectory().getFullPathName() << newLine << "Current executable file: " << File::getSpecialLocation (File::currentExecutableFile).getFullPathName() << newLine @@ -151,6 +152,18 @@ private: return addressStrings.joinIntoString (", "); } + + static String getIPAddressList() + { + Array addresses; + IPAddress::findAllAddresses (addresses); + + StringArray addressStrings; + for (int i = 0; i < addresses.size(); ++i) + addressStrings.add (addresses[i].toString()); + + return addressStrings.joinIntoString (", "); + } }; diff --git a/modules/juce_core/juce_core.cpp b/modules/juce_core/juce_core.cpp index bf01ab4d93..f1e85e0f7c 100644 --- a/modules/juce_core/juce_core.cpp +++ b/modules/juce_core/juce_core.cpp @@ -84,6 +84,8 @@ #include #include #include + #include + #include #if ! JUCE_ANDROID #include @@ -128,6 +130,7 @@ namespace juce #include "network/juce_NamedPipe.cpp" #include "network/juce_Socket.cpp" #include "network/juce_URL.cpp" +#include "network/juce_IPAddress.cpp" #include "streams/juce_BufferedInputStream.cpp" #include "streams/juce_FileInputSource.cpp" #include "streams/juce_InputStream.cpp" diff --git a/modules/juce_core/juce_core.h b/modules/juce_core/juce_core.h index 469b0fd62a..8001ff1784 100644 --- a/modules/juce_core/juce_core.h +++ b/modules/juce_core/juce_core.h @@ -280,6 +280,9 @@ namespace juce #ifndef __JUCE_WINDOWSREGISTRY_JUCEHEADER__ #include "misc/juce_WindowsRegistry.h" #endif +#ifndef __JUCE_IPADDRESS_JUCEHEADER__ + #include "network/juce_IPAddress.h" +#endif #ifndef __JUCE_MACADDRESS_JUCEHEADER__ #include "network/juce_MACAddress.h" #endif diff --git a/modules/juce_core/native/juce_win32_Network.cpp b/modules/juce_core/native/juce_win32_Network.cpp index 58fba604e9..d76990170f 100644 --- a/modules/juce_core/native/juce_win32_Network.cpp +++ b/modules/juce_core/native/juce_win32_Network.cpp @@ -315,27 +315,39 @@ InputStream* URL::createNativeStream (const String& address, bool isPost, const //============================================================================== -namespace MACAddressHelpers +struct GetAdaptersInfoHelper { - void getViaGetAdaptersInfo (Array& result) + bool callGetAdaptersInfo() { DynamicLibrary dll ("iphlpapi.dll"); JUCE_LOAD_WINAPI_FUNCTION (dll, GetAdaptersInfo, getAdaptersInfo, DWORD, (PIP_ADAPTER_INFO, PULONG)) - if (getAdaptersInfo != nullptr) + if (getAdaptersInfo == nullptr) + return false; + + adapterInfo.malloc (1); + ULONG len = sizeof (IP_ADAPTER_INFO); + + if (getAdaptersInfo (adapterInfo, &len) == ERROR_BUFFER_OVERFLOW) + adapterInfo.malloc (len, 1); + + return getAdaptersInfo (adapterInfo, &len) == NO_ERROR; + } + + HeapBlock adapterInfo; +}; + +namespace MACAddressHelpers +{ + void getViaGetAdaptersInfo (Array& result) + { + GetAdaptersInfoHelper gah; + + if (gah.callGetAdaptersInfo()) { - ULONG len = sizeof (IP_ADAPTER_INFO); - HeapBlock adapterInfo (1); - - if (getAdaptersInfo (adapterInfo, &len) == ERROR_BUFFER_OVERFLOW) - adapterInfo.malloc (len, 1); - - if (getAdaptersInfo (adapterInfo, &len) == NO_ERROR) - { - for (PIP_ADAPTER_INFO adapter = adapterInfo; adapter != nullptr; adapter = adapter->Next) - if (adapter->AddressLength >= 6) - result.addIfNotAlreadyThere (MACAddress (adapter->Address)); - } + for (PIP_ADAPTER_INFO adapter = gah.adapterInfo; adapter != nullptr; adapter = adapter->Next) + if (adapter->AddressLength >= 6) + result.addIfNotAlreadyThere (MACAddress (adapter->Address)); } } @@ -394,6 +406,24 @@ void MACAddress::findAllAddresses (Array& result) MACAddressHelpers::getViaNetBios (result); } +void IPAddress::findAllAddresses (Array& result) +{ + result.addIfNotAlreadyThere (IPAddress::local()); + + GetAdaptersInfoHelper gah; + + if (gah.callGetAdaptersInfo()) + { + for (PIP_ADAPTER_INFO adapter = gah.adapterInfo; adapter != nullptr; adapter = adapter->Next) + { + IPAddress ip (adapter->IpAddressList.IpAddress.String); + + if (ip != IPAddress::any()) + result.addIfNotAlreadyThere (ip); + } + } +} + //============================================================================== bool Process::openEmailWithAttachments (const String& targetEmailAddress, const String& emailSubject, diff --git a/modules/juce_core/network/juce_IPAddress.cpp b/modules/juce_core/network/juce_IPAddress.cpp new file mode 100644 index 0000000000..2f6cda7bb3 --- /dev/null +++ b/modules/juce_core/network/juce_IPAddress.cpp @@ -0,0 +1,149 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-11 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +IPAddress::IPAddress() noexcept +{ + address[0] = 0; address[1] = 0; + address[2] = 0; address[3] = 0; +} + +IPAddress::IPAddress (const uint8 bytes[4]) noexcept +{ + address[0] = bytes[0]; address[1] = bytes[1]; + address[2] = bytes[2]; address[3] = bytes[3]; +} + +IPAddress::IPAddress (uint8 a0, uint8 a1, uint8 a2, uint8 a3) noexcept +{ + address[0] = a0; address[1] = a1; + address[2] = a2; address[3] = a3; +} + +IPAddress::IPAddress (uint32 n) noexcept +{ + address[0] = (n >> 24); + address[1] = (n >> 16) & 255; + address[2] = (n >> 8) & 255; + address[3] = (n & 255); +} + +IPAddress::IPAddress (const String& adr) +{ + StringArray tokens; + tokens.addTokens (adr, ".", String::empty); + + for (int i = 0; i < 4; ++i) + address[i] = (uint8) tokens[i].getIntValue(); +} + +String IPAddress::toString() const +{ + String s ((int) address[0]); + + for (int i = 1; i < 4; ++i) + s << '.' << (int) address[i]; + + return s; +} + +IPAddress IPAddress::any() noexcept { return IPAddress(); } +IPAddress IPAddress::broadcast() noexcept { return IPAddress (255, 255, 255, 255); } +IPAddress IPAddress::local() noexcept { return IPAddress (127, 0, 0, 1); } + +bool IPAddress::operator== (const IPAddress& other) const noexcept +{ + return address[0] == other.address[0] + && address[1] == other.address[1] + && address[2] == other.address[2] + && address[3] == other.address[3]; +} + +bool IPAddress::operator!= (const IPAddress& other) const noexcept +{ + return ! operator== (other); +} + +#if ! JUCE_WINDOWS +static void addAddress (const sockaddr_in* addr_in, Array& result) +{ + in_addr_t addr = addr_in->sin_addr.s_addr; + + if (addr != INADDR_NONE) + result.addIfNotAlreadyThere (IPAddress (ntohl (addr))); +} + +static void findIPAddresses (int sock, Array& result) +{ + ifconf cfg; + HeapBlock buffer; + size_t bufferSize = 4096; + + const size_t ifreq_size_in = IFNAMSIZ + sizeof (struct sockaddr_in); + const size_t ifreq_size_in6 = IFNAMSIZ + sizeof (struct sockaddr_in6); + + do + { + bufferSize *= 2; + buffer.calloc (bufferSize); + + cfg.ifc_len = bufferSize; + cfg.ifc_buf = buffer; + + if (ioctl (sock, SIOCGIFCONF, &cfg) < 0 && errno != EINVAL) + return; + + } while (bufferSize < cfg.ifc_len + 2 * ifreq_size_in6); + + #if JUCE_MAC || JUCE_IOS + while (cfg.ifc_len >= (int) ifreq_size_in) + { + if (cfg.ifc_req->ifr_addr.sa_family == AF_INET) // Skip non-internet addresses + addAddress ((const sockaddr_in*) &cfg.ifc_req->ifr_addr, result); + + cfg.ifc_len -= IFNAMSIZ + cfg.ifc_req->ifr_addr.sa_len; + cfg.ifc_buf += IFNAMSIZ + cfg.ifc_req->ifr_addr.sa_len; + } + #else + for (int i = 0; i < cfg.ifc_len / sizeof (struct ifreq); ++i) + { + const ifreq& item = cfg.ifc_req[i]; + + if (item.ifr_addr.sa_family == AF_INET) + addAddress ((const sockaddr_in*) &item.ifr_addr, result); + } + #endif +} + +void IPAddress::findAllAddresses (Array& result) +{ + const int sock = socket (AF_INET, SOCK_DGRAM, 0); // a dummy socket to execute the IO control + + if (sock >= 0) + { + findIPAddresses (sock, result); + ::close (sock); + } +} +#endif diff --git a/modules/juce_core/network/juce_IPAddress.h b/modules/juce_core/network/juce_IPAddress.h new file mode 100644 index 0000000000..26a826ff03 --- /dev/null +++ b/modules/juce_core/network/juce_IPAddress.h @@ -0,0 +1,79 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-11 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCE_IPADDRESS_JUCEHEADER__ +#define __JUCE_IPADDRESS_JUCEHEADER__ + + +//============================================================================== +/** + An IPV4 address. +*/ +class JUCE_API IPAddress +{ +public: + //============================================================================== + /** Populates a list of all the IP addresses that this machine is using. */ + static void findAllAddresses (Array& results); + + //============================================================================== + /** Creates a null address (0.0.0.0). */ + IPAddress() noexcept; + + /** Creates an address from 4 bytes. */ + explicit IPAddress (const uint8 bytes[4]) noexcept; + + /** Creates an address from 4 bytes. */ + IPAddress (uint8 address1, uint8 address2, uint8 address3, uint8 address4) noexcept; + + /** Creates an address from a packed 32-bit integer, where the MSB is + the first number in the address, and the LSB is the last. + */ + explicit IPAddress (uint32 asNativeEndian32Bit) noexcept; + + /** Parses a string IP address of the form "a.b.c.d". */ + explicit IPAddress (const String& address); + + /** Returns a dot-separated string in the form "1.2.3.4" */ + String toString() const; + + /** Returns an address meaning "any" (0.0.0.0) */ + static IPAddress any() noexcept; + + /** Returns an address meaning "broadcast" (255.255.255.255) */ + static IPAddress broadcast() noexcept; + + /** Returns an address meaning "localhost" (127.0.0.1) */ + static IPAddress local() noexcept; + + bool operator== (const IPAddress& other) const noexcept; + bool operator!= (const IPAddress& other) const noexcept; + + /** The elements of the IP address. */ + uint8 address[4]; +}; + + +#endif // __JUCE_IPADDRESS_JUCEHEADER__ diff --git a/modules/juce_core/zip/juce_GZIPDecompressorInputStream.cpp b/modules/juce_core/zip/juce_GZIPDecompressorInputStream.cpp index d0621900b0..db233cc474 100644 --- a/modules/juce_core/zip/juce_GZIPDecompressorInputStream.cpp +++ b/modules/juce_core/zip/juce_GZIPDecompressorInputStream.cpp @@ -62,6 +62,7 @@ namespace zlibNamespace #include "zlib/zutil.c" #undef Byte #undef fdopen + #undef local #if JUCE_CLANG #pragma clang diagnostic pop