Commit fc0a3168 authored by John DuBois's avatar John DuBois

[master]Revert "Merge branch 'master' of ssh://git.bind10.isc.org/var/bind10/git/bind10"

This reverts commit 8f74718c, reversing
changes made to 956a0a58.
parent 8f74718c
......@@ -935,8 +935,6 @@ AC_CONFIG_FILES([Makefile
tests/tools/Makefile
tests/tools/badpacket/Makefile
tests/tools/badpacket/tests/Makefile
tests/tools/perfdhcp/Makefile
tests/tools/perfdhcp/tests/Makefile
])
AC_OUTPUT([doc/version.ent
src/bin/cfgmgr/b10-cfgmgr.py
......
SUBDIRS = badpacket perfdhcp
SUBDIRS = badpacket
/*
* 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 <stdio.h>
#include "procconf.h"
#include "perfdhcp.h"
#include "cloptions.h"
#include "dkdebug.h"
static void printHelp(const char* progName, const char* usage);
static void initialize(void);
// The current version information
const char* VERSION = "perfdhcp v1.0 2011-10-30";
static const char* PROGNAME = "perfdhcp";
static int v6 = 0; // DHCPv6 operation (-6)
static int initialOnly = 0; // Do only initial exchange (-i)
static unsigned rate = 0; // Request rate (-r)
static unsigned numRequest = 0; // Number of requests (-n)
static double dropTime = 0.0; // Response timeout (-d)
static double testPeriod = 0.0; // Test period (-p)
static const char* server = NULL; // Server to contact
static const char* maxDropOpt = NULL; // Max dropped responses (-D)
static const char* localName = NULL; // Local host/interface (-l)
/*
* Return value:
* 0 if the command has been satisfied and the program should exit 0.
* 2 for usage error, in which case an error message will have been printed.
* 1 if argument processing was successful and the program should continue.
*/
int
procArgs(int argc, const char* argv[]) {
char usage[] =
"Usage:\n\
perfdhcp [-hv] [-4|-6] [-r<rate>] [-n<num-request>] [-p<test-period>]\n\
[-d<drop-time>] [-D<max-drop>] [-l<local-addr|interface>] [-i]\n\
[-x<diagnostic-selector>] [server]\n";
int v4 = 0; /* DHCPv4 operation explicitly requested */
const char* msg; /* Failure message from procOpts() */
int help = 0; /* Help requested */
int versionReq = 0; /* Version requested */
const char* diagStr = NULL; /* Diagnostics requested (-x) */
/* option descriptions */
confvar_t optConf[] = {
{ 'h', NULL, CF_SWITCH, &help, 1 },
{ 'v', NULL, CF_SWITCH, &versionReq, 1 },
{ '4', NULL, CF_SWITCH, &v4, 1 },
{ '6', NULL, CF_SWITCH, &v6, 1 },
{ 'i', NULL, CF_SWITCH, &initialOnly, 1 },
{ 'l', NULL, CF_NE_STRING, &localName, 0 },
{ 'r', NULL, CF_POS_INT, &rate, 0 },
{ 'n', NULL, CF_POS_INT, &numRequest, 0 },
{ 'd', NULL, CF_POS_FLOAT, &dropTime, 0 },
{ 'p', NULL, CF_POS_FLOAT, &testPeriod, 0 },
{ 'D', NULL, CF_NE_STRING, &maxDropOpt, 0 },
{ 'x', NULL, CF_STRING, &diagStr, 0 },
{ '\0', NULL, CF_ENDLIST, NULL, 0 }
};
/* diagnostic map */
const struct dkdesc diagLetters[] = {
{ 's', DK_SOCK },
{ 'm', DK_MSG },
{ 'p', DK_PACKET },
{ 'a', DK_ALL },
{ '\0', 0 }
};
initialize();
/* Process command line options */
msg = procOpts(&argc, &argv, optConf, NULL, PROGNAME, NULL);
if (msg != NULL) {
fprintf(stderr, "%s: %s\n", PROGNAME, msg);
return(2);
}
if (help) {
printHelp(PROGNAME, usage);
return(0);
}
if (versionReq) {
printf("%s\n", VERSION);
return(0);
}
if (diagStr != NULL) {
char c;
if ((c = dk_setup(diagStr, diagLetters)) != '\0') {
fprintf(stderr,
"%s: Invalid selector character given with -x: '%c'\n",
PROGNAME, c);
return(2);
}
}
if (v4 && v6) {
fprintf(stderr, "%s: Must not give -4 and -6 together.\n", PROGNAME);
return(2);
}
switch (argc) {
case 0:
if (v6 && localName != NULL) {
server = "all";
} else {
if (v6) {
fprintf(stderr,
"%s: Use -l to specify an interface name.\n\%s\n",
PROGNAME, usage);
}
else {
fprintf(stderr, "%s: Must specify a DHCP server.\n\%s\n",
PROGNAME, usage);
}
return(2);
}
break;
case 1:
server = argv[0];
break;
default:
fprintf(stderr, "%s: Too many arguments.\n\%s\n", PROGNAME, usage);
return(2);
}
return(1);
}
/*
* Initialize values set by procArgs().
* Initialized though they are static to allow for repeated calls for testing.
*/
static void
initialize(void) {
v6 = 0;
initialOnly = 0;
rate = 0;
numRequest = 0;
dropTime = 0.0;
testPeriod = 0.0;
maxDropOpt = NULL;
localName = NULL;
server = NULL;
}
static void
printHelp(const char* progName, const char* usage) {
printf(
"%s: Execute a performance test against a DHCP server.\n\
%s\n\
The [server] argument is the name/address of the DHCP server to contact. \n\
For DHCPv4 operation, exchanges are initiated by transmitting a DHCP\n\
DISCOVER to this address. For DHCPv6 operation, exchanges are initiated\n\
by transmitting a DHCP SOLICIT to this address. In the DHCPv6 case, the\n\
special name \"all\" can be used to refer to\n\
All_DHCP_Relay_Agents_and_Servers (the multicast address FF02::1:2), or\n\
the special name \"servers\" to refer to All_DHCP_Servers (the multicast\n\
address FF05::1:3). The [server] argument is optional only in the case\n\
that -l is used to specify an interface, in which case [server] defaults\n\
to \"all\".\n\
\n\
Exchanges are initiated by transmitting a DHCP SOLICIT to\n\
All_DHCP_Relay_Agents_and_Servers (the multicast address FF02::1:2) via\n\
this interface.\n\
\n\
The default is to perform a single 4-way exchange, effectively pinging the\n\
server. The -r option is used to set up a performance test.\n\
\n\
Options:\n\
-4: DHCPv4 operation (default). This is incompatible with the -6 option.\n\
-6: DHCPv6 operation. This is incompatible with the -4 option.\n\
-h: Print this help.\n\
-i: Do only the initial part of an exchange: DO or SA, depending on\n\
whether -6 is given.\n\
-l<local-addr|interface>: For DHCPv4 operation, specify the local\n\
hostname/address to use when communicating with the server. By\n\
default, the interface address through which traffic would normally be\n\
routed to the server is used.\n\
For DHCPv6 operation, specify the name of the network interface via\n\
which exchanges are initiated. This must be specified unless a server\n\
name is given, in which case the interface through which traffic would\n\
normally be routed to the server is used.\n\
-r<rate>: Initiate <rate> DORA/SARR (or if -i is given, DO/SA) exchanges per\n\
second. A periodic report is generated showing the number of exchanges\n\
which were not completed, as well as the average response latency. The\n\
program continues until interrupted, at which point a final report is\n\
generated.\n\
-v: Report the version number of this program.\n\
-x<diagnostic-selector>: Include extended diagnostics in the output.\n\
<diagnostic-selector> is a string of characters, each specifying an\n\
operation for which verbose output is desired. The selector characters\n\
are:\n\
[TO BE ADDED]\n\
\n\
The remaining options are used only in conjunction with -r:\n\
\n\
-d<drop-time>: Specify the time after which a request is treated as having\n\
been lost. The value is given in seconds and may contain a fractional\n\
component. The default is 1 second.\n\
-D<max-drop>: Abort the test if more than <max-drop> requests have been\n\
dropped. Use -D0 to abort if even a single request has been dropped. \n\
If <max-drop> includes the suffix \"%%\", it specifies a maximum\n\
percentage of requests that may be dropped before abort. In this\n\
case, testing of the threshold begins after 10 requests have been\n\
expected to be received.\n\
-n<num-request>: Initiate <num-request> transactions. No report is\n\
generated until all transactions have been initiated/waited-for, after\n\
which a report is generated and the program terminates.\n\
-p<test-period>: Send requests for the given test period, which is\n\
specified in the same manner as -d. This can be used as an\n\
alternative to -n, or both options can be given, in which case the\n\
testing is completed when either limit is reached.\n\
\n\
Exit status:\n\
The exit status is:\n\
0 on complete success.\n\
1 for a general error.\n\
2 if an error is found in the command line arguments.\n\
3 if there are no general failures in operation, but one or more exchanges\n\
are not successfully completed.\n",
progName, usage);
}
int
isV6(void) {
return v6;
}
int
getInitialOnly(void) {
return initialOnly;
}
unsigned
getRate(void) {
return rate;
}
unsigned
getNumRequest(void) {
return numRequest;
}
double
getDropTime(void) {
return dropTime;
}
double
getTestPeriod(void) {
return testPeriod;
}
const char *
getServer(void) {
return server;
}
const char *
getLocalName(void) {
return localName;
}
const char *
getMaxDrop(void) {
return maxDropOpt;
}
/*
* 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 CLOPTIONS_H
#define CLOPTIONS_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include "procconf.h"
/*
* Process the options/arguments passed to the program.
*
* Input varibles:
* argc, argv: Command line data.
*
* Return value:
* 0 if the command has been satisfied and the program should exit 0.
* 2 for usage error, in which case an error message will have been printed.
* 1 if argument processing was successful and the program should continue.
*/
int procArgs(int argc, const char* argv[]);
/*
* These functions return values set by command line options
*/
int isV6(void); // DHCPv6 operation (-6)
int getInitialOnly(void); // Do only initial exchange (-i)
unsigned getRate(void); // Request rate (-r)
unsigned getNumRequest(void); // Number of requests (-n)
double getDropTime(void); // Response timeout (-d)
double getTestPeriod(void); // Test period (-p)
const char* getServer(void); // Server to contact
const char* getLocalName(void); // Local host/interface (-l)
const char* getMaxDrop(void); // Max dropped responses (-D)
#ifdef __cplusplus
}
#endif
#endif
/*
* 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 <stdio.h>
#include <stdarg.h>
#include "dkdebug.h"
/*
* The set of diagnostic bits set by dk_setup(), and used by the other
* functions to test offered diagnostics against.
*/
static unsigned dk_diag_mask = 0;
char
dk_setup(const char* diag_str, const struct dkdesc* diags) {
dk_diag_mask = 0;
int i;
for (; *diag_str != '\0'; diag_str++) {
for (i = 0; diags[i].keyletter != '\0'; i++) {
if (diags[i].keyletter == *diag_str) {
dk_diag_mask |= diags[i].mask;
break;
}
}
if (diags[i].keyletter == '\0') {
return(*diag_str);
}
}
return('\0');
}
void
dkprintf(unsigned diag_req, const char format[], ...) {
va_list ap;
va_start(ap,format);
vdkprintf(diag_req, format, ap);
va_end(ap);
}
void
vdkprintf(unsigned diag_req, const char format[], va_list ap) {
if (diag_req & dk_diag_mask) {
vfprintf(stderr, format, ap);
}
}
int
dk_set(unsigned diag_req) {
return((diag_req & dk_diag_mask) != 0);
}
/*
* 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.
*/
/*
* This module implements a mask-style diagnostic printing/selection system.
* Each diagnostic is enabled by including an associated keyletter in a
* selector string given at initialization time (typically as a command-line
* option).
*/
#ifndef DKDEBUG_H
#define DKDEBUG_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdarg.h>
#define DK_ALL (~0), /* Select all diagnostics */
/*
* Elements of this type are used to map the available diagnostic keyletters to
* mask bits.
*/
struct dkdesc {
char keyletter;
unsigned mask;
};
/*
* Initialize diagnostic mask.
*
* Input variables:
*
* diag_str is a string giving the keyletters for diagnostics to enable.
*
* diags describes the available diagnostics, mapping each keyletter to any
* number of mask bits. It should be terminated with an element with keyletter
* set to the null character.
*
* Return value:
* If an invalid character is given in diag_str, that character; otherwise a
* null character.
*/
char dk_setup(const char* diag_str, const struct dkdesc* diags);
/*
* The remaining functions test the mask bitset diag_req against the currently
* enabled diagnostics, as set by dk_setup(). If any bits set in diag_req are
* among the enabled diagnostics, the diagnostic operation is enabled.
*/
/*
* If diagnostic operation is enabled, use the remaining arguments to print
* like fprintf(stderr, )
*/
void dkprintf(unsigned diag_req, const char format[], ...);
/*
* If diagnostic operation is enabled, use the remaining arguments to print
* like vfprintf(stderr, )
*/
void vdkprintf(unsigned diag_req, const char format[], va_list ap);
/*
* If diagnostic operation is enabled, return 1; else return false.
*/
int dk_set(unsigned diag_req);
#ifdef __cplusplus
}
#endif
#endif
/*
* 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 PERFDHCP_H
#define PERFDHCP_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* The masks associated with keyletters, used in dkdesc structures for setup
* and passed in the diag_req argument to the output/test functions to
* determine which diagnostics they are enabled for.
*/
enum {
DK_SOCK = 1,
DK_MSG = 2,
DK_PACKET = 4
};
#ifdef __cplusplus
}
#endif
#endif
/*
* 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 <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <stdarg.h>
#include <unistd.h>
#include <errno.h>
#include "procconf.h"
static char errmsg[256]; /* for returning error descriptions */
static const char* pc_name;
static const char* pc_usage;
#define INTERNAL_ERROR -1
#define USAGE_ERROR -2
/*
* error: printf-style interface to print an error message or write it into
* global errmsg. If a usage message has been given (the indicator that errors
* should be handled internally), the message is printed to stderr and the
* program is exited. If not, it is written into errmsg.
* Input variables:
* errtype is the error type. If USAGE_ERROR, the program's usage is included
* in error messages, and the exit status is 2; otherwise the exit status
* is 1.
* format and the remaining arguments are as for printf().
*/
static void
error(const int errtype, const char* format, ...) {
va_list ap;
va_start(ap,format);
if (pc_usage != NULL) { /* error messages should be printed directly */
fprintf(stderr, "%s: ", pc_name);
vfprintf(stderr, format, ap);
putc('\n', stderr);
if (errtype == USAGE_ERROR) {
fputs(pc_usage, stderr);
}
exit(errtype == USAGE_ERROR ? 2 : 1);
} else {
vsnprintf(errmsg, sizeof(errmsg), format, ap);
}
va_end(ap);
}
/*
* Allocate memory, with error checking.
* On allocation failure, error() is called; see its description.
* The memory is zeroed before being returned.
*/
static void*
pc_malloc(size_t size) {
void* ret = calloc(1, size);
if (ret == NULL) {
error(INTERNAL_ERROR, "Out of memory");
}
return(ret);
}
/*
* Generate an error message describing an error in the value passed with an
* option. This is a front end for error(); see its usage for details.
* Input variables:
* expected: A description of what was expected for the value.
* varDesc: The descriptor for the option.
* value: The value that was given with the option.
* detail: If non-null, additional detail to append regardign the problem.
*/
static void
opterror(const char* expected, const char* value, const confvar_t* varDesc,
const char* detail) {
if (detail == NULL) {
detail = "";
}
error(USAGE_ERROR,
"Invalid value given for option -%c: expected %s, got: %s%s",
varDesc->outind, expected, value, detail);
}
/*