dnslib.
doc/ja_JP.eucJP/dhclient-script.8 doc/ja_JP.eucJP/dhclient.8 \
doc/ja_JP.eucJP/dhclient.conf.5 doc/ja_JP.eucJP/dhclient.leases.5 \
doc/ja_JP.eucJP/dhcp-eval.5 doc/ja_JP.eucJP/dhcp-options.5 \
- doc/examples/dhclient-dhcpv6.conf doc/examples/dhcpd-dhcpv6.conf
+ doc/examples/dhclient-dhcpv6.conf doc/examples/dhcpd-dhcpv6.conf \
+ util/bind.sh util/bindlib.sh util/bindcus.sh \
+ bind/bind.tar.gz bind/version.tmp
-SUBDIRS = includes tests common minires dst omapip client dhcpctl relay server
+SUBDIRS = includes tests common dst omapip client dhcpctl relay server
nobase_include_HEADERS = dhcpctl/dhcpctl.h
gunzip dhcp-4.1.0.tar.gz
tar xvf dhcp-4.1.0.tar
+ BUILDING BIND LIBRARIES
+
+To build the BIND libraries used by DHCP cd to the dhcp-4.1.0 subdirectory
+that you've just created and run the bindcus.sh from the the util
+subdirectory - something like this:
+
+ sh util/bindcus.sh
+
+In order to build the necessary libraries you will need to have "gmake"
+available on your build system.
+
CONFIGURING IT
Now, cd to the dhcp-4.1.0 subdirectory that you've just created and
DYNAMIC DNS UPDATES
A fully-featured implementation of dynamic DNS updates is included in
-this release. There are no build dependencies with any BIND version
-- this version can and should just use the resolver in your C library.
+this release. It uses libraries from BIND and, to avoid issues with
+different versions, includes the necessary BIND version.
There is documentation for the DDNS support in the dhcpd.conf manual
page - see the beginning of this document for information on finding
ISC DHCP 4.2.x includes features that were not included in DHCP 4.1.x.
These include:
+Processing the DHCP to DNS server transactions in an asyncrhonous fashion.
+The DHCP server or client can now continue with it's processing while
+awaiting replies from the DNS server.
+
There are a number of DHCPv6 limitations and features missing in this
release, which will be addressed in the future:
calculations. Invalid renew and rebinding times (e.g., greater than the
determined lease time) are omitted.
+- Processing the DHCP to DNS server transactions in an asyncrhonous fashion.
+ The DHCP server or client can now continue with it's processing while
+ awaiting replies from the DNS server.
+
Changes since 4.1.0 (bug fixes)
- Remove infinite loop in token_print_indent_concat().
scripts/bsdos scripts/freebsd scripts/linux scripts/macos \
scripts/netbsd scripts/nextstep scripts/openbsd \
scripts/solaris scripts/openwrt
-dhclient_LDADD = ../common/libdhcp.a ../minires/libres.a \
- ../omapip/libomapi.a ../dst/libdst.a
+dhclient_LDADD = ../common/libdhcp.a ../omapip/libomapi.a \
+ ../bind/lib/libdns.a ../bind/lib/libisc.a
man_MANS = dhclient.8 dhclient-script.8 dhclient.conf.5 dhclient.leases.5
EXTRA_DIST = $(man_MANS)
} while (1);
token = next_token (&val, (unsigned *)0, cfile);
status = (cfile -> warnings_occurred
- ? ISC_R_BADPARSE
+ ? DHCP_R_BADPARSE
: ISC_R_SUCCESS);
end_parse (&cfile);
return status;
MDL);
dfree(ia, MDL);
data_string_forget(&ds, MDL);
- return ISC_R_BADPARSE;
+ return DHCP_R_BADPARSE;
}
}
data_string_forget(&ds, MDL);
MDL);
dfree(ia, MDL);
data_string_forget(&ds, MDL);
- return ISC_R_BADPARSE;
+ return DHCP_R_BADPARSE;
}
}
data_string_forget(&ds, MDL);
MDL);
dfree(ia, MDL);
data_string_forget(&ds, MDL);
- return ISC_R_BADPARSE;
+ return DHCP_R_BADPARSE;
}
}
data_string_forget(&ds, MDL);
MDL);
dfree(addr, MDL);
data_string_forget(&ds, MDL);
- return ISC_R_BADPARSE;
+ return DHCP_R_BADPARSE;
}
}
MDL);
dfree(pfx, MDL);
data_string_forget(&ds, MDL);
- return ISC_R_BADPARSE;
+ return DHCP_R_BADPARSE;
}
}
isc_result_t rval = ISC_R_SUCCESS;
if ((options == NULL) || (code == NULL))
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if ((msg != NULL) && (msg->len != 0))
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
memset(&ds, 0, sizeof(ds));
NULL, &global_scope, oc, MDL)) {
if (ds.len < 2) {
log_error("Invalid status code length %d.", ds.len);
- rval = ISC_R_FORMERR;
+ rval = DHCP_R_FORMERR;
} else
*code = getUShort(ds.data);
isc_result_t status;
if ((scope == NULL) || (code == NULL))
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
/* If we don't find a code, we assume success. */
*code = STATUS_Success;
log_fatal("Impossible condition at %s:%d.", MDL);
if (client == NULL) {
- *rvalp = ISC_R_INVALIDARG;
+ *rvalp = DHCP_R_INVALIDARG;
return ISC_FALSE;
}
log_fatal("Impossible condition at %s:%d.", MDL);
if (client == NULL) {
- *rvalp = ISC_R_INVALIDARG;
+ *rvalp = DHCP_R_INVALIDARG;
return ISC_FALSE;
}
rval = *rvalp;
log_fatal("Impossible condition at %s:%d.", MDL);
if (client == NULL) {
- *rvalp = ISC_R_INVALIDARG;
+ *rvalp = DHCP_R_INVALIDARG;
return ISC_FALSE;
}
rval = *rvalp;
log_fatal("Impossible condition at %s:%d.", MDL);
if (client == NULL) {
- *rvalp = ISC_R_INVALIDARG;
+ *rvalp = DHCP_R_INVALIDARG;
return ISC_FALSE;
}
rval = *rvalp;
int nscore, sscore;
if ((client == NULL) || (new == NULL))
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
switch (client->state) {
case S_INIT:
break;
default:
log_error("dhc6_check_reply: no type.");
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
rval = dhc6_check_status(rval, ia->options,
scope, &code);
struct dhc6_addr *addr, *oldaddr;
struct dhc6_lease *lease, *old;
const char *reason;
+#if defined (NSUPDATE)
TIME dns_update_offset = 1;
+#endif
lease = client->active_lease;
if (lease == NULL) {
} else
oldaddr = NULL;
+#if defined (NSUPDATE)
if ((oldaddr == NULL) && (ia->ia_type == D6O_IA_NA))
dhclient_schedule_updates(client,
&addr->address,
dns_update_offset++);
+#endif
/* Shell out to setup the new binding. */
script_init(client, reason, NULL);
piaddr(addr->address),
(unsigned) addr->plen);
+#if defined (NSUPDATE)
/* Remove DDNS bindings at depref time. */
if ((ia->ia_type == D6O_IA_NA) &&
client->config->do_forward_update)
- client_dns_update(client, 0, 0,
+ client_dns_remove(client,
&addr->address);
+#endif
}
}
}
piaddr(addr->address),
(unsigned) addr->plen);
+#if defined (NSUPDATE)
/* We remove DNS records at depref time, but
* it is possible that we might get here
* without depreffing.
if ((ia->ia_type == D6O_IA_NA) &&
client->config->do_forward_update &&
!(addr->flags & DHC6_ADDR_DEPREFFED))
- client_dns_update(client, 0, 0,
+ client_dns_remove(client,
&addr->address);
+#endif
continue;
}
client->active_lease, ia, addr);
script_go(client);
+#if defined (NSUPDATE)
if ((ia->ia_type == D6O_IA_NA) &&
client->config->do_forward_update)
- client_dns_update(client, 0, 0, &addr->address);
+ client_dns_remove(client, &addr->address);
+#endif
}
}
}
#include <sys/time.h>
#include <sys/wait.h>
#include <limits.h>
+#include <dns/result.h>
TIME default_lease_time = 43200; /* 12 hours... */
TIME max_lease_time = 86400; /* 24 hours... */
setlogmask(LOG_UPTO(LOG_INFO));
#endif
+ /* Set up the isc and dns library managers */
+ status = dhcp_context_create();
+ if (status != ISC_R_SUCCESS)
+ log_fatal("Can't initialize context: %s",
+ isc_result_totext(status));
+
/* Set up the OMAPI. */
status = omapi_init();
if (status != ISC_R_SUCCESS)
client -> state = S_BOUND;
reinitialize_interfaces ();
go_daemon ();
+#if defined (NSUPDATE)
if (client->config->do_forward_update)
- dhclient_schedule_updates(client, &client->active->address,
- 1);
+ dhclient_schedule_updates(client, &client->active->address, 1);
+#endif
}
/* state_bound is called when we've successfully bound to a particular
int stat;
if ((duid == NULL) || (duid->len <= 2))
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (leaseFile == NULL) { /* XXX? */
leaseFile = fopen(path_dhclient_db, "w");
}
if (client == NULL || lease == NULL)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (leaseFile == NULL) { /* XXX? */
leaseFile = fopen(path_dhclient_db, "w");
exit (0);
}
+#if defined (NSUPDATE)
+/*
+ * If the first query fails, the updater MUST NOT delete the DNS name. It
+ * may be that the host whose lease on the server has expired has moved
+ * to another network and obtained a lease from a different server,
+ * which has caused the client's A RR to be replaced. It may also be
+ * that some other client has been configured with a name that matches
+ * the name of the DHCP client, and the policy was that the last client
+ * to specify the name would get the name. In this case, the DHCID RR
+ * will no longer match the updater's notion of the client-identity of
+ * the host pointed to by the DNS name.
+ * -- "Interaction between DHCP and DNS"
+ */
+
+/* The first and second stages are pretty similar so we combine them */
+void
+client_dns_remove_action(dhcp_ddns_cb_t *ddns_cb,
+ isc_result_t eresult)
+{
+
+ isc_result_t result;
+
+ if ((eresult == ISC_R_SUCCESS) &&
+ (ddns_cb->state == DDNS_STATE_REM_FW_YXDHCID)) {
+ /* Do the second stage of the FWD removal */
+ ddns_cb->state = DDNS_STATE_REM_FW_NXRR;
+
+ result = ddns_modify_fwd(ddns_cb);
+ if (result == ISC_R_SUCCESS) {
+ return;
+ }
+ }
+
+ /* If we are done or have an error clean up */
+ ddns_cb_free(ddns_cb, MDL);
+ return;
+}
+
+void
+client_dns_remove(struct client_state *client,
+ struct iaddr *addr)
+{
+ dhcp_ddns_cb_t *ddns_cb;
+ isc_result_t result;
+
+ /* if we have an old ddns request for this client, cancel it */
+ if (client->ddns_cb != NULL) {
+ ddns_cancel(client->ddns_cb);
+ client->ddns_cb = NULL;
+ }
+
+ ddns_cb = ddns_cb_alloc(MDL);
+ if (ddns_cb != NULL) {
+ ddns_cb->address = *addr;
+ ddns_cb->timeout = 0;
+
+ ddns_cb->state = DDNS_STATE_REM_FW_YXDHCID;
+ ddns_cb->flags = DDNS_UPDATE_ADDR;
+ ddns_cb->cur_func = client_dns_remove_action;
+
+ result = client_dns_update(client, ddns_cb);
+
+ if (result != ISC_R_TIMEDOUT) {
+ ddns_cb_free(ddns_cb, MDL);
+ }
+ }
+}
+#endif
+
isc_result_t dhcp_set_control_state (control_object_state_t oldstate,
control_object_state_t newstate)
{
case server_shutdown:
if (client -> active &&
client -> active -> expiry > cur_time) {
- if (client -> config -> do_forward_update)
- client_dns_update(client, 0, 0,
- &client->active->address);
+#if defined (NSUPDATE)
+ if (client->config->do_forward_update) {
+ client_dns_remove(client,
+ &client->active->address);
+ }
+#endif
do_release (client);
}
break;
return ISC_R_SUCCESS;
}
-/* Schedule updates to retry occasionally until it no longer times out.
+#if defined (NSUPDATE)
+/*
+ * Called after a timeout if the DNS update failed on the previous try.
+ * Starts the retry process. If the retry times out it will schedule
+ * this routine to run again after a 10x wait.
*/
void
-dhclient_schedule_updates(struct client_state *client, struct iaddr *addr,
- int offset)
+client_dns_update_timeout (void *cp)
{
- struct dns_update_state *ustate;
- struct timeval tv;
-
- if (!client->config->do_forward_update)
- return;
-
- ustate = dmalloc(sizeof(*ustate), MDL);
+ dhcp_ddns_cb_t *ddns_cb = (dhcp_ddns_cb_t *)cp;
+ struct client_state *client = (struct client_state *)ddns_cb->lease;
+ isc_result_t status = ISC_R_FAILURE;
- if (ustate != NULL) {
- ustate->client = client;
- ustate->address = *addr;
- ustate->dns_update_timeout = 1;
+ if ((client != NULL) &&
+ ((client->active != NULL) ||
+ (client->active_lease != NULL)))
+ status = client_dns_update(client, ddns_cb);
- tv.tv_sec = cur_time + offset;
- tv.tv_usec = 0;
- add_timeout(&tv, client_dns_update_timeout,
- ustate, NULL, NULL);
- } else {
- log_error("Unable to allocate dns update state for %s.",
- piaddr(*addr));
+ /*
+ * A status of timedout indicates that we started the update and
+ * have released control of the control block. Any other status
+ * indicates that we should clean up the control block. We either
+ * got a success which indicates that we didn't really need to
+ * send an update or some other error in which case we weren't able
+ * to start the update process. In both cases we still own
+ * the control block and should free it.
+ */
+ if (status != ISC_R_TIMEDOUT) {
+ if (client != NULL) {
+ client->ddns_cb = NULL;
+ }
+ ddns_cb_free(ddns_cb, MDL);
}
}
-/* Called after a timeout if the DNS update failed on the previous try.
- Retries the update, and if it times out, schedules a retry after
- ten times as long of a wait. */
+/*
+ * If the first query succeeds, the updater can conclude that it
+ * has added a new name whose only RRs are the A and DHCID RR records.
+ * The A RR update is now complete (and a client updater is finished,
+ * while a server might proceed to perform a PTR RR update).
+ * -- "Interaction between DHCP and DNS"
+ *
+ * If the second query succeeds, the updater can conclude that the current
+ * client was the last client associated with the domain name, and that
+ * the name now contains the updated A RR. The A RR update is now
+ * complete (and a client updater is finished, while a server would
+ * then proceed to perform a PTR RR update).
+ * -- "Interaction between DHCP and DNS"
+ *
+ * If the second query fails with NXRRSET, the updater must conclude
+ * that the client's desired name is in use by another host. At this
+ * juncture, the updater can decide (based on some administrative
+ * configuration outside of the scope of this document) whether to let
+ * the existing owner of the name keep that name, and to (possibly)
+ * perform some name disambiguation operation on behalf of the current
+ * client, or to replace the RRs on the name with RRs that represent
+ * the current client. If the configured policy allows replacement of
+ * existing records, the updater submits a query that deletes the
+ * existing A RR and the existing DHCID RR, adding A and DHCID RRs that
+ * represent the IP address and client-identity of the new client.
+ * -- "Interaction between DHCP and DNS"
+ */
-void client_dns_update_timeout (void *cp)
+/* The first and second stages are pretty similar so we combine them */
+void
+client_dns_update_action(dhcp_ddns_cb_t *ddns_cb,
+ isc_result_t eresult)
{
- struct dns_update_state *ustate = cp;
- isc_result_t status = ISC_R_FAILURE;
+ isc_result_t result;
struct timeval tv;
- /* XXX: DNS TTL is a problem we need to solve properly. Until
- * that time, 300 is a placeholder default for something that is
- * less insane than a value scaled by lease timeout.
- */
- if ((ustate->client->active != NULL) ||
- (ustate->client->active_lease != NULL))
- status = client_dns_update(ustate->client, 1, 300,
- &ustate->address);
-
- if (status == ISC_R_TIMEDOUT) {
- if (ustate->dns_update_timeout < 3600)
- ustate->dns_update_timeout *= 10;
- tv.tv_sec = cur_time + ustate->dns_update_timeout;
+ switch(eresult) {
+ case ISC_R_SUCCESS:
+ default:
+ /* Either we succeeded or broke in a bad way, clean up */
+ break;
+
+ case DNS_R_YXRRSET:
+ /*
+ * This is the only difference between the two stages,
+ * check to see if it is the first stage, in which case
+ * start the second stage
+ */
+ if (ddns_cb->state == DDNS_STATE_ADD_FW_NXDOMAIN) {
+ ddns_cb->state = DDNS_STATE_ADD_FW_YXDHCID;
+ ddns_cb->cur_func = client_dns_update_action;
+
+ result = ddns_modify_fwd(ddns_cb);
+ if (result == ISC_R_SUCCESS) {
+ return;
+ }
+ }
+ break;
+
+ case ISC_R_TIMEDOUT:
+ /*
+ * We got a timeout response from the DNS module. Schedule
+ * another attempt for later. We forget the name, dhcid and
+ * zone so if it gets changed we will get the new information.
+ */
+ data_string_forget(&ddns_cb->fwd_name, MDL);
+ data_string_forget(&ddns_cb->dhcid, MDL);
+ if (ddns_cb->zone != NULL) {
+ forget_zone((struct dns_zone **)&ddns_cb->zone);
+ }
+
+ /* Reset to doing the first stage */
+ ddns_cb->state = DDNS_STATE_ADD_FW_NXDOMAIN;
+ ddns_cb->cur_func = client_dns_update_action;
+
+ /* and update our timer */
+ if (ddns_cb->timeout < 3600)
+ ddns_cb->timeout *= 10;
+ tv.tv_sec = cur_time + ddns_cb->timeout;
tv.tv_usec = 0;
add_timeout(&tv, client_dns_update_timeout,
- ustate, NULL, NULL);
- } else
- dfree(ustate, MDL);
+ ddns_cb, NULL, NULL);
+ return;
+ }
+
+ ddns_cb_free(ddns_cb, MDL);
+ return;
}
/* See if we should do a DNS update, and if so, do it. */
-isc_result_t client_dns_update (struct client_state *client, int addp,
- int ttl, struct iaddr *address)
+isc_result_t
+client_dns_update(struct client_state *client, dhcp_ddns_cb_t *ddns_cb)
{
- struct data_string ddns_fwd_name, ddns_dhcid, client_identifier;
+ struct data_string client_identifier;
struct option_cache *oc;
int ignorep;
int result;
return ISC_R_SUCCESS;
/* If no FQDN option was supplied, don't do the update. */
- memset (&ddns_fwd_name, 0, sizeof ddns_fwd_name);
if (!(oc = lookup_option (&fqdn_universe, client -> sent_options,
FQDN_FQDN)) ||
- !evaluate_option_cache (&ddns_fwd_name, (struct packet *)0,
+ !evaluate_option_cache (&ddns_cb->fwd_name, (struct packet *)0,
(struct lease *)0, client,
client -> sent_options,
(struct option_state *)0,
* the client identifier, if there is one, or the interface's
* MAC address.
*/
- memset (&ddns_dhcid, 0, sizeof ddns_dhcid);
-
result = 0;
memset(&client_identifier, 0, sizeof(client_identifier));
if (client->active_lease != NULL) {
* field. We aren't using RFC4701 DHCID RR's yet,
* but this is as good a value as any.
*/
- result = get_dhcid(&ddns_dhcid, 2,
+ result = get_dhcid(&ddns_cb->dhcid, 2,
client_identifier.data,
client_identifier.len);
data_string_forget(&client_identifier, MDL);
evaluate_option_cache(&client_identifier, NULL, NULL,
client, client->sent_options, NULL,
&global_scope, oc, MDL)) {
- result = get_dhcid(&ddns_dhcid,
+ result = get_dhcid(&ddns_cb->dhcid,
DHO_DHCP_CLIENT_IDENTIFIER,
client_identifier.data,
client_identifier.len);
data_string_forget(&client_identifier, MDL);
} else
- result = get_dhcid(&ddns_dhcid, 0,
+ result = get_dhcid(&ddns_cb->dhcid, 0,
client->interface->hw_address.hbuf,
client->interface->hw_address.hlen);
}
if (!result) {
- data_string_forget(&ddns_fwd_name, MDL);
return ISC_R_SUCCESS;
}
- /* Start the resolver, if necessary. */
- if (!resolver_inited) {
- minires_ninit (&resolver_state);
- resolver_inited = 1;
- resolver_state.retrans = 1;
- resolver_state.retry = 1;
- }
-
/*
* Perform updates.
*/
- if (ddns_fwd_name.len && ddns_dhcid.len) {
- if (addp)
- rcode = ddns_update_fwd(&ddns_fwd_name, *address,
- &ddns_dhcid, ttl, 1, 1);
- else
- rcode = ddns_remove_fwd(&ddns_fwd_name, *address,
- &ddns_dhcid);
+ if (ddns_cb->fwd_name.len && ddns_cb->dhcid.len) {
+ rcode = ddns_modify_fwd(ddns_cb);
} else
rcode = ISC_R_FAILURE;
- data_string_forget (&ddns_fwd_name, MDL);
- data_string_forget (&ddns_dhcid, MDL);
+ /*
+ * A success from the modify routine means we are performing
+ * async processing, for which we use the timedout error message.
+ */
+ if (rcode == ISC_R_SUCCESS) {
+ rcode = ISC_R_TIMEDOUT;
+ }
+
return rcode;
}
+
+/*
+ * Schedule the first update. They will continue to retry occasionally
+ * until they no longer time out (or fail).
+ */
+void
+dhclient_schedule_updates(struct client_state *client,
+ struct iaddr *addr,
+ int offset)
+{
+ dhcp_ddns_cb_t *ddns_cb;
+ struct timeval tv;
+
+ if (!client->config->do_forward_update)
+ return;
+
+ /* cancel any outstanding ddns requests */
+ if (client->ddns_cb != NULL) {
+ ddns_cancel(client->ddns_cb);
+ client->ddns_cb = NULL;
+ }
+
+ ddns_cb = ddns_cb_alloc(MDL);
+
+ if (ddns_cb != NULL) {
+ ddns_cb->lease = (void *)client;
+ ddns_cb->address = *addr;
+ ddns_cb->timeout = 1;
+
+ /*
+ * XXX: DNS TTL is a problem we need to solve properly.
+ * Until that time, 300 is a placeholder default for
+ * something that is less insane than a value scaled
+ * by lease timeout.
+ */
+ ddns_cb->ttl = 300;
+
+ ddns_cb->state = DDNS_STATE_ADD_FW_NXDOMAIN;
+ ddns_cb->cur_func = client_dns_update_action;
+ ddns_cb->flags = DDNS_UPDATE_ADDR | DDNS_INCLUDE_RRSET;
+
+ client->ddns_cb = ddns_cb;
+
+ tv.tv_sec = cur_time + offset;
+ tv.tv_usec = 0;
+ add_timeout(&tv, client_dns_update_timeout,
+ ddns_cb, NULL, NULL);
+ } else {
+ log_error("Unable to allocate dns update state for %s",
+ piaddr(*addr));
+ }
+}
+#endif
+
void
dhcpv4_client_assignments(void)
{
noinst_LIBRARIES = libdhcp.a
libdhcp_a_SOURCES = alloc.c bpf.c comapi.c conflex.c ctrace.c discover.c \
dispatch.c dlpi.c dns.c ethernet.c execute.c fddi.c \
- icmp.c inet.c lpf.c memory.c nit.c options.c packet.c \
- parse.c print.c raw.c resolv.c socket.c tables.c tr.c \
- tree.c upf.c heap.c
+ icmp.c inet.c lpf.c memory.c nit.c ns_name.c options.c \
+ packet.c parse.c print.c raw.c resolv.c socket.c \
+ tables.c tr.c tree.c upf.c
man_MANS = dhcp-eval.5 dhcp-options.5
EXTRA_DIST = $(man_MANS)
isc_result_t status;
if (h -> type != dhcp_type_group)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
group = (struct group_object *)h;
/* XXX For now, we can only set these values on new group objects.
value -> u.buffer.len);
group -> name [value -> u.buffer.len] = 0;
} else
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
return ISC_R_SUCCESS;
}
(&group -> group -> statements, parse, &lose,
context_any))) {
end_parse (&parse);
- return ISC_R_BADPARSE;
+ return DHCP_R_BADPARSE;
}
end_parse (&parse);
return ISC_R_SUCCESS;
} else
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
/* 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)
+ if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED)
return status;
}
isc_result_t status;
if (h -> type != dhcp_type_group)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
group = (struct group_object *)h;
if (!omapi_ds_strcmp (name, "name"))
struct group_object *group, *t;
if (h -> type != dhcp_type_group)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
group = (struct group_object *)h;
if (group -> name) {
int updatep = 0;
if (h -> type != dhcp_type_group)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
group = (struct group_object *)h;
if (!strcmp (name, "updated")) {
/* A group object isn't valid if a subgroup hasn't yet been
associated with it. */
if (!group -> group)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
/* Group objects always have to have names. */
if (!group -> name) {
isc_result_t status;
if (h -> type != dhcp_type_group)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
group = (struct group_object *)h;
/* Write out all the values. */
struct group_object *group;
if (!ref)
- return ISC_R_NOKEYS;
+ return DHCP_R_NOKEYS;
/* First see if we were sent a handle. */
status = omapi_get_value_str (ref, id, "handle", &tv);
/* Don't return the object if the type is wrong. */
if ((*lp) -> type != dhcp_type_group) {
omapi_object_dereference (lp, MDL);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
}
if (*lp && *lp != (omapi_object_t *)group) {
group_object_dereference (&group, MDL);
omapi_object_dereference (lp, MDL);
- return ISC_R_KEYCONFLICT;
+ return DHCP_R_KEYCONFLICT;
} else if (!*lp) {
/* XXX fix so that hash lookup itself creates
XXX the reference. */
/* If we get to here without finding a group, no valid key was
specified. */
if (!*lp)
- return ISC_R_NOKEYS;
+ return DHCP_R_NOKEYS;
if (((struct group_object *)(*lp)) -> flags & GROUP_OBJECT_DELETED) {
omapi_object_dereference (lp, MDL);
struct group_object *group;
isc_result_t status;
if (lp -> type != dhcp_type_group)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
group = (struct group_object *)lp;
group -> flags |= GROUP_OBJECT_DELETED;
unsigned long newstate;
if (h -> type != dhcp_type_control)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
control = (dhcp_control_object_t *)h;
if (!omapi_ds_strcmp (name, "state")) {
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)
+ if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED)
return status;
}
isc_result_t status;
if (h -> type != dhcp_type_control)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
control = (dhcp_control_object_t *)h;
if (!omapi_ds_strcmp (name, "state"))
const char *file, int line)
{
if (h -> type != dhcp_type_control)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
/* Can't destroy the control object. */
return ISC_R_NOPERM;
isc_result_t status;
if (h -> type != dhcp_type_control)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
control = (dhcp_control_object_t *)h;
/* Try to find some inner object that can take the value. */
isc_result_t status;
if (h -> type != dhcp_type_control)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
control = (dhcp_control_object_t *)h;
/* Write out all the values. */
/* Don't return the object if the type is wrong. */
if ((*lp) -> type != dhcp_type_control) {
omapi_object_dereference (lp, MDL);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
}
}
isc_result_t status;
if (h -> type != dhcp_type_subnet)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
subnet = (struct subnet *)h;
/* No values to set yet. */
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)
+ if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED)
return status;
}
isc_result_t status;
if (h -> type != dhcp_type_subnet)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
subnet = (struct subnet *)h;
/* No values to get yet. */
struct subnet *subnet;
if (h -> type != dhcp_type_subnet)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
subnet = (struct subnet *)h;
#if defined (DEBUG_MEMORY_LEAKAGE) || \
int updatep = 0;
if (h -> type != dhcp_type_subnet)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
subnet = (struct subnet *)h;
/* Can't write subnets yet. */
isc_result_t status;
if (h -> type != dhcp_type_subnet)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
subnet = (struct subnet *)h;
/* Can't stuff subnet values yet. */
/* If we get to here without finding a subnet, no valid key was
specified. */
if (!*lp)
- return ISC_R_NOKEYS;
+ return DHCP_R_NOKEYS;
return ISC_R_SUCCESS;
}
isc_result_t status;
if (h -> type != dhcp_type_shared_network)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
shared_network = (struct shared_network *)h;
/* No values to set yet. */
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)
+ if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED)
return status;
}
isc_result_t status;
if (h -> type != dhcp_type_shared_network)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
shared_network = (struct shared_network *)h;
/* No values to get yet. */
struct shared_network *shared_network;
if (h -> type != dhcp_type_shared_network)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
shared_network = (struct shared_network *)h;
#if defined (DEBUG_MEMORY_LEAKAGE) || \
int updatep = 0;
if (h -> type != dhcp_type_shared_network)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
shared_network = (struct shared_network *)h;
/* Can't write shared_networks yet. */
isc_result_t status;
if (h -> type != dhcp_type_shared_network)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
shared_network = (struct shared_network *)h;
/* Can't stuff shared_network values yet. */
/* If we get to here without finding a shared_network, no valid key was
specified. */
if (!*lp)
- return ISC_R_NOKEYS;
+ return DHCP_R_NOKEYS;
return ISC_R_SUCCESS;
}
struct parse *saved_state;
if (cfile->saved_state == NULL) {
- return ISC_R_NOTYET;
+ return DHCP_R_NOTYET;
}
saved_state = cfile->saved_state;
interface_reference (&tmp, next, MDL);
}
- /* Now register all the remaining interfaces as protocols. */
+ /*
+ * Now register all the remaining interfaces as protocols.
+ * We register with omapi to allow for control of the interface,
+ * we've already registered the fd or socket with the socket
+ * manager as part of if_register_receive().
+ */
for (tmp = interfaces; tmp; tmp = tmp -> next) {
/* not if it's been registered before */
if (tmp -> flags & INTERFACE_RUNNING)
continue;
if (tmp -> rfdesc == -1)
continue;
+ switch (local_family) {
#ifdef DHCPv6
- if (local_family == AF_INET6) {
+ case AF_INET6:
status = omapi_register_io_object((omapi_object_t *)tmp,
if_readsocket,
0, got_one_v6, 0, 0);
- } else {
-#else
- {
+ break;
#endif /* DHCPv6 */
+ case AF_INET:
+ default:
status = omapi_register_io_object((omapi_object_t *)tmp,
if_readsocket,
0, got_one, 0, 0);
+ break;
}
+
if (status != ISC_R_SUCCESS)
log_fatal ("Can't register I/O handle for %s: %s",
tmp -> name, isc_result_totext (status));
if (local_family == AF_INET6)
break;
#endif
- }
+ } /* for (tmp = interfaces; ... */
if (state == DISCOVER_SERVER && wifcount == 0) {
log_info ("%s", "");
struct interface_info *ip;
if (h -> type != dhcp_type_interface)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
ip = (struct interface_info *)h;
again:
unsigned int if_idx = 0;
if (h->type != dhcp_type_interface) {
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
ip = (struct interface_info *)h;
isc_result_t status;
if (h -> type != dhcp_type_interface)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
interface = (struct interface_info *)h;
if (!omapi_ds_strcmp (name, "name")) {
value -> u.buffer.len);
interface -> name [value -> u.buffer.len] = 0;
} else
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
return ISC_R_SUCCESS;
}
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)
+ if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED)
return status;
}
struct interface_info *interface;
if (h -> type != dhcp_type_interface)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
interface = (struct interface_info *)h;
if (interface -> ifp) {
isc_result_t status;
if (h -> type != dhcp_type_interface)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
interface = (struct interface_info *)h;
/* If it's an update signal, see if the interface is dead right
isc_result_t status;
if (h -> type != dhcp_type_interface)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
interface = (struct interface_info *)h;
/* Write out all the values. */
struct interface_info *interface;
if (!ref)
- return ISC_R_NOKEYS;
+ return DHCP_R_NOKEYS;
/* First see if we were sent a handle. */
status = omapi_get_value_str (ref, id, "handle", &tv);
/* 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;
+ return DHCP_R_INVALIDARG;
}
}
omapi_value_dereference (&tv, MDL);
if (*ip && *ip != (omapi_object_t *)interface) {
omapi_object_dereference (ip, MDL);
- return ISC_R_KEYCONFLICT;
+ return DHCP_R_KEYCONFLICT;
} else if (!interface) {
if (*ip)
omapi_object_dereference (ip, MDL);
/* If we get to here without finding an interface, no valid key was
specified. */
if (!*ip)
- return ISC_R_NOKEYS;
+ return DHCP_R_NOKEYS;
return ISC_R_SUCCESS;
}
/* remove the io object */
omapi_unregister_io_object ((omapi_object_t *)interface);
- if (local_family == AF_INET) {
- if_deregister_send(interface);
- if_deregister_receive(interface);
+ switch(local_family) {
#ifdef DHCPv6
- } else {
+ case AF_INET6:
if_deregister6(interface);
+ break;
#endif /* DHCPv6 */
+ case AF_INET:
+ default:
+ if_deregister_send(interface);
+ if_deregister_receive(interface);
+ break;
}
return ISC_R_SUCCESS;
Network input dispatcher... */
/*
- * Copyright (c) 2004-2008 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2009 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1995-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
* <info@isc.org>
* https://www.isc.org/
*
- * This software has been written for Internet Systems Consortium
- * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
- * To learn more about Internet Systems Consortium, see
- * ``https://www.isc.org/''. To learn more about Vixie Enterprises,
- * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
- * ``http://www.nominum.com''.
*/
#include "dhcpd.h"
addressing information from it, and then call through the
bootp_packet_handler hook to try to do something with it. */
-void dispatch ()
+/*
+ * Use the DHCP timeout list as a place to store DHCP specific
+ * information, but use the ISC timer system to actually dispatch
+ * the events.
+ *
+ * There are several things that the DHCP timer code does that the
+ * ISC code doesn't:
+ * 1) It allows for negative times
+ * 2) The cancel arguments are different. The DHCP code uses the
+ * function and data to find the proper timer to cancel while the
+ * ISC code uses a pointer to the timer.
+ * 3) The DHCP code includes provision for incrementing and decrementing
+ * a reference counter associated with the data.
+ * The first one is fairly easy to fix but will take some time to go throuh
+ * the callers and update them. The second is also not all that difficult
+ * in concept - add a pointer to the appropriate structures to hold a pointer
+ * to the timer and use that. The complications arise in trying to ensure
+ * that all of the corner cases are covered. The last one is potentially
+ * more painful and requires more investigation.
+ *
+ * The plan is continue with the older DHCP calls and timer list. The
+ * calls will continue to manipulate the list but will also pass a
+ * timer to the ISC timer code for the actual dispatch. Later, if desired,
+ * we can go back and modify the underlying calls to use the ISC
+ * timer functions directly without requiring all of the code to change
+ * at the same time.
+ */
+
+void
+dispatch(void)
{
- struct timeval tv, *tvp;
isc_result_t status;
- /* Wait for a packet or a timeout... XXX */
- do {
- tvp = process_outstanding_timeouts (&tv);
- status = omapi_one_dispatch (0, tvp);
- } while (status == ISC_R_TIMEDOUT || status == ISC_R_SUCCESS);
- log_fatal ("omapi_one_dispatch failed: %s -- exiting.",
+ status = isc_app_ctxrun(dhcp_gbl_ctx.actx);
+
+ isclib_cleanup();
+
+ log_fatal ("Dispatch routine failed: %s -- exiting",
isc_result_totext (status));
}
+void
+isclib_timer_callback(isc_task_t *taskp,
+ isc_event_t *eventp)
+{
+ struct timeout *t = (struct timeout *)eventp->ev_arg;
+ struct timeout *q, *r;
+
+ /* Get the current time... */
+ gettimeofday (&cur_tv, (struct timezone *)0);
+
+ /*
+ * Find the timeout on the dhcp list and remove it.
+ * As the list isn't ordered we search the entire list
+ */
+
+ r = NULL;
+ for (q = timeouts; q; q = q->next) {
+ if (q == t) {
+ if (r)
+ r->next = q->next;
+ else
+ timeouts = q->next;
+ break;
+ }
+ r = q;
+ }
+
+ /*
+ * The timer should always be on the list. If it is we do
+ * the work and detach the timer block, if not we log an error.
+ * In both cases we attempt free the ISC event and continue
+ * processing.
+ */
+
+ if (q != NULL) {
+ /* call the callback function */
+ (*(q->func)) (q->what);
+ if (q->unref) {
+ (*q->unref) (&q->what, MDL);
+ }
+ q->next = free_timeouts;
+ isc_timer_detach(&q->isc_timeout);
+ free_timeouts = q;
+ } else {
+ /*
+ * Hmm, we should clean up the timer structure but aren't
+ * sure about the pointer to the timer block we got so
+ * don't try to - may change this to a log_fatal
+ */
+ log_error("Error finding timer structure");
+ }
+
+ isc_event_free(&eventp);
+ return;
+}
+
+/* maximum value for usec */
+#define USEC_MAX 1000000
+
void add_timeout (when, where, what, ref, unref)
struct timeval *when;
void (*where) PROTO ((void *));
tvunref_t unref;
{
struct timeout *t, *q;
+ int usereset = 0;
+ isc_result_t status;
+ int sec, usec;
+ isc_interval_t interval;
+ isc_time_t expires;
/* See if this timeout supersedes an existing timeout. */
t = (struct timeout *)0;
- for (q = timeouts; q; q = q -> next) {
- if ((where == NULL || q -> func == where) &&
- q -> what == what) {
+ for (q = timeouts; q; q = q->next) {
+ if ((where == NULL || q->func == where) &&
+ q->what == what) {
if (t)
- t -> next = q -> next;
+ t->next = q->next;
else
- timeouts = q -> next;
+ timeouts = q->next;
+ usereset = 1;
break;
}
t = q;
if (!q) {
if (free_timeouts) {
q = free_timeouts;
- free_timeouts = q -> next;
+ free_timeouts = q->next;
} else {
q = ((struct timeout *)
- dmalloc (sizeof (struct timeout), MDL));
- if (!q)
- log_fatal ("add_timeout: no memory!");
+ dmalloc(sizeof(struct timeout), MDL));
+ if (!q) {
+ log_fatal("add_timeout: no memory!");
+ }
}
- memset (q, 0, sizeof *q);
- q -> func = where;
- q -> ref = ref;
- q -> unref = unref;
- if (q -> ref)
- (*q -> ref)(&q -> what, what, MDL);
+ memset(q, 0, sizeof *q);
+ q->func = where;
+ q->ref = ref;
+ q->unref = unref;
+ if (q->ref)
+ (*q->ref)(&q->what, what, MDL);
else
- q -> what = what;
+ q->what = what;
}
- q -> when . tv_sec = when -> tv_sec;
- q -> when . tv_usec = when -> tv_usec;
+ /* We don't really need this, but keep it for now */
+ q->when.tv_sec = when->tv_sec;
+ q->when.tv_usec = when->tv_usec;
+
+ /*
+ * Don't bother sorting the DHCP list, just add it to the front.
+ * Eventually the list should be removed as we migrate the callers
+ * to the native ISC timer functions, if it becomes a performance
+ * problem before then we may need to order the list.
+ */
+ q->next = timeouts;
+ timeouts = q;
+
+ /*
+ * Set up the interval values - The previous timers allowed
+ * negative values to be set, the ISC timer library doesn't like
+ * that so we make any negative values 0 which sould amount to
+ * the same thing.
+ */
- /* Now sort this timeout into the timeout list. */
+ /*
+ * The value passed in is a time from an epoch but we need a relative
+ * time so we need to do some math to try and recover the period.
+ * This is complicated by the fact that not all of the calls cared
+ * about the usec value, if it's zero we assume the caller didn't care.
+ */
- /* Beginning of list? */
- if (!timeouts || (timeouts -> when . tv_sec > q -> when . tv_sec) ||
- ((timeouts -> when . tv_sec == q -> when . tv_sec) &&
- (timeouts -> when . tv_usec > q -> when . tv_usec))) {
- q -> next = timeouts;
- timeouts = q;
- return;
+ sec = when->tv_sec - cur_tv.tv_sec;
+ usec = when->tv_usec - cur_tv.tv_usec;
+
+ if ((when->tv_usec != 0) && (usec < 0)) {
+ sec--;
+ usec += USEC_MAX;
}
- /* Middle of list? */
- for (t = timeouts; t -> next; t = t -> next) {
- if ((t -> next -> when . tv_sec > q -> when . tv_sec) ||
- ((t -> next -> when . tv_sec == q -> when . tv_sec) &&
- (t -> next -> when . tv_usec > q -> when . tv_usec))) {
- q -> next = t -> next;
- t -> next = q;
- return;
- }
+ if (sec < 0) {
+ sec = 0;
+ usec = 0;
+ } else if (usec < 0) {
+ usec = 0;
+ } else if (usec >= USEC_MAX) {
+ usec = USEC_MAX - 1;
+ }
+
+ isc_interval_set(&interval, sec, usec * 1000);
+ status = isc_time_nowplusinterval(&expires, &interval);
+ if (status != ISC_R_SUCCESS) {
+ /*
+ * The system time function isn't happy or returned
+ * a value larger than isc_time_t can hold.
+ */
+ log_fatal("Unable to set up timer: %s",
+ isc_result_totext(status));
+ }
+
+ if (usereset == 0) {
+ status = isc_timer_create(dhcp_gbl_ctx.timermgr,
+ isc_timertype_once, &expires,
+ NULL, dhcp_gbl_ctx.task,
+ isclib_timer_callback,
+ (void *)q, &q->isc_timeout);
+ } else {
+ status = isc_timer_reset(q->isc_timeout,
+ isc_timertype_once, &expires,
+ NULL, 0);
+ }
+
+ /* If it fails log an error and die */
+ if (status != ISC_R_SUCCESS) {
+ log_fatal("Unable to add timeout to isclib\n");
}
- /* End of list. */
- t -> next = q;
- q -> next = (struct timeout *)0;
+ return;
}
void cancel_timeout (where, what)
/* Look for this timeout on the list, and unlink it if we find it. */
t = (struct timeout *)0;
for (q = timeouts; q; q = q -> next) {
- if (q -> func == where && q -> what == what) {
+ if (q->func == where && q->what == what) {
if (t)
- t -> next = q -> next;
+ t->next = q->next;
else
- timeouts = q -> next;
+ timeouts = q->next;
break;
}
t = q;
}
- /* If we found the timeout, put it on the free list. */
+ /* If we found the timeout, cancel it and put it on the free list. */
if (q) {
- if (q -> unref)
- (*q -> unref) (&q -> what, MDL);
- q -> next = free_timeouts;
+ isc_timer_detach(&q->isc_timeout);
+
+ if (q->unref)
+ (*q->unref) (&q->what, MDL);
+ q->next = free_timeouts;
free_timeouts = q;
}
}
{
struct timeout *t, *n;
for (t = timeouts; t; t = n) {
- n = t -> next;
- if (t -> unref && t -> what)
- (*t -> unref) (&t -> what, MDL);
- t -> next = free_timeouts;
+ n = t->next;
+ isc_timer_detach(&t->isc_timeout);
+ if (t->unref && t->what)
+ (*t->unref) (&t->what, MDL);
+ t->next = free_timeouts;
free_timeouts = t;
}
}
{
struct timeout *t, *n;
for (t = free_timeouts; t; t = n) {
- n = t -> next;
- dfree (t, MDL);
+ n = t->next;
+ dfree(t, MDL);
}
}
#endif
Domain Name Service subroutines. */
/*
- * Copyright (c) 2004-2007 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2007, 2009 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 2001-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
* <info@isc.org>
* https://www.isc.org/
*
- * This software has been written for Internet Systems Consortium
- * by Ted Lemon in cooperation with Nominum, Inc.
- * To learn more about Internet Systems Consortium, see
- * ``https://www.isc.org/''. To learn more about Nominum, Inc., see
- * ``http://www.nominum.com''.
+ * The original software was written for Internet Systems Consortium
+ * by Ted Lemon it has since been extensively modified to use the
+ * asynchronous DNS routines.
*/
#include "dhcpd.h"
#include "arpa/nameser.h"
-#include "dst/md5.h"
+#include <isc/md5.h>
-/* This file is kind of a crutch for the BIND 8 nsupdate code, which has
- * itself been cruelly hacked from its original state. What this code
- * does is twofold: first, it maintains a database of zone cuts that can
+#include <dns/result.h>
+
+/*
+ * This file contains code to connect the DHCP code to the libdns modules.
+ * As part of that function it maintains a database of zone cuts that can
* be used to figure out which server should be contacted to update any
- * given domain name. Secondly, it maintains a set of named TSIG keys,
- * and associates those keys with zones. When an update is requested for
- * a particular zone, the key associated with that zone is used for the
- * update.
+ * given domain name. Included in the zone information may be a pointer
+ * to a key in which case that key is used for the update. If no zone
+ * is found then the DNS code determines the zone on its own.
*
* The way this works is that you define the domain name to which an
* SOA corresponds, and the addresses of some primaries for that domain name:
* "FOO.COM" above, even though theoretically it should try GAZANGA...
* and TOPANGA... first.
*
- * If the update fails with a predefined or cached zone (we'll get to
- * those in a second), then it tries to find a more specific zone. This
- * is done by looking first for an SOA for GAZANGA.TOPANGA.FOO.COM. Then
- * an SOA for TOPANGA.FOO.COM is sought. If during this search a predefined
- * or cached zone is found, the update fails - there's something wrong
- * somewhere.
+ * If the update fails with a predefined zone the zone is marked as bad
+ * and another search of the predefined zones is done. If no predefined
+ * zone is found finding a zone is left to the DNS module via examination
+ * of SOA records. If the DNS module finds a zone it may cache the zone
+ * but the zone won't be cached here.
*
- * If a more specific zone _is_ found, that zone is cached for the length of
- * its TTL in the same database as that described above. TSIG updates are
- * never done for cached zones - if you want TSIG updates you _must_
- * write a zone definition linking the key to the zone. In cases where you
- * know for sure what the key is but do not want to hardcode the IP addresses
- * of the primary or secondaries, a zone declaration can be made that doesn't
- * include any primary or secondary declarations. When the DHCP server
- * encounters this while hunting up a matching zone for a name, it looks up
- * the SOA, fills in the IP addresses, and uses that record for the update.
+ * TSIG updates are not performed on zones found by the DNS module - if
+ * you want TSIG updates you _must_ write a zone definition linking the
+ * key to the zone. In cases where you know for sure what the key is
+ * but do not want to hardcode the IP addresses of the primary or
+ * secondaries, a zone declaration can be made that doesn't include any
+ * primary or secondary declarations. When the DHCP server encounters
+ * this while hunting up a matching zone for a name, it looks up the SOA,
+ * fills in the IP addresses, and uses that record for the update.
* If the SOA lookup returns NXRRSET, a warning is printed and the zone is
- * discarded, TSIG key and all. The search for the zone then continues as if
- * the zone record hadn't been found. Zones without IP addresses don't
- * match when initially hunting for a predefined or cached zone to update.
+ * discarded, TSIG key and all. The search for the zone then continues
+ * as if the zone record hadn't been found. Zones without IP addresses
+ * don't match when initially hunting for a zone to update.
*
- * When an update is attempted and no predefined or cached zone is found
+ * When an update is attempted and no predefined zone is found
* that matches any enclosing domain of the domain being updated, the DHCP
* server goes through the same process that is done when the update to a
- * predefined or cached zone fails - starting with the most specific domain
+ * predefined zone fails - starting with the most specific domain
* name (GAZANGA.TOPANGA.FOO.COM) and moving to the least specific (the root),
- * it tries to look up an SOA record. When it finds one, it creates a cached
- * zone and attempts an update, and gives up if the update fails.
+ * it tries to look up an SOA record.
*
* TSIG keys are defined like this:
*
* and the key type must be one of the key types defined in the draft
* or by the IANA. Currently only the HMAC-MD5... key type is
* supported.
+ *
+ * The DDNS processing has been split into two areas. One is the
+ * control code that determines what should be done. That code is found
+ * in the client or server directories. The other is the common code
+ * that performs functions such as properly formatting the arguments.
+ * That code is found in this file. The basic processing flow for a
+ * DDNS update is:
+ * In the client or server code determine what needs to be done and
+ * collect the necesary information then pass it to a function from
+ * this file.
+ * In this code lookup the zone and extract the zone and key information
+ * (if available) and prepare the arguments for the DNS module.
+ * When the DNS module completes its work (times out or gets a reply)
+ * it will trigger another function here which does generic processing
+ * and then passes control back to the code from the server or client.
+ * The server or client code then determines the next step which may
+ * result in another call to this module in which case the process repeats.
*/
dns_zone_hash_t *dns_zone_hash;
+/*
+ * DHCP dns structures
+ * Normally the relationship between these structures isn't one to one
+ * but in the DHCP case it (mostly) is. To make the allocations, frees,
+ * and passing of the memory easier we make a single structure with all
+ * the pieces.
+ *
+ * The maximum size of the data buffer should be large enough for any
+ * items DHCP will generate
+ */
+
+typedef struct dhcp_ddns_rdata {
+ dns_rdata_t rdata;
+ dns_rdatalist_t rdatalist;
+ dns_rdataset_t rdataset;
+} dhcp_ddns_data_t;
+
#if defined (NSUPDATE)
+
+/*
+ * Code to allocate and free a dddns control block. This block is used
+ * to pass and track the information associated with a DDNS update request.
+ */
+dhcp_ddns_cb_t *
+ddns_cb_alloc(const char *file, int line)
+{
+ dhcp_ddns_cb_t *ddns_cb;
+ int i;
+
+ ddns_cb = dmalloc(sizeof(*ddns_cb), file, line);
+ if (ddns_cb != NULL) {
+ ISC_LIST_INIT(ddns_cb->zone_server_list);
+ for (i = 0; i < DHCP_MAXNS; i++) {
+ ISC_LINK_INIT(&ddns_cb->zone_addrs[i], link);
+ }
+ }
+
+ return(ddns_cb);
+}
+
+void
+ddns_cb_free(dhcp_ddns_cb_t *ddns_cb, const char *file, int line)
+{
+ data_string_forget(&ddns_cb->fwd_name, file, line);
+ data_string_forget(&ddns_cb->rev_name, file, line);
+ data_string_forget(&ddns_cb->dhcid, file, line);
+
+ if (ddns_cb->zone != NULL) {
+ forget_zone((struct dns_zone **)&ddns_cb->zone);
+ }
+
+ dfree(ddns_cb, file, line);
+}
+
+void
+ddns_cb_forget_zone(dhcp_ddns_cb_t *ddns_cb)
+{
+ int i;
+
+ forget_zone(&ddns_cb->zone);
+ ddns_cb->zone_name[0] = 0;
+ ISC_LIST_INIT(ddns_cb->zone_server_list);
+ for (i = 0; i < DHCP_MAXNS; i++) {
+ ISC_LINK_INIT(&ddns_cb->zone_addrs[i], link);
+ }
+}
+
isc_result_t find_tsig_key (ns_tsig_key **key, const char *zname,
struct dns_zone *zone)
{
return ISC_R_NOTFOUND;
if (!zone -> key) {
- return ISC_R_KEY_UNKNOWN;
+ return DHCP_R_KEY_UNKNOWN;
}
if ((!zone -> key -> name ||
(!zone -> key) ||
(!zone -> key -> key) ||
(zone -> key -> key -> len == 0)) {
- return ISC_R_INVALIDKEY;
+ return DHCP_R_INVALIDKEY;
}
tkey = dmalloc (sizeof *tkey, MDL);
if (!tkey) {
if (!dns_zone_new_hash(&dns_zone_hash, DNS_HASH_SIZE, MDL))
return ISC_R_NOMEMORY;
}
+
dns_zone_hash_add (dns_zone_hash, zone -> name, 0, zone, MDL);
return ISC_R_SUCCESS;
}
}
#if defined (NSUPDATE)
-isc_result_t find_cached_zone (const char *dname, ns_class class,
- char *zname, size_t zsize,
- struct in_addr *addrs,
- int naddrs, int *naddrout,
- struct dns_zone **zcookie)
+isc_result_t
+find_cached_zone(dhcp_ddns_cb_t *ddns_cb, int direction)
{
isc_result_t status = ISC_R_NOTFOUND;
const char *np;
struct dns_zone *zone = (struct dns_zone *)0;
struct data_string nsaddrs;
+ struct in_addr zone_addr;
int ix;
- /* The absence of the zcookie pointer indicates that we
- succeeded previously, but the update itself failed, meaning
- that we shouldn't use the cached zone. */
- if (!zcookie)
- return ISC_R_NOTFOUND;
+ if (direction == FIND_FORWARD) {
+ np = (const char *)ddns_cb->fwd_name.data;
+ } else {
+ np = (const char *)ddns_cb->rev_name.data;
+ }
/* We can't look up a null zone. */
- if (!dname || !*dname)
- return ISC_R_INVALIDARG;
+ if ((np == NULL) || (*np == '\0')) {
+ return DHCP_R_INVALIDARG;
+ }
- /* For each subzone, try to find a cached zone. */
- for (np = dname; np; np = strchr (np, '.')) {
+ /*
+ * For each subzone, try to find a cached zone.
+ * Skip the first zone as that shouldn't work.
+ */
+ for (np = strchr(np, '.'); np != NULL; np = strchr(np, '.')) {
np++;
status = dns_zone_lookup (&zone, np);
if (status == ISC_R_SUCCESS)
}
/* Make sure the zone name will fit. */
- if (strlen (zone -> name) > zsize) {
+ if (strlen(zone->name) > sizeof(ddns_cb->zone_name)) {
dns_zone_dereference (&zone, MDL);
return ISC_R_NOSPACE;
}
- strcpy (zname, zone -> name);
+ strcpy((char *)&ddns_cb->zone_name[0], zone->name);
memset (&nsaddrs, 0, sizeof nsaddrs);
ix = 0;
&global_scope,
zone -> primary, MDL)) {
int ip = 0;
- while (ix < naddrs) {
+ while (ix < DHCP_MAXNS) {
if (ip + 4 > nsaddrs.len)
break;
- memcpy (&addrs [ix], &nsaddrs.data [ip], 4);
+ memcpy(&zone_addr, &nsaddrs.data[ip], 4);
+ isc_sockaddr_fromin(&ddns_cb->zone_addrs[ix],
+ &zone_addr,
+ NS_DEFAULTPORT);
+ ISC_LIST_APPEND(ddns_cb->zone_server_list,
+ &ddns_cb->zone_addrs[ix],
+ link);
ip += 4;
ix++;
}
&global_scope,
zone -> secondary, MDL)) {
int ip = 0;
- while (ix < naddrs) {
+ while (ix < DHCP_MAXNS) {
if (ip + 4 > nsaddrs.len)
break;
- memcpy (&addrs [ix], &nsaddrs.data [ip], 4);
+ memcpy(&zone_addr, &nsaddrs.data[ip], 4);
+ isc_sockaddr_fromin(&ddns_cb->zone_addrs[ix],
+ &zone_addr,
+ NS_DEFAULTPORT);
+ ISC_LIST_APPEND(ddns_cb->zone_server_list,
+ &ddns_cb->zone_addrs[ix],
+ link);
ip += 4;
ix++;
}
}
}
- /* It's not an error for zcookie to have a value here - actually,
- it's quite likely, because res_nupdate cycles through all the
- names in the update looking for their zones. */
- if (!*zcookie)
- dns_zone_reference (zcookie, zone, MDL);
+ dns_zone_reference(&ddns_cb->zone, zone, MDL);
dns_zone_dereference (&zone, MDL);
- if (naddrout)
- *naddrout = ix;
return ISC_R_SUCCESS;
}
dns_zone_dereference (zone, MDL);
}
-void cache_found_zone (ns_class class,
- char *zname, struct in_addr *addrs, int naddrs)
-{
- struct dns_zone *zone = (struct dns_zone *)0;
- int ix = strlen (zname);
-
- if (zname [ix - 1] == '.')
- ix = 0;
-
- /* See if there's already such a zone. */
- if (dns_zone_lookup (&zone, zname) == ISC_R_SUCCESS) {
- /* If it's not a dynamic zone, leave it alone. */
- if (!zone -> timeout)
- return;
- /* Address may have changed, so just blow it away. */
- if (zone -> primary)
- option_cache_dereference (&zone -> primary, MDL);
- if (zone -> secondary)
- option_cache_dereference (&zone -> secondary, MDL);
- } else if (!dns_zone_allocate (&zone, MDL))
- return;
-
- if (!zone -> name) {
- zone -> name =
- dmalloc (strlen (zname) + 1 + (ix != 0), MDL);
- if (!zone -> name) {
- dns_zone_dereference (&zone, MDL);
- return;
- }
- strcpy (zone -> name, zname);
- /* Add a trailing '.' if it was missing. */
- if (ix) {
- zone -> name [ix] = '.';
- zone -> name [ix + 1] = 0;
- }
- }
-
- /* XXX Need to get the lower-level code to push the actual zone
- XXX TTL up to us. */
- zone -> timeout = cur_time + 1800;
-
- if (!option_cache_allocate (&zone -> primary, MDL)) {
- dns_zone_dereference (&zone, MDL);
- return;
- }
- if (!buffer_allocate (&zone -> primary -> data.buffer,
- naddrs * sizeof (struct in_addr), MDL)) {
- dns_zone_dereference (&zone, MDL);
- return;
- }
- memcpy (zone -> primary -> data.buffer -> data,
- addrs, naddrs * sizeof *addrs);
- zone -> primary -> data.data =
- &zone -> primary -> data.buffer -> data [0];
- zone -> primary -> data.len = naddrs * sizeof *addrs;
-
- enter_dns_zone (zone);
-}
-
/* Have to use TXT records for now. */
#define T_DHCID T_TXT
int get_dhcid (struct data_string *id,
int type, const u_int8_t *data, unsigned len)
{
- unsigned char buf[MD5_DIGEST_LENGTH];
- MD5_CTX md5;
+ unsigned char buf[ISC_MD5_DIGESTLENGTH];
+ isc_md5_t md5;
int i;
/* Types can only be 0..(2^16)-1. */
if (type < 0 || type > 65535)
return 0;
- /* Hexadecimal MD5 digest plus two byte type and NUL. */
+ /*
+ * Hexadecimal MD5 digest plus two byte type, NUL,
+ * and one byte for length for dns.
+ */
if (!buffer_allocate (&id -> buffer,
- (MD5_DIGEST_LENGTH * 2) + 3, MDL))
+ (ISC_MD5_DIGESTLENGTH * 2) + 4, MDL))
return 0;
id -> data = id -> buffer -> data;
* -- "Interaction between DHCP and DNS"
* <draft-ietf-dhc-dhcp-dns-12.txt>
* M. Stapp, Y. Rekhter
+ *
+ * We put the length into the first byte to turn
+ * this into a dns text string. This avoid needing to
+ * copy the string to add the byte later.
*/
+ id->buffer->data[0] = ISC_MD5_DIGESTLENGTH * 2 + 2;
- /* Put the type in the first two bytes. */
- id -> buffer -> data [0] = "0123456789abcdef" [type >> 4];
- id -> buffer -> data [1] = "0123456789abcdef" [type % 15];
-
+ /* Put the type in the next two bytes. */
+ id->buffer->data[1] = "0123456789abcdef"[type >> 4];
+ id->buffer->data[2] = "0123456789abcdef"[type % 15];
+
/* Mash together an MD5 hash of the identifier. */
- MD5_Init (&md5);
- MD5_Update (&md5, data, len);
- MD5_Final (buf, &md5);
+ isc_md5_init(&md5);
+ isc_md5_update(&md5, data, len);
+ isc_md5_final(&md5, buf);
/* Convert into ASCII. */
- for (i = 0; i < MD5_DIGEST_LENGTH; i++) {
- id -> buffer -> data [i * 2 + 2] =
- "0123456789abcdef" [(buf [i] >> 4) & 0xf];
- id -> buffer -> data [i * 2 + 3] =
- "0123456789abcdef" [buf [i] & 0xf];
+ for (i = 0; i < ISC_MD5_DIGESTLENGTH; i++) {
+ id->buffer->data[i * 2 + 3] =
+ "0123456789abcdef"[(buf[i] >> 4) & 0xf];
+ id->buffer->data[i * 2 + 4] =
+ "0123456789abcdef"[buf[i] & 0xf];
}
- id -> len = MD5_DIGEST_LENGTH * 2 + 2;
- id -> buffer -> data [id -> len] = 0;
- id -> terminated = 1;
+
+ id->len = ISC_MD5_DIGESTLENGTH * 2 + 3;
+ id->buffer->data[id->len] = 0;
+ id->terminated = 1;
return 1;
}
-/* Now for the DDNS update code that is shared between client and
- server... */
+/*
+ * The dhcid (text version) that we pass to DNS includes a length byte
+ * at the start but the text we store in the lease doesn't include the
+ * length byte. The following routines are to convert between the two
+ * styles.
+ *
+ * When converting from a dhcid to a leaseid we reuse the buffer and
+ * simply adjust the data pointer and length fields in the data string.
+ * This avoids any prolems with allocating space.
+ */
+
+void
+dhcid_tolease(struct data_string *dhcid,
+ struct data_string *leaseid)
+{
+ /* copy the data string then update the fields */
+ data_string_copy(leaseid, dhcid, MDL);
+ leaseid->data++;
+ leaseid->len--;
+}
isc_result_t
-ddns_update_fwd(struct data_string *ddns_fwd_name, struct iaddr ddns_addr,
- struct data_string *ddns_dhcid, unsigned long ttl,
- unsigned rrsetp, unsigned conflict) {
- ns_updque updqueue;
- ns_updrec *updrec;
- isc_result_t result;
- const char *logstr;
- char ddns_address[
- sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
- int ddns_address_type;
-
- /*
- * We want to delete either A or AAAA records, depending on
- * whether we have an IPv4 or an IPv6 address.
- */
- if (ddns_addr.len == 4) {
- ddns_address_type = T_A;
- } else if (ddns_addr.len == 16) {
- ddns_address_type = T_AAAA;
- } else {
- return ISC_R_INVALIDARG;
+dhcid_fromlease(struct data_string *dhcid,
+ struct data_string *leaseid)
+{
+ if (!buffer_allocate(&dhcid->buffer, leaseid->len + 2, MDL)) {
+ return(ISC_R_FAILURE);
}
- strcpy(ddns_address, piaddr(ddns_addr));
- /*
- * When a DHCP client or server intends to update an A RR, it first
- * prepares a DNS UPDATE query which includes as a prerequisite the
- * assertion that the name does not exist. The update section of the
- * query attempts to add the new name and its IP address mapping (an A
- * RR), and the DHCID RR with its unique client-identity.
- * -- "Interaction between DHCP and DNS"
- */
+ dhcid->data = dhcid->buffer->data;
- ISC_LIST_INIT (updqueue);
-
- /*
- * A RR does not exist.
- */
- updrec = minires_mkupdrec (S_PREREQ,
- (const char *)ddns_fwd_name -> data,
- C_IN, ddns_address_type, 0);
- if (!updrec) {
- result = ISC_R_NOMEMORY;
- goto error;
+ dhcid->buffer->data[0] = leaseid->len;
+ memcpy(dhcid->buffer->data + 1, leaseid->data, leaseid->len);
+ dhcid->len = leaseid->len + 1;
+ if (leaseid->terminated == 1) {
+ dhcid->buffer->data[dhcid->len] = 0;
+ dhcid->terminated = 1;
}
- updrec -> r_data = (unsigned char *)0;
- updrec -> r_size = 0;
- updrec -> r_opcode = rrsetp ? NXRRSET : NXDOMAIN;
-
- ISC_LIST_APPEND (updqueue, updrec, r_link);
-
+ return(ISC_R_SUCCESS);
+}
- /*
- * Add A RR.
- */
- updrec = minires_mkupdrec (S_UPDATE,
- (const char *)ddns_fwd_name -> data,
- C_IN, ddns_address_type, ttl);
- if (!updrec) {
- result = ISC_R_NOMEMORY;
- goto error;
- }
+/*
+ * Construct the dataset for this item.
+ * This is a fairly simple arrangement as the operations we do are simple.
+ * If there is data we simply have the rdata point to it - the formatting
+ * must be correct already. We then link the rdatalist to the rdata and
+ * create a rdataset from the rdatalist.
+ */
- updrec -> r_data = (unsigned char *)ddns_address;
- updrec -> r_size = strlen (ddns_address);
- updrec -> r_opcode = ADD;
+static isc_result_t
+make_dns_dataset(dns_rdataclass_t dataclass,
+ dns_rdatatype_t datatype,
+ dhcp_ddns_data_t *dataspace,
+ unsigned char *data,
+ int datalen,
+ int ttl)
+{
+ dns_rdata_t *rdata = &dataspace->rdata;
+ dns_rdatalist_t *rdatalist = &dataspace->rdatalist;;
+ dns_rdataset_t *rdataset = &dataspace->rdataset;
- ISC_LIST_APPEND (updqueue, updrec, r_link);
+ isc_region_t region;
+ /* set up the rdata */
+ dns_rdata_init(rdata);
- /*
- * Add DHCID RR.
- */
- updrec = minires_mkupdrec (S_UPDATE,
- (const char *)ddns_fwd_name -> data,
- C_IN, T_DHCID, ttl);
- if (!updrec) {
- result = ISC_R_NOMEMORY;
- goto error;
+ if (data == NULL) {
+ /* No data, set up the rdata fields we care about */
+ rdata->flags = DNS_RDATA_UPDATE;
+ rdata->type = datatype;
+ rdata->rdclass = dataclass;
+ } else {
+ switch(datatype) {
+ case dns_rdatatype_a:
+ case dns_rdatatype_aaaa:
+ case dns_rdatatype_txt:
+ case dns_rdatatype_dhcid:
+ case dns_rdatatype_ptr:
+ /* The data must be in the right format we simply
+ * need to supply it via the correct structure */
+ region.base = data;
+ region.length = datalen;
+ dns_rdata_fromregion(rdata, dataclass, datatype,
+ ®ion);
+ break;
+ default:
+ return(DHCP_R_INVALIDARG);
+ break;
+ }
}
- updrec -> r_data = ddns_dhcid -> data;
- updrec -> r_size = ddns_dhcid -> len;
- updrec -> r_opcode = ADD;
-
- ISC_LIST_APPEND (updqueue, updrec, r_link);
+ /* setup the datalist and attach the rdata to it */
+ dns_rdatalist_init(rdatalist);
+ rdatalist->type = datatype;
+ rdatalist->rdclass = dataclass;
+ rdatalist->ttl = ttl;
+ ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
+ /* convert the datalist to a dataset */
+ dns_rdataset_init(rdataset);
+ dns_rdatalist_tordataset(rdatalist, rdataset);
- /*
- * Attempt to perform the update.
- */
- result = minires_nupdate (&resolver_state, ISC_LIST_HEAD (updqueue));
+ return(ISC_R_SUCCESS);
+}
-#ifdef DEBUG_DNS_UPDATES
- print_dns_status ((int)result, &updqueue);
-#endif
+/*
+ * When a DHCP client or server intends to update an A RR, it first
+ * prepares a DNS UPDATE query which includes as a prerequisite the
+ * assertion that the name does not exist. The update section of the
+ * query attempts to add the new name and its IP address mapping (an A
+ * RR), and the DHCID RR with its unique client-identity.
+ * -- "Interaction between DHCP and DNS"
+ *
+ * There are two cases, one for the server and one for the client.
+ *
+ * For the server the first step will have a request of:
+ * The name is not in use
+ * Add an A RR
+ * Add a DHCID RR (currently txt)
+ *
+ * For the client the first step will have a request of:
+ * The A RR does not exist
+ * Add an A RR
+ * Add a DHCID RR (currently txt)
+ */
- /*
- * If this update operation succeeds, the updater can conclude that it
- * has added a new name whose only RRs are the A and DHCID RR records.
- * The A RR update is now complete (and a client updater is finished,
- * while a server might proceed to perform a PTR RR update).
- * -- "Interaction between DHCP and DNS"
- */
+static isc_result_t
+ddns_modify_fwd_add1(dhcp_ddns_cb_t *ddns_cb,
+ dhcp_ddns_data_t *dataspace,
+ dns_name_t *pname,
+ dns_name_t *uname)
+{
+ isc_result_t result;
- if (result == ISC_R_SUCCESS) {
- log_info ("Added new forward map from %.*s to %s",
- (int)ddns_fwd_name -> len,
- (const char *)ddns_fwd_name -> data, ddns_address);
- goto error;
+ /* Construct the prerequisite list */
+ if ((ddns_cb->flags & DDNS_INCLUDE_RRSET) != 0) {
+ /* The A RR shouldn't exist */
+ result = make_dns_dataset(dns_rdataclass_none,
+ ddns_cb->address_type,
+ dataspace, NULL, 0, 0);
+ } else {
+ /* The name is not in use */
+ result = make_dns_dataset(dns_rdataclass_none,
+ dns_rdatatype_any,
+ dataspace, NULL, 0, 0);
}
+ if (result != ISC_R_SUCCESS) {
+ return(result);
+ }
+ ISC_LIST_APPEND(pname->list, &dataspace->rdataset, link);
+ dataspace++;
+
+ /* Construct the update list */
+ /* Add the A RR */
+ result = make_dns_dataset(dns_rdataclass_in, ddns_cb->address_type,
+ dataspace,
+ (unsigned char *)ddns_cb->address.iabuf,
+ ddns_cb->address.len, ddns_cb->ttl);
+ if (result != ISC_R_SUCCESS) {
+ return(result);
+ }
+ ISC_LIST_APPEND(uname->list, &dataspace->rdataset, link);
+ dataspace++;
+
+ /* Add the DHCID RR */
+ result = make_dns_dataset(dns_rdataclass_in, dns_rdatatype_txt,
+ dataspace,
+ (unsigned char *)ddns_cb->dhcid.data,
+ ddns_cb->dhcid.len, ddns_cb->ttl);
+ if (result != ISC_R_SUCCESS) {
+ return(result);
+ }
+ ISC_LIST_APPEND(uname->list, &dataspace->rdataset, link);
+ return(ISC_R_SUCCESS);
+}
- /*
- * If the first update operation fails with YXDOMAIN, the updater can
- * conclude that the intended name is in use. The updater then
- * attempts to confirm that the DNS name is not being used by some
- * other host. The updater prepares a second UPDATE query in which the
- * prerequisite is that the desired name has attached to it a DHCID RR
- * whose contents match the client identity. The update section of
- * this query deletes the existing A records on the name, and adds the
- * A record that matches the DHCP binding and the DHCID RR with the
- * client identity.
- * -- "Interaction between DHCP and DNS"
- */
-
- if (result != (rrsetp ? ISC_R_YXRRSET : ISC_R_YXDOMAIN)) {
- log_error ("Unable to add forward map from %.*s to %s: %s",
- (int)ddns_fwd_name -> len,
- (const char *)ddns_fwd_name -> data, ddns_address,
- isc_result_totext (result));
- goto error;
- }
+/*
+ * If the first update operation fails with YXDOMAIN, the updater can
+ * conclude that the intended name is in use. The updater then
+ * attempts to confirm that the DNS name is not being used by some
+ * other host. The updater prepares a second UPDATE query in which the
+ * prerequisite is that the desired name has attached to it a DHCID RR
+ * whose contents match the client identity. The update section of
+ * this query deletes the existing A records on the name, and adds the
+ * A record that matches the DHCP binding and the DHCID RR with the
+ * client identity.
+ * -- "Interaction between DHCP and DNS"
+ *
+ * The message for the second step depends on if we are doing conflict
+ * resolution. If we are we include a prerequisite. If not we delete
+ * the DHCID in addition to all A rrsets.
+ *
+ * Conflict resolution:
+ * DHCID RR exists, and matches client identity.
+ * Delete A RRset.
+ * Add A RR.
+ *
+ * Conflict override:
+ * Delete DHCID RRs.
+ * Add DHCID RR
+ * Delete A RRset.
+ * Add A RR.
+ */
- while (!ISC_LIST_EMPTY (updqueue)) {
- updrec = ISC_LIST_HEAD (updqueue);
- ISC_LIST_UNLINK (updqueue, updrec, r_link);
- minires_freeupdrec (updrec);
- }
+static isc_result_t
+ddns_modify_fwd_add2(dhcp_ddns_cb_t *ddns_cb,
+ dhcp_ddns_data_t *dataspace,
+ dns_name_t *pname,
+ dns_name_t *uname)
+{
+ isc_result_t result;
- /* If we're doing conflict resolution, we use a set of prereqs. If
- * not, we delete the DHCID in addition to all A rrsets.
+ /*
+ * If we are doing conflict resolution (unset) we use a prereq list.
+ * If not we delete the DHCID in addition to all A rrsets.
*/
- if (conflict) {
- /*
- * DHCID RR exists, and matches client identity.
- */
- updrec = minires_mkupdrec (S_PREREQ,
- (const char *)ddns_fwd_name -> data,
- C_IN, T_DHCID, 0);
- if (!updrec) {
- result = ISC_R_NOMEMORY;
- goto error;
+ if ((ddns_cb->flags & DDNS_CONFLICT_OVERRIDE) == 0) {
+ /* Construct the prereq list */
+ /* The DHCID RR exists and matches the client identity */
+ result = make_dns_dataset(dns_rdataclass_in, dns_rdatatype_txt,
+ dataspace,
+ (unsigned char *)ddns_cb->dhcid.data,
+ ddns_cb->dhcid.len, 0);
+ if (result != ISC_R_SUCCESS) {
+ return(result);
}
-
- updrec -> r_data = ddns_dhcid -> data;
- updrec -> r_size = ddns_dhcid -> len;
- updrec -> r_opcode = YXRRSET;
-
- ISC_LIST_APPEND (updqueue, updrec, r_link);
+ ISC_LIST_APPEND(pname->list, &dataspace->rdataset, link);
+ dataspace++;
} else {
- /*
- * Conflict detection override: delete DHCID RRs.
- */
- updrec = minires_mkupdrec(S_UPDATE,
- (const char *)ddns_fwd_name->data,
- C_IN, T_DHCID, 0);
-
- if (!updrec) {
- result = ISC_R_NOMEMORY;
- goto error;
+ /* Start constructing the update list.
+ * Conflict detection override: delete DHCID RRs */
+ result = make_dns_dataset(dns_rdataclass_any,
+ dns_rdatatype_txt,
+ dataspace, NULL, 0, 0);
+ if (result != ISC_R_SUCCESS) {
+ return(result);
}
-
- updrec->r_data = NULL;
- updrec->r_size = 0;
- updrec->r_opcode = DELETE;
-
- ISC_LIST_APPEND(updqueue, updrec, r_link);
-
-
- /*
- * With all other DHCID RR's deleted, add this client's
- * DHCID unconditionally (as update-conflict-detection is
- * disabled).
- */
- updrec = minires_mkupdrec(S_UPDATE,
- (const char *)ddns_fwd_name->data,
- C_IN, T_DHCID, ttl);
- if (!updrec) {
- result = ISC_R_NOMEMORY;
- goto error;
+ ISC_LIST_APPEND(uname->list, &dataspace->rdataset, link);
+ dataspace++;
+
+ /* Add current DHCID RR */
+ result = make_dns_dataset(dns_rdataclass_in, dns_rdatatype_txt,
+ dataspace,
+ (unsigned char *)ddns_cb->dhcid.data,
+ ddns_cb->dhcid.len, ddns_cb->ttl);
+ if (result != ISC_R_SUCCESS) {
+ return(result);
}
-
- updrec->r_data = ddns_dhcid->data;
- updrec->r_size = ddns_dhcid->len;
- updrec->r_opcode = ADD;
-
- ISC_LIST_APPEND (updqueue, updrec, r_link);
+ ISC_LIST_APPEND(uname->list, &dataspace->rdataset, link);
+ dataspace++;
}
-
- /*
- * Delete A RRset.
- */
- updrec = minires_mkupdrec (S_UPDATE,
- (const char *)ddns_fwd_name -> data,
- C_IN, ddns_address_type, 0);
- if (!updrec) {
- result = ISC_R_NOMEMORY;
- goto error;
+ /* Start or continue constructing the update list */
+ /* Delete the A RRset */
+ result = make_dns_dataset(dns_rdataclass_any, ddns_cb->address_type,
+ dataspace, NULL, 0, 0);
+ if (result != ISC_R_SUCCESS) {
+ return(result);
}
+ ISC_LIST_APPEND(uname->list, &dataspace->rdataset, link);
+ dataspace++;
+
+ /* Add the A RR */
+ result = make_dns_dataset(dns_rdataclass_in, ddns_cb->address_type,
+ dataspace,
+ (unsigned char *)ddns_cb->address.iabuf,
+ ddns_cb->address.len, ddns_cb->ttl);
+ if (result != ISC_R_SUCCESS) {
+ return(result);
+ }
+ ISC_LIST_APPEND(uname->list, &dataspace->rdataset, link);
- updrec -> r_data = (unsigned char *)0;
- updrec -> r_size = 0;
- updrec -> r_opcode = DELETE;
+ return(ISC_R_SUCCESS);
+}
- ISC_LIST_APPEND (updqueue, updrec, r_link);
+/*
+ * The entity chosen to handle the A record for this client (either the
+ * client or the server) SHOULD delete the A record that was added when
+ * the lease was made to the client.
+ *
+ * In order to perform this delete, the updater prepares an UPDATE
+ * query which contains two prerequisites. The first prerequisite
+ * asserts that the DHCID RR exists whose data is the client identity
+ * described in Section 4.3. The second prerequisite asserts that the
+ * data in the A RR contains the IP address of the lease that has
+ * expired or been released.
+ * -- "Interaction between DHCP and DNS"
+ *
+ * First try has:
+ * DHCID RR exists, and matches client identity.
+ * A RR matches the expiring lease.
+ * Delete appropriate A RR.
+ */
+static isc_result_t
+ddns_modify_fwd_rem1(dhcp_ddns_cb_t *ddns_cb,
+ dhcp_ddns_data_t *dataspace,
+ dns_name_t *pname,
+ dns_name_t *uname)
+{
+ isc_result_t result;
- /*
- * Add A RR.
- */
- updrec = minires_mkupdrec (S_UPDATE,
- (const char *)ddns_fwd_name -> data,
- C_IN, ddns_address_type, ttl);
- if (!updrec) {
- result = ISC_R_NOMEMORY;
- goto error;
+ /* Consruct the prereq list */
+ /* The DHCID RR exists and matches the client identity */
+ result = make_dns_dataset(dns_rdataclass_in, dns_rdatatype_txt,
+ dataspace,
+ (unsigned char *)ddns_cb->dhcid.data,
+ ddns_cb->dhcid.len, 0);
+ if (result != ISC_R_SUCCESS) {
+ return(result);
+ }
+ ISC_LIST_APPEND(pname->list, &dataspace->rdataset, link);
+ dataspace++;
+
+ /* The A RR matches the expiring lease */
+ result = make_dns_dataset(dns_rdataclass_in, ddns_cb->address_type,
+ dataspace,
+ (unsigned char *)ddns_cb->address.iabuf,
+ ddns_cb->address.len, 0);
+ if (result != ISC_R_SUCCESS) {
+ return(result);
}
+ ISC_LIST_APPEND(pname->list, &dataspace->rdataset, link);
+ dataspace++;
+
+ /* Construct the update list */
+ /* Delete A RRset */
+ result = make_dns_dataset(dns_rdataclass_none, ddns_cb->address_type,
+ dataspace,
+ (unsigned char *)ddns_cb->address.iabuf,
+ ddns_cb->address.len, 0);
+ if (result != ISC_R_SUCCESS) {
+ return(result);
+ }
+ ISC_LIST_APPEND(uname->list, &dataspace->rdataset, link);
- updrec -> r_data = (unsigned char *)ddns_address;
- updrec -> r_size = strlen (ddns_address);
- updrec -> r_opcode = ADD;
+ return(ISC_R_SUCCESS);
+}
- ISC_LIST_APPEND (updqueue, updrec, r_link);
+/*
+ * If the deletion of the A succeeded, and there are no A or AAAA
+ * records left for this domain, then we can blow away the DHCID
+ * record as well. We can't blow away the DHCID record above
+ * because it's possible that more than one record has been added
+ * to this domain name.
+ *
+ * Second query has:
+ * A RR does not exist.
+ * AAAA RR does not exist.
+ * Delete appropriate DHCID RR.
+ */
+static isc_result_t
+ddns_modify_fwd_rem2(dhcp_ddns_cb_t *ddns_cb,
+ dhcp_ddns_data_t *dataspace,
+ dns_name_t *pname,
+ dns_name_t *uname)
+{
+ isc_result_t result;
- /*
- * Attempt to perform the update.
- */
- result = minires_nupdate (&resolver_state, ISC_LIST_HEAD (updqueue));
+ /* Construct the prereq list */
+ /* The A RR does not exist */
+ result = make_dns_dataset(dns_rdataclass_none, dns_rdatatype_a,
+ dataspace, NULL, 0, 0);
+ if (result != ISC_R_SUCCESS) {
+ return(result);
+ }
+ ISC_LIST_APPEND(pname->list, &dataspace->rdataset, link);
+ dataspace++;
- switch (result) {
- case ISC_R_SUCCESS:
- logstr = NULL;
- break;
+ /* The AAAA RR does not exist */
+ result = make_dns_dataset(dns_rdataclass_none, dns_rdatatype_aaaa,
+ dataspace, NULL, 0, 0);
+ if (result != ISC_R_SUCCESS) {
+ return(result);
+ }
+ ISC_LIST_APPEND(pname->list, &dataspace->rdataset, link);
+ dataspace++;
+
+ /* Construct the update list */
+ /* Delete DHCID RR */
+ result = make_dns_dataset(dns_rdataclass_none, dns_rdatatype_txt,
+ dataspace,
+ (unsigned char *)ddns_cb->dhcid.data,
+ ddns_cb->dhcid.len, 0);
+ if (result != ISC_R_SUCCESS) {
+ return(result);
+ }
+ ISC_LIST_APPEND(uname->list, &dataspace->rdataset, link);
- case ISC_R_YXRRSET:
- case ISC_R_YXDOMAIN:
- logstr = "DHCID mismatch, belongs to another client.";
- break;
+ return(ISC_R_SUCCESS);
+}
- case ISC_R_NXRRSET:
- case ISC_R_NXDOMAIN:
- logstr = "Has an address record but no DHCID, not mine.";
- break;
+/*
+ * This routine converts from the task action call into something
+ * easier to work with. It also handles the common case of a signature
+ * or zone not being correct.
+ */
+void ddns_interlude(isc_task_t *taskp,
+ isc_event_t *eventp)
+{
+ dhcp_ddns_cb_t *ddns_cb = (dhcp_ddns_cb_t *)eventp->ev_arg;
+ dns_clientupdateevent_t *ddns_event = (dns_clientupdateevent_t *)eventp;
+ isc_result_t eresult = ddns_event->result;
+ isc_result_t result;
- default:
- logstr = isc_result_totext(result);
- break;
- }
+ /* We've extracted the information we want from it, get rid of
+ * the event block.*/
+ isc_event_free(&eventp);
- if (logstr != NULL)
- log_error("Forward map from %.*s to %s FAILED: %s",
- (int)ddns_fwd_name -> len,
- (const char *)ddns_fwd_name -> data,
- ddns_address, logstr);
- else
- log_info("Added new forward map from %.*s to %s",
- (int)ddns_fwd_name -> len,
- (const char *)ddns_fwd_name -> data, ddns_address);
+ /* This transaction is complete, clear the value */
+ ddns_cb->transaction = NULL;
-#if defined (DEBUG_DNS_UPDATES)
- print_dns_status ((int)result, &updqueue);
-#endif
+ /* If we cancelled or tried to cancel the operation we just
+ * need to clean up. */
+ if ((eresult == ISC_R_CANCELED) ||
+ ((ddns_cb->flags & DDNS_ABORT) != 0)) {
+ if (ddns_cb->next_op != NULL) {
+ /* if necessary cleanup up next op block */
+ ddns_cb_free(ddns_cb->next_op, MDL);
+ }
+ ddns_cb_free(ddns_cb, MDL);
+ return;
+ }
- /*
- * If this query succeeds, the updater can conclude that the current
- * client was the last client associated with the domain name, and that
- * the name now contains the updated A RR. The A RR update is now
- * complete (and a client updater is finished, while a server would
- * then proceed to perform a PTR RR update).
- * -- "Interaction between DHCP and DNS"
- */
+ /* If we had a problem with our key or zone try again */
+ if ((eresult == DNS_R_NOTAUTH) ||
+ (eresult == DNS_R_NOTZONE)) {
+ int i;
+ /* Our zone information was questionable,
+ * repudiate it and try again */
+ repudiate_zone(&ddns_cb->zone);
+ ddns_cb->zone_name[0] = 0;
+ ISC_LIST_INIT(ddns_cb->zone_server_list);
+ for (i = 0; i < DHCP_MAXNS; i++) {
+ ISC_LINK_INIT(&ddns_cb->zone_addrs[i], link);
+ }
- /*
- * If the second query fails with NXRRSET, the updater must conclude
- * that the client's desired name is in use by another host. At this
- * juncture, the updater can decide (based on some administrative
- * configuration outside of the scope of this document) whether to let
- * the existing owner of the name keep that name, and to (possibly)
- * perform some name disambiguation operation on behalf of the current
- * client, or to replace the RRs on the name with RRs that represent
- * the current client. If the configured policy allows replacement of
- * existing records, the updater submits a query that deletes the
- * existing A RR and the existing DHCID RR, adding A and DHCID RRs that
- * represent the IP address and client-identity of the new client.
- * -- "Interaction between DHCP and DNS"
- */
+ if ((ddns_cb->state &
+ (DDNS_STATE_ADD_PTR | DDNS_STATE_REM_PTR)) != 0) {
+ result = ddns_modify_ptr(ddns_cb);
+ } else {
+ result = ddns_modify_fwd(ddns_cb);
+ }
- error:
- while (!ISC_LIST_EMPTY (updqueue)) {
- updrec = ISC_LIST_HEAD (updqueue);
- ISC_LIST_UNLINK (updqueue, updrec, r_link);
- minires_freeupdrec (updrec);
+ if (result != ISC_R_SUCCESS) {
+ /* if we couldn't redo the query toss it */
+ if (ddns_cb->next_op != NULL) {
+ /* cleanup up next op block */
+ ddns_cb_free(ddns_cb->next_op, MDL);
+ }
+ ddns_cb_free(ddns_cb, MDL);
+ }
+ return;
+ } else {
+ /* pass it along to be processed */
+ ddns_cb->cur_func(ddns_cb, eresult);
}
-
- return result;
+
+ return;
}
+/*
+ * This routine does the generic work for sending a ddns message to
+ * modify the forward record (A or AAAA) and calls one of a set of
+ * routines to build the specific message.
+ */
+
isc_result_t
-ddns_remove_fwd(struct data_string *ddns_fwd_name,
- struct iaddr ddns_addr,
- struct data_string *ddns_dhcid) {
- ns_updque updqueue;
- ns_updrec *updrec;
- isc_result_t result = SERVFAIL;
- char ddns_address[
- sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
- int ddns_address_type;
-
- /*
- * We want to delete either A or AAAA records, depending on
- * whether we have an IPv4 or an IPv6 address.
- */
- if (ddns_addr.len == 4) {
- ddns_address_type = T_A;
- } else if (ddns_addr.len == 16) {
- ddns_address_type = T_AAAA;
+ddns_modify_fwd(dhcp_ddns_cb_t *ddns_cb)
+{
+ isc_result_t result;
+ dns_tsec_t *tsec_key = NULL;
+
+ unsigned char *clientname;
+ dhcp_ddns_data_t *dataspace = NULL;
+ dns_namelist_t prereqlist, updatelist;
+ dns_fixedname_t zname0, pname0, uname0;
+ dns_name_t *zname = NULL, *pname, *uname;
+
+ isc_sockaddrlist_t *zlist = NULL;
+
+ /* Get a pointer to the clientname to make things easier. */
+ clientname = (unsigned char *)ddns_cb->fwd_name.data;
+
+ /* Extract and validate the type of the address. */
+ if (ddns_cb->address.len == 4) {
+ ddns_cb->address_type = dns_rdatatype_a;
+ } else if (ddns_cb->address.len == 16) {
+ ddns_cb->address_type = dns_rdatatype_aaaa;
} else {
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
- strcpy(ddns_address, piaddr(ddns_addr));
/*
- * The entity chosen to handle the A record for this client (either the
- * client or the server) SHOULD delete the A record that was added when
- * the lease was made to the client.
- *
- * In order to perform this delete, the updater prepares an UPDATE
- * query which contains two prerequisites. The first prerequisite
- * asserts that the DHCID RR exists whose data is the client identity
- * described in Section 4.3. The second prerequisite asserts that the
- * data in the A RR contains the IP address of the lease that has
- * expired or been released.
- * -- "Interaction between DHCP and DNS"
+ * If we already have a zone use it, otherwise try to lookup the
+ * zone in our cache. If we find one we will have a pointer to
+ * the zone that needs to be dereferenced when we are done with it.
+ * If we don't find one that is okay we'll let the DNS code try and
+ * find the information for us.
*/
- ISC_LIST_INIT (updqueue);
+ if (ddns_cb->zone == NULL) {
+ result = find_cached_zone(ddns_cb, FIND_FORWARD);
+ }
/*
- * DHCID RR exists, and matches client identity.
+ * If we have a zone try to get any information we need
+ * from it - name, addresses and the key. The address
+ * and key may be empty the name can't be.
*/
- updrec = minires_mkupdrec (S_PREREQ,
- (const char *)ddns_fwd_name -> data,
- C_IN, T_DHCID,0);
- if (!updrec) {
- result = ISC_R_NOMEMORY;
- goto error;
+ if (ddns_cb->zone) {
+ /* Set up the zone name for use by DNS */
+ result = dhcp_isc_name(ddns_cb->zone_name, &zname0, &zname);
+ if (result != ISC_R_SUCCESS) {
+ log_error("Unable to build name for zone for "
+ "fwd update: %s %s",
+ ddns_cb->zone_name,
+ isc_result_totext(result));
+ goto cleanup;
+ }
+
+ if (!(ISC_LIST_EMPTY(ddns_cb->zone_server_list))) {
+ /* If we have any addresses get them */
+ zlist = &ddns_cb->zone_server_list;
+ }
+
+
+ if (ddns_cb->zone->key != NULL) {
+ /*
+ * Not having a key is fine, having a key
+ * but not a tsec is odd so we warn the user.
+ */
+ /*sar*/
+ /* should we do the warning? */
+ tsec_key = ddns_cb->zone->key->tsec_key;
+ if (tsec_key == NULL) {
+ log_error("No tsec for use with key %s",
+ ddns_cb->zone->key->name);
+ }
+ }
}
- updrec -> r_data = ddns_dhcid -> data;
- updrec -> r_size = ddns_dhcid -> len;
- updrec -> r_opcode = YXRRSET;
+ /* Set up the DNS names for the prereq and update lists */
+ if (((result = dhcp_isc_name(clientname, &pname0, &pname))
+ != ISC_R_SUCCESS) ||
+ ((result = dhcp_isc_name(clientname, &uname0, &uname))
+ != ISC_R_SUCCESS)) {
+ log_error("Unable to build name for fwd update: %s %s",
+ clientname, isc_result_totext(result));
+ goto cleanup;
+ }
- ISC_LIST_APPEND (updqueue, updrec, r_link);
+ /* Allocate the various isc dns library structures we may require. */
+ dataspace = isc_mem_get(dhcp_gbl_ctx.mctx, sizeof(*dataspace) * 4);
+ if (dataspace == NULL) {
+ log_error("Unable to allocate memory for fwd update");
+ result = ISC_R_NOMEMORY;
+ goto cleanup;
+ }
+ ISC_LIST_INIT(prereqlist);
+ ISC_LIST_INIT(updatelist);
- /*
- * Address RR (A/AAAA) matches the expiring lease.
- */
- updrec = minires_mkupdrec (S_PREREQ,
- (const char *)ddns_fwd_name -> data,
- C_IN, ddns_address_type, 0);
- if (!updrec) {
- result = ISC_R_NOMEMORY;
- goto error;
- }
+ switch(ddns_cb->state) {
+ case DDNS_STATE_ADD_FW_NXDOMAIN:
+ result = ddns_modify_fwd_add1(ddns_cb, dataspace,
+ pname, uname);
+ if (result != ISC_R_SUCCESS) {
+ goto cleanup;
+ }
+ ISC_LIST_APPEND(prereqlist, pname, link);
+ break;
+ case DDNS_STATE_ADD_FW_YXDHCID:
+ result = ddns_modify_fwd_add2(ddns_cb, dataspace,
+ pname, uname);
+ if (result != ISC_R_SUCCESS) {
+ goto cleanup;
+ }
- updrec -> r_data = (unsigned char *)ddns_address;
- updrec -> r_size = strlen (ddns_address);
- updrec -> r_opcode = YXRRSET;
+ /* If we aren't doing conflict override we have entries
+ * in the pname list and we need to attach it to the
+ * prereqlist */
- ISC_LIST_APPEND (updqueue, updrec, r_link);
+ if ((ddns_cb->flags & DDNS_CONFLICT_OVERRIDE) == 0) {
+ ISC_LIST_APPEND(prereqlist, pname, link);
+ }
+ break;
+ case DDNS_STATE_REM_FW_YXDHCID:
+ result = ddns_modify_fwd_rem1(ddns_cb, dataspace,
+ pname, uname);
+ if (result != ISC_R_SUCCESS) {
+ goto cleanup;
+ }
+ ISC_LIST_APPEND(prereqlist, pname, link);
+ break;
+ case DDNS_STATE_REM_FW_NXRR:
+ result = ddns_modify_fwd_rem2(ddns_cb, dataspace,
+ pname, uname);
+ if (result != ISC_R_SUCCESS) {
+ goto cleanup;
+ }
+ ISC_LIST_APPEND(prereqlist, pname, link);
+ break;
+
+ default:
+ log_error("Invalid operation in ddns code.");
+ result = DHCP_R_INVALIDARG;
+ goto cleanup;
+ break;
+ }
/*
- * Delete appropriate Address RR (A/AAAA).
+ * We always have an update list but may not have a prereqlist
+ * if we are doing conflict override.
*/
- updrec = minires_mkupdrec (S_UPDATE,
- (const char *)ddns_fwd_name -> data,
- C_IN, ddns_address_type, 0);
- if (!updrec) {
- result = ISC_R_NOMEMORY;
- goto error;
+ ISC_LIST_APPEND(updatelist, uname, link);
+
+ /* send the message, cleanup and return the result */
+ result = dns_client_startupdate(dhcp_gbl_ctx.dnsclient,
+ dns_rdataclass_in, zname,
+ &prereqlist, &updatelist,
+ zlist, tsec_key,
+ DNS_CLIENTRESOPT_ALLOWRUN,
+ dhcp_gbl_ctx.task,
+ ddns_interlude,
+ (void *)ddns_cb,
+ &ddns_cb->transaction);
+
+ cleanup:
+ if (dataspace != NULL) {
+ isc_mem_put(dhcp_gbl_ctx.mctx, dataspace,
+ sizeof(*dataspace) * 4);
}
+ return(result);
+}
- updrec -> r_data = (unsigned char *)ddns_address;
- updrec -> r_size = strlen (ddns_address);
- updrec -> r_opcode = DELETE;
-
- ISC_LIST_APPEND (updqueue, updrec, r_link);
- /*
- * Attempt to perform the update.
- */
- result = minires_nupdate (&resolver_state, ISC_LIST_HEAD (updqueue));
- print_dns_status ((int)result, &updqueue);
+isc_result_t
+ddns_modify_ptr(dhcp_ddns_cb_t *ddns_cb)
+{
+ isc_result_t result;
+ dns_tsec_t *tsec_key = NULL;
+ unsigned char *ptrname;
+ dhcp_ddns_data_t *dataspace = NULL;
+ dns_namelist_t updatelist;
+ dns_fixedname_t zname0, uname0;
+ dns_name_t *zname = NULL, *uname;
+ isc_sockaddrlist_t *zlist = NULL;
+ unsigned char buf[256];
+ int buflen;
/*
- * If the query fails, the updater MUST NOT delete the DNS name. It
- * may be that the host whose lease on the server has expired has moved
- * to another network and obtained a lease from a different server,
- * which has caused the client's A RR to be replaced. It may also be
- * that some other client has been configured with a name that matches
- * the name of the DHCP client, and the policy was that the last client
- * to specify the name would get the name. In this case, the DHCID RR
- * will no longer match the updater's notion of the client-identity of
- * the host pointed to by the DNS name.
- * -- "Interaction between DHCP and DNS"
+ * Try to lookup the zone in the zone cache. As with the forward
+ * case it's okay if we don't have one, the DNS code will try to
+ * find something also if we succeed we will need to dereference
+ * the zone later. Unlike with the forward case we assume we won't
+ * have a pre-existing zone.
*/
+ result = find_cached_zone(ddns_cb, FIND_REVERSE);
+ if ((result == ISC_R_SUCCESS) &&
+ !(ISC_LIST_EMPTY(ddns_cb->zone_server_list))) {
+ /* Set up the zone name for use by DNS */
+ result = dhcp_isc_name(ddns_cb->zone_name, &zname0, &zname);
+ if (result != ISC_R_SUCCESS) {
+ log_error("Unable to build name for zone for "
+ "fwd update: %s %s",
+ ddns_cb->zone_name,
+ isc_result_totext(result));
+ goto cleanup;
+ }
+ /* If we have any addresses get them */
+ if (!(ISC_LIST_EMPTY(ddns_cb->zone_server_list))) {
+ zlist = &ddns_cb->zone_server_list;
+ }
- if (result != ISC_R_SUCCESS) {
- /* If the rrset isn't there, we didn't need to do the
- delete, which is success. */
- if (result == ISC_R_NXRRSET || result == ISC_R_NXDOMAIN)
- result = ISC_R_SUCCESS;
- goto error;
+ /*
+ * If we now have a zone try to get the key, NULL is okay,
+ * having a key but not a tsec is odd so we warn.
+ */
+ /*sar*/
+ /* should we do the warning if we have a key but no tsec? */
+ if ((ddns_cb->zone != NULL) && (ddns_cb->zone->key != NULL)) {
+ tsec_key = ddns_cb->zone->key->tsec_key;
+ if (tsec_key == NULL) {
+ log_error("No tsec for use with key %s",
+ ddns_cb->zone->key->name);
+ }
+ }
}
- while (!ISC_LIST_EMPTY (updqueue)) {
- updrec = ISC_LIST_HEAD (updqueue);
- ISC_LIST_UNLINK (updqueue, updrec, r_link);
- minires_freeupdrec (updrec);
- }
+ /* We must have a name for the update list */
+ /* Get a pointer to the ptrname to make things easier. */
+ ptrname = (unsigned char *)ddns_cb->rev_name.data;
- /*
- * If the deletion of the desired address succeeded (its A or AAAA
- * RR was removed above), and there are zero other A or AAAA records
- * left for this domain, then we can delete the DHCID record as well.
- * We can't delete the DHCID record above because it's possible the
- * client has more than one valid address added to this domain name,
- * by this or other DHCP servers.
- *
- * Essentially, this final update is a cleanup operation that is only
- * intended to succeed after the last address has been removed from
- * DNS (which is only expected to happen after the client is not
- * reasonably in possession of those addresses).
- */
- ISC_LIST_INIT (updqueue);
+ if ((result = dhcp_isc_name(ptrname, &uname0, &uname))
+ != ISC_R_SUCCESS) {
+ log_error("Unable to build name for fwd update: %s %s",
+ ptrname, isc_result_totext(result));
+ goto cleanup;
+ }
/*
- * A RR does not exist.
+ * Allocate the various isc dns library structures we may require.
+ * Allocating one blob avoids being halfway through the process
+ * and being unable to allocate as well as making the free easy.
*/
- updrec = minires_mkupdrec(S_PREREQ, (const char *)ddns_fwd_name->data,
- C_IN, T_A, 0);
- if (updrec == NULL) {
- result = ISC_R_NOMEMORY;
- goto error;
+ dataspace = isc_mem_get(dhcp_gbl_ctx.mctx, sizeof(*dataspace) * 2);
+ if (dataspace == NULL) {
+ log_error("Unable to allocate memory for fwd update");
+ result = ISC_R_NOMEMORY;
+ goto cleanup;
}
- updrec->r_data = NULL;
- updrec->r_size = 0;
- updrec->r_opcode = NXRRSET;
-
- ISC_LIST_APPEND (updqueue, updrec, r_link);
+ ISC_LIST_INIT(updatelist);
/*
- * AAAA RR does not exist.
+ * Construct the update list
+ * We always delete what's currently there
+ * Delete PTR RR.
*/
- updrec = minires_mkupdrec(S_PREREQ, (const char *)ddns_fwd_name->data,
- C_IN, T_AAAA, 0);
-
- if (updrec == NULL) {
- result = ISC_R_NOMEMORY;
- goto error;
+ result = make_dns_dataset(dns_rdataclass_any, dns_rdatatype_ptr,
+ &dataspace[0], NULL, 0, 0);
+ if (result != ISC_R_SUCCESS) {
+ goto cleanup;
}
-
- updrec->r_data = NULL;
- updrec->r_size = 0;
- updrec->r_opcode = NXRRSET;
-
- ISC_LIST_APPEND(updqueue, updrec, r_link);
+ ISC_LIST_APPEND(uname->list, &dataspace[0].rdataset, link);
/*
- * Delete appropriate DHCID RR.
+ * If we are updating the pointer we then add the new one
+ * Add PTR RR.
*/
- updrec = minires_mkupdrec (S_UPDATE,
- (const char *)ddns_fwd_name -> data,
- C_IN, T_DHCID, 0);
- if (!updrec) {
- result = ISC_R_NOMEMORY;
- goto error;
- }
+ if (ddns_cb->state == DDNS_STATE_ADD_PTR) {
+#if 0
+ /*
+ * I've left this dead code in the file for now in case
+ * we decide to try and get rid of the ns_name functions.
+ * sar
+ */
- updrec -> r_data = ddns_dhcid -> data;
- updrec -> r_size = ddns_dhcid -> len;
- updrec -> r_opcode = DELETE;
+ /*
+ * Need to convert pointer into on the wire representation
+ * We replace the '.' characters with the lengths of the
+ * next name and add a length to the beginning for the first
+ * name.
+ */
+ if (ddns_cb->fwd_name.len == 1) {
+ /* the root */
+ buf[0] = 0;
+ buflen = 1;
+ } else {
+ unsigned char *cp;
+ buf[0] = '.';
+ memcpy(&buf[1], ddns_cb->fwd_name.data,
+ ddns_cb->fwd_name.len);
+ for(cp = buf + ddns_cb->fwd_name.len, buflen = 0;
+ cp != buf;
+ cp--) {
+ if (*cp == '.') {
+ *cp = buflen;
+ buflen = 0;
+ } else {
+ buflen++;
+ }
+ }
+ *cp = buflen;
+ buflen = ddns_cb->fwd_name.len + 1;
+ }
+#endif
+ /*
+ * Need to convert pointer into on the wire representation
+ */
+ if (MRns_name_pton((char *)ddns_cb->fwd_name.data,
+ buf, 256) == -1) {
+ goto cleanup;
+ }
+ buflen = 0;
+ while (buf[buflen] != 0) {
+ buflen += buf[buflen] + 1;
+ }
+ buflen++;
+
+ result = make_dns_dataset(dns_rdataclass_in,
+ dns_rdatatype_ptr,
+ &dataspace[1],
+ buf, buflen, ddns_cb->ttl);
+ if (result != ISC_R_SUCCESS) {
+ goto cleanup;
+ }
+ ISC_LIST_APPEND(uname->list, &dataspace[1].rdataset, link);
+ }
- ISC_LIST_APPEND (updqueue, updrec, r_link);
+ ISC_LIST_APPEND(updatelist, uname, link);
+ /*sar*/
/*
- * Attempt to perform the update.
+ * for now I'll cleanup the dataset immediately, it would be
+ * more efficient to keep it around in case the signaturure failed
+ * and we wanted to retry it.
*/
- result = minires_nupdate (&resolver_state, ISC_LIST_HEAD (updqueue));
- print_dns_status ((int)result, &updqueue);
-
- /* Fall through. */
- error:
-
- while (!ISC_LIST_EMPTY (updqueue)) {
- updrec = ISC_LIST_HEAD (updqueue);
- ISC_LIST_UNLINK (updqueue, updrec, r_link);
- minires_freeupdrec (updrec);
+ /* send the message, cleanup and return the result */
+ result = dns_client_startupdate((dns_client_t *)dhcp_gbl_ctx.dnsclient,
+ dns_rdataclass_in, zname,
+ NULL, &updatelist,
+ zlist, tsec_key,
+ DNS_CLIENTRESOPT_ALLOWRUN,
+ dhcp_gbl_ctx.task,
+ ddns_interlude, (void *)ddns_cb,
+ &ddns_cb->transaction);
+ cleanup:
+ if (dataspace != NULL) {
+ isc_mem_put(dhcp_gbl_ctx.mctx, dataspace,
+ sizeof(*dataspace) * 2);
}
-
- return result;
+ return(result);
}
+void
+ddns_cancel(dhcp_ddns_cb_t *ddns_cb) {
+ ddns_cb->flags |= DDNS_ABORT;
+ if (ddns_cb->transaction != NULL) {
+ dns_client_cancelupdate((dns_clientupdatetrans_t *)
+ ddns_cb->transaction);
+ }
+ ddns_cb->lease = NULL;
+}
#endif /* NSUPDATE */
int tmp;
if (result == NULL) {
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
if (*result != NULL) {
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
if ((lo == NULL) || (hi == NULL) || (lo->len != hi->len)) {
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
/*
struct iaddrcidrnetlist *p;
if (result == NULL) {
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
if (*result == NULL) {
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
while (*result != NULL) {
group_hash_lookup (&d, group_name_hash, group -> name,
strlen (group -> name), MDL);
} else
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (!d)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
/* Also not okay to delete a group that's not the one in
the hash table. */
if (d != group)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
/* If it's dynamic, and we're deleting it, we can just blow away the
hash table entry. */
--- /dev/null
+/*
+ * Copyright (c) 2004,2009 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1996-2003 by Internet Software Consortium
+ *
+ * Permission to use, copy, modify, and 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 ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC 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.
+ *
+ * Internet Systems Consortium, Inc.
+ * 950 Charter Street
+ * Redwood City, CA 94063
+ * <info@isc.org>
+ * http://www.isc.org/
+ */
+
+#ifndef lint
+static const char rcsid[] = "$Id: ns_name.c,v 1.2 2009/10/28 04:12:29 sar Exp $";
+#endif
+
+#include <sys/types.h>
+
+#include <netinet/in.h>
+#include <sys/socket.h>
+
+#include <errno.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "minires.h"
+#include "arpa/nameser.h"
+
+/* Data. */
+
+static const char digits[] = "0123456789";
+
+/* Forward. */
+
+static int special(int);
+static int printable(int);
+static int dn_find(const u_char *, const u_char *,
+ const u_char * const *,
+ const u_char * const *);
+
+/* Public. */
+
+/*
+ * MRns_name_ntop(src, dst, dstsiz)
+ * Convert an encoded domain name to printable ascii as per RFC1035.
+ * return:
+ * Number of bytes written to buffer, or -1 (with errno set)
+ * notes:
+ * The root is returned as "."
+ * All other domains are returned in non absolute form
+ */
+int
+MRns_name_ntop(const u_char *src, char *dst, size_t dstsiz) {
+ const u_char *cp;
+ char *dn, *eom;
+ u_char c;
+ u_int n;
+
+ cp = src;
+ dn = dst;
+ eom = dst + dstsiz;
+
+ while ((n = *cp++) != 0) {
+ if ((n & NS_CMPRSFLGS) != 0) {
+ /* Some kind of compression pointer. */
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ if (dn != dst) {
+ if (dn >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *dn++ = '.';
+ }
+ if (dn + n >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ for ((void)NULL; n > 0; n--) {
+ c = *cp++;
+ if (special(c)) {
+ if (dn + 1 >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *dn++ = '\\';
+ *dn++ = (char)c;
+ } else if (!printable(c)) {
+ if (dn + 3 >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *dn++ = '\\';
+ *dn++ = digits[c / 100];
+ *dn++ = digits[(c % 100) / 10];
+ *dn++ = digits[c % 10];
+ } else {
+ if (dn >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *dn++ = (char)c;
+ }
+ }
+ }
+ if (dn == dst) {
+ if (dn >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *dn++ = '.';
+ }
+ if (dn >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *dn++ = '\0';
+ return (dn - dst);
+}
+
+/*
+ * MRns_name_pton(src, dst, dstsiz)
+ * Convert a ascii string into an encoded domain name as per RFC1035.
+ * return:
+ * -1 if it fails
+ * 1 if string was fully qualified
+ * 0 is string was not fully qualified
+ * notes:
+ * Enforces label and domain length limits.
+ */
+
+int
+MRns_name_pton(const char *src, u_char *dst, size_t dstsiz) {
+ u_char *label, *bp, *eom;
+ int c, n, escaped;
+ char *cp;
+
+ escaped = 0;
+ bp = dst;
+ eom = dst + dstsiz;
+ label = bp++;
+
+ while ((c = *src++) != 0) {
+ if (escaped) {
+ if ((cp = strchr(digits, c)) != NULL) {
+ n = (cp - digits) * 100;
+ if ((c = *src++) == 0 ||
+ (cp = strchr(digits, c)) == NULL) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ n += (cp - digits) * 10;
+ if ((c = *src++) == 0 ||
+ (cp = strchr(digits, c)) == NULL) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ n += (cp - digits);
+ if (n > 255) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ c = n;
+ }
+ escaped = 0;
+ } else if (c == '\\') {
+ escaped = 1;
+ continue;
+ } else if (c == '.') {
+ c = (bp - label - 1);
+ if ((c & NS_CMPRSFLGS) != 0) { /* Label too big. */
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ if (label >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *label = c;
+ /* Fully qualified ? */
+ if (*src == '\0') {
+ if (c != 0) {
+ if (bp >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *bp++ = '\0';
+ }
+ if ((bp - dst) > MAXCDNAME) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ return (1);
+ }
+ if (c == 0 || *src == '.') {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ label = bp++;
+ continue;
+ }
+ if (bp >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *bp++ = (u_char)c;
+ }
+ c = (bp - label - 1);
+ if ((c & NS_CMPRSFLGS) != 0) { /* Label too big. */
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ if (label >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *label = c;
+ if (c != 0) {
+ if (bp >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *bp++ = 0;
+ }
+ if ((bp - dst) > MAXCDNAME) { /* src too big */
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ return (0);
+}
+
+/*
+ * MRns_name_ntol(src, dst, dstsiz)
+ * Convert a network strings labels into all lowercase.
+ * return:
+ * Number of bytes written to buffer, or -1 (with errno set)
+ * notes:
+ * Enforces label and domain length limits.
+ */
+
+int
+MRns_name_ntol(const u_char *src, u_char *dst, size_t dstsiz) {
+ const u_char *cp;
+ u_char *dn, *eom;
+ u_char c;
+ u_int n;
+
+ cp = src;
+ dn = dst;
+ eom = dst + dstsiz;
+
+ if (dn >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ while ((n = *cp++) != 0) {
+ if ((n & NS_CMPRSFLGS) != 0) {
+ /* Some kind of compression pointer. */
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *dn++ = n;
+ if (dn + n >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ for ((void)NULL; n > 0; n--) {
+ c = *cp++;
+ if (isupper(c))
+ *dn++ = tolower(c);
+ else
+ *dn++ = c;
+ }
+ }
+ *dn++ = '\0';
+ return (dn - dst);
+}
+
+/*
+ * MRns_name_unpack(msg, eom, src, dst, dstsiz)
+ * Unpack a domain name from a message, source may be compressed.
+ * return:
+ * -1 if it fails, or consumed octets if it succeeds.
+ */
+int
+MRns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src,
+ u_char *dst, size_t dstsiz)
+{
+ const u_char *srcp, *dstlim;
+ u_char *dstp;
+ unsigned n;
+ int len;
+ int checked;
+
+ len = -1;
+ checked = 0;
+ dstp = dst;
+ srcp = src;
+ dstlim = dst + dstsiz;
+ if (srcp < msg || srcp >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ /* Fetch next label in domain name. */
+ while ((n = *srcp++) != 0) {
+ /* Check for indirection. */
+ switch (n & NS_CMPRSFLGS) {
+ case 0:
+ /* Limit checks. */
+ if (dstp + n + 1 >= dstlim || srcp + n >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ checked += n + 1;
+ *dstp++ = n;
+ memcpy(dstp, srcp, n);
+ dstp += n;
+ srcp += n;
+ break;
+
+ case NS_CMPRSFLGS:
+ if (srcp >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ if (len < 0)
+ len = srcp - src + 1;
+ srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff));
+ if (srcp < msg || srcp >= eom) { /* Out of range. */
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ checked += 2;
+ /*
+ * Check for loops in the compressed name;
+ * if we've looked at the whole message,
+ * there must be a loop.
+ */
+ if (checked >= eom - msg) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ break;
+
+ default:
+ errno = EMSGSIZE;
+ return (-1); /* flag error */
+ }
+ }
+ *dstp = '\0';
+ if (len < 0)
+ len = srcp - src;
+ return (len);
+}
+
+/*
+ * MRns_name_pack(src, dst, dstsiz, dnptrs, lastdnptr)
+ * Pack domain name 'domain' into 'comp_dn'.
+ * return:
+ * Size of the compressed name, or -1.
+ * notes:
+ * 'dnptrs' is an array of pointers to previous compressed names.
+ * dnptrs[0] is a pointer to the beginning of the message. The array
+ * ends with NULL.
+ * 'lastdnptr' is a pointer to the end of the array pointed to
+ * by 'dnptrs'.
+ * Side effects:
+ * The list of pointers in dnptrs is updated for labels inserted into
+ * the message as we compress the name. If 'dnptr' is NULL, we don't
+ * try to compress names. If 'lastdnptr' is NULL, we don't update the
+ * list.
+ */
+int
+MRns_name_pack(const u_char *src, u_char *dst, unsigned dstsiz,
+ const u_char **dnptrs, const u_char **lastdnptr)
+{
+ u_char *dstp;
+ const u_char **cpp, **lpp, *eob, *msg;
+ const u_char *srcp;
+ unsigned n;
+ int l;
+
+ srcp = src;
+ dstp = dst;
+ eob = dstp + dstsiz;
+ lpp = cpp = NULL;
+ if (dnptrs != NULL) {
+ if ((msg = *dnptrs++) != NULL) {
+ for (cpp = dnptrs; *cpp != NULL; cpp++)
+ (void)NULL;
+ lpp = cpp; /* end of list to search */
+ }
+ } else
+ msg = NULL;
+
+ /* make sure the domain we are about to add is legal */
+ l = 0;
+ do {
+ n = *srcp;
+ if ((n & NS_CMPRSFLGS) != 0) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ l += n + 1;
+ if (l > MAXCDNAME) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ srcp += n + 1;
+ } while (n != 0);
+
+ /* from here on we need to reset compression pointer array on error */
+ srcp = src;
+ do {
+ /* Look to see if we can use pointers. */
+ n = *srcp;
+ if (n != 0 && msg != NULL) {
+ l = dn_find(srcp, msg, (const u_char * const *)dnptrs,
+ (const u_char * const *)lpp);
+ if (l >= 0) {
+ if (dstp + 1 >= eob) {
+ goto cleanup;
+ }
+ *dstp++ = (l >> 8) | NS_CMPRSFLGS;
+ *dstp++ = l % 256;
+ return (dstp - dst);
+ }
+ /* Not found, save it. */
+ if (lastdnptr != NULL && cpp < lastdnptr - 1 &&
+ (dstp - msg) < 0x4000) {
+ *cpp++ = dstp;
+ *cpp = NULL;
+ }
+ }
+ /* copy label to buffer */
+ if (n & NS_CMPRSFLGS) { /* Should not happen. */
+ goto cleanup;
+ }
+ if (dstp + 1 + n >= eob) {
+ goto cleanup;
+ }
+ memcpy(dstp, srcp, n + 1);
+ srcp += n + 1;
+ dstp += n + 1;
+ } while (n != 0);
+
+ if (dstp > eob) {
+cleanup:
+ if (msg != NULL)
+ *lpp = NULL;
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ return (dstp - dst);
+}
+
+/*
+ * MRns_name_uncompress(msg, eom, src, dst, dstsiz)
+ * Expand compressed domain name to presentation format.
+ * return:
+ * Number of bytes read out of `src', or -1 (with errno set).
+ * note:
+ * Root domain returns as "." not "".
+ */
+int
+MRns_name_uncompress(const u_char *msg, const u_char *eom, const u_char *src,
+ char *dst, size_t dstsiz)
+{
+ u_char tmp[NS_MAXCDNAME];
+ int n;
+
+ if ((n = MRns_name_unpack(msg, eom, src, tmp, sizeof tmp)) == -1)
+ return (-1);
+ if (MRns_name_ntop(tmp, dst, dstsiz) == -1)
+ return (-1);
+ return (n);
+}
+
+/*
+ * MRns_name_compress(src, dst, dstsiz, dnptrs, lastdnptr)
+ * Compress a domain name into wire format, using compression pointers.
+ * return:
+ * Number of bytes consumed in `dst' or -1 (with errno set).
+ * notes:
+ * 'dnptrs' is an array of pointers to previous compressed names.
+ * dnptrs[0] is a pointer to the beginning of the message.
+ * The list ends with NULL. 'lastdnptr' is a pointer to the end of the
+ * array pointed to by 'dnptrs'. Side effect is to update the list of
+ * pointers for labels inserted into the message as we compress the name.
+ * If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr'
+ * is NULL, we don't update the list.
+ */
+int
+MRns_name_compress(const char *src, u_char *dst, size_t dstsiz,
+ const u_char **dnptrs, const u_char **lastdnptr)
+{
+ u_char tmp[NS_MAXCDNAME];
+
+ if (MRns_name_pton(src, tmp, sizeof tmp) == -1)
+ return (-1);
+ return (MRns_name_pack(tmp, dst, dstsiz, dnptrs, lastdnptr));
+}
+
+/*
+ * MRns_name_skip(ptrptr, eom)
+ * Advance *ptrptr to skip over the compressed name it points at.
+ * return:
+ * 0 on success, -1 (with errno set) on failure.
+ */
+int
+MRns_name_skip(const u_char **ptrptr, const u_char *eom) {
+ const u_char *cp;
+ u_int n;
+
+ cp = *ptrptr;
+ while (cp < eom && (n = *cp++) != 0) {
+ /* Check for indirection. */
+ switch (n & NS_CMPRSFLGS) {
+ case 0: /* normal case, n == len */
+ cp += n;
+ continue;
+ case NS_CMPRSFLGS: /* indirection */
+ cp++;
+ break;
+ default: /* illegal type */
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ break;
+ }
+ if (cp > eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *ptrptr = cp;
+ return (0);
+}
+
+/* Private. */
+
+/*
+ * special(ch)
+ * Thinking in noninternationalized USASCII (per the DNS spec),
+ * is this characted special ("in need of quoting") ?
+ * return:
+ * boolean.
+ */
+static int
+special(int ch) {
+ switch (ch) {
+ case 0x22: /* '"' */
+ case 0x2E: /* '.' */
+ case 0x3B: /* ';' */
+ case 0x5C: /* '\\' */
+ /* Special modifiers in zone files. */
+ case 0x40: /* '@' */
+ case 0x24: /* '$' */
+ return (1);
+ default:
+ return (0);
+ }
+}
+
+/*
+ * printable(ch)
+ * Thinking in noninternationalized USASCII (per the DNS spec),
+ * is this character visible and not a space when printed ?
+ * return:
+ * boolean.
+ */
+static int
+printable(int ch) {
+ return (ch > 0x20 && ch < 0x7f);
+}
+
+/*
+ * Thinking in noninternationalized USASCII (per the DNS spec),
+ * convert this character to lower case if it's upper case.
+ */
+static int
+mklower(int ch) {
+ if (ch >= 0x41 && ch <= 0x5A)
+ return (ch + 0x20);
+ return (ch);
+}
+
+/*
+ * dn_find(domain, msg, dnptrs, lastdnptr)
+ * Search for the counted-label name in an array of compressed names.
+ * return:
+ * offset from msg if found, or -1.
+ * notes:
+ * dnptrs is the pointer to the first name on the list,
+ * not the pointer to the start of the message.
+ */
+static int
+dn_find(const u_char *domain, const u_char *msg,
+ const u_char * const *dnptrs,
+ const u_char * const *lastdnptr)
+{
+ const u_char *dn, *cp, *sp;
+ const u_char * const *cpp;
+ u_int n;
+
+ for (cpp = dnptrs; cpp < lastdnptr; cpp++) {
+ dn = domain;
+ sp = cp = *cpp;
+ while ((n = *cp++) != 0) {
+ /*
+ * check for indirection
+ */
+ switch (n & NS_CMPRSFLGS) {
+ case 0: /* normal case, n == len */
+ if (n != *dn++)
+ goto next;
+ for ((void)NULL; n > 0; n--)
+ if (mklower(*dn++) != mklower(*cp++))
+ goto next;
+ /* Is next root for both ? */
+ if (*dn == '\0' && *cp == '\0')
+ return (sp - msg);
+ if (*dn)
+ continue;
+ goto next;
+
+ case NS_CMPRSFLGS: /* indirection */
+ cp = msg + (((n & 0x3f) << 8) | *cp);
+ break;
+
+ default: /* illegal type */
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ }
+ next: ;
+ }
+ errno = ENOENT;
+ return (-1);
+}
unsigned code;
if (opt == NULL)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
token = next_token (&val, (unsigned *)0, cfile);
if (!is_identifier (token)) {
"expecting identifier after option keyword.");
if (token != SEMI)
skip_to_semi (cfile);
- return ISC_R_BADPARSE;
+ return DHCP_R_BADPARSE;
}
uname = dmalloc (strlen (val) + 1, MDL);
if (!uname)
parse_warn (cfile, "expecting identifier after '.'");
if (token != SEMI)
skip_to_semi (cfile);
- return ISC_R_BADPARSE;
+ return DHCP_R_BADPARSE;
}
/* Look up the option name hash table for the specified
}
return 1;
}
-
+#if defined (NSUPDATE_OLD)
/*
* dns-expression :==
* UPDATE LPAREN ns-class COMMA ns-type COMMA data-expression COMMA
}
return 1;
}
-
+#endif /* NSUPDATE_OLD */
/* Parse a subexpression that does not contain a binary operator. */
int parse_non_binary (expr, cfile, lose, context)
struct collection *col;
struct expression *nexp, **ep;
int known;
+ char *cptr;
+#if defined (NSUPDATE_OLD)
enum expr_op opcode;
const char *s;
- char *cptr;
unsigned long u;
+#endif
isc_result_t status;
unsigned len;
case TOKEN_NOT:
token = next_token (&val, (unsigned *)0, cfile);
+#if defined(NSUPDATE_OLD)
if (context == context_dns) {
token = peek_token (&val, (unsigned *)0, cfile);
goto not_exists;
}
+#endif
if (!expression_allocate (expr, MDL))
log_fatal ("can't allocate expression");
(*expr) -> op = expr_not;
break;
case EXISTS:
+#if defined(NSUPDATE_OLD)
if (context == context_dns)
goto ns_exists;
+#endif
token = next_token (&val, (unsigned *)0, cfile);
if (!expression_allocate (expr, MDL))
log_fatal ("can't allocate expression");
goto norparen;
break;
+#if defined(NSUPDATE_OLD)
/* dns-update and dns-delete are present for historical
purposes, but are deprecated in favor of ns-update
in combination with update, delete, exists and not
if (token != RPAREN)
goto norparen;
break;
-
+#endif /* NSUPDATE_OLD */
case OPTION:
case CONFIG_OPTION:
if (!expression_allocate (expr, MDL))
(*expr) -> op = expr_host_decl_name;
break;
+#if defined(NSUPDATE_OLD)
case UPDATED_DNS_RR:
token = next_token (&val, (unsigned *)0, cfile);
log_fatal ("can't allocate variable name.");
strcpy ((*expr) -> data.variable, s);
break;
-
+#endif /* NSUPDATE_OLD */
case PACKET:
token = next_token (&val, (unsigned *)0, cfile);
if (!expression_allocate (expr, MDL))
goto ns_const;
case NS_NOTAUTH:
- known = ISC_R_NOTAUTH;
+ known = DHCP_R_NOTAUTH;
goto ns_const;
case NS_NOTIMP:
goto ns_const;
case NS_NOTZONE:
- known = ISC_R_NOTZONE;
+ known = DHCP_R_NOTZONE;
goto ns_const;
case NS_NXDOMAIN:
- known = ISC_R_NXDOMAIN;
+ known = DHCP_R_NXDOMAIN;
goto ns_const;
case NS_NXRRSET:
- known = ISC_R_NXRRSET;
+ known = DHCP_R_NXRRSET;
goto ns_const;
case NS_REFUSED:
- known = ISC_R_REFUSED;
+ known = DHCP_R_REFUSED;
goto ns_const;
case NS_SERVFAIL:
- known = ISC_R_SERVFAIL;
+ known = DHCP_R_SERVFAIL;
goto ns_const;
case NS_YXDOMAIN:
- known = ISC_R_YXDOMAIN;
+ known = DHCP_R_YXDOMAIN;
goto ns_const;
case NS_YXRRSET:
- known = ISC_R_YXRRSET;
+ known = DHCP_R_YXRRSET;
goto ns_const;
case BOOTING:
}
#if defined (NSUPDATE)
+#if 0
void print_dns_status (int status, ns_updque *uq)
{
char obuf [1024];
else
log_info ("%s", obuf);
}
+#endif
#endif /* NSUPDATE */
/* Format the given time as "A; # B", where A is the format
int sock;
int flag;
int domain;
+#ifdef DHCPv6
+ struct sockaddr_in6 *addr6;
+#endif
+ struct sockaddr_in *addr;
/* INSIST((family == AF_INET) || (family == AF_INET6)); */
* address family.
*/
memset(&name, 0, sizeof(name));
+ switch (family) {
#ifdef DHCPv6
- if (family == AF_INET6) {
- struct sockaddr_in6 *addr = (struct sockaddr_in6 *)&name;
- addr->sin6_family = AF_INET6;
- addr->sin6_port = local_port;
+ case AF_INET6:
+ addr6 = (struct sockaddr_in6 *)&name;
+ addr6->sin6_family = AF_INET6;
+ addr6->sin6_port = local_port;
/* XXX: What will happen to multicasts if this is nonzero? */
- memcpy(&addr->sin6_addr,
+ memcpy(&addr6->sin6_addr,
&local_address6,
- sizeof(addr->sin6_addr));
+ sizeof(addr6->sin6_addr));
#ifdef HAVE_SA_LEN
- addr->sin6_len = sizeof(*addr);
+ addr6->sin6_len = sizeof(*addr6);
#endif
- name_len = sizeof(*addr);
+ name_len = sizeof(*addr6);
domain = PF_INET6;
if ((info->flags & INTERFACE_STREAMS) == INTERFACE_UPSTREAM) {
*do_multicast = 0;
}
- } else {
-#else
- {
+ break;
#endif /* DHCPv6 */
- struct sockaddr_in *addr = (struct sockaddr_in *)&name;
+
+ case AF_INET:
+ default:
+ addr = (struct sockaddr_in *)&name;
addr->sin_family = AF_INET;
addr->sin_port = local_port;
memcpy(&addr->sin_addr,
#endif
name_len = sizeof(*addr);
domain = PF_INET;
+ break;
}
/* Make a socket... */
struct interface_info *interface;
if (object -> type != dhcp_type_interface)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
interface = (struct interface_info *)object;
status = recvfrom (interface -> wfdesc, buf, sizeof buf, 0,
const char * file, int line)
{
if (!dest || !src)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (*dest) {
#if defined(POINTER_DEBUG)
log_fatal("%s(%d): reference store into non-null pointer!",
file, line);
#else
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
#endif
}
option_dereference(struct option **dest, const char *file, int line)
{
if (!dest)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (!*dest) {
#if defined (POINTER_DEBUG)
log_fatal("%s(%d): dereference of null pointer!", file, line);
#else
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
#endif
}
#if defined (POINTER_DEBUG)
log_fatal("%s(%d): dereference of <= 0 refcnt!", file, line);
#else
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
#endif
}
test_alloc_SOURCES = test_alloc.c
test_alloc_LDADD = ../libdhcp.a ../../tests/libt_api.a \
- ../../omapip/libomapi.a ../../dst/libdst.a ../../minires/libres.a
+ ../../omapip/libomapi.a ../../bind/lib/libdns.a \
+ ../../bind/lib/libisc.a
static int do_host_lookup PROTO ((struct data_string *,
struct dns_host_entry *));
-#ifdef NSUPDATE
-struct __res_state resolver_state;
-int resolver_inited = 0;
-#endif
-
#define DS_SPRINTF_SIZE 128
/*
status = (evaluate_data_expression
(&bv -> value.data, packet, lease, client_state,
in_options, cfg_options, scope, expr, MDL));
+#if defined (NSUPDATE_OLD)
} else if (is_dns_expression (expr)) {
-#if defined (NSUPDATE)
if (!binding_value_allocate (&bv, MDL))
return 0;
bv -> type = binding_dns;
data_string_forget (&bv -> value.data, file, line);
break;
case binding_dns:
-#if defined (NSUPDATE)
+#if defined (NSUPDATE_OLD)
if (bv -> value.dns) {
if (bv -> value.dns -> r_data) {
dfree (bv -> value.dns -> r_data_ephem, MDL);
return 1;
}
-#if defined (NSUPDATE)
+#if defined (NSUPDATE_OLD)
int evaluate_dns_expression (result, packet, lease, client_state, in_options,
cfg_options, scope, expr)
ns_updrec **result;
expr -> op);
return 0;
}
-#endif /* defined (NSUPDATE) */
+#endif /* defined (NSUPDATE_OLD) */
int evaluate_boolean_expression (result, packet, lease, client_state,
in_options, cfg_options, scope, expr)
else
*result = expr -> op == expr_not_equal;
break;
-
+#if defined (NSUPDATE_OLD)
case binding_dns:
#if defined (NSUPDATE)
/* XXX This should be a comparison for equal
*result = expr -> op == expr_not_equal;
#endif
break;
-
+#endif /* NSUPDATE_OLD */
case binding_function:
if (bv -> value.fundef == obv -> value.fundef)
*result = expr -> op == expr_equal;
{
struct data_string data;
int status, sleft, sright;
-#if defined (NSUPDATE)
+#if defined (NSUPDATE_OLD)
ns_updrec *nut;
ns_updque uq;
-#endif
struct expression *cur, *next;
+#endif
+
struct binding *binding;
struct binding_value *bv;
unsigned long ileft, iright;
return 1;
case expr_dns_transaction:
-#if !defined (NSUPDATE)
+#if !defined (NSUPDATE_OLD)
return 0;
#else
if (!resolver_inited) {
minires_freeupdrec (tmp);
}
return status;
-#endif /* NSUPDATE */
+#endif /* NSUPDATE_OLD */
case expr_variable_reference:
if (scope && *scope) {
#include <sys/socket.h>
])
+libbind =
+AC_ARG_WITH(libbind,
+ AC_HELP_STRING([--with-libbind=PATH],
+ [bind includes and libraries are in PATH
+ (default is ./bind)]),
+ use_libbind="$withval", use_libbind="no")
+case "$use_libbind" in
+yes)
+ libbind="\${top_srcdir}/bind"
+ ;;
+no)
+ libbind="\${top_srcdir}/bind"
+ ;;
+*)
+ libbind="$use_libbind"
+ ;;
+esac
+
# Append selected warning levels to CFLAGS before substitution (but after
# AC_TRY_COMPILE & etc).
CFLAGS="$CFLAGS $STD_CWARNINGS"
+# Try to add the bind include directory
+CFLAGS="$CFLAGS -I$libbind/include"
+
AC_OUTPUT([
Makefile
client/Makefile
dhcpctl/Makefile
dst/Makefile
includes/Makefile
- minires/Makefile
omapip/Makefile
relay/Makefile
server/Makefile
EXTRA_DIST = $(man_MANS)
omshell_SOURCES = omshell.c
-omshell_LDADD = libdhcpctl.a ../common/libdhcp.a ../minires/libres.a \
- ../omapip/libomapi.a ../dst/libdst.a
+omshell_LDADD = libdhcpctl.a ../common/libdhcp.a ../omapip/libomapi.a \
+ ../bind/lib/libdns.a ../bind/lib/libisc.a
libdhcpctl_a_SOURCES = dhcpctl.c callback.c remote.c
cltest_SOURCES = cltest.c
-cltest_LDADD = libdhcpctl.a ../common/libdhcp.a ../minires/libres.a \
- ../omapip/libomapi.a ../dst/libdst.a
+cltest_LDADD = libdhcpctl.a ../common/libdhcp.a ../omapip/libomapi.a \
+ ../bind/lib/libdns.a ../bind/lib/libisc.a
\ No newline at end of file
omapi_typed_data_t *value)
{
if (h -> type != dhcpctl_callback_type)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (h -> inner && h -> inner -> type -> set_value)
return (*(h -> inner -> type -> set_value))
omapi_value_t **value)
{
if (h -> type != dhcpctl_callback_type)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (h -> inner && h -> inner -> type -> get_value)
return (*(h -> inner -> type -> get_value))
isc_result_t waitstatus;
if (o -> type != dhcpctl_callback_type)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
p = (dhcpctl_callback_object_t *)o;
/* Not a signal we recognize? */
{
dhcpctl_callback_object_t *p;
if (h -> type != dhcpctl_callback_type)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
p = (dhcpctl_callback_object_t *)h;
if (p -> handle)
omapi_object_dereference ((omapi_object_t **)&p -> handle,
omapi_object_t *p)
{
if (p -> type != dhcpctl_callback_type)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (p -> inner && p -> inner -> type -> stuff_values)
return (*(p -> inner -> type -> stuff_values)) (c, id,
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
-#include <isc-dhcp/result.h>
+#include "omapip/result.h"
#include "dhcpctl.h"
int main (int, char **);
{
isc_result_t status;
+ /* Set up the isc and dns library managers */
+ status = dhcp_context_create();
+ if (status != ISC_R_SUCCESS)
+ return status;
+
status = omapi_init();
if (status != ISC_R_SUCCESS)
return status;
(unsigned)port, authinfo);
if (status == ISC_R_SUCCESS)
return status;
- if (status != ISC_R_INCOMPLETE) {
+ if (status != DHCP_R_INCOMPLETE) {
omapi_object_dereference (connection, MDL);
return status;
}
dhcpctl_remote_object_t *ro;
if (h -> type != dhcpctl_remote_type)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
ro = (dhcpctl_remote_object_t *)h;
status = omapi_message_new (&message, MDL);
dhcpctl_remote_object_t *ro;
if (h -> type != dhcpctl_remote_type)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
ro = (dhcpctl_remote_object_t *)h;
status = omapi_message_new (&message, MDL);
dhcpctl_remote_object_t *ro;
if (h -> type != dhcpctl_remote_type)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
ro = (dhcpctl_remote_object_t *)h;
status = omapi_message_new (&message, MDL);
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
-#include <isc-dhcp/result.h>
+//#include "result.h"
#include <syslog.h>
#include "dhcpctl.h"
#include "dhcpd.h"
break;
case KEY:
- token = next_token (&val, (unsigned *)0, cfile);
- if (!is_identifier (token)) {
- printf ("usage: key <name> <value>\n");
- skip_to_semi (cfile);
- break;
- }
- s = dmalloc (strlen (val) + 1, MDL);
- if (!s) {
- printf ("no memory for key name.\n");
- skip_to_semi (cfile);
- break;
+ token = peek_token(&val, (unsigned *)0, cfile);
+ if (token == STRING) {
+ token = next_token (&val, (unsigned *)0, cfile);
+ if (!is_identifier (token)) {
+ printf ("usage: key <name> <value>\n");
+ skip_to_semi (cfile);
+ break;
+ }
+ s = dmalloc (strlen (val) + 1, MDL);
+ if (!s) {
+ printf ("no memory for key name.\n");
+ skip_to_semi (cfile);
+ break;
+ }
+ strcpy (s, val);
+ } else {
+ s = parse_host_name(cfile);
+ if (s == NULL) {
+ printf ("usage: key <name> <value>\n");
+ skip_to_semi(cfile);
+ break;
+ }
}
- strcpy (s, val);
name = s;
+
memset (&secret, 0, sizeof secret);
if (!parse_base64 (&secret, cfile)) {
skip_to_semi (cfile);
dhcpctl_remote_object_t *remote;
if (h -> type != dhcpctl_remote_type)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
remote = (dhcpctl_remote_object_t *)h;
status = omapi_message_new (&message, MDL);
isc_result_t status;
if (h -> type != dhcpctl_remote_type)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
ro = (dhcpctl_remote_object_t *)h;
if (!omapi_ds_strcmp (name, "remote-handle")) {
omapi_value_t **value)
{
if (h -> type != dhcpctl_remote_type)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (h -> inner && h -> inner -> type -> get_value)
return (*(h -> inner -> type -> get_value))
omapi_typed_data_t *tv;
if (o -> type != dhcpctl_remote_type)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
p = (dhcpctl_remote_object_t *)o;
if (!strcmp (name, "updated")) {
{
dhcpctl_remote_object_t *p;
if (h -> type != dhcpctl_remote_type)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
p = (dhcpctl_remote_object_t *)h;
if (p -> handle)
omapi_object_dereference ((omapi_object_t **)&p -> handle,
omapi_object_t *p)
{
if (p -> type != dhcpctl_remote_type)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (p -> inner && p -> inner -> type -> stuff_values)
return (*(p -> inner -> type -> stuff_values)) (c, id,
*/
#if !defined(LINT) && !defined(CODECENTER)
-static const char rcsid[] = "$Id: base64.c,v 1.3 2009/07/23 18:52:20 sar Exp $";
+static const char rcsid[] = "$Id: base64.c,v 1.4 2009/10/28 04:12:30 sar Exp $";
#endif /* not lint */
#include <sys/types.h>
#include <sys/socket.h>
-#include "minires/minires.h"
#include "arpa/nameser.h"
#define Assert(Cond) if (!(Cond)) abort()
#ifndef LINT
-static const char rcsid[] = "$Header: /tmp/cvstest/DHCP/dst/dst_api.c,v 1.7 2009/01/22 00:43:58 sar Exp $";
+static const char rcsid[] = "$Header: /tmp/cvstest/DHCP/dst/dst_api.c,v 1.8 2009/10/28 04:12:30 sar Exp $";
#endif
/*
#include <sys/socket.h>
#include <netinet/in.h>
-#include "minires/minires.h"
#include "arpa/nameser.h"
#include "dst_internal.h"
# define DUMP(a,b,c,d)
#endif
+#if defined (MINIRES_LIB)
+#define b64_pton MRb64_pton
+#define b64_ntop MRb64_ntop
+
+int b64_pton (char const *, unsigned char *, size_t);
+int b64_ntop (unsigned char const *, size_t, char *, size_t);
+
+#define USE_MD5
+#endif
+
#endif /* DST_INTERNAL_H */
-static const char rcsid[] = "$Header: /tmp/cvstest/DHCP/dst/dst_support.c,v 1.4 2007/12/06 00:50:22 dhankins Exp $";
+static const char rcsid[] = "$Header: /tmp/cvstest/DHCP/dst/dst_support.c,v 1.5 2009/10/28 04:12:30 sar Exp $";
/*
#include <netinet/in.h>
#include <sys/socket.h>
-#include "minires/minires.h"
#include "arpa/nameser.h"
#include "dst_internal.h"
#ifdef HMAC_MD5
#ifndef LINT
-static const char rcsid[] = "$Header: /tmp/cvstest/DHCP/dst/hmac_link.c,v 1.3 2007/12/06 00:50:22 dhankins Exp $";
+static const char rcsid[] = "$Header: /tmp/cvstest/DHCP/dst/hmac_link.c,v 1.4 2009/10/28 04:12:30 sar Exp $";
#endif
/*
* Portions Copyright (c) 1995-1998 by Trusted Information Systems, Inc.
#include <netinet/in.h>
#include <sys/socket.h>
-#include "minires/minires.h"
#include "arpa/nameser.h"
#include "dst_internal.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include "md5_locl.h"
-#include "minires/minires.h"
#ifdef USE_MD5 /* Added by ogud@tis.com 1998/1/26 */
#ifndef LINT
-static const char rcsid[] = "$Header: /tmp/cvstest/DHCP/dst/prandom.c,v 1.6 2007/11/30 21:51:43 fdupont Exp $";
+static const char rcsid[] = "$Header: /tmp/cvstest/DHCP/dst/prandom.c,v 1.7 2009/10/28 04:12:30 sar Exp $";
#endif
/*
* Portions Copyright (c) 1995-1998 by Trusted Information Systems, Inc.
#include <netinet/in.h>
#include <sys/socket.h>
#define NEED_PRAND_CONF
-#include "minires/minires.h"
+
#include "dst_internal.h"
#include "arpa/nameser.h"
nobase_include_HEADERS = omapip/alloc.h omapip/buffer.h omapip/convert.h \
omapip/hash.h omapip/omapip.h omapip/omapip_p.h \
- omapip/trace.h \
- isc-dhcp/boolean.h isc-dhcp/formatcheck.h \
- isc-dhcp/lang.h isc-dhcp/mem.h isc-dhcp/result.h \
- isc-dhcp/types.h isc-dhcp/commandline.h \
- isc-dhcp/dst.h isc-dhcp/int.h isc-dhcp/list.h \
- isc-dhcp/print.h isc-dhcp/string.h
+ omapip/trace.h
EXTRA_DIST = cdefs.h ctrace.h dhcp.h dhcp6.h dhcpd.h dhctoken.h failover.h \
heap.h inet.h osdep.h site.h statement.h tree.h t_api.h \
arpa/nameser.h arpa/nameser_compat.h \
- minires/minires.h minires/res_update.h minires/resolv.h \
netinet/if_ether.h netinet/ip.h netinet/ip_icmp.h netinet/udp.h
#include "osdep.h"
#include "arpa/nameser.h"
-#if defined (NSUPDATE)
-# include "minires/minires.h"
-#endif
+
+#include "minires.h"
struct hash_table;
typedef struct hash_table group_hash_t;
#define EOL '\n'
#endif
+#include <omapip/isclib.h>
+#include <omapip/result.h>
+
#include "dhcp.h"
#include "dhcp6.h"
#include "statement.h"
#include "tree.h"
#include "inet.h"
#include "dhctoken.h"
-#include "heap.h"
-#include <isc-dhcp/result.h>
#include <omapip/omapip_p.h>
#if !defined (BYTE_NAME_HASH_SIZE)
TIME cltt; /* Client last transaction time. */
u_int32_t last_xid; /* XID we sent in this lease's BNDUPD */
struct lease *next_pending;
+
+ /*
+ * A pointer to the state of the ddns update for this lease.
+ * It should be set while the update is in progress and cleared
+ * when the update finishes. It can be used to cancel the
+ * update if we want to do a different update.
+ */
+ struct dhcp_ddns_cb *ddns_cb;
};
struct lease_state {
* a no-op).
*/
void (*v6_handler)(struct packet *, struct client_state *);
+
+ /*
+ * A pointer to the state of the ddns update for this lease.
+ * It should be set while the update is in progress and cleared
+ * when the update finishes. It can be used to cancel the
+ * update if we want to do a different update.
+ */
+ struct dhcp_ddns_cb *ddns_cb;
};
struct envadd_state {
void *what;
tvref_t ref;
tvunref_t unref;
+ isc_timer_t *isc_timeout;
};
struct eventqueue {
int heap_index; /* index into heap, or -1
(internal use only) */
+
+ /*
+ * A pointer to the state of the ddns update for this lease.
+ * It should be set while the update is in progress and cleared
+ * when the update finishes. It can be used to cancel the
+ * update if we want to do a different update.
+ */
+ struct dhcp_ddns_cb *ddns_cb;
+
};
struct ia_xx {
struct subnet *subnet; /* subnet for this pool */
};
+/* Flags and state for dhcp_ddns_cb_t */
+#define DDNS_UPDATE_ADDR 0x01
+#define DDNS_UPDATE_PTR 0x02
+#define DDNS_INCLUDE_RRSET 0x04
+#define DDNS_CONFLICT_OVERRIDE 0x08
+#define DDNS_CLIENT_DID_UPDATE 0x10
+#define DDNS_EXECUTE_NEXT 0x20
+#define DDNS_ABORT 0x40
+
+/*
+ * The following two groups are separate and we could reuse
+ * values but not reusing them may be useful in the future.
+ */
+#define DDNS_STATE_CLEANUP 0 // The previous step failed, cleanup
+
+#define DDNS_STATE_ADD_FW_NXDOMAIN 1
+#define DDNS_STATE_ADD_FW_YXDHCID 2
+#define DDNS_STATE_ADD_PTR 3
+
+#define DDNS_STATE_REM_FW_YXDHCID 17
+#define DDNS_STATE_REM_FW_NXRR 18
+#define DDNS_STATE_REM_PTR 19
+
+struct dhcp_ddns_cb;
+
+typedef void (*ddns_action_t)(struct dhcp_ddns_cb *ddns_cb,
+ isc_result_t result);
+
+typedef struct dhcp_ddns_cb {
+ struct data_string fwd_name;
+ struct data_string rev_name;
+ struct data_string dhcid;
+ struct iaddr address;
+ int address_type;
+
+ unsigned long ttl;
+
+ unsigned char zone_name[DHCP_MAXDNS_WIRE];
+ isc_sockaddrlist_t zone_server_list;
+ isc_sockaddr_t zone_addrs[DHCP_MAXNS];
+ int zone_addr_count;
+ struct dns_zone *zone;
+
+ int flags;
+ TIME timeout;
+ int state;
+ ddns_action_t cur_func;
+
+ struct dhcp_ddns_cb * next_op;
+
+ /* Lease or client state that triggered the ddns operation */
+ void *lease;
+ struct binding_scope **scope;
+
+ void *transaction;
+ void *dataspace;
+} dhcp_ddns_cb_t;
+
extern struct ipv6_pool **pools;
extern int num_pools;
/* ddns.c */
int ddns_updates(struct packet *, struct lease *, struct lease *,
struct iasubopt *, struct iasubopt *, struct option_state *);
-int ddns_removals(struct lease *, struct iasubopt *);
+int ddns_removals(struct lease *, struct iasubopt *, struct dhcp_ddns_cb *);
/* parse.c */
void add_enumeration (struct enumeration *);
struct binding_scope **, struct expression *,
const char *, int);
int binding_value_dereference (struct binding_value **, const char *, int);
-#if defined (NSUPDATE)
+#if defined (NSUPDATE_OLD)
int evaluate_dns_expression PROTO ((ns_updrec **, struct packet *,
struct lease *,
struct client_state *,
const char *, const char *, const char *);
void indent_spaces (FILE *, int);
#if defined (NSUPDATE)
+#if 0
void print_dns_status (int, ns_updque *);
#endif
+#endif
const char *print_time(TIME);
void get_hw_addr(const char *name, struct hardware *hw);
void dhclient_schedule_updates(struct client_state *client,
struct iaddr *addr, int offset);
void client_dns_update_timeout (void *cp);
-isc_result_t client_dns_update(struct client_state *client, int, int,
- struct iaddr *);
+isc_result_t client_dns_update(struct client_state *client,
+ dhcp_ddns_cb_t *ddns_cb);
+void client_dns_remove(struct client_state *client, struct iaddr *addr);
void dhcpv4_client_assignments(void);
void dhcpv6_client_assignments(void);
isc_result_t dns_zone_lookup (struct dns_zone **, const char *);
int dns_zone_dereference PROTO ((struct dns_zone **, const char *, int));
#if defined (NSUPDATE)
-isc_result_t find_cached_zone (const char *, ns_class, char *,
- size_t, struct in_addr *, int, int *,
- struct dns_zone **);
+#define FIND_FORWARD 0
+#define FIND_REVERSE 1
+isc_result_t find_cached_zone (dhcp_ddns_cb_t *, int);
void forget_zone (struct dns_zone **);
void repudiate_zone (struct dns_zone **);
-void cache_found_zone (ns_class, char *, struct in_addr *, int);
+//void cache_found_zone (ns_class, char *, struct in_addr *, int);
int get_dhcid (struct data_string *, int, const u_int8_t *, unsigned);
+void dhcid_tolease (struct data_string *, struct data_string *);
+isc_result_t dhcid_fromlease (struct data_string *, struct data_string *);
isc_result_t ddns_update_fwd(struct data_string *, struct iaddr,
struct data_string *, unsigned long, unsigned,
unsigned);
void mark_phosts_unavailable(void);
void mark_interfaces_unavailable(void);
+dhcp_ddns_cb_t *ddns_cb_alloc(const char *file, int line);
+void ddns_cb_free (dhcp_ddns_cb_t *ddns_cb, const char *file, int line);
+void ddns_cb_forget_zone (dhcp_ddns_cb_t *ddns_cb);
+
+//void *key_from_zone(struct dns_zone *zone);
+
+isc_result_t
+ddns_modify_fwd(dhcp_ddns_cb_t *ddns_cb);
+
+isc_result_t
+ddns_modify_ptr(dhcp_ddns_cb_t *ddns_cb);
+
+void
+ddns_cancel(dhcp_ddns_cb_t *ddns_cb);
+++ /dev/null
-/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * 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 ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC 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.
- */
-
-/* $Id: commandline.h,v 1.2 2007/11/16 11:04:11 shane Exp $ */
-
-#ifndef ISC_COMMANDLINE_H
-#define ISC_COMMANDLINE_H 1
-
-/*! \file isc/commandline.h */
-
-#include <isc-dhcp/boolean.h>
-#include <isc-dhcp/lang.h>
-/*#include <isc-dhcp/platform.h>*/
-
-/*% Index into parent argv vector. */
-extern int isc_commandline_index;
-/*% Character checked for validity. */
-extern int isc_commandline_option;
-/*% Argument associated with option. */
-extern char *isc_commandline_argument;
-/*% For printing error messages. */
-extern char *isc_commandline_progname;
-/*% Print error message. */
-extern isc_boolean_t isc_commandline_errprint;
-/*% Reset getopt. */
-extern isc_boolean_t isc_commandline_reset;
-
-ISC_LANG_BEGINDECLS
-
-/*% parse command line */
-int
-isc_commandline_parse(int argc, char * const *argv, const char *options);
-
-ISC_LANG_ENDDECLS
-
-#endif /* ISC_COMMANDLINE_H */
+++ /dev/null
-/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2000, 2001 Internet Software Consortium.
- *
- * 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 ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC 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.
- */
-
-/* $Id: formatcheck.h,v 1.2 2007/11/16 11:04:11 shane Exp $ */
-
-#ifndef ISC_FORMATCHECK_H
-#define ISC_FORMATCHECK_H 1
-
-/*! \file isc/formatcheck.h */
-
-/*%
- * ISC_FORMAT_PRINTF().
- *
- * \li fmt is the location of the format string parameter.
- * \li args is the location of the first argument (or 0 for no argument checking).
- *
- * Note:
- * \li The first parameter is 1, not 0.
- */
-#ifdef __GNUC__
-#define ISC_FORMAT_PRINTF(fmt, args) __attribute__((__format__(__printf__, fmt, args)))
-#else
-#define ISC_FORMAT_PRINTF(fmt, args)
-#endif
-
-#endif /* ISC_FORMATCHECK_H */
+++ /dev/null
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1999-2003 by Internet Software Consortium
- *
- * Permission to use, copy, modify, and 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 ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC 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.
- *
- * Internet Systems Consortium, Inc.
- * 950 Charter Street
- * Redwood City, CA 94063
- * <info@isc.org>
- * https://www.isc.org/
- */
-
-#ifndef ISC_INT_H
-#define ISC_INT_H 1
-
-#include <isc-dhcp/lang.h>
-
-ISC_LANG_BEGINDECLS
-
-typedef char isc_int8_t;
-typedef unsigned char isc_uint8_t;
-typedef short isc_int16_t;
-typedef unsigned short isc_uint16_t;
-typedef int isc_int32_t;
-typedef unsigned int isc_uint32_t;
-typedef long long isc_int64_t;
-typedef unsigned long long isc_uint64_t;
-
-ISC_LANG_ENDDECLS
-
-#endif /* ISC_INT_H */
+++ /dev/null
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1999-2003 by Internet Software Consortium
- *
- * Permission to use, copy, modify, and 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 ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC 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.
- *
- * Internet Systems Consortium, Inc.
- * 950 Charter Street
- * Redwood City, CA 94063
- * <info@isc.org>
- * https://www.isc.org/
- */
-
-#ifndef ISC_LANG_H
-#define ISC_LANG_H 1
-
-#ifdef __cplusplus
-#define ISC_LANG_BEGINDECLS extern "C" {
-#define ISC_LANG_ENDDECLS }
-#else
-#define ISC_LANG_BEGINDECLS
-#define ISC_LANG_ENDDECLS
-#endif
-
-#endif /* ISC_LANG_H */
+++ /dev/null
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1997-2003 by Internet Software Consortium
- *
- * Permission to use, copy, modify, and 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 ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC 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.
- *
- * Internet Systems Consortium, Inc.
- * 950 Charter Street
- * Redwood City, CA 94063
- * <info@isc.org>
- * https://www.isc.org/
- */
-
-#ifndef ISC_LIST_H
-#define ISC_LIST_H 1
-
-#define ISC_LIST(type) struct { type *head, *tail; }
-#define ISC_LIST_INIT(list) \
- do { (list).head = NULL; (list).tail = NULL; } while (0)
-
-#define ISC_LINK(type) struct { type *prev, *next; }
-#define ISC_LINK_INIT(elt, link) \
- do { \
- (elt)->link.prev = (void *)(-1); \
- (elt)->link.next = (void *)(-1); \
- } while (0)
-#define ISC_LINK_LINKED(elt, link) ((elt)->link.prev != (void *)(-1))
-
-#define ISC_LIST_HEAD(list) ((list).head)
-#define ISC_LIST_TAIL(list) ((list).tail)
-#define ISC_LIST_EMPTY(list) ((list).head == NULL)
-
-#define ISC_LIST_PREPEND(list, elt, link) \
- do { \
- if ((list).head != NULL) \
- (list).head->link.prev = (elt); \
- else \
- (list).tail = (elt); \
- (elt)->link.prev = NULL; \
- (elt)->link.next = (list).head; \
- (list).head = (elt); \
- } while (0)
-
-#define ISC_LIST_APPEND(list, elt, link) \
- do { \
- if ((list).tail != NULL) \
- (list).tail->link.next = (elt); \
- else \
- (list).head = (elt); \
- (elt)->link.prev = (list).tail; \
- (elt)->link.next = NULL; \
- (list).tail = (elt); \
- } while (0)
-
-#define ISC_LIST_UNLINK(list, elt, link) \
- do { \
- if ((elt)->link.next != NULL) \
- (elt)->link.next->link.prev = (elt)->link.prev; \
- else \
- (list).tail = (elt)->link.prev; \
- if ((elt)->link.prev != NULL) \
- (elt)->link.prev->link.next = (elt)->link.next; \
- else \
- (list).head = (elt)->link.next; \
- (elt)->link.prev = (void *)(-1); \
- (elt)->link.next = (void *)(-1); \
- } while (0)
-
-#define ISC_LIST_PREV(elt, link) ((elt)->link.prev)
-#define ISC_LIST_NEXT(elt, link) ((elt)->link.next)
-
-#define ISC_LIST_INSERTBEFORE(list, before, elt, link) \
- do { \
- if ((before)->link.prev == NULL) \
- ISC_LIST_PREPEND(list, elt, link); \
- else { \
- (elt)->link.prev = (before)->link.prev; \
- (before)->link.prev = (elt); \
- (elt)->link.prev->link.next = (elt); \
- (elt)->link.next = (before); \
- } \
- } while (0)
-
-#define ISC_LIST_INSERTAFTER(list, after, elt, link) \
- do { \
- if ((after)->link.next == NULL) \
- ISC_LIST_APPEND(list, elt, link); \
- else { \
- (elt)->link.next = (after)->link.next; \
- (after)->link.next = (elt); \
- (elt)->link.next->link.prev = (elt); \
- (elt)->link.prev = (after); \
- } \
- } while (0)
-
-#define ISC_LIST_APPENDLIST(list1, list2, link) \
- do { \
- if (ISC_LIST_EMPTY(list1)) \
- (list1) = (list2); \
- else if (!ISC_LIST_EMPTY(list2)) { \
- (list1).tail->link.next = (list2).head; \
- (list2).head->link.prev = (list1).tail; \
- (list1).tail = (list2).tail; \
- (list2).head = NULL; \
- (list2).tail = NULL; \
- } \
- } while (0)
-
-#define ISC_LIST_ENQUEUE(list, elt, link) ISC_LIST_APPEND(list, elt, link)
-#define ISC_LIST_DEQUEUE(list, elt, link) ISC_LIST_UNLINK(list, elt, link)
-
-#endif /* ISC_LIST_H */
+++ /dev/null
-/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1997-2001 Internet Software Consortium.
- *
- * 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 ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC 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.
- */
-
-/* $Id: mem.h,v 1.2 2007/11/16 11:04:11 shane Exp $ */
-
-#ifndef ISC_MEM_H
-#define ISC_MEM_H 1
-
-/*! \file isc/mem.h */
-
-#include <stdio.h>
-
-#include <isc-dhcp/lang.h>
-/*#include <isc-dhcp/mutex.h>*/
-/*#include <isc-dhcp/platform.h>*/
-#include <isc-dhcp/types.h>
-/*#include <isc-dhcp/xml.h>*/
-#include <isc-dhcp/result.h>
-
-ISC_LANG_BEGINDECLS
-
-#define ISC_MEM_LOWATER 0
-#define ISC_MEM_HIWATER 1
-typedef void (*isc_mem_water_t)(void *, int);
-
-typedef void * (*isc_memalloc_t)(void *, size_t);
-typedef void (*isc_memfree_t)(void *, void *);
-
-/*%
- * Define ISC_MEM_DEBUG=1 to make all functions that free memory
- * set the pointer being freed to NULL after being freed.
- * This is the default; set ISC_MEM_DEBUG=0 to disable it.
- */
-#ifndef ISC_MEM_DEBUG
-#define ISC_MEM_DEBUG 1
-#endif
-
-/*%
- * Define ISC_MEM_TRACKLINES=1 to turn on detailed tracing of memory
- * allocation and freeing by file and line number.
- */
-#ifndef ISC_MEM_TRACKLINES
-#define ISC_MEM_TRACKLINES 1
-#endif
-
-/*%
- * Define ISC_MEM_CHECKOVERRUN=1 to turn on checks for using memory outside
- * the requested space. This will increase the size of each allocation.
- */
-#ifndef ISC_MEM_CHECKOVERRUN
-#define ISC_MEM_CHECKOVERRUN 1
-#endif
-
-/*%
- * Define ISC_MEM_FILL=1 to fill each block of memory returned to the system
- * with the byte string '0xbe'. This helps track down uninitialized pointers
- * and the like. On freeing memory, the space is filled with '0xde' for
- * the same reasons.
- */
-#ifndef ISC_MEM_FILL
-#define ISC_MEM_FILL 1
-#endif
-
-/*%
- * Define ISC_MEMPOOL_NAMES=1 to make memory pools store a symbolic
- * name so that the leaking pool can be more readily identified in
- * case of a memory leak.
- */
-#ifndef ISC_MEMPOOL_NAMES
-#define ISC_MEMPOOL_NAMES 1
-#endif
-
-extern unsigned int isc_mem_debugging;
-/*@{*/
-#define ISC_MEM_DEBUGTRACE 0x00000001U
-#define ISC_MEM_DEBUGRECORD 0x00000002U
-#define ISC_MEM_DEBUGUSAGE 0x00000004U
-#define ISC_MEM_DEBUGSIZE 0x00000008U
-#define ISC_MEM_DEBUGCTX 0x00000010U
-#define ISC_MEM_DEBUGALL 0x0000001FU
-/*!<
- * The variable isc_mem_debugging holds a set of flags for
- * turning certain memory debugging options on or off at
- * runtime. Its is intialized to the value ISC_MEM_DEGBUGGING,
- * which is 0 by default but may be overridden at compile time.
- * The following flags can be specified:
- *
- * \li #ISC_MEM_DEBUGTRACE
- * Log each allocation and free to isc_lctx.
- *
- * \li #ISC_MEM_DEBUGRECORD
- * Remember each allocation, and match them up on free.
- * Crash if a free doesn't match an allocation.
- *
- * \li #ISC_MEM_DEBUGUSAGE
- * If a hi_water mark is set, print the maximium inuse memory
- * every time it is raised once it exceeds the hi_water mark.
- *
- * \li #ISC_MEM_DEBUGSIZE
- * Check the size argument being passed to isc_mem_put() matches
- * that passed to isc_mem_get().
- *
- * \li #ISC_MEM_DEBUGCTX
- * Check the mctx argument being passed to isc_mem_put() matches
- * that passed to isc_mem_get().
- */
-/*@}*/
-
-#if ISC_MEM_TRACKLINES
-#define _ISC_MEM_FILELINE , __FILE__, __LINE__
-#define _ISC_MEM_FLARG , const char *, int
-#else
-#define _ISC_MEM_FILELINE
-#define _ISC_MEM_FLARG
-#endif
-
-/*!
- * Define ISC_MEM_USE_INTERNAL_MALLOC=1 to use the internal malloc()
- * implementation in preference to the system one. The internal malloc()
- * is very space-efficient, and quite fast on uniprocessor systems. It
- * performs poorly on multiprocessor machines.
- * JT: we can overcome the performance issue on multiprocessor machines
- * by carefully separating memory contexts.
- */
-
-#ifndef ISC_MEM_USE_INTERNAL_MALLOC
-#define ISC_MEM_USE_INTERNAL_MALLOC 1
-#endif
-
-/*
- * Flags for isc_mem_create2()calls.
- */
-#define ISC_MEMFLAG_NOLOCK 0x00000001 /* no lock is necessary */
-#define ISC_MEMFLAG_INTERNAL 0x00000002 /* use internal malloc */
-#if ISC_MEM_USE_INTERNAL_MALLOC
-#define ISC_MEMFLAG_DEFAULT ISC_MEMFLAG_INTERNAL
-#else
-#define ISC_MEMFLAG_DEFAULT 0
-#endif
-
-
-#define isc_mem_get(c, s) isc__mem_get((c), (s) _ISC_MEM_FILELINE)
-#define isc_mem_allocate(c, s) isc__mem_allocate((c), (s) _ISC_MEM_FILELINE)
-#define isc_mem_strdup(c, p) isc__mem_strdup((c), (p) _ISC_MEM_FILELINE)
-#define isc_mempool_get(c) isc__mempool_get((c) _ISC_MEM_FILELINE)
-
-/*%
- * isc_mem_putanddetach() is a convienence function for use where you
- * have a structure with an attached memory context.
- *
- * Given:
- *
- * \code
- * struct {
- * ...
- * isc_mem_t *mctx;
- * ...
- * } *ptr;
- *
- * isc_mem_t *mctx;
- *
- * isc_mem_putanddetach(&ptr->mctx, ptr, sizeof(*ptr));
- * \endcode
- *
- * is the equivalent of:
- *
- * \code
- * mctx = NULL;
- * isc_mem_attach(ptr->mctx, &mctx);
- * isc_mem_detach(&ptr->mctx);
- * isc_mem_put(mctx, ptr, sizeof(*ptr));
- * isc_mem_detach(&mctx);
- * \endcode
- */
-
-#if ISC_MEM_DEBUG
-#define isc_mem_put(c, p, s) \
- do { \
- isc__mem_put((c), (p), (s) _ISC_MEM_FILELINE); \
- (p) = NULL; \
- } while (0)
-#define isc_mem_putanddetach(c, p, s) \
- do { \
- isc__mem_putanddetach((c), (p), (s) _ISC_MEM_FILELINE); \
- (p) = NULL; \
- } while (0)
-#define isc_mem_free(c, p) \
- do { \
- isc__mem_free((c), (p) _ISC_MEM_FILELINE); \
- (p) = NULL; \
- } while (0)
-#define isc_mempool_put(c, p) \
- do { \
- isc__mempool_put((c), (p) _ISC_MEM_FILELINE); \
- (p) = NULL; \
- } while (0)
-#else
-#define isc_mem_put(c, p, s) isc__mem_put((c), (p), (s) _ISC_MEM_FILELINE)
-#define isc_mem_putanddetach(c, p, s) \
- isc__mem_putanddetach((c), (p), (s) _ISC_MEM_FILELINE)
-#define isc_mem_free(c, p) isc__mem_free((c), (p) _ISC_MEM_FILELINE)
-#define isc_mempool_put(c, p) isc__mempool_put((c), (p) _ISC_MEM_FILELINE)
-#endif
-
-/*@{*/
-isc_result_t
-isc_mem_create(size_t max_size, size_t target_size,
- isc_mem_t **mctxp);
-
-isc_result_t
-isc_mem_create2(size_t max_size, size_t target_size,
- isc_mem_t **mctxp, unsigned int flags);
-
-isc_result_t
-isc_mem_createx(size_t max_size, size_t target_size,
- isc_memalloc_t memalloc, isc_memfree_t memfree,
- void *arg, isc_mem_t **mctxp);
-
-isc_result_t
-isc_mem_createx2(size_t max_size, size_t target_size,
- isc_memalloc_t memalloc, isc_memfree_t memfree,
- void *arg, isc_mem_t **mctxp, unsigned int flags);
-
-/*!<
- * \brief Create a memory context.
- *
- * 'max_size' and 'target_size' are tuning parameters. When
- * ISC_MEMFLAG_INTERNAL is set, allocations smaller than 'max_size'
- * will be satisfied by getting blocks of size 'target_size' from the
- * system allocator and breaking them up into pieces; larger allocations
- * will use the system allocator directly. If 'max_size' and/or
- * 'target_size' are zero, default values will be * used. When
- * ISC_MEMFLAG_INTERNAL is not set, 'target_size' is ignored.
- *
- * 'max_size' is also used to size the statistics arrays and the array
- * used to record active memory when ISC_MEM_DEBUGRECORD is set. Settin
- * 'max_size' too low can have detrimental effects on performance.
- *
- * A memory context created using isc_mem_createx() will obtain
- * memory from the system by calling 'memalloc' and 'memfree',
- * passing them the argument 'arg'. A memory context created
- * using isc_mem_create() will use the standard library malloc()
- * and free().
- *
- * If ISC_MEMFLAG_NOLOCK is set in 'flags', the corresponding memory context
- * will be accessed without locking. The user who creates the context must
- * ensure there be no race. Since this can be a source of bug, it is generally
- * inadvisable to use this flag unless the user is very sure about the race
- * condition and the access to the object is highly performance sensitive.
- *
- * Requires:
- * mctxp != NULL && *mctxp == NULL */
-/*@}*/
-
-/*@{*/
-void
-isc_mem_attach(isc_mem_t *, isc_mem_t **);
-void
-isc_mem_detach(isc_mem_t **);
-/*!<
- * \brief Attach to / detach from a memory context.
- *
- * This is intended for applications that use multiple memory contexts
- * in such a way that it is not obvious when the last allocations from
- * a given context has been freed and destroying the context is safe.
- *
- * Most applications do not need to call these functions as they can
- * simply create a single memory context at the beginning of main()
- * and destroy it at the end of main(), thereby guaranteeing that it
- * is not destroyed while there are outstanding allocations.
- */
-/*@}*/
-
-void
-isc_mem_destroy(isc_mem_t **);
-/*%<
- * Destroy a memory context.
- */
-
-isc_result_t
-isc_mem_ondestroy(isc_mem_t *ctx,
- isc_task_t *task,
- isc_event_t **event);
-/*%<
- * Request to be notified with an event when a memory context has
- * been successfully destroyed.
- */
-
-void
-isc_mem_stats(isc_mem_t *mctx, FILE *out);
-/*%<
- * Print memory usage statistics for 'mctx' on the stream 'out'.
- */
-
-void
-isc_mem_setdestroycheck(isc_mem_t *mctx,
- isc_boolean_t on);
-/*%<
- * If 'on' is ISC_TRUE, 'mctx' will check for memory leaks when
- * destroyed and abort the program if any are present.
- */
-
-/*@{*/
-void
-isc_mem_setquota(isc_mem_t *, size_t);
-size_t
-isc_mem_getquota(isc_mem_t *);
-/*%<
- * Set/get the memory quota of 'mctx'. This is a hard limit
- * on the amount of memory that may be allocated from mctx;
- * if it is exceeded, allocations will fail.
- */
-/*@}*/
-
-size_t
-isc_mem_inuse(isc_mem_t *mctx);
-/*%<
- * Get an estimate of the number of memory in use in 'mctx', in bytes.
- * This includes quantization overhead, but does not include memory
- * allocated from the system but not yet used.
- */
-
-void
-isc_mem_setwater(isc_mem_t *mctx, isc_mem_water_t water, void *water_arg,
- size_t hiwater, size_t lowater);
-/*%<
- * Set high and low water marks for this memory context.
- *
- * When the memory
- * usage of 'mctx' exceeds 'hiwater', '(water)(water_arg, #ISC_MEM_HIWATER)'
- * will be called. When the usage drops below 'lowater', 'water' will
- * again be called, this time with #ISC_MEM_LOWATER.
- *
- * If 'water' is NULL then 'water_arg', 'hi_water' and 'lo_water' are
- * ignored and the state is reset.
- *
- * Requires:
- *
- * 'water' is not NULL.
- * hi_water >= lo_water
- */
-
-void
-isc_mem_printactive(isc_mem_t *mctx, FILE *file);
-/*%<
- * Print to 'file' all active memory in 'mctx'.
- *
- * Requires ISC_MEM_DEBUGRECORD to have been set.
- */
-
-void
-isc_mem_printallactive(FILE *file);
-/*%<
- * Print to 'file' all active memory in all contexts.
- *
- * Requires ISC_MEM_DEBUGRECORD to have been set.
- */
-
-void
-isc_mem_checkdestroyed(FILE *file);
-/*%<
- * Check that all memory contexts have been destroyed.
- * Prints out those that have not been.
- * Fatally fails if there are still active contexts.
- */
-
-/*
- * Memory pools
- */
-
-isc_result_t
-isc_mempool_create(isc_mem_t *mctx, size_t size, isc_mempool_t **mpctxp);
-/*%<
- * Create a memory pool.
- *
- * Requires:
- *\li mctx is a valid memory context.
- *\li size > 0
- *\li mpctxp != NULL and *mpctxp == NULL
- *
- * Defaults:
- *\li maxalloc = UINT_MAX
- *\li freemax = 1
- *\li fillcount = 1
- *
- * Returns:
- *\li #ISC_R_NOMEMORY -- not enough memory to create pool
- *\li #ISC_R_SUCCESS -- all is well.
- */
-
-void
-isc_mempool_destroy(isc_mempool_t **mpctxp);
-/*%<
- * Destroy a memory pool.
- *
- * Requires:
- *\li mpctxp != NULL && *mpctxp is a valid pool.
- *\li The pool has no un"put" allocations outstanding
- */
-
-void
-isc_mempool_setname(isc_mempool_t *mpctx, const char *name);
-/*%<
- * Associate a name with a memory pool. At most 15 characters may be used.
- *
- * Requires:
- *\li mpctx is a valid pool.
- *\li name != NULL;
- */
-
-/*
-void
-isc_mempool_associatelock(isc_mempool_t *mpctx, isc_mutex_t *lock);
-*/
-/*%<
- * Associate a lock with this memory pool.
- *
- * This lock is used when getting or putting items using this memory pool,
- * and it is also used to set or get internal state via the isc_mempool_get*()
- * and isc_mempool_set*() set of functions.
- *
- * Mutiple pools can each share a single lock. For instance, if "manager"
- * type object contained pools for various sizes of events, and each of
- * these pools used a common lock. Note that this lock must NEVER be used
- * by other than mempool routines once it is given to a pool, since that can
- * easily cause double locking.
- *
- * Requires:
- *
- *\li mpctpx is a valid pool.
- *
- *\li lock != NULL.
- *
- *\li No previous lock is assigned to this pool.
- *
- *\li The lock is initialized before calling this function via the normal
- * means of doing that.
- */
-
-/*
- * The following functions get/set various parameters. Note that due to
- * the unlocked nature of pools these are potentially random values unless
- * the imposed externally provided locking protocols are followed.
- *
- * Also note that the quota limits will not always take immediate effect.
- * For instance, setting "maxalloc" to a number smaller than the currently
- * allocated count is permitted. New allocations will be refused until
- * the count drops below this threshold.
- *
- * All functions require (in addition to other requirements):
- * mpctx is a valid memory pool
- */
-
-unsigned int
-isc_mempool_getfreemax(isc_mempool_t *mpctx);
-/*%<
- * Returns the maximum allowed size of the free list.
- */
-
-void
-isc_mempool_setfreemax(isc_mempool_t *mpctx, unsigned int limit);
-/*%<
- * Sets the maximum allowed size of the free list.
- */
-
-unsigned int
-isc_mempool_getfreecount(isc_mempool_t *mpctx);
-/*%<
- * Returns current size of the free list.
- */
-
-unsigned int
-isc_mempool_getmaxalloc(isc_mempool_t *mpctx);
-/*!<
- * Returns the maximum allowed number of allocations.
- */
-
-void
-isc_mempool_setmaxalloc(isc_mempool_t *mpctx, unsigned int limit);
-/*%<
- * Sets the maximum allowed number of allocations.
- *
- * Additional requirements:
- *\li limit > 0
- */
-
-unsigned int
-isc_mempool_getallocated(isc_mempool_t *mpctx);
-/*%<
- * Returns the number of items allocated from this pool.
- */
-
-unsigned int
-isc_mempool_getfillcount(isc_mempool_t *mpctx);
-/*%<
- * Returns the number of items allocated as a block from the parent memory
- * context when the free list is empty.
- */
-
-void
-isc_mempool_setfillcount(isc_mempool_t *mpctx, unsigned int limit);
-/*%<
- * Sets the fillcount.
- *
- * Additional requirements:
- *\li limit > 0
- */
-
-
-/*
- * Pseudo-private functions for use via macros. Do not call directly.
- */
-void *
-isc__mem_get(isc_mem_t *, size_t _ISC_MEM_FLARG);
-void
-isc__mem_putanddetach(isc_mem_t **, void *,
- size_t _ISC_MEM_FLARG);
-void
-isc__mem_put(isc_mem_t *, void *, size_t _ISC_MEM_FLARG);
-void *
-isc__mem_allocate(isc_mem_t *, size_t _ISC_MEM_FLARG);
-void
-isc__mem_free(isc_mem_t *, void * _ISC_MEM_FLARG);
-char *
-isc__mem_strdup(isc_mem_t *, const char *_ISC_MEM_FLARG);
-void *
-isc__mempool_get(isc_mempool_t * _ISC_MEM_FLARG);
-void
-isc__mempool_put(isc_mempool_t *, void * _ISC_MEM_FLARG);
-
-#ifdef HAVE_LIBXML2
-void
-isc_mem_renderxml(isc_mem_t *mgr, xmlTextWriterPtr writer);
-#endif /* HAVE_LIBXML2 */
-
-ISC_LANG_ENDDECLS
-
-#endif /* ISC_MEM_H */
+++ /dev/null
-/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001, 2003 Internet Software Consortium.
- *
- * 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 ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC 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.
- */
-
-/* $Id: print.h,v 1.2 2007/11/16 11:04:11 shane Exp $ */
-
-#ifndef ISC_PRINT_H
-#define ISC_PRINT_H 1
-
-/*! \file isc/print.h */
-
-/***
- *** Imports
- ***/
-
-#include <isc-dhcp/formatcheck.h> /* Required for ISC_FORMAT_PRINTF() macro. */
-#include <isc-dhcp/lang.h>
-/*#include <isc-dhcp/platform.h>*/
-
-/*!
- * This block allows lib/isc/print.c to be cleanly compiled even if
- * the platform does not need it. The standard Makefile will still
- * not compile print.c or archive print.o, so this is just to make test
- * compilation ("make print.o") easier.
- */
-#if !defined(ISC_PLATFORM_NEEDVSNPRINTF) && defined(ISC__PRINT_SOURCE)
-#define ISC_PLATFORM_NEEDVSNPRINTF
-#endif
-
-#if !defined(ISC_PLATFORM_NEEDSPRINTF) && defined(ISC__PRINT_SOURCE)
-#define ISC_PLATFORM_NEEDSPRINTF
-#endif
-
-/***
- *** Macros
- ***/
-#define ISC_PRINT_QUADFORMAT ISC_PLATFORM_QUADFORMAT
-
-/***
- *** Functions
- ***/
-
-#ifdef ISC_PLATFORM_NEEDVSNPRINTF
-#include <stdarg.h>
-#include <stddef.h>
-#endif
-#ifdef ISC_PLATFORM_NEEDSPRINTF
-#include <stdio.h>
-#endif
-
-
-ISC_LANG_BEGINDECLS
-
-#ifdef ISC_PLATFORM_NEEDVSNPRINTF
-int
-isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap)
- ISC_FORMAT_PRINTF(3, 0);
-#define vsnprintf isc_print_vsnprintf
-
-int
-isc_print_snprintf(char *str, size_t size, const char *format, ...)
- ISC_FORMAT_PRINTF(3, 4);
-#define snprintf isc_print_snprintf
-#endif /* ISC_PLATFORM_NEEDVSNPRINTF */
-
-#ifdef ISC_PLATFORM_NEEDSPRINTF
-int
-isc_print_sprintf(char *str, const char *format, ...) ISC_FORMAT_PRINTF(2, 3);
-#define sprintf isc_print_sprintf
-#endif
-
-ISC_LANG_ENDDECLS
-
-#endif /* ISC_PRINT_H */
+++ /dev/null
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1998-2003 by Internet Software Consortium
- *
- * Permission to use, copy, modify, and 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 ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC 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.
- *
- * Internet Systems Consortium, Inc.
- * 950 Charter Street
- * Redwood City, CA 94063
- * <info@isc.org>
- * https://www.isc.org/
- */
-
-#ifndef ISC_RESULT_H
-#define ISC_RESULT_H 1
-
-#include <isc-dhcp/boolean.h>
-#include <isc-dhcp/lang.h>
-#include <isc-dhcp/list.h>
-#include <isc-dhcp/types.h>
-
-ISC_LANG_BEGINDECLS
-
-typedef enum {
- ISC_R_SUCCESS = 0,
- ISC_R_NOMEMORY = 1,
- ISC_R_TIMEDOUT = 2,
- ISC_R_NOTHREADS = 3,
- ISC_R_ADDRNOTAVAIL = 4,
- ISC_R_ADDRINUSE = 5,
- ISC_R_NOPERM = 6,
- ISC_R_NOCONN = 7,
- ISC_R_NETUNREACH = 8,
- ISC_R_HOSTUNREACH = 9,
- ISC_R_NETDOWN = 10,
- ISC_R_HOSTDOWN = 11,
- ISC_R_CONNREFUSED = 12,
- ISC_R_NORESOURCES = 13,
- ISC_R_EOF = 14,
- ISC_R_BOUND = 15,
- ISC_R_TASKDONE = 16,
- ISC_R_LOCKBUSY = 17,
- ISC_R_EXISTS = 18,
- ISC_R_NOSPACE = 19,
- ISC_R_CANCELED = 20,
- ISC_R_TASKNOSEND = 21,
- ISC_R_SHUTTINGDOWN = 22,
- ISC_R_NOTFOUND = 23,
- ISC_R_UNEXPECTEDEND = 24,
- ISC_R_FAILURE = 25,
- ISC_R_IOERROR = 26,
- ISC_R_NOTIMPLEMENTED = 27,
- ISC_R_UNBALANCED = 28,
- ISC_R_NOMORE = 29,
- ISC_R_INVALIDFILE = 30,
- ISC_R_BADBASE64 = 31,
- ISC_R_UNEXPECTEDTOKEN = 32,
- ISC_R_QUOTA = 33,
- ISC_R_UNEXPECTED = 34,
- ISC_R_ALREADYRUNNING = 35,
- ISC_R_HOSTUNKNOWN = 36,
- ISC_R_VERSIONMISMATCH = 37,
- ISC_R_PROTOCOLERROR = 38,
- ISC_R_INVALIDARG = 39,
- ISC_R_NOTCONNECTED = 40,
- ISC_R_NOTYET = 41,
- ISC_R_UNCHANGED = 42,
- ISC_R_MULTIPLE = 43,
- ISC_R_KEYCONFLICT = 44,
- ISC_R_BADPARSE = 45,
- ISC_R_NOKEYS = 46,
- ISC_R_KEY_UNKNOWN = 47,
- ISC_R_INVALIDKEY = 48,
- ISC_R_INCOMPLETE = 49,
- ISC_R_FORMERR = 50,
- ISC_R_SERVFAIL = 51,
- ISC_R_NXDOMAIN = 52,
- ISC_R_NOTIMPL = 53,
- ISC_R_REFUSED = 54,
- ISC_R_YXDOMAIN = 55,
- ISC_R_YXRRSET = 56,
- ISC_R_NXRRSET = 57,
- ISC_R_NOTAUTH = 58,
- ISC_R_NOTZONE = 59,
- ISC_R_BADSIG = 60,
- ISC_R_BADKEY = 61,
- ISC_R_BADTIME = 62,
- ISC_R_NOROOTZONE = 63,
- ISC_R_DESTADDRREQ = 64,
- ISC_R_CROSSZONE = 65,
- ISC_R_NO_TSIG = 66,
- ISC_R_NOT_EQUAL = 67,
- ISC_R_CONNRESET = 68,
- ISC_R_UNKNOWNATTRIBUTE = 69
-} isc_result_t;
-
-
-#define ISC_R_NRESULTS 70 /* Number of results */
-
-const char * isc_result_totext(isc_result_t);
-isc_result_t isc_result_register(unsigned int base,
- unsigned int nresults,
- char **text,
- isc_msgcat_t *msgcat,
- int set);
-
-ISC_LANG_ENDDECLS
-
-#endif /* ISC_RESULT_H */
+++ /dev/null
-/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
- *
- * 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 ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC 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.
- */
-
-/* $Id: string.h,v 1.2 2007/11/16 11:04:11 shane Exp $ */
-
-#ifndef ISC_STRING_H
-#define ISC_STRING_H 1
-
-/*! \file isc/string.h */
-
-#include <isc-dhcp/formatcheck.h>
-#include <isc-dhcp/int.h>
-#include <isc-dhcp/lang.h>
-/*#include <isc-dhcp/platform.h>*/
-#include <isc-dhcp/types.h>
-#include <isc-dhcp/result.h>
-
-#include <string.h>
-
-#ifdef ISC_PLATFORM_HAVESTRINGSH
-#include <strings.h>
-#endif
-
-#define ISC_STRING_MAGIC 0x5e
-
-ISC_LANG_BEGINDECLS
-
-isc_uint64_t
-isc_string_touint64(char *source, char **endp, int base);
-/*%<
- * Convert the string pointed to by 'source' to isc_uint64_t.
- *
- * On successful conversion 'endp' points to the first character
- * after conversion is complete.
- *
- * 'base': 0 or 2..36
- *
- * If base is 0 the base is computed from the string type.
- *
- * On error 'endp' points to 'source'.
- */
-
-isc_result_t
-isc_string_copy(char *target, size_t size, const char *source);
-/*
- * Copy the string pointed to by 'source' to 'target' which is a
- * pointer to a string of at least 'size' bytes.
- *
- * Requires:
- * 'target' is a pointer to a char[] of at least 'size' bytes.
- * 'size' an integer > 0.
- * 'source' == NULL or points to a NUL terminated string.
- *
- * Ensures:
- * If result == ISC_R_SUCCESS
- * 'target' will be a NUL terminated string of no more
- * than 'size' bytes (including NUL).
- *
- * If result == ISC_R_NOSPACE
- * 'target' is undefined.
- *
- * Returns:
- * ISC_R_SUCCESS -- 'source' was successfully copied to 'target'.
- * ISC_R_NOSPACE -- 'source' could not be copied since 'target'
- * is too small.
- */
-
-void
-isc_string_copy_truncate(char *target, size_t size, const char *source);
-/*
- * Copy the string pointed to by 'source' to 'target' which is a
- * pointer to a string of at least 'size' bytes.
- *
- * Requires:
- * 'target' is a pointer to a char[] of at least 'size' bytes.
- * 'size' an integer > 0.
- * 'source' == NULL or points to a NUL terminated string.
- *
- * Ensures:
- * 'target' will be a NUL terminated string of no more
- * than 'size' bytes (including NUL).
- */
-
-isc_result_t
-isc_string_append(char *target, size_t size, const char *source);
-/*
- * Append the string pointed to by 'source' to 'target' which is a
- * pointer to a NUL terminated string of at least 'size' bytes.
- *
- * Requires:
- * 'target' is a pointer to a NUL terminated char[] of at
- * least 'size' bytes.
- * 'size' an integer > 0.
- * 'source' == NULL or points to a NUL terminated string.
- *
- * Ensures:
- * If result == ISC_R_SUCCESS
- * 'target' will be a NUL terminated string of no more
- * than 'size' bytes (including NUL).
- *
- * If result == ISC_R_NOSPACE
- * 'target' is undefined.
- *
- * Returns:
- * ISC_R_SUCCESS -- 'source' was successfully appended to 'target'.
- * ISC_R_NOSPACE -- 'source' could not be appended since 'target'
- * is too small.
- */
-
-void
-isc_string_append_truncate(char *target, size_t size, const char *source);
-/*
- * Append the string pointed to by 'source' to 'target' which is a
- * pointer to a NUL terminated string of at least 'size' bytes.
- *
- * Requires:
- * 'target' is a pointer to a NUL terminated char[] of at
- * least 'size' bytes.
- * 'size' an integer > 0.
- * 'source' == NULL or points to a NUL terminated string.
- *
- * Ensures:
- * 'target' will be a NUL terminated string of no more
- * than 'size' bytes (including NUL).
- */
-
-isc_result_t
-isc_string_printf(char *target, size_t size, const char *format, ...)
- ISC_FORMAT_PRINTF(3, 4);
-/*
- * Print 'format' to 'target' which is a pointer to a string of at least
- * 'size' bytes.
- *
- * Requires:
- * 'target' is a pointer to a char[] of at least 'size' bytes.
- * 'size' an integer > 0.
- * 'format' == NULL or points to a NUL terminated string.
- *
- * Ensures:
- * If result == ISC_R_SUCCESS
- * 'target' will be a NUL terminated string of no more
- * than 'size' bytes (including NUL).
- *
- * If result == ISC_R_NOSPACE
- * 'target' is undefined.
- *
- * Returns:
- * ISC_R_SUCCESS -- 'format' was successfully printed to 'target'.
- * ISC_R_NOSPACE -- 'format' could not be printed to 'target' since it
- * is too small.
- */
-
-void
-isc_string_printf_truncate(char *target, size_t size, const char *format, ...)
- ISC_FORMAT_PRINTF(3, 4);
-/*
- * Print 'format' to 'target' which is a pointer to a string of at least
- * 'size' bytes.
- *
- * Requires:
- * 'target' is a pointer to a char[] of at least 'size' bytes.
- * 'size' an integer > 0.
- * 'format' == NULL or points to a NUL terminated string.
- *
- * Ensures:
- * 'target' will be a NUL terminated string of no more
- * than 'size' bytes (including NUL).
- */
-
-
-/*
-char *
-isc_string_regiondup(isc_mem_t *mctx, const isc_region_t *source);
-*/
-/*
- * Copy the region pointed to by r to a NUL terminated string
- * allocated from the memory context pointed to by mctx.
- *
- * The result should be deallocated using isc_mem_free()
- *
- * Requires:
- * 'mctx' is a point to a valid memory context.
- * 'source' is a pointer to a valid region.
- *
- * Returns:
- * a pointer to a NUL terminated string or
- * NULL if memory for the copy could not be allocated
- *
- */
-
-char *
-isc_string_separate(char **stringp, const char *delim);
-
-#ifdef ISC_PLATFORM_NEEDSTRSEP
-#define strsep isc_string_separate
-#endif
-
-#ifdef ISC_PLATFORM_NEEDMEMMOVE
-#define memmove(a,b,c) bcopy(b,a,c)
-#endif
-
-size_t
-isc_string_strlcpy(char *dst, const char *src, size_t size);
-
-
-#ifdef ISC_PLATFORM_NEEDSTRLCPY
-#define strlcpy isc_string_strlcpy
-#endif
-
-
-size_t
-isc_string_strlcat(char *dst, const char *src, size_t size);
-
-#ifdef ISC_PLATFORM_NEEDSTRLCAT
-#define strlcat isc_string_strlcat
-#endif
-
-ISC_LANG_ENDDECLS
-
-#endif /* ISC_STRING_H */
+++ /dev/null
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1999-2003 by Internet Software Consortium
- *
- * Permission to use, copy, modify, and 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 ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC 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.
- *
- * Internet Systems Consortium, Inc.
- * 950 Charter Street
- * Redwood City, CA 94063
- * <info@isc.org>
- * https://www.isc.org/
- */
-
-#ifndef ISC_TYPES_H
-#define ISC_TYPES_H 1
-
-#include <isc-dhcp/int.h>
-#include <isc-dhcp/boolean.h>
-#include <isc-dhcp/list.h>
-
-/***
- *** Core Types.
- ***/
-
-typedef struct isc_mem isc_mem_t;
-typedef struct isc_mempool isc_mempool_t;
-typedef struct isc_msgcat isc_msgcat_t;
-typedef unsigned int isc_eventtype_t;
-typedef struct isc_event isc_event_t;
-typedef struct isc_task isc_task_t;
-typedef struct isc_taskmgr isc_taskmgr_t;
-typedef struct isc_rwlock isc_rwlock_t;
-
-typedef void (*isc_taskaction_t)(isc_task_t *, isc_event_t *);
-
-#endif /* ISC_TYPES_H */
/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1998-2003 by Internet Software Consortium
+ * Copyright (c) 2004,2007-2009 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2001-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* 950 Charter Street
* Redwood City, CA 94063
* <info@isc.org>
- * https://www.isc.org/
+ * http://www.isc.org/
*/
+#ifndef MINIRES_H
+#define MINIRES_H
-#ifndef ISC_BOOLEAN_H
-#define ISC_BOOLEAN_H 1
+#include "cdefs.h"
+#include "osdep.h"
-#include <isc-dhcp/lang.h>
-
-ISC_LANG_BEGINDECLS
-
-typedef enum { isc_boolean_false = 0, isc_boolean_true = 1 } isc_boolean_t;
-
-#define ISC_FALSE isc_boolean_false
-#define ISC_TRUE isc_boolean_true
+/*
+ * Based on the Dynamic DNS reference implementation by Viraj Bais
+ * <viraj_bais@ccm.fm.intel.com>
+ */
-ISC_LANG_ENDDECLS
+int MRns_name_compress(const char *, u_char *, size_t, const unsigned char **,
+ const unsigned char **);
+int MRns_name_unpack(const unsigned char *, const unsigned char *,
+ const unsigned char *, unsigned char *, size_t);
+int MRns_name_pack (const unsigned char *, unsigned char *,
+ unsigned, const unsigned char **, const unsigned char **);
+int MRns_name_ntop(const unsigned char *, char *, size_t);
+int MRns_name_pton(const char *, u_char *, size_t);
-#endif /* ISC_BOOLEAN_H */
+#endif /* MINIRES_H */
+++ /dev/null
-/*
- * Copyright (c) 2004,2007-2008 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 2001-2003 by Internet Software Consortium
- *
- * Permission to use, copy, modify, and 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 ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC 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.
- *
- * Internet Systems Consortium, Inc.
- * 950 Charter Street
- * Redwood City, CA 94063
- * <info@isc.org>
- * https://www.isc.org/
- */
-#ifndef MINIRES_H
-#define MINIRES_H
-
-#include "cdefs.h"
-#include "osdep.h"
-
-#define _ns_flagdata MR_ns_flagdata
-
-#include "minires/resolv.h"
-#include "minires/res_update.h"
-#include "isc-dhcp/result.h"
-
-/*
- * Based on the Dynamic DNS reference implementation by Viraj Bais
- * <viraj_bais@ccm.fm.intel.com>
- */
-
-int minires_mkupdate (ns_updrec *, unsigned char *, unsigned);
-int minires_update (ns_updrec *);
-ns_updrec *minires_mkupdrec (int, const char *, unsigned int,
- unsigned int, unsigned long);
-void minires_freeupdrec (ns_updrec *);
-int minires_nmkupdate (res_state, ns_updrec *, double *, unsigned *);
-isc_result_t minires_nupdate (res_state, ns_updrec *);
-int minires_ninit (res_state);
-ns_rcode isc_rcode_to_ns (isc_result_t);
-
-int MRns_name_compress(const char *, u_char *, size_t, const unsigned char **,
- const unsigned char **);
-int MRns_name_unpack(const unsigned char *, const unsigned char *,
- const unsigned char *, unsigned char *, size_t);
-int MRns_name_ntop(const unsigned char *, char *, size_t);
-int MRns_name_pton(const char *, u_char *, size_t);
-
-#if defined (MINIRES_LIB)
-#define res_update minires_update
-#define res_mkupdate minires_mkupdate
-#define res_mkupdrec minires_mkupdrec
-#define res_freeupdrec minires_freeupdrec
-#define res_nmkupdate minires_nmkupdate
-#define res_nupdate minires_nupdate
-#define __p_type_syms MR__p_type_syms
-#define dn_comp MRdn_comp
-#define loc_aton MRloc_aton
-#define sym_ston MRsym_ston
-#define res_buildservicelist MRres_buildservicelist
-#define res_destroyservicelist MRres_destroyservicelist
-#define res_buildprotolist MRres_buildprotolist
-#define res_destroyprotolist MRres_destroyprotolist
-#define res_servicenumber MRres_servicenumber
-#define res_protocolnumber MRres_protocolnumber
-#define res_protocolname MRres_protocolname
-#define res_servicename MRres_servicename
-#define ns_datetosecs MRns_datetosecs
-#define b64_pton MRb64_pton
-#define res_ninit minires_ninit
-#define res_randomid MRres_randomid
-#define res_findzonecut MRres_findzonecut
-#define res_nsend MRres_nsend
-#define res_nsendsigned MRres_nsendsigned
-#define ns_samename MRns_samename
-#define res_nameinquery MRres_nameinquery
-#define res_queriesmatch MRres_queriesmatch
-#define dn_expand MRdn_expand
-#define ns_get16 MRns_get16
-#define res_close MRres_close
-#define res_nclose MRres_nclose
-#define res_ourserver_p MRres_ourserver_p
-#define ns_sign MRns_sign
-#define p_class MRp_class
-#define p_section MRp_section
-#define ns_makecanon MRns_makecanon
-#define ns_parserr MRns_parserr
-#define ns_samedomain MRns_samedomain
-#define ns_name_uncompress MRns_name_uncompress
-#define res_nmkquery MRres_nmkquery
-#define ns_initparse MRns_initparse
-#define res_nquery MRres_nquery
-#define res_nsearch MRres_nsearch
-#define res_hostalias MRres_hostalias
-#define res_nquerydomain MRres_nquerydomain
-#define ns_skiprr MRns_skiprr
-#define dn_skipname MRdn_skipname
-#define ns_name_ntol MRns_name_ntol
-#define ns_sign_tcp_init MRns_sign_tcp_init
-#define ns_sign_tcp MRns_sign_tcp
-#define ns_name_ntop MRns_name_ntop
-#define ns_name_pton MRns_name_pton
-#define ns_name_unpack MRns_name_unpack
-#define ns_name_pack MRns_name_pack
-#define ns_name_compress MRns_name_compress
-#define ns_name_skip MRns_name_skip
-#define ns_subdomain MRns_subdomain
-#define ns_find_tsig MRns_find_tsig
-#define ns_verify MRns_verify
-#define ns_verify_tcp_init MRns_verify_tcp_init
-#define ns_verify_tcp MRns_verify_tcp
-#define b64_ntop MRb64_ntop
-
-extern const struct res_sym __p_type_syms[];
-extern struct timeval cur_tv;
-#define cur_time cur_tv.tv_sec
-
-int dn_comp (const char *,
- unsigned char *, unsigned, unsigned char **, unsigned char **);
-int loc_aton (const char *, u_char *);
-int sym_ston (const struct res_sym *, const char *, int *);
-void res_buildservicelist (void);
-void res_destroyservicelist (void);
-void res_buildprotolist(void);
-void res_destroyprotolist(void);
-const char *res_protocolname(int);
-const char *res_servicename(u_int16_t, const char *);
-u_int32_t ns_datetosecs (const char *cp, int *errp);
-int b64_pton (char const *, unsigned char *, size_t);
-u_int res_randomid(void);
-isc_result_t res_findzonecut (res_state, const char *, ns_class, int, char *,
- size_t, struct in_addr *, int, int *, void *);
-isc_result_t res_nsend (res_state,
- double *, unsigned, double *, unsigned, unsigned *);
-isc_result_t res_nsendsigned (res_state, double *, unsigned, ns_tsig_key *,
- double *, unsigned, unsigned *);
-int ns_samename (const char *, const char *);
-int res_nameinquery (const char *, int, int,
- const unsigned char *, const unsigned char *);
-int res_queriesmatch (const unsigned char *, const unsigned char *,
- const unsigned char *, const unsigned char *);
-int dn_expand (const unsigned char *,
- const unsigned char *, const unsigned char *, char *, unsigned);
-unsigned int ns_get16 (const unsigned char *);
-void res_close (void);
-void res_nclose (res_state);
-int res_ourserver_p (const res_state, const struct sockaddr_in *);
-isc_result_t ns_sign (unsigned char *, unsigned *,
- unsigned, int, void *, const unsigned char *,
- unsigned, unsigned char *, unsigned *, time_t);
-const char *p_class (int);
-const char *p_section (int section, int opcode);
-isc_result_t ns_makecanon (const char *, char *, size_t);
-isc_result_t ns_parserr (ns_msg *, ns_sect, int, ns_rr *);
-int ns_samedomain (const char *, const char *);
-int ns_name_uncompress (const u_char *, const u_char *,
- const u_char *, char *, size_t);
-isc_result_t res_nmkquery (res_state, int, const char *, ns_class, ns_type,
- const unsigned char *, unsigned,
- const unsigned char *, double *,
- unsigned, unsigned *);
-isc_result_t ns_initparse (const unsigned char *, unsigned, ns_msg *);
-isc_result_t res_nquery(res_state, const char *,
- ns_class, ns_type, double *, unsigned, unsigned *);
-isc_result_t res_nsearch(res_state, const char *,
- ns_class, ns_type, double *, unsigned, unsigned *);
-const char *res_hostalias (const res_state, const char *, char *, size_t);
-isc_result_t res_nquerydomain(res_state, const char *, const char *,
- ns_class class, ns_type type,
- double *, unsigned, unsigned *);
-
-isc_result_t ns_skiprr(const unsigned char *,
- const unsigned char *, ns_sect, int, int *);
-int dn_skipname (const unsigned char *, const unsigned char *);
-u_int32_t getULong (const unsigned char *);
-int32_t getLong (const unsigned char *);
-u_int32_t getUShort (const unsigned char *);
-int32_t getShort (const unsigned char *);
-u_int32_t getUChar (const unsigned char *);
-void putULong (unsigned char *, u_int32_t);
-void putLong (unsigned char *, int32_t);
-void putUShort (unsigned char *, u_int32_t);
-void putShort (unsigned char *, int32_t);
-void putUChar (unsigned char *, u_int32_t);
-int ns_name_ntol (const unsigned char *, unsigned char *, size_t);
-isc_result_t ns_sign_tcp_init (void *, const unsigned char *,
- unsigned, ns_tcp_tsig_state *);
-isc_result_t ns_sign_tcp (unsigned char *,
- unsigned *, unsigned, int, ns_tcp_tsig_state *, int);
-int ns_name_pack (const unsigned char *, unsigned char *,
- unsigned, const unsigned char **, const unsigned char **);
-int ns_name_skip (const unsigned char **, const unsigned char *);
-int ns_subdomain (const char *, const char *);
-unsigned char *ns_find_tsig (unsigned char *, unsigned char *);
-isc_result_t ns_verify (unsigned char *, unsigned *, void *,
- const unsigned char *,
- unsigned, unsigned char *, unsigned *, time_t *, int);
-isc_result_t ns_verify_tcp_init (void *, const unsigned char *, unsigned,
- ns_tcp_tsig_state *);
-isc_result_t ns_verify_tcp (unsigned char *, unsigned *,
- ns_tcp_tsig_state *, int);
-int b64_ntop (unsigned char const *, size_t, char *, size_t);
-
-ns_rcode find_cached_zone (const char *, ns_class, char *,
- size_t, struct in_addr *, int, int *, void *);
-int find_tsig_key (ns_tsig_key **, const char *, void *);
-int forget_zone (void *);
-int repudiate_zone (void *);
-void cache_found_zone (ns_class, char *, struct in_addr *, int);
-isc_result_t uerr2isc (int);
-isc_result_t ns_rcode_to_isc (int);
-
-#define DprintQ(a,b,c,d)
-#define Dprint(a,b)
-#define Perror(a, b, c, d)
-#define Aerror(a, b, c, d, e)
-#define DPRINTF(x)
-
-#define USE_MD5
-#endif
-
-#if defined (TRACING)
-void trace_mr_statp_setup (res_state);
-#endif
-
-#endif /* MINIRES_H */
+++ /dev/null
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1999-2003 by Internet Software Consortium
- *
- * Permission to use, copy, modify, and 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 ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC 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.
- *
- * Internet Systems Consortium, Inc.
- * 950 Charter Street
- * Redwood City, CA 94063
- * <info@isc.org>
- * https://www.isc.org/
- */
-
-/*
- * $Id: res_update.h,v 1.5 2009/07/23 18:52:20 sar Exp $
- */
-
-#ifndef __RES_UPDATE_H
-#define __RES_UPDATE_H
-
-#include <sys/types.h>
-#include "arpa/nameser.h"
-#include <isc-dhcp/list.h>
-
-/*
- * This RR-like structure is particular to UPDATE.
- */
-typedef struct ns_updrec {
- ISC_LINK(struct ns_updrec) r_link, r_glink;
- ns_sect r_section; /* ZONE/PREREQUISITE/UPDATE */
- char *r_dname; /* owner of the RR */
- ns_class r_class; /* class number */
- ns_type r_type; /* type number */
- u_int32_t r_ttl; /* time to live */
- const unsigned char *r_data; /* rdata fields as text string */
- unsigned char *r_data_ephem; /* pointer to freeable r_data */
- unsigned int r_size; /* size of r_data field */
- int r_opcode; /* type of operation */
- /* following fields for private use by the resolver/server
- routines */
- struct databuf *r_dp; /* databuf to process */
- struct databuf *r_deldp; /* databuf's deleted/overwritten */
- unsigned int r_zone; /* zone number on server */
-} ns_updrec;
-typedef ISC_LIST(ns_updrec) ns_updque;
-
-#endif /*__RES_UPDATE_H*/
+++ /dev/null
-/*
- * Copyright (c) 1983, 1987, 1989
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*
- * Portions Copyright (c) 2004,2007-2008 by Internet Systems Consortium,
- * Inc. ("ISC")
- * Portions Copyright (c) 1995-2003 by Internet Software Consortium
- *
- * Permission to use, copy, modify, and 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 ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC 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.
- *
- * Internet Systems Consortium, Inc.
- * 950 Charter Street
- * Redwood City, CA 94063
- * <info@isc.org>
- * https://www.isc.org/
- */
-
-/*
- * @(#)resolv.h 8.1 (Berkeley) 6/2/93
- * $Id: resolv.h,v 1.7 2009/07/23 18:52:20 sar Exp $
- */
-
-#ifndef _RESOLV_H_
-#define _RESOLV_H_
-
-#include <sys/types.h>
-
-/*
- * This used to be defined in res_query.c, now it's in herror.c.
- * [XXX no it's not. It's in irs/irs_data.c]
- * It was
- * never extern'd by any *.h file before it was placed here. For thread
- * aware programs, the last h_errno value set is stored in res->h_errno.
- *
- * XXX: There doesn't seem to be a good reason for exposing RES_SET_H_ERRNO
- * (and __h_errno_set) to the public via <resolv.h>.
- * XXX: __h_errno_set is really part of IRS, not part of the resolver.
- * If somebody wants to build and use a resolver that doesn't use IRS,
- * what do they do? Perhaps something like
- * #ifdef WANT_IRS
- * # define RES_SET_H_ERRNO(r,x) __h_errno_set(r,x)
- * #else
- * # define RES_SET_H_ERRNO(r,x) (h_errno = (r)->res_h_errno = (x))
- * #endif
- */
-
-#define RES_SET_H_ERRNO(r,x) __h_errno_set(r,x)
-struct __res_state; /* forward */
-void __h_errno_set(struct __res_state *res, int err);
-
-/*
- * Resolver configuration file.
- * Normally not present, but may contain the address of the
- * inital name server(s) to query and the domain search list.
- */
-
-#ifndef _PATH_RESCONF
-#define _PATH_RESCONF "/etc/resolv.conf"
-#endif
-
-typedef enum { res_goahead, res_nextns, res_modified, res_done, res_error }
- res_sendhookact;
-
-typedef res_sendhookact (*res_send_qhook) (struct sockaddr_in * const *ns,
- double **query,
- unsigned *querylen,
- double *ans,
- unsigned anssiz,
- int *resplen);
-
-typedef res_sendhookact (*res_send_rhook) (const struct sockaddr_in *ns,
- double *query,
- unsigned querylen,
- double *ans,
- unsigned anssiz,
- int *resplen);
-
-struct res_sym {
- int number; /* Identifying number, like T_MX */
- char * name; /* Its symbolic name, like "MX" */
- char * humanname; /* Its fun name, like "mail exchanger" */
-};
-
-/*
- * Global defines and variables for resolver stub.
- */
-#define MAXNS 3 /* max # name servers we'll track */
-#define MAXDFLSRCH 3 /* # default domain levels to try */
-#define MAXDNSRCH 6 /* max # domains in search path */
-#define LOCALDOMAINPARTS 2 /* min levels in name that is "local" */
-
-#define RES_TIMEOUT 5 /* min. seconds between retries */
-#define MAXRESOLVSORT 10 /* number of net to sort on */
-#define RES_MAXNDOTS 15 /* should reflect bit field size */
-#define RES_MAXRETRANS 30 /* only for resolv.conf/RES_OPTIONS */
-#define RES_MAXRETRY 5 /* only for resolv.conf/RES_OPTIONS */
-#define RES_DFLRETRY 2 /* Default #/tries. */
-
-struct __res_state {
- int retrans; /* retransmition time interval */
- int retry; /* number of times to retransmit */
- u_long options; /* option flags - see below. */
- int nscount; /* number of name servers */
- struct sockaddr_in
- nsaddr_list[MAXNS]; /* address of name server */
-#define nsaddr nsaddr_list[0] /* for backward compatibility */
- u_short id; /* current message id */
- char *dnsrch[MAXDNSRCH+1]; /* components of domain to search */
- char defdname[256]; /* default domain (deprecated) */
- u_long pfcode; /* RES_PRF_ flags - see below. */
- unsigned ndots:4; /* threshold for initial abs. query */
- unsigned nsort:4; /* number of elements in sort_list[] */
- char unused[3];
- struct {
- struct in_addr addr;
- u_int32_t mask;
- } sort_list[MAXRESOLVSORT];
- res_send_qhook qhook; /* query hook */
- res_send_rhook rhook; /* response hook */
- int res_h_errno; /* last one set for this context */
- int _sock; /* PRIVATE: for res_send i/o */
- u_int _flags; /* PRIVATE: see below */
- char pad[52]; /* On an i386 this means 512b total. */
-};
-
-typedef struct __res_state *res_state;
-
-/*
- * Resolver flags (used to be discrete per-module statics ints).
- */
-#define RES_F_VC 0x00000001 /* socket is TCP */
-#define RES_F_CONN 0x00000002 /* socket is connected */
-
-/* res_findzonecut() options */
-#define RES_EXHAUSTIVE 0x00000001 /* always do all queries */
-
-/*
- * Resolver options (keep these in synch with res_debug.c, please)
- */
-#define RES_INIT 0x00000001 /* address initialized */
-#define RES_DEBUG 0x00000002 /* print debug messages */
-#define RES_AAONLY 0x00000004 /* authoritative answers only (!IMPL)*/
-#define RES_USEVC 0x00000008 /* use virtual circuit */
-#define RES_PRIMARY 0x00000010 /* query primary server only (!IMPL) */
-#define RES_IGNTC 0x00000020 /* ignore trucation errors */
-#define RES_RECURSE 0x00000040 /* recursion desired */
-#define RES_DEFNAMES 0x00000080 /* use default domain name */
-#define RES_STAYOPEN 0x00000100 /* Keep TCP socket open */
-#define RES_DNSRCH 0x00000200 /* search up local domain tree */
-#define RES_INSECURE1 0x00000400 /* type 1 security disabled */
-#define RES_INSECURE2 0x00000800 /* type 2 security disabled */
-#define RES_NOALIASES 0x00001000 /* shuts off HOSTALIASES feature */
-#define RES_USE_INET6 0x00002000 /* use/map IPv6 in gethostbyname() */
-#define RES_ROTATE 0x00004000 /* rotate ns list after each query */
-#define RES_NOCHECKNAME 0x00008000 /* do not check names for sanity. */
-#define RES_KEEPTSIG 0x00010000 /* do not strip TSIG records */
-
-#define RES_DEFAULT (RES_RECURSE | RES_DEFNAMES | RES_DNSRCH)
-
-/*
- * Resolver "pfcode" values. Used by dig.
- */
-#define RES_PRF_STATS 0x00000001
-#define RES_PRF_UPDATE 0x00000002
-#define RES_PRF_CLASS 0x00000004
-#define RES_PRF_CMD 0x00000008
-#define RES_PRF_QUES 0x00000010
-#define RES_PRF_ANS 0x00000020
-#define RES_PRF_AUTH 0x00000040
-#define RES_PRF_ADD 0x00000080
-#define RES_PRF_HEAD1 0x00000100
-#define RES_PRF_HEAD2 0x00000200
-#define RES_PRF_TTLID 0x00000400
-#define RES_PRF_HEADX 0x00000800
-#define RES_PRF_QUERY 0x00001000
-#define RES_PRF_REPLY 0x00002000
-#define RES_PRF_INIT 0x00004000
-/* 0x00008000 */
-
-#if 0
-/* Things involving an internal (static) resolver context. */
-#ifdef _REENTRANT
-extern struct __res_state *__res_state(void);
-#define _res (*__res_state())
-#else
-#ifndef __BIND_NOSTATIC
-extern struct __res_state _res;
-#endif
-#endif
-
-void fp_nquery (const u_char *, int, FILE *);
-void fp_query (const u_char *, FILE *);
-const char * hostalias (const char *);
-void p_query (const u_char *);
-void res_close (void);
-int res_init (void);
-int res_isourserver (const struct sockaddr_in *);
-int res_mkquery (int, const char *, int, int, const u_char *,
- int, const u_char *, u_char *, int);
-int res_query (const char *, int, int, u_char *, int);
-int res_querydomain (const char *, const char *, int, int,
- u_char *, int);
-int res_search (const char *, int, int, u_char *, int);
-int res_send (const u_char *, int, u_char *, int);
-int res_sendsigned (const u_char *, int, ns_tsig_key *,
- u_char *, int);
-
-#if !defined(SHARED_LIBBIND) || defined(LIB)
-/*
- * If libbind is a shared object (well, DLL anyway)
- * these externs break the linker when resolv.h is
- * included by a lib client (like named)
- * Make them go away if a client is including this
- *
- */
-extern const struct res_sym __p_key_syms[];
-extern const struct res_sym __p_cert_syms[];
-extern const struct res_sym __p_class_syms[];
-extern const struct res_sym __p_type_syms[];
-extern const struct res_sym __p_rcode_syms[];
-#endif /* SHARED_LIBBIND */
-
-int res_hnok (const char *);
-int res_ownok (const char *);
-int res_mailok (const char *);
-int res_dnok (const char *);
-int sym_ston (const struct res_sym *, const char *, int *);
-const char * sym_ntos (const struct res_sym *, int, int *);
-const char * sym_ntop (const struct res_sym *, int, int *);
-int b64_ntop (u_char const *, size_t, char *, size_t);
-int b64_pton (char const *, u_char *, size_t);
-int loc_aton (const char *ascii, u_char *binary);
-const char * loc_ntoa (const u_char *binary, char *ascii);
-int dn_skipname (const u_char *, const u_char *);
-void putlong (u_int32_t, u_char *);
-void putshort (u_int16_t, u_char *);
-const char * p_class (int);
-const char * p_time (u_int32_t);
-const char * p_type (int);
-const char * p_rcode (int);
-const u_char * p_cdnname (const u_char *, const u_char *, int, FILE *);
-const u_char * p_cdname (const u_char *, const u_char *, FILE *);
-const u_char * p_fqnname (const u_char *cp, const u_char *msg,
- int, char *, int);
-const u_char * p_fqname (const u_char *, const u_char *, FILE *);
-const char * p_option (u_long option);
-char * p_secstodate (u_long);
-int dn_count_labels (const char *);
-int dn_expand (const u_char *, const u_char *, const u_char *,
- char *, int);
-u_int res_randomid (void);
-int res_nameinquery (const char *, int, int,
- const u_char *, const u_char *);
-int res_queriesmatch (const u_char *, const u_char *,
- const u_char *, const u_char *);
-const char * p_section (int section, int opcode);
-/* Things involving a resolver context. */
-int res_ninit (res_state);
-int res_nisourserver (const res_state,
- const struct sockaddr_in *);
-void fp_resstat (const res_state, FILE *);
-void res_npquery (const res_state, const u_char *, int, FILE *);
-const char * res_hostalias (const res_state, const char *,
- char *, size_t);
-int res_nquery (res_state,
- const char *, int, int, u_char *, int);
-int res_nsearch (res_state, const char *, int,
- int, u_char *, int);
-int res_nquerydomain (res_state,
- const char *, const char *, int, int,
- u_char *, int);
-int res_nmkquery (res_state,
- int, const char *, int, int, const u_char *,
- int, const u_char *, u_char *, int);
-int res_nsend (res_state, const u_char *, int, u_char *, int);
-int res_nsendsigned (res_state, const u_char *, int,
- ns_tsig_key *, u_char *, int);
-int res_findzonecut (res_state, const char *, ns_class, int,
- char *, size_t, struct in_addr *, int);
-void res_nclose (res_state);
-
-#endif /* 0 */
-#endif /* !_RESOLV_H_ */
--- /dev/null
+/* isclib.h
+
+ connections to the isc and dns libraries */
+
+/*
+ * Copyright (c) 2009 by Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and 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 ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC 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.
+ *
+ * Internet Systems Consortium, Inc.
+ * 950 Charter Street
+ * Redwood City, CA 94063
+ * <info@isc.org>
+ * http://www.isc.org/
+ *
+ */
+
+#ifndef ISCLIB_H
+#define ISCLIB_H
+
+#include "config.h"
+
+#include <syslog.h>
+
+#define MAXWIRE 256
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+
+#include <arpa/inet.h>
+
+#include <unistd.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netdb.h>
+
+#include <isc/buffer.h>
+#include <isc/lex.h>
+#include <isc/lib.h>
+#include <isc/app.h>
+#include <isc/mem.h>
+#include <isc/parseint.h>
+#include <isc/socket.h>
+#include <isc/sockaddr.h>
+#include <isc/task.h>
+#include <isc/timer.h>
+#include <isc/heap.h>
+#include <isc/random.h>
+
+#include <dns/client.h>
+#include <dns/fixedname.h>
+#include <dns/keyvalues.h>
+#include <dns/lib.h>
+#include <dns/name.h>
+#include <dns/rdata.h>
+#include <dns/rdataclass.h>
+#include <dns/rdatalist.h>
+#include <dns/rdataset.h>
+#include <dns/rdatastruct.h>
+#include <dns/rdatatype.h>
+#include <dns/result.h>
+#include <dns/secalg.h>
+#include <dns/tsec.h>
+
+#include <dst/dst.h>
+
+#include "result.h"
+
+
+/*
+ * DHCP context structure
+ * This holds the libisc information for a dhcp entity
+ */
+
+typedef struct dhcp_context {
+ isc_mem_t *mctx;
+ isc_appctx_t *actx;
+ int actx_started;
+ isc_taskmgr_t *taskmgr;
+ isc_task_t *task;
+ isc_socketmgr_t *socketmgr;
+ isc_timermgr_t *timermgr;
+#if defined (NSUPDATE)
+ dns_client_t *dnsclient;
+#endif
+} dhcp_context_t;
+
+extern dhcp_context_t dhcp_gbl_ctx;
+
+#define DHCP_MAXDNS_WIRE 256
+#define DHCP_MAXNS 3
+#define DHCP_HMAC_MD5_NAME "HMAC-MD5.SIG-ALG.REG.INT."
+
+isc_result_t dhcp_isc_name(unsigned char *namestr,
+ dns_fixedname_t *namefix,
+ dns_name_t **name);
+
+isc_result_t
+isclib_make_dst_key(char *inname,
+ char *algorithm,
+ unsigned char *secret,
+ int length,
+ dst_key_t **dstkey);
+
+isc_result_t dhcp_context_create(void);
+void isclib_cleanup(void);
+
+#endif /* ISCLIB_H */
#ifndef _OMAPIP_H_
#define _OMAPIP_H_
-#include <isc-dhcp/result.h>
+#include "result.h"
#include <stdarg.h>
+#include <dns/tsec.h>
+
typedef unsigned int omapi_handle_t;
struct __omapi_object;
char *name;
char *algorithm;
omapi_data_string_t *key;
+ dns_tsec_t *tsec_key;
} omapi_auth_key_t;
#define OMAPI_CREATE 1
#include "osdep.h"
*/
-#include <isc-dhcp/dst.h>
-#include <isc-dhcp/result.h>
+#include <dst/dst.h>
+#include "result.h"
#include <omapip/convert.h>
#include <omapip/hash.h>
#include <omapip/omapip.h>
#include <omapip/trace.h>
+/* DST_API control flags */
+/* These are used in functions dst_sign_data and dst_verify_data */
+#define SIG_MODE_INIT 1 /* initalize digest */
+#define SIG_MODE_UPDATE 2 /* add data to digest */
+#define SIG_MODE_FINAL 4 /* generate/verify signature */
+#define SIG_MODE_ALL (SIG_MODE_INIT|SIG_MODE_UPDATE|SIG_MODE_FINAL)
+
/* OMAPI protocol header, version 1.00 */
typedef struct {
u_int32_t authlen; /* Length of authenticator. */
omapi_buffer_t *outbufs;
omapi_listener_object_t *listener; /* Listener that accepted this
connection, if any. */
- DST_KEY *in_key; /* Authenticator signing incoming
+ dst_key_t *in_key; /* Authenticator signing incoming
data. */
void *in_context; /* Input hash context. */
- DST_KEY *out_key; /* Authenticator signing outgoing
+ dst_key_t *out_key; /* Authenticator signing outgoing
data. */
void *out_context; /* Output hash context. */
} omapi_connection_object_t;
isc_result_t (*reader) (omapi_object_t *);
isc_result_t (*writer) (omapi_object_t *);
isc_result_t (*reaper) (omapi_object_t *);
+ isc_socket_t *fd;
} omapi_io_object_t;
typedef struct __omapi_generic_object {
omapi_message_object_t, omapi_type_message)
isc_result_t omapi_connection_sign_data (int mode,
- DST_KEY *key,
+ dst_key_t *key,
void **context,
const unsigned char *data,
const unsigned len,
--- /dev/null
+/* result.h
+ */
+
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * 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 ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC 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.
+ *
+ * Internet Systems Consortium, Inc.
+ * 950 Charter Street
+ * Redwood City, CA 94063
+ * <info@isc.org>
+ * https://www.isc.org/
+ */
+
+#ifndef DHCP_RESULT_H
+#define DHCP_RESULT_H 1
+
+#include <isc/lang.h>
+#include <isc/resultclass.h>
+#include <isc/types.h>
+
+#include <isc/result.h>
+
+/*
+ * DHCP result codes
+ */
+
+/*
+ * In the previous code the results started at 36
+ * rather than ISC_RESULTCLASS_DHCP + 0
+ * ISC_R_NOTCONNECTED was + 4 (40), it has been superseded by the isc version
+ */
+
+#define DHCP_R_HOSTUNKNOWN (ISC_RESULTCLASS_DHCP + 0)
+#define DHCP_R_VERSIONMISMATCH (ISC_RESULTCLASS_DHCP + 1)
+#define DHCP_R_PROTOCOLERROR (ISC_RESULTCLASS_DHCP + 2)
+#define DHCP_R_INVALIDARG (ISC_RESULTCLASS_DHCP + 3)
+#define DHCP_R_NOTYET (ISC_RESULTCLASS_DHCP + 4)
+#define DHCP_R_UNCHANGED (ISC_RESULTCLASS_DHCP + 5)
+#define DHCP_R_MULTIPLE (ISC_RESULTCLASS_DHCP + 6)
+#define DHCP_R_KEYCONFLICT (ISC_RESULTCLASS_DHCP + 7)
+#define DHCP_R_BADPARSE (ISC_RESULTCLASS_DHCP + 8)
+#define DHCP_R_NOKEYS (ISC_RESULTCLASS_DHCP + 9)
+#define DHCP_R_KEY_UNKNOWN (ISC_RESULTCLASS_DHCP + 10)
+#define DHCP_R_INVALIDKEY (ISC_RESULTCLASS_DHCP + 11)
+#define DHCP_R_INCOMPLETE (ISC_RESULTCLASS_DHCP + 12)
+#define DHCP_R_FORMERR (ISC_RESULTCLASS_DHCP + 13)
+#define DHCP_R_SERVFAIL (ISC_RESULTCLASS_DHCP + 14)
+#define DHCP_R_NXDOMAIN (ISC_RESULTCLASS_DHCP + 15)
+#define DHCP_R_NOTIMPL (ISC_RESULTCLASS_DHCP + 16)
+#define DHCP_R_REFUSED (ISC_RESULTCLASS_DHCP + 17)
+#define DHCP_R_YXDOMAIN (ISC_RESULTCLASS_DHCP + 18)
+#define DHCP_R_YXRRSET (ISC_RESULTCLASS_DHCP + 19)
+#define DHCP_R_NXRRSET (ISC_RESULTCLASS_DHCP + 20)
+#define DHCP_R_NOTAUTH (ISC_RESULTCLASS_DHCP + 21)
+#define DHCP_R_NOTZONE (ISC_RESULTCLASS_DHCP + 22)
+#define DHCP_R_BADSIG (ISC_RESULTCLASS_DHCP + 23)
+#define DHCP_R_BADKEY (ISC_RESULTCLASS_DHCP + 24)
+#define DHCP_R_BADTIME (ISC_RESULTCLASS_DHCP + 25)
+#define DHCP_R_NOROOTZONE (ISC_RESULTCLASS_DHCP + 26)
+#define DHCP_R_DESTADDRREQ (ISC_RESULTCLASS_DHCP + 27)
+#define DHCP_R_CROSSZONE (ISC_RESULTCLASS_DHCP + 28)
+#define DHCP_R_NO_TSIG (ISC_RESULTCLASS_DHCP + 29)
+#define DHCP_R_NOT_EQUAL (ISC_RESULTCLASS_DHCP + 30)
+#define DHCP_R_CONNRESET (ISC_RESULTCLASS_DHCP + 31)
+#define DHCP_R_UNKNOWNATTRIBUTE (ISC_RESULTCLASS_DHCP + 32)
+
+#define DHCP_R_NRESULTS 33 /*%< Number of results */
+
+// Included for historical reasons, these should be removed as
+// soon as reasonable
+#define ISC_R_HOSTUNKNOWN DHCP_R_HOSTUNKNOWN
+#define ISC_R_VERSIONMISMATCH DHCP_R_VERSIONMISMATCH
+#define ISC_R_PROTOCOLERROR DHCP_R_PROTOCOLERROR
+#define ISC_R_INVALIDARG DHCP_R_INVALIDARG
+#define ISC_R_NOTYET DHCP_R_NOTYET
+#define ISC_R_UNCHANGED DHCP_R_UNCHANGED
+#define ISC_R_MULTIPLE DHCP_R_MULTIPLE
+#define ISC_R_KEYCONFLICT DHCP_R_KEYCONFLICT
+#define ISC_R_BADPARSE DHCP_R_BADPARSE
+#define ISC_R_NOKEYS DHCP_R_NOKEYS
+#define ISC_R_KEY_UNKNOWN DHCP_R_KEY_UNKNOWN
+#define ISC_R_INVALIDKEY DHCP_R_INVALIDKEY
+#define ISC_R_INCOMPLETE DHCP_R_INCOMPLETE
+#define ISC_R_FORMERR DHCP_R_FORMERR
+#define ISC_R_SERVFAIL DHCP_R_SERVFAIL
+#define ISC_R_NXDOMAIN DHCP_R_NXDOMAIN
+#define ISC_R_NOTIMPL DHCP_R_NOTIMPL
+#define ISC_R_REFUSED DHCP_R_REFUSED
+#define ISC_R_YXDOMAIN DHCP_R_YXDOMAIN
+#define ISC_R_YXRRSET DHCP_R_YXRRSET
+#define ISC_R_NXRRSET DHCP_R_NXRRSET
+#define ISC_R_NOTAUTH DHCP_R_NOTAUTH
+#define ISC_R_NOTZONE DHCP_R_NOTZONE
+#define ISC_R_BADSIG DHCP_R_BADSIG
+#define ISC_R_BADKEY DHCP_R_BADKEY
+#define ISC_R_BADTIME DHCP_R_BADTIME
+#define ISC_R_NOROOTZONE DHCP_R_NOROOTZONE
+#define ISC_R_DESTADDRREQ DHCP_R_DESTADDRREQ
+#define ISC_R_CROSSZONE DHCP_R_CROSSZONE
+#define ISC_R_NO_TSIG DHCP_R_NO_TSIG
+#define ISC_R_NOT_EQUAL DHCP_R_NOT_EQUAL
+#define ISC_R_CONNRESET DHCP_R_CONNRESET
+#define ISC_R_UNKNOWNATTRIBUTE DHCP_R_UNKNOWNATTRIBUTE
+
+isc_result_t
+dhcp_result_register(void);
+
+#endif /* DHCP_RESULT_H */
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: t_api.h,v 1.2 2007/11/16 11:04:11 shane Exp $ */
+/* $Id: t_api.h,v 1.3 2009/10/28 04:12:30 sar Exp $ */
#ifndef TESTS_T_API_H
#define TESTS_T_API_H 1
#include <stdio.h>
-#include <isc-dhcp/lang.h>
-#include <isc-dhcp/result.h>
-#include <isc-dhcp/formatcheck.h>
+#include <omapip/result.h>
+#include <isc/lang.h>
+#include <isc/formatcheck.h>
/*
*
struct data_string data;
unsigned long intval;
int boolean;
-#if defined (NSUPDATE)
+#if defined (NSUPDATE_OLD)
ns_updrec *dns;
#endif
struct fundef *fundef;
libomapi_a_SOURCES = protocol.c buffer.c alloc.c result.c connection.c \
errwarn.c listener.c dispatch.c generic.c support.c \
handle.c message.c convert.c hash.c auth.c inet_addr.c \
- array.c trace.c mrtrace.c toisc.c iscprint.c
+ array.c trace.c mrtrace.c toisc.c iscprint.c isclib.c
+
man_MANS = omapi.3
EXTRA_DIST = $(man_MANS)
svtest_SOURCES = test.c
-svtest_LDADD = libomapi.a ../dst/libdst.a
+svtest_LDADD = libomapi.a ../bind/lib/libdns.a ../bind/lib/libisc.a
/* Sanity check. */
if (tsize < sizeof (omapi_object_t))
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
foo = dmalloc (tsize, file, line);
if (!foo)
const char *file, int line)
{
if (!h || !r)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (*r) {
#if defined (POINTER_DEBUG)
file, line);
abort ();
#else
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
#endif
}
*r = h;
omapi_object_t *p, *hp;
if (!h)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (!*h) {
#if defined (POINTER_DEBUG)
log_error ("%s(%d): dereference of null pointer!", file, line);
abort ();
#else
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
#endif
}
abort ();
#else
*h = 0;
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
#endif
}
const char *file, int line)
{
if (!h || !r)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (*r) {
#if defined (POINTER_DEBUG)
file, line);
abort ();
#else
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
#endif
}
*r = h;
const char *file, int line)
{
if (!h)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (!*h) {
#if defined (POINTER_DEBUG)
log_error ("%s(%d): dereference of null pointer!", file, line);
abort ();
#else
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
#endif
}
abort ();
#else
*h = 0;
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
#endif
}
len = OMAPI_TYPED_DATA_NOBUFFER_LEN + val;
if (len < val) {
va_end(l);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
break;
case omapi_datatype_data:
len = OMAPI_TYPED_DATA_NOBUFFER_LEN + val;
if (len < val) {
va_end(l);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
break;
case omapi_datatype_object:
break;
default:
va_end (l);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
va_end (l);
const char *file, int line)
{
if (!h || !r)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (*r) {
#if defined (POINTER_DEBUG)
log_error ("%s(%d): reference store into non-null pointer!", file, line);
abort ();
#else
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
#endif
}
*r = h;
const char *file, int line)
{
if (!h)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (!*h) {
#if defined (POINTER_DEBUG)
log_error ("%s(%d): dereference of null pointer!", file, line);
abort ();
#else
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
#endif
}
abort ();
#else
*h = 0;
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
#endif
}
nlen = OMAPI_DATA_STRING_EMPTY_SIZE + len;
if (nlen < len)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
new = dmalloc (nlen, file, line);
if (!new)
return ISC_R_NOMEMORY;
const char *file, int line)
{
if (!h || !r)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (*r) {
#if defined (POINTER_DEBUG)
log_error ("%s(%d): reference store into non-null pointer!", file, line);
abort ();
#else
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
#endif
}
*r = h;
const char *file, int line)
{
if (!h)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (!*h) {
#if defined (POINTER_DEBUG)
log_error ("%s(%d): dereference of null pointer!", file, line);
abort ();
#else
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
#endif
}
abort ();
#else
*h = 0;
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
#endif
}
const char *file, int line)
{
if (!h || !r)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (*r) {
#if defined (POINTER_DEBUG)
file, line);
abort ();
#else
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
#endif
}
*r = h;
const char *file, int line)
{
if (!h)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (!*h) {
#if defined (POINTER_DEBUG)
log_error ("%s(%d): dereference of null pointer!", file, line);
abort ();
#else
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
#endif
}
abort ();
#else
*h = 0;
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
#endif
}
const char *file, int line)
{
if (!h || !r)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (*r) {
#if defined (POINTER_DEBUG)
file, line);
abort ();
#else
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
#endif
}
*r = h;
const char *file, int line)
{
if (!h)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (!*h) {
#if defined (POINTER_DEBUG)
log_error ("%s(%d): dereference of null pointer!", file, line);
abort ();
#else
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
#endif
}
abort ();
#else
*h = 0;
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
#endif
}
omapi_array_t *aptr;
if (!array || *array)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
aptr = dmalloc (sizeof (omapi_array_t),file, line);
if (!aptr)
return ISC_R_NOMEMORY;
int i;
if (!array || !*array)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
aptr = *array;
for (i = 0; i < aptr -> count; i++)
if (aptr -> data [i] && aptr -> deref)
isc_result_t status;
if (!array)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (!ptr)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (index < 0)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
/* If the proposed index is larger than the current available
space in the array, make more space in the array. */
const char *file, int line)
{
if (!array || !ptr || *ptr || index < 0 || index >= array -> count)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (array -> data [index])
return (*array -> ref) (ptr,
array -> data [index], file, line);
{
omapi_auth_key_t *a;
- if (h -> type != omapi_type_auth_key)
- return ISC_R_INVALIDARG;
+ if (h->type != omapi_type_auth_key)
+ return DHCP_R_INVALIDARG;
a = (omapi_auth_key_t *)h;
- if (auth_key_hash)
- omapi_auth_key_hash_delete (auth_key_hash, a -> name, 0, MDL);
-
- if (a -> name)
- dfree (a -> name, MDL);
- if (a -> algorithm)
- dfree (a -> algorithm, MDL);
- if (a -> key)
- omapi_data_string_dereference (&a -> key, MDL);
+ if (auth_key_hash != NULL)
+ omapi_auth_key_hash_delete(auth_key_hash, a->name, 0, MDL);
+
+ if (a->name != NULL)
+ dfree(a->name, MDL);
+ if (a->algorithm != NULL)
+ dfree(a->algorithm, MDL);
+ if (a->key != NULL)
+ omapi_data_string_dereference(&a->key, MDL);
+ if (a->tsec_key != NULL)
+ dns_tsec_destroy(&a->tsec_key);
return ISC_R_SUCCESS;
}
isc_result_t omapi_auth_key_enter (omapi_auth_key_t *a)
{
omapi_auth_key_t *tk;
+ isc_result_t status;
+ dst_key_t *dstkey;
if (a -> type != omapi_type_auth_key)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
tk = (omapi_auth_key_t *)0;
if (auth_key_hash) {
KEY_HASH_SIZE, MDL))
return ISC_R_NOMEMORY;
}
+
+ /*
+ * If possible create a tsec structure for this key,
+ * if we can't create the structure we put out a warning
+ * and continue.
+ */
+ status = isclib_make_dst_key(a->name, a->algorithm,
+ a->key->value, a->key->len,
+ &dstkey);
+ if (status == ISC_R_SUCCESS) {
+ status = dns_tsec_create(dhcp_gbl_ctx.mctx, dns_tsectype_tsig,
+ dstkey, &a->tsec_key);
+ }
+ if (status != ISC_R_SUCCESS) {
+ if (dstkey != NULL) {
+ dst_key_free(&dstkey);
+ }
+ log_error("Unable to create tsec structure for %s", a->name);
+ }
+
omapi_auth_key_hash_add (auth_key_hash, a -> name, 0, a, MDL);
return ISC_R_SUCCESS;
-
}
isc_result_t omapi_auth_key_lookup_name (omapi_auth_key_t **a,
return ISC_R_NOTFOUND;
if (!ref)
- return ISC_R_NOKEYS;
+ return DHCP_R_NOKEYS;
status = omapi_get_value_str (ref, id, "name", &name);
if (status != ISC_R_SUCCESS)
isc_result_t status;
if (h -> type != omapi_type_auth_key)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
a = (omapi_auth_key_t *)h;
/* Write only the name and algorithm -- not the secret! */
unsigned bytes_to_read;
if (!h || h -> type != omapi_type_connection)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
c = (omapi_connection_object_t *)h;
/* See if there are enough bytes. */
else if (errno == EIO)
return ISC_R_IOERROR;
else if (errno == EINVAL)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
else if (errno == ECONNRESET) {
omapi_disconnect (h, 1);
return ISC_R_SHUTTINGDOWN;
/* Make sure len is valid. */
if (len < 0)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (!h || h -> type != omapi_type_connection)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
c = (omapi_connection_object_t *)h;
/* If the connection is closed, return an error if the caller
} else {
status = omapi_buffer_new (&c -> outbufs, MDL);
if (status != ISC_R_SUCCESS)
- return status;
+ goto leave;
buffer = c -> outbufs;
}
if (!BUFFER_BYTES_FREE (buffer)) {
status = (omapi_buffer_new (&buffer -> next, MDL));
if (status != ISC_R_SUCCESS)
- return status;
+ goto leave;
buffer = buffer -> next;
}
&bufp [bytes_copied], copy_len,
(omapi_typed_data_t **)0);
if (status != ISC_R_SUCCESS)
- return status;
+ goto leave;
}
memcpy (&buffer -> buf [buffer -> tail],
if (buffer -> tail == sizeof buffer -> buf)
buffer -> tail = 0;
}
- return ISC_R_SUCCESS;
+
+ status = ISC_R_SUCCESS;
+
+ leave:
+ /*
+ * If we have any bytes to send and we have a proper io object
+ * inform the socket code that we would like to know when we
+ * can send more bytes.
+ */
+ if (c->out_bytes != 0) {
+ if ((c->outer != NULL) &&
+ (c->outer->type == omapi_type_io_object)) {
+ omapi_io_object_t *io = (omapi_io_object_t *)c->outer;
+ isc_socket_fdwatchpoke(io->fd,
+ ISC_SOCKFDWATCH_WRITE);
+ }
+ }
+
+ return (status);
}
/* Copy some bytes from the input buffer, and advance the input buffer
isc_result_t status;
if (!h || h -> type != omapi_type_connection)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
c = (omapi_connection_object_t *)h;
if (size > c -> in_bytes)
omapi_connection_object_t *c;
if (!h || h -> type != omapi_type_connection)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
c = (omapi_connection_object_t *)h;
/* Already flushed... */
are really errors. */
if (bytes_written < 0) {
if (errno == EWOULDBLOCK || errno == EAGAIN)
- return ISC_R_SUCCESS;
+ return ISC_R_INPROGRESS;
else if (errno == EPIPE)
return ISC_R_NOCONN;
#ifdef EDQUOT
else if (errno == EIO)
return ISC_R_IOERROR;
else if (errno == EINVAL)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
else if (errno == ECONNRESET)
return ISC_R_SHUTTINGDOWN;
else
return ISC_R_UNEXPECTED;
}
if (bytes_written == 0)
- return ISC_R_SUCCESS;
+ return ISC_R_INPROGRESS;
#if defined (TRACING)
if (trace_record ()) {
O.S. output buffer and a further write would block,
so stop trying to flush now. */
if (bytes_written != bytes_this_write)
- return ISC_R_SUCCESS;
+ return ISC_R_INPROGRESS;
}
if (!BYTES_IN_BUFFER (buffer))
return omapi_connection_put_uint32 (c, handle);
}
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
isc_result_t omapi_connection_put_name (omapi_object_t *c, const char *name)
#include <arpa/nameser.h>
#include <errno.h>
-
#if defined (TRACING)
static void trace_connect_input (trace_type_t *, unsigned, char *);
static void trace_connect_stop (trace_type_t *);
name. It's okay for this call to block. */
he = gethostbyname (server_name);
if (!he)
- return ISC_R_HOSTUNKNOWN;
+ return DHCP_R_HOSTUNKNOWN;
for (i = 0; he -> h_addr_list [i]; i++)
;
if (i == 0)
- return ISC_R_HOSTUNKNOWN;
+ return DHCP_R_HOSTUNKNOWN;
hix = i;
status = omapi_addr_list_new (&addrs, hix, MDL);
/* Only do TCPv4 so far. */
if (local_addr -> addrtype != AF_INET) {
omapi_connection_dereference (&obj, MDL);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
local_sin.sin_port = htons (local_addr -> port);
memcpy (&local_sin.sin_addr,
c = (omapi_connection_object_t *)h;
if (c -> type != omapi_type_connection)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
#if defined (TRACING)
if (trace_record ()) {
#endif
c -> state = omapi_connection_closed;
+#if 0
+ /*
+ * Disconnecting from the I/O object seems incorrect as it doesn't
+ * cause the I/O object to be cleaned and released. Previous to
+ * using the isc socket library this wouldn't have caused a problem
+ * with the socket library we would have a reference to a closed
+ * socket. Instead we now do an unregister to properly free the
+ * I/O object.
+ */
+
/* Disconnect from I/O object, if any. */
if (h -> outer) {
if (h -> outer -> inner)
omapi_object_dereference (&h -> outer -> inner, MDL);
omapi_object_dereference (&h -> outer, MDL);
}
+#else
+ if (h->outer) {
+ omapi_unregister_io_object(h);
+ }
+#endif
/* If whatever created us registered a signal handler, send it
a disconnect signal. */
omapi_connection_object_t *c;
if (h -> type != omapi_type_connection)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
c = (omapi_connection_object_t *)h;
c -> bytes_needed = bytes;
if (c -> bytes_needed <= c -> in_bytes) {
return ISC_R_SUCCESS;
}
- return ISC_R_NOTYET;
+ return DHCP_R_NOTYET;
}
/* Return the socket on which the dispatcher should wait for readiness
- to read, for a connection object. If we already have more bytes than
- we need to do the next thing, and we have at least a single full input
- buffer, then don't indicate that we're ready to read. */
+ to read, for a connection object. */
int omapi_connection_readfd (omapi_object_t *h)
{
omapi_connection_object_t *c;
c = (omapi_connection_object_t *)h;
if (c -> state != omapi_connection_connected)
return -1;
- if (c -> in_bytes >= OMAPI_BUF_SIZE - 1 &&
- c -> in_bytes > c -> bytes_needed)
- return -1;
return c -> socket;
}
-/* Return the socket on which the dispatcher should wait for readiness
- to write, for a connection object. If there are no bytes buffered
- for writing, then don't indicate that we're ready to write. */
+/*
+ * Return the socket on which the dispatcher should wait for readiness
+ * to write, for a connection object. When bytes are buffered we should
+ * also poke the dispatcher to tell it to start or re-start watching the
+ * socket.
+ */
int omapi_connection_writefd (omapi_object_t *h)
{
omapi_connection_object_t *c;
if (h -> type != omapi_type_connection)
return -1;
c = (omapi_connection_object_t *)h;
- if (c -> state == omapi_connection_connecting)
- return c -> socket;
- if (c -> out_bytes)
- return c -> socket;
- else
- return -1;
+ return c->socket;
}
isc_result_t omapi_connection_connect (omapi_object_t *h)
isc_result_t status;
if (h -> type != omapi_type_connection)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
c = (omapi_connection_object_t *)h;
if (c -> state == omapi_connection_connecting) {
if (c -> connect_list -> addresses [c -> cptr].addrtype !=
AF_INET) {
omapi_disconnect (h, 1);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
memcpy (&c -> remote_addr.sin_addr,
return status;
}
c -> state = omapi_connection_connecting;
- return ISC_R_INCOMPLETE;
+ return DHCP_R_INCOMPLETE;
}
c -> state = omapi_connection_connected;
}
omapi_connection_object_t *c;
if (h -> type != omapi_type_connection)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
c = (omapi_connection_object_t *)h;
if (c -> state == omapi_connection_disconnecting &&
return ISC_R_SUCCESS;
}
-static isc_result_t make_dst_key (DST_KEY **dst_key, omapi_object_t *a) {
+static isc_result_t make_dst_key (dst_key_t **dst_key, omapi_object_t *a) {
omapi_value_t *name = (omapi_value_t *)0;
omapi_value_t *algorithm = (omapi_value_t *)0;
omapi_value_t *key = (omapi_value_t *)0;
- int algorithm_id = UNKNOWN_KEYALG;
char *name_str = NULL;
isc_result_t status = ISC_R_SUCCESS;
(a, (omapi_object_t *)0, "key", &key);
if (status == ISC_R_SUCCESS) {
- if ((algorithm -> value -> type == omapi_datatype_data ||
- algorithm -> value -> type == omapi_datatype_string) &&
- strncasecmp ((char *)algorithm -> value -> u.buffer.value,
- NS_TSIG_ALG_HMAC_MD5 ".",
- algorithm -> value -> u.buffer.len) == 0) {
- algorithm_id = KEY_HMAC_MD5;
- } else {
- status = ISC_R_INVALIDARG;
+ if ((algorithm->value->type != omapi_datatype_data &&
+ algorithm->value->type != omapi_datatype_string) ||
+ strncasecmp((char *)algorithm->value->u.buffer.value,
+ NS_TSIG_ALG_HMAC_MD5 ".",
+ algorithm->value->u.buffer.len) != 0) {
+ status = DHCP_R_INVALIDARG;
}
}
name -> value -> u.buffer.len);
name_str [name -> value -> u.buffer.len] = 0;
- *dst_key = dst_buffer_to_key (name_str, algorithm_id, 0, 0,
- key -> value -> u.buffer.value,
- key -> value -> u.buffer.len);
- if (!*dst_key)
+ status = isclib_make_dst_key(name_str,
+ DHCP_HMAC_MD5_NAME,
+ key->value->u.buffer.value,
+ key->value->u.buffer.len,
+ dst_key);
+
+ if (*dst_key == NULL)
status = ISC_R_NOMEMORY;
}
}
isc_result_t omapi_connection_sign_data (int mode,
- DST_KEY *key,
+ dst_key_t *key,
void **context,
const unsigned char *data,
const unsigned len,
{
omapi_typed_data_t *td = (omapi_typed_data_t *)0;
isc_result_t status;
- int r;
+ dst_context_t **dctx = (dst_context_t **)context;
+ /* Create the context for the dst module */
+ if (mode & SIG_MODE_INIT) {
+ status = dst_context_create(key, dhcp_gbl_ctx.mctx, dctx);
+ if (status != ISC_R_SUCCESS) {
+ return status;
+ }
+ }
+
+ /* If we have any data add it to the context */
+ if (len != 0) {
+ isc_region_t region;
+ region.base = (unsigned char *)data;
+ region.length = len;
+ dst_context_adddata(*dctx, ®ion);
+ }
+
+ /* Finish the signature and clean up the context */
if (mode & SIG_MODE_FINAL) {
+ unsigned int sigsize;
+ isc_buffer_t sigbuf;
+
+ status = dst_key_sigsize(key, &sigsize);
+ if (status != ISC_R_SUCCESS) {
+ goto cleanup;
+ }
+
status = omapi_typed_data_new (MDL, &td,
omapi_datatype_data,
- dst_sig_size (key));
- if (status != ISC_R_SUCCESS)
- return status;
- }
+ sigsize);
+ if (status != ISC_R_SUCCESS) {
+ goto cleanup;
+ }
- r = dst_sign_data (mode, key, context, data, len,
- td ? td -> u.buffer.value : (u_char *)0,
- td ? td -> u.buffer.len : 0);
+ isc_buffer_init(&sigbuf, td->u.buffer.value, td->u.buffer.len);
+ status = dst_context_sign(*dctx, &sigbuf);
+ if (status != ISC_R_SUCCESS) {
+ goto cleanup;
+ }
- /* dst_sign_data() really should do this for us, shouldn't it? */
- if (mode & SIG_MODE_FINAL)
- *context = (void *)0;
+ if (result) {
+ omapi_typed_data_reference (result, td, MDL);
+ }
- if (r < 0) {
- if (td)
+ cleanup:
+ /* We are done with the context and the td. On success
+ * the td is now referenced from result, on failure we
+ * don't need it any more */
+ if (td) {
omapi_typed_data_dereference (&td, MDL);
- return ISC_R_INVALIDKEY;
- }
-
- if (result && td) {
- omapi_typed_data_reference (result, td, MDL);
+ }
+ dst_context_destroy(dctx);
+ return status;
}
- if (td)
- omapi_typed_data_dereference (&td, MDL);
-
return ISC_R_SUCCESS;
}
{
omapi_connection_object_t *c;
- if (h -> type != omapi_type_connection)
- return ISC_R_INVALIDARG;
+ if (h->type != omapi_type_connection)
+ return DHCP_R_INVALIDARG;
c = (omapi_connection_object_t *)h;
- if (!c -> out_key)
+ if (c->out_key == NULL)
return ISC_R_NOTFOUND;
- *l = dst_sig_size (c -> out_key);
- return ISC_R_SUCCESS;
+ return(dst_key_sigsize(c->out_key, l));
}
isc_result_t omapi_connection_set_value (omapi_object_t *h,
isc_result_t status;
if (h -> type != omapi_type_connection)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
c = (omapi_connection_object_t *)h;
if (omapi_ds_strcmp (name, "input-authenticator") == 0) {
if (value && value -> type != omapi_datatype_object)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (c -> in_context) {
omapi_connection_sign_data (SIG_MODE_FINAL,
(omapi_typed_data_t **) 0);
}
- if (c -> in_key) {
- dst_free_key (c -> in_key);
- c -> in_key = (DST_KEY *)0;
+ if (c->in_key != NULL) {
+ dst_key_free(&c->in_key);
}
if (value) {
}
else if (omapi_ds_strcmp (name, "output-authenticator") == 0) {
if (value && value -> type != omapi_datatype_object)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (c -> out_context) {
omapi_connection_sign_data (SIG_MODE_FINAL,
(omapi_typed_data_t **) 0);
}
- if (c -> out_key) {
- dst_free_key (c -> out_key);
- c -> out_key = (DST_KEY *)0;
+ if (c->out_key != NULL) {
+ dst_key_free(&c->out_key);
}
if (value) {
omapi_connection_object_t *c;
omapi_typed_data_t *td = (omapi_typed_data_t *)0;
isc_result_t status;
+ unsigned int sigsize;
if (h -> type != omapi_type_connection)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
c = (omapi_connection_object_t *)h;
if (omapi_ds_strcmp (name, "input-signature") == 0) {
return status;
} else if (omapi_ds_strcmp (name, "input-signature-size") == 0) {
- if (!c -> in_key)
+ if (c->in_key == NULL)
return ISC_R_NOTFOUND;
- return omapi_make_int_value (value, name,
- dst_sig_size (c -> in_key), MDL);
+ status = dst_key_sigsize(c->in_key, &sigsize);
+ if (status != ISC_R_SUCCESS) {
+ return(status);
+ }
+
+ return omapi_make_int_value(value, name, sigsize, MDL);
} else if (omapi_ds_strcmp (name, "output-signature") == 0) {
if (!c -> out_key || !c -> out_context)
return status;
} else if (omapi_ds_strcmp (name, "output-signature-size") == 0) {
- if (!c -> out_key)
+ if (c->out_key == NULL)
return ISC_R_NOTFOUND;
- return omapi_make_int_value (value, name,
- dst_sig_size (c -> out_key), MDL);
+
+ status = dst_key_sigsize(c->out_key, &sigsize);
+ if (status != ISC_R_SUCCESS) {
+ return(status);
+ }
+
+ return omapi_make_int_value(value, name, sigsize, MDL);
}
if (h -> inner && h -> inner -> type -> get_value)
const char *name, va_list ap)
{
if (h -> type != omapi_type_connection)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
#ifdef DEBUG_PROTOCOL
log_debug ("omapi_connection_signal_handler(%s)", name);
omapi_object_t *m)
{
if (m -> type != omapi_type_connection)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (m -> inner && m -> inner -> type -> stuff_values)
return (*(m -> inner -> type -> stuff_values)) (c, id,
}
}
+/*
+ * Callback routine to connect the omapi I/O object and socket with
+ * the isc socket code. The isc socket code will call this routine
+ * which will then call the correct local routine to process the bytes.
+ *
+ * Currently we are always willing to read more data, this should be modified
+ * so that on connections we don't read more if we already have enough.
+ *
+ * If we have more bytes to write we ask the library to call us when
+ * we can write more. If we indicate we don't have more to write we need
+ * to poke the library via isc_socket_fdwatchpoke.
+ */
+int
+omapi_iscsock_cb(isc_task_t *task,
+ isc_socket_t *socket,
+ void *cbarg,
+ int flags)
+{
+ omapi_io_object_t *obj;
+ isc_result_t status;
+
+ /* Get the current time... */
+ gettimeofday (&cur_tv, (struct timezone *)0);
+
+ /* Not much to be done if we have the wrong type of object. */
+ if (((omapi_object_t *)cbarg) -> type != omapi_type_io_object) {
+ log_fatal ("Incorrect object type, must be of type io_object");
+ }
+ obj = (omapi_io_object_t *)cbarg;
+
+ if ((flags == ISC_SOCKFDWATCH_READ) &&
+ (obj->reader != NULL) &&
+ (obj->inner != NULL)) {
+ obj->reader(obj->inner);
+ /* We always ask for more when reading */
+ return (1);
+ } else if ((flags == ISC_SOCKFDWATCH_WRITE) &&
+ (obj->writer != NULL) &&
+ (obj->inner != NULL)) {
+ status = obj->writer(obj->inner);
+ /* If the writer has more to write they should return
+ * ISC_R_INPROGRESS */
+ if (status == ISC_R_INPROGRESS) {
+ return (1);
+ }
+ }
+
+ /*
+ * We get here if we either had an error (inconsistent
+ * structures etc) or no more to write, tell the socket
+ * lib we don't have more to do right now.
+ */
+ return (0);
+}
/* Register an I/O handle so that we can do asynchronous I/O on it. */
{
isc_result_t status;
omapi_io_object_t *obj, *p;
+ int fd_flags = 0, fd = 0;
/* omapi_io_states is a static object. If its reference count
is zero, this is the first I/O handle to be registered, so
return status;
}
+ /*
+ * Attach the I/O object to the isc socket library via the
+ * fdwatch function. This allows the socket library to watch
+ * over a socket that we built. If there are both a read and
+ * a write socket we asssume they are the same socket.
+ */
+
+ if (readfd) {
+ fd_flags |= ISC_SOCKFDWATCH_READ;
+ fd = readfd(h);
+ }
+
+ if (writefd) {
+ fd_flags |= ISC_SOCKFDWATCH_WRITE;
+ fd = writefd(h);
+ }
+
+ if (fd_flags != 0) {
+ status = isc_socket_fdwatchcreate(dhcp_gbl_ctx.socketmgr,
+ fd, fd_flags,
+ omapi_iscsock_cb,
+ obj,
+ dhcp_gbl_ctx.task,
+ &obj->fd);
+ if (status != ISC_R_SUCCESS) {
+ log_error("Unable to register fd with library %s",
+ isc_result_totext(status));
+
+ /*sar*/
+ /* is this the cleanup we need? */
+ omapi_object_dereference(&h->outer, MDL);
+ omapi_io_dereference (&obj, MDL);
+ return (status);
+ }
+ }
+
+
/* Find the last I/O state, if there are any. */
for (p = omapi_io_states.next;
p && p -> next; p = p -> next)
omapi_io_object_t *p, *obj, *last, *ph;
if (!h -> outer || h -> outer -> type != omapi_type_io_object)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
obj = (omapi_io_object_t *)h -> outer;
ph = (omapi_io_object_t *)0;
omapi_io_reference (&ph, obj, MDL);
}
omapi_object_dereference (&obj -> inner, MDL);
omapi_object_dereference (&h -> outer, MDL);
+
+ /* remove isc socket associations */
+ if (obj->fd != NULL) {
+ isc_socket_detach(&obj->fd);
+ }
+
omapi_io_dereference (&ph, MDL);
return ISC_R_SUCCESS;
}
omapi_io_dereference(&prev, MDL);
}
omapi_io_reference(&prev, io, MDL);
-
}
/*
omapi_typed_data_t *value)
{
if (h -> type != omapi_type_io_object)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (h -> inner && h -> inner -> type -> set_value)
return (*(h -> inner -> type -> set_value))
omapi_value_t **value)
{
if (h -> type != omapi_type_io_object)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (h -> inner && h -> inner -> type -> get_value)
return (*(h -> inner -> type -> get_value))
omapi_io_object_t *obj = NULL, *p, *last = NULL, **holder;
if (h -> type != omapi_type_io_object)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
/* remove from the list of I/O states */
for (p = omapi_io_states.next; p; p = p -> next) {
const char *name, va_list ap)
{
if (h -> type != omapi_type_io_object)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (h -> inner && h -> inner -> type -> signal_handler)
return (*(h -> inner -> type -> signal_handler)) (h -> inner,
omapi_object_t *i)
{
if (i -> type != omapi_type_io_object)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (i -> inner && i -> inner -> type -> stuff_values)
return (*(i -> inner -> type -> stuff_values)) (c, id,
omapi_waiter_object_t *waiter;
if (h -> type != omapi_type_waiter)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (!strcmp (name, "ready")) {
waiter = (omapi_waiter_object_t *)h;
return ISC_R_SUCCESS;
}
- if (!strcmp (name, "status")) {
+ if (!strcmp(name, "status")) {
waiter = (omapi_waiter_object_t *)h;
- waiter -> ready = 1;
- waiter -> waitstatus = va_arg (ap, isc_result_t);
+ waiter->ready = 1;
+ waiter->waitstatus = va_arg(ap, isc_result_t);
return ISC_R_SUCCESS;
}
if (!strcmp (name, "disconnect")) {
waiter = (omapi_waiter_object_t *)h;
waiter -> ready = 1;
- waiter -> waitstatus = ISC_R_CONNRESET;
+ waiter -> waitstatus = DHCP_R_CONNRESET;
return ISC_R_SUCCESS;
}
isc_result_t status;
if (h -> type != omapi_type_generic)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
g = (omapi_generic_object_t *)h;
/* See if there's already a value with this name attached to
omapi_generic_object_t *g;
if (h -> type != omapi_type_generic)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
g = (omapi_generic_object_t *)h;
/* Look up the specified name in our list of objects. */
const char *name, va_list ap)
{
if (h -> type != omapi_type_generic)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (h -> inner && h -> inner -> type -> signal_handler)
return (*(h -> inner -> type -> signal_handler)) (h -> inner,
isc_result_t status;
if (g -> type != omapi_type_generic)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
src = (omapi_generic_object_t *)g;
for (i = 0; i < src -> nvalues; i++) {
omapi_generic_object_t *g;
if (o -> type != omapi_type_generic)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
g = (omapi_generic_object_t *)o;
for (i = 0; i < g -> nvalues; i++) {
memcpy (&h, handle -> u.buffer.value, sizeof h);
h = ntohl (h);
} else
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
return omapi_handle_lookup (obj, h);
}
--- /dev/null
+/*
+ * Copyright(c) 2009 by Internet Systems Consortium, Inc.("ISC")
+ *
+ * Permission to use, copy, modify, and 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 ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC 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.
+ *
+ * Internet Systems Consortium, Inc.
+ * 950 Charter Street
+ * Redwood City, CA 94063
+ * <info@isc.org>
+ * http://www.isc.org/
+ *
+ */
+
+/*Trying to figure out what we need to define to get things to work.
+ It looks like we want/need the export library but need the fdwatchcommand
+ which may be a problem */
+
+#include "dhcpd.h"
+
+dhcp_context_t dhcp_gbl_ctx;
+
+void
+isclib_cleanup(void)
+{
+#if defined (NSUPDATE)
+ if (dhcp_gbl_ctx.dnsclient != NULL)
+ dns_client_destroy((dns_client_t **)&dhcp_gbl_ctx.dnsclient);
+#endif
+
+ if (dhcp_gbl_ctx.task != NULL) {
+// isc_task_destroy(&dhcp_gbl_ctx.task);
+ isc_task_shutdown(dhcp_gbl_ctx.task);
+ isc_task_detach(&dhcp_gbl_ctx.task);
+ }
+
+ if (dhcp_gbl_ctx.timermgr != NULL)
+ isc_timermgr_destroy(&dhcp_gbl_ctx.timermgr);
+
+ if (dhcp_gbl_ctx.socketmgr != NULL)
+ isc_socketmgr_destroy(&dhcp_gbl_ctx.socketmgr);
+
+ if (dhcp_gbl_ctx.taskmgr != NULL)
+ isc_taskmgr_destroy(&dhcp_gbl_ctx.taskmgr);
+
+ if (dhcp_gbl_ctx.actx_started != ISC_FALSE) {
+ isc_app_ctxfinish(dhcp_gbl_ctx.actx);
+ dhcp_gbl_ctx.actx_started = ISC_FALSE;
+ }
+
+ if (dhcp_gbl_ctx.actx != NULL)
+ isc_appctx_destroy(&dhcp_gbl_ctx.actx);
+
+ if (dhcp_gbl_ctx.mctx != NULL)
+ isc_mem_detach(&dhcp_gbl_ctx.mctx);
+
+ return;
+}
+
+isc_result_t
+dhcp_context_create(void) {
+ isc_result_t result;
+
+ /*
+ * Set up the error messages, this isn't the right place
+ * for this call but it is convienent for now.
+ */
+ result = dhcp_result_register();
+ if (result != ISC_R_SUCCESS) {
+ log_fatal("register_table() %s: %u", "failed", result);
+ }
+
+ memset(&dhcp_gbl_ctx, 0, sizeof (dhcp_gbl_ctx));
+
+ isc_lib_register();
+
+ /* get the current time for use as the random seed */
+ gettimeofday(&cur_tv, (struct timezone *)0);
+ isc_random_seed(cur_tv.tv_sec);
+
+#if defined (NSUPDATE)
+ result = dns_lib_init();
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+#endif
+
+ result = isc_mem_create(0, 0, &dhcp_gbl_ctx.mctx);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = isc_appctx_create(dhcp_gbl_ctx.mctx, &dhcp_gbl_ctx.actx);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = isc_app_ctxstart(dhcp_gbl_ctx.actx);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ dhcp_gbl_ctx.actx_started = ISC_TRUE;
+
+ result = isc_taskmgr_createinctx(dhcp_gbl_ctx.mctx,
+ dhcp_gbl_ctx.actx,
+ 1, 0,
+ &dhcp_gbl_ctx.taskmgr);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = isc_socketmgr_createinctx(dhcp_gbl_ctx.mctx,
+ dhcp_gbl_ctx.actx,
+ &dhcp_gbl_ctx.socketmgr);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = isc_timermgr_createinctx(dhcp_gbl_ctx.mctx,
+ dhcp_gbl_ctx.actx,
+ &dhcp_gbl_ctx.timermgr);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = isc_task_create(dhcp_gbl_ctx.taskmgr, 0, &dhcp_gbl_ctx.task);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+#if defined (NSUPDATE)
+ result = dns_client_createx(dhcp_gbl_ctx.mctx,
+ dhcp_gbl_ctx.actx,
+ dhcp_gbl_ctx.taskmgr,
+ dhcp_gbl_ctx.socketmgr,
+ dhcp_gbl_ctx.timermgr,
+ 0,
+ &dhcp_gbl_ctx.dnsclient);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+#else
+ /* The dst library is inited as part of dns_lib_init, we don't
+ * need it if NSUPDATE is enabled */
+ result = dst_lib_init(dhcp_gbl_ctx.mctx, NULL, 0);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+#endif
+ return(ISC_R_SUCCESS);
+
+ cleanup:
+ isclib_cleanup();
+
+ return(result);
+}
+
+/* Convert a string name into the proper structure for the isc routines */
+isc_result_t
+dhcp_isc_name(unsigned char *namestr,
+ dns_fixedname_t *namefix,
+ dns_name_t **name)
+{
+ size_t namelen;
+ isc_buffer_t b;
+ isc_result_t result;
+
+ namelen = strlen((char *)namestr);
+ isc_buffer_init(&b, namestr, namelen);
+ isc_buffer_add(&b, namelen);
+ dns_fixedname_init(namefix);
+ *name = dns_fixedname_name(namefix);
+ result = dns_name_fromtext(*name, &b, NULL, 0, NULL);
+ isc_buffer_invalidate(&b);
+ return(result);
+}
+
+isc_result_t
+isclib_make_dst_key(char *inname,
+ char *algorithm,
+ unsigned char *secret,
+ int length,
+ dst_key_t **dstkey)
+{
+ isc_result_t result;
+ dns_name_t *name;
+ dns_fixedname_t name0;
+ isc_buffer_t b;
+ int namelen;
+
+ isc_buffer_init(&b, secret, length);
+ isc_buffer_add(&b, length);
+
+ /* We only support HMAC_MD5 currently */
+ if (strcasecmp(algorithm, DHCP_HMAC_MD5_NAME) != 0) {
+ return(DHCP_R_INVALIDARG);
+ }
+
+ /*
+ * Previously we allowed key names without a trailing '.'
+ * however the current dst code requires the names to end
+ * in a period. If the name doesn't have a trailing period
+ * add one before sending it to the dst code.
+ */
+ namelen = strlen(inname);
+ if (inname[namelen-1] != '.') {
+ char *newname = NULL;
+ newname = (char *)dmalloc(namelen + 2, MDL);
+ if (newname == NULL) {
+ log_error("unable to allocate memory for key name");
+ return(ISC_R_NOMEMORY);
+ }
+ strcpy(newname, inname);
+ newname[namelen] = '.';
+ newname[namelen+1] = 0;
+ result = dhcp_isc_name((unsigned char *)newname, &name0, &name);
+ dfree(newname, MDL);
+ } else {
+ result = dhcp_isc_name((unsigned char *)inname, &name0, &name);
+ }
+
+ if (result != ISC_R_SUCCESS) {
+ return(result);
+ }
+
+ return(dst_key_frombuffer(name, DST_ALG_HMACMD5, DNS_KEYOWNER_ENTITY,
+ DNS_KEYPROTO_DNSSEC, dns_rdataclass_in,
+ &b, dhcp_gbl_ctx.mctx, dstkey));
+}
+
/* Currently only support IPv4 addresses. */
if (addr->addrtype != AF_INET)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
/* Get the handle. */
obj = (omapi_listener_object_t *)0;
int socket;
if (h -> type != omapi_type_listener)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
listener = (omapi_listener_object_t *)h;
/* Accept the connection. */
omapi_listener_object_t *l;
if (h -> type != omapi_type_listener)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
l = (omapi_listener_object_t *)h;
l -> verify_addr = verify_addr;
omapi_typed_data_t *value)
{
if (h -> type != omapi_type_listener)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (h -> inner && h -> inner -> type -> set_value)
return (*(h -> inner -> type -> set_value))
omapi_value_t **value)
{
if (h -> type != omapi_type_listener)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (h -> inner && h -> inner -> type -> get_value)
return (*(h -> inner -> type -> get_value))
omapi_listener_object_t *l;
if (h -> type != omapi_type_listener)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
l = (omapi_listener_object_t *)h;
#ifdef DEBUG_PROTOCOL
const char *name, va_list ap)
{
if (h -> type != omapi_type_listener)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (h -> inner && h -> inner -> type -> signal_handler)
return (*(h -> inner -> type -> signal_handler)) (h -> inner,
omapi_object_t *l)
{
if (l -> type != omapi_type_listener)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (l -> inner && l -> inner -> type -> stuff_values)
return (*(l -> inner -> type -> stuff_values)) (c, id,
isc_result_t status;
if (h -> type != omapi_type_message)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
m = (omapi_message_object_t *)h;
/* Can't set authlen. */
} else if (!omapi_ds_strcmp (name, "object")) {
if (value -> type != omapi_datatype_object)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (m -> object)
omapi_object_dereference (&m -> object, MDL);
omapi_object_reference (&m -> object, value -> u.object, MDL);
} else if (!omapi_ds_strcmp (name, "notify-object")) {
if (value -> type != omapi_datatype_object)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (m -> notify_object)
omapi_object_dereference (&m -> notify_object, MDL);
omapi_object_reference (&m -> notify_object,
/* Can set authid, but it has to be an integer. */
} else if (!omapi_ds_strcmp (name, "authid")) {
if (value -> type != omapi_datatype_int)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
m -> authid = value -> u.integer;
return ISC_R_SUCCESS;
/* Can set op, but it has to be an integer. */
} else if (!omapi_ds_strcmp (name, "op")) {
if (value -> type != omapi_datatype_int)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
m -> op = value -> u.integer;
return ISC_R_SUCCESS;
/* Handle also has to be an integer. */
} else if (!omapi_ds_strcmp (name, "handle")) {
if (value -> type != omapi_datatype_int)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
m -> h = value -> u.integer;
return ISC_R_SUCCESS;
/* Transaction ID has to be an integer. */
} else if (!omapi_ds_strcmp (name, "id")) {
if (value -> type != omapi_datatype_int)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
m -> id = value -> u.integer;
return ISC_R_SUCCESS;
/* Remote transaction ID has to be an integer. */
} else if (!omapi_ds_strcmp (name, "rid")) {
if (value -> type != omapi_datatype_int)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
m -> rid = value -> u.integer;
return ISC_R_SUCCESS;
}
{
omapi_message_object_t *m;
if (h -> type != omapi_type_message)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
m = (omapi_message_object_t *)h;
/* Look for values that are in the message data structure. */
{
omapi_message_object_t *m;
if (h -> type != omapi_type_message)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
m = (omapi_message_object_t *)h;
if (m -> authenticator) {
omapi_typed_data_dereference (&m -> authenticator, file, line);
{
omapi_message_object_t *m;
if (h -> type != omapi_type_message)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
m = (omapi_message_object_t *)h;
if (!strcmp (name, "status")) {
omapi_object_t *m)
{
if (m -> type != omapi_type_message)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (m -> inner && m -> inner -> type -> stuff_values)
return (*(m -> inner -> type -> stuff_values)) (c, id,
omapi_message_object_t *m;
if (mo -> type != omapi_type_message)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
m = (omapi_message_object_t *)mo;
/* Already registered? */
if (m -> prev || m -> next || omapi_registered_messages == m)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (omapi_registered_messages) {
omapi_object_reference
omapi_message_object_t *n;
if (mo -> type != omapi_type_message)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
m = (omapi_message_object_t *)mo;
/* Not registered? */
if (!m -> prev && omapi_registered_messages != m)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
n = (omapi_message_object_t *)0;
if (m -> next) {
omapi_object_type_t *type;
if (mo -> type != omapi_type_message)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
message = (omapi_message_object_t *)mo;
#ifdef DEBUG_PROTOCOL
/* All messages must have an authenticator, with the exception
of messages that are opening a new authenticator. */
- if (omapi_protocol_authenticated (po) &&
- !message -> id_object &&
- message -> op != OMAPI_OP_OPEN) {
+ if (omapi_protocol_authenticated(po) &&
+ !message->id_object &&
+ message->op != OMAPI_OP_OPEN) {
return omapi_protocol_send_status
- (po, message -> id_object, ISC_R_NOKEYS,
- message -> id, "No authenticator on message");
+ (po, message->id_object, DHCP_R_NOKEYS,
+ message->id, "No authenticator on message");
}
}
case OMAPI_OP_OPEN:
if (m) {
return omapi_protocol_send_status
- (po, message -> id_object, ISC_R_INVALIDARG,
- message -> id, "OPEN can't be a response");
+ (po, message->id_object, DHCP_R_INVALIDARG,
+ message->id, "OPEN can't be a response");
}
/* Get the type of the requested object, if one was
/* If this object had no authenticator, the requested object
must be an authenticator object. */
- if (omapi_protocol_authenticated (po) &&
- !message -> id_object &&
+ if (omapi_protocol_authenticated(po) &&
+ !message->id_object &&
type != omapi_type_auth_key) {
return omapi_protocol_send_status
- (po, message -> id_object, ISC_R_NOKEYS,
- message -> id, "No authenticator on message");
+ (po, message->id_object, DHCP_R_NOKEYS,
+ message->id, "No authenticator on message");
}
/* Get the create flag. */
if (!type) {
if (create) {
return omapi_protocol_send_status
- (po, message -> id_object,
- ISC_R_INVALIDARG,
- message -> id,
+ (po, message->id_object,
+ DHCP_R_INVALIDARG,
+ message->id,
"type required on create");
}
goto refresh;
if (status != ISC_R_SUCCESS &&
status != ISC_R_NOTFOUND &&
- status != ISC_R_NOKEYS) {
+ status != DHCP_R_NOKEYS) {
return omapi_protocol_send_status
(po, message -> id_object,
status, message -> id,
#include "dhcpd.h"
#include <omapip/omapip_p.h>
-#include "minires/minires.h"
+#include "minires.h"
#include "arpa/nameser.h"
#include <errno.h>
trace_mr_randomid_stop, MDL);
}
+#if 0
void trace_mr_statp_setup (res_state statp)
{
unsigned buflen = 0;
}
}
#endif
+#endif
ssize_t trace_mr_send (int fd, void *msg, size_t len, int flags)
{
return status;
rstatus = omapi_connect ((omapi_object_t *)obj, server_name, port);
- if (rstatus != ISC_R_SUCCESS && rstatus != ISC_R_INCOMPLETE) {
+ if (rstatus != ISC_R_SUCCESS && rstatus != DHCP_R_INCOMPLETE) {
omapi_protocol_dereference (&obj, MDL);
return rstatus;
}
}
obj -> insecure = 0;
- rstatus = ISC_R_INCOMPLETE;
+ rstatus = DHCP_R_INCOMPLETE;
} else {
obj -> insecure = 1;
#if 0
#endif
if (h -> type != omapi_type_protocol)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
p = (omapi_protocol_object_t *)h;
if (!h -> outer || h -> outer -> type != omapi_type_connection)
protocol input state machine. */
p -> state = omapi_protocol_intro_wait;
status = omapi_connection_require (h -> outer, 8);
- if (status != ISC_R_SUCCESS && status != ISC_R_NOTYET)
+ if (status != ISC_R_SUCCESS && status != DHCP_R_NOTYET)
return status;
/* Make up an initial transaction ID for this connection. */
if (po -> type != omapi_type_protocol ||
!po -> outer || po -> outer -> type != omapi_type_connection ||
mo -> type != omapi_type_message)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (omo && omo -> type != omapi_type_message)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
p = (omapi_protocol_object_t *)po;
c = (omapi_object_t *)(po -> outer);
m = (omapi_message_object_t *)mo;
}
if (!ra)
- return ISC_R_KEY_UNKNOWN;
+ return DHCP_R_KEY_UNKNOWN;
} else if (p -> remote_auth_list) {
ra = p -> default_auth;
} else {
}
if (!p -> outer || p -> outer -> type != omapi_type_connection)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
c = p -> outer;
/* We get here because we requested that we be woken up after
/* We currently only support the current protocol version. */
if (p -> protocol_version != OMAPI_PROTOCOL_VERSION) {
omapi_disconnect (c, 1);
- return ISC_R_VERSIONMISMATCH;
+ return DHCP_R_VERSIONMISMATCH;
}
if (p -> header_size < sizeof (omapi_protocol_header_t)) {
omapi_disconnect (c, 1);
- return ISC_R_PROTOCOLERROR;
+ return DHCP_R_PROTOCOLERROR;
}
if (p -> default_auth) {
p -> message -> authenticator -> u.buffer.value,
p -> message -> authlen) != 0))) {
/* Invalid signature. */
- p -> verify_result = ISC_R_INVALIDKEY;
+ p->verify_result = DHCP_R_INVALIDKEY;
}
omapi_value_dereference (&signature, MDL);
if (ao -> type != omapi_type_auth_key &&
(!ao -> inner || ao -> inner -> type != omapi_type_auth_key))
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (po -> type != omapi_type_protocol)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
p = (omapi_protocol_object_t *)po;
#ifdef DEBUG_PROTOCOL
omapi_remote_auth_t *r;
if (po -> type != omapi_type_protocol)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
p = (omapi_protocol_object_t *)po;
for (r = p -> remote_auth_list; r; r = r -> next)
if (r -> remote_handle == handle)
return omapi_object_reference (a, r -> a, MDL);
- return ISC_R_KEY_UNKNOWN;
+ return DHCP_R_KEY_UNKNOWN;
}
isc_result_t omapi_protocol_set_value (omapi_object_t *h,
omapi_remote_auth_t *r;
if (h -> type != omapi_type_protocol)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
p = (omapi_protocol_object_t *)h;
if (omapi_ds_strcmp (name, "default-authenticator") == 0) {
if (value -> type != omapi_datatype_object)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (!value || !value -> u.object) {
p -> default_auth = (omapi_remote_auth_t *)0;
break;
if (!r)
- return ISC_R_KEY_UNKNOWN;
+ return DHCP_R_KEY_UNKNOWN;
p -> default_auth = r;
}
omapi_protocol_object_t *p;
if (h -> type != omapi_type_protocol)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
p = (omapi_protocol_object_t *)h;
if (omapi_ds_strcmp (name, "default-authenticator") == 0) {
{
omapi_protocol_object_t *p;
if (h -> type != omapi_type_protocol)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
p = (omapi_protocol_object_t *)h;
if (p -> message)
omapi_message_dereference (&p -> message, file, line);
omapi_object_t *p)
{
if (p -> type != omapi_type_protocol)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (p -> inner && p -> inner -> type -> stuff_values)
return (*(p -> inner -> type -> stuff_values)) (c, id,
h = h -> outer;
if (h -> type != omapi_type_protocol_listener)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
l = (omapi_protocol_listener_object_t *)h;
l -> verify_auth = verify_auth;
omapi_protocol_listener_object_t *p;
if (!o || o -> type != omapi_type_protocol_listener)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
p = (omapi_protocol_listener_object_t *)o;
/* Not a signal we recognize? */
c = va_arg (ap, omapi_object_t *);
if (!c || c -> type != omapi_type_connection)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
obj = (omapi_protocol_object_t *)0;
status = omapi_protocol_allocate (&obj, MDL);
omapi_typed_data_t *value)
{
if (h -> type != omapi_type_protocol_listener)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (h -> inner && h -> inner -> type -> set_value)
return (*(h -> inner -> type -> set_value))
omapi_value_t **value)
{
if (h -> type != omapi_type_protocol_listener)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (h -> inner && h -> inner -> type -> get_value)
return (*(h -> inner -> type -> get_value))
const char *file, int line)
{
if (h -> type != omapi_type_protocol_listener)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
return ISC_R_SUCCESS;
}
omapi_object_t *p)
{
if (p -> type != omapi_type_protocol_listener)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (p -> inner && p -> inner -> type -> stuff_values)
return (*(p -> inner -> type -> stuff_values)) (c, id,
omapi_object_t *mo;
if (po -> type != omapi_type_protocol)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
status = omapi_message_new ((omapi_object_t **)&message, MDL);
if (status != ISC_R_SUCCESS)
omapi_object_t *mo;
if (po -> type != omapi_type_protocol)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
status = omapi_message_new ((omapi_object_t **)&message, MDL);
mo = (omapi_object_t *)message;
omapi_object_t *mo;
if (po -> type != omapi_type_protocol)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
status = omapi_message_new ((omapi_object_t **)&message, MDL);
if (status != ISC_R_SUCCESS)
/* result.c
+ */
- Cheap knock-off of libisc result table code. This is just a place-holder
- until the actual libisc merge. */
-
-/*
- * Copyright (c) 2004,2007 by Internet Systems Consortium, Inc. ("ISC")
+/*
+ * Copyright (c) 2004,2007,2009 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1999-2003 by Internet Software Consortium
*
- * Permission to use, copy, modify, and distribute this software for any
+ * 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 ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC 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.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC 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.
*
* Internet Systems Consortium, Inc.
* 950 Charter Street
* <info@isc.org>
* https://www.isc.org/
*
- * This software has been written for Internet Systems Consortium
- * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
- * To learn more about Internet Systems Consortium, see
- * ``https://www.isc.org/''. To learn more about Vixie Enterprises,
- * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
- * ``http://www.nominum.com''.
*/
#include "dhcpd.h"
-#include <omapip/omapip_p.h>
+/*
+ * In the previous code the results started at 36
+ * rather than ISC_RESULTCLASS_DHCP + 0
+ * ISC_R_NOTCONNECTED was + 4 (40), it has been superseeded by the isc version
+ */
-static const char *text[ISC_R_NRESULTS] = {
- "success", /* 0 */
- "out of memory", /* 1 */
- "timed out", /* 2 */
- "no available threads", /* 3 */
- "address not available", /* 4 */
- "address in use", /* 5 */
- "permission denied", /* 6 */
- "no pending connections", /* 7 */
- "network unreachable", /* 8 */
- "host unreachable", /* 9 */
- "network down", /* 10 */
- "host down", /* 11 */
- "connection refused", /* 12 */
- "not enough free resources", /* 13 */
- "end of file", /* 14 */
- "socket already bound", /* 15 */
- "task is done", /* 16 */
- "lock busy", /* 17 */
- "already exists", /* 18 */
- "ran out of space", /* 19 */
- "operation canceled", /* 20 */
- "sending events is not allowed", /* 21 */
- "shutting down", /* 22 */
- "not found", /* 23 */
- "unexpected end of input", /* 24 */
- "failure", /* 25 */
- "I/O error", /* 26 */
- "not implemented", /* 27 */
- "unbalanced parentheses", /* 28 */
- "no more", /* 29 */
- "invalid file", /* 30 */
- "bad base64 encoding", /* 31 */
- "unexpected token", /* 32 */
- "quota reached", /* 33 */
- "unexpected error", /* 34 */
- "already running", /* 35 */
- "host unknown", /* 36 */
- "protocol version mismatch", /* 37 */
- "protocol error", /* 38 */
- "invalid argument", /* 39 */
- "not connected", /* 40 */
- "data not yet available", /* 41 */
- "object unchanged", /* 42 */
- "more than one object matches key", /* 43 */
- "key conflict", /* 44 */
- "parse error(s) occurred", /* 45 */
- "no key specified", /* 46 */
- "zone TSIG key not known", /* 47 */
- "invalid TSIG key", /* 48 */
- "operation in progress", /* 49 */
- "DNS format error", /* 50 */
- "DNS server failed", /* 51 */
- "no such domain", /* 52 */
- "not implemented", /* 53 */
- "refused", /* 54 */
- "domain already exists", /* 55 */
- "RRset already exists", /* 56 */
- "no such RRset", /* 57 */
- "not authorized", /* 58 */
- "not a zone", /* 59 */
- "bad DNS signature", /* 60 */
- "bad DNS key", /* 61 */
- "clock skew too great", /* 62 */
- "no root zone", /* 63 */
- "destination address required", /* 64 */
- "cross-zone update", /* 65 */
- "no TSIG signature", /* 66 */
- "not equal", /* 67 */
- "connection reset by peer", /* 68 */
- "unknown attribute" /* 69 */
+static const char *text[DHCP_R_NRESULTS] = {
+ "host unknown", /* 0 */
+ "protocol version mismatch", /* 1 */
+ "protocol error", /* 2 */
+ "invalid argument", /* 3 */
+ "data not yet available", /* 4 */
+ "object unchanged", /* 5 */
+ "more than one object matches key", /* 6 */
+ "key conflict", /* 7 */
+ "parse error(s) occurred", /* 8 */
+ "no key specified", /* 9 */
+ "zone TSIG key not known", /* 10 */
+ "invalid TSIG key", /* 11 */
+ "operation in progress", /* 12 */
+ "DNS format error", /* 13 */
+ "DNS server failed", /* 14 */
+ "no such domain", /* 15 */
+ "not implemented", /* 16 */
+ "refused", /* 17 */
+ "domain already exists", /* 18 */
+ "RRset already exists", /* 19 */
+ "no such RRset", /* 20 */
+ "not authorized", /* 21 */
+ "not a zone", /* 22 */
+ "bad DNS signature", /* 23 */
+ "bad DNS key", /* 24 */
+ "clock skew too great", /* 25 */
+ "no root zone", /* 26 */
+ "destination address required", /* 27 */
+ "cross-zone update", /* 28 */
+ "no TSIG signature", /* 29 */
+ "not equal", /* 30 */
+ "connection reset by peer", /* 31 */
+ "unknown attribute" /* 32 */
};
-const char *isc_result_totext (isc_result_t result)
-{
- static char ebuf[40];
+#define DHCP_RESULT_RESULTSET 2
+#define DHCP_RESULT_UNAVAILABLESET 3
+
+// This is a placeholder as we don't allow for external message catalogs yet
+isc_msgcat_t * dhcp_msgcat = NULL;
+
+isc_result_t
+dhcp_result_register(void) {
+ isc_result_t result;
+
+ result = isc_result_register(ISC_RESULTCLASS_DHCP, DHCP_R_NRESULTS,
+ text, dhcp_msgcat, DHCP_RESULT_RESULTSET);
- if (result >= ISC_R_SUCCESS && result < ISC_R_NRESULTS)
- return text [result];
- sprintf(ebuf, "unknown error: %d", result);
- return ebuf;
+ return(result);
}
{
isc_result_t status;
- dst_init();
-
/* Register all the standard object types... */
status = omapi_object_type_register (&omapi_type_connection,
"connection",
int i;
if (!src)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (src -> type != omapi_type_generic)
return ISC_R_NOTIMPLEMENTED;
gsrc = (omapi_generic_object_t *)src;
status = omapi_set_value (obj, id,
gsrc -> values [i] -> name,
gsrc -> values [i] -> value);
- if (status != ISC_R_SUCCESS && status != ISC_R_UNCHANGED)
+ if (status != ISC_R_SUCCESS && status != DHCP_R_UNCHANGED)
return status;
}
if (handle)
} else if (t -> type == omapi_datatype_string ||
t -> type == omapi_datatype_data) {
if (t -> u.buffer.len != sizeof (rv))
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
memcpy (&rv, t -> u.buffer.value, sizeof rv);
*v = ntohl (rv);
return ISC_R_SUCCESS;
}
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
-#include <isc-dhcp/result.h>
+#include <omapip/result.h>
#include <sys/time.h>
#include <omapip/omapip.h>
+#include <omapip/isclib.h>
int main (int argc, char **argv)
{
omapi_object_t *connection = (omapi_object_t*)0;
isc_result_t status;
+ dhcp_context_create();
+
omapi_init ();
if (argc > 1 && !strcmp (argv [1], "listen")) {
#include <omapip/omapip_p.h>
#include "arpa/nameser.h"
-#include "minires/minires.h"
+#include "minires.h"
#include <errno.h>
-isc_result_t ns_rcode_to_isc (int nsr)
-{
- switch (nsr) {
- case ns_r_noerror:
- return ISC_R_SUCCESS;
-
- case ns_r_formerr:
- return ISC_R_FORMERR;
-
- case ns_r_servfail:
- return ISC_R_SERVFAIL;
-
- case ns_r_nxdomain:
- return ISC_R_NXDOMAIN;
-
- case ns_r_notimpl:
- return ISC_R_NOTIMPL;
-
- case ns_r_refused:
- return ISC_R_REFUSED;
-
- case ns_r_yxdomain:
- return ISC_R_YXDOMAIN;
-
- case ns_r_yxrrset:
- return ISC_R_YXRRSET;
-
- case ns_r_nxrrset:
- return ISC_R_NXRRSET;
-
- case ns_r_notauth:
- return ISC_R_NOTAUTH;
-
- case ns_r_notzone:
- return ISC_R_NOTZONE;
-
- case ns_r_badsig:
- return ISC_R_BADSIG;
-
- case ns_r_badkey:
- return ISC_R_BADKEY;
-
- case ns_r_badtime:
- return ISC_R_BADTIME;
-
- default:
- ;
- }
- return ISC_R_UNEXPECTED;
-}
-
isc_result_t uerr2isc (int err)
{
switch (err) {
return ISC_R_NOSPACE;
case ENOEXEC:
- return ISC_R_FORMERR;
+ return DHCP_R_FORMERR;
case ECHILD:
return ISC_R_NOTFOUND;
return ISC_R_NOPERM;
case EFAULT:
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
case EEXIST:
return ISC_R_EXISTS;
case EINVAL:
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
case ENOTTY:
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
case EFBIG:
return ISC_R_NOSPACE;
return ISC_R_INVALIDFILE;
case EDESTADDRREQ:
- return ISC_R_DESTADDRREQ;
+ return DHCP_R_DESTADDRREQ;
case EMSGSIZE:
return ISC_R_NOSPACE;
case EPROTOTYPE:
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
case ENOPROTOOPT:
return ISC_R_NOTIMPLEMENTED;
return ISC_R_TIMEDOUT;
case ECONNRESET:
- return ISC_R_CONNRESET;
+ return DHCP_R_CONNRESET;
case ENOBUFS:
return ISC_R_NOSPACE;
#ifdef ERPCMISMATCH
case ERPCMISMATCH:
- return ISC_R_VERSIONMISMATCH;
+ return DHCP_R_VERSIONMISMATCH;
#endif
#ifdef EPROGMISMATCH
case EPROGMISMATCH:
- return ISC_R_VERSIONMISMATCH;
+ return DHCP_R_VERSIONMISMATCH;
#endif
#ifdef EAUTH
case EAUTH:
- return ISC_R_NOTAUTH;
+ return DHCP_R_NOTAUTH;
#endif
#ifdef ENEEDAUTH
case ENEEDAUTH:
- return ISC_R_NOTAUTH;
+ return DHCP_R_NOTAUTH;
#endif
#ifdef EOVERFLOW
}
return ISC_R_UNEXPECTED;
}
-
-ns_rcode isc_rcode_to_ns (isc_result_t isc)
-{
- switch (isc) {
- case ISC_R_SUCCESS:
- return ns_r_noerror;
-
- case ISC_R_FORMERR:
- return ns_r_formerr;
-
- case ISC_R_SERVFAIL:
- return ns_r_servfail;
-
- case ISC_R_NXDOMAIN:
- return ns_r_nxdomain;
-
- case ISC_R_NOTIMPL:
- return ns_r_notimpl;
-
- case ISC_R_REFUSED:
- return ns_r_refused;
-
- case ISC_R_YXDOMAIN:
- return ns_r_yxdomain;
-
- case ISC_R_YXRRSET:
- return ns_r_yxrrset;
-
- case ISC_R_NXRRSET:
- return ns_r_nxrrset;
-
- case ISC_R_NOTAUTH:
- return ns_r_notauth;
-
- case ISC_R_NOTZONE:
- return ns_r_notzone;
-
- case ISC_R_BADSIG:
- return ns_r_badsig;
-
- case ISC_R_BADKEY:
- return ns_r_badkey;
-
- case ISC_R_BADTIME:
- return ns_r_badtime;
-
- default:
- ;
- }
- return ns_r_servfail;
-}
if (traceoutfile) {
log_error ("%s(%d): trace_begin called twice",
file, line);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
traceoutfile = open (filename, O_CREAT | O_WRONLY | O_EXCL, 0600);
if (!ttype) {
log_error ("%s(%d): trace_write_packet with null trace type",
file ? file : "<unknown file>", line);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
if (!traceoutfile) {
log_error ("%s(%d): trace_write_packet with no tracefile.",
file ? file : "<unknown file>", line);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
/* Compute the total length of the iov. */
"%ld %ld.",
(long int)status,
(long int)tracefile_header.phlen);
- return ISC_R_PROTOCOLERROR;
+ return DHCP_R_PROTOCOLERROR;
}
/* Swap the packet. */
else {
log_error ("Trace packet with unknown index %ld",
(long int)tpkt -> type_index);
- return ISC_R_PROTOCOLERROR;
+ return DHCP_R_PROTOCOLERROR;
}
/* If we were just hunting for the time marker, we've found it,
status = fsetpos (traceinfile, &curpos);
if (status < 0) {
log_error ("fsetpos in tracefile failed: %m");
- return ISC_R_PROTOCOLERROR;
+ return DHCP_R_PROTOCOLERROR;
}
return ISC_R_EXISTS;
}
status = fsetpos (traceinfile, &curpos);
if (status < 0) {
log_error ("fsetpos in tracefile failed: %m");
- return ISC_R_PROTOCOLERROR;
+ return DHCP_R_PROTOCOLERROR;
}
return ISC_R_UNEXPECTEDTOKEN;
}
else
log_error ("Short read on trace payload: %d %d.",
status, paylen);
- return ISC_R_PROTOCOLERROR;
+ return DHCP_R_PROTOCOLERROR;
}
/* Store the actual length of the payload. */
isc_result_t status;
if (!buf || *buf)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
tpkt = dmalloc ((unsigned)tracefile_header.phlen, MDL);
if (!tpkt) {
/* Disallow some obvious bogosities. */
if (!buf || !len || *buf)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
/* Save file position in case of filename mismatch. */
status = fgetpos (traceinfile, &curpos);
log_error ("fsetpos in tracefile failed: %m");
dfree (tpkt, MDL);
dfree (*buf, MDL);
- return ISC_R_PROTOCOLERROR;
+ return DHCP_R_PROTOCOLERROR;
}
return ISC_R_UNEXPECTEDTOKEN;
}
sbin_PROGRAMS = dhcrelay
dhcrelay_SOURCES = dhcrelay.c
-dhcrelay_LDADD = ../common/libdhcp.a ../omapip/libomapi.a ../dst/libdst.a ../minires/libres.a
+dhcrelay_LDADD = ../common/libdhcp.a ../omapip/libomapi.a \
+ ../bind/lib/libdns.a ../bind/lib/libisc.a
man_MANS = dhcrelay.8
EXTRA_DIST = $(man_MANS)
setlogmask(LOG_UPTO(LOG_INFO));
#endif
+ /* Set up the isc and dns library managers */
+ status = dhcp_context_create();
+ if (status != ISC_R_SUCCESS)
+ log_fatal("Can't initialize context: %s",
+ isc_result_totext(status));
+
/* Set up the OMAPI. */
status = omapi_init();
if (status != ISC_R_SUCCESS)
dhcpv6.c mdb6.c
# libomapi.a this is here twice to handle circular library dependencies :(
-dhcpd_LDADD = ../common/libdhcp.a ../omapip/libomapi.a ../dst/libdst.a \
- ../dhcpctl/libdhcpctl.a ../minires/libres.a \
- ../omapip/libomapi.a
+dhcpd_LDADD = ../common/libdhcp.a ../omapip/libomapi.a \
+ ../dhcpctl/libdhcpctl.a ../omapip/libomapi.a \
+ ../bind/lib/libdns.a ../bind/lib/libisc.a
man_MANS = dhcpd.8 dhcpd.conf.5 dhcpd.leases.5
EXTRA_DIST = $(man_MANS)
} while (1);
token = next_token (&val, (unsigned *)0, cfile);
- status = cfile -> warnings_occurred ? ISC_R_BADPARSE : ISC_R_SUCCESS;
+ status = cfile->warnings_occurred ? DHCP_R_BADPARSE : ISC_R_SUCCESS;
return status;
}
} while (1);
- status = cfile -> warnings_occurred ? ISC_R_BADPARSE : ISC_R_SUCCESS;
+ status = cfile->warnings_occurred ? DHCP_R_BADPARSE : ISC_R_SUCCESS;
return status;
}
char *s;
if ((db_file == NULL) || (bnd == NULL) || (prepend == NULL))
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (bnd->value->type == binding_data) {
if (bnd->value->value.data.data != NULL) {
#include "dhcpd.h"
#include "dst/md5.h"
-#include "minires/minires.h"
+#include <dns/result.h>
#ifdef NSUPDATE
+static void ddns_fwd_srv_connector(struct lease *lease,
+ struct iasubopt *lease6,
+ struct binding_scope **inscope,
+ dhcp_ddns_cb_t *ddns_cb,
+ isc_result_t eresult);
+
/* DN: No way of checking that there is enough space in a data_string's
buffer. Be certain to allocate enough!
TL: This is why the expression evaluation code allocates a *new*
ds1 -> len += ds2 -> len;
}
-static isc_result_t ddns_update_ptr (struct data_string *ddns_fwd_name,
- struct data_string *ddns_rev_name,
- unsigned long ttl)
-{
- ns_updque updqueue;
- ns_updrec *updrec;
- isc_result_t result = ISC_R_UNEXPECTED;
-
- /*
- * The DHCP server submits a DNS query which deletes all of the PTR RRs
- * associated with the lease IP address, and adds a PTR RR whose data
- * is the client's (possibly disambiguated) host name. The server also
- * adds a DHCID RR specified in Section 4.3.
- * -- "Interaction between DHCP and DNS"
- */
-
- ISC_LIST_INIT (updqueue);
-
- /*
- * Delete all PTR RRs.
- */
- updrec = minires_mkupdrec (S_UPDATE,
- (const char *)ddns_rev_name -> data,
- C_IN, T_PTR, 0);
- if (!updrec) {
- result = ISC_R_NOMEMORY;
- goto error;
- }
-
- updrec -> r_data = (unsigned char *)0;
- updrec -> r_size = 0;
- updrec -> r_opcode = DELETE;
-
- ISC_LIST_APPEND (updqueue, updrec, r_link);
-
- /*
- * Add PTR RR.
- */
- updrec = minires_mkupdrec (S_UPDATE,
- (const char *)ddns_rev_name -> data,
- C_IN, T_PTR, ttl);
- if (!updrec) {
- result = ISC_R_NOMEMORY;
- goto error;
- }
-
- updrec -> r_data = ddns_fwd_name -> data;
- updrec -> r_size = ddns_fwd_name -> len;
- updrec -> r_opcode = ADD;
-
- ISC_LIST_APPEND (updqueue, updrec, r_link);
-
- /*
- * Attempt to perform the update.
- */
- result = minires_nupdate (&resolver_state, ISC_LIST_HEAD (updqueue));
-#if defined (DEBUG)
- print_dns_status ((int)result, &updqueue);
-#endif
- if (result == ISC_R_SUCCESS) {
- log_info ("added reverse map from %.*s to %.*s",
- (int)ddns_rev_name -> len,
- (const char *)ddns_rev_name -> data,
- (int)ddns_fwd_name -> len,
- (const char *)ddns_fwd_name -> data);
- } else {
- log_error ("unable to add reverse map from %.*s to %.*s: %s",
- (int)ddns_rev_name -> len,
- (const char *)ddns_rev_name -> data,
- (int)ddns_fwd_name -> len,
- (const char *)ddns_fwd_name -> data,
- isc_result_totext (result));
- }
-
- /* Fall through. */
- error:
-
- while (!ISC_LIST_EMPTY (updqueue)) {
- updrec = ISC_LIST_HEAD (updqueue);
- ISC_LIST_UNLINK (updqueue, updrec, r_link);
- minires_freeupdrec (updrec);
- }
-
- return result;
-}
-
-
-static isc_result_t ddns_remove_ptr (struct data_string *ddns_rev_name)
-{
- ns_updque updqueue;
- ns_updrec *updrec;
- isc_result_t result;
-
- /*
- * When a lease expires or a DHCP client issues a DHCPRELEASE request,
- * the DHCP server SHOULD delete the PTR RR that matches the DHCP
- * binding, if one was successfully added. The server's update query
- * SHOULD assert that the name in the PTR record matches the name of
- * the client whose lease has expired or been released.
- * -- "Interaction between DHCP and DNS"
- */
-
- ISC_LIST_INIT (updqueue);
-
- /*
- * Delete the PTR RRset for the leased address.
- */
- updrec = minires_mkupdrec (S_UPDATE,
- (const char *)ddns_rev_name -> data,
- C_IN, T_PTR, 0);
- if (!updrec) {
- result = ISC_R_NOMEMORY;
- goto error;
- }
-
- updrec -> r_data = (unsigned char *)0;
- updrec -> r_size = 0;
- updrec -> r_opcode = DELETE;
-
- ISC_LIST_APPEND (updqueue, updrec, r_link);
-
- /*
- * Attempt to perform the update.
- */
- result = minires_nupdate (&resolver_state, ISC_LIST_HEAD (updqueue));
-#if defined (DEBUG)
- print_dns_status ((int)result, &updqueue);
-#endif
- if (result == ISC_R_SUCCESS) {
- log_info ("removed reverse map on %.*s",
- (int)ddns_rev_name -> len,
- (const char *)ddns_rev_name -> data);
- } else {
- if (result != ISC_R_NXRRSET && result != ISC_R_NXDOMAIN)
- log_error ("can't remove reverse map on %.*s: %s",
- (int)ddns_rev_name -> len,
- (const char *)ddns_rev_name -> data,
- isc_result_totext (result));
- }
-
- /* Not there is success. */
- if (result == ISC_R_NXRRSET || result == ISC_R_NXDOMAIN)
- result = ISC_R_SUCCESS;
-
- /* Fall through. */
- error:
-
- while (!ISC_LIST_EMPTY (updqueue)) {
- updrec = ISC_LIST_HEAD (updqueue);
- ISC_LIST_UNLINK (updqueue, updrec, r_link);
- minires_freeupdrec (updrec);
- }
-
- return result;
-}
-
/* Determine what, if any, forward and reverse updates need to be
* performed, and carry them through.
struct data_string ddns_domainname;
struct data_string old_ddns_fwd_name;
struct data_string ddns_fwd_name;
- struct data_string ddns_rev_name;
+ //struct data_string ddns_rev_name;
struct data_string ddns_dhcid;
- struct binding_scope **scope;
- struct iaddr addr;
+ struct binding_scope **scope = NULL;
+ //struct iaddr addr;
struct data_string d1;
struct option_cache *oc;
int s1, s2;
int result = 0;
- isc_result_t rcode1 = ISC_R_SUCCESS, rcode2 = ISC_R_SUCCESS;
+ isc_result_t rcode1 = ISC_R_SUCCESS;
int server_updates_a = 1;
- int server_updates_ptr = 1;
+ //int server_updates_ptr = 1;
struct buffer *bp = (struct buffer *)0;
int ignorep = 0, client_ignorep = 0;
int rev_name_len;
int i;
+ dhcp_ddns_cb_t *ddns_cb;
+ int do_remove = 0;
+
if (ddns_update_style != 2)
return 0;
+ /*
+ * sigh, I want to cancel any previous udpates before we do anything
+ * else but this means we need to deal with the lease vs lease6
+ * question twice.
+ * If there is a ddns request already outstanding cancel it.
+ */
+
if (lease != NULL) {
- scope = &(lease->scope);
- addr = lease->ip_addr;
+ if ((old != NULL) && (old->ddns_cb != NULL)) {
+ ddns_cancel(old->ddns_cb);
+ old->ddns_cb = NULL;
+ }
} else if (lease6 != NULL) {
- scope = &(lease6->scope);
- memcpy(addr.iabuf, lease6->addr.s6_addr, 16);
- addr.len = 16;
+ if ((old6 != NULL) && (old6->ddns_cb != NULL)) {
+ ddns_cancel(old->ddns_cb);
+ old6->ddns_cb = NULL;
+ }
} else {
log_fatal("Impossible condition at %s:%d.", MDL);
/* Silence compiler warnings. */
- return 0;
+ result = 0;
+ return(0);
+ }
+
+ /* allocate our control block */
+ ddns_cb = ddns_cb_alloc(MDL);
+ if (ddns_cb == NULL) {
+ return(0);
+ }
+ /* assume that we shall update both the A and ptr records */
+ ddns_cb->flags = DDNS_UPDATE_ADDR | DDNS_UPDATE_PTR;
+
+ if (lease != NULL) {
+ scope = &(lease->scope);
+ ddns_cb->address = lease->ip_addr;
+ } else if (lease6 != NULL) {
+ scope = &(lease6->scope);
+ memcpy(ddns_cb->address.iabuf, lease6->addr.s6_addr, 16);
+ ddns_cb->address.len = 16;
}
- memset(&d1, 0, sizeof(d1));
+ memset (&d1, 0, sizeof(d1));
memset (&ddns_hostname, 0, sizeof (ddns_hostname));
memset (&ddns_domainname, 0, sizeof (ddns_domainname));
memset (&old_ddns_fwd_name, 0, sizeof (ddns_fwd_name));
memset (&ddns_fwd_name, 0, sizeof (ddns_fwd_name));
- memset (&ddns_rev_name, 0, sizeof (ddns_rev_name));
+ //memset (&ddns_rev_name, 0, sizeof (ddns_rev_name));
memset (&ddns_dhcid, 0, sizeof (ddns_dhcid));
/* If we are allowed to accept the client's update of its own A
NULL, packet->options,
options, scope, oc, MDL))
goto noclient;
+ ddns_cb->flags &= ~DDNS_UPDATE_ADDR;
server_updates_a = 0;
goto client_updates;
}
!evaluate_boolean_option_cache(&ignorep, packet, lease,
NULL, packet->options,
options, scope, oc, MDL)) {
- return 0;
+ goto out;
}
/* If it's a static lease, then don't do the DNS update unless we're
!evaluate_boolean_option_cache(&ignorep, packet, lease,
NULL, packet->options,
options, scope, oc, MDL))
- return 0;
+ goto out;
}
/*
ddns_hostname.len + ddns_domainname.len + 2,
MDL);
if (ddns_fwd_name.buffer) {
- ddns_fwd_name.data = ddns_fwd_name.buffer -> data;
+ ddns_fwd_name.data = ddns_fwd_name.buffer->data;
data_string_append (&ddns_fwd_name, &ddns_hostname);
- ddns_fwd_name.buffer -> data [ddns_fwd_name.len] = '.';
+ ddns_fwd_name.buffer->data[ddns_fwd_name.len] = '.';
ddns_fwd_name.len++;
data_string_append (&ddns_fwd_name, &ddns_domainname);
- ddns_fwd_name.buffer -> data [ddns_fwd_name.len] ='\0';
+ ddns_fwd_name.buffer->data[ddns_fwd_name.len] ='\0';
ddns_fwd_name.terminated = 1;
}
}
if (old_ddns_fwd_name.len != ddns_fwd_name.len ||
memcmp (old_ddns_fwd_name.data, ddns_fwd_name.data,
old_ddns_fwd_name.len)) {
- /* If the name is different, try to delete
- the old A record. */
- if (!ddns_removals(lease, lease6))
- goto out;
- /* If the delete succeeded, go install the new
- record. */
+ /*
+ * If the name is different, mark the old record
+ * for deletion and continue getting the new info.
+ */
+ do_remove = 1;
goto in;
}
/* If we don't have a name that the client has been assigned, we
can just skip all this. */
- if (!ddns_fwd_name.len)
- goto out;
- if (ddns_fwd_name.len > 255) {
- log_error ("client provided fqdn: too long");
+ if ((!ddns_fwd_name.len) || (ddns_fwd_name.len > 255)) {
+ if (ddns_fwd_name.len > 255) {
+ log_error ("client provided fqdn: too long");
+ }
+
+ /* If desired do the removals */
+ if (do_remove != 0) {
+ (void) ddns_removals(lease, lease6, NULL);
+ }
goto out;
}
packet->options, options, scope,
oc, MDL)) {
if (d1.len == sizeof (u_int32_t))
- ddns_ttl = getULong (d1.data);
+ ddns_cb->ttl = getULong (d1.data);
data_string_forget (&d1, MDL);
}
}
* Figure out the length of the part of the name that depends
* on the address.
*/
- if (addr.len == 4) {
+ if (ddns_cb->address.len == 4) {
char buf[17];
/* XXX: WOW this is gross. */
rev_name_len = snprintf(buf, sizeof(buf), "%u.%u.%u.%u.",
- addr.iabuf[3] & 0xff,
- addr.iabuf[2] & 0xff,
- addr.iabuf[1] & 0xff,
- addr.iabuf[0] & 0xff) + 1;
+ ddns_cb->address.iabuf[3] & 0xff,
+ ddns_cb->address.iabuf[2] & 0xff,
+ ddns_cb->address.iabuf[1] & 0xff,
+ ddns_cb->address.iabuf[0] & 0xff) + 1;
if (s1) {
rev_name_len += d1.len;
data_string_forget(&d1, MDL);
}
}
- } else if (addr.len == 16) {
+ } else if (ddns_cb->address.len == 16) {
/*
* IPv6 reverse names are always the same length, with
* 32 hex characters separated by dots.
/* Set s1 to make sure we gate into updates. */
s1 = 1;
} else {
- log_fatal("invalid address length %d", addr.len);
+ log_fatal("invalid address length %d", ddns_cb->address.len);
/* Silence compiler warnings. */
return 0;
}
!evaluate_boolean_option_cache(&ignorep, packet, lease, NULL,
packet->options, options,
scope, oc, MDL)) {
- server_updates_ptr = 0;
+ ddns_cb->flags &= ~DDNS_UPDATE_PTR;
}
if (s1) {
- buffer_allocate(&ddns_rev_name.buffer, rev_name_len, MDL);
- if (ddns_rev_name.buffer != NULL) {
- ddns_rev_name.data = ddns_rev_name.buffer->data;
-
- if (addr.len == 4) {
- ddns_rev_name.len =
- sprintf((char *)ddns_rev_name.buffer->data,
+ buffer_allocate(&ddns_cb->rev_name.buffer, rev_name_len, MDL);
+ if (ddns_cb->rev_name.buffer != NULL) {
+ struct data_string *rname = &ddns_cb->rev_name;
+ rname->data = rname->buffer->data;
+
+ if (ddns_cb->address.len == 4) {
+ rname->len =
+ sprintf((char *)rname->buffer->data,
"%u.%u.%u.%u.",
- addr.iabuf[3] & 0xff,
- addr.iabuf[2] & 0xff,
- addr.iabuf[1] & 0xff,
- addr.iabuf[0] & 0xff);
+ ddns_cb->address.iabuf[3] & 0xff,
+ ddns_cb->address.iabuf[2] & 0xff,
+ ddns_cb->address.iabuf[1] & 0xff,
+ ddns_cb->address.iabuf[0] & 0xff);
/*
* d1.data may be opaque, garbage bytes, from
* user (mis)configuration.
*/
- data_string_append(&ddns_rev_name, &d1);
- ddns_rev_name.buffer->data[ddns_rev_name.len] =
- '\0';
- } else if (addr.len == 16) {
- char *p = (char *)&ddns_rev_name.buffer->data;
- unsigned char *a = addr.iabuf + 15;
+ data_string_append(rname, &d1);
+ rname->buffer->data[rname->len] = '\0';
+ } else if (ddns_cb->address.len == 16) {
+ char *p = (char *)&rname->buffer->data;
+ unsigned char *a = ddns_cb->address.iabuf + 15;
for (i=0; i<16; i++) {
sprintf(p, "%x.%x.",
(*a & 0xF), ((*a >> 4) & 0xF));
a -= 1;
}
strcat(p, "ip6.arpa.");
- ddns_rev_name.len =
- strlen((const char *)ddns_rev_name.data);
+ rname->len = strlen((const char *)rname->data);
}
- ddns_rev_name.terminated = 1;
+ rname->terminated = 1;
}
if (d1.data != NULL)
/*
* If we are updating the A record, compute the DHCID value.
*/
- if (server_updates_a) {
- memset (&ddns_dhcid, 0, sizeof ddns_dhcid);
+ if ((ddns_cb->flags & DDNS_UPDATE_ADDR) != 0) {
if (lease6 != NULL)
- result = get_dhcid(&ddns_dhcid, 2,
+ result = get_dhcid(&ddns_cb->dhcid, 2,
lease6->ia->iaid_duid.data,
lease6->ia->iaid_duid.len);
else if ((lease != NULL) && (lease->uid != NULL) &&
(lease->uid_len != 0))
- result = get_dhcid (&ddns_dhcid,
+ result = get_dhcid (&ddns_cb->dhcid,
DHO_DHCP_CLIENT_IDENTIFIER,
lease -> uid, lease -> uid_len);
else if (lease != NULL)
- result = get_dhcid (&ddns_dhcid, 0,
+ result = get_dhcid (&ddns_cb->dhcid, 0,
lease -> hardware_addr.hbuf,
lease -> hardware_addr.hlen);
else
goto badfqdn;
}
- /*
- * Start the resolver, if necessary.
- */
- if (!resolver_inited) {
- minires_ninit (&resolver_state);
- resolver_inited = 1;
- resolver_state.retrans = 1;
- resolver_state.retry = 1;
- }
-
/*
* Perform updates.
*/
- if (ddns_fwd_name.len && ddns_dhcid.len) {
- unsigned conflict;
+ data_string_copy(&ddns_cb->fwd_name, &ddns_fwd_name, MDL);
+
+ if (ddns_cb->flags && DDNS_UPDATE_ADDR) {
oc = lookup_option(&server_universe, options,
SV_DDNS_CONFLICT_DETECT);
- if (!oc ||
- evaluate_boolean_option_cache(&ignorep, packet, lease,
- NULL, packet->options,
- options, scope, oc, MDL))
- conflict = 1;
- else
- conflict = 0;
+ if (oc &&
+ !evaluate_boolean_option_cache(&ignorep, packet, lease,
+ NULL, packet->options,
+ options, scope, oc, MDL))
+ ddns_cb->flags |= DDNS_CONFLICT_OVERRIDE;
- rcode1 = ddns_update_fwd(&ddns_fwd_name, addr, &ddns_dhcid,
- ddns_ttl, 0, conflict);
}
- if (rcode1 == ISC_R_SUCCESS && server_updates_ptr) {
- if (ddns_fwd_name.len && ddns_rev_name.len)
- rcode2 = ddns_update_ptr (&ddns_fwd_name,
- &ddns_rev_name, ddns_ttl);
- } else
- rcode2 = rcode1;
-
- if (rcode1 == ISC_R_SUCCESS &&
- (server_updates_a || rcode2 == ISC_R_SUCCESS)) {
- bind_ds_value(scope, server_updates_a ? "ddns-fwd-name"
- : "ddns-client-fqdn",
- &ddns_fwd_name);
- if (server_updates_a)
- bind_ds_value(scope, "ddns-txt", &ddns_dhcid);
+ /*
+ * Previously if we failed during the removal operations
+ * we skipped the fqdn option processing. I'm not sure
+ * if we want to continue with that if we fail before sending
+ * the ddns messages. Currently we don't.
+ */
+ if (do_remove) {
+ rcode1 = ddns_removals(lease, lease6, ddns_cb);
}
-
- if (rcode2 == ISC_R_SUCCESS && server_updates_ptr) {
- bind_ds_value(scope, "ddns-rev-name", &ddns_rev_name);
+ else {
+ ddns_fwd_srv_connector(lease, lease6, scope, ddns_cb,
+ ISC_R_SUCCESS);
}
+ ddns_cb = NULL;
noerror:
/*
bp, &bp->data [2], 1,
FQDN_ENCODED, 0))
goto badfqdn;
- bp -> data [3] = isc_rcode_to_ns (rcode1);
+ bp -> data [3] = 255;//isc_rcode_to_ns (rcode1);
if (!save_option_buffer(&fqdn_universe, options,
bp, &bp->data [3], 1,
FQDN_RCODE1, 0))
goto badfqdn;
- bp -> data [4] = isc_rcode_to_ns (rcode2);
+ bp -> data [4] = 255;//isc_rcode_to_ns (rcode2);
if (!save_option_buffer(&fqdn_universe, options,
bp, &bp->data [4], 1,
FQDN_RCODE2, 0))
/*
* Final cleanup.
*/
+ if (ddns_cb != NULL) {
+ ddns_cb_free(ddns_cb, MDL);
+ }
+
data_string_forget(&d1, MDL);
data_string_forget(&ddns_hostname, MDL);
data_string_forget(&ddns_domainname, MDL);
data_string_forget(&old_ddns_fwd_name, MDL);
data_string_forget(&ddns_fwd_name, MDL);
- data_string_forget(&ddns_rev_name, MDL);
- data_string_forget(&ddns_dhcid, MDL);
+ //data_string_forget(&ddns_rev_name, MDL);
+ //data_string_forget(&ddns_dhcid, MDL);
if (bp)
buffer_dereference(&bp, MDL);
return result;
}
-/* Remove relevant entries from DNS. */
+/*
+ * Utility function to update text strings within a lease.
+ *
+ * The first issue is to find the proper scope. Sometimes we shall be
+ * called with a pointer to the scope in other cases we need to find
+ * the proper lease and then get the scope. Once we have the scope we update
+ * the proper strings, as indicated by the state value in the control block.
+ * Lastly, if we needed to find the scope we write it out, if we used a
+ * scope that was passed as an argument we don't write it, assuming that
+ * our caller (or his ...) will do the write.
+ */
+
+isc_result_t
+ddns_update_lease_text(dhcp_ddns_cb_t *ddns_cb,
+ struct binding_scope **inscope)
+{
+ struct binding_scope **scope = NULL;
+ struct lease *lease = NULL;
+ struct iasubopt *lease6 = NULL;
+ struct ipv6_pool *pool = NULL;
+ struct in6_addr addr;
+ struct data_string lease_dhcid;
+
+ if (inscope != NULL) {
+ scope = inscope;
+ } else if (ddns_cb->address.len == 4) {
+ if (find_lease_by_ip_addr(&lease, ddns_cb->address, MDL) != 0){
+ scope = &(lease->scope);
+ }
+ } else if (ddns_cb->address.len == 16) {
+ memcpy(&addr, &ddns_cb->address.iabuf, 16);
+ if ((find_ipv6_pool(&pool, D6O_IA_TA, &addr) ==
+ ISC_R_SUCCESS) ||
+ (find_ipv6_pool(&pool, D6O_IA_NA, &addr) ==
+ ISC_R_SUCCESS)) {
+ if (iasubopt_hash_lookup(&lease6, pool->leases,
+ &addr, 16, MDL)) {
+ scope = &(lease6->scope);
+ }
+ ipv6_pool_dereference(&pool, MDL);
+ }
+ } else {
+ log_fatal("Impossible condition at %s:%d.", MDL);
+ }
+
+ if (scope == NULL) {
+ /* If necessary get rid of the lease */
+ if (lease) {
+ lease_dereference(&lease, MDL);
+ }
+ else if (lease6) {
+ iasubopt_dereference(&lease6, MDL);
+ }
+
+ return(ISC_R_FAILURE);
+ }
+
+ /* We now have a scope and can proceed to update it */
+ switch(ddns_cb->state) {
+ case DDNS_STATE_REM_PTR:
+ unset(*scope, "ddns-rev-name");
+ if ((ddns_cb->flags & DDNS_CLIENT_DID_UPDATE) != 0) {
+ unset(*scope, "ddns-client-fqdn");
+ }
+ break;
+
+ case DDNS_STATE_ADD_PTR:
+ case DDNS_STATE_CLEANUP:
+ bind_ds_value(scope, "ddns-rev-name", &ddns_cb->rev_name);
+ if ((ddns_cb->flags & DDNS_UPDATE_ADDR) == 0) {
+ bind_ds_value(scope, "ddns-client-fqdn",
+ &ddns_cb->fwd_name);
+ }
+ break;
+
+ case DDNS_STATE_ADD_FW_YXDHCID:
+ case DDNS_STATE_ADD_FW_NXDOMAIN:
+ bind_ds_value(scope, "ddns-fwd-name", &ddns_cb->fwd_name);
+
+ /* convert from dns version to lease version of dhcid */
+ memset(&lease_dhcid, 0, sizeof(lease_dhcid));
+ dhcid_tolease(&ddns_cb->dhcid, &lease_dhcid);
+ bind_ds_value(scope, "ddns-txt", &lease_dhcid);
+ data_string_forget(&lease_dhcid, MDL);
+
+ break;
+
+ case DDNS_STATE_REM_FW_NXRR:
+ case DDNS_STATE_REM_FW_YXDHCID:
+ unset(*scope, "ddns-fwd-name");
+ unset(*scope, "ddns-txt");
+ break;
+ }
+
+ /* If necessary write it out and get rid of the lease */
+ if (lease) {
+ write_lease(lease);
+ lease_dereference(&lease, MDL);
+ } else if (lease6) {
+ write_ia(lease6->ia);
+ iasubopt_dereference(&lease6, MDL);
+ }
+
+ return(ISC_R_SUCCESS);
+}
+
+
+#if 0
+isc_result_t
+ddns_get_lease(dhcp_ddns_cb_t *ddns_cb)
+{
+ isc_result_t result = ISC_R_FAILURE;
+
+ if (ddns_cb->address.len == 4) {
+ struct lease **lease = (struct lease **)(&(ddns_cb->lease));
+ if (find_lease_by_ip_addr(lease, ddns_cb->address, MDL) != 0) {
+ ddns_cb->scope = &((*lease)->scope);
+ result = ISC_R_SUCCESS;
+ }
+ }
+ else if (ddns_cb->address.len == 16) {
+ struct ipv6_pool *pool = NULL;
+ struct iasubopt **lease = (struct iasubopt **)(&(ddns_cb->lease));
+ struct in6_addr addr;
+
+ memcpy(&addr, &ddns_cb->address.iabuf, 16);
+ if ((find_ipv6_pool(&pool, D6O_IA_TA, &addr) !=
+ ISC_R_SUCCESS) &&
+ (find_ipv6_pool(&pool, D6O_IA_NA, &addr) !=
+ ISC_R_SUCCESS)) {
+ return(ISC_R_FAILURE);
+ }
+
+ if (iasubopt_hash_lookup(lease, pool->leases,
+ &addr, 16, MDL)) {
+ ddns_cb->scope = &((*lease)->scope);
+ result = ISC_R_SUCCESS;
+ }
+ ipv6_pool_dereference(&pool, MDL);
+ }
+ else {
+ log_fatal("Impossible condition at %s:%d.", MDL);
+ }
+
+ return(result);
+}
+
+isc_result_t
+ddns_write_lease(dhcp_ddns_cb_t *ddns_cb)
+{
+
+ if (ddns_cb->address.len == 4) {
+ struct lease **lease = (struct lease **)(&(ddns_cb->lease));
+
+ write_lease(*lease);
+ ddns_cb->scope = NULL;
+ lease_dereference(lease, MDL);
+ }
+ else if (ddns_cb->address.len == 16) {
+ struct iasubopt **lease = (struct iasubopt **)(&(ddns_cb->lease));
+ /*sar*/
+ /* Hmmm, this seems to be what we do elsewhere, but I'm
+ not sure this is writing the scope info */
+ write_ia((*lease)->ia);
+ ddns_cb->scope = NULL;
+ iasubopt_dereference(lease, MDL);
+ }
+ else {
+ log_fatal("Impossible condition at %s:%d.", MDL);
+ }
+
+ return(ISC_R_SUCCESS);
+}
+#endif
+
+/*
+ * Utility function to update the pointer to the DDNS control block
+ * in a lease.
+ * SUCCESS - able to update the pointer
+ * FAILURE - lease didn't exist or sanity checks failed
+ * lease and lease6 may be empty in which case we attempt to find
+ * the lease from the ddns_cb information.
+ * ddns_cb is the control block to use if a lookup is necessary
+ * ddns_cb_set is the pointer to insert into the lease and may be NULL
+ * The last two arguments may look odd as they will be the same much of the
+ * time, but I need an argument to tell me if I'm setting or clearing in
+ * addition to the address information from the cb to look up the lease.
+ * using the same value twice allows me more flexibility.
+ */
+
+isc_result_t
+ddns_update_lease_ptr(struct lease *lease,
+ struct iasubopt *lease6,
+ dhcp_ddns_cb_t *ddns_cb,
+ dhcp_ddns_cb_t *ddns_cb_set)
+{
+ if (lease != NULL) {
+ lease->ddns_cb = ddns_cb_set;
+ } else if (lease6 != NULL) {
+ lease6->ddns_cb = ddns_cb_set;
+ } else if (ddns_cb->address.len == 4) {
+ struct lease *find_lease = NULL;
+ if (find_lease_by_ip_addr(&find_lease,
+ ddns_cb->address, MDL) != 0) {
+ find_lease->ddns_cb = ddns_cb_set;
+ lease_dereference(&find_lease, MDL);
+ }
+ else {
+ return(ISC_R_FAILURE);
+ }
+ } else if (ddns_cb->address.len == 16) {
+ struct iasubopt *find_lease6 = NULL;
+ struct ipv6_pool *pool = NULL;
+ struct in6_addr addr;
+
+ memcpy(&addr, &ddns_cb->address.iabuf, 16);
+ if ((find_ipv6_pool(&pool, D6O_IA_TA, &addr) !=
+ ISC_R_SUCCESS) &&
+ (find_ipv6_pool(&pool, D6O_IA_NA, &addr) !=
+ ISC_R_SUCCESS)) {
+ return(ISC_R_FAILURE);
+ }
+
+ if (iasubopt_hash_lookup(&find_lease6, pool->leases,
+ &addr, 16, MDL)) {
+ find_lease6->ddns_cb = ddns_cb_set;
+ iasubopt_dereference(&find_lease6, MDL);
+ } else {
+ return(ISC_R_FAILURE);
+ }
+ ipv6_pool_dereference(&pool, MDL);
+ } else {
+ /* shouldn't get here */
+ log_fatal("Impossible condition at %s:%d.", MDL);
+ }
+
+ return(ISC_R_SUCCESS);
+}
+
+void
+ddns_ptr_add(dhcp_ddns_cb_t *ddns_cb,
+ isc_result_t eresult)
+{
+ if (eresult == ISC_R_SUCCESS) {
+ log_info("added reverse map from %.*s to %.*s",
+ (int)ddns_cb->rev_name.len,
+ (const char *)ddns_cb->rev_name.data,
+ (int)ddns_cb->fwd_name.len,
+ (const char *)ddns_cb->fwd_name.data);
+
+ ddns_update_lease_text(ddns_cb, NULL);
+ } else {
+ log_error("unable to add reverse map from %.*s to %.*s: %s",
+ (int)ddns_cb->rev_name.len,
+ (const char *)ddns_cb->rev_name.data,
+ (int)ddns_cb->fwd_name.len,
+ (const char *)ddns_cb->fwd_name.data,
+ isc_result_totext (eresult));
+ }
+
+ ddns_update_lease_ptr(NULL, NULL, ddns_cb, NULL);
+ ddns_cb_free(ddns_cb, MDL);
+ /*
+ * A single DDNS operation may require several calls depending on
+ * the current state as the prerequisites for the first message
+ * may not succeed requiring a second operation and potentially
+ * a ptr operation after that. The commit_leases operation is
+ * invoked at the end of this set of operations in order to require
+ * a single write for all of the changes. We call commit_leases
+ * here rather than immediately after the call to update the lease
+ * text in order to save any previously written data.
+ */
+ commit_leases();
+ return;
+}
+
+/*
+ * action routine when trying to remove a pointer
+ * this will be called after the ddns queries have completed
+ * if we succeeded in removing the pointer we go to the next step (if any)
+ * if not we cleanup and leave.
+ */
+
+void
+ddns_ptr_remove(dhcp_ddns_cb_t *ddns_cb,
+ isc_result_t eresult)
+{
+ isc_result_t result = eresult;
+
+ switch(eresult) {
+ case ISC_R_SUCCESS:
+ log_info("removed reverse map on %.*s",
+ (int)ddns_cb->rev_name.len,
+ (const char *)ddns_cb->rev_name.data);
+ /* fall through */
+ case DNS_R_NXRRSET:
+ case DNS_R_NXDOMAIN:
+ /* No entry is the same as success.
+ * Remove the information from the lease and
+ * continue with any next step */
+ ddns_update_lease_text(ddns_cb, NULL);
+
+ /* trigger any add operation */
+ result = ISC_R_SUCCESS;
+ break;
+
+ default:
+ log_error("can't remove reverse map on %.*s: %s",
+ (int)ddns_cb->rev_name.len,
+ (const char *)ddns_cb->rev_name.data,
+ isc_result_totext (eresult));
+ break;
+ }
+
+ ddns_update_lease_ptr(NULL, NULL, ddns_cb, NULL);
+ ddns_fwd_srv_connector(NULL, NULL, NULL, ddns_cb->next_op, result);
+ ddns_cb_free(ddns_cb, MDL);
+ return;
+}
+
+
+/*
+ * If the first query succeeds, the updater can conclude that it
+ * has added a new name whose only RRs are the A and DHCID RR records.
+ * The A RR update is now complete (and a client updater is finished,
+ * while a server might proceed to perform a PTR RR update).
+ * -- "Interaction between DHCP and DNS"
+ *
+ * If the second query succeeds, the updater can conclude that the current
+ * client was the last client associated with the domain name, and that
+ * the name now contains the updated A RR. The A RR update is now
+ * complete (and a client updater is finished, while a server would
+ * then proceed to perform a PTR RR update).
+ * -- "Interaction between DHCP and DNS"
+ *
+ * If the second query fails with NXRRSET, the updater must conclude
+ * that the client's desired name is in use by another host. At this
+ * juncture, the updater can decide (based on some administrative
+ * configuration outside of the scope of this document) whether to let
+ * the existing owner of the name keep that name, and to (possibly)
+ * perform some name disambiguation operation on behalf of the current
+ * client, or to replace the RRs on the name with RRs that represent
+ * the current client. If the configured policy allows replacement of
+ * existing records, the updater submits a query that deletes the
+ * existing A RR and the existing DHCID RR, adding A and DHCID RRs that
+ * represent the IP address and client-identity of the new client.
+ * -- "Interaction between DHCP and DNS"
+ */
+
+void
+ddns_fwd_srv_add2(dhcp_ddns_cb_t *ddns_cb,
+ isc_result_t eresult)
+{
+ isc_result_t result;
+ const char *logstr = NULL;
+ char ddns_address[
+ sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
+
+ /* Construct a printable form of the address for logging */
+ strcpy(ddns_address, piaddr(ddns_cb->address));
+
+ switch(eresult) {
+ case ISC_R_SUCCESS:
+ log_info("Added new forward map from %.*s to %s",
+ (int)ddns_cb->fwd_name.len,
+ (const char *)ddns_cb->fwd_name.data,
+ ddns_address);
+
+ ddns_update_lease_text(ddns_cb, NULL);
+
+ if ((ddns_cb->flags & DDNS_UPDATE_PTR) != 0) {
+ /* if we have zone information get rid of it */
+ if (ddns_cb->zone != NULL) {
+ ddns_cb_forget_zone(ddns_cb);
+ }
+
+ ddns_cb->state = DDNS_STATE_ADD_PTR;
+ ddns_cb->cur_func = ddns_ptr_add;
+
+ result = ddns_modify_ptr(ddns_cb);
+ if (result == ISC_R_SUCCESS) {
+ return;
+ }
+ }
+ break;
+
+ case DNS_R_YXRRSET:
+ case DNS_R_YXDOMAIN:
+ logstr = "DHCID mismatch, belongs to another client.";
+ break;
+
+ case DNS_R_NXRRSET:
+ case DNS_R_NXDOMAIN:
+ logstr = "Has an address record but no DHCID, not mine.";
+ break;
+
+ default:
+ logstr = isc_result_totext(eresult);
+ break;
+ }
+
+ if (logstr != NULL) {
+ log_error("Forward map from %.*s to %s FAILED: %s",
+ (int)ddns_cb->fwd_name.len,
+ (const char *)ddns_cb->fwd_name.data,
+ ddns_address, logstr);
+ }
+
+ ddns_update_lease_ptr(NULL, NULL, ddns_cb, NULL);
+ ddns_cb_free(ddns_cb, MDL);
+ /*
+ * A single DDNS operation may require several calls depending on
+ * the current state as the prerequisites for the first message
+ * may not succeed requiring a second operation and potentially
+ * a ptr operation after that. The commit_leases operation is
+ * invoked at the end of this set of operations in order to require
+ * a single write for all of the changes. We call commit_leases
+ * here rather than immediately after the call to update the lease
+ * text in order to save any previously written data.
+ */
+ commit_leases();
+ return;
+}
+
+void
+ddns_fwd_srv_add1(dhcp_ddns_cb_t *ddns_cb,
+ isc_result_t eresult)
+{
+ isc_result_t result;
+ char ddns_address[
+ sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
+
+ /* Construct a printable form of the address for logging */
+ strcpy(ddns_address, piaddr(ddns_cb->address));
+
+ switch(eresult) {
+ case ISC_R_SUCCESS:
+ log_info ("Added new forward map from %.*s to %s",
+ (int)ddns_cb->fwd_name.len,
+ (const char *)ddns_cb->fwd_name.data,
+ ddns_address);
+
+ ddns_update_lease_text(ddns_cb, NULL);
+
+ if ((ddns_cb->flags & DDNS_UPDATE_PTR) != 0) {
+ /* if we have zone information get rid of it */
+ if (ddns_cb->zone != NULL) {
+ ddns_cb_forget_zone(ddns_cb);
+ }
+
+ ddns_cb->state = DDNS_STATE_ADD_PTR;
+ ddns_cb->cur_func = ddns_ptr_add;
+
+ result = ddns_modify_ptr(ddns_cb);
+ if (result == ISC_R_SUCCESS) {
+ return;
+ }
+ }
+
+ break;
+
+ case DNS_R_YXDOMAIN:
+ /* we can reuse the zone information */
+ ddns_cb->state = DDNS_STATE_ADD_FW_YXDHCID;
+ ddns_cb->cur_func = ddns_fwd_srv_add2;
+
+ result = ddns_modify_fwd(ddns_cb);
+ if (result == ISC_R_SUCCESS) {
+ return;
+ }
+
+ break;
+
+ default:
+ log_error ("Unable to add forward map from %.*s to %s: %s",
+ (int)ddns_cb->fwd_name.len,
+ (const char *)ddns_cb->fwd_name.data,
+ ddns_address,
+ isc_result_totext (eresult));
+ break;
+ }
+
+ ddns_update_lease_ptr(NULL, NULL, ddns_cb, NULL);
+ ddns_cb_free(ddns_cb, MDL);
+ /*
+ * A single DDNS operation may require several calls depending on
+ * the current state as the prerequisites for the first message
+ * may not succeed requiring a second operation and potentially
+ * a ptr operation after that. The commit_leases operation is
+ * invoked at the end of this set of operations in order to require
+ * a single write for all of the changes. We call commit_leases
+ * here rather than immediately after the call to update the lease
+ * text in order to save any previously written data.
+ */
+ commit_leases();
+ return;
+}
+
+static void
+ddns_fwd_srv_connector(struct lease *lease,
+ struct iasubopt *lease6,
+ struct binding_scope **inscope,
+ dhcp_ddns_cb_t *ddns_cb,
+ isc_result_t eresult)
+{
+ isc_result_t result = ISC_R_FAILURE;
+
+ if (ddns_cb == NULL) {
+ /* nothing to do */
+ return;
+ }
+
+ if (eresult == ISC_R_SUCCESS) {
+ /*
+ * If we have updates dispatch as appropriate,
+ * if not do FQDN binding if desired.
+ */
+
+ if (ddns_cb->flags & DDNS_UPDATE_ADDR) {
+ ddns_cb->state = DDNS_STATE_ADD_FW_NXDOMAIN;
+ ddns_cb->cur_func = ddns_fwd_srv_add1;
+ result = ddns_modify_fwd(ddns_cb);
+ } else if ((ddns_cb->flags & DDNS_UPDATE_PTR) &&
+ (ddns_cb->rev_name.len != 0)) {
+ ddns_cb->state = DDNS_STATE_ADD_PTR;
+ ddns_cb->cur_func = ddns_ptr_add;
+ result = ddns_modify_ptr(ddns_cb);
+ } else {
+ ddns_update_lease_text(ddns_cb, inscope);
+ }
+ }
+
+ if (result == ISC_R_SUCCESS) {
+ ddns_update_lease_ptr(lease, lease6, ddns_cb, ddns_cb);
+ } else {
+ ddns_cb_free(ddns_cb, MDL);
+ }
+
+ return;
+}
+
+/*
+ * If the first query fails, the updater MUST NOT delete the DNS name. It
+ * may be that the host whose lease on the server has expired has moved
+ * to another network and obtained a lease from a different server,
+ * which has caused the client's A RR to be replaced. It may also be
+ * that some other client has been configured with a name that matches
+ * the name of the DHCP client, and the policy was that the last client
+ * to specify the name would get the name. In this case, the DHCID RR
+ * will no longer match the updater's notion of the client-identity of
+ * the host pointed to by the DNS name.
+ * -- "Interaction between DHCP and DNS"
+ */
+
+void
+ddns_fwd_srv_rem2(dhcp_ddns_cb_t *ddns_cb,
+ isc_result_t eresult)
+{
+ if (eresult == ISC_R_SUCCESS) {
+ ddns_update_lease_text(ddns_cb, NULL);
+
+ /* Do the next operation */
+ if ((ddns_cb->flags & DDNS_UPDATE_PTR) != 0) {
+ /* if we have zone information get rid of it */
+ if (ddns_cb->zone != NULL) {
+ ddns_cb_forget_zone(ddns_cb);
+ }
+
+ ddns_cb->state = DDNS_STATE_REM_PTR;
+ ddns_cb->cur_func = ddns_ptr_remove;
+
+ eresult = ddns_modify_ptr(ddns_cb);
+ if (eresult == ISC_R_SUCCESS) {
+ return;
+ }
+ }
+ }
+
+ ddns_update_lease_ptr(NULL, NULL, ddns_cb, NULL);
+ ddns_fwd_srv_connector(NULL, NULL, NULL, ddns_cb->next_op, eresult);
+ ddns_cb_free(ddns_cb, MDL);
+ return;
+}
+
+
+/*
+ * First action routine when trying to remove a fwd
+ * this will be called after the ddns queries have completed
+ * if we succeeded in removing the fwd we go to the next step (if any)
+ * if not we cleanup and leave.
+ */
+
+void
+ddns_fwd_srv_rem1(dhcp_ddns_cb_t *ddns_cb,
+ isc_result_t eresult)
+{
+ isc_result_t result = eresult;
+
+ switch(eresult) {
+ case ISC_R_SUCCESS:
+ /* Do the second step of the FWD removal */
+ ddns_cb->state = DDNS_STATE_REM_FW_NXRR;
+ ddns_cb->cur_func = ddns_fwd_srv_rem2;
+ result = ddns_modify_fwd(ddns_cb);
+ if (result == ISC_R_SUCCESS) {
+ return;
+ }
+ break;
+
+ case DNS_R_NXRRSET:
+ case DNS_R_NXDOMAIN:
+ ddns_update_lease_text(ddns_cb, NULL);
+
+ /* Do the next operation */
+ if ((ddns_cb->flags & DDNS_UPDATE_PTR) != 0) {
+ /* if we have zone information get rid of it */
+ if (ddns_cb->zone != NULL) {
+ ddns_cb_forget_zone(ddns_cb);
+ }
+
+ ddns_cb->state = DDNS_STATE_REM_PTR;
+ ddns_cb->cur_func = ddns_ptr_remove;
+
+ result = ddns_modify_ptr(ddns_cb);
+ if (result == ISC_R_SUCCESS) {
+ return;
+ }
+ }
+ else {
+ /* Trigger the add operation */
+ eresult = ISC_R_SUCCESS;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ ddns_update_lease_ptr(NULL, NULL, ddns_cb, NULL);
+ ddns_fwd_srv_connector(NULL, NULL, NULL, ddns_cb->next_op, eresult);
+ ddns_cb_free(ddns_cb, MDL);
+}
+
+
+/*
+ * Remove relevant entries from DNS.
+ *
+ * Return values:
+ * 0 - badness occurred and we weren't able to do what was wanted
+ * 1 - we were able to do stuff but it's in progress
+ * in both cases any additional block has been passed on to it's handler
+ */
+
int
-ddns_removals(struct lease *lease, struct iasubopt *lease6)
+ddns_removals(struct lease *lease,
+ struct iasubopt *lease6,
+ dhcp_ddns_cb_t *add_ddns_cb)
{
- struct data_string ddns_fwd_name;
- struct data_string ddns_rev_name;
- struct data_string ddns_dhcid;
- isc_result_t rcode;
- struct binding_scope **scope;
- struct iaddr addr;
+ isc_result_t rcode, execute_add = ISC_R_FAILURE;
+ struct binding_scope **scope = NULL;
int result = 0;
- int client_updated = 0;
+ dhcp_ddns_cb_t *ddns_cb;
+ struct data_string leaseid;
+ /* allocate our control block */
+ ddns_cb = ddns_cb_alloc(MDL);
+ if (ddns_cb == NULL) {
+ goto cleanup;
+ }
+
if (lease != NULL) {
scope = &(lease->scope);
- addr = lease->ip_addr;
+ ddns_cb->address = lease->ip_addr;
} else if (lease6 != NULL) {
scope = &(lease6->scope);
- memcpy(addr.iabuf, lease6->addr.s6_addr, 16);
- addr.len = 16;
+ memcpy(&ddns_cb->address.iabuf, lease6->addr.s6_addr, 16);
+ ddns_cb->address.len = 16;
} else
- return 0;
+ goto cleanup;
/* No scope implies that DDNS has not been performed for this lease. */
if (*scope == NULL)
- return 0;
+ goto cleanup;
if (ddns_update_style != 2)
- return 0;
+ goto cleanup;
+
+ /* Assume that we are removing both records */
+ ddns_cb->flags = DDNS_UPDATE_ADDR | DDNS_UPDATE_PTR;
+
+ /* and that we want to do the add call */
+ execute_add = ISC_R_SUCCESS;
/*
* Look up stored names.
*/
- memset (&ddns_fwd_name, 0, sizeof (ddns_fwd_name));
- memset (&ddns_rev_name, 0, sizeof (ddns_rev_name));
- memset (&ddns_dhcid, 0, sizeof (ddns_dhcid));
/*
- * Start the resolver, if necessary.
+ * Find the fwd name and copy it to the control block. If we don't
+ * have it we can't delete the fwd record but we can still try to
+ * remove the ptr record and cleanup the lease information if the
+ * client did the fwd update.
*/
- if (!resolver_inited) {
- minires_ninit (&resolver_state);
- resolver_inited = 1;
- resolver_state.retrans = 1;
- resolver_state.retry = 1;
+ if (!find_bound_string(&ddns_cb->fwd_name, *scope, "ddns-fwd-name")) {
+ /* don't try and delete the A, or do the add */
+ ddns_cb->flags &= ~DDNS_UPDATE_ADDR;
+ execute_add = ISC_R_FAILURE;
+
+ /* Check if client did update */
+ if (find_bound_string(&ddns_cb->fwd_name, *scope,
+ "ddns-client-fqdn")) {
+ ddns_cb->flags |= DDNS_CLIENT_DID_UPDATE;
+ }
}
- /* We need the fwd name whether we are deleting both records or just
- the PTR record, so if it's not there, we can't proceed. */
- if (!find_bound_string(&ddns_fwd_name, *scope, "ddns-fwd-name")) {
- /* If there's no ddns-fwd-name, look for the client fqdn,
- in case the client did the update. */
- if (find_bound_string(&ddns_fwd_name, *scope,
- "ddns-client-fqdn"))
- client_updated = 1;
- goto try_rev;
+ /*
+ * Find the ptr name and copy it to the control block. If we don't
+ * have it this isn't an interim or rfc3??? record so we can't delete
+ * the A record using this mechanism but we can delete the ptr record.
+ * In this case we will attempt to do any requested next step.
+ */
+ memset(&leaseid, 0, sizeof(leaseid));
+ if (!find_bound_string (&leaseid, *scope, "ddns-txt")) {
+ ddns_cb->flags &= ~DDNS_UPDATE_ADDR;
+ } else {
+ if (dhcid_fromlease(&ddns_cb->dhcid, &leaseid) !=
+ ISC_R_SUCCESS) {
+ /* We couldn't convert the dhcid from the lease
+ * version to the dns version. We can't delete
+ * the A record but can continue to the ptr
+ */
+ ddns_cb->flags &= ~DDNS_UPDATE_ADDR;
+ }
+ data_string_forget(&leaseid, MDL);
}
- /* If the ddns-txt binding isn't there, this isn't an interim
- or rfc3??? record, so we can't delete the A record using
- this mechanism, but we can delete the PTR record. */
- if (!find_bound_string (&ddns_dhcid, *scope, "ddns-txt")) {
- result = 1;
- goto try_rev;
+ /*
+ * Find the rev name and copy it to the control block. If we don't
+ * have it we can't get rid of it but we can try to remove the fwd
+ * pointer if desired.
+ */
+ if (!find_bound_string(&ddns_cb->rev_name, *scope, "ddns-rev-name")) {
+ ddns_cb->flags &= ~DDNS_UPDATE_PTR;
}
+
+ /*
+ * If we have a second control block for doing an add
+ * after the remove finished attach it to our control block.
+ */
+ ddns_cb->next_op = add_ddns_cb;
/*
- * Perform removals.
+ * Now that we've collected the information we can try to process it.
+ * If necessary we call an appropriate routine to send a message and
+ * provide it with an action routine to run on the control block given
+ * the results of the message. We have three entry points from here,
+ * one for removing the A record, the next for removing the PTR and
+ * the third for doing any requested add.
*/
- if (ddns_fwd_name.len)
- rcode = ddns_remove_fwd(&ddns_fwd_name, addr, &ddns_dhcid);
- else
- rcode = ISC_R_SUCCESS;
+ if ((ddns_cb->flags & DDNS_UPDATE_ADDR) != 0) {
+ if (ddns_cb->fwd_name.len != 0) {
+ ddns_cb->state = DDNS_STATE_REM_FW_YXDHCID;
+ ddns_cb->cur_func = ddns_fwd_srv_rem1;
+
+ rcode = ddns_modify_fwd(ddns_cb);
+ if (rcode == ISC_R_SUCCESS) {
+ ddns_update_lease_ptr(lease, lease6, ddns_cb,
+ ddns_cb);
+ return(1);
+ }
- if (rcode == ISC_R_SUCCESS) {
- result = 1;
- unset(*scope, "ddns-fwd-name");
- unset(*scope, "ddns-txt");
- try_rev:
- if (find_bound_string(&ddns_rev_name, *scope,
- "ddns-rev-name")) {
- if (ddns_remove_ptr(&ddns_rev_name) == NOERROR) {
- unset(*scope, "ddns-rev-name");
- if (client_updated)
- unset(*scope, "ddns-client-fqdn");
- /* XXX this is to compensate for a bug in
- XXX 3.0rc8, and should be removed before
- XXX 3.0pl1. */
- else if (!ddns_fwd_name.len)
- unset(*scope, "ddns-text");
- } else
- result = 0;
- }
- }
-
- data_string_forget (&ddns_fwd_name, MDL);
- data_string_forget (&ddns_rev_name, MDL);
- data_string_forget (&ddns_dhcid, MDL);
+ /*
+ * We weren't able to process the request tag the
+ * add so we won't execute it.
+ */
+ execute_add = ISC_R_FAILURE;
+ goto cleanup;
+ }
+ else {
+ /*remove info from scope */
+ unset(*scope, "ddns-fwd-name");
+ unset(*scope, "ddns-txt");
+ }
+ }
- return result;
+ if ((ddns_cb->flags & DDNS_UPDATE_PTR) != 0) {
+ ddns_cb->state = DDNS_STATE_REM_PTR;
+ ddns_cb->cur_func = ddns_ptr_remove;
+
+ /*
+ * if execute add isn't success remove the control block so
+ * it won't be processed when the remove completes. We
+ * also arrange to clean it up and get rid of it.
+ */
+ if (execute_add != ISC_R_SUCCESS) {
+ ddns_cb->next_op = NULL;
+ ddns_fwd_srv_connector(lease, lease6, scope,
+ add_ddns_cb, execute_add);
+ add_ddns_cb = NULL;
+ }
+ else {
+ result = 1;
+ }
+
+ rcode = ddns_modify_ptr(ddns_cb);
+ if (rcode == ISC_R_SUCCESS) {
+ ddns_update_lease_ptr(lease, lease6, ddns_cb, ddns_cb);
+ return(result);
+ }
+
+ /* We weren't able to process the request tag the
+ * add so we won't execute it */
+ execute_add = ISC_R_FAILURE;
+ goto cleanup;
+ }
+
+ cleanup:
+ /*
+ * We've gotten here because we didn't need to send a message or
+ * we failed when trying to do so. We send the additional cb
+ * off to handle sending and/or cleanup and cleanup anything
+ * we allocated here.
+ */
+ ddns_fwd_srv_connector(lease, lease6, scope, add_ddns_cb, execute_add);
+ ddns_cb_free(ddns_cb, MDL);
+
+ return(result);
}
#endif /* NSUPDATE */
} \n\
}";
-int ddns_update_style;
#endif /* NSUPDATE */
+int ddns_update_style;
const char *path_dhcpd_conf = _PATH_DHCPD_CONF;
const char *path_dhcpd_db = _PATH_DHCPD_DB;
static isc_result_t verify_auth (omapi_object_t *p, omapi_auth_key_t *a) {
if (a != omapi_key)
- return ISC_R_INVALIDKEY;
+ return DHCP_R_INVALIDKEY;
return ISC_R_SUCCESS;
}
isc_result_t result;
unsigned seed;
struct interface_info *ip;
+#if defined (NSUPDATE)
struct parse *parse;
int lose;
+#endif
int no_dhcpd_conf = 0;
int no_dhcpd_db = 0;
int no_dhcpd_pid = 0;
else if (fd != -1)
close(fd);
+ /* Set up the isc and dns library managers */
+ status = dhcp_context_create();
+ if (status != ISC_R_SUCCESS)
+ log_fatal("Can't initialize context: %s",
+ isc_result_totext(status));
+
/* Set up the client classification system. */
classification_setup ();
struct option_cache *oc;
char *s;
isc_result_t result;
+#if defined (NSUPDATE)
struct parse *parse;
+#endif
int tmp;
/* Now try to get the lease file name. */
} else {
ddns_update_style = DDNS_UPDATE_STYLE_NONE;
}
+#if defined (NSUPDATE)
+ /* We no longer support ad_hoc, tell the user */
+ if (ddns_update_style == DDNS_UPDATE_STYLE_AD_HOC) {
+ log_fatal("ddns-update-style ad_hoc no longer supported");
+ }
+#else
+ /* If we don't have support for updates compiled in tell the user */
+ if (ddns_update_style != DDNS_UPDATE_STYLE_NONE) {
+ log_fatal("Support for ddns-update-style not compiled in");
+ }
+#endif
oc = lookup_option (&server_universe, options, SV_LOG_FACILITY);
if (oc) {
dhcp_io_shutdown_countdown (0);
return ISC_R_SUCCESS;
}
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
* Verify our lq_query structure is empty.
*/
if ((lq_query->data != NULL) || (lq_query->len != 0)) {
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
oc = lookup_option(&dhcpv6_universe, packet->options, D6O_LQ_QUERY);
if ((server_duid_type != DUID_LL) && (server_duid_type != DUID_LLT)) {
log_error("Invalid DUID type %d specified, "
"only LL and LLT types supported", server_duid_type);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
/*
* Verify our client_id structure is empty.
*/
if ((client_id->data != NULL) || (client_id->len != 0)) {
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
oc = lookup_option(&dhcpv6_universe, packet->options, D6O_CLIENTID);
isc_result_t result;
if (requested_addr->len < sizeof(tmp_addr)) {
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
memcpy(&tmp_addr, requested_addr->data, sizeof(tmp_addr));
if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr)) {
isc_result_t result;
if (requested_pref->len < sizeof(tmp_plen) + sizeof(tmp_pref)) {
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
tmp_plen = (int) requested_pref->data[0];
if ((tmp_plen < 3) || (tmp_plen > 128)) {
if (reply->fixed.len < 16) {
log_error("reply_process_ia_na: invalid fixed address.");
- status = ISC_R_INVALIDARG;
+ status = DHCP_R_INVALIDARG;
goto cleanup;
}
renew_lease6(tmp->ipv6_pool, tmp);
schedule_lease_timeout(tmp->ipv6_pool);
+#if defined (NSUPDATE)
/*
* Perform ddns updates.
*/
ddns_updates(reply->packet, NULL, NULL,
tmp, NULL, reply->opt_state);
}
+#endif
}
/* Remove any old ia from the hash. */
renew_lease6(tmp->ipv6_pool, tmp);
schedule_lease_timeout(tmp->ipv6_pool);
+#if defined (NSUPDATE)
/*
* Perform ddns updates.
*/
ddns_updates(reply->packet, NULL, NULL,
tmp, NULL, reply->opt_state);
}
+#endif
}
/* Remove any old ia from the hash. */
if ((reply == NULL) || (reply->shared == NULL) ||
(reply->shared->ipv6_pools == NULL) || (addr == NULL) ||
(reply->lease != NULL))
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
memset(&data_addr, 0, sizeof(data_addr));
data_addr.len = addr->len;
if (reply->static_lease) {
if (reply->host == NULL)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
send_addr.len = 16;
memcpy(send_addr.iabuf, reply->fixed.data, 16);
if ((reply == NULL) || (reply->shared == NULL) ||
(reply->shared->ipv6_pools == NULL) || (pref == NULL) ||
(reply->lease != NULL))
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
memset(&data_pref, 0, sizeof(data_pref));
data_pref.len = 17;
struct iaddrcidrnetlist *l;
if (reply->host == NULL)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
for (l = reply->host->fixed_prefix; l != NULL; l = l->next) {
if (l->cidrnet.bits == reply->preflen)
isc_result_t status;
if ((shared == NULL) || (*shared != NULL) || (packet == NULL))
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
/*
* First, find the link address where the packet from the client
/* In case the peer is already running, immediately try
to establish a connection with it. */
status = dhcp_failover_link_initiate ((omapi_object_t *)state);
- if (status != ISC_R_SUCCESS && status != ISC_R_INCOMPLETE) {
+ if (status != ISC_R_SUCCESS && status != DHCP_R_INCOMPLETE) {
#if defined (DEBUG_FAILOVER_TIMING)
log_info ("add_timeout +90 dhcp_failover_reconnect");
#endif
break;
}
if (!o)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
state = (dhcp_failover_state_t *)o;
obj = (dhcp_failover_link_t *)0;
data_string_forget (&ds, MDL);
dhcp_failover_link_dereference (&obj, MDL);
omapi_addr_list_dereference (&addrs, MDL);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
local_addr.addrtype = AF_INET;
local_addr.addrlen = ds.len;
}
if (!h -> outer || h -> outer -> type != omapi_type_connection)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
c = h -> outer;
/* We get here because we requested that we be woken up after
log_info ("failover: connect: no matching state.");
omapi_disconnect (c, 1);
link -> state = dhcp_flink_disconnected;
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
/* Once we have the entire message, and we've validated
if (link -> imsg_count + 2 > link -> imsg_len) {
log_error ("FAILOVER: message overflow at option code.");
- return ISC_R_PROTOCOLERROR;
+ return DHCP_R_PROTOCOLERROR;
}
/* Get option code. */
if (link -> imsg_count + 2 > link -> imsg_len) {
log_error ("FAILOVER: message overflow at length.");
- return ISC_R_PROTOCOLERROR;
+ return DHCP_R_PROTOCOLERROR;
}
/* Get option length. */
if (link -> imsg_count + option_len > link -> imsg_len) {
log_error ("FAILOVER: message overflow at data.");
- return ISC_R_PROTOCOLERROR;
+ return DHCP_R_PROTOCOLERROR;
}
/* If it's an unknown code, skip over it. */
link -> imsg_count += option_len;
if (link -> imsg_count != link -> imsg_len) {
log_error ("FAILOVER: digest not at end of message");
- return ISC_R_PROTOCOLERROR;
+ return DHCP_R_PROTOCOLERROR;
}
#if defined (DEBUG_FAILOVER_MESSAGES)
log_debug (" option %s len %d",
if (link -> imsg -> options_present & ft_options [option_code].bit) {
log_error ("FAILOVER: duplicate option %s",
ft_options [option_code].name);
- return ISC_R_PROTOCOLERROR;
+ return DHCP_R_PROTOCOLERROR;
}
/* Make sure the option is appropriate for this type of message.
(ft_sizes [ft_options [option_code].type] *
ft_options [option_code].num_present),
ft_options [option_code].name);
- return ISC_R_PROTOCOLERROR;
+ return DHCP_R_PROTOCOLERROR;
}
} else {
failover_option_t *fo;
/* Actually, NO_MEMORY, but if we lose here
we have to drop the connection. */
- return ISC_R_PROTOCOLERROR;
+ return DHCP_R_PROTOCOLERROR;
}
omapi_connection_copyout (ddns -> data, c, op_count);
goto out;
if (op_size > 1 && option_len % op_size) {
log_error ("FAILOVER: option_len %d not %s%d",
option_len, "multiple of ", op_size);
- return ISC_R_PROTOCOLERROR;
+ return DHCP_R_PROTOCOLERROR;
}
op_count = option_len / op_size;
log_error ("FAILOVER: no memory getting %s (%d)",
"option data", op_count);
- return ISC_R_PROTOCOLERROR;
+ return DHCP_R_PROTOCOLERROR;
}
op = fo -> data;
}
log_error ("FAILOVER: option %s: bad type %d",
ft_options [option_code].name,
ft_options [option_code].type);
- return ISC_R_PROTOCOLERROR;
+ return DHCP_R_PROTOCOLERROR;
}
}
out:
omapi_typed_data_t *value)
{
if (h -> type != omapi_type_protocol)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
/* Never valid to set these. */
if (!omapi_ds_strcmp (name, "link-port") ||
dhcp_failover_link_t *link;
if (h -> type != omapi_type_protocol)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
link = (dhcp_failover_link_t *)h;
if (!omapi_ds_strcmp (name, "link-port")) {
{
dhcp_failover_link_t *link;
if (h -> type != dhcp_type_failover_link)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
link = (dhcp_failover_link_t *)h;
if (link -> peer_address)
isc_result_t status;
if (l -> type != dhcp_type_failover_link)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
link = (dhcp_failover_link_t *)l;
status = omapi_connection_put_name (c, "link-port");
return status;
if (!value -> value) {
omapi_value_dereference (&value, MDL);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
status = omapi_get_int_value (&port, value -> value);
if (!value -> value) {
nogood:
omapi_value_dereference (&value, MDL);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
if (value -> value -> type != omapi_datatype_data ||
dhcp_failover_state_t *s, *state = (dhcp_failover_state_t *)0;
if (!o || o -> type != dhcp_type_failover_listener)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
p = (dhcp_failover_listener_t *)o;
/* Not a signal we recognize? */
c = va_arg (ap, omapi_connection_object_t *);
if (!c || c -> type != omapi_type_connection)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
/* See if we can find a failover_state object that
matches this connection. */
omapi_typed_data_t *value)
{
if (h -> type != dhcp_type_failover_listener)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (h -> inner && h -> inner -> type -> set_value)
return (*(h -> inner -> type -> set_value))
omapi_value_t **value)
{
if (h -> type != dhcp_type_failover_listener)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (h -> inner && h -> inner -> type -> get_value)
return (*(h -> inner -> type -> get_value))
dhcp_failover_listener_t *l;
if (h -> type != dhcp_type_failover_listener)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
l = (dhcp_failover_listener_t *)h;
if (l -> next)
dhcp_failover_listener_dereference (&l -> next, file, line);
omapi_object_t *p)
{
if (p -> type != dhcp_type_failover_listener)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (p -> inner && p -> inner -> type -> stuff_values)
return (*(p -> inner -> type -> stuff_values)) (c, id,
return status;
if (!value -> value) {
omapi_value_dereference (&value, MDL);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
status = omapi_get_int_value (&port, value -> value);
struct timeval tv;
if (!o || o -> type != dhcp_type_failover_state)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
state = (dhcp_failover_state_t *)o;
/* Not a signal we recognize? */
break;
}
}
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
isc_result_t dhcp_failover_set_service_state (dhcp_failover_state_t *state)
isc_result_t status;
if (h -> type != dhcp_type_failover_state)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
/* This list of successful returns is completely wrong, but the
fastest way to make dhcpctl do something vaguely sane when
return;
status = dhcp_failover_link_initiate ((omapi_object_t *)state);
- if (status != ISC_R_SUCCESS && status != ISC_R_INCOMPLETE) {
+ if (status != ISC_R_SUCCESS && status != DHCP_R_INCOMPLETE) {
log_info ("failover peer %s: %s", state -> name,
isc_result_totext (status));
#if defined (DEBUG_FAILOVER_TIMING)
isc_result_t status;
if (h -> type != dhcp_type_failover_state)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
s = (dhcp_failover_state_t *)h;
if (!omapi_ds_strcmp (name, "name")) {
dhcp_failover_state_t *s;
if (h -> type != dhcp_type_failover_state)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
s = (dhcp_failover_state_t *)h;
if (s -> link_to_peer)
isc_result_t status;
if (c -> type != omapi_type_connection)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
conn = (omapi_connection_object_t *)c;
if (h -> type != dhcp_type_failover_state)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
s = (dhcp_failover_state_t *)h;
status = omapi_connection_put_name (c, "name");
dhcp_failover_state_t *s;
if (!ref)
- return ISC_R_NOKEYS;
+ return DHCP_R_NOKEYS;
/* First see if we were sent a handle. */
status = omapi_get_value_str (ref, id, "handle", &tv);
/* Don't return the object if the type is wrong. */
if ((*sp) -> type != dhcp_type_failover_state) {
omapi_object_dereference (sp, MDL);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
}
then the query was invalid. */
if (*sp && *sp != (omapi_object_t *)s) {
omapi_object_dereference (sp, MDL);
- return ISC_R_KEYCONFLICT;
+ return DHCP_R_KEYCONFLICT;
} else if (!s) {
if (*sp)
omapi_object_dereference (sp, MDL);
/* If we get to here without finding a lease, no valid key was
specified. */
if (!*sp)
- return ISC_R_NOKEYS;
+ return DHCP_R_NOKEYS;
return ISC_R_SUCCESS;
}
va_end(list);
if (bad_option)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
/* Now send the message header. */
#endif
if (!state || state -> type != dhcp_type_failover_state)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
link = state -> link_to_peer;
if (!link ||
!link -> outer ||
link -> outer -> type != omapi_type_connection)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
status = (dhcp_failover_put_message
(link, link -> outer,
#endif
if (!l || l -> type != dhcp_type_failover_link)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
link = (dhcp_failover_link_t *)l;
state = link -> state_object;
if (!l -> outer || l -> outer -> type != omapi_type_connection)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
status =
(dhcp_failover_put_message
#endif
if (!l || l -> type != dhcp_type_failover_link)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
link = (dhcp_failover_link_t *)l;
if (!l -> outer || l -> outer -> type != omapi_type_connection)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
status =
(dhcp_failover_put_message
#endif
if (!l || l -> type != dhcp_type_failover_link)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
link = (dhcp_failover_link_t *)l;
state = link -> state_object;
if (!l -> outer || l -> outer -> type != omapi_type_connection)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (!message && reason)
message = dhcp_failover_reject_reason_print (reason);
if (!state -> link_to_peer ||
state -> link_to_peer -> type != dhcp_type_failover_link)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
link = (dhcp_failover_link_t *)state -> link_to_peer;
if (!link -> outer || link -> outer -> type != omapi_type_connection)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
transmit_state = lease->desired_binding_state;
if (lease->flags & RESERVED_LEASE) {
if (!state -> link_to_peer ||
state -> link_to_peer -> type != dhcp_type_failover_link)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
link = (dhcp_failover_link_t *)state -> link_to_peer;
if (!link -> outer || link -> outer -> type != omapi_type_connection)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (!message && reason)
message = dhcp_failover_reject_reason_print (reason);
if (!state -> link_to_peer ||
state -> link_to_peer -> type != dhcp_type_failover_link)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
link = (dhcp_failover_link_t *)state -> link_to_peer;
if (!link -> outer || link -> outer -> type != omapi_type_connection)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
status = (dhcp_failover_put_message
(link, link -> outer,
if (!state -> link_to_peer ||
state -> link_to_peer -> type != dhcp_type_failover_link)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
link = (dhcp_failover_link_t *)state -> link_to_peer;
if (!link -> outer || link -> outer -> type != omapi_type_connection)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
status = (dhcp_failover_put_message
(link, link -> outer,
if (!state -> link_to_peer ||
state -> link_to_peer -> type != dhcp_type_failover_link)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
link = (dhcp_failover_link_t *)state -> link_to_peer;
if (!link -> outer || link -> outer -> type != omapi_type_connection)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (state -> curUPD)
return ISC_R_ALREADYRUNNING;
if (!state -> link_to_peer ||
state -> link_to_peer -> type != dhcp_type_failover_link)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
link = (dhcp_failover_link_t *)state -> link_to_peer;
if (!link -> outer || link -> outer -> type != omapi_type_connection)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
/* If there is an UPDREQ in progress, then upgrade to UPDREQALL. */
if (state -> curUPD && (state -> curUPD != FTM_UPDREQ))
if (!state -> link_to_peer ||
state -> link_to_peer -> type != dhcp_type_failover_link)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
link = (dhcp_failover_link_t *)state -> link_to_peer;
if (!link -> outer || link -> outer -> type != omapi_type_connection)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
status = (dhcp_failover_put_message
(link, link -> outer,
*/
if (msg->binding_status == FTS_ACTIVE &&
(chaddr_changed || ident_changed)) {
- ddns_removals(lease, NULL);
+ ddns_removals(lease, NULL, NULL);
if (lease->scope != NULL)
binding_scope_dereference(&lease->scope, MDL);
if (!collections -> classes) {
/* A subclass with no parent is invalid. */
if (cd->name == NULL)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
class_reference (&collections -> classes, cd, MDL);
} else if (cd->name != NULL) { /* regular class */
comp->ends = lease->ends;
comp->next_binding_state = lease->next_binding_state;
+ /* move the ddns control block information */
+ comp->ddns_cb = lease->ddns_cb;
+
just_move_it:
#if defined (FAILOVER_PROTOCOL)
/* Atsfp should be cleared upon any state change that implies
lease -> binding_state == FTS_ACTIVE &&
lease -> next_binding_state != FTS_RELEASED))) {
#if defined (NSUPDATE)
- ddns_removals(lease, NULL);
+ ddns_removals(lease, NULL, NULL);
#endif
if (lease -> on_expiry) {
execute_statements ((struct binding_value **)0,
* release message. This is not true of expiry, where the
* peer may have extended the lease.
*/
- ddns_removals(lease, NULL);
+ ddns_removals(lease, NULL, NULL);
#endif
if (lease -> on_release) {
execute_statements ((struct binding_value **)0,
/* If there are statements to execute when the lease is
released, execute them. */
#if defined (NSUPDATE)
- ddns_removals(lease, NULL);
+ ddns_removals(lease, NULL, NULL);
#endif
if (lease -> on_release) {
execute_statements ((struct binding_value **)0,
{
struct lease *lt = (struct lease *)0;
#if defined (NSUPDATE)
- ddns_removals(lease, NULL);
+ ddns_removals(lease, NULL, NULL);
#endif
if (!lease_copy (<, lease, MDL))
{
struct lease *lt = (struct lease *)0;
#if defined (NSUPDATE)
- ddns_removals(lease, NULL);
+ ddns_removals(lease, NULL, NULL);
#endif
if (!lease_copy (<, lease, MDL))
#include <time.h>
#include <netinet/in.h>
-#include "isc-dhcp/result.h"
-
#include <stdarg.h>
#include "dhcpd.h"
#include "omapip/omapip.h"
#include "omapip/hash.h"
-#include "dst/md5.h"
+#include <isc/md5.h>
HASH_FUNCTIONS(ia, unsigned char *, struct ia_xx, ia_hash_t,
ia_reference, ia_dereference, do_string_hash);
if (iasubopt == NULL) {
log_error("%s(%d): NULL pointer reference", file, line);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
if (*iasubopt != NULL) {
log_error("%s(%d): non-NULL pointer", file, line);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
tmp = dmalloc(sizeof(*tmp), file, line);
const char *file, int line) {
if (iasubopt == NULL) {
log_error("%s(%d): NULL pointer reference", file, line);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
if (*iasubopt != NULL) {
log_error("%s(%d): non-NULL pointer", file, line);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
if (src == NULL) {
log_error("%s(%d): NULL pointer reference", file, line);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
*iasubopt = src;
src->refcnt++;
if ((iasubopt == NULL) || (*iasubopt == NULL)) {
log_error("%s(%d): NULL pointer", file, line);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
tmp = *iasubopt;
if (ia == NULL) {
log_error("%s(%d): NULL pointer reference", file, line);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
if (*ia != NULL) {
log_error("%s(%d): non-NULL pointer", file, line);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
tmp = dmalloc(sizeof(*tmp), file, line);
const char *file, int line) {
if (ia == NULL) {
log_error("%s(%d): NULL pointer reference", file, line);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
if (*ia != NULL) {
log_error("%s(%d): non-NULL pointer", file, line);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
if (src == NULL) {
log_error("%s(%d): NULL pointer reference", file, line);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
*ia = src;
src->refcnt++;
if ((ia == NULL) || (*ia == NULL)) {
log_error("%s(%d): NULL pointer", file, line);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
tmp = *ia;
if (pool == NULL) {
log_error("%s(%d): NULL pointer reference", file, line);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
if (*pool != NULL) {
log_error("%s(%d): non-NULL pointer", file, line);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
tmp = dmalloc(sizeof(*tmp), file, line);
dfree(tmp, file, line);
return ISC_R_NOMEMORY;
}
- if (isc_heap_create(lease_older, lease_index_changed,
+ if (isc_heap_create(dhcp_gbl_ctx.mctx, lease_older, lease_index_changed,
0, &(tmp->active_timeouts)) != ISC_R_SUCCESS) {
iasubopt_free_hash_table(&(tmp->leases), file, line);
dfree(tmp, file, line);
return ISC_R_NOMEMORY;
}
- if (isc_heap_create(lease_older, lease_index_changed,
+ if (isc_heap_create(dhcp_gbl_ctx.mctx, lease_older, lease_index_changed,
0, &(tmp->inactive_timeouts)) != ISC_R_SUCCESS) {
isc_heap_destroy(&(tmp->active_timeouts));
iasubopt_free_hash_table(&(tmp->leases), file, line);
const char *file, int line) {
if (pool == NULL) {
log_error("%s(%d): NULL pointer reference", file, line);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
if (*pool != NULL) {
log_error("%s(%d): non-NULL pointer", file, line);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
if (src == NULL) {
log_error("%s(%d): NULL pointer reference", file, line);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
*pool = src;
src->refcnt++;
if ((pool == NULL) || (*pool == NULL)) {
log_error("%s(%d): NULL pointer", file, line);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
tmp = *pool;
build_address6(struct in6_addr *addr,
const struct in6_addr *net_start_addr, int net_bits,
const struct data_string *input) {
- MD5_CTX ctx;
+ isc_md5_t ctx;
int net_bytes;
int i;
char *str;
* Yes, we know MD5 isn't cryptographically sound.
* No, we don't care.
*/
- MD5_Init(&ctx);
- MD5_Update(&ctx, input->data, input->len);
- MD5_Final((unsigned char *)addr, &ctx);
+ isc_md5_init(&ctx);
+ isc_md5_update(&ctx, input->data, input->len);
+ isc_md5_final(&ctx, (unsigned char *)addr);
/*
* Copy the [0..128] network bits over.
build_temporary6(struct in6_addr *addr,
const struct in6_addr *net_start_addr, int net_bits,
const struct data_string *input) {
- static u_int8_t history[8];
+ static u_int32_t history[2];
static u_int32_t counter = 0;
- MD5_CTX ctx;
+ isc_md5_t ctx;
unsigned char md[16];
- extern int dst_s_random(u_int8_t *, unsigned);
/*
* First time/time to reseed.
* Please use a good pseudo-random generator here!
*/
if (counter == 0) {
- if (dst_s_random(history, 8) != 8)
- log_fatal("Random failed.");
+ isc_random_get(&history[0]);
+ isc_random_get(&history[1]);
}
/*
* Use MD5 as recommended by RFC 4941.
*/
- MD5_Init(&ctx);
- MD5_Update(&ctx, history, 8UL);
- MD5_Update(&ctx, input->data, input->len);
- MD5_Final(md, &ctx);
+ isc_md5_init(&ctx);
+ isc_md5_update(&ctx, (unsigned char *)&history[0], 8UL);
+ isc_md5_update(&ctx, input->data, input->len);
+ isc_md5_final(&ctx, md);
/*
* Build the address.
/*
* Save history for the next call.
*/
- memcpy(history, md + 8, 8);
+ memcpy((unsigned char *)&history[0], md + 8, 8);
counter++;
}
case D6O_IA_PD:
/* prefix */
log_error("create_lease6: prefix pool.");
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
default:
log_error("create_lease6: untyped pool.");
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
/*
old_heap_index = lease->heap_index;
insert_result = isc_heap_insert(pool->inactive_timeouts, lease);
if (insert_result == ISC_R_SUCCESS) {
+#if defined (NSUPDATE)
/* Process events upon expiration. */
if (pool->pool_type != D6O_IA_PD) {
- ddns_removals(NULL, lease);
+ ddns_removals(NULL, lease, NULL);
}
+#endif
/* Binding scopes are no longer valid after expiry or
* release.
if (leasep == NULL) {
log_error("%s(%d): NULL pointer reference", MDL);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
if (*leasep != NULL) {
log_error("%s(%d): non-NULL pointer", MDL);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
if (pool->num_active > 0) {
const struct in6_addr *net_start_pref,
int pool_bits, int pref_bits,
const struct data_string *input) {
- MD5_CTX ctx;
+ isc_md5_t ctx;
int net_bytes;
int i;
char *str;
* Yes, we know MD5 isn't cryptographically sound.
* No, we don't care.
*/
- MD5_Init(&ctx);
- MD5_Update(&ctx, input->data, input->len);
- MD5_Final((unsigned char *)pref, &ctx);
+ isc_md5_init(&ctx);
+ isc_md5_update(&ctx, input->data, input->len);
+ isc_md5_final(&ctx, (unsigned char *)pref);
/*
* Copy the network bits over.
* DH: Do we want to do this on a special 'depref'
* timer rather than expiration timer?
*/
+#if defined (NSUPDATE)
if (pool->pool_type != D6O_IA_PD) {
- ddns_removals(NULL, lease);
+ ddns_removals(NULL, lease, NULL);
}
+#endif
write_ia(lease->ia);
if (pool == NULL) {
log_error("%s(%d): NULL pointer reference", MDL);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
if (*pool != NULL) {
log_error("%s(%d): non-NULL pointer", MDL);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
for (i=0; i<num_pools; i++) {
* Test 1: Error iaaddr manipulation.
*/
/* bogus allocate arguments */
- if (iasubopt_allocate(NULL, MDL) != ISC_R_INVALIDARG) {
+ if (iasubopt_allocate(NULL, MDL) != DHCP_R_INVALIDARG) {
printf("ERROR: iasubopt_allocate() %s:%d\n", MDL);
return 1;
}
iaaddr = (struct iasubopt *)1;
- if (iasubopt_allocate(&iaaddr, MDL) != ISC_R_INVALIDARG) {
+ if (iasubopt_allocate(&iaaddr, MDL) != DHCP_R_INVALIDARG) {
printf("ERROR: iasubopt_allocate() %s:%d\n", MDL);
return 1;
}
printf("ERROR: iasubopt_allocate() %s:%d\n", MDL);
return 1;
}
- if (iasubopt_reference(NULL, iaaddr, MDL) != ISC_R_INVALIDARG) {
+ if (iasubopt_reference(NULL, iaaddr, MDL) != DHCP_R_INVALIDARG) {
printf("ERROR: iasubopt_reference() %s:%d\n", MDL);
return 1;
}
iaaddr_copy = (struct iasubopt *)1;
- if (iasubopt_reference(&iaaddr_copy, iaaddr, MDL) != ISC_R_INVALIDARG) {
+ if (iasubopt_reference(&iaaddr_copy, iaaddr,
+ MDL) != DHCP_R_INVALIDARG) {
printf("ERROR: iasubopt_reference() %s:%d\n", MDL);
return 1;
}
iaaddr_copy = NULL;
- if (iasubopt_reference(&iaaddr_copy, NULL, MDL) != ISC_R_INVALIDARG) {
+ if (iasubopt_reference(&iaaddr_copy, NULL, MDL) != DHCP_R_INVALIDARG) {
printf("ERROR: iasubopt_reference() %s:%d\n", MDL);
return 1;
}
}
/* bogus dereference arguments */
- if (iasubopt_dereference(NULL, MDL) != ISC_R_INVALIDARG) {
+ if (iasubopt_dereference(NULL, MDL) != DHCP_R_INVALIDARG) {
printf("ERROR: iasubopt_dereference() %s:%d\n", MDL);
return 1;
}
iaaddr = NULL;
- if (iasubopt_dereference(&iaaddr, MDL) != ISC_R_INVALIDARG) {
+ if (iasubopt_dereference(&iaaddr, MDL) != DHCP_R_INVALIDARG) {
printf("ERROR: iasubopt_dereference() %s:%d\n", MDL);
return 1;
}
* Test 4: Errors in ia_na.
*/
/* bogus allocate arguments */
- if (ia_allocate(NULL, 123, "", 0, MDL) != ISC_R_INVALIDARG) {
+ if (ia_allocate(NULL, 123, "", 0, MDL) != DHCP_R_INVALIDARG) {
printf("ERROR: ia_allocate() %s:%d\n", MDL);
return 1;
}
ia_na = (struct ia_na *)1;
- if (ia_allocate(&ia_na, 456, "", 0, MDL) != ISC_R_INVALIDARG) {
+ if (ia_allocate(&ia_na, 456, "", 0, MDL) != DHCP_R_INVALIDARG) {
printf("ERROR: ia_allocate() %s:%d\n", MDL);
return 1;
}
printf("ERROR: ia_allocate() %s:%d\n", MDL);
return 1;
}
- if (ia_reference(NULL, ia_na, MDL) != ISC_R_INVALIDARG) {
+ if (ia_reference(NULL, ia_na, MDL) != DHCP_R_INVALIDARG) {
printf("ERROR: ia_reference() %s:%d\n", MDL);
return 1;
}
ia_na_copy = (struct ia_na *)1;
- if (ia_reference(&ia_na_copy, ia_na, MDL) != ISC_R_INVALIDARG) {
+ if (ia_reference(&ia_na_copy, ia_na, MDL) != DHCP_R_INVALIDARG) {
printf("ERROR: ia_reference() %s:%d\n", MDL);
return 1;
}
ia_na_copy = NULL;
- if (ia_reference(&ia_na_copy, NULL, MDL) != ISC_R_INVALIDARG) {
+ if (ia_reference(&ia_na_copy, NULL, MDL) != DHCP_R_INVALIDARG) {
printf("ERROR: ia_reference() %s:%d\n", MDL);
return 1;
}
}
/* bogus dereference arguments */
- if (ia_dereference(NULL, MDL) != ISC_R_INVALIDARG) {
+ if (ia_dereference(NULL, MDL) != DHCP_R_INVALIDARG) {
printf("ERROR: ia_dereference() %s:%d\n", MDL);
return 1;
}
/*
* Test 6: Error ipv6_pool manipulation
*/
- if (ipv6_pool_allocate(NULL, 0, &addr, 64, 128, MDL) != ISC_R_INVALIDARG) {
+ if (ipv6_pool_allocate(NULL, 0, &addr,
+ 64, 128, MDL) != DHCP_R_INVALIDARG) {
printf("ERROR: ipv6_pool_allocate() %s:%d\n", MDL);
return 1;
}
pool = (struct ipv6_pool *)1;
- if (ipv6_pool_allocate(&pool, 0, &addr, 64, 128, MDL) != ISC_R_INVALIDARG) {
+ if (ipv6_pool_allocate(&pool, 0, &addr,
+ 64, 128, MDL) != DHCP_R_INVALIDARG) {
printf("ERROR: ipv6_pool_allocate() %s:%d\n", MDL);
return 1;
}
- if (ipv6_pool_reference(NULL, pool, MDL) != ISC_R_INVALIDARG) {
+ if (ipv6_pool_reference(NULL, pool, MDL) != DHCP_R_INVALIDARG) {
printf("ERROR: ipv6_pool_reference() %s:%d\n", MDL);
return 1;
}
pool_copy = (struct ipv6_pool *)1;
- if (ipv6_pool_reference(&pool_copy, pool, MDL) != ISC_R_INVALIDARG) {
+ if (ipv6_pool_reference(&pool_copy, pool, MDL) != DHCP_R_INVALIDARG) {
printf("ERROR: ipv6_pool_reference() %s:%d\n", MDL);
return 1;
}
pool_copy = NULL;
- if (ipv6_pool_reference(&pool_copy, NULL, MDL) != ISC_R_INVALIDARG) {
+ if (ipv6_pool_reference(&pool_copy, NULL, MDL) != DHCP_R_INVALIDARG) {
printf("ERROR: ipv6_pool_reference() %s:%d\n", MDL);
return 1;
}
- if (ipv6_pool_dereference(NULL, MDL) != ISC_R_INVALIDARG) {
+ if (ipv6_pool_dereference(NULL, MDL) != DHCP_R_INVALIDARG) {
printf("ERROR: ipv6_pool_dereference() %s:%d\n", MDL);
return 1;
}
- if (ipv6_pool_dereference(&pool_copy, MDL) != ISC_R_INVALIDARG) {
+ if (ipv6_pool_dereference(&pool_copy, MDL) != DHCP_R_INVALIDARG) {
printf("ERROR: ipv6_pool_dereference() %s:%d\n", MDL);
return 1;
}
isc_result_t status;
if (h -> type != dhcp_type_lease)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
lease = (struct lease *)h;
/* We're skipping a lot of things it might be interesting to
return status;
if (bar < 1 || bar > FTS_LAST)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
nls = binding_state_names [bar - 1];
if (lease -> binding_state >= 1 &&
lease -> binding_state <= FTS_LAST)
piaddr (lease -> ip_addr), ols, nls);
return ISC_R_IOERROR;
}
- return ISC_R_UNCHANGED;
+ return DHCP_R_UNCHANGED;
} else if (!omapi_ds_strcmp (name, "ip-address")) {
return ISC_R_NOPERM;
} else if (!omapi_ds_strcmp (name, "dhcp-client-identifier")) {
- return ISC_R_UNCHANGED; /* XXX take change. */
+ return DHCP_R_UNCHANGED; /* XXX take change. */
} else if (!omapi_ds_strcmp (name, "hostname")) {
- return ISC_R_UNCHANGED; /* XXX take change. */
+ return DHCP_R_UNCHANGED; /* XXX take change. */
} else if (!omapi_ds_strcmp (name, "client-hostname")) {
- return ISC_R_UNCHANGED; /* XXX take change. */
+ return DHCP_R_UNCHANGED; /* XXX take change. */
} else if (!omapi_ds_strcmp (name, "host")) {
- return ISC_R_UNCHANGED; /* XXX take change. */
+ return DHCP_R_UNCHANGED; /* XXX take change. */
} else if (!omapi_ds_strcmp (name, "subnet")) {
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
} else if (!omapi_ds_strcmp (name, "pool")) {
return ISC_R_NOPERM;
} else if (!omapi_ds_strcmp (name, "starts")) {
u_int8_t oldflags;
if (value->type != omapi_datatype_data)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
oldflags = lease->flags;
lease->flags = (value->u.buffer.value[0] & EPHEMERAL_FLAGS) |
}
return ISC_R_SUCCESS;
} else if (!omapi_ds_strcmp (name, "billing-class")) {
- return ISC_R_UNCHANGED; /* XXX carefully allow change. */
+ return DHCP_R_UNCHANGED; /* XXX carefully allow change. */
} else if (!omapi_ds_strcmp (name, "hardware-address")) {
- return ISC_R_UNCHANGED; /* XXX take change. */
+ return DHCP_R_UNCHANGED; /* XXX take change. */
} else if (!omapi_ds_strcmp (name, "hardware-type")) {
- return ISC_R_UNCHANGED; /* XXX take change. */
+ return DHCP_R_UNCHANGED; /* XXX take change. */
} else if (lease -> scope) {
status = binding_scope_set_value (lease -> scope, 0, name, value);
if (status == ISC_R_SUCCESS) {
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)
+ if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED)
return status;
}
isc_result_t status;
if (h -> type != dhcp_type_lease)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
lease = (struct lease *)h;
if (!omapi_ds_strcmp (name, "state"))
if (status == ISC_R_SUCCESS)
return status;
}
- return ISC_R_UNKNOWNATTRIBUTE;
+ return DHCP_R_UNKNOWNATTRIBUTE;
}
isc_result_t dhcp_lease_destroy (omapi_object_t *h, const char *file, int line)
struct lease *lease;
if (h -> type != dhcp_type_lease)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
lease = (struct lease *)h;
if (lease -> uid)
isc_result_t status;
if (h -> type != dhcp_type_lease)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
lease = (struct lease *)h;
if (!strcmp (name, "updated"))
u_int8_t flagbuf;
if (h -> type != dhcp_type_lease)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
lease = (struct lease *)h;
/* Write out all the values. */
struct lease *lease;
if (!ref)
- return ISC_R_NOKEYS;
+ return DHCP_R_NOKEYS;
/* First see if we were sent a handle. */
status = omapi_get_value_str (ref, id, "handle", &tv);
/* Don't return the object if the type is wrong. */
if ((*lp) -> type != dhcp_type_lease) {
omapi_object_dereference (lp, MDL);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
}
if (*lp && *lp != (omapi_object_t *)lease) {
omapi_object_dereference (lp, MDL);
lease_dereference (&lease, MDL);
- return ISC_R_KEYCONFLICT;
+ return DHCP_R_KEYCONFLICT;
} else if (!lease) {
if (*lp)
omapi_object_dereference (lp, MDL);
if (*lp && *lp != (omapi_object_t *)lease) {
omapi_object_dereference (lp, MDL);
lease_dereference (&lease, MDL);
- return ISC_R_KEYCONFLICT;
+ return DHCP_R_KEYCONFLICT;
} else if (!lease) {
if (*lp)
omapi_object_dereference (lp, MDL);
} else if (lease -> n_uid) {
if (*lp)
omapi_object_dereference (lp, MDL);
- return ISC_R_MULTIPLE;
+ return DHCP_R_MULTIPLE;
} else if (!*lp) {
/* XXX fix so that hash lookup itself creates
XXX the reference. */
(tv -> value -> u.buffer.value[2] != 0)) {
omapi_value_dereference (&tv, MDL);
dfree (haddr, MDL);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
haddr[0] = tv -> value -> u.buffer.value[3];
} else {
omapi_value_dereference (&tv, MDL);
dfree (haddr, MDL);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
omapi_value_dereference (&tv, MDL);
if (*lp && *lp != (omapi_object_t *)lease) {
omapi_object_dereference (lp, MDL);
lease_dereference (&lease, MDL);
- return ISC_R_KEYCONFLICT;
+ return DHCP_R_KEYCONFLICT;
} else if (!lease) {
if (*lp)
omapi_object_dereference (lp, MDL);
if (*lp)
omapi_object_dereference (lp, MDL);
lease_dereference (&lease, MDL);
- return ISC_R_MULTIPLE;
+ return DHCP_R_MULTIPLE;
} else if (!*lp) {
/* XXX fix so that hash lookup itself creates
XXX the reference. */
/* If we get to here without finding a lease, no valid key was
specified. */
if (!*lp)
- return ISC_R_NOKEYS;
+ return DHCP_R_NOKEYS;
return ISC_R_SUCCESS;
}
isc_result_t status;
if (h -> type != dhcp_type_host)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
host = (struct host_decl *)h;
/* XXX For now, we can only set these values on new host objects.
value -> u.buffer.len);
host -> name [value -> u.buffer.len] = 0;
} else
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
return ISC_R_SUCCESS;
}
group, MDL);
group_object_dereference (&group, MDL);
} else
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
return ISC_R_SUCCESS;
}
value -> type == omapi_datatype_string)) {
if (value -> u.buffer.len >
(sizeof host -> interface.hbuf) - 1)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
memcpy (&host -> interface.hbuf [1],
value -> u.buffer.value,
value -> u.buffer.len);
host -> interface.hlen = value -> u.buffer.len + 1;
} else
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
return ISC_R_SUCCESS;
}
if (value && (value -> type == omapi_datatype_data &&
value -> u.buffer.len == sizeof type)) {
if (value -> u.buffer.len > sizeof type)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
memcpy (&type,
value -> u.buffer.value,
value -> u.buffer.len);
} else if (value -> type == omapi_datatype_int)
type = value -> u.integer;
else
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
host -> interface.hbuf [0] = type;
return ISC_R_SUCCESS;
}
value -> u.buffer.len);
host -> client_identifier.len = value -> u.buffer.len;
} else
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
return ISC_R_SUCCESS;
}
}
data_string_forget (&ds, MDL);
} else
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
return ISC_R_SUCCESS;
}
(&host -> group -> statements, parse, &lose,
context_any))) {
end_parse (&parse);
- return ISC_R_BADPARSE;
+ return DHCP_R_BADPARSE;
}
end_parse (&parse);
} else
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
return ISC_R_SUCCESS;
}
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)
+ if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED)
return status;
}
- return ISC_R_UNKNOWNATTRIBUTE;
+ return DHCP_R_UNKNOWNATTRIBUTE;
}
struct data_string ip_addrs;
if (h -> type != dhcp_type_host)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
host = (struct host_decl *)h;
if (!omapi_ds_strcmp (name, "ip-addresses")) {
if (status == ISC_R_SUCCESS)
return status;
}
- return ISC_R_UNKNOWNATTRIBUTE;
+ return DHCP_R_UNKNOWNATTRIBUTE;
}
isc_result_t dhcp_host_destroy (omapi_object_t *h, const char *file, int line)
struct host_decl *host;
if (h -> type != dhcp_type_host)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
host = (struct host_decl *)h;
#if defined (DEBUG_MEMORY_LEAKAGE) || \
int updatep = 0;
if (h -> type != dhcp_type_host)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
host = (struct host_decl *)h;
if (!strcmp (name, "updated")) {
/* There must be a client identifier of some sort. */
if (host -> interface.hlen == 0 &&
!host -> client_identifier.len)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
if (!host -> name) {
char hnbuf [64];
struct data_string ip_addrs;
if (h -> type != dhcp_type_host)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
host = (struct host_decl *)h;
/* Write out all the values. */
struct host_decl *host;
if (!ref)
- return ISC_R_NOKEYS;
+ return DHCP_R_NOKEYS;
/* First see if we were sent a handle. */
status = omapi_get_value_str (ref, id, "handle", &tv);
/* Don't return the object if the type is wrong. */
if ((*lp) -> type != dhcp_type_host) {
omapi_object_dereference (lp, MDL);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
if (((struct host_decl *)(*lp)) -> flags & HOST_DECL_DELETED) {
omapi_object_dereference (lp, MDL);
omapi_object_dereference (lp, MDL);
if (host)
host_dereference (&host, MDL);
- return ISC_R_KEYCONFLICT;
+ return DHCP_R_KEYCONFLICT;
} else if (!host || (host -> flags & HOST_DECL_DELETED)) {
if (*lp)
omapi_object_dereference (lp, MDL);
(tv -> value -> u.buffer.value[2] != 0)) {
omapi_value_dereference (&tv, MDL);
dfree (haddr, MDL);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
haddr[0] = tv -> value -> u.buffer.value[3];
} else {
omapi_value_dereference (&tv, MDL);
dfree (haddr, MDL);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
omapi_value_dereference (&tv, MDL);
omapi_object_dereference (lp, MDL);
if (host)
host_dereference (&host, MDL);
- return ISC_R_KEYCONFLICT;
+ return DHCP_R_KEYCONFLICT;
} else if (!host || (host -> flags & HOST_DECL_DELETED)) {
if (*lp)
omapi_object_dereference (lp, MDL);
omapi_object_dereference (lp, MDL);
if (host)
host_dereference (&host, MDL);
- return ISC_R_KEYCONFLICT;
+ return DHCP_R_KEYCONFLICT;
} else if (!host || (host -> flags &
HOST_DECL_DELETED)) {
if (host)
omapi_object_dereference (lp, MDL);
if (host)
host_dereference (&host, MDL);
- return ISC_R_KEYCONFLICT;
+ return DHCP_R_KEYCONFLICT;
} else if (!host || (host -> flags & HOST_DECL_DELETED)) {
if (host)
host_dereference (&host, MDL);
/* If we get to here without finding a host, no valid key was
specified. */
if (!*lp)
- return ISC_R_NOKEYS;
+ return DHCP_R_NOKEYS;
return ISC_R_SUCCESS;
}
{
struct host_decl *hp;
if (lp -> type != dhcp_type_host)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
hp = (struct host_decl *)lp;
#ifdef DEBUG_OMAPI
isc_result_t status;
if (h -> type != dhcp_type_pool)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
pool = (struct pool *)h;
/* No values to set yet. */
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)
+ if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED)
return status;
}
- return ISC_R_UNKNOWNATTRIBUTE;
+ return DHCP_R_UNKNOWNATTRIBUTE;
}
isc_result_t status;
if (h -> type != dhcp_type_pool)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
pool = (struct pool *)h;
/* No values to get yet. */
if (status == ISC_R_SUCCESS)
return status;
}
- return ISC_R_UNKNOWNATTRIBUTE;
+ return DHCP_R_UNKNOWNATTRIBUTE;
}
isc_result_t dhcp_pool_destroy (omapi_object_t *h, const char *file, int line)
#endif
if (h -> type != dhcp_type_pool)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
pool = (struct pool *)h;
#if defined (DEBUG_MEMORY_LEAKAGE) || \
int updatep = 0;
if (h -> type != dhcp_type_pool)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
pool = (struct pool *)h;
/* Can't write pools yet. */
isc_result_t status;
if (h -> type != dhcp_type_pool)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
pool = (struct pool *)h;
/* Can't stuff pool values yet. */
/* If we get to here without finding a pool, no valid key was
specified. */
if (!*lp)
- return ISC_R_NOKEYS;
+ return DHCP_R_NOKEYS;
return ISC_R_SUCCESS;
}
memcpy(class->name, value->u.buffer.value,
value->u.buffer.len);
} else
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
return ISC_R_SUCCESS;
}
value->u.buffer.value, value->u.buffer.len);
class->hash_string.len = value->u.buffer.len;
} else
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
return ISC_R_SUCCESS;
}
group_reference(&class->group, group->group, MDL);
group_object_dereference(&group, MDL);
} else
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
return ISC_R_SUCCESS;
}
class->submatch->op = expr_hardware;
} else
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
} else
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
return ISC_R_SUCCESS;
}
value->type == omapi_datatype_string) {
/* XXXJAB support 'options' here. */
/* XXXJAB specifically 'bootfile-name' */
- return ISC_R_INVALIDARG; /* XXX tmp */
+ return DHCP_R_INVALIDARG; /* XXX tmp */
} else
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
return ISC_R_SUCCESS;
}
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)
+ if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED)
return status;
}
- return ISC_R_UNKNOWNATTRIBUTE;
+ return DHCP_R_UNKNOWNATTRIBUTE;
}
omapi_typed_data_t *value)
{
if (h -> type != dhcp_type_class)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
return class_set_value(h, id, name, value);
}
isc_result_t status;
if (h -> type != dhcp_type_class)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
class = (struct class *)h;
if (!omapi_ds_strcmp (name, "name"))
if (status == ISC_R_SUCCESS)
return status;
}
- return ISC_R_UNKNOWNATTRIBUTE;
+ return DHCP_R_UNKNOWNATTRIBUTE;
}
isc_result_t dhcp_class_destroy (omapi_object_t *h, const char *file, int line)
struct class *class;
if (h -> type != dhcp_type_class && h -> type != dhcp_type_subclass)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
class = (struct class *)h;
#if defined (DEBUG_MEMORY_LEAKAGE) || \
if (!issubclass) {
if (class -> name == 0 || strlen(class -> name) == 0) {
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
} else {
if (class -> superclass == 0) {
- return ISC_R_INVALIDARG; /* didn't give name */
+ return DHCP_R_INVALIDARG; /* didn't give name */
}
if (class -> hash_string.data == NULL) {
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
}
const char *name, va_list ap)
{
if (h -> type != dhcp_type_class)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
return class_signal_handler(h, name, ap);
}
isc_result_t status;
if (h -> type != dhcp_type_class)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
class = (struct class *)h;
/* Can't stuff class values yet. */
"hashstring", &hv);
if (status != ISC_R_SUCCESS) {
class_dereference(&class, MDL);
- return ISC_R_NOKEYS;
+ return DHCP_R_NOKEYS;
}
if (hv -> value -> type != omapi_datatype_data &&
hv -> value -> type != omapi_datatype_string) {
class_dereference(&class, MDL);
omapi_value_dereference (&hv, MDL);
- return ISC_R_NOKEYS;
+ return DHCP_R_NOKEYS;
}
class_hash_lookup (&subclass, class -> hash,
/* Don't return the object if the type is wrong. */
if (class -> type != typewanted) {
class_dereference (&class, MDL);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
if (class -> flags & CLASS_DECL_DELETED) {
return ISC_R_SUCCESS;
}
- return ISC_R_NOKEYS;
+ return DHCP_R_NOKEYS;
}
{
struct class *cp;
if (lp -> type != dhcp_type_class)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
cp = (struct class *)lp;
#ifdef DEBUG_OMAPI
omapi_typed_data_t *value)
{
if (h -> type != dhcp_type_subclass)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
return class_set_value(h, id, name, value);
}
isc_result_t status;
if (h -> type != dhcp_type_class)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
subclass = (struct class *)h;
if (subclass -> name != 0)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
/* XXXJAB No values to get yet. */
if (status == ISC_R_SUCCESS)
return status;
}
- return ISC_R_UNKNOWNATTRIBUTE;
+ return DHCP_R_UNKNOWNATTRIBUTE;
}
isc_result_t dhcp_subclass_signal_handler (omapi_object_t *h,
const char *name, va_list ap)
{
if (h -> type != dhcp_type_subclass)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
return class_signal_handler(h, name, ap);
}
isc_result_t status;
if (h -> type != dhcp_type_class)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
subclass = (struct class *)h;
if (subclass -> name != 0)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
/* Can't stuff subclass values yet. */
struct class *cp;
if (lp -> type != dhcp_type_subclass)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
cp = (struct class *)lp;
#ifdef DEBUG_OMAPI
bp = find_binding (scope, nname);
if (!bp && !createp) {
dfree (nname, MDL);
- return ISC_R_UNKNOWNATTRIBUTE;
+ return DHCP_R_UNKNOWNATTRIBUTE;
}
if (!value) {
dfree (nname, MDL);
if (!bp)
- return ISC_R_UNKNOWNATTRIBUTE;
+ return DHCP_R_UNKNOWNATTRIBUTE;
binding_value_dereference (&bp -> value, MDL);
return ISC_R_SUCCESS;
}
case omapi_datatype_object:
binding_value_dereference (&nv, MDL);
dfree (nname, MDL);
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
}
if (!bp) {
bp = find_binding (scope, nname);
dfree (nname, MDL);
if (!bp)
- return ISC_R_UNKNOWNATTRIBUTE;
+ return DHCP_R_UNKNOWNATTRIBUTE;
if (!bp -> value)
- return ISC_R_UNKNOWNATTRIBUTE;
+ return DHCP_R_UNKNOWNATTRIBUTE;
switch (bp -> value -> type) {
case binding_boolean:
/* Can't return values for these two (yet?). */
case binding_dns:
case binding_function:
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
default:
log_fatal ("Impossible case at %s:%d.", MDL);
{
struct lease *lease;
if (lo -> type != dhcp_type_lease)
- return ISC_R_INVALIDARG;
+ return DHCP_R_INVALIDARG;
lease = (struct lease *)lo;
memset (lease, 0, sizeof (struct lease));
lease -> next = free_leases;
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: t_api.c,v 1.3 2009/01/22 00:43:58 sar Exp $ */
+/* $Id: t_api.c,v 1.4 2009/10/28 04:12:30 sar Exp $ */
/*! \file */
#include <sys/wait.h>
-#include <isc-dhcp/boolean.h>
-#include <isc-dhcp/commandline.h>
-#include <isc-dhcp/print.h>
-#include <isc-dhcp/string.h>
-#include <isc-dhcp/mem.h>
+#include <isc/boolean.h>
+#include <isc/commandline.h>
+#include <isc/print.h>
+#include <isc/string.h>
+#include <isc/mem.h>
#ifdef DNS_SUPPORT
#include <dns/compress.h>
-#include <dns/result.h>
+#include <omapip/result.h>
#endif /* DNS_SUPPORT */
#ifndef BIND_SUPPORT
--- /dev/null
+#!/bin/sh
+#
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# 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 ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC 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.
+
+# $Id: bind.sh,v 1.2 2009/10/28 04:12:30 sar Exp $
+
+# Get the bind distribution for the libraries
+# This script is used to build the DHCP distribution and shouldn't be shipped
+#
+# Usage: sh bind.sh
+#
+# Currently no arguments
+#
+
+topdir=`pwd`
+binddir=$topdir/bind
+
+case $# in
+ 1)
+ case "$1" in
+ 4.2.0) BINDTAG=v9_7_0b1 ;;
+ 4.1.2) BINDTAG=v9_7_0b1 ;;
+ *) echo "usage: sh bind.sh <version>" >&2
+ exit 1
+ ;;
+ esac
+ ;;
+ *) echo "usage: sh bind.sh <version>" >&2
+ exit 1
+ ;;
+esac
+
+# Delete all previous bind stuff
+rm -rf bind
+
+# Make and move to our directory for all things bind
+mkdir $binddir
+cd $binddir
+
+# Get the bind release kit shell script
+cvs checkout -p -r $BINDTAG bind9/util/kit.sh > kit.sh
+
+# Create the bind tarball, which has the side effect of
+# setting up the bind directory we will use for building
+# the export libraries
+sh kit.sh $BINDTAG $binddir
+
+. ./version.tmp
+
+version=${MAJORVER}.${MINORVER}.${PATCHVER}${RELEASETYPE}${RELEASEVER}
+bindsrcdir=bind-$version
+
+# move the tar file to a known place for use by the make dist command
+mv bind-9.7*.tar.gz bind.tar.gz
+
+# temporary hack to allow testing when using snapshots
+#mv $binddir/bind-9.7* $binddir/$bindsrcdir
+
+# Run the script to build and install the export libraries
+sh $topdir/util/bindlib.sh $binddir $bindsrcdir
+
--- /dev/null
+#!/bin/sh
+#
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# 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 ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC 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.
+
+# $Id: bindcus.sh,v 1.2 2009/10/28 04:12:30 sar Exp $
+
+# Configure and build the bind libraries for use by DHCP
+#
+# Usage: sh bindcus.sh
+#
+# Currently no arguments
+#
+
+
+topdir=`pwd`
+binddir=$topdir/bind
+cd bind
+
+. ./version.tmp
+version=${MAJORVER}.${MINORVER}.${PATCHVER}${RELEASETYPE}${RELEASEVER}
+bindsrcdir=bind-$version
+
+# Extract the source from the tarball
+gunzip -c bind.tar.gz | tar xf -
+
+# Run the script to build and install the export libraries
+sh $topdir/util/bindlib.sh $binddir $bindsrcdir
--- /dev/null
+#!/bin/sh
+#
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# 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 ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC 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.
+
+# $Id: bindlib.sh,v 1.2 2009/10/28 04:12:30 sar Exp $
+
+# Configure, build and install the bind export libraries for use by DHCP
+#
+# Usage: sh bindlib.sh <bind directory> <bind source directory>
+# The intention is for this script to be called by other scrips
+# (bind.sh or bindcus.sh) rather than be called directly.
+#
+# <bind directory> = directory for bind stuff within DHCP, typically
+# <dhcp>/bind
+#
+# <bind source directory> = directory for the unpacked bind source code
+# typically <dhcp>/bind/bind-<version>
+#
+
+binddir="$1"
+bindsrcdir="$2"
+
+# Configure the export libraries
+cd $bindsrcdir
+./configure --without-libxml2 --enable-exportlib --enable-threads=no --with-export-includedir=$binddir/include --with-export-libdir=$binddir/lib > $binddir/configure.log
+
+# Build the export librares
+cd lib/export
+gmake > $binddir/build.log
+
+# Install the libraries and includes
+gmake install > $binddir/install.log