aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--networking/udhcp/files.c86
1 files changed, 40 insertions, 46 deletions
diff --git a/networking/udhcp/files.c b/networking/udhcp/files.c
index a23e8862c..968d8ed79 100644
--- a/networking/udhcp/files.c
+++ b/networking/udhcp/files.c
@@ -21,7 +21,6 @@ static inline uint64_t hton64(uint64_t v)
21#endif 21#endif
22#define ntoh64(v) hton64(v) 22#define ntoh64(v) hton64(v)
23 23
24
25/* on these functions, make sure your datatype matches */ 24/* on these functions, make sure your datatype matches */
26static int FAST_FUNC read_nip(const char *line, void *arg) 25static int FAST_FUNC read_nip(const char *line, void *arg)
27{ 26{
@@ -35,13 +34,11 @@ static int FAST_FUNC read_nip(const char *line, void *arg)
35 return 1; 34 return 1;
36} 35}
37 36
38
39static int FAST_FUNC read_mac(const char *line, void *arg) 37static int FAST_FUNC read_mac(const char *line, void *arg)
40{ 38{
41 return NULL == ether_aton_r(line, (struct ether_addr *)arg); 39 return NULL == ether_aton_r(line, (struct ether_addr *)arg);
42} 40}
43 41
44
45static int FAST_FUNC read_str(const char *line, void *arg) 42static int FAST_FUNC read_str(const char *line, void *arg)
46{ 43{
47 char **dest = arg; 44 char **dest = arg;
@@ -51,30 +48,27 @@ static int FAST_FUNC read_str(const char *line, void *arg)
51 return 1; 48 return 1;
52} 49}
53 50
54
55static int FAST_FUNC read_u32(const char *line, void *arg) 51static int FAST_FUNC read_u32(const char *line, void *arg)
56{ 52{
57 *(uint32_t*)arg = bb_strtou32(line, NULL, 10); 53 *(uint32_t*)arg = bb_strtou32(line, NULL, 10);
58 return errno == 0; 54 return errno == 0;
59} 55}
60 56
61 57static int read_yn(const char *line, void *arg)
62static int FAST_FUNC read_yn(const char *line, void *arg)
63{ 58{
64 char *dest = arg; 59 char *dest = arg;
65 60
66 if (!strcasecmp("yes", line)) { 61 if (strcasecmp("yes", line) == 0) {
67 *dest = 1; 62 *dest = 1;
68 return 1; 63 return 1;
69 } 64 }
70 if (!strcasecmp("no", line)) { 65 if (strcasecmp("no", line) == 0) {
71 *dest = 0; 66 *dest = 0;
72 return 1; 67 return 1;
73 } 68 }
74 return 0; 69 return 0;
75} 70}
76 71
77
78/* find option 'code' in opt_list */ 72/* find option 'code' in opt_list */
79struct option_set* FAST_FUNC find_option(struct option_set *opt_list, uint8_t code) 73struct option_set* FAST_FUNC find_option(struct option_set *opt_list, uint8_t code)
80{ 74{
@@ -86,29 +80,33 @@ struct option_set* FAST_FUNC find_option(struct option_set *opt_list, uint8_t co
86 return NULL; 80 return NULL;
87} 81}
88 82
89
90/* add an option to the opt_list */ 83/* add an option to the opt_list */
91static void attach_option(struct option_set **opt_list, 84static NOINLINE void attach_option(
92 const struct dhcp_option *option, char *buffer, int length) 85 struct option_set **opt_list,
86 const struct dhcp_option *option,
87 char *buffer,
88 int length)
93{ 89{
94 struct option_set *existing, *new, **curr; 90 struct option_set *existing, *new, **curr;
91#if ENABLE_FEATURE_UDHCP_RFC3397
92 char *allocated = NULL;
93#endif
95 94
96 existing = find_option(*opt_list, option->code); 95 existing = find_option(*opt_list, option->code);
97 if (!existing) { 96 if (!existing) {
98 log2("Attaching option %02x to list", option->code); 97 log2("Attaching option %02x to list", option->code);
99
100#if ENABLE_FEATURE_UDHCP_RFC3397 98#if ENABLE_FEATURE_UDHCP_RFC3397
101 if ((option->flags & OPTION_TYPE_MASK) == OPTION_STR1035) 99 if ((option->flags & OPTION_TYPE_MASK) == OPTION_STR1035) {
102 /* reuse buffer and length for RFC1035-formatted string */ 100 /* reuse buffer and length for RFC1035-formatted string */
103 buffer = (char *)dname_enc(NULL, 0, buffer, &length); 101 allocated = buffer = (char *)dname_enc(NULL, 0, buffer, &length);
102 }
104#endif 103#endif
105
106 /* make a new option */ 104 /* make a new option */
107 new = xmalloc(sizeof(*new)); 105 new = xmalloc(sizeof(*new));
108 new->data = xmalloc(length + 2); 106 new->data = xmalloc(length + OPT_DATA);
109 new->data[OPT_CODE] = option->code; 107 new->data[OPT_CODE] = option->code;
110 new->data[OPT_LEN] = length; 108 new->data[OPT_LEN] = length;
111 memcpy(new->data + 2, buffer, length); 109 memcpy(new->data + OPT_DATA, buffer, length);
112 110
113 curr = opt_list; 111 curr = opt_list;
114 while (*curr && (*curr)->data[OPT_CODE] < option->code) 112 while (*curr && (*curr)->data[OPT_CODE] < option->code)
@@ -116,44 +114,41 @@ static void attach_option(struct option_set **opt_list,
116 114
117 new->next = *curr; 115 new->next = *curr;
118 *curr = new; 116 *curr = new;
119#if ENABLE_FEATURE_UDHCP_RFC3397 117 goto ret;
120 if ((option->flags & OPTION_TYPE_MASK) == OPTION_STR1035 && buffer != NULL)
121 free(buffer);
122#endif
123 return;
124 } 118 }
125 119
126 /* add it to an existing option */
127 log1("Attaching option %02x to existing member of list", option->code);
128 if (option->flags & OPTION_LIST) { 120 if (option->flags & OPTION_LIST) {
121 unsigned old_len;
122
123 /* add it to an existing option */
124 log1("Attaching option %02x to existing member of list", option->code);
125 old_len = existing->data[OPT_LEN];
129#if ENABLE_FEATURE_UDHCP_RFC3397 126#if ENABLE_FEATURE_UDHCP_RFC3397
130 if ((option->flags & OPTION_TYPE_MASK) == OPTION_STR1035) 127 if ((option->flags & OPTION_TYPE_MASK) == OPTION_STR1035) {
131 /* reuse buffer and length for RFC1035-formatted string */ 128 /* reuse buffer and length for RFC1035-formatted string */
132 buffer = (char *)dname_enc(existing->data + 2, 129 allocated = buffer = (char *)dname_enc(existing->data + OPT_DATA, old_len, buffer, &length);
133 existing->data[OPT_LEN], buffer, &length); 130 }
134#endif 131#endif
135 if (existing->data[OPT_LEN] + length <= 255) { 132 if (old_len + length < 255) {
136 existing->data = xrealloc(existing->data, 133 /* actually 255 is ok too, but adding a space can overlow it */
137 existing->data[OPT_LEN] + length + 3); 134
135 existing->data = xrealloc(existing->data, OPT_DATA + 1 + old_len + length);
138 if ((option->flags & OPTION_TYPE_MASK) == OPTION_STRING) { 136 if ((option->flags & OPTION_TYPE_MASK) == OPTION_STRING) {
139 /* ' ' can bring us to 256 - bad */
140 if (existing->data[OPT_LEN] + length >= 255)
141 return;
142 /* add space separator between STRING options in a list */ 137 /* add space separator between STRING options in a list */
143 existing->data[existing->data[OPT_LEN] + 2] = ' '; 138 existing->data[OPT_DATA + old_len] = ' ';
144 existing->data[OPT_LEN]++; 139 old_len++;
145 } 140 }
146 memcpy(existing->data + existing->data[OPT_LEN] + 2, buffer, length); 141 memcpy(existing->data + OPT_DATA + old_len, buffer, length);
147 existing->data[OPT_LEN] += length; 142 existing->data[OPT_LEN] = old_len + length;
148 } /* else, ignore the data, we could put this in a second option in the future */ 143 } /* else, ignore the data, we could put this in a second option in the future */
144 } /* else, ignore the new data */
145
146 ret: ;
149#if ENABLE_FEATURE_UDHCP_RFC3397 147#if ENABLE_FEATURE_UDHCP_RFC3397
150 if ((option->flags & OPTION_TYPE_MASK) == OPTION_STR1035 && buffer != NULL) 148 free(allocated);
151 free(buffer);
152#endif 149#endif
153 } /* else, ignore the new data */
154} 150}
155 151
156
157/* read a dhcp option and add it to opt_list */ 152/* read a dhcp option and add it to opt_list */
158static int FAST_FUNC read_opt(const char *const_line, void *arg) 153static int FAST_FUNC read_opt(const char *const_line, void *arg)
159{ 154{
@@ -166,7 +161,7 @@ static int FAST_FUNC read_opt(const char *const_line, void *arg)
166 uint16_t *result_u16 = (uint16_t *) buffer; 161 uint16_t *result_u16 = (uint16_t *) buffer;
167 uint32_t *result_u32 = (uint32_t *) buffer; 162 uint32_t *result_u32 = (uint32_t *) buffer;
168 163
169 /* Cheat, the only const line we'll actually get is "" */ 164 /* Cheat, the only *const* line possible is "" */
170 line = (char *) const_line; 165 line = (char *) const_line;
171 opt = strtok(line, " \t="); 166 opt = strtok(line, " \t=");
172 if (!opt) 167 if (!opt)
@@ -180,7 +175,8 @@ static int FAST_FUNC read_opt(const char *const_line, void *arg)
180 retval = 0; 175 retval = 0;
181 do { 176 do {
182 val = strtok(NULL, ", \t"); 177 val = strtok(NULL, ", \t");
183 if (!val) break; 178 if (!val)
179 break;
184 length = dhcp_option_lengths[option->flags & OPTION_TYPE_MASK]; 180 length = dhcp_option_lengths[option->flags & OPTION_TYPE_MASK];
185 retval = 0; 181 retval = 0;
186 opt = buffer; /* new meaning for variable opt */ 182 opt = buffer; /* new meaning for variable opt */
@@ -337,7 +333,6 @@ void FAST_FUNC read_config(const char *file)
337 server_config.end_ip = ntohl(server_config.end_ip); 333 server_config.end_ip = ntohl(server_config.end_ip);
338} 334}
339 335
340
341void FAST_FUNC write_leases(void) 336void FAST_FUNC write_leases(void)
342{ 337{
343 int fd; 338 int fd;
@@ -385,7 +380,6 @@ void FAST_FUNC write_leases(void)
385 } 380 }
386} 381}
387 382
388
389void FAST_FUNC read_leases(const char *file) 383void FAST_FUNC read_leases(const char *file)
390{ 384{
391 struct dyn_lease lease; 385 struct dyn_lease lease;