-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
963 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# Copyright 2021 Larthia, University of Pisa. All rights reserved. | ||
# Use of this source code is governed by a BSD-style | ||
# license that can be found in the LICENSE file. | ||
|
||
cmake_minimum_required(VERSION 3.10) | ||
|
||
project (nethuns-gen) | ||
|
||
include(/usr/local/share/nethuns/Nethuns.cmake) | ||
|
||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) | ||
|
||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-aliasing -fomit-frame-pointer -fno-stack-protector -Wall -Wextra -Wno-unused-local-typedef -std=c++20 -pipe") | ||
|
||
# | ||
# Compiler options... | ||
# | ||
|
||
include_directories(${NETHUNS_INCLUDE_DIRS} . ../src) | ||
|
||
link_directories(/usr/local/lib) | ||
|
||
add_executable(nethuns-gen src/main.cpp | ||
src/options.cpp | ||
src/generator.cpp | ||
src/packets.cpp) | ||
|
||
target_link_libraries(nethuns-gen ${NETHUNS_LIBRARY_DIRS} -pthread) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
#pragma once | ||
|
||
#include <pthread.h> | ||
#include <sched.h> | ||
|
||
#ifdef __APPLE__ | ||
#include <sys/types.h> // this header cannot be included in C++ apps | ||
#include <sys/sysctl.h> | ||
#include <mach/mach_init.h> | ||
#include <mach/thread_act.h> | ||
#endif | ||
|
||
#include <stdexcept> | ||
|
||
namespace this_thread { | ||
|
||
#if defined (__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) | ||
static inline void | ||
affinity(int core) | ||
{ | ||
cpu_set_t cpuset; | ||
CPU_ZERO(&cpuset); CPU_SET(core, &cpuset); | ||
|
||
pthread_t pth = pthread_self(); | ||
if ( ::pthread_setaffinity_np(pth, sizeof(cpuset), &cpuset) != 0) | ||
throw std::runtime_error("this_thread::affinity: pthread_setaffinity_np error on core " + std::to_string(core)); | ||
} | ||
|
||
#elif defined(__APPLE__) | ||
|
||
[[maybe_unused]] static inline void | ||
affinity(int core) | ||
{ | ||
thread_port_t mach_thread; | ||
thread_affinity_policy_data_t policy = { core }; | ||
mach_thread = pthread_mach_thread_np(pthread_self()); | ||
if (thread_policy_set(mach_thread, THREAD_AFFINITY_POLICY, (thread_policy_t)&policy, 1) != 0) | ||
throw std::runtime_error("this_thread::affinity: thread_policy_set"); | ||
|
||
policy.affinity_tag = -1; | ||
|
||
mach_msg_type_number_t policy_count = THREAD_AFFINITY_POLICY_COUNT; | ||
boolean_t get_default = false; | ||
|
||
if (thread_policy_get(mach_thread, THREAD_AFFINITY_POLICY, (thread_policy_t)&policy, &policy_count, &get_default) != 0) | ||
throw std::runtime_error("this_thread::affinity: thread_policy_get"); | ||
|
||
if (static_cast<int>(policy.affinity_tag) != core) | ||
throw std::runtime_error("this_thread::affinity: couldn't set thread affinity"); | ||
} | ||
|
||
#else | ||
|
||
static inline void | ||
affinity(int core) | ||
{ | ||
throw std::runtime_error("this_thread::affinity: not supported on this platform"); | ||
} | ||
|
||
#endif | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
#pragma once | ||
|
||
#include <nethuns/nethuns.h> | ||
|
||
#include <cstddef> | ||
#include <string> | ||
#include <limits> | ||
#include <vector> | ||
#include <filesystem> | ||
#include <optional> | ||
#include <atomic> | ||
|
||
#include "hdr/netaddr.hpp" | ||
|
||
struct generator | ||
{ | ||
std::string source; | ||
std::string dev; | ||
std::optional<int> cpu = std::nullopt; | ||
|
||
int amp = 1; | ||
int speed = 1; | ||
|
||
std::size_t max_packets = std::numeric_limits<size_t>::max(); | ||
std::size_t pkt_rate = std::numeric_limits<size_t>::max(); | ||
std::size_t loops = std::numeric_limits<size_t>::max(); | ||
std::optional<uint16_t> pktlen = std::nullopt; | ||
|
||
std::optional<netaddr> randomize_src_ip = std::nullopt; | ||
std::optional<netaddr> randomize_dst_ip = std::nullopt; | ||
std::vector<netaddr> randomize_prefix; | ||
|
||
std::string mac_source; | ||
std::string mac_dest; | ||
|
||
bool mac_consistency = false; | ||
bool fix_checksums = false; | ||
bool verbose = false; | ||
|
||
bool is_pcap_file() const { | ||
std::filesystem::path p(source); | ||
return p.extension() == ".pcap" || p.extension() == ".pcapng"; | ||
} | ||
|
||
bool has_rate_limiter() const { | ||
return pkt_rate != std::numeric_limits<size_t>::max(); | ||
} | ||
|
||
bool has_speed_control() const { | ||
return speed > 0; | ||
} | ||
|
||
bool has_randomizer() const { | ||
return randomize_src_ip || randomize_dst_ip || !randomize_prefix.empty(); | ||
} | ||
}; | ||
|
||
struct generator_stats | ||
{ | ||
std::atomic_size_t packets = 0; | ||
std::atomic_size_t bytes = 0; | ||
std::atomic_size_t errors = 0; | ||
std::atomic_size_t discarded = 0; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
#pragma once | ||
|
||
#include <nethuns/nethuns.h> | ||
|
||
#include <string> | ||
|
||
struct netaddr | ||
{ | ||
uint32_t addr; | ||
uint32_t mask; | ||
|
||
netaddr() | ||
: addr(0) | ||
, mask(0) | ||
{} | ||
|
||
netaddr(const char *str) { | ||
auto pos = std::string{str}.find('/'); | ||
if (pos == std::string::npos) { | ||
throw std::runtime_error("invalid prefix"); | ||
} | ||
auto addr_str = std::string{str}.substr(0, pos); | ||
auto prefix_str = std::string{str}.substr(pos + 1); | ||
|
||
addr = inet_addr(addr_str.c_str()); | ||
mask = htonl(~((1ul << (32 - std::stoi(prefix_str))) - 1)); | ||
} | ||
|
||
auto to_string() const -> std::string { | ||
char addr_buf[INET_ADDRSTRLEN]; | ||
inet_ntop(AF_INET, &addr, addr_buf, INET_ADDRSTRLEN); | ||
|
||
char mask_buf[INET_ADDRSTRLEN]; | ||
inet_ntop(AF_INET, &mask, mask_buf, INET_ADDRSTRLEN); | ||
|
||
return std::string{addr_buf} + "/" + std::string{mask_buf}; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
#pragma once | ||
#include <vector> | ||
|
||
#include "hdr/generator.hpp" | ||
|
||
struct options { | ||
std::vector<generator> generators; | ||
}; | ||
|
||
constexpr unsigned int bitfield(bool first) { | ||
return (first ? 1u : 0u); | ||
} | ||
|
||
template <typename ...Bools> | ||
constexpr unsigned int bitfield(bool first, Bools... rest) { | ||
return (first ? 1u : 0u) | bitfield(rest...) << 1; | ||
} | ||
|
||
void validate_options(const options& opt); | ||
|
||
options | ||
parse_opt(int argc, char **argv); | ||
|
||
int | ||
run(const options& opt); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
#pragma once | ||
|
||
#include <memory> | ||
#include <cstdint> | ||
#include <string> | ||
#include <optional> | ||
#include <map> | ||
|
||
struct packet | ||
{ | ||
std::shared_ptr<uint8_t[]> data_; | ||
std::size_t len_; | ||
|
||
template <std::size_t N> | ||
static inline auto from_hex_stream(const char (&str)[N]) -> packet { | ||
auto pkt = std::make_shared<uint8_t[]>(N/2); | ||
for (std::size_t i = 0; i < N/2; ++i) { | ||
pkt[i] = std::stoi(std::string(str + i*2, 2), nullptr, 16); | ||
} | ||
return { .data_ = pkt, .len_ = N/2 }; | ||
} | ||
|
||
template <std::size_t N> | ||
static inline auto from_c_string(const char (&str)[N]) -> packet { | ||
auto pkt = std::make_shared<uint8_t[]>(N); | ||
memcpy(pkt.get(), str, N); | ||
return { .data_ = pkt, .len_ = N }; | ||
} | ||
|
||
static auto builder(const std::string &name, std::optional<uint16_t> len) -> packet | ||
{ | ||
auto it = catalog_.find(name); | ||
if (it == catalog_.end()) { | ||
throw std::runtime_error("packet '" + name + "'not found!"); | ||
} | ||
|
||
return it->second(len); | ||
} | ||
|
||
void resize(uint16_t size) { | ||
if (size < len_) { | ||
len_ = size; | ||
} else { | ||
auto new_data = std::make_shared<uint8_t[]>(size); | ||
memcpy(new_data.get(), data_.get(), len_); | ||
bzero(new_data.get() + len_, size - len_); | ||
data_ = new_data; | ||
len_ = size; | ||
} | ||
} | ||
|
||
private: | ||
static std::map<std::string, std::function<packet(std::optional<uint16_t>)>> catalog_; | ||
|
||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
#pragma once | ||
#include <chrono> | ||
|
||
template <int MAX_PERIOD = 16> | ||
struct rate_limiter | ||
{ | ||
int period_ = 0; | ||
|
||
template <typename TimePoint> | ||
auto wait(TimePoint deadline, size_t pktnum) -> void | ||
{ | ||
if ((pktnum & ((1 << period_) - 1)) == 0) { | ||
auto spinning = false; | ||
while (std::chrono::steady_clock::now() < deadline) | ||
{ | ||
spinning = true; | ||
} | ||
|
||
if (spinning) { | ||
if (period_ > 0) { | ||
--period_; | ||
} | ||
} else { | ||
if (period_ < MAX_PERIOD) { | ||
++period_; | ||
} | ||
} | ||
} | ||
} | ||
}; |
Oops, something went wrong.