summaryrefslogtreecommitdiff
path: root/drivers/wiznet5k/internet
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/wiznet5k/internet')
-rw-r--r--drivers/wiznet5k/internet/dhcp/dhcp.c978
-rw-r--r--drivers/wiznet5k/internet/dhcp/dhcp.h150
-rw-r--r--drivers/wiznet5k/internet/dns/dns.c566
-rw-r--r--drivers/wiznet5k/internet/dns/dns.h96
4 files changed, 1790 insertions, 0 deletions
diff --git a/drivers/wiznet5k/internet/dhcp/dhcp.c b/drivers/wiznet5k/internet/dhcp/dhcp.c
new file mode 100644
index 000000000..574758259
--- /dev/null
+++ b/drivers/wiznet5k/internet/dhcp/dhcp.c
@@ -0,0 +1,978 @@
+//*****************************************************************************
+//
+//! \file dhcp.c
+//! \brief DHCP APIs implement file.
+//! \details Processig DHCP protocol as DISCOVER, OFFER, REQUEST, ACK, NACK and DECLINE.
+//! \version 1.1.0
+//! \date 2013/11/18
+//! \par Revision history
+//! <2013/11/18> 1st Release
+//! <2012/12/20> V1.1.0
+//! 1. Optimize code
+//! 2. Add reg_dhcp_cbfunc()
+//! 3. Add DHCP_stop()
+//! 4. Integrate check_DHCP_state() & DHCP_run() to DHCP_run()
+//! 5. Don't care system endian
+//! 6. Add comments
+//! <2012/12/26> V1.1.1
+//! 1. Modify variable declaration: dhcp_tick_1s is declared volatile for code optimization
+//! \author Eric Jung & MidnightCow
+//! \copyright
+//!
+//! Copyright (c) 2013, WIZnet Co., LTD.
+//! All rights reserved.
+//!
+//! Redistribution and use in source and binary forms, with or without
+//! modification, are permitted provided that the following conditions
+//! are met:
+//!
+//! * Redistributions of source code must retain the above copyright
+//! notice, this list of conditions and the following disclaimer.
+//! * Redistributions in binary form must reproduce the above copyright
+//! notice, this list of conditions and the following disclaimer in the
+//! documentation and/or other materials provided with the distribution.
+//! * Neither the name of the <ORGANIZATION> nor the names of its
+//! contributors may be used to endorse or promote products derived
+//! from this software without specific prior written permission.
+//!
+//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+//! THE POSSIBILITY OF SUCH DAMAGE.
+//
+//*****************************************************************************
+
+//#include "Ethernet/socket.h"
+//#include "Internet/DHCP/dhcp.h"
+#include "../../Ethernet/socket.h"
+#include "dhcp.h"
+
+/* If you want to display debug & processing message, Define _DHCP_DEBUG_ in dhcp.h */
+
+#ifdef _DHCP_DEBUG_
+ #include <stdio.h>
+#endif
+
+/* DHCP state machine. */
+#define STATE_DHCP_INIT 0 ///< Initialize
+#define STATE_DHCP_DISCOVER 1 ///< send DISCOVER and wait OFFER
+#define STATE_DHCP_REQUEST 2 ///< send REQEUST and wait ACK or NACK
+#define STATE_DHCP_LEASED 3 ///< ReceiveD ACK and IP leased
+#define STATE_DHCP_REREQUEST 4 ///< send REQUEST for maintaining leased IP
+#define STATE_DHCP_RELEASE 5 ///< No use
+#define STATE_DHCP_STOP 6 ///< Stop processing DHCP
+
+#define DHCP_FLAGSBROADCAST 0x8000 ///< The broadcast value of flags in @ref RIP_MSG
+#define DHCP_FLAGSUNICAST 0x0000 ///< The unicast value of flags in @ref RIP_MSG
+
+/* DHCP message OP code */
+#define DHCP_BOOTREQUEST 1 ///< Request Message used in op of @ref RIP_MSG
+#define DHCP_BOOTREPLY 2 ///< Reply Message used i op of @ref RIP_MSG
+
+/* DHCP message type */
+#define DHCP_DISCOVER 1 ///< DISCOVER message in OPT of @ref RIP_MSG
+#define DHCP_OFFER 2 ///< OFFER message in OPT of @ref RIP_MSG
+#define DHCP_REQUEST 3 ///< REQUEST message in OPT of @ref RIP_MSG
+#define DHCP_DECLINE 4 ///< DECLINE message in OPT of @ref RIP_MSG
+#define DHCP_ACK 5 ///< ACK message in OPT of @ref RIP_MSG
+#define DHCP_NAK 6 ///< NACK message in OPT of @ref RIP_MSG
+#define DHCP_RELEASE 7 ///< RELEASE message in OPT of @ref RIP_MSG. No use
+#define DHCP_INFORM 8 ///< INFORM message in OPT of @ref RIP_MSG. No use
+
+#define DHCP_HTYPE10MB 1 ///< Used in type of @ref RIP_MSG
+#define DHCP_HTYPE100MB 2 ///< Used in type of @ref RIP_MSG
+
+#define DHCP_HLENETHERNET 6 ///< Used in hlen of @ref RIP_MSG
+#define DHCP_HOPS 0 ///< Used in hops of @ref RIP_MSG
+#define DHCP_SECS 0 ///< Used in secs of @ref RIP_MSG
+
+#define INFINITE_LEASETIME 0xffffffff ///< Infinite lease time
+
+#define OPT_SIZE 312 /// Max OPT size of @ref RIP_MSG
+#define RIP_MSG_SIZE (236+OPT_SIZE) /// Max size of @ref RIP_MSG
+
+/*
+ * @brief DHCP option and value (cf. RFC1533)
+ */
+enum
+{
+ padOption = 0,
+ subnetMask = 1,
+ timerOffset = 2,
+ routersOnSubnet = 3,
+ timeServer = 4,
+ nameServer = 5,
+ dns = 6,
+ logServer = 7,
+ cookieServer = 8,
+ lprServer = 9,
+ impressServer = 10,
+ resourceLocationServer = 11,
+ hostName = 12,
+ bootFileSize = 13,
+ meritDumpFile = 14,
+ domainName = 15,
+ swapServer = 16,
+ rootPath = 17,
+ extentionsPath = 18,
+ IPforwarding = 19,
+ nonLocalSourceRouting = 20,
+ policyFilter = 21,
+ maxDgramReasmSize = 22,
+ defaultIPTTL = 23,
+ pathMTUagingTimeout = 24,
+ pathMTUplateauTable = 25,
+ ifMTU = 26,
+ allSubnetsLocal = 27,
+ broadcastAddr = 28,
+ performMaskDiscovery = 29,
+ maskSupplier = 30,
+ performRouterDiscovery = 31,
+ routerSolicitationAddr = 32,
+ staticRoute = 33,
+ trailerEncapsulation = 34,
+ arpCacheTimeout = 35,
+ ethernetEncapsulation = 36,
+ tcpDefaultTTL = 37,
+ tcpKeepaliveInterval = 38,
+ tcpKeepaliveGarbage = 39,
+ nisDomainName = 40,
+ nisServers = 41,
+ ntpServers = 42,
+ vendorSpecificInfo = 43,
+ netBIOSnameServer = 44,
+ netBIOSdgramDistServer = 45,
+ netBIOSnodeType = 46,
+ netBIOSscope = 47,
+ xFontServer = 48,
+ xDisplayManager = 49,
+ dhcpRequestedIPaddr = 50,
+ dhcpIPaddrLeaseTime = 51,
+ dhcpOptionOverload = 52,
+ dhcpMessageType = 53,
+ dhcpServerIdentifier = 54,
+ dhcpParamRequest = 55,
+ dhcpMsg = 56,
+ dhcpMaxMsgSize = 57,
+ dhcpT1value = 58,
+ dhcpT2value = 59,
+ dhcpClassIdentifier = 60,
+ dhcpClientIdentifier = 61,
+ endOption = 255
+};
+
+/*
+ * @brief DHCP message format
+ */
+typedef struct {
+ uint8_t op; ///< @ref DHCP_BOOTREQUEST or @ref DHCP_BOOTREPLY
+ uint8_t htype; ///< @ref DHCP_HTYPE10MB or @ref DHCP_HTYPE100MB
+ uint8_t hlen; ///< @ref DHCP_HLENETHERNET
+ uint8_t hops; ///< @ref DHCP_HOPS
+ uint32_t xid; ///< @ref DHCP_XID This increase one every DHCP transaction.
+ uint16_t secs; ///< @ref DHCP_SECS
+ uint16_t flags; ///< @ref DHCP_FLAGSBROADCAST or @ref DHCP_FLAGSUNICAST
+ uint8_t ciaddr[4]; ///< @ref Request IP to DHCP sever
+ uint8_t yiaddr[4]; ///< @ref Offered IP from DHCP server
+ uint8_t siaddr[4]; ///< No use
+ uint8_t giaddr[4]; ///< No use
+ uint8_t chaddr[16]; ///< DHCP client 6bytes MAC address. Others is filled to zero
+ uint8_t sname[64]; ///< No use
+ uint8_t file[128]; ///< No use
+ uint8_t OPT[OPT_SIZE]; ///< Option
+} RIP_MSG;
+
+
+
+uint8_t DHCP_SOCKET; // Socket number for DHCP
+
+uint8_t DHCP_SIP[4]; // DHCP Server IP address
+
+// Network information from DHCP Server
+uint8_t OLD_allocated_ip[4] = {0, }; // Previous IP address
+uint8_t DHCP_allocated_ip[4] = {0, }; // IP address from DHCP
+uint8_t DHCP_allocated_gw[4] = {0, }; // Gateway address from DHCP
+uint8_t DHCP_allocated_sn[4] = {0, }; // Subnet mask from DHCP
+uint8_t DHCP_allocated_dns[4] = {0, }; // DNS address from DHCP
+
+
+int8_t dhcp_state = STATE_DHCP_INIT; // DHCP state
+int8_t dhcp_retry_count = 0;
+
+uint32_t dhcp_lease_time = INFINITE_LEASETIME;
+volatile uint32_t dhcp_tick_1s = 0; // unit 1 second
+uint32_t dhcp_tick_next = DHCP_WAIT_TIME ;
+
+uint32_t DHCP_XID; // Any number
+
+RIP_MSG* pDHCPMSG; // Buffer pointer for DHCP processing
+
+uint8_t HOST_NAME[] = DCHP_HOST_NAME;
+
+uint8_t DHCP_CHADDR[6]; // DHCP Client MAC address.
+
+/* The default callback function */
+void default_ip_assign(void);
+void default_ip_update(void);
+void default_ip_conflict(void);
+
+/* Callback handler */
+void (*dhcp_ip_assign)(void) = default_ip_assign; /* handler to be called when the IP address from DHCP server is first assigned */
+void (*dhcp_ip_update)(void) = default_ip_update; /* handler to be called when the IP address from DHCP server is updated */
+void (*dhcp_ip_conflict)(void) = default_ip_conflict; /* handler to be called when the IP address from DHCP server is conflict */
+
+void reg_dhcp_cbfunc(void(*ip_assign)(void), void(*ip_update)(void), void(*ip_conflict)(void));
+
+
+/* send DISCOVER message to DHCP server */
+void send_DHCP_DISCOVER(void);
+
+/* send REQEUST message to DHCP server */
+void send_DHCP_REQUEST(void);
+
+/* send DECLINE message to DHCP server */
+void send_DHCP_DECLINE(void);
+
+/* IP conflict check by sending ARP-request to leased IP and wait ARP-response. */
+int8_t check_DHCP_leasedIP(void);
+
+/* check the timeout in DHCP process */
+uint8_t check_DHCP_timeout(void);
+
+/* Intialize to timeout process. */
+void reset_DHCP_timeout(void);
+
+/* Parse message as OFFER and ACK and NACK from DHCP server.*/
+int8_t parseDHCPCMSG(void);
+
+/* The default handler of ip assign first */
+void default_ip_assign(void)
+{
+ setSIPR(DHCP_allocated_ip);
+ setSUBR(DHCP_allocated_sn);
+ setGAR (DHCP_allocated_gw);
+}
+
+/* The default handler of ip changed */
+void default_ip_update(void)
+{
+ /* WIZchip Software Reset */
+ setMR(MR_RST);
+ getMR(); // for delay
+ default_ip_assign();
+ setSHAR(DHCP_CHADDR);
+}
+
+/* The default handler of ip changed */
+void default_ip_conflict(void)
+{
+ // WIZchip Software Reset
+ setMR(MR_RST);
+ getMR(); // for delay
+ setSHAR(DHCP_CHADDR);
+}
+
+/* register the call back func. */
+void reg_dhcp_cbfunc(void(*ip_assign)(void), void(*ip_update)(void), void(*ip_conflict)(void))
+{
+ dhcp_ip_assign = default_ip_assign;
+ dhcp_ip_update = default_ip_update;
+ dhcp_ip_conflict = default_ip_conflict;
+ if(ip_assign) dhcp_ip_assign = ip_assign;
+ if(ip_update) dhcp_ip_update = ip_update;
+ if(ip_conflict) dhcp_ip_conflict = ip_conflict;
+}
+
+/* make the common DHCP message */
+void makeDHCPMSG(void)
+{
+ uint8_t bk_mac[6];
+ uint8_t* ptmp;
+ uint8_t i;
+ getSHAR(bk_mac);
+ pDHCPMSG->op = DHCP_BOOTREQUEST;
+ pDHCPMSG->htype = DHCP_HTYPE10MB;
+ pDHCPMSG->hlen = DHCP_HLENETHERNET;
+ pDHCPMSG->hops = DHCP_HOPS;
+ ptmp = (uint8_t*)(&pDHCPMSG->xid);
+ *(ptmp+0) = (uint8_t)((DHCP_XID & 0xFF000000) >> 24);
+ *(ptmp+1) = (uint8_t)((DHCP_XID & 0x00FF0000) >> 16);
+ *(ptmp+2) = (uint8_t)((DHCP_XID & 0x0000FF00) >> 8);
+ *(ptmp+3) = (uint8_t)((DHCP_XID & 0x000000FF) >> 0);
+ pDHCPMSG->secs = DHCP_SECS;
+ ptmp = (uint8_t*)(&pDHCPMSG->flags);
+ *(ptmp+0) = (uint8_t)((DHCP_FLAGSBROADCAST & 0xFF00) >> 8);
+ *(ptmp+1) = (uint8_t)((DHCP_FLAGSBROADCAST & 0x00FF) >> 0);
+
+ pDHCPMSG->ciaddr[0] = 0;
+ pDHCPMSG->ciaddr[1] = 0;
+ pDHCPMSG->ciaddr[2] = 0;
+ pDHCPMSG->ciaddr[3] = 0;
+
+ pDHCPMSG->yiaddr[0] = 0;
+ pDHCPMSG->yiaddr[1] = 0;
+ pDHCPMSG->yiaddr[2] = 0;
+ pDHCPMSG->yiaddr[3] = 0;
+
+ pDHCPMSG->siaddr[0] = 0;
+ pDHCPMSG->siaddr[1] = 0;
+ pDHCPMSG->siaddr[2] = 0;
+ pDHCPMSG->siaddr[3] = 0;
+
+ pDHCPMSG->giaddr[0] = 0;
+ pDHCPMSG->giaddr[1] = 0;
+ pDHCPMSG->giaddr[2] = 0;
+ pDHCPMSG->giaddr[3] = 0;
+
+ pDHCPMSG->chaddr[0] = DHCP_CHADDR[0];
+ pDHCPMSG->chaddr[1] = DHCP_CHADDR[1];
+ pDHCPMSG->chaddr[2] = DHCP_CHADDR[2];
+ pDHCPMSG->chaddr[3] = DHCP_CHADDR[3];
+ pDHCPMSG->chaddr[4] = DHCP_CHADDR[4];
+ pDHCPMSG->chaddr[5] = DHCP_CHADDR[5];
+
+ for (i = 6; i < 16; i++) pDHCPMSG->chaddr[i] = 0;
+ for (i = 0; i < 64; i++) pDHCPMSG->sname[i] = 0;
+ for (i = 0; i < 128; i++) pDHCPMSG->file[i] = 0;
+
+ // MAGIC_COOKIE
+ pDHCPMSG->OPT[0] = (uint8_t)((MAGIC_COOKIE & 0xFF000000) >> 24);
+ pDHCPMSG->OPT[1] = (uint8_t)((MAGIC_COOKIE & 0x00FF0000) >> 16);
+ pDHCPMSG->OPT[2] = (uint8_t)((MAGIC_COOKIE & 0x0000FF00) >> 8);
+ pDHCPMSG->OPT[3] = (uint8_t) (MAGIC_COOKIE & 0x000000FF) >> 0;
+}
+
+/* SEND DHCP DISCOVER */
+void send_DHCP_DISCOVER(void)
+{
+ uint16_t i;
+ uint8_t ip[4];
+ uint16_t k = 0;
+
+ makeDHCPMSG();
+
+ k = 4; // because MAGIC_COOKIE already made by makeDHCPMSG()
+
+ // Option Request Param
+ pDHCPMSG->OPT[k++] = dhcpMessageType;
+ pDHCPMSG->OPT[k++] = 0x01;
+ pDHCPMSG->OPT[k++] = DHCP_DISCOVER;
+
+ // Client identifier
+ pDHCPMSG->OPT[k++] = dhcpClientIdentifier;
+ pDHCPMSG->OPT[k++] = 0x07;
+ pDHCPMSG->OPT[k++] = 0x01;
+ pDHCPMSG->OPT[k++] = DHCP_CHADDR[0];
+ pDHCPMSG->OPT[k++] = DHCP_CHADDR[1];
+ pDHCPMSG->OPT[k++] = DHCP_CHADDR[2];
+ pDHCPMSG->OPT[k++] = DHCP_CHADDR[3];
+ pDHCPMSG->OPT[k++] = DHCP_CHADDR[4];
+ pDHCPMSG->OPT[k++] = DHCP_CHADDR[5];
+
+ // host name
+ pDHCPMSG->OPT[k++] = hostName;
+ pDHCPMSG->OPT[k++] = 0; // fill zero length of hostname
+ for(i = 0 ; HOST_NAME[i] != 0; i++)
+ pDHCPMSG->OPT[k++] = HOST_NAME[i];
+ pDHCPMSG->OPT[k++] = DHCP_CHADDR[3];
+ pDHCPMSG->OPT[k++] = DHCP_CHADDR[4];
+ pDHCPMSG->OPT[k++] = DHCP_CHADDR[5];
+ pDHCPMSG->OPT[k - (i+3+1)] = i+3; // length of hostname
+
+ pDHCPMSG->OPT[k++] = dhcpParamRequest;
+ pDHCPMSG->OPT[k++] = 0x06; // length of request
+ pDHCPMSG->OPT[k++] = subnetMask;
+ pDHCPMSG->OPT[k++] = routersOnSubnet;
+ pDHCPMSG->OPT[k++] = dns;
+ pDHCPMSG->OPT[k++] = domainName;
+ pDHCPMSG->OPT[k++] = dhcpT1value;
+ pDHCPMSG->OPT[k++] = dhcpT2value;
+ pDHCPMSG->OPT[k++] = endOption;
+
+ for (i = k; i < OPT_SIZE; i++) pDHCPMSG->OPT[i] = 0;
+
+ // send broadcasting packet
+ ip[0] = 255;
+ ip[1] = 255;
+ ip[2] = 255;
+ ip[3] = 255;
+
+#ifdef _DHCP_DEBUG_
+ printf("> Send DHCP_DISCOVER\r\n");
+#endif
+
+ sendto(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT);
+}
+
+/* SEND DHCP REQUEST */
+void send_DHCP_REQUEST(void)
+{
+ int i;
+ uint8_t ip[4];
+ uint16_t k = 0;
+
+ makeDHCPMSG();
+
+ if(dhcp_state == STATE_DHCP_LEASED || dhcp_state == STATE_DHCP_REREQUEST)
+ {
+ *((uint8_t*)(&pDHCPMSG->flags)) = ((DHCP_FLAGSUNICAST & 0xFF00)>> 8);
+ *((uint8_t*)(&pDHCPMSG->flags)+1) = (DHCP_FLAGSUNICAST & 0x00FF);
+ pDHCPMSG->ciaddr[0] = DHCP_allocated_ip[0];
+ pDHCPMSG->ciaddr[1] = DHCP_allocated_ip[1];
+ pDHCPMSG->ciaddr[2] = DHCP_allocated_ip[2];
+ pDHCPMSG->ciaddr[3] = DHCP_allocated_ip[3];
+ ip[0] = DHCP_SIP[0];
+ ip[1] = DHCP_SIP[1];
+ ip[2] = DHCP_SIP[2];
+ ip[3] = DHCP_SIP[3];
+ }
+ else
+ {
+ ip[0] = 255;
+ ip[1] = 255;
+ ip[2] = 255;
+ ip[3] = 255;
+ }
+
+ k = 4; // because MAGIC_COOKIE already made by makeDHCPMSG()
+
+ // Option Request Param.
+ pDHCPMSG->OPT[k++] = dhcpMessageType;
+ pDHCPMSG->OPT[k++] = 0x01;
+ pDHCPMSG->OPT[k++] = DHCP_REQUEST;
+
+ pDHCPMSG->OPT[k++] = dhcpClientIdentifier;
+ pDHCPMSG->OPT[k++] = 0x07;
+ pDHCPMSG->OPT[k++] = 0x01;
+ pDHCPMSG->OPT[k++] = DHCP_CHADDR[0];
+ pDHCPMSG->OPT[k++] = DHCP_CHADDR[1];
+ pDHCPMSG->OPT[k++] = DHCP_CHADDR[2];
+ pDHCPMSG->OPT[k++] = DHCP_CHADDR[3];
+ pDHCPMSG->OPT[k++] = DHCP_CHADDR[4];
+ pDHCPMSG->OPT[k++] = DHCP_CHADDR[5];
+
+ if(ip[3] == 255) // if(dchp_state == STATE_DHCP_LEASED || dchp_state == DHCP_REREQUEST_STATE)
+ {
+ pDHCPMSG->OPT[k++] = dhcpRequestedIPaddr;
+ pDHCPMSG->OPT[k++] = 0x04;
+ pDHCPMSG->OPT[k++] = DHCP_allocated_ip[0];
+ pDHCPMSG->OPT[k++] = DHCP_allocated_ip[1];
+ pDHCPMSG->OPT[k++] = DHCP_allocated_ip[2];
+ pDHCPMSG->OPT[k++] = DHCP_allocated_ip[3];
+
+ pDHCPMSG->OPT[k++] = dhcpServerIdentifier;
+ pDHCPMSG->OPT[k++] = 0x04;
+ pDHCPMSG->OPT[k++] = DHCP_SIP[0];
+ pDHCPMSG->OPT[k++] = DHCP_SIP[1];
+ pDHCPMSG->OPT[k++] = DHCP_SIP[2];
+ pDHCPMSG->OPT[k++] = DHCP_SIP[3];
+ }
+
+ // host name
+ pDHCPMSG->OPT[k++] = hostName;
+ pDHCPMSG->OPT[k++] = 0; // length of hostname
+ for(i = 0 ; HOST_NAME[i] != 0; i++)
+ pDHCPMSG->OPT[k++] = HOST_NAME[i];
+ pDHCPMSG->OPT[k++] = DHCP_CHADDR[3];
+ pDHCPMSG->OPT[k++] = DHCP_CHADDR[4];
+ pDHCPMSG->OPT[k++] = DHCP_CHADDR[5];
+ pDHCPMSG->OPT[k - (i+3+1)] = i+3; // length of hostname
+
+ pDHCPMSG->OPT[k++] = dhcpParamRequest;
+ pDHCPMSG->OPT[k++] = 0x08;
+ pDHCPMSG->OPT[k++] = subnetMask;
+ pDHCPMSG->OPT[k++] = routersOnSubnet;
+ pDHCPMSG->OPT[k++] = dns;
+ pDHCPMSG->OPT[k++] = domainName;
+ pDHCPMSG->OPT[k++] = dhcpT1value;
+ pDHCPMSG->OPT[k++] = dhcpT2value;
+ pDHCPMSG->OPT[k++] = performRouterDiscovery;
+ pDHCPMSG->OPT[k++] = staticRoute;
+ pDHCPMSG->OPT[k++] = endOption;
+
+ for (i = k; i < OPT_SIZE; i++) pDHCPMSG->OPT[i] = 0;
+
+#ifdef _DHCP_DEBUG_
+ printf("> Send DHCP_REQUEST\r\n");
+#endif
+
+ sendto(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT);
+
+}
+
+/* SEND DHCP DHCPDECLINE */
+void send_DHCP_DECLINE(void)
+{
+ int i;
+ uint8_t ip[4];
+ uint16_t k = 0;
+
+ makeDHCPMSG();
+
+ k = 4; // because MAGIC_COOKIE already made by makeDHCPMSG()
+
+ *((uint8_t*)(&pDHCPMSG->flags)) = ((DHCP_FLAGSUNICAST & 0xFF00)>> 8);
+ *((uint8_t*)(&pDHCPMSG->flags)+1) = (DHCP_FLAGSUNICAST & 0x00FF);
+
+ // Option Request Param.
+ pDHCPMSG->OPT[k++] = dhcpMessageType;
+ pDHCPMSG->OPT[k++] = 0x01;
+ pDHCPMSG->OPT[k++] = DHCP_DECLINE;
+
+ pDHCPMSG->OPT[k++] = dhcpClientIdentifier;
+ pDHCPMSG->OPT[k++] = 0x07;
+ pDHCPMSG->OPT[k++] = 0x01;
+ pDHCPMSG->OPT[k++] = DHCP_CHADDR[0];
+ pDHCPMSG->OPT[k++] = DHCP_CHADDR[1];
+ pDHCPMSG->OPT[k++] = DHCP_CHADDR[2];
+ pDHCPMSG->OPT[k++] = DHCP_CHADDR[3];
+ pDHCPMSG->OPT[k++] = DHCP_CHADDR[4];
+ pDHCPMSG->OPT[k++] = DHCP_CHADDR[5];
+
+ pDHCPMSG->OPT[k++] = dhcpRequestedIPaddr;
+ pDHCPMSG->OPT[k++] = 0x04;
+ pDHCPMSG->OPT[k++] = DHCP_allocated_ip[0];
+ pDHCPMSG->OPT[k++] = DHCP_allocated_ip[1];
+ pDHCPMSG->OPT[k++] = DHCP_allocated_ip[2];
+ pDHCPMSG->OPT[k++] = DHCP_allocated_ip[3];
+
+ pDHCPMSG->OPT[k++] = dhcpServerIdentifier;
+ pDHCPMSG->OPT[k++] = 0x04;
+ pDHCPMSG->OPT[k++] = DHCP_SIP[0];
+ pDHCPMSG->OPT[k++] = DHCP_SIP[1];
+ pDHCPMSG->OPT[k++] = DHCP_SIP[2];
+ pDHCPMSG->OPT[k++] = DHCP_SIP[3];
+
+ pDHCPMSG->OPT[k++] = endOption;
+
+ for (i = k; i < OPT_SIZE; i++) pDHCPMSG->OPT[i] = 0;
+
+ //send broadcasting packet
+ ip[0] = 0xFF;
+ ip[1] = 0xFF;
+ ip[2] = 0xFF;
+ ip[3] = 0xFF;
+
+#ifdef _DHCP_DEBUG_
+ printf("\r\n> Send DHCP_DECLINE\r\n");
+#endif
+
+ sendto(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT);
+}
+
+/* PARSE REPLY pDHCPMSG */
+int8_t parseDHCPMSG(void)
+{
+ uint8_t svr_addr[6];
+ uint16_t svr_port;
+ uint16_t len;
+
+ uint8_t * p;
+ uint8_t * e;
+ uint8_t type;
+ uint8_t opt_len;
+
+ if((len = getSn_RX_RSR(DHCP_SOCKET)) > 0)
+ {
+ len = recvfrom(DHCP_SOCKET, (uint8_t *)pDHCPMSG, len, svr_addr, &svr_port);
+ #ifdef _DHCP_DEBUG_
+ 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);
+ #endif
+ }
+ else return 0;
+ if (svr_port == DHCP_SERVER_PORT) {
+ // compare mac address
+ if ( (pDHCPMSG->chaddr[0] != DHCP_CHADDR[0]) || (pDHCPMSG->chaddr[1] != DHCP_CHADDR[1]) ||
+ (pDHCPMSG->chaddr[2] != DHCP_CHADDR[2]) || (pDHCPMSG->chaddr[3] != DHCP_CHADDR[3]) ||
+ (pDHCPMSG->chaddr[4] != DHCP_CHADDR[4]) || (pDHCPMSG->chaddr[5] != DHCP_CHADDR[5]) )
+ return 0;
+ type = 0;
+ p = (uint8_t *)(&pDHCPMSG->op);
+ p = p + 240; // 240 = sizeof(RIP_MSG) + MAGIC_COOKIE size in RIP_MSG.opt - sizeof(RIP_MSG.opt)
+ e = p + (len - 240);
+
+ while ( p < e ) {
+
+ switch ( *p ) {
+
+ case endOption :
+ p = e; // for break while(p < e)
+ break;
+ case padOption :
+ p++;
+ break;
+ case dhcpMessageType :
+ p++;
+ p++;
+ type = *p++;
+ break;
+ case subnetMask :
+ p++;
+ p++;
+ DHCP_allocated_sn[0] = *p++;
+ DHCP_allocated_sn[1] = *p++;
+ DHCP_allocated_sn[2] = *p++;
+ DHCP_allocated_sn[3] = *p++;
+ break;
+ case routersOnSubnet :
+ p++;
+ opt_len = *p++;
+ DHCP_allocated_gw[0] = *p++;
+ DHCP_allocated_gw[1] = *p++;
+ DHCP_allocated_gw[2] = *p++;
+ DHCP_allocated_gw[3] = *p++;
+ p = p + (opt_len - 4);
+ break;
+ case dns :
+ p++;
+ opt_len = *p++;
+ DHCP_allocated_dns[0] = *p++;
+ DHCP_allocated_dns[1] = *p++;
+ DHCP_allocated_dns[2] = *p++;
+ DHCP_allocated_dns[3] = *p++;
+ p = p + (opt_len - 4);
+ break;
+ case dhcpIPaddrLeaseTime :
+ p++;
+ opt_len = *p++;
+ dhcp_lease_time = *p++;
+ dhcp_lease_time = (dhcp_lease_time << 8) + *p++;
+ dhcp_lease_time = (dhcp_lease_time << 8) + *p++;
+ dhcp_lease_time = (dhcp_lease_time << 8) + *p++;
+ #ifdef _DHCP_DEBUG_
+ dhcp_lease_time = 10;
+ #endif
+ break;
+ case dhcpServerIdentifier :
+ p++;
+ opt_len = *p++;
+ DHCP_SIP[0] = *p++;
+ DHCP_SIP[1] = *p++;
+ DHCP_SIP[2] = *p++;
+ DHCP_SIP[3] = *p++;
+ break;
+ default :
+ p++;
+ opt_len = *p++;
+ p += opt_len;
+ break;
+ } // switch
+ } // while
+ } // if
+ return type;
+}
+
+uint8_t DHCP_run(void)
+{
+ uint8_t type;
+ uint8_t ret;
+
+ if(dhcp_state == STATE_DHCP_STOP) return DHCP_STOPPED;
+
+ if(getSn_SR(DHCP_SOCKET) != SOCK_UDP)
+ socket(DHCP_SOCKET, Sn_MR_UDP, DHCP_CLIENT_PORT, 0x00);
+
+ ret = DHCP_RUNNING;
+ type = parseDHCPMSG();
+
+ switch ( dhcp_state ) {
+ case STATE_DHCP_INIT :
+ DHCP_allocated_ip[0] = 0;
+ DHCP_allocated_ip[1] = 0;
+ DHCP_allocated_ip[2] = 0;
+ DHCP_allocated_ip[3] = 0;
+ send_DHCP_DISCOVER();
+ dhcp_state = STATE_DHCP_DISCOVER;
+ break;
+ case STATE_DHCP_DISCOVER :
+ if (type == DHCP_OFFER){
+#ifdef _DHCP_DEBUG_
+ printf("> Receive DHCP_OFFER\r\n");
+#endif
+ DHCP_allocated_ip[0] = pDHCPMSG->yiaddr[0];
+ DHCP_allocated_ip[1] = pDHCPMSG->yiaddr[1];
+ DHCP_allocated_ip[2] = pDHCPMSG->yiaddr[2];
+ DHCP_allocated_ip[3] = pDHCPMSG->yiaddr[3];
+
+ send_DHCP_REQUEST();
+ dhcp_state = STATE_DHCP_REQUEST;
+ } else ret = check_DHCP_timeout();
+ break;
+
+ case STATE_DHCP_REQUEST :
+ if (type == DHCP_ACK) {
+
+#ifdef _DHCP_DEBUG_
+ printf("> Receive DHCP_ACK\r\n");
+#endif
+ if (check_DHCP_leasedIP()) {
+ // Network info assignment from DHCP
+ dhcp_ip_assign();
+ reset_DHCP_timeout();
+
+ dhcp_state = STATE_DHCP_LEASED;
+ } else {
+ // IP address conflict occurred
+ reset_DHCP_timeout();
+ dhcp_ip_conflict();
+ dhcp_state = STATE_DHCP_INIT;
+ }
+ } else if (type == DHCP_NAK) {
+
+#ifdef _DHCP_DEBUG_
+ printf("> Receive DHCP_NACK\r\n");
+#endif
+
+ reset_DHCP_timeout();
+
+ dhcp_state = STATE_DHCP_DISCOVER;
+ } else ret = check_DHCP_timeout();
+ break;
+
+ case STATE_DHCP_LEASED :
+ ret = DHCP_IP_LEASED;
+ if ((dhcp_lease_time != INFINITE_LEASETIME) && ((dhcp_lease_time/2) < dhcp_tick_1s)) {
+
+#ifdef _DHCP_DEBUG_
+ printf("> Maintains the IP address \r\n");
+#endif
+
+ type = 0;
+ OLD_allocated_ip[0] = DHCP_allocated_ip[0];
+ OLD_allocated_ip[1] = DHCP_allocated_ip[1];
+ OLD_allocated_ip[2] = DHCP_allocated_ip[2];
+ OLD_allocated_ip[3] = DHCP_allocated_ip[3];
+
+ DHCP_XID++;
+
+ send_DHCP_REQUEST();
+
+ reset_DHCP_timeout();
+
+ dhcp_state = STATE_DHCP_REREQUEST;
+ }
+ break;
+
+ case STATE_DHCP_REREQUEST :
+ ret = DHCP_IP_LEASED;
+ if (type == DHCP_ACK) {
+ dhcp_retry_count = 0;
+ if (OLD_allocated_ip[0] != DHCP_allocated_ip[0] ||
+ OLD_allocated_ip[1] != DHCP_allocated_ip[1] ||
+ OLD_allocated_ip[2] != DHCP_allocated_ip[2] ||
+ OLD_allocated_ip[3] != DHCP_allocated_ip[3])
+ {
+ ret = DHCP_IP_CHANGED;
+ dhcp_ip_update();
+ #ifdef _DHCP_DEBUG_
+ printf(">IP changed.\r\n");
+ #endif
+
+ }
+ #ifdef _DHCP_DEBUG_
+ else printf(">IP is continued.\r\n");
+ #endif
+ reset_DHCP_timeout();
+ dhcp_state = STATE_DHCP_LEASED;
+ } else if (type == DHCP_NAK) {
+
+#ifdef _DHCP_DEBUG_
+ printf("> Receive DHCP_NACK, Failed to maintain ip\r\n");
+#endif
+
+ reset_DHCP_timeout();
+
+ dhcp_state = STATE_DHCP_DISCOVER;
+ } else ret = check_DHCP_timeout();
+ break;
+ default :
+ break;
+ }
+
+ return ret;
+}
+
+void DHCP_stop(void)
+{
+ close(DHCP_SOCKET);
+ dhcp_state = STATE_DHCP_STOP;
+}
+
+uint8_t check_DHCP_timeout(void)
+{
+ uint8_t ret = DHCP_RUNNING;
+
+ if (dhcp_retry_count < MAX_DHCP_RETRY) {
+ if (dhcp_tick_next < dhcp_tick_1s) {
+
+ switch ( dhcp_state ) {
+ case STATE_DHCP_DISCOVER :
+// printf("<<timeout>> state : STATE_DHCP_DISCOVER\r\n");
+ send_DHCP_DISCOVER();
+ break;
+
+ case STATE_DHCP_REQUEST :
+// printf("<<timeout>> state : STATE_DHCP_REQUEST\r\n");
+
+ send_DHCP_REQUEST();
+ break;
+
+ case STATE_DHCP_REREQUEST :
+// printf("<<timeout>> state : STATE_DHCP_REREQUEST\r\n");
+
+ send_DHCP_REQUEST();
+ break;
+
+ default :
+ break;
+ }
+
+ dhcp_tick_1s = 0;
+ dhcp_tick_next = dhcp_tick_1s + DHCP_WAIT_TIME;
+ dhcp_retry_count++;
+ }
+ } else { // timeout occurred
+
+ switch(dhcp_state) {
+ case STATE_DHCP_DISCOVER:
+ dhcp_state = STATE_DHCP_INIT;
+ ret = DHCP_FAILED;
+ break;
+ case STATE_DHCP_REQUEST:
+ case STATE_DHCP_REREQUEST:
+ send_DHCP_DISCOVER();
+ dhcp_state = STATE_DHCP_DISCOVER;
+ break;
+ default :
+ break;
+ }
+ reset_DHCP_timeout();
+ }
+ return ret;
+}
+
+int8_t check_DHCP_leasedIP(void)
+{
+ uint8_t tmp;
+ int32_t ret;
+
+ //WIZchip RCR value changed for ARP Timeout count control
+ tmp = getRCR();
+ setRCR(0x03);
+
+ // IP conflict detection : ARP request - ARP reply
+ // Broadcasting ARP Request for check the IP conflict using UDP sendto() function
+ ret = sendto(DHCP_SOCKET, (uint8_t *)"CHECK_IP_CONFLICT", 17, DHCP_allocated_ip, 5000);
+
+ // RCR value restore
+ setRCR(tmp);
+
+ if(ret == SOCKERR_TIMEOUT) {
+ // UDP send Timeout occurred : allocated IP address is unique, DHCP Success
+
+#ifdef _DHCP_DEBUG_
+ printf("\r\n> Check leased IP - OK\r\n");
+#endif
+
+ return 1;
+ } else {
+ // Received ARP reply or etc : IP address conflict occur, DHCP Failed
+ send_DHCP_DECLINE();
+
+ ret = dhcp_tick_1s;
+ while((dhcp_tick_1s - ret) < 2) ; // wait for 1s over; wait to complete to send DECLINE message;
+
+ return 0;
+ }
+}
+
+void DHCP_init(uint8_t s, uint8_t * buf)
+{
+ uint8_t zeroip[4] = {0,0,0,0};
+ getSHAR(DHCP_CHADDR);
+ if((DHCP_CHADDR[0] | DHCP_CHADDR[1] | DHCP_CHADDR[2] | DHCP_CHADDR[3] | DHCP_CHADDR[4] | DHCP_CHADDR[5]) == 0x00)
+ {
+ // assign temporary mac address, you should be set SHAR before call this function.
+ DHCP_CHADDR[0] = 0x00;
+ DHCP_CHADDR[1] = 0x08;
+ DHCP_CHADDR[2] = 0xdc;
+ DHCP_CHADDR[3] = 0x00;
+ DHCP_CHADDR[4] = 0x00;
+ DHCP_CHADDR[5] = 0x00;
+ setSHAR(DHCP_CHADDR);
+ }
+
+ DHCP_SOCKET = s; // SOCK_DHCP
+ pDHCPMSG = (RIP_MSG*)buf;
+ DHCP_XID = 0x12345678;
+
+ // WIZchip Netinfo Clear
+ setSIPR(zeroip);
+ setSIPR(zeroip);
+ setGAR(zeroip);
+
+ reset_DHCP_timeout();
+ dhcp_state = STATE_DHCP_INIT;
+}
+
+
+/* Rset the DHCP timeout count and retry count. */
+void reset_DHCP_timeout(void)
+{
+ dhcp_tick_1s = 0;
+ dhcp_tick_next = DHCP_WAIT_TIME;
+ dhcp_retry_count = 0;
+}
+
+void DHCP_time_handler(void)
+{
+ dhcp_tick_1s++;
+}
+
+void getIPfromDHCP(uint8_t* ip)
+{
+ ip[0] = DHCP_allocated_ip[0];
+ ip[1] = DHCP_allocated_ip[1];
+ ip[2] = DHCP_allocated_ip[2];
+ ip[3] = DHCP_allocated_ip[3];
+}
+
+void getGWfromDHCP(uint8_t* ip)
+{
+ ip[0] =DHCP_allocated_gw[0];
+ ip[1] =DHCP_allocated_gw[1];
+ ip[2] =DHCP_allocated_gw[2];
+ ip[3] =DHCP_allocated_gw[3];
+}
+
+void getSNfromDHCP(uint8_t* ip)
+{
+ ip[0] = DHCP_allocated_sn[0];
+ ip[1] = DHCP_allocated_sn[1];
+ ip[2] = DHCP_allocated_sn[2];
+ ip[3] = DHCP_allocated_sn[3];
+}
+
+void getDNSfromDHCP(uint8_t* ip)
+{
+ ip[0] = DHCP_allocated_dns[0];
+ ip[1] = DHCP_allocated_dns[1];
+ ip[2] = DHCP_allocated_dns[2];
+ ip[3] = DHCP_allocated_dns[3];
+}
+
+uint32_t getDHCPLeasetime(void)
+{
+ return dhcp_lease_time;
+}
+
+
+
+
diff --git a/drivers/wiznet5k/internet/dhcp/dhcp.h b/drivers/wiznet5k/internet/dhcp/dhcp.h
new file mode 100644
index 000000000..ee154d506
--- /dev/null
+++ b/drivers/wiznet5k/internet/dhcp/dhcp.h
@@ -0,0 +1,150 @@
+//*****************************************************************************
+//
+//! \file dhcp.h
+//! \brief DHCP APIs Header file.
+//! \details Processig DHCP protocol as DISCOVER, OFFER, REQUEST, ACK, NACK and DECLINE.
+//! \version 1.1.0
+//! \date 2013/11/18
+//! \par Revision history
+//! <2013/11/18> 1st Release
+//! <2012/12/20> V1.1.0
+//! 1. Move unreferenced DEFINE to dhcp.c
+//! <2012/12/26> V1.1.1
+//! \author Eric Jung & MidnightCow
+//! \copyright
+//!
+//! Copyright (c) 2013, WIZnet Co., LTD.
+//! All rights reserved.
+//!
+//! Redistribution and use in source and binary forms, with or without
+//! modification, are permitted provided that the following conditions
+//! are met:
+//!
+//! * Redistributions of source code must retain the above copyright
+//! notice, this list of conditions and the following disclaimer.
+//! * Redistributions in binary form must reproduce the above copyright
+//! notice, this list of conditions and the following disclaimer in the
+//! documentation and/or other materials provided with the distribution.
+//! * Neither the name of the <ORGANIZATION> nor the names of its
+//! contributors may be used to endorse or promote products derived
+//! from this software without specific prior written permission.
+//!
+//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+//! THE POSSIBILITY OF SUCH DAMAGE.
+//
+//*****************************************************************************
+#ifndef _DHCP_H_
+#define _DHCP_H_
+
+/*
+ * @brief
+ * @details If you want to display debug & processing message, Define _DHCP_DEBUG_
+ * @note If defined, it depends on <stdio.h>
+ */
+
+//#define _DHCP_DEBUG_
+
+/* Retry to processing DHCP */
+#define MAX_DHCP_RETRY 2 ///< Maximum retry count
+#define DHCP_WAIT_TIME 10 ///< Wait Time 10s
+
+/* UDP port numbers for DHCP */
+#define DHCP_SERVER_PORT 67 ///< DHCP server port number
+#define DHCP_CLIENT_PORT 68 ///< DHCP client port number
+
+#define MAGIC_COOKIE 0x63825363 ///< Any number. You can be modified it any number
+
+#define DCHP_HOST_NAME "WIZnet\0"
+
+/*
+ * @brief return value of @ref DHCP_run()
+ */
+enum
+{
+ DHCP_FAILED = 0, ///< Processing Fail
+ DHCP_RUNNING, ///< Processing DHCP protocol
+ DHCP_IP_ASSIGN, ///< First Occupy IP from DHPC server (if cbfunc == null, act as default default_ip_assign)
+ DHCP_IP_CHANGED, ///< Change IP address by new IP address from DHCP (if cbfunc == null, act as default default_ip_update)
+ DHCP_IP_LEASED, ///< Stand by
+ DHCP_STOPPED ///< Stop processing DHCP protocol
+};
+
+/*
+ * @brief DHCP client initialization (outside of the main loop)
+ * @param s - socket number
+ * @param buf - buffer for processing DHCP message
+ */
+void DHCP_init(uint8_t s, uint8_t * buf);
+
+/*
+ * @brief DHCP 1s Tick Timer handler
+ * @note SHOULD BE register to your system 1s Tick timer handler
+ */
+void DHCP_time_handler(void);
+
+/*
+ * @brief Register call back function
+ * @param ip_assign - callback func when IP is assigned from DHCP server first
+ * @param ip_update - callback func when IP is changed
+ * @prarm ip_conflict - callback func when the assigned IP is conflict with others.
+ */
+void reg_dhcp_cbfunc(void(*ip_assign)(void), void(*ip_update)(void), void(*ip_conflict)(void));
+
+/*
+ * @brief DHCP client in the main loop
+ * @return The value is as the follow \n
+ * @ref DHCP_FAILED \n
+ * @ref DHCP_RUNNING \n
+ * @ref DHCP_IP_ASSIGN \n
+ * @ref DHCP_IP_CHANGED \n
+ * @ref DHCP_IP_LEASED \n
+ * @ref DHCP_STOPPED \n
+ *
+ * @note This function is always called by you main task.
+ */
+uint8_t DHCP_run(void);
+
+/*
+ * @brief Stop DHCP processing
+ * @note If you want to restart. call DHCP_init() and DHCP_run()
+ */
+void DHCP_stop(void);
+
+/* Get Network information assigned from DHCP server */
+/*
+ * @brief Get IP address
+ * @param ip - IP address to be returned
+ */
+void getIPfromDHCP(uint8_t* ip);
+/*
+ * @brief Get Gateway address
+ * @param ip - Gateway address to be returned
+ */
+void getGWfromDHCP(uint8_t* ip);
+/*
+ * @brief Get Subnet mask value
+ * @param ip - Subnet mask to be returned
+ */
+void getSNfromDHCP(uint8_t* ip);
+/*
+ * @brief Get DNS address
+ * @param ip - DNS address to be returned
+ */
+void getDNSfromDHCP(uint8_t* ip);
+
+/*
+ * @brief Get the leased time by DHCP sever
+ * @return unit 1s
+ */
+uint32_t getDHCPLeasetime(void);
+
+#endif /* _DHCP_H_ */
diff --git a/drivers/wiznet5k/internet/dns/dns.c b/drivers/wiznet5k/internet/dns/dns.c
new file mode 100644
index 000000000..48f486e0b
--- /dev/null
+++ b/drivers/wiznet5k/internet/dns/dns.c
@@ -0,0 +1,566 @@
+//*****************************************************************************
+//
+//! \file dns.c
+//! \brief DNS APIs Implement file.
+//! \details Send DNS query & Receive DNS reponse. \n
+//! It depends on stdlib.h & string.h in ansi-c library
+//! \version 1.1.0
+//! \date 2013/11/18
+//! \par Revision history
+//! <2013/10/21> 1st Release
+//! <2013/12/20> V1.1.0
+//! 1. Remove secondary DNS server in DNS_run
+//! If 1st DNS_run failed, call DNS_run with 2nd DNS again
+//! 2. DNS_timerHandler -> DNS_time_handler
+//! 3. Remove the unused define
+//! 4. Integrated dns.h dns.c & dns_parse.h dns_parse.c into dns.h & dns.c
+//! <2013/12/20> V1.1.0
+//!
+//! \author Eric Jung & MidnightCow
+//! \copyright
+//!
+//! Copyright (c) 2013, WIZnet Co., LTD.
+//! All rights reserved.
+//!
+//! Redistribution and use in source and binary forms, with or without
+//! modification, are permitted provided that the following conditions
+//! are met:
+//!
+//! * Redistributions of source code must retain the above copyright
+//! notice, this list of conditions and the following disclaimer.
+//! * Redistributions in binary form must reproduce the above copyright
+//! notice, this list of conditions and the following disclaimer in the
+//! documentation and/or other materials provided with the distribution.
+//! * Neither the name of the <ORGANIZATION> nor the names of its
+//! contributors may be used to endorse or promote products derived
+//! from this software without specific prior written permission.
+//!
+//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+//! THE POSSIBILITY OF SUCH DAMAGE.
+//
+//*****************************************************************************
+
+#include <string.h>
+#include <stdlib.h>
+
+//#include "Ethernet/socket.h"
+//#include "Internet/DNS/dns.h"
+#include "../../ethernet/socket.h"
+#include "dns.h"
+
+#ifdef _DNS_DEBUG_
+ #include <stdio.h>
+#endif
+
+#define INITRTT 2000L /* Initial smoothed response time */
+#define MAXCNAME (MAX_DOMAIN_NAME + (MAX_DOMAIN_NAME>>1)) /* Maximum amount of cname recursion */
+
+#define TYPE_A 1 /* Host address */
+#define TYPE_NS 2 /* Name server */
+#define TYPE_MD 3 /* Mail destination (obsolete) */
+#define TYPE_MF 4 /* Mail forwarder (obsolete) */
+#define TYPE_CNAME 5 /* Canonical name */
+#define TYPE_SOA 6 /* Start of Authority */
+#define TYPE_MB 7 /* Mailbox name (experimental) */
+#define TYPE_MG 8 /* Mail group member (experimental) */
+#define TYPE_MR 9 /* Mail rename name (experimental) */
+#define TYPE_NULL 10 /* Null (experimental) */
+#define TYPE_WKS 11 /* Well-known sockets */
+#define TYPE_PTR 12 /* Pointer record */
+#define TYPE_HINFO 13 /* Host information */
+#define TYPE_MINFO 14 /* Mailbox information (experimental)*/
+#define TYPE_MX 15 /* Mail exchanger */
+#define TYPE_TXT 16 /* Text strings */
+#define TYPE_ANY 255 /* Matches any type */
+
+#define CLASS_IN 1 /* The ARPA Internet */
+
+/* Round trip timing parameters */
+#define AGAIN 8 /* Average RTT gain = 1/8 */
+#define LAGAIN 3 /* Log2(AGAIN) */
+#define DGAIN 4 /* Mean deviation gain = 1/4 */
+#define LDGAIN 2 /* log2(DGAIN) */
+
+/* Header for all domain messages */
+struct dhdr
+{
+ uint16_t id; /* Identification */
+ uint8_t qr; /* Query/Response */
+#define QUERY 0
+#define RESPONSE 1
+ uint8_t opcode;
+#define IQUERY 1
+ uint8_t aa; /* Authoratative answer */
+ uint8_t tc; /* Truncation */
+ uint8_t rd; /* Recursion desired */
+ uint8_t ra; /* Recursion available */
+ uint8_t rcode; /* Response code */
+#define NO_ERROR 0
+#define FORMAT_ERROR 1
+#define SERVER_FAIL 2
+#define NAME_ERROR 3
+#define NOT_IMPL 4
+#define REFUSED 5
+ uint16_t qdcount; /* Question count */
+ uint16_t ancount; /* Answer count */
+ uint16_t nscount; /* Authority (name server) count */
+ uint16_t arcount; /* Additional record count */
+};
+
+
+uint8_t* pDNSMSG; // DNS message buffer
+uint8_t DNS_SOCKET; // SOCKET number for DNS
+uint16_t DNS_MSGID; // DNS message ID
+
+extern uint32_t HAL_GetTick(void);
+uint32_t hal_sys_tick;
+
+/* converts uint16_t from network buffer to a host byte order integer. */
+uint16_t get16(uint8_t * s)
+{
+ uint16_t i;
+ i = *s++ << 8;
+ i = i + *s;
+ return i;
+}
+
+/* copies uint16_t to the network buffer with network byte order. */
+uint8_t * put16(uint8_t * s, uint16_t i)
+{
+ *s++ = i >> 8;
+ *s++ = i;
+ return s;
+}
+
+
+/*
+ * CONVERT A DOMAIN NAME TO THE HUMAN-READABLE FORM
+ *
+ * Description : This function converts a compressed domain name to the human-readable form
+ * Arguments : msg - is a pointer to the reply message
+ * compressed - is a pointer to the domain name in reply message.
+ * buf - is a pointer to the buffer for the human-readable form name.
+ * len - is the MAX. size of buffer.
+ * Returns : the length of compressed message
+ */
+int parse_name(uint8_t * msg, uint8_t * compressed, char * buf, int16_t len)
+{
+ uint16_t slen; /* Length of current segment */
+ uint8_t * cp;
+ int clen = 0; /* Total length of compressed name */
+ int indirect = 0; /* Set if indirection encountered */
+ int nseg = 0; /* Total number of segments in name */
+
+ cp = compressed;
+
+ for (;;)
+ {
+ slen = *cp++; /* Length of this segment */
+
+ if (!indirect) clen++;
+
+ if ((slen & 0xc0) == 0xc0)
+ {
+ if (!indirect)
+ clen++;
+ indirect = 1;
+ /* Follow indirection */
+ cp = &msg[((slen & 0x3f)<<8) + *cp];
+ slen = *cp++;
+ }
+
+ if (slen == 0) /* zero length == all done */
+ break;
+
+ len -= slen + 1;
+
+ if (len < 0) return -1;
+
+ if (!indirect) clen += slen;
+
+ while (slen-- != 0) *buf++ = (char)*cp++;
+ *buf++ = '.';
+ nseg++;
+ }
+
+ if (nseg == 0)
+ {
+ /* Root name; represent as single dot */
+ *buf++ = '.';
+ len--;
+ }
+
+ *buf++ = '\0';
+ len--;
+
+ return clen; /* Length of compressed message */
+}
+
+/*
+ * PARSE QUESTION SECTION
+ *
+ * Description : This function parses the question record of the reply message.
+ * Arguments : msg - is a pointer to the reply message
+ * cp - is a pointer to the question record.
+ * Returns : a pointer the to next record.
+ */
+uint8_t * dns_question(uint8_t * msg, uint8_t * cp)
+{
+ int len;
+ char name[MAXCNAME];
+
+ len = parse_name(msg, cp, name, MAXCNAME);
+
+
+ if (len == -1) return 0;
+
+ cp += len;
+ cp += 2; /* type */
+ cp += 2; /* class */
+
+ return cp;
+}
+
+
+/*
+ * PARSE ANSER SECTION
+ *
+ * Description : This function parses the answer record of the reply message.
+ * Arguments : msg - is a pointer to the reply message
+ * cp - is a pointer to the answer record.
+ * Returns : a pointer the to next record.
+ */
+uint8_t * dns_answer(uint8_t * msg, uint8_t * cp, uint8_t * ip_from_dns)
+{
+ int len, type;
+ char name[MAXCNAME];
+
+ len = parse_name(msg, cp, name, MAXCNAME);
+
+ if (len == -1) return 0;
+
+ cp += len;
+ type = get16(cp);
+ cp += 2; /* type */
+ cp += 2; /* class */
+ cp += 4; /* ttl */
+ cp += 2; /* len */
+
+
+ switch (type)
+ {
+ case TYPE_A:
+ /* Just read the address directly into the structure */
+ ip_from_dns[0] = *cp++;
+ ip_from_dns[1] = *cp++;
+ ip_from_dns[2] = *cp++;
+ ip_from_dns[3] = *cp++;
+ break;
+ case TYPE_CNAME:
+ case TYPE_MB:
+ case TYPE_MG:
+ case TYPE_MR:
+ case TYPE_NS:
+ case TYPE_PTR:
+ /* These types all consist of a single domain name */
+ /* convert it to ASCII format */
+ len = parse_name(msg, cp, name, MAXCNAME);
+ if (len == -1) return 0;
+
+ cp += len;
+ break;
+ case TYPE_HINFO:
+ len = *cp++;
+ cp += len;
+
+ len = *cp++;
+ cp += len;
+ break;
+ case TYPE_MX:
+ cp += 2;
+ /* Get domain name of exchanger */
+ len = parse_name(msg, cp, name, MAXCNAME);
+ if (len == -1) return 0;
+
+ cp += len;
+ break;
+ case TYPE_SOA:
+ /* Get domain name of name server */
+ len = parse_name(msg, cp, name, MAXCNAME);
+ if (len == -1) return 0;
+
+ cp += len;
+
+ /* Get domain name of responsible person */
+ len = parse_name(msg, cp, name, MAXCNAME);
+ if (len == -1) return 0;
+
+ cp += len;
+
+ cp += 4;
+ cp += 4;
+ cp += 4;
+ cp += 4;
+ cp += 4;
+ break;
+ case TYPE_TXT:
+ /* Just stash */
+ break;
+ default:
+ /* Ignore */
+ break;
+ }
+
+ return cp;
+}
+
+/*
+ * PARSE THE DNS REPLY
+ *
+ * Description : This function parses the reply message from DNS server.
+ * Arguments : dhdr - is a pointer to the header for DNS message
+ * buf - is a pointer to the reply message.
+ * len - is the size of reply message.
+ * Returns : -1 - Domain name length is too big
+ * 0 - Fail (Timeout or parse error)
+ * 1 - Success,
+ */
+int8_t parseDNSMSG(struct dhdr * pdhdr, uint8_t * pbuf, uint8_t * ip_from_dns)
+{
+ uint16_t tmp;
+ uint16_t i;
+ uint8_t * msg;
+ uint8_t * cp;
+
+ msg = pbuf;
+ memset(pdhdr, 0, sizeof(*pdhdr));
+
+ pdhdr->id = get16(&msg[0]);
+ tmp = get16(&msg[2]);
+ if (tmp & 0x8000) pdhdr->qr = 1;
+
+ pdhdr->opcode = (tmp >> 11) & 0xf;
+
+ if (tmp & 0x0400) pdhdr->aa = 1;
+ if (tmp & 0x0200) pdhdr->tc = 1;
+ if (tmp & 0x0100) pdhdr->rd = 1;
+ if (tmp & 0x0080) pdhdr->ra = 1;
+
+ pdhdr->rcode = tmp & 0xf;
+ pdhdr->qdcount = get16(&msg[4]);
+ pdhdr->ancount = get16(&msg[6]);
+ pdhdr->nscount = get16(&msg[8]);
+ pdhdr->arcount = get16(&msg[10]);
+
+
+ /* Now parse the variable length sections */
+ cp = &msg[12];
+
+ /* Question section */
+ for (i = 0; i < pdhdr->qdcount; i++)
+ {
+ cp = dns_question(msg, cp);
+ if(!cp)
+ {
+#ifdef _DNS_DEBUG_
+ printf("MAX_DOMAIN_NAME is too small, it should be redefined in dns.h\r\n");
+#endif
+ return -1;
+ }
+ }
+
+ /* Answer section */
+ for (i = 0; i < pdhdr->ancount; i++)
+ {
+ cp = dns_answer(msg, cp, ip_from_dns);
+ if(!cp)
+ {
+#ifdef _DNS_DEBUG_
+ printf("MAX_DOMAIN_NAME is too small, it should be redefined in dns.h\r\n");
+#endif
+ return -1;
+ }
+
+ }
+
+ /* Name server (authority) section */
+ for (i = 0; i < pdhdr->nscount; i++)
+ {
+ ;
+ }
+
+ /* Additional section */
+ for (i = 0; i < pdhdr->arcount; i++)
+ {
+ ;
+ }
+
+ if(pdhdr->rcode == 0) return 1; // No error
+ else return 0;
+}
+
+
+/*
+ * MAKE DNS QUERY MESSAGE
+ *
+ * Description : This function makes DNS query message.
+ * Arguments : op - Recursion desired
+ * name - is a pointer to the domain name.
+ * buf - is a pointer to the buffer for DNS message.
+ * len - is the MAX. size of buffer.
+ * Returns : the pointer to the DNS message.
+ */
+int16_t dns_makequery(uint16_t op, char * name, uint8_t * buf, uint16_t len)
+{
+ uint8_t *cp;
+ char *cp1;
+ char sname[MAXCNAME];
+ char *dname;
+ uint16_t p;
+ uint16_t dlen;
+
+ cp = buf;
+
+ DNS_MSGID++;
+ cp = put16(cp, DNS_MSGID);
+ p = (op << 11) | 0x0100; /* Recursion desired */
+ cp = put16(cp, p);
+ cp = put16(cp, 1);
+ cp = put16(cp, 0);
+ cp = put16(cp, 0);
+ cp = put16(cp, 0);
+
+ strcpy(sname, name);
+ dname = sname;
+ dlen = strlen(dname);
+ for (;;)
+ {
+ /* Look for next dot */
+ cp1 = strchr(dname, '.');
+
+ if (cp1 != NULL) len = cp1 - dname; /* More to come */
+ else len = dlen; /* Last component */
+
+ *cp++ = len; /* Write length of component */
+ if (len == 0) break;
+
+ /* Copy component up to (but not including) dot */
+ memcpy(cp, dname, len);
+ cp += len;
+ if (cp1 == NULL)
+ {
+ *cp++ = 0; /* Last one; write null and finish */
+ break;
+ }
+ dname += len+1;
+ dlen -= len+1;
+ }
+
+ cp = put16(cp, 0x0001); /* type */
+ cp = put16(cp, 0x0001); /* class */
+
+ return ((int16_t)((uint32_t)(cp) - (uint32_t)(buf)));
+}
+
+/*
+ * CHECK DNS TIMEOUT
+ *
+ * Description : This function check the DNS timeout
+ * Arguments : None.
+ * Returns : -1 - timeout occurred, 0 - timer over, but no timeout, 1 - no timer over, no timeout occur
+ * Note : timeout : retry count and timer both over.
+ */
+
+int8_t check_DNS_timeout(void)
+{
+ static uint8_t retry_count;
+
+ uint32_t tick = HAL_GetTick();
+ if(tick - hal_sys_tick >= DNS_WAIT_TIME * 1000)
+ {
+ hal_sys_tick = tick;
+ if(retry_count >= MAX_DNS_RETRY) {
+ retry_count = 0;
+ return -1; // timeout occurred
+ }
+ retry_count++;
+ return 0; // timer over, but no timeout
+ }
+
+ return 1; // no timer over, no timeout occur
+}
+
+
+
+/* DNS CLIENT INIT */
+void DNS_init(uint8_t s, uint8_t * buf)
+{
+ DNS_SOCKET = s; // SOCK_DNS
+ pDNSMSG = buf; // User's shared buffer
+ DNS_MSGID = DNS_MSG_ID;
+}
+
+/* DNS CLIENT RUN */
+int8_t DNS_run(uint8_t * dns_ip, uint8_t * name, uint8_t * ip_from_dns)
+{
+ int8_t ret;
+ struct dhdr dhp;
+ uint8_t ip[4];
+ uint16_t len, port;
+ int8_t ret_check_timeout;
+
+ hal_sys_tick = HAL_GetTick();
+
+ // Socket open
+ socket(DNS_SOCKET, Sn_MR_UDP, 0, 0);
+
+#ifdef _DNS_DEBUG_
+ printf("> DNS Query to DNS Server : %d.%d.%d.%d\r\n", dns_ip[0], dns_ip[1], dns_ip[2], dns_ip[3]);
+#endif
+
+ len = dns_makequery(0, (char *)name, pDNSMSG, MAX_DNS_BUF_SIZE);
+ sendto(DNS_SOCKET, pDNSMSG, len, dns_ip, IPPORT_DOMAIN);
+
+ while (1)
+ {
+ if ((len = getSn_RX_RSR(DNS_SOCKET)) > 0)
+ {
+ if (len > MAX_DNS_BUF_SIZE) len = MAX_DNS_BUF_SIZE;
+ len = recvfrom(DNS_SOCKET, pDNSMSG, len, ip, &port);
+ #ifdef _DNS_DEBUG_
+ printf("> Receive DNS message from %d.%d.%d.%d(%d). len = %d\r\n", ip[0], ip[1], ip[2], ip[3],port,len);
+ #endif
+ ret = parseDNSMSG(&dhp, pDNSMSG, ip_from_dns);
+ break;
+ }
+ // Check Timeout
+ ret_check_timeout = check_DNS_timeout();
+ if (ret_check_timeout < 0) {
+
+#ifdef _DNS_DEBUG_
+ printf("> DNS Server is not responding : %d.%d.%d.%d\r\n", dns_ip[0], dns_ip[1], dns_ip[2], dns_ip[3]);
+#endif
+ return 0; // timeout occurred
+ }
+ else if (ret_check_timeout == 0) {
+
+#ifdef _DNS_DEBUG_
+ printf("> DNS Timeout\r\n");
+#endif
+ sendto(DNS_SOCKET, pDNSMSG, len, dns_ip, IPPORT_DOMAIN);
+ }
+ }
+ close(DNS_SOCKET);
+ // Return value
+ // 0 > : failed / 1 - success
+ return ret;
+}
diff --git a/drivers/wiznet5k/internet/dns/dns.h b/drivers/wiznet5k/internet/dns/dns.h
new file mode 100644
index 000000000..de0039515
--- /dev/null
+++ b/drivers/wiznet5k/internet/dns/dns.h
@@ -0,0 +1,96 @@
+//*****************************************************************************
+//
+//! \file dns.h
+//! \brief DNS APIs Header file.
+//! \details Send DNS query & Receive DNS reponse.
+//! \version 1.1.0
+//! \date 2013/11/18
+//! \par Revision history
+//! <2013/10/21> 1st Release
+//! <2013/12/20> V1.1.0
+//! 1. Remove secondary DNS server in DNS_run
+//! If 1st DNS_run failed, call DNS_run with 2nd DNS again
+//! 2. DNS_timerHandler -> DNS_time_handler
+//! 3. Move the no reference define to dns.c
+//! 4. Integrated dns.h dns.c & dns_parse.h dns_parse.c into dns.h & dns.c
+//! <2013/12/20> V1.1.0
+//!
+//! \author Eric Jung & MidnightCow
+//! \copyright
+//!
+//! Copyright (c) 2013, WIZnet Co., LTD.
+//! All rights reserved.
+//!
+//! Redistribution and use in source and binary forms, with or without
+//! modification, are permitted provided that the following conditions
+//! are met:
+//!
+//! * Redistributions of source code must retain the above copyright
+//! notice, this list of conditions and the following disclaimer.
+//! * Redistributions in binary form must reproduce the above copyright
+//! notice, this list of conditions and the following disclaimer in the
+//! documentation and/or other materials provided with the distribution.
+//! * Neither the name of the <ORGANIZATION> nor the names of its
+//! contributors may be used to endorse or promote products derived
+//! from this software without specific prior written permission.
+//!
+//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+//! THE POSSIBILITY OF SUCH DAMAGE.
+//
+//*****************************************************************************
+
+#ifndef _DNS_H_
+#define _DNS_H_
+
+#include <stdint.h>
+/*
+ * @brief Define it for Debug & Monitor DNS processing.
+ * @note If defined, it depends on <stdio.h>
+ */
+
+//#define _DNS_DEBUG_
+
+#define MAX_DNS_BUF_SIZE 256 ///< maximum size of DNS buffer. */
+/*
+ * @brief Maximum length of your queried Domain name
+ * @todo SHOULD BE defined it equal as or greater than your Domain name length + null character(1)
+ * @note SHOULD BE careful to stack overflow because it is allocated 1.5 times as MAX_DOMAIN_NAME in stack.
+ */
+#define MAX_DOMAIN_NAME 32 // for example "www.google.com"
+
+#define MAX_DNS_RETRY 2 ///< Requery Count
+#define DNS_WAIT_TIME 4 ///< Wait response time. unit 1s.
+
+#define IPPORT_DOMAIN 53 ///< DNS server port number
+
+#define DNS_MSG_ID 0x1122 ///< ID for DNS message. You can be modified it any number
+/*
+ * @brief DNS process initialize
+ * @param s : Socket number for DNS
+ * @param buf : Buffer for DNS message
+ */
+void DNS_init(uint8_t s, uint8_t * buf);
+
+/*
+ * @brief DNS process
+ * @details Send DNS query and receive DNS response
+ * @param dns_ip : DNS server ip address
+ * @param name : Domain name to be queried
+ * @param ip_from_dns : IP address from DNS server
+ * @return -1 : failed. @ref MAX_DOMIN_NAME is too small \n
+ * 0 : failed (Timeout or Parse error)\n
+ * 1 : success
+ * @note This function blocks until success or fail. max time = @ref MAX_DNS_RETRY * @ref DNS_WAIT_TIME
+ */
+int8_t DNS_run(uint8_t * dns_ip, uint8_t * name, uint8_t * ip_from_dns);
+
+#endif /* _DNS_H_ */