Add black list functionality for D-Star and DMR.

This commit is contained in:
Jonathan Naylor 2016-04-06 18:46:05 +01:00
parent 3ee457830b
commit 371684ae03
9 changed files with 114 additions and 23 deletions

View file

@ -16,12 +16,14 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#include "DStarDefines.h"
#include "Conf.h" #include "Conf.h"
#include "Log.h" #include "Log.h"
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include <cctype>
const int BUFFER_SIZE = 500; const int BUFFER_SIZE = 500;
@ -74,12 +76,14 @@ m_modemDebug(false),
m_dstarEnabled(true), m_dstarEnabled(true),
m_dstarModule("C"), m_dstarModule("C"),
m_dstarSelfOnly(false), m_dstarSelfOnly(false),
m_dstarBlackList(),
m_dmrEnabled(true), m_dmrEnabled(true),
m_dmrBeacons(false), m_dmrBeacons(false),
m_dmrId(0U), m_dmrId(0U),
m_dmrColorCode(2U), m_dmrColorCode(2U),
m_dmrSelfOnly(false), m_dmrSelfOnly(false),
m_dmrPrefixes(), m_dmrPrefixes(),
m_dmrBlackList(),
m_fusionEnabled(true), m_fusionEnabled(true),
m_fusionParrotEnabled(false), m_fusionParrotEnabled(false),
m_dstarNetworkEnabled(true), m_dstarNetworkEnabled(true),
@ -229,6 +233,19 @@ bool CConf::read()
m_dstarModule = value; m_dstarModule = value;
else if (::strcmp(key, "SelfOnly") == 0) else if (::strcmp(key, "SelfOnly") == 0)
m_dstarSelfOnly = ::atoi(value) == 1; 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) { } else if (section == SECTION_DMR) {
if (::strcmp(key, "Enable") == 0) if (::strcmp(key, "Enable") == 0)
m_dmrEnabled = ::atoi(value) == 1; m_dmrEnabled = ::atoi(value) == 1;
@ -248,6 +265,14 @@ bool CConf::read()
m_dmrPrefixes.push_back(prefix); m_dmrPrefixes.push_back(prefix);
p = ::strtok(NULL, ",\r\n"); 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) { } else if (section == SECTION_FUSION) {
if (::strcmp(key, "Enable") == 0) if (::strcmp(key, "Enable") == 0)
@ -472,6 +497,11 @@ bool CConf::getDStarSelfOnly() const
return m_dstarSelfOnly; return m_dstarSelfOnly;
} }
std::vector<std::string> CConf::getDStarBlackList() const
{
return m_dstarBlackList;
}
bool CConf::getDMREnabled() const bool CConf::getDMREnabled() const
{ {
return m_dmrEnabled; return m_dmrEnabled;
@ -502,6 +532,11 @@ std::vector<unsigned int> CConf::getDMRPrefixes() const
return m_dmrPrefixes; return m_dmrPrefixes;
} }
std::vector<unsigned int> CConf::getDMRBlackList() const
{
return m_dmrBlackList;
}
bool CConf::getFusionEnabled() const bool CConf::getFusionEnabled() const
{ {
return m_fusionEnabled; return m_fusionEnabled;

4
Conf.h
View file

@ -70,6 +70,7 @@ public:
bool getDStarEnabled() const; bool getDStarEnabled() const;
std::string getDStarModule() const; std::string getDStarModule() const;
bool getDStarSelfOnly() const; bool getDStarSelfOnly() const;
std::vector<std::string> getDStarBlackList() const;
// The DMR section // The DMR section
bool getDMREnabled() const; bool getDMREnabled() const;
@ -78,6 +79,7 @@ public:
unsigned int getDMRColorCode() const; unsigned int getDMRColorCode() const;
bool getDMRSelfOnly() const; bool getDMRSelfOnly() const;
std::vector<unsigned int> getDMRPrefixes() const; std::vector<unsigned int> getDMRPrefixes() const;
std::vector<unsigned int> getDMRBlackList() const;
// The System Fusion section // The System Fusion section
bool getFusionEnabled() const; bool getFusionEnabled() const;
@ -152,6 +154,7 @@ private:
bool m_dstarEnabled; bool m_dstarEnabled;
std::string m_dstarModule; std::string m_dstarModule;
bool m_dstarSelfOnly; bool m_dstarSelfOnly;
std::vector<std::string> m_dstarBlackList;
bool m_dmrEnabled; bool m_dmrEnabled;
bool m_dmrBeacons; bool m_dmrBeacons;
@ -159,6 +162,7 @@ private:
unsigned int m_dmrColorCode; unsigned int m_dmrColorCode;
bool m_dmrSelfOnly; bool m_dmrSelfOnly;
std::vector<unsigned int> m_dmrPrefixes; std::vector<unsigned int> m_dmrPrefixes;
std::vector<unsigned int> m_dmrBlackList;
bool m_fusionEnabled; bool m_fusionEnabled;
bool m_fusionParrotEnabled; bool m_fusionParrotEnabled;

View file

@ -20,11 +20,12 @@
#include <cassert> #include <cassert>
#include <algorithm> #include <algorithm>
CDMRControl::CDMRControl(unsigned int id, unsigned int colorCode, bool selfOnly, const std::vector<unsigned int>& 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<unsigned int>& prefixes, const std::vector<unsigned int>& blackList, unsigned int timeout, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex) :
m_id(id), m_id(id),
m_colorCode(colorCode), m_colorCode(colorCode),
m_selfOnly(selfOnly), m_selfOnly(selfOnly),
m_prefixes(prefixes), m_prefixes(prefixes),
m_blackList(blackList),
m_modem(modem), m_modem(modem),
m_network(network), m_network(network),
m_slot1(1U, timeout), m_slot1(1U, timeout),
@ -33,7 +34,7 @@ m_slot2(2U, timeout)
assert(modem != NULL); assert(modem != NULL);
assert(display != 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() CDMRControl::~CDMRControl()
@ -66,6 +67,11 @@ bool CDMRControl::processWakeup(const unsigned char* data)
return false; return false;
} }
} else { } 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; unsigned int prefix = srcId / 10000U;
if (prefix == 0U || prefix > 999U) { if (prefix == 0U || prefix > 999U) {
LogMessage("Invalid CSBK BS_Dwn_Act received from %u", srcId); LogMessage("Invalid CSBK BS_Dwn_Act received from %u", srcId);

View file

@ -29,7 +29,7 @@
class CDMRControl { class CDMRControl {
public: public:
CDMRControl(unsigned int id, unsigned int colorCode, bool selfOnly, const std::vector<unsigned int>& prefixes, unsigned int timeout, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex); CDMRControl(unsigned int id, unsigned int colorCode, bool selfOnly, const std::vector<unsigned int>& prefixes, const std::vector<unsigned int>& blackList, unsigned int timeout, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex);
~CDMRControl(); ~CDMRControl();
bool processWakeup(const unsigned char* data); bool processWakeup(const unsigned char* data);
@ -43,14 +43,15 @@ public:
void clock(); void clock();
private: private:
unsigned int m_id; unsigned int m_id;
unsigned int m_colorCode; unsigned int m_colorCode;
bool m_selfOnly; bool m_selfOnly;
std::vector<unsigned int> m_prefixes; std::vector<unsigned int> m_prefixes;
CModem* m_modem; std::vector<unsigned int> m_blackList;
CDMRIPSC* m_network; CModem* m_modem;
CDMRSlot m_slot1; CDMRIPSC* m_network;
CDMRSlot m_slot2; CDMRSlot m_slot1;
CDMRSlot m_slot2;
}; };
#endif #endif

View file

@ -31,6 +31,7 @@ unsigned int CDMRSlot::m_id = 0U;
unsigned int CDMRSlot::m_colorCode = 0U; unsigned int CDMRSlot::m_colorCode = 0U;
bool CDMRSlot::m_selfOnly = false; bool CDMRSlot::m_selfOnly = false;
std::vector<unsigned int> CDMRSlot::m_prefixes; std::vector<unsigned int> CDMRSlot::m_prefixes;
std::vector<unsigned int> CDMRSlot::m_blackList;
CModem* CDMRSlot::m_modem = NULL; CModem* CDMRSlot::m_modem = NULL;
CDMRIPSC* CDMRSlot::m_network = NULL; CDMRIPSC* CDMRSlot::m_network = NULL;
IDisplay* CDMRSlot::m_display = NULL; IDisplay* CDMRSlot::m_display = NULL;
@ -1228,7 +1229,7 @@ void CDMRSlot::writeQueueNet(const unsigned char *data)
m_queue.addData(data, len); m_queue.addData(data, len);
} }
void CDMRSlot::init(unsigned int id, unsigned int colorCode, bool selfOnly, const std::vector<unsigned int>& prefixes, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex) void CDMRSlot::init(unsigned int id, unsigned int colorCode, bool selfOnly, const std::vector<unsigned int>& prefixes, const std::vector<unsigned int>& blackList, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex)
{ {
assert(id != 0U); assert(id != 0U);
assert(modem != NULL); assert(modem != NULL);
@ -1238,6 +1239,7 @@ void CDMRSlot::init(unsigned int id, unsigned int colorCode, bool selfOnly, cons
m_colorCode = colorCode; m_colorCode = colorCode;
m_selfOnly = selfOnly; m_selfOnly = selfOnly;
m_prefixes = prefixes; m_prefixes = prefixes;
m_blackList = blackList;
m_modem = modem; m_modem = modem;
m_network = network; m_network = network;
m_display = display; m_display = display;
@ -1259,6 +1261,9 @@ bool CDMRSlot::validateId(unsigned int id)
if (m_selfOnly) { if (m_selfOnly) {
return id == m_id; return id == m_id;
} else { } else {
if (std::find(m_blackList.begin(), m_blackList.end(), id) != m_blackList.end())
return false;
unsigned int prefix = id / 10000U; unsigned int prefix = id / 10000U;
if (prefix == 0U || prefix > 999U) if (prefix == 0U || prefix > 999U)
return false; return false;

View file

@ -49,7 +49,7 @@ public:
void clock(); void clock();
static void init(unsigned int id, unsigned int colorCode, bool selfOnly, const std::vector<unsigned int>& prefixes, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex); static void init(unsigned int id, unsigned int colorCode, bool selfOnly, const std::vector<unsigned int>& prefixes, const std::vector<unsigned int>& blackList, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex);
private: private:
unsigned int m_slotNo; unsigned int m_slotNo;
@ -88,6 +88,7 @@ private:
static unsigned int m_colorCode; static unsigned int m_colorCode;
static bool m_selfOnly; static bool m_selfOnly;
static std::vector<unsigned int> m_prefixes; static std::vector<unsigned int> m_prefixes;
static std::vector<unsigned int> m_blackList;
static CModem* m_modem; static CModem* m_modem;
static CDMRIPSC* m_network; static CDMRIPSC* m_network;
static IDisplay* m_display; static IDisplay* m_display;

View file

@ -19,15 +19,28 @@
#include <cstdio> #include <cstdio>
#include <cassert> #include <cassert>
#include <ctime> #include <ctime>
#include <algorithm>
#include <functional>
const unsigned int MAX_SYNC_BIT_ERRORS = 2U; 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 // #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<std::string>& blackList, CDStarNetwork* network, IDisplay* display, unsigned int timeout, bool duplex) :
m_callsign(NULL), m_callsign(NULL),
m_gateway(NULL), m_gateway(NULL),
m_selfOnly(selfOnly), m_selfOnly(selfOnly),
m_blackList(blackList),
m_network(network), m_network(network),
m_display(display), m_display(display),
m_duplex(duplex), m_duplex(duplex),
@ -127,6 +140,11 @@ bool CDStarControl::writeModem(unsigned char *data)
return false; 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]; unsigned char callsign[DSTAR_LONG_CALLSIGN_LENGTH];
header.getRPTCall1(callsign); header.getRPTCall1(callsign);
@ -252,7 +270,23 @@ bool CDStarControl::writeModem(unsigned char *data)
// Is this a transmission destined for a repeater? // Is this a transmission destined for a repeater?
if (!header->isRepeater()) { 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; return false;
} }
@ -262,15 +296,13 @@ bool CDStarControl::writeModem(unsigned char *data)
// Is it for us? // Is it for us?
if (::memcmp(callsign, m_callsign, DSTAR_LONG_CALLSIGN_LENGTH) != 0) { if (::memcmp(callsign, m_callsign, DSTAR_LONG_CALLSIGN_LENGTH) != 0) {
LogMessage("D-Star, received RF header for wrong repeater - %8.8s", callsign); LogMessage("D-Star, received RF header for wrong repeater - %8.8s", callsign);
delete header;
return false; return false;
} }
unsigned char gateway[DSTAR_LONG_CALLSIGN_LENGTH]; unsigned char gateway[DSTAR_LONG_CALLSIGN_LENGTH];
header->getRPTCall2(gateway); header->getRPTCall2(gateway);
unsigned char my1[DSTAR_LONG_CALLSIGN_LENGTH];
header->getMyCall1(my1);
unsigned char my2[DSTAR_SHORT_CALLSIGN_LENGTH]; unsigned char my2[DSTAR_SHORT_CALLSIGN_LENGTH];
header->getMyCall2(my2); header->getMyCall2(my2);

View file

@ -32,10 +32,11 @@
#include "Modem.h" #include "Modem.h"
#include <string> #include <string>
#include <vector>
class CDStarControl { class CDStarControl {
public: 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<std::string>& blackList, CDStarNetwork* network, IDisplay* display, unsigned int timeout, bool duplex);
~CDStarControl(); ~CDStarControl();
bool writeModem(unsigned char* data); bool writeModem(unsigned char* data);
@ -48,6 +49,7 @@ private:
unsigned char* m_callsign; unsigned char* m_callsign;
unsigned char* m_gateway; unsigned char* m_gateway;
bool m_selfOnly; bool m_selfOnly;
std::vector<std::string> m_blackList;
CDStarNetwork* m_network; CDStarNetwork* m_network;
IDisplay* m_display; IDisplay* m_display;
bool m_duplex; bool m_duplex;

View file

@ -143,18 +143,20 @@ int CMMDVMHost::run()
CDStarControl* dstar = NULL; CDStarControl* dstar = NULL;
if (m_dstarEnabled) { if (m_dstarEnabled) {
std::string callsign = m_conf.getCallsign(); std::string callsign = m_conf.getCallsign();
std::string module = m_conf.getDStarModule(); std::string module = m_conf.getDStarModule();
bool selfOnly = m_conf.getDStarSelfOnly(); bool selfOnly = m_conf.getDStarSelfOnly();
unsigned int timeout = m_conf.getTimeout(); unsigned int timeout = m_conf.getTimeout();
std::vector<std::string> blackList = m_conf.getDStarBlackList();
LogInfo("D-Star Parameters"); LogInfo("D-Star Parameters");
LogInfo(" Callsign: %s", callsign.c_str()); LogInfo(" Callsign: %s", callsign.c_str());
LogInfo(" Module: %s", module.c_str()); LogInfo(" Module: %s", module.c_str());
LogInfo(" Self Only: %s", selfOnly ? "yes" : "no"); LogInfo(" Self Only: %s", selfOnly ? "yes" : "no");
if (blackList.size() > 0U)
LogInfo(" Black List: %u", blackList.size());
LogInfo(" Timeout: %us", timeout); LogInfo(" Timeout: %us", timeout);
dstar = new CDStarControl(callsign, module, selfOnly, blackList, m_dstarNetwork, m_display, timeout, m_duplex);
dstar = new CDStarControl(callsign, module, selfOnly, m_dstarNetwork, m_display, timeout, m_duplex);
} }
CDMRControl* dmr = NULL; CDMRControl* dmr = NULL;
@ -163,6 +165,7 @@ int CMMDVMHost::run()
unsigned int colorCode = m_conf.getDMRColorCode(); unsigned int colorCode = m_conf.getDMRColorCode();
bool selfOnly = m_conf.getDMRSelfOnly(); bool selfOnly = m_conf.getDMRSelfOnly();
std::vector<unsigned int> prefixes = m_conf.getDMRPrefixes(); std::vector<unsigned int> prefixes = m_conf.getDMRPrefixes();
std::vector<unsigned int> blackList = m_conf.getDMRBlackList();
unsigned int timeout = m_conf.getTimeout(); unsigned int timeout = m_conf.getTimeout();
LogInfo("DMR Parameters"); LogInfo("DMR Parameters");
@ -170,9 +173,11 @@ int CMMDVMHost::run()
LogInfo(" Color Code: %u", colorCode); LogInfo(" Color Code: %u", colorCode);
LogInfo(" Self Only: %s", selfOnly ? "yes" : "no"); LogInfo(" Self Only: %s", selfOnly ? "yes" : "no");
LogInfo(" Prefixes: %u", prefixes.size()); LogInfo(" Prefixes: %u", prefixes.size());
if (blackList.size() > 0U)
LogInfo(" Black List: %u", blackList.size());
LogInfo(" Timeout: %us", timeout); 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; CYSFControl* ysf = NULL;