cloptions.cc 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /*
  2. * Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
  3. *
  4. * Permission to use, copy, modify, and/or distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  9. * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  10. * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  11. * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  12. * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  13. * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  14. * PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #include <stdio.h>
  17. #include "procconf.h"
  18. #include "perfdhcp.h"
  19. #include "cloptions.h"
  20. static void printHelp(const char *progName, const char *usage);
  21. /*
  22. * Return value:
  23. * 0 if the command has been satisfied and the program should exit 0.
  24. * 2 for usage error, in which case an error message will have been printed.
  25. * 1 if argument processing was successful and the program should continue.
  26. */
  27. int
  28. procArgs(int argc, char **argv)
  29. {
  30. char usage[] =
  31. "Usage:\n\
  32. perfdhcp [-hv] [-4|-6] [-r<rate>] [-n<num-request>] [-p<test-period>]\n\
  33. [-d<drop-time>] [-D<max-drop>] [-l<local-addr|interface>] [-i]\n\
  34. [-x<diagnostic-selector>] [server]\n";
  35. int v4 = 0;
  36. char *maxDropOpt;
  37. double dropTime;
  38. double testPeriod;
  39. /* Names of configuration variables, for defaults file processor */
  40. confvar_t optConf[] = {
  41. { 'h', NULL, CF_SWITCH, NULL, 0 },
  42. { 'v', NULL, CF_SWITCH, NULL, 0 },
  43. { '4', NULL, CF_SWITCH, &v4, 1 },
  44. { '6', NULL, CF_SWITCH, &v6, 1 },
  45. { 'i', NULL, CF_SWITCH, &initialOnly, 1 },
  46. { 'l', NULL, CF_NE_STRING, &localName, 0 },
  47. { 'r', NULL, CF_POS_INT, &rate, 0 },
  48. { 'x', NULL, CF_STRING, &diagSelector, 0 },
  49. { 'd', NULL, CF_POS_FLOAT, &dropTime, 0 },
  50. { 'D', NULL, CF_STRING, &maxDropOpt, 0 },
  51. { 'n', NULL, CF_POS_INT, &numRequest, 0 },
  52. { 'p', NULL, CF_POS_FLOAT, &testPeriod, 0 },
  53. { '\0', NULL, CF_ENDLIST, NULL, 0 }
  54. };
  55. confdata_t confdata;
  56. /* Process command line options and config file */
  57. procOpts(&argc, &argv, optConf, &confdata, NULL, progName, usage);
  58. if (confdata.map['h']->num > 0) {
  59. printHelp(progName, usage);
  60. return 0;
  61. }
  62. if (confdata.map['v']->num > 0) {
  63. printf("dhcpperf v1.0 2011-10-30\n");
  64. return 0;
  65. }
  66. if (v4 && v6) {
  67. fprintf(stderr, "Must not give -4 and -6 together.\n");
  68. return 2;
  69. }
  70. switch (argc) {
  71. case 0:
  72. if (v6 && localName != NULL)
  73. server = "all";
  74. else {
  75. if (v6)
  76. fprintf(stderr, "Use -l to specify an interface name.\n\%s\n", usage);
  77. else
  78. fprintf(stderr, "Must specify a DHCP server.\n\%s\n", usage);
  79. return 2;
  80. }
  81. break;
  82. case 1:
  83. server = argv[0];
  84. break;
  85. default:
  86. fprintf(stderr, "Too many arguments.\n\%s\n", usage);
  87. return 2;
  88. }
  89. return 1;
  90. }
  91. static void
  92. printHelp(const char *progName, const char *usage)
  93. {
  94. printf(
  95. "%s: Execute a performance test against a DHCP server.\n\
  96. %s\n\
  97. The [server] argument is the name/address of the DHCP server to contact. For\n\
  98. DHCPv4 operation, exchanges are initiated by transmitting a DHCP DISCOVER to\n\
  99. this address. For DHCPv6 operation, exchanges are initiated by transmitting a\n\
  100. DHCP SOLICIT to this address. In the DHCPv6 case, the special name \"all\" can\n\
  101. be used to refer to All_DHCP_Relay_Agents_and_Servers (the multicast address\n\
  102. FF02::1:2), or the special name \"servers\" to refer to All_DHCP_Servers (the\n\
  103. multicast address FF05::1:3). The [server] argument is optional only in the\n\
  104. case that -l is used to specify an interface, in which case [server] defaults\n\
  105. to \"all\".\n\
  106. \n\
  107. Exchanges are initiated by transmitting a DHCP SOLICIT to\n\
  108. All_DHCP_Relay_Agents_and_Servers (the multicast address FF02::1:2) via this\n\
  109. interface.\n\
  110. \n\
  111. The default is to perform a single 4-way exchange, effectively pinging the\n\
  112. server. The -r option is used to set up a performance test.\n\
  113. \n\
  114. Options:\n\
  115. -4: DHCPv4 operation (default). This is incompatible with the -6 option.\n\
  116. -6: DHCPv6 operation. This is incompatible with the -4 option.\n\
  117. -h: Print this help.\n\
  118. -i: Do only the initial part of an exchange: DO or SA, depending on whether -6\n\
  119. is given.\n\
  120. -l<local-addr|interface>: For DHCPv4 operation, specify the local\n\
  121. hostname/address to use when communicating with the server. By default,\n\
  122. the interface address through which traffic would normally be routed to the\n\
  123. server is used.\n\
  124. For DHCPv6 operation, specify the name of the network interface via which\n\
  125. exchanges are initiated. This must be specified unless a server name is\n\
  126. given, in which case the interface through which traffic would normally be\n\
  127. routed to the server is used.\n\
  128. -r<rate>: Initiate <rate> DORA/SARR (or if -i is given, DO/SA) exchanges per\n\
  129. second. A periodic report is generated showing the number of exchanges\n\
  130. which were not completed, as well as the average response latency. The\n\
  131. program continues until interrupted, at which point a final report is\n\
  132. generated.\n\
  133. -v: Report the version number of this program.\n\
  134. -x<diagnostic-selector>: Include extended diagnostics in the output.\n\
  135. <diagnostic-selector> is a string of single-keywords specifying the\n\
  136. operations for which verbose output is desired. The selector keyletters\n\
  137. are:\n\
  138. [TO BE ADDED]\n\
  139. \n\
  140. The remaining options are used only in conjunction with -r:\n\
  141. \n\
  142. -d<drop-time>: Specify the time after which a request is treated as having been\n\
  143. lost. The value is given in seconds and may contain a fractional\n\
  144. component. The default is 1 second.\n\
  145. -D<max-drop>: Abort the test if more than <max-drop> requests have been\n\
  146. dropped. Use -D0 to abort if even a single request has been dropped. If\n\
  147. <max-drop> includes the suffix \"%%\", it specifies a maximum percentage of\n\
  148. requests that may be dropped before abort. In this case, testing of the\n\
  149. threshold begins after 10 requests have been expected to be received.\n\
  150. -n<num-request>: Initiate <num-request> transactions. No report is generated\n\
  151. until all transactions have been initiated/waited-for, after which a report\n\
  152. is generated and the program terminates.\n\
  153. -p<test-period>: Send requests for the given test period, which is specified in\n\
  154. the same manner as -d. This can be used as an alternative to -n, or both\n\
  155. options can be given, in which case the testing is completed when either\n\
  156. limit is reached.\n\
  157. \n\
  158. Exit status:\n\
  159. The exit status is:\n\
  160. 0 on complete success.\n\
  161. 1 for a general error.\n\
  162. 2 if an error is found in the command line arguments.\n\
  163. 3 if there are no general failures in operation, but one or more exchanges are\n\
  164. not successfully completed.\n",
  165. progName, usage);
  166. }