- #include <WinDNS.h>
- void dns_mx()
- {
- ManagedObject<Sockets> sock = new Sockets(INVALID_SOCKET, Sockets::SSL_NONE, AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- if (sock.IsSatisfied()) {
- #define DNS_TARGET "\\x07noreply\\x02""cf\\x00"
- #pragma warning(push)
- #pragma warning(disable:4201)
- RLIB_ALIGN(1) union DNS_NAME_HEADER
- {
- WORD offset;
- RLIB_ALIGN(1) struct {
- RLIB_ALIGN(1) union {
- RLIB_ALIGN(1) struct {
- char a : 6;
- char h1 : 1;
- char h0 : 1;
- };
- char len;
- };
- };
- };
- RLIB_ALIGN(1) struct DNS_MX_RDATA
- {
- WORD preference;
- RLIB_ALIGN(1) union {
- DNS_NAME_HEADER nameHeader;
- char nameExchange[sizeof(DNS_NAME_HEADER)];
- };
- };
- RLIB_ALIGN(1) union DNS_PACKET
- {
- char db[DNS_RFC_MAX_UDP_PACKET_LENGTH];
- RLIB_ALIGN(1) struct {
- DNS_HEADER dh;
- char dn[RLIB_COUNTOF_STR(DNS_TARGET)];
- RLIB_ALIGN(1) union {
- char dd[DNS_RFC_MAX_UDP_PACKET_LENGTH - sizeof(DNS_HEADER) - RLIB_COUNTOF_STR(DNS_TARGET)];
- RLIB_ALIGN(1) struct {
- DNS_WIRE_QUESTION dwq;
- RLIB_ALIGN(1) union {
- char dwq_end;
- DNS_NAME_HEADER dnh;
- };
- };
- };
- };
- };
- #pragma warning(pop)
- DNS_PACKET query;
- query.dh.Xid = LOWORD(&query);
- query.dh.RecursionDesired = 1;
- query.dh.Truncation = 0;
- query.dh.Authoritative = 0;
- query.dh.Opcode = DNS_OPCODE_QUERY;
- query.dh.IsResponse = 0;
- query.dh.ResponseCode = DNS_RCODE_NOERROR;
- query.dh.CheckingDisabled = 0;
- query.dh.AuthenticatedData = 0;
- query.dh.Reserved = 0;
- query.dh.RecursionAvailable = 0;
- INLINE_HTONS(query.dh.QuestionCount, 1);
- query.dh.AnswerCount = 0;
- query.dh.NameServerCount = 0;
- query.dh.AdditionalCount = 0;
- ::memcpy(query.dn, RLIB_STR_LEN(DNS_TARGET));
- query.dwq.QuestionType = DNS_RTYPE_MX;
- query.dwq.QuestionClass = DNS_RCLASS_INTERNET;
- int sret = sock->SendTo(&query, static_cast<int>(&query.dwq_end - query.db),
- RLIB_STR_LEN(_T("202.96.128.166")), DNS_PORT_HOST_ORDER);
- if (sret >= static_cast<int>(sizeof(DNS_HEADER))) {
- sock->SetRcvTimeO(18000);
- RLIB_RENAME(query, response);
- sockaddr_in saddr;
- int slen = sizeof(saddr);
- sret = sock->RecvFrom(&response, sizeof(response), &saddr, &slen);
- if (sret >= static_cast<int>(sizeof(DNS_HEADER))) {
- RLIB_NTOHS(response.dh.AnswerCount, response.dh.AnswerCount);
- DNS_WIRE_RECORD *lpdwr;
- DNS_NAME_HEADER *lpdnh = &response.dnh;
- char name[DNS_MAX_NAME_BUFFER_LENGTH];
- auto decompress_name = [](char *lpn)
- {
- BYTE len;
- while ((len = lpn[0]) != 0) {
- lpn[0] = '.';
- lpn += len + 1;
- }
- };
- while (response.dh.AnswerCount-- > 0) {
- if (lpdnh->h0 & lpdnh->h1){
- // 0xc00c compressed name
- lpdnh->h0 = lpdnh->h1 = 0;
- RLIB_NTOHS(lpdnh->offset, lpdnh->offset);
- ::strcpy(name, response.db + lpdnh->offset);
- decompress_name(name);
- ::OutputDebugStringA(name);
- ::OutputDebugString(RLIB_NEWLINE);
- lpdwr = reinterpret_cast<DNS_WIRE_RECORD *>(reinterpret_cast<LPBYTE>(lpdnh) + sizeof(*lpdnh));
- INLINE_NTOHS(lpdwr->DataLength, lpdwr->DataLength);
- INLINE_NTOHL(lpdwr->TimeToLive, lpdwr->TimeToLive);
- // skip rdata
- DNS_MX_RDATA *lpmx = reinterpret_cast<DNS_MX_RDATA *>(reinterpret_cast<LPBYTE>(lpdwr) + sizeof(*lpdwr));
- ::strcpy(name, lpmx->nameExchange);
- decompress_name(name);
- ::OutputDebugStringA(name);
- ::OutputDebugString(RLIB_NEWLINE);
- lpdnh = reinterpret_cast<DNS_NAME_HEADER *>(lpmx + lpdwr->DataLength);
- } else {
- // continue parse pointer
- // -> standard name + \\0
- // -> standard name + pointer + [... + \\0]
- ::strcpy(name, reinterpret_cast<char *>(lpdnh)); // ignore pointer case!!!
- decompress_name(name);
- ::OutputDebugStringA(name);
- ::OutputDebugString(RLIB_NEWLINE);
- } //if
- }
- } //if
- } //if
- } //if
- }
- //该片段来自于http://www.codesnippet.cn/detail/2405201614695.html
来源: http://www.codesnippet.cn/detail/2405201614695.html