DNS资源记录与gethostbyname

来源:互联网 发布:开支软件 编辑:程序博客网 时间:2024/05/16 08:37

1.    DNS资源记录

DNS资源记录类型主要有以下几种:

A :A记录将主机名映射为IPV4地址,例如:

       ns.abc.com.             IN   A   192.168.100.5
       mail1.abc.com.       IN   A   192.168.100.6

AAAA :AAAA记录将主机名映射为IPV6地址,格式同上。

CNAME :CNAME记录别名与正式名称之间的对应关系,格式为:

       Alias   IN   CNAME    Canonical-hostname
MX :
MX记录提供了邮件路由信息,以及邮件交换器的主机名称以及相应的优先值。

PTR : PTR记录将IP地址与主机名进行映射对应,作用正好与A记录相反。

【注意】在Linux或者windows系统上,nslookup命令可以查看这几种类型记录。

 

2.    gethostbyname函数的语法:

函数的语法形式如下:

      struct hostent *gethostbyname(const char *hostname)      

      函数的主要功能是执行依次对CNAMEA记录或者AAAA记录的查询,并返回主机对应的别名、正式名、IPV4IPV6地址。函数返回类型结构定义如下:

           structhostent {

             char *h_name;  //主机的正式名称

             char **h_aliases;  //主机的别名列

             int h_addrtype;  //主机的地址类型

             int h_length; //主机的地址长度(4字节或者16字节)

             char **h_addr_list; //主机对应的IPV4或者IPV6地址列

             #define h_addr h_addr_list[0] //地址列表中的第一个地址

        };

      根据上面的定义,值得注意的是,对于某台主机,可能存在着多个别名以及多个AAAAA记录,即多个IP地址。

【测试程序】

/**************************************  modify by dragon based on UNP code**************************************/#include <netdb.h>#include <stdio.h>#include <string.h>#define IN6ADDRSZ 16 #defineINT16SZ 2static const char *inet_ntop4(const u_char *src, char *dst, size_t size);static const char *inet_ntop6(const u_char *src, char *dst, size_t size);static const char *inet_ntop(int af, const void *src, char *dst, size_t size);static const char *inet_ntop4(const u_char *src, char *dst, size_t size){static const char fmt[] = "%u.%u.%u.%u";char tmp[sizeof "255.255.255.255"];sprintf(tmp, fmt, src[0], src[1], src[2], src[3]);if (strlen(tmp) > size) {return NULL;}strcpy(dst, tmp);return (dst);}static const char *inet_ntop6(const u_char *src, char *dst, size_t size){/* * Note that int32_t and int16_t need only be "at least" large enough * to contain a value of the specified size.  On some systems, like * Crays, there is no such thing as an integer variable with 16 bits. * Keep this in mind if you think this function should have been coded * to use pointer overlays.  All the world's not a VAX. */char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;struct { int base, len; } best, cur;u_int words[IN6ADDRSZ / INT16SZ];int i;/* * Preprocess: *Copy the input (bytewise) array into a wordwise array. *Find the longest run of 0x00's in src[] for :: shorthanding. */memset(words, 0, sizeof words);for (i = 0; i < IN6ADDRSZ; i++)words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));best.base = -1;cur.base = -1;for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {if (words[i] == 0) {if (cur.base == -1)cur.base = i, cur.len = 1;elsecur.len++;} else {if (cur.base != -1) {if (best.base == -1 || cur.len > best.len)best = cur;cur.base = -1;}}}if (cur.base != -1) {if (best.base == -1 || cur.len > best.len)best = cur;}if (best.base != -1 && best.len < 2)best.base = -1;/* * Format the result. */tp = tmp;for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {/* Are we inside the best run of 0x00's? */if (best.base != -1 && i >= best.base &&    i < (best.base + best.len)) {if (i == best.base)*tp++ = ':';continue;}/* Are we following an initial run of 0x00s or any real hex? */if (i != 0)*tp++ = ':';/* Is this address an encapsulated IPv4? */if (i == 6 && best.base == 0 &&    (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))return (NULL);tp += strlen(tp);break;}sprintf(tp, "%x", words[i]);tp += strlen(tp);}/* Was it a trailing run of 0x00's? */if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))*tp++ = ':';*tp++ = '\0';/* * Check for overflow, copy, and we're done. */if ((tp - tmp) > size) {return (NULL);}strcpy(dst, tmp);return (dst);}static const char *inet_ntop(int af, const void *src, char *dst, size_t size){switch (af) {case AF_INET:return (inet_ntop4(src, dst, size));case AF_INET6:return (inet_ntop6(src, dst, size));default:return (NULL);}/* NOTREACHED */}intmain(int argc, char **argv){char*ptr, **pptr;charstr[INET6_ADDRSTRLEN];struct hostent*hptr;while (--argc > 0) {ptr = *++argv;if ( (hptr = gethostbyname(ptr)) == NULL) {printf("gethostbyname error for host: %s",ptr);continue;}printf("official hostname: %s\n", hptr->h_name);printf("h_addrtype is %d.\n", hptr->h_addrtype);  //2---AF_INET  10---AF_INET6for (pptr = hptr->h_aliases; *pptr != NULL; pptr++)printf("\talias: %s\n", *pptr);switch (hptr->h_addrtype) {case AF_INET:#ifdefAF_INET6case AF_INET6:#endifpptr = hptr->h_addr_list;for ( ; *pptr != NULL; pptr++)printf("\taddress: %s\n",inet_ntop(hptr->h_addrtype, *pptr, str, sizeof(str)));break;default:printf("unknown address type");break;}}return 0;}



原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 买的烤鱼片刺多怎么办 鸡蛋不太新鲜了怎么办 麻雀从巢里掉下来怎么办 小鱼生了鱼蛋怎么办 吃了没熟透的鱼怎么办 吃了变质的虾怎么办 吃了不新鲜的肉怎么办 吃不新鲜的虾怎么办 鸡胸肉不新鲜了怎么办 吃了不新鲜的鱼怎么办 生的猪肉有点臭怎么办? 猪肉馅不新鲜了怎么办 买的肉有点臭了怎么办 炸的东西不脆了怎么办 油炸东西回软了怎么办 吃石斑鱼蛋吐了怎么办 家里的烟筒堵了怎么办 脖子上长鸡皮肤怎么办 铁板烤蔬菜粘锅怎么办 残余尿量300ml怎么办 肌肉拉伤怎么办恢复快小腿 睡觉把背扭了怎么办 后背一侧扭筋了怎么办 背部的筋扭到了怎么办 跳绳跳得膝盖疼怎么办 跑步小腿变粗了怎么办 一蹲下膝盖就响怎么办 做深蹲时膝盖总是吱吱响怎么办 爬山爬的膝盖疼怎么办 膝盖一吹风就疼怎么办 走路太多膝盖腿疼怎么办 膝盖一着凉就痛怎么办 月子里脚受凉了怎么办 膝关节受凉少量积液发胀怎么办 刮痧后吹空调了怎么办 200斤胖子膝盖痛怎么办 风扇吹的腿疼怎么办 膝盖受凉但不疼怎么办 刮痧后洗了澡怎么办 刮痧后喝了啤酒怎么办 艾灸后吃水果了怎么办