BIND 10 trac703, updated. 3999bb246ea782310611471d3ff28cdd85bf4a0d [trac703] Added ability to set section count fields
BIND 10 source code commits
bind10-changes at lists.isc.org
Tue Apr 12 18:00:08 UTC 2011
The branch, trac703 has been updated
via 3999bb246ea782310611471d3ff28cdd85bf4a0d (commit)
via 10b62db1ae170eed2fb897335037d50c399b37e9 (commit)
via f155c3edec68515cccb5f5c4da611af08770ae4e (commit)
via 4e9bf13057eba0ccff7052f1859ab49b0a27c777 (commit)
from 6ce4dde0aeb2a0aa3457f0037be5d549b3e9b966 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 3999bb246ea782310611471d3ff28cdd85bf4a0d
Author: Stephen Morris <stephen at isc.org>
Date: Tue Apr 12 18:28:49 2011 +0100
[trac703] Added ability to set section count fields
commit 10b62db1ae170eed2fb897335037d50c399b37e9
Author: Stephen Morris <stephen at isc.org>
Date: Tue Apr 12 17:27:41 2011 +0100
[trac703] Section count modification now added
commit f155c3edec68515cccb5f5c4da611af08770ae4e
Author: Stephen Morris <stephen at isc.org>
Date: Tue Apr 12 15:15:02 2011 +0100
[trac703] Integrated new command processing into the program
commit 4e9bf13057eba0ccff7052f1859ab49b0a27c777
Author: Stephen Morris <stephen at isc.org>
Date: Tue Apr 12 12:33:22 2011 +0100
[trac703] Add options information class
As part of work tackling the review, add a class giving information
about some of the command-line options.
-----------------------------------------------------------------------
Summary of changes:
tests/tools/badpacket/Makefile.am | 1 +
tests/tools/badpacket/badpacket.cc | 19 +-
tests/tools/badpacket/command_options.cc | 153 ++++--
tests/tools/badpacket/command_options.h | 89 +---
tests/tools/badpacket/header_flags.h | 192 +------
tests/tools/badpacket/option_info.cc | 103 ++++
tests/tools/badpacket/option_info.h | 163 ++++++
tests/tools/badpacket/scan.cc | 150 ++++--
tests/tools/badpacket/scan.h | 30 +
tests/tools/badpacket/tests/Makefile.am | 2 +
.../badpacket/tests/command_options_unittest.cc | 566 +++++++++-----------
.../tools/badpacket/tests/header_flags_unittest.cc | 299 ++++++-----
.../tools/badpacket/tests/option_info_unittest.cc | 154 ++++++
13 files changed, 1128 insertions(+), 793 deletions(-)
create mode 100644 tests/tools/badpacket/option_info.cc
create mode 100644 tests/tools/badpacket/option_info.h
create mode 100644 tests/tools/badpacket/tests/option_info_unittest.cc
-----------------------------------------------------------------------
diff --git a/tests/tools/badpacket/Makefile.am b/tests/tools/badpacket/Makefile.am
index 90d8871..8d7b0b3 100644
--- a/tests/tools/badpacket/Makefile.am
+++ b/tests/tools/badpacket/Makefile.am
@@ -16,6 +16,7 @@ noinst_PROGRAMS = badpacket
badpacket_SOURCES = badpacket.cc
badpacket_SOURCES += command_options.cc command_options.h
badpacket_SOURCES += header_flags.h
+badpacket_SOURCES += option_info.cc option_info.h
badpacket_SOURCES += scan.cc scan.h
badpacket_SOURCES += version.h
diff --git a/tests/tools/badpacket/badpacket.cc b/tests/tools/badpacket/badpacket.cc
index ecfdc0d..894b72f 100644
--- a/tests/tools/badpacket/badpacket.cc
+++ b/tests/tools/badpacket/badpacket.cc
@@ -13,9 +13,11 @@
// PERFORMANCE OF THIS SOFTWARE.
#include <unistd.h>
+#include <iostream>
#include <config.h>
+#include <exceptions/exceptions.h>
#include "command_options.h"
#include "scan.h"
@@ -41,12 +43,17 @@ using namespace isc::badpacket;
/// \brief Main Program
int main(int argc, char* argv[]) {
- CommandOptions command_line;
- command_line.parse(argc, argv);
-
- // Construct the scan object and perform the scan.
- Scan scanner;
- scanner.scan(command_line);
+ try {
+ CommandOptions options;
+ options.parse(argc, argv);
+
+ // Construct the scan object and perform the scan.
+ Scan scanner;
+ scanner.scan(options);
+ } catch (isc::Exception& e) {
+ std::cout << "ERROR: " << e.what() << "\n";
+ return 1;
+ }
return 0;
}
diff --git a/tests/tools/badpacket/command_options.cc b/tests/tools/badpacket/command_options.cc
index f649074..8eda345 100644
--- a/tests/tools/badpacket/command_options.cc
+++ b/tests/tools/badpacket/command_options.cc
@@ -24,11 +24,11 @@
#include "log/strutil.h"
#include "command_options.h"
+#include "option_info.h"
#include "version.h"
using namespace std;
using namespace isc;
-namespace po = boost::program_options;
namespace isc {
namespace badpacket {
@@ -43,12 +43,13 @@ CommandOptions::parse(int argc, char* const argv[]) {
// structure (as opposed to just putting a string literal there) is
// occasioned by a version of solaris which declares the first field
// as "char*" (instead of the correct "const char*").
-
char HELP[] = {"help"};
char VERSION[] = {"version"};
char ADDRESS[] = {"address"};
char PORT[] = {"port"};
char TIMEOUT[] = {"timeout"};
+
+ // Settings for options in the flags field
char QR[] = {"qr"};
char OP[] = {"op"};
char AA[] = {"aa"};
@@ -60,6 +61,12 @@ CommandOptions::parse(int argc, char* const argv[]) {
char CD[] = {"cd"};
char RC[] = {"rc"};
+ // Settings for the count fields
+ char QC[] = {"qc"};
+ char AC[] = {"ac"};
+ char UC[] = {"uc"};
+ char DC[] = {"dc"};
+
const struct option longopts[] = {
{HELP, 0, NULL, 'h'}, // Print usage message and exit
{VERSION, 0, NULL, 'v'}, // Print program version and exit
@@ -72,13 +79,17 @@ CommandOptions::parse(int argc, char* const argv[]) {
{TC, 1, NULL, 'T'}, // Truncated
{RD, 1, NULL, 'D'}, // recursion Desired
{RA, 1, NULL, 'R'}, // Recursion available
- {Z, 1, NULL, 'Z'}, // Must be Zero (reserved bit)
+ {Z, 1, NULL, 'Z'}, // must be Zero (reserved bit)
{AD, 1, NULL, 'U'}, // aUthenticated data
{CD, 1, NULL, 'C'}, // Checking disabled
{RC, 1, NULL, 'E'}, // rEsult code
+ {QC, 1, NULL, 'Y'}, // querY section count
+ {AC, 1, NULL, 'W'}, // ansWer section count
+ {UC, 1, NULL, 'H'}, // autHority section count
+ {DC, 1, NULL, 'I'}, // addItional section count
{NULL, 0, NULL, 0 }
};
- const char* shortopts = "hva:p:t:Q:O:A:T:D:R:Z:U:C:E:";
+ const char* shortopts = "hva:p:t:Q:O:A:T:D:R:Z:U:C:E:Y:W:H:I:";
// Set variables to defaults before parsing
@@ -110,47 +121,25 @@ CommandOptions::parse(int argc, char* const argv[]) {
break;
case 'Q': // --qr (query/response)
- processOptionValue(optarg, values_.qr, 0, 1);
- break;
-
case 'O': // --op (operation code)
- processOptionValue(optarg, values_.op, 0, 15);
- break;
-
case 'A': // --aa (authoritative answer)
- processOptionValue(optarg, values_.aa, 0, 1);
- break;
-
case 'T': // --tc (truncated)
- processOptionValue(optarg, values_.tc, 0, 1);
- break;
-
case 'D': // --rd (recursion desired)
- processOptionValue(optarg, values_.rd, 0, 1);
- break;
-
case 'R': // --ra (recursion available)
- processOptionValue(optarg, values_.ra, 0, 1);
- break;
-
case 'Z': // --z (zero: reserved bit)
- processOptionValue(optarg, values_.z, 0, 1);
- break;
-
case 'U': // --ad (authenticated data)
- processOptionValue(optarg, values_.ad, 0, 1);
- break;
-
case 'C': // --cd (checking disabled)
- processOptionValue(optarg, values_.cd, 0, 1);
- break;
-
case 'E': // --rc (result code)
- processOptionValue(optarg, values_.rc, 0, 15);
+ case 'Y': // --qc (query count)
+ case 'W': // --ac (answer count)
+ case 'H': // --uc (authority count)
+ case 'I': // --dc (additional count)
+ processOptionValue(c, optarg);
break;
default:
- isc_throw(isc::InvalidParameter, "Unknown switch");
+ isc_throw(isc::InvalidParameter,
+ "unknown option '" << argv[optind] << "' given on the command line");
}
}
@@ -191,15 +180,28 @@ CommandOptions::usage() {
"--port <port> [-p] Port to which to send query. Defaults to 53.\n"
"--timeout <value> [-t] Timeout value for the query. Specified in ms, it\n"
" defaults to 500ms.\n"
- "--qr <range> [-Q] Set query/response bit. Valid <range> is 0-1\n"
- "--op <range> [-O] Set opcode. Valid <range> is 0-15\n"
- "--aa <range> [-A] Set authoritative answer bit. Valid <range> is 0-1\n"
- "--tc <range> [-T] Set truncated bit. Valid <range> is 0-1\n"
- "--z <range> [-Z] Set zero (reserved) bit. Valid <range> is 0-1\n"
- "--ad <range> [-U] Set authentiacted data bit. Valid <range> is 0-1\n"
- "--cd <range> [-C] Set checking disabled bit. Valid <range> is 0-1\n"
+ "\n"
+ "The following options set fields in the outgoing DNS message flags word\n"
+ "\n"
+ "--qr <range> [-Q] Set query/response bit. Valid <range> is 0-1.\n"
+ "--op <range> [-O] Set opcode. Valid <range> is 0-15.\n"
+ "--aa <range> [-A] Set authoritative answer bit. Valid <range> is 0-1.\n"
+ "--tc <range> [-T] Set truncated bit. Valid <range> is 0-1.\n"
+ "--rd <range> [-T] Set recursion desired bit. Valid <range> is 0-1.\n"
+ "--ra <range> [-T] Set recursion available bit. Valid <range> is 0-1.\n"
+ "--z <range> [-Z] Set zero (reserved) bit. Valid <range> is 0-1.\n"
+ "--ad <range> [-U] Set authenticated data bit. Valid <range> is 0-1.\n"
+ "--cd <range> [-C] Set checking disabled bit. Valid <range> is 0-1.\n"
"--rc <range> [-E] Set rcode value. Valid <range> is 0-15\n"
"\n"
+ "The following options set the various section counts (independent of what is\n"
+ "actually in the section)\n"
+ "\n"
+ "--qc <range> [-Q] Set the query count. Valid range is 0-65535.\n"
+ "--ac <range> [-Q] Set the answer count. Valid range is 0-65535.\n"
+ "--uc <range> [-Q] Set the authority count. Valid range is 0-65535.\n"
+ "--dc <range> [-Q] Set the additional count. Valid range is 0-65535.\n"
+ "\n"
"query Name to query for. The query is for an 'IN' A record.\n"
" If not given, the name 'www.example.com' is used.\n"
;
@@ -213,29 +215,68 @@ CommandOptions::version() {
// Process single flag
void
-CommandOptions::processOptionValue(const char* arg, uint32_t* where, uint32_t minval,
- uint32_t maxval)
-{
+CommandOptions::processOptionValue(int c, const char* value) {
+
+ // Get values for this option
+ int index = OptionInfo::getIndex(c);
+ const char* name = OptionInfo::name(index);
+ uint32_t minval = OptionInfo::minval(index);
+ uint32_t maxval = OptionInfo::maxval(index);
+
// Split the string up into one or two tokens
- vector<string> values = isc::strutil::tokens(string(arg), "-");
- if ((values.size() < 1) || (values.size() > 2)) {
- isc_throw(isc::BadValue, "command argument is '" << arg << "': it must "
- "be in the form 'int' or 'int1-int2'");
+ vector<string> tokens = isc::strutil::tokens(string(value), "-");
+ if ((tokens.size() < 1) || (tokens.size() > 2)) {
+ isc_throw(isc::BadValue, "value given for " << name << " is '" << value <<
+ "': it must be in the form 'int' or 'int1-int2'");
}
// Convert to uint32.
- uint32_t start = boost::lexical_cast<uint32_t>(values[0]);
- uint32_t end = start;
- if (values.size() == 2) {
- end = boost::lexical_cast<uint32_t>(values[1]);
+ int i = 0;
+ try {
+ do {
+ limits_[index][i] = boost::lexical_cast<uint32_t>(tokens[i]);
+ ++i;
+ } while (i < tokens.size());
+ } catch (boost::bad_lexical_cast) {
+ isc_throw(isc::BadValue, "value given for " << name << " is '" << value <<
+ "': it must be in the form 'int' or 'int1-int2'");
+ }
+
+ // Set the limits in the correct order.
+ if (tokens.size() == 1) {
+ limits_[index][1] = limits_[index][0];
+ } else if (limits_[index][0] > limits_[index][1]) {
+ swap(limits_[index][0], limits_[index][1]);
}
- if (start > end) {
- swap(start, end);
+
+ // Check that tokens lie inside the allowed ranges
+ if ((tokens.size() == 1) &&
+ ((limits_[index][0] < OptionInfo::minval(index)) || (limits_[index][0] > maxval))) {
+ isc_throw(isc::BadValue, "the value of " << limits_[index][0] <<
+ " given for " << name << " is outside the range of " <<
+ minval << " to " << maxval);
+ } else if (limits_[index][0] < minval) {
+ isc_throw(isc::BadValue, "the lower limit of " << limits_[index][0] <<
+ " given for " << name << " is below the minimum permitted"
+ " value of " << minval);
+ } else if (limits_[index][1] > maxval) {
+ isc_throw(isc::BadValue, "the upper limit of " << limits_[index][1] <<
+ " given for " << name << " is above the maximum permitted"
+ " value of " << maxval);
}
+}
+
+// Minimum and maximum value of the flag
+uint32_t
+CommandOptions::minimum(int index) const {
+ OptionInfo::checkIndex(index);
+ return (limits_[index][0]);
+}
- // Coerce values into the desired range
- where[0] = max(minval, min(start, maxval));
- where[1] = min(maxval, max(end, minval));
+uint32_t
+CommandOptions::maximum(int index) const {
+ OptionInfo::checkIndex(index);
+ return (limits_[index][1]);
}
} // namespace badpacket
diff --git a/tests/tools/badpacket/command_options.h b/tests/tools/badpacket/command_options.h
index a1132b9..06ed0ab 100644
--- a/tests/tools/badpacket/command_options.h
+++ b/tests/tools/badpacket/command_options.h
@@ -19,7 +19,7 @@
#include <stdint.h>
#include <utility>
-#include <boost/program_options.hpp>
+#include "option_info.h"
namespace isc {
namespace badpacket {
@@ -36,8 +36,8 @@ namespace badpacket {
/// - \c --option value1-value2
///
/// Either way, two values are extracted the low value and the high value (in
-/// the former case, bost are the same). The values are stored in a
-/// "FlagValues" structure, which can be returned on request.
+/// the former case, both are the same). The values are stored in an array
+/// and can be returned on request.
///
/// For simplicity, the class also takes care of the --help and --version flags,
/// each of which will cause a message to be printed to stdout and the program
@@ -46,48 +46,6 @@ namespace badpacket {
class CommandOptions {
public:
- /// \brief Flags Word Values
- ///
- /// Structure holding the values for the flag settings. Each variable in
- /// the structure corresponds to one of the fields in the flags word. The
- /// variables are two-ewlement arrays: element 0 of the array holds the low
- /// value in the range given, and element 1 the high value. If only a
- /// single value is given, both elements hold the same value.
-
- struct FlagValues {
- uint32_t qr[2]; // QR bit
- uint32_t op[2]; // OPCODE field
- uint32_t aa[2]; // AA bit
- uint32_t tc[2]; // TC bit
- uint32_t rd[2]; // RD bit
- uint32_t ra[2]; // RA bit
- uint32_t z[2]; // Z bit (reserved bit)
- uint32_t ad[2]; // AD bit
- uint32_t cd[2]; // CD bit
- uint32_t rc[2]; // RCODE field
-
- /// \brief Default Constructor
- ///
- /// Sets everything to zero.
- FlagValues() {
- reset();
- }
-
- /// \brief Reset All Values to Zero
- void reset() {
- qr[0] = qr[1] = 0;
- op[0] = op[1] = 0;
- aa[0] = aa[1] = 0;
- tc[0] = tc[1] = 0;
- rd[0] = rd[1] = 0;
- ra[0] = ra[1] = 0;
- z[0] = z[1] = 0;
- ad[0] = ad[1] = 0;
- cd[0] = cd[1] = 0;
- rc[0] = rc[1] = 0;
- }
- };
-
/// \brief CommandOptions Constructor
///
/// Set values to defaults.
@@ -95,15 +53,21 @@ public:
reset();
}
- /// \brief Return Flags Word Values
+ /// \brief Return minimum value for option
///
- /// Returns a copy of the flags word structure for use by the caller. This
- /// structure holds the flags field settings specified on the command line.
+ /// \param index Index of the command-line option.
///
- /// \return Copy of the values specified on the command line.
- FlagValues getFlagValues() const {
- return values_;
- }
+ /// \return uint32_t holding the minimum value given (or the default if
+ /// the option was not specified on the command line).
+ uint32_t minimum(int index) const;
+
+ /// \brief Return maximum value for option
+ ///
+ /// \param index Index of the command-line option.
+ ///
+ /// \return uint32_t holding the maximum value given (or the default if
+ /// the option was not specified on the command line).
+ uint32_t maximum(int index) const;
/// \brief Return Target Address
std::string getAddress() const {
@@ -127,11 +91,14 @@ public:
/// \brief Reset To Defaults
void reset() {
- values_.reset();
address_ = "127.0.0.1";
port_ = 53;
timeout_ = 500;
qname_ = "www.example.com";
+
+ for (int i = 0; i < OptionInfo::SIZE; ++i) {
+ limits_[i][0] = limits_[i][1] = OptionInfo::defval(i);
+ }
}
/// \brief Parse Command Line
@@ -145,10 +112,10 @@ public:
/// \param argv Argument value array passed to main().
void parse(int argc, char* const argv[]);
- /// \brief Print Usage Information
+ /// \brief Print Usage Information And Exit Program
void usage();
- /// \brief Print Version Information
+ /// \brief Print Version Information And Exit Program
void version();
// The following are protected to aid testing
@@ -160,17 +127,15 @@ protected:
/// placing it in the appropriate location. On error a BadValue exception
/// is thrown.
///
- /// \param arg flag argument read from the command line
- /// \param where Two-element uint32_t array into which the data is put
- /// \param minval Minimum allowed value
- /// \param maxval Maximum allowed value
- void processOptionValue(const char* arg, uint32_t* where, uint32_t minval,
- uint32_t maxval);
+ /// \param c Short form option character from the command line
+ /// \param value Value of the option read from the command line
+ void processOptionValue(int c, const char* value);
// Member variables
private:
- FlagValues values_; ///< Values read from command line
+ uint32_t limits_[OptionInfo::SIZE][2];
+ ///< Value of options (minimum and maximum)
std::string address_; ///< Address to where query is sent
uint16_t port_; ///< Target port
int timeout_; ///< Timeout for query
diff --git a/tests/tools/badpacket/header_flags.h b/tests/tools/badpacket/header_flags.h
index 2810356..3c84439 100644
--- a/tests/tools/badpacket/header_flags.h
+++ b/tests/tools/badpacket/header_flags.h
@@ -15,6 +15,9 @@
#ifndef __HEADER_FLAGS_H
#define __HEADER_FLAGS_H
+#include <exceptions/exceptions.h>
+#include "option_info.h"
+
namespace isc {
namespace badpacket {
@@ -26,31 +29,6 @@ namespace badpacket {
class HeaderFlags {
public:
- // The following declaration describes the various fields in the DNS
- // packet header.
- enum FieldParameter {
- QR_MASK = 0x8000, // Maskd efining the field
- QR_OFF = 15, // Offset of field in the flags word (i.e. shift
- OP_MASK = 0x7800, // ... this number of bits to the left)
- OP_OFF = 11,
- AA_MASK = 0x0400,
- AA_OFF = 10,
- TC_MASK = 0x0200,
- TC_OFF = 9,
- RD_MASK = 0x0100,
- RD_OFF = 8,
- RA_MASK = 0x0080,
- RA_OFF = 7,
- Z_MASK = 0x0040,
- Z_OFF = 6,
- AD_MASK = 0x0020,
- AD_OFF = 5,
- CD_MASK = 0x0010,
- CD_OFF = 4,
- RC_MASK = 0x000F,
- RC_OFF = 0
- };
-
/// \brief Constructor
HeaderFlags() {
reset();
@@ -76,169 +54,45 @@ public:
flags_ = value;
}
- /// \brief Get QR Bit
- uint16_t getQR() const {
- return (getField(QR_MASK, QR_OFF));
- }
-
- /// \brief Set QR Bit
- ///
- /// \param value New value of the field, which must be 0 or 1: values
- /// outside that range are coerced to the nearest boundary.
- void setQR(uint16_t value) {
- setField(value, QR_MASK, QR_OFF);
- }
-
- /// \brief Get OP Value
- uint16_t getOP() const {
- return (getField(OP_MASK, OP_OFF));
- }
-
- /// \brief Set OP Value
- ///
- /// \param value New value of the field, which must in the range 0 to 15:
- /// values outside that range are coerced to the nearest boundary.
- void setOP(uint16_t value) {
- setField(value, OP_MASK, OP_OFF);
- }
-
- /// \brief Get AA Bit
- uint16_t getAA() const {
- return (getField(AA_MASK, AA_OFF));
- }
-
- /// \brief Set AA Bit
- ///
- /// \param value New value of the field, which must be 0 or 1: values
- /// outside that range are coerced to the nearest boundary.
- void setAA(uint16_t value) {
- setField(value, AA_MASK, AA_OFF);
- }
-
- /// \brief Get TC Bit
- uint16_t getTC() const {
- return (getField(TC_MASK, TC_OFF));
- }
-
- /// \brief Set TC Bit
- ///
- /// \param value New value of the field, which must be 0 or 1: values
- /// outside that range are coerced to the nearest boundary.
- void setTC(uint16_t value) {
- setField(value, TC_MASK, TC_OFF);
- }
-
- /// \brief Get RD Bit
- uint16_t getRD() const {
- return (getField(RD_MASK, RD_OFF));
- }
-
- /// \brief Set RD Bit
- ///
- /// \param value New value of the field, which must be 0 or 1: values
- /// outside that range are coerced to the nearest boundary.
- void setRD(uint16_t value) {
- setField(value, RD_MASK, RD_OFF);
- }
-
- /// \brief Get RA Bit
- uint16_t getRA() const {
- return (getField(RA_MASK, RA_OFF));
- }
-
- /// \brief Set RA Bit
- ///
- /// \param value New value of the field, which must be 0 or 1: values
- /// outside that range are coerced to the nearest boundary.
- void setRA(uint16_t value) {
- setField(value, RA_MASK, RA_OFF);
- }
-
- /// \brief Get Z Bit
- uint16_t getZ() const {
- return (getField(Z_MASK, Z_OFF));
- }
-
- /// \brief Set Z Bit
- ///
- /// \param value New value of the field, which must be 0 or 1: values
- /// outside that range are coerced to the nearest boundary.
- void setZ(uint16_t value) {
- setField(value, Z_MASK, Z_OFF);
- }
-
- /// \brief Get AD Bit
- uint16_t getAD() const {
- return (getField(AD_MASK, AD_OFF));
- }
-
- /// \brief Set AD Bit
- ///
- /// \param value New value of the field, which must be 0 or 1: values
- /// outside that range are coerced to the nearest boundary.
- void setAD(uint16_t value) {
- setField(value, AD_MASK, AD_OFF);
- }
-
- /// \brief Get CD Bit
- uint16_t getCD() const {
- return (getField(CD_MASK, CD_OFF));
- }
-
- /// \brief Set CD Bit
- ///
- /// \param value New value of the field, which must be 0 or 1: values
- /// outside that range are coerced to the nearest boundary.
- void setCD(uint16_t value) {
- setField(value, CD_MASK, CD_OFF);
- }
-
- /// \brief Get RC Value
- uint16_t getRC() const {
- return (getField(RC_MASK, RC_OFF));
- }
-
- /// \brief Set RC Value
- ///
- /// \param value New value of the field, which must be in the range 0 to 15:
- /// values outside that range are coerced to the nearest boundary.
- void setRC(uint16_t value) {
- setField(value, RC_MASK, RC_OFF);
- }
-
-private:
-
/// \brief Get Field
///
/// Return the value of a bit field in the flags word.
///
- /// \param mask Bit mask identifying the field.
- /// \param offset Offset of the field in the flags word.
+ /// \param int Index of the bit field in the OptionInfo data structure
///
/// \return Value of the field.
- uint16_t getField(FieldParameter mask, FieldParameter offset) const {
- return ((flags_ & mask) >> offset);
+ uint16_t get(int index) const {
+ OptionInfo::checkIndex(index);
+ return ((flags_ & OptionInfo::mask(index)) >> OptionInfo::offset(index));
}
/// \brief Set Field
///
/// Sets the value of a bit field.
///
+ /// \param int Index of the bit field in the OptionInfo data structure
/// \param value Value to set. If the value is more than the field can
/// hold, it is set to the maximum.
- /// \param mask Bit mask identifying the field.
- /// \param offset Offset of the field in the flags word.
- void setField(uint16_t value, FieldParameter mask, FieldParameter offset) {
+ void set(int index, uint16_t value) {
+ // Declare an OptionInfo object for brevity
+ OptionInfo o;
+
+ // Ensure in range
+ o.checkIndex(index);
- // Ensure the value is within limits.
- uint16_t maxval = mask >> offset;
- uint16_t val = (value > maxval) ? maxval : value;
+ // Ensure the value is within limits and throw an exception if not. (This
+ // should not really be needed, as the command line parsing should have
+ // checked the limits. But be safe.)
+ if ((value < o.minval(index)) || (value > o.maxval(index))) {
+ isc_throw(isc::BadValue, "value of index " << index << " is out of range");
+ }
// Clear the field then set it with the value.
- flags_ &= ~mask;
- flags_ |= (val << offset);
+ flags_ &= ~o.mask(index);
+ flags_ |= (value << o.offset(index));
}
+private:
uint16_t flags_; ///< Variable holding field values
};
diff --git a/tests/tools/badpacket/option_info.cc b/tests/tools/badpacket/option_info.cc
new file mode 100644
index 0000000..ccb44c4
--- /dev/null
+++ b/tests/tools/badpacket/option_info.cc
@@ -0,0 +1,103 @@
+// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include "option_info.h"
+
+namespace {
+
+// Define the various options for the command switches. This includes both the
+// long form and short form of the switch. Unfortunately this means that the
+// information is duplicated here and where the long options are specified for
+// getopt_long, but this inconvenience is outweighed by the simplified command
+// processing.
+
+isc::badpacket::OptionInfo::Parameter option_information[] = {
+ {'Q', "qr", 2, 0x8000, 15, 0, 0, 1},
+ {'O', "op", 2, 0x7800, 11, 0, 0, 15},
+ {'A', "aa", 2, 0x0400, 10, 0, 0, 1},
+ {'T', "tc", 2, 0x0200, 9, 0, 0, 1},
+ {'D', "rd", 2, 0x0100, 8, 0, 0, 1},
+ {'R', "ra", 2, 0x0080, 7, 0, 0, 1},
+ {'Z', "z", 2, 0x0040, 6, 0, 0, 1},
+ {'U', "ad", 2, 0x0020, 5, 0, 0, 1},
+ {'C', "cd", 2, 0x0010, 4, 0, 0, 1},
+ {'E', "rc", 2, 0x000F, 0, 0, 0, 15},
+ {'Y', "qc", 4, 0, 0, 1, 0, 0xFFFF},
+ {'W', "ac", 6, 0, 0, 0, 0, 0xFFFF},
+ {'H', "uc", 8, 0, 0, 0, 0, 0xFFFF},
+ {'I', "dc", 10, 0, 0, 0, 0, 0xFFFF}
+};
+
+} // Anonymous namespace
+
+namespace isc {
+namespace badpacket {
+
+// Locate the index of the information in the array from the short switch.
+int
+OptionInfo::getIndex(int c) {
+ for (int i = 0; i < SIZE; ++i) {
+ if (c == option_information[i].short_form) {
+ return (i);
+ }
+ }
+ isc_throw(isc::BadValue, "unknown option: " << c);
+}
+
+// Methods to return values from the array
+
+const char*
+OptionInfo::name(int i) {
+ checkIndex(i);
+ return (option_information[i].long_form);
+}
+
+uint16_t
+OptionInfo::mask(int i) {
+ checkIndex(i);
+ return (option_information[i].mask);
+}
+
+int
+OptionInfo::word(int i) {
+ checkIndex(i);
+ return (option_information[i].word);
+}
+
+int
+OptionInfo::offset(int i) {
+ checkIndex(i);
+ return (option_information[i].offset);
+}
+
+uint32_t
+OptionInfo::minval(int i) {
+ checkIndex(i);
+ return (option_information[i].minval);
+}
+
+uint32_t
+OptionInfo::defval(int i) {
+ checkIndex(i);
+ return (option_information[i].defval);
+}
+
+uint32_t
+OptionInfo::maxval(int i) {
+ checkIndex(i);
+ return (option_information[i].maxval);
+}
+
+} // namespace badpacket
+} // namespace isc
diff --git a/tests/tools/badpacket/option_info.h b/tests/tools/badpacket/option_info.h
new file mode 100644
index 0000000..8b4e4b9
--- /dev/null
+++ b/tests/tools/badpacket/option_info.h
@@ -0,0 +1,163 @@
+// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef __OPTION_INFO_H
+#define __OPTION_INFO_H
+
+#include <stdint.h>
+#include "exceptions/exceptions.h"
+
+namespace isc {
+namespace badpacket {
+
+/// \brief Option Information
+///
+/// Holds details about the options that can be specified on the command line
+/// that require values and which control data put in the DNS message sent to
+/// the remote system.
+///
+/// Currently all of these options correspond to fields in the flags word of the
+/// DNS message header, so the information includes details about the position
+/// of the fields and an appropriate bit mask.
+///
+/// Note that the class does not hold values specified on the command line - it
+/// only holds information about command-line options.
+
+class OptionInfo {
+public:
+
+ /// \brief Array Indexes
+ ///
+ /// The data for the flags options are held in an array. Although an enum,
+ /// only the numeric values are used - they are indexes into arrays.
+ enum Index {
+ QR = 0, // Query/response
+ OP = 1, // Opcode
+ AA = 2, // Authoritative answer
+ TC = 3, // Truncated
+ RD = 4, // Recursion desired
+ RA = 5, // Recursion available
+ Z = 6, // Zero (reserved)
+ AD = 7, // Authenticated data
+ CD = 8, // Checking disabled
+ RC = 9, // Response code
+ QC = 10, // Query count
+ AC = 11, // Answer count
+ UC = 12, // Authority count
+ DC = 13, // Additional count
+ SIZE = 14 // Number of index values
+ };
+
+ /// \brief Option Parameters
+ ///
+ /// Defines a structure that holds information associated with each of the
+ /// flags field command options. Note all members of the structure are
+ /// relevant to all options
+ struct Parameter {
+ const char short_form; // Short form of the command switch
+ const char* long_form; // Long form of the command switch
+ int word; // Byte offset of word in the header
+ uint16_t mask; // Bit mask of field in the flags word
+ int offset; // Offset of field in flags word
+ uint32_t defval; // Default value
+ uint32_t minval; // Minimum valid value for this field
+ uint32_t maxval; // Maximum valid value for this field
+ };
+
+ /// \brief Return index for command option
+ ///
+ /// Given the short form of a switch, return the index into the options
+ /// array.
+ ///
+ /// \param c The character that is the short form of the command line option.
+ /// An 'int' is used as the value passed will be the return vaue from
+ /// 'getopt()' (or equivalent) which is an int.
+ ///
+ /// \return A valid index value (else an exception is thrown).
+ static int getIndex(int c);
+
+ /// \brief Return long form of command switch for this field
+ ///
+ /// \param index A valid index (one of the values in the 'Index' enum).
+ ///
+ /// \return The long option name (e.q. "qr" for the Query/Response field).
+ static const char* name(int index);
+
+ /// \brief Return header word offset
+ ///
+ /// Returns the byte offset in the DNS message header of the two-byte word
+ /// holding the data in question.
+ ///
+ /// \param index A valid index (one of the values in the 'Index' enum).
+ ///
+ /// \return The offset in the header foe this datum.
+ static int word(int index);
+
+ /// \brief Return mask associated with switch field
+ ///
+ /// \param index A valid index (one of the values in the 'Index' enum).
+ ///
+ /// \return The mask for this particular option in the DNS message flags
+ /// field.
+ static uint16_t mask(int index);
+
+ /// \brief Return offset associated with switch field
+ ///
+ /// \param index A valid index (one of the values in the 'Index' enum).
+ ///
+ /// \return The offset of the field corresponding to this option in the DNS
+ /// message flags field.
+ static int offset(int index);
+
+ /// \brief Return minimum allowed value of field
+ ///
+ /// \param index A valid index (one of the values in the 'Index' enum).
+ ///
+ /// \return Minimum allowed value for this option. This is usually 0.
+ static uint32_t minval(int index);
+
+ /// \brief Return default value of a field
+ ///
+ /// \param index A valid index (one of the values in the 'Index' enum).
+ ///
+ /// \return Default value for this option
+ static uint32_t defval(int index);
+
+ /// \brief Return maximum allowed value of field
+ ///
+ /// \param index A valid index (one of the values in the 'Index' enum).
+ ///
+ /// \return Maximum allowed value for this option. If the option is a bit
+ /// in the flags field of the DNS message hearder, this will be 1.
+ static uint32_t maxval(int index);
+
+ /// \brief Check Array Index
+ ///
+ /// Checks the passed field index and throws an exception if it does not
+ /// correspond to one of the valid indexes in the 'Index' enum.
+ ///
+ /// \param index An index value.
+ ///
+ static void checkIndex(int i) {
+ if ((i < 0) || (i >= SIZE)) {
+ isc_throw(isc::OutOfRange, "option index must be in the range "
+ "0 to " << SIZE);
+ }
+ }
+};
+
+} // namespace badpacket
+} // namespace isc
+
+#endif // __OPTION_INFO_H
diff --git a/tests/tools/badpacket/scan.cc b/tests/tools/badpacket/scan.cc
index 2059ba5..f8cee96 100644
--- a/tests/tools/badpacket/scan.cc
+++ b/tests/tools/badpacket/scan.cc
@@ -60,35 +60,63 @@ Scan::scan(const CommandOptions& options) {
MessageRenderer renderer(*msgbuf);
message.toWire(renderer);
- // Now loop through the flags setting data. This is quite deep nesting,
+ iterateFlagsFields(msgbuf, options);
+}
+
+// Iterate through the various settings in the flags fields
+void
+Scan::iterateFlagsFields(OutputBufferPtr& msgbuf, const CommandOptions& options) {
+
+ // Loop through the flags setting data. This is quite deep nesting,
// but we will continue to indent so as to make things clear (for those
// readers lucky enough to have a wide screen).
- CommandOptions::FlagValues values = options.getFlagValues();
HeaderFlags flags;
- for (uint16_t qr = values.qr[0]; qr <= values.qr[1]; ++qr) {
- flags.setQR(qr);
- for (uint16_t op = values.op[0]; op <= values.op[1]; ++op) {
- flags.setOP(op);
- for (uint16_t aa = values.aa[0]; aa <= values.aa[1]; ++aa) {
- flags.setAA(aa);
- for (uint16_t tc = values.tc[0]; tc <= values.tc[1]; ++tc) {
- flags.setTC(tc);
- for (uint16_t rd = values.rd[0]; rd <= values.rd[1]; ++rd) {
- flags.setRD(rd);
- for (uint16_t ra = values.ra[0]; ra <= values.ra[1]; ++ra) {
- flags.setRA(ra);
- for (uint16_t z = values.z[0]; z <= values.z[1]; ++z) {
- flags.setZ(z);
- for (uint16_t ad = values.ad[0]; ad <= values.ad[1]; ++ad) {
- flags.setAD(ad);
- for (uint16_t cd = values.cd[0]; cd <= values.cd[1]; ++cd) {
- flags.setCD(cd);
- for (uint16_t rc = values.rc[0]; rc <= values.rc[1]; ++rc) {
- flags.setRC(rc);
-
- // Set the flags in the message and do the I/O.
+ for (uint32_t qr = options.minimum(OptionInfo::QR);
+ qr <= options.maximum(OptionInfo::QR); ++qr) {
+ flags.set(OptionInfo::QR, qr);
+
+ for (uint32_t op = options.minimum(OptionInfo::OP);
+ op <= options.maximum(OptionInfo::OP); ++op) {
+ flags.set(OptionInfo::OP, op);
+
+ for (uint32_t aa = options.minimum(OptionInfo::AA);
+ aa <= options.maximum(OptionInfo::AA); ++aa) {
+ flags.set(OptionInfo::AA, aa);
+
+ for (uint32_t tc = options.minimum(OptionInfo::TC);
+ tc <= options.maximum(OptionInfo::TC); ++tc) {
+ flags.set(OptionInfo::TC, tc);
+
+ for (uint32_t rd = options.minimum(OptionInfo::RD);
+ rd <= options.maximum(OptionInfo::RD); ++rd) {
+ flags.set(OptionInfo::RD, rd);
+
+ for (uint32_t ra = options.minimum(OptionInfo::RA);
+ ra <= options.maximum(OptionInfo::RA); ++ra) {
+ flags.set(OptionInfo::RA, ra);
+
+ for (uint32_t z = options.minimum(OptionInfo::Z);
+ z <= options.maximum(OptionInfo::Z); ++z) {
+ flags.set(OptionInfo::Z, z);
+
+ for (uint32_t ad = options.minimum(OptionInfo::AD);
+ ad <= options.maximum(OptionInfo::AD); ++ad) {
+ flags.set(OptionInfo::AD, ad);
+
+ for (uint32_t cd = options.minimum(OptionInfo::CD);
+ cd <= options.maximum(OptionInfo::CD); ++cd) {
+ flags.set(OptionInfo::CD, cd);
+
+ for (uint32_t rc = options.minimum(OptionInfo::RC);
+ rc <= options.maximum(OptionInfo::RC); ++rc) {
+ flags.set(OptionInfo::RC, rc);
+
+ // Set the flags in the message.
msgbuf->writeUint16At(flags.getValue(), 2);
- scanOne(msgbuf, options);
+
+ // And for this flag combination, iterate over the section
+ // count fields.
+ iterateCountFields(msgbuf, options);
}
}
}
@@ -101,7 +129,35 @@ Scan::scan(const CommandOptions& options) {
}
}
-// Perform the message exchange for a single combination of flags.
+// Iterate through the various count fields
+void
+Scan::iterateCountFields(OutputBufferPtr& msgbuf, const CommandOptions& options) {
+ for (uint32_t qc = options.minimum(OptionInfo::QC);
+ qc <= options.maximum(OptionInfo::QC); ++qc) {
+ msgbuf->writeUint16At(qc, OptionInfo::word(OptionInfo::QC));
+
+ for (uint32_t ac = options.minimum(OptionInfo::AC);
+ ac <= options.maximum(OptionInfo::AC); ++ac) {
+ msgbuf->writeUint16At(ac, OptionInfo::word(OptionInfo::AC));
+
+ for (uint32_t uc = options.minimum(OptionInfo::UC);
+ uc <= options.maximum(OptionInfo::UC); ++uc) {
+ msgbuf->writeUint16At(uc, OptionInfo::word(OptionInfo::UC));
+
+ for (uint32_t dc = options.minimum(OptionInfo::DC);
+ dc <= options.maximum(OptionInfo::DC); ++dc) {
+ msgbuf->writeUint16At(dc, OptionInfo::word(OptionInfo::DC));
+
+ // Do the I/O.
+ scanOne(msgbuf, options);
+
+ }
+ }
+ }
+ }
+}
+
+// Perform the message exchange for a single combination command options.
void
Scan::scanOne(isc::dns::OutputBufferPtr& msgbuf, const CommandOptions& options) {
@@ -151,21 +207,41 @@ Scan::getFields(isc::dns::OutputBufferPtr& msgbuf) {
// Extract the flags field from the buffer
InputBuffer inbuf(msgbuf->getData(), msgbuf->getLength());
- inbuf.setPosition(2);
+ inbuf.setPosition(OptionInfo::word(OptionInfo::QR));
flags.setValue(inbuf.readUint16());
std::ostringstream os;
os << std::hex << std::uppercase <<
- "QR:" << flags.getQR() << " " <<
- "OP:" << flags.getOP() << " " <<
- "AA:" << flags.getAA() << " " <<
- "TC:" << flags.getTC() << " " <<
- "RD:" << flags.getRD() << " " <<
- "RA:" << flags.getRA() << " " <<
- "Z:" << flags.getZ() << " " <<
- "AD:" << flags.getAD() << " " <<
- "CD:" << flags.getCD() << " " <<
- "RC:" << flags.getRC();
+ "QR:" << flags.get(OptionInfo::QR) << " " <<
+ "OP:" << flags.get(OptionInfo::OP) << " " <<
+ "AA:" << flags.get(OptionInfo::AA) << " " <<
+ "TC:" << flags.get(OptionInfo::TC) << " " <<
+ "RD:" << flags.get(OptionInfo::RD) << " " <<
+ "RA:" << flags.get(OptionInfo::RA) << " " <<
+ "Z:" << flags.get(OptionInfo::Z) << " " <<
+ "AD:" << flags.get(OptionInfo::AD) << " " <<
+ "CD:" << flags.get(OptionInfo::CD) << " " <<
+ "RC:" << flags.get(OptionInfo::RC);
+
+ // Section count fields
+ os << " ";
+
+ inbuf.setPosition(OptionInfo::word(OptionInfo::QC));
+ os << std::hex << std::uppercase <<
+ "QC:" << inbuf.readUint16() << " ";
+
+ inbuf.setPosition(OptionInfo::word(OptionInfo::AC));
+ os << std::hex << std::uppercase <<
+ "AC:" << inbuf.readUint16() << " ";
+
+ inbuf.setPosition(OptionInfo::word(OptionInfo::UC));
+ os << std::hex << std::uppercase <<
+ "UC:" << inbuf.readUint16() << " ";
+
+ inbuf.setPosition(OptionInfo::word(OptionInfo::DC));
+ os << std::hex << std::uppercase <<
+ "DC:" << inbuf.readUint16();
+
return (os.str());
}
diff --git a/tests/tools/badpacket/scan.h b/tests/tools/badpacket/scan.h
index 5c03a4a..09eb544 100644
--- a/tests/tools/badpacket/scan.h
+++ b/tests/tools/badpacket/scan.h
@@ -59,6 +59,36 @@ public:
virtual void operator()(asiolink::IOFetch::Result result);
private:
+ /// \brief Set Flags Fields Options
+ ///
+ /// Iterates through all combinations of the DNS message flags fields specified
+ /// on the command line and calls scanOne for each combination.
+ ///
+ /// \param msgbuf Message that will be sent to the remote nameserver. The
+ /// QID given will be ignored - the value used will be determined by
+ /// the sending code
+ /// \param options Command-line options (the important ones being address,
+ /// port and timeout).
+ void iterateFlagsFields(isc::dns::OutputBufferPtr& msgbuf,
+ const CommandOptions& options);
+
+ /// \brief Set Count Fields Options
+ ///
+ /// Iterates through all combinations of the count fields specified on the
+ /// command line.
+ ///
+ /// The count fields are set by default to question count = 1, all the rest
+ /// zero. Command-line options allow these values to be altered, although
+ /// the actual contents of the sections are not changed.
+ ///
+ /// \param msgbuf Message that will be sent to the remote nameserver. The
+ /// QID given will be ignored - the value used will be determined by
+ /// the sending code
+ /// \param options Command-line options (the important ones being address,
+ /// port and timeout).
+ void iterateCountFields(isc::dns::OutputBufferPtr& msgbuf,
+ const CommandOptions& options);
+
/// \brief Scan One Value
///
/// Performs one exchange of packets with the remote nameserver, sending
diff --git a/tests/tools/badpacket/tests/Makefile.am b/tests/tools/badpacket/tests/Makefile.am
index 3f38be9..7cde4aa 100644
--- a/tests/tools/badpacket/tests/Makefile.am
+++ b/tests/tools/badpacket/tests/Makefile.am
@@ -15,8 +15,10 @@ if HAVE_GTEST
TESTS += run_unittests
run_unittests_SOURCES = run_unittests.cc
run_unittests_SOURCES += command_options_unittest.cc
+run_unittests_SOURCES += option_info_unittest.cc
run_unittests_SOURCES += header_flags_unittest.cc
run_unittests_SOURCES += $(top_builddir)/tests/tools/badpacket/command_options.cc
+run_unittests_SOURCES += $(top_builddir)/tests/tools/badpacket/option_info.cc
run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
diff --git a/tests/tools/badpacket/tests/command_options_unittest.cc b/tests/tools/badpacket/tests/command_options_unittest.cc
index fe7ceb0..ec9ccf8 100644
--- a/tests/tools/badpacket/tests/command_options_unittest.cc
+++ b/tests/tools/badpacket/tests/command_options_unittest.cc
@@ -25,103 +25,57 @@ using namespace isc;
using namespace isc::badpacket;
-// Test fixture class
+/// \brief Test Fixture Class
class CommandOptionsTest : public virtual ::testing::Test,
public virtual CommandOptions
{
public:
- CommandOptionsTest() {}
-};
-
-// Check that the getRange() method works
-
-TEST_F(CommandOptionsTest, processOptionValue) {
-
- uint32_t result[2];
-
- // Check valid data
- processOptionValue("1", result, 0, 1);
- EXPECT_EQ(1, result[0]);
- EXPECT_EQ(1, result[1]);
-
- processOptionValue("0-2", result, 0, 5);
- EXPECT_EQ(0, result[0]);
- EXPECT_EQ(2, result[1]);
-
- processOptionValue("4-8", result, 0, 10);
- EXPECT_EQ(4, result[0]);
- EXPECT_EQ(8, result[1]);
-
- processOptionValue("172-103", result, 0, 200);
- EXPECT_EQ(103, result[0]);
- EXPECT_EQ(172, result[1]);
-
- // Check coercion is as expected
- processOptionValue("1", result, 3, 4); // Single value below range
- EXPECT_EQ(3, result[0]);
- EXPECT_EQ(3, result[1]);
-
- processOptionValue("7", result, 3, 6); // Single value above range
- EXPECT_EQ(6, result[0]);
- EXPECT_EQ(6, result[1]);
-
- processOptionValue("2-6", result, 5, 10); // Range overlaps valid range on low side
- EXPECT_EQ(5, result[0]);
- EXPECT_EQ(6, result[1]);
-
- processOptionValue("4-7", result, 5, 9); // Range overlaps valid range on high side
- EXPECT_EQ(5, result[0]);
- EXPECT_EQ(7, result[1]);
-
- processOptionValue("9-1", result, 4, 8); // Range overlaps valid range
- EXPECT_EQ(4, result[0]);
- EXPECT_EQ(8, result[1]);
-
- processOptionValue("4-8", result, 1, 9); // Range inside valid range
- EXPECT_EQ(4, result[0]);
- EXPECT_EQ(8, result[1]);
-
- // Now the invalid ones.
- EXPECT_ANY_THROW(processOptionValue("", result, 0, 1));
- EXPECT_ANY_THROW(processOptionValue(" ", result, 0, 1));
- EXPECT_ANY_THROW(processOptionValue("abc", result, 0, 1));
- EXPECT_ANY_THROW(processOptionValue("xyz-def", result, 0, 1));
- EXPECT_ANY_THROW(processOptionValue("0.7", result, 0, 1));
- EXPECT_ANY_THROW(processOptionValue("0.7-2.3", result, 0, 1));
-}
-
-
-// Checks the minimum and maximum values specified for a flag
-void
-checkValuePair(const uint32_t value[2], uint32_t minval = 0,
- uint32_t maxval = 0)
-{
- EXPECT_EQ(minval, value[0]);
- EXPECT_EQ(maxval, value[1]);
-}
-// Checks that all flag values in the command values are zero
-void
-checkDefaultFlagValues(const CommandOptions::FlagValues& values) {
- checkValuePair(values.qr);
- checkValuePair(values.op);
- checkValuePair(values.aa);
- checkValuePair(values.tc);
- checkValuePair(values.z);
- checkValuePair(values.ad);
- checkValuePair(values.cd);
- checkValuePair(values.rc);
-}
+ /// \brief Default Constructor
+ CommandOptionsTest() {}
-// Checks non-flag options are set to defaults.
-void
-checkDefaultOtherValues(CommandOptions& options) {
- EXPECT_EQ("127.0.0.1", options.getAddress());
- EXPECT_EQ(53, options.getPort());
- EXPECT_EQ(500, options.getTimeout());
- EXPECT_EQ("www.example.com", options.getQname());
-}
+ /// \brief Checks the minimum and maximum () specified for an option
+ ///
+ /// Checks the () for one of the options whose values are stored in the
+ /// class's limits) array.
+ ///
+ /// \param index Index of the option in the limits_ array
+ /// \param minval Expected minimum value
+ /// \param maxval Expected maximum value
+ void checkValuePair(int index, uint32_t minval = 0, uint32_t maxval = 0)
+ {
+ EXPECT_EQ(minimum(index), minval);
+ EXPECT_EQ(maximum(index), maxval);
+ }
+
+ /// \brief Checks that all options giving flags () are zero.
+ ///
+ /// Checks that all options whose () are stored in the class's limits_
+ /// array have both their maximum and minimum () set to zero.
+ void checkDefaultLimitsValues() {
+ checkValuePair(OptionInfo::QR);
+ checkValuePair(OptionInfo::OP);
+ checkValuePair(OptionInfo::AA);
+ checkValuePair(OptionInfo::TC);
+ checkValuePair(OptionInfo::Z);
+ checkValuePair(OptionInfo::AD);
+ checkValuePair(OptionInfo::CD);
+ checkValuePair(OptionInfo::RC);
+ }
+
+ /// \brief Check Non-Limit Options
+ ///
+ /// Checks that the options whose () are NOT stored in the limits_
+ /// array are set to their default ().
+ void
+ checkDefaultOtherValues() {
+ EXPECT_EQ("127.0.0.1", getAddress());
+ EXPECT_EQ(53, getPort());
+ EXPECT_EQ(500, getTimeout());
+ EXPECT_EQ("www.example.com", getQname());
+ }
+};
// Check that each of the options will be recognised
@@ -138,7 +92,7 @@ TEST_F(CommandOptionsTest, address) {
EXPECT_EQ(53, getPort());
EXPECT_EQ(500, getTimeout());
EXPECT_EQ("www.example.com", getQname());
- checkDefaultFlagValues(getFlagValues());
+ checkDefaultLimitsValues();
}
TEST_F(CommandOptionsTest, port) {
@@ -150,7 +104,7 @@ TEST_F(CommandOptionsTest, port) {
EXPECT_EQ(153, getPort());
EXPECT_EQ(500, getTimeout());
EXPECT_EQ("www.example.com", getQname());
- checkDefaultFlagValues(getFlagValues());
+ checkDefaultLimitsValues();
}
TEST_F(CommandOptionsTest, timeout) {
@@ -162,7 +116,7 @@ TEST_F(CommandOptionsTest, timeout) {
EXPECT_EQ(53, getPort());
EXPECT_EQ(250, getTimeout());
EXPECT_EQ("www.example.com", getQname());
- checkDefaultFlagValues(getFlagValues());
+ checkDefaultLimitsValues();
}
TEST_F(CommandOptionsTest, parameter) {
@@ -174,372 +128,356 @@ TEST_F(CommandOptionsTest, parameter) {
EXPECT_EQ(53, getPort());
EXPECT_EQ(500, getTimeout());
EXPECT_EQ("ftp.example.net", getQname());
- checkDefaultFlagValues(getFlagValues());
+ checkDefaultLimitsValues();
}
// The various tests of the different flags
TEST_F(CommandOptionsTest, qr) {
- // Specifying a value of zero, we expect all flag values to be zero
+ // Specifying a value of zero, we expect all flag () to be zero
const char* argv1[] = {"badpacket", "--qr", "0"};
int argc1 = sizeof(argv1) / sizeof(const char*);
parse(argc1, const_cast<char**>(argv1));
- checkDefaultOtherValues(*this);
- FlagValues values = getFlagValues();
- checkDefaultFlagValues(values);
+ checkDefaultOtherValues();
+ checkDefaultLimitsValues();
// Check that a value of 1 is accepted
const char* argv2[] = {"badpacket", "--qr", "1"};
int argc2 = sizeof(argv2) / sizeof(const char*);
parse(argc2, const_cast<char**>(argv2));
- checkDefaultOtherValues(*this);
- values = getFlagValues();
- checkValuePair(values.qr, 1, 1);
- checkValuePair(values.op);
- checkValuePair(values.aa);
- checkValuePair(values.tc);
- checkValuePair(values.z);
- checkValuePair(values.ad);
- checkValuePair(values.cd);
- checkValuePair(values.rc);
+ checkDefaultOtherValues();
+ checkValuePair(OptionInfo::QR, 1, 1);
+ checkValuePair(OptionInfo::OP);
+ checkValuePair(OptionInfo::AA);
+ checkValuePair(OptionInfo::TC);
+ checkValuePair(OptionInfo::Z);
+ checkValuePair(OptionInfo::AD);
+ checkValuePair(OptionInfo::CD);
+ checkValuePair(OptionInfo::RC);
// Check that a range is accepted (in this case, specified backwards)
const char* argv3[] = {"badpacket", "--qr", "1-0"};
int argc3 = sizeof(argv3) / sizeof(const char*);
parse(argc3, const_cast<char**>(argv3));
- checkDefaultOtherValues(*this);
- values = getFlagValues();
- checkValuePair(values.qr, 0, 1);
- checkValuePair(values.op);
- checkValuePair(values.aa);
- checkValuePair(values.tc);
- checkValuePair(values.z);
- checkValuePair(values.ad);
- checkValuePair(values.cd);
- checkValuePair(values.rc);
+ checkDefaultOtherValues();
+ checkValuePair(OptionInfo::QR, 0, 1);
+ checkValuePair(OptionInfo::OP);
+ checkValuePair(OptionInfo::AA);
+ checkValuePair(OptionInfo::TC);
+ checkValuePair(OptionInfo::Z);
+ checkValuePair(OptionInfo::AD);
+ checkValuePair(OptionInfo::CD);
+ checkValuePair(OptionInfo::RC);
}
// The following are cut-and-pasted from the "qr" test. (It is awkward to put
-// the test into a general function because of differing string values and
+// the test into a general function because of differing string () and
// variables.)
TEST_F(CommandOptionsTest, op) {
- // Specifying a value of zero, we expect all flag values to be zero
+ // Specifying a value of zero, we expect all flag () to be zero
const char* argv1[] = {"badpacket", "--op", "0"};
int argc1 = sizeof(argv1) / sizeof(const char*);
parse(argc1, const_cast<char**>(argv1));
- checkDefaultOtherValues(*this);
- FlagValues values = getFlagValues();
- checkDefaultFlagValues(values);
+ checkDefaultOtherValues();
+ checkDefaultLimitsValues();
// Check that a value of 1 is accepted
const char* argv2[] = {"badpacket", "--op", "8"};
int argc2 = sizeof(argv2) / sizeof(const char*);
parse(argc2, const_cast<char**>(argv2));
- checkDefaultOtherValues(*this);
- values = getFlagValues();
- checkValuePair(values.qr);
- checkValuePair(values.op, 8, 8);
- checkValuePair(values.aa);
- checkValuePair(values.tc);
- checkValuePair(values.z);
- checkValuePair(values.ad);
- checkValuePair(values.cd);
- checkValuePair(values.rc);
+ checkDefaultOtherValues();
+ checkValuePair(OptionInfo::QR);
+ checkValuePair(OptionInfo::OP, 8, 8);
+ checkValuePair(OptionInfo::AA);
+ checkValuePair(OptionInfo::TC);
+ checkValuePair(OptionInfo::Z);
+ checkValuePair(OptionInfo::AD);
+ checkValuePair(OptionInfo::CD);
+ checkValuePair(OptionInfo::RC);
- // Check that a range is accepted (in this case, specified backwards and
- // outside the range - so it should be truncated).
- const char* argv3[] = {"badpacket", "--op", "21-0"};
+ // Check that a range is accepted (in this case, specified backwards)
+ const char* argv3[] = {"badpacket", "--op", "14-2"};
int argc3 = sizeof(argv3) / sizeof(const char*);
parse(argc3, const_cast<char**>(argv3));
- checkDefaultOtherValues(*this);
- values = getFlagValues();
- checkValuePair(values.qr);
- checkValuePair(values.op, 0, 15);
- checkValuePair(values.aa);
- checkValuePair(values.tc);
- checkValuePair(values.z);
- checkValuePair(values.ad);
- checkValuePair(values.cd);
- checkValuePair(values.rc);
+ checkDefaultOtherValues();
+ checkValuePair(OptionInfo::QR);
+ checkValuePair(OptionInfo::OP, 2, 14);
+ checkValuePair(OptionInfo::AA);
+ checkValuePair(OptionInfo::TC);
+ checkValuePair(OptionInfo::Z);
+ checkValuePair(OptionInfo::AD);
+ checkValuePair(OptionInfo::CD);
+ checkValuePair(OptionInfo::RC);
}
TEST_F(CommandOptionsTest, aa) {
- // Specifying a value of zero, we expect all flag values to be zero
+ // Specifying a value of zero, we expect all flag () to be zero
const char* argv1[] = {"badpacket", "--aa", "0"};
int argc1 = sizeof(argv1) / sizeof(const char*);
parse(argc1, const_cast<char**>(argv1));
- checkDefaultOtherValues(*this);
- FlagValues values = getFlagValues();
- checkDefaultFlagValues(values);
+ checkDefaultOtherValues();
+ checkDefaultLimitsValues();
// Check that a value of 1 is accepted
const char* argv2[] = {"badpacket", "--aa", "1"};
int argc2 = sizeof(argv2) / sizeof(const char*);
parse(argc2, const_cast<char**>(argv2));
- checkDefaultOtherValues(*this);
- values = getFlagValues();
- checkValuePair(values.qr);
- checkValuePair(values.op);
- checkValuePair(values.aa, 1, 1);
- checkValuePair(values.tc);
- checkValuePair(values.z);
- checkValuePair(values.ad);
- checkValuePair(values.cd);
- checkValuePair(values.rc);
-
- // Check that a range is accepted (in this case, specified backwards and
- // outside the range - so it should be truncated).
- const char* argv3[] = {"badpacket", "--aa", "21-0"};
+ checkDefaultOtherValues();
+ checkValuePair(OptionInfo::QR);
+ checkValuePair(OptionInfo::OP);
+ checkValuePair(OptionInfo::AA, 1, 1);
+ checkValuePair(OptionInfo::TC);
+ checkValuePair(OptionInfo::Z);
+ checkValuePair(OptionInfo::AD);
+ checkValuePair(OptionInfo::CD);
+ checkValuePair(OptionInfo::RC);
+
+ // Check that a range is accepted.
+ const char* argv3[] = {"badpacket", "--aa", "1-0"};
int argc3 = sizeof(argv3) / sizeof(const char*);
parse(argc3, const_cast<char**>(argv3));
- checkDefaultOtherValues(*this);
- values = getFlagValues();
- checkValuePair(values.qr);
- checkValuePair(values.op);
- checkValuePair(values.aa, 0, 1);
- checkValuePair(values.tc);
- checkValuePair(values.z);
- checkValuePair(values.ad);
- checkValuePair(values.cd);
- checkValuePair(values.rc);
+ checkDefaultOtherValues();
+ checkValuePair(OptionInfo::QR);
+ checkValuePair(OptionInfo::OP);
+ checkValuePair(OptionInfo::AA, 0, 1);
+ checkValuePair(OptionInfo::TC);
+ checkValuePair(OptionInfo::Z);
+ checkValuePair(OptionInfo::AD);
+ checkValuePair(OptionInfo::CD);
+ checkValuePair(OptionInfo::RC);
}
TEST_F(CommandOptionsTest, tc) {
- // Specifying a value of zero, we expect all flag values to be zero
+ // Specifying a value of zero, we expect all flag () to be zero
const char* argv1[] = {"badpacket", "--tc", "0"};
int argc1 = sizeof(argv1) / sizeof(const char*);
parse(argc1, const_cast<char**>(argv1));
- checkDefaultOtherValues(*this);
- FlagValues values = getFlagValues();
- checkDefaultFlagValues(values);
+ checkDefaultOtherValues();
+ checkDefaultLimitsValues();
// Check that a value of 1 is accepted
const char* argv2[] = {"badpacket", "--tc", "1"};
int argc2 = sizeof(argv2) / sizeof(const char*);
parse(argc2, const_cast<char**>(argv2));
- checkDefaultOtherValues(*this);
- values = getFlagValues();
- checkValuePair(values.qr);
- checkValuePair(values.op);
- checkValuePair(values.aa);
- checkValuePair(values.tc, 1, 1);
- checkValuePair(values.z);
- checkValuePair(values.ad);
- checkValuePair(values.cd);
- checkValuePair(values.rc);
-
- // Check that a range is accepted (in this case, specified backwards and
- // outside the range - so it should be truncated).
- const char* argv3[] = {"badpacket", "--tc", "21-0"};
+ checkDefaultOtherValues();
+ checkValuePair(OptionInfo::QR);
+ checkValuePair(OptionInfo::OP);
+ checkValuePair(OptionInfo::AA);
+ checkValuePair(OptionInfo::TC, 1, 1);
+ checkValuePair(OptionInfo::Z);
+ checkValuePair(OptionInfo::AD);
+ checkValuePair(OptionInfo::CD);
+ checkValuePair(OptionInfo::RC);
+
+ // Check that a range is accepted.
+ const char* argv3[] = {"badpacket", "--tc", "1-0"};
int argc3 = sizeof(argv3) / sizeof(const char*);
parse(argc3, const_cast<char**>(argv3));
- checkDefaultOtherValues(*this);
- values = getFlagValues();
- checkValuePair(values.qr);
- checkValuePair(values.op);
- checkValuePair(values.aa);
- checkValuePair(values.tc, 0, 1);
- checkValuePair(values.z);
- checkValuePair(values.ad);
- checkValuePair(values.cd);
- checkValuePair(values.rc);
+ checkDefaultOtherValues();
+ checkValuePair(OptionInfo::QR);
+ checkValuePair(OptionInfo::OP);
+ checkValuePair(OptionInfo::AA);
+ checkValuePair(OptionInfo::TC, 0, 1);
+ checkValuePair(OptionInfo::Z);
+ checkValuePair(OptionInfo::AD);
+ checkValuePair(OptionInfo::CD);
+ checkValuePair(OptionInfo::RC);
}
TEST_F(CommandOptionsTest, z) {
- // Specifying a value of zero, we expect all flag values to be zero
+ // Specifying a value of zero, we expect all flag () to be zero
const char* argv1[] = {"badpacket", "--z", "0"};
int argc1 = sizeof(argv1) / sizeof(const char*);
parse(argc1, const_cast<char**>(argv1));
- checkDefaultOtherValues(*this);
- FlagValues values = getFlagValues();
- checkDefaultFlagValues(values);
+ checkDefaultOtherValues();
+ checkDefaultLimitsValues();
// Check that a value of 1 is accepted
const char* argv2[] = {"badpacket", "--z", "1"};
int argc2 = sizeof(argv2) / sizeof(const char*);
parse(argc2, const_cast<char**>(argv2));
- checkDefaultOtherValues(*this);
- values = getFlagValues();
- checkValuePair(values.qr);
- checkValuePair(values.op);
- checkValuePair(values.aa);
- checkValuePair(values.tc);
- checkValuePair(values.z, 1, 1);
- checkValuePair(values.ad);
- checkValuePair(values.cd);
- checkValuePair(values.rc);
-
- // Check that a range is accepted (in this case, specified backwards and
- // outside the range - so it should be truncated).
- const char* argv3[] = {"badpacket", "--z", "21-0"};
+ checkDefaultOtherValues();
+ checkValuePair(OptionInfo::QR);
+ checkValuePair(OptionInfo::OP);
+ checkValuePair(OptionInfo::AA);
+ checkValuePair(OptionInfo::TC);
+ checkValuePair(OptionInfo::Z, 1, 1);
+ checkValuePair(OptionInfo::AD);
+ checkValuePair(OptionInfo::CD);
+ checkValuePair(OptionInfo::RC);
+
+ // Check that a range is accepted.
+ const char* argv3[] = {"badpacket", "--z", "1-0"};
int argc3 = sizeof(argv3) / sizeof(const char*);
parse(argc3, const_cast<char**>(argv3));
- checkDefaultOtherValues(*this);
- values = getFlagValues();
- checkValuePair(values.qr);
- checkValuePair(values.op);
- checkValuePair(values.aa);
- checkValuePair(values.tc);
- checkValuePair(values.z, 0, 1);
- checkValuePair(values.ad);
- checkValuePair(values.cd);
- checkValuePair(values.rc);
+ checkDefaultOtherValues();
+ checkValuePair(OptionInfo::QR);
+ checkValuePair(OptionInfo::OP);
+ checkValuePair(OptionInfo::AA);
+ checkValuePair(OptionInfo::TC);
+ checkValuePair(OptionInfo::Z, 0, 1);
+ checkValuePair(OptionInfo::AD);
+ checkValuePair(OptionInfo::CD);
+ checkValuePair(OptionInfo::RC);
}
TEST_F(CommandOptionsTest, ad) {
- // Specifying a value of zero, we expect all flag values to be zero
+ // Specifying a value of zero, we expect all flag () to be zero
const char* argv1[] = {"badpacket", "--ad", "0"};
int argc1 = sizeof(argv1) / sizeof(const char*);
parse(argc1, const_cast<char**>(argv1));
- checkDefaultOtherValues(*this);
- FlagValues values = getFlagValues();
- checkDefaultFlagValues(values);
+ checkDefaultOtherValues();
+ checkDefaultLimitsValues();
// Check that a value of 1 is accepted
const char* argv2[] = {"badpacket", "--ad", "1"};
int argc2 = sizeof(argv2) / sizeof(const char*);
parse(argc2, const_cast<char**>(argv2));
- checkDefaultOtherValues(*this);
- values = getFlagValues();
- checkValuePair(values.qr);
- checkValuePair(values.op);
- checkValuePair(values.aa);
- checkValuePair(values.tc);
- checkValuePair(values.z);
- checkValuePair(values.ad, 1, 1);
- checkValuePair(values.cd);
- checkValuePair(values.rc);
-
- // Check that a range is accepted (in this case, specified backwards and
- // outside the range - so it should be truncated).
- const char* argv3[] = {"badpacket", "--ad", "21-0"};
+ checkDefaultOtherValues();
+ checkValuePair(OptionInfo::QR);
+ checkValuePair(OptionInfo::OP);
+ checkValuePair(OptionInfo::AA);
+ checkValuePair(OptionInfo::TC);
+ checkValuePair(OptionInfo::Z);
+ checkValuePair(OptionInfo::AD, 1, 1);
+ checkValuePair(OptionInfo::CD);
+ checkValuePair(OptionInfo::RC);
+
+ // Check that a range is accepted.
+ const char* argv3[] = {"badpacket", "--ad", "0-1"};
int argc3 = sizeof(argv3) / sizeof(const char*);
parse(argc3, const_cast<char**>(argv3));
- checkDefaultOtherValues(*this);
- values = getFlagValues();
- checkValuePair(values.qr);
- checkValuePair(values.op);
- checkValuePair(values.aa);
- checkValuePair(values.tc);
- checkValuePair(values.z);
- checkValuePair(values.ad, 0, 1);
- checkValuePair(values.cd);
- checkValuePair(values.rc);
+ checkDefaultOtherValues();
+ checkValuePair(OptionInfo::QR);
+ checkValuePair(OptionInfo::OP);
+ checkValuePair(OptionInfo::AA);
+ checkValuePair(OptionInfo::TC);
+ checkValuePair(OptionInfo::Z);
+ checkValuePair(OptionInfo::AD, 0, 1);
+ checkValuePair(OptionInfo::CD);
+ checkValuePair(OptionInfo::RC);
}
TEST_F(CommandOptionsTest, cd) {
- // Specifying a value of zero, we expect all flag values to be zero
+ // Specifying a value of zero, we expect all flag () to be zero
const char* argv1[] = {"badpacket", "--cd", "0"};
int argc1 = sizeof(argv1) / sizeof(const char*);
parse(argc1, const_cast<char**>(argv1));
- checkDefaultOtherValues(*this);
- FlagValues values = getFlagValues();
- checkDefaultFlagValues(values);
+ checkDefaultOtherValues();
+ checkDefaultLimitsValues();
// Check that a value of 1 is accepted
const char* argv2[] = {"badpacket", "--cd", "1"};
int argc2 = sizeof(argv2) / sizeof(const char*);
parse(argc2, const_cast<char**>(argv2));
- checkDefaultOtherValues(*this);
- values = getFlagValues();
- checkValuePair(values.qr);
- checkValuePair(values.op);
- checkValuePair(values.aa);
- checkValuePair(values.tc);
- checkValuePair(values.z);
- checkValuePair(values.ad);
- checkValuePair(values.cd, 1, 1);
- checkValuePair(values.rc);
-
- // Check that a range is accepted (in this case, specified backwards and
- // outside the range - so it should be truncated).
- const char* argv3[] = {"badpacket", "--cd", "21-0"};
+ checkDefaultOtherValues();
+ checkValuePair(OptionInfo::QR);
+ checkValuePair(OptionInfo::OP);
+ checkValuePair(OptionInfo::AA);
+ checkValuePair(OptionInfo::TC);
+ checkValuePair(OptionInfo::Z);
+ checkValuePair(OptionInfo::AD);
+ checkValuePair(OptionInfo::CD, 1, 1);
+ checkValuePair(OptionInfo::RC);
+
+ // Check that a range is accepted.
+ const char* argv3[] = {"badpacket", "--cd", "1-0"};
int argc3 = sizeof(argv3) / sizeof(const char*);
parse(argc3, const_cast<char**>(argv3));
- checkDefaultOtherValues(*this);
- values = getFlagValues();
- checkValuePair(values.qr);
- checkValuePair(values.op);
- checkValuePair(values.aa);
- checkValuePair(values.tc);
- checkValuePair(values.z);
- checkValuePair(values.ad);
- checkValuePair(values.cd, 0, 1);
- checkValuePair(values.rc);
+ checkDefaultOtherValues();
+ checkValuePair(OptionInfo::QR);
+ checkValuePair(OptionInfo::OP);
+ checkValuePair(OptionInfo::AA);
+ checkValuePair(OptionInfo::TC);
+ checkValuePair(OptionInfo::Z);
+ checkValuePair(OptionInfo::AD);
+ checkValuePair(OptionInfo::CD, 0, 1);
+ checkValuePair(OptionInfo::RC);
}
TEST_F(CommandOptionsTest, rc) {
- // Specifying a value of zero, we expect all flag values to be zero
+ // Specifying a value of zero, we expect all flag () to be zero
const char* argv1[] = {"badpacket", "--rc", "0"};
int argc1 = sizeof(argv1) / sizeof(const char*);
parse(argc1, const_cast<char**>(argv1));
- checkDefaultOtherValues(*this);
- FlagValues values = getFlagValues();
- checkDefaultFlagValues(values);
+ checkDefaultOtherValues();
+ checkDefaultLimitsValues();
- // Check that a value of 1 is accepted
- const char* argv2[] = {"badpacket", "--rc", "21"};
+ // Check that a valid value is accepted.
+ const char* argv2[] = {"badpacket", "--rc", "15"};
int argc2 = sizeof(argv2) / sizeof(const char*);
parse(argc2, const_cast<char**>(argv2));
- checkDefaultOtherValues(*this);
- values = getFlagValues();
- checkValuePair(values.qr);
- checkValuePair(values.op);
- checkValuePair(values.aa);
- checkValuePair(values.tc);
- checkValuePair(values.z);
- checkValuePair(values.ad);
- checkValuePair(values.cd);
- checkValuePair(values.rc, 15, 15);
+ checkDefaultOtherValues();
+ checkValuePair(OptionInfo::QR);
+ checkValuePair(OptionInfo::OP);
+ checkValuePair(OptionInfo::AA);
+ checkValuePair(OptionInfo::TC);
+ checkValuePair(OptionInfo::Z);
+ checkValuePair(OptionInfo::AD);
+ checkValuePair(OptionInfo::CD);
+ checkValuePair(OptionInfo::RC, 15, 15);
// Check that a range is accepted (in this case, specified backwards and
// outside the range - so it should be truncated).
- const char* argv3[] = {"badpacket", "--rc", "21-0"};
+ const char* argv3[] = {"badpacket", "--rc", "8-4"};
int argc3 = sizeof(argv3) / sizeof(const char*);
parse(argc3, const_cast<char**>(argv3));
- checkDefaultOtherValues(*this);
- values = getFlagValues();
- checkValuePair(values.qr);
- checkValuePair(values.op);
- checkValuePair(values.aa);
- checkValuePair(values.tc);
- checkValuePair(values.z);
- checkValuePair(values.ad);
- checkValuePair(values.cd);
- checkValuePair(values.rc, 0, 15);
+ checkDefaultOtherValues();
+ checkValuePair(OptionInfo::QR);
+ checkValuePair(OptionInfo::OP);
+ checkValuePair(OptionInfo::AA);
+ checkValuePair(OptionInfo::TC);
+ checkValuePair(OptionInfo::Z);
+ checkValuePair(OptionInfo::AD);
+ checkValuePair(OptionInfo::CD);
+ checkValuePair(OptionInfo::RC, 4, 8);
}
+// Check that invalid () are caught.
+TEST_F(CommandOptionsTest, processOptionValue) {
-// Check that the other flags work
+ // Check out of range () cause a BadValue exception
+ EXPECT_THROW(processOptionValue('Q', "2"), isc::BadValue); // Single value above range
+ EXPECT_THROW(processOptionValue('O', "0-17"), isc::BadValue); // Range overlapping valid range
+
+ // ... and that any invalid string does the same
+ EXPECT_THROW(processOptionValue('O', ""), isc::BadValue);
+ EXPECT_THROW(processOptionValue('O', " "), isc::BadValue);
+ EXPECT_THROW(processOptionValue('O', "1-2-3"), isc::BadValue);
+ EXPECT_THROW(processOptionValue('O', "abc"), isc::BadValue);
+ EXPECT_THROW(processOptionValue('O', "abc-xyz"), isc::BadValue);
+ EXPECT_THROW(processOptionValue('O', "0.7"), isc::BadValue);
+ EXPECT_THROW(processOptionValue('O', "0.7-2.3"), isc::BadValue);
+}
diff --git a/tests/tools/badpacket/tests/header_flags_unittest.cc b/tests/tools/badpacket/tests/header_flags_unittest.cc
index dce4dc9..bc39b32 100644
--- a/tests/tools/badpacket/tests/header_flags_unittest.cc
+++ b/tests/tools/badpacket/tests/header_flags_unittest.cc
@@ -16,6 +16,7 @@
#include <stdint.h>
#include <gtest/gtest.h>
+#include "../option_info.h"
#include "../header_flags.h"
using namespace isc::badpacket;
@@ -31,16 +32,16 @@ public:
// Convenience function to check that all values are zero
void
checkZero(const HeaderFlags& flags) {
- EXPECT_EQ(0, flags.getQR());
- EXPECT_EQ(0, flags.getOP());
- EXPECT_EQ(0, flags.getAA());
- EXPECT_EQ(0, flags.getTC());
- EXPECT_EQ(0, flags.getRD());
- EXPECT_EQ(0, flags.getRA());
- EXPECT_EQ(0, flags.getZ());
- EXPECT_EQ(0, flags.getAD());
- EXPECT_EQ(0, flags.getCD());
- EXPECT_EQ(0, flags.getRC());
+ EXPECT_EQ(0, flags.get(OptionInfo::QR));
+ EXPECT_EQ(0, flags.get(OptionInfo::OP));
+ EXPECT_EQ(0, flags.get(OptionInfo::AA));
+ EXPECT_EQ(0, flags.get(OptionInfo::TC));
+ EXPECT_EQ(0, flags.get(OptionInfo::RD));
+ EXPECT_EQ(0, flags.get(OptionInfo::RA));
+ EXPECT_EQ(0, flags.get(OptionInfo::Z));
+ EXPECT_EQ(0, flags.get(OptionInfo::AD));
+ EXPECT_EQ(0, flags.get(OptionInfo::CD));
+ EXPECT_EQ(0, flags.get(OptionInfo::RC));
EXPECT_EQ(0, flags.getValue());
}
@@ -53,20 +54,20 @@ TEST_F(HeaderFlagsTest, QRfield) {
HeaderFlags flags;
checkZero(flags);
- flags.setQR(1);
- EXPECT_EQ(1, flags.getQR());
- EXPECT_EQ(0, flags.getOP());
- EXPECT_EQ(0, flags.getAA());
- EXPECT_EQ(0, flags.getTC());
- EXPECT_EQ(0, flags.getRD());
- EXPECT_EQ(0, flags.getRA());
- EXPECT_EQ(0, flags.getZ());
- EXPECT_EQ(0, flags.getAD());
- EXPECT_EQ(0, flags.getCD());
- EXPECT_EQ(0, flags.getRC());
+ flags.set(OptionInfo::QR, 1);
+ EXPECT_EQ(1, flags.get(OptionInfo::QR));
+ EXPECT_EQ(0, flags.get(OptionInfo::OP));
+ EXPECT_EQ(0, flags.get(OptionInfo::AA));
+ EXPECT_EQ(0, flags.get(OptionInfo::TC));
+ EXPECT_EQ(0, flags.get(OptionInfo::RD));
+ EXPECT_EQ(0, flags.get(OptionInfo::RA));
+ EXPECT_EQ(0, flags.get(OptionInfo::Z));
+ EXPECT_EQ(0, flags.get(OptionInfo::AD));
+ EXPECT_EQ(0, flags.get(OptionInfo::CD));
+ EXPECT_EQ(0, flags.get(OptionInfo::RC));
EXPECT_NE(0, flags.getValue());
- flags.setQR(0);
+ flags.set(OptionInfo::QR, 0);
checkZero(flags);
}
@@ -74,20 +75,20 @@ TEST_F(HeaderFlagsTest, OPfield) {
HeaderFlags flags;
checkZero(flags);
- flags.setOP(15);
- EXPECT_EQ(0, flags.getQR());
- EXPECT_EQ(15, flags.getOP());
- EXPECT_EQ(0, flags.getAA());
- EXPECT_EQ(0, flags.getTC());
- EXPECT_EQ(0, flags.getRD());
- EXPECT_EQ(0, flags.getRA());
- EXPECT_EQ(0, flags.getZ());
- EXPECT_EQ(0, flags.getAD());
- EXPECT_EQ(0, flags.getCD());
- EXPECT_EQ(0, flags.getRC());
+ flags.set(OptionInfo::OP, 15);
+ EXPECT_EQ(0, flags.get(OptionInfo::QR));
+ EXPECT_EQ(15, flags.get(OptionInfo::OP));
+ EXPECT_EQ(0, flags.get(OptionInfo::AA));
+ EXPECT_EQ(0, flags.get(OptionInfo::TC));
+ EXPECT_EQ(0, flags.get(OptionInfo::RD));
+ EXPECT_EQ(0, flags.get(OptionInfo::RA));
+ EXPECT_EQ(0, flags.get(OptionInfo::Z));
+ EXPECT_EQ(0, flags.get(OptionInfo::AD));
+ EXPECT_EQ(0, flags.get(OptionInfo::CD));
+ EXPECT_EQ(0, flags.get(OptionInfo::RC));
EXPECT_NE(0, flags.getValue());
- flags.setOP(0);
+ flags.set(OptionInfo::OP, 0);
checkZero(flags);
}
@@ -95,20 +96,20 @@ TEST_F(HeaderFlagsTest, AAfield) {
HeaderFlags flags;
checkZero(flags);
- flags.setAA(1);
- EXPECT_EQ(0, flags.getQR());
- EXPECT_EQ(0, flags.getOP());
- EXPECT_EQ(1, flags.getAA());
- EXPECT_EQ(0, flags.getTC());
- EXPECT_EQ(0, flags.getRD());
- EXPECT_EQ(0, flags.getRA());
- EXPECT_EQ(0, flags.getZ());
- EXPECT_EQ(0, flags.getAD());
- EXPECT_EQ(0, flags.getCD());
- EXPECT_EQ(0, flags.getRC());
+ flags.set(OptionInfo::AA, 1);
+ EXPECT_EQ(0, flags.get(OptionInfo::QR));
+ EXPECT_EQ(0, flags.get(OptionInfo::OP));
+ EXPECT_EQ(1, flags.get(OptionInfo::AA));
+ EXPECT_EQ(0, flags.get(OptionInfo::TC));
+ EXPECT_EQ(0, flags.get(OptionInfo::RD));
+ EXPECT_EQ(0, flags.get(OptionInfo::RA));
+ EXPECT_EQ(0, flags.get(OptionInfo::Z));
+ EXPECT_EQ(0, flags.get(OptionInfo::AD));
+ EXPECT_EQ(0, flags.get(OptionInfo::CD));
+ EXPECT_EQ(0, flags.get(OptionInfo::RC));
EXPECT_NE(0, flags.getValue());
- flags.setAA(0);
+ flags.set(OptionInfo::AA, 0);
checkZero(flags);
}
@@ -116,20 +117,20 @@ TEST_F(HeaderFlagsTest, TCfield) {
HeaderFlags flags;
checkZero(flags);
- flags.setTC(1);
- EXPECT_EQ(0, flags.getQR());
- EXPECT_EQ(0, flags.getOP());
- EXPECT_EQ(0, flags.getAA());
- EXPECT_EQ(1, flags.getTC());
- EXPECT_EQ(0, flags.getRD());
- EXPECT_EQ(0, flags.getRA());
- EXPECT_EQ(0, flags.getZ());
- EXPECT_EQ(0, flags.getAD());
- EXPECT_EQ(0, flags.getCD());
- EXPECT_EQ(0, flags.getRC());
+ flags.set(OptionInfo::TC, 1);
+ EXPECT_EQ(0, flags.get(OptionInfo::QR));
+ EXPECT_EQ(0, flags.get(OptionInfo::OP));
+ EXPECT_EQ(0, flags.get(OptionInfo::AA));
+ EXPECT_EQ(1, flags.get(OptionInfo::TC));
+ EXPECT_EQ(0, flags.get(OptionInfo::RD));
+ EXPECT_EQ(0, flags.get(OptionInfo::RA));
+ EXPECT_EQ(0, flags.get(OptionInfo::Z));
+ EXPECT_EQ(0, flags.get(OptionInfo::AD));
+ EXPECT_EQ(0, flags.get(OptionInfo::CD));
+ EXPECT_EQ(0, flags.get(OptionInfo::RC));
EXPECT_NE(0, flags.getValue());
- flags.setTC(0);
+ flags.set(OptionInfo::TC, 0);
checkZero(flags);
}
@@ -137,20 +138,20 @@ TEST_F(HeaderFlagsTest, RDfield) {
HeaderFlags flags;
checkZero(flags);
- flags.setRD(1);
- EXPECT_EQ(0, flags.getQR());
- EXPECT_EQ(0, flags.getOP());
- EXPECT_EQ(0, flags.getAA());
- EXPECT_EQ(0, flags.getTC());
- EXPECT_EQ(1, flags.getRD());
- EXPECT_EQ(0, flags.getRA());
- EXPECT_EQ(0, flags.getZ());
- EXPECT_EQ(0, flags.getAD());
- EXPECT_EQ(0, flags.getCD());
- EXPECT_EQ(0, flags.getRC());
+ flags.set(OptionInfo::RD, 1);
+ EXPECT_EQ(0, flags.get(OptionInfo::QR));
+ EXPECT_EQ(0, flags.get(OptionInfo::OP));
+ EXPECT_EQ(0, flags.get(OptionInfo::AA));
+ EXPECT_EQ(0, flags.get(OptionInfo::TC));
+ EXPECT_EQ(1, flags.get(OptionInfo::RD));
+ EXPECT_EQ(0, flags.get(OptionInfo::RA));
+ EXPECT_EQ(0, flags.get(OptionInfo::Z));
+ EXPECT_EQ(0, flags.get(OptionInfo::AD));
+ EXPECT_EQ(0, flags.get(OptionInfo::CD));
+ EXPECT_EQ(0, flags.get(OptionInfo::RC));
EXPECT_NE(0, flags.getValue());
- flags.setRD(0);
+ flags.set(OptionInfo::RD, 0);
checkZero(flags);
}
@@ -158,20 +159,20 @@ TEST_F(HeaderFlagsTest, RAfield) {
HeaderFlags flags;
checkZero(flags);
- flags.setRA(1);
- EXPECT_EQ(0, flags.getQR());
- EXPECT_EQ(0, flags.getOP());
- EXPECT_EQ(0, flags.getAA());
- EXPECT_EQ(0, flags.getTC());
- EXPECT_EQ(0, flags.getRD());
- EXPECT_EQ(1, flags.getRA());
- EXPECT_EQ(0, flags.getZ());
- EXPECT_EQ(0, flags.getAD());
- EXPECT_EQ(0, flags.getCD());
- EXPECT_EQ(0, flags.getRC());
+ flags.set(OptionInfo::RA, 1);
+ EXPECT_EQ(0, flags.get(OptionInfo::QR));
+ EXPECT_EQ(0, flags.get(OptionInfo::OP));
+ EXPECT_EQ(0, flags.get(OptionInfo::AA));
+ EXPECT_EQ(0, flags.get(OptionInfo::TC));
+ EXPECT_EQ(0, flags.get(OptionInfo::RD));
+ EXPECT_EQ(1, flags.get(OptionInfo::RA));
+ EXPECT_EQ(0, flags.get(OptionInfo::Z));
+ EXPECT_EQ(0, flags.get(OptionInfo::AD));
+ EXPECT_EQ(0, flags.get(OptionInfo::CD));
+ EXPECT_EQ(0, flags.get(OptionInfo::RC));
EXPECT_NE(0, flags.getValue());
- flags.setRA(0);
+ flags.set(OptionInfo::RA, 0);
checkZero(flags);
}
@@ -179,20 +180,20 @@ TEST_F(HeaderFlagsTest, Zfield) {
HeaderFlags flags;
checkZero(flags);
- flags.setZ(1);
- EXPECT_EQ(0, flags.getQR());
- EXPECT_EQ(0, flags.getOP());
- EXPECT_EQ(0, flags.getAA());
- EXPECT_EQ(0, flags.getTC());
- EXPECT_EQ(0, flags.getRD());
- EXPECT_EQ(0, flags.getRA());
- EXPECT_EQ(1, flags.getZ());
- EXPECT_EQ(0, flags.getAD());
- EXPECT_EQ(0, flags.getCD());
- EXPECT_EQ(0, flags.getRC());
+ flags.set(OptionInfo::Z, 1);
+ EXPECT_EQ(0, flags.get(OptionInfo::QR));
+ EXPECT_EQ(0, flags.get(OptionInfo::OP));
+ EXPECT_EQ(0, flags.get(OptionInfo::AA));
+ EXPECT_EQ(0, flags.get(OptionInfo::TC));
+ EXPECT_EQ(0, flags.get(OptionInfo::RD));
+ EXPECT_EQ(0, flags.get(OptionInfo::RA));
+ EXPECT_EQ(1, flags.get(OptionInfo::Z));
+ EXPECT_EQ(0, flags.get(OptionInfo::AD));
+ EXPECT_EQ(0, flags.get(OptionInfo::CD));
+ EXPECT_EQ(0, flags.get(OptionInfo::RC));
EXPECT_NE(0, flags.getValue());
- flags.setZ(0);
+ flags.set(OptionInfo::Z, 0);
checkZero(flags);
}
@@ -200,20 +201,20 @@ TEST_F(HeaderFlagsTest, ADfield) {
HeaderFlags flags;
checkZero(flags);
- flags.setAD(1);
- EXPECT_EQ(0, flags.getQR());
- EXPECT_EQ(0, flags.getOP());
- EXPECT_EQ(0, flags.getAA());
- EXPECT_EQ(0, flags.getTC());
- EXPECT_EQ(0, flags.getRD());
- EXPECT_EQ(0, flags.getRA());
- EXPECT_EQ(0, flags.getZ());
- EXPECT_EQ(1, flags.getAD());
- EXPECT_EQ(0, flags.getCD());
- EXPECT_EQ(0, flags.getRC());
+ flags.set(OptionInfo::AD, 1);
+ EXPECT_EQ(0, flags.get(OptionInfo::QR));
+ EXPECT_EQ(0, flags.get(OptionInfo::OP));
+ EXPECT_EQ(0, flags.get(OptionInfo::AA));
+ EXPECT_EQ(0, flags.get(OptionInfo::TC));
+ EXPECT_EQ(0, flags.get(OptionInfo::RD));
+ EXPECT_EQ(0, flags.get(OptionInfo::RA));
+ EXPECT_EQ(0, flags.get(OptionInfo::Z));
+ EXPECT_EQ(1, flags.get(OptionInfo::AD));
+ EXPECT_EQ(0, flags.get(OptionInfo::CD));
+ EXPECT_EQ(0, flags.get(OptionInfo::RC));
EXPECT_NE(0, flags.getValue());
- flags.setAD(0);
+ flags.set(OptionInfo::AD, 0);
checkZero(flags);
}
@@ -221,20 +222,20 @@ TEST_F(HeaderFlagsTest, CDfield) {
HeaderFlags flags;
checkZero(flags);
- flags.setCD(1);
- EXPECT_EQ(0, flags.getQR());
- EXPECT_EQ(0, flags.getOP());
- EXPECT_EQ(0, flags.getAA());
- EXPECT_EQ(0, flags.getTC());
- EXPECT_EQ(0, flags.getRD());
- EXPECT_EQ(0, flags.getRA());
- EXPECT_EQ(0, flags.getZ());
- EXPECT_EQ(0, flags.getAD());
- EXPECT_EQ(1, flags.getCD());
- EXPECT_EQ(0, flags.getRC());
+ flags.set(OptionInfo::CD, 1);
+ EXPECT_EQ(0, flags.get(OptionInfo::QR));
+ EXPECT_EQ(0, flags.get(OptionInfo::OP));
+ EXPECT_EQ(0, flags.get(OptionInfo::AA));
+ EXPECT_EQ(0, flags.get(OptionInfo::TC));
+ EXPECT_EQ(0, flags.get(OptionInfo::RD));
+ EXPECT_EQ(0, flags.get(OptionInfo::RA));
+ EXPECT_EQ(0, flags.get(OptionInfo::Z));
+ EXPECT_EQ(0, flags.get(OptionInfo::AD));
+ EXPECT_EQ(1, flags.get(OptionInfo::CD));
+ EXPECT_EQ(0, flags.get(OptionInfo::RC));
EXPECT_NE(0, flags.getValue());
- flags.setCD(0);
+ flags.set(OptionInfo::CD, 0);
checkZero(flags);
}
@@ -242,20 +243,20 @@ TEST_F(HeaderFlagsTest, RCfield) {
HeaderFlags flags;
checkZero(flags);
- flags.setRC(7);
- EXPECT_EQ(0, flags.getQR());
- EXPECT_EQ(0, flags.getOP());
- EXPECT_EQ(0, flags.getAA());
- EXPECT_EQ(0, flags.getTC());
- EXPECT_EQ(0, flags.getRD());
- EXPECT_EQ(0, flags.getRA());
- EXPECT_EQ(0, flags.getZ());
- EXPECT_EQ(0, flags.getAD());
- EXPECT_EQ(0, flags.getCD());
- EXPECT_EQ(7, flags.getRC());
+ flags.set(OptionInfo::RC, 15);
+ EXPECT_EQ(0, flags.get(OptionInfo::QR));
+ EXPECT_EQ(0, flags.get(OptionInfo::OP));
+ EXPECT_EQ(0, flags.get(OptionInfo::AA));
+ EXPECT_EQ(0, flags.get(OptionInfo::TC));
+ EXPECT_EQ(0, flags.get(OptionInfo::RD));
+ EXPECT_EQ(0, flags.get(OptionInfo::RA));
+ EXPECT_EQ(0, flags.get(OptionInfo::Z));
+ EXPECT_EQ(0, flags.get(OptionInfo::AD));
+ EXPECT_EQ(0, flags.get(OptionInfo::CD));
+ EXPECT_EQ(15, flags.get(OptionInfo::RC));
EXPECT_NE(0, flags.getValue());
- flags.setRC(0);
+ flags.set(OptionInfo::RC, 0);
checkZero(flags);
}
@@ -265,42 +266,42 @@ TEST_F(HeaderFlagsTest, bitValues) {
HeaderFlags flags;
checkZero(flags);
- flags.setQR(1);
+ flags.set(OptionInfo::QR, 1);
EXPECT_EQ(0x8000, flags.getValue());
- flags.setQR(0);
- flags.setOP(15);
+ flags.set(OptionInfo::QR, 0);
+ flags.set(OptionInfo::OP, 15);
EXPECT_EQ(0x7800, flags.getValue());
- flags.setOP(0);
- flags.setAA(1);
+ flags.set(OptionInfo::OP, 0);
+ flags.set(OptionInfo::AA, 1);
EXPECT_EQ(0x0400, flags.getValue());
- flags.setAA(0);
- flags.setTC(1);
+ flags.set(OptionInfo::AA, 0);
+ flags.set(OptionInfo::TC, 1);
EXPECT_EQ(0x0200, flags.getValue());
- flags.setTC(0);
- flags.setRD(1);
+ flags.set(OptionInfo::TC, 0);
+ flags.set(OptionInfo::RD, 1);
EXPECT_EQ(0x0100, flags.getValue());
- flags.setRD(0);
- flags.setRA(1);
+ flags.set(OptionInfo::RD, 0);
+ flags.set(OptionInfo::RA, 1);
EXPECT_EQ(0x0080, flags.getValue());
- flags.setRA(0);
- flags.setZ(1);
+ flags.set(OptionInfo::RA, 0);
+ flags.set(OptionInfo::Z, 1);
EXPECT_EQ(0x0040, flags.getValue());
- flags.setZ(0);
- flags.setAD(1);
+ flags.set(OptionInfo::Z, 0);
+ flags.set(OptionInfo::AD, 1);
EXPECT_EQ(0x0020, flags.getValue());
- flags.setAD(0);
- flags.setCD(1);
+ flags.set(OptionInfo::AD, 0);
+ flags.set(OptionInfo::CD, 1);
EXPECT_EQ(0x0010, flags.getValue());
- flags.setCD(0);
- flags.setRC(15);
+ flags.set(OptionInfo::CD, 0);
+ flags.set(OptionInfo::RC, 15);
EXPECT_EQ(0x000F, flags.getValue());
}
diff --git a/tests/tools/badpacket/tests/option_info_unittest.cc b/tests/tools/badpacket/tests/option_info_unittest.cc
new file mode 100644
index 0000000..cacb213
--- /dev/null
+++ b/tests/tools/badpacket/tests/option_info_unittest.cc
@@ -0,0 +1,154 @@
+// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <cstddef>
+#include <stdint.h>
+#include <gtest/gtest.h>
+
+#include "../option_info.h"
+
+using namespace isc::badpacket;
+
+
+// Test fixture class
+
+class OptionInfoTest : public ::testing::Test {
+public:
+ OptionInfoTest() {}
+};
+
+
+// Check the values are as expected
+
+TEST_F(OptionInfoTest, FlagValues) {
+ EXPECT_STREQ("qr", OptionInfo::name(OptionInfo::QR));
+ EXPECT_STREQ("qr", OptionInfo::name(OptionInfo::getIndex('Q')));
+ EXPECT_EQ(2, OptionInfo::word(OptionInfo::QR));
+ EXPECT_EQ(0x8000, OptionInfo::mask(OptionInfo::QR));
+ EXPECT_EQ(15, OptionInfo::offset(OptionInfo::QR));
+ EXPECT_EQ(0, OptionInfo::minval(OptionInfo::QR));
+ EXPECT_EQ(0, OptionInfo::defval(OptionInfo::QR));
+ EXPECT_EQ(1, OptionInfo::maxval(OptionInfo::QR));
+
+ EXPECT_STREQ("op", OptionInfo::name(OptionInfo::OP));
+ EXPECT_STREQ("op", OptionInfo::name(OptionInfo::getIndex('O')));
+ EXPECT_EQ(2, OptionInfo::word(OptionInfo::OP));
+ EXPECT_EQ(0x7800, OptionInfo::mask(OptionInfo::OP));
+ EXPECT_EQ(11, OptionInfo::offset(OptionInfo::OP));
+ EXPECT_EQ(0, OptionInfo::minval(OptionInfo::OP));
+ EXPECT_EQ(0, OptionInfo::defval(OptionInfo::OP));
+ EXPECT_EQ(15, OptionInfo::maxval(OptionInfo::OP));
+
+ EXPECT_STREQ("aa", OptionInfo::name(OptionInfo::AA));
+ EXPECT_STREQ("aa", OptionInfo::name(OptionInfo::getIndex('A')));
+ EXPECT_EQ(2, OptionInfo::word(OptionInfo::AA));
+ EXPECT_EQ(0x0400, OptionInfo::mask(OptionInfo::AA));
+ EXPECT_EQ(10, OptionInfo::offset(OptionInfo::AA));
+ EXPECT_EQ(0, OptionInfo::minval(OptionInfo::AA));
+ EXPECT_EQ(0, OptionInfo::defval(OptionInfo::AA));
+ EXPECT_EQ(1, OptionInfo::maxval(OptionInfo::AA));
+
+ EXPECT_STREQ("tc", OptionInfo::name(OptionInfo::TC));
+ EXPECT_STREQ("tc", OptionInfo::name(OptionInfo::getIndex('T')));
+ EXPECT_EQ(2, OptionInfo::word(OptionInfo::TC));
+ EXPECT_EQ(0x0200, OptionInfo::mask(OptionInfo::TC));
+ EXPECT_EQ(9, OptionInfo::offset(OptionInfo::TC));
+ EXPECT_EQ(0, OptionInfo::minval(OptionInfo::TC));
+ EXPECT_EQ(0, OptionInfo::defval(OptionInfo::TC));
+ EXPECT_EQ(1, OptionInfo::maxval(OptionInfo::TC));
+
+ EXPECT_STREQ("rd", OptionInfo::name(OptionInfo::RD));
+ EXPECT_STREQ("rd", OptionInfo::name(OptionInfo::getIndex('D')));
+ EXPECT_EQ(2, OptionInfo::word(OptionInfo::RD));
+ EXPECT_EQ(0x0100, OptionInfo::mask(OptionInfo::RD));
+ EXPECT_EQ(8, OptionInfo::offset(OptionInfo::RD));
+ EXPECT_EQ(0, OptionInfo::minval(OptionInfo::RD));
+ EXPECT_EQ(0, OptionInfo::defval(OptionInfo::RD));
+ EXPECT_EQ(1, OptionInfo::maxval(OptionInfo::RD));
+
+ EXPECT_STREQ("ra", OptionInfo::name(OptionInfo::RA));
+ EXPECT_STREQ("ra", OptionInfo::name(OptionInfo::getIndex('R')));
+ EXPECT_EQ(2, OptionInfo::word(OptionInfo::RA));
+ EXPECT_EQ(0x0080, OptionInfo::mask(OptionInfo::RA));
+ EXPECT_EQ(7, OptionInfo::offset(OptionInfo::RA));
+ EXPECT_EQ(0, OptionInfo::minval(OptionInfo::RA));
+ EXPECT_EQ(0, OptionInfo::defval(OptionInfo::RA));
+ EXPECT_EQ(1, OptionInfo::maxval(OptionInfo::RA));
+
+ EXPECT_STREQ("z", OptionInfo::name(OptionInfo::Z));
+ EXPECT_STREQ("z", OptionInfo::name(OptionInfo::getIndex('Z')));
+ EXPECT_EQ(2, OptionInfo::word(OptionInfo::Z));
+ EXPECT_EQ(0x0040, OptionInfo::mask(OptionInfo::Z));
+ EXPECT_EQ(6, OptionInfo::offset(OptionInfo::Z));
+ EXPECT_EQ(0, OptionInfo::minval(OptionInfo::Z));
+ EXPECT_EQ(0, OptionInfo::defval(OptionInfo::Z));
+ EXPECT_EQ(1, OptionInfo::maxval(OptionInfo::Z));
+
+ EXPECT_STREQ("ad", OptionInfo::name(OptionInfo::AD));
+ EXPECT_STREQ("ad", OptionInfo::name(OptionInfo::getIndex('U')));
+ EXPECT_EQ(2, OptionInfo::word(OptionInfo::AD));
+ EXPECT_EQ(0x0020, OptionInfo::mask(OptionInfo::AD));
+ EXPECT_EQ(5, OptionInfo::offset(OptionInfo::AD));
+ EXPECT_EQ(0, OptionInfo::minval(OptionInfo::AD));
+ EXPECT_EQ(0, OptionInfo::defval(OptionInfo::AD));
+ EXPECT_EQ(1, OptionInfo::maxval(OptionInfo::AD));
+
+ EXPECT_STREQ("cd", OptionInfo::name(OptionInfo::CD));
+ EXPECT_STREQ("cd", OptionInfo::name(OptionInfo::getIndex('C')));
+ EXPECT_EQ(2, OptionInfo::word(OptionInfo::CD));
+ EXPECT_EQ(0x0010, OptionInfo::mask(OptionInfo::CD));
+ EXPECT_EQ(4, OptionInfo::offset(OptionInfo::CD));
+ EXPECT_EQ(0, OptionInfo::minval(OptionInfo::CD));
+ EXPECT_EQ(0, OptionInfo::defval(OptionInfo::CD));
+ EXPECT_EQ(1, OptionInfo::maxval(OptionInfo::CD));
+
+ EXPECT_STREQ("rc", OptionInfo::name(OptionInfo::RC));
+ EXPECT_STREQ("rc", OptionInfo::name(OptionInfo::getIndex('E')));
+ EXPECT_EQ(2, OptionInfo::word(OptionInfo::RC));
+ EXPECT_EQ(0x000F, OptionInfo::mask(OptionInfo::RC));
+ EXPECT_EQ(0, OptionInfo::offset(OptionInfo::RC));
+ EXPECT_EQ(0, OptionInfo::minval(OptionInfo::RC));
+ EXPECT_EQ(0, OptionInfo::defval(OptionInfo::RC));
+ EXPECT_EQ(15, OptionInfo::maxval(OptionInfo::RC));
+}
+
+TEST_F(OptionInfoTest, CountValues) {
+ EXPECT_STREQ("qc", OptionInfo::name(OptionInfo::QC));
+ EXPECT_STREQ("qc", OptionInfo::name(OptionInfo::getIndex('Y')));
+ EXPECT_EQ(4, OptionInfo::word(OptionInfo::QC));
+ EXPECT_EQ(1, OptionInfo::defval(OptionInfo::QC));
+ EXPECT_EQ(0, OptionInfo::minval(OptionInfo::QC));
+ EXPECT_EQ(0xFFFF, OptionInfo::maxval(OptionInfo::QC));
+
+ EXPECT_STREQ("ac", OptionInfo::name(OptionInfo::AC));
+ EXPECT_STREQ("ac", OptionInfo::name(OptionInfo::getIndex('W')));
+ EXPECT_EQ(6, OptionInfo::word(OptionInfo::AC));
+ EXPECT_EQ(0, OptionInfo::defval(OptionInfo::AC));
+ EXPECT_EQ(0, OptionInfo::minval(OptionInfo::AC));
+ EXPECT_EQ(0xFFFF, OptionInfo::maxval(OptionInfo::AC));
+
+ EXPECT_STREQ("uc", OptionInfo::name(OptionInfo::UC));
+ EXPECT_STREQ("uc", OptionInfo::name(OptionInfo::getIndex('H')));
+ EXPECT_EQ(8, OptionInfo::word(OptionInfo::UC));
+ EXPECT_EQ(0, OptionInfo::defval(OptionInfo::UC));
+ EXPECT_EQ(0, OptionInfo::minval(OptionInfo::UC));
+ EXPECT_EQ(0xFFFF, OptionInfo::maxval(OptionInfo::UC));
+
+ EXPECT_STREQ("dc", OptionInfo::name(OptionInfo::DC));
+ EXPECT_STREQ("dc", OptionInfo::name(OptionInfo::getIndex('I')));
+ EXPECT_EQ(10, OptionInfo::word(OptionInfo::DC));
+ EXPECT_EQ(0, OptionInfo::defval(OptionInfo::DC));
+ EXPECT_EQ(0, OptionInfo::minval(OptionInfo::DC));
+ EXPECT_EQ(0xFFFF, OptionInfo::maxval(OptionInfo::DC));
+}
More information about the bind10-changes
mailing list