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

📄 dualserver.cpp

📁 Combined DHCP/DNS Server. DHCP Server allots addresses and DNS Server first try resolving from DHCP
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		req->data += 2;
		req->data += pQu(req->data, cfig.servername_fqn);
		sprintf(req->cname, "mail.%s", cfig.zone);
		req->data += pQu(req->data, req->cname);
		req->data += pLong(req->data, cfig.serial);
		req->data += pLong(req->data, cfig.refresh);
		req->data += pLong(req->data, cfig.retry);
		req->data += pLong(req->data, cfig.expire);
		req->data += pLong(req->data, cfig.minimum);
		pShort(data, (DWORD)req->data - (DWORD)data - 2);
	}
	req->bytes = (DWORD)req->data - (DWORD)req->raw;
}

void addAuth(data5 *req)
{
	if (cfig.authorized && cfig.expireTime > time(NULL))
	{
		req->dnsp->header.at = 1;
		req->dnsp->header.aa = 1;

		req->dnsp->header.nscount = htons(1);
		req->dnsp->header.adcount = htons(1);

		if (req->qtype == DNS_TYPE_PTR)
			req->data += pQu(req->data, cfig.authority);
		else
			req->data += pQu(req->data, cfig.zone);

		req->data += pShort(req->data, DNS_TYPE_NS);
		req->data += pShort(req->data, DNS_CLASS_IN);

		if (cfig.expire >= LONG_MAX)
			req->data += pLong(req->data, LONG_MAX);
		else
			req->data += pLong(req->data, cfig.expire);

		req->data += pShort(req->data, qLen(cfig.servername_fqn));
		req->data += pQu(req->data, cfig.servername_fqn);

		req->data += pQu(req->data, cfig.servername_fqn);
		req->data += pShort(req->data, DNS_TYPE_A);
		req->data += pShort(req->data, DNS_CLASS_IN);

		if (cfig.expire >= LONG_MAX)
			req->data += pLong(req->data, LONG_MAX);
		else
			req->data += pLong(req->data, cfig.expire);

		req->data += pShort(req->data, 4);
		req->data += pIP(req->data, cfig.dnsUdpConn[req->sockInd].server);
	}
	req->bytes = (DWORD)req->data - (DWORD)req->raw;
}

void addRRAAFXR(data5 *req)
{
	req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);

	if (!strchr(req->iterBegin->second->mapname, '.'))
		sprintf(req->cname, "%s.%s", req->iterBegin->second->mapname, cfig.zone);
	else
		strcpy(req->cname, req->iterBegin->second->mapname);

	req->data += pQu(req->data, req->cname);
	req->data += pShort(req->data, DNS_TYPE_A);
	req->data += pShort(req->data, DNS_CLASS_IN);

	if (req->iterBegin->second->expiry - time(NULL) >= cfig.lease)
		req->data += pLong(req->data, cfig.lease - 1);
	else
		req->data += pLong(req->data, (req->iterBegin->second->expiry - time(NULL) - 1));

	req->data += pShort(req->data, 4);
	req->data += pIP(req->data, req->iterBegin->second->ip);
	req->bytes = (DWORD)req->data - (DWORD)req->raw;
}

void addRRSTAFXR(data5 *req)
{
	req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);

	if (!strchr(req->iterBegin->second->mapname, '.'))
		sprintf(req->cname, "%s.%s", req->iterBegin->second->mapname, cfig.zone);
	else
		strcpy(req->cname, req->iterBegin->second->mapname);

	req->data += pQu(req->data, req->cname);
	req->data += pShort(req->data, DNS_TYPE_A);
	req->data += pShort(req->data, DNS_CLASS_IN);
	req->data += pLong(req->data, cfig.lease);
	req->data += pShort(req->data, 4);
	req->data += pIP(req->data, req->iterBegin->second->ip);
	req->bytes = (DWORD)req->data - (DWORD)req->raw;
}

void addRRCNAFXR(data5 *req)
{
	req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);

	if (!strchr(req->iterBegin->second->mapname, '.'))
		sprintf(req->cname, "%s.%s", req->iterBegin->second->mapname, cfig.zone);
	else
		strcpy(req->cname, req->iterBegin->second->mapname);

	req->data += pQu(req->data, req->cname);
	req->data += pShort(req->data, DNS_TYPE_CNAME);
	req->data += pShort(req->data, DNS_CLASS_IN);
	req->data += pLong(req->data, cfig.lease);

	if (!strchr(req->iterBegin->second->hostname, '.'))
		sprintf(req->cname, "%s.%s", req->iterBegin->second->hostname, cfig.zone);
	else
		strcpy(req->cname, req->iterBegin->second->hostname);

	req->data += pShort(req->data, qLen(req->cname));
	req->data += pQu(req->data, req->cname);
	req->bytes = (DWORD)req->data - (DWORD)req->raw;
}

void addRRMXAFXR(data5 *req)
{
	data7 *cache = req->iterBegin->second;
	req->data += pQu(req->data, req->query);
	req->data += pShort(req->data, DNS_TYPE_MX);
	req->data += pShort(req->data, DNS_CLASS_IN);
	req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);
	req->data += pLong(req->data, cfig.lease);

	if (!strchr(cache->hostname, '.'))
		sprintf(req->cname, "%s.%s", cache->hostname, cfig.zone);
	else
		strcpy(req->cname, cache->hostname);

	req->data += pShort(req->data, qLen(req->cname) + 2);
	req->data += pShort(req->data, cache->mailPref);
	req->data += pQu(req->data, req->cname);
	req->bytes = (DWORD)req->data - (DWORD)req->raw;
}

WORD gdnmess(data5 *req, BYTE sockInd)
{
	memset(req, 0, sizeof(data5));
	socklen_t nLen = sizeof(req->addr);
	errno = 0;

	req->bytes = recvfrom(cfig.dnsUdpConn[sockInd].sock,
	                      req->raw,
	                      sizeof(req->raw),
	                      0,
	                      (sockaddr*) &req->addr,
	                      &nLen);

	errno = WSAGetLastError();

	if (errno || req->bytes <= 0)
	{
		if (cfig.logLevel)
		{
			sprintf(logBuff, "Error %i Getting DNS Message", errno);
			logMess(logBuff, 1);
		}
		return 0;
	}

	req->sockInd = sockInd;
	req->dnsp = (dnsPacket*)req->raw;

	if (req->dnsp->header.qr != 0 || ntohs(req->dnsp->header.qdcount) != 1 || ntohs(req->dnsp->header.ancount))
	{
		req->dnsp->header.rcode = RCODE_NOTIMPL;
		return req->bytes;
	}

	req->data = &req->dnsp->data;
	for (int i = 1; i <= ntohs(req->dnsp->header.qdcount); i++)
	{
		req->data += fQu(req->query, req->dnsp, req->data);
		req->qtype = fShort(req->data);
		req->data += 2;
		req->qclass = fShort(req->data);
		req->data += 2;
	}

	if (req->qclass != DNS_CLASS_IN || !req->qtype)
	{
		req->dnsp->header.rcode = RCODE_NOTIMPL;
		return req->bytes;
	}

	DWORD iip = ntohl(req->addr.sin_addr.s_addr);

	for (int i = 0; i < 32 && cfig.dnsRanges[i].rangeStart; i++)
	{
		if (iip >= cfig.dnsRanges[i].rangeStart && iip <= cfig.dnsRanges[i].rangeEnd)
			return req->bytes;
	}

	for (int i = 0; i < 32 && cfig.dhcpRanges[i].rangeStart; i++)
	{
		if (iip >= cfig.dhcpRanges[i].rangeStart && iip <= cfig.dhcpRanges[i].rangeEnd)
			return req->bytes;
	}

	if (findEntry(cacheInd, IP2String(req->cname, iip)))
		return req->bytes;

	if (req->addr.sin_addr.s_addr == cfig.zoneServers[0] || req->addr.sin_addr.s_addr == cfig.zoneServers[1])
		return req->bytes;

	req->dnsp->header.rcode = RCODE_REFUSED;
	return req->bytes;
}

void procTCP(void *lpParam)
{
	//printf("Here\n");
	data5 *req = (data5*)lpParam;
	char logBuff[256];
	errno = 0;
	req->bytes = recv(req->sock, req->raw, sizeof(req->raw), 0);
	errno = WSAGetLastError();

	if (errno || req->bytes <= 0)
	{
		if (cfig.logLevel)
		{
			sprintf(logBuff, "Error %i Getting DNS Message", errno);
			logMess(logBuff, 1);
		}
		closesocket(req->sock);
		free(req);
		_endthread();
		return ;
	}

	WORD pktSize = fShort(req->raw);
	req->data = req->raw;
	req->data += 2;
	req->dnsp = (dnsPacket*)(req->data);

	if (req->dnsp->header.qr != 0 || ntohs(req->dnsp->header.qdcount) != 1 || ntohs(req->dnsp->header.ancount))
	{
		req->dnsp->header.rcode = RCODE_NOTIMPL;
		sTCPmess(req);
		closesocket(req->sock);
		free(req);
		_endthread();
		return ;
		;
	}

	req->data = &req->dnsp->data;
	for (int i = 1; i <= ntohs(req->dnsp->header.qdcount); i++)
	{
		req->data += fQu(req->query, req->dnsp, req->data);
		req->qtype = fShort(req->data);
		req->data += 2;
		req->qclass = fShort(req->data);
		req->data += 2;
	}

	if (req->qclass != DNS_CLASS_IN || !req->qtype)
	{
		req->dnsp->header.rcode = RCODE_NOTIMPL;
		sTCPmess(req);
		closesocket(req->sock);
		free(req);
		_endthread();
		return ;
	}

	bool allowed = false;

	DWORD ip = req->addr.sin_addr.s_addr;

	for (int i = 0; i < MAX_SERVERS; i++)
	{
		if (ip == cfig.zoneServers[i] || ip == cfig.servers[i])
		{
			allowed = true;
			break;
		}
	}

	if (!allowed)
	{
		sprintf(logBuff, "Client %s, TCP Query, Access Denied", inet_ntoa(req->addr.sin_addr));
		logMess(logBuff, 1);
		req->dnsp->header.rcode = RCODE_REFUSED;
		sTCPmess(req);
		closesocket(req->sock);
		free(req);
		_endthread();
		return ;
	}

	strcpy(req->mapname, req->query);
	strcpy(req->cname, req->query);
	myLower(req->mapname);

	if (ntohs(req->dnsp->header.qdcount) == 1 && ntohs(req->dnsp->header.opcode) == 0)
	{
		req->dnsp->header.ancount = 0;
		req->dnsp->header.nscount = 0;
		req->dnsp->header.adcount = 0;
		req->dnsp->header.ra = 0;
		bool AXFRError = false;

		switch (req->qtype)
		{
			case DNS_TYPE_SOA:
				if (!strcasecmp(req->mapname, cfig.zone))
				{
					req->dnsp->header.aa = 0;
					req->dnsp->header.at = 0;
					addRRSOA(req);
					sTCPmess(req);
					sprintf(logBuff, "Client %s, SOA Sent", inet_ntoa(req->addr.sin_addr));
					logMess(logBuff, 2);
				}
				break;

			case DNS_TYPE_AXFR:
			case DNS_TYPE_IXFR:

				if (!strcasecmp(req->mapname, cfig.zone))
				{
					DWORD tempserial = cfig.serial;
					WORD records = 0;

					req->dnsp->header.qdcount = 0;
					req->dnsp->header.ancount = 0;
					req->data = &req->dnsp->data;
					addRRSOA(req);

					if (!sTCPmess(req))
					{
						AXFRError = true;
						break;
					}
					else
						records++;

					time_t currTime = time(NULL);
					req->iterBegin = dnsCache[cacheInd].begin();

					while (!AXFRError && req->iterBegin != dnsCache[cacheInd].end())
					{
						req->dnsp->header.ancount = 0;
						req->data = &req->dnsp->data;

						if (req->iterBegin->second->expiry > currTime)
						{
							switch (req->iterBegin->second->dataType)
							{
								case LOCAL_A:
									addRRAAFXR(req);
									break;

								case SERVER_A_AUTH:
									if (cfig.dnsTcpConn[req->sockInd].server == req->iterBegin->second->ip)
										addRRSTAFXR(req);
									else
									{
										req->iterBegin++;
										continue;
									}
									break;

								case STATIC_A_AUTH:
								case STATIC_A_NAUTH:
									addRRSTAFXR(req);
									break;

								case LOCAL_CNAME:
								case EXT_CNAME:
									addRRCNAFXR(req);
									break;

								case MX:
									addRRMXAFXR(req);
									break;

								default:
									req->iterBegin++;
									continue;
							}

							if (tempserial != cfig.serial)
							{
								AXFRError = true;
								break;
							}

							if (!sTCPmess(req))
							{
								AXFRError = true;
								break;
							}
							else
								records++;

						}
						req->iterBegin++;
					}

					req->dnsp->header.ancount = 0;
					req->data = &req->dnsp->data;
					addRRSOA(req);

					if (!AXFRError && tempserial == cfig.serial)
					{
						if (sTCPmess(req))
						{
							records++;
							sprintf(logBuff, "Client %s, Zone with %u RRs Sent", inet_ntoa(req->addr.sin_addr), records);
							logMess(logBuff, 2);
						}
					}
				}
				else
				{
					req->dnsp->header.rcode = RCODE_NOTAUTH;
					sTCPmess(req);
					sprintf(logBuff, "Client %s, Server is not Authorized for Zone %s", inet_ntoa(req->addr.sin_addr), req->query);
					logMess(logBuff, 1);
				}
				break;

			default:
				req->dnsp->header.rcode = RCODE_NOTIMPL;
				sTCPmess(req);
				sprintf(logBuff, "Client %s, DNS Query Type %u not supported", inet_ntoa(req->addr.sin_addr), req->qtype);
				logMess(logBuff, 1);
		}
	}
	closesocket(req->sock);
	free(req);
	_endthread();
	return;
}

WORD sTCPmess(data5 *req)
{
	req->dnsp->header.qr = 1;
	errno = 0;

	pShort(req->raw, req->bytes - 2);
	req->bytes = send(req->sock, req->raw, req->bytes, 0);

	errno = WSAGetLastError();

	if (errno)
	{
		if (cfig.logLevel)
		{
			sprintf(logBuff, "Error %i sending DNS Reply", errno);
			logMess(logBuff, 1);
		}
		return 0;
	}
	else if (req->bytes <= 0)
		return 0;

	return req->bytes;
}

WORD sdnmess(data5 *req)
{
	req->dnsp->header.qr = 1;
	errno = 0;

	req->bytes = sendto(cfig.dnsUdpConn[req->sockInd].sock,
	                    req->raw,
	                    req->bytes,
	                    0,
	                    (sockaddr*) & req->addr,
	                    sizeof(req->addr));

	errno = WSAGetLastError();

	if (errno)
	{
		if (cfig.logLevel)
		{
			sprintf(logBuff, "Error %i sending DNS Reply", errno);
			logMess(logBuff, 1);
		}
		return 0;
	}
	else if (req->bytes <= 0)
		return 0;

	return req->bytes;
}

⌨️ 快捷键说明

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