Compare commits

...

22 Commits

Author SHA1 Message Date
b10a0de9e6 Grabbing adresses if available from header 2021-11-22 12:37:44 +01:00
58a535401a Grabbing first data from header 2021-11-22 12:37:28 +01:00
c37a214808 Added type-string 2021-11-22 12:24:07 +01:00
9ce2da6f61 Renamed size to payloadSize 2021-11-22 12:23:56 +01:00
177181668d Renamed linkSpeed to dataRate 2021-11-22 12:23:43 +01:00
9755e86a98 Change packet-macs to string 2021-11-22 11:53:31 +01:00
c5bc468ab9 Added documentation to find 2021-11-22 11:31:13 +01:00
ee3505090d Added helper-file for finding items in std::vector<std::string> 2021-11-22 11:27:48 +01:00
cb33dd0f80 Moved timestampConvert to own helper-file 2021-11-22 11:26:38 +01:00
8a62d2899b Moved split to own helper-file 2021-11-22 11:24:10 +01:00
6de2063288 Implemented textTimestamp converter to timestampMicros 2021-11-22 10:35:08 +01:00
5d3e861fc9 Gathering first data from textPacket 2021-11-22 10:34:16 +01:00
9c18c50640 Added TextHandler to exec-call 2021-11-22 10:33:24 +01:00
8e5cb85c1a Fixed passing of handlerFunction-pointer 2021-11-22 10:32:57 +01:00
e7dcaf99a0 Created empty PacketHandler 2021-11-22 10:32:29 +01:00
36f252437d Changed from only strings to vector-strings 2021-11-22 10:32:04 +01:00
5ac832623d Created empty TextPacketHandler 2021-11-22 10:31:41 +01:00
57b8ae868c Changed packet-timestamp to uint64_t for epoch-timestamp in micros 2021-11-22 10:28:41 +01:00
e66f6c1140 Fixed strcopy being wrong way around 2021-11-22 10:28:23 +01:00
f3b9eb25a7 Added missing pthread-library 2021-11-22 09:10:59 +01:00
35edc6ca6e Created basic chained handlers 2021-11-22 09:08:25 +01:00
b8b2bb7202 Added basic packet-structure 2021-11-22 09:07:49 +01:00
11 changed files with 241 additions and 4 deletions

View File

@ -6,6 +6,8 @@ enable_testing()
add_executable(rfmon-to-influx main.cpp)
target_link_libraries(rfmon-to-influx pthread)
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)

21
DTO/packet.hpp Normal file
View File

@ -0,0 +1,21 @@
#ifndef C42FA9F6_8CF3_453F_8FA0_918E543DCD59
#define C42FA9F6_8CF3_453F_8FA0_918E543DCD59
#include <string>
struct Packet {
uint64_t timestampMicros;
std::string srcMac;
std::string dstMac;
unsigned int payloadSize;
char signal;
unsigned int frequency;
unsigned char dataRate;
std::string type;
};
#endif /* C42FA9F6_8CF3_453F_8FA0_918E543DCD59 */

17
handler/asyncHandler.hpp Normal file
View File

@ -0,0 +1,17 @@
#ifndef EFFCCB40_3639_4BD4_9649_302F05987909
#define EFFCCB40_3639_4BD4_9649_302F05987909
#include <future>
#include <string.h>
#include "bufHandler.hpp"
void asyncHandler(char *buf){
// Create a copy of buf for our thread
char bufCopy[265];
strcpy(bufCopy, buf);
// \/ Surpress unused warning
(void)std::async(std::launch::async, bufHandler, bufCopy);
}
#endif /* EFFCCB40_3639_4BD4_9649_302F05987909 */

22
handler/bufHandler.hpp Normal file
View File

@ -0,0 +1,22 @@
#ifndef C251BA62_6D80_4033_86B6_61F184E6F250
#define C251BA62_6D80_4033_86B6_61F184E6F250
#include <string>
#include "textPacketHandler.hpp"
using namespace std::string_literals;
std::vector<std::string> buffer;
void bufHandler(char *buf){
// When first char of buf has text (no tab), we got a new packet
if(buf[0] != '\t'){
// Submit the just-read text-packet
if(buffer.size() != 0) textPacketHandler(buffer);
buffer = std::vector<std::string>();
}
// Append part-packet
buffer.push_back(buf);
}
#endif /* C251BA62_6D80_4033_86B6_61F184E6F250 */

10
handler/packetHandler.hpp Normal file
View File

@ -0,0 +1,10 @@
#ifndef EA8E466A_DAAA_4747_9CEE_65B77A4EF694
#define EA8E466A_DAAA_4747_9CEE_65B77A4EF694
#include "../DTO/packet.hpp"
void packetHandler(Packet packet){
}
#endif /* EA8E466A_DAAA_4747_9CEE_65B77A4EF694 */

View File

@ -0,0 +1,60 @@
#ifndef EE781A91_6D07_47AC_B3C4_F99E29F3731F
#define EE781A91_6D07_47AC_B3C4_F99E29F3731F
#include <string>
#include "../DTO/packet.hpp"
#include <vector>
#include <sstream>
#include <locale>
#include <iomanip>
#include "../helper/split.hpp"
#include "../helper/timestampConvert.hpp"
#include "../helper/find.hpp"
void textPacketHandler(std::vector<std::string> textPacket){
/// Here we have to parse the packet
// Create empty packet
Packet packet;
const std::string textHeader = textPacket[0];
const std::vector<std::string> headerData = split(textHeader, ' ');
std::string textTimestamp = headerData[0];
uint64_t timestamp = convertStringToTimestampMicros(textTimestamp);
// Find remaining data based on keys in/around fields
int linkSpeedIndex = findIs(headerData, "Mb/s", 1, 1);
packet.dataRate = std::stoi(headerData[linkSpeedIndex]);
int frequencyIndex = findIs(headerData, "MHz", 1, 1);
packet.frequency = std::stoi(headerData[frequencyIndex]);
int signalIndex = findIs(headerData, "signal", 1, 1);
std::string signalText = headerData[signalIndex].substr(0, 3);
packet.signal = std::stoi(signalText);
// Addresses seem complicated at first, but just have many fields which might be available.
// SA and DA are src- and dst-Addresses
// BSSID is the used bssid
// TA and RA are transmitter- and receiver-address which are used exclusively for RTS and CTS in tcpdump
// BEWARE: SA, DA, BSSID, TA and RA can be used together, but tcpdump doesnt display all of them!
// DA might also not be a valid MAC-address, but Broadcast or an encoded IPv4/6 Multicast-address
int saIndex = findContains(headerData, "SA:", 1);
std::string sAddr = (saIndex != -1) ? headerData[saIndex].substr("SA:"s.length()) : "";
int daIndex = findContains(headerData, "DA:", 1);
std::string dAddr = (daIndex != -1) ? headerData[daIndex].substr("DA:"s.length()) : "";
int bssidIndex = findContains(headerData, "BSSID:", 1);
std::string bssidAddr = (bssidIndex != -1) ? headerData[bssidIndex].substr("BSSID:"s.length()) : "";
int taIndex = findContains(headerData, "SA:", 1);
std::string tAddr = (taIndex != -1) ? headerData[taIndex].substr("SA:"s.length()) : "";
int raIndex = findContains(headerData, "RA:", 1);
std::string rAddr = (raIndex != -1) ? headerData[raIndex].substr("RA:"s.length()) : "";
}
#endif /* EE781A91_6D07_47AC_B3C4_F99E29F3731F */

View File

@ -8,7 +8,7 @@
/// @param cmd is the command
/// @param handler is the handler(char*)-function
/// @return Return-code form command
int exec(const char* cmd, const int *(handler)(char*) = nullptr){
int exec(const char* cmd, void (*handler)(char*) = nullptr){
const int buf_size = 256;
char buf[buf_size];

53
helper/find.hpp Normal file
View File

@ -0,0 +1,53 @@
#ifndef B6A9DEE0_30C6_4492_AB96_87D9C5C10E8B
#define B6A9DEE0_30C6_4492_AB96_87D9C5C10E8B
#include <string>
#include <vector>
/// @brief Internal function
void prepare(const int &size, int &start, const int &offset, int &end){
// Set missing fields
if(!end) end = size;
// Edit start/end according to offset
if(offset < 0)
start += offset;
else if(offset > 0)
end -= offset;
}
/// @brief Find str-index based on contains-content
/// @param data is the vector-string-data to search
/// @param strContains string to find
/// @param start where to start searching
/// @param offset search offset to position (results in index being shifted by -offset)
/// @param end where to end searching
/// @return index of found index (with offset if any)
int findContains(const std::vector<std::string> &data, const std::string &strContains, int start = 0, int offset = 0, int end = 0){
prepare(data.size(), start, offset, end);
for(int i=start; i<data.size()-offset; ++i){
if(!data[i+offset].find(strContains))
return i;
}
return -1;
}
/// @brief Find str-index based on exact-content
/// @param data is the vector-string-data to search
/// @param strIs string to find (exact)
/// @param start where to start searching
/// @param offset search offset to position (results in index being shifted by -offset)
/// @param end where to end searching
/// @return index of found index (with offset if any)
int findIs(const std::vector<std::string> &data, const std::string &strIs, int start = 0, int offset = 0, int end = 0){
prepare(data.size(), start, offset, end);
for(int i=start; i<data.size()-offset; ++i){
if(data[i+offset] == strIs)
return i;
}
return -1;
}
#endif /* B6A9DEE0_30C6_4492_AB96_87D9C5C10E8B */

16
helper/split.hpp Normal file
View File

@ -0,0 +1,16 @@
#ifndef F7CFE6A7_34BF_4E04_94CF_DB8374980631
#define F7CFE6A7_34BF_4E04_94CF_DB8374980631
std::vector<std::string> split(const std::string& s, char delimiter)
{
std::vector<std::string> tokens;
std::string token;
std::istringstream tokenStream(s);
while (std::getline(tokenStream, token, delimiter))
{
tokens.push_back(token);
}
return tokens;
}
#endif /* F7CFE6A7_34BF_4E04_94CF_DB8374980631 */

View File

@ -0,0 +1,36 @@
#ifndef CC724CA7_8BB8_43B9_8A9A_54BD880A76AA
#define CC724CA7_8BB8_43B9_8A9A_54BD880A76AA
uint64_t convertStringToTimestampMicros(std::string textTimestamp){
uint64_t timestamp;
std::tm t = {};
std::istringstream ssTimestamp = std::istringstream(textTimestamp);
if (ssTimestamp >> std::get_time(&t, "%H:%M:%S"))
{
// Get current time
std::time_t curT = std::time(0);
std::tm* curTime = std::localtime(&curT);
// Set missing fields
t.tm_mday = curTime->tm_mday;
t.tm_mon = curTime->tm_mon;
t.tm_year = curTime->tm_year;
t.tm_zone = curTime->tm_zone;
// Convert tm to time
std::time_t time = std::mktime(&t);
// Get micros
int micros = std::stoi(textTimestamp.substr(9, 6));
// Calculate timestamp epoch in micros
timestamp = time*1000000 + micros;
return timestamp;
}
else
{
throw std::runtime_error("Could not parse time: '"+ textTimestamp +"'");
}
}
#endif /* CC724CA7_8BB8_43B9_8A9A_54BD880A76AA */

View File

@ -1,7 +1,7 @@
#include <stdio.h>
#include <string>
#include "./helper/exec.hpp"
#include "./handler/asyncHandler.hpp"
const std::string tcpdump_baseCmd = "tcpdump -vvv -e -n -X -s0 -i ";
@ -14,9 +14,9 @@ int main(int argc, char *args[]){
fprintf(stderr, "Missing interface\n");
exit(1);
}
int exitCode = exec(tcpdump_cmd.c_str());
int exitCode = exec(tcpdump_cmd.c_str(), &asyncHandler);
if(exitCode){
fprintf(stderr, "\ntcpdump exited with non-zero ExitCode: %d\n Something went wrong! Check tcpdump-output for more information.\n", exitCode);
exit(1);