Line No. | Rev | Author | Line |
---|---|---|---|
1 | 32 | kaklik | /********************************************************************* |
2 | * |
||
3 | * Dynamic Host Configuration Protocol (DHCP) Server |
||
4 | * Module for Microchip TCP/IP Stack |
||
5 | * -Provides automatic IP address, subnet mask, gateway address, |
||
6 | * DNS server address, and other configuration parameters on DHCP |
||
7 | * enabled networks. |
||
8 | * -Reference: RFC 2131, 2132 |
||
9 | * |
||
10 | ********************************************************************* |
||
11 | * FileName: DHCPs.c |
||
12 | * Dependencies: UDP, ARP, Tick |
||
13 | * Processor: PIC18, PIC24F, PIC24H, dsPIC30F, dsPIC33F, PIC32 |
||
14 | * Compiler: Microchip C32 v1.05 or higher |
||
15 | * Microchip C30 v3.12 or higher |
||
16 | * Microchip C18 v3.30 or higher |
||
17 | * HI-TECH PICC-18 PRO 9.63PL2 or higher |
||
18 | * Company: Microchip Technology, Inc. |
||
19 | * |
||
20 | * Software License Agreement |
||
21 | * |
||
22 | * Copyright (C) 2002-2009 Microchip Technology Inc. All rights |
||
23 | * reserved. |
||
24 | * |
||
25 | * Microchip licenses to you the right to use, modify, copy, and |
||
26 | * distribute: |
||
27 | * (i) the Software when embedded on a Microchip microcontroller or |
||
28 | * digital signal controller product ("Device") which is |
||
29 | * integrated into Licensee's product; or |
||
30 | * (ii) ONLY the Software driver source files ENC28J60.c, ENC28J60.h, |
||
31 | * ENCX24J600.c and ENCX24J600.h ported to a non-Microchip device |
||
32 | * used in conjunction with a Microchip ethernet controller for |
||
33 | * the sole purpose of interfacing with the ethernet controller. |
||
34 | * |
||
35 | * You should refer to the license agreement accompanying this |
||
36 | * Software for additional information regarding your rights and |
||
37 | * obligations. |
||
38 | * |
||
39 | * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT |
||
40 | * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT |
||
41 | * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A |
||
42 | * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL |
||
43 | * MICROCHIP BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR |
||
44 | * CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF |
||
45 | * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS |
||
46 | * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE |
||
47 | * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER |
||
48 | * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT |
||
49 | * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE. |
||
50 | * |
||
51 | * |
||
52 | * Author Date Comment |
||
53 | *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||
54 | * Howard Schlunder 02/28/07 Original |
||
55 | ********************************************************************/ |
||
56 | #define __DHCPS_C |
||
57 | |||
58 | #include "TCPIPConfig.h" |
||
59 | |||
60 | #if defined(STACK_USE_DHCP_SERVER) |
||
61 | |||
62 | #include "TCPIP Stack/TCPIP.h" |
||
63 | |||
64 | // Duration of our DHCP Lease in seconds. This is extrememly short so |
||
65 | // the client won't use our IP for long if we inadvertantly |
||
66 | // provide a lease on a network that has a more authoratative DHCP server. |
||
67 | #define DHCP_LEASE_DURATION 60ul |
||
68 | /// Ignore: #define DHCP_MAX_LEASES 2 // Not implemented |
||
69 | |||
70 | // DHCP Control Block. Lease IP address is derived from index into DCB array. |
||
71 | typedef struct |
||
72 | { |
||
73 | DWORD LeaseExpires; // Expiration time for this lease |
||
74 | MAC_ADDR ClientMAC; // Client's MAC address. Multicase bit is used to determine if a lease is given out or not |
||
75 | enum |
||
76 | { |
||
77 | LEASE_UNUSED = 0, |
||
78 | LEASE_REQUESTED, |
||
79 | LEASE_GRANTED |
||
80 | } smLease; // Status of this lease |
||
81 | } DHCP_CONTROL_BLOCK; |
||
82 | |||
83 | static UDP_SOCKET MySocket; // Socket used by DHCP Server |
||
84 | static IP_ADDR DHCPNextLease; // IP Address to provide for next lease |
||
85 | /// Ignore: static DHCP_CONTROL_BLOCK DCB[DHCP_MAX_LEASES]; // Not Implmented |
||
86 | BOOL bDHCPServerEnabled = TRUE; // Whether or not the DHCP server is enabled |
||
87 | |||
88 | static void DHCPReplyToDiscovery(BOOTP_HEADER *Header); |
||
89 | static void DHCPReplyToRequest(BOOTP_HEADER *Header, BOOL bAccept); |
||
90 | |||
91 | |||
92 | /***************************************************************************** |
||
93 | Function: |
||
94 | void DHCPServerTask(void) |
||
95 | |||
96 | Summary: |
||
97 | Performs periodic DHCP server tasks. |
||
98 | |||
99 | Description: |
||
100 | This function performs any periodic tasks requied by the DHCP server |
||
101 | module, such as processing DHCP requests and distributing IP addresses. |
||
102 | |||
103 | Precondition: |
||
104 | None |
||
105 | |||
106 | Parameters: |
||
107 | None |
||
108 | |||
109 | Returns: |
||
110 | None |
||
111 | ***************************************************************************/ |
||
112 | void DHCPServerTask(void) |
||
113 | { |
||
114 | BYTE i; |
||
115 | BYTE Option, Len; |
||
116 | BOOTP_HEADER BOOTPHeader; |
||
117 | DWORD dw; |
||
118 | BOOL bAccept; |
||
119 | static enum |
||
120 | { |
||
121 | DHCP_OPEN_SOCKET, |
||
122 | DHCP_LISTEN |
||
123 | } smDHCPServer = DHCP_OPEN_SOCKET; |
||
124 | |||
125 | #if defined(STACK_USE_ZEROCONF_LINK_LOCAL) |
||
126 | static BOOL bLeaseAvailable = TRUE; |
||
127 | #endif |
||
128 | |||
129 | #if defined(STACK_USE_DHCP_CLIENT) |
||
130 | // Make sure we don't clobber anyone else's DHCP server |
||
131 | if(DHCPIsServerDetected(0)) |
||
132 | return; |
||
133 | #endif |
||
134 | |||
135 | if(!bDHCPServerEnabled) |
||
136 | return; |
||
137 | |||
138 | switch(smDHCPServer) |
||
139 | { |
||
140 | case DHCP_OPEN_SOCKET: |
||
141 | // Obtain a UDP socket to listen/transmit on |
||
142 | MySocket = UDPOpen(DHCP_SERVER_PORT, NULL, DHCP_CLIENT_PORT); |
||
143 | if(MySocket == INVALID_UDP_SOCKET) |
||
144 | break; |
||
145 | |||
146 | |||
147 | // Decide which address to lease out |
||
148 | // Note that this needs to be changed if we are to |
||
149 | // support more than one lease |
||
150 | DHCPNextLease.Val = (AppConfig.MyIPAddr.Val & AppConfig.MyMask.Val) + 0x02000000; |
||
151 | if(DHCPNextLease.v[3] == 255u) |
||
152 | DHCPNextLease.v[3] += 0x03; |
||
153 | if(DHCPNextLease.v[3] == 0u) |
||
154 | DHCPNextLease.v[3] += 0x02; |
||
155 | |||
156 | smDHCPServer++; |
||
157 | |||
158 | case DHCP_LISTEN: |
||
159 | // Check to see if a valid DHCP packet has arrived |
||
160 | if(UDPIsGetReady(MySocket) < 241u) |
||
161 | break; |
||
162 | |||
163 | // Retrieve the BOOTP header |
||
164 | UDPGetArray((BYTE*)&BOOTPHeader, sizeof(BOOTPHeader)); |
||
165 | |||
166 | bAccept = (BOOTPHeader.ClientIP.Val == DHCPNextLease.Val) || (BOOTPHeader.ClientIP.Val == 0x00000000u); |
||
167 | |||
168 | // Validate first three fields |
||
169 | if(BOOTPHeader.MessageType != 1u) |
||
170 | break; |
||
171 | if(BOOTPHeader.HardwareType != 1u) |
||
172 | break; |
||
173 | if(BOOTPHeader.HardwareLen != 6u) |
||
174 | break; |
||
175 | |||
176 | // Throw away 10 unused bytes of hardware address, |
||
177 | // server host name, and boot file name -- unsupported/not needed. |
||
178 | for(i = 0; i < 64+128+(16-sizeof(MAC_ADDR)); i++) |
||
179 | UDPGet(&Option); |
||
180 | |||
181 | // Obtain Magic Cookie and verify |
||
182 | UDPGetArray((BYTE*)&dw, sizeof(DWORD)); |
||
183 | if(dw != 0x63538263ul) |
||
184 | break; |
||
185 | |||
186 | // Obtain options |
||
187 | while(1) |
||
188 | { |
||
189 | // Get option type |
||
190 | if(!UDPGet(&Option)) |
||
191 | break; |
||
192 | if(Option == DHCP_END_OPTION) |
||
193 | break; |
||
194 | |||
195 | // Get option length |
||
196 | UDPGet(&Len); |
||
197 | |||
198 | // Process option |
||
199 | switch(Option) |
||
200 | { |
||
201 | case DHCP_MESSAGE_TYPE: |
||
202 | UDPGet(&i); |
||
203 | switch(i) |
||
204 | { |
||
205 | case DHCP_DISCOVER_MESSAGE: |
||
206 | DHCPReplyToDiscovery(&BOOTPHeader); |
||
207 | break; |
||
208 | |||
209 | case DHCP_REQUEST_MESSAGE: |
||
210 | #if defined(STACK_USE_ZEROCONF_LINK_LOCAL) |
||
211 | if ( (BOOTPHeader.ClientIP.Val == 0x00000000u) && |
||
212 | (bLeaseAvailable == FALSE) ) |
||
213 | { |
||
214 | // Lease available only to the current lease holder |
||
215 | break; |
||
216 | } |
||
217 | #endif |
||
218 | |||
219 | DHCPReplyToRequest(&BOOTPHeader, bAccept); |
||
220 | |||
221 | #if defined(STACK_USE_ZEROCONF_LINK_LOCAL) |
||
222 | bLeaseAvailable = FALSE; |
||
223 | #endif |
||
224 | |||
225 | break; |
||
226 | |||
227 | // Need to handle these if supporting more than one DHCP lease |
||
228 | case DHCP_RELEASE_MESSAGE: |
||
229 | case DHCP_DECLINE_MESSAGE: |
||
230 | break; |
||
231 | } |
||
232 | break; |
||
233 | |||
234 | case DHCP_PARAM_REQUEST_IP_ADDRESS: |
||
235 | if(Len == 4u) |
||
236 | { |
||
237 | // Get the requested IP address and see if it is the one we have on offer. |
||
238 | UDPGetArray((BYTE*)&dw, 4); |
||
239 | Len -= 4; |
||
240 | bAccept = (dw == DHCPNextLease.Val); |
||
241 | } |
||
242 | break; |
||
243 | |||
244 | case DHCP_END_OPTION: |
||
245 | UDPDiscard(); |
||
246 | return; |
||
247 | } |
||
248 | |||
249 | // Remove any unprocessed bytes that we don't care about |
||
250 | while(Len--) |
||
251 | { |
||
252 | UDPGet(&i); |
||
253 | } |
||
254 | } |
||
255 | |||
256 | UDPDiscard(); |
||
257 | break; |
||
258 | } |
||
259 | } |
||
260 | |||
261 | |||
262 | /***************************************************************************** |
||
263 | Function: |
||
264 | static void DHCPReplyToDiscovery(BOOTP_HEADER *Header) |
||
265 | |||
266 | Summary: |
||
267 | Replies to a DHCP Discover message. |
||
268 | |||
269 | Description: |
||
270 | This function replies to a DHCP Discover message by sending out a |
||
271 | DHCP Offer message. |
||
272 | |||
273 | Precondition: |
||
274 | None |
||
275 | |||
276 | Parameters: |
||
277 | Header - the BootP header this is in response to. |
||
278 | |||
279 | Returns: |
||
280 | None |
||
281 | ***************************************************************************/ |
||
282 | static void DHCPReplyToDiscovery(BOOTP_HEADER *Header) |
||
283 | { |
||
284 | BYTE i; |
||
285 | |||
286 | // Set the correct socket to active and ensure that |
||
287 | // enough space is available to generate the DHCP response |
||
288 | if(UDPIsPutReady(MySocket) < 300u) |
||
289 | return; |
||
290 | |||
291 | // Begin putting the BOOTP Header and DHCP options |
||
292 | UDPPut(BOOT_REPLY); // Message Type: 2 (BOOTP Reply) |
||
293 | // Reply with the same Hardware Type, Hardware Address Length, Hops, and Transaction ID fields |
||
294 | UDPPutArray((BYTE*)&(Header->HardwareType), 7); |
||
295 | UDPPut(0x00); // Seconds Elapsed: 0 (Not used) |
||
296 | UDPPut(0x00); // Seconds Elapsed: 0 (Not used) |
||
297 | UDPPutArray((BYTE*)&(Header->BootpFlags), sizeof(Header->BootpFlags)); |
||
298 | UDPPut(0x00); // Your (client) IP Address: 0.0.0.0 (none yet assigned) |
||
299 | UDPPut(0x00); // Your (client) IP Address: 0.0.0.0 (none yet assigned) |
||
300 | UDPPut(0x00); // Your (client) IP Address: 0.0.0.0 (none yet assigned) |
||
301 | UDPPut(0x00); // Your (client) IP Address: 0.0.0.0 (none yet assigned) |
||
302 | UDPPutArray((BYTE*)&DHCPNextLease, sizeof(IP_ADDR)); // Lease IP address to give out |
||
303 | UDPPut(0x00); // Next Server IP Address: 0.0.0.0 (not used) |
||
304 | UDPPut(0x00); // Next Server IP Address: 0.0.0.0 (not used) |
||
305 | UDPPut(0x00); // Next Server IP Address: 0.0.0.0 (not used) |
||
306 | UDPPut(0x00); // Next Server IP Address: 0.0.0.0 (not used) |
||
307 | UDPPut(0x00); // Relay Agent IP Address: 0.0.0.0 (not used) |
||
308 | UDPPut(0x00); // Relay Agent IP Address: 0.0.0.0 (not used) |
||
309 | UDPPut(0x00); // Relay Agent IP Address: 0.0.0.0 (not used) |
||
310 | UDPPut(0x00); // Relay Agent IP Address: 0.0.0.0 (not used) |
||
311 | UDPPutArray((BYTE*)&(Header->ClientMAC), sizeof(MAC_ADDR)); // Client MAC address: Same as given by client |
||
312 | for(i = 0; i < 64+128+(16-sizeof(MAC_ADDR)); i++) // Remaining 10 bytes of client hardware address, server host name: Null string (not used) |
||
313 | UDPPut(0x00); // Boot filename: Null string (not used) |
||
314 | UDPPut(0x63); // Magic Cookie: 0x63538263 |
||
315 | UDPPut(0x82); // Magic Cookie: 0x63538263 |
||
316 | UDPPut(0x53); // Magic Cookie: 0x63538263 |
||
317 | UDPPut(0x63); // Magic Cookie: 0x63538263 |
||
318 | |||
319 | // Options: DHCP Offer |
||
320 | UDPPut(DHCP_MESSAGE_TYPE); |
||
321 | UDPPut(1); |
||
322 | UDPPut(DHCP_OFFER_MESSAGE); |
||
323 | |||
324 | // Option: Subnet Mask |
||
325 | UDPPut(DHCP_SUBNET_MASK); |
||
326 | UDPPut(sizeof(IP_ADDR)); |
||
327 | UDPPutArray((BYTE*)&AppConfig.MyMask, sizeof(IP_ADDR)); |
||
328 | |||
329 | // Option: Lease duration |
||
330 | UDPPut(DHCP_IP_LEASE_TIME); |
||
331 | UDPPut(4); |
||
332 | UDPPut((DHCP_LEASE_DURATION>>24) & 0xFF); |
||
333 | UDPPut((DHCP_LEASE_DURATION>>16) & 0xFF); |
||
334 | UDPPut((DHCP_LEASE_DURATION>>8) & 0xFF); |
||
335 | UDPPut((DHCP_LEASE_DURATION) & 0xFF); |
||
336 | |||
337 | // Option: Server identifier |
||
338 | UDPPut(DHCP_SERVER_IDENTIFIER); |
||
339 | UDPPut(sizeof(IP_ADDR)); |
||
340 | UDPPutArray((BYTE*)&AppConfig.MyIPAddr, sizeof(IP_ADDR)); |
||
341 | |||
342 | // Option: Router/Gateway address |
||
343 | UDPPut(DHCP_ROUTER); |
||
344 | UDPPut(sizeof(IP_ADDR)); |
||
345 | UDPPutArray((BYTE*)&AppConfig.MyIPAddr, sizeof(IP_ADDR)); |
||
346 | |||
347 | // Option: DNS server address |
||
348 | UDPPut(DHCP_DNS); |
||
349 | UDPPut(sizeof(IP_ADDR)); |
||
350 | UDPPutArray((BYTE*)&AppConfig.MyIPAddr, sizeof(IP_ADDR)); |
||
351 | |||
352 | // No more options, mark ending |
||
353 | UDPPut(DHCP_END_OPTION); |
||
354 | |||
355 | // Add zero padding to ensure compatibility with old BOOTP relays that discard small packets (<300 UDP octets) |
||
356 | while(UDPTxCount < 300u) |
||
357 | UDPPut(0); |
||
358 | |||
359 | // Force remote destination address to be the broadcast address, regardless |
||
360 | // of what the node's source IP address was (to ensure we don't try to |
||
361 | // unicast to 0.0.0.0). |
||
362 | memset((void*)&UDPSocketInfo[MySocket].remoteNode, 0xFF, sizeof(NODE_INFO)); |
||
363 | |||
364 | // Transmit the packet |
||
365 | UDPFlush(); |
||
366 | } |
||
367 | |||
368 | |||
369 | /***************************************************************************** |
||
370 | Function: |
||
371 | static void DHCPReplyToRequest(BOOTP_HEADER *Header, BOOL bAccept) |
||
372 | |||
373 | Summary: |
||
374 | Replies to a DHCP Request message. |
||
375 | |||
376 | Description: |
||
377 | This function replies to a DHCP Request message by sending out a |
||
378 | DHCP Acknowledge message. |
||
379 | |||
380 | Precondition: |
||
381 | None |
||
382 | |||
383 | Parameters: |
||
384 | Header - the BootP header this is in response to. |
||
385 | bAccept - whether or not we've accepted this request |
||
386 | |||
387 | Returns: |
||
388 | None |
||
389 | |||
390 | Internal: |
||
391 | Needs to support more than one simultaneous lease in the future. |
||
392 | ***************************************************************************/ |
||
393 | static void DHCPReplyToRequest(BOOTP_HEADER *Header, BOOL bAccept) |
||
394 | { |
||
395 | BYTE i; |
||
396 | |||
397 | // Set the correct socket to active and ensure that |
||
398 | // enough space is available to generate the DHCP response |
||
399 | if(UDPIsPutReady(MySocket) < 300u) |
||
400 | return; |
||
401 | |||
402 | // Search through all remaining options and look for the Requested IP address field |
||
403 | // Obtain options |
||
404 | while(UDPIsGetReady(MySocket)) |
||
405 | { |
||
406 | BYTE Option, Len; |
||
407 | DWORD dw; |
||
408 | |||
409 | // Get option type |
||
410 | if(!UDPGet(&Option)) |
||
411 | break; |
||
412 | if(Option == DHCP_END_OPTION) |
||
413 | break; |
||
414 | |||
415 | // Get option length |
||
416 | UDPGet(&Len); |
||
417 | |||
418 | // Process option |
||
419 | if((Option == DHCP_PARAM_REQUEST_IP_ADDRESS) && (Len == 4u)) |
||
420 | { |
||
421 | // Get the requested IP address and see if it is the one we have on offer. If not, we should send back a NAK, but since there could be some other DHCP server offering this address, we'll just silently ignore this request. |
||
422 | UDPGetArray((BYTE*)&dw, 4); |
||
423 | Len -= 4; |
||
424 | if(dw != DHCPNextLease.Val) |
||
425 | { |
||
426 | bAccept = FALSE; |
||
427 | } |
||
428 | break; |
||
429 | } |
||
430 | |||
431 | // Remove the unprocessed bytes that we don't care about |
||
432 | while(Len--) |
||
433 | { |
||
434 | UDPGet(&i); |
||
435 | } |
||
436 | } |
||
437 | |||
438 | // Begin putting the BOOTP Header and DHCP options |
||
439 | UDPPut(BOOT_REPLY); // Message Type: 2 (BOOTP Reply) |
||
440 | // Reply with the same Hardware Type, Hardware Address Length, Hops, and Transaction ID fields |
||
441 | UDPPutArray((BYTE*)&(Header->HardwareType), 7); |
||
442 | UDPPut(0x00); // Seconds Elapsed: 0 (Not used) |
||
443 | UDPPut(0x00); // Seconds Elapsed: 0 (Not used) |
||
444 | UDPPutArray((BYTE*)&(Header->BootpFlags), sizeof(Header->BootpFlags)); |
||
445 | UDPPutArray((BYTE*)&(Header->ClientIP), sizeof(IP_ADDR));// Your (client) IP Address: |
||
446 | UDPPutArray((BYTE*)&DHCPNextLease, sizeof(IP_ADDR)); // Lease IP address to give out |
||
447 | UDPPut(0x00); // Next Server IP Address: 0.0.0.0 (not used) |
||
448 | UDPPut(0x00); // Next Server IP Address: 0.0.0.0 (not used) |
||
449 | UDPPut(0x00); // Next Server IP Address: 0.0.0.0 (not used) |
||
450 | UDPPut(0x00); // Next Server IP Address: 0.0.0.0 (not used) |
||
451 | UDPPut(0x00); // Relay Agent IP Address: 0.0.0.0 (not used) |
||
452 | UDPPut(0x00); // Relay Agent IP Address: 0.0.0.0 (not used) |
||
453 | UDPPut(0x00); // Relay Agent IP Address: 0.0.0.0 (not used) |
||
454 | UDPPut(0x00); // Relay Agent IP Address: 0.0.0.0 (not used) |
||
455 | UDPPutArray((BYTE*)&(Header->ClientMAC), sizeof(MAC_ADDR)); // Client MAC address: Same as given by client |
||
456 | for(i = 0; i < 64+128+(16-sizeof(MAC_ADDR)); i++) // Remaining 10 bytes of client hardware address, server host name: Null string (not used) |
||
457 | UDPPut(0x00); // Boot filename: Null string (not used) |
||
458 | UDPPut(0x63); // Magic Cookie: 0x63538263 |
||
459 | UDPPut(0x82); // Magic Cookie: 0x63538263 |
||
460 | UDPPut(0x53); // Magic Cookie: 0x63538263 |
||
461 | UDPPut(0x63); // Magic Cookie: 0x63538263 |
||
462 | |||
463 | // Options: DHCP lease ACKnowledge |
||
464 | if(bAccept) |
||
465 | { |
||
466 | UDPPut(DHCP_OPTION_ACK_MESSAGE); |
||
467 | UDPPut(1); |
||
468 | UDPPut(DHCP_ACK_MESSAGE); |
||
469 | } |
||
470 | else // Send a NACK |
||
471 | { |
||
472 | UDPPut(DHCP_OPTION_ACK_MESSAGE); |
||
473 | UDPPut(1); |
||
474 | UDPPut(DHCP_NAK_MESSAGE); |
||
475 | } |
||
476 | |||
477 | // Option: Lease duration |
||
478 | UDPPut(DHCP_IP_LEASE_TIME); |
||
479 | UDPPut(4); |
||
480 | UDPPut((DHCP_LEASE_DURATION>>24) & 0xFF); |
||
481 | UDPPut((DHCP_LEASE_DURATION>>16) & 0xFF); |
||
482 | UDPPut((DHCP_LEASE_DURATION>>8) & 0xFF); |
||
483 | UDPPut((DHCP_LEASE_DURATION) & 0xFF); |
||
484 | |||
485 | // Option: Server identifier |
||
486 | UDPPut(DHCP_SERVER_IDENTIFIER); |
||
487 | UDPPut(sizeof(IP_ADDR)); |
||
488 | UDPPutArray((BYTE*)&AppConfig.MyIPAddr, sizeof(IP_ADDR)); |
||
489 | |||
490 | // Option: Subnet Mask |
||
491 | UDPPut(DHCP_SUBNET_MASK); |
||
492 | UDPPut(sizeof(IP_ADDR)); |
||
493 | UDPPutArray((BYTE*)&AppConfig.MyMask, sizeof(IP_ADDR)); |
||
494 | |||
495 | // Option: Router/Gateway address |
||
496 | UDPPut(DHCP_ROUTER); |
||
497 | UDPPut(sizeof(IP_ADDR)); |
||
498 | UDPPutArray((BYTE*)&AppConfig.MyIPAddr, sizeof(IP_ADDR)); |
||
499 | |||
500 | // Option: DNS server address |
||
501 | UDPPut(DHCP_DNS); |
||
502 | UDPPut(sizeof(IP_ADDR)); |
||
503 | UDPPutArray((BYTE*)&AppConfig.MyIPAddr, sizeof(IP_ADDR)); |
||
504 | |||
505 | // No more options, mark ending |
||
506 | UDPPut(DHCP_END_OPTION); |
||
507 | |||
508 | // Add zero padding to ensure compatibility with old BOOTP relays that discard small packets (<300 UDP octets) |
||
509 | while(UDPTxCount < 300u) |
||
510 | UDPPut(0); |
||
511 | |||
512 | // Force remote destination address to be the broadcast address, regardless |
||
513 | // of what the node's source IP address was (to ensure we don't try to |
||
514 | // unicast to 0.0.0.0). |
||
515 | memset((void*)&UDPSocketInfo[MySocket].remoteNode, 0xFF, sizeof(NODE_INFO)); |
||
516 | |||
517 | // Transmit the packet |
||
518 | UDPFlush(); |
||
519 | } |
||
520 | |||
521 | #endif //#if defined(STACK_USE_DHCP_SERVER) |
Powered by WebSVN v2.8.3