Skip to content

Commit

Permalink
Merge branch 'vpn'
Browse files Browse the repository at this point in the history
  • Loading branch information
folkertvanheusden committed May 30, 2024
2 parents 3be9e51 + 2643e63 commit f650d79
Show file tree
Hide file tree
Showing 22 changed files with 588 additions and 44 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ add_executable(myip
phys_sctp_udp.cpp
phys_slip.cpp
phys_tap.cpp
phys_vpn_insertion_point.cpp
proc.cpp
router.cpp
sctp.cpp
Expand All @@ -83,6 +84,7 @@ add_executable(myip
udp.cpp
utils.cpp
vnc.cpp
vpn.cpp
)

add_executable(myiptop
Expand Down
28 changes: 26 additions & 2 deletions address_cache.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// (C) 2020-2022 by folkert van heusden <[email protected]>, released under Apache License v2.0
// (C) 2020-2024 by folkert van heusden <[email protected]>, released under Apache License v2.0
#include <assert.h>
#include <chrono>
#include <string.h>
Expand All @@ -9,6 +9,10 @@
#include "time.h"


std::shared_mutex address_cache::cache_lock;
std::map<any_addr, address_cache::address_entry_t> address_cache::cache;
std::map<any_addr, phys *> address_cache::mac_cache;

address_cache::address_cache(stats *const s)
{
// 1.3.6.1.4.1.57850.1.7: address cache
Expand Down Expand Up @@ -47,6 +51,11 @@ void address_cache::update_cache(const any_addr & mac, const any_addr & ip, phys
it->second = { static_entry ? 0 : get_us(), mac, interface };
stats_inc_counter(address_cache_update);
}

auto it_mac = mac_cache.find(mac);

if (it_mac == mac_cache.end()) // TODO cleanup, like regular cache
mac_cache.insert({ mac, interface });
}

void address_cache::add_static_entry(phys *const interface, const any_addr & mac, const any_addr & ip)
Expand Down Expand Up @@ -76,6 +85,21 @@ std::pair<phys *, any_addr *> address_cache::query_cache(const any_addr & ip, co
return { it->second.interface, new any_addr(it->second.addr) };
}

phys * address_cache::query_mac_cache(const any_addr & mac)
{
const std::shared_lock<std::shared_mutex> lock(cache_lock);

stats_inc_counter(address_cache_req);

auto it = mac_cache.find(mac);
if (it == mac_cache.end()) {
DOLOG(ll_warning, "address_cache: MAC %s is not in the cache\n", mac.to_str().c_str());
return nullptr;
}

return it->second;
}

void address_cache::cache_cleaner()
{
set_thread_name("myip-acc");
Expand Down Expand Up @@ -115,5 +139,5 @@ void address_cache::dump_cache()
const std::shared_lock<std::shared_mutex> lock(cache_lock);

for(auto & e : cache)
DOLOG(ll_debug, "address_cache: %ld %s %s\n", e.second.ts, e.second.addr.to_str().c_str(), e.second.interface->to_str().c_str());
DOLOG(ll_debug, "address_cache: %s (%ld) %s %s\n", e.first.to_str().c_str(), e.second.ts, e.second.addr.to_str().c_str(), e.second.interface->to_str().c_str());
}
20 changes: 11 additions & 9 deletions address_cache.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// (C) 2020-2022 by folkert van heusden <[email protected]>, released under Apache License v2.0
// (C) 2020-2024 by folkert van heusden <[email protected]>, released under Apache License v2.0
#pragma once

#include <atomic>
Expand All @@ -11,17 +11,18 @@
#include "time.h"


typedef struct {
uint64_t ts;
any_addr addr;
phys *interface;
} address_entry_t;

class address_cache
{
protected:
std::shared_mutex cache_lock;
std::map<any_addr, address_entry_t> cache;
typedef struct {
uint64_t ts;
any_addr addr;
phys *interface;
} address_entry_t;

static std::shared_mutex cache_lock;
static std::map<any_addr, address_entry_t> cache;
static std::map<any_addr, phys *> mac_cache;

interruptable_sleep cleaner_stop;
std::thread *cleaner_th { nullptr };
Expand All @@ -41,6 +42,7 @@ class address_cache
void add_static_entry(phys *const interface, const any_addr & mac, const any_addr & ip);

virtual std::pair<phys *, any_addr *> query_cache(const any_addr & ip, const bool static_entry = false);
virtual phys * query_mac_cache(const any_addr & mac);

void dump_cache();
};
5 changes: 5 additions & 0 deletions hash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ std::string md5hex(const std::string & in)
return rc;
}

void md5bin(const uint8_t *const in, const size_t len, uint8_t *const h_out)
{
MD5(in, len, h_out);
}

uint64_t MurmurHash64A(const void *const key, const int len, const uint64_t seed)
{
const uint64_t m = 0xc6a4a7935bd1e995LLU;
Expand Down
4 changes: 3 additions & 1 deletion hash.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@

#include <stdint.h>
#include <string>
#include <openssl/md5.h>


uint64_t MurmurHash64A(const void *const key, const int len, const uint64_t seed);

void md5bin(const uint8_t *const in, const size_t len, uint8_t *const h_out);
std::string md5hex(const std::string & in);

uint32_t crc32(const uint8_t *const data, const size_t n_data, const uint32_t polynomial);
3 changes: 2 additions & 1 deletion icmp4.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// (C) 2020-2022 by folkert van heusden <[email protected]>, released under Apache License v2.0
// (C) 2020-2024 by folkert van heusden <[email protected]>, released under Apache License v2.0
#include <chrono>
#include <bsd/sys/time.h>

#include "icmp4.h"
#include "ipv4.h"
Expand Down
17 changes: 11 additions & 6 deletions mac_resolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,29 +77,29 @@ void mac_resolver::dump_work() const
DOLOG(ll_debug, "mac_resolver::dump: --- FIN ---\n");
}

std::optional<any_addr> mac_resolver::get_mac(phys *const interface, const any_addr & ip)
std::optional<std::pair<phys*, any_addr> > mac_resolver::get_mac(phys *const interface, const any_addr & ip)
{
DOLOG(ll_debug, "mac_resolver::get_mac: resolving %s via %s\n", ip.to_str().c_str(), interface->to_str().c_str());
DOLOG(ll_debug, "mac_resolver::get_mac: resolving %s\n", ip.to_str().c_str());

auto phys_family = interface->get_phys_type();

auto special_ip_addresses_mac = check_special_ip_addresses(ip, phys_family);
if (special_ip_addresses_mac.has_value()) {
DOLOG(ll_debug, "mac_resolver::get_mac: %s is special\n", ip.to_str().c_str());

return special_ip_addresses_mac;
return { { interface, special_ip_addresses_mac.value() } };
}

auto cache_result = query_cache(ip);

if (cache_result.first == interface) {
if (cache_result.first != nullptr) {
any_addr rc = *cache_result.second;

DOLOG(ll_debug, "mac_resolver::get_mac: %s is at %s\n", ip.to_str().c_str(), rc.to_str().c_str());

delete cache_result.second;

return rc;
return { { cache_result.first, rc } };
}

if (!send_request(ip, phys_family)) {
Expand Down Expand Up @@ -141,7 +141,7 @@ std::optional<any_addr> mac_resolver::get_mac(phys *const interface, const any_a
DOLOG(ll_debug, "mac_resolver: no MAC found for %s\n", ip.to_str().c_str());
}

return result;
return { { interface, result.value() } };
}

if (repeated == false && get_ms() - start_ts >= 500) {
Expand All @@ -159,3 +159,8 @@ std::optional<any_addr> mac_resolver::get_mac(phys *const interface, const any_a

return { };
}

std::optional<phys *> mac_resolver::get_phys_by_mac(const any_addr & mac)
{
return query_mac_cache(mac);
}
3 changes: 2 additions & 1 deletion mac_resolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ class mac_resolver : public address_cache, public network_layer
mac_resolver(stats *const s, router *const r);
virtual ~mac_resolver();

std::optional<any_addr> get_mac(phys *const interface, const any_addr & ip);
std::optional<std::pair<phys*, any_addr> > get_mac(phys *const interface, const any_addr & ip);
std::optional<phys *> get_phys_by_mac(const any_addr & mac);

std::map<any_addr, std::optional<mac_resolver::mac_resolver_result> > dump_state() const;

Expand Down
57 changes: 56 additions & 1 deletion main.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// (C) 2020-2023 by folkert van heusden <[email protected]>, released under Apache License v2.0
// (C) 2020-2024 by folkert van heusden <[email protected]>, released under Apache License v2.0
#include <errno.h>
#include <getopt.h>
#include <libconfig.h++>
Expand All @@ -19,6 +19,7 @@
#include "phys_ppp.h"
#include "phys_sctp_udp.h"
#include "phys_slip.h"
#include "phys_vpn_insertion_point.h"
#include "arp.h"
#include "dns.h"
#include "graphviz.h"
Expand Down Expand Up @@ -387,6 +388,8 @@ int main(int argc, char *argv[])

std::vector<phys *> devs;

std::map<std::string, phys_vpn_insertion_point *> vpns;

for(size_t i=0; i<n_interfaces; i++) {
const libconfig::Setting &interface = interfaces[i];

Expand Down Expand Up @@ -432,6 +435,18 @@ int main(int argc, char *argv[])

//dev->start_pcap("test-prom.pcap", true, true);
}
else if (type == "vpn") {
std::string dev_name = cfg_str(interface, "dev-name", "device name", false, "eth0");

sd.register_oid(myformat("1.3.6.1.2.1.31.1.1.1.1.%zu", i + 1), dev_name); // name
sd.register_oid(myformat("1.3.6.1.2.1.2.2.1.2.1.%zu", i + 1), "MyIP Ethernet device"); // description
sd.register_oid(myformat("1.3.6.1.2.1.17.1.4.1.%zu", i + 1), snmp_integer::si_integer, 1); // device is up (1)

auto vpn_dev = new phys_vpn_insertion_point(i + 1, &s, dev_name, r, my_mac);
dev = vpn_dev;

vpns.insert({ dev_name, vpn_dev });
}
else if (type == "kiss") {
std::string descr = cfg_str(interface, "descriptor", "pty-master:dev-file, pty-client:dev-file, tty:dev-file:baudrate, tcp-client:host:port, tcp-server:listen-addr:port", false, "");

Expand Down Expand Up @@ -894,6 +909,46 @@ int main(int argc, char *argv[])
// just fine
}

// VPN
try {
const libconfig::Setting & s_vpn = root.lookup("vpn");

std::string my_ip_str = cfg_str(s_vpn, "my-ip", "my IP (external for tunnel)", false, "");
any_addr my_ip = parse_address(my_ip_str, 4, ".", 10);

int my_port = cfg_int(s_vpn, "my-port", "udp port to listen on", false, 4000);

std::string peer_ip_str = cfg_str(s_vpn, "peer-ip", "peer IP", false, "");
any_addr peer_ip = parse_address(peer_ip_str, 4, ".", 10);

int peer_port = cfg_int(s_vpn, "peer-port", "peer port", false, 4000);

std::string psk = cfg_str(s_vpn, "key", "PSK (ascii)", false, "");

for(auto & dev : vpns) {
ipv4 *i4 = dynamic_cast<ipv4 *>(dev.second->get_protocol(0x0800));
if (!i4)
continue;

udp *const u = dynamic_cast<udp *>(i4->get_transport_layer(0x11));
if (!u)
continue;

vpn *v = new vpn(dev.second, &s, u, my_ip, my_port, peer_ip, peer_port, psk);
dev.second->configure_endpoint(v);

u->add_handler(my_port, std::bind(&vpn::input, v, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6), nullptr);

std::string my_ip = i4->get_addr().to_str();
g->add_connection(g->add_node("VPN " + my_ip, "VPN " + peer_ip_str), my_ip);

applications.push_back(v);
}
}
catch(const libconfig::SettingNotFoundException &nfex) {
// just fine
}

// HTTP
try {
const libconfig::Setting & s_http = root.lookup("http");
Expand Down
10 changes: 10 additions & 0 deletions net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,13 @@ bool check_subnet(const any_addr & addr, const any_addr & network, const uint8_t

return true;
}

any_addr gen_opponent_mac(const any_addr & my_mac)
{
uint8_t src_mac_bin[6] { 0 };

for(int i=0; i<6; i++)
src_mac_bin[i] = my_mac[i] ^ ((i & 1) ? 0x55 : 0xaa);

return any_addr(any_addr::mac, src_mac_bin);
}
2 changes: 2 additions & 0 deletions net.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@ std::optional<std::string> get_host_as_text(struct sockaddr *const a);

bool check_subnet(const any_addr & addr, const any_addr & network, const int cidr);
bool check_subnet(const any_addr & addr, const any_addr & network, const uint8_t netmask[4]);

any_addr gen_opponent_mac(const any_addr & my_mac);
10 changes: 0 additions & 10 deletions phys_gen_ppp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,6 @@
#include "utils.h"


any_addr gen_opponent_mac(const any_addr & my_mac)
{
uint8_t src_mac_bin[6] { 0 };

for(int i=0; i<6; i++)
src_mac_bin[i] = my_mac[i] ^ ((i & 1) ? 0x55 : 0xaa);

return any_addr(any_addr::mac, src_mac_bin);
}

phys_gen_ppp::phys_gen_ppp(const size_t dev_index, stats *const s, const std::string & name, const any_addr & my_mac, const any_addr & opponent_address, router *const r) :
phys(dev_index, s, "ppp-" + name, r),
my_mac(my_mac),
Expand Down
2 changes: 1 addition & 1 deletion phys_promiscuous.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ void phys_promiscuous::operator()()
continue;
}

if (process_ethernet_frame(ts, std::vector<uint8_t>(buffer, buffer + size), &prot_map, r, this))
if (process_ethernet_frame(ts, std::vector<uint8_t>(buffer, buffer + size), &prot_map, r, this) == false)
CDOLOG(ll_info, "[prom]", "failed processing Ethernet frame\n");
}

Expand Down
2 changes: 1 addition & 1 deletion phys_tap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ void phys_tap::operator()()
continue;
}

if (process_ethernet_frame(ts, std::vector<uint8_t>(buffer, buffer + size), &prot_map, r, this))
if (process_ethernet_frame(ts, std::vector<uint8_t>(buffer, buffer + size), &prot_map, r, this) == false)
CDOLOG(ll_info, "[tap]", "failed processing Ethernet frame\n");
}

Expand Down
Loading

0 comments on commit f650d79

Please sign in to comment.