mirror of
https://github.com/g4klx/DAPNETGateway.git
synced 2026-08-26 12:32:45 -04:00
Merge pull request #18 from hacknix/master
Add support for whitelist and blacklist REGEX matching on message body
This commit is contained in:
commit
3a44ac4aa6
9 changed files with 213 additions and 3 deletions
18
Conf.cpp
18
Conf.cpp
|
|
@ -37,6 +37,8 @@ CConf::CConf(const std::string& file) :
|
|||
m_file(file),
|
||||
m_callsign(),
|
||||
m_whiteList(),
|
||||
m_blacklistRegexfile(),
|
||||
m_whitelistRegexfile(),
|
||||
m_rptAddress(),
|
||||
m_rptPort(0U),
|
||||
m_myAddress(),
|
||||
|
|
@ -105,7 +107,11 @@ bool CConf::read()
|
|||
m_whiteList.push_back(ric);
|
||||
p = ::strtok(NULL, ",\r\n");
|
||||
}
|
||||
} else if (::strcmp(key, "RptAddress") == 0)
|
||||
} else if (::strcmp(key,"BlacklistRegexfile") == 0)
|
||||
m_blacklistRegexfile = value;
|
||||
else if (::strcmp(key,"WhitelistRegexfile") == 0)
|
||||
m_whitelistRegexfile = value;
|
||||
else if (::strcmp(key, "RptAddress") == 0)
|
||||
m_rptAddress = value;
|
||||
else if (::strcmp(key, "RptPort") == 0)
|
||||
m_rptPort = (unsigned int)::atoi(value);
|
||||
|
|
@ -155,6 +161,16 @@ std::vector<uint32_t> CConf::getWhiteList() const
|
|||
return m_whiteList;
|
||||
}
|
||||
|
||||
std::string CConf::getblacklistRegexfile() const
|
||||
{
|
||||
return m_blacklistRegexfile;
|
||||
}
|
||||
|
||||
std::string CConf::getwhitelistRegexfile() const
|
||||
{
|
||||
return m_whitelistRegexfile;
|
||||
}
|
||||
|
||||
std::string CConf::getRptAddress() const
|
||||
{
|
||||
return m_rptAddress;
|
||||
|
|
|
|||
4
Conf.h
4
Conf.h
|
|
@ -33,6 +33,8 @@ public:
|
|||
// The General section
|
||||
std::string getCallsign() const;
|
||||
std::vector<unsigned int> getWhiteList() const;
|
||||
std::string getblacklistRegexfile() const;
|
||||
std::string getwhitelistRegexfile() const;
|
||||
std::string getRptAddress() const;
|
||||
unsigned int getRptPort() const;
|
||||
std::string getMyAddress() const;
|
||||
|
|
@ -56,6 +58,8 @@ private:
|
|||
|
||||
std::string m_callsign;
|
||||
std::vector<unsigned int> m_whiteList;
|
||||
std::string m_blacklistRegexfile;
|
||||
std::string m_whitelistRegexfile;
|
||||
std::string m_rptAddress;
|
||||
unsigned int m_rptPort;
|
||||
std::string m_myAddress;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@
|
|||
#include "Thread.h"
|
||||
#include "Timer.h"
|
||||
#include "Log.h"
|
||||
#include "REGEX.h"
|
||||
#include <regex>
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#include <Windows.h>
|
||||
|
|
@ -108,6 +110,8 @@ m_schedule(NULL),
|
|||
m_allSlots(false),
|
||||
m_currentSlot(0U),
|
||||
m_sentCodewords(0U),
|
||||
m_regexBlacklist(),
|
||||
m_regexWhitelist(),
|
||||
m_mmdvmFree(false)
|
||||
{
|
||||
}
|
||||
|
|
@ -263,6 +267,18 @@ int CDAPNETGateway::run()
|
|||
}
|
||||
|
||||
std::vector<unsigned int> whiteList = m_conf.getWhiteList();
|
||||
std::vector<std::regex> regexBlacklist;
|
||||
std::vector<std::regex> regexWhitelist;
|
||||
|
||||
m_regexBlacklist = new CREGEX(m_conf.getblacklistRegexfile());
|
||||
if (m_regexBlacklist->load())
|
||||
regexBlacklist = m_regexBlacklist->get();
|
||||
|
||||
m_regexWhitelist = new CREGEX(m_conf.getwhitelistRegexfile());
|
||||
if (m_regexWhitelist->load())
|
||||
regexWhitelist = m_regexWhitelist->get();
|
||||
|
||||
|
||||
|
||||
for (;;) {
|
||||
unsigned char buffer[200U];
|
||||
|
|
@ -296,12 +312,39 @@ int CDAPNETGateway::run()
|
|||
CPOCSAGMessage* message = m_dapnetNetwork->readMessage();
|
||||
if (message != NULL) {
|
||||
bool found = true;
|
||||
bool blacklistRegexmatch = false;
|
||||
bool whitelistRegexmatch = true;
|
||||
|
||||
// If we have a white list of RICs, use it.
|
||||
if (!whiteList.empty())
|
||||
found = std::find(whiteList.begin(), whiteList.end(), message->m_ric) != whiteList.end();
|
||||
|
||||
std::string messageBody(reinterpret_cast<char*>(message->m_message));
|
||||
//If we have a list of blacklist REGEXes, use them
|
||||
if (!regexBlacklist.empty()) {
|
||||
for (std::regex regex : regexBlacklist) {
|
||||
bool ret = std::regex_match(messageBody,regex);
|
||||
//If the regex matches the message body, don't send the message
|
||||
if (ret) {
|
||||
blacklistRegexmatch = true;
|
||||
LogDebug("Blacklist REGEX match: Not queueing message to %07u, type %u, message: \"%.*s\"", message->m_ric, message->m_type, message->m_length, messageBody.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
if(!regexWhitelist.empty() && !blacklistRegexmatch) {
|
||||
for (std::regex regex : regexWhitelist) {
|
||||
bool ret = std::regex_match(messageBody,regex);
|
||||
//If the regex does not match the message body, don't send the message
|
||||
if (!ret) {
|
||||
whitelistRegexmatch = false;
|
||||
LogDebug("No whitelist REGEX match: Not queueing message to %07u, type %u, message: \"%.*s\"", message->m_ric, message->m_type, message->m_length, messageBody.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (found && !blacklistRegexmatch && whitelistRegexmatch) {
|
||||
switch (message->m_functional) {
|
||||
case FUNCTIONAL_ALPHANUMERIC:
|
||||
LogDebug("Queueing message to %07u, type %u, func Alphanumeric: \"%.*s\"", message->m_ric, message->m_type, message->m_length, message->m_message);
|
||||
|
|
|
|||
|
|
@ -24,10 +24,12 @@
|
|||
#include "POCSAGMessage.h"
|
||||
#include "StopWatch.h"
|
||||
#include "Conf.h"
|
||||
#include "REGEX.h"
|
||||
|
||||
#include <string>
|
||||
#include <deque>
|
||||
#include <vector>
|
||||
#include <regex>
|
||||
|
||||
class CDAPNETGateway
|
||||
{
|
||||
|
|
@ -47,6 +49,8 @@ private:
|
|||
bool m_allSlots;
|
||||
unsigned int m_currentSlot;
|
||||
unsigned int m_sentCodewords;
|
||||
CREGEX* m_regexBlacklist;
|
||||
CREGEX* m_regexWhitelist;
|
||||
bool m_mmdvmFree;
|
||||
|
||||
|
||||
|
|
@ -56,6 +60,9 @@ private:
|
|||
unsigned int calculateCodewords(const CPOCSAGMessage* message) const;
|
||||
void loadSchedule();
|
||||
bool sendMessage(CPOCSAGMessage* message) const;
|
||||
|
||||
// std::vector<std::regex> m_regexBlacklist;
|
||||
// std::vector<std::regex> m_regexWhitelist;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
[General]
|
||||
Callsign=g9bf
|
||||
# WhiteList=12345,78901
|
||||
#BlacklistRegexfile=/tmp/blregexes.txt
|
||||
#WhitelistRegexfile=/tmp/wlregexes.txt
|
||||
RptAddress=127.0.0.1
|
||||
RptPort=3800
|
||||
LocalAddress=127.0.0.1
|
||||
|
|
|
|||
2
Makefile
2
Makefile
|
|
@ -4,7 +4,7 @@ CFLAGS = -g -O3 -Wall -std=c++0x -pthread
|
|||
LIBS = -lm -lpthread
|
||||
LDFLAGS = -g
|
||||
|
||||
OBJECTS = Conf.o DAPNETGateway.o DAPNETNetwork.o Log.o POCSAGMessage.o POCSAGNetwork.o StopWatch.o TCPSocket.o Thread.o Timer.o UDPSocket.o Utils.o
|
||||
OBJECTS = Conf.o DAPNETGateway.o DAPNETNetwork.o Log.o POCSAGMessage.o POCSAGNetwork.o StopWatch.o TCPSocket.o Thread.o Timer.o UDPSocket.o Utils.o REGEX.o
|
||||
|
||||
all: DAPNETGateway
|
||||
|
||||
|
|
|
|||
21
README.REGEX
Normal file
21
README.REGEX
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
The REGEX functionality allows you to whitelist or blacklist messages based on
|
||||
pattern matching the message body itself (not the RIC).
|
||||
|
||||
The options for this are:
|
||||
|
||||
|
||||
WhitelistRegexfile=
|
||||
BlacklistRegexfile=
|
||||
|
||||
REGEXs are placed in the the respective textfile, one per line. These need to
|
||||
be a full match, i.e. they need to match the entire message, begining with ^
|
||||
and ending with $.
|
||||
|
||||
For example:
|
||||
|
||||
^NAGIOS.*$ - matches all Nagios alerts
|
||||
|
||||
^(G|M|2).+$ - Matches messages with the first character as a G.M or 2 - i.e.
|
||||
match all UK callsigns.
|
||||
|
||||
|
||||
74
REGEX.cpp
Normal file
74
REGEX.cpp
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright (C) 2016,2017 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* Contributed by Simon G7RZU
|
||||
*
|
||||
* 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
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "REGEX.h"
|
||||
#include "Log.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
CREGEX::CREGEX(const std::string& regexFile) :
|
||||
m_regexFile(regexFile),
|
||||
m_regex()
|
||||
{
|
||||
}
|
||||
|
||||
bool CREGEX::load()
|
||||
{
|
||||
FILE* fp = ::fopen(m_regexFile.c_str(), "rt");
|
||||
if (fp != NULL) {
|
||||
char buffer[100U];
|
||||
std::regex regex;
|
||||
while (::fgets(buffer, 100U, fp) != NULL) {
|
||||
if (buffer[0U] == '#')
|
||||
continue;
|
||||
|
||||
const char* regexStr = ::strtok(buffer, "\r\n");
|
||||
|
||||
if (regexStr != NULL) {
|
||||
try {
|
||||
regex = std::regex(regexStr);
|
||||
}
|
||||
|
||||
catch(const std::regex_error& e) {
|
||||
LogDebug("error in regex %s (%s), skipping",regexStr,e.what());
|
||||
continue;
|
||||
}
|
||||
m_regex.push_back(regex);
|
||||
}
|
||||
}
|
||||
|
||||
::fclose(fp);
|
||||
}
|
||||
|
||||
size_t size = m_regex.size();
|
||||
LogInfo("Loaded %u REGEX from file %s", size, m_regexFile.c_str());
|
||||
|
||||
size = m_regex.size();
|
||||
if (size == 0U)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<std::regex> CREGEX::get()
|
||||
{
|
||||
return(m_regex);
|
||||
}
|
||||
43
REGEX.h
Normal file
43
REGEX.h
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (C) 2016,2017 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* Contributed by Simon G7RZU
|
||||
*
|
||||
* 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
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#if !defined(REGEX_H)
|
||||
#define REGEX_H
|
||||
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <regex>
|
||||
|
||||
class CREGEX {
|
||||
public:
|
||||
|
||||
std::vector<std::regex> get();
|
||||
bool load();
|
||||
CREGEX(const std::string& regexFile);
|
||||
~CREGEX();
|
||||
|
||||
private:
|
||||
|
||||
std::string m_regexFile;
|
||||
std::vector<std::regex> m_regex;
|
||||
};
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue