diff options
author | Ted Lemon <source@isc.org> | 2000-01-28 20:30:37 +0000 |
---|---|---|
committer | Ted Lemon <source@isc.org> | 2000-01-28 20:30:37 +0000 |
commit | 347de8bdb628837f37076ce06143be2c9c0f3c03 (patch) | |
tree | 09c44e5dbeb8a435228b78e9548b73b9332b5e4b /client | |
parent | bc7b98ab10d9e232ba687a97f24c15ff286ba631 (diff) | |
download | isc-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.dist | 4 | ||||
-rw-r--r-- | client/dhclient.c | 94 | ||||
-rw-r--r-- | client/omapi.c | 259 |
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; +} |