Разводим червей Ms-Rem (Ms-Rem@yandex.ru) Хакер, номер #084, стр. 084-118-3 if DnsQuery(Domain, DNS_TYPE_MX, DNS_QUERY_STANDARD, nil, @pQueryResultsSet, nil) = 0 then begin Result := pQueryResultsSet^.Data.MX.pNameExchange; GlobalFree(dword(pQueryResultsSet)); end; end; Как ты видишь, резолвить с помощью DNS API проще простого, но так как этот метод не всегда приемлем, перейдем к рассмотрению следующего метода. [ручной DNS резолвинг] Я попытаюсь рассказать немного о DNS-протоколе. Я не ставлю перед собой цели подробно рассказывать обо всей системе, но попытаюсь дать основные понятия, необходимые для понимания этого протокола. Подробно ты можешь все прочитать в документации RFC 1034 и 1035. DNS-запросы бывают разного типа. Тип запроса имеет числовое значение от 1 до 16 и определяет информацию, которую вы желаете получить. Номер типа ответа всегда соответствует номеру типа запроса, чтобы знать, что и к чему относится. Вот основные типы DNS-запросов: 01 A host address (IP адрес хоста) 02 NS authoritative name server (NS сервер) 03 MD mail destination (устар.тип, сейчас юзают MX) 04 MF mail forwarder (устар.тип, сейчас юзают MX) 05 CNAME the canonical name for alias 06 SOA marks of a start of zone of authority 07 MB (experimental) 08 MG (experimental) 09 MR mail rename domain name (experimental) 10 NULL a null RR 11 WKS a well known service description 12 PTR a domain name pointer 13 HINFO host information 14 MINFO mail box or mail list information 15 MX mail exchange 16 TXT text string Из них нас интересуют только MX-записи, имеющие номер 15. Наряду с типом запроса, существует еще и класс запроса. Это связано с тем, что протокол DNS универсален и может работать практически в любых сетях, а не только в TCP/IP. Так как другие сети нам не понадобятся, нас будет интересовать только один класс запросов - IN (=1), который предназначен для использования в Интернете. Пакет запроса имеет следующий вид: Packet Length - 2 байта Query/Response header - 12 байтов Question - нет фиксированной длины, зависит от количества вопросов Answer - формируется сервером, нет фиксированной длины Authority - формируется сервером, нет фиксированной длины Additional - формируется сервером, нет фиксированной длины Запрос должен включать в себя Length, Header и Question, а ответ может иметь все поля, но поле Answer в нем является обязательным. Теперь определим структуру, описывающую заголовки Query/Response header: TDNSHeader = packed record qryID : word; - идентификатор запроса options: word; - флаги qdcount: word; - счетчик записей в поле Question ancount: word; - счетчик записей в поле Answer nscount: word; - счетчик записей в поле Authority arcount: word; - счетчик записей в поле Additional end; TQueryType = packed record QType : word; - тип запроса QClass: word; - класс запроса end; Чтобы получить адрес SMTP-сервера, куда мы хотим послать письмо, мы должны составить запрос, послать его, принять и декодировать ответ. Со структурой запроса, я думаю, все понятно, давай теперь разберемся с возвращаемыми ответами, а для этого надо разобраться, что такое RR-записи. Они формируются NS-сервером и располагаются только в ответе и строго следом за полем запроса. То есть Answer и все последующие состоят из некоторого количества RR-записей различного формата. В них передаются в качестве информации и IP-адреса, и названия серверов, и просто текстовая информация. Подробно все типы этих записей приведены в RFC 1035, они довольно похожи друг на друга и различаются лишь мелкими деталями. Так что я буду говорить только об интересующих меня. Аббревиатура RR означает Resource Record (это официальное название из документа). |