• 大小: 12KB
    文件类型: .cpp
    金币: 1
    下载: 0 次
    发布日期: 2021-05-19
  • 语言: C/C++
  • 标签: DNS  

资源简介

设计一个DNS服务器程序,读入“域名-IP地址”对照表,当客户端查询域名对应的IP地址时,用域名检索该对照表,三种检索结果: 检索结果为ip地址0.0.0.0,则向客户端返回“域名不存在”的报错消息(不良网站拦截功能) 检索结果为普通IP地址,则向客户返回这个地址(服务器功能) 表中未检到该域名,则向因特网DNS服务器发出查询,并将结果返给客户端(中继功能) 考虑多个计算机上的客户端会同时查询,需要进行消息ID的转换

资源截图

代码片段和文件信息

#include 
#include 
#include  
#include  
#include  
#include 
#include 
#include 
#include 
using namespace std;

#pragma  comment(lib “Ws2_32.lib“) 

#define DEF_DNS_ADDRESS “192.168.146.2“ //外部DNS服务器地址
#define LOCAL_ADDRESS “127.0.0.1“ //本地DNS服务器地址
#define DNS_PORT 53 //进行DNS服务的53端口
#define BUF_SIZE 512
#define LENGTH 65
#define AMOUNT 300
#define NOTFOUND -1

//DNS报文首部
typedef struct DNSHeader
{
    unsigned short ID;
    unsigned short Flags;
    unsigned short QuestNum;
    unsigned short AnswerNum;
    unsigned short AuthorNum;
    unsigned short AdditionNum;
} DNSHDR *pDNSHDR;

//DNS域名解析表结构
typedef struct translate
{
string IP; //IP地址
string domain; //域名
} Translate;

//ID转换表结构
typedef struct IDChange
{
unsigned short oldID; //原有ID
BOOL done; //标记是否完成解析
SOCKADDR_IN client; //请求者套接字地址
} IDTransform;

Translate DNS_table[AMOUNT]; //DNS域名解析表
IDTransform IDTransTable[AMOUNT]; //ID转换表
int IDcount = 0; //转换表中的条目个数
char url[LENGTH]; //域名
SYSTEMTIME sys;                     //系统时间
int Day Hour Minute Second Milliseconds;//保存系统时间的变量

//函数:获取域名解析表
int GetTable(char *tablePath)
{
int i=0 j pos=0;
string table[AMOUNT];

ifstream infile(tablePath ios::in); //以读入方式打开文本文件

if(! infile) {
cerr << “Open“ << tablePath << “error!“ < exit(1);
}

//每次从文件中读入一行,直至读到文件结束符为止
while (getline(infile table[i]) && i < AMOUNT)
i++;

if (i == AMOUNT-1)
cout << “The DNS table memory is full. “ << endl;

for (j = 0; j < i-1; j++) {
pos = table[j].find(‘ ‘);
if (pos > table[j].size())
cout << “The record is not in a correct format. “ << endl;
else {
DNS_table[j].IP = table[j].substr(0 pos);
DNS_table[j].domain = table[j].substr(pos+1);
}
}

infile.close(); //关闭文件
cout << “Load records succeed. “ << endl;

return i-1; //返回域名解析表中条目个数
}

//函数:获取DNS请求中的域名
void GetUrl(char *recvbuf int recvnum)
{
char urlname[LENGTH];
int i = 0 j k = 0;

memset(url 0 LENGTH);
memcpy(urlname &(recvbuf[sizeof(DNSHDR)]) recvnum-16); //获取请求报文中的域名表示

int len = strlen(urlname);

//域名转换
while (i < len) {
if (urlname[i] > 0 && urlname[i] <= 63)
for (j = urlname[i] i++; j > 0; j-- i++ k++)
url[k] = urlname[i];

if (urlname[i] != 0) {
url[k] = ‘.‘;
    k++;
}
}

url[k] = ‘\0‘;
}

//函数:判断是否在表中找到DNS请求中的域名,找到返回下标
int IsFind(char* url int num)
{
int find = NOTFOUND;
char* domain;

for (int i = 0; i < num; i++) {
domain = (char *)DNS_table[i].domain.c_str();
if (strcmp(domain url) == 0) { //找到
find = i;
break;
}
}

return find;
}

//函数:将请求ID转换为新的ID,并将信息写入ID转换表中
unsigned short RegisterNewID (unsigned short oID SOCKADDR_IN temp BOOL ifdone)
{
srand(time(NULL));
IDTransTable[IDcount].oldID = oID;
IDTransTable[IDcount].client = temp;

评论

共有 条评论