Esempio n. 1
0
dhcpctl_status dhcpctl_set_data_value (dhcpctl_handle h,
				       const char *value, unsigned len,
				       const char *value_name)
{
	isc_result_t status;
	omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
	omapi_data_string_t *name = (omapi_data_string_t *)0;
	unsigned ll;

	ll = strlen (value_name);
	status = omapi_data_string_new (&name, ll, MDL);
	if (status != ISC_R_SUCCESS)
		return status;
	memcpy (name -> value, value_name, ll);

	status = omapi_typed_data_new (MDL, &tv,
				       omapi_datatype_data, len, value);
	if (status != ISC_R_SUCCESS) {
		omapi_data_string_dereference (&name, MDL);
		return status;
	}
	memcpy (tv -> u.buffer.value, value, len);

	status = omapi_set_value (h, (omapi_object_t *)0, name, tv);
	omapi_data_string_dereference (&name, MDL);
	omapi_typed_data_dereference (&tv, MDL);
	return status;
}
Esempio n. 2
0
isc_result_t omapi_get_value_str (omapi_object_t *h,
				  omapi_object_t *id,
				  const char *name,
				  omapi_value_t **value)
{
	omapi_object_t *outer;
	omapi_data_string_t *nds;
	isc_result_t status;

	nds = (omapi_data_string_t *)0;
	status = omapi_data_string_new (&nds, strlen (name), MDL);
	if (status != ISC_R_SUCCESS)
		return status;
	memcpy (nds -> value, name, strlen (name));

	for (outer = h; outer -> outer; outer = outer -> outer)
		;
	if (outer -> type -> get_value)
		status = (*(outer -> type -> get_value)) (outer,
							  id, nds, value);
	else
		status = ISC_R_NOTFOUND;
	omapi_data_string_dereference (&nds, MDL);
	return status;
}
Esempio n. 3
0
isc_result_t omapi_set_string_value (omapi_object_t *h, omapi_object_t *id,
				     const char *name, const char *value)
{
	isc_result_t status;
	omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
	omapi_data_string_t *n = (omapi_data_string_t *)0;
	int len;
	int ip;

	status = omapi_data_string_new (&n, strlen (name), MDL);
	if (status != ISC_R_SUCCESS)
		return status;
	memcpy (n -> value, name, strlen (name));

	status = omapi_typed_data_new (MDL, &tv, omapi_datatype_string, value);
	if (status != ISC_R_SUCCESS) {
		omapi_data_string_dereference (&n, MDL);
		return status;
	}

	status = omapi_set_value (h, id, n, tv);
	omapi_data_string_dereference (&n, MDL);
	omapi_typed_data_dereference (&tv, MDL);
	return status;
}
Esempio n. 4
0
dhcpctl_status dhcpctl_get_value (dhcpctl_data_string *result,
				  dhcpctl_handle h, const char *value_name)
{
	isc_result_t status;
	omapi_value_t *tv = (omapi_value_t *)0;
	omapi_data_string_t *value = (omapi_data_string_t *)0;
	unsigned len;
	int ip;

	status = omapi_get_value_str (h, (omapi_object_t *)0, value_name, &tv);
	if (status != ISC_R_SUCCESS)
		return status;

	switch (tv -> value -> type) {
	      case omapi_datatype_int:
		len = sizeof (int);
		break;

	      case omapi_datatype_string:
	      case omapi_datatype_data:
		len = tv -> value -> u.buffer.len;
		break;

	      case omapi_datatype_object:
		len = sizeof (omapi_handle_t);
		break;

	      default:
		omapi_typed_data_dereference (&tv -> value, MDL);
		return ISC_R_UNEXPECTED;
	}

	status = omapi_data_string_new (result, len, MDL);
	if (status != ISC_R_SUCCESS) {
		omapi_typed_data_dereference (&tv -> value, MDL);
		return status;
	}

	switch (tv -> value -> type) {
	      case omapi_datatype_int:
		ip = htonl (tv -> value -> u.integer);
		memcpy ((*result) -> value, &ip, sizeof ip);
		break;

	      case omapi_datatype_string:
	      case omapi_datatype_data:
		memcpy ((*result) -> value,
			tv -> value -> u.buffer.value,
			tv -> value -> u.buffer.len);
		break;

	      case omapi_datatype_object:
		ip = htonl (tv -> value -> u.object -> handle);
		memcpy ((*result) -> value, &ip, sizeof ip);
		break;
	}

	omapi_value_dereference (&tv, MDL);
	return ISC_R_SUCCESS;
}
Esempio n. 5
0
dhcpctl_status dhcpctl_new_authenticator (dhcpctl_handle *h,
					  const char *name,
					  const char *algorithm,
					  const unsigned char *secret,
					  unsigned secret_len)
{
	struct auth_key *key = (struct auth_key *)0;
	isc_result_t status;

	status = omapi_auth_key_new (&key, MDL);
	if (status != ISC_R_SUCCESS)
		return status;

	key -> name = dmalloc (strlen (name) + 1, MDL);
	if (!key -> name) {
		omapi_auth_key_dereference (&key, MDL);
		return ISC_R_NOMEMORY;
	}
	strcpy (key -> name, name);

	/* If the algorithm name isn't an FQDN, tack on the
	   .SIG-ALG.REG.NET. domain. */
	if (strchr (algorithm, '.') == 0) {
		static char add[] = ".SIG-ALG.REG.INT.";
		key -> algorithm = dmalloc (strlen (algorithm) +
		                            sizeof (add), MDL);
		if (!key -> algorithm) {
			omapi_auth_key_dereference (&key, MDL);
			return ISC_R_NOMEMORY;
		}
		strcpy (key -> algorithm, algorithm);
		strcat (key -> algorithm, add);
	} else {
		key -> algorithm = dmalloc (strlen (algorithm) + 1, MDL);
		if (!key -> algorithm) {
			omapi_auth_key_dereference (&key, MDL);
			return ISC_R_NOMEMORY;
		}
		strcpy (key -> algorithm, algorithm);
	}

	status = omapi_data_string_new (&key -> key, secret_len, MDL);
	if (status != ISC_R_SUCCESS) {
		omapi_auth_key_dereference (&key, MDL);
		return status;
	}
	memcpy (key -> key -> value, secret, secret_len);
	key -> key -> len = secret_len;

	*h = (dhcpctl_handle) key;
	return ISC_R_SUCCESS;
}
Esempio n. 6
0
dhcpctl_status dhcpctl_set_null_value (dhcpctl_handle h,
				       const char *value_name)
{
	isc_result_t status;
	omapi_data_string_t *name = (omapi_data_string_t *)0;
	unsigned ll;

	ll = strlen (value_name);
	status = omapi_data_string_new (&name, ll, MDL);
	if (status != ISC_R_SUCCESS)
		return status;
	memcpy (name -> value, value_name, ll);

	status = omapi_set_value (h, (omapi_object_t *)0, name,
				  (omapi_typed_data_t *)0);
	omapi_data_string_dereference (&name, MDL);
	return status;
}
Esempio n. 7
0
isc_result_t omapi_set_value_str (omapi_object_t *h,
				  omapi_object_t *id,
				  const char *name,
				  omapi_typed_data_t *value)
{
	omapi_data_string_t *nds;
	isc_result_t status;

	nds = (omapi_data_string_t *)0;
	status = omapi_data_string_new (&nds, strlen (name), MDL);
	if (status != ISC_R_SUCCESS)
		return status;
	memcpy (nds -> value, name, strlen (name));

	status = omapi_set_value (h, id, nds, value);
	omapi_data_string_dereference (&nds, MDL);
	return status;
}
Esempio n. 8
0
dhcpctl_status dhcpctl_set_int_value (dhcpctl_handle h, int value,
				      const char *value_name)
{
	isc_result_t status;
	omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
	omapi_data_string_t *name = (omapi_data_string_t *)0;

	status = omapi_data_string_new (&name, strlen (value_name), MDL);
	if (status != ISC_R_SUCCESS)
		return status;
	memcpy (name -> value, value_name, strlen (value_name));

	status = omapi_typed_data_new (MDL, &tv, omapi_datatype_int, value);
	if (status != ISC_R_SUCCESS) {
		omapi_data_string_dereference (&name, MDL);
		return status;
	}

	status = omapi_set_value (h, (omapi_object_t *)0, name, tv);
	omapi_data_string_dereference (&name, MDL);
	omapi_typed_data_dereference (&tv, MDL);
	return status;
}
Esempio n. 9
0
/* valspec is a string of form "var=value" 
 * Return values:
     0 - parse error
    -1 - error setting value
     1 - OK
*/
int setvalue(dhcpctl_handle *p_obj, dhcpctl_data_string *p_val, char *valspec){
    char *var, *val;
    isc_result_t status;
    dhcpctl_handle object;
    dhcpctl_data_string value;
    omprop setproperty;
    omstate setstate;
    struct in_addr convaddr;
    char hwaddr[6];
    int i;
    uint32_t hostint,netint;
    struct tm timestruct;
    time_t timeval;

    object=*p_obj;
    value=*p_val;
    var=valspec;
    val=index(valspec,'=');
    if (val == NULL) return 0;
    *val++='\0';
    setproperty=stringtoprop(var);
    switch(setproperty){
    case op_ipaddr:
	if (inet_pton(AF_INET, val, &convaddr)<=0) return 0;
	omapi_data_string_new(&value, 4, MDL);
	memcpy(value->value, &convaddr.s_addr,4);
	break;
    case op_hwaddr:
	if (strlen(val) != 17) return 0;
	for (i=0; i < 17; i+=3){
	    if (i != 15 && val[i+2] != ':') return 0;
	    val[i+2]='\0';
	    hwaddr[i/3]=(char)strtol(&val[i], NULL, 16);
	}
	omapi_data_string_new(&value, 6, MDL);
	memcpy(value->value, hwaddr, 6);
	break;
    case op_hwtype:
	hostint=atol(val);
	netint=htonl(hostint);
	omapi_data_string_new(&value, sizeof netint, MDL);
	memcpy(value->value, &netint, sizeof netint);
	break;
    case op_state:
	setstate=stringtostate(val);
	netint=htonl((unsigned long)setstate);
	omapi_data_string_new(&value, sizeof netint, MDL);
	memcpy(value->value, &netint, sizeof netint);
	break;
    case op_ends:
    case op_tstp:
    case op_tsfp:
    case op_cltt:
	strptime(val, "%a %b %d %T %Y", &timestruct);
	timeval=mktime(&timestruct);
	netint=htonl((unsigned long)timeval);
	omapi_data_string_new(&value, 4, MDL);
	memcpy(value->value, &netint, 4);
	break;
    case op_name:
    case op_client_hostname:
    case op_statements:
    case op_group:
	i=strlen(val);
	omapi_data_string_new(&value, i, MDL);
	memcpy(value->value, val, i);
	break;
    default:
	return 0;
    } /* end of switch */

    status=dhcpctl_set_value(object, value, var);
    if (status != ISC_R_SUCCESS){
	dhcpctl_data_string_dereference(&value, MDL);
	return -1;
    }
    return 1;
}
Esempio n. 10
0
isc_result_t omapi_protocol_signal_handler (omapi_object_t *h,
					    const char *name, va_list ap)
{
	isc_result_t status;
	omapi_protocol_object_t *p;
	omapi_object_t *c;
	omapi_message_object_t *m;
	omapi_value_t *signature;
	u_int16_t nlen;
	u_int32_t vlen;
	u_int32_t th;
#if defined (DEBUG_MEMORY_LEAKAGE)
	unsigned long previous_outstanding = 0xDEADBEEF;
	unsigned long connect_outstanding = 0xDEADBEEF;
#endif

	if (h -> type != omapi_type_protocol) {
		/* XXX shouldn't happen.   Put an assert here? */
		return ISC_R_UNEXPECTED;
	}
	p = (omapi_protocol_object_t *)h;

	if (!strcmp (name, "connect")) {
#if defined (DEBUG_MEMORY_LEAKAGE)
		connect_outstanding = dmalloc_outstanding;
#endif
		/* Send the introductory message. */
		status = omapi_protocol_send_intro
			(h, OMAPI_PROTOCOL_VERSION,
			 sizeof (omapi_protocol_header_t));
		if (status != ISC_R_SUCCESS) {
			omapi_disconnect (p -> outer, 1);
			return status;
		}
		return ISC_R_SUCCESS;
	}

	/* Should only receive these when opening the initial authenticator. */
	if (!strcmp (name, "status")) {
		status = va_arg (ap, isc_result_t);
		if (status != ISC_R_SUCCESS) {
			omapi_signal_in (h -> inner, "status", status,
					 (omapi_object_t *)0);
			omapi_disconnect (p -> outer, 1);
			return status;
		} else {
			return omapi_signal_in (h -> inner, "ready");
		}
	}

	/* If we get a disconnect, dump memory usage. */
	if (!strcmp (name, "disconnect")) {
#if defined (DEBUG_MEMORY_LEAKAGE)
	    if (connect_outstanding != 0xDEADBEEF) {
		log_info ("generation %ld: %ld new, %ld outstanding, %ld%s",
			  dmalloc_generation,
			  dmalloc_outstanding - previous_outstanding,
			  dmalloc_outstanding, dmalloc_longterm, " long-term");
	    }
#endif
#if defined (DEBUG_MEMORY_LEAKAGE)
	    dmalloc_dump_outstanding ();
#endif
#if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY)
	    dump_rc_history ();
#endif
	    for (m = omapi_registered_messages; m; m = m -> next) {
		if (m -> protocol_object == p) {
		    if (m -> object)
			omapi_signal (m -> object, "disconnect");
		}
	    }
	}

	/* Not a signal we recognize? */
	if (strcmp (name, "ready")) {
		if (p -> inner && p -> inner -> type -> signal_handler)
			return (*(p -> inner -> type -> signal_handler)) (h,
									  name,
									  ap);
		return ISC_R_NOTFOUND;
	}

	if (!p -> outer || p -> outer -> type != omapi_type_connection)
		return ISC_R_INVALIDARG;
	c = p -> outer;

	/* We get here because we requested that we be woken up after
           some number of bytes were read, and that number of bytes
           has in fact been read. */
	switch (p -> state) {
	      case omapi_protocol_intro_wait:
		/* Get protocol version and header size in network
		   byte order. */
		omapi_connection_get_uint32 (c, &p -> protocol_version);
		omapi_connection_get_uint32 (c, &p -> header_size);
	
		/* We currently only support the current protocol version. */
		if (p -> protocol_version != OMAPI_PROTOCOL_VERSION) {
			omapi_disconnect (c, 1);
			return ISC_R_VERSIONMISMATCH;
		}

		if (p -> header_size < sizeof (omapi_protocol_header_t)) {
			omapi_disconnect (c, 1);
			return ISC_R_PROTOCOLERROR;
		}

		if (p -> default_auth) {
			status = omapi_protocol_send_open
				(h, (omapi_object_t *)0, "authenticator",
				 p -> default_auth -> a,
				 OMAPI_NOTIFY_PROTOCOL);
			if (status != ISC_R_SUCCESS) {
				omapi_disconnect (c, 1);
				return status;
			}
		} else {
			status = omapi_signal_in (h -> inner, "ready");
		}

	      to_header_wait:
		/* The next thing we're expecting is a message header. */
		p -> state = omapi_protocol_header_wait;

		/* Register a need for the number of bytes in a
		   header, and if we already have that many, process
		   them immediately. */
		if ((omapi_connection_require (c, p -> header_size)) !=
		    ISC_R_SUCCESS)
			break;
		/* If we already have the data, fall through. */

	      case omapi_protocol_header_wait:
#if defined (DEBUG_MEMORY_LEAKAGE)
		if (previous_outstanding != 0xDEADBEEF) {
			log_info ("%s %ld: %ld new, %ld outstanding, %ld%s",
				  "generation", dmalloc_generation,
				  dmalloc_outstanding - previous_outstanding,
				  dmalloc_outstanding, dmalloc_longterm,
				  " long-term");
#endif
#if (defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL))
			dmalloc_dump_outstanding ();
#endif
#if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY)
			dump_rc_history ();
#endif
#if defined (DEBUG_MEMORY_LEAKAGE)
		}
		previous_outstanding = dmalloc_outstanding;
#endif
		status = omapi_message_new ((omapi_object_t **)&p -> message,
					    MDL);
		if (status != ISC_R_SUCCESS) {
			omapi_disconnect (c, 1);
			return status;
		}

		p -> verify_result = ISC_R_SUCCESS;

		/* Swap in the header... */
		omapi_connection_get_uint32 (c, &p -> message -> authid);

		/* Bind the authenticator to the message object. */
		if (p -> message -> authid) {
			status = (omapi_protocol_lookup_auth
				  (&p -> message -> id_object, h,
				   p -> message -> authid));
			if (status != ISC_R_SUCCESS)
				p -> verify_result = status;

			/* Activate the authentication key. */
			status = omapi_set_object_value
				(c, (omapi_object_t *)0, "input-authenticator",
				 p -> message -> id_object);
			if (status != ISC_R_SUCCESS) {
				omapi_disconnect (c, 1);
				return status;
			}
		}

		omapi_connection_get_uint32 (c, &p -> message -> authlen);
		omapi_connection_get_uint32 (c, &p -> message -> op);
		omapi_connection_get_uint32 (c, &th);
		p -> message -> h = th;
		omapi_connection_get_uint32 (c, &p -> message -> id);
		omapi_connection_get_uint32 (c, &p -> message -> rid);

		/* If there was any extra header data, skip over it. */
		if (p -> header_size > sizeof (omapi_protocol_header_t)) {
			omapi_connection_copyout
				(0, c, (p -> header_size -
					sizeof (omapi_protocol_header_t)));
		}
						     
		/* XXX must compute partial signature across the
                   XXX preceding bytes.    Also, if authenticator
		   specifies encryption as well as signing, we may
		   have to decrypt the data on the way in. */

		/* First we read in message-specific values, then object
		   values. */
		p -> reading_message_values = 1;

	      need_name_length:
		/* The next thing we're expecting is length of the
		   first name. */
		p -> state = omapi_protocol_name_length_wait;

		/* Wait for a 16-bit length. */
		if ((omapi_connection_require (c, 2)) != ISC_R_SUCCESS)
			break;
		/* If it's already here, fall through. */

	      case omapi_protocol_name_length_wait:
		omapi_connection_get_uint16 (c, &nlen);
		/* A zero-length name means that we're done reading name+value
		   pairs. */
		if (nlen == 0) {
			/* If we've already read in the object, we are
			   done reading the message, but if we've just
			   finished reading in the values associated
			   with the message, we need to read the
			   object. */
			if (p -> reading_message_values) {
				p -> reading_message_values = 0;
				goto need_name_length;
			}

			/* If the authenticator length is zero, there's no
			   signature to read in, so go straight to processing
			   the message. */
			if (p -> message -> authlen == 0)
				goto message_done;

			/* The next thing we're expecting is the
                           message signature. */
			p -> state = omapi_protocol_signature_wait;

			/* Wait for the number of bytes specified for
			   the authenticator.  If we already have it,
			   go read it in. */
			if (omapi_connection_require
			    (c, p -> message -> authlen) == ISC_R_SUCCESS)
				goto signature_wait;
			break;
		}

		/* Allocate a buffer for the name. */
		status = (omapi_data_string_new (&p -> name, nlen, MDL));
		if (status != ISC_R_SUCCESS) {
			omapi_disconnect (c, 1);
			return ISC_R_NOMEMORY;
		}
		p -> state = omapi_protocol_name_wait;
		if (omapi_connection_require (c, nlen) != ISC_R_SUCCESS)
			break;
		/* If it's already here, fall through. */
					     
	      case omapi_protocol_name_wait:
		omapi_connection_copyout (p -> name -> value, c,
					  p -> name -> len);
		/* Wait for a 32-bit length. */
		p -> state = omapi_protocol_value_length_wait;
		if ((omapi_connection_require (c, 4)) != ISC_R_SUCCESS)
			break;
		/* If it's already here, fall through. */

	      case omapi_protocol_value_length_wait:
		omapi_connection_get_uint32 (c, &vlen);

		/* Zero-length values are allowed - if we get one, we
		   don't have to read any data for the value - just
		   get the next one, if there is a next one. */
		if (!vlen)
			goto insert_new_value;

		status = omapi_typed_data_new (MDL, &p -> value,
					       omapi_datatype_data,
					       vlen);
		if (status != ISC_R_SUCCESS) {
			omapi_disconnect (c, 1);
			return ISC_R_NOMEMORY;
		}

		p -> state = omapi_protocol_value_wait;
		if (omapi_connection_require (c, vlen) != ISC_R_SUCCESS)
			break;
		/* If it's already here, fall through. */
					     
	      case omapi_protocol_value_wait:
		omapi_connection_copyout (p -> value -> u.buffer.value, c,
					  p -> value -> u.buffer.len);

	      insert_new_value:
		if (p -> reading_message_values) {
			status = (omapi_set_value
				  ((omapi_object_t *)p -> message,
				   p -> message -> id_object,
				   p -> name, p -> value));
		} else {
			if (!p -> message -> object) {
				/* We need a generic object to hang off of the
				   incoming message. */
				status = (omapi_generic_new
					  (&p -> message -> object, MDL));
				if (status != ISC_R_SUCCESS) {
					omapi_disconnect (c, 1);
					return status;
				}
			}
			status = (omapi_set_value
				  ((omapi_object_t *)p -> message -> object,
				   p -> message -> id_object,
				   p -> name, p -> value));
		}
		if (status != ISC_R_SUCCESS) {
			omapi_disconnect (c, 1);
			return status;
		}
		omapi_data_string_dereference (&p -> name, MDL);
		if (p -> value)
			omapi_typed_data_dereference (&p -> value, MDL);
		goto need_name_length;

	      signature_wait:
	      case omapi_protocol_signature_wait:
		if (p -> message -> id_object) {
			/* Compute the signature of the message. */
			signature = (omapi_value_t *)0;
			status = omapi_get_value_str (c, (omapi_object_t *)0,
						      "input-signature",
						      &signature);
			if (status != ISC_R_SUCCESS) {
				omapi_disconnect (c, 1);
				return status;
			}

			/* Disable the authentication key on the connection. */
			status = omapi_set_value_str (c, (omapi_object_t *)0,
						      "input-authenticator",
						      (omapi_typed_data_t *)0);
			if (status != ISC_R_SUCCESS) {
				omapi_value_dereference (&signature, MDL);
				omapi_disconnect (c, 1);
				return status;
			}
		}

		/* Read the authenticator. */
		status = omapi_typed_data_new (MDL,
					       &p -> message -> authenticator,
					       omapi_datatype_data,
					       p -> message -> authlen);
			
		if (status != ISC_R_SUCCESS) {
			omapi_value_dereference (&signature, MDL);
			omapi_disconnect (c, 1);
			return ISC_R_NOMEMORY;
		}
		omapi_connection_copyout
			(p -> message -> authenticator -> u.buffer.value, c,
			 p -> message -> authlen);

		/* Verify the signature. */
		if (p -> message -> id_object &&
		    ((signature -> value -> u.buffer.len !=
		      p -> message -> authlen) ||
		     (memcmp (signature -> value -> u.buffer.value,
			      p -> message -> authenticator -> u.buffer.value,
			      p -> message -> authlen) != 0))) {
			/* Invalid signature. */
			p -> verify_result = ISC_R_INVALIDKEY;
		}

		omapi_value_dereference (&signature, MDL);

		/* Process the message. */
	      message_done:
		if (p -> verify_result != ISC_R_SUCCESS) {
			status = omapi_protocol_send_status
				(h, (omapi_object_t *)0, p -> verify_result,
				 p -> message -> id, (char *)0);
		} else {
			status = omapi_message_process
				((omapi_object_t *)p -> message, h);
		}
		if (status != ISC_R_SUCCESS) {
			omapi_disconnect (c, 1);
			return ISC_R_NOMEMORY;
		}

		omapi_message_dereference (&p -> message, MDL);
#if defined (DEBUG_MEMORY_LEAKAGE)
		log_info ("generation %ld: %ld new, %ld outstanding, %ld%s",
			  dmalloc_generation,
			  dmalloc_outstanding - previous_outstanding,
			  dmalloc_outstanding, dmalloc_longterm, " long-term");
#endif
#if (defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL))
		dmalloc_dump_outstanding ();
#endif
#if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY)
		dump_rc_history ();
#endif
#if defined (DEBUG_MEMORY_LEAKAGE)
		previous_outstanding = 0xDEADBEEF;
#endif
		/* Now wait for the next message. */
		goto to_header_wait;		

	      default:
		/* XXX should never get here.   Assertion? */
		break;
	}
	return ISC_R_SUCCESS;
}