Browse Source

Split DHCP packet creation into two parts: creating the basic packet

structure, and populating it with options.  This should allow us to
use the same basic options list for both DHCPDISCOVER and DHCPREQUEST,
plus making it much easier to set the non-constant parameters
(e.g. requested IP address) in request packets.
tags/v0.9.3
Michael Brown 18 years ago
parent
commit
254fe6e00e
2 changed files with 257 additions and 208 deletions
  1. 117
    82
      src/include/gpxe/dhcp.h
  2. 140
    126
      src/net/udp/dhcp.c

+ 117
- 82
src/include/gpxe/dhcp.h View File

@@ -11,88 +11,6 @@
11 11
 #include <gpxe/list.h>
12 12
 #include <gpxe/in.h>
13 13
 
14
-/**
15
- * A DHCP packet
16
- *
17
- */
18
-struct dhcp_packet {
19
-	/** Operation
20
-	 *
21
-	 * This must be either @c BOOTP_REQUEST or @c BOOTP_REPLY.
22
-	 */
23
-	uint8_t op;
24
-	/** Hardware address type
25
-	 *
26
-	 * This is an ARPHRD_XXX constant.  Note that ARPHRD_XXX
27
-	 * constants are nominally 16 bits wide; this could be
28
-	 * considered to be a bug in the BOOTP/DHCP specification.
29
-	 */
30
-	uint8_t htype;
31
-	/** Hardware address length */
32
-	uint8_t hlen;
33
-	/** Number of hops from server */
34
-	uint8_t hops;
35
-	/** Transaction ID */
36
-	uint32_t xid;
37
-	/** Seconds since start of acquisition */
38
-	uint16_t secs;
39
-	/** Flags */
40
-	uint16_t flags;
41
-	/** "Client" IP address
42
-	 *
43
-	 * This is filled in if the client already has an IP address
44
-	 * assigned and can respond to ARP requests.
45
-	 */
46
-	struct in_addr ciaddr;
47
-	/** "Your" IP address
48
-	 *
49
-	 * This is the IP address assigned by the server to the client.
50
-	 */
51
-	struct in_addr yiaddr;
52
-	/** "Server" IP address
53
-	 *
54
-	 * This is the IP address of the next server to be used in the
55
-	 * boot process.
56
-	 */
57
-	struct in_addr siaddr;
58
-	/** "Gateway" IP address
59
-	 *
60
-	 * This is the IP address of the DHCP relay agent, if any.
61
-	 */
62
-	struct in_addr giaddr;
63
-	/** Client hardware address */
64
-	uint8_t chaddr[16];
65
-	/** Server host name (null terminated)
66
-	 *
67
-	 * This field may be overridden and contain DHCP options
68
-	 */
69
-	uint8_t sname[64];
70
-	/** Boot file name (null terminated)
71
-	 *
72
-	 * This field may be overridden and contain DHCP options
73
-	 */
74
-	uint8_t file[128];
75
-	/** DHCP magic cookie
76
-	 *
77
-	 * Must have the value @c DHCP_MAGIC_COOKIE.
78
-	 */
79
-	uint32_t magic;
80
-	/** DHCP options
81
-	 *
82
-	 * Variable length; extends to the end of the packet.
83
-	 */
84
-	uint8_t options[0];
85
-};
86
-
87
-/** Opcode for a request from client to server */
88
-#define BOOTP_REQUEST 1
89
-
90
-/** Opcode for a reply from server to client */
91
-#define BOOTP_REPLY 2
92
-
93
-/** DHCP magic cookie */
94
-#define DHCP_MAGIC_COOKIE 0x63825363UL
95
-
96 14
 /** Construct a tag value for an encapsulated option
97 15
  *
98 16
  * This tag value can be passed to Etherboot functions when searching
@@ -276,6 +194,123 @@ struct dhcp_option_block {
276 194
 	signed int priority;
277 195
 };
278 196
 
197
+/**
198
+ * A DHCP header
199
+ *
200
+ */
201
+struct dhcphdr {
202
+	/** Operation
203
+	 *
204
+	 * This must be either @c BOOTP_REQUEST or @c BOOTP_REPLY.
205
+	 */
206
+	uint8_t op;
207
+	/** Hardware address type
208
+	 *
209
+	 * This is an ARPHRD_XXX constant.  Note that ARPHRD_XXX
210
+	 * constants are nominally 16 bits wide; this could be
211
+	 * considered to be a bug in the BOOTP/DHCP specification.
212
+	 */
213
+	uint8_t htype;
214
+	/** Hardware address length */
215
+	uint8_t hlen;
216
+	/** Number of hops from server */
217
+	uint8_t hops;
218
+	/** Transaction ID */
219
+	uint32_t xid;
220
+	/** Seconds since start of acquisition */
221
+	uint16_t secs;
222
+	/** Flags */
223
+	uint16_t flags;
224
+	/** "Client" IP address
225
+	 *
226
+	 * This is filled in if the client already has an IP address
227
+	 * assigned and can respond to ARP requests.
228
+	 */
229
+	struct in_addr ciaddr;
230
+	/** "Your" IP address
231
+	 *
232
+	 * This is the IP address assigned by the server to the client.
233
+	 */
234
+	struct in_addr yiaddr;
235
+	/** "Server" IP address
236
+	 *
237
+	 * This is the IP address of the next server to be used in the
238
+	 * boot process.
239
+	 */
240
+	struct in_addr siaddr;
241
+	/** "Gateway" IP address
242
+	 *
243
+	 * This is the IP address of the DHCP relay agent, if any.
244
+	 */
245
+	struct in_addr giaddr;
246
+	/** Client hardware address */
247
+	uint8_t chaddr[16];
248
+	/** Server host name (null terminated)
249
+	 *
250
+	 * This field may be overridden and contain DHCP options
251
+	 */
252
+	uint8_t sname[64];
253
+	/** Boot file name (null terminated)
254
+	 *
255
+	 * This field may be overridden and contain DHCP options
256
+	 */
257
+	uint8_t file[128];
258
+	/** DHCP magic cookie
259
+	 *
260
+	 * Must have the value @c DHCP_MAGIC_COOKIE.
261
+	 */
262
+	uint32_t magic;
263
+	/** DHCP options
264
+	 *
265
+	 * Variable length; extends to the end of the packet.
266
+	 */
267
+	uint8_t options[0];
268
+};
269
+
270
+/** Opcode for a request from client to server */
271
+#define BOOTP_REQUEST 1
272
+
273
+/** Opcode for a reply from server to client */
274
+#define BOOTP_REPLY 2
275
+
276
+/** DHCP magic cookie */
277
+#define DHCP_MAGIC_COOKIE 0x63825363UL
278
+
279
+/** DHCP packet option block fill order
280
+ *
281
+ * This is the order in which option blocks are filled when
282
+ * reassembling a DHCP packet.  We fill the smallest field ("sname")
283
+ * first, to maximise the chances of being able to fit large options
284
+ * within fields which are large enough to contain them.
285
+ */
286
+enum dhcp_packet_option_block_fill_order {
287
+	OPTS_SNAME = 0,
288
+	OPTS_FILE,
289
+	OPTS_MAIN,
290
+	NUM_OPT_BLOCKS
291
+};
292
+
293
+/**
294
+ * A DHCP packet
295
+ *
296
+ */
297
+struct dhcp_packet {
298
+	/** The DHCP packet contents */
299
+	struct dhcphdr *dhcphdr;
300
+	/** Maximum length of the DHCP packet buffer */
301
+	size_t max_len;
302
+	/** Used length of the DHCP packet buffer */
303
+	size_t len;
304
+	/** DHCP option blocks within a DHCP packet
305
+	 *
306
+	 * A DHCP packet contains three fields which can be used to
307
+	 * contain options: the actual "options" field plus the "file"
308
+	 * and "sname" fields (which can be overloaded to contain
309
+	 * options).
310
+	 */
311
+	struct dhcp_option_block options[NUM_OPT_BLOCKS];
312
+};
313
+
279 314
 /** A DHCP session */
280 315
 struct dhcp_session {
281 316
 	/** Network device being configured */

+ 140
- 126
src/net/udp/dhcp.c View File

@@ -46,105 +46,106 @@ static const uint8_t dhcp_op[] = {
46 46
 	[DHCPINFORM]	= BOOTP_REQUEST,
47 47
 };
48 48
 
49
-/** DHCP packet option block fill order
50
- *
51
- * This is the order in which option blocks are filled when
52
- * reassembling a DHCP packet.  We fill the smallest field ("sname")
53
- * first, to maximise the chances of being able to fit large options
54
- * within fields which are large enough to contain them.
55
- */
56
-enum dhcp_packet_option_block_fill_order {
57
-	OPTS_SNAME = 0,
58
-	OPTS_FILE,
59
-	OPTS_MAIN,
60
-	NUM_OPT_BLOCKS
61
-};
62
-
63
-/** DHCP option blocks within a DHCP packet
64
- *
65
- * A DHCP packet contains three fields which can be used to contain
66
- * options: the actual "options" field plus the "file" and "sname"
67
- * fields (which can be overloaded to contain options).
68
- */
69
-struct dhcp_packet_option_blocks {
70
-	struct dhcp_option_block options[NUM_OPT_BLOCKS];
71
-};
72
-
73 49
 /**
74 50
  * Set option within DHCP packet
75 51
  *
76
- * @v optblocks		DHCP packet option blocks
52
+ * @v dhcppkt		DHCP packet
77 53
  * @v tag		DHCP option tag
78 54
  * @v data		New value for DHCP option
79 55
  * @v len		Length of value, in bytes
80
- * @ret option		DHCP option, or NULL
56
+ * @ret rc		Return status code
81 57
  *
82 58
  * Sets the option within the first available options block within the
83 59
  * DHCP packet.  Option blocks are tried in the order specified by @c
84 60
  * dhcp_option_block_fill_order.
61
+ *
62
+ * The magic options @c DHCP_EB_YIADDR and @c DHCP_EB_SIADDR are
63
+ * intercepted and inserted into the appropriate fixed fields within
64
+ * the DHCP packet.  The option @c DHCP_OPTION_OVERLOAD is silently
65
+ * ignored, since our DHCP packet assembly method relies on always
66
+ * having option overloading in use.
85 67
  */
86
-static struct dhcp_option *
87
-set_dhcp_packet_option ( struct dhcp_packet_option_blocks *optblocks,
88
-			 unsigned int tag, const void *data, size_t len ) {
68
+static int set_dhcp_packet_option ( struct dhcp_packet *dhcppkt,
69
+				    unsigned int tag, const void *data,
70
+				    size_t len ) {
71
+	struct dhcphdr *dhcphdr = dhcppkt->dhcphdr;
89 72
 	struct dhcp_option_block *options;
90
-	struct dhcp_option *option;
73
+	struct dhcp_option *option = NULL;
91 74
 
92
-	for ( options = optblocks->options ;
93
-	      options < &optblocks->options[NUM_OPT_BLOCKS] ; options++ ) {
75
+	/* Special-case the magic options */
76
+	switch ( tag ) {
77
+	case DHCP_OPTION_OVERLOAD:
78
+		/* Hard-coded in packets we create; always ignore */
79
+		return 0;
80
+	case DHCP_EB_YIADDR:
81
+		memcpy ( &dhcphdr->yiaddr, data, sizeof ( dhcphdr->yiaddr ) );
82
+		return 0;
83
+	case DHCP_EB_SIADDR:
84
+		memcpy ( &dhcphdr->siaddr, data, sizeof ( dhcphdr->siaddr ) );
85
+		return 0;
86
+	default:
87
+		/* Continue processing as normal */
88
+		break;
89
+	}
90
+		
91
+	/* Set option in first available options block */
92
+	for ( options = dhcppkt->options ;
93
+	      options < &dhcppkt->options[NUM_OPT_BLOCKS] ; options++ ) {
94 94
 		option = set_dhcp_option ( options, tag, data, len );
95 95
 		if ( option )
96
-			return option;
96
+			break;
97 97
 	}
98
-	return NULL;
98
+
99
+	/* Update DHCP packet length */
100
+	dhcppkt->len = ( offsetof ( typeof ( *dhcppkt->dhcphdr ), options )
101
+			 + dhcppkt->options[OPTS_MAIN].len );
102
+
103
+	return ( option ? 0 : -ENOSPC );
99 104
 }
100 105
 
101 106
 /**
102
- * Copy options to DHCP packet
107
+ * Set options within DHCP packet
103 108
  *
104
- * @v optblocks		DHCP packet option blocks
109
+ * @v dhcppkt		DHCP packet
110
+ * @v options		DHCP option block, or NULL
105 111
  * @v encapsulator	Encapsulating option, or zero
106 112
  * @ret rc		Return status code
107 113
  * 
108
- * Copies options from DHCP options blocks into a DHCP packet.  Most
109
- * options are copied verbatim.  Recognised encapsulated options
110
- * fields are handled as such.  Selected options (e.g. @c
111
- * DHCP_OPTION_OVERLOAD) are always ignored, since these special cases
112
- * are handled by other code.
114
+ * Copies options with the specified encapsulator from DHCP options
115
+ * blocks into a DHCP packet.  Most options are copied verbatim.
116
+ * Recognised encapsulated options fields are handled as such.
117
+ *
118
+ * @c options may specify a single options block, or be left as NULL
119
+ * in order to copy options from all registered options blocks.
113 120
  */
114
-static int
115
-copy_dhcp_options_to_packet ( struct dhcp_packet_option_blocks *optblocks,
116
-			      unsigned int encapsulator ) {
121
+static int set_dhcp_packet_encap_options ( struct dhcp_packet *dhcppkt,
122
+					   struct dhcp_option_block *options,
123
+					   unsigned int encapsulator ) {
117 124
 	unsigned int subtag;
118 125
 	unsigned int tag;
119 126
 	struct dhcp_option *option;
120
-	struct dhcp_option *copied;
121 127
 	int rc;
122 128
 
123 129
 	for ( subtag = DHCP_MIN_OPTION; subtag <= DHCP_MAX_OPTION; subtag++ ) {
124 130
 		tag = DHCP_ENCAP_OPT ( encapsulator, subtag );
125 131
 		switch ( tag ) {
126
-		case DHCP_OPTION_OVERLOAD:
127
-			/* Hard-coded in packets we reassemble; skip
128
-			 * this option
129
-			 */
130
-			break;
131 132
 		case DHCP_EB_ENCAP:
132 133
 		case DHCP_VENDOR_ENCAP:
133 134
 			/* Process encapsulated options field */
134
-			if ( ( rc = copy_dhcp_options_to_packet ( optblocks,
135
-								  tag ) ) != 0)
135
+			if ( ( rc = set_dhcp_packet_encap_options ( dhcppkt,
136
+								    options,
137
+								    tag )) !=0)
136 138
 				return rc;
137 139
 			break;
138 140
 		default:
139 141
 			/* Copy option to reassembled packet */
140
-			option = find_global_dhcp_option ( tag );
142
+			option = find_dhcp_option ( options, tag );
141 143
 			if ( ! option )
142 144
 				break;
143
-			copied = set_dhcp_packet_option ( optblocks, tag,
144
-							  &option->data,
145
-							  option->len );
146
-			if ( ! copied )
147
-				return -ENOSPC;
145
+			if ( ( rc = set_dhcp_packet_option ( dhcppkt, tag,
146
+							     &option->data,
147
+							     option->len)) !=0)
148
+				return rc;
148 149
 			break;
149 150
 		};
150 151
 	}
@@ -153,66 +154,77 @@ copy_dhcp_options_to_packet ( struct dhcp_packet_option_blocks *optblocks,
153 154
 }
154 155
 
155 156
 /**
156
- * Assemble a DHCP packet
157
+ * Set options within DHCP packet
158
+ *
159
+ * @v dhcppkt		DHCP packet
160
+ * @v options		DHCP option block, or NULL
161
+ * @ret rc		Return status code
162
+ * 
163
+ * Copies options from DHCP options blocks into a DHCP packet.  Most
164
+ * options are copied verbatim.  Recognised encapsulated options
165
+ * fields are handled as such.
166
+ *
167
+ * @c options may specify a single options block, or be left as NULL
168
+ * in order to copy options from all registered options blocks.
169
+ */
170
+static int set_dhcp_packet_options ( struct dhcp_packet *dhcppkt,
171
+				     struct dhcp_option_block *options ) {
172
+	return set_dhcp_packet_encap_options ( dhcppkt, options, 0 );
173
+}
174
+
175
+/**
176
+ * Create a DHCP packet
157 177
  *
158 178
  * @v dhcp		DHCP session
159
- * @v data		Packet to be filled in
160
- * @v max_len		Length of packet buffer
161
- * @ret len		Length of assembled packet
179
+ * @v msgtype		DHCP message type
180
+ * @v data		Buffer for DHCP packet
181
+ * @v max_len		Size of DHCP packet buffer
182
+ * @v dhcppkt		DHCP packet structure to fill in
183
+ * @ret rc		Return status code
162 184
  *
163
- * Reconstruct a DHCP packet from a DHCP options list.
185
+ * Creates a DHCP packet in the specified buffer, and fills out a @c
186
+ * dhcp_packet structure that can be passed to
187
+ * set_dhcp_packet_option() or set_dhcp_packet_options().
164 188
  */
165
-size_t dhcp_assemble ( struct dhcp_session *dhcp, void *data,
166
-		       size_t max_len ) {
167
-	struct dhcp_packet *dhcppkt = data;
168
-	struct dhcp_option *option;
169
-	struct dhcp_packet_option_blocks optblocks;
170
-	unsigned int dhcp_message_type;
189
+int create_dhcp_packet ( struct dhcp_session *dhcp, uint8_t msgtype,
190
+			 void *data, size_t max_len,
191
+			 struct dhcp_packet *dhcppkt ) {
192
+	struct dhcphdr *dhcphdr = data;
171 193
 	static const uint8_t overloading = ( DHCP_OPTION_OVERLOAD_FILE |
172 194
 					     DHCP_OPTION_OVERLOAD_SNAME );
173 195
 
174
-	/* Fill in constant fields */
175
-	memset ( dhcppkt, 0, max_len );
176
-	dhcppkt->xid = dhcp->xid;
177
-	dhcppkt->magic = htonl ( DHCP_MAGIC_COOKIE );
178
-
179
-	/* Derive "op" field from DHCP_MESSAGE_TYPE option value */
180
-	dhcp_message_type = find_global_dhcp_num_option ( DHCP_MESSAGE_TYPE );
181
-	dhcppkt->op = dhcp_op[dhcp_message_type];
182
-
183
-	/* Fill in NIC details */
184
-	dhcppkt->htype = ntohs ( dhcp->netdev->ll_protocol->ll_proto );
185
-	dhcppkt->hlen = dhcp->netdev->ll_protocol->ll_addr_len;
186
-	memcpy ( dhcppkt->chaddr, dhcp->netdev->ll_addr, dhcppkt->hlen );
187
-
188
-	/* Fill in IP addresses if present */
189
-	option = find_global_dhcp_option ( DHCP_EB_YIADDR );
190
-	if ( option ) {
191
-		memcpy ( &dhcppkt->yiaddr, &option->data,
192
-			 sizeof ( dhcppkt->yiaddr ) );
193
-	}
194
-	option = find_global_dhcp_option ( DHCP_EB_SIADDR );
195
-	if ( option ) {
196
-		memcpy ( &dhcppkt->siaddr, &option->data,
197
-			 sizeof ( dhcppkt->siaddr ) );
198
-	}
199
-
200
-	/* Initialise option blocks */
201
-	init_dhcp_options ( &optblocks.options[OPTS_MAIN], dhcppkt->options,
196
+	/* Initialise DHCP packet structure */
197
+	dhcppkt->dhcphdr = dhcphdr;
198
+	dhcppkt->max_len = max_len;
199
+	init_dhcp_options ( &dhcppkt->options[OPTS_MAIN], dhcphdr->options,
202 200
 			    ( max_len -
203
-			      offsetof ( typeof ( *dhcppkt ), options ) ) );
204
-	init_dhcp_options ( &optblocks.options[OPTS_FILE], dhcppkt->file,
205
-			    sizeof ( dhcppkt->file ) );
206
-	init_dhcp_options ( &optblocks.options[OPTS_SNAME], dhcppkt->sname,
207
-			    sizeof ( dhcppkt->sname ) );
208
-	set_dhcp_option ( &optblocks.options[OPTS_MAIN], DHCP_OPTION_OVERLOAD,
209
-			  &overloading, sizeof ( overloading ) );
201
+			      offsetof ( typeof ( *dhcphdr ), options ) ) );
202
+	init_dhcp_options ( &dhcppkt->options[OPTS_FILE], dhcphdr->file,
203
+			    sizeof ( dhcphdr->file ) );
204
+	init_dhcp_options ( &dhcppkt->options[OPTS_SNAME], dhcphdr->sname,
205
+			    sizeof ( dhcphdr->sname ) );
206
+	
207
+	/* Initialise DHCP packet content */
208
+	memset ( dhcphdr, 0, max_len );
209
+	dhcphdr->xid = dhcp->xid;
210
+	dhcphdr->magic = htonl ( DHCP_MAGIC_COOKIE );
211
+	dhcphdr->htype = ntohs ( dhcp->netdev->ll_protocol->ll_proto );
212
+	dhcphdr->hlen = dhcp->netdev->ll_protocol->ll_addr_len;
213
+	memcpy ( dhcphdr->chaddr, dhcp->netdev->ll_addr, dhcphdr->hlen );
214
+	dhcphdr->op = dhcp_op[msgtype];
215
+
216
+	/* Set DHCP_OPTION_OVERLOAD option within the main options block */
217
+	if ( ! set_dhcp_option ( &dhcppkt->options[OPTS_MAIN],
218
+				 DHCP_OPTION_OVERLOAD, &overloading,
219
+				 sizeof ( overloading ) ) )
220
+		return -ENOSPC;
210 221
 
211
-	/* Populate option blocks */
212
-	copy_dhcp_options_to_packet ( &optblocks, 0 );
222
+	/* Set DHCP_MESSAGE_TYPE option */
223
+	if ( ! set_dhcp_packet_option ( dhcppkt, DHCP_MESSAGE_TYPE,
224
+					&msgtype, sizeof ( msgtype ) ) )
225
+		return -ENOSPC;
213 226
 
214
-	return ( offsetof ( typeof ( *dhcppkt ), options )
215
-		 + optblocks.options[OPTS_MAIN].len );
227
+	return 0;
216 228
 }
217 229
 
218 230
 /**
@@ -280,22 +292,24 @@ static void merge_dhcp_field ( struct dhcp_option_block *options,
280 292
  * converted into the corresponding DHCP options (@c
281 293
  * DHCP_BOOTFILE_NAME and @c DHCP_TFTP_SERVER_NAME respectively).  If
282 294
  * these fields are used for option overloading, their options are
283
- * merged in to the options block.  The values of the "yiaddr" and
284
- * "siaddr" fields will be stored within the options block as the
285
- * options @c DHCP_EB_YIADDR and @c DHCP_EB_SIADDR.
295
+ * merged in to the options block.
296
+ *
297
+ * The values of the "yiaddr" and "siaddr" fields will be stored
298
+ * within the options block as the magic options @c DHCP_EB_YIADDR and
299
+ * @c DHCP_EB_SIADDR.
286 300
  * 
287 301
  * Note that this call allocates new memory for the constructed DHCP
288 302
  * options block; it is the responsibility of the caller to eventually
289 303
  * free this memory.
290 304
  */
291 305
 struct dhcp_option_block * dhcp_parse ( const void *data, size_t len ) {
292
-	const struct dhcp_packet *dhcppkt = data;
306
+	const struct dhcphdr *dhcphdr = data;
293 307
 	struct dhcp_option_block *options;
294 308
 	size_t options_len;
295 309
 	unsigned int overloading;
296 310
 
297 311
 	/* Sanity check */
298
-	if ( len < sizeof ( *dhcppkt ) )
312
+	if ( len < sizeof ( *dhcphdr ) )
299 313
 		return NULL;
300 314
 
301 315
 	/* Calculate size of resulting concatenated option block:
@@ -314,9 +328,9 @@ struct dhcp_option_block * dhcp_parse ( const void *data, size_t len ) {
314 328
 	 *
315 329
 	 *   1 byte for a final terminating DHCP_END tag.
316 330
 	 */
317
-	options_len = ( ( len - offsetof ( typeof ( *dhcppkt ), options ) ) - 1
318
-			+ ( sizeof ( dhcppkt->file ) + 1 )
319
-			+ ( sizeof ( dhcppkt->sname ) + 1 )
331
+	options_len = ( ( len - offsetof ( typeof ( *dhcphdr ), options ) ) - 1
332
+			+ ( sizeof ( dhcphdr->file ) + 1 )
333
+			+ ( sizeof ( dhcphdr->sname ) + 1 )
320 334
 			+ 15 /* yiaddr and siaddr */
321 335
 			+ 1 /* DHCP_END tag */ );
322 336
 	
@@ -329,10 +343,10 @@ struct dhcp_option_block * dhcp_parse ( const void *data, size_t len ) {
329 343
 	}
330 344
 	
331 345
 	/* Merge in "options" field, if this is a DHCP packet */
332
-	if ( dhcppkt->magic == htonl ( DHCP_MAGIC_COOKIE ) ) {
333
-		merge_dhcp_field ( options, dhcppkt->options,
346
+	if ( dhcphdr->magic == htonl ( DHCP_MAGIC_COOKIE ) ) {
347
+		merge_dhcp_field ( options, dhcphdr->options,
334 348
 				   ( len -
335
-				     offsetof ( typeof (*dhcppkt), options ) ),
349
+				     offsetof ( typeof (*dhcphdr), options ) ),
336 350
 				   0 /* Always contains options */ );
337 351
 	}
338 352
 
@@ -340,21 +354,21 @@ struct dhcp_option_block * dhcp_parse ( const void *data, size_t len ) {
340 354
 	overloading = find_dhcp_num_option ( options, DHCP_OPTION_OVERLOAD );
341 355
 	
342 356
 	/* Merge in "file" and "sname" fields */
343
-	merge_dhcp_field ( options, dhcppkt->file, sizeof ( dhcppkt->file ),
357
+	merge_dhcp_field ( options, dhcphdr->file, sizeof ( dhcphdr->file ),
344 358
 			   ( ( overloading & DHCP_OPTION_OVERLOAD_FILE ) ?
345 359
 			     DHCP_BOOTFILE_NAME : 0 ) );
346
-	merge_dhcp_field ( options, dhcppkt->sname, sizeof ( dhcppkt->sname ),
360
+	merge_dhcp_field ( options, dhcphdr->sname, sizeof ( dhcphdr->sname ),
347 361
 			   ( ( overloading & DHCP_OPTION_OVERLOAD_SNAME ) ?
348 362
 			     DHCP_TFTP_SERVER_NAME : 0 ) );
349 363
 
350
-	/* Set options for "yiaddr" and "siaddr", if present */
351
-	if ( dhcppkt->yiaddr.s_addr ) {
364
+	/* Set magic options for "yiaddr" and "siaddr", if present */
365
+	if ( dhcphdr->yiaddr.s_addr ) {
352 366
 		set_dhcp_option ( options, DHCP_EB_YIADDR,
353
-				  &dhcppkt->yiaddr, sizeof (dhcppkt->yiaddr) );
367
+				  &dhcphdr->yiaddr, sizeof (dhcphdr->yiaddr) );
354 368
 	}
355
-	if ( dhcppkt->siaddr.s_addr ) {
369
+	if ( dhcphdr->siaddr.s_addr ) {
356 370
 		set_dhcp_option ( options, DHCP_EB_SIADDR,
357
-				  &dhcppkt->siaddr, sizeof (dhcppkt->siaddr) );
371
+				  &dhcphdr->siaddr, sizeof (dhcphdr->siaddr) );
358 372
 	}
359 373
 	
360 374
 	assert ( options->len <= options->max_len );

Loading…
Cancel
Save