Добрый день! Вопрос: Вот я получил от DNS - сервера ответ. Как узнать по какому смещению в полученном пакете находятся: - IP - адреса остальных его DNS - серверов - IP - серверов ретрансляции почтовых сообщений? Спасибо.
Фиксированных смещений нет. Записи в ответах идут в произвольном порядке. В аттаче код на С++, который делает запрос и разбирает ответ.
Турецкий Пример твой классный (dns.rar), еще раз спасибо, но он не полностью разбирает ответ. Пример разбирает только имена NS , MX ... и других записей, а IP - не выделяет. Может еще что-то есть из примеров ?
Ну доделай сам. Я писал этот код для определенных целей, а не для реализации DNS вообще. RFC883 в зубы и вперед
Это Турецкий. Почему не выделяет IP ? Еще как выделяет, фактически код не работает с PTR запросами (возвращение имени по адресу). IP адрес возвращается в записях типа A. Код, который получает спислк MX серверов домена, как раз с помощью функции из аттача. Код (Text): int get_mx_records(const char * name_server, const char *name, struct in_addr *list) { int total_sections; DNS_SECTION sections[32]; //Получение доменного Name Server total_sections = dns_query(name_server,DNS_TYPE_NS,name,sections); if(total_sections<=0) return -1; int i=0,k=0; //Быбираем первую NS запись в ответе while( (i<total_sections)&&(sections[i].type != DNS_TYPE_NS) ) i++; if (i==total_sections) return -1; //Если нет записей, то ваходим с ошибкой //Пытаемся найти A запись об этом адресе while( (k<total_sections)&&strcmp(sections[k].name,sections[i].data.ns.name) ) k++; //Тут сложная кострукция, котаря делает DNS запрос на получение MX записей по адресу //полученному в предыдущем ответе //если в ответе не было записей, то резольвим IP адрес по имени стандартными средствами total_sections = dns_query(inet_ntoa((k==total_sections)?(*((struct in_addr*)gethostbyname(sections[i].data.ns.name)->h_addr_list[0])):(sections[k].data.a.addr)), DNS_TYPE_MX,name,sections); if(total_sections<=0) return -1; //Если нет MX записей - выходим int total_mx_records=0; int min_priority=0, cur_priority, cur; //Сортируем по возрастанию приоритета while(1) { cur_priority = 100000; cur = -1; //Ищем запись с наименьшим приоритетом for(i=0; i<total_sections; i++) { if((sections[i].type==DNS_TYPE_MX)&&(sections[i].data.mx.preference>=min_priority)) if((sections[i].data.mx.preference<cur_priority)&&(sections[i].data.mx.preference<65535)) { cur_priority = sections[i].data.mx.preference; cur=i; } } if(cur == -1) break; //Пытаемся найти IP адрес в ответе k=0; while( (k<total_sections)&&strcmp(sections[k].name,sections[cur].data.mx.name) ) k++; //Если IP адрес не найден в ответе, то резольвим его стандартными средствами и пишем в результат *list++ = (k==total_sections)?(*((struct in_addr*)gethostbyname(sections[cur].data.mx.name)->h_addr_list[0])):(sections[k].data.a.addr); total_mx_records++; //Маркируем прочитанную запись максимальным приоритетом min_priority=cur_priority; sections[cur].data.mx.preference = 65535; } return total_mx_records; } Надеюсь ты не спамом заниматься будешь.
GanDJuStas спасибо! хорошо видать разобрался ты в этом. пытаюсь разобраться тоже. >Надеюсь ты не спамом заниматься будешь. да куда нам с нашим каналом, только людей смешить да свои деньги тратить.
GanDJuStas можно ? еще два вопроса: 1. что в пакете следует сразу за 0xC0 2. что ты подаешь на вход dns_copy_name_full() первым вторым и третьим параметром просто от таких функций, которые вызывают сами себя, у меня истерика начинается Код (Text): if((*name & 0xC0)==0xC0) { dns_copy_name_full(p,p+(htons(*((unsigned short*)name)) & ~0xC000),dst); return k+2; }
В DNS пакете имена (адреса) преставляются в виде набора кусков. Каждый кусок каждый является частью символического представления именим или адреса (например www.mail.ru разбивается на 3 куска: www, mail, ru). В пакете передается сначала длина, а потом сам текст, то есть будет передано 0x3www0x4mail0x2ru0x0. Ноль в конце - огрничитель. Однобайтовое поле длины всегда содержит 0 в двух старших битах. Если в двух старших битах единицы, то это "указатель". Указатель составляет 2 байта. После обнуления старших битов представляет смещение в сегмента в пакете. Например в ответ на MX запрос на mail.ru MX запись будет содеражить такое 0x3mxs0xC012. По смещению 0x12 (взято для примера) от начала пакета будет идти 0x4mail0x2ru0x0. Функция dns_copy_name_full обработает указатели и вернет строку mxs.mail.ru. Первый параметр функции - указатель на начало пакета, второй - указатель на обрабатываемую строку, третий - выходная строка. Функция возвращает смещение указателя name после чтения строки
спасибо!!!! я долго искал структуру заголовка dns запроса... пишу на Си но такого объявления типа ешо не видел... unsigned id:16;