From: Ted Lemon Date: Tue, 15 Feb 2000 20:40:36 +0000 (+0000) Subject: Incorporate Brian Murrell's new OMAPI DHCP client changes. X-Git-Tag: V3-BETA-2-PATCH-1~304 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bdcaf7b95d9b5a409919e0f359e3c651a6f1e100;p=thirdparty%2Fdhcp.git Incorporate Brian Murrell's new OMAPI DHCP client changes. --- diff --git a/client/dhclient.c b/client/dhclient.c index c1b7e7263..49d09b50d 100644 --- a/client/dhclient.c +++ b/client/dhclient.c @@ -29,7 +29,7 @@ #ifndef lint static char ocopyright[] = -"$Id: dhclient.c,v 1.96 2000/02/02 20:47:55 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n"; +"$Id: dhclient.c,v 1.97 2000/02/15 20:40:27 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -1854,7 +1854,7 @@ void make_release (client, lease) sizeof client -> packet.siaddr); client -> packet.giaddr = giaddr; memcpy (client -> packet.chaddr, - &client -> interface -> hw_address.hbuf [0], + &client -> interface -> hw_address.hbuf [1], client -> interface -> hw_address.hlen); #ifdef DEBUG_PACKET @@ -2332,25 +2332,34 @@ void do_release(client) 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; + /* is there even a lease to release? */ + if (client -> active) { + /* Make a DHCPRELEASE 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 and only DHCPRELEASE packet. */ + send_release (client); + } - /* Send out the first DHCPREQUEST packet. */ - send_release (client); + /* remove the timeouts for this client */ + cancel_timeout (NULL, client); - script_init (client, - "RELEASE", (struct string_list *)0); - if (client -> alias) - script_write_params (client, "alias_", - client -> alias); - script_go (client); + /* if there was no lease, nothing to "do" */ + if (client -> active) { + script_init (client, + "RELEASE", (struct string_list *)0); + if (client -> alias) + script_write_params (client, "alias_", + client -> alias); + script_go (client); + } } diff --git a/client/omapi.c b/client/omapi.c index b902f441d..22d3b627b 100644 --- a/client/omapi.c +++ b/client/omapi.c @@ -4,7 +4,7 @@ #ifndef lint static char copyright[] = -"$Id: omapi.c,v 1.2 2000/02/02 07:36:32 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n"; +"$Id: omapi.c,v 1.3 2000/02/15 20:40:27 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -255,5 +255,35 @@ isc_result_t dhclient_interface_create (omapi_object_t **lp, isc_result_t dhclient_interface_remove (omapi_object_t *lp, omapi_object_t *id) { - return ISC_R_NOTIMPLEMENTED; + struct interface_info *interface, *ip, *last; + + interface = (struct interface_info *)lp; + + /* remove from interfaces */ + last = 0; + for (ip = interfaces; ip; ip = ip -> next) { + if (!strcmp (ip -> name, interface -> name)) { + if (last) + last -> next = ip -> next; + else + interfaces = ip -> next; + break; + } + last = ip; + } + + /* add the interface to the dummy_interface list */ + interface -> next = dummy_interfaces; + dummy_interfaces = interface; + + /* do a DHCPRELEASE */ + do_release (interface -> client); + + /* remove the io object */ + omapi_io_destroy (interface -> outer, MDL); + + if_deregister_send (interface); + if_deregister_receive (interface); + + return ISC_R_SUCCESS; } diff --git a/common/discover.c b/common/discover.c index 2c52bf784..86195fdae 100644 --- a/common/discover.c +++ b/common/discover.c @@ -22,7 +22,7 @@ #ifndef lint static char copyright[] = -"$Id: discover.c,v 1.22 2000/01/29 16:15:52 mellon Exp $ Copyright (c) 1995, 1996, 1998, 1999 The Internet Software Consortium. All rights reserved.\n"; +"$Id: discover.c,v 1.23 2000/02/15 20:40:30 mellon Exp $ Copyright (c) 1995, 1996, 1998, 1999 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -64,6 +64,7 @@ void discover_interfaces (state) char *s; #endif isc_result_t status; + static int setup_fallback = 0; if (!dhcp_type_interface) { status = omapi_object_type_register @@ -165,12 +166,12 @@ void discover_interfaces (state) last = 0; for (ip = dummy_interfaces; ip; ip = ip -> next) { if (!strcmp (ip -> name, tmp -> name)) { - /* remove from dummy_interfaces */ + /* Remove from dummy_interfaces */ if (last) last -> next = ip -> next; else dummy_interfaces = ip -> next; - /* copy "client" to tmp */ + /* Copy "client" to tmp */ if (ip -> client) { tmp -> client = ip -> client; tmp -> client -> interface = tmp; @@ -470,8 +471,10 @@ void discover_interfaces (state) /* If we're just trying to get a list of interfaces that we might be able to configure, we can quit now. */ - if (state == DISCOVER_UNCONFIGURED) + if (state == DISCOVER_UNCONFIGURED) { + close (sock); return; + } /* Weed out the interfaces that did not have IP addresses. */ last = (struct interface_info *)0; @@ -560,7 +563,11 @@ void discover_interfaces (state) close (sock); - maybe_setup_fallback (); + if (!setup_fallback) { + setup_fallback = 1; + maybe_setup_fallback (); + } + #if defined (HAVE_SETFD) if (fallback_interface) { if (fcntl (fallback_interface -> rfdesc, F_SETFD, 1) < 0) diff --git a/common/dispatch.c b/common/dispatch.c index 7f29f9572..5bdf0bd0b 100644 --- a/common/dispatch.c +++ b/common/dispatch.c @@ -22,7 +22,7 @@ #ifndef lint static char copyright[] = -"$Id: dispatch.c,v 1.59 2000/01/26 14:55:33 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n"; +"$Id: dispatch.c,v 1.60 2000/02/15 20:40:30 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -84,7 +84,8 @@ void add_timeout (when, where, what) /* See if this timeout supersedes an existing timeout. */ t = (struct timeout *)0; for (q = timeouts; q; q = q -> next) { - if (q -> func == where && q -> what == what) { + if ((where == NULL || q -> func == where) && + q -> what == what) { if (t) t -> next = q -> next; else diff --git a/common/lpf.c b/common/lpf.c index 2ec3a69db..e1a88be1e 100644 --- a/common/lpf.c +++ b/common/lpf.c @@ -23,7 +23,7 @@ #ifndef lint static char copyright[] = -"$Id: lpf.c,v 1.20 2000/01/27 23:27:38 mellon Exp $ Copyright (c) 1995, 1996, 1998, 1999 The Internet Software Consortium. All rights reserved.\n"; +"$Id: lpf.c,v 1.21 2000/02/15 20:40:30 mellon Exp $ Copyright (c) 1995, 1996, 1998, 1999 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -106,7 +106,7 @@ void if_register_send (info) /* If we're using the lpf API for sending and receiving, we don't need to register this interface twice. */ #ifndef USE_LPF_RECEIVE - info -> wfdesc = if_register_lpf (info, interface); + info -> wfdesc = if_register_lpf (info); #else info -> wfdesc = info -> rfdesc; #endif @@ -120,6 +120,28 @@ void if_register_send (info) (info -> shared_network ? info -> shared_network -> name : "")); } + +void if_deregister_send (info) + struct interface_info *info; +{ + /* don't need to close twice if we are using lpf for sending and + receiving */ +#ifndef USE_LPF_RECEIVE + /* for LPF this is simple, packet filters are removed when sockets + are closed */ + close (info -> wfdesc); +#endif + info -> wfdesc = 0; + if (!quiet_interface_discovery) + log_info ("NOT Sending on LPF/%s/%s%s%s", + info -> name, + print_hw_addr (info -> hw_address.hbuf [0], + info -> hw_address.hlen - 1, + &info -> hw_address.hbuf [1]), + (info -> shared_network ? "/" : ""), + (info -> shared_network ? + info -> shared_network -> name : "")); +} #endif /* USE_LPF_SEND */ #ifdef USE_LPF_RECEIVE @@ -155,6 +177,24 @@ void if_register_receive (info) info -> shared_network -> name : "")); } +void if_deregister_receive (info) + struct interface_info *info; +{ + /* for LPF this is simple, packet filters are removed when sockets + are closed */ + close (info -> rfdesc); + info -> rfdesc = 0; + if (!quiet_interface_discovery) + log_info ("NOT Listening on LPF/%s/%s%s%s", + info -> name, + print_hw_addr (info -> hw_address.hbuf [0], + info -> hw_address.hlen - 1, + &info -> hw_address.hbuf [1]), + (info -> shared_network ? "/" : ""), + (info -> shared_network ? + info -> shared_network -> name : "")); +} + static void lpf_gen_filter_setup (info) struct interface_info *info; { diff --git a/dhcpctl/cltest.c b/dhcpctl/cltest.c index b6f1cde95..4cbc9cf83 100644 --- a/dhcpctl/cltest.c +++ b/dhcpctl/cltest.c @@ -11,6 +11,8 @@ int main (int, char **); +enum modes { up, down }; + int main (argc, argv) int argc; char **argv; @@ -21,6 +23,17 @@ int main (argc, argv) dhcpctl_data_string cid; dhcpctl_data_string result, groupname, identifier; int i; + int mode; + char *action; + + if (!strcmp (argv [1], "-u")) { + mode = up; + } else if (!strcmp (argv [1], "-d")) { + mode = down; + } else { + fprintf (stderr, "Unknown switch \"%s\"\n", argv [1]); + exit (1); + } status = dhcpctl_initialize (); if (status != ISC_R_SUCCESS) { @@ -46,19 +59,52 @@ int main (argc, argv) exit (1); } - status = dhcpctl_set_string_value (interface_handle, argv[1], "name"); + status = dhcpctl_set_string_value (interface_handle, argv [2], "name"); if (status != ISC_R_SUCCESS) { fprintf (stderr, "dhcpctl_set_value: %s\n", isc_result_totext (status)); exit (1); } - status = dhcpctl_open_object (interface_handle, connection, - DHCPCTL_CREATE | DHCPCTL_EXCL); - if (status != ISC_R_SUCCESS) { - fprintf (stderr, "dhcpctl_open_object: %s\n", - isc_result_totext (status)); - exit (1); + if (mode == up) { + /* "up" the interface */ + printf ("upping interface %s\n", argv [2]); + action = "create"; + status = dhcpctl_open_object (interface_handle, connection, + DHCPCTL_CREATE | DHCPCTL_EXCL); + if (status != ISC_R_SUCCESS) { + fprintf (stderr, "dhcpctl_open_object: %s\n", + isc_result_totext (status)); + exit (1); + } + } else { + /* down the interface */ + printf ("downing interface %s\n", argv [2]); + action = "remove"; + status = dhcpctl_open_object (interface_handle, connection, 0); + if (status != ISC_R_SUCCESS) { + fprintf (stderr, "dhcpctl_open_object: %s\n", + isc_result_totext (status)); + exit (1); + } + status = dhcpctl_wait_for_completion (interface_handle, + &waitstatus); + if (status != ISC_R_SUCCESS) { + fprintf (stderr, "dhcpctl_wait_for_completion: %s\n", + isc_result_totext (status)); + exit (1); + } + if (waitstatus != ISC_R_SUCCESS) { + fprintf (stderr, "dhcpctl_wait_for_completion: %s\n", + isc_result_totext (waitstatus)); + exit (1); + } + status = dhcpctl_object_remove (connection, interface_handle); + if (status != ISC_R_SUCCESS) { + fprintf (stderr, "dhcpctl_open_object: %s\n", + isc_result_totext (status)); + exit (1); + } } status = dhcpctl_wait_for_completion (interface_handle, &waitstatus); @@ -68,7 +114,7 @@ int main (argc, argv) exit (1); } if (waitstatus != ISC_R_SUCCESS) { - fprintf (stderr, "interface object create: %s\n", + fprintf (stderr, "interface object %s: %s\n", action, isc_result_totext (waitstatus)); exit (1); } diff --git a/includes/dhcpd.h b/includes/dhcpd.h index 0c315853d..ba2aae274 100644 --- a/includes/dhcpd.h +++ b/includes/dhcpd.h @@ -1717,12 +1717,14 @@ void enter_auth_key PROTO ((struct data_string *, struct auth_key *)); const struct auth_key *auth_key_lookup PROTO ((struct data_string *)); /* omapi.c */ +extern omapi_object_type_t *dhcp_type_interface; extern omapi_object_type_t *dhcp_type_lease; extern omapi_object_type_t *dhcp_type_group; extern omapi_object_type_t *dhcp_type_pool; extern omapi_object_type_t *dhcp_type_shared_network; extern omapi_object_type_t *dhcp_type_subnet; extern omapi_object_type_t *dhcp_type_class; + #if defined (FAILOVER_PROTOCOL) extern omapi_object_type_t *dhcp_type_failover_state; extern omapi_object_type_t *dhcp_type_failover_link; diff --git a/omapip/dispatch.c b/omapip/dispatch.c index ae3c3826d..c571737d3 100644 --- a/omapip/dispatch.c +++ b/omapip/dispatch.c @@ -342,8 +342,29 @@ isc_result_t omapi_io_get_value (omapi_object_t *h, isc_result_t omapi_io_destroy (omapi_object_t *h, const char *file, int line) { + omapi_io_object_t *obj, *p, *last; + if (h -> type != omapi_type_io_object) return ISC_R_INVALIDARG; + + obj = (omapi_io_object_t *)h; + + /* only ios for interface objects? */ + if (strcmp (obj -> inner -> type ->name, "interface") == 0) { + /* remove from the list of I/O states */ + for (p = omapi_io_states.next; p; p = p -> next) { + if (p == obj) { + last -> next = p -> next; + break; + } + last = p; + } + + /* + * omapi_object_dereference ((omapi_object_t **)&obj, MDL); + */ + } + return ISC_R_SUCCESS; } diff --git a/omapip/generic.c b/omapip/generic.c index a3f69f240..73d39346f 100644 --- a/omapip/generic.c +++ b/omapip/generic.c @@ -117,7 +117,8 @@ isc_result_t omapi_generic_set_value (omapi_object_t *h, memcpy (va, g -> values, g -> va_max * sizeof *va); memset (va + g -> va_max, 0, (vm_new - g -> va_max) * sizeof *va); - dfree (g -> values, MDL); + if (g -> values) + dfree (g -> values, MDL); g -> values = va; g -> va_max = vm_new; }