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
 #include <gpxe/list.h>
11
 #include <gpxe/list.h>
12
 #include <gpxe/in.h>
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
 /** Construct a tag value for an encapsulated option
14
 /** Construct a tag value for an encapsulated option
97
  *
15
  *
98
  * This tag value can be passed to Etherboot functions when searching
16
  * This tag value can be passed to Etherboot functions when searching
276
 	signed int priority;
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
 /** A DHCP session */
314
 /** A DHCP session */
280
 struct dhcp_session {
315
 struct dhcp_session {
281
 	/** Network device being configured */
316
 	/** Network device being configured */

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

46
 	[DHCPINFORM]	= BOOTP_REQUEST,
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
  * Set option within DHCP packet
50
  * Set option within DHCP packet
75
  *
51
  *
76
- * @v optblocks		DHCP packet option blocks
52
+ * @v dhcppkt		DHCP packet
77
  * @v tag		DHCP option tag
53
  * @v tag		DHCP option tag
78
  * @v data		New value for DHCP option
54
  * @v data		New value for DHCP option
79
  * @v len		Length of value, in bytes
55
  * @v len		Length of value, in bytes
80
- * @ret option		DHCP option, or NULL
56
+ * @ret rc		Return status code
81
  *
57
  *
82
  * Sets the option within the first available options block within the
58
  * Sets the option within the first available options block within the
83
  * DHCP packet.  Option blocks are tried in the order specified by @c
59
  * DHCP packet.  Option blocks are tried in the order specified by @c
84
  * dhcp_option_block_fill_order.
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
 	struct dhcp_option_block *options;
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
 		option = set_dhcp_option ( options, tag, data, len );
94
 		option = set_dhcp_option ( options, tag, data, len );
95
 		if ( option )
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
  * @v encapsulator	Encapsulating option, or zero
111
  * @v encapsulator	Encapsulating option, or zero
106
  * @ret rc		Return status code
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
 	unsigned int subtag;
124
 	unsigned int subtag;
118
 	unsigned int tag;
125
 	unsigned int tag;
119
 	struct dhcp_option *option;
126
 	struct dhcp_option *option;
120
-	struct dhcp_option *copied;
121
 	int rc;
127
 	int rc;
122
 
128
 
123
 	for ( subtag = DHCP_MIN_OPTION; subtag <= DHCP_MAX_OPTION; subtag++ ) {
129
 	for ( subtag = DHCP_MIN_OPTION; subtag <= DHCP_MAX_OPTION; subtag++ ) {
124
 		tag = DHCP_ENCAP_OPT ( encapsulator, subtag );
130
 		tag = DHCP_ENCAP_OPT ( encapsulator, subtag );
125
 		switch ( tag ) {
131
 		switch ( tag ) {
126
-		case DHCP_OPTION_OVERLOAD:
127
-			/* Hard-coded in packets we reassemble; skip
128
-			 * this option
129
-			 */
130
-			break;
131
 		case DHCP_EB_ENCAP:
132
 		case DHCP_EB_ENCAP:
132
 		case DHCP_VENDOR_ENCAP:
133
 		case DHCP_VENDOR_ENCAP:
133
 			/* Process encapsulated options field */
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
 				return rc;
138
 				return rc;
137
 			break;
139
 			break;
138
 		default:
140
 		default:
139
 			/* Copy option to reassembled packet */
141
 			/* Copy option to reassembled packet */
140
-			option = find_global_dhcp_option ( tag );
142
+			option = find_dhcp_option ( options, tag );
141
 			if ( ! option )
143
 			if ( ! option )
142
 				break;
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
 			break;
149
 			break;
149
 		};
150
 		};
150
 	}
151
 	}
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
  * @v dhcp		DHCP session
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
 	static const uint8_t overloading = ( DHCP_OPTION_OVERLOAD_FILE |
193
 	static const uint8_t overloading = ( DHCP_OPTION_OVERLOAD_FILE |
172
 					     DHCP_OPTION_OVERLOAD_SNAME );
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
 			    ( max_len -
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
  * converted into the corresponding DHCP options (@c
292
  * converted into the corresponding DHCP options (@c
281
  * DHCP_BOOTFILE_NAME and @c DHCP_TFTP_SERVER_NAME respectively).  If
293
  * DHCP_BOOTFILE_NAME and @c DHCP_TFTP_SERVER_NAME respectively).  If
282
  * these fields are used for option overloading, their options are
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
  * Note that this call allocates new memory for the constructed DHCP
301
  * Note that this call allocates new memory for the constructed DHCP
288
  * options block; it is the responsibility of the caller to eventually
302
  * options block; it is the responsibility of the caller to eventually
289
  * free this memory.
303
  * free this memory.
290
  */
304
  */
291
 struct dhcp_option_block * dhcp_parse ( const void *data, size_t len ) {
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
 	struct dhcp_option_block *options;
307
 	struct dhcp_option_block *options;
294
 	size_t options_len;
308
 	size_t options_len;
295
 	unsigned int overloading;
309
 	unsigned int overloading;
296
 
310
 
297
 	/* Sanity check */
311
 	/* Sanity check */
298
-	if ( len < sizeof ( *dhcppkt ) )
312
+	if ( len < sizeof ( *dhcphdr ) )
299
 		return NULL;
313
 		return NULL;
300
 
314
 
301
 	/* Calculate size of resulting concatenated option block:
315
 	/* Calculate size of resulting concatenated option block:
314
 	 *
328
 	 *
315
 	 *   1 byte for a final terminating DHCP_END tag.
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
 			+ 15 /* yiaddr and siaddr */
334
 			+ 15 /* yiaddr and siaddr */
321
 			+ 1 /* DHCP_END tag */ );
335
 			+ 1 /* DHCP_END tag */ );
322
 	
336
 	
329
 	}
343
 	}
330
 	
344
 	
331
 	/* Merge in "options" field, if this is a DHCP packet */
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
 				   ( len -
348
 				   ( len -
335
-				     offsetof ( typeof (*dhcppkt), options ) ),
349
+				     offsetof ( typeof (*dhcphdr), options ) ),
336
 				   0 /* Always contains options */ );
350
 				   0 /* Always contains options */ );
337
 	}
351
 	}
338
 
352
 
340
 	overloading = find_dhcp_num_option ( options, DHCP_OPTION_OVERLOAD );
354
 	overloading = find_dhcp_num_option ( options, DHCP_OPTION_OVERLOAD );
341
 	
355
 	
342
 	/* Merge in "file" and "sname" fields */
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
 			   ( ( overloading & DHCP_OPTION_OVERLOAD_FILE ) ?
358
 			   ( ( overloading & DHCP_OPTION_OVERLOAD_FILE ) ?
345
 			     DHCP_BOOTFILE_NAME : 0 ) );
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
 			   ( ( overloading & DHCP_OPTION_OVERLOAD_SNAME ) ?
361
 			   ( ( overloading & DHCP_OPTION_OVERLOAD_SNAME ) ?
348
 			     DHCP_TFTP_SERVER_NAME : 0 ) );
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
 		set_dhcp_option ( options, DHCP_EB_YIADDR,
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
 		set_dhcp_option ( options, DHCP_EB_SIADDR,
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
 	assert ( options->len <= options->max_len );
374
 	assert ( options->len <= options->max_len );

Loading…
Cancel
Save