码迷,mamicode.com
首页 > 其他好文 > 详细

sockets: DNS库函数的名字与地址转换

时间:2015-02-28 21:44:36      阅读:253      评论:0      收藏:0      [点我收藏+]

标签:sockets   dns   

###########################################################

DNS库函数的名字与地址转换

######################################################

 

通常给出的是数值地址(也就是IP地址),不方便记忆;

域名系统(DNS):用于在主机名字和IP地址之间的映射。

 

/etc/resolv.conf包含本地名字服务器主机的IP地址。

 

获取名字和地址信息的方法:

1.使用DNS

2.静态主机文件(/etc/hosts)

3.网络信息系统(NIS)

4.轻权目录访问协议(LDAP)

 

下面主要是在名字和数值之间转换的DNS函数:

#include <netdb.h>

#include <sys/socket.h>

#include <sys/types.h>

extern int h_errno

函数出错不设置errno,而是设置h_errno。

 

-----------------------------------------------------------

主机信息相关函数

/etc/hosts

根据IP地址和主机名 获取hostent信息

 

struct hostent

{

char*h_name;           //host name

char*h_aliases;         //alias  names

inth_addrtype;          //AF_INET

inth_length;               //4

char**h_addr_list;   //ipv4  address

};

 

struct hostent *gethostent(void);   /* systemv/posix extension */

void sethostent(int stayopen);

 

struct hostent *gethostbyname(const char *hostname);

只能返回hostname对应的Ipv4的地址;ipv4的函数,一般不用了;

name一般是hostname,也可以是hostname对应的的IP。

 

struct hostent *gethostbyaddr(const void *addr, socklen_t len, int type);

传入in_addr的机构指针和长度,type=AF_INET;返回hostname。

 

void herror(const char *s);

在stderr打印出错信息。

 

const char *hstrerror(int err);

传入h_errno,返回指向错误说明的字符串。

 

--------------------------------

以上函数是不可重入的,下面是相应的可重入版本:

由调用者分配空间,由可重入函数填写该结构。

不同的系统提供的接口不同。

 

int gethostent_r(struct hostent *ret, char *buf, size_t buflen, structhostent **result, int *h_errnop);

 

int gethostbyname_r(const char *hostname,

struct hostent *ret, 返回值存放的结构

char *buf, size_t buflen, 由调用者分配的空间和大小

struct hostent **result, //?

int *h_errnop);返回错误码

 

int gethostbyaddr_r(const void *addr, socklen_t len, int type,

struct hostent *ret,

char *buf, size_t buflen,

struct hostent **result,//?

int *h_errnop);返回错误码

 

void endhostent(void);

释放调用者创建的缓冲区

 

-----------------------------------------------------------

服务信息相关函数

 

/etc/services 包含从servname到port的映射关系

 

根据服务名和端口获取 servent信息

 

struct servent

{

char*s_name;       /* service name */

char**s_aliases;   /* alias name */

int s_port;               /* port */

char*s_proto         /* proto to use */

};

 

void setservent(int stayopen);

struct servent *getservent(void);

 

struct servent *getservbyname(const char *servname, const char *proto);

根据服务名超找相应的服务的信息。

 

典型调用:

sptr = getservbyname(“ftp”, “tcp”);

sptr = getservbyname(“telnet”, “tcp”);

sptr = getservbyname(“smtp”, “tcp”);

sptr = getservbyname(“git”, “tcp”);

 

struct servent *getservbyport(int port, const char *proto);

根据端口号超找相应服务的信息。

 

-------------------------

服务相关的函数的可重入版本:

 

int getservent_r(struct servent*result_buf, char *buf, size_t buflen, struct servent **result);

 

int getservbyname_r(const char*name, const char *proto, struct servent *result_buf, char *buf, size_t buflen,struct servent **result);

 

int getservbyport_r(int port,const char *proto, struct servent *result_buf, char *buf, size_t buflen, structservent **result);

 

void endservent(void);

释放调用者创建的缓冲区

 

-----------------------------------------------------

网络信息相关函数

/etc/networks

 

struct netent

{

char*n_name;//net work name

char**n_aliases;//alias names

intn_addrtype;//AF_INET

uint32_tn_net;//network number

};

 

struct netent *getnetent(void);

void setnetent(int stayopen);

 

struct netent *getnetbyname(const char *netname);

根据网络名称获取网络相关信息

 

struct netent *getnetbyaddr(uint32_t net, int type);

根据网络类型和网络号获取网络相关信息

 

---------------------------

网络相关的可重入的函数

 

int getnetent_r(struct netent *result_buf, char *buf, size_t buflen,struct netent **result, int *h_errnop);

 

int getnetentbyname_r(const char *name, struct netent *result_buf, char*buf, size_t buflen, struct netent **result, int *h_errnop);

 

int getnetbyaddr_r(uint32_t net, int type, struct netent *result_buf,char *buf, size_t buflen, struct netent **result, int *h_errnop);

 

void endnetent(void);

释放调用者创建的缓冲区

 

-----------------------------------------------------

协议信息相关函数

/etc/protocols

 

struct protoent

{

char*p_name;//protocol name

char**p_aliases;//alias name

intp_proto;//protocol number

};

 

struct protoent *getprotent(void);

void setprotoent(int stayopen);

 

struct protoent *getprotobyname(const char *protocolname);

根据协议名获取协议相关信息

 

struct protoent *getprotobynumber(int protonumber);

根据协议号获取协议相关信息

 

---------------------------

协议信息相关的可重入的函数

 

int getprotoent_r(struct protoent *result_buf, char *buf, size_tbuflen, struct protoent **result);

 

int getprotobyname_r(const char *name, struct protoent *result_buf,char *buf, size_t buflen, struct protoent **result);

 

int getprotobynumber_r(int proto, struct protoent *result_buf, char*buf, size_t buflen, struct protoent **result);

 

void endprotoent(void);

释放调用者创建的缓冲区

 

-----------------------------------------------------------

网络分组相关的函数

 

int setnetgrent(const char *netgroup);

int getnetgrent(char **host, char **user, char **domain);

 

可重入的版本:

int getnetgrent_r(char **host, char **user, char **domain, //主机名用户名域名

char *buf, int buflen //调用者创建空间和长度

);根据三个名字获取网络分组信息

 

void endnetgrent(void);

释放调用者创建的缓冲区

 

int innetgr(const char *netgroup, const char *host, const char *user,const char *domain);

检查成员hostname、username、domainname是否在netgroup网络分组中。

 

-----------------------------------------------------------

IPv6的协议函数

根据主机名、IP地址、服务名、端口号获取通用套接字地址结构。

 

struct addrinfo

{

   int ai_flags;/AI_XXX

   int ai_family;//AF_XXX

   int ai_socktype;//SOCK_XXX

   int ai_protocol;//0 orIPPROTO_XXX

   socklen_t ai_addrlen;//length of ai_addr

   char *ai_canonname;//hostname

   struct sockaddr *ai_addr;//返回的通用套接字地址结构

   struct addrinfo *ai_next;//结构链表的地址

}

 

ai_flags:

AI_PASSIVE

AI_CANONAME

AI_NUMERICHOST

AI_NUMERICSERV

AI_V4MAPPED:如果ai_family=AF_INET6,如果没有可用的AAAA记录,就返回A记录对应的ipv4映射的ipv6地址。

AI_ALL

AI_ADDRCONFIG

 

int getaddrinfo(const char*hostname,//主机名或IP地址

const char *service,//服务名或端口号

const struct addrinfo *hints,//用于设置addrinfo的前四个变量

struct addrinfo **res//返回的指向addrinfo结构链表的指针

);

 

const char *gai_strerror(interrcode);

根据getaddrinfo返回的非0的错误值res,返回一个指向出错信息串的指针。

 

void freeaddrinfo(structaddrinfo *res);

getaddrinfo返回的存储空间都是动态获取的。

ai指向getaddrinfo返回的第一个addrinfo结构,

调用freeaddrinfo将动态获取的空间返还给系统。

 

int getnameinfo(const struct sockaddr *sa, socklen_t salen, 套接字地址结构和长度

char *host, size_t hostlen, 主机名或IP及其长度

char *serv, size_t servlen, 服务名或端口号及其长度

int flags 标志

);

返回的主机名和服务名需要预先分配空间。

 

flags:

NI_DGRAM

NI_NAMEREQD

NI_NOFQDN

NI_NUMERICHOST

NI_NUMERICSCOPE

NI_NUMERICSERV

 

getaddrinfo和getnameinfo可重入的条件是由它调用的函数都是可重入的。

 

-----------------------------------------------------------

其它netdb函数:

 

例行返回一个远程命令的流:

 

int rcmd(char **ahost, int inport, const char *locuser, const char*remuser, const char *cmd, int *fd2p);

 

int rresvport(int *port);

 

int iruserok(uint32_t raddr, int superuser, const char *ruser, constchar *luser);

 

int ruserok(const char *rhost, int superuser, const char *ruser, constchar *luser);

sockets: DNS库函数的名字与地址转换

标签:sockets   dns   

原文地址:http://blog.csdn.net/wowotouweizi/article/details/43989031

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!