diff --git a/.kateproject b/.kateproject new file mode 100644 index 0000000..10f6888 --- /dev/null +++ b/.kateproject @@ -0,0 +1,4 @@ +{ + "name": "MMDVMHost" + , "files": [ { "git": 1 } ] + } diff --git a/Conf.cpp b/Conf.cpp index 8a67ea2..56e4378 100644 --- a/Conf.cpp +++ b/Conf.cpp @@ -91,10 +91,14 @@ m_dmrColorCode(2U), m_dmrSelfOnly(false), m_dmrPrefixes(), m_dmrBlackList(), -m_dmrDstIdBlacklistSlot1(), -m_dmrDstIdBlacklistSlot2(), -m_dmrDstIdWhitelistSlot1(), -m_dmrDstIdWhitelistSlot2(), +m_dmrDstIdBlacklistSlot1RF(), +m_dmrDstIdBlacklistSlot2RF(), +m_dmrDstIdWhitelistSlot1RF(), +m_dmrDstIdWhitelistSlot2RF(), +m_dmrDstIdBlacklistSlot1NET(), +m_dmrDstIdBlacklistSlot2NET(), +m_dmrDstIdWhitelistSlot1NET(), +m_dmrDstIdWhitelistSlot2NET(), m_dmrLookupFile(), m_dmrCallHang(3U), m_dmrTXHang(4U), @@ -326,36 +330,68 @@ bool CConf::read() m_dmrBlackList.push_back(id); p = ::strtok(NULL, ",\r\n"); } - } else if (::strcmp(key, "DstIdBlackListSlot1") == 0) { + } else if (::strcmp(key, "DstIdBlackListSlot1RF") == 0) { char* p = ::strtok(value, ",\r\n"); while (p != NULL) { unsigned int id = (unsigned int)::atoi(p); if (id > 0U) - m_dmrDstIdBlacklistSlot1.push_back(id); + m_dmrDstIdBlacklistSlot1RF.push_back(id); p = ::strtok(NULL, ",\r\n"); } - } else if (::strcmp(key, "DstIdBlackListSlot2") == 0) { + } else if (::strcmp(key, "DstIdBlackListSlot2RF") == 0) { char* p = ::strtok(value, ",\r\n"); while (p != NULL) { unsigned int id = (unsigned int)::atoi(p); if (id > 0U) - m_dmrDstIdBlacklistSlot2.push_back(id); + m_dmrDstIdBlacklistSlot2RF.push_back(id); p = ::strtok(NULL, ",\r\n"); } - } else if (::strcmp(key, "DstIdWhiteListSlot1") == 0) { + } else if (::strcmp(key, "DstIdWhiteListSlot1RF") == 0) { char* p = ::strtok(value, ",\r\n"); while (p != NULL) { unsigned int id = (unsigned int)::atoi(p); if (id > 0U) - m_dmrDstIdWhitelistSlot1.push_back(id); + m_dmrDstIdWhitelistSlot1RF.push_back(id); p = ::strtok(NULL, ",\r\n"); } - } else if (::strcmp(key, "DstIdWhiteListSlot2") == 0) { + } else if (::strcmp(key, "DstIdWhiteListSlot2RF") == 0) { char* p = ::strtok(value, ",\r\n"); while (p != NULL) { unsigned int id = (unsigned int)::atoi(p); if (id > 0U) - m_dmrDstIdWhitelistSlot2.push_back(id); + m_dmrDstIdWhitelistSlot2RF.push_back(id); + p = ::strtok(NULL, ",\r\n"); + } + } else if (::strcmp(key, "DstIdBlackListSlot1NET") == 0) { + char* p = ::strtok(value, ",\r\n"); + while (p != NULL) { + unsigned int id = (unsigned int)::atoi(p); + if (id > 0U) + m_dmrDstIdBlacklistSlot1NET.push_back(id); + p = ::strtok(NULL, ",\r\n"); + } + } else if (::strcmp(key, "DstIdBlackListSlot2NET") == 0) { + char* p = ::strtok(value, ",\r\n"); + while (p != NULL) { + unsigned int id = (unsigned int)::atoi(p); + if (id > 0U) + m_dmrDstIdBlacklistSlot2NET.push_back(id); + p = ::strtok(NULL, ",\r\n"); + } + } else if (::strcmp(key, "DstIdWhiteListSlot1NET") == 0) { + char* p = ::strtok(value, ",\r\n"); + while (p != NULL) { + unsigned int id = (unsigned int)::atoi(p); + if (id > 0U) + m_dmrDstIdWhitelistSlot1NET.push_back(id); + p = ::strtok(NULL, ",\r\n"); + } + } else if (::strcmp(key, "DstIdWhiteListSlot2NET") == 0) { + char* p = ::strtok(value, ",\r\n"); + while (p != NULL) { + unsigned int id = (unsigned int)::atoi(p); + if (id > 0U) + m_dmrDstIdWhitelistSlot2NET.push_back(id); p = ::strtok(NULL, ",\r\n"); } } else if (::strcmp(key, "LookupFile") == 0) @@ -681,20 +717,35 @@ std::vector CConf::getDMRBlackList() const { return m_dmrBlackList; } -std::vector CConf::getDMRDstIdBlacklistSlot1() const +std::vector CConf::getDMRDstIdBlacklistSlot1RF() const { - return m_dmrDstIdBlacklistSlot1; + return m_dmrDstIdBlacklistSlot1RF; } -std::vector CConf::getDMRDstIdBlacklistSlot2() const +std::vector CConf::getDMRDstIdBlacklistSlot2RF() const { - return m_dmrDstIdBlacklistSlot2; + return m_dmrDstIdBlacklistSlot2RF; } -std::vector CConf::getDMRDstIdWhitelistSlot1() const +std::vector CConf::getDMRDstIdWhitelistSlot1RF() const { - return m_dmrDstIdWhitelistSlot1; -}std::vector CConf::getDMRDstIdWhitelistSlot2() const + return m_dmrDstIdWhitelistSlot1RF; +}std::vector CConf::getDMRDstIdWhitelistSlot2RF() const { - return m_dmrDstIdWhitelistSlot2; + return m_dmrDstIdWhitelistSlot2RF; +} +std::vector CConf::getDMRDstIdBlacklistSlot1NET() const +{ + return m_dmrDstIdBlacklistSlot1NET; +} +std::vector CConf::getDMRDstIdBlacklistSlot2NET() const +{ + return m_dmrDstIdBlacklistSlot2NET; +} +std::vector CConf::getDMRDstIdWhitelistSlot1NET() const +{ + return m_dmrDstIdWhitelistSlot1NET; +}std::vector CConf::getDMRDstIdWhitelistSlot2NET() const +{ + return m_dmrDstIdWhitelistSlot2NET; } std::string CConf::getDMRLookupFile() const { diff --git a/Conf.h b/Conf.h index 08b6621..8fc694f 100644 --- a/Conf.h +++ b/Conf.h @@ -86,10 +86,14 @@ public: bool getDMRSelfOnly() const; std::vector getDMRPrefixes() const; std::vector getDMRBlackList() const; - std::vector getDMRDstIdBlacklistSlot1() const; - std::vector getDMRDstIdBlacklistSlot2() const; - std::vector getDMRDstIdWhitelistSlot1() const; - std::vector getDMRDstIdWhitelistSlot2() const; + std::vector getDMRDstIdBlacklistSlot1RF() const; + std::vector getDMRDstIdBlacklistSlot2RF() const; + std::vector getDMRDstIdWhitelistSlot1RF() const; + std::vector getDMRDstIdWhitelistSlot2RF() const; + std::vector getDMRDstIdBlacklistSlot1NET() const; + std::vector getDMRDstIdBlacklistSlot2NET() const; + std::vector getDMRDstIdWhitelistSlot1NET() const; + std::vector getDMRDstIdWhitelistSlot2NET() const; std::string getDMRLookupFile() const; unsigned int getDMRCallHang() const; unsigned int getDMRTXHang() const; @@ -201,10 +205,14 @@ private: bool m_dmrSelfOnly; std::vector m_dmrPrefixes; std::vector m_dmrBlackList; - std::vector m_dmrDstIdBlacklistSlot1; - std::vector m_dmrDstIdBlacklistSlot2; - std::vector m_dmrDstIdWhitelistSlot1; - std::vector m_dmrDstIdWhitelistSlot2; + std::vector m_dmrDstIdBlacklistSlot1RF; + std::vector m_dmrDstIdBlacklistSlot2RF; + std::vector m_dmrDstIdWhitelistSlot1RF; + std::vector m_dmrDstIdWhitelistSlot2RF; + std::vector m_dmrDstIdBlacklistSlot1NET; + std::vector m_dmrDstIdBlacklistSlot2NET; + std::vector m_dmrDstIdWhitelistSlot1NET; + std::vector m_dmrDstIdWhitelistSlot2NET; std::string m_dmrLookupFile; unsigned int m_dmrCallHang; unsigned int m_dmrTXHang; diff --git a/DMRAccessControl.cpp b/DMRAccessControl.cpp new file mode 100644 index 0000000..4222007 --- /dev/null +++ b/DMRAccessControl.cpp @@ -0,0 +1,198 @@ +/* + * 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 2 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + */ + +#include "DMRAccessControl.h" +#include "Log.h" + +#include +#include + +std::vector DMRAccessControl::m_dstBlackListSlot1RF; +std::vector DMRAccessControl::m_dstBlackListSlot2RF; +std::vector DMRAccessControl::m_dstWhiteListSlot1RF; +std::vector DMRAccessControl::m_dstWhiteListSlot2RF; + +std::vector DMRAccessControl::m_dstBlackListSlot1NET; +std::vector DMRAccessControl::m_dstBlackListSlot2NET; +std::vector DMRAccessControl::m_dstWhiteListSlot1NET; +std::vector DMRAccessControl::m_dstWhiteListSlot2NET; + +std::vector DMRAccessControl::m_SrcIdBlacklist; + +std::vector DMRAccessControl::m_prefixes; +bool DMRAccessControl::m_selfOnly; +unsigned int DMRAccessControl::m_id; + +void DMRAccessControl::init(const std::vector& DstIdBlacklistSlot1RF, const std::vector& DstIdWhitelistSlot1RF, const std::vector& DstIdBlacklistSlot2RF, const std::vector& DstIdWhitelistSlot2RF, const std::vector& DstIdBlacklistSlot1NET, const std::vector& DstIdWhitelistSlot1NET, const std::vector& DstIdBlacklistSlot2NET, const std::vector& DstIdWhitelistSlot2NET, const std::vector& SrcIdBlacklist, bool selfOnly, const std::vector& prefixes,unsigned int id) +{ + + m_dstBlackListSlot1RF = DstIdBlacklistSlot1RF; + m_dstWhiteListSlot1RF = DstIdWhitelistSlot1RF; + m_dstBlackListSlot2RF = DstIdBlacklistSlot2RF; + m_dstWhiteListSlot2RF = DstIdWhitelistSlot2RF; + m_dstBlackListSlot1NET = DstIdBlacklistSlot1NET; + m_dstWhiteListSlot1NET = DstIdWhitelistSlot1NET; + m_dstBlackListSlot2NET = DstIdBlacklistSlot2NET; + m_dstWhiteListSlot2NET = DstIdWhitelistSlot2NET; +} + +bool DMRAccessControl::DstIdBlacklist(unsigned int did, unsigned int slot, bool network) +{ + static std::vector Blacklist; + + if (slot == 1U) { + + if (network) { + Blacklist = m_dstBlackListSlot1NET; + } + else { + Blacklist = m_dstBlackListSlot1RF; + } + } else { + if (network) { + Blacklist = m_dstBlackListSlot2NET; + } + else { + Blacklist = m_dstBlackListSlot2RF; + } + } + if (std::find(Blacklist.begin(), Blacklist.end(), did) != Blacklist.end()) + return true; + + return false; +} + +bool DMRAccessControl::DstIdWhitelist(unsigned int did, unsigned int slot, bool gt4k, bool network) +{ + if (network) { + + if (slot == 1U) { + if (m_dstWhiteListSlot1NET.size() == 0U) + return true; + + // No reflectors on slot1, so we only allow all IDs over 99999 unless specifically whitelisted. + //Allow traffic to TG0 as I think this is a special case - need to confirm + if (gt4k) { + if (std::find(m_dstWhiteListSlot1NET.begin(), m_dstWhiteListSlot1NET.end(), did) != m_dstWhiteListSlot1NET.end() || did >= 99999U || did == 0) + return true; + } else { + if (std::find(m_dstWhiteListSlot1NET.begin(), m_dstWhiteListSlot1NET.end(), did) != m_dstWhiteListSlot1NET.end() || did == 0) + return true; + } + } else { + if (m_dstWhiteListSlot2NET.size() == 0U) + return true; + + //On slot2 we allow reflector control IDs, but not secondary TG IDs unless specifically listed. Also allow echo. + if (gt4k) { + if (std::find(m_dstWhiteListSlot2NET.begin(), m_dstWhiteListSlot2NET.end(), did) != m_dstWhiteListSlot2NET.end() || did == 0) + return true; + + //if dstId in secondary TG range or whitelist + else if (did >= 4000) { + if (did > 5000U && did < 10000U) + return false; + else + return true; + } + } else { + if (std::find(m_dstWhiteListSlot2NET.begin(), m_dstWhiteListSlot2NET.end(), did) != m_dstWhiteListSlot2NET.end()) + return true; + } + } + + return false; + + + } else { + if (slot == 1U) { + if (m_dstWhiteListSlot1RF.size() == 0U) + return true; + + // No reflectors on slot1, so we only allow all IDs over 99999 unless specifically whitelisted. + //Allow traffic to TG0 as I think this is a special case - need to confirm + if (gt4k) { + if (std::find(m_dstWhiteListSlot1RF.begin(), m_dstWhiteListSlot1RF.end(), did) != m_dstWhiteListSlot1RF.end() || did >= 99999U || did == 0) + return true; + } else { + if (std::find(m_dstWhiteListSlot1RF.begin(), m_dstWhiteListSlot1RF.end(), did) != m_dstWhiteListSlot1RF.end() || did == 0) + return true; + } + } else { + if (m_dstWhiteListSlot2RF.size() == 0U) + return true; + + //On slot2 we allow reflector control IDs, but not secondary TG IDs unless specifically listed. Also allow echo. + if (gt4k) { + if (std::find(m_dstWhiteListSlot2RF.begin(), m_dstWhiteListSlot2RF.end(), did) != m_dstWhiteListSlot2RF.end() || did == 0) + return true; + + //if dstId in secondary TG range or whitelist + else if (did >= 4000) { + if (did > 5000U && did < 10000U) + return false; + else + return true; + } + } else { + if (std::find(m_dstWhiteListSlot2RF.begin(), m_dstWhiteListSlot2RF.end(), did) != m_dstWhiteListSlot2RF.end()) + return true; + } + } + + return false; + + } +} + +bool DMRAccessControl::validateSrcId(unsigned int id) +{ + if (m_selfOnly) { + return id == m_id; + } else { + if (std::find(m_SrcIdBlacklist.begin(), m_SrcIdBlacklist.end(), id) != m_SrcIdBlacklist.end()) + return false; + + unsigned int prefix = id / 10000U; + if (prefix == 0U || prefix > 999U) + return false; + + if (m_prefixes.size() == 0U) + return true; + + return std::find(m_prefixes.begin(), m_prefixes.end(), prefix) != m_prefixes.end(); + } +} + +bool DMRAccessControl::validateAccess (unsigned int src_id, unsigned int dst_id, unsigned int slot, bool network) +{ + // source ID validation is only applied to RF traffic + if (!network && !DMRAccessControl::validateSrcId(src_id)) { + LogMessage("DMR Slot %u, invalid access attempt from %u (blacklisted)", slot, src_id); + return false; + + } + else if (DMRAccessControl::DstIdBlacklist(dst_id, slot, network)) { + LogMessage("DMR Slot %u, invalid access attempt to TG%u (TG blacklisted)", slot, dst_id); + return false; + } + else if (!DMRAccessControl::DstIdWhitelist(dst_id, slot, true, network)) { + LogMessage("DMR Slot %u, invalid access attempt to TG%u (TG not in whitelist)", slot, dst_id); + return false; + } + else + return true; + +} diff --git a/DMRAccessControl.h b/DMRAccessControl.h new file mode 100644 index 0000000..01ca408 --- /dev/null +++ b/DMRAccessControl.h @@ -0,0 +1,56 @@ +/* + * 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 2 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + */ +#if !defined(DMRAccessControl_H) +#define DMRAccessControl_H + +#include + +class DMRAccessControl { +public: + + static bool validateAccess (unsigned int src_id, unsigned int dst_id, unsigned int slot, bool network); + + static void init(const std::vector& DstIdBlacklistSlot1RF, const std::vector& DstIdWhitelistSlot1RF, const std::vector& DstIdBlacklistSlot2RF, const std::vector& DstIdWhitelistSlot2RF, const std::vector& DstIdBlacklistSlot1NET, const std::vector& DstIdWhitelistSlot1NET, const std::vector& DstIdBlacklistSlot2NET, const std::vector& DstIdWhitelistSlot2NET, const std::vector& SrcIdBlacklist, bool selfOnly, const std::vector& prefixes,unsigned int id); + + + +private: + static std::vector m_dstBlackListSlot1RF; + static std::vector m_dstBlackListSlot2RF; + static std::vector m_dstWhiteListSlot1RF; + static std::vector m_dstWhiteListSlot2RF; + + static std::vector m_dstBlackListSlot1NET; + static std::vector m_dstBlackListSlot2NET; + static std::vector m_dstWhiteListSlot1NET; + static std::vector m_dstWhiteListSlot2NET; + + static std::vector m_SrcIdBlacklist; + + static std::vector m_prefixes; + + static bool m_selfOnly; + static unsigned int m_id; + + static bool DstIdBlacklist(unsigned int did,unsigned int slot, bool network); + static bool DstIdWhitelist(unsigned int did,unsigned int slot,bool gt4k, bool network); + + static bool validateSrcId(unsigned int id); + + + +}; + +#endif \ No newline at end of file diff --git a/DMRControl.cpp b/DMRControl.cpp index f4e2674..1e39d2f 100644 --- a/DMRControl.cpp +++ b/DMRControl.cpp @@ -20,7 +20,7 @@ #include #include -CDMRControl::CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector& prefixes, const std::vector& blackList, const std::vector& DstIdBlacklistSlot1, const std::vector& DstIdWhitelistSlot1, const std::vector& DstIdBlacklistSlot2, const std::vector& DstIdWhitelistSlot2, unsigned int timeout, CModem* modem, CDMRIPSC* network, CDisplay* display, bool duplex, const std::string& lookupFile) : +CDMRControl::CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector& prefixes, const std::vector& blackList, const std::vector& DstIdBlacklistSlot1RF, const std::vector& DstIdWhitelistSlot1RF, const std::vector& DstIdBlacklistSlot2RF, const std::vector& DstIdWhitelistSlot2RF, const std::vector& DstIdBlacklistSlot1NET, const std::vector& DstIdWhitelistSlot1NET, const std::vector& DstIdBlacklistSlot2NET, const std::vector& DstIdWhitelistSlot2NET, unsigned int timeout, CModem* modem, CDMRIPSC* network, CDisplay* display, bool duplex, const std::string& lookupFile) : m_id(id), m_colorCode(colorCode), m_selfOnly(selfOnly), @@ -38,7 +38,7 @@ m_lookup(NULL) m_lookup = new CDMRLookup(lookupFile); m_lookup->read(); - CDMRSlot::init(id, colorCode, callHang, selfOnly, prefixes, blackList, DstIdBlacklistSlot1, DstIdWhitelistSlot1, DstIdBlacklistSlot2, DstIdWhitelistSlot2, modem, network, display, duplex, m_lookup); + CDMRSlot::init(id, colorCode, callHang, selfOnly, prefixes, blackList, DstIdBlacklistSlot1RF, DstIdWhitelistSlot1RF, DstIdBlacklistSlot2RF, DstIdWhitelistSlot2RF, DstIdBlacklistSlot1NET, DstIdWhitelistSlot1NET, DstIdBlacklistSlot2NET, DstIdWhitelistSlot2NET, modem, network, display, duplex, m_lookup); } CDMRControl::~CDMRControl() diff --git a/DMRControl.h b/DMRControl.h index 3d3f8fe..f0da13c 100644 --- a/DMRControl.h +++ b/DMRControl.h @@ -30,7 +30,7 @@ class CDMRControl { public: - CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector& prefixes, const std::vector& blackList, const std::vector& DstIdBlacklistSlot1, const std::vector& DstIdWhitelistSlot1, const std::vector& DstIdBlacklistSlot2, const std::vector& DstIdWhitelistSlot2, unsigned int timeout, CModem* modem, CDMRIPSC* network, CDisplay* display, bool duplex, const std::string& lookupFile); + CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector& prefixes, const std::vector& blackList, const std::vector& DstIdBlacklistSlot1RF, const std::vector& DstIdWhitelistSlot1RF, const std::vector& DstIdBlacklistSlot2RF, const std::vector& DstIdWhitelistSlot2RF,const std::vector& DstIdBlacklistSlot1NET, const std::vector& DstIdWhitelistSlot1NET, const std::vector& DstIdBlacklistSlot2NET, const std::vector& DstIdWhitelistSlot2NET, unsigned int timeout, CModem* modem, CDMRIPSC* network, CDisplay* display, bool duplex, const std::string& lookupFile); ~CDMRControl(); bool processWakeup(const unsigned char* data); diff --git a/DMRSlot.cpp b/DMRSlot.cpp index 162ebc9..356c490 100644 --- a/DMRSlot.cpp +++ b/DMRSlot.cpp @@ -22,6 +22,7 @@ #include "Sync.h" #include "CRC.h" #include "Log.h" +#include "DMRAccessControl.h" #include #include @@ -32,10 +33,6 @@ unsigned int CDMRSlot::m_colorCode = 0U; bool CDMRSlot::m_selfOnly = false; std::vector CDMRSlot::m_prefixes; std::vector CDMRSlot::m_blackList; -std::vector CDMRSlot::m_dstBlackListSlot1; -std::vector CDMRSlot::m_dstWhiteListSlot1; -std::vector CDMRSlot::m_dstBlackListSlot2; -std::vector CDMRSlot::m_dstWhiteListSlot2; CModem* CDMRSlot::m_modem = NULL; CDMRIPSC* CDMRSlot::m_network = NULL; @@ -139,28 +136,13 @@ void CDMRSlot::writeModem(unsigned char *data) return; unsigned int id = lc->getSrcId(); - if (!validateId(id)) { - LogMessage("DMR Slot %u, invalid access attempt from %u (blacklisted)", m_slotNo, id); - delete lc; - return; - } - - // add check for valid dst id (e.g. TG) - // - G7RZU unsigned int did = lc->getDstId(); - if (DstIdBlacklist(did, m_slotNo)) { - LogMessage("DMR Slot %u, invalid access attempt to TG%u (TG blacklisted)", m_slotNo, did); - delete lc; - return; - } - // true sets allow greater than 4k. Need to add boolean in conf for this later. - if (!DstIdWhitelist(did, m_slotNo, true)) { - LogMessage("DMR Slot %u, invalid access attempt to TG%u (TG not in whitelist)", m_slotNo, did); - delete lc; - return; + if (!DMRAccessControl::validateAccess(id,did,m_slotNo,false)) { + delete lc; + return; } - + m_rfLC = lc; // Store the LC for the embedded LC @@ -272,22 +254,9 @@ void CDMRSlot::writeModem(unsigned char *data) unsigned int srcId = dataHeader.getSrcId(); unsigned int dstId = dataHeader.getDstId(); - if (!validateId(srcId)) { - LogMessage("DMR Slot %u, invalid access attempt from %u", m_slotNo, srcId); - return; - } - // add check for valid dst id (e.g. TG) - // - G7RZU - if (DstIdBlacklist(dstId, m_slotNo)) { - LogMessage("DMR Slot %u, invalid access attempt to TG %u (TG blacklisted)", m_slotNo, dstId); - return; - } - - // true sets allow greater than 4k. Need to add boolean in conf for this later. - if (!DstIdWhitelist(dstId, m_slotNo, true)) { - LogMessage("DMR Slot %u, invalid access attempt to TG %u (TG not in whitelist)", m_slotNo, dstId); - return; + if (!DMRAccessControl::validateAccess(srcId,dstId,m_slotNo,false)) { + return; } m_rfFrames = dataHeader.getBlocks(); @@ -343,22 +312,8 @@ void CDMRSlot::writeModem(unsigned char *data) unsigned int srcId = csbk.getSrcId(); unsigned int dstId = csbk.getDstId(); - if (!validateId(srcId)) { - LogMessage("DMR Slot %u, invalid access attempt from %u", m_slotNo, srcId); - return; - } - - // add check for valid dst id (e.g. TG) - // - G7RZU - if (DstIdBlacklist(dstId, m_slotNo)) { - LogMessage("DMR Slot %u, invalid access attempt to TG %u (TG blacklisted)", m_slotNo, dstId); - return; - } - - // true sets allow greater than 4k. Need to add boolean in conf for this later. - if (!DstIdWhitelist(dstId, m_slotNo, true)) { - LogMessage("DMR Slot %u, invalid access attempt to TG %u (TG not in whitelist)", m_slotNo, dstId); - return; + if (!DMRAccessControl::validateAccess(srcId,dstId,m_slotNo,false)) { + return; } // Regenerate the CSBK data @@ -509,27 +464,13 @@ void CDMRSlot::writeModem(unsigned char *data) CDMRLC* lc = m_rfEmbeddedLC.addData(data + 2U, emb.getLCSS()); if (lc != NULL) { + unsigned int id = lc->getSrcId(); - if (!validateId(id)) { - LogMessage("DMR Slot %u, invalid access attempt from %u", m_slotNo, id); - delete lc; - return; - } - - // add check for valid dst id (e.g. TG) - // - G7RZU unsigned int did = lc->getDstId(); - if (DstIdBlacklist(did, m_slotNo)) { - LogMessage("DMR Slot %u, invalid access attempt to TG%u (TG blacklisted)", m_slotNo, did); - delete lc; - return; - } - // true sets allow greater than 4k. Need to add boolean in conf for this later. - if (!DstIdWhitelist(did, m_slotNo, true)) { - LogMessage("DMR Slot %u, invalid access attempt to TG%u (TG not in whitelist)", m_slotNo, did); - delete lc; - return; + if (!DMRAccessControl::validateAccess(id,did,m_slotNo,false)) { + delete lc; + return; } m_rfLC = lc; @@ -804,18 +745,11 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) return; } - // add check for valid dst id (e.g. TG) - // - G7RZU unsigned int did = m_netLC->getDstId(); - if (DstIdBlacklist(did, m_slotNo)) { - LogMessage("DMR Slot %u, invalid traffic to TG%u (TG blacklisted)", m_slotNo, did); - return; - } + unsigned int id = m_netLC->getSrcId(); - // true sets allow greater than 4k. Need to add boolean in conf for this later. - if (!DstIdWhitelist(did, m_slotNo, true)) { - LogMessage("DMR Slot %u, invalid traffic to TG%u (TG not in whitelist)", m_slotNo, did); - return; + if (!DMRAccessControl::validateAccess(id,did,m_slotNo,true)) { + return; } // Store the LC for the embedded LC @@ -876,20 +810,14 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) if (m_netState != RS_NET_AUDIO) return; - // add check for valid dst id (e.g. TG) - // - G7RZU - unsigned int did = m_netLC->getDstId(); - if (DstIdBlacklist(did, m_slotNo)) { - LogMessage("DMR Slot %u, invalid traffic to TG%u (TG blacklisted)", m_slotNo, did); - return; - } - // true sets allow greater than 4k. Need to add boolean in conf for this later. - if (!DstIdWhitelist(did, m_slotNo, true)) { - LogMessage("DMR Slot %u, invalid traffic to TG%u (TG not in whitelist)", m_slotNo, did); - return; - } - + unsigned int did = m_netLC->getDstId(); + unsigned int id = m_netLC->getSrcId(); + + if (!DMRAccessControl::validateAccess(id,did,m_slotNo,true)) { + return; + } + // Regenerate the Slot Type CDMRSlotType slotType; slotType.setColorCode(m_colorCode); @@ -917,22 +845,13 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) if (m_netState != RS_NET_AUDIO) return; - // add check for valid dst id (e.g. TG) - // - G7RZU unsigned int did = m_netLC->getDstId(); - if (DstIdBlacklist(did, m_slotNo)) { - LogMessage("DMR Slot %u, invalid traffic to TG%u (TG blacklisted)", m_slotNo, did); - writeEndNet(); - return; - } + unsigned int id = m_netLC->getSrcId(); - // true sets allow greater than 4k. Need to add boolean in conf for this later. - if (!DstIdWhitelist(did, m_slotNo, true)) { - LogMessage("DMR Slot %u, invalid traffic to TG%u (TG not in whitelist)", m_slotNo, did); - writeEndNet(); - return; + if (!DMRAccessControl::validateAccess(id,did,m_slotNo,true)) { + return; } - + // Regenerate the LC data CDMRFullLC fullLC; fullLC.encode(*m_netLC, data + 2U, DT_TERMINATOR_WITH_LC); @@ -984,22 +903,10 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) unsigned int srcId = dataHeader.getSrcId(); unsigned int dstId = dataHeader.getDstId(); - m_netLC = new CDMRLC(gi ? FLCO_GROUP : FLCO_USER_USER, srcId, dstId); - - // add check for valid dst id (e.g. TG) - // - G7RZU - unsigned int did = dataHeader.getDstId(); - if (DstIdBlacklist(did, m_slotNo)) { - LogMessage("DMR Slot %u, invalid traffic to TG%u (TG blacklisted)", m_slotNo, did); - return; + if (!DMRAccessControl::validateAccess(srcId,dstId,m_slotNo,true)) { + return; } - - // true sets allow greater than 4k. Need to add boolean in conf for this later. - if (!DstIdWhitelist(did, m_slotNo, true)) { - LogMessage("DMR Slot %u, invalid traffic to TG%u (TG not in whitelist)", m_slotNo, did); - return; - } - + m_netFrames = dataHeader.getBlocks(); // Regenerate the data header @@ -1040,20 +947,13 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) if (m_netState == RS_NET_IDLE) { m_netLC = new CDMRLC(dmrData.getFLCO(), dmrData.getSrcId(), dmrData.getDstId()); - // add check for valid dst id (e.g. TG) - // - G7RZU unsigned int did = dmrData.getDstId(); - if (DstIdBlacklist(did, m_slotNo)) { - LogMessage("DMR Slot %u, invalid traffic to TG%u (TG blacklisted)", m_slotNo, did); - return; - } + unsigned int id = dmrData.getSrcId(); - // true sets allow greater than 4k. Need to add boolean in conf for this later. - if (!DstIdWhitelist(did, m_slotNo, true)) { - LogMessage("DMR Slot %u, invalid traffic to TG%u (TG not in whitelist)", m_slotNo, did); - return; + if (!DMRAccessControl::validateAccess(id,did,m_slotNo,true)) { + return; } - + m_netTimeoutTimer.start(); if (m_duplex) { @@ -1147,20 +1047,13 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) if (m_netState != RS_NET_AUDIO) return; - // add check for valid dst id (e.g. TG) - // - G7RZU unsigned int did = m_netLC->getDstId(); - if (DstIdBlacklist(did, m_slotNo)) { - LogMessage("DMR Slot %u, invalid traffic to TG%u (TG blacklisted)", m_slotNo, did); - return; - } + unsigned int id = m_netLC->getSrcId(); - // true sets allow greater than 4k. Need to add boolean in conf for this later. - if (!DstIdWhitelist(did, m_slotNo, true)) { - LogMessage("DMR Slot %u, invalid traffic to TG%u (TG not in whitelist)", m_slotNo, did); - return; + if (!DMRAccessControl::validateAccess(id,did,m_slotNo,true)) { + return; } - + unsigned char fid = m_netLC->getFID(); if (fid == FID_ETSI || fid == FID_DMRA) m_netErrs += m_fec.regenerateDMR(data + 2U); @@ -1218,20 +1111,11 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) unsigned int srcId = csbk.getSrcId(); unsigned int dstId = csbk.getDstId(); - // add check for valid dst id (e.g. TG) - // - G7RZU - unsigned int did = dstId; - if (DstIdBlacklist(did, m_slotNo)) { - LogMessage("DMR Slot %u, invalid traffic to TG%u (TG blacklisted)", m_slotNo, did); - return; - } - // true sets allow greater than 4k. Need to add boolean in conf for this later. - if (!DstIdWhitelist(did, m_slotNo, true)) { - LogMessage("DMR Slot %u, invalid traffic to TG%u (TG not in whitelist)", m_slotNo, did); - return; + if (!DMRAccessControl::validateAccess(srcId,dstId,m_slotNo,true)) { + return; } - + // Regenerate the CSBK data csbk.get(data + 2U); @@ -1455,7 +1339,7 @@ void CDMRSlot::writeQueueNet(const unsigned char *data) m_queue.addData(data, len); } -void CDMRSlot::init(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector& prefixes, const std::vector& blackList, const std::vector& DstIdBlacklistSlot1, const std::vector& DstIdWhitelistSlot1, const std::vector& DstIdBlacklistSlot2, const std::vector& DstIdWhitelistSlot2, CModem* modem, CDMRIPSC* network, CDisplay* display, bool duplex, CDMRLookup* lookup) +void CDMRSlot::init(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector& prefixes, const std::vector& SrcIdBlacklist, const std::vector& DstIdBlacklistSlot1RF, const std::vector& DstIdWhitelistSlot1RF, const std::vector& DstIdBlacklistSlot2RF, const std::vector& DstIdWhitelistSlot2RF, const std::vector& DstIdBlacklistSlot1NET, const std::vector& DstIdWhitelistSlot1NET, const std::vector& DstIdBlacklistSlot2NET, const std::vector& DstIdWhitelistSlot2NET, CModem* modem, CDMRIPSC* network, CDisplay* display, bool duplex, CDMRLookup* lookup) { assert(id != 0U); assert(modem != NULL); @@ -1466,11 +1350,7 @@ void CDMRSlot::init(unsigned int id, unsigned int colorCode, unsigned int callHa m_colorCode = colorCode; m_selfOnly = selfOnly; m_prefixes = prefixes; - m_blackList = blackList; - m_dstBlackListSlot1 = DstIdBlacklistSlot1; - m_dstWhiteListSlot1 = DstIdWhitelistSlot1; - m_dstBlackListSlot2 = DstIdBlacklistSlot2; - m_dstWhiteListSlot2 = DstIdWhitelistSlot2; +// m_blackList = blackList; m_modem = modem; m_network = network; m_display = display; @@ -1487,77 +1367,11 @@ void CDMRSlot::init(unsigned int id, unsigned int colorCode, unsigned int callHa slotType.setColorCode(colorCode); slotType.setDataType(DT_IDLE); slotType.getData(m_idle + 2U); + + //Load black and white lists to DMRAccessControl + DMRAccessControl::init(DstIdBlacklistSlot1RF, DstIdWhitelistSlot1RF, DstIdBlacklistSlot2RF, DstIdWhitelistSlot2RF, DstIdBlacklistSlot1NET, DstIdWhitelistSlot1NET, DstIdBlacklistSlot2NET, DstIdWhitelistSlot2NET, SrcIdBlacklist, m_selfOnly, m_prefixes, m_id); } -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; - - if (m_prefixes.size() == 0U) - return true; - - return std::find(m_prefixes.begin(), m_prefixes.end(), prefix) != m_prefixes.end(); - } -} - -//is dst id blacklisted? -bool CDMRSlot::DstIdBlacklist(unsigned int did, unsigned int slot) -{ - if (slot == 1U) { - if (std::find(m_dstBlackListSlot1.begin(), m_dstBlackListSlot1.end(), did) != m_dstBlackListSlot1.end()) - return true; - } else { - if (std::find(m_dstBlackListSlot2.begin(), m_dstBlackListSlot2.end(), did) != m_dstBlackListSlot2.end()) - return true; - } - - return false; -} - -bool CDMRSlot::DstIdWhitelist(unsigned int did, unsigned int slot, bool gt4k) -{ - if (slot == 1U) { - if (m_dstWhiteListSlot1.size() == 0U) - return true; - - // No reflectors on slot1, so we only allow all IDs over 99999 unless specifically whitelisted. - //Allow traffic to TG0 as I think this is a special case - need to confirm - if (gt4k) { - if (std::find(m_dstWhiteListSlot1.begin(), m_dstWhiteListSlot1.end(), did) != m_dstWhiteListSlot1.end() || did >= 99999U || did == 0) - return true; - } else { - if (std::find(m_dstWhiteListSlot1.begin(), m_dstWhiteListSlot1.end(), did) != m_dstWhiteListSlot1.end() || did == 0) - return true; - } - } else { - if (m_dstWhiteListSlot2.size() == 0U) - return true; - - //On slot2 we allow reflector control IDs, but not secondary TG IDs unless specifically listed. Also allow echo. - if (gt4k) { - if (std::find(m_dstWhiteListSlot2.begin(), m_dstWhiteListSlot2.end(), did) != m_dstWhiteListSlot2.end() || did >= 4000) { - //if dstId in secondary TG range - if (did > 5000U && did < 10000U) - return false; - else - return true; - } - } else { - if (std::find(m_dstWhiteListSlot2.begin(), m_dstWhiteListSlot2.end(), did) != m_dstWhiteListSlot2.end()) - return true; - } - } - - return false; -} void CDMRSlot::setShortLC(unsigned int slotNo, unsigned int id, FLCO flco, bool voice) { diff --git a/DMRSlot.h b/DMRSlot.h index aa363b5..c011c98 100644 --- a/DMRSlot.h +++ b/DMRSlot.h @@ -50,7 +50,7 @@ public: void clock(); - static void init(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector& prefixes, const std::vector& blackList, const std::vector& DstIdBlacklistSlot1, const std::vector& DstIdWhitelistSlot1, const std::vector& DstIdBlacklistSlot2, const std::vector& DstIdWhitelistSlot2, CModem* modem, CDMRIPSC* network, CDisplay* display, bool duplex, CDMRLookup* lookup); + static void init(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector& prefixes, const std::vector& SrcIdBlackList, const std::vector& DstIdBlacklistSlot1RF, const std::vector& DstIdWhitelistSlot1RF, const std::vector& DstIdBlacklistSlot2RF, const std::vector& DstIdWhitelistSlot2RF, const std::vector& DstIdBlacklistSlot1NET, const std::vector& DstIdWhitelistSlot1NET, const std::vector& DstIdBlacklistSlot2NET, const std::vector& DstIdWhitelistSlot2NET, CModem* modem, CDMRIPSC* network, CDisplay* display, bool duplex, CDMRLookup* lookup); private: unsigned int m_slotNo; @@ -90,11 +90,12 @@ private: static bool m_selfOnly; static std::vector m_prefixes; static std::vector m_blackList; +/* static std::vector m_dstBlackListSlot1; static std::vector m_dstBlackListSlot2; static std::vector m_dstWhiteListSlot1; static std::vector m_dstWhiteListSlot2; - +*/ static CModem* m_modem; static CDMRIPSC* m_network; static CDisplay* m_display; @@ -131,8 +132,6 @@ private: static void setShortLC(unsigned int slotNo, unsigned int id, FLCO flco = FLCO_GROUP, bool voice = true); static bool validateId(unsigned int id); - static bool DstIdBlacklist(unsigned int did,unsigned int slot); - static bool DstIdWhitelist(unsigned int did,unsigned int slot,bool gt4k); }; #endif diff --git a/MMDVM.ini b/MMDVM.ini index 494a87b..f9a7f64 100644 --- a/MMDVM.ini +++ b/MMDVM.ini @@ -59,10 +59,14 @@ LookupFile=DMRIds.dat CallHang=3 TXHang=4 #Blacklist= -#DstIdBlackListSlot1= -#DstIdBlackListSlot2= -#DstIdWhiteListSlot1= -#DstIdWhiteListSlot2= +#DstIdBlackListSlot1RF= +#DstIdBlackListSlot2RF= +#DstIdWhiteListSlot1RF= +#DstIdWhiteListSlot2RF= +#DstIdBlackListSlot1NET= +#DstIdBlackListSlot2NET= +#DstIdWhiteListSlot1NET= +#DstIdWhiteListSlot2NET= [System Fusion] Enable=1 diff --git a/MMDVMHost.cpp b/MMDVMHost.cpp index 1988e99..5d09240 100644 --- a/MMDVMHost.cpp +++ b/MMDVMHost.cpp @@ -290,10 +290,14 @@ int CMMDVMHost::run() bool selfOnly = m_conf.getDMRSelfOnly(); std::vector prefixes = m_conf.getDMRPrefixes(); std::vector blackList = m_conf.getDMRBlackList(); - std::vector dstIDBlackListSlot1 = m_conf.getDMRDstIdBlacklistSlot1(); - std::vector dstIDBlackListSlot2 = m_conf.getDMRDstIdBlacklistSlot2(); - std::vector dstIDWhiteListSlot1 = m_conf.getDMRDstIdWhitelistSlot1(); - std::vector dstIDWhiteListSlot2 = m_conf.getDMRDstIdWhitelistSlot2(); + std::vector dstIDBlackListSlot1RF = m_conf.getDMRDstIdBlacklistSlot1RF(); + std::vector dstIDBlackListSlot2RF = m_conf.getDMRDstIdBlacklistSlot2RF(); + std::vector dstIDWhiteListSlot1RF = m_conf.getDMRDstIdWhitelistSlot1RF(); + std::vector dstIDWhiteListSlot2RF = m_conf.getDMRDstIdWhitelistSlot2RF(); + std::vector dstIDBlackListSlot1NET = m_conf.getDMRDstIdBlacklistSlot1NET(); + std::vector dstIDBlackListSlot2NET = m_conf.getDMRDstIdBlacklistSlot2NET(); + std::vector dstIDWhiteListSlot1NET = m_conf.getDMRDstIdWhitelistSlot1NET(); + std::vector dstIDWhiteListSlot2NET = m_conf.getDMRDstIdWhitelistSlot2NET(); std::string lookupFile = m_conf.getDMRLookupFile(); unsigned int callHang = m_conf.getDMRCallHang(); unsigned int txHang = m_conf.getDMRTXHang(); @@ -313,21 +317,29 @@ int CMMDVMHost::run() LogInfo(" Prefixes: %u", prefixes.size()); if (blackList.size() > 0U) - LogInfo(" Black List: %u", blackList.size()); - if (dstIDBlackListSlot1.size() > 0U) - LogInfo(" Slot 1 Destination ID Black List: %u entries", dstIDBlackListSlot1.size()); - if (dstIDBlackListSlot2.size() > 0U) - LogInfo(" Slot 2 Destination ID Black List: %u entries", dstIDBlackListSlot2.size()); - if (dstIDWhiteListSlot1.size() > 0U) - LogInfo(" Slot 1 Destination ID White List: %u entries", dstIDWhiteListSlot1.size()); - if (dstIDWhiteListSlot2.size() > 0U) - LogInfo(" Slot 2 Destination ID White List: %u entries", dstIDWhiteListSlot2.size()); + LogInfo(" Source ID Black List: %u", blackList.size()); + if (dstIDBlackListSlot1RF.size() > 0U) + LogInfo(" Slot 1 RF Destination ID Black List: %u entries", dstIDBlackListSlot1RF.size()); + if (dstIDBlackListSlot2RF.size() > 0U) + LogInfo(" Slot 2 RF Destination ID Black List: %u entries", dstIDBlackListSlot2RF.size()); + if (dstIDWhiteListSlot1RF.size() > 0U) + LogInfo(" Slot 1 RF Destination ID White List: %u entries", dstIDWhiteListSlot1RF.size()); + if (dstIDWhiteListSlot2RF.size() > 0U) + LogInfo(" Slot 2 RF Destination ID White List: %u entries", dstIDWhiteListSlot2RF.size()); + if (dstIDBlackListSlot1NET.size() > 0U) + LogInfo(" Slot 1 NET Destination ID Black List: %u entries", dstIDBlackListSlot1NET.size()); + if (dstIDBlackListSlot2NET.size() > 0U) + LogInfo(" Slot 2 NET Destination ID Black List: %u entries", dstIDBlackListSlot2NET.size()); + if (dstIDWhiteListSlot1NET.size() > 0U) + LogInfo(" Slot 1 NET Destination ID White List: %u entries", dstIDWhiteListSlot1NET.size()); + if (dstIDWhiteListSlot2NET.size() > 0U) + LogInfo(" Slot 2 NET Destination ID White List: %u entries", dstIDWhiteListSlot2NET.size()); LogInfo(" Lookup File: %s", lookupFile.length() > 0U ? lookupFile.c_str() : "None"); LogInfo(" Call Hang: %us", callHang); LogInfo(" TX Hang: %us", txHang); - dmr = new CDMRControl(id, colorCode, callHang, selfOnly, prefixes, blackList,dstIDBlackListSlot1,dstIDWhiteListSlot1, dstIDBlackListSlot2, dstIDWhiteListSlot2, m_timeout, m_modem, m_dmrNetwork, m_display, m_duplex, lookupFile); + dmr = new CDMRControl(id, colorCode, callHang, selfOnly, prefixes, blackList,dstIDBlackListSlot1RF,dstIDWhiteListSlot1RF, dstIDBlackListSlot2RF, dstIDWhiteListSlot2RF, dstIDBlackListSlot1NET,dstIDWhiteListSlot1NET, dstIDBlackListSlot2NET, dstIDWhiteListSlot2NET, m_timeout, m_modem, m_dmrNetwork, m_display, m_duplex, lookupFile); m_dmrTXTimer.setTimeout(txHang); } diff --git a/Makefile b/Makefile index 64fa332..ae39487 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ LDFLAGS = -g OBJECTS = \ AMBEFEC.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRIPSC.o DMRLookup.o DMRLC.o \ - DMRShortLC.o DMRSlot.o DMRSlotType.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o Golay24128.o Hamming.o Log.o MMDVMHost.o \ + DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o Golay24128.o Hamming.o Log.o MMDVMHost.o \ Modem.o Nextion.o NullDisplay.o QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o \ YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o @@ -22,4 +22,4 @@ MMDVMHost: $(OBJECTS) clean: $(RM) MMDVMHost *.o *.d *.bak *~ - \ No newline at end of file + diff --git a/README.DMR_ACL b/README.DMR_ACL index 9fb7a58..a4eccc2 100644 --- a/README.DMR_ACL +++ b/README.DMR_ACL @@ -1,10 +1,14 @@ To use DMR Access Control you can add the following fields to your MMDVM.ini: Blacklist= -DstIdBlackListSlot1= -DstIdBlackListSlot2= -DstIdWhiteListSlot1= -DstIdWhiteListSlot2= +DstIdBlackListSlot1RF= +DstIdBlackListSlot2RF= +DstIdWhiteListSlot1RF= +DstIdWhiteListSlot2RF= +DstIdBlackListSlot1NET= +DstIdBlackListSlot2NET= +DstIdWhiteListSlot1NET= +DstIdWhiteListSlot2NET= So, for example: @@ -24,5 +28,5 @@ You can use the blacklist with the whitelist if you want to specifically block I For example, to block users from disconnecting the reflectors, you could block ID 4000. -To block users connecting to reflector 4400 you could add ID 4400 to the blacklist for that slot. +To block users connecting to reflector 4400 you could add ID 4400 to the network blacklist for that slot.