linux名字與地址轉換
2015/07/07 13:08
瀏覽134
迴響0
推薦0
引用0
在網絡中,主機都是用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;
}
#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;
}
你可能會有興趣的文章:
限會員,要發表迴響,請先登入


