diff --git a/pcsx2/CMakeLists.txt b/pcsx2/CMakeLists.txt index 0898861cca..622a8dc3bb 100644 --- a/pcsx2/CMakeLists.txt +++ b/pcsx2/CMakeLists.txt @@ -355,6 +355,7 @@ set(pcsx2DEV9Sources DEV9/ATA/ATA_Transfer.cpp DEV9/ATA/HddCreate.cpp DEV9/InternalServers/DHCP_Server.cpp + DEV9/InternalServers/DNS_Logger.cpp DEV9/InternalServers/DNS_Server.cpp DEV9/PacketReader/IP/UDP/DHCP/DHCP_Options.cpp DEV9/PacketReader/IP/UDP/DHCP/DHCP_Packet.cpp @@ -380,6 +381,7 @@ set(pcsx2DEV9Headers DEV9/ATA/HddCreate.h DEV9/DEV9.h DEV9/InternalServers/DHCP_Server.cpp + DEV9/InternalServers/DNS_Logger.h DEV9/InternalServers/DNS_Server.h DEV9/net.h DEV9/PacketReader/IP/UDP/DHCP/DHCP_Options.h diff --git a/pcsx2/DEV9/DEV9.h b/pcsx2/DEV9/DEV9.h index c8363b20ec..337efe7702 100644 --- a/pcsx2/DEV9/DEV9.h +++ b/pcsx2/DEV9/DEV9.h @@ -77,6 +77,7 @@ struct ConfigDEV9 int AutoGateway; int AutoDNS1; int AutoDNS2; + int EthLogDNS; std::vector EthHosts; #ifdef _WIN32 wchar_t Hdd[256]; diff --git a/pcsx2/DEV9/DEV9Config.cpp b/pcsx2/DEV9/DEV9Config.cpp index c0aecfd26f..ba10d6930c 100644 --- a/pcsx2/DEV9/DEV9Config.cpp +++ b/pcsx2/DEV9/DEV9Config.cpp @@ -105,7 +105,7 @@ void LoadDnsHosts() else ini.Entry(L"Enabled", entry.Enabled, false); - if (entry.Enabled) + if (config.EthLogDNS && entry.Enabled) Console.WriteLn("DEV9: Host entry %i: url %s mapped to %s", i, entry.Url.c_str(), tmp.ToStdString().c_str()); config.EthHosts.push_back(entry); diff --git a/pcsx2/DEV9/InternalServers/DNS_Logger.cpp b/pcsx2/DEV9/InternalServers/DNS_Logger.cpp new file mode 100644 index 0000000000..378a83065e --- /dev/null +++ b/pcsx2/DEV9/InternalServers/DNS_Logger.cpp @@ -0,0 +1,166 @@ +/* PCSX2 - PS2 Emulator for PCs + * Copyright (C) 2002-2021 PCSX2 Dev Team + * + * PCSX2 is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * PCSX2 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. + * + * You should have received a copy of the GNU General Public License along with PCSX2. + * If not, see . + */ + +#include "PrecompiledHeader.h" + +#include "DNS_Logger.h" +#include "DEV9/PacketReader/IP/UDP/UDP_Packet.h" +#include "DEV9/PacketReader/IP/UDP/DNS/DNS_Packet.h" + +using PacketReader::PayloadPtr; +using namespace PacketReader::IP; +using namespace PacketReader::IP::UDP; +using namespace PacketReader::IP::UDP::DNS; + +namespace InternalServers +{ + void DNS_Logger::InspectRecv(IP_Payload* payload) + { + UDP_Packet* udpPacket = static_cast(payload); + PayloadPtr* udpPayload = static_cast(udpPacket->GetPayload()); + DNS_Packet dns(udpPayload->data, udpPayload->GetLength()); + LogPacket(&dns); + } + + void DNS_Logger::InspectSend(IP_Payload* payload) + { + UDP_Packet* udpPacket = static_cast(payload); + PayloadPtr* udpPayload = static_cast(udpPacket->GetPayload()); + DNS_Packet dns(udpPayload->data, udpPayload->GetLength()); + LogPacket(&dns); + } + + std::string DNS_Logger::VectorToString(const std::vector& data) + { + std::string str; + if (data.size() != 0) + { + str.reserve(data.size() * 4); + for (size_t i = 0; i < data.size(); i++) + str += std::to_string(data[i]) + ":"; + + str.pop_back(); + } //else leave string empty + + return str; + } + + const char* DNS_Logger::OpCodeToString(DNS_OPCode opcode) + { + switch (opcode) + { + case DNS_OPCode::Query: + return "Query"; + case DNS_OPCode::IQuery: + return "IQuery"; + case DNS_OPCode::Status: + return "Status"; + case DNS_OPCode::Reserved: + return "Reserved"; + case DNS_OPCode::Notify: + return "Notify"; + case DNS_OPCode::Update: + return "Update"; + default: + return "Unknown"; + } + } + + const char* DNS_Logger::RCodeToString(DNS_RCode rcode) + { + switch (rcode) + { + case DNS_RCode::NoError: + return "NoError"; + case DNS_RCode::FormatError: + return "FormatError"; + case DNS_RCode::ServerFailure: + return "ServerFailure"; + case DNS_RCode::NameError: + return "NameError"; + case DNS_RCode::NotImplemented: + return "NotImplemented"; + case DNS_RCode::Refused: + return "Refused"; + case DNS_RCode::YXDomain: + return "YXDomain"; + case DNS_RCode::YXRRSet: + return "YXRRSet"; + case DNS_RCode::NXRRSet: + return "NXRRSet"; + case DNS_RCode::NotAuth: + return "NotAuth"; + case DNS_RCode::NotZone: + return "NotZone"; + default: + return "Unknown"; + } + } + + void DNS_Logger::LogPacket(DNS_Packet* dns) + { + Console.WriteLn("DEV9: DNS: ID %i", dns->id); + Console.WriteLn("DEV9: DNS: Is Response? %s", dns->GetQR() ? "True" : "False"); + Console.WriteLn("DEV9: DNS: OpCode %s (%i)", OpCodeToString((DNS_OPCode)dns->GetOpCode()), dns->GetOpCode()); + Console.WriteLn("DEV9: DNS: Is Authoritative (not cached)? %s", dns->GetAA() ? "True" : "False"); + Console.WriteLn("DEV9: DNS: Is Truncated? %s", dns->GetTC() ? "True" : "False"); + Console.WriteLn("DEV9: DNS: Recursion Desired? %s", dns->GetRD() ? "True" : "False"); + Console.WriteLn("DEV9: DNS: Recursion Available? %s", dns->GetRA() ? "True" : "False"); + Console.WriteLn("DEV9: DNS: Zero %i", dns->GetZ0()); + Console.WriteLn("DEV9: DNS: Authenticated Data? %s", dns->GetAD() ? "True" : "False"); + Console.WriteLn("DEV9: DNS: Checking Disabled? %s", dns->GetCD() ? "True" : "False"); + Console.WriteLn("DEV9: DNS: Result %s (%i)", RCodeToString((DNS_RCode)dns->GetRCode()), dns->GetRCode()); + + Console.WriteLn("DEV9: DNS: Question Count %i", dns->questions.size()); + Console.WriteLn("DEV9: DNS: Answer Count %i", dns->answers.size()); + Console.WriteLn("DEV9: DNS: Authority Count %i", dns->authorities.size()); + Console.WriteLn("DEV9: DNS: Additional Count %i", dns->additional.size()); + + for (size_t i = 0; i < dns->questions.size(); i++) + { + DNS_QuestionEntry entry = dns->questions[i]; + Console.WriteLn("DEV9: DNS: Q%i Name %s", i, entry.name.c_str()); + Console.WriteLn("DEV9: DNS: Q%i Type %i", i, entry.entryType); + Console.WriteLn("DEV9: DNS: Q%i Class %i", i, entry.entryClass); + } + for (size_t i = 0; i < dns->answers.size(); i++) + { + DNS_ResponseEntry entry = dns->answers[i]; + Console.WriteLn("DEV9: DNS: Ans%i Name %s", i, entry.name.c_str()); + Console.WriteLn("DEV9: DNS: Ans%i Type %i", i, entry.entryType); + Console.WriteLn("DEV9: DNS: Ans%i Class %i", i, entry.entryClass); + Console.WriteLn("DEV9: DNS: Ans%i TTL %i", i, entry.timeToLive); + Console.WriteLn("DEV9: DNS: Ans%i Data %s", i, VectorToString(entry.data).c_str()); + } + for (size_t i = 0; i < dns->authorities.size(); i++) + { + DNS_ResponseEntry entry = dns->authorities[i]; + Console.WriteLn("DEV9: DNS: Auth%i Name %s", i, entry.name.c_str()); + Console.WriteLn("DEV9: DNS: Auth%i Type %i", i, entry.entryType); + Console.WriteLn("DEV9: DNS: Auth%i Class %i", i, entry.entryClass); + Console.WriteLn("DEV9: DNS: Auth%i TTL %i", i, entry.timeToLive); + Console.WriteLn("DEV9: DNS: Auth%i Data %s", i, VectorToString(entry.data).c_str()); + } + for (size_t i = 0; i < dns->additional.size(); i++) + { + DNS_ResponseEntry entry = dns->authorities[i]; + Console.WriteLn("DEV9: DNS: Add%i Name %s", i, entry.name.c_str()); + Console.WriteLn("DEV9: DNS: Add%i Type %i", i, entry.entryType); + Console.WriteLn("DEV9: DNS: Add%i Class %i", i, entry.entryClass); + Console.WriteLn("DEV9: DNS: Add%i TTL %i", i, entry.timeToLive); + Console.WriteLn("DEV9: DNS: Add%i Data %s", i, VectorToString(entry.data).c_str()); + } + } +} // namespace InternalServers diff --git a/pcsx2/DEV9/InternalServers/DNS_Logger.h b/pcsx2/DEV9/InternalServers/DNS_Logger.h new file mode 100644 index 0000000000..eef76a58cd --- /dev/null +++ b/pcsx2/DEV9/InternalServers/DNS_Logger.h @@ -0,0 +1,38 @@ +/* PCSX2 - PS2 Emulator for PCs + * Copyright (C) 2002-2021 PCSX2 Dev Team + * + * PCSX2 is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * PCSX2 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. + * + * You should have received a copy of the GNU General Public License along with PCSX2. + * If not, see . + */ + +#pragma once +#include "DEV9/PacketReader/IP/IP_Packet.h" +#include "DEV9/PacketReader/IP/UDP/DNS/DNS_Packet.h" + +namespace InternalServers +{ + class DNS_Logger + { + public: + DNS_Logger(){}; + + //Expects a UDP_payload + void InspectRecv(PacketReader::IP::IP_Payload* payload); + //Expects a UDP_payload + void InspectSend(PacketReader::IP::IP_Payload* payload); + + private: + std::string VectorToString(const std::vector& data); + const char* OpCodeToString(PacketReader::IP::UDP::DNS::DNS_OPCode opcode); + const char* RCodeToString(PacketReader::IP::UDP::DNS::DNS_RCode rcode); + void LogPacket(PacketReader::IP::UDP::DNS::DNS_Packet* payload); + }; +} // namespace InternalServers diff --git a/pcsx2/DEV9/Linux/Config.cpp b/pcsx2/DEV9/Linux/Config.cpp index a5add8c7b1..afd62fac9d 100644 --- a/pcsx2/DEV9/Linux/Config.cpp +++ b/pcsx2/DEV9/Linux/Config.cpp @@ -90,6 +90,10 @@ void SaveConf() xmlNewChild(root_node, NULL, BAD_CAST "AutoDNS2", BAD_CAST buff); + sprintf(buff, "%d", config.EthLogDNS); + xmlNewChild(root_node, NULL, BAD_CAST "EthLogDNS", + BAD_CAST buff); + xmlNewChild(root_node, NULL, BAD_CAST "Hdd", BAD_CAST config.Hdd); @@ -201,6 +205,10 @@ void LoadConf() { config.AutoDNS2 = atoi((const char*)xmlNodeGetContent(cur_node)); } + if (0 == strcmp((const char*)cur_node->name, "EthLogDNS")) + { + config.EthLogDNS = atoi((const char*)xmlNodeGetContent(cur_node)); + } if (0 == strcmp((const char*)cur_node->name, "Hdd")) { strcpy(config.Hdd, (const char*)xmlNodeGetContent(cur_node)); diff --git a/pcsx2/DEV9/Win32/DEV9WinConfig.cpp b/pcsx2/DEV9/Win32/DEV9WinConfig.cpp index 9e79a3cd34..44876fab7e 100644 --- a/pcsx2/DEV9/Win32/DEV9WinConfig.cpp +++ b/pcsx2/DEV9/Win32/DEV9WinConfig.cpp @@ -76,6 +76,7 @@ void SaveConf() WritePrivateProfileString(L"DEV9", L"DNS2", addrBuff, file.c_str()); WritePrivateProfileInt(L"DEV9", L"AutoDNS2", config.AutoDNS2, file.c_str()); + WritePrivateProfileInt(L"DEV9", L"EthLogDNS", config.EthLogDNS, file.c_str()); WritePrivateProfileString(L"DEV9", L"Hdd", config.Hdd, file.c_str()); WritePrivateProfileInt(L"DEV9", L"HddSize", config.HddSize, file.c_str()); @@ -123,6 +124,7 @@ void LoadConf() InetPton(AF_INET, addrBuff, &config.DNS2); config.AutoDNS2 = GetPrivateProfileInt(L"DEV9", L"AutoDNS2", config.AutoDNS2, file.c_str()); + config.EthLogDNS = GetPrivateProfileInt(L"DEV9", L"EthLogDNS", config.EthLogDNS, file.c_str()); GetPrivateProfileString(L"DEV9", L"Hdd", HDD_DEF, config.Hdd, sizeof(config.Hdd), file.c_str()); config.HddSize = GetPrivateProfileInt(L"DEV9", L"HddSize", config.HddSize, file.c_str()); diff --git a/pcsx2/DEV9/Win32/tap-win32.cpp b/pcsx2/DEV9/Win32/tap-win32.cpp index aecd8163a8..de9019ccff 100644 --- a/pcsx2/DEV9/Win32/tap-win32.cpp +++ b/pcsx2/DEV9/Win32/tap-win32.cpp @@ -608,14 +608,18 @@ bool TAPAdapter::recv(NetPacket* pkt) } } - if (result) - return VerifyPkt(pkt, read_size); + if (result && VerifyPkt(pkt, read_size)) + { + InspectRecv(pkt); + return true; + } else return false; } //sends the packet .rv :true success bool TAPAdapter::send(NetPacket* pkt) { + InspectSend(pkt); if (NetAdapter::send(pkt)) return true; diff --git a/pcsx2/DEV9/net.cpp b/pcsx2/DEV9/net.cpp index 69377cf684..924530234a 100644 --- a/pcsx2/DEV9/net.cpp +++ b/pcsx2/DEV9/net.cpp @@ -237,6 +237,57 @@ NetAdapter::~NetAdapter() } } +void NetAdapter::InspectSend(NetPacket* pkt) +{ + if (config.EthLogDNS) + { + EthernetFrame frame(pkt); + if (frame.protocol == (u16)EtherType::IPv4) + { + PayloadPtr* payload = static_cast(frame.GetPayload()); + IP_Packet ippkt(payload->data, payload->GetLength()); + + if (ippkt.protocol == (u16)IP_Type::UDP) + { + IP_PayloadPtr* ipPayload = static_cast(ippkt.GetPayload()); + UDP_Packet udppkt(ipPayload->data, ipPayload->GetLength()); + + if (udppkt.destinationPort == 53) + { + Console.WriteLn("DEV9: DNS: Packet Sent To %i.%i.%i.%i", + ippkt.destinationIP.bytes[0], ippkt.destinationIP.bytes[1], ippkt.destinationIP.bytes[2], ippkt.destinationIP.bytes[3]); + dnsLogger.InspectSend(&udppkt); + } + } + } + } +} +void NetAdapter::InspectRecv(NetPacket* pkt) +{ + if (config.EthLogDNS) + { + EthernetFrame frame(pkt); + if (frame.protocol == (u16)EtherType::IPv4) + { + PayloadPtr* payload = static_cast(frame.GetPayload()); + IP_Packet ippkt(payload->data, payload->GetLength()); + + if (ippkt.protocol == (u16)IP_Type::UDP) + { + IP_PayloadPtr* ipPayload = static_cast(ippkt.GetPayload()); + UDP_Packet udppkt(ipPayload->data, ipPayload->GetLength()); + + if (udppkt.sourcePort == 53) + { + Console.WriteLn("DEV9: DNS: Packet Sent From %i.%i.%i.%i", + ippkt.sourceIP.bytes[0], ippkt.sourceIP.bytes[1], ippkt.sourceIP.bytes[2], ippkt.sourceIP.bytes[3]); + dnsLogger.InspectRecv(&udppkt); + } + } + } + } +} + void NetAdapter::SetMACAddress(u8* mac) { if (mac == nullptr) @@ -332,6 +383,7 @@ bool NetAdapter::InternalServerRecv(NetPacket* pkt) memcpy(frame.destinationMAC, ps2MAC, 6); frame.protocol = (u16)EtherType::IPv4; frame.WritePacket(pkt); + InspectRecv(pkt); return true; } diff --git a/pcsx2/DEV9/net.h b/pcsx2/DEV9/net.h index be1fc2f8f3..1a8f233ac2 100644 --- a/pcsx2/DEV9/net.h +++ b/pcsx2/DEV9/net.h @@ -33,6 +33,7 @@ #include "PacketReader/IP/IP_Address.h" #include "InternalServers/DHCP_Server.h" +#include "InternalServers/DNS_Logger.h" #include "InternalServers/DNS_Server.h" struct ConfigDEV9; @@ -98,6 +99,7 @@ private: bool internalRxHasData = false; InternalServers::DHCP_Server dhcpServer = InternalServers::DHCP_Server([&] { InternalSignalReceived(); }); + InternalServers::DNS_Logger dnsLogger; InternalServers::DNS_Server dnsServer = InternalServers::DNS_Server([&] { InternalSignalReceived(); }); public: @@ -114,6 +116,9 @@ protected: void SetMACAddress(u8* mac); bool VerifyPkt(NetPacket* pkt, int read_size); + void InspectRecv(NetPacket* pkt); + void InspectSend(NetPacket* pkt); + #ifdef _WIN32 void InitInternalServer(PIP_ADAPTER_ADDRESSES adapter); void ReloadInternalServer(PIP_ADAPTER_ADDRESSES adapter); diff --git a/pcsx2/DEV9/pcap_io.cpp b/pcsx2/DEV9/pcap_io.cpp index 1ed6a86a1e..0677b0da55 100644 --- a/pcsx2/DEV9/pcap_io.cpp +++ b/pcsx2/DEV9/pcap_io.cpp @@ -412,18 +412,18 @@ bool PCAPAdapter::isInitialised() bool PCAPAdapter::recv(NetPacket* pkt) { int size = pcap_io_recv(pkt->buffer, sizeof(pkt->buffer)); - if (size <= 0) + if (size > 0 && VerifyPkt(pkt, size)) { - return false; + InspectRecv(pkt); + return true; } else - { - return VerifyPkt(pkt, size); - } + return false; } //sends the packet .rv :true success bool PCAPAdapter::send(NetPacket* pkt) { + InspectSend(pkt); if (NetAdapter::send(pkt)) return true; diff --git a/pcsx2/pcsx2.vcxproj b/pcsx2/pcsx2.vcxproj index 2402cb150e..9d6a70caf2 100644 --- a/pcsx2/pcsx2.vcxproj +++ b/pcsx2/pcsx2.vcxproj @@ -280,6 +280,7 @@ + @@ -726,6 +727,7 @@ + diff --git a/pcsx2/pcsx2.vcxproj.filters b/pcsx2/pcsx2.vcxproj.filters index 8522dcffd2..1f87e014f4 100644 --- a/pcsx2/pcsx2.vcxproj.filters +++ b/pcsx2/pcsx2.vcxproj.filters @@ -196,6 +196,9 @@ {229bf045-e378-4ec5-bdf8-43938762511e} + + {64b05697-98cd-48ed-b5a5-cb0f6044ca15} + {df9de75c-2272-4f73-b2a0-4f9f492ba1e9} @@ -1187,6 +1190,9 @@ System\Ps2\DEV9\InternalServers + + System\Ps2\DEV9\InternalServers + System\Ps2\DEV9\InternalServers @@ -2239,6 +2245,9 @@ System\Ps2\DEV9\InternalServers + + System\Ps2\DEV9\InternalServers + System\Ps2\DEV9\InternalServers