diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-02-27 21:15:08 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-02-27 21:15:08 +0000 |
commit | 5066473d411d6a474af3393d1b62a58ee3313861 (patch) | |
tree | 7649f98fbe056b9b7f87893f70b5b50cc5007fe9 /networking/udhcp | |
parent | 966bb4376665e0cf22e64f7901fb956edbd2f1a9 (diff) | |
download | busybox-w32-5066473d411d6a474af3393d1b62a58ee3313861.tar.gz busybox-w32-5066473d411d6a474af3393d1b62a58ee3313861.tar.bz2 busybox-w32-5066473d411d6a474af3393d1b62a58ee3313861.zip |
udhcp: optionally support RFC3397 (by Gabriel L. Somlo <somlo@cmu.edu>)
Diffstat (limited to 'networking/udhcp')
-rw-r--r-- | networking/udhcp/Config.in | 8 | ||||
-rw-r--r-- | networking/udhcp/Kbuild | 19 | ||||
-rw-r--r-- | networking/udhcp/files.c | 23 | ||||
-rw-r--r-- | networking/udhcp/options.c | 8 | ||||
-rw-r--r-- | networking/udhcp/options.h | 7 | ||||
-rw-r--r-- | networking/udhcp/script.c | 33 |
6 files changed, 77 insertions, 21 deletions
diff --git a/networking/udhcp/Config.in b/networking/udhcp/Config.in index f633473eb..9dd02c497 100644 --- a/networking/udhcp/Config.in +++ b/networking/udhcp/Config.in | |||
@@ -65,3 +65,11 @@ config FEATURE_UDHCP_DEBUG | |||
65 | the background. | 65 | the background. |
66 | 66 | ||
67 | See http://udhcp.busybox.net for further details. | 67 | See http://udhcp.busybox.net for further details. |
68 | |||
69 | config FEATURE_RFC3397 | ||
70 | bool "Support for RFC3397 domain search (experimental)" | ||
71 | default n | ||
72 | depends on APP_UDHCPD || APP_UDHCPC | ||
73 | help | ||
74 | If selected, both client and server will support passing of domain | ||
75 | search lists via option 119, specified in RFC3397. | ||
diff --git a/networking/udhcp/Kbuild b/networking/udhcp/Kbuild index dc2c01f61..57d2511f0 100644 --- a/networking/udhcp/Kbuild +++ b/networking/udhcp/Kbuild | |||
@@ -6,13 +6,14 @@ | |||
6 | # | 6 | # |
7 | 7 | ||
8 | lib-y:= | 8 | lib-y:= |
9 | lib-$(CONFIG_APP_UDHCPC) += common.o options.o packet.o pidfile.o \ | 9 | lib-$(CONFIG_APP_UDHCPC) += common.o options.o packet.o pidfile.o \ |
10 | signalpipe.o socket.o | 10 | signalpipe.o socket.o |
11 | lib-$(CONFIG_APP_UDHCPD) += common.o options.o packet.o pidfile.o \ | 11 | lib-$(CONFIG_APP_UDHCPD) += common.o options.o packet.o pidfile.o \ |
12 | signalpipe.o socket.o | 12 | signalpipe.o socket.o |
13 | lib-$(CONFIG_APP_UDHCPC) += dhcpc.o clientpacket.o clientsocket.o \ | 13 | lib-$(CONFIG_APP_UDHCPC) += dhcpc.o clientpacket.o clientsocket.o \ |
14 | script.o | 14 | script.o |
15 | lib-$(CONFIG_APP_UDHCPD) += dhcpd.o arpping.o files.o leases.o \ | 15 | lib-$(CONFIG_APP_UDHCPD) += dhcpd.o arpping.o files.o leases.o \ |
16 | serverpacket.o static_leases.o | 16 | serverpacket.o static_leases.o |
17 | lib-$(CONFIG_APP_DUMPLEASES) += dumpleases.o | 17 | lib-$(CONFIG_APP_DUMPLEASES) += dumpleases.o |
18 | lib-$(CONFIG_APP_DHCPRELAY) += dhcprelay.o | 18 | lib-$(CONFIG_APP_DHCPRELAY) += dhcprelay.o |
19 | lib-$(CONFIG_FEATURE_RFC3397) += domain_codec.o | ||
diff --git a/networking/udhcp/files.c b/networking/udhcp/files.c index e35f50a17..ab6f4a3e4 100644 --- a/networking/udhcp/files.c +++ b/networking/udhcp/files.c | |||
@@ -104,6 +104,12 @@ static void attach_option(struct option_set **opt_list, | |||
104 | if (!existing) { | 104 | if (!existing) { |
105 | DEBUG("Attaching option %s to list", option->name); | 105 | DEBUG("Attaching option %s to list", option->name); |
106 | 106 | ||
107 | #if ENABLE_FEATURE_RFC3397 | ||
108 | if ((option->flags & TYPE_MASK) == OPTION_STR1035) | ||
109 | /* reuse buffer and length for RFC1035-formatted string */ | ||
110 | buffer = dname_enc(NULL, 0, buffer, &length); | ||
111 | #endif | ||
112 | |||
107 | /* make a new option */ | 113 | /* make a new option */ |
108 | new = xmalloc(sizeof(struct option_set)); | 114 | new = xmalloc(sizeof(struct option_set)); |
109 | new->data = xmalloc(length + 2); | 115 | new->data = xmalloc(length + 2); |
@@ -117,12 +123,22 @@ static void attach_option(struct option_set **opt_list, | |||
117 | 123 | ||
118 | new->next = *curr; | 124 | new->next = *curr; |
119 | *curr = new; | 125 | *curr = new; |
126 | #if ENABLE_FEATURE_RFC3397 | ||
127 | if ((option->flags & TYPE_MASK) == OPTION_STR1035 && buffer != NULL) | ||
128 | free(buffer); | ||
129 | #endif | ||
120 | return; | 130 | return; |
121 | } | 131 | } |
122 | 132 | ||
123 | /* add it to an existing option */ | 133 | /* add it to an existing option */ |
124 | DEBUG("Attaching option %s to existing member of list", option->name); | 134 | DEBUG("Attaching option %s to existing member of list", option->name); |
125 | if (option->flags & OPTION_LIST) { | 135 | if (option->flags & OPTION_LIST) { |
136 | #if ENABLE_FEATURE_RFC3397 | ||
137 | if ((option->flags & TYPE_MASK) == OPTION_STR1035) | ||
138 | /* reuse buffer and length for RFC1035-formatted string */ | ||
139 | buffer = dname_enc(existing->data + 2, | ||
140 | existing->data[OPT_LEN], buffer, &length); | ||
141 | #endif | ||
126 | if (existing->data[OPT_LEN] + length <= 255) { | 142 | if (existing->data[OPT_LEN] + length <= 255) { |
127 | existing->data = xrealloc(existing->data, | 143 | existing->data = xrealloc(existing->data, |
128 | existing->data[OPT_LEN] + length + 3); | 144 | existing->data[OPT_LEN] + length + 3); |
@@ -137,6 +153,10 @@ static void attach_option(struct option_set **opt_list, | |||
137 | memcpy(existing->data + existing->data[OPT_LEN] + 2, buffer, length); | 153 | memcpy(existing->data + existing->data[OPT_LEN] + 2, buffer, length); |
138 | existing->data[OPT_LEN] += length; | 154 | existing->data[OPT_LEN] += length; |
139 | } /* else, ignore the data, we could put this in a second option in the future */ | 155 | } /* else, ignore the data, we could put this in a second option in the future */ |
156 | #if ENABLE_FEATURE_RFC3397 | ||
157 | if ((option->flags & TYPE_MASK) == OPTION_STR1035 && buffer != NULL) | ||
158 | free(buffer); | ||
159 | #endif | ||
140 | } /* else, ignore the new data */ | 160 | } /* else, ignore the new data */ |
141 | } | 161 | } |
142 | 162 | ||
@@ -183,6 +203,9 @@ static int read_opt(const char *const_line, void *arg) | |||
183 | if (retval) retval = read_ip(val, buffer + 4); | 203 | if (retval) retval = read_ip(val, buffer + 4); |
184 | break; | 204 | break; |
185 | case OPTION_STRING: | 205 | case OPTION_STRING: |
206 | #if ENABLE_FEATURE_RFC3397 | ||
207 | case OPTION_STR1035: | ||
208 | #endif | ||
186 | length = strlen(val); | 209 | length = strlen(val); |
187 | if (length > 0) { | 210 | if (length > 0) { |
188 | if (length > 254) length = 254; | 211 | if (length > 254) length = 254; |
diff --git a/networking/udhcp/options.c b/networking/udhcp/options.c index bda6efc7e..a58adb9a9 100644 --- a/networking/udhcp/options.c +++ b/networking/udhcp/options.c | |||
@@ -11,7 +11,7 @@ | |||
11 | 11 | ||
12 | /* supported options are easily added here */ | 12 | /* supported options are easily added here */ |
13 | const struct dhcp_option dhcp_options[] = { | 13 | const struct dhcp_option dhcp_options[] = { |
14 | /* name[10] flags code */ | 14 | /* name[12] flags code */ |
15 | {"subnet", OPTION_IP | OPTION_REQ, 0x01}, | 15 | {"subnet", OPTION_IP | OPTION_REQ, 0x01}, |
16 | {"timezone", OPTION_S32, 0x02}, | 16 | {"timezone", OPTION_S32, 0x02}, |
17 | {"router", OPTION_IP | OPTION_LIST | OPTION_REQ, 0x03}, | 17 | {"router", OPTION_IP | OPTION_LIST | OPTION_REQ, 0x03}, |
@@ -43,6 +43,9 @@ const struct dhcp_option dhcp_options[] = { | |||
43 | {"tftp", OPTION_STRING, 0x42}, | 43 | {"tftp", OPTION_STRING, 0x42}, |
44 | {"bootfile", OPTION_STRING, 0x43}, | 44 | {"bootfile", OPTION_STRING, 0x43}, |
45 | {"userclass", OPTION_STRING, 0x4D}, | 45 | {"userclass", OPTION_STRING, 0x4D}, |
46 | #if ENABLE_FEATURE_RFC3397 | ||
47 | {"search", OPTION_STR1035 | OPTION_LIST | OPTION_REQ, 0x77}, | ||
48 | #endif | ||
46 | /* MSIE's "Web Proxy Autodiscovery Protocol" support */ | 49 | /* MSIE's "Web Proxy Autodiscovery Protocol" support */ |
47 | {"wpad", OPTION_STRING, 0xfc}, | 50 | {"wpad", OPTION_STRING, 0xfc}, |
48 | {"", 0x00, 0x00} | 51 | {"", 0x00, 0x00} |
@@ -54,6 +57,9 @@ const unsigned char option_lengths[] = { | |||
54 | [OPTION_IP_PAIR] = 8, | 57 | [OPTION_IP_PAIR] = 8, |
55 | [OPTION_BOOLEAN] = 1, | 58 | [OPTION_BOOLEAN] = 1, |
56 | [OPTION_STRING] = 1, | 59 | [OPTION_STRING] = 1, |
60 | #if ENABLE_FEATURE_RFC3397 | ||
61 | [OPTION_STR1035] = 1, | ||
62 | #endif | ||
57 | [OPTION_U8] = 1, | 63 | [OPTION_U8] = 1, |
58 | [OPTION_U16] = 2, | 64 | [OPTION_U16] = 2, |
59 | [OPTION_S16] = 2, | 65 | [OPTION_S16] = 2, |
diff --git a/networking/udhcp/options.h b/networking/udhcp/options.h index 588504e5d..11f013fd4 100644 --- a/networking/udhcp/options.h +++ b/networking/udhcp/options.h | |||
@@ -9,6 +9,9 @@ enum { | |||
9 | OPTION_IP=1, | 9 | OPTION_IP=1, |
10 | OPTION_IP_PAIR, | 10 | OPTION_IP_PAIR, |
11 | OPTION_STRING, | 11 | OPTION_STRING, |
12 | #if ENABLE_FEATURE_RFC3397 | ||
13 | OPTION_STR1035, /* RFC1035 compressed domain name list */ | ||
14 | #endif | ||
12 | OPTION_BOOLEAN, | 15 | OPTION_BOOLEAN, |
13 | OPTION_U8, | 16 | OPTION_U8, |
14 | OPTION_U16, | 17 | OPTION_U16, |
@@ -33,5 +36,9 @@ uint8_t *get_option(struct dhcpMessage *packet, int code); | |||
33 | int end_option(uint8_t *optionptr); | 36 | int end_option(uint8_t *optionptr); |
34 | int add_option_string(uint8_t *optionptr, uint8_t *string); | 37 | int add_option_string(uint8_t *optionptr, uint8_t *string); |
35 | int add_simple_option(uint8_t *optionptr, uint8_t code, uint32_t data); | 38 | int add_simple_option(uint8_t *optionptr, uint8_t code, uint32_t data); |
39 | #if ENABLE_FEATURE_RFC3397 | ||
40 | char *dname_dec(const uint8_t *cstr, int clen, const char *pre); | ||
41 | uint8_t *dname_enc(const uint8_t *cstr, int clen, const char *src, int *retlen); | ||
42 | #endif | ||
36 | 43 | ||
37 | #endif | 44 | #endif |
diff --git a/networking/udhcp/script.c b/networking/udhcp/script.c index d2b0bb05b..dc8ff7a1c 100644 --- a/networking/udhcp/script.c +++ b/networking/udhcp/script.c | |||
@@ -19,6 +19,9 @@ static const int max_option_length[] = { | |||
19 | [OPTION_IP] = sizeof("255.255.255.255 "), | 19 | [OPTION_IP] = sizeof("255.255.255.255 "), |
20 | [OPTION_IP_PAIR] = sizeof("255.255.255.255 ") * 2, | 20 | [OPTION_IP_PAIR] = sizeof("255.255.255.255 ") * 2, |
21 | [OPTION_STRING] = 1, | 21 | [OPTION_STRING] = 1, |
22 | #if ENABLE_FEATURE_RFC3397 | ||
23 | [OPTION_STR1035] = 1, | ||
24 | #endif | ||
22 | [OPTION_BOOLEAN] = sizeof("yes "), | 25 | [OPTION_BOOLEAN] = sizeof("yes "), |
23 | [OPTION_U8] = sizeof("255 "), | 26 | [OPTION_U8] = sizeof("255 "), |
24 | [OPTION_U16] = sizeof("65535 "), | 27 | [OPTION_U16] = sizeof("65535 "), |
@@ -53,21 +56,23 @@ static int mton(struct in_addr *mask) | |||
53 | } | 56 | } |
54 | 57 | ||
55 | 58 | ||
56 | /* Fill dest with the text of option 'option'. */ | 59 | /* Allocate and fill with the text of option 'option'. */ |
57 | static void fill_options(char *dest, uint8_t *option, | 60 | static char *alloc_fill_opts(uint8_t *option, const struct dhcp_option *type_p) |
58 | const struct dhcp_option *type_p) | ||
59 | { | 61 | { |
60 | int type, optlen; | 62 | int len, type, optlen; |
61 | uint16_t val_u16; | 63 | uint16_t val_u16; |
62 | int16_t val_s16; | 64 | int16_t val_s16; |
63 | uint32_t val_u32; | 65 | uint32_t val_u32; |
64 | int32_t val_s32; | 66 | int32_t val_s32; |
65 | int len = option[OPT_LEN - 2]; | 67 | char *dest, *ret; |
66 | |||
67 | dest += sprintf(dest, "%s=", type_p->name); | ||
68 | 68 | ||
69 | len = option[OPT_LEN - 2]; | ||
69 | type = type_p->flags & TYPE_MASK; | 70 | type = type_p->flags & TYPE_MASK; |
70 | optlen = option_lengths[type]; | 71 | optlen = option_lengths[type]; |
72 | |||
73 | dest = ret = xmalloc(upper_length(len, type) + strlen(type_p->name) + 2); | ||
74 | dest += sprintf(ret, "%s=", type_p->name); | ||
75 | |||
71 | for (;;) { | 76 | for (;;) { |
72 | switch (type) { | 77 | switch (type) { |
73 | case OPTION_IP_PAIR: | 78 | case OPTION_IP_PAIR: |
@@ -103,13 +108,21 @@ static void fill_options(char *dest, uint8_t *option, | |||
103 | case OPTION_STRING: | 108 | case OPTION_STRING: |
104 | memcpy(dest, option, len); | 109 | memcpy(dest, option, len); |
105 | dest[len] = '\0'; | 110 | dest[len] = '\0'; |
106 | return; /* Short circuit this case */ | 111 | return ret; /* Short circuit this case */ |
112 | #if ENABLE_FEATURE_RFC3397 | ||
113 | case OPTION_STR1035: | ||
114 | /* unpack option into dest; use ret for prefix (i.e., "optname=") */ | ||
115 | dest = dname_dec(option, len, ret); | ||
116 | free(ret); | ||
117 | return dest; | ||
118 | #endif | ||
107 | } | 119 | } |
108 | option += optlen; | 120 | option += optlen; |
109 | len -= optlen; | 121 | len -= optlen; |
110 | if (len <= 0) break; | 122 | if (len <= 0) break; |
111 | dest += sprintf(dest, " "); | 123 | dest += sprintf(dest, " "); |
112 | } | 124 | } |
125 | return ret; | ||
113 | } | 126 | } |
114 | 127 | ||
115 | 128 | ||
@@ -155,9 +168,7 @@ static char **fill_envp(struct dhcpMessage *packet) | |||
155 | temp = get_option(packet, dhcp_options[i].code); | 168 | temp = get_option(packet, dhcp_options[i].code); |
156 | if (!temp) | 169 | if (!temp) |
157 | continue; | 170 | continue; |
158 | envp[j] = xmalloc(upper_length(temp[OPT_LEN - 2], | 171 | envp[j++] = alloc_fill_opts(temp, &dhcp_options[i]); |
159 | dhcp_options[i].flags & TYPE_MASK) + strlen(dhcp_options[i].name) + 2); | ||
160 | fill_options(envp[j++], temp, &dhcp_options[i]); | ||
161 | 172 | ||
162 | /* Fill in a subnet bits option for things like /24 */ | 173 | /* Fill in a subnet bits option for things like /24 */ |
163 | if (dhcp_options[i].code == DHCP_SUBNET) { | 174 | if (dhcp_options[i].code == DHCP_SUBNET) { |