1 | //***************************************************************************** |
---|
2 | // |
---|
3 | //! \file dhcp.c |
---|
4 | //! \brief DHCP APIs implement file. |
---|
5 | //! \details Processing DHCP protocol as DISCOVER, OFFER, REQUEST, ACK, NACK and DECLINE. |
---|
6 | //! \version 1.1.1 |
---|
7 | //! \date 2019/10/08 |
---|
8 | //! \par Revision history |
---|
9 | //! <2019/10/08> compare DHCP server ip address |
---|
10 | //! <2013/11/18> 1st Release |
---|
11 | //! <2012/12/20> V1.1.0 |
---|
12 | //! 1. Optimize code |
---|
13 | //! 2. Add reg_dhcp_cbfunc() |
---|
14 | //! 3. Add DHCP_stop() |
---|
15 | //! 4. Integrate check_DHCP_state() & DHCP_run() to DHCP_run() |
---|
16 | //! 5. Don't care system endian |
---|
17 | //! 6. Add comments |
---|
18 | //! <2012/12/26> V1.1.1 |
---|
19 | //! 1. Modify variable declaration: dhcp_tick_1s is declared volatile for code optimization |
---|
20 | //! \author Eric Jung & MidnightCow |
---|
21 | //! \copyright |
---|
22 | //! |
---|
23 | //! Copyright (c) 2013, WIZnet Co., LTD. |
---|
24 | //! All rights reserved. |
---|
25 | //! |
---|
26 | //! Redistribution and use in source and binary forms, with or without |
---|
27 | //! modification, are permitted provided that the following conditions |
---|
28 | //! are met: |
---|
29 | //! |
---|
30 | //! * Redistributions of source code must retain the above copyright |
---|
31 | //! notice, this list of conditions and the following disclaimer. |
---|
32 | //! * Redistributions in binary form must reproduce the above copyright |
---|
33 | //! notice, this list of conditions and the following disclaimer in the |
---|
34 | //! documentation and/or other materials provided with the distribution. |
---|
35 | //! * Neither the name of the <ORGANIZATION> nor the names of its |
---|
36 | //! contributors may be used to endorse or promote products derived |
---|
37 | //! from this software without specific prior written permission. |
---|
38 | //! |
---|
39 | //! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
---|
40 | //! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
---|
41 | //! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
---|
42 | //! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
---|
43 | //! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
---|
44 | //! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
---|
45 | //! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
---|
46 | //! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
---|
47 | //! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
---|
48 | //! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
---|
49 | //! THE POSSIBILITY OF SUCH DAMAGE. |
---|
50 | // |
---|
51 | //***************************************************************************** |
---|
52 | |
---|
53 | #include "socket.h" |
---|
54 | #include "dhcp.h" |
---|
55 | |
---|
56 | /* If you want to display debug & processing message, Define _DHCP_DEBUG_ in dhcp.h */ |
---|
57 | |
---|
58 | #ifdef _DHCP_DEBUG_ |
---|
59 | #include <stdio.h> |
---|
60 | #endif |
---|
61 | |
---|
62 | /* DHCP state machine. */ |
---|
63 | #define STATE_DHCP_INIT 0 ///< Initialize |
---|
64 | #define STATE_DHCP_DISCOVER 1 ///< send DISCOVER and wait OFFER |
---|
65 | #define STATE_DHCP_REQUEST 2 ///< send REQEUST and wait ACK or NACK |
---|
66 | #define STATE_DHCP_LEASED 3 ///< ReceiveD ACK and IP leased |
---|
67 | #define STATE_DHCP_REREQUEST 4 ///< send REQUEST for maintaining leased IP |
---|
68 | #define STATE_DHCP_RELEASE 5 ///< No use |
---|
69 | #define STATE_DHCP_STOP 6 ///< Stop processing DHCP |
---|
70 | |
---|
71 | #define DHCP_FLAGSBROADCAST 0x8000 ///< The broadcast value of flags in @ref RIP_MSG |
---|
72 | #define DHCP_FLAGSUNICAST 0x0000 ///< The unicast value of flags in @ref RIP_MSG |
---|
73 | |
---|
74 | /* DHCP message OP code */ |
---|
75 | #define DHCP_BOOTREQUEST 1 ///< Request Message used in op of @ref RIP_MSG |
---|
76 | #define DHCP_BOOTREPLY 2 ///< Reply Message used i op of @ref RIP_MSG |
---|
77 | |
---|
78 | /* DHCP message type */ |
---|
79 | #define DHCP_DISCOVER 1 ///< DISCOVER message in OPT of @ref RIP_MSG |
---|
80 | #define DHCP_OFFER 2 ///< OFFER message in OPT of @ref RIP_MSG |
---|
81 | #define DHCP_REQUEST 3 ///< REQUEST message in OPT of @ref RIP_MSG |
---|
82 | #define DHCP_DECLINE 4 ///< DECLINE message in OPT of @ref RIP_MSG |
---|
83 | #define DHCP_ACK 5 ///< ACK message in OPT of @ref RIP_MSG |
---|
84 | #define DHCP_NAK 6 ///< NACK message in OPT of @ref RIP_MSG |
---|
85 | #define DHCP_RELEASE 7 ///< RELEASE message in OPT of @ref RIP_MSG. No use |
---|
86 | #define DHCP_INFORM 8 ///< INFORM message in OPT of @ref RIP_MSG. No use |
---|
87 | |
---|
88 | #define DHCP_HTYPE10MB 1 ///< Used in type of @ref RIP_MSG |
---|
89 | #define DHCP_HTYPE100MB 2 ///< Used in type of @ref RIP_MSG |
---|
90 | |
---|
91 | #define DHCP_HLENETHERNET 6 ///< Used in hlen of @ref RIP_MSG |
---|
92 | #define DHCP_HOPS 0 ///< Used in hops of @ref RIP_MSG |
---|
93 | #define DHCP_SECS 0 ///< Used in secs of @ref RIP_MSG |
---|
94 | |
---|
95 | #define INFINITE_LEASETIME 0xffffffff ///< Infinite lease time |
---|
96 | |
---|
97 | #define OPT_SIZE 312 /// Max OPT size of @ref RIP_MSG |
---|
98 | #define RIP_MSG_SIZE (236+OPT_SIZE) /// Max size of @ref RIP_MSG |
---|
99 | |
---|
100 | /* |
---|
101 | * @brief DHCP option and value (cf. RFC1533) |
---|
102 | */ |
---|
103 | enum |
---|
104 | { |
---|
105 | padOption = 0, |
---|
106 | subnetMask = 1, |
---|
107 | timerOffset = 2, |
---|
108 | routersOnSubnet = 3, |
---|
109 | timeServer = 4, |
---|
110 | nameServer = 5, |
---|
111 | dns = 6, |
---|
112 | logServer = 7, |
---|
113 | cookieServer = 8, |
---|
114 | lprServer = 9, |
---|
115 | impressServer = 10, |
---|
116 | resourceLocationServer = 11, |
---|
117 | hostName = 12, |
---|
118 | bootFileSize = 13, |
---|
119 | meritDumpFile = 14, |
---|
120 | domainName = 15, |
---|
121 | swapServer = 16, |
---|
122 | rootPath = 17, |
---|
123 | extentionsPath = 18, |
---|
124 | IPforwarding = 19, |
---|
125 | nonLocalSourceRouting = 20, |
---|
126 | policyFilter = 21, |
---|
127 | maxDgramReasmSize = 22, |
---|
128 | defaultIPTTL = 23, |
---|
129 | pathMTUagingTimeout = 24, |
---|
130 | pathMTUplateauTable = 25, |
---|
131 | ifMTU = 26, |
---|
132 | allSubnetsLocal = 27, |
---|
133 | broadcastAddr = 28, |
---|
134 | performMaskDiscovery = 29, |
---|
135 | maskSupplier = 30, |
---|
136 | performRouterDiscovery = 31, |
---|
137 | routerSolicitationAddr = 32, |
---|
138 | staticRoute = 33, |
---|
139 | trailerEncapsulation = 34, |
---|
140 | arpCacheTimeout = 35, |
---|
141 | ethernetEncapsulation = 36, |
---|
142 | tcpDefaultTTL = 37, |
---|
143 | tcpKeepaliveInterval = 38, |
---|
144 | tcpKeepaliveGarbage = 39, |
---|
145 | nisDomainName = 40, |
---|
146 | nisServers = 41, |
---|
147 | ntpServers = 42, |
---|
148 | vendorSpecificInfo = 43, |
---|
149 | netBIOSnameServer = 44, |
---|
150 | netBIOSdgramDistServer = 45, |
---|
151 | netBIOSnodeType = 46, |
---|
152 | netBIOSscope = 47, |
---|
153 | xFontServer = 48, |
---|
154 | xDisplayManager = 49, |
---|
155 | dhcpRequestedIPaddr = 50, |
---|
156 | dhcpIPaddrLeaseTime = 51, |
---|
157 | dhcpOptionOverload = 52, |
---|
158 | dhcpMessageType = 53, |
---|
159 | dhcpServerIdentifier = 54, |
---|
160 | dhcpParamRequest = 55, |
---|
161 | dhcpMsg = 56, |
---|
162 | dhcpMaxMsgSize = 57, |
---|
163 | dhcpT1value = 58, |
---|
164 | dhcpT2value = 59, |
---|
165 | dhcpClassIdentifier = 60, |
---|
166 | dhcpClientIdentifier = 61, |
---|
167 | endOption = 255 |
---|
168 | }; |
---|
169 | |
---|
170 | /* |
---|
171 | * @brief DHCP message format |
---|
172 | */ |
---|
173 | typedef struct { |
---|
174 | uint8_t op; ///< @ref DHCP_BOOTREQUEST or @ref DHCP_BOOTREPLY |
---|
175 | uint8_t htype; ///< @ref DHCP_HTYPE10MB or @ref DHCP_HTYPE100MB |
---|
176 | uint8_t hlen; ///< @ref DHCP_HLENETHERNET |
---|
177 | uint8_t hops; ///< @ref DHCP_HOPS |
---|
178 | uint32_t xid; ///< @ref DHCP_XID This increase one every DHCP transaction. |
---|
179 | uint16_t secs; ///< @ref DHCP_SECS |
---|
180 | uint16_t flags; ///< @ref DHCP_FLAGSBROADCAST or @ref DHCP_FLAGSUNICAST |
---|
181 | uint8_t ciaddr[4]; ///< @ref Request IP to DHCP sever |
---|
182 | uint8_t yiaddr[4]; ///< @ref Offered IP from DHCP server |
---|
183 | uint8_t siaddr[4]; ///< No use |
---|
184 | uint8_t giaddr[4]; ///< No use |
---|
185 | uint8_t chaddr[16]; ///< DHCP client 6bytes MAC address. Others is filled to zero |
---|
186 | uint8_t sname[64]; ///< No use |
---|
187 | uint8_t file[128]; ///< No use |
---|
188 | uint8_t OPT[OPT_SIZE]; ///< Option |
---|
189 | } RIP_MSG; |
---|
190 | |
---|
191 | |
---|
192 | |
---|
193 | uint8_t DHCP_SOCKET; // Socket number for DHCP |
---|
194 | |
---|
195 | uint8_t DHCP_SIP[4]; // DHCP Server IP address |
---|
196 | uint8_t DHCP_REAL_SIP[4]; // For extract my DHCP server in a few DHCP server |
---|
197 | |
---|
198 | // Network information from DHCP Server |
---|
199 | uint8_t OLD_allocated_ip[4] = {0, }; // Previous IP address |
---|
200 | uint8_t DHCP_allocated_ip[4] = {0, }; // IP address from DHCP |
---|
201 | uint8_t DHCP_allocated_gw[4] = {0, }; // Gateway address from DHCP |
---|
202 | uint8_t DHCP_allocated_sn[4] = {0, }; // Subnet mask from DHCP |
---|
203 | uint8_t DHCP_allocated_dns[4] = {0, }; // DNS address from DHCP |
---|
204 | |
---|
205 | |
---|
206 | int8_t dhcp_state = STATE_DHCP_INIT; // DHCP state |
---|
207 | int8_t dhcp_retry_count = 0; |
---|
208 | |
---|
209 | uint32_t dhcp_lease_time = INFINITE_LEASETIME; |
---|
210 | volatile uint32_t dhcp_tick_1s = 0; // unit 1 second |
---|
211 | uint32_t dhcp_tick_next = DHCP_WAIT_TIME ; |
---|
212 | |
---|
213 | uint32_t DHCP_XID; // Any number |
---|
214 | |
---|
215 | RIP_MSG* pDHCPMSG; // Buffer pointer for DHCP processing |
---|
216 | |
---|
217 | uint8_t HOST_NAME[] = DCHP_HOST_NAME; |
---|
218 | |
---|
219 | uint8_t DHCP_CHADDR[6]; // DHCP Client MAC address. |
---|
220 | |
---|
221 | /* The default callback function */ |
---|
222 | void default_ip_assign(void); |
---|
223 | void default_ip_update(void); |
---|
224 | void default_ip_conflict(void); |
---|
225 | |
---|
226 | /* Callback handler */ |
---|
227 | void (*dhcp_ip_assign)(void) = default_ip_assign; /* handler to be called when the IP address from DHCP server is first assigned */ |
---|
228 | void (*dhcp_ip_update)(void) = default_ip_update; /* handler to be called when the IP address from DHCP server is updated */ |
---|
229 | void (*dhcp_ip_conflict)(void) = default_ip_conflict; /* handler to be called when the IP address from DHCP server is conflict */ |
---|
230 | |
---|
231 | void reg_dhcp_cbfunc(void(*ip_assign)(void), void(*ip_update)(void), void(*ip_conflict)(void)); |
---|
232 | |
---|
233 | char NibbleToHex(uint8_t nibble); |
---|
234 | |
---|
235 | /* send DISCOVER message to DHCP server */ |
---|
236 | void send_DHCP_DISCOVER(void); |
---|
237 | |
---|
238 | /* send REQEUST message to DHCP server */ |
---|
239 | void send_DHCP_REQUEST(void); |
---|
240 | |
---|
241 | /* send DECLINE message to DHCP server */ |
---|
242 | void send_DHCP_DECLINE(void); |
---|
243 | |
---|
244 | /* IP conflict check by sending ARP-request to leased IP and wait ARP-response. */ |
---|
245 | int8_t check_DHCP_leasedIP(void); |
---|
246 | |
---|
247 | /* check the timeout in DHCP process */ |
---|
248 | uint8_t check_DHCP_timeout(void); |
---|
249 | |
---|
250 | /* Initialize to timeout process. */ |
---|
251 | void reset_DHCP_timeout(void); |
---|
252 | |
---|
253 | /* Parse message as OFFER and ACK and NACK from DHCP server.*/ |
---|
254 | int8_t parseDHCPCMSG(void); |
---|
255 | |
---|
256 | /* The default handler of ip assign first */ |
---|
257 | void default_ip_assign(void) |
---|
258 | { |
---|
259 | setSIPR(DHCP_allocated_ip); |
---|
260 | setSUBR(DHCP_allocated_sn); |
---|
261 | setGAR (DHCP_allocated_gw); |
---|
262 | } |
---|
263 | |
---|
264 | /* The default handler of ip changed */ |
---|
265 | void default_ip_update(void) |
---|
266 | { |
---|
267 | /* WIZchip Software Reset */ |
---|
268 | setMR(MR_RST); |
---|
269 | getMR(); // for delay |
---|
270 | default_ip_assign(); |
---|
271 | setSHAR(DHCP_CHADDR); |
---|
272 | } |
---|
273 | |
---|
274 | /* The default handler of ip changed */ |
---|
275 | void default_ip_conflict(void) |
---|
276 | { |
---|
277 | // WIZchip Software Reset |
---|
278 | setMR(MR_RST); |
---|
279 | getMR(); // for delay |
---|
280 | setSHAR(DHCP_CHADDR); |
---|
281 | } |
---|
282 | |
---|
283 | /* register the call back func. */ |
---|
284 | void reg_dhcp_cbfunc(void(*ip_assign)(void), void(*ip_update)(void), void(*ip_conflict)(void)) |
---|
285 | { |
---|
286 | dhcp_ip_assign = default_ip_assign; |
---|
287 | dhcp_ip_update = default_ip_update; |
---|
288 | dhcp_ip_conflict = default_ip_conflict; |
---|
289 | if(ip_assign) dhcp_ip_assign = ip_assign; |
---|
290 | if(ip_update) dhcp_ip_update = ip_update; |
---|
291 | if(ip_conflict) dhcp_ip_conflict = ip_conflict; |
---|
292 | } |
---|
293 | |
---|
294 | /* make the common DHCP message */ |
---|
295 | void makeDHCPMSG(void) |
---|
296 | { |
---|
297 | uint8_t bk_mac[6]; |
---|
298 | uint8_t* ptmp; |
---|
299 | uint8_t i; |
---|
300 | getSHAR(bk_mac); |
---|
301 | pDHCPMSG->op = DHCP_BOOTREQUEST; |
---|
302 | pDHCPMSG->htype = DHCP_HTYPE10MB; |
---|
303 | pDHCPMSG->hlen = DHCP_HLENETHERNET; |
---|
304 | pDHCPMSG->hops = DHCP_HOPS; |
---|
305 | ptmp = (uint8_t*)(&pDHCPMSG->xid); |
---|
306 | *(ptmp+0) = (uint8_t)((DHCP_XID & 0xFF000000) >> 24); |
---|
307 | *(ptmp+1) = (uint8_t)((DHCP_XID & 0x00FF0000) >> 16); |
---|
308 | *(ptmp+2) = (uint8_t)((DHCP_XID & 0x0000FF00) >> 8); |
---|
309 | *(ptmp+3) = (uint8_t)((DHCP_XID & 0x000000FF) >> 0); |
---|
310 | pDHCPMSG->secs = DHCP_SECS; |
---|
311 | ptmp = (uint8_t*)(&pDHCPMSG->flags); |
---|
312 | *(ptmp+0) = (uint8_t)((DHCP_FLAGSBROADCAST & 0xFF00) >> 8); |
---|
313 | *(ptmp+1) = (uint8_t)((DHCP_FLAGSBROADCAST & 0x00FF) >> 0); |
---|
314 | |
---|
315 | pDHCPMSG->ciaddr[0] = 0; |
---|
316 | pDHCPMSG->ciaddr[1] = 0; |
---|
317 | pDHCPMSG->ciaddr[2] = 0; |
---|
318 | pDHCPMSG->ciaddr[3] = 0; |
---|
319 | |
---|
320 | pDHCPMSG->yiaddr[0] = 0; |
---|
321 | pDHCPMSG->yiaddr[1] = 0; |
---|
322 | pDHCPMSG->yiaddr[2] = 0; |
---|
323 | pDHCPMSG->yiaddr[3] = 0; |
---|
324 | |
---|
325 | pDHCPMSG->siaddr[0] = 0; |
---|
326 | pDHCPMSG->siaddr[1] = 0; |
---|
327 | pDHCPMSG->siaddr[2] = 0; |
---|
328 | pDHCPMSG->siaddr[3] = 0; |
---|
329 | |
---|
330 | pDHCPMSG->giaddr[0] = 0; |
---|
331 | pDHCPMSG->giaddr[1] = 0; |
---|
332 | pDHCPMSG->giaddr[2] = 0; |
---|
333 | pDHCPMSG->giaddr[3] = 0; |
---|
334 | |
---|
335 | pDHCPMSG->chaddr[0] = DHCP_CHADDR[0]; |
---|
336 | pDHCPMSG->chaddr[1] = DHCP_CHADDR[1]; |
---|
337 | pDHCPMSG->chaddr[2] = DHCP_CHADDR[2]; |
---|
338 | pDHCPMSG->chaddr[3] = DHCP_CHADDR[3]; |
---|
339 | pDHCPMSG->chaddr[4] = DHCP_CHADDR[4]; |
---|
340 | pDHCPMSG->chaddr[5] = DHCP_CHADDR[5]; |
---|
341 | |
---|
342 | for (i = 6; i < 16; i++) pDHCPMSG->chaddr[i] = 0; |
---|
343 | for (i = 0; i < 64; i++) pDHCPMSG->sname[i] = 0; |
---|
344 | for (i = 0; i < 128; i++) pDHCPMSG->file[i] = 0; |
---|
345 | |
---|
346 | // MAGIC_COOKIE |
---|
347 | pDHCPMSG->OPT[0] = (uint8_t)((MAGIC_COOKIE & 0xFF000000) >> 24); |
---|
348 | pDHCPMSG->OPT[1] = (uint8_t)((MAGIC_COOKIE & 0x00FF0000) >> 16); |
---|
349 | pDHCPMSG->OPT[2] = (uint8_t)((MAGIC_COOKIE & 0x0000FF00) >> 8); |
---|
350 | pDHCPMSG->OPT[3] = (uint8_t) (MAGIC_COOKIE & 0x000000FF) >> 0; |
---|
351 | } |
---|
352 | |
---|
353 | /* SEND DHCP DISCOVER */ |
---|
354 | void send_DHCP_DISCOVER(void) |
---|
355 | { |
---|
356 | uint16_t i; |
---|
357 | uint8_t ip[4]; |
---|
358 | uint16_t k = 0; |
---|
359 | |
---|
360 | makeDHCPMSG(); |
---|
361 | DHCP_SIP[0]=0; |
---|
362 | DHCP_SIP[1]=0; |
---|
363 | DHCP_SIP[2]=0; |
---|
364 | DHCP_SIP[3]=0; |
---|
365 | DHCP_REAL_SIP[0]=0; |
---|
366 | DHCP_REAL_SIP[1]=0; |
---|
367 | DHCP_REAL_SIP[2]=0; |
---|
368 | DHCP_REAL_SIP[3]=0; |
---|
369 | |
---|
370 | k = 4; // because MAGIC_COOKIE already made by makeDHCPMSG() |
---|
371 | |
---|
372 | // Option Request Param |
---|
373 | pDHCPMSG->OPT[k++] = dhcpMessageType; |
---|
374 | pDHCPMSG->OPT[k++] = 0x01; |
---|
375 | pDHCPMSG->OPT[k++] = DHCP_DISCOVER; |
---|
376 | |
---|
377 | // Client identifier |
---|
378 | pDHCPMSG->OPT[k++] = dhcpClientIdentifier; |
---|
379 | pDHCPMSG->OPT[k++] = 0x07; |
---|
380 | pDHCPMSG->OPT[k++] = 0x01; |
---|
381 | pDHCPMSG->OPT[k++] = DHCP_CHADDR[0]; |
---|
382 | pDHCPMSG->OPT[k++] = DHCP_CHADDR[1]; |
---|
383 | pDHCPMSG->OPT[k++] = DHCP_CHADDR[2]; |
---|
384 | pDHCPMSG->OPT[k++] = DHCP_CHADDR[3]; |
---|
385 | pDHCPMSG->OPT[k++] = DHCP_CHADDR[4]; |
---|
386 | pDHCPMSG->OPT[k++] = DHCP_CHADDR[5]; |
---|
387 | |
---|
388 | // host name |
---|
389 | pDHCPMSG->OPT[k++] = hostName; |
---|
390 | pDHCPMSG->OPT[k++] = 0; // fill zero length of hostname |
---|
391 | for(i = 0 ; HOST_NAME[i] != 0; i++) |
---|
392 | pDHCPMSG->OPT[k++] = HOST_NAME[i]; |
---|
393 | pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[3] >> 4); |
---|
394 | pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[3]); |
---|
395 | pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[4] >> 4); |
---|
396 | pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[4]); |
---|
397 | pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[5] >> 4); |
---|
398 | pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[5]); |
---|
399 | pDHCPMSG->OPT[k - (i+6+1)] = i+6; // length of hostname |
---|
400 | |
---|
401 | pDHCPMSG->OPT[k++] = dhcpParamRequest; |
---|
402 | pDHCPMSG->OPT[k++] = 0x06; // length of request |
---|
403 | pDHCPMSG->OPT[k++] = subnetMask; |
---|
404 | pDHCPMSG->OPT[k++] = routersOnSubnet; |
---|
405 | pDHCPMSG->OPT[k++] = dns; |
---|
406 | pDHCPMSG->OPT[k++] = domainName; |
---|
407 | pDHCPMSG->OPT[k++] = dhcpT1value; |
---|
408 | pDHCPMSG->OPT[k++] = dhcpT2value; |
---|
409 | pDHCPMSG->OPT[k++] = endOption; |
---|
410 | |
---|
411 | for (i = k; i < OPT_SIZE; i++) pDHCPMSG->OPT[i] = 0; |
---|
412 | |
---|
413 | // send broadcasting packet |
---|
414 | ip[0] = 255; |
---|
415 | ip[1] = 255; |
---|
416 | ip[2] = 255; |
---|
417 | ip[3] = 255; |
---|
418 | |
---|
419 | #ifdef _DHCP_DEBUG_ |
---|
420 | printf("> Send DHCP_DISCOVER\r\n"); |
---|
421 | #endif |
---|
422 | |
---|
423 | sendto(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT); |
---|
424 | } |
---|
425 | |
---|
426 | /* SEND DHCP REQUEST */ |
---|
427 | void send_DHCP_REQUEST(void) |
---|
428 | { |
---|
429 | int i; |
---|
430 | uint8_t ip[4]; |
---|
431 | uint16_t k = 0; |
---|
432 | |
---|
433 | makeDHCPMSG(); |
---|
434 | |
---|
435 | if(dhcp_state == STATE_DHCP_LEASED || dhcp_state == STATE_DHCP_REREQUEST) |
---|
436 | { |
---|
437 | *((uint8_t*)(&pDHCPMSG->flags)) = ((DHCP_FLAGSUNICAST & 0xFF00)>> 8); |
---|
438 | *((uint8_t*)(&pDHCPMSG->flags)+1) = (DHCP_FLAGSUNICAST & 0x00FF); |
---|
439 | pDHCPMSG->ciaddr[0] = DHCP_allocated_ip[0]; |
---|
440 | pDHCPMSG->ciaddr[1] = DHCP_allocated_ip[1]; |
---|
441 | pDHCPMSG->ciaddr[2] = DHCP_allocated_ip[2]; |
---|
442 | pDHCPMSG->ciaddr[3] = DHCP_allocated_ip[3]; |
---|
443 | ip[0] = DHCP_SIP[0]; |
---|
444 | ip[1] = DHCP_SIP[1]; |
---|
445 | ip[2] = DHCP_SIP[2]; |
---|
446 | ip[3] = DHCP_SIP[3]; |
---|
447 | } |
---|
448 | else |
---|
449 | { |
---|
450 | ip[0] = 255; |
---|
451 | ip[1] = 255; |
---|
452 | ip[2] = 255; |
---|
453 | ip[3] = 255; |
---|
454 | } |
---|
455 | |
---|
456 | k = 4; // because MAGIC_COOKIE already made by makeDHCPMSG() |
---|
457 | |
---|
458 | // Option Request Param. |
---|
459 | pDHCPMSG->OPT[k++] = dhcpMessageType; |
---|
460 | pDHCPMSG->OPT[k++] = 0x01; |
---|
461 | pDHCPMSG->OPT[k++] = DHCP_REQUEST; |
---|
462 | |
---|
463 | pDHCPMSG->OPT[k++] = dhcpClientIdentifier; |
---|
464 | pDHCPMSG->OPT[k++] = 0x07; |
---|
465 | pDHCPMSG->OPT[k++] = 0x01; |
---|
466 | pDHCPMSG->OPT[k++] = DHCP_CHADDR[0]; |
---|
467 | pDHCPMSG->OPT[k++] = DHCP_CHADDR[1]; |
---|
468 | pDHCPMSG->OPT[k++] = DHCP_CHADDR[2]; |
---|
469 | pDHCPMSG->OPT[k++] = DHCP_CHADDR[3]; |
---|
470 | pDHCPMSG->OPT[k++] = DHCP_CHADDR[4]; |
---|
471 | pDHCPMSG->OPT[k++] = DHCP_CHADDR[5]; |
---|
472 | |
---|
473 | if(ip[3] == 255) // if(dchp_state == STATE_DHCP_LEASED || dchp_state == DHCP_REREQUEST_STATE) |
---|
474 | { |
---|
475 | pDHCPMSG->OPT[k++] = dhcpRequestedIPaddr; |
---|
476 | pDHCPMSG->OPT[k++] = 0x04; |
---|
477 | pDHCPMSG->OPT[k++] = DHCP_allocated_ip[0]; |
---|
478 | pDHCPMSG->OPT[k++] = DHCP_allocated_ip[1]; |
---|
479 | pDHCPMSG->OPT[k++] = DHCP_allocated_ip[2]; |
---|
480 | pDHCPMSG->OPT[k++] = DHCP_allocated_ip[3]; |
---|
481 | |
---|
482 | pDHCPMSG->OPT[k++] = dhcpServerIdentifier; |
---|
483 | pDHCPMSG->OPT[k++] = 0x04; |
---|
484 | pDHCPMSG->OPT[k++] = DHCP_SIP[0]; |
---|
485 | pDHCPMSG->OPT[k++] = DHCP_SIP[1]; |
---|
486 | pDHCPMSG->OPT[k++] = DHCP_SIP[2]; |
---|
487 | pDHCPMSG->OPT[k++] = DHCP_SIP[3]; |
---|
488 | } |
---|
489 | |
---|
490 | // host name |
---|
491 | pDHCPMSG->OPT[k++] = hostName; |
---|
492 | pDHCPMSG->OPT[k++] = 0; // length of hostname |
---|
493 | for(i = 0 ; HOST_NAME[i] != 0; i++) |
---|
494 | pDHCPMSG->OPT[k++] = HOST_NAME[i]; |
---|
495 | pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[3] >> 4); |
---|
496 | pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[3]); |
---|
497 | pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[4] >> 4); |
---|
498 | pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[4]); |
---|
499 | pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[5] >> 4); |
---|
500 | pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[5]); |
---|
501 | pDHCPMSG->OPT[k - (i+6+1)] = i+6; // length of hostname |
---|
502 | |
---|
503 | pDHCPMSG->OPT[k++] = dhcpParamRequest; |
---|
504 | pDHCPMSG->OPT[k++] = 0x08; |
---|
505 | pDHCPMSG->OPT[k++] = subnetMask; |
---|
506 | pDHCPMSG->OPT[k++] = routersOnSubnet; |
---|
507 | pDHCPMSG->OPT[k++] = dns; |
---|
508 | pDHCPMSG->OPT[k++] = domainName; |
---|
509 | pDHCPMSG->OPT[k++] = dhcpT1value; |
---|
510 | pDHCPMSG->OPT[k++] = dhcpT2value; |
---|
511 | pDHCPMSG->OPT[k++] = performRouterDiscovery; |
---|
512 | pDHCPMSG->OPT[k++] = staticRoute; |
---|
513 | pDHCPMSG->OPT[k++] = endOption; |
---|
514 | |
---|
515 | for (i = k; i < OPT_SIZE; i++) pDHCPMSG->OPT[i] = 0; |
---|
516 | |
---|
517 | #ifdef _DHCP_DEBUG_ |
---|
518 | printf("> Send DHCP_REQUEST\r\n"); |
---|
519 | #endif |
---|
520 | |
---|
521 | sendto(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT); |
---|
522 | |
---|
523 | } |
---|
524 | |
---|
525 | /* SEND DHCP DHCPDECLINE */ |
---|
526 | void send_DHCP_DECLINE(void) |
---|
527 | { |
---|
528 | int i; |
---|
529 | uint8_t ip[4]; |
---|
530 | uint16_t k = 0; |
---|
531 | |
---|
532 | makeDHCPMSG(); |
---|
533 | |
---|
534 | k = 4; // because MAGIC_COOKIE already made by makeDHCPMSG() |
---|
535 | |
---|
536 | *((uint8_t*)(&pDHCPMSG->flags)) = ((DHCP_FLAGSUNICAST & 0xFF00)>> 8); |
---|
537 | *((uint8_t*)(&pDHCPMSG->flags)+1) = (DHCP_FLAGSUNICAST & 0x00FF); |
---|
538 | |
---|
539 | // Option Request Param. |
---|
540 | pDHCPMSG->OPT[k++] = dhcpMessageType; |
---|
541 | pDHCPMSG->OPT[k++] = 0x01; |
---|
542 | pDHCPMSG->OPT[k++] = DHCP_DECLINE; |
---|
543 | |
---|
544 | pDHCPMSG->OPT[k++] = dhcpClientIdentifier; |
---|
545 | pDHCPMSG->OPT[k++] = 0x07; |
---|
546 | pDHCPMSG->OPT[k++] = 0x01; |
---|
547 | pDHCPMSG->OPT[k++] = DHCP_CHADDR[0]; |
---|
548 | pDHCPMSG->OPT[k++] = DHCP_CHADDR[1]; |
---|
549 | pDHCPMSG->OPT[k++] = DHCP_CHADDR[2]; |
---|
550 | pDHCPMSG->OPT[k++] = DHCP_CHADDR[3]; |
---|
551 | pDHCPMSG->OPT[k++] = DHCP_CHADDR[4]; |
---|
552 | pDHCPMSG->OPT[k++] = DHCP_CHADDR[5]; |
---|
553 | |
---|
554 | pDHCPMSG->OPT[k++] = dhcpRequestedIPaddr; |
---|
555 | pDHCPMSG->OPT[k++] = 0x04; |
---|
556 | pDHCPMSG->OPT[k++] = DHCP_allocated_ip[0]; |
---|
557 | pDHCPMSG->OPT[k++] = DHCP_allocated_ip[1]; |
---|
558 | pDHCPMSG->OPT[k++] = DHCP_allocated_ip[2]; |
---|
559 | pDHCPMSG->OPT[k++] = DHCP_allocated_ip[3]; |
---|
560 | |
---|
561 | pDHCPMSG->OPT[k++] = dhcpServerIdentifier; |
---|
562 | pDHCPMSG->OPT[k++] = 0x04; |
---|
563 | pDHCPMSG->OPT[k++] = DHCP_SIP[0]; |
---|
564 | pDHCPMSG->OPT[k++] = DHCP_SIP[1]; |
---|
565 | pDHCPMSG->OPT[k++] = DHCP_SIP[2]; |
---|
566 | pDHCPMSG->OPT[k++] = DHCP_SIP[3]; |
---|
567 | |
---|
568 | pDHCPMSG->OPT[k++] = endOption; |
---|
569 | |
---|
570 | for (i = k; i < OPT_SIZE; i++) pDHCPMSG->OPT[i] = 0; |
---|
571 | |
---|
572 | //send broadcasting packet |
---|
573 | ip[0] = 0xFF; |
---|
574 | ip[1] = 0xFF; |
---|
575 | ip[2] = 0xFF; |
---|
576 | ip[3] = 0xFF; |
---|
577 | |
---|
578 | #ifdef _DHCP_DEBUG_ |
---|
579 | printf("\r\n> Send DHCP_DECLINE\r\n"); |
---|
580 | #endif |
---|
581 | |
---|
582 | sendto(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT); |
---|
583 | } |
---|
584 | |
---|
585 | /* PARSE REPLY pDHCPMSG */ |
---|
586 | int8_t parseDHCPMSG(void) |
---|
587 | { |
---|
588 | uint8_t svr_addr[6]; |
---|
589 | uint16_t svr_port; |
---|
590 | uint16_t len; |
---|
591 | |
---|
592 | uint8_t* p; |
---|
593 | uint8_t* e; |
---|
594 | uint8_t type = 0; |
---|
595 | uint8_t opt_len; |
---|
596 | |
---|
597 | if ((len = getSn_RX_RSR(DHCP_SOCKET)) > 0) |
---|
598 | { |
---|
599 | len = recvfrom(DHCP_SOCKET, (uint8_t *)pDHCPMSG, len, svr_addr, &svr_port); |
---|
600 | #ifdef _DHCP_DEBUG_ |
---|
601 | printf("DHCP message : %d.%d.%d.%d(%d) %d received. \r\n",svr_addr[0],svr_addr[1],svr_addr[2], svr_addr[3],svr_port, len); |
---|
602 | #endif |
---|
603 | } |
---|
604 | else return 0; |
---|
605 | |
---|
606 | if (svr_port == DHCP_SERVER_PORT) |
---|
607 | { // compare mac address |
---|
608 | if ( (pDHCPMSG->chaddr[0] != DHCP_CHADDR[0]) || (pDHCPMSG->chaddr[1] != DHCP_CHADDR[1]) || |
---|
609 | (pDHCPMSG->chaddr[2] != DHCP_CHADDR[2]) || (pDHCPMSG->chaddr[3] != DHCP_CHADDR[3]) || |
---|
610 | (pDHCPMSG->chaddr[4] != DHCP_CHADDR[4]) || (pDHCPMSG->chaddr[5] != DHCP_CHADDR[5]) ) |
---|
611 | { |
---|
612 | #ifdef _DHCP_DEBUG_ |
---|
613 | printf("No My DHCP Message. This message is ignored.\r\n"); |
---|
614 | #endif |
---|
615 | return 0; |
---|
616 | } |
---|
617 | |
---|
618 | //compare DHCP server ip address |
---|
619 | if ((DHCP_SIP[0]!=0) || (DHCP_SIP[1]!=0) || (DHCP_SIP[2]!=0) || (DHCP_SIP[3]!=0)) |
---|
620 | { |
---|
621 | if( ((svr_addr[0]!=DHCP_SIP[0])|| (svr_addr[1]!=DHCP_SIP[1])|| (svr_addr[2]!=DHCP_SIP[2])|| (svr_addr[3]!=DHCP_SIP[3])) && |
---|
622 | ((svr_addr[0]!=DHCP_REAL_SIP[0])|| (svr_addr[1]!=DHCP_REAL_SIP[1])|| (svr_addr[2]!=DHCP_REAL_SIP[2])|| (svr_addr[3]!=DHCP_REAL_SIP[3])) ) |
---|
623 | { |
---|
624 | #ifdef _DHCP_DEBUG_ |
---|
625 | printf("Another DHCP sever send a response message. This is ignored.\r\n"); |
---|
626 | #endif |
---|
627 | return 0; |
---|
628 | } |
---|
629 | } |
---|
630 | |
---|
631 | p = (uint8_t *)(&pDHCPMSG->op); |
---|
632 | p = p + 240; // 240 = sizeof(RIP_MSG) + MAGIC_COOKIE size in RIP_MSG.opt - sizeof(RIP_MSG.opt) |
---|
633 | e = p + (len - 240); |
---|
634 | |
---|
635 | while ( p < e ) |
---|
636 | { |
---|
637 | switch ( *p ) |
---|
638 | { |
---|
639 | case endOption : |
---|
640 | p = e; // for break while(p < e) |
---|
641 | break; |
---|
642 | case padOption : |
---|
643 | p++; |
---|
644 | break; |
---|
645 | case dhcpMessageType : |
---|
646 | p++; |
---|
647 | p++; |
---|
648 | type = *p++; |
---|
649 | break; |
---|
650 | case subnetMask : |
---|
651 | p++; |
---|
652 | p++; |
---|
653 | DHCP_allocated_sn[0] = *p++; |
---|
654 | DHCP_allocated_sn[1] = *p++; |
---|
655 | DHCP_allocated_sn[2] = *p++; |
---|
656 | DHCP_allocated_sn[3] = *p++; |
---|
657 | break; |
---|
658 | case routersOnSubnet : |
---|
659 | p++; |
---|
660 | opt_len = *p++; |
---|
661 | DHCP_allocated_gw[0] = *p++; |
---|
662 | DHCP_allocated_gw[1] = *p++; |
---|
663 | DHCP_allocated_gw[2] = *p++; |
---|
664 | DHCP_allocated_gw[3] = *p++; |
---|
665 | p = p + (opt_len - 4); |
---|
666 | break; |
---|
667 | case dns : |
---|
668 | p++; |
---|
669 | opt_len = *p++; |
---|
670 | DHCP_allocated_dns[0] = *p++; |
---|
671 | DHCP_allocated_dns[1] = *p++; |
---|
672 | DHCP_allocated_dns[2] = *p++; |
---|
673 | DHCP_allocated_dns[3] = *p++; |
---|
674 | p = p + (opt_len - 4); |
---|
675 | break; |
---|
676 | case dhcpIPaddrLeaseTime : |
---|
677 | p++; |
---|
678 | opt_len = *p++; |
---|
679 | dhcp_lease_time = *p++; |
---|
680 | dhcp_lease_time = (dhcp_lease_time << 8) + *p++; |
---|
681 | dhcp_lease_time = (dhcp_lease_time << 8) + *p++; |
---|
682 | dhcp_lease_time = (dhcp_lease_time << 8) + *p++; |
---|
683 | #ifdef _DHCP_DEBUG_ |
---|
684 | dhcp_lease_time = 10; |
---|
685 | #endif |
---|
686 | break; |
---|
687 | case dhcpServerIdentifier : |
---|
688 | p++; |
---|
689 | opt_len = *p++; |
---|
690 | DHCP_SIP[0] = *p++; |
---|
691 | DHCP_SIP[1] = *p++; |
---|
692 | DHCP_SIP[2] = *p++; |
---|
693 | DHCP_SIP[3] = *p++; |
---|
694 | DHCP_REAL_SIP[0]=svr_addr[0]; |
---|
695 | DHCP_REAL_SIP[1]=svr_addr[1]; |
---|
696 | DHCP_REAL_SIP[2]=svr_addr[2]; |
---|
697 | DHCP_REAL_SIP[3]=svr_addr[3]; |
---|
698 | break; |
---|
699 | default : |
---|
700 | p++; |
---|
701 | opt_len = *p++; |
---|
702 | p += opt_len; |
---|
703 | break; |
---|
704 | } // switch |
---|
705 | } // while |
---|
706 | } // if |
---|
707 | return type; |
---|
708 | } |
---|
709 | |
---|
710 | uint8_t DHCP_run(void) |
---|
711 | { |
---|
712 | uint8_t type; |
---|
713 | uint8_t ret; |
---|
714 | |
---|
715 | if (dhcp_state == STATE_DHCP_STOP) return DHCP_STOPPED; |
---|
716 | |
---|
717 | if (getSn_SR(DHCP_SOCKET) != SOCK_UDP) |
---|
718 | socket(DHCP_SOCKET, Sn_MR_UDP, DHCP_CLIENT_PORT, 0x00); |
---|
719 | |
---|
720 | ret = DHCP_RUNNING; |
---|
721 | type = parseDHCPMSG(); |
---|
722 | |
---|
723 | switch ( dhcp_state ) |
---|
724 | { |
---|
725 | case STATE_DHCP_INIT : |
---|
726 | DHCP_allocated_ip[0] = 0; |
---|
727 | DHCP_allocated_ip[1] = 0; |
---|
728 | DHCP_allocated_ip[2] = 0; |
---|
729 | DHCP_allocated_ip[3] = 0; |
---|
730 | send_DHCP_DISCOVER(); |
---|
731 | dhcp_state = STATE_DHCP_DISCOVER; |
---|
732 | break; |
---|
733 | case STATE_DHCP_DISCOVER : |
---|
734 | if (type == DHCP_OFFER) |
---|
735 | { |
---|
736 | #ifdef _DHCP_DEBUG_ |
---|
737 | printf("> Receive DHCP_OFFER\r\n"); |
---|
738 | #endif |
---|
739 | DHCP_allocated_ip[0] = pDHCPMSG->yiaddr[0]; |
---|
740 | DHCP_allocated_ip[1] = pDHCPMSG->yiaddr[1]; |
---|
741 | DHCP_allocated_ip[2] = pDHCPMSG->yiaddr[2]; |
---|
742 | DHCP_allocated_ip[3] = pDHCPMSG->yiaddr[3]; |
---|
743 | |
---|
744 | send_DHCP_REQUEST(); |
---|
745 | dhcp_state = STATE_DHCP_REQUEST; |
---|
746 | } |
---|
747 | else |
---|
748 | ret = check_DHCP_timeout(); |
---|
749 | break; |
---|
750 | |
---|
751 | case STATE_DHCP_REQUEST : |
---|
752 | if (type == DHCP_ACK) |
---|
753 | { |
---|
754 | #ifdef _DHCP_DEBUG_ |
---|
755 | printf("> Receive DHCP_ACK\r\n"); |
---|
756 | #endif |
---|
757 | if (check_DHCP_leasedIP()) |
---|
758 | { // Network info assignment from DHCP |
---|
759 | dhcp_ip_assign(); |
---|
760 | reset_DHCP_timeout(); |
---|
761 | |
---|
762 | dhcp_state = STATE_DHCP_LEASED; |
---|
763 | } |
---|
764 | else |
---|
765 | { // IP address conflict occurred |
---|
766 | reset_DHCP_timeout(); |
---|
767 | dhcp_ip_conflict(); |
---|
768 | dhcp_state = STATE_DHCP_INIT; |
---|
769 | } |
---|
770 | } |
---|
771 | else if (type == DHCP_NAK) |
---|
772 | { |
---|
773 | #ifdef _DHCP_DEBUG_ |
---|
774 | printf("> Receive DHCP_NACK\r\n"); |
---|
775 | #endif |
---|
776 | reset_DHCP_timeout(); |
---|
777 | |
---|
778 | dhcp_state = STATE_DHCP_DISCOVER; |
---|
779 | } |
---|
780 | else |
---|
781 | ret = check_DHCP_timeout(); |
---|
782 | break; |
---|
783 | |
---|
784 | case STATE_DHCP_LEASED : |
---|
785 | ret = DHCP_IP_LEASED; |
---|
786 | if ((dhcp_lease_time != INFINITE_LEASETIME) && ((dhcp_lease_time/2) < dhcp_tick_1s)) |
---|
787 | { |
---|
788 | #ifdef _DHCP_DEBUG_ |
---|
789 | printf("> Maintains the IP address \r\n"); |
---|
790 | #endif |
---|
791 | type = 0; |
---|
792 | OLD_allocated_ip[0] = DHCP_allocated_ip[0]; |
---|
793 | OLD_allocated_ip[1] = DHCP_allocated_ip[1]; |
---|
794 | OLD_allocated_ip[2] = DHCP_allocated_ip[2]; |
---|
795 | OLD_allocated_ip[3] = DHCP_allocated_ip[3]; |
---|
796 | |
---|
797 | DHCP_XID++; |
---|
798 | |
---|
799 | send_DHCP_REQUEST(); |
---|
800 | |
---|
801 | reset_DHCP_timeout(); |
---|
802 | |
---|
803 | dhcp_state = STATE_DHCP_REREQUEST; |
---|
804 | } |
---|
805 | break; |
---|
806 | |
---|
807 | case STATE_DHCP_REREQUEST : |
---|
808 | ret = DHCP_IP_LEASED; |
---|
809 | if (type == DHCP_ACK) |
---|
810 | { |
---|
811 | dhcp_retry_count = 0; |
---|
812 | if (OLD_allocated_ip[0] != DHCP_allocated_ip[0] || |
---|
813 | OLD_allocated_ip[1] != DHCP_allocated_ip[1] || |
---|
814 | OLD_allocated_ip[2] != DHCP_allocated_ip[2] || |
---|
815 | OLD_allocated_ip[3] != DHCP_allocated_ip[3]) |
---|
816 | { |
---|
817 | ret = DHCP_IP_CHANGED; |
---|
818 | dhcp_ip_update(); |
---|
819 | #ifdef _DHCP_DEBUG_ |
---|
820 | printf(">IP changed.\r\n"); |
---|
821 | #endif |
---|
822 | |
---|
823 | } |
---|
824 | #ifdef _DHCP_DEBUG_ |
---|
825 | else printf(">IP is continued.\r\n"); |
---|
826 | #endif |
---|
827 | reset_DHCP_timeout(); |
---|
828 | dhcp_state = STATE_DHCP_LEASED; |
---|
829 | } |
---|
830 | else if (type == DHCP_NAK) |
---|
831 | { |
---|
832 | #ifdef _DHCP_DEBUG_ |
---|
833 | printf("> Receive DHCP_NACK, Failed to maintain ip\r\n"); |
---|
834 | #endif |
---|
835 | reset_DHCP_timeout(); |
---|
836 | |
---|
837 | dhcp_state = STATE_DHCP_DISCOVER; |
---|
838 | } |
---|
839 | else |
---|
840 | ret = check_DHCP_timeout(); |
---|
841 | break; |
---|
842 | default : |
---|
843 | break; |
---|
844 | } |
---|
845 | |
---|
846 | return ret; |
---|
847 | } |
---|
848 | |
---|
849 | void DHCP_stop(void) |
---|
850 | { |
---|
851 | close(DHCP_SOCKET); |
---|
852 | dhcp_state = STATE_DHCP_STOP; |
---|
853 | } |
---|
854 | |
---|
855 | uint8_t check_DHCP_timeout(void) |
---|
856 | { |
---|
857 | uint8_t ret = DHCP_RUNNING; |
---|
858 | |
---|
859 | if (dhcp_retry_count < MAX_DHCP_RETRY) { |
---|
860 | if (dhcp_tick_next < dhcp_tick_1s) { |
---|
861 | |
---|
862 | switch ( dhcp_state ) { |
---|
863 | case STATE_DHCP_DISCOVER : |
---|
864 | // printf("<<timeout>> state : STATE_DHCP_DISCOVER\r\n"); |
---|
865 | send_DHCP_DISCOVER(); |
---|
866 | break; |
---|
867 | |
---|
868 | case STATE_DHCP_REQUEST : |
---|
869 | // printf("<<timeout>> state : STATE_DHCP_REQUEST\r\n"); |
---|
870 | |
---|
871 | send_DHCP_REQUEST(); |
---|
872 | break; |
---|
873 | |
---|
874 | case STATE_DHCP_REREQUEST : |
---|
875 | // printf("<<timeout>> state : STATE_DHCP_REREQUEST\r\n"); |
---|
876 | |
---|
877 | send_DHCP_REQUEST(); |
---|
878 | break; |
---|
879 | |
---|
880 | default : |
---|
881 | break; |
---|
882 | } |
---|
883 | |
---|
884 | dhcp_tick_1s = 0; |
---|
885 | dhcp_tick_next = dhcp_tick_1s + DHCP_WAIT_TIME; |
---|
886 | dhcp_retry_count++; |
---|
887 | } |
---|
888 | } else { // timeout occurred |
---|
889 | |
---|
890 | switch(dhcp_state) { |
---|
891 | case STATE_DHCP_DISCOVER: |
---|
892 | dhcp_state = STATE_DHCP_INIT; |
---|
893 | ret = DHCP_FAILED; |
---|
894 | break; |
---|
895 | case STATE_DHCP_REQUEST: |
---|
896 | case STATE_DHCP_REREQUEST: |
---|
897 | send_DHCP_DISCOVER(); |
---|
898 | dhcp_state = STATE_DHCP_DISCOVER; |
---|
899 | break; |
---|
900 | default : |
---|
901 | break; |
---|
902 | } |
---|
903 | reset_DHCP_timeout(); |
---|
904 | } |
---|
905 | return ret; |
---|
906 | } |
---|
907 | |
---|
908 | int8_t check_DHCP_leasedIP(void) |
---|
909 | { |
---|
910 | uint8_t tmp; |
---|
911 | int32_t ret; |
---|
912 | |
---|
913 | //WIZchip RCR value changed for ARP Timeout count control |
---|
914 | tmp = getRCR(); |
---|
915 | setRCR(0x03); |
---|
916 | |
---|
917 | // IP conflict detection : ARP request - ARP reply |
---|
918 | // Broadcasting ARP Request for check the IP conflict using UDP sendto() function |
---|
919 | ret = sendto(DHCP_SOCKET, (uint8_t *)"CHECK_IP_CONFLICT", 17, DHCP_allocated_ip, 5000); |
---|
920 | |
---|
921 | // RCR value restore |
---|
922 | setRCR(tmp); |
---|
923 | |
---|
924 | if(ret == SOCKERR_TIMEOUT) { |
---|
925 | // UDP send Timeout occurred : allocated IP address is unique, DHCP Success |
---|
926 | |
---|
927 | #ifdef _DHCP_DEBUG_ |
---|
928 | printf("\r\n> Check leased IP - OK\r\n"); |
---|
929 | #endif |
---|
930 | |
---|
931 | return 1; |
---|
932 | } else { |
---|
933 | // Received ARP reply or etc : IP address conflict occur, DHCP Failed |
---|
934 | send_DHCP_DECLINE(); |
---|
935 | |
---|
936 | ret = dhcp_tick_1s; |
---|
937 | while((dhcp_tick_1s - ret) < 2) ; // wait for 1s over; wait to complete to send DECLINE message; |
---|
938 | |
---|
939 | return 0; |
---|
940 | } |
---|
941 | } |
---|
942 | |
---|
943 | void DHCP_init(uint8_t s, uint8_t * buf) |
---|
944 | { |
---|
945 | uint8_t zeroip[4] = {0,0,0,0}; |
---|
946 | getSHAR(DHCP_CHADDR); |
---|
947 | if((DHCP_CHADDR[0] | DHCP_CHADDR[1] | DHCP_CHADDR[2] | DHCP_CHADDR[3] | DHCP_CHADDR[4] | DHCP_CHADDR[5]) == 0x00) |
---|
948 | { |
---|
949 | // assigning temporary mac address, you should be set SHAR before call this function. |
---|
950 | DHCP_CHADDR[0] = 0x00; |
---|
951 | DHCP_CHADDR[1] = 0x08; |
---|
952 | DHCP_CHADDR[2] = 0xdc; |
---|
953 | DHCP_CHADDR[3] = 0x00; |
---|
954 | DHCP_CHADDR[4] = 0x00; |
---|
955 | DHCP_CHADDR[5] = 0x00; |
---|
956 | setSHAR(DHCP_CHADDR); |
---|
957 | } |
---|
958 | |
---|
959 | DHCP_SOCKET = s; // SOCK_DHCP |
---|
960 | pDHCPMSG = (RIP_MSG*)buf; |
---|
961 | DHCP_XID = 0x12345678; |
---|
962 | { |
---|
963 | DHCP_XID += DHCP_CHADDR[3]; |
---|
964 | DHCP_XID += DHCP_CHADDR[4]; |
---|
965 | DHCP_XID += DHCP_CHADDR[5]; |
---|
966 | DHCP_XID += (DHCP_CHADDR[3] ^ DHCP_CHADDR[4] ^ DHCP_CHADDR[5]); |
---|
967 | } |
---|
968 | // WIZchip Netinfo Clear |
---|
969 | setSIPR(zeroip); |
---|
970 | setGAR(zeroip); |
---|
971 | |
---|
972 | reset_DHCP_timeout(); |
---|
973 | dhcp_state = STATE_DHCP_INIT; |
---|
974 | } |
---|
975 | |
---|
976 | |
---|
977 | /* Reset the DHCP timeout count and retry count. */ |
---|
978 | void reset_DHCP_timeout(void) |
---|
979 | { |
---|
980 | dhcp_tick_1s = 0; |
---|
981 | dhcp_tick_next = DHCP_WAIT_TIME; |
---|
982 | dhcp_retry_count = 0; |
---|
983 | } |
---|
984 | |
---|
985 | void DHCP_time_handler(void) |
---|
986 | { |
---|
987 | dhcp_tick_1s++; |
---|
988 | } |
---|
989 | |
---|
990 | void getIPfromDHCP(uint8_t* ip) |
---|
991 | { |
---|
992 | ip[0] = DHCP_allocated_ip[0]; |
---|
993 | ip[1] = DHCP_allocated_ip[1]; |
---|
994 | ip[2] = DHCP_allocated_ip[2]; |
---|
995 | ip[3] = DHCP_allocated_ip[3]; |
---|
996 | } |
---|
997 | |
---|
998 | void getGWfromDHCP(uint8_t* ip) |
---|
999 | { |
---|
1000 | ip[0] =DHCP_allocated_gw[0]; |
---|
1001 | ip[1] =DHCP_allocated_gw[1]; |
---|
1002 | ip[2] =DHCP_allocated_gw[2]; |
---|
1003 | ip[3] =DHCP_allocated_gw[3]; |
---|
1004 | } |
---|
1005 | |
---|
1006 | void getSNfromDHCP(uint8_t* ip) |
---|
1007 | { |
---|
1008 | ip[0] = DHCP_allocated_sn[0]; |
---|
1009 | ip[1] = DHCP_allocated_sn[1]; |
---|
1010 | ip[2] = DHCP_allocated_sn[2]; |
---|
1011 | ip[3] = DHCP_allocated_sn[3]; |
---|
1012 | } |
---|
1013 | |
---|
1014 | void getDNSfromDHCP(uint8_t* ip) |
---|
1015 | { |
---|
1016 | ip[0] = DHCP_allocated_dns[0]; |
---|
1017 | ip[1] = DHCP_allocated_dns[1]; |
---|
1018 | ip[2] = DHCP_allocated_dns[2]; |
---|
1019 | ip[3] = DHCP_allocated_dns[3]; |
---|
1020 | } |
---|
1021 | |
---|
1022 | uint32_t getDHCPLeasetime(void) |
---|
1023 | { |
---|
1024 | return dhcp_lease_time; |
---|
1025 | } |
---|
1026 | |
---|
1027 | char NibbleToHex(uint8_t nibble) |
---|
1028 | { |
---|
1029 | nibble &= 0x0F; |
---|
1030 | if (nibble <= 9) |
---|
1031 | return nibble + '0'; |
---|
1032 | else |
---|
1033 | return nibble + ('A'-0x0A); |
---|
1034 | } |
---|
1035 | |
---|
1036 | |
---|