PATCH: udhcpd "option domain" multiple values

Denis Vlasenko vda.linux at googlemail.com
Thu Feb 1 14:08:20 PST 2007


On Friday 26 January 2007 18:00, Gabriel L. Somlo wrote:
> Denis & All,
> 
> Whatever I specify as the value for "option domain" in udhcpd.conf
> ends up being on the "search" line in my client's /etc/resolv.conf
> 
> As such, I discovered that specifying multiple values for
> "option domain" doesn't work with udhcpd.
> 
> The following patch fixes that by making "domain" accept a list of
> options, and by insuring that STRING type options with multiple values
> end up being separated by spaces (instead of being cat-ed together).
> 
> Let me know what you think.
> 
> Thanks,
> Gabriel 
> 
> 
> diff -NarU5 busybox-svn-17463.orig/networking/udhcp/files.c busybox-svn-17463/networking/udhcp/files.c
> --- busybox-svn-17463.orig/networking/udhcp/files.c	2007-01-22 11:17:58.000000000 -0500
> +++ busybox-svn-17463/networking/udhcp/files.c	2007-01-26 11:52:26.000000000 -0500
> @@ -106,11 +106,16 @@
>  	if (existing) {
>  		DEBUG("Attaching option %s to existing member of list", option->name);
>  		if (option->flags & OPTION_LIST) {
>  			if (existing->data[OPT_LEN] + length <= 255) {
>  				existing->data = realloc(existing->data,

realloc? why not xrealloc?

> -						existing->data[OPT_LEN] + length + 2);
> +						existing->data[OPT_LEN] + length + 3);
> +				if ((option->flags & TYPE_MASK) == OPTION_STRING) {
> +					/* add space separator between STRING options in a list */
> +					*(existing->data + existing->data[OPT_LEN] + 2) = ' ';
> +					existing->data[OPT_LEN]++;
> +				}
>  				memcpy(existing->data + existing->data[OPT_LEN] + 2, buffer, length);
>  				existing->data[OPT_LEN] += length;

You can overflow existing->data[OPT_LEN].

The below version should fix that (and even mostly fit
into 80 column displays). Can you try it?

static void attach_option(struct option_set **opt_list,
                const struct dhcp_option *option, char *buffer, int length)
{
        struct option_set *existing, *new, **curr;

        existing = find_option(*opt_list, option->code);
        if (!existing) {
                DEBUG("Attaching option %s to list", option->name);

                /* make a new option */
                new = xmalloc(sizeof(struct option_set));
                new->data = xmalloc(length + 2);
                new->data[OPT_CODE] = option->code;
                new->data[OPT_LEN] = length;
                memcpy(new->data + 2, buffer, length);

                curr = opt_list;
                while (*curr && (*curr)->data[OPT_CODE] < option->code)
                        curr = &(*curr)->next;

                new->next = *curr;
                *curr = new;
                return;
        }

        /* add it to an existing option */
        DEBUG("Attaching option %s to existing member of list", option->name);
        if (option->flags & OPTION_LIST) {
                if (existing->data[OPT_LEN] + length <= 255) {
                        existing->data = xrealloc(existing->data,
                                        existing->data[OPT_LEN] + length + 3);
                        if ((option->flags & TYPE_MASK) == OPTION_STRING) {
                                if (existing->data[OPT_LEN] + length >= 255)
                                        return;
                                /* add space separator between STRING options in a list */
                                existing->data[existing->data[OPT_LEN] + 2] = ' ';
                                existing->data[OPT_LEN]++;
                        }
                        memcpy(existing->data + existing->data[OPT_LEN] + 2, buffer, length);
                        existing->data[OPT_LEN] += length;
                } /* else, ignore the data, we could put this in a second option in the future */
        } /* else, ignore the new data */
}

--
vda


More information about the busybox mailing list