DNS functions reference (part 1)/ru
Справочник функций DNS (Часть 1)
Справочник функций DNS (Часть 2)
Фунции DNS (пример программы)
Справочник функций DNS ( Часть 1 )
Привет, эта первая часть статьи предназначается, чтобы вы знали, как создать DNS-запрос на linux, без необходимости сделать всю тяжелую работу (UDP и все подобные виды вещей). Эта часть раскроет часть запроса DNS. Часть 2 раскрывает, как проанализировать запрос в данных, которыми вы можете легко управлять.
Этот файл не раскрывает:
- - dn_comp(unsigned char *exp_dn, unsigned char *comp_dn, int length, unsigned char **dnptrs, unsigned char *exp_dn, unsigned char **lastdnptr);
- - dn_expand(unsigned char *msg, unsigned char *eomorig, unsigned char *comp_dn, unsigned char *exp_dn, int length);
ns_* (NameServer) функции будут описаны в следующем выпуске статьи.
Листинг
res_init(void) : Эта функция читает файл /etc/resolv.conf и инициализирует структуру, называемую _res (куда будет сохраняться информация для ваших текущих заданных установок).
res_query(const char *dname, int class, int type, unsigned char *answer, int anslen) : Эта функция опрашивает сервера DNS для заданного доменного имени domain name(const char *dname) для возможного типа type(int type) и класса class(int class). Ответ на запрос положится в буффер answer(unsigned char *answer), который получит длину anslen(int anslen).
res_search(const char *dname, int class, int type, unsigned char *answer, int anslen) : Опрашивает DNS-сервера, используя res_query() до тех пор, пока не получит удачный ответ. Доменное имя domain name(const char *dname) будет заполнено, если это не подлинный FQDN.
res_querydomain(const char *name, const char *domain, int class, int type, unsigned char *answer, int anslen) : Эта функция создаёт запрос с использованием res_query(), объединяя name(const char *name) и domain(const char *domain) перед запросом.
Следующие функции - это функции нижнего уровня, и использовать их вы должны только тогда, когда не могут использоваться функции верхнего уровня.
res_mkquery(int op, const char *dname, int class, int type, char *data, int datalen, struct rrec *newrr, char *buf, int buflen) : Эта функция создаёт DNS-запрос в буффер buffer(char *buf), с указанной максимальной длинной length(int buflen). Op(int op) может быть любым из определённых заголовков <arpa/nameser.h>. Аргумент под числом 7(struct rrec *newrr) обычно не используется и может быть установлен в NULL, по соображениям вашей безопасности, который не может быть описан в этой статье.
res_send(const char *msg, int msglen, char *answer, int anslen) : Эта функция будет отправлять уже отформатированный запрос(сделанный res_mkquery()), который может быть указан в первом аргументе(const char *msg), если он указывается, его длина должна быть указана во втором аргументе(int msglen). Ответ будет отправлен в char-переменную(char *answer) и максимальная длина ответа должна быть отправлена последним аргументом(int anslen).
Функция res_init() будет возвращать 0 в случае удачи, иначе -1, конечно, будет установлена значение в переменную h_errno.
res_query(), res_search(), res_querydomain(), res_mkquery() и res_send() будут возвращать длину ответа, если нет ошибок, если была ошибка, будут возвращать -1 и значение переменной h_errno будет изменено.
Список заголовков, требующихся для использования этих функций
<netinet/in.h> <arpa/nameser.h> <resolv.h>
Примечание: для компиляции кода вы должны слинковаться с библиотекой ресолвера, которая находится в /usr/lib/libresolv.a (-lresolv будет работать, если вы не используете функции NS-парсеров).
Структура _res из <resolv.h> (/usr/include/resolv.h):
struct __res_state {
int retrans; /* retransmition time interval */
int retry; /* number of times to retransmit */
u_long options; /* option flags - see below. */
int nscount; /* number of name servers */
struct sockaddr_in
nsaddr_list[MAXNS]; /* address of name server */
# define nsaddr nsaddr_list[0] /* for backward compatibility */
u_short id; /* current message id */
char *dnsrch[MAXDNSRCH+1]; /* components of domain to search */
char defdname[256]; /* default domain (deprecated) */
u_long pfcode; /* RES_PRF_ flags - see below. */
unsigned ndots:4; /* threshold for initial abs. query */
unsigned nsort:4; /* number of elements in sort_list[] */
char unused[3];
struct {
struct in_addr addr;
u_int32_t mask;
} sort_list[MAXRESOLVSORT];
res_send_qhook qhook; /* query hook */
res_send_rhook rhook; /* response hook */
int res_h_errno; /* last one set for this context */
int _vcsock; /* PRIVATE: for res_send VC i/o */
u_int _flags; /* PRIVATE: see below */
union {
char pad[52]; /* On an i386 this means 512b total. */
struct {
u_int16_t nscount;
u_int16_t nsmap[MAXNS];
int nssocks[MAXNS];
u_int16_t nscount6;
u_int16_t nsinit;
struct sockaddr_in6 *nsaddrs[MAXNS];
#ifdef _LIBC
unsigned long long int initstamp
__attribute__((packed));
#else
unsigned int _initstamp[2];
#endif
} _ext;
} _u;
};
Возможные значения для "int class" из <arpa/nameser.h> (/usr/include/arpa/nameser.h):
typedef enum __ns_class {
ns_c_invalid = 0, /* Cookie. */
ns_c_in = 1, /* Internet. */
ns_c_2 = 2, /* unallocated/unsupported. */
ns_c_chaos = 3, /* MIT Chaos-net. */
ns_c_hs = 4, /* MIT Hesiod. */
/* Query class values which do not appear in resource records */
ns_c_none = 254, /* for prereq. sections in update requests
*/
ns_c_any = 255, /* Wildcard match. */
ns_c_max = 65536
} ns_class;
Возможные значения для "int type" из <arpa/nameser.h> (/usr/include/arpa/nameser.h):
typedef enum __ns_type {
ns_t_invalid = 0, /* Cookie. */
ns_t_a = 1, /* Host address. */
ns_t_ns = 2, /* Authoritative server. */
ns_t_md = 3, /* Mail destination. */
ns_t_mf = 4, /* Mail forwarder. */
ns_t_cname = 5, /* Canonical name. */
ns_t_soa = 6, /* Start of authority zone. */
ns_t_mb = 7, /* Mailbox domain name. */
ns_t_mg = 8, /* Mail group member. */
ns_t_mr = 9, /* Mail rename name. */
ns_t_null = 10, /* Null resource record. */
ns_t_wks = 11, /* Well known service. */
ns_t_ptr = 12, /* Domain name pointer. */
ns_t_hinfo = 13, /* Host information. */
ns_t_minfo = 14, /* Mailbox information. */
ns_t_mx = 15, /* Mail routing information. */
ns_t_txt = 16, /* Text strings. */
ns_t_rp = 17, /* Responsible person. */
ns_t_afsdb = 18, /* AFS cell database. */
ns_t_x25 = 19, /* X_25 calling address. */
ns_t_isdn = 20, /* ISDN calling address. */
ns_t_rt = 21, /* Router. */
ns_t_nsap = 22, /* NSAP address. */
ns_t_nsap_ptr = 23, /* Reverse NSAP lookup (deprecated). */
ns_t_sig = 24, /* Security signature. */
ns_t_key = 25, /* Security key. */
ns_t_px = 26, /* X.400 mail mapping. */
ns_t_gpos = 27, /* Geographical position (withdrawn). */
ns_t_aaaa = 28, /* Ip6 Address. */
ns_t_loc = 29, /* Location Information. */
ns_t_nxt = 30, /* Next domain (security). */
ns_t_eid = 31, /* Endpoint identifier. */
ns_t_nimloc = 32, /* Nimrod Locator. */
ns_t_srv = 33, /* Server Selection. */
ns_t_atma = 34, /* ATM Address */
ns_t_naptr = 35, /* Naming Authority PoinTeR */
ns_t_kx = 36, /* Key Exchange */
ns_t_cert = 37, /* Certification record */
ns_t_a6 = 38, /* IPv6 address (deprecated, use ns_t_aaaa) */
ns_t_dname = 39, /* Non-terminal DNAME (for IPv6) */
ns_t_sink = 40, /* Kitchen sink (experimentatl) */
ns_t_opt = 41, /* EDNS0 option (meta-RR) */
ns_t_tsig = 250, /* Transaction signature. */
ns_t_ixfr = 251, /* Incremental zone transfer. */
ns_t_axfr = 252, /* Transfer zone of authority. */
ns_t_mailb = 253, /* Transfer mailbox records. */
ns_t_maila = 254, /* Transfer mail agent records. */
ns_t_any = 255, /* Wildcard match. */
ns_t_zxfr = 256, /* BIND-specific, nonstandard. */
ns_t_max = 65536
} ns_type;
Op-коды (для res_mkquery()) из <arpa/nameser.h> (/usr/include/arpa/nameser.h):
typedef enum __ns_opcode {
ns_o_query = 0, /* Standard query. */
ns_o_iquery = 1, /* Inverse query (deprecated/unsupported). */
ns_o_status = 2, /* Name server status query (unsupported). */
/* Opcode 3 is undefined/reserved. */
ns_o_notify = 4, /* Zone change notification. */
ns_o_update = 5, /* Zone update message. */
ns_o_max = 6
} ns_opcode;