Skip to content

Commit

Permalink
Added auto-renewal for hold mode. Fixed -T launch parameter. Moved so…
Browse files Browse the repository at this point in the history
…me code blocks to separate functions
  • Loading branch information
easymoney322 committed Jun 24, 2023
1 parent 7474e72 commit d9f2970
Show file tree
Hide file tree
Showing 9 changed files with 259 additions and 61 deletions.
5 changes: 3 additions & 2 deletions GlobalVars.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#include "GlobalVars.hpp"

std::vector<WinDev> DEVS; //Vector, containing all our interfaces
std::vector <pcpp::Packet> SentPackets;
std::vector <ProlongationStruct> ProlongationList;
std::string SMAC{ "" }; //Our MAC
std::string DMAC{ "" }; //MAC of device we will be impersonating (Optional)
std::string GWMAC{ "" }; //Gateway MAC (Optional)
Expand All @@ -11,8 +13,7 @@ bool istcp = false;
bool both = false;
uint_fast8_t progmode=0;
uint_fast16_t gwlistenerport = 5351; //Default port
extern uint_fast16_t internalport = 1025;
uint_fast16_t internalport = 1025;
uint_fast16_t externalport = 1025;
uint_fast32_t mappinglifetime = 7200; //Recommended to be 2 hrs (https://datatracker.ietf.org/doc/html/rfc6886)
std::vector <pcpp::Packet> SentPackets;
WinDev OutputInterface;
22 changes: 21 additions & 1 deletion GlobalVars.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <string>
#include <vector>
#include <packet.h>
#include <chrono>
extern bool istcp;
extern bool both;

Expand All @@ -18,9 +19,11 @@ extern uint_fast16_t gwlistenerport; //Port that NAT-PMP-capable gateway listeni
extern uint_fast16_t internalport;
extern uint_fast16_t externalport;
extern uint_fast32_t mappinglifetime; //Recommended to be 2 hrs (https://datatracker.ietf.org/doc/html/rfc6886)

extern std::vector <pcpp::Packet> SentPackets;

extern struct WinDev {
extern struct WinDev
{
std::string ipaddr{ "" }; //IPv4 address of an interface as as tring
std::string gwayip{ "" }; //DGWAY as a string
std::vector<uint_fast8_t> macaddrvec; //MAC address of an interface
Expand All @@ -33,4 +36,21 @@ extern struct WinDev {
};
extern WinDev OutputInterface;
extern std::vector<WinDev> DEVS;

extern struct ProtoPort
{
std::string proto{ "UDP" };
uint_fast16_t portnumin{ 0 };
uint_fast16_t portnumout{ 0 };
std::string UpdateText{ "" };
};
extern struct ProlongationStruct
{
pcpp::Packet Packet;
uint_fast64_t TimestampOfNextUpdate;
std::chrono::time_point <std::chrono::system_clock> chronotimepoint;
ProtoPort ProtocolAndPort;
};

extern std::vector <ProlongationStruct> ProlongationList;
#endif
10 changes: 10 additions & 0 deletions LaunchOptionsHandling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,16 @@ int LaunchOptionsProcessing(int localargc, char* localargv[])
SMAC.clear();
}

if (true == has_option(launcharguments, "-T")) //Source MAC argument handling
{
std::string lifetimestring = get_option(launcharguments, "-T");
mappinglifetime = stoi(lifetimestring);
std::cout << "Mapping lifetime is set to " << mappinglifetime << " seconds." << std::endl;
}
else
{
SMAC.clear();
}

if (true == has_option(launcharguments, "-GW")) //Gateway IPv4 argument handling
{
Expand Down
8 changes: 8 additions & 0 deletions NetFormating.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,4 +201,12 @@ char DetermineDelimiter(std::string inputstring, uint_fast8_t expectedblocksize)
}
g = '\0';
return g;
}

uint_fast32_t GetMappingLifetimeFromPacket(pcpp::Packet lspacket)
{
uint8_t* ppayload = lspacket.getLayerOfType<pcpp::PayloadLayer>()->getPayload();
uint_fast32_t* packetlifetime = (uint_fast32_t*)&ppayload[8];
uint_fast32_t hostorder = ntohl(*packetlifetime);
return hostorder;
}
3 changes: 3 additions & 0 deletions NetFormating.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@
#include <vector>
#include <algorithm>
#include <PayloadLayer.h>
#include <chrono>
#include <Packet.h>

char DetermineDelimiter(std::string inputstring, uint_fast8_t expectedblocksize);
int MakeMeIpv4(uint_fast32_t input, unsigned int& a, unsigned int& b, unsigned int& c, unsigned int& d);
uint_fast16_t portcheck(const std::string inputstring, const char* whos);
uint_fast32_t GetMappingLifetimeFromPacket(pcpp::Packet lspacket);
uint_fast32_t SchizoConverter(std::string inputstring);

void PrintIPV4(const char* msg, uint_fast32_t input);
Expand Down
241 changes: 188 additions & 53 deletions NetFunctions.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#include "NetFunctions.hpp"

#define VERBOSE
#pragma warning(disable : 4996)
uint_fast8_t sendspoof(std::string lsDMAC, std::string lsGWMAC, std::string lsDADDR, WinDev Out, bool lstcp, uint_fast16_t lsinternalport, uint_fast16_t lsexternalport, std::string lsDGWAY, uint_fast16_t lsGWlistenport, uint_fast32_t mappingtime)
{
/*
Expand Down Expand Up @@ -63,57 +62,8 @@ uint_fast8_t sendspoof(std::string lsDMAC, std::string lsGWMAC, std::string lsDA
newPacket.computeCalculateFields();

pcpp::IPv4Address testv4(Out.ipaddr);
if (true == testv4.isValid())
{
pcpp::PcapLiveDevice* dev = pcpp::PcapLiveDeviceList::getInstance().getPcapLiveDeviceByIp(testv4);
if (nullptr == dev)
{
std::cerr << "Couldn't find interface by provided IP address or name" << std::endl;
return 201;
}
if (!dev->open())
{
std::cerr << "Couldn't open the device." << std::endl;
return 202;
}
else
{
std::cout << "Trying to send packet for ";
if (true == lstcp)
{
std::cout << "TCP" << std::endl;
}
else
{
std::cout << "UDP" << std::endl;
}
int sentCount = dev->sendPacket(&newPacket);


if (1 == progmode) //Caching mappings is only needed in Hold mode
{
bool alreadyexists = false;
for (unsigned int sp = 0; sp < SentPackets.size(); sp++)
{
if (0 == ComparePayloads(*(SentPackets.at(sp).getLayerOfType<pcpp::PayloadLayer>()), newPayload))
{
alreadyexists = true;
SentPackets.at(sp) = newPacket;
}
}
if (false == alreadyexists)
{
SentPackets.push_back(newPacket);
}
}

std::this_thread::sleep_for(std::chrono::milliseconds(250)); //250ms delay to assure correct processing in series of requests

}
free(lsbuffer);
return 0;
}
std::cerr << "Host address didn't pass the validation check. Aborting..." << std::endl;
SendPacketWrap(newPacket, Out);
free(lsbuffer);
return 322;
}
std::cerr << "Wasn't able to allocate memory. Aborting..." << std::endl;
Expand Down Expand Up @@ -371,4 +321,189 @@ uint_fast8_t PrintPayloadFromPacket(pcpp::Packet packet)
std::cout << std::hex << std::setfill('0') << std::setw(2) << (int)ppayload[i] << "-";
}
return 0;
}


uint_fast64_t CreateTimestampOfNextUpdate(pcpp::PayloadLayer payload)
{
uint8_t* pdata = payload.getPayload();
uint_fast32_t* packetlifetime = (uint_fast32_t*)&pdata[8];
uint_fast32_t hostorder = ntohl(*packetlifetime);
hostorder /= 2; //Time till refresh in seconds
uint_fast64_t systime = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count(); //Current time
uint_fast64_t timeofrefresh = systime + hostorder; //Time of required update

return timeofrefresh;
}


std::chrono::time_point <std::chrono::system_clock> CreateTimepointOfNextUpdate(pcpp::PayloadLayer payload)
{
uint8_t* pdata = payload.getPayload();
uint_fast32_t* packetlifetime = (uint_fast32_t*)&pdata[8];
uint_fast32_t hostorder = ntohl(*packetlifetime);
hostorder /= 2; //Time till refresh in seconds
std::chrono::time_point <std::chrono::system_clock> systemtime = std::chrono::system_clock::now();
std::chrono::time_point <std::chrono::system_clock> timeofrefresh = systemtime + std::chrono::seconds(hostorder);
const std::time_t datetimesyst = std::chrono::system_clock::to_time_t(systemtime);
const std::time_t datetimerefr = std::chrono::system_clock::to_time_t(timeofrefresh);
return timeofrefresh;
}



uint_fast64_t CreateTimestampOfNextUpdate(pcpp::Packet packet)
{
uint8_t* ppayload = packet.getLayerOfType<pcpp::PayloadLayer>()->getPayload();
uint_fast64_t retval = CreateTimestampOfNextUpdate(*ppayload);
return retval;
}

uint_fast64_t CreateTimestampOfNextUpdate(uint32_t lifetime)
{

uint_fast64_t secondstillupdate = lifetime / 2;
uint_fast64_t systime = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count(); //Current time
uint_fast64_t timeofrefresh = systime + secondstillupdate; //Time of required update

return timeofrefresh;
}

ProtoPort GetProtoAndPortFromPayloadLayer(pcpp::PayloadLayer lspayload)
{
uint8_t* pdata = lspayload.getPayload();
uint8_t opmode = pdata[1];
std::string retstr;
uint16_t retint = 0;
uint16_t retext = 0;
if (1 == opmode)
{
retstr = "UDP";
}
if (2 == opmode)
{
retstr = "TCP";
}
if ( retstr.empty() )
{
std::cerr << "Error occured during protocol processing" << std::endl;
}

uint_fast16_t* portnumint = (uint_fast16_t*)&pdata[4]; //4,5 = INT
retint = ntohs(*portnumint);
uint_fast16_t* portnumext = (uint_fast16_t*)&pdata[6]; //4,5 = INT
retext = ntohs(*portnumext);
std::string Updstr = "Updated mapping for " + retstr + '-' + std::to_string(retint) + '-' + std::to_string(retext) + '.';
return { retstr,retint, retext, Updstr };
}

ProtoPort GetProtoAndPortFromPacket(pcpp::Packet packet)
{
pcpp::PayloadLayer * ppayload = packet.getLayerOfType<pcpp::PayloadLayer>();
ProtoPort retval = GetProtoAndPortFromPayloadLayer(*ppayload);
return retval;
}

uint_fast8_t WatchList()
{
std::chrono::time_point <std::chrono::system_clock> systemtime;
while (0 < ProlongationList.size() )
{
systemtime = std::chrono::system_clock::now();
for (int it = 0; it < ProlongationList.size(); it++)
{
if (ProlongationList.at(it).chronotimepoint <= systemtime)
{
uint8_t res = SendPacketWrap(ProlongationList.at(it).Packet, OutputInterface);
if (0 != res)
{
std::cerr << "An error occured when tried to update mapping time!" << std::endl;
}
}

}
}
return 0;
}

uint_fast8_t SendPacketWrap(pcpp::Packet &lspacket, WinDev lsOut)
{
pcpp::IPv4Address testv4(lsOut.ipaddr);
if (true == testv4.isValid())
{
pcpp::PcapLiveDevice* dev = pcpp::PcapLiveDeviceList::getInstance().getPcapLiveDeviceByIp(testv4);
if (nullptr == dev)
{
std::cerr << "Couldn't find interface by provided IP address or name" << std::endl;
return 201;
}
if (!dev->open())
{
std::cerr << "Couldn't open the device." << std::endl;
return 202;
}
else
{
dev->sendPacket(&lspacket);
if (1 == progmode) //Caching mappings is only needed in Hold mode
{
bool alreadyexists = false;
pcpp::PayloadLayer lspayload = *(lspacket.getLayerOfType<pcpp::PayloadLayer>());
for (unsigned int sp = 0; sp < SentPackets.size(); sp++)
{
if (0 == ComparePayloads(*(SentPackets.at(sp).getLayerOfType<pcpp::PayloadLayer>()), lspayload))
{
alreadyexists = true;
SentPackets.at(sp) = lspacket;
}
}
if (false == alreadyexists)
{
SentPackets.push_back(lspacket);
}
uint32_t mappingtime = GetMappingLifetimeFromPacket(lspacket);
if (0 != mappingtime)
{
alreadyexists = false;
for (unsigned int sp = 0; sp < ProlongationList.size(); sp++)
{
if (0 == ComparePayloads(*(ProlongationList.at(sp).Packet.getLayerOfType<pcpp::PayloadLayer>()), lspayload))
{
alreadyexists = true;
std::chrono::time_point <std::chrono::system_clock> UpdateTime = CreateTimepointOfNextUpdate(lspayload);
ProlongationList.at(sp).TimestampOfNextUpdate = CreateTimestampOfNextUpdate(lspacket);
ProlongationList.at(sp).chronotimepoint = UpdateTime;
std::time_t datetimerefr = std::chrono::system_clock::to_time_t(UpdateTime);
std::string str1 = ProlongationList.at(sp).ProtocolAndPort.UpdateText;
std::string str2 = "Next update for this mapping will be at " + (std::string) std::ctime(&datetimerefr);
uint_fast64_t outwidth;
if (str1.size() > str2.size())
{
outwidth = str1.size();
}
else
{
outwidth = str2.size();
}
std::cout << std::setw(outwidth) << std::setfill('-') << " " << std::endl;
std::cout << str1 << std::endl;
std::cout << str2;
std::cout << std::setw(outwidth) << std::setfill('-') << " " << std::endl;
}
}
if (false == alreadyexists)
{
ProtoPort lsportstruc = GetProtoAndPortFromPayloadLayer(lspayload);
std::string Updstr= "Updated mapping for " + lsportstruc.proto + '-' + std::to_string(lsportstruc.portnumin) + '-' + std::to_string(lsportstruc.portnumout) + '.';
ProlongationList.push_back({ lspacket, CreateTimestampOfNextUpdate(mappinglifetime),CreateTimepointOfNextUpdate(lspayload),lsportstruc});
}
}
}
std::this_thread::sleep_for(std::chrono::milliseconds(250)); //250ms delay to assure correct processing in series of requests
return 0;
}
}
std::cerr << "Host address didn't pass the validation check. Aborting..." << std::endl;
return 322;

}
11 changes: 11 additions & 0 deletions NetFunctions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
#include "GlobalVars.hpp"
WinDev FindAppropriateDevice(const std::vector <WinDev> inputvec, const std::string DestIp);
WinDev FindAppropriateDeviceByMac(const std::vector <WinDev> inputvec, const std::string SMAC);
ProtoPort GetProtoAndPortFromPayloadLayer(pcpp::PayloadLayer lspayload);
ProtoPort GetProtoAndPortFromPacket(pcpp::Packet packet);
void getDevices();
void sendarp(WinDev localstruct, std::string destinationv4, std::vector <uint_fast8_t>& inputvec); //[IN] WinDev, [IN] std::string IPV4, [OUT] std::vector uint_fast8_t
uint_fast8_t ComparePayloads(pcpp::PayloadLayer payload1, pcpp::PayloadLayer payload2); //0 = equal, 1 = not equal, 2 = len(p1)>len(p2), 3 = len(p1)<len(p2)
Expand All @@ -24,3 +26,12 @@ uint_fast8_t DestroySingleMapping(std::string dsDMAC, std::string dsGWMAC, std::
uint_fast8_t sendspoof(std::string lsDMAC, std::string lsGWMAC, std::string lsDADDR, WinDev Out, bool lstcp, uint_fast16_t lsinternalport, uint_fast16_t lsexternalport, std::string lsDGWAY, uint_fast16_t lsGWlistenport, uint_fast32_t mappingtime);
uint_fast8_t PrintPayloadFromPacket(pcpp::Packet packet);
uint_fast8_t RemoveCreatedMappings(std::vector <pcpp::Packet>& packetvector, WinDev lsOut);

uint_fast8_t SendPacketWrap(pcpp::Packet& lspacket, WinDev lsOut);
uint_fast64_t CreateTimestampOfNextUpdate(pcpp::Packet packet);
uint_fast64_t CreateTimestampOfNextUpdate(pcpp::PayloadLayer payload);
uint_fast64_t CreateTimestampOfNextUpdate(uint32_t lifetime);
std::chrono::time_point <std::chrono::system_clock> CreateTimepointOfNextUpdate(pcpp::PayloadLayer payload);
uint_fast8_t WatchList();


Loading

0 comments on commit d9f2970

Please sign in to comment.