From 371684ae034ff56567df9aa8716117e2e288a055 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Wed, 6 Apr 2016 18:46:05 +0100 Subject: [PATCH] Add black list functionality for D-Star and DMR. --- Conf.cpp | 35 +++++++++++++++++++++++++++++++++++ Conf.h | 4 ++++ DMRControl.cpp | 10 ++++++++-- DMRControl.h | 17 +++++++++-------- DMRSlot.cpp | 7 ++++++- DMRSlot.h | 3 ++- DStarControl.cpp | 42 +++++++++++++++++++++++++++++++++++++----- DStarControl.h | 4 +++- MMDVMHost.cpp | 15 ++++++++++----- 9 files changed, 114 insertions(+), 23 deletions(-) diff --git a/Conf.cpp b/Conf.cpp index 51d9b1d..0ef34a5 100644 --- a/Conf.cpp +++ b/Conf.cpp @@ -16,12 +16,14 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "DStarDefines.h" #include "Conf.h" #include "Log.h" #include #include #include +#include const int BUFFER_SIZE = 500; @@ -74,12 +76,14 @@ m_modemDebug(false), m_dstarEnabled(true), m_dstarModule("C"), m_dstarSelfOnly(false), +m_dstarBlackList(), m_dmrEnabled(true), m_dmrBeacons(false), m_dmrId(0U), m_dmrColorCode(2U), m_dmrSelfOnly(false), m_dmrPrefixes(), +m_dmrBlackList(), m_fusionEnabled(true), m_fusionParrotEnabled(false), m_dstarNetworkEnabled(true), @@ -229,6 +233,19 @@ bool CConf::read() m_dstarModule = value; else if (::strcmp(key, "SelfOnly") == 0) m_dstarSelfOnly = ::atoi(value) == 1; + else if (::strcmp(key, "BlackList") == 0) { + char* p = ::strtok(value, ",\r\n"); + while (p != NULL) { + if (::strlen(p) > 0U) { + for (unsigned int i = 0U; p[i] != 0U; i++) + p[i] = ::toupper(p[i]); + std::string callsign = std::string(p); + callsign.resize(DSTAR_LONG_CALLSIGN_LENGTH, ' '); + m_dstarBlackList.push_back(callsign); + } + p = ::strtok(NULL, ",\r\n"); + } + } } else if (section == SECTION_DMR) { if (::strcmp(key, "Enable") == 0) m_dmrEnabled = ::atoi(value) == 1; @@ -248,6 +265,14 @@ bool CConf::read() m_dmrPrefixes.push_back(prefix); p = ::strtok(NULL, ",\r\n"); } + } else if (::strcmp(key, "BlackList") == 0) { + char* p = ::strtok(value, ",\r\n"); + while (p != NULL) { + unsigned int id = (unsigned int)::atoi(p); + if (id > 0U) + m_dmrBlackList.push_back(id); + p = ::strtok(NULL, ",\r\n"); + } } } else if (section == SECTION_FUSION) { if (::strcmp(key, "Enable") == 0) @@ -472,6 +497,11 @@ bool CConf::getDStarSelfOnly() const return m_dstarSelfOnly; } +std::vector CConf::getDStarBlackList() const +{ + return m_dstarBlackList; +} + bool CConf::getDMREnabled() const { return m_dmrEnabled; @@ -502,6 +532,11 @@ std::vector CConf::getDMRPrefixes() const return m_dmrPrefixes; } +std::vector CConf::getDMRBlackList() const +{ + return m_dmrBlackList; +} + bool CConf::getFusionEnabled() const { return m_fusionEnabled; diff --git a/Conf.h b/Conf.h index f76fef7..fca75e0 100644 --- a/Conf.h +++ b/Conf.h @@ -70,6 +70,7 @@ public: bool getDStarEnabled() const; std::string getDStarModule() const; bool getDStarSelfOnly() const; + std::vector getDStarBlackList() const; // The DMR section bool getDMREnabled() const; @@ -78,6 +79,7 @@ public: unsigned int getDMRColorCode() const; bool getDMRSelfOnly() const; std::vector getDMRPrefixes() const; + std::vector getDMRBlackList() const; // The System Fusion section bool getFusionEnabled() const; @@ -152,6 +154,7 @@ private: bool m_dstarEnabled; std::string m_dstarModule; bool m_dstarSelfOnly; + std::vector m_dstarBlackList; bool m_dmrEnabled; bool m_dmrBeacons; @@ -159,6 +162,7 @@ private: unsigned int m_dmrColorCode; bool m_dmrSelfOnly; std::vector m_dmrPrefixes; + std::vector m_dmrBlackList; bool m_fusionEnabled; bool m_fusionParrotEnabled; diff --git a/DMRControl.cpp b/DMRControl.cpp index 8e89e6f..466c249 100644 --- a/DMRControl.cpp +++ b/DMRControl.cpp @@ -20,11 +20,12 @@ #include #include -CDMRControl::CDMRControl(unsigned int id, unsigned int colorCode, bool selfOnly, const std::vector& prefixes, unsigned int timeout, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex) : +CDMRControl::CDMRControl(unsigned int id, unsigned int colorCode, bool selfOnly, const std::vector& prefixes, const std::vector& blackList, unsigned int timeout, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex) : m_id(id), m_colorCode(colorCode), m_selfOnly(selfOnly), m_prefixes(prefixes), +m_blackList(blackList), m_modem(modem), m_network(network), m_slot1(1U, timeout), @@ -33,7 +34,7 @@ m_slot2(2U, timeout) assert(modem != NULL); assert(display != NULL); - CDMRSlot::init(id, colorCode, selfOnly, prefixes, modem, network, display, duplex); + CDMRSlot::init(id, colorCode, selfOnly, prefixes, blackList, modem, network, display, duplex); } CDMRControl::~CDMRControl() @@ -66,6 +67,11 @@ bool CDMRControl::processWakeup(const unsigned char* data) return false; } } else { + if (std::find(m_blackList.begin(), m_blackList.end(), srcId) != m_blackList.end()) { + LogMessage("Invalid CSBK BS_Dwn_Act received from %u", srcId); + return false; + } + unsigned int prefix = srcId / 10000U; if (prefix == 0U || prefix > 999U) { LogMessage("Invalid CSBK BS_Dwn_Act received from %u", srcId); diff --git a/DMRControl.h b/DMRControl.h index 711aed8..888bb5b 100644 --- a/DMRControl.h +++ b/DMRControl.h @@ -29,7 +29,7 @@ class CDMRControl { public: - CDMRControl(unsigned int id, unsigned int colorCode, bool selfOnly, const std::vector& prefixes, unsigned int timeout, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex); + CDMRControl(unsigned int id, unsigned int colorCode, bool selfOnly, const std::vector& prefixes, const std::vector& blackList, unsigned int timeout, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex); ~CDMRControl(); bool processWakeup(const unsigned char* data); @@ -43,14 +43,15 @@ public: void clock(); private: - unsigned int m_id; - unsigned int m_colorCode; - bool m_selfOnly; + unsigned int m_id; + unsigned int m_colorCode; + bool m_selfOnly; std::vector m_prefixes; - CModem* m_modem; - CDMRIPSC* m_network; - CDMRSlot m_slot1; - CDMRSlot m_slot2; + std::vector m_blackList; + CModem* m_modem; + CDMRIPSC* m_network; + CDMRSlot m_slot1; + CDMRSlot m_slot2; }; #endif diff --git a/DMRSlot.cpp b/DMRSlot.cpp index 5bbfeac..94e1e30 100644 --- a/DMRSlot.cpp +++ b/DMRSlot.cpp @@ -31,6 +31,7 @@ unsigned int CDMRSlot::m_id = 0U; unsigned int CDMRSlot::m_colorCode = 0U; bool CDMRSlot::m_selfOnly = false; std::vector CDMRSlot::m_prefixes; +std::vector CDMRSlot::m_blackList; CModem* CDMRSlot::m_modem = NULL; CDMRIPSC* CDMRSlot::m_network = NULL; IDisplay* CDMRSlot::m_display = NULL; @@ -1228,7 +1229,7 @@ void CDMRSlot::writeQueueNet(const unsigned char *data) m_queue.addData(data, len); } -void CDMRSlot::init(unsigned int id, unsigned int colorCode, bool selfOnly, const std::vector& prefixes, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex) +void CDMRSlot::init(unsigned int id, unsigned int colorCode, bool selfOnly, const std::vector& prefixes, const std::vector& blackList, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex) { assert(id != 0U); assert(modem != NULL); @@ -1238,6 +1239,7 @@ void CDMRSlot::init(unsigned int id, unsigned int colorCode, bool selfOnly, cons m_colorCode = colorCode; m_selfOnly = selfOnly; m_prefixes = prefixes; + m_blackList = blackList; m_modem = modem; m_network = network; m_display = display; @@ -1259,6 +1261,9 @@ bool CDMRSlot::validateId(unsigned int id) if (m_selfOnly) { return id == m_id; } else { + if (std::find(m_blackList.begin(), m_blackList.end(), id) != m_blackList.end()) + return false; + unsigned int prefix = id / 10000U; if (prefix == 0U || prefix > 999U) return false; diff --git a/DMRSlot.h b/DMRSlot.h index 9cb2f65..481ee3d 100644 --- a/DMRSlot.h +++ b/DMRSlot.h @@ -49,7 +49,7 @@ public: void clock(); - static void init(unsigned int id, unsigned int colorCode, bool selfOnly, const std::vector& prefixes, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex); + static void init(unsigned int id, unsigned int colorCode, bool selfOnly, const std::vector& prefixes, const std::vector& blackList, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex); private: unsigned int m_slotNo; @@ -88,6 +88,7 @@ private: static unsigned int m_colorCode; static bool m_selfOnly; static std::vector m_prefixes; + static std::vector m_blackList; static CModem* m_modem; static CDMRIPSC* m_network; static IDisplay* m_display; diff --git a/DStarControl.cpp b/DStarControl.cpp index ca4fbb7..5a96c8a 100644 --- a/DStarControl.cpp +++ b/DStarControl.cpp @@ -19,15 +19,28 @@ #include #include #include +#include +#include const unsigned int MAX_SYNC_BIT_ERRORS = 2U; +bool CallsignCompare(const std::string& arg, const unsigned char* my) +{ + for (unsigned int i = 0U; i < (DSTAR_LONG_CALLSIGN_LENGTH - 1U); i++) { + if (arg.at(i) != my[i]) + return false; + } + + return true; +} + // #define DUMP_DSTAR -CDStarControl::CDStarControl(const std::string& callsign, const std::string& module, bool selfOnly, CDStarNetwork* network, IDisplay* display, unsigned int timeout, bool duplex) : +CDStarControl::CDStarControl(const std::string& callsign, const std::string& module, bool selfOnly, const std::vector& blackList, CDStarNetwork* network, IDisplay* display, unsigned int timeout, bool duplex) : m_callsign(NULL), m_gateway(NULL), m_selfOnly(selfOnly), +m_blackList(blackList), m_network(network), m_display(display), m_duplex(duplex), @@ -127,6 +140,11 @@ bool CDStarControl::writeModem(unsigned char *data) return false; } + if (!m_selfOnly && std::find_if(m_blackList.begin(), m_blackList.end(), std::bind(CallsignCompare, std::placeholders::_1, my1)) != m_blackList.end()) { + LogMessage("D-Star, invalid access attempt from %8.8s", my1); + return false; + } + unsigned char callsign[DSTAR_LONG_CALLSIGN_LENGTH]; header.getRPTCall1(callsign); @@ -252,7 +270,23 @@ bool CDStarControl::writeModem(unsigned char *data) // Is this a transmission destined for a repeater? if (!header->isRepeater()) { - LogMessage("D-Star, non repeater RF late entry header received"); + LogMessage("D-Star, non repeater RF header received"); + delete header; + return false; + } + + unsigned char my1[DSTAR_LONG_CALLSIGN_LENGTH]; + header->getMyCall1(my1); + + if (m_selfOnly && ::memcmp(my1, m_callsign, DSTAR_LONG_CALLSIGN_LENGTH - 1U) != 0) { + LogMessage("D-Star, invalid access attempt from %8.8s", my1); + delete header; + return false; + } + + if (!m_selfOnly && std::find_if(m_blackList.begin(), m_blackList.end(), std::bind(CallsignCompare, std::placeholders::_1, my1)) != m_blackList.end()) { + LogMessage("D-Star, invalid access attempt from %8.8s", my1); + delete header; return false; } @@ -262,15 +296,13 @@ bool CDStarControl::writeModem(unsigned char *data) // Is it for us? if (::memcmp(callsign, m_callsign, DSTAR_LONG_CALLSIGN_LENGTH) != 0) { LogMessage("D-Star, received RF header for wrong repeater - %8.8s", callsign); + delete header; return false; } unsigned char gateway[DSTAR_LONG_CALLSIGN_LENGTH]; header->getRPTCall2(gateway); - unsigned char my1[DSTAR_LONG_CALLSIGN_LENGTH]; - header->getMyCall1(my1); - unsigned char my2[DSTAR_SHORT_CALLSIGN_LENGTH]; header->getMyCall2(my2); diff --git a/DStarControl.h b/DStarControl.h index 3036af0..ef327b4 100644 --- a/DStarControl.h +++ b/DStarControl.h @@ -32,10 +32,11 @@ #include "Modem.h" #include +#include class CDStarControl { public: - CDStarControl(const std::string& callsign, const std::string& module, bool selfOnly, CDStarNetwork* network, IDisplay* display, unsigned int timeout, bool duplex); + CDStarControl(const std::string& callsign, const std::string& module, bool selfOnly, const std::vector& blackList, CDStarNetwork* network, IDisplay* display, unsigned int timeout, bool duplex); ~CDStarControl(); bool writeModem(unsigned char* data); @@ -48,6 +49,7 @@ private: unsigned char* m_callsign; unsigned char* m_gateway; bool m_selfOnly; + std::vector m_blackList; CDStarNetwork* m_network; IDisplay* m_display; bool m_duplex; diff --git a/MMDVMHost.cpp b/MMDVMHost.cpp index 9a4ad53..8fa5b41 100644 --- a/MMDVMHost.cpp +++ b/MMDVMHost.cpp @@ -143,18 +143,20 @@ int CMMDVMHost::run() CDStarControl* dstar = NULL; if (m_dstarEnabled) { std::string callsign = m_conf.getCallsign(); - std::string module = m_conf.getDStarModule(); - bool selfOnly = m_conf.getDStarSelfOnly(); + std::string module = m_conf.getDStarModule(); + bool selfOnly = m_conf.getDStarSelfOnly(); unsigned int timeout = m_conf.getTimeout(); + std::vector blackList = m_conf.getDStarBlackList(); LogInfo("D-Star Parameters"); LogInfo(" Callsign: %s", callsign.c_str()); LogInfo(" Module: %s", module.c_str()); LogInfo(" Self Only: %s", selfOnly ? "yes" : "no"); + if (blackList.size() > 0U) + LogInfo(" Black List: %u", blackList.size()); LogInfo(" Timeout: %us", timeout); - - dstar = new CDStarControl(callsign, module, selfOnly, m_dstarNetwork, m_display, timeout, m_duplex); + dstar = new CDStarControl(callsign, module, selfOnly, blackList, m_dstarNetwork, m_display, timeout, m_duplex); } CDMRControl* dmr = NULL; @@ -163,6 +165,7 @@ int CMMDVMHost::run() unsigned int colorCode = m_conf.getDMRColorCode(); bool selfOnly = m_conf.getDMRSelfOnly(); std::vector prefixes = m_conf.getDMRPrefixes(); + std::vector blackList = m_conf.getDMRBlackList(); unsigned int timeout = m_conf.getTimeout(); LogInfo("DMR Parameters"); @@ -170,9 +173,11 @@ int CMMDVMHost::run() LogInfo(" Color Code: %u", colorCode); LogInfo(" Self Only: %s", selfOnly ? "yes" : "no"); LogInfo(" Prefixes: %u", prefixes.size()); + if (blackList.size() > 0U) + LogInfo(" Black List: %u", blackList.size()); LogInfo(" Timeout: %us", timeout); - dmr = new CDMRControl(id, colorCode, selfOnly, prefixes, timeout, m_modem, m_dmrNetwork, m_display, m_duplex); + dmr = new CDMRControl(id, colorCode, selfOnly, prefixes, blackList, timeout, m_modem, m_dmrNetwork, m_display, m_duplex); } CYSFControl* ysf = NULL;