C++实现DNS域名解析(三)

2014-11-24 13:28:51 · 作者: · 浏览: 368
ent, FD_READ);
66
67 m_szDNSPacket = new (std::nothrow) char[DNS_PACKET_MAX_SIZE];
68 if (m_szDNSPacket == NULL)
69 {
70 return FALSE;
71 }
72
73 m_usCurrentProcID = (USHORT)GetCurrentProcessId();
74
75 return TRUE;
76 }
77
78 BOOL CDNSLookup::UnInit()
79 {
80 WSACleanup();
81
82 if (m_szDNSPacket != NULL)
83 {
84 delete [] m_szDNSPacket;
85 }
86
87 return TRUE;
88 }
89
90 BOOL CDNSLookup::DNSLookupCore(ULONG ulDNSServerIP, char *szDomainName, std::vector *pveculIPList, std::vector *pvecstrCNameList, ULONG ulTimeout, ULONG *pulTimeSpent)
91 {
92 if (m_bIsInitOK == FALSE || szDomainName == NULL)
93 {
94 return FALSE;
95 }
96
97 //配置SOCKET
98 sockaddr_in sockAddrDNSServer;
99 sockAddrDNSServer.sin_family = AF_INET;
100 sockAddrDNSServer.sin_addr.s_addr = ulDNSServerIP;
101 sockAddrDNSServer.sin_port = htons( DNS_PORT );
102
103 //DNS查询与解析
104 if (!SendDNSRequest(sockAddrDNSServer, szDomainName)
105 || !RecvDNSResponse(sockAddrDNSServer, ulTimeout, pveculIPList, pvecstrCNameList, pulTimeSpent))
106 {
107 return FALSE;
108 }
109
110 return TRUE;
111 }
112
113 BOOL CDNSLookup::SendDNSRequest(sockaddr_in sockAddrDNSServer, char *szDomainName)
114 {
115 char *pWriteDNSPacket = m_szDNSPacket;
116 memset(pWriteDNSPacket, 0, DNS_PACKET_MAX_SIZE);
117
118 //填充DNS查询报文头部
119 DNSHeader *pDNSHeader = (DNSHeader*)pWriteDNSPacket;
120 pDNSHeader->usTransID = m_usCurrentProcID;
121 pDNSHeader->usFlags = htons(0x0100);
122 pDNSHeader->usQuestionCount = htons(0x0001);
123 pDNSHeader->usAnswerCount = 0x0000;
124 pDNSHeader->usAuthorityCount = 0x0000;
125 pDNSHeader->usAdditionalCount = 0x0000;
126
127 //设置DNS查询报文内容
128 USHORT usQType = htons(0x0001);
129 USHORT usQClass = htons(0x0001);
130 USHORT nDomainNameLen = strlen(szDomainName);
131 char *szEncodedDomainName = (char *)malloc(nDomainNameLen + 2);
132 if (szEncodedDomainName == NULL)
133 {
134 return FALSE;
135 }
136 if (!EncodeDotStr(szDomainName, szEncodedDomainName, nDomainNameLen + 2))
137 {
138 return FALSE;
139 }
140
141 //填充DNS查询报文内容
142 USHORT nEncodedDomainNameLen = strlen(szEncodedDomainName) + 1;
143 memcpy(pWriteDNSPacket += sizeof(DNSHeader), szEncodedDomainName, nEncodedDomainNameLen);
144 memcpy(pWriteDNSPacket += nEncodedDomainNameLen, (char*)(&usQType), DNS_TYPE_SIZE);
145 memcpy(pWriteDNSPacket += DNS_TYPE_SIZE, (char*)(&usQClass), DNS_CLASS_SIZE);
146 free (szEncodedDomainName);
147
148 //发送DNS查询报文
149 USHORT nDNSPacketSize = sizeof(DNSHeader) + nEncodedDomainNameLen + DNS_TYPE_SIZE + DNS_CLASS_SIZE;
150 if (sendto(m_sock, m_szDNSPacket, nDNSPacketSize, 0, (sockaddr*)&sockAddrDNSServer, sizeof(sockAddrDNSServer)) == SOCKET_ERROR)
151 {
152 return FALSE;
153 }
154
155 return TRUE;
156 }
157
158 BOOL CDNSLookup::RecvDNSResponse(sockaddr_in sockAddrDNSServer, ULONG ulTimeout, std::vector *pveculIPList, std::vector *pvecstrCNameList, ULONG *p