📄 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 + -