mirror of
https://github.com/sheumann/hush.git
synced 2024-12-22 14:30:31 +00:00
udhcp: optionally support RFC3397 (by Gabriel L. Somlo <somlo@cmu.edu>)
This commit is contained in:
parent
966bb43766
commit
5066473d41
@ -65,3 +65,11 @@ config FEATURE_UDHCP_DEBUG
|
|||||||
the background.
|
the background.
|
||||||
|
|
||||||
See http://udhcp.busybox.net for further details.
|
See http://udhcp.busybox.net for further details.
|
||||||
|
|
||||||
|
config FEATURE_RFC3397
|
||||||
|
bool "Support for RFC3397 domain search (experimental)"
|
||||||
|
default n
|
||||||
|
depends on APP_UDHCPD || APP_UDHCPC
|
||||||
|
help
|
||||||
|
If selected, both client and server will support passing of domain
|
||||||
|
search lists via option 119, specified in RFC3397.
|
||||||
|
@ -16,3 +16,4 @@ lib-$(CONFIG_APP_UDHCPD) += dhcpd.o arpping.o files.o leases.o \
|
|||||||
serverpacket.o static_leases.o
|
serverpacket.o static_leases.o
|
||||||
lib-$(CONFIG_APP_DUMPLEASES) += dumpleases.o
|
lib-$(CONFIG_APP_DUMPLEASES) += dumpleases.o
|
||||||
lib-$(CONFIG_APP_DHCPRELAY) += dhcprelay.o
|
lib-$(CONFIG_APP_DHCPRELAY) += dhcprelay.o
|
||||||
|
lib-$(CONFIG_FEATURE_RFC3397) += domain_codec.o
|
||||||
|
@ -104,6 +104,12 @@ static void attach_option(struct option_set **opt_list,
|
|||||||
if (!existing) {
|
if (!existing) {
|
||||||
DEBUG("Attaching option %s to list", option->name);
|
DEBUG("Attaching option %s to list", option->name);
|
||||||
|
|
||||||
|
#if ENABLE_FEATURE_RFC3397
|
||||||
|
if ((option->flags & TYPE_MASK) == OPTION_STR1035)
|
||||||
|
/* reuse buffer and length for RFC1035-formatted string */
|
||||||
|
buffer = dname_enc(NULL, 0, buffer, &length);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* make a new option */
|
/* make a new option */
|
||||||
new = xmalloc(sizeof(struct option_set));
|
new = xmalloc(sizeof(struct option_set));
|
||||||
new->data = xmalloc(length + 2);
|
new->data = xmalloc(length + 2);
|
||||||
@ -117,12 +123,22 @@ static void attach_option(struct option_set **opt_list,
|
|||||||
|
|
||||||
new->next = *curr;
|
new->next = *curr;
|
||||||
*curr = new;
|
*curr = new;
|
||||||
|
#if ENABLE_FEATURE_RFC3397
|
||||||
|
if ((option->flags & TYPE_MASK) == OPTION_STR1035 && buffer != NULL)
|
||||||
|
free(buffer);
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add it to an existing option */
|
/* add it to an existing option */
|
||||||
DEBUG("Attaching option %s to existing member of list", option->name);
|
DEBUG("Attaching option %s to existing member of list", option->name);
|
||||||
if (option->flags & OPTION_LIST) {
|
if (option->flags & OPTION_LIST) {
|
||||||
|
#if ENABLE_FEATURE_RFC3397
|
||||||
|
if ((option->flags & TYPE_MASK) == OPTION_STR1035)
|
||||||
|
/* reuse buffer and length for RFC1035-formatted string */
|
||||||
|
buffer = dname_enc(existing->data + 2,
|
||||||
|
existing->data[OPT_LEN], buffer, &length);
|
||||||
|
#endif
|
||||||
if (existing->data[OPT_LEN] + length <= 255) {
|
if (existing->data[OPT_LEN] + length <= 255) {
|
||||||
existing->data = xrealloc(existing->data,
|
existing->data = xrealloc(existing->data,
|
||||||
existing->data[OPT_LEN] + length + 3);
|
existing->data[OPT_LEN] + length + 3);
|
||||||
@ -137,6 +153,10 @@ static void attach_option(struct option_set **opt_list,
|
|||||||
memcpy(existing->data + existing->data[OPT_LEN] + 2, buffer, length);
|
memcpy(existing->data + existing->data[OPT_LEN] + 2, buffer, length);
|
||||||
existing->data[OPT_LEN] += length;
|
existing->data[OPT_LEN] += length;
|
||||||
} /* else, ignore the data, we could put this in a second option in the future */
|
} /* else, ignore the data, we could put this in a second option in the future */
|
||||||
|
#if ENABLE_FEATURE_RFC3397
|
||||||
|
if ((option->flags & TYPE_MASK) == OPTION_STR1035 && buffer != NULL)
|
||||||
|
free(buffer);
|
||||||
|
#endif
|
||||||
} /* else, ignore the new data */
|
} /* else, ignore the new data */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,6 +203,9 @@ static int read_opt(const char *const_line, void *arg)
|
|||||||
if (retval) retval = read_ip(val, buffer + 4);
|
if (retval) retval = read_ip(val, buffer + 4);
|
||||||
break;
|
break;
|
||||||
case OPTION_STRING:
|
case OPTION_STRING:
|
||||||
|
#if ENABLE_FEATURE_RFC3397
|
||||||
|
case OPTION_STR1035:
|
||||||
|
#endif
|
||||||
length = strlen(val);
|
length = strlen(val);
|
||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
if (length > 254) length = 254;
|
if (length > 254) length = 254;
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
/* supported options are easily added here */
|
/* supported options are easily added here */
|
||||||
const struct dhcp_option dhcp_options[] = {
|
const struct dhcp_option dhcp_options[] = {
|
||||||
/* name[10] flags code */
|
/* name[12] flags code */
|
||||||
{"subnet", OPTION_IP | OPTION_REQ, 0x01},
|
{"subnet", OPTION_IP | OPTION_REQ, 0x01},
|
||||||
{"timezone", OPTION_S32, 0x02},
|
{"timezone", OPTION_S32, 0x02},
|
||||||
{"router", OPTION_IP | OPTION_LIST | OPTION_REQ, 0x03},
|
{"router", OPTION_IP | OPTION_LIST | OPTION_REQ, 0x03},
|
||||||
@ -43,6 +43,9 @@ const struct dhcp_option dhcp_options[] = {
|
|||||||
{"tftp", OPTION_STRING, 0x42},
|
{"tftp", OPTION_STRING, 0x42},
|
||||||
{"bootfile", OPTION_STRING, 0x43},
|
{"bootfile", OPTION_STRING, 0x43},
|
||||||
{"userclass", OPTION_STRING, 0x4D},
|
{"userclass", OPTION_STRING, 0x4D},
|
||||||
|
#if ENABLE_FEATURE_RFC3397
|
||||||
|
{"search", OPTION_STR1035 | OPTION_LIST | OPTION_REQ, 0x77},
|
||||||
|
#endif
|
||||||
/* MSIE's "Web Proxy Autodiscovery Protocol" support */
|
/* MSIE's "Web Proxy Autodiscovery Protocol" support */
|
||||||
{"wpad", OPTION_STRING, 0xfc},
|
{"wpad", OPTION_STRING, 0xfc},
|
||||||
{"", 0x00, 0x00}
|
{"", 0x00, 0x00}
|
||||||
@ -54,6 +57,9 @@ const unsigned char option_lengths[] = {
|
|||||||
[OPTION_IP_PAIR] = 8,
|
[OPTION_IP_PAIR] = 8,
|
||||||
[OPTION_BOOLEAN] = 1,
|
[OPTION_BOOLEAN] = 1,
|
||||||
[OPTION_STRING] = 1,
|
[OPTION_STRING] = 1,
|
||||||
|
#if ENABLE_FEATURE_RFC3397
|
||||||
|
[OPTION_STR1035] = 1,
|
||||||
|
#endif
|
||||||
[OPTION_U8] = 1,
|
[OPTION_U8] = 1,
|
||||||
[OPTION_U16] = 2,
|
[OPTION_U16] = 2,
|
||||||
[OPTION_S16] = 2,
|
[OPTION_S16] = 2,
|
||||||
|
@ -9,6 +9,9 @@ enum {
|
|||||||
OPTION_IP=1,
|
OPTION_IP=1,
|
||||||
OPTION_IP_PAIR,
|
OPTION_IP_PAIR,
|
||||||
OPTION_STRING,
|
OPTION_STRING,
|
||||||
|
#if ENABLE_FEATURE_RFC3397
|
||||||
|
OPTION_STR1035, /* RFC1035 compressed domain name list */
|
||||||
|
#endif
|
||||||
OPTION_BOOLEAN,
|
OPTION_BOOLEAN,
|
||||||
OPTION_U8,
|
OPTION_U8,
|
||||||
OPTION_U16,
|
OPTION_U16,
|
||||||
@ -33,5 +36,9 @@ uint8_t *get_option(struct dhcpMessage *packet, int code);
|
|||||||
int end_option(uint8_t *optionptr);
|
int end_option(uint8_t *optionptr);
|
||||||
int add_option_string(uint8_t *optionptr, uint8_t *string);
|
int add_option_string(uint8_t *optionptr, uint8_t *string);
|
||||||
int add_simple_option(uint8_t *optionptr, uint8_t code, uint32_t data);
|
int add_simple_option(uint8_t *optionptr, uint8_t code, uint32_t data);
|
||||||
|
#if ENABLE_FEATURE_RFC3397
|
||||||
|
char *dname_dec(const uint8_t *cstr, int clen, const char *pre);
|
||||||
|
uint8_t *dname_enc(const uint8_t *cstr, int clen, const char *src, int *retlen);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -19,6 +19,9 @@ static const int max_option_length[] = {
|
|||||||
[OPTION_IP] = sizeof("255.255.255.255 "),
|
[OPTION_IP] = sizeof("255.255.255.255 "),
|
||||||
[OPTION_IP_PAIR] = sizeof("255.255.255.255 ") * 2,
|
[OPTION_IP_PAIR] = sizeof("255.255.255.255 ") * 2,
|
||||||
[OPTION_STRING] = 1,
|
[OPTION_STRING] = 1,
|
||||||
|
#if ENABLE_FEATURE_RFC3397
|
||||||
|
[OPTION_STR1035] = 1,
|
||||||
|
#endif
|
||||||
[OPTION_BOOLEAN] = sizeof("yes "),
|
[OPTION_BOOLEAN] = sizeof("yes "),
|
||||||
[OPTION_U8] = sizeof("255 "),
|
[OPTION_U8] = sizeof("255 "),
|
||||||
[OPTION_U16] = sizeof("65535 "),
|
[OPTION_U16] = sizeof("65535 "),
|
||||||
@ -53,21 +56,23 @@ static int mton(struct in_addr *mask)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Fill dest with the text of option 'option'. */
|
/* Allocate and fill with the text of option 'option'. */
|
||||||
static void fill_options(char *dest, uint8_t *option,
|
static char *alloc_fill_opts(uint8_t *option, const struct dhcp_option *type_p)
|
||||||
const struct dhcp_option *type_p)
|
|
||||||
{
|
{
|
||||||
int type, optlen;
|
int len, type, optlen;
|
||||||
uint16_t val_u16;
|
uint16_t val_u16;
|
||||||
int16_t val_s16;
|
int16_t val_s16;
|
||||||
uint32_t val_u32;
|
uint32_t val_u32;
|
||||||
int32_t val_s32;
|
int32_t val_s32;
|
||||||
int len = option[OPT_LEN - 2];
|
char *dest, *ret;
|
||||||
|
|
||||||
dest += sprintf(dest, "%s=", type_p->name);
|
|
||||||
|
|
||||||
|
len = option[OPT_LEN - 2];
|
||||||
type = type_p->flags & TYPE_MASK;
|
type = type_p->flags & TYPE_MASK;
|
||||||
optlen = option_lengths[type];
|
optlen = option_lengths[type];
|
||||||
|
|
||||||
|
dest = ret = xmalloc(upper_length(len, type) + strlen(type_p->name) + 2);
|
||||||
|
dest += sprintf(ret, "%s=", type_p->name);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case OPTION_IP_PAIR:
|
case OPTION_IP_PAIR:
|
||||||
@ -103,13 +108,21 @@ static void fill_options(char *dest, uint8_t *option,
|
|||||||
case OPTION_STRING:
|
case OPTION_STRING:
|
||||||
memcpy(dest, option, len);
|
memcpy(dest, option, len);
|
||||||
dest[len] = '\0';
|
dest[len] = '\0';
|
||||||
return; /* Short circuit this case */
|
return ret; /* Short circuit this case */
|
||||||
|
#if ENABLE_FEATURE_RFC3397
|
||||||
|
case OPTION_STR1035:
|
||||||
|
/* unpack option into dest; use ret for prefix (i.e., "optname=") */
|
||||||
|
dest = dname_dec(option, len, ret);
|
||||||
|
free(ret);
|
||||||
|
return dest;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
option += optlen;
|
option += optlen;
|
||||||
len -= optlen;
|
len -= optlen;
|
||||||
if (len <= 0) break;
|
if (len <= 0) break;
|
||||||
dest += sprintf(dest, " ");
|
dest += sprintf(dest, " ");
|
||||||
}
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -155,9 +168,7 @@ static char **fill_envp(struct dhcpMessage *packet)
|
|||||||
temp = get_option(packet, dhcp_options[i].code);
|
temp = get_option(packet, dhcp_options[i].code);
|
||||||
if (!temp)
|
if (!temp)
|
||||||
continue;
|
continue;
|
||||||
envp[j] = xmalloc(upper_length(temp[OPT_LEN - 2],
|
envp[j++] = alloc_fill_opts(temp, &dhcp_options[i]);
|
||||||
dhcp_options[i].flags & TYPE_MASK) + strlen(dhcp_options[i].name) + 2);
|
|
||||||
fill_options(envp[j++], temp, &dhcp_options[i]);
|
|
||||||
|
|
||||||
/* Fill in a subnet bits option for things like /24 */
|
/* Fill in a subnet bits option for things like /24 */
|
||||||
if (dhcp_options[i].code == DHCP_SUBNET) {
|
if (dhcp_options[i].code == DHCP_SUBNET) {
|
||||||
|
Loading…
Reference in New Issue
Block a user