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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 15 - (hide annotations) (download)
Thu Apr 19 09:01:15 2007 UTC (17 years, 2 months ago) by hedin
File MIME type: text/plain
File size: 25358 byte(s)
added the TCP/IP stack, source code.
1 hedin 15 /*********************************************************************
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