Commit d85912df authored by John DuBois's avatar John DuBois

[1324]

Added braces around some single-line if blocks missed in the previous
coding-guidelines changes
Further work on BIND9 style conformance, where it doesn't contradict BIND10
style.  Not yet complete.
Added comments in headers and source files
Added BIND10 headers to remaining files
Removed debugging code left in
Added more gtests, for option combinations
Removed files that are not part of currently tested code base
Addressed other requirements from code review (not yet complete)
parent 06d6be69
SUBDIRS = . tests
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
AM_CPPFLAGS += -I$(top_srcdir)/src/lib/log -I$(top_builddir)/src/lib/log
AM_CPPFLAGS += $(BOOST_INCLUDES)
AM_CXXFLAGS = $(B10_CXXFLAGS)
if USE_STATIC_LINK
AM_LDFLAGS = -static
endif
CLEANFILES = *.gcno *.gcda
noinst_PROGRAMS = perfdhcp
perfdhcp_SOURCES = perfdhcp.cc
perfdhcp_SOURCES += packetdisp.c
perfdhcp_SOURCES += externals.cc
perfdhcp_SOURCES += perfdhcp.h
perfdhcp_SOURCES += dhcp.h dhcp6.h
perfdhcp_SOURCES += cloptions.cc
perfdhcp_SOURCES += dkdebug.cc dkdebug.h
perfdhcp_SOURCES += procconf.h procconf.cc
perfdhcp_CXXFLAGS = $(AM_CXXFLAGS)
if USE_CLANGPP
perfdhcp_CXXFLAGS += -Wno-error
endif
......@@ -46,53 +46,56 @@ perfdhcp [-hv] [-4|-6] [-r<rate>] [-n<num-request>] [-p<test-period>]\n\
/* Names of configuration variables, for defaults file processor */
confvar_t optConf[] = {
{ 'h', NULL, CF_SWITCH, NULL, 0 },
{ 'v', NULL, CF_SWITCH, NULL, 0 },
{ '4', NULL, CF_SWITCH, &v4, 1 },
{ '6', NULL, CF_SWITCH, &v6, 1 },
{ 'i', NULL, CF_SWITCH, NULL, 1 },
{ 'l', NULL, CF_NE_STRING, &localName, 0 },
{ 'r', NULL, CF_POS_INT, NULL, 0 },
{ 'x', NULL, CF_STRING, NULL, 0 },
{ 'd', NULL, CF_POS_FLOAT, &dropTime, 0 },
{ 'D', NULL, CF_NE_STRING, &maxDropOpt, 0 },
{ 'n', NULL, CF_POS_INT, NULL, 0 },
{ 'p', NULL, CF_POS_FLOAT, &testPeriod, 0 },
{ '\0', NULL, CF_ENDLIST, NULL, 0 }
{ 'h', NULL, CF_SWITCH, NULL, 0 },
{ 'v', NULL, CF_SWITCH, NULL, 0 },
{ '4', NULL, CF_SWITCH, &v4, 1 },
{ '6', NULL, CF_SWITCH, &v6, 1 },
{ 'i', NULL, CF_SWITCH, NULL, 1 },
{ 'l', NULL, CF_NE_STRING, &localName, 0 },
{ 'r', NULL, CF_POS_INT, NULL, 0 },
{ 'x', NULL, CF_STRING, NULL, 0 },
{ 'd', NULL, CF_POS_FLOAT, &dropTime, 0 },
{ 'D', NULL, CF_NE_STRING, &maxDropOpt, 0 },
{ 'n', NULL, CF_POS_INT, NULL, 0 },
{ 'p', NULL, CF_POS_FLOAT, &testPeriod, 0 },
{ '\0', NULL, CF_ENDLIST, NULL, 0 }
};
/* Process command line options and config file */
msg = procOpts(&argc, &argv, optConf, confdata, NULL, progName, NULL);
msg = procOpts(&argc, &argv, optConf, confdata, progName, NULL);
if (msg != NULL) {
fprintf(stderr, "%s: %s\n", progName, msg);
return 2;
return(2);
}
if (confdata->map['h']->num > 0) {
printHelp(progName, usage);
return 0;
return(0);
}
if (confdata->map['v']->num > 0) {
printf("dhcpperf v1.0 2011-10-30\n");
return 0;
return(0);
}
if (v4 && v6) {
fprintf(stderr, "%s: Must not give -4 and -6 together.\n", progName);
return 2;
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",
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);
fprintf(stderr, "%s: Must specify a DHCP server.\n\%s\n",
progName, usage);
}
return 2;
return(2);
}
break;
case 1:
......@@ -100,9 +103,9 @@ perfdhcp [-hv] [-4|-6] [-r<rate>] [-n<num-request>] [-p<test-period>]\n\
break;
default:
fprintf(stderr, "%s: Too many arguments.\n\%s\n", progName, usage);
return 2;
return(2);
}
return 1;
return(1);
}
static void
......
/*
* 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
#include <stdint.h>
#include "procconf.h"
/*
* Process the options/arguments passed to the program.
*
* Input varibles:
* argc, argv: Command line data.
*
* Output variables:
* confdata; Processed command line data.
* server: The server to contact. This will always be set, either to the given
* value or to "all" (see usage).
*
* 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[], confdata_t* confdata,
const char** server);
#endif
......@@ -32,10 +32,10 @@ dk_setup(const char* diag_str, const struct dkdesc* diags) {
break;
}
if (diags[i].keyletter == '\0') {
return 0;
return(0);
}
}
return 1;
return(1);
}
void
......@@ -56,5 +56,5 @@ vdkprintf(unsigned diag_req, const char format[], va_list ap) {
int
dk_set(unsigned diag_req) {
return diag_req & dk_diag_mask;
return(diag_req & dk_diag_mask);
}
/*
* 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 DKDEBUG_H
#define DKDEBUG_H
#ifdef __cplusplus
extern "C" {
#endif
......@@ -19,3 +38,5 @@ 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.
#include "perfdhcp.h"
#include "cloptions.h"
int v6 = 0;
int initialOnly = 0;
const char *localName = NULL;
unsigned rate = 0;
unsigned numRequest = 0;
const char *server = NULL;
const char *diagSelector = "";
/*
* 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 <unistd.h>
#include <strings.h>
#include <string.h>
#include "perfdhcp.h"
#include "dkdebug.h"
static const char * enum_lookup(const char * const table[], size_t size, unsigned index);
static const char *optionName(int v6, unsigned optnum);
static void printOption(int v6, unsigned optnum, size_t len, const unsigned char *value);
static void print_dhcpv4_packet(const struct dhcp_packet *pkt, size_t len);
static void print_dhcpv6_packet(const struct dhcpv6_packet *pkt, size_t len);
typedef enum {
T_UNK,
T_STRING,
T_PERIOD,
T_IPADDR,
T_MTYPE,
T_STATUS
} opt_type;
struct dhcp_option_desc {
char *name;
opt_type type;
};
static struct dhcp_option_desc option_desc[] = {
[DHO_PAD] = { "PAD", T_UNK },
[DHO_SUBNET_MASK] = { "SUBNET_MASK", T_UNK },
[DHO_TIME_OFFSET] = { "TIME_OFFSET", T_PERIOD },
[DHO_ROUTERS] = { "ROUTERS", T_IPADDR },
[DHO_TIME_SERVERS] = { "TIME_SERVERS", T_UNK },
[DHO_NAME_SERVERS] = { "NAME_SERVERS", T_UNK },
[DHO_DOMAIN_NAME_SERVERS] = { "DOMAIN_NAME_SERVERS", T_IPADDR },
[DHO_LOG_SERVERS] = { "LOG_SERVERS", T_UNK },
[DHO_COOKIE_SERVERS] = { "COOKIE_SERVERS", T_UNK },
[DHO_LPR_SERVERS] = { "LPR_SERVERS", T_IPADDR },
[DHO_IMPRESS_SERVERS] = { "IMPRESS_SERVERS", T_UNK },
[DHO_RESOURCE_LOCATION_SERVERS] = { "RESOURCE_LOCATION_SERVERS", T_UNK },
[DHO_HOST_NAME] = { "HOST_NAME", T_UNK },
[DHO_BOOT_SIZE] = { "BOOT_SIZE", T_UNK },
[DHO_MERIT_DUMP] = { "MERIT_DUMP", T_UNK },
[DHO_DOMAIN_NAME] = { "DOMAIN_NAME", T_STRING },
[DHO_SWAP_SERVER] = { "SWAP_SERVER", T_UNK },
[DHO_ROOT_PATH] = { "ROOT_PATH", T_UNK },
[DHO_EXTENSIONS_PATH] = { "EXTENSIONS_PATH", T_UNK },
[DHO_IP_FORWARDING] = { "IP_FORWARDING", T_UNK },
[DHO_NON_LOCAL_SOURCE_ROUTING] = { "NON_LOCAL_SOURCE_ROUTING", T_UNK },
[DHO_POLICY_FILTER] = { "POLICY_FILTER", T_UNK },
[DHO_MAX_DGRAM_REASSEMBLY] = { "MAX_DGRAM_REASSEMBLY", T_UNK },
[DHO_DEFAULT_IP_TTL] = { "DEFAULT_IP_TTL", T_UNK },
[DHO_PATH_MTU_AGING_TIMEOUT] = { "PATH_MTU_AGING_TIMEOUT", T_UNK },
[DHO_PATH_MTU_PLATEAU_TABLE] = { "PATH_MTU_PLATEAU_TABLE", T_UNK },
[DHO_INTERFACE_MTU] = { "INTERFACE_MTU", T_UNK },
[DHO_ALL_SUBNETS_LOCAL] = { "ALL_SUBNETS_LOCAL", T_UNK },
[DHO_BROADCAST_ADDRESS] = { "BROADCAST_ADDRESS", T_UNK },
[DHO_PERFORM_MASK_DISCOVERY] = { "PERFORM_MASK_DISCOVERY", T_UNK },
[DHO_MASK_SUPPLIER] = { "MASK_SUPPLIER", T_UNK },
[DHO_ROUTER_DISCOVERY] = { "ROUTER_DISCOVERY", T_UNK },
[DHO_ROUTER_SOLICITATION_ADDRESS] = { "ROUTER_SOLICITATION_ADDRESS", T_UNK },
[DHO_STATIC_ROUTES] = { "STATIC_ROUTES", T_UNK },
[DHO_TRAILER_ENCAPSULATION] = { "TRAILER_ENCAPSULATION", T_UNK },
[DHO_ARP_CACHE_TIMEOUT] = { "ARP_CACHE_TIMEOUT", T_UNK },
[DHO_IEEE802_3_ENCAPSULATION] = { "IEEE802_3_ENCAPSULATION", T_UNK },
[DHO_DEFAULT_TCP_TTL] = { "DEFAULT_TCP_TTL", T_UNK },
[DHO_TCP_KEEPALIVE_INTERVAL] = { "TCP_KEEPALIVE_INTERVAL", T_UNK },
[DHO_TCP_KEEPALIVE_GARBAGE] = { "TCP_KEEPALIVE_GARBAGE", T_UNK },
[DHO_NIS_DOMAIN] = { "NIS_DOMAIN", T_UNK },
[DHO_NIS_SERVERS] = { "NIS_SERVERS", T_UNK },
[DHO_NTP_SERVERS] = { "NTP_SERVERS", T_IPADDR },
[DHO_VENDOR_ENCAPSULATED_OPTIONS] = { "VENDOR_ENCAPSULATED_OPTIONS", T_UNK },
[DHO_NETBIOS_NAME_SERVERS] = { "NETBIOS_NAME_SERVERS", T_UNK },
[DHO_NETBIOS_DD_SERVER] = { "NETBIOS_DD_SERVER", T_UNK },
[DHO_NETBIOS_NODE_TYPE] = { "NETBIOS_NODE_TYPE", T_UNK },
[DHO_NETBIOS_SCOPE] = { "NETBIOS_SCOPE", T_UNK },
[DHO_FONT_SERVERS] = { "FONT_SERVERS", T_UNK },
[DHO_X_DISPLAY_MANAGER] = { "X_DISPLAY_MANAGER", T_UNK },
[DHO_DHCP_REQUESTED_ADDRESS] = { "DHCP_REQUESTED_ADDRESS", T_IPADDR },
[DHO_DHCP_LEASE_TIME] = { "DHCP_LEASE_TIME", T_PERIOD },
[DHO_DHCP_OPTION_OVERLOAD] = { "DHCP_OPTION_OVERLOAD", T_UNK },
[DHO_DHCP_MESSAGE_TYPE] = { "DHCP_MESSAGE_TYPE", T_MTYPE },
[DHO_DHCP_SERVER_IDENTIFIER] = { "DHCP_SERVER_IDENTIFIER", T_UNK },
[DHO_DHCP_PARAMETER_REQUEST_LIST] = { "DHCP_PARAMETER_REQUEST_LIST", T_UNK },
[DHO_DHCP_MESSAGE] = { "DHCP_MESSAGE", T_UNK },
[DHO_DHCP_MAX_MESSAGE_SIZE] = { "DHCP_MAX_MESSAGE_SIZE", T_UNK },
[DHO_DHCP_RENEWAL_TIME] = { "DHCP_RENEWAL_TIME", T_UNK },
[DHO_DHCP_REBINDING_TIME] = { "DHCP_REBINDING_TIME", T_UNK },
[DHO_VENDOR_CLASS_IDENTIFIER] = { "VENDOR_CLASS_IDENTIFIER", T_UNK },
[DHO_DHCP_CLIENT_IDENTIFIER] = { "DHCP_CLIENT_IDENTIFIER", T_UNK },
[DHO_NWIP_DOMAIN_NAME] = { "NWIP_DOMAIN_NAME", T_UNK },
[DHO_NWIP_SUBOPTIONS] = { "NWIP_SUBOPTIONS", T_UNK },
[DHO_USER_CLASS] = { "USER_CLASS", T_UNK },
[DHO_USER_CLASS] = { "USER_CLASS", T_UNK },
[DHO_FQDN] = { "FQDN", T_UNK },
[DHO_DHCP_AGENT_OPTIONS] = { "DHCP_AGENT_OPTIONS", T_UNK },
[DHO_AUTHENTICATE] = { "AUTHENTICATE", T_UNK },
[DHO_CLIENT_LAST_TRANSACTION_TIME] = { "CLIENT_LAST_TRANSACTION_TIME", T_UNK },
[DHO_ASSOCIATED_IP] = { "ASSOCIATED_IP", T_UNK },
[DHO_SUBNET_SELECTION] = { "SUBNET_SELECTION", T_UNK },
[DHO_DOMAIN_SEARCH] = { "DOMAIN_SEARCH", T_UNK },
[DHO_VIVCO_SUBOPTIONS] = { "VIVCO_SUBOPTIONS", T_UNK },
[DHO_VIVSO_SUBOPTIONS] = { "VIVSO_SUBOPTIONS", T_UNK },
[DHO_END] = { "END", T_UNK },
[64] = { "NIS Domain", T_UNK },
[65] = { "NIS Servers", T_UNK },
[66] = { "TFTP Server", T_UNK },
[67] = { "Bootfile name", T_UNK },
[68] = { "Mobile IP Home Agent", T_UNK },
[69] = { "SMTP Server", T_IPADDR },
[70] = { "POP Server", T_IPADDR },
[71] = { "NNTP Server", T_IPADDR },
[72] = { "WWW Server", T_IPADDR },
[73] = { "Finger Server", T_IPADDR },
[74] = { "IRC Server", T_IPADDR },
[75] = { "StreetTalk Server", T_IPADDR },
[76] = { "StreetTalk Directory Assistance Server", T_IPADDR }
};
static const char * const message_types[] = {
[DHCPDISCOVER] = "DHCPDISCOVER",
[DHCPOFFER] = "DHCPOFFER",
[DHCPREQUEST] = "DHCPREQUEST",
[DHCPDECLINE] = "DHCPDECLINE",
[DHCPACK] = "DHCPACK",
[DHCPNAK] = "DHCPNAK",
[DHCPRELEASE] = "DHCPRELEASE",
[DHCPINFORM] = "DHCPINFORM",
[DHCPLEASEQUERY] = "DHCPLEASEQUERY",
[DHCPLEASEUNASSIGNED] = "DHCPLEASEUNASSIGNED",
[DHCPLEASEUNKNOWN] = "DHCPLEASEUNKNOWN",
[DHCPLEASEACTIVE] = "DHCPLEASEACTIVE"
};
static struct dhcp_option_desc option6_desc[] = {
[D6O_CLIENTID] = { "D6O_CLIENTID", T_UNK },
[D6O_SERVERID] = { "D6O_SERVERID", T_UNK },
[D6O_IA_NA] = { "D6O_IA_NA", T_UNK },
[D6O_IA_TA] = { "D6O_IA_TA", T_UNK },
[D6O_IAADDR] = { "D6O_IAADDR", T_UNK },
[D6O_ORO] = { "D6O_ORO", T_UNK },
[D6O_PREFERENCE] = { "D6O_PREFERENCE", T_UNK },
[D6O_ELAPSED_TIME] = { "D6O_ELAPSED_TIME", T_PERIOD },
[D6O_RELAY_MSG] = { "D6O_RELAY_MSG", T_UNK },
[D6O_AUTH] = { "D6O_AUTH", T_UNK },
[D6O_UNICAST] = { "D6O_UNICAST", T_UNK },
[D6O_STATUS_CODE] = { "D6O_STATUS_CODE", T_STATUS },
[D6O_RAPID_COMMIT] = { "D6O_RAPID_COMMIT", T_UNK },
[D6O_USER_CLASS] = { "D6O_USER_CLASS", T_UNK },
[D6O_VENDOR_CLASS] = { "D6O_VENDOR_CLASS", T_UNK },
[D6O_VENDOR_OPTS] = { "D6O_VENDOR_OPTS", T_UNK },
[D6O_INTERFACE_ID] = { "D6O_INTERFACE_ID", T_UNK },
[D6O_RECONF_MSG] = { "D6O_RECONF_MSG", T_UNK },
[D6O_RECONF_ACCEPT] = { "D6O_RECONF_ACCEPT", T_UNK },
[D6O_SIP_SERVERS_DNS] = { "D6O_SIP_SERVERS_DNS", T_UNK },
[D6O_SIP_SERVERS_ADDR] = { "D6O_SIP_SERVERS_ADDR", T_UNK },
[D6O_NAME_SERVERS] = { "D6O_NAME_SERVERS", T_IPADDR },
[D6O_DOMAIN_SEARCH] = { "D6O_DOMAIN_SEARCH", T_UNK },
[D6O_IA_PD] = { "D6O_IA_PD", T_UNK },
[D6O_IAPREFIX] = { "D6O_IAPREFIX", T_UNK },
[D6O_NIS_SERVERS] = { "D6O_NIS_SERVERS", T_UNK },
[D6O_NISP_SERVERS] = { "D6O_NISP_SERVERS", T_UNK },
[D6O_NIS_DOMAIN_NAME] = { "D6O_NIS_DOMAIN_NAME", T_UNK },
[D6O_NISP_DOMAIN_NAME] = { "D6O_NISP_DOMAIN_NAME", T_UNK },
[D6O_SNTP_SERVERS] = { "D6O_SNTP_SERVERS", T_UNK },
[D6O_INFORMATION_REFRESH_TIME] = { "D6O_INFORMATION_REFRESH_TIME", T_UNK },
[D6O_BCMCS_SERVER_D] = { "D6O_BCMCS_SERVER_D", T_UNK },
[D6O_BCMCS_SERVER_A] = { "D6O_BCMCS_SERVER_A", T_UNK },
[D6O_GEOCONF_CIVIC] = { "D6O_GEOCONF_CIVIC", T_UNK },
[D6O_REMOTE_ID] = { "D6O_REMOTE_ID", T_UNK },
[D6O_SUBSCRIBER_ID] = { "D6O_SUBSCRIBER_ID", T_UNK },
[D6O_CLIENT_FQDN] = { "D6O_CLIENT_FQDN", T_UNK },
[D6O_PANA_AGENT] = { "D6O_PANA_AGENT", T_UNK },
[D6O_NEW_POSIX_TIMEZONE] = { "D6O_NEW_POSIX_TIMEZONE", T_UNK },
[D6O_NEW_TZDB_TIMEZONE] = { "D6O_NEW_TZDB_TIMEZONE", T_UNK },
[D6O_ERO] = { "D6O_ERO", T_UNK },
[D6O_LQ_QUERY] = { "D6O_LQ_QUERY", T_UNK },
[D6O_CLIENT_DATA] = { "D6O_CLIENT_DATA", T_UNK },
[D6O_CLT_TIME] = { "D6O_CLT_TIME", T_UNK },
[D6O_LQ_RELAY_DATA] = { "D6O_LQ_RELAY_DATA", T_UNK },
[D6O_LQ_CLIENT_LINK] = { "D6O_LQ_CLIENT_LINK", T_UNK }
};
static const char * const message6_types[] = {
[DHCPV6_SOLICIT] = "DHCPV6_SOLICIT",
[DHCPV6_ADVERTISE] = "DHCPV6_ADVERTISE",
[DHCPV6_REQUEST] = "DHCPV6_REQUEST",
[DHCPV6_CONFIRM] = "DHCPV6_CONFIRM",
[DHCPV6_RENEW] = "DHCPV6_RENEW",
[DHCPV6_REBIND] = "DHCPV6_REBIND",
[DHCPV6_REPLY] = "DHCPV6_REPLY",
[DHCPV6_RELEASE] = "DHCPV6_RELEASE",
[DHCPV6_DECLINE] = "DHCPV6_DECLINE",
[DHCPV6_RECONFIGURE] = "DHCPV6_RECONFIGURE",
[DHCPV6_INFORMATION_REQUEST] = "DHCPV6_INFORMATION_REQUEST",
[DHCPV6_RELAY_FORW] = "DHCPV6_RELAY_FORW",
[DHCPV6_RELAY_REPL] = "DHCPV6_RELAY_REPL",
[DHCPV6_LEASEQUERY] = "DHCPV6_LEASEQUERY",
[DHCPV6_LEASEQUERY_REPLY] = "DHCPV6_LEASEQUERY_REPLY"
};
static const char * const status_codes[] = {
[STATUS_Success] = "Success",
[STATUS_UnspecFail] = "UnspecFail",
[STATUS_NoAddrsAvail] = "NoAddrsAvail",
[STATUS_NoBinding] = "NoBinding",
[STATUS_NotOnLink] = "NotOnLink",
[STATUS_UseMulticast] = "UseMulticast",
[STATUS_NoPrefixAvail] = "NoPrefixAvail",
[STATUS_UnknownQueryType] = "UnknownQueryType",
[STATUS_MalformedQuery] = "MalformedQuery",
[STATUS_NotConfigured] = "NotConfigured",
[STATUS_NotAllowed] = "NotAllowed",
};
void
print_dhcp_packet(int v6, const void *pkt, size_t len)
{
if (v6)
print_dhcpv6_packet((struct dhcpv6_packet *)pkt, len);
else
print_dhcpv4_packet((struct dhcp_packet *)pkt, len);
if (dk_set(DK_PACKET)) {
unsigned i;
fprintf(stderr, "Raw packet contents (%zu bytes):\n", len);
for (i = 0; i < len; i++)
fprintf(stderr, "%02x ", ((unsigned char *)pkt)[i]);
fputc('\n', stderr);
}
}
/*
* Note: Not reentrant
*/
static const char *
enum_lookup(const char * const table[], size_t size, unsigned index)
{
static char numbuf[10];
if (index < (size / sizeof(char *)) && table[index] != NULL)
return table[index];
else {
snprintf(numbuf, sizeof(numbuf), "%u", index);
return numbuf;
}
}
/*
* Note: Not reentrant
*/
static const char *
optionName(int v6, unsigned optnum)
{
static char numbuf[16];
unsigned maxOpt = ((v6 ? sizeof(option6_desc) : sizeof(option_desc)) - 1) /
sizeof(struct dhcp_option_desc);
struct dhcp_option_desc *descTable;
if (optnum > maxOpt) {
snprintf(numbuf, sizeof(numbuf), "invalid (%u)", optnum);
return numbuf;
}
descTable = v6 ? option6_desc : option_desc;
if (descTable[optnum].name == NULL) {
snprintf(numbuf, sizeof(numbuf), "%u", optnum);
return numbuf;
}
else
return descTable[optnum].name;
}
/*
*
* Output variables: None
*/
static void
printOption(int v6, unsigned optnum, size_t len, const unsigned char *value)
{
struct dhcp_option_desc *descTable = v6 ? option6_desc : option_desc;
char buf[ADDR_NAME_BUFSIZE];
unsigned i;
unsigned maxOpt = ((v6 ? sizeof(option6_desc) : sizeof(option_desc)) - 1) / sizeof(struct dhcp_option_desc);
unsigned statusCode;
fprintf(stderr, "Option %s (%d) length %zu value ", optionName(v6, optnum), optnum, len);
switch (optnum > maxOpt ? T_UNK : descTable[optnum].type) {
case T_STRING:
fprintf(stderr, "\"%.*s\"\n", (int) len, value);
break;
case T_PERIOD:
fprintf(stderr, "%d seconds\n", ntohl(*(int *)value));
break;
case T_MTYPE:
fprintf(stderr, "%s\n", enum_lookup(message_types, sizeof(message_types), *value));
break;
case T_IPADDR:
for (i = 0; len - i >= 4; i += 4)
fprintf(stderr, "%s%s", addrtoa(AF_INET, (struct in_addr *)(value+i), buf), len - i > 4 ? ", " : "\n");
break;
case T_STATUS:
statusCode = ntohs(*(uint16_t *)value);
fprintf(stderr, "%s: %*.*s\n",
enum_lookup(status_codes, sizeof(status_codes), statusCode),
(int)len - 2, (int)len - 2, value + 2);
break;
default:
for (i = 0; i < len; i++)
fprintf(stderr, "%02x", value[i]);
fputc('\n', stderr);
break;
}
}
static void
print_dhcpv4_packet(const struct dhcp_packet *pkt, size_t msglen)
{
int i;
const unsigned char *p;
aaddr_buf buf1, buf2, buf3, buf4;
fprintf(stderr,
"opcode %u\n\
htype %u\n\
hlen %u\n\
hops %u\n\
xid 0x%0x\n\
secs %u\n\
flags 0x%x\n\
ciaddr %s\n\
yiaddr %s\n\
siaddr %s\n\
giaddr %s\n\
chaddr ",
pkt->op,
pkt->htype,
pkt->hlen,
pkt->hops,
pkt->xid,
pkt->secs,
pkt->flags,
addrtoa(AF_INET, &pkt->ciaddr, buf1),
addrtoa(AF_INET, &pkt->yiaddr, buf2),
addrtoa(AF_INET, &pkt->siaddr, buf3),
addrtoa(AF_INET, &pkt->giaddr, buf4));
for (i = 0; i < pkt->hlen; i++)
fprintf(stderr, "%02x", pkt->chaddr[i]);
fputc('\n', stderr);
fprintf(stderr, "magic 0x%x\n", *(unsigned int *)&pkt->options);
p = &pkt->options[4];
while ((unsigned) (p - (unsigned char *)pkt) < msglen && *p != DHO_END) {
if (*p == DHO_PAD) {
fprintf(stderr, "Option PAD\n");
p++;
}
else {
unsigned optnum = *p++;
size_t len = *p++;
printOption(0, optnum, len, p);
p += len;
}
}
}
static void