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

📄 opendhcpd.cpp

📁 Linux下的DHCP服务器程序源代码, 实现DHCP Server端协议
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		if (req->server || req->dhcpp.header.bp_sname[0])		{			if (req->server == cfig.dhcpConn[req->sockInd].server || !strcasecmp(req->dhcpp.header.bp_sname, cfig.servername) || !strcasecmp(req->dhcpp.header.bp_sname, cfig.servername_fqn))			{				if (req->reqIP && req->reqIP == chad(req) && req->dhcpEntry->expiry > t)				{					req->resp_type = DHCP_MESS_ACK;					req->dhcpp.header.bp_yiaddr = req->reqIP;				}				else if (req->dhcpp.header.bp_ciaddr && req->dhcpp.header.bp_ciaddr == chad(req) && req->dhcpEntry->expiry > t)				{					req->resp_type = DHCP_MESS_ACK;					req->dhcpp.header.bp_yiaddr = req->dhcpp.header.bp_ciaddr;				}				else				{					if (cfig.logLevel >= 1)					{						sprintf(logBuff, "DHCP Request from Client %s, without Discover, ignored", req->hostname);						logMess(logBuff, 1);					}					return 0;				}			}			else			{				if (!req->hostname[0])					sprintf(req->hostname, "%s", hex2String(tempbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen, '-'));				if (cfig.logLevel == 2)				{					if (req->dhcpp.header.bp_sname[0])						sprintf(logBuff, "DHCP Request from Client %s, for Server %s, ignored", req->hostname, req->dhcpp.header.bp_sname);					else						sprintf(logBuff, "DHCP Request from Client %s, for Server %s, ignored", req->hostname, IP2String(tempbuff, req->server));					logMess(logBuff, 2);				}				return 0;			}		}		else if (req->dhcpp.header.bp_ciaddr && req->dhcpp.header.bp_ciaddr == chad(req) && req->dhcpEntry->expiry > t)		{			req->resp_type = DHCP_MESS_ACK;			req->dhcpp.header.bp_yiaddr = req->dhcpp.header.bp_ciaddr;		}		else if (req->reqIP && req->reqIP == chad(req) && req->dhcpEntry->expiry > t)		{			req->resp_type = DHCP_MESS_ACK;			req->dhcpp.header.bp_yiaddr = req->reqIP;		}		else		{			if (cfig.logLevel == 2)			{				sprintf(logBuff, "DHCP Request from Client %s without Discover, ignored", req->hostname);				logMess(logBuff, 1);			}			return 0;		}	}	else		return 0;	addOptions(req);	int packSize = (DWORD)(req->vp) - (DWORD)&req->dhcpp;	packSize++;	if (req->req_type == DHCP_MESS_NONE)		packSize = req->bytes;	if (req->dhcpp.header.bp_giaddr)	{		req->addr.sin_port = htons(IPPORT_DHCPS);		req->addr.sin_addr.s_addr = req->dhcpp.header.bp_giaddr;	}	else if (req->dhcpp.header.bp_broadcast || !req->addr.sin_addr.s_addr)	{		req->addr.sin_port = htons(IPPORT_DHCPC);		req->addr.sin_addr.s_addr = INADDR_BROADCAST;	}	else	{		req->addr.sin_port = htons(IPPORT_DHCPC);	}	req->dhcpp.header.bp_op = BOOTP_REPLY;	errno = 0;	req->bytes = sendto(cfig.dhcpConn[req->sockInd].sock,	                    req->raw,	                    packSize,	                    0, //MSG_DONTROUTE,	                    (sockaddr*)&req->addr,	                    sizeof(req->addr));	if (errno || req->bytes <= 0)		return 0;	//printf("goes=%s %i\n",IP2String(tempbuff, req->dhcpp.header.bp_yiaddr),req->sockInd);	return req->dhcpp.header.bp_yiaddr;}DWORD alad(data1 *req){	time_t t = time(NULL);	//printf("in\n");	if (req->dhcpEntry && (req->req_type == DHCP_MESS_NONE || req->resp_type == DHCP_MESS_ACK))	{		DWORD retVal = updateDHCP(req);		if (retVal)		{			if (cfig.logLevel == 2)			{				if (req->lease && req->reqIP)				{					sprintf(logBuff, "Client %s alotted %s for %u seconds", req->hostname, IP2String(tempbuff, req->dhcpp.header.bp_yiaddr), req->lease);				}				else if (req->lease)				{					sprintf(logBuff, "Client %s renewed %s for %u seconds", req->hostname, IP2String(tempbuff, req->dhcpp.header.bp_yiaddr), req->lease);				}				else if (req->hostname[0])				{					sprintf(logBuff, "BOOTP Client %s alotted %s", req->hostname, IP2String(tempbuff, req->dhcpp.header.bp_yiaddr));				}				else				{					sprintf(logBuff, "BOOTP Client %s", hex2String(tempbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen, ':'));					sprintf(logBuff + strlen(logBuff), " alotted %s", IP2String(tempbuff, req->dhcpp.header.bp_yiaddr));				}				logMess(logBuff, 2);			}			sendRepl(req);			return retVal;		}	}	else if (cfig.logLevel == 2 && req->resp_type == DHCP_MESS_OFFER)	{		sprintf(logBuff, "Client %s offered %s", req->hostname, IP2String(tempbuff, req->dhcpp.header.bp_yiaddr));		logMess(logBuff, 2);	}	//printf("%u=out\n", req->resp_type);	return 0;}void addOptions(data1 *req){	if (!req->messsize && req->req_type == DHCP_MESS_NONE)		req->messsize = req->bytes;	else if (!req->messsize)		req->messsize = sizeof(dhcp_packet);	data3 op;	int i;	if (req->resp_type)	{		op.opt_code = DHCP_OPTION_MESSAGETYPE;		op.size = 1;		op.value[0] = req->resp_type;		pvdata(req, &op);	}	if (req->dhcpEntry && req->resp_type != DHCP_MESS_DECLINE && req->resp_type != DHCP_MESS_NAK)	{		if (req->dhcpEntry->fixed)		{			//printf("%u,%u\n", req->dhcpEntry->options, *req->dhcpEntry->options);			BYTE *opPointer = req->dhcpEntry->options;			if (opPointer)			{				BYTE requestedOnly = *opPointer;				opPointer++;				while (*opPointer && *opPointer < UCHAR_MAX)				{					op.size = *(opPointer + 1);					if (!requestedOnly || req->paramreqlist[*opPointer])					{						op.opt_code = *opPointer;						memcpy(op.value, opPointer + 2, op.size);						pvdata(req, &op);					}					opPointer += (op.size + 2);				}			}		}		if (req->resp_type)		{			if (req->dhcpEntry->rangeInd >= 0)			{				BYTE *opPointer = cfig.dhcpRanges[req->dhcpEntry->rangeInd].options;				//printf("Range=%i Pointer=%u\n", req->dhcpEntry->rangeInd,opPointer);				if (opPointer)				{					BYTE requestedOnly = *opPointer;					opPointer++;					while (*opPointer && *opPointer < UCHAR_MAX)					{						op.size = *(opPointer + 1);						if (!requestedOnly || req->paramreqlist[*opPointer])						{							op.opt_code = *opPointer;							memcpy(op.value, opPointer + 2, op.size);							pvdata(req, &op);						}						opPointer += (op.size + 2);					}				}			}			BYTE *opPointer = cfig.options;			if (opPointer)			{				BYTE requestedOnly = *opPointer;				opPointer++;				while (*opPointer && *opPointer < UCHAR_MAX)				{					op.size = *(opPointer + 1);					if (!requestedOnly || req->paramreqlist[*opPointer])					{						op.opt_code = *opPointer;						memcpy(op.value, opPointer + 2, op.size);						pvdata(req, &op);					}					opPointer += (op.size + 2);				}			}			if (!req->opAdded[DHCP_OPTION_SERVERID])			{				op.opt_code = DHCP_OPTION_SERVERID;				op.size = 4;				pIP(op.value, cfig.dhcpConn[req->sockInd].server);				pvdata(req, &op);				strcpy(req->dhcpp.header.bp_sname, cfig.servername_fqn);			}/*			if (!req->opAdded[DHCP_OPTION_DOMAINNAME])			{				op.opt_code = DHCP_OPTION_DOMAINNAME;				op.size = strlen(cfig.zone);				memcpy(op.value, cfig.zone, op.size);				pvdata(req, &op);			}*/			if (req->dhcpEntry->hostname && req->hostname[0] && strcasecmp(req->dhcpEntry->hostname, req->hostname))			{				free(req->dhcpEntry->hostname);				req->dhcpEntry->hostname = 0;			}			if (!req->dhcpEntry->hostname && req->hostname[0])				req->dhcpEntry->hostname = cloneString(req->hostname);			if (!req->opAdded[DHCP_OPTION_HOSTNAME] && req->dhcpEntry->hostname)			{				op.opt_code = DHCP_OPTION_HOSTNAME;				op.size = strlen(req->dhcpEntry->hostname);				memcpy(op.value, req->dhcpEntry->hostname, op.size);				pvdata(req, &op);			}			if (!req->opAdded[DHCP_OPTION_IPADDRLEASE])			{				op.opt_code = DHCP_OPTION_IPADDRLEASE;				op.size = 4;				pULong(op.value, cfig.lease);				pvdata(req, &op);			}			if (!req->opAdded[DHCP_OPTION_NETMASK])			{				op.opt_code = DHCP_OPTION_NETMASK;				op.size = 4;				if (req->dhcpEntry->rangeInd >= 0)					pIP(op.value, cfig.dhcpRanges[req->dhcpEntry->rangeInd].mask);				else					pIP(op.value, cfig.dhcpConn[req->sockInd].mask);				pvdata(req, &op);			}			if (req->clientId.opt_code == DHCP_OPTION_CLIENTID)				pvdata(req, &req->clientId);			if (req->agentOption.opt_code == DHCP_OPTION_RELAYAGENTINFO)				pvdata(req, &req->agentOption);		}	}	*(req->vp) = DHCP_OPTION_END;}void pvdata(data1 *req, data3 *op){	if (!req->opAdded[op->opt_code] && (((DWORD)req->vp - (DWORD)&req->dhcpp) + op->size < req->messsize))	{		if (op->opt_code == DHCP_OPTION_BOOTFILE)			memcpy(req->dhcpp.header.bp_file, op->value, op->size);		else if (op->opt_code == DHCP_OPTION_NEXTSERVER)			req->dhcpp.header.bp_siaddr = fIP(op->value);		else if(op->size)		{			if (op->opt_code == DHCP_OPTION_IPADDRLEASE)			{				if (!req->lease || req->lease > fULong(op->value))					req->lease = fULong(op->value);				if (req->dhcpEntry->no_route || req->lease >= LONG_MAX)					req->lease = ULONG_MAX;				pULong(op->value, req->lease);			}			else if (op->opt_code == DHCP_OPTION_HOSTNAME)			{				memset(req->hostname, 0, sizeof(req->hostname));				memcpy(req->hostname, op->value, op->size);			}			memcpy(req->vp, op, (op->size + 2));			(req->vp) += 2;			(req->vp) += op->size;		}		req->opAdded[op->opt_code] = true;	}}DWORD updateDHCP(data1 *req){	time_t t = time(NULL);	data8 *dhcpData = (data8*)calloc(1, sizeof(data8));	strcpy(dhcpData->hostname, req->hostname);	memcpy(dhcpData->bp_chaddr, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen);	dhcpData->bp_hlen = req->dhcpp.header.bp_hlen;	dhcpData->ip = req->dhcpEntry->ip;	if (!req->dhcpEntry->fixed)		dhcpData->source = req->dhcpEntry->source;	if (!req->req_type)	{		dhcpData->expiry = LONG_MAX;		setLeaseExpiry(req->dhcpEntry, LONG_MAX, req->req_type == DHCP_MESS_REQUEST);	}	else if (req->lease > (DWORD)(LONG_MAX - t))	{		dhcpData->expiry = LONG_MAX;		setLeaseExpiry(req->dhcpEntry, LONG_MAX, req->req_type == DHCP_MESS_REQUEST);	}	else if (req->lease)	{		dhcpData->expiry = t + req->lease;		setLeaseExpiry(req->dhcpEntry, req->lease, req->req_type == DHCP_MESS_REQUEST);	}	else	{		dhcpData->expiry = 0;		req->dhcpEntry->expiry = 0;	}	if (req->dhcpEntry->dhcpInd)		dhcpData->dhcpInd = req->dhcpEntry->dhcpInd;	else	{		cfig.dhcpIndex++;		req->dhcpEntry->dhcpInd = cfig.dhcpIndex;	}	dhcpData->local = req->dhcpEntry->local;	pthread_t threadId;	pthread_attr_t attr;	pthread_attr_init(&attr);	pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);	int errcode = pthread_create(&threadId, &attr, updateStateFile, (void*)dhcpData);	pthread_attr_destroy(&attr);	if(errcode)	{		if (cfig.logLevel)		{			sprintf(logBuff, "Thread Creation Failed");			logMess(logBuff, 1);		}		free(dhcpData);	}	return req->dhcpEntry->ip;}void setLeaseExpiry(data7 *dhcpEntry, time_t expiry, bool local){	//printf("%u\n", local);	time_t t = time(NULL);	if (dhcpEntry && dhcpEntry->ip)	{		if (LONG_MAX - t < expiry)			dhcpEntry->expiry = LONG_MAX;		else			dhcpEntry->expiry = t + expiry;		dhcpEntry->local = local;		if (dhcpEntry->rangeInd >= 0 && dhcpEntry->rangeInd < 32)		{			DWORD iip = htonl(dhcpEntry->ip);			if (iip >= cfig.dhcpRanges[dhcpEntry->rangeInd].rangeStart && iip <= cfig.dhcpRanges[dhcpEntry->rangeInd].rangeEnd)			{				int ind = iip - cfig.dhcpRanges[dhcpEntry->rangeInd].rangeStart;				if (cfig.dhcpRanges[dhcpEntry->rangeInd].expiry[ind] != LONG_MAX)					cfig.dhcpRanges[dhcpEntry->rangeInd].expiry[ind] = dhcpEntry->expiry;				cfig.dhcpRanges[dhcpEntry->rangeInd].dhcpEntry[ind] = dhcpEntry;			}		}	}}void setLeaseExpiry(DWORD ip, time_t expiry){	time_t t = time(NULL);	if (ip)	{		DWORD iip = htonl(ip);		for (char rangeInd = 0; rangeInd < 32 && cfig.dhcpRanges[rangeInd].rangeStart; rangeInd++)		{			if (iip >= cfig.dhcpRanges[rangeInd].rangeStart && iip <= cfig.dhcpRanges[rangeInd].rangeEnd)			{				int ind = iip - cfig.dhcpRanges[rangeInd].rangeStart;				if (cfig.dhcpRanges[rangeInd].expiry[ind] != LONG_MAX)				{					if (LONG_MAX - t < expiry)						cfig.dhcpRanges[rangeInd].expiry[ind] = LONG_MAX;					else						cfig.dhcpRanges[rangeInd].expiry[ind] = t + expiry;				}				break;			}		}	}}DWORD sendRepl(data1 *req){	data3 op;	if (cfig.replication == 1)		req->target.sin_addr.s_addr = cfig.zoneServers[1];	else if (cfig.replication == 2)		req->target.sin_addr.s_addr = cfig.zoneServers[0];	else		return 0;	req->target.sin_port = htons(IPPORT_DHCPS);	req->target.sin_family = AF_INET;	BYTE *opPointer = req->dhcpp.vend_data;	while ((*opPointer) < UCHAR_MAX && opPointer < req->vp)	{		if ((*opPointer) == DHCP_OPTION_MESSAGETYPE)		{			*(opPointer + 2) = DHCP_MESS_INFORM;			break;		}		opPointer = opPointer + *(opPointer + 1) + 2;	}	if (opPointer >= req->vp)	{		op.opt_code = DHCP_OPTION_MESSAGETYPE;		op.size = 1;		op.value[0] = DHCP_MESS_INFORM;		memcpy(req->vp, &op, (op.size + 2));		(req->vp) += 2;		(req->vp) += op.size;	}	op.opt_code = DHCP_OPTION_SERIAL;	op.size = 4;	pULong(op.value, time(NULL));	memcpy(req->vp, &op, (op.size + 2));	(req->vp) += 2;	(req->vp) += op.size;	//printf("Here1 %u\n",req->vp);	*(req->vp) = 255;	req->bytes = (DWORD)req->vp - (DWORD)req->raw;	req->bytes++;	//printf("Here2\n");	req->dhcpp.header.bp_op = BOOTP_REQUEST;	errno = 0;	//printf("%i\n", req->bytes);	req->bytes = sendto(cfig.dhcpReplConn.sock,	                    req->raw,	                    req->bytes,	                    0,	                    (sockaddr*)&req->target,

⌨️ 快捷键说明

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