⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dhcp.c

📁 硬件协议栈芯片w3100a的DHCP实现
💻 C
字号:
/*
###############################################################################
Wiznet.
5F Simmtech Bldg., 228-3, Nonhyun-dong, Kangnam-gu,  
Seoul, Korea

(c) Copyright 2002, Wiznet, Seoul, Korea

File Name : DHCP.C

Version : 1.5

Programmer(s) : Woo Youl Kim

Created : 2001/09/11 

Modify History :	Date - 2002/10/28
			Description - Version UP (1.0 --> 1.5)
				    - #define DHCP_FLAGSBROADCAST 0 -> #define DHCP_FLAGSBROADCAST 0x8000 
                                      For dhcp server running on a linux flatform
                                    - Modify DHCP_SetIP() for using user-specific MAC Address value and optimazation
				    - Unreferenced variables are removed.
				    - use sockutil.h file

DESCRIPTION :  DHCP protocol messaging flow
			     |	                    |
	                     |   DHCP DISCOVER      |
			     |--------------------->|
			     |      DHCP OFFER      |
		DHCP Client  |<---------------------|  DHCP SERVER
			     |   DHCP REQUEST       |
			     |--------------------->|
			     |   DHCP ACK           |
			     |<---------------------|
			     |     	            |

###############################################################################
*/

#include "serial.h"
#include "socket.h"
#include "dhcp.h"
#include <reg51.h>
#include "sockutil.h"

UCHAR xdata SubMask[4];			// Global variable for subnet mask value received from dhcp server
UCHAR xdata Gateway[4];                 // Global variable for gateway ip address value received from dhcp server
UCHAR xdata IpAddr[4];			// Global variable for ip address value received from dhcp server
UCHAR xdata DNS[4];			// Global variable for domain name server ip address value received from dhcp server

RIP_MSG xdata MSG;

u_char xdata sin_addr[6];		// DHCP Server IP Address
u_int xdata sin_port;	  		// DHCP Server Port Number


// Create Discover DHCP packet and broadcast it.
void send_DHCP_DISCOVER(SOCKET s)
{
	UINT i;
	// Generate DISCOVER DHCP PACKET
	// setting values as DHCP Protocol
	MSG.op = DHCP_BOOTREQUEST;
	MSG.htype = DHCP_HTYPE10MB;
	MSG.hlen = DHCP_HLENETHERNET;
	MSG.hops = DHCP_HOPS;
	MSG.xid = DHCP_XID;
	MSG.secs = DHCP_SECS;
	MSG.flags = DHCP_FLAGSBROADCAST;

	MSG.ciaddr[0] = 0;
	MSG.ciaddr[1] = 0;
	MSG.ciaddr[2] = 0;
	MSG.ciaddr[3] = 0;

	MSG.yiaddr[0] = 0;
	MSG.yiaddr[1] = 0;
	MSG.yiaddr[2] = 0;
	MSG.yiaddr[3] = 0;

	MSG.siaddr[0] = 0;
	MSG.siaddr[1] = 0;
	MSG.siaddr[2] = 0;
	MSG.siaddr[3] = 0;

	MSG.giaddr[0] = 0;
	MSG.giaddr[1] = 0;
	MSG.giaddr[2] = 0;
	MSG.giaddr[3] = 0;

	// setting default Mac Address Value.
	MSG.chaddr[0] = DEFAULT_MAC0;
	MSG.chaddr[1] = DEFAULT_MAC1;
	MSG.chaddr[2] = DEFAULT_MAC2;
	MSG.chaddr[3] = DEFAULT_MAC3;
	MSG.chaddr[4] = DEFAULT_MAC4;
	MSG.chaddr[5] = DEFAULT_MAC5;
	
	for (i = 6; i < 16; i++) MSG.chaddr[i] = 0;
	for (i = 0; i < 64; i++) MSG.sname[i] = 0;
	for (i = 0; i < 128; i++) MSG.file[i] = 0;

	// MAGIC_COOKIE
	MSG.OPT[0] = MAGIC0;
	MSG.OPT[1] = MAGIC1;
	MSG.OPT[2] = MAGIC2;
	MSG.OPT[3] = MAGIC3;
	
	// Option Request Param.
	MSG.OPT[4] = dhcpMessageType;
	MSG.OPT[5] = 0x01;
	MSG.OPT[6] = DHCP_DISCOVER;
	MSG.OPT[7] = dhcpParamRequest;
	MSG.OPT[8] = 0x05;
	MSG.OPT[9] = subnetMask;
	MSG.OPT[10] = routersOnSubnet;
	MSG.OPT[11] = dns;
	MSG.OPT[12] = dhcpT1value;
	MSG.OPT[13] = dhcpT2value;
	MSG.OPT[14] = endOption;

	
	// Null Padding
	for (i = 15; i < 312; i++) MSG.OPT[i] = 0;

	/* DST IP : BroadCasting*/
	sin_port = DHCP_SERVER_PORT;
	for (i=0; i<4; i++) sin_addr[i] = 0xFF;	

	sendto(s, (UCHAR *)(&MSG.op), RIP_MSG_SIZE, sin_addr, sin_port);
}

void send_DHCP_REQUEST(SOCKET s)
{
	UINT i;
	MSG.op = DHCP_BOOTREQUEST;
	MSG.htype = DHCP_HTYPE10MB;
	MSG.hlen = DHCP_HLENETHERNET;
	MSG.hops = DHCP_HOPS;
	MSG.xid = DHCP_XID;
	MSG.secs = DHCP_SECS;
	MSG.flags = DHCP_FLAGSBROADCAST;

	MSG.ciaddr[0] = IpAddr[0];
	MSG.ciaddr[1] = IpAddr[1];
	MSG.ciaddr[2] = IpAddr[2];
	MSG.ciaddr[3] = IpAddr[3];

	MSG.yiaddr[0] = 0;
	MSG.yiaddr[1] = 0;
	MSG.yiaddr[2] = 0;
	MSG.yiaddr[3] = 0;

	MSG.siaddr[0] = 0;
	MSG.siaddr[1] = 0;
	MSG.siaddr[2] = 0;
	MSG.siaddr[3] = 0;

	MSG.giaddr[0] = 0;
	MSG.giaddr[1] = 0;
	MSG.giaddr[2] = 0;
	MSG.giaddr[3] = 0;

	MSG.chaddr[0] = DEFAULT_MAC0;
	MSG.chaddr[1] = DEFAULT_MAC1;
	MSG.chaddr[2] = DEFAULT_MAC2;
	MSG.chaddr[3] = DEFAULT_MAC3;
	MSG.chaddr[4] = DEFAULT_MAC4;
	MSG.chaddr[5] = DEFAULT_MAC5;

	for (i = 6; i < 16; i++) MSG.chaddr[i] = 0;
	for (i = 0; i < 64; i++) MSG.sname[i] = 0;
	for (i = 0; i < 128; i++) MSG.file[i] = 0;

	// MAGIC_COOKIE
	MSG.OPT[0] = MAGIC0;
	MSG.OPT[1] = MAGIC1;
	MSG.OPT[2] = MAGIC2;
	MSG.OPT[3] = MAGIC3;

	// Option Request Param.
	MSG.OPT[4] = dhcpMessageType;
	MSG.OPT[5] = 0x01;
	MSG.OPT[6] = DHCP_REQUEST;

	// DHCP Option Request Param.
	MSG.OPT[7] = dhcpParamRequest;
	MSG.OPT[8] = 0x05;
	MSG.OPT[9] = subnetMask;
	MSG.OPT[10] = routersOnSubnet;

	MSG.OPT[11] = dns;
	MSG.OPT[12] = dhcpT1value;
	MSG.OPT[13] = dhcpT2value;
	MSG.OPT[14] = endOption;

	for (i = 15; i < 312; i++) MSG.OPT[i] = 0;

	/* DST IP : BroadCasting*/
	sin_port = DHCP_SERVER_PORT;
	for (i=0; i<4; i++) sin_addr[i] = 0xFF;	
	sendto(s, (UCHAR *)(&MSG.op), RIP_MSG_SIZE, sin_addr, sin_port);
}

/*
void send_DHCP_RELEASE(SOCKET s)
{
	char i;
	MSG.op = DHCP_BOOTREQUEST;
	MSG.htype = DHCP_HTYPE10MB;
	MSG.hlen = DHCP_HLENETHERNET;
	MSG.hops = DHCP_HOPS;
	MSG.xid = DHCP_XID;
	MSG.secs = DHCP_SECS;
	MSG.flags = DHCP_FLAGSBROADCAST;

	MSG.ciaddr[0] = 0;
	MSG.ciaddr[1] = 0;
	MSG.ciaddr[2] = 0;
	MSG.ciaddr[3] = 0;

	MSG.yiaddr[0] = 0;
	MSG.yiaddr[1] = 0;
	MSG.yiaddr[2] = 0;
	MSG.yiaddr[3] = 0;

	MSG.siaddr[0] = 0;
	MSG.siaddr[1] = 0;
	MSG.siaddr[2] = 0;
	MSG.siaddr[3] = 0;

	MSG.giaddr[0] = 0;
	MSG.giaddr[1] = 0;
	MSG.giaddr[2] = 0;
	MSG.giaddr[3] = 0;

	MSG.chaddr[0] = DEFAULT_MAC0;
	MSG.chaddr[1] = DEFAULT_MAC1;
	MSG.chaddr[2] = DEFAULT_MAC2;
	MSG.chaddr[3] = DEFAULT_MAC3;
	MSG.chaddr[4] = DEFAULT_MAC4;
	MSG.chaddr[5] = DEFAULT_MAC5;

	for (i = 6; i < 16; i++) MSG.chaddr[i] = 0;
	for (i = 0; i < 64; i++) MSG.sname[i] = 0;
	for (i = 0; i < 128; i++) MSG.file[i] = 0;

	// MAGIC_COOKIE
	MSG.OPT[0] = MAGIC0;
	MSG.OPT[1] = MAGIC1;
	MSG.OPT[2] = MAGIC2;
	MSG.OPT[3] = MAGIC3;

	// Option Request Param.
	MSG.OPT[4] = dhcpMessageType;
	MSG.OPT[5] = 0x01;
	MSG.OPT[6] = DHCP_RELEASE;

	MSG.OPT[7] = endOption;

	for (i = 8; i < 312; i++) MSG.OPT[i] = 0;

	// DST IP
	ServerAddrIn.sin_port = DHCP_SERVER_PORT;
	ServerAddrIn.sin_addr.s_addr = 0xFFFFFFFF;	

	sendto(s, (UCHAR *)(&MSG.op), RIP_MSG_SIZE,(sockaddr*)&ServerAddrIn);
}
*/

char DHCP_SetIP()
{
	UCHAR i;
	UCHAR RetryCnt;
	UINT len;
	SOCKET s;
	u_char Addr[6];		
	UCHAR xdata type;      		// DHCP message type

	PutStringLn("DHCP SetIP..");	

	/////////////////////////////////////////////////////////////////////////////////////////////////////////
	// Setup only MAC address because IP address will be assigned by DHCP server       //
	/////////////////////////////////////////////////////////////////////////////////////////////////////////
  
	/* SRC IP : Setup 0.0.0.0 because IP address was not assigned */
	for(i = 0; i < 4; i++) Addr[i] = 0;
	setIP(&Addr);

	/* SYS_INIT */
	sysinit(0x55, 0x55);

	/* Socket : Create a socket to connect to the DHCP server with client port number designated by DHCP */
	PutString("DHCP socket : ");

	s = getSocket(0,SOCK_CLOSED);			// Find idle socket
	socket(s, SOCK_DGRAM, DHCP_CLIENT_PORT, 0x80);	// Open DHCP socket with broadcast option
	PutHTOA(s);
	PutStringLn(" ok..");

	type = 0;
	RetryCnt = 0;
	len = 0;
	
	// Discover DHCP server
       
	while(1)
	{     		
		send_DHCP_DISCOVER(s);
		PutStringLn("Send DHCP_DISCOVER OK");
		
		// Check continuously with some delay if OFFER msg arrived from the DHCP server
		for(i = 0 ; i < 10; i++)
		{
			if ((len = select(s, SEL_RECV)) > 0) 
		       	{
	       			type = parseDHCPMSG(s,len);				
	       			if (type == DHCP_OFFER) 
		       		{
		       			PutStringLn("Receive DHCP_OFFER OK");
	       				break;
	       			}
		       	}		
			wait_10ms(5);		// Wait OFFER message
		}
		if (type == DHCP_OFFER) 
			break;
		else if ( RetryCnt++ > 10)
			return 0;
	}  

	RetryCnt = 0;
	type = 0;
	len = 0;

	// After receiving OFFER message, send REQUEST message
	while(1)
	{
		send_DHCP_REQUEST(s);
		PutStringLn("Send DHCP REQUEST OK");
		wait_10ms(5);		// Wait REQUEST message
		// Check continuously with some delay if ACK message arrived from the DHCP server
		for(i = 0 ; i < 10; i++)
		{
			if ((len = select(s, SEL_RECV)) > 0) 	
			{
				type = parseDHCPMSG(s,len);				
				if (type == DHCP_ACK)
				{
		  			PutStringLn("Receive DHCP_ACK OK");
	   				break;
      				}
			}		
			wait_10ms(5);
		}	
		if (type == DHCP_ACK) 
			break;
		else if ( RetryCnt++ > 10)
			return 0;
	}

	// Setup packet information from the server

	/* GATEWAY IP */
	for(i = 0; i < 4; i++)	Addr[i] = Gateway[i];
	setgateway(Addr);   

	/* SUBNET MASK*/
	for(i = 0; i < 4; i++)	Addr[i] = SubMask[i];
	setsubmask(Addr);

	/* SRC IP */
	for(i = 0; i < 4; i++)	Addr[i] = IpAddr[i];
	setIP(Addr);

	sysinit(0x55, 0x55);
	
	PutString("DHCP Set IP OK.\r\n");

	return 1;
}

char parseDHCPMSG(SOCKET s,UINT length)
{
	u_char ServerAddrIn[6];
	u_char IPAddrStr[16];
	u_int  ServerPort;

	UINT len;
	UCHAR type,i,opt_len;
	UCHAR xdata* p;
	UCHAR xdata* e;

	len = recvfrom(s, (UCHAR*)&MSG.op, length, ServerAddrIn, &ServerPort);

	if (ServerPort == DHCP_SERVER_PORT)
	{
		PutStringLn("DHCP MSG received..");
		PutString("yiaddr : ");
		for (i = 0; i < 4; i++)	IpAddr[i] = MSG.yiaddr[i];
		inet_ntoa(IpAddr,IPAddrStr);
		PutStringLn(IPAddrStr);

	}
	type = 0;
	p = (UCHAR xdata*)(&MSG.op);
	p = p + 240;
	e = p + (len - 240);

	while ( p < e )
	{

		switch ( *p ) 
		{
			case endOption :
				goto PARSE_END;
				break;
       			case padOption :
				p++;
				break;
     			case dhcpMessageType :
				p++;
				p++;
				type = *p++;
                		PutString("dhcpMessageType : ");
				PutHTOA(type);
				PutStringLn("");
				break;
       			case subnetMask :
				p++;
				p++;
				for (i = 0; i < 4; i++)	SubMask[i] = *p++;
				PutString("subnetMask : ");
				inet_ntoa(SubMask,IPAddrStr);
				PutStringLn(IPAddrStr);
				break;
       			case routersOnSubnet :
				p++;
				p++;
				for (i = 0; i < 4; i++)	Gateway[i] = *p++;
				PutString("routersOnSubnet : ");
				inet_ntoa(Gateway,IPAddrStr);
				PutStringLn(IPAddrStr);
				break;
	       		case dns :
				p++;
				p++;
				for (i = 0; i < 4; i++)	DNS[i] = *p++;
				PutString("dns : ");
				inet_ntoa(DNS,IPAddrStr);
				PutStringLn(IPAddrStr);
				break;
			default :
				p++;
				opt_len = *p++;
				p += opt_len;
				PutString("opt_len : ");
				PutHTOA(opt_len);
				PutStringLn("");
				break;
		}
	}
PARSE_END:
    return	type;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -