summaryrefslogtreecommitdiff
path: root/networking/udhcp
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-02-27 21:15:08 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-02-27 21:15:08 +0000
commit5066473d411d6a474af3393d1b62a58ee3313861 (patch)
tree7649f98fbe056b9b7f87893f70b5b50cc5007fe9 /networking/udhcp
parent966bb4376665e0cf22e64f7901fb956edbd2f1a9 (diff)
downloadbusybox-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.in8
-rw-r--r--networking/udhcp/Kbuild19
-rw-r--r--networking/udhcp/files.c23
-rw-r--r--networking/udhcp/options.c8
-rw-r--r--networking/udhcp/options.h7
-rw-r--r--networking/udhcp/script.c33
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
69config 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
8lib-y:= 8lib-y:=
9lib-$(CONFIG_APP_UDHCPC) += common.o options.o packet.o pidfile.o \ 9lib-$(CONFIG_APP_UDHCPC) += common.o options.o packet.o pidfile.o \
10 signalpipe.o socket.o 10 signalpipe.o socket.o
11lib-$(CONFIG_APP_UDHCPD) += common.o options.o packet.o pidfile.o \ 11lib-$(CONFIG_APP_UDHCPD) += common.o options.o packet.o pidfile.o \
12 signalpipe.o socket.o 12 signalpipe.o socket.o
13lib-$(CONFIG_APP_UDHCPC) += dhcpc.o clientpacket.o clientsocket.o \ 13lib-$(CONFIG_APP_UDHCPC) += dhcpc.o clientpacket.o clientsocket.o \
14 script.o 14 script.o
15lib-$(CONFIG_APP_UDHCPD) += dhcpd.o arpping.o files.o leases.o \ 15lib-$(CONFIG_APP_UDHCPD) += dhcpd.o arpping.o files.o leases.o \
16 serverpacket.o static_leases.o 16 serverpacket.o static_leases.o
17lib-$(CONFIG_APP_DUMPLEASES) += dumpleases.o 17lib-$(CONFIG_APP_DUMPLEASES) += dumpleases.o
18lib-$(CONFIG_APP_DHCPRELAY) += dhcprelay.o 18lib-$(CONFIG_APP_DHCPRELAY) += dhcprelay.o
19lib-$(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 */
13const struct dhcp_option dhcp_options[] = { 13const 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);
33int end_option(uint8_t *optionptr); 36int end_option(uint8_t *optionptr);
34int add_option_string(uint8_t *optionptr, uint8_t *string); 37int add_option_string(uint8_t *optionptr, uint8_t *string);
35int add_simple_option(uint8_t *optionptr, uint8_t code, uint32_t data); 38int add_simple_option(uint8_t *optionptr, uint8_t code, uint32_t data);
39#if ENABLE_FEATURE_RFC3397
40char *dname_dec(const uint8_t *cstr, int clen, const char *pre);
41uint8_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'. */
57static void fill_options(char *dest, uint8_t *option, 60static 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) {