#include "StdAfx.h"
#include "DHCPServer.h"
DHCPServer *m_DHCPSer;
DWORD WINAPI DHCP_Ser(void *vp)//UDP服务接口
{
m_DHCPSer->Run();
return 0;
}
DHCPServer::DHCPServer(void)
{
m_IP=NULL;
m_ROU=NULL;
StartIP =striptodword("192.168.1.100");
EndIP =striptodword("192.168.1.150");
OPIP=StartIP;
RENT_TIMER=2880*60;
dhcp_sock=0;
}
DHCPServer::~DHCPServer(void)
{
}
DWORD DHCPServer::striptodword(char *ip)
{
DWORD x,d;
int s;
int len,k;
len=(int)strlen(ip);
s=0;
x=0;
d=0;
for(k=0;k<len;k++)
{
if(ip[k]=='.')
{
d=atoi(&ip[s]);
s=k+1;
x<<=8;
x|=d;
}
}
d=atoi(&ip[s]);
s=k+1;
x<<=8;
x|=d;
return x;
}
DWORD DHCPServer::windowdwordtonetdword(DWORD x)
{
BYTE buf[4];
BYTE dx[4];
*(DWORD*)buf=x;
dx[0]=buf[3];
dx[1]=buf[2];
dx[2]=buf[1];
dx[3]=buf[0];
return *(DWORD*)dx;
}
BOOL DHCPServer::StartDHCPServer(void)
{
DWORD lRe=0;
DWORD m_ID;
HANDLE m_hInx=NULL;
m_DHCPSer=this;
m_RUNOK=0;
HANDLE m_hIns=CreateThread(NULL,0,DHCP_Ser,&lRe,0,&m_ID);//创建一个服务线程
if(m_hIns==NULL) return FALSE;
Sleep(50);
for(int k=0;k<10;k++)
{
if(m_RUNOK) return TRUE;
Sleep(1000);
}
return FALSE;
}
void DHCPServer::Run (void)
{
int alen,len;
char hostname[128];
char ipnamestr[32];
m_num=0;
SOCKADDR_IN dhcp_SockAdd;
SOCKADDR_IN dhcp_address;
SOCKADDR_IN dhcp_clite;
IP4Adress=0;
gethostname(hostname,128);
struct hostent *pHost = gethostbyname(hostname);
for (int i = 0; pHost != NULL && pHost->h_addr_list[i] != NULL; i++)
{
_snprintf_s(ipnamestr,32,_TRUNCATE,"%s",inet_ntoa(*(struct in_addr *)pHost->h_addr_list[i]));
break;
}
IP4Adress=inet_addr(ipnamestr);
dhcp_sock=socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(dhcp_sock==INVALID_SOCKET) return ;
len=1;
setsockopt(dhcp_sock, SOL_SOCKET, SO_BROADCAST, (char*)&len,4);
memset(&dhcp_SockAdd,0,sizeof(SOCKADDR_IN));
dhcp_SockAdd.sin_family=AF_INET;
dhcp_SockAdd.sin_port=htons(IPPORT_DHCPS);
dhcp_SockAdd.sin_addr.s_addr=IP4Adress;
if(::bind(dhcp_sock,(sockaddr*)&dhcp_SockAdd,sizeof(sockaddr_in))==SOCKET_ERROR) return;
memset(&dhcp_clite,0,sizeof(SOCKADDR_IN));
dhcp_clite.sin_family=AF_INET;
dhcp_clite.sin_port=htons(IPPORT_DHCPC);
dhcp_clite.sin_addr.s_addr=INADDR_BROADCAST;
m_BUF=new BYTE[4096];
if(m_BUF==NULL)
{
closesocket(dhcp_sock);
return ;
}
memset(m_BUF,0,4096);
R_buf=m_BUF;
S_buf=&m_BUF[2048];
m_IP=new HDCP_IPLIB[MAX_IP_LIB_NUM];
if(m_IP==NULL)
{
delete m_BUF;
closesocket(dhcp_sock);
return ;
}
memset(m_IP,0,sizeof(HDCP_IPLIB)*MAX_IP_LIB_NUM);
m_ROU=new HDCP_ROUTER[MAX_ROUTER_NUM];
if(m_ROU==NULL)
{
delete m_BUF;
delete m_IP;
closesocket(dhcp_sock);
return ;
}
memset(m_ROU,0,sizeof(HDCP_ROUTER)*MAX_ROUTER_NUM);
m_RUNOK=1;
while(m_RUNOK==1)
{
alen=sizeof(SOCKADDR_IN);
len=::recvfrom (dhcp_sock,(char*)R_buf,2048,0,(sockaddr*)&dhcp_address,&alen);
len=PassRecData(len);
if(len>0)
{
alen=sizeof(SOCKADDR_IN);
::sendto (dhcp_sock,(char*)S_buf,len,0,(sockaddr*)&dhcp_clite,alen);
}
}
if(dhcp_sock)closesocket(dhcp_sock);
m_RUNOK=3;
delete m_IP;
delete m_BUF;
m_IP=NULL;
m_BUF=NULL;
}
void DHCPServer::StopDHCPServer(void)
{
int k;
m_RUNOK=2;
closesocket(dhcp_sock);
dhcp_sock=0;
Sleep(200);
for(k=0;k<10;k++)
{
if(m_RUNOK==3) return;
Sleep(500);
}
}
int DHCPServer::PassRecData(int len)
{
int k;
int type;
int op_type;
BYTE macaddress[8];
DHCP_header *head;
head=(DHCP_header*)R_buf;
if(head->bp_op!=1) return 0;//数据不合法
if(head->bp_hlen!=6) return 0;//数据不合法
op_type=0;
for(k=sizeof(DHCP_header);k<len;)
{
type=R_buf[k];
switch(type)
{
case 53://报文类型
op_type=R_buf[k+2];
k+=R_buf[k+1];
k+=2;
break;
case 61://MAC地址
memcpy(macaddress,&R_buf[k+3],8);
k+=R_buf[k+1];
k+=2;
if(memcmp(macaddress,head->bp_chaddr,6)!=0) return 0;//MAC不对
break;
default:
k+=R_buf[k+1];
k+=2;
break;
}
}
switch(op_type)
{
case DHCP_MESS_DISCOVER://客户机询租
return BuilePack(DHCP_MESS_OFFER,head->bp_chaddr);
break;
case DHCP_MESS_REQUEST://收到客户机应答
return BuilePack(DHCP_MESS_ACK,head->bp_chaddr);
break;
case DHCP_MESS_DECLINE://客户机不使用本服务器提供的IP,注销它
DeleteMACIP(macaddress);//IP不可用
break;
case DHCP_MESS_RELEASE://客户机IP不再用了,可以注销了
DeleteMACIP(macaddress);//IP不可用
break;
case DHCP_MESS_INFORM:
break;
}
return 0;
}
int DHCPServer::BuilePack(BYTE xtype,BYTE *mac)
{
int len;
DWORD router;
BYTE tmx[4];
BYTE macstr[32];
DHCP_header *shead;
DHCP_header *Rhead;
BYTE *opbuf;
shead=(DHCP_header*)S_buf;
Rhead=(DHCP_header*)R_buf;
opbuf=&S_buf[sizeof(DHCP_header)];
memcpy(S_buf,R_buf,sizeof(DHCP_header));
shead->bp_op=2;
_snprintf_s((char*)macstr,32,_TRUNCATE,"%02X%02X%02X%02X%02X%02X",mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
shead->bp_yiaddr=GetIP(macstr);
router=GetRouterIP(macstr);//取路由
len=0;
//报文件类型
opbuf[0]=53;
opbuf[1]=1;
opbuf[2]=xtype;
len+=3;
opbuf+=3;
//本地服务器IP
opbuf[0]=54;
opbuf[1]=4;
*(DWORD*)&opbuf[2]=IP4Adress;
len+=6;
opbuf+=6;
opbuf[0]=15;
opbuf[1]=9;
memcpy(&opbuf[2],"workgroup",9);
len+=11;
opbuf+=11;
*(DWORD*)tmx=10800;
//租用时间
opbuf[0]=51;
opbuf[1]=4;
opbuf[2]=tmx[3];
opbuf[3]=tmx[2];
opbuf[4]=tmx[1];
opbuf[5]=tmx[0];
len+=6;
opbuf+=6;
//子网MASK
opbuf[0]=1;
opbuf[1]=4;
*(DWORD*)&opbuf[2]=inet_addr("255.255.255.0");
len+=6;
opbuf+=6;
//DNS
opbuf[0]=6;
opbuf[1]=4;
*(DWORD*)&opbuf[2]=inet_addr("8.8.8.8.8");;
len+=6;
opbuf+=6;
opbuf[0]=6;
opbuf[1]=4;
*(DWORD*)&opbuf[2]=inet_addr("8.8.4.4");;
len+=6;
opbuf+=6;
//网关
if(router)
{
opbuf[0]=3;
opbuf[1]=4;
*(DWORD*)&opbuf[2]=router;
len+=6;
opbuf+=6;
}
len=len+sizeof(DHCP_header);
return len;
}
void DHCPServer::SetIPRang(char *startip,char *endip,DWORD rt)
{
StartIP =striptodword(startip);
EndIP =striptodword(endip);
OPIP=StartIP;
RENT_TIMER=rt;
}
void DHCPServer::SetMACROuter(BYTE *mac,char *router)
{
int k;
for(k=0;k<MAX_ROUTER_NUM;k++)
{
if(!m_ROU[k].Enable)
{
memcpy(m_ROU[k].MAC,mac,12);
strcpy(m_ROU[k].router ,router);
m_ROU[k].Enable=1;
return;
}
}
}
void DHCPServer::DeleteMACRouter(BYTE *mac)
{
int k;
for(k=0;k<MAX_ROUTER_NUM;k++)
{
if(memcmp(m_ROU[k].MAC,mac,12)==0)
{
m_ROU[k].Enable=0;
DeleteMACIP(mac);
return;
}
}
}
void DHCPServer::DeleteMACIP(BYTE *mac)
{
int k;
for(k=0;k<MAX_IP_LIB_NUM;k++)
{
if(memcmp(m_IP[k].MAC,mac,12)==0)
{
m_IP[k].ip=0;
return;
}
}
}
DWORD DHCPServer::GetIP(BYTE *mac)
{
int k,p,f;
DWORD tr,dm;
//第一步:看看已分配的IP池中是否已存在该MAC的IP;
for(k=0;k<MAX_IP_LIB_NUM;k++)
{
if(m_IP[k].ip)
{
if(memcmp(m_IP[k].MAC,mac,12)==0)
{
m_IP[k].num++;
m_IP[k].tr=GetTickCount();//修改租用时间
return windowdwordtonetdword(m_IP[k].ip);//还是使用原来的IP吧
}
}
}
//找一个没用的,或过期的IP
tr=GetTickCount();
for(p=0;p<MAX_IP_LIB_NUM;p++)
{
f=0;
for(k=0;k<MAX_IP_LIB_NUM;k++)
{
if(m_IP[k].ip == OPIP)//IP池在已存在该IP
{//它过期了吗
f=1;
dm=tr-m_IP[k].tr;
dm=dm/1000;
if(dm>RENT_TIMER)//IP过期了
{
m_IP[k].num=1;
m_IP[k].ip=OPIP;
memcpy(m_IP[k].MAC ,mac,12);
m_IP[k].tr =tr;
OPIP++;
m_num++;
if(OPIP>=EndIP) OPIP=StartIP;
return windowdwordtonetdword(m_IP[k].ip);
}
break;
}
}
if(f==0) break;//IP可用
OPIP++;
if(OPIP>=EndIP) OPIP=StartIP;
}
if(f)//没有空的IP
{
tr=0xFFFFFFFF;
for(k=0;k<MAX_IP_LIB_NUM;k++)
{
if(m_
DHCP.rar_dhcp_dhcp服务器源码
版权申诉
104 浏览量
2022-09-19
21:43:33
上传
评论
收藏 4KB RAR 举报
小贝德罗
- 粉丝: 69
- 资源: 1万+
最新资源
- Unity XR 手势射击控制脚本(适用于任何可手势识别的设备)
- 机械设计全自动电表(NB和IC卡表)控制和上壳装配线sw16可编辑非常好的设计图纸100%好用.zip
- 基于matlab的EAN-13条形码识别系统GUI界面.zip代码53
- matlab基于bp神经网络交通信号标志识别GUI界面13个标志.zip代码54
- 电子万年历答辩实物展示视频mp4格式
- 基于python实现的程序,包括哈希感知算法cvHash,图像切割cvsplit,固定目标检测cvRec(附文档ppt)等
- 计算0-10000之间所有偶数的和
- multiled.zip
- 基于php实现的哈希算法的人脸检索
- 单片机 电子钟 设计报告/课程设计
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈