Skip to content

Commit

Permalink
Network - Add DNS namespace
Browse files Browse the repository at this point in the history
  • Loading branch information
nlogozzo committed Jul 24, 2024
1 parent 30c7adc commit b10e297
Show file tree
Hide file tree
Showing 8 changed files with 170 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
- Added `Nickvision::Events::Event::count()` method
- Added `Nickvision::Events::Event::operator bool()` method
#### Network
- Added `Nickvision::Network::DNS` namespace
- Added `Nickvision::Network::IPv4Address` class
- Added `Nickvision::Network::MacAddress` class
### Fixes
Expand Down
3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ add_library (${PROJECT_NAME}
"src/localization/gettext.cpp"
"src/logging/logger.cpp"
"src/network/curleasy.cpp"
"src/network/dns.cpp"
"src/network/ipv4address.cpp"
"src/network/macaddress.cpp"
"src/network/networkmonitor.cpp"
Expand Down Expand Up @@ -94,7 +95,7 @@ if(USING_VCPKG)
endif()
if(WIN32)
find_package(sqlcipher CONFIG REQUIRED)
target_link_libraries(${PROJECT_NAME} PUBLIC sqlcipher::sqlcipher Advapi32 Dwmapi Gdiplus Kernel32 Shell32 UxTheme)
target_link_libraries(${PROJECT_NAME} PUBLIC sqlcipher::sqlcipher Advapi32 Dnsapi Dwmapi Gdiplus Kernel32 Shell32 UxTheme)
elseif(LINUX)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
Expand Down
40 changes: 40 additions & 0 deletions include/network/dns.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* @file
* @author Nicholas Logozzo <[email protected]>
*
* @section LICENSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 3 of
* the License, or (at your option) any later version.
*
* This program 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 at
* https://www.gnu.org/copyleft/gpl.html
*
* @section DESCRIPTION
*
* Functions for working with DNS.
*/

#ifndef DNS_H
#define DNS_H

#include <string>
#include <vector>
#include "ipv4address.h"

namespace Nickvision::Network::DNS
{
/**
* @brief Resolves a hostname to IPv4 addresses.
* @param hostname The hostname to resolve
* @return A list of IPv4 addresses that the hostname resolves to
*/
std::vector<IPv4Address> resolve(const std::string& hostname);
}

#endif //DNS_H
27 changes: 27 additions & 0 deletions include/network/ipv4address.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
/**
* @file
* @author Nicholas Logozzo <[email protected]>
*
* @section LICENSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 3 of
* the License, or (at your option) any later version.
*
* This program 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 at
* https://www.gnu.org/copyleft/gpl.html
*
* @section DESCRIPTION
*
* A model of an IPv4 address.
*/

#ifndef IPV4ADDRESS_H
#define IPV4ADDRESS_H

Expand All @@ -20,6 +42,11 @@ namespace Nickvision::Network
* @param fourth The fourth byte of the address
*/
IPv4Address(unsigned char first, unsigned char second, unsigned char third, unsigned char fourth);
/**
* @brief Constructs an IPv4Address.
* @param address The address as a long
*/
IPv4Address(unsigned long address);
/**
* @brief Gets the first byte of the address.
* @return The first byte of the address
Expand Down
22 changes: 22 additions & 0 deletions include/network/macaddress.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
/**
* @file
* @author Nicholas Logozzo <[email protected]>
*
* @section LICENSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 3 of
* the License, or (at your option) any later version.
*
* This program 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 at
* https://www.gnu.org/copyleft/gpl.html
*
* @section DESCRIPTION
*
* A model of a MAC address.
*/

#ifndef MACADDRESS_H
#define MACADDRESS_H

Expand Down
53 changes: 53 additions & 0 deletions src/network/dns.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#include "network/dns.h"
#ifdef _WIN32
#include <windows.h>
#include <windns.h>
#elif defined(__linux__)
#include <gio/gio.h>
#endif

namespace Nickvision::Network
{
std::vector<IPv4Address> DNS::resolve(const std::string& hostname)
{
std::vector<IPv4Address> addresses;
#ifdef _WIN32
DNS_RECORDA* record{ nullptr };
if(DnsQuery_A(hostname.c_str(), DNS_TYPE_A, DNS_QUERY_STANDARD, nullptr, &record, nullptr) == 0)
{
DNS_RECORDA* next{ record };
while(next)
{
if(next->wType == DNS_TYPE_A)
{
addresses.push_back({ next->Data.A.IpAddress });
}
next = next->pNext;
}
}
DnsFree(record, DnsFreeRecordList);

#else
GResolver* resolver{ g_resolver_get_default() };
GList* records{ g_resolver_lookup_by_name(resolver, hostname.c_str(), nullptr, nullptr) };
if(records)
{
GList* next{ records };
while(next)
{
GInetAddress* address{ G_INET_ADDRESS(next->data) };
if(g_inet_address_get_family(address) == G_SOCKET_FAMILY_IPV4)
{
gchar* str{ g_inet_address_to_string(address) };
addresses.push_back(*IPv4Address::parse(str));
g_free(str);
}
next = next->next;
}
g_resolver_free_addresses(records);
}
g_object_unref(resolver);
#endif
return addresses;
}
}
9 changes: 9 additions & 0 deletions src/network/ipv4address.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ namespace Nickvision::Network

}

IPv4Address::IPv4Address(unsigned long address)
: m_first{ static_cast<unsigned char>((address >> 24) & 0xFF) },
m_second{ static_cast<unsigned char>((address >> 16) & 0xFF) },
m_third{ static_cast<unsigned char>((address >> 8) & 0xFF) },
m_fourth{ static_cast<unsigned char>(address & 0xFF) }
{

}

unsigned char IPv4Address::getFirst() const
{
return m_first;
Expand Down
16 changes: 16 additions & 0 deletions tests/networktests.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <gtest/gtest.h>
#include "network/dns.h"
#include "network/ipv4address.h"
#include "network/macaddress.h"
#include "network/networkmonitor.h"
Expand Down Expand Up @@ -83,6 +84,16 @@ TEST_F(NetworkTest, IPv4Address3)
ASSERT_FALSE(ip.has_value());
}

TEST_F(NetworkTest, IPv4Address4)
{
IPv4Address ip{ 0x7F000001 };
ASSERT_EQ(ip.getFirst(), 127);
ASSERT_EQ(ip.getSecond(), 0);
ASSERT_EQ(ip.getThird(), 0);
ASSERT_EQ(ip.getFourth(), 1);
ASSERT_EQ(ip.str(), "127.0.0.1");
}

TEST_F(NetworkTest, MacAddress1)
{
MacAddress mac{ 0x00, 0x1A, 0x2B, 0x3C, 0x4D, 0x5E };
Expand Down Expand Up @@ -112,4 +123,9 @@ TEST_F(NetworkTest, MacAddress3)
{
std::optional<MacAddress> mac{ MacAddress::parse("00:1A:2B:3C:4D") };
ASSERT_FALSE(mac.has_value());
}

TEST_F(NetworkTest, Dns1)
{
ASSERT_FALSE(DNS::resolve("www.google.com").empty());
}

0 comments on commit b10e297

Please sign in to comment.