/************************************
编译:
gcc -g -o dns dns.c -lresolv
测试:
./dns gmail.com
结果:
pref domain name
20 alt2.gmail-smtp-in.l.google.com
30 alt3.gmail-smtp-in.l.google.com
40 alt4.gmail-smtp-in.l.google.com
5 gmail-smtp-in.l.google.com
10 alt1.gmail-smtp-in.l.google.com
*************************************/
//-----------------------------------
// dns.h
#ifndef DNS_H
#define DNS_H
#define DNS_MSG_END -2
#define dns_mx_query(str) dns_resolve((str), T_MX)
#define dns_mx_expand() dns_findmx(T_MX)
#define foreach_mxrr(p, dn) while(dns_mx_expand() != DNS_MSG_END \
&& (!dns_get_mxrr(&p, dn, MAXDNAME)))
void dns_init(void);
int dns_get_mxrr(unsigned short *, unsigned char *, unsigned int);
int dns_resolve(char *, int);
int dns_findmx(int);
#endif
//-----------------------------------
//dns.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <sys types.h="">
#include <netinet in.h="">
#include <arpa nameser.h="">
#include <resolv.h>
#include <errno.h>
#include "dns.h"
extern int res_query();
extern int res_search();
extern int errno;
extern int h_errno;
HEADER *hdr;
unsigned char *buf;
static int response_len;
static unsigned char *response_end;
static unsigned char *response_pos;
static int num_answers;
static char name[MAXDNAME];
unsigned short pref;
static unsigned short getshort(unsigned char *c)
{
unsigned short u;
u = c[0];
return (u << 8) + c[1];
}
int dns_resolve(char *domain, int type)
{
int n;
int i;
errno = 0;
if (domain == NULL)
return -1;
response_len = res_search(domain, C_IN, type, buf, PACKETSZ);
if (response_len <= 0)
return -1;
if (response_len >= PACKETSZ)
response_len = PACKETSZ;
response_end = buf + response_len;
response_pos = buf + sizeof(HEADER);
n = ntohs(hdr->qdcount);
while (n-- > 0) {
i = dn_expand(buf, response_end, response_pos, name, MAXDNAME);
response_pos += i;
i = response_end - response_pos;
if (i < QFIXEDSZ) return -1;
response_pos += QFIXEDSZ;
}
num_answers = ntohs(hdr->ancount);
return num_answers;
}
int dns_findmx(int want_type)
{
unsigned short rrtype;
unsigned short rrdlen;
int i;
if (num_answers <= 0) return DNS_MSG_END;
num_answers--;
if (response_pos == response_end) return -1;
i = dn_expand(buf, response_end, response_pos, name, MAXDNAME);
if (i < 0) return -1;
response_pos += i;
i = response_end - response_pos;
if (i < 10) return -1;
rrtype = getshort(response_pos);
rrdlen = getshort(response_pos + 8);
response_pos += 10;
if (rrtype == want_type) {
if (rrdlen < 3) return -1;
pref = (response_pos[0] << 8) + response_pos[1];
memset(name, 0, MAXDNAME);
if (dn_expand(buf, response_end, response_pos + 2, name, MAXDNAME) < 0)
return -1;
response_pos += rrdlen;
return strlen(name);
}
response_pos += rrdlen;
return 0;
}
void dns_init()
{
res_init();
memset(name, 0, MAXDNAME);
}
int dns_get_mxrr(unsigned short *p, unsigned char *dn, unsigned int len)
{
*p = pref;
strncpy(dn, name, len);
if (len < (strlen(name) + 1))
return -1;
return 0;
}
int main(int argc, char **argv)
{
char dname[MAXDNAME];
int i;
unsigned short p;
buf = (unsigned char *)calloc(1, PACKETSZ);
if (buf == NULL) {
fprintf(stderr, "calloc for response.buf failed");
exit(-1);
}
hdr = (void *)buf;
dns_init();
if (argc != 2) {
fprintf(stderr, "bad argument\n");
exit(-1);
}
i = dns_mx_query(argv[1]);
if (i < 0) {
fprintf(stderr, "err\n");
return 0;
}
printf("pref\tdomain name\n");
foreach_mxrr(p, dname) {
printf("%d\t%s\n", p, dname);
}
if (buf) {
free(buf);
buf = NULL;
}
return 0;
}
使用Resolver获取MX记录
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 坑点1:选择完视频后 setDidFinishPickingVideoHandle block回调拿取到了PHAs...
- Laravel 和 Vue.js 使用 Axios 通过 Put 请求上传文件 获取不到 Request 数据,通...
- laravel5 默认已经关闭了query log查询日志,所以要使用必须先开启 开启 DB::enableQue...
- 使用了v-if 后,将不会渲染子组件内容,导致this.$refs获取不到对应的名称 解决办法就是 代替 v-if...