在网络中,主机都是用ip地址标示的;但是,出于很多理由,我们应该使用名字,而非纯数字:名字比较好记,数值地址可以变动但名字可以不变(如域名),随着往ipv6上转移,地址变得很长,数值书写容易出错等等。本文示例linux几个处理名字与地址转换的函数的使用:
-
#include <netdb.h>
-
#include <sys/socket.h>
-
#include <arpa/inet.h>
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <netinet/in.h>
-
#include <getopt.h>
-
-
struct option g_opts[] = {
-
{"host", required_argument, null, 'h'},
-
{"server", required_argument, null, 's'},
-
{"protocol", required_argument, null, 'p'},
-
{"help", no_argument, null, 'h'}
-
};
-
-
/* struct hostent
-
{
-
char *h_name;
-
char **h_aliases;
-
int h_addrtype;
-
int h_length;
-
char **h_addr_list;
-
#define h_addr h_addr_list[0]
-
};
-
*/
-
-
/*
-
struct servent {
-
char *s_name; //official service name
-
char **s_aliases; //alias list
-
int s_port; //port number, network-byte order
-
char *s_proto; // protocol to use
-
*/
-
void showusage()
-
{
-
printf("usage:\n\tidns -h [ipstr/hostname]\n\t -s [servname/servport] -g [protocol]\n");
-
}
-
-
static void printservent(struct servent *sptr)
-
{
-
char **pptr;
-
-
printf("server name: %s\n", sptr->s_name);
-
-
pptr = sptr->s_aliases;
-
while (pptr && *pptr != null)
-
{
-
printf("\taliases: %s\n", *pptr);
-
pptr;
-
}
-
-
printf("\tport: %d\n", ntohs(sptr->s_port));
-
printf("\tproto: %s\n", sptr->s_proto);
-
}
-
-
static void printhostent(struct hostent *hptr)
-
{
-
char str[33] = { 0, };
-
char **pptr;
-
-
if (null == hptr)
-
return;
-
-
printf("official hostname:%s\n", hptr->h_name);
-
-
for (pptr = hptr->h_aliases; *pptr != null; pptr)
-
printf("alias:%s\n", *pptr);
-
-
switch (hptr->h_addrtype)
-
{
-
case af_inet:
-
case af_inet6:
-
pptr = hptr->h_addr_list;
-
for (; pptr && *pptr != null; pptr)
-
printf("address: %s\n", inet_ntop(hptr->h_addrtype, *pptr, str, 32));
-
break;
-
default:
-
printf("unknow address type\n");
-
break;
-
}
-
-
}
-
-
static void printherror(int perror)
-
{
-
switch (perror)
-
{
-
case host_not_found:
-
printf("host not found!\n");
-
break;
-
// case no_address:
-
// case no_data:printf("112\n");break;
-
case no_recovery:
-
printf("no recovery!\n");
-
break;
-
case try_again:
-
printf("try again\n");
-
break;
-
default:
-
printf("unknow error type:%d\n", perror);
-
return;
-
}
-
}
-
-
void igethostbyname_common(char *name)
-
{
-
struct addrinfo *answer, hint, *curr;
-
char ipstr[16];
-
int ret;
-
-
memset(&hint, 0, sizeof(hint));
-
hint.ai_flags = ai_canonname;
-
-
ret = getaddrinfo(name, null, &hint, &answer);
-
if (ret != 0)
-
{
-
fprintf(stderr, "getaddrinfo fail: %s\n", gai_strerror(ret));
-
exit(1);
-
}
-
-
for (curr = answer; curr != null; curr = curr->ai_next)
-
{
-
printf("host name: %s\n", curr->ai_canonname == null ? "" : curr->ai_canonname);
-
-
inet_ntop(af_inet, &(((struct sockaddr_in *)(curr->ai_addr))->sin_addr), ipstr, 16);
-
printf("addr: %s\n", ipstr);
-
}
-
-
freeaddrinfo(answer);
-
}
-
-
void igethostbyname_ipv4(char *name)
-
{
-
struct hostent *hptr;
-
if ((hptr = gethostbyname(name)) == null)
-
{
-
printf("gethostbyname fail for host:%s\n", name);
-
return;
-
}
-
printhostent(hptr);
-
}
-
-
void igethostbyaddr_ipv4(char *addr)
-
{
-
struct hostent *hptr;
-
in_addr_t nip;
-
int trytimes = 3;
-
-
nip = inet_addr(addr);
-
-
l_try_again:
-
if ((hptr = gethostbyaddr(&nip, 4, af_inet)) == null)
-
{
-
if (h_errno == try_again && trytimes > 0)
-
{
-
trytimes--;
-
goto l_try_again;
-
}
-
-
printf("fail to get host by addr<%s>: ", addr);
-
printherror(h_errno);
-
return;
-
}
-
printhostent(hptr);
-
}
-
-
void igetservbyname(char *name, char *proto)
-
{
-
struct servent *sptr;
-
-
if ((sptr = getservbyname(name, proto)) == null)
-
{
-
printf("can not find server with name:%s and protocol:%s\n", name, proto);
-
return;
-
}
-
-
printservent(sptr);
-
-
}
-
-
void igetservbyport(int port, char *proto)
-
{
-
struct servent *sptr;
-
-
if ((sptr = getservbyport(htons(port), proto)) == null)
-
{
-
printf("can not find server with port:%d and protocol:%s\n", port, proto);
-
return;
-
}
-
printservent(sptr);
-
}
-
-
char g_buf[64] = { 0, };
-
char g_proto[16] = { 0, };
-
-
int main(int argc, char **argv)
-
{
-
int opt;
-
int cmdtype = 0;
-
-
int temp = 0;
-
-
if (argc < 2)
-
{
-
showusage();
-
return 0;
-
}
-
-
while ((opt = getopt_long(argc, argv, "s:h:p:", g_opts, null)) != -1)
-
{
-
switch (opt)
-
{
-
case 's':
-
strcpy(g_buf, optarg);
-
cmdtype = 1;
-
break;
-
case 'h':
-
strcpy(g_buf, optarg);
-
cmdtype = 2;
-
break;
-
case 'p':
-
strcpy(g_proto, optarg);
-
break;
-
case 'h':
-
showusage();
-
break;
-
default:
-
showusage();
-
return;
-
}
-
}
-
-
if (cmdtype == 2 && (inet_addr(g_buf)) == inaddr_none)
-
{
-
igethostbyname_ipv4(g_buf);
-
}
-
else if (cmdtype == 2)
-
{
-
igethostbyaddr_ipv4(g_buf);
-
}
-
else if (cmdtype == 1)
-
{
-
temp = atoi(g_buf);
-
if (temp > 0)
-
igetservbyport(temp, g_proto);
-
else
-
igetservbyname(g_buf, g_proto);
-
}
-
else
-
showusage();
-
-
return 0;
-
}
阅读(2697) | 评论(0) | 转发(0) |