summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
authorTed Lemon <source@isc.org>2000-01-28 20:30:37 +0000
committerTed Lemon <source@isc.org>2000-01-28 20:30:37 +0000
commit347de8bdb628837f37076ce06143be2c9c0f3c03 (patch)
tree09c44e5dbeb8a435228b78e9548b73b9332b5e4b /client
parentbc7b98ab10d9e232ba687a97f24c15ff286ba631 (diff)
downloadisc-dhcp-347de8bdb628837f37076ce06143be2c9c0f3c03.tar.gz
Brian Murrell's changes to allow the client to be directed using OMAPI.
Diffstat (limited to 'client')
-rw-r--r--client/Makefile.dist4
-rw-r--r--client/dhclient.c94
-rw-r--r--client/omapi.c259
3 files changed, 346 insertions, 11 deletions
diff --git a/client/Makefile.dist b/client/Makefile.dist
index 584d8b58..43c42e2d 100644
--- a/client/Makefile.dist
+++ b/client/Makefile.dist
@@ -21,8 +21,8 @@ CATMANPAGES = dhclient.cat8 dhclient.conf.cat5 dhclient-script.cat8 \
dhclient.leases.cat5
SEDMANPAGES = dhclient.man8 dhclient.conf.man5 dhclient-script.man8 \
dhclient.leases.man5
-SRCS = dhclient.c clparse.c
-OBJS = dhclient.o clparse.o
+SRCS = dhclient.c clparse.c omapi.c
+OBJS = dhclient.o clparse.o omapi.o
PROG = dhclient
MAN = dhclient.8 dhclient.conf.5 dhclient-script.8 dhclient.leases.5
diff --git a/client/dhclient.c b/client/dhclient.c
index 7764e6fb..9c18c47d 100644
--- a/client/dhclient.c
+++ b/client/dhclient.c
@@ -29,7 +29,7 @@
#ifndef lint
static char ocopyright[] =
-"$Id: dhclient.c,v 1.93 2000/01/26 14:55:26 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
+"$Id: dhclient.c,v 1.94 2000/01/28 20:30:26 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -73,6 +73,8 @@ int save_scripts;
static void usage PROTO ((void));
+void do_release(struct client_state *);
+
int main (argc, argv, envp)
int argc;
char **argv, **envp;
@@ -86,6 +88,9 @@ int main (argc, argv, envp)
char *server = (char *)0;
char *relay = (char *)0;
isc_result_t status;
+ int release_mode = 0;
+ omapi_object_t *listener;
+ isc_result_t result;
#ifdef SYSLOG_4_2
openlog ("dhclient", LOG_NDELAY);
@@ -99,7 +104,10 @@ int main (argc, argv, envp)
#endif
for (i = 1; i < argc; i++) {
- if (!strcmp (argv [i], "-p")) {
+ if (!strcmp (argv [i], "-r")) {
+ release_mode = 1;
+ no_daemon = 1;
+ } else if (!strcmp (argv [i], "-p")) {
if (++i == argc)
usage ();
local_port = htons (atoi (argv [i]));
@@ -132,6 +140,9 @@ int main (argc, argv, envp)
if (++i == argc)
usage ();
relay = argv [i];
+ } else if (!strcmp (argv [i], "-n")) {
+ /* do not start up any interfaces */
+ interfaces_requested = 1;
} else if (argv [i][0] == '-') {
usage ();
} else {
@@ -149,6 +160,16 @@ int main (argc, argv, envp)
}
}
+ /* first kill of any currently running client */
+ if (release_mode) {
+ /* XXX inelegant hack to prove concept */
+ char command[1024];
+
+ snprintf (command, 1024, "kill `cat %s`",
+ path_dhclient_pid);
+ system (command);
+ }
+
if (!quiet) {
log_info ("%s %s", message, DHCP_VERSION);
log_info (copyright);
@@ -225,6 +246,10 @@ int main (argc, argv, envp)
log_fatal ("Can't initialize OMAPI: %s",
isc_result_totext (status));
+ /* Set up the OMAPI wrappers for various server database internal
+ objects. */
+ dhclient_db_objects_setup ();
+
/* Discover all the network interfaces. */
discover_interfaces (DISCOVER_UNCONFIGURED);
@@ -251,7 +276,7 @@ int main (argc, argv, envp)
/* Nothing more to do. */
exit (0);
- } else {
+ } else if (!release_mode) {
/* Call the script with the list of interfaces. */
for (ip = interfaces; ip; ip = ip -> next) {
/* If interfaces were specified, don't configure
@@ -295,15 +320,35 @@ int main (argc, argv, envp)
/* Start a configuration state machine for each interface. */
for (ip = interfaces; ip; ip = ip -> next) {
+ ip -> flags |= INTERFACE_RUNNING;
for (client = ip -> client; client; client = client -> next) {
- client -> state = S_INIT;
- /* Set up a timeout to start the initialization
- process. */
- add_timeout (cur_time + random () % 5,
- state_reboot, client);
+ if (release_mode)
+ do_release (client);
+ else {
+ client -> state = S_INIT;
+ /* Set up a timeout to start the initialization
+ process. */
+ add_timeout (cur_time + random () % 5,
+ state_reboot, client);
+ }
}
}
+ if (release_mode)
+ return 0;
+
+ /* Start up a listener for the object management API protocol. */
+ listener = (omapi_object_t *)0;
+ result = omapi_generic_new (&listener, MDL);
+ if (result != ISC_R_SUCCESS)
+ log_fatal ("Can't allocate new generic object: %s\n",
+ isc_result_totext (result));
+ result = omapi_protocol_listen (listener,
+ OMAPI_PROTOCOL_PORT, 1);
+ if (result != ISC_R_SUCCESS)
+ log_fatal ("Can't start OMAPI protocol: %s",
+ isc_result_totext (result));
+
/* Set up the bootp packet handler... */
bootp_packet_handler = do_packet;
@@ -1778,7 +1823,7 @@ void make_release (client, lease)
oc = lookup_option (&dhcp_universe, lease -> options,
DHO_DHCP_SERVER_IDENTIFIER);
make_client_options (client, lease, &request, oc,
- &lease -> address, (u_int32_t *)0,
+ (struct iaddr *)0, (u_int32_t *)0,
&options);
/* Set up the option buffer... */
@@ -2276,6 +2321,37 @@ void client_location_changed ()
}
}
+void do_release(client)
+ struct client_state *client;
+{
+ /* make_request doesn't initialize xid because it normally comes
+ from the DHCPDISCOVER, but we haven't sent a DHCPDISCOVER,
+ so pick an xid now. */
+ client -> xid = random ();
+
+ /* Make a DHCPREQUEST packet, and set appropriate per-interface
+ flags. */
+ make_release (client, client -> active);
+ client -> destination = iaddr_broadcast;
+ client -> first_sending = cur_time;
+ client -> interval = client -> config -> initial_interval;
+
+ /* Zap the medium list... */
+ client -> medium = (struct string_list *)0;
+
+ /* Send out the first DHCPREQUEST packet. */
+ send_release (client);
+
+ script_init (client,
+ "RELEASE", (struct string_list *)0);
+ if (client -> alias)
+ script_write_params (client, "alias_",
+ client -> alias);
+ script_go (client);
+}
+
+
+
/* The client should never receive a relay agent information option,
so if it does, log it and discard it. */
diff --git a/client/omapi.c b/client/omapi.c
new file mode 100644
index 00000000..442bc630
--- /dev/null
+++ b/client/omapi.c
@@ -0,0 +1,259 @@
+/* omapi.c
+
+ OMAPI object interfaces for the DHCP client. */
+
+#ifndef lint
+static char copyright[] =
+"$Id: omapi.c,v 1.1 2000/01/28 20:30:26 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
+#endif /* not lint */
+
+#include "dhcpd.h"
+#include <omapip/omapip_p.h>
+
+void dhclient_db_objects_setup ()
+{
+ isc_result_t status;
+
+ status = omapi_object_type_register (&dhcp_type_interface,
+ "interface",
+ dhclient_interface_set_value,
+ dhclient_interface_get_value,
+ dhclient_interface_destroy,
+ dhclient_interface_signal_handler,
+ dhclient_interface_stuff_values,
+ dhclient_interface_lookup,
+ dhclient_interface_create,
+ dhclient_interface_remove);
+ if (status != ISC_R_SUCCESS)
+ log_fatal ("Can't register interface object type: %s",
+ isc_result_totext (status));
+
+}
+
+isc_result_t dhclient_interface_set_value (omapi_object_t *h,
+ omapi_object_t *id,
+ omapi_data_string_t *name,
+ omapi_typed_data_t *value)
+{
+ struct interface_info *interface;
+ isc_result_t status;
+ int foo;
+
+ if (h -> type != dhcp_type_interface)
+ return ISC_R_INVALIDARG;
+ interface = (struct interface_info *)h;
+
+ if (!omapi_ds_strcmp (name, "name")) {
+ if (value -> type == omapi_datatype_data ||
+ value -> type == omapi_datatype_string) {
+ memcpy (interface -> name,
+ value -> u.buffer.value,
+ value -> u.buffer.len);
+ interface -> name [value -> u.buffer.len] = 0;
+ } else
+ return ISC_R_INVALIDARG;
+ return ISC_R_SUCCESS;
+ }
+
+ /* Try to find some inner object that can take the value. */
+ if (h -> inner && h -> inner -> type -> set_value) {
+ status = ((*(h -> inner -> type -> set_value))
+ (h -> inner, id, name, value));
+ if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED)
+ return status;
+ }
+
+ return ISC_R_NOTFOUND;
+}
+
+
+isc_result_t dhclient_interface_get_value (omapi_object_t *h,
+ omapi_object_t *id,
+ omapi_data_string_t *name,
+ omapi_value_t **value)
+{
+ return ISC_R_NOTIMPLEMENTED;
+}
+
+isc_result_t dhclient_interface_destroy (omapi_object_t *h,
+ const char *file, int line)
+{
+ struct interface_info *interface;
+ isc_result_t status;
+
+ if (h -> type != dhcp_type_interface)
+ return ISC_R_INVALIDARG;
+ interface = (struct interface_info *)h;
+
+
+ if (interface -> ifp)
+ free (interface -> ifp);
+ dfree (interface, file, line);
+ return ISC_R_SUCCESS;
+}
+
+isc_result_t dhclient_interface_signal_handler (omapi_object_t *h,
+ const char *name, va_list ap)
+{
+ struct interface_info *ip, *interface;
+ struct client_config *config;
+ struct client_state *client;
+
+ if (h -> type != dhcp_type_interface)
+ return ISC_R_INVALIDARG;
+ interface = (struct interface_info *)h;
+
+ interface -> next = interfaces;
+ interfaces = interface;
+
+ discover_interfaces (DISCOVER_UNCONFIGURED);
+
+ for (ip = interfaces; ip; ip = ip -> next) {
+ /* If interfaces were specified, don't configure
+ interfaces that weren't specified! */
+ if (ip -> flags & INTERFACE_RUNNING ||
+ (ip -> flags & (INTERFACE_REQUESTED |
+ INTERFACE_AUTOMATIC)) !=
+ INTERFACE_REQUESTED)
+ continue;
+ script_init (ip -> client,
+ "PREINIT", (struct string_list *)0);
+ if (ip -> client -> alias)
+ script_write_params (ip -> client, "alias_",
+ ip -> client -> alias);
+ script_go (ip -> client);
+ }
+
+ discover_interfaces (interfaces_requested
+ ? DISCOVER_REQUESTED
+ : DISCOVER_RUNNING);
+
+ for (ip = interfaces; ip; ip = ip -> next) {
+ if (ip -> flags & INTERFACE_RUNNING)
+ continue;
+ ip -> flags |= INTERFACE_RUNNING;
+ for (client = ip -> client; client; client = client -> next) {
+ client -> state = S_INIT;
+ /* Set up a timeout to start the initialization
+ process. */
+ add_timeout (cur_time + random () % 5,
+ state_reboot, client);
+ }
+ }
+ return ISC_R_SUCCESS;
+}
+
+isc_result_t dhclient_interface_stuff_values (omapi_object_t *c,
+ omapi_object_t *id,
+ omapi_object_t *h)
+{
+ struct interface_info *interface;
+ isc_result_t status;
+
+ if (h -> type != dhcp_type_interface)
+ return ISC_R_INVALIDARG;
+ interface = (struct interface_info *)h;
+
+ /* Write out all the values. */
+
+ status = omapi_connection_put_name (c, "state");
+ if (status != ISC_R_SUCCESS)
+ return status;
+ if (interface -> flags && INTERFACE_REQUESTED)
+ status = omapi_connection_put_string (c, "up");
+ else
+ status = omapi_connection_put_string (c, "down");
+ if (status != ISC_R_SUCCESS)
+ return status;
+
+ /* Write out the inner object, if any. */
+ if (h -> inner && h -> inner -> type -> stuff_values) {
+ status = ((*(h -> inner -> type -> stuff_values))
+ (c, id, h -> inner));
+ if (status == ISC_R_SUCCESS)
+ return status;
+ }
+
+ return ISC_R_SUCCESS;
+}
+
+isc_result_t dhclient_interface_lookup (omapi_object_t **ip,
+ omapi_object_t *id,
+ omapi_object_t *ref)
+{
+ omapi_value_t *tv = (omapi_value_t *)0;
+ isc_result_t status;
+ struct interface_info *interface;
+
+ /* First see if we were sent a handle. */
+ status = omapi_get_value_str (ref, id, "handle", &tv);
+ if (status == ISC_R_SUCCESS) {
+ status = omapi_handle_td_lookup (ip, tv -> value);
+
+ omapi_value_dereference (&tv, MDL);
+ if (status != ISC_R_SUCCESS)
+ return status;
+
+ /* Don't return the object if the type is wrong. */
+ if ((*ip) -> type != dhcp_type_interface) {
+ omapi_object_dereference (ip, MDL);
+ return ISC_R_INVALIDARG;
+ }
+ }
+
+ /* Now look for an interface name. */
+ status = omapi_get_value_str (ref, id, "name", &tv);
+ if (status == ISC_R_SUCCESS) {
+ for (interface = interfaces; interface;
+ interface = interface -> next) {
+ if (strncmp (interface -> name,
+ tv -> value -> u.buffer.value,
+ tv -> value -> u.buffer.len) == 0)
+ break;
+ }
+ omapi_value_dereference (&tv, MDL);
+ if (*ip && *ip != (omapi_object_t *)interface) {
+ omapi_object_dereference (ip, MDL);
+ return ISC_R_KEYCONFLICT;
+ } else if (!interface) {
+ if (*ip)
+ omapi_object_dereference (ip, MDL);
+ return ISC_R_NOTFOUND;
+ } else if (!*ip)
+ /* XXX fix so that hash lookup itself creates
+ XXX the reference. */
+ omapi_object_reference (ip,
+ (omapi_object_t *)interface,
+ MDL);
+ }
+
+ /* If we get to here without finding an interface, no valid key was
+ specified. */
+ if (!*ip)
+ return ISC_R_NOKEYS;
+ return ISC_R_SUCCESS;
+}
+
+/* actually just go discover the interface */
+isc_result_t dhclient_interface_create (omapi_object_t **lp,
+ omapi_object_t *id)
+{
+ struct interface_info *hp;
+
+ hp = (struct interface_info *)dmalloc (sizeof (struct interface_info),
+ MDL);
+ if (!hp)
+ return ISC_R_NOMEMORY;
+ memset (hp, 0, sizeof *hp);
+ hp -> refcnt = 0;
+ hp -> type = dhcp_type_interface;
+ hp -> flags = INTERFACE_REQUESTED;
+ return omapi_object_reference (lp, (omapi_object_t *)hp, MDL);
+
+}
+
+isc_result_t dhclient_interface_remove (omapi_object_t *lp,
+ omapi_object_t *id)
+{
+ return ISC_R_NOTIMPLEMENTED;
+}