PATCH: udhcpd "option domain" multiple values

Gabriel L. Somlo somlo at cmu.edu
Thu Feb 1 21:07:00 UTC 2007


On Tue, Jan 30, 2007 at 02:58:50PM -0600, Jason Schoon wrote:
> On 1/30/07, Gabriel L. Somlo <somlo at cmu.edu> wrote:
> >And what to do about all the (pre isc 3.1.0) clients that just dump the
> >content of option 15 into the search string ? :)
> 
> They still will.  Or they will disregard the option entirely.

So, the way I see it, 3.1.0 and later clients will first look for the
domain-search option to add to resolv.conf, and default to domain-name
if the former isn't being sent by the server. As far as pre-3.1.0
clients:

> They will not
> have your patch, so they will not be expecting to receive multiple strings
> in a single field.  They will be expecting this field to contain a single
> domain value.

no, they'll expect a single string :) which may contain spaces. Which
is the way this is being done today, via the domain-name option.
Here's a quote from the dhcp-options man page that comes with 3.1.0a3:

	The domain-search option specifies a 'search list' of
	Domain Names to be used by the client to locate
	not-fully-qualified domain names. The difference between
	this option and historic use of the domain-name option
	                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
	for the same ends is that this option is encoded in
	^^^^^^^^^^^^^^^^^^
	RFC1035 compressed labels on the wire.

The problem with udhcpd is that it won't allow quoted strings to be
parsed from the udhcpd.conf file (which would allow passing single
strings that contain spaces).

So, we either complicate parsing of strings from the config file, or
we make certain string-type options listable, and insert single spaces
between members of the "list", ending up with longer strings that
contain spaces.

We'd have to do one or the other of these anyway, even for RFC3397, as
we'll try to pass multiple strings (or one space-separated line of
them) to the domain-search option.

My patch did this in one of the two possible ways. Do you think it
should be done the other way (i.e., by adding support for parsing
quoted strings from the config file) ?

Speaking of RFC3397, I've written a compact function that expands
RFC1035-compressed strings, and it's included at the bottom of this
email, if anyone wants to poke at it. I'm working on a compression
function, at which time I'll whip up a patch to add 3397 to udhcpd.

Either way, adding 3397 support won't fix my original problem, which
is to support passing space-separated strings via the domain-name
option, which is something lots of people do, today, with isc dhcpd...

Cheers.
Gabriel


#define NS_CMPRSFLGS 0xc0	/* name compression pointer flag */

/* expand a RFC1035-compressed list of domain names "src", of length "slen";
 * returns a newly allocated string containing the space-separated domains,
 * or NULL if an error occurs.
 */
char *ns_name_expand(const unsigned char *src, unsigned slen) {
	const unsigned char *c;
	unsigned crtpos, retpos, len = 0;
	char *dst = NULL;

	if (!src || !slen)
		return NULL;

	/* We make two passes over the src string. First, we compute
	 * how long the resulting string would be. Then we allocate a
	 * new buffer of the required length, and fill it in with the
	 * expanded content. The advantage of this approach is not
	 * having to deal with requiring callers to supply their own
	 * buffer, then having to check if it's sufficiently large, etc.
	 */

	while (!dst) {

		if (len > 0)	/* second pass? allocate dst buffer */
			dst = xmalloc(len);

		len = crtpos = retpos = 0;

		while (crtpos < slen) {
			c = src + crtpos;

			if (*c & NS_CMPRSFLGS) { /* pointer */
				if (retpos == 0) /* toplevel? save ret. spot */
					retpos = crtpos + 2;
				crtpos = *(c + 1);/* jump to pointed location */
			} else if (*c) { /* label */
				if (dst)
					memcpy(dst + len, c + 1, *c);
				len += (*c + 1);
				crtpos += (*c + 1);
				if (dst)
					*(dst + len - 1) = '.';
			} else {  /* null -- end of current domain name */
				if (retpos == 0) { /* toplevel? keep going */
					crtpos++;
				} else {   /* go back to toplevel saved spot */
					crtpos = retpos;
					retpos = 0;
				}
				if (dst)
					*(dst + len - 1) = ' ';
			}
		}

		if (dst)
			*(dst + len - 1) = '\0';
	}

	return dst;
}



More information about the busybox mailing list