|
@@ -103,7 +103,7 @@ static unsigned int dhcp_option_len ( struct dhcp_option *option ) {
|
103
|
103
|
* DHCP option block. Encapsulated options may be searched for by
|
104
|
104
|
* using DHCP_ENCAP_OPT() to construct the tag value.
|
105
|
105
|
*
|
106
|
|
- * If the option is encapsulated, and @c encapsulator is non-NULL, it
|
|
106
|
+ * If the option is encapsulated, and @c encap_offset is non-NULL, it
|
107
|
107
|
* will be filled in with the offset of the encapsulating option.
|
108
|
108
|
*
|
109
|
109
|
* This routine is designed to be paranoid. It does not assume that
|
|
@@ -136,8 +136,15 @@ static int find_dhcp_option_with_encap ( struct dhcp_options *options,
|
136
|
136
|
if ( remaining < 0 )
|
137
|
137
|
break;
|
138
|
138
|
/* Check for explicit end marker */
|
139
|
|
- if ( option->tag == DHCP_END )
|
140
|
|
- break;
|
|
139
|
+ if ( option->tag == DHCP_END ) {
|
|
140
|
+ if ( tag == DHCP_END )
|
|
141
|
+ /* Special case where the caller is interested
|
|
142
|
+ * in whether we have this marker or not.
|
|
143
|
+ */
|
|
144
|
+ return offset;
|
|
145
|
+ else
|
|
146
|
+ break;
|
|
147
|
+ }
|
141
|
148
|
/* Check for matching tag */
|
142
|
149
|
if ( option->tag == tag ) {
|
143
|
150
|
DBGC ( options, "DHCPOPT %p found %s (length %d)\n",
|
|
@@ -256,7 +263,7 @@ static int set_dhcp_option ( struct dhcp_options *options, unsigned int tag,
|
256
|
263
|
static const uint8_t empty_encapsulator[] = { DHCP_END };
|
257
|
264
|
int offset;
|
258
|
265
|
int encap_offset = -1;
|
259
|
|
- int creation_offset = 0;
|
|
266
|
+ int creation_offset;
|
260
|
267
|
struct dhcp_option *option;
|
261
|
268
|
unsigned int encap_tag = DHCP_ENCAPSULATOR ( tag );
|
262
|
269
|
size_t old_len = 0;
|
|
@@ -267,6 +274,10 @@ static int set_dhcp_option ( struct dhcp_options *options, unsigned int tag,
|
267
|
274
|
if ( tag == DHCP_PAD )
|
268
|
275
|
return -ENOTTY;
|
269
|
276
|
|
|
277
|
+ creation_offset = find_dhcp_option_with_encap ( options, DHCP_END,
|
|
278
|
+ NULL );
|
|
279
|
+ if ( creation_offset < 0 )
|
|
280
|
+ creation_offset = options->len;
|
270
|
281
|
/* Find old instance of this option, if any */
|
271
|
282
|
offset = find_dhcp_option_with_encap ( options, tag, &encap_offset );
|
272
|
283
|
if ( offset >= 0 ) {
|