/[H8]/trunk/docs/Microchip TCP_IP stack/TCPIP Stack/DHCP.c
ViewVC logotype

Contents of /trunk/docs/Microchip TCP_IP stack/TCPIP Stack/DHCP.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 15 - (show annotations) (download)
Thu Apr 19 09:01:15 2007 UTC (17 years, 1 month ago) by hedin
File MIME type: text/plain
File size: 25358 byte(s)
added the TCP/IP stack, source code.
1 /*********************************************************************
2 *
3 * Dynamic Host Configuration Protocol (DHCP) Client
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: DHCP.c
12 * Dependencies: StackTsk.h
13 * UDP.h
14 * Processor: PIC18, PIC24F, PIC24H, dsPIC30F, dsPIC33F
15 * Complier: Microchip C18 v3.02 or higher
16 * Microchip C30 v2.01 or higher
17 * Company: Microchip Technology, Inc.
18 *
19 * Software License Agreement
20 *
21 * Copyright © 2002-2007 Microchip Technology Inc. All rights
22 * reserved.
23 *
24 * Microchip licenses to you the right to use, modify, copy, and
25 * distribute:
26 * (i) the Software when embedded on a Microchip microcontroller or
27 * digital signal controller product (“Device”) which is
28 * integrated into Licensee’s product; or
29 * (ii) ONLY the Software driver source files ENC28J60.c and
30 * ENC28J60.h ported to a non-Microchip device used in
31 * conjunction with a Microchip ethernet controller for the
32 * sole purpose of interfacing with the ethernet controller.
33 *
34 * You should refer to the license agreement accompanying this
35 * Software for additional information regarding your rights and
36 * obligations.
37 *
38 * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” WITHOUT
39 * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
40 * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
41 * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
42 * MICROCHIP BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR
43 * CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
44 * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
45 * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
46 * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
47 * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
48 * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
49 *
50 *
51 * Author Date Comment
52 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
53 * Nilesh Rajbharti 3/21/01 Original (Rev 1.0)
54 * Nilesh Rajbharti 7/10/02 Explicitly initialized tempIPAddress
55 * (Rev 2.11)
56 * Nilesh Rajbharti 5/16/03 Increased DHCP_TIMEOUT to 2 seconds.
57 * Nilesh Rajbharti 5/16/03 Fixed SM_DHCP_BROADCAST logic
58 * where UDPPut was called before setting
59 * active socket.
60 * Robert Sloan 5/29/03 Improved DHCP State machine to handle
61 * NAK and renew existing IP address.
62 * Nilesh Rajbharti 8/15/03 Modified _DHCPRecieve() to check for
63 * chaddr field before accpting the packet.
64 * Fixed DHCPTask() where it would not
65 * reply to first OFFER.
66 * Nilesh Rajbharti 3/1/04 Used tickDiff in DHCPTask() "bind"
67 * state to adjust for irregular TICK_SECOND
68 * Without this logic, actual lease time count
69 * down may be incorrect.
70 * Howard Schlunder 5/11/06 Fixed tickDiff usage, reducing
71 * accumulated timing error. Fixed DHCP
72 * state machine requesting IP 0.0.0.0
73 * after lease expiration.
74 * Howard Schlunder 6/01/06 Added DHCPFlags.bits.bOfferReceived flag to
75 * allow operation on networks with multiple
76 * DHCP servers offering multiple addresses
77 * Howard Schlunder 8/01/06 Added DNS server option to DHCP request,
78 * untested Host Name option to DHCP request
79 * Howard Schlunder 1/09/06 Fixed a DHCP renewal not renewing lease time bug
80 * Howard Schlunder 3/16/07 Rewrote DHCP state machine
81 ********************************************************************/
82 #define __DHCP_C
83 #include "TCPIP Stack/TCPIP.h"
84
85 #if defined(STACK_USE_DHCP_CLIENT)
86
87
88 #define DHCP_TIMEOUT (TICK)(2*TICK_SECOND)
89
90
91 SM_DHCP smDHCPState = SM_DHCP_GET_SOCKET;
92 DHCP_CLIENT_FLAGS DHCPFlags = { 0x00 };
93 BYTE DHCPBindCount = 0;
94
95 static UDP_SOCKET DHCPSocket = INVALID_UDP_SOCKET;
96 static DWORD_VAL DHCPServerID;
97 static DWORD_VAL DHCPLeaseTime;
98 static IP_ADDR tempIPAddress;
99 static IP_ADDR tempGateway;
100 static IP_ADDR tempMask;
101 #if defined(STACK_USE_DNS)
102 static IP_ADDR tempDNS;
103 static IP_ADDR tempDNS2;
104 #endif
105 //static BYTE tempHostName[16];
106 static union
107 {
108 struct
109 {
110 char IPAddress:1;
111 char Gateway:1;
112 char Mask:1;
113 char DNS:1;
114 char DNS2:1;
115 char HostName:1;
116 } bits;
117 BYTE Val;
118 } ValidValues;
119
120
121 static BYTE _DHCPReceive(void);
122 static void _DHCPSend(BYTE messageType);
123
124
125 /*********************************************************************
126 * Function: void DHCPReset(void)
127 *
128 * PreCondition: None
129 *
130 * Input: None
131 *
132 * Output: None
133 *
134 * Side Effects: None
135 *
136 * Overview: Resets the DHCP client, giving up any lease,
137 * knowledge of DHCP servers, etc.
138 *
139 * Note: None
140 ********************************************************************/
141 void DHCPReset(void)
142 {
143 // Do nothing if DHCP is disabled
144 if(smDHCPState == SM_DHCP_DISABLED)
145 return;
146
147 if(DHCPSocket != INVALID_UDP_SOCKET)
148 smDHCPState = SM_DHCP_SEND_DISCOVERY;
149 else
150 smDHCPState = SM_DHCP_GET_SOCKET;
151
152 DHCPBindCount = 0;
153 DHCPFlags.bits.bIsBound = FALSE;
154 }
155
156
157 /*********************************************************************
158 * Function: void DHCPTask(void)
159 *
160 * PreCondition: DHCPInit() is already called
161 *
162 * Input: None
163 *
164 * Output: None
165 *
166 * Side Effects: None
167 *
168 * Overview: Gets and generates DHCP messages to obtain a
169 * lease and keep it from expiring
170 *
171 * Note: None
172 ********************************************************************/
173 void DHCPTask(void)
174 {
175 static TICK eventTime;
176
177 switch(smDHCPState)
178 {
179 case SM_DHCP_DISABLED:
180 if(DHCPSocket != INVALID_UDP_SOCKET)
181 {
182 UDPClose(DHCPSocket);
183 DHCPSocket = INVALID_UDP_SOCKET;
184 }
185 break;
186
187 case SM_DHCP_GET_SOCKET:
188 // Open a socket to send and receive broadcast messages on
189 DHCPSocket = UDPOpen(DHCP_CLIENT_PORT, NULL, DHCP_SERVER_PORT);
190 if(DHCPSocket == INVALID_UDP_SOCKET)
191 break;
192
193 smDHCPState = SM_DHCP_SEND_DISCOVERY;
194 // No break
195
196 case SM_DHCP_SEND_DISCOVERY:
197 if(UDPIsPutReady(DHCPSocket) < 258)
198 break;
199
200 // Ensure that we transmit to the broadcast IP and MAC addresses
201 // The UDP Socket remembers who it was last talking to
202 memset((void*)&UDPSocketInfo[DHCPSocket].remoteNode, 0xFF, sizeof(UDPSocketInfo[DHCPSocket].remoteNode));
203
204 // Assume default IP Lease time of 60 seconds.
205 // This should be minimum possible to make sure that if
206 // server did not specify lease time, we try again after this minimum time.
207 DHCPLeaseTime.Val = 60;
208 ValidValues.Val = 0x00;
209 DHCPBindCount = 0;
210 DHCPFlags.bits.bIsBound = FALSE;
211 DHCPFlags.bits.bOfferReceived = FALSE;
212
213 // Send the DHCP Discover broadcast
214 _DHCPSend(DHCP_DISCOVER_MESSAGE);
215
216 // Start a timer and begin looking for a response
217 eventTime = TickGet() + DHCP_TIMEOUT;
218 smDHCPState = SM_DHCP_GET_OFFER;
219 break;
220
221 case SM_DHCP_GET_OFFER:
222 // Check to see if a packet has arrived
223 if(UDPIsGetReady(DHCPSocket) < 250)
224 {
225 // Go back and transmit a new discovery if we didn't get an offer after 2 seconds
226 if((LONG)(eventTime - TickGet()) <= (LONG)0)
227 smDHCPState = SM_DHCP_SEND_DISCOVERY;
228 break;
229 }
230
231 // Let the DHCP server module know that there is a DHCP server
232 // on this network
233 DHCPFlags.bits.bDHCPServerDetected = TRUE;
234
235 // Check to see if we received an offer
236 if(_DHCPReceive() != DHCP_OFFER_MESSAGE)
237 break;
238
239 smDHCPState = SM_DHCP_SEND_REQUEST;
240 // No break
241
242 case SM_DHCP_SEND_REQUEST:
243 if(UDPIsPutReady(DHCPSocket) < 258)
244 break;
245
246 // Send the DHCP request message
247 _DHCPSend(DHCP_REQUEST_MESSAGE);
248
249 // Start a timer and begin looking for a response
250 eventTime = TickGet() + DHCP_TIMEOUT;
251 smDHCPState = SM_DHCP_GET_REQUEST_ACK;
252 break;
253
254 case SM_DHCP_GET_REQUEST_ACK:
255 // Check to see if a packet has arrived
256 if(UDPIsGetReady(DHCPSocket) < 250)
257 {
258 // Go back and transmit a new discovery if we didn't get an ACK after 2 seconds
259 if((LONG)(eventTime - TickGet()) <= (LONG)0)
260 smDHCPState = SM_DHCP_SEND_DISCOVERY;
261 break;
262 }
263
264 // Check to see if we received an offer
265 switch(_DHCPReceive())
266 {
267 case DHCP_ACK_MESSAGE:
268 eventTime = TickGet() + TICK_SECOND;
269 smDHCPState = SM_DHCP_BOUND;
270
271 DHCPFlags.bits.bIsBound = TRUE;
272 DHCPBindCount++;
273 if(ValidValues.bits.IPAddress)
274 AppConfig.MyIPAddr = tempIPAddress;
275 if(ValidValues.bits.Mask)
276 AppConfig.MyMask = tempMask;
277 if(ValidValues.bits.Gateway)
278 AppConfig.MyGateway = tempGateway;
279 #if defined(STACK_USE_DNS)
280 if(ValidValues.bits.DNS)
281 AppConfig.PrimaryDNSServer = tempDNS;
282 if(ValidValues.bits.DNS2)
283 AppConfig.SecondaryDNSServer = tempDNS2;
284 #endif
285 // if(ValidValues.bits.HostName)
286 // memcpy(AppConfig.NetBIOSName, (void*)tempHostName, sizeof(AppConfig.NetBIOSName));
287
288 break;
289
290 case DHCP_NAK_MESSAGE:
291 smDHCPState = SM_DHCP_SEND_DISCOVERY;
292 break;
293 }
294 break;
295
296 case SM_DHCP_BOUND:
297 if((LONG)(eventTime - TickGet()) >= (LONG)0)
298 break;
299
300 // Check to see if our lease has nearly expired and we must renew
301 eventTime += TICK_SECOND;
302 DHCPLeaseTime.Val--;
303 if(DHCPLeaseTime.Val)
304 break;
305
306 smDHCPState = SM_DHCP_SEND_RENEW;
307 // No break
308
309 case SM_DHCP_SEND_RENEW:
310 case SM_DHCP_SEND_RENEW2:
311 case SM_DHCP_SEND_RENEW3:
312 if(UDPIsPutReady(DHCPSocket) < 258)
313 break;
314
315 // Send the DHCP request message
316 _DHCPSend(DHCP_REQUEST_MESSAGE);
317 DHCPFlags.bits.bOfferReceived = FALSE;
318
319 // Start a timer and begin looking for a response
320 eventTime = TickGet() + DHCP_TIMEOUT;
321 smDHCPState++;
322 break;
323
324 case SM_DHCP_GET_RENEW_ACK:
325 case SM_DHCP_GET_RENEW_ACK2:
326 case SM_DHCP_GET_RENEW_ACK3:
327 // Check to see if a packet has arrived
328 if(UDPIsGetReady(DHCPSocket) < 250)
329 {
330 // Go back and transmit a new discovery if we didn't get an ACK after 2 seconds
331 if((LONG)(eventTime - TickGet()) <= (LONG)0)
332 {
333 if(++smDHCPState > SM_DHCP_GET_RENEW_ACK3)
334 smDHCPState = SM_DHCP_SEND_DISCOVERY;
335 }
336 break;
337 }
338
339 // Check to see if we received an offer
340 switch(_DHCPReceive())
341 {
342 case DHCP_ACK_MESSAGE:
343 eventTime = TickGet() + TICK_SECOND;
344 DHCPBindCount++;
345 smDHCPState = SM_DHCP_BOUND;
346 break;
347
348 case DHCP_NAK_MESSAGE:
349 smDHCPState = SM_DHCP_SEND_DISCOVERY;
350 break;
351 }
352 break;
353 }
354 }
355
356
357
358 /*********************************************************************
359 DHCP PACKET FORMAT AS PER RFC 1541
360
361 0 1 2 3
362 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
363 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
364 | op (1) | htype (1) | hlen (1) | hops (1) |
365 +---------------+---------------+---------------+---------------+
366 | xid (4) |
367 +-------------------------------+-------------------------------+
368 | secs (2) | flags (2) |
369 +-------------------------------+-------------------------------+
370 | ciaddr (4) |
371 +---------------------------------------------------------------+
372 | yiaddr (4) |
373 +---------------------------------------------------------------+
374 | siaddr (4) |
375 +---------------------------------------------------------------+
376 | giaddr (4) |
377 +---------------------------------------------------------------+
378 | |
379 | chaddr (16) |
380 | |
381 | |
382 +---------------------------------------------------------------+
383 | |
384 | sname (64) |
385 +---------------------------------------------------------------+
386 | |
387 | file (128) |
388 +---------------------------------------------------------------+
389 | |
390 | options (312) |
391 +---------------------------------------------------------------+
392
393 ********************************************************************/
394 static BYTE _DHCPReceive(void)
395 {
396 BYTE v;
397 BYTE i, j;
398 BYTE type;
399 BOOL lbDone;
400 DWORD_VAL tempServerID;
401
402
403 // Assume unknown message until proven otherwise.
404 type = DHCP_UNKNOWN_MESSAGE;
405
406 UDPGet(&v); // op
407
408 // Make sure this is BOOT_REPLY.
409 if ( v == BOOT_REPLY )
410 {
411 // Discard htype, hlen, hops, xid, secs, flags, ciaddr.
412 for ( i = 0; i < 15u; i++ )
413 UDPGet(&v);
414
415 // Check to see if this is the first offer
416 if(DHCPFlags.bits.bOfferReceived)
417 {
418 // Discard offered IP address, we already have an offer
419 for ( i = 0; i < 4u; i++ )
420 UDPGet(&v);
421 }
422 else
423 {
424 // Save offered IP address until we know for sure that we have it.
425 UDPGetArray((BYTE*)&tempIPAddress, sizeof(tempIPAddress));
426 ValidValues.bits.IPAddress = 1;
427 }
428
429 // Ignore siaddr, giaddr
430 for ( i = 0; i < 8u; i++ )
431 UDPGet(&v);
432
433 // Check to see if chaddr (Client Hardware Address) belongs to us.
434 for ( i = 0; i < 6u; i++ )
435 {
436 UDPGet(&v);
437 if ( v != AppConfig.MyMACAddr.v[i])
438 goto UDPInvalid;
439 }
440
441
442 // Ignore part of chaddr, sname, file, magic cookie.
443 for ( i = 0; i < 206u; i++ )
444 UDPGet(&v);
445
446 lbDone = FALSE;
447 do
448 {
449 // Get the Option number
450 // Break out eventually in case if this is a malformed
451 // DHCP message, ie: missing DHCP_END_OPTION marker
452 if(!UDPGet(&v))
453 {
454 lbDone = TRUE;
455 break;
456 }
457
458 switch(v)
459 {
460 case DHCP_MESSAGE_TYPE:
461 UDPGet(&v); // Skip len
462 // Len must be 1.
463 if ( v == 1u )
464 {
465 UDPGet(&type); // Get type
466
467 // Throw away the packet if we know we don't need it (ie: another offer when we already have one)
468 if(DHCPFlags.bits.bOfferReceived && (type == DHCP_OFFER_MESSAGE))
469 {
470 goto UDPInvalid;
471 }
472 }
473 else
474 goto UDPInvalid;
475 break;
476
477 case DHCP_SUBNET_MASK:
478 UDPGet(&v); // Skip len
479 // Len must be 4.
480 if ( v == 4u )
481 {
482 // Check to see if this is the first offer
483 if(DHCPFlags.bits.bOfferReceived)
484 {
485 // Discard offered IP mask, we already have an offer
486 for ( i = 0; i < 4u; i++ )
487 UDPGet(&v);
488 }
489 else
490 {
491 UDPGetArray((BYTE*)&tempMask, sizeof(tempMask));
492 ValidValues.bits.Mask = 1;
493 }
494 }
495 else
496 goto UDPInvalid;
497 break;
498
499 case DHCP_ROUTER:
500 UDPGet(&j);
501 // Len must be >= 4.
502 if ( j >= 4u )
503 {
504 // Check to see if this is the first offer
505 if(DHCPFlags.bits.bOfferReceived)
506 {
507 // Discard offered Gateway address, we already have an offer
508 for ( i = 0; i < 4u; i++ )
509 UDPGet(&v);
510 }
511 else
512 {
513 UDPGetArray((BYTE*)&tempGateway, sizeof(tempGateway));
514 ValidValues.bits.Gateway = 1;
515 }
516 }
517 else
518 goto UDPInvalid;
519
520 // Discard any other router addresses.
521 j -= 4;
522 while(j--)
523 UDPGet(&v);
524 break;
525
526 #if defined(STACK_USE_DNS)
527 case DHCP_DNS:
528 UDPGet(&j);
529 // Len must be >= 4.
530 if(j < 4u)
531 goto UDPInvalid;
532
533 // Check to see if this is the first offer
534 if(!DHCPFlags.bits.bOfferReceived)
535 {
536 UDPGetArray((BYTE*)&tempDNS, sizeof(tempDNS));
537 ValidValues.bits.DNS = 1;
538 j -= 4;
539 }
540
541 // Len must be >= 4 for a secondary DNS server address
542 if(j >= 4u)
543 {
544 // Check to see if this is the first offer
545 if(!DHCPFlags.bits.bOfferReceived)
546 {
547 UDPGetArray((BYTE*)&tempDNS2, sizeof(tempDNS2));
548 ValidValues.bits.DNS2 = 1;
549 j -= 4;
550 }
551 }
552
553 // Discard any other DNS server addresses
554 while(j--)
555 UDPGet(&v);
556 break;
557 #endif
558
559 // case DHCP_HOST_NAME:
560 // UDPGet(&j);
561 // // Len must be >= 4.
562 // if(j < 1u)
563 // goto UDPInvalid;
564 //
565 // // Check to see if this is the first offer
566 // if(DHCPFlags.bits.bOfferReceived)
567 // {
568 // // Discard offered host name, we already have an offer
569 // while(j--)
570 // UDPGet(&v);
571 // }
572 // else
573 // {
574 // for(i = 0; j, i < sizeof(tempHostName); i++, j--)
575 // {
576 // UDPGet(&tempHostName[i]);
577 // }
578 // while(j--)
579 // {
580 // UDPGet(&v);
581 // }
582 // ValidValues.bits.HostName = 1;
583 // }
584 //
585 // break;
586
587 case DHCP_SERVER_IDENTIFIER:
588 UDPGet(&v); // Get len
589 // Len must be 4.
590 if ( v == 4u )
591 {
592 UDPGet(&tempServerID.v[3]); // Get the id
593 UDPGet(&tempServerID.v[2]);
594 UDPGet(&tempServerID.v[1]);
595 UDPGet(&tempServerID.v[0]);
596 }
597 else
598 goto UDPInvalid;
599 break;
600
601 case DHCP_END_OPTION:
602 lbDone = TRUE;
603 break;
604
605 case DHCP_IP_LEASE_TIME:
606 UDPGet(&v); // Get len
607 // Len must be 4.
608 if ( v == 4u )
609 {
610 // Check to see if this is the first offer
611 if(DHCPFlags.bits.bOfferReceived)
612 {
613 // Discard offered lease time, we already have an offer
614 for ( i = 0; i < 4u; i++ )
615 UDPGet(&v);
616 }
617 else
618 {
619 UDPGet(&DHCPLeaseTime.v[3]);
620 UDPGet(&DHCPLeaseTime.v[2]);
621 UDPGet(&DHCPLeaseTime.v[1]);
622 UDPGet(&DHCPLeaseTime.v[0]);
623
624 // In case if our clock is not as accurate as the remote
625 // DHCP server's clock, let's treat the lease time as only
626 // 96.875% of the value given
627 DHCPLeaseTime.Val -= DHCPLeaseTime.Val>>5;
628 }
629 }
630 else
631 goto UDPInvalid;
632 break;
633
634 default:
635 // Ignore all unsupport tags.
636 UDPGet(&j); // Get option len
637 while( j-- ) // Ignore option values
638 UDPGet(&v);
639 }
640 } while( !lbDone );
641 }
642
643 // If this is an OFFER message, remember current server id.
644 if ( type == DHCP_OFFER_MESSAGE )
645 {
646 DHCPServerID.Val = tempServerID.Val;
647 DHCPFlags.bits.bOfferReceived = TRUE;
648 }
649 else
650 {
651 // For other types of messages, make sure that received
652 // server id matches with our previous one.
653 if ( DHCPServerID.Val != tempServerID.Val )
654 type = DHCP_UNKNOWN_MESSAGE;
655 }
656
657 UDPDiscard(); // We are done with this packet
658 return type;
659
660 UDPInvalid:
661 UDPDiscard();
662 return DHCP_UNKNOWN_MESSAGE;
663
664 }
665
666
667
668
669
670 static void _DHCPSend(BYTE messageType)
671 {
672 BYTE i;
673 IP_ADDR MyIP;
674
675
676 UDPPut(BOOT_REQUEST); // op
677 UDPPut(BOOT_HW_TYPE); // htype
678 UDPPut(BOOT_LEN_OF_HW_TYPE); // hlen
679 UDPPut(0); // hops
680 UDPPut(0x12); // xid[0]
681 UDPPut(0x23); // xid[1]
682 UDPPut(0x34); // xid[2]
683 UDPPut(0x56); // xid[3]
684 UDPPut(0); // secs[0]
685 UDPPut(0); // secs[1]
686 UDPPut(0x80); // flags[0] with BF set
687 UDPPut(0); // flags[1]
688
689 // If this is DHCP REQUEST message, use previously allocated IP address.
690 #if 0
691 if ( messageType == DHCP_REQUEST_MESSAGE )
692 {
693 UDPPutArray((BYTE*)&tempIPAddress, sizeof(tempIPAddress));
694 }
695 else
696 #endif
697 {
698 UDPPut(0x00);
699 UDPPut(0x00);
700 UDPPut(0x00);
701 UDPPut(0x00);
702 }
703
704 // Set yiaddr, siaddr, giaddr as zeros,
705 for ( i = 0; i < 12u; i++ )
706 UDPPut(0x00);
707
708 // Load chaddr - Client hardware address.
709 UDPPutArray((BYTE*)&AppConfig.MyMACAddr, sizeof(AppConfig.MyMACAddr));
710
711 // Set chaddr[6..15], sname and file as zeros.
712 for ( i = 0; i < 202u; i++ )
713 UDPPut(0);
714
715 // Load magic cookie as per RFC 1533.
716 UDPPut(99);
717 UDPPut(130);
718 UDPPut(83);
719 UDPPut(99);
720
721 // Load message type.
722 UDPPut(DHCP_MESSAGE_TYPE);
723 UDPPut(DHCP_MESSAGE_TYPE_LEN);
724 UDPPut(messageType);
725
726 if(messageType == DHCP_DISCOVER_MESSAGE)
727 {
728 // Reset offered flag so we know to act upon the next valid offer
729 DHCPFlags.bits.bOfferReceived = FALSE;
730 }
731
732
733 if ( messageType != DHCP_DISCOVER_MESSAGE && tempIPAddress.Val != 0x0000u )
734 {
735 // DHCP REQUEST message may include server identifier,
736 // to identify the server we are talking to.
737 // DHCP ACK may include it too. To simplify logic,
738 // we will include server identifier in DHCP ACK message too.
739 // _DHCPReceive() would populate "serverID" when it
740 // receives DHCP OFFER message. We will simply use that
741 // when we are replying to server.
742 // If this is a renwal request, do not include server id.
743 UDPPut(DHCP_SERVER_IDENTIFIER);
744 UDPPut(DHCP_SERVER_IDENTIFIER_LEN);
745 UDPPut(DHCPServerID.v[3]);
746 UDPPut(DHCPServerID.v[2]);
747 UDPPut(DHCPServerID.v[1]);
748 UDPPut(DHCPServerID.v[0]);
749 }
750
751 // Load our interested parameters
752 // This is hardcoded list. If any new parameters are desired,
753 // new lines must be added here.
754 UDPPut(DHCP_PARAM_REQUEST_LIST);
755 UDPPut(DHCP_PARAM_REQUEST_LIST_LEN);
756 UDPPut(DHCP_SUBNET_MASK);
757 UDPPut(DHCP_ROUTER);
758 UDPPut(DHCP_DNS);
759 UDPPut(DHCP_HOST_NAME);
760
761 // Add requested IP address to DHCP Request Message
762 if ( messageType == DHCP_REQUEST_MESSAGE )
763 {
764 UDPPut(DHCP_PARAM_REQUEST_IP_ADDRESS);
765 UDPPut(DHCP_PARAM_REQUEST_IP_ADDRESS_LEN);
766 UDPPutArray((BYTE*)&tempIPAddress, DHCP_PARAM_REQUEST_IP_ADDRESS_LEN);
767 }
768
769 // Add any new paramter request here.
770
771 // End of Options.
772 UDPPut(DHCP_END_OPTION);
773
774 // Make sure we advirtise a 0.0.0.0 IP address so all DHCP servers will respond. If we have a static IP outside the DHCP server's scope, it may simply ignore discover messages.
775 MyIP.Val = AppConfig.MyIPAddr.Val;
776 AppConfig.MyIPAddr.Val = 0x00000000;
777 UDPFlush();
778 AppConfig.MyIPAddr.Val = MyIP.Val;
779
780 }
781
782
783 #endif //#if defined(STACK_USE_DHCP_CLIENT)

  ViewVC Help
Powered by ViewVC 1.1.20