12 #error To use American Fuzzy Lop you have to set CXX to afl-clang-fast++
19 #include <boost/lexical_cast.hpp>
36 constexpr
size_t Fuzz::BUFFER_SIZE;
37 constexpr
size_t Fuzz::MAX_SEND_SIZE;
38 constexpr
long Fuzz::MAX_LOOP_COUNT;
41 Fuzz::Fuzz(
int ipversion, uint16_t port) :
42 loop_max_(MAX_LOOP_COUNT), sockaddr_len_(0), sockaddr_ptr_(nullptr),
52 const char*
interface = getenv("KEA_AFL_INTERFACE");
54 isc_throw(FuzzInitFail,
"no fuzzing interface has been set");
58 const char* address = getenv(
"KEA_AFL_ADDRESS");
60 isc_throw(FuzzInitFail,
"no fuzzing address has been set");
66 const char *loop_max_ptr = getenv(
"KEA_AFL_LOOP_MAX");
67 if (loop_max_ptr != 0) {
69 loop_max_ = boost::lexical_cast<
long>(loop_max_ptr);
70 }
catch (
const boost::bad_lexical_cast&) {
71 reason <<
"cannot convert loop count " << loop_max_ptr
77 reason <<
"KEA_AFL_LOOP_MAX is " << loop_max_ <<
". "
78 <<
"It must be an integer greater than zero.";
84 createAddressStructures(ipversion, interface, address, port);
89 sockfd_ = socket((ipversion == 4) ? AF_INET : AF_INET6, SOCK_DGRAM, 0);
92 .arg(strerror(errno));
97 .arg(port).arg(loop_max_);
99 }
catch (
const FuzzInitFail& e) {
109 static_cast<void>(close(sockfd_));
114 Fuzz::createAddressStructures(
int ipversion,
const char* interface,
115 const char* address, uint16_t port) {
119 if ((ipversion == 6) && (strstr(address,
":") != NULL)) {
122 memset(&servaddr6_, 0,
sizeof (servaddr6_));
124 servaddr6_.sin6_family = AF_INET6;
125 if (inet_pton(AF_INET6, address, &servaddr6_.sin6_addr) != 1) {
126 reason <<
"inet_pton() failed: can't convert "
127 << address <<
" to an IPv6 address" << endl;
130 servaddr6_.sin6_port = htons(port);
133 servaddr6_.sin6_scope_id = if_nametoindex(interface);
134 if (servaddr6_.sin6_scope_id == 0) {
135 reason <<
"error retrieving interface ID for "
136 <<
interface << ": " << strerror(errno);
137 isc_throw(FuzzInitFail, reason.str());
140 sockaddr_ptr_ = reinterpret_cast<sockaddr*>(&servaddr6_);
141 sockaddr_len_ = sizeof(servaddr6_);
143 } else if ((ipversion == 4) && (strstr(address, ".") != NULL)) {
147 memset(&servaddr4_, 0, sizeof(servaddr4_));
149 servaddr4_.sin_family = AF_INET;
150 if (inet_pton(AF_INET, address, &servaddr4_.sin_addr) != 1) {
151 reason << "inet_pton() failed: can't convert "
152 << address << " to an IPv6 address" << endl;
153 isc_throw(FuzzInitFail, reason.str());
155 servaddr4_.sin_port = htons(port);
157 sockaddr_ptr_ = reinterpret_cast<sockaddr*>(&servaddr4_);
158 sockaddr_len_ = sizeof(servaddr4_);
161 reason << "Expected IP version (" << ipversion << ") is not "
162 << "4 or 6, or the given address " << address << " does not "
163 << "match the IP version expected";
164 isc_throw(FuzzInitFail, reason.str());
173 Fuzz::transfer(void) const {
177 char buf[BUFFER_SIZE];
178 ssize_t length = read(0, buf, sizeof(buf));
183 LOG_DEBUG(fuzz_logger, FUZZ_DBG_TRACE_DETAIL, FUZZ_DATA_READ).arg(length);
189 size_t send_len = (length < MAX_SEND_SIZE) ? length : MAX_SEND_SIZE;
190 ssize_t sent = sendto(sockfd_, buf, send_len, 0, sockaddr_ptr_,
193 LOG_DEBUG(fuzz_logger, FUZZ_DBG_TRACE_DETAIL, FUZZ_SEND).arg(sent);
194 } else if (sent != length) {
195 LOG_WARN(fuzz_logger, FUZZ_SHORT_SEND).arg(length).arg(sent);
197 LOG_ERROR(fuzz_logger, FUZZ_SEND_ERROR).arg(strerror(errno));
203 LOG_ERROR(fuzz_logger, FUZZ_READ_FAIL).arg(strerror(errnum));
const isc::log::MessageID FUZZ_INIT_COMPLETE
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
const isc::log::MessageID FUZZ_INIT_FAIL
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
const isc::log::MessageID FUZZ_SOCKET_CREATE_FAIL
Defines the logger used by the top-level component of kea-dhcp-ddns.
isc::log::Logger fuzz_logger("fuzz")
Logger for the HostMgr and the code it calls.
#define LOG_FATAL(LOGGER, MESSAGE)
Macro to conveniently test fatal output and log it.