mirror of
https://github.com/sheumann/hush.git
synced 2024-12-21 23:29:34 +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.
|
||||
|
||||
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.
|
||||
|
@ -6,13 +6,14 @@
|
||||
#
|
||||
|
||||
lib-y:=
|
||||
lib-$(CONFIG_APP_UDHCPC) += common.o options.o packet.o pidfile.o \
|
||||
signalpipe.o socket.o
|
||||
lib-$(CONFIG_APP_UDHCPD) += common.o options.o packet.o pidfile.o \
|
||||
signalpipe.o socket.o
|
||||
lib-$(CONFIG_APP_UDHCPC) += dhcpc.o clientpacket.o clientsocket.o \
|
||||
script.o
|
||||
lib-$(CONFIG_APP_UDHCPD) += dhcpd.o arpping.o files.o leases.o \
|
||||
serverpacket.o static_leases.o
|
||||
lib-$(CONFIG_APP_DUMPLEASES) += dumpleases.o
|
||||
lib-$(CONFIG_APP_UDHCPC) += common.o options.o packet.o pidfile.o \
|
||||
signalpipe.o socket.o
|
||||
lib-$(CONFIG_APP_UDHCPD) += common.o options.o packet.o pidfile.o \
|
||||
signalpipe.o socket.o
|
||||
lib-$(CONFIG_APP_UDHCPC) += dhcpc.o clientpacket.o clientsocket.o \
|
||||
script.o
|
||||
lib-$(CONFIG_APP_UDHCPD) += dhcpd.o arpping.o files.o leases.o \
|
||||
serverpacket.o static_leases.o
|
||||
lib-$(CONFIG_APP_DUMPLEASES) += dumpleases.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) {
|
||||
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 */
|
||||
new = xmalloc(sizeof(struct option_set));
|
||||
new->data = xmalloc(length + 2);
|
||||
@ -117,12 +123,22 @@ static void attach_option(struct option_set **opt_list,
|
||||
|
||||
new->next = *curr;
|
||||
*curr = new;
|
||||
#if ENABLE_FEATURE_RFC3397
|
||||
if ((option->flags & TYPE_MASK) == OPTION_STR1035 && buffer != NULL)
|
||||
free(buffer);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
/* add it to an existing option */
|
||||
DEBUG("Attaching option %s to existing member of list", option->name);
|
||||
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) {
|
||||
existing->data = xrealloc(existing->data,
|
||||
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);
|
||||
existing->data[OPT_LEN] += length;
|
||||
} /* 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 */
|
||||
}
|
||||
|
||||
@ -183,6 +203,9 @@ static int read_opt(const char *const_line, void *arg)
|
||||
if (retval) retval = read_ip(val, buffer + 4);
|
||||
break;
|
||||
case OPTION_STRING:
|
||||
#if ENABLE_FEATURE_RFC3397
|
||||
case OPTION_STR1035:
|
||||
#endif
|
||||
length = strlen(val);
|
||||
if (length > 0) {
|
||||
if (length > 254) length = 254;
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
/* supported options are easily added here */
|
||||
const struct dhcp_option dhcp_options[] = {
|
||||
/* name[10] flags code */
|
||||
/* name[12] flags code */
|
||||
{"subnet", OPTION_IP | OPTION_REQ, 0x01},
|
||||
{"timezone", OPTION_S32, 0x02},
|
||||
{"router", OPTION_IP | OPTION_LIST | OPTION_REQ, 0x03},
|
||||
@ -43,6 +43,9 @@ const struct dhcp_option dhcp_options[] = {
|
||||
{"tftp", OPTION_STRING, 0x42},
|
||||
{"bootfile", OPTION_STRING, 0x43},
|
||||
{"userclass", OPTION_STRING, 0x4D},
|
||||
#if ENABLE_FEATURE_RFC3397
|
||||
{"search", OPTION_STR1035 | OPTION_LIST | OPTION_REQ, 0x77},
|
||||
#endif
|
||||
/* MSIE's "Web Proxy Autodiscovery Protocol" support */
|
||||
{"wpad", OPTION_STRING, 0xfc},
|
||||
{"", 0x00, 0x00}
|
||||
@ -54,6 +57,9 @@ const unsigned char option_lengths[] = {
|
||||
[OPTION_IP_PAIR] = 8,
|
||||
[OPTION_BOOLEAN] = 1,
|
||||
[OPTION_STRING] = 1,
|
||||
#if ENABLE_FEATURE_RFC3397
|
||||
[OPTION_STR1035] = 1,
|
||||
#endif
|
||||
[OPTION_U8] = 1,
|
||||
[OPTION_U16] = 2,
|
||||
[OPTION_S16] = 2,
|
||||
|
@ -9,6 +9,9 @@ enum {
|
||||
OPTION_IP=1,
|
||||
OPTION_IP_PAIR,
|
||||
OPTION_STRING,
|
||||
#if ENABLE_FEATURE_RFC3397
|
||||
OPTION_STR1035, /* RFC1035 compressed domain name list */
|
||||
#endif
|
||||
OPTION_BOOLEAN,
|
||||
OPTION_U8,
|
||||
OPTION_U16,
|
||||
@ -33,5 +36,9 @@ uint8_t *get_option(struct dhcpMessage *packet, int code);
|
||||
int end_option(uint8_t *optionptr);
|
||||
int add_option_string(uint8_t *optionptr, uint8_t *string);
|
||||
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
|
||||
|
@ -19,6 +19,9 @@ static const int max_option_length[] = {
|
||||
[OPTION_IP] = sizeof("255.255.255.255 "),
|
||||
[OPTION_IP_PAIR] = sizeof("255.255.255.255 ") * 2,
|
||||
[OPTION_STRING] = 1,
|
||||
#if ENABLE_FEATURE_RFC3397
|
||||
[OPTION_STR1035] = 1,
|
||||
#endif
|
||||
[OPTION_BOOLEAN] = sizeof("yes "),
|
||||
[OPTION_U8] = sizeof("255 "),
|
||||
[OPTION_U16] = sizeof("65535 "),
|
||||
@ -53,21 +56,23 @@ static int mton(struct in_addr *mask)
|
||||
}
|
||||
|
||||
|
||||
/* Fill dest with the text of option 'option'. */
|
||||
static void fill_options(char *dest, uint8_t *option,
|
||||
const struct dhcp_option *type_p)
|
||||
/* Allocate and fill with the text of option 'option'. */
|
||||
static char *alloc_fill_opts(uint8_t *option, const struct dhcp_option *type_p)
|
||||
{
|
||||
int type, optlen;
|
||||
int len, type, optlen;
|
||||
uint16_t val_u16;
|
||||
int16_t val_s16;
|
||||
uint32_t val_u32;
|
||||
int32_t val_s32;
|
||||
int len = option[OPT_LEN - 2];
|
||||
|
||||
dest += sprintf(dest, "%s=", type_p->name);
|
||||
char *dest, *ret;
|
||||
|
||||
len = option[OPT_LEN - 2];
|
||||
type = type_p->flags & TYPE_MASK;
|
||||
optlen = option_lengths[type];
|
||||
|
||||
dest = ret = xmalloc(upper_length(len, type) + strlen(type_p->name) + 2);
|
||||
dest += sprintf(ret, "%s=", type_p->name);
|
||||
|
||||
for (;;) {
|
||||
switch (type) {
|
||||
case OPTION_IP_PAIR:
|
||||
@ -103,13 +108,21 @@ static void fill_options(char *dest, uint8_t *option,
|
||||
case OPTION_STRING:
|
||||
memcpy(dest, option, len);
|
||||
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;
|
||||
len -= optlen;
|
||||
if (len <= 0) break;
|
||||
dest += sprintf(dest, " ");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -155,9 +168,7 @@ static char **fill_envp(struct dhcpMessage *packet)
|
||||
temp = get_option(packet, dhcp_options[i].code);
|
||||
if (!temp)
|
||||
continue;
|
||||
envp[j] = xmalloc(upper_length(temp[OPT_LEN - 2],
|
||||
dhcp_options[i].flags & TYPE_MASK) + strlen(dhcp_options[i].name) + 2);
|
||||
fill_options(envp[j++], temp, &dhcp_options[i]);
|
||||
envp[j++] = alloc_fill_opts(temp, &dhcp_options[i]);
|
||||
|
||||
/* Fill in a subnet bits option for things like /24 */
|
||||
if (dhcp_options[i].code == DHCP_SUBNET) {
|
||||
|
Loading…
Reference in New Issue
Block a user