본문 바로가기

WIZnet DNS/7.DNS Source code

DNS Source Code

안녕하세요~

이 블로그 Step by step으로 DNS에 대하여 연재합니다. 만약 DNS가 무엇인지 모르시거나, 아래 내용들이 이해가 가지 않으시면 아래 링크를 참조하셔서 확인부탁드립니다.
DNS시작하기 ! – https://jinheeahn.wordpress.com/2015/08/28/1-dns-시작하기

DNS 통신에 대하여! – https://jinheeahn.wordpress.com/2015/09/07/2-dns 통신에 대하여

DNS Header – https://jinheeahn.wordpress.com/2015/09/08/3-dns-message/

DNS 질의 메세지 – https://jinheeahn.wordpress.com/2015/09/21/4-dns-질의 메세지

DNS 응답 메세지 - https://jinheeahn.wordpress.com/2015/09/21/5-dns-응답 메세지


그리고 Wireshark DNS packet 잡기도 연재하였으니 아래의 링크를 확인해주세요.

Wireshark로 DNS pakcet 잡기 – https://jinheeahn.wordpress.com/2015/09/21/dns-wireshark pakcet 잡기


자, 이제 시작해보도록 할게요.

우선 이 코드는 DHCP와 관련되어 있다는 점을 먼저 말씀드립니다.

이 프로젝트의 최종 목표는 DHCP를 이용하여 IP를 할당받고 할당받은 IP를 이용해서 도메인의 IP를 알아보는 것입니다.

도메인 = www.google.com

위 도메인의 IP 정보를 알아보는 것입니다.

WIZNET Driver -> Protocol -> DHCP를 가시면 DHCP에 대한 기초설명과 DHCP를 구현한 코드까지 있으니 참조해주세요.

그럼, 코드를 보여드리겠습니다. DHCP 코드에 DNS 코드를 하나 더 얹어 사용했습니다.

Socket은 총 2개 Open했구요. 하나는 DHCP용, 하나는 DNS용입니다.


사용할 Module은 DHCP 구현할 때 사용했던  WIZnet사의 W5500-EVB입니다.

Tool은 LPCXpresso를 사용하겠습니다.

이건 무료 배포버전이구요. 유료로 업그레이드 가능합니다.

무료와 유료버전의 차이는 코드 사이즈라고 보시면 되겠습니다.

근데 ! 왜 LPCXpresso를 사용하냐구요?? W5500-EVB가 NXP사의 Cortex-M0의 MCU를 사용하기 때문입니다!

Module에 대한 자세한 정보는 아래의 링크를 확인해주세요!

http://wizwiki.net/wiki/doku.php?id=products:w5500:w5500_evb:start

그 밖의 처음 사용하시는 분들은 Getting Started를 확인해주세요.

  1. Getting Started – getting_started#hello_world
  2. Getting Started – Firmware Upload

W5500-EVB의 Application 예제들은 GITHUB이라는 사이트에 업로드 되어 있습니다. 참조해주세요.

https://github.com/Wiznet/ioLibrary_Driver


자, 이제 코딩을 올려보도록 하겠습니다. 분명 너무 길어서 무슨 코드인지 한번에 알아보기는 어려우실 거에요. 일단 WIZnet사에서 제공하는 ioLibrary에는 DNS도 있습니다.


코드에 궁금하신 것이 있으면 댓글 부탁드립니다.



[code language="c"]


/*
===============================================================================
 Name : W5500-EVB.c
 Author : $(author)
 Version :
 Copyright : $(copyright)
 Description : main definition
===============================================================================
*/

#if defined (__USE_LPCOPEN)
#if defined(NO_BOARD_LIB)
#include <chip.h>
#else
#include <board.h>
#endif
#endif

#include "cr_section_macros.h"
#include "socket.h"
#include"spi_handler.h"
#include "w5500_init.h"
#include "w5500.h"
#include <stdio.h>
#include <string.h>
#include "w5500_DHCP.h"

// TODO: insert other include files here

// TODO: insert other definitions and declarations here

#define DHCP_DISCOVER      		 1        ///< send DISCOVER and wait OFFER

#define STATE_DHCP_DISCOVER      0        ///< Initialize
#define STATE_DHCP_OFFER	     1        ///< send DISCOVER and wait OFFER
#define STATE_DHCP_REQUEST       2        ///< send REQEUST and wait ACK or NACK
#define STATE_DHCP_ACK			 3
#define STATE_DHCP_REREQUEST	 4

#define DHCP_FLAGSBROADCAST      0x8000   ///< The broadcast value of flags in @ref RIP_MSG

/* DHCP message OP code */
#define DHCP_BOOTREQUEST         1        ///< Request Message used in op of @ref RIP_MSG

/* DHCP message type */
#define DHCP_DISCOVER            1        ///< DISCOVER message in OPT of @ref RIP_MSG
#define DHCP_REQUEST			 3
#define DHCP_ACK				 5
#define DHCP_NAK				 6

#define DHCP_HTYPE10MB           1        ///< Used in type of @ref RIP_MSG

/////////////////////////////////////////////////// DHCP Option pakcet

#define DHCP_Message_type		 0x35
#define Client_identifier		 0x3D
#define Requested_IP_ADDRESS	 0x32 		// want IP
#define Host_Name				 0x0C
#define DHCP_HOST_NAME			 "WIZnet"
#define Vendor_class_identifier	 0x3C
#define Parameter_request_list	 0x37
#define DHCP_SEVER_Identifier	 0x36

#define subnet_mask 						1
#define domain_name							15
#define	router								3
#define	domain_name_server					6

#define	netbios_over_tcp_name_server		44
#define	netbios_over_tcp_node_type			46
#define	netbios_over_tcp_scope				47
#define	perform_router_discover				31
#define	static_route						33
#define	classless_static_route				121
#define	private_classless_static_route		249
#define	vendor_specific_information			43

////////////////////////////////////////////////////

#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 //////////////////////////////////////////////////// Socket information #define DHCP_SERVER 67 #define DHCP_Client 68 #define TCP_SOCKET 0 #define UDP_SOCKET 1 #define TCP_PORT 5000 #define OPT_SIZE 312 /// Max OPT size of @ref RIP_MSG #define RIP_MSG_SIZE (236+OPT_SIZE) /// Max size of @ref RIP_MSG uint8_t UDP_buffer[RIP_MSG_SIZE]; ///////////////////////////////////////////////////// DNS #define DNS_MSG_ID 0x1324 #define DNS_SOCKET 2 #define DNS_Local_Server_PORT 53 #define DNS_client 0 #define DNS_MSG_SIZE 256 /// DNS buffer size uint8_t DNS_buffer[DNS_MSG_SIZE]; ///////////////////////////////////////////////////// DHCP State uint8_t dhcp_states = STATE_DHCP_DISCOVER; enum { padOption = 0x00, subnetMask = 0x01, timerOffset = 0x02, routersOnSubnet = 0x03, timeServer = 0x04, nameServer = 0x05, dns = 0x06, logServer = 0x07, cookieServer = 0x08, lprServer = 0x09, impressServer = 0x0A, resourceLocationServer = 0x0B, hostName = 0x0C, bootFileSize = 0x0D, meritDumpFile = 0x0E, domainName = 0x0F, swapServer = 0x10, rootPath = 0x11, extentionsPath = 0x12, IPforwarding = 0x13, nonLocalSourceRouting = 0x14, policyFilter = 0x15, maxDgramReasmSize = 0x16, defaultIPTTL = 0x17, pathMTUagingTimeout = 0x18, pathMTUplateauTable = 0x19, ifMTU = 0x1A, allSubnetsLocal = 0x1B, broadcastAddr = 0x1C, performMaskDiscovery = 0x1D, maskSupplier = 0x1E, performRouterDiscovery = 0x1F, routerSolicitationAddr = 0x20, staticRoute = 0x21, trailerEncapsulation = 0x22, arpCacheTimeout = 0x23, ethernetEncapsulation = 0x24, tcpDefaultTTL = 0x25, tcpKeepaliveInterval = 0x26, tcpKeepaliveGarbage = 0x27, nisDomainName = 0x28, nisServers = 0x29, ntpServers = 0x2A, vendorSpecificInfo = 0x2B, netBIOSnameServer = 0x2C, netBIOSdgramDistServer = 0x2D, netBIOSnodeType = 0x2E, netBIOSscope = 0x2F, xFontServer = 0x30, xDisplayManager = 0x31, dhcpRequestedIPaddr = 0x32, dhcpIPaddrLeaseTime = 0x33, dhcpOptionOverload = 0x34, dhcpMessageType = 0x35, dhcpServerIdentifier = 0x36, dhcpParamRequest = 0x37, dhcpMsg = 0x38, dhcpMaxMsgSize = 0x39, dhcpT1value = 0x3A, dhcpT2value = 0x3B, dhcpClassIdentifier = 0x3C, dhcpClientIdentifier = 0x3D, endOption = 0xFF }; ////////////////////////////////////////////////////////// DNS Response #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 */ /* Header for all domain messages */ struct DNS_MSG2 { uint16_t id; // Identification uint8_t qr; // Query / Response #define QUERY 0 #define RESPONSE 1 uint8_t opcode; #define IQUERY 1 #define STATUS 3 #define Notify 4 #define Update 5 uint8_t aa; uint8_t tc; uint8_t rd; uint8_t ra; uint8_t z; uint8_t ad; uint8_t cd; uint8_t rcode; #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 quecount; // question count uint16_t anscount; // answer count uint16_t authorcount; // authority (name server) count uint16_t addcount; // additional record count }; ////////////////////////////////////////////////////////// int main(void) { /////////////////////////////////////////// common variable uint8_t ip[4]={0,}; uint8_t DHCP_CHADDR[6]; uint8_t ptmp[7] = {0,}; /////////////////////////////////////////// BOOTP packet uint8_t OP = 0x01; uint8_t HTYPE = 0x01; uint8_t HLEN = 0x06; uint8_t HOPS = 0x00; uint32_t XID = 0x12345678; uint16_t SECS = 0x0000; uint16_t FLAGS_BORADCAST = 0x8000; uint16_t FLAGS_UNICAST = 0x0000; uint8_t CIADDR[4] = {0,}; uint8_t YIADDR[4] = {0,}; uint8_t SIADDR[4] = {0,}; uint8_t GIADDR[4] = {0,}; uint8_t CHADDR[16] = {0,}; //uint8_t host_name[64] = {0,}; //uint8_t file_name[128] = {0,}; uint32_t MAGIC_COOKIE = 0x63825363; //////////////////////////////////////////// make Discover Option //uint8_t host_names[] = DHCP_HOST_NAME; uint32_t host_name1 = 0x57495A6E; uint16_t host_name2 = 0x6574; //////////////////////////////////////////// offer & ACK uint8_t Target_ip[4]={255,255,255,255}; uint16_t Target_port; uint16_t Rx_len; uint8_t * pOption; uint8_t * eOption; uint16_t dOption; uint16_t dOption_CAL; uint8_t Option_len; uint32_t CHECK_XID = 0; uint32_t CHECK_DNSID = 0; uint32_t CHECK_MAGIC = 0; uint8_t DHCP_ASSIGN_Message_type; uint8_t DHCP_ASSIGN_IP[4] = {0,}; uint8_t DHCP_ServerIP[4] = {0,}; uint8_t DHCP_ASSIGN_LEASETIME[4] = {0,}; uint8_t DHCP_ASSIGN_SUBNET[4] = {0,}; uint8_t DHCP_ASSIGN_ROUTER_CAL[8] = {0,}; uint8_t DHCP_ASSIGN_ROUTER1[4] = {0,}; uint8_t DHCP_ASSIGN_ROUTER2[4] = {0,}; uint8_t DHCP_ASSIGN_Domain_server_CAL[8] = {0,}; uint8_t DHCP_ASSIGN_Domain_server1[4] = {0,}; uint8_t DHCP_ASSIGN_Domain_server2[4] = {0,}; uint8_t i; //////////////////////////////////////////////////DNS uint16_t DNS_FLAG = 0x0100; uint16_t DNS_Question = 0x0001; uint16_t DNS_Answer = 0x0000; uint16_t DNS_Authority = 0x0000; uint16_t DNS_Additional = 0x0000; uint8_t Domain_name[] = "www.google.com"; uint16_t DNS_Domain_Type = 0x0001; uint16_t DNS_Domain_class = 0x0001; uint8_t *pDNSBUF; uint16_t dns_query_len; uint8_t dns_recv_ip[4] = {0,}; uint16_t dns_recv_port[4] = {0,}; uint8_t ip_from_dns_server[4] = {0,}; #if defined (__USE_LPCOPEN) #if !defined(NO_BOARD_LIB) // Read clock settings and update SystemCoreClock variable SystemCoreClockUpdate(); // Set up and initialize all required blocks and // functions related to the board hardware Board_Init(); // Set the LED to the state of On Board_LED_Set(0, true); #endif #endif SPI_Init(); W5500_Init(); Net_Conf(); getSHAR(DHCP_CHADDR); DHCP_CHADDR[0] = 0x00; DHCP_CHADDR[1] = 0x08; DHCP_CHADDR[2] = 0xdc; DHCP_CHADDR[3] = 0x19; DHCP_CHADDR[4] = 0x84; DHCP_CHADDR[5] = 0x82; setSHAR(DHCP_CHADDR); CHADDR[0] = DHCP_CHADDR[0]; CHADDR[1] = DHCP_CHADDR[1]; CHADDR[2] = DHCP_CHADDR[2]; CHADDR[3] = DHCP_CHADDR[3]; CHADDR[4] = DHCP_CHADDR[4]; CHADDR[5] = DHCP_CHADDR[5]; // DNS buffer pointer setting void DNS_init(uint8_t *buf) { pDNSBUF = buf; } uint8_t * DNS_PUT_VAL (uint8_t* s, uint16_t i) { *s++ = i >> 8;
		*s++ = i;
		return s;
	}

	uint16_t DNS_GET_VAL (uint8_t *s)
	{
		uint16_t i;
		i = *s++ << 8; i = i + *s; return i; } void DNS_Query(void) { uint8_t *s; char *p1; char cname[16] = {0,}; char *dname; char DNS_localserver_ip[4] = {0,}; uint16_t len; uint16_t dlen; if(socket(DNS_SOCKET, Sn_MR_UDP, DNS_client, 0) == DNS_SOCKET) { printf("DNS_Socket creation\r\n"); printf("DNS Server IP 1st : %d,%d,%d,%d\r\n",DHCP_ASSIGN_Domain_server1[0],DHCP_ASSIGN_Domain_server1[1],DHCP_ASSIGN_Domain_server1[2],DHCP_ASSIGN_Domain_server1[3]); printf("DNS Server IP 2nd : %d,%d,%d,%d\r\n",DHCP_ASSIGN_Domain_server2[0],DHCP_ASSIGN_Domain_server2[1],DHCP_ASSIGN_Domain_server2[2],DHCP_ASSIGN_Domain_server2[3]); } s = pDNSBUF; s = DNS_PUT_VAL(s, DNS_MSG_ID); s = DNS_PUT_VAL(s, DNS_FLAG); s = DNS_PUT_VAL(s, DNS_Question); s = DNS_PUT_VAL(s, DNS_Answer); s = DNS_PUT_VAL(s, DNS_Authority); s = DNS_PUT_VAL(s, DNS_Additional); strcpy(cname, (char *)Domain_name); // 여기서 Data가 들어가는 것임. dname = cname; // pointer of cname. dlen = strlen(dname); while(1) { p1 = strchr(dname,'.'); // if / else를 넣음으로써 루프 탈출이 가능. if (p1 != NULL){ // 1. p1이 NULL이 아니면 CAL 수행 len = p1 - dname; } else len = dlen; // 2. p1이 NULL이니깐 dlen도 0 *s++ = len; if(len == 0) break; // 3. len이 0이니깐 루프 탈출 strncpy((char *)s, dname, len); // len 갯수만큼 dname의 문자열이 p로 들어감. s += len; // 주소값 len만큼 증가. if (p1 == NULL) { *s++ = 0; /* Last one; write null and finish */ break; } dname += len+1; // dname에서 len만큼 (-)한다. + 1은 (.) 포함 dlen -= len+1; } s = DNS_PUT_VAL(s, DNS_Domain_Type); s = DNS_PUT_VAL(s, DNS_Domain_class); strcpy(DNS_localserver_ip, (char *)DHCP_ASSIGN_Domain_server1); // IP value dns_query_len = ((uint16_t)((uint32_t)s - (uint32_t)pDNSBUF)); // pointer length return sendto(DNS_SOCKET, pDNSBUF, dns_query_len, DNS_localserver_ip, DNS_Local_Server_PORT); printf("DNS Query SEND\r\n"); } void DNS_Response(void) { struct DNS_MSG2 *pDNSMSGs; struct DNS_MSG2 DNSMSGs; pDNSMSGs = &DNSMSGs; uint16_t tmp; uint8_t *cp; while(1) { if((Rx_len = getSn_RX_RSR(DNS_SOCKET)) > 0)
			{
				printf("Receive Data ! \r\n");
				Rx_len = recvfrom(DNS_SOCKET, (uint8_t *)DNS_buffer, DNS_MSG_SIZE, dns_recv_ip, dns_recv_port);

				CHECK_DNSID = DNS_GET_VAL(&DNS_buffer[0]);
				if (DNS_MSG_ID != CHECK_DNSID)
				{
					printf("DNS_MSG_ID error\r\n");
					while(1);
				}
				tmp = DNS_GET_VAL(&DNS_buffer[2]);

				if(tmp & 0x8000)
				{
					pDNSMSGs->qr = 1;
				}
				if (tmp & 0x4000)
				{
					printf("Response opcode error\r\n");
					while(1);
				}
				if (tmp & 0x2000)
				{
					printf("Response opcode error\r\n");
					while(1);
				}
				if (tmp & 0x1000)
				{
					printf("Response opcode error\r\n");
					while(1);
				}
				if (tmp & 0x0800)
				{
					printf("Response opcode error\r\n");
					while(1);
				}

				if(pDNSMSGs->qr != 1)
				{
					printf("Not Message response.. check the Query\r\n");
				}

				pDNSMSGs->opcode = (tmp & 0xf);

				if(tmp & 0x0400) pDNSMSGs->aa = 1;
				if(tmp & 0x0200) pDNSMSGs->tc = 1;
				if(tmp & 0x0100) pDNSMSGs->rd = 1;
				if(tmp & 0x0080) pDNSMSGs->ra = 1;
				if(tmp & 0x0040) pDNSMSGs->z = 1; // basically Zero(0)
				if(tmp & 0x0020) pDNSMSGs->ad = 1; // Authenticated data
				if(tmp & 0x0010) pDNSMSGs->cd = 1; // Checking Disabled

				pDNSMSGs->rcode = tmp & 0xf;

				pDNSMSGs->quecount = DNS_GET_VAL(&DNS_buffer[4]);
				pDNSMSGs->anscount = DNS_GET_VAL(&DNS_buffer[6]);
				pDNSMSGs->authorcount = DNS_GET_VAL(&DNS_buffer[8]);
				pDNSMSGs->addcount = DNS_GET_VAL(&DNS_buffer[10]);

				cp = &DNS_buffer[12];

				for(i = 0; i < pDNSMSGs->quecount; i++)
				{
					uint8_t slen;
					uint16_t len;
					while(1)
					{
						slen = *cp++;

						if(slen == 0x00)
						{
							break;
						}

						len = slen;
						cp += len;
					}
					cp += 2;
					cp += 2;
				}

				for(i = 0; i < pDNSMSGs->anscount; i++)
				{
					uint8_t slen;
					uint16_t TYPE;
					while(1)
					{
						slen = *cp++;
						if(slen == 0xc0)
						{
							cp++;
							break;
						}
					}
					TYPE = DNS_GET_VAL(cp);
					cp += 2;
					cp += 2;
					cp += 4;
					cp += 2;

					switch(TYPE)
					{
					case TYPE_A:

						/* Just read the address directly into the structure */
						ip_from_dns_server[0] = *cp++;
						ip_from_dns_server[1] = *cp++;
						ip_from_dns_server[2] = *cp++;
						ip_from_dns_server[3] = *cp++;
						printf("DNS IP : %d,%d,%d,%d\r\n",ip_from_dns_server[0],ip_from_dns_server[1],ip_from_dns_server[2],ip_from_dns_server[3]);
						break;
					case TYPE_CNAME:
					case TYPE_MB:
					case TYPE_MG:
					case TYPE_MR:
					case TYPE_NS:
					case TYPE_PTR:
						break;
					case TYPE_HINFO:
						break;
					case TYPE_MX:
						break;
					case TYPE_SOA:
						break;
					case TYPE_TXT:
						break;
					default:
						break;
					}
				}
			}
		}
	}

	///////////////////////////////////////////////////// Network assign

	void network_assign(void)
	{
		uint8_t tmp[4] = {0,};

		setSIPR(DHCP_ASSIGN_IP);
		setSUBR(DHCP_ASSIGN_SUBNET);
		setGAR (DHCP_ASSIGN_ROUTER1);

		getSIPR(tmp); printf("IP ADDRESS : %d,%d,%d,%d\r\n",tmp[0],tmp[1],tmp[2],tmp[3]);
		getSUBR(tmp); printf("SUBNET MASK : %d,%d,%d,%d\r\n",tmp[0],tmp[1],tmp[2],tmp[3]);
		getGAR(tmp); printf("GATEWAY : %d,%d,%d,%d\r\n",tmp[0],tmp[1],tmp[2],tmp[3]);
	}

	if(socket(UDP_SOCKET,Sn_MR_UDP,DHCP_Client,0) == UDP_SOCKET)
		{
			printf("socket UDP creation\r\n");
		}
	while(1)
	{
		switch(dhcp_states)
		{
		case STATE_DHCP_DISCOVER:

			UDP_buffer[0] = OP;
			UDP_buffer[1] = HTYPE;
			UDP_buffer[2] = HLEN;
			UDP_buffer[3] = HOPS;

			ptmp[0] = (uint8_t)((XID & 0xFF000000) >> 24);
			UDP_buffer[4] = ptmp[0];
			ptmp[1] = (uint8_t)((XID & 0x00FF0000) >> 16);
			UDP_buffer[5] = ptmp[1];
			ptmp[2] = (uint8_t)((XID & 0x0000FF00) >>  8);
			UDP_buffer[6] = ptmp[2];
			ptmp[3] = (uint8_t)((XID & 0x000000FF) >>  0);
			UDP_buffer[7] = ptmp[3];

			ptmp[4] = (uint8_t)((SECS & 0xFF00) >>  8);
			UDP_buffer[8] = ptmp[4];
			ptmp[5] = (uint8_t)((SECS & 0x00FF) >>  8);
			UDP_buffer[9] = ptmp[5];

			ptmp[6] = (uint8_t)((FLAGS_BORADCAST & 0xFF00) >> 8);
			UDP_buffer[10] = ptmp[6];
			ptmp[7] = (uint8_t)((FLAGS_BORADCAST & 0x00FF) >> 0);
			UDP_buffer[11] = ptmp[7];

			UDP_buffer[12] = CIADDR[0];
			UDP_buffer[13] = CIADDR[1];
			UDP_buffer[14] = CIADDR[2];
			UDP_buffer[15] = CIADDR[3];
			UDP_buffer[16] = YIADDR[0];
			UDP_buffer[17] = YIADDR[1];
			UDP_buffer[18] = YIADDR[2];
			UDP_buffer[19] = YIADDR[3];
			UDP_buffer[20] = SIADDR[0];
			UDP_buffer[21] = SIADDR[1];
			UDP_buffer[22] = SIADDR[2];
			UDP_buffer[23] = SIADDR[3];
			UDP_buffer[24] = GIADDR[0];
			UDP_buffer[25] = GIADDR[1];
			UDP_buffer[26] = GIADDR[2];
			UDP_buffer[27] = GIADDR[3];
			UDP_buffer[28] = CHADDR[0];
			UDP_buffer[29] = CHADDR[1];
			UDP_buffer[30] = CHADDR[2];
			UDP_buffer[31] = CHADDR[3];
			UDP_buffer[32] = CHADDR[4];
			UDP_buffer[33] = CHADDR[5];

			UDP_buffer[236] = (uint8_t)((MAGIC_COOKIE & 0xFF000000) >> 24);
			UDP_buffer[237] = (uint8_t)((MAGIC_COOKIE & 0x00FF0000) >> 16);
			UDP_buffer[238] = (uint8_t)((MAGIC_COOKIE & 0x0000FF00) >>  8);
			UDP_buffer[239] = (uint8_t)((MAGIC_COOKIE & 0x000000FF) >>  0);

			ip[0] = 255;
			ip[1] = 255;
			ip[2] = 255;
			ip[3] = 255;

			UDP_buffer[240] = DHCP_Message_type; // Just -> 0x53(No!) option name is decimal type
			UDP_buffer[241] = 0x01;
			UDP_buffer[242] = DHCP_DISCOVER;
			UDP_buffer[243] = Client_identifier;
			UDP_buffer[244] = 0x07;
			UDP_buffer[245] = 0x01;
			UDP_buffer[246] = DHCP_CHADDR[0];
			UDP_buffer[247] = DHCP_CHADDR[1];
			UDP_buffer[248] = DHCP_CHADDR[2];
			UDP_buffer[249] = DHCP_CHADDR[3];
			UDP_buffer[250] = DHCP_CHADDR[4];
			UDP_buffer[251] = DHCP_CHADDR[5];

			UDP_buffer[252] = Host_Name;
			UDP_buffer[253] = 0x0A; // Hex
			UDP_buffer[254] = (uint8_t)((host_name1 & 0xFF000000) >> 24);
			UDP_buffer[255] = (uint8_t)((host_name1 & 0x00FF0000) >> 16);
			UDP_buffer[256] = (uint8_t)((host_name1 & 0x0000FF00) >>  8);
			UDP_buffer[257] = (uint8_t)((host_name1 & 0x000000FF) >>  0);
			UDP_buffer[258] = (uint8_t)((host_name2 & 0x0FF00) >>  8);
			UDP_buffer[259] = (uint8_t)((host_name2 & 0x000FF) >>  0);

			UDP_buffer[264] = Parameter_request_list;
			UDP_buffer[265] = 0x04;
			UDP_buffer[266] = subnet_mask;
			UDP_buffer[267] = domain_name;
			UDP_buffer[268] = router;
			UDP_buffer[269] = domain_name_server;

			UDP_buffer[270] = 255;

			sendto(UDP_SOCKET, (uint8_t *)UDP_buffer, RIP_MSG_SIZE,ip,DHCP_SERVER);
			printf("----DISCOVER Message SEND----\r\n");
			memset(UDP_buffer,0,RIP_MSG_SIZE);
			dhcp_states = STATE_DHCP_OFFER;
				break;

		case STATE_DHCP_OFFER:
			if((Rx_len = getSn_RX_RSR(UDP_SOCKET)) > 0)
				{
					Rx_len = recvfrom(UDP_SOCKET, (uint8_t *)UDP_buffer, Rx_len, Target_ip, &Target_port);
					printf("----Offer Message----\r\n");
					if (Target_port == DHCP_SERVER)
					{
						printf("CHECK XID\r\n");
						CHECK_XID |= (uint32_t)((UDP_buffer[4] & 0xFFFFFFFF) << 24);
						CHECK_XID |= (uint32_t)((UDP_buffer[5] & 0xFFFFFFFF) << 16);
						CHECK_XID |= (uint32_t)((UDP_buffer[6] & 0xFFFFFFFF) <<  8);
						CHECK_XID |= (uint32_t)((UDP_buffer[7] & 0xFFFFFFFF) <<  0);
						if (XID != CHECK_XID)
						{
							printf("XID error\r\n");
							return 0;
						}
						printf("CHECK CHADDR\r\n");
						if ((UDP_buffer[28] != DHCP_CHADDR[0]) || (UDP_buffer[29] != DHCP_CHADDR[1]) ||
							 (UDP_buffer[30] != DHCP_CHADDR[2]) || (UDP_buffer[31] != DHCP_CHADDR[3]) ||
							 (UDP_buffer[32] != DHCP_CHADDR[4]) || (UDP_buffer[33] != DHCP_CHADDR[5]))
						{
							printf("CHADDR error\r\n");
							return 0;
						}
						printf("CHECK MAGIC\r\n");
						CHECK_MAGIC |= (uint32_t)((UDP_buffer[236] & 0xFFFFFFFF) << 24);
						CHECK_MAGIC |= (uint32_t)((UDP_buffer[237] & 0xFFFFFFFF) << 16);
						CHECK_MAGIC |= (uint32_t)((UDP_buffer[238] & 0xFFFFFFFF) <<  8);
						CHECK_MAGIC |= (uint32_t)((UDP_buffer[239] & 0xFFFFFFFF) <<  0);
						if(CHECK_MAGIC != 0x63825363)
						{
							printf("magic error\r\n");
							return 0;
						}
						printf("CHECK COMPLITE\r\n");

						//Your IP Address
						DHCP_ASSIGN_IP[0] = UDP_buffer[16];
						DHCP_ASSIGN_IP[1] = UDP_buffer[17];
						DHCP_ASSIGN_IP[2] = UDP_buffer[18];
						DHCP_ASSIGN_IP[3] = UDP_buffer[19];

						pOption = (uint8_t*)(&UDP_buffer); // OP start address
						pOption = pOption + 240;
						eOption = pOption + (Rx_len - 240);

						printf("-----Option Message-----\r\n");
						while ( pOption < eOption ) { switch(*pOption) { case dhcpMessageType: pOption++; Option_len = *pOption++; if(Option_len > dOption) // check length
								{
									return 0;
								}
								for(i=0;i<option_len;i++) { if(Option_len == 1) { DHCP_ASSIGN_Message_type = *pOption++; } else{ pOption += Option_len; } } dOption = dOption - (Option_len + 2); dOption_CAL = dOption; printf("dhcpMessageType Value : %d\r\n",DHCP_ASSIGN_Message_type); break; case dhcpServerIdentifier: pOption++; Option_len = *pOption++; if(Option_len > dOption) // check length. from hacking
								{
									return 0;
								}
								for(i=0;i<option_len;i++) { if(Option_len == 4) { DHCP_ServerIP[i] = *pOption++; } else{ pOption += Option_len; } } dOption = dOption - (Option_len + 2); dOption_CAL = dOption; printf("serverIP : %d,%d,%d,%d\r\n",DHCP_ServerIP[0],DHCP_ServerIP[1],DHCP_ServerIP[2],DHCP_ServerIP[3]); break; case dhcpIPaddrLeaseTime: pOption++; Option_len = *pOption++; if(Option_len > dOption) // check length. from hacking
								{
									return 0;
								}
								for(i=0;i<option_len;i++) { if(Option_len == 4) { DHCP_ASSIGN_LEASETIME[i] = *pOption++; } else{ pOption += Option_len; } } dOption = dOption - (Option_len + 2); dOption_CAL = dOption; printf("LEASE : %d,%d,%d,%d\r\n",DHCP_ASSIGN_LEASETIME[0],DHCP_ASSIGN_LEASETIME[1],DHCP_ASSIGN_LEASETIME[2],DHCP_ASSIGN_LEASETIME[3]); break; case subnetMask: pOption++; Option_len = *pOption++; if(Option_len > dOption) // check length. from hacking
								{
									return 0;
								}
								for(i=0;i<option_len;i++) { if(Option_len == 4) { DHCP_ASSIGN_SUBNET[i] = *pOption++; } else{ pOption += Option_len; } } dOption = dOption - (Option_len + 2); dOption_CAL = dOption; printf("subnet mask : %d,%d,%d,%d\r\n",DHCP_ASSIGN_SUBNET[0],DHCP_ASSIGN_SUBNET[1],DHCP_ASSIGN_SUBNET[2],DHCP_ASSIGN_SUBNET[3]); break; case routersOnSubnet: pOption++; Option_len = *pOption++; if(Option_len > dOption) // check length. from hacking
								{
									return 0;
								}
								for(i=0;i<option_len;i++) { if(Option_len == 4) { DHCP_ASSIGN_ROUTER1[i] = *pOption++; } else if(Option_len > 8)
									{
										pOption += Option_len;
									}
									else{
										DHCP_ASSIGN_ROUTER_CAL[i] = *pOption++;
									}
								}
								if(Option_len == 8)
								{
									DHCP_ASSIGN_ROUTER1[0] = DHCP_ASSIGN_ROUTER_CAL[0];
									DHCP_ASSIGN_ROUTER1[1] = DHCP_ASSIGN_ROUTER_CAL[1];
									DHCP_ASSIGN_ROUTER1[2] = DHCP_ASSIGN_ROUTER_CAL[2];
									DHCP_ASSIGN_ROUTER1[3] = DHCP_ASSIGN_ROUTER_CAL[3];
									DHCP_ASSIGN_ROUTER2[0] = DHCP_ASSIGN_ROUTER_CAL[4];
									DHCP_ASSIGN_ROUTER2[1] = DHCP_ASSIGN_ROUTER_CAL[5];
									DHCP_ASSIGN_ROUTER2[2] = DHCP_ASSIGN_ROUTER_CAL[6];
									DHCP_ASSIGN_ROUTER2[3] = DHCP_ASSIGN_ROUTER_CAL[7];
								}
								dOption = dOption - (Option_len + 2);
								dOption_CAL = dOption;
								printf("router1 : %d,%d,%d,%d\r\n",DHCP_ASSIGN_ROUTER1[0],DHCP_ASSIGN_ROUTER1[1],DHCP_ASSIGN_ROUTER1[2],DHCP_ASSIGN_ROUTER1[3]);
								printf("router2 : %d,%d,%d,%d\r\n",DHCP_ASSIGN_ROUTER2[0],DHCP_ASSIGN_ROUTER2[1],DHCP_ASSIGN_ROUTER2[2],DHCP_ASSIGN_ROUTER2[3]);
								break;
							case dns:
								pOption++;
								Option_len = *pOption++;
								if(Option_len > dOption) // check length. from hacking
								{
									return 0;
								}
								for(i=0;i<option_len;i++) { if(Option_len > 8)
									{
										pOption += Option_len;
									}
									else if(Option_len == 4)
									{
										DHCP_ASSIGN_Domain_server1[i] = *pOption++;
									}
									else{
										DHCP_ASSIGN_Domain_server_CAL[i] = *pOption++;
									}
								}
								if(Option_len == 8)
								{
									DHCP_ASSIGN_Domain_server1[0] = DHCP_ASSIGN_Domain_server_CAL[0];
									DHCP_ASSIGN_Domain_server1[1] = DHCP_ASSIGN_Domain_server_CAL[1];
									DHCP_ASSIGN_Domain_server1[2] = DHCP_ASSIGN_Domain_server_CAL[2];
									DHCP_ASSIGN_Domain_server1[3] = DHCP_ASSIGN_Domain_server_CAL[3];
									DHCP_ASSIGN_Domain_server2[0] = DHCP_ASSIGN_Domain_server_CAL[4];
									DHCP_ASSIGN_Domain_server2[1] = DHCP_ASSIGN_Domain_server_CAL[5];
									DHCP_ASSIGN_Domain_server2[2] = DHCP_ASSIGN_Domain_server_CAL[6];
									DHCP_ASSIGN_Domain_server2[3] = DHCP_ASSIGN_Domain_server_CAL[7];
								}
								dOption = dOption - (Option_len + 2);
								dOption_CAL = dOption;
								printf("domain1 : %d,%d,%d,%d\r\n",DHCP_ASSIGN_Domain_server1[0],DHCP_ASSIGN_Domain_server1[1],DHCP_ASSIGN_Domain_server1[2],DHCP_ASSIGN_Domain_server1[3]);
								printf("domain2 : %d,%d,%d,%d\r\n",DHCP_ASSIGN_Domain_server2[0],DHCP_ASSIGN_Domain_server2[1],DHCP_ASSIGN_Domain_server2[2],DHCP_ASSIGN_Domain_server2[3]);
								break;
							case endOption:
								pOption = eOption; // escape switch condition
								printf("end\r\n");
								dOption = dOption - dOption_CAL;
								dhcp_states = STATE_DHCP_REREQUEST;
								break;
							default: // If receive unregistration option packet, operate default case
								pOption++;
								Option_len = *pOption++;
								pOption += Option_len;
								printf("not search\r\n");
								break;
							}
						}
						if(dOption)
						{
							return 0;
						}
						else{
							printf("Option Parser End\r\n");
						}
				}
			dhcp_states = STATE_DHCP_REQUEST;
			}
			break;

		case STATE_DHCP_REQUEST :
		{
			UDP_buffer[0] = OP;
			UDP_buffer[1] = HTYPE;
			UDP_buffer[2] = HLEN;
			UDP_buffer[3] = HOPS;

			ptmp[0] = (uint8_t)((XID & 0xFF000000) >> 24);
			UDP_buffer[4] = ptmp[0];
			ptmp[1] = (uint8_t)((XID & 0x00FF0000) >> 16);
			UDP_buffer[5] = ptmp[1];
			ptmp[2] = (uint8_t)((XID & 0x0000FF00) >>  8);
			UDP_buffer[6] = ptmp[2];
			ptmp[3] = (uint8_t)((XID & 0x000000FF) >>  0);
			UDP_buffer[7] = ptmp[3];

			ptmp[4] = (uint8_t)((SECS & 0xFF00) >>  8);
			UDP_buffer[8] = ptmp[4];
			ptmp[5] = (uint8_t)((SECS & 0x00FF) >>  8);
			UDP_buffer[9] = ptmp[5];

			ptmp[6] = (uint8_t)((FLAGS_UNICAST & 0xFF00) >> 8);
			UDP_buffer[10] = ptmp[6];
			ptmp[7] = (uint8_t)((FLAGS_UNICAST & 0x00FF) >> 0);
			UDP_buffer[11] = ptmp[7];

			UDP_buffer[12] = CIADDR[0];
			UDP_buffer[13] = CIADDR[1];
			UDP_buffer[14] = CIADDR[2];
			UDP_buffer[15] = CIADDR[3];
			UDP_buffer[16] = YIADDR[0];
			UDP_buffer[17] = YIADDR[1];
			UDP_buffer[18] = YIADDR[2];
			UDP_buffer[19] = YIADDR[3];
			UDP_buffer[20] = SIADDR[0];
			UDP_buffer[21] = SIADDR[1];
			UDP_buffer[22] = SIADDR[2];
			UDP_buffer[23] = SIADDR[3];
			UDP_buffer[24] = GIADDR[0];
			UDP_buffer[25] = GIADDR[1];
			UDP_buffer[26] = GIADDR[2];
			UDP_buffer[27] = GIADDR[3];
			UDP_buffer[28] = CHADDR[0];
			UDP_buffer[29] = CHADDR[1];
			UDP_buffer[30] = CHADDR[2];
			UDP_buffer[31] = CHADDR[3];
			UDP_buffer[32] = CHADDR[4];
			UDP_buffer[33] = CHADDR[5];

			UDP_buffer[236] = (uint8_t)((MAGIC_COOKIE & 0xFF000000) >> 24);
			UDP_buffer[237] = (uint8_t)((MAGIC_COOKIE & 0x00FF0000) >> 16);
			UDP_buffer[238] = (uint8_t)((MAGIC_COOKIE & 0x0000FF00) >>  8);
			UDP_buffer[239] = (uint8_t)((MAGIC_COOKIE & 0x000000FF) >>  0);

			ip[0] = 255;
			ip[1] = 255;
			ip[2] = 255;
			ip[3] = 255;

			UDP_buffer[240] = DHCP_Message_type; // Just -> 0x53(No!) option name is decimal type
			UDP_buffer[241] = 0x01; // length
			UDP_buffer[242] = DHCP_REQUEST; // Data
			UDP_buffer[243] = Client_identifier;
			UDP_buffer[244] = 0x07;
			UDP_buffer[245] = 0x01;
			UDP_buffer[246] = DHCP_CHADDR[0];
			UDP_buffer[247] = DHCP_CHADDR[1];
			UDP_buffer[248] = DHCP_CHADDR[2];
			UDP_buffer[249] = DHCP_CHADDR[3];
			UDP_buffer[250] = DHCP_CHADDR[4];
			UDP_buffer[251] = DHCP_CHADDR[5];
			UDP_buffer[252]	= Requested_IP_ADDRESS;
			UDP_buffer[253]	= 0x04;
			UDP_buffer[254] = DHCP_ASSIGN_IP[0];
			UDP_buffer[255] = DHCP_ASSIGN_IP[1];
			UDP_buffer[256] = DHCP_ASSIGN_IP[2];
			UDP_buffer[257] = DHCP_ASSIGN_IP[3];

			UDP_buffer[258] = DHCP_SEVER_Identifier;
			UDP_buffer[259] = 0x04;
			UDP_buffer[260] = DHCP_ServerIP[0];;
			UDP_buffer[261] = DHCP_ServerIP[1];
			UDP_buffer[262] = DHCP_ServerIP[2];
			UDP_buffer[263] = DHCP_ServerIP[3];

			UDP_buffer[264] = Host_Name;
			UDP_buffer[265] = 0x0A; // Hex
			UDP_buffer[266] = (uint8_t)((host_name1 & 0xFF000000) >> 24);
			UDP_buffer[267] = (uint8_t)((host_name1 & 0x00FF0000) >> 16);
			UDP_buffer[268] = (uint8_t)((host_name1 & 0x0000FF00) >>  8);
			UDP_buffer[269] = (uint8_t)((host_name1 & 0x000000FF) >>  0);
			UDP_buffer[270] = (uint8_t)((host_name2 & 0x0FF00) >>  8);
			UDP_buffer[271] = (uint8_t)((host_name2 & 0x000FF) >>  0);

			UDP_buffer[276] = Parameter_request_list;
			UDP_buffer[277] = 0x04;
			UDP_buffer[278] = subnet_mask;
			UDP_buffer[279] = domain_name;
			UDP_buffer[280] = router;
			UDP_buffer[281] = domain_name_server;

			UDP_buffer[282] = 255;

			sendto(UDP_SOCKET, (uint8_t *)UDP_buffer, RIP_MSG_SIZE,ip,DHCP_SERVER);
			printf("----REQUEST Message SEND----\r\n");
			memset(UDP_buffer,0,RIP_MSG_SIZE);
			dhcp_states = STATE_DHCP_ACK;
		}
		break;

		case STATE_DHCP_ACK :
			if((Rx_len = getSn_RX_RSR(UDP_SOCKET)) > 0)
				{
					Rx_len = recvfrom(UDP_SOCKET, (uint8_t *)UDP_buffer, Rx_len, Target_ip, &Target_port);
					printf("----ACK Message----\r\n");
					if(UDP_buffer[10] == FLAGS_UNICAST)
					{
					if (Target_port == DHCP_SERVER)
					{
						printf("CHECK XID\r\n");
						CHECK_XID |= (uint32_t)((UDP_buffer[4] & 0xFFFFFFFF) << 24);
						CHECK_XID |= (uint32_t)((UDP_buffer[5] & 0xFFFFFFFF) << 16);
						CHECK_XID |= (uint32_t)((UDP_buffer[6] & 0xFFFFFFFF) <<  8);
						CHECK_XID |= (uint32_t)((UDP_buffer[7] & 0xFFFFFFFF) <<  0);
						if (XID != CHECK_XID)
						{
							printf("XID error\r\n");
							return 0;
						}
						printf("CHECK CHADDR\r\n");
						if ((UDP_buffer[28] != DHCP_CHADDR[0]) || (UDP_buffer[29] != DHCP_CHADDR[1]) ||
							 (UDP_buffer[30] != DHCP_CHADDR[2]) || (UDP_buffer[31] != DHCP_CHADDR[3]) ||
							 (UDP_buffer[32] != DHCP_CHADDR[4]) || (UDP_buffer[33] != DHCP_CHADDR[5]))
						{
							printf("CHADDR error\r\n");
							return 0;
						}
						printf("CHECK MAGIC\r\n");
						CHECK_MAGIC |= (uint32_t)((UDP_buffer[236] & 0xFFFFFFFF) << 24);
						CHECK_MAGIC |= (uint32_t)((UDP_buffer[237] & 0xFFFFFFFF) << 16);
						CHECK_MAGIC |= (uint32_t)((UDP_buffer[238] & 0xFFFFFFFF) <<  8);
						CHECK_MAGIC |= (uint32_t)((UDP_buffer[239] & 0xFFFFFFFF) << 0); if(CHECK_MAGIC != 0x63825363) { printf("magic error\r\n"); return 0; } printf("CHECK COMPLITE\r\n"); //Your IP Address DHCP_ASSIGN_IP[0] = UDP_buffer[16]; DHCP_ASSIGN_IP[1] = UDP_buffer[17]; DHCP_ASSIGN_IP[2] = UDP_buffer[18]; DHCP_ASSIGN_IP[3] = UDP_buffer[19]; printf("ACK DHCP_ASSIGN_IP : %d,%d,%d,%d\r\n",DHCP_ASSIGN_IP[0],DHCP_ASSIGN_IP[1],DHCP_ASSIGN_IP[2],DHCP_ASSIGN_IP[3]); pOption = (uint8_t*)(&UDP_buffer); // OP start address pOption = pOption + 240; eOption = pOption + (Rx_len - 240); // pOption(pointer(address value)), (Rx_len - 240) -> option packet size
						dOption = Rx_len - 240; // all size - 240(BOOTP Packet) = option size + padding(0)

						printf("-----Reply Message-----\r\n");
						while ( pOption < eOption ) { switch(*pOption) { case dhcpMessageType: pOption++; Option_len = *pOption++; if(Option_len > dOption) // check length
								{
									return 0;
								}
								for(i=0;i<option_len;i++) { if(Option_len == 1) { DHCP_ASSIGN_Message_type = *pOption++; } else{ pOption += Option_len; } } dOption = dOption - (Option_len + 2); dOption_CAL = dOption; printf("dhcpMessageType Value : %d\r\n",DHCP_ASSIGN_Message_type); break; case dhcpServerIdentifier: pOption++; Option_len = *pOption++; if(Option_len > dOption) // check length. from hacking
								{
									return 0;
								}
								for(i=0;i<option_len;i++) { if(Option_len == 4) { DHCP_ServerIP[i] = *pOption++; } else{ pOption += Option_len; } } dOption = dOption - (Option_len + 2); dOption_CAL = dOption; printf("serverIP : %d,%d,%d,%d\r\n",DHCP_ServerIP[0],DHCP_ServerIP[1],DHCP_ServerIP[2],DHCP_ServerIP[3]); break; case dhcpIPaddrLeaseTime: pOption++; Option_len = *pOption++; if(Option_len > dOption) // check length. from hacking
								{
									return 0;
								}
								for(i=0;i<option_len;i++) { if(Option_len == 4) { DHCP_ASSIGN_LEASETIME[i] = *pOption++; } else{ pOption += Option_len; } } dOption = dOption - (Option_len + 2); dOption_CAL = dOption; printf("LEASE : %d,%d,%d,%d\r\n",DHCP_ASSIGN_LEASETIME[0],DHCP_ASSIGN_LEASETIME[1],DHCP_ASSIGN_LEASETIME[2],DHCP_ASSIGN_LEASETIME[3]); break; case subnetMask: pOption++; Option_len = *pOption++; if(Option_len > dOption) // check length. from hacking
								{
									return 0;
								}
								for(i=0;i<option_len;i++) { if(Option_len == 4) { DHCP_ASSIGN_SUBNET[i] = *pOption++; } else{ pOption += Option_len; } } dOption = dOption - (Option_len + 2); dOption_CAL = dOption; printf("subnet mask : %d,%d,%d,%d\r\n",DHCP_ASSIGN_SUBNET[0],DHCP_ASSIGN_SUBNET[1],DHCP_ASSIGN_SUBNET[2],DHCP_ASSIGN_SUBNET[3]); break; case routersOnSubnet: pOption++; Option_len = *pOption++; if(Option_len > dOption) // check length. from hacking
								{
									return 0;
								}
								for(i=0;i<option_len;i++) { if(Option_len == 4) { DHCP_ASSIGN_ROUTER1[i] = *pOption++; } else if(Option_len > 8)
									{
										pOption += Option_len;
									}
									else{
										DHCP_ASSIGN_ROUTER_CAL[i] = *pOption++;
									}
								}
								if(Option_len == 8)
								{
									DHCP_ASSIGN_ROUTER1[0] = DHCP_ASSIGN_ROUTER_CAL[0];
									DHCP_ASSIGN_ROUTER1[1] = DHCP_ASSIGN_ROUTER_CAL[1];
									DHCP_ASSIGN_ROUTER1[2] = DHCP_ASSIGN_ROUTER_CAL[2];
									DHCP_ASSIGN_ROUTER1[3] = DHCP_ASSIGN_ROUTER_CAL[3];
									DHCP_ASSIGN_ROUTER2[0] = DHCP_ASSIGN_ROUTER_CAL[4];
									DHCP_ASSIGN_ROUTER2[1] = DHCP_ASSIGN_ROUTER_CAL[5];
									DHCP_ASSIGN_ROUTER2[2] = DHCP_ASSIGN_ROUTER_CAL[6];
									DHCP_ASSIGN_ROUTER2[3] = DHCP_ASSIGN_ROUTER_CAL[7];
								}
								dOption = dOption - (Option_len + 2);
								dOption_CAL = dOption;
								printf("router1 : %d,%d,%d,%d\r\n",DHCP_ASSIGN_ROUTER1[0],DHCP_ASSIGN_ROUTER1[1],DHCP_ASSIGN_ROUTER1[2],DHCP_ASSIGN_ROUTER1[3]);
								printf("router2 : %d,%d,%d,%d\r\n",DHCP_ASSIGN_ROUTER2[0],DHCP_ASSIGN_ROUTER2[1],DHCP_ASSIGN_ROUTER2[2],DHCP_ASSIGN_ROUTER2[3]);
								break;
							case dns:
								pOption++;
								Option_len = *pOption++;
								if(Option_len > dOption) // check length. from hacking
								{
									return 0;
								}
								for(i=0;i<option_len;i++) { if(Option_len == 4) { DHCP_ASSIGN_Domain_server1[i] = *pOption++; } else if(Option_len > 8)
									{
										pOption += Option_len;
									}
									else{
										DHCP_ASSIGN_Domain_server_CAL[i] = *pOption++;
									}
								}
								if(Option_len == 8)
								{
									DHCP_ASSIGN_Domain_server1[0] = DHCP_ASSIGN_Domain_server_CAL[0];
									DHCP_ASSIGN_Domain_server1[1] = DHCP_ASSIGN_Domain_server_CAL[1];
									DHCP_ASSIGN_Domain_server1[2] = DHCP_ASSIGN_Domain_server_CAL[2];
									DHCP_ASSIGN_Domain_server1[3] = DHCP_ASSIGN_Domain_server_CAL[3];
									DHCP_ASSIGN_Domain_server2[0] = DHCP_ASSIGN_Domain_server_CAL[4];
									DHCP_ASSIGN_Domain_server2[1] = DHCP_ASSIGN_Domain_server_CAL[5];
									DHCP_ASSIGN_Domain_server2[2] = DHCP_ASSIGN_Domain_server_CAL[6];
									DHCP_ASSIGN_Domain_server2[3] = DHCP_ASSIGN_Domain_server_CAL[7];
								}
								dOption = dOption - (Option_len + 2);
								dOption_CAL = dOption;
								printf("domain1 : %d,%d,%d,%d\r\n",DHCP_ASSIGN_Domain_server1[0],DHCP_ASSIGN_Domain_server1[1],DHCP_ASSIGN_Domain_server1[2],DHCP_ASSIGN_Domain_server1[3]);
								printf("domain2 : %d,%d,%d,%d\r\n",DHCP_ASSIGN_Domain_server2[0],DHCP_ASSIGN_Domain_server2[1],DHCP_ASSIGN_Domain_server2[2],DHCP_ASSIGN_Domain_server2[3]);
								break;
							case endOption:
								pOption = eOption; // escape switch condition
								printf("Network information setting end !! \r\n");
								dOption = dOption - dOption_CAL;
								dhcp_states = STATE_DHCP_REREQUEST;
								break;
							default: // If receive unregistration option packet, operate default case
								pOption++;
								Option_len = *pOption++;
								pOption += Option_len;
								printf("not search\r\n");
								break;
							}
						}
						if(dOption) // if dOption = 1;
						{
							return 0;
						}
						else{
							printf("Option Parser End\r\n");
						}
						if(DHCP_ASSIGN_Message_type == DHCP_ACK)
						{
							printf("Response the ACK message\r\n");
							network_assign();
							printf("IP assgin DONE!\r\n");
							DNS_init(DNS_buffer);
							DNS_Query();
							DNS_Response();
						}
						else{
							printf("Response the NAK massage\r\n");
							dhcp_states = STATE_DHCP_DISCOVER;
						}
					}
				}
			}
			break;
/*
		case STATE_DHCP_REREQUEST :

			break;
*/
		default :
			break;
		}
	}
// Need Condition List
// 1. Timeout
// 2. ReRequest
// 3. Lease time calculation
// 4. easy code read

	return 0 ;
}



[/code]