Commit 0ad9b8c8 authored by John DuBois's avatar John DuBois

[1324]

Addressed changes from code review.
Functional change: corrected use of EXPECT_EQ macros in tests.
parent 3a330862
......@@ -23,13 +23,18 @@
static void printHelp(const char* progName, const char* usage);
static void initialize(void);
// The current version information
static const char* version = "dhcpperf v1.0 2011-10-30";
const char progName[] = "dhcpperf";
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; // Server to contact
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)
......@@ -49,13 +54,13 @@ perfdhcp [-hv] [-4|-6] [-r<rate>] [-n<num-request>] [-p<test-period>]\n\
int v4 = 0; /* DHCPv4 operation explicitly requested */
const char* msg; /* Failure message from procOpts() */
int help = 0; /* Help requested */
int version = 0; /* Version 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, &version, 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 },
......@@ -90,8 +95,8 @@ perfdhcp [-hv] [-4|-6] [-r<rate>] [-n<num-request>] [-p<test-period>]\n\
printHelp(progName, usage);
return(0);
}
if (version) {
printf("dhcpperf v1.0 2011-10-30\n");
if (versionReq) {
printf("%s\n", version);
return(0);
}
if (diagStr != NULL) {
......@@ -149,6 +154,7 @@ initialize(void) {
testPeriod = 0.0;
maxDropOpt = NULL;
localName = NULL;
server = NULL;
}
static void
......@@ -230,46 +236,46 @@ The exit status is:\n\
}
int
getv6(void) {
isV6(void) {
return v6;
}
int
getinitialOnly(void) {
getInitialOnly(void) {
return initialOnly;
}
unsigned
getrate(void) {
getRate(void) {
return rate;
}
unsigned
getnumRequest(void) {
getNumRequest(void) {
return numRequest;
}
double
getdropTime(void) {
getDropTime(void) {
return dropTime;
}
double
gettestPeriod(void) {
getTestPeriod(void) {
return testPeriod;
}
const char *
getserver(void) {
getServer(void) {
return server;
}
const char *
getlocalName(void) {
getLocalName(void) {
return localName;
}
const char *
getmaxDrop(void) {
getMaxDrop(void) {
return maxDropOpt;
}
......@@ -36,14 +36,14 @@ int procArgs(int argc, const char* argv[]);
/*
* These functions return values set by command line options
*/
int getv6(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)
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)
#endif
/* dhcp.h
Protocol structures... */
/*
* Copyright (c) 2004-2009 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1995-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and 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.
*
* Internet Systems Consortium, Inc.
* 950 Charter Street
* Redwood City, CA 94063
* <info@isc.org>
* https://www.isc.org/
*
* This software has been written for Internet Systems Consortium
* by Ted Lemon in cooperation with Vixie Enterprises. To learn more
* about Internet Systems Consortium, see ``https://www.isc.org''.
* To learn more about Vixie Enterprises, see ``http://www.vix.com''.
*/
#ifndef DHCP_H
#define DHCP_H
#define DHCP_UDP_OVERHEAD (20 + /* IP header */ \
8) /* UDP header */
#define DHCP_SNAME_LEN 64
#define DHCP_FILE_LEN 128
#define DHCP_FIXED_NON_UDP 236
#define DHCP_FIXED_LEN (DHCP_FIXED_NON_UDP + DHCP_UDP_OVERHEAD)
/* Everything but options. */
#define BOOTP_MIN_LEN 300
#define DHCP_MTU_MAX 1500
#define DHCP_MTU_MIN 576
#define DHCP_MAX_OPTION_LEN (DHCP_MTU_MAX - DHCP_FIXED_LEN)
#define DHCP_MIN_OPTION_LEN (DHCP_MTU_MIN - DHCP_FIXED_LEN)
struct dhcp_packet {
u_int8_t op; /* 0: Message opcode/type */
u_int8_t htype; /* 1: Hardware addr type (net/if_types.h) */
u_int8_t hlen; /* 2: Hardware addr length */
u_int8_t hops; /* 3: Number of relay agent hops from client */
u_int32_t xid; /* 4: Transaction ID */
u_int16_t secs; /* 8: Seconds since client started looking */
u_int16_t flags; /* 10: Flag bits */
struct in_addr ciaddr; /* 12: Client IP address (if already in use) */
struct in_addr yiaddr; /* 16: Client IP address */
struct in_addr siaddr; /* 18: IP address of next server to talk to */
struct in_addr giaddr; /* 20: DHCP relay agent IP address */
unsigned char chaddr [16]; /* 24: Client hardware address */
char sname [DHCP_SNAME_LEN]; /* 40: Server name */
char file [DHCP_FILE_LEN]; /* 104: Boot filename */
unsigned char options [DHCP_MAX_OPTION_LEN];
/* 212: Optional parameters
(actual length dependent on MTU). */
};
/* BOOTP (rfc951) message types */
#define BOOTREQUEST 1
#define BOOTREPLY 2
/* Possible values for flags field... */
#define BOOTP_BROADCAST 32768L
/* Possible values for hardware type (htype) field... */
#define HTYPE_ETHER 1 /* Ethernet 10Mbps */
#define HTYPE_IEEE802 6 /* IEEE 802.2 Token Ring... */
#define HTYPE_FDDI 8 /* FDDI... */
/* Magic cookie validating dhcp options field (and bootp vendor
extensions field). */
#define DHCP_OPTIONS_COOKIE "\143\202\123\143"
/* DHCP Option codes: */
#define DHO_PAD 0
#define DHO_SUBNET_MASK 1
#define DHO_TIME_OFFSET 2
#define DHO_ROUTERS 3
#define DHO_TIME_SERVERS 4
#define DHO_NAME_SERVERS 5
#define DHO_DOMAIN_NAME_SERVERS 6
#define DHO_LOG_SERVERS 7
#define DHO_COOKIE_SERVERS 8
#define DHO_LPR_SERVERS 9
#define DHO_IMPRESS_SERVERS 10
#define DHO_RESOURCE_LOCATION_SERVERS 11
#define DHO_HOST_NAME 12
#define DHO_BOOT_SIZE 13
#define DHO_MERIT_DUMP 14
#define DHO_DOMAIN_NAME 15
#define DHO_SWAP_SERVER 16
#define DHO_ROOT_PATH 17
#define DHO_EXTENSIONS_PATH 18
#define DHO_IP_FORWARDING 19
#define DHO_NON_LOCAL_SOURCE_ROUTING 20
#define DHO_POLICY_FILTER 21
#define DHO_MAX_DGRAM_REASSEMBLY 22
#define DHO_DEFAULT_IP_TTL 23
#define DHO_PATH_MTU_AGING_TIMEOUT 24
#define DHO_PATH_MTU_PLATEAU_TABLE 25
#define DHO_INTERFACE_MTU 26
#define DHO_ALL_SUBNETS_LOCAL 27
#define DHO_BROADCAST_ADDRESS 28
#define DHO_PERFORM_MASK_DISCOVERY 29
#define DHO_MASK_SUPPLIER 30
#define DHO_ROUTER_DISCOVERY 31
#define DHO_ROUTER_SOLICITATION_ADDRESS 32
#define DHO_STATIC_ROUTES 33
#define DHO_TRAILER_ENCAPSULATION 34
#define DHO_ARP_CACHE_TIMEOUT 35
#define DHO_IEEE802_3_ENCAPSULATION 36
#define DHO_DEFAULT_TCP_TTL 37
#define DHO_TCP_KEEPALIVE_INTERVAL 38
#define DHO_TCP_KEEPALIVE_GARBAGE 39
#define DHO_NIS_DOMAIN 40
#define DHO_NIS_SERVERS 41
#define DHO_NTP_SERVERS 42
#define DHO_VENDOR_ENCAPSULATED_OPTIONS 43
#define DHO_NETBIOS_NAME_SERVERS 44
#define DHO_NETBIOS_DD_SERVER 45
#define DHO_NETBIOS_NODE_TYPE 46
#define DHO_NETBIOS_SCOPE 47
#define DHO_FONT_SERVERS 48
#define DHO_X_DISPLAY_MANAGER 49
#define DHO_DHCP_REQUESTED_ADDRESS 50
#define DHO_DHCP_LEASE_TIME 51
#define DHO_DHCP_OPTION_OVERLOAD 52
#define DHO_DHCP_MESSAGE_TYPE 53
#define DHO_DHCP_SERVER_IDENTIFIER 54
#define DHO_DHCP_PARAMETER_REQUEST_LIST 55
#define DHO_DHCP_MESSAGE 56
#define DHO_DHCP_MAX_MESSAGE_SIZE 57
#define DHO_DHCP_RENEWAL_TIME 58
#define DHO_DHCP_REBINDING_TIME 59
#define DHO_VENDOR_CLASS_IDENTIFIER 60
#define DHO_DHCP_CLIENT_IDENTIFIER 61
#define DHO_NWIP_DOMAIN_NAME 62
#define DHO_NWIP_SUBOPTIONS 63
#define DHO_USER_CLASS 77
#define DHO_FQDN 81
#define DHO_DHCP_AGENT_OPTIONS 82
#define DHO_AUTHENTICATE 90 /* RFC3118, was 210 */
#define DHO_CLIENT_LAST_TRANSACTION_TIME 91
#define DHO_ASSOCIATED_IP 92
#define DHO_SUBNET_SELECTION 118 /* RFC3011! */
#define DHO_DOMAIN_SEARCH 119 /* RFC3397 */
#define DHO_VIVCO_SUBOPTIONS 124
#define DHO_VIVSO_SUBOPTIONS 125
#define DHO_END 255
/* DHCP message types. */
#define DHCPDISCOVER 1
#define DHCPOFFER 2
#define DHCPREQUEST 3
#define DHCPDECLINE 4
#define DHCPACK 5
#define DHCPNAK 6
#define DHCPRELEASE 7
#define DHCPINFORM 8
#define DHCPLEASEQUERY 10
#define DHCPLEASEUNASSIGNED 11
#define DHCPLEASEUNKNOWN 12
#define DHCPLEASEACTIVE 13
/* Relay Agent Information option subtypes: */
#define RAI_CIRCUIT_ID 1
#define RAI_REMOTE_ID 2
#define RAI_AGENT_ID 3
#define RAI_LINK_SELECT 5
/* FQDN suboptions: */
#define FQDN_NO_CLIENT_UPDATE 1
#define FQDN_SERVER_UPDATE 2
#define FQDN_ENCODED 3
#define FQDN_RCODE1 4
#define FQDN_RCODE2 5
#define FQDN_HOSTNAME 6
#define FQDN_DOMAINNAME 7
#define FQDN_FQDN 8
#define FQDN_SUBOPTION_COUNT 8
/* Enterprise Suboptions: */
#define VENDOR_ISC_SUBOPTIONS 2495
#endif /* DHCP_H */
/* dhcp6.h
DHCPv6 Protocol structures... */
/*
* Copyright (c) 2006-2009 by Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and 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.
*
* Internet Systems Consortium, Inc.
* 950 Charter Street
* Redwood City, CA 94063
* <info@isc.org>
* https://www.isc.org/
*/
/* DHCPv6 Option codes: */
#define D6O_CLIENTID 1 /* RFC3315 */
#define D6O_SERVERID 2
#define D6O_IA_NA 3
#define D6O_IA_TA 4
#define D6O_IAADDR 5
#define D6O_ORO 6
#define D6O_PREFERENCE 7
#define D6O_ELAPSED_TIME 8
#define D6O_RELAY_MSG 9
/* Option code 10 unassigned. */
#define D6O_AUTH 11
#define D6O_UNICAST 12
#define D6O_STATUS_CODE 13
#define D6O_RAPID_COMMIT 14
#define D6O_USER_CLASS 15
#define D6O_VENDOR_CLASS 16
#define D6O_VENDOR_OPTS 17
#define D6O_INTERFACE_ID 18
#define D6O_RECONF_MSG 19
#define D6O_RECONF_ACCEPT 20
#define D6O_SIP_SERVERS_DNS 21 /* RFC3319 */
#define D6O_SIP_SERVERS_ADDR 22 /* RFC3319 */
#define D6O_NAME_SERVERS 23 /* RFC3646 */
#define D6O_DOMAIN_SEARCH 24 /* RFC3646 */
#define D6O_IA_PD 25 /* RFC3633 */
#define D6O_IAPREFIX 26 /* RFC3633 */
#define D6O_NIS_SERVERS 27 /* RFC3898 */
#define D6O_NISP_SERVERS 28 /* RFC3898 */
#define D6O_NIS_DOMAIN_NAME 29 /* RFC3898 */
#define D6O_NISP_DOMAIN_NAME 30 /* RFC3898 */
#define D6O_SNTP_SERVERS 31 /* RFC4075 */
#define D6O_INFORMATION_REFRESH_TIME 32 /* RFC4242 */
#define D6O_BCMCS_SERVER_D 33 /* RFC4280 */
#define D6O_BCMCS_SERVER_A 34 /* RFC4280 */
/* 35 is unassigned */
#define D6O_GEOCONF_CIVIC 36 /* RFC4776 */
#define D6O_REMOTE_ID 37 /* RFC4649 */
#define D6O_SUBSCRIBER_ID 38 /* RFC4580 */
#define D6O_CLIENT_FQDN 39 /* RFC4704 */
#define D6O_PANA_AGENT 40 /* paa-option */
#define D6O_NEW_POSIX_TIMEZONE 41 /* RFC4833 */
#define D6O_NEW_TZDB_TIMEZONE 42 /* RFC4833 */
#define D6O_ERO 43 /* RFC4994 */
#define D6O_LQ_QUERY 44 /* RFC5007 */
#define D6O_CLIENT_DATA 45 /* RFC5007 */
#define D6O_CLT_TIME 46 /* RFC5007 */
#define D6O_LQ_RELAY_DATA 47 /* RFC5007 */
#define D6O_LQ_CLIENT_LINK 48 /* RFC5007 */
/*
* Status Codes, from RFC 3315 section 24.4, and RFC 3633, 5007.
*/
#define STATUS_Success 0
#define STATUS_UnspecFail 1
#define STATUS_NoAddrsAvail 2
#define STATUS_NoBinding 3
#define STATUS_NotOnLink 4
#define STATUS_UseMulticast 5
#define STATUS_NoPrefixAvail 6
#define STATUS_UnknownQueryType 7
#define STATUS_MalformedQuery 8
#define STATUS_NotConfigured 9
#define STATUS_NotAllowed 10
/*
* DHCPv6 message types, defined in section 5.3 of RFC 3315
*/
#define DHCPV6_SOLICIT 1
#define DHCPV6_ADVERTISE 2
#define DHCPV6_REQUEST 3
#define DHCPV6_CONFIRM 4
#define DHCPV6_RENEW 5
#define DHCPV6_REBIND 6
#define DHCPV6_REPLY 7
#define DHCPV6_RELEASE 8
#define DHCPV6_DECLINE 9
#define DHCPV6_RECONFIGURE 10
#define DHCPV6_INFORMATION_REQUEST 11
#define DHCPV6_RELAY_FORW 12
#define DHCPV6_RELAY_REPL 13
#define DHCPV6_LEASEQUERY 14
#define DHCPV6_LEASEQUERY_REPLY 15
extern const char *dhcpv6_type_names[];
extern const int dhcpv6_type_name_max;
/* DUID type definitions (RFC3315 section 9).
*/
#define DUID_LLT 1
#define DUID_EN 2
#define DUID_LL 3
/* Offsets into IA_*'s where Option spaces commence. */
#define IA_NA_OFFSET 12 /* IAID, T1, T2, all 4 octets each */
#define IA_TA_OFFSET 4 /* IAID only, 4 octets */
#define IA_PD_OFFSET 12 /* IAID, T1, T2, all 4 octets each */
/* Offset into IAADDR's where Option spaces commence. */
#define IAADDR_OFFSET 24
/* Offset into IAPREFIX's where Option spaces commence. */
#define IAPREFIX_OFFSET 25
/* Offset into LQ_QUERY's where Option spaces commence. */
#define LQ_QUERY_OFFSET 17
/*
* DHCPv6 well-known multicast addressess, from section 5.1 of RFC 3315
*/
#define All_DHCP_Relay_Agents_and_Servers "FF02::1:2"
#define All_DHCP_Servers "FF05::1:3"
/*
* DHCPv6 Retransmission Constants (RFC3315 section 5.5, RFC 5007)
*/
#define SOL_MAX_DELAY 1
#define SOL_TIMEOUT 1
#define SOL_MAX_RT 120
#define REQ_TIMEOUT 1
#define REQ_MAX_RT 30
#define REQ_MAX_RC 10
#define CNF_MAX_DELAY 1
#define CNF_TIMEOUT 1
#define CNF_MAX_RT 4
#define CNF_MAX_RD 10
#define REN_TIMEOUT 10
#define REN_MAX_RT 600
#define REB_TIMEOUT 10
#define REB_MAX_RT 600
#define INF_MAX_DELAY 1
#define INF_TIMEOUT 1
#define INF_MAX_RT 120
#define REL_TIMEOUT 1
#define REL_MAX_RC 5
#define DEC_TIMEOUT 1
#define DEC_MAX_RC 5
#define REC_TIMEOUT 2
#define REC_MAX_RC 8
#define HOP_COUNT_LIMIT 32
#define LQ6_TIMEOUT 1
#define LQ6_MAX_RT 10
#define LQ6_MAX_RC 5
/*
* Normal packet format, defined in section 6 of RFC 3315
*/
struct dhcpv6_packet {
unsigned char msg_type;
unsigned char transaction_id[3];
unsigned char options[FLEXIBLE_ARRAY_MEMBER];
};
/* Offset into DHCPV6 Reply packets where Options spaces commence. */
#define REPLY_OPTIONS_INDEX 4
/*
* Relay packet format, defined in section 7 of RFC 3315
*/
struct dhcpv6_relay_packet {
unsigned char msg_type;
unsigned char hop_count;
unsigned char link_address[16];
unsigned char peer_address[16];
unsigned char options[FLEXIBLE_ARRAY_MEMBER];
};
/* Leasequery query-types (RFC 5007) */
#define LQ6QT_BY_ADDRESS 1
#define LQ6QT_BY_CLIENTID 2
/*
* DUID time starts 2000-01-01.
* This constant is the number of seconds since 1970-01-01,
* when the Unix epoch began.
*/
#define DUID_TIME_EPOCH 946684800
/* Information-Request Time option (RFC 4242) */
#define IRT_DEFAULT 86400
#define IRT_MINIMUM 600
......@@ -18,7 +18,11 @@
#include <stdarg.h>
#include "dkdebug.h"
unsigned dk_diag_mask;
/*
* The set of diagnostic bits set by dk_setup(), and used by the other
* functions to test offered diagnostics against.
*/
unsigned dk_diag_mask = 0;
char
dk_setup(const char* diag_str, const struct dkdesc* diags) {
......
......@@ -30,8 +30,7 @@ extern "C" {
#include <stdarg.h>
/* Use as the mask in a dkdesc structure to enable all diagnostics */
#define DK_ALL (~0)
#define DK_ALL (~0), /* Select all diagnostics */
/*
* Elements of this type are used to map the available diagnostic keyletters to
......
......@@ -21,11 +21,18 @@
extern "C" {
#endif
#define DK_SOCK 1
#define DK_MSG 2
#define DK_PACKET 4
extern const char progName[];
const char progName[] = "dhcpperf";
/*
* 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
}
......
......@@ -65,10 +65,11 @@ error(const int errtype, const char* format, ...) {
/*
* 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 = malloc(size);
void* ret = calloc(1, size);
if (ret == NULL) {
error(INTERNAL_ERROR, "Out of memory");
}
......@@ -107,9 +108,12 @@ opterror(const char* expected, const char* value, const confvar_t* varDesc,
*
* Output variables:
* The option data is stored in a malloced confval structure, which is appended
* to the option list pointed to by first. The 'next' element is set to NULL.
* last is used to track the last record in each option list, so option values
* can be appended easily.
* to the option list. The first element of the list is pointed to by first.
* first should be NULL if the list contains no elements; in this case it is
* set to point to the new structure. Otherwise the structure is appended to
* the element pointed to by last (it is updated to point to that structure).
* The 'next' element of the new structure is set to NULL; this is the list
* termination indicator when traversing it.
*
* Return value:
* 0 if option was ignored.
......@@ -275,7 +279,7 @@ addOptVal(const char* value, const confvar_t* varDesc,
*/
static int
procCmdLineArgs(int* argc, const char** argv[], const confvar_t optConf[],
confval** first, confval** last) {
confval** perOptRecordsFirst, confval** perOptRecordsLast) {
char* p;
extern char* optarg; /* For getopt */
extern int optind; /* For getopt */
......@@ -318,8 +322,9 @@ procCmdLineArgs(int* argc, const char** argv[], const confvar_t optConf[],
return(-1);
}
ind = optCharToConf[optchar];
switch (ret = addOptVal(optarg, &optConf[ind], &first[ind],
&last[ind])) {
switch (ret = addOptVal(optarg, &optConf[ind],
&perOptRecordsFirst[ind],
&perOptRecordsLast[ind])) {
case 1:
count++;
break;
......@@ -369,10 +374,17 @@ const char*
procOpts(int* argc, const char** argv[], const confvar_t optConf[],
confdata_t* confdata, const char name[],
const char usage[]) {
/*
* First & last records in the linked lists maintained for each option.
* These will point to arrays indexed by option number, giving one pointer
* (each) per option, used to maintain/return the list of values seen for
* that option (see the description of first & last in addOptVal()
*/
confval** perOptRecordsFirst;
confval** perOptRecordsLast;
/* Number of configuration options given in optConf */
unsigned numConf;