summaryrefslogtreecommitdiff
path: root/tests/test-dhcp-client.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test-dhcp-client.c')
-rw-r--r--tests/test-dhcp-client.c189
1 files changed, 189 insertions, 0 deletions
diff --git a/tests/test-dhcp-client.c b/tests/test-dhcp-client.c
new file mode 100644
index 000000000..2fee3fc11
--- /dev/null
+++ b/tests/test-dhcp-client.c
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2008, 2009 Nicira Networks.
+ *
+ * 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 THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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 <config.h>
+#include "dhcp-client.h"
+#include <arpa/inet.h>
+#include <getopt.h>
+#include <stdlib.h>
+#include <limits.h>
+#include "command-line.h"
+#include "dhcp.h"
+#include "fatal-signal.h"
+#include "fault.h"
+#include "poll-loop.h"
+#include "util.h"
+#include "vlog.h"
+
+/* --request-ip: IP address to request from server. If zero, then do not
+ * request a specific IP address. */
+static struct in_addr request_ip;
+
+/* --vendor-class: Vendor class string to include in request. If null, no
+ * vendor class string is included. */
+static const char *vendor_class;
+
+/* --no-resolv-conf: Update /etc/resolv.conf to match DHCP reply? */
+static bool update_resolv_conf = true;
+
+static void parse_options(int argc, char *argv[]);
+static void usage(void);
+static void release(void *cli_);
+static void modify_dhcp_request(struct dhcp_msg *, void *aux);
+
+int
+main(int argc, char *argv[])
+{
+ struct dhclient *cli;
+ int error;
+
+ set_program_name(argv[0]);
+ register_fault_handlers();
+ vlog_init();
+ parse_options(argc, argv);
+
+ argc -= optind;
+ argv += optind;
+ if (argc != 1) {
+ ovs_fatal(0, "exactly one non-option argument required; "
+ "use --help for help");
+ }
+
+ error = dhclient_create(argv[0], modify_dhcp_request, NULL, NULL, &cli);
+ if (error) {
+ ovs_fatal(error, "dhclient_create failed");
+ }
+ dhclient_init(cli, request_ip.s_addr);
+ fatal_signal_add_hook(release, cli, true);
+
+ for (;;) {
+ fatal_signal_block();
+ dhclient_run(cli);
+ if (dhclient_changed(cli)) {
+ dhclient_configure_netdev(cli);
+ if (update_resolv_conf) {
+ dhclient_update_resolv_conf(cli);
+ }
+ }
+ dhclient_wait(cli);
+ fatal_signal_unblock();
+ poll_block();
+ }
+}
+
+static void
+release(void *cli_)
+{
+ struct dhclient *cli = cli_;
+ dhclient_release(cli);
+ if (dhclient_changed(cli)) {
+ dhclient_configure_netdev(cli);
+ }
+}
+
+static void
+modify_dhcp_request(struct dhcp_msg *msg, void *aux UNUSED)
+{
+ if (vendor_class) {
+ dhcp_msg_put_string(msg, DHCP_CODE_VENDOR_CLASS, vendor_class);
+ }
+}
+
+static void
+parse_options(int argc, char *argv[])
+{
+ enum {
+ OPT_REQUEST_IP = UCHAR_MAX + 1,
+ OPT_VENDOR_CLASS,
+ OPT_NO_RESOLV_CONF
+ };
+ static struct option long_options[] = {
+ {"request-ip", required_argument, 0, OPT_REQUEST_IP },
+ {"vendor-class", required_argument, 0, OPT_VENDOR_CLASS },
+ {"no-resolv-conf", no_argument, 0, OPT_NO_RESOLV_CONF},
+ {"verbose", optional_argument, 0, 'v'},
+ {"help", no_argument, 0, 'h'},
+ {"version", no_argument, 0, 'V'},
+ {0, 0, 0, 0},
+ };
+ char *short_options = long_options_to_short_options(long_options);
+
+ for (;;) {
+ int c;
+
+ c = getopt_long(argc, argv, short_options, long_options, NULL);
+ if (c == -1) {
+ break;
+ }
+
+ switch (c) {
+ case OPT_REQUEST_IP:
+ if (!inet_aton(optarg, &request_ip)) {
+ ovs_fatal(0,
+ "--request-ip argument is not a valid IP address");
+ }
+ break;
+
+ case OPT_VENDOR_CLASS:
+ vendor_class = optarg;
+ break;
+
+ case OPT_NO_RESOLV_CONF:
+ update_resolv_conf = false;
+ break;
+
+ case 'h':
+ usage();
+
+ case 'V':
+ printf("%s %s compiled "__DATE__" "__TIME__"\n",
+ program_name, VERSION BUILDNR);
+ exit(EXIT_SUCCESS);
+
+ case 'v':
+ vlog_set_verbosity(optarg);
+ break;
+
+ case '?':
+ exit(EXIT_FAILURE);
+
+ default:
+ abort();
+ }
+ }
+ free(short_options);
+}
+
+static void
+usage(void)
+{
+ printf("%s: standalone program for testing Open vSwitch DHCP client.\n"
+ "usage: %s [OPTIONS] NETDEV\n"
+ "where NETDEV is a network device (e.g. eth0).\n"
+ "\nDHCP options:\n"
+ " --request-ip=IP request specified IP address (default:\n"
+ " do not request a specific IP)\n"
+ " --vendor-class=STRING use STRING as vendor class (default:\n"
+ " none); use OpenFlow to imitate secchan\n"
+ " --no-resolv-conf do not update /etc/resolv.conf\n",
+ program_name, program_name);
+ vlog_usage();
+ printf("\nOther options:\n"
+ " -h, --help display this help message\n"
+ " -V, --version display version information\n");
+ exit(EXIT_SUCCESS);
+}
+