16#include <boost/lexical_cast.hpp>
36constexpr size_t PacketFuzzer::BUFFER_SIZE;
37constexpr size_t PacketFuzzer::MAX_SEND_SIZE;
38constexpr long PacketFuzzer::MAX_LOOP_COUNT;
41PacketFuzzer::PacketFuzzer(uint16_t
const port,
42 string const interface,
44 : loop_max_(MAX_LOOP_COUNT), sockaddr_len_(0), sockaddr_ptr_(nullptr), sockfd_(-1) {
52 const char *loop_max_ptr(
nullptr);
54 loop_max_ptr = getenv(
"KEA_AFL_LOOP_MAX");
58 loop_max_ = boost::lexical_cast<long>(loop_max_ptr);
59 }
catch (
const boost::bad_lexical_cast&) {
61 "cannot convert loop count " << loop_max_ptr <<
" to an integer");
65 isc_throw(FuzzInitFail,
"KEA_AFL_LOOP_MAX is "
67 <<
"It must be an integer greater than zero.");
74 createAddressStructures(port, interface, io_address);
79 sockfd_ = socket(io_address.isV4() ? AF_INET : AF_INET6, SOCK_DGRAM, 0);
82 .arg(strerror(errno));
87 .arg(port).arg(loop_max_);
89 }
catch (
const FuzzInitFail& e) {
98PacketFuzzer::~PacketFuzzer() {
99 static_cast<void>(close(sockfd_));
104PacketFuzzer::createAddressStructures(uint16_t
const port,
105 string const& interface,
107 string const address(io_address.
toText());
110 if (io_address.
isV6()) {
113 memset(&servaddr6_, 0,
sizeof (servaddr6_));
115 servaddr6_.sin6_family = AF_INET6;
116 if (inet_pton(AF_INET6, address.c_str(), &servaddr6_.sin6_addr) != 1) {
118 "inet_pton() failed: can't convert " << address <<
" to an IPv6 address");
120 servaddr6_.sin6_port = htons(port);
123 servaddr6_.sin6_scope_id = if_nametoindex(interface.c_str());
124 if (servaddr6_.sin6_scope_id == 0) {
126 "error retrieving interface ID for " << interface <<
": " << strerror(errno));
129 sockaddr_ptr_ =
reinterpret_cast<sockaddr*
>(&servaddr6_);
130 sockaddr_len_ =
sizeof(servaddr6_);
132 }
else if (io_address.
isV4()) {
136 memset(&servaddr4_, 0,
sizeof(servaddr4_));
138 servaddr4_.sin_family = AF_INET;
139 if (inet_pton(AF_INET, address.c_str(), &servaddr4_.sin_addr) != 1) {
141 "inet_pton() failed: can't convert " << address <<
" to an IPv4 address");
143 servaddr4_.sin_port = htons(port);
145 sockaddr_ptr_ =
reinterpret_cast<sockaddr*
>(&servaddr4_);
146 sockaddr_len_ =
sizeof(servaddr4_);
150 isc_throw(FuzzInitFail,
"unknown IOAddress IP version");
155PacketFuzzer::transfer()
const {
158 uint8_t buf[BUFFER_SIZE];
159 ssize_t
const length(read(0, buf,
sizeof(buf)));
161 transfer(&buf[0], length);
167PacketFuzzer::transfer(uint8_t
const*
data,
size_t size)
const {
168 char buf[BUFFER_SIZE];
169 ssize_t
const length(size);
172 memcpy(&buf[0],
data, min(BUFFER_SIZE, size));
184 size_t send_len = (size < MAX_SEND_SIZE) ? size : MAX_SEND_SIZE;
185 ssize_t sent = sendto(sockfd_, buf, send_len, 0, sockaddr_ptr_,
189 }
else if (sent != length) {
The IOAddress class represents an IP addresses (version agnostic).
std::string toText() const
Convert the address to a string.
bool isV6() const
Convenience function to check for an IPv6 address.
bool isV4() const
Convenience function to check for an IPv4 address.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
#define LOG_FATAL(LOGGER, MESSAGE)
Macro to conveniently test fatal output and log it.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
const isc::log::MessageID FUZZ_INIT_FAIL
const isc::log::MessageID FUZZ_SHORT_SEND
const isc::log::MessageID FUZZ_INIT_COMPLETE
const isc::log::MessageID FUZZ_SEND_ERROR
const int FUZZ_DBG_TRACE_DETAIL
Record detailed traces.
const isc::log::MessageID FUZZ_SOCKET_CREATE_FAIL
isc::log::Logger fuzz_logger("fuzz")
Logger for the HostMgr and the code it calls.
const isc::log::MessageID FUZZ_READ_FAIL
const isc::log::MessageID FUZZ_DATA_READ
const isc::log::MessageID FUZZ_SEND
Defines the logger used by the top-level component of kea-lfc.