DNS functions reference (part 2)/ru
Справочник функций DNS (Часть 1)
Справочник функций DNS (Часть 2)
Фунции DNS (пример программы)
Справочник функций DNS ( Часть 2 )
Привет, эта вторая часть раскажет вам о том, как парсить результаты, полученные функцией res_*, о которых мы упомянули в первой статье Справочник функций DNS (Часть 1). Эти функции разрешают вам конвертировать ответы в нормальный текст, для чтения или использовать так, как вам захочется. Приступим.
Листинг
int res_init_parse(const u_char *msg, int msglen, ns_msg *handle) : Эта функция может быть вызвана только перед использованием любой функции парсинга. Аргументы должны быть: ответ на запрос должен заполнить первый аргумент(const u_char *msg), размер ответа во втором аргументе(int msglen) и наконец, указатель ns_msg должен быть передан в последний аргумент(ns_msg *handle), этот последний указатель важная структура, которая должна передаваться во все другие ns_* функции.
const u_char *ns_msg_base(ns_msg handle) : Эта функция возвратит указатель на начало ответа.
const u_char *ns_msg_end(ns_msg handle) : Эта функция возвратит указатель в конец ответа.
int ns_msg_size(ns_msg handle) : Эта функция возвратит размер ответа.
u_int16_t ns_msg_id(ns_msg handle) : Это возвратит идентификацию от секции заголовка пакета, в котором содержится ответ.
u_int16_t ns_msg_get_flag(ns_msg handle, ns_flag flag) : Возвратит поля флагов из секции заголовка в пакете, в котором содержится ответ. Первый аргумент должен быть структурой, которая заполнена функцией ns_init_parse() и второй аргумент должен быть любым из ns_flags.
u_int16_t ns_msg_count(ns_msg handle, ns_sect section) : Returns a counter from the header section of the response packet. The first argument must be, of course, the structure filled in by ns_init_parse(), while the second argument can be any of the ns_sect enum values.
int ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr) : Эта функция разворачивает информацию о записи из ответа и сохраняет её в rr.rr(ns_rr *rr). Параметр section будет описан в секции параметров ns_msg_count().
char *ns_rr_name/u_int16_t ns_rr_type/u_int16_t ns_rr_class/u_int16_t ns_rr_ttl/u_int16_t ns_rr_rdlen/const u_char *ns_rr_rdata(ns_rr rr) : Все эти функции будут возвращать индивидуальные поля с ответа DNS, только аргумент(ns_rr rr) должен быть структурой, возвращённой функциейns_parserr().
int ns_name_compress(const char *exp_dn, u_char *comp_dn, size_t length, const u_char **dnptrs, const u_char **lastdnptr) : Эта функция сжимает доменное имя, эта функция не может быть вызвана вами непосредственно. Вы должны сжать доменное имя для чего-нибудь, это делается прекрасно. Первый аргумент FQDN, null-terminated. Второй аргумент - это функция которая содержит окончательный результат, третий аргумент (size_t length) - это размер второго аргумента, четвёртый аргумент(const u_char **dnptrs) - массив указателей на предыдущий сжатый список доменных имён. И последний аргумент(const u_char **lastdnptr) - это указатель на последний элемент четвёртого аргумента.
int ns_name_uncompress(const u_char *msg, const u_char *eomorig, const u_char *comp_dn, char *exp_dn, size_t length) : Эта функция будет разжимать сжатые данные предыдущей функцией(that used the function ns_name_compress()). Этот первый аргумент (const u_char *msg) - указатель на начало ответа DNS, второй(const u_char *eomorig) - указатель на начало байта после ответа DNS, which will asure you that ns_name_uncompress() won't crash. Третий аргумент(const u_char *comp_dn) сжатое доменное имя предыдущей функцией, пятый - где расширенное имя будет находится и последний аргумент(size_t length) - размер четвёртого аргумента(char *exp_dn).
int ns_name_skip(const u_char **ptrptr, const u_char *eom) : Это будет пропускать доменное имя, которое было разжато. Аргументы: первый(const u_char **ptrptr) - указатель на домен, который должен быть пропущен, второй аргумент(const u_char *eom) - указатель на первый байт после сообщения, таким образом функция не будет передавать сообщение максимальной длины.
u_int ns_get16(const u_char *cp) : Эта функция будет возвращать unsigned short integer из пакета DNS.
void ns_put16(u_int s, u_char *cp) : Принимает 16-bit значение, определённое в первом аргументе(u_int s), расположение которого, указывает второй аргумент(u_char *cp).
u_long ns_get32(const u_char *cp) : Эта функция используется также как и функция ns_get16(), но используя 32-bit целое, вместо 16-bit.
void ns_put32(u_long l, u_char *cp) : Принимает 32-bit значение, определённое в первом аргументе(u_long l), расположение которого, указывает второй аргумент(u_char *cp).
Список заголовков, требуемых для использования этих функций:
<sys/types.h> <netinet/in.h> <netdb.h> <arpa/nameser.h> <resolv.h>
Примечание: для компиляции кода вы должны слинковаться с библиотекой ресолвера, которая находится в /usr/lib/libresolv.a (-lresolv будет работать, если вы не используете функции NS-парсеров).
Структура ns_msg из <arpa/nameser.h> (/usr/include/arpa/nameser.h):
typedef struct __ns_msg {
const u_char *_msg, *_eom;
u_int16_t _id, _flags, _counts[ns_s_max];
const u_char *_sections[ns_s_max];
ns_sect _sect;
int _rrnum;
const u_char *_ptr;
} ns_msg;
Замечание: Вы не должны делать что-либо сами с этой структурой, приостановитесь, хорошо знать, что она содержит.
Структура ns_rr из <arpa/nameser.h> (/usr/include/arpa/nameser.h):
typedef struct __ns_rr {
char name[NS_MAXDNAME];
u_int16_t type;
u_int16_t rr_class;
u_int32_t ttl;
u_int16_t rdlength;
const u_char * rdata;
} ns_rr;
Примечание: Снова, вы не должны делать что-либо сами с этой структурой, приостановитесь, хорошо знать, что она содержит.
Возможные значения для "ns_sect" из <arpa/nameser.h> (/usr/include/arpa/nameser.h):
typedef enum __ns_sect {
ns_s_qd = 0, /* Query: Question. */
ns_s_zn = 0, /* Update: Zone. */
ns_s_an = 1, /* Query: Answer. */
ns_s_pr = 1, /* Update: Prerequisites. */
ns_s_ns = 2, /* Query: Name servers. */
ns_s_ud = 2, /* Update: Update. */
ns_s_ar = 3, /* Query|Update: Additional records. */
ns_s_max = 4
} ns_sect;
Возможные значения для "ns_flag" из <arpa/nameser.h> (/usr/include/arpa/nameser.h):
typedef enum __ns_flag {
ns_f_qr, /* Question/Response. */
ns_f_opcode, /* Operation code. */
ns_f_aa, /* Authoritative Answer. */
ns_f_tc, /* Truncation occurred. */
ns_f_rd, /* Recursion Desired. */
ns_f_ra, /* Recursion Available. */
ns_f_z, /* MBZ. */
ns_f_ad, /* Authentic Data (DNSSEC). */
ns_f_cd, /* Checking Disabled (DNSSEC). */
ns_f_rcode, /* Response code. */
ns_f_max
} ns_flag;