Разбор ответа DNS - сервера.

Тема в разделе "WASM.NETWORKS", создана пользователем _sheva740, 25 май 2007.

  1. _sheva740

    _sheva740 New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    1.539
    Адрес:
    Poland
    Добрый день!

    Вопрос:
    Вот я получил от DNS - сервера ответ.
    Как узнать по какому смещению в полученном пакете
    находятся:
    - IP - адреса остальных его DNS - серверов
    - IP - серверов ретрансляции почтовых сообщений?
    Спасибо.
     
  2. Турецкий

    Турецкий New Member

    Публикаций:
    0
    Регистрация:
    10 окт 2006
    Сообщения:
    10
    Фиксированных смещений нет. Записи в ответах идут в произвольном порядке.

    В аттаче код на С++, который делает запрос и разбирает ответ.
     
  3. _sheva740

    _sheva740 New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    1.539
    Адрес:
    Poland
    Турецкий
    Спасибо большое!
     
  4. _sheva740

    _sheva740 New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    1.539
    Адрес:
    Poland
    Турецкий
    Пример твой классный (dns.rar), еще раз спасибо, но он не полностью разбирает ответ.
    Пример разбирает только имена NS , MX ... и других записей, а IP - не выделяет.

    Может еще что-то есть из примеров ?
     
  5. Турецкий

    Турецкий New Member

    Публикаций:
    0
    Регистрация:
    10 окт 2006
    Сообщения:
    10
    Ну доделай сам. Я писал этот код для определенных целей, а не для реализации DNS вообще.
    RFC883 в зубы и вперед
     
  6. GanDJuStas

    GanDJuStas New Member

    Публикаций:
    0
    Регистрация:
    11 мар 2003
    Сообщения:
    21
    Адрес:
    Russia
    Это Турецкий.

    Почему не выделяет IP ? Еще как выделяет, фактически код не работает с PTR запросами (возвращение имени по адресу).

    IP адрес возвращается в записях типа A.

    Код, который получает спислк MX серверов домена, как раз с помощью функции из аттача.

    Код (Text):
    1. int get_mx_records(const char * name_server, const char *name, struct in_addr *list)
    2. {
    3.     int total_sections;
    4.     DNS_SECTION sections[32];
    5.  
    6.     //Получение доменного Name Server
    7.     total_sections = dns_query(name_server,DNS_TYPE_NS,name,sections);
    8.     if(total_sections<=0) return -1;
    9.    
    10.     int i=0,k=0;
    11.  
    12.     //Быбираем первую NS запись в ответе
    13.     while( (i<total_sections)&&(sections[i].type != DNS_TYPE_NS) ) i++;
    14.     if (i==total_sections) return -1; //Если нет записей, то ваходим с ошибкой
    15.  
    16.            //Пытаемся найти A запись об этом адресе
    17.     while( (k<total_sections)&&strcmp(sections[k].name,sections[i].data.ns.name) ) k++;
    18.    
    19.     //Тут сложная кострукция, котаря делает DNS запрос на получение MX записей по адресу
    20.            //полученному в предыдущем ответе
    21.            //если в ответе не было записей, то резольвим IP адрес по имени стандартными средствами
    22.     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)),
    23.                                 DNS_TYPE_MX,name,sections);
    24.     if(total_sections<=0) return -1; //Если нет MX записей - выходим
    25.  
    26.     int total_mx_records=0;
    27.     int min_priority=0, cur_priority, cur;
    28.    
    29.     //Сортируем по возрастанию приоритета
    30.     while(1)
    31.     {
    32.         cur_priority = 100000;
    33.         cur = -1;
    34.  
    35.                        //Ищем запись с наименьшим приоритетом
    36.         for(i=0; i<total_sections; i++)
    37.         {
    38.             if((sections[i].type==DNS_TYPE_MX)&&(sections[i].data.mx.preference>=min_priority))
    39.                 if((sections[i].data.mx.preference<cur_priority)&&(sections[i].data.mx.preference<65535))
    40.                 {
    41.                     cur_priority = sections[i].data.mx.preference;
    42.                     cur=i;
    43.                 }
    44.         }
    45.        
    46.         if(cur == -1) break;
    47.        
    48.                       //Пытаемся найти IP адрес в ответе
    49.         k=0;
    50.         while( (k<total_sections)&&strcmp(sections[k].name,sections[cur].data.mx.name) ) k++;
    51.  
    52.                        //Если IP адрес не найден в ответе, то резольвим его стандартными средствами и пишем в результат
    53.         *list++ = (k==total_sections)?(*((struct in_addr*)gethostbyname(sections[cur].data.mx.name)->h_addr_list[0])):(sections[k].data.a.addr);
    54.         total_mx_records++;
    55.  
    56.                       //Маркируем прочитанную запись максимальным приоритетом
    57.         min_priority=cur_priority;
    58.         sections[cur].data.mx.preference = 65535;
    59.     }
    60.     return total_mx_records;
    61. }
    Надеюсь ты не спамом заниматься будешь.
     
  7. _sheva740

    _sheva740 New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    1.539
    Адрес:
    Poland
    GanDJuStas

    спасибо!
    хорошо видать разобрался ты в этом.
    пытаюсь разобраться тоже.

    >Надеюсь ты не спамом заниматься будешь.
    да куда нам с нашим каналом, только людей смешить да свои деньги тратить.
     
  8. _sheva740

    _sheva740 New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    1.539
    Адрес:
    Poland
    GanDJuStas
    можно ? еще два вопроса:
    1. что в пакете следует сразу за 0xC0
    2. что ты подаешь на вход dns_copy_name_full() первым вторым и третьим параметром
    просто от таких функций, которые вызывают сами себя, у меня истерика начинается :dntknw:


    Код (Text):
    1. if((*name & 0xC0)==0xC0)
    2.  {
    3.     dns_copy_name_full(p,p+(htons(*((unsigned short*)name)) & ~0xC000),dst);
    4.     return k+2;
    5. }
     
  9. GanDJuStas

    GanDJuStas New Member

    Публикаций:
    0
    Регистрация:
    11 мар 2003
    Сообщения:
    21
    Адрес:
    Russia
    В 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 после чтения строки
     
  10. _sheva740

    _sheva740 New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    1.539
    Адрес:
    Poland
    GanDJuStas
    спасибо дружище !!! (не ожидал что ответишь)!!!
    Теперь яснее стало :) !!!
     
  11. lennon

    lennon New Member

    Публикаций:
    0
    Регистрация:
    25 авг 2008
    Сообщения:
    1
    спасибо!!!! я долго искал структуру заголовка dns запроса...
    пишу на Си но такого объявления типа ешо не видел... unsigned id:16;