先来说IP地址转换吧。
IP地址有两种表示形式,一种是字符串形式,如192.168.1.2,英语叫做IPv4 number-and-dots notation;一种是整数形式,一般是个很大的整数,英语叫做binary data,也称为二进制地址。
本文讲叙如何在这两种形式间转换。
1.
IP地址字符串形式转为整数形式
Linux提供了3个函数:
int inet_aton(const char *cp, struct
in_addr *inp);
in_addr_t inet_addr(const char *cp);
in_addr_t inet_network(const char *cp);
inet_addr返回的整数形式是网络字节序,而inet_network返回的整数形式是主机字节序。两者并无差异,但都有一个小缺陷,当IP是255.255.255.255时,这两个函数会认为这个是无效的IP地址,这是历史遗留问题。
inet_aton函数和上面两个函数的区别就是他认为255.255.255.255是有效的,其返回的是网络字节序的IP地址。
2.
IP地址整数形式转为字符串形式
char *inet_ntoa(struct in_addr in);
对于IP地址的掩码,有两种表示方法:一种是masklen形式;一种是maskstring形式。
1.
maskstring转为masklen
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<sys/types.h>
#include <arpa/inet.h>
int32_t get_netmask_length(char* mask)
{
int32_t masklen=0, i=0;
uint32_t netmask=0;
if(mask == NULL)
{
return 0;
}
struct in_addr ip_addr;
if( inet_aton(mask, &ip_addr) )
{
netmask = ntohl(ip_addr.s_addr);
}else{
netmask = 0;
return 0;
}
while(0 == (netmask & 0x01) && i<32)
{
i++;
netmask = netmask>>1;
}
masklen = 32-i;
return masklen;
}
int main()
{
char str[]="255.255.255.255";
int32_t length;
length = get_netmask_length(str);
printf("%d\n",length);
return 0;
}
|
2.
masklen转为maskstring
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<sys/types.h>
#include <arpa/inet.h>
char *get_netmask_string(int32_t masklen)
{
uint32_t mask=0;
int32_t i=0;
struct in_addr ip_addr;
if(masklen < 0 || masklen > 32)
{
return NULL;
}
for(i=0;i<masklen;i++)
mask |= 0x80000000>>i;
ip_addr.s_addr = htonl(mask);
return inet_ntoa(ip_addr);
}
int main()
{
int32_t length = 26;
char *maskstring = NULL;
maskstring = get_netmask_string(length);
printf("%s\n",maskstring);
return 0;
}
|
阅读(5594) | 评论(0) | 转发(0) |